diff options
432 files changed, 11639 insertions, 27232 deletions
diff --git a/Android.bp b/Android.bp index 8164d6a477e4..c47b74717dcd 100644 --- a/Android.bp +++ b/Android.bp @@ -747,6 +747,7 @@ gensrcs { srcs: [ ":ipconnectivity-proto-src", + ":libstats_atom_enum_protos", "core/proto/**/*.proto", "libs/incident/**/*.proto", ], @@ -773,6 +774,7 @@ gensrcs { srcs: [ ":ipconnectivity-proto-src", + ":libstats_atom_enum_protos", "core/proto/**/*.proto", "libs/incident/**/*.proto", ], @@ -912,13 +914,18 @@ java_library_host { name: "platformprotos", srcs: [ ":ipconnectivity-proto-src", + ":libstats_atom_enum_protos", + ":libstats_internal_protos", "cmds/am/proto/instrumentation_data.proto", "cmds/statsd/src/**/*.proto", "core/proto/**/*.proto", "libs/incident/proto/**/*.proto", ], proto: { - include_dirs: ["external/protobuf/src"], + include_dirs: [ + "external/protobuf/src", + "frameworks/proto_logging/stats", + ], type: "full", }, // Protos have lots of MissingOverride and similar. @@ -943,6 +950,7 @@ java_library { sdk_version: "9", srcs: [ ":ipconnectivity-proto-src", + ":libstats_atom_enum_protos", "core/proto/**/*.proto", "libs/incident/proto/android/os/**/*.proto", ], @@ -958,6 +966,7 @@ java_library { srcs: [ ":ipconnectivity-proto-src", + ":libstats_atom_enum_protos", "core/proto/**/*.proto", "libs/incident/proto/android/os/**/*.proto", ], @@ -979,7 +988,9 @@ cc_defaults { proto: { export_proto_headers: true, - include_dirs: ["external/protobuf/src"], + include_dirs: [ + "external/protobuf/src", + ], }, cflags: [ @@ -990,6 +1001,7 @@ cc_defaults { srcs: [ ":ipconnectivity-proto-src", + ":libstats_atom_enum_protos", "core/proto/**/*.proto", ], } diff --git a/core/proto/android/stats/storage/storage_enums.proto b/apex/appsearch/framework/java/android/app/appsearch/AppSearchBatchResult.aidl index 6892e287472f..4686de8df268 100644 --- a/core/proto/android/stats/storage/storage_enums.proto +++ b/apex/appsearch/framework/java/android/app/appsearch/AppSearchBatchResult.aidl @@ -1,11 +1,11 @@ -/* - * Copyright (C) 2019 The Android Open Source Project +/** + * 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 + * 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, @@ -13,14 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +package android.app.appsearch; -syntax = "proto2"; - -package android.stats.storage; - -enum ExternalStorageType { - UNKNOWN = 0; - SD_CARD = 1; - USB = 2; - OTHER = 3; -} +/** {@hide} */ +parcelable AppSearchBatchResult;
\ No newline at end of file diff --git a/apex/appsearch/framework/java/android/app/appsearch/AppSearchManager.java b/apex/appsearch/framework/java/android/app/appsearch/AppSearchManager.java index f2c9942edbb3..e57359fbf50e 100644 --- a/apex/appsearch/framework/java/android/app/appsearch/AppSearchManager.java +++ b/apex/appsearch/framework/java/android/app/appsearch/AppSearchManager.java @@ -15,10 +15,12 @@ */ package android.app.appsearch; +import android.annotation.CallbackExecutor; import android.annotation.NonNull; import android.annotation.SystemService; import android.content.Context; import android.os.Bundle; +import android.os.ParcelableException; import android.os.RemoteException; import com.android.internal.infra.AndroidFuture; @@ -27,7 +29,10 @@ import com.android.internal.util.Preconditions; import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.concurrent.ExecutionException; +import java.util.concurrent.Executor; +import java.util.function.Consumer; /** * This class provides access to the centralized AppSearch index maintained by the system. @@ -40,12 +45,99 @@ import java.util.concurrent.ExecutionException; // TODO(b/148046169): This class header needs a detailed example/tutorial. @SystemService(Context.APP_SEARCH_SERVICE) public class AppSearchManager { - private static final String DEFAULT_DATABASE = ""; + /** + * The default empty database name. + * @hide + */ + public static final String DEFAULT_DATABASE_NAME = ""; + private final IAppSearchManager mService; /** @hide */ public AppSearchManager(@NonNull IAppSearchManager service) { - mService = service; + mService = Objects.requireNonNull(service); + } + + /** Contains information about how to create the search session. */ + public static final class SearchContext { + final String mDatabaseName; + + SearchContext(@NonNull String databaseName) { + mDatabaseName = Objects.requireNonNull(databaseName); + } + + /** + * Returns the name of the database to create or open. + * + * <p>Databases with different names are fully separate with distinct types, namespaces, + * and data. + */ + @NonNull + public String getDatabaseName() { + return mDatabaseName; + } + + /** Builder for {@link SearchContext} objects. */ + public static final class Builder { + private String mDatabaseName = DEFAULT_DATABASE_NAME; + private boolean mBuilt = false; + + /** + * Sets the name of the database associated with {@link AppSearchSession}. + * + * <p>{@link AppSearchSession} will create or open a database under the given name. + * + * <p>Databases with different names are fully separate with distinct types, namespaces, + * and data. + * + * <p>Database name cannot contain {@code '/'}. + * + * <p>If not specified, defaults to {@link #DEFAULT_DATABASE_NAME}. + * @param databaseName The name of the database. + * @throws IllegalArgumentException if the databaseName contains {@code '/'}. + */ + @NonNull + public Builder setDatabaseName(@NonNull String databaseName) { + Preconditions.checkState(!mBuilt, "Builder has already been used"); + Objects.requireNonNull(databaseName); + if (databaseName.contains("/")) { + throw new IllegalArgumentException("Database name cannot contain '/'"); + } + mDatabaseName = databaseName; + return this; + } + + /** Builds a {@link SearchContext} instance. */ + @NonNull + public SearchContext build() { + Preconditions.checkState(!mBuilt, "Builder has already been used"); + mBuilt = true; + return new SearchContext(mDatabaseName); + } + } + } + + /** + * Creates a new {@link AppSearchSession}. + * + * <p>This process requires an AppSearch native indexing file system for each user. If it's not + * created for this user, the initialization process will create one under user's directory. + * + * @param searchContext The {@link SearchContext} contains all information to create a new + * {@link AppSearchSession} + * @param executor Executor on which to invoke the callback. + * @param callback The {@link AppSearchResult}<{@link AppSearchSession}> of + * performing this operation. Or a {@link AppSearchResult} with failure + * reason code and error information. + */ + public void createSearchSession( + @NonNull SearchContext searchContext, + @NonNull @CallbackExecutor Executor executor, + @NonNull Consumer<AppSearchResult<AppSearchSession>> callback) { + Objects.requireNonNull(searchContext); + Objects.requireNonNull(executor); + Objects.requireNonNull(callback); + AppSearchSession.createSearchSession(searchContext, mService, executor, callback); } /** @@ -99,7 +191,7 @@ public class AppSearchManager { * * @param request The schema update request. * @return the result of performing this operation. - * + * @deprecated use {@link AppSearchSession#setSchema} instead. * @hide */ @NonNull @@ -113,9 +205,14 @@ public class AppSearchManager { } AndroidFuture<AppSearchResult> future = new AndroidFuture<>(); try { - mService.setSchema(DEFAULT_DATABASE, schemaBundles, request.isForceOverride(), future); + mService.setSchema(DEFAULT_DATABASE_NAME, schemaBundles, request.isForceOverride(), + new IAppSearchResultCallback.Stub() { + public void onResult(AppSearchResult result) { + future.complete(result); + } + }); } catch (RemoteException e) { - future.completeExceptionally(e); + throw e.rethrowFromSystemServer(); } return getFutureOrThrow(future); } @@ -134,6 +231,9 @@ public class AppSearchManager { * {@link AppSearchBatchResult} are the URIs of the input documents. The values are * {@code null} if they were successfully indexed, or a failed {@link AppSearchResult} * otherwise. + * @throws RuntimeException If an error occurred during the execution. + * + * @deprecated use {@link AppSearchSession#putDocuments} instead. * @hide */ public AppSearchBatchResult<String, Void> putDocuments(@NonNull PutDocumentsRequest request) { @@ -146,7 +246,16 @@ public class AppSearchManager { } AndroidFuture<AppSearchBatchResult> future = new AndroidFuture<>(); try { - mService.putDocuments(DEFAULT_DATABASE, documentBundles, future); + mService.putDocuments(DEFAULT_DATABASE_NAME, documentBundles, + new IAppSearchBatchResultCallback.Stub() { + public void onResult(AppSearchBatchResult result) { + future.complete(result); + } + + public void onSystemError(ParcelableException exception) { + future.completeExceptionally(exception); + } + }); } catch (RemoteException e) { future.completeExceptionally(e); } @@ -165,6 +274,9 @@ public class AppSearchManager { * {@link GenericDocument}s on success, or a failed {@link AppSearchResult} otherwise. * URIs that are not found will return a failed {@link AppSearchResult} with a result code * of {@link AppSearchResult#RESULT_NOT_FOUND}. + * @throws RuntimeException If an error occurred during the execution. + * + * @deprecated use {@link AppSearchSession#getByUri} instead. */ public AppSearchBatchResult<String, GenericDocument> getByUri( @NonNull GetByUriRequest request) { @@ -173,7 +285,16 @@ public class AppSearchManager { List<String> uris = new ArrayList<>(request.getUris()); AndroidFuture<AppSearchBatchResult> future = new AndroidFuture<>(); try { - mService.getDocuments(DEFAULT_DATABASE, request.getNamespace(), uris, future); + mService.getDocuments(DEFAULT_DATABASE_NAME, request.getNamespace(), uris, + new IAppSearchBatchResultCallback.Stub() { + public void onResult(AppSearchBatchResult result) { + future.complete(result); + } + + public void onSystemError(ParcelableException exception) { + future.completeExceptionally(exception); + } + }); } catch (RemoteException e) { future.completeExceptionally(e); } @@ -252,6 +373,9 @@ public class AppSearchManager { * * @param queryExpression Query String to search. * @param searchSpec Spec for setting filters, raw query etc. + * @throws RuntimeException If an error occurred during the execution. + * + * @deprecated use AppSearchSession#query instead. * @hide */ @NonNull @@ -261,7 +385,7 @@ public class AppSearchManager { // them in one big list. AndroidFuture<AppSearchResult> searchResultsFuture = new AndroidFuture<>(); try { - mService.query(DEFAULT_DATABASE, queryExpression, + mService.query(DEFAULT_DATABASE_NAME, queryExpression, searchSpec.getBundle(), searchResultsFuture); } catch (RemoteException e) { searchResultsFuture.completeExceptionally(e); @@ -278,7 +402,7 @@ public class AppSearchManager { } /** - * Deletes {@link GenericDocument}s by URI. + * Removes {@link GenericDocument}s by URI. * * <p>You should not call this method directly; instead, use the {@code AppSearch#delete()} API * provided by JetPack. @@ -289,12 +413,24 @@ public class AppSearchManager { * or a failed {@link AppSearchResult} otherwise. URIs that are not found will return a * failed {@link AppSearchResult} with a result code of * {@link AppSearchResult#RESULT_NOT_FOUND}. + * @throws RuntimeException If an error occurred during the execution. + * + * @deprecated use {@link AppSearchSession#removeByUri} instead. */ public AppSearchBatchResult<String, Void> removeByUri(@NonNull RemoveByUriRequest request) { List<String> uris = new ArrayList<>(request.getUris()); AndroidFuture<AppSearchBatchResult> future = new AndroidFuture<>(); try { - mService.removeByUri(DEFAULT_DATABASE, request.getNamespace(), uris, future); + mService.removeByUri(DEFAULT_DATABASE_NAME, request.getNamespace(), uris, + new IAppSearchBatchResultCallback.Stub() { + public void onResult(AppSearchBatchResult result) { + future.complete(result); + } + + public void onSystemError(ParcelableException exception) { + future.completeExceptionally(exception); + } + }); } catch (RemoteException e) { future.completeExceptionally(e); } diff --git a/apex/appsearch/framework/java/android/app/appsearch/AppSearchResult.aidl b/apex/appsearch/framework/java/android/app/appsearch/AppSearchResult.aidl new file mode 100644 index 000000000000..f0b29964b895 --- /dev/null +++ b/apex/appsearch/framework/java/android/app/appsearch/AppSearchResult.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.appsearch; + +/** {@hide} */ +parcelable AppSearchResult;
\ No newline at end of file diff --git a/apex/appsearch/framework/java/android/app/appsearch/AppSearchResult.java b/apex/appsearch/framework/java/android/app/appsearch/AppSearchResult.java index 979eab90a980..6e2ed70cca01 100644 --- a/apex/appsearch/framework/java/android/app/appsearch/AppSearchResult.java +++ b/apex/appsearch/framework/java/android/app/appsearch/AppSearchResult.java @@ -19,9 +19,11 @@ package android.app.appsearch; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; +import android.app.appsearch.exceptions.AppSearchException; import android.os.Parcel; import android.os.Parcelable; +import java.io.IOException; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.Objects; @@ -218,4 +220,25 @@ public final class AppSearchResult<ValueType> implements Parcelable { @ResultCode int resultCode, @Nullable String errorMessage) { return new AppSearchResult<>(resultCode, /*resultValue=*/ null, errorMessage); } + + /** @hide */ + @NonNull + public static <ValueType> AppSearchResult<ValueType> throwableToFailedResult( + @NonNull Throwable t) { + if (t instanceof AppSearchException) { + return ((AppSearchException) t).toAppSearchResult(); + } + + @AppSearchResult.ResultCode int resultCode; + if (t instanceof IllegalStateException) { + resultCode = AppSearchResult.RESULT_INTERNAL_ERROR; + } else if (t instanceof IllegalArgumentException) { + resultCode = AppSearchResult.RESULT_INVALID_ARGUMENT; + } else if (t instanceof IOException) { + resultCode = AppSearchResult.RESULT_IO_ERROR; + } else { + resultCode = AppSearchResult.RESULT_UNKNOWN_ERROR; + } + return AppSearchResult.newFailedResult(resultCode, t.toString()); + } } diff --git a/apex/appsearch/framework/java/android/app/appsearch/AppSearchSession.java b/apex/appsearch/framework/java/android/app/appsearch/AppSearchSession.java new file mode 100644 index 000000000000..531436ecaf0c --- /dev/null +++ b/apex/appsearch/framework/java/android/app/appsearch/AppSearchSession.java @@ -0,0 +1,312 @@ +/* + * 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.appsearch; + +import android.annotation.CallbackExecutor; +import android.annotation.NonNull; +import android.app.appsearch.exceptions.AppSearchException; +import android.os.Bundle; +import android.os.ParcelableException; +import android.os.RemoteException; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.concurrent.Executor; +import java.util.function.Consumer; + +/** + * Represents a connection to an AppSearch storage system where {@link GenericDocument}s can be + * placed and queried. + * @hide + */ +public final class AppSearchSession { + private final String mDatabaseName; + private final IAppSearchManager mService; + + static void createSearchSession( + @NonNull AppSearchManager.SearchContext searchContext, + @NonNull IAppSearchManager service, + @NonNull @CallbackExecutor Executor executor, + @NonNull Consumer<AppSearchResult<AppSearchSession>> callback) { + AppSearchSession searchSession = + new AppSearchSession(searchContext.mDatabaseName, service); + searchSession.initialize(executor, callback); + } + + // NOTE: No instance of this class should be created or returned except via initialize(). + // Once the callback.accept has been called here, the class is ready to use. + private void initialize( + @NonNull @CallbackExecutor Executor executor, + @NonNull Consumer<AppSearchResult<AppSearchSession>> callback) { + try { + mService.initialize(new IAppSearchResultCallback.Stub() { + public void onResult(AppSearchResult result) { + executor.execute(() -> { + if (result.isSuccess()) { + callback.accept( + AppSearchResult.newSuccessfulResult(AppSearchSession.this)); + } else { + callback.accept(result); + } + }); + } + }); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + private AppSearchSession(@NonNull String databaseName, @NonNull IAppSearchManager service) { + mDatabaseName = databaseName; + mService = service; + } + + /** + * Sets the schema will be used by documents provided to the {@link #putDocuments} method. + * + * <p>The schema provided here is compared to the stored copy of the schema previously supplied + * to {@link #setSchema}, if any, to determine how to treat existing documents. The following + * types of schema modifications are always safe and are made without deleting any existing + * documents: + * <ul> + * <li>Addition of new types + * <li>Addition of new + * {@link AppSearchSchema.PropertyConfig#CARDINALITY_OPTIONAL OPTIONAL} or + * {@link AppSearchSchema.PropertyConfig#CARDINALITY_REPEATED REPEATED} properties to a + * type + * <li>Changing the cardinality of a data type to be less restrictive (e.g. changing an + * {@link AppSearchSchema.PropertyConfig#CARDINALITY_OPTIONAL OPTIONAL} property into a + * {@link AppSearchSchema.PropertyConfig#CARDINALITY_REPEATED REPEATED} property. + * </ul> + * + * <p>The following types of schema changes are not backwards-compatible: + * <ul> + * <li>Removal of an existing type + * <li>Removal of a property from a type + * <li>Changing the data type ({@code boolean}, {@code long}, etc.) of an existing property + * <li>For properties of {@code Document} type, changing the schema type of + * {@code Document}s of that property + * <li>Changing the cardinality of a data type to be more restrictive (e.g. changing an + * {@link AppSearchSchema.PropertyConfig#CARDINALITY_OPTIONAL OPTIONAL} property into a + * {@link AppSearchSchema.PropertyConfig#CARDINALITY_REQUIRED REQUIRED} property). + * <li>Adding a + * {@link AppSearchSchema.PropertyConfig#CARDINALITY_REQUIRED REQUIRED} property. + * </ul> + * <p>Supplying a schema with such changes will, by default, result in this call returning an + * {@link AppSearchResult} with a code of {@link AppSearchResult#RESULT_INVALID_SCHEMA} and an + * error message describing the incompatibility. In this case the previously set schema will + * remain active. + * + * <p>If you need to make non-backwards-compatible changes as described above, you can set the + * {@link SetSchemaRequest.Builder#setForceOverride} method to {@code true}. In this case, + * instead of returning an {@link AppSearchResult} with the + * {@link AppSearchResult#RESULT_INVALID_SCHEMA} error code, all documents which are not + * compatible with the new schema will be deleted and the incompatible schema will be applied. + * + * <p>It is a no-op to set the same schema as has been previously set; this is handled + * efficiently. + * + * @param request The schema update request. + * @param executor Executor on which to invoke the callback. + * @param callback Callback to receive errors resulting from setting the schema. If the + * operation succeeds, the callback will be invoked with {@code null}. + */ + public void setSchema( + @NonNull SetSchemaRequest request, + @NonNull @CallbackExecutor Executor executor, + @NonNull Consumer<AppSearchResult<Void>> callback) { + Objects.requireNonNull(request); + Objects.requireNonNull(executor); + Objects.requireNonNull(callback); + List<Bundle> schemaBundles = new ArrayList<>(request.getSchemas().size()); + for (AppSearchSchema schema : request.getSchemas()) { + schemaBundles.add(schema.getBundle()); + } + try { + mService.setSchema(mDatabaseName, schemaBundles, request.isForceOverride(), + new IAppSearchResultCallback.Stub() { + public void onResult(AppSearchResult result) { + executor.execute(() -> callback.accept(result)); + } + }); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * Indexes documents into AppSearch. + * + * <p>Each {@link GenericDocument}'s {@code schemaType} field must be set to the name of a + * schema type previously registered via the {@link #setSchema} method. + * + * @param request {@link PutDocumentsRequest} containing documents to be indexed + * @param executor Executor on which to invoke the callback. + * @param callback Callback to receive pending result of performing this operation. The keys + * of the returned {@link AppSearchBatchResult} are the URIs of the input + * documents. The values are {@code null} if they were successfully indexed, + * or a failed {@link AppSearchResult} otherwise. + * Or {@link BatchResultCallback#onSystemError} will be invoked with an + * {@link AppSearchException} if an error occurred in AppSearch initialization + * or a cause {@link Throwable} if other error occurred in AppSearch service. + */ + public void putDocuments( + @NonNull PutDocumentsRequest request, + @NonNull @CallbackExecutor Executor executor, + @NonNull BatchResultCallback<String, Void> callback) { + Objects.requireNonNull(request); + Objects.requireNonNull(executor); + Objects.requireNonNull(callback); + List<GenericDocument> documents = request.getDocuments(); + List<Bundle> documentBundles = new ArrayList<>(documents.size()); + for (int i = 0; i < documents.size(); i++) { + documentBundles.add(documents.get(i).getBundle()); + } + try { + mService.putDocuments(mDatabaseName, documentBundles, + new IAppSearchBatchResultCallback.Stub() { + public void onResult(AppSearchBatchResult result) { + executor.execute(() -> callback.onResult(result)); + } + + public void onSystemError(ParcelableException exception) { + executor.execute(() -> callback.onSystemError(exception.getCause())); + } + }); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * Retrieves {@link GenericDocument}s by URI. + * + * @param request {@link GetByUriRequest} containing URIs to be retrieved. + * @param executor Executor on which to invoke the callback. + * @param callback Callback to receive the pending result of performing this operation. The keys + * of the returned {@link AppSearchBatchResult} are the input URIs. The values + * are the returned {@link GenericDocument}s on success, or a failed + * {@link AppSearchResult} otherwise. URIs that are not found will return a + * failed {@link AppSearchResult} with a result code of + * {@link AppSearchResult#RESULT_NOT_FOUND}. + * Or {@link BatchResultCallback#onSystemError} will be invoked with an + * {@link AppSearchException} if an error occurred in AppSearch initialization + * or a cause {@link Throwable} if other error occurred in AppSearch service. + */ + public void getByUri( + @NonNull GetByUriRequest request, + @NonNull @CallbackExecutor Executor executor, + @NonNull BatchResultCallback<String, GenericDocument> callback) { + Objects.requireNonNull(request); + Objects.requireNonNull(executor); + Objects.requireNonNull(callback); + try { + mService.getDocuments(mDatabaseName, request.getNamespace(), + new ArrayList<>(request.getUris()), + new IAppSearchBatchResultCallback.Stub() { + public void onResult(AppSearchBatchResult result) { + executor.execute(() -> { + AppSearchBatchResult.Builder<String, GenericDocument> + documentResultBuilder = + new AppSearchBatchResult.Builder<>(); + + // Translate successful results + for (Map.Entry<String, Bundle> bundleEntry : + (Set<Map.Entry<String, Bundle>>) + result.getSuccesses().entrySet()) { + GenericDocument document; + try { + document = new GenericDocument(bundleEntry.getValue()); + } catch (Throwable t) { + // These documents went through validation, so how could + // this fail? We must have done something wrong. + documentResultBuilder.setFailure( + bundleEntry.getKey(), + AppSearchResult.RESULT_INTERNAL_ERROR, + t.getMessage()); + continue; + } + documentResultBuilder.setSuccess( + bundleEntry.getKey(), document); + } + + // Translate failed results + for (Map.Entry<String, AppSearchResult<Bundle>> bundleEntry : + (Set<Map.Entry<String, AppSearchResult<Bundle>>>) + result.getFailures().entrySet()) { + documentResultBuilder.setFailure( + bundleEntry.getKey(), + bundleEntry.getValue().getResultCode(), + bundleEntry.getValue().getErrorMessage()); + } + callback.onResult(documentResultBuilder.build()); + }); + } + + public void onSystemError(ParcelableException exception) { + executor.execute(() -> callback.onSystemError(exception.getCause())); + } + }); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * Removes {@link GenericDocument}s from the index by URI. + * + * @param request Request containing URIs to be removed. + * @param executor Executor on which to invoke the callback. + * @param callback Callback to receive the pending result of performing this operation. The keys + * of the returned {@link AppSearchBatchResult} are the input URIs. The values + * are {@code null} on success, or a failed {@link AppSearchResult} otherwise. + * URIs that are not found will return a failed {@link AppSearchResult} with a + * result code of {@link AppSearchResult#RESULT_NOT_FOUND}. + * Or {@link BatchResultCallback#onSystemError} will be invoked with an + * {@link AppSearchException} if an error occurred in AppSearch initialization + * or a cause {@link Throwable} if other error occurred in AppSearch service. + */ + public void removeByUri( + @NonNull RemoveByUriRequest request, + @NonNull @CallbackExecutor Executor executor, + @NonNull BatchResultCallback<String, Void> callback) { + Objects.requireNonNull(request); + Objects.requireNonNull(executor); + Objects.requireNonNull(callback); + try { + mService.removeByUri(mDatabaseName, request.getNamespace(), + new ArrayList<>(request.getUris()), + new IAppSearchBatchResultCallback.Stub() { + public void onResult(AppSearchBatchResult result) { + executor.execute(() -> callback.onResult(result)); + } + + public void onSystemError(ParcelableException exception) { + executor.execute(() -> callback.onSystemError(exception.getCause())); + } + }); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + // TODO(b/162450968) port query() and SearchResults.java to platform. + // TODO(b/162450968) port removeByQuery() to platform. +} diff --git a/apex/appsearch/framework/java/android/app/appsearch/BatchResultCallback.java b/apex/appsearch/framework/java/android/app/appsearch/BatchResultCallback.java new file mode 100644 index 000000000000..1689e02c7ce4 --- /dev/null +++ b/apex/appsearch/framework/java/android/app/appsearch/BatchResultCallback.java @@ -0,0 +1,47 @@ +/* + * 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 android.app.appsearch; + +/** + * The callback interface to return {@link AppSearchBatchResult}. + * + * @param <KeyType> The type of the keys for {@link AppSearchBatchResult#getSuccesses} and + * {@link AppSearchBatchResult#getFailures}. + * @param <ValueType> The type of result objects associated with the keys. + * @hide + */ +public interface BatchResultCallback<KeyType, ValueType> { + + /** + * Called when {@link AppSearchBatchResult} results are ready. + * + * @param result The result of the executed request. + */ + void onResult(AppSearchBatchResult<KeyType, ValueType> result); + + + /** + * Called when a system error occurred. + * + * @param throwable The cause throwable. + */ + default void onSystemError(Throwable throwable) { + if (throwable != null) { + throw new RuntimeException(throwable); + } + } +} diff --git a/core/proto/android/stats/mediaprovider/mediaprovider_enums.proto b/apex/appsearch/framework/java/android/app/appsearch/IAppSearchBatchResultCallback.aidl index 138782bf5d19..b1bbd18b98e2 100644 --- a/core/proto/android/stats/mediaprovider/mediaprovider_enums.proto +++ b/apex/appsearch/framework/java/android/app/appsearch/IAppSearchBatchResultCallback.aidl @@ -1,11 +1,11 @@ -/* - * Copyright (C) 2019 The Android Open Source Project +/** + * 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 + * 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, @@ -13,18 +13,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +package android.app.appsearch; -syntax = "proto2"; -package android.stats.mediaprovider; -option java_multiple_files = true; +import android.app.appsearch.AppSearchBatchResult; +import android.os.ParcelableException; -enum VolumeType { - // Volume is unknown - UNKNOWN = 0; - // Volume is MediaStore.VOLUME_INTERNAL - INTERNAL = 1; - // Volume is MediaStore.VOLUME_EXTERNAL_PRIMARY - EXTERNAL_PRIMARY = 2; - // Volume is non-primary external storage - EXTERNAL_OTHER = 3; -} +/** {@hide} */ +oneway interface IAppSearchBatchResultCallback { + void onResult(in AppSearchBatchResult result); + void onSystemError(in ParcelableException exception); +}
\ No newline at end of file diff --git a/apex/appsearch/framework/java/android/app/appsearch/IAppSearchManager.aidl b/apex/appsearch/framework/java/android/app/appsearch/IAppSearchManager.aidl index 01260ea193f6..4a981022da73 100644 --- a/apex/appsearch/framework/java/android/app/appsearch/IAppSearchManager.aidl +++ b/apex/appsearch/framework/java/android/app/appsearch/IAppSearchManager.aidl @@ -17,10 +17,12 @@ package android.app.appsearch; import android.os.Bundle; +import android.app.appsearch.AppSearchBatchResult; +import android.app.appsearch.AppSearchResult; +import android.app.appsearch.IAppSearchBatchResultCallback; +import android.app.appsearch.IAppSearchResultCallback; import com.android.internal.infra.AndroidFuture; -parcelable AppSearchResult; -parcelable AppSearchBatchResult; parcelable SearchResults; /** {@hide} */ @@ -32,14 +34,14 @@ interface IAppSearchManager { * @param schemaBundles List of AppSearchSchema bundles. * @param forceOverride Whether to apply the new schema even if it is incompatible. All * incompatible documents will be deleted. - * @param callback {@link AndroidFuture}<{@link AppSearchResult}<{@link Void}>>. - * The results of the call. + * @param callback {@link IAppSearchResultCallback#onResult} will be called with an + * {@link AppSearchResult}<{@link Void}>. */ void setSchema( in String databaseName, in List<Bundle> schemaBundles, boolean forceOverride, - in AndroidFuture<AppSearchResult> callback); + in IAppSearchResultCallback callback); /** * Inserts documents into the index. @@ -47,16 +49,16 @@ interface IAppSearchManager { * @param databaseName The name of the database where this document lives. * @param documentBundes List of GenericDocument bundles. * @param callback - * {@link AndroidFuture}<{@link AppSearchBatchResult}<{@link String}, {@link Void}>>. - * If the call fails to start, {@code callback} will be completed exceptionally. Otherwise, - * {@code callback} will be completed with an + * If the call fails to start, {@link IAppSearchBatchResultCallback#onSystemError} + * will be called with the cause throwable. Otherwise, + * {@link IAppSearchBatchResultCallback#onResult} will be called with an * {@link AppSearchBatchResult}<{@link String}, {@link Void}> * where the keys are document URIs, and the values are {@code null}. */ void putDocuments( in String databaseName, in List<Bundle> documentBundles, - in AndroidFuture<AppSearchBatchResult> callback); + in IAppSearchBatchResultCallback callback); /** * Retrieves documents from the index. @@ -65,9 +67,9 @@ interface IAppSearchManager { * @param namespace The namespace this document resides in. * @param uris The URIs of the documents to retrieve * @param callback - * {@link AndroidFuture}<{@link AppSearchBatchResult}<{@link String}, {@link Bundle}>>. - * If the call fails to start, {@code callback} will be completed exceptionally. Otherwise, - * {@code callback} will be completed with an + * If the call fails to start, {@link IAppSearchBatchResultCallback#onSystemError} + * will be called with the cause throwable. Otherwise, + * {@link IAppSearchBatchResultCallback#onResult} will be called with an * {@link AppSearchBatchResult}<{@link String}, {@link Bundle}> * where the keys are document URIs, and the values are Document bundles. */ @@ -75,7 +77,7 @@ interface IAppSearchManager { in String databaseName, in String namespace, in List<String> uris, - in AndroidFuture<AppSearchBatchResult> callback); + in IAppSearchBatchResultCallback callback); /** * Searches a document based on a given specifications. @@ -98,9 +100,9 @@ interface IAppSearchManager { * @param namespace Namespace of the document to remove. * @param uris The URIs of the documents to delete * @param callback - * {@link AndroidFuture}<{@link AppSearchBatchResult}<{@link String}, {@link Void}>>. - * If the call fails to start, {@code callback} will be completed exceptionally. Otherwise, - * {@code callback} will be completed with an + * If the call fails to start, {@link IAppSearchBatchResultCallback#onSystemError} + * will be called with the cause throwable. Otherwise, + * {@link IAppSearchBatchResultCallback#onResult} will be called with an * {@link AppSearchBatchResult}<{@link String}, {@link Void}> * where the keys are document URIs. If a document doesn't exist, it will be reported as a * failure where the {@code throwable} is {@code null}. @@ -109,7 +111,7 @@ interface IAppSearchManager { in String databaseName, in String namespace, in List<String> uris, - in AndroidFuture<AppSearchBatchResult> callback); + in IAppSearchBatchResultCallback callback); /** * Removes documents by given query. @@ -124,4 +126,12 @@ interface IAppSearchManager { in String queryExpression, in Bundle searchSpecBundle, in AndroidFuture<AppSearchResult> callback); + + /** + * Creates and initializes AppSearchImpl for the calling app. + * + * @param callback {@link IAppSearchResultCallback#onResult} will be called with an + * {@link AppSearchResult}<{@link Void}>. + */ + void initialize(in IAppSearchResultCallback callback); } diff --git a/core/proto/android/bluetooth/hfp/enums.proto b/apex/appsearch/framework/java/android/app/appsearch/IAppSearchResultCallback.aidl index d286e4b64d67..27729a5ad058 100644 --- a/core/proto/android/bluetooth/hfp/enums.proto +++ b/apex/appsearch/framework/java/android/app/appsearch/IAppSearchResultCallback.aidl @@ -1,11 +1,11 @@ -/* - * Copyright 2018 The Android Open Source Project +/** + * 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 + * 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, @@ -13,16 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +package android.app.appsearch; -syntax = "proto2"; -package android.bluetooth.hfp; +import android.app.appsearch.AppSearchResult; +import android.os.ParcelableException; -option java_outer_classname = "BluetoothHfpProtoEnums"; -option java_multiple_files = true; - -enum ScoCodec { - SCO_CODEC_UNKNOWN = 0; - SCO_CODEC_CVSD = 1; - // Default codec behind Wide Band Speech - SCO_CODEC_MSBC = 2; +/** {@hide} */ +oneway interface IAppSearchResultCallback { + void onResult(in AppSearchResult result); }
\ No newline at end of file diff --git a/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java b/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java index 1dfde528e69b..8269799d5a0d 100644 --- a/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java +++ b/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java @@ -15,27 +15,32 @@ */ package com.android.server.appsearch; +import static android.app.appsearch.AppSearchResult.throwableToFailedResult; + import android.annotation.NonNull; import android.app.appsearch.AppSearchBatchResult; import android.app.appsearch.AppSearchResult; import android.app.appsearch.AppSearchSchema; import android.app.appsearch.GenericDocument; +import android.app.appsearch.IAppSearchBatchResultCallback; import android.app.appsearch.IAppSearchManager; +import android.app.appsearch.IAppSearchResultCallback; import android.app.appsearch.SearchResultPage; import android.app.appsearch.SearchSpec; -import android.app.appsearch.exceptions.AppSearchException; import android.content.Context; import android.os.Binder; import android.os.Bundle; +import android.os.ParcelableException; +import android.os.RemoteException; import android.os.UserHandle; import android.util.ArraySet; +import android.util.Log; import com.android.internal.infra.AndroidFuture; import com.android.internal.util.Preconditions; import com.android.server.SystemService; import com.android.server.appsearch.external.localstorage.AppSearchImpl; -import java.io.IOException; import java.util.List; import java.util.Set; @@ -61,10 +66,9 @@ public class AppSearchManagerService extends SystemService { @NonNull String databaseName, @NonNull List<Bundle> schemaBundles, boolean forceOverride, - @NonNull AndroidFuture<AppSearchResult> callback) { + @NonNull IAppSearchResultCallback callback) { Preconditions.checkNotNull(databaseName); Preconditions.checkNotNull(schemaBundles); - Preconditions.checkNotNull(callback); int callingUid = Binder.getCallingUidOrThrow(); int callingUserId = UserHandle.getUserId(callingUid); final long callingIdentity = Binder.clearCallingIdentity(); @@ -76,9 +80,10 @@ public class AppSearchManagerService extends SystemService { AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId); databaseName = rewriteDatabaseNameWithUid(databaseName, callingUid); impl.setSchema(databaseName, schemas, forceOverride); - callback.complete(AppSearchResult.newSuccessfulResult(/*result=*/ null)); + invokeCallbackOnResult(callback, + AppSearchResult.newSuccessfulResult(/*result=*/ null)); } catch (Throwable t) { - callback.complete(throwableToFailedResult(t)); + invokeCallbackOnError(callback, t); } finally { Binder.restoreCallingIdentity(callingIdentity); } @@ -88,7 +93,7 @@ public class AppSearchManagerService extends SystemService { public void putDocuments( @NonNull String databaseName, @NonNull List<Bundle> documentBundles, - @NonNull AndroidFuture<AppSearchBatchResult> callback) { + @NonNull IAppSearchBatchResultCallback callback) { Preconditions.checkNotNull(databaseName); Preconditions.checkNotNull(documentBundles); Preconditions.checkNotNull(callback); @@ -96,22 +101,24 @@ public class AppSearchManagerService extends SystemService { int callingUserId = UserHandle.getUserId(callingUid); final long callingIdentity = Binder.clearCallingIdentity(); try { - AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId); - databaseName = rewriteDatabaseNameWithUid(databaseName, callingUid); AppSearchBatchResult.Builder<String, Void> resultBuilder = new AppSearchBatchResult.Builder<>(); + AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId); + databaseName = rewriteDatabaseNameWithUid(databaseName, callingUid); for (int i = 0; i < documentBundles.size(); i++) { GenericDocument document = new GenericDocument(documentBundles.get(i)); try { + // TODO(b/173451571): reduce burden of binder thread by enqueue request onto + // a separate thread. impl.putDocument(databaseName, document); resultBuilder.setSuccess(document.getUri(), /*result=*/ null); } catch (Throwable t) { resultBuilder.setResult(document.getUri(), throwableToFailedResult(t)); } } - callback.complete(resultBuilder.build()); + invokeCallbackOnResult(callback, resultBuilder.build()); } catch (Throwable t) { - callback.completeExceptionally(t); + invokeCallbackOnError(callback, t); } finally { Binder.restoreCallingIdentity(callingIdentity); } @@ -119,7 +126,8 @@ public class AppSearchManagerService extends SystemService { @Override public void getDocuments(@NonNull String databaseName, @NonNull String namespace, - @NonNull List<String> uris, @NonNull AndroidFuture<AppSearchBatchResult> callback) { + @NonNull List<String> uris, + @NonNull IAppSearchBatchResultCallback callback) { Preconditions.checkNotNull(databaseName); Preconditions.checkNotNull(namespace); Preconditions.checkNotNull(uris); @@ -128,10 +136,10 @@ public class AppSearchManagerService extends SystemService { int callingUserId = UserHandle.getUserId(callingUid); final long callingIdentity = Binder.clearCallingIdentity(); try { - AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId); - databaseName = rewriteDatabaseNameWithUid(databaseName, callingUid); AppSearchBatchResult.Builder<String, Bundle> resultBuilder = new AppSearchBatchResult.Builder<>(); + AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId); + databaseName = rewriteDatabaseNameWithUid(databaseName, callingUid); for (int i = 0; i < uris.size(); i++) { String uri = uris.get(i); try { @@ -141,9 +149,9 @@ public class AppSearchManagerService extends SystemService { resultBuilder.setResult(uri, throwableToFailedResult(t)); } } - callback.complete(resultBuilder.build()); + invokeCallbackOnResult(callback, resultBuilder.build()); } catch (Throwable t) { - callback.completeExceptionally(t); + invokeCallbackOnError(callback, t); } finally { Binder.restoreCallingIdentity(callingIdentity); } @@ -182,19 +190,19 @@ public class AppSearchManagerService extends SystemService { @Override public void removeByUri(@NonNull String databaseName, @NonNull String namespace, - List<String> uris, AndroidFuture<AppSearchBatchResult> callback) { + @NonNull List<String> uris, + @NonNull IAppSearchBatchResultCallback callback) { Preconditions.checkNotNull(databaseName); - Preconditions.checkNotNull(namespace); Preconditions.checkNotNull(uris); Preconditions.checkNotNull(callback); int callingUid = Binder.getCallingUidOrThrow(); int callingUserId = UserHandle.getUserId(callingUid); final long callingIdentity = Binder.clearCallingIdentity(); + AppSearchBatchResult.Builder<String, Void> resultBuilder = + new AppSearchBatchResult.Builder<>(); try { AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId); databaseName = rewriteDatabaseNameWithUid(databaseName, callingUid); - AppSearchBatchResult.Builder<String, Void> resultBuilder = - new AppSearchBatchResult.Builder<>(); for (int i = 0; i < uris.size(); i++) { String uri = uris.get(i); try { @@ -204,9 +212,9 @@ public class AppSearchManagerService extends SystemService { resultBuilder.setResult(uri, throwableToFailedResult(t)); } } - callback.complete(resultBuilder.build()); + invokeCallbackOnResult(callback, resultBuilder.build()); } catch (Throwable t) { - callback.completeExceptionally(t); + invokeCallbackOnError(callback, t); } finally { Binder.restoreCallingIdentity(callingIdentity); } @@ -237,6 +245,21 @@ public class AppSearchManagerService extends SystemService { } } + @Override + public void initialize(@NonNull IAppSearchResultCallback callback) { + int callingUid = Binder.getCallingUidOrThrow(); + int callingUserId = UserHandle.getUserId(callingUid); + final long callingIdentity = Binder.clearCallingIdentity(); + try { + ImplInstanceManager.getInstance(getContext(), callingUserId); + invokeCallbackOnResult(callback, AppSearchResult.newSuccessfulResult(null)); + } catch (Throwable t) { + invokeCallbackOnError(callback, t); + } finally { + Binder.restoreCallingIdentity(callingIdentity); + } + } + /** * Rewrites the database name by adding a prefix of unique name for the given uid. * @@ -256,23 +279,51 @@ public class AppSearchManagerService extends SystemService { return callingUidName + CALLING_NAME_DATABASE_DELIMITER + databaseName; } - private <ValueType> AppSearchResult<ValueType> throwableToFailedResult( - @NonNull Throwable t) { - if (t instanceof AppSearchException) { - return ((AppSearchException) t).toAppSearchResult(); + /** Invokes the {@link IAppSearchResultCallback} with the result. */ + private void invokeCallbackOnResult(IAppSearchResultCallback callback, + AppSearchResult result) { + try { + callback.onResult(result); + } catch (RemoteException e) { + Log.d(TAG, "Unable to send result to the callback", e); } + } - @AppSearchResult.ResultCode int resultCode; - if (t instanceof IllegalStateException) { - resultCode = AppSearchResult.RESULT_INTERNAL_ERROR; - } else if (t instanceof IllegalArgumentException) { - resultCode = AppSearchResult.RESULT_INVALID_ARGUMENT; - } else if (t instanceof IOException) { - resultCode = AppSearchResult.RESULT_IO_ERROR; - } else { - resultCode = AppSearchResult.RESULT_UNKNOWN_ERROR; + /** Invokes the {@link IAppSearchBatchResultCallback} with the result. */ + private void invokeCallbackOnResult(IAppSearchBatchResultCallback callback, + AppSearchBatchResult result) { + try { + callback.onResult(result); + } catch (RemoteException e) { + Log.d(TAG, "Unable to send result to the callback", e); + } + } + + /** + * Invokes the {@link IAppSearchResultCallback} with an throwable. + * + * <p>The throwable is convert to a {@link AppSearchResult}; + */ + private void invokeCallbackOnError(IAppSearchResultCallback callback, Throwable throwable) { + try { + callback.onResult(throwableToFailedResult(throwable)); + } catch (RemoteException e) { + Log.d(TAG, "Unable to send result to the callback", e); + } + } + + /** + * Invokes the {@link IAppSearchBatchResultCallback} with an throwable. + * + * <p>The throwable is converted to {@link ParcelableException}. + */ + private void invokeCallbackOnError(IAppSearchBatchResultCallback callback, + Throwable throwable) { + try { + callback.onSystemError(new ParcelableException(throwable)); + } catch (RemoteException e) { + Log.d(TAG, "Unable to send error to the callback", e); } - return AppSearchResult.newFailedResult(resultCode, t.getMessage()); } } } diff --git a/apex/jobscheduler/framework/java/com/android/server/usage/AppStandbyInternal.java b/apex/jobscheduler/framework/java/com/android/server/usage/AppStandbyInternal.java index 398ccb69fbe8..2ce85ee57205 100644 --- a/apex/jobscheduler/framework/java/com/android/server/usage/AppStandbyInternal.java +++ b/apex/jobscheduler/framework/java/com/android/server/usage/AppStandbyInternal.java @@ -3,7 +3,6 @@ package com.android.server.usage; import android.annotation.NonNull; import android.annotation.UserIdInt; import android.app.usage.AppStandbyInfo; -import android.app.usage.UsageEvents; import android.app.usage.UsageStatsManager.StandbyBuckets; import android.app.usage.UsageStatsManager.SystemForcedReasons; import android.content.Context; @@ -68,8 +67,6 @@ public interface AppStandbyInternal { */ void postOneTimeCheckIdleStates(); - void reportEvent(UsageEvents.Event event, int userId); - void setLastJobRunTime(String packageName, int userId, long elapsedRealtime); long getTimeSinceLastJobRun(String packageName, int userId); diff --git a/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java index 1157ee905b86..0b0923a67de6 100644 --- a/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java +++ b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java @@ -62,6 +62,7 @@ import android.app.usage.AppStandbyInfo; import android.app.usage.UsageEvents; import android.app.usage.UsageStatsManager.StandbyBuckets; import android.app.usage.UsageStatsManager.SystemForcedReasons; +import android.app.usage.UsageStatsManagerInternal; import android.appwidget.AppWidgetManager; import android.content.BroadcastReceiver; import android.content.ContentResolver; @@ -128,9 +129,10 @@ import java.util.concurrent.CountDownLatch; * Manages the standby state of an app, listening to various events. * * Unit test: - atest com.android.server.usage.AppStandbyControllerTests + * atest com.android.server.usage.AppStandbyControllerTests */ -public class AppStandbyController implements AppStandbyInternal { +public class AppStandbyController + implements AppStandbyInternal, UsageStatsManagerInternal.UsageEventListener { private static final String TAG = "AppStandbyController"; // Do not submit with true. @@ -468,10 +470,21 @@ public class AppStandbyController implements AppStandbyInternal { @VisibleForTesting void setAppIdleEnabled(boolean enabled) { + // Don't call out to USM with the lock held. Also, register the listener before we + // change our internal state so no events fall through the cracks. + final UsageStatsManagerInternal usmi = + LocalServices.getService(UsageStatsManagerInternal.class); + if (enabled) { + usmi.registerListener(this); + } else { + usmi.unregisterListener(this); + } + synchronized (mAppIdleLock) { if (mAppIdleEnabled != enabled) { final boolean oldParoleState = isInParole(); mAppIdleEnabled = enabled; + if (isInParole() != oldParoleState) { postParoleStateChanged(); } @@ -489,6 +502,11 @@ public class AppStandbyController implements AppStandbyInternal { mInjector.onBootPhase(phase); if (phase == PHASE_SYSTEM_SERVICES_READY) { Slog.d(TAG, "Setting app idle enabled state"); + + if (mAppIdleEnabled) { + LocalServices.getService(UsageStatsManagerInternal.class).registerListener(this); + } + // Observe changes to the threshold ConstantsObserver settingsObserver = new ConstantsObserver(mHandler); settingsObserver.start(); @@ -912,8 +930,10 @@ public class AppStandbyController implements AppStandbyInternal { } } - @Override - public void reportEvent(UsageEvents.Event event, int userId) { + /** + * Callback to inform listeners of a new event. + */ + public void onUsageEvent(int userId, @NonNull UsageEvents.Event event) { if (!mAppIdleEnabled) return; final int eventType = event.getEventType(); if ((eventType == UsageEvents.Event.ACTIVITY_RESUMED diff --git a/cmds/statsd/Android.bp b/cmds/statsd/Android.bp index d225f966c39d..6aad82fda915 100644 --- a/cmds/statsd/Android.bp +++ b/cmds/statsd/Android.bp @@ -14,34 +14,6 @@ // limitations under the License. // -// ========================================================== -// Build the library for use on the host -// ========================================================== -cc_library_host_shared { - name: "libstats_proto_host", - srcs: [ - "src/atoms.proto", - "src/atom_field_options.proto", - ], - - shared_libs: [ - "libplatformprotos", - ], - - proto: { - type: "full", - export_proto_headers: true, - include_dirs: [ - "external/protobuf/src", - ], - }, - - export_shared_lib_headers: [ - "libplatformprotos", - ] - -} - cc_defaults { name: "statsd_defaults", @@ -277,9 +249,8 @@ cc_test { // atom_field_options.proto needs field_options.proto, but that is // not included in libprotobuf-cpp-lite, so compile it here. ":libprotobuf-internal-protos", + ":libstats_internal_protos", - "src/atom_field_options.proto", - "src/atoms.proto", "src/shell/shell_data.proto", "src/stats_log.proto", "tests/AlarmMonitor_test.cpp", @@ -346,7 +317,10 @@ cc_test { proto: { type: "lite", - include_dirs: ["external/protobuf/src"], + include_dirs: [ + "external/protobuf/src", + "frameworks/proto_logging/stats", + ], }, } @@ -363,6 +337,7 @@ cc_benchmark { // atom_field_options.proto needs field_options.proto, but that is // not included in libprotobuf-cpp-lite, so compile it here. ":libprotobuf-internal-protos", + ":libstats_internal_protos", "benchmark/duration_metric_benchmark.cpp", "benchmark/filter_value_benchmark.cpp", @@ -372,14 +347,15 @@ cc_benchmark { "benchmark/main.cpp", "benchmark/metric_util.cpp", "benchmark/stats_write_benchmark.cpp", - "src/atom_field_options.proto", - "src/atoms.proto", "src/stats_log.proto", ], proto: { type: "lite", - include_dirs: ["external/protobuf/src"], + include_dirs: [ + "external/protobuf/src", + "frameworks/proto_logging/stats", + ], }, cflags: [ @@ -411,11 +387,14 @@ java_library { sdk_version: "core_current", proto: { type: "lite", - include_dirs: ["external/protobuf/src"], + include_dirs: [ + "external/protobuf/src", + "frameworks/proto_logging/stats", + ], }, srcs: [ - "src/atoms.proto", + ":libstats_atoms_proto", "src/shell/shell_config.proto", "src/shell/shell_data.proto", "src/stats_log.proto", @@ -437,10 +416,13 @@ java_library { proto: { type: "nano", output_params: ["store_unknown_fields=true"], - include_dirs: ["external/protobuf/src"], + include_dirs: [ + "external/protobuf/src", + "frameworks/proto_logging/stats", + ], }, srcs: [ - "src/atoms.proto", + ":libstats_atoms_proto", "src/shell/shell_config.proto", "src/shell/shell_data.proto", "src/stats_log.proto", diff --git a/cmds/statsd/src/OWNERS b/cmds/statsd/src/OWNERS new file mode 100644 index 000000000000..0f3ddf7388d9 --- /dev/null +++ b/cmds/statsd/src/OWNERS @@ -0,0 +1,6 @@ +# Temporary OWNERS Block to assist with migration +# bug: 167962588 +per-file *atoms.proto = set noparent +per-file *atom_field_options.proto = set noparent +per-file *atoms.proto = baligh@google.com, yro@google.com, singhtejinder@google.com, jeffreyhuang@google.com +per-file *atom_field_options.proto = baligh@google.com, yro@google.com, singhtejinder@google.com, jeffreyhuang@google.com diff --git a/cmds/statsd/src/atom_field_options.proto b/cmds/statsd/src/atom_field_options.proto deleted file mode 100644 index ff5717e4fa78..000000000000 --- a/cmds/statsd/src/atom_field_options.proto +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -syntax = "proto2"; - -package android.os.statsd; -option java_package = "com.android.os"; -option java_multiple_files = true; -option java_outer_classname = "AtomFieldOptions"; - -import "google/protobuf/descriptor.proto"; - -// Used to annotate an atom that represents a state change. A state change atom must have exactly -// ONE exclusive state field, and any number of primary key fields. For example, message -// UidProcessStateChanged { -// optional int32 uid = 1 [(state_field_option).primary_field = true]; -// optional android.app.ProcessStateEnum state = -// 2 [(state_field_option).exclusive_state = true]; -// } -// Each UidProcessStateChanged atom event represents a state change for a specific uid. -// A new state automatically overrides the previous state. -// -// If the atom has 2 or more primary fields, it means the combination of the -// primary fields are the primary key. -// For example: -// message ThreadStateChanged { -// optional int32 pid = 1 [(state_field_option).primary_field = true]; -// optional int32 tid = 2 [(state_field_option).primary_field = true]; -// optional int32 state = 3 [(state_field_option).exclusive_state = true]; -// } -// -// Sometimes, there is no primary key field, when the state is GLOBAL. -// For example, -// message ScreenStateChanged { -// optional android.view.DisplayStateEnum state = -// 1 [(state_field_option).exclusive_state = true]; -// } -// -// For state atoms with attribution chain, sometimes the primary key is the first uid in the chain. -// For example: -// message AudioStateChanged { -// repeated AttributionNode attribution_node = 1 -// [(stateFieldOption).primary_field_first_uid = true]; -// -// enum State { -// OFF = 0; -// ON = 1; -// // RESET indicates all audio stopped. Used when it (re)starts (e.g. after it crashes). -// RESET = 2; -// } -// optional State state = 2 [(stateFieldOption).exclusive_state = true]; -// } -message StateAtomFieldOption { - // Fields that represent the key that the state belongs to. - // Used on simple proto fields. Do not use on attribution chains. - optional bool primary_field = 1 [default = false]; - - // The field that represents the state. It's an exclusive state. - optional bool exclusive_state = 2 [default = false]; - - // Used on an attribution chain field to indicate that the first uid is the - // primary field. - optional bool primary_field_first_uid = 3 [default = false]; - - // Note: We cannot annotate directly on the enums because many enums are imported from other - // proto files in the platform. proto-lite cc library does not support annotations unfortunately - - // Knowing the default state value allows state trackers to remove entries that become the - // default state. If there is no default value specified, the default value is unknown, and all - // states will be tracked in memory. - optional int32 default_state_value = 4; - - // A reset state signals all states go to default value. For example, BLE reset means all active - // BLE scans are to be turned off. - optional int32 trigger_state_reset_value = 5; - - // If the state change needs to count nesting. - optional bool nested = 6 [default = true]; -} - -// Used to generate StatsLog.write APIs. -enum LogMode { - MODE_UNSET = 0; - // Log fields as their actual types e.g., all primary data types. - // Or fields that are hardcoded in stats_log_api_gen tool e.g., AttributionNode - MODE_AUTOMATIC = 1; - // Log fields in their proto binary format. These fields will not be parsed in statsd - MODE_BYTES = 2; -} - -extend google.protobuf.FieldOptions { - // Flags to decorate an atom that presents a state change. - optional StateAtomFieldOption state_field_option = 50000; - - // Flags to decorate the uid fields in an atom. - optional bool is_uid = 50001 [default = false]; - - optional LogMode log_mode = 50002 [default = MODE_AUTOMATIC]; - - repeated string module = 50004; - - optional bool truncate_timestamp = 50005 [default = false]; -} diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto deleted file mode 100644 index 8363e9f3191d..000000000000 --- a/cmds/statsd/src/atoms.proto +++ /dev/null @@ -1,12608 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -syntax = "proto2"; - -package android.os.statsd; -option java_package = "com.android.os"; -option java_outer_classname = "AtomsProto"; - -import "frameworks/base/cmds/statsd/src/atom_field_options.proto"; -import "frameworks/base/core/proto/android/app/enums.proto"; -import "frameworks/base/core/proto/android/app/job/enums.proto"; -import "frameworks/base/core/proto/android/app/settings_enums.proto"; -import "frameworks/base/core/proto/android/app/media_output_enum.proto"; -import "frameworks/base/core/proto/android/app/tvsettings_enums.proto"; -import "frameworks/base/core/proto/android/bluetooth/a2dp/enums.proto"; -import "frameworks/base/core/proto/android/bluetooth/enums.proto"; -import "frameworks/base/core/proto/android/bluetooth/hci/enums.proto"; -import "frameworks/base/core/proto/android/bluetooth/hfp/enums.proto"; -import "frameworks/base/core/proto/android/bluetooth/smp/enums.proto"; -import "frameworks/base/core/proto/android/debug/enums.proto"; -import "frameworks/base/core/proto/android/hardware/biometrics/enums.proto"; -import "frameworks/base/core/proto/android/hardware/sensor/assist/enums.proto"; -import "frameworks/base/core/proto/android/net/networkcapabilities.proto"; -import "frameworks/base/core/proto/android/os/enums.proto"; -import "frameworks/base/core/proto/android/server/connectivity/data_stall_event.proto"; -import "frameworks/base/core/proto/android/server/enums.proto"; -import "frameworks/base/core/proto/android/server/job/enums.proto"; -import "frameworks/base/core/proto/android/server/location/enums.proto"; -import "frameworks/base/core/proto/android/service/procstats_enum.proto"; -import "frameworks/base/core/proto/android/service/usb.proto"; -import "frameworks/base/core/proto/android/stats/camera/camera.proto"; -import "frameworks/base/core/proto/android/stats/connectivity/network_stack.proto"; -import "frameworks/base/core/proto/android/stats/connectivity/tethering.proto"; -import "frameworks/base/core/proto/android/stats/dnsresolver/dns_resolver.proto"; -import "frameworks/base/core/proto/android/stats/devicepolicy/device_policy.proto"; -import "frameworks/base/core/proto/android/stats/devicepolicy/device_policy_enums.proto"; -import "frameworks/base/core/proto/android/stats/docsui/docsui_enums.proto"; -import "frameworks/base/core/proto/android/stats/accessibility/accessibility_enums.proto"; -import "frameworks/base/core/proto/android/stats/enums.proto"; -import "frameworks/base/core/proto/android/stats/hdmi/enums.proto"; -import "frameworks/base/core/proto/android/stats/intelligence/enums.proto"; -import "frameworks/base/core/proto/android/stats/launcher/launcher.proto"; -import "frameworks/base/core/proto/android/stats/location/location_enums.proto"; -import "frameworks/base/core/proto/android/stats/mediametrics/mediametrics.proto"; -import "frameworks/base/core/proto/android/stats/mediaprovider/mediaprovider_enums.proto"; -import "frameworks/base/core/proto/android/stats/storage/storage_enums.proto"; -import "frameworks/base/core/proto/android/stats/style/style_enums.proto"; -import "frameworks/base/core/proto/android/stats/sysui/notification_enums.proto"; -import "frameworks/base/core/proto/android/stats/tls/enums.proto"; -import "frameworks/base/core/proto/android/stats/tv/tif_enums.proto"; -import "frameworks/base/core/proto/android/telecomm/enums.proto"; -import "frameworks/base/core/proto/android/telephony/enums.proto"; -import "frameworks/base/core/proto/android/view/enums.proto"; -import "frameworks/base/core/proto/android/wifi/enums.proto"; -import "frameworks/base/core/proto/android/stats/textclassifier/textclassifier_enums.proto"; -import "frameworks/base/core/proto/android/stats/otaupdate/updateengine_enums.proto"; - -/** - * The primary atom class. This message defines all of the available - * raw stats log events from the Android system, also known as "atoms." - * - * This field contains a single oneof with all of the available messages. - * The stats-log-api-gen tool runs as part of the Android build and - * generates the android.util.StatsLog class, which contains the constants - * and methods that Android uses to log. - * - * This Atom class is not actually built into the Android system. - * Instead, statsd on Android constructs these messages synthetically, - * in the format defined here and in stats_log.proto. - */ -message Atom { - // Pushed atoms start at 2. - oneof pushed { - // For StatsLog reasons, 1 is illegal and will not work. Must start at 2. - BleScanStateChanged ble_scan_state_changed = 2 - [(module) = "bluetooth", (module) = "statsdtest"]; - ProcessStateChanged process_state_changed = 3 [(module) = "framework"]; - BleScanResultReceived ble_scan_result_received = 4 [(module) = "bluetooth"]; - SensorStateChanged sensor_state_changed = - 5 [(module) = "framework", (module) = "statsdtest"]; - GpsScanStateChanged gps_scan_state_changed = 6 [(module) = "framework"]; - SyncStateChanged sync_state_changed = 7 [(module) = "framework", (module) = "statsdtest"]; - ScheduledJobStateChanged scheduled_job_state_changed = - 8 [(module) = "framework", (module) = "statsdtest"]; - ScreenBrightnessChanged screen_brightness_changed = - 9 [(module) = "framework", (module) = "statsdtest"]; - WakelockStateChanged wakelock_state_changed = - 10 [(module) = "framework", (module) = "statsdtest"]; - LongPartialWakelockStateChanged long_partial_wakelock_state_changed = - 11 [(module) = "framework"]; - MobileRadioPowerStateChanged mobile_radio_power_state_changed = - 12 [(module) = "framework", (truncate_timestamp) = true]; - WifiRadioPowerStateChanged wifi_radio_power_state_changed = 13 [(module) = "framework"]; - ActivityManagerSleepStateChanged activity_manager_sleep_state_changed = - 14 [(module) = "framework"]; - MemoryFactorStateChanged memory_factor_state_changed = 15 [(module) = "framework"]; - ExcessiveCpuUsageReported excessive_cpu_usage_reported = 16 [(module) = "framework"]; - CachedKillReported cached_kill_reported = 17 [(module) = "framework"]; - ProcessMemoryStatReported process_memory_stat_reported = 18 [(module) = "framework"]; - LauncherUIChanged launcher_event = 19 [(module) = "sysui"]; - BatterySaverModeStateChanged battery_saver_mode_state_changed = - 20 [(module) = "framework", (module) = "statsdtest"]; - DeviceIdleModeStateChanged device_idle_mode_state_changed = 21 [(module) = "framework"]; - DeviceIdlingModeStateChanged device_idling_mode_state_changed = 22 [(module) = "framework"]; - AudioStateChanged audio_state_changed = - 23 [(module) = "framework", (truncate_timestamp) = true]; - MediaCodecStateChanged media_codec_state_changed = 24 [(module) = "framework"]; - CameraStateChanged camera_state_changed = 25 [(module) = "framework"]; - FlashlightStateChanged flashlight_state_changed = 26 [(module) = "framework"]; - UidProcessStateChanged uid_process_state_changed = - 27 [(module) = "framework", (module) = "statsdtest"]; - ProcessLifeCycleStateChanged process_life_cycle_state_changed = - 28 [(module) = "framework", (module) = "statsdtest"]; - ScreenStateChanged screen_state_changed = - 29 [(module) = "framework", (module) = "statsdtest"]; - BatteryLevelChanged battery_level_changed = - 30 [(module) = "framework", (module) = "statsdtest"]; - ChargingStateChanged charging_state_changed = 31 [(module) = "framework"]; - PluggedStateChanged plugged_state_changed = 32 - [(module) = "framework", (module) = "statsdtest"]; - InteractiveStateChanged interactive_state_changed = 33 [(module) = "framework"]; - TouchEventReported touch_event_reported = 34; - WakeupAlarmOccurred wakeup_alarm_occurred = 35 [(module) = "framework"]; - KernelWakeupReported kernel_wakeup_reported = 36 [(module) = "framework"]; - WifiLockStateChanged wifi_lock_state_changed = 37 [(module) = "wifi"]; - WifiSignalStrengthChanged wifi_signal_strength_changed = 38 [(module) = "wifi"]; - WifiScanStateChanged wifi_scan_state_changed = 39 [(module) = "wifi"]; - PhoneSignalStrengthChanged phone_signal_strength_changed = - 40 [(module) = "framework", (truncate_timestamp) = true]; - SettingChanged setting_changed = 41 [(module) = "framework"]; - ActivityForegroundStateChanged activity_foreground_state_changed = - 42 [(module) = "framework", (module) = "statsdtest"]; - IsolatedUidChanged isolated_uid_changed = - 43 [(module) = "framework", (module) = "statsd", (module) = "statsdtest"]; - PacketWakeupOccurred packet_wakeup_occurred = 44 [(module) = "framework"]; - WallClockTimeShifted wall_clock_time_shifted = 45 [(module) = "framework"]; - AnomalyDetected anomaly_detected = 46 [(module) = "statsd"]; - AppBreadcrumbReported app_breadcrumb_reported = 47 [(module) = "statsd"]; - AppStartOccurred app_start_occurred = 48 [(module) = "framework", (module) = "statsdtest"]; - AppStartCanceled app_start_canceled = 49 [(module) = "framework"]; - AppStartFullyDrawn app_start_fully_drawn = 50 [(module) = "framework"]; - LmkKillOccurred lmk_kill_occurred = 51 [(module) = "lmkd"]; - PictureInPictureStateChanged picture_in_picture_state_changed = 52 [(module) = "framework"]; - WifiMulticastLockStateChanged wifi_multicast_lock_state_changed = 53 [(module) = "wifi"]; - LmkStateChanged lmk_state_changed = 54 [(module) = "lmkd"]; - AppStartMemoryStateCaptured app_start_memory_state_captured = 55 [(module) = "framework"]; - ShutdownSequenceReported shutdown_sequence_reported = 56 [(module) = "framework"]; - BootSequenceReported boot_sequence_reported = 57; - DaveyOccurred davey_occurred = 58 [(module) = "statsd", deprecated = true]; - OverlayStateChanged overlay_state_changed = - 59 [(module) = "framework", (module) = "statsdtest"]; - ForegroundServiceStateChanged foreground_service_state_changed - = 60 [(module) = "framework"]; - CallStateChanged call_state_changed = - 61 [(module) = "telecom", (truncate_timestamp) = true]; - KeyguardStateChanged keyguard_state_changed = 62 [(module) = "sysui"]; - KeyguardBouncerStateChanged keyguard_bouncer_state_changed = 63 [(module) = "sysui"]; - KeyguardBouncerPasswordEntered keyguard_bouncer_password_entered = 64 [(module) = "sysui"]; - AppDied app_died = 65 [(module) = "framework"]; - ResourceConfigurationChanged resource_configuration_changed = 66 [(module) = "framework"]; - BluetoothEnabledStateChanged bluetooth_enabled_state_changed = 67 [(module) = "framework"]; - BluetoothConnectionStateChanged bluetooth_connection_state_changed = - 68 [(module) = "bluetooth"]; - GpsSignalQualityChanged gps_signal_quality_changed = 69 [(module) = "framework"]; - UsbConnectorStateChanged usb_connector_state_changed = 70 [(module) = "framework"]; - SpeakerImpedanceReported speaker_impedance_reported = 71; - HardwareFailed hardware_failed = 72; - PhysicalDropDetected physical_drop_detected = 73; - ChargeCyclesReported charge_cycles_reported = 74; - MobileConnectionStateChanged mobile_connection_state_changed = 75 [(module) = "telephony"]; - MobileRadioTechnologyChanged mobile_radio_technology_changed = 76 [(module) = "telephony"]; - UsbDeviceAttached usb_device_attached = 77 [(module) = "framework"]; - AppCrashOccurred app_crash_occurred = 78 [(module) = "framework", (module) = "statsdtest"]; - ANROccurred anr_occurred = 79 [(module) = "framework"]; - WTFOccurred wtf_occurred = 80 [(module) = "framework"]; - LowMemReported low_mem_reported = 81 [(module) = "framework"]; - GenericAtom generic_atom = 82; - KeyValuePairsAtom key_value_pairs_atom = 83 [(module) = "framework", (module) = "statsd"]; - VibratorStateChanged vibrator_state_changed = 84 [(module) = "framework"]; - DeferredJobStatsReported deferred_job_stats_reported = 85 [(module) = "framework"]; - ThermalThrottlingStateChanged thermal_throttling = 86 [deprecated=true]; - BiometricAcquired biometric_acquired = 87 [(module) = "framework"]; - BiometricAuthenticated biometric_authenticated = 88 [(module) = "framework"]; - BiometricErrorOccurred biometric_error_occurred = 89 [(module) = "framework"]; - UiEventReported ui_event_reported = 90 [(module) = "framework", (module) = "sysui"]; - BatteryHealthSnapshot battery_health_snapshot = 91; - SlowIo slow_io = 92; - BatteryCausedShutdown battery_caused_shutdown = 93; - PhoneServiceStateChanged phone_service_state_changed = 94 [(module) = "framework"]; - PhoneStateChanged phone_state_changed = 95 [(module) = "framework"]; - UserRestrictionChanged user_restriction_changed = 96; - SettingsUIChanged settings_ui_changed = 97 [(module) = "settings"]; - ConnectivityStateChanged connectivity_state_changed = 98 [(module) = "framework"]; - // TODO: service state change is very noisy shortly after boot, as well - // as at other transitions - coming out of doze, device plugged in, etc. - // Consider removing this if it becomes a problem - ServiceStateChanged service_state_changed = 99 [(module) = "framework"]; - ServiceLaunchReported service_launch_reported = 100 [(module) = "framework"]; - FlagFlipUpdateOccurred flag_flip_update_occurred = 101 [(module) = "framework"]; - BinaryPushStateChanged binary_push_state_changed = 102 [(module) = "statsd"]; - DevicePolicyEvent device_policy_event = 103 [(module) = "framework"]; - DocsUIFileOperationCanceledReported docs_ui_file_op_canceled = 104 [(module) = "docsui"]; - DocsUIFileOperationCopyMoveModeReported docs_ui_file_op_copy_move_mode_reported = - 105 [(module) = "docsui"]; - DocsUIFileOperationFailureReported docs_ui_file_op_failure = 106 [(module) = "docsui"]; - DocsUIFileOperationReported docs_ui_provider_file_op = 107 [(module) = "docsui"]; - DocsUIInvalidScopedAccessRequestReported docs_ui_invalid_scoped_access_request = - 108 [(module) = "docsui"]; - DocsUILaunchReported docs_ui_launch_reported = 109 [(module) = "docsui"]; - DocsUIRootVisitedReported docs_ui_root_visited = 110 [(module) = "docsui"]; - DocsUIStartupMsReported docs_ui_startup_ms = 111 [(module) = "docsui"]; - DocsUIUserActionReported docs_ui_user_action_reported = 112 [(module) = "docsui"]; - WifiEnabledStateChanged wifi_enabled_state_changed = 113 [(module) = "framework"]; - WifiRunningStateChanged wifi_running_state_changed = 114 - [(module) = "framework", deprecated = true]; - AppCompacted app_compacted = 115 [(module) = "framework"]; - NetworkDnsEventReported network_dns_event_reported = 116 [(module) = "resolv"]; - DocsUIPickerLaunchedFromReported docs_ui_picker_launched_from_reported = - 117 [(module) = "docsui"]; - DocsUIPickResultReported docs_ui_pick_result_reported = 118 [(module) = "docsui"]; - DocsUISearchModeReported docs_ui_search_mode_reported = 119 [(module) = "docsui"]; - DocsUISearchTypeReported docs_ui_search_type_reported = 120 [(module) = "docsui"]; - DataStallEvent data_stall_event = 121 [(module) = "network_stack"]; - RescuePartyResetReported rescue_party_reset_reported = 122 [(module) = "framework"]; - SignedConfigReported signed_config_reported = 123 [(module) = "framework"]; - GnssNiEventReported gnss_ni_event_reported = 124 [(module) = "framework"]; - BluetoothLinkLayerConnectionEvent bluetooth_link_layer_connection_event = - 125 [(module) = "bluetooth"]; - BluetoothAclConnectionStateChanged bluetooth_acl_connection_state_changed = - 126 [(module) = "bluetooth"]; - BluetoothScoConnectionStateChanged bluetooth_sco_connection_state_changed = - 127 [(module) = "bluetooth"]; - AppDowngraded app_downgraded = 128 [(module) = "framework"]; - AppOptimizedAfterDowngraded app_optimized_after_downgraded = 129; - LowStorageStateChanged low_storage_state_changed = 130 [(module) = "framework"]; - GnssNfwNotificationReported gnss_nfw_notification_reported = 131 [(module) = "framework"]; - GnssConfigurationReported gnss_configuration_reported = 132 [(module) = "framework"]; - UsbPortOverheatEvent usb_port_overheat_event_reported = 133; - NfcErrorOccurred nfc_error_occurred = 134 [(module) = "nfc"]; - NfcStateChanged nfc_state_changed = 135 [(module) = "nfc"]; - NfcBeamOccurred nfc_beam_occurred = 136 [(module) = "nfc"]; - NfcCardemulationOccurred nfc_cardemulation_occurred = 137 [(module) = "nfc"]; - NfcTagOccurred nfc_tag_occurred = 138 [(module) = "nfc"]; - NfcHceTransactionOccurred nfc_hce_transaction_occurred = 139 [(module) = "nfc"]; - SeStateChanged se_state_changed = 140 [(module) = "secure_element"]; - SeOmapiReported se_omapi_reported = 141 [(module) = "secure_element"]; - BroadcastDispatchLatencyReported broadcast_dispatch_latency_reported = - 142 [(module) = "framework"]; - AttentionManagerServiceResultReported attention_manager_service_result_reported = - 143 [(module) = "framework"]; - AdbConnectionChanged adb_connection_changed = 144 [(module) = "framework"]; - SpeechDspStatReported speech_dsp_stat_reported = 145; - UsbContaminantReported usb_contaminant_reported = 146 [(module) = "framework"]; - WatchdogRollbackOccurred watchdog_rollback_occurred = - 147 [(module) = "framework", (module) = "statsd"]; - BiometricSystemHealthIssueDetected biometric_system_health_issue_detected = - 148 [(module) = "framework"]; - BubbleUIChanged bubble_ui_changed = 149 [(module) = "framework"]; - ScheduledJobConstraintChanged scheduled_job_constraint_changed = - 150 [(module) = "framework"]; - BluetoothActiveDeviceChanged bluetooth_active_device_changed = - 151 [(module) = "bluetooth"]; - BluetoothA2dpPlaybackStateChanged bluetooth_a2dp_playback_state_changed = - 152 [(module) = "bluetooth"]; - BluetoothA2dpCodecConfigChanged bluetooth_a2dp_codec_config_changed = - 153 [(module) = "bluetooth"]; - BluetoothA2dpCodecCapabilityChanged bluetooth_a2dp_codec_capability_changed = - 154 [(module) = "bluetooth"]; - BluetoothA2dpAudioUnderrunReported bluetooth_a2dp_audio_underrun_reported = - 155 [(module) = "bluetooth"]; - BluetoothA2dpAudioOverrunReported bluetooth_a2dp_audio_overrun_reported = - 156 [(module) = "bluetooth"]; - BluetoothDeviceRssiReported bluetooth_device_rssi_reported = - 157 [(module) = "bluetooth"]; - BluetoothDeviceFailedContactCounterReported - bluetooth_device_failed_contact_counter_reported = 158 [(module) = "bluetooth"]; - BluetoothDeviceTxPowerLevelReported bluetooth_device_tx_power_level_reported = - 159 [(module) = "bluetooth"]; - BluetoothHciTimeoutReported bluetooth_hci_timeout_reported = - 160 [(module) = "bluetooth"]; - BluetoothQualityReportReported bluetooth_quality_report_reported = - 161 [(module) = "bluetooth"]; - BluetoothDeviceInfoReported bluetooth_device_info_reported = - 162 [(module) = "bluetooth"]; - BluetoothRemoteVersionInfoReported bluetooth_remote_version_info_reported = - 163 [(module) = "bluetooth"]; - BluetoothSdpAttributeReported bluetooth_sdp_attribute_reported = - 164 [(module) = "bluetooth"]; - BluetoothBondStateChanged bluetooth_bond_state_changed = - 165 [(module) = "bluetooth"]; - BluetoothClassicPairingEventReported bluetooth_classic_pairing_event_reported = - 166 [(module) = "bluetooth"]; - BluetoothSmpPairingEventReported bluetooth_smp_pairing_event_reported = - 167 [(module) = "bluetooth"]; - ScreenTimeoutExtensionReported screen_timeout_extension_reported = - 168 [(module) = "framework"]; - ProcessStartTime process_start_time = 169 [(module) = "framework"]; - PermissionGrantRequestResultReported permission_grant_request_result_reported = - 170 [(module) = "permissioncontroller"]; - BluetoothSocketConnectionStateChanged bluetooth_socket_connection_state_changed = 171; - DeviceIdentifierAccessDenied device_identifier_access_denied = - 172 [(module) = "telephony_common"]; - BubbleDeveloperErrorReported bubble_developer_error_reported = 173 [(module) = "framework"]; - AssistGestureStageReported assist_gesture_stage_reported = 174 [(module) = "sysui"]; - AssistGestureFeedbackReported assist_gesture_feedback_reported = 175 [(module) = "sysui"]; - AssistGestureProgressReported assist_gesture_progress_reported = 176 [(module) = "sysui"]; - TouchGestureClassified touch_gesture_classified = 177 [(module) = "framework"]; - HiddenApiUsed hidden_api_used = 178 [(module) = "framework"]; - StyleUIChanged style_ui_changed = 179 [(module) = "sysui"]; - PrivacyIndicatorsInteracted privacy_indicators_interacted = - 180 [(module) = "permissioncontroller"]; - AppInstallOnExternalStorageReported app_install_on_external_storage_reported = - 181 [(module) = "framework"]; - NetworkStackReported network_stack_reported = 182 [(module) = "network_stack"]; - AppMovedStorageReported app_moved_storage_reported = 183 [(module) = "framework"]; - BiometricEnrolled biometric_enrolled = 184 [(module) = "framework"]; - SystemServerWatchdogOccurred system_server_watchdog_occurred = 185 [(module) = "framework"]; - TombStoneOccurred tomb_stone_occurred = 186 [(module) = "framework"]; - BluetoothClassOfDeviceReported bluetooth_class_of_device_reported = - 187 [(module) = "bluetooth"]; - IntelligenceEventReported intelligence_event_reported = - 188 [(module) = "intelligence"]; - ThermalThrottlingSeverityStateChanged thermal_throttling_severity_state_changed = - 189 [(module) = "framework"]; - RoleRequestResultReported role_request_result_reported = - 190 [(module) = "permissioncontroller"]; - MediametricsAudiopolicyReported mediametrics_audiopolicy_reported = 191; - MediametricsAudiorecordReported mediametrics_audiorecord_reported = 192; - MediametricsAudiothreadReported mediametrics_audiothread_reported = 193; - MediametricsAudiotrackReported mediametrics_audiotrack_reported = 194; - MediametricsCodecReported mediametrics_codec_reported = 195; - MediametricsDrmWidevineReported mediametrics_drm_widevine_reported = 196; - MediametricsExtractorReported mediametrics_extractor_reported = 197; - MediametricsMediadrmReported mediametrics_mediadrm_reported = 198; - MediametricsNuPlayerReported mediametrics_nuplayer_reported = 199; - MediametricsRecorderReported mediametrics_recorder_reported = 200; - MediametricsDrmManagerReported mediametrics_drmmanager_reported = 201; - CarPowerStateChanged car_power_state_changed = 203 [(module) = "car"]; - GarageModeInfo garage_mode_info = 204 [(module) = "car"]; - TestAtomReported test_atom_reported = 205 [(module) = "cts"]; - ContentCaptureCallerMismatchReported content_capture_caller_mismatch_reported = - 206 [(module) = "framework"]; - ContentCaptureServiceEvents content_capture_service_events = 207 [(module) = "framework"]; - ContentCaptureSessionEvents content_capture_session_events = 208 [(module) = "framework"]; - ContentCaptureFlushed content_capture_flushed = 209 [(module) = "framework"]; - LocationManagerApiUsageReported location_manager_api_usage_reported = - 210 [(module) = "framework"]; - ReviewPermissionsFragmentResultReported review_permissions_fragment_result_reported = - 211 [(module) = "permissioncontroller"]; - RuntimePermissionsUpgradeResult runtime_permissions_upgrade_result = - 212 [(module) = "permissioncontroller"]; - GrantPermissionsActivityButtonActions grant_permissions_activity_button_actions = - 213 [(module) = "permissioncontroller"]; - LocationAccessCheckNotificationAction location_access_check_notification_action = - 214 [(module) = "permissioncontroller"]; - AppPermissionFragmentActionReported app_permission_fragment_action_reported = - 215 [(module) = "permissioncontroller"]; - AppPermissionFragmentViewed app_permission_fragment_viewed = - 216 [(module) = "permissioncontroller"]; - AppPermissionsFragmentViewed app_permissions_fragment_viewed = - 217 [(module) = "permissioncontroller"]; - PermissionAppsFragmentViewed permission_apps_fragment_viewed = - 218 [(module) = "permissioncontroller"]; - TextSelectionEvent text_selection_event = 219 [(module) = "textclassifier"]; - TextLinkifyEvent text_linkify_event = 220 [(module) = "textclassifier"]; - ConversationActionsEvent conversation_actions_event = 221 [(module) = "textclassifier"]; - LanguageDetectionEvent language_detection_event = 222 [(module) = "textclassifier"]; - ExclusionRectStateChanged exclusion_rect_state_changed = 223 [(module) = "framework"]; - BackGesture back_gesture_reported_reported = 224 [(module) = "sysui"]; - UpdateEngineUpdateAttemptReported update_engine_update_attempt_reported = 225; - UpdateEngineSuccessfulUpdateReported update_engine_successful_update_reported = 226; - CameraActionEvent camera_action_event = 227 [(module) = "framework"]; - AppCompatibilityChangeReported app_compatibility_change_reported = - 228 [(module) = "framework"]; - PerfettoUploaded perfetto_uploaded = 229 [(module) = "perfetto"]; - VmsClientConnectionStateChanged vms_client_connection_state_changed = - 230 [(module) = "car"]; - MediaProviderScanOccurred media_provider_scan_occurred = 233 [(module) = "mediaprovider"]; - MediaContentDeleted media_content_deleted = 234 [(module) = "mediaprovider"]; - MediaProviderPermissionRequested media_provider_permission_requested = - 235 [(module) = "mediaprovider"]; - MediaProviderSchemaChanged media_provider_schema_changed = 236 [(module) = "mediaprovider"]; - MediaProviderIdleMaintenanceFinished media_provider_idle_maintenance_finished = - 237 [(module) = "mediaprovider"]; - RebootEscrowRecoveryReported reboot_escrow_recovery_reported = 238 [(module) = "framework"]; - BootTimeEventDuration boot_time_event_duration_reported = 239 [(module) = "framework"]; - BootTimeEventElapsedTime boot_time_event_elapsed_time_reported = - 240 [(module) = "framework"]; - BootTimeEventUtcTime boot_time_event_utc_time_reported = 241; - BootTimeEventErrorCode boot_time_event_error_code_reported = 242 [(module) = "framework"]; - UserspaceRebootReported userspace_reboot_reported = 243 [(module) = "framework"]; - NotificationReported notification_reported = 244 [(module) = "framework"]; - NotificationPanelReported notification_panel_reported = 245 [(module) = "sysui"]; - NotificationChannelModified notification_channel_modified = 246 [(module) = "framework"]; - IntegrityCheckResultReported integrity_check_result_reported = 247 [(module) = "framework"]; - IntegrityRulesPushed integrity_rules_pushed = 248 [(module) = "framework"]; - CellBroadcastMessageReported cb_message_reported = - 249 [(module) = "cellbroadcast"]; - CellBroadcastMessageError cb_message_error = - 250 [(module) = "cellbroadcast"]; - WifiHealthStatReported wifi_health_stat_reported = 251 [(module) = "wifi"]; - WifiFailureStatReported wifi_failure_stat_reported = 252 [(module) = "wifi"]; - WifiConnectionResultReported wifi_connection_result_reported = 253 [(module) = "wifi"]; - AppFreezeChanged app_freeze_changed = 254 [(module) = "framework"]; - SnapshotMergeReported snapshot_merge_reported = 255; - ForegroundServiceAppOpSessionEnded foreground_service_app_op_session_ended = - 256 [(module) = "framework"]; - DisplayJankReported display_jank_reported = 257; - AppStandbyBucketChanged app_standby_bucket_changed = 258 [(module) = "framework"]; - SharesheetStarted sharesheet_started = 259 [(module) = "framework"]; - RankingSelected ranking_selected = 260 [(module) = "framework", (module) = "sysui"]; - TvSettingsUIInteracted tvsettings_ui_interacted = 261 [(module) = "tv_settings"]; - LauncherStaticLayout launcher_snapshot = 262 [(module) = "sysui"]; - PackageInstallerV2Reported package_installer_v2_reported = 263 [(module) = "framework"]; - UserLifecycleJourneyReported user_lifecycle_journey_reported = 264 [(module) = "framework"]; - UserLifecycleEventOccurred user_lifecycle_event_occurred = 265 [(module) = "framework"]; - AccessibilityShortcutReported accessibility_shortcut_reported = - 266 [(module) = "framework"]; - AccessibilityServiceReported accessibility_service_reported = 267 [(module) = "settings"]; - DocsUIDragAndDropReported docs_ui_drag_and_drop_reported = 268 [(module) = "docsui"]; - AppUsageEventOccurred app_usage_event_occurred = 269 [(module) = "framework"]; - AutoRevokeNotificationClicked auto_revoke_notification_clicked = - 270 [(module) = "permissioncontroller"]; - AutoRevokeFragmentAppViewed auto_revoke_fragment_app_viewed = - 271 [(module) = "permissioncontroller"]; - AutoRevokedAppInteraction auto_revoked_app_interaction = - 272 [(module) = "permissioncontroller", (module) = "settings"]; - AppPermissionGroupsFragmentAutoRevokeAction - app_permission_groups_fragment_auto_revoke_action = - 273 [(module) = "permissioncontroller"]; - EvsUsageStatsReported evs_usage_stats_reported = 274 [(module) = "evs"]; - AudioPowerUsageDataReported audio_power_usage_data_reported = 275; - TvTunerStateChanged tv_tuner_state_changed = 276 [(module) = "framework"]; - MediaOutputOpSwitchReported mediaoutput_op_switch_reported = - 277 [(module) = "settings"]; - CellBroadcastMessageFiltered cb_message_filtered = - 278 [(module) = "cellbroadcast"]; - TvTunerDvrStatus tv_tuner_dvr_status = 279 [(module) = "framework"]; - TvCasSessionOpenStatus tv_cas_session_open_status = - 280 [(module) = "framework"]; - AssistantInvocationReported assistant_invocation_reported = 281 [(module) = "framework"]; - DisplayWakeReported display_wake_reported = 282 [(module) = "framework"]; - CarUserHalModifyUserRequestReported car_user_hal_modify_user_request_reported = - 283 [(module) = "car"]; - CarUserHalModifyUserResponseReported car_user_hal_modify_user_response_reported = - 284 [(module) = "car"]; - CarUserHalPostSwitchResponseReported car_user_hal_post_switch_response_reported = - 285 [(module) = "car"]; - CarUserHalInitialUserInfoRequestReported car_user_hal_initial_user_info_request_reported = - 286 [(module) = "car"]; - CarUserHalInitialUserInfoResponseReported car_user_hal_initial_user_info_response_reported = - 287 [(module) = "car"]; - CarUserHalUserAssociationRequestReported car_user_hal_user_association_request_reported = - 288 [(module) = "car"]; - CarUserHalSetUserAssociationResponseReported car_user_hal_set_user_association_response_reported = - 289 [(module) = "car"]; - NetworkIpProvisioningReported network_ip_provisioning_reported = - 290 [(module) = "network_stack"]; - NetworkDhcpRenewReported network_dhcp_renew_reported = 291 [(module) = "network_stack"]; - NetworkValidationReported network_validation_reported = 292 [(module) = "network_stack"]; - NetworkStackQuirkReported network_stack_quirk_reported = 293 [(module) = "network_stack"]; - MediametricsAudioRecordDeviceUsageReported mediametrics_audiorecorddeviceusage_reported = - 294; - MediametricsAudioThreadDeviceUsageReported mediametrics_audiothreaddeviceusage_reported = - 295; - MediametricsAudioTrackDeviceUsageReported mediametrics_audiotrackdeviceusage_reported = - 296; - MediametricsAudioDeviceConnectionReported mediametrics_audiodeviceconnection_reported = - 297; - BlobCommitted blob_committed = 298 [(module) = "framework"]; - BlobLeased blob_leased = 299 [(module) = "framework"]; - BlobOpened blob_opened = 300 [(module) = "framework"]; - ContactsProviderStatusReported contacts_provider_status_reported = 301; - KeystoreKeyEventReported keystore_key_event_reported = 302; - NetworkTetheringReported network_tethering_reported = - 303 [(module) = "network_tethering"]; - ImeTouchReported ime_touch_reported = 304 [(module) = "sysui"]; - UIInteractionFrameInfoReported ui_interaction_frame_info_reported = - 305 [(module) = "framework"]; - UIActionLatencyReported ui_action_latency_reported = 306 [(module) = "framework"]; - WifiDisconnectReported wifi_disconnect_reported = 307 [(module) = "wifi"]; - WifiConnectionStateChanged wifi_connection_state_changed = 308 [(module) = "wifi"]; - HdmiCecActiveSourceChanged hdmi_cec_active_source_changed = 309 [(module) = "framework"]; - HdmiCecMessageReported hdmi_cec_message_reported = 310 [(module) = "framework"]; - AirplaneMode airplane_mode = 311 [(module) = "telephony"]; - ModemRestart modem_restart = 312 [(module) = "telephony"]; - CarrierIdMismatchReported carrier_id_mismatch_reported = 313 [(module) = "telephony"]; - CarrierIdTableUpdated carrier_id_table_updated = 314 [(module) = "telephony"]; - DataStallRecoveryReported data_stall_recovery_reported = 315 [(module) = "telephony"]; - MediametricsMediaParserReported mediametrics_mediaparser_reported = 316; - TlsHandshakeReported tls_handshake_reported = 317 [(module) = "conscrypt"]; - TextClassifierApiUsageReported text_classifier_api_usage_reported = 318 [(module) = "textclassifier"]; - KilledAppStatsReported killed_app_stats_reported = 319 [(module) = "carwatchdogd"]; - MediametricsPlaybackReported mediametrics_playback_reported = 320; - MediaNetworkInfoChanged media_network_info_changed = 321; - MediaPlaybackStateChanged media_playback_state_changed = 322; - MediaPlaybackErrorReported media_playback_error_reported = 323; - MediaPlaybackTrackChanged media_playback_track_changed = 324; - WifiScanReported wifi_scan_reported = 325 [(module) = "wifi"]; - WifiPnoScanReported wifi_pno_scan_reported = 326 [(module) = "wifi"]; - TifTuneStateChanged tif_tune_changed = 327 [(module) = "framework"]; - AutoRotateReported auto_rotate_reported = 328 [(module) = "framework"]; - - // StatsdStats tracks platform atoms with ids upto 500. - // Update StatsdStats::kMaxPushedAtomId when atom ids here approach that value. - } - - // Pulled events will start at field 10000. - // Next: 10092 - oneof pulled { - WifiBytesTransfer wifi_bytes_transfer = 10000 [(module) = "framework"]; - WifiBytesTransferByFgBg wifi_bytes_transfer_by_fg_bg = 10001 [(module) = "framework"]; - MobileBytesTransfer mobile_bytes_transfer = - 10002 [(module) = "framework", (truncate_timestamp) = true]; - MobileBytesTransferByFgBg mobile_bytes_transfer_by_fg_bg = - 10003 [(module) = "framework", (truncate_timestamp) = true]; - BluetoothBytesTransfer bluetooth_bytes_transfer = 10006 [(module) = "framework"]; - KernelWakelock kernel_wakelock = 10004 [(module) = "framework"]; - SubsystemSleepState subsystem_sleep_state = 10005 [(module) = "statsdtest"]; - CpuTimePerFreq cpu_time_per_freq = 10008 [(module) = "framework"]; - CpuTimePerUid cpu_time_per_uid = 10009 [(module) = "framework", (module) = "statsdtest"]; - CpuTimePerUidFreq cpu_time_per_uid_freq = - 10010 [(module) = "framework", (module) = "statsd"]; - WifiActivityInfo wifi_activity_info = 10011 [(module) = "framework"]; - ModemActivityInfo modem_activity_info = 10012 [(module) = "framework"]; - BluetoothActivityInfo bluetooth_activity_info = 10007 [(module) = "framework"]; - ProcessMemoryState process_memory_state = 10013 [(module) = "framework"]; - SystemElapsedRealtime system_elapsed_realtime = 10014 [(module) = "framework"]; - SystemUptime system_uptime = 10015 [(module) = "framework"]; - CpuActiveTime cpu_active_time = 10016 [(module) = "framework", (module) = "statsdtest"]; - CpuClusterTime cpu_cluster_time = 10017 [(module) = "framework"]; - DiskSpace disk_space = 10018 [deprecated=true, (module) = "statsdtest"]; - RemainingBatteryCapacity remaining_battery_capacity = 10019 [(module) = "framework"]; - FullBatteryCapacity full_battery_capacity = 10020 [(module) = "framework"]; - Temperature temperature = 10021 [(module) = "framework", (module) = "statsdtest"]; - BinderCalls binder_calls = 10022 [(module) = "framework", (module) = "statsd"]; - BinderCallsExceptions binder_calls_exceptions = 10023 [(module) = "framework"]; - LooperStats looper_stats = 10024 [(module) = "framework", (module) = "statsd"]; - DiskStats disk_stats = 10025 [(module) = "framework"]; - DirectoryUsage directory_usage = 10026 [(module) = "framework"]; - AppSize app_size = 10027 [(module) = "framework"]; - CategorySize category_size = 10028 [(module) = "framework"]; - ProcStats proc_stats = 10029 [(module) = "framework"]; - BatteryVoltage battery_voltage = 10030 [(module) = "framework"]; - NumFingerprintsEnrolled num_fingerprints_enrolled = 10031 [(module) = "framework"]; - DiskIo disk_io = 10032 [(module) = "framework"]; - PowerProfile power_profile = 10033 [(module) = "framework"]; - ProcStatsPkgProc proc_stats_pkg_proc = 10034 [(module) = "framework"]; - ProcessCpuTime process_cpu_time = 10035 [(module) = "framework"]; - CpuTimePerThreadFreq cpu_time_per_thread_freq = 10037 [(module) = "framework"]; - OnDevicePowerMeasurement on_device_power_measurement = 10038; - DeviceCalculatedPowerUse device_calculated_power_use = 10039 [(module) = "framework"]; - DeviceCalculatedPowerBlameUid device_calculated_power_blame_uid = - 10040 [(module) = "framework"]; - DeviceCalculatedPowerBlameOther device_calculated_power_blame_other = - 10041 [(module) = "framework"]; - ProcessMemoryHighWaterMark process_memory_high_water_mark = 10042 [(module) = "framework"]; - BatteryLevel battery_level = 10043 [(module) = "framework"]; - BuildInformation build_information = 10044 [(module) = "framework"]; - BatteryCycleCount battery_cycle_count = 10045 [(module) = "framework"]; - DebugElapsedClock debug_elapsed_clock = 10046 [(module) = "framework"]; - DebugFailingElapsedClock debug_failing_elapsed_clock = 10047 [(module) = "framework"]; - NumFacesEnrolled num_faces_enrolled = 10048 [(module) = "framework"]; - RoleHolder role_holder = 10049 [(module) = "framework"]; - DangerousPermissionState dangerous_permission_state = 10050 [(module) = "framework"]; - TrainInfo train_info = 10051 [(module) = "statsd"]; - TimeZoneDataInfo time_zone_data_info = 10052 [(module) = "framework"]; - ExternalStorageInfo external_storage_info = 10053 [(module) = "framework"]; - GpuStatsGlobalInfo gpu_stats_global_info = 10054; - GpuStatsAppInfo gpu_stats_app_info = 10055; - SystemIonHeapSize system_ion_heap_size = 10056 [deprecated = true, (module) = "framework"]; - AppsOnExternalStorageInfo apps_on_external_storage_info = 10057 [(module) = "framework"]; - FaceSettings face_settings = 10058 [(module) = "framework"]; - CoolingDevice cooling_device = 10059 [(module) = "framework"]; - AppOps app_ops = 10060 [(module) = "framework"]; - ProcessSystemIonHeapSize process_system_ion_heap_size = 10061 [(module) = "framework"]; - SurfaceflingerStatsGlobalInfo surfaceflinger_stats_global_info = 10062; - SurfaceflingerStatsLayerInfo surfaceflinger_stats_layer_info = 10063; - ProcessMemorySnapshot process_memory_snapshot = 10064 [(module) = "framework"]; - VmsClientStats vms_client_stats = 10065 [(module) = "car"]; - NotificationRemoteViews notification_remote_views = 10066 [(module) = "framework"]; - DangerousPermissionStateSampled dangerous_permission_state_sampled = - 10067 [(module) = "framework"]; - GraphicsStats graphics_stats = 10068; - RuntimeAppOpAccess runtime_app_op_access = 10069 [(module) = "framework"]; - IonHeapSize ion_heap_size = 10070 [(module) = "framework"]; - PackageNotificationPreferences package_notification_preferences = - 10071 [(module) = "framework"]; - PackageNotificationChannelPreferences package_notification_channel_preferences = - 10072 [(module) = "framework"]; - PackageNotificationChannelGroupPreferences package_notification_channel_group_preferences = - 10073 [(module) = "framework"]; - GnssStats gnss_stats = 10074 [(module) = "framework"]; - AttributedAppOps attributed_app_ops = 10075 [(module) = "framework"]; - VoiceCallSession voice_call_session = 10076 [(module) = "telephony"]; - VoiceCallRatUsage voice_call_rat_usage = 10077 [(module) = "telephony"]; - SimSlotState sim_slot_state = 10078 [(module) = "telephony"]; - SupportedRadioAccessFamily supported_radio_access_family = 10079 [(module) = "telephony"]; - SettingSnapshot setting_snapshot = 10080 [(module) = "framework"]; - BlobInfo blob_info = 10081 [(module) = "framework"]; - DataUsageBytesTransfer data_usage_bytes_transfer = - 10082 [(module) = "framework", (truncate_timestamp) = true]; - BytesTransferByTagAndMetered bytes_transfer_by_tag_and_metered = - 10083 [(module) = "framework", (truncate_timestamp) = true]; - DNDModeProto dnd_mode_rule = 10084 [(module) = "framework"]; - GeneralExternalStorageAccessStats general_external_storage_access_stats = - 10085 [(module) = "mediaprovider"]; - IncomingSms incoming_sms = 10086 [(module) = "telephony"]; - OutgoingSms outgoing_sms = 10087 [(module) = "telephony"]; - CarrierIdTableVersion carrier_id_table_version = 10088 [(module) = "telephony"]; - DataCallSession data_call_session = 10089 [(module) = "telephony"]; - CellularServiceState cellular_service_state = 10090 [(module) = "telephony"]; - CellularDataServiceSwitch cellular_data_service_switch = 10091 [(module) = "telephony"]; - } - - // DO NOT USE field numbers above 100,000 in AOSP. - // Field numbers 100,000 - 199,999 are reserved for non-AOSP (e.g. OEMs) to use. - // Field numbers 200,000 and above are reserved for future use; do not use them at all. - - reserved 10036; -} - -/** - * This proto represents a node of an attribution chain. - * Note: All attribution chains are represented as a repeated field of type - * AttributionNode. It is understood that in such arrays, the order is that - * of calls, that is [A, B, C] if A calls B that calls C. - */ -message AttributionNode { - // The uid for a given element in the attribution chain. - optional int32 uid = 1; - - // The (optional) string tag for an element in the attribution chain. If the - // element has no tag, it is encoded as an empty string. - optional string tag = 2; -} - -message KeyValuePair { - optional int32 key = 1; - oneof value { - int32 value_int = 2; - int64 value_long = 3; - string value_str = 4; - float value_float = 5; - } -} - -message KeyValuePairsAtom { - optional int32 uid = 1; - repeated KeyValuePair pairs = 2; -} - -/* - * ***************************************************************************** - * Below are all of the individual atoms that are logged by Android via statsd. - * - * RULES: - * - The field ids for each atom must start at 1, and count upwards by 1. - * Skipping field ids is not allowed. - * - These form an API, so renaming, renumbering or removing fields is - * not allowed between android releases. (This is not currently enforced, - * but there will be a tool to enforce this restriction). - * - The types must be built-in protocol buffer types, namely, no sub-messages - * are allowed (yet). The bytes type is also not allowed. - * - The CamelCase name of the message type should match the - * underscore_separated name as defined in Atom. - * - If an atom represents work that can be attributed to an app, there can - * be exactly one AttributionChain field. It must be field number 1. - * - A field that is a uid should be a string field, tagged with the [xxx] - * annotation. The generated code on android will be represented by UIDs, - * and those UIDs will be translated in xxx to those strings. - * - * CONVENTIONS: - * - Events are past tense. e.g. ScreenStateChanged, not ScreenStateChange. - * - If there is a UID, it goes first. Think in an object-oriented fashion. - * ***************************************************************************** - */ - -/** - * This atom is deprecated starting in Q. Please use ThermalThrottlingSeverityStateChanged. - * Logs when the Thermal service HAL notifies the throttling start/stop events. - * - * Logged from: - * frameworks/base/services/core/java/com/android/server/stats/StatsCompanionService.java - */ -message ThermalThrottlingStateChanged { - // The type of temperature being reported (CPU, GPU, SKIN, etc) - optional android.os.TemperatureTypeEnum sensor_type = 1; - - // Throttling state, this field is DEPRECATED - enum State { - UNKNOWN = 0; - START = 1; // START indicated that throttling was triggered. - STOP = 2; // STOP indicates that throttling was cleared. - } - optional State state = 2; - - optional float temperature = 3; -} - -/** - * Logs when the screen state changes. - * - * Logged from: - * frameworks/base/services/core/java/com/android/server/am/BatteryStatsService.java - */ -message ScreenStateChanged { - // New screen state, from frameworks/base/core/proto/android/view/enums.proto. - optional android.view.DisplayStateEnum state = 1 - [(state_field_option).exclusive_state = true, (state_field_option).nested = false]; -} - -/** - * Logs that the process state of the uid, as determined by ActivityManager - * (i.e. the highest process state of that uid's processes) has changed. - * - * Logged from: - * frameworks/base/services/core/java/com/android/server/am/BatteryStatsService.java - */ -message UidProcessStateChanged { - optional int32 uid = 1 [(state_field_option).primary_field = true, (is_uid) = true]; - - // The state, from frameworks/base/core/proto/android/app/enums.proto. - optional android.app.ProcessStateEnum state = 2 - [(state_field_option).exclusive_state = true, (state_field_option).nested = false]; -} - -/** - * Logs process state change of a process, as per the activity manager. - * - * Logged from: - * frameworks/base/services/core/java/com/android/server/am/ProcessRecord.java - */ -message ProcessStateChanged { - optional int32 uid = 1; - optional string process_name = 2; - optional string package_name = 3; - // TODO: remove this when validation is done - optional int64 version = 5; - // The state, from frameworks/base/core/proto/android/app/enums.proto. - optional android.app.ProcessStateEnum state = 4; -} - -/** - * Logs when ActivityManagerService sleep state is changed. - * - * Logged from: - * frameworks/base/services/core/java/com/android/server/am/ActivityTaskManagerService.java - */ -message ActivityManagerSleepStateChanged { - // TODO: import frameworks proto - enum State { - UNKNOWN = 0; - ASLEEP = 1; - AWAKE = 2; - } - optional State state = 1 - [(state_field_option).exclusive_state = true, (state_field_option).nested = false]; -} - -/** - * Logs when system memory state changes. - * - * Logged from: - * frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java - */ -message MemoryFactorStateChanged { - // TODO: import frameworks proto - enum State { - MEMORY_UNKNOWN = 0; - NORMAL = 1; // normal. - MODERATE = 2; // moderate memory pressure. - LOW = 3; // low memory. - CRITICAL = 4; // critical memory. - - } - optional State factor = 1 [(state_field_option).exclusive_state = true]; -} - -/** - * Logs when app is using too much cpu, according to ActivityManagerService. - * - * Logged from: - * frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java - */ -message ExcessiveCpuUsageReported { - optional int32 uid = 1; - optional string process_name = 2; - optional string package_name = 3; - // package version. TODO: remove this when validation is done - optional int64 version = 4; -} - -/** - * Logs when a cached process is killed, along with its pss. - * - * Logged from: - * frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java - */ -message CachedKillReported { - optional int32 uid = 1; - optional string process_name = 2; - optional string package_name = 3; - // TODO: remove this when validation is done - optional int64 version = 5; - optional int64 pss = 4; -} - -/** - * Logs the change in wifi health. - * - * Logged from: - * frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiDataStall.java - */ -message WifiHealthStatReported { - enum Band { - UNKNOWN = 0; - // All of 2.4GHz band - BAND_2G = 1; - // Frequencies in the range of [5150, 5250) GHz - BAND_5G_LOW = 2; - // Frequencies in the range of [5250, 5725) GHz - BAND_5G_MIDDLE = 3; - // Frequencies in the range of [5725, 5850) GHz - BAND_5G_HIGH = 4; - // Frequencies in the range of [5925, 6425) GHz - BAND_6G_LOW = 5; - // Frequencies in the range of [6425, 6875) GHz - BAND_6G_MIDDLE = 6; - // Frequencies in the range of [6875, 7125) GHz - BAND_6G_HIGH = 7; - } - // duration this stat is obtained over in milliseconds - optional int32 duration_millis = 1; - // whether wifi is classified as sufficient for the user's data traffic, determined - // by whether the calculated throughput exceeds the average demand within |duration_millis| - optional bool is_sufficient = 2; - // whether cellular data is available - optional bool is_cell_data_available = 3; - // the Band bucket the connected network is on - optional Band band = 4; -} - -/** - * Logged when wifi detects a significant change in connection failure rate. - * - * Logged from: frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiHealthMonitor.java - * - */ -message WifiFailureStatReported { - enum AbnormalityType { - UNKNOWN = 0; - SIGNIFICANT_INCREASE = 1; - SIGNIFICANT_DECREASE = 2; - SIMPLY_HIGH = 3; - } - enum FailureType { - FAILURE_UNKNOWN = 0; - FAILURE_CONNECTION = 1; - FAILURE_ASSOCIATION_REJECTION = 2; - FAILURE_ASSOCIATION_TIMEOUT = 3; - FAILURE_AUTHENTICATION = 4; - FAILURE_NON_LOCAL_DISCONNECTION = 5; - FAILURE_SHORT_CONNECTION_DUE_TO_NON_LOCAL_DISCONNECTION = 6; - } - // Reason for uploading this stat - optional AbnormalityType abnormality_type = 1; - // The particular type of failure - optional FailureType failure_type = 2; - // How many times we have encountered this combination of AbnormalityType and FailureType - optional int32 failure_count = 3; -} - -/** - * Logs whether a Wifi connection attempt was successful and reasons for failure if it wasn't. - * - * Logged from: - * frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiMetrics.java - */ -message WifiConnectionResultReported { - enum FailureCode { - FAILURE_UNKNOWN = 0; - FAILURE_ASSOCIATION_TIMEOUT = 1; - FAILURE_ASSOCIATION_REJECTION = 2; - FAILURE_AUTHENTICATION_GENERAL = 3; - FAILURE_AUTHENTICATION_EAP = 4; - FAILURE_DHCP = 5; - FAILURE_NETWORK_DISCONNECTION = 6; - FAILURE_ROAM_TIMEOUT = 7; - FAILURE_WRONG_PASSWORD = 8; - } - - enum Trigger { - UNKNOWN = 0; - // Connection attempt was initiated manually. - MANUAL = 1; - // Automatic reconnection to the same network as connected previously. - RECONNECT_SAME_NETWORK = 2; - // Automatic reconnection to a saved network, but not the previous one. - AUTOCONNECT_CONFIGURED_NETWORK = 3; - // Automatic first connection attempt after device boot. - AUTOCONNECT_BOOT = 4; - } - - // True represents a successful connection. - optional bool connection_result = 1; - // Reason for the connection failure. - optional FailureCode failure_code = 2; - // Scan RSSI before the connection attempt. - optional int32 rssi = 3; - // Time taken by this connection attempt. - optional int32 connection_attempt_duration_millis = 4; - // Band bucket the connected network is on. - optional android.net.wifi.WifiBandBucket band = 5; - // Authentication type. - optional android.net.wifi.WifiAuthType auth_type = 6; - // What triggered this connection attempt. - optional Trigger trigger = 7; - // Whether this network was used (successfully connected to) previously. - optional bool network_used = 8; - // Time taken from the last successful connection (or device boot if that's the first one). - optional int32 time_since_last_connection_seconds = 9; -} - -/** - * Logs when a Wifi connection drops. - * - * Logged from: - * frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiMetrics.java - */ -message WifiDisconnectReported { - enum FailureCode { - UNKNOWN = 0; - - // Wifi supplicant failure reason codes (IEEE Std 802.11-2016, 9.4.1.7, Table 9-45). - // See ISupplicantStaIfaceCallback.java:ReasonCode - UNSPECIFIED = 1; - PREV_AUTH_NOT_VALID = 2; - DEAUTH_LEAVING = 3; - DISASSOC_DUE_TO_INACTIVITY = 4; - DISASSOC_AP_BUSY = 5; - CLASS2_FRAME_FROM_NONAUTH_STA = 6; - CLASS3_FRAME_FROM_NONASSOC_STA = 7; - DISASSOC_STA_HAS_LEFT = 8; - STA_REQ_ASSOC_WITHOUT_AUTH = 9; - PWR_CAPABILITY_NOT_VALID = 10; - SUPPORTED_CHANNEL_NOT_VALID = 11; - BSS_TRANSITION_DISASSOC = 12; - INVALID_IE = 13; - MICHAEL_MIC_FAILURE = 14; - FOURWAY_HANDSHAKE_TIMEOUT = 15; - GROUP_KEY_UPDATE_TIMEOUT = 16; - IE_IN_4WAY_DIFFERS = 17; - GROUP_CIPHER_NOT_VALID = 18; - PAIRWISE_CIPHER_NOT_VALID = 19; - AKMP_NOT_VALID = 20; - UNSUPPORTED_RSN_IE_VERSION = 21; - INVALID_RSN_IE_CAPAB = 22; - IEEE_802_1X_AUTH_FAILED = 23; - CIPHER_SUITE_REJECTED = 24; - TDLS_TEARDOWN_UNREACHABLE = 25; - TDLS_TEARDOWN_UNSPECIFIED = 26; - SSP_REQUESTED_DISASSOC = 27; - NO_SSP_ROAMING_AGREEMENT = 28; - BAD_CIPHER_OR_AKM = 29; - NOT_AUTHORIZED_THIS_LOCATION = 30; - SERVICE_CHANGE_PRECLUDES_TS = 31; - UNSPECIFIED_QOS_REASON = 32; - NOT_ENOUGH_BANDWIDTH = 33; - DISASSOC_LOW_ACK = 34; - EXCEEDED_TXOP = 35; - STA_LEAVING = 36; - END_TS_BA_DLS = 37; - UNKNOWN_TS_BA = 38; - TIMEOUT = 39; - PEERKEY_MISMATCH = 45; - AUTHORIZED_ACCESS_LIMIT_REACHED = 46; - EXTERNAL_SERVICE_REQUIREMENTS = 47; - INVALID_FT_ACTION_FRAME_COUNT = 48; - INVALID_PMKID = 49; - INVALID_MDE = 50; - INVALID_FTE = 51; - MESH_PEERING_CANCELLED = 52; - MESH_MAX_PEERS = 53; - MESH_CONFIG_POLICY_VIOLATION = 54; - MESH_CLOSE_RCVD = 55; - MESH_MAX_RETRIES = 56; - MESH_CONFIRM_TIMEOUT = 57; - MESH_INVALID_GTK = 58; - MESH_INCONSISTENT_PARAMS = 59; - MESH_INVALID_SECURITY_CAP = 60; - MESH_PATH_ERROR_NO_PROXY_INFO = 61; - MESH_PATH_ERROR_NO_FORWARDING_INFO = 62; - MESH_PATH_ERROR_DEST_UNREACHABLE = 63; - MAC_ADDRESS_ALREADY_EXISTS_IN_MBSS = 64; - MESH_CHANNEL_SWITCH_REGULATORY_REQ = 65; - MESH_CHANNEL_SWITCH_UNSPECIFIED = 66; - - // ClientModeImpl error codes - // Defined in /frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiMetrics.java - IFACE_DESTROYED = 10000; - WIFI_DISABLED = 10001; - SUPPLICANT_DISCONNECTED = 10002; - CONNECTING_WATCHDOG_TIMER = 10003; - ROAM_WATCHDOG_TIMER = 10004; - } - - // How long the session lasted from successful connection to disconnect. - optional int32 connected_duration_seconds = 1; - - // Reason for the disconnect. - optional FailureCode failure_code = 2; - - // Band bucket the connected network was on. - optional android.net.wifi.WifiBandBucket band = 3; - - // Authentication type. - optional android.net.wifi.WifiAuthType auth_type = 4; - - // Last seen RSSI before the disconnect. - optional int32 last_rssi = 5; - - // Last seen link speed before the disconnect. - optional int32 last_link_speed = 6; -} - -/** - * Logs when Wifi connection is established or dropped. - * - * Logged from: - * frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiMetrics.java - */ -message WifiConnectionStateChanged { - optional bool is_connected = 1; - - // Band bucket the connected network was on. - // Filled for both connected and disconnected cases. - optional android.net.wifi.WifiBandBucket band = 2; - - // Authentication type. - // Filled for both connected and disconnected cases. - optional android.net.wifi.WifiAuthType auth_type = 3; -} - -/** - * Logs when memory stats of a process is reported. - * - * Logged from: - * frameworks/base/services/core/java/com/android/server/am/ProcessRecord.java - */ -message ProcessMemoryStatReported { - optional int32 uid = 1; - optional string process_name = 2; - optional string package_name = 3; - //TODO: remove this when validation is done - optional int64 version = 9; - optional int64 pss = 4; - optional int64 uss = 5; - optional int64 rss = 6; - enum Type { - ADD_PSS_INTERNAL_SINGLE = 0; - ADD_PSS_INTERNAL_ALL_MEM = 1; - ADD_PSS_INTERNAL_ALL_POLL = 2; - ADD_PSS_EXTERNAL = 3; - ADD_PSS_EXTERNAL_SLOW = 4; - } - optional Type type = 7; - optional int64 duration_millis = 8; -} - -/** - * Logs that a process started, finished, crashed, or ANRed. - * - * Logged from: - * frameworks/base/services/core/java/com/android/server/am/BatteryStatsService.java - */ -message ProcessLifeCycleStateChanged { - optional int32 uid = 1 [(is_uid) = true]; - - // The process name (usually same as the app name). - optional string process_name = 2; - - // What lifecycle state the process changed to. - // This enum is specific to atoms.proto. - enum State { - FINISHED = 0; - STARTED = 1; - CRASHED = 2; - } - optional State state = 3; -} - -/** - * Logs when the ble scan state changes. - * - * Logged from: - * packages/apps/Bluetooth/src/com/android/bluetooth/gatt/AppScanStats.java - */ -message BleScanStateChanged { - repeated AttributionNode attribution_node = 1 - [(state_field_option).primary_field_first_uid = true]; - - enum State { - OFF = 0; - ON = 1; - // RESET indicates all ble stopped. Used when it (re)starts (e.g. after it crashes). - RESET = 2; - } - optional State state = 2 [ - (state_field_option).exclusive_state = true, - (state_field_option).default_state_value = 0 /* State.OFF */, - (state_field_option).trigger_state_reset_value = 2 /* State.RESET */, - (state_field_option).nested = true - ]; - - // Does the scan have a filter. - optional bool is_filtered = 3 [(state_field_option).primary_field = true]; - // Whether the scan is a CALLBACK_TYPE_FIRST_MATCH scan. Called 'background' scan internally. - optional bool is_first_match = 4 [(state_field_option).primary_field = true]; - // Whether the scan set to piggy-back off the results of other scans (SCAN_MODE_OPPORTUNISTIC). - optional bool is_opportunistic = 5 [(state_field_option).primary_field = true]; -} - -/** - * Logs reporting of a ble scan finding results. - * - * Logged from: - * packages/apps/Bluetooth/src/com/android/bluetooth/gatt/AppScanStats.java - */ -// TODO: Consider also tracking per-scanner-id. -message BleScanResultReceived { - repeated AttributionNode attribution_node = 1; - - // Number of ble scan results returned. - optional int32 num_results = 2; -} - -/** - * Logs when a sensor state changes. - * - * Logged from: - * frameworks/base/services/core/java/com/android/server/am/BatteryStatsService.java - */ -message SensorStateChanged { - repeated AttributionNode attribution_node = 1; - - // The id (int) of the sensor. - optional int32 sensor_id = 2; - - enum State { - OFF = 0; - ON = 1; - } - optional State state = 3; -} - -/** - * Logs when GPS state changes. - * - * Logged from: - * frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java - */ -message GpsScanStateChanged { - repeated AttributionNode attribution_node = 1; - - enum State { - OFF = 0; - ON = 1; - } - optional State state = 2; -} - -/** - * Logs when GPS signal quality. - * - * Logged from: - * /frameworks/base/location/java/com/android/internal/location/gnssmetrics/GnssMetrics.java - */ -message GpsSignalQualityChanged { - optional android.server.location.GpsSignalQualityEnum level = 1; -} - - -/** - * Logs when a sync manager sync state changes. - * - * Logged from: - * frameworks/base/services/core/java/com/android/server/am/BatteryStatsService.java - */ -message SyncStateChanged { - repeated AttributionNode attribution_node = 1; - - // Name of the sync (as named in the app). Can be chosen at run-time. - optional string sync_name = 2; - - enum State { - OFF = 0; - ON = 1; - } - optional State state = 3; -} - -/* - * Deferred job stats. - * - * Logged from: - * frameworks/base/services/core/java/com/android/server/job/JobSchedulerService.java -*/ -message DeferredJobStatsReported { - repeated AttributionNode attribution_node = 1; - - // Number of jobs deferred. - optional int32 num_jobs_deferred = 2; - - // Time since the last job runs. - optional int64 time_since_last_job_millis = 3; -} - -/** - * Logs when a job scheduler job state changes. - * - * Logged from: - * frameworks/base/services/core/java/com/android/server/am/BatteryStatsService.java - */ -message ScheduledJobStateChanged { - repeated AttributionNode attribution_node = 1; - - // Name of the job (as named in the app) - optional string job_name = 2; - - enum State { - FINISHED = 0; - STARTED = 1; - SCHEDULED = 2; - } - optional State state = 3; - - // The reason a job has stopped. - // This is only applicable when the state is FINISHED. - // The default value is STOP_REASON_UNKNOWN. - optional android.app.job.StopReasonEnum stop_reason = 4; - - // The standby bucket of the app that scheduled the job. These match the framework constants - // defined in JobSchedulerService.java with the addition of UNKNOWN using -1, as ACTIVE is - // already assigned 0. - enum Bucket { - UNKNOWN = -1; - ACTIVE = 0; - WORKING_SET = 1; - FREQUENT = 2; - RARE = 3; - NEVER = 4; - RESTRICTED = 5; - } - optional Bucket standby_bucket = 5 [default = UNKNOWN]; - - // The job id (as assigned by the app). - optional int32 job_id = 6; - - // One flag for each of the API constraints defined by Jobscheduler. Does not include implcit - // constraints as they are always assumed to be set. - optional bool has_charging_constraint = 7; - optional bool has_battery_not_low_constraint = 8; - optional bool has_storage_not_low_constraint = 9; - optional bool has_timing_delay_constraint = 10; - optional bool has_deadline_constraint = 11; - optional bool has_idle_constraint = 12; - optional bool has_connectivity_constraint = 13; - optional bool has_content_trigger_constraint = 14; -} - -/** - * Logs when the audio state changes. - * - * Logged from: - * frameworks/base/services/core/java/com/android/server/am/BatteryStatsService.java - */ -message AudioStateChanged { - repeated AttributionNode attribution_node = 1; - - enum State { - OFF = 0; - ON = 1; - // RESET indicates all audio stopped. Used when it (re)starts (e.g. after it crashes). - RESET = 2; - } - optional State state = 2; -} - -/** - * Logs when the video codec state changes. - * - * Logged from: - * frameworks/base/services/core/java/com/android/server/am/BatteryStatsService.java - */ -message MediaCodecStateChanged { - repeated AttributionNode attribution_node = 1; - - enum State { - OFF = 0; - ON = 1; - // RESET indicates all mediaCodec stopped. Used when it (re)starts (e.g. after it crashes). - RESET = 2; - } - optional State state = 2; -} - -/** - * Logs when the flashlight state changes. - * - * Logged from: - * frameworks/base/services/core/java/com/android/server/am/BatteryStatsService.java - */ -message FlashlightStateChanged { - repeated AttributionNode attribution_node = 1; - - enum State { - OFF = 0; - ON = 1; - // RESET indicates all flashlight stopped. Used when it (re)starts (e.g. after it crashes). - RESET = 2; - } - optional State state = 2; -} - -/** - * Logs when the camera state changes. - * - * Logged from: - * frameworks/base/services/core/java/com/android/server/am/BatteryStatsService.java - */ -message CameraStateChanged { - repeated AttributionNode attribution_node = 1; - - enum State { - OFF = 0; - ON = 1; - // RESET indicates all camera stopped. Used when it (re)starts (e.g. after it crashes). - RESET = 2; - } - optional State state = 2; -} - -/** - * Logs that the state of a wakelock (per app and per wakelock name) has changed. - * - * Logged from: - * TODO - */ -message WakelockStateChanged { - repeated AttributionNode attribution_node = 1 - [(state_field_option).primary_field_first_uid = true]; - - // The type (level) of the wakelock; e.g. a partial wakelock or a full wakelock. - // From frameworks/base/core/proto/android/os/enums.proto. - optional android.os.WakeLockLevelEnum type = 2 [(state_field_option).primary_field = true]; - - // The wakelock tag (Called tag in the Java API, sometimes name elsewhere). - optional string tag = 3 [(state_field_option).primary_field = true]; - - enum State { - RELEASE = 0; - ACQUIRE = 1; - CHANGE_RELEASE = 2; - CHANGE_ACQUIRE = 3; - } - optional State state = 4 [ - (state_field_option).exclusive_state = true, - (state_field_option).default_state_value = 0, - (state_field_option).nested = true - ]; -} - -/** - * Logs when a partial wakelock is considered 'long' (over 1 min). - * - * Logged from: - * frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java - */ -message LongPartialWakelockStateChanged { - repeated AttributionNode attribution_node = 1; - - // The wakelock tag (Called tag in the Java API, sometimes name elsewhere). - optional string tag = 2; - - // TODO: I have no idea what this is. - optional string history_tag = 3; - - enum State { - OFF = 0; - ON = 1; - } - optional State state = 4; -} - -/** - * Logs when the device is interactive, according to the PowerManager Notifier. - * - * Logged from: - * frameworks/base/services/core/java/com/android/server/power/Notifier.java - */ -message InteractiveStateChanged { - enum State { - OFF = 0; - ON = 1; - } - optional State state = 1; -} - -/** - * Logs Battery Saver state change. - * - * Logged from: - * frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java - */ -message BatterySaverModeStateChanged { - enum State { - OFF = 0; - ON = 1; - } - optional State state = 1 - [(state_field_option).exclusive_state = true, (state_field_option).nested = false]; -} - -/** - * Logs Doze mode state change. - * - * Logged from: - * frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java - */ -message DeviceIdleModeStateChanged { - optional android.server.DeviceIdleModeEnum state = 1 - [(state_field_option).exclusive_state = true, (state_field_option).nested = false]; -} - - -/** - * Logs state change of Doze mode including maintenance windows. - * - * Logged from: - * frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java - */ -message DeviceIdlingModeStateChanged { - optional android.server.DeviceIdleModeEnum state = 1 - [(state_field_option).exclusive_state = true, (state_field_option).nested = false]; -} - -/** - * Logs screen brightness level. - * - * Logged from: - * frameworks/base/services/core/java/com/android/server/am/BatteryStatsService.java - */ -message ScreenBrightnessChanged { - // Screen brightness level. Should be in [-1, 255] according to PowerManager.java. - optional int32 level = 1; -} - -/** - * Logs battery level (percent full, from 0 to 100). - * - * Logged from: - * frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java - */ -message BatteryLevelChanged { - // Battery level. Should be in [0, 100]. - optional int32 battery_level = 1; -} - -/** - * Logs change in charging status of the device. - * - * Logged from: - * frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java - */ -message ChargingStateChanged { - // State of the battery, from frameworks/base/core/proto/android/os/enums.proto. - optional android.os.BatteryStatusEnum state = 1 - [(state_field_option).exclusive_state = true, (state_field_option).nested = false]; -} - -/** - * Logs whether the device is plugged in, and what power source it is using. - * - * Logged from: - * frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java - */ -message PluggedStateChanged { - // Whether the device is plugged in, from frameworks/base/core/proto/android/os/enums.proto. - optional android.os.BatteryPluggedStateEnum state = 1 - [(state_field_option).exclusive_state = true, (state_field_option).nested = false]; -} - -/** - * Logs when an app's wakeup alarm fires. - * - * Logged from: - * frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java - */ -message WakeupAlarmOccurred { - repeated AttributionNode attribution_node = 1; - - // Name of the wakeup alarm. - optional string tag = 2; - - // Name of source package (for historical reasons, since BatteryStats tracked it). - optional string package_name = 3; - - // The App Standby bucket of the app that scheduled the alarm at the time the alarm fired. - optional AppStandbyBucketChanged.Bucket app_standby_bucket = 4; -} - -/** - * Logs when an an app causes the mobile radio to change state. - * Changing from LOW to MEDIUM or HIGH can be considered the app waking the mobile radio. - * - * Logged from: - * frameworks/base/services/core/java/com/android/server/NetworkManagementService.java - */ -message MobileRadioPowerStateChanged { - repeated AttributionNode attribution_node = 1; - - // Power state, from frameworks/base/core/proto/android/telephony/enums.proto. - optional android.telephony.DataConnectionPowerStateEnum state = 2; -} - -/** - * Logs when an an app causes the wifi radio to change state. - * Changing from LOW to MEDIUM or HIGH can be considered the app waking the wifi radio. - * - * Logged from: - * frameworks/base/services/core/java/com/android/server/NetworkManagementService.java - */ -message WifiRadioPowerStateChanged { - repeated AttributionNode attribution_node = 1; - - // Power state, from frameworks/base/core/proto/android/telephony/enums.proto. - optional android.telephony.DataConnectionPowerStateEnum state = 2; -} - -/** - * Logs kernel wakeup reasons and aborts. - * - * Logged from: - * frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java - */ -message KernelWakeupReported { - // Name of the kernel wakeup reason (or abort). - optional string wakeup_reason_name = 1; - - // Duration (in microseconds) for the wake-up interrupt to be serviced. - optional int64 duration_micros = 2; -} - -/** - * Logs when Wifi is toggled on/off. - * Note that Wifi may still perform certain functions (e.g. location scanning) even when disabled. - * - * Logged from: - * frameworks/base/services/core/java/com/android/server/am/BatteryStatsService.java - */ -message WifiEnabledStateChanged { - enum State { - OFF = 0; - ON = 1; - } - optional State state = 1; -} - -/** - * This atom is deprecated starting in R. - * - * Logs when an app causes Wifi to run. In this context, 'to run' means to use Wifi Client Mode. - * TODO: Include support for Hotspot, perhaps by using an extra field to denote 'mode'. - * Note that Wifi Scanning is monitored separately in WifiScanStateChanged. - * - * Logged from: - * frameworks/base/services/core/java/com/android/server/am/BatteryStatsService.java - */ -message WifiRunningStateChanged { - repeated AttributionNode attribution_node = 1; - - enum State { - OFF = 0; - ON = 1; - } - optional State state = 2; -} - -/** - * Logs wifi locks held by an app. - * - * Logged from: - * frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java - */ -message WifiLockStateChanged { - repeated AttributionNode attribution_node = 1; - - enum State { - OFF = 0; - ON = 1; - } - optional State state = 2; - - // WifiLock type, from frameworks/base/core/proto/android/wifi/enums.proto. - optional android.net.wifi.WifiModeEnum mode = 3; -} - -/** - * Logs wifi signal strength changes. - * - * Logged from: - * frameworks/opt/net/wifi/service/java/com/android/server/wifi/ClientModeImpl.java - */ -message WifiSignalStrengthChanged { - // Signal strength, from frameworks/base/core/proto/android/telephony/enums.proto. - optional android.telephony.SignalStrengthEnum signal_strength = 1; -} - -/** - * Logs wifi scans performed by an app. - * - * Logged from: - * frameworks/opt/net/wifi/service/java/com/android/server/wifi/scanner/WifiScanningServiceImpl.java - */ -message WifiScanStateChanged { - repeated AttributionNode attribution_node = 1; - - enum State { - OFF = 0; - ON = 1; - } - optional State state = 2; -} - -/** - * Logs wifi multicast locks held by an app - * - * Logged from: - * frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiMulticastLockManager.java - */ -message WifiMulticastLockStateChanged { - repeated AttributionNode attribution_node = 1; - - enum State { - OFF = 0; - ON = 1; - } - optional State state = 2; - - optional string tag = 3; -} - -/** - * Logs shutdown reason and duration on next boot. - * - * Logged from: - * frameworks/base/core/java/com/android/server/BootReceiver.java - */ -message ShutdownSequenceReported { - // True if shutdown is for a reboot. Default: false if we do not know. - optional bool reboot = 1; - - // Reason for shutdown. Eg: userrequested. Default: "<EMPTY>". - optional string reason = 2; - - // Beginning of shutdown time in ms using wall clock time since unix epoch. - // Default: 0 if no start time received. - optional int64 start_time_millis = 3; - - // Duration of shutdown in ms. Default: 0 if no duration received. - optional int64 duration_millis = 4; -} - - -/** - * Logs boot reason and duration. - * - * Logged from: - * system/core/bootstat/bootstat.cpp - */ -message BootSequenceReported { - // Reason for bootloader boot. Eg. reboot. See bootstat.cpp for larger list - // Default: "<EMPTY>" if not available. - optional string bootloader_reason = 1; - - // Reason for system boot. Eg. bootloader, reboot,userrequested - // Default: "<EMPTY>" if not available. - optional string system_reason = 2; - - // End of boot time in ms from unix epoch using system wall clock. - optional int64 end_time_millis = 3; - - // Total boot duration in ms. - optional int64 total_duration_millis = 4; - - // Bootloader duration in ms. - optional int64 bootloader_duration_millis = 5; - - // Time since last boot in ms. Default: 0 if not available. - optional int64 time_since_last_boot = 6; -} - - -/** - * Logs call state and disconnect cause (if applicable). - * - * Logged from: - * packages/services/Telecomm/src/com/android/server/telecom/Call.java - */ -message CallStateChanged { - // The state of the call. Eg. DIALING, ACTIVE, ON_HOLD, DISCONNECTED. - // From frameworks/base/core/proto/android/telecomm/enums.proto. - optional android.telecom.CallStateEnum call_state = 1; - - // The reason the call disconnected. Eg. ERROR, MISSED, REJECTED, BUSY. - // This value is only applicable when the call_state is DISCONNECTED, and - // should always be UNKNOWN if the call_state is not DISCONNECTED. - // From frameworks/base/core/proto/android/telecomm/enums.proto. - optional android.telecom.DisconnectCauseEnum disconnect_cause = 2; - - // True if the call is self-managed, which are apps that use the - // telecom infrastructure to make their own calls. - optional bool self_managed = 3; - - // True if call is external. External calls are calls on connected Wear - // devices but show up in Telecom so the user can pull them onto the device. - optional bool external_call = 4; -} - -/** - * Logs keyguard state. The keyguard is the lock screen. - * - * Logged from: - * frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java - */ -message KeyguardStateChanged { - enum State { - UNKNOWN = 0; - // The keyguard is hidden when the phone is unlocked. - HIDDEN = 1; - // The keyguard is shown when the phone is locked (screen turns off). - SHOWN= 2; - // The keyguard is occluded when something is overlaying the keyguard. - // Eg. Opening the camera while on the lock screen. - OCCLUDED = 3; - } - optional State state = 1; -} - -/** - * Logs keyguard bouncer state. The bouncer is a part of the keyguard, and - * prompts the user to enter a password (pattern, pin, etc). - * - * Logged from: - * frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java - */ - -message KeyguardBouncerStateChanged { - enum State { - UNKNOWN = 0; - // Bouncer is hidden, either as a result of successfully entering the - // password, screen timing out, or user going back to lock screen. - HIDDEN = 1; - // This is when the user is being prompted to enter the password. - SHOWN = 2; - } - optional State state = 1; -} - -/** - * Logs the result of entering a password into the keyguard bouncer. - * - * Logged from: - * frameworks/base/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java - */ -message KeyguardBouncerPasswordEntered { - enum BouncerResult { - UNKNOWN = 0; - // The password entered was incorrect. - FAILURE = 1; - // The password entered was correct. - SUCCESS = 2; - } - optional BouncerResult result = 1; -} - -/* - * Logs changes to the configuration of the device. The configuration is defined - * in frameworks/base/core/java/android/content/res/Configuration.java - * More documentation is at https://d.android.com/reference/android/content/res/Configuration.html - * Please go there to interpret the possible values each field can be. - * - * Logged from: - * frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java - */ -message ResourceConfigurationChanged { - // Bit mask of color capabilities of the screen. - // Contains information about the color gamut and hdr mode of the screen. - // See: https://d.android.com/reference/android/content/res/Configuration.html#colorMode - optional int32 color_mode = 1; - - // The target screen density being rendered to. - // See: https://d.android.com/reference/android/content/res/Configuration.html#densityDpi - optional int32 density_dpi = 2; - - // Current user preference for the scaling factor for fonts, - // relative to the base density scaling. - // See: https://d.android.com/reference/android/content/res/Configuration.html#fontScale - optional float font_scale = 3; - - // Flag indicating whether the hard keyboard is hidden. - // See: https://d.android.com/reference/android/content/res/Configuration.html#hardKeyboardHidden - optional int32 hard_keyboard_hidden = 4; - - // The type of keyboard attached to the device. - // See: https://d.android.com/reference/android/content/res/Configuration.html#keyboard - optional int32 keyboard = 5; - - // Flag indicating whether any keyboard is available. Takes soft keyboards into account. - // See: https://d.android.com/reference/android/content/res/Configuration.html#keyboardHidden - optional int32 keyboard_hidden = 6; - - // IMSI MCC (Mobile Country Code), corresponding to mcc resource qualifier. - // 0 if undefined. - // See: https://d.android.com/reference/android/content/res/Configuration.html#mcc - optional int32 mcc = 7; - - // IMSI MNC (Mobile Network Code), corresponding to mnc resource qualifier. - // 0 if undefined. Note: the actual MNC may be 0, to check for this use the - // MNC_ZERO symbol defined in Configuration.java. - // See: https://d.android.com/reference/android/content/res/Configuration.html#mnc - optional int32 mnc = 8; - - // The kind of navigation available on the device. - // See: https://developer.android.com/reference/android/content/res/Configuration.html#navigation - optional int32 navigation = 9; - - // Flag indicating whether the navigation is available. - // See: https://d.android.com/reference/android/content/res/Configuration.html#navigationHidden - optional int32 navigation_hidden = 10; - - // Overall orientation of the screen. - // See: https://d.android.com/reference/android/content/res/Configuration.html#orientation - optional int32 orientation = 11; - - // The current height of the available screen space, in dp units. - // See: https://d.android.com/reference/android/content/res/Configuration.html#screenHeightDp - optional int32 screen_height_dp = 12; - - // Bit mask of overall layout of the screen. - // Contains information about screen size, whether the screen is wider/taller - // than normal, whether the screen layout is right-tl-left or left-to-right, - // and whether the screen has a rounded shape. - // See: https://d.android.com/reference/android/content/res/Configuration.html#screenLayout - optional int32 screen_layout = 13; - - // Current width of the available screen space, in dp units. - // See: https://d.android.com/reference/android/content/res/Configuration.html#screenWidthDp - optional int32 screen_width_dp = 14; - - // The smallest screen size an application will see in normal operation. - // This is the smallest value of both screenWidthDp and screenHeightDp - // in portrait and landscape. - // See: https://d.android.com/reference/android/content/res/Configuration.html#smallestScreenWidthDp - optional int32 smallest_screen_width_dp = 15; - - // The type of touch screen attached to the device. - // See: https://d.android.com/reference/android/content/res/Configuration.html#touchscreen - optional int32 touchscreen = 16; - - // Bit mask of the ui mode. - // Contains information about the overall ui mode of the device. - // Eg: NORMAL, DESK, CAR, TELEVISION, WATCH, VR_HEADSET - // Also contains information about whether the device is in night mode. - // See: https://d.android.com/reference/android/content/res/Configuration.html#uiMode - optional int32 ui_mode = 17; -} - - -/** - * Logs changes in the connection state of the mobile radio. - * - * Logged from: - * frameworks/opt/telephony/src/java/com/android/internal/telephony/dataconnection/DataConnection.java - */ -message MobileConnectionStateChanged { - // States are from the state machine DataConnection.java. - enum State { - UNKNOWN = 0; - // The connection is inactive, or disconnected. - INACTIVE = 1; - // The connection is being activated, or connecting. - ACTIVATING = 2; - // The connection is active, or connected. - ACTIVE = 3; - // The connection is disconnecting. - DISCONNECTING = 4; - // The connection is disconnecting after creating a connection. - DISCONNECTION_ERROR_CREATING_CONNECTION = 5; - } - optional State state = 1; - // For multi-sim phones, this distinguishes between the sim cards. - optional int32 sim_slot_index = 2; - // Used to identify the connection. Starts at 0 and increments by 1 for - // every new network created. Resets whenever the device reboots. - optional int32 data_connection_id = 3; - // A bitmask for the capabilities of this connection. - // Eg. DEFAULT (internet), MMS, SUPL, DUN, IMS. - // Default value (if we have no information): 0 - optional int64 capabilities = 4; - // If this connection has internet. - // This just checks if the DEFAULT bit of capabilities is set. - optional bool has_internet = 5; -} - -/** - * Logs changes in mobile radio technology. eg: LTE, EDGE, CDMA. - * - * Logged from: - * frameworks/opt/telephony/src/java/com/android/internal/telephony/ServiceStateTracker.java - */ -message MobileRadioTechnologyChanged { - optional android.telephony.NetworkTypeEnum state = 1; - // For multi-sim phones, this distinguishes between the sim cards. - optional int32 sim_slot_index = 2; -} - -/** - * Logs the VID and PID of any connected USB devices. - * - * Notes if any Audio, HID (input buttons/mouse/keyboard), or Storage interfaces are present. - * - * Logged by Vendor. - */ -message UsbDeviceAttached { - optional int32 vid = 1; - optional int32 pid = 2; - optional bool has_audio = 3; - optional bool has_hid = 4; - optional bool has_storage = 5; - enum State { - STATE_DISCONNECTED = 0; - STATE_CONNECTED = 1; - } - optional State state = 6; - optional int64 last_connect_duration_millis = 7; -} - - -/** - * Logs when Bluetooth is enabled and disabled. - * - * Logged from: - * services/core/java/com/android/server/BluetoothManagerService.java - */ -message BluetoothEnabledStateChanged { - repeated AttributionNode attribution_node = 1; - // Whether or not bluetooth is enabled on the device. - enum State { - UNKNOWN = 0; - ENABLED = 1; - DISABLED = 2; - } - optional State state = 2; - // The reason for being enabled/disabled. - // Eg. Airplane mode, crash, application request. - optional android.bluetooth.EnableDisableReasonEnum reason = 3; - // If the reason is an application request, this will be the package name. - optional string pkg_name = 4; -} - -/** - * Logs when profiles on a Bluetooth device connects and disconnects. - * - * Logged from: - * packages/apps/Bluetooth/src/com/android/bluetooth/btservice/RemoteDevices.java - * - * Next Tag: 6 - */ -message BluetoothConnectionStateChanged { - // The state of the connection. - // Eg: CONNECTING, CONNECTED, DISCONNECTING, DISCONNECTED. - optional android.bluetooth.ConnectionStateEnum state = 1; - // An identifier that can be used to match connect and disconnect events. - // Currently is last two bytes of a hash of a device level ID and - // the mac address of the bluetooth device that is connected. - // Deprecated: use obfuscated_id instead, this one is always 0 for Q+ - optional int32 obfuscated_id = 2 [deprecated = true]; - // The profile that is connected. Eg. GATT, A2DP, HEADSET. - // From android.bluetooth.BluetoothAdapter.java - // Default: 0 when not used - optional int32 bt_profile = 3; - // An identifier that can be used to match events for this device. - // Currently, this is a salted hash of the MAC address of this Bluetooth device. - // Salt: Randomly generated 256 bit value - // Hash algorithm: HMAC-SHA256 - // Size: 32 byte - // Default: null or empty if the device identifier is not known - optional bytes new_obfuscated_id = 4 [(android.os.statsd.log_mode) = MODE_BYTES]; - // An identifier that can be used to match events for this device. - // The incremental identifier is locally generated and guaranteed not derived - // from any globally unique hardware id. - // For paired devices, it stays consistent between Bluetooth toggling for the - // same remote device. - // For unpaired devices, it stays consistent within the same Bluetooth adapter - // session for the same remote device. - // Default: 0 if the device's metric id is unknown. - optional int32 metric_id = 5; -} - -/** - * Logs when a Bluetooth device connects and disconnects over ACL - * - * Logged from: - * packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterProperties.java - * - * Next Tag: 4 - */ -message BluetoothAclConnectionStateChanged { - // An identifier that can be used to match events for this device. - // Currently, this is a salted hash of the MAC address of this Bluetooth device. - // Salt: Randomly generated 256 bit value - // Hash algorithm: HMAC-SHA256 - // Size: 32 byte - // Default: null or empty if the device identifier is not known - optional bytes obfuscated_id = 1 [(android.os.statsd.log_mode) = MODE_BYTES]; - // The state of the connection. - // Eg: CONNECTING, CONNECTED, DISCONNECTING, DISCONNECTED. - optional android.bluetooth.ConnectionStateEnum state = 2; - // An identifier that can be used to match events for this device. - // The incremental identifier is locally generated and guaranteed not derived - // from any globally unique hardware id. - // For paired devices, it stays consistent between Bluetooth toggling for the - // same remote device. - // For unpaired devices, it stays consistent within the same Bluetooth adapter - // session for the same remote device. - // Default: 0 if the device's metric id is unknown. - optional int32 metric_id = 3; -} - -/** - * Logs when a Bluetooth device connects and disconnects over SCO - * - * Logged from: - * packages/apps/Bluetooth/src/com/android/bluetooth/hfp/HeadsetStateMachine.java - * packages/apps/Bluetooth/src/com/android/bluetooth/hfp/HeadsetClientStateMachine.java - * - * Next Tag: 5 - */ -message BluetoothScoConnectionStateChanged { - // An identifier that can be used to match events for this device. - // Currently, this is a salted hash of the MAC address of this Bluetooth device. - // Salt: Randomly generated 256 bit value - // Hash algorithm: HMAC-SHA256 - // Size: 32 byte - // Default: null or empty if the device identifier is not known - optional bytes obfuscated_id = 1 [(android.os.statsd.log_mode) = MODE_BYTES]; - // The state of the connection. - // Eg: CONNECTING, CONNECTED, DISCONNECTING, DISCONNECTED. - optional android.bluetooth.ConnectionStateEnum state = 2; - // Codec used for this SCO connection - // Default: UNKNOWN - optional android.bluetooth.hfp.ScoCodec codec = 3; - // An identifier that can be used to match events for this device. - // The incremental identifier is locally generated and guaranteed not derived - // from any globally unique hardware id. - // For paired devices, it stays consistent between Bluetooth toggling for the - // same remote device. - // For unpaired devices, it stays consistent within the same Bluetooth adapter - // session for the same remote device. - // Default: 0 if the device's metric id is unknown. - optional int32 metric_id = 4; -} - -/** - * Logged when active device of a profile changes - * - * Logged from: - * packages/apps/Bluetooth/src/com/android/bluetooth/a2dp/A2dpService.java - * packages/apps/Bluetooth/src/com/android/bluetooth/hfp/HeadsetService.java - * packages/apps/Bluetooth/src/com/android/bluetooth/hearingaid/HearingAidService.java - */ -message BluetoothActiveDeviceChanged { - // The profile whose active device has changed. Eg. A2DP, HEADSET, HEARING_AID - // From android.bluetooth.BluetoothProfile - optional int32 bt_profile = 1; - // An identifier that can be used to match events for this new active device. - // Currently, this is a salted hash of the MAC address of this Bluetooth device. - // Salt: Randomly generated 256 bit value - // Hash algorithm: HMAC-SHA256 - // Size: 32 byte - // Default: null or empty if there is no active device for this profile - optional bytes obfuscated_id = 2 [(android.os.statsd.log_mode) = MODE_BYTES]; - // An identifier that can be used to match events for this device. - // The incremental identifier is locally generated and guaranteed not derived - // from any globally unique hardware id. - // For paired devices, it stays consistent between Bluetooth toggling for the - // same remote device. - // For unpaired devices, it stays consistent within the same Bluetooth adapter - // session for the same remote device. - // Default: 0 if the device's metric id is unknown. - optional int32 metric_id = 3; -} - -// Logs when there is an event affecting Bluetooth device's link layer connection. -// - This event is triggered when there is a related HCI command or event -// - Users of this metrics can deduce Bluetooth device's connection state from these events -// - HCI commands are logged before the command is sent, after receiving command status, and after -// receiving command complete -// - HCI events are logged when they arrive -// -// Low level log from system/bt -// -// Bluetooth classic commands: -// - CMD_CREATE_CONNECTION -// - CMD_DISCONNECT -// - CMD_CREATE_CONNECTION_CANCEL -// - CMD_ACCEPT_CONNECTION_REQUEST -// - CMD_REJECT_CONNECTION_REQUEST -// - CMD_SETUP_ESCO_CONNECTION -// - CMD_ACCEPT_ESCO_CONNECTION -// - CMD_REJECT_ESCO_CONNECTION -// - CMD_ENH_SETUP_ESCO_CONNECTION -// - CMD_ENH_ACCEPT_ESCO_CONNECTION -// -// Bluetooth low energy commands: -// - CMD_BLE_CREATE_LL_CONN [Only logged on error or when initiator filter policy is 0x00] -// - CMD_BLE_CREATE_CONN_CANCEL [Only logged when there is an error] -// - CMD_BLE_EXTENDED_CREATE_CONNECTION [Only logged on error or when initiator filter policy is 0x00] -// - CMD_BLE_CLEAR_WHITE_LIST -// - CMD_BLE_ADD_WHITE_LIST -// - CMD_BLE_REMOVE_WHITE_LIST -// -// Bluetooth classic events: -// - EVT_CONNECTION_COMP -// - EVT_CONNECTION_REQUEST -// - EVT_DISCONNECTION_COMP -// - EVT_ESCO_CONNECTION_COMP -// - EVT_ESCO_CONNECTION_CHANGED -// -// Bluetooth low energy meta events: -// - BLE_EVT_CONN_COMPLETE_EVT -// - BLE_EVT_ENHANCED_CONN_COMPLETE_EVT -// -// Next tag: 10 -message BluetoothLinkLayerConnectionEvent { - // An identifier that can be used to match events for this device. - // Currently, this is a salted hash of the MAC address of this Bluetooth device. - // Salt: Randomly generated 256 bit value - // Hash algorithm: HMAC-SHA256 - // Size: 32 byte - // Default: null or empty if the device identifier is not known - optional bytes obfuscated_id = 1 [(android.os.statsd.log_mode) = MODE_BYTES]; - // Connection handle of this connection if available - // Range: 0x0000 - 0x0EFF (12 bits) - // Default: 0xFFFF if the handle is unknown - optional int32 connection_handle = 2; - // Direction of the link - // Default: DIRECTION_UNKNOWN - optional android.bluetooth.DirectionEnum direction = 3; - // Type of this link - // Default: LINK_TYPE_UNKNOWN - optional android.bluetooth.LinkTypeEnum type = 4; - - // Reason metadata for this link layer connection event, rules for interpretation: - // 1. If hci_cmd is set and valid, hci_event can be either EVT_COMMAND_STATUS or - // EVT_COMMAND_COMPLETE, ignore hci_ble_event in this case - // 2. If hci_event is set to EVT_BLE_META, look at hci_ble_event; otherwise, if hci_event is - // set and valid, ignore hci_ble_event - - // HCI command associated with this event - // Default: CMD_UNKNOWN - optional android.bluetooth.hci.CommandEnum hci_cmd = 5; - // HCI event associated with this event - // Default: EVT_UNKNOWN - optional android.bluetooth.hci.EventEnum hci_event = 6; - // HCI BLE meta event associated with this event - // Default: BLE_EVT_UNKNOWN - optional android.bluetooth.hci.BleMetaEventEnum hci_ble_event = 7; - // HCI command status code if this is triggerred by hci_cmd - // Default: STATUS_UNKNOWN - optional android.bluetooth.hci.StatusEnum cmd_status = 8; - // HCI reason code associated with this event - // Default: STATUS_UNKNOWN - optional android.bluetooth.hci.StatusEnum reason_code = 9; - // An identifier that can be used to match events for this device. - // The incremental identifier is locally generated and guaranteed not derived - // from any globally unique hardware id. - // For paired devices, it stays consistent between Bluetooth toggling for the - // same remote device. - // For unpaired devices, it stays consistent within the same Bluetooth adapter - // session for the same remote device. - // Default: 0 if the device's metric id is unknown. - optional int32 metric_id = 10; -} - -/** - * Logs when a module is rolled back by Watchdog. - * - * Logged from: Rollback Manager - */ -message WatchdogRollbackOccurred { - enum RollbackType { - UNKNOWN = 0; - ROLLBACK_INITIATE = 1; - ROLLBACK_SUCCESS = 2; - ROLLBACK_FAILURE = 3; - ROLLBACK_BOOT_TRIGGERED = 4; - } - optional RollbackType rollback_type = 1; - - optional string package_name = 2; - - optional int32 package_version_code = 3; - - enum RollbackReasonType { - REASON_UNKNOWN = 0; - REASON_NATIVE_CRASH = 1; - REASON_EXPLICIT_HEALTH_CHECK = 2; - REASON_APP_CRASH = 3; - REASON_APP_NOT_RESPONDING = 4; - REASON_NATIVE_CRASH_DURING_BOOT = 5; - } - optional RollbackReasonType rollback_reason = 4; - - // Set by RollbackPackageHealthObserver to be the package that is failing when a rollback - // is initiated. Empty if the package is unknown. - optional string failing_package_name = 5; - - optional TrainExperimentIds experiment_ids = 6 [(log_mode) = MODE_BYTES]; -} - -/** - * Logs when there is a change in Bluetooth A2DP playback state - * - * Logged from: - * packages/apps/Bluetooth/src/com/android/bluetooth/a2dp/A2dpService.java - */ -message BluetoothA2dpPlaybackStateChanged { - // An identifier that can be used to match events for this device. - // Currently, this is a salted hash of the MAC address of this Bluetooth device. - // Salt: Randomly generated 256 bit value - // Hash algorithm: HMAC-SHA256 - // Size: 32 byte - // Default: null or empty if the device identifier is not known - optional bytes obfuscated_id = 1 [(android.os.statsd.log_mode) = MODE_BYTES]; - // Current playback state - // Default: PLAYBACK_STATE_UNKNOWN - optional android.bluetooth.a2dp.PlaybackStateEnum playback_state = 2; - // Current audio coding mode - // Default: AUDIO_CODING_MODE_UNKNOWN - optional android.bluetooth.a2dp.AudioCodingModeEnum audio_coding_mode = 3; - // An identifier that can be used to match events for this device. - // The incremental identifier is locally generated and guaranteed not derived - // from any globally unique hardware id. - // For paired devices, it stays consistent between Bluetooth toggling for the - // same remote device. - // For unpaired devices, it stays consistent within the same Bluetooth adapter - // session for the same remote device. - // Default: 0 if the device's metric id is unknown. - optional int32 metric_id = 4; -} - -/** - * Logs when there is a change in A2DP codec config for a particular remote device - * - * Logged from: - * frameworks/base/core/java/android/bluetooth/BluetoothCodecConfig.java - * packages/apps/Bluetooth/src/com/android/bluetooth/a2dp/A2dpService.java - */ -message BluetoothA2dpCodecConfigChanged { - // An identifier that can be used to match events for this device. - // Currently, this is a salted hash of the MAC address of this Bluetooth device. - // Salt: Randomly generated 256 bit value - // Hash algorithm: HMAC-SHA256 - // Size: 32 byte - // Default: null or empty if the device identifier is not known - optional bytes obfuscated_id = 1 [(android.os.statsd.log_mode) = MODE_BYTES]; - // Type of codec as defined by various SOURCE_CODEC_TYPE_* constants in BluetoothCodecConfig - // Default SOURCE_CODEC_TYPE_INVALID - optional int32 codec_type = 2; - // Codec priroity, the higher the more preferred, -1 for disabled - // Default: CODEC_PRIORITY_DEFAULT - optional int32 codec_priority = 3; - // Sample rate in Hz as defined by various SAMPLE_RATE_* constants in BluetoothCodecConfig - // Default: SAMPLE_RATE_NONE - optional int32 sample_rate = 4; - // Bits per sample as defined by various BITS_PER_SAMPLE_* constants in BluetoothCodecConfig - // Default: BITS_PER_SAMPLE_NONE - optional int32 bits_per_sample = 5; - // Channel mode as defined by various CHANNEL_MODE_* constants in BluetoothCodecConfig - // Default: CHANNEL_MODE_NONE - optional int32 channel_mode = 6; - // Codec specific values - // Default 0 - optional int64 codec_specific_1 = 7; - optional int64 codec_specific_2 = 8; - optional int64 codec_specific_3 = 9; - optional int64 codec_specific_4 = 10; - // An identifier that can be used to match events for this device. - // The incremental identifier is locally generated and guaranteed not derived - // from any globally unique hardware id. - // For paired devices, it stays consistent between Bluetooth toggling for the - // same remote device. - // For unpaired devices, it stays consistent within the same Bluetooth adapter - // session for the same remote device. - // Default: 0 if the device's metric id is unknown. - optional int32 metric_id = 11; -} - -/** - * Logs when there is a change in selectable A2DP codec capability for a paricular remote device - * Each codec's capability is logged separately due to statsd restriction - * - * Logged from: - * frameworks/base/core/java/android/bluetooth/BluetoothCodecConfig.java - * packages/apps/Bluetooth/src/com/android/bluetooth/a2dp/A2dpService.java - */ -message BluetoothA2dpCodecCapabilityChanged { - // An identifier that can be used to match events for this device. - // Currently, this is a salted hash of the MAC address of this Bluetooth device. - // Salt: Randomly generated 256 bit value - // Hash algorithm: HMAC-SHA256 - // Size: 32 byte - // Default: null or empty if the device identifier is not known - optional bytes obfuscated_id = 1 [(android.os.statsd.log_mode) = MODE_BYTES]; - // Type of codec as defined by various SOURCE_CODEC_TYPE_* constants in BluetoothCodecConfig - // Default SOURCE_CODEC_TYPE_INVALID - optional int32 codec_type = 2; - // Codec priroity, the higher the more preferred, -1 for disabled - // Default: CODEC_PRIORITY_DEFAULT - optional int32 codec_priority = 3; - // A bit field of supported sample rates as defined by various SAMPLE_RATE_* constants - // in BluetoothCodecConfig - // Default: empty and SAMPLE_RATE_NONE for individual item - optional int32 sample_rate = 4; - // A bit field of supported bits per sample as defined by various BITS_PER_SAMPLE_* constants - // in BluetoothCodecConfig - // Default: empty and BITS_PER_SAMPLE_NONE for individual item - optional int32 bits_per_sample = 5; - // A bit field of supported channel mode as defined by various CHANNEL_MODE_* constants in - // BluetoothCodecConfig - // Default: empty and CHANNEL_MODE_NONE for individual item - optional int32 channel_mode = 6; - // Codec specific values - // Default 0 - optional int64 codec_specific_1 = 7; - optional int64 codec_specific_2 = 8; - optional int64 codec_specific_3 = 9; - optional int64 codec_specific_4 = 10; - // An identifier that can be used to match events for this device. - // The incremental identifier is locally generated and guaranteed not derived - // from any globally unique hardware id. - // For paired devices, it stays consistent between Bluetooth toggling for the - // same remote device. - // For unpaired devices, it stays consistent within the same Bluetooth adapter - // session for the same remote device. - // Default: 0 if the device's metric id is unknown. - optional int32 metric_id = 11; -} - -/** - * Logs when A2DP failed to read from PCM source. - * This typically happens when audio HAL cannot supply A2DP with data fast enough for encoding. - * - * Logged from: - * system/bt - */ -message BluetoothA2dpAudioUnderrunReported { - // An identifier that can be used to match events for this device. - // Currently, this is a salted hash of the MAC address of this Bluetooth device. - // Salt: Randomly generated 256 bit value - // Hash algorithm: HMAC-SHA256 - // Size: 32 byte - // Default: null or empty if the device identifier is not known - optional bytes obfuscated_id = 1 [(android.os.statsd.log_mode) = MODE_BYTES]; - // Encoding interval in nanoseconds - // Default: 0 - optional int64 encoding_interval_nanos = 2; - // Number of bytes of PCM data that could not be read from the source - // Default: 0 - optional int32 num_missing_pcm_bytes = 3; - // An identifier that can be used to match events for this device. - // The incremental identifier is locally generated and guaranteed not derived - // from any globally unique hardware id. - // For paired devices, it stays consistent between Bluetooth toggling for the - // same remote device. - // For unpaired devices, it stays consistent within the same Bluetooth adapter - // session for the same remote device. - // Default: 0 if the device's metric id is unknown. - optional int32 metric_id = 4; -} - -/** - * Logs when A2DP failed send encoded data to the remote device fast enough such that the transmit - * buffer queue is full and we have to drop data - * - * Logged from: - * system/bt - */ -message BluetoothA2dpAudioOverrunReported { - // An identifier that can be used to match events for this device. - // Currently, this is a salted hash of the MAC address of this Bluetooth device. - // Salt: Randomly generated 256 bit value - // Hash algorithm: HMAC-SHA256 - // Size: 32 byte - // Default: null or empty if the device identifier is not known - optional bytes obfuscated_id = 1 [(android.os.statsd.log_mode) = MODE_BYTES]; - // Encoding interval in nanoseconds - // Default: 0 - optional int64 encoding_interval_nanos = 2; - // Number of buffers dropped in this event - // Each buffer is encoded in one encoding interval and consists of multiple encoded frames - // Default: 0 - optional int32 num_dropped_buffers = 3; - // Number of encoded buffers dropped in this event - // Default 0 - optional int32 num_dropped_encoded_frames = 4; - // Number of encoded bytes dropped in this event - // Default: 0 - optional int32 num_dropped_encoded_bytes = 5; - // An identifier that can be used to match events for this device. - // The incremental identifier is locally generated and guaranteed not derived - // from any globally unique hardware id. - // For paired devices, it stays consistent between Bluetooth toggling for the - // same remote device. - // For unpaired devices, it stays consistent within the same Bluetooth adapter - // session for the same remote device. - // Default: 0 if the device's metric id is unknown. - optional int32 metric_id = 6; -} - -/** - * Logs when we receive reports regarding a device's RSSI value - * - * Logged from: - * system/bt - */ -message BluetoothDeviceRssiReported { - // An identifier that can be used to match events for this device. - // Currently, this is a salted hash of the MAC address of this Bluetooth device. - // Salt: Randomly generated 256 bit value - // Hash algorithm: HMAC-SHA256 - // Size: 32 byte - // Default: null or empty if the device identifier is not known - optional bytes obfuscated_id = 1 [(android.os.statsd.log_mode) = MODE_BYTES]; - // Connection handle of this connection if available - // Range: 0x0000 - 0x0EFF (12 bits) - // Default: 0xFFFF if the handle is unknown - optional int32 connection_handle = 2; - // HCI command status code if this is triggerred by hci_cmd - // Default: STATUS_UNKNOWN - optional android.bluetooth.hci.StatusEnum hci_status = 3; - // BR/EDR - // Range: -128 ≤ N ≤ 127 (signed integer) - // Units: dB - // LE: - // Range: -127 to 20, 127 (signed integer) - // Units: dBm - // Invalid when an out of range value is reported - optional int32 rssi = 4; - // An identifier that can be used to match events for this device. - // The incremental identifier is locally generated and guaranteed not derived - // from any globally unique hardware id. - // For paired devices, it stays consistent between Bluetooth toggling for the - // same remote device. - // For unpaired devices, it stays consistent within the same Bluetooth adapter - // session for the same remote device. - // Default: 0 if the device's metric id is unknown. - optional int32 metric_id = 5; -} - -/** - * Logs when we receive reports regarding how many consecutive failed contacts for a connection - * - * Logged from: - * system/bt - */ -message BluetoothDeviceFailedContactCounterReported { - // An identifier that can be used to match events for this device. - // Currently, this is a salted hash of the MAC address of this Bluetooth device. - // Salt: Randomly generated 256 bit value - // Hash algorithm: HMAC-SHA256 - // Size: 32 byte - // Default: null or empty if the device identifier is not known - optional bytes obfuscated_id = 1 [(android.os.statsd.log_mode) = MODE_BYTES]; - // Connection handle of this connection if available - // Range: 0x0000 - 0x0EFF (12 bits) - // Default: 0xFFFF if the handle is unknown - optional int32 connection_handle = 2; - // HCI command status code if this is triggerred by hci_cmd - // Default: STATUS_UNKNOWN - optional android.bluetooth.hci.StatusEnum cmd_status = 3; - // Number of consecutive failed contacts for a connection corresponding to the Handle - // Range: uint16_t, 0-0xFFFF - // Default: 0xFFFFF - optional int32 failed_contact_counter = 4; - // An identifier that can be used to match events for this device. - // The incremental identifier is locally generated and guaranteed not derived - // from any globally unique hardware id. - // For paired devices, it stays consistent between Bluetooth toggling for the - // same remote device. - // For unpaired devices, it stays consistent within the same Bluetooth adapter - // session for the same remote device. - // Default: 0 if the device's metric id is unknown. - optional int32 metric_id = 5; -} - -/** - * Logs when we receive reports regarding the tranmit power level used for a specific connection - * - * Logged from: - * system/bt - */ -message BluetoothDeviceTxPowerLevelReported { - // An identifier that can be used to match events for this device. - // Currently, this is a salted hash of the MAC address of this Bluetooth device. - // Salt: Randomly generated 256 bit value - // Hash algorithm: HMAC-SHA256 - // Size: 32 byte - // Default: null or empty if the device identifier is not known - optional bytes obfuscated_id = 1 [(android.os.statsd.log_mode) = MODE_BYTES]; - // Connection handle of this connection if available - // Range: 0x0000 - 0x0EFF (12 bits) - // Default: 0xFFFF if the handle is unknown - optional int32 connection_handle = 2; - // HCI command status code if this is triggered by hci_cmd - // Default: STATUS_UNKNOWN - optional android.bluetooth.hci.StatusEnum hci_status = 3; - // Range: -30 ≤ N ≤ 20 - // Units: dBm - // Invalid when an out of range value is reported - optional int32 transmit_power_level = 4; - // An identifier that can be used to match events for this device. - // The incremental identifier is locally generated and guaranteed not derived - // from any globally unique hardware id. - // For paired devices, it stays consistent between Bluetooth toggling for the - // same remote device. - // For unpaired devices, it stays consistent within the same Bluetooth adapter - // session for the same remote device. - // Default: 0 if the device's metric id is unknown. - optional int32 metric_id = 5; -} - -/** - * Logs when Bluetooth controller failed to reply with command status within a timeout period after - * receiving an HCI command from the host - * - * Logged from: system/bt - */ -message BluetoothHciTimeoutReported { - // HCI command associated with this event - // Default: CMD_UNKNOWN - optional android.bluetooth.hci.CommandEnum hci_command = 1; -} - -/** - * Logs when we receive Bluetooth Link Quality Report event from the controller - * See Android Bluetooth HCI specification for more details - * - * Note: all count and bytes field are counted since last event - * - * Logged from: system/bt - */ -message BluetoothQualityReportReported { - // Quality report ID - // Original type: uint8_t - // Default: BQR_ID_UNKNOWN - optional android.bluetooth.hci.BqrIdEnum quality_report_id = 1; - // Packet type of the connection - // Original type: uint8_t - // Default: BQR_PACKET_TYPE_UNKNOWN - optional android.bluetooth.hci.BqrPacketTypeEnum packet_types = 2; - // Connection handle of the connection - // Original type: uint16_t - optional int32 connection_handle = 3; - // Performing Role for the connection - // Original type: uint8_t - optional int32 connection_role = 4; - // Current Transmit Power Level for the connection. This value is the same as the controller's - // response to the HCI_Read_Transmit_Power_Level HCI command - // Original type: uint8_t - optional int32 tx_power_level = 5; - // Received Signal Strength Indication (RSSI) value for the connection. This value is an - // absolute receiver signal strength value - // Original type: int8_t - optional int32 rssi = 6; - // Signal-to-Noise Ratio (SNR) value for the connection. It is the average SNR of all the - // channels used by the link currently - // Original type: uint8_t - optional int32 snr = 7; - // Indicates the number of unused channels in AFH_channel_map - // Original type: uint8_t - optional int32 unused_afh_channel_count = 8; - // Indicates the number of the channels which are interfered and quality is bad but are still - // selected for AFH - // Original type: uint8_t - optional int32 afh_select_unideal_channel_count = 9; - // Current Link Supervision Timeout Setting - // Unit: N * 0.3125 ms (1 Bluetooth Clock) - // Original type: uint16_t - optional int32 lsto = 10; - // Piconet Clock for the specified Connection_Handle. This value is the same as the controller's - // response to HCI_Read_Clock HCI command with the parameter "Which_Clock" of - // 0x01 (Piconet Clock) - // Unit: N * 0.3125 ms (1 Bluetooth Clock) - // Original type: uint32_t - optional int64 connection_piconet_clock = 11; - // The count of retransmission - // Original type: uint32_t - optional int64 retransmission_count = 12; - // The count of no RX - // Original type: uint32_t - optional int64 no_rx_count = 13; - // The count of NAK (Negative Acknowledge) - // Original type: uint32_t - optional int64 nak_count = 14; - // Controller timestamp of last TX ACK - // Unit: N * 0.3125 ms (1 Bluetooth Clock) - // Original type: uint32_t - optional int64 last_tx_ack_timestamp = 15; - // The count of Flow-off (STOP) - // Original type: uint32_t - optional int64 flow_off_count = 16; - // Controller timestamp of last Flow-on (GO) - // Unit: N * 0.3125 ms (1 Bluetooth Clock) - // Original type: uint32_t - optional int64 last_flow_on_timestamp = 17; - // Buffer overflow count (how many bytes of TX data are dropped) since the last event - // Original type: uint32_t - optional int64 buffer_overflow_bytes = 18; - // Buffer underflow count (in byte) since last event - // Original type: uint32_t - optional int64 buffer_underflow_bytes = 19; -} - -/** - * Logs when a Bluetooth device's manufacturer information is learnt by the Bluetooth stack - * - * Notes: - * - Each event can be partially filled as we might learn different pieces of device - * information at different time - * - Multiple device info events can be combined to give more complete picture - * - When multiple device info events tries to describe the same information, the - * later one wins - * - * Logged from: - * packages/apps/Bluetooth - */ -message BluetoothDeviceInfoReported { - // An identifier that can be used to match events for this device. - // Currently, this is a salted hash of the MAC address of this Bluetooth device. - // Salt: Randomly generated 256 bit value - // Hash algorithm: HMAC-SHA256 - // Size: 32 byte - // Default: null or empty if the device identifier is not known - optional bytes obfuscated_id = 1 [(android.os.statsd.log_mode) = MODE_BYTES]; - // Where is this device info obtained from - optional android.bluetooth.DeviceInfoSrcEnum source_type = 2; - // Name of the data source - // For EXTERNAL: package name of the data source - // For INTERNAL: null for general case, component name otherwise - optional string source_name = 3; - // Name of the manufacturer of this device - optional string manufacturer = 4; - // Model of this device - optional string model = 5; - // Hardware version of this device - optional string hardware_version = 6; - // Software version of this device - optional string software_version = 7; - // An identifier that can be used to match events for this device. - // The incremental identifier is locally generated and guaranteed not derived - // from any globally unique hardware id. - // For paired devices, it stays consistent between Bluetooth toggling for the - // same remote device. - // For unpaired devices, it stays consistent within the same Bluetooth adapter - // session for the same remote device. - // Default: 0 if the device's metric id is unknown. - optional int32 metric_id = 8; -} - -/** - * Logs when we receive Bluetooth Read Remote Version Information Complete Event from the remote - * device, as documented by the Bluetooth Core HCI specification - * Reference: https://www.bluetooth.com/specifications/bluetooth-core-specification - * Vol 2, Part E, Page 1118 - * - * Logged from: - * system/bt - */ -message BluetoothRemoteVersionInfoReported { - // Connection handle of the connection - // Original type: uint16_t - optional int32 connection_handle = 1; - // HCI command status code - // Default: STATUS_UNKNOWN - optional android.bluetooth.hci.StatusEnum hci_status = 2; - // 1 byte Version of current LMP in the remote controller - optional int32 lmp_version = 3; - // 2 bytes LMP manufacturer code of the remote controller - // https://www.bluetooth.com/specifications/assigned-numbers/company-identifiers - optional int32 lmp_manufacturer_code = 4; - // 4 bytes subversion of the LMP in the remote controller - optional int32 lmp_subversion = 5; -} - -/** - * Logs when certain Bluetooth SDP attributes are discovered - * Constant definitions are from: - * https://www.bluetooth.com/specifications/assigned-numbers/service-discovery - * - * Current logged attributes: - * - BluetoothProfileDescriptorList - * - Supported Features Bitmask - * - * Logged from: - * system/bt - */ -message BluetoothSdpAttributeReported { - // An identifier that can be used to match events for this device. - // Currently, this is a salted hash of the MAC address of this Bluetooth device. - // Salt: Randomly generated 256 bit value - // Hash algorithm: HMAC-SHA256 - optional bytes obfuscated_id = 1 [(android.os.statsd.log_mode) = MODE_BYTES]; - // Short form UUIDs used to identify Bluetooth protocols, profiles, and service classes - // Original type: uint16_t - optional int32 protocol_uuid = 2; - // Short form UUIDs used to identify Bluetooth SDP attribute types - // Original type: uint16_t - optional int32 attribute_id = 3; - // Attribute value for the particular attribute - optional bytes attribute_value = 4 [(android.os.statsd.log_mode) = MODE_BYTES]; - // An identifier that can be used to match events for this device. - // The incremental identifier is locally generated and guaranteed not derived - // from any globally unique hardware id. - // For paired devices, it stays consistent between Bluetooth toggling for the - // same remote device. - // For unpaired devices, it stays consistent within the same Bluetooth adapter - // session for the same remote device. - // Default: 0 if the device's metric id is unknown. - optional int32 metric_id = 5; -} - -/** - * Logs when bond state of a Bluetooth device changes - * - * Logged from: - * frameworks/base/core/java/android/bluetooth/BluetoothDevice.java - * packages/apps/Bluetooth/src/com/android/bluetooth/btservice/BondStateMachine.java - */ -message BluetoothBondStateChanged { - // An identifier that can be used to match events for this device. - // Currently, this is a salted hash of the MAC address of this Bluetooth device. - // Salt: Randomly generated 256 bit value - // Hash algorithm: HMAC-SHA256 - // Size: 32 byte - // Default: null or empty if the device identifier is not known - optional bytes obfuscated_id = 1 [(android.os.statsd.log_mode) = MODE_BYTES]; - // Preferred transport type to remote dual mode device - // Default: TRANSPORT_AUTO means no preference - optional android.bluetooth.TransportTypeEnum transport = 2; - // The type of this Bluetooth device (Classic, LE, or Dual mode) - // Default: UNKNOWN - optional android.bluetooth.DeviceTypeEnum type = 3; - // Current bond state (NONE, BONDING, BONDED) - // Default: BOND_STATE_UNKNOWN - optional android.bluetooth.BondStateEnum bond_state = 4; - // Bonding sub state - // Default: BOND_SUB_STATE_UNKNOWN - optional android.bluetooth.BondSubStateEnum bonding_sub_state = 5; - // Unbond Reason - // Default: UNBOND_REASON_UNKNOWN - optional android.bluetooth.UnbondReasonEnum unbond_reason = 6; - // An identifier that can be used to match events for this device. - // The incremental identifier is locally generated and guaranteed not derived - // from any globally unique hardware id. - // For paired devices, it stays consistent between Bluetooth toggling for the - // same remote device. - // For unpaired devices, it stays consistent within the same Bluetooth adapter - // session for the same remote device. - // Default: 0 if the device's metric id is unknown. - optional int32 metric_id = 7; -} - -/** - * Logs there is an event related Bluetooth classic pairing - * - * Logged from: - * system/bt - */ -message BluetoothClassicPairingEventReported { - // An identifier that can be used to match events for this device. - // Currently, this is a salted hash of the MAC address of this Bluetooth device. - // Salt: Randomly generated 256 bit value - // Hash algorithm: HMAC-SHA256 - // Size: 32 byte - // Default: null or empty if the device identifier is not known - optional bytes obfuscated_id = 1 [(android.os.statsd.log_mode) = MODE_BYTES]; - // Connection handle of this connection if available - // Range: 0x0000 - 0x0EFF (12 bits) - // Default: 0xFFFF if the handle is unknown - optional int32 connection_handle = 2; - // HCI command associated with this event - // Default: CMD_UNKNOWN - optional android.bluetooth.hci.CommandEnum hci_cmd = 3; - // HCI event associated with this event - // Default: EVT_UNKNOWN - optional android.bluetooth.hci.EventEnum hci_event = 4; - // HCI command status code if this is triggerred by hci_cmd - // Default: STATUS_UNKNOWN - optional android.bluetooth.hci.StatusEnum cmd_status = 5; - // HCI reason code associated with this event - // Default: STATUS_UNKNOWN - optional android.bluetooth.hci.StatusEnum reason_code = 6; - // A status value related to this specific event - // Default: 0 - optional int64 event_value = 7; - // An identifier that can be used to match events for this device. - // The incremental identifier is locally generated and guaranteed not derived - // from any globally unique hardware id. - // For paired devices, it stays consistent between Bluetooth toggling for the - // same remote device. - // For unpaired devices, it stays consistent within the same Bluetooth adapter - // session for the same remote device. - // Default: 0 if the device's metric id is unknown. - optional int32 metric_id = 8; -} - -/** - * Logs when there is an event related to Bluetooth Security Manager Protocol (SMP) - * - * Logged from: - * system/bt - */ -message BluetoothSmpPairingEventReported { - // An identifier that can be used to match events for this device. - // Currently, this is a salted hash of the MAC address of this Bluetooth device. - // Salt: Randomly generated 256 bit value - // Hash algorithm: HMAC-SHA256 - // Size: 32 byte - // Default: null or empty if the device identifier is not known - optional bytes obfuscated_id = 1 [(android.os.statsd.log_mode) = MODE_BYTES]; - // SMP command sent or received over L2CAP - // Default: CMD_UNKNOWN - optional android.bluetooth.smp.CommandEnum smp_command = 2; - // Whether this command is sent or received - // Default: DIRECTION_UNKNOWN - optional android.bluetooth.DirectionEnum direction = 3; - // SMP failure reason code - // Default: PAIRING_FAIL_REASON_DEFAULT - optional android.bluetooth.smp.PairingFailReasonEnum smp_fail_reason = 4; - // An identifier that can be used to match events for this device. - // The incremental identifier is locally generated and guaranteed not derived - // from any globally unique hardware id. - // For paired devices, it stays consistent between Bluetooth toggling for the - // same remote device. - // For unpaired devices, it stays consistent within the same Bluetooth adapter - // session for the same remote device. - // Default: 0 if the device's metric id is unknown. - optional int32 metric_id = 5; -} - -/** - * Logs when a Bluetooth socket’s connection state changed - * - * Logged from: - * system/bt - */ -message BluetoothSocketConnectionStateChanged { - // An identifier that can be used to match events for this device. - // Currently, this is a salted hash of the MAC address of this Bluetooth device. - // Salt: Randomly generated 256 bit value - // Hash algorithm: HMAC-SHA256 - // Size: 32 byte - // Default: null or empty if this is a server listener socket - optional bytes obfuscated_id = 1 [(android.os.statsd.log_mode) = MODE_BYTES]; - // Temporary port of this socket for the current connection or session only - // Default 0 when unknown or don't care - optional int32 port = 2; - // Socket type as mentioned in - // frameworks/base/core/java/android/bluetooth/BluetoothSocket.java - // Default: SOCKET_TYPE_UNKNOWN - optional android.bluetooth.SocketTypeEnum type = 3; - // Socket connection state - // Default: SOCKET_CONNECTION_STATE_UNKNOWN - optional android.bluetooth.SocketConnectionstateEnum state = 4; - // Number of bytes sent to remote device during this connection - optional int64 tx_bytes = 5; - // Number of bytes received from remote device during this connection - optional int64 rx_bytes = 6; - // Socket owner's UID - optional int32 uid = 7 [(is_uid) = true]; - // Server port of this socket, if any. When both |server_port| and |port| fields are populated, - // |port| must be spawned by |server_port| - // Default 0 when unknown or don't care - optional int32 server_port = 8; - // Whether this is a server listener socket - optional android.bluetooth.SocketRoleEnum is_server = 9; - // An identifier that can be used to match events for this device. - // The incremental identifier is locally generated and guaranteed not derived - // from any globally unique hardware id. - // For paired devices, it stays consistent between Bluetooth toggling for the - // same remote device. - // For unpaired devices, it stays consistent within the same Bluetooth adapter - // session for the same remote device. - // Default: 0 if the device's metric id is unknown. - optional int32 metric_id = 10; -} - -/** - * Logs when Class of Device (CoD) value is learnt for a device during pairing or connection - * - * Logged from: - * packages/apps/Bluetooth/src/com/android/bluetooth/btservice/BondStateMachine.java - * packages/apps/Bluetooth/src/com/android/bluetooth/btservice/RemoteDevices.java - * - */ -message BluetoothClassOfDeviceReported { - // An identifier that can be used to match events for this device. - // Currently, this is a salted hash of the MAC address of this Bluetooth device. - // Salt: Randomly generated 256 bit value - // Hash algorithm: HMAC-SHA256 - // Size: 32 byte - // Default: null or empty if this is a server listener socket - optional bytes obfuscated_id = 1 [(android.os.statsd.log_mode) = MODE_BYTES]; - // Class of Device (CoD) value including both Major, Minor device class and service class - // Defined in: https://www.bluetooth.com/specifications/assigned-numbers/baseband - // Also defined in: https://developer.android.com/reference/android/bluetooth/BluetoothClass - // Default: 0 - optional int32 class_of_device = 2; - // An identifier that can be used to match events for this device. - // The incremental identifier is locally generated and guaranteed not derived - // from any globally unique hardware id. - // For paired devices, it stays consistent between Bluetooth toggling for the - // same remote device. - // For unpaired devices, it stays consistent within the same Bluetooth adapter - // session for the same remote device. - // Default: 0 if the device's metric id is unknown. - optional int32 metric_id = 3; -} - -/** - * Logs when something is plugged into or removed from the USB-C connector. - * - * Logged from: - * UsbService - */ -message UsbConnectorStateChanged { - enum State { - STATE_DISCONNECTED = 0; - STATE_CONNECTED = 1; - } - optional State state = 1 - [(state_field_option).exclusive_state = true, (state_field_option).nested = false]; - optional string id = 2 [(state_field_option).primary_field = true]; - // Last active session in ms. - // 0 when the port is in connected state. - optional int64 last_connect_duration_millis = 3; -} - -/** - * Logs the reported speaker impedance. - * - * Logged from: - * Vendor audio implementation. - */ -message SpeakerImpedanceReported { - optional int32 speaker_location = 1; - optional int32 impedance = 2; -} - -/** - * Logs the report of a failed hardware. - * - * Logged from: - * Vendor HALs. - * - */ -message HardwareFailed { - enum HardwareType { - HARDWARE_FAILED_UNKNOWN = 0; - HARDWARE_FAILED_MICROPHONE = 1; - HARDWARE_FAILED_CODEC = 2; - HARDWARE_FAILED_SPEAKER = 3; - HARDWARE_FAILED_FINGERPRINT = 4; - } - optional HardwareType hardware_type = 1; - - /** - * hardware_location allows vendors to differentiate between multiple instances of - * the same hardware_type. The specific locations are vendor defined integers, - * referring to board-specific numbering schemes. - */ - optional int32 hardware_location = 2; - - /** - * failure_code is specific to the HardwareType of the failed hardware. - * It should use one of the enum values defined below. - */ - enum HardwareErrorCode { - UNKNOWN = 0; - COMPLETE = 1; - SPEAKER_HIGH_Z = 2; - SPEAKER_SHORT = 3; - FINGERPRINT_SENSOR_BROKEN = 4; - FINGERPRINT_TOO_MANY_DEAD_PIXELS = 5; - DEGRADE = 6; - } - optional int32 failure_code = 3; -} - -/** - * Log an event when the device has been physically dropped. - * Reported from the /vendor partition. - */ -message PhysicalDropDetected { - // Confidence that the event was actually a drop, 0 -> 100 - optional int32 confidence_pctg = 1; - // Peak acceleration of the drop, in 1/1000s of a g. - optional int32 accel_peak_thousandths_g = 2; - // Duration of freefall in ms - optional int32 freefall_time_millis = 3; -} - -/** - * Log bucketed battery charge cycles. - * - * Each bucket represents cycles of the battery past - * a given charge point. For example, if 10 cycle buckets are - * initialized, bucket 1 is the lowest 1/10th of the battery, - * and bucket 10 is 100%. - * - * Logged from: - * /sys/class/power_supply/bms/cycle_count, via Vendor. - */ -message ChargeCyclesReported { - optional int32 cycle_bucket_1 = 1; - optional int32 cycle_bucket_2 = 2; - optional int32 cycle_bucket_3 = 3; - optional int32 cycle_bucket_4 = 4; - optional int32 cycle_bucket_5 = 5; - optional int32 cycle_bucket_6 = 6; - optional int32 cycle_bucket_7 = 7; - optional int32 cycle_bucket_8 = 8; - optional int32 cycle_bucket_9 = 9; - optional int32 cycle_bucket_10 = 10; -} - -/** - * Log battery health snapshot. - * - * Resistance, Voltage, Open Circuit Voltage, Temperature, and Charge Level - * are snapshotted periodically over 24hrs. - */ -message BatteryHealthSnapshot { - enum BatterySnapshotType { - UNKNOWN = 0; - MIN_TEMP = 1; // Snapshot at min batt temp over 24hrs. - MAX_TEMP = 2; // Snapshot at max batt temp over 24hrs. - MIN_RESISTANCE = 3; // Snapshot at min batt resistance over 24hrs. - MAX_RESISTANCE = 4; // Snapshot at max batt resistance over 24hrs. - MIN_VOLTAGE = 5; // Snapshot at min batt voltage over 24hrs. - MAX_VOLTAGE = 6; // Snapshot at max batt voltage over 24hrs. - MIN_CURRENT = 7; // Snapshot at min batt current over 24hrs. - MAX_CURRENT = 8; // Snapshot at max batt current over 24hrs. - MIN_BATT_LEVEL = 9; // Snapshot at min battery level (SoC) over 24hrs. - MAX_BATT_LEVEL = 10; // Snapshot at max battery level (SoC) over 24hrs. - AVG_RESISTANCE = 11; // Snapshot at average battery resistance over 24hrs. - } - optional BatterySnapshotType type = 1; - // Temperature, in 1/10ths of degree C. - optional int32 temperature_deci_celsius = 2; - // Voltage Battery Voltage, in microVolts. - optional int32 voltage_micro_volt = 3; - // Current Battery current, in microAmps. - optional int32 current_micro_amps = 4; - // OpenCircuitVoltage Battery Open Circuit Voltage, in microVolts. - optional int32 open_circuit_micro_volt = 5; - // Resistance Battery Resistance, in microOhms. - optional int32 resistance_micro_ohm = 6; - // Level Battery Level, as % of full. - optional int32 level_percent = 7; -} - -/** - * Log slow I/O operations on the primary storage. - */ -message SlowIo { - // Classifications of IO Operations. - enum IoOperation { - UNKNOWN = 0; - READ = 1; - WRITE = 2; - UNMAP = 3; - SYNC = 4; - } - optional IoOperation operation = 1; - - // The number of slow IO operations of this type over 24 hours. - optional int32 count = 2; -} - -/** - * Log battery caused shutdown with the last recorded voltage. - */ -message BatteryCausedShutdown { - // The last recorded battery voltage prior to shutdown. - optional int32 last_recorded_micro_volt = 1; -} - -/** - * Logs when ThermalService receives throttling events. - * - * Logged from: - * frameworks/base/services/core/java/com/android/server/stats/StatsCompanionService.java - */ -message ThermalThrottlingSeverityStateChanged { - // The type of temperature being reported (CPU, GPU, SKIN, etc) - optional android.os.TemperatureTypeEnum sensor_type = 1; - - // The name of the temperature source. Eg. CPU0 - optional string sensor_name = 2; - - // Temperature in tenths of a degree C. - // For BCL, it is decimillivolt, decimilliamps, and percentage * 10. - optional int32 temperature_deci_celsius = 3; - - // Relative severity of the throttling, see enum definition. - optional android.os.ThrottlingSeverityEnum severity = 4; -} - -/** - * Logs the duration of a davey (jank of >=700ms) when it occurs - * - * Logged from: - * frameworks/base/libs/hwui/JankTracker.cpp - */ -message DaveyOccurred { - // The UID that logged this atom. - optional int32 uid = 1 [(is_uid) = true]; - - // Amount of time it took to render the frame. Should be >=700ms. - optional int64 jank_duration_millis = 2; -} - -/** - * Logs phone signal strength changes. - * - * Logged from: - * frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java - */ -message PhoneSignalStrengthChanged { - // Signal strength, from frameworks/base/core/proto/android/telephony/enums.proto. - optional android.telephony.SignalStrengthEnum signal_strength = 1; -} - - -/** - * Logs when the phone state, sim state or signal strength changes - * - * Logged from: - * frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java - */ -message PhoneServiceStateChanged { - optional android.telephony.ServiceStateEnum state = 1; - optional android.telephony.SimStateEnum sim_state = 2; - optional android.telephony.SignalStrengthEnum signal_strength = 3; -} - -/** - * Logs when the phone becomes on or off. - * - * Logged from: - * frameworks/base/core/java/com/android/internal/os/TelephonyRegistry.java - */ -message PhoneStateChanged { - enum State { - OFF = 0; - ON = 1; - } - optional State state = 1; -} - -message BackGesture { - enum BackType { - DEFAULT_BACK_TYPE = 0; - COMPLETED = 1; - COMPLETED_REJECTED = 2; // successful because coming from rejected area - INCOMPLETE_EXCLUDED = 3; // would have been successful but in the exclusion area - INCOMPLETE = 4; // Unsuccessful, for reasons other than below. - INCOMPLETE_FAR_FROM_EDGE = 5; // Unsuccessful, far from the edge. - INCOMPLETE_MULTI_TOUCH = 6; // Unsuccessful, multi touch. - INCOMPLETE_LONG_PRESS = 7; // Unsuccessful, long press. - INCOMPLETE_VERTICAL_MOVE = 8; // Unsuccessful, move vertically. - } - optional BackType type = 1; - - optional int32 y_coordinate = 2 [deprecated = true]; // y coordinate for ACTION_DOWN event - optional int32 start_x = 4; // X coordinate for ACTION_DOWN event. - optional int32 start_y = 5; // Y coordinate for ACTION_DOWN event. - optional int32 end_x = 6; // X coordinate for ACTION_MOVE event. - optional int32 end_y = 7; // Y coordinate for ACTION_MOVE event. - optional int32 left_boundary = 8; // left edge width + left inset - optional int32 right_boundary = 9; // screen width - (right edge width + right inset) - // The score between 0 and 1 which is the prediction output for the Back Gesture model. - optional float ml_model_score = 10; - optional string package_name = 11; // The name of the top 100 most used package by all users. - - enum WindowHorizontalLocation { - DEFAULT_LOCATION = 0; - LEFT = 1; - RIGHT = 2; - } - optional WindowHorizontalLocation x_location = 3 [deprecated = true]; -} - -message ExclusionRectStateChanged { - optional string component_name = 1; // if not available, simply packageName - optional int32 requested_height = 2; // px - optional int32 rejected_height = 3; // px - - enum WindowHorizontalLocation { - DEFAULT_LOCATION = 0; - LEFT = 1; - RIGHT = 2; - } - optional WindowHorizontalLocation x_location = 4; - optional bool landscape = 5; - optional bool splitscreen = 6; - optional int32 duration_millis = 7; -} - -/** - * Logs when IME is on. - * - * Logged from: /packages/SystemUI/src/com/android/systemui/ - statusbar/phone/NavigationBarView.java - * - */ -message ImeTouchReported { - optional int32 x_coordinate = 1; // X coordinate for ACTION_DOWN event. - optional int32 y_coordinate = 2; // Y coordinate for ACTION_DOWN event. -} - -/** - * Logs when Launcher (HomeScreen) UI has changed or was interacted. - * - * Logged from: - * packages/apps/Launcher3 - */ -message LauncherUIChanged { - optional android.stats.launcher.LauncherAction action = 1 [deprecated = true]; - optional android.stats.launcher.LauncherState src_state = 2; - optional android.stats.launcher.LauncherState dst_state = 3; - optional android.stats.launcher.LauncherExtension extension = 4 [(log_mode) = MODE_BYTES, deprecated = true]; - optional bool is_swipe_up_enabled = 5 [deprecated = true]; - - // The event id (e.g., app launch, drag and drop, long press) - optional int32 event_id = 6; - // The event's source or target id (e.g., icon, task, button) - optional int32 target_id = 7; - // If the target needs to be tracked, use this id field - optional int32 instance_id = 8; - optional int32 uid = 9 [(is_uid) = true]; - optional string package_name = 10; - optional string component_name = 11; - - // (x, y) coordinate and the index information of the target on the container - optional int32 grid_x = 12 [default = -1]; - optional int32 grid_y = 13 [default = -1]; - optional int32 page_id = 14 [default = -2]; - - // e.g., folder icon's (x, y) location and index information on the workspace - optional int32 grid_x_parent = 15 [default = -1]; - optional int32 grid_y_parent = 16 [default = -1]; - optional int32 page_id_parent = 17 [default = -2]; - - // e.g., SEARCHBOX_ALLAPPS, FOLDER_WORKSPACE - optional int32 hierarchy = 18; - - optional bool is_work_profile = 19; - - // Used to store the predicted rank of the target - optional int32 rank = 20 [default = -1]; - - // e.g., folderLabelState can be captured in the following two fields - optional int32 from_state = 21; - optional int32 to_state = 22; - - // e.g., autofilled or suggested texts that are not user entered - optional string edittext = 23; - - // e.g., number of contents inside a container (e.g., icons inside a folder) - optional int32 cardinality = 24; -} - -/** - * Used for snapshot of the HomeScreen UI elements - * - * Logged from: - * packages/apps/Launcher3 - */ -message LauncherStaticLayout { - // The event id (e.g., snapshot, drag and drop) - optional int32 event_id = 1; - // The event's source or target id (e.g., icon, shortcut, widget) - optional int32 target_id = 2; - // If the target needs to be tracked, use this id field - optional int32 instance_id = 3; - optional int32 uid = 4 [(is_uid) = true]; - optional string package_name = 5; - optional string component_name = 6; - - // (x, y) coordinate and the index information of the target on the container - optional int32 grid_x = 7 [default = -1]; - optional int32 grid_y = 8 [default = -1]; - optional int32 page_id = 9 [default = -2]; - - // e.g., folder icon's (x, y) location and index information on the workspace - // e.g., when used with widgets target, use these values for (span_x, span_y) - optional int32 grid_x_parent = 10 [default = -1]; - optional int32 grid_y_parent = 11 [default = -1]; - optional int32 page_id_parent = 12 [default = -2]; - - // UNKNOWN = 0 - // HOTSEAT = 1 - // WORKSPACE = 2 - // FOLDER_HOTSEAT = 3 - // FOLDER_WORKSPACE = 4 - optional int32 hierarchy = 13; - - optional bool is_work_profile = 14; - - // e.g., PIN, WIDGET TRAY, APPS TRAY, PREDICTION - optional int32 origin = 15; - - // e.g., number of icons inside a folder - optional int32 cardinality = 16; - - // e.g., (x, y) span of the widget inside homescreen grid system - optional int32 span_x = 17 [default = 1]; - optional int32 span_y = 18 [default = 1]; -} - -/** - * Logs when Wallpaper or ThemePicker UI has changed. - * - * Logged from: - * packages/apps/ThemePicker - * packages/apps/WallpaperPicker2 - */ -message StyleUIChanged { - optional android.stats.style.Action action = 1; - optional int32 color_package_hash = 2; - optional int32 font_package_hash = 3; - optional int32 shape_package_hash = 4; - optional int32 clock_package_hash = 5; - optional int32 launcher_grid = 6; - optional int32 wallpaper_category_hash = 7; - optional int32 wallpaper_id_hash = 8; - optional int32 color_preference = 9; - optional android.stats.style.LocationPreference location_preference = 10; - optional android.stats.style.DatePreference date_preference = 11; - optional android.stats.style.LaunchedPreference launched_preference = 12; -} - -/** - * Logs when Settings UI has changed. - * - * Logged from: - * packages/apps/Settings - */ -message SettingsUIChanged { - /** - * Where this SettingsUIChange event comes from. For example, if - * it's a PAGE_VISIBLE event, where the page is opened from. - */ - optional android.app.settings.PageId attribution = 1; - - /** - * What the UI action is. - */ - optional android.app.settings.Action action = 2; - - /** - * Where the action is happening - */ - optional android.app.settings.PageId page_id = 3; - - /** - * What preference changed in this event. - */ - optional string changed_preference_key = 4; - - /** - * The new value of the changed preference. - */ - optional int64 changed_preference_int_value = 5; -} - -/** - * Logs basic timing information about touch events. - * Reported at most every 5 minutes while device is being interacted with. - * - * Logged from: - * frameworks/native/services/inputflinger - */ -message TouchEventReported { - /** - * The fields latency_{min|max|mean|stdev} represent minimum, maximum, mean, - * and the standard deviation of the time spent processing touchscreen events - * in the kernel and inputflinger. The units are microseconds. - * - * On supported devices, the starting point is taken during the hard interrupt inside the - * kernel touch driver. On all other devices, the starting point is taken inside - * the kernel's input event subsystem upon receipt of the input event. - * The ending point is taken inside InputDispatcher, just after the input event - * is sent to the app. - */ - // Minimum value - optional float latency_min_micros = 1; - // Maximum value - optional float latency_max_micros = 2; - // Average value - optional float latency_mean_micros = 3; - // Standard deviation - optional float latency_stdev_micros = 4; - // Number of touch events (input_event) in this report - optional int32 count = 5; -} - -/** - * Logs gesture classification and timing information for touch events. - * - * Logged from: - * frameworks/base/core/java/android/view/GestureDetector.java - * frameworks/base/core/java/android/view/View.java - */ -message TouchGestureClassified { - // The source of the classification (e.g. Java class name). - optional string source = 1; - - enum Classification { - UNKNOWN_CLASSIFICATION = 0; - SINGLE_TAP = 1; - DOUBLE_TAP = 2; - LONG_PRESS = 3; - DEEP_PRESS = 4; - SCROLL = 5; - } - // The classification of the gesture. - optional Classification classification = 2; - - // The interval from the start of a touch event stream until the - // classification was made. - optional int32 latency_millis = 3; - - // The distance from the location of the first touch event to the - // location of the touch event when the classification was made. - optional float displacement_px = 4; -} - -/** - * Logs that a setting was updated. - * Logged from: - * frameworks/base/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java - * The tag and is_default allow resetting of settings to default values based on the specified - * tag. See Settings#putString(ContentResolver, String, String, String, boolean) for more details. - */ -message SettingChanged { - // The name of the setting. - optional string setting = 1; - - // The change being imposed on this setting. May represent a number, eg "3". - optional string value = 2; - - // The new value of this setting. For most settings, this is same as value. For some settings, - // value is +X or -X where X represents an element in a set. For example, if the previous value - // is A,B,C and value is -B, then new_value is A,C and prev_value is A,B,C. - // The +/- feature is currently only used for location_providers_allowed. - optional string new_value = 3; - - // The previous value of this setting. - optional string prev_value = 4; - - // The tag used with the is_default for resetting sets of settings. This is generally null. - optional string tag = 5; - - // True if this setting with tag should be resettable. - optional bool is_default = 6; - - // The associated user (for multi-user feature). Defined in android/os/UserHandle.java - optional int32 user = 7; - - enum ChangeReason { - UPDATED = 1; // Updated can be an insertion or an update. - DELETED = 2; - } - optional ChangeReason reason = 8; -} - -/** - * Logs activity going to foreground or background - * - * Logged from: - * frameworks/base/services/core/java/com/android/server/am/ActivityRecord.java - */ -message ActivityForegroundStateChanged { - optional int32 uid = 1 [(is_uid) = true]; - optional string pkg_name = 2; - optional string class_name = 3; - - enum State { - BACKGROUND = 0; - FOREGROUND = 1; - } - optional State state = 4; -} - -/** - * Logs when a volume entered low Storage state. - * Logged from: - * frameworks/base/services/core/java/com/android/server/storage/DeviceStorageMonitorService.java - */ -message LowStorageStateChanged { - // Volume that ran out of storage. - optional string volume_description = 1; - - enum State { - UNKNOWN = 0; - OFF = 1; - ON = 2; - } - optional State state = 2; -} - -/** - * Logs when an app is downgraded. - * Logged from: - * frameworks/base/services/core/java/com/android/server/pm/BackgroundDexOptService.java - */ -message AppDowngraded { - optional string package_name = 1; - // Size of the package (all data) before being downgraded. - optional int64 size_in_bytes_before = 2; - // Size of the package (all data) after being downgraded. - optional int64 size_in_bytes_after = 3; - - optional bool aggressive = 4; -} - -/** - * Logs when an app is optimized after being downgraded. - * Logged from: - * frameworks/base/services/core/java/com/android/server/pm/BackgroundDexOptService.java - */ -message AppOptimizedAfterDowngraded { - optional string package_name = 1; -} - -/** - * Logs whenever an app is installed on external storage. - * Logged from: - frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java - */ -message AppInstallOnExternalStorageReported { - // The type of external storage. - optional android.stats.storage.ExternalStorageType storage_type = 1; - // The name of the package that is installed on the sd card. - optional string package_name = 2; -} - -/** - * Logs when an app crashes. - * Logged from: - * frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java - */ -message AppCrashOccurred { - optional int32 uid = 1 [(is_uid) = true]; - - optional string event_type = 2; - - // The name of the process. - // system_server if it is not by an app - optional string process_name = 3; - - // The pid if available. -1 means not available. - optional int32 pid = 4; - - optional string package_name = 5; - - enum InstantApp { - UNAVAILABLE = 0; - FALSE = 1; - TRUE = 2; - } - optional InstantApp is_instant_app = 6; - - enum ForegroundState { - UNKNOWN = 0; - BACKGROUND = 1; - FOREGROUND = 2; - } - optional ForegroundState foreground_state = 7; - - optional android.server.ErrorSource error_source = 8; - - optional bool is_package_loading = 9; -} - -/** - * Logs when a WTF (What a Terrible Failure) happened. - * Logged from: - * frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java - */ -message WTFOccurred { - optional int32 uid = 1 [(is_uid) = true]; - - optional string tag = 2; - - // The name of the process. - // system_server if it is not by an app - optional string process_name = 3; - - // The pid if available. -1 means not available. - optional int32 pid = 4; - - optional android.server.ErrorSource error_source = 5; -} - -/** - * Logs when system server reports low memory. - * Logged from: - * frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java - */ -message LowMemReported { -} - -/** - * Logs when an app ANR (App Not Responding) occurs. - * Logged from: - * frameworks/base/services/core/java/com/android/server/am/AppErrors.java - */ -message ANROccurred { - optional int32 uid = 1 [(is_uid) = true]; - - optional string process_name = 2; - - optional string short_component_name = 3; - - optional string reason = 4; - - enum InstantApp { - UNAVAILABLE = 0; - FALSE = 1; - TRUE = 2; - } - optional InstantApp is_instant_app = 5; - - enum ForegroundState { - UNKNOWN = 0; - BACKGROUND = 1; - FOREGROUND = 2; - } - optional ForegroundState foreground_state = 6; - - optional android.server.ErrorSource error_source = 7; - - optional string package_name = 8; - - optional bool is_package_loading = 9; -} - -/** - * Logs when the vibrator state changes. - * Logged from: - * frameworks/base/services/core/java/com/android/server/VibratorService.java - */ -message VibratorStateChanged { - repeated AttributionNode attribution_node = 1; - - enum State { - OFF = 0; - ON = 1; - } - optional State state = 2; - - // Duration (in milliseconds) requested to keep the vibrator on. - // Only applicable for State == ON. - optional int64 duration_millis = 3; -} - -/* - * Allows other apps to push events into statsd. - * Logged from: - * frameworks/base/core/java/android/util/StatsLog.java - */ -message AppBreadcrumbReported { - // The uid of the application that sent this custom atom. - optional int32 uid = 1 [(is_uid) = true]; - - // An arbitrary label chosen by the developer. For Android P, the label should be in [0, 16). - optional int32 label = 2; - - // Allows applications to easily use a custom event as start/stop boundaries (ie, define custom - // predicates for the metrics). - enum State { - UNKNOWN = 0; - UNSPECIFIED = 1; // For events that are known to not represent START/STOP. - STOP = 2; - START = 3; - } - optional State state = 3; -} - -/** - * Logs the wall-clock time when a significant wall-clock time shift occurs. - * For example, this could be due to the user manually changing the time. - * - * Logged from: - * frameworks/base/services/core/java/com/android/server/AlarmManagerService.java - */ -message WallClockTimeShifted { - // New wall-clock time in milliseconds, according to System.currentTimeMillis(). - optional int64 wall_clock_timestamp_millis = 1; -} - -/** - * Logs when statsd detects an anomaly. - * - * Logged from: - * frameworks/base/cmds/statsd/src/anomaly/AnomalyTracker.cpp - */ -message AnomalyDetected { - // Uid that owns the config whose anomaly detection alert fired. - optional int32 config_uid = 1 [(is_uid) = true]; - - // Id of the config whose anomaly detection alert fired. - optional int64 config_id = 2; - - // Id of the alert (i.e. name of the anomaly that was detected). - optional int64 alert_id = 3; -} - -message AppStartOccurred { - // The uid if available. -1 means not available. - optional int32 uid = 1 [(is_uid) = true]; - - // The app package name. - optional string pkg_name = 2; - - enum TransitionType { - UNKNOWN = 0; - WARM = 1; - HOT = 2; - COLD = 3; - RELAUNCH = 4; - } - // The transition type. - optional TransitionType type = 3; - - // The activity name. - optional string activity_name = 4; - - // The name of the calling app. Empty if not set. - optional string calling_pkg_name = 5; - - // Whether the app is an instant app. - optional bool is_instant_app = 6; - - // Device uptime when activity started. - optional int64 activity_start_millis = 7; - - optional android.app.AppTransitionReasonEnum reason = 8; - - optional int32 transition_delay_millis = 9; - // -1 if not set. - optional int32 starting_window_delay_millis = 10; - // -1 if not set. - optional int32 bind_application_delay_millis = 11; - optional int32 windows_drawn_delay_millis = 12; - - // Empty if not set. - optional string launch_token = 13; - - // The compiler filter used when when the package was optimized. - optional int32 package_optimization_compilation_filter = 14; - - // The reason why the package was optimized. - optional int32 package_optimization_compilation_reason = 15; - - enum SourceType { - UNAVAILABLE = 0; - LAUNCHER = 1; - NOTIFICATION = 2; - LOCKSCREEN = 3; - RECENTS_ANIMATION = 4; - } - // The type of the startup source. - optional SourceType source_type = 16; - - // The time from the startup source to the beginning of handling the startup event. - // -1 means not available. - optional int32 source_event_delay_millis = 17; -} - -message AppStartCanceled { - // The uid if available. -1 means not available. - optional int32 uid = 1 [(is_uid) = true]; - - // The app package name. - optional string pkg_name = 2; - - enum TransitionType { - UNKNOWN = 0; - WARM = 1; - HOT = 2; - COLD = 3; - RELAUNCH = 4; - } - // The transition type. - optional TransitionType type = 3; - - // The activity name. - optional string activity_name = 4; -} - -message AppStartFullyDrawn { - // The uid if available. -1 means not available. - optional int32 uid = 1 [(is_uid) = true]; - - // The app package name. - optional string pkg_name = 2; - - enum TransitionType { - UNKNOWN = 0; - WITH_BUNDLE = 1; - WITHOUT_BUNDLE = 2; - } - // The transition type. - optional TransitionType type = 3; - - // The activity name. - optional string activity_name = 4; - - optional bool transition_process_running = 5; - - // App startup time (until call to Activity#reportFullyDrawn()). - optional int64 app_startup_time_millis = 6; - - // The compiler filter used when when the package was optimized. - optional int32 package_optimization_compilation_filter = 7; - - // The reason why the package was optimized. - optional int32 package_optimization_compilation_reason = 8; - - enum SourceType { - UNAVAILABLE = 0; - LAUNCHER = 1; - NOTIFICATION = 2; - LOCKSCREEN = 3; - } - // The type of the startup source. - optional SourceType source_type = 9; - - // The time from the startup source to the beginning of handling the startup event. - // -1 means not available. - optional int32 source_event_delay_millis = 10; -} - -/** - * Logs a picture-in-picture action - * Logged from: - * frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java - * frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java - * frameworks/base/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java - */ -message PictureInPictureStateChanged { - // -1 if it is not available - optional int32 uid = 1 [(is_uid) = true]; - - optional string short_name = 2; - - enum State { - ENTERED = 1; - EXPANDED_TO_FULL_SCREEN = 2; - MINIMIZED = 3; - DISMISSED = 4; - } - optional State state = 3; -} - -/** - * Logs overlay action - * Logged from: - * services/core/java/com/android/server/wm/Session.java - */ -message OverlayStateChanged { - optional int32 uid = 1 [(state_field_option).primary_field = true, (is_uid) = true]; - - optional string package_name = 2 [(state_field_option).primary_field = true]; - - optional bool using_alert_window = 3; - - enum State { - ENTERED = 1; - EXITED = 2; - } - optional State state = 4 - [(state_field_option).exclusive_state = true, (state_field_option).nested = false]; -} - -/** - * Logs foreground service starts and stops. - * Note that this is not when a service starts or stops, but when it is - * considered foreground. - * Logged from - * frameworks/base/services/core/java/com/android/server/am/ActiveServices.java - */ -message ForegroundServiceStateChanged { - optional int32 uid = 1 [(is_uid) = true]; - // package_name + "/" + class_name - optional string short_name = 2; - - enum State { - ENTER = 1; - EXIT = 2; - } - optional State state = 3; - - // Whether the fgs is allowed while-in-use permissions, i.e. is considered 'in-use' to the user. - // (If the fgs was started while the app wasn't TOP it usually will be denied these permissions) - optional bool allow_while_in_use_permission = 4; -} - -/** - * Logs the number of times a uid accesses a sensitive AppOp during a foreground service session. - * A foreground service session is any continuous period during which the uid holds at least one - * foreground service; the atom will be pushed when the uid no longer holds any foreground services. - * Accesses initiated while the uid is in the TOP state are ignored. - * Sessions with no attempted accesses are not logged. - * Logged from - * frameworks/base/services/core/java/com/android/server/am/ActiveServices.java - */ -message ForegroundServiceAppOpSessionEnded { - optional int32 uid = 1 [(is_uid) = true]; - - // The operation's name. - // Only following four ops are logged - // COARSE_LOCATION = 0 - // FINE_LOCATION = 1 - // CAMERA = 26 - // RECORD_AUDIO = 27 - optional android.app.AppOpEnum app_op_name = 2 [default = APP_OP_NONE]; - - // The uid's permission mode for accessing the AppOp during this fgs session. - enum Mode { - MODE_UNKNOWN = 0; - MODE_ALLOWED = 1; // Always allowed - MODE_IGNORED = 2; // Denied - MODE_FOREGROUND = 3; // Allow-while-in-use (or allowed-one-time) - } - optional Mode app_op_mode = 3; - - // Number of times this AppOp was requested and allowed. - optional int32 count_ops_accepted = 4; - // Number of times this AppOp was requested but denied. - optional int32 count_ops_rejected = 5; -} - -/** - * Logs creation or removal of an isolated uid. Isolated uid's are temporary uid's to sandbox risky - * behavior in its own uid. However, the metrics of these isolated uid's almost always should be - * attributed back to the parent (host) uid. One example is Chrome. - * - * Logged from: - * frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java - */ -message IsolatedUidChanged { - // The host UID. Generally, we should attribute metrics from the isolated uid to the host uid. - // NOTE: DO NOT annotate uid field in this atom. This atom is specially handled in statsd. - // This field is ignored when event == REMOVED. - optional int32 parent_uid = 1; - - optional int32 isolated_uid = 2; - - // We expect an isolated uid to be removed before if it's used for another parent uid. - enum Event { - REMOVED = 0; - CREATED = 1; - } - optional Event event = 3; -} - -/* - * Logs the reception of an incoming network packet causing the main system to wake up for - * processing that packet. These events are notified by the kernel via Netlink NFLOG to Netd - * and processed by WakeupController.cpp. - */ -message PacketWakeupOccurred { - // The uid owning the socket into which the packet was delivered, or -1 if the packet was - // delivered nowhere. - optional int32 uid = 1 [(is_uid) = true]; - // The interface name on which the packet was received. - optional string iface = 2; - // The ethertype value of the packet. - optional int32 ethertype = 3; - // String representation of the destination MAC address of the packet. - optional string destination_hardware_address = 4; - // String representation of the source address of the packet if this was an IP packet. - optional string source_ip = 5; - // String representation of the destination address of the packet if this was an IP packet. - optional string destination_ip = 6; - // The value of the protocol field if this was an IPv4 packet or the value of the Next Header - // field if this was an IPv6 packet. The range of possible values is the same for both IP - // families. - optional int32 ip_next_header = 7; - // The source port if this was a TCP or UDP packet. - optional int32 source_port = 8; - // The destination port if this was a TCP or UDP packet. - optional int32 destination_port = 9; -} - -/* - * Logs the memory stats for an app on startup. - * Logged from: - * frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java - */ -message AppStartMemoryStateCaptured { - // The uid if available. -1 means not available. - optional int32 uid = 1 [(is_uid) = true]; - - // The process name. - optional string process_name = 2; - - // The activity name. - optional string activity_name = 3; - - // # of page-faults - optional int64 page_fault = 4; - - // # of major page-faults - optional int64 page_major_fault = 5; - - // RSS - optional int64 rss_in_bytes = 6; - - // CACHE - optional int64 cache_in_bytes = 7; - - // SWAP - optional int64 swap_in_bytes = 8; -} - -/* - * Logs the change in Low Memory Killer Daemon (LMKD) state which is used as start/stop boundaries - * for LMK event. - * Logged from: - * system/core/lmkd/lmkd.c - */ -message LmkStateChanged { - enum State { - UNKNOWN = 0; - START = 1; - STOP = 2; - } - optional State state = 1; -} - -/* - * Logs the event when Low Memory Killer Daemon (LMKD) kills a process to reduce memory pressure. - * Logged from: - * system/core/lmkd/lmkd.c - */ -message LmkKillOccurred { - enum Reason { - UNKNOWN = 0; - PRESSURE_AFTER_KILL = 1; - NOT_RESPONDING = 2; - LOW_SWAP_AND_THRASHING = 3; - LOW_MEM_AND_SWAP = 4; - LOW_MEM_AND_THRASHING = 5; - DIRECT_RECL_AND_THRASHING = 6; - LOW_MEM_AND_SWAP_UTIL = 7; - } - - // The uid if available. -1 means not available. - optional int32 uid = 1 [(is_uid) = true]; - - // The process name. - optional string process_name = 2; - - // oom adj score. - optional int32 oom_adj_score = 3; - - // # of page-faults - optional int64 page_fault = 4; - - // # of major page-faults - optional int64 page_major_fault = 5; - - // RSS - optional int64 rss_in_bytes = 6; - - // CACHE - optional int64 cache_in_bytes = 7; - - // SWAP - optional int64 swap_in_bytes = 8; - - // The elapsed real time of start of the process. - optional int64 process_start_time_nanos = 9; - - // Min oom adj score considered by lmkd. - optional int32 min_oom_score = 10; - - // Free physical memory on device at LMK time. - optional int32 free_mem_kb = 11; - - // Free swap on device at LMK time. - optional int32 free_swap_kb = 12; - - // What triggered the LMK event. - optional Reason reason = 13; -} - -/* - * Logs when the ActivityManagerService detects that an app died. - * - * Logged from: - * frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java - */ -message AppDied { - // timestamp(elapsedRealtime) of record creation - optional uint64 timestamp_millis = 1 [(state_field_option).exclusive_state = true]; -} - -/** - * An atom for generic metrics logging. Available from Android Q. - */ -message GenericAtom { - // The uid of the application that sent this custom atom. - optional int32 uid = 1 [(is_uid) = true]; - - // An event_id indicates the type of event. - optional android.stats.EventType event_id = 2; -} - -/** - * Atom for simple logging of user interaction and impression events, such as "the user touched - * this button" or "this dialog was displayed". - * Keep the UI event stream clean: don't use for system or background events. - * Log using the UiEventLogger wrapper - don't write with the StatsLog API directly. - * - * Logged from: - * frameworks/base/services/core/java/com/android/server/ - * frameworks/base/packages/SystemUI/src/com/android/systemui/ - */ -message UiEventReported { - // The event_id. - optional int32 event_id = 1; - // The event's source or target uid and package, if applicable. - // For example, the package posting a notification, or the destination package of a share. - optional int32 uid = 2 [(is_uid) = true]; - optional string package_name = 3; - // An identifier used to disambiguate which logs refer to a particular instance of some - // UI element. Useful when there might be multiple instances simultaneously active. - optional int32 instance_id = 4; -} - -/** - * Reports a notification was created or updated. - * - * Logged from: - * frameworks/base/services/core/java/com/android/server/notification/ - */ -message NotificationReported { - // The event_id (as for UiEventReported). - optional int32 event_id = 1; - // The notifying app's uid and package. - optional int32 uid = 2 [(is_uid) = true]; - optional string package_name = 3; - // A small system-assigned identifier for the notification. - // Locally probably-unique, but expect collisions across users and/or days. - optional int32 instance_id = 4; - optional int32 notification_id_hash = 5; // Small hash of the app-assigned notif ID + tag - optional int32 channel_id_hash = 6; // Small hash of app-assigned channel ID - - // Grouping information - optional int32 group_id_hash = 7; // Small hash of the group ID of the notification - optional int32 group_instance_id = 8; // Instance_id of the group-summary notification - optional bool is_group_summary = 9; // Tags the group-summary notification - - // Attributes - optional string category = 10; // App-assigned notification category (API-defined strings) - optional int32 style = 11; // App-assigned notification style - optional int32 num_people = 12; // Number of Person records attached to the notification - - // Ordering, importance and interruptiveness - - optional int32 position = 13; // Position in NotificationManager's list - - optional android.stats.sysui.NotificationImportance importance = 14; - optional int32 alerting = 15; // Bitfield, 1=buzz 2=beep 4=blink - - enum NotificationImportanceExplanation { - IMPORTANCE_EXPLANATION_UNKNOWN = 0; - IMPORTANCE_EXPLANATION_APP = 1; // App-specified channel importance. - IMPORTANCE_EXPLANATION_USER = 2; // User-specified channel importance. - IMPORTANCE_EXPLANATION_ASST = 3; // Notification Assistant override. - IMPORTANCE_EXPLANATION_SYSTEM = 4; // System override. - // Like _APP, but based on pre-channels priority signal. - IMPORTANCE_EXPLANATION_APP_PRE_CHANNELS = 5; - } - - optional NotificationImportanceExplanation importance_source = 16; - optional android.stats.sysui.NotificationImportance importance_initial = 17; - optional NotificationImportanceExplanation importance_initial_source = 18; - optional android.stats.sysui.NotificationImportance importance_asst = 19; - optional int32 assistant_hash = 20; - optional float assistant_ranking_score = 21; -} - -message Notification { - // The notifying app's uid and package. - optional int32 uid = 1 [(is_uid) = true]; - optional string package_name = 2; - // A small system-assigned identifier for the notification. - optional int32 instance_id = 3; - - // Grouping information. - optional int32 group_instance_id = 4; - optional bool is_group_summary = 5; - - // The section of the shade that the notification is in. - // See SystemUI Notifications.proto. - enum NotificationSection { - SECTION_UNKNOWN = 0; - SECTION_HEADS_UP = 1; - SECTION_MEDIA_CONTROLS = 2; - SECTION_PEOPLE = 3; - SECTION_ALERTING = 4; - SECTION_SILENT = 5; - SECTION_FOREGROUND_SERVICE = 6; - } - optional NotificationSection section = 6; -} - -message NotificationList { - repeated Notification notifications = 1; // An ordered sequence of notifications. -} - -/** - * Reports a notification panel was displayed, e.g. from the lockscreen or status bar. - * - * Logged from: - * frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/notification/ - */ -message NotificationPanelReported { - // The event_id (as for UiEventReported). - optional int32 event_id = 1; - optional int32 num_notifications = 2; - // The notifications in the panel, in the order that they appear there. - optional NotificationList notifications = 3 [(log_mode) = MODE_BYTES]; -} - -/** - * Reports a notification channel, or channel group, was created, updated, or deleted. - * - * Logged from: - * frameworks/base/services/core/java/com/android/server/notification/ - */ -message NotificationChannelModified { - // The event_id (as for UiEventReported). - optional int32 event_id = 1; - // The notifying app's uid and package. - optional int32 uid = 2 [(is_uid) = true]; - optional string package_name = 3; - // Hash of app-assigned notification channel ID or channel-group ID - optional int32 channel_id_hash = 4; - // Previous importance setting, if applicable - optional android.stats.sysui.NotificationImportance old_importance = 5; - // New importance setting - optional android.stats.sysui.NotificationImportance importance = 6; - // whether or not this channel represents a conversation - optional bool is_conversation = 7; - // Hash of app-assigned notification conversation id - optional int32 conversation_id_hash = 8; - // whether or not the user demoted this channel out of the conversation space - optional bool is_conversation_demoted = 9; - // whether this conversation is marked as being a priority - optional bool is_conversation_priority = 10; -} - -/** - * Logs when a biometric acquire event occurs. - * - * Logged from: - * frameworks/base/services/core/java/com/android/server/biometrics - */ -message BiometricAcquired { - // Biometric modality that was acquired. - optional android.hardware.biometrics.ModalityEnum modality = 1; - // The associated user. Eg: 0 for owners, 10+ for others. Defined in android/os/UserHandle.java. - optional int32 user = 2; - // If this acquire is for a crypto operation. e.g. Secure purchases, unlock password storage. - optional bool is_crypto = 3; - // Action that the device is performing. Acquired messages are only expected for enroll and - // authenticate. Other actions may indicate an error. - optional android.hardware.biometrics.ActionEnum action = 4; - // The client that this acquisition was received for. - optional android.hardware.biometrics.ClientEnum client = 5; - // Acquired constants, e.g. ACQUIRED_GOOD. See constants defined by <Biometric>Manager. - optional int32 acquire_info = 6; - // Vendor-specific acquire info. Valid only if acquire_info == ACQUIRED_VENDOR. - optional int32 acquire_info_vendor = 7; - // Dictates if this message should trigger additional debugging. - optional bool debug = 8; -} - -/** - * Logs when a biometric authentication event occurs. - * - * Logged from: - * frameworks/base/services/core/java/com/android/server/biometrics - */ -message BiometricAuthenticated { - // Biometric modality that was used. - optional android.hardware.biometrics.ModalityEnum modality = 1; - // The associated user. Eg: 0 for owners, 10+ for others. Defined in android/os/UserHandle.java - optional int32 user = 2; - // If this authentication is for a crypto operation. e.g. Secure purchases, unlock password - // storage. - optional bool is_crypto = 3; - // The client that this acquisition was received for. - optional android.hardware.biometrics.ClientEnum client = 4; - // If authentication requires user confirmation. See BiometricPrompt's - // setRequireConfirmation(bool) method. - optional bool require_confirmation = 5; - - enum State { - UNKNOWN = 0; - REJECTED = 1; - PENDING_CONFIRMATION = 2; - CONFIRMED = 3; - } - - // State of the current auth attempt. - optional State state = 6; - // Time it took to authenticate. For BiometricPrompt where setRequireConfirmation(false) is - // specified and supported by the biometric modality, this is from the first ACQUIRED_GOOD to - // AUTHENTICATED. for setRequireConfirmation(true), this is from PENDING_CONFIRMATION to - // CONFIRMED. - optional int64 latency_millis = 7; - // Dictates if this message should trigger additional debugging. - optional bool debug = 8; -} - -/** - * Logs when a biometric error occurs. - * - * Logged from: - * frameworks/base/services/core/java/com/android/server/biometrics - */ -message BiometricErrorOccurred { - // Biometric modality that was used. - optional android.hardware.biometrics.ModalityEnum modality = 1; - // The associated user. Eg: 0 for owners, 10+ for others. Defined in android/os/UserHandle.java - optional int32 user = 2; - // If this error is for a crypto operation. e.g. Secure purchases, unlock password storage. - optional bool is_crypto = 3; - // Action that the device is performing. - optional android.hardware.biometrics.ActionEnum action = 4; - // The client that this acquisition was received for. - optional android.hardware.biometrics.ClientEnum client = 5; - // Error constants. See constants defined by <Biometric>Manager. Enums won't work since errors - // are unique to modality. - optional int32 error_info = 6; - // Vendor-specific error info. Valid only if acquire_info == ACQUIRED_VENDOR. These are defined - // by the vendor and not specified by the HIDL interface. - optional int32 error_info_vendor = 7; - // Dictates if this message should trigger additional debugging. - optional bool debug = 8; - // Time spent during the authentication attempt. - optional int64 latency_millis = 9; -} - -/** - * Logs when a system health issue is detected. - * Logged from: - * frameworks/base/services/core/java/com/android/server/biometrics - */ -message BiometricSystemHealthIssueDetected { - // Biometric modality. - optional android.hardware.biometrics.ModalityEnum modality = 1; - // Type of issue detected. - optional android.hardware.biometrics.IssueEnum issue = 2; - // Dictates if this message should trigger additional debugging. - optional bool debug = 3; -} - -/** - * Logs when a biometric enrollment occurs. - * - * Logged from: - * frameworks/base/services/core/java/com/android/server/biometrics - */ -message BiometricEnrolled { - // Biometric modality that was used. - optional android.hardware.biometrics.ModalityEnum modality = 1; - // The associated user. Eg: 0 for owners, 10+ for others. Defined in android/os/UserHandle.java - optional int32 user = 2; - // The amount of time the enrollment took in milliseconds. - optional int64 latency_millis = 3; - // Whether or not the enrollment was successful. - optional bool success = 4; -} - -/* - * Logs when a flag flip update occurrs. Used for mainline modules that update via flag flips. - */ -message FlagFlipUpdateOccurred { - // If the event is from a flag config package, specify the package name. - optional string flag_flip_package_name = 1; - - // The order id of the package - optional int64 order_id = 2; -} - -/** - * Potential experiment ids that goes with a train install. - * Should be kept in sync with experiment_ids.proto. - */ -message TrainExperimentIds { - repeated int64 experiment_id = 1; -} - -/* - * Logs when a binary push state changes. - * Logged by the installer via public api. - */ -message BinaryPushStateChanged { - // Name of the train. - optional string train_name = 1; - // Version code for a "train" of packages that need to be installed atomically - optional int64 train_version_code = 2; - // After installation of this package, device requires a restart. - optional bool requires_staging = 3; - // Rollback should be enabled for this install. - optional bool rollback_enabled = 4; - // Requires low latency monitoring if possible. - optional bool requires_low_latency_monitor = 5; - - enum State { - UNKNOWN = 0; - INSTALL_REQUESTED = 1; - INSTALL_STARTED = 2; - INSTALL_STAGED_NOT_READY = 3; - INSTALL_STAGED_READY = 4; - INSTALL_SUCCESS = 5; - // Replaced by INSTALL_FAILURE_DOWNLOAD, INSTALL_FAILURE_STATE_MISMATCH, - // and INSTALL_FAILURE_COMMIT. - INSTALL_FAILURE = 6 [deprecated = true]; - // This enum is for installs that are manually cancelled via the Manual Update UI. - INSTALL_CANCELLED = 7; - INSTALLER_ROLLBACK_REQUESTED = 8; - INSTALLER_ROLLBACK_INITIATED = 9; - INSTALLER_ROLLBACK_INITIATED_FAILURE = 10; - INSTALLER_ROLLBACK_STAGED = 11; - INSTALLER_ROLLBACK_STAGED_FAILURE = 12; - INSTALLER_ROLLBACK_BOOT_TRIGGERED = 13; - INSTALLER_ROLLBACK_BOOT_TRIGGERED_FAILURE = 14; - INSTALLER_ROLLBACK_SUCCESS = 15; - INSTALLER_ROLLBACK_FAILURE = 16; - INSTALLER_ROLLBACK_STAGED_CANCEL_REQUESTED = 17; - INSTALLER_ROLLBACK_STAGED_CANCEL_SUCCESS = 18; - INSTALLER_ROLLBACK_STAGED_CANCEL_FAILURE = 19; - INSTALL_STAGED_CANCEL_REQUESTED = 20; - INSTALL_STAGED_CANCEL_SUCCESS = 21; - INSTALL_STAGED_CANCEL_FAILURE = 22; - INSTALL_FAILURE_DOWNLOAD = 23; - INSTALL_FAILURE_STATE_MISMATCH = 24; - INSTALL_FAILURE_COMMIT = 25; - REBOOT_TRIGGERED = 26; - // Logged after INSTALL_REQUESTED for devices installing a train that - // contains no module requiring reboot. - REBOOT_NOT_REQUIRED = 27; - // Logged after INSTALL_REQUESTED for devices that are installing a train - // which requires reboot and eligible for soft restart. - SOFT_RESTART_ELIGIBLE = 28; - // Logged after INSTALL_REQUESTED for devices that are installing a train - // which requires reboot and eligible for notification restart. - NOTIFICATION_RESTART_ELIGIBLE = 29; - // Logged after INSTALL_REQUESTED for devices that are installing a train - // which requires reboot and not eligible for any reboot promotion strategy - // (e.g. soft restart, notification restart). - NO_REBOOT_PROMOTION_STRATEGY_ELIGIBLE = 30; - REBOOT_TRIGGER_FAILURE = 31; - } - optional State state = 6; - // Possible experiment ids for monitoring this push. - optional TrainExperimentIds experiment_ids = 7 [(log_mode) = MODE_BYTES]; - // user id - optional int32 user_id = 8; - optional int32 reason = 9; - // Whether or not this is a rollback event - optional bool is_rollback = 10; -} - -/* Test atom, is not logged anywhere */ -message TestAtomReported { - repeated AttributionNode attribution_node = 1; - optional int32 int_field = 2; - optional int64 long_field = 3; - optional float float_field = 4; - optional string string_field = 5; - optional bool boolean_field = 6; - enum State { - UNKNOWN = 0; - OFF = 1; - ON = 2; - } - optional State state = 7; - optional TrainExperimentIds bytes_field = 8 [(android.os.statsd.log_mode) = MODE_BYTES]; -} - -/** Represents USB port overheat event. */ -message UsbPortOverheatEvent { - /* Temperature of USB port at USB plug event, in 1/10ths of degree C. */ - optional int32 plug_temperature_deci_c = 1; - - /* Maximum temperature of USB port during overheat event, in 1/10ths of degree C. */ - optional int32 max_temperature_deci_c = 2; - - /* Time between USB plug event and overheat threshold trip, in seconds. */ - optional int32 time_to_overheat_secs = 3; - - /* Time between overheat threshold trip and hysteresis, in seconds. */ - optional int32 time_to_hysteresis_secs = 4; - - /* Time between hysteresis and active mitigation ending, in seconds. */ - optional int32 time_to_inactive_secs = 5; -}; - -/** - * Logs total effective full charge and discharge cycles on a battery. - * Here are some examples of one effective cycle: - * 1) the battery charges from 0% to 100% and drains back to 0%, - * 2) charging from 50% to 100% and draining back to 50% twice. - * Pulled from: - * frameworks/base/cmds/statsd/src/external/ResourceHealthManagerPuller.cpp - */ -message BatteryCycleCount { - /* Number of total charge and discharge cycles on the system battery. */ - optional int32 cycle_count = 1; -} - -/** - * Logs that external storage is mounted and information about it, the storage type (sd card/usb/ - * others), its type (public or private) and the size in bytes. - * Pulled from: - * StatsCompanionService - */ - -message ExternalStorageInfo { - - enum VolumeType { - UNKNOWN = 0; - PUBLIC = 1; - PRIVATE = 2; - OTHER = 3; - } - - // The type of external storage. - optional android.stats.storage.ExternalStorageType storage_type = 1; - // Type of the volume: TYPE_PUBLIC if portable and TYPE_PRIVATE if internal. - optional VolumeType volume_type = 2; - // Total size of the sd card in bytes. - optional int64 size_bytes = 3; -} - -/* - * Logs when a connection becomes available and lost. - * Logged in StatsCompanionService.java - */ -message ConnectivityStateChanged { - // Id of the network. - optional int32 net_id = 1; - - enum State { - UNKNOWN = 0; - CONNECTED = 1; - DISCONNECTED = 2; - } - // Connected state of a network. - optional State state = 2; -} - -/** - * Logs when a service starts and stops. - * Logged from: - * services/core/java/com/android/server/am/ActiveServices.java - */ -message ServiceStateChanged { - - optional int32 uid = 1 [(is_uid) = true]; - - optional string package_name = 2; - - optional string service_name = 3; - - enum State { - START = 1; - STOP = 2; - } - - optional State state = 4; -} - -/** - * Logs when a service is launched. - * Logged from: - * services/core/java/com/android/server/am/ActiveServices.java - */ -message ServiceLaunchReported { - - optional int32 uid = 1 [(is_uid) = true]; - - optional string package_name = 2; - - optional string service_name = 3; -} - -/** - * Logs when a hidden API is used. - * - * Logged from: - * libcore/libart/src/main/java/dalvik/system/VMRuntime.java - */ -message HiddenApiUsed { - // The uid of the app making the hidden access. - optional int32 uid = 1 [(is_uid) = true]; - - // Signature of the method or field accessed. - optional string signature = 2; - - enum AccessMethod { - NONE = 0; - REFLECTION = 1; - JNI = 2; - LINKING = 3; - } - - // Type of access. - optional AccessMethod access_method = 3; - - // Whether the access was prevented or not. - optional bool access_denied = 4; -} - -/** - * Logs user interaction with the Privacy Indicators added in Q. In particular: - * - When user sees privacy chip - * - When user clicks privacy chip - * - How does the user exit the Privacy Dialog - * Logged from: - * packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java - */ -message PrivacyIndicatorsInteracted { - - enum Type { - UNKNOWN = 0; - CHIP_VIEWED = 1; - CHIP_CLICKED = 2; - reserved 3; // Used only in beta builds, never shipped - DIALOG_DISMISS = 4; - DIALOG_LINE_ITEM = 5; - } - - optional Type type = 1 [(state_field_option).exclusive_state = true]; -} - -/** - * Logs information about a package that is moved from the internal to external storage and vice - * versa. - * It logs the package name, the type of the external storage where the package is installed - * (if moved to external storage, or UNKNOWN if moved to internal storage), - * and the move type: if it's from internal to external or the other way around. - * - * Logged from: - frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java - */ -message AppMovedStorageReported { - enum MoveType { - UNKNOWN = 0; - TO_EXTERNAL = 1; - TO_INTERNAL = 2; - } - // The type of the external storage. - optional android.stats.storage.ExternalStorageType external_storage_type = 1; - // The type of move. - optional MoveType move_type = 2; - // The name of the package that was moved. - optional string package_name = 3; -} - -/** - * Logs when system server watchdog occurs. - * Logged from: - * frameworks/base/services/core/java/com/android/server/Watchdog.java - */ -message SystemServerWatchdogOccurred { - optional string subject = 1; -} - -/** - * Logs when new file added to tombstones. - * Logged from: - * frameworks/base/core/java/com/android/server/BootReceiver.java - */ -message TombStoneOccurred { -} - -/* - * Information about a role request - * - * Logged from: - * packages/apps/PermissionController/src/com/android/packageinstaller/role/ui/RequestRoleFragment.java - */ -message RoleRequestResultReported { - // UID of application requesting the role - optional int32 requesting_uid = 1; - - // Package name of application requesting the role - optional string requesting_package_name = 2; - - // The role to be granted - optional string role_name = 3; - - // The count of applications qualifying for the role - optional int32 qualifying_count = 4; - - // UID of application current granted the role - optional int32 current_uid = 5; - - // Package name of application current granted the role - optional string current_package_name = 6; - - // UID of another application that user chose to grant the role to, instead of the requesting - // application - optional int32 granted_another_uid = 7; - - // Package name of another application that user chose to grant the role to, instead of the - // requesting application - optional string granted_another_package_name = 8; - - enum Result { - UNDEFINED = 0; - // role request was ignored - IGNORED = 1; - // role request was ignored because it's already granted - IGNORED_ALREADY_GRANTED = 2; - // role request was ignored because the application isn't qualified - IGNORED_NOT_QUALIFIED = 3; - // role request was ignored because user said it should be always denied - IGNORED_USER_ALWAYS_DENIED = 4; - // role was granted by user action - USER_GRANTED = 5; - // role was denied by user action - USER_DENIED = 6; - // role was denied by user granting another application the role - USER_DENIED_GRANTED_ANOTHER = 7; - // role was denied and set to be always denied by the user - USER_DENIED_WITH_ALWAYS = 8; - } - // The result of the role request - optional Result result = 9; -} - -/** - * Logs when a Vehicle Maps Service client's connection state has changed - * - * Logged from: - * packages/services/Car/service/src/com/android/car/stats/VmsClientLog.java - */ -message VmsClientConnectionStateChanged { - // The UID of the VMS client app - optional int32 uid = 1 [(is_uid) = true]; - - enum State { - UNKNOWN = 0; - // Attempting to connect to the client - CONNECTING = 1; - // Client connection established - CONNECTED = 2; - // Client connection closed unexpectedly - DISCONNECTED = 3; - // Client connection closed by VMS - TERMINATED = 4; - // Error establishing the client connection - CONNECTION_ERROR = 5; - } - - optional State state = 2; -} - -message MimeTypes { - repeated string mime_types = 1; -} - -/** - * Logs statistics regarding accesses to external storage. - * All stats are normalized for one day period. - * - * Logged from: - * packages/providers/MediaProvider/src/com/android/providers/media/MediaProvider.java - */ -message GeneralExternalStorageAccessStats { - optional int32 uid = 1 [(is_uid) = true]; - // Total number of accesses like creation, open, delete and rename/update. - // Includes file path and ContentResolver accesses - optional uint32 total_accesses = 2; - // Number of file path accesses, as opposed to file path and ContentResolver. - optional uint32 file_path_accesses = 3; - // Number of accesses on secondary volumes like SD cards. - // Includes file path and ContentResolver accesses - optional uint32 secondary_storage_accesses = 4; - // Comma-separated list of mime types that were accessed. - optional MimeTypes mime_types_accessed = 5 [(log_mode) = MODE_BYTES]; -} - -/** - * Logs when MediaProvider has successfully finished scanning a storage volume. - * - * Logged from: - * packages/providers/MediaProvider/src/com/android/providers/media/scan/ModernMediaScanner.java - */ -message MediaProviderScanOccurred { - enum Reason { - // Scan triggered due to unknown reason - UNKNOWN = 0; - // Scan triggered due to storage volume being mounted - MOUNTED = 1; - // Scan triggered due to explicit user action or app request - DEMAND = 2; - // Scan triggered due to idle maintenance - IDLE = 3; - } - - // Volume type that this event pertains to - optional android.stats.mediaprovider.VolumeType volume_type = 1; - // Reason why this scan was triggered - optional Reason reason = 2; - // Total number of files scanned - optional int64 item_count = 3; - // Duration of scan, normalized per file - optional float normalized_duration_millis = 4; - // Number of database inserts, normalized per file - optional float normalized_insert_count = 5; - // Number of database updates, normalized per file - optional float normalized_update_count = 6; - // Number of database deletes, normalized per file - optional float normalized_delete_count = 7; -} - -/** - * Logs when an app has asked MediaProvider to delete media belonging to the user. - * - * Logged from: - * packages/providers/MediaProvider/src/com/android/providers/media/MediaProvider.java - */ -message MediaContentDeleted { - // Volume type that this event pertains to - optional android.stats.mediaprovider.VolumeType volume_type = 1; - // UID of app that requested deletion - optional int32 uid = 2 [(is_uid) = true]; - // Number of items that were deleted - optional int32 item_count = 3; -} - -/** - * Logs when an app has asked MediaProvider to grant them access to media belonging to the user. - * - * Logged from: - * packages/providers/MediaProvider/src/com/android/providers/media/PermissionActivity.java - */ -message MediaProviderPermissionRequested { - enum Result { - UNKNOWN = 0; - USER_GRANTED = 1; - AUTO_GRANTED = 2; - USER_DENIED = 3; - USER_DENIED_WITH_PREJUDICE = 4; - AUTO_DENIED = 5; - } - - // Volume type that this event pertains to - optional android.stats.mediaprovider.VolumeType volume_type = 1; - // UID of app that requested permission - optional int32 uid = 2 [(is_uid) = true]; - // Number of items that were requested - optional int32 item_count = 3; - // Result of this request - optional Result result = 4; -} - -/** - * Logs when MediaProvider has finished upgrading or downgrading its database schema. - * - * Logged from: - * packages/providers/MediaProvider/src/com/android/providers/media/DatabaseHelper.java - */ -message MediaProviderSchemaChanged { - // Volume type that this event pertains to - optional android.stats.mediaprovider.VolumeType volume_type = 1; - // Old database version code - optional int32 version_from = 2; - // New database version code - optional int32 version_to = 3; - // Total number of files in database - optional int64 item_count = 4; - // Duration of schema change, normalized per file - optional float normalized_duration_millis = 5; -} - -/** - * Logs when MediaProvider has finished an idle maintenance job. - * - * Logged from: - * packages/providers/MediaProvider/src/com/android/providers/media/MediaProvider.java - */ -message MediaProviderIdleMaintenanceFinished { - // Volume type that this event pertains to - optional android.stats.mediaprovider.VolumeType volume_type = 1; - - // Total number of files in database - optional int64 item_count = 2; - // Duration of idle maintenance, normalized per file - optional float normalized_duration_millis = 3; - // Number of thumbnails found to be stale, normalized per file - optional float normalized_stale_thumbnails = 4; - // Number of items found to be expired, normalized per file - optional float normalized_expired_media = 5; -} - -/** - * Represents boot time event with duration in ms. - * - * Logged from: bootstat and various system server components. Check each enums for details. - */ -message BootTimeEventDuration { - enum DurationEvent { - UNKNOWN = 0; - // Bootloader time excluding BOOTLOADER_UI_WAIT + boot complete time. Logged from bootstat. - ABSOLUTE_BOOT_TIME = 1; - // Bootloader's 1st stage execution time. - // Logged from bootstat. - BOOTLOADER_FIRST_STAGE_EXEC = 2; - // Bootloader's 1st stage loading time. - // Logged from bootstat. - BOOTLOADER_FIRST_STAGE_LOAD = 3; - // Bootloader's kernel loading time. - // Logged from bootstat. - BOOTLOADER_KERNEL_LOAD = 4; - // Bootloader's 2nd stage execution time. - // Logged from bootstat. - BOOTLOADER_SECOND_STAGE_EXEC = 5; - // Bootloader's 2nd stage loading time. - // Logged from bootstat. - BOOTLOADER_SECOND_STAGE_LOAD = 6; - // Duration for Bootloader to show unlocked device's warning UI. This should not happen - // for locked device. - // Logged from bootstat. - BOOTLOADER_UI_WAIT = 7; - // Total time spend in bootloader. This is the sum of all BOOTLOADER_* listed above. - // Logged from bootstat. - BOOTLOADER_TOTAL = 8; - // Shutdown duration inside init for the reboot before the current boot up. - // Logged from f/b/services/.../BootReceiver.java. - SHUTDOWN_DURATION = 9; - // Total time for mounting of disk devices during bootup. - // Logged from f/b/services/.../BootReceiver.java. - MOUNT_DEFAULT_DURATION = 10; - // Total time for early stage mounting of disk devices during bootup. - // Logged from f/b/services/.../BootReceiver.java. - MOUNT_EARLY_DURATION = 11; - // Total time for late stage mounting of disk devices during bootup. - // Logged from f/b/services/.../BootReceiver.java. - MOUNT_LATE_DURATION = 12; - // Average time to scan non-system app after OTA - // Logged from f/b/services/.../PackageManagerService.java - OTA_PACKAGE_MANAGER_INIT_TIME = 13; - // Time to initialize Package manager after OTA - // Logged from f/b/services/.../PackageManagerService.java - OTA_PACKAGE_MANAGER_DATA_APP_AVG_SCAN_TIME = 14; - // Time to scan all system app from Package manager after OTA - // Logged from f/b/services/.../PackageManagerService.java - OTA_PACKAGE_MANAGER_SYSTEM_APP_AVG_SCAN_TIME = 15; - // Init's total time for cold boot stage. - // Logged from bootstat. - COLDBOOT_WAIT = 16; - // Init's total time for initializing selinux. - // Logged from bootstat. - SELINUX_INIT = 17; - // Time since last factory reset. - // Logged from bootstat. - FACTORY_RESET_TIME_SINCE_RESET = 18; - // Init's total time spent for completing the 1st stage. - // Logged from bootstat. - ANDROID_INIT_STAGE_1 = 19; - } - - // Type of the event. - optional DurationEvent event = 1; - // Duration of the event in ms. - optional int64 duration_millis = 2; -} - -/** - * Represents the start of specific boot time event during bootup in ms. This is usually a time - * since boot-up. - * - * Logged from: bootstat and various system server components. Check each enums for details. - */ -message BootTimeEventElapsedTime { - enum ElapsedTimeEvent { - UNKNOWN = 0; - // Time when init starts 1st stage. Logged from bootstat. - ANDROID_INIT_STAGE_1 = 1; - // Time when sys.boot_completed prop is set. - // Logged from bootstat. - BOOT_COMPLETE = 2; - // BOOT_COMPLETE for encrypted device. - BOOT_COMPLETE_ENCRYPTION = 3; - // BOOT_COMPLETE for device with no encryption. - BOOT_COMPLETE_NO_ENCRYPTION = 4; - // Adjusted BOOT_COMPLETE for encrypted device extracting decryption time. - BOOT_COMPLETE_POST_DECRYPT = 5; - // BOOT_COMPLETE after factory reset. - FACTORY_RESET_BOOT_COMPLETE = 6; - // BOOT_COMPLETE_NO_ENCRYPTION after factory reset. - FACTORY_RESET_BOOT_COMPLETE_NO_ENCRYPTION = 7; - // BOOT_COMPLETE_POST_DECRYPT after factory reset. - FACTORY_RESET_BOOT_COMPLETE_POST_DECRYPT = 8; - // BOOT_COMPLETE after OTA. - OTA_BOOT_COMPLETE = 9; - // BOOT_COMPLETE_NO_ENCRYPTION after OTA. - OTA_BOOT_COMPLETE_NO_ENCRYPTION = 10; - // BOOT_COMPLETE_POST_DECRYPT after OTA. - OTA_BOOT_COMPLETE_POST_DECRYPT = 11; - // Time when the system starts sending LOCKED_BOOT_COMPLETED broadcast. - // Logged from f/b/services/.../UserController.java - FRAMEWORK_LOCKED_BOOT_COMPLETED = 12; - // Time when the system starts sending BOOT_COMPLETED broadcast. - // Logged from f/b/services/.../UserController.java - FRAMEWORK_BOOT_COMPLETED = 13; - // Time when the package manager starts init. - // Logged from f/b/services/.../SystemServer.java - PACKAGE_MANAGER_INIT_START = 14; - // Time when package manager is ready - // Logged from f/b/services/.../SystemServer.java - PACKAGE_MANAGER_INIT_READY = 15; - // Represents the time when user has entered unlock credential for system with user pin. - // Logged from bootstat. - POST_DECRYPT = 16; - // Represents the start of zygote's init. - // Logged from zygote itself. - ZYGOTE_INIT_START = 17; - // Represents the start of secondary zygote's init. - // TODO: add logging to zygote - SECONDARY_ZYGOTE_INIT_START = 18; - // Represents the start of system server's init. - // Logged from f/b/services/.../SystemServer.java - SYSTEM_SERVER_INIT_START = 19; - // Represents the completion of system server's init. - // Logged from f/b/services/.../SystemServer.java - SYSTEM_SERVER_READY = 20; - // Represents the start of launcher during boot-up. - // TODO: add logging - LAUNCHER_START = 21; - // Represents the completion of launcher's initial rendering. User can use other apps from - // launcher from this point. - // TODO: add logging - LAUNCHER_SHOWN = 22; - } - - // Type of the event. - optional ElapsedTimeEvent event = 1; - // Time since bootup for the event. - // It should be acquired from SystemClock elapsedRealtime() call or equivalent. - optional int64 time_millis = 2; -} - -/** - * Boot time events with UTC time. - * - * Logged from: bootstat and various system server components. Check each enums for details. - */ -message BootTimeEventUtcTime { - enum UtcTimeEvent { - UNKNOWN = 0; - // Time of the bootstat's marking of 1st boot after the last factory reset. - // Logged from bootstat. - FACTORY_RESET_RESET_TIME = 1; - // The time when bootstat records FACTORY_RESET_* events. This is close to - // BOOT_COMPLETE time for the current bootup. - // Logged from bootstat. - FACTORY_RESET_CURRENT_TIME = 2; - // DUplicate of FACTORY_RESET_RESET_TIME added for debugging purpose. - // Logged from bootstat. - FACTORY_RESET_RECORD_VALUE = 3; - } - - // Type of the event. - optional UtcTimeEvent event = 1; - // UTC time for the event. - optional int64 utc_time_secs = 2; -} - -/** - * Boot time events representing specific error code during bootup. - * Meaning of error code can be different per each event type. - * - * Logged from: bootstat and various system server components. Check each enums for details. - */ -message BootTimeEventErrorCode { - enum ErrorCodeEvent { - UNKNOWN = 0; - // Linux error code for time() call to get the current UTC time. - // Logged from bootstat. - FACTORY_RESET_CURRENT_TIME_FAILURE = 1; - // Represents UmountStat before the reboot for the current boot up. Error codes defined - // as UMOUNT_STAT_* from init/reboot.cpp. - // Logged from f/b/services/.../BootReceiver.java. - SHUTDOWN_UMOUNT_STAT = 2; - // Reprepsents fie system mounting error code of /data partition for the current boot. - // Error codes defined as combination of FsStatFlags from system/core/fs_mgr/fs_mgr.cpp. - // Logged from f/b/services/.../BootReceiver.java. - FS_MGR_FS_STAT_DATA_PARTITION = 3; - } - - // Type of the event. - optional ErrorCodeEvent event = 1; - // error code defined per each event type. - // For example, this can have a value of FsStatFlags.FS_STAT_FULL_MOUNT_FAILED for the event of - // FS_MGR_FS_STAT. - optional int32 error_code = 2; -} - -/** - * Collects Virtual A/B statistics related to the use of dm-snapshot performed - * after an OTA. - * - * Logged from: - * - system/update_engine/cleanup_previous_update_action.cc - */ -message SnapshotMergeReported { - // Keep in sync with - // system/core/fs_mgr/libsnapshot/android/snapshot/snapshot.proto - enum UpdateState { - // No update or merge is in progress. - NONE = 0; - // An update is applying; snapshots may already exist. - INITIATED = 1; - // An update is pending, but has not been successfully booted yet. - UNVERIFIED = 2; - // The kernel is merging in the background. - MERGING = 3; - // Post-merge cleanup steps could not be completed due to a transient - // error, but the next reboot will finish any pending operations. - MERGE_NEEDS_REBOOT = 4; - // Merging is complete, and needs to be acknowledged. - MERGE_COMPLETED = 5; - // Merging failed due to an unrecoverable error. - MERGE_FAILED = 6; - // The update was implicitly cancelled, either by a rollback or a flash - // operation via fastboot. This state can only be returned by WaitForMerge. - CANCELLED = 7; - }; - - // Status of the update after the merge attempts. - optional UpdateState final_state = 1; - - // Time to complete a merge operation in milliseconds. - // A negative value corresponds to the case in which the merge operation - // was interrupted and resumed (e.g. in case of a system reboot during the - // merge). - optional int64 duration_millis = 2; - - // Number of reboots that occurred after issuing and before completing the - // merge of all the snapshot devices. - optional int32 intermediate_reboots = 3; - - // The device has been upgraded to Virtual A/B. - optional bool is_vab_retrofit = 4; - - // Space that has been temporarily allocated in the /data partition - // containing the dm-snapshot's copy-on-write data generated during a - // Virtual A/B update. - optional int64 cow_file_size_bytes = 5; -} - -/** - * Event representing when BlobStoreManager.Session#commit() is called - * - * Logged from: - * frameworks/base/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java - */ -message BlobCommitted { - // Uid of the Blob committer - optional int32 uid = 1 [(is_uid) = true]; - - // Id of the Blob committed - optional int64 blob_id = 2; - - // Size of the Blob - optional int64 size = 3; - - enum Result { - UNKNOWN = 0; - // Commit Succeeded - SUCCESS = 1; - // Commit Failed: Error occurred during commit - ERROR_DURING_COMMIT = 2; - // Commit Failed: Digest of the data did not match Blob digest - DIGEST_MISMATCH = 3; - // Commit Failed: Allowed count limit exceeded - COUNT_LIMIT_EXCEEDED = 4; - } - optional Result result = 4; -} - -/** - * Event representing when BlobStoreManager#acquireLease() is called - * - * Logged from: - * frameworks/base/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java - */ -message BlobLeased{ - // Uid of the Blob leasee - optional int32 uid = 1 [(is_uid) = true]; - - // Id of the Blob leased or 0 if the Blob does not exist - optional int64 blob_id = 2; - - // Size of the Blob or 0 if the Blob does not exist - optional int64 size = 3; - - enum Result { - UNKNOWN = 0; - // Lease Succeeded - SUCCESS = 1; - // Lease Failed: Blob does not exist - BLOB_DNE = 2; - // Lease Failed: Leasee does not have access to the Blob - ACCESS_NOT_ALLOWED = 3; - // Lease Failed: Leasee requested an invalid expiry duration - LEASE_EXPIRY_INVALID = 4; - // Lease Failed: Leasee has exceeded the total data lease limit - DATA_SIZE_LIMIT_EXCEEDED = 5; - // Leasee Failed: Allowed count limit exceeded - COUNT_LIMIT_EXCEEDED = 6; - } - optional Result result = 4; -} - -/** - * Event representing when BlobStoreManager#openBlob() is called - * - * Logged from: - * frameworks/base/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java - */ -message BlobOpened{ - // Uid of the Blob opener - optional int32 uid = 1 [(is_uid) = true]; - - // Id of the Blob opened or 0 if the Blob does not exist - optional int64 blob_id = 2; - - // Size of the Blob or 0 if the Blob does not exist - optional int64 size = 3; - - enum Result { - UNKNOWN = 0; - // Open Succeeded - SUCCESS = 1; - // Open Failed: Blob does not exist - BLOB_DNE = 2; - // Open Failed: Opener does not have access to the Blob - ACCESS_NOT_ALLOWED = 3; - } - optional Result result = 4; -} - -/** - * Event to track Jank for various system interactions. - * - * Logged from: - * frameworks/base/core/java/com/android/internal/jank/FrameTracker.java - */ -message UIInteractionFrameInfoReported { - enum InteractionType { - UNKNOWN = 0; - NOTIFICATION_SHADE_SWIPE = 1; - SHADE_EXPAND_COLLAPSE_LOCK = 2; - SHADE_SCROLL_FLING = 3; - SHADE_ROW_EXPAND = 4; - SHADE_ROW_SWIPE = 5; - SHADE_QS_EXPAND_COLLAPSE = 6; - SHADE_QS_SCROLL_SWIPE = 7; - LAUNCHER_APP_LAUNCH_FROM_RECENTS = 8; - LAUNCHER_APP_LAUNCH_FROM_ICON = 9; - LAUNCHER_APP_CLOSE_TO_HOME = 10; - LAUNCHER_APP_CLOSE_TO_PIP = 11; - LAUNCHER_QUICK_SWITCH = 12; - SHADE_HEADS_UP_APPEAR = 13; - SHADE_HEADS_UP_DISAPPEAR = 14; - SHADE_NOTIFICATION_ADD = 15; - SHADE_NOTIFICATION_REMOVE = 16; - SHADE_APP_LAUNCH = 17; - } - - optional InteractionType interaction_type = 1; - - // Number of frames rendered during the interaction. - optional int64 total_frames = 2; - - // Number of frames that were skipped in rendering during the interaction. - optional int64 missed_frames = 3; - - // Maximum time it took to render a single frame during the interaction. - optional int64 max_frame_time_nanos = 4; -} - -/** - * Event to track various latencies in SystemUI. - * - * Logged from: - * frameworks/base/core/java/com/android/internal/util/LatencyTracker.java - */ -message UIActionLatencyReported { - enum ActionType { - UNKNOWN = 0; - ACTION_EXPAND_PANEL = 1; - ACTION_TOGGLE_RECENTS = 2; - ACTION_FINGERPRINT_WAKE_AND_UNLOCK = 3; - ACTION_CHECK_CREDENTIAL = 4; - ACTION_CHECK_CREDENTIAL_UNLOCKED = 5; - ACTION_TURN_ON_SCREEN = 6; - ACTION_ROTATE_SCREEN = 7; - ACTION_FACE_WAKE_AND_UNLOCK = 8; - } - - optional ActionType action = 1; - - optional int64 latency_millis = 2; -} - -////////////////////////////////////////////////////////////////////// -// Pulled atoms below this line // -////////////////////////////////////////////////////////////////////// - -/** - * Pulls bytes transferred via wifi (Sum of foreground and background usage). - * - * Pulled from: - * StatsCompanionService (using BatteryStats to get which interfaces are wifi) - */ -message WifiBytesTransfer { - optional int32 uid = 1 [(is_uid) = true]; - - optional int64 rx_bytes = 2; - - optional int64 rx_packets = 3; - - optional int64 tx_bytes = 4; - - optional int64 tx_packets = 5; -} - -/** - * Pulls bytes transferred via wifi (separated by foreground and background usage). - * - * Pulled from: - * StatsCompanionService (using BatteryStats to get which interfaces are wifi) - */ -message WifiBytesTransferByFgBg { - optional int32 uid = 1 [(is_uid) = true]; - - // 1 denotes foreground and 0 denotes background. This is called Set in NetworkStats. - optional bool is_foreground = 2; - - optional int64 rx_bytes = 3; - - optional int64 rx_packets = 4; - - optional int64 tx_bytes = 5; - - optional int64 tx_packets = 6; -} - -/** - * Pulls bytes transferred via mobile networks (Sum of foreground and background usage). - * - * Pulled from: - * StatsCompanionService (using BatteryStats to get which interfaces are mobile data) - */ -message MobileBytesTransfer { - optional int32 uid = 1 [(is_uid) = true]; - - optional int64 rx_bytes = 2; - - optional int64 rx_packets = 3; - - optional int64 tx_bytes = 4; - - optional int64 tx_packets = 5; -} - -/** - * Pulls bytes transferred via mobile networks (separated by foreground and background usage). - * - * Pulled from: - * StatsCompanionService (using BatteryStats to get which interfaces are mobile data) - */ -message MobileBytesTransferByFgBg { - optional int32 uid = 1 [(is_uid) = true]; - - // 1 denotes foreground and 0 denotes background. This is called Set in - // NetworkStats. - optional bool is_foreground = 2; - - optional int64 rx_bytes = 3; - - optional int64 rx_packets = 4; - - optional int64 tx_bytes = 5; - - optional int64 tx_packets = 6; -} - -/** - * Used for pull network statistics via mobile|wifi networks, and sliced by interesting dimensions. - * Note that the data is expected to be sliced into more dimensions in future. In other words, - * the caller must not assume any row of data is one full report when filtering with a set of - * matching conditions, because future data may represent with multiple rows what is currently - * represented by one. - * To avoid being broken by future slicing, callers must take care to aggregate rows even if they - * query all the existing columns. - * - * Pulled from: - * StatsPullAtomService (using NetworkStatsService to get NetworkStats) - */ -message DataUsageBytesTransfer { - // State of this record. Should be NetworkStats#SET_DEFAULT or NetworkStats#SET_FOREGROUND to - // indicate the foreground state, or NetworkStats#SET_ALL to indicate the record is for all - // states combined, not including debug states. See NetworkStats#SET_*. - optional int32 state = 1; - - optional int64 rx_bytes = 2; - - optional int64 rx_packets = 3; - - optional int64 tx_bytes = 4; - - optional int64 tx_packets = 5; - - // Radio Access Technology (RAT) type of this record, should be one of - // TelephonyManager#NETWORK_TYPE_* constants, or NetworkTemplate#NETWORK_TYPE_ALL to indicate - // the record is for all rat types combined. - optional int32 rat_type = 6; - - // Mcc/Mnc read from sim if the record is for a specific subscription, null indicates the - // record is combined across subscriptions. - optional string sim_mcc = 7; - optional string sim_mnc = 8; - - // Allows mobile virtual network operators (MVNOs) to be identified with individual IDs. - // See TelephonyManager#getSimCarrierId. - optional int32 carrier_id = 9; - - // Enumeration of opportunistic states with an additional ALL state indicates the record is - // combined regardless of the boolean value in its field. - enum DataSubscriptionState { - UNKNOWN = 0; // For server side backward compatibility. - ALL = 1; - OPPORTUNISTIC = 2; - NOT_OPPORTUNISTIC = 3; - } - // Mark whether the subscription is an opportunistic data subscription, and ALL indicates the - // record is combined across opportunistic data subscriptions. - // See {@link SubscriptionManager#setOpportunistic}. - optional DataSubscriptionState opportunistic_data_sub = 10; - - // Indicate whether NR is connected, server side could use this with RAT type to determine if - // the record is for 5G NSA (Non Stand Alone) mode, where the primary cell is still LTE and - // network allocates a secondary 5G cell so telephony reports RAT = LTE along with NR state as - // connected. - optional bool is_nr_connected = 11; -} - -/** - * Pulls bytes transferred via bluetooth. It is pulled from Bluetooth controller. - * - * Pulled from: - * StatsCompanionService - */ -message BluetoothBytesTransfer { - optional int32 uid = 1 [(is_uid) = true]; - - optional int64 rx_bytes = 2; - - optional int64 tx_bytes = 3; -} - -/** - * Pulls the kernel wakelock durations. This atom is adapted from - * android/internal/os/KernelWakelockStats.java - * - * Pulled from: - * StatsCompanionService using KernelWakelockReader. - */ -message KernelWakelock { - optional string name = 1; - - optional int32 count = 2; - - optional int32 version = 3; - - optional int64 time_micros = 4; -} - -/** - * Pulls low power state information. If power.stats HAL is not available, this - * includes platform and subsystem sleep state information, - * PowerStatePlatformSleepState, PowerStateVoter or PowerStateSubsystemSleepState - * as defined in: - * hardware/interfaces/power/1.0/types.hal - * hardware/interfaces/power/1.1/types.hal - * If power.stats HAL is available, this includes PowerEntityStateResidencyResult - * as defined in: - * hardware/interfaces/power/stats/1.0/types.hal - */ -message SubsystemSleepState { - // Subsystem name - optional string subsystem_name = 1; - // For PlatformLowPowerStats (hal 1.0), this is the voter name, which could be empty. - // For SubsystemLowPowerStats (hal 1.1), this is the sleep state name. - // For PowerEntityStateResidencyResult (hal power/stats/1.0) this is the - // powerEntityStateName from the corresponding PowerEntityStateInfo. - optional string subname = 2; - // The number of times it entered, or voted for entering the sleep state - optional uint64 count = 3; - // The length of time spent in, or spent voting for, the sleep state - optional uint64 time_millis = 4; -} - -/** - * Pulls on-device power measurement information. - * Data defined by hardware/interfaces/power/stats/1.0/types.hal. - * Pulled from: - * frameworks/base/cmds/statsd/src/external/PowerStatsPuller.cpp - */ -message OnDevicePowerMeasurement { - // Name of the subsystem (to which the rail belongs). - optional string subsystem_name = 1; - - // Rail name. The rail lies within the subsystem. - optional string rail_name = 2; - - // Time (in ms since boot) at which the rail energy value was measured. - // This may differ slightly from the time that statsd logs this information. - optional uint64 measurement_timestamp_millis = 3; - - // Accumulated energy used via the rail since device boot in uWs. - optional uint64 energy_microwatt_secs = 4; -} - -/** - * Pulls Cpu time per frequency. - * Pulls the time the cpu spend on the frequency index. Frequency index - * starts from highest to lowest. The value should be monotonically - * increasing since boot. However, if there is a cpu - * hotplug event, the value would be reset as well. - */ -message CpuTimePerFreq { - optional uint32 cluster = 1; - optional uint32 freq_index = 2; - optional uint64 time_millis = 3; -} - -/** - * Pulls Cpu Time Per Uid. - * Note that isolated process uid time should be attributed to host uids. - */ -message CpuTimePerUid { - optional int32 uid = 1 [(is_uid) = true]; - optional uint64 user_time_micros = 2; - optional uint64 sys_time_micros = 3; -} - -/** - * Pulls Cpu Time Per Uid per frequency. - * Note that isolated process uid time should be attributed to host uids. - * For each uid, we order the time by descending frequencies. - */ -message CpuTimePerUidFreq { - optional int32 uid = 1 [(is_uid) = true]; - optional uint32 freq_index = 2; - optional uint64 time_millis = 3; -} - -/** - * Pulls Wifi Controller Activity Energy Info - */ -message WifiActivityInfo { - // timestamp(wall clock) of record creation - optional uint64 timestamp_millis = 1; - // stack reported state - // TODO: replace this with proto enum - optional int32 stack_state = 2; - // tx time in millis - optional uint64 controller_tx_time_millis = 3; - // rx time in millis - optional uint64 controller_rx_time_millis = 4; - // idle time in millis - optional uint64 controller_idle_time_millis = 5; - // product of current(mA), voltage(V) and time(ms) - optional uint64 controller_energy_used = 6; -} - -/** - * Pulls Modem Activity Energy Info - */ -message ModemActivityInfo { - // timestamp(wall clock) of record creation - optional uint64 timestamp_millis = 1; - // sleep time in millis. - optional uint64 sleep_time_millis = 2; - // idle time in millis - optional uint64 controller_idle_time_millis = 3; - /** - * Tx power index - * index 0 = tx_power < 0dBm - * index 1 = 0dBm < tx_power < 5dBm - * index 2 = 5dBm < tx_power < 15dBm - * index 3 = 15dBm < tx_power < 20dBm - * index 4 = tx_power > 20dBm - */ - // tx time in ms at power level 0 - optional uint64 controller_tx_time_pl0_millis = 4; - // tx time in ms at power level 1 - optional uint64 controller_tx_time_pl1_millis = 5; - // tx time in ms at power level 2 - optional uint64 controller_tx_time_pl2_millis = 6; - // tx time in ms at power level 3 - optional uint64 controller_tx_time_pl3_millis = 7; - // tx time in ms at power level 4 - optional uint64 controller_tx_time_pl4_millis = 8; - // rx time in ms at power level 5 - optional uint64 controller_rx_time_millis = 9; - // product of current(mA), voltage(V) and time(ms) - optional uint64 energy_used = 10 [deprecated=true]; -} - -/** - * Pulls Bluetooth Activity Energy Info - * Note: BluetoothBytesTransfer is pulled at the same time from the controller. - */ -message BluetoothActivityInfo { - // timestamp(wall clock) of record creation - optional uint64 timestamp_millis = 1; - // bluetooth stack state - optional int32 bluetooth_stack_state = 2; - // tx time in millis - optional uint64 controller_tx_time_millis = 3; - // rx time in millis - optional uint64 controller_rx_time_millis = 4; - // idle time in millis - optional uint64 controller_idle_time_millis = 5; - // product of current(mA), voltage(V) and time(ms) - optional uint64 energy_used = 6; -} - -/* - * Logs the memory stats for a process. - * - * Pulled from StatsCompanionService for all managed processes (from ActivityManagerService). - */ -message ProcessMemoryState { - // The uid if available. -1 means not available. - optional int32 uid = 1 [(is_uid) = true]; - - // The process name. - // Usually package name, "system" for system server. - // Provided by ActivityManagerService. - optional string process_name = 2; - - // Current OOM score adjustment. Value read from ProcessRecord. - optional int32 oom_adj_score = 3; - - // # of page-faults - optional int64 page_fault = 4; - - // # of major page-faults - optional int64 page_major_fault = 5; - - // RSS - // Value is read from memory.stat, field total_rss if per-app memory - // cgroups are enabled. Otherwise, value from /proc/pid/stat. - optional int64 rss_in_bytes = 6; - - // CACHE - // Value is read from memory.stat, field total_cache if per-app memory - // cgroups are enabled. Otherwise, 0. - optional int64 cache_in_bytes = 7; - - // SWAP - // Value is read from memory.stat, field total_swap if per-app memory - // cgroups are enabled. Otherwise, 0. - optional int64 swap_in_bytes = 8; - - // Deprecated: use ProcessMemoryHighWaterMark atom instead. Always -1. - optional int64 rss_high_watermark_in_bytes = 9 [deprecated = true]; - - // Deprecated: use ProcessMemorySnapshot atom instead. Always -1. - optional int64 start_time_nanos = 10 [deprecated = true]; - - // Deprecated: use ProcessMemorySnapshot atom instead. Always -1. - optional int32 anon_rss_and_swap_in_kilobytes = 11 [deprecated = true]; -} - -/* - * Logs the memory high-water mark for a process. - * - * Pulled from StatsCompanionService for all managed processes (from ActivityManagerServie) - * and for selected native processes. - * - * Pulling this atom resets high-water mark counters for all processes. - */ -message ProcessMemoryHighWaterMark { - // The uid if available. -1 means not available. - optional int32 uid = 1 [(is_uid) = true]; - - // The process name. - // Usually package name or process cmdline. - // Provided by ActivityManagerService or read from /proc/PID/cmdline. - optional string process_name = 2; - - // Deprecated: use rss_high_water_mark_in_kilobytes instead. This field is - // computed by converting kilobytes to bytes. - optional int64 rss_high_water_mark_in_bytes = 3 [deprecated = true]; - - // RSS high-water mark. Peak RSS usage of the process. Read from the VmHWM field in - // /proc/PID/status. - optional int32 rss_high_water_mark_in_kilobytes = 4; -} - -/* - * Logs the memory stats for a process. - * - * Pulled from StatsCompanionService for all managed processes (from ActivityManagerService) - * and for selected native processes. - */ -message ProcessMemorySnapshot { - // The uid if available. -1 means not available. - optional int32 uid = 1 [(is_uid) = true]; - - // The process name. - // Usually package name or process cmdline. - // Provided by ActivityManagerService or read from /proc/PID/cmdline. - optional string process_name = 2; - - // The pid of the process. - // Allows to disambiguate instances of the process. - optional int32 pid = 3; - - // The current OOM score adjustment value. - // Read from ProcessRecord for managed processes. - // Placeholder -1001 (OOM_SCORE_ADJ_MIN - 1, outside of allowed range) for native ones. - optional int32 oom_score_adj = 4; - - // The current RSS of the process. - // VmRSS from /proc/pid/status. - optional int32 rss_in_kilobytes = 5; - - // The current anon RSS of the process. - // RssAnon from /proc/pid/status. - optional int32 anon_rss_in_kilobytes = 6; - - // The current swap size of the process. - // VmSwap from /proc/pid/status. - optional int32 swap_in_kilobytes = 7; - - // The sum of rss_in_kilobytes and swap_in_kilobytes. - optional int32 anon_rss_and_swap_in_kilobytes = 8; -} - -/* - * Elapsed real time from SystemClock. - */ -message SystemElapsedRealtime { - optional uint64 time_millis = 1; -} - -/* - * Up time from SystemClock. - */ -message SystemUptime { - // Milliseconds since the system was booted. - // This clock stops when the system enters deep sleep (CPU off, display dark, device waiting - // for external input). - // It is not affected by clock scaling, idle, or other power saving mechanisms. - optional uint64 uptime_millis = 1; -} - -/* - * Reads from /proc/uid_concurrent_active_time which has the format: - * active: X (X is # cores) - * [uid0]: [time-0] [time-1] [time-2] ... (# entries = # cores) - * [uid1]: [time-0] [time-1] [time-2] ... ... - * ... - * Time-N means the CPU time a UID spent running concurrently with N other processes. - * The file contains a monotonically increasing count of time for a single boot. - */ -message CpuActiveTime { - optional int32 uid = 1 [(is_uid) = true]; - optional uint64 time_millis = 2; -} - -/** - * Reads from /proc/uid_concurrent_policy_time which has the format: - * policy0: X policy4: Y (there are X cores on policy0, Y cores on policy4) - * [uid0]: [time-0-0] [time-0-1] ... [time-1-0] [time-1-1] ... - * [uid1]: [time-0-0] [time-0-1] ... [time-1-0] [time-1-1] ... - * ... - * Time-X-Y means the time a UID spent on clusterX running concurrently with Y other processes. - * The file contains a monotonically increasing count of time for a single boot. - */ -message CpuClusterTime { - optional int32 uid = 1 [(is_uid) = true]; - optional int32 cluster_index = 2; - optional uint64 time_millis = 3; -} - -/* - * Pulls free disk space, for data, system partition and temporary directory. - */ -message DiskSpace { - // available bytes in data partition - optional uint64 data_available_bytes = 1; - // available bytes in system partition - optional uint64 system_available_bytes = 2; - // available bytes in download cache or temp directories - optional uint64 temp_available_bytes = 3; -} - -/** - * Pulls battery coulomb counter, which is the remaining battery charge in uAh. - * - * Pulled from StatsCompanionService.java - */ -message RemainingBatteryCapacity { - optional int32 charge_micro_ampere_hour = 1; -} - -/** - * Pulls battery capacity, which is the battery capacity when full in uAh. - * Pulled from: - * frameworks/base/cmds/statsd/src/external/ResourceHealthManagerPuller.cpp - */ -message FullBatteryCapacity { - optional int32 capacity_micro_ampere_hour = 1; -} - -/** - * Pulls battery voltage. - * Pulled from: - * frameworks/base/cmds/statsd/src/external/ResourceHealthManagerPuller.cpp - */ -message BatteryVoltage { - // The voltage of the battery, in millivolts. - optional int32 voltage_millivolt = 1; -} - -/** - * Pulls battery level (percent full, from 0 to 100). - * - * Pulled from: - * frameworks/base/cmds/statsd/src/external/ResourceHealthManagerPuller.cpp - */ -message BatteryLevel { - // Battery level. Should be in [0, 100]. - optional int32 battery_level = 1; -} - -/** - * Pulls the temperature of various parts of the device. - * The units are tenths of a degree Celsius. Eg: 30.3C is reported as 303. - * - * Pulled from StatsCompanionService.java - */ -message Temperature { - // The type of temperature being reported. Eg. CPU, GPU, SKIN, BATTERY, BCL_. - optional android.os.TemperatureTypeEnum sensor_location = 1; - - // The name of the temperature source. Eg. CPU0 - optional string sensor_name = 2; - - // Temperature in tenths of a degree C. - // For BCL, it is decimillivolt, decimilliamps, and percentage * 10. - optional int32 temperature_deci_celsius = 3; - - // Relative severity of the throttling, see enum definition. - optional android.os.ThrottlingSeverityEnum severity = 4; -} - -/** - * Pulls the statistics of calls to Binder. - * - * Binder stats will be reset every time the data is pulled. It means it can only be pulled by one - * config on the device. - * - * Next tag: 15 - */ -message BinderCalls { - // UID of the process responsible for the binder transaction. It will be set if the process - // executing the binder transaction attribute the transaction to another uid using - // Binder.setThreadWorkSource(). - // - // If not set, the value will be -1. - optional int32 uid = 1 [(is_uid) = true]; - // UID of the process executing the binder transaction. - optional int32 direct_caller_uid = 14; - // Fully qualified class name of the API call. - // - // This is a system server class name. - // - // TODO(gaillard): figure out if binder call stats includes data from isolated uids, if a uid - // gets recycled and we have isolated uids, we might attribute the data incorrectly. - // TODO(gaillard): there is a high dimensions cardinality, figure out if we should drop the less - // commonly used APIs. - optional string service_class_name = 2; - // Method name of the API call. It can also be a transaction code if we cannot - // resolve it to a name. See Binder#getTransactionName. - // - // This is a system server method name. - optional string service_method_name = 3; - // Total number of API calls. - optional int64 call_count = 4; - // True if the screen was interactive PowerManager#isInteractive at the end of the call. - optional bool screen_interactive = 13; - // Total number of API calls we have data recorded for. If we collected data for all the calls, - // call_count will be equal to recorded_call_count. - // - // If recorded_call_count is different than call_count, it means data collection has been - // sampled. All the fields below will be sampled in this case. - optional int64 recorded_call_count = 12; - // Number of exceptions thrown by the API. - optional int64 recorded_exception_count = 5; - // Total latency of all API calls. - // Average can be computed using total_latency_micros / recorded_call_count. - optional int64 recorded_total_latency_micros = 6; - // Maximum latency of one API call. - optional int64 recorded_max_latency_micros = 7; - // Total CPU usage of all API calls. - // Average can be computed using total_cpu_micros / recorded_call_count. - // Total can be computed using total_cpu_micros / recorded_call_count * call_count. - optional int64 recorded_total_cpu_micros = 8; - // Maximum CPU usage of one API call. - optional int64 recorded_max_cpu_micros = 9; - // Maximum parcel reply size of one API call. - optional int64 recorded_max_reply_size_bytes = 10; - // Maximum parcel request size of one API call. - optional int64 recorded_max_request_size_bytes = 11; -} - -/** - * Pulls the statistics of exceptions during calls to Binder. - * - * Binder stats are cumulative from boot unless somebody reset the data using - * > adb shell dumpsys binder_calls_stats --reset - */ -message BinderCallsExceptions { - // Exception class name, e.g. java.lang.IllegalArgumentException. - // - // This is an exception class name thrown by the system server. - optional string exception_class_name = 1; - // Total number of exceptions. - optional int64 exception_count = 2; -} - -/** - * Pulls the statistics of message dispatching on HandlerThreads. - * - * Looper stats will be reset every time the data is pulled. It means it can only be pulled by one - * config on the device. - * - * Next tag: 11 - */ -message LooperStats { - // The uid that made a call to the System Server and caused the message to be enqueued. - optional int32 uid = 1 [(is_uid) = true]; - - // Fully qualified class name of the handler target class. - // - // This field does not contain PII. This is a system server class name. - optional string handler_class_name = 2; - - // The name of the thread that runs the Looper. - // - // This field does not contain PII. This is a system server thread name. - optional string looper_thread_name = 3; - - // The name of the dispatched message. - // - // This field does not contain PII. This is a system server constant or class - // name. - optional string message_name = 4; - - // Total number of successfully dispatched messages. - optional int64 message_count = 5; - - // Total number of messages that failed dispatching. - optional int64 exception_count = 6; - - // Total number of processed messages we have data recorded for. If we - // collected data for all the messages, message_count will be equal to - // recorded_message_count. - // - // If recorded_message_count is different than message_count, it means data - // collection has been sampled. The fields below will be sampled in this case. - optional int64 recorded_message_count = 7; - - // Total latency of all processed messages. - // Average can be computed using recorded_total_latency_micros / - // recorded_message_count. - optional int64 recorded_total_latency_micros = 8; - - // Total CPU usage of all processed message. - // Average can be computed using recorded_total_cpu_micros / - // recorded_message_count. Total can be computed using - // recorded_total_cpu_micros / recorded_message_count * message_count. - optional int64 recorded_total_cpu_micros = 9; - - // True if the screen was interactive PowerManager#isInteractive at the end of the call. - optional bool screen_interactive = 10; - - // Max recorded CPU usage of all processed messages. - optional int64 recorded_max_cpu_micros = 11; - - // Max recorded latency of all processed messages. - optional int64 recorded_max_latency_micros = 12; - - // Total number of messages we tracked the dispatching delay for. If we - // collected data for all the messages, message_count will be equal to - // recorded_delay_message_count. - // - // If recorded_delay_message_count is different than message_count, it means data - // collection has been sampled or/and not all messages specified the target dispatch time. - // The fields below will be sampled in this case. - optional int64 recorded_delay_message_count = 13; - - // Total dispatching delay of all processed messages. - // Calculated as a difference between the target dispatching time (Message.when) - // and the actual dispatching time. - // Average can be computed using recorded_total_delay_millis / recorded_delay_message_count. - optional int64 recorded_total_delay_millis = 14; - - // Max dispatching delay of all processed messages. - // Calculated as a difference between the target dispatching time (Message.when) - // and the actual dispatching time. - optional int64 recorded_max_delay_millis = 15; -} - -/** - * Pulls disk information, such as write speed and latency. - */ -message DiskStats { - // Time taken to open, write 512B to, and close a file. - // -1 if error performing the check. - optional int64 data_write_latency_millis = 1; - - optional bool file_based_encryption = 2; - - // Recent disk write speed in kB/s. - // -1 if error querying storageed. - // 0 if data is unavailable. - optional int32 recent_disk_write_speed = 3; -} - - -/** - * Free and total bytes of the Data, Cache, and System partition. - */ -message DirectoryUsage { - enum Directory { - UNKNOWN = 0; - DATA = 1; - CACHE = 2; - SYSTEM = 3; - } - optional Directory directory = 1; - optional int64 free_bytes = 2; - optional int64 total_bytes = 3; -} - - -/** - * Size of an application: apk size, data size, and cache size. - * Reads from a cached file produced daily by DiskStatsLoggingService.java. - * Information is only reported for apps with the primary user (user 0). - * Sizes are aggregated by package name. - */ -message AppSize { - // Including uids will involve modifying diskstats logic. - optional string package_name = 1; - // App size in bytes. -1 if unavailable. - optional int64 app_size_bytes = 2; - // App data size in bytes. -1 if unavailable. - optional int64 app_data_size_bytes = 3; - // App cache size in bytes. -1 if unavailable. - optional int64 app_cache_size_bytes = 4; - // Time that the cache file was produced. - // Uses System.currentTimeMillis(), which is wall clock time. - optional int64 cache_time_millis = 5; -} - - -/** - * Size of a particular category. Eg: photos, videos. - * Reads from a cached file produced daily by DiskStatsLoggingService.java. - */ -message CategorySize { - enum Category { - UNKNOWN = 0; - APP_SIZE = 1; - APP_DATA_SIZE = 2; - APP_CACHE_SIZE = 3; - PHOTOS = 4; - VIDEOS = 5; - AUDIO = 6; - DOWNLOADS = 7; - SYSTEM = 8; - OTHER = 9; - } - optional Category category = 1; - // Category size in bytes. - optional int64 size_bytes = 2; - // Time that the cache file was produced. - // Uses System.currentTimeMillis(), which is wall clock time. - optional int64 cache_time_millis = 3; -} - -/** - * Pulls per uid I/O stats. The stats are cumulative since boot. - * - * Read/write bytes are I/O events from a storage device - * Read/write chars are data requested by read/write syscalls, and can be - * satisfied by caching. - * - * Pulled from StatsCompanionService, which reads proc/uid_io/stats. - */ -message DiskIo { - optional int32 uid = 1 [(is_uid) = true]; - optional int64 fg_chars_read = 2; - optional int64 fg_chars_write = 3; - optional int64 fg_bytes_read = 4; - optional int64 fg_bytes_write = 5; - optional int64 bg_chars_read = 6; - optional int64 bg_chars_write = 7; - optional int64 bg_bytes_read = 8; - optional int64 bg_bytes_write = 9; - optional int64 fg_fsync = 10; - optional int64 bg_fsync= 11; -} - - -/** - * Pulls the number of fingerprints for each user. - * - * Pulled from StatsCompanionService, which queries <Biometric>Manager. - */ -message NumFingerprintsEnrolled { - // The associated user. Eg: 0 for owners, 10+ for others. - // Defined in android/os/UserHandle.java - optional int32 user = 1; - // Number of fingerprints registered to that user. - optional int32 num_fingerprints_enrolled = 2; -} - -/** - * Pulls the number of faces for each user. - * - * Pulled from StatsCompanionService, which queries <Biometric>Manager. - */ -message NumFacesEnrolled { - // The associated user. Eg: 0 for owners, 10+ for others. - // Defined in android/os/UserHandle.java - optional int32 user = 1; - // Number of faces registered to that user. - optional int32 num_faces_enrolled = 2; -} -/** - * A mapping of role holder -> role - */ -message RoleHolder { - // uid of the role holder - optional int32 uid = 1 [(is_uid) = true]; - - // package name of the role holder - optional string package_name = 2; - - // the role held - optional string role = 3; -} - -message AggStats { - // These are all in byte resolution. - optional int64 min = 1 [deprecated = true]; - optional int64 average = 2 [deprecated = true]; - optional int64 max = 3 [deprecated = true]; - - // These are all in kilobyte resolution. Can fit in int32, so smaller on the wire than the above - // int64 fields. - optional int32 mean_kb = 4; - optional int32 max_kb = 5; -} - -// A reduced subset of process states; reducing the number of possible states allows more -// aggressive device-side aggregation of statistics and hence reduces metric upload size. -enum ProcessStateAggregated { - PROCESS_STATE_UNKNOWN = 0; - // Persistent system process. - PROCESS_STATE_PERSISTENT = 1; - // Top activity; actually any visible activity. - PROCESS_STATE_TOP = 2; - // Process binding to top or a foreground service. - PROCESS_STATE_BOUND_TOP_OR_FGS = 3; - // Processing running a foreground service. - PROCESS_STATE_FGS = 4; - // Important foreground process (ime, wallpaper, etc). - PROCESS_STATE_IMPORTANT_FOREGROUND = 5; - // Important background process. - PROCESS_STATE_BACKGROUND = 6; - // Process running a receiver. - PROCESS_STATE_RECEIVER = 7; - // All kinds of cached processes. - PROCESS_STATE_CACHED = 8; -} - -// Next tag: 13 -message ProcessStatsStateProto { - optional android.service.procstats.ScreenState screen_state = 1; - - optional android.service.procstats.MemoryState memory_state = 2 [deprecated = true]; - - // this enum list is from frameworks/base/core/java/com/android/internal/app/procstats/ProcessStats.java - // and not frameworks/base/core/java/android/app/ActivityManager.java - optional android.service.procstats.ProcessState process_state = 3 [deprecated = true]; - - optional ProcessStateAggregated process_state_aggregated = 10; - - // Millisecond uptime duration spent in this state - optional int64 duration_millis = 4 [deprecated = true]; - // Same as above, but with minute resolution so it fits into an int32. - optional int32 duration_minutes = 11; - - // Millisecond elapsed realtime duration spent in this state - optional int64 realtime_duration_millis = 9 [deprecated = true]; - // Same as above, but with minute resolution so it fits into an int32. - optional int32 realtime_duration_minutes = 12; - - // # of samples taken - optional int32 sample_size = 5; - - // PSS is memory reserved for this process - optional AggStats pss = 6 [deprecated = true]; - - // USS is memory shared between processes, divided evenly for accounting - optional AggStats uss = 7 [deprecated = true]; - - // RSS is memory resident for this process - optional AggStats rss = 8; -} - -// Next Tag: 8 -message ProcessStatsProto { - // Name of process. - optional string process = 1; - - // Uid of the process. - optional int32 uid = 2 [(is_uid) = true]; - - // Information about how often kills occurred - message Kill { - // Count of excessive CPU kills - optional int32 cpu = 1; - - // Count of kills when cached - optional int32 cached = 2; - - // PSS stats during cached kill - optional AggStats cached_pss = 3; - } - optional Kill kill = 3 [deprecated = true]; - - // Time and memory spent in various states. - repeated ProcessStatsStateProto states = 5; - - // Total time process has been running... screen_state, memory_state, and process_state - // will not be set. - optional ProcessStatsStateProto total_running_state = 6; - - // Association data for this process in this state; - // each entry here is one association. - repeated ProcessStatsAssociationProto assocs = 7; -} - -// Next Tag: 6 -message ProcessStatsAssociationProto { - // Procss Name of the associated process (client process of service binding) - optional string assoc_process_name = 1; - - // Package Name of the associated package (client package of service binding) - optional string assoc_package_name = 2 [deprecated = true]; - - // UID of the associated process/package (client package of service binding) - optional int32 assoc_uid = 5 [(is_uid) = true]; - - // Total count of the times this association (service binding) appeared. - optional int32 total_count = 3; - - // Uptime total duration in seconds this association (service binding) was around. - optional int32 total_duration_secs = 4; -} - -message PackageServiceOperationStatsProto { - // Operate enum: Started, Foreground, Bound, Executing - optional android.service.procstats.ServiceOperationState operation = 1; - - // Number of times the service was in this operation. - optional int32 count = 2; - - // Information about a state the service can be in. - message StateStats { - // Screen state enum. - optional android.service.procstats.ScreenState screen_state = 1; - // Memory state enum. - optional android.service.procstats.MemoryState memory_state = 2; - - // duration in milliseconds. - optional int64 duration_millis = 3; - // Millisecond elapsed realtime duration spent in this state - optional int64 realtime_duration_millis = 4; - } - repeated StateStats state_stats = 3; -} - -message PackageServiceStatsProto { - // Name of service component. - optional string service_name = 1; - - // The operation stats. - // The package_name, package_uid, package_version, service_name will not be set to save space. - repeated PackageServiceOperationStatsProto operation_stats = 2; -} - -message PackageAssociationSourceProcessStatsProto { - // Uid of the process. - optional int32 process_uid = 1; - // Process name. - optional string process_name = 2; - // Package name. - optional string package_name = 7; - // Total count of the times this association appeared. - optional int32 total_count = 3; - - // Millisecond uptime total duration this association was around. - optional int64 total_duration_millis = 4; - - // Total count of the times this association became actively impacting its target process. - optional int32 active_count = 5; - - // Information on one source in this association. - message StateStats { - // Process state enum. - optional android.service.procstats.ProcessState process_state = 1; - // Millisecond uptime duration spent in this state - optional int64 duration_millis = 2; - // Millisecond elapsed realtime duration spent in this state - optional int64 realtime_duration_mmillis = 3; - } - repeated StateStats active_state_stats = 6; -} - -message PackageAssociationProcessStatsProto { - // Name of the target component. - optional string component_name = 1; - // Information on one source in this association. - repeated PackageAssociationSourceProcessStatsProto sources = 2; -} - - -message ProcessStatsPackageProto { - // Name of package. - optional string package = 1; - - // Uid of the package. - optional int32 uid = 2; - - // Version of the package. - optional int64 version = 3; - - // Stats for each process running with the package loaded in to it. - repeated ProcessStatsProto process_stats = 4; - - // Stats for each of the package's services. - repeated PackageServiceStatsProto service_stats = 5; - - // Stats for each association with the package. - repeated PackageAssociationProcessStatsProto association_stats = 6; -} - -message ProcessStatsSectionProto { - // Elapsed realtime at start of report. - optional int64 start_realtime_millis = 1; - - // Elapsed realtime at end of report. - optional int64 end_realtime_millis = 2; - - // CPU uptime at start of report. - optional int64 start_uptime_millis = 3; - - // CPU uptime at end of report. - optional int64 end_uptime_millis = 4; - - // System runtime library. e.g. "libdvm.so", "libart.so". - optional string runtime = 5; - - // whether kernel reports swapped pss. - optional bool has_swapped_pss = 6; - - // Data completeness. e.g. "complete", "partial", shutdown", or "sysprops". - enum Status { - STATUS_UNKNOWN = 0; - STATUS_COMPLETE = 1; - STATUS_PARTIAL = 2; - STATUS_SHUTDOWN = 3; - STATUS_SYSPROPS = 4; - } - repeated Status status = 7; - - // Number of pages available of various types and sizes, representation fragmentation. - repeated ProcessStatsAvailablePagesProto available_pages = 10; - - // Stats for each process. - repeated ProcessStatsProto process_stats = 8; - - // Stats for each package. - repeated ProcessStatsPackageProto package_stats = 9; -} - -message ProcessStatsAvailablePagesProto { - // Node these pages are in (as per /proc/pagetypeinfo) - optional int32 node = 1; - - // Zone these pages are in (as per /proc/pagetypeinfo) - optional string zone = 2; - - // Label for the type of these pages (as per /proc/pagetypeinfo) - optional string label = 3; - - // Distribution of number of pages available by order size. First entry in array is - // order 0, second is order 1, etc. Each order increase is a doubling of page size. - repeated int32 pages_per_order = 4; -} - -/** - * Pulled from ProcessStatsService.java - */ -message ProcStats { - optional ProcessStatsSectionProto proc_stats_section = 1 [(log_mode) = MODE_BYTES]; - // Data pulled from device into this is sometimes sharded across multiple atoms to work around - // a size limit. When this happens, this shard ID will contain an increasing 1-indexed integer - // with the number of this shard. - optional int32 shard_id = 2; -} - -/** - * Pulled from ProcessStatsService.java - */ -message ProcStatsPkgProc { - optional ProcessStatsSectionProto proc_stats_section = 1 [(log_mode) = MODE_BYTES]; -} - -// Next Tag: 2 -message PackageRemoteViewInfoProto { - optional string package_name = 1; - // add per-package additional info here (like channels) -} - -// Next Tag: 2 -message NotificationRemoteViewsProto { - repeated PackageRemoteViewInfoProto package_remote_view_info = 1; -} - -/** - * Pulled from NotificationManagerService.java - */ -message NotificationRemoteViews { - optional NotificationRemoteViewsProto notification_remote_views = 1 [(log_mode) = MODE_BYTES]; -} - -/** - * Atom that contains a list of a package's preferences, pulled from NotificationManagerService.java - */ -message PackageNotificationPreferences { - // Uid under which the package is installed. - optional int32 uid = 1 [(is_uid) = true]; - // Notification importance, which specifies when and how a notification is displayed. - // Specified under core/java/android/app/NotificationManager.java. - optional int32 importance = 2; - // Lockscreen visibility as set by the user. - optional int32 visibility = 3; - // Bitfield mask indicating what fields were locked by the user (see LockableAppfields in - // PreferencesHelper.java) - optional int32 user_locked_fields = 4; -} - -/** - * Atom that contains a list of a package's channel preferences, pulled from - * NotificationManagerService.java. - */ -message PackageNotificationChannelPreferences { - // Uid under which the package is installed. - optional int32 uid = 1 [(is_uid) = true]; - // Channel's ID. Should always be available. - optional string channel_id = 2; - // Channel's name. Should always be available. - optional string channel_name = 3; - // Channel's description. Optionally set by the channel creator. - optional string description = 4; - // Notification importance, which specifies when and how a notification is displayed. Specified - // under core/java/android/app/NotificationManager.java. - optional int32 importance = 5; - // Bitmask representing which fields have been set by the user. See field bitmask descriptions - // at core/java/android/app/NotificationChannel.java - optional int32 user_locked_fields = 6; - // Indicates if the channel was deleted by the app. - optional bool is_deleted = 7; - // Indicates if the channel was marked as a conversation by the app. - optional bool is_conversation = 8; - // Indicates if the channel is a conversation that was demoted by the user. - optional bool is_demoted_conversation = 9; - // Indicates if the channel is a conversation that was marked as important by the user. - optional bool is_important_conversation = 10; -} - -/** - * Atom that represents an item in the list of Do Not Disturb rules, pulled from - * NotificationManagerService.java. - */ -message DNDModeProto { - enum Mode { - ROOT_CONFIG = -1; // Used to distinguish the config (one per user) from the rules. - ZEN_MODE_OFF = 0; - ZEN_MODE_IMPORTANT_INTERRUPTIONS = 1; - ZEN_MODE_NO_INTERRUPTIONS = 2; - ZEN_MODE_ALARMS = 3; - } - optional int32 user = 1; // Android user ID (0, 1, 10, ...) - optional bool enabled = 2; // true for ROOT_CONFIG if a manualRule is enabled - optional bool channels_bypassing = 3; // only valid for ROOT_CONFIG - optional Mode zen_mode = 4; - // id is one of the system default rule IDs, or empty - // May also be "MANUAL_RULE" to indicate app-activation of the manual rule. - optional string id = 5; - optional int32 uid = 6 [(is_uid) = true]; // currently only SYSTEM_UID or 0 for other - optional DNDPolicyProto policy = 7 [(log_mode) = MODE_BYTES]; -} - -/** - * Atom that represents a Do Not Disturb policy, an optional detail proto for DNDModeProto. - */ -message DNDPolicyProto { - enum State { - STATE_UNSET = 0; - STATE_ALLOW = 1; - STATE_DISALLOW = 2; - } - optional State calls = 1; - optional State repeat_callers = 2; - optional State messages = 3; - optional State conversations = 4; - optional State reminders = 5; - optional State events = 6; - optional State alarms = 7; - optional State media = 8; - optional State system = 9; - optional State fullscreen = 10; - optional State lights = 11; - optional State peek = 12; - optional State status_bar = 13; - optional State badge = 14; - optional State ambient = 15; - optional State notification_list = 16; - - enum PeopleType { - PEOPLE_UNSET = 0; - PEOPLE_ANYONE = 1; - PEOPLE_CONTACTS = 2; - PEOPLE_STARRED = 3; - PEOPLE_NONE = 4; - } - - optional PeopleType allow_calls_from = 17; - optional PeopleType allow_messages_from = 18; - - enum ConversationType { - CONV_UNSET = 0; - CONV_ANYONE = 1; - CONV_IMPORTANT = 2; - CONV_NONE = 3; - } - - optional ConversationType allow_conversations_from = 19; -} - -/** - * Atom that contains a list of a package's channel group preferences, pulled from - * NotificationManagerService.java. - */ -message PackageNotificationChannelGroupPreferences { - // Uid under which the package is installed. - optional int32 uid = 1 [(is_uid) = true]; - // Channel Group's ID. Should always be available. - optional string group_id = 2; - // Channel Group's name. Should always be available. - optional string group_name = 3; - // Channel Group's description. Optionally set by group creator. - optional string description = 4; - // Indicates if notifications from this channel group are blocked. - optional bool is_blocked = 5; - // Bitmask representing which fields have been set by the user. See field bitmask descriptions - // at core/java/android/app/NotificationChannelGroup.java - optional int32 user_locked_fields = 6; -} - -message PowerProfileProto { - optional double cpu_suspend = 1; - - optional double cpu_idle = 2; - - optional double cpu_active = 3; - - message CpuCluster { - optional int32 id = 1; - optional double cluster_power = 2; - optional int32 cores = 3; - repeated int64 speed = 4; - repeated double core_power = 5; - } - - repeated CpuCluster cpu_cluster = 40; - - optional double wifi_scan = 4; - - optional double wifi_on = 5; - - optional double wifi_active = 6; - - optional double wifi_controller_idle = 7; - - optional double wifi_controller_rx = 8; - - optional double wifi_controller_tx = 9; - - repeated double wifi_controller_tx_levels = 10; - - optional double wifi_controller_operating_voltage = 11; - - optional double bluetooth_controller_idle = 12; - - optional double bluetooth_controller_rx = 13; - - optional double bluetooth_controller_tx = 14; - - optional double bluetooth_controller_operating_voltage = 15; - - optional double modem_controller_sleep = 16; - - optional double modem_controller_idle = 17; - - optional double modem_controller_rx = 18; - - repeated double modem_controller_tx = 19; - - optional double modem_controller_operating_voltage = 20; - - optional double gps_on = 21; - - repeated double gps_signal_quality_based = 22; - - optional double gps_operating_voltage = 23; - - optional double bluetooth_on = 24; - - optional double bluetooth_active = 25; - - optional double bluetooth_at_cmd = 26; - - optional double ambient_display = 27; - - optional double screen_on = 28; - - optional double radio_on = 29; - - optional double radio_scanning = 30; - - optional double radio_active = 31; - - optional double screen_full = 32; - - optional double audio = 33; - - optional double video = 34; - - optional double flashlight = 35; - - optional double memory = 36; - - optional double camera = 37; - - optional double wifi_batched_scan = 38; - - optional double battery_capacity = 39; -} - -/** - * power_profile.xml and other constants for power model calculations. - * Pulled from PowerProfile.java - */ -message PowerProfile { - optional PowerProfileProto power_profile = 1 [(log_mode) = MODE_BYTES]; -} - -/** - * Logs when a user restriction was added or removed. - * - * Logged from: - * frameworks/base/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java - */ -message UserRestrictionChanged { - // The raw string of the user restriction as defined in UserManager. - // Allowed values are defined in UserRestrictionsUtils#USER_RESTRICTIONS. - optional string restriction = 1; - // Whether the restriction is enabled or disabled. - optional bool enabled = 2; -} - -/** - * Pulls process user time and system time. Puller takes a snapshot of all pids - * in the system and returns cpu stats for those that are working at the time. - * Dead pids will be dropped. Kernel processes are excluded. - * Min cool-down is 5 sec. - */ -message ProcessCpuTime { - optional int32 uid = 1 [(is_uid) = true]; - - optional string process_name = 2; - // Process cpu time in user space, cumulative from boot/process start - optional int64 user_time_millis = 3; - // Process cpu time in system space, cumulative from boot/process start - optional int64 system_time_millis = 4; -} - -/** - * Pulls the CPU usage for each thread. - * - * Read from /proc/$PID/task/$TID/time_in_state files. - * - * TODO(mishaw): This is an experimental atom. Issues with big/little CPU frequencies, and - * time_in_state files not being present on some phones, have not been addressed. These should be - * considered before a public release. - */ -message CpuTimePerThreadFreq { - // UID that owns the process. - optional int32 uid = 1 [(is_uid) = true]; - // ID of the process. - optional int32 process_id = 2; - // ID of the thread. - optional int32 thread_id = 3; - // Name of the process taken from `/proc/$PID/cmdline`. - optional string process_name = 4; - // Name of the thread taken from `/proc/$PID/task/$TID/comm` - optional string thread_name = 5; - - // Report eight different frequencies, and how much time is spent in each frequency. Frequencies - // are given in KHz, and time is given in milliseconds since the thread started. All eight - // frequencies are given here as the alternative is sending eight separate atoms. This method - // significantly reduces the amount of data created - optional int32 frequency1_khz = 6; - optional int32 time1_millis = 7; - optional int32 frequency2_khz = 8; - optional int32 time2_millis = 9; - optional int32 frequency3_khz = 10; - optional int32 time3_millis = 11; - optional int32 frequency4_khz = 12; - optional int32 time4_millis = 13; - optional int32 frequency5_khz = 14; - optional int32 time5_millis = 15; - optional int32 frequency6_khz = 16; - optional int32 time6_millis = 17; - optional int32 frequency7_khz = 18; - optional int32 time7_millis = 19; - optional int32 frequency8_khz = 20; - optional int32 time8_millis = 21; -} - -/** - * Pulls information about the device's build. - */ -message BuildInformation { - // Build.FINGERPRINT. A string that uniquely identifies this build. Do not parse. - // E.g. may be composed of the brand, product, device, release, id, incremental, type, and tags. - optional string fingerprint = 1; - - // Build.BRAND. The consumer-visible brand with which the product/hardware will be associated. - optional string brand = 2; - - // Build.PRODUCT. The name of the overall product. - optional string product = 3; - - // Build.DEVICE. The name of the industrial design. - optional string device = 4; - - // Build.VERSION.RELEASE. The user-visible version string. E.g., "1.0" or "3.4b5" or "bananas". - optional string version_release = 5; - - // Build.ID. E.g. a label like "M4-rc20". - optional string id = 6; - - // Build.VERSION.INCREMENTAL. The internal value used by the underlying source control to - // represent this build. - optional string version_incremental = 7; - - // Build.TYPE. The type of build, like "user" or "eng". - optional string type = 8; - - // Build.TAGS. Comma-separated tags describing the build, like "unsigned,debug". - optional string tags = 9; -} - -/** - * Logs information about mismatched caller for content capture. - * - * Logged from: - * frameworks/base/core/java/android/service/contentcapture/ContentCaptureService.java - */ -message ContentCaptureCallerMismatchReported { - optional string intended_package = 1; - optional string calling_package = 2; -} - -/** - * Logs information about content capture service events. - * - * Logged from: - * frameworks/base/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureMetricsLogger.java - */ -message ContentCaptureServiceEvents { - // The type of event. - enum Event { - UNKNOWN = 0; - ON_CONNECTED = 1; - ON_DISCONNECTED = 2; - SET_WHITELIST = 3; - SET_DISABLED = 4; - ON_USER_DATA_REMOVED = 5; - ON_DATA_SHARE_REQUEST = 6; - ACCEPT_DATA_SHARE_REQUEST = 7; - REJECT_DATA_SHARE_REQUEST = 8; - DATA_SHARE_WRITE_FINISHED = 9; - DATA_SHARE_ERROR_IOEXCEPTION = 10; - DATA_SHARE_ERROR_EMPTY_DATA = 11; - DATA_SHARE_ERROR_CLIENT_PIPE_FAIL = 12; - DATA_SHARE_ERROR_SERVICE_PIPE_FAIL = 13; - DATA_SHARE_ERROR_CONCURRENT_REQUEST = 14; - DATA_SHARE_ERROR_TIMEOUT_INTERRUPTED = 15; - } - optional Event event = 1; - // component/package of content capture service. - optional string service_info = 2; - // component/package of target. - // it's a concatenated list of component/package for SET_WHITELIST event - // separated by " ". - optional string target_info = 3; -} - -/** - * Logs information about content capture session events. - * - * Logged from: - * frameworks/base/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureMetricsLogger.java - */ -message ContentCaptureSessionEvents { - // The type of event. - enum Event { - UNKNOWN = 0; - ON_SESSION_STARTED = 1; - ON_SESSION_FINISHED = 2; - SESSION_NOT_CREATED = 3; - } - optional int32 session_id = 1; - optional Event event = 2; - // (n/a on session finished) - optional int32 state_flags = 3; - // component/package of content capture service. - optional string service_info = 4; - // component/package of app. - // (n/a on session finished) - optional string app_info = 5; - optional bool is_child_session = 6; -} - -/** - * Logs information about session being flushed. - * - * Logged from: - * frameworks/base/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureMetricsLogger.java - */ -message ContentCaptureFlushed { - optional int32 session_id = 1; - // component/package of content capture service. - optional string service_info = 2; - // component/package of app. - optional string app_info = 3; - // session start/finish events - optional int32 child_session_started = 4; - optional int32 child_session_finished = 5; - // count of view events. - optional int32 view_appeared_count = 6; - optional int32 view_disappeared_count = 7; - optional int32 view_text_changed_count = 8; - - // Flush stats. - optional int32 max_events = 9; - optional int32 idle_flush_freq = 10; - optional int32 text_flush_freq = 11; - optional int32 flush_reason = 12; -} - -/** - * Pulls on-device BatteryStats power use calculations for the overall device. - */ -message DeviceCalculatedPowerUse { - // Power used by the device in nAs (i.e. nanocoulombs (nC)), as computed by BatteryStats, since - // BatteryStats last reset (i.e. roughly since device was last significantly charged). - // Currently, this is from BatteryStatsHelper.getComputedPower() (not getTotalPower()). - optional int64 computed_power_nano_amp_secs = 1; -} - -/** - * Pulls on-device BatteryStats power use calculations broken down by uid. - * This atom should be complemented by DeviceCalculatedPowerBlameOther, which contains the power use - * that is attributed to non-uid items. They must all be included to get the total power use. - */ -message DeviceCalculatedPowerBlameUid { - // Uid being blamed. Note: isolated uids have already been mapped to host uid. - optional int32 uid = 1 [(is_uid) = true]; - - // Power used by this uid in nAs (i.e. nanocoulombs (nC)), as computed by BatteryStats, since - // BatteryStats last reset (i.e. roughly since device was last significantly charged). - optional int64 power_nano_amp_secs = 2; -} - -/** - * Pulls on-device BatteryStats power use calculations that are not due to a uid, broken down by - * drain type. - * This atom should be complemented by DeviceCalculatedPowerBlameUid, which contains the blame that - * is attributed uids. They must all be included to get the total power use. - */ -message DeviceCalculatedPowerBlameOther { - // The type of item whose power use is being reported. - enum DrainType { - AMBIENT_DISPLAY = 0; - // reserved 1; reserved "APP"; // Logged instead in DeviceCalculatedPowerBlameUid. - BLUETOOTH = 2; - CAMERA = 3; - // Cell-standby - CELL = 4; - FLASHLIGHT = 5; - IDLE = 6; - MEMORY = 7; - // Amount that total computed drain exceeded the drain estimated using the - // battery level changes and capacity. - OVERCOUNTED = 8; - PHONE = 9; - SCREEN = 10; - // Amount that total computed drain was below the drain estimated using the - // battery level changes and capacity. - UNACCOUNTED = 11; - // reserved 12; reserved "USER"; // Entire drain for a user. This is NOT supported. - WIFI = 13; - } - optional DrainType drain_type = 1; - - // Power used by this item in nAs (i.e. nanocoulombs (nC)), as computed by BatteryStats, since - // BatteryStats last reset (i.e. roughly since device was last significantly charged). - optional int64 power_nano_amp_secs = 2; -} - -/** - * Logs device policy features. - * - * Logged from: - * frameworks/base/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java - * packages/apps/ManagedProvisioning/src/com/android/managedprovisioning/ - */ -message DevicePolicyEvent { - // The event id - unique for each event. - optional android.stats.devicepolicy.EventId event_id = 1; - // The admin package name. - optional string admin_package_name = 2; - // A generic integer parameter. - optional int32 integer_value = 3; - // A generic boolean parameter. - optional bool boolean_value = 4; - // A parameter specifying a time period in milliseconds. - optional uint64 time_period_millis = 5; - // A parameter specifying a list of package names, bundle extras or string parameters. - optional android.stats.devicepolicy.StringList string_list_value = 6 [(log_mode) = MODE_BYTES]; -} - -/** - * Logs when DocumentsUI is started, and how. Call this when DocumentsUI first starts up. - * - * Logged from: - * package/app/DocumentsUI/src/com/android/documentsui/Metrics.java - */ -message DocsUILaunchReported { - optional android.stats.docsui.LaunchAction launch_action = 1; - optional bool has_initial_uri = 2; - optional android.stats.docsui.MimeType mime_type = 3; - optional android.stats.docsui.Root initial_root = 4; -} - -/** - * Logs root/app visited event in file managers/picker. Call this when the user - * taps on root/app in hamburger menu. - * - * Logged from: - * package/app/DocumentsUI/src/com/android/documentsui/Metrics.java - */ -message DocsUIRootVisitedReported { - optional android.stats.docsui.ContextScope scope = 1; - optional android.stats.docsui.Root root = 2; -} - -/** - * Logs file operation stats. Call this when a file operation has completed. - * - * Logged from: - * package/app/DocumentsUI/src/com/android/documentsui/Metrics.java - */ -message DocsUIFileOperationReported { - optional android.stats.docsui.Provider provider = 1; - optional android.stats.docsui.FileOperation file_op = 2; -} - -/** - * Logs file operation stats. Call this when a copy/move operation has completed with a specific - * mode. - * - * Logged from: - * package/app/DocumentsUI/src/com/android/documentsui/Metrics.java - */ -message DocsUIFileOperationCopyMoveModeReported { - optional android.stats.docsui.FileOperation file_op = 1; - optional android.stats.docsui.CopyMoveOpMode mode = 2; -} - - -/** - * Logs file sub operation stats. Call this when a file operation has failed. - * - * Logged from: - * package/app/DocumentsUI/src/com/android/documentsui/Metrics.java - */ -message DocsUIFileOperationFailureReported { - optional android.stats.docsui.Authority authority = 1; - optional android.stats.docsui.SubFileOperation sub_op = 2; -} - -/** -* Logs the cancellation of a file operation. Call this when a job is canceled -* -* Logged from: -* package/app/DocumentsUI/src/com/android/documentsui/Metrics.java -*/ -message DocsUIFileOperationCanceledReported { - optional android.stats.docsui.FileOperation file_op = 1; -} - -/** - * Logs startup time in milliseconds. - * - * Logged from: - * package/app/DocumentsUI/src/com/android/documentsui/Metrics.java - */ -message DocsUIStartupMsReported { - optional int32 startup_millis = 1; -} - -/** - * Logs the action that was started by user. - * - * Logged from: - * package/app/DocumentsUI/src/com/android/documentsui/Metrics.java - */ -message DocsUIUserActionReported { - optional android.stats.docsui.UserAction action = 1; -} - -/** - * Logs the invalid type when invalid scoped access is requested. - * - * Logged from: - * package/app/DocumentsUI/src/com/android/documentsui/ScopedAccessMetrics.java - */ -message DocsUIInvalidScopedAccessRequestReported { - optional android.stats.docsui.InvalidScopedAccess type = 1; -} - -/** - * Logs the package name that launches docsui picker mode. - * - * Logged from: - * package/app/DocumentsUI/src/com/android/documentsui/Metrics.java - */ -message DocsUIPickerLaunchedFromReported { - optional string package_name = 1; -} - -/** - * Logs the search type. - * - * Logged from: - * package/app/DocumentsUI/src/com/android/documentsui/Metrics.java - */ -message DocsUISearchTypeReported { - optional android.stats.docsui.SearchType search_type = 1; -} - -/** - * Logs the search mode. - * - * Logged from: - * package/app/DocumentsUI/src/com/android/documentsui/Metrics.java - */ -message DocsUISearchModeReported { - optional android.stats.docsui.SearchMode search_mode = 1; -} - -/** - * Logs the pick result information. - * - * Logged from: - * package/app/DocumentsUI/src/com/android/documentsui/Metrics.java - */ -message DocsUIPickResultReported { - optional int32 total_action_count = 1; - optional int64 duration_millis = 2; - optional int32 file_count= 3; - optional bool is_searching = 4; - optional android.stats.docsui.Root picked_from = 5; - optional android.stats.docsui.MimeType mime_type = 6; - optional int32 repeatedly_pick_times = 7; -} - -/** Logs the drag and drop of files. - - * Logged from: - * package/app/DocumentsUI/src/com/android/documentsui/Metrics.java - */ -message DocsUIDragAndDropReported { - optional bool drag_initiated_from_docsui = 1; -} - -/** - * Logs when an app's memory is compacted. - * - * Logged from: - * frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java - */ -message AppCompacted { - // The pid of the process being compacted. - optional int32 pid = 1; - - // The name of the process being compacted. - optional string process_name = 2; - - // The type of compaction. - enum Action { - UNKNOWN = 0; - SOME = 1; - FULL = 2; - PERSISTENT = 3; - BFGS = 4; - } - optional Action action = 3; - - // Total RSS in kilobytes consumed by the process prior to compaction. - optional int64 before_rss_total_kilobytes = 4; - - // File RSS in kilobytes consumed by the process prior to compaction. - optional int64 before_rss_file_kilobytes = 5; - - // Anonymous RSS in kilobytes consumed by the process prior to compaction. - optional int64 before_rss_anon_kilobytes = 6; - - // Swap in kilobytes consumed by the process prior to compaction. - optional int64 before_swap_kilobytes = 7; - - // Total RSS in kilobytes consumed by the process after compaction. - optional int64 after_rss_total_kilobytes = 8; - - // File RSS in kilobytes consumed by the process after compaction. - optional int64 after_rss_file_kilobytes = 9; - - // Anonymous RSS in kilobytes consumed by the process after compaction. - optional int64 after_rss_anon_kilobytes = 10; - - // Swap in kilobytes consumed by the process after compaction. - optional int64 after_swap_kilobytes = 11; - - // The time taken to perform compaction in milliseconds. - optional int64 time_to_compact_millis = 12; - - // The last compaction action performed for this app. - optional Action last_action = 13; - - // The last time that compaction was attempted on this process in milliseconds - // since boot, not including sleep (see SystemClock.uptimeMillis()). - optional int64 last_compact_timestamp_ms_since_boot = 14; - - // The "setAdj" (i.e. previous) oom_score_adj at the time of compaction. - optional int32 oom_score_adj = 15; - - // The process state at the time of compaction. - optional android.app.ProcessStateEnum process_state = 16 [default = PROCESS_STATE_UNKNOWN]; - - // Free ZRAM in kilobytes before compaction. - optional int64 before_zram_free_kilobytes = 17; - - // Free ZRAM in kilobytes after compaction. - optional int64 after_zram_free_kilobytes = 18; -} - -/** - * Logs when a Tethering event occurs. - * - */ -message NetworkTetheringReported { - // tethering error code - optional android.stats.connectivity.ErrorCode error_code = 1; - - // tethering downstream type - optional android.stats.connectivity.DownstreamType downstream_type = 2; - - // transport type of upstream network - optional android.stats.connectivity.UpstreamType upstream_type = 3; - - // The user type of Tethering - optional android.stats.connectivity.UserType user_type= 4; -} - -/** - * Logs a DNS lookup operation initiated by the system resolver on behalf of an application - * invoking native APIs such as getaddrinfo() or Java APIs such as Network#getAllByName(). - * - * The NetworkDnsEventReported message represents the entire lookup operation, which may - * result one or more queries to the recursive DNS resolvers. Those are individually logged - * in DnsQueryEvents to enable computing error rates and network latency and timeouts - * broken up by query type, transport, network interface, etc. - */ -message NetworkDnsEventReported { - optional android.stats.dnsresolver.EventType event_type = 1; - - optional android.stats.dnsresolver.ReturnCode return_code = 2; - - // The latency in microseconds of the entire DNS lookup operation. - optional int32 latency_micros = 3; - - // Only valid for event_type = EVENT_GETADDRINFO. - optional int32 hints_ai_flags = 4; - - // Flags passed to android_res_nsend() defined in multinetwork.h - // Only valid for event_type = EVENT_RESNSEND. - optional int32 res_nsend_flags = 5; - - optional android.stats.dnsresolver.NetworkType network_type = 6; - - // The DNS over TLS mode on a specific netId. - optional android.stats.dnsresolver.PrivateDnsModes private_dns_modes = 7; - - // Additional pass-through fields opaque to statsd. - // The DNS resolver Mainline module can add new fields here without requiring an OS update. - optional android.stats.dnsresolver.DnsQueryEvents dns_query_events = 8 [(log_mode) = MODE_BYTES]; - - // The sample rate of DNS stats (to statsd) is 1/sampling_rate_denom. - optional int32 sampling_rate_denom = 9; -} - -/** - * logs the CapportApiData info - * Logged from: - * packages/modules/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java - */ -message CapportApiData { - // The TTL of the network connection provided by captive portal - optional int32 remaining_ttl_secs = 1; - - // The limit traffic data of the network connection provided by captive portal - optional int32 remaining_bytes = 2; - - // Is portal url option included in the DHCP packet (Yes, No) - optional bool has_portal_url = 3; - - // Is venue info (e.g. store info, maps, flight status) included (Yes, No) - optional bool has_venue_info = 4; -} - -/** - * logs a network Probe Event - * Logged from: - * packages/modules/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java - */ -message ProbeEvent { - // The probe type (http or https, or captive portal API...) - optional android.stats.connectivity.ProbeType probe_type = 1; - - // The latency in microseconds of the probe event - optional int32 latency_micros = 2; - - // The result of the probe event - optional android.stats.connectivity.ProbeResult probe_result = 3; - - // The CaptivePortal API info - optional CapportApiData capport_api_data = 4; -} - -/** - * log each ProbeEvent in ProbeEvents - * Logged from: - * packages/modules/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java - */ -message ProbeEvents { - // Record probe event during the validation - repeated ProbeEvent probe_event = 1; -} - -/** - * The DHCP (Dynamic Host Configuration Protocol) session info - * Logged from: - * packages/modules/NetworkStack/src/android/net/dhcp/DhcpClient.java - */ -message DhcpSession { - // The DHCP Feature(s) enabled in this session - repeated android.stats.connectivity.DhcpFeature used_features = 1; - - // The discover packet (re)transmit count - optional int32 discover_count = 2; - - // The request packet (re)transmit count - optional int32 request_count = 3; - - // The IPv4 address conflict count - // (only be meaningful when duplicate address detection is enabled) - optional int32 conflict_count = 4; - - // The DHCP packet parsing error code in this session - // (defined in android.net.metrics.DhcpErrorEvent) - repeated android.stats.connectivity.DhcpErrorCode error_code = 5; - - // The result of DHCP hostname transliteration - optional android.stats.connectivity.HostnameTransResult ht_result = 6; -} - -/** - * Logs Network IP provisioning event - * Logged from: - * packages/modules/NetworkStack/src/com/android/networkstack/metrics/NetworkIpProvisioningMetrics.java - */ -message NetworkIpProvisioningReported { - // Transport type (WIFI, CELLULAR, BLUETOOTH, ..) - optional android.stats.connectivity.TransportType transport_type = 1; - - // The latency in microseconds of IP Provisioning over IPV4 - optional int32 ipv4_latency_micros = 2; - - // The latency in microseconds of IP Provisioning over IPV6 - optional int32 ipv6_latency_micros = 3; - - // The time duration between provisioning start and end (success or failure) - optional int64 provisioning_duration_micros = 4; - - // The specific disconnect reason for this IP provisioning - optional android.stats.connectivity.DisconnectCode disconnect_code = 5; - - // Log DHCP session info (Only valid for IPv4) - optional DhcpSession dhcp_session = 6 [(log_mode) = MODE_BYTES]; - - // The random number between 0 ~ 999 for sampling - optional int32 random_number = 7; -} - -/** - * Logs Network DHCP Renew event - * Logged from: - * packages/modules/NetworkStack/src/android/net/dhcp/DhcpClient.java - */ -message NetworkDhcpRenewReported { - // Transport type (WIFI, CELLULAR, BLUETOOTH, ..) - optional android.stats.connectivity.TransportType transport_type = 1; - - // The request packet (re)transmit count - optional int32 request_count = 2; - - // The latency in microseconds of DHCP Renew - optional int32 latency_micros = 3; - - // The DHCP error code is defined in android.net.metrics.DhcpErrorEvent - optional android.stats.connectivity.DhcpErrorCode error_code = 4; - - // The result of DHCP renew - optional android.stats.connectivity.DhcpRenewResult renew_result = 5; - - // The random number between 0 ~ 999 for sampling - optional int32 random_number = 6; -} - -/** - * Logs Network Validation event - * Logged from: - * packages/modules/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java - */ -message NetworkValidationReported { - // Transport type (WIFI, CELLULAR, BLUETOOTH, ..) - optional android.stats.connectivity.TransportType transport_type = 1; - - // Record each probe event - optional ProbeEvents probe_events = 2 [(log_mode) = MODE_BYTES]; - - // The result of the network validation - optional android.stats.connectivity.ValidationResult validation_result = 3; - - // The latency in microseconds of network validation - optional int32 latency_micros = 4; - - // The validation index (the first validation attempt or second, third...) - optional int32 validation_index = 5; - - // The random number between 0 ~ 999 for sampling - optional int32 random_number = 6; -} - -/** - * Logs NetworkStack Quirk event - * Logged from: - * packages/modules/NetworkStack/src/com/android/networkstack/ - */ -message NetworkStackQuirkReported { - // Transport type (WIFI, CELLULAR, BLUETOOTH, ..) - optional android.stats.connectivity.TransportType transport_type = 1; - - // Record each Quirk event - optional android.stats.connectivity.NetworkQuirkEvent event = 2; -} - -/** - * Logs when a data stall event occurs. - * - * Log from: - * packages/modules/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java - */ -message DataStallEvent { - // Data stall evaluation type. - // See packages/modules/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java - // Refer to the definition of DATA_STALL_EVALUATION_TYPE_*. - optional int32 evaluation_type = 1; - // See definition in data_stall_event.proto. - optional com.android.server.connectivity.ProbeResult validation_result = 2; - // See definition in data_stall_event.proto. - optional android.net.NetworkCapabilitiesProto.Transport network_type = 3; - // See definition in data_stall_event.proto. - optional com.android.server.connectivity.WifiData wifi_info = 4 [(log_mode) = MODE_BYTES]; - // See definition in data_stall_event.proto. - optional com.android.server.connectivity.CellularData cell_info = 5 [(log_mode) = MODE_BYTES]; - // See definition in data_stall_event.proto. - optional com.android.server.connectivity.DnsEvent dns_event = 6 [(log_mode) = MODE_BYTES]; - // The tcp packets fail rate from the latest tcp polling. - optional int32 tcp_fail_rate = 7; - // Number of packets sent since the last received packet. - optional int32 tcp_sent_since_last_recv = 8; -} - -/* - * Logs when RescueParty resets some set of experiment flags. - * - * Logged from: - * frameworks/base/services/core/java/com/android/server/RescueParty.java - */ -message RescuePartyResetReported { - // The rescue level of this reset. A value of 0 indicates missing or unknown level information. - optional int32 rescue_level = 1; -} - -/** - * Logs when signed config is received from an APK, and if that config was applied successfully. - * Logged from: - * frameworks/base/services/core/java/com/android/server/signedconfig/SignedConfigService.java - */ -message SignedConfigReported { - enum Type { - UNKNOWN_TYPE = 0; - GLOBAL_SETTINGS = 1; - } - optional Type type = 1; - - // The final status of the signed config received. - enum Status { - UNKNOWN_STATUS = 0; - APPLIED = 1; - BASE64_FAILURE_CONFIG = 2; - BASE64_FAILURE_SIGNATURE = 3; - SECURITY_EXCEPTION = 4; - INVALID_CONFIG = 5; - OLD_CONFIG = 6; - SIGNATURE_CHECK_FAILED = 7; - NOT_APPLICABLE = 8; - SIGNATURE_CHECK_FAILED_PROD_KEY_ABSENT = 9; - } - optional Status status = 2; - - // The version of the signed config processed. - optional int32 version = 3; - - // The package name that the config was extracted from. - optional string from_package = 4; - - enum Key { - NO_KEY = 0; - DEBUG = 1; - PRODUCTION = 2; - } - // Which key was used to verify the config. - optional Key verified_with = 5; -} - -/* - * Logs GNSS Network-Initiated (NI) location events. - * - * Logged from: - * frameworks/base/services/core/java/com/android/server/location/GnssLocationProvider.java - */ -message GnssNiEventReported { - // The type of GnssNiEvent. - enum EventType { - UNKNOWN = 0; - NI_REQUEST = 1; - NI_RESPONSE = 2; - } - optional EventType event_type = 1; - - // An ID generated by HAL to associate NI notifications and UI responses. - optional int32 notification_id = 2; - - // A type which distinguishes different categories of NI request, such as VOICE, UMTS_SUPL etc. - optional android.server.location.GnssNiType ni_type = 3; - - // NI requires notification. - optional bool need_notify = 4; - - // NI requires verification. - optional bool need_verify = 5; - - // NI requires privacy override, no notification/minimal trace. - optional bool privacy_override = 6; - - // Timeout period to wait for user response. Set to 0 for no timeout limit. Specified in - // seconds. - optional int32 timeout = 7; - - // Default response when timeout. - optional android.server.location.GnssUserResponseType default_response = 8; - - // String representing the requester of the network inititated location request. - optional string requestor_id = 9; - - // Notification message text string representing the service(for eg. SUPL-service) who sent the - // network initiated location request. - optional string text = 10; - - // requestorId decoding scheme. - optional android.server.location.GnssNiEncodingType requestor_id_encoding = 11; - - // Notification message text decoding scheme. - optional android.server.location.GnssNiEncodingType text_encoding = 12; - - // True if SUPL ES is enabled. - optional bool is_supl_es_enabled = 13; - - // True if GNSS location is enabled. - optional bool is_location_enabled = 14; - - // GNSS NI responses which define the response in NI structures. - optional android.server.location.GnssUserResponseType user_response = 15; -} - -/** - * Logs GNSS non-framework (NFW) location notification. - * - * Logged from: - * frameworks/base/services/core/java/com/android/server/location/GnssLocationProvider.java - */ -message GnssNfwNotificationReported { - // Package name of the Android proxy application representing the non-framework entity that - // requested location. Set to empty string if unknown. - optional string proxy_app_package_name = 1; - - // Protocol stack that initiated the non-framework location request. - optional android.server.location.NfwProtocolStack protocol_stack = 2; - - // Name of the protocol stack if protocol_stack field is set to OTHER_PROTOCOL_STACK. Otherwise, - // set to empty string. This field is opaque to the framework and used for logging purposes. - optional string other_protocol_stack_name = 3; - - // Source initiating/receiving the location information. - optional android.server.location.NfwRequestor requestor = 4; - - // Identity of the endpoint receiving the location information. For example, carrier name, OEM - // name, SUPL SLP/E-SLP FQDN, chipset vendor name, etc. This field is opaque to the framework - // and used for logging purposes. - optional string requestor_id = 5; - - // Indicates whether location information was provided for this request. - optional android.server.location.NfwResponseType response_type = 6; - - // True if the device is in user initiated emergency session. - optional bool in_emergency_mode = 7; - - // True if cached location is provided. - optional bool is_cached_location = 8; - - // True if proxy app permission mismatch between framework and GNSS HAL. - optional bool is_permission_mismatched = 9; -} - -/** - * Logs GNSS configuration as defined in IGnssConfiguration.hal. - * - * Logged from: - * frameworks/base/services/core/java/com/android/server/location/GnssConfiguration.java - */ -message GnssConfigurationReported { - // SUPL host name. - optional string supl_host = 1; - - // SUPL port number. - optional int32 supl_port = 2; - - // C2K host name. - optional string c2k_host = 3; - - // C2K port number. - optional int32 c2k_port = 4; - - // The SUPL version requested by Carrier. - optional int32 supl_ver = 5; - - // The SUPL mode. - optional android.server.location.SuplMode supl_mode = 6; - - // True if NI emergency SUPL restrictions is enabled. - optional bool supl_es = 7; - - // LTE Positioning Profile settings - optional android.server.location.LppProfile lpp_profile = 8; - - // Positioning protocol on A-Glonass system. - optional android.server.location.GlonassPosProtocol a_glonass_pos_protocol_select = 9; - - // True if emergency PDN is used. Otherwise, regular PDN is used. - optional bool use_emergency_pdn_for_emergency_supl= 10; - - // Configurations of how GPS functionalities should be locked when user turns off GPS On setting. - optional android.server.location.GpsLock gps_lock = 11; - - // Number of seconds to extend the emergency session duration post emergency call. - optional int32 es_extension_sec = 12; - - // The full list of package names of proxy Android applications representing the non-framework - // location access entities (on/off the device) for which the framework user has granted - // non-framework location access permission. The package names are concatenated in one string - // with spaces as separators. - optional string enabled_proxy_app_package_name_list = 13; -} - -/** - * Logs when a NFC device's error occurred. - * Logged from: - * system/nfc/src/nfc/nfc/nfc_ncif.cc - * packages/apps/Nfc/src/com/android/nfc/cardemulation/AidRoutingManager.java - */ -message NfcErrorOccurred { - enum Type { - UNKNOWN = 0; - CMD_TIMEOUT = 1; - ERROR_NOTIFICATION = 2; - AID_OVERFLOW = 3; - } - optional Type type = 1; - // If it's nci cmd timeout, log the timeout command. - optional uint32 nci_cmd = 2; - - optional uint32 error_ntf_status_code = 3; -} - -/** - * Logs when a NFC device's state changed event - * Logged from: - * packages/apps/Nfc/src/com/android/nfc/NfcService.java - */ -message NfcStateChanged { - enum State { - UNKNOWN = 0; - OFF = 1; - ON = 2; - ON_LOCKED = 3; // Secure Nfc enabled. - CRASH_RESTART = 4; // NfcService watchdog timeout restart. - } - optional State state = 1; -} - -/** - * Logs when a NFC Beam Transaction occurred. - * Logged from: - * packages/apps/Nfc/src/com/android/nfc/P2pLinkManager.java - */ -message NfcBeamOccurred { - enum Operation { - UNKNOWN = 0; - SEND = 1; - RECEIVE = 2; - } - optional Operation operation = 1; -} - -/** - * Logs when a NFC Card Emulation Transaction occurred. - * Logged from: - * packages/apps/Nfc/src/com/android/nfc/cardemulation/HostEmulationManager.java - * packages/apps/Nfc/src/com/android/nfc/cardemulation/HostNfcFEmulationManager.java - */ -message NfcCardemulationOccurred { - enum Category { - UNKNOWN = 0; - HCE_PAYMENT = 1; - HCE_OTHER = 2; - OFFHOST = 3; - } - // Transaction belongs to HCE payment or HCE other category, or offhost. - optional Category category = 1; - // SeName from transaction: SIMx, eSEx, HCE, HCEF. - optional string se_name = 2; -} - -/** - * Logs when a NFC Tag event occurred. - * Logged from: - * packages/apps/Nfc/src/com/android/nfc/NfcDispatcher.java - */ -message NfcTagOccurred { - enum Type { - UNKNOWN = 0; - URL = 1; - BT_PAIRING = 2; - PROVISION = 3; - WIFI_CONNECT = 4; - APP_LAUNCH = 5; - OTHERS = 6; - } - optional Type type = 1; -} - -/** - * Logs when Hce transaction triggered - * Logged from: - * system/nfc/src/nfc/nfc/nfc_ncif.cc - */ -message NfcHceTransactionOccurred { - // The latency period(in microseconds) it took for the first HCE data - // exchange. - optional uint32 latency_micros = 1; -} - -/** - * Logs when SecureElement state event changed - * Logged from: - * packages/apps/SecureElement/src/com/android/se/Terminal.java - */ -message SeStateChanged { - enum State { - UNKNOWN = 0; - INITIALIZED = 1; - DISCONNECTED = 2; - CONNECTED = 3; - HALCRASH = 4; - } - optional State state = 1; - - optional string state_change_reason = 2; - // SIMx or eSEx. - optional string terminal = 3; -} - -/** - * Information about a permission grant request - */ -message PermissionGrantRequestResultReported { - // unique value identifying an API call. A API call might result in multiple of these atoms - optional int64 request_id = 1; - - // UID of package requesting the permission grant - optional int32 uid = 2 [(is_uid) = true]; - - // Name of package requesting the permission grant - optional string package_name = 3; - - // The permission to be granted - optional string permission_name = 4; - - // If the permission was explicitly requested via the API or added by the system - optional bool is_implicit = 5; - - enum Result { - UNDEFINED = 0; - // permission request was ignored - IGNORED = 1; - // permission request was ignored because it was user fixed - IGNORED_USER_FIXED = 2; - // permission request was ignored because it was policy fixed - IGNORED_POLICY_FIXED = 3; - // permission was granted by user action - USER_GRANTED = 4; - // permission was automatically granted - AUTO_GRANTED = 5; - // permission was denied by user action - USER_DENIED = 6; - // permission was denied with prejudice by the user - USER_DENIED_WITH_PREJUDICE = 7; - // permission was automatically denied - AUTO_DENIED = 8; - // permission request was ignored because permission is restricted - IGNORED_RESTRICTED_PERMISSION = 9; - // one time permission was granted by user action - USER_GRANTED_ONE_TIME = 10; - // user ignored request by leaving the request screen without choosing any option - USER_IGNORED = 11; - // user granted the permission after being linked to settings - USER_GRANTED_IN_SETTINGS = 12; - // user denied the permission after being linked to settings - USER_DENIED_IN_SETTINGS = 13; - // user denied the permission with prejudice after being linked to settings - USER_DENIED_WITH_PREJUDICE_IN_SETTINGS = 14; - // permission was automatically revoked after one-time permission expired - AUTO_ONE_TIME_PERMISSION_REVOKED = 15; - // permission was automatically revoked for unused app - AUTO_UNUSED_APP_PERMISSION_REVOKED = 16; - } - // The result of the permission grant - optional Result result = 6; -} - -/** - * Logs when Omapi API used - * Logged from: - * packages/apps/SecureElement/src/com/android/se/Terminal.java - */ -message SeOmapiReported { - enum Operation { - UNKNOWN = 0; - OPEN_CHANNEL = 1; - } - optional Operation operation = 1; - // SIMx or eSEx. - optional string terminal = 2; - - optional string package_name = 3; -} - -/** - * Logs the dispatch latency of a broadcast during processing of BOOT_COMPLETED. - * The dispatch latency is the dispatchClockTime - enqueueClockTime. - * Logged from: - * frameworks/base/services/core/java/com/android/server/am/BroadcastQueue.java - */ -message BroadcastDispatchLatencyReported { - optional int64 dispatch_latency_millis = 1; -} - -/** - * Logs AttentionManagerService attention check result. - * - * Logged from: - * frameworks/base/services/core/java/com/android/server/attention/AttentionManagerService.java - */ -message AttentionManagerServiceResultReported { - // See core/java/android/service/attention/AttentionService.java - enum AttentionCheckResult { - UNKNOWN = 20; - ATTENTION_SUCCESS_ABSENT = 0; - ATTENTION_SUCCESS_PRESENT = 1; - ATTENTION_FAILURE_UNKNOWN = 2; - ATTENTION_FAILURE_CANCELLED = 3; - ATTENTION_FAILURE_PREEMPTED = 4; - ATTENTION_FAILURE_TIMED_OUT = 5; - ATTENTION_FAILURE_CAMERA_PERMISSION_ABSENT = 6; - } - optional AttentionCheckResult attention_check_result = 1 [default = UNKNOWN]; -} - -/** - * Logs when an adb connection changes state. - * - * Logged from: - * frameworks/base/services/core/java/com/android/server/adb/AdbDebuggingManager.java - */ -message AdbConnectionChanged { - // The last time this system connected via adb, or 0 if the 'always allow' option was not - // previously selected for this system. - optional int64 last_connection_time_millis = 1; - - // The time in ms within which a subsequent connection from an 'always allow' system is allowed - // to reconnect via adb without user interaction. - optional int64 auth_window_millis = 2; - - // The state of the adb connection from frameworks/base/core/proto/android/debug/enums.proto. - optional android.debug.AdbConnectionStateEnum state = 3; - - // True if the 'always allow' option was selected for this system. - optional bool always_allow = 4; -} - -/* - * Logs the reported speech DSP status. - * - * Logged from: - * Vendor audio implementation. - */ -message SpeechDspStatReported { - // The total Speech DSP uptime in milliseconds. - optional int32 total_uptime_millis = 1; - // The total Speech DSP downtime in milliseconds. - optional int32 total_downtime_millis = 2; - optional int32 total_crash_count = 3; - optional int32 total_recover_count = 4; -} - -/** - * Logs USB connector contaminant status. - * - * Logged from: USB Service. - */ -message UsbContaminantReported { - optional string id = 1; - optional android.service.usb.ContaminantPresenceStatus status = 2; -} - -/** - * This atom is for debugging purpose. - */ -message DebugElapsedClock { - // Monotically increasing value for each pull. - optional int64 pull_count = 1; - // Time from System.elapsedRealtime. - optional int64 elapsed_clock_millis = 2; - // Time from System.elapsedRealtime. - optional int64 same_elapsed_clock_millis = 3; - // Diff between current elapsed time and elapsed time from previous pull. - optional int64 elapsed_clock_diff_millis = 4; - - enum Type { - TYPE_UNKNOWN = 0; - ALWAYS_PRESENT = 1; - PRESENT_ON_ODD_PULLS = 2; - } - // Type of behavior for the pulled data. - optional Type type = 5; -} - -/** - * This atom is for debugging purpose. - */ -message DebugFailingElapsedClock { - // Monotically increasing value for each pull. - optional int64 pull_count = 1; - // Time from System.elapsedRealtime. - optional int64 elapsed_clock_millis = 2; - // Time from System.elapsedRealtime. - optional int64 same_elapsed_clock_millis = 3; - // Diff between current elapsed time and elapsed time from previous pull. - optional int64 elapsed_clock_diff_millis = 4; -} - -/** Logs System UI bubbles event changed. - * - * Logged from: - * frameworks/base/packages/SystemUI/src/com/android/systemui/bubbles - */ -message BubbleUIChanged { - - // The app package that is posting the bubble. - optional string package_name = 1; - - // The notification channel that is posting the bubble. - optional string notification_channel = 2; - - // The notification id associated with the posted bubble. - optional int32 notification_id = 3; - - // The position of the bubble within the bubble stack. - optional int32 position = 4; - - // The total number of bubbles within the bubble stack. - optional int32 total_number = 5; - - // User interactions with the bubble. - enum Action { - UNKNOWN = 0; - POSTED = 1; - UPDATED = 2; - EXPANDED = 3; - COLLAPSED = 4; - DISMISSED = 5; - STACK_DISMISSED = 6; - STACK_MOVED = 7; - HEADER_GO_TO_APP = 8; - HEADER_GO_TO_SETTINGS = 9; - PERMISSION_OPT_IN = 10; - PERMISSION_OPT_OUT = 11; - PERMISSION_DIALOG_SHOWN = 12; - SWIPE_LEFT = 13; - SWIPE_RIGHT = 14; - STACK_EXPANDED = 15; - FLYOUT = 16; - } - optional Action action = 6; - - // Normalized screen position of the bubble stack. The range is between 0 and 1. - optional float normalized_x_position = 7; - optional float normalized_y_position = 8; - - // Whether the bubble is unread. If it is unread, a dot is shown in the bubble stack icon. - optional bool is_unread = 9; - - // Whether the bubble is an on-going one. - optional bool is_ongoing = 10; - - // Whether the bubble is produced by an app running in foreground. - // This is deprecated and the value should be ignored. - optional bool is_foreground = 11 [deprecated = true]; -} - -/** - * Logs System UI bubbles developer errors. - * - * Logged from: - * frameworks/base/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java - */ -message BubbleDeveloperErrorReported { - - // The app package that is posting the bubble. - optional string package_name = 1; - - // Bubble developer error type enums. - enum Error { - UNKNOWN = 0; - ACTIVITY_INFO_MISSING = 1; - ACTIVITY_INFO_NOT_RESIZABLE = 2; - DOCUMENT_LAUNCH_NOT_ALWAYS = 3; - } - optional Error error = 2 [default = UNKNOWN]; -} - -/** - * Logs that a constraint for a scheduled job has changed. - * - * Logged from: - * frameworks/base/services/core/java/com/android/server/job/controllers/JobStatus.java - */ -message ScheduledJobConstraintChanged { - repeated AttributionNode attribution_node = 1; - - // Name of the job. - optional string job_name = 2; - - optional com.android.server.job.ConstraintEnum constraint = 3; - - enum State { - UNKNOWN = 0; - UNSATISFIED = 1; - SATISFIED = 2; - } - optional State state = 4; -} - -/** - * Logs PowerManagerService screen timeout resets (extensions) that happen when an attention check - * returns true. - * - * Logged from: - * frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java - */ -message ScreenTimeoutExtensionReported { - // Describes how many times in a row did the power manager reset the screen off timeout. - optional uint32 consecutive_timeout_extended_count = 1; -} - -/* -* Logs number of milliseconds it takes to start a process. -* The definition of app process start time is from the app launch time to -* the time that Zygote finished forking the app process and loaded the -* application package's java classes. - -* This metric is different from AppStartOccurred which is for foreground -* activity only. - -* ProcessStartTime can report all processes (both foreground and background) -* start time. -* -* Logged from: -* frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java -*/ -message ProcessStartTime { - // The uid of the ProcessRecord. - optional int32 uid = 1 [(is_uid) = true]; - - // The process pid. - optional int32 pid = 2; - - // The process name. - // Usually package name, "system" for system server. - // Provided by ActivityManagerService. - optional string process_name = 3; - - enum StartType { - UNKNOWN = 0; - WARM = 1; - HOT = 2; - COLD = 3; - } - - // The start type. - optional StartType type = 4; - - // The elapsed realtime at the start of the process. - optional int64 process_start_time_millis = 5; - - // Number of milliseconds it takes to reach bind application. - optional int32 bind_application_delay_millis = 6; - - // Number of milliseconds it takes to finish start of the process. - optional int32 process_start_delay_millis = 7; - - // hostingType field in ProcessRecord, the component type such as "activity", - // "service", "content provider", "broadcast" or other strings. - optional string hosting_type = 8; - - // hostingNameStr field in ProcessRecord. The component class name that runs - // in this process. - optional string hosting_name = 9; -} - -/** - * Track Media Codec usage - * Logged from: - * frameworks/av/media/libstagefright/MediaCodec.cpp - * frameworks/av/services/mediaanalytics/statsd_codec.cpp - */ -message MediametricsCodecReported { - optional int64 timestamp_nanos = 1; - optional string package_name = 2; - optional int64 package_version_code = 3; - optional int64 media_apex_version = 4; - - optional android.stats.mediametrics.CodecData codec_data = 5 [(android.os.statsd.log_mode) = MODE_BYTES]; -} - -/** - * Track Media Extractor (pulling video/audio streams out of containers) usage - * Logged from: - * frameworks/av/media/libstagefright/RemoteMediaExtractor.cpp - * frameworks/av/services/mediaanalytics/statsd_extractor.cpp - */ -message MediametricsExtractorReported { - optional int64 timestamp_nanos = 1; - optional string package_name = 2; - optional int64 package_version_code = 3; - optional int64 media_apex_version = 4; - - optional android.stats.mediametrics.ExtractorData extractor_data = 5 [(android.os.statsd.log_mode) = MODE_BYTES]; -} - -/** - * Track MediaParser (parsing video/audio streams from containers) usage - * Logged from: - * - * frameworks/av/services/mediametrics/statsd_mediaparser.cpp - * frameworks/base/apex/media/framework/jni/android_media_MediaParserJNI.cpp - */ -message MediametricsMediaParserReported { - optional int64 timestamp_nanos = 1; - optional string package_name = 2; - optional int64 package_version_code = 3; - - // MediaParser specific data. - /** - * The name of the parser selected for parsing the media, or an empty string - * if no parser was selected. - */ - optional string parser_name = 4; - /** - * Whether the parser was created by name. 1 represents true, and 0 - * represents false. - */ - optional int32 created_by_name = 5; - /** - * The parser names in the sniffing pool separated by "|". - */ - optional string parser_pool = 6; - /** - * The fully qualified name of the last encountered exception, or an empty - * string if no exception was encountered. - */ - optional string last_exception = 7; - /** - * The size of the parsed media in bytes, or -1 if unknown. Note this value - * contains intentional random error to prevent media content - * identification. - */ - optional int64 resource_byte_count = 8; - /** - * The duration of the media in milliseconds, or -1 if unknown. Note this - * value contains intentional random error to prevent media content - * identification. - */ - optional int64 duration_millis = 9; - /** - * The MIME types of the tracks separated by "|". - */ - optional string track_mime_types = 10; - /** - * The tracks' RFC 6381 codec strings separated by "|". - */ - optional string track_codecs = 11; - /** - * Concatenation of the parameters altered by the client, separated by "|". - */ - optional string altered_parameters = 12; - /** - * The video width in pixels, or -1 if unknown or not applicable. - */ - optional int32 video_width = 13; - /** - * The video height in pixels, or -1 if unknown or not applicable. - */ - optional int32 video_height = 14; -} - -/** - * Track how we arbitrate between microphone/input requests. - * Logged from - * frameworks/av/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp - * frameworks/av/services/mediaanalytics/statsd_audiopolicy.cpp - */ -message MediametricsAudiopolicyReported { - optional int64 timestamp_nanos = 1; - optional string package_name = 2; - optional int64 package_version_code = 3; - optional int64 media_apex_version = 4; - - optional android.stats.mediametrics.AudioPolicyData audiopolicy_data = 5 [(android.os.statsd.log_mode) = MODE_BYTES]; -} - -/** - * Track how we arbitrate between microphone requests. - * Logged from - * frameworks/av/media/libaudioclient/AudioRecord.cpp - * frameworks/av/services/mediaanalytics/statsd_audiorecord.cpp - */ -message MediametricsAudiorecordReported { - optional int64 timestamp_nanos = 1; - optional string package_name = 2; - optional int64 package_version_code = 3; - optional int64 media_apex_version = 4; - - optional android.stats.mediametrics.AudioRecordData audiorecord_data = 5 [(android.os.statsd.log_mode) = MODE_BYTES]; -} - -/** - * Track how we arbitrate between microphone/input requests. - * Logged from - * frameworks/av/media/libnblog/ReportPerformance.cpp - * frameworks/av/services/mediaanalytics/statsd_audiothread.cpp - */ -message MediametricsAudiothreadReported { - optional int64 timestamp_nanos = 1; - optional string package_name = 2; - optional int64 package_version_code = 3; - optional int64 media_apex_version = 4; - - optional android.stats.mediametrics.AudioThreadData audiothread_data = 5 [(android.os.statsd.log_mode) = MODE_BYTES]; -} - -/** - * Track how we arbitrate between microphone/input requests. - * Logged from - * frameworks/av/media/libaudioclient/AudioTrack.cpp - * frameworks/av/services/mediaanalytics/statsd_audiotrack.cpp - */ -message MediametricsAudiotrackReported { - optional int64 timestamp_nanos = 1; - optional string package_name = 2; - optional int64 package_version_code = 3; - optional int64 media_apex_version = 4; - - optional android.stats.mediametrics.AudioTrackData audiotrack_data = 5 [(android.os.statsd.log_mode) = MODE_BYTES]; -} - -/** - * Track information about DRM framework performance - * Logged from - * frameworks/av/drm/libmediadrm/DrmHal.cpp - * frameworks/av/services/mediaanalytics/statsd_drm.cpp - */ -message MediametricsMediadrmReported { - optional int64 timestamp_nanos = 1; - optional string package_name = 2; - optional int64 package_version_code = 3; - optional int64 media_apex_version = 4; - - // vendor+description tell about which DRM plugin is in use on this device - optional string vendor = 5; - optional string description = 6; - // from frameworks/av/drm/libmediadrm/protos/metrics.proto - optional bytes framework_stats = 7 [(android.os.statsd.log_mode) = MODE_BYTES]; -} - -/** - * Track information about the widevine DRM plugin performance - * Logged from - * vendor/widevine/libwvdrmengine/cdm/metrics - * frameworks/av/services/mediaanalytics/statsd_drm.cpp - */ -message MediametricsDrmWidevineReported { - optional int64 timestamp_nanos = 1; - optional string package_name = 2; - optional int64 package_version_code = 3; - optional int64 media_apex_version = 4; - - optional bytes vendor_specific_stats = 5 [(android.os.statsd.log_mode) = MODE_BYTES]; -} - -/** - * Track information about recordings (e.g. camcorder) - * Logged from - * frameworks/av/media/libmediaplayerservice/StagefrightRecorder.cpp - * frameworks/av/services/mediaanalytics/statsd_recorder.cpp - */ -message MediametricsRecorderReported { - optional int64 timestamp_nanos = 1; - optional string package_name = 2; - optional int64 package_version_code = 3; - optional int64 media_apex_version = 4; - - optional android.stats.mediametrics.RecorderData recorder_data = 5 [(android.os.statsd.log_mode) = MODE_BYTES]; -} - -/** - * Track Media Player usage - * Logged from: - * frameworks/av/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp - * frameworks/av/services/mediaanalytics/statsd_nuplayer.cpp - */ -message MediametricsNuPlayerReported { - optional int64 timestamp_nanos = 1; - optional string package_name = 2; - optional int64 package_version_code = 3; - optional int64 media_apex_version = 4; - - optional android.stats.mediametrics.NuPlayerData nuplayer_data = 5 [(android.os.statsd.log_mode) = MODE_BYTES]; -} - -/** - * Track Legacy DRM usage - * Logged from - * frameworks/av/drm/drmserver/DrmManager.cpp - */ -message MediametricsDrmManagerReported { - optional int64 timestamp_nanos = 1; - optional string package_name = 2; - optional int64 package_version_code = 3; - optional int64 media_apex_version = 4; - - enum Method { - METHOD_NOT_FOUND = -1; - GET_CONSTRAINTS = 0; - GET_METADATA = 1; - CAN_HANDLE = 2; - PROCESS_DRM_INFO = 3; - ACQUIRE_DRM_INFO = 4; - SAVE_RIGHTS = 5; - GET_ORIGINAL_MIME_TYPE = 6; - GET_DRM_OBJECT_TYPE = 7; - CHECK_RIGHTS_STATUS = 8; - REMOVE_RIGHTS = 9; - REMOVE_ALL_RIGHTS = 10; - OPEN_CONVERT_SESSION = 11; - OPEN_DECRYPT_SESSION = 12; - } - - // plugin_id+description inform which Legacy DRM plugins are still in use on device - optional string plugin_id = 5; - optional string description = 6; - optional Method method = 7; - optional string mime_types = 8; - - optional int64 get_constraints_count = 9; - optional int64 get_metadata_count = 10; - optional int64 can_handle_count = 11; - optional int64 process_drm_info_count = 12; - optional int64 acquire_drm_info_count = 13; - optional int64 save_rights_count = 14; - optional int64 get_original_mime_type_count = 15; - optional int64 get_drm_object_type_count = 16; - optional int64 check_rights_status_count = 17; - optional int64 remove_rights_count = 18; - optional int64 remove_all_rights_count = 19; - optional int64 open_convert_session_count = 20; - optional int64 open_decrypt_session_count = 21; -} - -/** - * State of a dangerous permission requested by a package - * Pulled from: StatsCompanionService -*/ -message DangerousPermissionState { - // Name of the permission - optional string permission_name = 1; - - // Uid of the package - optional int32 uid = 2 [(is_uid) = true]; - - // Package requesting the permission - optional string package_name = 3; - - // If the permission is granted to the uid - optional bool is_granted = 4; - - // Permission flags as per android.content.pm.PermissionFlags - optional int32 permission_flags = 5; -} - -/** - * Logs when a package is denied access to a device identifier based on the new access requirements. - * - * Logged from: - * frameworks/base/telephony/java/com/android/internal/telephony/TelephonyPermissions.java - */ -message DeviceIdentifierAccessDenied { - // The name of the package denied access to the requested device identifier. - optional string package_name = 1; - - // The name of the device identifier method the package attempted to invoke. - optional string method_name = 2; - - // True if the package is preinstalled. - // Starting from Android 11, this boolean is not set and will always be false. - optional bool is_preinstalled = 3 [deprecated = true]; - - // True if the package is privileged. - // Starting from Android 11, this boolean is not set and will always be false. - optional bool is_priv_app = 4 [deprecated = true]; -} - -/** - * Pulls the ongoing mainline install train version code. - * Pulled from StatsCompanionService - */ -message TrainInfo { - optional int64 train_version_code = 1; - - optional TrainExperimentIds train_experiment_id = 2 [(log_mode) = MODE_BYTES]; - - optional string train_name = 3; - - enum Status { - UNKNOWN = 0; - INSTALL_REQUESTED = 1; - INSTALL_STARTED = 2; - INSTALL_STAGED_NOT_READY = 3; - INSTALL_STAGED_READY = 4; - INSTALL_SUCCESS = 5; - // Replaced by INSTALL_FAILURE_DOWNLOAD, INSTALL_FAILURE_STATE_MISMATCH, - // and INSTALL_FAILURE_COMMIT. - INSTALL_FAILURE = 6 [deprecated = true]; - // This enum is for installs that are manually cancelled via the Manual Update UI. - INSTALL_CANCELLED = 7; - INSTALLER_ROLLBACK_REQUESTED = 8; - INSTALLER_ROLLBACK_INITIATED = 9; - INSTALLER_ROLLBACK_INITIATED_FAILURE = 10; - INSTALLER_ROLLBACK_STAGED = 11; - INSTALLER_ROLLBACK_STAGED_FAILURE = 12; - INSTALLER_ROLLBACK_BOOT_TRIGGERED = 13; - INSTALLER_ROLLBACK_BOOT_TRIGGERED_FAILURE = 14; - INSTALLER_ROLLBACK_SUCCESS = 15; - INSTALLER_ROLLBACK_FAILURE = 16; - INSTALLER_ROLLBACK_STAGED_CANCEL_REQUESTED = 17; - INSTALLER_ROLLBACK_STAGED_CANCEL_SUCCESS = 18; - INSTALLER_ROLLBACK_STAGED_CANCEL_FAILURE = 19; - INSTALL_STAGED_CANCEL_REQUESTED = 20; - INSTALL_STAGED_CANCEL_SUCCESS = 21; - INSTALL_STAGED_CANCEL_FAILURE = 22; - INSTALL_FAILURE_DOWNLOAD = 23; - INSTALL_FAILURE_STATE_MISMATCH = 24; - INSTALL_FAILURE_COMMIT = 25; - REBOOT_TRIGGERED = 26; - } - optional Status status = 4; -} - -/** - * Logs the gesture stage changed event. - * - * Logged from: - * frameworks/base/packages/SystemUI/ - */ -message AssistGestureStageReported { - optional android.hardware.sensor.assist.AssistGestureStageEnum gesture_stage = 1; -} - -/** - * Logs the feedback type. - * - * Logged from: - * frameworks/base/packages/SystemUI/ - */ -message AssistGestureFeedbackReported { - // Whether or not the gesture was used. - optional android.hardware.sensor.assist.AssistGestureFeedbackEnum feedback_type = 1; -} - -/** - * Logs the progress. - * - * Logged from: - * frameworks/base/packages/SystemUI/ - */ -message AssistGestureProgressReported { - // [0,100] progress for the assist gesture. - optional int32 progress = 1; -} - -/* - * Information about the time zone data on a device. - */ -message TimeZoneDataInfo { - // A version identifier for the data set on device. e.g. "2018i" - optional string tzdb_version = 1; -} - -/** - * Logs the GPU stats global health information. - * - * Logged from: - * frameworks/native/services/gpuservice/gpustats/ - */ -message GpuStatsGlobalInfo { - // Package name of the gpu driver. - optional string driver_package_name = 1; - - // Version name of the gpu driver. - optional string driver_version_name = 2; - - // Version code of the gpu driver. - optional int64 driver_version_code = 3; - - // Build time of the gpu driver in UTC as seconds since January 1, 1970. - optional int64 driver_build_time = 4; - - // Total count of the gl driver gets loaded. - optional int64 gl_loading_count = 5; - - // Total count of the gl driver fails to be loaded. - optional int64 gl_loading_failure_count = 6; - - // Total count of the Vulkan driver gets loaded. - optional int64 vk_loading_count = 7; - - // Total count of the Vulkan driver fails to be loaded. - optional int64 vk_loading_failure_count = 8; - - // Api version of the system Vulkan driver. - optional int32 vulkan_version = 9; - - // Api version of the system CPU Vulkan driver. - optional int32 cpu_vulkan_version = 10; - - // Api version of the system GLES driver. - optional int32 gles_version = 11; - - // Total count of the angle driver gets loaded. - optional int64 angle_loading_count = 12; - - // Total count of the angle driver fails to be loaded. - optional int64 angle_loading_failure_count = 13; -} - -/** - * GPU driver loading time info. - */ -message GpuDriverLoadingTime { - // List of all the driver loading times for this app. The list size is - // capped at 50. - repeated int64 driver_loading_time = 1; -} - -/** - * Logs the GPU stats per app health information. - * - * Logged from: - * frameworks/native/services/gpuservice/gpustats/ - */ -message GpuStatsAppInfo { - // Package name of the application that loads the gpu driver. Total number - // of different packages is capped at 100. - optional string app_package_name = 1; - - // Version code of the gpu driver this app loads. - optional int64 driver_version_code = 2; - - // gl driver loading time info. - optional GpuDriverLoadingTime gl_driver_loading_time = 3 - [(android.os.statsd.log_mode) = MODE_BYTES]; - - // Vulkan driver loading time info. - optional GpuDriverLoadingTime vk_driver_loading_time = 4 - [(android.os.statsd.log_mode) = MODE_BYTES]; - - // Angle driver loading time info. - optional GpuDriverLoadingTime angle_driver_loading_time = 5 - [(android.os.statsd.log_mode) = MODE_BYTES]; - - // CPU Vulkan implementation is in use. - optional bool cpu_vulkan_in_use = 6; - - // App is not doing pre-rotation correctly. - optional bool false_prerotation = 7; - - // App creates GLESv1 context. - optional bool gles_1_in_use = 8; -} - -/* - * Logs the size of the system ion heap. - * - * Pulled from StatsCompanionService. - */ -message SystemIonHeapSize { - // Deprecated due to limited support of ion stats in debugfs. - // Use `IonHeapSize` instead. - option deprecated = true; - - // Size of the system ion heap in bytes. - // Read from debugfs. - optional int64 size_in_bytes = 1; -} - -/* - * Logs the total size of the ion heap. - * - * Pulled from StatsCompanionService. - */ -message IonHeapSize { - // Total size of all ion heaps in kilobytes. - // Read from: /sys/kernel/ion/total_heaps_kb. - optional int32 total_size_kb = 1; -} - -/* - * Logs the per-process size of the system ion heap. - * - * Pulled from StatsCompanionService. - */ -message ProcessSystemIonHeapSize { - // The uid if available. -1 means not available. - optional int32 uid = 1 [(is_uid) = true]; - - // The process name (from /proc/PID/cmdline). - optional string process_name = 2; - - // Sum of sizes of all allocations. - optional int32 total_size_in_kilobytes = 3; - - // Number of allocations. - optional int32 allocation_count = 4; - - // Size of the largest allocation. - optional int32 max_size_in_kilobytes = 5; -} - -/** - * Push network stack events. - * - * Log from: - * frameworks/base/packages/NetworkStack/ - */ -message NetworkStackReported { - // The id that indicates the event reported from NetworkStack. - optional int32 event_id = 1; - // The data for the reported events. - optional android.stats.connectivity.NetworkStackEventData network_stack_event = 2 [(log_mode) = MODE_BYTES]; -} - -/** - * Logs the apps that are installed on the external storage. - * Pulled from: - * StatsCompanionService - */ -message AppsOnExternalStorageInfo { - // The type of the external storage. - optional android.stats.storage.ExternalStorageType external_storage_type = 1; - // The name of the package that is installed on the external storage. - optional string package_name = 2; -} - -/** - * Logs the settings related to Face. - * Logged from: - * frameworks/base/services/core/java/com/android/server/stats - */ -message FaceSettings { - // Whether or not face unlock is allowed on Keyguard. - optional bool unlock_keyguard_enabled = 1; - // Whether or not face unlock dismisses the Keyguard. - optional bool unlock_dismisses_keyguard = 2; - // Whether or not face unlock requires attention. - optional bool unlock_attention_required = 3; - // Whether or not face unlock is allowed for apps (through BiometricPrompt). - optional bool unlock_app_enabled = 4; - // Whether or not face unlock always requires user confirmation. - optional bool unlock_always_require_confirmation = 5; - // Whether or not a diverse set of poses are required during enrollment. - optional bool unlock_diversity_required = 6; -} - -/** - * Logs cooling devices maintained by the kernel. - * - * Pulled from StatsCompanionService.java - */ -message CoolingDevice { - // The type of cooling device being reported. Eg. CPU, GPU... - optional android.os.CoolingTypeEnum device_location = 1; - // The name of the cooling device source. Eg. CPU0 - optional string device_name = 2; - // Current throttle state of the cooling device. The value can any unsigned - // integer between 0 and max_state defined in its driver. 0 means device is - // not in throttling, higher value means deeper throttling. - optional int32 state = 3; -} - -/** - * Intelligence has several counter-type events that don't warrant a - * full separate atom. These are primarily API call counters but also include - * counters for feature usage and specific failure modes. - * - * Logged from the Intelligence mainline module. - */ -message IntelligenceEventReported { - // The event type. - optional android.stats.intelligence.EventType event_id = 1; - // Success, failure. - optional android.stats.intelligence.Status status = 2; - // How many times the event occured (to report a batch of high frequency events). - optional int32 count = 3; - // How long the event took (sum of durations if count > 1) - optional int64 duration_millis = 4; -} - -/** - * Logs when Car Power state changed. - * - * Logged from: - * packages/services/Car/service/src/com/android/car/CarStatsLog.java - */ -message CarPowerStateChanged { - // States come from CpmsState in CarPowerManagementService.java. - enum State { - WAIT_FOR_VHAL = 0; - ON = 1; - SHUTDOWN_PREPARE = 2; - WAIT_FOR_FINISH = 3; - SUSPEND = 4; - SIMULATE_SLEEP = 5; - } - optional State state = 1; -} - -/** - * Logs when Car User Hal is requested to switch/create/remove user. - * - * Logged from: - * packages/services/Car/service/src/com/android/car/hal/UserHalService.java - */ -message CarUserHalModifyUserRequestReported { - // Request id for the request. - optional int32 request_id = 1; - // Request type. - enum RequestType { - UNKNOWN = 0; - // Car user manager requested user switch. - SWITCH_REQUEST_ANDROID = 1; - // OEM requested User switch. - SWITCH_REQUEST_OEM = 2; - // Hal switch requested after android switch using activity manager. - SWITCH_REQUEST_LEGACY = 3; - // Create User - CREATE_REQUEST = 4; - // Remove User - REMOVE_REQUEST = 5; - } - optional RequestType request_type = 2; - // Android User id of the current user which can only be 0, 10, 11 and so on. - // -1 if not available. - optional int32 user_id = 3; - // VHAL flags of the current user. (-1 if not available) - optional int32 user_flags = 4; - // Android User id of the target user for switch/create/remove. It can only - // be 0, 10, 11 and so on. -1 if not available. - optional int32 target_user_id = 5; - // VHAL flags of the target user for switch/create/remove. (-1 if not available) - optional int32 target_user_flags = 6; - // Request timeout Milliseconds (-1 if not available) - optional int32 timeout_millis = 7; -} - -/** - * Logs when Car User Hal responds to switch/create user request. - * - * Logged from: - * packages/services/Car/service/src/com/android/car/hal/UserHalService.java - */ -message CarUserHalModifyUserResponseReported { - // Request id of the request associated with the response. - optional int32 request_id = 1; - // Car user hal callback status. - enum CallbackStatus { - UNKNOWN = 0; - // Hal response was invalid. - INVALID = 1; - // Hal response was ok. - OK = 2; - // Hal timeout during set call. - HAL_SET_TIMEOUT = 3; - // Hal response timeout. - HAL_RESPONSE_TIMEOUT = 4; - // Hal responded with wrong info. - WRONG_HAL_RESPONSE = 5; - // Hal is processing multiple requests simultaneously. - CONCURRENT_OPERATION = 6; - } - optional CallbackStatus callback_status = 2; - - // Hal request status for user switch/create/remove. - enum HalRequestStatus { - UNSPECIFIED = 0; - // Hal request for user switch/create is successful. - SUCCESS = 1; - // Hal request for user switch/create failed. - FAILURE = 2; - } - optional HalRequestStatus request_status = 3; -} - -/** - * Logs when post switch response is posted to Car User Hal. - * - * Logged from: - * packages/services/Car/service/src/com/android/car/hal/UserHalService.java - */ -message CarUserHalPostSwitchResponseReported { - // Request id. - optional int32 request_id = 1; - - // Android user switch status. - enum UserSwitchStatus { - UNKNOWN = 0; - // Android user switch is successful. - SUCCESS = 1; - // Android user switch failed. - FAILURE = 2; - } - optional UserSwitchStatus switch_status = 2; -} - -/** - * Logs when initial user information is requested from Car User Hal. - * - * Logged from: - * packages/services/Car/service/src/com/android/car/hal/UserHalService.java - */ -message CarUserHalInitialUserInfoRequestReported { - // Request id for the request. - optional int32 request_id = 1; - - // Request type for initial user information. - enum InitialUserInfoRequestType { - UNKNOWN = 0; - // At the first time Android was booted (or after a factory reset). - FIRST_BOOT = 1; - // At the first time Android was booted after the system was updated. - FIRST_BOOT_AFTER_OTA = 2; - // When Android was booted "from scratch". - COLD_BOOT = 3; - // When Android was resumed after the system was suspended to memory. - RESUME = 4; - } - optional InitialUserInfoRequestType request_type = 2; - // Request timeout Milliseconds (-1 if not available) - optional int32 timeout_millis = 3; -} - -/** - * Logs when Car User Hal responds to initial user information requests. - * - * Logged from: - * packages/services/Car/service/src/com/android/car/hal/UserHalService.java - */ -message CarUserHalInitialUserInfoResponseReported { - // Request id of the request associated with the response. - optional int32 request_id = 1; - // Car user hal callback status. - enum CallbackStatus { - UNKNOWN = 0; - // Hal response was invalid. - INVALID = 1; - // Hal response was ok. - OK = 2; - // Hal timeout during set call. - HAL_SET_TIMEOUT = 3; - // Hal response timeout. - HAL_RESPONSE_TIMEOUT = 4; - // Hal responded with wrong info. - WRONG_HAL_RESPONSE = 5; - // Hal is processing multiple requests simultaneously. - CONCURRENT_OPERATION = 6; - } - optional CallbackStatus callback_status = 2; - // Response for initial user information request. - enum InitialUserInfoResponseAction { - UNSPECIFIED = 0; - // Let the Android System decide what to do. - DEFAULT = 1; - // Switch to an existing Android user. - SWITCH = 2; - // Create a new Android user (and switch to it). - CREATE = 3; - } - optional InitialUserInfoResponseAction response_action = 3; - // Android User id of the target user which can only be 0, 10, 11 and so on. - // -1 if not available. - optional int32 target_user = 4; - // VHAL flags of the current user. (-1 if not available) - optional int32 target_user_flags = 5; - // User locales - optional string user_locales = 6; -} - -/** - * Logs when set user association is requested from Car User Hal. - * - * Logged from: - * packages/services/Car/service/src/com/android/car/hal/UserHalService.java - */ -message CarUserHalUserAssociationRequestReported { - // Request id for the request. - optional int32 request_id = 1; - // Request type. - enum RequestType { - UNKNOWN = 0; - // For setting user association information. - SET = 1; - // For getting user association information. - GET = 2; - } - optional RequestType request_type = 2; - // Android User id of the current user which can only be 0, 10, 11 and so on. - // -1 if not available. - optional int32 current_user_id = 3; - // VHAL flags of the current user. (-1 if not available) - optional int32 current_user_flags = 4; - // Number of the set associations requested. - optional int32 number_associations = 5; - // Concatenated string for the types from set associations request. - // This is a string converted from an array of integers. - optional string user_identification_association_types = 6; - // Concatenated string for the values from set associations request. - // This is a string converted from an array of integers. - optional string user_identification_association_values = 7; -} - -/** - * Logs when Car User Hal responds to set user association requests. - * - * Logged from: - * packages/services/Car/service/src/com/android/car/hal/UserHalService.java - */ -message CarUserHalSetUserAssociationResponseReported { - // Request id of the request associated with the response. - optional int32 request_id = 1; - // Car user hal callback status. - enum CallbackStatus { - UNKNOWN = 0; - // Hal response was invalid. - INVALID = 1; - // Hal response was ok. - OK = 2; - // Hal timeout during set call. - HAL_SET_TIMEOUT = 3; - // Hal response timeout. - HAL_RESPONSE_TIMEOUT = 4; - // Hal responded with wrong info. - WRONG_HAL_RESPONSE = 5; - // Hal is processing multiple requests simultaneously. - CONCURRENT_OPERATION = 6; - } - optional CallbackStatus callback_status = 2; - // Number of the set associations in the response. - optional int32 number_associations = 3; - // Concatenated string for the types from set associations request. - // This is a string converted from an array of integers. - optional string user_identification_association_types = 4; - // Concatenated string for the values from set associations request. - // This is a string converted from an array of integers. - optional string user_identification_association_values = 5; -} - -/** - * Logs whether GarageMode is entered. - * - * Logged from: - * packages/services/Car/service/src/com/android/car/CarStatsLog.java - */ -message GarageModeInfo { - // Whether GarageMode is entered. - optional bool is_garage_mode = 1; -} - -/** - * Historical app ops data per package. - */ -message AppOps { - // Uid of the package requesting the op - optional int32 uid = 1 [(is_uid) = true]; - - // Name of the package performing the op - optional string package_name = 2; - - // operation id - optional android.app.AppOpEnum op_id = 3 [default = APP_OP_NONE]; - - // The number of times the op was granted while the app was in the - // foreground (only for trusted requests) - optional int64 trusted_foreground_granted_count = 4; - - // The number of times the op was granted while the app was in the - // background (only for trusted requests) - optional int64 trusted_background_granted_count = 5; - - // The number of times the op was rejected while the app was in the - // foreground (only for trusted requests) - optional int64 trusted_foreground_rejected_count = 6; - - // The number of times the op was rejected while the app was in the - // background (only for trusted requests) - optional int64 trusted_background_rejected_count = 7; - - // For long-running operations, total duration of the operation - // while the app was in the foreground (only for trusted requests) - optional int64 trusted_foreground_duration_millis = 8; - - // For long-running operations, total duration of the operation - // while the app was in the background (only for trusted requests) - optional int64 trusted_background_duration_millis = 9; - - // Whether AppOps is guarded by Runtime permission - optional bool is_runtime_permission = 10; -} - -/** - * Historical app ops data per package and attribution tag. - */ -message AttributedAppOps { - // Uid of the package requesting the op - optional int32 uid = 1 [(is_uid) = true]; - - // Name of the package performing the op - optional string package_name = 2; - - // tag; provided by developer when accessing related API, limited at 50 chars by API. - // Attributions must be provided through manifest using <attribution> tag available in R and - // above. - optional string tag = 3; - - // operation id - optional android.app.AppOpEnum op = 4 [default = APP_OP_NONE]; - - // The number of times the op was granted while the app was in the - // foreground (only for trusted requests) - optional int64 trusted_foreground_granted_count = 5; - - // The number of times the op was granted while the app was in the - // background (only for trusted requests) - optional int64 trusted_background_granted_count = 6; - - // The number of times the op was rejected while the app was in the - // foreground (only for trusted requests) - optional int64 trusted_foreground_rejected_count = 7; - - // The number of times the op was rejected while the app was in the - // background (only for trusted requests) - optional int64 trusted_background_rejected_count = 8; - - // For long-running operations, total duration of the operation - // while the app was in the foreground (only for trusted requests) - optional int64 trusted_foreground_duration_millis = 9; - - // For long-running operations, total duration of the operation - // while the app was in the background (only for trusted requests) - optional int64 trusted_background_duration_millis = 10; - - // Whether AppOps is guarded by Runtime permission - optional bool is_runtime_permission = 11; - - // Sampling rate used on device, from 0 to 100 - optional int32 sampling_rate = 12; -} - -/** - * Location Manager API Usage information(e.g. API under usage, - * API call's parameters). - * Logged from: - * frameworks/base/services/core/java/com/android/server/LocationManagerService.java - */ -message LocationManagerApiUsageReported { - - // Indicating if usage starts or usage ends. - optional android.stats.location.UsageState state = 1; - - // LocationManagerService's API in use. - // We can identify which API from LocationManager is - // invoking current LMS API by the combination of - // API parameter(e.g. is_listener_null, is_intent_null, - // is_location_request_null) - optional android.stats.location.LocationManagerServiceApi api_in_use = 2; - - // Name of the package calling the API. - optional string calling_package_name = 3; - - // Type of the location provider. - optional android.stats.location.ProviderType provider = 4; - - // Quality of the location request - optional android.stats.location.LocationRequestQuality quality = 5; - - // The desired interval for active location updates, in milliseconds. - // Bucketized to reduce cardinality. - optional android.stats.location.LocationRequestIntervalBucket bucketized_interval = 6; - - // Minimum distance between location updates, in meters. - // Bucketized to reduce cardinality. - optional android.stats.location.SmallestDisplacementBucket - bucketized_smallest_displacement = 7; - - // The number of location updates. - optional int64 num_updates = 8; - - // The request expiration time, in millisecond since boot. - // Bucketized to reduce cardinality. - optional android.stats.location.ExpirationBucket - bucketized_expire_in = 9; - - // Type of Callback passed in for this API. - optional android.stats.location.CallbackType callback_type = 10; - - // The radius of the central point of the alert - // region, in meters. Only for API REQUEST_GEOFENCE. - // Bucketized to reduce cardinality. - optional android.stats.location.GeofenceRadiusBucket bucketized_radius = 11; - - // Activity Importance of API caller. - // Categorized to 3 types that are interesting from location's perspective. - optional android.stats.location.ActivityImportance activiy_importance = 12; -} - -/** - * Information about a permission grant or denial made by user inside ReviewPermissionsFragment - */ -message ReviewPermissionsFragmentResultReported { - // unique value identifying a permission group change. A permission group change might result - // in multiple of these atoms - optional int64 change_id = 1; - - // UID of package the permission belongs to - optional int32 uid = 2 [(is_uid) = true]; - - // Name of package the permission belongs to - optional string package_name = 3; - - // The permission to be granted - optional string permission_name = 4; - - // The result of the permission grant - optional bool permission_granted = 5; -} - -/** -* Information about results of permission upgrade by RuntimePermissionsUpgradeController -* Logged from: RuntimePermissionUpdgradeController -*/ -message RuntimePermissionsUpgradeResult { - // Permission granted as result of upgrade - optional string permission_name = 1; - - // UID of package granted permission - optional int32 uid = 2 [(is_uid) = true]; - - // Name of package granted permission - optional string package_name = 3; -} - -/** -* Information about a buttons presented in GrantPermissionsActivty and choice made by user -*/ -message GrantPermissionsActivityButtonActions { - // Permission granted as result of upgrade - optional string permission_group_name = 1; - - // UID of package granted permission - optional int32 uid = 2 [(is_uid) = true]; - - // Name of package requesting permission - optional string package_name = 3; - - // Buttons presented in the dialog - bit flags, bit numbers are in accordance with - // LABEL_ constants in GrantPermissionActivity.java - optional int32 buttons_presented = 4; - - // Button clicked by user - same as bit flags in buttons_presented with only single bit set - optional int32 button_clicked = 5; - - // id which identifies single session of user interacting with permission controller - optional int64 session_id = 6; -} - -/** - * Information about LocationAccessCheck notification presented to user - */ -message LocationAccessCheckNotificationAction { - - // id which identifies single session of user interacting with permission controller - optional int64 session_id = 1; - - // Uid of package for which location access check is presented - optional int32 package_uid = 2; - - // Name of package for which location access check is presented - optional string package_name = 3; - - enum Result { - UNDEFINED = 0; - // notification was presented to the user - NOTIFICATION_PRESENTED = 1; - // notification was declined by the user - NOTIFICATION_DECLINED = 2; - // notification was clicked by the user - NOTIFICATION_CLICKED = 3; - } - - // View / interaction recorded - optional Result result = 4; -} - -/** - * Information about a permission grant or revoke made by user inside AppPermissionFragment - */ -message AppPermissionFragmentActionReported { - // id which identifies single session of user interacting with permission controller - optional int64 session_id = 1; - - // unique value identifying a permission group change. A permission group change might result - // in multiple of these atoms - optional int64 change_id = 2; - - // UID of package the permission belongs to - optional int32 uid = 3 [(is_uid) = true]; - - // Name of package the permission belongs to - optional string package_name = 4; - - // The permission to be granted - optional string permission_name = 5; - - // The result of the permission grant - optional bool permission_granted = 6; - - // State of Permission Flags after grant as per android.content.pm.PermissionFlags - optional int32 permission_flags = 7; - - enum Button { - UNDEFINED = 0; - // Allow button - ALLOW = 1; - // Deny button - DENY = 2; - // Ask every time button - ASK_EVERY_TIME = 3; - // Allow all the time button - ALLOW_ALWAYS = 4; - // Allow only while using the app button - ALLOW_FOREGROUND = 5; - // Same is Deny button but shown in while in use dialog - DENY_FOREGROUND = 6; - } - - // Button pressed in the dialog - optional Button button_pressed = 8; -} - -/** -* Information about a AppPermissionFragment viewed by user -*/ -message AppPermissionFragmentViewed { - // id which identifies single session of user interacting with permission controller - optional int64 session_id = 1; - - // UID of package for which permissions are viewed - optional int32 uid = 2 [(is_uid) = true]; - - // Name of package for which permissions are viewed - optional string package_name = 3; - - // Permission group viewed - optional string permission_group_name = 4; -} - -/** -* Information about a AppPermissionGroupsFragment viewed by user. Fragment has been renamed, but -* the log retains the old fragment name. -*/ -message AppPermissionsFragmentViewed { - // id which identifies single session of user interacting with permission controller - optional int64 session_id = 1; - - // id which identifies single view as every view might have several logging records - // with different package information attached - optional int64 view_id = 2; - - // Permission group viewed - optional string permission_group_name = 3; - - // UID of package for which permissions are viewed - optional int32 uid = 4 [(is_uid) = true]; - - // Name of package for which permissions are viewed - optional string package_name = 5; - - // Category in which permission is included - enum Category { - UNDEFINED = 0; - ALLOWED = 1; - ALLOWED_FOREGROUND = 2; - DENIED = 3; - } - optional Category category = 6; -} -/** -* Information about a PermissionAppsFragment viewed by user. -* Logged from ui/handheld/PermissionAppsFragment.java -*/ -message PermissionAppsFragmentViewed { - // id which identifies single session of user interacting with permission controller - optional int64 session_id = 1; - - // id which identifies single view as every view might have several logging records - // with different package information attached - optional int64 view_id = 2; - - // Permission group viewed - optional string permission_group_name = 3; - - // UID of package for which permissions are viewed - optional int32 uid = 4 [(is_uid) = true]; - - // Name of package for which permissions are viewed - optional string package_name = 5; - - // Category in which app is included - enum Category { - UNDEFINED = 0; - ALLOWED = 1; - ALLOWED_FOREGROUND = 2; - DENIED = 3; - } - optional Category category = 6; -} - -/** -* Log that the Auto Revoke notification has been clicked -* Logged from ui/ManagePermissionsActivity -*/ -message AutoRevokeNotificationClicked { - // id which identifies single session of user interacting with permission controller - optional int64 session_id = 1; -} - -/** -* Log that an app has been displayed on the auto revoke page, and lists one permission that was -* auto revoked for it. -* Logged from ui/handheld/AutoRevokeFragment -*/ -message AutoRevokeFragmentAppViewed { - // id which identifies single session of user interacting with permission controller - optional int64 session_id = 1; - - // UID of package for which permissions are viewed - optional int32 uid = 2 [(is_uid) = true]; - - // Name of package for which permissions are viewed - optional string package_name = 3; - - // The name of a permission group that has been revoked - optional string permission_group_name = 4; - - // The age of the app- more than three months old, or more than six months - enum Age { - UNDEFINED = 0; - NEWER_BUCKET = 1; - OLDER_BUCKET = 2; - } - - // How long the app has been unused. Currently, newer bucket is 3 months, older is 6 months - optional Age age = 5; -} - -/** -* Log that the user has interacted with an app on the auto revoke fragment -* Logged from ui/handheld/AutoRevokeFragment -*/ -message AutoRevokedAppInteraction { - // id which identifies single session of user interacting with permission controller - optional int64 session_id = 1; - - // UID of package for which permissions are viewed - optional int32 uid = 2 [(is_uid) = true]; - - // Name of package for which permissions are viewed - optional string package_name = 3; - - enum Action { - UNDEFINED = 0; - REMOVE = 1; - OPEN = 2; - APP_INFO = 3; - PERMISSIONS = 4; - REMOVE_IN_SETTINGS = 5; - OPEN_IN_SETTINGS = 6; - } - - // The action the user took to interact with the app - optional Action action = 4; -} - -/** -* Log that the AppPermissionGroupsFragment has been interacted with for the possible purposes of -* auto revoke, or that the auto revoke switch has been changed -* Logged from ui/handheld/AppPermissionGroupsFragment - */ -message AppPermissionGroupsFragmentAutoRevokeAction { - // id which identifies single session of user interacting with permission controller - optional int64 session_id = 1; - - // UID of package for which permissions are viewed - optional int32 uid = 2 [(is_uid) = true]; - - // Name of package for which permissions are viewed - optional string package_name = 3; - - enum Action { - UNDEFINED = 0; - OPENED_FOR_AUTO_REVOKE = 1; - OPENED_FROM_INTENT = 2; - SWITCH_ENABLED = 3; - SWITCH_DISABLED = 4; - } - - // The action the user took to interact with the fragment - optional Action action = 4; -} - -/** - * Logs when there is a smart selection related event. - * See frameworks/base/core/java/android/view/textclassifier/TextClassifierEvent.java - * Logged from: TextClassifierEventLogger.java - */ -message TextSelectionEvent { - // A session ID. - optional string session_id = 1; - - // Event type of this event. - optional android.stats.textclassifier.EventType event_type = 2; - - // Name of the annotator model that is involved in this event. - optional string model_name = 3; - - // Type of widget that was involved in triggering this event. - optional android.stats.textclassifier.WidgetType widget_type = 4; - - // Index of this event in a session. - optional int32 event_index = 5; - - // Entity type that is involved. - optional string entity_type = 6; - - // Relative word index of the start of the selection. - optional int32 relative_word_start_index = 7; - - // Relative word (exclusive) index of the end of the selection. - optional int32 relative_word_end_index = 8; - - // Relative word index of the start of the smart selection. - optional int32 relative_suggested_word_start_index = 9; - - // Relative word (exclusive) index of the end of the smart selection. - optional int32 relative_suggested_word_end_index = 10; - - // Name of source package. - optional string package_name = 11; - - // Name of the LangID model that is involved in this event. - optional string langid_model_name = 12; -} - -/** - * Logs when there is a smart linkify related event. - * See frameworks/base/core/java/android/view/textclassifier/TextClassifierEvent.java - * Logged from: TextClassifierEventLogger.java - */ -message TextLinkifyEvent { - // A session ID. - optional string session_id = 1; - - // Event type of this event. - optional android.stats.textclassifier.EventType event_type = 2; - - // Name of the annotator model that is involved in this event. - optional string model_name = 3; - - // Type of widget that was involved in triggering this event. - optional android.stats.textclassifier.WidgetType widget_type = 4; - - // Index of this event in a session. - optional int32 event_index = 5; - - // Entity type that is involved. - optional string entity_type = 6; - - // Number of links detected. - optional int32 num_links = 7; - - // The total length of all links. - optional int32 linked_text_length = 8; - - // Length of input text. - optional int32 text_length = 9; - - // Time spent on generating links in ms. - optional int64 latency_millis = 10; - - // Name of source package. - optional string package_name = 11; - - // Name of the LangID model that is involved in this event. - optional string langid_model_name = 12; -} - -/** - * Logs when there is a conversation actions related event. - * See frameworks/base/core/java/android/view/textclassifier/TextClassifierEvent.java - * Logged from: TextClassifierEventLogger.java - */ -message ConversationActionsEvent { - // A session ID. - optional string session_id = 1; - - // Event type of this event. - optional android.stats.textclassifier.EventType event_type = 2; - - // Name of the actions model that is involved in this event. - optional string model_name = 3; - - // Type of widget that was involved in triggering this event. - optional android.stats.textclassifier.WidgetType widget_type = 4; - - // The first entity type that is involved. - optional string first_entity_type = 5; - - // The second entity type that is involved. - optional string second_entity_type = 6; - - // The third entity type that is involved. - optional string third_entity_type = 7; - - // The score of the first entity type. - optional float score = 8; - - // Name of source package. - optional string package_name = 9; - - // Name of the annotator model that is involved in this event. - optional string annotator_model_name = 10; - - // Name of the LangID model that is involved in this event. - optional string langid_model_name = 11; -} - -/** - * Logs when there is a language detection related event. - * See frameworks/base/core/java/android/view/textclassifier/TextClassifierEvent.java - * Logged from: TextClassifierEventLogger.java - */ -message LanguageDetectionEvent { - // A session ID. - optional string session_id = 1; - - // Event type of this event. - optional android.stats.textclassifier.EventType event_type = 2; - - // Name of the language detection model that is involved in this event. - optional string model_name = 3; - - // Type of widget that was involved in triggering this event. - optional android.stats.textclassifier.WidgetType widget_type = 4; - - // Detected language. - optional string language_tag = 5; - - // Score of the detected language. - optional float score = 6; - - // Position of this action. - optional int32 action_index = 7; - - // Name of source package. - optional string package_name = 8; -} - -/** - * Information about an OTA update attempt by update_engine. - * Logged from platform/system/update_engine/metrics_reporter_android.cc - */ -message UpdateEngineUpdateAttemptReported { - // The number of attempts for the update engine to apply a given payload. - optional int32 attempt_number = 1; - - optional android.stats.otaupdate.PayloadType payload_type = 2; - - // The total time in minutes for the update engine to apply a given payload. - // The time is calculated by calling clock_gettime() / CLOCK_BOOTTIME; and - // it's increased when the system is sleeping. - optional int32 duration_boottime_in_minutes = 3; - - // The total time in minutes for the update engine to apply a given payload. - // The time is calculated by calling clock_gettime() / CLOCK_MONOTONIC_RAW; - // and it's not increased when the system is sleeping. - optional int32 duration_monotonic_in_minutes = 4; - - // The size of the payload in MiBs. - optional int32 payload_size_mib = 5; - - // The attempt result reported by the update engine for an OTA update. - optional android.stats.otaupdate.AttemptResult attempt_result = 6; - - // The error code reported by the update engine after an OTA update attempt - // on A/B devices. - optional android.stats.otaupdate.ErrorCode error_code = 7; - - // The build fingerprint of the source system. The value is read from a - // system property when the device takes the update. e.g. - // Android/aosp_sailfish/sailfish:10/QP1A.190425.004/5507117:userdebug/test-keys - optional string source_fingerprint = 8; - - // Size of super partition. - optional int64 super_partition_size_bytes = 9; - - // Size of current slot within the super partition. - optional int64 slot_size_bytes = 10; - - // Free space available in the super partition. - optional int64 super_free_space_bytes = 11; -} - -/** - * Information about all the attempts the device make before finishing the - * successful update. - * Logged from platform/system/update_engine/metrics_reporter_android.cc - */ -message UpdateEngineSuccessfulUpdateReported { - // The number of attempts for the update engine to apply the payload for a - // successful update. - optional int32 attempt_count = 1; - - optional android.stats.otaupdate.PayloadType payload_type = 2; - - optional int32 payload_size_mib = 3; - - // The total number of bytes downloaded by update_engine since the last - // successful update. - optional int32 total_bytes_downloaded_mib = 4; - - // The ratio in percentage of the over-downloaded bytes compared to the - // total bytes needed to successfully install the update. e.g. 200 if we - // download 200MiB in total for a 100MiB package. - optional int32 download_overhead_percentage = 5; - - // The total time in minutes for the update engine to apply the payload for a - // successful update. - optional int32 total_duration_minutes = 6; - - // The number of reboot of the device during a successful update. - optional int32 reboot_count = 7; -} - -/** - * Reported when the RebootEscrow HAL has attempted to recover the escrowed - * key to indicate whether it was successful or not. - * - * Logged from: - * frameworks/base/services/core/java/com/android/server/locksettings/RebootEscrowManager.java - */ -message RebootEscrowRecoveryReported { - optional bool successful = 1; -} - -/** - * Global display pipeline metrics reported by SurfaceFlinger. - * Metrics exist beginning in Android 11. - * Pulled from: - * frameworks/native/services/surfaceflinger/TimeStats/TimeStats.cpp - */ -message SurfaceflingerStatsGlobalInfo { - // Total number of frames presented during the tracing period - optional int64 total_frames = 1; - // Total number of frames missed - optional int64 missed_frames = 2; - // Total number of frames that fell back to client composition - optional int64 client_composition_frames = 3; - // Total time the display was turned on - optional int64 display_on_millis = 4; - // Total time that was spent performing animations. - // This is derived from the present-to-present layer histogram - optional int64 animation_millis = 5; - // Total number of event connections tracked by SurfaceFlinger at the time - // of this pull. If this number grows prohibitively large, then this can - // cause jank due to resource contention. - optional int32 event_connection_count = 6; - // Set of timings measured from when SurfaceFlinger began compositing a - // frame, until the frame was requested to be presented to the display. This - // measures SurfaceFlinger's total CPU walltime on the critical path per - // frame. - optional FrameTimingHistogram frame_duration = 7 - [(android.os.statsd.log_mode) = MODE_BYTES]; - // Set of timings measured from when SurfaceFlinger first began using the - // GPU to composite a frame, until the GPU has finished compositing that - // frame. This measures the total additional time SurfaceFlinger needed to - // perform due to falling back into GPU composition. - optional FrameTimingHistogram render_engine_timing = 8 - [(android.os.statsd.log_mode) = MODE_BYTES]; - // Number of frames where SF saw a frame, based on its frame timeline. - // Frame timelines may include transactions without updating buffer contents. - // Introduced in Android 12. - optional int32 total_timeline_frames = 9; - // Number of frames where SF saw a janky frame. - // Introduced in Android 12. - optional int32 total_janky_frames = 10; - // Number of janky frames where SF spent a long time on the CPU. - // Introduced in Android 12. - optional int32 total_janky_frames_with_long_cpu = 11; - // Number of janky frames where SF spent a long time on the GPU. - // Introduced in Android 12. - optional int32 total_janky_frames_with_long_gpu = 12; - // Number of janky frames where SF missed the frame deadline, but there - // was not an attributed reason (e.g., maybe HWC missed?) - // Introduced in Android 12. - optional int32 total_janky_frames_sf_unattributed = 13; - // Number of janky frames where the app missed the frame deadline, but - // there was not an attributed reason - // Introduced in Android 12. - optional int32 total_janky_frames_app_unattributed = 14; - - // Next ID: 15 -} - -/** - * Per-layer display pipeline metrics reported by SurfaceFlinger. - * Metrics exist beginning in Android 11. - * The number of layers uploaded may be restricted due to size limitations. - * Pulled from: - * frameworks/native/services/surfaceflinger/TimeStats/TimeStats.cpp - */ -message SurfaceflingerStatsLayerInfo { - // UID of the application who submitted this layer for presentation - // This is intended to be used as a dimension for surfacing rendering - // statistics to applications. - // Introduced in Android 12. - optional int32 uid = 12 [(is_uid) = true]; - // The layer for this set of metrics - // In many scenarios the package name is included in the layer name, e.g., - // layers created by Window Manager. But this is not a guarantee - in the - // general case layer names are arbitrary debug names. - optional string layer_name = 1; - // Total number of frames presented - optional int64 total_frames = 2; - // Total number of dropped frames while latching a buffer for this layer. - optional int64 dropped_frames = 3; - // Set of timings measured between successive presentation timestamps. - optional FrameTimingHistogram present_to_present = 4 - [(android.os.statsd.log_mode) = MODE_BYTES]; - // Set of timings measured from when an app queued a buffer for - // presentation, until the buffer was actually presented to the - // display. - optional FrameTimingHistogram post_to_present = 5 - [(android.os.statsd.log_mode) = MODE_BYTES]; - // Set of timings measured from when a buffer is ready to be presented, - // until the buffer was actually presented to the display. - optional FrameTimingHistogram acquire_to_present = 6 - [(android.os.statsd.log_mode) = MODE_BYTES]; - // Set of timings measured from when a buffer was latched by - // SurfaceFlinger, until the buffer was presented to the display - optional FrameTimingHistogram latch_to_present = 7 - [(android.os.statsd.log_mode) = MODE_BYTES]; - // Set of timings measured from the desired presentation to the actual - // presentation time - optional FrameTimingHistogram desired_to_present = 8 - [(android.os.statsd.log_mode) = MODE_BYTES]; - // Set of timings measured from when an app queued a buffer for - // presentation, until the buffer was ready to be presented. - optional FrameTimingHistogram post_to_acquire = 9 - [(android.os.statsd.log_mode) = MODE_BYTES]; - // Frames missed latch because the acquire fence didn't fire - optional int64 late_acquire_frames = 10; - // Frames latched early because the desired present time was bad - optional int64 bad_desired_present_frames = 11; - // Number of frames where SF saw a frame, based on its frame timeline. - // Frame timelines may include transactions without updating buffer contents. - // Introduced in Android 12. - optional int32 total_timeline_frames = 13; - // Number of frames where SF saw a janky frame. - // Introduced in Android 12. - optional int32 total_janky_frames = 14; - // Number of janky frames where SF spent a long time on the CPU. - // Introduced in Android 12. - optional int32 total_janky_frames_with_long_cpu = 15; - // Number of janky frames where SF spent a long time on the GPU. - // Introduced in Android 12. - optional int32 total_janky_frames_with_long_gpu = 16; - // Number of janky frames where SF missed the frame deadline, but there - // was not an attributed reason (e.g., maybe HWC missed?) - // Introduced in Android 12. - optional int32 total_janky_frames_sf_unattributed = 17; - // Number of janky frames where the app missed the frame deadline, but - // there was not an attributed reason - // Introduced in Android 12. - optional int32 total_janky_frames_app_unattributed = 18; - - // Next ID: 19 -} - -/** - * Histogram of frame counts bucketed by time in milliseconds. - * Because of size limitations, we hard-cap the number of buckets, with - * buckets for corresponding to larger milliseconds being less precise. - */ -message FrameTimingHistogram { - // Timings in milliseconds that describes a set of histogram buckets - repeated int32 time_millis_buckets = 1; - // Number of frames that match to each time_millis, i.e. the bucket - // contents - // It's required that len(time_millis) == len(frame_count) - repeated int64 frame_counts = 2; -} - -/** - * Janky event as reported by SurfaceFlinger. - * This event is intended to be consumed by a Perfetto subscriber for - * automated trace collection. - * - * Logged from: - * frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp - */ -message DisplayJankReported { - // Informational field for how long the janky event lasted in milliseconds - optional int64 event_duration_millis = 1; - // Number of frame deadlines missed, where SurfaceFlinger failed to update - // the display on time. - optional int32 present_deadlines_missed = 2; -} - -/** - * Information about camera facing and API level usage. - * Logged from: - * frameworks/base/services/core/java/com/android/server/camera/CameraServiceProxy.java - */ -message CameraActionEvent { - // Camera session duration in milliseconds if action is SESSION. - // 0 if action is OPEN or CLOSE. - optional int64 duration_millis = 1; - - // Camera API level used. - // 1 for camera1 API, and 2 for camera2 API. - optional int32 api_level = 2; - - // Name of client package - optional string package_name = 3; - - // Camera facing - enum Facing { - UNKNOWN = 0; - BACK = 1; - FRONT = 2; - EXTERNAL = 3; - } - optional Facing facing = 4; - - // Camera ID - optional string camera_id = 5; - - // Camera action type - enum Action { - UNKNOWN_ACTION = 0; - OPEN = 1; - CLOSE = 2; - SESSION = 3; - } - optional Action action = 6; - - // Whether the client is accessing camera using ndk - optional bool is_ndk = 7; - - // Action OPEN: Open latency - // Action CLOSE: Close latency - // Action SESSION: Camera session creation duration. - // If this entry is reusing an existing session, the value is -1. - optional int32 latency_millis = 8; - - // session type: 0 for normal mode, 1 for constrained high speed mode - optional int32 operating_mode = 9; - - // If actioh is SESSION: number of internal reconfigurations - // Else: 0 - optional int32 internal_reconfig = 10; - - // Number of requests for this capture session. Only applicable to SESSION - // action. - optional int64 request_count = 11; - // Number of result errors. Only applicable to SESSION action. - optional int64 result_error_count = 12; - // Whether the device runs into error state. - optional bool device_error = 13; - - // If action is SESSION: Stream states - // Else: stream_count = 0 - optional int32 stream_count = 14; - optional android.stats.camera.CameraStreamProto stream_1 = 15 - [(android.os.statsd.log_mode) = MODE_BYTES]; - optional android.stats.camera.CameraStreamProto stream_2 = 16 - [(android.os.statsd.log_mode) = MODE_BYTES]; - optional android.stats.camera.CameraStreamProto stream_3 = 17 - [(android.os.statsd.log_mode) = MODE_BYTES]; - optional android.stats.camera.CameraStreamProto stream_4 = 18 - [(android.os.statsd.log_mode) = MODE_BYTES]; - optional android.stats.camera.CameraStreamProto stream_5 = 19 - [(android.os.statsd.log_mode) = MODE_BYTES]; -} - -/** - * Logs when a compatibility change is affecting an app. - * - * Logged from: - * frameworks/base/core/java/android/app/AppCompatCallbacks.java and - * frameworks/base/services/core/java/com/android/server/compat/PlatformCompat.java - */ -message AppCompatibilityChangeReported { - // The UID of the app being affected by the compatibilty change. - optional int32 uid = 1 [(is_uid) = true]; - - // The ID of the change affecting the app. - optional int64 change_id = 2; - - enum State { - UNKNOWN_STATE = 0; - ENABLED = 1; - DISABLED = 2; - LOGGED = 3; - } - - // The state of the change - if logged from gating whether it was enabled or disabled, or just - // logged otherwise. - optional State state = 3; - - enum Source { - UNKNOWN_SOURCE = 0; - APP_PROCESS = 1; - SYSTEM_SERVER = 2; - } - - // Where it was logged from. - optional Source source = 4; - -} - -/** - * Logged from - * external/perfetto/src/perfetto_cmd/perfetto_cmd.cc - */ -message PerfettoUploaded { - enum Event { - PERFETTO_UNDEFINED = 0; - PERFETTO_TRACE_BEGIN = 1; - PERFETTO_BACKGROUND_TRACE_BEGIN = 2; - PERFETTO_ON_CONNECT = 3; - PERFETTO_ON_TRACING_DISABLED = 4; - PERFETTO_UPLOAD_DROPBOX_BEGIN = 5; - PERFETTO_UPLOAD_DROPBOX_SUCCESS = 6; - PERFETTO_UPLOAD_DROPBOX_FAILURE = 7; - PERFETTO_UPLOAD_INCIDENT_BEGIN = 8; - PERFETTO_UPLOAD_INCIDENT_SUCCESS = 9; - PERFETTO_UPLOAD_INCIDENT_FAILURE = 10; - PERFETTO_FINALIZE_TRACE_AND_EXIT = 11; - PERFETTO_TRIGGER_BEGIN = 12; - PERFETTO_TRIGGER_SUCCESS = 13; - PERFETTO_TRIGGER_FAILURE = 14; - PERFETTO_HIT_GUARDRAILS = 15; - PERFETTO_ON_TIMEOUT = 16; - PERFETTO_NOT_UPLOADING_EMPTY_TRACE = 17; - } - - // Which stage of the pipeline we are reporting from. - optional Event event = 1; - - // UUID matching the one set inside the SystemInfo trace packet. - optional int64 trace_uuid_lsb = 2; - optional int64 trace_uuid_msb = 3; -} - -/** - * Pulls client metrics on data transferred via Vehicle Maps Service. - * Metrics are keyed by uid + layer. - * - * Pulled from: - * packages/services/Car/service/src/com/android/car/stats/CarStatsService.java - */ -message VmsClientStats { - // UID of the VMS client app - optional int32 uid = 1 [(is_uid) = true]; - - // VMS layer definition - optional int32 layer_type = 2; - optional int32 layer_channel = 3; - optional int32 layer_version = 4; - - // Bytes and packets sent by the client for the layer - optional int64 tx_bytes = 5; - optional int64 tx_packets = 6; - - // Bytes and packets received by the client for the layer - optional int64 rx_bytes = 7; - optional int64 rx_packets = 8; - - // Bytes and packets dropped due to client error - optional int64 dropped_bytes = 9; - optional int64 dropped_packets = 10; -} - -/** - * State of a dangerous permission requested by a package - sampled - * Pulled from: StatsCompanionService.java with data obtained from PackageManager API -*/ -message DangerousPermissionStateSampled { - // Name of the permission - optional string permission_name = 1; - - // Uid of the package - optional int32 uid = 2 [(is_uid) = true]; - - // If the permission is granted to the uid - optional bool is_granted = 3; - - // Permission flags as per android.content.pm.PermissionFlags - optional int32 permission_flags = 4; -} - -/** - * HWUI stats for a given app. - */ -message GraphicsStats { - // The package name of the app - optional string package_name = 1; - - // The version code of the app - optional int64 version_code = 2; - - // The start & end timestamps in UTC as - // milliseconds since January 1, 1970 - // Compatible with java.util.Date#setTime() - optional int64 start_millis = 3; - - optional int64 end_millis = 4; - - // HWUI renders pipeline type: GL (1) or Vulkan (2). - enum PipelineType { - UNKNOWN = 0; - GL = 1; - VULKAN = 2; - } - - // HWUI renders pipeline type: GL or Vulkan. - optional PipelineType pipeline = 5; - - // Distinct frame count. - optional int32 total_frames = 6; - - // Number of "missed vsync" events. - optional int32 missed_vsync_count = 7; - - // Number of frames in triple-buffering scenario (high input latency) - optional int32 high_input_latency_count = 8; - - // Number of "slow UI thread" events. - optional int32 slow_ui_thread_count = 9; - - // Number of "slow bitmap upload" events. - optional int32 slow_bitmap_upload_count = 10; - - // Number of "slow draw" events. - optional int32 slow_draw_count = 11; - - // Number of frames that missed their deadline (aka, visibly janked) - optional int32 missed_deadline_count = 12; - - // The frame time histogram for the package - optional FrameTimingHistogram cpu_histogram = 13 - [(android.os.statsd.log_mode) = MODE_BYTES]; - - // The gpu frame time histogram for the package - optional FrameTimingHistogram gpu_histogram = 14 - [(android.os.statsd.log_mode) = MODE_BYTES]; - - // UI mainline module version. - optional int64 version_ui_module = 15; - - // If true, these are HWUI stats for up to a 24h period for a given app from today. - // If false, these are HWUI stats for a 24h period for a given app from the last complete - // day (yesterday). Stats from yesterday stay constant, while stats from today may change as - // more apps are running / rendering. - optional bool is_today = 16; -} - -/** - * Message related to dangerous (runtime) app ops access - */ -message RuntimeAppOpAccess { - // Uid of the package accessing app op - optional int32 uid = 1 [(is_uid) = true]; - - // Name of the package accessing app op - optional string package_name = 2; - - // deprecated - set to empty string - optional string op_deprecated = 3 [deprecated = true]; - - // attribution_tag; provided by developer when accessing related API, limited at 50 chars by - // API. Attributions must be provided through manifest using <attribution> tag available in R - // and above. - optional string attribution_tag = 4; - - // message related to app op access, limited to 600 chars by API - optional string message = 5; - - enum SamplingStrategy { - DEFAULT = 0; - UNIFORM = 1; - RARELY_USED = 2; - BOOT_TIME_SAMPLING = 3; - UNIFORM_OPS = 4; - } - - // sampling strategy used to collect this message - optional SamplingStrategy sampling_strategy = 6; - - // operation id - optional android.app.AppOpEnum op = 7 [default = APP_OP_NONE]; -} - -/* - * Logs userspace reboot outcome and duration. - * - * Logged from: - * frameworks/base/core/java/com/android/server/BootReceiver.java - */ -message UserspaceRebootReported { - // Possible outcomes of userspace reboot. - enum Outcome { - // Default value in case platform failed to determine the outcome. - OUTCOME_UNKNOWN = 0; - // Userspace reboot succeeded (i.e. boot completed without a fall back to hard reboot). - SUCCESS = 1; - // Userspace reboot shutdown sequence was aborted. - FAILED_SHUTDOWN_SEQUENCE_ABORTED = 2; - // Remounting userdata into checkpointing mode failed. - FAILED_USERDATA_REMOUNT = 3; - // Device didn't finish booting before timeout and userspace reboot watchdog issued a hard - // reboot. - FAILED_USERSPACE_REBOOT_WATCHDOG_TRIGGERED = 4; - } - // Outcome of userspace reboot. Always set. - optional Outcome outcome = 1; - // Duration of userspace reboot in case it has a successful outcome. - // Duration is measured as time between userspace reboot was initiated and until boot completed - // (e.g. sys.boot_completed=1). - optional int64 duration_millis = 2; - // State of primary user's (user0) credential encryption storage. - enum UserEncryptionState { - // Default value. - USER_ENCRYPTION_STATE_UNKNOWN = 0; - // Credential encrypted storage is unlocked. - UNLOCKED = 1; - // Credential encrypted storage is locked. - LOCKED = 2; - } - // State of primary user's encryption storage at the moment boot completed. Always set. - optional UserEncryptionState user_encryption_state = 3; -} - -/* - * Logs integrity check information during each install. - * - * Logged from: - * frameworks/base/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java - */ -message IntegrityCheckResultReported { - optional string package_name = 1; - optional string app_certificate_hash = 2; - optional int64 version_code = 3; - optional string installer_package_name = 4; - enum Response { - UNKNOWN = 0; - ALLOWED = 1; - REJECTED = 2; - FORCE_ALLOWED = 3; - } - optional Response response = 5; - // An estimate on the cause of the response. This will only be populated for - // REJECTED and FORCE_ALLOWED - optional bool caused_by_app_cert_rule = 6; - optional bool caused_by_installer_rule = 7; -} - -/** - * Logs the information about the rules and the provider whenever rules are - * pushed into AppIntegrityManager. - * - * Logged from: - * frameworks/base/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java - */ -message IntegrityRulesPushed { - optional bool success = 1; - // Package name of the app that pushed the rules. - optional string rule_provider = 2; - // Version string of arbitrary format provided by the rule provider to - // identify the rules. - optional string rule_version = 3; -} - -/** - * Logs when a cell broadcast message is received on the device. - * - * Logged from Cell Broadcast module and platform: - * packages/modules/CellBroadcastService/src/com/android/cellbroadcastservice/ - * packages/apps/CellBroadcastReceiver/ - * frameworks/opt/telephony/src/java/com/android/internal/telephony/CellBroadcastServiceManager.java - */ -message CellBroadcastMessageReported { - // The type of Cell Broadcast message - enum CbType { - UNKNOWN_TYPE = 0; - GSM = 1; - CDMA = 2; - CDMA_SPC = 3; - } - - // The parts of the cell broadcast message pipeline - enum ReportSource { - UNKNOWN_SOURCE = 0; - FRAMEWORK = 1; - CB_SERVICE = 2; - CB_RECEIVER_APP = 3; - } - - // GSM, CDMA, CDMA-SCP - optional CbType type = 1; - - // The source of the report - optional ReportSource source = 2; -} - -/** - * Logs when a cell broadcast message is filtered out, or otherwise intentionally not sent to CBR. - * - * Logged from CellBroadcastService module: - * packages/modules/CellBroadcastService/src/com/android/cellbroadcastservice/ - */ -message CellBroadcastMessageFiltered { - enum FilterReason { - NOT_FILTERED = 0; - DUPLICATE_MESSAGE = 1; - GEOFENCED_MESSAGE = 2; - AREA_INFO_MESSAGE = 3; - } - - // GSM, CDMA, CDMA-SCP - optional CellBroadcastMessageReported.CbType type = 1; - - // The source of the report - optional FilterReason filter = 2; -} - -/** - * Logs when an error occurs while handling a cell broadcast message; - * - * Logged from CellBroadcastService module: - * packages/modules/CellBroadcastService/src/com/android/cellbroadcastservice/ - */ -message CellBroadcastMessageError { - // The type of error raised when trying to handle a cell broadcast message - enum ErrorType { - UNKNOWN_TYPE = 0; - CDMA_DECODING_ERROR = 1; - CDMA_SCP_EMPTY = 2; - CDMA_SCP_HANDLING_ERROR = 3; - GSM_INVALID_HEADER_LENGTH = 4; - GSM_UNSUPPORTED_HEADER_MESSAGE_TYPE = 5; - GSM_UNSUPPORTED_HEADER_DATA_CODING_SCHEME = 6; - GSM_INVALID_PDU = 7; - GSM_INVALID_GEO_FENCING_DATA = 8; - GSM_UMTS_INVALID_WAC = 9; - FAILED_TO_INSERT_TO_DB = 10; - UNEXPECTED_GEOMETRY_FROM_FWK = 11; - UNEXPECTED_GSM_MESSAGE_TYPE_FROM_FWK = 12; - UNEXPECTED_CDMA_MESSAGE_TYPE_FROM_FWK = 13; - UNEXPECTED_CDMA_SCP_MESSAGE_TYPE_FROM_FWK = 14; - NO_CONNECTION_TO_CB_SERVICE = 15; - } - - // What kind of error occurred - optional ErrorType type = 1; - - // Exception message (or log message) associated with the error (max 1000 chars) - optional string exception_message = 2; -} - -/** - * Logs when a TV Input Service Session changes tune state - * This is atom ID 327. - * - * Logged from: - * frameworks/base/services/core/java/com/android/server/tv/TvInputManagerService.java - */ -message TifTuneStateChanged { - - // Tv Input Service uid, TV Player uid - repeated AttributionNode attribution_node = 1 [ - (state_field_option).primary_field_first_uid = true - ]; - optional android.stats.tv.TifTuneState state = 2 [ - (state_field_option).exclusive_state = true, - (state_field_option).default_state_value = 0, - (state_field_option).nested = false - ]; - // This a globally unique 128 bit random number created by TvInputManagerService when - // android.media.tv.TvInputManager#createSession is called. - // It is has no device or user association. - // See android.media.tv.TvInputService.onCreateSession(java.lang.String, java.lang.String) - // WARNING: Any changes to this field should be carefully reviewed for privacy. - // Inspect the code at - // framework/base/cmds/statsd/src/atoms.proto - // TifTuneState - // frameworks/base/services/core/java/com/android/server/tv/TvInputManagerService.java - // logTuneStateChanged - // BinderService.createSession - // SessionState.sessionId - optional string tif_session_id = 3 [(state_field_option).primary_field = true]; -} - -/** - * Logs when a tune occurs through device's Frontend. - * This is atom ID 276. - * - * Logged from: - * frameworks/base/media/java/android/media/tv/tuner/Tuner.java - */ -message TvTunerStateChanged { - enum State { - UNKNOWN = 0; - TUNING = 1; // Signal is tuned - LOCKED = 2; // the signal is locked - NOT_LOCKED = 3; // the signal isn’t locked. - SIGNAL_LOST = 4; // the signal was locked, but is lost now. - SCANNING = 5; // the signal is scanned - SCAN_STOPPED = 6; // the scan is stopped. - } - // The uid of the application that sent this custom atom. - optional int32 uid = 1 [(is_uid) = true]; - // new state - optional State state = 2; -} - -/** - * Logs the status of a dvr playback or record. - * This is atom ID 279. - * - * Logged from: - * frameworks/base/media/java/android/media/tv/tuner/dvr - */ -message TvTunerDvrStatus { - enum Type { - UNKNOWN_TYPE = 0; - PLAYBACK = 1; // is a playback - RECORD = 2; // is a record - } - enum State { - UNKNOWN_STATE = 0; - STARTED = 1; // DVR is started - STOPPED = 2; // DVR is stopped - } - // The uid of the application that sent this custom atom. - optional int32 uid = 1 [(is_uid) = true]; - // DVR type - optional Type type = 2; - // DVR state - optional State state = 3; - // Identify the segment of a record or playback - optional int32 segment_id = 4; - // indicate how many overflow or underflow happened between started to stopped - optional int32 overflow_underflow_count = 5; -} - -/** - * Logs when a cas session opened through MediaCas. - * This is atom ID 280. - * - * Logged from: - * frameworks/base/media/java/android/media/MediaCas.java - */ -message TvCasSessionOpenStatus { - enum State { - UNKNOWN = 0; - SUCCEEDED = 1; // indicate that the session is opened successfully. - FAILED = 2; // indicate that the session isn’t opened successfully. - } - // The uid of the application that sent this custom atom. - optional int32 uid = 1 [(is_uid) = true]; - // Cas system Id - optional int32 cas_system_id = 2; - // State of the session - optional State state = 3; -} - -/** - * Logs for ContactsProvider general usage. - * This is atom ID 301. - * - * Logged from: - * packages/providers/ContactsProvider/src/com/android/providers/contacts/ContactsProvider2.java - */ -message ContactsProviderStatusReported { - enum ApiType { - UNKNOWN_API = 0; - QUERY = 1; - // INSERT includes insert and bulkInsert, and inserts triggered by applyBatch. - INSERT = 2; - // UPDATE and DELETE includes update/delete and the ones triggered by applyBatch. - UPDATE = 3; - DELETE = 4; - } - - enum ResultType { - UNKNOWN_RESULT = 0; - SUCCESS = 1; - FAIL = 2; - ILLEGAL_ARGUMENT = 3; - UNSUPPORTED_OPERATION = 4; - } - - enum CallerType { - UNSPECIFIED_CALLER_TYPE = 0; - CALLER_IS_SYNC_ADAPTER = 1; - CALLER_IS_NOT_SYNC_ADAPTER = 2; - } - - optional ApiType api_type = 1; - // Defined in - // packages/providers/ContactsProvider/src/com/android/providers/contacts/ContactsProvider2.java - optional int32 uri_type = 2; - optional CallerType caller_type = 3; - optional ResultType result_type = 4; - optional int32 result_count = 5; - optional int64 latency_micros = 6; -} - -/** - * Logs when an app is frozen or unfrozen. - * - * Logged from: - * frameworks/base/services/core/java/com/android/server/am/CachedAppOptimizer.java - */ -message AppFreezeChanged { - // The type of event. - enum Action { - UNKNOWN = 0; - FREEZE_APP = 1; - UNFREEZE_APP = 2; - } - optional Action action = 1; - - // Pid of the process being frozen. - optional int32 pid = 2; - - // Name of the process being frozen. - optional string process_name = 3; - - // Time since last unfrozen. - optional int64 time_unfrozen_millis = 4; -} - -/** - * Pulls information for a single voice call. - * - * Each pull creates multiple atoms, one for each call. The sequence is randomized when pulled. - * - * Pulled from: - * frameworks/opt/telephony/src/java/com/android/internal/telephony/metrics/MetricsCollector.java - */ -message VoiceCallSession { - // Bearer (IMS or CS) when the call started. - optional android.telephony.CallBearerEnum bearer_at_start = 1; - - // Bearer (IMS or CS) when the call ended. - // The bearer may change during the call, e.g. due to SRVCC. - optional android.telephony.CallBearerEnum bearer_at_end = 2; - - // Direction of the call (incoming or outgoing). - optional android.telephony.CallDirectionEnum direction = 3; - - // Time spent setting up the call. - optional android.telephony.CallSetupDurationEnum setup_duration = 4; - - // Whether the call ended before the setup was completed. - optional bool setup_failed = 5; - - // IMS reason code or CS disconnect cause. - // For IMS, see: frameworks/base/telephony/java/android/telephony/ims/ImsReasonInfo.java - // For CS, see: frameworks/base/telephony/java/android/telephony/DisconnectCause.java - optional int32 disconnect_reason_code = 6; - - // IMS extra code or CS precise disconnect cause. - // For IMS, this code is vendor-specific - // For CS, see: frameworks/base/telephony/java/android/telephony/PreciseDisconnectCause.java - optional int32 disconnect_extra_code = 7; - - // IMS extra message or CS vendor cause. - optional string disconnect_extra_message = 8; - - // Radio access technology (RAT) used when call started. - optional android.telephony.NetworkTypeEnum rat_at_start = 9; - - // Radio access technology (RAT) used when call terminated. - optional android.telephony.NetworkTypeEnum rat_at_end = 10; - - // Number of times RAT changed during the call. - optional int64 rat_switch_count = 11; - - // A bitmask of all codecs used during the call. - // See: frameworks/opt/telephony/src/java/com/android/internal/telephony/metrics/VoiceCallSessionStats.java - optional int64 codec_bitmask = 12; - - // Number of other calls going on during call setup, for the same SIM slot. - optional int32 concurrent_call_count_at_start = 13; - - // Number of other calls going on during call termination, for the same SIM slot. - optional int32 concurrent_call_count_at_end = 14; - - // Index of the SIM used, 0 for single-SIM devices. - optional int32 sim_slot_index = 15; - - // Whether the device was in multi-SIM mode (with multiple active SIM profiles). - optional bool is_multi_sim = 16; - - // Whether the call was made with an eSIM profile. - optional bool is_esim = 17; - - // Carrier ID of the SIM card. - // See https://source.android.com/devices/tech/config/carrierid. - optional int32 carrier_id = 18; - - // Whether an SRVCC has been completed successfully for this call. - optional bool srvcc_completed = 19; - - // Number of SRVCC failures. - optional int64 srvcc_failure_count = 20; - - // Number of SRVCC cancellations. - optional int64 srvcc_cancellation_count = 21; - - // Whether the Real-Time Text (RTT) was ever used in the call (rather than whether RTT was - // enabled in the dialer's settings). - optional bool rtt_enabled = 22; - - // Whether this was an emergency call. - optional bool is_emergency = 23; - - // Whether the call was performed while roaming. - optional bool is_roaming = 24; - - // A random number used as the dimension field to pull multiple atoms. - optional int32 dimension = 25; - - // Signal strength at the end of the call. This value is applicable to both cellular and WiFi. - optional android.telephony.SignalStrengthEnum signal_strength_at_end = 26; - - // Band at the end of the call. Value 0 is used if the band is unknown. - // See GeranBands, UtranBands and EutranBands in IRadio interface, depending on the RAT at - // the end of the call. - optional int32 band_at_end = 27; - - // Time spent setting up the call in milliseconds. - // The time is measured from dial to ringing for outgoing calls, and from answer to connected - // for incoming calls. - optional int32 setup_duration_millis = 28; - - // Main codec quality. The codec quality was equal to or greater than this value for at least - // 70% of the call. - optional android.telephony.CodecQuality main_codec_quality = 29; - - // Whether video was enabled at any point during the call. - optional bool video_enabled = 30; - - // Radio access technology (RAT) used when call is connected. - optional android.telephony.NetworkTypeEnum rat_at_connected = 31; - - // Whether the call was a conference call (applicable only for calls over IMS). - optional bool is_multiparty = 32; -} - -/** - * Pulls voice call radio access technology (RAT) usage. - * - * Each pull creates multiple atoms, one for each carrier/RAT, the order of which is irrelevant to - * time. The atom will be skipped if not enough data is available. - * - * Pulled from: - * frameworks/opt/telephony/src/java/com/android/internal/telephony/metrics/MetricsCollector.java - */ -message VoiceCallRatUsage { - // Carrier ID (https://source.android.com/devices/tech/config/carrierid). - optional int32 carrier_id = 1; - - // Radio access technology. - optional android.telephony.NetworkTypeEnum rat = 2; - - // Total duration that voice calls spent on this carrier and RAT, rounded to 5 minute. - optional int64 total_duration_seconds = 3; - - // Total number of calls using this carrier and RAT. - // A call is counted once even if it used the RAT multiple times. - optional int64 call_count = 4; -} - -/** - * Pulls amount of time spend in each cellular service state. - * - * Each pull creates multiple atoms, one for each SIM slot/carrier/RAT(including ENDC), the order of - * which is irrelevant to time. If multi SIM settings changes during the period, durations will be - * counted separately before and after the change. Airplane mode does not count towards durations. - * - * Pulled from: - * frameworks/opt/telephony/src/java/com/android/internal/telephony/metrics/MetricsCollector.java - */ -message CellularServiceState { - // Radio access technology (RAT) for voice. - // NETWORK_TYPE_UNKNOWN when the device is out of service. - // NETWORK_TYPE_IWLAN when the device is using VoWiFi. - optional android.telephony.NetworkTypeEnum voice_rat = 1; - - // Radio access technology (RAT) for data. - // NETWORK_TYPE_UNKNOWN when the device is out of service. - // Only cellular RATs are valid and show where the device is camped. - optional android.telephony.NetworkTypeEnum data_rat = 2; - - // Whether the device was in roaming (domestic or international) for voice. - optional android.telephony.RoamingTypeEnum voice_roaming_type = 3; - - // Whether the device was in roaming (domestic or international) for data. - optional android.telephony.RoamingTypeEnum data_roaming_type = 4; - - // Whether the device is on LTE and has access to NR NSA, i.e. cell supports 5G (ENDC) and UE - // registration (attach/TAU) indicates ENDC is not restricted. - optional bool is_endc = 5; - - // Index of the SIM used, 0 for single-SIM devices. - optional int32 sim_slot_index = 6; - - // Whether the device was in multi-SIM mode (with multiple active SIM profiles). - optional bool is_multi_sim = 7; - - // Carrier ID of the SIM card. - // See https://source.android.com/devices/tech/config/carrierid. - optional int32 carrier_id = 8; - - // Total time spent in this service state, rounded to 5 minutes. - optional int32 total_time_seconds = 9; -} - -/** - * Pulls the number of times cellular data service state switches. - * - * Each pull creates multiple atoms, one for each RAT combination, the order of which is irrelevant - * to time. Switches for different SIM slots, carrier IDs, or multi-SIM settings are counted - * separately. - * - * Pulled from: - * frameworks/opt/telephony/src/java/com/android/internal/telephony/metrics/MetricsCollector.java - */ -message CellularDataServiceSwitch { - // Cellular RAT of the DATA domain from where the switch occurred. - optional android.telephony.NetworkTypeEnum rat_from = 1; - - // Cellular RAT of the DATA domain to where the switch occurred. - optional android.telephony.NetworkTypeEnum rat_to = 2; - - // Index of the SIM used, 0 for single-SIM devices. - optional int32 sim_slot_index = 3; - - // Whether the device was in multi-SIM mode (with multiple active SIM profiles). - optional bool is_multi_sim = 4; - - // Carrier ID of the SIM card. - // See https://source.android.com/devices/tech/config/carrierid. - optional int32 carrier_id = 5; - - // Number of switches from rat_from to rat_to. - optional int32 switch_count = 6; -} - -/** - * Pulls the number of active SIM slots and SIMs/eSIM profiles. - * - * Pulled from: - * frameworks/opt/telephony/src/java/com/android/internal/telephony/metrics/MetricsCollector.java - */ -message SimSlotState { - // Number of active SIM slots (both physical and eSIM profiles) in the device. - optional int32 active_slot_count = 1; - - // Number of SIM cards (both physical and active eSIM profiles). - // This number is always equal to or less than the number of active SIM slots. - optional int32 sim_count = 2; - - // Number of active eSIM profiles. - // This number is always equal to or less than the number of SIMs. - optional int32 esim_count = 3; -} - -/** - * Pulls supported cellular radio access technologies. - * - * This atom reports the capabilities of the device, rather than the network it has access to. - * - * Pulled from: - * frameworks/opt/telephony/src/java/com/android/internal/telephony/metrics/MetricsCollector.java - */ -message SupportedRadioAccessFamily { - // A bitmask of supported radio technologies. - // See android.telephony.TelephonyManager.NetworkTypeBitMask. - optional int64 network_type_bitmask = 1; -} - -/** - * Pulls information for a single incoming SMS. - * - * Each pull creates multiple atoms, one for each SMS. The sequence is randomized when pulled. - * - * Pulled from: - * frameworks/opt/telephony/src/java/com/android/internal/telephony/metrics/MetricsCollector.java - */ -message IncomingSms { - // Format of the SMS (3GPP or 3GPP2). - optional android.telephony.SmsFormatEnum sms_format = 1; - - // Technology of the SMS (CS or IMS). - optional android.telephony.SmsTechEnum sms_tech = 2; - - // Radio access technology (RAT) used for the SMS. It can be IWLAN in case of IMS. - optional android.telephony.NetworkTypeEnum rat = 3; - - // Type the SMS. - optional android.telephony.SmsTypeEnum sms_type = 4; - - // Number of total parts. - optional int32 total_parts = 5; - - // Number of received parts (if smaller than total parts, the SMS was dropped). - optional int32 received_parts = 6; - - // Indicates if the incoming SMS was blocked. - optional bool blocked = 7; - - // Indicate a specific error handling the SMS - optional android.telephony.SmsIncomingErrorEnum error = 8; - - // Whether the SMS was received while roaming. - optional bool is_roaming = 9; - - // Index of the SIM used, 0 for single-SIM devices. - optional int32 sim_slot_index = 10; - - // Whether the device was in multi-SIM mode (with multiple active SIM profiles). - optional bool is_multi_sim = 11; - - // Whether the message was received with an eSIM profile. - optional bool is_esim = 12; - - // Carrier ID of the SIM card used for the SMS. - // See https://source.android.com/devices/tech/config/carrierid. - optional int32 carrier_id = 13; - - // Random message ID. - optional int64 message_id = 14; -} - -/** - * Pulls information for a single outgoing SMS. - * - * Each pull creates multiple atoms, one for each SMS. The sequence is randomized when pulled. - * - * Pulled from: - * frameworks/opt/telephony/src/java/com/android/internal/telephony/metrics/MetricsCollector.java - */ -message OutgoingSms { - // Format of the SMS (3GPP or 3GPP2). - optional android.telephony.SmsFormatEnum sms_format = 1; - - // Technology of the SMS (CS or IMS). - optional android.telephony.SmsTechEnum sms_tech = 2; - - // Radio access technology (RAT) used for the SMS. It can be IWLAN in case of IMS. - optional android.telephony.NetworkTypeEnum rat = 3; - - // Result of the SMS sending. - optional android.telephony.SmsSendResultEnum send_result = 4; - - // Error code - // For IMS technology, see @SmsManager.Result in - // http://cs/android/frameworks/base/telephony/java/android/telephony/SmsManager.java - // For CS technology: - // - GSM format: see GsmSmsErrorCode (3GPP 27.005 clause 3.2.5) - // - CDMA format: see CdmaSmsErrorCode (3GPP2 N.S0005 (IS-41-C) Table 171) - optional int32 error_code = 5; - - // Whether the SMS was sent while roaming. - optional bool is_roaming = 6; - - // Whether the default SMS application generated the SMS (regardless of which application). - optional bool is_from_default_app = 7; - - // Index of the SIM used, 0 for single-SIM devices. - optional int32 sim_slot_index = 8; - - // Whether the device was in multi-SIM mode (with multiple active SIM profiles). - optional bool is_multi_sim = 9; - - // Whether the message was sent with an eSIM profile. - optional bool is_esim = 10; - - // Carrier ID of the SIM card used for the SMS. - // See https://source.android.com/devices/tech/config/carrierid. - optional int32 carrier_id = 11; - - // Random message ID. - optional int64 message_id = 12; - - // Retry count: 0 for the first attempt and then increasing for each attempt. - optional int32 retry_id = 13; -} - -/** - * Logs information about usage of airplane mode. - * - * Logged from: - * frameworks/opt/telephony/src/java/com/android/internal/telephony/metrics/AirplaneModeStats.java - */ -message AirplaneMode { - // Status of airplane mode - optional bool is_enabled = 1; - - // When is_enabled is false, indicates if this was a very short airplane mode toggle - // (i.e. airplane mode was disabled after less than 10 seconds from enablement). - optional bool short_toggle = 2; - - // Carrier ID of the SIM card. - // See https://source.android.com/devices/tech/config/carrierid. - optional int32 carrier_id = 3; -} - -/** - * Logs information about modem restarts. - * - * Logged from: - * frameworks/opt/telephony/src/java/com/android/internal/telephony/metrics/ModemRestartStats.java - */ -message ModemRestart { - // Software version of the modem, as provided by android.os.Build.getRadioVersion(). - optional string baseband_version = 1; - - // Reason of the modem restart, as provided in the modemReset indication of IRadio HAL. - optional string reason = 2; - - // Carrier ID of the first SIM card. - // See https://source.android.com/devices/tech/config/carrierid. - optional int32 carrier_id = 3; -} - -/** - * Logs the SIM card details when the carrier ID match is not complete. - * - * The atom is pushed when a SIM card is initialized and the MCC/MNC is not present in the - * carrier ID table, or the SIM card contains a GID1 value that is not present in the carrier ID - * table. This atom is pushed only once for each type of SIM card. - * - * Logged from: - * frameworks/opt/telephony/src/java/com/android/internal/telephony/metrics/CarrierIdMatchStats.java - */ -message CarrierIdMismatchReported { - // Matched carrier ID. The value -1 is used if no match is found. - optional int32 carrier_id = 1; - - // MCC/MNC of the SIM card. - optional string mcc_mnc = 2; - - // Group identifier (level 1) of the SIM card. - optional string gid1 = 3; - - // SPN value of the SIM card. - optional string spn = 4; - - // First record of the PNN in the SIM card. This field is populated only if the SPN is missing - // or empty. - optional string pnn = 5; -} - -/** - * Logs the version of the carrier ID matching table at first power up and when it is updated. - * - * Logged from: - * frameworks/opt/telephony/src/java/com/android/internal/telephony/metrics/CarrierIdMatchStats.java - */ -message CarrierIdTableUpdated { - // Version of the CarrierId matching table. - optional int32 table_version = 1; -} - -/** - * Pulls the version of the carrier ID matching table. - * - * Logged from: - * frameworks/opt/telephony/src/java/com/android/internal/telephony/metrics/MetricsCollector.java - */ -message CarrierIdTableVersion { - // Version of the CarrierId matching table. - optional int32 table_version = 1; -} - -/** - * Pulls information for a single data call session - * - * Each pull creates multiple atoms, one for each data call session. - * The sequence is randomized when pulled. - * - * Pulled from: - * frameworks/opt/telephony/src/java/com/android/internal/telephony/metrics/MetricsCollector.java - */ -message DataCallSession { - // A random number to be used as dimension to capture multiple atoms - optional int32 dimension = 1; - - // Whether the device was in multi-SIM mode (with multiple active SIM profiles). - optional bool is_multi_sim = 2; - - // Whether the call was made with an eSIM profile. - optional bool is_esim = 3; - - // Data profile of this call (for what purpose this call was made) - optional android.telephony.DataProfileEnum profile = 4; - - // APN type bitmask of the APN used: - // @ApnType in frameworks/base/telephony/java/android/telephony/Annotation.java. - optional int32 apn_type_bitmask = 5; - - // Carrier ID of the SIM - // See https://source.android.com/devices/tech/config/carrierid. - optional int32 carrier_id = 6; - - // Whether the subscription is roaming - optional bool is_roaming = 7; - - // Data RAT when the call ended, can be IWLAN for IMS/MMS, otherwise should be WWAN PS RAT. - // In the case that the connection hasn't ended yet, this field holds the current RAT. - // In the case the call ended due to Out Of Service (OOS), - // this field should be the last known RAT. - optional android.telephony.NetworkTypeEnum rat_at_end = 8; - - // Was the data call ended due to OOS - optional bool oos_at_end = 9; - - // Number of RAT switches during the data call - optional int64 rat_switch_count = 10; - - // Whether the call is on an opportunistic subscription - optional bool is_opportunistic = 11; - - // Packet data protocol used - optional android.telephony.ApnProtocolEnum ip_type = 12; - - // Whether the data call terminated before being established - optional bool setup_failed = 13; - - // Reason why the data call terminated, as in RIL_DataCallFailCause from ril.h - optional int32 failure_cause = 14; - - // Suggested retry back-off timer value from RIL - optional int32 suggested_retry_millis = 15; - - // Why the data call was deactivated - // Set by telephony for MO deactivations (unrelated to failure_cause) - optional android.telephony.DataDeactivateReasonEnum deactivate_reason = 16; - - // Duration of the data call, rounded into the closest 5 minutes. - optional int64 duration_minutes = 17; - - // Whether the data call is still connected when the atom is collected. - optional bool ongoing = 18; -} - -/** - * Logs data stall recovery event - * - * Logged from: - * frameworks/opt/telephony/src/java/com/android/internal/telephony/dataconnection/DcTracker.java - */ -message DataStallRecoveryReported { - // Carrier ID of the SIM - // See https://source.android.com/devices/tech/config/carrierid. - optional int32 carrier_id = 1; - - // Data RAT when the stall happened - optional android.telephony.NetworkTypeEnum rat = 2; - - // Signal strength when stall happened - optional android.telephony.SignalStrengthEnum signal_strength = 3; - - // Action taken to recover - optional android.telephony.DataStallRecoveryActionEnum action = 4; - - // Whether the subscription is opportunistic - optional bool is_opportunistic = 5; - - // Whether the device is in multi-SIM mode - optional bool is_multi_sim = 6; -} - -/** - * Logs gnss stats from location service provider - * - * Pulled from: - * frameworks/base/location/java/com/android/internal/location/gnssmetrics/GnssMetrics.java - */ -message GnssStats { - // Number of location reports since boot - optional int64 location_reports = 1; - - // Total pulled reports of Location failures since boot - optional int64 location_failure_reports = 2; - - // Number of time to first fix reports since boot - optional int64 time_to_first_fix_reports = 3; - - // Total pulled reported time to first fix (in milli-seconds) since boot - optional int64 time_to_first_fix_millis = 4; - - // Number of position accuracy reports since boot - optional int64 position_accuracy_reports = 5; - - // Total pulled reported position accuracy (in meters) since boot - optional int64 position_accuracy_meters = 6; - - // Number of top 4 average CN0 reports since boot - optional int64 top_four_average_cn0_reports = 7; - - // Total pulled reported of top 4 average CN0 (dB-mHz) since boot - optional int64 top_four_average_cn0_db_mhz = 8; - - // Number of l5 top 4 average CN0 reports since boot - optional int64 l5_top_four_average_cn0_reports = 9; - - // Total pulled reported of l5 top 4 average CN0 (dB-mHz) since boot - optional int64 l5_top_four_average_cn0_db_mhz = 10; - - // Total number of sv status messages reports since boot - optional int64 sv_status_reports = 11; - - // Total number of sv status messages reports, where sv is used in fix since boot - optional int64 sv_status_reports_used_in_fix = 12; - - // Total number of L5 sv status messages reports since boot - optional int64 l5_sv_status_reports = 13; - - // Total number of L5 sv status messages reports, where sv is used in fix since boot - optional int64 l5_sv_status_reports_used_in_fix = 14; -} - -/** - * Logs when an app is moved to a different standby bucket. - * - * Logged from: - * frameworks/base/apex/jobscheduler/service/java/com/android/server/usage/AppIdleHistory.java - */ -message AppStandbyBucketChanged { - optional string package_name = 1; - - // Should be 0, 10, 11, 12, etc. where 0 is the owner. See UserHandle for more documentation. - optional int32 user_id = 2; - - // These enum values match the constants defined in UsageStatsManager.java. - enum Bucket { - BUCKET_UNKNOWN = 0; - BUCKET_EXEMPTED = 5; - BUCKET_ACTIVE = 10; - BUCKET_WORKING_SET = 20; - BUCKET_FREQUENT = 30; - BUCKET_RARE = 40; - BUCKET_RESTRICTED = 45; - BUCKET_NEVER = 50; - } - optional Bucket bucket = 3; - - enum MainReason { - MAIN_UNKNOWN = 0; - MAIN_DEFAULT = 0x0100; - MAIN_TIMEOUT = 0x0200; - MAIN_USAGE = 0x0300; - MAIN_FORCED_BY_USER = 0x0400; - MAIN_PREDICTED = 0x0500; - MAIN_FORCED_BY_SYSTEM = 0x0600; - } - optional MainReason main_reason = 4; - - // A more detailed reason for the standby bucket change. The sub reason name is dependent on - // the main reason. Values are one of the REASON_SUB_XXX constants defined in - // UsageStatsManager.java. - optional int32 sub_reason = 5; -} - -/** -* Reports a started sharesheet transaction. -* -* Logged from: -* frameworks/base/core/java/com/android/internal/app/ChooserActivity.java -*/ -message SharesheetStarted { - // The event_id (as for UiEventReported). - optional int32 event_id = 1; - // The calling app's package name. - optional string package_name = 2; - // An identifier to tie together multiple logs relating to the same share event - optional int32 instance_id = 3; - // The mime type of the share - optional string mime_type = 4; - // The number of direct targets the calling app is providing that will be shown. - optional int32 num_app_provided_direct_targets = 5; - // The number of app targets the calling app is providing that will be shown. - optional int32 num_app_provided_app_targets = 6; - // True if the share originates from the workprofile - optional bool is_workprofile = 7; - - enum SharesheetPreviewType { // Constants from ChooserActivity.java - CONTENT_PREVIEW_TYPE_UNKNOWN = 0; // Default for proto 2 / 3 compatibility. - CONTENT_PREVIEW_IMAGE = 1; // The preview shown in the sharesheet is an image. - CONTENT_PREVIEW_FILE = 2; // The preview shown in the sharesheet is a file. - CONTENT_PREVIEW_TEXT = 3; // The preview shown in the sharesheet is text. - } - // How the sharesheet preview is presented. - optional SharesheetPreviewType preview_type = 8; - - enum ResolverActivityIntent { // Intents handled by ResolverActivity.java - INTENT_DEFAULT = 0; - INTENT_ACTION_VIEW = 1; - INTENT_ACTION_EDIT = 2; - INTENT_ACTION_SEND = 3; - INTENT_ACTION_SENDTO = 4; - INTENT_ACTION_SEND_MULTIPLE = 5; - INTENT_ACTION_IMAGE_CAPTURE = 6; - INTENT_ACTION_MAIN = 7; - } - // The intent being processed (only SEND and SEND_MULTIPLE are system sharesheet) - optional ResolverActivityIntent intent_type = 9; -} - -/** - * Reports a ranking selection event. - * - * Logged from: - * frameworks/base/core/java/com/android/internal/app/ChooserActivity.java (sharesheet) - */ -message RankingSelected { - // The event_id (as for UiEventReported). - optional int32 event_id = 1; - // The relevant app's package name (can be source or picked package). - optional string package_name = 2; - // An identifier to tie together multiple logs relating to the same share event. - optional int32 instance_id = 3; - // Which of the ranked targets got picked, default starting position 0. - optional int32 position_picked = 4; -} - -/** - * Logs when TvSettings UI is interacted at. - * - * Logged from: packages/apps/TvSettings - */ -message TvSettingsUIInteracted { - - /** The UI action category */ - optional android.app.tvsettings.Action action = 1; - - /** The ID of the entry that the users actioned on */ - optional android.app.tvsettings.ItemId item_id = 2; -} - -/** - * Logs information about a package installation using package installer V2 APIs. - * - * Logged from: - * frameworks/base/services/core/java/com/android/server/pm/PackageInstallerSession.java - */ -message PackageInstallerV2Reported { - // Whether this installation uses Incremental File System - optional bool is_incremental = 1; - // Name of the package that is intended to be installed - optional string package_name = 2; - // The duration between when the install was requested to when the install has completed - optional int64 duration_millis = 3; - // Installation result in final integer, which are SystemApi's. - // Return_code 1 indicates success. - // For full list, see frameworks/base/core/java/android/content/pm/PackageManager.java - optional int32 return_code = 4; - // Total size of the APKs installed for this package - optional int64 apks_size_bytes = 5; -} - -/** - * Logs settings provider values. - * - * Use DeviceConfig.getProperties to get a list Setting key, query the data from content provider, - * then write the value to proto. - * - */ -message SettingSnapshot { - - // Setting key - optional string name = 1; - - enum SettingsValueType { - NOTASSIGNED = 0; - ASSIGNED_BOOL_TYPE = 1; - ASSIGNED_INT_TYPE = 2; - ASSIGNED_FLOAT_TYPE = 3; - ASSIGNED_STRING_TYPE = 4; - }; - // Setting value type - optional SettingsValueType type = 2; - - optional bool bool_value = 3; - - optional int32 int_value = 4; - - optional float float_value = 5; - - optional string str_value = 6; - - // Android user index. 0 for primary user, 10, 11 for secondary or profile user - optional int32 user_id = 7; -} - -/** - * An event logged to indicate that a user journey is about to be performed. This atom includes - * relevant information about the users involved in the journey. A UserLifecycleEventOccurred event - * will immediately follow this atom which will describe the event(s) and its state. - * - * Logged from: - * frameworks/base/services/core/java/com/android/server/am/UserController.java - * frameworks/base/services/core/java/com/android/server/pm/UserManagerService.java - */ -message UserLifecycleJourneyReported { - // An identifier to track a chain of user lifecycle events occurring (referenced in the - // UserLifecycleEventOccurred atom) - optional int64 session_id = 1; - - // Indicates what type of user journey this session is related to - enum Journey { - UNKNOWN = 0; // Undefined user lifecycle journey - USER_SWITCH_UI = 1; // A user switch journey where a UI is shown - USER_SWITCH_FG = 2; // A user switch journey without a UI shown - USER_START = 3; // A user start journey - USER_CREATE = 4; // A user creation journey - } - optional Journey journey = 2; - // Which user the journey is originating from - could be -1 for certain phases (eg USER_CREATE) - // This integer is a UserIdInt (eg 0 for the system user, 10 for secondary/guest) - optional int32 origin_user = 3; - // Which user the journey is targeting - // This integer is a UserIdInt (eg 0 for the system user, 10 for secondary/guest) - optional int32 target_user = 4; - - // What is the user type of the target user - // These should be in sync with USER_TYPE_* flags defined in UserManager.java - enum UserType { - TYPE_UNKNOWN = 0; - FULL_SYSTEM = 1; - FULL_SECONDARY = 2; - FULL_GUEST = 3; - FULL_DEMO = 4; - FULL_RESTRICTED = 5; - PROFILE_MANAGED = 6; - SYSTEM_HEADLESS = 7; - } - optional UserType user_type = 5; - // What are the flags attached to the target user - optional int32 user_flags = 6; -} - -/** - * An event logged when a specific user lifecycle event is performed. These events should be - * correlated with a UserLifecycleJourneyReported atom via the session_id. - * Note: journeys can span over multiple events, hence some events may share a single session id. - * - * Logged from: - * frameworks/base/services/core/java/com/android/server/am/UserController.java - * frameworks/base/services/core/java/com/android/server/pm/UserManagerService.java - */ -message UserLifecycleEventOccurred { - // An id which links back to user details (reported in the UserLifecycleJourneyReported atom) - optional int64 session_id = 1; - // The target user for this event (same as target_user in the UserLifecycleJourneyReported atom) - // This integer is a UserIdInt (eg 0 for the system user, 10 for secondary/guest) - optional int32 user_id = 2; - - enum Event { - UNKNOWN = 0; // Indicates that the associated user journey timed-out or resulted in an error - SWITCH_USER = 1; // Indicates that this is a user switch event - START_USER = 2; // Indicates that this is a user start event - CREATE_USER = 3; // Indicates that this is a user create event - USER_RUNNING_LOCKED = 4; // Indicates that user is running in locked state - UNLOCKING_USER = 5; // Indicates that this is a user unlocking event - UNLOCKED_USER = 6; // Indicates that this is a user unlocked event - } - optional Event event = 3; - - enum State { - NONE = 0; // Indicates the associated event has no start/end defined - BEGIN = 1; - FINISH = 2; - } - optional State state = 4; // Represents the state of an event (beginning/ending) -} - -/** - * Logs when accessibility shortcut clicked. - * - * Logged from: - * frameworks/base/services/accessibility/java/com/android/server/accessibility - */ -message AccessibilityShortcutReported { - // The accessibility feature(including installed a11y service, framework a11y feature, - // and installed a11y activity) package name that is assigned to the accessibility shortcut. - optional string package_name = 1; - - // The definition of the accessibility shortcut. - // From frameworks/base/core/proto/android/stats/accessibility/accessibility_enums.proto. - optional android.stats.accessibility.ShortcutType shortcut_type = 2; - - // The definition of the service status. - // From frameworks/base/core/proto/android/stats/accessibility/accessibility_enums.proto. - optional android.stats.accessibility.ServiceStatus service_status = 3; -} - -/** - * Logs when accessibility service status changed. - * - * Logged from: - * packages/apps/Settings/src/com/android/settings/accessibility - */ -message AccessibilityServiceReported { - // The accessibility service package name. - optional string package_name = 1; - - // The definition of the service status. - // From frameworks/base/core/proto/android/stats/accessibility/accessibility_enums.proto. - optional android.stats.accessibility.ServiceStatus service_status = 2; -} - -/** - * Logs when display wake up. - * - * Logged from: - * services/core/java/com/android/server/power/Notifier.java - */ - -message DisplayWakeReported { - // Wake_up_reason code - // If LOWORD(wake_up_reason) = 0 - // reference to HIWORD(wake_up_reason) PowerManager.WAKE_REASON_XXX - // else reference wake_up_reason to - // services/core/java/com/android/server/power/Notifier.java#onWakeUp - optional int32 wake_up_reason = 1; -} - -/** - * Logs app usage events. - */ -message AppUsageEventOccurred { - optional int32 uid = 1 [(is_uid) = true]; - optional string package_name = 2; - optional string class_name = 3; - - enum EventType { - NONE = 0; - MOVE_TO_FOREGROUND = 1; - MOVE_TO_BACKGROUND = 2; - } - optional EventType event_type = 4; -} - -/* - * Quality metrics logged when EVS cameras are active. - * - * Logged from: - * packages/services/Car/evs/manager/1.1/Enumerator.cpp - */ -message EvsUsageStatsReported { - - // Camera identifier to distinguish the source camera device. This is not - // globally unique and therefore cannot be used to identify the user and/or - // the device. - optional int32 device_id = 1; - - // Peak number of clients during the service - optional int32 peak_num_clients = 2; - - // Number of erroneous events during the service - optional int32 num_errors = 3; - - // Round trip latency of the very first frame - optional int64 first_latency_millis = 4; - - // Average frame round trip latency - optional float avg_latency_millis = 5; - - // Peak frame round trip latency - optional int64 peak_latency_millis = 6; - - // Total number of frames received - optional int64 total_frames = 7; - - // Number of frames ignored - optional int64 ignored_frames = 8; - - // Number of dropped frames to synchronize camera devices - optional int64 dropped_frames_to_sync = 9; - - // The duration of the service - optional int64 duration_millis = 10; -} - -/** - * Logs audio power usage stats. - * - * Pushed from: - * frameworks/av/services/mediametrics/AudioPowerUsage.cpp - */ -message AudioPowerUsageDataReported { - /** - * Device used for input/output - * - * All audio devices please refer to below file: - * system/media/audio/include/system/audio-base.h - * - * Define our own enum values because we don't report all audio devices. - * Currently, we only report built-in audio devices such as handset, speaker, - * built-in mics, common audio devices such as wired headset, usb headset - * and bluetooth devices. - */ - enum AudioDevice { - OUTPUT_EARPIECE = 0x1; // handset - OUTPUT_SPEAKER = 0x2; // dual speaker - OUTPUT_WIRED_HEADSET = 0x4; // 3.5mm headset - OUTPUT_USB_HEADSET = 0x8; // usb headset - OUTPUT_BLUETOOTH_SCO = 0x10; // bluetooth sco - OUTPUT_BLUETOOTH_A2DP = 0x20; // a2dp - OUTPUT_SPEAKER_SAFE = 0x40; // bottom speaker - - INPUT_DEVICE_BIT = 0x40000000; // non-negative positive int32. - INPUT_BUILTIN_MIC = 0x40000001; // buildin mic - INPUT_BUILTIN_BACK_MIC = 0x40000002; // buildin back mic - INPUT_WIRED_HEADSET_MIC = 0x40000004; // 3.5mm headset mic - INPUT_USB_HEADSET_MIC = 0x40000008; // usb headset mic - INPUT_BLUETOOTH_SCO = 0x40000010; // bluetooth sco mic - } - optional AudioDevice audio_device = 1; - - // Duration of the audio in seconds - optional int32 duration_secs = 2; - - // Average volume (0 ... 1.0) - optional float average_volume = 3; - - enum AudioType { - UNKNOWN_TYPE = 0; - VOICE_CALL_TYPE = 1; // voice call - VOIP_CALL_TYPE = 2; // voip call, including uplink and downlink - MEDIA_TYPE = 3; // music and system sound - RINGTONE_NOTIFICATION_TYPE = 4; // ringtone and notification - ALARM_TYPE = 5; // alarm type - // record type - CAMCORDER_TYPE = 6; // camcorder - RECORD_TYPE = 7; // other recording - } - optional AudioType type = 4; -} - -/** - * Pulls bytes transferred over WiFi and mobile networks sliced by uid, is_metered, and tag. - * - * Pulled from: - * StatsPullAtomService, which uses NetworkStatsService to query NetworkStats. - */ -message BytesTransferByTagAndMetered { - optional int32 uid = 1 [(is_uid) = true]; - - optional bool is_metered = 2; - - optional int32 tag = 3; - - optional int64 rx_bytes = 4; - - optional int64 rx_packets = 5; - - optional int64 tx_bytes = 6; - - optional int64 tx_packets = 7; -} - -/* - * Logs when the Media Output Switcher finishes a media switch operation. - * - * Logged from: - * packages/apps/Settings/src/com/android/settings/media/MediaOutputSliceWorker.java - */ -message MediaOutputOpSwitchReported { - // Source medium type before switching. - optional android.app.settings.mediaoutput.MediumType source = 1; - - // Target medium type after switching. - optional android.app.settings.mediaoutput.MediumType target = 2; - - // The result of switching. - optional android.app.settings.mediaoutput.SwitchResult result = 3; - - // The detail code of a switching result. - optional android.app.settings.mediaoutput.SubResult subresult = 4; - - /* - * The package name of a pre-installed app, whose media session is being switched. - */ - optional string media_session_package_name = 5; - - // The amount of available wired devices when a switching is being performed. - optional int32 available_wired_device_count = 6; - - // The amount of available Bluetooth devices a switching is being performed. - optional int32 available_bt_device_count = 7; - - // The amount of available remote devices when a switching is being performed. - optional int32 available_remote_device_count = 8; - - // The amount of applied devices within a remote dynamic group after a switching is done. - optional int32 applied_device_count_within_remote_group = 9; -} - -/** - * Logs when the Assistant is invoked. - * - * Logged from: - * frameworks/base/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java - */ -message AssistantInvocationReported { - - // The event_id (as for UiEventReported). - optional int32 event_id = 1; - - // The registered Assistant's uid and package (as for UiEventReported). - optional int32 uid = 2 [(is_uid) = true]; - optional string package_name = 3; - - // An identifier used to disambiguate which logs refer to a particular invocation of the - // Assistant (as for UiEventReported). - optional int32 instance_id = 4; - - // The state of the device at the time of invocation. - enum DeviceState { - UNKNOWN_DEVICE_STATE = 0; - AOD1 = 1; - AOD2 = 2; - BOUNCER = 3; - UNLOCKED_LOCKSCREEN = 4; - LAUNCHER_HOME = 5; - LAUNCHER_OVERVIEW = 6; - LAUNCHER_ALL_APPS = 7; - APP_DEFAULT = 8; - APP_IMMERSIVE = 9; - APP_FULLSCREEN = 10; - } - optional DeviceState device_state = 5; - - // Whether the Assistant handles were showing at the time of invocation. - optional bool assistant_handles_showing = 6; -} - -/** - * Logs when an AudioRecord finishes running on an audio device - * - * Logged from: - * frameworks/av/services/mediametrics/AudioAnalytics.cpp - */ -message MediametricsAudioRecordDeviceUsageReported { - // The devices connected to this AudioRecord. - // A string OR of various input device categories, e.g. "DEVICE1|DEVICE2". - // See lookup<INPUT_DEVICE>() in frameworks/av/services/mediametrics/AudioTypes.cpp - // See audio_device_t in system/media/audio/include/system/audio-base.h - optional string devices = 1; - - // The name of the remote device attached to the device, typically available for USB or BT. - // This may be empty for a fixed device, or separated by "|" if more than one. - optional string device_names = 2; - - // The amount of time spent in the device as measured by the active track in AudioFlinger. - optional int64 device_time_nanos = 3; - - // The audio data format used for encoding. - // An enumeration from system/media/audio/include/system/audio-base.h audio_format_t - optional string encoding = 4; - - // The client-server buffer framecount. - // The framecount is generally between 960 - 48000 for PCM encoding. - // The framecount represents raw buffer size in bytes for non-PCM encoding. - optional int32 frame_count = 5; - - // The number of audio intervals (contiguous, continuous playbacks). - optional int32 interval_count = 6; - - // The sample rate of the AudioRecord. - // A number generally between 8000-96000 (frames per second). - optional int32 sample_rate = 7; - - // The audio input flags used to construct the AudioRecord. - // A string OR from system/media/audio/include/system/audio-base.h audio_input_flags_t - optional string flags = 8; - - // The santized package name of the audio client associated with the AudioRecord. - // See getSanitizedPackageNameAndVersionCode() in - // frameworks/av/services/mediametrics/MediaMetricsService.cpp - optional string package_name = 9; - - // The selected device id (nonzero if a non-default device is selected) - optional int32 selected_device_id = 10; - - // The caller of the AudioRecord. - // See lookup<CALLER_NAME>() in frameworks/av/services/mediametrics/AudioTypes.cpp - optional string caller = 11; - - // The audio source for AudioRecord. - // An enumeration from system/media/audio/include/system/audio-base.h audio_source_t - optional string source = 12; -} - -/** - * Logs when an AudioThread finishes running on an audio device - * - * Logged from: - * frameworks/av/services/mediametrics/AudioAnalytics.cpp - */ -message MediametricsAudioThreadDeviceUsageReported { - // The devices connected to this audio thread. - // A string OR of various input device categories, e.g. "DEVICE1|DEVICE2". - // (for record threads): - // See lookup<INPUT_DEVICE> in frameworks/av/services/mediametrics/AudioTypes.cpp - // (for playback threads): - // See lookup<OUTPUT_DEVICE>() in frameworks/av/services/mediametrics/AudioTypes.cpp - // See audio_device_t in system/media/audio/include/system/audio-base.h - optional string devices = 1; - - // The name of the remote device attached to the device, typically available for USB or BT. - // This may be empty for a fixed device, or separated by "|" if more than one. - optional string device_names = 2; - - // The amount of time spent in the device as measured by the active track in AudioFlinger. - optional int64 device_time_nanos = 3; - - // The audio data format used for encoding. - // An enumeration from system/media/audio/include/system/audio-base.h audio_format_t - optional string encoding = 4; - - // The framecount of the buffer delivered to (or from) the HAL. - // The framecount is generally ~960 for PCM encoding. - // The framecount represents raw buffer size in bytes for non-PCM encoding. - optional int32 frame_count = 5; - - // The number of audio intervals (contiguous, continuous playbacks). - optional int32 interval_count = 6; - - // The sample rate of the audio thread. - // A number generally between 8000-96000 (frames per second). - optional int32 sample_rate = 7; - - // The audio flags used to construct the thread - // (for record threads): - // A string OR from system/media/audio/include/system/audio-base.h audio_input_flags_t - // (for playback threads): - // A string OR from system/media/audio/include/system/audio-base.h audio_output_flags_t - optional string flags = 8; - - // The number of underruns encountered for a playback thread or the - // number of overruns encountered for a capture thread. - optional int32 xruns = 9; - - // The type of thread - // A thread type enumeration from - // frameworks/av/mediametrics/services/Translate.h - optional string type = 10; -} - -/** - * Logs when an AudioTrack finishes running on an audio device - * - * Logged from: - * frameworks/av/services/mediametrics/AudioAnalytics.cpp - */ -message MediametricsAudioTrackDeviceUsageReported { - // The output devices connected to this AudioTrack. - // A string OR of various output device categories, e.g. "DEVICE1|DEVICE2". - // See lookup<OUTPUT_DEVICE>() in frameworks/av/services/mediametrics/AudioTypes.cpp - // See audio_device_t in system/media/audio/include/system/audio-base.h - optional string devices = 1; - - // The name of the remote device attached to the device, typically available for USB or BT. - // This may be empty for a fixed device, or separated by "|" if more than one. - optional string device_names = 2; - - // The amount of time spent in the device as measured by the active track in AudioFlinger. - optional int64 device_time_nanos = 3; - - // The audio data format used for encoding. - // An enumeration from system/media/audio/include/system/audio-base.h audio_format_t - optional string encoding = 4; - - // The client-server buffer framecount. - // The framecount is generally between 960 - 48000 for PCM encoding. - // The framecount represents raw buffer size in bytes for non-PCM encoding. - // A static track (see traits) may have a very large framecount. - optional int32 frame_count = 5; - - // The number of audio intervals (contiguous, continuous playbacks). - optional int32 interval_count = 6; - - // The sample rate of the AudioTrack. - // A number generally between 8000-96000 (frames per second). - optional int32 sample_rate = 7; - - // The audio flags used to construct the AudioTrack. - // A string OR from system/media/audio/include/system/audio-base.h audio_output_flags_t - optional string flags = 8; - - // The number of underruns encountered. - optional int32 xruns = 9; - - // The santized package name of the audio client associated with the AudioTrack. - // See getSanitizedPackageNameAndVersionCode() in - // frameworks/av/services/mediametrics/MediaMetricsService.cpp - optional string package_name = 10; - - // The latency of the last sample in the buffer in milliseconds. - optional float device_latency_millis = 11; - - // The startup time in milliseconds from start() to sample played. - optional float device_startup_millis = 12; - - // The average volume of the track on the device [ 0.f - 1.f ] - optional float device_volume = 13; - - // The selected device id (nonzero if a non-default device is selected) - optional int32 selected_device_id = 14; - - // The stream_type category for the AudioTrack. - // An enumeration from system/media/audio/include/system/audio-base.h audio_stream_type_t - optional string stream_type = 15; - - // The usage for the AudioTrack. - // An enumeration from system/media/audio/include/system/audio-base.h audio_usage_t - optional string usage = 16; - - // The content type of the AudioTrack. - // An enumeration from system/media/audio/include/system/audio-base.h audio_content_type_t - optional string content_type = 17; - - // The caller of the AudioTrack. - // See lookup<CALLER_NAME>() in frameworks/av/services/mediametrics/AudioTypes.cpp - optional string caller = 18; - - // The traits of the AudioTrack. - // A string OR of different traits, may be empty string. - // Only "static" is supported for R. - // See lookup<TRACK_TRAITS>() in frameworks/av/services/mediametrics/AudioTypes.cpp - optional string traits = 19; -} - -/** - * Logs the status of an audio device connection attempt. - * - * Logged from: - * frameworks/av/services/mediametrics/AudioAnalytics.cpp - */ -message MediametricsAudioDeviceConnectionReported { - // The input devices represented by this report. - // A string OR of various input device categories, e.g. "DEVICE1|DEVICE2". - // See lookup<INPUT_DEVICE>() in frameworks/av/services/mediametrics/AudioTypes.cpp - // See audio_device_t in system/media/audio/include/system/audio-base.h - optional string input_devices = 1; - - // The output devices represented by this report. - // A string OR of various output device categories. - // See lookup<OUTPUT_DEVICE>() in frameworks/av/services/mediametrics/AudioTypes.cpp - // See audio_device_t in system/media/audio/include/system/audio-base.h - optional string output_devices = 2; - - // The name of the remote device attached to the device, typically available for USB or BT. - // This may be empty for a fixed device, or separated by "|" if more than one. - optional string device_names = 3; - - // The result of the audio device connection. - // 0 indicates success: connection verified. - // 1 indicates unknown: connection not verified or not known if diverted properly. - // Other values indicate specific status. - // See DeviceConnectionResult in frameworks/av/services/mediametrics/AudioTypes.h - optional int32 result = 4; - - // Average milliseconds of time to connect - optional float time_to_connect_millis = 5; - - // Number of connections if aggregated statistics, otherwise 1. - optional int32 connection_count = 6; -} - -/** - * Logs: i) creation of different types of cryptographic keys in the keystore, - * ii) operations performed using the keys, - * iii) attestation of the keys - * Logged from: system/security/keystore/key_event_log_handler.cpp - */ -message KeystoreKeyEventReported { - - enum Algorithm { - /** Asymmetric algorithms. */ - RSA = 1; - // 2 removed, do not reuse. - EC = 3; - /** Block cipher algorithms */ - AES = 32; - TRIPLE_DES = 33; - /** MAC algorithms */ - HMAC = 128; - }; - /** Algorithm associated with the key */ - optional Algorithm algorithm = 1; - - /** Size of the key */ - optional int32 key_size = 2; - - enum KeyOrigin { - /** Generated in keymaster. Should not exist outside the TEE. */ - GENERATED = 0; - /** Derived inside keymaster. Likely exists off-device. */ - DERIVED = 1; - /** Imported into keymaster. Existed as cleartext in Android. */ - IMPORTED = 2; - /** Keymaster did not record origin. */ - UNKNOWN = 3; - /** Securely imported into Keymaster. */ - SECURELY_IMPORTED = 4; - }; - /* Logs whether the key was generated, imported, securely imported, or derived.*/ - optional KeyOrigin key_origin = 3; - - enum HardwareAuthenticatorType { - NONE = 0; - PASSWORD = 1; - FINGERPRINT = 2; - // Additional entries must be powers of 2. - }; - /** - * What auth types does this key require? If none, - * then no auth required. - */ - optional HardwareAuthenticatorType user_auth_type = 4; - - /** - * If user authentication is required, is the requirement time based? If it - * is not time based then this field will not be used and the key is per - * operation. Per operation keys must be user authenticated on each usage. - */ - optional int32 user_auth_key_timeout_secs = 5; - - /** - * padding mode, digest, block_mode and purpose should ideally be repeated - * fields. However, since statsd does not support repeated fields in - * pushed atoms, they are represented using bitmaps. - */ - - /** Track which padding mode is being used.*/ - optional int32 padding_mode_bitmap = 6; - - /** Track which digest is being used. */ - optional int32 digest_bitmap = 7; - - /** Track what block mode is being used (for encryption). */ - optional int32 block_mode_bitmap = 8; - - /** Track what purpose is this key serving. */ - optional int32 purpose_bitmap = 9; - - enum EcCurve { - P_224 = 0; - P_256 = 1; - P_384 = 2; - P_521 = 3; - }; - /** Which ec curve was selected if elliptic curve cryptography is in use **/ - optional EcCurve ec_curve = 10; - - enum KeyBlobUsageRequirements { - STANDALONE = 0; - REQUIRES_FILE_SYSTEM = 1; - }; - /** Standalone or is a file system required */ - optional KeyBlobUsageRequirements key_blob_usage_reqs = 11; - - enum Type { - key_operation = 0; - key_creation = 1; - key_attestation = 2; - } - /** Key creation event, operation event or attestation event? */ - optional Type type = 12; - - /** Was the key creation, operation, or attestation successful? */ - optional bool was_successful = 13; - - /** Response code or error code */ - optional int32 error_code = 14; -} - -// Blob Committer stats -// Keep in sync between: -// frameworks/base/core/proto/android/server/blobstoremanagerservice.proto -// frameworks/base/cmds/statsd/src/atoms.proto -message BlobCommitterProto { - // Committer app's uid - optional int32 uid = 1 [(is_uid) = true]; - - // Unix epoch timestamp of the commit in milliseconds - optional int64 commit_timestamp_millis = 2; - - // Flags of what access types the committer has set for the Blob - optional int32 access_mode = 3; - - // Number of packages that have been whitelisted for ACCESS_TYPE_WHITELIST - optional int32 num_whitelisted_package = 4; -} - -// Blob Leasee stats -// Keep in sync between: -// frameworks/base/core/proto/android/server/blobstoremanagerservice.proto -// frameworks/base/cmds/statsd/src/atoms.proto -message BlobLeaseeProto { - // Leasee app's uid - optional int32 uid = 1 [(is_uid) = true]; - - // Unix epoch timestamp for lease expiration in milliseconds - optional int64 lease_expiry_timestamp_millis = 2; -} - -// List of Blob Committers -// Keep in sync between: -// frameworks/base/core/proto/android/server/blobstoremanagerservice.proto -// frameworks/base/cmds/statsd/src/atoms.proto -message BlobCommitterListProto { - repeated BlobCommitterProto committer = 1; -} - -// List of Blob Leasees -// Keep in sync between: -// frameworks/base/core/proto/android/server/blobstoremanagerservice.proto -// frameworks/base/cmds/statsd/src/atoms.proto -message BlobLeaseeListProto { - repeated BlobLeaseeProto leasee = 1; -} - -/** - * Logs the current state of a Blob committed with BlobStoreManager - * - * Pulled from: - * frameworks/base/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java - */ -message BlobInfo { - // Id of the Blob - optional int64 blob_id = 1; - - // Size of the Blob data - optional int64 size = 2; - - // Unix epoch timestamp of the Blob's expiration in milliseconds - optional int64 expiry_timestamp_millis = 3; - - // List of committers of this Blob - optional BlobCommitterListProto committers = 4 [(log_mode) = MODE_BYTES]; - - // List of leasees of this Blob - optional BlobLeaseeListProto leasees = 5 [(log_mode) = MODE_BYTES]; -} - -/** - * Logs when the HDMI CEC active source changes. - * - * Logged from: - * frameworks/base/services/core/java/com/android/server/hdmi/HdmiCecAtomWriter.java - */ -message HdmiCecActiveSourceChanged { - // The logical address of the active source. - optional android.stats.hdmi.LogicalAddress active_source_logical_address = 1; - - // The physical address of the active source. Consists of four hexadecimal nibbles. - // Examples: 0x1234, 0x0000 (root device). 0xFFFF represents an unknown or invalid address. - // See section 8.7 in the HDMI 1.4b spec for details. - optional int32 active_source_physical_address = 2; - - // The relationship between this device and the active source. - optional android.stats.hdmi.PathRelationship local_relationship = 3; -} - -/** - * Logs when an HDMI CEC message is sent or received. - * - * Logged from: - * frameworks/base/services/core/java/com/android/server/hdmi/HdmiCecAtomWriter.java - */ -message HdmiCecMessageReported { - // The calling uid of the application that caused this atom to be written. - optional int32 uid = 1 [(is_uid) = true]; - - // Whether a HDMI CEC message is sent from this device, to this device, or neither. - optional android.stats.hdmi.MessageDirection direction = 2; - - // The HDMI CEC logical address of the initiator. - optional android.stats.hdmi.LogicalAddress initiator_logical_address = 3; - - // The HDMI CEC logical address of the destination. - optional android.stats.hdmi.LogicalAddress destination_logical_address = 4; - - // The opcode of the message. Ranges from 0x00 to 0xFF. - // For all values, see section "CEC 15 Message Descriptions" in the HDMI CEC 1.4b spec. - optional int32 opcode = 5; - - // The result of attempting to send the message on its final retransmission attempt. - // Only applicable to outgoing messages; set to SEND_MESSAGE_RESULT_UNKNOWN otherwise. - optional android.stats.hdmi.SendMessageResult send_message_result = 6; - - // Fields specific to <User Control Pressed> messages - - // The user control command that was received. - optional android.stats.hdmi.UserControlPressedCommand user_control_pressed_command = 7; - - // Fields specific to <Feature Abort> messages - - // The opcode of the message that was feature aborted. - // Set to 0x100 when unknown or not applicable. - optional int32 feature_abort_opcode = 8; - - // The reason for the feature abort. - optional android.stats.hdmi.FeatureAbortReason feature_abort_reason = 9; -} - -/** - * Logs when an auto rotate event occurs while smart auto rotate is enabled. - */ -message AutoRotateReported { - enum Orientation { - UNKNOWN = 1; - ROTATION_0 = 2; - ROTATION_90 = 3; - ROTATION_180 = 4; - ROTATION_270 = 5; - DISABLED = 6; - UNAVAILABLE = 7; - FAILURE = 8; - } - - // Orientation of the device when a rotation was detected. - optional Orientation current_orientation = 1; - // The orientation of the phone after rotation before going through the recommendation service. - optional Orientation proposed_orientation = 2; - // Orientation recommended by the smart autorotate service component outside of the platform. It - // may or may not match the proposed_orientation. Can be disabled or unavailable if the - // recommendation service is disabled or unavailable. Will be unknown if the service failed. - optional Orientation recommended_orientation = 3; - // Time taken to calculate the rotation recommendation. - optional int64 recommendation_process_duration_millis = 4; -} - -/** - * Pushes TLS handshake counters from Conscrypt. - * Pulled from: - * external/conscrypt/common/src/main/java/org/conscrypt/ConscryptEngineSocket.java - * external/conscrypt/common/src/main/java/org/conscrypt/ConscryptFileDescriptorSocket.java - */ -message TlsHandshakeReported { - optional bool success = 1; - - optional android.stats.tls.Protocol protocol = 2; - - optional android.stats.tls.CipherSuite cipher_suite = 3; - - optional int32 handshake_duration_millis = 4; -} - -/** - * Logs when a TextClassifier API is invoked. - * - * See frameworks/base/core/java/android/view/textclassifier/TextClassifier.java - * Logged from: external/libtextclassifier/java/ - */ -message TextClassifierApiUsageReported { - enum ApiType { - UNKNOWN_API = 0; - SUGGEST_SELECTION = 1; - CLASSIFY_TEXT = 2; - GENERATE_LINKS = 3; - DETECT_LANGUAGES = 4; - SUGGEST_CONVERSATION_ACTIONS = 5; - } - optional ApiType api_type = 1; - - enum ResultType { - UNKNOWN_RESULT = 0; - SUCCESS = 1; - FAIL = 2; - } - optional ResultType result_type = 2; - optional int64 latency_millis = 3; -} - -/** - * Logs the current state of an application before it is killed. - * - * Pushed from: - * packages/services/Car/watchdog/server/src/ApplicationTerminator.cpp - */ -message KilledAppStatsReported { - // Linux process uid for the package. - optional int32 uid = 1 [(is_uid) = true]; - - // Name of the package that was killed. - optional string package_name = 2; - - // State of the application when it was killed. - enum AppState { - UNKNOWN_APP_STATE = 0; - BACKGROUND = 1; - FOREGROUND = 2; - } - optional AppState app_state = 3; - - // System state indicating whether the system was in normal mode or garage mode. - enum SystemState { - UNKNOWN_SYSTEM_STATE = 0; - USER_INTERACTION_MODE = 1; - NO_USER_INTERACTION_MODE = 2; - } - optional SystemState system_state = 4; - - // Reason for killing the application. - // Keep in sync between: - // packages/services/Car/watchdog/server/src/ApplicationTerminator.h - // frameworks/base/cmds/statsd/src/atoms.proto - enum KillReason { - UNKNOWN_KILL_REASON = 0; - KILLED_ON_ANR = 1; - KILLED_ON_IO_OVERUSE = 2; - KILLED_ON_MEMORY_OVERUSE = 3; - } - optional KillReason kill_reason = 5; - - // Stats of the processes owned by the application when the application was killed. - // The process stack traces are not collected when the application was killed due to IO_OVERUSE. - optional ProcessStats process_stat = 6 [(log_mode) = MODE_BYTES]; - - // The application's I/O overuse stats logged only when the kill reason is KILLED_ON_IO_OVERUSE. - optional IoOveruseStats io_overuse_stats = 7 [(log_mode) = MODE_BYTES]; -} - -/** - * Logs I/O overuse stats for a package. - * - * Keep in sync between: - * packages/services/Car/watchdog/server/src/proto/statsd.proto - * frameworks/base/cmds/statsd/src/atoms.proto - * - * Logged from: - * packages/services/Car/watchdog/server/src/ApplicationTerminator.cpp - */ -message IoOveruseStats { - enum Period { - DAILY = 0; - WEEKLY = 1; - } - - // Threshold and usage stats period. - optional Period period = 1; - - // Threshold in-terms of write bytes defined for the package. - optional PerStateBytes threshold = 2; - - // Number of write bytes in each state for the specified period. - optional PerStateBytes written_bytes = 3; -}; - -/** - * Logs bytes attributed to each application and system states. - * - * Keep in sync between: - * packages/services/Car/watchdog/server/src/proto/statsd.proto - * frameworks/base/cmds/statsd/src/atoms.proto - * - * Logged from: - * packages/services/Car/watchdog/server/src/ApplicationTerminator.cpp - */ -message PerStateBytes { - // Number of bytes attributed to the application foreground. - optional int64 foreground_bytes = 1; - - // Number of bytes attributed to the application background. - optional int64 background_bytes = 2; - - // Number of bytes attributed to the garage mode. - optional int64 garage_mode_bytes = 3; -} - -/** - * Logs each ProcessStat in ProcessStats. - * Keep in sync between: - * packages/services/Car/watchdog/server/src/proto/statsd.proto - * frameworks/base/cmds/statsd/src/atoms.proto - * Logged from: - * packages/services/Car/watchdog/server/src/ApplicationTerminator.cpp - */ -message ProcessStats { - // Records the stats of the processes owned by an application. - repeated ProcessStat process_stat = 1; -} - -/** - * Logs a process's stats. - * Keep in sync between: - * packages/services/Car/watchdog/server/src/proto/statsd.proto - * frameworks/base/cmds/statsd/src/atoms.proto - * Logged from: - * packages/services/Car/watchdog/server/src/ApplicationTerminator.cpp - */ -message ProcessStat { - // Command name of the process. - optional string process_name = 1; - - // Process uptime. - optional uint64 uptime_milliseconds = 2; - - // Number of major page faults caused by the process and its children. - optional uint64 major_page_faults = 3; - - // Peak virtual memory size in kb. - optional uint64 vm_peak_kb = 4; - - // Virtual memory size in kb. - optional uint64 vm_size_kb = 5; - - // Peak resident set size (high water mark) in kb. - optional uint64 vm_hwm_kb = 6; - - // Resident set size in kb. - optional uint64 vm_rss_kb = 7; -} - -/* - * pushes Media playback information. - * Logged from - * (WIP) frameworks/av/services/mediaanalytics/playback_statsd.cpp - */ -message MediametricsPlaybackReported { - optional int32 uid = 1 [(is_uid) = true]; - - // Randomly generated playback ID. A Base64 encoded hex string representing a 128-bit integer - optional string playback_id = 2; - // The total length of the media in milliseconds. 0 for live contents. - optional int64 media_duration_millis = 3; - // Network, device, or mixed. - optional android.stats.mediametrics.StreamSourceType stream_source = 4; - // Stream type. DASH, HLS, etc - optional android.stats.mediametrics.StreamType stream_type = 5; - // Live, VOD, others - optional android.stats.mediametrics.PlaybackType playback_type = 6; - // DRM type - optional android.stats.mediametrics.DrmType drm_type = 7; - // Main, AD, others - optional android.stats.mediametrics.ContentType content_type = 8; - // Player name. E.g. ExoPlayer - optional string player_name = 9; - // Player version. E.g. 1.10.3e - optional string player_version = 10; - // Player related experiment IDs - optional Experiments experiment_ids = 11 [(log_mode) = MODE_BYTES]; - // Number of frames played. Dropped frames included. -1 means unknown. - optional int32 video_frames_played = 12; - // Number of frames dropped. -1 means unknown. - optional int32 video_frames_dropped = 13; - // Number of audio underruns. -1 means unknown. - optional int32 audio_underrun_count = 14; - // Total number of bytes read from the network - optional int64 network_bytes_read = 15; - // Total number of bytes read from on-device sources - optional int64 local_bytes_read = 16; - // Total transfer spent reading from the network in ms. - // For parallel requests, the overlapping time intervals are counted only once. - optional int64 network_transfer_duration_millis = 17; -} - -message MediaNetworkInfoChanged { - // Randomly generated playback ID. A Base64 encoded hex string representing a 128-bit integer - optional string playback_id = 1; - // New network type - optional android.stats.mediametrics.NetworkType type = 2; - // Network Start time, relative to playback creation time in millisecond. - // It's in absolute time (e.g. always ticks even if the playback is paused). - optional int64 time_since_playback_created_millis = 3; -} - -message MediaPlaybackStateChanged { - // Randomly generated playback ID. A Base64 encoded hex string representing a 128-bit integer - optional string playback_id = 1; - // New playback state - optional android.stats.mediametrics.PlaybackState playback_state = 2; - // State change time, relative to playback creation time in millisecond. - // It's in absolute time (e.g. always ticks even if the playback is paused). - optional int64 time_since_playback_created_millis = 3; -} - -message MediaPlaybackErrorReported { - // Randomly generated playback ID. A Base64 encoded hex string representing a 128-bit integer - optional string playback_id = 1; - // A shortened call stack of the error - optional string exception_stack = 2; - // Error code - optional android.stats.mediametrics.PlaybackErrorCode error_code = 3; - // Sub-code of error type specified by the error code. - optional int32 sub_error_code = 4; - // Error time, relative to playback creation time in millisecond. - // It's in absolute time (e.g. always ticks even if the playback is paused). - optional int64 time_since_playback_created_millis = 5; -} - -message MediaPlaybackTrackChanged { - // Randomly generated playback ID. A Base64 encoded hex string representing a 128-bit integer - optional string playback_id = 1; - // The track is on or off after the change - optional android.stats.mediametrics.TrackState state = 2; - // The reason of the track change - optional android.stats.mediametrics.TrackChangeReason reason = 3; - // The MIME type of the container. E.g. video/mp4 - optional string container_mime_type = 4; - // The sample MIME type of the track. E.g. video/avc - optional string sample_mime_type = 5; - - // Codec name - optional string codec_name = 6; - // Bits per second. 0 means unknown. - optional int32 bitrate = 7; - - // Track change time, relative to playback creation time in millisecond. - // It's in absolute time (e.g. always ticks even if the playback is paused). - optional int64 time_since_playback_created_millis = 8; - - // Track type. Audio, Video, Text - optional android.stats.mediametrics.TrackType type = 9; - // 2-letter ISO 639-1 language code. - optional string language = 10; - // IETF BCP 47 optional language region subtag based on a two-letter country code - optional string language_region = 11; - // Number of channels - optional int32 channel_count = 12; - // Samples per second - optional int32 sample_rate = 13; - // The width of the video in pixels. - optional int32 width = 14; - // The height of the video in pixels. - optional int32 height = 15; -} - -message Experiments { - // Experiment IDs sent by the player. - repeated int64 experiments = 1; -} - -/** - * Logs when a Wifi network scan happens. - * - * Logged from: - * frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiMetrics.java - */ -message WifiScanReported { - enum Type { - TYPE_UNKNOWN = 0; - - // Single scan. - TYPE_SINGLE = 1; - - // Background scan (deprecated, should not happen). - TYPE_BACKGROUND = 2; - } - - enum Result { - RESULT_UNKNOWN = 0; - - // Failed to start scan. - RESULT_FAILED_TO_START = 1; - - // The HAL reported a scan failure after the scan was started. - RESULT_FAILED_TO_SCAN = 2; - - // Scan succeeded. - RESULT_SUCCESS = 3; - } - - enum Source { - SOURCE_UNKNOWN = 0; - - // No work source set - not possible to determine the origin. - SOURCE_NO_WORK_SOURCE = 1; - - // The Wifi stack. - SOURCE_WIFI_STACK = 2; - - // GMS on behalf of some other app. - SOURCE_GMS = 3; - - // Settings app. - SOURCE_SETTINGS_APP = 4; - - // Other app directly. - SOURCE_OTHER_APP = 5; - } - - enum Importance { - IMPORTANCE_UNKNOWN = 0; - - // Foreground app. Corresponds to the value of - // ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND or less. - IMPORTANCE_FOREGROUND = 1; - - // Foreground service. Corresponds to the value of - // ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE - IMPORTANCE_FOREGROUND_SERVICE = 2; - - // Everything else. - IMPORTANCE_BACKGROUND = 3; - } - - // Scan type - optional Type type = 1; - - // Outcome: success/failure - optional Result result = 2; - - // What initiated a scan. - optional Source source = 3; - - // Process importance of the initiator. - // This is only available for non-system calls. - optional Importance importance = 4; - - // Time taken for the scan. - optional int32 scan_duration_millis = 5; - - // Count of found networks. - optional int32 count_networks_found = 6; -} - -/** - * Logs when a Wifi PNO (Preferred Network Offload) scan happens. - * - * Logged from: - * frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiMetrics.java - */ -message WifiPnoScanReported { - enum State { - UNKNOWN = 0; - - // Scan started. - STARTED = 1; - - // Scan failed to start (e.g. bad request, unsupported by hardware, etc). - FAILED_TO_START = 2; - - // Scan completed and a network was found. - // Note - due to implementation constraints, nothing is reported when a scan completes but - // doesn't find any networks. - FINISHED_NETWORKS_FOUND = 3; - - // Scan failed. - FAILED = 4; - } - - optional State state = 1; -} diff --git a/cmds/statsd/src/shell/shell_data.proto b/cmds/statsd/src/shell/shell_data.proto index 236bdbdd31f6..ec41cbc5caff 100644 --- a/cmds/statsd/src/shell/shell_data.proto +++ b/cmds/statsd/src/shell/shell_data.proto @@ -21,7 +21,7 @@ package android.os.statsd; option java_package = "com.android.os.statsd"; option java_outer_classname = "ShellDataProto"; -import "frameworks/base/cmds/statsd/src/atoms.proto"; +import "frameworks/proto_logging/stats/atoms.proto"; // The output of shell subscription, including both pulled and pushed subscriptions. message ShellData { diff --git a/cmds/statsd/src/stats_log.proto b/cmds/statsd/src/stats_log.proto index ddd2725c9cb9..bb0796326f01 100644 --- a/cmds/statsd/src/stats_log.proto +++ b/cmds/statsd/src/stats_log.proto @@ -21,7 +21,7 @@ package android.os.statsd; option java_package = "com.android.os"; option java_outer_classname = "StatsLog"; -import "frameworks/base/cmds/statsd/src/atoms.proto"; +import "frameworks/proto_logging/stats/atoms.proto"; message DimensionsValue { optional int32 field = 1; diff --git a/cmds/statsd/tests/LogEvent_test.cpp b/cmds/statsd/tests/LogEvent_test.cpp index 5c170c07eb7d..bde59f497b19 100644 --- a/cmds/statsd/tests/LogEvent_test.cpp +++ b/cmds/statsd/tests/LogEvent_test.cpp @@ -16,8 +16,8 @@ #include <gtest/gtest.h> -#include "frameworks/base/cmds/statsd/src/atoms.pb.h" -#include "frameworks/base/core/proto/android/stats/launcher/launcher.pb.h" +#include "frameworks/proto_logging/stats/atoms.pb.h" +#include "frameworks/proto_logging/stats/enums/stats/launcher/launcher.pb.h" #include "log/log_event_list.h" #include "stats_event.h" diff --git a/cmds/statsd/tests/shell/ShellSubscriber_test.cpp b/cmds/statsd/tests/shell/ShellSubscriber_test.cpp index 4fa4135e983f..1ba8593231b0 100644 --- a/cmds/statsd/tests/shell/ShellSubscriber_test.cpp +++ b/cmds/statsd/tests/shell/ShellSubscriber_test.cpp @@ -20,9 +20,9 @@ #include <vector> -#include "frameworks/base/cmds/statsd/src/atoms.pb.h" #include "frameworks/base/cmds/statsd/src/shell/shell_config.pb.h" #include "frameworks/base/cmds/statsd/src/shell/shell_data.pb.h" +#include "frameworks/proto_logging/stats/atoms.pb.h" #include "stats_event.h" #include "tests/metrics/metrics_test_helper.h" #include "tests/statsd_test_util.h" diff --git a/core/api/current.txt b/core/api/current.txt index 9f7f3917a11f..b86e16fadbb5 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -30583,6 +30583,7 @@ package android.net { method public static long getMobileRxPackets(); method public static long getMobileTxBytes(); method public static long getMobileTxPackets(); + method public static long getRxBytes(@NonNull String); method public static long getRxPackets(@NonNull String); method public static int getThreadStatsTag(); method public static int getThreadStatsUid(); @@ -30590,6 +30591,7 @@ package android.net { method public static long getTotalRxPackets(); method public static long getTotalTxBytes(); method public static long getTotalTxPackets(); + method public static long getTxBytes(@NonNull String); method public static long getTxPackets(@NonNull String); method public static long getUidRxBytes(int); method public static long getUidRxPackets(int); @@ -44553,6 +44555,7 @@ package android.telecom { method public android.telecom.PhoneAccount.Builder toBuilder(); method public void writeToParcel(android.os.Parcel, int); field public static final int CAPABILITY_ADHOC_CONFERENCE_CALLING = 16384; // 0x4000 + field public static final int CAPABILITY_CALL_COMPOSER = 32768; // 0x8000 field public static final int CAPABILITY_CALL_PROVIDER = 2; // 0x2 field public static final int CAPABILITY_CALL_SUBJECT = 64; // 0x40 field public static final int CAPABILITY_CONNECTION_MANAGER = 1; // 0x1 @@ -46862,6 +46865,11 @@ package android.telephony { method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void switchMultiSimConfig(int); method public void updateAvailableNetworks(@NonNull java.util.List<android.telephony.AvailableNetworkInfo>, @Nullable java.util.concurrent.Executor, @Nullable java.util.function.Consumer<java.lang.Integer>); field public static final String ACTION_CARRIER_MESSAGING_CLIENT_SERVICE = "android.telephony.action.CARRIER_MESSAGING_CLIENT_SERVICE"; + field public static final String ACTION_CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE = "android.telephony.action.CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE"; + field public static final String ACTION_CARRIER_SIGNAL_PCO_VALUE = "android.telephony.action.CARRIER_SIGNAL_PCO_VALUE"; + field public static final String ACTION_CARRIER_SIGNAL_REDIRECTED = "android.telephony.action.CARRIER_SIGNAL_REDIRECTED"; + field public static final String ACTION_CARRIER_SIGNAL_REQUEST_NETWORK_FAILED = "android.telephony.action.CARRIER_SIGNAL_REQUEST_NETWORK_FAILED"; + field public static final String ACTION_CARRIER_SIGNAL_RESET = "android.telephony.action.CARRIER_SIGNAL_RESET"; field public static final String ACTION_CONFIGURE_VOICEMAIL = "android.telephony.action.CONFIGURE_VOICEMAIL"; field public static final String ACTION_MULTI_SIM_CONFIG_CHANGED = "android.telephony.action.MULTI_SIM_CONFIG_CHANGED"; field public static final String ACTION_NETWORK_COUNTRY_CHANGED = "android.telephony.action.NETWORK_COUNTRY_CHANGED"; @@ -46904,16 +46912,23 @@ package android.telephony { field public static final int ERI_OFF = 1; // 0x1 field public static final int ERI_ON = 0; // 0x0 field public static final String EXTRA_ACTIVE_SIM_SUPPORTED_COUNT = "android.telephony.extra.ACTIVE_SIM_SUPPORTED_COUNT"; + field public static final String EXTRA_APN_PROTOCOL = "android.telephony.extra.APN_PROTOCOL"; + field public static final String EXTRA_APN_TYPE = "android.telephony.extra.APN_TYPE"; field public static final String EXTRA_CALL_VOICEMAIL_INTENT = "android.telephony.extra.CALL_VOICEMAIL_INTENT"; field public static final String EXTRA_CARRIER_ID = "android.telephony.extra.CARRIER_ID"; field public static final String EXTRA_CARRIER_NAME = "android.telephony.extra.CARRIER_NAME"; + field public static final String EXTRA_DATA_FAIL_CAUSE = "android.telephony.extra.DATA_FAIL_CAUSE"; + field public static final String EXTRA_DEFAULT_NETWORK_AVAILABLE = "android.telephony.extra.DEFAULT_NETWORK_AVAILABLE"; field public static final String EXTRA_HIDE_PUBLIC_SETTINGS = "android.telephony.extra.HIDE_PUBLIC_SETTINGS"; field @Deprecated public static final String EXTRA_INCOMING_NUMBER = "incoming_number"; field public static final String EXTRA_IS_REFRESH = "android.telephony.extra.IS_REFRESH"; field public static final String EXTRA_LAUNCH_VOICEMAIL_SETTINGS_INTENT = "android.telephony.extra.LAUNCH_VOICEMAIL_SETTINGS_INTENT"; field public static final String EXTRA_NETWORK_COUNTRY = "android.telephony.extra.NETWORK_COUNTRY"; field public static final String EXTRA_NOTIFICATION_COUNT = "android.telephony.extra.NOTIFICATION_COUNT"; + field public static final String EXTRA_PCO_ID = "android.telephony.extra.PCO_ID"; + field public static final String EXTRA_PCO_VALUE = "android.telephony.extra.PCO_VALUE"; field public static final String EXTRA_PHONE_ACCOUNT_HANDLE = "android.telephony.extra.PHONE_ACCOUNT_HANDLE"; + field public static final String EXTRA_REDIRECTION_URL = "android.telephony.extra.REDIRECTION_URL"; field public static final String EXTRA_SPECIFIC_CARRIER_ID = "android.telephony.extra.SPECIFIC_CARRIER_ID"; field public static final String EXTRA_SPECIFIC_CARRIER_NAME = "android.telephony.extra.SPECIFIC_CARRIER_NAME"; field public static final String EXTRA_STATE = "state"; diff --git a/core/api/system-current.txt b/core/api/system-current.txt index 0b044bee9e64..7d82f43af975 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -228,6 +228,7 @@ package android { field public static final String SHOW_KEYGUARD_MESSAGE = "android.permission.SHOW_KEYGUARD_MESSAGE"; field public static final String SHUTDOWN = "android.permission.SHUTDOWN"; field public static final String START_ACTIVITIES_FROM_BACKGROUND = "android.permission.START_ACTIVITIES_FROM_BACKGROUND"; + field public static final String START_FOREGROUND_SERVICES_FROM_BACKGROUND = "android.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND"; field public static final String STATUS_BAR_SERVICE = "android.permission.STATUS_BAR_SERVICE"; field public static final String STOP_APP_SWITCHES = "android.permission.STOP_APP_SWITCHES"; field public static final String SUBSTITUTE_NOTIFICATION_APP_NAME = "android.permission.SUBSTITUTE_NOTIFICATION_APP_NAME"; @@ -603,7 +604,7 @@ package android.app { method public static android.app.BroadcastOptions makeBasic(); method @RequiresPermission(android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND) public void setBackgroundActivityStartsAllowed(boolean); method public void setDontSendToRestrictedApps(boolean); - method @RequiresPermission(android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST) public void setTemporaryAppWhitelistDuration(long); + method @RequiresPermission(anyOf={android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST, android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND, android.Manifest.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND}) public void setTemporaryAppWhitelistDuration(long); method public android.os.Bundle toBundle(); } @@ -1764,6 +1765,7 @@ package android.content { field public static final String BACKUP_SERVICE = "backup"; field public static final String BATTERY_STATS_SERVICE = "batterystats"; field public static final int BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS = 1048576; // 0x100000 + field public static final int BIND_ALLOW_FOREGROUND_SERVICE_STARTS_FROM_BACKGROUND = 262144; // 0x40000 field public static final String BUGREPORT_SERVICE = "bugreport"; field public static final String CONTENT_SUGGESTIONS_SERVICE = "content_suggestions"; field public static final String CONTEXTHUB_SERVICE = "contexthub"; @@ -2280,6 +2282,7 @@ package android.content.pm { field public static final int PROTECTION_FLAG_DOCUMENTER = 262144; // 0x40000 field public static final int PROTECTION_FLAG_INCIDENT_REPORT_APPROVER = 1048576; // 0x100000 field public static final int PROTECTION_FLAG_OEM = 16384; // 0x4000 + field public static final int PROTECTION_FLAG_RECENTS = 33554432; // 0x2000000 field public static final int PROTECTION_FLAG_RETAIL_DEMO = 16777216; // 0x1000000 field public static final int PROTECTION_FLAG_SYSTEM_TEXT_CLASSIFIER = 65536; // 0x10000 field public static final int PROTECTION_FLAG_WELLBEING = 131072; // 0x20000 diff --git a/core/api/test-current.txt b/core/api/test-current.txt index 52a79bae6324..5434bcca0575 100644 --- a/core/api/test-current.txt +++ b/core/api/test-current.txt @@ -832,6 +832,14 @@ package android.hardware.soundtrigger { } +package android.inputmethodservice { + + public class InputMethodService extends android.inputmethodservice.AbstractInputMethodService { + field public static final long FINISH_INPUT_NO_FALLBACK_CONNECTION = 156215187L; // 0x94fa793L + } + +} + package android.location { public final class GnssClock implements android.os.Parcelable { @@ -2082,12 +2090,15 @@ package android.view { } public interface WindowManager extends android.view.ViewManager { + method public default int getDisplayImePolicy(int); method public default void holdLock(android.os.IBinder, int); - method public default void setShouldShowIme(int, boolean); + method public default void setDisplayImePolicy(int, int); method public default void setShouldShowSystemDecors(int, boolean); method public default void setShouldShowWithInsecureKeyguard(int, boolean); - method public default boolean shouldShowIme(int); method public default boolean shouldShowSystemDecors(int); + field public static final int DISPLAY_IME_POLICY_FALLBACK_DISPLAY = 1; // 0x1 + field public static final int DISPLAY_IME_POLICY_HIDE = 2; // 0x2 + field public static final int DISPLAY_IME_POLICY_LOCAL = 0; // 0x0 } public static class WindowManager.LayoutParams extends android.view.ViewGroup.LayoutParams implements android.os.Parcelable { diff --git a/core/java/android/app/BroadcastOptions.java b/core/java/android/app/BroadcastOptions.java index 03dca30f8560..298c45582174 100644 --- a/core/java/android/app/BroadcastOptions.java +++ b/core/java/android/app/BroadcastOptions.java @@ -90,7 +90,9 @@ public class BroadcastOptions { * power allowlist when this broadcast is being delivered to it. * @param duration The duration in milliseconds; 0 means to not place on allowlist. */ - @RequiresPermission(android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST) + @RequiresPermission(anyOf = {android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST, + android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND, + android.Manifest.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND}) public void setTemporaryAppWhitelistDuration(long duration) { mTemporaryAppWhitelistDuration = duration; } diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index 2bf5368b691b..a886beddf64c 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -4901,7 +4901,7 @@ public class Notification implements Parcelable bindNotificationHeader(contentView, p); bindLargeIconAndApplyMargin(contentView, p, result); boolean showProgress = handleProgressBar(contentView, ex, p); - if (p.title != null && p.title.length() > 0 && !p.mHasCustomContent) { + if (p.hasTitle()) { contentView.setViewVisibility(R.id.title, View.VISIBLE); contentView.setTextViewText(R.id.title, processTextSpans(p.title)); setTextViewColorPrimary(contentView, R.id.title, p); @@ -4909,7 +4909,7 @@ public class Notification implements Parcelable ? ViewGroup.LayoutParams.WRAP_CONTENT : ViewGroup.LayoutParams.MATCH_PARENT); } - if (p.text != null) { + if (p.text != null && p.text.length() != 0) { int textId = showProgress ? com.android.internal.R.id.text_line_1 : com.android.internal.R.id.text; contentView.setTextViewText(textId, processTextSpans(p.text)); @@ -5296,7 +5296,7 @@ public class Notification implements Parcelable contentView.setViewVisibility(R.id.app_name_text, View.GONE); return false; } - if (p.mHeaderless && !p.mHasCustomContent) { + if (p.mHeaderless && p.hasTitle()) { contentView.setViewVisibility(R.id.app_name_text, View.GONE); // the headerless template will have the TITLE in this position; return true to // keep the divider visible between that title and the next text element. @@ -11073,6 +11073,10 @@ public class Notification implements Parcelable return this; } + final boolean hasTitle() { + return title != null && title.length() != 0 && !mHasCustomContent; + } + final StandardTemplateParams viewType(int viewType) { mViewType = viewType; return this; diff --git a/core/java/android/app/Service.java b/core/java/android/app/Service.java index b96b54ad8d21..3798de921dc7 100644 --- a/core/java/android/app/Service.java +++ b/core/java/android/app/Service.java @@ -697,6 +697,10 @@ public abstract class Service extends ContextWrapper implements ComponentCallbac * service element of manifest file. The value of attribute * {@link android.R.attr#foregroundServiceType} can be multiple flags ORed together.</p> * + * @throws IllegalStateException If the app targeting API is + * {@link android.os.Build.VERSION_CODES#S} or later, and the service is restricted from + * becoming foreground service due to background restriction. + * * @param id The identifier for this notification as per * {@link NotificationManager#notify(int, Notification) * NotificationManager.notify(int, Notification)}; must not be 0. diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index 16ae081049ef..42427fa825eb 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -6436,6 +6436,8 @@ public class DevicePolicyManager { } /** + * Called by a privileged caller holding {@code BIND_DEVICE_ADMIN} permission to retrieve + * the remove warning for the given device admin. * @hide */ public void getRemoveWarning(@Nullable ComponentName admin, RemoteCallback result) { @@ -8505,6 +8507,8 @@ public class DevicePolicyManager { * it previously set with {@link #addUserRestriction(ComponentName, String)}. * * @param admin Which {@link DeviceAdminReceiver} this request is associated with. + * @return a {@link Bundle} whose keys are the user restrictions, and the values a + * {@code boolean} indicating whether the restriction is set. * @throws SecurityException if {@code admin} is not a device or profile owner. */ public @NonNull Bundle getUserRestrictions(@NonNull ComponentName admin) { diff --git a/core/java/android/bluetooth/BluetoothCodecStatus.java b/core/java/android/bluetooth/BluetoothCodecStatus.java index 3a65aaa0d16c..7764ebeb2e33 100644 --- a/core/java/android/bluetooth/BluetoothCodecStatus.java +++ b/core/java/android/bluetooth/BluetoothCodecStatus.java @@ -18,7 +18,6 @@ package android.bluetooth; import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; -import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -40,7 +39,7 @@ public final class BluetoothCodecStatus implements Parcelable { * This extra represents the current codec status of the A2DP * profile. */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) + @UnsupportedAppUsage public static final String EXTRA_CODEC_STATUS = "android.bluetooth.extra.CODEC_STATUS"; @@ -199,7 +198,7 @@ public final class BluetoothCodecStatus implements Parcelable { * * @return the current codec configuration */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) + @UnsupportedAppUsage public @Nullable BluetoothCodecConfig getCodecConfig() { return mCodecConfig; } @@ -209,7 +208,7 @@ public final class BluetoothCodecStatus implements Parcelable { * * @return an array with the codecs local capabilities */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) + @UnsupportedAppUsage public @Nullable BluetoothCodecConfig[] getCodecsLocalCapabilities() { return mCodecsLocalCapabilities; } @@ -219,7 +218,7 @@ public final class BluetoothCodecStatus implements Parcelable { * * @return an array with the codecs selectable capabilities */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) + @UnsupportedAppUsage public @Nullable BluetoothCodecConfig[] getCodecsSelectableCapabilities() { return mCodecsSelectableCapabilities; } diff --git a/core/java/android/companion/OWNERS b/core/java/android/companion/OWNERS new file mode 100644 index 000000000000..da723b3b67da --- /dev/null +++ b/core/java/android/companion/OWNERS @@ -0,0 +1 @@ +eugenesusla@google.com
\ No newline at end of file diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index 6a3f6b4034ff..8f92bf1e3253 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -367,6 +367,16 @@ public abstract class Context { /*********** Hidden flags below this line ***********/ /** + * Flag for {@link #bindService}: allow background foreground service starts from the bound + * service's process. + * This flag is only respected if the caller is holding + * {@link android.Manifest.permission#START_FOREGROUND_SERVICES_FROM_BACKGROUND}. + * @hide + */ + @SystemApi + public static final int BIND_ALLOW_FOREGROUND_SERVICE_STARTS_FROM_BACKGROUND = 0x00040000; + + /** * Flag for {@link #bindService}: This flag is intended to be used only by the system to adjust * the scheduling policy for IMEs (and any other out-of-process user-visible components that * work closely with the top app) so that UI hosted in such services can have the same @@ -3107,6 +3117,10 @@ public abstract class Context { * @throws SecurityException If the caller does not have permission to access the service * or the service can not be found. * + * @throws IllegalStateException If the caller app's targeting API is + * {@link android.os.Build.VERSION_CODES#S} or later, and the foreground service is restricted + * from start due to background restriction. + * * @see #stopService * @see android.app.Service#startForeground(int, android.app.Notification) */ diff --git a/core/java/android/content/pm/PermissionInfo.java b/core/java/android/content/pm/PermissionInfo.java index c6450ffdf91c..cd9ba6a5b451 100644 --- a/core/java/android/content/pm/PermissionInfo.java +++ b/core/java/android/content/pm/PermissionInfo.java @@ -251,6 +251,16 @@ public class PermissionInfo extends PackageItemInfo implements Parcelable { @SystemApi public static final int PROTECTION_FLAG_RETAIL_DEMO = 0x1000000; + /** + * Additional flag for {@link #protectionLevel}, corresponding + * to the <code>recents</code> value of + * {@link android.R.attr#protectionLevel}. + * + * @hide + */ + @SystemApi + public static final int PROTECTION_FLAG_RECENTS = 0x2000000; + /** @hide */ @IntDef(flag = true, prefix = { "PROTECTION_FLAG_" }, value = { PROTECTION_FLAG_PRIVILEGED, @@ -274,6 +284,7 @@ public class PermissionInfo extends PackageItemInfo implements Parcelable { PROTECTION_FLAG_APP_PREDICTOR, PROTECTION_FLAG_COMPANION, PROTECTION_FLAG_RETAIL_DEMO, + PROTECTION_FLAG_RECENTS, }) @Retention(RetentionPolicy.SOURCE) public @interface ProtectionFlags {} @@ -532,6 +543,9 @@ public class PermissionInfo extends PackageItemInfo implements Parcelable { if ((level & PermissionInfo.PROTECTION_FLAG_RETAIL_DEMO) != 0) { protLevel.append("|retailDemo"); } + if ((level & PermissionInfo.PROTECTION_FLAG_RECENTS) != 0) { + protLevel.append("|recents"); + } return protLevel.toString(); } diff --git a/core/java/android/hardware/biometrics/SensorPropertiesInternal.java b/core/java/android/hardware/biometrics/SensorPropertiesInternal.java index 2189de0827b7..0b81c6c8cc25 100644 --- a/core/java/android/hardware/biometrics/SensorPropertiesInternal.java +++ b/core/java/android/hardware/biometrics/SensorPropertiesInternal.java @@ -16,13 +16,10 @@ package android.hardware.biometrics; -import android.annotation.IntDef; +import android.annotation.NonNull; import android.os.Parcel; import android.os.Parcelable; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - /** * The base class containing all modality-agnostic information. This is a superset of the * {@link android.hardware.biometrics.common.CommonProps}, and provides backwards-compatible @@ -35,6 +32,11 @@ public class SensorPropertiesInternal implements Parcelable { @SensorProperties.Strength public final int sensorStrength; public final int maxEnrollmentsPerUser; + public static SensorPropertiesInternal from(@NonNull SensorPropertiesInternal prop) { + return new SensorPropertiesInternal(prop.sensorId, prop.sensorStrength, + prop.maxEnrollmentsPerUser); + } + protected SensorPropertiesInternal(int sensorId, @SensorProperties.Strength int sensorStrength, int maxEnrollmentsPerUser) { this.sensorId = sensorId; @@ -72,4 +74,10 @@ public class SensorPropertiesInternal implements Parcelable { dest.writeInt(sensorStrength); dest.writeInt(maxEnrollmentsPerUser); } + + @Override + public String toString() { + return "ID: " + sensorId + ", Strength: " + sensorStrength + + ", MaxEnrollmentsPerUser: " + maxEnrollmentsPerUser; + } } diff --git a/core/java/android/hardware/display/DisplayManagerGlobal.java b/core/java/android/hardware/display/DisplayManagerGlobal.java index b046d1df5b8c..7b4889f0a1b3 100644 --- a/core/java/android/hardware/display/DisplayManagerGlobal.java +++ b/core/java/android/hardware/display/DisplayManagerGlobal.java @@ -358,7 +358,7 @@ public final class DisplayManagerGlobal { // listener. DisplayInfo display = getDisplayInfoLocked(displayId); if (display != null) { - float refreshRate = display.getMode().getRefreshRate(); + float refreshRate = display.getRefreshRate(); // Signal native callbacks if we ever set a refresh rate. nSignalNativeCallbacks(refreshRate); } @@ -862,7 +862,7 @@ public final class DisplayManagerGlobal { if (display != null) { // We need to tell AChoreographer instances the current refresh rate so that apps // can get it for free once a callback first registers. - float refreshRate = display.getMode().getRefreshRate(); + float refreshRate = display.getRefreshRate(); nSignalNativeCallbacks(refreshRate); } } diff --git a/core/java/android/hardware/face/FaceSensorPropertiesInternal.java b/core/java/android/hardware/face/FaceSensorPropertiesInternal.java index e91554b532b0..b9c0d12de22b 100644 --- a/core/java/android/hardware/face/FaceSensorPropertiesInternal.java +++ b/core/java/android/hardware/face/FaceSensorPropertiesInternal.java @@ -19,7 +19,6 @@ package android.hardware.face; import android.hardware.biometrics.SensorProperties; import android.hardware.biometrics.SensorPropertiesInternal; import android.os.Parcel; -import android.os.Parcelable; /** * Container for face sensor properties. @@ -78,4 +77,9 @@ public class FaceSensorPropertiesInternal extends SensorPropertiesInternal { dest.writeBoolean(supportsFaceDetection); dest.writeBoolean(supportsSelfIllumination); } + + @Override + public String toString() { + return "ID: " + sensorId + ", Strength: " + sensorStrength; + } } diff --git a/core/java/android/hardware/input/InputManager.java b/core/java/android/hardware/input/InputManager.java index 7fb73ceab4f4..81ea2f5a17dd 100644 --- a/core/java/android/hardware/input/InputManager.java +++ b/core/java/android/hardware/input/InputManager.java @@ -56,6 +56,7 @@ import android.view.PointerIcon; import android.view.VerifiedInputEvent; import android.view.WindowManager.LayoutParams; +import com.android.internal.annotations.VisibleForTesting; import com.android.internal.os.SomeArgs; import com.android.internal.util.ArrayUtils; @@ -275,6 +276,21 @@ public final class InputManager { * * @hide */ + @VisibleForTesting + public static InputManager resetInstance(IInputManager inputManagerService) { + synchronized (InputManager.class) { + sInstance = new InputManager(inputManagerService); + return sInstance; + } + } + + /** + * Gets an instance of the input manager. + * + * @return The input manager instance. + * + * @hide + */ @UnsupportedAppUsage public static InputManager getInstance() { synchronized (InputManager.class) { @@ -1428,7 +1444,7 @@ public final class InputManager { @Override public boolean hasAmplitudeControl() { - return false; + return true; } /** diff --git a/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java b/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java index e9de27456f97..0766917642e8 100644 --- a/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java +++ b/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java @@ -54,6 +54,8 @@ class IInputMethodSessionWrapper extends IInputMethodSession.Stub private static final int DO_VIEW_CLICKED = 115; private static final int DO_NOTIFY_IME_HIDDEN = 120; private static final int DO_REMOVE_IME_SURFACE = 130; + private static final int DO_FINISH_INPUT = 140; + @UnsupportedAppUsage HandlerCaller mCaller; @@ -141,6 +143,10 @@ class IInputMethodSessionWrapper extends IInputMethodSession.Stub mInputMethodSession.removeImeSurface(); return; } + case DO_FINISH_INPUT: { + mInputMethodSession.finishInput(); + return; + } } Log.w(TAG, "Unhandled message code: " + msg.what); } @@ -222,6 +228,10 @@ class IInputMethodSessionWrapper extends IInputMethodSession.Stub mCaller.executeOrSendMessage(mCaller.obtainMessage(DO_FINISH_SESSION)); } + @Override + public void finishInput() { + mCaller.executeOrSendMessage(mCaller.obtainMessage(DO_FINISH_INPUT)); + } private final class ImeInputEventReceiver extends InputEventReceiver implements InputMethodSession.EventCallback { private final SparseArray<InputEvent> mPendingEvents = new SparseArray<InputEvent>(); diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java index ae260e16806f..4a5d831cd705 100644 --- a/core/java/android/inputmethodservice/InputMethodService.java +++ b/core/java/android/inputmethodservice/InputMethodService.java @@ -61,9 +61,12 @@ import android.annotation.IntDef; import android.annotation.MainThread; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.TestApi; import android.annotation.UiContext; import android.app.ActivityManager; import android.app.Dialog; +import android.compat.annotation.ChangeId; +import android.compat.annotation.EnabledSince; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.pm.PackageManager; @@ -411,7 +414,29 @@ public class InputMethodService extends AbstractInputMethodService { @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) int mTheme = 0; - + + /** + * Finish the {@link InputConnection} when the device becomes + * {@link android.os.PowerManager#isInteractive non-interactive}. + * + * <p> + * If enabled by the current {@link InputMethodService input method}, the current input + * connection will be {@link InputMethodService#onFinishInput finished} whenever the devices + * becomes non-interactive. + * + * <p> + * If not enabled, the current input connection will instead be silently deactivated when the + * devices becomes non-interactive, and an {@link InputMethodService#onFinishInput + * onFinishInput()} {@link InputMethodService#onStartInput onStartInput()} pair is dispatched + * when the device becomes interactive again. + * + * @hide + */ + @TestApi + @ChangeId + @EnabledSince(targetSdkVersion = Build.VERSION_CODES.S) + public static final long FINISH_INPUT_NO_FALLBACK_CONNECTION = 156215187L; // This is a bug id. + LayoutInflater mInflater; TypedArray mThemeAttrs; @UnsupportedAppUsage @@ -2325,7 +2350,7 @@ public class InputMethodService extends AbstractInputMethodService { } void doStartInput(InputConnection ic, EditorInfo attribute, boolean restarting) { - if (!restarting) { + if (!restarting && mInputStarted) { doFinishInput(); } ImeTracing.getInstance().triggerServiceDump("InputMethodService#doStartInput", this); diff --git a/core/java/android/inputmethodservice/MultiClientInputMethodClientCallbackAdaptor.java b/core/java/android/inputmethodservice/MultiClientInputMethodClientCallbackAdaptor.java index dbb669be1402..2db9ed1103fa 100644 --- a/core/java/android/inputmethodservice/MultiClientInputMethodClientCallbackAdaptor.java +++ b/core/java/android/inputmethodservice/MultiClientInputMethodClientCallbackAdaptor.java @@ -23,6 +23,7 @@ import android.os.Bundle; import android.os.Debug; import android.os.Handler; import android.os.Looper; +import android.os.RemoteException; import android.os.ResultReceiver; import android.util.Log; import android.view.InputChannel; @@ -38,8 +39,8 @@ import android.view.inputmethod.EditorInfo; import android.view.inputmethod.ExtractedText; import com.android.internal.annotations.GuardedBy; -import com.android.internal.inputmethod.IMultiClientInputMethodSession; import com.android.internal.inputmethod.CancellationGroup; +import com.android.internal.inputmethod.IMultiClientInputMethodSession; import com.android.internal.os.SomeArgs; import com.android.internal.util.function.pooled.PooledLambda; import com.android.internal.view.IInputContext; @@ -303,6 +304,12 @@ final class MultiClientInputMethodClientCallbackAdaptor { // no-op for multi-session reportNotSupported(); } + + @Override + public void finishInput() throws RemoteException { + // no-op for multi-session + reportNotSupported(); + } } private static final class MultiClientInputMethodSessionImpl diff --git a/core/java/android/net/TrafficStats.java b/core/java/android/net/TrafficStats.java index 4e019cf0732e..fa650617f380 100644 --- a/core/java/android/net/TrafficStats.java +++ b/core/java/android/net/TrafficStats.java @@ -597,10 +597,17 @@ public class TrafficStats { } /** - * Return the number of packets transmitted on the specified interface since - * device boot. Statistics are measured at the network layer, so both TCP and + * Return the number of packets transmitted on the specified interface since the interface + * was created. Statistics are measured at the network layer, so both TCP and * UDP usage are included. * + * Note that the returned values are partial statistics that do not count data from several + * sources and do not apply several adjustments that are necessary for correctness, such + * as adjusting for VPN apps, IPv6-in-IPv4 translation, etc. These values can be used to + * determine whether traffic is being transferred on the specific interface but are not a + * substitute for the more accurate statistics provided by the {@link NetworkStatsManager} + * APIs. + * * @param iface The name of the interface. * @return The number of transmitted packets. */ @@ -613,10 +620,17 @@ public class TrafficStats { } /** - * Return the number of packets received on the specified interface since - * device boot. Statistics are measured at the network layer, so both TCP + * Return the number of packets received on the specified interface since the interface was + * created. Statistics are measured at the network layer, so both TCP * and UDP usage are included. * + * Note that the returned values are partial statistics that do not count data from several + * sources and do not apply several adjustments that are necessary for correctness, such + * as adjusting for VPN apps, IPv6-in-IPv4 translation, etc. These values can be used to + * determine whether traffic is being transferred on the specific interface but are not a + * substitute for the more accurate statistics provided by the {@link NetworkStatsManager} + * APIs. + * * @param iface The name of the interface. * @return The number of received packets. */ @@ -628,9 +642,22 @@ public class TrafficStats { } } - /** {@hide} */ - @UnsupportedAppUsage - public static long getTxBytes(String iface) { + /** + * Return the number of bytes transmitted on the specified interface since the interface + * was created. Statistics are measured at the network layer, so both TCP and + * UDP usage are included. + * + * Note that the returned values are partial statistics that do not count data from several + * sources and do not apply several adjustments that are necessary for correctness, such + * as adjusting for VPN apps, IPv6-in-IPv4 translation, etc. These values can be used to + * determine whether traffic is being transferred on the specific interface but are not a + * substitute for the more accurate statistics provided by the {@link NetworkStatsManager} + * APIs. + * + * @param iface The name of the interface. + * @return The number of transmitted bytes. + */ + public static long getTxBytes(@NonNull String iface) { try { return getStatsService().getIfaceStats(iface, TYPE_TX_BYTES); } catch (RemoteException e) { @@ -638,9 +665,22 @@ public class TrafficStats { } } - /** {@hide} */ - @UnsupportedAppUsage - public static long getRxBytes(String iface) { + /** + * Return the number of bytes received on the specified interface since the interface + * was created. Statistics are measured at the network layer, so both TCP + * and UDP usage are included. + * + * Note that the returned values are partial statistics that do not count data from several + * sources and do not apply several adjustments that are necessary for correctness, such + * as adjusting for VPN apps, IPv6-in-IPv4 translation, etc. These values can be used to + * determine whether traffic is being transferred on the specific interface but are not a + * substitute for the more accurate statistics provided by the {@link NetworkStatsManager} + * APIs. + * + * @param iface The name of the interface. + * @return The number of received bytes. + */ + public static long getRxBytes(@NonNull String iface) { try { return getStatsService().getIfaceStats(iface, TYPE_RX_BYTES); } catch (RemoteException e) { diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java index 00023a5caf75..9c2ae4e7c48a 100644 --- a/core/java/android/os/BatteryStats.java +++ b/core/java/android/os/BatteryStats.java @@ -2481,6 +2481,29 @@ public abstract class BatteryStats implements Parcelable { "group", "compl", "dorm", "uninit" }; + /** + * Returned value if energy data is unavailable + * + * {@hide} + */ + public static final long ENERGY_DATA_UNAVAILABLE = -1; + + /** + * Returns the energy in microjoules that the screen consumed while on. + * Will return {@link #ENERGY_DATA_UNAVAILABLE} if data is unavailable + * + * {@hide} + */ + public abstract long getScreenOnEnergy(); + + /** + * Returns the energy in microjoules that the screen consumed while in doze + * Will return {@link #ENERGY_DATA_UNAVAILABLE} if data is unavailable + * + * {@hide} + */ + public abstract long getScreenDozeEnergy(); + public static final BitDescription[] HISTORY_STATE_DESCRIPTIONS = new BitDescription[] { new BitDescription(HistoryItem.STATE_CPU_RUNNING_FLAG, "running", "r"), new BitDescription(HistoryItem.STATE_WAKE_LOCK_FLAG, "wake_lock", "w"), diff --git a/core/java/android/os/ParcelableHolder.java b/core/java/android/os/ParcelableHolder.java index 95c07b6b2451..fb9fa109bfa3 100644 --- a/core/java/android/os/ParcelableHolder.java +++ b/core/java/android/os/ParcelableHolder.java @@ -170,16 +170,21 @@ public final class ParcelableHolder implements Parcelable { mParcelable = null; + int dataSize = parcel.readInt(); + if (dataSize < 0) { + throw new IllegalArgumentException("dataSize from parcel is negative"); + } else if (dataSize == 0) { + if (mParcel != null) { + mParcel.recycle(); + mParcel = null; + } + return; + } if (mParcel == null) { mParcel = Parcel.obtain(); } mParcel.setDataPosition(0); mParcel.setDataSize(0); - - int dataSize = parcel.readInt(); - if (dataSize < 0) { - throw new IllegalArgumentException("dataSize from parcel is negative"); - } int dataStartPos = parcel.dataPosition(); mParcel.appendFrom(parcel, dataStartPos, dataSize); @@ -196,6 +201,11 @@ public final class ParcelableHolder implements Parcelable { return; } + if (mParcelable == null) { + parcel.writeInt(0); + return; + } + int sizePos = parcel.dataPosition(); parcel.writeInt(0); int dataStartPos = parcel.dataPosition(); diff --git a/core/java/android/security/keymaster/KeymasterDefs.java b/core/java/android/security/keymaster/KeymasterDefs.java index e32ffa6e9d05..18921639f55d 100644 --- a/core/java/android/security/keymaster/KeymasterDefs.java +++ b/core/java/android/security/keymaster/KeymasterDefs.java @@ -94,6 +94,8 @@ public final class KeymasterDefs { public static final int KM_TAG_ATTESTATION_ID_MEID = KM_BYTES | 715; public static final int KM_TAG_ATTESTATION_ID_MANUFACTURER = KM_BYTES | 716; public static final int KM_TAG_ATTESTATION_ID_MODEL = KM_BYTES | 717; + public static final int KM_TAG_VENDOR_PATCHLEVEL = KM_UINT | 718; + public static final int KM_TAG_BOOT_PATCHLEVEL = KM_UINT | 719; public static final int KM_TAG_DEVICE_UNIQUE_ATTESTATION = KM_BOOL | 720; public static final int KM_TAG_ASSOCIATED_DATA = KM_BYTES | 1000; diff --git a/core/java/android/view/Choreographer.java b/core/java/android/view/Choreographer.java index 3da3184afae1..59299f6b15eb 100644 --- a/core/java/android/view/Choreographer.java +++ b/core/java/android/view/Choreographer.java @@ -276,7 +276,7 @@ public final class Choreographer { private static float getRefreshRate() { DisplayInfo di = DisplayManagerGlobal.getInstance().getDisplayInfo( Display.DEFAULT_DISPLAY); - return di.getMode().getRefreshRate(); + return di.getRefreshRate(); } /** @@ -944,7 +944,7 @@ public final class Choreographer { private VsyncEventData mLastVsyncEventData = new VsyncEventData(); public FrameDisplayEventReceiver(Looper looper, int vsyncSource) { - super(looper, vsyncSource, CONFIG_CHANGED_EVENT_SUPPRESS); + super(looper, vsyncSource, 0); } // TODO(b/116025192): physicalDisplayId is ignored because SF only emits VSYNC events for diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java index 3021aa6a0783..56c7e27151e0 100644 --- a/core/java/android/view/Display.java +++ b/core/java/android/view/Display.java @@ -456,6 +456,9 @@ public final class Display { // TODO (b/114338689): Remove the flag and use WindowManager#REMOVE_CONTENT_MODE_DESTROY public static final int REMOVE_MODE_DESTROY_CONTENT = 1; + /** @hide */ + public static final int DISPLAY_MODE_ID_FOR_FRAME_RATE_OVERRIDE = 0xFF; + /** * Internal method to create a display. * The display created with this method will have a static {@link DisplayAdjustments} applied. @@ -886,7 +889,7 @@ public final class Display { public float getRefreshRate() { synchronized (this) { updateDisplayInfoLocked(); - return mDisplayInfo.getMode().getRefreshRate(); + return mDisplayInfo.getRefreshRate(); } } @@ -1391,6 +1394,23 @@ public final class Display { } /** + * Returns true if the display is in an off state such as {@link #STATE_OFF}. + * @hide + */ + public static boolean isOffState(int state) { + return state == STATE_OFF; + } + + /** + * Returns true if the display is in an on state such as {@link #STATE_ON} + * or {@link #STATE_VR} or {@link #STATE_ON_SUSPEND}. + * @hide + */ + public static boolean isOnState(int state) { + return state == STATE_ON || state == STATE_VR || state == STATE_ON_SUSPEND; + } + + /** * A mode supported by a given display. * * @see Display#getSupportedModes() @@ -1509,6 +1529,16 @@ public final class Display { Float.floatToIntBits(mRefreshRate) == Float.floatToIntBits(refreshRate); } + /** + * Returns {@code true} if this mode equals to the other mode in all parameters except + * the refresh rate. + * + * @hide + */ + public boolean equalsExceptRefreshRate(@Nullable Display.Mode other) { + return mWidth == other.mWidth && mHeight == other.mHeight; + } + @Override public boolean equals(@Nullable Object other) { if (this == other) { diff --git a/core/java/android/view/DisplayEventReceiver.java b/core/java/android/view/DisplayEventReceiver.java index e8a4ed44b7c8..5d4a4e52975a 100644 --- a/core/java/android/view/DisplayEventReceiver.java +++ b/core/java/android/view/DisplayEventReceiver.java @@ -23,6 +23,8 @@ import android.os.Looper; import android.os.MessageQueue; import android.util.Log; +import com.android.internal.annotations.VisibleForTesting; + import dalvik.annotation.optimization.FastNative; import dalvik.system.CloseGuard; @@ -56,18 +58,18 @@ public abstract class DisplayEventReceiver { public static final int VSYNC_SOURCE_SURFACE_FLINGER = 1; /** - * Specifies to suppress config changed events from being generated from Surface Flinger. + * Specifies to generate config changed events from Surface Flinger. * <p> * Needs to be kept in sync with frameworks/native/include/gui/ISurfaceComposer.h */ - public static final int CONFIG_CHANGED_EVENT_SUPPRESS = 0; + public static final int EVENT_REGISTRATION_CONFIG_CHANGED_FLAG = 0x1; /** - * Specifies to generate config changed events from Surface Flinger. + * Specifies to generate frame rate override events from Surface Flinger. * <p> * Needs to be kept in sync with frameworks/native/include/gui/ISurfaceComposer.h */ - public static final int CONFIG_CHANGED_EVENT_DISPATCH = 1; + public static final int EVENT_REGISTRATION_FRAME_RATE_OVERRIDE_FLAG = 0x2; private static final String TAG = "DisplayEventReceiver"; @@ -81,7 +83,7 @@ public abstract class DisplayEventReceiver { private MessageQueue mMessageQueue; private static native long nativeInit(WeakReference<DisplayEventReceiver> receiver, - MessageQueue messageQueue, int vsyncSource, int configChanged); + MessageQueue messageQueue, int vsyncSource, int eventRegistration); private static native void nativeDispose(long receiverPtr); @FastNative private static native void nativeScheduleVsync(long receiverPtr); @@ -93,7 +95,7 @@ public abstract class DisplayEventReceiver { */ @UnsupportedAppUsage public DisplayEventReceiver(Looper looper) { - this(looper, VSYNC_SOURCE_APP, CONFIG_CHANGED_EVENT_SUPPRESS); + this(looper, VSYNC_SOURCE_APP, 0); } /** @@ -101,17 +103,17 @@ public abstract class DisplayEventReceiver { * * @param looper The looper to use when invoking callbacks. * @param vsyncSource The source of the vsync tick. Must be on of the VSYNC_SOURCE_* values. - * @param configChanged Whether to dispatch config changed events. Must be one of the - * CONFIG_CHANGED_EVENT_* values. + * @param eventRegistration Which events to dispatch. Must be a bitfield consist of the + * EVENT_REGISTRATION_*_FLAG values. */ - public DisplayEventReceiver(Looper looper, int vsyncSource, int configChanged) { + public DisplayEventReceiver(Looper looper, int vsyncSource, int eventRegistration) { if (looper == null) { throw new IllegalArgumentException("looper must not be null"); } mMessageQueue = looper.getQueue(); mReceiverPtr = nativeInit(new WeakReference<DisplayEventReceiver>(this), mMessageQueue, - vsyncSource, configChanged); + vsyncSource, eventRegistration); mCloseGuard.open("dispose"); } @@ -206,6 +208,41 @@ public abstract class DisplayEventReceiver { } /** + * Represents a mapping between a UID and an override frame rate + */ + public static class FrameRateOverride { + // The application uid + public final int uid; + + // The frame rate that this application runs at + public final float frameRateHz; + + + @VisibleForTesting + public FrameRateOverride(int uid, float frameRateHz) { + this.uid = uid; + this.frameRateHz = frameRateHz; + } + + @Override + public String toString() { + return "{uid=" + uid + " frameRateHz=" + frameRateHz + "}"; + } + } + + /** + * Called when frame rate override event is received. + * + * @param timestampNanos The timestamp of the event, in the {@link System#nanoTime()} + * timebase. + * @param physicalDisplayId Stable display ID that uniquely describes a (display, port) pair. + * @param overrides The mappings from uid to frame rates + */ + public void onFrameRateOverridesChanged(long timestampNanos, long physicalDisplayId, + FrameRateOverride[] overrides) { + } + + /** * Schedules a single vertical sync pulse to be delivered when the next * display frame begins. */ @@ -240,4 +277,11 @@ public abstract class DisplayEventReceiver { onConfigChanged(timestampNanos, physicalDisplayId, configId); } + // Called from native code. + @SuppressWarnings("unused") + private void dispatchFrameRateOverrides(long timestampNanos, long physicalDisplayId, + FrameRateOverride[] overrides) { + onFrameRateOverridesChanged(timestampNanos, physicalDisplayId, overrides); + } + } diff --git a/core/java/android/view/DisplayInfo.java b/core/java/android/view/DisplayInfo.java index fe9a1a76bbaf..020160584f67 100644 --- a/core/java/android/view/DisplayInfo.java +++ b/core/java/android/view/DisplayInfo.java @@ -261,6 +261,11 @@ public final class DisplayInfo implements Parcelable { public String ownerPackageName; /** + * The refresh rate override for this app. 0 means no override. + */ + public float refreshRateOverride; + + /** * @hide * Get current remove mode of the display - what actions should be performed with the display's * content when it is removed. @@ -332,7 +337,8 @@ public final class DisplayInfo implements Parcelable { && state == other.state && ownerUid == other.ownerUid && Objects.equals(ownerPackageName, other.ownerPackageName) - && removeMode == other.removeMode; + && removeMode == other.removeMode + && refreshRateOverride == other.refreshRateOverride; } @Override @@ -376,6 +382,7 @@ public final class DisplayInfo implements Parcelable { ownerUid = other.ownerUid; ownerPackageName = other.ownerPackageName; removeMode = other.removeMode; + refreshRateOverride = other.refreshRateOverride; } public void readFromParcel(Parcel source) { @@ -421,6 +428,7 @@ public final class DisplayInfo implements Parcelable { ownerPackageName = source.readString8(); uniqueId = source.readString8(); removeMode = source.readInt(); + refreshRateOverride = source.readFloat(); } @Override @@ -465,6 +473,7 @@ public final class DisplayInfo implements Parcelable { dest.writeString8(ownerPackageName); dest.writeString8(uniqueId); dest.writeInt(removeMode); + dest.writeFloat(refreshRateOverride); } @Override @@ -472,6 +481,17 @@ public final class DisplayInfo implements Parcelable { return 0; } + /** + * Returns the refresh rate the application would experience. + */ + public float getRefreshRate() { + if (refreshRateOverride > 0) { + return refreshRateOverride; + } + + return getMode().getRefreshRate(); + } + public Display.Mode getMode() { return findMode(modeId); } @@ -675,6 +695,9 @@ public final class DisplayInfo implements Parcelable { } sb.append(", removeMode "); sb.append(removeMode); + sb.append(", refreshRateOverride "); + sb.append(refreshRateOverride); + sb.append("}"); return sb.toString(); } diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl index 053353330e4e..1a6eea554cae 100644 --- a/core/java/android/view/IWindowManager.aidl +++ b/core/java/android/view/IWindowManager.aidl @@ -648,24 +648,24 @@ interface IWindowManager void setShouldShowSystemDecors(int displayId, boolean shouldShow); /** - * Indicates that the display should show IME. + * Indicates the policy for how the display should show IME. * * @param displayId The id of the display. - * @return {@code true} if the display should show IME. + * @return The policy for how the display should show IME. * @see KeyguardManager#isDeviceSecure() * @see KeyguardManager#isDeviceLocked() */ - boolean shouldShowIme(int displayId); + int getDisplayImePolicy(int displayId); /** - * Sets that the display should show IME. + * Sets the policy for how the display should show IME. * * @param displayId The id of the display. - * @param shouldShow Indicates that the display should show IME. + * @param imePolicy Indicates the policy for how the display should show IME. * @see KeyguardManager#isDeviceSecure() * @see KeyguardManager#isDeviceLocked() */ - void setShouldShowIme(int displayId, boolean shouldShow); + void setDisplayImePolicy(int displayId, int imePolicy); /** * Waits for transactions to get applied before injecting input, optionally waiting for diff --git a/core/java/android/view/ImeFocusController.java b/core/java/android/view/ImeFocusController.java index efc0bd2785f4..4a5c95f43d46 100644 --- a/core/java/android/view/ImeFocusController.java +++ b/core/java/android/view/ImeFocusController.java @@ -222,6 +222,25 @@ public final class ImeFocusController { } /** + * To handle the lifecycle of the input connection when the device interactivity state changed. + * (i.e. Calling IMS#onFinishInput when the device screen-off and Calling IMS#onStartInput + * when the device screen-on again). + */ + @UiThread + public void onInteractiveChanged(boolean interactive) { + final InputMethodManagerDelegate immDelegate = getImmDelegate(); + if (!immDelegate.isCurrentRootView(mViewRootImpl)) { + return; + } + if (interactive) { + final View focusedView = mViewRootImpl.mView.findFocus(); + onViewFocusChanged(focusedView, focusedView != null); + } else { + mDelegate.finishInputAndReportToIme(); + } + } + + /** * @param windowAttribute {@link WindowManager.LayoutParams} to be checked. * @return Whether the window is in local focus mode or not. */ @@ -256,6 +275,7 @@ public final class ImeFocusController { @WindowManager.LayoutParams.SoftInputModeFlags int softInputMode, int windowFlags, boolean forceNewFocus); void finishInput(); + void finishInputAndReportToIme(); void closeCurrentIme(); void finishComposingText(); void setCurrentRootView(ViewRootImpl rootView); diff --git a/core/java/android/view/InputDevice.java b/core/java/android/view/InputDevice.java index 22ac4dcd2cfe..8da833a28efa 100644 --- a/core/java/android/view/InputDevice.java +++ b/core/java/android/view/InputDevice.java @@ -29,6 +29,8 @@ import android.os.Parcel; import android.os.Parcelable; import android.os.Vibrator; +import com.android.internal.annotations.VisibleForTesting; + import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; @@ -423,9 +425,13 @@ public final class InputDevice implements Parcelable { } }; - // Called by native code. + /** + * Called by native code + * @hide + */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) - private InputDevice(int id, int generation, int controllerNumber, String name, int vendorId, + @VisibleForTesting + public InputDevice(int id, int generation, int controllerNumber, String name, int vendorId, int productId, String descriptor, boolean isExternal, int sources, int keyboardType, KeyCharacterMap keyCharacterMap, boolean hasVibrator, boolean hasMicrophone, boolean hasButtonUnderPad) { diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java index 436acef17c4d..d0a7c26741c7 100644 --- a/core/java/android/view/WindowManager.java +++ b/core/java/android/view/WindowManager.java @@ -461,6 +461,40 @@ public interface WindowManager extends ViewManager { @interface RemoveContentMode {} /** + * Display IME Policy: The IME should appear on the local display. + * @hide + */ + @TestApi + int DISPLAY_IME_POLICY_LOCAL = 0; + + /** + * Display IME Policy: The IME should appear on the fallback display. + * @hide + */ + @TestApi + int DISPLAY_IME_POLICY_FALLBACK_DISPLAY = 1; + + /** + * Display IME Policy: The IME should be hidden. + * + * Setting this policy will prevent the IME from making a connection. This + * will prevent any IME from receiving metadata about input. + * @hide + */ + @TestApi + int DISPLAY_IME_POLICY_HIDE = 2; + + /** + * @hide + */ + @IntDef({ + DISPLAY_IME_POLICY_LOCAL, + DISPLAY_IME_POLICY_FALLBACK_DISPLAY, + DISPLAY_IME_POLICY_HIDE, + }) + @interface DisplayImePolicy {} + + /** * Exception that is thrown when trying to add view whose * {@link LayoutParams} {@link LayoutParams#token} * is invalid. @@ -695,27 +729,26 @@ public interface WindowManager extends ViewManager { } /** - * Sets that the display should show IME. + * Sets the policy for how the display should show IME. * * @param displayId Display ID. - * @param shouldShow Indicates that the display should show IME. + * @param imePolicy Indicates the policy for how the display should show IME. * @hide */ @TestApi - default void setShouldShowIme(int displayId, boolean shouldShow) { + default void setDisplayImePolicy(int displayId, @DisplayImePolicy int imePolicy) { } /** - * Indicates that the display should show IME. + * Indicates the policy for how the display should show IME. * * @param displayId The id of the display. - * @return {@code true} if the display should show IME when an input field becomes - * focused on it. + * @return The policy for how the display should show IME. * @hide */ @TestApi - default boolean shouldShowIme(int displayId) { - return false; + default @DisplayImePolicy int getDisplayImePolicy(int displayId) { + return DISPLAY_IME_POLICY_FALLBACK_DISPLAY; } public static class LayoutParams extends ViewGroup.LayoutParams implements Parcelable { diff --git a/core/java/android/view/WindowManagerImpl.java b/core/java/android/view/WindowManagerImpl.java index d56929e06906..3384bbe4fd76 100644 --- a/core/java/android/view/WindowManagerImpl.java +++ b/core/java/android/view/WindowManagerImpl.java @@ -201,20 +201,20 @@ public final class WindowManagerImpl implements WindowManager { } @Override - public void setShouldShowIme(int displayId, boolean shouldShow) { + public void setDisplayImePolicy(int displayId, @DisplayImePolicy int imePolicy) { try { - WindowManagerGlobal.getWindowManagerService().setShouldShowIme(displayId, shouldShow); + WindowManagerGlobal.getWindowManagerService().setDisplayImePolicy(displayId, imePolicy); } catch (RemoteException e) { } } @Override - public boolean shouldShowIme(int displayId) { + public @DisplayImePolicy int getDisplayImePolicy(int displayId) { try { - return WindowManagerGlobal.getWindowManagerService().shouldShowIme(displayId); + return WindowManagerGlobal.getWindowManagerService().getDisplayImePolicy(displayId); } catch (RemoteException e) { } - return false; + return DISPLAY_IME_POLICY_FALLBACK_DISPLAY; } @Override diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java index 3c89a4bfad59..315d4461692c 100644 --- a/core/java/android/view/inputmethod/InputMethodManager.java +++ b/core/java/android/view/inputmethod/InputMethodManager.java @@ -599,6 +599,27 @@ public final class InputMethodManager { } /** + * Used by {@link ImeFocusController} to finish input connection and callback + * {@link InputMethodService#onFinishInput()}. + * + * This method is especially for when ImeFocusController received device screen-off event to + * ensure the entire finish input connection and the connection lifecycle callback to + * IME can be done for security concern. + */ + @Override + public void finishInputAndReportToIme() { + synchronized (mH) { + finishInputLocked(); + if (mCurMethod != null) { + try { + mCurMethod.finishInput(); + } catch (RemoteException e) { + } + } + } + } + + /** * Used by {@link ImeFocusController} to hide current input method editor. */ @Override @@ -849,12 +870,23 @@ public final class InputMethodManager { case MSG_SET_ACTIVE: { final boolean active = msg.arg1 != 0; final boolean fullscreen = msg.arg2 != 0; + final boolean reportToImeController = msg.obj != null && (boolean) msg.obj; if (DEBUG) { Log.i(TAG, "handleMessage: MSG_SET_ACTIVE " + active + ", was " + mActive); } synchronized (mH) { mActive = active; mFullscreenMode = fullscreen; + + // Report active state to ImeFocusController to handle IME input + // connection lifecycle callback when it allowed. + final ImeFocusController controller = getFocusController(); + final View rootView = mCurRootView != null ? mCurRootView.getView() : null; + if (controller != null && rootView != null && reportToImeController) { + rootView.post(() -> controller.onInteractiveChanged(active)); + return; + } + if (!active) { // Some other client has starting using the IME, so note // that this happened and make sure our own editor's @@ -1061,8 +1093,9 @@ public final class InputMethodManager { } @Override - public void setActive(boolean active, boolean fullscreen) { - mH.obtainMessage(MSG_SET_ACTIVE, active ? 1 : 0, fullscreen ? 1 : 0).sendToTarget(); + public void setActive(boolean active, boolean fullscreen, boolean reportToImeController) { + mH.obtainMessage(MSG_SET_ACTIVE, active ? 1 : 0, fullscreen ? 1 : 0, + reportToImeController).sendToTarget(); } @Override diff --git a/core/java/android/webkit/PacProcessor.java b/core/java/android/webkit/PacProcessor.java index d7b4e8bba884..21fa6fc88c13 100644 --- a/core/java/android/webkit/PacProcessor.java +++ b/core/java/android/webkit/PacProcessor.java @@ -54,7 +54,7 @@ public interface PacProcessor { */ @NonNull static PacProcessor createInstance() { - throw new UnsupportedOperationException("Not implemented"); + return WebViewFactory.getProvider().createPacProcessor(); } /** diff --git a/core/java/android/widget/SelectionActionModeHelper.java b/core/java/android/widget/SelectionActionModeHelper.java index e74ce53306c1..a034a7c2dc7e 100644 --- a/core/java/android/widget/SelectionActionModeHelper.java +++ b/core/java/android/widget/SelectionActionModeHelper.java @@ -156,7 +156,8 @@ public final class SelectionActionModeHelper { mSmartSelectSprite != null ? this::startSelectionActionModeWithSmartSelectAnimation : this::startSelectionActionMode, - mTextClassificationHelper::getOriginalSelection) + mTextClassificationHelper::getOriginalSelection, + mTextClassificationHelper::isTextClassifierDestroyed) .execute(); } } @@ -178,7 +179,8 @@ public final class SelectionActionModeHelper { mTextClassificationHelper.getTimeoutDuration(), mTextClassificationHelper::classifyText, this::startLinkActionMode, - mTextClassificationHelper::getOriginalSelection) + mTextClassificationHelper::getOriginalSelection, + mTextClassificationHelper::isTextClassifierDestroyed) .execute(); } } @@ -194,7 +196,8 @@ public final class SelectionActionModeHelper { mTextClassificationHelper.getTimeoutDuration(), mTextClassificationHelper::classifyText, this::invalidateActionMode, - mTextClassificationHelper::getOriginalSelection) + mTextClassificationHelper::getOriginalSelection, + mTextClassificationHelper::isTextClassifierDestroyed) .execute(); } } @@ -992,6 +995,7 @@ public final class SelectionActionModeHelper { private final Supplier<SelectionResult> mSelectionResultSupplier; private final Consumer<SelectionResult> mSelectionResultCallback; private final Supplier<SelectionResult> mTimeOutResultSupplier; + private final Supplier<Boolean> mIsTextClassifierDestroyedSupplier; private final TextView mTextView; private final String mOriginalText; @@ -1006,13 +1010,16 @@ public final class SelectionActionModeHelper { @NonNull TextView textView, int timeOut, @NonNull Supplier<SelectionResult> selectionResultSupplier, @NonNull Consumer<SelectionResult> selectionResultCallback, - @NonNull Supplier<SelectionResult> timeOutResultSupplier) { + @NonNull Supplier<SelectionResult> timeOutResultSupplier, + @NonNull Supplier<Boolean> isTextClassifierDestroyedSupplier) { super(textView != null ? textView.getHandler() : null); mTextView = Objects.requireNonNull(textView); mTimeOutDuration = timeOut; mSelectionResultSupplier = Objects.requireNonNull(selectionResultSupplier); mSelectionResultCallback = Objects.requireNonNull(selectionResultCallback); mTimeOutResultSupplier = Objects.requireNonNull(timeOutResultSupplier); + mIsTextClassifierDestroyedSupplier = + Objects.requireNonNull(isTextClassifierDestroyedSupplier); // Make a copy of the original text. mOriginalText = getText(mTextView).toString(); } @@ -1022,7 +1029,19 @@ public final class SelectionActionModeHelper { protected SelectionResult doInBackground(Void... params) { final Runnable onTimeOut = this::onTimeOut; mTextView.postDelayed(onTimeOut, mTimeOutDuration); - final SelectionResult result = mSelectionResultSupplier.get(); + SelectionResult result = null; + try { + result = mSelectionResultSupplier.get(); + } catch (IllegalStateException e) { + // Swallows the exception if the text classifier session is destroyed + if (mIsTextClassifierDestroyedSupplier.get()) { + Log.w(LOG_TAG, + "TextClassificationAsyncTask failed because TextClassifier destroyed", + e); + } else { + throw e; + } + } mTextView.removeCallbacks(onTimeOut); return result; } @@ -1154,6 +1173,10 @@ public final class SelectionActionModeHelper { } } + public boolean isTextClassifierDestroyed() { + return mTextClassifier.get().isDestroyed(); + } + private boolean isDarkLaunchEnabled() { return TextClassificationManager.getSettings(mContext).isModelDarkLaunchEnabled(); } diff --git a/core/java/android/window/DisplayAreaOrganizer.java b/core/java/android/window/DisplayAreaOrganizer.java index 6e20452ad061..1ac188cf2486 100644 --- a/core/java/android/window/DisplayAreaOrganizer.java +++ b/core/java/android/window/DisplayAreaOrganizer.java @@ -101,6 +101,19 @@ public class DisplayAreaOrganizer extends WindowOrganizer { public static final int FEATURE_VENDOR_FIRST = FEATURE_SYSTEM_LAST + 1; /** + * Last possible vendor specific display area id. + * @hide + */ + public static final int FEATURE_VENDOR_LAST = FEATURE_VENDOR_FIRST + 10_000; + + /** + * Task display areas that can be created at runtime start with this value. + * @see #createTaskDisplayArea(int, int, String) + * @hide + */ + public static final int FEATURE_RUNTIME_TASK_CONTAINER_FIRST = FEATURE_VENDOR_LAST + 1; + + /** * Registers a DisplayAreaOrganizer to manage display areas for a given feature. A feature can * not be registered by multiple organizers at the same time. * @@ -132,6 +145,50 @@ public class DisplayAreaOrganizer extends WindowOrganizer { } /** + * Creates a persistent task display area. It will be added to be the top most task display area + * in the root. + * + * The new created TDA is organized by the organizer, and will be deleted on calling + * {@link #deleteTaskDisplayArea(WindowContainerToken)} or {@link #unregisterOrganizer()}. + * + * @param displayId the display to create the new task display area in. + * @param rootFeatureId the root display area to create the new task display area in. Caller can + * use {@link #FEATURE_ROOT} as the root of the logical display. + * @param name the name for the new task display area. + * @return the new created task display area. + * @throws IllegalArgumentException if failed to create a new task display area. + * @hide + */ + @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) + @CallSuper + @NonNull + public DisplayAreaAppearedInfo createTaskDisplayArea(int displayId, int rootFeatureId, + @NonNull String name) { + try { + return getController().createTaskDisplayArea( + mInterface, displayId, rootFeatureId, name); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * Deletes a persistent task display area. It can only be one that created by an organizer. + * + * @throws IllegalArgumentException if failed to delete the task display area. + * @hide + */ + @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) + @CallSuper + public void deleteTaskDisplayArea(@NonNull WindowContainerToken taskDisplayArea) { + try { + getController().deleteTaskDisplayArea(taskDisplayArea); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** * Called when a DisplayArea of the registered window type can be controlled by this organizer. * It will not be called for the DisplayAreas that exist when {@link #registerOrganizer(int)} is * called. diff --git a/core/java/android/window/IDisplayAreaOrganizerController.aidl b/core/java/android/window/IDisplayAreaOrganizerController.aidl index edabcf8ad0de..26fa434506cf 100644 --- a/core/java/android/window/IDisplayAreaOrganizerController.aidl +++ b/core/java/android/window/IDisplayAreaOrganizerController.aidl @@ -19,6 +19,7 @@ package android.window; import android.content.pm.ParceledListSlice; import android.window.DisplayAreaAppearedInfo; import android.window.IDisplayAreaOrganizer; +import android.window.WindowContainerToken; /** @hide */ interface IDisplayAreaOrganizerController { @@ -37,4 +38,28 @@ interface IDisplayAreaOrganizerController { * Unregisters a previously registered display area organizer. */ void unregisterOrganizer(in IDisplayAreaOrganizer organizer); + + /** + * Creates a persistent task display area. It will be added to be the top most task display area + * in the root. + * + * The new created TDA is organized by the organizer, and will be deleted on calling + * {@link #deleteTaskDisplayArea(WindowContainerToken)} or {@link #unregisterOrganizer()}. + * + * @param displayId the display to create the new task display area in. + * @param rootFeatureId the root display area to create the new task display area in. Caller can + * use {@link #FEATURE_ROOT} as the root of the logical display. + * @param name the name for the new task display area. + * @return the new created task display area. + * @throws IllegalArgumentException if failed to create a new task display area. + */ + DisplayAreaAppearedInfo createTaskDisplayArea(in IDisplayAreaOrganizer organizer, int displayId, + int rootFeatureId, in String name); + + /** + * Deletes a persistent task display area. It can only be one that created by an organizer. + * + * @throws IllegalArgumentException if failed to delete the task display area. + */ + void deleteTaskDisplayArea(in WindowContainerToken taskDisplayArea); } diff --git a/core/java/android/window/TransitionInfo.java b/core/java/android/window/TransitionInfo.java index 0eef84765890..b4e7d6a9269f 100644 --- a/core/java/android/window/TransitionInfo.java +++ b/core/java/android/window/TransitionInfo.java @@ -19,6 +19,7 @@ package android.window; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; +import android.graphics.Point; import android.graphics.Rect; import android.os.Parcel; import android.os.Parcelable; @@ -66,6 +67,9 @@ public final class TransitionInfo implements Parcelable { private final @WindowManager.TransitionOldType int mType; private final ArrayList<Change> mChanges = new ArrayList<>(); + private SurfaceControl mRootLeash; + private final Point mRootOffset = new Point(); + /** @hide */ public TransitionInfo(@WindowManager.TransitionOldType int type) { mType = type; @@ -74,6 +78,9 @@ public final class TransitionInfo implements Parcelable { private TransitionInfo(Parcel in) { mType = in.readInt(); in.readList(mChanges, null /* classLoader */); + mRootLeash = new SurfaceControl(); + mRootLeash.readFromParcel(in); + mRootOffset.readFromParcel(in); } @Override @@ -81,6 +88,8 @@ public final class TransitionInfo implements Parcelable { public void writeToParcel(@NonNull Parcel dest, int flags) { dest.writeInt(mType); dest.writeList(mChanges); + mRootLeash.writeToParcel(dest, flags); + mRootOffset.writeToParcel(dest, flags); } @NonNull @@ -103,10 +112,35 @@ public final class TransitionInfo implements Parcelable { return 0; } + /** @see #getRootLeash() */ + public void setRootLeash(@NonNull SurfaceControl leash, int offsetLeft, int offsetTop) { + mRootLeash = leash; + mRootOffset.set(offsetLeft, offsetTop); + } + public int getType() { return mType; } + /** + * @return a surfacecontrol that can serve as a parent surfacecontrol for all the changing + * participants to animate within. This will generally be placed at the highest-z-order + * shared ancestor of all participants. + */ + @NonNull + public SurfaceControl getRootLeash() { + if (mRootLeash == null) { + throw new IllegalStateException("Trying to get a leash which wasn't set"); + } + return mRootLeash; + } + + /** @return the offset (relative to the screen) of the root leash. */ + @NonNull + public Point getRootOffset() { + return mRootOffset; + } + @NonNull public List<Change> getChanges() { return mChanges; @@ -136,7 +170,7 @@ public final class TransitionInfo implements Parcelable { @Override public String toString() { StringBuilder sb = new StringBuilder(); - sb.append("{t=" + mType + " c=["); + sb.append("{t=" + mType + " ro=" + mRootOffset + " c=["); for (int i = 0; i < mChanges.size(); ++i) { if (i > 0) { sb.append(','); @@ -167,8 +201,9 @@ public final class TransitionInfo implements Parcelable { private WindowContainerToken mParent; private final SurfaceControl mLeash; private int mMode = TRANSIT_NONE; - private final Rect mStartBounds = new Rect(); - private final Rect mEndBounds = new Rect(); + private final Rect mStartAbsBounds = new Rect(); + private final Rect mEndAbsBounds = new Rect(); + private final Point mEndRelOffset = new Point(); public Change(@Nullable WindowContainerToken container, @NonNull SurfaceControl leash) { mContainer = container; @@ -181,8 +216,9 @@ public final class TransitionInfo implements Parcelable { mLeash = new SurfaceControl(); mLeash.readFromParcel(in); mMode = in.readInt(); - mStartBounds.readFromParcel(in); - mEndBounds.readFromParcel(in); + mStartAbsBounds.readFromParcel(in); + mEndAbsBounds.readFromParcel(in); + mEndRelOffset.readFromParcel(in); } /** Sets the parent of this change's container. The parent must be a participant or null. */ @@ -195,14 +231,19 @@ public final class TransitionInfo implements Parcelable { mMode = mode; } - /** Sets the bounds this container occupied before the change */ - public void setStartBounds(@Nullable Rect rect) { - mStartBounds.set(rect); + /** Sets the bounds this container occupied before the change in screen space */ + public void setStartAbsBounds(@Nullable Rect rect) { + mStartAbsBounds.set(rect); } - /** Sets the bounds this container will occupy after the change */ - public void setEndBounds(@Nullable Rect rect) { - mEndBounds.set(rect); + /** Sets the bounds this container will occupy after the change in screen space */ + public void setEndAbsBounds(@Nullable Rect rect) { + mEndAbsBounds.set(rect); + } + + /** Sets the offset of this container from its parent surface */ + public void setEndRelOffset(int left, int top) { + mEndRelOffset.set(left, top); } /** @return the container that is changing. May be null if non-remotable (eg. activity) */ @@ -230,8 +271,8 @@ public final class TransitionInfo implements Parcelable { * is coming into existence. */ @NonNull - public Rect getStartBounds() { - return mStartBounds; + public Rect getStartAbsBounds() { + return mStartAbsBounds; } /** @@ -239,8 +280,16 @@ public final class TransitionInfo implements Parcelable { * is disappearing. */ @NonNull - public Rect getEndBounds() { - return mEndBounds; + public Rect getEndAbsBounds() { + return mEndAbsBounds; + } + + /** + * @return the offset of the container's surface from its parent surface after the change. + */ + @NonNull + public Point getEndRelOffset() { + return mEndRelOffset; } /** @return the leash or surface to animate for this container */ @@ -256,8 +305,9 @@ public final class TransitionInfo implements Parcelable { dest.writeTypedObject(mParent, flags); mLeash.writeToParcel(dest, flags); dest.writeInt(mMode); - mStartBounds.writeToParcel(dest, flags); - mEndBounds.writeToParcel(dest, flags); + mStartAbsBounds.writeToParcel(dest, flags); + mEndAbsBounds.writeToParcel(dest, flags); + mEndRelOffset.writeToParcel(dest, flags); } @NonNull @@ -283,8 +333,8 @@ public final class TransitionInfo implements Parcelable { @Override public String toString() { return "{" + mContainer + "(" + mParent + ") leash=" + mLeash - + " m=" + modeToString(mMode) + " sb=" + mStartBounds - + " eb=" + mEndBounds + "}"; + + " m=" + modeToString(mMode) + " sb=" + mStartAbsBounds + + " eb=" + mEndAbsBounds + " eo=" + mEndRelOffset + "}"; } } } diff --git a/core/java/com/android/internal/compat/ChangeReporter.java b/core/java/com/android/internal/compat/ChangeReporter.java index 7a87be35ea98..b9d3df678a91 100644 --- a/core/java/com/android/internal/compat/ChangeReporter.java +++ b/core/java/com/android/internal/compat/ChangeReporter.java @@ -223,7 +223,7 @@ public final class ChangeReporter { FrameworkStatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__SOURCE__SYSTEM_SERVER; @Retention(RetentionPolicy.SOURCE) - @IntDef(flag = true, prefix = { "STATE_" }, value = { + @IntDef(prefix = { "STATE_" }, value = { STATE_UNKNOWN_STATE, STATE_ENABLED, STATE_DISABLED, @@ -233,7 +233,7 @@ public final class ChangeReporter { } @Retention(RetentionPolicy.SOURCE) - @IntDef(flag = true, prefix = { "SOURCE_" }, value = { + @IntDef(prefix = { "SOURCE_" }, value = { SOURCE_UNKNOWN_SOURCE, SOURCE_APP_PROCESS, SOURCE_SYSTEM_SERVER diff --git a/core/java/com/android/internal/content/FileSystemProvider.java b/core/java/com/android/internal/content/FileSystemProvider.java index 3b5fecfc600a..0ede1b86b524 100644 --- a/core/java/com/android/internal/content/FileSystemProvider.java +++ b/core/java/com/android/internal/content/FileSystemProvider.java @@ -20,15 +20,14 @@ import android.annotation.CallSuper; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.ContentResolver; +import android.content.Context; import android.content.Intent; import android.content.res.AssetFileDescriptor; import android.database.Cursor; -import android.database.DatabaseUtils; import android.database.MatrixCursor; import android.database.MatrixCursor.RowBuilder; import android.graphics.Point; import android.net.Uri; -import android.os.Binder; import android.os.Bundle; import android.os.CancellationSignal; import android.os.FileObserver; @@ -39,7 +38,6 @@ import android.provider.DocumentsContract; import android.provider.DocumentsContract.Document; import android.provider.DocumentsProvider; import android.provider.MediaStore; -import android.provider.MediaStore.Files.FileColumns; import android.provider.MetadataReader; import android.system.Int64Ref; import android.text.TextUtils; @@ -66,6 +64,7 @@ import java.nio.file.attribute.BasicFileAttributes; import java.util.Arrays; import java.util.LinkedList; import java.util.List; +import java.util.Locale; import java.util.Set; import java.util.concurrent.CopyOnWriteArrayList; import java.util.function.Predicate; @@ -271,8 +270,7 @@ public abstract class FileSystemProvider extends DocumentsProvider { throw new IllegalStateException("Failed to touch " + file + ": " + e); } } - MediaStore.scanFile(getContext().getContentResolver(), file); - + updateMediaStore(getContext(), file); return childId; } @@ -295,7 +293,9 @@ public abstract class FileSystemProvider extends DocumentsProvider { onDocIdChanged(afterDocId); final File afterVisibleFile = getFileForDocId(afterDocId, true); - moveInMediaStore(beforeVisibleFile, afterVisibleFile); + + updateMediaStore(getContext(), beforeVisibleFile); + updateMediaStore(getContext(), afterVisibleFile); if (!TextUtils.equals(docId, afterDocId)) { return afterDocId; @@ -323,17 +323,23 @@ public abstract class FileSystemProvider extends DocumentsProvider { onDocIdChanged(sourceDocumentId); onDocIdDeleted(sourceDocumentId); onDocIdChanged(docId); - moveInMediaStore(visibleFileBefore, getFileForDocId(docId, true)); - + // update the database + updateMediaStore(getContext(), visibleFileBefore); + updateMediaStore(getContext(), getFileForDocId(docId, true)); return docId; } - private void moveInMediaStore(@Nullable File oldVisibleFile, @Nullable File newVisibleFile) { - if (oldVisibleFile != null) { - MediaStore.scanFile(getContext().getContentResolver(), oldVisibleFile); - } - if (newVisibleFile != null) { - MediaStore.scanFile(getContext().getContentResolver(), newVisibleFile); + private static void updateMediaStore(@NonNull Context context, File file) { + if (file != null) { + final ContentResolver resolver = context.getContentResolver(); + final String noMedia = ".nomedia"; + // For file, check whether the file name is .nomedia or not. + // If yes, scan the parent directory to update all files in the directory. + if (!file.isDirectory() && file.getName().toLowerCase(Locale.ROOT).endsWith(noMedia)) { + MediaStore.scanFile(resolver, file.getParentFile()); + } else { + MediaStore.scanFile(resolver, file); + } } } @@ -354,35 +360,7 @@ public abstract class FileSystemProvider extends DocumentsProvider { onDocIdChanged(docId); onDocIdDeleted(docId); - removeFromMediaStore(visibleFile); - } - - private void removeFromMediaStore(@Nullable File visibleFile) - throws FileNotFoundException { - // visibleFolder is null if we're removing a document from external thumb drive or SD card. - if (visibleFile != null) { - final long token = Binder.clearCallingIdentity(); - - try { - final ContentResolver resolver = getContext().getContentResolver(); - final Uri externalUri = MediaStore.Files.getContentUri("external"); - final Bundle queryArgs = new Bundle(); - queryArgs.putInt(MediaStore.QUERY_ARG_MATCH_PENDING, MediaStore.MATCH_INCLUDE); - - // Remove the media store entry corresponding to visibleFile and if it is a - // directory, also remove media store entries for any files inside this directory. - // Logic borrowed from com.android.providers.media.scan.ModernMediaScanner. - final String pathEscapedForLike = DatabaseUtils.escapeForLike( - visibleFile.getAbsolutePath()); - ContentResolver.includeSqlSelectionArgs(queryArgs, - FileColumns.DATA + " LIKE ? ESCAPE '\\' OR " - + FileColumns.DATA + " LIKE ? ESCAPE '\\'", - new String[] {pathEscapedForLike + "/%", pathEscapedForLike}); - resolver.delete(externalUri, queryArgs); - } finally { - Binder.restoreCallingIdentity(token); - } - } + updateMediaStore(getContext(), visibleFile); } @Override diff --git a/core/java/com/android/internal/infra/AbstractMultiplePendingRequestsRemoteService.java b/core/java/com/android/internal/infra/AbstractMultiplePendingRequestsRemoteService.java index 70505bc5895b..6c01780dac76 100644 --- a/core/java/com/android/internal/infra/AbstractMultiplePendingRequestsRemoteService.java +++ b/core/java/com/android/internal/infra/AbstractMultiplePendingRequestsRemoteService.java @@ -33,7 +33,10 @@ import java.util.List; * * @param <S> the concrete remote service class * @param <I> the interface of the binder service + * + * @deprecated Use {@link ServiceConnector} to manage remote service connections */ +@Deprecated public abstract class AbstractMultiplePendingRequestsRemoteService<S extends AbstractMultiplePendingRequestsRemoteService<S, I>, I extends IInterface> extends AbstractRemoteService<S, I> { diff --git a/core/java/com/android/internal/infra/AbstractRemoteService.java b/core/java/com/android/internal/infra/AbstractRemoteService.java index 722e5c102fcf..f63ac2e14e20 100644 --- a/core/java/com/android/internal/infra/AbstractRemoteService.java +++ b/core/java/com/android/internal/infra/AbstractRemoteService.java @@ -58,9 +58,12 @@ import java.util.ArrayList; * @param <S> the concrete remote service class * @param <I> the interface of the binder service * + * @deprecated Use {@link ServiceConnector} to manage remote service connections + * * @hide */ //TODO(b/117779333): improve javadoc above instead of using Autofill as an example +@Deprecated public abstract class AbstractRemoteService<S extends AbstractRemoteService<S, I>, I extends IInterface> implements DeathRecipient { private static final int MSG_BIND = 1; diff --git a/core/java/com/android/internal/infra/AbstractSinglePendingRequestRemoteService.java b/core/java/com/android/internal/infra/AbstractSinglePendingRequestRemoteService.java index 2ebf2fd820d8..0d9af8c8bcf5 100644 --- a/core/java/com/android/internal/infra/AbstractSinglePendingRequestRemoteService.java +++ b/core/java/com/android/internal/infra/AbstractSinglePendingRequestRemoteService.java @@ -33,8 +33,11 @@ import java.io.PrintWriter; * @param <S> the concrete remote service class * @param <I> the interface of the binder service * + * @deprecated Use {@link ServiceConnector} to manage remote service connections + * * @hide */ +@Deprecated public abstract class AbstractSinglePendingRequestRemoteService<S extends AbstractSinglePendingRequestRemoteService<S, I>, I extends IInterface> extends AbstractRemoteService<S, I> { diff --git a/core/java/com/android/internal/infra/OWNERS b/core/java/com/android/internal/infra/OWNERS new file mode 100644 index 000000000000..45503582b2c5 --- /dev/null +++ b/core/java/com/android/internal/infra/OWNERS @@ -0,0 +1,6 @@ +per-file AndroidFuture.java = eugenesusla@google.com +per-file RemoteStream.java = eugenesusla@google.com +per-file PerUser.java = eugenesusla@google.com +per-file ServiceConnector.java = eugenesusla@google.com +per-file AndroidFuture.aidl = eugenesusla@google.com +per-file IAndroidFuture.aidl = eugenesusla@google.com
\ No newline at end of file diff --git a/core/java/com/android/internal/inputmethod/Completable.java b/core/java/com/android/internal/inputmethod/Completable.java index 16473b98b813..d8d1a7df6aa8 100644 --- a/core/java/com/android/internal/inputmethod/Completable.java +++ b/core/java/com/android/internal/inputmethod/Completable.java @@ -19,6 +19,7 @@ package com.android.internal.inputmethod; import android.annotation.AnyThread; import android.annotation.NonNull; import android.annotation.Nullable; +import android.util.Log; import com.android.internal.annotations.GuardedBy; @@ -275,4 +276,53 @@ public final class Completable { */ public static final class InputBindResult extends Values<com.android.internal.view.InputBindResult> { } + + /** + * Await the result by the {@link Completable.Int}, and log it if there is no result after + * given timeout. + * + * @return the result once {@link ValueBase#onComplete()} + */ + @AnyThread + public static int getResultOrZero(@NonNull Completable.Int value, String tag, + @NonNull String methodName, @Nullable CancellationGroup cancellationGroup, + int maxWaitTime) { + final boolean timedOut = value.await(maxWaitTime, TimeUnit.MILLISECONDS, cancellationGroup); + if (value.hasValue()) { + return value.getValue(); + } + logInternal(tag, methodName, timedOut, maxWaitTime, 0); + return 0; + } + + /** + * Await the result by the {@link Completable.Values}, and log it if there is no result after + * given timeout. + * + * @return the result once {@link ValueBase#onComplete()} + */ + @AnyThread + @Nullable + public static <T> T getResultOrNull(@NonNull Completable.Values<T> value, String tag, + @NonNull String methodName, @Nullable CancellationGroup cancellationGroup, + int maxWaitTime) { + final boolean timedOut = value.await(maxWaitTime, TimeUnit.MILLISECONDS, cancellationGroup); + if (value.hasValue()) { + return value.getValue(); + } + logInternal(tag, methodName, timedOut, maxWaitTime, null); + return null; + } + + @AnyThread + private static void logInternal(String tag, @Nullable String methodName, boolean timedOut, + int maxWaitTime, @Nullable Object defaultValue) { + if (timedOut) { + Log.w(tag, methodName + " didn't respond in " + maxWaitTime + " msec." + + " Returning default: " + defaultValue); + } else { + Log.w(tag, methodName + " was canceled before complete. Returning default: " + + defaultValue); + } + } } diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java index 7c442b408624..7571f5db8cad 100644 --- a/core/java/com/android/internal/os/BatteryStatsImpl.java +++ b/core/java/com/android/internal/os/BatteryStatsImpl.java @@ -98,6 +98,8 @@ import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidActiveTimeRead import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidClusterTimeReader; import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidFreqTimeReader; import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidUserSysTimeReader; +import com.android.internal.power.MeasuredEnergyArray; +import com.android.internal.power.MeasuredEnergyStats; import com.android.internal.util.ArrayUtils; import com.android.internal.util.FastPrintWriter; import com.android.internal.util.FastXmlSerializer; @@ -155,7 +157,7 @@ public class BatteryStatsImpl extends BatteryStats { private static final int MAGIC = 0xBA757475; // 'BATSTATS' // Current on-disk Parcel version - static final int VERSION = 189 + (USE_OLD_HISTORY ? 1000 : 0); + static final int VERSION = 190 + (USE_OLD_HISTORY ? 1000 : 0); // The maximum number of names wakelocks we will keep track of // per uid; once the limit is reached, we batch the remaining wakelocks @@ -349,12 +351,20 @@ public class BatteryStatsImpl extends BatteryStats { } /** interface to update rail information for power monitor */ - public interface RailEnergyDataCallback { + public interface MeasuredEnergyRetriever { /** Function to fill the map for the rail data stats * Used for power monitoring feature * @param railStats */ void fillRailDataStats(RailStats railStats); + /** + * Function to get energy consumption data + * + * @return an array of measured energy (in microjoules) since boot, will be null if + * measured energy data is unavailable + */ + @Nullable + MeasuredEnergyArray getEnergyConsumptionData(); } public static abstract class UserInfoProvider { @@ -391,7 +401,7 @@ public class BatteryStatsImpl extends BatteryStats { } }; - public final RailEnergyDataCallback mRailEnergyDataCallback; + public final MeasuredEnergyRetriever mMeasuredEnergyRetriever; /** * This handler is running on {@link BackgroundThread}. @@ -624,8 +634,10 @@ public class BatteryStatsImpl extends BatteryStats { int UPDATE_WIFI = 0x02; int UPDATE_RADIO = 0x04; int UPDATE_BT = 0x08; - int UPDATE_RPM = 0x10; // 16 - int UPDATE_ALL = UPDATE_CPU | UPDATE_WIFI | UPDATE_RADIO | UPDATE_BT | UPDATE_RPM; + int UPDATE_RPM = 0x10; + int UPDATE_ENERGY = 0x20; + int UPDATE_ALL = + UPDATE_CPU | UPDATE_WIFI | UPDATE_RADIO | UPDATE_BT | UPDATE_RPM | UPDATE_ENERGY; Future<?> scheduleSync(String reason, int flags); Future<?> scheduleCpuSyncDueToRemovedUid(int uid); @@ -633,8 +645,11 @@ public class BatteryStatsImpl extends BatteryStats { long delayMillis); Future<?> scheduleCopyFromAllUidsCpuTimes(boolean onBattery, boolean onBatteryScreenOff); Future<?> scheduleCpuSyncDueToSettingChange(); - Future<?> scheduleCpuSyncDueToScreenStateChange(boolean onBattery, - boolean onBatteryScreenOff); + /** + * Schedule a sync because of a screen state change. + */ + Future<?> scheduleSyncDueToScreenStateChange(int flags, boolean onBattery, + boolean onBatteryScreenOff, int screenState); Future<?> scheduleCpuSyncDueToWakelockChange(long delayMillis); void cancelCpuSyncDueToWakelockChange(); Future<?> scheduleSyncDueToBatteryLevelChange(long delayMillis); @@ -932,6 +947,13 @@ public class BatteryStatsImpl extends BatteryStats { int mWifiRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; /** + * Accumulated energy consumption of various consumers while on battery. + * If energy consumer data is unavailable this will be null. + */ + @GuardedBy("this") + MeasuredEnergyStats mBatteryMeasuredEnergyStats; + + /** * These provide time bases that discount the time the device is plugged * in to power. */ @@ -1123,7 +1145,7 @@ public class BatteryStatsImpl extends BatteryStats { mBatteryStatsHistory = null; mHandler = null; mPlatformIdleStateCallback = null; - mRailEnergyDataCallback = null; + mMeasuredEnergyRetriever = null; mUserInfoProvider = null; mConstants = new Constants(mHandler); clearHistoryLocked(); @@ -1424,7 +1446,8 @@ public class BatteryStatsImpl extends BatteryStats { * @param in the parcel to read from * @return the Counter or null. */ - public static @Nullable Counter readCounterFromParcel(TimeBase timeBase, Parcel in) { + @Nullable + public static Counter readCounterFromParcel(TimeBase timeBase, Parcel in) { if (in.readInt() == 0) { return null; } @@ -3949,7 +3972,7 @@ public class BatteryStatsImpl extends BatteryStats { @GuardedBy("this") public void updateTimeBasesLocked(boolean unplugged, int screenState, long uptimeUs, long realtimeUs) { - final boolean screenOff = !isScreenOn(screenState); + final boolean screenOff = !Display.isOnState(screenState); final boolean updateOnBatteryTimeBase = unplugged != mOnBatteryTimeBase.isRunning(); final boolean updateOnBatteryScreenOffTimeBase = (unplugged && screenOff) != mOnBatteryScreenOffTimeBase.isRunning(); @@ -5012,16 +5035,16 @@ public class BatteryStatsImpl extends BatteryStats { } boolean updateHistory = false; - if (isScreenDoze(state) && !isScreenDoze(oldState)) { + if (Display.isDozeState(state) && !Display.isDozeState(oldState)) { mHistoryCur.states |= HistoryItem.STATE_SCREEN_DOZE_FLAG; mScreenDozeTimer.startRunningLocked(elapsedRealtimeMs); updateHistory = true; - } else if (isScreenDoze(oldState) && !isScreenDoze(state)) { + } else if (Display.isDozeState(oldState) && !Display.isDozeState(state)) { mHistoryCur.states &= ~HistoryItem.STATE_SCREEN_DOZE_FLAG; mScreenDozeTimer.stopRunningLocked(elapsedRealtimeMs); updateHistory = true; } - if (isScreenOn(state)) { + if (Display.isOnState(state)) { mHistoryCur.states |= HistoryItem.STATE_SCREEN_ON_FLAG; if (DEBUG_HISTORY) Slog.v(TAG, "Screen on to: " + Integer.toHexString(mHistoryCur.states)); @@ -5031,7 +5054,7 @@ public class BatteryStatsImpl extends BatteryStats { .startRunningLocked(elapsedRealtimeMs); } updateHistory = true; - } else if (isScreenOn(oldState)) { + } else if (Display.isOnState(oldState)) { mHistoryCur.states &= ~HistoryItem.STATE_SCREEN_ON_FLAG; if (DEBUG_HISTORY) Slog.v(TAG, "Screen off to: " + Integer.toHexString(mHistoryCur.states)); @@ -5047,15 +5070,21 @@ public class BatteryStatsImpl extends BatteryStats { + Display.stateToString(state)); addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); } - mExternalSync.scheduleCpuSyncDueToScreenStateChange( - mOnBatteryTimeBase.isRunning(), mOnBatteryScreenOffTimeBase.isRunning()); - if (isScreenOn(state)) { + int updateFlag = ExternalStatsSync.UPDATE_CPU; + if (mBatteryMeasuredEnergyStats != null && mBatteryMeasuredEnergyStats.hasSubsystem( + MeasuredEnergyArray.SUBSYSTEM_DISPLAY)) { + updateFlag |= ExternalStatsSync.UPDATE_ENERGY; + } + mExternalSync.scheduleSyncDueToScreenStateChange(updateFlag, + mOnBatteryTimeBase.isRunning(), mOnBatteryScreenOffTimeBase.isRunning(), + mScreenState); + if (Display.isOnState(state)) { updateTimeBasesLocked(mOnBatteryTimeBase.isRunning(), state, uptimeMs * 1000, elapsedRealtimeMs * 1000); // Fake a wake lock, so we consider the device waked as long as the screen is on. noteStartWakeLocked(-1, -1, null, "screen", null, WAKE_TYPE_PARTIAL, false, elapsedRealtimeMs, uptimeMs); - } else if (isScreenOn(oldState)) { + } else if (Display.isOnState(oldState)) { noteStopWakeLocked(-1, -1, null, "screen", "screen", WAKE_TYPE_PARTIAL, elapsedRealtimeMs, uptimeMs); updateTimeBasesLocked(mOnBatteryTimeBase.isRunning(), state, @@ -7039,6 +7068,26 @@ public class BatteryStatsImpl extends BatteryStats { } } + @Override + public long getScreenOnEnergy() { + if (mBatteryMeasuredEnergyStats == null || !mBatteryMeasuredEnergyStats.hasSubsystem( + MeasuredEnergyArray.SUBSYSTEM_DISPLAY)) { + return ENERGY_DATA_UNAVAILABLE; + } + return mBatteryMeasuredEnergyStats.getAccumulatedBucketEnergy( + MeasuredEnergyStats.ENERGY_BUCKET_SCREEN_ON); + } + + @Override + public long getScreenDozeEnergy() { + if (mBatteryMeasuredEnergyStats == null || !mBatteryMeasuredEnergyStats.hasSubsystem( + MeasuredEnergyArray.SUBSYSTEM_DISPLAY)) { + return ENERGY_DATA_UNAVAILABLE; + } + return mBatteryMeasuredEnergyStats.getAccumulatedBucketEnergy( + MeasuredEnergyStats.ENERGY_BUCKET_SCREEN_DOZE); + } + @Override public long getStartClockTime() { final long currentTimeMs = System.currentTimeMillis(); if ((currentTimeMs > MILLISECONDS_IN_YEAR @@ -10457,12 +10506,12 @@ public class BatteryStatsImpl extends BatteryStats { } public BatteryStatsImpl(File systemDir, Handler handler, PlatformIdleStateCallback cb, - RailEnergyDataCallback railStatsCb, UserInfoProvider userInfoProvider) { - this(new SystemClocks(), systemDir, handler, cb, railStatsCb, userInfoProvider); + MeasuredEnergyRetriever energyStatsCb, UserInfoProvider userInfoProvider) { + this(new SystemClocks(), systemDir, handler, cb, energyStatsCb, userInfoProvider); } private BatteryStatsImpl(Clocks clocks, File systemDir, Handler handler, - PlatformIdleStateCallback cb, RailEnergyDataCallback railStatsCb, + PlatformIdleStateCallback cb, MeasuredEnergyRetriever energyStatsCb, UserInfoProvider userInfoProvider) { init(clocks); @@ -10563,12 +10612,19 @@ public class BatteryStatsImpl extends BatteryStats { clearHistoryLocked(); updateDailyDeadlineLocked(); mPlatformIdleStateCallback = cb; - mRailEnergyDataCallback = railStatsCb; + mMeasuredEnergyRetriever = energyStatsCb; mUserInfoProvider = userInfoProvider; // Notify statsd that the system is initially not in doze. mDeviceIdleMode = DEVICE_IDLE_MODE_OFF; FrameworkStatsLog.write(FrameworkStatsLog.DEVICE_IDLE_MODE_STATE_CHANGED, mDeviceIdleMode); + + final MeasuredEnergyArray energyStats = mMeasuredEnergyRetriever.getEnergyConsumptionData(); + // If measured energy is not available, it is not supported and + // mBatteryMeasuredEnergyStats should be left null. + if (energyStats != null) { + mBatteryMeasuredEnergyStats = new MeasuredEnergyStats(energyStats, mScreenState); + } } @UnsupportedAppUsage @@ -10588,7 +10644,7 @@ public class BatteryStatsImpl extends BatteryStats { mBatteryStatsHistory = new BatteryStatsHistory(this, mHistoryBuffer); readFromParcel(p); mPlatformIdleStateCallback = null; - mRailEnergyDataCallback = null; + mMeasuredEnergyRetriever = null; } public void setPowerProfileLocked(PowerProfile profile) { @@ -11097,19 +11153,6 @@ public class BatteryStatsImpl extends BatteryStats { return mCharging; } - public boolean isScreenOn(int state) { - return state == Display.STATE_ON || state == Display.STATE_VR - || state == Display.STATE_ON_SUSPEND; - } - - public boolean isScreenOff(int state) { - return state == Display.STATE_OFF; - } - - public boolean isScreenDoze(int state) { - return state == Display.STATE_DOZE || state == Display.STATE_DOZE_SUSPEND; - } - void initTimes(long uptimeUs, long realtimeUs) { mStartClockTimeMs = System.currentTimeMillis(); mOnBatteryTimeBase.init(uptimeUs, realtimeUs); @@ -11152,11 +11195,11 @@ public class BatteryStatsImpl extends BatteryStats { mOnBatteryTimeBase.reset(uptimeUs, realtimeUs); mOnBatteryScreenOffTimeBase.reset(uptimeUs, realtimeUs); if ((mHistoryCur.states&HistoryItem.STATE_BATTERY_PLUGGED_FLAG) == 0) { - if (isScreenOn(mScreenState)) { + if (Display.isOnState(mScreenState)) { mDischargeScreenOnUnplugLevel = mHistoryCur.batteryLevel; mDischargeScreenDozeUnplugLevel = 0; mDischargeScreenOffUnplugLevel = 0; - } else if (isScreenDoze(mScreenState)) { + } else if (Display.isDozeState(mScreenState)) { mDischargeScreenOnUnplugLevel = 0; mDischargeScreenDozeUnplugLevel = mHistoryCur.batteryLevel; mDischargeScreenOffUnplugLevel = 0; @@ -11286,6 +11329,11 @@ public class BatteryStatsImpl extends BatteryStats { mTmpRailStats.reset(); + if (mBatteryMeasuredEnergyStats != null) { + mBatteryMeasuredEnergyStats.reset(); + mExternalSync.scheduleSync("reset", ExternalStatsSync.UPDATE_ENERGY); + } + resetIfNotNull(mSystemServerCpuTimesUs, false, elapsedRealtimeUs); resetIfNotNull(mSystemServerThreadCpuTimesUs, false, elapsedRealtimeUs); resetIfNotNull(mBinderThreadCpuTimesUs, false, elapsedRealtimeUs); @@ -11339,19 +11387,19 @@ public class BatteryStatsImpl extends BatteryStats { } private void updateOldDischargeScreenLevelLocked(int state) { - if (isScreenOn(state)) { + if (Display.isOnState(state)) { int diff = mDischargeScreenOnUnplugLevel - mDischargeCurrentLevel; if (diff > 0) { mDischargeAmountScreenOn += diff; mDischargeAmountScreenOnSinceCharge += diff; } - } else if (isScreenDoze(state)) { + } else if (Display.isDozeState(state)) { int diff = mDischargeScreenDozeUnplugLevel - mDischargeCurrentLevel; if (diff > 0) { mDischargeAmountScreenDoze += diff; mDischargeAmountScreenDozeSinceCharge += diff; } - } else if (isScreenOff(state)){ + } else if (Display.isOffState(state)) { int diff = mDischargeScreenOffUnplugLevel - mDischargeCurrentLevel; if (diff > 0) { mDischargeAmountScreenOff += diff; @@ -11361,15 +11409,15 @@ public class BatteryStatsImpl extends BatteryStats { } private void updateNewDischargeScreenLevelLocked(int state) { - if (isScreenOn(state)) { + if (Display.isOnState(state)) { mDischargeScreenOnUnplugLevel = mDischargeCurrentLevel; mDischargeScreenOffUnplugLevel = 0; mDischargeScreenDozeUnplugLevel = 0; - } else if (isScreenDoze(state)){ + } else if (Display.isDozeState(state)) { mDischargeScreenOnUnplugLevel = 0; mDischargeScreenDozeUnplugLevel = mDischargeCurrentLevel; mDischargeScreenOffUnplugLevel = 0; - } else if (isScreenOff(state)) { + } else if (Display.isOffState(state)) { mDischargeScreenOnUnplugLevel = 0; mDischargeScreenDozeUnplugLevel = 0; mDischargeScreenOffUnplugLevel = mDischargeCurrentLevel; @@ -12163,10 +12211,25 @@ public class BatteryStatsImpl extends BatteryStats { * Read and record Rail Energy data. */ public void updateRailStatsLocked() { - if (mRailEnergyDataCallback == null || !mTmpRailStats.isRailStatsAvailable()) { + if (mMeasuredEnergyRetriever == null || !mTmpRailStats.isRailStatsAvailable()) { return; } - mRailEnergyDataCallback.fillRailDataStats(mTmpRailStats); + mMeasuredEnergyRetriever.fillRailDataStats(mTmpRailStats); + } + + /** + * Get energy consumed (in microjoules) by a set of subsystems from the {@link + * MeasuredEnergyRetriever}, if available. + * + * @return a SparseLongArray that maps consumer id to energy consumed. Returns null if data is + * unavailable. + */ + @Nullable + public MeasuredEnergyArray getEnergyConsumptionDataLocked() { + if (mMeasuredEnergyRetriever == null) { + return null; + } + return mMeasuredEnergyRetriever.getEnergyConsumptionData(); } /** @@ -12428,6 +12491,21 @@ public class BatteryStatsImpl extends BatteryStats { } /** + * Update energy consumption data with a new snapshot of energy data. + * Generally this should only be called from BatteryExternalStatsWorker. + * + * @param energyStats latest energy data to update with. + */ + @GuardedBy("this") + public void updateMeasuredEnergyStatsLocked(@NonNull MeasuredEnergyArray energyStats, + int screenState) { + if (mBatteryMeasuredEnergyStats != null) { + mBatteryMeasuredEnergyStats.update(energyStats, screenState, + mOnBatteryTimeBase.isRunning()); + } + } + + /** * Mark the current partial timers as gone through a collection so that they will be * considered in the next cpu times distribution to wakelock holders. */ @@ -12919,11 +12997,11 @@ public class BatteryStatsImpl extends BatteryStats { } addHistoryRecordLocked(mSecRealtime, mSecUptime); mDischargeCurrentLevel = mDischargeUnplugLevel = level; - if (isScreenOn(screenState)) { + if (Display.isOnState(screenState)) { mDischargeScreenOnUnplugLevel = level; mDischargeScreenDozeUnplugLevel = 0; mDischargeScreenOffUnplugLevel = 0; - } else if (isScreenDoze(screenState)) { + } else if (Display.isDozeState(screenState)) { mDischargeScreenOnUnplugLevel = 0; mDischargeScreenDozeUnplugLevel = level; mDischargeScreenOffUnplugLevel = 0; @@ -13079,7 +13157,7 @@ public class BatteryStatsImpl extends BatteryStats { final long chargeDiff = mHistoryCur.batteryChargeUAh - chargeUAh; mDischargeCounter.addCountLocked(chargeDiff); mDischargeScreenOffCounter.addCountLocked(chargeDiff); - if (isScreenDoze(mScreenState)) { + if (Display.isDozeState(mScreenState)) { mDischargeScreenDozeCounter.addCountLocked(chargeDiff); } if (mDeviceIdleMode == DEVICE_IDLE_MODE_LIGHT) { @@ -13130,7 +13208,7 @@ public class BatteryStatsImpl extends BatteryStats { final long chargeDiff = mHistoryCur.batteryChargeUAh - chargeUAh; mDischargeCounter.addCountLocked(chargeDiff); mDischargeScreenOffCounter.addCountLocked(chargeDiff); - if (isScreenDoze(mScreenState)) { + if (Display.isDozeState(mScreenState)) { mDischargeScreenDozeCounter.addCountLocked(chargeDiff); } if (mDeviceIdleMode == DEVICE_IDLE_MODE_LIGHT) { @@ -13584,7 +13662,7 @@ public class BatteryStatsImpl extends BatteryStats { public int getDischargeAmountScreenOn() { synchronized(this) { int val = mDischargeAmountScreenOn; - if (mOnBattery && isScreenOn(mScreenState) + if (mOnBattery && Display.isOnState(mScreenState) && mDischargeCurrentLevel < mDischargeScreenOnUnplugLevel) { val += mDischargeScreenOnUnplugLevel-mDischargeCurrentLevel; } @@ -13596,7 +13674,7 @@ public class BatteryStatsImpl extends BatteryStats { public int getDischargeAmountScreenOnSinceCharge() { synchronized(this) { int val = mDischargeAmountScreenOnSinceCharge; - if (mOnBattery && isScreenOn(mScreenState) + if (mOnBattery && Display.isOnState(mScreenState) && mDischargeCurrentLevel < mDischargeScreenOnUnplugLevel) { val += mDischargeScreenOnUnplugLevel-mDischargeCurrentLevel; } @@ -13609,7 +13687,7 @@ public class BatteryStatsImpl extends BatteryStats { public int getDischargeAmountScreenOff() { synchronized(this) { int val = mDischargeAmountScreenOff; - if (mOnBattery && isScreenOff(mScreenState) + if (mOnBattery && Display.isOffState(mScreenState) && mDischargeCurrentLevel < mDischargeScreenOffUnplugLevel) { val += mDischargeScreenOffUnplugLevel-mDischargeCurrentLevel; } @@ -13622,7 +13700,7 @@ public class BatteryStatsImpl extends BatteryStats { public int getDischargeAmountScreenOffSinceCharge() { synchronized(this) { int val = mDischargeAmountScreenOffSinceCharge; - if (mOnBattery && isScreenOff(mScreenState) + if (mOnBattery && Display.isOffState(mScreenState) && mDischargeCurrentLevel < mDischargeScreenOffUnplugLevel) { val += mDischargeScreenOffUnplugLevel-mDischargeCurrentLevel; } @@ -13635,7 +13713,7 @@ public class BatteryStatsImpl extends BatteryStats { public int getDischargeAmountScreenDoze() { synchronized(this) { int val = mDischargeAmountScreenDoze; - if (mOnBattery && isScreenDoze(mScreenState) + if (mOnBattery && Display.isDozeState(mScreenState) && mDischargeCurrentLevel < mDischargeScreenDozeUnplugLevel) { val += mDischargeScreenDozeUnplugLevel-mDischargeCurrentLevel; } @@ -13647,7 +13725,7 @@ public class BatteryStatsImpl extends BatteryStats { public int getDischargeAmountScreenDozeSinceCharge() { synchronized(this) { int val = mDischargeAmountScreenDozeSinceCharge; - if (mOnBattery && isScreenDoze(mScreenState) + if (mOnBattery && Display.isDozeState(mScreenState) && mDischargeCurrentLevel < mDischargeScreenDozeUnplugLevel) { val += mDischargeScreenDozeUnplugLevel-mDischargeCurrentLevel; } @@ -14129,6 +14207,19 @@ public class BatteryStatsImpl extends BatteryStats { } } + /** + * Dump measured energy stats + */ + @GuardedBy("this") + public void dumpMeasuredEnergyStatsLocked(PrintWriter pw) { + if (mBatteryMeasuredEnergyStats == null) return; + final IndentingPrintWriter iPw = new IndentingPrintWriter(pw, " "); + iPw.println("On battery measured energy stats:"); + iPw.increaseIndent(); + mBatteryMeasuredEnergyStats.dump(iPw); + iPw.decreaseIndent(); + } + final ReentrantLock mWriteLock = new ReentrantLock(); public void writeAsyncLocked() { @@ -14504,6 +14595,8 @@ public class BatteryStatsImpl extends BatteryStats { mNextMaxDailyDeadlineMs = in.readLong(); mBatteryTimeToFullSeconds = in.readLong(); + MeasuredEnergyStats.readSummaryFromParcel(mBatteryMeasuredEnergyStats, in); + mStartCount++; mScreenState = Display.STATE_UNKNOWN; @@ -14997,6 +15090,8 @@ public class BatteryStatsImpl extends BatteryStats { out.writeLong(mNextMaxDailyDeadlineMs); out.writeLong(mBatteryTimeToFullSeconds); + MeasuredEnergyStats.writeSummaryToParcel(mBatteryMeasuredEnergyStats, out); + mScreenOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); mScreenDozeTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { @@ -15581,6 +15676,10 @@ public class BatteryStatsImpl extends BatteryStats { mLastWriteTimeMs = in.readLong(); mBatteryTimeToFullSeconds = in.readLong(); + if (in.readInt() != 0) { + mBatteryMeasuredEnergyStats = new MeasuredEnergyStats(in); + } + mRpmStats.clear(); int NRPMS = in.readInt(); for (int irpm = 0; irpm < NRPMS; irpm++) { @@ -15783,6 +15882,13 @@ public class BatteryStatsImpl extends BatteryStats { out.writeLong(mLastWriteTimeMs); out.writeLong(mBatteryTimeToFullSeconds); + if (mBatteryMeasuredEnergyStats != null) { + out.writeInt(1); + mBatteryMeasuredEnergyStats.writeToParcel(out); + } else { + out.writeInt(0); + } + out.writeInt(mRpmStats.size()); for (Map.Entry<String, SamplingTimer> ent : mRpmStats.entrySet()) { SamplingTimer rpmt = ent.getValue(); @@ -16036,5 +16142,8 @@ public class BatteryStatsImpl extends BatteryStats { pw.println(); dumpConstantsLocked(pw); + + pw.println(); + dumpMeasuredEnergyStatsLocked(pw); } } diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java index 1fcc6b0a6d55..9b5d295fa7a5 100644 --- a/core/java/com/android/internal/os/ZygoteInit.java +++ b/core/java/com/android/internal/os/ZygoteInit.java @@ -625,8 +625,11 @@ public class ZygoteInit { /** * Creates a PathClassLoader for the given class path that is associated with a shared - * namespace, i.e., this classloader can access platform-private native libraries. The - * classloader will use java.library.path as the native library path. + * namespace, i.e., this classloader can access platform-private native libraries. + * + * The classloader will add java.library.path to the native library path for the classloader + * namespace. Since it includes platform locations like /system/lib, this is only appropriate + * for platform code that don't need linker namespace isolation (as opposed to APEXes and apps). */ static ClassLoader createPathClassLoader(String classPath, int targetSdkVersion) { String libraryPath = System.getProperty("java.library.path"); diff --git a/core/java/com/android/internal/power/MeasuredEnergyArray.java b/core/java/com/android/internal/power/MeasuredEnergyArray.java new file mode 100644 index 000000000000..1f6dc260a197 --- /dev/null +++ b/core/java/com/android/internal/power/MeasuredEnergyArray.java @@ -0,0 +1,66 @@ +/* + * 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.internal.power; + + +import android.annotation.IntDef; + +import com.android.internal.os.RailStats; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * Interface to provide subsystem energy data. + * TODO: replace this and {@link RailStats} once b/173077356 is done + */ +public interface MeasuredEnergyArray { + int SUBSYSTEM_UNKNOWN = -1; + int SUBSYSTEM_DISPLAY = 0; + int NUMBER_SUBSYSTEMS = 1; + String[] SUBSYSTEM_NAMES = {"display"}; + + + @IntDef(prefix = { "SUBSYSTEM_" }, value = { + SUBSYSTEM_UNKNOWN, + SUBSYSTEM_DISPLAY, + }) + @Retention(RetentionPolicy.SOURCE) + @interface MeasuredEnergySubsystem {} + + /** + * Get the subsystem at an index in array. + * + * @param index into the array. + * @return subsystem. + */ + @MeasuredEnergySubsystem + int getSubsystem(int index); + + /** + * Get the energy (in microjoules) consumed since boot of the subsystem at an index. + * + * @param index into the array. + * @return energy (in microjoules) consumed since boot. + */ + long getEnergy(int index); + + /** + * Return number of subsystems in the array. + */ + int size(); +} diff --git a/core/java/com/android/internal/power/MeasuredEnergyStats.java b/core/java/com/android/internal/power/MeasuredEnergyStats.java new file mode 100644 index 000000000000..7b6e0790e14f --- /dev/null +++ b/core/java/com/android/internal/power/MeasuredEnergyStats.java @@ -0,0 +1,307 @@ +/* + * 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.internal.power; + + +import android.annotation.IntDef; +import android.annotation.Nullable; +import android.os.Parcel; +import android.view.Display; + +import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.power.MeasuredEnergyArray.MeasuredEnergySubsystem; + +import java.io.PrintWriter; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.util.Arrays; + +/** + * MeasuredEnergyStats adds up the measured energy usage of various subsystems + */ +@VisibleForTesting +public class MeasuredEnergyStats { + private static final long UNAVAILABLE = -1; + private static final long RESET = -2; + + public static final int ENERGY_BUCKET_UNKNOWN = -1; + public static final int ENERGY_BUCKET_SCREEN_ON = 0; + public static final int ENERGY_BUCKET_SCREEN_DOZE = 1; + public static final int ENERGY_BUCKET_SCREEN_OTHER = 2; + public static final int NUMBER_ENERGY_BUCKETS = 3; + private static final String[] ENERGY_BUCKET_NAMES = + {"screen-on", "screen-doze", "screen-other"}; + + @IntDef(prefix = {"ENERGY_BUCKET_"}, value = { + ENERGY_BUCKET_UNKNOWN, + ENERGY_BUCKET_SCREEN_ON, + ENERGY_BUCKET_SCREEN_DOZE, + ENERGY_BUCKET_SCREEN_OTHER, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface EnergyBucket { + } + + /** + * Energy snapshots from the last time each {@link MeasuredEnergySubsystem} was updated. + * An energy snapshot will be set to {@link #UNAVAILABLE} if the subsystem has never been + * updated. + * An energy snapshot will be set to {@link #RESET} on a reset. A subsystems energy will + * need to be updated at least twice to start accumulating energy again. + */ + private final long[] mMeasuredEnergySnapshots = + new long[MeasuredEnergyArray.NUMBER_SUBSYSTEMS]; + + /** + * Total energy in microjoules since the last reset that an {@link EnergyBucket} has + * accumulated. + * + * Warning: Long array is used for access speed. If the number of supported subsystems + * becomes too large, consider using an alternate data structure. + */ + private final long[] mAccumulatedEnergiesMicroJoules = new long[NUMBER_ENERGY_BUCKETS]; + + /** + * Last known screen state. + */ + private int mLastScreenState; + + public MeasuredEnergyStats(MeasuredEnergyArray energyArray, int screenState) { + Arrays.fill(mMeasuredEnergySnapshots, UNAVAILABLE); + + update(energyArray, screenState, false); + } + + public MeasuredEnergyStats(Parcel in) { + in.readLongArray(mAccumulatedEnergiesMicroJoules); + } + + /** + * Constructor for creating a temp MeasuredEnergyStats + * See {@link #readSummaryFromParcel(MeasuredEnergyStats, Parcel)} + */ + private MeasuredEnergyStats() { + Arrays.fill(mMeasuredEnergySnapshots, UNAVAILABLE); + } + + /** Write to parcel */ + public void writeToParcel(Parcel out) { + out.writeLongArray(mAccumulatedEnergiesMicroJoules); + } + + /** + * Read from summary parcel. + * Note: Measured subsystem availability may be different from when the summary parcel was + * written. + */ + private void readSummaryFromParcel(Parcel in) { + final int size = in.readInt(); + for (int i = 0; i < size; i++) { + final int bucket = in.readInt(); + final long energyUJ = in.readLong(); + + final int subsystem = getSubsystem(bucket); + // Only accept the summary energy if subsystem is currently available + if (subsystem != MeasuredEnergyArray.SUBSYSTEM_UNKNOWN + && mMeasuredEnergySnapshots[subsystem] != UNAVAILABLE) { + mAccumulatedEnergiesMicroJoules[bucket] = energyUJ; + } + } + } + + /** + * Write to summary parcel. + * Note: Measured subsystem availability may be different when the summary parcel is read. + * Note: {@link com.android.internal.os.BatteryStatsImpl#VERSION} must be updated if summary + * parceling changes. + */ + private void writeSummaryToParcel(Parcel out) { + final int sizePos = out.dataPosition(); + out.writeInt(0); + int size = 0; + // Write only the buckets with reported energy + for (int i = 0; i < NUMBER_ENERGY_BUCKETS; i++) { + final int subsystem = getSubsystem(i); + if (mMeasuredEnergySnapshots[subsystem] == UNAVAILABLE) continue; + + out.writeInt(i); + out.writeLong(mAccumulatedEnergiesMicroJoules[i]); + size++; + } + final int currPos = out.dataPosition(); + out.setDataPosition(sizePos); + out.writeInt(size); + out.setDataPosition(currPos); + } + + /** + * Update with the latest measured energies and device state. + * + * @param energyArray measured energy array for some subsystems. + * @param screenState screen state to attribute disaply energy to after this update. + * @param accumulate whether or not to accumulate the latest energy + */ + public void update(MeasuredEnergyArray energyArray, int screenState, boolean accumulate) { + final int size = energyArray.size(); + if (!accumulate) { + for (int i = 0; i < size; i++) { + final int subsystem = energyArray.getSubsystem(i); + mMeasuredEnergySnapshots[subsystem] = energyArray.getEnergy(i); + } + } else { + for (int i = 0; i < size; i++) { + final int subsystem = energyArray.getSubsystem(i); + final long newEnergyUJ = energyArray.getEnergy(i); + final long oldEnergyUJ = mMeasuredEnergySnapshots[subsystem]; + mMeasuredEnergySnapshots[subsystem] = newEnergyUJ; + + // This is the first valid energy, skip accumulating the delta + if (oldEnergyUJ < 0) continue; + final long deltaUJ = newEnergyUJ - oldEnergyUJ; + + final int bucket = getEnergyBucket(subsystem, mLastScreenState); + mAccumulatedEnergiesMicroJoules[bucket] += deltaUJ; + } + } + mLastScreenState = screenState; + } + + /** + * Map {@link MeasuredEnergySubsystem} and device state to an {@link EnergyBucket}. + * Keep in sync with {@link #getSubsystem} + */ + @EnergyBucket + private int getEnergyBucket(@MeasuredEnergySubsystem int subsystem, int screenState) { + switch (subsystem) { + case MeasuredEnergyArray.SUBSYSTEM_DISPLAY: + if (Display.isOnState(screenState)) { + return ENERGY_BUCKET_SCREEN_ON; + } else if (Display.isDozeState(screenState)) { + return ENERGY_BUCKET_SCREEN_DOZE; + } else { + return ENERGY_BUCKET_SCREEN_OTHER; + } + default: + return ENERGY_BUCKET_UNKNOWN; + } + } + + /** + * Map {@link EnergyBucket} to a {@link MeasuredEnergySubsystem}. + * Keep in sync with {@link #getEnergyBucket} + */ + @MeasuredEnergySubsystem + private int getSubsystem(@EnergyBucket int bucket) { + switch (bucket) { + case ENERGY_BUCKET_SCREEN_ON: //fallthrough + case ENERGY_BUCKET_SCREEN_DOZE: //fallthrough + case ENERGY_BUCKET_SCREEN_OTHER: + return MeasuredEnergyArray.SUBSYSTEM_DISPLAY; + default: + return MeasuredEnergyArray.SUBSYSTEM_UNKNOWN; + } + } + + /** + * Check if a subsystem's measured energy is available. + * @param subsystem which subsystem. + * @return true if subsystem is avaiable. + */ + public boolean hasSubsystem(@MeasuredEnergySubsystem int subsystem) { + return mMeasuredEnergySnapshots[subsystem] != UNAVAILABLE; + } + + /** + * Return accumulated energy (in microjoules) since last reset. + */ + public long getAccumulatedBucketEnergy(@EnergyBucket int bucket) { + return mAccumulatedEnergiesMicroJoules[bucket]; + } + + /** + * Populate a MeasuredEnergyStats from a parcel. If the stats is null, consume and + * ignore the parcelled data. + */ + public static void readSummaryFromParcel(@Nullable MeasuredEnergyStats stats, Parcel in) { + // Check if any MeasuredEnergyStats exists on the parcel + if (in.readInt() == 0) return; + + // If stats is null, create a placeholder MeasuredEnergyStats to consume the parcel data + final MeasuredEnergyStats mes = stats != null ? stats : new MeasuredEnergyStats(); + mes.readSummaryFromParcel(in); + } + + /** + * Write a MeasuredEnergyStats to a parcel. If the stats is null, just write a 0. + */ + public static void writeSummaryToParcel(@Nullable MeasuredEnergyStats stats, + Parcel dest) { + if (stats == null) { + dest.writeInt(0); + return; + } + dest.writeInt(1); + stats.writeSummaryToParcel(dest); + } + + /** + * Reset accumulated energy. + */ + public void reset() { + for (int i = 0; i < MeasuredEnergyArray.NUMBER_SUBSYSTEMS; i++) { + // Leave subsystems marked as unavailable alone. + if (mMeasuredEnergySnapshots[i] == UNAVAILABLE) continue; + mMeasuredEnergySnapshots[i] = RESET; + } + Arrays.fill(mAccumulatedEnergiesMicroJoules, 0); + } + + /** + * Dump debug data. + */ + public void dump(PrintWriter pw) { + pw.println("Measured energy snapshot (microjoules):"); + pw.print(" "); + for (int i = 0; i < MeasuredEnergyArray.NUMBER_SUBSYSTEMS; i++) { + final long energyUJ = mMeasuredEnergySnapshots[i]; + if (energyUJ == UNAVAILABLE) continue; + pw.print(MeasuredEnergyArray.SUBSYSTEM_NAMES[i]); + pw.print(" : "); + if (energyUJ == RESET) { + pw.print("reset"); + } else { + pw.print(energyUJ); + } + if (i != MeasuredEnergyArray.NUMBER_SUBSYSTEMS - 1) { + pw.print(", "); + } + } + pw.println(); + + pw.println("Accumulated energy since last reset (microjoules):"); + pw.print(" "); + for (int i = 0; i < NUMBER_ENERGY_BUCKETS; i++) { + pw.print(ENERGY_BUCKET_NAMES[i]); + pw.print(" : "); + pw.print(mAccumulatedEnergiesMicroJoules[i]); + if (i != NUMBER_ENERGY_BUCKETS - 1) { + pw.print(", "); + } + } + pw.println(); + } +} diff --git a/core/java/com/android/internal/util/function/pooled/OWNERS b/core/java/com/android/internal/util/function/pooled/OWNERS new file mode 100644 index 000000000000..da723b3b67da --- /dev/null +++ b/core/java/com/android/internal/util/function/pooled/OWNERS @@ -0,0 +1 @@ +eugenesusla@google.com
\ No newline at end of file diff --git a/core/java/com/android/internal/view/IInputMethodClient.aidl b/core/java/com/android/internal/view/IInputMethodClient.aidl index 1145f5183206..ec9a0a2f4801 100644 --- a/core/java/com/android/internal/view/IInputMethodClient.aidl +++ b/core/java/com/android/internal/view/IInputMethodClient.aidl @@ -25,7 +25,7 @@ import com.android.internal.view.InputBindResult; oneway interface IInputMethodClient { void onBindMethod(in InputBindResult res); void onUnbindMethod(int sequence, int unbindReason); - void setActive(boolean active, boolean fullscreen); + void setActive(boolean active, boolean fullscreen, boolean reportToImeController); void scheduleStartInputIfNecessary(boolean fullscreen); void reportFullscreenMode(boolean fullscreen); void applyImeVisibility(boolean setVisible); diff --git a/core/java/com/android/internal/view/IInputMethodManager.aidl b/core/java/com/android/internal/view/IInputMethodManager.aidl index 844c56bd3529..33abbe82c109 100644 --- a/core/java/com/android/internal/view/IInputMethodManager.aidl +++ b/core/java/com/android/internal/view/IInputMethodManager.aidl @@ -79,4 +79,9 @@ interface IInputMethodManager { void removeImeSurfaceFromWindow(in IBinder windowToken); void startProtoDump(in byte[] protoDump, int source, String where); boolean isImeTraceEnabled(); + + // Starts an ime trace. + void startImeTrace(); + // Stops an ime trace. + void stopImeTrace(); } diff --git a/core/java/com/android/internal/view/IInputMethodSession.aidl b/core/java/com/android/internal/view/IInputMethodSession.aidl index 0319e3637384..c6afd78ec04b 100644 --- a/core/java/com/android/internal/view/IInputMethodSession.aidl +++ b/core/java/com/android/internal/view/IInputMethodSession.aidl @@ -52,4 +52,6 @@ oneway interface IInputMethodSession { void notifyImeHidden(); void removeImeSurface(); + + void finishInput(); } diff --git a/core/java/com/android/internal/view/InputConnectionWrapper.java b/core/java/com/android/internal/view/InputConnectionWrapper.java index ec4fe17746ee..8c763a6efe54 100644 --- a/core/java/com/android/internal/view/InputConnectionWrapper.java +++ b/core/java/com/android/internal/view/InputConnectionWrapper.java @@ -24,7 +24,6 @@ import android.inputmethodservice.AbstractInputMethodService; import android.os.Bundle; import android.os.Handler; import android.os.RemoteException; -import android.util.Log; import android.view.KeyEvent; import android.view.inputmethod.CompletionInfo; import android.view.inputmethod.CorrectionInfo; @@ -41,7 +40,6 @@ import com.android.internal.inputmethod.Completable; import com.android.internal.inputmethod.ResultCallbacks; import java.lang.ref.WeakReference; -import java.util.concurrent.TimeUnit; public class InputConnectionWrapper implements InputConnection { private static final String TAG = "InputConnectionWrapper"; @@ -73,43 +71,6 @@ public class InputConnectionWrapper implements InputConnection { mCancellationGroup = cancellationGroup; } - @AnyThread - private static void logInternal(@Nullable String methodName, boolean timedOut, - @Nullable Object defaultValue) { - if (timedOut) { - Log.w(TAG, methodName + " didn't respond in " + MAX_WAIT_TIME_MILLIS + " msec." - + " Returning default: " + defaultValue); - } else { - Log.w(TAG, methodName + " was canceled before complete. Returning default: " - + defaultValue); - } - } - - @AnyThread - private static int getResultOrZero(@NonNull Completable.Int value, @NonNull String methodName, - @Nullable CancellationGroup cancellationGroup) { - final boolean timedOut = - value.await(MAX_WAIT_TIME_MILLIS, TimeUnit.MILLISECONDS, cancellationGroup); - if (value.hasValue()) { - return value.getValue(); - } - logInternal(methodName, timedOut, 0); - return 0; - } - - @AnyThread - @Nullable - private static <T> T getResultOrNull(@NonNull Completable.Values<T> value, - @NonNull String methodName, @Nullable CancellationGroup cancellationGroup) { - final boolean timedOut = - value.await(MAX_WAIT_TIME_MILLIS, TimeUnit.MILLISECONDS, cancellationGroup); - if (value.hasValue()) { - return value.getValue(); - } - logInternal(methodName, timedOut, null); - return null; - } - /** * See {@link InputConnection#getTextAfterCursor(int, int)}. */ @@ -126,7 +87,8 @@ public class InputConnectionWrapper implements InputConnection { } catch (RemoteException e) { return null; } - return getResultOrNull(value, "getTextAfterCursor()", mCancellationGroup); + return Completable.getResultOrNull( + value, TAG, "getTextAfterCursor()", mCancellationGroup, MAX_WAIT_TIME_MILLIS); } /** @@ -145,7 +107,8 @@ public class InputConnectionWrapper implements InputConnection { } catch (RemoteException e) { return null; } - return getResultOrNull(value, "getTextBeforeCursor()", mCancellationGroup); + return Completable.getResultOrNull( + value, TAG, "getTextBeforeCursor()", mCancellationGroup, MAX_WAIT_TIME_MILLIS); } @AnyThread @@ -164,7 +127,8 @@ public class InputConnectionWrapper implements InputConnection { } catch (RemoteException e) { return null; } - return getResultOrNull(value, "getSelectedText()", mCancellationGroup); + return Completable.getResultOrNull( + value, TAG, "getSelectedText()", mCancellationGroup, MAX_WAIT_TIME_MILLIS); } /** @@ -197,7 +161,8 @@ public class InputConnectionWrapper implements InputConnection { } catch (RemoteException e) { return null; } - return getResultOrNull(value, "getSurroundingText()", mCancellationGroup); + return Completable.getResultOrNull( + value, TAG, "getSurroundingText()", mCancellationGroup, MAX_WAIT_TIME_MILLIS); } @AnyThread @@ -212,7 +177,8 @@ public class InputConnectionWrapper implements InputConnection { } catch (RemoteException e) { return 0; } - return getResultOrZero(value, "getCursorCapsMode()", mCancellationGroup); + return Completable.getResultOrZero( + value, TAG, "getCursorCapsMode()", mCancellationGroup, MAX_WAIT_TIME_MILLIS); } @AnyThread @@ -227,7 +193,8 @@ public class InputConnectionWrapper implements InputConnection { } catch (RemoteException e) { return null; } - return getResultOrNull(value, "getExtractedText()", mCancellationGroup); + return Completable.getResultOrNull( + value, TAG, "getExtractedText()", mCancellationGroup, MAX_WAIT_TIME_MILLIS); } @AnyThread @@ -438,7 +405,8 @@ public class InputConnectionWrapper implements InputConnection { } catch (RemoteException e) { return false; } - return getResultOrZero(value, "requestUpdateCursorAnchorInfo()", mCancellationGroup) != 0; + return Completable.getResultOrZero(value, TAG, "requestUpdateCursorAnchorInfo()", + mCancellationGroup, MAX_WAIT_TIME_MILLIS) != 0; } @AnyThread @@ -478,7 +446,8 @@ public class InputConnectionWrapper implements InputConnection { } catch (RemoteException e) { return false; } - return getResultOrZero(value, "commitContent()", mCancellationGroup) != 0; + return Completable.getResultOrZero( + value, TAG, "commitContent()", mCancellationGroup, MAX_WAIT_TIME_MILLIS) != 0; } @AnyThread diff --git a/core/java/com/android/internal/widget/FloatingToolbar.java b/core/java/com/android/internal/widget/FloatingToolbar.java index 58817a8a48a9..514e0b8e0ded 100644 --- a/core/java/com/android/internal/widget/FloatingToolbar.java +++ b/core/java/com/android/internal/widget/FloatingToolbar.java @@ -61,12 +61,17 @@ import android.widget.PopupWindow; import android.widget.TextView; import com.android.internal.R; +import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.Preconditions; import java.util.ArrayList; +import java.util.Collection; import java.util.Comparator; +import java.util.Iterator; +import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; +import java.util.Map; import java.util.Objects; /** @@ -93,7 +98,6 @@ public final class FloatingToolbar { private final Rect mPreviousContentRect = new Rect(); private Menu mMenu; - private List<MenuItem> mShowingMenuItems = new ArrayList<>(); private MenuItem.OnMenuItemClickListener mMenuItemClickListener = NO_OP_MENUITEM_CLICK_LISTENER; private int mSuggestedWidth; @@ -274,10 +278,11 @@ public final class FloatingToolbar { private void doShow() { List<MenuItem> menuItems = getVisibleAndEnabledMenuItems(mMenu); menuItems.sort(mMenuItemComparator); - if (!isCurrentlyShowing(menuItems) || mWidthChanged) { + if (mPopup.isLayoutRequired(menuItems) || mWidthChanged) { mPopup.dismiss(); mPopup.layoutMenuItems(menuItems, mMenuItemClickListener, mSuggestedWidth); - mShowingMenuItems = menuItems; + } else { + mPopup.updateMenuItems(menuItems, mMenuItemClickListener); } if (!mPopup.isShowing()) { mPopup.show(mContentRect); @@ -289,33 +294,10 @@ public final class FloatingToolbar { } /** - * Returns true if this floating toolbar is currently showing the specified menu items. - */ - private boolean isCurrentlyShowing(List<MenuItem> menuItems) { - if (mShowingMenuItems == null || menuItems.size() != mShowingMenuItems.size()) { - return false; - } - - final int size = menuItems.size(); - for (int i = 0; i < size; i++) { - final MenuItem menuItem = menuItems.get(i); - final MenuItem showingItem = mShowingMenuItems.get(i); - if (menuItem.getItemId() != showingItem.getItemId() - || !TextUtils.equals(menuItem.getTitle(), showingItem.getTitle()) - || !Objects.equals(menuItem.getIcon(), showingItem.getIcon()) - || menuItem.getGroupId() != showingItem.getGroupId()) { - return false; - } - } - - return true; - } - - /** * Returns the visible and enabled menu items in the specified menu. * This method is recursive. */ - private List<MenuItem> getVisibleAndEnabledMenuItems(Menu menu) { + private static List<MenuItem> getVisibleAndEnabledMenuItems(Menu menu) { List<MenuItem> menuItems = new ArrayList<>(); for (int i = 0; (menu != null) && (i < menu.size()); i++) { MenuItem menuItem = menu.getItem(i); @@ -427,17 +409,25 @@ public final class FloatingToolbar { private Size mOverflowPanelSize; // Should be null when there is no overflow. private Size mMainPanelSize; - /* Item click listeners */ + /* Menu items and click listeners */ + private final Map<MenuItemRepr, MenuItem> mMenuItems = new LinkedHashMap<>(); private MenuItem.OnMenuItemClickListener mOnMenuItemClickListener; private final View.OnClickListener mMenuItemButtonOnClickListener = new View.OnClickListener() { @Override public void onClick(View v) { - if (v.getTag() instanceof MenuItem) { - if (mOnMenuItemClickListener != null) { - mOnMenuItemClickListener.onMenuItemClick((MenuItem) v.getTag()); - } + if (mOnMenuItemClickListener == null) { + return; + } + final Object tag = v.getTag(); + if (!(tag instanceof MenuItemRepr)) { + return; } + final MenuItem menuItem = mMenuItems.get((MenuItemRepr) tag); + if (menuItem == null) { + return; + } + mOnMenuItemClickListener.onMenuItemClick(menuItem); } }; @@ -558,9 +548,9 @@ public final class FloatingToolbar { List<MenuItem> menuItems, MenuItem.OnMenuItemClickListener menuItemClickListener, int suggestedWidth) { - mOnMenuItemClickListener = menuItemClickListener; cancelOverflowAnimations(); clearPanels(); + updateMenuItems(menuItems, menuItemClickListener); menuItems = layoutMainPanelItems(menuItems, getAdjustedToolbarWidth(suggestedWidth)); if (!menuItems.isEmpty()) { // Add remaining items to the overflow. @@ -570,6 +560,28 @@ public final class FloatingToolbar { } /** + * Updates the popup's menu items without rebuilding the widget. + * Use in place of layoutMenuItems() when the popup's views need not be reconstructed. + * + * @see isLayoutRequired(List<MenuItem>) + */ + public void updateMenuItems( + List<MenuItem> menuItems, MenuItem.OnMenuItemClickListener menuItemClickListener) { + mMenuItems.clear(); + for (MenuItem menuItem : menuItems) { + mMenuItems.put(MenuItemRepr.of(menuItem), menuItem); + } + mOnMenuItemClickListener = menuItemClickListener; + } + + /** + * Returns true if this popup needs a relayout to properly render the specified menu items. + */ + public boolean isLayoutRequired(List<MenuItem> menuItems) { + return !MenuItemRepr.reprEquals(menuItems, mMenuItems.values()); + } + + /** * Shows this popup at the specified coordinates. * The specified coordinates may be adjusted to make sure the popup is entirely on-screen. */ @@ -1374,7 +1386,7 @@ public final class FloatingToolbar { } private void setButtonTagAndClickListener(View menuItemButton, MenuItem menuItem) { - menuItemButton.setTag(menuItem); + menuItemButton.setTag(MenuItemRepr.of(menuItem)); menuItemButton.setOnClickListener(mMenuItemButtonOnClickListener); } @@ -1656,6 +1668,85 @@ public final class FloatingToolbar { } /** + * Represents the identity of a MenuItem that is rendered in a FloatingToolbarPopup. + */ + @VisibleForTesting + public static final class MenuItemRepr { + + public final int itemId; + public final int groupId; + @Nullable public final String title; + @Nullable private final Drawable mIcon; + + private MenuItemRepr( + int itemId, int groupId, @Nullable CharSequence title, @Nullable Drawable icon) { + this.itemId = itemId; + this.groupId = groupId; + this.title = (title == null) ? null : title.toString(); + mIcon = icon; + } + + /** + * Creates an instance of MenuItemRepr for the specified menu item. + */ + public static MenuItemRepr of(MenuItem menuItem) { + return new MenuItemRepr( + menuItem.getItemId(), + menuItem.getGroupId(), + menuItem.getTitle(), + menuItem.getIcon()); + } + + /** + * Returns this object's hashcode. + */ + @Override + public int hashCode() { + return Objects.hash(itemId, groupId, title, mIcon); + } + + /** + * Returns true if this object is the same as the specified object. + */ + @Override + public boolean equals(Object o) { + if (o == this) { + return true; + } + if (!(o instanceof MenuItemRepr)) { + return false; + } + final MenuItemRepr other = (MenuItemRepr) o; + return itemId == other.itemId + && groupId == other.groupId + && TextUtils.equals(title, other.title) + // Many Drawables (icons) do not implement equals(). Using equals() here instead + // of reference comparisons in case a Drawable subclass implements equals(). + && Objects.equals(mIcon, other.mIcon); + } + + /** + * Returns true if the two menu item collections are the same based on MenuItemRepr. + */ + public static boolean reprEquals( + Collection<MenuItem> menuItems1, Collection<MenuItem> menuItems2) { + if (menuItems1.size() != menuItems2.size()) { + return false; + } + + final Iterator<MenuItem> menuItems2Iter = menuItems2.iterator(); + for (MenuItem menuItem1 : menuItems1) { + final MenuItem menuItem2 = menuItems2Iter.next(); + if (!MenuItemRepr.of(menuItem1).equals(MenuItemRepr.of(menuItem2))) { + return false; + } + } + + return true; + } + } + + /** * Creates and returns a menu button for the specified menu item. */ private static View createMenuItemButton( diff --git a/core/jni/android_view_DisplayEventReceiver.cpp b/core/jni/android_view_DisplayEventReceiver.cpp index e7e9c31ef90e..6337680147a5 100644 --- a/core/jni/android_view_DisplayEventReceiver.cpp +++ b/core/jni/android_view_DisplayEventReceiver.cpp @@ -41,14 +41,21 @@ static struct { jmethodID dispatchVsync; jmethodID dispatchHotplug; jmethodID dispatchConfigChanged; + jmethodID dispatchFrameRateOverrides; + + struct { + jclass clazz; + jmethodID init; + } frameRateOverrideClassInfo; + } gDisplayEventReceiverClassInfo; class NativeDisplayEventReceiver : public DisplayEventDispatcher { public: - NativeDisplayEventReceiver(JNIEnv* env, - jobject receiverWeak, const sp<MessageQueue>& messageQueue, jint vsyncSource, - jint configChanged); + NativeDisplayEventReceiver(JNIEnv* env, jobject receiverWeak, + const sp<MessageQueue>& messageQueue, jint vsyncSource, + jint eventRegistration); void dispose(); @@ -64,16 +71,17 @@ private: void dispatchHotplug(nsecs_t timestamp, PhysicalDisplayId displayId, bool connected) override; void dispatchConfigChanged(nsecs_t timestamp, PhysicalDisplayId displayId, int32_t configId, nsecs_t vsyncPeriod) override; + void dispatchFrameRateOverrides(nsecs_t timestamp, PhysicalDisplayId displayId, + std::vector<FrameRateOverride> overrides) override; void dispatchNullEvent(nsecs_t timestamp, PhysicalDisplayId displayId) override {} }; - -NativeDisplayEventReceiver::NativeDisplayEventReceiver(JNIEnv* env, - jobject receiverWeak, const sp<MessageQueue>& messageQueue, jint vsyncSource, - jint configChanged) : - DisplayEventDispatcher(messageQueue->getLooper(), - static_cast<ISurfaceComposer::VsyncSource>(vsyncSource), - static_cast<ISurfaceComposer::ConfigChanged>(configChanged)), +NativeDisplayEventReceiver::NativeDisplayEventReceiver(JNIEnv* env, jobject receiverWeak, + const sp<MessageQueue>& messageQueue, + jint vsyncSource, jint eventRegistration) + : DisplayEventDispatcher(messageQueue->getLooper(), + static_cast<ISurfaceComposer::VsyncSource>(vsyncSource), + static_cast<ISurfaceComposer::EventRegistration>(eventRegistration)), mReceiverWeakGlobal(env->NewGlobalRef(receiverWeak)), mMessageQueue(messageQueue) { ALOGV("receiver %p ~ Initializing display event receiver.", this); @@ -137,16 +145,48 @@ void NativeDisplayEventReceiver::dispatchConfigChanged( mMessageQueue->raiseAndClearException(env, "dispatchConfigChanged"); } -static jlong nativeInit(JNIEnv* env, jclass clazz, jobject receiverWeak, - jobject messageQueueObj, jint vsyncSource, jint configChanged) { +void NativeDisplayEventReceiver::dispatchFrameRateOverrides( + nsecs_t timestamp, PhysicalDisplayId displayId, std::vector<FrameRateOverride> overrides) { + JNIEnv* env = AndroidRuntime::getJNIEnv(); + + ScopedLocalRef<jobject> receiverObj(env, jniGetReferent(env, mReceiverWeakGlobal)); + if (receiverObj.get()) { + ALOGV("receiver %p ~ Invoking FrameRateOverride handler.", this); + const auto frameRateOverrideClass = + gDisplayEventReceiverClassInfo.frameRateOverrideClassInfo.clazz; + const auto frameRateOverrideInit = + gDisplayEventReceiverClassInfo.frameRateOverrideClassInfo.init; + auto frameRateOverrideInitObject = + env->NewObject(frameRateOverrideClass, frameRateOverrideInit, 0, 0); + auto frameRateOverrideArray = env->NewObjectArray(overrides.size(), frameRateOverrideClass, + frameRateOverrideInitObject); + for (size_t i = 0; i < overrides.size(); i++) { + auto FrameRateOverrideObject = + env->NewObject(frameRateOverrideClass, frameRateOverrideInit, overrides[i].uid, + overrides[i].frameRateHz); + env->SetObjectArrayElement(frameRateOverrideArray, i, FrameRateOverrideObject); + } + + env->CallVoidMethod(receiverObj.get(), + gDisplayEventReceiverClassInfo.dispatchFrameRateOverrides, timestamp, + displayId.value, frameRateOverrideArray); + ALOGV("receiver %p ~ Returned from FrameRateOverride handler.", this); + } + + mMessageQueue->raiseAndClearException(env, "dispatchConfigChanged"); +} + +static jlong nativeInit(JNIEnv* env, jclass clazz, jobject receiverWeak, jobject messageQueueObj, + jint vsyncSource, jint eventRegistration) { sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj); if (messageQueue == NULL) { jniThrowRuntimeException(env, "MessageQueue is not initialized."); return 0; } - sp<NativeDisplayEventReceiver> receiver = new NativeDisplayEventReceiver(env, - receiverWeak, messageQueue, vsyncSource, configChanged); + sp<NativeDisplayEventReceiver> receiver = + new NativeDisplayEventReceiver(env, receiverWeak, messageQueue, vsyncSource, + eventRegistration); status_t status = receiver->initialize(); if (status) { String8 message; @@ -205,6 +245,18 @@ int register_android_view_DisplayEventReceiver(JNIEnv* env) { gDisplayEventReceiverClassInfo.clazz, "dispatchHotplug", "(JJZ)V"); gDisplayEventReceiverClassInfo.dispatchConfigChanged = GetMethodIDOrDie(env, gDisplayEventReceiverClassInfo.clazz, "dispatchConfigChanged", "(JJI)V"); + gDisplayEventReceiverClassInfo.dispatchFrameRateOverrides = + GetMethodIDOrDie(env, gDisplayEventReceiverClassInfo.clazz, + "dispatchFrameRateOverrides", + "(JJ[Landroid/view/DisplayEventReceiver$FrameRateOverride;)V"); + + jclass frameRateOverrideClazz = + FindClassOrDie(env, "android/view/DisplayEventReceiver$FrameRateOverride"); + gDisplayEventReceiverClassInfo.frameRateOverrideClassInfo.clazz = + MakeGlobalRefOrDie(env, frameRateOverrideClazz); + gDisplayEventReceiverClassInfo.frameRateOverrideClassInfo.init = + GetMethodIDOrDie(env, gDisplayEventReceiverClassInfo.frameRateOverrideClassInfo.clazz, + "<init>", "(IF)V"); return res; } diff --git a/core/proto/Android.bp b/core/proto/Android.bp deleted file mode 100644 index 3b891d6b4947..000000000000 --- a/core/proto/Android.bp +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (C) 2018 The Android Open Source Project -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// C++ library for Bluetooth platform wide protobuf definitions -cc_library_static { - name: "libbt-platform-protos-lite", - host_supported: true, - proto: { - export_proto_headers: true, - type: "lite", - }, - srcs: [ - "android/bluetooth/a2dp/enums.proto", - "android/bluetooth/enums.proto", - "android/bluetooth/hci/enums.proto", - "android/bluetooth/hfp/enums.proto", - "android/bluetooth/smp/enums.proto", - ], -} diff --git a/core/proto/OWNERS b/core/proto/OWNERS index 542d26fa233e..5eeeb048e6d6 100644 --- a/core/proto/OWNERS +++ b/core/proto/OWNERS @@ -25,3 +25,18 @@ hyunyoungs@google.com # Graphics stats jreck@google.com + +# Temporary Block to assist in migration +# Bug: 143080132 +per-file *enums.proto = baligh@google.com, yro@google.com, jeffreyhuang@google.com +per-file *media_output_enum.proto = baligh@google.com, yro@google.com, jeffreyhuang@google.com +per-file *networkcapabilities.proto = baligh@google.com, yro@google.com, jeffreyhuang@google.com +per-file *data_stall_event.proto = baligh@google.com, yro@google.com, jeffreyhuang@google.com +per-file *procstats_enum.proto = baligh@google.com, yro@google.com, jeffreyhuang@google.com +per-file *usb.proto = baligh@google.com, yro@google.com, jeffreyhuang@google.com +per-file *network_stack.proto = baligh@google.com, yro@google.com, jeffreyhuang@google.com +per-file *tethering.proto = baligh@google.com, yro@google.com, jeffreyhuang@google.com +per-file *dns_resolver.proto = baligh@google.com, yro@google.com, jeffreyhuang@google.com +per-file *device_policy.proto = baligh@google.com, yro@google.com, jeffreyhuang@google.com +per-file *launcher.proto = baligh@google.com, yro@google.com, jeffreyhuang@google.com +per-file *mediametrics.proto = baligh@google.com, yro@google.com, jeffreyhuang@google.com diff --git a/core/proto/android/app/enums.proto b/core/proto/android/app/enums.proto deleted file mode 100644 index 722194b322c6..000000000000 --- a/core/proto/android/app/enums.proto +++ /dev/null @@ -1,215 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -syntax = "proto2"; - -package android.app; - -option java_outer_classname = "AppProtoEnums"; -option java_multiple_files = true; - -// ActivityManagerInternal.java's APP_TRANSITION reasons. -enum AppTransitionReasonEnum { - APP_TRANSITION_REASON_UNKNOWN = 0; - // The transition was started because we drew the splash screen. - APP_TRANSITION_SPLASH_SCREEN = 1; - // The transition was started because we all app windows were drawn. - APP_TRANSITION_WINDOWS_DRAWN = 2; - // The transition was started because of a timeout. - APP_TRANSITION_TIMEOUT = 3; - // The transition was started because of a we drew a task snapshot. - APP_TRANSITION_SNAPSHOT = 4; - // The transition was started because it was a recents animation and we only needed to wait on - // the wallpaper. - APP_TRANSITION_RECENTS_ANIM = 5; -} - -// ActivityManager.java PROCESS_STATEs -// Next tag: 1021 -enum ProcessStateEnum { - // Unlike the ActivityManager PROCESS_STATE values, the ordering and numerical values - // here are completely fixed and arbitrary. Order is irrelevant. - // No attempt need be made to keep them in sync. - // The values here must not be modified. Any new process states can be appended to the end. - - // Process state that is unknown to this proto file (i.e. is not mapped - // by ActivityManager.processStateAmToProto()). Can only happen if there's a bug in the mapping. - PROCESS_STATE_UNKNOWN_TO_PROTO = 998; - // Not a real process state. - PROCESS_STATE_UNKNOWN = 999; - // Process is a persistent system process. - PROCESS_STATE_PERSISTENT = 1000; - // Process is a persistent system process and is doing UI. - PROCESS_STATE_PERSISTENT_UI = 1001; - // Process is hosting the current top activities. Note that this covers - // all activities that are visible to the user. - PROCESS_STATE_TOP = 1002; - // Process is bound to a TOP app. - PROCESS_STATE_BOUND_TOP = 1020; - // Process is hosting a foreground service. - PROCESS_STATE_FOREGROUND_SERVICE = 1003; - // Process is hosting a service bound by the system or another foreground app. - PROCESS_STATE_BOUND_FOREGROUND_SERVICE = 1004; - // Process is important to the user, and something they are aware of. - PROCESS_STATE_IMPORTANT_FOREGROUND = 1005; - // Process is important to the user, but not something they are aware of. - PROCESS_STATE_IMPORTANT_BACKGROUND = 1006; - // Process is in the background transient so we will try to keep running. - PROCESS_STATE_TRANSIENT_BACKGROUND = 1007; - // Process is in the background running a backup/restore operation. - PROCESS_STATE_BACKUP = 1008; - // Process is in the background running a service. Unlike oom_adj, this - // level is used for both the normal running in background state and the - // executing operations state. - PROCESS_STATE_SERVICE = 1009; - // Process is in the background running a receiver. Note that from the - // perspective of oom_adj, receivers run at a higher foreground level, but - // for our prioritization here that is not necessary and putting them - // below services means many fewer changes in some process states as they - // receive broadcasts. - PROCESS_STATE_RECEIVER = 1010; - // Same as PROCESS_STATE_TOP but while device is sleeping. - PROCESS_STATE_TOP_SLEEPING = 1011; - // Process is in the background, but it can't restore its state so we want - // to try to avoid killing it. - PROCESS_STATE_HEAVY_WEIGHT = 1012; - // Process is in the background but hosts the home activity. - PROCESS_STATE_HOME = 1013; - // Process is in the background but hosts the last shown activity. - PROCESS_STATE_LAST_ACTIVITY = 1014; - // Process is being cached for later use and contains activities. - PROCESS_STATE_CACHED_ACTIVITY = 1015; - // Process is being cached for later use and is a client of another cached - // process that contains activities. - PROCESS_STATE_CACHED_ACTIVITY_CLIENT = 1016; - // Process is being cached for later use and has an activity that corresponds - // to an existing recent task. - PROCESS_STATE_CACHED_RECENT = 1017; - // Process is being cached for later use and is empty. - PROCESS_STATE_CACHED_EMPTY = 1018; - // Process does not exist. - PROCESS_STATE_NONEXISTENT = 1019; -} - -// AppOpsManager.java - operation ids for logging -enum AppOpEnum { - APP_OP_NONE = -1; - APP_OP_COARSE_LOCATION = 0; - APP_OP_FINE_LOCATION = 1; - APP_OP_GPS = 2; - APP_OP_VIBRATE = 3; - APP_OP_READ_CONTACTS = 4; - APP_OP_WRITE_CONTACTS = 5; - APP_OP_READ_CALL_LOG = 6; - APP_OP_WRITE_CALL_LOG = 7; - APP_OP_READ_CALENDAR = 8; - APP_OP_WRITE_CALENDAR = 9; - APP_OP_WIFI_SCAN = 10; - APP_OP_POST_NOTIFICATION = 11; - APP_OP_NEIGHBORING_CELLS = 12; - APP_OP_CALL_PHONE = 13; - APP_OP_READ_SMS = 14; - APP_OP_WRITE_SMS = 15; - APP_OP_RECEIVE_SMS = 16; - APP_OP_RECEIVE_EMERGENCY_SMS = 17; - APP_OP_RECEIVE_MMS = 18; - APP_OP_RECEIVE_WAP_PUSH = 19; - APP_OP_SEND_SMS = 20; - APP_OP_READ_ICC_SMS = 21; - APP_OP_WRITE_ICC_SMS = 22; - APP_OP_WRITE_SETTINGS = 23; - APP_OP_SYSTEM_ALERT_WINDOW = 24; - APP_OP_ACCESS_NOTIFICATIONS = 25; - APP_OP_CAMERA = 26; - APP_OP_RECORD_AUDIO = 27; - APP_OP_PLAY_AUDIO = 28; - APP_OP_READ_CLIPBOARD = 29; - APP_OP_WRITE_CLIPBOARD = 30; - APP_OP_TAKE_MEDIA_BUTTONS = 31; - APP_OP_TAKE_AUDIO_FOCUS = 32; - APP_OP_AUDIO_MASTER_VOLUME = 33; - APP_OP_AUDIO_VOICE_VOLUME = 34; - APP_OP_AUDIO_RING_VOLUME = 35; - APP_OP_AUDIO_MEDIA_VOLUME = 36; - APP_OP_AUDIO_ALARM_VOLUME = 37; - APP_OP_AUDIO_NOTIFICATION_VOLUME = 38; - APP_OP_AUDIO_BLUETOOTH_VOLUME = 39; - APP_OP_WAKE_LOCK = 40; - APP_OP_MONITOR_LOCATION = 41; - APP_OP_MONITOR_HIGH_POWER_LOCATION = 42; - APP_OP_GET_USAGE_STATS = 43; - APP_OP_MUTE_MICROPHONE = 44; - APP_OP_TOAST_WINDOW = 45; - APP_OP_PROJECT_MEDIA = 46; - APP_OP_ACTIVATE_VPN = 47; - APP_OP_WRITE_WALLPAPER = 48; - APP_OP_ASSIST_STRUCTURE = 49; - APP_OP_ASSIST_SCREENSHOT = 50; - APP_OP_READ_PHONE_STATE = 51; - APP_OP_ADD_VOICEMAIL = 52; - APP_OP_USE_SIP = 53; - APP_OP_PROCESS_OUTGOING_CALLS = 54; - APP_OP_USE_FINGERPRINT = 55; - APP_OP_BODY_SENSORS = 56; - APP_OP_READ_CELL_BROADCASTS = 57; - APP_OP_MOCK_LOCATION = 58; - APP_OP_READ_EXTERNAL_STORAGE = 59; - APP_OP_WRITE_EXTERNAL_STORAGE = 60; - APP_OP_TURN_SCREEN_ON = 61; - APP_OP_GET_ACCOUNTS = 62; - APP_OP_RUN_IN_BACKGROUND = 63; - APP_OP_AUDIO_ACCESSIBILITY_VOLUME = 64; - APP_OP_READ_PHONE_NUMBERS = 65; - APP_OP_REQUEST_INSTALL_PACKAGES = 66; - APP_OP_PICTURE_IN_PICTURE = 67; - APP_OP_INSTANT_APP_START_FOREGROUND = 68; - APP_OP_ANSWER_PHONE_CALLS = 69; - APP_OP_RUN_ANY_IN_BACKGROUND = 70; - APP_OP_CHANGE_WIFI_STATE = 71; - APP_OP_REQUEST_DELETE_PACKAGES = 72; - APP_OP_BIND_ACCESSIBILITY_SERVICE = 73; - APP_OP_ACCEPT_HANDOVER = 74; - APP_OP_MANAGE_IPSEC_TUNNELS = 75; - APP_OP_START_FOREGROUND = 76; - APP_OP_BLUETOOTH_SCAN = 77; - APP_OP_USE_BIOMETRIC = 78; - APP_OP_ACTIVITY_RECOGNITION = 79; - APP_OP_SMS_FINANCIAL_TRANSACTIONS = 80; - APP_OP_READ_MEDIA_AUDIO = 81; - APP_OP_WRITE_MEDIA_AUDIO = 82; - APP_OP_READ_MEDIA_VIDEO = 83; - APP_OP_WRITE_MEDIA_VIDEO = 84; - APP_OP_READ_MEDIA_IMAGES = 85; - APP_OP_WRITE_MEDIA_IMAGES = 86; - APP_OP_LEGACY_STORAGE = 87; - APP_OP_ACCESS_ACCESSIBILITY = 88; - APP_OP_READ_DEVICE_IDENTIFIERS = 89; - APP_OP_ACCESS_MEDIA_LOCATION = 90; - APP_OP_QUERY_ALL_PACKAGES = 91; - APP_OP_MANAGE_EXTERNAL_STORAGE = 92; - APP_OP_INTERACT_ACROSS_PROFILES = 93; - APP_OP_ACTIVATE_PLATFORM_VPN = 94; - APP_OP_LOADER_USAGE_STATS = 95; - APP_OP_DEPRECATED_1 = 96 [deprecated = true]; - APP_OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED = 97; - APP_OP_AUTO_REVOKE_MANAGED_BY_INSTALLER = 98; - APP_OP_NO_ISOLATED_STORAGE = 99; - APP_OP_PHONE_CALL_MICROPHONE = 100; - APP_OP_PHONE_CALL_CAMERA = 101; - APP_OP_RECORD_AUDIO_HOTWORD = 102; - APP_OP_MANAGE_ONGOING_CALLS = 103; - APP_OP_MANAGE_CREDENTIALS = 104; -} diff --git a/core/proto/android/app/job/enums.proto b/core/proto/android/app/job/enums.proto deleted file mode 100644 index 41863bbbfbf1..000000000000 --- a/core/proto/android/app/job/enums.proto +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -syntax = "proto2"; - -package android.app.job; - -// This file is for JobScheduler enums inside the app directory. If you're -// adding enums for system-server-side code, use the file in -// frameworks/base/core/proto/android/server/job. -option java_outer_classname = "JobProtoEnums"; -option java_multiple_files = true; - -// Reasons a job is stopped. -// Primarily used in android.app.job.JobParameters.java. -enum StopReasonEnum { - STOP_REASON_UNKNOWN = -1; - STOP_REASON_CANCELLED = 0; - STOP_REASON_CONSTRAINTS_NOT_SATISFIED = 1; - STOP_REASON_PREEMPT = 2; - STOP_REASON_TIMEOUT = 3; - STOP_REASON_DEVICE_IDLE = 4; - STOP_REASON_DEVICE_THERMAL = 5; - STOP_REASON_RESTRICTED_BUCKET = 6; -} diff --git a/core/proto/android/app/media_output_enum.proto b/core/proto/android/app/media_output_enum.proto deleted file mode 100644 index 0d42fb77025a..000000000000 --- a/core/proto/android/app/media_output_enum.proto +++ /dev/null @@ -1,65 +0,0 @@ -/* - * 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. - */ - -syntax = "proto2"; - -package android.app.settings.mediaoutput; -option java_multiple_files = true; - -/** - * The medium type specified in an output switching operation. - */ -enum MediumType { - UNKNOWN_TYPE = 0; - BUILTIN_SPEAKER = 1; - WIRED_3POINT5_MM_AUDIO = 100; - WIRED_3POINT5_MM_HEADSET = 101; - WIRED_3POINT5_MM_HEADPHONES = 102; - USB_C_AUDIO = 200; - USB_C_DEVICE = 201; - USB_C_HEADSET = 202; - USB_C_ACCESSORY = 203; - USB_C_DOCK = 204; - USB_C_HDMI = 205; - BLUETOOTH = 300; - BLUETOOTH_HEARING_AID = 301; - BLUETOOTH_A2DP = 302; - REMOTE_SINGLE = 400; - REMOTE_TV = 401; - REMOTE_SPEAKER = 402; - REMOTE_GROUP = 500; - REMOTE_DYNAMIC_GROUP = 501; -}; - -/** - * The result of an output switching operation. - */ -enum SwitchResult { - ERROR = 0; - OK = 1; -}; - -/** - * The sub result of an output switching operation. - */ -enum SubResult { - UNKNOWN_ERROR = 0; - NO_ERROR = 1; - REJECTED = 2; - NETWORK_ERROR = 3; - ROUTE_NOT_AVAILABLE = 4; - INVALID_COMMAND = 5; -} diff --git a/core/proto/android/app/settings_enums.proto b/core/proto/android/app/settings_enums.proto deleted file mode 100644 index a2a7649645f5..000000000000 --- a/core/proto/android/app/settings_enums.proto +++ /dev/null @@ -1,2794 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -syntax = "proto2"; - -package android.app.settings; -option java_multiple_files = true; - -/** - * The action performed in this event - */ -enum Action { - ACTION_UNKNOWN = 0; - PAGE_VISIBLE = 1; - PAGE_HIDE = 2; - - // ACTION: Settings > Wi-Fi > [Long press network] > Connect to network - // SUBTYPE: true if connecting to a saved network, false if not - // CATEGORY: SETTINGS - // OS: 6.0 - ACTION_WIFI_CONNECT = 135; - - // ACTION: Settings > Wi-Fi > [Long press network] > Forget network - // CATEGORY: SETTINGS - // OS: 6.0 - ACTION_WIFI_FORGET = 137; - - // ACTION: Settings > Wi-Fi > Toggle off - // SUBTYPE: true if connected to network before toggle, false if not - // CATEGORY: SETTINGS - // OS: 6.0 - ACTION_WIFI_OFF = 138; - - // ACTION: Settings > Wi-Fi > Toggle on - // CATEGORY: SETTINGS - // OS: 6.0 - ACTION_WIFI_ON = 139; - - // ACTION: Settings > Bluetooth > Overflow > Rename this device - // CATEGORY: SETTINGS - // OS: 6.0 - ACTION_BLUETOOTH_RENAME = 161; - - // ACTION: Settings > Bluetooth > Overflow > Show received files - // CATEGORY: SETTINGS - // OS: 6.0 - ACTION_BLUETOOTH_FILES = 162; - - // ACTION: DND Settings > Priority only allows > Reminder toggle - // SUBTYPE: 0 is off, 1 is on - // CATEGORY: SETTINGS - // OS: 6.0 - ACTION_ZEN_ALLOW_REMINDERS = 167; - - // ACTION: DND Settings > Priority only allows > Event toggle - // SUBTYPE: 0 is off, 1 is on - // CATEGORY: SETTINGS - // OS: 6.0 - ACTION_ZEN_ALLOW_EVENTS = 168; - - // ACTION: DND Settings > Priority only allows > Messages - // SUBTYPE: 0 is off, 1 is on - // CATEGORY: SETTINGS - // OS: 6.0 - ACTION_ZEN_ALLOW_MESSAGES = 169; - - // ACTION: DND Settings > Priority only allows > Calls - // SUBTYPE: 0 is off, 1 is on - // CATEGORY: SETTINGS - // OS: 6.0 - ACTION_ZEN_ALLOW_CALLS = 170; - - // ACTION: DND Settings > Priority only allows > Repeat callers toggle - // SUBTYPE: 0 is off, 1 is on - // CATEGORY: SETTINGS - // OS: 6.0 - ACTION_ZEN_ALLOW_REPEAT_CALLS = 171; - - // ACTION: DND Settings > Automatic rules > [Rule] > Delete rule > Delete - // CATEGORY: SETTINGS - // OS: 6.0 - ACTION_ZEN_DELETE_RULE_OK = 175; - - // ACTION: Settings > More > Airplane mode toggle - // SUBTYPE: 0 is off, 1 is on - // CATEGORY: SETTINGS - // OS: 6.0 - ACTION_AIRPLANE_TOGGLE = 177; - - // ACTION: Settings > Data usage > Cellular data toggle - // SUBTYPE: 0 is off, 1 is on - // CATEGORY: SETTINGS - // OS: 6.0 - ACTION_CELL_DATA_TOGGLE = 178; - - // ACTION: Settings > Display > When device is rotated - // CATEGORY: SETTINGS - // OS: 6.0 - ACTION_ROTATION_LOCK = 203; - - // OPEN: Settings > Search > Perform search - // CATEGORY: SETTINGS - // OS: 6.0 - ACTION_SEARCH_RESULTS = 226; - - // ACTION: Settings > Security > Nexus Imprint > [Fingerprint] > Delete - // CATEGORY: SETTINGS - // OS: 6.0 - ACTION_FINGERPRINT_DELETE = 253; - - // ACTION: Settings > Security > Nexus Imprint > [Fingerprint] > Rename - // CATEGORY: SETTINGS - // OS: 6.0 - ACTION_FINGERPRINT_RENAME = 254; - - // ACTION: Settings -> Developer Options -> Take bug report -> Interactive report - // CATEGORY: SETTINGS - // OS: N - // Interactive bug report initiated from Settings. - ACTION_BUGREPORT_FROM_SETTINGS_INTERACTIVE = 294; - - // ACTION: Settings -> Developer Options -> Take bug report -> Full report - // CATEGORY: SETTINGS - // OS: N - // Interactive bug report initiated from Settings. - ACTION_BUGREPORT_FROM_SETTINGS_FULL = 295; - - // click on collapsed conditional or clicks expand button - ACTION_SETTINGS_CONDITION_EXPAND = 373; - - // click main area of expanded conditional - ACTION_SETTINGS_CONDITION_CLICK = 375; - - // click a direct button on expanded conditional - ACTION_SETTINGS_CONDITION_BUTTON = 376; - - // Action: user enable / disabled data saver using Settings - // OPEN: Settings -> Data Usage -> Data saver -> On/off toggle - // VALUE: 1 for enabled, 0 for disabled - // CATEGORY: SETTINGS - // OS: N - ACTION_DATA_SAVER_MODE = 394; - - // User whitelisted an app for Data Saver mode; action pass package name of app - // Action: user enable / disabled data saver using Settings - // OPEN: Settings -> Data Usage -> Data saver -> Unrestricted data access > APP toggle turned on - // or - // Settings -> Apps -> APP -> Data usage -> Unrestricted data usage toggle turned on - // VALUE: package name of APP - // CATEGORY: SETTINGS - // OS: N - ACTION_DATA_SAVER_WHITELIST = 395; - - // User blacklisted an app for Data Saver mode; action pass package name of app - // OPEN: Settings -> Apps -> APP -> Data usage -> Background data toggle turned off - // VALUE: package name of APP - // CATEGORY: SETTINGS - // OS: N - ACTION_DATA_SAVER_BLACKLIST = 396; - - // ACTION: Settings -> Storage -> Manage storage -> Click Storage Manager - // SUBTYPE: false is off, true is on - ACTION_TOGGLE_STORAGE_MANAGER = 489; - - // OPEN: Settings > Display -> Ambient Display - // CATEGORY: SETTINGS - ACTION_AMBIENT_DISPLAY = 495; - - // ACTION: Allow Battery optimization for an app - APP_SPECIAL_PERMISSION_BATTERY_ALLOW = 764; - - // ACTION: Deny Battery optimization for an app - APP_SPECIAL_PERMISSION_BATTERY_DENY = 765; - - // ACTION: Enable Device Admin app - APP_SPECIAL_PERMISSION_ADMIN_ALLOW = 766; - - // ACTION: Disable Device Admin app - APP_SPECIAL_PERMISSION_ADMIN_DENY = 767; - - // ACTION: Allow "Do Not Disturb access" for an app - APP_SPECIAL_PERMISSION_DND_ALLOW = 768; - - // ACTION: Deny "Do Not Disturb access" for an app - APP_SPECIAL_PERMISSION_DND_DENY = 769; - - // ACTION: Allow "Draw over other apps" for an app - APP_SPECIAL_PERMISSION_APPDRAW_ALLOW = 770; - - // ACTION: Deny "Display over other apps" for an app - APP_SPECIAL_PERMISSION_APPDRAW_DENY = 771; - - // ACTION: Allow "VR helper services" for an app - APP_SPECIAL_PERMISSION_VRHELPER_ALLOW = 772; - - // ACTION: Deny "VR helper services" for an app - APP_SPECIAL_PERMISSION_VRHELPER_DENY = 773; - - // ACTION: Allow "Modify system settings" for an app - APP_SPECIAL_PERMISSION_SETTINGS_CHANGE_ALLOW = 774; - - // ACTION: Deny "Modify system settings" for an app - APP_SPECIAL_PERMISSION_SETTINGS_CHANGE_DENY = 775; - - // ACTION: Allow "Notification access" for an app - APP_SPECIAL_PERMISSION_NOTIVIEW_ALLOW = 776; - - // ACTION: Deny "Notification access" for an app - APP_SPECIAL_PERMISSION_NOTIVIEW_DENY = 777; - - // ACTION: "Premium SMS access" for an app - "ask user" option - APP_SPECIAL_PERMISSION_PREMIUM_SMS_ASK = 778; - - // ACTION: "Premium SMS access" for an app - "never allow" option - APP_SPECIAL_PERMISSION_PREMIUM_SMS_DENY = 779; - - // ACTION: "Premium SMS access" for an app - "always allow" option - APP_SPECIAL_PERMISSION_PREMIUM_SMS_ALWAYS_ALLOW = 780; - - // ACTION: Allow "Unrestricted data access" for an app - APP_SPECIAL_PERMISSION_UNL_DATA_ALLOW = 781; - - // ACTION: Deny "Unrestricted data access" for an app - APP_SPECIAL_PERMISSION_UNL_DATA_DENY = 782; - - // ACTION: Allow "Usage access" for an app - APP_SPECIAL_PERMISSION_USAGE_VIEW_ALLOW = 783; - - // ACTION: Deny "Usage access" for an app - APP_SPECIAL_PERMISSION_USAGE_VIEW_DENY = 784; - - // ACTION: "Force stop" action on an app - ACTION_APP_FORCE_STOP = 807; - - // ACTION: Allow "Enable picture-in-picture" for an app - APP_PICTURE_IN_PICTURE_ALLOW = 813; - - // ACTION: Create a Settings shortcut item. - ACTION_SETTINGS_CREATE_SHORTCUT = 829; - - // ACTION: A tile in Settings information architecture is clicked - ACTION_SETTINGS_TILE_CLICK = 830; - - // ACTION: Settings advanced button is expanded - ACTION_SETTINGS_ADVANCED_BUTTON_EXPAND = 834; - - // ACTION: Deny "Enable picture-in-picture" for an app - APP_PICTURE_IN_PICTURE_DENY = 814; - - // ACTION: Settings -> Display -> Theme - ACTION_THEME = 816; - - // ACTION: Settings > About device > Build number - ACTION_SETTINGS_BUILD_NUMBER_PREF = 847; - - // ACTION: Settings > Battery > Menu > Optimization - ACTION_SETTINGS_MENU_BATTERY_OPTIMIZATION = 851; - - // ACTION: Settings > Battery > Menu > Apps Toggle - ACTION_SETTINGS_MENU_BATTERY_APPS_TOGGLE = 852; - - // ACTION: Settings > Any preference is changed - ACTION_SETTINGS_PREFERENCE_CHANGE = 853; - - // ACTION: Settings > Connected devices > Bluetooth -> Available devices - ACTION_SETTINGS_BLUETOOTH_PAIR = 866; - - // ACTION: Settings > Connected devices > Bluetooth -> Paired devices - ACTION_SETTINGS_BLUETOOTH_CONNECT = 867; - - // ACTION: Settings > Connected devices > Bluetooth -> Connected device - ACTION_SETTINGS_BLUETOOTH_DISCONNECT = 868; - - // ACTION: Settings > Connected devices > Bluetooth -> Error dialog - ACTION_SETTINGS_BLUETOOTH_CONNECT_ERROR = 869; - - // ACTION: Settings > Connected devices > Bluetooth master switch Toggle - ACTION_SETTINGS_MASTER_SWITCH_BLUETOOTH_TOGGLE = 870; - - // ACTION: Settings > App detail > Uninstall - ACTION_SETTINGS_UNINSTALL_APP = 872; - - // ACTION: Settings > App detail > Uninstall Device admin app - ACTION_SETTINGS_UNINSTALL_DEVICE_ADMIN = 873; - - // ACTION: Settings > App detail > Disable app - ACTION_SETTINGS_DISABLE_APP = 874; - - // ACTION: Settings > App detail > Enable app - ACTION_SETTINGS_ENABLE_APP = 875; - - // ACTION: Settings > App detail > Clear data - ACTION_SETTINGS_CLEAR_APP_DATA = 876; - - // ACTION: Settings > App detail > Clear cache - ACTION_SETTINGS_CLEAR_APP_CACHE = 877; - - // ACTION: Logs pressing the "Clear app" button in the app info settings page for an instant - // app. - // VALUE: The package name of the app - ACTION_SETTINGS_CLEAR_INSTANT_APP = 923; - - // OPEN: Assist Gesture training intro in Settings - // CATEGORY: SETTINGS - // OS: O DR - SETTINGS_ASSIST_GESTURE_TRAINING_INTRO = 991; - - // OPEN: Assist Gesture training enrolling in Settings - // CATEGORY: SETTINGS - // OS: O DR - SETTINGS_ASSIST_GESTURE_TRAINING_ENROLLING = 992; - - // OPEN: Assist Gesture training finished in Settings - // CATEGORY: SETTINGS - // OS: O DR - SETTINGS_ASSIST_GESTURE_TRAINING_FINISHED = 993; - - // ACTION: Update default app from Settings - ACTION_SETTINGS_UPDATE_DEFAULT_APP = 1000; - - // ACTION: Settings > Wi-Fi > [Long press network] > Sign in to network - // CATEGORY: SETTINGS - // OS: O DR - ACTION_WIFI_SIGNIN = 1008; - - // ACTION: Settings > Notification Settings > Open application notification - // CATEGORY: SETTINGS - // OS: O DR - ACTION_OPEN_APP_NOTIFICATION_SETTING = 1016; - - // ACTION: Settings > App Info > Open app settings - // CATEGORY: SETTINGS - // OS: O DR - ACTION_OPEN_APP_SETTING = 1017; - - // ACTION: Collect PSD Signals - // CATEGORY: SETTINGS - // OS: O DR - ACTION_PSD_LOADER = 1019; - - // OPEN: Settings > Trampoline Intent > Settings page - // CATEGORY: SETTINGS - // OS: O DR - TRAMPOLINE_SETTINGS_EVENT = 1033; - - // ACTION: Logged when user tries to pair a Bluetooth device without name from Settings app - // CATEGORY: SETTINGS - // OS: O MR - ACTION_SETTINGS_BLUETOOTH_PAIR_DEVICES_WITHOUT_NAMES = 1096; - - // ACTION: Settings > Network & Internet > Mobile network > Network - // CATEGORY: SETTINGS - ACTION_MOBILE_NETWORK_MANUAL_SELECT_NETWORK = 1210; - - // ACTION: DND Settings > Priority only allows > Alarms toggle - // SUBTYPE: 0 is off, 1 is on - // CATEGORY: SETTINGS - // OS: P - ACTION_ZEN_ALLOW_ALARMS = 1226; - - // ACTION: DND Settings > Priority only allows > Media toggle - // SUBTYPE: 0 is off, 1 is on - // CATEGORY: SETTINGS - // OS: P - ACTION_ZEN_ALLOW_MEDIA = 1227; - - // ACTION: A private dns mode been selected by user - // CATEGORY: SETTINGS - // OS: P - ACTION_PRIVATE_DNS_MODE = 1249; - - // OPEN: Settings > Sound > Do Not Disturb > Turn on automatically > Select rule ("Event") > Rule name > OK - // CATEGORY: SETTINGS - // OS: P - ACTION_ZEN_MODE_RULE_NAME_CHANGE_OK = 1267; - - // OPEN: Settings > Sound > Do Not Disturb > TURN ON NOW/TURN OFF NOW - // CATEGORY: SETTINGS - // OS: P - ACTION_ZEN_TOGGLE_DND_BUTTON = 1268; - - // ACTION: DND Settings > What to block > full screen intents - // SUBTYPE: false is allowed, true is blocked - // CATEGORY: SETTINGS - // OS: 6.0 - ACTION_ZEN_BLOCK_FULL_SCREEN_INTENTS = 1332; - - // ACTION: DND Settings > What to block - // SUBTYPE: false is allowed, true is blocked - // OS: P - ACTION_ZEN_BLOCK_LIGHT = 1333; - - // ACTION: DND Settings > What to block - // SUBTYPE: false is allowed, true is blocked - // OS: P - ACTION_ZEN_BLOCK_PEEK = 1334; - - // ACTION: DND Settings > What to block - // SUBTYPE: false is allowed, true is blocked - // OS: P - ACTION_ZEN_BLOCK_STATUS = 1335; - - // ACTION: DND Settings > What to block - // SUBTYPE: false is allowed, true is blocked - // OS: P - ACTION_ZEN_BLOCK_BADGE = 1336; - - // ACTION: DND Settings > What to block - // SUBTYPE: false is allowed, true is blocked - // OS: P - ACTION_ZEN_BLOCK_AMBIENT = 1337; - - // ACTION: DND Settings > What to block - // SUBTYPE: false is allowed, true is blocked - // OS: P - ACTION_ZEN_BLOCK_NOTIFICATION_LIST = 1338; - - // ACTION: DND Settings > Priority only allows > System toggle - // SUBTYPE: 0 is off, 1 is on - // CATEGORY: SETTINGS - // OS: P - ACTION_ZEN_ALLOW_SYSTEM = 1340; - - // ACTION: Settings > Battery settings > Battery tip > App restriction tip - // OS: P - ACTION_APP_RESTRICTION_TIP = 1347; - - // ACTION: Settings > Battery settings > Battery tip > High usage tip - // OS: P - ACTION_HIGH_USAGE_TIP = 1348; - - // ACTION: Settings > Battery settings > Battery tip > Summary tip - // OS: P - ACTION_SUMMARY_TIP = 1349; - - // ACTION: Settings > Battery settings > Battery tip > Smart battery tip - // OS: P - ACTION_SMART_BATTERY_TIP = 1350; - - // ACTION: Settings > Battery settings > Battery tip > Early warning tip - // OS: P - ACTION_EARLY_WARNING_TIP = 1351; - - // ACTION: Settings > Battery settings > Battery tip > Low battery tip - // OS: P - ACTION_LOW_BATTERY_TIP = 1352; - - // ACTION: Settings > Battery settings > Battery tip > App restriction list shown - // OS: P - ACTION_APP_RESTRICTION_TIP_LIST = 1353; - - // ACTION: Settings > Battery settings > Battery tip > High usage list shown - // OS: P - ACTION_HIGH_USAGE_TIP_LIST = 1354; - - // ACTION: Settings > Battery settings > Battery tip > Open app restriction page - // CATEGORY: SETTINGS - // OS: P - ACTION_TIP_OPEN_APP_RESTRICTION_PAGE = 1361; - - // ACTION: Settings > Battery settings > Battery tip > Restrict app - // CATEGORY: SETTINGS - // OS: P - ACTION_TIP_RESTRICT_APP = 1362; - - // ACTION: Settings > Battery settings > Battery tip > Unrestrict app - // CATEGORY: SETTINGS - // OS: P - ACTION_TIP_UNRESTRICT_APP = 1363; - - // ACTION: Settings > Battery settings > Battery tip > Open smart battery page - // CATEGORY: SETTINGS - // OS: P - ACTION_TIP_OPEN_SMART_BATTERY = 1364; - - // ACTION: Settings > Battery settings > Battery tip > Turn on battery saver - // CATEGORY: SETTINGS - // OS: P - ACTION_TIP_TURN_ON_BATTERY_SAVER = 1365; - - // ACTION: Settings > Anomaly receiver > Anomaly received - // CATEGORY: SETTINGS - // OS: P - ACTION_ANOMALY_TRIGGERED = 1367; - - // ACTION: A Settings Slice is requested - // CATEGORY: SETTINGS - // OS: P - ACTION_SETTINGS_SLICE_REQUESTED = 1371; - - // ACTION: A Settings Slice is updated with new value - // CATEGORY: SETTINGS - // OS: P - ACTION_SETTINGS_SLICE_CHANGED = 1372; - - // OPEN: DND onboarding activity > Ok button - // CATEGORY: SETTINGS - // OS: P - ACTION_ZEN_ONBOARDING_OK = 1378; - - // OPEN: DND onboarding activity > Settings link - // CATEGORY: SETTINGS - // OS: P - ACTION_ZEN_ONBOARDING_SETTINGS = 1379; - - // ACTION: Settings > Anomaly receiver > Anomaly ignored, don't show up in battery settings - // CATEGORY: SETTINGS - // OS: P - ACTION_ANOMALY_IGNORED = 1387; - - // ACTION: Settings > Battery settings > Battery tip > Open battery saver page - // CATEGORY: SETTINGS - // OS: P - ACTION_TIP_OPEN_BATTERY_SAVER_PAGE = 1388; - - // ACTION: DND Settings > What to block - // OS: P - ACTION_ZEN_SOUND_ONLY = 1396; - - // ACTION: DND Settings > Notifications - // OS: P - ACTION_ZEN_SOUND_AND_VIS_EFFECTS = 1397; - - // ACTION: DND Settings > Notifications - // OS: P - ACTION_ZEN_SHOW_CUSTOM = 1398; - - // ACTION: DND Settings > Notifications - // OS: P - ACTION_ZEN_CUSTOM = 1399; - - // OPEN: DND onboarding activity > don't update button - // CATEGORY: SETTINGS - // OS: P - ACTION_ZEN_ONBOARDING_KEEP_CURRENT_SETTINGS = 1406; - - // ACTION: Storage initialization wizard initialization choice of external/portable - // CATEGORY: SETTINGS - // OS: P - ACTION_STORAGE_INIT_EXTERNAL = 1407; - - // ACTION: Storage initialization wizard initialization choice of internal/adoptable - // CATEGORY: SETTINGS - // OS: P - ACTION_STORAGE_INIT_INTERNAL = 1408; - - // ACTION: Storage initialization wizard benchmark fast choice of continue - // CATEGORY: SETTINGS - // OS: P - ACTION_STORAGE_BENCHMARK_FAST_CONTINUE = 1409; - - // ACTION: Storage initialization wizard benchmark slow choice of continue - // CATEGORY: SETTINGS - // OS: P - ACTION_STORAGE_BENCHMARK_SLOW_CONTINUE = 1410; - - // ACTION: Storage initialization wizard benchmark slow choice of abort - // CATEGORY: SETTINGS - // OS: P - ACTION_STORAGE_BENCHMARK_SLOW_ABORT = 1411; - - // ACTION: Storage initialization wizard migration choice of now - // CATEGORY: SETTINGS - // OS: P - ACTION_STORAGE_MIGRATE_NOW = 1412; - - // ACTION: Storage initialization wizard migration choice of later - // CATEGORY: SETTINGS - // OS: P - ACTION_STORAGE_MIGRATE_LATER = 1413; - - // OPEN: Settings > Sound > Switch a2dp devices dialog - // CATEGORY: SETTINGS - // OS: P - DIALOG_SWITCH_A2DP_DEVICES = 1415; - - - // OPEN: Settings > Sound > Switch hfp devices dialog - // CATEGORY: SETTINGS - // OS: P - DIALOG_SWITCH_HFP_DEVICES = 1416; - - // OPEN: QS Sensor Privacy Mode tile shown - // ACTION: QS Sensor Privacy Mode tile tapped - // SUBTYPE: 0 is off, 1 is on - // CATEGORY: QUICK_SETTINGS - // OS: Q - QS_SENSOR_PRIVACY = 1598; - - // ACTION: Tap & Pay -> Default Application Setting -> Use Forground - ACTION_NFC_PAYMENT_FOREGROUND_SETTING = 1622; - - // ACTION: Tap & Pay -> Default Application Setting -> Use Default - ACTION_NFC_PAYMENT_ALWAYS_SETTING = 1623; - - // ACTION: Settings > Search Bar > Avatar - // CATEGORY: SETTINGS - // OS: Q - CLICK_ACCOUNT_AVATAR = 1643; - - // ACTION: Set new password (action intent android.app.action.SET_NEW_PASSWORD) - // CATEGORY: SETTINGS - // OS: Q - ACTION_SET_NEW_PASSWORD = 1645; - - // ACTION: Set new password (action intent android.app.action.SET_NEW_PARENT_PROFILE_PASSWORD) - // CATEGORY: SETTINGS - // OS: Q - ACTION_SET_NEW_PARENT_PROFILE_PASSWORD = 1646; - - // ACTION: An interaction with a Slice or other component in the Panel. - // CATEGORY: SETTINGS - // OS: Q - ACTION_PANEL_INTERACTION = 1658; - - // ACTION: Show Contextual homepage. Log total loading latency. - ACTION_CONTEXTUAL_HOME_SHOW = 1662; - - // ACTION: Contextual card displays - ACTION_CONTEXTUAL_CARD_SHOW = 1663; - - // ACTION: Contextual cards are eligible to be shown, but don't rank high - ACTION_CONTEXTUAL_CARD_NOT_SHOW = 1664; - - // ACTION: Settings > long press a card, and click dismiss - // Contextual card is dismissed - ACTION_CONTEXTUAL_CARD_DISMISS = 1665; - - // ACTION: Settings > click a card - // Contextual card is clicked - ACTION_CONTEXTUAL_CARD_CLICK = 1666; - - // Mapping: go/at-mapping - ACTION_ATSG = 1674; - - ACTION_ATPG = 1675; - - ACTION_ATCLPB = 1676; - - ACTION_ATCGIB = 1677; - - ACTION_ATCPAB = 1678; - - ACTION_ATCSAUC = 1679; - - ACTION_ATCSCUC = 1680; - - ACTION_ATCHNUC = 1681; - - // ACTION: Individual contextual card loading time - ACTION_CONTEXTUAL_CARD_LOAD = 1684; - - //ACTION: Contextual card loading timeout - ACTION_CONTEXTUAL_CARD_LOAD_TIMEOUT = 1685; - - //ACTION: Log result for each card's eligibility check - ACTION_CONTEXTUAL_CARD_ELIGIBILITY = 1686; - - // ACTION: Display white balance setting enabled or disabled. - // CATEGORY: SETTINGS - // OS: Q - ACTION_DISPLAY_WHITE_BALANCE_SETTING_CHANGED = 1703; - - // ACTION: Share a Wi-Fi network by generating a QR code - ACTION_SETTINGS_SHARE_WIFI_QR_CODE = 1710; - - // ACTION: Connect to a Wi-Fi network by scanning a QR code - ACTION_SETTINGS_ENROLL_WIFI_QR_CODE = 1711; - - // ACTION: Share Wi-Fi hotspot by generating a QR code - ACTION_SETTINGS_SHARE_WIFI_HOTSPOT_QR_CODE = 1712; - - // ACTION: Settings > Initialize Search bar > Verify Slice > Invalid data - ACTION_VERIFY_SLICE_ERROR_INVALID_DATA = 1725; - - // ACTION: Settings > Initialize Search bar > Verify Slice > Parsing error - ACTION_VERIFY_SLICE_PARSING_ERROR = 1726; - - // ACTION: Settings > Initialize Search bar > Verify Slice > Other exception - ACTION_VERIFY_SLICE_OTHER_EXCEPTION = 1727; - - // Custom tag to evaluate the consuming time of the Controller.updateState. - // CATEGORY: SETTINGS - // OS: R - ACTION_CONTROLLER_UPDATE_STATE = 1728; - - // Custom tag to evaluate the consuming time from onAttach to - // DashboardFragment.updatePreferenceStates. - // CATEGORY: SETTINGS - // OS: R - ACTION_DASHBOARD_VISIBLE_TIME = 1729; - - // ACTION: Allow "Access all files" for an app - APP_SPECIAL_PERMISSION_MANAGE_EXT_STRG_ALLOW = 1730; - - // ACTION: Deny "Access all files" for an app - APP_SPECIAL_PERMISSION_MANAGE_EXT_STRG_DENY = 1731; - - // ACTION: Battery feature usage - ACTION_BATTERY_OPTION_FEATURE_USAGE = 1732; - - // ACTION: Battery feature runtime event - ACTION_BATTERY_OPTION_RUNTIME_EVENT = 1733; - - // ACTION: Settings > Developer Options > Toggle on Wireless debugging - // CATEGORY: SETTINGS - // OS: R - ACTION_ADB_WIRELESS_ON = 1734; - - // ACTION: Settings > Developer Options > Toggle off Wireless debugging - // CATEGORY: SETTINGS - // OS: R - ACTION_ADB_WIRELESS_OFF = 1735; - - // ACTION: Change Wi-Fi hotspot name - // CATEGORY: SETTINGS - // OS: R - ACTION_SETTINGS_CHANGE_WIFI_HOTSPOT_NAME = 1736; - - // ACTION: Change Wi-Fi hotspot password - // CATEGORY: SETTINGS - // OS: R - ACTION_SETTINGS_CHANGE_WIFI_HOTSPOT_PASSWORD = 1737; - - // ACTION: Settings > Security > Toggle on Confirm Sim deletion - // CATEGORY: SETTINGS - // OS: R - ACTION_CONFIRM_SIM_DELETION_ON = 1738; - - // ACTION: Settings > Security > Toggle off Confirm Sim deletion - // CATEGORY: SETTINGS - // OS: R - ACTION_CONFIRM_SIM_DELETION_OFF = 1739; - - // ACTION: Settings > System > Gestures > Double tap > Toggle on Double tap - // CATEGORY: SETTINGS - // OS: S - ACTION_COLUMBUS_ENABLED = 1740; - - // ACTION: Settings > System > Gestures > Double tap > Toggle off Double tap - // CATEGORY: SETTINGS - // OS: S - ACTION_COLUMBUS_DISABLED = 1741; - - // ACTION: Settings > System > Gestures > Double tap > Invoke Assistant - // CATEGORY: SETTINGS - // OS: S - ACTION_COLUMBUS_ACTION_ASSISTANT = 1742; - - // ACTION: Settings > System > Gestures > Double tap > Take screenshot - // CATEGORY: SETTINGS - // OS: S - ACTION_COLUMBUS_ACTION_SCREENSHOT = 1743; - - // ACTION: Settings > System > Gestures > Double tap > Play and pause - // CATEGORY: SETTINGS - // OS: S - ACTION_COLUMBUS_ACTION_PLAY_PAUSE = 1744; - - // ACTION: Settings > System > Gestures > Double tap > Open app overview - // CATEGORY: SETTINGS - // OS: S - ACTION_COLUMBUS_ACTION_OVERVIEW = 1745; - - // ACTION: Settings > System > Gestures > Double tap > Open notification shade - // CATEGORY: SETTINGS - // OS: S - ACTION_COLUMBUS_ACTION_NOTIFICATION_SHADE = 1746; - - // ACTION: Settings > System > Gestures > Double tap > Require harder taps - // CATEGORY: SETTINGS - // OS: S - ACTION_COLUMBUS_LOW_SENSITIVITY = 1747; - - // OPEN: Columbus Gesture training intro in Settings - // CATEGORY: SETTINGS - // OS: S - SETTINGS_COLUMBUS_GESTURE_TRAINING_INTRO = 1748; - - // OPEN: Columbus Gesture training enrolling in Settings - // CATEGORY: SETTINGS - // OS: S - SETTINGS_COLUMBUS_GESTURE_TRAINING_ENROLLING = 1749; - - // OPEN: Columbus Gesture training finished in Settings - // CATEGORY: SETTINGS - // OS: S - SETTINGS_COLUMBUS_GESTURE_TRAINING_FINISHED = 1750; -} - -/** - * Id for Settings pages. Each page must have its own unique Id. - */ -enum PageId { - // Unknown page. Should not be used in production code. - PAGE_UNKNOWN = 0; - - // OPEN: Settings > Accessibility - // CATEGORY: SETTINGS - // OS: 6.0 - ACCESSIBILITY = 2; - - // OPEN: Settings > Accessibility > Captions preference - // CATEGORY: SETTINGS - // OS: 6.0 - ACCESSIBILITY_CAPTION_PROPERTIES = 3; - - // OPEN: Settings > Accessibility > [Service] - // CATEGORY: SETTINGS - // OS: 6.0 - ACCESSIBILITY_SERVICE = 4; - - // OPEN: Settings > Accessibility > Color correction - // CATEGORY: SETTINGS - // OS: 6.0 - ACCESSIBILITY_TOGGLE_DALTONIZER = 5; - - // OPEN: Settings > Accessibility > Accessibility shortcut - // CATEGORY: SETTINGS - // OS: 6.0 - ACCESSIBILITY_TOGGLE_GLOBAL_GESTURE = 6; - - // OPEN: Settings > Accessibility > Magnification gestures (Renamed in O) - // OPEN: Settings > Accessibility > Magnification > Magnify with triple-tap - // OPEN: Settings > Accessibility > Magnification > Magnify with button - // CATEGORY: SETTINGS - // OS: 6.0 - ACCESSIBILITY_TOGGLE_SCREEN_MAGNIFICATION = 7; - - // OPEN: Settings > Accounts - // CATEGORY: SETTINGS - // OS: 6.0 - ACCOUNT = 8; - - // OPEN: Settings > Accounts > [Single Account Sync Settings] - // CATEGORY: SETTINGS - // OS: 6.0 - ACCOUNTS_ACCOUNT_SYNC = 9; - - // OPEN: Settings > Accounts > Add an account - // CATEGORY: SETTINGS - // OS: 6.0 - ACCOUNTS_CHOOSE_ACCOUNT_ACTIVITY = 10; - - // OPEN: Settings > Cellular network settings > APNs - // CATEGORY: SETTINGS - // OS: 6.0 - APN = 12; - - // OPEN: Settings > More > Cellular network settings > APNs > [Edit APN] - // CATEGORY: SETTINGS - // OS: 6.0 - APN_EDITOR = 13; - - // OPEN: Settings > Apps > Configure apps > App links > [App] - // CATEGORY: SETTINGS - // OS: 6.0 - APPLICATIONS_APP_LAUNCH = 17; - - // OPEN: Settings > Internal storage > Apps storage > [App] - // CATEGORY: SETTINGS - // OS: 6.0 - APPLICATIONS_APP_STORAGE = 19; - - // OPEN: Settings > Apps > [App info] - // CATEGORY: SETTINGS - // OS: 6.0 - APPLICATIONS_INSTALLED_APP_DETAILS = 20; - - // OPEN: Settings > Memory > App usage > [App Memory usage] - // CATEGORY: SETTINGS - // OS: 6.0 - APPLICATIONS_PROCESS_STATS_DETAIL = 21; - - // OPEN: Settings > Memory > App usage - // CATEGORY: SETTINGS - // OS: 6.0 - APPLICATIONS_PROCESS_STATS_UI = 23; - - // OPEN: Choose Bluetooth device (ex: when sharing) - // CATEGORY: SETTINGS - // OS: 6.0 - BLUETOOTH_DEVICE_PICKER = 25; - - // OPEN: Settings > Security > Choose screen lock - // CATEGORY: SETTINGS - // OS: 6.0 - CHOOSE_LOCK_GENERIC = 27; - - // OPEN: Settings > Security > Choose screen lock > Choose your password - // CATEGORY: SETTINGS - // OS: 6.0 - CHOOSE_LOCK_PASSWORD = 28; - - // OPEN: Settings > Security > Choose screen lock > Choose your pattern - // CATEGORY: SETTINGS - // OS: 6.0 - CHOOSE_LOCK_PATTERN = 29; - - // OPEN: Settings > Security > Choose screen lock > Confirm your password - // CATEGORY: SETTINGS - // OS: 6.0 - CONFIRM_LOCK_PASSWORD = 30; - - // OPEN: Settings > Security > Choose screen lock > Confirm your pattern - // CATEGORY: SETTINGS - // OS: 6.0 - CONFIRM_LOCK_PATTERN = 31; - - // OPEN: Settings > Security > Encrypt phone - // CATEGORY: SETTINGS - // OS: 6.0 - CRYPT_KEEPER = 32; - - // OPEN: Settings > Security > Encrypt phone > Confirm - // CATEGORY: SETTINGS - // OS: 6.0 - CRYPT_KEEPER_CONFIRM = 33; - - // OPEN: Settings (Root page) - // CATEGORY: SETTINGS - // OS: 6.0 - DASHBOARD_SUMMARY = 35; - - // OPEN: Settings > Data usage - // CATEGORY: SETTINGS - // OS: 6.0 - DATA_USAGE_SUMMARY = 37; - - // OPEN: Settings > Date & time - // CATEGORY: SETTINGS - // OS: 6.0 - DATE_TIME = 38; - - // OPEN: Settings > Developer options - // CATEGORY: SETTINGS - // OS: 6.0 - DEVELOPMENT = 39; - - // OPEN: Settings > About phone - // CATEGORY: SETTINGS - // OS: 6.0 - DEVICEINFO = 40; - - // OPEN: Settings > Internal storage - // CATEGORY: SETTINGS - // OS: 6.0 - DEVICEINFO_STORAGE = 42; - - // OPEN: Settings > Display - // CATEGORY: SETTINGS - // OS: 6.0 - DISPLAY = 46; - - // OPEN: Settings > Display > Daydream - // CATEGORY: SETTINGS - // OS: 6.0 - DREAM = 47; - - // OPEN: Settings > Security > Screen lock > Secure start-up - // CATEGORY: SETTINGS - // OS: 6.0 - ENCRYPTION = 48; - - // OPEN: Settings > Security > Nexus Imprint - // CATEGORY: SETTINGS - // OS: 6.0 - FINGERPRINT = 49; - - // OPEN: Settings > Battery > History details - // CATEGORY: SETTINGS - // OS: 6.0 - FUELGAUGE_BATTERY_HISTORY_DETAIL = 51; - - // OPEN: Settings > Battery > Battery saver - // CATEGORY: SETTINGS - // OS: 6.0 - FUELGAUGE_BATTERY_SAVER = 52; - - // OPEN: Settings > Battery > [App Use details] - // CATEGORY: SETTINGS - // OS: 6.0 - FUELGAUGE_POWER_USAGE_DETAIL = 53; - - // OPEN: Settings > Security > SIM card lock settings - // CATEGORY: SETTINGS - // OS: 6.0 - ICC_LOCK = 56; - - // OPEN: Settings > Language & input > Physical keyboard - // CATEGORY: SETTINGS - // OS: 6.0 - INPUTMETHOD_KEYBOARD = 58; - - // OPEN: Settings > Language & input > Spell checker - // CATEGORY: SETTINGS - // OS: 6.0 - INPUTMETHOD_SPELL_CHECKERS = 59; - - // OBSOLETE - INPUTMETHOD_SUBTYPE_ENABLER = 60; - - // OPEN: Settings > Language & input > Personal dictionary - // CATEGORY: SETTINGS - // OS: 6.0 - INPUTMETHOD_USER_DICTIONARY = 61; - - // OPEN: Settings > Language & input > Add word - // CATEGORY: SETTINGS - // OS: 6.0 - INPUTMETHOD_USER_DICTIONARY_ADD_WORD = 62; - - // OPEN: Settings > Location - // CATEGORY: SETTINGS - // OS: 6.0 - LOCATION = 63; - - // OPEN: Settings > Apps - // CATEGORY: SETTINGS - // OS: 6.0 - MANAGE_APPLICATIONS = 65; - - // OPEN: Settings > Backup & reset > Factory data reset - // CATEGORY: SETTINGS - // OS: 6.0 - MASTER_CLEAR = 66; - - // OPEN: Settings > Backup & reset > Factory data reset > Confirm - // CATEGORY: SETTINGS - // OS: 6.0 - MASTER_CLEAR_CONFIRM = 67; - - // OPEN: Settings > More > Android Beam - // CATEGORY: SETTINGS - // OS: 6.0 - NFC_BEAM = 69; - - // OPEN: Settings > Tap & pay - // CATEGORY: SETTINGS - // OS: 6.0 - NFC_PAYMENT = 70; - - // OPEN: Settings > Sound & notification > App notifications > [App] - // CATEGORY: SETTINGS - // OS: 6.0 - NOTIFICATION_APP_NOTIFICATION = 72; - - // OBSOLETE - NOTIFICATION_REDACTION = 74; - - // OPEN: Settings Widget > Notification log - // CATEGORY: SETTINGS - // OS: 6.0 - NOTIFICATION_STATION = 75; - - // OPEN: Settings > Sound & notification > Do not disturb - // CATEGORY: SETTINGS - // OS: 6.0 - NOTIFICATION_ZEN_MODE = 76; - - - // OPEN: Print job notification > Print job settings - // CATEGORY: SETTINGS - // OS: 6.0 - PRINT_JOB_SETTINGS = 78; - - // OPEN: Settings > Printing > [Print Service] - // CATEGORY: SETTINGS - // OS: 6.0 - PRINT_SERVICE_SETTINGS = 79; - - // OPEN: Settings > Printing - // CATEGORY: SETTINGS - // OS: 6.0 - PRINT_SETTINGS = 80; - - // OPEN: Settings > Backup & reset - // CATEGORY: SETTINGS - // OS: 6.0 - PRIVACY = 81; - - //OBSOLETE - PROXY_SELECTOR = 82; - - // OPEN: Settings > Backup & reset > Network settings reset - // CATEGORY: SETTINGS - // OS: 6.0 - RESET_NETWORK = 83; - - // OPEN: Settings > Backup & reset > Network settings reset > Confirm - // CATEGORY: SETTINGS - // OS: 6.0 - RESET_NETWORK_CONFIRM = 84; - - // OPEN: Settings > Developer Options > Running Services - // CATEGORY: SETTINGS - // OS: 6.0 - RUNNING_SERVICE_DETAILS = 85; - - // OPEN: Settings > Security > Screen pinning - // CATEGORY: SETTINGS - // OS: 6.0 - SCREEN_PINNING = 86; - - // OPEN: Settings > Security - // CATEGORY: SETTINGS - // OS: 6.0 - SECURITY = 87; - - // OPEN: Settings > SIM cards - // CATEGORY: SETTINGS - // OS: 6.0 - SIM = 88; - - // OBSOLETE - TESTING = 89; - - // OPEN: Settings > More > Tethering & portable hotspot - // CATEGORY: SETTINGS - // OS: 6.0 - TETHER = 90; - - // OPEN: Settings > Security > Trust agents - // CATEGORY: SETTINGS - // OS: 6.0 - TRUST_AGENT = 91; - - // OPEN: Settings > Security > Trusted credentials - // CATEGORY: SETTINGS - // OS: 6.0 - TRUSTED_CREDENTIALS = 92; - - // OPEN: Settings > Language & input > TTS output > [Engine] > Settings - // CATEGORY: SETTINGS - // OS: 6.0 - TTS_ENGINE_SETTINGS = 93; - - // OPEN: Settings > Language & input > Text-to-speech output - // CATEGORY: SETTINGS - // OS: 6.0 - TTS_TEXT_TO_SPEECH = 94; - - // OPEN: Settings > Security > Apps with usage access - // CATEGORY: SETTINGS - // OS: 6.0 - USAGE_ACCESS = 95; - - // OPEN: Settings > Users - // CATEGORY: SETTINGS - // OS: 6.0 - USER = 96; - - // OPEN: Settings > Users > [Restricted profile app & content access] - // CATEGORY: SETTINGS - // OS: 6.0 - USERS_APP_RESTRICTIONS = 97; - - // OPEN: Settings > Users > [User settings] - // CATEGORY: SETTINGS - // OS: 6.0 - USER_DETAILS = 98; - - // OPEN: Settings > More > VPN - // CATEGORY: SETTINGS - // OS: 6.0 - VPN = 100; - - // OPEN: Settings > Display > Choose wallpaper from - // CATEGORY: SETTINGS - // OS: 6.0 - WALLPAPER_TYPE = 101; - - // OPEN: Settings > Display > Cast - // CATEGORY: SETTINGS - // OS: 6.0 - WFD_WIFI_DISPLAY = 102; - - // OPEN: Settings > Wi-Fi - // CATEGORY: SETTINGS - // OS: 6.0 - WIFI = 103; - - // OPEN: Settings > More > Wi-Fi Calling - // CATEGORY: SETTINGS - // OS: 6.0 - WIFI_CALLING = 105; - - // OPEN: Settings > Wi-Fi > Saved networks - // CATEGORY: SETTINGS - // OS: 6.0 - WIFI_SAVED_ACCESS_POINTS = 106; - - // OPEN: Settings > Wi-Fi > Advanced Wi-Fi > Wi-Fi Direct - // CATEGORY: SETTINGS - // OS: 6.0 - WIFI_P2P = 109; - - // OPEN: Settings > Apps > Configure apps > App permissions - // CATEGORY: SETTINGS - // OS: 6.0 - APPLICATIONS_ADVANCED = 130; - - // OPEN: Settings > Location > Scanning - // CATEGORY: SETTINGS - // OS: 6.0 - LOCATION_SCANNING = 131; - - // OPEN: Settings > Sound & notification > App notifications - // CATEGORY: SETTINGS - // OS: 6.0 - MANAGE_APPLICATIONS_NOTIFICATIONS = 133; - - // OPEN: Settings > Sound & notification > DND > Priority only allows - // CATEGORY: SETTINGS - // OS: 6.0 - NOTIFICATION_ZEN_MODE_PRIORITY = 141; - - // OPEN: Settings > Sound & notification > DND > Automatic rules - // CATEGORY: SETTINGS - // OS: 6.0 - NOTIFICATION_ZEN_MODE_AUTOMATION = 142; - - // OPEN: Settings > Sound & notification > DND > [Time based rule] - // CATEGORY: SETTINGS - // OS: 6.0 - NOTIFICATION_ZEN_MODE_SCHEDULE_RULE = 144; - - // OPEN: Settings > Apps > Configure apps > App links - // CATEGORY: SETTINGS - // OS: 6.0 - MANAGE_DOMAIN_URLS = 143; - - // OPEN: Settings > Sound & notification > DND > [Event rule] - // CATEGORY: SETTINGS - // OS: 6.0 - NOTIFICATION_ZEN_MODE_EVENT_RULE = 146; - - // OPEN: Settings > Sound & notification > Notification access - // CATEGORY: SETTINGS - // OS: 6.0 - NOTIFICATION_ACCESS = 179; - - // OPEN: Settings > Sound & notification > Do Not Disturb access - // CATEGORY: SETTINGS - // OS: 6.0 - NOTIFICATION_ZEN_MODE_ACCESS = 180; - - // OPEN: Settings > Internal storage > Apps storage - // CATEGORY: SETTINGS - // OS: 6.0 - APPLICATIONS_STORAGE_APPS = 182; - - // OPEN: Settings > Security > Usage access - // CATEGORY: SETTINGS - // OS: 6.0 - APPLICATIONS_USAGE_ACCESS_DETAIL = 183; - - // OPEN: Settings > Battery > Battery optimization - // CATEGORY: SETTINGS - // OS: 6.0 - APPLICATIONS_HIGH_POWER_APPS = 184; - - // OPEN: Settings > Apps > Configure > Default apps > Assist & voice input - // CATEGORY: SETTINGS - // OS: 6.0 - APPLICATIONS_MANAGE_ASSIST = 201; - - // OPEN: Settings > Memory - // CATEGORY: SETTINGS - // OS: 6.0 - PROCESS_STATS_SUMMARY = 202; - - // OPEN: Settings > Apps > Configure Apps > Display over other apps - // CATEGORY: SETTINGS - // OS: 6.0 - SYSTEM_ALERT_WINDOW_APPS = 221; - - // OPEN: Settings > About phone > Legal information - // CATEGORY: SETTINGS - // OS: 6.0 - ABOUT_LEGAL_SETTINGS = 225; - - - // OPEN: Settings > Developer options > Inactive apps - // CATEGORY: SETTINGS - // OS: 6.0 - FUELGAUGE_INACTIVE_APPS = 238; - - // OPEN: Settings > Security > Nexus Imprint > Add Fingerprint - // CATEGORY: SETTINGS - // OS: 6.0 - FINGERPRINT_ENROLLING = 240; - // OPEN: Fingerprint Enroll > Find Sensor - // CATEGORY: SETTINGS - // OS: 6.0 - FINGERPRINT_FIND_SENSOR = 241; - - // OPEN: Fingerprint Enroll > Fingerprint Enrolled! - // CATEGORY: SETTINGS - // OS: 6.0 - FINGERPRINT_ENROLL_FINISH = 242; - - // OPEN: Fingerprint Enroll introduction - // CATEGORY: SETTINGS - // OS: 6.0 - FINGERPRINT_ENROLL_INTRO = 243; - - // OPEN: Fingerprint Enroll > Let's Start! - // CATEGORY: SETTINGS - // OS: 6.0 - FINGERPRINT_ENROLL_SIDECAR = 245; - - // OPEN: Fingerprint Enroll SUW > Let's Start! - // CATEGORY: SETTINGS - // OS: 6.0 - FINGERPRINT_ENROLLING_SETUP = 246; - - // OPEN: Fingerprint Enroll SUW > Find Sensor - // CATEGORY: SETTINGS - // OS: 6.0 - FINGERPRINT_FIND_SENSOR_SETUP = 247; - - // OPEN: Fingerprint Enroll SUW > Fingerprint Enrolled! - // CATEGORY: SETTINGS - // OS: 6.0 - FINGERPRINT_ENROLL_FINISH_SETUP = 248; - - // OPEN: Fingerprint Enroll SUW introduction - // CATEGORY: SETTINGS - // OS: 6.0 - FINGERPRINT_ENROLL_INTRO_SETUP = 249; - - // OPEN: Settings > Developer Options > Background Check - // CATEGORY: SETTINGS - // OS: N - BACKGROUND_CHECK_SUMMARY = 258; - - // OPEN: Settings > Notifications > [App] > Channel Notifications - // CATEGORY: SETTINGS - // OS: N - NOTIFICATION_TOPIC_NOTIFICATION = 265; - - // OPEN: Settings > Security > User credentials - // CATEGORY: Settings - // OS: N - USER_CREDENTIALS = 285; - - // Logs that the user has edited the enabled VR listeners. - // CATEGORY: SETTINGS - // OS: N - VR_MANAGE_LISTENERS = 334; - - // Settings -> Accessibility -> Click after pointer stops moving - // CATEGORY: SETTINGS - // OS: N - ACCESSIBILITY_TOGGLE_AUTOCLICK = 335; - - // Settings -> Sound - // CATEGORY: SETTINGS - // OS: N - SOUND = 336; - - // Settings -> Notifications -> Gear - // CATEGORY: SETTINGS - // OS: N - CONFIGURE_NOTIFICATION = 337; - - // Settings -> Wi-Fi -> Gear - // CATEGORY: SETTINGS - // OS: N - CONFIGURE_WIFI = 338; - - // Settings -> Display -> Display size - // OS: N - DISPLAY_SCREEN_ZOOM = 339; - - // Settings -> Display -> Font size - // CATEGORY: SETTINGS - // OS: N - ACCESSIBILITY_FONT_SIZE = 340; - - // Settings -> Data usage -> Cellular/Wi-Fi data usage - // CATEGORY: SETTINGS - // OS: N - DATA_USAGE_LIST = 341; - - // Settings -> Data usage -> Billing cycle or DATA_USAGE_LIST -> Gear - // CATEGORY: SETTINGS - // OS: N - BILLING_CYCLE = 342; - - // DATA_USAGE_LIST -> Any item or App info -> Data usage - // CATEGORY: SETTINGS - // OS: N - APP_DATA_USAGE = 343; - - // Settings -> Language & input -> Language - // CATEGORY: SETTINGS - // OS: N - USER_LOCALE_LIST = 344; - - // Settings -> Language & input -> Virtual keyboard - // CATEGORY: SETTINGS - // OS: N - VIRTUAL_KEYBOARDS = 345; - - // Settings -> Language & input -> Physical keyboard - // CATEGORY: SETTINGS - // OS: N - PHYSICAL_KEYBOARDS = 346; - - // Settings -> Language & input -> Virtual keyboard -> Add a virtual keyboard - // CATEGORY: SETTINGS - // OS: N - ENABLE_VIRTUAL_KEYBOARDS = 347; - - // Settings -> Data usage -> Data Saver - // CATEGORY: SETTINGS - // OS: N - DATA_SAVER_SUMMARY = 348; - - // Settings -> Data usage -> Data Saver -> Unrestricted data access - // CATEGORY: SETTINGS - // OS: N - DATA_USAGE_UNRESTRICTED_ACCESS = 349; - - // Settings -> Apps -> Gear -> Special access - SPECIAL_ACCESS = 351; - - // OPEN: SUW Welcome Screen -> Vision Settings - // CATEGORY: SETTINGS - // OS: N - SUW_ACCESSIBILITY = 367; - - // OPEN: SUW Welcome Screen -> Vision Settings -> Magnification gestures (Renamed in O) - // OPEN: SUW Welcome Screen -> Vision Settings -> Magnification -> Magnify with triple-tap - // OPEN: SUW Welcome Screen -> Vision Settings -> Magnification -> Magnify with button - // ACTION: New magnification gesture configuration is chosen - // SUBTYPE: 0 is off, 1 is on - // CATEGORY: SETTINGS - // OS: N - SUW_ACCESSIBILITY_TOGGLE_SCREEN_MAGNIFICATION = 368; - - // OPEN: SUW Welcome Screen -> Vision Settings -> Font size - // ACTION: New font size is chosen - // SUBTYPE: 0 is small, 1 is default, 2 is large, 3 is largest - // CATEGORY: SETTINGS - // OS: N - SUW_ACCESSIBILITY_FONT_SIZE = 369; - - // OPEN: SUW Welcome Screen -> Vision Settings -> Display size - // ACTION: New display size is chosen - // SUBTYPE: 0 is small, 1 is default, 2 is large, 3 is larger, 4 is largest - // CATEGORY: SETTINGS - // OS: N - SUW_ACCESSIBILITY_DISPLAY_SIZE = 370; - - // OPEN: SUW Welcome Screen -> Vision Settings -> TalkBack - // ACTION: New screen reader configuration is chosen - // SUBTYPE: 0 is off, 1 is on - // CATEGORY: SETTINGS - // OS: N - SUW_ACCESSIBILITY_TOGGLE_SCREEN_READER = 371; - - // Airplane mode on - SETTINGS_CONDITION_AIRPLANE_MODE = 377; - // AKA Data saver on - SETTINGS_CONDITION_BACKGROUND_DATA = 378; - // Battery saver on - SETTINGS_CONDITION_BATTERY_SAVER = 379; - // Cellular data off - SETTINGS_CONDITION_CELLULAR_DATA = 380; - // Do not disturb on - SETTINGS_CONDITION_DND = 381; - // Hotspot on - SETTINGS_CONDITION_HOTSPOT = 382; - // Work profile off - SETTINGS_CONDITION_WORK_MODE = 383; - - // Settings > Apps > Gear > Special Access > Premium SMS access - PREMIUM_SMS_ACCESS = 388; - - // OPEN: Settings > Accounts > Work profile settings - // CATEGORY: SETTINGS - ACCOUNTS_WORK_PROFILE_SETTINGS = 401; - - // Settings -> Dev options -> Convert to file encryption - CONVERT_FBE = 402; - - // Settings -> Dev options -> Convert to file encryption -> WIPE AND CONVERT... - CONVERT_FBE_CONFIRM = 403; - - // Settings -> Dev options -> Running services - RUNNING_SERVICES = 404; - - // The dialog shown by 3P intent to change current webview implementation. - WEBVIEW_IMPLEMENTATION = 405; - - // OPEN: Settings > Internal storage > Storage manager - // CATEGORY: SETTINGS - STORAGE_MANAGER_SETTINGS = 458; - - // OPEN: Settings -> Gestures - // CATEGORY: SETTINGS - SETTINGS_GESTURES = 459; - - // OPEN: Settings > Display > Night Light - // CATEGORY: SETTINGS - NIGHT_DISPLAY_SETTINGS = 488; - - // Night Light on - SETTINGS_CONDITION_NIGHT_DISPLAY = 492; - - // OPEN: Settings > Language & input > Personal dictionary (single locale) - USER_DICTIONARY_SETTINGS = 514; - - // OPEN: Settings > Date & time > Select time zone - ZONE_PICKER = 515; - - // OPEN: Settings > Security > Device administrators - DEVICE_ADMIN_SETTINGS = 516; - - // OPEN: Settings > Security > Factory Reset Protection dialog - DIALOG_FRP = 528; - - // OPEN: Settings > Custom list preference with confirmation message - DIALOG_CUSTOM_LIST_CONFIRMATION = 529; - - // OPEN: Settings > APN Editor > Error dialog - DIALOG_APN_EDITOR_ERROR = 530; - - // OPEN: Settings > Users > Edit owner info dialog - DIALOG_OWNER_INFO_SETTINGS = 531; - - // OPEN: Settings > Security > Use one lock dialog - DIALOG_UNIFICATION_CONFIRMATION = 532; - - // OPEN: Settings > Security > User Credential - DIALOG_USER_CREDENTIAL = 533; - - // OPEN: Settings > Accounts > Remove account - DIALOG_REMOVE_USER = 534; - - // OPEN: Settings > Accounts > Confirm auto sync dialog - DIALOG_CONFIRM_AUTO_SYNC_CHANGE = 535; - - // OPEN: Settings > Apps > Dialog for running service details - DIALOG_RUNNIGN_SERVICE = 536; - - // OPEN: Settings > Bluetooth > Rename this device - DIALOG_BLUETOOTH_RENAME = 538; - - // OPEN: Settings > Battery optimization > details for app - DIALOG_HIGH_POWER_DETAILS = 540; - - // OPEN: Settings > Keyboard > Show keyboard layout dialog - DIALOG_KEYBOARD_LAYOUT = 541; - - // OPEN: Settings > WIFI Scan permission dialog - DIALOG_WIFI_SCAN_MODE = 543; - - // OPEN: Settings > Wireless > VPN > Config dialog - DIALOG_LEGACY_VPN_CONFIG = 545; - - // OPEN: Settings > Wireless > VPN > Config dialog for app - DIALOG_VPN_APP_CONFIG = 546; - - // OPEN: Settings > Wireless > VPN > Cannot connect dialog - DIALOG_VPN_CANNOT_CONNECT = 547; - - // OPEN: Settings > Wireless > VPN > Replace existing VPN dialog - DIALOG_VPN_REPLACE_EXISTING = 548; - - // OPEN: Settings > Billing cycle > Edit billing cycle dates dialog - DIALOG_BILLING_CYCLE = 549; - - // OPEN: Settings > Billing cycle > Edit data limit/warning dialog - DIALOG_BILLING_BYTE_LIMIT = 550; - - // OPEN: Settings > Billing cycle > turn on data limit dialog - DIALOG_BILLING_CONFIRM_LIMIT = 551; - - // OPEN: Settings > Service > Turn off notification access dialog - DIALOG_DISABLE_NOTIFICATION_ACCESS = 552; - - // OPEN: Settings > Sound > Use personal sound for work profile dialog - DIALOG_UNIFY_SOUND_SETTINGS = 553; - - // OPEN: Settings > Zen mode > Dialog warning about the zen access privileges being granted. - DIALOG_ZEN_ACCESS_GRANT = 554; - - // OPEN: Settings > Zen mode > Dialog warning about the zen access privileges being revoked. - DIALOG_ZEN_ACCESS_REVOKE = 555; - - // OPEN: Settings > Zen mode > Dialog that picks time for zen mode. - DIALOG_ZEN_TIMEPICKER = 556; - - // OPEN: Settings > Apps > Dialog that informs user to allow service access for app. - DIALOG_SERVICE_ACCESS_WARNING = 557; - - // OPEN: Settings > Apps > Dialog for app actions (such as force stop/clear data) - DIALOG_APP_INFO_ACTION = 558; - - // OPEN: Settings > Storage > Dialog for forgetting a storage device - DIALOG_VOLUME_FORGET = 559; - - // OPEN: Settings > Storage > Dialog for initializing a volume - DIALOG_VOLUME_INIT = 561; - - // OPEN: Settings > Storage > Dialog for unmounting a volume - DIALOG_VOLUME_UNMOUNT = 562; - - // OPEN: Settings > Storage > Dialog for renaming a volume - DIALOG_VOLUME_RENAME = 563; - - // OPEN: Settings > Storage > Dialog for clear cache - DIALOG_STORAGE_CLEAR_CACHE = 564; - - // OPEN: Settings > Storage > Dialog for system info - DIALOG_STORAGE_SYSTEM_INFO = 565; - - // OPEN: Settings > Storage > Dialog for other info - DIALOG_STORAGE_OTHER_INFO = 566; - - // OPEN: Settings > Storage > Dialog for user info - DIALOG_STORAGE_USER_INFO = 567; - // OPEN: Settings > Add fingerprint > Dialog when user touches fingerprint icon. - DIALOG_FINGERPRINT_ICON_TOUCH = 568; - - // OPEN: Settings > Add fingerprint > Error dialog - DIALOG_FINGERPINT_ERROR = 569; - - // OPEN: Settings > Fingerprint > Rename or delete dialog - DIALOG_FINGERPINT_EDIT = 570; - - // OPEN: Settings > Fingerprint > Dialog for deleting last fingerprint - DIALOG_FINGERPINT_DELETE_LAST = 571; - - // OPEN: SUW > Fingerprint > Dialog to confirm skip fingerprint setup entirely. - DIALOG_FINGERPRINT_SKIP_SETUP = 573; - - // OPEN: Settings > Proxy Selector error dialog - DIALOG_PROXY_SELECTOR_ERROR = 574; - - // OPEN: Settings > Wifi > P2P Settings > Disconnect dialog - DIALOG_WIFI_P2P_DISCONNECT = 575; - - // OPEN: Settings > Wifi > P2P Settings > Cancel connection dialog - DIALOG_WIFI_P2P_CANCEL_CONNECT = 576; - - // OPEN: Settings > Wifi > P2P Settings > Rename dialog - DIALOG_WIFI_P2P_RENAME = 577; - - // OPEN: Settings > Wifi > P2P Settings > Forget group dialog - DIALOG_WIFI_P2P_DELETE_GROUP = 578; - - // OPEN: Settings > APN > Restore default dialog - DIALOG_APN_RESTORE_DEFAULT = 579; - - // OPEN: Settings > Encryption interstitial accessibility warning dialog - DIALOG_ENCRYPTION_INTERSTITIAL_ACCESSIBILITY = 581; - - // OPEN: Settings > Acessibility > Enable accessiblity service dialog - DIALOG_ACCESSIBILITY_SERVICE_ENABLE = 583; - - // OPEN: Settings > Acessibility > Disable accessiblity service dialog - DIALOG_ACCESSIBILITY_SERVICE_DISABLE = 584; - - // OPEN: Settings > Account > Remove account dialog - DIALOG_ACCOUNT_SYNC_REMOVE = 585; - - // OPEN: Settings > Account > Remove account failed dialog - DIALOG_ACCOUNT_SYNC_FAILED_REMOVAL = 586; - - // OPEN: Settings > Account > Cannot do onetime sync dialog - DIALOG_ACCOUNT_SYNC_CANNOT_ONETIME_SYNC = 587; - - // OPEN: Settings > Display > Night light > Set start time dialog - DIALOG_NIGHT_DISPLAY_SET_START_TIME = 588; - - // OPEN: Settings > Display > Night light > Set end time dialog - DIALOG_NIGHT_DISPLAY_SET_END_TIME = 589; - - - - // OPEN: Settings > User > Edit info dialog - DIALOG_USER_EDIT = 590; - - // OPEN: Settings > User > Confirm remove dialog - DIALOG_USER_REMOVE = 591; - - // OPEN: Settings > User > Enable calling dialog - DIALOG_USER_ENABLE_CALLING = 592; - - // OPEN: Settings > User > Enable calling and sms dialog - DIALOG_USER_ENABLE_CALLING_AND_SMS = 593; - - // OPEN: Settings > User > Cannot manage device message dialog - DIALOG_USER_CANNOT_MANAGE = 594; - - // OPEN: Settings > User > Add user dialog - DIALOG_USER_ADD = 595; - - // OPEN: Settings > User > Setup user dialog - DIALOG_USER_SETUP = 596; - - // OPEN: Settings > User > Setup profile dialog - DIALOG_USER_SETUP_PROFILE = 597; - - // OPEN: Settings > User > Choose user type dialog - DIALOG_USER_CHOOSE_TYPE = 598; - - // OPEN: Settings > User > Need lockscreen dialog - DIALOG_USER_NEED_LOCKSCREEN = 599; - - // OPEN: Settings > User > Confirm exit guest mode dialog - DIALOG_USER_CONFIRM_EXIT_GUEST = 600; - - // OPEN: Settings > User > Edit user profile dialog - DIALOG_USER_EDIT_PROFILE = 601; - - - // OPEN: Settings > Wifi > Saved AP > Edit dialog - DIALOG_WIFI_SAVED_AP_EDIT = 602; - - // OPEN: Settings > Wifi > Edit AP dialog - DIALOG_WIFI_AP_EDIT = 603; - - // OPEN: Settings > Wifi > Write config to NFC dialog - DIALOG_WIFI_WRITE_NFC = 606; - - // OPEN: Settings > Date > Date picker dialog - DIALOG_DATE_PICKER = 607; - - // OPEN: Settings > Date > Time picker dialog - DIALOG_TIME_PICKER = 608; - - // OPEN: Settings > Wireless > Manage wireless plan dialog - DIALOG_MANAGE_MOBILE_PLAN = 609; - - // OPEN Settings > Bluetooth > Attempt to connect to device that shows dialog - BLUETOOTH_DIALOG_FRAGMENT = 613; - - // OPEN: Settings > Security - // CATEGORY: SETTINGS - // OS: O - ENTERPRISE_PRIVACY_SETTINGS = 628; - - // OPEN: Settings > System - SETTINGS_SYSTEM_CATEGORY = 744; - - // OPEN: Settings > Storage - SETTINGS_STORAGE_CATEGORY = 745; - - // OPEN: Settings > Network & Internet - SETTINGS_NETWORK_CATEGORY = 746; - - // OPEN: Settings > Connected Device - SETTINGS_CONNECTED_DEVICE_CATEGORY = 747; - - // OPEN: Settings > App & Notification - SETTINGS_APP_NOTIF_CATEGORY = 748; - - // OPEN: Settings > System > Language & Region - SETTINGS_LANGUAGE_CATEGORY = 750; - - // OPEN: Settings > System > Input & Gesture > Swipe fingerprint for notifications - SETTINGS_GESTURE_SWIPE_TO_NOTIFICATION = 751; - - // OPEN: Settings > System > Input & Gesture > Double tap power button gesture - SETTINGS_GESTURE_DOUBLE_TAP_POWER = 752; - - // OPEN: Settings > System > Input & Gesture > Pick up gesture - SETTINGS_GESTURE_PICKUP = 753; - - // OPEN: Settings > System > Input & Gesture > Double tap screen gesture - SETTINGS_GESTURE_DOUBLE_TAP_SCREEN = 754; - - // OPEN: Settings > System > Input & Gesture > Double twist gesture - SETTINGS_GESTURE_DOUBLE_TWIST = 755; - - // OPEN: Settings > Apps > Default Apps > Default browser - DEFAULT_BROWSER_PICKER = 785; - // OPEN: Settings > Apps > Default Apps > Default emergency app - DEFAULT_EMERGENCY_APP_PICKER = 786; - - // OPEN: Settings > Apps > Default Apps > Default home - DEFAULT_HOME_PICKER = 787; - - // OPEN: Settings > Apps > Default Apps > Default phone - DEFAULT_PHONE_PICKER = 788; - - // OPEN: Settings > Apps > Default Apps > Default sms - DEFAULT_SMS_PICKER = 789; - - // OPEN: Settings > Apps > Notification > Notification Assistant - DEFAULT_NOTIFICATION_ASSISTANT = 790; - - - // OPEN: Settings > Apps > Default Apps > Warning dialog to confirm selection - DEFAULT_APP_PICKER_CONFIRMATION_DIALOG = 791; - - // OPEN: Settings > Apps > Default Apps > Default autofill app - DEFAULT_AUTOFILL_PICKER = 792; - - // OPEN: Settings > Apps > Gear > Special Access > Install other apps - // CATEGORY: SETTINGS - // OS: 8.0 - MANAGE_EXTERNAL_SOURCES = 808; - - // Logs that the user has edited the picture-in-picture settings. - // CATEGORY: SETTINGS - SETTINGS_MANAGE_PICTURE_IN_PICTURE = 812; - - // OPEN: SUW Welcome Screen -> Vision Settings -> Select to Speak - // ACTION: Select to Speak configuration is chosen - // SUBTYPE: 0 is off, 1 is on - // CATEGORY: SETTINGS - // OS: N - SUW_ACCESSIBILITY_TOGGLE_SELECT_TO_SPEAK = 817; - - // OPEN: Settings > System > Backup - // CATEGORY: SETTINGS - // OS: O - BACKUP_SETTINGS = 818; - - // OPEN: Settings > Storage > Games - // CATEGORY: SETTINGS - // OS: O - APPLICATIONS_STORAGE_GAMES = 838; - - // OPEN: Settings > Storage > Audio and Music - // CATEGORY: SETTINGS - // OS: O - APPLICATIONS_STORAGE_MUSIC = 839; - - // ACTION: Settings > Storage > Free Up Space to launch Deletion Helper - // CATEGORY: SETTINGS - // OS: O - STORAGE_FREE_UP_SPACE_NOW = 840; - - // ACTION: Settings > Storage > Files to open the File Manager - // CATEGORY: SETTINGS - // OS: O - STORAGE_FILES = 841; - - // OPEN: Settings > Apps > Default Apps > Assist > Default assist - DEFAULT_ASSIST_PICKER = 843; - - // OPEN: Settings > Apps > Default Apps > Assist > Default voice input - DEFAULT_VOICE_INPUT_PICKER = 844; - - // OPEN: Settings > Storage > [Profile] - SETTINGS_STORAGE_PROFILE = 845; - - // OPEN: Settings > Security & screen lock -> Encryption & crendentials - // CATEGORY: SETTINGS - // OS: O - ENCRYPTION_AND_CREDENTIAL = 846; - - // OPEN: Settings > Wi-Fi > Network Details (click on Access Point) - // CATEGORY: SETTINGS - // OS: O - WIFI_NETWORK_DETAILS = 849; - - // OPEN: Settings > Wi-Fi > Wifi Preferences -> Advanced -> Network Scorer - // CATEGORY: SETTINGS - // OS: O - SETTINGS_NETWORK_SCORER = 861; - - // OPEN: Settings > About device > Model > Hardware info dialog - DIALOG_SETTINGS_HARDWARE_INFO = 862; - - // OPEN: Settings > Security & screen lock -> Lock screen preferences - // CATEGORY: SETTINGS - SETTINGS_LOCK_SCREEN_PREFERENCES = 882; - - - // OPEN: Settings -> Display -> When in VR Mode - VR_DISPLAY_PREFERENCE = 921; - - // OPEN: Settings > Accessibility > Magnification - // CATEGORY: SETTINGS - // OS: O - ACCESSIBILITY_SCREEN_MAGNIFICATION_SETTINGS = 922; - - // OPEN: Settings -> System -> Reset options - RESET_DASHBOARD = 924; - - // OPEN: Settings > Security > Nexus Imprint > [Fingerprint] > Delete - // CATEGORY: SETTINGS - // OS: O - FINGERPRINT_REMOVE_SIDECAR = 934; - - // OPEN: Settings > Storage > Movies & TV - // CATEGORY: SETTINGS - // OS: O - APPLICATIONS_STORAGE_MOVIES = 935; - - // OPEN: Settings > Security > Managed Device Info > Apps installed - // CATEGORY: SETTINGS - // OS: O - ENTERPRISE_PRIVACY_INSTALLED_APPS = 938; - - // OPEN: Settings > Security > Managed Device Info > nnn permissions - // CATEGORY: SETTINGS - // OS: O - ENTERPRISE_PRIVACY_PERMISSIONS = 939; - - - // OPEN: Settings > Security > Managed Device Info > Default apps - // CATEGORY: SETTINGS - // OS: O - ENTERPRISE_PRIVACY_DEFAULT_APPS = 940; - - // OPEN: Choose screen lock dialog in Settings - // CATEGORY: SETTINGS - // OS: O DR - SETTINGS_CHOOSE_LOCK_DIALOG = 990; - - // OPEN: Settings > System > Languages & input > Assist gesture - // CATEGORY: SETTINGS - // OS: O DR - SETTINGS_ASSIST_GESTURE = 996; - - // OPEN: Settings > Connected Devices > Bluetooth > (click on details link for a paired device) - BLUETOOTH_DEVICE_DETAILS = 1009; - - // OPEN: Settings > credential pages - prompt for key guard configuration confirmation - CONFIGURE_KEYGUARD_DIALOG = 1010; - - // OPEN: Settings > Network > Tether > Wi-Fi hotspot - WIFI_TETHER_SETTINGS = 1014; - - // OPEN: Settings->Connected Devices->Bluetooth->(click on details link for a paired device) - // -> Edit name button. - // CATEGORY: SETTINGS - // OS: O DR - DIALOG_BLUETOOTH_PAIRED_DEVICE_RENAME = 1015; - - // OPEN: Settings > Connected devices > Bluetooth > Pair new device - // CATEGORY: SETTINGS - // OS: O DR - BLUETOOTH_PAIRING = 1018; - - // OPEN: Settings->Connected Devices->Bluetooth->(click on details link for a paired device) - // -> Forget button. - // CATEGORY: SETTINGS - // OS: O DR - DIALOG_BLUETOOTH_PAIRED_DEVICE_FORGET = 1031; - - // OPEN: Settings > Storage > Photos & Videos - // CATEGORY: SETTINGS - // OS: O MR - APPLICATIONS_STORAGE_PHOTOS = 1092; - - // OPEN: Settings > Display > Colors - // CATEGORY: SETTINGS - // OS: O MR - COLOR_MODE_SETTINGS = 1143; - - // OPEN: Settings > Developer Options > Experiment dashboard - // CATEGORY: SETTINGS - SETTINGS_FEATURE_FLAGS_DASHBOARD = 1217; - - // OPEN: Settings > Notifications > [App] > Topic Notifications - // CATEGORY: SETTINGS - // OS: P - NOTIFICATION_CHANNEL_GROUP = 1218; - - // OPEN: Settings > Developer options > Enable > Info dialog - // CATEGORY: SETTINGS - // OS: P - DIALOG_ENABLE_DEVELOPMENT_OPTIONS = 1219; - - // OPEN: Settings > Developer options > OEM unlocking > Info dialog - // CATEGORY: SETTINGS - // OS: P - DIALOG_ENABLE_OEM_UNLOCKING = 1220; - - // OPEN: Settings > Developer options > USB debugging > Info dialog - // CATEGORY: SETTINGS - // OS: P - DIALOG_ENABLE_ADB = 1222; - - // OPEN: Settings > Security > Nexus Imprint > [Fingerprint] - // CATEGORY: SETTINGS - // OS: P - FINGERPRINT_AUTHENTICATE_SIDECAR = 1221; - - // OPEN: Settings > Developer options > Revoke USB debugging authorizations > Info dialog - // CATEGORY: SETTINGS - // OS: P - DIALOG_CLEAR_ADB_KEYS = 1223; - - // Open: Settings > Developer options > Quick setting tile config - // CATEGORY: SETTINGS - // OS: P - DEVELOPMENT_QS_TILE_CONFIG = 1224; - - // OPEN: Settings > Developer options > Store logger data persistently on device > Info dialog - // CATEGORY: SETTINGS - // OS: P - DIALOG_LOG_PERSIST = 1225; - - // OPEN: Settings > Network & Internet > Mobile network > Wi-Fi calling - // CATEGORY: SETTINGS - // OS: P - WIFI_CALLING_FOR_SUB = 1230; - - // Open: Settings > Dev options > Oem unlock > lock it > warning dialog. - // OS: P - DIALOG_OEM_LOCK_INFO = 1238; - - // Open: Settings > System > About phone > IMEI - // CATEGORY: SETTINGS - // OS: P - DIALOG_IMEI_INFO = 1240; - - // OPEN: Settings > System > About Phone > Sim status - // CATEGORY: SETTINGS - // OS: P - DIALOG_SIM_STATUS = 1246; - - // OPEN: Settings > System > About Phone > Android Version - // CATEGORY: SETTINGS - // OS: P - DIALOG_FIRMWARE_VERSION = 1247; - - // OPEN: Settings > Battery(version 2) - // CATEGORY: SETTINGS - // OS: P - FUELGAUGE_POWER_USAGE_SUMMARY_V2 = 1263; - - // OPEN: Settings > Connected devices > Connection preferences - // CATEGORY: SETTINGS - // OS: P - CONNECTION_DEVICE_ADVANCED = 1264; - - // OPEN: Settings > Security > Screen lock gear icon - // CATEGORY: SETTINGS - // OS: P - SCREEN_LOCK_SETTINGS = 1265; - - // OPEN: Settings > Sound > Do Not Disturb > Turn on automatically > Delete rule (trash can icon) - // CATEGORY: SETTINGS - // OS: P - NOTIFICATION_ZEN_MODE_DELETE_RULE_DIALOG = 1266; - - // OPEN: Settings > Sound > Do Not Disturb > Turn on automatically > Add rule > Event/Time - // OPEN: Settings > Sound > Do Not Disturb > Turn on automatically > Select rule ("Event") > Rule name - // CATEGORY: SETTINGS - // OS: P - NOTIFICATION_ZEN_MODE_RULE_NAME_DIALOG = 1269; - - // OPEN: Settings > Sound > Do Not Disturb > Turn on automatically > Add rule - // CATEGORY: SETTINGS - // OS: P - NOTIFICATION_ZEN_MODE_RULE_SELECTION_DIALOG = 1270; - - // OPEN: Settings > Battery > Smart Battery - // CATEGORY: SETTINGS - // OS: P - FUELGAUGE_SMART_BATTERY = 1281; - - // OPEN: Settings > Battery > Smart Battery > Restricted apps - // CATEGORY: SETTINGS - // OS: P - FUELGAUGE_RESTRICTED_APP_DETAILS = 1285; - - // OPEN: Settings > Sound & notification > Do Not Disturb > Turn on now - // CATEGORY: SETTINGS - // OS: P - NOTIFICATION_ZEN_MODE_ENABLE_DIALOG = 1286; - - // OPEN: Settings->Connected Devices->USB->(click on details link) - // CATEGORY: SETTINGS - // OS: P - USB_DEVICE_DETAILS = 1291; - - // OPEN: Settings > Accessibility > Vibration - // CATEGORY: SETTINGS - // OS: P - ACCESSIBILITY_VIBRATION = 1292; - - // OPEN: Settings > Accessibility > Vibration > Notification vibration - // CATEGORY: SETTINGS - // OS: P - ACCESSIBILITY_VIBRATION_NOTIFICATION = 1293; - - // OPEN: Settings > Accessibility > Vibration > Touch vibration - // CATEGORY: SETTINGS - // OS: P - ACCESSIBILITY_VIBRATION_TOUCH = 1294; - - // OPEN: Settings->Developer Options->Default USB - // CATEGORY: SETTINGS - // OS: P - USB_DEFAULT = 1312; - - // OPEN: Settings > Battery > Battery tip > Battery tip Dialog - // CATEGORY: SETTINGS - // OS: P - FUELGAUGE_BATTERY_TIP_DIALOG = 1323; - - // OPEN: DND Settings > What to block - // OS: P - ZEN_WHAT_TO_BLOCK = 1339; - - // OPEN: Settings > Sounds > Do Not Disturb > Duration - // CATEGORY: SETTINGS - // OS: P - NOTIFICATION_ZEN_MODE_DURATION_DIALOG = 1341; - - // OPEN: Settings > Date & time > Select time zone -> Region - // CATEGORY: SETTINGS - // OS: P - SETTINGS_ZONE_PICKER_REGION = 1355; - - // OPEN: Settings > Date & time > Select time zone -> Time Zone - // CATEGORY: SETTINGS - // OS: P - SETTINGS_ZONE_PICKER_TIME_ZONE = 1356; - // OPEN: Settings > Date & time > Select time zone -> Select UTC Offset - // CATEGORY: SETTINGS - // OS: P - SETTINGS_ZONE_PICKER_FIXED_OFFSET = 1357; - - // OPEN: Settings > Gestures > Prevent Ringing - // OS: P - SETTINGS_PREVENT_RINGING = 1360; - - // Settings > Condition > Device muted - // CATEGORY: SETTINGS - // OS: P - SETTINGS_CONDITION_DEVICE_MUTED = 1368; - - // Settings > Condition > Device vibrate - // CATEGORY: SETTINGS - // OS: P - SETTINGS_CONDITION_DEVICE_VIBRATE = 1369; - - // OPEN: Settings > Connected devices > previously connected devices - // CATEGORY: SETTINGS - // OS: P - PREVIOUSLY_CONNECTED_DEVICES = 1370; - - // OPEN: Settings > Network & Internet > Wi-Fi > Wi-Fi Preferences > Turn on Wi-Fi automatically - // note: Wifi Scanning must be off for this dialog to show - // CATEGORY: SETTINGS - // OS: P - WIFI_SCANNING_NEEDED_DIALOG = 1373; - - // OPEN: Settings > System > Gestures > System navigation - // CATEGORY: SETTINGS - // OS: P - SETTINGS_GESTURE_SWIPE_UP = 1374; - - // OPEN: Settings > Storage > Dialog to format a storage volume - // CATEGORY: SETTINGS - // OS: P - DIALOG_VOLUME_FORMAT = 1375; - - // OPEN: DND onboarding activity - // CATEGORY: SETTINGS - // OS: P - SETTINGS_ZEN_ONBOARDING = 1380; - - // OPEN: Settings > Display > Auto brightness - // CATEGORY: SETTINGS - // OS: P - SETTINGS_AUTO_BRIGHTNESS = 1381; - - // OPEN: Settings > Connected Devices > Bluetooth - // CATEGORY: SETTINGS - // OS: P - BLUETOOTH_FRAGMENT = 1390; - - // Screen: DND Settings > Notifications - // OS: P - SETTINGS_ZEN_NOTIFICATIONS = 1400; - - // An event category for slices. - // OPEN: Slice became visible. - // CLOSE: Slice became invisible. - // ACTION: Slice was tapped. - SLICE = 1401; - - // OPEN: Settings -> Developer Options -> Disable Bluetooth A2DP hardware - // offload - // CATEGORY: SETTINGS - // OS: P - DIALOG_BLUETOOTH_DISABLE_A2DP_HW_OFFLOAD = 1441; - - // OPEN: Settings homepage - SETTINGS_HOMEPAGE = 1502; - - // OPEN: Settings > Create shortcut(widget) - // CATEGORY: SETTINGS - // OS: Q - SETTINGS_CREATE_SHORTCUT = 1503; - - // OPEN: Face Enroll introduction - // CATEGORY: SETTINGS - // OS: Q - FACE_ENROLL_INTRO = 1506; - - // OPEN: Face Enroll introduction - // CATEGORY: SETTINGS - // OS: Q - FACE_ENROLL_ENROLLING = 1507; - - // OPEN: Face Enroll introduction - // CATEGORY: SETTINGS - // OS: Q - FACE_ENROLL_FINISHED = 1508; - - // OPEN: Face Enroll sidecar - // CATEGORY: SETTINGS - // OS: Q - FACE_ENROLL_SIDECAR = 1509; - - // OPEN: Settings > Add face > Error dialog - // OS: Q - DIALOG_FACE_ERROR = 1510; - - // OPEN: Settings > Security > Face - // CATEGORY: SETTINGS - // OS: Q - FACE = 1511; - - // OPEN: Settings > Acessibility > HearingAid pairing instructions dialog - // CATEGORY: SETTINGS - // OS: Q - DIALOG_ACCESSIBILITY_HEARINGAID = 1512; - - // OPEN: Settings > Add face - // OS: Q - FACE_ENROLL_PREVIEW = 1554; - - // OPEN: Settings > Network & Internet > Wi-Fi > Add network - // CATEGORY: SETTINGS - // OS: Q - SETTINGS_WIFI_ADD_NETWORK = 1556; - - // OPEN: Settings > System > Input & Gesture > Reach up gesture - // OS: Q - SETTINGS_GESTURE_WAKE_LOCK_SCREEN = 1557; - - // OPEN: Settings > System > Input & Gesture > Wake screen - SETTINGS_GESTURE_WAKE_SCREEN = 1570; - - // OPEN: Settings > Network & internet > Mobile network - MOBILE_NETWORK = 1571; - - // OPEN: Settings > Network & internet > Mobile network > Choose network - MOBILE_NETWORK_SELECT = 1581; - - // OPEN: Settings > Network & internet > Mobile network > Mobile Data > Dialog - MOBILE_DATA_DIALOG = 1582; - - // OPEN: Settings > Network & internet > Mobile network > Data roaming > Dialog - MOBILE_ROAMING_DIALOG = 1583; - - // Settings > Display > Lock screen display > On lock screen - LOCK_SCREEN_NOTIFICATION_CONTENT = 1584; - - // ConfirmDeviceCredentials > BiometricPrompt - BIOMETRIC_FRAGMENT = 1585; - - // OPEN: Biometric Enrollment (android.settings.BIOMETRIC_ENROLL action intent) - BIOMETRIC_ENROLL_ACTIVITY = 1586; - - // OPEN: Settings > Privacy - TOP_LEVEL_PRIVACY = 1587; - - // OPEN: Settings > Sound & notification > Do Not Disturb > See all exceptions > - // Allow apps to override - // CATEGORY: SETTINGS - // OS: Q - NOTIFICATION_ZEN_MODE_OVERRIDING_APPS = 1588; - - - // OPEN: Settings > Sound & notification > Do Not Disturb > See all exceptions > - // Allow apps to override > Choose app - // CATEGORY: SETTINGS - // OS: Q - NOTIFICATION_ZEN_MODE_OVERRIDING_APP = 1589; - - // OPEN: Settings > Developer options > Disable > Info dialog - DIALOG_DISABLE_DEVELOPMENT_OPTIONS = 1591; - - // OPEN: WifiDppConfiguratorActivity (android.settings.WIFI_DPP_CONFIGURATOR_XXX action intents) - SETTINGS_WIFI_DPP_CONFIGURATOR = 1595; - - // OPEN: WifiDppEnrolleeActivity (android.settings.WIFI_DPP_ENROLLEE_XXX action intents) - SETTINGS_WIFI_DPP_ENROLLEE = 1596; - - // OPEN: Settings > Apps & Notifications -> Special app access -> Financial Apps Sms Access - SETTINGS_FINANCIAL_APPS_SMS_ACCESS = 1597; - - - - // OPEN: Settings > Sound > Do Not Disturb > Schedules > (Click on system rule) - // > Do Not Disturb behavior - // CATEGORY: SETTINGS - // OS: Q - ZEN_CUSTOM_RULE_SETTINGS = 1604; - - // OPEN: Settings > Sound > Do Not Disturb > Schedules > (Click on system rule) - // > Do Not Disturb behavior > Custom - // CATEGORY: SETTINGS - // OS: Q - ZEN_CUSTOM_RULE_SOUND_SETTINGS = 1605; - - // OPEN: Settings > Sound > Do Not Disturb > Schedules > (Click on system rule) - // > Do Not Disturb behavior > Use default Do Not Disturb behavior - // CATEGORY: SETTINGS - // OS: Q - ZEN_CUSTOM_RULE_DEFAULT_SETTINGS = 1606; - - // OPEN: Settings > Sound > Do Not Disturb > Schedules > (Click on system rule) - // > Do Not Disturb behavior > Use default Do Not Disturb behavior - // > Notification restriction - // CATEGORY: SETTINGS - // OS: Q - ZEN_CUSTOM_RULE_NOTIFICATION_RESTRICTIONS = 1608; - - // OPEN: Settings > Sound > Do Not Disturb > Schedules > (Click on system rule) - // > Do Not Disturb behavior > Use default Do Not Disturb behavior - // > Notification restriction > Custom - // CATEGORY: SETTINGS - // OS: Q - ZEN_CUSTOM_RULE_VIS_EFFECTS = 1609; - - // OPEN: Settings > Sound > Do Not Disturb > Schedules > (Click on system rule) - // > Do Not Disturb behavior > Use default Do Not Disturb behavior - // > Notification restriction > Custom > Allow messages - // CATEGORY: SETTINGS - // OS: Q - ZEN_CUSTOM_RULE_MESSAGES = 1610; - - // OPEN: Settings > Sound > Do Not Disturb > Schedules > (Click on system rule) - // > Do Not Disturb behavior > Use default Do Not Disturb behavior - // > Notification restriction > Custom > Allow calls - // CATEGORY: SETTINGS - // OS: Q - ZEN_CUSTOM_RULE_CALLS = 1611; - - // OPEN: Settings > Sound > Do Not Disturb > Click footer link if custom settings applied - // CATEGORY: SETTINGS - // OS: Q - ZEN_CUSTOM_SETTINGS_DIALOG = 1612; - - // OPEN: Settings > Developer Options > Graphics Driver Preferences - // CATEGORY: SETTINGS - // OS: Q - SETTINGS_GRAPHICS_DRIVER_DASHBOARD = 1613; - - // OPEN: Settings > Accessibility > Vibration > Ring vibration - // CATEGORY: SETTINGS - // OS: Q - ACCESSIBILITY_VIBRATION_RING = 1620; - - // OPEN: Settings > System > Input & Gesture > Skip songs - SETTINGS_GESTURE_SKIP = 1624; - - // OPEN: Settings > System > Input & Gesture > Silence alerts - SETTINGS_GESTURE_SILENCE = 1625; - - // OPEN: Settings > System > Input & Gesture > Tap to check - SETTINGS_GESTURE_TAP_SCREEN = 1626; - - // OPEN: Settings > Network & internet > Click Mobile network to land on a page with a list of - // SIM/eSIM subscriptions. - MOBILE_NETWORK_LIST = 1627; - - // OPEN: Settings > Display > Adaptive sleep - // OS: Q - SETTINGS_ADAPTIVE_SLEEP = 1628; - - // OPEN: Settings > System > Aware - SETTINGS_AWARE = 1632; - - // OPEN: Settings > System > Aware > Disable > Dialog - DIALOG_AWARE_DISABLE = 1633; - - // OPEN: Settings > Settings > Network & internet > Click Mobile network to land on page with - // details for a SIM/eSIM mobile network > Click edit icon to bring up a rename dialog. - // OS: Q - MOBILE_NETWORK_RENAME_DIALOG = 1642; - - // OPEN: Set new password (android.app.action.SET_NEW_PASSWORD action intent) - // CATEGORY: SETTINGS - // OS: Q - SET_NEW_PASSWORD_ACTIVITY = 1644; - - // Panel for Internet Connectivity - PANEL_INTERNET_CONNECTIVITY = 1654; - - // Panel for Volume - PANEL_VOLUME = 1655; - - // Panel for NFC - PANEL_NFC = 1656; - - // Panel for Media Output - PANEL_MEDIA_OUTPUT = 1657; - - // Mapping: go/at-mapping - PAGE_ATSSI = 1667; - - PAGE_ATSII = 1668; - - PAGE_ATUS = 1669; - - PAGE_ATSSP = 1670; - - PAGE_ATSAP = 1671; - - PAGE_ATSCP = 1672; - - PAGE_ATHNP = 1673; - - // OPEN: Accessibility detail settings (android.settings.ACCESSIBILITY_DETAILS_SETTINGS intent) - ACCESSIBILITY_DETAILS_SETTINGS = 1682; - - // Open: Settings will show the conditional when Grayscale mode is on - SETTINGS_CONDITION_GRAYSCALE_MODE = 1683; - - // Panel for Wifi - PANEL_WIFI = 1687; - - // Open: Settings > Special App Access > Do not disturb control for app - ZEN_ACCESS_DETAIL = 1692; - - // OPEN: Settings > Face > Remove face - // OS: Q - DIALOG_FACE_REMOVE = 1693; - - // Settings > Display > Theme - DARK_UI_SETTINGS = 1698; - - // Settings > global bubble settings - BUBBLE_SETTINGS = 1699; - - // Settings > app > bubble settings - APP_BUBBLE_SETTINGS = 1700; - - // OPEN: Settings > System > Aware > Info dialog - DIALOG_AWARE_STATUS = 1701; - - // Open: Settings > app > bubble settings > confirmation dialog - DIALOG_APP_BUBBLE_SETTINGS = 1702; - - // OPEN: Settings > Pick SIM dialog - DIALOG_SIM_LIST = 1707; - - // OPEN: Settings > Pick SIM (that supports calling) dialog - DIALOG_CALL_SIM_LIST = 1708; - - // OPEN: Settings > Pick preferred SIM dialog - DIALOG_PREFERRED_SIM_PICKER = 1709; - - // OPEN: Settings > Network & internet > Mobile network > Delete sim - DIALOG_DELETE_SIM_CONFIRMATION = 1713; - - // OPEN: Settings > Network & internet > Mobile network > Delete sim > (answer yes to - // confirmation) - DIALOG_DELETE_SIM_PROGRESS = 1714; - - // Settings > Apps and notifications > Notifications > Gentle notifications - GENTLE_NOTIFICATIONS_SCREEN = 1715; - - // OPEN: Settings > System > Gestures > Global Actions Panel - // CATEGORY: SETTINGS - // OS: Q - GLOBAL_ACTIONS_PANEL_SETTINGS = 1728; - - // OPEN: Settings > Display > Dark Theme - // CATEGORY: SETTINGS - // OS: Q - // Note: Only shows up on first time toggle - DIALOG_DARK_UI_INFO = 1740; - - // OPEN: Settings > About phone > Legal information > Google Play system update licenses - // CATEGORY: SETTINGS - // OS: Q - MODULE_LICENSES_DASHBOARD = 1746; - - // OPEN: Settings > System > Gestures > System navigation > Info icon - // CATEGORY: SETTINGS - // OS: Q - // Note: Info icon is visible only when gesture navigation is not available and disabled - SETTINGS_GESTURE_NAV_NOT_AVAILABLE_DLG = 1747; - - // OPEN: Settings > System > Gestures > System navigation > Gear icon - // CATEGORY: SETTINGS - // OS: Q - // Note: Gear icon is shown next to gesture navigation preference and opens sensitivity dialog - SETTINGS_GESTURE_NAV_BACK_SENSITIVITY_DLG = 1748; - - // OPEN: Settings > System > Aware > Aware Display - // CATEGORY: SETTINGS - // OS: Q - SETTINGS_AWARE_DISPLAY = 1750; - - // OPEN: Settings > System > Input & Gesture > tap gesture - // CATEGORY: SETTINGS - // OS: Q - SETTINGS_GESTURE_TAP = 1751; - // ---- End Q Constants, all Q constants go above this line ---- - // OPEN: Settings > Network & Internet > Wi-Fi > Click new network - // CATEGORY: SETTINGS - // OS: R - SETTINGS_WIFI_CONFIGURE_NETWORK = 1800; - - // OPEN: Settings > Accessibility > Magnification - // CATEGORY: SETTINGS - // OS: R - // Note: Shows up only when Magnify with shortcut is enabled - // and under accessibility button mode. - DIALOG_TOGGLE_SCREEN_MAGNIFICATION_ACCESSIBILITY_BUTTON = 1801; - - // OPEN: Settings > Accessibility > Magnification - // CATEGORY: SETTINGS - // OS: R - // Note: Shows up only when Magnify with shortcut is enabled. - // and under gesture navigation mode. - DIALOG_TOGGLE_SCREEN_MAGNIFICATION_GESTURE_NAVIGATION = 1802; - - // OPEN: Settings > Security & screen lock -> Encryption & credentials > Install a certificate - // CATEGORY: SETTINGS - // OS: R - INSTALL_CERTIFICATE_FROM_STORAGE = 1803; - - // OPEN: Settings > Apps and notifications > Special app access > notification access > - // an app - // CATEGORY: SETTINGS - // OS: R - NOTIFICATION_ACCESS_DETAIL = 1804; - - // OPEN: Settings > Developer Options > Platform Compat - // CATEGORY: SETTINGS - // OS: R - SETTINGS_PLATFORM_COMPAT_DASHBOARD = 1805; - - // OPEN: Settings > Location -> Work profile tab - // CATEGORY: SETTINGS - // OS: R - LOCATION_WORK = 1806; - - // OPEN: Settings > Account -> Work profile tab - // CATEGORY: SETTINGS - // OS: R - ACCOUNT_WORK = 1807; - - // OPEN: Settings > Developer Options > Bug report handler - // CATEGORY: SETTINGS - // OS: R - SETTINGS_BUGREPORT_HANDLER = 1808; - - // Panel for adding Wi-Fi networks - // CATEGORY: SETTINGS - // OS: R - PANEL_ADD_WIFI_NETWORKS = 1809; - - // OPEN: Settings > Accessibility > Enable the feature or shortcut > Show tutorial dialog - // CATEGORY: SETTINGS - // OS: R - DIALOG_ACCESSIBILITY_TUTORIAL = 1810; - - // OPEN: Settings > Accessibility > Edit shortcut dialog - // CATEGORY: SETTINGS - // OS: R - DIALOG_ACCESSIBILITY_SERVICE_EDIT_SHORTCUT = 1812; - - // OPEN: Settings > Accessibility > Magnification > Edit shortcut dialog - // CATEGORY: SETTINGS - // OS: R - DIALOG_MAGNIFICATION_EDIT_SHORTCUT = 1813; - - // OPEN: Settings > Accessibility > Color correction > Edit shortcut dialog - // CATEGORY: SETTINGS - // OS: R - DIALOG_DALTONIZER_EDIT_SHORTCUT = 1814; - - // OPEN: Settings > Accessibility > Magnification > Settings - // CATEGORY: SETTINGS - // OS: R - ACCESSIBILITY_MAGNIFICATION_SETTINGS = 1815; - - // OPEN: Settings > Accessibility > Magnification > Settings > Magnification area dialog - // CATEGORY: SETTINGS - // OS: R - DIALOG_MAGNIFICATION_CAPABILITY = 1816; - - // OPEN: Settings > Accessibility > Color inversion - // CATEGORY: SETTINGS - // OS: R - ACCESSIBILITY_COLOR_INVERSION_SETTINGS = 1817; - - // OPEN: Settings > Accessibility > Color inversion > Edit shortcut dialog - // CATEGORY: SETTINGS - // OS: R - DIALOG_COLOR_INVERSION_EDIT_SHORTCUT = 1818; - - // OPEN: Settings > Accessibility > Captions preference > Captions appearance - // CATEGORY: SETTINGS - // OS: R - ACCESSIBILITY_CAPTION_APPEARANCE = 1819; - - // OPEN: Settings > Accessibility > Captions preference > More options - // CATEGORY: SETTINGS - // OS: R - ACCESSIBILITY_CAPTION_MORE_OPTIONS = 1820; - - // OPEN: Settings > Battery > Battery share - // CATEGORY: SETTINGS - // OS: R - FUELGAUGE_BATTERY_SHARE = 1821; - - // OPEN: Settings -> Apps & Notifications -> Special App Access - // CATEGORY: SETTINGS - // OS: R - MANAGE_EXTERNAL_STORAGE = 1822; - - // Open: Settings > DND > People - // OS: R - DND_PEOPLE = 1823; - - // OPEN: Settings > Apps and notifications > App info > one of any app > Open by default - // > Open supported links - // CATEGORY: SETTINGS - // OS: R - OPEN_SUPPORTED_LINKS = 1824; - - // OPEN: Settings > Display > Dark theme > Set start time dialog - DIALOG_DARK_THEME_SET_START_TIME = 1825; - - // OPEN: Settings > Display > Dark theme > Set end time dialog - DIALOG_DARK_THEME_SET_END_TIME = 1826; - - // OPEN: Settings -> Sound -> Vibrate for calls - // CATEGORY: SETTINGS - // OS: R - VIBRATE_FOR_CALLS = 1827; - - // OPEN: Settings > Connected devices > Connection preferences > NFC - // CATEGORY: SETTINGS - // OS: R - CONNECTION_DEVICE_ADVANCED_NFC = 1828; - - // OPEN: Settings -> Apps & Notifications -> Special App Access - INTERACT_ACROSS_PROFILES = 1829; - - // OPEN: Settings > Notifications > (app or conversations) > conversation - NOTIFICATION_CONVERSATION_SETTINGS = 1830; - - // OPEN: Settings > Developer Options > Wireless debugging - // CATEGORY: SETTINGS - // OS: R - SETTINGS_ADB_WIRELESS = 1831; - - // OPEN: Settings > Developer Options > Wireless debugging - // > Pair device with pairing code > Pairing code dialog - // CATEGORY: SETTINGS - // OS: R - ADB_WIRELESS_DEVICE_PAIRING_DIALOG = 1832; - - // OPEN: Settings > Developer Options > Wireless debugging - // > Pair device with QR code > Scan QR code > Pairing device dialog - // CATEGORY: SETTINGS - // OS: R - ADB_WIRELESS_DEVICE_QR_PAIRING_DIALOG = 1833; - - // OPEN: Settings > apps & notifications > notifications > conversations - // CATEGORY: SETTINGS - // OS: R - NOTIFICATION_CONVERSATION_LIST_SETTINGS = 1834; - - // Panel for Media Output Group operation - // CATEGORY: SETTINGS - // OS: R - PANEL_MEDIA_OUTPUT_GROUP = 1835; - - // OPEN: Settings > Developer Options > Wireless debugging - // > Click on paired device - // CATEGORY: SETTINGS - // OS: R - ADB_WIRELESS_DEVICE_DETAILS = 1836; - - // Open: Settings > Sound > Do Not Disturb > People > Conversations - // OS: R - DND_CONVERSATIONS = 1837; - - // Open: Settings > Sound > Do Not Disturb > People > Calls - // OS: R - DND_CALLS = 1838; - - // Open: Settings > Sound > Do Not Disturb > People > Messages - // OS: R - DND_MESSAGES = 1839; - - // Open: Settings > Sound > Do Not Disturb > Apps > <Choose App> - // OS: R - DND_APPS_BYPASSING = 1840; - - // OPEN: Settings > System > Gestures > One-Handed - // CATEGORY: SETTINGS - // OS: R QPR - SETTINGS_ONE_HANDED = 1841; - - // OPEN: Settings > Battery > Advanced battery option - // CATEGORY: SETTINGS - // OS: R - FUELGAUGE_ADVANCED_BATTERY_OPTION = 1842; - - // OPEN: Settings > System > Gestures > Power menu - // CATEGORY: SETTINGS - // OS: R - POWER_MENU_SETTINGS = 1843; - - // OPEN: Settings > System > Gestures > Power menu > Device controls - // CATEGORY: SETTINGS - // OS: R - DEVICE_CONTROLS_SETTINGS = 1844; - - // OPEN: Settings > Sound > Media - // CATEGORY: SETTINGS - // OS: R - MEDIA_CONTROLS_SETTINGS = 1845; - - // OPEN: Settings > System > Gestures > Swipe for notification - // CATEGORY: SETTINGS - // OS: R QPR - SETTINGS_SWIPE_BOTTOM_TO_NOTIFICATION = 1846; - - // OPEN: Settings > System > Gestures > Emergency SOS Gesture - // CATEGORY: SETTINGS - // OS: S - EMERGENCY_SOS_GESTURE_SETTINGS = 1847; - - // OPEN: Settings > System > Gestures > Double tap - // CATEGORY: SETTINGS - // OS: S - SETTINGS_COLUMBUS = 1848; - - // OPEN: Settings > Accessibility > Magnification > Settings > Magnification area > Magnification switch shortcut dialog - // CATEGORY: SETTINGS - // OS: S - DIALOG_MAGNIFICATION_SWITCH_SHORTCUT = 1849; - - // OPEN: Settings > Network & internet > Adaptive connectivity - // CATEGORY: SETTINGS - // OS: R QPR - ADAPTIVE_CONNECTIVITY_CATEGORY = 1850; - - // OS: R QPR2 - BLUETOOTH_PAIRING_RECEIVER = 1851; - - // OPEN: Settings > Display > Screen timeout - // CATEGORY: SETTINGS - // OS: S - SCREEN_TIMEOUT = 1852; - - // OPEN: Settings > Accessibility > Reduce Bright Colors - // CATEGORY: SETTINGS - // OS: S - REDUCE_BRIGHT_COLORS_SETTINGS = 1853; - - // OPEN: Settings > Location > Time Zone Detection - // CATEGORY: SETTINGS - // OS: S - LOCATION_TIME_ZONE_DETECTION = 1854; - - // OPEN: Settings > Developer options > Media transcode settings - // CATEGORY: SETTINGS - // OS: S - TRANSCODE_SETTINGS = 1855; -} diff --git a/core/proto/android/app/tvsettings_enums.proto b/core/proto/android/app/tvsettings_enums.proto deleted file mode 100644 index 77bf98f1c15e..000000000000 --- a/core/proto/android/app/tvsettings_enums.proto +++ /dev/null @@ -1,1132 +0,0 @@ -/* - * 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. - */ - -syntax = "proto2"; - -package android.app.tvsettings; -option java_multiple_files = true; -option java_outer_classname = "TvSettingsEnums"; - -/** The performed action types */ -enum Action { - - /** - * Denotes an unknown action. It is a filler that should generally be - * avoided. - */ - ACTION_UNKNOWN = 0; - - /** - * Denotes that a TvSettings page is being focused. (Previewing a page in - * two panel settings should NOT be considered as focusing on the page.) - */ - PAGE_FOCUSED = 1; - - /** - * Denotes that an entry (typically a leaf node of settings tree) is - * selected by a user. - */ - ENTRY_SELECTED = 2; - - /** Denotes that a toggle is clicked by a user. */ - TOGGLE_INTERACTED = 3; - - /** - * Denotes that a TvSettings page is being focused in the forward direction - * into the settings tree. - */ - PAGE_FOCUSED_FORWARD = 4; - - /** - * Denotes that a TvSettings page is being focused in the backward direction - * up the settings tree. - */ - PAGE_FOCUSED_BACKWARD = 5; - - /** Denotes that a toggle is turned on by a user. */ - TOGGLED_ON = 6; - - /** Denotes that a toggle is turned off by a user. */ - TOGGLED_OFF = 7; - -} - -/** - * Ids for TvSettings focusable pages or actionable entries - * - * For details of the scheme, please refer to the "Definition of item_id" and - * "Evolve of item_id" sections in go/atv-settings-ww-logging-design. - */ -enum ItemId { - - option allow_alias = true; - - // Filler that should be avoided - UNKNOWN = 0x00000000; - - // TvSettings - TV_SETTINGS_ROOT = 0x00000001; - - // TvSettings unknown/default classic page - PAGE_CLASSIC_DEFAULT = 0x00000002; - - // TvSettings unknown/default slice page - PAGE_SLICE_DEFAULT = 0x00000003; - - // TvSettings unknown/default entry - ENTRY_DEFAULT = 0x00000004; - - // TvSettings > Suggested settings entry - SUGGESTED_SETTINGS = 0x00000010; - - // TvSettings > Quick Settings - QUICK_SETTINGS = 0x00000011; - - // VERSION 1: Starting with Q - // These are ordered in depth-first search manner. - - // TvSettings > Network & Internet - NETWORK = 0x11000000; - - // TvSettings > Network & Internet > Wi-Fi (toggle) - NETWORK_WIFI_ON_OFF = 0x11100000; - - // TvSettings > Network & Internet > - // [A connected network entry in available networks list] - NETWORK_AP_INFO = 0x11200000; - - // TvSettings > Network & Internet > - // [A connected network entry in available networks list] > Proxy settings - NETWORK_AP_INFO_PROXY_SETTINGS = 0x11210000; - - // TvSettings > Network & Internet > - // [A connected network entry in available networks list] > IP settings - NETWORK_AP_INFO_IP_SETTINGS = 0x11220000; - - // TvSettings > Network & Internet > - // [A connected network entry in available networks list] > Forget network - NETWORK_AP_INFO_FORGET_NETWORK = 0x11230000; - - // TvSettings > Network & Internet > - // [A not connected network entry in available networks list] - NETWORK_NOT_CONNECTED_AP = 0x11300000; - - // TvSettings > Network & Internet > See all - NETWORK_SEE_ALL = 0x11400000; - - // TvSettings > Network & Internet > See fewer - NETWORK_SEE_FEWER = 0x11500000; - - // TvSettings > Network & Internet > Add new network - NETWORK_ADD_NEW_NETWORK = 0x11600000; - - // TvSettings > Network & Internet > Scanning always available (toggle) - NETWORK_ALWAYS_SCANNING_NETWORKS = 0x11700000; - - // TvSettings > Network & Internet > Proxy settings (in Ethernet category) - NETWORK_ETHERNET_PROXY_SETTINGS = 0x11800000; - - // TvSettings > Network & Internet > IP settings (in Ethernet category) - NETWORK_ETHERNET_IP_SETTINGS = 0x11900000; - - // TvSettings > Account & Sign In (Slice) - ACCOUNT_SLICE = 0x12000000; - - // TvSettings > Account & Sign In (Slice) > [A regular account] - ACCOUNT_SLICE_REG_ACCOUNT = 0x12100000; - - // TvSettings > Account & Sign In (Slice) > [A regular account] > - // Services - ACCOUNT_SLICE_REG_ACCOUNT_SERVICES = 0x12110000; - - // TvSettings > Account & Sign In (Slice) > [A regular account] > - // Payment & Purchases - ACCOUNT_SLICE_REG_ACCOUNT_PAYMENT = 0x12120000; - - // TvSettings > Account & Sign In (Slice) > [A regular account] > - // Payment & Purchases > - // Require authentication for purchases (reauth interval) - ACCOUNT_SLICE_REG_ACCOUNT_PAYMENT_REAUTH = 0x12121000; - - // TvSettings > Account & Sign In (Slice) > [A regular account] > - // Payment & Purchases > - // Require authentication for purchases (reauth interval) > Always - ACCOUNT_SLICE_REG_ACCOUNT_PAYMENT_REAUTH_ALWAYS = 0x12121100; - - // TvSettings > Account & Sign In (Slice) > [A regular account] > - // Payment & Purchases > - // Require authentication for purchases (reauth interval) > Every 30 minutes - ACCOUNT_SLICE_REG_ACCOUNT_PAYMENT_REAUTH_30MINS = 0x12121200; - - // TvSettings > Account & Sign In (Slice) > [A regular account] > - // Payment & Purchases > - // Require authentication for purchases (reauth interval) > Never - ACCOUNT_SLICE_REG_ACCOUNT_PAYMENT_REAUTH_NEVER = 0x12121300; - - // TvSettings > Account & Sign In (Slice) > [A regular account] > - // Google Assistant - ACCOUNT_SLICE_REG_ACCOUNT_ASSISTANT = 0x12130000; - - // TvSettings > Account & Sign In (Slice) > [A regular account] > - // Google Assistant > SafeSearch filter (toggle) - ACCOUNT_SLICE_REG_ACCOUNT_ASSISTANT_SAFE_SEARCH = 0x12131000; - - // TvSettings > Account & Sign In (Slice) > [A regular account] > - // Google Assistant > Block offensive words (toggle) - ACCOUNT_SLICE_REG_ACCOUNT_ASSISTANT_BLOCK_OFFENSIVE = 0x12132000; - - // TvSettings > Account & Sign In (Slice) > [A regular account] > - // Google Assistant > Searchable apps - ACCOUNT_SLICE_REG_ACCOUNT_ASSISTANT_SEARCHABLE_APPS = 0x12133000; - - // TvSettings > Account & Sign In (Slice) > [A regular account] > - // Google Assistant > Personal results (toggle) - ACCOUNT_SLICE_REG_ACCOUNT_ASSISTANT_PERSONAL_RESULTS = 0x12134000; - - // TvSettings > Account & Sign In (Slice) > [A regular account] > - // Apps only mode (toggle) - ACCOUNT_SLICE_REG_ACCOUNT_APPS_ONLY_MODE = 0x12140000; - - // Reserving [0x12150000, 0x12190000] for possible future settings - - // TvSettings > Account & Sign In (Slice) > [A regular account] > Remove - ACCOUNT_SLICE_REG_ACCOUNT_REMOVE = 0x121A0000; - - // Reserving [0x12200000, 0x12900000] for possible future settings - - // TvSettings > Account & Sign In (Slice) > Add account... - ACCOUNT_SLICE_ADD_ACCOUNT = 0x12A00000; - - // TvSettings > Account & Sign In (Classic) - ACCOUNT_CLASSIC = 0x13000000; - - // TvSettings > Account & Sign In (Classic) > [A regular account] - ACCOUNT_CLASSIC_REG_ACCOUNT = 0x13100000; - - // TvSettings > Account & Sign In (Classic) > [A regular account] > Sync now - ACCOUNT_CLASSIC_REG_ACCOUNT_SYNC_NOW = 0x13110000; - - // TvSettings > Account & Sign In (Classic) > [A regular account] > - // Remove account - ACCOUNT_CLASSIC_REG_ACCOUNT_REMOVE_ACCOUNT = 0x13120000; - - // TvSettings > Account & Sign In (Classic) > [A regular account] > - // [Choose synced apps] Calendar (toggle) - ACCOUNT_CLASSIC_REG_ACCOUNT_SYNC_CALENDAR = 0x13130000; - - // TvSettings > Account & Sign In (Classic) > [A regular account] > - // [Choose synced apps] Contacts (toggle) - ACCOUNT_CLASSIC_REG_ACCOUNT_SYNC_CONTACTS = 0x13140000; - - // TvSettings > Account & Sign In (Classic) > [A regular account] > - // [Choose synced apps] Google Play Movies & TV (toggle) - ACCOUNT_CLASSIC_REG_ACCOUNT_SYNC_GPMT = 0x13150000; - - // TvSettings > Account & Sign In (Classic) > [A regular account] > - // [Choose synced apps] Google Play Music (toggle) - ACCOUNT_CLASSIC_REG_ACCOUNT_SYNC_GPM = 0x13160000; - - // TvSettings > Account & Sign In (Classic) > [A regular account] > - // [Choose synced apps] People details (toggle) - ACCOUNT_CLASSIC_REG_ACCOUNT_SYNC_PEOPLE = 0x13170000; - - // Reserving [0x13200000, 0x13900000] for possible future settings - - // TvSettings > Account & Sign In (Classic) > Add account - ACCOUNT_CLASSIC_ADD_ACCOUNT = 0x13A00000; - - // TvSettings > Privacy - PRIVACY = 0x14000000; - - // TvSettings > Privacy > Location - PRIVACY_LOCATION = 0x14100000; - - // TvSettings > Privacy > Location > Location status (radio button) - PRIVACY_LOCATION_STATUS = 0x14110000; - - // TvSettings > Privacy > Location > Location status (radio button) > - // Use Wi-Fi to estimate location - PRIVACY_LOCATION_STATUS_USE_WIFI = 0x14111000; - - // TvSettings > Privacy > Location > Location status (radio button) > Off - PRIVACY_LOCATION_STATUS_OFF = 0x14112000; - - // TvSettings > Privacy > Location > Scanning always available (toggle) - PRIVACY_LOCATION_ALWAYS_SCANNING_NETWORKS = 0x14120000; - - // TvSettings > Privacy > Location > [An app that had recent requests] - PRIVACY_LOCATION_REQUESTED_APP = 0x14130000; - - // TvSettings > Privacy > Usage & Diagnostics - PRIVACY_DIAGNOSTICS = 0x14200000; - - // TvSettings > Privacy > Usage & Diagnostics > On (Toggle) - PRIVACY_DIAGNOSTICS_ON_OFF = 0x14210000; - - // TvSettings > Privacy > Ads - PRIVACY_ADS = 0x14300000; - - // The following three IDs may not actually be logged as they are within a - // GMSCore Activity but we reserve IDs for them. - // TvSettings > Privacy > Ads > Reset advertising ID - PRIVACY_ADS_RESET_AD_ID = 0x14310000; - - // TvSettings > Privacy > Ads > Opt out of Ads Personalization - PRIVACY_ADS_OPT_OUT_PERSONALIZATION = 0x14320000; - - // TvSettings > Privacy > Ads > Ads by Google (WebView) - PRIVACY_ADS_ADS_BY_GOOGLE = 0x14330000; - - // TvSettings > Display & Sound - DISPLAY_SOUND = 0x15000000; - - // TvSettings > Display & Sound > Advanced display settings - DISPLAY_SOUND_ADVANCED_DISPLAY = 0x15100000; - - // TvSettings > Display & Sound > Advanced display settings > - // Allow game mode (toggle) - DISPLAY_SOUND_ADVANCED_DISPLAY_GAME_MODE = 0x15110000; - - // TvSettings > Display & Sound > System sounds (toggle) - DISPLAY_SOUND_SYSTEM_SOUNDS = 0x15200000; - - // TvSettings > Display & Sound > Advanced sound settings - DISPLAY_SOUND_ADVANCED_SOUNDS = 0x15300000; - - // TvSettings > Display & Sound > Advanced sound settings > Select formats - DISPLAY_SOUND_ADVANCED_SOUNDS_SELECT_FORMATS = 0x15310000; - - // TvSettings > Display & Sound > Advanced sound settings > Select formats > - // Auto... - DISPLAY_SOUND_ADVANCED_SOUNDS_SELECT_FORMATS_AUTO = 0x15311000; - - // TvSettings > Display & Sound > Advanced sound settings > Select formats > - // None... - DISPLAY_SOUND_ADVANCED_SOUNDS_SELECT_FORMATS_NONE = 0x15312000; - - // TvSettings > Display & Sound > Advanced sound settings > Select formats > - // Manual... - DISPLAY_SOUND_ADVANCED_SOUNDS_SELECT_FORMATS_MANUAL = 0x15313000; - - // TvSettings > Display & Sound > Advanced sound settings > - // Dolby AC-4 (toggle) - DISPLAY_SOUND_ADVANCED_SOUNDS_DAC4 = 0x15320000; - - // TvSettings > Display & Sound > Advanced sound settings > - // Dolby Atmos in Dolby Digital Plus (toggle) - DISPLAY_SOUND_ADVANCED_SOUNDS_DADDP = 0x15330000; - - // TvSettings > Display & Sound > Advanced sound settings > - // Dolby Digital (toggle) - DISPLAY_SOUND_ADVANCED_SOUNDS_DD = 0x15340000; - - // TvSettings > Display & Sound > Advanced sound settings > - // Dolby Digital Plus (toggle) - DISPLAY_SOUND_ADVANCED_SOUNDS_DDP = 0x15350000; - - // TvSettings > Display & Sound > Advanced sound settings > DTS (toggle) - DISPLAY_SOUND_ADVANCED_SOUNDS_DTS = 0x15360000; - - // TvSettings > Display & Sound > Advanced sound settings > DTS-HD (toggle) - DISPLAY_SOUND_ADVANCED_SOUNDS_DTSHD = 0x15370000; - - // TvSettings > Display & Sound > Advanced sound settings > AAC (toggle) - DISPLAY_SOUND_ADVANCED_SOUNDS_AAC = 0x15380000; - - // TvSettings > Display & Sound > Advanced sound settings > - // Dolby TrueHD (toggle) - DISPLAY_SOUND_ADVANCED_SOUNDS_DTHD = 0x15390000; - - // TvSettings > Apps - APPS = 0x16000000; - - // TvSettings > Apps > See all apps - APPS_ALL_APPS = 0x16100000; - - // TvSettings > Apps > See all apps > [An app entry] - APPS_ALL_APPS_APP_ENTRY = 0x16110000; - - // TvSettings > Apps > See all apps > [An app entry] > Open - APPS_ALL_APPS_APP_ENTRY_OPEN = 0x16111000; - - // TvSettings > Apps > See all apps > [An app entry] > Force stop - APPS_ALL_APPS_APP_ENTRY_FORCE_STOP = 0x16112000; - - // TvSettings > Apps > See all apps > [An app entry] > Uninstall - APPS_ALL_APPS_APP_ENTRY_UNINSTALL = 0x16113000; - - // TvSettings > Apps > See all apps > [An app entry] > Uninstall updates - APPS_ALL_APPS_APP_ENTRY_UNINSTALL_UPDATES = 0x16114000; - - // TvSettings > Apps > See all apps > [An app entry] > Disable - APPS_ALL_APPS_APP_ENTRY_DISABLE = 0x16115000; - - // TvSettings > Apps > See all apps > [An app entry] > Clear data - APPS_ALL_APPS_APP_ENTRY_CLEAR_DATA = 0x16116000; - - // TvSettings > Apps > See all apps > [An app entry] > Clear cache - APPS_ALL_APPS_APP_ENTRY_CLEAR_CACHE = 0x16117000; - - // TvSettings > Apps > See all apps > [An app entry] > Clear defaults - APPS_ALL_APPS_APP_ENTRY_CLEAR_DEFAULTS = 0x16118000; - - // TvSettings > Apps > See all apps > [An app entry] > - // Notifications (toggle) - APPS_ALL_APPS_APP_ENTRY_NOTIFICATIONS = 0x16119000; - - // TvSettings > Apps > See all apps > [An app entry] > Permissions - APPS_ALL_APPS_APP_ENTRY_PERMISSIONS = 0x1611A000; - - // TvSettings > Apps > See all apps > [An app entry] > Enable - APPS_ALL_APPS_APP_ENTRY_ENABLE = 0x1611B000; - - // TvSettings > Apps > See all apps > [An app entry] > Open source licenses - APPS_ALL_APPS_APP_ENTRY_LICENSES = 0x1611C000; - - // TvSettings > Apps > See all apps > Show system apps - APPS_ALL_APPS_SHOW_SYSTEM_APPS = 0x16120000; - - // TvSettings > Apps > App permissions - APPS_APP_PERMISSIONS = 0x16200000; - - // TvSettings > Apps > App permission > Body sensors - APPS_APP_PERMISSIONS_BODY_SENSORS = 0x16210000; - - // TvSettings > Apps > App permission > Calendar - APPS_APP_PERMISSIONS_CALENDAR = 0x16220000; - - // TvSettings > Apps > App permission > Call logs - APPS_APP_PERMISSIONS_CALL_LOGS = 0x16230000; - - // TvSettings > Apps > App permission > Camera - APPS_APP_PERMISSIONS_CAMERA = 0x16240000; - - // TvSettings > Apps > App permission > Contacts - APPS_APP_PERMISSIONS_CONTACTS = 0x16250000; - - // TvSettings > Apps > App permission > Location - APPS_APP_PERMISSIONS_LOCATION = 0x16260000; - - // TvSettings > Apps > App permission > Microphone - APPS_APP_PERMISSIONS_MICROPHONE = 0x16270000; - - // TvSettings > Apps > App permission > Phone - APPS_APP_PERMISSIONS_PHONE = 0x16280000; - - // TvSettings > Apps > App permission > Physical activity - APPS_APP_PERMISSIONS_PHYSICAL_ACTIVITY = 0x16290000; - - // TvSettings > Apps > App permission > SMS - APPS_APP_PERMISSIONS_SMS = 0x162A0000; - - // TvSettings > Apps > App permission > Storage - APPS_APP_PERMISSIONS_STORAGE = 0x162B0000; - - // TvSettings > Apps > App permission > Additional permissions - APPS_APP_PERMISSIONS_ADDITIONAL = 0x162C0000; - - // TvSettings > Apps > App permission > Additional permissions > - // real all TV listings - APPS_APP_PERMISSIONS_ADDITIONAL_READ_TV_LISTINGS = 0x162C1000; - - // TvSettings > Apps > App permission > Additional permissions > - // real instant messages - APPS_APP_PERMISSIONS_ADDITIONAL_READ_INSTANT_MESSAGES = 0x162C2000; - - // TvSettings > Apps > App permission > Additional permissions > - // write instant messages - APPS_APP_PERMISSIONS_ADDITIONAL_WRITE_INSTANT_MESSAGES = 0x162C3000; - - // TvSettings > Apps > Special app access - APPS_SPECIAL_APP_ACCESS = 0x16300000; - - // TvSettings > Apps > Special app access > Energy optimization - APPS_SPECIAL_APP_ACCESS_ENERGY_OPTIMIZATION = 0x16310000; - - // TvSettings > Apps > Special app access > Usage access - APPS_SPECIAL_APP_ACCESS_USAGE_ACCESS = 0x16320000; - - // TvSettings > Apps > Special app access > Notification access - APPS_SPECIAL_APP_ACCESS_NOTIFICATION_ACCESS = 0x16330000; - - // TvSettings > Apps > Special app access > Display over other apps - APPS_SPECIAL_APP_ACCESS_DISPLAY_OVER_OTHERS = 0x16340000; - - // TvSettings > Apps > Special app access > Modify system settings - APPS_SPECIAL_APP_ACCESS_MODIFY_SYSTEM_SETTINGS = 0x16350000; - - // TvSettings > Apps > Special app access > Picture-in-picture - APPS_SPECIAL_APP_ACCESS_PICTURE_IN_PICTURE = 0x16360000; - - // TvSettings > Apps > Security & restrictions - APPS_SECURITY_RESTRICTIONS = 0x16400000; - - // TvSettings > Apps > Security & restrictions > Unknown sources - APPS_SECURITY_RESTRICTIONS_UNKNOWN_SOURCES = 0x16410000; - - // TvSettings > Apps > Security & restrictions > Verify apps (toggle) - APPS_SECURITY_RESTRICTIONS_VERIFY_APPS = 0x16420000; - - // TvSettings > Apps > Security & restrictions > Create restricted profile - APPS_SECURITY_RESTRICTIONS_CREATE_PROFILE = 0x16430000; - - // TvSettings > Apps > Security & restrictions > Enter restricted profile - APPS_SECURITY_RESTRICTIONS_ENTER_PROFILE = 0x16440000; - - // TvSettings > Apps > Security & restrictions > - // Allowed apps (Restricted Profile) - APPS_SECURITY_RESTRICTIONS_PROFILE_ALLOWED_APPS = 0x16450000; - - // TvSettings > Apps > Security & restrictions > - // Change pin (Restricted Profile) - APPS_SECURITY_RESTRICTIONS_PROFILE_CHANGE_PIN = 0x16460000; - - // TvSettings > Apps > Security & restrictions > - // Delete restricted profile - APPS_SECURITY_RESTRICTIONS_DELETE_PROFILE = 0x16470000; - - // TvSettings > Apps > Security & restrictions > - // Exit restricted profile - APPS_SECURITY_RESTRICTIONS_EXIT_PROFILE = 0x16480000; - - // TvSettings > System (same as TvSettings > Device Preferences) - SYSTEM = 0x17000000; - - // TvSettings > System > About - SYSTEM_ABOUT = 0x17100000; - - // TvSettings > System > System update - SYSTEM_ABOUT_SYSTEM_UPDATE = 0x17110000; - - // TvSettings > System > Device name - SYSTEM_ABOUT_DEVICE_NAME = 0x17120000; - - // TvSettings > System > Factory reset - SYSTEM_ABOUT_FACTORY_RESET = 0x17130000; - - // TvSettings > System > Status - SYSTEM_ABOUT_STATUS = 0x17140000; - - // TvSettings > System > Legal information - SYSTEM_ABOUT_LEGAL_INFO = 0x17150000; - - // TvSettings > System > Legal information > Open source licenses - SYSTEM_ABOUT_LEGAL_INFO_OPEN_SOURCE = 0x17151000; - - // TvSettings > System > Legal information > Google legal - SYSTEM_ABOUT_LEGAL_INFO_GOOGLE_LEGAL = 0x17152000; - - // TvSettings > System > Legal information > System WebView licenses - SYSTEM_ABOUT_LEGAL_INFO_SYSTEM_WEBVIEW = 0x17153000; - - // TvSettings > System > Build - SYSTEM_ABOUT_BUILD = 0x17160000; - - // TvSettings > System > Date & time - SYSTEM_DATE_TIME = 0x17200000; - - // TvSettings > System > Date & time > Automatic data & time - SYSTEM_DATE_TIME_AUTOMATIC = 0x17210000; - - // TvSettings > System > Date & time > Automatic data & time > - // Use network-provided time - SYSTEM_DATE_TIME_AUTOMATIC_USE_NETWORK_TIME = 0x17211000; - - // TvSettings > System > Date & time > Automatic data & time > Off - SYSTEM_DATE_TIME_AUTOMATIC_OFF = 0x17212000; - - // TvSettings > System > Date & time > Set date - SYSTEM_DATE_TIME_SET_DATE = 0x17220000; - - // TvSettings > System > Date & time > Set time - SYSTEM_DATE_TIME_SET_TIME = 0x17230000; - - // TvSettings > System > Date & time > Set time zone - SYSTEM_DATE_TIME_SET_TIME_ZONE = 0x17240000; - - // TvSettings > System > Date & time > Set time zone > [A time zone button] - SYSTEM_DATE_TIME_SET_TIME_ZONE_BUTTON = 0x17241000; - - // TvSettings > System > Date & time > Use 24-hour format (toggle) - SYSTEM_DATE_TIME_USE_24_HOUR_FORMAT = 0x17250000; - - // TvSettings > System > Language - SYSTEM_LANGUAGE = 0x17300000; - - // TvSettings > System > Language > [A language button] - SYSTEM_LANGUAGE_BUTTON = 0x17310000; - - // TvSettings > System > Keyboard - SYSTEM_KEYBOARD = 0x17400000; - - // TvSettings > System > Keyboard > Current keyboard - SYSTEM_KEYBOARD_CURRENT_KEYBOARD = 0x17410000; - - // TvSettings > System > Keyboard > Gboard Settings - SYSTEM_KEYBOARD_GBOARD_SETTINGS = 0x17420000; - - // TvSettings > System > Keyboard > Gboard Settings > Languages - SYSTEM_KEYBOARD_GBOARD_SETTINGS_LANGUAGES = 0x17421000; - - // TvSettings > System > Keyboard > Gboard Settings > Terms of services - SYSTEM_KEYBOARD_GBOARD_SETTINGS_TOS = 0x17422000; - - // TvSettings > System > Keyboard > Gboard Settings > Privacy policy - SYSTEM_KEYBOARD_GBOARD_SETTINGS_PRIVACY_POLICY = 0x17423000; - - // TvSettings > System > Keyboard > Gboard Settings > Open source licenses - SYSTEM_KEYBOARD_GBOARD_SETTINGS_OPEN_SOURCE = 0x17424000; - - // TvSettings > System > Keyboard > Gboard Settings > - // Share usage statistics (toggle) - SYSTEM_KEYBOARD_GBOARD_SETTINGS_SHARE_USAGE_STATS = 0x17425000; - - // TvSettings > System > Keyboard > Manage keyboards - SYSTEM_KEYBOARD_MANAGE_KEYBOARDS = 0x17430000; - - // TvSettings > System > Storage - SYSTEM_STORAGE = 0x17500000; - - // TvSettings > System > Internal shared storage - SYSTEM_STORAGE_INTERNAL_STORAGE = 0x17510000; - - // TvSettings > System > Internal shared storage > Apps - SYSTEM_STORAGE_INTERNAL_STORAGE_APPS = 0x17511000; - - // TvSettings > System > Internal shared storage > - // Cached data (brings up "Clear cached data?" dialog upon click) - SYSTEM_STORAGE_INTERNAL_STORAGE_CACHED = 0x17512000; - - // TvSettings > System > Ambient mode - SYSTEM_AMBIENT = 0x17600000; - - // TvSettings > System > Ambient mode > Start now - SYSTEM_AMBIENT_START = 0x17610000; - - // TvSettings > System > Ambient mode > Settings - SYSTEM_AMBIENT_SETTINGS = 0x17620000; - - // TvSettings > System > Ambient mode > Settings > Google Photos (Channels) - SYSTEM_AMBIENT_SETTINGS_CHANNEL_GP = 0x17621000; - - // TvSettings > System > Ambient mode > Settings > Art gallery (Channels) - SYSTEM_AMBIENT_SETTINGS_CHANNEL_AG = 0x17622000; - - // TvSettings > System > Ambient mode > Settings > - // Cinematic videos (Channels) - SYSTEM_AMBIENT_SETTINGS_CHANNEL_CV = 0x17623000; - - // TvSettings > System > Ambient mode > Settings > Experimental (Channels) - SYSTEM_AMBIENT_SETTINGS_CHANNEL_EXP = 0x17624000; - - // TvSettings > System > Ambient mode > Settings > Weather - SYSTEM_AMBIENT_SETTINGS_WEATHER = 0x17625000; - - // TvSettings > System > Ambient mode > Settings > Weather > Hide - SYSTEM_AMBIENT_SETTINGS_WEATHER_HIDE = 0x17625100; - - // TvSettings > System > Ambient mode > Settings > Weather > Celsius (Unit) - SYSTEM_AMBIENT_SETTINGS_WEATHER_UNIT_C = 0x17625200; - - // TvSettings > System > Ambient mode > Settings > Weather > - // Fahrenheit (Unit) - SYSTEM_AMBIENT_SETTINGS_WEATHER_UNIT_F = 0x17625300; - - // TvSettings > System > Ambient mode > Settings > Weather > Both (Unit) - SYSTEM_AMBIENT_SETTINGS_WEATHER_UNIT_BOTH = 0x17625400; - - // TvSettings > System > Ambient mode > Settings > Time - SYSTEM_AMBIENT_SETTINGS_TIME = 0x17626000; - - // TvSettings > System > Ambient mode > Settings > Time > Hide - SYSTEM_AMBIENT_SETTINGS_TIME_HIDE = 0x17626100; - - // TvSettings > System > Ambient mode > Settings > Time > Show - SYSTEM_AMBIENT_SETTINGS_TIME_SHOW = 0x17626200; - - // TvSettings > System > Ambient mode > Settings > Device information - SYSTEM_AMBIENT_SETTINGS_DEVICE_INFO = 0x17627000; - - // TvSettings > System > Ambient mode > Settings > Device information > Hide - SYSTEM_AMBIENT_SETTINGS_DEVICE_INFO_HIDE = 0x17627100; - - // TvSettings > System > Ambient mode > Settings > Device information > Show - SYSTEM_AMBIENT_SETTINGS_DEVICE_INFO_SHOW = 0x17627200; - - // TvSettings > System > Ambient mode > Settings > Personal photo data - SYSTEM_AMBIENT_SETTINGS_PPD = 0x17628000; - - // TvSettings > System > Ambient mode > Settings > Personal photo data > - // Hide - SYSTEM_AMBIENT_SETTINGS_PPD_HIDE = 0x17628100; - - // TvSettings > System > Ambient mode > Settings > Personal photo data > - // Show - SYSTEM_AMBIENT_SETTINGS_PPD_SHOW = 0x17628200; - - // TvSettings > System > Ambient mode > Settings > Portrait Google Photos - SYSTEM_AMBIENT_SETTINGS_PGP = 0x17629000; - - // TvSettings > System > Ambient mode > Settings > Portrait Google Photos > - // Hide - SYSTEM_AMBIENT_SETTINGS_PGP_HIDE = 0x17629100; - - // TvSettings > System > Ambient mode > Settings > Portrait Google Photos > - // Show - SYSTEM_AMBIENT_SETTINGS_PGP_SHOW = 0x17629200; - - // TvSettings > System > Ambient mode > Settings > Portrait Google Photos > - // Show pairs - SYSTEM_AMBIENT_SETTINGS_PGP_SHOW_PAIRS = 0x17629300; - - // TvSettings > System > Ambient mode > Settings > Personal photo curation - SYSTEM_AMBIENT_SETTINGS_PPC = 0x1762A000; - - // TvSettings > System > Ambient mode > Settings > Personal photo curation > - // All albums - SYSTEM_AMBIENT_SETTINGS_PPC_ALL_ALBUMS = 0x1762A100; - - // TvSettings > System > Ambient mode > Settings > Personal photo curation > - // Live albums only - SYSTEM_AMBIENT_SETTINGS_PPC_LIVE_ALBUMS = 0x1762A200; - - // TvSettings > System > Ambient mode > Settings > Slideshow speed - SYSTEM_AMBIENT_SETTINGS_SLIDE_SPEED = 0x1762B000; - - // TvSettings > System > Ambient mode > Settings > Slideshow speed > 5s - SYSTEM_AMBIENT_SETTINGS_SLIDE_SPEED_5S = 0x1762B100; - - // TvSettings > System > Ambient mode > Settings > Slideshow speed > 10s - SYSTEM_AMBIENT_SETTINGS_SLIDE_SPEED_10S = 0x1762B200; - - // TvSettings > System > Ambient mode > Settings > Slideshow speed > 30s - SYSTEM_AMBIENT_SETTINGS_SLIDE_SPEED_30S = 0x1762B300; - - // TvSettings > System > Ambient mode > Settings > Slideshow speed > 1m - SYSTEM_AMBIENT_SETTINGS_SLIDE_SPEED_1M = 0x1762B400; - - // TvSettings > System > Ambient mode > Settings > Slideshow speed > 3m - SYSTEM_AMBIENT_SETTINGS_SLIDE_SPEED_3M = 0x1762B500; - - // TvSettings > System > Ambient mode > Settings > Slideshow speed > 5m - SYSTEM_AMBIENT_SETTINGS_SLIDE_SPEED_5M = 0x1762B600; - - // TvSettings > System > Ambient mode > Settings > Slideshow speed > 10m - SYSTEM_AMBIENT_SETTINGS_SLIDE_SPEED_10M = 0x1762B700; - - // TvSettings > System > Energy saver - SYSTEM_ENERGYSAVER = 0x17700000; - - // TvSettings > System > Energy saver > Turn off display after - SYSTEM_ENERGYSAVER_START_DELAY = 0x17710000; - - // TvSettings > System > Energy saver > Turn off display after > 15 minutes - SYSTEM_ENERGYSAVER_START_DELAY_15M = 0x17711000; - - // TvSettings > System > Energy saver > Turn off display after > 30 minutes - SYSTEM_ENERGYSAVER_START_DELAY_30M = 0x17712000; - - // TvSettings > System > Energy saver > Turn off display after > 1 hour - SYSTEM_ENERGYSAVER_START_DELAY_1H = 0x17713000; - - // TvSettings > System > Energy saver > Turn off display after > 3 hours - SYSTEM_ENERGYSAVER_START_DELAY_3H = 0x17714000; - - // TvSettings > System > Energy saver > Turn off display after > 6 hours - SYSTEM_ENERGYSAVER_START_DELAY_6H = 0x17715000; - - // TvSettings > System > Energy saver > Turn off display after > 12 hours - SYSTEM_ENERGYSAVER_START_DELAY_12H = 0x17716000; - - // TvSettings > System > Energy saver > Turn off display after > Never - SYSTEM_ENERGYSAVER_START_DELAY_NEVER = 0x17717000; - - // TvSettings > System > Accessibility - SYSTEM_A11Y = 0x17800000; - - // TvSettings > System > Accessibility > Captions - SYSTEM_A11Y_CAPTIONS = 0x17810000; - - // TvSettings > System > Accessibility > Captions > Display (toggle) - SYSTEM_A11Y_CAPTIONS_DISPLAY_ON_OFF = 0x17811000; - - // TvSettings > System > Accessibility > Captions > Language - SYSTEM_A11Y_CAPTIONS_LANGUAGE = 0x17812000; - - // TvSettings > System > Accessibility > Captions > Language > [A language] - SYSTEM_A11Y_CAPTIONS_LANGUAGE_BUTTON = 0x17812100; - - // TvSettings > System > Accessibility > Captions > Text size - SYSTEM_A11Y_CAPTIONS_TEXT_SIZE = 0x17813000; - - // TvSettings > System > Accessibility > Captions > Text size > Very small - SYSTEM_A11Y_CAPTIONS_TEXT_SIZE_VERY_SMALL = 0x17813100; - - // TvSettings > System > Accessibility > Captions > Text size > Small - SYSTEM_A11Y_CAPTIONS_TEXT_SIZE_SMALL = 0x17813200; - - // TvSettings > System > Accessibility > Captions > Text size > Normal - SYSTEM_A11Y_CAPTIONS_TEXT_SIZE_NORMAL = 0x17813300; - - // TvSettings > System > Accessibility > Captions > Text size > Large - SYSTEM_A11Y_CAPTIONS_TEXT_SIZE_LARGE = 0x17813400; - - // TvSettings > System > Accessibility > Captions > Text size > Very large - SYSTEM_A11Y_CAPTIONS_TEXT_SIZE_VERY_LARGE = 0x17813500; - - // TvSettings > System > Accessibility > Captions > - // White on black (radio button) - SYSTEM_A11Y_CAPTIONS_WHITE_ON_BLACK = 0x17814000; - - // TvSettings > System > Accessibility > Captions > - // Black on white (radio button) - SYSTEM_A11Y_CAPTIONS_BLACK_ON_WHITE = 0x17815000; - - // TvSettings > System > Accessibility > Captions > - // Yellow on black (radio button) - SYSTEM_A11Y_CAPTIONS_YELLOW_ON_BLACK = 0x17816000; - - // TvSettings > System > Accessibility > Captions > - // Yellow on blue (radio button) - SYSTEM_A11Y_CAPTIONS_YELLOW_ON_BLUE = 0x17817000; - - // TvSettings > System > Accessibility > Captions > Custom - SYSTEM_A11Y_CAPTIONS_CUSTOM = 0x17818000; - - // TvSettings > System > Accessibility > Captions > Custom > Font family - SYSTEM_A11Y_CAPTIONS_CUSTOM_FONT = 0x17818100; - - // TvSettings > System > Accessibility > Captions > Custom > Text color - SYSTEM_A11Y_CAPTIONS_CUSTOM_TEXT_COLOR = 0x17818200; - - // TvSettings > System > Accessibility > Captions > Custom > Text opacity - SYSTEM_A11Y_CAPTIONS_CUSTOM_TEXT_OPACITY = 0x17818300; - - // TvSettings > System > Accessibility > Captions > Custom > Edge type - SYSTEM_A11Y_CAPTIONS_CUSTOM_EDGE_TYPE = 0x17818400; - - // TvSettings > System > Accessibility > Captions > Custom > Edge color - SYSTEM_A11Y_CAPTIONS_CUSTOM_EDGE_COLOR = 0x17818500; - - // TvSettings > System > Accessibility > Captions > Custom > - // Show background (toggle) - SYSTEM_A11Y_CAPTIONS_SHOW_BACKGROUND = 0x17818600; - - // TvSettings > System > Accessibility > Captions > Custom > - // Background color - SYSTEM_A11Y_CAPTIONS_BACKGROUND_COLOR = 0x17818700; - - // TvSettings > System > Accessibility > Captions > Custom > - // Background opacity - SYSTEM_A11Y_CAPTIONS_BACKGROUND_OPACITY = 0x17818800; - - // TvSettings > System > Accessibility > Captions > Custom > - // Show window (toggle) - SYSTEM_A11Y_CAPTIONS_SHOW_WINDOW = 0x17818900; - - // TvSettings > System > Accessibility > Captions > Custom > Window color - SYSTEM_A11Y_CAPTIONS_WINDOW_COLOR = 0x17818A00; - - // TvSettings > System > Accessibility > Captions > Custom > Window opacity - SYSTEM_A11Y_CAPTIONS_WINDOW_OPACITY = 0x17818B00; - - // TvSettings > System > Accessibility > High contrast text (toggle) - SYSTEM_A11Y_HIGH_CONTRAST_TEXT = 0x17820000; - - // TvSettings > System > Accessibility > Text to speech - SYSTEM_A11Y_TTS = 0x17830000; - - // TvSettings > System > Accessibility > Text to speech > [Select an engine] - SYSTEM_A11Y_TTS_ENGINE_SELECT = 0x17831000; - - // TvSettings > System > Accessibility > Text to speech > - // Engine configuration - SYSTEM_A11Y_TTS_ENGINE_CONFIG = 0x17832000; - - // TvSettings > System > Accessibility > Text to speech > - // Engine configuration > Language - SYSTEM_A11Y_TTS_ENGINE_CONFIG_LANGUAGE = 0x17832100; - - // TvSettings > System > Accessibility > Text to speech > - // Engine configuration > Language > Button - SYSTEM_A11Y_TTS_ENGINE_CONFIG_LANGUAGE_CHOOSE_LANGUAGE = 0x17832110; - - // TvSettings > System > Accessibility > Text to speech > - // Engine configuration > Settings for Google Text-to-speech Engine - SYSTEM_A11Y_TTS_ENGINE_CONFIG_SETTINGS_GTTS_ENGINE = 0x17832200; - - // TvSettings > System > Accessibility > Text to speech > - // Engine configuration > Install voice data - SYSTEM_A11Y_TTS_ENGINE_CONFIG_INSTALL_VOICE_DATA = 0x17832300; - - // TvSettings > System > Accessibility > Text to speech > Speech rate - SYSTEM_A11Y_TTS_SPEECH_RATE = 0x17833000; - - // TvSettings > System > Accessibility > Text to speech > - // Listen to an example - SYSTEM_A11Y_TTS_LISTEN_EXAMPLE = 0x17834000; - - // TvSettings > System > Accessibility > Accessibility shortcut - SYSTEM_A11Y_SHORTCUT = 0x17840000; - - // TvSettings > System > Accessibility > Accessibility shortcut > - // Enable (toggle) - SYSTEM_A11Y_SHORTCUT_ON_OFF = 0x17841000; - - // TvSettings > System > Accessibility > Accessibility shortcut > - // Shortcut services - SYSTEM_A11Y_SHORTCUT_SERVICE = 0x17842000; - - // TvSettings > System > Accessibility > TalkBack - SYSTEM_A11Y_TALKBACK = 0x17850000; - - // TvSettings > System > Accessibility > TalkBack > Enable (toggle) - SYSTEM_A11Y_TALKBACK_ON_OFF = 0x17851000; - - // TvSettings > System > Accessibility > TalkBack > Configuration - SYSTEM_A11Y_TALKBACK_CONFIG = 0x17852000; - - // TvSettings > System > Accessibility > Accessibility Menu - SYSTEM_A11Y_A11Y_MENU = 0x17860000; - - // TvSettings > System > Accessibility > Accessibility Menu > - // Enable (toggle) - SYSTEM_A11Y_A11Y_MENU_ON_OFF = 0x17861000; - - // TvSettings > System > Accessibility > Accessibility Menu > Configuration - SYSTEM_A11Y_A11Y_MENU_CONFIG = 0x17862000; - - // TvSettings > System > Accessibility > Select to Speak - SYSTEM_A11Y_STS = 0x17870000; - - // TvSettings > System > Accessibility > Select to Speak > Enable (toggle) - SYSTEM_A11Y_STS_ON_OFF = 0x17871000; - - // TvSettings > System > Accessibility > Select to Speak > Configuration - SYSTEM_A11Y_STS_CONFIG = 0x17872000; - - // TvSettings > System > Accessibility > Switch Access - SYSTEM_A11Y_SWITCH_ACCESS = 0x17880000; - - // TvSettings > System > Accessibility > Switch Access > Enable (Toggle) - SYSTEM_A11Y_SWITCH_ACCESS_ON_OFF = 0x17881000; - - // TvSettings > System > Accessibility > Switch Access > Configuration - SYSTEM_A11Y_SWITCH_ACCESS_CONFIG = 0x17882000; - - // TvSettings > System > Reboot - SYSTEM_REBOOT = 0x17900000; - - // TvSettings > Device Preferences > Home screen (in classic TvSettings) - PREFERENCES_HOME_SCREEN = 0x17A00000; - - // TvSettings > Device Preferences > Home screen (in classic TvSettings) > - // Customize channels - PREFERENCES_HOME_SCREEN_CUSTOMIZE_CHANNELS = 0x17A10000; - - // TvSettings > Device Preferences > Home screen (in classic TvSettings) > - // Customize channels > Play Next - PREFERENCES_HOME_SCREEN_CUSTOMIZE_CHANNELS_PN = 0x17A11000; - - // TvSettings > Device Preferences > Home screen (in classic TvSettings) > - // Customize channels > Play Next > On (toggle) - PREFERENCES_HOME_SCREEN_CUSTOMIZE_CHANNELS_PN_ON_OFF = 0x17A11100; - - // TvSettings > Device Preferences > Home screen (in classic TvSettings) > - // Customize channels > Play Next > Google Play Movies & TV (toggle) - PREFERENCES_HOME_SCREEN_CUSTOMIZE_CHANNELS_PN_GPMT = 0x17A11200; - - // TvSettings > Device Preferences > Home screen (in classic TvSettings) > - // Customize channels > Play Next > Google Play Music (toggle) - PREFERENCES_HOME_SCREEN_CUSTOMIZE_CHANNELS_PN_GPM = 0x17A11300; - - // TvSettings > Device Preferences > Home screen (in classic TvSettings) > - // Customize channels > Play Next > Promotional channels (toggle) - PREFERENCES_HOME_SCREEN_CUSTOMIZE_CHANNELS_PN_PROMOTIONAL = 0x17A11400; - - // TvSettings > Device Preferences > Home screen (in classic TvSettings) > - // Customize channels > Home screen channels - PREFERENCES_HOME_SCREEN_CUSTOMIZE_CHANNELS_HOME_SCREEN = 0x17A12000; - - // TvSettings > Device Preferences > Home screen (in classic TvSettings) > - // Customize channels > Promotional channels - PREFERENCES_HOME_SCREEN_CUSTOMIZE_CHANNELS_PROMOTIONAL = 0x17A13000; - - // TvSettings > Device Preferences > Home screen (in classic TvSettings) > - // Enable video previews (toggle) - PREFERENCES_HOME_SCREEN_VIDEO_PREVIEWS = 0x17A20000; - - // TvSettings > Device Preferences > Home screen (in classic TvSettings) > - // Enable audio previews (toggle) - PREFERENCES_HOME_SCREEN_AUDIO_PREVIEWS = 0x17A30000; - - // TvSettings > Device Preferences > Home screen (in classic TvSettings) > - // Reorder apps - PREFERENCES_HOME_SCREEN_REORDER_APPS = 0x17A40000; - - // TvSettings > Device Preferences > Home screen (in classic TvSettings) > - // Reorder games - PREFERENCES_HOME_SCREEN_REORDER_GAMES = 0x17A50000; - - // TvSettings > Device Preferences > Home screen (in classic TvSettings) > - // Android TV Home open source licenses - PREFERENCES_HOME_SCREEN_ATVH_OPEN_SOURCE = 0x17A60000; - - // TvSettings > Device Preferences > Home screen (in classic TvSettings) > - // Android TV Core Services open source licenses - PREFERENCES_HOME_SCREEN_ATVCS_OPEN_SOURCE = 0x17A70000; - - // TvSettings > Device Preferences > Google Assistant - PREFERENCES_ASSISTANT = 0x17B00000; - - // TvSettings > Device Preferences > Google Assistant > Accounts - PREFERENCES_ASSISTANT_ACCOUNTS = 0x17B10000; - - // TvSettings > Device Preferences > Google Assistant > Accept permissions - PREFERENCES_ASSISTANT_ACCEPT_PERMISSIONS = 0x17B20000; - - // TvSettings > Device Preferences > Google Assistant > View permissions - PREFERENCES_ASSISTANT_VIEW_PERMISSIONS = 0x17B30000; - - // TvSettings > Device Preferences > Google Assistant > Searchable apps - // (aliasing ACCOUNT_SLICE_REG_ACCOUNT_ASSISTANT_SEARCHABLE_APPS) - PREFERENCES_ASSISTANT_SEARCHABLE_APPS = 0x12133000; - - // TvSettings > Device Preferences > Google Assistant > SafeSearch filter - // (aliasing ACCOUNT_SLICE_REG_ACCOUNT_ASSISTANT_SAFE_SEARCH) - PREFERENCES_ASSISTANT_SAFESEARCH_FILTER = 0x12131000; - - // TvSettings > Device Preferences > Google Assistant > - // Block offensive words - // (aliasing ACCOUNT_SLICE_REG_ACCOUNT_ASSISTANT_BLOCK_OFFENSIVE) - PREFERENCES_ASSISTANT_BLOCK_OFFENSIVE = 0x12132000; - - // TvSettings > Device Preferences > Google Assistant > Open source licenses - PREFERENCES_ASSISTANT_OPEN_SOURCE = 0x17B40000; - - // TvSettings > Device Preferences > Chromecast Android Shell - PREFERENCES_CHROMECAST_SHELL = 0x17C00000; - - // TvSettings > Device Preferences > Chromecast Android Shell > - // Open source licenses - PREFERENCES_CHROMECAST_SHELL_OPEN_SOURCE = 0x17C10000; - - // TvSettings > Device Preferences > Screen saver - PREFERENCES_SCREENSAVER = 0x17D00000; - - // TvSettings > Device Preferences > Screen saver > Screen saver (chooser) - PREFERENCES_SCREENSAVER_CHOOSER = 0x17D10000; - - // TvSettings > Device Preferences > Screen saver > Screen saver (chooser) > - // Turn screen off - PREFERENCES_SCREENSAVER_CHOOSER_SCREEN_OFF = 0x17D11000; - - // TvSettings > Device Preferences > Screen saver > Screen saver (chooser) > - // Backdrop - PREFERENCES_SCREENSAVER_CHOOSER_BACKDROP = 0x17D12000; - - // TvSettings > Device Preferences > Screen saver > Screen saver (chooser) > - // Colors - PREFERENCES_SCREENSAVER_CHOOSER_COLORS = 0x17D13000; - - // TvSettings > Device Preferences > Screen saver > When to start - PREFERENCES_SCREENSAVER_START_DELAY = 0x17D20000; - - // TvSettings > Device Preferences > Screen saver > When to start > - // 5 minutes - PREFERENCES_SCREENSAVER_START_DELAY_5M = 0x17D21000; - - // TvSettings > Device Preferences > Screen saver > When to start > - // 15 minutes - PREFERENCES_SCREENSAVER_START_DELAY_15M = 0x17D22000; - - // TvSettings > Device Preferences > Screen saver > When to start > - // 30 minutes - PREFERENCES_SCREENSAVER_START_DELAY_30M = 0x17D23000; - - // TvSettings > Device Preferences > Screen saver > When to start > - // 1 hour - PREFERENCES_SCREENSAVER_START_DELAY_1H = 0x17D24000; - - // TvSettings > Device Preferences > Screen saver > When to start > - // 2 hours - PREFERENCES_SCREENSAVER_START_DELAY_2H = 0x17D25000; - - // TvSettings > Device Preferences > Screen saver > Start now - PREFERENCES_SCREENSAVER_START_NOW = 0x17D30000; - - // TvSettings > Connected Devices (Slice) - CONNECTED_SLICE = 0x18000000; - - // TvSettings > Connected Devices (Slice) > Connect remote or headphones - CONNECTED_SLICE_CONNECT_NEW_DEVICES = 0x18100000; - - // TvSettings > Connected Devices (Slice) > [A connected device] - CONNECTED_SLICE_DEVICE_ENTRY = 0x18200000; - - // TvSettings > Connected Devices (Slice) > [A connected device] > - // Remote update - CONNECTED_SLICE_DEVICE_ENTRY_UPDATE = 0x18210000; - - // TvSettings > Connected Devices (Slice) > [A connected device] > Rename - CONNECTED_SLICE_DEVICE_ENTRY_RENAME = 0x18220000; - - // TvSettings > Connected Devices (Slice) > [A connected device] > Forget - CONNECTED_SLICE_DEVICE_ENTRY_FORGET = 0x18230000; - - // TvSettings > Connected Devices (Slice) > HDMI-CEC - CONNECTED_SLICE_HDMICEC = 0x18300000; - - // TvSettings > Connected Devices (Slice) > HDMI-CEC > Enable (toggle) - CONNECTED_SLICE_HDMICEC_ON_OFF = 0x18310000; - - // TvSettings > Connected Devices (aliasing CONNECTED_SLICE) - CONNECTED_CLASSIC = 0x18000000; - - // TvSettings > Connected Devices > Connect remote - // (aliasing CONNECTED_SLICE_CONNECT_NEW_DEVICES) - CONNECTED_CLASSIC_CONNECT_REMOTE = 0x18100000; - - // TvSettings > Connected Devices > [A connected device] - // (aliasing CONNECTED_SLICE_DEVICE_ENTRY) - CONNECTED_CLASSIC_DEVICE_ENTRY = 0x18200000; - - // TvSettings > Connected Devices > [A connected device] > Update - // (aliasing CONNECTED_SLICE_DEVICE_ENTRY_UPDATE) - CONNECTED_CLASSIC_DEVICE_ENTRY_UPDATE = 0x18210000; - - // TvSettings > Connected Devices > [A connected device] > Rename - // (aliasing CONNECTED_SLICE_DEVICE_ENTRY_RENAME) - CONNECTED_CLASSIC_DEVICE_ENTRY_RENAME = 0x18220000; - - // TvSettings > Connected Devices > [A connected device] > Forget - // (aliasing CONNECTED_SLICE_DEVICE_ENTRY_FORGET) - CONNECTED_CLASSIC_DEVICE_ENTRY_FORGET = 0x18230000; - - // TvSettings > Connected Devices > HDMI-CEC - // (aliasing CONNECTED_SLICE_HDMICEC) - CONNECTED_CLASSIC_HDMICEC = 0x18300000; - - // TvSettings > Connected Devices > HDMI-CEC > Enable (toggle) - // (aliasing CONNECTED_SLICE_HDMICEC_ON_OFF) - CONNECTED_CLASSIC_HDMICEC_ON_OFF = 0x18310000; - - // TvSettings > Help & Feedback - FEEDBACK = 0x19000000; - - // TvSettings > Help & Feedback > Send feedback - FEEDBACK_SEND = 0x19100000; -} diff --git a/core/proto/android/bluetooth/a2dp/enums.proto b/core/proto/android/bluetooth/a2dp/enums.proto deleted file mode 100644 index 5a025bdd6c10..000000000000 --- a/core/proto/android/bluetooth/a2dp/enums.proto +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -syntax = "proto2"; -package android.bluetooth.a2dp; - -option java_outer_classname = "BluetoothA2dpProtoEnums"; -option java_multiple_files = true; - -// A2dp playback state enum, defined from: -// frameworks/base/core/java/android/bluetooth/BluetoothA2dp.java -enum PlaybackStateEnum { - PLAYBACK_STATE_UNKNOWN = 0; - PLAYBACK_STATE_PLAYING = 10; - PLAYBACK_STATE_NOT_PLAYING = 11; -} - -enum AudioCodingModeEnum { - AUDIO_CODING_MODE_UNKNOWN = 0; - AUDIO_CODING_MODE_HARDWARE = 1; - AUDIO_CODING_MODE_SOFTWARE = 2; -} diff --git a/core/proto/android/bluetooth/enums.proto b/core/proto/android/bluetooth/enums.proto deleted file mode 100644 index dc60ededf965..000000000000 --- a/core/proto/android/bluetooth/enums.proto +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -syntax = "proto2"; -package android.bluetooth; - -option java_outer_classname = "BluetoothProtoEnums"; -option java_multiple_files = true; - -// Bluetooth connection states. -enum ConnectionStateEnum { - CONNECTION_STATE_DISCONNECTED = 0; - CONNECTION_STATE_CONNECTING = 1; - CONNECTION_STATE_CONNECTED = 2; - CONNECTION_STATE_DISCONNECTING = 3; -} - -// Bluetooth Adapter Enable and Disable Reasons -enum EnableDisableReasonEnum { - ENABLE_DISABLE_REASON_UNSPECIFIED = 0; - ENABLE_DISABLE_REASON_APPLICATION_REQUEST = 1; - ENABLE_DISABLE_REASON_AIRPLANE_MODE = 2; - ENABLE_DISABLE_REASON_DISALLOWED = 3; - ENABLE_DISABLE_REASON_RESTARTED = 4; - ENABLE_DISABLE_REASON_START_ERROR = 5; - ENABLE_DISABLE_REASON_SYSTEM_BOOT = 6; - ENABLE_DISABLE_REASON_CRASH = 7; - ENABLE_DISABLE_REASON_USER_SWITCH = 8; - ENABLE_DISABLE_REASON_RESTORE_USER_SETTING = 9; - ENABLE_DISABLE_REASON_FACTORY_RESET = 10; - ENABLE_DISABLE_REASON_INIT_FLAGS_CHANGED = 11; -} - -enum DirectionEnum { - DIRECTION_UNKNOWN = 0; - DIRECTION_OUTGOING = 1; - DIRECTION_INCOMING = 2; -} - -// First item is the default value, other values follow Bluetooth spec definition -enum LinkTypeEnum { - // Link type is at most 1 byte (0xFF), thus 0xFFF must not be a valid value - LINK_TYPE_UNKNOWN = 0xFFF; - LINK_TYPE_SCO = 0x00; - LINK_TYPE_ACL = 0x01; - LINK_TYPE_ESCO = 0x02; -} - -enum DeviceInfoSrcEnum { - DEVICE_INFO_SRC_UNKNOWN = 0; - // Within Android Bluetooth stack - DEVICE_INFO_INTERNAL = 1; - // Outside Android Bluetooth stack - DEVICE_INFO_EXTERNAL = 2; -} - -enum DeviceTypeEnum { - DEVICE_TYPE_UNKNOWN = 0; - DEVICE_TYPE_CLASSIC = 1; - DEVICE_TYPE_LE = 2; - DEVICE_TYPE_DUAL = 3; -} - -// Defined in frameworks/base/core/java/android/bluetooth/BluetoothDevice.java -enum TransportTypeEnum { - TRANSPORT_TYPE_AUTO = 0; - TRANSPORT_TYPE_BREDR = 1; - TRANSPORT_TYPE_LE = 2; -} - -// Bond state enum -// Defined in frameworks/base/core/java/android/bluetooth/BluetoothDevice.java -enum BondStateEnum { - BOND_STATE_UNKNOWN = 0; - BOND_STATE_NONE = 10; - BOND_STATE_BONDING = 11; - BOND_STATE_BONDED = 12; -} - -// Sub states within the bonding general state -enum BondSubStateEnum { - BOND_SUB_STATE_UNKNOWN = 0; - BOND_SUB_STATE_LOCAL_OOB_DATA_PROVIDED = 1; - BOND_SUB_STATE_LOCAL_PIN_REQUESTED = 2; - BOND_SUB_STATE_LOCAL_PIN_REPLIED = 3; - BOND_SUB_STATE_LOCAL_SSP_REQUESTED = 4; - BOND_SUB_STATE_LOCAL_SSP_REPLIED = 5; -} - -enum UnbondReasonEnum { - UNBOND_REASON_UNKNOWN = 0; - UNBOND_REASON_AUTH_FAILED = 1; - UNBOND_REASON_AUTH_REJECTED = 2; - UNBOND_REASON_AUTH_CANCELED = 3; - UNBOND_REASON_REMOTE_DEVICE_DOWN = 4; - UNBOND_REASON_DISCOVERY_IN_PROGRESS = 5; - UNBOND_REASON_AUTH_TIMEOUT = 6; - UNBOND_REASON_REPEATED_ATTEMPTS = 7; - UNBOND_REASON_REMOTE_AUTH_CANCELED = 8; - UNBOND_REASON_REMOVED = 9; -} - -enum SocketTypeEnum { - SOCKET_TYPE_UNKNOWN = 0; - SOCKET_TYPE_RFCOMM = 1; - SOCKET_TYPE_SCO = 2; - SOCKET_TYPE_L2CAP_BREDR = 3; - SOCKET_TYPE_L2CAP_LE = 4; -} - -enum SocketConnectionstateEnum { - SOCKET_CONNECTION_STATE_UNKNOWN = 0; - // Socket acts as a server waiting for connection - SOCKET_CONNECTION_STATE_LISTENING = 1; - // Socket acts as a client trying to connect - SOCKET_CONNECTION_STATE_CONNECTING = 2; - // Socket is connected - SOCKET_CONNECTION_STATE_CONNECTED = 3; - // Socket tries to disconnect from remote - SOCKET_CONNECTION_STATE_DISCONNECTING = 4; - // This socket is closed - SOCKET_CONNECTION_STATE_DISCONNECTED = 5; -} - -enum SocketRoleEnum { - SOCKET_ROLE_UNKNOWN = 0; - SOCKET_ROLE_LISTEN = 1; - SOCKET_ROLE_CONNECTION = 2; -} diff --git a/core/proto/android/bluetooth/hci/enums.proto b/core/proto/android/bluetooth/hci/enums.proto deleted file mode 100644 index ef894e548351..000000000000 --- a/core/proto/android/bluetooth/hci/enums.proto +++ /dev/null @@ -1,559 +0,0 @@ -/* - * Copyright 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -syntax = "proto2"; -package android.bluetooth.hci; - -option java_outer_classname = "BluetoothHciProtoEnums"; -option java_multiple_files = true; - -// HCI command opcodes (OCF+OGF) from Bluetooth 5.0 specification Vol 2, Part E, Section 7 -// Original definition: system/bt/stack/include/hcidefs.h -enum CommandEnum { - // Opcode is at most 2 bytes (0xFFFF), thus 0xFFFFF must not be a valid value - CMD_UNKNOWN = 0xFFFFF; - // Link control commands 0x0400 - CMD_INQUIRY = 0x0401; - CMD_INQUIRY_CANCEL = 0x0402; - CMD_PERIODIC_INQUIRY_MODE = 0x0403; - CMD_EXIT_PERIODIC_INQUIRY_MODE = 0x0404; - CMD_CREATE_CONNECTION = 0x0405; - CMD_DISCONNECT = 0x0406; - CMD_ADD_SCO_CONNECTION = 0x0407; // Deprecated since Bluetooth 1.2 - CMD_CREATE_CONNECTION_CANCEL = 0x0408; - CMD_ACCEPT_CONNECTION_REQUEST = 0x0409; - CMD_REJECT_CONNECTION_REQUEST = 0x040A; - CMD_LINK_KEY_REQUEST_REPLY = 0x040B; - CMD_LINK_KEY_REQUEST_NEG_REPLY = 0x040C; - CMD_PIN_CODE_REQUEST_REPLY = 0x040D; - CMD_PIN_CODE_REQUEST_NEG_REPLY = 0x040E; - CMD_CHANGE_CONN_PACKET_TYPE = 0x040F; - CMD_AUTHENTICATION_REQUESTED = 0x0411; - CMD_SET_CONN_ENCRYPTION = 0x0413; - CMD_CHANGE_CONN_LINK_KEY = 0x0415; - CMD_MASTER_LINK_KEY = 0x0417; - CMD_RMT_NAME_REQUEST = 0x0419; - CMD_RMT_NAME_REQUEST_CANCEL = 0x041A; - CMD_READ_RMT_FEATURES = 0x041B; - CMD_READ_RMT_EXT_FEATURES = 0x041C; - CMD_READ_RMT_VERSION_INFO = 0x041D; - CMD_READ_RMT_CLOCK_OFFSET = 0x041F; - CMD_READ_LMP_HANDLE = 0x0420; - CMD_SETUP_ESCO_CONNECTION = 0x0428; - CMD_ACCEPT_ESCO_CONNECTION = 0x0429; - CMD_REJECT_ESCO_CONNECTION = 0x042A; - CMD_IO_CAPABILITY_REQUEST_REPLY = 0x042B; - CMD_USER_CONF_REQUEST_REPLY = 0x042C; - CMD_USER_CONF_VALUE_NEG_REPLY = 0x042D; - CMD_USER_PASSKEY_REQ_REPLY = 0x042E; - CMD_USER_PASSKEY_REQ_NEG_REPLY = 0x042F; - CMD_REM_OOB_DATA_REQ_REPLY = 0x0430; - CMD_REM_OOB_DATA_REQ_NEG_REPLY = 0x0433; - CMD_IO_CAP_REQ_NEG_REPLY = 0x0434; - // BEGIN: AMP commands (not used in system/bt) - CMD_CREATE_PHYSICAL_LINK = 0x0435; - CMD_ACCEPT_PHYSICAL_LINK = 0x0436; - CMD_DISCONNECT_PHYSICAL_LINK = 0x0437; - CMD_CREATE_LOGICAL_LINK = 0x0438; - CMD_ACCEPT_LOGICAL_LINK = 0x0439; - CMD_DISCONNECT_LOGICAL_LINK = 0x043A; - CMD_LOGICAL_LINK_CANCEL = 0x043B; - CMD_FLOW_SPEC_MODIFY = 0x043C; - // END: AMP commands - CMD_ENH_SETUP_ESCO_CONNECTION = 0x043D; - CMD_ENH_ACCEPT_ESCO_CONNECTION = 0x043E; - CMD_TRUNCATED_PAGE = 0x043F; - CMD_TRUNCATED_PAGE_CANCEL = 0x0440; - CMD_SET_CLB = 0x0441; - CMD_RECEIVE_CLB = 0x0442; - CMD_START_SYNC_TRAIN = 0x0443; - CMD_RECEIVE_SYNC_TRAIN = 0x0444; - CMD_REM_OOB_EXTENDED_DATA_REQ_REPLY = 0x0445; // Not currently used in system/bt - // Link policy commands 0x0800 - CMD_HOLD_MODE = 0x0801; - CMD_SNIFF_MODE = 0x0803; - CMD_EXIT_SNIFF_MODE = 0x0804; - CMD_PARK_MODE = 0x0805; - CMD_EXIT_PARK_MODE = 0x0806; - CMD_QOS_SETUP = 0x0807; - CMD_ROLE_DISCOVERY = 0x0809; - CMD_SWITCH_ROLE = 0x080B; - CMD_READ_POLICY_SETTINGS = 0x080C; - CMD_WRITE_POLICY_SETTINGS = 0x080D; - CMD_READ_DEF_POLICY_SETTINGS = 0x080E; - CMD_WRITE_DEF_POLICY_SETTINGS = 0x080F; - CMD_FLOW_SPECIFICATION = 0x0810; - CMD_SNIFF_SUB_RATE = 0x0811; - // Host controller baseband commands 0x0C00 - CMD_SET_EVENT_MASK = 0x0C01; - CMD_RESET = 0x0C03; - CMD_SET_EVENT_FILTER = 0x0C05; - CMD_FLUSH = 0x0C08; - CMD_READ_PIN_TYPE = 0x0C09; - CMD_WRITE_PIN_TYPE = 0x0C0A; - CMD_CREATE_NEW_UNIT_KEY = 0x0C0B; - CMD_GET_MWS_TRANS_LAYER_CFG = 0x0C0C; // Deprecated (not used in spec) - CMD_READ_STORED_LINK_KEY = 0x0C0D; - CMD_WRITE_STORED_LINK_KEY = 0x0C11; - CMD_DELETE_STORED_LINK_KEY = 0x0C12; - CMD_CHANGE_LOCAL_NAME = 0x0C13; - CMD_READ_LOCAL_NAME = 0x0C14; - CMD_READ_CONN_ACCEPT_TOUT = 0x0C15; - CMD_WRITE_CONN_ACCEPT_TOUT = 0x0C16; - CMD_READ_PAGE_TOUT = 0x0C17; - CMD_WRITE_PAGE_TOUT = 0x0C18; - CMD_READ_SCAN_ENABLE = 0x0C19; - CMD_WRITE_SCAN_ENABLE = 0x0C1A; - CMD_READ_PAGESCAN_CFG = 0x0C1B; - CMD_WRITE_PAGESCAN_CFG = 0x0C1C; - CMD_READ_INQUIRYSCAN_CFG = 0x0C1D; - CMD_WRITE_INQUIRYSCAN_CFG = 0x0C1E; - CMD_READ_AUTHENTICATION_ENABLE = 0x0C1F; - CMD_WRITE_AUTHENTICATION_ENABLE = 0x0C20; - CMD_READ_ENCRYPTION_MODE = 0x0C21; // Deprecated - CMD_WRITE_ENCRYPTION_MODE = 0x0C22; // Deprecated - CMD_READ_CLASS_OF_DEVICE = 0x0C23; - CMD_WRITE_CLASS_OF_DEVICE = 0x0C24; - CMD_READ_VOICE_SETTINGS = 0x0C25; - CMD_WRITE_VOICE_SETTINGS = 0x0C26; - CMD_READ_AUTOMATIC_FLUSH_TIMEOUT = 0x0C27; - CMD_WRITE_AUTOMATIC_FLUSH_TIMEOUT = 0x0C28; - CMD_READ_NUM_BCAST_REXMITS = 0x0C29; - CMD_WRITE_NUM_BCAST_REXMITS = 0x0C2A; - CMD_READ_HOLD_MODE_ACTIVITY = 0x0C2B; - CMD_WRITE_HOLD_MODE_ACTIVITY = 0x0C2C; - CMD_READ_TRANSMIT_POWER_LEVEL = 0x0C2D; - CMD_READ_SCO_FLOW_CTRL_ENABLE = 0x0C2E; - CMD_WRITE_SCO_FLOW_CTRL_ENABLE = 0x0C2F; - CMD_SET_HC_TO_HOST_FLOW_CTRL = 0x0C31; - CMD_HOST_BUFFER_SIZE = 0x0C33; - CMD_HOST_NUM_PACKETS_DONE = 0x0C35; - CMD_READ_LINK_SUPER_TOUT = 0x0C36; - CMD_WRITE_LINK_SUPER_TOUT = 0x0C37; - CMD_READ_NUM_SUPPORTED_IAC = 0x0C38; - CMD_READ_CURRENT_IAC_LAP = 0x0C39; - CMD_WRITE_CURRENT_IAC_LAP = 0x0C3A; - CMD_READ_PAGESCAN_PERIOD_MODE = 0x0C3B; // Deprecated - CMD_WRITE_PAGESCAN_PERIOD_MODE = 0x0C3C; // Deprecated - CMD_READ_PAGESCAN_MODE = 0x0C3D; // Deprecated - CMD_WRITE_PAGESCAN_MODE = 0x0C3E; // Deprecated - CMD_SET_AFH_CHANNELS = 0x0C3F; - CMD_READ_INQSCAN_TYPE = 0x0C42; - CMD_WRITE_INQSCAN_TYPE = 0x0C43; - CMD_READ_INQUIRY_MODE = 0x0C44; - CMD_WRITE_INQUIRY_MODE = 0x0C45; - CMD_READ_PAGESCAN_TYPE = 0x0C46; - CMD_WRITE_PAGESCAN_TYPE = 0x0C47; - CMD_READ_AFH_ASSESSMENT_MODE = 0x0C48; - CMD_WRITE_AFH_ASSESSMENT_MODE = 0x0C49; - CMD_READ_EXT_INQ_RESPONSE = 0x0C51; - CMD_WRITE_EXT_INQ_RESPONSE = 0x0C52; - CMD_REFRESH_ENCRYPTION_KEY = 0x0C53; - CMD_READ_SIMPLE_PAIRING_MODE = 0x0C55; - CMD_WRITE_SIMPLE_PAIRING_MODE = 0x0C56; - CMD_READ_LOCAL_OOB_DATA = 0x0C57; - CMD_READ_INQ_TX_POWER_LEVEL = 0x0C58; - CMD_WRITE_INQ_TX_POWER_LEVEL = 0x0C59; - CMD_READ_ERRONEOUS_DATA_RPT = 0x0C5A; - CMD_WRITE_ERRONEOUS_DATA_RPT = 0x0C5B; - CMD_ENHANCED_FLUSH = 0x0C5F; - CMD_SEND_KEYPRESS_NOTIF = 0x0C60; - CMD_READ_LOGICAL_LINK_ACCEPT_TIMEOUT = 0x0C61; - CMD_WRITE_LOGICAL_LINK_ACCEPT_TIMEOUT = 0x0C62; - CMD_SET_EVENT_MASK_PAGE_2 = 0x0C63; - CMD_READ_LOCATION_DATA = 0x0C64; - CMD_WRITE_LOCATION_DATA = 0x0C65; - CMD_READ_FLOW_CONTROL_MODE = 0x0C66; - CMD_WRITE_FLOW_CONTROL_MODE = 0x0C67; - CMD_READ_ENHANCED_TX_PWR_LEVEL = 0x0C68; // Not currently used in system/bt - CMD_READ_BE_FLUSH_TOUT = 0x0C69; - CMD_WRITE_BE_FLUSH_TOUT = 0x0C6A; - CMD_SHORT_RANGE_MODE = 0x0C6B; - CMD_READ_BLE_HOST_SUPPORT = 0x0C6C; - CMD_WRITE_BLE_HOST_SUPPORT = 0x0C6D; - CMD_SET_MWS_CHANNEL_PARAMETERS = 0x0C6E; - CMD_SET_EXTERNAL_FRAME_CONFIGURATION = 0x0C6F; - CMD_SET_MWS_SIGNALING = 0x0C70; - CMD_SET_MWS_TRANSPORT_LAYER = 0x0C71; - CMD_SET_MWS_SCAN_FREQUENCY_TABLE = 0x0C72; - CMD_SET_MWS_PATTERN_CONFIGURATION = 0x0C73; - CMD_SET_RESERVED_LT_ADDR = 0x0C74; - CMD_DELETE_RESERVED_LT_ADDR = 0x0C75; - CMD_WRITE_CLB_DATA = 0x0C76; - CMD_READ_SYNC_TRAIN_PARAM = 0x0C77; - CMD_WRITE_SYNC_TRAIN_PARAM = 0x0C78; - CMD_READ_SECURE_CONNS_SUPPORT = 0x0C79; - CMD_WRITE_SECURE_CONNS_SUPPORT = 0x0C7A; - CMD_READ_AUTHED_PAYLOAD_TIMEOUT = 0x0C7B; // Not currently used in system/bt - CMD_WRITE_AUTHED_PAYLOAD_TIMEOUT = 0x0C7C; // Not currently used in system/bt - CMD_READ_LOCAL_OOB_EXTENDED_DATA = 0x0C7D; // Not currently used in system/bt - CMD_READ_EXTENDED_PAGE_TIMEOUT = 0x0C7E; // Not currently used in system/bt - CMD_WRITE_EXTENDED_PAGE_TIMEOUT = 0x0C7F; // Not currently used in system/bt - CMD_READ_EXTENDED_INQUIRY_LENGTH = 0x0C80; // Not currently used in system/bt - CMD_WRITE_EXTENDED_INQUIRY_LENGTH = 0x0C81; // Not currently used in system/bt - // Informational parameter commands 0x1000 - CMD_READ_LOCAL_VERSION_INFO = 0x1001; - CMD_READ_LOCAL_SUPPORTED_CMDS = 0x1002; - CMD_READ_LOCAL_FEATURES = 0x1003; - CMD_READ_LOCAL_EXT_FEATURES = 0x1004; - CMD_READ_BUFFER_SIZE = 0x1005; - CMD_READ_COUNTRY_CODE = 0x1007; // Deprecated - CMD_READ_BD_ADDR = 0x1009; - CMD_READ_DATA_BLOCK_SIZE = 0x100A; - CMD_READ_LOCAL_SUPPORTED_CODECS = 0x100B; - // Status parameter commands 0x1400 - CMD_READ_FAILED_CONTACT_COUNTER = 0x1401; - CMD_RESET_FAILED_CONTACT_COUNTER = 0x1402; - CMD_GET_LINK_QUALITY = 0x1403; - CMD_READ_RSSI = 0x1405; - CMD_READ_AFH_CH_MAP = 0x1406; - CMD_READ_CLOCK = 0x1407; - CMD_READ_ENCR_KEY_SIZE = 0x1408; - CMD_READ_LOCAL_AMP_INFO = 0x1409; - CMD_READ_LOCAL_AMP_ASSOC = 0x140A; - CMD_WRITE_REMOTE_AMP_ASSOC = 0x140B; - CMD_GET_MWS_TRANSPORT_CFG = 0x140C; // Not currently used in system/bt - CMD_SET_TRIGGERED_CLK_CAPTURE = 0x140D; // Not currently used in system/bt - // Testing commands 0x1800 - CMD_READ_LOOPBACK_MODE = 0x1801; - CMD_WRITE_LOOPBACK_MODE = 0x1802; - CMD_ENABLE_DEV_UNDER_TEST_MODE = 0x1803; - CMD_WRITE_SIMP_PAIR_DEBUG_MODE = 0x1804; - CMD_ENABLE_AMP_RCVR_REPORTS = 0x1807; - CMD_AMP_TEST_END = 0x1808; - CMD_AMP_TEST = 0x1809; - CMD_WRITE_SECURE_CONN_TEST_MODE = 0x180A; // Not currently used in system/bt - // BLE commands 0x2000 - CMD_BLE_SET_EVENT_MASK = 0x2001; - CMD_BLE_READ_BUFFER_SIZE = 0x2002; - CMD_BLE_READ_LOCAL_SPT_FEAT = 0x2003; - CMD_BLE_WRITE_LOCAL_SPT_FEAT = 0x2004; - CMD_BLE_WRITE_RANDOM_ADDR = 0x2005; - CMD_BLE_WRITE_ADV_PARAMS = 0x2006; - CMD_BLE_READ_ADV_CHNL_TX_POWER = 0x2007; - CMD_BLE_WRITE_ADV_DATA = 0x2008; - CMD_BLE_WRITE_SCAN_RSP_DATA = 0x2009; - CMD_BLE_WRITE_ADV_ENABLE = 0x200A; - CMD_BLE_WRITE_SCAN_PARAMS = 0x200B; - CMD_BLE_WRITE_SCAN_ENABLE = 0x200C; - CMD_BLE_CREATE_LL_CONN = 0x200D; - CMD_BLE_CREATE_CONN_CANCEL = 0x200E; - CMD_BLE_READ_WHITE_LIST_SIZE = 0x200F; - CMD_BLE_CLEAR_WHITE_LIST = 0x2010; - CMD_BLE_ADD_WHITE_LIST = 0x2011; - CMD_BLE_REMOVE_WHITE_LIST = 0x2012; - CMD_BLE_UPD_LL_CONN_PARAMS = 0x2013; - CMD_BLE_SET_HOST_CHNL_CLASS = 0x2014; - CMD_BLE_READ_CHNL_MAP = 0x2015; - CMD_BLE_READ_REMOTE_FEAT = 0x2016; - CMD_BLE_ENCRYPT = 0x2017; - CMD_BLE_RAND = 0x2018; - CMD_BLE_START_ENC = 0x2019; - CMD_BLE_LTK_REQ_REPLY = 0x201A; - CMD_BLE_LTK_REQ_NEG_REPLY = 0x201B; - CMD_BLE_READ_SUPPORTED_STATES = 0x201C; - CMD_BLE_RECEIVER_TEST = 0x201D; - CMD_BLE_TRANSMITTER_TEST = 0x201E; - CMD_BLE_TEST_END = 0x201F; - CMD_BLE_RC_PARAM_REQ_REPLY = 0x2020; - CMD_BLE_RC_PARAM_REQ_NEG_REPLY = 0x2021; - CMD_BLE_SET_DATA_LENGTH = 0x2022; - CMD_BLE_READ_DEFAULT_DATA_LENGTH = 0x2023; - CMD_BLE_WRITE_DEFAULT_DATA_LENGTH = 0x2024; - CMD_BLE_GENERATE_DHKEY = 0x2026; // Not currently used in system/bt - CMD_BLE_ADD_DEV_RESOLVING_LIST = 0x2027; - CMD_BLE_RM_DEV_RESOLVING_LIST = 0x2028; - CMD_BLE_CLEAR_RESOLVING_LIST = 0x2029; - CMD_BLE_READ_RESOLVING_LIST_SIZE = 0x202A; - CMD_BLE_READ_RESOLVABLE_ADDR_PEER = 0x202B; - CMD_BLE_READ_RESOLVABLE_ADDR_LOCAL = 0x202C; - CMD_BLE_SET_ADDR_RESOLUTION_ENABLE = 0x202D; - CMD_BLE_SET_RAND_PRIV_ADDR_TIMOUT = 0x202E; - CMD_BLE_READ_MAXIMUM_DATA_LENGTH = 0x202F; - CMD_BLE_READ_PHY = 0x2030; - CMD_BLE_SET_DEFAULT_PHY = 0x2031; - CMD_BLE_SET_PHY = 0x2032; - CMD_BLE_ENH_RECEIVER_TEST = 0x2033; - CMD_BLE_ENH_TRANSMITTER_TEST = 0x2034; - CMD_BLE_SET_EXT_ADVERTISING_RANDOM_ADDRESS = 0x2035; - CMD_BLE_SET_EXT_ADVERTISING_PARAM = 0x2036; - CMD_BLE_SET_EXT_ADVERTISING_DATA = 0x2037; - CMD_BLE_SET_EXT_ADVERTISING_SCAN_RESP = 0x2038; - CMD_BLE_SET_EXT_ADVERTISING_ENABLE = 0x2039; - CMD_BLE_READ_MAXIMUM_ADVERTISING_DATA_LENGTH = 0x203A; - CMD_BLE_READ_NUMBER_OF_SUPPORTED_ADVERTISING_SETS = 0x203B; - CMD_BLE_REMOVE_ADVERTISING_SET = 0x203C; - CMD_BLE_CLEAR_ADVERTISING_SETS = 0x203D; - CMD_BLE_SET_PERIODIC_ADVERTISING_PARAM = 0x203E; - CMD_BLE_SET_PERIODIC_ADVERTISING_DATA = 0x203F; - CMD_BLE_SET_PERIODIC_ADVERTISING_ENABLE = 0x2040; - CMD_BLE_SET_EXTENDED_SCAN_PARAMETERS = 0x2041; - CMD_BLE_SET_EXTENDED_SCAN_ENABLE = 0x2042; - CMD_BLE_EXTENDED_CREATE_CONNECTION = 0x2043; - CMD_BLE_PERIODIC_ADVERTISING_CREATE_SYNC = 0x2044; - CMD_BLE_PERIODIC_ADVERTISING_CREATE_SYNC_CANCEL = 0x2045; - CMD_BLE_PERIODIC_ADVERTISING_TERMINATE_SYNC = 0x2046; - CMD_BLE_ADD_DEVICE_TO_PERIODIC_ADVERTISING_LIST = 0x2047; - CMD_BLE_RM_DEVICE_FROM_PERIODIC_ADVERTISING_LIST = 0x2048; - CMD_BLE_CLEAR_PERIODIC_ADVERTISING_LIST = 0x2049; - CMD_BLE_READ_PERIODIC_ADVERTISING_LIST_SIZE = 0x204A; - CMD_BLE_READ_TRANSMIT_POWER = 0x204B; - CMD_BLE_READ_RF_COMPENS_POWER = 0x204C; - CMD_BLE_WRITE_RF_COMPENS_POWER = 0x204D; - CMD_BLE_SET_PRIVACY_MODE = 0x204E; - // Vendor specific commands 0xFC00 and above - // Android vendor specific commands defined in - // https://source.android.com/devices/bluetooth/hci_requirements#vendor-specific-capabilities - CMD_BLE_VENDOR_CAP = 0xFD53; - CMD_BLE_MULTI_ADV = 0xFD54; - CMD_BLE_BATCH_SCAN = 0xFD56; - CMD_BLE_ADV_FILTER = 0xFD57; - CMD_BLE_TRACK_ADV = 0xFD58; - CMD_BLE_ENERGY_INFO = 0xFD59; - CMD_BLE_EXTENDED_SCAN_PARAMS = 0xFD5A; - CMD_CONTROLLER_DEBUG_INFO = 0xFD5B; - CMD_CONTROLLER_A2DP_OPCODE = 0xFD5D; - CMD_BRCM_SET_ACL_PRIORITY = 0xFC57; - // Other vendor specific commands below here -} - -// HCI event codes from the Bluetooth 5.0 specification Vol 2, Part 7, Section 7 -// Original definition: system/bt/stack/include/hcidefs.h -enum EventEnum { - // Event is at most 1 byte (0xFF), thus 0xFFF must not be a valid value - EVT_UNKNOWN = 0xFFF; - EVT_INQUIRY_COMP = 0x01; - EVT_INQUIRY_RESULT = 0x02; - EVT_CONNECTION_COMP = 0x03; - EVT_CONNECTION_REQUEST = 0x04; - EVT_DISCONNECTION_COMP = 0x05; - EVT_AUTHENTICATION_COMP = 0x06; - EVT_RMT_NAME_REQUEST_COMP = 0x07; - EVT_ENCRYPTION_CHANGE = 0x08; - EVT_CHANGE_CONN_LINK_KEY = 0x09; - EVT_MASTER_LINK_KEY_COMP = 0x0A; - EVT_READ_RMT_FEATURES_COMP = 0x0B; - EVT_READ_RMT_VERSION_COMP = 0x0C; - EVT_QOS_SETUP_COMP = 0x0D; - EVT_COMMAND_COMPLETE = 0x0E; - EVT_COMMAND_STATUS = 0x0F; - EVT_HARDWARE_ERROR = 0x10; - EVT_FLUSH_OCCURRED = 0x11; - EVT_ROLE_CHANGE = 0x12; - EVT_NUM_COMPL_DATA_PKTS = 0x13; - EVT_MODE_CHANGE = 0x14; - EVT_RETURN_LINK_KEYS = 0x15; - EVT_PIN_CODE_REQUEST = 0x16; - EVT_LINK_KEY_REQUEST = 0x17; - EVT_LINK_KEY_NOTIFICATION = 0x18; - EVT_LOOPBACK_COMMAND = 0x19; - EVT_DATA_BUF_OVERFLOW = 0x1A; - EVT_MAX_SLOTS_CHANGED = 0x1B; - EVT_READ_CLOCK_OFF_COMP = 0x1C; - EVT_CONN_PKT_TYPE_CHANGE = 0x1D; - EVT_QOS_VIOLATION = 0x1E; - EVT_PAGE_SCAN_MODE_CHANGE = 0x1F; // Deprecated - EVT_PAGE_SCAN_REP_MODE_CHNG = 0x20; - EVT_FLOW_SPECIFICATION_COMP = 0x21; - EVT_INQUIRY_RSSI_RESULT = 0x22; - EVT_READ_RMT_EXT_FEATURES_COMP = 0x23; - EVT_ESCO_CONNECTION_COMP = 0x2C; - EVT_ESCO_CONNECTION_CHANGED = 0x2D; - EVT_SNIFF_SUB_RATE = 0x2E; - EVT_EXTENDED_INQUIRY_RESULT = 0x2F; - EVT_ENCRYPTION_KEY_REFRESH_COMP = 0x30; - EVT_IO_CAPABILITY_REQUEST = 0x31; - EVT_IO_CAPABILITY_RESPONSE = 0x32; - EVT_USER_CONFIRMATION_REQUEST = 0x33; - EVT_USER_PASSKEY_REQUEST = 0x34; - EVT_REMOTE_OOB_DATA_REQUEST = 0x35; - EVT_SIMPLE_PAIRING_COMPLETE = 0x36; - EVT_LINK_SUPER_TOUT_CHANGED = 0x38; - EVT_ENHANCED_FLUSH_COMPLETE = 0x39; - EVT_USER_PASSKEY_NOTIFY = 0x3B; - EVT_KEYPRESS_NOTIFY = 0x3C; - EVT_RMT_HOST_SUP_FEAT_NOTIFY = 0x3D; - EVT_BLE_META = 0x3E; - EVT_PHYSICAL_LINK_COMP = 0x40; - EVT_CHANNEL_SELECTED = 0x41; - EVT_DISC_PHYSICAL_LINK_COMP = 0x42; - EVT_PHY_LINK_LOSS_EARLY_WARNING = 0x43; - EVT_PHY_LINK_RECOVERY = 0x44; - EVT_LOGICAL_LINK_COMP = 0x45; - EVT_DISC_LOGICAL_LINK_COMP = 0x46; - EVT_FLOW_SPEC_MODIFY_COMP = 0x47; - EVT_NUM_COMPL_DATA_BLOCKS = 0x48; - EVT_AMP_TEST_START = 0x49; // Not currently used in system/bt - EVT_AMP_TEST_END = 0x4A; // Not currently used in system/bt - EVT_AMP_RECEIVER_RPT = 0x4B; // Not currently used in system/bt - EVT_SHORT_RANGE_MODE_COMPLETE = 0x4C; - EVT_AMP_STATUS_CHANGE = 0x4D; - EVT_SET_TRIGGERED_CLOCK_CAPTURE = 0x4E; - EVT_SYNC_TRAIN_CMPL = 0x4F; // Not currently used in system/bt - EVT_SYNC_TRAIN_RCVD = 0x50; // Not currently used in system/bt - EVT_CONNLESS_SLAVE_BROADCAST_RCVD = 0x51; // Not currently used in system/bt - EVT_CONNLESS_SLAVE_BROADCAST_TIMEOUT = 0x52; // Not currently used in system/bt - EVT_TRUNCATED_PAGE_CMPL = 0x53; // Not currently used in system/bt - EVT_SLAVE_PAGE_RES_TIMEOUT = 0x54; // Not currently used in system/bt - EVT_CONNLESS_SLAVE_BROADCAST_CHNL_MAP_CHANGE = 0x55; // Not currently used in system/bt - EVT_INQUIRY_RES_NOTIFICATION = 0x56; // Not currently used in system/bt - EVT_AUTHED_PAYLOAD_TIMEOUT = 0x57; // Not currently used in system/bt - EVT_SAM_STATUS_CHANGE = 0x58; // Not currently used in system/bt -} - -// Bluetooth low energy related meta event codes -// from the Bluetooth 5.0 specification Vol 2, Part E, Section 7.7.65 -// Original definition: system/bt/stack/include/hcidefs.h -enum BleMetaEventEnum { - // BLE meta event code is at most 1 byte (0xFF), thus 0xFFF must not be a valid value - BLE_EVT_UNKNOWN = 0xFFF; - BLE_EVT_CONN_COMPLETE_EVT = 0x01; - BLE_EVT_ADV_PKT_RPT_EVT = 0x02; - BLE_EVT_LL_CONN_PARAM_UPD_EVT = 0x03; - BLE_EVT_READ_REMOTE_FEAT_CMPL_EVT = 0x04; - BLE_EVT_LTK_REQ_EVT = 0x05; - BLE_EVT_RC_PARAM_REQ_EVT = 0x06; - BLE_EVT_DATA_LENGTH_CHANGE_EVT = 0x07; - BLE_EVT_READ_LOCAL_P256_PUB_KEY = 0x08; // Not currently used in system/bt - BLE_EVT_GEN_DHKEY_CMPL = 0x09; // Not currently used in system/bt - BLE_EVT_ENHANCED_CONN_COMPLETE_EVT = 0x0a; - BLE_EVT_DIRECT_ADV_EVT = 0x0b; - BLE_EVT_PHY_UPDATE_COMPLETE_EVT = 0x0c; - BLE_EVT_EXTENDED_ADVERTISING_REPORT_EVT = 0x0D; - BLE_EVT_PERIODIC_ADV_SYNC_EST_EVT = 0x0E; - BLE_EVT_PERIODIC_ADV_REPORT_EVT = 0x0F; - BLE_EVT_PERIODIC_ADV_SYNC_LOST_EVT = 0x10; - BLE_EVT_SCAN_TIMEOUT_EVT = 0x11; - BLE_EVT_ADVERTISING_SET_TERMINATED_EVT = 0x12; - BLE_EVT_SCAN_REQ_RX_EVT = 0x13; - BLE_EVT_CHNL_SELECTION_ALGORITHM = 0x14; // Not currently used in system/bt -} - -// HCI status code from the Bluetooth 5.0 specification Vol 2, Part D. -// Original definition: system/bt/stack/include/hcidefs.h -enum StatusEnum { - // Status is at most 1 byte (0xFF), thus 0xFFF must not be a valid value - STATUS_UNKNOWN = 0xFFF; - STATUS_SUCCESS = 0x00; - STATUS_ILLEGAL_COMMAND = 0x01; - STATUS_NO_CONNECTION = 0x02; - STATUS_HW_FAILURE = 0x03; - STATUS_PAGE_TIMEOUT = 0x04; - STATUS_AUTH_FAILURE = 0x05; - STATUS_KEY_MISSING = 0x06; - STATUS_MEMORY_FULL = 0x07; - STATUS_CONNECTION_TOUT = 0x08; - STATUS_MAX_NUM_OF_CONNECTIONS = 0x09; - STATUS_MAX_NUM_OF_SCOS = 0x0A; - STATUS_CONNECTION_EXISTS = 0x0B; - STATUS_COMMAND_DISALLOWED = 0x0C; - STATUS_HOST_REJECT_RESOURCES = 0x0D; - STATUS_HOST_REJECT_SECURITY = 0x0E; - STATUS_HOST_REJECT_DEVICE = 0x0F; - STATUS_HOST_TIMEOUT = 0x10; - STATUS_UNSUPPORTED_VALUE = 0x11; - STATUS_ILLEGAL_PARAMETER_FMT = 0x12; - STATUS_PEER_USER = 0x13; - STATUS_PEER_LOW_RESOURCES = 0x14; - STATUS_PEER_POWER_OFF = 0x15; - STATUS_CONN_CAUSE_LOCAL_HOST = 0x16; - STATUS_REPEATED_ATTEMPTS = 0x17; - STATUS_PAIRING_NOT_ALLOWED = 0x18; - STATUS_UNKNOWN_LMP_PDU = 0x19; - STATUS_UNSUPPORTED_REM_FEATURE = 0x1A; - STATUS_SCO_OFFSET_REJECTED = 0x1B; - STATUS_SCO_INTERVAL_REJECTED = 0x1C; - STATUS_SCO_AIR_MODE = 0x1D; - STATUS_INVALID_LMP_PARAM = 0x1E; - STATUS_UNSPECIFIED = 0x1F; - STATUS_UNSUPPORTED_LMP_FEATURE = 0x20; - STATUS_ROLE_CHANGE_NOT_ALLOWED = 0x21; - STATUS_LMP_RESPONSE_TIMEOUT = 0x22; - STATUS_LMP_STATUS_TRANS_COLLISION = 0x23; - STATUS_LMP_PDU_NOT_ALLOWED = 0x24; - STATUS_ENCRY_MODE_NOT_ACCEPTABLE = 0x25; - STATUS_UNIT_KEY_USED = 0x26; - STATUS_QOS_NOT_SUPPORTED = 0x27; - STATUS_INSTANT_PASSED = 0x28; - STATUS_PAIRING_WITH_UNIT_KEY_NOT_SUPPORTED = 0x29; - STATUS_DIFF_TRANSACTION_COLLISION = 0x2A; - STATUS_UNDEFINED_0x2B = 0x2B; // Not used - STATUS_QOS_UNACCEPTABLE_PARAM = 0x2C; - STATUS_QOS_REJECTED = 0x2D; - STATUS_CHAN_CLASSIF_NOT_SUPPORTED = 0x2E; - STATUS_INSUFFCIENT_SECURITY = 0x2F; - STATUS_PARAM_OUT_OF_RANGE = 0x30; - STATUS_UNDEFINED_0x31 = 0x31; // Not used - STATUS_ROLE_SWITCH_PENDING = 0x32; - STATUS_UNDEFINED_0x33 = 0x33; - STATUS_RESERVED_SLOT_VIOLATION = 0x34; - STATUS_ROLE_SWITCH_FAILED = 0x35; - STATUS_INQ_RSP_DATA_TOO_LARGE = 0x36; - STATUS_SIMPLE_PAIRING_NOT_SUPPORTED = 0x37; - STATUS_HOST_BUSY_PAIRING = 0x38; - STATUS_REJ_NO_SUITABLE_CHANNEL = 0x39; - STATUS_CONTROLLER_BUSY = 0x3A; - STATUS_UNACCEPT_CONN_INTERVAL = 0x3B; - STATUS_ADVERTISING_TIMEOUT = 0x3C; - STATUS_CONN_TOUT_DUE_TO_MIC_FAILURE = 0x3D; - STATUS_CONN_FAILED_ESTABLISHMENT = 0x3E; - STATUS_MAC_CONNECTION_FAILED = 0x3F; - STATUS_LT_ADDR_ALREADY_IN_USE = 0x40; - STATUS_LT_ADDR_NOT_ALLOCATED = 0x41; - STATUS_CLB_NOT_ENABLED = 0x42; - STATUS_CLB_DATA_TOO_BIG = 0x43; - STATUS_OPERATION_CANCELED_BY_HOST = 0x44; // Not currently used in system/bt -} - -enum BqrIdEnum { - BQR_ID_UNKNOWN = 0x00; - BQR_ID_MONITOR_MODE = 0x01; - BQR_ID_APPROACH_LSTO = 0x02; - BQR_ID_A2DP_AUDIO_CHOPPY = 0x03; - BQR_ID_SCO_VOICE_CHOPPY = 0x04; -} - -enum BqrPacketTypeEnum { - BQR_PACKET_TYPE_UNKNOWN = 0x00; - BQR_PACKET_TYPE_ID = 0x01; - BQR_PACKET_TYPE_NULL = 0x02; - BQR_PACKET_TYPE_POLL = 0x03; - BQR_PACKET_TYPE_FHS = 0x04; - BQR_PACKET_TYPE_HV1 = 0x05; - BQR_PACKET_TYPE_HV2 = 0x06; - BQR_PACKET_TYPE_HV3 = 0x07; - BQR_PACKET_TYPE_DV = 0x08; - BQR_PACKET_TYPE_EV3 = 0x09; - BQR_PACKET_TYPE_EV4 = 0x0A; - BQR_PACKET_TYPE_EV5 = 0x0B; - BQR_PACKET_TYPE_2EV3 = 0x0C; - BQR_PACKET_TYPE_2EV5 = 0x0D; - BQR_PACKET_TYPE_3EV3 = 0x0E; - BQR_PACKET_TYPE_3EV5 = 0x0F; - BQR_PACKET_TYPE_DM1 = 0x10; - BQR_PACKET_TYPE_DH1 = 0x11; - BQR_PACKET_TYPE_DM3 = 0x12; - BQR_PACKET_TYPE_DH3 = 0x13; - BQR_PACKET_TYPE_DM5 = 0x14; - BQR_PACKET_TYPE_DH5 = 0x15; - BQR_PACKET_TYPE_AUX1 = 0x16; - BQR_PACKET_TYPE_2DH1 = 0x17; - BQR_PACKET_TYPE_2DH3 = 0x18; - BQR_PACKET_TYPE_2DH5 = 0x19; - BQR_PACKET_TYPE_3DH1 = 0x1A; - BQR_PACKET_TYPE_3DH3 = 0x1B; - BQR_PACKET_TYPE_3DH5 = 0x1C; -} diff --git a/core/proto/android/bluetooth/smp/enums.proto b/core/proto/android/bluetooth/smp/enums.proto deleted file mode 100644 index c6747b78dc29..000000000000 --- a/core/proto/android/bluetooth/smp/enums.proto +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 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. - */ - -syntax = "proto2"; -package android.bluetooth.smp; - -option java_outer_classname = "BluetoothSmpProtoEnums"; -option java_multiple_files = true; - -// SMP Pairing command codes -enum CommandEnum { - CMD_UNKNOWN = 0x00; - CMD_PAIRING_REQUEST = 0x01; - CMD_PAIRING_RESPONSE = 0x02; - CMD_PAIRING_CONFIRM = 0x03; - CMD_PAIRING_RANDOM = 0x04; - CMD_PAIRING_FAILED = 0x05; - CMD_ENCRYPTION_INFON = 0x06; - CMD_MASTER_IDENTIFICATION = 0x07; - CMD_IDENTITY_INFO = 0x08; - CMD_IDENTITY_ADDR_INFO = 0x09; - CMD_SIGNING_INFO = 0x0A; - CMD_SECURITY_REQUEST = 0x0B; - CMD_PAIRING_PUBLIC_KEY = 0x0C; - CMD_PAIRING_DHKEY_CHECK = 0x0D; - CMD_PAIRING_KEYPRESS_INFO = 0x0E; -} - -enum PairingFailReasonEnum { - PAIRING_FAIL_REASON_RESERVED = 0x00; - PAIRING_FAIL_REASON_PASSKEY_ENTRY = 0x01; - PAIRING_FAIL_REASON_OOB = 0x02; - PAIRING_FAIL_REASON_AUTH_REQ = 0x03; - PAIRING_FAIL_REASON_CONFIRM_VALUE = 0x04; - PAIRING_FAIL_REASON_PAIR_NOT_SUPPORT = 0x05; - PAIRING_FAIL_REASON_ENC_KEY_SIZE = 0x06; - PAIRING_FAIL_REASON_INVALID_CMD = 0x07; - PAIRING_FAIL_REASON_UNSPECIFIED = 0x08; - PAIRING_FAIL_REASON_REPEATED_ATTEMPTS = 0x09; - PAIRING_FAIL_REASON_INVALID_PARAMETERS = 0x0A; - PAIRING_FAIL_REASON_DHKEY_CHK = 0x0B; - PAIRING_FAIL_REASON_NUMERIC_COMPARISON = 0x0C; - PAIRING_FAIL_REASON_CLASSIC_PAIRING_IN_PROGR = 0x0D; - PAIRING_FAIL_REASON_XTRANS_DERIVE_NOT_ALLOW = 0x0E; -}
\ No newline at end of file diff --git a/core/proto/android/debug/enums.proto b/core/proto/android/debug/enums.proto deleted file mode 100644 index 6747bb7276b3..000000000000 --- a/core/proto/android/debug/enums.proto +++ /dev/null @@ -1,67 +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. - */ - -syntax = "proto2"; -package android.debug; - -option java_outer_classname = "AdbProtoEnums"; -option java_multiple_files = true; - -/** - * adb connection state used to track adb connection changes in AdbDebuggingManager.java. - */ -enum AdbConnectionStateEnum { - UNKNOWN = 0; - - /** - * The adb connection is waiting for approval from the user. - */ - AWAITING_USER_APPROVAL = 1; - - /** - * The user allowed the adb connection from the system. - */ - USER_ALLOWED = 2; - - /** - * The user denied the adb connection from the system. - */ - USER_DENIED = 3; - - /** - * The adb connection was automatically allowed without user interaction due to the system - * being previously allowed by the user with the 'always allow' option selected, and the adb - * grant has not yet expired. - */ - AUTOMATICALLY_ALLOWED = 4; - - /** - * An empty or invalid base64 encoded key was provided to the framework; the connection was - * automatically denied. - */ - DENIED_INVALID_KEY = 5; - - /** - * vold decrypt has not yet occurred; the connection was automatically denied. - */ - DENIED_VOLD_DECRYPT = 6; - - /** - * The adb session has been disconnected. - */ - DISCONNECTED = 7; -} - diff --git a/core/proto/android/hardware/biometrics/enums.proto b/core/proto/android/hardware/biometrics/enums.proto deleted file mode 100644 index f2e06383b5b1..000000000000 --- a/core/proto/android/hardware/biometrics/enums.proto +++ /dev/null @@ -1,60 +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. - */ - -syntax = "proto2"; - -package android.hardware.biometrics; - -option java_outer_classname = "BiometricsProtoEnums"; -option java_multiple_files = true; - -// Logging constants for <Biometric>Service and BiometricService - -enum ModalityEnum { - MODALITY_UNKNOWN = 0; - MODALITY_FINGERPRINT = 1; // 1 << 0 - MODALITY_IRIS = 2; // 1 << 1 - MODALITY_FACE = 4; // 1 << 2 -} - -enum ClientEnum { - CLIENT_UNKNOWN = 0; - CLIENT_KEYGUARD = 1; - CLIENT_BIOMETRIC_PROMPT = 2; - CLIENT_FINGERPRINT_MANAGER = 3; // Deprecated API before BiometricPrompt was introduced -} - -enum ActionEnum { - ACTION_UNKNOWN = 0; - ACTION_ENROLL = 1; - ACTION_AUTHENTICATE = 2; - ACTION_ENUMERATE = 3; - ACTION_REMOVE = 4; -} - -enum IssueEnum { - ISSUE_UNKNOWN = 0; - // When a biometric HAL has crashed. - ISSUE_HAL_DEATH = 1; - // When Android Framework has a template that doesn't exist in the HAL. The framework - // is expected to remove its template to stay in sync with the HAL. - ISSUE_UNKNOWN_TEMPLATE_ENROLLED_FRAMEWORK = 2; - // When the HAL has a template that doesn't exist in Android Framework. The framework - // is expected to notify the HAL to remove this template to stay in sync with the framework. - ISSUE_UNKNOWN_TEMPLATE_ENROLLED_HAL = 3; - // When the HAL has not sent ERROR_CANCELED within the specified timeout. - ISSUE_CANCEL_TIMED_OUT = 4; -}
\ No newline at end of file diff --git a/core/proto/android/hardware/sensor/assist/enums.proto b/core/proto/android/hardware/sensor/assist/enums.proto deleted file mode 100644 index 012dcb2e937e..000000000000 --- a/core/proto/android/hardware/sensor/assist/enums.proto +++ /dev/null @@ -1,34 +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. - */ - -syntax = "proto2"; -package android.hardware.sensor.assist; - -option java_outer_classname = "AssistGestureProtoEnums"; -option java_multiple_files = true; - -enum AssistGestureStageEnum { - ASSIST_GESTURE_STAGE_UNKNOWN = 0; - ASSIST_GESTURE_STAGE_PROGRESS = 1; - ASSIST_GESTURE_STAGE_PRIMED = 2; - ASSIST_GESTURE_STAGE_DETECTED = 3; -} - -enum AssistGestureFeedbackEnum { - ASSIST_GESTURE_FEEDBACK_UNKNOWN = 0; - ASSIST_GESTURE_FEEDBACK_NOT_USED = 1; - ASSIST_GESTURE_FEEDBACK_USED = 2; -}
\ No newline at end of file diff --git a/core/proto/android/net/networkcapabilities.proto b/core/proto/android/net/networkcapabilities.proto deleted file mode 100644 index be0cad18a24d..000000000000 --- a/core/proto/android/net/networkcapabilities.proto +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -syntax = "proto2"; - -package android.net; - -option java_multiple_files = true; - -import "frameworks/base/core/proto/android/privacy.proto"; - -/** - * An android.net.NetworkCapabilities object. - */ -message NetworkCapabilitiesProto { - option (.android.msg_privacy).dest = DEST_AUTOMATIC; - - enum Transport { - // Indicates this network uses a Cellular transport. - TRANSPORT_CELLULAR = 0; - // Indicates this network uses a Wi-Fi transport. - TRANSPORT_WIFI = 1; - // Indicates this network uses a Bluetooth transport. - TRANSPORT_BLUETOOTH = 2; - // Indicates this network uses an Ethernet transport. - TRANSPORT_ETHERNET = 3; - // Indicates this network uses a VPN transport. - TRANSPORT_VPN = 4; - // Indicates this network uses a Wi-Fi Aware transport. - TRANSPORT_WIFI_AWARE = 5; - // Indicates this network uses a LoWPAN transport. - TRANSPORT_LOWPAN = 6; - } - repeated Transport transports = 1; - - enum NetCapability { - // Indicates this is a network that has the ability to reach the - // carrier's MMSC for sending and receiving MMS messages. - NET_CAPABILITY_MMS = 0; - // Indicates this is a network that has the ability to reach the - // carrier's SUPL server, used to retrieve GPS information. - NET_CAPABILITY_SUPL = 1; - // Indicates this is a network that has the ability to reach the - // carrier's DUN or tethering gateway. - NET_CAPABILITY_DUN = 2; - // Indicates this is a network that has the ability to reach the - // carrier's FOTA portal, used for over the air updates. - NET_CAPABILITY_FOTA = 3; - // Indicates this is a network that has the ability to reach the - // carrier's IMS servers, used for network registration and signaling. - NET_CAPABILITY_IMS = 4; - // Indicates this is a network that has the ability to reach the - // carrier's CBS servers, used for carrier specific services. - NET_CAPABILITY_CBS = 5; - // Indicates this is a network that has the ability to reach a Wi-Fi - // direct peer. - NET_CAPABILITY_WIFI_P2P = 6; - // Indicates this is a network that has the ability to reach a carrier's - // Initial Attach servers. - NET_CAPABILITY_IA = 7; - // Indicates this is a network that has the ability to reach a carrier's - // RCS servers, used for Rich Communication Services. - NET_CAPABILITY_RCS = 8; - // Indicates this is a network that has the ability to reach a carrier's - // XCAP servers, used for configuration and control. - NET_CAPABILITY_XCAP = 9; - // Indicates this is a network that has the ability to reach a carrier's - // Emergency IMS servers or other services, used for network signaling - // during emergency calls. - NET_CAPABILITY_EIMS = 10; - // Indicates that this network is unmetered. - NET_CAPABILITY_NOT_METERED = 11; - // Indicates that this network should be able to reach the internet. - NET_CAPABILITY_INTERNET = 12; - // Indicates that this network is available for general use. If this is - // not set applications should not attempt to communicate on this - // network. Note that this is simply informative and not enforcement - - // enforcement is handled via other means. Set by default. - NET_CAPABILITY_NOT_RESTRICTED = 13; - // Indicates that the user has indicated implicit trust of this network. - // This generally means it's a sim-selected carrier, a plugged in - // ethernet, a paired BT device or a wifi the user asked to connect to. - // Untrusted networks are probably limited to unknown wifi AP. Set by - // default. - NET_CAPABILITY_TRUSTED = 14; - // Indicates that this network is not a VPN. This capability is set by - // default and should be explicitly cleared for VPN networks. - NET_CAPABILITY_NOT_VPN = 15; - // Indicates that connectivity on this network was successfully - // validated. For example, for a network with NET_CAPABILITY_INTERNET, - // it means that Internet connectivity was successfully detected. - NET_CAPABILITY_VALIDATED = 16; - // Indicates that this network was found to have a captive portal in - // place last time it was probed. - NET_CAPABILITY_CAPTIVE_PORTAL = 17; - // Indicates that this network is not roaming. - NET_CAPABILITY_NOT_ROAMING = 18; - // Indicates that this network is available for use by apps, and not a - // network that is being kept up in the background to facilitate fast - // network switching. - NET_CAPABILITY_FOREGROUND = 19; - } - repeated NetCapability capabilities = 2; - - // Passive link bandwidth. This is a rough guide of the expected peak - // bandwidth for the first hop on the given transport. It is not measured, - // but may take into account link parameters (Radio technology, allocated - // channels, etc). - optional int32 link_up_bandwidth_kbps = 3; - optional int32 link_down_bandwidth_kbps = 4; - - optional string network_specifier = 5 [ (.android.privacy).dest = DEST_EXPLICIT ]; - - // True if this object specifies a signal strength. - optional bool can_report_signal_strength = 6; - // This is a signed integer, and higher values indicate better signal. The - // exact units are bearer-dependent. For example, Wi-Fi uses RSSI. - // Only valid if can_report_signal_strength is true. - optional sint32 signal_strength = 7; -} diff --git a/core/proto/android/net/networkrequest.proto b/core/proto/android/net/networkrequest.proto index b35a0203ff02..6794c8cd8acb 100644 --- a/core/proto/android/net/networkrequest.proto +++ b/core/proto/android/net/networkrequest.proto @@ -20,8 +20,8 @@ package android.net; option java_multiple_files = true; -import "frameworks/base/core/proto/android/net/networkcapabilities.proto"; import "frameworks/base/core/proto/android/privacy.proto"; +import "frameworks/proto_logging/stats/enums/net/networkcapabilities.proto"; /** * An android.net.NetworkRequest object. diff --git a/core/proto/android/os/batterystats.proto b/core/proto/android/os/batterystats.proto index 892ebf70ca75..7d68a0df23d5 100644 --- a/core/proto/android/os/batterystats.proto +++ b/core/proto/android/os/batterystats.proto @@ -19,10 +19,10 @@ option java_multiple_files = true; package android.os; -import "frameworks/base/core/proto/android/app/job/enums.proto"; import "frameworks/base/core/proto/android/os/powermanager.proto"; -import "frameworks/base/core/proto/android/telephony/enums.proto"; import "frameworks/base/core/proto/android/privacy.proto"; +import "frameworks/proto_logging/stats/enums/app/job/enums.proto"; +import "frameworks/proto_logging/stats/enums/telephony/enums.proto"; message BatteryStatsProto { option (android.msg_privacy).dest = DEST_AUTOMATIC; diff --git a/core/proto/android/os/enums.proto b/core/proto/android/os/enums.proto deleted file mode 100644 index 566861b6e836..000000000000 --- a/core/proto/android/os/enums.proto +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -syntax = "proto2"; -package android.os; - -option java_outer_classname = "OsProtoEnums"; -option java_multiple_files = true; - -// These constants are defined in hardware/interfaces/health/1.0/types.hal -// They are primarily used by android/os/BatteryManager.java. -enum BatteryHealthEnum { - BATTERY_HEALTH_INVALID = 0; - BATTERY_HEALTH_UNKNOWN = 1; - BATTERY_HEALTH_GOOD = 2; - BATTERY_HEALTH_OVERHEAT = 3; - BATTERY_HEALTH_DEAD = 4; - BATTERY_HEALTH_OVER_VOLTAGE = 5; - BATTERY_HEALTH_UNSPECIFIED_FAILURE = 6; - BATTERY_HEALTH_COLD = 7; -} - -// Plug states, primarily used by android/os/BatteryManager.java. -enum BatteryPluggedStateEnum { - // Note that NONE is not in BatteryManager.java's constants. - BATTERY_PLUGGED_NONE = 0; - // Power source is an AC charger. - BATTERY_PLUGGED_AC = 1; - // Power source is a USB port. - BATTERY_PLUGGED_USB = 2; - // Power source is wireless. - BATTERY_PLUGGED_WIRELESS = 4; -} - -// These constants are defined in hardware/interfaces/health/1.0/types.hal -// They are primarily used by android/os/BatteryManager.java. -enum BatteryStatusEnum { - BATTERY_STATUS_INVALID = 0; - BATTERY_STATUS_UNKNOWN = 1; - BATTERY_STATUS_CHARGING = 2; - BATTERY_STATUS_DISCHARGING = 3; - BATTERY_STATUS_NOT_CHARGING = 4; - BATTERY_STATUS_FULL = 5; -} - -// These constants are defined in hardware/interfaces/thermal/1.0/types.hal -// and in hardware/interfaces/thermal/2.0/types.hal -// They are primarily used by android/os/HardwarePropertiesManager.java. -// Any change to the types in the thermal hal should be made here as well. -enum TemperatureTypeEnum { - TEMPERATURE_TYPE_UNKNOWN = -1; - TEMPERATURE_TYPE_CPU = 0; - TEMPERATURE_TYPE_GPU = 1; - TEMPERATURE_TYPE_BATTERY = 2; - TEMPERATURE_TYPE_SKIN = 3; - TEMPERATURE_TYPE_USB_PORT = 4; - TEMPERATURE_TYPE_POWER_AMPLIFIER = 5; - - // Battery Charge Limit - virtual thermal sensors. - TEMPERATURE_TYPE_BCL_VOLTAGE = 6; - TEMPERATURE_TYPE_BCL_CURRENT = 7; - TEMPERATURE_TYPE_BCL_PERCENTAGE = 8; - - // Neural Processing Unit. - TEMPERATURE_TYPE_NPU = 9; -} - -// Device throttling severity -// These constants are defined in hardware/interfaces/thermal/2.0/types.hal. -// Any change to the types in the thermal hal should be made here as well. -enum ThrottlingSeverityEnum { - // Not under throttling. - NONE = 0; - // Light throttling where UX is not impacted. - LIGHT = 1; - // Moderate throttling where UX is not largely impacted. - MODERATE = 2; - // Severe throttling where UX is largely impacted. - // Similar to 1.0 throttlingThreshold. - SEVERE = 3; - // Platform has done everything to reduce power. - CRITICAL = 4; - // Key components in platform are shutting down due to thermal condition. - // Device functionalities will be limited. - EMERGENCY = 5; - // Need shutdown immediately. - SHUTDOWN = 6; -}; - -// Device cooling device types. -// These constants are defined in hardware/interfaces/thermal/2.0/types.hal. -// Any change to the types in the thermal hal should be made here as well. -enum CoolingTypeEnum { - FAN = 0; - BATTERY = 1; - CPU = 2; - GPU = 3; - MODEM = 4; - NPU = 5; - COMPONENT = 6; -}; - -// Wakelock types, primarily used by android/os/PowerManager.java. -enum WakeLockLevelEnum { - // NOTE: Wake lock levels were previously defined as a bit field, except - // that only a few combinations were actually supported so the bit field - // was removed. This explains why the numbering scheme is so odd. If - // adding a new wake lock level, any unused value can be used. - - // Ensures that the CPU is running; the screen and keyboard backlight - // will be allowed to go off. - PARTIAL_WAKE_LOCK = 1; - - // Ensures that the screen is on (but may be dimmed); the keyboard - // backlight will be allowed to go off. If the user presses the power - // button, then the SCREEN_DIM_WAKE_LOCK will be implicitly released by - // the system, causing both the screen and the CPU to be turned off. - SCREEN_DIM_WAKE_LOCK = 6 [deprecated = true]; - - // Ensures that the screen is on at full brightness; the keyboard - // backlight will be allowed to go off. If the user presses the power - // button, then the SCREEN_BRIGHT_WAKE_LOCK will be implicitly released - // by the system, causing both the screen and the CPU to be turned off. - SCREEN_BRIGHT_WAKE_LOCK = 10 [deprecated = true]; - - // Ensures that the screen and keyboard backlight are on at full - // brightness. If the user presses the power button, then the - // FULL_WAKE_LOCK will be implicitly released by the system, causing - // both the screen and the CPU to be turned off. - FULL_WAKE_LOCK = 26 [deprecated = true]; - - // Turns the screen off when the proximity sensor activates. If the - // proximity sensor detects that an object is nearby, the screen turns - // off immediately. Shortly after the object moves away, the screen - // turns on again. - // A proximity wake lock does not prevent the device from falling asleep - // unlike FULL_WAKE_LOCK, SCREEN_BRIGHT_WAKE_LOCK and - // SCREEN_DIM_WAKE_LOCK. If there is no user activity and no other wake - // locks are held, then the device will fall asleep (and lock) as usual. - // However, the device will not fall asleep while the screen has been - // turned off by the proximity sensor because it effectively counts as - // ongoing user activity. - PROXIMITY_SCREEN_OFF_WAKE_LOCK = 32; - - // Put the screen in a low power state and allow the CPU to suspend if - // no other wake locks are held. This is used by the dream manager to - // implement doze mode. It currently has no effect unless the power - // manager is in the dozing state. - DOZE_WAKE_LOCK = 64; - - // Keep the device awake enough to allow drawing to occur. This is used - // by the window manager to allow applications to draw while the system - // is dozing. It currently has no effect unless the power manager is in - // the dozing state. - DRAW_WAKE_LOCK = 128; -} diff --git a/core/proto/android/os/incident.proto b/core/proto/android/os/incident.proto index fe65bda365af..8de30f8547a7 100644 --- a/core/proto/android/os/incident.proto +++ b/core/proto/android/os/incident.proto @@ -56,13 +56,13 @@ import "frameworks/base/core/proto/android/service/print.proto"; import "frameworks/base/core/proto/android/service/procstats.proto"; import "frameworks/base/core/proto/android/service/restricted_image.proto"; import "frameworks/base/core/proto/android/service/sensor_service.proto"; -import "frameworks/base/core/proto/android/service/usb.proto"; import "frameworks/base/core/proto/android/util/event_log_tags.proto"; import "frameworks/base/core/proto/android/util/log.proto"; import "frameworks/base/core/proto/android/util/textdump.proto"; import "frameworks/base/core/proto/android/privacy.proto"; import "frameworks/base/core/proto/android/section.proto"; import "frameworks/base/proto/src/ipconnectivity.proto"; +import "frameworks/proto_logging/stats/enums/service/usb.proto"; package android.os; diff --git a/core/proto/android/stats/devicepolicy/device_policy.proto b/core/proto/android/server/accessibility.proto index af30cf3f9941..7fe7f0d5f3cc 100644 --- a/core/proto/android/stats/devicepolicy/device_policy.proto +++ b/core/proto/android/server/accessibility.proto @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 The Android Open Source Project + * 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. @@ -16,9 +16,12 @@ syntax = "proto2"; -package android.stats.devicepolicy; +import "frameworks/base/core/proto/android/typedef.proto"; + +package com.android.server.accessibility; + option java_multiple_files = true; -message StringList { - repeated string string_value = 1; +/* The proto format trace entry for accessibility service */ +message AccessibilityDumpProto { } diff --git a/core/proto/android/server/accessibilitytrace.proto b/core/proto/android/server/accessibilitytrace.proto new file mode 100644 index 000000000000..1fc4a01936b1 --- /dev/null +++ b/core/proto/android/server/accessibilitytrace.proto @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +syntax = "proto2"; + +import "frameworks/base/core/proto/android/server/accessibility.proto"; +import "frameworks/base/core/proto/android/server/windowmanagerservice.proto"; + +package com.android.server.accessibility; + +option java_multiple_files = true; + +/* represents a file full of accessibility trace entries. + Encoded, it should start with 0x9 0x41 0x31 0x31 0x59 0x54 0x52 0x41 0x43 (.A11YTRAC), such + that they can be easily identified. */ +message AccessibilityTraceFileProto { + + /* constant; MAGIC_NUMBER = (long) MAGIC_NUMBER_H << 32 | MagicNumber.MAGIC_NUMBER_L + (this is needed because enums have to be 32 bits and there's no nice way to put 64bit + constants into .proto files. */ + enum MagicNumber { + INVALID = 0; + MAGIC_NUMBER_L = 0x59313141; /* A11Y (little-endian ASCII) */ + MAGIC_NUMBER_H = 0x43415254; /* TRAC (little-endian ASCII) */ + } + + optional fixed64 magic_number = 1; /* Must be the first field, set to value in MagicNumber */ + repeated AccessibilityTraceProto entry = 2; +} + +/* one accessibility trace entry. */ +message AccessibilityTraceProto { + /* required: elapsed realtime in nanos since boot of when this entry was logged */ + optional fixed64 elapsed_realtime_nanos = 1; + optional string calendar_time = 2; + + optional string process_name = 3; + optional string thread_id_name = 4; + + /* where the trace originated */ + optional string where = 5; + + optional string calling_pkg = 6; + optional string calling_params = 7; + optional string calling_stacks = 8; + + optional AccessibilityDumpProto accessibility_service = 9; + optional com.android.server.wm.WindowManagerServiceDumpProto window_manager_service = 10; +} diff --git a/core/proto/android/server/activitymanagerservice.proto b/core/proto/android/server/activitymanagerservice.proto index 2d2ead455a4d..fa046c6593af 100644 --- a/core/proto/android/server/activitymanagerservice.proto +++ b/core/proto/android/server/activitymanagerservice.proto @@ -20,7 +20,6 @@ package com.android.server.am; import "frameworks/base/core/proto/android/app/activitymanager.proto"; import "frameworks/base/core/proto/android/app/appexitinfo.proto"; -import "frameworks/base/core/proto/android/app/enums.proto"; import "frameworks/base/core/proto/android/app/notification.proto"; import "frameworks/base/core/proto/android/app/profilerinfo.proto"; import "frameworks/base/core/proto/android/content/component_name.proto"; @@ -35,6 +34,7 @@ import "frameworks/base/core/proto/android/server/intentresolver.proto"; import "frameworks/base/core/proto/android/server/windowmanagerservice.proto"; import "frameworks/base/core/proto/android/util/common.proto"; import "frameworks/base/core/proto/android/privacy.proto"; +import "frameworks/proto_logging/stats/enums/app/enums.proto"; option java_multiple_files = true; diff --git a/core/proto/android/server/bluetooth_manager_service.proto b/core/proto/android/server/bluetooth_manager_service.proto index 998413f05ebe..c33f66a9aeca 100644 --- a/core/proto/android/server/bluetooth_manager_service.proto +++ b/core/proto/android/server/bluetooth_manager_service.proto @@ -17,8 +17,8 @@ syntax = "proto2"; package com.android.server; -import "frameworks/base/core/proto/android/bluetooth/enums.proto"; import "frameworks/base/core/proto/android/privacy.proto"; +import "frameworks/proto_logging/stats/enums/bluetooth/enums.proto"; option java_multiple_files = true; diff --git a/core/proto/android/server/connectivity/Android.bp b/core/proto/android/server/connectivity/Android.bp deleted file mode 100644 index 50c238b96307..000000000000 --- a/core/proto/android/server/connectivity/Android.bp +++ /dev/null @@ -1,26 +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. - -java_library_static { - name: "datastallprotosnano", - proto: { - type: "nano", - }, - srcs: [ - "data_stall_event.proto", - ], - sdk_version: "system_current", - // this is part of updatable modules(NetworkStack) which targets 29(Q) - min_sdk_version: "29", -} diff --git a/core/proto/android/server/connectivity/data_stall_event.proto b/core/proto/android/server/connectivity/data_stall_event.proto deleted file mode 100644 index 787074ba494e..000000000000 --- a/core/proto/android/server/connectivity/data_stall_event.proto +++ /dev/null @@ -1,91 +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. - */ - -syntax = "proto2"; - -package com.android.server.connectivity; -option java_multiple_files = true; -option java_outer_classname = "DataStallEventProto"; - -enum ProbeResult { - UNKNOWN = 0; - VALID = 1; - INVALID = 2; - PORTAL = 3; - PARTIAL = 4; -} - -enum ApBand { - AP_BAND_UNKNOWN = 0; - AP_BAND_2GHZ = 1; - AP_BAND_5GHZ = 2; - AP_BAND_6GHZ = 3; -} - -// Refer to definition in TelephonyManager.java. -enum RadioTech { - RADIO_TECHNOLOGY_UNKNOWN = 0; - RADIO_TECHNOLOGY_GPRS = 1; - RADIO_TECHNOLOGY_EDGE = 2; - RADIO_TECHNOLOGY_UMTS = 3; - RADIO_TECHNOLOGY_IS95A = 4; - RADIO_TECHNOLOGY_IS95B = 5; - RADIO_TECHNOLOGY_1XRTT = 6; - RADIO_TECHNOLOGY_EVDO_0 = 7; - RADIO_TECHNOLOGY_EVDO_A = 8; - RADIO_TECHNOLOGY_HSDPA = 9; - RADIO_TECHNOLOGY_HSUPA = 10; - RADIO_TECHNOLOGY_HSPA = 11; - RADIO_TECHNOLOGY_EVDO_B = 12; - RADIO_TECHNOLOGY_LTE = 13; - RADIO_TECHNOLOGY_EHRPD = 14; - RADIO_TECHNOLOGY_HSPAP = 15; - RADIO_TECHNOLOGY_GSM = 16; - RADIO_TECHNOLOGY_TD_SCDMA = 17; - RADIO_TECHNOLOGY_IWLAN = 18; - RADIO_TECHNOLOGY_LTE_CA = 19; - RADIO_TECHNOLOGY_NR = 20; -} - -// Cellular specific information. -message CellularData { - // Indicate the radio technology at the time of data stall suspected. - optional RadioTech rat_type = 1; - // True if device is in roaming network at the time of data stall suspected. - optional bool is_roaming = 2; - // Registered network MccMnc when data stall happen - optional string network_mccmnc = 3; - // Indicate the SIM card carrier. - optional string sim_mccmnc = 4; - // Signal strength level at the time of data stall suspected. - optional int32 signal_strength = 5; -} - -// Wifi specific information. -message WifiData { - // Signal strength at the time of data stall suspected. - // RSSI range is between -55 to -110. - optional int32 signal_strength = 1; - // AP band. - optional ApBand wifi_band = 2; -} - -message DnsEvent { - // The dns return code. - repeated int32 dns_return_code = 1; - // Indicate the timestamp of the dns event. - repeated int64 dns_time = 2; -} diff --git a/core/proto/android/server/enums.proto b/core/proto/android/server/enums.proto deleted file mode 100644 index 89f7010e8d81..000000000000 --- a/core/proto/android/server/enums.proto +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -syntax = "proto2"; -package android.server; - -option java_outer_classname = "ServerProtoEnums"; -option java_multiple_files = true; - -enum DeviceIdleModeEnum { - // Device idle mode - not active. - DEVICE_IDLE_MODE_OFF = 0; - // Device idle mode - active in lightweight mode. - DEVICE_IDLE_MODE_LIGHT = 1; - // Device idle mode - active in full mode. - DEVICE_IDLE_MODE_DEEP = 2; -} - -enum ErrorSource { - ERROR_SOURCE_UNKNOWN = 0; - // Data app - DATA_APP = 1; - // System app - SYSTEM_APP = 2; - // System server. - SYSTEM_SERVER = 3; -} diff --git a/core/proto/android/server/job/enums.proto b/core/proto/android/server/job/enums.proto deleted file mode 100644 index 50fc0310ad99..000000000000 --- a/core/proto/android/server/job/enums.proto +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -syntax = "proto2"; - -package com.android.server.job; - -// This file is for JobScheduler enums inside the server directory. If you're -// adding enums for app-side code, use the file in -// frameworks/base/core/proto/android/app/job. -option java_outer_classname = "JobServerProtoEnums"; -option java_multiple_files = true; - -// Set of constraints that a job potentially needs satisfied before it can run. -// Defined in -// frameworks/base/services/core/java/com/android/server/job/controllers/JobStatus.java -enum ConstraintEnum { - CONSTRAINT_UNKNOWN = 0; - CONSTRAINT_CHARGING = 1; - CONSTRAINT_BATTERY_NOT_LOW = 2; - CONSTRAINT_STORAGE_NOT_LOW = 3; - CONSTRAINT_TIMING_DELAY = 4; - CONSTRAINT_DEADLINE = 5; - CONSTRAINT_IDLE = 6; - CONSTRAINT_CONNECTIVITY = 7; - CONSTRAINT_CONTENT_TRIGGER = 8; - CONSTRAINT_DEVICE_NOT_DOZING = 9; - CONSTRAINT_WITHIN_QUOTA = 10; - CONSTRAINT_BACKGROUND_NOT_RESTRICTED = 11; -} diff --git a/core/proto/android/server/jobscheduler.proto b/core/proto/android/server/jobscheduler.proto index 0e2bd2605836..d18722049109 100644 --- a/core/proto/android/server/jobscheduler.proto +++ b/core/proto/android/server/jobscheduler.proto @@ -20,7 +20,6 @@ package com.android.server.job; option java_multiple_files = true; -import "frameworks/base/core/proto/android/app/job/enums.proto"; import "frameworks/base/core/proto/android/content/clipdata.proto"; import "frameworks/base/core/proto/android/content/component_name.proto"; import "frameworks/base/core/proto/android/content/intent.proto"; @@ -29,10 +28,11 @@ import "frameworks/base/core/proto/android/net/networkrequest.proto"; import "frameworks/base/core/proto/android/os/bundle.proto"; import "frameworks/base/core/proto/android/os/persistablebundle.proto"; import "frameworks/base/core/proto/android/server/appstatetracker.proto"; -import "frameworks/base/core/proto/android/server/job/enums.proto"; import "frameworks/base/core/proto/android/server/statlogger.proto"; import "frameworks/base/core/proto/android/privacy.proto"; import "frameworks/base/core/proto/android/util/quotatracker.proto"; +import "frameworks/proto_logging/stats/enums/app/job/enums.proto"; +import "frameworks/proto_logging/stats/enums/server/job/enums.proto"; message JobSchedulerServiceDumpProto { option (.android.msg_privacy).dest = DEST_AUTOMATIC; diff --git a/core/proto/android/server/location/enums.proto b/core/proto/android/server/location/enums.proto deleted file mode 100644 index 943ff181fe14..000000000000 --- a/core/proto/android/server/location/enums.proto +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -syntax = "proto2"; - -package android.server.location; - -option java_outer_classname = "ServerLocationProtoEnums"; -option java_multiple_files = true; - -// GPS Signal Quality levels, -// primarily used by location/java/com/android/internal/location/gnssmetrics/GnssMetrics.java -enum GpsSignalQualityEnum { - GPS_SIGNAL_QUALITY_UNKNOWN = -1; - GPS_SIGNAL_QUALITY_POOR = 0; - GPS_SIGNAL_QUALITY_GOOD = 1; -} - -// A type which distinguishes different categories of NI request, such as VOICE, UMTS_SUPL etc. -enum GnssNiType { - VOICE = 1; - UMTS_SUPL = 2; - UMTS_CTRL_PLANE = 3; - EMERGENCY_SUPL = 4; -}; - -// GNSS NI responses, used to define the response in NI structures. -enum GnssUserResponseType { - RESPONSE_ACCEPT = 1; - RESPONSE_DENY = 2; - RESPONSE_NORESP = 3; -}; - -// GNSS NI data encoding scheme. -enum GnssNiEncodingType { - ENC_NONE = 0; - ENC_SUPL_GSM_DEFAULT = 1; - ENC_SUPL_UTF8 = 2; - ENC_SUPL_UCS2 = 3; - ENC_UNKNOWN = -1; -}; - -// Protocol stack that initiated the non-framework location request. -enum NfwProtocolStack { - // Cellular control plane requests. - CTRL_PLANE = 0; - // All types of SUPL requests. - SUPL = 1; - // All types of requests from IMS. - IMS = 10; - // All types of requests from SIM. - SIM = 11; - // Requests from other protocol stacks. - OTHER_PROTOCOL_STACK = 100; -}; - -// Source initiating/receiving the location information. -enum NfwRequestor { - // Wireless service provider. - CARRIER = 0; - // Device manufacturer. - OEM = 10; - // Modem chipset vendor. - MODEM_CHIPSET_VENDOR = 11; - // GNSS chipset vendor. - GNSS_CHIPSET_VENDOR = 12; - // Other chipset vendor. - OTHER_CHIPSET_VENDOR = 13; - // Automobile client. - AUTOMOBILE_CLIENT = 20; - // Other sources. - OTHER_REQUESTOR = 100; -}; - -// Indicates whether location information was provided for this request. -enum NfwResponseType { - // Request rejected because framework has not given permission for this use case. - REJECTED = 0; - // Request accepted but could not provide location because of a failure. - ACCEPTED_NO_LOCATION_PROVIDED = 1; - // Request accepted and location provided. - ACCEPTED_LOCATION_PROVIDED = 2; -}; - -// The SUPL mode. -enum SuplMode { - // Mobile Station Based. - MSB = 0x01; - // Mobile Station Assisted. - MSA = 0x02; -}; - -// Enum that hold the bit masks for various LTE Positioning Profile settings (LPP_PROFILE -// configuration parameter). If none of the bits in the enum are set, the default setting is -// Radio Resource Location Protocol(RRLP). -enum LppProfile { - // Enable LTE Positioning Protocol user plane. - USER_PLANE = 0x01; - // Enable LTE Positioning Protocol Control plane. - CONTROL_PLANE = 0x02; -}; - -// Positioning protocol on A-Glonass system. -enum GlonassPosProtocol { - // Radio Resource Control(RRC) control-plane. - RRC_CPLANE = 0x01; - // Radio Resource Location user-plane. - RRLP_CPLANE = 0x02; - // LTE Positioning Protocol User plane. - LPP_UPLANE = 0x04; -}; - -// Configurations of how GPS functionalities should be locked when user turns off GPS On setting. -enum GpsLock { - // Lock Mobile Originated GPS functionalitues. - MO = 0x01; - // Lock Network Initiated GPS functionalities. - NI = 0x02; -}; diff --git a/core/proto/android/server/powermanagerservice.proto b/core/proto/android/server/powermanagerservice.proto index a2f2c46cba6a..0d23946ebbb8 100644 --- a/core/proto/android/server/powermanagerservice.proto +++ b/core/proto/android/server/powermanagerservice.proto @@ -19,16 +19,16 @@ package com.android.server.power; option java_multiple_files = true; -import "frameworks/base/core/proto/android/app/enums.proto"; import "frameworks/base/core/proto/android/content/intent.proto"; -import "frameworks/base/core/proto/android/os/enums.proto"; import "frameworks/base/core/proto/android/os/looper.proto"; import "frameworks/base/core/proto/android/os/powermanager.proto"; import "frameworks/base/core/proto/android/os/worksource.proto"; import "frameworks/base/core/proto/android/providers/settings.proto"; import "frameworks/base/core/proto/android/server/wirelesschargerdetector.proto"; -import "frameworks/base/core/proto/android/view/enums.proto"; import "frameworks/base/core/proto/android/privacy.proto"; +import "frameworks/proto_logging/stats/enums/app/enums.proto"; +import "frameworks/proto_logging/stats/enums/os/enums.proto"; +import "frameworks/proto_logging/stats/enums/view/enums.proto"; message PowerManagerServiceDumpProto { option (.android.msg_privacy).dest = DEST_AUTOMATIC; diff --git a/core/proto/android/server/windowmanagerservice.proto b/core/proto/android/server/windowmanagerservice.proto index 0453d3f3763d..c4c007d8113b 100644 --- a/core/proto/android/server/windowmanagerservice.proto +++ b/core/proto/android/server/windowmanagerservice.proto @@ -24,7 +24,6 @@ import "frameworks/base/core/proto/android/server/windowcontainerthumbnail.proto import "frameworks/base/core/proto/android/server/surfaceanimator.proto"; import "frameworks/base/core/proto/android/view/displaycutout.proto"; import "frameworks/base/core/proto/android/view/displayinfo.proto"; -import "frameworks/base/core/proto/android/view/enums.proto"; import "frameworks/base/core/proto/android/view/surface.proto"; import "frameworks/base/core/proto/android/view/windowlayoutparams.proto"; import "frameworks/base/core/proto/android/privacy.proto"; @@ -34,6 +33,8 @@ import "frameworks/base/core/proto/android/view/surfacecontrol.proto"; import "frameworks/base/core/proto/android/view/insetssource.proto"; import "frameworks/base/core/proto/android/view/insetssourcecontrol.proto"; +import "frameworks/proto_logging/stats/enums/view/enums.proto"; + package com.android.server.wm; option java_multiple_files = true; @@ -206,9 +207,10 @@ message DisplayContentProto { optional WindowStateProto input_method_control_target = 29; optional WindowStateProto current_focus = 30; optional ImeInsetsSourceProviderProto ime_insets_source_provider = 31; - optional bool can_show_ime = 32; + optional bool can_show_ime = 32 [deprecated=true]; optional DisplayRotationProto display_rotation = 33; + optional int32 ime_policy = 34; } /* represents DisplayArea object */ diff --git a/core/proto/android/service/battery.proto b/core/proto/android/service/battery.proto index 586411f8ad96..3a112e7c85f0 100644 --- a/core/proto/android/service/battery.proto +++ b/core/proto/android/service/battery.proto @@ -20,8 +20,8 @@ package android.service.battery; option java_multiple_files = true; option java_outer_classname = "BatteryServiceProto"; -import "frameworks/base/core/proto/android/os/enums.proto"; import "frameworks/base/core/proto/android/privacy.proto"; +import "frameworks/proto_logging/stats/enums/os/enums.proto"; message BatteryServiceDumpProto { option (android.msg_privacy).dest = DEST_AUTOMATIC; diff --git a/core/proto/android/service/procstats.proto b/core/proto/android/service/procstats.proto index 7a4c0706e119..57051f07d124 100644 --- a/core/proto/android/service/procstats.proto +++ b/core/proto/android/service/procstats.proto @@ -21,8 +21,8 @@ option java_multiple_files = true; option java_outer_classname = "ProcessStatsServiceProto"; import "frameworks/base/core/proto/android/util/common.proto"; -import "frameworks/base/core/proto/android/service/procstats_enum.proto"; import "frameworks/base/core/proto/android/privacy.proto"; +import "frameworks/proto_logging/stats/enums/service/procstats_enum.proto"; /** * Data from ProcStatsService Dumpsys diff --git a/core/proto/android/service/procstats_enum.proto b/core/proto/android/service/procstats_enum.proto deleted file mode 100644 index 2abf3730aa9f..000000000000 --- a/core/proto/android/service/procstats_enum.proto +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -syntax = "proto2"; -package android.service.procstats; - -option java_multiple_files = true; -option java_outer_classname = "ProcessStatsEnums"; - -enum ScreenState { - SCREEN_STATE_UNKNOWN = 0; - SCREEN_STATE_OFF = 1; - SCREEN_STATE_ON = 2; -} - -enum MemoryState { - MEMORY_STATE_UNKNOWN = 0; - MEMORY_STATE_NORMAL = 1; // normal. - MEMORY_STATE_MODERATE = 2; // moderate memory pressure. - MEMORY_STATE_LOW = 3; // low memory. - MEMORY_STATE_CRITICAL = 4; // critical memory. -} - -// this enum list is from frameworks/base/core/java/com/android/internal/app/procstats/ProcessStats.java -// and not frameworks/base/core/java/android/app/ActivityManager.java -enum ProcessState { - PROCESS_STATE_UNKNOWN = 0; - // Persistent system process. - PROCESS_STATE_PERSISTENT = 1; - // Top activity; actually any visible activity. - PROCESS_STATE_TOP = 2; - // Important foreground process (ime, wallpaper, etc). - PROCESS_STATE_IMPORTANT_FOREGROUND = 3; - // Important background process. - PROCESS_STATE_IMPORTANT_BACKGROUND = 4; - // Performing backup operation. - PROCESS_STATE_BACKUP = 5; - // Background process running a service. - PROCESS_STATE_SERVICE = 6; - // Process not running, but would be if there was enough RAM. - PROCESS_STATE_SERVICE_RESTARTING = 7; - // Process running a receiver. - PROCESS_STATE_RECEIVER = 8; - // Heavy-weight process (currently not used). - PROCESS_STATE_HEAVY_WEIGHT = 9; - // Process hosting home/launcher app when not on top. - PROCESS_STATE_HOME = 10; - // Process hosting the last app the user was in. - PROCESS_STATE_LAST_ACTIVITY = 11; - // Cached process hosting a previous activity. - PROCESS_STATE_CACHED_ACTIVITY = 12; - // Cached process hosting a client activity. - PROCESS_STATE_CACHED_ACTIVITY_CLIENT = 13; - // Cached process that is empty. - PROCESS_STATE_CACHED_EMPTY = 14; -} - -enum ServiceOperationState { - SERVICE_OPERATION_STATE_UNKNOWN = 0; - SERVICE_OPERATION_STATE_RUNNING = 1; - SERVICE_OPERATION_STATE_STARTED = 2; - SERVICE_OPERATION_STATE_FOREGROUND = 3; - SERVICE_OPERATION_STATE_BOUND = 4; - SERVICE_OPERATION_STATE_EXECUTING = 5; -} - -// this enum list is from frameworks/base/core/java/com/android/internal/app/procstats/ProcessStats.java -// and not frameworks/base/core/java/android/app/ActivityManager.java -enum AggregatedProcessState { - AGGREGATED_PROCESS_STATE_UNKNOWN = 0; - // Persistent system process; PERSISTENT or PERSISTENT_UI in ActivityManager - AGGREGATED_PROCESS_STATE_PERSISTENT = 1; - // Top activity; actually any visible activity; TOP or TOP_SLEEPING in ActivityManager - AGGREGATED_PROCESS_STATE_TOP = 2; - // Bound top foreground process; BOUND_TOP or BOUND_FOREGROUND_SERVICE in ActivityManager - AGGREGATED_PROCESS_STATE_BOUND_TOP_OR_FGS = 3; - // Important foreground process; FOREGROUND_SERVICE in ActivityManager - AGGREGATED_PROCESS_STATE_FGS = 4; - // Important foreground process ; IMPORTANT_FOREGROUND in ActivityManager - AGGREGATED_PROCESS_STATE_IMPORTANT_FOREGROUND = 5; - // Various background processes; IMPORTANT_BACKGROUND, TRANSIENT_BACKGROUND, BACKUP, SERVICE, - // HEAVY_WEIGHT in ActivityManager - AGGREGATED_PROCESS_STATE_BACKGROUND = 6; - // Process running a receiver; RECEIVER in ActivityManager - AGGREGATED_PROCESS_STATE_RECEIVER = 7; - // Various cached processes; HOME, LAST_ACTIVITY, CACHED_ACTIVITY, CACHED_RECENT, - // CACHED_ACTIVITY_CLIENT, CACHED_EMPTY in ActivityManager - AGGREGATED_PROCESS_STATE_CACHED = 8; -}
\ No newline at end of file diff --git a/core/proto/android/service/usb.proto b/core/proto/android/service/usb.proto deleted file mode 100644 index 40c5a85e1f24..000000000000 --- a/core/proto/android/service/usb.proto +++ /dev/null @@ -1,440 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -syntax = "proto2"; -package android.service.usb; - -option java_multiple_files = true; -option java_outer_classname = "UsbServiceProto"; - -import "frameworks/base/core/proto/android/content/component_name.proto"; -import "frameworks/base/core/proto/android/service/enums.proto"; -import "frameworks/base/core/proto/android/privacy.proto"; - -message UsbServiceDumpProto { - option (android.msg_privacy).dest = DEST_AUTOMATIC; - - optional UsbDeviceManagerProto device_manager = 1; - optional UsbHostManagerProto host_manager = 2; - optional UsbPortManagerProto port_manager = 3; - optional UsbAlsaManagerProto alsa_manager = 4; - optional UsbSettingsManagerProto settings_manager = 5; - optional UsbPermissionsManagerProto permissions_manager = 6; -} - -message UsbDeviceManagerProto { - option (android.msg_privacy).dest = DEST_AUTOMATIC; - - optional UsbHandlerProto handler = 1; - optional UsbDebuggingManagerProto debugging_manager = 2; -} - -message UsbHandlerProto { - option (android.msg_privacy).dest = DEST_AUTOMATIC; - - /* Same as android.hardware.usb.gadget.V1_0.GadgetFunction.* */ - enum Function { - FUNCTION_ADB = 1; - FUNCTION_ACCESSORY = 2; - FUNCTION_MTP = 4; - FUNCTION_MIDI = 8; - FUNCTION_PTP = 16; - FUNCTION_RNDIS = 32; - FUNCTION_AUDIO_SOURCE = 64; - } - - repeated Function current_functions = 1; - optional bool current_functions_applied = 2; - repeated Function screen_unlocked_functions = 3; - optional bool screen_locked = 4; - optional bool connected = 5; - optional bool configured = 6; - optional UsbAccessoryProto current_accessory = 7; - optional bool host_connected = 8; - optional bool source_power = 9; - optional bool sink_power = 10; - optional bool usb_charging = 11; - optional bool hide_usb_notification = 12; - optional bool audio_accessory_connected = 13; - optional bool adb_enabled = 14; - optional string kernel_state = 15; - optional string kernel_function_list = 16; -} - -message UsbAccessoryProto { - option (android.msg_privacy).dest = DEST_AUTOMATIC; - - optional string manufacturer = 1; - optional string model = 2; - // For "classical" USB-accessories the manufacturer bakes this into the - // firmware of the device. If an Android phone is configured as accessory, the - // app that sets up the accessory side of the connection set this. Either way, - // these are part of the detection protocol, and so they cannot be user set or - // unique. - optional string description = 3; - optional string version = 4; - optional string uri = 5 [ (android.privacy).dest = DEST_EXPLICIT ]; - // Non-resettable hardware ID. - optional string serial = 6 [ (android.privacy).dest = DEST_LOCAL ]; -} - -message UsbDebuggingManagerProto { - option (android.msg_privacy).dest = DEST_AUTOMATIC; - - optional bool connected_to_adb = 1; - // A workstation that connects to the phone for debugging is identified by - // this key. - optional string last_key_received = 2 [ (android.privacy).dest = DEST_EXPLICIT ]; - optional string user_keys = 3 [ (android.privacy).dest = DEST_LOCAL ]; - optional string system_keys = 4 [ (android.privacy).dest = DEST_LOCAL ]; -} - -message UsbHostManagerProto { - option (android.msg_privacy).dest = DEST_AUTOMATIC; - - optional android.content.ComponentNameProto default_usb_host_connection_handler = 1; - repeated UsbDeviceProto devices = 2; - optional int32 num_connects = 3; - repeated UsbConnectionRecordProto connections = 4; -} - -message UsbDeviceProto { - option (android.msg_privacy).dest = DEST_AUTOMATIC; - - // Generic USB name, not user-provided. - optional string name = 1; - // ID specific to the vendor, not the device. - optional int32 vendor_id = 2; - // ID of this product type: Each vendor gives each product a unique ID. E.g. - // all mice of the same model would have the same ID. - optional int32 product_id = 3; - optional int32 class = 4; - optional int32 subclass = 5; - optional int32 protocol = 6; - optional string manufacturer_name = 7; - optional string product_name = 8; - optional string version = 9; - // Non-resettable hardware ID. - optional string serial_number = 10 [ (android.privacy).dest = DEST_LOCAL ]; - repeated UsbConfigurationProto configurations = 11; -} - -message UsbConfigurationProto { - option (android.msg_privacy).dest = DEST_AUTOMATIC; - - // A single USB device can have several configurations and the app accessing - // the USB device can switch between them. At any time only one can be active. - // Each configuration can present completely different interfaces end - // endpoints, i.e. a completely different behavior. - optional int32 id = 1; - // Hardware-defined name, not set by the user. - optional string name = 2; - optional uint32 attributes = 3; - optional int32 max_power = 4; - repeated UsbInterfaceProto interfaces = 5; -} - -message UsbInterfaceProto { - option (android.msg_privacy).dest = DEST_AUTOMATIC; - - // Hardware defined. This is the id used by the app to identify the interface. - optional int32 id = 1; - optional int32 alternate_settings = 2; - optional string name = 3; - optional int32 class = 4; - optional int32 subclass = 5; - optional int32 protocol = 6; - repeated UsbEndPointProto endpoints = 7; -} - -message UsbEndPointProto { - option (android.msg_privacy).dest = DEST_AUTOMATIC; - - optional int32 endpoint_number = 1; - optional android.service.UsbEndPointDirection direction = 2; - // The address of the endpoint. Needed to read and write to the endpoint. - optional int32 address = 3; - optional android.service.UsbEndPointType type = 4; - optional uint32 attributes = 5; - optional int32 max_packet_size = 6; - optional int32 interval = 7; -} - -message UsbConnectionRecordProto { - option (android.msg_privacy).dest = DEST_AUTOMATIC; - - // usb device's address, e.g. 001/002, nothing about the phone - optional string device_address = 1; - optional android.service.UsbConnectionRecordMode mode = 2; - optional int64 timestamp = 3; - optional int32 manufacturer = 4; - optional int32 product = 5; - optional UsbIsHeadsetProto is_headset = 6; -} - -message UsbIsHeadsetProto { - option (android.msg_privacy).dest = DEST_AUTOMATIC; - - optional bool in = 1; - optional bool out = 2; -} - -message UsbPortManagerProto { - option (android.msg_privacy).dest = DEST_AUTOMATIC; - - optional bool is_simulation_active = 1; - repeated UsbPortInfoProto usb_ports = 2; -} - -message UsbPortInfoProto { - option (android.msg_privacy).dest = DEST_AUTOMATIC; - - optional UsbPortProto port = 1; - optional UsbPortStatusProto status = 2; - optional bool can_change_mode = 3; - optional bool can_change_power_role = 4; - optional bool can_change_data_role = 5; - optional int64 connected_at_millis = 6; - optional int64 last_connect_duration_millis = 7; -} - -message UsbPortProto { - option (android.msg_privacy).dest = DEST_AUTOMATIC; - - /* Same as android.hardware.usb.V1_1.Constants.PortMode_1_1 */ - enum Mode { - MODE_NONE = 0; - MODE_UFP = 1; - MODE_DFP = 2; - MODE_DRP = 3; - MODE_AUDIO_ACCESSORY = 4; - MODE_DEBUG_ACCESSORY = 8; - } - - // ID of the port. A device (eg: Chromebooks) might have multiple ports. - optional string id = 1; - repeated Mode supported_modes = 2; -} - -/* Same as android.hardware.usb.V1_2.Constants.ContaminantPresenceStatus */ -enum ContaminantPresenceStatus { - CONTAMINANT_STATUS_UNKNOWN = 0; - CONTAMINANT_STATUS_NOT_SUPPORTED = 1; - CONTAMINANT_STATUS_DISABLED = 2; - CONTAMINANT_STATUS_NOT_DETECTED = 3; - CONTAMINANT_STATUS_DETECTED = 4; -} - -message UsbPortStatusProto { - option (android.msg_privacy).dest = DEST_AUTOMATIC; - - /* Same as android.hardware.usb.V1_0.Constants.PortPowerRole */ - enum PowerRole { - POWER_ROLE_NONE = 0; - POWER_ROLE_SOURCE = 1; - POWER_ROLE_SINK = 2; - } - - /* Same as android.hardware.usb.V1_0.Constants.PortDataRole */ - enum DataRole { - DATA_ROLE_NONE = 0; - DATA_ROLE_HOST = 1; - DATA_ROLE_DEVICE = 2; - } - - optional bool connected = 1; - optional UsbPortProto.Mode current_mode = 2; - optional PowerRole power_role = 3; - optional DataRole data_role = 4; - repeated UsbPortStatusRoleCombinationProto role_combinations = 5; - optional ContaminantPresenceStatus contaminant_presence_status = 6; -} - -message UsbPortStatusRoleCombinationProto { - option (android.msg_privacy).dest = DEST_AUTOMATIC; - - optional UsbPortStatusProto.PowerRole power_role = 1; - optional UsbPortStatusProto.DataRole data_role = 2; -} - -message UsbAlsaManagerProto { - option (android.msg_privacy).dest = DEST_AUTOMATIC; - - optional int32 cards_parser = 1; - repeated UsbAlsaDeviceProto alsa_devices = 2; - repeated UsbMidiDeviceProto midi_devices = 3; -} - -message UsbAlsaDeviceProto { - option (android.msg_privacy).dest = DEST_AUTOMATIC; - - optional int32 card = 1; - optional int32 device = 2; - optional string name = 3; - optional bool has_playback = 4; - optional bool has_capture = 5; - // usb device's address, e.g. 001/002, nothing about the phone - optional string address = 6; -} - -message UsbMidiDeviceProto { - option (android.msg_privacy).dest = DEST_AUTOMATIC; - - optional int32 card = 1; - optional int32 device = 2; - // usb device's address, e.g. 001/002, nothing about the phone - optional string device_address = 3; -} - -message UsbSettingsManagerProto { - option (android.msg_privacy).dest = DEST_AUTOMATIC; - - repeated UsbUserSettingsManagerProto user_settings = 1; - repeated UsbProfileGroupSettingsManagerProto profile_group_settings = 2; -} - -message UsbUserSettingsManagerProto { - option (android.msg_privacy).dest = DEST_AUTOMATIC; - - optional int32 user_id = 1; - reserved 2; // previously device_permissions, now unused - reserved 3; // previously accessory_permissions, now unused - repeated UsbDeviceAttachedActivities device_attached_activities = 4; - repeated UsbAccessoryAttachedActivities accessory_attached_activities = 5; -} - -message UsbProfileGroupSettingsManagerProto { - option (android.msg_privacy).dest = DEST_AUTOMATIC; - - // The user id of the personal profile if the device has a work profile. - optional int32 parent_user_id = 1; - repeated UsbSettingsDevicePreferenceProto device_preferences = 2; - repeated UsbSettingsAccessoryPreferenceProto accessory_preferences = 3; -} - -message UsbSettingsDevicePreferenceProto { - option (android.msg_privacy).dest = DEST_AUTOMATIC; - - optional UsbDeviceFilterProto filter = 1; - optional UserPackageProto user_package = 2; -} - -message UsbPermissionsManagerProto { - option (android.msg_privacy).dest = DEST_AUTOMATIC; - - repeated UsbUserPermissionsManagerProto user_permissions = 1; -} - -message UsbUserPermissionsManagerProto { - option (android.msg_privacy).dest = DEST_AUTOMATIC; - - optional int32 user_id = 1; - - repeated UsbDevicePermissionProto device_permissions = 2; - repeated UsbAccessoryPermissionProto accessory_permissions = 3; - - repeated UsbDevicePersistentPermissionProto device_persistent_permissions = 4; - repeated UsbAccessoryPersistentPermissionProto accessory_persistent_permissions = 5; -} - -message UsbDevicePermissionProto { - option (android.msg_privacy).dest = DEST_AUTOMATIC; - - // Name of device set by manufacturer - // All devices of the same model have the same name - optional string device_name = 1; - repeated int32 uids = 2; -} - -message UsbAccessoryPermissionProto { - option (android.msg_privacy).dest = DEST_AUTOMATIC; - - // Description of accessory set by manufacturer - // All accessories of the same model have the same description - optional string accessory_description = 1; - repeated int32 uids = 2; -} - -message UsbDevicePersistentPermissionProto { - option (android.msg_privacy).dest = DEST_AUTOMATIC; - - optional UsbDeviceFilterProto device_filter = 1; - repeated UsbUidPermissionProto permission_values = 2; -} - -message UsbAccessoryPersistentPermissionProto { - option (android.msg_privacy).dest = DEST_AUTOMATIC; - - optional UsbAccessoryFilterProto accessory_filter = 1; - repeated UsbUidPermissionProto permission_values = 2; -} - -message UsbUidPermissionProto { - option (android.msg_privacy).dest = DEST_AUTOMATIC; - - optional int32 uid = 1; - optional bool is_granted = 2; -} - -message UsbDeviceFilterProto { - option (android.msg_privacy).dest = DEST_AUTOMATIC; - - // Mirrors the vendor_id of UsbDeviceProto. - optional int32 vendor_id = 1; - optional int32 product_id = 2; - optional int32 class = 3; - optional int32 subclass = 4; - optional int32 protocol = 5; - optional string manufacturer_name = 6; - optional string product_name = 7; - optional string serial_number = 8 [ (android.privacy).dest = DEST_EXPLICIT ]; -} - -message UserPackageProto { - option (android.msg_privacy).dest = DEST_AUTOMATIC; - - optional int32 user_id = 1; - optional string package_name =2; -} - -message UsbSettingsAccessoryPreferenceProto { - option (android.msg_privacy).dest = DEST_AUTOMATIC; - - optional UsbAccessoryFilterProto filter = 1; - optional UserPackageProto user_package = 2; -} - -message UsbAccessoryFilterProto { - option (android.msg_privacy).dest = DEST_AUTOMATIC; - - optional string manufacturer = 1; - optional string model = 2; - optional string version = 3; -} - -message UsbDeviceAttachedActivities { - option (android.msg_privacy).dest = DEST_AUTOMATIC; - - optional android.content.ComponentNameProto activity = 1; - repeated UsbDeviceFilterProto filters = 2; -} - -message UsbAccessoryAttachedActivities { - option (android.msg_privacy).dest = DEST_AUTOMATIC; - - optional android.content.ComponentNameProto activity = 1; - repeated UsbAccessoryFilterProto filters = 2; -} diff --git a/core/proto/android/stats/camera/Android.bp b/core/proto/android/stats/camera/Android.bp deleted file mode 100644 index cc75e57af87b..000000000000 --- a/core/proto/android/stats/camera/Android.bp +++ /dev/null @@ -1,33 +0,0 @@ -// 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. - -java_library { - name: "cameraprotosnano", - proto: { - type: "nano", - }, - srcs: [ - "*.proto", - ], - java_version: "1.8", - target: { - android: { - jarjar_rules: "jarjar-rules.txt", - }, - host: { - static_libs: ["libprotobuf-java-nano"], - } - }, - sdk_version: "core_platform", -} diff --git a/core/proto/android/stats/camera/camera.proto b/core/proto/android/stats/camera/camera.proto deleted file mode 100644 index 406285551d98..000000000000 --- a/core/proto/android/stats/camera/camera.proto +++ /dev/null @@ -1,44 +0,0 @@ -/* - * 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. - */ - -syntax = "proto2"; -package android.stats.camera; -option java_multiple_files = true; - -message CameraStreamProto { - // The stream width (in pixels) - optional int32 width = 1; - // The stream height (in pixels) - optional int32 height = 2; - // The format of the stream - optional int32 format = 3; - // The dataspace of the stream - optional int32 data_space = 4; - // The usage flag of the stream - optional int64 usage = 5; - - // The number of requests for this stream - optional int64 request_count = 6; - // The number of buffer error for this stream - optional int64 error_count = 7; - // The capture latency of first request for this stream - optional int32 first_capture_latency_millis = 8; - - // The maximum number of hal buffers - optional int32 max_hal_buffers = 9; - // The maximum number of app buffers - optional int32 max_app_buffers = 10; -} diff --git a/core/proto/android/stats/camera/jarjar-rules.txt b/core/proto/android/stats/camera/jarjar-rules.txt deleted file mode 100644 index 40043a861ceb..000000000000 --- a/core/proto/android/stats/camera/jarjar-rules.txt +++ /dev/null @@ -1 +0,0 @@ -rule com.google.protobuf.nano.** com.android.framework.protobuf.nano.@1 diff --git a/core/proto/android/stats/connectivity/Android.bp b/core/proto/android/stats/connectivity/Android.bp deleted file mode 100644 index 5e6ac3cd3ca1..000000000000 --- a/core/proto/android/stats/connectivity/Android.bp +++ /dev/null @@ -1,38 +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. - -java_library_static { - name: "networkstackprotos", - proto: { - type: "lite", - }, - srcs: [ - "network_stack.proto", - ], - sdk_version: "system_29", -} - -java_library_static { - name: "tetheringprotos", - proto: { - type: "lite", - }, - srcs: [ - "tethering.proto", - ], - apex_available: [ - "com.android.tethering", - ], - sdk_version: "system_current", -} diff --git a/core/proto/android/stats/connectivity/network_stack.proto b/core/proto/android/stats/connectivity/network_stack.proto deleted file mode 100644 index e9726d7ce195..000000000000 --- a/core/proto/android/stats/connectivity/network_stack.proto +++ /dev/null @@ -1,180 +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. - */ - -syntax = "proto2"; - -package android.stats.connectivity; -option java_multiple_files = true; -option java_outer_classname = "NetworkStackProto"; - -enum DhcpRenewResult { - RR_UNKNOWN = 0; - RR_SUCCESS = 1; - RR_ERROR_NAK = 2; - RR_ERROR_IP_MISMATCH = 3; - RR_ERROR_IP_EXPIRE = 4; -} - -enum DisconnectCode { - DC_NONE = 0; - DC_NORMAL_TERMINATION = 1; - DC_PROVISIONING_FAIL = 2; - DC_ERROR_STARTING_IPV4 = 4; - DC_ERROR_STARTING_IPV6 = 5; - DC_ERROR_STARTING_IPREACHABILITYMONITOR = 6; - DC_INVALID_PROVISIONING = 7; - DC_INTERFACE_NOT_FOUND = 8; - DC_PROVISIONING_TIMEOUT = 9; -} - -enum TransportType { - TT_UNKNOWN = 0; - // Indicates this network uses a Cellular transport - TT_CELLULAR = 1; - // Indicates this network uses a Wi-Fi transport - TT_WIFI = 2; - // Indicates this network uses a Bluetooth transport - TT_BLUETOOTH = 3; - // Indicates this network uses an Ethernet transport - TT_ETHERNET = 4; - // Indicates this network uses a Wi-Fi Aware transport - TT_WIFI_AWARE = 5; - // Indicates this network uses a LoWPAN transport - TT_LOWPAN = 6; - // Indicates this network uses a Cellular+VPN transport - TT_CELLULAR_VPN = 7; - // Indicates this network uses a Wi-Fi+VPN transport - TT_WIFI_VPN = 8; - // Indicates this network uses a Bluetooth+VPN transport - TT_BLUETOOTH_VPN = 9; - // Indicates this network uses an Ethernet+VPN transport - TT_ETHERNET_VPN = 10; - // Indicates this network uses a Wi-Fi+Cellular+VPN transport - TT_WIFI_CELLULAR_VPN = 11; - // Indicates this network uses for test only - TT_TEST = 12; -} - -enum DhcpFeature { - DF_UNKNOWN = 0; - // DHCP INIT-REBOOT state - DF_INITREBOOT = 1; - // DHCP rapid commit option - DF_RAPIDCOMMIT = 2; - // Duplicate address detection - DF_DAD = 3; - // Fast initial Link setup - DF_FILS = 4; -} - -enum HostnameTransResult { - HTR_UNKNOWN = 0; - HTR_SUCCESS = 1; - HTR_FAILURE = 2; - HTR_DISABLE = 3; -} - -enum ProbeResult { - PR_UNKNOWN = 0; - PR_SUCCESS = 1; - PR_FAILURE = 2; - PR_PORTAL = 3; - // DNS query for the probe host returned a private IP address - PR_PRIVATE_IP_DNS = 4; -} - -enum ValidationResult { - VR_UNKNOWN = 0; - VR_SUCCESS = 1; - VR_FAILURE = 2; - VR_PORTAL = 3; - VR_PARTIAL = 4; -} - -enum ProbeType { - PT_UNKNOWN = 0; - PT_DNS = 1; - PT_HTTP = 2; - PT_HTTPS = 3; - PT_PAC = 4; - PT_FALLBACK = 5; - PT_PRIVDNS = 6; - PT_CAPPORT_API = 7; -} - -// The Dhcp error code is defined in android.net.metrics.DhcpErrorEvent -enum DhcpErrorCode { - ET_UNKNOWN = 0; - ET_L2_ERROR = 1; - ET_L3_ERROR = 2; - ET_L4_ERROR = 3; - ET_DHCP_ERROR = 4; - ET_MISC_ERROR = 5; - /* Reserve for error type - // ET_L2_ERROR_TYPE = ET_L2_ERROR << 8; - ET_L2_ERROR_TYPE = 256; - // ET_L3_ERROR_TYPE = ET_L3_ERROR << 8; - ET_L3_ERROR_TYPE = 512; - // ET_L4_ERROR_TYPE = ET_L4_ERROR << 8; - ET_L4_ERROR_TYPE = 768; - // ET_DHCP_ERROR_TYPE = ET_DHCP_ERROR << 8; - ET_DHCP_ERROR_TYPE = 1024; - // ET_MISC_ERROR_TYPE = ET_MISC_ERROR << 8; - ET_MISC_ERROR_TYPE = 1280; - */ - // ET_L2_TOO_SHORT = (ET_L2_ERROR_TYPE | 0x1) << 16; - ET_L2_TOO_SHORT = 16842752; - // ET_L2_WRONG_ETH_TYPE = (ET_L2_ERROR_TYPE | 0x2) << 16; - ET_L2_WRONG_ETH_TYPE = 16908288; - // ET_L3_TOO_SHORT = (ET_L3_ERROR_TYPE | 0x1) << 16; - ET_L3_TOO_SHORT = 33619968; - // ET_L3_NOT_IPV4 = (ET_L3_ERROR_TYPE | 0x2) << 16; - ET_L3_NOT_IPV4 = 33685504; - // ET_L3_INVALID_IP = (ET_L3_ERROR_TYPE | 0x3) << 16; - ET_L3_INVALID_IP = 33751040; - // ET_L4_NOT_UDP = (ET_L4_ERROR_TYPE | 0x1) << 16; - ET_L4_NOT_UDP = 50397184; - // ET_L4_WRONG_PORT = (ET_L4_ERROR_TYPE | 0x2) << 16; - ET_L4_WRONG_PORT = 50462720; - // ET_BOOTP_TOO_SHORT = (ET_DHCP_ERROR_TYPE | 0x1) << 16; - ET_BOOTP_TOO_SHORT = 67174400; - // ET_DHCP_BAD_MAGIC_COOKIE = (ET_DHCP_ERROR_TYPE | 0x2) << 16; - ET_DHCP_BAD_MAGIC_COOKIE = 67239936; - // ET_DHCP_INVALID_OPTION_LENGTH = (ET_DHCP_ERROR_TYPE | 0x3) << 16; - ET_DHCP_INVALID_OPTION_LENGTH = 67305472; - // ET_DHCP_NO_MSG_TYPE = (ET_DHCP_ERROR_TYPE | 0x4) << 16; - ET_DHCP_NO_MSG_TYPE = 67371008; - // ET_DHCP_UNKNOWN_MSG_TYPE = (ET_DHCP_ERROR_TYPE | 0x5) << 16; - ET_DHCP_UNKNOWN_MSG_TYPE = 67436544; - // ET_DHCP_NO_COOKIE = (ET_DHCP_ERROR_TYPE | 0x6) << 16; - ET_DHCP_NO_COOKIE = 67502080; - // ET_BUFFER_UNDERFLOW = (ET_MISC_ERROR_TYPE | 0x1) << 16; - ET_BUFFER_UNDERFLOW = 83951616; - // ET_RECEIVE_ERROR = (ET_MISC_ERROR_TYPE | 0x2) << 16; - ET_RECEIVE_ERROR = 84017152; - // ET_PARSING_ERROR = (ET_MISC_ERROR_TYPE | 0x3) << 16; - ET_PARSING_ERROR = 84082688; -} - -enum NetworkQuirkEvent { - QE_UNKNOWN = 0; - QE_IPV6_PROVISIONING_ROUTER_LOST = 1; -} - -message NetworkStackEventData { - -} - diff --git a/core/proto/android/stats/connectivity/tethering.proto b/core/proto/android/stats/connectivity/tethering.proto deleted file mode 100644 index 13f0b8c44fb5..000000000000 --- a/core/proto/android/stats/connectivity/tethering.proto +++ /dev/null @@ -1,97 +0,0 @@ -/* - * 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. - */ -syntax = "proto2"; -package android.stats.connectivity; -option java_multiple_files = true; -option java_outer_classname = "TetheringProto"; - -enum ErrorCode { - EC_NO_ERROR = 0; - EC_UNKNOWN_IFACE = 1; - EC_SERVICE_UNAVAIL = 2; - EC_UNSUPPORTED = 3; - EC_UNAVAIL_IFACE = 4; - EC_INTERNAL_ERROR = 5; - EC_TETHER_IFACE_ERROR = 6; - EC_UNTETHER_IFACE_ERROR = 7; - EC_ENABLE_FORWARDING_ERROR = 8; - EC_DISABLE_FORWARDING_ERROR = 9; - EC_IFACE_CFG_ERROR = 10; - EC_PROVISIONING_FAILED = 11; - EC_DHCPSERVER_ERROR = 12; - EC_ENTITLEMENT_UNKNOWN = 13; - EC_NO_CHANGE_TETHERING_PERMISSION = 14; - EC_NO_ACCESS_TETHERING_PERMISSION = 15; - EC_UNKNOWN_TYPE = 16; -} - -enum DownstreamType { - // Unspecific tethering type. - DS_UNSPECIFIED = 0; - // Wifi tethering type. - DS_TETHERING_WIFI = 1; - // USB tethering type. - DS_TETHERING_USB = 2; - // Bluetooth tethering type. - DS_TETHERING_BLUETOOTH = 3; - // Wifi P2p tethering type. - DS_TETHERING_WIFI_P2P = 4; - // NCM (Network Control Model) local tethering type. - DS_TETHERING_NCM = 5; - // Ethernet tethering type. - DS_TETHERING_ETHERNET = 6; -} - -enum UpstreamType { - UT_UNKNOWN = 0; - // Indicates upstream using a Cellular transport. - UT_CELLULAR = 1; - // Indicates upstream using a Wi-Fi transport. - UT_WIFI = 2; - // Indicates upstream using a Bluetooth transport. - UT_BLUETOOTH = 3; - // Indicates upstream using an Ethernet transport. - UT_ETHERNET = 4; - // Indicates upstream using a Wi-Fi Aware transport. - UT_WIFI_AWARE = 5; - // Indicates upstream using a LoWPAN transport. - UT_LOWPAN = 6; - // Indicates upstream using a Cellular+VPN transport. - UT_CELLULAR_VPN = 7; - // Indicates upstream using a Wi-Fi+VPN transport. - UT_WIFI_VPN = 8; - // Indicates upstream using a Bluetooth+VPN transport. - UT_BLUETOOTH_VPN = 9; - // Indicates upstream using an Ethernet+VPN transport. - UT_ETHERNET_VPN = 10; - // Indicates upstream using a Wi-Fi+Cellular+VPN transport. - UT_WIFI_CELLULAR_VPN = 11; - // Indicates upstream using for test only. - UT_TEST = 12; - // Indicates upstream using DUN capability + Cellular transport. - UT_DUN_CELLULAR = 13; -} - -enum UserType { - // Unknown. - USER_UNKNOWN = 0; - // Settings. - USER_SETTINGS = 1; - // System UI. - USER_SYSTEMUI = 2; - // Google mobile service. - USER_GMS = 3; -} diff --git a/core/proto/android/stats/devicepolicy/Android.bp b/core/proto/android/stats/devicepolicy/Android.bp deleted file mode 100644 index 5fb278a34dae..000000000000 --- a/core/proto/android/stats/devicepolicy/Android.bp +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (C) 2018 The Android Open Source Project -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -java_library_static { - name: "devicepolicyprotosnano", - proto: { - type: "nano", - }, - srcs: [ - "*.proto", - ], - java_version: "1.8", - target: { - android: { - jarjar_rules: "jarjar-rules.txt", - }, - host: { - static_libs: ["libprotobuf-java-nano"], - } - }, - sdk_version: "core_platform", -} diff --git a/core/proto/android/stats/devicepolicy/device_policy_enums.proto b/core/proto/android/stats/devicepolicy/device_policy_enums.proto deleted file mode 100644 index 7c1a04944d68..000000000000 --- a/core/proto/android/stats/devicepolicy/device_policy_enums.proto +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -syntax = "proto2"; - -package android.stats.devicepolicy; -option java_multiple_files = true; - -/** - * Id for device policy features. - */ -enum EventId { - SET_PASSWORD_QUALITY = 1; - SET_PASSWORD_MINIMUM_LENGTH = 2; - SET_PASSWORD_MINIMUM_NUMERIC = 3; - SET_PASSWORD_MINIMUM_NON_LETTER = 4; - SET_PASSWORD_MINIMUM_LETTERS = 5; - SET_PASSWORD_MINIMUM_LOWER_CASE = 6; - SET_PASSWORD_MINIMUM_UPPER_CASE = 7; - SET_PASSWORD_MINIMUM_SYMBOLS = 8; - SET_KEYGUARD_DISABLED_FEATURES = 9; - LOCK_NOW = 10; - WIPE_DATA_WITH_REASON = 11; - ADD_USER_RESTRICTION = 12; - REMOVE_USER_RESTRICTION = 13; - SET_SECURE_SETTING = 14; - SET_SECURITY_LOGGING_ENABLED = 15; - RETRIEVE_SECURITY_LOGS = 16; - RETRIEVE_PRE_REBOOT_SECURITY_LOGS = 17; - SET_PERMISSION_POLICY = 18; - SET_PERMISSION_GRANT_STATE = 19; - INSTALL_KEY_PAIR = 20; - INSTALL_CA_CERT = 21; - CHOOSE_PRIVATE_KEY_ALIAS = 22; - REMOVE_KEY_PAIR = 23; - UNINSTALL_CA_CERTS = 24; - SET_CERT_INSTALLER_PACKAGE = 25; - SET_ALWAYS_ON_VPN_PACKAGE = 26; - SET_PERMITTED_INPUT_METHODS = 27; - SET_PERMITTED_ACCESSIBILITY_SERVICES = 28; - SET_SCREEN_CAPTURE_DISABLED = 29; - SET_CAMERA_DISABLED = 30; - QUERY_SUMMARY_FOR_USER = 31; - QUERY_SUMMARY = 32; - QUERY_DETAILS = 33; - REBOOT = 34; - SET_MASTER_VOLUME_MUTED = 35; - SET_AUTO_TIME_REQUIRED = 36; - SET_KEYGUARD_DISABLED = 37; - SET_STATUS_BAR_DISABLED = 38; - SET_ORGANIZATION_COLOR = 39; - SET_PROFILE_NAME = 40; - SET_USER_ICON = 41; - SET_DEVICE_OWNER_LOCK_SCREEN_INFO = 42; - SET_SHORT_SUPPORT_MESSAGE = 43; - SET_LONG_SUPPORT_MESSAGE = 44; - SET_CROSS_PROFILE_CONTACTS_SEARCH_DISABLED = 45; - SET_CROSS_PROFILE_CALLER_ID_DISABLED = 46; - SET_BLUETOOTH_CONTACT_SHARING_DISABLED = 47; - ADD_CROSS_PROFILE_INTENT_FILTER = 48; - ADD_CROSS_PROFILE_WIDGET_PROVIDER = 49; - SET_SYSTEM_UPDATE_POLICY = 50; - SET_LOCKTASK_MODE_ENABLED = 51; - ADD_PERSISTENT_PREFERRED_ACTIVITY = 52; - REQUEST_BUGREPORT = 53; - GET_WIFI_MAC_ADDRESS = 54; - REQUEST_QUIET_MODE_ENABLED = 55; - WORK_PROFILE_LOCATION_CHANGED = 56; - DO_USER_INFO_CLICKED = 57; - TRANSFER_OWNERSHIP = 58; - GENERATE_KEY_PAIR = 59; - SET_KEY_PAIR_CERTIFICATE = 60; - SET_KEEP_UNINSTALLED_PACKAGES = 61; - SET_APPLICATION_RESTRICTIONS = 62; - SET_APPLICATION_HIDDEN = 63; - ENABLE_SYSTEM_APP = 64; - ENABLE_SYSTEM_APP_WITH_INTENT = 65; - INSTALL_EXISTING_PACKAGE = 66; - SET_UNINSTALL_BLOCKED = 67; - SET_PACKAGES_SUSPENDED = 68; - ON_LOCK_TASK_MODE_ENTERING = 69; - SET_CROSS_PROFILE_CALENDAR_PACKAGES = 70; - GET_USER_PASSWORD_COMPLEXITY_LEVEL = 72; - INSTALL_SYSTEM_UPDATE = 73; - INSTALL_SYSTEM_UPDATE_ERROR = 74; - IS_MANAGED_KIOSK = 75; - IS_UNATTENDED_MANAGED_KIOSK = 76; - PROVISIONING_MANAGED_PROFILE_ON_FULLY_MANAGED_DEVICE = 77; - PROVISIONING_PERSISTENT_DEVICE_OWNER = 78; - - // existing Tron logs to be migrated to statsd - PROVISIONING_ENTRY_POINT_NFC = 79; - PROVISIONING_ENTRY_POINT_QR_CODE = 80; - PROVISIONING_ENTRY_POINT_CLOUD_ENROLLMENT = 81; - PROVISIONING_ENTRY_POINT_ADB = 82; - PROVISIONING_ENTRY_POINT_TRUSTED_SOURCE = 83; - PROVISIONING_DPC_PACKAGE_NAME = 84; - PROVISIONING_DPC_INSTALLED_BY_PACKAGE = 85; - PROVISIONING_PROVISIONING_ACTIVITY_TIME_MS = 86; - PROVISIONING_PREPROVISIONING_ACTIVITY_TIME_MS = 87; - PROVISIONING_ENCRYPT_DEVICE_ACTIVITY_TIME_MS = 88; - PROVISIONING_WEB_ACTIVITY_TIME_MS = 89; - PROVISIONING_TRAMPOLINE_ACTIVITY_TIME_MS = 90 [deprecated=true]; - PROVISIONING_POST_ENCRYPTION_ACTIVITY_TIME_MS = 91 [deprecated=true]; - PROVISIONING_FINALIZATION_ACTIVITY_TIME_MS = 92 [deprecated=true]; - PROVISIONING_NETWORK_TYPE = 93; - PROVISIONING_ACTION = 94; - PROVISIONING_EXTRAS = 95; - PROVISIONING_COPY_ACCOUNT_TASK_MS = 96; - PROVISIONING_CREATE_PROFILE_TASK_MS = 97; - PROVISIONING_START_PROFILE_TASK_MS = 98; - PROVISIONING_DOWNLOAD_PACKAGE_TASK_MS = 99; - PROVISIONING_INSTALL_PACKAGE_TASK_MS = 100; - PROVISIONING_CANCELLED = 101; - PROVISIONING_ERROR = 102; - PROVISIONING_COPY_ACCOUNT_STATUS = 103; - PROVISIONING_TOTAL_TASK_TIME_MS = 104; - PROVISIONING_SESSION_STARTED = 105; - PROVISIONING_SESSION_COMPLETED = 106; - PROVISIONING_TERMS_ACTIVITY_TIME_MS = 107; - PROVISIONING_TERMS_COUNT = 108; - PROVISIONING_TERMS_READ = 109; - - SEPARATE_PROFILE_CHALLENGE_CHANGED = 110; - SET_GLOBAL_SETTING = 111; - INSTALL_PACKAGE = 112; - UNINSTALL_PACKAGE = 113; - WIFI_SERVICE_ADD_NETWORK_SUGGESTIONS = 114; - WIFI_SERVICE_ADD_OR_UPDATE_NETWORK = 115; - QUERY_SUMMARY_FOR_DEVICE = 116; - REMOVE_CROSS_PROFILE_WIDGET_PROVIDER = 117; - ESTABLISH_VPN = 118; - SET_NETWORK_LOGGING_ENABLED = 119; - RETRIEVE_NETWORK_LOGS = 120; - PROVISIONING_PREPARE_TOTAL_TIME_MS = 121; - PROVISIONING_PREPARE_STARTED = 122; - PROVISIONING_PREPARE_COMPLETED = 123; - PROVISIONING_FLOW_TYPE = 124; - CROSS_PROFILE_APPS_GET_TARGET_USER_PROFILES = 125; - CROSS_PROFILE_APPS_START_ACTIVITY_AS_USER = 126; - SET_AUTO_TIME = 127; - SET_AUTO_TIME_ZONE = 128; - SET_USER_CONTROL_DISABLED_PACKAGES = 129; - SET_FACTORY_RESET_PROTECTION = 130; - SET_COMMON_CRITERIA_MODE = 131; - ALLOW_MODIFICATION_OF_ADMIN_CONFIGURED_NETWORKS = 132; - SET_TIME = 133; - SET_TIME_ZONE = 134; - SET_PERSONAL_APPS_SUSPENDED = 135; - SET_MANAGED_PROFILE_MAXIMUM_TIME_OFF = 136; - COMP_TO_ORG_OWNED_PO_MIGRATED = 137; - SET_CROSS_PROFILE_PACKAGES = 138; - SET_INTERACT_ACROSS_PROFILES_APP_OP = 139; - GET_CROSS_PROFILE_PACKAGES = 140; - CAN_REQUEST_INTERACT_ACROSS_PROFILES_TRUE = 141; - CAN_REQUEST_INTERACT_ACROSS_PROFILES_FALSE_NO_PROFILES = 142; - CAN_REQUEST_INTERACT_ACROSS_PROFILES_FALSE_WHITELIST = 143; - CAN_REQUEST_INTERACT_ACROSS_PROFILES_FALSE_PERMISSION = 144; - CAN_INTERACT_ACROSS_PROFILES_TRUE = 145; - CAN_INTERACT_ACROSS_PROFILES_FALSE_PERMISSION = 146; - CAN_INTERACT_ACROSS_PROFILES_FALSE_NO_PROFILES = 147; - CREATE_CROSS_PROFILE_INTENT = 148; - IS_MANAGED_PROFILE = 149; - START_ACTIVITY_BY_INTENT = 150; - BIND_CROSS_PROFILE_SERVICE = 151; - PROVISIONING_DPC_SETUP_STARTED = 152; - PROVISIONING_DPC_SETUP_COMPLETED = 153; - PROVISIONING_ORGANIZATION_OWNED_MANAGED_PROFILE = 154; - RESOLVER_CROSS_PROFILE_TARGET_OPENED = 155; - RESOLVER_SWITCH_TABS = 156; - RESOLVER_EMPTY_STATE_WORK_APPS_DISABLED = 157; - RESOLVER_EMPTY_STATE_NO_SHARING_TO_PERSONAL= 158; - RESOLVER_EMPTY_STATE_NO_SHARING_TO_WORK= 159; - RESOLVER_EMPTY_STATE_NO_APPS_RESOLVED= 160; - RESOLVER_AUTOLAUNCH_CROSS_PROFILE_TARGET = 161; - CROSS_PROFILE_SETTINGS_PAGE_LAUNCHED_FROM_APP = 162; - CROSS_PROFILE_SETTINGS_PAGE_LAUNCHED_FROM_SETTINGS = 163; - CROSS_PROFILE_SETTINGS_PAGE_ADMIN_RESTRICTED = 164; - CROSS_PROFILE_SETTINGS_PAGE_MISSING_WORK_APP = 165; - CROSS_PROFILE_SETTINGS_PAGE_MISSING_PERSONAL_APP = 166; - CROSS_PROFILE_SETTINGS_PAGE_MISSING_INSTALL_BANNER_INTENT = 167; - CROSS_PROFILE_SETTINGS_PAGE_INSTALL_BANNER_CLICKED = 168; - CROSS_PROFILE_SETTINGS_PAGE_INSTALL_BANNER_NO_INTENT_CLICKED = 169; - CROSS_PROFILE_SETTINGS_PAGE_USER_CONSENTED = 170; - CROSS_PROFILE_SETTINGS_PAGE_USER_DECLINED_CONSENT = 171; - CROSS_PROFILE_SETTINGS_PAGE_PERMISSION_REVOKED = 172; - DOCSUI_EMPTY_STATE_NO_PERMISSION = 173; - DOCSUI_EMPTY_STATE_QUIET_MODE = 174; - DOCSUI_LAUNCH_OTHER_APP = 175; - DOCSUI_PICK_RESULT = 176; -} diff --git a/core/proto/android/stats/devicepolicy/jarjar-rules.txt b/core/proto/android/stats/devicepolicy/jarjar-rules.txt deleted file mode 100644 index 40043a861ceb..000000000000 --- a/core/proto/android/stats/devicepolicy/jarjar-rules.txt +++ /dev/null @@ -1 +0,0 @@ -rule com.google.protobuf.nano.** com.android.framework.protobuf.nano.@1 diff --git a/core/proto/android/stats/dnsresolver/Android.bp b/core/proto/android/stats/dnsresolver/Android.bp deleted file mode 100644 index 1e8c76314448..000000000000 --- a/core/proto/android/stats/dnsresolver/Android.bp +++ /dev/null @@ -1,24 +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. - -java_library_static { - name: "dnsresolverprotosnano", - proto: { - type: "nano", - }, - srcs: [ - "dns_resolver.proto", - ], - sdk_version: "system_current", -} diff --git a/core/proto/android/stats/dnsresolver/dns_resolver.proto b/core/proto/android/stats/dnsresolver/dns_resolver.proto deleted file mode 100644 index b17d12c9c315..000000000000 --- a/core/proto/android/stats/dnsresolver/dns_resolver.proto +++ /dev/null @@ -1,375 +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. - */ -syntax = "proto2"; -package android.stats.dnsresolver; - -enum EventType { - EVENT_UNKNOWN = 0; - EVENT_GETADDRINFO = 1; - EVENT_GETHOSTBYNAME = 2; - EVENT_GETHOSTBYADDR = 3; - EVENT_RES_NSEND = 4; -} - -// The return value of the DNS resolver for each DNS lookups. -// bionic/libc/include/netdb.h -// system/netd/resolv/include/netd_resolv/resolv.h -enum ReturnCode { - RC_EAI_NO_ERROR = 0; - RC_EAI_ADDRFAMILY = 1; - RC_EAI_AGAIN = 2; - RC_EAI_BADFLAGS = 3; - RC_EAI_FAIL = 4; - RC_EAI_FAMILY = 5; - RC_EAI_MEMORY = 6; - RC_EAI_NODATA = 7; - RC_EAI_NONAME = 8; - RC_EAI_SERVICE = 9; - RC_EAI_SOCKTYPE = 10; - RC_EAI_SYSTEM = 11; - RC_EAI_BADHINTS = 12; - RC_EAI_PROTOCOL = 13; - RC_EAI_OVERFLOW = 14; - RC_RESOLV_INTERNAL_ERROR = 254; - RC_RESOLV_TIMEOUT = 255; - RC_EAI_MAX = 256; -} - -enum NsRcode { - NS_R_NO_ERROR = 0; // No error occurred. - NS_R_FORMERR = 1; // Format error. - NS_R_SERVFAIL = 2; // Server failure. - NS_R_NXDOMAIN = 3; // Name error. - NS_R_NOTIMPL = 4; // Unimplemented. - NS_R_REFUSED = 5; // Operation refused. - // these are for BIND_UPDATE - NS_R_YXDOMAIN = 6; // Name exists - NS_R_YXRRSET = 7; // RRset exists - NS_R_NXRRSET = 8; // RRset does not exist - NS_R_NOTAUTH = 9; // Not authoritative for zone - NS_R_NOTZONE = 10; // Zone of record different from zone section - NS_R_MAX = 11; - // Define rcode=12~15(UNASSIGNED) in rcode enum type. - // Some DNS Servers might return undefined code to devices. - // Without the enum definition, that would be noise for our dashboard. - NS_R_UNASSIGNED12 = 12; // Unassigned - NS_R_UNASSIGNED13 = 13; // Unassigned - NS_R_UNASSIGNED14 = 14; // Unassigned - NS_R_UNASSIGNED15 = 15; // Unassigned - // The following are EDNS extended rcodes - NS_R_BADVERS = 16; - // The following are TSIG errors - // NS_R_BADSIG = 16, - NS_R_BADKEY = 17; - NS_R_BADTIME = 18; - NS_R_INTERNAL_ERROR = 254; - NS_R_TIMEOUT = 255; -} - -// Currently defined type values for resources and queries. -enum NsType { - NS_T_INVALID = 0; // Cookie. - NS_T_A = 1; // Host address. - NS_T_NS = 2; // Authoritative server. - NS_T_MD = 3; // Mail destination. - NS_T_MF = 4; // Mail forwarder. - NS_T_CNAME = 5; // Canonical name. - NS_T_SOA = 6; // Start of authority zone. - NS_T_MB = 7; // Mailbox domain name. - NS_T_MG = 8; // Mail group member. - NS_T_MR = 9; // Mail rename name. - NS_T_NULL = 10; // Null resource record. - NS_T_WKS = 11; // Well known service. - NS_T_PTR = 12; // Domain name pointer. - NS_T_HINFO = 13; // Host information. - NS_T_MINFO = 14; // Mailbox information. - NS_T_MX = 15; // Mail routing information. - NS_T_TXT = 16; // Text strings. - NS_T_RP = 17; // Responsible person. - NS_T_AFSDB = 18; // AFS cell database. - NS_T_X25 = 19; // X_25 calling address. - NS_T_ISDN = 20; // ISDN calling address. - NS_T_RT = 21; // Router. - NS_T_NSAP = 22; // NSAP address. - NS_T_NSAP_PTR = 23; // Reverse NSAP lookup (deprecated). - NS_T_SIG = 24; // Security signature. - NS_T_KEY = 25; // Security key. - NS_T_PX = 26; // X.400 mail mapping. - NS_T_GPOS = 27; // Geographical position (withdrawn). - NS_T_AAAA = 28; // IPv6 Address. - NS_T_LOC = 29; // Location Information. - NS_T_NXT = 30; // Next domain (security). - NS_T_EID = 31; // Endpoint identifier. - NS_T_NIMLOC = 32; // Nimrod Locator. - NS_T_SRV = 33; // Server Selection. - NS_T_ATMA = 34; // ATM Address - NS_T_NAPTR = 35; // Naming Authority PoinTeR - NS_T_KX = 36; // Key Exchange - NS_T_CERT = 37; // Certification record - NS_T_A6 = 38; // IPv6 address (experimental) - NS_T_DNAME = 39; // Non-terminal DNAME - NS_T_SINK = 40; // Kitchen sink (experimentatl) - NS_T_OPT = 41; // EDNS0 option (meta-RR) - NS_T_APL = 42; // Address prefix list (RFC 3123) - NS_T_DS = 43; // Delegation Signer - NS_T_SSHFP = 44; // SSH Fingerprint - NS_T_IPSECKEY = 45; // IPSEC Key - NS_T_RRSIG = 46; // RRset Signature - NS_T_NSEC = 47; // Negative security - NS_T_DNSKEY = 48; // DNS Key - NS_T_DHCID = 49; // Dynamic host configuratin identifier - NS_T_NSEC3 = 50; // Negative security type 3 - NS_T_NSEC3PARAM = 51; // Negative security type 3 parameters - NS_T_HIP = 55; // Host Identity Protocol - NS_T_SPF = 99; // Sender Policy Framework - NS_T_TKEY = 249; // Transaction key - NS_T_TSIG = 250; // Transaction signature. - NS_T_IXFR = 251; // Incremental zone transfer. - NS_T_AXFR = 252; // Transfer zone of authority. - NS_T_MAILB = 253; // Transfer mailbox records. - NS_T_MAILA = 254; // Transfer mail agent records. - NS_T_ANY = 255; // Wildcard match. - NS_T_ZXFR = 256; // BIND-specific, nonstandard. - NS_T_DLV = 32769; // DNSSEC look-aside validatation. - NS_T_MAX = 65536; -} - -enum IpVersion { - IV_UNKNOWN = 0; - IV_IPV4 = 1; - IV_IPV6 = 2; -} - -enum Protocol { - PROTO_UNKNOWN = 0; - PROTO_UDP = 1; - PROTO_TCP = 2; - PROTO_DOT = 3; -} - -enum PrivateDnsModes { - PDM_UNKNOWN = 0; - PDM_OFF = 1; - PDM_OPPORTUNISTIC = 2; - PDM_STRICT = 3; -} - -enum NetworkType { - NT_UNKNOWN = 0; - // Indicates this network uses a Cellular transport. - NT_CELLULAR = 1; - // Indicates this network uses a Wi-Fi transport. - NT_WIFI = 2; - // Indicates this network uses a Bluetooth transport. - NT_BLUETOOTH = 3; - // Indicates this network uses an Ethernet transport. - NT_ETHERNET = 4; - // Indicates this network uses a VPN transport, now deprecated. - NT_VPN = 5 [deprecated=true]; - // Indicates this network uses a Wi-Fi Aware transport. - NT_WIFI_AWARE = 6; - // Indicates this network uses a LoWPAN transport. - NT_LOWPAN = 7; - // Indicates this network uses a Cellular+VPN transport. - NT_CELLULAR_VPN = 8; - // Indicates this network uses a Wi-Fi+VPN transport. - NT_WIFI_VPN = 9; - // Indicates this network uses a Bluetooth+VPN transport. - NT_BLUETOOTH_VPN = 10; - // Indicates this network uses an Ethernet+VPN transport. - NT_ETHERNET_VPN = 11; - // Indicates this network uses a Wi-Fi+Cellular+VPN transport. - NT_WIFI_CELLULAR_VPN = 12; -} - -enum CacheStatus{ - // the cache can't handle that kind of queries. - // or the answer buffer is too small. - CS_UNSUPPORTED = 0; - // the cache doesn't know about this query. - CS_NOTFOUND = 1; - // the cache found the answer. - CS_FOUND = 2; - // Don't do anything on cache. - CS_SKIP = 3; -} - -// The enum LinuxErrno is defined in the following 2 files. -// 1. bionic/libc/kernel/uapi/asm-generic/errno-base.h -// 2. bionic/libc/kernel/uapi/asm-generic/errno.h -enum LinuxErrno { - SYS_NO_ERROR = 0; - SYS_EPERM = 1; // Not super-user - SYS_ENOENT = 2; // No such file or directory - SYS_ESRCH = 3; // No such process - SYS_EINTR = 4; // Interrupted system call - SYS_EIO = 5; // I/O error - SYS_ENXIO = 6; // No such device or address - SYS_E2BIG = 7; // Arg list too long - SYS_ENOEXEC = 8; // Exec format error - SYS_EBADF = 9; // Bad file number - SYS_ECHILD = 10; // No children - SYS_EAGAIN = 11; // No more processes - SYS_ENOMEM = 12; // Not enough core - SYS_EACCES = 13; // Permission denied - SYS_EFAULT = 14; // Bad address - SYS_ENOTBLK = 15; // Block device required - SYS_EBUSY = 16; // Mount device busy - SYS_EEXIST = 17; // File exists - SYS_EXDEV = 18; // Cross-device link - SYS_ENODEV = 19; // No such device - SYS_ENOTDIR = 20; // Not a directory - SYS_EISDIR = 21; // Is a directory - SYS_EINVAL = 22; // Invalid argument - SYS_ENFILE = 23; // Too many open files in system - SYS_EMFILE = 24; // Too many open files - SYS_ENOTTY = 25; // Not a typewriter - SYS_ETXTBSY = 26; // Text file busy - SYS_EFBIG = 27; // File too large - SYS_ENOSPC = 28; // No space left on device - SYS_ESPIPE = 29; // Illegal seek - SYS_EROFS = 30; // Read only file system - SYS_EMLINK = 31; // Too many links - SYS_EPIPE = 32; // Broken pipe - SYS_EDOM = 33; // Math arg out of domain of func - SYS_ERANGE = 34; // Math result not representable - SYS_EDEADLOCK = 35; // File locking deadlock error - SYS_ENAMETOOLONG = 36; // File or path name too long - SYS_ENOLCK = 37; // No record locks available - SYS_ENOSYS = 38; // Function not implemented - SYS_ENOTEMPTY = 39; // Directory not empty - SYS_ELOOP = 40; // Too many symbolic links - SYS_ENOMSG = 42; // No message of desired type - SYS_EIDRM = 43; // Identifier removed - SYS_ECHRNG = 44; // Channel number out of range - SYS_EL2NSYNC = 45; // Level 2 not synchronized - SYS_EL3HLT = 46; // Level 3 halted - SYS_EL3RST = 47; // Level 3 reset - SYS_ELNRNG = 48; // Link number out of range - SYS_EUNATCH = 49; // rotocol driver not attached - SYS_ENOCSI = 50; // No CSI structure available - SYS_EL2HLT = 51; // Level 2 halted - SYS_EBADE = 52; // Invalid exchange - SYS_EBADR = 53; // Invalid request descriptor - SYS_EXFULL = 54; // Exchange full - SYS_ENOANO = 55; // No anode - SYS_EBADRQC = 56; // Invalid request code - SYS_EBADSLT = 57; // Invalid slot - SYS_EBFONT = 59; // Bad font file fmt - SYS_ENOSTR = 60; // Device not a stream - SYS_ENODATA = 61; // No data (for no delay io) - SYS_ETIME = 62; // Timer expired - SYS_ENOSR = 63; // Out of streams resources - SYS_ENONET = 64; // Machine is not on the network - SYS_ENOPKG = 65; // Package not installed - SYS_EREMOTE = 66; // The object is remote - SYS_ENOLINK = 67; // The link has been severed - SYS_EADV = 68; // Advertise error - SYS_ESRMNT = 69; // Srmount error - SYS_ECOMM = 70; // Communication error on send - SYS_EPROTO = 71; // Protocol error - SYS_EMULTIHOP = 72; // Multihop attempted - SYS_EDOTDOT = 73; // Cross mount point (not really error) - SYS_EBADMSG = 74; // Trying to read unreadable message - SYS_EOVERFLOW = 75; // Value too large for defined data type - SYS_ENOTUNIQ = 76; // Given log. name not unique - SYS_EBADFD = 77; // f.d. invalid for this operation - SYS_EREMCHG = 78; // Remote address changed - SYS_ELIBACC = 79; // Can't access a needed shared lib - SYS_ELIBBAD = 80; // Accessing a corrupted shared lib - SYS_ELIBSCN = 81; // .lib section in a.out corrupted - SYS_ELIBMAX = 82; // Attempting to link in too many libs - SYS_ELIBEXEC = 83; // Attempting to exec a shared library - SYS_EILSEQ = 84; - SYS_ERESTART = 85; - SYS_ESTRPIPE = 86; - SYS_EUSERS = 87; - SYS_ENOTSOCK = 88; // Socket operation on non-socket - SYS_EDESTADDRREQ = 89; // Destination address required - SYS_EMSGSIZE = 90; // Message too long - SYS_EPROTOTYPE = 91; // Protocol wrong type for socket - SYS_ENOPROTOOPT = 92; // Protocol not available - SYS_EPROTONOSUPPORT = 93; // Unknown protocol - SYS_ESOCKTNOSUPPORT = 94; // Socket type not supported - SYS_EOPNOTSUPP = 95; // Operation not supported on transport endpoint - SYS_EPFNOSUPPORT = 96; // Protocol family not supported - SYS_EAFNOSUPPORT = 97; // Address family not supported by protocol family - SYS_EADDRINUSE = 98; // Address already in use - SYS_EADDRNOTAVAIL = 99; // Address not available - SYS_ENETDOWN = 100; // Network interface is not configured - SYS_ENETUNREACH = 101; // Network is unreachable - SYS_ENETRESET = 102; - SYS_ECONNABORTED = 103; // Connection aborted - SYS_ECONNRESET = 104; // Connection reset by peer - SYS_ENOBUFS = 105; // No buffer space available - SYS_EISCONN = 106; // Socket is already connected - SYS_ENOTCONN = 107; // Socket is not connected - SYS_ESHUTDOWN = 108; // Can't send after socket shutdown - SYS_ETOOMANYREFS = 109; - SYS_ETIMEDOUT = 110; // Connection timed out - SYS_ECONNREFUSED = 111; // Connection refused - SYS_EHOSTDOWN = 112; // Host is down - SYS_EHOSTUNREACH = 113; // Host is unreachable - SYS_EALREADY = 114; // Socket already connected - SYS_EINPROGRESS = 115; // Connection already in progress - SYS_ESTALE = 116; - SYS_EUCLEAN = 117; - SYS_ENOTNAM = 118; - SYS_ENAVAIL = 119; - SYS_EISNAM = 120; - SYS_EREMOTEIO = 121; - SYS_EDQUOT = 122; - SYS_ENOMEDIUM = 123; // No medium (in tape drive) - SYS_EMEDIUMTYPE = 124; - SYS_ECANCELED = 125; - SYS_ENOKEY = 126; - SYS_EKEYEXPIRED = 127; - SYS_EKEYREVOKED = 128; - SYS_EKEYREJECTED = 129; - SYS_EOWNERDEAD = 130; - SYS_ENOTRECOVERABLE = 131; - SYS_ERFKILL = 132; - SYS_EHWPOISON = 133; -} - -message DnsQueryEvent { - optional android.stats.dnsresolver.NsRcode rcode = 1; - - optional android.stats.dnsresolver.NsType type = 2; - - optional android.stats.dnsresolver.CacheStatus cache_hit = 3; - - optional android.stats.dnsresolver.IpVersion ip_version = 4; - - optional android.stats.dnsresolver.Protocol protocol = 5; - - // Number of DNS query retry times - optional int32 retry_times = 6; - - // Ordinal number of name server. - optional int32 dns_server_index = 7; - - // Used only by TCP and DOT. True for new connections. - optional bool connected = 8; - - optional int32 latency_micros = 9; - - optional android.stats.dnsresolver.LinuxErrno linux_errno = 10; -} - -message DnsQueryEvents { - repeated DnsQueryEvent dns_query_event = 1; -} diff --git a/core/proto/android/stats/docsui/docsui_enums.proto b/core/proto/android/stats/docsui/docsui_enums.proto deleted file mode 100644 index 5963f6a7f938..000000000000 --- a/core/proto/android/stats/docsui/docsui_enums.proto +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -syntax = "proto2"; -package android.stats.docsui; -option java_multiple_files = true; - -enum LaunchAction { - UNKNOWN = 0; - OPEN = 1; - CREATE = 2; - GET_CONTENT = 3; - OPEN_TREE = 4; - PICK_COPY_DEST = 5; - BROWSE = 6; - OTHER = 7; -} - -enum MimeType { - MIME_UNKNOWN = 0; - MIME_NONE = 1; - MIME_ANY = 2; - MIME_APPLICATION = 3; - MIME_AUDIO = 4; - MIME_IMAGE = 5; - MIME_MESSAGE = 6; - MIME_MULTIPART = 7; - MIME_TEXT = 8; - MIME_VIDEO = 9; - MIME_OTHER = 10; -} - -enum Root { - ROOT_UNKNOWN = 0; - ROOT_NONE = 1; - ROOT_OTHER_DOCS_PROVIDER = 2; - ROOT_AUDIO = 3; - ROOT_DEVICE_STORAGE = 4; - ROOT_DOWNLOADS = 5; - ROOT_HOME = 6; - ROOT_IMAGES = 7; - ROOT_RECENTS = 8; - ROOT_VIDEOS = 9; - ROOT_MTP = 10; - ROOT_THIRD_PARTY_APP = 11; - ROOT_DOCUMENTS = 12; -} - -enum ContextScope { - SCOPE_UNKNOWN = 0; - SCOPE_FILES = 1; - SCOPE_PICKER = 2; -} - -enum Provider { - PROVIDER_UNKNOWN = 0; - PROVIDER_SYSTEM = 1; - PROVIDER_EXTERNAL = 2; -} - -enum FileOperation { - OP_UNKNOWN = 0; - OP_OTHER = 1; - OP_COPY = 2; - OP_COPY_INTRA_PROVIDER = 3; - OP_COPY_SYSTEM_PROVIDER = 4; - OP_COPY_EXTERNAL_PROVIDER = 5; - OP_MOVE = 6; - OP_MOVE_INTRA_PROVIDER = 7; - OP_MOVE_SYSTEM_PROVIDER = 8; - OP_MOVE_EXTERNAL_PROVIDER = 9; - OP_DELETE = 10; - OP_RENAME = 11; - OP_CREATE_DIR = 12; - OP_OTHER_ERROR = 13; - OP_DELETE_ERROR = 14; - OP_MOVE_ERROR = 15; - OP_COPY_ERROR = 16; - OP_RENAME_ERROR = 17; - OP_CREATE_DIR_ERROR = 18; - OP_COMPRESS_INTRA_PROVIDER = 19; - OP_COMPRESS_SYSTEM_PROVIDER = 20; - OP_COMPRESS_EXTERNAL_PROVIDER = 21; - OP_EXTRACT_INTRA_PROVIDER = 22; - OP_EXTRACT_SYSTEM_PROVIDER = 23; - OP_EXTRACT_EXTERNAL_PROVIDER = 24; - OP_COMPRESS_ERROR = 25; - OP_EXTRACT_ERROR = 26; -} - -enum SubFileOperation { - SUB_OP_UNKNOWN = 0; - SUB_OP_QUERY_DOC = 1; - SUB_OP_QUERY_CHILD = 2; - SUB_OP_OPEN_FILE = 3; - SUB_OP_READ_FILE = 4; - SUB_OP_CREATE_DOC = 5; - SUB_OP_WRITE_FILE = 6; - SUB_OP_DELETE_DOC = 7; - SUB_OP_OBTAIN_STREAM_TYPE = 8; - SUB_OP_QUICK_MOVE = 9; - SUB_OP_QUICK_COPY = 10; -} - -enum CopyMoveOpMode { - MODE_UNKNOWN = 0; - MODE_PROVIDER = 1; - MODE_CONVERTED = 2; - MODE_CONVENTIONAL = 3; -} - -enum Authority { - AUTH_UNKNOWN = 0; - AUTH_OTHER = 1; - AUTH_MEDIA = 2; - AUTH_STORAGE_INTERNAL = 3; - AUTH_STORAGE_EXTERNAL = 4; - AUTH_DOWNLOADS = 5; - AUTH_MTP = 6; -} - -enum UserAction { - ACTION_UNKNOWN = 0; - ACTION_OTHER = 1; - ACTION_GRID = 2; - ACTION_LIST = 3; - ACTION_SORT_NAME = 4; - ACTION_SORT_DATE = 5; - ACTION_SORT_SIZE = 6; - ACTION_SORT_TYPE = 7; - ACTION_SEARCH = 8; - ACTION_SHOW_SIZE = 9; - ACTION_HIDE_SIZE = 10; - ACTION_SETTINGS = 11; - ACTION_COPY_TO = 12; - ACTION_MOVE_TO = 13; - ACTION_DELETE = 14; - ACTION_RENAME = 15; - ACTION_CREATE_DIR = 16; - ACTION_SELECT_ALL = 17; - ACTION_SHARE = 18; - ACTION_OPEN = 19; - ACTION_SHOW_ADVANCED = 20; - ACTION_HIDE_ADVANCED = 21; - ACTION_NEW_WINDOW = 22; - ACTION_PASTE_CLIPBOARD = 23; - ACTION_COPY_CLIPBOARD = 24; - ACTION_DRAG_N_DROP = 25; - ACTION_DRAG_N_DROP_MULTI_WINDOW = 26; - ACTION_CUT_CLIPBOARD = 27; - ACTION_COMPRESS = 28; - ACTION_EXTRACT_TO = 29; - ACTION_VIEW_IN_APPLICATION = 30; - ACTION_INSPECTOR = 31; - ACTION_SEARCH_CHIP = 32; - ACTION_SEARCH_HISTORY = 33; -} - -enum InvalidScopedAccess { - SCOPED_DIR_ACCESS_UNKNOWN = 0; - SCOPED_DIR_ACCESS_INVALID_ARGUMENTS = 1; - SCOPED_DIR_ACCESS_INVALID_DIRECTORY = 2; - SCOPED_DIR_ACCESS_ERROR = 3; - SCOPED_DIR_ACCESS_DEPRECATED = 4; -} - -enum SearchType { - TYPE_UNKNOWN = 0; - TYPE_CHIP_IMAGES = 1; - TYPE_CHIP_AUDIOS = 2; - TYPE_CHIP_VIDEOS = 3; - TYPE_CHIP_DOCS = 4; - TYPE_SEARCH_HISTORY = 5; - TYPE_SEARCH_STRING = 6; - TYPE_CHIP_LARGE_FILES = 7; - TYPE_CHIP_FROM_THIS_WEEK = 8; -} - -enum SearchMode { - SEARCH_UNKNOWN = 0; - SEARCH_KEYWORD = 1; - SEARCH_CHIPS = 2; - SEARCH_KEYWORD_N_CHIPS = 3; -} diff --git a/core/proto/android/stats/enums.proto b/core/proto/android/stats/enums.proto deleted file mode 100644 index 8f8055ed2451..000000000000 --- a/core/proto/android/stats/enums.proto +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -syntax = "proto2"; - -package android.stats; -option java_outer_classname = "StatsEnums"; - -enum EventType { - // Unknown. - TYPE_UNKNOWN = 0; - CONTENT_SUGGESTIONS_CLASSIFY_CONTENT_CALL_SUCCEEDED = 1; - CONTENT_SUGGESTIONS_CLASSIFY_CONTENT_CALL_FAILED = 2; - CONTENT_SUGGESTIONS_SUGGEST_CONTENT_CALL_SUCCEEDED = 3; - CONTENT_SUGGESTIONS_SUGGEST_CONTENT_CALL_FAILED = 4; -} diff --git a/core/proto/android/stats/hdmi/enums.proto b/core/proto/android/stats/hdmi/enums.proto deleted file mode 100644 index acb8899fbdd9..000000000000 --- a/core/proto/android/stats/hdmi/enums.proto +++ /dev/null @@ -1,122 +0,0 @@ -/* - * 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. - */ - -syntax = "proto2"; - -package android.stats.hdmi; -option java_multiple_files = true; -option java_outer_classname = "HdmiStatsEnums"; - -// HDMI CEC logical addresses. -// Values correspond to "CEC Table 5 Logical Addresses" in the HDMI CEC 1.4b spec. -enum LogicalAddress { - LOGICAL_ADDRESS_UNKNOWN = -1; - TV = 0; - RECORDING_DEVICE_1 = 1; - RECORDING_DEVICE_2 = 2; - TUNER_1 = 3; - PLAYBACK_DEVICE_1 = 4; - AUDIO_SYSTEM = 5; - TUNER_2 = 6; - TUNER_3 = 7; - PLAYBACK_DEVICE_2 = 8; - RECORDING_DEVICE_3 = 9; - TUNER_4 = 10; - PLAYBACK_DEVICE_3 = 11; - RESERVED_1 = 12; - RESERVED_2 = 13; - SPECIFIC_USE = 14; - UNREGISTERED_OR_BROADCAST = 15; -} - -// The relationship between two paths. -// Values correspond exactly to PathRelationship in com.android.server.hdmi.Constants. -enum PathRelationship { - RELATIONSHIP_TO_ACTIVE_SOURCE_UNKNOWN = 0; - DIFFERENT_BRANCH = 1; - ANCESTOR = 2; - DESCENDANT = 3; - SIBLING = 4; - SAME = 5; -} - -// The result of attempting to send a HDMI CEC message. -// Values correspond to the constants in android.hardware.tv.cec.V1_0.SendMessageResult, -// offset by 10. -enum SendMessageResult { - SEND_MESSAGE_RESULT_UNKNOWN = 0; - SUCCESS = 10; - NACK = 11; - BUSY = 12; - FAIL = 13; -} - -// Whether a HDMI CEC message is sent from this device, to this device, or neither. -enum MessageDirection { - MESSAGE_DIRECTION_UNKNOWN = 0; - MESSAGE_DIRECTION_OTHER = 1; // None of the other options. - OUTGOING = 2; // Sent from this device. - INCOMING = 3; // Sent to this device. - TO_SELF = 4; // Sent from this device, to this device. Indicates a bug. -} - -// User control commands. Each value can represent an individual command, or a set of commands. -// Values correspond to "CEC Table 30 UI Command Codes" in the HDMI CEC 1.4b spec, offset by 0x100. -enum UserControlPressedCommand { - USER_CONTROL_PRESSED_COMMAND_UNKNOWN = 0; - - // Represents all codes that are not represented by another value. - USER_CONTROL_PRESSED_COMMAND_OTHER = 1; - - // Represents all number codes (codes 0x1E through 0x29). - NUMBER = 2; - - // Navigation - SELECT = 0x100; - UP = 0x101; - DOWN = 0x102; - LEFT = 0x103; - RIGHT = 0x104; - RIGHT_UP = 0x105; - RIGHT_DOWN = 0x106; - LEFT_UP = 0x107; - LEFT_DOWN = 0x108; - EXIT = 0x10D; - - // Volume - VOLUME_UP = 0x141; - VOLUME_DOWN = 0x142; - VOLUME_MUTE = 0x143; - - // Power - POWER = 0x140; - POWER_TOGGLE = 0x16B; - POWER_OFF = 0x16C; - POWER_ON = 0x16D; -} - -// Reason parameter of the <Feature Abort> message. -// Values correspond to "CEC Table 29 Operand Descriptions" in the HDMI CEC 1.4b spec, -// offset by 10. -enum FeatureAbortReason { - FEATURE_ABORT_REASON_UNKNOWN = 0; - UNRECOGNIZED_OPCODE = 10; - NOT_IN_CORRECT_MODE_TO_RESPOND = 11; - CANNOT_PROVIDE_SOURCE = 12; - INVALID_OPERAND = 13; - REFUSED = 14; - UNABLE_TO_DETERMINE = 15; -}
\ No newline at end of file diff --git a/core/proto/android/stats/intelligence/enums.proto b/core/proto/android/stats/intelligence/enums.proto deleted file mode 100644 index 0c210e3fd08f..000000000000 --- a/core/proto/android/stats/intelligence/enums.proto +++ /dev/null @@ -1,40 +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. - */ - -syntax = "proto2"; - -package android.stats.intelligence; -option java_outer_classname = "IntelligenceStatsEnums"; - -enum Status { - // The value wasn't set. - // protoc requires enum values to be unique by package rather than enum type. - // This forces us to prefix the enum values. - STATUS_UNKNOWN = 0; - // The event succeeded. - STATUS_SUCCEEDED = 1; - // The event had an error. - STATUS_FAILED = 2; -} - -enum EventType { - // The value wasn't set. - EVENT_UNKNOWN = 0; - // ContentSuggestionsService classifyContentSelections call. - EVENT_CONTENT_SUGGESTIONS_CLASSIFY_CONTENT_CALL = 1; - // ContentSuggestionsService suggestContentSelections call. - EVENT_CONTENT_SUGGESTIONS_SUGGEST_CONTENT_CALL = 2; -} diff --git a/core/proto/android/stats/launcher/Android.bp b/core/proto/android/stats/launcher/Android.bp deleted file mode 100644 index 976a0b8634a3..000000000000 --- a/core/proto/android/stats/launcher/Android.bp +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (C) 2018 The Android Open Source Project -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -java_library { - name: "launcherprotosnano", - proto: { - type: "nano", - output_params: ["store_unknown_fields=true"], - include_dirs: ["external/protobuf/src"], - }, - - sdk_version: "current", - srcs: [ - "*.proto", - ], -} - -java_library { - name: "launcherprotoslite", - proto: { - type: "lite", - include_dirs: ["external/protobuf/src"], - }, - - sdk_version: "current", - srcs: [ - "*.proto", - ], -} diff --git a/core/proto/android/stats/launcher/launcher.proto b/core/proto/android/stats/launcher/launcher.proto deleted file mode 100644 index fc177d57b193..000000000000 --- a/core/proto/android/stats/launcher/launcher.proto +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -syntax = "proto2"; -package android.stats.launcher; -option java_multiple_files = true; - -enum LauncherAction { - DEFAULT_ACTION = 0; - LAUNCH_APP = 1; - LAUNCH_TASK = 2; - DISMISS_TASK = 3; - LONGPRESS = 4; - DRAGDROP = 5; - SWIPE_UP = 6; - SWIPE_DOWN = 7; - SWIPE_LEFT = 8; - SWIPE_RIGHT = 9; -} - -enum LauncherState { - LAUNCHER_STATE_UNSPECIFIED = 0; - BACKGROUND = 1; - HOME = 2; - OVERVIEW = 3; - ALLAPPS = 4; - UNCHANGED = 5; -} - -message LauncherTarget { - enum Type { - NONE = 0; - ITEM_TYPE = 1; - CONTROL_TYPE = 2; - CONTAINER_TYPE = 3; - } - enum Item { - DEFAULT_ITEM = 0; - APP_ICON = 1; - SHORTCUT = 2; - WIDGET = 3; - FOLDER_ICON = 4; - DEEPSHORTCUT = 5; - SEARCHBOX = 6; - EDITTEXT = 7; - NOTIFICATION = 8; - TASK = 9; - } - enum Container { - DEFAULT_CONTAINER = 0; - HOTSEAT = 1; - FOLDER = 2; - PREDICTION = 3; - SEARCHRESULT = 4; - } - enum Control { - DEFAULT_CONTROL = 0; - MENU = 1; - UNINSTALL = 2; - REMOVE = 3; - } - optional Type type = 1; - optional Item item = 2; - optional Container container = 3; - optional Control control = 4; - optional string launch_component = 5; - optional int32 page_id = 6; - optional int32 grid_x = 7; - optional int32 grid_y = 8; -} - -message LauncherExtension { - repeated LauncherTarget src_target = 1; - repeated LauncherTarget dst_target = 2; -} diff --git a/core/proto/android/stats/location/location_enums.proto b/core/proto/android/stats/location/location_enums.proto deleted file mode 100644 index 553c01c5d0dd..000000000000 --- a/core/proto/android/stats/location/location_enums.proto +++ /dev/null @@ -1,122 +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. - */ - -syntax = "proto2"; - -package android.stats.location; -option java_outer_classname = "LocationStatsEnums"; - - -// APIs from LocationManagerService -enum LocationManagerServiceApi { - API_UNKNOWN = 0; - API_REQUEST_LOCATION_UPDATES = 1; - API_ADD_GNSS_MEASUREMENTS_LISTENER = 2; - API_REGISTER_GNSS_STATUS_CALLBACK = 3; - API_REQUEST_GEOFENCE = 4; - API_SEND_EXTRA_COMMAND = 5; -} - -enum UsageState { - USAGE_STARTED = 0; - USAGE_ENDED = 1; -} - -// Type of location providers -enum ProviderType { - PROVIDER_UNKNOWN = 0; - PROVIDER_NETWORK = 1; - PROVIDER_GPS = 2; - PROVIDER_PASSIVE = 3; - PROVIDER_FUSED = 4; -} - -// Type of Callback passed in for this API -enum CallbackType { - CALLBACK_UNKNOWN = 0; - // Current API does not need a callback, e.g. sendExtraCommand - CALLBACK_NOT_APPLICABLE = 1; - CALLBACK_LISTENER = 2; - CALLBACK_PENDING_INTENT = 3; -} - -// Possible values for mQuality field in -// frameworks/base/location/java/android/location/LocationRequest.java -enum LocationRequestQuality { - QUALITY_UNKNOWN = 0; - ACCURACY_FINE = 100; - ACCURACY_BLOCK = 102; - ACCURACY_CITY = 104; - POWER_NONE = 200; - POWER_LOW = 201; - POWER_HIGH = 203; -} - -// Bucketized values for interval field in -// frameworks/base/location/java/android/location/LocationRequest.java -enum LocationRequestIntervalBucket { - INTERVAL_UNKNOWN = 0; - INTERVAL_BETWEEN_0_SEC_AND_1_SEC = 1; - INTERVAL_BETWEEN_1_SEC_AND_5_SEC = 2; - INTERVAL_BETWEEN_5_SEC_AND_1_MIN = 3; - INTERVAL_BETWEEN_1_MIN_AND_10_MIN = 4; - INTERVAL_BETWEEN_10_MIN_AND_1_HOUR = 5; - INTERVAL_LARGER_THAN_1_HOUR = 6; -} - -// Bucketized values for small displacement field in -// frameworks/base/location/java/android/location/LocationRequest.java -// Value in meters. -enum SmallestDisplacementBucket { - DISTANCE_UNKNOWN = 0; - DISTANCE_ZERO = 1; - DISTANCE_BETWEEN_0_AND_100 = 2; - DISTANCE_LARGER_THAN_100 = 3; -} - -// Bucketized values for expire_in field in -// frameworks/base/location/java/android/location/LocationRequest.java -enum ExpirationBucket { - EXPIRATION_UNKNOWN = 0; - EXPIRATION_BETWEEN_0_AND_20_SEC = 1; - EXPIRATION_BETWEEN_20_SEC_AND_1_MIN = 2; - EXPIRATION_BETWEEN_1_MIN_AND_10_MIN = 3; - EXPIRATION_BETWEEN_10_MIN_AND_1_HOUR = 4; - EXPIRATION_LARGER_THAN_1_HOUR = 5; - EXPIRATION_NO_EXPIRY = 6; -} - -// Bucketized values for radius field in -// frameworks/base/location/java/android/location/Geofence.java -// Value in meters. -enum GeofenceRadiusBucket { - RADIUS_UNKNOWN = 0; - RADIUS_BETWEEN_0_AND_100 = 1; - RADIUS_BETWEEN_100_AND_200 = 2; - RADIUS_BETWEEN_200_AND_300 = 3; - RADIUS_BETWEEN_300_AND_1000 = 4; - RADIUS_BETWEEN_1000_AND_10000 = 5; - RADIUS_LARGER_THAN_100000 = 6; - RADIUS_NEGATIVE = 7; -} - -// Caller Activity Importance. -enum ActivityImportance { - IMPORTANCE_UNKNOWN = 0; - IMPORTANCE_TOP = 1; - IMPORTANCE_FORGROUND_SERVICE = 2; - IMPORTANCE_BACKGROUND = 3; -} diff --git a/core/proto/android/stats/mediametrics/mediametrics.proto b/core/proto/android/stats/mediametrics/mediametrics.proto deleted file mode 100644 index eb8a3b19f263..000000000000 --- a/core/proto/android/stats/mediametrics/mediametrics.proto +++ /dev/null @@ -1,354 +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. - */ - -syntax = "proto2"; - -package android.stats.mediametrics; - -/** - * Track how we arbitrate between microphone/input requests. - * Logged from - * frameworks/av/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp - * frameworks/av/services/mediaanalytics/statsd_audiopolicy.cpp - * Next Tag: 10 - */ -message AudioPolicyData { - optional int32 status = 1; - optional string request_source = 2; - optional string request_package = 3; - optional int32 request_session = 4; - optional string request_device = 5; - optional string active_source = 6; - optional string active_package = 7; - optional int32 active_session = 8; - optional string active_device = 9; -} - -/** - * Track properties of audio recording - * Logged from - * frameworks/av/media/libaudioclient/AudioRecord.cpp - * frameworks/av/services/mediaanalytics/statsd_audiorecord.cpp - * Next Tag: 16 - */ -message AudioRecordData { - optional string encoding = 1; - optional string source = 2; - optional int32 latency = 3; - optional int32 samplerate = 4; - optional int32 channels = 5; - optional int64 created_millis = 6; - optional int64 duration_millis = 7; - optional int32 count = 8; - optional int32 error_code = 9; - optional string error_function = 10; - optional int32 port_id = 11; - optional int32 frame_count = 12; - optional string attributes = 13; - optional int64 channel_mask = 14; - optional int64 start_count = 15; - -} - -/** - * Track audio thread performance data - * Logged from - * frameworks/av/media/libnblog/ReportPerformance.cpp - * frameworks/av/services/mediaanalytics/statsd_audiothread.cpp - * Next Tag: 28 - */ -message AudioThreadData { - optional string type = 1; - optional int32 framecount = 2; - optional int32 samplerate = 3; - optional string work_millis_hist = 4; - optional string latency_millis_hist = 5; - optional string warmup_millis_hist = 6; - optional int64 underruns = 7; - optional int64 overruns = 8; - optional int64 active_millis = 9; - optional int64 duration_millis = 10; - - optional int32 id = 11; - optional int32 port_id = 12; - optional int32 sample_rate = 13; - optional int64 channel_mask = 14; - optional string encoding = 15; - optional int32 frame_count = 16; - optional string output_device = 17; - optional string input_device = 18; - optional double io_jitter_mean_millis = 19; - optional double io_jitter_stddev_millis = 20; - optional double process_time_mean_millis = 21; - optional double process_time_stddev_millis = 22; - optional double timestamp_jitter_mean_millis = 23; - optional double timestamp_jitter_stddev_millis = 24; - optional double latency_mean_millis = 25; - optional double latency_stddev_millis = 26; - -} - -/** - * Track audio track playback data - * Logged from - * frameworks/av/media/libaudioclient/AudioTrack.cpp - * frameworks/av/services/mediaanalytics/statsd_audiotrack.cpp - * Next Tag: 12 - */ -message AudioTrackData { - optional string stream_type = 1; - optional string content_type = 2; - optional string track_usage = 3; - optional int32 sample_rate = 4; - optional int64 channel_mask = 5; - - optional int32 underrun_frames = 6; - optional int32 startup_glitch = 7; - - optional int32 port_id = 8; - optional string encoding = 9; - optional int32 frame_count = 10; - optional string attributes = 11; - - -} - -/** - * Track Media Codec usage - * Logged from: - * frameworks/av/media/libstagefright/MediaCodec.cpp - * frameworks/av/services/mediaanalytics/statsd_codec.cpp - * Next Tag: 26 - */ -message CodecData { - optional string codec = 1; - optional string mime = 2; - optional string mode = 3; - optional int32 encoder = 4; - optional int32 secure = 5; - optional int32 width = 6; - optional int32 height = 7; - optional int32 rotation = 8; - optional int32 crypto = 9; - optional int32 profile = 10; - optional int32 level = 11; - optional int32 max_width = 12; - optional int32 max_height = 13; - optional int32 error_code = 14; - optional string error_state = 15; - optional int64 latency_max = 16; - optional int64 latency_min = 17; - optional int64 latency_avg = 18; - optional int64 latency_count = 19; - optional int64 latency_unknown = 20; - optional int32 queue_input_buffer_error = 21; - optional int32 queue_secure_input_buffer_error = 22; - optional string bitrate_mode = 23; - optional int32 bitrate = 24; - optional int64 lifetime_millis = 25; -} - -/** - * Track Media Extractor (pulling video/audio streams out of containers) usage - * Logged from: - * frameworks/av/media/libstagefright/RemoteMediaExtractor.cpp - * frameworks/av/services/mediaanalytics/statsd_extractor.cpp - * Next Tag: 5 - */ -message ExtractorData { - optional string format = 1; - optional string mime = 2; - optional int32 tracks = 3; - - enum EntryPoint { - UNSET = 0; // For backwards compatibility with clients that don't - // collect the entry point. - SDK = 1; - NDK_WITH_JVM = 2; - NDK_NO_JVM = 3; - OTHER = 4; // For extractor users that don't make use of the APIs. - } - - optional EntryPoint entry_point = 4 [default = UNSET]; -} - -/** - * Track Media Player usage - * this handles both nuplayer and nuplayer2 - * Logged from: - * frameworks/av/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp - * frameworks/av/media/libmediaplayer2/nuplayer2/NuPlayer2Driver.cpp - * frameworks/av/services/mediaanalytics/statsd_nuplayer.cpp - * Next Tag: 21 - */ -message NuPlayerData { - optional string whichPlayer = 1; - - optional string video_mime = 2; - optional string video_codec = 3; - optional int32 width = 4; - optional int32 height = 5; - optional int64 frames = 6; - optional int64 frames_dropped = 7; - optional double framerate = 8; - optional string audio_mime = 9; - optional string audio_codec = 10; - optional int64 duration_millis = 11; - optional int64 playing_millis = 12; - optional int32 error = 13; - optional int32 error_code = 14; - optional string error_state = 15; - optional string data_source_type = 16; - optional int64 rebuffering_millis = 17; - optional int32 rebuffers = 18; - optional int32 rebuffer_at_exit = 19; - optional int64 frames_dropped_startup = 20; -} - -/** - * Track information about recordings (e.g. camcorder) - * Logged from - * frameworks/av/media/libmediaplayerservice/StagefrightRecorder.cpp - * frameworks/av/services/mediaanalytics/if_statsd.cpp - * Next Tag: 22 - */ -message RecorderData { - optional string audio_mime = 1; - optional string video_mime = 2; - optional int32 video_profile = 3; - optional int32 video_level = 4; - optional int32 width = 5; - optional int32 height = 6; - optional int32 rotation = 7; - optional int32 framerate = 8; - optional int32 capture_fps = 9; - optional double capture_fps_enable = 10; - optional int64 duration_millis = 11; - optional int64 paused_millis = 12; - optional int32 paused_count = 13; - optional int32 audio_bitrate = 14; - optional int32 audio_channels = 15; - optional int32 audio_samplerate = 16; - optional int32 movie_timescale = 17; - optional int32 audio_timescale = 18; - optional int32 video_timescale = 19; - optional int32 video_bitrate = 20; - optional int32 iframe_interval = 21; -} - -enum StreamType { - STREAM_TYPE_UNKNOWN = 0; - STREAM_TYPE_OTHER = 1; - STREAM_TYPE_PROGRESSIVE = 2; - STREAM_TYPE_DASH = 3; - STREAM_TYPE_HLS = 4; - STREAM_TYPE_SS = 5; -} - -enum DrmType { - DRM_TYPE_NONE = 0; - DRM_TYPE_OTHER = 1; - DRM_TYPE_PLAY_READY = 2; - DRM_TYPE_WV_L1 = 3; - DRM_TYPE_WV_L3 = 4; -} - -enum PlaybackType { - PLAYBACK_TYPE_VOD = 0; - PLAYBACK_TYPE_LIVE = 1; - PLAYBACK_TYPE_OTHER = 2; -} - -enum ContentType { - CONTENT_TYPE_MAIN = 0; - CONTENT_TYPE_AD = 1; - CONTENT_TYPE_OTHER = 2; -} - -enum StreamSourceType { - STREAM_SOURCE_UNKNOWN = 0; - STREAM_SOURCE_NETWORK = 1; - STREAM_SOURCE_DEVICE = 2; - STREAM_SOURCE_MIXED = 3; -} -enum NetworkType { - NETWORK_TYPE_NONE = 0; - NETWORK_TYPE_OTHER = 1; - NETWORK_TYPE_WIFI = 2; - NETWORK_TYPE_ETHERNET = 3; - NETWORK_TYPE_2G = 4; - NETWORK_TYPE_3G = 5; - NETWORK_TYPE_4G = 6; - NETWORK_TYPE_5G_NSA = 7; - NETWORK_TYPE_5G_SA = 8; -} - -enum PlaybackState { - // Playback has not started (initial state) - NOT_STARTED = 0; - // Playback is buffering in the background for initial playback start - JOINING_BACKGROUND = 1; - // Playback is buffering in the foreground for initial playback start - JOINING_FOREGROUND = 2; - // Playback is actively playing - PLAYING = 3; - // Playback is paused but ready to play - PAUSED = 4; - // Playback is handling a seek - SEEKING = 5; - // Playback is buffering to resume active playback - BUFFERING = 6; - // Playback is buffering while paused - PAUSED_BUFFERING = 7; - // Playback is suppressed (e.g. due to audio focus loss) - SUPPRESSED = 8; - // Playback is suppressed (e.g. due to audio focus loss) while buffering to resume a - // playback - SUPPRESSED_BUFFERING = 9; - // Playback has reached the end of the media - ENDED = 10; - // Playback is stopped and can be restarted - STOPPED = 11; - // Playback is stopped due a fatal error and can be retried - FAILED = 12; - // Playback is interrupted by an ad - INTERRUPTED_BY_AD = 13; - // Playback is abandoned before reaching the end of the media - ABANDONED = 14; -} - -enum PlaybackErrorCode { - ERROR_CODE_UNKNOWN = 0; - ERROR_CODE_OTHER = 1; - ERROR_CODE_RUNTIME = 2; -} - -enum TrackType { - AUDIO = 0; - VIDEO = 1; - TEXT = 2; -} -enum TrackState { - OFF = 0; - ON = 1; -} -enum TrackChangeReason { - REASON_UNKNOWN = 0; - REASON_OTHER = 1; - REASON_INITIAL = 2; - REASON_MANUAL = 3; - REASON_ADAPTIVE = 4; -} diff --git a/core/proto/android/stats/otaupdate/updateengine_enums.proto b/core/proto/android/stats/otaupdate/updateengine_enums.proto deleted file mode 100644 index a6e9919ba606..000000000000 --- a/core/proto/android/stats/otaupdate/updateengine_enums.proto +++ /dev/null @@ -1,82 +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. - */ - -syntax = "proto2"; -package android.stats.otaupdate; - -// The payload type of an OTA update attempt on A/B devices. -enum PayloadType { - FULL = 10000; - DELTA = 10001; -} - -// The attempt result reported by the update engine for an OTA update. -enum AttemptResult { - UPDATE_SUCCEEDED = 10000; - INTERNAL_ERROR = 10001; - PAYLOAD_DOWNLOAD_ERROR = 10002; - METADATA_MALFORMED = 10003; - OPERATION_MALFORMED = 10004; - OPERATION_EXECUTION_ERROR = 10005; - METADATA_VERIFICATION_FAILED = 10006; - PAYLOAD_VERIFICATION_FAILED = 10007; - VERIFICATION_FAILED = 10008; - POSTINSTALL_FAILED = 10009; - ABNORMAL_TERMINATION = 10010; - UPDATE_CANCELED = 10011; - UPDATE_SUCCEEDED_NOT_ACTIVE = 10012; -} - -// The error code reported by the update engine after an OTA update attempt -// on A/B devices. More details in system/update_engine/common/error_code.h -enum ErrorCode { - SUCCESS = 10000; - ERROR = 10001; - FILESYSTEM_COPIER_ERROR = 10004; - POST_INSTALL_RUNNER_ERROR = 10005; - PAYLOAD_MISMATCHED_TYPE_ERROR = 10006; - INSTALL_DEVICE_OPEN_ERROR = 10007; - KERNEL_DEVICE_OPEN_ERROR = 10008; - DOWNLOAD_TRANSFER_ERROR = 10009; - PAYLOAD_HASH_MISMATCH_ERROR = 10010; - PAYLOAD_SIZE_MISMATCH_ERROR = 10011; - DOWNLOAD_PAYLOAD_VERIFICATION_ERROR = 10012; - DOWNLOAD_NEW_PARTITION_INFO_ERROR = 10013; - DOWNLOAD_WRITE_ERROR = 10014; - NEW_ROOTFS_VERIFICATION_ERROR = 10015; - SIGNED_DELTA_PAYLOAD_EXPECTED_ERROR = 10017; - DOWNLOAD_PAYLOAD_PUB_KEY_VERIFICATION_ERROR = 10018; - DOWNLOAD_STATE_INITIALIZATION_ERROR = 10020; - DOWNLOAD_INVALID_METADATA_MAGIC_STRING = 10021; - DOWNLOAD_SIGNATURE_MISSING_IN_MANIFEST = 10022; - DOWNLOAD_MANIFEST_PARSE_ERROR = 10023; - DOWNLOAD_METADATA_SIGNATURE_ERROR = 10024; - DOWNLOAD_METADATA_SIGNATURE_VERIFICATION_ERROR = 10025; - DOWNLOAD_METADATA_SIGNATURE_MISMATCH = 10026; - DOWNLOAD_OPERATION_HASH_VERIFICATION_ERROR = 10027; - DOWNLOAD_OPERATION_EXECUTION_ERROR = 10028; - DOWNLOAD_OPERATION_HASH_MISMATCH = 10029; - DOWNLOAD_INVALID_METADATA_SIZE = 10032; - DOWNLOAD_INVALID_METADATA_SIGNATURE = 10033; - DOWNLOAD_OPERATION_HASH_MISSING_ERROR = 10038; - DOWNLOAD_METADATA_SIGNATURE_MISSING_ERROR = 10039; - UNSUPPORTED_MAJOR_PAYLOAD_VERSION = 10044; - UNSUPPORTED_MINOR_PAYLOAD_VERSION = 10045; - FILESYSTEM_VERIFIER_ERROR = 10047; - USER_CANCELED = 10048; - PAYLOAD_TIMESTAMP_ERROR = 10051; - UPDATED_BUT_NOT_ACTIVE = 10052; -} diff --git a/core/proto/android/stats/style/Android.bp b/core/proto/android/stats/style/Android.bp deleted file mode 100644 index f085a52f8cdb..000000000000 --- a/core/proto/android/stats/style/Android.bp +++ /dev/null @@ -1,27 +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. - -java_library { - name: "styleprotosnano", - proto: { - type: "nano", - output_params: ["store_unknown_fields=true"], - include_dirs: ["external/protobuf/src"], - }, - - sdk_version: "current", - srcs: [ - "*.proto", - ], -} diff --git a/core/proto/android/stats/style/style_enums.proto b/core/proto/android/stats/style/style_enums.proto deleted file mode 100644 index 2876882e78ba..000000000000 --- a/core/proto/android/stats/style/style_enums.proto +++ /dev/null @@ -1,69 +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. - */ - -syntax = "proto2"; -package android.stats.style; -option java_multiple_files = true; - -enum Action { - DEFAULT_ACTION = 0; - ONRESUME = 1; - ONSTOP = 2; - PICKER_SELECT = 3; - PICKER_APPLIED = 4; - WALLPAPER_OPEN_CATEGORY = 5; - WALLPAPER_SELECT = 6; - WALLPAPER_APPLIED = 7; - WALLPAPER_EXPLORE = 8; - WALLPAPER_DOWNLOAD = 9; - WALLPAPER_REMOVE = 10; - LIVE_WALLPAPER_DOWNLOAD_SUCCESS = 11; - LIVE_WALLPAPER_DOWNLOAD_FAILED = 12; - LIVE_WALLPAPER_DOWNLOAD_CANCELLED = 13; - LIVE_WALLPAPER_DELETE_SUCCESS = 14; - LIVE_WALLPAPER_DELETE_FAILED = 15; - LIVE_WALLPAPER_APPLIED = 16; - LIVE_WALLPAPER_INFO_SELECT = 17; - LIVE_WALLPAPER_CUSTOMIZE_SELECT = 18; - LIVE_WALLPAPER_QUESTIONNAIRE_SELECT = 19; - LIVE_WALLPAPER_QUESTIONNAIRE_APPLIED = 20; - LIVE_WALLPAPER_EFFECT_SHOW = 21; - APP_LAUNCHED = 22; -} - -enum LocationPreference { - LOCATION_PREFERENCE_UNSPECIFIED = 0; - LOCATION_UNAVAILABLE = 1; - LOCATION_CURRENT = 2; - LOCATION_MANUAL = 3; -} - -enum DatePreference { - DATE_PREFERENCE_UNSPECIFIED = 0; - DATE_UNAVAILABLE = 1; - DATE_MANUAL = 2; -} - -enum LaunchedPreference { - LAUNCHED_PREFERENCE_UNSPECIFIED = 0; - LAUNCHED_LAUNCHER = 1; - LAUNCHED_SETTINGS = 2; - LAUNCHED_SUW = 3; - LAUNCHED_TIPS = 4; - LAUNCHED_LAUNCH_ICON = 5; - LAUNCHED_CROP_AND_SET_ACTION = 6; - LAUNCHED_DEEP_LINK = 7; -} diff --git a/core/proto/android/stats/sysui/notification_enums.proto b/core/proto/android/stats/sysui/notification_enums.proto deleted file mode 100644 index 30bdecae07d1..000000000000 --- a/core/proto/android/stats/sysui/notification_enums.proto +++ /dev/null @@ -1,30 +0,0 @@ -/* - * 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. - */ - -syntax = "proto2"; - -package android.stats.sysui; - -// Enum used in NotificationReported and NotificationChannelModified atoms -enum NotificationImportance { // Constants from NotificationManager.java - IMPORTANCE_UNSPECIFIED = -1000; // Should not occur for real notifications. - IMPORTANCE_NONE = 0; // No importance: does not show in the shade. - IMPORTANCE_MIN = 1; // Minimum to show in the shade. - IMPORTANCE_LOW = 2; // Shows in shade, maybe status bar, no buzz/beep. - IMPORTANCE_DEFAULT = 3; // Shows everywhere, makes noise, no heads-up. - IMPORTANCE_HIGH = 4; // Shows everywhere, makes noise, heads-up, may full-screen. - IMPORTANCE_IMPORTANT_CONVERSATION = 5; // High + isImportantConversation(). -} diff --git a/core/proto/android/stats/textclassifier/Android.bp b/core/proto/android/stats/textclassifier/Android.bp deleted file mode 100644 index bf9022711206..000000000000 --- a/core/proto/android/stats/textclassifier/Android.bp +++ /dev/null @@ -1,23 +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. - -java_library_static { - name: "textclassifierprotoslite", - proto: { - type: "lite", - }, - srcs: [ - "*.proto", - ], -}
\ No newline at end of file diff --git a/core/proto/android/stats/textclassifier/textclassifier_enums.proto b/core/proto/android/stats/textclassifier/textclassifier_enums.proto deleted file mode 100644 index 4be7b7c2df7c..000000000000 --- a/core/proto/android/stats/textclassifier/textclassifier_enums.proto +++ /dev/null @@ -1,87 +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. - */ - -syntax = "proto2"; -package android.stats.textclassifier; -option java_multiple_files = true; - -enum EventType { - TYPE_UNKNOWN = 0; - // User started a new selection. - SELECTION_STARTED = 1; - // User modified an existing selection. - SELECTION_MODIFIED = 2; - // Smart selection triggered for a single token (word). - SMART_SELECTION_SINGLE = 3; - // Smart selection triggered spanning multiple tokens (words). - SMART_SELECTION_MULTI = 4; - // Something else other than user or the default TextClassifier triggered a selection. - AUTO_SELECTION = 5; - // Smart actions shown to the user. - ACTIONS_SHOWN = 6; - // User clicked a link. - LINK_CLICKED = 7; - // User typed over the selection. - OVERTYPE = 8; - // User clicked on Copy action. - COPY_ACTION = 9; - // User clicked on Paste action. - PASTE_ACTION = 10; - // User clicked on Cut action. - CUT_ACTION = 11; - // User clicked on Share action. - SHARE_ACTION = 12; - // User clicked on a Smart action. - SMART_ACTION = 13; - // User dragged+dropped the selection. - SELECTION_DRAG = 14; - // Selection is destroyed. - SELECTION_DESTROYED = 15; - // User clicked on a custom action. - OTHER_ACTION = 16; - // User clicked on Select All action - SELECT_ALL = 17; - // User reset the smart selection. - SELECTION_RESET = 18; - // User composed a reply. - MANUAL_REPLY = 19; - // TextClassifier generated some actions - ACTIONS_GENERATED = 20; - // Some text links were generated - LINKS_GENERATED = 21; -} - -enum WidgetType { - WIDGET_TYPE_UNKNOWN = 0; - // Standard TextView - WIDGET_TYPE_TEXTVIEW = 1; - // EditText - WIDGET_TYPE_EDITTEXT = 2; - // Not selectable textview - WIDGET_TYPE_UNSELECTABLE_TEXTVIEW = 3; - // Standard Webview - WIDGET_TYPE_WEBVIEW = 4; - // Editable TextView - WIDGET_TYPE_EDIT_WEBVIEW = 5; - // Custom text widget - WIDGET_TYPE_CUSTOM_TEXTVIEW = 6; - // Custom editable text widget. - WIDGET_TYPE_CUSTOM_EDITTEXT = 7; - // Non-selectable text widget. - WIDGET_TYPE_CUSTOM_UNSELECTABLE_TEXTVIEW = 8; - // Notification - WIDGET_TYPE_NOTIFICATION = 9; -} diff --git a/core/proto/android/stats/tls/enums.proto b/core/proto/android/stats/tls/enums.proto deleted file mode 100644 index a64137d7caa9..000000000000 --- a/core/proto/android/stats/tls/enums.proto +++ /dev/null @@ -1,70 +0,0 @@ -/* - * 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. - */ -syntax = "proto2"; -package android.stats.tls; - -// Keep in sync with -// external/conscrypt/{android,platform}/src/main/java/org/conscrypt/Platform.java -enum Protocol { - UNKNOWN_PROTO = 0; - SSL_V3 = 1; - TLS_V1 = 2; - TLS_V1_1 = 3; - TLS_V1_2 = 4; - TLS_V1_3 = 5; -} - -// Cipher suites' ids are based on IANA's database: -// https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-4 -// -// If you add new cipher suite, make sure id is the same as in IANA's database (see link above) -// -// Keep in sync with -// external/conscrypt/{android,platform}/src/main/java/org/conscrypt/Platform.java -enum CipherSuite { - UNKNOWN_CIPHER_SUITE = 0x0000; - - TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA = 0xC00A; - TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA = 0xC014; - TLS_RSA_WITH_AES_256_CBC_SHA = 0x0035; - TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA = 0xC009; - TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA = 0xC013; - TLS_RSA_WITH_AES_128_CBC_SHA = 0x002F; - TLS_RSA_WITH_3DES_EDE_CBC_SHA = 0x000A; - - // TLSv1.2 cipher suites - TLS_RSA_WITH_AES_128_GCM_SHA256 = 0x009C; - TLS_RSA_WITH_AES_256_GCM_SHA384 = 0x009D; - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 = 0xC02F; - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 = 0xC030; - TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 = 0xC02B; - TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 = 0xC02C; - TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 = 0xCCA9; - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 = 0xCCA8; - - // Pre-Shared Key (PSK) cipher suites - TLS_PSK_WITH_AES_128_CBC_SHA = 0x008C; - TLS_PSK_WITH_AES_256_CBC_SHA = 0x008D; - TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA = 0xC035; - TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA = 0xC036; - TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256 = 0xCCAC; - - // TLS 1.3 cipher suites - TLS_AES_128_GCM_SHA256 = 0x1301; - TLS_AES_256_GCM_SHA384 = 0x1302; - TLS_CHACHA20_POLY1305_SHA256 = 0x1303; -} - diff --git a/core/proto/android/stats/tv/tif_enums.proto b/core/proto/android/stats/tv/tif_enums.proto deleted file mode 100644 index a9028e529186..000000000000 --- a/core/proto/android/stats/tv/tif_enums.proto +++ /dev/null @@ -1,56 +0,0 @@ -/* - * 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. - */ - -syntax = "proto2"; - -package android.stats.tv; -option java_multiple_files = true; - -// Enums for TV Input Framework -option java_outer_classname = "TifStatsEnums"; - -// Tune State of a TV Input Service Framework -enum TifTuneState { - TIF_TUNE_STATE_UNKNOWN = 0; - CREATED = 1; - SURFACE_ATTACHED = 2; - SURFACE_DETACHED = 3; - RELEASED = 4; - TUNE_STARTED = 5; - VIDEO_AVAILABLE = 6; - - // Keep in sync with TvInputManager - // Use the TvInputManager value + 100 - VIDEO_UNAVAILABLE_REASON_UNKNOWN = 100; - VIDEO_UNAVAILABLE_REASON_TUNING = 101; - VIDEO_UNAVAILABLE_REASON_WEAK_SIGNAL = 102; - VIDEO_UNAVAILABLE_REASON_BUFFERING = 103; - VIDEO_UNAVAILABLE_REASON_AUDIO_ONLY = 104; - VIDEO_UNAVAILABLE_REASON_NOT_CONNECTED = 105; - VIDEO_UNAVAILABLE_REASON_INSUFFICIENT_RESOURCE = 106; - VIDEO_UNAVAILABLE_REASON_CAS_INSUFFICIENT_OUTPUT_PROTECTION=107; - VIDEO_UNAVAILABLE_REASON_CAS_PVR_RECORDING_NOT_ALLOWED=108; - VIDEO_UNAVAILABLE_REASON_CAS_NO_LICENSE=109; - VIDEO_UNAVAILABLE_REASON_CAS_LICENSE_EXPIRED=110; - VIDEO_UNAVAILABLE_REASON_CAS_NEED_ACTIVATION=111; - VIDEO_UNAVAILABLE_REASON_CAS_NEED_PAIRING=112; - VIDEO_UNAVAILABLE_REASON_CAS_NO_CARD=113; - VIDEO_UNAVAILABLE_REASON_CAS_CARD_MUTE=114; - VIDEO_UNAVAILABLE_REASON_CAS_CARD_INVALID=115; - VIDEO_UNAVAILABLE_REASON_CAS_BLACKOUT=116; - VIDEO_UNAVAILABLE_REASON_CAS_REBOOTING=117; - VIDEO_UNAVAILABLE_REASON_CAS_UNKNOWN=118; -} diff --git a/core/proto/android/telecomm/enums.proto b/core/proto/android/telecomm/enums.proto deleted file mode 100644 index 5ca4a85f7c6a..000000000000 --- a/core/proto/android/telecomm/enums.proto +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -syntax = "proto2"; -package android.telecom; - -option java_outer_classname = "TelecomProtoEnums"; -option java_multiple_files = true; - -/** - * Call states, primarily used in CallState.java, - * Call.java, and CallsManager.java in packages/services. - */ -enum CallStateEnum { - /** - * Indicates that a call is new and not connected. This is used as the default state internally - * within Telecom and should not be used between Telecom and call services. Call services are - * not expected to ever interact with NEW calls, but {@link android.telecom.InCallService}s will - * see calls in this state. - */ - NEW = 0; - - /** - * The initial state of an outgoing {@code Call}. - * Common transitions are to {@link #DIALING} state for a successful call or - * {@link #DISCONNECTED} if it failed. - */ - CONNECTING = 1; - - /** - * The state of an outgoing {@code Call} when waiting on user to select a - * {@link android.telecom.PhoneAccount} through which to place the call. - */ - SELECT_PHONE_ACCOUNT = 2; - - /** - * Indicates that a call is outgoing and in the dialing state. A call transitions to this state - * once an outgoing call has begun (e.g., user presses the dial button in Dialer). Calls in this - * state usually transition to {@link #ACTIVE} if the call was answered or {@link #DISCONNECTED} - * if the call was disconnected somehow (e.g., failure or cancellation of the call by the user). - */ - DIALING = 3; - - /** - * Indicates that a call is incoming and the user still has the option of answering, rejecting, - * or doing nothing with the call. This state is usually associated with some type of audible - * ringtone. Normal transitions are to {@link #ACTIVE} if answered or {@link #DISCONNECTED} - * otherwise. - */ - RINGING = 4; - - /** - * Indicates that a call is currently connected to another party and a communication channel is - * open between them. The normal transition to this state is by the user answering a - * {@link #DIALING} call or a {@link #RINGING} call being answered by the other party. - */ - ACTIVE = 5; - - /** - * Indicates that the call is currently on hold. In this state, the call is not terminated - * but no communication is allowed until the call is no longer on hold. The typical transition - * to this state is by the user putting an {@link #ACTIVE} call on hold by explicitly performing - * an action, such as clicking the hold button. - */ - ON_HOLD = 6; - - /** - * Indicates that a call is currently disconnected. All states can transition to this state - * by the call service giving notice that the connection has been severed. When the user - * explicitly ends a call, it will not transition to this state until the call service confirms - * the disconnection or communication was lost to the call service currently responsible for - * this call (e.g., call service crashes). - */ - DISCONNECTED = 7; - - /** - * Indicates that the call was attempted (mostly in the context of outgoing, at least at the - * time of writing) but cancelled before it was successfully connected. - */ - ABORTED = 8; - - /** - * Indicates that the call is in the process of being disconnected and will transition next - * to a {@link #DISCONNECTED} state. - * <p> - * This state is not expected to be communicated from the Telephony layer, but will be reported - * to the InCall UI for calls where disconnection has been initiated by the user but the - * ConnectionService has confirmed the call as disconnected. - */ - DISCONNECTING = 9; - - /** - * Indicates that the call is in the process of being pulled to the local device. - * <p> - * This state should only be set on a call with - * {@link android.telecom.Connection#PROPERTY_IS_EXTERNAL_CALL} and - * {@link android.telecom.Connection#CAPABILITY_CAN_PULL_CALL}. - */ - PULLING = 10; - - /** - * Indicates that an incoming call has been answered by the in-call UI, but Telephony hasn't yet - * set the call to active. - */ - ANSWERED = 11; - - /** - * Indicates that the call is undergoing audio processing by a different app in the background. - * @see android.telecom.Call#STATE_AUDIO_PROCESSING - */ - AUDIO_PROCESSING = 12; - - /** - * Indicates that the call is in a fake ringing state. - * @see android.telecom.Call#STATE_SIMULATED_RINGING - */ - SIMULATED_RINGING = 13; -} - -// Disconnect causes for a call. Primarily used by android/telecom/DisconnectCause.java -enum DisconnectCauseEnum { - /** - * Disconnected because of an unknown or unspecified reason. - */ - UNKNOWN = 0; - - /** - * Disconnected because there was an error, such as a problem with the network. - */ - ERROR = 1; - - /** - * Disconnected because of a local user-initiated action, such as hanging up. - */ - LOCAL = 2; - - /** - * Disconnected because of a remote user-initiated action, such as the other party hanging up - * up. - */ - REMOTE = 3; - - /** - * Disconnected because it has been canceled. - */ - CANCELED = 4; - - /** - * Disconnected because there was no response to an incoming call. - */ - MISSED = 5; - - /** - * Disconnected because the user rejected an incoming call. - */ - REJECTED = 6; - - /** - * Disconnected because the other party was busy. - */ - BUSY = 7; - - /** - * Disconnected because of a restriction on placing the call, such as dialing in airplane - * mode. - */ - RESTRICTED = 8; - - /** - * Disconnected for reason not described by other disconnect codes. - */ - OTHER = 9; - - /** - * Disconnected because the connection manager did not support the call. The call will be tried - * again without a connection manager. See {@link PhoneAccount#CAPABILITY_CONNECTION_MANAGER}. - */ - CONNECTION_MANAGER_NOT_SUPPORTED = 10; - - /** - * Disconnected because the user did not locally answer the incoming call, but it was answered - * on another device where the call was ringing. - */ - ANSWERED_ELSEWHERE = 11; - - /** - * Disconnected because the call was pulled from the current device to another device. - */ - CALL_PULLED = 12; -} diff --git a/core/proto/android/telephony/enums.proto b/core/proto/android/telephony/enums.proto deleted file mode 100644 index b435fe7d9784..000000000000 --- a/core/proto/android/telephony/enums.proto +++ /dev/null @@ -1,288 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -syntax = "proto2"; -package android.telephony; - -option java_outer_classname = "TelephonyProtoEnums"; -option java_multiple_files = true; - -enum CallBearerEnum { - /** Call bearer is unknown or invalid */ - CALL_BEARER_UNKNOWN = 0; - - /** Call bearer is legacy CS */ - CALL_BEARER_CS = 1; - - /** Call bearer is IMS */ - CALL_BEARER_IMS = 2; -} - -enum CallDirectionEnum { - /** Call direction: unknown or invalid */ - CALL_DIRECTION_UNKNOWN = 0; - - /** Call direction: mobile originated (outgoing for this device) */ - CALL_DIRECTION_MO = 1; - - /** Call direction: mobile terminated (incoming for this device) */ - CALL_DIRECTION_MT = 2; -} - -// Call setup duration buckets. -// See com.android.internal.telephony.metrics.VoiceCallSessionStats for definition. -enum CallSetupDurationEnum { - CALL_SETUP_DURATION_UNKNOWN = 0; - CALL_SETUP_DURATION_EXTREMELY_FAST = 1; - CALL_SETUP_DURATION_ULTRA_FAST = 2; - CALL_SETUP_DURATION_VERY_FAST = 3; - CALL_SETUP_DURATION_FAST = 4; - CALL_SETUP_DURATION_NORMAL = 5; - CALL_SETUP_DURATION_SLOW = 6; - CALL_SETUP_DURATION_VERY_SLOW = 7; - CALL_SETUP_DURATION_ULTRA_SLOW = 8; - CALL_SETUP_DURATION_EXTREMELY_SLOW = 9; -} - -// Data conn. power states, primarily used by android/telephony/DataConnectionRealTimeInfo.java. -enum DataConnectionPowerStateEnum { - DATA_CONNECTION_POWER_STATE_LOW = 1; - DATA_CONNECTION_POWER_STATE_MEDIUM = 2; - DATA_CONNECTION_POWER_STATE_HIGH = 3; - DATA_CONNECTION_POWER_STATE_UNKNOWN = 2147483647; // Java Integer.MAX_VALUE; -} - -// Network type enums, primarily used by android/telephony/TelephonyManager.java. -// Do not add negative types. -enum NetworkTypeEnum { - NETWORK_TYPE_UNKNOWN = 0; - NETWORK_TYPE_GPRS = 1; - NETWORK_TYPE_EDGE = 2; - NETWORK_TYPE_UMTS = 3; - NETWORK_TYPE_CDMA = 4; - NETWORK_TYPE_EVDO_0 = 5; - NETWORK_TYPE_EVDO_A = 6; - NETWORK_TYPE_1XRTT = 7; - NETWORK_TYPE_HSDPA = 8; - NETWORK_TYPE_HSUPA = 9; - NETWORK_TYPE_HSPA = 10; - NETWORK_TYPE_IDEN = 11; - NETWORK_TYPE_EVDO_B = 12; - NETWORK_TYPE_LTE = 13; - NETWORK_TYPE_EHRPD = 14; - NETWORK_TYPE_HSPAP = 15; - NETWORK_TYPE_GSM = 16; - NETWORK_TYPE_TD_SCDMA = 17; - NETWORK_TYPE_IWLAN = 18; - NETWORK_TYPE_LTE_CA = 19; - NETWORK_TYPE_NR = 20; -} - -// Roaming type enums, see android.telephony.ServiceState.RoamingType for definitions. -enum RoamingTypeEnum { - ROAMING_TYPE_NOT_ROAMING = 0; - ROAMING_TYPE_ROAMING = 1; - ROAMING_TYPE_ROAMING_DOMESTIC = 2; - ROAMING_TYPE_ROAMING_INTERNATIONAL = 3; -} - -// Signal strength levels, as defined in android/telephony/SignalStrength.java. -enum SignalStrengthEnum { - SIGNAL_STRENGTH_NONE_OR_UNKNOWN = 0; - SIGNAL_STRENGTH_POOR = 1; - SIGNAL_STRENGTH_MODERATE = 2; - SIGNAL_STRENGTH_GOOD = 3; - SIGNAL_STRENGTH_GREAT = 4; -} - -enum ServiceStateEnum { - /** - * Normal operation condition, the phone is registered - * with an operator either in home network or in roaming. - */ - SERVICE_STATE_IN_SERVICE = 0; - - /** - * Phone is not registered with any operator, the phone - * can be currently searching a new operator to register to, or not - * searching to registration at all, or registration is denied, or radio - * signal is not available. - */ - SERVICE_STATE_OUT_OF_SERVICE = 1; - - /** - * The phone is registered and locked. Only emergency numbers are allowed. {@more} - */ - SERVICE_STATE_EMERGENCY_ONLY = 2; - - /** - * Radio of telephony is explicitly powered off. - */ - SERVICE_STATE_POWER_OFF = 3; -} - -enum SimStateEnum { - SIM_STATE_UNKNOWN = 0; - /** SIM card state: no SIM card is available in the device */ - SIM_STATE_ABSENT = 1; - /** SIM card state: Locked: requires the user's SIM PIN to unlock */ - SIM_STATE_PIN_REQUIRED = 2; - /** SIM card state: Locked: requires the user's SIM PUK to unlock */ - SIM_STATE_PUK_REQUIRED = 3; - /** SIM card state: Locked: requires a network PIN to unlock */ - SIM_STATE_NETWORK_LOCKED = 4; - /** SIM card state: Ready */ - SIM_STATE_READY = 5; - /** SIM card state: SIM Card is NOT READY */ - SIM_STATE_NOT_READY = 6; - /** SIM card state: SIM Card Error, permanently disabled */ - SIM_STATE_PERM_DISABLED = 7; - /** SIM card state: SIM Card Error, present but faulty */ - SIM_STATE_CARD_IO_ERROR = 8; - /** SIM card state: SIM Card restricted, present but not usable due to - * carrier restrictions. - */ - SIM_STATE_CARD_RESTRICTED = 9; - /** - * SIM card state: Loaded: SIM card applications have been loaded - * @hide - */ - SIM_STATE_LOADED = 10; - /** - * SIM card state: SIM Card is present - * @hide - */ - SIM_STATE_PRESENT = 11; -} - -// Format of SMS message -enum SmsFormatEnum { - /** Unknown format */ - SMS_FORMAT_UNKNOWN = 0; - /** Format compliant with 3GPP TS 23.040 */ - SMS_FORMAT_3GPP = 1; - /** Format compliant with 3GPP2 TS C.S0015-B */ - SMS_FORMAT_3GPP2 = 2; -} - -// Technology used to carry an SMS message -enum SmsTechEnum { - /** - * Unknown SMS technology used to carry the SMS. - * This value is also used for injected SMS. - */ - SMS_TECH_UNKNOWN = 0; - /** The SMS was carried over CS bearer in 3GPP network */ - SMS_TECH_CS_3GPP = 1; - /** The SMS was carried over CS bearer in 3GPP2 network */ - SMS_TECH_CS_3GPP2 = 2; - /** The SMS was carried over IMS */ - SMS_TECH_IMS = 3; -} - -// Types of SMS message -enum SmsTypeEnum { - /** Normal type. */ - SMS_TYPE_NORMAL = 0; - /** SMS-PP (point-to-point). */ - SMS_TYPE_SMS_PP = 1; - /** Voicemail indication. */ - SMS_TYPE_VOICEMAIL_INDICATION = 2; - /** Type 0 message (3GPP TS 23.040 9.2.3.9). */ - SMS_TYPE_ZERO = 3; - /** WAP-PUSH message. */ - SMS_TYPE_WAP_PUSH = 4; -} - -// Incoming SMS errors -enum SmsIncomingErrorEnum { - SMS_SUCCESS = 0; - SMS_ERROR_GENERIC = 1; - SMS_ERROR_NO_MEMORY = 2; - SMS_ERROR_NOT_SUPPORTED = 3; -} - -// Outgoing SMS results -enum SmsSendResultEnum { - // Unknown error - SMS_SEND_RESULT_UNKNOWN = 0; - // Success - SMS_SEND_RESULT_SUCCESS = 1; - // Permanent error - SMS_SEND_RESULT_ERROR = 2; - // Temporary error, retry - SMS_SEND_RESULT_ERROR_RETRY = 3; - // Error over IMS, retry on CS - SMS_SEND_RESULT_ERROR_FALLBACK = 4; -} - -// Data profile of the data call. From -// frameworks/base/telephony/java/com/android/internal/telephony/RILConstants.java -enum DataProfileEnum { - DATA_PROFILE_DEFAULT = 0; - DATA_PROFILE_TETHERED = 1; - DATA_PROFILE_IMS = 2; - DATA_PROFILE_FOTA = 3; - DATA_PROFILE_CBS = 4; - DATA_PROFILE_OEM_BASE = 1000; - DATA_PROFILE_INVALID = -1; -} - -// Reason of data call deactivation. From -// frameworks/base/telephony/java/android/telephony/data/DataService.java#DeactivateDataReason -enum DataDeactivateReasonEnum { - DEACTIVATE_REASON_UNKNOWN = 0; - DEACTIVATE_REASON_NORMAL = 1; - DEACTIVATE_REASON_RADIO_OFF = 2; - DEACTIVATE_REASON_HANDOVER = 3; -} - -// IP type of the data call -// see frameworks/base/telephony/java/android/telephony/data/ApnSetting.java#ProtocolType -enum ApnProtocolEnum { - APN_PROTOCOL_IPV4 = 0; - APN_PROTOCOL_IPV6 = 1; - APN_PROTOCOL_IPV4V6 = 2; - APN_PROTOCOL_PPP = 3; -} - -// Action taken to recover a data call that is stalled. From -// frameworks/opt/telephony/src/java/com/android/internal/telephony/dataconnection/DcTracker.java -// #RecoveryAction -enum DataStallRecoveryActionEnum { - RECOVERY_ACTION_GET_DATA_CALL_LIST = 0; - RECOVERY_ACTION_CLEANUP = 1; - RECOVERY_ACTION_REREGISTER = 2; - RECOVERY_ACTION_RADIO_RESTART = 3; -} - -// Codec quality -enum CodecQuality { - /** Codec quality: unknown */ - CODEC_QUALITY_UNKNOWN = 0; - - /** Codec quality: narrowband */ - CODEC_QUALITY_NARROWBAND = 1; - - /** Codec quality: wideband */ - CODEC_QUALITY_WIDEBAND = 2; - - /** Codec quality: super-wideband */ - CODEC_QUALITY_SUPER_WIDEBAND = 3; - - /** Codec quality: fullband */ - CODEC_QUALITY_FULLBAND = 4; -} diff --git a/core/proto/android/view/enums.proto b/core/proto/android/view/enums.proto deleted file mode 100644 index a601abee17f6..000000000000 --- a/core/proto/android/view/enums.proto +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -syntax = "proto2"; -package android.view; - -option java_outer_classname = "ViewProtoEnums"; -option java_multiple_files = true; - -// Screen states, primarily used by android/view/Display.java. -enum DisplayStateEnum { - // The display state is unknown. - DISPLAY_STATE_UNKNOWN = 0; - // The display state is off. - DISPLAY_STATE_OFF = 1; - // The display state is on. - DISPLAY_STATE_ON = 2; - // The display is dozing in a low power state; it is still on but is - // optimized for showing system-provided content while the device is - // non-interactive. - DISPLAY_STATE_DOZE = 3; - // The display is dozing in a suspended low power state; it is still on - // but is optimized for showing static system-provided content while the - // device is non-interactive. - DISPLAY_STATE_DOZE_SUSPEND = 4; - // The display is on and optimized for VR mode. - DISPLAY_STATE_VR = 5; - // The display is in a suspended full power state; it is still on but the - // CPU is not updating it. - DISPLAY_STATE_ON_SUSPEND = 6; -} - -// Constants found in android.view.WindowManager. -enum TransitionTypeEnum { - TRANSIT_NONE = 0; - TRANSIT_UNSET = -1; - TRANSIT_ACTIVITY_OPEN = 6; - TRANSIT_ACTIVITY_CLOSE = 7; - TRANSIT_TASK_OPEN = 8; - TRANSIT_TASK_CLOSE = 9; - TRANSIT_TASK_TO_FRONT = 10; - TRANSIT_TASK_TO_BACK = 11; - TRANSIT_WALLPAPER_CLOSE = 12; - TRANSIT_WALLPAPER_OPEN = 13; - TRANSIT_WALLPAPER_INTRA_OPEN = 14; - TRANSIT_WALLPAPER_INTRA_CLOSE = 15; - TRANSIT_TASK_OPEN_BEHIND = 16; - TRANSIT_TASK_IN_PLACE = 17; - TRANSIT_ACTIVITY_RELAUNCH = 18; - TRANSIT_DOCK_TASK_FROM_RECENTS = 19 [deprecated=true]; - TRANSIT_KEYGUARD_GOING_AWAY = 20; - TRANSIT_KEYGUARD_GOING_AWAY_ON_WALLPAPER = 21; - TRANSIT_KEYGUARD_OCCLUDE = 22; - TRANSIT_KEYGUARD_UNOCCLUDE = 23; - TRANSIT_TRANSLUCENT_ACTIVITY_OPEN = 24; - TRANSIT_TRANSLUCENT_ACTIVITY_CLOSE = 25; - TRANSIT_CRASHING_ACTIVITY_CLOSE = 26; -} diff --git a/core/proto/android/wifi/enums.proto b/core/proto/android/wifi/enums.proto deleted file mode 100644 index e676fef8c2e0..000000000000 --- a/core/proto/android/wifi/enums.proto +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -syntax = "proto2"; -package android.net.wifi; - -option java_outer_classname = "WifiProtoEnums"; -option java_multiple_files = true; - -/** - * Wifi Lock modes, primarily used in - * frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiLockManager.java. - */ -enum WifiModeEnum { - /** - * Deprecated. - * Wi-Fi will be kept active, and will behave normally. - */ - WIFI_MODE_FULL = 1 [deprecated=true]; - - /** - * Deprecated. - * Wi-Fi will be kept active, but the only operation that will be supported is initiation of - * scans, and the subsequent reporting of scan results. - */ - WIFI_MODE_SCAN_ONLY = 2 [deprecated=true]; - - /** - * Wi-Fi will not go to power save. - */ - WIFI_MODE_FULL_HIGH_PERF = 3; - - /** - * Wi-Fi will operate with a priority to achieve low latency. - */ - WIFI_MODE_FULL_LOW_LATENCY = 4; -} - -/** - * Wifi authentication type. - */ -enum WifiAuthType { - AUTH_TYPE_NONE = 0; - - // WPA pre-shared key. - AUTH_TYPE_WPA_PSK = 1; - // WPA using EAP authentication. Generally used with an external authentication server. - AUTH_TYPE_WPA_EAP = 2; - // IEEE 802.1X using EAP authentication and (optionally) dynamically generated WEP keys. - AUTH_TYPE_IEEE8021X = 3; - // WPA2 pre-shared key for use with soft access point. - AUTH_TYPE_WPA2_PSK = 4; - // Hotspot 2.0 r2 OSEN. - AUTH_TYPE_OSEN = 5; - // IEEE 802.11r Fast BSS Transition with PSK authentication. - AUTH_TYPE_FT_PSK = 6; - // IEEE 802.11r Fast BSS Transition with EAP authentication. - AUTH_TYPE_FT_EAP = 7; - // Simultaneous Authentication of Equals. - AUTH_TYPE_SAE = 8; - // Opportunistic Wireless Encryption. - AUTH_TYPE_OWE = 9; - // SUITE_B_192 192 bit level - AUTH_TYPE_SUITE_B_192 = 10; - // WPA pre-shared key with stronger SHA256-based algorithms. - AUTH_TYPE_WPA_PSK_SHA256 = 11; - // WPA using EAP authentication with stronger SHA256-based algorithms. - AUTH_TYPE_WPA_EAP_SHA256 = 12; - // WAPI pre-shared key. - AUTH_TYPE_WAPI_PSK = 13; - // WAPI certificate to be specified. - AUTH_TYPE_WAPI_CERT = 14; - // IEEE 802.11ai FILS SK with SHA256. - AUTH_TYPE_FILS_SHA256 = 15; - // IEEE 802.11ai FILS SK with SHA384. - AUTH_TYPE_FILS_SHA384 = 16; -} - -/** - * Bucketed wifi band. - */ -enum WifiBandBucket { - BAND_UNKNOWN = 0; - - // All of 2.4GHz band - BAND_2G = 1; - // Frequencies in the range of [5150, 5250) GHz - BAND_5G_LOW = 2; - // Frequencies in the range of [5250, 5725) GHz - BAND_5G_MIDDLE = 3; - // Frequencies in the range of [5725, 5850) GHz - BAND_5G_HIGH = 4; - // Frequencies in the range of [5925, 6425) GHz - BAND_6G_LOW = 5; - // Frequencies in the range of [6425, 6875) GHz - BAND_6G_MIDDLE = 6; - // Frequencies in the range of [6875, 7125) GHz - BAND_6G_HIGH = 7; -}
\ No newline at end of file diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index ea667277efee..11a821468aa1 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -2557,6 +2557,10 @@ <permission android:name="android.permission.START_ACTIVITIES_FROM_BACKGROUND" android:protectionLevel="signature|privileged|vendorPrivileged|oem|verifier" /> + <!-- @SystemApi @hide Allows an application to start foreground services from background --> + <permission android:name="android.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND" + android:protectionLevel="signature|privileged|vendorPrivileged|oem|verifier" /> + <!-- @SystemApi Must be required by activities that handle the intent action {@link Intent#ACTION_SEND_SHOW_SUSPENDED_APP_DETAILS}. This is for use by apps that hold {@link Manifest.permission#SUSPEND_APPS} to interact with the system. @@ -5219,6 +5223,9 @@ android:label="@string/sensor_notification_service"/> <!-- Attribution for Twilight service. --> <attribution android:tag="TwilightService" android:label="@string/twilight_service"/> + <!-- Attribution for the Offline LocationTimeZoneProvider, used to detect time zone using + on-device data --> + <attribution android:tag="OfflineLocationTimeZoneProvider" android:label="@string/offline_location_time_zone_detection_service"/> <application android:process="system" android:persistent="true" @@ -5685,6 +5692,18 @@ </intent-filter> </service> + <!-- AOSP configures a default secondary LocationTimeZoneProvider that uses an on-device + data set from the com.android.geotz APEX. --> + <uses-library android:name="com.android.location.provider" /> + <service android:name="com.android.timezone.geotz.provider.OfflineLocationTimeZoneService" + android:exported="false"> + <intent-filter> + <action android:name="com.android.location.timezone.service.v1.SecondaryLocationTimeZoneProvider" /> + </intent-filter> + <meta-data android:name="serviceVersion" android:value="1" /> + <meta-data android:name="serviceIsMultiuser" android:value="true" /> + </service> + <provider android:name="com.android.server.textclassifier.IconsContentProvider" android:authorities="com.android.textclassifier.icons" diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml index c32e8dc94486..85b19e7de04b 100644 --- a/core/res/res/values/attrs_manifest.xml +++ b/core/res/res/values/attrs_manifest.xml @@ -303,6 +303,9 @@ <!-- Additional flag from base permission type: this permission will be granted to the retail demo app, as defined by the OEM. --> <flag name="retailDemo" value="0x1000000" /> + <!-- Additional flag from base permission type: this permission will be granted to the + recents app. --> + <flag name="recents" value="0x2000000" /> </attr> <!-- Flags indicating more context for a permission group. --> diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index eda1c7a7950f..c9f140df68cb 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -1603,7 +1603,7 @@ <integer name="config_timeZoneRulesCheckRetryCount">5</integer> <!-- Whether the geolocation time zone detection feature is enabled. --> - <bool name="config_enableGeolocationTimeZoneDetection" translatable="false">false</bool> + <bool name="config_enableGeolocationTimeZoneDetection" translatable="false">true</bool> <!-- Whether to enable primary location time zone provider overlay which allows the primary location time zone provider to be replaced by an app at run-time. When disabled, only the @@ -1622,8 +1622,13 @@ wants to disable the overlay mechanism can set it to false. --> <bool name="config_enableSecondaryLocationTimeZoneOverlay" translatable="false">false</bool> <!-- Package name providing the secondary location time zone provider. Used only when - config_enableSecondaryLocationTimeZoneOverlay is false. --> - <string name="config_secondaryLocationTimeZoneProviderPackageName" translatable="false">@null</string> + config_enableSecondaryLocationTimeZoneOverlay is false. + + By default, set to "android" to pick up the default LocationTimeZoneProvider configured in + the system server's AndroidManifest.xml. See the + com.android.location.timezone.service.v1.SecondaryLocationTimeZoneProvider intent-filter + definition there for more information. --> + <string name="config_secondaryLocationTimeZoneProviderPackageName" translatable="false">android</string> <!-- Whether to enable network location overlay which allows network location provider to be replaced by an app at run-time. When disabled, only the diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index be6b6b15fe4d..8e3a0cbdd10c 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -433,6 +433,9 @@ <string name="sensor_notification_service">Sensor Notification Service</string> <!-- Attribution for Twilight service. [CHAR LIMIT=NONE]--> <string name="twilight_service">Twilight Service</string> + <!-- Attribution for Offline LocationTimeZoneDetector service, i.e. one capable of performing + time zone lookup using geo-spacial information held on the device. [CHAR LIMIT=NONE]--> + <string name="offline_location_time_zone_detection_service">Offline Time Zone Detection Service</string> <!-- Factory reset warning dialog strings--> <skip /> <!-- Shows up in the dialog's title to warn about an impeding factory reset. [CHAR LIMIT=NONE] --> diff --git a/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java b/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java index 4fe68cd5a27a..e5da41c7c113 100644 --- a/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java +++ b/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java @@ -51,6 +51,8 @@ import android.content.res.Configuration; import android.content.res.Resources; import android.graphics.Rect; import android.hardware.display.DisplayManager; +import android.hardware.display.VirtualDisplay; +import android.os.Bundle; import android.os.IBinder; import android.platform.test.annotations.Presubmit; import android.util.DisplayMetrics; @@ -66,6 +68,7 @@ import androidx.test.runner.AndroidJUnit4; import com.android.internal.content.ReferrerIntent; +import org.junit.After; import org.junit.Test; import org.junit.runner.RunWith; @@ -95,6 +98,16 @@ public class ActivityThreadTest { new ActivityTestRule<>(TestActivity.class, true /* initialTouchMode */, false /* launchActivity */); + private ArrayList<VirtualDisplay> mCreatedVirtualDisplays; + + @After + public void tearDown() { + if (mCreatedVirtualDisplays != null) { + mCreatedVirtualDisplays.forEach(VirtualDisplay::release); + mCreatedVirtualDisplays = null; + } + } + @Test public void testDoubleRelaunch() throws Exception { final Activity activity = mActivityTestRule.launchActivity(new Intent()); @@ -410,7 +423,6 @@ public class ActivityThreadTest { Context appContext = activity.getApplication(); Configuration originalAppConfig = new Configuration(appContext.getResources().getConfiguration()); - DisplayManager dm = appContext.getSystemService(DisplayManager.class); int virtualDisplayWidth; int virtualDisplayHeight; @@ -421,8 +433,8 @@ public class ActivityThreadTest { virtualDisplayWidth = 200; virtualDisplayHeight = 100; } - Display virtualDisplay = dm.createVirtualDisplay("virtual-display", - virtualDisplayWidth, virtualDisplayHeight, 200, null, 0).getDisplay(); + final Display virtualDisplay = createVirtualDisplay(appContext, + virtualDisplayWidth, virtualDisplayHeight); Context virtualDisplayContext = appContext.createDisplayContext(virtualDisplay); int originalVirtualDisplayOrientation = virtualDisplayContext.getResources() .getConfiguration().orientation; @@ -467,7 +479,6 @@ public class ActivityThreadTest { InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> { Configuration originalActivityConfig = new Configuration(activity.getResources().getConfiguration()); - DisplayManager dm = activity.getSystemService(DisplayManager.class); int virtualDisplayWidth; int virtualDisplayHeight; @@ -478,8 +489,8 @@ public class ActivityThreadTest { virtualDisplayWidth = 200; virtualDisplayHeight = 100; } - Display virtualDisplay = dm.createVirtualDisplay("virtual-display", - virtualDisplayWidth, virtualDisplayHeight, 200, null, 0).getDisplay(); + final Display virtualDisplay = createVirtualDisplay(activity, + virtualDisplayWidth, virtualDisplayHeight); Context virtualDisplayContext = activity.createDisplayContext(virtualDisplay); int originalVirtualDisplayOrientation = virtualDisplayContext.getResources() .getConfiguration().orientation; @@ -704,6 +715,17 @@ public class ActivityThreadTest { return config.seq; } + private Display createVirtualDisplay(Context context, int w, int h) { + final DisplayManager dm = context.getSystemService(DisplayManager.class); + final VirtualDisplay virtualDisplay = dm.createVirtualDisplay("virtual-display", w, h, + 200 /* densityDpi */, null /* surface */, 0 /* flags */); + if (mCreatedVirtualDisplays == null) { + mCreatedVirtualDisplays = new ArrayList<>(); + } + mCreatedVirtualDisplays.add(virtualDisplay); + return virtualDisplay.getDisplay(); + } + private static ActivityClientRecord getActivityClientRecord(Activity activity) { final ActivityThread thread = activity.getActivityThread(); final IBinder token = activity.getActivityToken(); @@ -796,6 +818,14 @@ public class ActivityThreadTest { volatile CountDownLatch mConfigLatch; @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getWindow().getDecorView().setKeepScreenOn(true); + setShowWhenLocked(true); + setTurnScreenOn(true); + } + + @Override public void onConfigurationChanged(Configuration config) { super.onConfigurationChanged(config); mConfig.setTo(config); diff --git a/core/tests/coretests/src/android/graphics/TypefaceSystemFallbackTest.java b/core/tests/coretests/src/android/graphics/TypefaceSystemFallbackTest.java index c66bac6cc335..82d066f6ab16 100644 --- a/core/tests/coretests/src/android/graphics/TypefaceSystemFallbackTest.java +++ b/core/tests/coretests/src/android/graphics/TypefaceSystemFallbackTest.java @@ -23,7 +23,6 @@ import static org.junit.Assert.assertTrue; import android.content.Context; import android.content.res.AssetManager; -import android.graphics.fonts.Font; import android.graphics.fonts.FontCustomizationParser; import android.graphics.fonts.FontFamily; import android.graphics.fonts.SystemFonts; @@ -49,7 +48,6 @@ import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.StandardCopyOption; -import java.util.ArrayList; import java.util.Locale; @SmallTest @@ -133,14 +131,14 @@ public class TypefaceSystemFallbackTest { private static void buildSystemFallback(String xml, FontCustomizationParser.Result oemCustomization, ArrayMap<String, Typeface> fontMap, ArrayMap<String, FontFamily[]> fallbackMap) { - final ArrayList<Font> availableFonts = new ArrayList<>(); try (FileOutputStream fos = new FileOutputStream(TEST_FONTS_XML)) { fos.write(xml.getBytes(Charset.forName("UTF-8"))); } catch (IOException e) { throw new RuntimeException(e); } + final FontConfig.Alias[] aliases = SystemFonts.buildSystemFallback(TEST_FONTS_XML, - TEST_FONT_DIR, oemCustomization, fallbackMap, availableFonts); + TEST_FONT_DIR, oemCustomization, fallbackMap); Typeface.initSystemDefaultTypefaces(fontMap, fallbackMap, aliases); } @@ -156,12 +154,11 @@ public class TypefaceSystemFallbackTest { public void testBuildSystemFallback() { final ArrayMap<String, Typeface> fontMap = new ArrayMap<>(); final ArrayMap<String, FontFamily[]> fallbackMap = new ArrayMap<>(); - final ArrayList<Font> availableFonts = new ArrayList<>(); final FontCustomizationParser.Result oemCustomization = new FontCustomizationParser.Result(); final FontConfig.Alias[] aliases = SystemFonts.buildSystemFallback(SYSTEM_FONTS_XML, - SYSTEM_FONT_DIR, oemCustomization, fallbackMap, availableFonts); + SYSTEM_FONT_DIR, oemCustomization, fallbackMap); assertNotNull(aliases); assertFalse(fallbackMap.isEmpty()); diff --git a/core/tests/coretests/src/android/graphics/TypefaceTest.java b/core/tests/coretests/src/android/graphics/TypefaceTest.java index 5fa8c4fbaa56..392c6b7199a5 100644 --- a/core/tests/coretests/src/android/graphics/TypefaceTest.java +++ b/core/tests/coretests/src/android/graphics/TypefaceTest.java @@ -23,8 +23,11 @@ import static org.junit.Assert.assertTrue; import android.content.Context; import android.content.res.AssetManager; import android.content.res.Resources; +import android.graphics.fonts.FontFamily; import android.graphics.fonts.SystemFonts; import android.os.SharedMemory; +import android.text.FontConfig; +import android.util.Pair; import androidx.test.InstrumentationRegistry; import androidx.test.filters.LargeTest; @@ -195,8 +198,9 @@ public class TypefaceTest { @Test public void testSerialize() throws Exception { HashMap<String, Typeface> systemFontMap = new HashMap<>(); - Typeface.initSystemDefaultTypefaces(systemFontMap, SystemFonts.getRawSystemFallbackMap(), - SystemFonts.getAliases()); + Pair<FontConfig.Alias[], Map<String, FontFamily[]>> res = + SystemFonts.initializePreinstalledFonts(); + Typeface.initSystemDefaultTypefaces(systemFontMap, res.second, res.first); SharedMemory sharedMemory = Typeface.serializeFontMap(systemFontMap); Map<String, Typeface> copiedFontMap = Typeface.deserializeFontMap(sharedMemory.mapReadOnly().order(ByteOrder.BIG_ENDIAN)); diff --git a/core/tests/coretests/src/android/text/FontFallbackSetup.java b/core/tests/coretests/src/android/text/FontFallbackSetup.java index cc51ec3da1fd..64e6f82d82af 100644 --- a/core/tests/coretests/src/android/text/FontFallbackSetup.java +++ b/core/tests/coretests/src/android/text/FontFallbackSetup.java @@ -20,7 +20,6 @@ import android.annotation.NonNull; import android.content.Context; import android.content.res.AssetManager; import android.graphics.Typeface; -import android.graphics.fonts.Font; import android.graphics.fonts.FontCustomizationParser; import android.graphics.fonts.FontFamily; import android.graphics.fonts.SystemFonts; @@ -35,7 +34,6 @@ import java.io.InputStream; import java.nio.charset.Charset; import java.nio.file.Files; import java.nio.file.StandardCopyOption; -import java.util.ArrayList; public class FontFallbackSetup implements AutoCloseable { private final String[] mTestFontFiles; @@ -78,11 +76,10 @@ public class FontFallbackSetup implements AutoCloseable { } final ArrayMap<String, FontFamily[]> fallbackMap = new ArrayMap<>(); - final ArrayList<Font> availableFonts = new ArrayList<>(); final FontCustomizationParser.Result oemCustomization = new FontCustomizationParser.Result(); final FontConfig.Alias[] aliases = SystemFonts.buildSystemFallback(testFontsXml, - mTestFontsDir, oemCustomization, fallbackMap, availableFonts); + mTestFontsDir, oemCustomization, fallbackMap); Typeface.initSystemDefaultTypefaces(mFontMap, fallbackMap, aliases); } diff --git a/core/tests/coretests/src/android/widget/TextViewActivityTest.java b/core/tests/coretests/src/android/widget/TextViewActivityTest.java index 7cde19c30dd4..40ef04a5e369 100644 --- a/core/tests/coretests/src/android/widget/TextViewActivityTest.java +++ b/core/tests/coretests/src/android/widget/TextViewActivityTest.java @@ -376,6 +376,56 @@ public class TextViewActivityTest { } @Test + public void testToolbarMenuItemClickAfterSelectionChange() throws Throwable { + final MenuItem[] latestItem = new MenuItem[1]; + final MenuItem[] clickedItem = new MenuItem[1]; + final String text = "abcd efg hijk"; + mActivityRule.runOnUiThread(() -> { + final TextView textView = mActivity.findViewById(R.id.textview); + textView.setText(text); + textView.setCustomSelectionActionModeCallback( + new ActionMode.Callback() { + @Override + public boolean onPrepareActionMode(ActionMode mode, Menu menu) { + menu.clear(); + latestItem[0] = menu.add("Item"); + return true; + } + + @Override + public boolean onActionItemClicked(ActionMode mode, MenuItem item) { + clickedItem[0] = item; + return true; + } + + @Override + public boolean onCreateActionMode(ActionMode mode, Menu menu) { + return true; + } + + @Override + public void onDestroyActionMode(ActionMode mode) {} + }); + }); + mInstrumentation.waitForIdleSync(); + + onView(withId(R.id.textview)).perform(longPressOnTextAtIndex(text.indexOf("f"))); + sleepForFloatingToolbarPopup(); + + // Change the selection so that the menu items are refreshed. + final TextView textView = mActivity.findViewById(R.id.textview); + onHandleView(com.android.internal.R.id.selection_start_handle) + .perform(dragHandle(textView, Handle.SELECTION_START, 0)); + sleepForFloatingToolbarPopup(); + assertFloatingToolbarIsDisplayed(); + + clickFloatingToolbarItem("Item"); + mInstrumentation.waitForIdleSync(); + + assertEquals(latestItem[0], clickedItem[0]); + } + + @Test public void testSelectionRemovedWhenNonselectableTextLosesFocus() throws Throwable { final TextLinks.TextLink textLink = addLinkifiedTextToTextView(R.id.nonselectable_textview); final int position = (textLink.getStart() + textLink.getEnd()) / 2; diff --git a/core/tests/coretests/src/android/widget/espresso/FloatingToolbarEspressoUtils.java b/core/tests/coretests/src/android/widget/espresso/FloatingToolbarEspressoUtils.java index d45d4b04af33..477978630ec2 100644 --- a/core/tests/coretests/src/android/widget/espresso/FloatingToolbarEspressoUtils.java +++ b/core/tests/coretests/src/android/widget/espresso/FloatingToolbarEspressoUtils.java @@ -28,10 +28,11 @@ import static androidx.test.espresso.matcher.ViewMatchers.withId; import static androidx.test.espresso.matcher.ViewMatchers.withTagValue; import static androidx.test.espresso.matcher.ViewMatchers.withText; +import static com.android.internal.widget.FloatingToolbar.MenuItemRepr; + import static org.hamcrest.Matchers.allOf; import static org.hamcrest.Matchers.is; -import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; @@ -158,8 +159,8 @@ public class FloatingToolbarEspressoUtils { public void describeTo(Description description) {} private void collectMenuItemIds(View view) { - if (view.getTag() instanceof MenuItem) { - menuItemIds.add(((MenuItem) view.getTag()).getItemId()); + if (view.getTag() instanceof MenuItemRepr) { + menuItemIds.add(((MenuItemRepr) view.getTag()).itemId); } else if (view instanceof ViewGroup) { ViewGroup viewGroup = (ViewGroup) view; for (int i = 0; i < viewGroup.getChildCount(); i++) { @@ -178,8 +179,8 @@ public class FloatingToolbarEspressoUtils { */ public static void assertFloatingToolbarDoesNotContainItem(String itemLabel) { final Predicate<View> hasMenuItemLabel = view -> - view.getTag() instanceof MenuItem - && itemLabel.equals(((MenuItem) view.getTag()).getTitle().toString()); + view.getTag() instanceof MenuItemRepr + && itemLabel.equals(((MenuItemRepr) view.getTag()).title); assertFloatingToolbarMenuItem(hasMenuItemLabel, false); } @@ -191,8 +192,8 @@ public class FloatingToolbarEspressoUtils { */ public static void assertFloatingToolbarDoesNotContainItem(final int menuItemId) { final Predicate<View> hasMenuItemId = view -> - view.getTag() instanceof MenuItem - && ((MenuItem) view.getTag()).getItemId() == menuItemId; + view.getTag() instanceof MenuItemRepr + && ((MenuItemRepr) view.getTag()).itemId == menuItemId; assertFloatingToolbarMenuItem(hasMenuItemId, false); } diff --git a/core/tests/coretests/src/com/android/internal/os/MockBatteryStatsImpl.java b/core/tests/coretests/src/com/android/internal/os/MockBatteryStatsImpl.java index 75dd7fb82f30..ff1d965c643f 100644 --- a/core/tests/coretests/src/com/android/internal/os/MockBatteryStatsImpl.java +++ b/core/tests/coretests/src/com/android/internal/os/MockBatteryStatsImpl.java @@ -192,8 +192,8 @@ public class MockBatteryStatsImpl extends BatteryStatsImpl { } @Override - public Future<?> scheduleCpuSyncDueToScreenStateChange( - boolean onBattery, boolean onBatteryScreenOff) { + public Future<?> scheduleSyncDueToScreenStateChange( + int flag, boolean onBattery, boolean onBatteryScreenOff, int screenState) { return null; } diff --git a/core/tests/coretests/src/com/android/internal/power/MeasuredEnergyStatsTest.java b/core/tests/coretests/src/com/android/internal/power/MeasuredEnergyStatsTest.java new file mode 100644 index 000000000000..88295efa90b9 --- /dev/null +++ b/core/tests/coretests/src/com/android/internal/power/MeasuredEnergyStatsTest.java @@ -0,0 +1,278 @@ +/* + * 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.internal.power; + +import static com.android.internal.power.MeasuredEnergyArray.NUMBER_SUBSYSTEMS; +import static com.android.internal.power.MeasuredEnergyArray.SUBSYSTEM_DISPLAY; +import static com.android.internal.power.MeasuredEnergyStats.ENERGY_BUCKET_SCREEN_DOZE; +import static com.android.internal.power.MeasuredEnergyStats.ENERGY_BUCKET_SCREEN_ON; +import static com.android.internal.power.MeasuredEnergyStats.NUMBER_ENERGY_BUCKETS; + +import static org.junit.Assert.assertEquals; + +import android.os.Parcel; +import android.view.Display; + +import org.junit.Before; +import org.junit.Test; + +/** + * Test class for {@link MeasuredEnergyStats}. + * + * To run the tests, use + * atest FrameworksCoreTests:com.android.internal.power.MeasuredEnergyStatsTest + */ +public class MeasuredEnergyStatsTest { + private MeasuredEnergyStats mStats; + private int[] mAllSubsystems = new int[NUMBER_SUBSYSTEMS]; + private long[] mCurrentSubsystemEnergyUJ = new long[NUMBER_SUBSYSTEMS]; + + MeasuredEnergyArray mMeasuredEnergyArray = new MeasuredEnergyArray() { + @Override + public int getSubsystem(int index) { + return mAllSubsystems[index]; + } + + @Override + public long getEnergy(int index) { + return mCurrentSubsystemEnergyUJ[index]; + } + + @Override + public int size() { + return NUMBER_SUBSYSTEMS; + } + }; + + @Before + public void setUp() { + // Populate all supported subsystems indexes and arbitrary starting energy values. + mAllSubsystems[SUBSYSTEM_DISPLAY] = SUBSYSTEM_DISPLAY; + mCurrentSubsystemEnergyUJ[SUBSYSTEM_DISPLAY] = 111; + + mStats = new MeasuredEnergyStats(mMeasuredEnergyArray, Display.STATE_UNKNOWN); + } + + @Test + public void testReadWriteParcel() { + // update with some arbitrary data + mCurrentSubsystemEnergyUJ[SUBSYSTEM_DISPLAY] += 222; + mStats.update(mMeasuredEnergyArray, Display.STATE_ON, true); + mCurrentSubsystemEnergyUJ[SUBSYSTEM_DISPLAY] += 321; + mStats.update(mMeasuredEnergyArray, Display.STATE_DOZE, true); + mCurrentSubsystemEnergyUJ[SUBSYSTEM_DISPLAY] += 456; + mStats.update(mMeasuredEnergyArray, Display.STATE_OFF, true); + + final Parcel parcel = Parcel.obtain(); + mStats.writeToParcel(parcel); + + parcel.setDataPosition(0); + MeasuredEnergyStats stats = new MeasuredEnergyStats(parcel); + + for (int i = 0; i < NUMBER_ENERGY_BUCKETS; i++) { + assertEquals(mStats.getAccumulatedBucketEnergy(i), stats.getAccumulatedBucketEnergy(i)); + } + parcel.recycle(); + } + + @Test + public void testReadWriteSummaryParcel() { + // update with some arbitrary data + mCurrentSubsystemEnergyUJ[SUBSYSTEM_DISPLAY] += 222; + mStats.update(mMeasuredEnergyArray, Display.STATE_ON, true); + mCurrentSubsystemEnergyUJ[SUBSYSTEM_DISPLAY] += 321; + mStats.update(mMeasuredEnergyArray, Display.STATE_DOZE, true); + mCurrentSubsystemEnergyUJ[SUBSYSTEM_DISPLAY] += 456; + mStats.update(mMeasuredEnergyArray, Display.STATE_OFF, true); + + final Parcel parcel = Parcel.obtain(); + MeasuredEnergyStats.writeSummaryToParcel(mStats, parcel); + + parcel.setDataPosition(0); + MeasuredEnergyStats stats = new MeasuredEnergyStats(mMeasuredEnergyArray, + Display.STATE_UNKNOWN); + MeasuredEnergyStats.readSummaryFromParcel(stats, parcel); + + for (int i = 0; i < NUMBER_ENERGY_BUCKETS; i++) { + assertEquals(mStats.getAccumulatedBucketEnergy(i), stats.getAccumulatedBucketEnergy(i)); + } + parcel.recycle(); + } + + @Test + public void testDisplayStateEnergyAttribution() { + long expectedScreenOnEnergy = 0; + long expectedScreenDozeEnergy = 0; + + // Display energy should be attributed to the previous screen state. + mStats.update(mMeasuredEnergyArray, Display.STATE_UNKNOWN, true); + + incrementDisplayState(222, Display.STATE_ON, true, expectedScreenOnEnergy, + expectedScreenDozeEnergy); + + expectedScreenOnEnergy += 321; + incrementDisplayState(321, Display.STATE_DOZE, true, expectedScreenOnEnergy, + expectedScreenDozeEnergy); + + expectedScreenDozeEnergy += 456; + incrementDisplayState(456, Display.STATE_OFF, true, expectedScreenOnEnergy, + expectedScreenDozeEnergy); + + incrementDisplayState(1111, Display.STATE_DOZE_SUSPEND, true, expectedScreenOnEnergy, + expectedScreenDozeEnergy); + + expectedScreenDozeEnergy += 2345; + incrementDisplayState(2345, Display.STATE_ON_SUSPEND, true, expectedScreenOnEnergy, + expectedScreenDozeEnergy); + + expectedScreenOnEnergy += 767; + incrementDisplayState(767, Display.STATE_VR, true, expectedScreenOnEnergy, + expectedScreenDozeEnergy); + + expectedScreenOnEnergy += 999; + incrementDisplayState(999, Display.STATE_UNKNOWN, true, expectedScreenOnEnergy, + expectedScreenDozeEnergy); + } + + @Test + public void testDisplayStateEnergyAttribution_notRunning() { + long expectedScreenOnEnergy = 0; + long expectedScreenDozeEnergy = 0; + + // Display energy should be attributed to the previous screen state. + mStats.update(mMeasuredEnergyArray, Display.STATE_UNKNOWN, true); + + incrementDisplayState(222, Display.STATE_ON, true, expectedScreenOnEnergy, + expectedScreenDozeEnergy); + + expectedScreenOnEnergy += 321; + incrementDisplayState(321, Display.STATE_DOZE, true, expectedScreenOnEnergy, + expectedScreenDozeEnergy); + + // Updates after this point should not result in energy accumulation. + incrementDisplayState(456, Display.STATE_OFF, false, expectedScreenOnEnergy, + expectedScreenDozeEnergy); + + incrementDisplayState(1111, Display.STATE_DOZE_SUSPEND, false, expectedScreenOnEnergy, + expectedScreenDozeEnergy); + + incrementDisplayState(2345, Display.STATE_ON_SUSPEND, false, expectedScreenOnEnergy, + expectedScreenDozeEnergy); + + incrementDisplayState(767, Display.STATE_VR, false, expectedScreenOnEnergy, + expectedScreenDozeEnergy); + + // Resume energy accumulation. + expectedScreenOnEnergy += 999; + incrementDisplayState(999, Display.STATE_UNKNOWN, true, expectedScreenOnEnergy, + expectedScreenDozeEnergy); + } + + @Test + public void testReset() { + // update with some arbitrary data. + mCurrentSubsystemEnergyUJ[SUBSYSTEM_DISPLAY] += 222; + mStats.update(mMeasuredEnergyArray, Display.STATE_ON, true); + mCurrentSubsystemEnergyUJ[SUBSYSTEM_DISPLAY] += 321; + mStats.update(mMeasuredEnergyArray, Display.STATE_DOZE, true); + mCurrentSubsystemEnergyUJ[SUBSYSTEM_DISPLAY] += 456; + mStats.update(mMeasuredEnergyArray, Display.STATE_OFF, true); + + mStats.reset(); + // All energy should be reset to 0 + for (int i = 0; i < NUMBER_ENERGY_BUCKETS; i++) { + assertEquals(mStats.getAccumulatedBucketEnergy(i), 0); + } + + // Increment all subsystem energy by some arbitrary amount and update + for (int i = 0; i < NUMBER_SUBSYSTEMS; i++) { + mCurrentSubsystemEnergyUJ[i] += 100 * i; + } + mStats.update(mMeasuredEnergyArray, Display.STATE_OFF, true); + + // All energy should still be 0 after the first post-reset update. + for (int i = 0; i < NUMBER_ENERGY_BUCKETS; i++) { + assertEquals(mStats.getAccumulatedBucketEnergy(i), 0); + } + + // Energy accumulation should continue like normal. + long expectedScreenOnEnergy = 0; + long expectedScreenDozeEnergy = 0; + incrementDisplayState(222, Display.STATE_ON, true, expectedScreenOnEnergy, + expectedScreenDozeEnergy); + + expectedScreenOnEnergy += 321; + incrementDisplayState(321, Display.STATE_DOZE, true, expectedScreenOnEnergy, + expectedScreenDozeEnergy); + + expectedScreenDozeEnergy += 456; + incrementDisplayState(456, Display.STATE_OFF, true, expectedScreenOnEnergy, + expectedScreenDozeEnergy); + } + + @Test + public void testHasSubsystem() { + for (int i = 0; i < NUMBER_SUBSYSTEMS; i++) { + assertEquals(mStats.hasSubsystem(i), true); + } + } + + @Test + public void testHasSubsystem_unavailable() { + // Setup MeasuredEnergyStats with not available subsystems. + int[] subsystems = new int[0]; + long[] energies = new long[0]; + MeasuredEnergyArray measuredEnergyArray = new MeasuredEnergyArray() { + @Override + public int getSubsystem(int index) { + return subsystems[index]; + } + + @Override + public long getEnergy(int index) { + return energies[index]; + } + + @Override + public int size() { + return 0; + } + }; + MeasuredEnergyStats stats = new MeasuredEnergyStats(measuredEnergyArray, + Display.STATE_UNKNOWN); + + for (int i = 0; i < NUMBER_SUBSYSTEMS; i++) { + assertEquals(stats.hasSubsystem(i), false); + } + + stats.reset(); + // a reset should not change the state of an unavailable subsystem. + for (int i = 0; i < NUMBER_SUBSYSTEMS; i++) { + assertEquals(stats.hasSubsystem(i), false); + } + } + + private void incrementDisplayState(long deltaEnergy, int nextState, boolean accumulate, + long expectScreenEnergy, long expectedDozeEnergy) { + mCurrentSubsystemEnergyUJ[SUBSYSTEM_DISPLAY] += deltaEnergy; + mStats.update(mMeasuredEnergyArray, nextState, accumulate); + assertEquals(expectScreenEnergy, + mStats.getAccumulatedBucketEnergy(ENERGY_BUCKET_SCREEN_ON)); + assertEquals(expectedDozeEnergy, + mStats.getAccumulatedBucketEnergy(ENERGY_BUCKET_SCREEN_DOZE)); + } +} diff --git a/core/tests/powertests/PowerStatsViewer/src/com/android/frameworks/core/powerstatsviewer/PowerStatsData.java b/core/tests/powertests/PowerStatsViewer/src/com/android/frameworks/core/powerstatsviewer/PowerStatsData.java index 099ee22b12e4..7aeb86ae0cb1 100644 --- a/core/tests/powertests/PowerStatsViewer/src/com/android/frameworks/core/powerstatsviewer/PowerStatsData.java +++ b/core/tests/powertests/PowerStatsViewer/src/com/android/frameworks/core/powerstatsviewer/PowerStatsData.java @@ -17,6 +17,7 @@ package com.android.frameworks.core.powerstatsviewer; import android.content.Context; +import android.os.BatteryStats; import android.os.Process; import com.android.internal.os.BatterySipper; @@ -32,6 +33,15 @@ public class PowerStatsData { private static final String[] PACKAGES_SYSTEM = {PACKAGE_MEDIA_PROVIDER, PACKAGE_CALENDAR_PROVIDER, PACKAGE_SYSTEMUI}; + // Temporary placeholder voltage for converting energy to charge + // TODO: remove this when b/173765509 is resolved + private static final double MOCK_NOMINAL_VOLTAGE = 3.7; + + // Unit conversion: + // mAh = uWs * (1/1000)(milli/micro) * (1/Voltage) * (1/3600)(hours/second) + private static final double UJ_2_MAH = + (1.0 / 1000) * (1.0 / MOCK_NOMINAL_VOLTAGE) * (1.0 / 3600); + enum EntryType { POWER, DURATION, @@ -50,6 +60,7 @@ public class PowerStatsData { public PowerStatsData(Context context, BatteryStatsHelper batteryStatsHelper, String powerConsumerId) { List<BatterySipper> usageList = batteryStatsHelper.getUsageList(); + BatteryStats batteryStats = batteryStatsHelper.getStats(); double totalPowerMah = 0; double totalSmearedPowerMah = 0; @@ -125,6 +136,8 @@ public class PowerStatsData { totalVideoTimeMs += sipper.videoTimeMs; } + long totalScreenMeasuredEnergyUJ = batteryStats.getScreenOnEnergy(); + if (requestedPowerConsumer == null) { mPowerConsumerInfo = null; return; @@ -135,10 +148,18 @@ public class PowerStatsData { addEntry("Total power", EntryType.POWER, requestedPowerConsumer.totalSmearedPowerMah, totalSmearedPowerMah); + maybeAddMeasuredEnergyEntry(requestedPowerConsumer.drainType, batteryStats); + addEntry("... excluding system", EntryType.POWER, requestedPowerConsumer.totalSmearedPowerMah, totalPowerExcludeSystemMah); addEntry("Screen, smeared", EntryType.POWER, requestedPowerConsumer.screenPowerMah, totalScreenPower); + if (totalScreenMeasuredEnergyUJ != BatteryStats.ENERGY_DATA_UNAVAILABLE) { + final double measuredCharge = UJ_2_MAH * totalScreenMeasuredEnergyUJ; + final double ratio = measuredCharge / totalScreenPower; + addEntry("Screen, smeared (PowerStatsHal adjusted)", EntryType.POWER, + requestedPowerConsumer.screenPowerMah * ratio, measuredCharge); + } addEntry("Other, smeared", EntryType.POWER, requestedPowerConsumer.proportionalSmearMah, totalProportionalSmearMah); addEntry("Excluding smeared", EntryType.POWER, @@ -218,6 +239,28 @@ public class PowerStatsData { mEntries.add(entry); } + private void maybeAddMeasuredEnergyEntry(BatterySipper.DrainType drainType, + BatteryStats batteryStats) { + switch (drainType) { + case AMBIENT_DISPLAY: + final long totalDozeMeasuredEnergyUJ = batteryStats.getScreenDozeEnergy(); + if (totalDozeMeasuredEnergyUJ != BatteryStats.ENERGY_DATA_UNAVAILABLE) { + final double measuredCharge = UJ_2_MAH * totalDozeMeasuredEnergyUJ; + addEntry("Measured ambient display power", EntryType.POWER, measuredCharge, + measuredCharge); + } + break; + case SCREEN: + final long totalScreenMeasuredEnergyUJ = batteryStats.getScreenOnEnergy(); + if (totalScreenMeasuredEnergyUJ != BatteryStats.ENERGY_DATA_UNAVAILABLE) { + final double measuredCharge = UJ_2_MAH * totalScreenMeasuredEnergyUJ; + addEntry("Measured screen power", EntryType.POWER, measuredCharge, + measuredCharge); + } + break; + } + } + public PowerConsumerInfoHelper.PowerConsumerInfo getPowerConsumerInfo() { return mPowerConsumerInfo; } diff --git a/core/tests/powertests/PowerStatsViewer/src/com/android/frameworks/core/powerstatsviewer/PowerStatsViewerActivity.java b/core/tests/powertests/PowerStatsViewer/src/com/android/frameworks/core/powerstatsviewer/PowerStatsViewerActivity.java index 78f2b9135d0c..05679101f86a 100644 --- a/core/tests/powertests/PowerStatsViewer/src/com/android/frameworks/core/powerstatsviewer/PowerStatsViewerActivity.java +++ b/core/tests/powertests/PowerStatsViewer/src/com/android/frameworks/core/powerstatsviewer/PowerStatsViewerActivity.java @@ -29,6 +29,7 @@ import android.widget.ImageView; import android.widget.TextView; import androidx.activity.ComponentActivity; +import androidx.activity.result.ActivityResultLauncher; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.loader.app.LoaderManager; @@ -60,6 +61,8 @@ public class PowerStatsViewerActivity extends ComponentActivity { private RecyclerView mPowerStatsDataView; private View mLoadingView; private View mEmptyView; + private ActivityResultLauncher<Void> mStartAppPicker = registerForActivityResult( + PowerConsumerPickerActivity.CONTRACT, this::onApplicationSelected); @Override protected void onCreate(@Nullable Bundle savedInstanceState) { @@ -105,8 +108,7 @@ public class PowerStatsViewerActivity extends ComponentActivity { } private void startAppPicker() { - registerForActivityResult(PowerConsumerPickerActivity.CONTRACT, this::onApplicationSelected) - .launch(null); + mStartAppPicker.launch(null); } private void onApplicationSelected(String powerConsumerId) { diff --git a/data/etc/com.android.provision.xml b/data/etc/com.android.provision.xml index 05404ef73732..d2ea0ec085d3 100644 --- a/data/etc/com.android.provision.xml +++ b/data/etc/com.android.provision.xml @@ -17,5 +17,7 @@ <permissions> <privapp-permissions package="com.android.provision"> <permission name="android.permission.WRITE_SECURE_SETTINGS"/> + <permissionn ame="android.permission.DISPATCH_PROVISIONING_MESSAGE"/> + <permission name="android.permission.MASTER_CLEAR"/> </privapp-permissions> </permissions> diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json index 52da707565d7..a52eca7e0d73 100644 --- a/data/etc/services.core.protolog.json +++ b/data/etc/services.core.protolog.json @@ -961,6 +961,12 @@ "group": "WM_DEBUG_WINDOW_ORGANIZER", "at": "com\/android\/server\/wm\/TaskOrganizerController.java" }, + "-948446688": { + "message": "Create TaskDisplayArea uid=%d", + "level": "VERBOSE", + "group": "WM_DEBUG_WINDOW_ORGANIZER", + "at": "com\/android\/server\/wm\/DisplayAreaOrganizerController.java" + }, "-937498525": { "message": "Executing finish of failed to pause activity: %s", "level": "VERBOSE", @@ -1273,6 +1279,12 @@ "group": "WM_DEBUG_STATES", "at": "com\/android\/server\/wm\/Task.java" }, + "-597091183": { + "message": "Delete TaskDisplayArea uid=%d", + "level": "VERBOSE", + "group": "WM_DEBUG_WINDOW_ORGANIZER", + "at": "com\/android\/server\/wm\/DisplayAreaOrganizerController.java" + }, "-593535526": { "message": "Binding proc %s with config %s", "level": "VERBOSE", @@ -1495,12 +1507,6 @@ "group": "WM_DEBUG_APP_TRANSITIONS", "at": "com\/android\/server\/wm\/ActivityRecord.java" }, - "-371630969": { - "message": "New wallpaper target=%s, oldWallpaper=%s, openingApps=%s, closingApps=%s", - "level": "VERBOSE", - "group": "WM_DEBUG_APP_TRANSITIONS", - "at": "com\/android\/server\/wm\/AppTransitionController.java" - }, "-354571697": { "message": "Existence Changed in transition %d: %s", "level": "VERBOSE", @@ -1555,6 +1561,12 @@ "group": "WM_DEBUG_WINDOW_TRANSITIONS", "at": "com\/android\/server\/wm\/Transition.java" }, + "-292790591": { + "message": "Attempted to set IME policy to a display that does not exist: %d", + "level": "WARN", + "group": "WM_ERROR", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, "-279436615": { "message": "Moving to PAUSING: %s", "level": "VERBOSE", @@ -1813,12 +1825,6 @@ "group": "WM_DEBUG_TASKS", "at": "com\/android\/server\/wm\/ActivityTaskManagerService.java" }, - "91350919": { - "message": "Attempted to set IME flag to a display that does not exist: %d", - "level": "WARN", - "group": "WM_ERROR", - "at": "com\/android\/server\/wm\/WindowManagerService.java" - }, "94402792": { "message": "Moving to RESUMED: %s (in existing)", "level": "VERBOSE", @@ -1831,12 +1837,6 @@ "group": "WM_DEBUG_IME", "at": "com\/android\/server\/wm\/WindowManagerService.java" }, - "95281111": { - "message": "Attempted to get IME flag of a display that does not exist: %d", - "level": "WARN", - "group": "WM_ERROR", - "at": "com\/android\/server\/wm\/WindowManagerService.java" - }, "95902367": { "message": "Relayout of %s: focusMayChange=%b", "level": "VERBOSE", @@ -2101,12 +2101,6 @@ "group": "WM_DEBUG_ORIENTATION", "at": "com\/android\/server\/wm\/WindowManagerService.java" }, - "355940361": { - "message": "Config is destroying non-running %s", - "level": "VERBOSE", - "group": "WM_DEBUG_CONFIGURATION", - "at": "com\/android\/server\/wm\/ActivityRecord.java" - }, "371173718": { "message": "finishSync cancel=%b for %s", "level": "VERBOSE", @@ -2749,6 +2743,12 @@ "group": "WM_SHOW_SURFACE_ALLOC", "at": "com\/android\/server\/wm\/ScreenRotationAnimation.java" }, + "1100065297": { + "message": "Attempted to get IME policy of a display that does not exist: %d", + "level": "WARN", + "group": "WM_ERROR", + "at": "com\/android\/server\/wm\/WindowManagerService.java" + }, "1112047265": { "message": "finishDrawingWindow: %s mDrawState=%s", "level": "DEBUG", diff --git a/graphics/java/android/graphics/HardwareRenderer.java b/graphics/java/android/graphics/HardwareRenderer.java index a7f2739153e1..cb4dd9e8cacd 100644 --- a/graphics/java/android/graphics/HardwareRenderer.java +++ b/graphics/java/android/graphics/HardwareRenderer.java @@ -1163,7 +1163,7 @@ public class HardwareRenderer { // heuristic we don't need to be always 100% correct. Mode activeMode = display.getMode(); nInitDisplayInfo(activeMode.getPhysicalWidth(), activeMode.getPhysicalHeight(), - activeMode.getRefreshRate(), maxRefreshRate, + display.getRefreshRate(), maxRefreshRate, wideColorDataspace.mNativeDataspace, display.getAppVsyncOffsetNanos(), display.getPresentationDeadlineNanos()); diff --git a/graphics/java/android/graphics/Typeface.java b/graphics/java/android/graphics/Typeface.java index 712349aaee57..36ef0a48fa20 100644 --- a/graphics/java/android/graphics/Typeface.java +++ b/graphics/java/android/graphics/Typeface.java @@ -44,6 +44,7 @@ import android.text.FontConfig; import android.util.Base64; import android.util.LongSparseArray; import android.util.LruCache; +import android.util.Pair; import android.util.SparseArray; import com.android.internal.annotations.GuardedBy; @@ -1321,8 +1322,9 @@ public class Typeface { /** @hide */ public static void loadPreinstalledSystemFontMap() { final HashMap<String, Typeface> systemFontMap = new HashMap<>(); - initSystemDefaultTypefaces(systemFontMap, SystemFonts.getRawSystemFallbackMap(), - SystemFonts.getAliases()); + Pair<FontConfig.Alias[], Map<String, FontFamily[]>> pair = + SystemFonts.initializePreinstalledFonts(); + initSystemDefaultTypefaces(systemFontMap, pair.second, pair.first); setSystemFontMap(systemFontMap); } diff --git a/graphics/java/android/graphics/fonts/SystemFonts.java b/graphics/java/android/graphics/fonts/SystemFonts.java index 95c470634518..3635adc3ce39 100644 --- a/graphics/java/android/graphics/fonts/SystemFonts.java +++ b/graphics/java/android/graphics/fonts/SystemFonts.java @@ -22,7 +22,9 @@ import android.graphics.FontListParser; import android.text.FontConfig; import android.util.ArrayMap; import android.util.Log; +import android.util.Pair; +import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.ArrayUtils; @@ -51,9 +53,9 @@ public final class SystemFonts { private SystemFonts() {} // Do not instansiate. - private static final Map<String, FontFamily[]> sSystemFallbackMap; - private static final FontConfig.Alias[] sAliases; - private static final List<Font> sAvailableFonts; + private static final Object LOCK = new Object(); + private static @GuardedBy("sLock") Set<Font> sAvailableFonts; + private static @GuardedBy("sLock") Map<String, FontFamily[]> sFamilyMap; /** * Returns all available font files in the system. @@ -61,29 +63,24 @@ public final class SystemFonts { * @return a set of system fonts */ public static @NonNull Set<Font> getAvailableFonts() { - HashSet<Font> set = new HashSet<>(); - set.addAll(sAvailableFonts); - return set; - } + synchronized (LOCK) { + if (sAvailableFonts != null) { + return sAvailableFonts; + } - /** - * Returns raw system fallback map. - * - * This method is intended to be used only by Typeface static initializer. - * @hide - */ - public static @NonNull Map<String, FontFamily[]> getRawSystemFallbackMap() { - return sSystemFallbackMap; - } + Set<Font> set = new HashSet<>(); - /** - * Returns a list of aliases. - * - * This method is intended to be used only by Typeface static initializer. - * @hide - */ - public static @NonNull FontConfig.Alias[] getAliases() { - return sAliases; + for (FontFamily[] items : sFamilyMap.values()) { + for (FontFamily family : items) { + for (int i = 0; i < family.getSize(); ++i) { + set.add(family.getFont(i)); + } + } + } + + sAvailableFonts = Collections.unmodifiableSet(set); + return sAvailableFonts; + } } private static @Nullable ByteBuffer mmap(@NonNull String fullPath) { @@ -98,8 +95,7 @@ public final class SystemFonts { private static void pushFamilyToFallback(@NonNull FontConfig.Family xmlFamily, @NonNull ArrayMap<String, ArrayList<FontFamily>> fallbackMap, - @NonNull Map<String, ByteBuffer> cache, - @NonNull ArrayList<Font> availableFonts) { + @NonNull Map<String, ByteBuffer> cache) { final String languageTags = xmlFamily.getLanguages(); final int variant = xmlFamily.getVariant(); @@ -123,7 +119,7 @@ public final class SystemFonts { } final FontFamily defaultFamily = defaultFonts.isEmpty() ? null : createFontFamily( - xmlFamily.getName(), defaultFonts, languageTags, variant, cache, availableFonts); + xmlFamily.getName(), defaultFonts, languageTags, variant, cache); // Insert family into fallback map. for (int i = 0; i < fallbackMap.size(); i++) { @@ -135,8 +131,7 @@ public final class SystemFonts { } } else { final FontFamily family = createFontFamily( - xmlFamily.getName(), fallback, languageTags, variant, cache, - availableFonts); + xmlFamily.getName(), fallback, languageTags, variant, cache); if (family != null) { fallbackMap.valueAt(i).add(family); } else if (defaultFamily != null) { @@ -152,8 +147,7 @@ public final class SystemFonts { @NonNull List<FontConfig.Font> fonts, @NonNull String languageTags, @FontConfig.Family.Variant int variant, - @NonNull Map<String, ByteBuffer> cache, - @NonNull ArrayList<Font> availableFonts) { + @NonNull Map<String, ByteBuffer> cache) { if (fonts.size() == 0) { return null; } @@ -187,7 +181,6 @@ public final class SystemFonts { throw new RuntimeException(e); // Never reaches here } - availableFonts.add(font); if (b == null) { b = new FontFamily.Builder(font); } else { @@ -199,12 +192,11 @@ public final class SystemFonts { private static void appendNamedFamily(@NonNull FontConfig.Family xmlFamily, @NonNull HashMap<String, ByteBuffer> bufferCache, - @NonNull ArrayMap<String, ArrayList<FontFamily>> fallbackListMap, - @NonNull ArrayList<Font> availableFonts) { + @NonNull ArrayMap<String, ArrayList<FontFamily>> fallbackListMap) { final String familyName = xmlFamily.getName(); final FontFamily family = createFontFamily( familyName, Arrays.asList(xmlFamily.getFonts()), - xmlFamily.getLanguages(), xmlFamily.getVariant(), bufferCache, availableFonts); + xmlFamily.getLanguages(), xmlFamily.getVariant(), bufferCache); if (family == null) { return; } @@ -227,8 +219,7 @@ public final class SystemFonts { public static FontConfig.Alias[] buildSystemFallback(@NonNull String xmlPath, @NonNull String fontDir, @NonNull FontCustomizationParser.Result oemCustomization, - @NonNull ArrayMap<String, FontFamily[]> fallbackMap, - @NonNull ArrayList<Font> availableFonts) { + @NonNull Map<String, FontFamily[]> fallbackMap) { try { final FileInputStream fontsIn = new FileInputStream(xmlPath); final FontConfig fontConfig = FontListParser.parse(fontsIn, fontDir); @@ -243,12 +234,12 @@ public final class SystemFonts { if (familyName == null) { continue; } - appendNamedFamily(xmlFamily, bufferCache, fallbackListMap, availableFonts); + appendNamedFamily(xmlFamily, bufferCache, fallbackListMap); } for (int i = 0; i < oemCustomization.mAdditionalNamedFamilies.size(); ++i) { appendNamedFamily(oemCustomization.mAdditionalNamedFamilies.get(i), - bufferCache, fallbackListMap, availableFonts); + bufferCache, fallbackListMap); } // Then, add fallback fonts to the each fallback map. @@ -257,7 +248,7 @@ public final class SystemFonts { // The first family (usually the sans-serif family) is always placed immediately // after the primary family in the fallback. if (i == 0 || xmlFamily.getName() == null) { - pushFamilyToFallback(xmlFamily, fallbackListMap, bufferCache, availableFonts); + pushFamilyToFallback(xmlFamily, fallbackListMap, bufferCache); } } @@ -292,14 +283,17 @@ public final class SystemFonts { } } - static { - final ArrayMap<String, FontFamily[]> systemFallbackMap = new ArrayMap<>(); - final ArrayList<Font> availableFonts = new ArrayList<>(); + /** @hide */ + public static @NonNull Pair<FontConfig.Alias[], Map<String, FontFamily[]>> + initializePreinstalledFonts() { final FontCustomizationParser.Result oemCustomization = readFontCustomization("/product/etc/fonts_customization.xml", "/product/fonts/"); - sAliases = buildSystemFallback("/system/etc/fonts.xml", "/system/fonts/", - oemCustomization, systemFallbackMap, availableFonts); - sSystemFallbackMap = Collections.unmodifiableMap(systemFallbackMap); - sAvailableFonts = Collections.unmodifiableList(availableFonts); + Map<String, FontFamily[]> map = new ArrayMap<>(); + FontConfig.Alias[] aliases = buildSystemFallback("/system/etc/fonts.xml", "/system/fonts/", + oemCustomization, map); + synchronized (LOCK) { + sFamilyMap = map; + } + return new Pair(aliases, map); } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/Transitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/Transitions.java index 388eb28223dc..120039de1240 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/Transitions.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/Transitions.java @@ -116,7 +116,7 @@ public class Transitions extends ITransitionPlayer.Stub { } @Override - public void onTransitionReady(@NonNull IBinder transitionToken, TransitionInfo info, + public void onTransitionReady(@NonNull IBinder transitionToken, @NonNull TransitionInfo info, @NonNull SurfaceControl.Transaction t) { ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "onTransitionReady %s: %s", transitionToken, info); @@ -131,22 +131,53 @@ public class Transitions extends ITransitionPlayer.Stub { + transitionToken); } mActiveTransitions.put(transitionToken, new ArrayList<>()); - for (int i = 0; i < info.getChanges().size(); ++i) { - final SurfaceControl leash = info.getChanges().get(i).getLeash(); + boolean isOpening = isOpeningType(info.getType()); + if (info.getRootLeash().isValid()) { + t.show(info.getRootLeash()); + } + // changes should be ordered top-to-bottom in z + for (int i = info.getChanges().size() - 1; i >= 0; --i) { + final TransitionInfo.Change change = info.getChanges().get(i); + final SurfaceControl leash = change.getLeash(); final int mode = info.getChanges().get(i).getMode(); + + // Don't animate anything with an animating parent + if (change.getParent() != null) { + if (mode == TRANSIT_OPEN || mode == TRANSIT_SHOW) { + t.show(leash); + t.setMatrix(leash, 1, 0, 0, 1); + } + continue; + } + + t.reparent(leash, info.getRootLeash()); + t.setPosition(leash, change.getEndAbsBounds().left - info.getRootOffset().x, + change.getEndAbsBounds().top - info.getRootOffset().y); + // Put all the OPEN/SHOW on top if (mode == TRANSIT_OPEN || mode == TRANSIT_SHOW) { t.show(leash); t.setMatrix(leash, 1, 0, 0, 1); - if (isOpeningType(info.getType())) { + if (isOpening) { + // put on top and fade in + t.setLayer(leash, info.getChanges().size() - i); t.setAlpha(leash, 0.f); startExampleAnimation(transitionToken, leash, true /* show */); } else { + // put on bottom and leave it visible without fade + t.setLayer(leash, -i); t.setAlpha(leash, 1.f); } } else if (mode == TRANSIT_CLOSE || mode == TRANSIT_HIDE) { - if (!isOpeningType(info.getType())) { + if (isOpening) { + // put on bottom and leave visible without fade + t.setLayer(leash, -i); + } else { + // put on top and fade out + t.setLayer(leash, info.getChanges().size() - i); startExampleAnimation(transitionToken, leash, false /* show */); } + } else { + t.setLayer(leash, info.getChanges().size() - i); } } t.apply(); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuActivityController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuActivityController.java index 1d5430008501..d4217553ef2d 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuActivityController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuActivityController.java @@ -239,7 +239,9 @@ public class PipMenuActivityController { + " callers=\n" + Debug.getCallers(5, " ")); } - maybeCreateSyncApplier(); + if (!maybeCreateSyncApplier()) { + return; + } mPipMenuView.showMenu(menuState, stackBounds, allowMenuTimeout, willResizeMenu, withDelay, showResizeHandle); diff --git a/libs/WindowManager/Shell/tests/flicker/Android.bp b/libs/WindowManager/Shell/tests/flicker/Android.bp index d7afa0e166b3..1bbe6884a48c 100644 --- a/libs/WindowManager/Shell/tests/flicker/Android.bp +++ b/libs/WindowManager/Shell/tests/flicker/Android.bp @@ -29,7 +29,10 @@ android_test { "truth-prebuilt", "app-helpers-core", "launcher-helper-lib", - "launcher-aosp-tapl" + "launcher-aosp-tapl", + "wm-flicker-common-assertions", + "wm-flicker-common-app-helpers", + "platform-test-annotations", ], } @@ -47,6 +50,9 @@ android_test { "truth-prebuilt", "app-helpers-core", "launcher-helper-lib", - "launcher-aosp-tapl" + "launcher-aosp-tapl", + "wm-flicker-common-assertions", + "wm-flicker-common-app-helpers", + "platform-test-annotations", ], } diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonConstants.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonConstants.kt index 3c222e7d8b56..bbf5afcff67a 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonConstants.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonConstants.kt @@ -31,6 +31,10 @@ val TEST_APP_PIP_ACTIVITY_COMPONENT_NAME: ComponentName = ComponentName.createRe TEST_APP_PACKAGE_NAME, ".PipActivity") const val TEST_APP_PIP_ACTIVITY_LABEL = "PipApp" const val TEST_APP_PIP_ACTIVITY_WINDOW_NAME = "PipActivity" +const val TEST_APP_PIP_MENU_ACTION_NO_OP = "No-Op" +const val TEST_APP_PIP_MENU_ACTION_ON = "On" +const val TEST_APP_PIP_MENU_ACTION_OFF = "Off" +const val TEST_APP_PIP_MENU_ACTION_CLEAR = "Clear" // Test App > Ime Activity val TEST_APP_IME_ACTIVITY_COMPONENT_NAME: ComponentName = ComponentName.createRelative( diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/PipAppHelper.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/PipAppHelper.kt index 532b3de6c99e..e85ba9ef6da2 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/PipAppHelper.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/PipAppHelper.kt @@ -70,6 +70,12 @@ class PipAppHelper( startButton.click() } + fun checkWithCustomActionsCheckbox() = uiDevice + .findObject(By.res(packageName, "with_custom_actions")) + ?.takeIf { it.isCheckable } + ?.apply { if (!isChecked) click() } + ?: error("'With custom actions' checkbox not found") + fun pauseMedia() = mediaController?.transportControls?.pause() ?: error("No active media session found") diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/pip/CommonAssertions.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/CommonAssertions.kt index 6bc9dcb5d96c..2a660747bc1d 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/pip/CommonAssertions.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/CommonAssertions.kt @@ -14,6 +14,6 @@ * limitations under the License. */ -package com.android.server.wm.flicker.pip +package com.android.wm.shell.flicker.pip internal const val PIP_WINDOW_TITLE = "PipMenuActivity" diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt index a1da7c939f60..cb1fe4e2981d 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt @@ -19,104 +19,113 @@ package com.android.wm.shell.flicker.pip import android.view.Surface import androidx.test.filters.FlakyTest import androidx.test.filters.RequiresDevice -import com.android.server.wm.flicker.dsl.flicker +import androidx.test.platform.app.InstrumentationRegistry +import com.android.server.wm.flicker.Flicker +import com.android.server.wm.flicker.FlickerTestRunner +import com.android.server.wm.flicker.FlickerTestRunnerFactory +import com.android.server.wm.flicker.helpers.buildTestTag import com.android.server.wm.flicker.helpers.closePipWindow import com.android.server.wm.flicker.helpers.expandPipWindow import com.android.server.wm.flicker.helpers.hasPipWindow +import com.android.server.wm.flicker.helpers.setRotation import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen -import com.android.wm.shell.flicker.navBarLayerIsAlwaysVisible -import com.android.wm.shell.flicker.navBarLayerRotatesAndScales -import com.android.wm.shell.flicker.navBarWindowIsAlwaysVisible -import com.android.wm.shell.flicker.noUncoveredRegions -import com.android.wm.shell.flicker.statusBarLayerIsAlwaysVisible -import com.android.wm.shell.flicker.statusBarLayerRotatesScales -import com.android.wm.shell.flicker.statusBarWindowIsAlwaysVisible -import com.android.wm.shell.flicker.PIP_WINDOW_NAME +import com.android.server.wm.flicker.navBarLayerIsAlwaysVisible +import com.android.server.wm.flicker.navBarLayerRotatesAndScales +import com.android.server.wm.flicker.statusBarLayerIsAlwaysVisible +import com.android.server.wm.flicker.statusBarLayerRotatesScales +import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible +import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible +import com.android.server.wm.flicker.noUncoveredRegions +import com.android.server.wm.flicker.repetitions +import com.android.server.wm.flicker.startRotation +import com.android.wm.shell.flicker.helpers.PipAppHelper import org.junit.FixMethodOrder -import org.junit.Test import org.junit.runner.RunWith import org.junit.runners.MethodSorters import org.junit.runners.Parameterized /** * Test Pip launch. - * To run this test: `atest WMShellFlickerTests:PipToAppTest` + * To run this test: `atest WMShellFlickerTests:EnterPipTest` */ @RequiresDevice @RunWith(Parameterized::class) @FixMethodOrder(MethodSorters.NAME_ASCENDING) @FlakyTest(bugId = 152738416) class EnterPipTest( - rotationName: String, - rotation: Int -) : PipTestBase(rotationName, rotation) { - @Test - fun test() { - flicker(instrumentation) { - withTag { buildTestTag("enterPip", testApp, rotation) } - repeat { 1 } - setup { - test { - device.wakeUpAndGoToHomeScreen() - } - eachRun { - device.pressHome() - testApp.open() - this.setRotation(rotation) - } - } - teardown { - eachRun { - if (device.hasPipWindow()) { - device.closePipWindow() + testName: String, + flickerSpec: Flicker +) : FlickerTestRunner(testName, flickerSpec) { + companion object { + @Parameterized.Parameters(name = "{0}") + @JvmStatic + fun getParams(): List<Array<Any>> { + val instrumentation = InstrumentationRegistry.getInstrumentation() + val testApp = PipAppHelper(instrumentation) + return FlickerTestRunnerFactory(instrumentation, listOf(Surface.ROTATION_0)) + .buildTest { configuration -> + withTestName { buildTestTag("enterPip", testApp, configuration) } + repeat { configuration.repetitions } + setup { + test { + device.wakeUpAndGoToHomeScreen() + } + eachRun { + device.pressHome() + testApp.open() + this.setRotation(configuration.startRotation) + } } - testApp.exit() - this.setRotation(Surface.ROTATION_0) - } - test { - if (device.hasPipWindow()) { - device.closePipWindow() + teardown { + eachRun { + if (device.hasPipWindow()) { + device.closePipWindow() + } + testApp.exit() + this.setRotation(Surface.ROTATION_0) + } + test { + if (device.hasPipWindow()) { + device.closePipWindow() + } + } } - } - } - transitions { - testApp.clickEnterPipButton() - device.expandPipWindow() - } - assertions { - windowManagerTrace { - navBarWindowIsAlwaysVisible() - statusBarWindowIsAlwaysVisible() - all("pipWindowBecomesVisible") { - this.showsAppWindow(testApp.`package`) - .then() - .showsAppWindow(PIP_WINDOW_NAME) + transitions { + testApp.clickEnterPipButton() + device.expandPipWindow() } - } + assertions { + windowManagerTrace { + navBarWindowIsAlwaysVisible() + statusBarWindowIsAlwaysVisible() - layersTrace { - navBarLayerIsAlwaysVisible() - statusBarLayerIsAlwaysVisible() - noUncoveredRegions(rotation, Surface.ROTATION_0, allStates = false) - navBarLayerRotatesAndScales(rotation, Surface.ROTATION_0) - statusBarLayerRotatesScales(rotation, Surface.ROTATION_0) + all("pipWindowBecomesVisible") { + this.showsAppWindow(testApp.`package`) + .then() + .showsAppWindow(PIP_WINDOW_TITLE) + } + } - all("pipLayerBecomesVisible") { - this.showsLayer(testApp.launcherName) - .then() - .showsLayer(PIP_WINDOW_NAME) + layersTrace { + navBarLayerIsAlwaysVisible(bugId = 140855415) + statusBarLayerIsAlwaysVisible() + noUncoveredRegions(configuration.startRotation, Surface.ROTATION_0, + enabled = false) + navBarLayerRotatesAndScales(configuration.startRotation, + Surface.ROTATION_0, bugId = 140855415) + statusBarLayerRotatesScales(configuration.startRotation, + Surface.ROTATION_0) + } + + layersTrace { + all("pipLayerBecomesVisible") { + this.showsLayer(testApp.launcherName) + .then() + .showsLayer(PIP_WINDOW_TITLE) + } + } } } - } - } - } - - companion object { - @Parameterized.Parameters(name = "{0}") - @JvmStatic - fun getParams(): Collection<Array<Any>> { - val supportedRotations = intArrayOf(Surface.ROTATION_0) - return supportedRotations.map { arrayOf(Surface.rotationToString(it), it) } } } -} +}
\ No newline at end of file diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/pip/PipToAppTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipToAppTest.kt index ac54a0a29350..e1fa6578e552 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/pip/PipToAppTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipToAppTest.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.server.wm.flicker.pip +package com.android.wm.shell.flicker.pip import android.view.Surface import androidx.test.filters.FlakyTest @@ -24,7 +24,6 @@ import com.android.server.wm.flicker.Flicker import com.android.server.wm.flicker.FlickerTestRunner import com.android.server.wm.flicker.FlickerTestRunnerFactory import com.android.server.wm.flicker.focusChanges -import com.android.server.wm.flicker.helpers.PipAppHelper import com.android.server.wm.flicker.helpers.buildTestTag import com.android.server.wm.flicker.helpers.closePipWindow import com.android.server.wm.flicker.helpers.expandPipWindow @@ -40,6 +39,7 @@ import com.android.server.wm.flicker.startRotation import com.android.server.wm.flicker.statusBarLayerIsAlwaysVisible import com.android.server.wm.flicker.statusBarLayerRotatesScales import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible +import com.android.wm.shell.flicker.helpers.PipAppHelper import org.junit.FixMethodOrder import org.junit.runner.RunWith import org.junit.runners.MethodSorters @@ -47,7 +47,7 @@ import org.junit.runners.Parameterized /** * Test Pip launch. - * To run this test: `atest FlickerTests:PipToAppTest` + * To run this test: `atest WMShellFlickerTests:PipToAppTest` */ @RequiresDevice @RunWith(Parameterized::class) @@ -75,7 +75,7 @@ class PipToAppTest( } eachRun { this.setRotation(configuration.startRotation) - testApp.clickEnterPipButton(device) + testApp.clickEnterPipButton() device.hasPipWindow() } } diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/pip/PipToHomeTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipToHomeTest.kt index f14a27d31ad1..bf1193786a59 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/pip/PipToHomeTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipToHomeTest.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.server.wm.flicker.pip +package com.android.wm.shell.flicker.pip import android.view.Surface import androidx.test.filters.FlakyTest @@ -24,7 +24,6 @@ import com.android.server.wm.flicker.Flicker import com.android.server.wm.flicker.FlickerTestRunner import com.android.server.wm.flicker.FlickerTestRunnerFactory import com.android.server.wm.flicker.focusChanges -import com.android.server.wm.flicker.helpers.PipAppHelper import com.android.server.wm.flicker.helpers.buildTestTag import com.android.server.wm.flicker.helpers.closePipWindow import com.android.server.wm.flicker.helpers.hasPipWindow @@ -39,6 +38,7 @@ import com.android.server.wm.flicker.startRotation import com.android.server.wm.flicker.statusBarLayerIsAlwaysVisible import com.android.server.wm.flicker.statusBarLayerRotatesScales import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible +import com.android.wm.shell.flicker.helpers.PipAppHelper import org.junit.FixMethodOrder import org.junit.runner.RunWith import org.junit.runners.MethodSorters @@ -46,7 +46,7 @@ import org.junit.runners.Parameterized /** * Test Pip launch. - * To run this test: `atest FlickerTests:PipToHomeTest` + * To run this test: `atest WMShellFlickerTests:PipToHomeTest` */ @RequiresDevice @RunWith(Parameterized::class) @@ -74,7 +74,7 @@ class PipToHomeTest( eachRun { testApp.open() this.setRotation(configuration.startRotation) - testApp.clickEnterPipButton(device) + testApp.clickEnterPipButton() device.hasPipWindow() } } @@ -93,7 +93,7 @@ class PipToHomeTest( } } transitions { - testApp.closePipWindow(device) + testApp.closePipWindow() } assertions { windowManagerTrace { diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/TvPipMenuTests.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/TvPipMenuTests.kt index 871732cf7460..4cb6447f7d7e 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/TvPipMenuTests.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/TvPipMenuTests.kt @@ -20,7 +20,12 @@ import android.graphics.Rect import androidx.test.filters.RequiresDevice import androidx.test.uiautomator.UiObject2 import com.android.wm.shell.flicker.SYSTEM_UI_PACKAGE_NAME +import com.android.wm.shell.flicker.TEST_APP_PIP_MENU_ACTION_CLEAR +import com.android.wm.shell.flicker.TEST_APP_PIP_MENU_ACTION_NO_OP +import com.android.wm.shell.flicker.TEST_APP_PIP_MENU_ACTION_OFF +import com.android.wm.shell.flicker.TEST_APP_PIP_MENU_ACTION_ON import com.android.wm.shell.flicker.wait +import org.junit.Assert.assertNull import org.junit.Assert.assertTrue import org.junit.Before import org.junit.Test @@ -128,6 +133,7 @@ class TvPipMenuTests : TvPipTestBase() { testApp.clickStartMediaSessionButton() enterPip_openMenu_assertShown() + assertFullscreenAndCloseButtonsAreShown() // PiP menu should contain the Pause button val pauseButton = uiDevice.findTvPipMenuElementWithDescription(pauseButtonDescription) @@ -137,6 +143,7 @@ class TvPipMenuTests : TvPipTestBase() { // When we pause media, the button should change from Pause to Play pauseButton.click() + assertFullscreenAndCloseButtonsAreShown() // PiP menu should contain the Play button now uiDevice.waitForTvPipMenuElementWithDescription(playButtonDescription) ?: fail("\"Play\" button should be shown in Pip menu if there is an active " + @@ -145,10 +152,99 @@ class TvPipMenuTests : TvPipTestBase() { testApp.closePipWindow() } + @Test + fun pipMenu_withCustomActions() { + // Enter PiP with custom actions. + testApp.checkWithCustomActionsCheckbox() + enterPip_openMenu_assertShown() + + // PiP menu should contain "No-Op", "Off" and "Clear" buttons... + uiDevice.findTvPipMenuElementWithDescription(TEST_APP_PIP_MENU_ACTION_NO_OP) + ?: fail("\"No-Op\" button should be shown in Pip menu") + val offButton = uiDevice.findTvPipMenuElementWithDescription(TEST_APP_PIP_MENU_ACTION_OFF) + ?: fail("\"Off\" button should be shown in Pip menu") + uiDevice.findTvPipMenuElementWithDescription(TEST_APP_PIP_MENU_ACTION_CLEAR) + ?: fail("\"Clear\" button should be shown in Pip menu") + // ... and should also contain the "Full screen" and "Close" buttons. + assertFullscreenAndCloseButtonsAreShown() + + offButton.click() + // Invoking the "Off" action should replace it with the "On" action/button and should + // remove the "No-Op" action/button. "Clear" action/button should remain in the menu ... + uiDevice.waitForTvPipMenuElementWithDescription(TEST_APP_PIP_MENU_ACTION_ON) + ?: fail("\"On\" button should be shown in Pip for a corresponding custom action") + assertNull("\"No-Op\" button should not be shown in Pip menu", + uiDevice.findTvPipMenuElementWithDescription(TEST_APP_PIP_MENU_ACTION_NO_OP)) + val clearButton = + uiDevice.findTvPipMenuElementWithDescription(TEST_APP_PIP_MENU_ACTION_CLEAR) + ?: fail("\"Clear\" button should be shown in Pip menu") + // ... as well as the "Full screen" and "Close" buttons. + assertFullscreenAndCloseButtonsAreShown() + + clearButton.click() + // Invoking the "Clear" action should remove all the custom actions and their corresponding + // buttons, ... + uiDevice.waitUntilTvPipMenuElementWithDescriptionIsGone(TEST_APP_PIP_MENU_ACTION_ON)?.also { + isGone -> if (!isGone) fail("\"On\" button should not be shown in Pip menu") + } + assertNull("\"Off\" button should not be shown in Pip menu", + uiDevice.findTvPipMenuElementWithDescription(TEST_APP_PIP_MENU_ACTION_OFF)) + assertNull("\"Clear\" button should not be shown in Pip menu", + uiDevice.findTvPipMenuElementWithDescription(TEST_APP_PIP_MENU_ACTION_CLEAR)) + assertNull("\"No-Op\" button should not be shown in Pip menu", + uiDevice.findTvPipMenuElementWithDescription(TEST_APP_PIP_MENU_ACTION_NO_OP)) + // ... but the menu should still contain the "Full screen" and "Close" buttons. + assertFullscreenAndCloseButtonsAreShown() + + testApp.closePipWindow() + } + + @Test + fun pipMenu_customActions_override_mediaControls() { + // Start media session before entering PiP with custom actions. + testApp.clickStartMediaSessionButton() + testApp.checkWithCustomActionsCheckbox() + enterPip_openMenu_assertShown() + + // PiP menu should contain "No-Op", "Off" and "Clear" buttons for the custom actions... + uiDevice.findTvPipMenuElementWithDescription(TEST_APP_PIP_MENU_ACTION_NO_OP) + ?: fail("\"No-Op\" button should be shown in Pip menu") + uiDevice.findTvPipMenuElementWithDescription(TEST_APP_PIP_MENU_ACTION_OFF) + ?: fail("\"Off\" button should be shown in Pip menu") + val clearButton = + uiDevice.findTvPipMenuElementWithDescription(TEST_APP_PIP_MENU_ACTION_CLEAR) + ?: fail("\"Clear\" button should be shown in Pip menu") + // ... should also contain the "Full screen" and "Close" buttons, ... + assertFullscreenAndCloseButtonsAreShown() + // ... but should not contain media buttons. + assertNull("\"Play\" button should not be shown in menu when there are custom actions", + uiDevice.findTvPipMenuElementWithDescription(playButtonDescription)) + assertNull("\"Pause\" button should not be shown in menu when there are custom actions", + uiDevice.findTvPipMenuElementWithDescription(pauseButtonDescription)) + + clearButton.click() + // Invoking the "Clear" action should remove all the custom actions, which should bring up + // media buttons... + uiDevice.waitForTvPipMenuElementWithDescription(pauseButtonDescription) + ?: fail("\"Pause\" button should be shown in Pip menu if there is an active " + + "playing media session.") + // ... while the "Full screen" and "Close" buttons should remain in the menu. + assertFullscreenAndCloseButtonsAreShown() + + testApp.closePipWindow() + } + private fun enterPip_openMenu_assertShown(): UiObject2 { testApp.clickEnterPipButton() // Pressing the Window key should bring up Pip menu uiDevice.pressWindowKey() return uiDevice.waitForTvPipMenu() ?: fail("Pip menu should have been shown") } + + private fun assertFullscreenAndCloseButtonsAreShown() { + uiDevice.findTvPipMenuCloseButton() + ?: fail("\"Close PIP\" button should be shown in Pip menu") + uiDevice.findTvPipMenuFullscreenButton() + ?: fail("\"Full screen\" button should be shown in Pip menu") + } }
\ No newline at end of file diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/TvUtils.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/TvUtils.kt index 8db8bc67da14..0732794903b7 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/TvUtils.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/TvUtils.kt @@ -58,6 +58,9 @@ fun UiDevice.waitForTvPipMenuElementWithDescription(desc: String): UiObject2? { ?.findObject(buttonSelector) } +fun UiDevice.waitUntilTvPipMenuElementWithDescriptionIsGone(desc: String): Boolean? = + wait(Until.gone(By.copy(tvPipMenuSelector).hasDescendant(By.desc(desc))), WAIT_TIME_MS) + fun UiObject2.isFullscreen(uiDevice: UiDevice): Boolean = visibleBounds.run { height() == uiDevice.displayHeight && width() == uiDevice.displayWidth }
\ No newline at end of file diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/OpenAppToSplitScreenTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/OpenAppToSplitScreenTest.kt index ae9fcf9a3b6e..1e328a8dae40 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/OpenAppToSplitScreenTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/OpenAppToSplitScreenTest.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.server.wm.flicker.splitscreen +package com.android.wm.shell.flicker.splitscreen import android.platform.test.annotations.Presubmit import androidx.test.filters.FlakyTest @@ -48,7 +48,7 @@ import org.junit.runners.Parameterized /** * Test open app to split screen. - * To run this test: `atest FlickerTests:OpenAppToSplitScreenTest` + * To run this test: `atest WMShellFlickerTests:OpenAppToSplitScreenTest` */ @Presubmit @RequiresDevice @@ -65,7 +65,7 @@ class OpenAppToSplitScreenTest( fun getParams(): Collection<Array<Any>> { val instrumentation = InstrumentationRegistry.getInstrumentation() val testApp = StandardAppHelper(instrumentation, - "com.android.server.wm.flicker.testapp", "SimpleApp") + "com.android.wm.shell.flicker.testapp", "SimpleApp") return FlickerTestRunnerFactory(instrumentation) .buildTest { configuration -> diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/ResizeSplitScreenTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/ResizeSplitScreenTest.kt index 4b9f02412f2a..7c83846621de 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/ResizeSplitScreenTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/ResizeSplitScreenTest.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.server.wm.flicker.splitscreen +package com.android.wm.shell.flicker.splitscreen import android.graphics.Region import android.util.Rational @@ -29,8 +29,8 @@ import com.android.server.wm.flicker.FlickerTestRunner import com.android.server.wm.flicker.FlickerTestRunnerFactory import com.android.server.wm.flicker.endRotation import com.android.server.wm.flicker.helpers.StandardAppHelper -import com.android.server.wm.flicker.focusDoesNotChange import com.android.server.wm.flicker.helpers.ImeAppHelper +import com.android.server.wm.flicker.focusDoesNotChange import com.android.server.wm.flicker.helpers.WindowUtils import com.android.server.wm.flicker.helpers.buildTestTag import com.android.server.wm.flicker.helpers.exitSplitScreen @@ -55,7 +55,7 @@ import org.junit.runners.Parameterized /** * Test split screen resizing window transitions. - * To run this test: `atest FlickerTests:ResizeSplitScreenTest` + * To run this test: `atest WMShellFlickerTests:ResizeSplitScreenTest` * * Currently it runs only in 0 degrees because of b/156100803 */ @@ -78,7 +78,7 @@ class ResizeSplitScreenTest( fun getParams(): Collection<Array<Any>> { val instrumentation = InstrumentationRegistry.getInstrumentation() val testAppTop = StandardAppHelper(instrumentation, - "com.android.server.wm.flicker.testapp", "SimpleApp") + "com.android.wm.shell.flicker.testapp", "SimpleApp") val testAppBottom = ImeAppHelper(instrumentation) return FlickerTestRunnerFactory(instrumentation, listOf(Surface.ROTATION_0)) diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/SplitScreenToLauncherTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SplitScreenToLauncherTest.kt index f966a66aa0a1..00979fa9fac0 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/SplitScreenToLauncherTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SplitScreenToLauncherTest.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.server.wm.flicker.splitscreen +package com.android.wm.shell.flicker.splitscreen import android.platform.test.annotations.Presubmit import android.view.Surface @@ -48,7 +48,7 @@ import org.junit.runners.Parameterized /** * Test open app to split screen. - * To run this test: `atest FlickerTests:SplitScreenToLauncherTest` + * To run this test: `atest WMShellFlickerTests:SplitScreenToLauncherTest` */ @Presubmit @RequiresDevice @@ -64,7 +64,7 @@ class SplitScreenToLauncherTest( fun getParams(): Collection<Array<Any>> { val instrumentation = InstrumentationRegistry.getInstrumentation() val testApp = StandardAppHelper(instrumentation, - "com.android.server.wm.flicker.testapp", "SimpleApp") + "com.android.wm.shell.flicker.testapp", "SimpleApp") // b/161435597 causes the test not to work on 90 degrees return FlickerTestRunnerFactory(instrumentation, listOf(Surface.ROTATION_0)) diff --git a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/AndroidManifest.xml b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/AndroidManifest.xml index 2ce120448ac4..628926a97bf5 100644 --- a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/AndroidManifest.xml +++ b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/AndroidManifest.xml @@ -73,5 +73,15 @@ <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> + + <activity android:name=".SimpleActivity" + android:taskAffinity="com.android.wm.shell.flicker.testapp.SimpleActivity" + android:label="SimpleApp" + android:exported="true"> + <intent-filter> + <action android:name="android.intent.action.MAIN"/> + <category android:name="android.intent.category.LAUNCHER"/> + </intent-filter> + </activity> </application> </manifest> diff --git a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/res/layout/activity_pip.xml b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/res/layout/activity_pip.xml index b4a4c165cc7b..e5d2f82080a2 100644 --- a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/res/layout/activity_pip.xml +++ b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/res/layout/activity_pip.xml @@ -28,6 +28,12 @@ android:text="Enter PIP" android:onClick="enterPip"/> + <CheckBox + android:id="@+id/with_custom_actions" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="With custom actions"/> + <RadioGroup android:layout_width="match_parent" android:layout_height="wrap_content" diff --git a/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_pip.xml b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/res/layout/activity_simple.xml index 2c58d91e34fe..5d94e5177dcc 100644 --- a/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_pip.xml +++ b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/res/layout/activity_simple.xml @@ -18,9 +18,6 @@ xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" - android:background="@android:color/holo_blue_bright"> - <Button android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:id="@+id/enter_pip" - android:text="Enter PIP"/> + android:background="@android:color/holo_orange_light"> + </LinearLayout> diff --git a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/PipActivity.java b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/PipActivity.java index d2fcd0d31558..909219583bf7 100644 --- a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/PipActivity.java +++ b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/PipActivity.java @@ -25,7 +25,15 @@ import static android.media.session.PlaybackState.STATE_PLAYING; import static android.media.session.PlaybackState.STATE_STOPPED; import android.app.Activity; +import android.app.PendingIntent; import android.app.PictureInPictureParams; +import android.app.RemoteAction; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.res.Configuration; +import android.graphics.drawable.Icon; import android.media.MediaMetadata; import android.media.session.MediaSession; import android.media.session.PlaybackState; @@ -34,6 +42,12 @@ import android.util.Rational; import android.view.View; import android.view.Window; import android.view.WindowManager; +import android.widget.CheckBox; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; public class PipActivity extends Activity { /** @@ -52,7 +66,19 @@ public class PipActivity extends Activity { private static final Rational RATIO_WIDE = new Rational(2, 1); private static final Rational RATIO_TALL = new Rational(1, 2); - private PictureInPictureParams.Builder mPipParamsBuilder; + private static final String PIP_ACTION_NO_OP = "No-Op"; + private static final String PIP_ACTION_OFF = "Off"; + private static final String PIP_ACTION_ON = "On"; + private static final String PIP_ACTION_CLEAR = "Clear"; + private static final String ACTION_NO_OP = "com.android.wm.shell.flicker.testapp.NO_OP"; + private static final String ACTION_SWITCH_OFF = + "com.android.wm.shell.flicker.testapp.SWITCH_OFF"; + private static final String ACTION_SWITCH_ON = "com.android.wm.shell.flicker.testapp.SWITCH_ON"; + private static final String ACTION_CLEAR = "com.android.wm.shell.flicker.testapp.CLEAR"; + + private final PictureInPictureParams.Builder mPipParamsBuilder = + new PictureInPictureParams.Builder() + .setAspectRatio(RATIO_DEFAULT); private MediaSession mMediaSession; private final PlaybackState.Builder mPlaybackStateBuilder = new PlaybackState.Builder() .setActions(ACTION_PLAY | ACTION_PAUSE | ACTION_STOP) @@ -60,6 +86,30 @@ public class PipActivity extends Activity { private PlaybackState mPlaybackState = mPlaybackStateBuilder.build(); private final MediaMetadata.Builder mMediaMetadataBuilder = new MediaMetadata.Builder(); + private final List<RemoteAction> mSwitchOffActions = new ArrayList<>(); + private final List<RemoteAction> mSwitchOnActions = new ArrayList<>(); + private final BroadcastReceiver mCustomActionReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + switch (intent.getAction()) { + case ACTION_SWITCH_ON: + mPipParamsBuilder.setActions(mSwitchOnActions); + break; + case ACTION_SWITCH_OFF: + mPipParamsBuilder.setActions(mSwitchOffActions); + break; + case ACTION_CLEAR: + mPipParamsBuilder.setActions(Collections.emptyList()); + break; + case ACTION_NO_OP: + default: + return; + } + setPictureInPictureParams(mPipParamsBuilder.build()); + } + }; + private boolean mIsReceiverRegistered = false; + @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -72,9 +122,6 @@ public class PipActivity extends Activity { setContentView(R.layout.activity_pip); - mPipParamsBuilder = new PictureInPictureParams.Builder() - .setAspectRatio(RATIO_DEFAULT); - findViewById(R.id.media_session_start) .setOnClickListener(v -> updateMediaSessionState(STATE_PLAYING)); findViewById(R.id.media_session_stop) @@ -98,9 +145,63 @@ public class PipActivity extends Activity { updateMediaSessionState(STATE_STOPPED); } }); + + // Build two sets of the custom actions. We'll replace one with the other when 'On'/'Off' + // action is invoked. + // The first set consists of 3 actions: 1) Off; 2) No-Op; 3) Clear. + // The second set consists of 2 actions: 1) On; 2) Clear. + // Upon invocation 'Clear' action clear-off all the custom actions, including itself. + final Icon icon = Icon.createWithResource(this, android.R.drawable.ic_menu_help); + final RemoteAction noOpAction = buildRemoteAction(icon, PIP_ACTION_NO_OP, ACTION_NO_OP); + final RemoteAction switchOnAction = + buildRemoteAction(icon, PIP_ACTION_ON, ACTION_SWITCH_ON); + final RemoteAction switchOffAction = + buildRemoteAction(icon, PIP_ACTION_OFF, ACTION_SWITCH_OFF); + final RemoteAction clearAllAction = buildRemoteAction(icon, PIP_ACTION_CLEAR, ACTION_CLEAR); + mSwitchOffActions.addAll(Arrays.asList(switchOnAction, clearAllAction)); + mSwitchOnActions.addAll(Arrays.asList(noOpAction, switchOffAction, clearAllAction)); + } + + @Override + protected void onDestroy() { + if (mIsReceiverRegistered) { + unregisterReceiver(mCustomActionReceiver); + mIsReceiverRegistered = false; + } + super.onDestroy(); + } + + @Override + public void onPictureInPictureModeChanged(boolean isInPictureInPictureMode, + Configuration newConfig) { + if (isInPictureInPictureMode && !mIsReceiverRegistered) { + final IntentFilter filter = new IntentFilter(); + filter.addAction(ACTION_NO_OP); + filter.addAction(ACTION_SWITCH_ON); + filter.addAction(ACTION_SWITCH_OFF); + filter.addAction(ACTION_CLEAR); + registerReceiver(mCustomActionReceiver, filter); + + mIsReceiverRegistered = true; + } else if (!isInPictureInPictureMode && mIsReceiverRegistered) { + unregisterReceiver(mCustomActionReceiver); + + mIsReceiverRegistered = false; + } + } + + private RemoteAction buildRemoteAction(Icon icon, String label, String action) { + final Intent intent = new Intent(action); + final PendingIntent pendingIntent = + PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT); + return new RemoteAction(icon, label, label, pendingIntent); } public void enterPip(View v) { + final boolean withCustomActions = + ((CheckBox) findViewById(R.id.with_custom_actions)).isChecked(); + mPipParamsBuilder.setActions( + withCustomActions ? mSwitchOnActions : Collections.emptyList()); enterPictureInPictureMode(mPipParamsBuilder.build()); } diff --git a/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/PipActivity.java b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/SimpleActivity.java index 9a8f39907877..5343c1893d4e 100644 --- a/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/PipActivity.java +++ b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/SimpleActivity.java @@ -14,17 +14,13 @@ * limitations under the License. */ -package com.android.server.wm.flicker.testapp; +package com.android.wm.shell.flicker.testapp; import android.app.Activity; -import android.app.PictureInPictureParams; -import android.graphics.Rect; import android.os.Bundle; -import android.util.Rational; import android.view.WindowManager; -import android.widget.Button; -public class PipActivity extends Activity { +public class SimpleActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -32,14 +28,6 @@ public class PipActivity extends Activity { p.layoutInDisplayCutoutMode = WindowManager.LayoutParams .LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES; getWindow().setAttributes(p); - setContentView(R.layout.activity_pip); - Button enterPip = (Button) findViewById(R.id.enter_pip); - - PictureInPictureParams params = new PictureInPictureParams.Builder() - .setAspectRatio(new Rational(1, 1)) - .setSourceRectHint(new Rect(0, 0, 100, 100)) - .build(); - - enterPip.setOnClickListener((v) -> enterPictureInPictureMode(params)); + setContentView(R.layout.activity_simple); } } diff --git a/libs/hwui/jni/pdf/PdfEditor.cpp b/libs/hwui/jni/pdf/PdfEditor.cpp index e65921ac8e0a..427bafa1bd83 100644 --- a/libs/hwui/jni/pdf/PdfEditor.cpp +++ b/libs/hwui/jni/pdf/PdfEditor.cpp @@ -129,8 +129,8 @@ static void nativeSetTransformAndClip(JNIEnv* env, jclass thiz, jlong documentPt // PDF's coordinate system origin is left-bottom while in graphics it // is the top-left. So, translate the PDF coordinates to ours. - SkMatrix reflectOnX = SkMatrix::MakeScale(1, -1); - SkMatrix moveUp = SkMatrix::MakeTrans(0, FPDF_GetPageHeight(page)); + SkMatrix reflectOnX = SkMatrix::Scale(1, -1); + SkMatrix moveUp = SkMatrix::Translate(0, FPDF_GetPageHeight(page)); SkMatrix coordinateChange = SkMatrix::Concat(moveUp, reflectOnX); // Apply the transformation what was created in our coordinates. diff --git a/libs/hwui/tests/unit/DeferredLayerUpdaterTests.cpp b/libs/hwui/tests/unit/DeferredLayerUpdaterTests.cpp index f4c3e13b0ea6..955a5e7d8b3a 100644 --- a/libs/hwui/tests/unit/DeferredLayerUpdaterTests.cpp +++ b/libs/hwui/tests/unit/DeferredLayerUpdaterTests.cpp @@ -39,7 +39,7 @@ RENDERTHREAD_TEST(DeferredLayerUpdater, updateLayer) { EXPECT_EQ(Matrix4::identity(), layerUpdater->backingLayer()->getTexTransform()); // push the deferred updates to the layer - SkMatrix scaledMatrix = SkMatrix::MakeScale(0.5, 0.5); + SkMatrix scaledMatrix = SkMatrix::Scale(0.5, 0.5); SkBitmap bitmap; bitmap.allocN32Pixels(16, 16); sk_sp<SkImage> layerImage = SkImage::MakeFromBitmap(bitmap); diff --git a/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp b/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp index abdf9d587189..accf0f4f2aaa 100644 --- a/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp +++ b/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp @@ -206,7 +206,7 @@ TEST(RenderNodeDrawable, saveLayerClipAndMatrixRestore) { ASSERT_EQ(SkRect::MakeLTRB(50, 50, 350, 350), getRecorderClipBounds(recorder)); recorder.translate(300.0f, 400.0f); - EXPECT_EQ(SkMatrix::MakeTrans(300.0f, 400.0f), getRecorderMatrix(recorder)); + EXPECT_EQ(SkMatrix::Translate(300.0f, 400.0f), getRecorderMatrix(recorder)); recorder.restore(); ASSERT_EQ(SkRect::MakeLTRB(0, 0, 400, 800), getRecorderClipBounds(recorder)); @@ -1120,14 +1120,14 @@ TEST(ReorderBarrierDrawable, testShadowMatrix) { if (mFirstDidConcat) { // First invocation is EndReorderBarrierDrawable::drawShadow to apply shadow matrix. mFirstDidConcat = false; - EXPECT_EQ(SkMatrix::MakeTrans(CASTER_X + TRANSLATE_X, CASTER_Y + TRANSLATE_Y), + EXPECT_EQ(SkMatrix::Translate(CASTER_X + TRANSLATE_X, CASTER_Y + TRANSLATE_Y), matrix); - EXPECT_EQ(SkMatrix::MakeTrans(CASTER_X + TRANSLATE_X, CASTER_Y + TRANSLATE_Y), + EXPECT_EQ(SkMatrix::Translate(CASTER_X + TRANSLATE_X, CASTER_Y + TRANSLATE_Y), getTotalMatrix()); } else { // Second invocation is preparing the matrix for an elevated RenderNodeDrawable. - EXPECT_EQ(SkMatrix::MakeTrans(TRANSLATE_X, TRANSLATE_Y), matrix); - EXPECT_EQ(SkMatrix::MakeTrans(TRANSLATE_X, TRANSLATE_Y), getTotalMatrix()); + EXPECT_EQ(SkMatrix::Translate(TRANSLATE_X, TRANSLATE_Y), matrix); + EXPECT_EQ(SkMatrix::Translate(TRANSLATE_X, TRANSLATE_Y), getTotalMatrix()); } } diff --git a/libs/hwui/tests/unit/SkiaDisplayListTests.cpp b/libs/hwui/tests/unit/SkiaDisplayListTests.cpp index 74a565439f85..2d34b0980546 100644 --- a/libs/hwui/tests/unit/SkiaDisplayListTests.cpp +++ b/libs/hwui/tests/unit/SkiaDisplayListTests.cpp @@ -263,10 +263,10 @@ RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaDisplayList, prepareListAndChildren_vdOffscr } // Another way to be offscreen: a matrix from the draw call. - for (const SkMatrix translate : { SkMatrix::MakeTrans(width, 0), - SkMatrix::MakeTrans(0, height), - SkMatrix::MakeTrans(-width, 0), - SkMatrix::MakeTrans(0, -height)}) { + for (const SkMatrix translate : { SkMatrix::Translate(width, 0), + SkMatrix::Translate(0, height), + SkMatrix::Translate(-width, 0), + SkMatrix::Translate(0, -height)}) { SkiaDisplayList skiaDL; VectorDrawableRoot dirtyVD(new VectorDrawable::Group()); dirtyVD.mutateProperties()->setBounds(bounds); @@ -291,7 +291,7 @@ RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaDisplayList, prepareListAndChildren_vdOffscr SkiaDisplayList skiaDL; VectorDrawableRoot dirtyVD(new VectorDrawable::Group()); dirtyVD.mutateProperties()->setBounds(bounds); - SkMatrix translate = SkMatrix::MakeTrans(50, 50); + SkMatrix translate = SkMatrix::Translate(50, 50); skiaDL.appendVD(&dirtyVD, translate); ASSERT_TRUE(dirtyVD.isDirty()); diff --git a/libs/hwui/tests/unit/SkiaRenderPropertiesTests.cpp b/libs/hwui/tests/unit/SkiaRenderPropertiesTests.cpp index eec25c6bd40d..15ecf5831f3a 100644 --- a/libs/hwui/tests/unit/SkiaRenderPropertiesTests.cpp +++ b/libs/hwui/tests/unit/SkiaRenderPropertiesTests.cpp @@ -111,11 +111,11 @@ TEST(RenderNodeDrawable, renderPropTransform) { [](RenderProperties& properties) { properties.setLeftTopRightBottom(10, 10, 110, 110); - SkMatrix staticMatrix = SkMatrix::MakeScale(1.2f, 1.2f); + SkMatrix staticMatrix = SkMatrix::Scale(1.2f, 1.2f); properties.setStaticMatrix(&staticMatrix); // ignored, since static overrides animation - SkMatrix animationMatrix = SkMatrix::MakeTrans(15, 15); + SkMatrix animationMatrix = SkMatrix::Translate(15, 15); properties.setAnimationMatrix(&animationMatrix); properties.setTranslationX(10); diff --git a/location/java/com/android/internal/location/timezone/ILocationTimeZoneProviderManager.aidl b/location/java/com/android/internal/location/timezone/ILocationTimeZoneProviderManager.aidl index f89a64fc586c..b5450b7a0f88 100644 --- a/location/java/com/android/internal/location/timezone/ILocationTimeZoneProviderManager.aidl +++ b/location/java/com/android/internal/location/timezone/ILocationTimeZoneProviderManager.aidl @@ -16,7 +16,7 @@ package com.android.internal.location.timezone; -import android.location.timezone.LocationTimeZoneEvent; +import com.android.internal.location.timezone.LocationTimeZoneEvent; /** * Binder interface for the manager of location time zone provider implementations. diff --git a/location/java/android/location/timezone/LocationTimeZoneEvent.aidl b/location/java/com/android/internal/location/timezone/LocationTimeZoneEvent.aidl index 538658822930..199e0671f910 100644 --- a/location/java/android/location/timezone/LocationTimeZoneEvent.aidl +++ b/location/java/com/android/internal/location/timezone/LocationTimeZoneEvent.aidl @@ -14,6 +14,6 @@ * limitations under the License. */ -package android.location.timezone; +package com.android.internal.location.timezone; parcelable LocationTimeZoneEvent; diff --git a/location/java/android/location/timezone/LocationTimeZoneEvent.java b/location/java/com/android/internal/location/timezone/LocationTimeZoneEvent.java index 922a38921048..31c27d1bb977 100644 --- a/location/java/android/location/timezone/LocationTimeZoneEvent.java +++ b/location/java/com/android/internal/location/timezone/LocationTimeZoneEvent.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.location.timezone; +package com.android.internal.location.timezone; import android.annotation.IntDef; import android.annotation.NonNull; @@ -24,6 +24,7 @@ import android.os.Parcelable; import com.android.internal.util.Preconditions; +import java.time.Duration; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -70,30 +71,30 @@ public final class LocationTimeZoneEvent implements Parcelable { @NonNull private final List<String> mTimeZoneIds; - private final long mElapsedRealtimeNanos; + private final long mElapsedRealtimeMillis; private LocationTimeZoneEvent(@EventType int eventType, @NonNull List<String> timeZoneIds, - long elapsedRealtimeNanos) { + long elapsedRealtimeMillis) { mEventType = checkValidEventType(eventType); mTimeZoneIds = immutableList(timeZoneIds); boolean emptyTimeZoneIdListExpected = eventType != EVENT_TYPE_SUCCESS; Preconditions.checkState(!emptyTimeZoneIdListExpected || timeZoneIds.isEmpty()); - mElapsedRealtimeNanos = elapsedRealtimeNanos; + mElapsedRealtimeMillis = elapsedRealtimeMillis; } /** * Returns the time of this fix, in elapsed real-time since system boot. * * <p>This value can be reliably compared to {@link - * android.os.SystemClock#elapsedRealtimeNanos}, to calculate the age of a fix and to compare + * android.os.SystemClock#elapsedRealtime()}, to calculate the age of a fix and to compare * {@link LocationTimeZoneEvent} instances. * - * @return elapsed real-time of fix, in nanoseconds since system boot. + * @return elapsed real-time of fix, in milliseconds */ - public long getElapsedRealtimeNanos() { - return mElapsedRealtimeNanos; + public long getElapsedRealtimeMillis() { + return mElapsedRealtimeMillis; } /** @@ -118,7 +119,8 @@ public final class LocationTimeZoneEvent implements Parcelable { return "LocationTimeZoneEvent{" + "mEventType=" + mEventType + ", mTimeZoneIds=" + mTimeZoneIds - + ", mElapsedRealtimeNanos=" + mElapsedRealtimeNanos + + ", mElapsedRealtimeMillis=" + mElapsedRealtimeMillis + + "(" + Duration.ofMillis(mElapsedRealtimeMillis) + ")" + '}'; } @@ -130,8 +132,8 @@ public final class LocationTimeZoneEvent implements Parcelable { @SuppressWarnings("unchecked") ArrayList<String> timeZoneIds = (ArrayList<String>) in.readArrayList(null /* classLoader */); - long elapsedRealtimeNanos = in.readLong(); - return new LocationTimeZoneEvent(eventType, timeZoneIds, elapsedRealtimeNanos); + long elapsedRealtimeMillis = in.readLong(); + return new LocationTimeZoneEvent(eventType, timeZoneIds, elapsedRealtimeMillis); } @Override @@ -149,7 +151,7 @@ public final class LocationTimeZoneEvent implements Parcelable { public void writeToParcel(Parcel parcel, int flags) { parcel.writeInt(mEventType); parcel.writeList(mTimeZoneIds); - parcel.writeLong(mElapsedRealtimeNanos); + parcel.writeLong(mElapsedRealtimeMillis); } @Override @@ -162,13 +164,13 @@ public final class LocationTimeZoneEvent implements Parcelable { } LocationTimeZoneEvent that = (LocationTimeZoneEvent) o; return mEventType == that.mEventType - && mElapsedRealtimeNanos == that.mElapsedRealtimeNanos + && mElapsedRealtimeMillis == that.mElapsedRealtimeMillis && mTimeZoneIds.equals(that.mTimeZoneIds); } @Override public int hashCode() { - return Objects.hash(mEventType, mTimeZoneIds, mElapsedRealtimeNanos); + return Objects.hash(mEventType, mTimeZoneIds, mElapsedRealtimeMillis); } /** @hide */ @@ -176,7 +178,7 @@ public final class LocationTimeZoneEvent implements Parcelable { private @EventType int mEventType = EVENT_TYPE_UNKNOWN; private @NonNull List<String> mTimeZoneIds = Collections.emptyList(); - private long mElapsedRealtimeNanos; + private long mElapsedRealtimeMillis; public Builder() { } @@ -187,7 +189,7 @@ public final class LocationTimeZoneEvent implements Parcelable { public Builder(@NonNull LocationTimeZoneEvent ltz) { mEventType = ltz.mEventType; mTimeZoneIds = ltz.mTimeZoneIds; - mElapsedRealtimeNanos = ltz.mElapsedRealtimeNanos; + mElapsedRealtimeMillis = ltz.mElapsedRealtimeMillis; } /** @@ -210,8 +212,8 @@ public final class LocationTimeZoneEvent implements Parcelable { /** * Sets the time of this event, in elapsed real-time since system boot. */ - public Builder setElapsedRealtimeNanos(long time) { - mElapsedRealtimeNanos = time; + public Builder setElapsedRealtimeMillis(long time) { + mElapsedRealtimeMillis = time; return this; } @@ -219,7 +221,7 @@ public final class LocationTimeZoneEvent implements Parcelable { * Builds a {@link LocationTimeZoneEvent} instance. */ public LocationTimeZoneEvent build() { - return new LocationTimeZoneEvent(mEventType, mTimeZoneIds, mElapsedRealtimeNanos); + return new LocationTimeZoneEvent(mEventType, mTimeZoneIds, mElapsedRealtimeMillis); } } diff --git a/location/lib/java/com/android/location/timezone/provider/LocationTimeZoneEventUnbundled.java b/location/lib/java/com/android/location/timezone/provider/LocationTimeZoneEventUnbundled.java index 07396333b05c..55f554554474 100644 --- a/location/lib/java/com/android/location/timezone/provider/LocationTimeZoneEventUnbundled.java +++ b/location/lib/java/com/android/location/timezone/provider/LocationTimeZoneEventUnbundled.java @@ -18,9 +18,10 @@ package com.android.location.timezone.provider; import android.annotation.IntDef; import android.annotation.NonNull; -import android.location.timezone.LocationTimeZoneEvent; import android.os.SystemClock; +import com.android.internal.location.timezone.LocationTimeZoneEvent; + import java.util.Collections; import java.util.List; import java.util.Objects; @@ -146,7 +147,7 @@ public final class LocationTimeZoneEventUnbundled { LocationTimeZoneEvent event = new LocationTimeZoneEvent.Builder() .setEventType(internalEventType) .setTimeZoneIds(mTimeZoneIds) - .setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos()) + .setElapsedRealtimeMillis(SystemClock.elapsedRealtime()) .build(); return new LocationTimeZoneEventUnbundled(event); } diff --git a/media/java/android/media/AudioRecord.java b/media/java/android/media/AudioRecord.java index 65e6feaa31d3..ea691a727d25 100644 --- a/media/java/android/media/AudioRecord.java +++ b/media/java/android/media/AudioRecord.java @@ -166,6 +166,7 @@ public class AudioRecord implements AudioRouting, MicrophoneDirection, //-------------------- /** * Accessed by native methods: provides access to C++ AudioRecord object + * Is 0 after release() */ @SuppressWarnings("unused") @UnsupportedAppUsage @@ -1872,7 +1873,11 @@ public class AudioRecord implements AudioRouting, MicrophoneDirection, if (mNativeRecorderInJavaObj == 0) { return 0; } - return native_getPortId(); + try { + return native_getPortId(); + } catch (IllegalStateException e) { + return 0; + } } //-------------------------------------------------------------------------- @@ -2055,6 +2060,9 @@ public class AudioRecord implements AudioRouting, MicrophoneDirection, private native final int native_get_active_microphones( ArrayList<MicrophoneInfo> activeMicrophones); + /** + * @throws IllegalStateException + */ private native int native_getPortId(); private native int native_set_preferred_microphone_direction(int direction); diff --git a/media/java/android/media/MediaTranscodeManager.java b/media/java/android/media/MediaTranscodeManager.java index 4544d049e09f..705da19b65e4 100644 --- a/media/java/android/media/MediaTranscodeManager.java +++ b/media/java/android/media/MediaTranscodeManager.java @@ -29,6 +29,7 @@ import android.net.Uri; import android.os.ParcelFileDescriptor; import android.os.RemoteException; import android.os.ServiceManager; +import android.os.ServiceSpecificException; import android.system.Os; import android.util.Log; @@ -616,15 +617,24 @@ public final class MediaTranscodeManager { /* Writes the TranscodingRequest to a parcel. */ private TranscodingRequestParcel writeToParcel(@NonNull Context context) { TranscodingRequestParcel parcel = new TranscodingRequestParcel(); - // TODO(hkuang): Implement all the fields here to pass to service. parcel.priority = mPriority; parcel.transcodingType = mType; parcel.sourceFilePath = mSourceUri.toString(); parcel.destinationFilePath = mDestinationUri.toString(); parcel.clientUid = mClientUid; parcel.clientPid = mClientPid; - parcel.clientPackageName = mClientUid < 0 ? context.getPackageName() : - context.getPackageManager().getNameForUid(mClientUid); + if (mClientUid < 0) { + parcel.clientPackageName = context.getPackageName(); + } else { + String packageName = context.getPackageManager().getNameForUid(mClientUid); + // PackageName is optional as some uid does not have package name. Set to + // "Unavailable" string in this case. + if (packageName == null) { + Log.w(TAG, "Failed to find package for uid: " + mClientUid); + packageName = "Unavailable"; + } + parcel.clientPackageName = packageName; + } parcel.requestedVideoTrackFormat = convertToVideoTrackFormat(mVideoTrackFormat); if (mTestConfig != null) { parcel.isForTesting = true; @@ -753,7 +763,7 @@ public final class MediaTranscodeManager { */ @NonNull public Builder setClientUid(int uid) { - if (uid <= 0) { + if (uid < 0) { throw new IllegalArgumentException("Invalid Uid"); } mClientUid = uid; @@ -769,7 +779,7 @@ public final class MediaTranscodeManager { */ @NonNull public Builder setClientPid(int pid) { - if (pid <= 0) { + if (pid < 0) { throw new IllegalArgumentException("Invalid pid"); } mClientPid = pid; @@ -1417,7 +1427,7 @@ public final class MediaTranscodeManager { mPendingTranscodingSessions.put(session.getSessionId(), session); return session; } - } catch (RemoteException re) { + } catch (RemoteException | ServiceSpecificException ex) { throw new UnsupportedOperationException( "Failed to submit request to Transcoding service"); } diff --git a/media/java/android/media/Rating.java b/media/java/android/media/Rating.java index be752583eae5..4da23a1319af 100644 --- a/media/java/android/media/Rating.java +++ b/media/java/android/media/Rating.java @@ -206,11 +206,12 @@ public final class Rating implements Parcelable { Log.e(TAG, "Invalid rating style (" + starRatingStyle + ") for a star rating"); return null; } - if ((starRating < 0.0f) || (starRating > maxRating)) { + if (starRating >= 0.0f && starRating <= maxRating) { + return new Rating(starRatingStyle, starRating); + } else { Log.e(TAG, "Trying to set out of range star-based rating"); return null; } - return new Rating(starRatingStyle, starRating); } /** @@ -221,11 +222,11 @@ public final class Rating implements Parcelable { * @return null if the rating is out of range, a new Rating instance otherwise. */ public static Rating newPercentageRating(float percent) { - if ((percent < 0.0f) || (percent > 100.0f)) { + if (percent >= 0.0f && percent <= 100.0f) { + return new Rating(RATING_PERCENTAGE, percent); + } else { Log.e(TAG, "Invalid percentage-based rating value"); return null; - } else { - return new Rating(RATING_PERCENTAGE, percent); } } diff --git a/media/native/midi/MidiDeviceInfo.cpp b/media/native/midi/MidiDeviceInfo.cpp index ac68d26c935b..8a573fba322b 100644 --- a/media/native/midi/MidiDeviceInfo.cpp +++ b/media/native/midi/MidiDeviceInfo.cpp @@ -90,13 +90,13 @@ status_t MidiDeviceInfo::readFromParcel(const Parcel* parcel) { status_t MidiDeviceInfo::readStringVector( const Parcel* parcel, Vector<String16> *vectorPtr, size_t defaultLength) { - std::unique_ptr<std::vector<std::unique_ptr<String16>>> v; + std::optional<std::vector<std::optional<String16>>> v; status_t result = parcel->readString16Vector(&v); if (result != OK) return result; vectorPtr->clear(); - if (v.get() != nullptr) { + if (v) { for (const auto& iter : *v) { - if (iter.get() != nullptr) { + if (iter) { vectorPtr->push_back(*iter); } else { vectorPtr->push_back(String16()); diff --git a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CustomConfigLoader.java b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CustomConfigLoader.java index c7f5e9a5ceec..f11febc15d04 100644 --- a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CustomConfigLoader.java +++ b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CustomConfigLoader.java @@ -20,6 +20,7 @@ import android.content.Intent; import android.os.PersistableBundle; import android.telephony.CarrierConfigManager; import android.telephony.TelephonyManager; +import android.telephony.data.ApnSetting; import android.text.TextUtils; import android.util.Log; @@ -85,8 +86,8 @@ public class CustomConfigLoader { case TelephonyManager.ACTION_CARRIER_SIGNAL_REQUEST_NETWORK_FAILED: configs = b.getStringArray(CarrierConfigManager .KEY_CARRIER_DEFAULT_ACTIONS_ON_DCFAILURE_STRING_ARRAY); - arg1 = intent.getStringExtra(TelephonyManager.EXTRA_APN_TYPE); - arg2 = intent.getStringExtra(TelephonyManager.EXTRA_ERROR_CODE); + arg1 = String.valueOf(intent.getIntExtra(TelephonyManager.EXTRA_APN_TYPE, -1)); + arg2 = intent.getStringExtra(TelephonyManager.EXTRA_DATA_FAIL_CAUSE); break; case TelephonyManager.ACTION_CARRIER_SIGNAL_RESET: configs = b.getStringArray(CarrierConfigManager @@ -141,10 +142,24 @@ public class CustomConfigLoader { // case 1 actionStr = splitStr[0]; } else if (splitStr.length == 2 && arg1 != null && arg2 != null) { - // case 2 + // case 2. The only thing that uses this is CARRIER_SIGNAL_REQUEST_NETWORK_FAILED, + // and the carrier config for that can provide either an int or string for the apn type, + // depending on when it was introduced. Therefore, return a positive match if either + // the int version or the string version of the apn type in the broadcast matches. + String apnInIntFormat = arg1; + String apnInStringFormat = null; + try { + int apnInt = Integer.parseInt(apnInIntFormat); + apnInStringFormat = ApnSetting.getApnTypeString(apnInt); + } catch (NumberFormatException e) { + Log.e(TAG, "Got invalid apn type from broadcast: " + apnInIntFormat); + } + String[] args = splitStr[0].split(INTRA_GROUP_DELIMITER); - if (args.length == 2 && TextUtils.equals(arg1, args[0]) && - TextUtils.equals(arg2, args[1])) { + boolean doesArg1Match = TextUtils.equals(apnInIntFormat, args[0]) + || (apnInStringFormat != null && TextUtils.equals(apnInStringFormat, args[0])); + if (args.length == 2 && doesArg1Match + && TextUtils.equals(arg2, args[1])) { actionStr = splitStr[1]; } } else if ((splitStr.length == 2) && (arg1 != null) && (arg2 == null)) { diff --git a/packages/SettingsLib/Android.bp b/packages/SettingsLib/Android.bp index 64dc2afafd6a..e6492aadd765 100644 --- a/packages/SettingsLib/Android.bp +++ b/packages/SettingsLib/Android.bp @@ -53,6 +53,7 @@ java_defaults { "SettingsLibUtils", "SettingsLibEmergencyNumber", "SettingsLibTopIntroPreference", + "SettingsLibBannerMessagePreference", ], } diff --git a/packages/SettingsLib/BannerMessagePreference/Android.bp b/packages/SettingsLib/BannerMessagePreference/Android.bp new file mode 100644 index 000000000000..095975afa13a --- /dev/null +++ b/packages/SettingsLib/BannerMessagePreference/Android.bp @@ -0,0 +1,13 @@ +android_library { + name: "SettingsLibBannerMessagePreference", + + srcs: ["src/**/*.java"], + resource_dirs: ["res"], + + static_libs: [ + "androidx.preference_preference", + ], + + sdk_version: "system_current", + min_sdk_version: "21", +} diff --git a/packages/SettingsLib/BannerMessagePreference/AndroidManifest.xml b/packages/SettingsLib/BannerMessagePreference/AndroidManifest.xml new file mode 100644 index 000000000000..56b886f7efb1 --- /dev/null +++ b/packages/SettingsLib/BannerMessagePreference/AndroidManifest.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. + --> + +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.settingslib.widget"> + + <uses-sdk android:minSdkVersion="21"/> + +</manifest> diff --git a/packages/SettingsLib/BannerMessagePreference/res/drawable/ic_warning.xml b/packages/SettingsLib/BannerMessagePreference/res/drawable/ic_warning.xml new file mode 100644 index 000000000000..c1f2c9f9f9d0 --- /dev/null +++ b/packages/SettingsLib/BannerMessagePreference/res/drawable/ic_warning.xml @@ -0,0 +1,26 @@ +<!-- + 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. + --> + +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24"> + <path + android:pathData="M1,21L12,2L23,21H1ZM19.53,19L12,5.99L4.47,19H19.53ZM11,16V18H13V16H11ZM11,10H13V14H11V10Z" + android:fillColor="?android:attr/colorError" + android:fillType="evenOdd"/> +</vector> diff --git a/packages/SettingsLib/BannerMessagePreference/res/layout/banner_message.xml b/packages/SettingsLib/BannerMessagePreference/res/layout/banner_message.xml new file mode 100644 index 000000000000..977e19687960 --- /dev/null +++ b/packages/SettingsLib/BannerMessagePreference/res/layout/banner_message.xml @@ -0,0 +1,73 @@ +<?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. +--> + +<LinearLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:paddingStart="24dp" + android:paddingEnd="16dp" + android:paddingTop="24dp" + android:paddingBottom="8dp" + android:orientation="vertical"> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal"> + + <ImageView + android:layout_width="24dp" + android:layout_height="24dp" + android:src="@drawable/ic_warning"/> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginStart="24dp" + android:orientation="vertical"> + + <TextView + android:id="@+id/banner_title" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:textAppearance="@style/Banner.Text.Title"/> + <TextView + android:id="@+id/banner_summary" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:textAppearance="@style/Banner.Text.Summary"/> + </LinearLayout> + </LinearLayout> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal" + android:gravity="end"> + <Button + android:id="@+id/banner_negative_btn" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + style="@android:style/Widget.DeviceDefault.Button.Borderless.Colored"/> + + <Button + android:id="@+id/banner_positive_btn" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + style="@android:style/Widget.DeviceDefault.Button.Borderless.Colored"/> + </LinearLayout> +</LinearLayout>
\ No newline at end of file diff --git a/packages/SettingsLib/BannerMessagePreference/res/values/styles.xml b/packages/SettingsLib/BannerMessagePreference/res/values/styles.xml new file mode 100644 index 000000000000..df47c642e402 --- /dev/null +++ b/packages/SettingsLib/BannerMessagePreference/res/values/styles.xml @@ -0,0 +1,31 @@ +<?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> + <style name="Banner.Text.Title" + parent="@android:style/TextAppearance.Material.Subhead"> + <item name="android:textSize">16sp</item> + <item name="android:fontFamily">@*android:string/config_headlineFontFamilyMedium</item> + <item name="android:textColor">?android:attr/textColorPrimary</item> + </style> + + <style name="Banner.Text.Summary" + parent="@*android:style/TextAppearance.DeviceDefault.Body1"> + <item name="android:textColor">?android:attr/textColorSecondary</item> + <item name="android:textSize">14sp</item> + </style> +</resources>
\ No newline at end of file diff --git a/packages/SettingsLib/BannerMessagePreference/src/com/android/settingslib/widget/BannerMessagePreference.java b/packages/SettingsLib/BannerMessagePreference/src/com/android/settingslib/widget/BannerMessagePreference.java new file mode 100644 index 000000000000..5352552d7c66 --- /dev/null +++ b/packages/SettingsLib/BannerMessagePreference/src/com/android/settingslib/widget/BannerMessagePreference.java @@ -0,0 +1,182 @@ +/* + * 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.settingslib.widget; + +import android.content.Context; +import android.text.TextUtils; +import android.util.AttributeSet; +import android.view.View; +import android.widget.Button; +import android.widget.TextView; + +import androidx.annotation.StringRes; +import androidx.preference.Preference; +import androidx.preference.PreferenceViewHolder; + +/** + * Banner message is a banner displaying important information (permission request, page error etc), + * and provide actions for user to address. It requires a user action to be dismissed. + */ +public class BannerMessagePreference extends Preference { + + private static final String TAG = "BannerPreference"; + private BannerMessagePreference.ButtonInfo mPositiveButtonInfo; + private BannerMessagePreference.ButtonInfo mNegativeButtonInfo; + + public BannerMessagePreference(Context context) { + super(context); + init(); + } + + public BannerMessagePreference(Context context, AttributeSet attrs) { + super(context, attrs); + init(); + } + + public BannerMessagePreference(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + init(); + } + + public BannerMessagePreference(Context context, AttributeSet attrs, int defStyleAttr, + int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + init(); + } + + @Override + public void onBindViewHolder(PreferenceViewHolder holder) { + super.onBindViewHolder(holder); + holder.setDividerAllowedAbove(true); + holder.setDividerAllowedBelow(true); + + mPositiveButtonInfo.mButton = (Button) holder.findViewById(R.id.banner_positive_btn); + mNegativeButtonInfo.mButton = (Button) holder.findViewById(R.id.banner_negative_btn); + + mPositiveButtonInfo.setUpButton(); + mNegativeButtonInfo.setUpButton(); + + final TextView titleView = (TextView) holder.findViewById(R.id.banner_title); + final TextView summaryView = (TextView) holder.findViewById(R.id.banner_summary); + + titleView.setText(getTitle()); + summaryView.setText(getSummary()); + } + + private void init() { + mPositiveButtonInfo = new BannerMessagePreference.ButtonInfo(); + mNegativeButtonInfo = new BannerMessagePreference.ButtonInfo(); + setSelectable(false); + setLayoutResource(R.layout.banner_message); + } + + /** + * Set the visibility state of positive button. + */ + public BannerMessagePreference setPositiveButtonVisible(boolean isVisible) { + if (isVisible != mPositiveButtonInfo.mIsVisible) { + mPositiveButtonInfo.mIsVisible = isVisible; + notifyChanged(); + } + return this; + } + + /** + * Set the visibility state of negative button. + */ + public BannerMessagePreference setNegativeButtonVisible(boolean isVisible) { + if (isVisible != mNegativeButtonInfo.mIsVisible) { + mNegativeButtonInfo.mIsVisible = isVisible; + notifyChanged(); + } + return this; + } + + /** + * Register a callback to be invoked when positive button is clicked. + */ + public BannerMessagePreference setPositiveButtonOnClickListener( + View.OnClickListener listener) { + if (listener != mPositiveButtonInfo.mListener) { + mPositiveButtonInfo.mListener = listener; + notifyChanged(); + } + return this; + } + + /** + * Register a callback to be invoked when negative button is clicked. + */ + public BannerMessagePreference setNegativeButtonOnClickListener( + View.OnClickListener listener) { + if (listener != mNegativeButtonInfo.mListener) { + mNegativeButtonInfo.mListener = listener; + notifyChanged(); + } + return this; + } + + /** + * Sets the text to be displayed in positive button. + */ + public BannerMessagePreference setPositiveButtonText(@StringRes int textResId) { + final String newText = getContext().getString(textResId); + if (!TextUtils.equals(newText, mPositiveButtonInfo.mText)) { + mPositiveButtonInfo.mText = newText; + notifyChanged(); + } + return this; + } + + /** + * Sets the text to be displayed in negative button. + */ + public BannerMessagePreference setNegativeButtonText(@StringRes int textResId) { + final String newText = getContext().getString(textResId); + if (!TextUtils.equals(newText, mNegativeButtonInfo.mText)) { + mNegativeButtonInfo.mText = newText; + notifyChanged(); + } + return this; + } + + static class ButtonInfo { + private Button mButton; + private CharSequence mText; + private View.OnClickListener mListener; + private boolean mIsVisible = true; + + void setUpButton() { + mButton.setText(mText); + mButton.setOnClickListener(mListener); + + if (shouldBeVisible()) { + mButton.setVisibility(View.VISIBLE); + } else { + mButton.setVisibility(View.GONE); + } + } + + /** + * By default, two buttons are visible. + * If user didn't set a text for a button, then it should not be shown. + */ + private boolean shouldBeVisible() { + return mIsVisible && (!TextUtils.isEmpty(mText)); + } + } +} diff --git a/packages/SettingsLib/Utils/src/com/android/settingslib/utils/applications/AppUtils.java b/packages/SettingsLib/Utils/src/com/android/settingslib/utils/applications/AppUtils.java index e7c0d9659d11..4505dad8ea12 100644 --- a/packages/SettingsLib/Utils/src/com/android/settingslib/utils/applications/AppUtils.java +++ b/packages/SettingsLib/Utils/src/com/android/settingslib/utils/applications/AppUtils.java @@ -52,6 +52,9 @@ public class AppUtils { public static String getAppContentDescription(Context context, String packageName, int userId) { final CharSequence appLabel = getApplicationLabel(context.getPackageManager(), packageName); + if (appLabel == null) { + return ""; + } return context.getSystemService(UserManager.class).isManagedProfile(userId) ? context.getString(R.string.accessibility_work_profile_app_description, appLabel) : appLabel.toString(); diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/BannerMessagePreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/BannerMessagePreferenceTest.java new file mode 100644 index 000000000000..8ab02983bfc2 --- /dev/null +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/BannerMessagePreferenceTest.java @@ -0,0 +1,149 @@ +/* + * 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.settingslib.widget; + +import static com.google.common.truth.Truth.assertThat; + +import android.content.Context; +import android.view.View; +import android.widget.Button; +import android.widget.TextView; + +import androidx.preference.PreferenceViewHolder; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.RuntimeEnvironment; + +@RunWith(RobolectricTestRunner.class) +public class BannerMessagePreferenceTest { + + private Context mContext; + private View mRootView; + private BannerMessagePreference mBannerPreference; + private PreferenceViewHolder mHolder; + + @Before + public void setUp() { + mContext = RuntimeEnvironment.application; + mRootView = View.inflate(mContext, R.layout.banner_message, null /* parent */); + mHolder = PreferenceViewHolder.createInstanceForTests(mRootView); + mBannerPreference = new BannerMessagePreference(mContext); + } + + @Test + public void onBindViewHolder_shouldSetTitle() { + mBannerPreference.setTitle("test"); + + mBannerPreference.onBindViewHolder(mHolder); + + assertThat(((TextView) mRootView.findViewById(R.id.banner_title)).getText()) + .isEqualTo("test"); + } + + @Test + public void onBindViewHolder_shouldSetSummary() { + mBannerPreference.setSummary("test"); + + mBannerPreference.onBindViewHolder(mHolder); + + assertThat(((TextView) mRootView.findViewById(R.id.banner_summary)).getText()) + .isEqualTo("test"); + } + + @Test + public void setPositiveButtonText_shouldShowPositiveButton() { + mBannerPreference.setPositiveButtonText(R.string.tts_settings_title); + + mBannerPreference.onBindViewHolder(mHolder); + + assertThat(((Button) mRootView.findViewById(R.id.banner_positive_btn)).getVisibility()) + .isEqualTo(View.VISIBLE); + } + + @Test + public void setNegativeButtonText_shouldShowNegativeButton() { + mBannerPreference.setNegativeButtonText(R.string.tts_settings_title); + + mBannerPreference.onBindViewHolder(mHolder); + + assertThat(((Button) mRootView.findViewById(R.id.banner_negative_btn)).getVisibility()) + .isEqualTo(View.VISIBLE); + } + + @Test + public void withoutSetPositiveButtonText_shouldHidePositiveButton() { + mBannerPreference.onBindViewHolder(mHolder); + + assertThat(((Button) mRootView.findViewById(R.id.banner_positive_btn)).getVisibility()) + .isEqualTo(View.GONE); + } + + @Test + public void withoutSetNegativeButtonText_shouldHideNegativeButton() { + mBannerPreference.onBindViewHolder(mHolder); + + assertThat(((Button) mRootView.findViewById(R.id.banner_negative_btn)).getVisibility()) + .isEqualTo(View.GONE); + } + + @Test + public void setPositiveButtonVisible_withTrue_shouldShowPositiveButton() { + mBannerPreference.setPositiveButtonText(R.string.tts_settings_title); + + mBannerPreference.setPositiveButtonVisible(true); + mBannerPreference.onBindViewHolder(mHolder); + + assertThat(((Button) mRootView.findViewById(R.id.banner_positive_btn)).getVisibility()) + .isEqualTo(View.VISIBLE); + } + + @Test + public void setPositiveButtonVisible_withFalse_shouldHidePositiveButton() { + mBannerPreference.setPositiveButtonText(R.string.tts_settings_title); + + mBannerPreference.setPositiveButtonVisible(false); + mBannerPreference.onBindViewHolder(mHolder); + + assertThat(((Button) mRootView.findViewById(R.id.banner_positive_btn)).getVisibility()) + .isEqualTo(View.GONE); + } + + @Test + public void setNegativeButtonVisible_withTrue_shouldShowNegativeButton() { + mBannerPreference.setNegativeButtonText(R.string.tts_settings_title); + + mBannerPreference.setNegativeButtonVisible(true); + mBannerPreference.onBindViewHolder(mHolder); + + assertThat(((Button) mRootView.findViewById(R.id.banner_negative_btn)).getVisibility()) + .isEqualTo(View.VISIBLE); + } + + @Test + public void setNegativeButtonVisible_withFalse_shouldHideNegativeButton() { + mBannerPreference.setNegativeButtonText(R.string.tts_settings_title); + + mBannerPreference.setNegativeButtonVisible(false); + mBannerPreference.onBindViewHolder(mHolder); + + assertThat(((Button) mRootView.findViewById(R.id.banner_negative_btn)).getVisibility()) + .isEqualTo(View.GONE); + } +} diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml index a97af4bbe324..2a699ea45abe 100644 --- a/packages/Shell/AndroidManifest.xml +++ b/packages/Shell/AndroidManifest.xml @@ -146,6 +146,7 @@ <uses-permission android:name="android.permission.MANAGE_ACTIVITY_TASKS" /> <uses-permission android:name="android.permission.START_TASKS_FROM_RECENTS" /> <uses-permission android:name="android.permission.START_ACTIVITIES_FROM_BACKGROUND" /> + <uses-permission android:name="android.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND" /> <uses-permission android:name="android.permission.ACTIVITY_EMBEDDING" /> <uses-permission android:name="android.permission.CONNECTIVITY_INTERNAL" /> <uses-permission android:name="android.permission.CHANGE_COMPONENT_ENABLED_STATE" /> diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp index 014d73f281cc..2ea0c2294f76 100644 --- a/packages/SystemUI/Android.bp +++ b/packages/SystemUI/Android.bp @@ -33,6 +33,13 @@ java_library { srcs: ["src/com/android/systemui/EventLogTags.logtags"], } +java_library { + name: "SystemUI-sensors", + srcs: [ + "src/com/android/systemui/util/sensors/ThresholdSensor.java", + ] +} + android_library { name: "SystemUI-core", srcs: [ diff --git a/packages/SystemUI/plugin/Android.bp b/packages/SystemUI/plugin/Android.bp index df5561acbbc4..ab4f800d2586 100644 --- a/packages/SystemUI/plugin/Android.bp +++ b/packages/SystemUI/plugin/Android.bp @@ -19,7 +19,8 @@ java_library { srcs: ["src/**/*.java"], static_libs: [ - "PluginCoreLib" + "PluginCoreLib", + "SystemUI-sensors", ], } diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/FalsingManager.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/FalsingManager.java index 0f94bca1d815..6e86f268a725 100644 --- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/FalsingManager.java +++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/FalsingManager.java @@ -20,6 +20,7 @@ import android.net.Uri; import android.view.MotionEvent; import com.android.systemui.plugins.annotations.ProvidesInterface; +import com.android.systemui.util.sensors.ThresholdSensor; import java.io.FileDescriptor; import java.io.PrintWriter; @@ -35,12 +36,6 @@ public interface FalsingManager { void onSuccessfulUnlock(); - void onNotificationActive(); - - void setShowingAod(boolean showingAod); - - void onNotificatonStartDraggingDown(); - boolean isUnlockingDisabled(); /** Returns true if the gesture should be rejected. */ @@ -82,66 +77,21 @@ public interface FalsingManager { */ boolean isFalseDoubleTap(); - void onNotificatonStopDraggingDown(); - - void setNotificationExpanded(); - boolean isClassifierEnabled(); - void onQsDown(); - - void setQsExpanded(boolean expanded); - boolean shouldEnforceBouncer(); - void onTrackingStarted(boolean secure); - - void onTrackingStopped(); - - void onLeftAffordanceOn(); - - void onCameraOn(); - - void onAffordanceSwipingStarted(boolean rightCorner); - - void onAffordanceSwipingAborted(); - - void onStartExpandingFromPulse(); - - void onExpansionFromPulseStopped(); - Uri reportRejectedTouch(); - void onScreenOnFromTouch(); - boolean isReportingEnabled(); - void onUnlockHintStarted(); - - void onCameraHintStarted(); - - void onLeftAffordanceHintStarted(); - - void onScreenTurningOn(); - - void onScreenOff(); - - void onNotificationStopDismissing(); - - void onNotificationDismissed(); - - void onNotificationStartDismissing(); - - void onNotificationDoubleTap(boolean accepted, float dx, float dy); - - void onBouncerShown(); - - void onBouncerHidden(); - void onTouchEvent(MotionEvent ev, int width, int height); /** From com.android.systemui.Dumpable. */ void dump(FileDescriptor fd, PrintWriter pw, String[] args); void cleanup(); + + /** Call to report a ProximityEvent to the FalsingManager. */ + void onProximityEvent(ThresholdSensor.ThresholdSensorEvent proximityEvent); } diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml index 880dd378e390..01b55b70d5ad 100644 --- a/packages/SystemUI/res/values/config.xml +++ b/packages/SystemUI/res/values/config.xml @@ -357,9 +357,6 @@ the notification is not swiped enough to dismiss it. --> <bool name="config_showNotificationGear">true</bool> - <!-- Whether or not a background should be drawn behind a notification. --> - <bool name="config_drawNotificationBackground">true</bool> - <!-- Whether or the notifications can be shown and dismissed with a drag. --> <bool name="config_enableNotificationShadeDrag">true</bool> diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index ea1258f025f7..5b74687c3109 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -226,6 +226,8 @@ <string name="screenshot_saved_text">Tap to view your screenshot</string> <!-- Notification title displayed when we fail to take a screenshot. [CHAR LIMIT=50] --> <string name="screenshot_failed_title">Couldn\'t save screenshot</string> + <!-- Notification text displayed when we fail to save a screenshot due to locked storage. [CHAR LIMIT=100] --> + <string name="screenshot_failed_to_save_user_locked_text">Device must be unlocked before screenshot can be saved</string> <!-- Notification text displayed when we fail to save a screenshot for unknown reasons. [CHAR LIMIT=100] --> <string name="screenshot_failed_to_save_unknown_text">Try taking screenshot again</string> <!-- Notification text displayed when we fail to save a screenshot. [CHAR LIMIT=100] --> diff --git a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java index 6151ac7a242b..3852b24fe4b3 100644 --- a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java +++ b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java @@ -327,8 +327,8 @@ public class SwipeHelper implements Gefingerpoken { if (Math.abs(delta) > pagingTouchSlop && Math.abs(delta) > Math.abs(deltaPerpendicular)) { if (mCallback.canChildBeDragged(mTouchedView)) { - mCallback.onBeginDrag(mTouchedView); mIsSwiping = true; + mCallback.onBeginDrag(mTouchedView); mInitialTouchPos = getPos(ev); mTranslation = getTranslation(mTouchedView); } diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java index 182b3e114887..935f89343754 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java @@ -281,7 +281,7 @@ public class AuthContainerView extends LinearLayout // Inflate biometric view only if necessary. if (Utils.isBiometricAllowed(mConfig.mPromptInfo)) { - if (config.mSensorIds.length == 1) { + if (config.mSensorIds.length == 1 || config.mSensorIds.length == 2) { final int singleSensorAuthId = config.mSensorIds[0]; if (Utils.containsSensorId(mFpProps, singleSensorAuthId)) { FingerprintSensorPropertiesInternal sensorProps = null; @@ -313,7 +313,6 @@ public class AuthContainerView extends LinearLayout return; } } else { - // The UI currently only supports authentication with a single sensor. Log.e(TAG, "Unsupported sensor array, length: " + config.mSensorIds.length); mBiometricView = null; mBackgroundView = null; diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollector.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollector.java new file mode 100644 index 000000000000..c05ce93f0c13 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollector.java @@ -0,0 +1,121 @@ +/* + * 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.classifier; + +import android.view.MotionEvent; + +/** + * Defines a class that can be used to ingest system events for later processing. + */ +public interface FalsingCollector { + /** */ + void onSuccessfulUnlock(); + + /** */ + void onNotificationActive(); + + /** */ + void setShowingAod(boolean showingAod); + + /** */ + void onNotificationStartDraggingDown(); + + /** */ + void onNotificationStopDraggingDown(); + + /** */ + void setNotificationExpanded(); + + /** */ + void onQsDown(); + + /** */ + void setQsExpanded(boolean expanded); + + /** */ + boolean shouldEnforceBouncer(); + + /** */ + void onTrackingStarted(boolean secure); + + /** */ + void onTrackingStopped(); + + /** */ + void onLeftAffordanceOn(); + + /** */ + void onCameraOn(); + + /** */ + void onAffordanceSwipingStarted(boolean rightCorner); + + /** */ + void onAffordanceSwipingAborted(); + + /** */ + void onStartExpandingFromPulse(); + + /** */ + void onExpansionFromPulseStopped(); + + /** */ + void onScreenOnFromTouch(); + + /** */ + boolean isReportingEnabled(); + + /** */ + void onUnlockHintStarted(); + + /** */ + void onCameraHintStarted(); + + /** */ + void onLeftAffordanceHintStarted(); + + /** */ + void onScreenTurningOn(); + + /** */ + void onScreenOff(); + + /** */ + void onNotificationStopDismissing(); + + /** */ + void onNotificationDismissed(); + + /** */ + void onNotificationStartDismissing(); + + /** */ + void onNotificationDoubleTap(boolean accepted, float dx, float dy); + + /** */ + void onBouncerShown(); + + /** */ + void onBouncerHidden(); + + /** */ + void onTouchEvent(MotionEvent ev, int width, int height); + + /** */ + void cleanup(); +} + diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorFake.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorFake.java new file mode 100644 index 000000000000..a5691118261a --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorFake.java @@ -0,0 +1,152 @@ +/* + * 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.classifier; + +import android.view.MotionEvent; + +/** */ +public class FalsingCollectorFake implements FalsingCollector { + @Override + public void onSuccessfulUnlock() { + } + + @Override + public void onNotificationActive() { + } + + @Override + public void setShowingAod(boolean showingAod) { + } + + @Override + public void onNotificationStartDraggingDown() { + } + + @Override + public void onNotificationStopDraggingDown() { + } + + @Override + public void setNotificationExpanded() { + } + + @Override + public void onQsDown() { + } + + @Override + public void setQsExpanded(boolean expanded) { + } + + @Override + public boolean shouldEnforceBouncer() { + return false; + } + + @Override + public void onTrackingStarted(boolean secure) { + } + + @Override + public void onTrackingStopped() { + } + + @Override + public void onLeftAffordanceOn() { + } + + @Override + public void onCameraOn() { + } + + @Override + public void onAffordanceSwipingStarted(boolean rightCorner) { + } + + @Override + public void onAffordanceSwipingAborted() { + } + + @Override + public void onStartExpandingFromPulse() { + } + + @Override + public void onExpansionFromPulseStopped() { + } + + @Override + public void onScreenOnFromTouch() { + } + + @Override + public boolean isReportingEnabled() { + return false; + } + + @Override + public void onUnlockHintStarted() { + } + + @Override + public void onCameraHintStarted() { + } + + @Override + public void onLeftAffordanceHintStarted() { + } + + @Override + public void onScreenTurningOn() { + } + + @Override + public void onScreenOff() { + } + + @Override + public void onNotificationStopDismissing() { + } + + @Override + public void onNotificationDismissed() { + } + + @Override + public void onNotificationStartDismissing() { + } + + @Override + public void onNotificationDoubleTap(boolean accepted, float dx, float dy) { + } + + @Override + public void onBouncerShown() { + } + + @Override + public void onBouncerHidden() { + } + + @Override + public void onTouchEvent(MotionEvent ev, int width, int height) { + } + + @Override + public void cleanup() { + } +} diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorImpl.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorImpl.java new file mode 100644 index 000000000000..3547392512a7 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorImpl.java @@ -0,0 +1,321 @@ +/* + * 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.classifier; + +import android.hardware.SensorManager; +import android.hardware.biometrics.BiometricSourceType; +import android.util.Log; +import android.view.MotionEvent; + +import com.android.keyguard.KeyguardUpdateMonitor; +import com.android.keyguard.KeyguardUpdateMonitorCallback; +import com.android.systemui.dagger.SysUISingleton; +import com.android.systemui.plugins.FalsingManager; +import com.android.systemui.plugins.statusbar.StatusBarStateController; +import com.android.systemui.statusbar.StatusBarState; +import com.android.systemui.util.sensors.ProximitySensor; +import com.android.systemui.util.sensors.ThresholdSensor; + +import javax.inject.Inject; + +@SysUISingleton +class FalsingCollectorImpl implements FalsingCollector { + + private static final boolean DEBUG = false; + private static final String TAG = "FalsingManager"; + private static final String PROXIMITY_SENSOR_TAG = "FalsingManager"; + + private final FalsingDataProvider mFalsingDataProvider; + private final FalsingManager mFalsingManager; + private final KeyguardUpdateMonitor mKeyguardUpdateMonitor; + private final ProximitySensor mProximitySensor; + private final StatusBarStateController mStatusBarStateController; + + private int mState; + private boolean mShowingAod; + private boolean mScreenOn; + private boolean mSessionStarted; + + private final ThresholdSensor.Listener mSensorEventListener = this::onProximityEvent; + + private final StatusBarStateController.StateListener mStatusBarStateListener = + new StatusBarStateController.StateListener() { + @Override + public void onStateChanged(int newState) { + logDebug("StatusBarState=" + StatusBarState.toShortString(newState)); + mState = newState; + updateSessionActive(); + } + }; + + + private final KeyguardUpdateMonitorCallback mKeyguardUpdateCallback = + new KeyguardUpdateMonitorCallback() { + @Override + public void onBiometricAuthenticated(int userId, + BiometricSourceType biometricSourceType, + boolean isStrongBiometric) { + if (userId == KeyguardUpdateMonitor.getCurrentUser() + && biometricSourceType == BiometricSourceType.FACE) { + mFalsingDataProvider.setJustUnlockedWithFace(true); + } + } + }; + + @Inject + FalsingCollectorImpl(FalsingDataProvider falsingDataProvider, FalsingManager falsingManager, + KeyguardUpdateMonitor keyguardUpdateMonitor, + ProximitySensor proximitySensor, StatusBarStateController statusBarStateController) { + mFalsingDataProvider = falsingDataProvider; + mFalsingManager = falsingManager; + mKeyguardUpdateMonitor = keyguardUpdateMonitor; + mProximitySensor = proximitySensor; + mStatusBarStateController = statusBarStateController; + + + mProximitySensor.setTag(PROXIMITY_SENSOR_TAG); + mProximitySensor.setDelay(SensorManager.SENSOR_DELAY_GAME); + + mStatusBarStateController.addCallback(mStatusBarStateListener); + mState = mStatusBarStateController.getState(); + + mKeyguardUpdateMonitor.registerCallback(mKeyguardUpdateCallback); + } + + @Override + public void onSuccessfulUnlock() { + mFalsingManager.onSuccessfulUnlock(); + sessionEnd(); + } + + @Override + public void onNotificationActive() { + } + + @Override + public void setShowingAod(boolean showingAod) { + mShowingAod = showingAod; + updateSessionActive(); + } + + @Override + public void onNotificationStartDraggingDown() { + updateInteractionType(Classifier.NOTIFICATION_DRAG_DOWN); + } + + @Override + public void onNotificationStopDraggingDown() { + } + + @Override + public void setNotificationExpanded() { + } + + @Override + public void onQsDown() { + updateInteractionType(Classifier.QUICK_SETTINGS); + } + + @Override + public void setQsExpanded(boolean expanded) { + if (expanded) { + unregisterSensors(); + } else if (mSessionStarted) { + registerSensors(); + } + } + + @Override + public boolean shouldEnforceBouncer() { + return false; + } + + @Override + public void onTrackingStarted(boolean secure) { + updateInteractionType(secure ? Classifier.BOUNCER_UNLOCK : Classifier.UNLOCK); + } + + @Override + public void onTrackingStopped() { + } + + @Override + public void onLeftAffordanceOn() { + } + + @Override + public void onCameraOn() { + } + + @Override + public void onAffordanceSwipingStarted(boolean rightCorner) { + updateInteractionType( + rightCorner ? Classifier.RIGHT_AFFORDANCE : Classifier.LEFT_AFFORDANCE); + } + + @Override + public void onAffordanceSwipingAborted() { + } + + @Override + public void onStartExpandingFromPulse() { + updateInteractionType(Classifier.PULSE_EXPAND); + } + + @Override + public void onExpansionFromPulseStopped() { + } + + @Override + public void onScreenOnFromTouch() { + onScreenTurningOn(); + } + + @Override + public boolean isReportingEnabled() { + return false; + } + + @Override + public void onUnlockHintStarted() { + } + + @Override + public void onCameraHintStarted() { + } + + @Override + public void onLeftAffordanceHintStarted() { + } + + @Override + public void onScreenTurningOn() { + mScreenOn = true; + updateSessionActive(); + } + + @Override + public void onScreenOff() { + mScreenOn = false; + updateSessionActive(); + } + + @Override + public void onNotificationStopDismissing() { + } + + @Override + public void onNotificationDismissed() { + } + + @Override + public void onNotificationStartDismissing() { + updateInteractionType(Classifier.NOTIFICATION_DISMISS); + } + + @Override + public void onNotificationDoubleTap(boolean accepted, float dx, float dy) { + } + + @Override + public void onBouncerShown() { + unregisterSensors(); + } + + @Override + public void onBouncerHidden() { + if (mSessionStarted) { + registerSensors(); + } + } + + @Override + public void onTouchEvent(MotionEvent ev, int width, int height) { + mFalsingDataProvider.onMotionEvent(ev); + mFalsingManager.onTouchEvent(ev, width, height); + } + + @Override + public void cleanup() { + unregisterSensors(); + mKeyguardUpdateMonitor.removeCallback(mKeyguardUpdateCallback); + mStatusBarStateController.removeCallback(mStatusBarStateListener); + } + + private void updateInteractionType(@Classifier.InteractionType int type) { + logDebug("InteractionType: " + type); + mFalsingDataProvider.setInteractionType(type); + } + + private boolean shouldSessionBeActive() { + return mScreenOn && (mState == StatusBarState.KEYGUARD) && !mShowingAod; + } + + private void updateSessionActive() { + if (shouldSessionBeActive()) { + sessionStart(); + } else { + sessionEnd(); + } + } + + private void sessionStart() { + if (!mSessionStarted && shouldSessionBeActive()) { + logDebug("Starting Session"); + mSessionStarted = true; + mFalsingDataProvider.setJustUnlockedWithFace(false); + registerSensors(); + mFalsingDataProvider.onSessionStarted(); + } + } + + private void sessionEnd() { + if (mSessionStarted) { + logDebug("Ending Session"); + mSessionStarted = false; + unregisterSensors(); + mFalsingDataProvider.onSessionEnd(); + } + } + + private void registerSensors() { + if (!mFalsingDataProvider.isWirelessCharging()) { + mProximitySensor.register(mSensorEventListener); + } + } + + private void unregisterSensors() { + mProximitySensor.unregister(mSensorEventListener); + } + + private void onProximityEvent(ThresholdSensor.ThresholdSensorEvent proximityEvent) { + // TODO: some of these classifiers might allow us to abort early, meaning we don't have to + // make these calls. + mFalsingManager.onProximityEvent(proximityEvent); + } + + + static void logDebug(String msg) { + logDebug(msg, null); + } + + static void logDebug(String msg, Throwable throwable) { + if (DEBUG) { + Log.d(TAG, msg, throwable); + } + } +} diff --git a/packages/SystemUI/src/com/android/systemui/classifier/brightline/FalsingDataProvider.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingDataProvider.java index 4681f9709a7d..b29871c1c3d0 100644 --- a/packages/SystemUI/src/com/android/systemui/classifier/brightline/FalsingDataProvider.java +++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingDataProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 The Android Open Source Project + * 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. @@ -14,14 +14,17 @@ * limitations under the License. */ -package com.android.systemui.classifier.brightline; +package com.android.systemui.classifier; import android.util.DisplayMetrics; import android.view.MotionEvent; import android.view.MotionEvent.PointerCoords; import android.view.MotionEvent.PointerProperties; -import com.android.systemui.classifier.Classifier; +import com.android.systemui.classifier.brightline.BrightLineFalsingManager; +import com.android.systemui.classifier.brightline.FalsingClassifier; +import com.android.systemui.classifier.brightline.TimeLimitedMotionEventBuffer; +import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.statusbar.policy.BatteryController; import com.android.systemui.util.time.SystemClock; @@ -36,6 +39,7 @@ import javax.inject.Inject; /** * Acts as a cache and utility class for FalsingClassifiers. */ +@SysUISingleton public class FalsingDataProvider { private static final long MOTION_EVENT_AGE_MS = 1000; @@ -48,6 +52,7 @@ public class FalsingDataProvider { private final SystemClock mSystemClock; private final float mXdpi; private final float mYdpi; + private final List<SessionListener> mSessionListeners = new ArrayList<>(); private @Classifier.InteractionType int mInteractionType; private final Deque<TimeLimitedMotionEventBuffer> mExtendedMotionEvents = new LinkedList<>(); @@ -57,9 +62,9 @@ public class FalsingDataProvider { private boolean mDirty = true; private float mAngle = 0; - private MotionEvent mFirstActualMotionEvent; private MotionEvent mFirstRecentMotionEvent; private MotionEvent mLastMotionEvent; + private boolean mJustUnlockedWithFace; @Inject public FalsingDataProvider(DisplayMetrics displayMetrics, BatteryController batteryController, @@ -76,10 +81,6 @@ public class FalsingDataProvider { } void onMotionEvent(MotionEvent motionEvent) { - if (motionEvent.getActionMasked() == MotionEvent.ACTION_DOWN) { - mFirstActualMotionEvent = motionEvent; - } - List<MotionEvent> motionEvents = unpackMotionEvent(motionEvent); FalsingClassifier.logDebug("Unpacked into: " + motionEvents.size()); if (BrightLineFalsingManager.DEBUG) { @@ -103,29 +104,29 @@ public class FalsingDataProvider { } /** Returns screen width in pixels. */ - int getWidthPixels() { + public int getWidthPixels() { return mWidthPixels; } /** Returns screen height in pixels. */ - int getHeightPixels() { + public int getHeightPixels() { return mHeightPixels; } - float getXdpi() { + public float getXdpi() { return mXdpi; } - float getYdpi() { + public float getYdpi() { return mYdpi; } - List<MotionEvent> getRecentMotionEvents() { + public List<MotionEvent> getRecentMotionEvents() { return mRecentMotionEvents; } /** Returns recent gestures, exclusive of the most recent gesture. Newer gestures come first. */ - Queue<? extends List<MotionEvent>> getHistoricalMotionEvents() { + public Queue<? extends List<MotionEvent>> getHistoricalMotionEvents() { long nowMs = mSystemClock.uptimeMillis(); mExtendedMotionEvents.removeIf( @@ -137,31 +138,38 @@ public class FalsingDataProvider { /** * interactionType is defined by {@link com.android.systemui.classifier.Classifier}. */ - final void setInteractionType(@Classifier.InteractionType int interactionType) { + public final void setInteractionType(@Classifier.InteractionType int interactionType) { if (mInteractionType != interactionType) { mInteractionType = interactionType; mDirty = true; } } + /** + * Returns true if new data has been supplied since the last time this class has been accessed. + */ public boolean isDirty() { return mDirty; } - final int getInteractionType() { + /** Return the interaction type that is being compared against for falsing. */ + public final int getInteractionType() { return mInteractionType; } - MotionEvent getFirstActualMotionEvent() { - return mFirstActualMotionEvent; - } - - MotionEvent getFirstRecentMotionEvent() { + /** + * Get the first recorded {@link MotionEvent} of the most recent gesture. + * + * Note that MotionEvents are not kept forever. As a gesture gets longer in duration, older + * MotionEvents may expire and be ejected. + */ + public MotionEvent getFirstRecentMotionEvent() { recalculateData(); return mFirstRecentMotionEvent; } - MotionEvent getLastMotionEvent() { + /** Get the last recorded {@link MotionEvent}. */ + public MotionEvent getLastMotionEvent() { recalculateData(); return mLastMotionEvent; } @@ -171,12 +179,13 @@ public class FalsingDataProvider { * * The angle will be in radians, always be between 0 and 2*PI, inclusive. */ - float getAngle() { + public float getAngle() { recalculateData(); return mAngle; } - boolean isHorizontal() { + /** Returns if the most recent gesture is more horizontal than vertical. */ + public boolean isHorizontal() { recalculateData(); if (mRecentMotionEvents.isEmpty()) { return false; @@ -186,7 +195,13 @@ public class FalsingDataProvider { .abs(mFirstRecentMotionEvent.getY() - mLastMotionEvent.getY()); } - boolean isRight() { + /** + * Is the most recent gesture more right than left. + * + * This does not mean the gesture is mostly horizontal. Simply that it ended at least one pixel + * to the right of where it started. See also {@link #isHorizontal()}. + */ + public boolean isRight() { recalculateData(); if (mRecentMotionEvents.isEmpty()) { return false; @@ -195,11 +210,18 @@ public class FalsingDataProvider { return mLastMotionEvent.getX() > mFirstRecentMotionEvent.getX(); } - boolean isVertical() { + /** Returns if the most recent gesture is more vertical than horizontal. */ + public boolean isVertical() { return !isHorizontal(); } - boolean isUp() { + /** + * Is the most recent gesture more up than down. + * + * This does not mean the gesture is mostly vertical. Simply that it ended at least one pixel + * higher than it started. See also {@link #isVertical()}. + */ + public boolean isUp() { recalculateData(); if (mRecentMotionEvents.isEmpty()) { return false; @@ -209,7 +231,7 @@ public class FalsingDataProvider { } /** Returns true if phone is being charged without a cable. */ - boolean isWirelessCharging() { + public boolean isWirelessCharging() { return mBatteryController.isWirelessCharging(); } @@ -292,9 +314,21 @@ public class FalsingDataProvider { return motionEvents; } - void onSessionEnd() { - mFirstActualMotionEvent = null; + /** Register a {@link SessionListener}. */ + public void addSessionListener(SessionListener listener) { + mSessionListeners.add(listener); + } + + /** Unregister a {@link SessionListener}. */ + public void removeSessionListener(SessionListener listener) { + mSessionListeners.remove(listener); + } + void onSessionStarted() { + mSessionListeners.forEach(SessionListener::onSessionStarted); + } + + void onSessionEnd() { for (MotionEvent ev : mRecentMotionEvents) { ev.recycle(); } @@ -302,5 +336,24 @@ public class FalsingDataProvider { mRecentMotionEvents.clear(); mDirty = true; + + mSessionListeners.forEach(SessionListener::onSessionEnded); + } + + public boolean isJustUnlockedWithFace() { + return mJustUnlockedWithFace; + } + + public void setJustUnlockedWithFace(boolean justUnlockedWithFace) { + mJustUnlockedWithFace = justUnlockedWithFace; + } + + /** Implement to be alerted abotu the beginning and ending of falsing tracking. */ + public interface SessionListener { + /** Called when the lock screen is shown and falsing-tracking begins. */ + void onSessionStarted(); + + /** Called when the lock screen exits and falsing-tracking ends. */ + void onSessionEnded(); } } diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerFake.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerFake.java index 121484303b99..32d27bcc01a6 100644 --- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerFake.java +++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerFake.java @@ -21,6 +21,7 @@ import android.view.MotionEvent; import com.android.internal.annotations.VisibleForTesting; import com.android.systemui.plugins.FalsingManager; +import com.android.systemui.util.sensors.ThresholdSensor; import java.io.FileDescriptor; import java.io.PrintWriter; @@ -43,21 +44,6 @@ public class FalsingManagerFake implements FalsingManager { } - @Override - public void onNotificationActive() { - - } - - @Override - public void setShowingAod(boolean showingAod) { - - } - - @Override - public void onNotificatonStartDraggingDown() { - - } - @VisibleForTesting public void setIsUnlockingDisabled(boolean isUnlockingDisabled) { mIsUnlockingDisabled = isUnlockingDisabled; @@ -100,16 +86,6 @@ public class FalsingManagerFake implements FalsingManager { return mIsFalseDoubleTap; } - @Override - public void onNotificatonStopDraggingDown() { - - } - - @Override - public void setNotificationExpanded() { - - } - @VisibleForTesting public void setIsClassiferEnabled(boolean isClassiferEnabled) { mIsClassiferEnabled = isClassiferEnabled; @@ -121,76 +97,15 @@ public class FalsingManagerFake implements FalsingManager { } @Override - public void onQsDown() { - - } - - @Override - public void setQsExpanded(boolean expanded) { - - } - - @VisibleForTesting - public void setShouldEnforceBouncer(boolean shouldEnforceBouncer) { - mShouldEnforceBouncer = shouldEnforceBouncer; - } - - @Override public boolean shouldEnforceBouncer() { return mShouldEnforceBouncer; } @Override - public void onTrackingStarted(boolean secure) { - - } - - @Override - public void onTrackingStopped() { - - } - - @Override - public void onLeftAffordanceOn() { - - } - - @Override - public void onCameraOn() { - - } - - @Override - public void onAffordanceSwipingStarted(boolean rightCorner) { - - } - - @Override - public void onAffordanceSwipingAborted() { - - } - - @Override - public void onStartExpandingFromPulse() { - - } - - @Override - public void onExpansionFromPulseStopped() { - - } - - @Override public Uri reportRejectedTouch() { return null; } - @Override - public void onScreenOnFromTouch() { - - } - - @VisibleForTesting public void setIsReportingEnabled(boolean isReportingEnabled) { mIsReportingEnabled = isReportingEnabled; @@ -202,70 +117,20 @@ public class FalsingManagerFake implements FalsingManager { } @Override - public void onUnlockHintStarted() { - - } - - @Override - public void onCameraHintStarted() { - - } - - @Override - public void onLeftAffordanceHintStarted() { - - } - - @Override - public void onScreenTurningOn() { - - } - - @Override - public void onScreenOff() { - - } - - @Override - public void onNotificationStopDismissing() { - - } - - @Override - public void onNotificationDismissed() { - - } - - @Override - public void onNotificationStartDismissing() { - - } - - @Override - public void onNotificationDoubleTap(boolean accepted, float dx, float dy) { - - } - - @Override - public void onBouncerShown() { + public void onTouchEvent(MotionEvent ev, int width, int height) { } @Override - public void onBouncerHidden() { - + public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { } @Override - public void onTouchEvent(MotionEvent ev, int width, int height) { - + public void cleanup() { } @Override - public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { - } + public void onProximityEvent(ThresholdSensor.ThresholdSensorEvent proximityEvent) { - @Override - public void cleanup() { } } diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java index 814fff9c6d43..74629411c13d 100644 --- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java +++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java @@ -17,37 +17,30 @@ package com.android.systemui.classifier; import android.content.Context; -import android.content.res.Resources; -import android.hardware.SensorManager; import android.net.Uri; import android.provider.DeviceConfig; import android.view.MotionEvent; -import android.view.ViewConfiguration; import androidx.annotation.NonNull; -import com.android.internal.annotations.VisibleForTesting; -import com.android.keyguard.KeyguardUpdateMonitor; import com.android.systemui.Dumpable; import com.android.systemui.classifier.brightline.BrightLineFalsingManager; -import com.android.systemui.classifier.brightline.FalsingDataProvider; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Main; -import com.android.systemui.dock.DockManager; import com.android.systemui.dump.DumpManager; import com.android.systemui.plugins.FalsingManager; import com.android.systemui.plugins.FalsingPlugin; import com.android.systemui.plugins.PluginListener; -import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.shared.plugins.PluginManager; import com.android.systemui.util.DeviceConfigProxy; -import com.android.systemui.util.sensors.ProximitySensor; +import com.android.systemui.util.sensors.ThresholdSensor; import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.concurrent.Executor; import javax.inject.Inject; +import javax.inject.Provider; /** * Simple passthrough implementation of {@link FalsingManager} allowing plugins to swap in. @@ -57,21 +50,14 @@ import javax.inject.Inject; @SysUISingleton public class FalsingManagerProxy implements FalsingManager, Dumpable { - private static final String PROXIMITY_SENSOR_TAG = "FalsingManager"; private static final String DUMPABLE_TAG = "FalsingManager"; public static final String FALSING_REMAIN_LOCKED = "falsing_failure_after_attempts"; public static final String FALSING_SUCCESS = "falsing_success_after_attempts"; private final PluginManager mPluginManager; - private final ProximitySensor mProximitySensor; - private final Resources mResources; - private final ViewConfiguration mViewConfiguration; - private final FalsingDataProvider mFalsingDataProvider; private final DeviceConfigProxy mDeviceConfig; - private final DockManager mDockManager; - private final KeyguardUpdateMonitor mKeyguardUpdateMonitor; + private final Provider<BrightLineFalsingManager> mBrightLineFalsingManagerProvider; private final DumpManager mDumpManager; - private final StatusBarStateController mStatusBarStateController; final PluginListener<FalsingPlugin> mPluginListener; private FalsingManager mInternalFalsingManager; @@ -81,31 +67,15 @@ public class FalsingManagerProxy implements FalsingManager, Dumpable { @Inject FalsingManagerProxy(PluginManager pluginManager, @Main Executor executor, - ProximitySensor proximitySensor, - DeviceConfigProxy deviceConfig, DockManager dockManager, - KeyguardUpdateMonitor keyguardUpdateMonitor, - DumpManager dumpManager, - StatusBarStateController statusBarStateController, - @Main Resources resources, - ViewConfiguration viewConfiguration, - FalsingDataProvider falsingDataProvider) { + DeviceConfigProxy deviceConfig, DumpManager dumpManager, + Provider<BrightLineFalsingManager> brightLineFalsingManagerProvider) { mPluginManager = pluginManager; - mProximitySensor = proximitySensor; - mDockManager = dockManager; - mKeyguardUpdateMonitor = keyguardUpdateMonitor; mDumpManager = dumpManager; - mStatusBarStateController = statusBarStateController; - mResources = resources; - mViewConfiguration = viewConfiguration; - mFalsingDataProvider = falsingDataProvider; - mProximitySensor.setTag(PROXIMITY_SENSOR_TAG); - mProximitySensor.setDelay(SensorManager.SENSOR_DELAY_GAME); mDeviceConfig = deviceConfig; + mBrightLineFalsingManagerProvider = brightLineFalsingManagerProvider; setupFalsingManager(); mDeviceConfig.addOnPropertiesChangedListener( - DeviceConfig.NAMESPACE_SYSTEMUI, - executor, - mDeviceConfigListener + DeviceConfig.NAMESPACE_SYSTEMUI, executor, mDeviceConfigListener ); mPluginListener = new PluginListener<FalsingPlugin>() { @@ -144,24 +114,7 @@ public class FalsingManagerProxy implements FalsingManager, Dumpable { if (mInternalFalsingManager != null) { mInternalFalsingManager.cleanup(); } - mInternalFalsingManager = new BrightLineFalsingManager( - mFalsingDataProvider, - mKeyguardUpdateMonitor, - mProximitySensor, - mDeviceConfig, - mResources, - mViewConfiguration, - mDockManager, - mStatusBarStateController - ); - } - - /** - * Returns the FalsingManager implementation in use. - */ - @VisibleForTesting - FalsingManager getInternalFalsingManager() { - return mInternalFalsingManager; + mInternalFalsingManager = mBrightLineFalsingManagerProvider.get(); } @Override @@ -170,21 +123,6 @@ public class FalsingManagerProxy implements FalsingManager, Dumpable { } @Override - public void onNotificationActive() { - mInternalFalsingManager.onNotificationActive(); - } - - @Override - public void setShowingAod(boolean showingAod) { - mInternalFalsingManager.setShowingAod(showingAod); - } - - @Override - public void onNotificatonStartDraggingDown() { - mInternalFalsingManager.onNotificatonStartDraggingDown(); - } - - @Override public boolean isUnlockingDisabled() { return mInternalFalsingManager.isUnlockingDisabled(); } @@ -194,7 +132,6 @@ public class FalsingManagerProxy implements FalsingManager, Dumpable { return mInternalFalsingManager.isFalseTouch(interactionType); } - @Override public boolean isFalseTap(boolean robustCheck) { return mInternalFalsingManager.isFalseTap(robustCheck); @@ -206,148 +143,33 @@ public class FalsingManagerProxy implements FalsingManager, Dumpable { } @Override - public void onNotificatonStopDraggingDown() { - mInternalFalsingManager.onNotificatonStartDraggingDown(); - } - - @Override - public void setNotificationExpanded() { - mInternalFalsingManager.setNotificationExpanded(); - } - - @Override public boolean isClassifierEnabled() { return mInternalFalsingManager.isClassifierEnabled(); } @Override - public void onQsDown() { - mInternalFalsingManager.onQsDown(); - } - - @Override - public void setQsExpanded(boolean expanded) { - mInternalFalsingManager.setQsExpanded(expanded); - } - - @Override public boolean shouldEnforceBouncer() { return mInternalFalsingManager.shouldEnforceBouncer(); } @Override - public void onTrackingStarted(boolean secure) { - mInternalFalsingManager.onTrackingStarted(secure); - } - - @Override - public void onTrackingStopped() { - mInternalFalsingManager.onTrackingStopped(); - } - - @Override - public void onLeftAffordanceOn() { - mInternalFalsingManager.onLeftAffordanceOn(); - } - - @Override - public void onCameraOn() { - mInternalFalsingManager.onCameraOn(); - } - - @Override - public void onAffordanceSwipingStarted(boolean rightCorner) { - mInternalFalsingManager.onAffordanceSwipingStarted(rightCorner); - } - - @Override - public void onAffordanceSwipingAborted() { - mInternalFalsingManager.onAffordanceSwipingAborted(); - } - - @Override - public void onStartExpandingFromPulse() { - mInternalFalsingManager.onStartExpandingFromPulse(); - } - - @Override - public void onExpansionFromPulseStopped() { - mInternalFalsingManager.onExpansionFromPulseStopped(); - } - - @Override public Uri reportRejectedTouch() { return mInternalFalsingManager.reportRejectedTouch(); } @Override - public void onScreenOnFromTouch() { - mInternalFalsingManager.onScreenOnFromTouch(); - } - - @Override public boolean isReportingEnabled() { return mInternalFalsingManager.isReportingEnabled(); } @Override - public void onUnlockHintStarted() { - mInternalFalsingManager.onUnlockHintStarted(); - } - - @Override - public void onCameraHintStarted() { - mInternalFalsingManager.onCameraHintStarted(); - } - - @Override - public void onLeftAffordanceHintStarted() { - mInternalFalsingManager.onLeftAffordanceHintStarted(); - } - - @Override - public void onScreenTurningOn() { - mInternalFalsingManager.onScreenTurningOn(); - } - - @Override - public void onScreenOff() { - mInternalFalsingManager.onScreenOff(); - } - - @Override - public void onNotificationStopDismissing() { - mInternalFalsingManager.onNotificationStopDismissing(); - } - - @Override - public void onNotificationDismissed() { - mInternalFalsingManager.onNotificationDismissed(); - } - - @Override - public void onNotificationStartDismissing() { - mInternalFalsingManager.onNotificationStartDismissing(); - } - - @Override - public void onNotificationDoubleTap(boolean accepted, float dx, float dy) { - mInternalFalsingManager.onNotificationDoubleTap(accepted, dx, dy); - } - - @Override - public void onBouncerShown() { - mInternalFalsingManager.onBouncerShown(); - } - - @Override - public void onBouncerHidden() { - mInternalFalsingManager.onBouncerHidden(); + public void onTouchEvent(MotionEvent ev, int width, int height) { + mInternalFalsingManager.onTouchEvent(ev, width, height); } @Override - public void onTouchEvent(MotionEvent ev, int width, int height) { - mInternalFalsingManager.onTouchEvent(ev, width, height); + public void onProximityEvent(ThresholdSensor.ThresholdSensorEvent proximityEvent) { + mInternalFalsingManager.onProximityEvent(proximityEvent); } @Override diff --git a/core/proto/android/stats/accessibility/accessibility_enums.proto b/packages/SystemUI/src/com/android/systemui/classifier/FalsingModule.java index 5118ad5a322c..937bcbaa6222 100644 --- a/core/proto/android/stats/accessibility/accessibility_enums.proto +++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingModule.java @@ -14,22 +14,18 @@ * limitations under the License. */ -syntax = "proto2"; -package android.stats.accessibility; -option java_multiple_files = true; +package com.android.systemui.classifier; -// The entry point of the accessibility shortcut. -enum ShortcutType { - UNKNOWN_TYPE = 0; - A11Y_BUTTON = 1; - VOLUME_KEY = 2; - TRIPLE_TAP = 3; - A11Y_BUTTON_LONG_PRESS = 4; -} +import com.android.systemui.dagger.SysUISingleton; + +import dagger.Binds; +import dagger.Module; -// The service status code. -enum ServiceStatus { - UNKNOWN = 0; - ENABLED = 1; - DISABLED = 2; -}
\ No newline at end of file +/** Dagger Module for Falsing. */ +@Module +public interface FalsingModule { + /** */ + @Binds + @SysUISingleton + FalsingCollector bindsFalsingCollector(FalsingCollectorImpl impl); +} diff --git a/packages/SystemUI/src/com/android/systemui/classifier/brightline/BrightLineFalsingManager.java b/packages/SystemUI/src/com/android/systemui/classifier/brightline/BrightLineFalsingManager.java index 334102d68507..f6b8b4c92049 100644 --- a/packages/SystemUI/src/com/android/systemui/classifier/brightline/BrightLineFalsingManager.java +++ b/packages/SystemUI/src/com/android/systemui/classifier/brightline/BrightLineFalsingManager.java @@ -16,12 +16,10 @@ package com.android.systemui.classifier.brightline; -import static com.android.systemui.classifier.FalsingManagerProxy.FALSING_REMAIN_LOCKED; import static com.android.systemui.classifier.FalsingManagerProxy.FALSING_SUCCESS; import android.app.ActivityManager; import android.content.res.Resources; -import android.hardware.biometrics.BiometricSourceType; import android.net.Uri; import android.os.Build; import android.util.IndentingPrintWriter; @@ -32,18 +30,15 @@ import android.view.ViewConfiguration; import androidx.annotation.NonNull; import com.android.internal.logging.MetricsLogger; -import com.android.keyguard.KeyguardUpdateMonitor; -import com.android.keyguard.KeyguardUpdateMonitorCallback; import com.android.systemui.R; import com.android.systemui.classifier.Classifier; +import com.android.systemui.classifier.FalsingDataProvider; +import com.android.systemui.classifier.FalsingDataProvider.SessionListener; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.dock.DockManager; import com.android.systemui.plugins.FalsingManager; -import com.android.systemui.plugins.statusbar.StatusBarStateController; -import com.android.systemui.statusbar.StatusBarState; import com.android.systemui.statusbar.phone.NotificationTapHelper; import com.android.systemui.util.DeviceConfigProxy; -import com.android.systemui.util.sensors.ProximitySensor; import com.android.systemui.util.sensors.ThresholdSensor; import java.io.FileDescriptor; @@ -56,30 +51,25 @@ import java.util.Queue; import java.util.StringJoiner; import java.util.stream.Collectors; +import javax.inject.Inject; + /** * FalsingManager designed to make clear why a touch was rejected. */ public class BrightLineFalsingManager implements FalsingManager { private static final String TAG = "FalsingManager"; - static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); + public static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); private static final int RECENT_INFO_LOG_SIZE = 40; private static final int RECENT_SWIPE_LOG_SIZE = 20; private final FalsingDataProvider mDataProvider; - private final KeyguardUpdateMonitor mKeyguardUpdateMonitor; - private final ProximitySensor mProximitySensor; private final DockManager mDockManager; - private final StatusBarStateController mStatusBarStateController; private final SingleTapClassifier mSingleTapClassifier; private final DoubleTapClassifier mDoubleTapClassifier; - private boolean mSessionStarted; - private MetricsLogger mMetricsLogger; + private final MetricsLogger mMetricsLogger; private int mIsFalseTouchCalls; - private boolean mShowingAod; - private boolean mScreenOn; - private boolean mJustUnlockedWithFace; private static final Queue<String> RECENT_INFO_LOG = new ArrayDeque<>(RECENT_INFO_LOG_SIZE + 1); private static final Queue<DebugSwipeRecord> RECENT_SWIPES = @@ -87,46 +77,26 @@ public class BrightLineFalsingManager implements FalsingManager { private final List<FalsingClassifier> mClassifiers; - private ThresholdSensor.Listener mSensorEventListener = this::onProximityEvent; - - private final KeyguardUpdateMonitorCallback mKeyguardUpdateCallback = - new KeyguardUpdateMonitorCallback() { - @Override - public void onBiometricAuthenticated(int userId, - BiometricSourceType biometricSourceType, - boolean isStrongBiometric) { - if (userId == KeyguardUpdateMonitor.getCurrentUser() - && biometricSourceType == BiometricSourceType.FACE) { - mJustUnlockedWithFace = true; - } - } - }; - private boolean mPreviousResult = false; + private final SessionListener mSessionListener = new SessionListener() { + @Override + public void onSessionEnded() { + mClassifiers.forEach(FalsingClassifier::onSessionEnded); + } - private StatusBarStateController.StateListener mStatusBarStateListener = - new StatusBarStateController.StateListener() { @Override - public void onStateChanged(int newState) { - logDebug("StatusBarState=" + StatusBarState.toShortString(newState)); - mState = newState; - updateSessionActive(); + public void onSessionStarted() { + mClassifiers.forEach(FalsingClassifier::onSessionStarted); } }; - private int mState; + private boolean mPreviousResult = false; + + @Inject public BrightLineFalsingManager(FalsingDataProvider falsingDataProvider, - KeyguardUpdateMonitor keyguardUpdateMonitor, ProximitySensor proximitySensor, DeviceConfigProxy deviceConfigProxy, @Main Resources resources, - ViewConfiguration viewConfiguration, DockManager dockManager, - StatusBarStateController statusBarStateController) { - mKeyguardUpdateMonitor = keyguardUpdateMonitor; + ViewConfiguration viewConfiguration, DockManager dockManager) { mDataProvider = falsingDataProvider; - mProximitySensor = proximitySensor; mDockManager = dockManager; - mStatusBarStateController = statusBarStateController; - mKeyguardUpdateMonitor.registerCallback(mKeyguardUpdateCallback); - mStatusBarStateController.addCallback(mStatusBarStateListener); - mState = mStatusBarStateController.getState(); mMetricsLogger = new MetricsLogger(); mClassifiers = new ArrayList<>(); @@ -146,58 +116,8 @@ public class BrightLineFalsingManager implements FalsingManager { mDoubleTapClassifier = new DoubleTapClassifier(mDataProvider, mSingleTapClassifier, resources.getDimension(R.dimen.double_tap_slop), NotificationTapHelper.DOUBLE_TAP_TIMEOUT_MS); - } - - private void registerSensors() { - if (!mDataProvider.isWirelessCharging()) { - mProximitySensor.register(mSensorEventListener); - } - } - - private void unregisterSensors() { - mProximitySensor.unregister(mSensorEventListener); - } - private void sessionStart() { - if (!mSessionStarted && shouldSessionBeActive()) { - logDebug("Starting Session"); - mSessionStarted = true; - mJustUnlockedWithFace = false; - registerSensors(); - mClassifiers.forEach(FalsingClassifier::onSessionStarted); - } - } - - private void sessionEnd() { - if (mSessionStarted) { - logDebug("Ending Session"); - mSessionStarted = false; - unregisterSensors(); - mDataProvider.onSessionEnd(); - mClassifiers.forEach(FalsingClassifier::onSessionEnded); - if (mIsFalseTouchCalls != 0) { - mMetricsLogger.histogram(FALSING_REMAIN_LOCKED, mIsFalseTouchCalls); - mIsFalseTouchCalls = 0; - } - } - } - - - private void updateSessionActive() { - if (shouldSessionBeActive()) { - sessionStart(); - } else { - sessionEnd(); - } - } - - private boolean shouldSessionBeActive() { - return mScreenOn && (mState == StatusBarState.KEYGUARD) && !mShowingAod; - } - - private void updateInteractionType(@Classifier.InteractionType int type) { - logDebug("InteractionType: " + type); - mDataProvider.setInteractionType(type); + mDataProvider.addSessionListener(mSessionListener); } @Override @@ -212,8 +132,9 @@ public class BrightLineFalsingManager implements FalsingManager { return mPreviousResult; } - mPreviousResult = !ActivityManager.isRunningInUserTestHarness() && !mJustUnlockedWithFace - && !mDockManager.isDocked() && mClassifiers.stream().anyMatch(falsingClassifier -> { + mPreviousResult = !ActivityManager.isRunningInUserTestHarness() + && !mDataProvider.isJustUnlockedWithFace() && !mDockManager.isDocked() + && mClassifiers.stream().anyMatch(falsingClassifier -> { boolean result = falsingClassifier.isFalseTouch(); if (result) { logInfo(String.format( @@ -245,9 +166,8 @@ public class BrightLineFalsingManager implements FalsingManager { (int) (motionEvent.getEventTime() - motionEvent.getDownTime()))) .collect(Collectors.toList()))); while (RECENT_SWIPES.size() > RECENT_INFO_LOG_SIZE) { - DebugSwipeRecord record = RECENT_SWIPES.remove(); + RECENT_SWIPES.remove(); } - } return mPreviousResult; @@ -287,11 +207,11 @@ public class BrightLineFalsingManager implements FalsingManager { public void onTouchEvent(MotionEvent motionEvent, int width, int height) { // TODO: some of these classifiers might allow us to abort early, meaning we don't have to // make these calls. - mDataProvider.onMotionEvent(motionEvent); mClassifiers.forEach((classifier) -> classifier.onTouchEvent(motionEvent)); } - private void onProximityEvent(ThresholdSensor.ThresholdSensorEvent proximityEvent) { + @Override + public void onProximityEvent(ThresholdSensor.ThresholdSensorEvent proximityEvent) { // TODO: some of these classifiers might allow us to abort early, meaning we don't have to // make these calls. mClassifiers.forEach((classifier) -> classifier.onProximityEvent(proximityEvent)); @@ -303,22 +223,6 @@ public class BrightLineFalsingManager implements FalsingManager { mMetricsLogger.histogram(FALSING_SUCCESS, mIsFalseTouchCalls); mIsFalseTouchCalls = 0; } - sessionEnd(); - } - - @Override - public void onNotificationActive() { - } - - @Override - public void setShowingAod(boolean showingAod) { - mShowingAod = showingAod; - updateSessionActive(); - } - - @Override - public void onNotificatonStartDraggingDown() { - updateInteractionType(Classifier.NOTIFICATION_DRAG_DOWN); } @Override @@ -326,147 +230,29 @@ public class BrightLineFalsingManager implements FalsingManager { return false; } - - @Override - public void onNotificatonStopDraggingDown() { - } - - @Override - public void setNotificationExpanded() { - } - - @Override - public void onQsDown() { - updateInteractionType(Classifier.QUICK_SETTINGS); - } - - @Override - public void setQsExpanded(boolean expanded) { - if (expanded) { - unregisterSensors(); - } else if (mSessionStarted) { - registerSensors(); - } - } - @Override public boolean shouldEnforceBouncer() { return false; } @Override - public void onTrackingStarted(boolean secure) { - updateInteractionType(secure ? Classifier.BOUNCER_UNLOCK : Classifier.UNLOCK); - } - - @Override - public void onTrackingStopped() { - } - - @Override - public void onLeftAffordanceOn() { - } - - @Override - public void onCameraOn() { - } - - @Override - public void onAffordanceSwipingStarted(boolean rightCorner) { - updateInteractionType( - rightCorner ? Classifier.RIGHT_AFFORDANCE : Classifier.LEFT_AFFORDANCE); - } - - @Override - public void onAffordanceSwipingAborted() { - } - - @Override - public void onStartExpandingFromPulse() { - updateInteractionType(Classifier.PULSE_EXPAND); - } - - @Override - public void onExpansionFromPulseStopped() { - } - - @Override public Uri reportRejectedTouch() { return null; } @Override - public void onScreenOnFromTouch() { - onScreenTurningOn(); - } - - @Override public boolean isReportingEnabled() { return false; } @Override - public void onUnlockHintStarted() { - } - - @Override - public void onCameraHintStarted() { - } - - @Override - public void onLeftAffordanceHintStarted() { - } - - @Override - public void onScreenTurningOn() { - mScreenOn = true; - updateSessionActive(); - } - - @Override - public void onScreenOff() { - mScreenOn = false; - updateSessionActive(); - } - - - @Override - public void onNotificationStopDismissing() { - } - - @Override - public void onNotificationDismissed() { - } - - @Override - public void onNotificationStartDismissing() { - updateInteractionType(Classifier.NOTIFICATION_DISMISS); - } - - @Override - public void onNotificationDoubleTap(boolean b, float v, float v1) { - } - - @Override - public void onBouncerShown() { - unregisterSensors(); - } - - @Override - public void onBouncerHidden() { - if (mSessionStarted) { - registerSensors(); - } - } - - @Override public void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter pw, @NonNull String[] args) { IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " "); ipw.println("BRIGHTLINE FALSING MANAGER"); ipw.print("classifierEnabled="); ipw.println(isClassifierEnabled() ? 1 : 0); ipw.print("mJustUnlockedWithFace="); - ipw.println(mJustUnlockedWithFace ? 1 : 0); + ipw.println(mDataProvider.isJustUnlockedWithFace() ? 1 : 0); ipw.print("isDocked="); ipw.println(mDockManager.isDocked() ? 1 : 0); ipw.print("width="); @@ -496,9 +282,7 @@ public class BrightLineFalsingManager implements FalsingManager { @Override public void cleanup() { - unregisterSensors(); - mKeyguardUpdateMonitor.removeCallback(mKeyguardUpdateCallback); - mStatusBarStateController.removeCallback(mStatusBarStateListener); + mDataProvider.removeSessionListener(mSessionListener); } static void logDebug(String msg) { diff --git a/packages/SystemUI/src/com/android/systemui/classifier/brightline/DiagonalClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/brightline/DiagonalClassifier.java index 520e0a12dec4..a73ccf575249 100644 --- a/packages/SystemUI/src/com/android/systemui/classifier/brightline/DiagonalClassifier.java +++ b/packages/SystemUI/src/com/android/systemui/classifier/brightline/DiagonalClassifier.java @@ -23,6 +23,7 @@ import static com.android.systemui.classifier.Classifier.RIGHT_AFFORDANCE; import android.provider.DeviceConfig; +import com.android.systemui.classifier.FalsingDataProvider; import com.android.systemui.util.DeviceConfigProxy; import java.util.Locale; diff --git a/packages/SystemUI/src/com/android/systemui/classifier/brightline/DistanceClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/brightline/DistanceClassifier.java index 0329183e6048..524d524f38b6 100644 --- a/packages/SystemUI/src/com/android/systemui/classifier/brightline/DistanceClassifier.java +++ b/packages/SystemUI/src/com/android/systemui/classifier/brightline/DistanceClassifier.java @@ -27,6 +27,7 @@ import android.provider.DeviceConfig; import android.view.MotionEvent; import android.view.VelocityTracker; +import com.android.systemui.classifier.FalsingDataProvider; import com.android.systemui.util.DeviceConfigProxy; import java.util.List; @@ -112,7 +113,6 @@ class DistanceClassifier extends FalsingClassifier { private DistanceVectors calculateDistances() { // This code assumes that there will be no missed DOWN or UP events. - VelocityTracker velocityTracker = VelocityTracker.obtain(); List<MotionEvent> motionEvents = getRecentMotionEvents(); if (motionEvents.size() < 3) { @@ -120,6 +120,8 @@ class DistanceClassifier extends FalsingClassifier { return new DistanceVectors(0, 0, 0, 0); } + VelocityTracker velocityTracker = VelocityTracker.obtain(); + for (MotionEvent motionEvent : motionEvents) { velocityTracker.addMovement(motionEvent); } diff --git a/packages/SystemUI/src/com/android/systemui/classifier/brightline/DoubleTapClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/brightline/DoubleTapClassifier.java index d3af1c347048..a27ea6172414 100644 --- a/packages/SystemUI/src/com/android/systemui/classifier/brightline/DoubleTapClassifier.java +++ b/packages/SystemUI/src/com/android/systemui/classifier/brightline/DoubleTapClassifier.java @@ -18,6 +18,8 @@ package com.android.systemui.classifier.brightline; import android.view.MotionEvent; +import com.android.systemui.classifier.FalsingDataProvider; + import java.util.List; import java.util.Queue; diff --git a/packages/SystemUI/src/com/android/systemui/classifier/brightline/FalsingClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/brightline/FalsingClassifier.java index ed417b3d09ec..568dc432729f 100644 --- a/packages/SystemUI/src/com/android/systemui/classifier/brightline/FalsingClassifier.java +++ b/packages/SystemUI/src/com/android/systemui/classifier/brightline/FalsingClassifier.java @@ -19,6 +19,7 @@ package com.android.systemui.classifier.brightline; import android.view.MotionEvent; import com.android.systemui.classifier.Classifier; +import com.android.systemui.classifier.FalsingDataProvider; import com.android.systemui.util.sensors.ProximitySensor; import java.util.List; @@ -27,7 +28,7 @@ import java.util.Queue; /** * Base class for rules that determine False touches. */ -abstract class FalsingClassifier { +public abstract class FalsingClassifier { private final FalsingDataProvider mDataProvider; FalsingClassifier(FalsingDataProvider dataProvider) { @@ -126,15 +127,18 @@ abstract class FalsingClassifier { */ abstract String getReason(); - static void logDebug(String msg) { + /** */ + public static void logDebug(String msg) { BrightLineFalsingManager.logDebug(msg); } - static void logInfo(String msg) { + /** */ + public static void logInfo(String msg) { BrightLineFalsingManager.logInfo(msg); } - static void logError(String msg) { + /** */ + public static void logError(String msg) { BrightLineFalsingManager.logError(msg); } } diff --git a/packages/SystemUI/src/com/android/systemui/classifier/brightline/PointerCountClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/brightline/PointerCountClassifier.java index b726c3e2783f..dd5d8a8f557b 100644 --- a/packages/SystemUI/src/com/android/systemui/classifier/brightline/PointerCountClassifier.java +++ b/packages/SystemUI/src/com/android/systemui/classifier/brightline/PointerCountClassifier.java @@ -21,6 +21,8 @@ import static com.android.systemui.classifier.Classifier.QUICK_SETTINGS; import android.view.MotionEvent; +import com.android.systemui.classifier.FalsingDataProvider; + import java.util.Locale; /** diff --git a/packages/SystemUI/src/com/android/systemui/classifier/brightline/ProximityClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/brightline/ProximityClassifier.java index b128678af5db..3551c241e71e 100644 --- a/packages/SystemUI/src/com/android/systemui/classifier/brightline/ProximityClassifier.java +++ b/packages/SystemUI/src/com/android/systemui/classifier/brightline/ProximityClassifier.java @@ -22,6 +22,7 @@ import static com.android.systemui.classifier.Classifier.QUICK_SETTINGS; import android.provider.DeviceConfig; import android.view.MotionEvent; +import com.android.systemui.classifier.FalsingDataProvider; import com.android.systemui.util.DeviceConfigProxy; import com.android.systemui.util.sensors.ProximitySensor; diff --git a/packages/SystemUI/src/com/android/systemui/classifier/brightline/SingleTapClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/brightline/SingleTapClassifier.java index 47708f4dd789..8c7648149e44 100644 --- a/packages/SystemUI/src/com/android/systemui/classifier/brightline/SingleTapClassifier.java +++ b/packages/SystemUI/src/com/android/systemui/classifier/brightline/SingleTapClassifier.java @@ -18,6 +18,8 @@ package com.android.systemui.classifier.brightline; import android.view.MotionEvent; +import com.android.systemui.classifier.FalsingDataProvider; + import java.util.List; /** diff --git a/packages/SystemUI/src/com/android/systemui/classifier/brightline/TimeLimitedMotionEventBuffer.java b/packages/SystemUI/src/com/android/systemui/classifier/brightline/TimeLimitedMotionEventBuffer.java index 92aa7c5b2f44..7430a1eda920 100644 --- a/packages/SystemUI/src/com/android/systemui/classifier/brightline/TimeLimitedMotionEventBuffer.java +++ b/packages/SystemUI/src/com/android/systemui/classifier/brightline/TimeLimitedMotionEventBuffer.java @@ -36,7 +36,7 @@ public class TimeLimitedMotionEventBuffer implements List<MotionEvent> { private final LinkedList<MotionEvent> mMotionEvents; private final long mMaxAgeMs; - TimeLimitedMotionEventBuffer(long maxAgeMs) { + public TimeLimitedMotionEventBuffer(long maxAgeMs) { super(); mMaxAgeMs = maxAgeMs; mMotionEvents = new LinkedList<>(); diff --git a/packages/SystemUI/src/com/android/systemui/classifier/brightline/TypeClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/brightline/TypeClassifier.java index 5f1b37ae06d9..f62871f383b3 100644 --- a/packages/SystemUI/src/com/android/systemui/classifier/brightline/TypeClassifier.java +++ b/packages/SystemUI/src/com/android/systemui/classifier/brightline/TypeClassifier.java @@ -26,6 +26,8 @@ import static com.android.systemui.classifier.Classifier.QUICK_SETTINGS; import static com.android.systemui.classifier.Classifier.RIGHT_AFFORDANCE; import static com.android.systemui.classifier.Classifier.UNLOCK; +import com.android.systemui.classifier.FalsingDataProvider; + /** * Ensure that the swipe direction generally matches that of the interaction type. */ diff --git a/packages/SystemUI/src/com/android/systemui/classifier/brightline/ZigZagClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/brightline/ZigZagClassifier.java index a796f3c6d547..9ca77d364bc4 100644 --- a/packages/SystemUI/src/com/android/systemui/classifier/brightline/ZigZagClassifier.java +++ b/packages/SystemUI/src/com/android/systemui/classifier/brightline/ZigZagClassifier.java @@ -25,6 +25,7 @@ import android.graphics.Point; import android.provider.DeviceConfig; import android.view.MotionEvent; +import com.android.systemui.classifier.FalsingDataProvider; import com.android.systemui.util.DeviceConfigProxy; import java.util.ArrayList; diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java index 780bb5b01103..4d697005be7b 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java +++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java @@ -27,6 +27,7 @@ import com.android.systemui.BootCompleteCache; import com.android.systemui.BootCompleteCacheImpl; import com.android.systemui.appops.dagger.AppOpsModule; import com.android.systemui.assist.AssistModule; +import com.android.systemui.classifier.FalsingModule; import com.android.systemui.controls.dagger.ControlsModule; import com.android.systemui.demomode.dagger.DemoModeModule; import com.android.systemui.doze.dagger.DozeComponent; @@ -89,6 +90,7 @@ import dagger.Provides; AssistModule.class, ControlsModule.class, DemoModeModule.class, + FalsingModule.class, LogModule.class, PeopleHubModule.class, PowerModule.class, diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeFalsingManagerAdapter.java b/packages/SystemUI/src/com/android/systemui/doze/DozeFalsingManagerAdapter.java index 94b8ba305d0c..ef696a88548a 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeFalsingManagerAdapter.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeFalsingManagerAdapter.java @@ -16,8 +16,8 @@ package com.android.systemui.doze; +import com.android.systemui.classifier.FalsingCollector; import com.android.systemui.doze.dagger.DozeScope; -import com.android.systemui.plugins.FalsingManager; import javax.inject.Inject; @@ -27,16 +27,16 @@ import javax.inject.Inject; @DozeScope public class DozeFalsingManagerAdapter implements DozeMachine.Part { - private final FalsingManager mFalsingManager; + private final FalsingCollector mFalsingCollector; @Inject - public DozeFalsingManagerAdapter(FalsingManager falsingManager) { - mFalsingManager = falsingManager; + public DozeFalsingManagerAdapter(FalsingCollector falsingCollector) { + mFalsingCollector = falsingCollector; } @Override public void transitionTo(DozeMachine.State oldState, DozeMachine.State newState) { - mFalsingManager.setShowingAod(isAodMode(newState)); + mFalsingCollector.setShowingAod(isAodMode(newState)); } private boolean isAodMode(DozeMachine.State state) { diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java index aea0dd0ee4b1..c6bfcbaae188 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java @@ -88,12 +88,12 @@ import com.android.systemui.Dumpable; import com.android.systemui.R; import com.android.systemui.SystemUI; import com.android.systemui.broadcast.BroadcastDispatcher; +import com.android.systemui.classifier.FalsingCollector; import com.android.systemui.dagger.qualifiers.UiBackground; import com.android.systemui.dump.DumpManager; import com.android.systemui.keyguard.KeyguardService; import com.android.systemui.keyguard.dagger.KeyguardModule; import com.android.systemui.navigationbar.NavigationModeController; -import com.android.systemui.plugins.FalsingManager; import com.android.systemui.shared.system.QuickStepContract; import com.android.systemui.statusbar.phone.BiometricUnlockController; import com.android.systemui.statusbar.phone.KeyguardBypassController; @@ -223,7 +223,7 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable { private boolean mBootSendUserPresent; private boolean mShuttingDown; private boolean mDozing; - private final FalsingManager mFalsingManager; + private final FalsingCollector mFalsingCollector; /** High level access to the power manager for WakeLocks */ private final PowerManager mPM; @@ -715,7 +715,7 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable { */ public KeyguardViewMediator( Context context, - FalsingManager falsingManager, + FalsingCollector falsingCollector, LockPatternUtils lockPatternUtils, BroadcastDispatcher broadcastDispatcher, Lazy<KeyguardViewController> statusBarKeyguardViewManagerLazy, @@ -727,7 +727,7 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable { NavigationModeController navigationModeController, KeyguardDisplayManager keyguardDisplayManager) { super(context); - mFalsingManager = falsingManager; + mFalsingCollector = falsingCollector; mLockPatternUtils = lockPatternUtils; mBroadcastDispatcher = broadcastDispatcher; mKeyguardViewControllerLazy = statusBarKeyguardViewManagerLazy; @@ -1682,7 +1682,7 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable { "KeyguardViewMediator#handleMessage START_KEYGUARD_EXIT_ANIM"); StartKeyguardExitAnimParams params = (StartKeyguardExitAnimParams) msg.obj; handleStartKeyguardExitAnimation(params.startTime, params.fadeoutDuration); - mFalsingManager.onSuccessfulUnlock(); + mFalsingCollector.onSuccessfulUnlock(); Trace.endSection(); break; case KEYGUARD_DONE_PENDING_TIMEOUT: diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java b/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java index e50fd6a96b5c..d7b5eea84c36 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java @@ -31,6 +31,8 @@ import com.android.keyguard.KeyguardUpdateMonitor; import com.android.keyguard.KeyguardViewController; import com.android.keyguard.dagger.KeyguardStatusViewComponent; import com.android.systemui.broadcast.BroadcastDispatcher; +import com.android.systemui.classifier.FalsingCollector; +import com.android.systemui.classifier.FalsingModule; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.dagger.qualifiers.UiBackground; @@ -39,7 +41,6 @@ import com.android.systemui.keyguard.DismissCallbackRegistry; import com.android.systemui.keyguard.FaceAuthScreenBrightnessController; import com.android.systemui.keyguard.KeyguardViewMediator; import com.android.systemui.navigationbar.NavigationModeController; -import com.android.systemui.plugins.FalsingManager; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.NotificationShadeWindowController; import com.android.systemui.statusbar.phone.KeyguardLiftController; @@ -59,7 +60,8 @@ import dagger.Provides; /** * Dagger Module providing {@link StatusBar}. */ -@Module(subcomponents = {KeyguardStatusViewComponent.class}) +@Module(subcomponents = {KeyguardStatusViewComponent.class}, + includes = {FalsingModule.class}) public class KeyguardModule { /** * Provides our instance of KeyguardViewMediator which is considered optional. @@ -68,7 +70,7 @@ public class KeyguardModule { @SysUISingleton public static KeyguardViewMediator newKeyguardViewMediator( Context context, - FalsingManager falsingManager, + FalsingCollector falsingCollector, LockPatternUtils lockPatternUtils, BroadcastDispatcher broadcastDispatcher, Lazy<KeyguardViewController> statusBarKeyguardViewManagerLazy, @@ -83,7 +85,7 @@ public class KeyguardModule { KeyguardDisplayManager keyguardDisplayManager) { return new KeyguardViewMediator( context, - falsingManager, + falsingCollector, lockPatternUtils, broadcastDispatcher, statusBarKeyguardViewManagerLazy, diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt index 5eb6687f0b81..935352665314 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt +++ b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt @@ -12,6 +12,7 @@ import android.view.ViewGroup import android.widget.LinearLayout import androidx.annotation.VisibleForTesting import com.android.systemui.R +import com.android.systemui.classifier.FalsingCollector import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.plugins.ActivityStarter @@ -44,6 +45,7 @@ class MediaCarouselController @Inject constructor( @Main executor: DelayableExecutor, private val mediaManager: MediaDataManager, configurationController: ConfigurationController, + falsingCollector: FalsingCollector, falsingManager: FalsingManager ) { /** @@ -156,7 +158,7 @@ class MediaCarouselController @Inject constructor( pageIndicator = mediaFrame.requireViewById(R.id.media_page_indicator) mediaCarouselScrollHandler = MediaCarouselScrollHandler(mediaCarousel, pageIndicator, executor, mediaManager::onSwipeToDismiss, this::updatePageIndicatorLocation, - this::closeGuts, falsingManager) + this::closeGuts, falsingCollector, falsingManager) isRtl = context.resources.configuration.layoutDirection == View.LAYOUT_DIRECTION_RTL inflateSettingsButton() mediaContent = mediaCarousel.requireViewById(R.id.media_carousel) diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaCarouselScrollHandler.kt b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselScrollHandler.kt index cb14f31abd16..bb6fbfab4c90 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaCarouselScrollHandler.kt +++ b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselScrollHandler.kt @@ -31,6 +31,7 @@ import com.android.systemui.Gefingerpoken import com.android.systemui.qs.PageIndicator import com.android.systemui.R import com.android.systemui.classifier.Classifier.NOTIFICATION_DISMISS +import com.android.systemui.classifier.FalsingCollector import com.android.systemui.plugins.FalsingManager import com.android.wm.shell.animation.PhysicsAnimator import com.android.systemui.util.concurrency.DelayableExecutor @@ -58,6 +59,7 @@ class MediaCarouselScrollHandler( private val dismissCallback: () -> Unit, private var translationChangedListener: () -> Unit, private val closeGuts: () -> Unit, + private val falsingCollector: FalsingCollector, private val falsingManager: FalsingManager ) { /** @@ -162,7 +164,7 @@ class MediaCarouselScrollHandler( override fun onDown(e: MotionEvent?): Boolean { if (falsingProtectionNeeded) { - falsingManager.onNotificationStartDismissing() + falsingCollector.onNotificationStartDismissing() } return false } @@ -258,7 +260,7 @@ class MediaCarouselScrollHandler( private fun onTouch(motionEvent: MotionEvent): Boolean { val isUp = motionEvent.action == MotionEvent.ACTION_UP if (isUp && falsingProtectionNeeded) { - falsingManager.onNotificationStopDismissing() + falsingCollector.onNotificationStopDismissing() } if (gestureDetector.onTouchEvent(motionEvent)) { if (isUp) { diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java index d7a2975a4b04..0f0a9a2766f1 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java @@ -134,7 +134,7 @@ public class ScreenRecordTile extends QSTileImpl<QSTile.BooleanState> getHost().collapsePanels(); Intent intent = mController.getPromptIntent(); ActivityStarter.OnDismissAction dismissAction = () -> { - mContext.startActivity(intent); + mHost.getUserContext().startActivity(intent); return false; }; mKeyguardDismissUtil.executeWhenUnlocked(dismissAction, false); diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingController.java b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingController.java index 10a44ddb17f2..7ca82774f737 100644 --- a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingController.java +++ b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingController.java @@ -54,14 +54,31 @@ public class RecordingController private CountDownTimer mCountDownTimer = null; private BroadcastDispatcher mBroadcastDispatcher; + protected static final String INTENT_UPDATE_STATE = + "com.android.systemui.screenrecord.UPDATE_STATE"; + protected static final String EXTRA_STATE = "extra_state"; + private ArrayList<RecordingStateChangeCallback> mListeners = new ArrayList<>(); @VisibleForTesting protected final BroadcastReceiver mUserChangeReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { - if (mStopIntent != null) { - stopRecording(); + stopRecording(); + } + }; + + @VisibleForTesting + protected final BroadcastReceiver mStateChangeReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + if (intent != null && INTENT_UPDATE_STATE.equals(intent.getAction())) { + if (intent.hasExtra(EXTRA_STATE)) { + boolean state = intent.getBooleanExtra(EXTRA_STATE, false); + updateState(state); + } else { + Log.e(TAG, "Received update intent with no state"); + } } } }; @@ -118,6 +135,10 @@ public class RecordingController IntentFilter userFilter = new IntentFilter(Intent.ACTION_USER_SWITCHED); mBroadcastDispatcher.registerReceiver(mUserChangeReceiver, userFilter, null, UserHandle.ALL); + + IntentFilter stateFilter = new IntentFilter(INTENT_UPDATE_STATE); + mBroadcastDispatcher.registerReceiver(mStateChangeReceiver, stateFilter, null, + UserHandle.ALL); Log.d(TAG, "sent start intent"); } catch (PendingIntent.CanceledException e) { Log.e(TAG, "Pending intent was cancelled: " + e.getMessage()); @@ -174,7 +195,6 @@ public class RecordingController } catch (PendingIntent.CanceledException e) { Log.e(TAG, "Error stopping: " + e.getMessage()); } - mBroadcastDispatcher.unregisterReceiver(mUserChangeReceiver); } /** @@ -182,6 +202,11 @@ public class RecordingController * @param isRecording */ public synchronized void updateState(boolean isRecording) { + if (!isRecording && mIsRecording) { + // Unregister receivers if we have stopped recording + mBroadcastDispatcher.unregisterReceiver(mUserChangeReceiver); + mBroadcastDispatcher.unregisterReceiver(mStateChangeReceiver); + } mIsRecording = isRecording; for (RecordingStateChangeCallback cb : mListeners) { if (isRecording) { diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java index 3bf118d1f39f..197582104f8e 100644 --- a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java +++ b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java @@ -69,6 +69,7 @@ public class RecordingService extends Service implements MediaRecorder.OnInfoLis private static final String ACTION_STOP_NOTIF = "com.android.systemui.screenrecord.STOP_FROM_NOTIF"; private static final String ACTION_SHARE = "com.android.systemui.screenrecord.SHARE"; + private static final String PERMISSION_SELF = "com.android.systemui.permission.SELF"; private final RecordingController mController; private final KeyguardDismissUtil mKeyguardDismissUtil; @@ -120,8 +121,8 @@ public class RecordingService extends Service implements MediaRecorder.OnInfoLis String action = intent.getAction(); Log.d(TAG, "onStartCommand " + action); - int mCurrentUserId = mUserContextTracker.getUserContext().getUserId(); - UserHandle currentUser = new UserHandle(mCurrentUserId); + int currentUserId = mUserContextTracker.getUserContext().getUserId(); + UserHandle currentUser = new UserHandle(currentUserId); switch (action) { case ACTION_START: mAudioSource = ScreenRecordingAudioSource @@ -137,11 +138,22 @@ public class RecordingService extends Service implements MediaRecorder.OnInfoLis mRecorder = new ScreenMediaRecorder( mUserContextTracker.getUserContext(), - mCurrentUserId, + currentUserId, mAudioSource, this ); - startRecording(); + + if (startRecording()) { + updateState(true); + createRecordingNotification(); + mUiEventLogger.log(Events.ScreenRecordEvent.SCREEN_RECORD_START); + } else { + updateState(false); + createErrorNotification(); + stopForeground(true); + stopSelf(); + return Service.START_NOT_STICKY; + } break; case ACTION_STOP_NOTIF: @@ -201,22 +213,63 @@ public class RecordingService extends Service implements MediaRecorder.OnInfoLis return mRecorder; } + private void updateState(boolean state) { + int userId = mUserContextTracker.getUserContext().getUserId(); + if (userId == UserHandle.USER_SYSTEM) { + // Main user has a reference to the correct controller, so no need to use a broadcast + mController.updateState(state); + } else { + Intent intent = new Intent(RecordingController.INTENT_UPDATE_STATE); + intent.putExtra(RecordingController.EXTRA_STATE, state); + intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); + sendBroadcast(intent, PERMISSION_SELF); + } + } + /** * Begin the recording session + * @return true if successful, false if something went wrong */ - private void startRecording() { + private boolean startRecording() { try { getRecorder().start(); - mController.updateState(true); - createRecordingNotification(); - mUiEventLogger.log(Events.ScreenRecordEvent.SCREEN_RECORD_START); - } catch (IOException | RemoteException | IllegalStateException e) { - Toast.makeText(this, - R.string.screenrecord_start_error, Toast.LENGTH_LONG) - .show(); + return true; + } catch (IOException | RemoteException | RuntimeException e) { + showErrorToast(R.string.screenrecord_start_error); e.printStackTrace(); - mController.updateState(false); } + return false; + } + + /** + * Simple error notification, needed since startForeground must be called to avoid errors + */ + @VisibleForTesting + protected void createErrorNotification() { + Resources res = getResources(); + NotificationChannel channel = new NotificationChannel( + CHANNEL_ID, + getString(R.string.screenrecord_name), + NotificationManager.IMPORTANCE_DEFAULT); + channel.setDescription(getString(R.string.screenrecord_channel_description)); + channel.enableVibration(true); + mNotificationManager.createNotificationChannel(channel); + + Bundle extras = new Bundle(); + extras.putString(Notification.EXTRA_SUBSTITUTE_APP_NAME, + res.getString(R.string.screenrecord_name)); + String notificationTitle = res.getString(R.string.screenrecord_start_error); + + Notification.Builder builder = new Notification.Builder(this, CHANNEL_ID) + .setSmallIcon(R.drawable.ic_screenrecord) + .setContentTitle(notificationTitle) + .addExtras(extras); + startForeground(NOTIFICATION_RECORDING_ID, builder.build()); + } + + @VisibleForTesting + protected void showErrorToast(int stringId) { + Toast.makeText(this, stringId, Toast.LENGTH_LONG).show(); } @VisibleForTesting @@ -247,6 +300,7 @@ public class RecordingService extends Service implements MediaRecorder.OnInfoLis .setColorized(true) .setColor(getResources().getColor(R.color.GM2_red_700)) .setOngoing(true) + .setShowForegroundImmediately(true) .setContentIntent( PendingIntent.getService(this, REQUEST_CODE, stopIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE)) @@ -326,7 +380,7 @@ public class RecordingService extends Service implements MediaRecorder.OnInfoLis } else { Log.e(TAG, "stopRecording called, but recorder was null"); } - mController.updateState(false); + updateState(false); } private void saveRecording(int userId) { @@ -344,8 +398,7 @@ public class RecordingService extends Service implements MediaRecorder.OnInfoLis } } catch (IOException e) { Log.e(TAG, "Error saving screen recording: " + e.getMessage()); - Toast.makeText(this, R.string.screenrecord_delete_error, Toast.LENGTH_LONG) - .show(); + showErrorToast(R.string.screenrecord_delete_error); } finally { mNotificationManager.cancelAsUser(null, NOTIFICATION_PROCESSING_ID, currentUser); } diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenMediaRecorder.java b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenMediaRecorder.java index 45564b0bfa6b..9037192e2ddc 100644 --- a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenMediaRecorder.java +++ b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenMediaRecorder.java @@ -94,7 +94,7 @@ public class ScreenMediaRecorder { mAudioSource = audioSource; } - private void prepare() throws IOException, RemoteException { + private void prepare() throws IOException, RemoteException, RuntimeException { //Setup media projection IBinder b = ServiceManager.getService(MEDIA_PROJECTION_SERVICE); IMediaProjectionManager mediaService = @@ -257,7 +257,7 @@ public class ScreenMediaRecorder { /** * Start screen recording */ - void start() throws IOException, RemoteException, IllegalStateException { + void start() throws IOException, RemoteException, RuntimeException { Log.d(TAG, "start recording"); prepare(); mMediaRecorder.start(); diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java b/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java index 672f82c2a583..2c82bcb24ad0 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java @@ -43,6 +43,7 @@ import android.view.WindowManager; import com.android.internal.logging.UiEventLogger; import com.android.internal.util.ScreenshotHelper; +import com.android.systemui.R; import com.android.systemui.shared.recents.utilities.BitmapUtil; import java.util.function.Consumer; @@ -55,6 +56,7 @@ public class TakeScreenshotService extends Service { private final ScreenshotController mScreenshot; private final UserManager mUserManager; private final UiEventLogger mUiEventLogger; + private final ScreenshotNotificationsController mNotificationsController; private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { @@ -90,6 +92,8 @@ public class TakeScreenshotService extends Service { // animation and error notification. if (!mUserManager.isUserUnlocked()) { Log.w(TAG, "Skipping screenshot because storage is locked!"); + mNotificationsController.notifyScreenshotError( + R.string.screenshot_failed_to_save_user_locked_text); post(() -> uriConsumer.accept(null)); post(onComplete); return; @@ -125,11 +129,15 @@ public class TakeScreenshotService extends Service { }; @Inject - public TakeScreenshotService(ScreenshotController screenshotController, UserManager userManager, - UiEventLogger uiEventLogger) { + public TakeScreenshotService( + ScreenshotController screenshotController, + UserManager userManager, + UiEventLogger uiEventLogger, + ScreenshotNotificationsController notificationsController) { mScreenshot = screenshotController; mUserManager = userManager; mUiEventLogger = uiEventLogger; + mNotificationsController = notificationsController; } @Override diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/DragDownHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/DragDownHelper.java index e61e05a7dc2f..7ef88bb0c2c8 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/DragDownHelper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/DragDownHelper.java @@ -31,6 +31,7 @@ import com.android.systemui.ExpandHelper; import com.android.systemui.Gefingerpoken; import com.android.systemui.Interpolators; import com.android.systemui.R; +import com.android.systemui.classifier.FalsingCollector; import com.android.systemui.plugins.FalsingManager; import com.android.systemui.statusbar.notification.row.ExpandableView; @@ -46,6 +47,7 @@ public class DragDownHelper implements Gefingerpoken { private static final int SPRING_BACK_ANIMATION_LENGTH_MS = 375; private int mMinDragDistance; + private final FalsingManager mFalsingManager; private ExpandHelper.Callback mCallback; private float mInitialTouchX; private float mInitialTouchY; @@ -58,20 +60,21 @@ public class DragDownHelper implements Gefingerpoken { private boolean mDraggedFarEnough; private ExpandableView mStartingChild; private float mLastHeight; - private FalsingManager mFalsingManager; + private FalsingCollector mFalsingCollector; public DragDownHelper(Context context, View host, ExpandHelper.Callback callback, - DragDownCallback dragDownCallback, - FalsingManager falsingManager) { + DragDownCallback dragDownCallback, FalsingManager falsingManager, + FalsingCollector falsingCollector) { mMinDragDistance = context.getResources().getDimensionPixelSize( R.dimen.keyguard_drag_down_min_distance); + mFalsingManager = falsingManager; final ViewConfiguration configuration = ViewConfiguration.get(context); mTouchSlop = configuration.getScaledTouchSlop(); mSlopMultiplier = configuration.getScaledAmbiguousGestureMultiplier(); mCallback = callback; mDragDownCallback = dragDownCallback; mHost = host; - mFalsingManager = falsingManager; + mFalsingCollector = falsingCollector; } @Override @@ -96,7 +99,7 @@ public class DragDownHelper implements Gefingerpoken { ? mTouchSlop * mSlopMultiplier : mTouchSlop; if (h > touchSlop && h > Math.abs(x - mInitialTouchX)) { - mFalsingManager.onNotificatonStartDraggingDown(); + mFalsingCollector.onNotificationStartDraggingDown(); mDraggingDown = true; captureStartingChild(mInitialTouchX, mInitialTouchY); mInitialTouchY = y; @@ -229,7 +232,7 @@ public class DragDownHelper implements Gefingerpoken { } private void stopDragging() { - mFalsingManager.onNotificatonStopDraggingDown(); + mFalsingCollector.onNotificationStopDraggingDown(); if (mStartingChild != null) { cancelExpansion(mStartingChild); mStartingChild = null; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt b/packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt index 6fa3633acc43..b7343f67a86d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt @@ -31,6 +31,7 @@ import com.android.systemui.Gefingerpoken import com.android.systemui.Interpolators import com.android.systemui.R import com.android.systemui.classifier.Classifier.NOTIFICATION_DRAG_DOWN +import com.android.systemui.classifier.FalsingCollector import com.android.systemui.dagger.SysUISingleton import com.android.systemui.plugins.FalsingManager import com.android.systemui.plugins.statusbar.StatusBarStateController @@ -57,7 +58,8 @@ constructor( private val headsUpManager: HeadsUpManagerPhone, private val roundnessManager: NotificationRoundnessManager, private val statusBarStateController: StatusBarStateController, - private val falsingManager: FalsingManager + private val falsingManager: FalsingManager, + private val falsingCollector: FalsingCollector ) : Gefingerpoken { companion object { private val RUBBERBAND_FACTOR_STATIC = 0.25f @@ -148,7 +150,7 @@ constructor( MotionEvent.ACTION_MOVE -> { val h = y - mInitialTouchY if (h > mTouchSlop && h > Math.abs(x - mInitialTouchX)) { - falsingManager.onStartExpandingFromPulse() + falsingCollector.onStartExpandingFromPulse() isExpanding = true captureStartingChild(mInitialTouchX, mInitialTouchY) mInitialTouchY = y @@ -301,7 +303,7 @@ constructor( private fun cancelExpansion() { isExpanding = false - falsingManager.onExpansionFromPulseStopped() + falsingCollector.onExpansionFromPulseStopped() if (mStartingChild != null) { reset(mStartingChild!!) mStartingChild = null diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewController.java index 0b79387fac77..50bbc38eddf3 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewController.java @@ -22,6 +22,7 @@ import android.view.View; import android.view.accessibility.AccessibilityManager; import com.android.systemui.Gefingerpoken; +import com.android.systemui.classifier.FalsingCollector; import com.android.systemui.plugins.FalsingManager; import com.android.systemui.statusbar.phone.NotificationTapHelper; import com.android.systemui.util.ViewController; @@ -36,6 +37,7 @@ public class ActivatableNotificationViewController private final ExpandableOutlineViewController mExpandableOutlineViewController; private final AccessibilityManager mAccessibilityManager; private final FalsingManager mFalsingManager; + private final FalsingCollector mFalsingCollector; private final NotificationTapHelper mNotificationTapHelper; private final TouchHandler mTouchHandler = new TouchHandler(); @@ -45,17 +47,19 @@ public class ActivatableNotificationViewController public ActivatableNotificationViewController(ActivatableNotificationView view, NotificationTapHelper.Factory notificationTapHelpFactory, ExpandableOutlineViewController expandableOutlineViewController, - AccessibilityManager accessibilityManager, FalsingManager falsingManager) { + AccessibilityManager accessibilityManager, FalsingManager falsingManager, + FalsingCollector falsingCollector) { super(view); mExpandableOutlineViewController = expandableOutlineViewController; mAccessibilityManager = accessibilityManager; mFalsingManager = falsingManager; + mFalsingCollector = falsingCollector; mNotificationTapHelper = notificationTapHelpFactory.create( (active) -> { if (active) { mView.makeActive(); - mFalsingManager.onNotificationActive(); + mFalsingCollector.onNotificationActive(); } else { mView.makeInactive(true /* animate */); } @@ -64,7 +68,7 @@ public class ActivatableNotificationViewController mView.setOnActivatedListener(new ActivatableNotificationView.OnActivatedListener() { @Override public void onActivated(ActivatableNotificationView view) { - mFalsingManager.onNotificationActive(); + mFalsingCollector.onNotificationActive(); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java index 5682c88edc63..5ed17f1ee07f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java @@ -43,7 +43,6 @@ import android.graphics.drawable.Drawable; import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; -import android.provider.Settings; import android.service.notification.StatusBarNotification; import android.util.ArraySet; import android.util.AttributeSet; @@ -74,7 +73,7 @@ import com.android.internal.widget.MessagingLayout; import com.android.systemui.Dependency; import com.android.systemui.Interpolators; import com.android.systemui.R; -import com.android.systemui.plugins.FalsingManager; +import com.android.systemui.classifier.FalsingCollector; import com.android.systemui.plugins.PluginListener; import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin; import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin.MenuItem; @@ -213,7 +212,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView private NotificationGuts mGuts; private NotificationEntry mEntry; private String mAppName; - private FalsingManager mFalsingManager; + private FalsingCollector mFalsingCollector; /** * Whether or not the notification is using the heads up view and should peek from the top. @@ -1584,7 +1583,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView OnExpandClickListener onExpandClickListener, NotificationMediaManager notificationMediaManager, CoordinateOnClickListener onFeedbackClickListener, - FalsingManager falsingManager, + FalsingCollector falsingCollector, StatusBarStateController statusBarStateController, PeopleNotificationIdentifier peopleNotificationIdentifier, OnUserInteractionCallback onUserInteractionCallback, @@ -1609,7 +1608,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView mOnExpandClickListener = onExpandClickListener; mMediaManager = notificationMediaManager; setOnFeedbackClickListener(onFeedbackClickListener); - mFalsingManager = falsingManager; + mFalsingCollector = falsingCollector; mStatusBarStateController = statusBarStateController; mPeopleNotificationIdentifier = peopleNotificationIdentifier; @@ -2176,7 +2175,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView * @param allowChildExpansion whether a call to this method allows expanding children */ public void setUserExpanded(boolean userExpanded, boolean allowChildExpansion) { - mFalsingManager.setNotificationExpanded(); + mFalsingCollector.setNotificationExpanded(); if (mIsSummaryWithChildren && !shouldShowPublic() && allowChildExpansion && !mChildrenContainer.showingAsLowPriority()) { final boolean wasExpanded = mGroupExpansionManager.isGroupExpanded(mEntry); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java index cb2af54a25cb..0d0e97eae519 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java @@ -25,7 +25,7 @@ import android.view.ViewGroup; import androidx.annotation.NonNull; -import com.android.systemui.plugins.FalsingManager; +import com.android.systemui.classifier.FalsingCollector; import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.shared.plugins.PluginManager; @@ -78,7 +78,7 @@ public class ExpandableNotificationRowController implements NodeController { private final ExpandableNotificationRow.CoordinateOnClickListener mOnFeedbackClickListener; private final NotificationGutsManager mNotificationGutsManager; private final OnUserInteractionCallback mOnUserInteractionCallback; - private final FalsingManager mFalsingManager; + private final FalsingCollector mFalsingCollector; private final boolean mAllowLongPress; private final PeopleNotificationIdentifier mPeopleNotificationIdentifier; private final Optional<BubblesManager> mBubblesManagerOptional; @@ -104,7 +104,7 @@ public class ExpandableNotificationRowController implements NodeController { NotificationGutsManager notificationGutsManager, @Named(ALLOW_NOTIFICATION_LONG_PRESS_NAME) boolean allowLongPress, OnUserInteractionCallback onUserInteractionCallback, - FalsingManager falsingManager, + FalsingCollector falsingCollector, PeopleNotificationIdentifier peopleNotificationIdentifier, Optional<BubblesManager> bubblesManagerOptional) { mView = view; @@ -127,7 +127,7 @@ public class ExpandableNotificationRowController implements NodeController { mOnUserInteractionCallback = onUserInteractionCallback; mOnFeedbackClickListener = mNotificationGutsManager::openGuts; mAllowLongPress = allowLongPress; - mFalsingManager = falsingManager; + mFalsingCollector = falsingCollector; mPeopleNotificationIdentifier = peopleNotificationIdentifier; mBubblesManagerOptional = bubblesManagerOptional; } @@ -150,7 +150,7 @@ public class ExpandableNotificationRowController implements NodeController { mOnExpandClickListener, mMediaManager, mOnFeedbackClickListener, - mFalsingManager, + mFalsingCollector, mStatusBarStateController, mPeopleNotificationIdentifier, mOnUserInteractionCallback, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java index 885048df13f1..ac3b6d26fab6 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java @@ -82,9 +82,6 @@ public class AmbientState { private ExpandableNotificationRow mTrackedHeadsUpRow; private float mAppearFraction; - /** Tracks the state from AlertingNotificationManager#hasNotifications() */ - private boolean mHasAlertEntries; - public AmbientState( Context context, @NonNull SectionProvider sectionProvider) { @@ -368,21 +365,10 @@ public class AmbientState { mPanelTracking = panelTracking; } - public boolean hasPulsingNotifications() { - return mPulsing && mHasAlertEntries; - } - public void setPulsing(boolean hasPulsing) { mPulsing = hasPulsing; } - /** - * @return if we're pulsing in general - */ - public boolean isPulsing() { - return mPulsing; - } - public boolean isPulsing(NotificationEntry entry) { return mPulsing && entry.isAlerting(); } @@ -541,8 +527,4 @@ public class AmbientState { public float getAppearFraction() { return mAppearFraction; } - - public void setHasAlertEntries(boolean hasAlertEntries) { - mHasAlertEntries = hasAlertEntries; - } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSection.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSection.java index 1131a65abe93..ba03a50b0ba5 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSection.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSection.java @@ -31,175 +31,22 @@ import com.android.systemui.statusbar.notification.ShadeViewRefactor; import com.android.systemui.statusbar.notification.row.ExpandableView; /** - * Represents the bounds of a section of the notification shade and handles animation when the - * bounds change. + * Represents the priority of a notification section and tracks first and last visible children. */ public class NotificationSection { private @PriorityBucket int mBucket; - private View mOwningView; - private Rect mBounds = new Rect(); - private Rect mCurrentBounds = new Rect(-1, -1, -1, -1); - private Rect mStartAnimationRect = new Rect(); - private Rect mEndAnimationRect = new Rect(); - private ObjectAnimator mTopAnimator = null; - private ObjectAnimator mBottomAnimator = null; private ExpandableView mFirstVisibleChild; private ExpandableView mLastVisibleChild; - NotificationSection(View owningView, @PriorityBucket int bucket) { - mOwningView = owningView; + NotificationSection(@PriorityBucket int bucket) { mBucket = bucket; } - public void cancelAnimators() { - if (mBottomAnimator != null) { - mBottomAnimator.cancel(); - } - if (mTopAnimator != null) { - mTopAnimator.cancel(); - } - } - - public Rect getCurrentBounds() { - return mCurrentBounds; - } - - public Rect getBounds() { - return mBounds; - } - - public boolean didBoundsChange() { - return !mCurrentBounds.equals(mBounds); - } - - public boolean areBoundsAnimating() { - return mBottomAnimator != null || mTopAnimator != null; - } - @PriorityBucket public int getBucket() { return mBucket; } - public void startBackgroundAnimation(boolean animateTop, boolean animateBottom) { - // Left and right bounds are always applied immediately. - mCurrentBounds.left = mBounds.left; - mCurrentBounds.right = mBounds.right; - startBottomAnimation(animateBottom); - startTopAnimation(animateTop); - } - - - @ShadeViewRefactor(ShadeViewRefactor.RefactorComponent.STATE_RESOLVER) - private void startTopAnimation(boolean animate) { - int previousEndValue = mEndAnimationRect.top; - int newEndValue = mBounds.top; - ObjectAnimator previousAnimator = mTopAnimator; - if (previousAnimator != null && previousEndValue == newEndValue) { - return; - } - if (!animate) { - // just a local update was performed - if (previousAnimator != null) { - // we need to increase all animation keyframes of the previous animator by the - // relative change to the end value - int previousStartValue = mStartAnimationRect.top; - PropertyValuesHolder[] values = previousAnimator.getValues(); - values[0].setIntValues(previousStartValue, newEndValue); - mStartAnimationRect.top = previousStartValue; - mEndAnimationRect.top = newEndValue; - previousAnimator.setCurrentPlayTime(previousAnimator.getCurrentPlayTime()); - return; - } else { - // no new animation needed, let's just apply the value - setBackgroundTop(newEndValue); - return; - } - } - if (previousAnimator != null) { - previousAnimator.cancel(); - } - ObjectAnimator animator = ObjectAnimator.ofInt(this, "backgroundTop", - mCurrentBounds.top, newEndValue); - Interpolator interpolator = Interpolators.FAST_OUT_SLOW_IN; - animator.setInterpolator(interpolator); - animator.setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD); - // remove the tag when the animation is finished - animator.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - mStartAnimationRect.top = -1; - mEndAnimationRect.top = -1; - mTopAnimator = null; - } - }); - animator.start(); - mStartAnimationRect.top = mCurrentBounds.top; - mEndAnimationRect.top = newEndValue; - mTopAnimator = animator; - } - - @ShadeViewRefactor(ShadeViewRefactor.RefactorComponent.STATE_RESOLVER) - private void startBottomAnimation(boolean animate) { - int previousStartValue = mStartAnimationRect.bottom; - int previousEndValue = mEndAnimationRect.bottom; - int newEndValue = mBounds.bottom; - ObjectAnimator previousAnimator = mBottomAnimator; - if (previousAnimator != null && previousEndValue == newEndValue) { - return; - } - if (!animate) { - // just a local update was performed - if (previousAnimator != null) { - // we need to increase all animation keyframes of the previous animator by the - // relative change to the end value - PropertyValuesHolder[] values = previousAnimator.getValues(); - values[0].setIntValues(previousStartValue, newEndValue); - mStartAnimationRect.bottom = previousStartValue; - mEndAnimationRect.bottom = newEndValue; - previousAnimator.setCurrentPlayTime(previousAnimator.getCurrentPlayTime()); - return; - } else { - // no new animation needed, let's just apply the value - setBackgroundBottom(newEndValue); - return; - } - } - if (previousAnimator != null) { - previousAnimator.cancel(); - } - ObjectAnimator animator = ObjectAnimator.ofInt(this, "backgroundBottom", - mCurrentBounds.bottom, newEndValue); - Interpolator interpolator = Interpolators.FAST_OUT_SLOW_IN; - animator.setInterpolator(interpolator); - animator.setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD); - // remove the tag when the animation is finished - animator.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - mStartAnimationRect.bottom = -1; - mEndAnimationRect.bottom = -1; - mBottomAnimator = null; - } - }); - animator.start(); - mStartAnimationRect.bottom = mCurrentBounds.bottom; - mEndAnimationRect.bottom = newEndValue; - mBottomAnimator = animator; - } - - @ShadeViewRefactor(ShadeViewRefactor.RefactorComponent.SHADE_VIEW) - private void setBackgroundTop(int top) { - mCurrentBounds.top = top; - mOwningView.invalidate(); - } - - @ShadeViewRefactor(ShadeViewRefactor.RefactorComponent.SHADE_VIEW) - private void setBackgroundBottom(int bottom) { - mCurrentBounds.bottom = bottom; - mOwningView.invalidate(); - } - public ExpandableView getFirstVisibleChild() { return mFirstVisibleChild; } @@ -219,93 +66,4 @@ public class NotificationSection { mLastVisibleChild = child; return changed; } - - public void resetCurrentBounds() { - mCurrentBounds.set(mBounds); - } - - /** - * Returns true if {@code top} is equal to the top of this section (if not currently animating) - * or where the top of this section will be when animation completes. - */ - public boolean isTargetTop(int top) { - return (mTopAnimator == null && mCurrentBounds.top == top) - || (mTopAnimator != null && mEndAnimationRect.top == top); - } - - /** - * Returns true if {@code bottom} is equal to the bottom of this section (if not currently - * animating) or where the bottom of this section will be when animation completes. - */ - public boolean isTargetBottom(int bottom) { - return (mBottomAnimator == null && mCurrentBounds.bottom == bottom) - || (mBottomAnimator != null && mEndAnimationRect.bottom == bottom); - } - - /** - * Update the bounds of this section based on it's views - * - * @param minTopPosition the minimum position that the top needs to have - * @param minBottomPosition the minimum position that the bottom needs to have - * @return the position of the new bottom - */ - public int updateBounds(int minTopPosition, int minBottomPosition, - boolean shiftBackgroundWithFirst) { - int top = minTopPosition; - int bottom = minTopPosition; - ExpandableView firstView = getFirstVisibleChild(); - if (firstView != null) { - // Round Y up to avoid seeing the background during animation - int finalTranslationY = (int) Math.ceil(ViewState.getFinalTranslationY(firstView)); - // TODO: look into the already animating part - int newTop; - if (isTargetTop(finalTranslationY)) { - // we're ending up at the same location as we are now, let's just skip the - // animation - newTop = finalTranslationY; - } else { - newTop = (int) Math.ceil(firstView.getTranslationY()); - } - top = Math.max(newTop, top); - if (firstView.showingPulsing()) { - // If we're pulsing, the notification can actually go below! - bottom = Math.max(bottom, finalTranslationY - + ExpandableViewState.getFinalActualHeight(firstView)); - if (shiftBackgroundWithFirst) { - mBounds.left += Math.max(firstView.getTranslation(), 0); - mBounds.right += Math.min(firstView.getTranslation(), 0); - } - } - } - top = Math.max(minTopPosition, top); - ExpandableView lastView = getLastVisibleChild(); - if (lastView != null) { - float finalTranslationY = ViewState.getFinalTranslationY(lastView); - int finalHeight = ExpandableViewState.getFinalActualHeight(lastView); - // Round Y down to avoid seeing the background during animation - int finalBottom = (int) Math.floor( - finalTranslationY + finalHeight - lastView.getClipBottomAmount()); - int newBottom; - if (isTargetBottom(finalBottom)) { - // we're ending up at the same location as we are now, lets just skip the animation - newBottom = finalBottom; - } else { - newBottom = (int) (lastView.getTranslationY() + lastView.getActualHeight() - - lastView.getClipBottomAmount()); - // The background can never be lower than the end of the last view - minBottomPosition = (int) Math.min( - lastView.getTranslationY() + lastView.getActualHeight(), - minBottomPosition); - } - bottom = Math.max(bottom, Math.max(newBottom, minBottomPosition)); - } - bottom = Math.max(top, bottom); - mBounds.top = top; - mBounds.bottom = bottom; - return bottom; - } - - public boolean needsBackground() { - return mFirstVisibleChild != null && mBucket != BUCKET_MEDIA_CONTROLS; - } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt index 4f7e14ba4a4c..36c5419b7399 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt @@ -126,7 +126,7 @@ class NotificationSectionsManager @Inject internal constructor( fun createSectionsForBuckets(): Array<NotificationSection> = sectionsFeatureManager.getNotificationBuckets() - .map { NotificationSection(parent, it) } + .map { NotificationSection(it) } .toTypedArray() /** diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java index 742e517e71e7..ba5f95e9c4d8 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java @@ -38,12 +38,9 @@ import android.content.Intent; import android.content.res.Configuration; import android.content.res.Resources; import android.graphics.Canvas; -import android.graphics.Color; import android.graphics.Outline; import android.graphics.Paint; import android.graphics.PointF; -import android.graphics.PorterDuff; -import android.graphics.PorterDuffXfermode; import android.graphics.Rect; import android.os.Bundle; import android.os.UserHandle; @@ -73,7 +70,6 @@ import android.widget.OverScroller; import android.widget.ScrollView; import com.android.internal.annotations.VisibleForTesting; -import com.android.internal.graphics.ColorUtils; import com.android.internal.jank.InteractionJankMonitor; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.keyguard.KeyguardSliceView; @@ -158,8 +154,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable private ExpandHelper mExpandHelper; private NotificationSwipeHelper mSwipeHelper; private int mCurrentStackHeight = Integer.MAX_VALUE; - private final Paint mBackgroundPaint = new Paint(); - private final boolean mShouldDrawNotificationBackground; private boolean mHighPriorityBeforeSpeedBump; private boolean mDismissRtl; @@ -258,7 +252,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable protected FooterView mFooterView; protected EmptyShadeView mEmptyShadeView; private boolean mDismissAllInProgress; - private boolean mFadeNotificationsOnDismiss; private FooterDismissListener mFooterDismissListener; private boolean mFlingAfterUpEvent; @@ -328,10 +321,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable } }; private NotificationSection[] mSections; - private boolean mAnimateNextBackgroundTop; - private boolean mAnimateNextBackgroundBottom; - private boolean mAnimateNextSectionBoundsChange; - private int mBgColor; private float mDimAmount; private ValueAnimator mDimAnimator; private ArrayList<ExpandableView> mTmpSortedChildren = new ArrayList<>(); @@ -342,25 +331,14 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable } }; private ValueAnimator.AnimatorUpdateListener mDimUpdateListener - = new ValueAnimator.AnimatorUpdateListener() { - - @Override - public void onAnimationUpdate(ValueAnimator animation) { - setDimAmount((Float) animation.getAnimatedValue()); - } - }; + = animation -> setDimAmount((Float) animation.getAnimatedValue()); protected ViewGroup mQsContainer; private boolean mContinuousShadowUpdate; - private boolean mContinuousBackgroundUpdate; private ViewTreeObserver.OnPreDrawListener mShadowUpdater = () -> { updateViewShadows(); return true; }; - private ViewTreeObserver.OnPreDrawListener mBackgroundUpdater = () -> { - updateBackground(); - return true; - }; private Comparator<ExpandableView> mViewPositionComparator = (view, otherView) -> { float endY = view.getTranslationY() + view.getActualHeight(); float otherEndY = otherView.getTranslationY() + otherView.getActualHeight(); @@ -379,7 +357,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable if (mAmbientState.isHiddenAtAll()) { float xProgress = mHideXInterpolator.getInterpolation( (1 - mLinearHideAmount) * mBackgroundXFactor); - outline.setRoundRect(mBackgroundAnimationRect, + outline.setRoundRect(mOutlineAnimationRect, MathUtils.lerp(mCornerRadius / 2.0f, mCornerRadius, xProgress)); outline.setAlpha(1.0f - mAmbientState.getHideAmount()); @@ -388,7 +366,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable } } }; - private PorterDuffXfermode mSrcMode = new PorterDuffXfermode(PorterDuff.Mode.SRC); private boolean mPulsing; private boolean mScrollable; private View mForcedScroll; @@ -422,7 +399,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable private boolean mInHeadsUpPinnedMode; private boolean mHeadsUpAnimatingAway; private int mStatusBarState; - private int mCachedBackgroundColor; private boolean mHeadsUpGoingAwayAnimationsAllowed = true; private Runnable mReflingAndAnimateScroll = () -> { if (ANCHOR_SCROLLING) { @@ -432,7 +408,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable }; private int mCornerRadius; private int mSidePaddings; - private final Rect mBackgroundAnimationRect = new Rect(); + private final Rect mOutlineAnimationRect = new Rect(); private ArrayList<BiConsumer<Float, Float>> mExpandedHeightListeners = new ArrayList<>(); private int mHeadsUpInset; private HeadsUpAppearanceController mHeadsUpAppearanceController; @@ -452,7 +428,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable private final NotificationSectionsManager mSectionsManager; private ForegroundServiceDungeonView mFgsSectionView; - private boolean mAnimateBottomOnLayout; private float mLastSentAppear; private float mLastSentExpandedHeight; private boolean mWillExpand; @@ -463,7 +438,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable private boolean mKeyguardMediaControllorVisible; private NotificationEntry mTopHeadsUpEntry; - private long mNumHeadsUp; private NotificationStackScrollLayoutController.TouchHandler mTouchHandler; private final ExpandableView.OnHeightChangedListener mOnChildHeightChangedListener = @@ -530,7 +504,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable mSections = mSectionsManager.createSectionsForBuckets(); mAmbientState = new AmbientState(context, mSectionsManager); - mBgColor = context.getColor(R.color.notification_shade_background_color); int minHeight = res.getDimensionPixelSize(R.dimen.notification_min_height); int maxHeight = res.getDimensionPixelSize(R.dimen.notification_max_height); mExpandHelper = new ExpandHelper(getContext(), mExpandHelperCallback, @@ -539,13 +512,9 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable mExpandHelper.setScrollAdapter(mScrollAdapter); mStackScrollAlgorithm = createStackScrollAlgorithm(context); - mShouldDrawNotificationBackground = - res.getBoolean(R.bool.config_drawNotificationBackground); setOutlineProvider(mOutlineProvider); - boolean willDraw = mShouldDrawNotificationBackground || DEBUG; - setWillNotDraw(!willDraw); - mBackgroundPaint.setAntiAlias(true); + setWillNotDraw(!DEBUG); if (DEBUG) { mDebugPaint = new Paint(); mDebugPaint.setColor(0xffff0000); @@ -590,7 +559,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable * @return the height at which we will wake up when pulsing */ public float getWakeUpHeight() { - ExpandableView firstChild = getFirstChildWithBackground(); + ExpandableView firstChild = getFirstExpandableView(); if (firstChild != null) { if (mKeyguardBypassEnabledProvider.getBypassEnabled()) { return firstChild.getHeadsUpHeightWithoutHeader(); @@ -641,22 +610,11 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable } void updateBgColor() { - mBgColor = mContext.getColor(R.color.notification_shade_background_color); - updateBackgroundDimming(); mShelf.onUiModeChanged(); } @ShadeViewRefactor(RefactorComponent.DECORATOR) protected void onDraw(Canvas canvas) { - if (mShouldDrawNotificationBackground - && (mSections[0].getCurrentBounds().top - < mSections[mSections.length - 1].getCurrentBounds().bottom - || mAmbientState.isDozing())) { - drawBackground(canvas); - } else if (mInHeadsUpPinnedMode || mHeadsUpAnimatingAway) { - drawHeadsUpBackground(canvas); - } - if (DEBUG) { int y = mTopPadding; canvas.drawLine(0, y, getWidth(), y, mDebugPaint); @@ -691,160 +649,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable } } - @ShadeViewRefactor(RefactorComponent.DECORATOR) - private void drawBackground(Canvas canvas) { - int lockScreenLeft = mSidePaddings; - int lockScreenRight = getWidth() - mSidePaddings; - int lockScreenTop = mSections[0].getCurrentBounds().top; - int lockScreenBottom = mSections[mSections.length - 1].getCurrentBounds().bottom; - int hiddenLeft = getWidth() / 2; - int hiddenTop = mTopPadding; - - float yProgress = 1 - mInterpolatedHideAmount; - float xProgress = mHideXInterpolator.getInterpolation( - (1 - mLinearHideAmount) * mBackgroundXFactor); - - int left = (int) MathUtils.lerp(hiddenLeft, lockScreenLeft, xProgress); - int right = (int) MathUtils.lerp(hiddenLeft, lockScreenRight, xProgress); - int top = (int) MathUtils.lerp(hiddenTop, lockScreenTop, yProgress); - int bottom = (int) MathUtils.lerp(hiddenTop, lockScreenBottom, yProgress); - mBackgroundAnimationRect.set( - left, - top, - right, - bottom); - - int backgroundTopAnimationOffset = top - lockScreenTop; - // TODO(kprevas): this may not be necessary any more since we don't display the shelf in AOD - boolean anySectionHasVisibleChild = false; - for (NotificationSection section : mSections) { - if (section.needsBackground()) { - anySectionHasVisibleChild = true; - break; - } - } - boolean shouldDrawBackground; - if (mKeyguardBypassEnabledProvider.getBypassEnabled() && onKeyguard()) { - shouldDrawBackground = isPulseExpanding(); - } else { - shouldDrawBackground = !mAmbientState.isDozing() || anySectionHasVisibleChild; - } - if (shouldDrawBackground) { - drawBackgroundRects(canvas, left, right, top, backgroundTopAnimationOffset); - } - - updateClipping(); - } - - /** - * Draws round rects for each background section. - * - * We want to draw a round rect for each background section as defined by {@link #mSections}. - * However, if two sections are directly adjacent with no gap between them (e.g. on the - * lockscreen where the shelf can appear directly below the high priority section, or while - * scrolling the shade so that the top of the shelf is right at the bottom of the high priority - * section), we don't want to round the adjacent corners. - * - * Since {@link Canvas} doesn't provide a way to draw a half-rounded rect, this means that we - * need to coalesce the backgrounds for adjacent sections and draw them as a single round rect. - * This method tracks the top of each rect we need to draw, then iterates through the visible - * sections. If a section is not adjacent to the previous section, we draw the previous rect - * behind the sections we've accumulated up to that point, then start a new rect at the top of - * the current section. When we're done iterating we will always have one rect left to draw. - */ - private void drawBackgroundRects(Canvas canvas, int left, int right, int top, - int animationYOffset) { - int backgroundRectTop = top; - int lastSectionBottom = - mSections[0].getCurrentBounds().bottom + animationYOffset; - int currentLeft = left; - int currentRight = right; - boolean first = true; - for (NotificationSection section : mSections) { - if (!section.needsBackground()) { - continue; - } - int sectionTop = section.getCurrentBounds().top + animationYOffset; - int ownLeft = Math.min(Math.max(left, section.getCurrentBounds().left), right); - int ownRight = Math.max(Math.min(right, section.getCurrentBounds().right), ownLeft); - // If sections are directly adjacent to each other, we don't want to draw them - // as separate roundrects, as the rounded corners right next to each other look - // bad. - if (sectionTop - lastSectionBottom > DISTANCE_BETWEEN_ADJACENT_SECTIONS_PX - || ((currentLeft != ownLeft || currentRight != ownRight) && !first)) { - canvas.drawRoundRect(currentLeft, - backgroundRectTop, - currentRight, - lastSectionBottom, - mCornerRadius, mCornerRadius, mBackgroundPaint); - backgroundRectTop = sectionTop; - } - currentLeft = ownLeft; - currentRight = ownRight; - lastSectionBottom = - section.getCurrentBounds().bottom + animationYOffset; - first = false; - } - canvas.drawRoundRect(currentLeft, - backgroundRectTop, - currentRight, - lastSectionBottom, - mCornerRadius, mCornerRadius, mBackgroundPaint); - } - - private void drawHeadsUpBackground(Canvas canvas) { - int left = mSidePaddings; - int right = getWidth() - mSidePaddings; - - float top = getHeight(); - float bottom = 0; - int childCount = getChildCount(); - for (int i = 0; i < childCount; i++) { - View child = getChildAt(i); - if (child.getVisibility() != View.GONE - && child instanceof ExpandableNotificationRow) { - ExpandableNotificationRow row = (ExpandableNotificationRow) child; - if ((row.isPinned() || row.isHeadsUpAnimatingAway()) && row.getTranslation() < 0 - && row.getProvider().shouldShowGutsOnSnapOpen()) { - top = Math.min(top, row.getTranslationY()); - bottom = Math.max(bottom, row.getTranslationY() + row.getActualHeight()); - } - } - } - - if (top < bottom) { - canvas.drawRoundRect( - left, top, right, bottom, - mCornerRadius, mCornerRadius, mBackgroundPaint); - } - } - - @ShadeViewRefactor(RefactorComponent.SHADE_VIEW) - void updateBackgroundDimming() { - // No need to update the background color if it's not being drawn. - if (!mShouldDrawNotificationBackground) { - return; - } - final boolean newFlowHideShelf = Settings.Global.getInt(mContext.getContentResolver(), - Settings.Global.SHOW_NEW_NOTIF_DISMISS, 1 /* on by default */) == 1; - if (newFlowHideShelf) { - mBackgroundPaint.setColor(Color.TRANSPARENT); - invalidate(); - return; - } - // Interpolate between semi-transparent notification panel background color - // and white AOD separator. - float colorInterpolation = MathUtils.smoothStep(0.4f /* start */, 1f /* end */, - mLinearHideAmount); - int color = ColorUtils.blendARGB(mBgColor, Color.WHITE, colorInterpolation); - - if (mCachedBackgroundColor != color) { - mCachedBackgroundColor = color; - mBackgroundPaint.setColor(color); - invalidate(); - } - } - private void reinitView() { initView(getContext(), mKeyguardBypassEnabledProvider, mSwipeHelper); } @@ -979,7 +783,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable updateContentHeight(); clampScrollPosition(); requestChildrenUpdate(); - updateFirstAndLastBackgroundViews(); + updateFirstAndLastExpandableView(); updateAlgorithmLayoutMinHeight(); updateOwnTranslationZ(); } @@ -1050,9 +854,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable private void onPreDrawDuringAnimation() { mShelf.updateAppearance(); updateClippingToTopRoundedCorner(); - if (!mNeedsAnimation && !mChildrenUpdateRequested) { - updateBackground(); - } } @ShadeViewRefactor(RefactorComponent.SHADE_VIEW) @@ -2369,131 +2170,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable } } - @ShadeViewRefactor(RefactorComponent.SHADE_VIEW) - private void updateBackground() { - // No need to update the background color if it's not being drawn. - if (!mShouldDrawNotificationBackground) { - return; - } - - updateBackgroundBounds(); - if (didSectionBoundsChange()) { - boolean animate = mAnimateNextSectionBoundsChange || mAnimateNextBackgroundTop - || mAnimateNextBackgroundBottom || areSectionBoundsAnimating(); - if (!isExpanded()) { - abortBackgroundAnimators(); - animate = false; - } - if (animate) { - startBackgroundAnimation(); - } else { - for (NotificationSection section : mSections) { - section.resetCurrentBounds(); - } - invalidate(); - } - } else { - abortBackgroundAnimators(); - } - mAnimateNextBackgroundTop = false; - mAnimateNextBackgroundBottom = false; - mAnimateNextSectionBoundsChange = false; - } - - @ShadeViewRefactor(RefactorComponent.STATE_RESOLVER) - private void abortBackgroundAnimators() { - for (NotificationSection section : mSections) { - section.cancelAnimators(); - } - } - - private boolean didSectionBoundsChange() { - for (NotificationSection section : mSections) { - if (section.didBoundsChange()) { - return true; - } - } - return false; - } - - @ShadeViewRefactor(RefactorComponent.STATE_RESOLVER) - private boolean areSectionBoundsAnimating() { - for (NotificationSection section : mSections) { - if (section.areBoundsAnimating()) { - return true; - } - } - return false; - } - - @ShadeViewRefactor(RefactorComponent.STATE_RESOLVER) - private void startBackgroundAnimation() { - // TODO(kprevas): do we still need separate fields for top/bottom? - // or can each section manage its own animation state? - NotificationSection firstVisibleSection = getFirstVisibleSection(); - NotificationSection lastVisibleSection = getLastVisibleSection(); - for (NotificationSection section : mSections) { - section.startBackgroundAnimation( - section == firstVisibleSection - ? mAnimateNextBackgroundTop - : mAnimateNextSectionBoundsChange, - section == lastVisibleSection - ? mAnimateNextBackgroundBottom - : mAnimateNextSectionBoundsChange); - } - } - - /** - * Update the background bounds to the new desired bounds - */ - @ShadeViewRefactor(RefactorComponent.SHADE_VIEW) - private void updateBackgroundBounds() { - int left = mSidePaddings; - int right = getWidth() - mSidePaddings; - for (NotificationSection section : mSections) { - section.getBounds().left = left; - section.getBounds().right = right; - } - - if (!mIsExpanded) { - for (NotificationSection section : mSections) { - section.getBounds().top = 0; - section.getBounds().bottom = 0; - } - return; - } - int minTopPosition; - NotificationSection lastSection = getLastVisibleSection(); - boolean onKeyguard = mStatusBarState == StatusBarState.KEYGUARD; - if (!onKeyguard) { - minTopPosition = (int) (mTopPadding + mStackTranslation); - } else if (lastSection == null) { - minTopPosition = mTopPadding; - } else { - // The first sections could be empty while there could still be elements in later - // sections. The position of these first few sections is determined by the position of - // the first visible section. - NotificationSection firstVisibleSection = getFirstVisibleSection(); - firstVisibleSection.updateBounds(0 /* minTopPosition*/, 0 /* minBottomPosition */, - false /* shiftPulsingWithFirst */); - minTopPosition = firstVisibleSection.getBounds().top; - } - boolean shiftPulsingWithFirst = mNumHeadsUp <= 1 - && (mAmbientState.isDozing() - || (mKeyguardBypassEnabledProvider.getBypassEnabled() && onKeyguard)); - for (NotificationSection section : mSections) { - int minBottomPosition = minTopPosition; - if (section == lastSection) { - // We need to make sure the section goes all the way to the shelf - minBottomPosition = (int) (ViewState.getFinalTranslationY(mShelf) - + mShelf.getIntrinsicHeight()); - } - minTopPosition = section.updateBounds(minTopPosition, minBottomPosition, - shiftPulsingWithFirst); - shiftPulsingWithFirst = false; - } - } - private NotificationSection getFirstVisibleSection() { for (NotificationSection section : mSections) { if (section.getFirstVisibleChild() != null) { @@ -2514,7 +2190,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable } @ShadeViewRefactor(RefactorComponent.COORDINATOR) - private ExpandableView getLastChildWithBackground() { + private ExpandableView getLastExpandableView() { int childCount = getChildCount(); for (int i = childCount - 1; i >= 0; i--) { ExpandableView child = (ExpandableView) getChildAt(i); @@ -2527,7 +2203,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable } @ShadeViewRefactor(RefactorComponent.COORDINATOR) - private ExpandableView getFirstChildWithBackground() { + private ExpandableView getFirstExpandableView() { int childCount = getChildCount(); for (int i = 0; i < childCount; i++) { ExpandableView child = (ExpandableView) getChildAt(i); @@ -2540,7 +2216,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable } //TODO: We shouldn't have to generate this list every time - private List<ExpandableView> getChildrenWithBackground() { + private List<ExpandableView> getExpandableViewList() { ArrayList<ExpandableView> children = new ArrayList<>(); int childCount = getChildCount(); for (int i = 0; i < childCount; i++) { @@ -3078,32 +2754,13 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable } @ShadeViewRefactor(RefactorComponent.STATE_RESOLVER) - private void updateFirstAndLastBackgroundViews() { - NotificationSection firstSection = getFirstVisibleSection(); - NotificationSection lastSection = getLastVisibleSection(); - ExpandableView previousFirstChild = - firstSection == null ? null : firstSection.getFirstVisibleChild(); - ExpandableView previousLastChild = - lastSection == null ? null : lastSection.getLastVisibleChild(); - - ExpandableView firstChild = getFirstChildWithBackground(); - ExpandableView lastChild = getLastChildWithBackground(); - boolean sectionViewsChanged = mSectionsManager.updateFirstAndLastViewsForAllSections( - mSections, getChildrenWithBackground()); - - if (mAnimationsEnabled && mIsExpanded) { - mAnimateNextBackgroundTop = firstChild != previousFirstChild; - mAnimateNextBackgroundBottom = lastChild != previousLastChild || mAnimateBottomOnLayout; - mAnimateNextSectionBoundsChange = sectionViewsChanged; - } else { - mAnimateNextBackgroundTop = false; - mAnimateNextBackgroundBottom = false; - mAnimateNextSectionBoundsChange = false; - } + private void updateFirstAndLastExpandableView() { + ExpandableView lastChild = getLastExpandableView(); + mSectionsManager.updateFirstAndLastViewsForAllSections( + mSections, getExpandableViewList()); mAmbientState.setLastVisibleBackgroundChild(lastChild); // TODO: Refactor SectionManager and put the RoundnessManager there. mController.getNoticationRoundessManager().updateRoundedChildren(mSections); - mAnimateBottomOnLayout = false; invalidate(); } @@ -3265,7 +2922,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable setAnimationRunning(true); mStateAnimator.startAnimationForEvents(mAnimationEvents, mGoToFullShadeDelay); mAnimationEvents.clear(); - updateBackground(); updateViewShadows(); updateClippingToTopRoundedCorner(); } else { @@ -4350,7 +4006,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable @ShadeViewRefactor(RefactorComponent.SHADE_VIEW) private void setDimAmount(float dimAmount) { mDimAmount = dimAmount; - updateBackgroundDimming(); } @ShadeViewRefactor(RefactorComponent.STATE_RESOLVER) @@ -4419,7 +4074,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable } runAnimationFinishedRunnables(); setAnimationRunning(false); - updateBackground(); updateViewShadows(); updateClippingToTopRoundedCorner(); } @@ -4554,7 +4208,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable invalidateOutline(); } updateAlgorithmHeightAndPadding(); - updateBackgroundDimming(); requestChildrenUpdate(); updateOwnTranslationZ(); } @@ -5435,7 +5088,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable */ public void setDozeAmount(float dozeAmount) { mAmbientState.setDozeAmount(dozeAmount); - updateContinuousBackgroundDrawing(); requestChildrenUpdate(); } @@ -5473,7 +5125,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable } void setAnimateBottomOnLayout(boolean animateBottomOnLayout) { - mAnimateBottomOnLayout = animateBottomOnLayout; } public void setOnPulseHeightChangedListener(Runnable listener) { @@ -5506,25 +5157,14 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable void onSwipeBegin() { requestDisallowInterceptTouchEvent(true); - updateFirstAndLastBackgroundViews(); updateContinuousShadowDrawing(); - updateContinuousBackgroundDrawing(); requestChildrenUpdate(); } - void onSwipeEnd() { - updateFirstAndLastBackgroundViews(); - } - void setTopHeadsUpEntry(NotificationEntry topEntry) { mTopHeadsUpEntry = topEntry; } - void setNumHeadsUp(long numHeadsUp) { - mNumHeadsUp = numHeadsUp; - mAmbientState.setHasAlertEntries(numHeadsUp > 0); - } - public boolean getIsExpanded() { return mIsExpanded; } @@ -5639,27 +5279,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable mSectionsManager.updateSectionBoundaries(reason); } - boolean isSilkDismissEnabled() { - return Settings.Global.getInt(mContext.getContentResolver(), - Settings.Global.SHOW_NEW_NOTIF_DISMISS, 1 /* enabled by default */) == 1; - } - - void updateContinuousBackgroundDrawing() { - if (isSilkDismissEnabled()) { - return; - } - boolean continuousBackground = !mAmbientState.isFullyAwake() - && mSwipeHelper.isSwiping(); - if (continuousBackground != mContinuousBackgroundUpdate) { - mContinuousBackgroundUpdate = continuousBackground; - if (continuousBackground) { - getViewTreeObserver().addOnPreDrawListener(mBackgroundUpdater); - } else { - getViewTreeObserver().removeOnPreDrawListener(mBackgroundUpdater); - } - } - } - @ShadeViewRefactor(RefactorComponent.STATE_RESOLVER) void updateContinuousShadowDrawing() { boolean continuousShadowUpdate = mAnimationRunning diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java index 006d8da91941..abbbbb8352f5 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java @@ -60,10 +60,10 @@ import com.android.systemui.ExpandHelper; import com.android.systemui.Gefingerpoken; import com.android.systemui.R; import com.android.systemui.SwipeHelper; +import com.android.systemui.classifier.FalsingCollector; import com.android.systemui.colorextraction.SysuiColorExtractor; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.media.KeyguardMediaController; -import com.android.systemui.plugins.FalsingManager; import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin; import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin.OnMenuEventListener; import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper; @@ -143,7 +143,7 @@ public class NotificationStackScrollLayoutController { private final ConfigurationController mConfigurationController; private final ZenModeController mZenModeController; private final MetricsLogger mMetricsLogger; - private final FalsingManager mFalsingManager; + private final FalsingCollector mFalsingCollector; private final Resources mResources; private final NotificationSwipeHelper.Builder mNotificationSwipeHelperBuilder; private final ScrimController mScrimController; @@ -361,7 +361,7 @@ public class NotificationStackScrollLayoutController { @Override public void onDragCancelled(View v) { - mFalsingManager.onNotificationStopDismissing(); + mFalsingCollector.onNotificationStopDismissing(); } /** @@ -394,7 +394,6 @@ public class NotificationStackScrollLayoutController { if (mView.getDismissAllInProgress()) { return; } - mView.onSwipeEnd(); if (view instanceof ExpandableNotificationRow) { ExpandableNotificationRow row = (ExpandableNotificationRow) view; if (row.isHeadsUp()) { @@ -405,8 +404,8 @@ public class NotificationStackScrollLayoutController { } mView.addSwipedOutView(view); - mFalsingManager.onNotificationDismissed(); - if (mFalsingManager.shouldEnforceBouncer()) { + mFalsingCollector.onNotificationDismissed(); + if (mFalsingCollector.shouldEnforceBouncer()) { mStatusBar.executeRunnableDismissingKeyguard( null, null /* cancelAction */, @@ -448,13 +447,12 @@ public class NotificationStackScrollLayoutController { @Override public void onBeginDrag(View v) { - mFalsingManager.onNotificationStartDismissing(); + mFalsingCollector.onNotificationStartDismissing(); mView.onSwipeBegin(); } @Override public void onChildSnappedBack(View animView, float targetLeft) { - mView.onSwipeEnd(); if (animView instanceof ExpandableNotificationRow) { ExpandableNotificationRow row = (ExpandableNotificationRow) animView; if (row.isPinned() && !canChildBeDismissed(row) @@ -518,9 +516,7 @@ public class NotificationStackScrollLayoutController { @Override public void onHeadsUpStateChanged(NotificationEntry entry, boolean isHeadsUp) { - long numEntries = mHeadsUpManager.getAllEntries().count(); NotificationEntry topEntry = mHeadsUpManager.getTopEntry(); - mView.setNumHeadsUp(numEntries); mView.setTopHeadsUpEntry(topEntry); mNotificationRoundnessManager.updateView(entry.getRow(), false /* animate */); } @@ -550,7 +546,7 @@ public class NotificationStackScrollLayoutController { SysuiColorExtractor colorExtractor, NotificationLockscreenUserManager lockscreenUserManager, MetricsLogger metricsLogger, - FalsingManager falsingManager, + FalsingCollector falsingCollector, @Main Resources resources, NotificationSwipeHelper.Builder notificationSwipeHelperBuilder, StatusBar statusBar, @@ -584,7 +580,7 @@ public class NotificationStackScrollLayoutController { mColorExtractor = colorExtractor; mLockscreenUserManager = lockscreenUserManager; mMetricsLogger = metricsLogger; - mFalsingManager = falsingManager; + mFalsingCollector = falsingCollector; mResources = resources; mNotificationSwipeHelperBuilder = notificationSwipeHelperBuilder; mStatusBar = statusBar; @@ -665,8 +661,6 @@ public class NotificationStackScrollLayoutController { mHeadsUpManager.setAnimationStateHandler(mView::setHeadsUpGoingAwayAnimationsAllowed); mDynamicPrivacyController.addListener(mDynamicPrivacyControllerListener); - mScrimController.setScrimBehindChangeRunnable(mView::updateBackgroundDimming); - mLockscreenUserManager.addUserChangedListener(mLockscreenUserChangeListener); mFadeNotificationsOnDismiss = // TODO: this should probably be injected directly diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java index 80cb289a3c0d..9854f5450df1 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java @@ -39,9 +39,9 @@ import com.android.keyguard.KeyguardUpdateMonitorCallback; import com.android.keyguard.ViewMediatorCallback; import com.android.keyguard.dagger.KeyguardBouncerComponent; import com.android.systemui.DejankUtils; +import com.android.systemui.classifier.FalsingCollector; import com.android.systemui.dagger.qualifiers.RootView; import com.android.systemui.keyguard.DismissCallbackRegistry; -import com.android.systemui.plugins.FalsingManager; import com.android.systemui.shared.system.SysUiStatsLog; import com.android.systemui.statusbar.policy.KeyguardStateController; @@ -65,7 +65,7 @@ public class KeyguardBouncer { protected final Context mContext; protected final ViewMediatorCallback mCallback; protected final ViewGroup mContainer; - private final FalsingManager mFalsingManager; + private final FalsingCollector mFalsingCollector; private final DismissCallbackRegistry mDismissCallbackRegistry; private final Handler mHandler; private final List<BouncerExpansionCallback> mExpansionCallbacks = new ArrayList<>(); @@ -100,7 +100,7 @@ public class KeyguardBouncer { private KeyguardBouncer(Context context, ViewMediatorCallback callback, ViewGroup container, - DismissCallbackRegistry dismissCallbackRegistry, FalsingManager falsingManager, + DismissCallbackRegistry dismissCallbackRegistry, FalsingCollector falsingCollector, BouncerExpansionCallback expansionCallback, KeyguardStateController keyguardStateController, KeyguardUpdateMonitor keyguardUpdateMonitor, @@ -111,7 +111,7 @@ public class KeyguardBouncer { mCallback = callback; mContainer = container; mKeyguardUpdateMonitor = keyguardUpdateMonitor; - mFalsingManager = falsingManager; + mFalsingCollector = falsingCollector; mDismissCallbackRegistry = dismissCallbackRegistry; mHandler = handler; mKeyguardStateController = keyguardStateController; @@ -203,7 +203,7 @@ public class KeyguardBouncer { * will never be notified and its internal state will be out of sync. */ private void onFullyShown() { - mFalsingManager.onBouncerShown(); + mFalsingCollector.onBouncerShown(); if (mKeyguardViewController == null) { Log.wtf(TAG, "onFullyShown when view was null"); } else { @@ -223,7 +223,7 @@ public class KeyguardBouncer { if (mRoot != null) { mRoot.setVisibility(View.INVISIBLE); } - mFalsingManager.onBouncerHidden(); + mFalsingCollector.onBouncerHidden(); DejankUtils.postAfterTraversal(mResetRunnable); } @@ -290,7 +290,7 @@ public class KeyguardBouncer { mDismissCallbackRegistry.notifyDismissCancelled(); } mIsScrimmed = false; - mFalsingManager.onBouncerHidden(); + mFalsingCollector.onBouncerHidden(); mCallback.onBouncerVisiblityChanged(false /* shown */); cancelShowRunnable(); if (mKeyguardViewController != null) { @@ -327,7 +327,7 @@ public class KeyguardBouncer { public void reset() { cancelShowRunnable(); inflateView(); - mFalsingManager.onBouncerHidden(); + mFalsingCollector.onBouncerHidden(); } public void onScreenTurnedOff() { @@ -541,7 +541,7 @@ public class KeyguardBouncer { private final Context mContext; private final ViewMediatorCallback mCallback; private final DismissCallbackRegistry mDismissCallbackRegistry; - private final FalsingManager mFalsingManager; + private final FalsingCollector mFalsingCollector; private final KeyguardStateController mKeyguardStateController; private final KeyguardUpdateMonitor mKeyguardUpdateMonitor; private final KeyguardBypassController mKeyguardBypassController; @@ -551,7 +551,7 @@ public class KeyguardBouncer { @Inject public Factory(Context context, ViewMediatorCallback callback, - DismissCallbackRegistry dismissCallbackRegistry, FalsingManager falsingManager, + DismissCallbackRegistry dismissCallbackRegistry, FalsingCollector falsingCollector, KeyguardStateController keyguardStateController, KeyguardUpdateMonitor keyguardUpdateMonitor, KeyguardBypassController keyguardBypassController, Handler handler, @@ -560,7 +560,7 @@ public class KeyguardBouncer { mContext = context; mCallback = callback; mDismissCallbackRegistry = dismissCallbackRegistry; - mFalsingManager = falsingManager; + mFalsingCollector = falsingCollector; mKeyguardStateController = keyguardStateController; mKeyguardUpdateMonitor = keyguardUpdateMonitor; mKeyguardBypassController = keyguardBypassController; @@ -572,7 +572,7 @@ public class KeyguardBouncer { public KeyguardBouncer create(@RootView ViewGroup container, BouncerExpansionCallback expansionCallback) { return new KeyguardBouncer(mContext, mCallback, container, - mDismissCallbackRegistry, mFalsingManager, expansionCallback, + mDismissCallbackRegistry, mFalsingCollector, expansionCallback, mKeyguardStateController, mKeyguardUpdateMonitor, mKeyguardBypassController, mHandler, mKeyguardSecurityModel, mKeyguardBouncerComponentFactory); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java index 6b8881168e4e..f7139aa2acce 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java @@ -79,6 +79,7 @@ import com.android.systemui.Interpolators; import com.android.systemui.R; import com.android.systemui.biometrics.AuthController; import com.android.systemui.classifier.Classifier; +import com.android.systemui.classifier.FalsingCollector; import com.android.systemui.dagger.qualifiers.DisplayId; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.doze.DozeLog; @@ -364,7 +365,8 @@ public class NotificationPanelViewController extends PanelViewController { private boolean mHeadsUpAnimatingAway; private boolean mLaunchingAffordance; private boolean mAffordanceHasPreview; - private FalsingManager mFalsingManager; + private final FalsingManager mFalsingManager; + private final FalsingCollector mFalsingCollector; private String mLastCameraLaunchSource = KeyguardBottomAreaView.CAMERA_LAUNCH_SOURCE_AFFORDANCE; private Runnable mHeadsUpExistenceChangedRunnable = () -> { @@ -502,7 +504,7 @@ public class NotificationPanelViewController extends PanelViewController { NotificationWakeUpCoordinator coordinator, PulseExpansionHandler pulseExpansionHandler, DynamicPrivacyController dynamicPrivacyController, KeyguardBypassController bypassController, FalsingManager falsingManager, - ShadeController shadeController, + FalsingCollector falsingCollector, ShadeController shadeController, NotificationLockscreenUserManager notificationLockscreenUserManager, NotificationEntryManager notificationEntryManager, KeyguardStateController keyguardStateController, @@ -543,6 +545,7 @@ public class NotificationPanelViewController extends PanelViewController { mView.setWillNotDraw(!DEBUG); mInjectionInflationController = injectionInflationController; mFalsingManager = falsingManager; + mFalsingCollector = falsingCollector; mPowerManager = powerManager; mWakeUpCoordinator = coordinator; mAccessibilityManager = accessibilityManager; @@ -1426,7 +1429,7 @@ public class NotificationPanelViewController extends PanelViewController { private void handleQsDown(MotionEvent event) { if (event.getActionMasked() == MotionEvent.ACTION_DOWN && shouldQuickSettingsIntercept( event.getX(), event.getY(), -1)) { - mFalsingManager.onQsDown(); + mFalsingCollector.onQsDown(); mQsTracking = true; onQsExpansionStarted(); mInitialHeightOnTouch = mQsExpansionHeight; @@ -1606,7 +1609,7 @@ public class NotificationPanelViewController extends PanelViewController { mQsExpanded = expanded; updateQsState(); requestPanelHeightUpdate(); - mFalsingManager.setQsExpanded(expanded); + mFalsingCollector.setQsExpanded(expanded); mStatusBar.setQsExpanded(expanded); mNotificationContainerParent.setQsExpanded(expanded); mPulseExpansionHandler.setQsExpanded(expanded); @@ -1743,7 +1746,7 @@ public class NotificationPanelViewController extends PanelViewController { } if (!mFalsingManager.isUnlockingDisabled() && mQsFullyExpanded - && mFalsingManager.shouldEnforceBouncer()) { + && mFalsingCollector.shouldEnforceBouncer()) { mStatusBar.executeRunnableDismissingKeyguard(null, null /* cancelAction */, false /* dismissShade */, true /* afterKeyguardGone */, false /* deferred */); } @@ -2404,7 +2407,7 @@ public class NotificationPanelViewController extends PanelViewController { @Override protected void onTrackingStarted() { - mFalsingManager.onTrackingStarted(!mKeyguardStateController.canDismissLockScreen()); + mFalsingCollector.onTrackingStarted(!mKeyguardStateController.canDismissLockScreen()); super.onTrackingStarted(); if (mQsFullyExpanded) { mQsExpandImmediate = true; @@ -2418,7 +2421,7 @@ public class NotificationPanelViewController extends PanelViewController { @Override protected void onTrackingStopped(boolean expand) { - mFalsingManager.onTrackingStopped(); + mFalsingCollector.onTrackingStopped(); super.onTrackingStopped(expand); if (expand) { mNotificationStackScrollLayoutController.setOverScrolledPixels(0.0f, true /* onTop */, @@ -3365,8 +3368,8 @@ public class NotificationPanelViewController extends PanelViewController { if (start) { mLockscreenGestureLogger.write(MetricsEvent.ACTION_LS_DIALER, lengthDp, velocityDp); mLockscreenGestureLogger.log(LockscreenUiEvent.LOCKSCREEN_DIALER); - mFalsingManager.onLeftAffordanceOn(); - if (mFalsingManager.shouldEnforceBouncer()) { + mFalsingCollector.onLeftAffordanceOn(); + if (mFalsingCollector.shouldEnforceBouncer()) { mStatusBar.executeRunnableDismissingKeyguard( () -> mKeyguardBottomArea.launchLeftAffordance(), null, true /* dismissShade */, false /* afterKeyguardGone */, @@ -3381,8 +3384,8 @@ public class NotificationPanelViewController extends PanelViewController { MetricsEvent.ACTION_LS_CAMERA, lengthDp, velocityDp); mLockscreenGestureLogger.log(LockscreenUiEvent.LOCKSCREEN_CAMERA); } - mFalsingManager.onCameraOn(); - if (mFalsingManager.shouldEnforceBouncer()) { + mFalsingCollector.onCameraOn(); + if (mFalsingCollector.shouldEnforceBouncer()) { mStatusBar.executeRunnableDismissingKeyguard( () -> mKeyguardBottomArea.launchCamera(mLastCameraLaunchSource), null, true /* dismissShade */, false /* afterKeyguardGone */, @@ -3413,7 +3416,7 @@ public class NotificationPanelViewController extends PanelViewController { @Override public void onSwipingStarted(boolean rightIcon) { - mFalsingManager.onAffordanceSwipingStarted(rightIcon); + mFalsingCollector.onAffordanceSwipingStarted(rightIcon); boolean camera = mView.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL ? !rightIcon @@ -3428,7 +3431,7 @@ public class NotificationPanelViewController extends PanelViewController { @Override public void onSwipingAborted() { - mFalsingManager.onAffordanceSwipingAborted(); + mFalsingCollector.onAffordanceSwipingAborted(); mKeyguardBottomArea.unbindCameraPrewarmService(false /* launched */); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewController.java index 3db3ab5a56c8..ba4fbb871b97 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewController.java @@ -36,6 +36,7 @@ import android.view.ViewGroup; import com.android.internal.annotations.VisibleForTesting; import com.android.systemui.ExpandHelper; import com.android.systemui.R; +import com.android.systemui.classifier.FalsingCollector; import com.android.systemui.dock.DockManager; import com.android.systemui.doze.DozeLog; import com.android.systemui.plugins.FalsingManager; @@ -73,6 +74,7 @@ public class NotificationShadeWindowViewController { private final KeyguardBypassController mBypassController; private final PluginManager mPluginManager; private final FalsingManager mFalsingManager; + private final FalsingCollector mFalsingCollector; private final TunerService mTunerService; private final NotificationLockscreenUserManager mNotificationLockscreenUserManager; private final NotificationEntryManager mNotificationEntryManager; @@ -118,6 +120,7 @@ public class NotificationShadeWindowViewController { DynamicPrivacyController dynamicPrivacyController, KeyguardBypassController bypassController, FalsingManager falsingManager, + FalsingCollector falsingCollector, PluginManager pluginManager, TunerService tunerService, NotificationLockscreenUserManager notificationLockscreenUserManager, @@ -140,6 +143,7 @@ public class NotificationShadeWindowViewController { mDynamicPrivacyController = dynamicPrivacyController; mBypassController = bypassController; mFalsingManager = falsingManager; + mFalsingCollector = falsingCollector; mPluginManager = pluginManager; mTunerService = tunerService; mNotificationLockscreenUserManager = notificationLockscreenUserManager; @@ -234,7 +238,7 @@ public class NotificationShadeWindowViewController { if (mTouchCancelled || mExpandAnimationRunning || mExpandAnimationPending) { return false; } - mFalsingManager.onTouchEvent(ev, mView.getWidth(), mView.getHeight()); + mFalsingCollector.onTouchEvent(ev, mView.getWidth(), mView.getHeight()); mGestureDetector.onTouchEvent(ev); if (mBrightnessMirror != null && mBrightnessMirror.getVisibility() == View.VISIBLE) { @@ -394,7 +398,7 @@ public class NotificationShadeWindowViewController { setDragDownHelper( new DragDownHelper( mView.getContext(), mView, expandHelperCallback, - dragDownCallback, mFalsingManager)); + dragDownCallback, mFalsingManager, mFalsingCollector)); mDepthController.setRoot(mView); mNotificationPanelViewController.addExpansionListener(mDepthController); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java index e6ac7dcee8a7..c8c5a6331a3b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java @@ -147,6 +147,7 @@ import com.android.systemui.SystemUI; import com.android.systemui.assist.AssistManager; import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.charging.WirelessChargingAnimation; +import com.android.systemui.classifier.FalsingCollector; import com.android.systemui.colorextraction.SysuiColorExtractor; import com.android.systemui.dagger.qualifiers.UiBackground; import com.android.systemui.demomode.DemoMode; @@ -384,6 +385,7 @@ public class StatusBar extends SystemUI implements DemoMode, private final StatusBarTouchableRegionManager mStatusBarTouchableRegionManager; private final DynamicPrivacyController mDynamicPrivacyController; private final BypassHeadsUpNotifier mBypassHeadsUpNotifier; + private final FalsingCollector mFalsingCollector; private final FalsingManager mFalsingManager; private final BroadcastDispatcher mBroadcastDispatcher; private final ConfigurationController mConfigurationController; @@ -692,6 +694,7 @@ public class StatusBar extends SystemUI implements DemoMode, DynamicPrivacyController dynamicPrivacyController, BypassHeadsUpNotifier bypassHeadsUpNotifier, FalsingManager falsingManager, + FalsingCollector falsingCollector, BroadcastDispatcher broadcastDispatcher, RemoteInputQuickSettingsDisabler remoteInputQuickSettingsDisabler, NotificationGutsManager notificationGutsManager, @@ -772,6 +775,7 @@ public class StatusBar extends SystemUI implements DemoMode, mStatusBarTouchableRegionManager = statusBarTouchableRegionManager; mDynamicPrivacyController = dynamicPrivacyController; mBypassHeadsUpNotifier = bypassHeadsUpNotifier; + mFalsingCollector = falsingCollector; mFalsingManager = falsingManager; mBroadcastDispatcher = broadcastDispatcher; mRemoteInputQuickSettingsDisabler = remoteInputQuickSettingsDisabler; @@ -1389,7 +1393,7 @@ public class StatusBar extends SystemUI implements DemoMode, where.getLocationInWindow(mTmpInt2); mWakeUpTouchLocation = new PointF(mTmpInt2[0] + where.getWidth() / 2, mTmpInt2[1] + where.getHeight() / 2); - mFalsingManager.onScreenOnFromTouch(); + mFalsingCollector.onScreenOnFromTouch(); } } @@ -1648,7 +1652,7 @@ public class StatusBar extends SystemUI implements DemoMode, return; } mReportRejectedTouch.setVisibility(mState == StatusBarState.KEYGUARD && !mDozing - && mFalsingManager.isReportingEnabled() ? View.VISIBLE : View.INVISIBLE); + && mFalsingCollector.isReportingEnabled() ? View.VISIBLE : View.INVISIBLE); } /** @@ -3685,7 +3689,7 @@ public class StatusBar extends SystemUI implements DemoMode, } public void onUnlockHintStarted() { - mFalsingManager.onUnlockHintStarted(); + mFalsingCollector.onUnlockHintStarted(); mKeyguardIndicationController.showTransientIndication(R.string.keyguard_unlock); } @@ -3695,17 +3699,17 @@ public class StatusBar extends SystemUI implements DemoMode, } public void onCameraHintStarted() { - mFalsingManager.onCameraHintStarted(); + mFalsingCollector.onCameraHintStarted(); mKeyguardIndicationController.showTransientIndication(R.string.camera_hint); } public void onVoiceAssistHintStarted() { - mFalsingManager.onLeftAffordanceHintStarted(); + mFalsingCollector.onLeftAffordanceHintStarted(); mKeyguardIndicationController.showTransientIndication(R.string.voice_hint); } public void onPhoneHintStarted() { - mFalsingManager.onLeftAffordanceHintStarted(); + mFalsingCollector.onLeftAffordanceHintStarted(); mKeyguardIndicationController.showTransientIndication(R.string.phone_hint); } @@ -3756,7 +3760,7 @@ public class StatusBar extends SystemUI implements DemoMode, boolean fullShadeNeedsBouncer = !mLockscreenUserManager. userAllowsPrivateNotificationsInPublic(mLockscreenUserManager.getCurrentUserId()) || !mLockscreenUserManager.shouldShowLockscreenNotifications() - || mFalsingManager.shouldEnforceBouncer(); + || mFalsingCollector.shouldEnforceBouncer(); if (mKeyguardBypassController.getBypassEnabled()) { fullShadeNeedsBouncer = false; } @@ -3888,7 +3892,7 @@ public class StatusBar extends SystemUI implements DemoMode, final ScreenLifecycle.Observer mScreenObserver = new ScreenLifecycle.Observer() { @Override public void onScreenTurningOn() { - mFalsingManager.onScreenTurningOn(); + mFalsingCollector.onScreenTurningOn(); mNotificationPanelViewController.onScreenTurningOn(); } @@ -3899,7 +3903,7 @@ public class StatusBar extends SystemUI implements DemoMode, @Override public void onScreenTurnedOff() { - mFalsingManager.onScreenOff(); + mFalsingCollector.onScreenOff(); mScrimController.onScreenTurnedOff(); updateIsKeyguard(); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java index f6631ce1414c..2aa3f37ccf11 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java @@ -31,6 +31,7 @@ import com.android.keyguard.ViewMediatorCallback; import com.android.systemui.InitController; import com.android.systemui.assist.AssistManager; import com.android.systemui.broadcast.BroadcastDispatcher; +import com.android.systemui.classifier.FalsingCollector; import com.android.systemui.colorextraction.SysuiColorExtractor; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.UiBackground; @@ -136,6 +137,7 @@ public interface StatusBarPhoneModule { DynamicPrivacyController dynamicPrivacyController, BypassHeadsUpNotifier bypassHeadsUpNotifier, FalsingManager falsingManager, + FalsingCollector falsingCollector, BroadcastDispatcher broadcastDispatcher, RemoteInputQuickSettingsDisabler remoteInputQuickSettingsDisabler, NotificationGutsManager notificationGutsManager, @@ -216,6 +218,7 @@ public interface StatusBarPhoneModule { dynamicPrivacyController, bypassHeadsUpNotifier, falsingManager, + falsingCollector, broadcastDispatcher, remoteInputQuickSettingsDisabler, notificationGutsManager, diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/ClassifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/ClassifierTest.java index 69d39fa10b72..472ed7a22fe3 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/ClassifierTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/ClassifierTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 The Android Open Source Project + * 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.classifier.brightline; +package com.android.systemui.classifier; import static com.android.systemui.classifier.Classifier.UNLOCK; @@ -55,7 +55,7 @@ public class ClassifierTest extends LeakCheckedTest { resetDataProvider(); } - FalsingDataProvider getDataProvider() { + protected FalsingDataProvider getDataProvider() { return mDataProvider; } @@ -63,15 +63,15 @@ public class ClassifierTest extends LeakCheckedTest { return mFakeBatteryController; } - void setOffsetX(float offsetX) { + protected void setOffsetX(float offsetX) { mOffsetX = offsetX; } - void setOffsetY(float offsetY) { + protected void setOffsetY(float offsetY) { mOffsetY = offsetY; } - void resetDataProvider() { + protected void resetDataProvider() { for (MotionEvent motionEvent : mMotionEvents) { motionEvent.recycle(); } @@ -81,28 +81,28 @@ public class ClassifierTest extends LeakCheckedTest { mDataProvider.onSessionEnd(); } - MotionEvent appendDownEvent(float x, float y) { + protected MotionEvent appendDownEvent(float x, float y) { return appendMotionEvent(MotionEvent.ACTION_DOWN, x, y); } - MotionEvent appendDownEvent(float x, float y, long eventTime) { + protected MotionEvent appendDownEvent(float x, float y, long eventTime) { return appendMotionEvent(MotionEvent.ACTION_DOWN, x, y, eventTime); } - MotionEvent appendMoveEvent(float x, float y) { + protected MotionEvent appendMoveEvent(float x, float y) { return appendMotionEvent(MotionEvent.ACTION_MOVE, x, y); } - MotionEvent appendMoveEvent(float x, float y, long eventTime) { + protected MotionEvent appendMoveEvent(float x, float y, long eventTime) { return appendMotionEvent(MotionEvent.ACTION_MOVE, x, y, eventTime); } - MotionEvent appendUpEvent(float x, float y) { + protected MotionEvent appendUpEvent(float x, float y) { return appendMotionEvent(MotionEvent.ACTION_UP, x, y); } - MotionEvent appendUpEvent(float x, float y, long eventTime) { + protected MotionEvent appendUpEvent(float x, float y, long eventTime) { return appendMotionEvent(MotionEvent.ACTION_UP, x, y, eventTime); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/BrightLineFalsingManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingCollectorImplTest.java index 30dddc02be90..af5e789a0c41 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/BrightLineFalsingManagerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingCollectorImplTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.classifier.brightline; +package com.android.systemui.classifier; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.never; @@ -22,123 +22,102 @@ import static org.mockito.Mockito.reset; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import android.content.res.Resources; -import android.test.suitebuilder.annotation.SmallTest; import android.testing.AndroidTestingRunner; -import android.testing.TestableLooper; -import android.util.DisplayMetrics; -import android.view.ViewConfiguration; -import com.android.internal.logging.testing.UiEventLoggerFake; +import androidx.test.filters.SmallTest; + import com.android.keyguard.KeyguardUpdateMonitor; -import com.android.systemui.R; -import com.android.systemui.dock.DockManager; -import com.android.systemui.dock.DockManagerFake; +import com.android.systemui.SysuiTestCase; +import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.StatusBarState; -import com.android.systemui.statusbar.StatusBarStateControllerImpl; import com.android.systemui.statusbar.SysuiStatusBarStateController; -import com.android.systemui.util.DeviceConfigProxy; -import com.android.systemui.util.DeviceConfigProxyFake; import com.android.systemui.util.sensors.ProximitySensor; import com.android.systemui.util.sensors.ThresholdSensor; -import com.android.systemui.util.time.FakeSystemClock; -import com.android.systemui.utils.leaks.FakeBatteryController; -import com.android.systemui.utils.leaks.LeakCheckedTest; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; @SmallTest @RunWith(AndroidTestingRunner.class) -@TestableLooper.RunWithLooper -public class BrightLineFalsingManagerTest extends LeakCheckedTest { - +public class FalsingCollectorImplTest extends SysuiTestCase { + private FalsingCollectorImpl mFalsingCollector; + @Mock + private FalsingDataProvider mFalsingDataProvider; + private final FalsingManagerFake mFalsingManager = new FalsingManagerFake(); @Mock private KeyguardUpdateMonitor mKeyguardUpdateMonitor; @Mock private ProximitySensor mProximitySensor; @Mock - private Resources mResources; - @Mock - private ViewConfiguration mViewConfiguration; private SysuiStatusBarStateController mStatusBarStateController; - private FalsingDataProvider mFalsingDataProvider; - private FakeBatteryController mFakeBatteryController; - - private BrightLineFalsingManager mFalsingManager; @Before - public void setup() { + public void setUp() { MockitoAnnotations.initMocks(this); - mFakeBatteryController = new FakeBatteryController(getLeakCheck()); - DisplayMetrics dm = new DisplayMetrics(); - dm.xdpi = 100; - dm.ydpi = 100; - dm.widthPixels = 100; - dm.heightPixels = 100; - mFalsingDataProvider = new FalsingDataProvider(dm, mFakeBatteryController, - new FakeSystemClock()); - DeviceConfigProxy deviceConfigProxy = new DeviceConfigProxyFake(); - DockManager dockManager = new DockManagerFake(); - mStatusBarStateController = new StatusBarStateControllerImpl(new UiEventLoggerFake()); - mStatusBarStateController.setState(StatusBarState.KEYGUARD); - when(mResources.getDimension(R.dimen.double_tap_slop)).thenReturn(1f); - when(mViewConfiguration.getScaledTouchSlop()).thenReturn(1); - mFalsingManager = new BrightLineFalsingManager(mFalsingDataProvider, - mKeyguardUpdateMonitor, mProximitySensor, deviceConfigProxy, mResources, - mViewConfiguration, dockManager, mStatusBarStateController); + + when(mStatusBarStateController.getState()).thenReturn(StatusBarState.KEYGUARD); + + mFalsingCollector = new FalsingCollectorImpl(mFalsingDataProvider, mFalsingManager, + mKeyguardUpdateMonitor, mProximitySensor, mStatusBarStateController); } + @Test public void testRegisterSensor() { - mFalsingManager.onScreenTurningOn(); + mFalsingCollector.onScreenTurningOn(); verify(mProximitySensor).register(any(ThresholdSensor.Listener.class)); } @Test public void testNoProximityWhenWirelessCharging() { - mFakeBatteryController.setWirelessCharging(true); - mFalsingManager.onScreenTurningOn(); + when(mFalsingDataProvider.isWirelessCharging()).thenReturn(true); + mFalsingCollector.onScreenTurningOn(); verify(mProximitySensor, never()).register(any(ThresholdSensor.Listener.class)); } @Test public void testUnregisterSensor() { - mFalsingManager.onScreenTurningOn(); + mFalsingCollector.onScreenTurningOn(); reset(mProximitySensor); - mFalsingManager.onScreenOff(); + mFalsingCollector.onScreenOff(); verify(mProximitySensor).unregister(any(ThresholdSensor.Listener.class)); } @Test public void testUnregisterSensor_QS() { - mFalsingManager.onScreenTurningOn(); + mFalsingCollector.onScreenTurningOn(); reset(mProximitySensor); - mFalsingManager.setQsExpanded(true); + mFalsingCollector.setQsExpanded(true); verify(mProximitySensor).unregister(any(ThresholdSensor.Listener.class)); - mFalsingManager.setQsExpanded(false); + mFalsingCollector.setQsExpanded(false); verify(mProximitySensor).register(any(ThresholdSensor.Listener.class)); } @Test public void testUnregisterSensor_Bouncer() { - mFalsingManager.onScreenTurningOn(); + mFalsingCollector.onScreenTurningOn(); reset(mProximitySensor); - mFalsingManager.onBouncerShown(); + mFalsingCollector.onBouncerShown(); verify(mProximitySensor).unregister(any(ThresholdSensor.Listener.class)); - mFalsingManager.onBouncerHidden(); + mFalsingCollector.onBouncerHidden(); verify(mProximitySensor).register(any(ThresholdSensor.Listener.class)); } @Test public void testUnregisterSensor_StateTransition() { - mFalsingManager.onScreenTurningOn(); + + ArgumentCaptor<StatusBarStateController.StateListener> stateListenerArgumentCaptor = + ArgumentCaptor.forClass(StatusBarStateController.StateListener.class); + verify(mStatusBarStateController).addCallback(stateListenerArgumentCaptor.capture()); + + mFalsingCollector.onScreenTurningOn(); reset(mProximitySensor); - mStatusBarStateController.setState(StatusBarState.SHADE); + stateListenerArgumentCaptor.getValue().onStateChanged(StatusBarState.SHADE); verify(mProximitySensor).unregister(any(ThresholdSensor.Listener.class)); } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/FalsingDataProviderTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingDataProviderTest.java index be38f4419372..be0cc97a2f0f 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/FalsingDataProviderTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingDataProviderTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 The Android Open Source Project + * 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.classifier.brightline; +package com.android.systemui.classifier; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.Matchers.closeTo; @@ -112,13 +112,6 @@ public class FalsingDataProviderTest extends ClassifierTest { assertThat(motionEventList.get(1).getX(), is(6f)); assertThat(motionEventList.get(0).getY(), is(7f)); assertThat(motionEventList.get(1).getY(), is(5f)); - - // The first, real event should still be a, however. - MotionEvent firstRealMotionEvent = mDataProvider.getFirstActualMotionEvent(); - assertThat(firstRealMotionEvent.getActionMasked(), is(MotionEvent.ACTION_DOWN)); - assertThat(firstRealMotionEvent.getEventTime(), is(1L)); - assertThat(firstRealMotionEvent.getX(), is(2f)); - assertThat(firstRealMotionEvent.getY(), is(9f)); } @Test diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/DiagonalClassifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/DiagonalClassifierTest.java index e88ff2df60ca..714d6581ff00 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/DiagonalClassifierTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/DiagonalClassifierTest.java @@ -27,6 +27,8 @@ import android.testing.AndroidTestingRunner; import androidx.test.filters.SmallTest; +import com.android.systemui.classifier.ClassifierTest; +import com.android.systemui.classifier.FalsingDataProvider; import com.android.systemui.util.DeviceConfigProxyFake; import org.junit.After; diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/DistanceClassifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/DistanceClassifierTest.java index e5ab9be288ef..d66c7a9d43a5 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/DistanceClassifierTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/DistanceClassifierTest.java @@ -23,6 +23,8 @@ import android.testing.AndroidTestingRunner; import androidx.test.filters.SmallTest; +import com.android.systemui.classifier.ClassifierTest; +import com.android.systemui.classifier.FalsingDataProvider; import com.android.systemui.util.DeviceConfigProxyFake; import org.junit.After; diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/DoubleTapClassifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/DoubleTapClassifierTest.java index 9f3a1e4821c9..288ab0ad6596 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/DoubleTapClassifierTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/DoubleTapClassifierTest.java @@ -27,6 +27,9 @@ import android.view.MotionEvent; import androidx.test.filters.SmallTest; +import com.android.systemui.classifier.ClassifierTest; +import com.android.systemui.classifier.FalsingDataProvider; + import org.junit.After; import org.junit.Before; import org.junit.Test; diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/PointerCountClassifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/PointerCountClassifierTest.java index 4f8e7c801d04..b512f0d6ef32 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/PointerCountClassifierTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/PointerCountClassifierTest.java @@ -26,6 +26,8 @@ import android.view.MotionEvent; import androidx.test.filters.SmallTest; +import com.android.systemui.classifier.ClassifierTest; + import org.junit.After; import org.junit.Before; import org.junit.Test; diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/ProximityClassifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/ProximityClassifierTest.java index 3cebf0d6af57..c2e290f166a3 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/ProximityClassifierTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/ProximityClassifierTest.java @@ -28,6 +28,8 @@ import android.view.MotionEvent; import androidx.test.filters.SmallTest; +import com.android.systemui.classifier.ClassifierTest; +import com.android.systemui.classifier.FalsingDataProvider; import com.android.systemui.util.DeviceConfigProxyFake; import com.android.systemui.util.sensors.ProximitySensor; diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/SingleTapClassifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/SingleTapClassifierTest.java index 642b077f0dcf..d67f2b833deb 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/SingleTapClassifierTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/SingleTapClassifierTest.java @@ -25,6 +25,9 @@ import android.view.MotionEvent; import androidx.test.filters.SmallTest; +import com.android.systemui.classifier.ClassifierTest; +import com.android.systemui.classifier.FalsingDataProvider; + import org.junit.After; import org.junit.Before; import org.junit.Test; diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/TypeClassifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/TypeClassifierTest.java index 4346e7df088f..5f3b84c2f7ae 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/TypeClassifierTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/TypeClassifierTest.java @@ -33,6 +33,9 @@ import android.testing.AndroidTestingRunner; import androidx.test.filters.SmallTest; +import com.android.systemui.classifier.ClassifierTest; +import com.android.systemui.classifier.FalsingDataProvider; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/ZigZagClassifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/ZigZagClassifierTest.java index a8cce00ba996..e49262f5099f 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/ZigZagClassifierTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/ZigZagClassifierTest.java @@ -23,6 +23,7 @@ import android.testing.AndroidTestingRunner; import androidx.test.filters.SmallTest; +import com.android.systemui.classifier.ClassifierTest; import com.android.systemui.util.DeviceConfigProxyFake; import org.junit.After; diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java index f6d6f562e3fa..67d0295c82d3 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java @@ -41,7 +41,7 @@ import com.android.keyguard.KeyguardDisplayManager; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.systemui.SysuiTestCase; import com.android.systemui.broadcast.BroadcastDispatcher; -import com.android.systemui.classifier.FalsingManagerFake; +import com.android.systemui.classifier.FalsingCollectorFake; import com.android.systemui.dump.DumpManager; import com.android.systemui.navigationbar.NavigationModeController; import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager; @@ -76,18 +76,18 @@ public class KeyguardViewMediatorTest extends SysuiTestCase { private DeviceConfigProxy mDeviceConfig = new DeviceConfigProxyFake(); private FakeExecutor mUiBgExecutor = new FakeExecutor(new FakeSystemClock()); - private FalsingManagerFake mFalsingManager; + private FalsingCollectorFake mFalsingCollector; @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); - mFalsingManager = new FalsingManagerFake(); + mFalsingCollector = new FalsingCollectorFake(); when(mLockPatternUtils.getDevicePolicyManager()).thenReturn(mDevicePolicyManager); when(mPowerManager.newWakeLock(anyInt(), any())).thenReturn(mock(WakeLock.class)); mViewMediator = new KeyguardViewMediator( - mContext, mFalsingManager, mLockPatternUtils, mBroadcastDispatcher, + mContext, mFalsingCollector, mLockPatternUtils, mBroadcastDispatcher, () -> mStatusBarKeyguardViewManager, mDismissCallbackRegistry, mUpdateMonitor, mDumpManager, mUiBgExecutor, mPowerManager, mTrustManager, mDeviceConfig, mNavigationModeController, diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingControllerTest.java index 11ef3e33f9d0..b7cc651dc24b 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingControllerTest.java @@ -19,6 +19,8 @@ package com.android.systemui.screenrecord; import static junit.framework.Assert.assertFalse; import static junit.framework.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.verify; import android.app.PendingIntent; @@ -128,6 +130,35 @@ public class RecordingControllerTest extends SysuiTestCase { verify(mCallback).onRecordingEnd(); } + // Test that broadcast will update state + @Test + public void testUpdateStateBroadcast() { + if (Looper.myLooper() == null) { + Looper.prepare(); + } + + // When a recording has started + PendingIntent startIntent = Mockito.mock(PendingIntent.class); + mController.startCountdown(0, 0, startIntent, null); + verify(mCallback).onCountdownEnd(); + + // then the receiver was registered + verify(mBroadcastDispatcher).registerReceiver(eq(mController.mStateChangeReceiver), + any(), any(), any()); + + // When the receiver gets an update + Intent intent = new Intent(RecordingController.INTENT_UPDATE_STATE); + intent.putExtra(RecordingController.EXTRA_STATE, false); + mController.mStateChangeReceiver.onReceive(mContext, intent); + + // then the state is updated + assertFalse(mController.isRecording()); + verify(mCallback).onRecordingEnd(); + + // and the receiver is unregistered + verify(mBroadcastDispatcher).unregisterReceiver(eq(mController.mStateChangeReceiver)); + } + // Test that switching users will stop an ongoing recording @Test public void testUserChange() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingServiceTest.java b/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingServiceTest.java index 3e37fde84544..91cafead596c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingServiceTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingServiceTest.java @@ -17,15 +17,18 @@ package com.android.systemui.screenrecord; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import android.app.Notification; import android.app.NotificationManager; import android.content.Intent; +import android.os.RemoteException; import android.testing.AndroidTestingRunner; import androidx.test.filters.SmallTest; @@ -43,6 +46,7 @@ import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.MockitoAnnotations; +import java.io.IOException; import java.util.concurrent.Executor; @RunWith(AndroidTestingRunner.class) @@ -88,6 +92,9 @@ public class RecordingServiceTest extends SysuiTestCase { doNothing().when(mRecordingService).createRecordingNotification(); doReturn(mNotification).when(mRecordingService).createProcessingNotification(); doReturn(mNotification).when(mRecordingService).createSaveNotification(any()); + doNothing().when(mRecordingService).createErrorNotification(); + doNothing().when(mRecordingService).showErrorToast(anyInt()); + doNothing().when(mRecordingService).stopForeground(anyBoolean()); doNothing().when(mRecordingService).startForeground(anyInt(), any()); doReturn(mScreenMediaRecorder).when(mRecordingService).getRecorder(); @@ -124,4 +131,16 @@ public class RecordingServiceTest extends SysuiTestCase { .log(Events.ScreenRecordEvent.SCREEN_RECORD_END_NOTIFICATION); verify(mUiEventLogger, times(0)).log(Events.ScreenRecordEvent.SCREEN_RECORD_END_QS_TILE); } + + @Test + public void testErrorUpdatesState() throws IOException, RemoteException { + // When the screen recording does not start properly + doThrow(new RuntimeException("fail")).when(mScreenMediaRecorder).start(); + + Intent startIntent = RecordingService.getStartIntent(mContext, 0, 0, false); + mRecordingService.onStartCommand(startIntent, 0, 0); + + // Then the state is set to not recording + verify(mController).updateState(false); + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationEntryManagerInflationTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationEntryManagerInflationTest.java index dbaf5c467c45..ababebdd807c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationEntryManagerInflationTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationEntryManagerInflationTest.java @@ -44,9 +44,9 @@ import com.android.internal.statusbar.IStatusBarService; import com.android.internal.util.NotificationMessagingUtil; import com.android.systemui.R; import com.android.systemui.SysuiTestCase; +import com.android.systemui.classifier.FalsingCollectorFake; import com.android.systemui.media.MediaFeatureFlag; import com.android.systemui.media.dialog.MediaOutputDialogFactory; -import com.android.systemui.plugins.FalsingManager; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.shared.plugins.PluginManager; import com.android.systemui.statusbar.FeatureFlags; @@ -129,7 +129,6 @@ public class NotificationEntryManagerInflationTest extends SysuiTestCase { @Mock(answer = Answers.RETURNS_SELF) private ExpandableNotificationRowComponent.Builder mExpandableNotificationRowComponentBuilder; @Mock private ExpandableNotificationRowComponent mExpandableNotificationRowComponent; - @Mock private FalsingManager mFalsingManager; @Mock private KeyguardBypassController mKeyguardBypassController; @Mock private StatusBarStateController mStatusBarStateController; @@ -244,7 +243,7 @@ public class NotificationEntryManagerInflationTest extends SysuiTestCase { mGutsManager, true, null, - mFalsingManager, + new FalsingCollectorFake(), mPeopleNotificationIdentifier, Optional.of(mock(BubblesManager.class)) )); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java index baae8fda18f9..7470a13ae39e 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java @@ -45,9 +45,9 @@ import android.widget.RemoteViews; import com.android.systemui.R; import com.android.systemui.TestableDependency; +import com.android.systemui.classifier.FalsingCollectorFake; import com.android.systemui.media.MediaFeatureFlag; import com.android.systemui.media.dialog.MediaOutputDialogFactory; -import com.android.systemui.plugins.FalsingManager; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.NotificationMediaManager; import com.android.systemui.statusbar.NotificationRemoteInputManager; @@ -428,7 +428,7 @@ public class NotificationTestHelper { mock(OnExpandClickListener.class), mock(NotificationMediaManager.class), mock(ExpandableNotificationRow.CoordinateOnClickListener.class), - mock(FalsingManager.class), + new FalsingCollectorFake(), mStatusBarStateController, mPeopleNotificationIdentifier, mock(OnUserInteractionCallback.class), diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollerControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollerControllerTest.java index 01d49c269fb2..3c4fde8f6106 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollerControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollerControllerTest.java @@ -42,9 +42,9 @@ import com.android.internal.logging.UiEventLogger; import com.android.internal.logging.nano.MetricsProto; import com.android.internal.statusbar.IStatusBarService; import com.android.systemui.SysuiTestCase; +import com.android.systemui.classifier.FalsingCollectorFake; import com.android.systemui.colorextraction.SysuiColorExtractor; import com.android.systemui.media.KeyguardMediaController; -import com.android.systemui.plugins.FalsingManager; import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin; import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin.OnMenuEventListener; import com.android.systemui.plugins.statusbar.StatusBarStateController; @@ -106,7 +106,6 @@ public class NotificationStackScrollerControllerTest extends SysuiTestCase { @Mock private SysuiColorExtractor mColorExtractor; @Mock private NotificationLockscreenUserManager mNotificationLockscreenUserManager; @Mock private MetricsLogger mMetricsLogger; - @Mock private FalsingManager mFalsingManager; @Mock private Resources mResources; @Mock(answer = Answers.RETURNS_SELF) private NotificationSwipeHelper.Builder mNotificationSwipeHelperBuilder; @@ -160,7 +159,7 @@ public class NotificationStackScrollerControllerTest extends SysuiTestCase { mColorExtractor, mNotificationLockscreenUserManager, mMetricsLogger, - mFalsingManager, + new FalsingCollectorFake(), mResources, mNotificationSwipeHelperBuilder, mStatusBar, diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java index 1b05ad7f8b5b..bc014ec16103 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java @@ -50,9 +50,9 @@ import com.android.keyguard.ViewMediatorCallback; import com.android.keyguard.dagger.KeyguardBouncerComponent; import com.android.systemui.DejankUtils; import com.android.systemui.SysuiTestCase; +import com.android.systemui.classifier.FalsingCollector; import com.android.systemui.keyguard.DismissCallbackRegistry; import com.android.systemui.plugins.ActivityStarter.OnDismissAction; -import com.android.systemui.plugins.FalsingManager; import com.android.systemui.statusbar.policy.KeyguardStateController; import org.junit.Assert; @@ -72,7 +72,7 @@ import org.mockito.stubbing.Answer; public class KeyguardBouncerTest extends SysuiTestCase { @Mock - private FalsingManager mFalsingManager; + private FalsingCollector mFalsingCollector; @Mock private ViewMediatorCallback mViewMediatorCallback; @Mock @@ -128,7 +128,7 @@ public class KeyguardBouncerTest extends SysuiTestCase { final ViewGroup container = new FrameLayout(getContext()); mBouncer = new KeyguardBouncer.Factory(getContext(), mViewMediatorCallback, - mDismissCallbackRegistry, mFalsingManager, + mDismissCallbackRegistry, mFalsingCollector, mKeyguardStateController, mKeyguardUpdateMonitor, mKeyguardBypassController, mHandler, mKeyguardSecurityModel, mKeyguardBouncerComponentFactory) @@ -143,10 +143,10 @@ public class KeyguardBouncerTest extends SysuiTestCase { @Test public void testShow_notifiesFalsingManager() { mBouncer.show(true); - verify(mFalsingManager).onBouncerShown(); + verify(mFalsingCollector).onBouncerShown(); mBouncer.show(true, false); - verifyNoMoreInteractions(mFalsingManager); + verifyNoMoreInteractions(mFalsingCollector); } /** @@ -212,11 +212,11 @@ public class KeyguardBouncerTest extends SysuiTestCase { mBouncer.setExpansion(0.5f); mBouncer.setExpansion(KeyguardBouncer.EXPANSION_HIDDEN); - verify(mFalsingManager).onBouncerHidden(); + verify(mFalsingCollector).onBouncerHidden(); verify(mExpansionCallback).onFullyHidden(); mBouncer.setExpansion(KeyguardBouncer.EXPANSION_VISIBLE); - verify(mFalsingManager).onBouncerShown(); + verify(mFalsingCollector).onBouncerShown(); verify(mExpansionCallback).onFullyShown(); verify(mExpansionCallback, never()).onStartingToHide(); @@ -239,7 +239,7 @@ public class KeyguardBouncerTest extends SysuiTestCase { @Test public void testHide_notifiesFalsingManager() { mBouncer.hide(false); - verify(mFalsingManager).onBouncerHidden(); + verify(mFalsingCollector).onBouncerHidden(); } @Test diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java index 4841b3bf951f..3d582e74ea4e 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java @@ -60,10 +60,10 @@ import com.android.keyguard.dagger.KeyguardStatusViewComponent; import com.android.systemui.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.biometrics.AuthController; +import com.android.systemui.classifier.FalsingCollectorFake; import com.android.systemui.classifier.FalsingManagerFake; import com.android.systemui.doze.DozeLog; import com.android.systemui.media.MediaHierarchyManager; -import com.android.systemui.plugins.FalsingManager; import com.android.systemui.qs.QSDetailDisplayer; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.KeyguardAffordanceView; @@ -132,8 +132,6 @@ public class NotificationPanelViewTest extends SysuiTestCase { @Mock private KeyguardUpdateMonitor mUpdateMonitor; @Mock - private FalsingManager mFalsingManager; - @Mock private KeyguardBypassController mKeyguardBypassController; @Mock private DozeParameters mDozeParameters; @@ -252,7 +250,7 @@ public class NotificationPanelViewTest extends SysuiTestCase { mKeyguardBypassController, mHeadsUpManager, mock(NotificationRoundnessManager.class), mStatusBarStateController, - new FalsingManagerFake()); + new FalsingManagerFake(), new FalsingCollectorFake()); when(mKeyguardStatusViewComponentFactory.build(any())) .thenReturn(mKeyguardStatusViewComponent); when(mKeyguardStatusViewComponent.getKeyguardClockSwitchController()) @@ -263,7 +261,7 @@ public class NotificationPanelViewTest extends SysuiTestCase { mResources, mInjectionInflationController, coordinator, expansionHandler, mDynamicPrivacyController, mKeyguardBypassController, - mFalsingManager, mShadeController, + new FalsingManagerFake(), new FalsingCollectorFake(), mShadeController, mNotificationLockscreenUserManager, mNotificationEntryManager, mKeyguardStateController, mStatusBarStateController, mDozeLog, mDozeParameters, mCommandQueue, mVibratorHelper, diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewTest.java index 25af584ed3f8..e0fa9babbb48 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewTest.java @@ -30,6 +30,7 @@ import androidx.test.filters.SmallTest; import com.android.systemui.R; import com.android.systemui.SystemUIFactory; import com.android.systemui.SysuiTestCase; +import com.android.systemui.classifier.FalsingCollectorFake; import com.android.systemui.classifier.FalsingManagerFake; import com.android.systemui.dock.DockManager; import com.android.systemui.doze.DozeLog; @@ -111,6 +112,7 @@ public class NotificationShadeWindowViewTest extends SysuiTestCase { mDynamicPrivacyController, mBypassController, new FalsingManagerFake(), + new FalsingCollectorFake(), mPluginManager, mTunerService, mNotificationLockScreenUserManager, diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java index 710122d83b22..5416f75dffff 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java @@ -83,6 +83,7 @@ import com.android.systemui.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.assist.AssistManager; import com.android.systemui.broadcast.BroadcastDispatcher; +import com.android.systemui.classifier.FalsingCollectorFake; import com.android.systemui.classifier.FalsingManagerFake; import com.android.systemui.colorextraction.SysuiColorExtractor; import com.android.systemui.demomode.DemoModeController; @@ -356,6 +357,7 @@ public class StatusBarTest extends SysuiTestCase { mDynamicPrivacyController, mBypassHeadsUpNotifier, new FalsingManagerFake(), + new FalsingCollectorFake(), mBroadcastDispatcher, new RemoteInputQuickSettingsDisabler( mContext, diff --git a/packages/services/PacProcessor/AndroidManifest.xml b/packages/services/PacProcessor/AndroidManifest.xml index ad1326194a4d..533098cbdc75 100644 --- a/packages/services/PacProcessor/AndroidManifest.xml +++ b/packages/services/PacProcessor/AndroidManifest.xml @@ -3,6 +3,7 @@ package="com.android.pacprocessor"> <uses-permission android:name="android.permission.INTERNET" /> + <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <application android:label="@string/app_name" diff --git a/services/Android.bp b/services/Android.bp index eb7b72ed2cfd..1101e2ad4234 100644 --- a/services/Android.bp +++ b/services/Android.bp @@ -9,6 +9,7 @@ filegroup { name: "services-all-sources", srcs: [ ":services.core-sources", + ":services.core-sources-am-wm", ":services.accessibility-sources", ":services.appprediction-sources", ":services.appwidget-sources", diff --git a/services/companion/java/com/android/server/companion/OWNERS b/services/companion/java/com/android/server/companion/OWNERS new file mode 100644 index 000000000000..da723b3b67da --- /dev/null +++ b/services/companion/java/com/android/server/companion/OWNERS @@ -0,0 +1 @@ +eugenesusla@google.com
\ No newline at end of file diff --git a/services/core/Android.bp b/services/core/Android.bp index 069a5ea3b32f..fec7ac0dd5bd 100644 --- a/services/core/Android.bp +++ b/services/core/Android.bp @@ -1,7 +1,20 @@ filegroup { + name: "services.core-sources-am-wm", + srcs: [ + "java/com/android/server/am/**/*.java", + "java/com/android/server/wm/**/*.java", + ], + path: "java", + visibility: ["//frameworks/base/services"], +} + +filegroup { name: "services.core-sources", srcs: ["java/**/*.java"], - exclude_srcs: [":connectivity-service-srcs"], + exclude_srcs: [ + ":connectivity-service-srcs", + ":services.core-sources-am-wm" + ], path: "java", visibility: [ "//frameworks/base/services", @@ -13,7 +26,7 @@ genrule { name: "services.core.protologsrc", srcs: [ ":protolog-groups", - ":services.core-sources", + ":services.core-sources-am-wm", ], tools: ["protologtool"], cmd: "$(location protologtool) transform-protolog-calls " + @@ -23,7 +36,7 @@ genrule { "--loggroups-class com.android.internal.protolog.ProtoLogGroup " + "--loggroups-jar $(location :protolog-groups) " + "--output-srcjar $(out) " + - "$(locations :services.core-sources)", + "$(locations :services.core-sources-am-wm)", out: ["services.core.protolog.srcjar"], } @@ -31,7 +44,7 @@ genrule { name: "generate-protolog.json", srcs: [ ":protolog-groups", - ":services.core-sources", + ":services.core-sources-am-wm", ], tools: ["protologtool"], cmd: "$(location protologtool) generate-viewer-config " + @@ -39,7 +52,7 @@ genrule { "--loggroups-class com.android.internal.protolog.ProtoLogGroup " + "--loggroups-jar $(location :protolog-groups) " + "--viewer-conf $(out) " + - "$(locations :services.core-sources)", + "$(locations :services.core-sources-am-wm)", out: ["services.core.protolog.json"], } @@ -63,6 +76,7 @@ java_library_static { name: "services.core.unboosted", defaults: ["platform_service_defaults"], srcs: [ + ":services.core-sources", ":services.core.protologsrc", ":dumpstate_aidl", ":framework_native_aidl", diff --git a/services/core/java/android/app/usage/UsageStatsManagerInternal.java b/services/core/java/android/app/usage/UsageStatsManagerInternal.java index fa84427ac064..b2226d1e0fa3 100644 --- a/services/core/java/android/app/usage/UsageStatsManagerInternal.java +++ b/services/core/java/android/app/usage/UsageStatsManagerInternal.java @@ -326,4 +326,18 @@ public abstract class UsageStatsManagerInternal { * @return {@code true} if the updating was successful, {@code false} otherwise */ public abstract boolean updatePackageMappingsData(); + + /** + * Listener interface for usage events. + */ + public interface UsageEventListener { + /** Callback to inform listeners of a new usage event. */ + void onUsageEvent(@UserIdInt int userId, @NonNull UsageEvents.Event event); + } + + /** Register a listener that will be notified of every new usage event. */ + public abstract void registerListener(@NonNull UsageEventListener listener); + + /** Unregister a listener from being notified of every new usage event. */ + public abstract void unregisterListener(@NonNull UsageEventListener listener); } diff --git a/services/core/java/android/content/pm/PackageManagerInternal.java b/services/core/java/android/content/pm/PackageManagerInternal.java index f20566280bc8..6989e320f465 100644 --- a/services/core/java/android/content/pm/PackageManagerInternal.java +++ b/services/core/java/android/content/pm/PackageManagerInternal.java @@ -77,6 +77,7 @@ public abstract class PackageManagerInternal { PACKAGE_WIFI, PACKAGE_COMPANION, PACKAGE_RETAIL_DEMO, + PACKAGE_RECENTS, }) @Retention(RetentionPolicy.SOURCE) public @interface KnownPackage {} @@ -97,9 +98,10 @@ public abstract class PackageManagerInternal { public static final int PACKAGE_WIFI = 13; public static final int PACKAGE_COMPANION = 14; public static final int PACKAGE_RETAIL_DEMO = 15; + public static final int PACKAGE_RECENTS = 16; // Integer value of the last known package ID. Increases as new ID is added to KnownPackage. // Please note the numbers should be continuous. - public static final int LAST_KNOWN_PACKAGE = PACKAGE_RETAIL_DEMO; + public static final int LAST_KNOWN_PACKAGE = PACKAGE_RECENTS; @IntDef(flag = true, prefix = "RESOLVE_", value = { RESOLVE_NON_BROWSER_ONLY, @@ -1060,6 +1062,8 @@ public abstract class PackageManagerInternal { return "Retail Demo"; case PACKAGE_OVERLAY_CONFIG_SIGNATURE: return "Overlay Config Signature"; + case PACKAGE_RECENTS: + return "Recents"; } return "Unknown"; } diff --git a/services/core/java/com/android/server/PackageWatchdog.java b/services/core/java/com/android/server/PackageWatchdog.java index 735d248b12e4..f3c5fd8d1064 100644 --- a/services/core/java/com/android/server/PackageWatchdog.java +++ b/services/core/java/com/android/server/PackageWatchdog.java @@ -47,7 +47,6 @@ import android.util.Xml; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.os.BackgroundThread; -import com.android.internal.util.FastXmlSerializer; import com.android.internal.util.IndentingPrintWriter; import com.android.internal.util.XmlUtils; @@ -64,7 +63,6 @@ import java.io.IOException; import java.io.InputStream; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; -import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; @@ -129,9 +127,17 @@ public class PackageWatchdog { @VisibleForTesting static final int DEFAULT_BOOT_LOOP_TRIGGER_COUNT = 5; static final long DEFAULT_BOOT_LOOP_TRIGGER_WINDOW_MS = TimeUnit.MINUTES.toMillis(10); + + // These properties track individual system server boot events, and are reset once the boot + // threshold is met, or the boot loop trigger window is exceeded between boot events. private static final String PROP_RESCUE_BOOT_COUNT = "sys.rescue_boot_count"; private static final String PROP_RESCUE_BOOT_START = "sys.rescue_boot_start"; + // These properties track multiple calls made to observers tracking boot loops. They are reset + // when the de-escalation window is exceeded between boot events. + private static final String PROP_BOOT_MITIGATION_WINDOW_START = "sys.boot_mitigation_start"; + private static final String PROP_BOOT_MITIGATION_COUNT = "sys.boot_mitigation_count"; + private long mNumberOfNativeCrashPollsRemaining; private static final int DB_VERSION = 1; @@ -191,7 +197,6 @@ public class PackageWatchdog { @FunctionalInterface @VisibleForTesting interface SystemClock { - // TODO: Add elapsedRealtime to this interface long uptimeMillis(); } @@ -471,13 +476,14 @@ public class PackageWatchdog { synchronized (mLock) { if (mBootThreshold.incrementAndTest()) { mBootThreshold.reset(); + int mitigationCount = mBootThreshold.getMitigationCount() + 1; PackageHealthObserver currentObserverToNotify = null; int currentObserverImpact = Integer.MAX_VALUE; for (int i = 0; i < mAllObservers.size(); i++) { final ObserverInternal observer = mAllObservers.valueAt(i); PackageHealthObserver registeredObserver = observer.registeredObserver; if (registeredObserver != null) { - int impact = registeredObserver.onBootLoop(); + int impact = registeredObserver.onBootLoop(mitigationCount); if (impact != PackageHealthObserverImpact.USER_IMPACT_NONE && impact < currentObserverImpact) { currentObserverToNotify = registeredObserver; @@ -486,7 +492,8 @@ public class PackageWatchdog { } } if (currentObserverToNotify != null) { - currentObserverToNotify.executeBootLoopMitigation(); + mBootThreshold.setMitigationCount(mitigationCount); + currentObserverToNotify.executeBootLoopMitigation(mitigationCount); } } } @@ -609,15 +616,20 @@ public class PackageWatchdog { /** * Called when the system server has booted several times within a window of time, defined * by {@link #mBootThreshold} + * + * @param mitigationCount the number of times mitigation has been attempted for this + * boot loop (including this time). */ - default @PackageHealthObserverImpact int onBootLoop() { + default @PackageHealthObserverImpact int onBootLoop(int mitigationCount) { return PackageHealthObserverImpact.USER_IMPACT_NONE; } /** * Executes mitigation for {@link #onBootLoop} + * @param mitigationCount the number of times mitigation has been attempted for this + * boot loop (including this time). */ - default boolean executeBootLoopMitigation() { + default boolean executeBootLoopMitigation(int mitigationCount) { return false; } @@ -1577,7 +1589,7 @@ public class PackageWatchdog { /** * Handles the thresholding logic for system server boots. */ - static class BootThreshold { + class BootThreshold { private final int mBootTriggerCount; private final long mTriggerWindow; @@ -1604,18 +1616,44 @@ public class PackageWatchdog { return SystemProperties.getLong(PROP_RESCUE_BOOT_START, 0); } + public int getMitigationCount() { + return SystemProperties.getInt(PROP_BOOT_MITIGATION_COUNT, 0); + } + public void setStart(long start) { - final long now = android.os.SystemClock.elapsedRealtime(); + setPropertyStart(PROP_RESCUE_BOOT_START, start); + } + + public void setMitigationStart(long start) { + setPropertyStart(PROP_BOOT_MITIGATION_WINDOW_START, start); + } + + public long getMitigationStart() { + return SystemProperties.getLong(PROP_BOOT_MITIGATION_WINDOW_START, 0); + } + + public void setMitigationCount(int count) { + SystemProperties.set(PROP_BOOT_MITIGATION_COUNT, Integer.toString(count)); + } + + public void setPropertyStart(String property, long start) { + final long now = mSystemClock.uptimeMillis(); final long newStart = MathUtils.constrain(start, 0, now); - SystemProperties.set(PROP_RESCUE_BOOT_START, Long.toString(newStart)); + SystemProperties.set(property, Long.toString(newStart)); } + /** Increments the boot counter, and returns whether the device is bootlooping. */ public boolean incrementAndTest() { - final long now = android.os.SystemClock.elapsedRealtime(); + final long now = mSystemClock.uptimeMillis(); if (now - getStart() < 0) { Slog.e(TAG, "Window was less than zero. Resetting start to current time."); setStart(now); + setMitigationStart(now); + } + if (now - getMitigationStart() > DEFAULT_DEESCALATION_WINDOW_MS) { + setMitigationCount(0); + setMitigationStart(now); } final long window = now - getStart(); if (window >= mTriggerWindow) { diff --git a/services/core/java/com/android/server/RescueParty.java b/services/core/java/com/android/server/RescueParty.java index d04949ac54db..a1cf8162f0e9 100644 --- a/services/core/java/com/android/server/RescueParty.java +++ b/services/core/java/com/android/server/RescueParty.java @@ -16,6 +16,8 @@ package com.android.server; +import static android.provider.DeviceConfig.Properties; + import static com.android.server.pm.PackageManagerServiceUtils.logCriticalInfo; import android.annotation.NonNull; @@ -29,7 +31,6 @@ import android.os.Build; import android.os.Bundle; import android.os.Environment; import android.os.FileUtils; -import android.os.Process; import android.os.RecoverySystem; import android.os.RemoteCallback; import android.os.SystemClock; @@ -37,10 +38,10 @@ import android.os.SystemProperties; import android.os.UserHandle; import android.provider.DeviceConfig; import android.provider.Settings; +import android.text.TextUtils; import android.util.ArraySet; import android.util.ExceptionUtils; import android.util.Log; -import android.util.MathUtils; import android.util.Slog; import com.android.internal.annotations.GuardedBy; @@ -75,8 +76,6 @@ import java.util.concurrent.TimeUnit; public class RescueParty { @VisibleForTesting static final String PROP_ENABLE_RESCUE = "persist.sys.enable_rescue"; - @VisibleForTesting - static final String PROP_RESCUE_LEVEL = "sys.rescue_level"; static final String PROP_ATTEMPTING_FACTORY_RESET = "sys.attempting_factory_reset"; static final String PROP_MAX_RESCUE_LEVEL_ATTEMPTED = "sys.max_rescue_level_attempted"; @VisibleForTesting @@ -97,6 +96,12 @@ public class RescueParty { static final long DEFAULT_OBSERVING_DURATION_MS = TimeUnit.DAYS.toMillis(2); @VisibleForTesting static final int DEVICE_CONFIG_RESET_MODE = Settings.RESET_MODE_TRUSTED_DEFAULTS; + // The DeviceConfig namespace containing all RescueParty switches. + @VisibleForTesting + static final String NAMESPACE_CONFIGURATION = "configuration"; + @VisibleForTesting + static final String NAMESPACE_TO_PACKAGE_MAPPING_FLAG = + "namespace_to_package_mapping"; private static final String NAME = "rescue-party-observer"; @@ -107,8 +112,6 @@ public class RescueParty { "persist.device_config.configuration.disable_rescue_party"; private static final String PROP_DISABLE_FACTORY_RESET_FLAG = "persist.device_config.configuration.disable_rescue_party_factory_reset"; - // The DeviceConfig namespace containing all RescueParty switches. - private static final String NAMESPACE_CONFIGURATION = "configuration"; private static final int PERSISTENT_MASK = ApplicationInfo.FLAG_PERSISTENT | ApplicationInfo.FLAG_SYSTEM; @@ -168,13 +171,87 @@ public class RescueParty { */ public static void onSettingsProviderPublished(Context context) { handleNativeRescuePartyResets(); - executeRescueLevel(context, /*failedPackage=*/ null); ContentResolver contentResolver = context.getContentResolver(); Settings.Config.registerMonitorCallback(contentResolver, new RemoteCallback(result -> { handleMonitorCallback(context, result); })); } + + /** + * Called when {@code RollbackManager} performs Mainline module rollbacks, + * to avoid rolled back modules consuming flag values only expected to work + * on modules of newer versions. + */ + public static void resetDeviceConfigForPackages(List<String> packageNames) { + if (packageNames == null) { + return; + } + Set<String> namespacesToReset = new ArraySet<String>(); + Iterator<String> it = packageNames.iterator(); + RescuePartyObserver rescuePartyObserver = RescuePartyObserver.getInstanceIfCreated(); + // Get runtime package to namespace mapping if created. + if (rescuePartyObserver != null) { + while (it.hasNext()) { + String packageName = it.next(); + Set<String> runtimeAffectedNamespaces = + rescuePartyObserver.getAffectedNamespaceSet(packageName); + if (runtimeAffectedNamespaces != null) { + namespacesToReset.addAll(runtimeAffectedNamespaces); + } + } + } + // Get preset package to namespace mapping if created. + Set<String> presetAffectedNamespaces = getPresetNamespacesForPackages( + packageNames); + if (presetAffectedNamespaces != null) { + namespacesToReset.addAll(presetAffectedNamespaces); + } + + // Clear flags under the namespaces mapped to these packages. + // Using setProperties since DeviceConfig.resetToDefaults bans the current flag set. + Iterator<String> namespaceIt = namespacesToReset.iterator(); + while (namespaceIt.hasNext()) { + String namespaceToReset = namespaceIt.next(); + Properties properties = new Properties.Builder(namespaceToReset).build(); + try { + DeviceConfig.setProperties(properties); + } catch (DeviceConfig.BadConfigException exception) { + logCriticalInfo(Log.WARN, "namespace " + namespaceToReset + + " is already banned, skip reset."); + } + } + } + + private static Set<String> getPresetNamespacesForPackages(List<String> packageNames) { + Set<String> resultSet = new ArraySet<String>(); + try { + String flagVal = DeviceConfig.getString(NAMESPACE_CONFIGURATION, + NAMESPACE_TO_PACKAGE_MAPPING_FLAG, ""); + String[] mappingEntries = flagVal.split(","); + for (int i = 0; i < mappingEntries.length; i++) { + if (TextUtils.isEmpty(mappingEntries[i])) { + continue; + } + String[] splittedEntry = mappingEntries[i].split(":"); + if (splittedEntry.length != 2) { + throw new RuntimeException("Invalid mapping entry: " + mappingEntries[i]); + } + String namespace = splittedEntry[0]; + String packageName = splittedEntry[1]; + + if (packageNames.contains(packageName)) { + resultSet.add(namespace); + } + } + } catch (Exception e) { + resultSet.clear(); + Slog.e(TAG, "Failed to read preset package to namespaces mapping.", e); + } finally { + return resultSet; + } + } + @VisibleForTesting static long getElapsedRealtime() { return SystemClock.elapsedRealtime(); @@ -260,33 +337,6 @@ public class RescueParty { } } - /** - * Get the next rescue level. This indicates the next level of mitigation that may be taken. - */ - private static int getNextRescueLevel() { - return MathUtils.constrain(SystemProperties.getInt(PROP_RESCUE_LEVEL, LEVEL_NONE) + 1, - LEVEL_NONE, getMaxRescueLevel()); - } - - /** - * Escalate to the next rescue level. After incrementing the level you'll - * probably want to call {@link #executeRescueLevel(Context, String)}. - */ - private static void incrementRescueLevel(int triggerUid) { - final int level = getNextRescueLevel(); - SystemProperties.set(PROP_RESCUE_LEVEL, Integer.toString(level)); - - EventLogTags.writeRescueLevel(level, triggerUid); - logCriticalInfo(Log.WARN, "Incremented rescue level to " - + levelToString(level) + " triggered by UID " + triggerUid); - } - - private static void executeRescueLevel(Context context, @Nullable String failedPackage) { - final int level = SystemProperties.getInt(PROP_RESCUE_LEVEL, LEVEL_NONE); - if (level == LEVEL_NONE) return; - executeRescueLevel(context, failedPackage, level); - } - private static void executeRescueLevel(Context context, @Nullable String failedPackage, int level) { Slog.w(TAG, "Attempting rescue level " + levelToString(level)); @@ -501,6 +551,14 @@ public class RescueParty { } } + /** Gets singleton instance. It returns null if the instance is not created yet.*/ + @Nullable + public static RescuePartyObserver getInstanceIfCreated() { + synchronized (RescuePartyObserver.class) { + return sRescuePartyObserver; + } + } + @VisibleForTesting static void reset() { synchronized (RescuePartyObserver.class) { @@ -561,20 +619,19 @@ public class RescueParty { } @Override - public int onBootLoop() { + public int onBootLoop(int mitigationCount) { if (isDisabled()) { return PackageHealthObserverImpact.USER_IMPACT_NONE; } - return mapRescueLevelToUserImpact(getNextRescueLevel()); + return mapRescueLevelToUserImpact(getRescueLevel(mitigationCount)); } @Override - public boolean executeBootLoopMitigation() { + public boolean executeBootLoopMitigation(int mitigationCount) { if (isDisabled()) { return false; } - incrementRescueLevel(Process.ROOT_UID); - executeRescueLevel(mContext, /*failedPackage=*/ null); + executeRescueLevel(mContext, /*failedPackage=*/ null, getRescueLevel(mitigationCount)); return true; } diff --git a/services/core/java/com/android/server/VibratorManagerService.java b/services/core/java/com/android/server/VibratorManagerService.java index 356cd0cd937b..f1f2815be8fa 100644 --- a/services/core/java/com/android/server/VibratorManagerService.java +++ b/services/core/java/com/android/server/VibratorManagerService.java @@ -159,7 +159,7 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { pw.println(" Prints this help text."); pw.println(""); pw.println(" list"); - pw.println(" Prints the id of device vibrators. This do not include any "); + pw.println(" Prints the id of device vibrators. This does not include any "); pw.println(" connected input device."); pw.println(""); } diff --git a/services/core/java/com/android/server/VibratorService.java b/services/core/java/com/android/server/VibratorService.java index 63fba25a3785..db2b4e4edd2b 100644 --- a/services/core/java/com/android/server/VibratorService.java +++ b/services/core/java/com/android/server/VibratorService.java @@ -16,8 +16,6 @@ package com.android.server; -import static android.os.VibrationEffect.Composition.PrimitiveEffect; - import android.annotation.Nullable; import android.app.ActivityManager; import android.app.AppOpsManager; @@ -28,8 +26,6 @@ import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageManager; import android.content.pm.PackageManagerInternal; -import android.content.res.Resources; -import android.hardware.input.InputManager; import android.hardware.vibrator.IVibrator; import android.os.BatteryStats; import android.os.Binder; @@ -45,7 +41,6 @@ import android.os.PowerManager.ServiceType; import android.os.PowerManagerInternal; import android.os.PowerSaveState; import android.os.Process; -import android.os.RemoteCallbackList; import android.os.RemoteException; import android.os.ResultReceiver; import android.os.ServiceManager; @@ -60,38 +55,33 @@ import android.os.WorkSource; import android.util.Slog; import android.util.SparseArray; import android.util.proto.ProtoOutputStream; -import android.view.InputDevice; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.app.IBatteryStats; import com.android.internal.util.DumpUtils; import com.android.internal.util.FrameworkStatsLog; +import com.android.server.vibrator.InputDeviceDelegate; +import com.android.server.vibrator.Vibration; import com.android.server.vibrator.VibrationScaler; import com.android.server.vibrator.VibrationSettings; - -import libcore.util.NativeAllocationRegistry; +import com.android.server.vibrator.VibratorController; +import com.android.server.vibrator.VibratorController.OnVibrationCompleteListener; import java.io.FileDescriptor; import java.io.PrintWriter; -import java.text.SimpleDateFormat; +import java.lang.ref.WeakReference; import java.util.ArrayList; -import java.util.Arrays; -import java.util.Date; import java.util.LinkedList; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; -public class VibratorService extends IVibratorService.Stub - implements InputManager.InputDeviceListener { +/** System implementation of {@link IVibratorService}. */ +public class VibratorService extends IVibratorService.Stub { private static final String TAG = "VibratorService"; - private static final SimpleDateFormat DEBUG_DATE_FORMAT = - new SimpleDateFormat("MM-dd HH:mm:ss.SSS"); private static final boolean DEBUG = false; private static final String EXTERNAL_VIBRATOR_SERVICE = "external_vibrator_service"; - private static final long[] DOUBLE_CLICK_EFFECT_FALLBACK_TIMINGS = { 0, 30, 100, 30 }; - // Default vibration attributes. Used when vibration is requested without attributes private static final VibrationAttributes DEFAULT_ATTRIBUTES = new VibrationAttributes.Builder().build(); @@ -99,22 +89,17 @@ public class VibratorService extends IVibratorService.Stub // Used to generate globally unique vibration ids. private final AtomicInteger mNextVibrationId = new AtomicInteger(1); // 0 = no callback - private final LinkedList<VibrationInfo> mPreviousRingVibrations; - private final LinkedList<VibrationInfo> mPreviousNotificationVibrations; - private final LinkedList<VibrationInfo> mPreviousAlarmVibrations; - private final LinkedList<VibrationInfo> mPreviousExternalVibrations; - private final LinkedList<VibrationInfo> mPreviousVibrations; + private final LinkedList<Vibration.DebugInfo> mPreviousRingVibrations; + private final LinkedList<Vibration.DebugInfo> mPreviousNotificationVibrations; + private final LinkedList<Vibration.DebugInfo> mPreviousAlarmVibrations; + private final LinkedList<Vibration.DebugInfo> mPreviousExternalVibrations; + private final LinkedList<Vibration.DebugInfo> mPreviousVibrations; private final int mPreviousVibrationsLimit; - private final boolean mAllowPriorityVibrationsInLowPowerMode; - private final List<Integer> mSupportedEffects; - private final List<Integer> mSupportedPrimitives; - private final long mCapabilities; - private final int mDefaultVibrationAmplitude; - private final SparseArray<VibrationEffect> mFallbackEffects; private final SparseArray<Integer> mProcStatesCache = new SparseArray<>(); private final WorkSource mTmpWorkSource = new WorkSource(); private final Handler mH; private final Object mLock = new Object(); + private final VibratorController mVibratorController; private final Context mContext; private final PowerManager.WakeLock mWakeLock; @@ -122,61 +107,21 @@ public class VibratorService extends IVibratorService.Stub private final IBatteryStats mBatteryStatsService; private final String mSystemUiPackage; private PowerManagerInternal mPowerManagerInternal; - private InputManager mIm; private VibrationSettings mVibrationSettings; private VibrationScaler mVibrationScaler; + private InputDeviceDelegate mInputDeviceDelegate; - private final NativeWrapper mNativeWrapper; private volatile VibrateWaveformThread mThread; - // mInputDeviceVibrators lock should be acquired after mLock, if both are - // to be acquired - private final ArrayList<Vibrator> mInputDeviceVibrators = new ArrayList<>(); - private boolean mVibrateInputDevicesSetting; // guarded by mInputDeviceVibrators - private boolean mInputDeviceListenerRegistered; // guarded by mInputDeviceVibrators - @GuardedBy("mLock") private Vibration mCurrentVibration; + @GuardedBy("mLock") + private VibrationDeathRecipient mCurrentVibrationDeathRecipient; private int mCurVibUid = -1; private ExternalVibrationHolder mCurrentExternalVibration; - private boolean mVibratorUnderExternalControl; private boolean mLowPowerMode; - @GuardedBy("mLock") - private boolean mIsVibrating; - @GuardedBy("mLock") - private final RemoteCallbackList<IVibratorStateListener> mVibratorStateListeners = - new RemoteCallbackList<>(); private SparseArray<Vibration> mAlwaysOnEffects = new SparseArray<>(); - static native long vibratorInit(OnCompleteListener listener); - - static native long vibratorGetFinalizer(); - - static native boolean vibratorExists(long nativeServicePtr); - - static native void vibratorOn(long nativeServicePtr, long milliseconds, long vibrationId); - - static native void vibratorOff(long nativeServicePtr); - - static native void vibratorSetAmplitude(long nativeServicePtr, int amplitude); - - static native int[] vibratorGetSupportedEffects(long nativeServicePtr); - - static native int[] vibratorGetSupportedPrimitives(long nativeServicePtr); - - static native long vibratorPerformEffect( - long nativeServicePtr, long effect, long strength, long vibrationId); - - static native void vibratorPerformComposedEffect(long nativeServicePtr, - VibrationEffect.Composition.PrimitiveEffect[] effect, long vibrationId); - - static native void vibratorSetExternalControl(long nativeServicePtr, boolean enabled); - - static native long vibratorGetCapabilities(long nativeServicePtr); - static native void vibratorAlwaysOnEnable(long nativeServicePtr, long id, long effect, - long strength); - static native void vibratorAlwaysOnDisable(long nativeServicePtr, long id); - private final IUidObserver mUidObserver = new IUidObserver.Stub() { @Override public void onUidStateChanged(int uid, int procState, long procStateSeq, int capability) { @@ -187,118 +132,65 @@ public class VibratorService extends IVibratorService.Stub mProcStatesCache.delete(uid); } - @Override public void onUidActive(int uid) { + @Override + public void onUidActive(int uid) { } - @Override public void onUidIdle(int uid, boolean disabled) { + @Override + public void onUidIdle(int uid, boolean disabled) { } - @Override public void onUidCachedChanged(int uid, boolean cached) { + @Override + public void onUidCachedChanged(int uid, boolean cached) { } }; - /** Listener for vibration completion callbacks from native. */ - public interface OnCompleteListener { + /** + * Implementation of {@link OnVibrationCompleteListener} with a weak reference to this service. + */ + private static final class VibrationCompleteListener implements OnVibrationCompleteListener { + private WeakReference<VibratorService> mServiceRef; + + VibrationCompleteListener(VibratorService service) { + mServiceRef = new WeakReference<>(service); + } - /** Callback triggered when vibration is complete, identified by {@link Vibration#id}. */ - void onComplete(long vibrationId); + @Override + public void onComplete(int vibratorId, long vibrationId) { + VibratorService service = mServiceRef.get(); + if (service != null) { + service.onVibrationComplete(vibrationId); + } + } } - /** Holder for a {@link VibrationEffect}. */ - private final class Vibration implements IBinder.DeathRecipient { - - public final IBinder token; - // Start time in CLOCK_BOOTTIME base. - public final long startTime; - public final VibrationAttributes attrs; - public final long id; - public final int uid; - public final String opPkg; - public final String reason; - - // The actual effect to be played. - public VibrationEffect effect; - // The original effect that was requested. Typically these two things differ because - // the effect was scaled based on the users vibration intensity settings. - public VibrationEffect originalEffect; - // The scale applied to the original effect. - public float scale; - - // Start/end times in unix epoch time. Only to be used for debugging purposes and to - // correlate with other system events, any duration calculations should be done use - // startTime so as not to be affected by discontinuities created by RTC adjustments. - private final long mStartTimeDebug; - private long mEndTimeDebug; - private VibrationInfo.Status mStatus; - - private Vibration(IBinder token, VibrationEffect effect, - VibrationAttributes attrs, int uid, String opPkg, String reason) { - this.token = token; - this.effect = effect; - this.id = mNextVibrationId.getAndIncrement(); - this.startTime = SystemClock.elapsedRealtime(); - this.attrs = attrs; - this.uid = uid; - this.opPkg = opPkg; - this.reason = reason; - mStartTimeDebug = System.currentTimeMillis(); - mStatus = VibrationInfo.Status.RUNNING; + /** Death recipient to bind {@link Vibration}. */ + private final class VibrationDeathRecipient implements IBinder.DeathRecipient { + + private final Vibration mVibration; + + private VibrationDeathRecipient(Vibration vibration) { + mVibration = vibration; } @Override public void binderDied() { synchronized (mLock) { - if (this == mCurrentVibration) { + if (mVibration == mCurrentVibration) { if (DEBUG) { Slog.d(TAG, "Vibration finished because binder died, cleaning up"); } - doCancelVibrateLocked(VibrationInfo.Status.CANCELLED); + doCancelVibrateLocked(Vibration.Status.CANCELLED); } } } - public void end(VibrationInfo.Status status) { - if (hasEnded()) { - // Vibration already ended, keep first ending status set and ignore this one. - return; - } - mStatus = status; - mEndTimeDebug = System.currentTimeMillis(); - } - - public boolean hasEnded() { - return mStatus != VibrationInfo.Status.RUNNING; - } - - public boolean hasTimeoutLongerThan(long millis) { - final long duration = effect.getDuration(); - return duration >= 0 && duration > millis; - } - - public boolean isHapticFeedback() { - return VibratorService.this.isHapticFeedback(attrs.getUsage()); - } - - public boolean isNotification() { - return VibratorService.this.isNotification(attrs.getUsage()); + private void linkToDeath() throws RemoteException { + mVibration.token.linkToDeath(this, 0); } - public boolean isRingtone() { - return VibratorService.this.isRingtone(attrs.getUsage()); - } - - public boolean isAlarm() { - return VibratorService.this.isAlarm(attrs.getUsage()); - } - - public boolean isFromSystem() { - return uid == Process.SYSTEM_UID || uid == 0 || mSystemUiPackage.equals(opPkg); - } - - public VibrationInfo toInfo() { - return new VibrationInfo( - mStartTimeDebug, mEndTimeDebug, effect, originalEffect, scale, attrs, - uid, opPkg, reason, mStatus); + private void unlinkToDeath() { + mVibration.token.unlinkToDeath(this, 0); } } @@ -310,17 +202,17 @@ public class VibratorService extends IVibratorService.Stub private final long mStartTimeDebug; private long mEndTimeDebug; - private VibrationInfo.Status mStatus; + private Vibration.Status mStatus; private ExternalVibrationHolder(ExternalVibration externalVibration) { this.externalVibration = externalVibration; this.scale = IExternalVibratorService.SCALE_NONE; mStartTimeDebug = System.currentTimeMillis(); - mStatus = VibrationInfo.Status.RUNNING; + mStatus = Vibration.Status.RUNNING; } - public void end(VibrationInfo.Status status) { - if (mStatus != VibrationInfo.Status.RUNNING) { + public void end(Vibration.Status status) { + if (mStatus != Vibration.Status.RUNNING) { // Vibration already ended, keep first ending status set and ignore this one. return; } @@ -328,8 +220,8 @@ public class VibratorService extends IVibratorService.Stub mEndTimeDebug = System.currentTimeMillis(); } - public VibrationInfo toInfo() { - return new VibrationInfo( + public Vibration.DebugInfo getDebugInfo() { + return new Vibration.DebugInfo( mStartTimeDebug, mEndTimeDebug, /* effect= */ null, /* originalEffect= */ null, scale, externalVibration.getVibrationAttributes(), externalVibration.getUid(), externalVibration.getPackage(), @@ -337,176 +229,19 @@ public class VibratorService extends IVibratorService.Stub } } - /** Debug information about vibrations. */ - private static class VibrationInfo { - - public enum Status { - RUNNING, - FINISHED, - CANCELLED, - ERROR_APP_OPS, - IGNORED, - IGNORED_APP_OPS, - IGNORED_BACKGROUND, - IGNORED_RINGTONE, - IGNORED_UNKNOWN_VIBRATION, - IGNORED_UNSUPPORTED, - IGNORED_FOR_ALARM, - IGNORED_FOR_EXTERNAL, - IGNORED_FOR_ONGOING, - IGNORED_FOR_POWER, - IGNORED_FOR_SETTINGS, - } - - private final long mStartTimeDebug; - private final long mEndTimeDebug; - private final VibrationEffect mEffect; - private final VibrationEffect mOriginalEffect; - private final float mScale; - private final VibrationAttributes mAttrs; - private final int mUid; - private final String mOpPkg; - private final String mReason; - private final VibrationInfo.Status mStatus; - - VibrationInfo(long startTimeDebug, long endTimeDebug, VibrationEffect effect, - VibrationEffect originalEffect, float scale, VibrationAttributes attrs, - int uid, String opPkg, String reason, VibrationInfo.Status status) { - mStartTimeDebug = startTimeDebug; - mEndTimeDebug = endTimeDebug; - mEffect = effect; - mOriginalEffect = originalEffect; - mScale = scale; - mAttrs = attrs; - mUid = uid; - mOpPkg = opPkg; - mReason = reason; - mStatus = status; - } - - @Override - public String toString() { - return new StringBuilder() - .append("startTime: ") - .append(DEBUG_DATE_FORMAT.format(new Date(mStartTimeDebug))) - .append(", endTime: ") - .append(mEndTimeDebug == 0 ? null - : DEBUG_DATE_FORMAT.format(new Date(mEndTimeDebug))) - .append(", status: ") - .append(mStatus.name().toLowerCase()) - .append(", effect: ") - .append(mEffect) - .append(", originalEffect: ") - .append(mOriginalEffect) - .append(", scale: ") - .append(String.format("%.2f", mScale)) - .append(", attrs: ") - .append(mAttrs) - .append(", uid: ") - .append(mUid) - .append(", opPkg: ") - .append(mOpPkg) - .append(", reason: ") - .append(mReason) - .toString(); - } - - void dumpProto(ProtoOutputStream proto, long fieldId) { - final long token = proto.start(fieldId); - proto.write(VibrationProto.START_TIME, mStartTimeDebug); - proto.write(VibrationProto.END_TIME, mEndTimeDebug); - proto.write(VibrationProto.STATUS, mStatus.ordinal()); - - final long attrsToken = proto.start(VibrationProto.ATTRIBUTES); - proto.write(VibrationAttributesProto.USAGE, mAttrs.getUsage()); - proto.write(VibrationAttributesProto.AUDIO_USAGE, mAttrs.getAudioUsage()); - proto.write(VibrationAttributesProto.FLAGS, mAttrs.getFlags()); - proto.end(attrsToken); - - if (mEffect != null) { - dumpEffect(proto, VibrationProto.EFFECT, mEffect); - } - if (mOriginalEffect != null) { - dumpEffect(proto, VibrationProto.ORIGINAL_EFFECT, mOriginalEffect); - } - - proto.end(token); - } - - private void dumpEffect(ProtoOutputStream proto, long fieldId, VibrationEffect effect) { - final long token = proto.start(fieldId); - if (effect instanceof VibrationEffect.OneShot) { - dumpEffect(proto, VibrationEffectProto.ONESHOT, (VibrationEffect.OneShot) effect); - } else if (effect instanceof VibrationEffect.Waveform) { - dumpEffect(proto, VibrationEffectProto.WAVEFORM, (VibrationEffect.Waveform) effect); - } else if (effect instanceof VibrationEffect.Prebaked) { - dumpEffect(proto, VibrationEffectProto.PREBAKED, (VibrationEffect.Prebaked) effect); - } else if (effect instanceof VibrationEffect.Composed) { - dumpEffect(proto, VibrationEffectProto.COMPOSED, (VibrationEffect.Composed) effect); - } - proto.end(token); - } - - private void dumpEffect(ProtoOutputStream proto, long fieldId, - VibrationEffect.OneShot effect) { - final long token = proto.start(fieldId); - proto.write(OneShotProto.DURATION, (int) effect.getDuration()); - proto.write(OneShotProto.AMPLITUDE, effect.getAmplitude()); - proto.end(token); - } - - private void dumpEffect(ProtoOutputStream proto, long fieldId, - VibrationEffect.Waveform effect) { - final long token = proto.start(fieldId); - for (long timing : effect.getTimings()) { - proto.write(WaveformProto.TIMINGS, (int) timing); - } - for (int amplitude : effect.getAmplitudes()) { - proto.write(WaveformProto.AMPLITUDES, amplitude); - } - proto.write(WaveformProto.REPEAT, effect.getRepeatIndex() >= 0); - proto.end(token); - } - - private void dumpEffect(ProtoOutputStream proto, long fieldId, - VibrationEffect.Prebaked effect) { - final long token = proto.start(fieldId); - proto.write(PrebakedProto.EFFECT_ID, effect.getId()); - proto.write(PrebakedProto.EFFECT_STRENGTH, effect.getEffectStrength()); - proto.write(PrebakedProto.FALLBACK, effect.shouldFallback()); - proto.end(token); - } - - private void dumpEffect(ProtoOutputStream proto, long fieldId, - VibrationEffect.Composed effect) { - final long token = proto.start(fieldId); - for (PrimitiveEffect primitive : effect.getPrimitiveEffects()) { - proto.write(ComposedProto.EFFECT_IDS, primitive.id); - proto.write(ComposedProto.EFFECT_SCALES, primitive.scale); - proto.write(ComposedProto.DELAYS, primitive.delay); - } - proto.end(token); - } - } - VibratorService(Context context) { this(context, new Injector()); } @VisibleForTesting VibratorService(Context context, Injector injector) { - mNativeWrapper = injector.getNativeWrapper(); mH = injector.createHandler(Looper.myLooper()); - - mNativeWrapper.vibratorInit(this::onVibrationComplete); + mVibratorController = injector.createVibratorController( + new VibrationCompleteListener(this)); // Reset the hardware to a default state, in case this is a runtime // restart instead of a fresh boot. - mNativeWrapper.vibratorOff(); - - mSupportedEffects = asList(mNativeWrapper.vibratorGetSupportedEffects()); - mSupportedPrimitives = asList(mNativeWrapper.vibratorGetSupportedPrimitives()); - mCapabilities = mNativeWrapper.vibratorGetCapabilities(); + mVibratorController.off(); mContext = context; PowerManager pm = context.getSystemService(PowerManager.class); @@ -522,12 +257,6 @@ public class VibratorService extends IVibratorService.Stub mPreviousVibrationsLimit = mContext.getResources().getInteger( com.android.internal.R.integer.config_previousVibrationsDumpLimit); - mDefaultVibrationAmplitude = mContext.getResources().getInteger( - com.android.internal.R.integer.config_defaultVibrationAmplitude); - - mAllowPriorityVibrationsInLowPowerMode = mContext.getResources().getBoolean( - com.android.internal.R.bool.config_allowPriorityVibrationsInLowPowerMode); - mPreviousRingVibrations = new LinkedList<>(); mPreviousNotificationVibrations = new LinkedList<>(); mPreviousAlarmVibrations = new LinkedList<>(); @@ -538,48 +267,15 @@ public class VibratorService extends IVibratorService.Stub filter.addAction(Intent.ACTION_SCREEN_OFF); context.registerReceiver(mIntentReceiver, filter); - VibrationEffect clickEffect = createEffectFromResource( - com.android.internal.R.array.config_virtualKeyVibePattern); - VibrationEffect doubleClickEffect = VibrationEffect.createWaveform( - DOUBLE_CLICK_EFFECT_FALLBACK_TIMINGS, -1 /*repeatIndex*/); - VibrationEffect heavyClickEffect = createEffectFromResource( - com.android.internal.R.array.config_longPressVibePattern); - VibrationEffect tickEffect = createEffectFromResource( - com.android.internal.R.array.config_clockTickVibePattern); - - mFallbackEffects = new SparseArray<>(); - mFallbackEffects.put(VibrationEffect.EFFECT_CLICK, clickEffect); - mFallbackEffects.put(VibrationEffect.EFFECT_DOUBLE_CLICK, doubleClickEffect); - mFallbackEffects.put(VibrationEffect.EFFECT_TICK, tickEffect); - mFallbackEffects.put(VibrationEffect.EFFECT_HEAVY_CLICK, heavyClickEffect); - - mFallbackEffects.put(VibrationEffect.EFFECT_TEXTURE_TICK, - VibrationEffect.get(VibrationEffect.EFFECT_TICK, false)); - injector.addService(EXTERNAL_VIBRATOR_SERVICE, new ExternalVibratorService()); } - private VibrationEffect createEffectFromResource(int resId) { - long[] timings = getLongIntArray(mContext.getResources(), resId); - return createEffectFromTimings(timings); - } - - private static VibrationEffect createEffectFromTimings(long[] timings) { - if (timings == null || timings.length == 0) { - return null; - } else if (timings.length == 1) { - return VibrationEffect.createOneShot(timings[0], VibrationEffect.DEFAULT_AMPLITUDE); - } else { - return VibrationEffect.createWaveform(timings, -1); - } - } - public void systemReady() { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "VibratorService#systemReady"); try { - mIm = mContext.getSystemService(InputManager.class); mVibrationSettings = new VibrationSettings(mContext, mH); mVibrationScaler = new VibrationScaler(mContext, mVibrationSettings); + mInputDeviceDelegate = new InputDeviceDelegate(mContext, mH); mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class); mPowerManagerInternal.registerLowPowerModeObserver( @@ -626,14 +322,19 @@ public class VibratorService extends IVibratorService.Stub if (DEBUG) { Slog.d(TAG, "Vibration finished by callback, cleaning up"); } - doCancelVibrateLocked(VibrationInfo.Status.FINISHED); + doCancelVibrateLocked(Vibration.Status.FINISHED); } } } @Override // Binder call public boolean hasVibrator() { - return doVibratorExists(); + // For now, we choose to ignore the presence of input devices that have vibrators + // when reporting whether the device has a vibrator. Applications often use this + // information to decide whether to enable certain features so they expect the + // result of hasVibrator() to be constant. For now, just report whether + // the device has a built-in vibrator. + return mVibratorController.isAvailable(); } @Override // Binder call @@ -641,32 +342,7 @@ public class VibratorService extends IVibratorService.Stub if (!hasPermission(android.Manifest.permission.ACCESS_VIBRATOR_STATE)) { throw new SecurityException("Requires ACCESS_VIBRATOR_STATE permission"); } - synchronized (mLock) { - return mIsVibrating; - } - } - - @GuardedBy("mLock") - private void notifyStateListenerLocked(IVibratorStateListener listener) { - try { - listener.onVibrating(mIsVibrating); - } catch (RemoteException | RuntimeException e) { - Slog.e(TAG, "Vibrator callback failed to call", e); - } - } - - @GuardedBy("mLock") - private void notifyStateListenersLocked() { - final int length = mVibratorStateListeners.beginBroadcast(); - try { - for (int i = 0; i < length; i++) { - final IVibratorStateListener listener = - mVibratorStateListeners.getBroadcastItem(i); - notifyStateListenerLocked(listener); - } - } finally { - mVibratorStateListeners.finishBroadcast(); - } + return mVibratorController.isVibrating(); } @Override // Binder call @@ -674,19 +350,7 @@ public class VibratorService extends IVibratorService.Stub if (!hasPermission(android.Manifest.permission.ACCESS_VIBRATOR_STATE)) { throw new SecurityException("Requires ACCESS_VIBRATOR_STATE permission"); } - synchronized (mLock) { - final long token = Binder.clearCallingIdentity(); - try { - if (!mVibratorStateListeners.register(listener)) { - return false; - } - // Notify its callback after new client registered. - notifyStateListenerLocked(listener); - return true; - } finally { - Binder.restoreCallingIdentity(token); - } - } + return mVibratorController.registerVibratorStateListener(listener); } @Override // Binder call @@ -695,54 +359,26 @@ public class VibratorService extends IVibratorService.Stub if (!hasPermission(android.Manifest.permission.ACCESS_VIBRATOR_STATE)) { throw new SecurityException("Requires ACCESS_VIBRATOR_STATE permission"); } - synchronized (mLock) { - final long token = Binder.clearCallingIdentity(); - try { - return mVibratorStateListeners.unregister(listener); - } finally { - Binder.restoreCallingIdentity(token); - } - } + return mVibratorController.unregisterVibratorStateListener(listener); } @Override // Binder call public boolean hasAmplitudeControl() { - synchronized (mInputDeviceVibrators) { - // Input device vibrators don't support amplitude controls yet, but are still used over - // the system vibrator when connected. - return hasCapability(IVibrator.CAP_AMPLITUDE_CONTROL) - && mInputDeviceVibrators.isEmpty(); - } + // Input device vibrators always support amplitude controls. + return mInputDeviceDelegate.isAvailable() + || mVibratorController.hasCapability(IVibrator.CAP_AMPLITUDE_CONTROL); } @Override // Binder call public int[] areEffectsSupported(int[] effectIds) { - int[] supported = new int[effectIds.length]; - if (mSupportedEffects == null) { - Arrays.fill(supported, Vibrator.VIBRATION_EFFECT_SUPPORT_UNKNOWN); - } else { - for (int i = 0; i < effectIds.length; i++) { - supported[i] = mSupportedEffects.contains(effectIds[i]) - ? Vibrator.VIBRATION_EFFECT_SUPPORT_YES - : Vibrator.VIBRATION_EFFECT_SUPPORT_NO; - } - } - return supported; + return mVibratorController.areEffectsSupported(effectIds); } @Override // Binder call public boolean[] arePrimitivesSupported(int[] primitiveIds) { - boolean[] supported = new boolean[primitiveIds.length]; - if (!hasCapability(IVibrator.CAP_COMPOSE_EFFECTS) || mSupportedPrimitives == null) { - return supported; - } - for (int i = 0; i < primitiveIds.length; i++) { - supported[i] = mSupportedPrimitives.contains(primitiveIds[i]); - } - return supported; + return mVibratorController.arePrimitivesSupported(primitiveIds); } - private static List<Integer> asList(int... vals) { if (vals == null) { return null; @@ -760,14 +396,14 @@ public class VibratorService extends IVibratorService.Stub if (!hasPermission(android.Manifest.permission.VIBRATE_ALWAYS_ON)) { throw new SecurityException("Requires VIBRATE_ALWAYS_ON permission"); } - if (!hasCapability(IVibrator.CAP_ALWAYS_ON_CONTROL)) { + if (!mVibratorController.hasCapability(IVibrator.CAP_ALWAYS_ON_CONTROL)) { Slog.e(TAG, "Always-on effects not supported."); return false; } if (effect == null) { synchronized (mLock) { mAlwaysOnEffects.delete(alwaysOnId); - mNativeWrapper.vibratorAlwaysOnDisable(alwaysOnId); + mVibratorController.updateAlwaysOn(alwaysOnId, /* effect= */ null); } } else { if (!verifyVibrationEffect(effect)) { @@ -779,7 +415,8 @@ public class VibratorService extends IVibratorService.Stub } attrs = fixupVibrationAttributes(attrs); synchronized (mLock) { - Vibration vib = new Vibration(null, effect, attrs, uid, opPkg, null); + Vibration vib = new Vibration(null, mNextVibrationId.getAndIncrement(), effect, + attrs, uid, opPkg, null); mAlwaysOnEffects.put(alwaysOnId, vib); updateAlwaysOnLocked(alwaysOnId, vib); } @@ -839,18 +476,6 @@ public class VibratorService extends IVibratorService.Stub return attrs; } - private static long[] getLongIntArray(Resources r, int resid) { - int[] ar = r.getIntArray(resid); - if (ar == null) { - return null; - } - long[] out = new long[ar.length]; - for (int i = 0; i < ar.length; i++) { - out[i] = ar[i]; - } - return out; - } - @Override // Binder call public void vibrate(int uid, String opPkg, VibrationEffect effect, @Nullable VibrationAttributes attrs, String reason, IBinder token) { @@ -869,24 +494,26 @@ public class VibratorService extends IVibratorService.Stub } attrs = fixupVibrationAttributes(attrs); - Vibration vib = new Vibration(token, effect, attrs, uid, opPkg, reason); + Vibration vib = new Vibration(token, mNextVibrationId.getAndIncrement(), effect, attrs, + uid, opPkg, reason); // If our current vibration is longer than the new vibration and is the same amplitude, // then just let the current one finish. synchronized (mLock) { + VibrationEffect currentEffect = + mCurrentVibration == null ? null : mCurrentVibration.getEffect(); if (effect instanceof VibrationEffect.OneShot - && mCurrentVibration != null - && mCurrentVibration.effect instanceof VibrationEffect.OneShot) { + && currentEffect instanceof VibrationEffect.OneShot) { VibrationEffect.OneShot newOneShot = (VibrationEffect.OneShot) effect; VibrationEffect.OneShot currentOneShot = - (VibrationEffect.OneShot) mCurrentVibration.effect; - if (mCurrentVibration.hasTimeoutLongerThan(newOneShot.getDuration()) + (VibrationEffect.OneShot) currentEffect; + if (currentOneShot.getDuration() > newOneShot.getDuration() && newOneShot.getAmplitude() == currentOneShot.getAmplitude()) { if (DEBUG) { Slog.d(TAG, "Ignoring incoming vibration in favor of current vibration"); } - endVibrationLocked(vib, VibrationInfo.Status.IGNORED_FOR_ONGOING); + endVibrationLocked(vib, Vibration.Status.IGNORED_FOR_ONGOING); return; } } @@ -898,7 +525,7 @@ public class VibratorService extends IVibratorService.Stub if (DEBUG) { Slog.d(TAG, "Ignoring incoming vibration for current external vibration"); } - endVibrationLocked(vib, VibrationInfo.Status.IGNORED_FOR_EXTERNAL); + endVibrationLocked(vib, Vibration.Status.IGNORED_FOR_EXTERNAL); return; } @@ -908,32 +535,32 @@ public class VibratorService extends IVibratorService.Stub // alarms, in favor of one-shot vibrations that are likely quite short. if (!isRepeatingVibration(effect) && mCurrentVibration != null - && isRepeatingVibration(mCurrentVibration.effect)) { + && isRepeatingVibration(currentEffect)) { if (DEBUG) { Slog.d(TAG, "Ignoring incoming vibration in favor of alarm vibration"); } - endVibrationLocked(vib, VibrationInfo.Status.IGNORED_FOR_ALARM); + endVibrationLocked(vib, Vibration.Status.IGNORED_FOR_ALARM); return; } if (mProcStatesCache.get(uid, ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND - && !vib.isNotification() && !vib.isRingtone() && !vib.isAlarm()) { + && !isNotification(vib) && !isRingtone(vib) && !isAlarm(vib)) { Slog.e(TAG, "Ignoring incoming vibration as process with" + " uid= " + uid + " is background," + " attrs= " + vib.attrs); - endVibrationLocked(vib, VibrationInfo.Status.IGNORED_BACKGROUND); + endVibrationLocked(vib, Vibration.Status.IGNORED_BACKGROUND); return; } - linkVibration(vib); + linkVibrationLocked(vib); final long ident = Binder.clearCallingIdentity(); try { - doCancelVibrateLocked(VibrationInfo.Status.CANCELLED); + doCancelVibrateLocked(Vibration.Status.CANCELLED); startVibrationLocked(vib); if (!vib.hasEnded() && mCurrentVibration.id != vib.id) { // Vibration was unexpectedly ignored: add to list for debugging - endVibrationLocked(vib, VibrationInfo.Status.IGNORED); + endVibrationLocked(vib, Vibration.Status.IGNORED); } } finally { Binder.restoreCallingIdentity(ident); @@ -953,13 +580,13 @@ public class VibratorService extends IVibratorService.Stub return effect.getDuration() == Long.MAX_VALUE; } - private void endVibrationLocked(Vibration vib, VibrationInfo.Status status) { - final LinkedList<VibrationInfo> previousVibrations; - if (vib.isRingtone()) { + private void endVibrationLocked(Vibration vib, Vibration.Status status) { + final LinkedList<Vibration.DebugInfo> previousVibrations; + if (isRingtone(vib)) { previousVibrations = mPreviousRingVibrations; - } else if (vib.isNotification()) { + } else if (isNotification(vib)) { previousVibrations = mPreviousNotificationVibrations; - } else if (vib.isAlarm()) { + } else if (isAlarm(vib)) { previousVibrations = mPreviousAlarmVibrations; } else { previousVibrations = mPreviousVibrations; @@ -969,15 +596,15 @@ public class VibratorService extends IVibratorService.Stub previousVibrations.removeFirst(); } vib.end(status); - previousVibrations.addLast(vib.toInfo()); + previousVibrations.addLast(vib.getDebugInfo()); } - private void endVibrationLocked(ExternalVibrationHolder vib, VibrationInfo.Status status) { + private void endVibrationLocked(ExternalVibrationHolder vib, Vibration.Status status) { if (mPreviousExternalVibrations.size() > mPreviousVibrationsLimit) { mPreviousExternalVibrations.removeFirst(); } vib.end(status); - mPreviousExternalVibrations.addLast(vib.toInfo()); + mPreviousExternalVibrations.addLast(vib.getDebugInfo()); } @Override // Binder call @@ -993,7 +620,7 @@ public class VibratorService extends IVibratorService.Stub } final long ident = Binder.clearCallingIdentity(); try { - doCancelVibrateLocked(VibrationInfo.Status.CANCELLED); + doCancelVibrateLocked(Vibration.Status.CANCELLED); } finally { Binder.restoreCallingIdentity(ident); } @@ -1002,7 +629,7 @@ public class VibratorService extends IVibratorService.Stub } @GuardedBy("mLock") - private void doCancelVibrateLocked(VibrationInfo.Status status) { + private void doCancelVibrateLocked(Vibration.Status status) { Trace.asyncTraceEnd(Trace.TRACE_TAG_VIBRATOR, "vibration", 0); Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "doCancelVibrateLocked"); try { @@ -1014,7 +641,7 @@ public class VibratorService extends IVibratorService.Stub endVibrationLocked(mCurrentExternalVibration, status); mCurrentExternalVibration.externalVibration.mute(); mCurrentExternalVibration = null; - setVibratorUnderExternalControl(false); + mVibratorController.setExternalControl(false); } doVibratorOff(); reportFinishVibrationLocked(status); @@ -1031,7 +658,7 @@ public class VibratorService extends IVibratorService.Stub synchronized (mLock) { // Make sure the vibration is really done. This also reports that the vibration is // finished. - doCancelVibrateLocked(VibrationInfo.Status.FINISHED); + doCancelVibrateLocked(Vibration.Status.FINISHED); } } @@ -1055,23 +682,22 @@ public class VibratorService extends IVibratorService.Stub try { // Set current vibration before starting it, so callback will work. mCurrentVibration = vib; - if (vib.effect instanceof VibrationEffect.OneShot) { + VibrationEffect effect = vib.getEffect(); + if (effect instanceof VibrationEffect.OneShot) { Trace.asyncTraceBegin(Trace.TRACE_TAG_VIBRATOR, "vibration", 0); doVibratorOn(vib); - } else if (vib.effect instanceof VibrationEffect.Waveform) { - // mThread better be null here. doCancelVibrate should always be - // called before startNextVibrationLocked or startVibrationLocked. - mThread = new VibrateWaveformThread(vib); - mThread.start(); - } else if (vib.effect instanceof VibrationEffect.Prebaked) { + } else if (effect instanceof VibrationEffect.Waveform) { + Trace.asyncTraceBegin(Trace.TRACE_TAG_VIBRATOR, "vibration", 0); + doVibratorWaveformEffectLocked(vib); + } else if (effect instanceof VibrationEffect.Prebaked) { Trace.asyncTraceBegin(Trace.TRACE_TAG_VIBRATOR, "vibration", 0); doVibratorPrebakedEffectLocked(vib); - } else if (vib.effect instanceof VibrationEffect.Composed) { + } else if (effect instanceof VibrationEffect.Composed) { Trace.asyncTraceBegin(Trace.TRACE_TAG_VIBRATOR, "vibration", 0); doVibratorComposedEffectLocked(vib); } else { Slog.e(TAG, "Unknown vibration type, ignoring"); - endVibrationLocked(vib, VibrationInfo.Status.IGNORED_UNKNOWN_VIBRATION); + endVibrationLocked(vib, Vibration.Status.IGNORED_UNKNOWN_VIBRATION); // The set current vibration is not actually playing, so drop it. mCurrentVibration = null; } @@ -1093,11 +719,7 @@ public class VibratorService extends IVibratorService.Stub /** Scale the vibration effect by the intensity as appropriate based its intent. */ private void applyVibrationIntensityScalingLocked(Vibration vib) { - VibrationEffect scaled = mVibrationScaler.scale(vib.effect, vib.attrs.getUsage()); - if (!scaled.equals(vib.effect)) { - vib.originalEffect = vib.effect; - vib.effect = scaled; - } + vib.updateEffect(mVibrationScaler.scale(vib.getEffect(), vib.attrs.getUsage())); } private static boolean shouldBypassDnd(VibrationAttributes attrs) { @@ -1123,21 +745,21 @@ public class VibratorService extends IVibratorService.Stub private boolean shouldVibrate(Vibration vib) { if (!shouldVibrateForPowerModeLocked(vib)) { - endVibrationLocked(vib, VibrationInfo.Status.IGNORED_FOR_POWER); + endVibrationLocked(vib, Vibration.Status.IGNORED_FOR_POWER); return false; } int intensity = mVibrationSettings.getCurrentIntensity(vib.attrs.getUsage()); if (intensity == Vibrator.VIBRATION_INTENSITY_OFF) { - endVibrationLocked(vib, VibrationInfo.Status.IGNORED_FOR_SETTINGS); + endVibrationLocked(vib, Vibration.Status.IGNORED_FOR_SETTINGS); return false; } - if (vib.isRingtone() && !mVibrationSettings.shouldVibrateForRingtone()) { + if (isRingtone(vib) && !mVibrationSettings.shouldVibrateForRingtone()) { if (DEBUG) { Slog.e(TAG, "Vibrate ignored, not vibrating for ringtones"); } - endVibrationLocked(vib, VibrationInfo.Status.IGNORED_RINGTONE); + endVibrationLocked(vib, Vibration.Status.IGNORED_RINGTONE); return false; } @@ -1147,9 +769,9 @@ public class VibratorService extends IVibratorService.Stub // We might be getting calls from within system_server, so we don't actually // want to throw a SecurityException here. Slog.w(TAG, "Would be an error: vibrate from uid " + vib.uid); - endVibrationLocked(vib, VibrationInfo.Status.ERROR_APP_OPS); + endVibrationLocked(vib, Vibration.Status.ERROR_APP_OPS); } else { - endVibrationLocked(vib, VibrationInfo.Status.IGNORED_APP_OPS); + endVibrationLocked(vib, Vibration.Status.IGNORED_APP_OPS); } return false; } @@ -1158,14 +780,14 @@ public class VibratorService extends IVibratorService.Stub } @GuardedBy("mLock") - private void reportFinishVibrationLocked(VibrationInfo.Status status) { + private void reportFinishVibrationLocked(Vibration.Status status) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "reportFinishVibrationLocked"); try { if (mCurrentVibration != null) { endVibrationLocked(mCurrentVibration, status); mAppOps.finishOp(AppOpsManager.OP_VIBRATE, mCurrentVibration.uid, mCurrentVibration.opPkg); - unlinkVibration(mCurrentVibration); + unlinkVibrationLocked(); mCurrentVibration = null; } } finally { @@ -1173,73 +795,45 @@ public class VibratorService extends IVibratorService.Stub } } - private void linkVibration(Vibration vib) { + @GuardedBy("mLock") + private void linkVibrationLocked(Vibration vib) { + // Unlink previously linked vibration, if any. + unlinkVibrationLocked(); // Only link against waveforms since they potentially don't have a finish if // they're repeating. Let other effects just play out until they're done. - if (vib.effect instanceof VibrationEffect.Waveform) { + if (vib.getEffect() instanceof VibrationEffect.Waveform) { try { - vib.token.linkToDeath(vib, 0); + mCurrentVibrationDeathRecipient = new VibrationDeathRecipient(vib); + mCurrentVibrationDeathRecipient.linkToDeath(); } catch (RemoteException e) { return; } } } - private void unlinkVibration(Vibration vib) { - if (vib.effect instanceof VibrationEffect.Waveform) { - vib.token.unlinkToDeath(vib, 0); + @GuardedBy("mLock") + private void unlinkVibrationLocked() { + if (mCurrentVibrationDeathRecipient != null) { + mCurrentVibrationDeathRecipient.unlinkToDeath(); + mCurrentVibrationDeathRecipient = null; } } private void updateVibrators() { synchronized (mLock) { - boolean devicesUpdated = updateInputDeviceVibratorsLocked(); + boolean devicesUpdated = mInputDeviceDelegate.updateInputDeviceVibrators( + mVibrationSettings.shouldVibrateInputDevices()); boolean lowPowerModeUpdated = updateLowPowerModeLocked(); if (devicesUpdated || lowPowerModeUpdated) { // If the state changes out from under us then just reset. - doCancelVibrateLocked(VibrationInfo.Status.CANCELLED); + doCancelVibrateLocked(Vibration.Status.CANCELLED); } updateAlwaysOnLocked(); } } - private boolean updateInputDeviceVibratorsLocked() { - boolean changed = false; - boolean vibrateInputDevices = mVibrationSettings.shouldVibrateInputDevices(); - if (vibrateInputDevices != mVibrateInputDevicesSetting) { - changed = true; - mVibrateInputDevicesSetting = vibrateInputDevices; - } - - if (mVibrateInputDevicesSetting) { - if (!mInputDeviceListenerRegistered) { - mInputDeviceListenerRegistered = true; - mIm.registerInputDeviceListener(this, mH); - } - } else { - if (mInputDeviceListenerRegistered) { - mInputDeviceListenerRegistered = false; - mIm.unregisterInputDeviceListener(this); - } - } - - mInputDeviceVibrators.clear(); - if (mVibrateInputDevicesSetting) { - int[] ids = mIm.getInputDeviceIds(); - for (int i = 0; i < ids.length; i++) { - InputDevice device = mIm.getInputDevice(ids[i]); - Vibrator vibrator = device.getVibrator(); - if (vibrator.hasVibrator()) { - mInputDeviceVibrators.add(vibrator); - } - } - return true; - } - return changed; - } - private boolean updateLowPowerModeLocked() { boolean lowPowerMode = mPowerManagerInternal .getLowPowerState(ServiceType.VIBRATION).batterySaverEnabled; @@ -1251,13 +845,13 @@ public class VibratorService extends IVibratorService.Stub } private void updateAlwaysOnLocked(int id, Vibration vib) { + VibrationEffect.Prebaked effect; if (!shouldVibrate(vib)) { - mNativeWrapper.vibratorAlwaysOnDisable(id); + effect = null; } else { - VibrationEffect.Prebaked scaled = mVibrationScaler.scale(vib.effect, - vib.attrs.getUsage()); - mNativeWrapper.vibratorAlwaysOnEnable(id, scaled.getId(), scaled.getEffectStrength()); + effect = mVibrationScaler.scale(vib.getEffect(), vib.attrs.getUsage()); } + mVibratorController.updateAlwaysOn(id, effect); } private void updateAlwaysOnLocked() { @@ -1268,85 +862,64 @@ public class VibratorService extends IVibratorService.Stub } } - @Override - public void onInputDeviceAdded(int deviceId) { - updateVibrators(); - } - - @Override - public void onInputDeviceChanged(int deviceId) { - updateVibrators(); - } - - @Override - public void onInputDeviceRemoved(int deviceId) { - updateVibrators(); - } - - private boolean doVibratorExists() { - // For now, we choose to ignore the presence of input devices that have vibrators - // when reporting whether the device has a vibrator. Applications often use this - // information to decide whether to enable certain features so they expect the - // result of hasVibrator() to be constant. For now, just report whether - // the device has a built-in vibrator. - //synchronized (mInputDeviceVibrators) { - // return !mInputDeviceVibrators.isEmpty() || vibratorExists(); - //} - return mNativeWrapper.vibratorExists(); - } - private void doVibratorOn(Vibration vib) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "doVibratorOn"); try { - synchronized (mInputDeviceVibrators) { - final VibrationEffect.OneShot oneShot = vib.effect.resolve( - mDefaultVibrationAmplitude); - if (DEBUG) { - Slog.d(TAG, "Turning vibrator on for " + oneShot.getDuration() + " ms" - + " with amplitude " + oneShot.getAmplitude() + "."); - } + final VibrationEffect.OneShot oneShot = (VibrationEffect.OneShot) vib.getEffect(); + if (DEBUG) { + Slog.d(TAG, "Turning vibrator on for " + oneShot.getDuration() + " ms" + + " with amplitude " + oneShot.getAmplitude() + "."); + } + boolean inputDevicesAvailable = mInputDeviceDelegate.vibrateIfAvailable( + vib.uid, vib.opPkg, oneShot, vib.reason, vib.attrs); + if (inputDevicesAvailable) { + // The set current vibration is no longer being played by this service, so drop it. + mCurrentVibration = null; + endVibrationLocked(vib, Vibration.Status.FORWARDED_TO_INPUT_DEVICES); + } else { noteVibratorOnLocked(vib.uid, oneShot.getDuration()); - final int vibratorCount = mInputDeviceVibrators.size(); - if (vibratorCount != 0) { - for (int i = 0; i < vibratorCount; i++) { - mInputDeviceVibrators.get(i).vibrate(vib.uid, vib.opPkg, oneShot, - vib.reason, vib.attrs); - } - } else { - // Note: ordering is important here! Many haptic drivers will reset their - // amplitude when enabled, so we always have to enable first, then set the - // amplitude. - mNativeWrapper.vibratorOn(oneShot.getDuration(), vib.id); - doVibratorSetAmplitude(oneShot.getAmplitude()); - } + // Note: ordering is important here! Many haptic drivers will reset their + // amplitude when enabled, so we always have to enable first, then set the + // amplitude. + mVibratorController.on(oneShot.getDuration(), vib.id); + mVibratorController.setAmplitude(oneShot.getAmplitude()); } } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } - private void doVibratorSetAmplitude(int amplitude) { - if (hasCapability(IVibrator.CAP_AMPLITUDE_CONTROL)) { - mNativeWrapper.vibratorSetAmplitude(amplitude); + private void doVibratorOff() { + Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "doVibratorOff"); + try { + if (DEBUG) { + Slog.d(TAG, "Turning vibrator off."); + } + noteVibratorOffLocked(); + boolean inputDevicesAvailable = mInputDeviceDelegate.cancelVibrateIfAvailable(); + if (!inputDevicesAvailable) { + mVibratorController.off(); + } + } finally { + Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } - private void doVibratorOff() { - Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "doVibratorOff"); + @GuardedBy("mLock") + private void doVibratorWaveformEffectLocked(Vibration vib) { + Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "doVibratorWaveformEffectLocked"); try { - synchronized (mInputDeviceVibrators) { - if (DEBUG) { - Slog.d(TAG, "Turning vibrator off."); - } - noteVibratorOffLocked(); - final int vibratorCount = mInputDeviceVibrators.size(); - if (vibratorCount != 0) { - for (int i = 0; i < vibratorCount; i++) { - mInputDeviceVibrators.get(i).cancel(); - } - } else { - mNativeWrapper.vibratorOff(); - } + boolean inputDevicesAvailable = mInputDeviceDelegate.vibrateIfAvailable( + vib.uid, vib.opPkg, vib.getEffect(), vib.reason, vib.attrs); + if (inputDevicesAvailable) { + // The set current vibration is no longer being played by this service, so drop it. + mCurrentVibration = null; + endVibrationLocked(vib, Vibration.Status.FORWARDED_TO_INPUT_DEVICES); + } else { + // mThread better be null here. doCancelVibrate should always be + // called before startNextVibrationLocked or startVibrationLocked. + mThread = new VibrateWaveformThread(vib); + mThread.start(); } } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); @@ -1357,37 +930,33 @@ public class VibratorService extends IVibratorService.Stub private void doVibratorPrebakedEffectLocked(Vibration vib) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "doVibratorPrebakedEffectLocked"); try { - final VibrationEffect.Prebaked prebaked = (VibrationEffect.Prebaked) vib.effect; - final boolean usingInputDeviceVibrators; - synchronized (mInputDeviceVibrators) { - usingInputDeviceVibrators = !mInputDeviceVibrators.isEmpty(); - } - // Input devices don't support prebaked effect, so skip trying it with them. - if (!usingInputDeviceVibrators) { - long duration = mNativeWrapper.vibratorPerformEffect( - prebaked.getId(), prebaked.getEffectStrength(), vib.id); + final VibrationEffect.Prebaked prebaked = (VibrationEffect.Prebaked) vib.getEffect(); + // Input devices don't support prebaked effect, so skip trying it with them and allow + // fallback to be attempted. + if (!mInputDeviceDelegate.isAvailable()) { + long duration = mVibratorController.on(prebaked, vib.id); if (duration > 0) { noteVibratorOnLocked(vib.uid, duration); return; } } - endVibrationLocked(vib, VibrationInfo.Status.IGNORED_UNSUPPORTED); + endVibrationLocked(vib, Vibration.Status.IGNORED_UNSUPPORTED); // The set current vibration is not actually playing, so drop it. mCurrentVibration = null; if (!prebaked.shouldFallback()) { return; } - VibrationEffect effect = getFallbackEffect(prebaked.getId()); + VibrationEffect effect = mVibrationSettings.getFallbackEffect(prebaked.getId()); if (effect == null) { Slog.w(TAG, "Failed to play prebaked effect, no fallback"); return; } - Vibration fallbackVib = new Vibration(vib.token, effect, vib.attrs, vib.uid, - vib.opPkg, vib.reason + " (fallback)"); + Vibration fallbackVib = new Vibration(vib.token, mNextVibrationId.getAndIncrement(), + effect, vib.attrs, vib.uid, vib.opPkg, vib.reason + " (fallback)"); // Set current vibration before starting it, so callback will work. mCurrentVibration = fallbackVib; - linkVibration(fallbackVib); + linkVibrationLocked(fallbackVib); applyVibrationIntensityScalingLocked(fallbackVib); startVibrationInnerLocked(fallbackVib); } finally { @@ -1400,53 +969,49 @@ public class VibratorService extends IVibratorService.Stub Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "doVibratorComposedEffectLocked"); try { - final VibrationEffect.Composed composed = (VibrationEffect.Composed) vib.effect; - final boolean usingInputDeviceVibrators; - synchronized (mInputDeviceVibrators) { - usingInputDeviceVibrators = !mInputDeviceVibrators.isEmpty(); - } - // Input devices don't support composed effect, so skip trying it with them. - if (usingInputDeviceVibrators || !hasCapability(IVibrator.CAP_COMPOSE_EFFECTS)) { - endVibrationLocked(vib, VibrationInfo.Status.IGNORED_UNSUPPORTED); + final VibrationEffect.Composed composed = (VibrationEffect.Composed) vib.getEffect(); + boolean inputDevicesAvailable = mInputDeviceDelegate.vibrateIfAvailable( + vib.uid, vib.opPkg, composed, vib.reason, vib.attrs); + if (inputDevicesAvailable) { + // The set current vibration is no longer being played by this service, so drop it. + mCurrentVibration = null; + endVibrationLocked(vib, Vibration.Status.FORWARDED_TO_INPUT_DEVICES); + return; + } else if (!mVibratorController.hasCapability(IVibrator.CAP_COMPOSE_EFFECTS)) { // The set current vibration is not actually playing, so drop it. mCurrentVibration = null; + endVibrationLocked(vib, Vibration.Status.IGNORED_UNSUPPORTED); return; } - PrimitiveEffect[] primitiveEffects = - composed.getPrimitiveEffects().toArray(new PrimitiveEffect[0]); - mNativeWrapper.vibratorPerformComposedEffect(primitiveEffects, vib.id); + mVibratorController.on(composed, vib.id); // Composed effects don't actually give us an estimated duration, so we just guess here. - noteVibratorOnLocked(vib.uid, 10 * primitiveEffects.length); + noteVibratorOnLocked(vib.uid, 10 * composed.getPrimitiveEffects().size()); } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } } - private boolean hasCapability(long capability) { - return (mCapabilities & capability) == capability; - } - - private VibrationEffect getFallbackEffect(int effectId) { - return mFallbackEffects.get(effectId); + private static boolean isNotification(Vibration vib) { + return vib.attrs.getUsage() == VibrationAttributes.USAGE_NOTIFICATION; } - private static boolean isNotification(int usageHint) { - return usageHint == VibrationAttributes.USAGE_NOTIFICATION; + private static boolean isRingtone(Vibration vib) { + return vib.attrs.getUsage() == VibrationAttributes.USAGE_RINGTONE; } - private static boolean isRingtone(int usageHint) { - return usageHint == VibrationAttributes.USAGE_RINGTONE; + private static boolean isHapticFeedback(Vibration vib) { + return vib.attrs.getUsage() == VibrationAttributes.USAGE_TOUCH; } - private static boolean isHapticFeedback(int usageHint) { - return usageHint == VibrationAttributes.USAGE_TOUCH; + private static boolean isAlarm(Vibration vib) { + return vib.attrs.getUsage() == VibrationAttributes.USAGE_ALARM; } - private static boolean isAlarm(int usageHint) { - return usageHint == VibrationAttributes.USAGE_ALARM; + private boolean isFromSystem(Vibration vib) { + return vib.uid == Process.SYSTEM_UID || vib.uid == 0 || mSystemUiPackage.equals(vib.opPkg); } private void noteVibratorOnLocked(int uid, long millis) { @@ -1455,10 +1020,6 @@ public class VibratorService extends IVibratorService.Stub FrameworkStatsLog.write_non_chained(FrameworkStatsLog.VIBRATOR_STATE_CHANGED, uid, null, FrameworkStatsLog.VIBRATOR_STATE_CHANGED__STATE__ON, millis); mCurVibUid = uid; - if (!mIsVibrating) { - mIsVibrating = true; - notifyStateListenersLocked(); - } } catch (RemoteException e) { } } @@ -1472,22 +1033,6 @@ public class VibratorService extends IVibratorService.Stub } catch (RemoteException e) { } mCurVibUid = -1; } - if (mIsVibrating) { - mIsVibrating = false; - notifyStateListenersLocked(); - } - } - - private void setVibratorUnderExternalControl(boolean externalControl) { - if (DEBUG) { - if (externalControl) { - Slog.d(TAG, "Vibrator going under external control."); - } else { - Slog.d(TAG, "Taking back control of vibrator."); - } - } - mVibratorUnderExternalControl = externalControl; - mNativeWrapper.vibratorSetExternalControl(externalControl); } private void dumpInternal(PrintWriter pw) { @@ -1495,48 +1040,43 @@ public class VibratorService extends IVibratorService.Stub synchronized (mLock) { pw.print(" mCurrentVibration="); if (mCurrentVibration != null) { - pw.println(mCurrentVibration.toInfo().toString()); + pw.println(mCurrentVibration.getDebugInfo().toString()); } else { pw.println("null"); } pw.print(" mCurrentExternalVibration="); if (mCurrentExternalVibration != null) { - pw.println(mCurrentExternalVibration.toInfo().toString()); + pw.println(mCurrentExternalVibration.getDebugInfo().toString()); } else { pw.println("null"); } - pw.println(" mVibratorUnderExternalControl=" + mVibratorUnderExternalControl); - pw.println(" mIsVibrating=" + mIsVibrating); - pw.println(" mVibratorStateListeners Count=" - + mVibratorStateListeners.getRegisteredCallbackCount()); pw.println(" mLowPowerMode=" + mLowPowerMode); + pw.println(" mVibratorController=" + mVibratorController); pw.println(" mVibrationSettings=" + mVibrationSettings); - pw.println(" mSupportedEffects=" + mSupportedEffects); - pw.println(" mSupportedPrimitives=" + mSupportedPrimitives); pw.println(); pw.println(" Previous ring vibrations:"); - for (VibrationInfo info : mPreviousRingVibrations) { + for (Vibration.DebugInfo info : mPreviousRingVibrations) { pw.print(" "); pw.println(info.toString()); } pw.println(" Previous notification vibrations:"); - for (VibrationInfo info : mPreviousNotificationVibrations) { + for (Vibration.DebugInfo info : mPreviousNotificationVibrations) { pw.println(" " + info); } pw.println(" Previous alarm vibrations:"); - for (VibrationInfo info : mPreviousAlarmVibrations) { + for (Vibration.DebugInfo info : mPreviousAlarmVibrations) { pw.println(" " + info); } pw.println(" Previous vibrations:"); - for (VibrationInfo info : mPreviousVibrations) { + for (Vibration.DebugInfo info : mPreviousVibrations) { pw.println(" " + info); } pw.println(" Previous external vibrations:"); - for (VibrationInfo info : mPreviousExternalVibrations) { + for (Vibration.DebugInfo info : mPreviousExternalVibrations) { pw.println(" " + info); } } @@ -1547,16 +1087,16 @@ public class VibratorService extends IVibratorService.Stub synchronized (mLock) { if (mCurrentVibration != null) { - mCurrentVibration.toInfo().dumpProto(proto, + mCurrentVibration.getDebugInfo().dumpProto(proto, VibratorServiceDumpProto.CURRENT_VIBRATION); } if (mCurrentExternalVibration != null) { - mCurrentExternalVibration.toInfo().dumpProto(proto, + mCurrentExternalVibration.getDebugInfo().dumpProto(proto, VibratorServiceDumpProto.CURRENT_EXTERNAL_VIBRATION); } - proto.write(VibratorServiceDumpProto.IS_VIBRATING, mIsVibrating); + proto.write(VibratorServiceDumpProto.IS_VIBRATING, mVibratorController.isVibrating()); proto.write(VibratorServiceDumpProto.VIBRATOR_UNDER_EXTERNAL_CONTROL, - mVibratorUnderExternalControl); + mVibratorController.isUnderExternalControl()); proto.write(VibratorServiceDumpProto.LOW_POWER_MODE, mLowPowerMode); proto.write(VibratorServiceDumpProto.HAPTIC_FEEDBACK_INTENSITY, mVibrationSettings.getCurrentIntensity(VibrationAttributes.USAGE_TOUCH)); @@ -1571,23 +1111,23 @@ public class VibratorService extends IVibratorService.Stub proto.write(VibratorServiceDumpProto.RING_DEFAULT_INTENSITY, mVibrationSettings.getDefaultIntensity(VibrationAttributes.USAGE_RINGTONE)); - for (VibrationInfo info : mPreviousRingVibrations) { + for (Vibration.DebugInfo info : mPreviousRingVibrations) { info.dumpProto(proto, VibratorServiceDumpProto.PREVIOUS_RING_VIBRATIONS); } - for (VibrationInfo info : mPreviousNotificationVibrations) { + for (Vibration.DebugInfo info : mPreviousNotificationVibrations) { info.dumpProto(proto, VibratorServiceDumpProto.PREVIOUS_NOTIFICATION_VIBRATIONS); } - for (VibrationInfo info : mPreviousAlarmVibrations) { + for (Vibration.DebugInfo info : mPreviousAlarmVibrations) { info.dumpProto(proto, VibratorServiceDumpProto.PREVIOUS_ALARM_VIBRATIONS); } - for (VibrationInfo info : mPreviousVibrations) { + for (Vibration.DebugInfo info : mPreviousVibrations) { info.dumpProto(proto, VibratorServiceDumpProto.PREVIOUS_VIBRATIONS); } - for (VibrationInfo info : mPreviousExternalVibrations) { + for (Vibration.DebugInfo info : mPreviousExternalVibrations) { info.dumpProto(proto, VibratorServiceDumpProto.PREVIOUS_EXTERNAL_VIBRATIONS); } } @@ -1602,9 +1142,9 @@ public class VibratorService extends IVibratorService.Stub private boolean mForceStop; VibrateWaveformThread(Vibration vib) { - mWaveform = (VibrationEffect.Waveform) vib.effect; - mVibration = new Vibration(vib.token, /* effect= */ null, vib.attrs, vib.uid, - vib.opPkg, vib.reason); + mWaveform = (VibrationEffect.Waveform) vib.getEffect(); + mVibration = new Vibration(vib.token, /* id= */ 0, /* effect= */ null, vib.attrs, + vib.uid, vib.opPkg, vib.reason); mTmpWorkSource.set(vib.uid); mWakeLock.setWorkSource(mTmpWorkSource); } @@ -1676,14 +1216,18 @@ public class VibratorService extends IVibratorService.Stub // appropriate intervals. long onDuration = getTotalOnDuration( timings, amplitudes, index - 1, repeat); - mVibration.effect = VibrationEffect.createOneShot( - onDuration, amplitude); + mVibration.updateEffect( + VibrationEffect.createOneShot(onDuration, amplitude)); doVibratorOn(mVibration); nextVibratorStopTime = now + onDuration; } else { // Vibrator is already ON, so just change its amplitude. - doVibratorSetAmplitude(amplitude); + mVibratorController.setAmplitude(amplitude); } + } else { + // Previous vibration should have already finished, but we make sure + // the vibrator will be off for the next step when amplitude is 0. + doVibratorOff(); } // We wait until the time this waveform step was supposed to end, @@ -1740,95 +1284,12 @@ public class VibratorService extends IVibratorService.Stub } } - /** Wrapper around the static-native methods of {@link VibratorService} for tests. */ - @VisibleForTesting - public static class NativeWrapper { - - private long mNativeServicePtr = 0; - - /** Checks if vibrator exists on device. */ - public boolean vibratorExists() { - return VibratorService.vibratorExists(mNativeServicePtr); - } - - /** Initializes connection to vibrator HAL service. */ - public void vibratorInit(OnCompleteListener listener) { - mNativeServicePtr = VibratorService.vibratorInit(listener); - long finalizerPtr = VibratorService.vibratorGetFinalizer(); - - if (finalizerPtr != 0) { - NativeAllocationRegistry registry = - NativeAllocationRegistry.createMalloced( - VibratorService.class.getClassLoader(), finalizerPtr); - registry.registerNativeAllocation(this, mNativeServicePtr); - } - } - - /** Turns vibrator on for given time. */ - public void vibratorOn(long milliseconds, long vibrationId) { - VibratorService.vibratorOn(mNativeServicePtr, milliseconds, vibrationId); - } - - /** Turns vibrator off. */ - public void vibratorOff() { - VibratorService.vibratorOff(mNativeServicePtr); - } - - /** Sets the amplitude for the vibrator to run. */ - public void vibratorSetAmplitude(int amplitude) { - VibratorService.vibratorSetAmplitude(mNativeServicePtr, amplitude); - } - - /** Returns all predefined effects supported by the device vibrator. */ - public int[] vibratorGetSupportedEffects() { - return VibratorService.vibratorGetSupportedEffects(mNativeServicePtr); - } - - /** Returns all compose primitives supported by the device vibrator. */ - public int[] vibratorGetSupportedPrimitives() { - return VibratorService.vibratorGetSupportedPrimitives(mNativeServicePtr); - } - - /** Turns vibrator on to perform one of the supported effects. */ - public long vibratorPerformEffect(long effect, long strength, long vibrationId) { - return VibratorService.vibratorPerformEffect( - mNativeServicePtr, effect, strength, vibrationId); - } - - /** Turns vibrator on to perform one of the supported composed effects. */ - public void vibratorPerformComposedEffect( - VibrationEffect.Composition.PrimitiveEffect[] effect, long vibrationId) { - VibratorService.vibratorPerformComposedEffect(mNativeServicePtr, effect, - vibrationId); - } - - /** Enabled the device vibrator to be controlled by another service. */ - public void vibratorSetExternalControl(boolean enabled) { - VibratorService.vibratorSetExternalControl(mNativeServicePtr, enabled); - } - - /** Returns all capabilities of the device vibrator. */ - public long vibratorGetCapabilities() { - return VibratorService.vibratorGetCapabilities(mNativeServicePtr); - } - - /** Enable always-on vibration with given id and effect. */ - public void vibratorAlwaysOnEnable(long id, long effect, long strength) { - VibratorService.vibratorAlwaysOnEnable(mNativeServicePtr, id, effect, strength); - } - - /** Disable always-on vibration for given id. */ - public void vibratorAlwaysOnDisable(long id) { - VibratorService.vibratorAlwaysOnDisable(mNativeServicePtr, id); - } - } - /** Point of injection for test dependencies */ @VisibleForTesting static class Injector { - NativeWrapper getNativeWrapper() { - return new NativeWrapper(); + VibratorController createVibratorController(OnVibrationCompleteListener listener) { + return new VibratorController(/* vibratorId= */ 0, listener); } Handler createHandler(Looper looper) { @@ -1851,9 +1312,9 @@ public class VibratorService extends IVibratorService.Stub // haptic feedback as part of the transition. So we don't cancel // system vibrations. if (mCurrentVibration != null - && !(mCurrentVibration.isHapticFeedback() - && mCurrentVibration.isFromSystem())) { - doCancelVibrateLocked(VibrationInfo.Status.CANCELLED); + && !(isHapticFeedback(mCurrentVibration) + && isFromSystem(mCurrentVibration))) { + doCancelVibrateLocked(Vibration.Status.CANCELLED); } } } @@ -1894,7 +1355,7 @@ public class VibratorService extends IVibratorService.Stub @Override public int onExternalVibrationStart(ExternalVibration vib) { - if (!hasCapability(IVibrator.CAP_EXTERNAL_CONTROL)) { + if (!mVibratorController.hasCapability(IVibrator.CAP_EXTERNAL_CONTROL)) { return IExternalVibratorService.SCALE_MUTE; } if (ActivityManager.checkComponentPermission(android.Manifest.permission.VIBRATE, @@ -1912,9 +1373,9 @@ public class VibratorService extends IVibratorService.Stub vibHolder.scale = SCALE_MUTE; if (mode == AppOpsManager.MODE_ERRORED) { Slog.w(TAG, "Would be an error: external vibrate from uid " + vib.getUid()); - endVibrationLocked(vibHolder, VibrationInfo.Status.ERROR_APP_OPS); + endVibrationLocked(vibHolder, Vibration.Status.ERROR_APP_OPS); } else { - endVibrationLocked(vibHolder, VibrationInfo.Status.IGNORED_APP_OPS); + endVibrationLocked(vibHolder, Vibration.Status.IGNORED_APP_OPS); } return IExternalVibratorService.SCALE_MUTE; } @@ -1929,10 +1390,13 @@ public class VibratorService extends IVibratorService.Stub if (mCurrentExternalVibration == null) { // If we're not under external control right now, then cancel any normal // vibration that may be playing and ready the vibrator for external control. - doCancelVibrateLocked(VibrationInfo.Status.CANCELLED); - setVibratorUnderExternalControl(true); + if (DEBUG) { + Slog.d(TAG, "Vibrator going under external control."); + } + doCancelVibrateLocked(Vibration.Status.CANCELLED); + mVibratorController.setExternalControl(true); } else { - endVibrationLocked(mCurrentExternalVibration, VibrationInfo.Status.CANCELLED); + endVibrationLocked(mCurrentExternalVibration, Vibration.Status.CANCELLED); } // At this point we either have an externally controlled vibration playing, or // no vibration playing. Since the interface defines that only one externally @@ -1962,12 +1426,12 @@ public class VibratorService extends IVibratorService.Stub if (DEBUG) { Slog.e(TAG, "Stopping external vibration" + vib); } - doCancelExternalVibrateLocked(VibrationInfo.Status.FINISHED); + doCancelExternalVibrateLocked(Vibration.Status.FINISHED); } } } - private void doCancelExternalVibrateLocked(VibrationInfo.Status status) { + private void doCancelExternalVibrateLocked(Vibration.Status status) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "doCancelExternalVibrateLocked"); try { if (mCurrentExternalVibration == null) { @@ -1978,7 +1442,7 @@ public class VibratorService extends IVibratorService.Stub mCurrentExternalDeathRecipient); mCurrentExternalDeathRecipient = null; mCurrentExternalVibration = null; - setVibratorUnderExternalControl(false); + mVibratorController.setExternalControl(false); } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); } @@ -1991,7 +1455,7 @@ public class VibratorService extends IVibratorService.Stub if (DEBUG) { Slog.d(TAG, "External vibration finished because binder died"); } - doCancelExternalVibrateLocked(VibrationInfo.Status.CANCELLED); + doCancelExternalVibrateLocked(Vibration.Status.CANCELLED); } } } @@ -2176,19 +1640,19 @@ public class VibratorService extends IVibratorService.Stub Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "runCapabilities"); try (PrintWriter pw = getOutPrintWriter();) { pw.println("Vibrator capabilities:"); - if (hasCapability(IVibrator.CAP_ALWAYS_ON_CONTROL)) { + if (mVibratorController.hasCapability(IVibrator.CAP_ALWAYS_ON_CONTROL)) { pw.println(" Always on effects"); } - if (hasCapability(IVibrator.CAP_COMPOSE_EFFECTS)) { + if (mVibratorController.hasCapability(IVibrator.CAP_COMPOSE_EFFECTS)) { pw.println(" Compose effects"); } - if (hasCapability(IVibrator.CAP_AMPLITUDE_CONTROL)) { + if (mVibratorController.hasCapability(IVibrator.CAP_AMPLITUDE_CONTROL)) { pw.println(" Amplitude control"); } - if (hasCapability(IVibrator.CAP_EXTERNAL_CONTROL)) { + if (mVibratorController.hasCapability(IVibrator.CAP_EXTERNAL_CONTROL)) { pw.println(" External control"); } - if (hasCapability(IVibrator.CAP_EXTERNAL_AMPLITUDE_CONTROL)) { + if (mVibratorController.hasCapability(IVibrator.CAP_EXTERNAL_AMPLITUDE_CONTROL)) { pw.println(" External amplitude control"); } pw.println(""); diff --git a/services/core/java/com/android/server/am/ActiveInstrumentation.java b/services/core/java/com/android/server/am/ActiveInstrumentation.java index 43474d5f22d4..61ccf11ff73e 100644 --- a/services/core/java/com/android/server/am/ActiveInstrumentation.java +++ b/services/core/java/com/android/server/am/ActiveInstrumentation.java @@ -52,6 +52,9 @@ class ActiveInstrumentation { // Whether the caller holds START_ACTIVITIES_FROM_BACKGROUND permission boolean mHasBackgroundActivityStartsPermission; + // Whether the caller holds START_FOREGROUND_SERVICES_FROM_BACKGROUND permission + boolean mHasBackgroundForegroundServiceStartsPermission; + // As given to us Bundle mArguments; @@ -128,6 +131,8 @@ class ActiveInstrumentation { } pw.print("mHasBackgroundActivityStartsPermission="); pw.println(mHasBackgroundActivityStartsPermission); + pw.print("mHasBackgroundForegroundServiceStartsPermission="); + pw.println(mHasBackgroundForegroundServiceStartsPermission); pw.print(prefix); pw.print("mArguments="); pw.println(mArguments); } diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java index d6f72990e4ac..872902626fb4 100644 --- a/services/core/java/com/android/server/am/ActiveServices.java +++ b/services/core/java/com/android/server/am/ActiveServices.java @@ -17,6 +17,8 @@ package com.android.server.am; import static android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND; +import static android.Manifest.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND; +import static android.Manifest.permission.SYSTEM_ALERT_WINDOW; import static android.app.ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE; import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_MANIFEST; @@ -56,9 +58,11 @@ import android.app.PendingIntent; import android.app.Service; import android.app.ServiceStartArgs; import android.app.admin.DevicePolicyEventLogger; +import android.app.compat.CompatChanges; import android.appwidget.AppWidgetManagerInternal; import android.compat.annotation.ChangeId; import android.compat.annotation.Disabled; +import android.compat.annotation.EnabledSince; import android.content.ComponentName; import android.content.ComponentName.WithComponentName; import android.content.Context; @@ -104,7 +108,6 @@ import android.webkit.WebViewZygote; import com.android.internal.R; import com.android.internal.annotations.GuardedBy; import com.android.internal.app.procstats.ServiceState; -import com.android.internal.compat.IPlatformCompat; import com.android.internal.messages.nano.SystemMessageProto; import com.android.internal.notification.SystemNotificationChannels; import com.android.internal.os.BatteryStatsImpl; @@ -147,30 +150,40 @@ public final class ActiveServices { public static final int FGS_FEATURE_DENIED = 0; public static final int FGS_FEATURE_ALLOWED_BY_UID_STATE = 1; - public static final int FGS_FEATURE_ALLOWED_BY_UID_VISIBLE = 2; - public static final int FGS_FEATURE_ALLOWED_BY_FLAG = 3; - public static final int FGS_FEATURE_ALLOWED_BY_SYSTEM_UID = 4; - public static final int FGS_FEATURE_ALLOWED_BY_INSTR_PERMISSION = 5; - public static final int FGS_FEATURE_ALLOWED_BY_TOKEN = 6; - public static final int FGS_FEATURE_ALLOWED_BY_PERMISSION = 7; - public static final int FGS_FEATURE_ALLOWED_BY_WHITELIST = 8; - public static final int FGS_FEATURE_ALLOWED_BY_DEVICE_OWNER = 9; - public static final int FGS_FEATURE_ALLOWED_BY_PROC_STATE = 10; - public static final int FGS_FEATURE_ALLOWED_BY_DEVICE_IDLE_ALLOW_LIST = 11; + public static final int FGS_FEATURE_ALLOWED_BY_PROC_STATE = 2; + public static final int FGS_FEATURE_ALLOWED_BY_UID_VISIBLE = 3; + public static final int FGS_FEATURE_ALLOWED_BY_FLAG = 4; + public static final int FGS_FEATURE_ALLOWED_BY_SYSTEM_UID = 5; + public static final int FGS_FEATURE_ALLOWED_BY_INSTR_BACKGROUND_ACTIVITY_PERMISSION = 6; + public static final int FGS_FEATURE_ALLOWED_BY_INSTR_BACKGROUND_FGS_PERMISSION = 7; + public static final int FGS_FEATURE_ALLOWED_BY_ACTIVITY_TOKEN = 8; + public static final int FGS_FEATURE_ALLOWED_BY_FGS_TOKEN = 9; + public static final int FGS_FEATURE_ALLOWED_BY_BACKGROUND_ACTIVITY_PERMISSION = 10; + public static final int FGS_FEATURE_ALLOWED_BY_BACKGROUND_FGS_PERMISSION = 12; + public static final int FGS_FEATURE_ALLOWED_BY_ALLOWLIST = 13; + public static final int FGS_FEATURE_ALLOWED_BY_DEVICE_OWNER = 14; + public static final int FGS_FEATURE_ALLOWED_BY_DEVICE_IDLE_ALLOW_LIST = 15; + public static final int FGS_FEATURE_ALLOWED_BY_SYSTEM_ALERT_WINDOW_PERMISSION = 16; + public static final int FGS_FEATURE_ALLOWED_BY_FGS_BINDING = 17; @IntDef(flag = true, prefix = { "FGS_FEATURE_" }, value = { FGS_FEATURE_DENIED, FGS_FEATURE_ALLOWED_BY_UID_STATE, + FGS_FEATURE_ALLOWED_BY_PROC_STATE, FGS_FEATURE_ALLOWED_BY_UID_VISIBLE, FGS_FEATURE_ALLOWED_BY_FLAG, FGS_FEATURE_ALLOWED_BY_SYSTEM_UID, - FGS_FEATURE_ALLOWED_BY_INSTR_PERMISSION, - FGS_FEATURE_ALLOWED_BY_TOKEN, - FGS_FEATURE_ALLOWED_BY_PERMISSION, - FGS_FEATURE_ALLOWED_BY_WHITELIST, + FGS_FEATURE_ALLOWED_BY_INSTR_BACKGROUND_ACTIVITY_PERMISSION, + FGS_FEATURE_ALLOWED_BY_INSTR_BACKGROUND_FGS_PERMISSION, + FGS_FEATURE_ALLOWED_BY_ACTIVITY_TOKEN, + FGS_FEATURE_ALLOWED_BY_FGS_TOKEN, + FGS_FEATURE_ALLOWED_BY_BACKGROUND_ACTIVITY_PERMISSION, + FGS_FEATURE_ALLOWED_BY_BACKGROUND_FGS_PERMISSION, + FGS_FEATURE_ALLOWED_BY_ALLOWLIST, FGS_FEATURE_ALLOWED_BY_DEVICE_OWNER, - FGS_FEATURE_ALLOWED_BY_PROC_STATE, - FGS_FEATURE_ALLOWED_BY_DEVICE_IDLE_ALLOW_LIST + FGS_FEATURE_ALLOWED_BY_DEVICE_IDLE_ALLOW_LIST, + FGS_FEATURE_ALLOWED_BY_SYSTEM_ALERT_WINDOW_PERMISSION, + FGS_FEATURE_ALLOWED_BY_FGS_BINDING }) @Retention(RetentionPolicy.SOURCE) public @interface FgsFeatureRetCode {} @@ -242,14 +255,12 @@ public final class ActiveServices { AppWidgetManagerInternal mAppWidgetManagerInternal; // white listed packageName. - ArraySet<String> mWhiteListAllowWhileInUsePermissionInFgs = new ArraySet<>(); + ArraySet<String> mAllowListWhileInUsePermissionInFgs = new ArraySet<>(); // TODO: remove this after feature development is done private static final SimpleDateFormat DATE_FORMATTER = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - private final IPlatformCompat mPlatformCompat; - /** * The BG-launch FGS restriction feature is going to be allowed only for apps targetSdkVersion * is higher than R. @@ -258,6 +269,14 @@ public final class ActiveServices { @Disabled static final long FGS_BG_START_RESTRICTION_CHANGE_ID = 170668199L; + /** + * If a service can not become foreground service due to BG-FGS-launch restriction or other + * reasons, throws an IllegalStateException. + */ + @ChangeId + @EnabledSince(targetSdkVersion = android.os.Build.VERSION_CODES.S) + static final long FGS_START_EXCEPTION_CHANGE_ID = 174041399L; + final Runnable mLastAnrDumpClearer = new Runnable() { @Override public void run() { synchronized (mAm) { @@ -456,26 +475,25 @@ public final class ActiveServices { ? maxBg : ActivityManager.isLowRamDeviceStatic() ? 1 : 8; final IBinder b = ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE); - mPlatformCompat = IPlatformCompat.Stub.asInterface(b); } void systemServicesReady() { AppStateTracker ast = LocalServices.getService(AppStateTracker.class); ast.addServiceStateListener(new ForcedStandbyListener()); mAppWidgetManagerInternal = LocalServices.getService(AppWidgetManagerInternal.class); - setWhiteListAllowWhileInUsePermissionInFgs(); + setAllowListWhileInUsePermissionInFgs(); } - private void setWhiteListAllowWhileInUsePermissionInFgs() { + private void setAllowListWhileInUsePermissionInFgs() { final String attentionServicePackageName = mAm.mContext.getPackageManager().getAttentionServicePackageName(); if (!TextUtils.isEmpty(attentionServicePackageName)) { - mWhiteListAllowWhileInUsePermissionInFgs.add(attentionServicePackageName); + mAllowListWhileInUsePermissionInFgs.add(attentionServicePackageName); } final String systemCaptionsServicePackageName = mAm.mContext.getPackageManager().getSystemCaptionsServicePackageName(); if (!TextUtils.isEmpty(systemCaptionsServicePackageName)) { - mWhiteListAllowWhileInUsePermissionInFgs.add(systemCaptionsServicePackageName); + mAllowListWhileInUsePermissionInFgs.add(systemCaptionsServicePackageName); } } @@ -583,13 +601,27 @@ public final class ActiveServices { Slog.wtf(TAG, "Background started FGS " + r.mInfoAllowStartForeground); r.mLoggedInfoAllowStartForeground = true; } - if (r.mAllowStartForeground == FGS_FEATURE_DENIED - && (mAm.mConstants.mFlagFgsStartRestrictionEnabled - || isChangeEnabled(FGS_BG_START_RESTRICTION_CHANGE_ID, r))) { - Slog.w(TAG, "startForegroundService() not allowed due to " + if (r.mAllowStartForeground == FGS_FEATURE_DENIED && isBgFgsRestrictionEnabled(r)) { + String msg = "startForegroundService() not allowed due to " + "mAllowStartForeground false: service " - + r.shortInstanceName); + + r.shortInstanceName; + Slog.w(TAG, msg); showFgsBgRestrictedNotificationLocked(r); + ApplicationInfo aInfo = null; + try { + aInfo = AppGlobals.getPackageManager().getApplicationInfo( + callingPackage, ActivityManagerService.STOCK_PM_FLAGS, + userId); + } catch (android.os.RemoteException e) { + // pm is in same process, this will never happen. + } + if (aInfo == null) { + throw new SecurityException("startServiceLocked failed, " + + "could not resolve client package " + callingPackage); + } + if (CompatChanges.isChangeEnabled(FGS_START_EXCEPTION_CHANGE_ID, aInfo.uid)) { + throw new IllegalStateException(msg); + } return null; } } @@ -1449,7 +1481,7 @@ public final class ActiveServices { } try { - boolean ignoreForeground = false; + String ignoreForeground = null; final int mode = mAm.getAppOpsManager().checkOpNoThrow( AppOpsManager.OP_START_FOREGROUND, r.appInfo.uid, r.packageName); switch (mode) { @@ -1459,9 +1491,9 @@ public final class ActiveServices { break; case AppOpsManager.MODE_IGNORED: // Whoops, silently ignore this. - Slog.w(TAG, "Service.startForeground() not allowed due to app op: service " - + r.shortInstanceName); - ignoreForeground = true; + ignoreForeground = "Service.startForeground() not allowed due to app op: " + + "service " + r.shortInstanceName; + Slog.w(TAG, ignoreForeground); break; default: throw new SecurityException("Foreground not allowed as per app op"); @@ -1469,19 +1501,18 @@ public final class ActiveServices { // Apps that are TOP or effectively similar may call startForeground() on // their services even if they are restricted from doing that while in bg. - if (!ignoreForeground + if (ignoreForeground == null && !appIsTopLocked(r.appInfo.uid) && appRestrictedAnyInBackground(r.appInfo.uid, r.packageName)) { - Slog.w(TAG, - "Service.startForeground() not allowed due to bg restriction: service " - + r.shortInstanceName); + ignoreForeground = "Service.startForeground() not allowed due to bg restriction" + + ":service " + r.shortInstanceName; + Slog.w(TAG, ignoreForeground); // Back off of any foreground expectations around this service, since we've // just turned down its fg request. updateServiceForegroundLocked(r.app, false); - ignoreForeground = true; } - if (!ignoreForeground) { + if (ignoreForeground == null) { if (isFgsBgStart(r.mAllowStartForeground)) { if (!r.mLoggedInfoAllowStartForeground) { Slog.wtf(TAG, "Background started FGS " @@ -1489,14 +1520,13 @@ public final class ActiveServices { r.mLoggedInfoAllowStartForeground = true; } if (r.mAllowStartForeground == FGS_FEATURE_DENIED - && (mAm.mConstants.mFlagFgsStartRestrictionEnabled - || isChangeEnabled(FGS_BG_START_RESTRICTION_CHANGE_ID, r))) { - Slog.w(TAG, "Service.startForeground() not allowed due to " - + "mAllowStartForeground false: service " - + r.shortInstanceName); + && isBgFgsRestrictionEnabled(r)) { + ignoreForeground = "Service.startForeground() not allowed due to " + + "mAllowStartForeground false: service " + + r.shortInstanceName; + Slog.w(TAG, ignoreForeground); showFgsBgRestrictedNotificationLocked(r); updateServiceForegroundLocked(r.app, true); - ignoreForeground = true; } } } @@ -1505,7 +1535,7 @@ public final class ActiveServices { // services, so now that we've enforced the startForegroundService() contract // we only do the machinery of making the service foreground when the app // is not restricted. - if (!ignoreForeground) { + if (ignoreForeground == null) { if (r.foregroundId != id) { cancelForegroundNotificationLocked(r); r.foregroundId = id; @@ -1567,6 +1597,10 @@ public final class ActiveServices { if (DEBUG_FOREGROUND_SERVICE) { Slog.d(TAG, "Suppressing startForeground() for FAS " + r); } + if (CompatChanges.isChangeEnabled(FGS_START_EXCEPTION_CHANGE_ID, r.appInfo.uid) + && isBgFgsRestrictionEnabled(r)) { + throw new IllegalStateException(ignoreForeground); + } } } finally { if (stopProcStatsOp) { @@ -2094,6 +2128,12 @@ public final class ActiveServices { "BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS"); } + if ((flags & Context.BIND_ALLOW_FOREGROUND_SERVICE_STARTS_FROM_BACKGROUND) != 0) { + mAm.enforceCallingPermission( + android.Manifest.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND, + "BIND_ALLOW_FOREGROUND_SERVICE_STARTS_FROM_BACKGROUND"); + } + final boolean callerFg = callerApp.setSchedGroup != ProcessList.SCHED_GROUP_BACKGROUND; final boolean isBindExternal = (flags & Context.BIND_EXTERNAL_SERVICE) != 0; final boolean allowInstant = (flags & Context.BIND_ALLOW_INSTANT) != 0; @@ -2239,6 +2279,11 @@ public final class ActiveServices { if ((flags & Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS) != 0) { s.setAllowedBgActivityStartsByBinding(true); } + + if ((flags & Context.BIND_ALLOW_FOREGROUND_SERVICE_STARTS_FROM_BACKGROUND) != 0) { + s.setAllowedBgFgsStartsByBinding(true); + } + if (s.app != null) { updateServiceClientActivitiesLocked(s.app, c, true); } @@ -2256,7 +2301,6 @@ public final class ActiveServices { return 0; } } - setFgsRestrictionLocked(callingPackage, callingPid, callingUid, service, s, false); if (s.app != null) { @@ -3647,6 +3691,9 @@ public final class ActiveServices { if ((c.flags & Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS) != 0) { s.updateIsAllowedBgActivityStartsByBinding(); } + if ((c.flags & Context.BIND_ALLOW_FOREGROUND_SERVICE_STARTS_FROM_BACKGROUND) != 0) { + s.updateIsAllowedBgFgsStartsByBinding(); + } if (s.app != null) { updateServiceClientActivitiesLocked(s.app, c, true); } @@ -5113,13 +5160,22 @@ public final class ActiveServices { } if (ret == FGS_FEATURE_DENIED) { + for (int i = mAm.mProcessList.mLruProcesses.size() - 1; i >= 0; i--) { + final ProcessRecord pr = mAm.mProcessList.mLruProcesses.get(i); + if (pr.uid == callingUid) { + if (pr.areBackgroundActivityStartsAllowedByToken()) { + ret = FGS_FEATURE_ALLOWED_BY_ACTIVITY_TOKEN; + break; + } + } + } + } + + if (ret == FGS_FEATURE_DENIED) { if (r.app != null) { ActiveInstrumentation instr = r.app.getActiveInstrumentation(); if (instr != null && instr.mHasBackgroundActivityStartsPermission) { - ret = FGS_FEATURE_ALLOWED_BY_INSTR_PERMISSION; - } - if (r.app.areBackgroundActivityStartsAllowedByToken()) { - ret = FGS_FEATURE_ALLOWED_BY_TOKEN; + ret = FGS_FEATURE_ALLOWED_BY_INSTR_BACKGROUND_ACTIVITY_PERMISSION; } } } @@ -5127,15 +5183,15 @@ public final class ActiveServices { if (ret == FGS_FEATURE_DENIED) { if (mAm.checkPermission(START_ACTIVITIES_FROM_BACKGROUND, callingPid, callingUid) == PERMISSION_GRANTED) { - ret = FGS_FEATURE_ALLOWED_BY_PERMISSION; + ret = FGS_FEATURE_ALLOWED_BY_BACKGROUND_ACTIVITY_PERMISSION; } } if (ret == FGS_FEATURE_DENIED) { - final boolean isWhiteListedPackage = - mWhiteListAllowWhileInUsePermissionInFgs.contains(callingPackage); - if (isWhiteListedPackage) { - ret = FGS_FEATURE_ALLOWED_BY_WHITELIST; + final boolean isAllowedPackage = + mAllowListWhileInUsePermissionInFgs.contains(callingPackage); + if (isAllowedPackage) { + ret = FGS_FEATURE_ALLOWED_BY_ALLOWLIST; } } @@ -5187,6 +5243,39 @@ public final class ActiveServices { } if (ret == FGS_FEATURE_DENIED) { + for (int i = mAm.mProcessList.mLruProcesses.size() - 1; i >= 0; i--) { + final ProcessRecord pr = mAm.mProcessList.mLruProcesses.get(i); + if (pr.uid == callingUid) { + if (pr.areBackgroundFgsStartsAllowedByToken()) { + ret = FGS_FEATURE_ALLOWED_BY_FGS_BINDING; + break; + } else { + final ActiveInstrumentation instr = pr.getActiveInstrumentation(); + if (instr != null + && instr.mHasBackgroundForegroundServiceStartsPermission) { + ret = FGS_FEATURE_ALLOWED_BY_INSTR_BACKGROUND_FGS_PERMISSION; + break; + } + } + } + } + } + + if (ret == FGS_FEATURE_DENIED) { + if (mAm.checkPermission(START_FOREGROUND_SERVICES_FROM_BACKGROUND, callingPid, + callingUid) == PERMISSION_GRANTED) { + ret = FGS_FEATURE_ALLOWED_BY_BACKGROUND_FGS_PERMISSION; + } + } + + if (ret == FGS_FEATURE_DENIED) { + if (mAm.checkPermission(SYSTEM_ALERT_WINDOW, callingPid, + callingUid) == PERMISSION_GRANTED) { + ret = FGS_FEATURE_ALLOWED_BY_SYSTEM_ALERT_WINDOW_PERMISSION; + } + } + + if (ret == FGS_FEATURE_DENIED) { if (mAm.mConstants.mFlagFgsStartTempAllowListEnabled && mAm.isOnDeviceIdleWhitelistLocked(r.appInfo.uid, false)) { // uid is on DeviceIdleController's allowlist. @@ -5217,26 +5306,36 @@ public final class ActiveServices { return "DENIED"; case FGS_FEATURE_ALLOWED_BY_UID_STATE: return "ALLOWED_BY_UID_STATE"; + case FGS_FEATURE_ALLOWED_BY_PROC_STATE: + return "ALLOWED_BY_PROC_STATE"; case FGS_FEATURE_ALLOWED_BY_UID_VISIBLE: return "ALLOWED_BY_UID_VISIBLE"; case FGS_FEATURE_ALLOWED_BY_FLAG: return "ALLOWED_BY_FLAG"; case FGS_FEATURE_ALLOWED_BY_SYSTEM_UID: return "ALLOWED_BY_SYSTEM_UID"; - case FGS_FEATURE_ALLOWED_BY_INSTR_PERMISSION: - return "ALLOWED_BY_INSTR_PERMISSION"; - case FGS_FEATURE_ALLOWED_BY_TOKEN: - return "ALLOWED_BY_TOKEN"; - case FGS_FEATURE_ALLOWED_BY_PERMISSION: - return "ALLOWED_BY_PERMISSION"; - case FGS_FEATURE_ALLOWED_BY_WHITELIST: + case FGS_FEATURE_ALLOWED_BY_INSTR_BACKGROUND_ACTIVITY_PERMISSION: + return "ALLOWED_BY_INSTR_BACKGROUND_ACTIVITY_PERMISSION"; + case FGS_FEATURE_ALLOWED_BY_INSTR_BACKGROUND_FGS_PERMISSION: + return "ALLOWED_BY_INSTR_BACKGROUND_FGS_PERMISSION"; + case FGS_FEATURE_ALLOWED_BY_ACTIVITY_TOKEN: + return "ALLOWED_BY_ACTIVITY_TOKEN"; + case FGS_FEATURE_ALLOWED_BY_FGS_TOKEN: + return "ALLOWED_BY_FGS_TOKEN"; + case FGS_FEATURE_ALLOWED_BY_BACKGROUND_ACTIVITY_PERMISSION: + return "ALLOWED_BY_BACKGROUND_ACTIVITY_PERMISSION"; + case FGS_FEATURE_ALLOWED_BY_BACKGROUND_FGS_PERMISSION: + return "ALLOWED_BY_BACKGROUND_FGS_PERMISSION"; + case FGS_FEATURE_ALLOWED_BY_ALLOWLIST: return "ALLOWED_BY_WHITELIST"; case FGS_FEATURE_ALLOWED_BY_DEVICE_OWNER: return "ALLOWED_BY_DEVICE_OWNER"; - case FGS_FEATURE_ALLOWED_BY_PROC_STATE: - return "ALLOWED_BY_PROC_STATE"; case FGS_FEATURE_ALLOWED_BY_DEVICE_IDLE_ALLOW_LIST: return "ALLOWED_BY_DEVICE_IDLE_ALLOW_LIST"; + case FGS_FEATURE_ALLOWED_BY_SYSTEM_ALERT_WINDOW_PERMISSION: + return "ALLOWED_BY_SYSTEM_ALERT_WINDOW_PERMISSION"; + case FGS_FEATURE_ALLOWED_BY_FGS_BINDING: + return "ALLOWED_BY_FGS_BINDING"; default: return ""; } @@ -5271,11 +5370,10 @@ public final class ActiveServices { NOTE_FOREGROUND_SERVICE_BG_LAUNCH, n.build(), UserHandle.ALL); } - private boolean isChangeEnabled(long changeId, ServiceRecord r) { - boolean enabled = false; - try { - enabled = mPlatformCompat.isChangeEnabled(changeId, r.appInfo); - } catch (RemoteException e) { } - return enabled; + private boolean isBgFgsRestrictionEnabled(ServiceRecord r) { + if (mAm.mConstants.mFlagFgsStartRestrictionEnabled) { + return true; + } + return CompatChanges.isChangeEnabled(FGS_BG_START_RESTRICTION_CHANGE_ID, r.appInfo.uid); } } diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 9eca15b241f4..75e8b13ccc0d 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -22,6 +22,7 @@ import static android.Manifest.permission.FILTER_EVENTS; import static android.Manifest.permission.INTERACT_ACROSS_USERS; import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; import static android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND; +import static android.Manifest.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND; import static android.app.ActivityManager.INSTR_FLAG_DISABLE_HIDDEN_API_CHECKS; import static android.app.ActivityManager.INSTR_FLAG_DISABLE_ISOLATED_STORAGE; import static android.app.ActivityManager.INSTR_FLAG_DISABLE_TEST_API_CHECKS; @@ -13321,15 +13322,22 @@ public class ActivityManagerService extends IActivityManager.Stub // See if the caller is allowed to do this. Note we are checking against // the actual real caller (not whoever provided the operation as say a // PendingIntent), because that who is actually supplied the arguments. - if (checkComponentPermission( - android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST, + if (checkComponentPermission(CHANGE_DEVICE_IDLE_TEMP_WHITELIST, + realCallingPid, realCallingUid, -1, true) + != PackageManager.PERMISSION_GRANTED + && checkComponentPermission(START_ACTIVITIES_FROM_BACKGROUND, + realCallingPid, realCallingUid, -1, true) + != PackageManager.PERMISSION_GRANTED + && checkComponentPermission(START_FOREGROUND_SERVICES_FROM_BACKGROUND, realCallingPid, realCallingUid, -1, true) != PackageManager.PERMISSION_GRANTED) { String msg = "Permission Denial: " + intent.getAction() + " broadcast from " + callerPackage + " (pid=" + callingPid + ", uid=" + callingUid + ")" + " requires " - + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST; + + CHANGE_DEVICE_IDLE_TEMP_WHITELIST + " or " + + START_ACTIVITIES_FROM_BACKGROUND + " or " + + START_FOREGROUND_SERVICES_FROM_BACKGROUND; Slog.w(TAG, msg); throw new SecurityException(msg); } @@ -14289,8 +14297,10 @@ public class ActivityManagerService extends IActivityManager.Stub activeInstr.mHasBackgroundActivityStartsPermission = checkPermission( START_ACTIVITIES_FROM_BACKGROUND, callingPid, callingUid) == PackageManager.PERMISSION_GRANTED; + activeInstr.mHasBackgroundForegroundServiceStartsPermission = checkPermission( + START_FOREGROUND_SERVICES_FROM_BACKGROUND, callingPid, callingUid) + == PackageManager.PERMISSION_GRANTED; activeInstr.mNoRestart = noRestart; - boolean disableHiddenApiChecks = ai.usesNonSdkApi() || (flags & INSTR_FLAG_DISABLE_HIDDEN_API_CHECKS) != 0; boolean disableTestApiChecks = disableHiddenApiChecks diff --git a/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java b/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java index 93dd1aa37a11..fdc0f5949da8 100644 --- a/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java +++ b/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java @@ -37,13 +37,14 @@ import android.util.Slog; import com.android.internal.annotations.GuardedBy; import com.android.internal.os.BatteryStatsImpl; +import com.android.internal.power.MeasuredEnergyArray; import com.android.internal.util.FrameworkStatsLog; import com.android.internal.util.function.pooled.PooledLambda; -import java.util.concurrent.ExecutionException; import libcore.util.EmptyArray; import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; import java.util.concurrent.Executor; import java.util.concurrent.Executors; import java.util.concurrent.Future; @@ -103,6 +104,9 @@ class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStatsSync { private boolean mOnBatteryScreenOff; @GuardedBy("this") + private int mScreenState; + + @GuardedBy("this") private boolean mUseLatestStates = true; @GuardedBy("this") @@ -194,15 +198,17 @@ class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStatsSync { } @Override - public Future<?> scheduleCpuSyncDueToScreenStateChange( - boolean onBattery, boolean onBatteryScreenOff) { + public Future<?> scheduleSyncDueToScreenStateChange( + int flags, boolean onBattery, boolean onBatteryScreenOff, int screenState) { synchronized (BatteryExternalStatsWorker.this) { if (mCurrentFuture == null || (mUpdateFlags & UPDATE_CPU) == 0) { mOnBattery = onBattery; mOnBatteryScreenOff = onBatteryScreenOff; mUseLatestStates = false; } - return scheduleSyncLocked("screen-state", UPDATE_CPU); + // always update screen state + mScreenState = screenState; + return scheduleSyncLocked("screen-state", flags); } } @@ -332,6 +338,7 @@ class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStatsSync { final int[] uidsToRemove; final boolean onBattery; final boolean onBatteryScreenOff; + final int screenState; final boolean useLatestStates; synchronized (BatteryExternalStatsWorker.this) { updateFlags = mUpdateFlags; @@ -339,6 +346,7 @@ class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStatsSync { uidsToRemove = mUidsToRemove.size() > 0 ? mUidsToRemove.toArray() : EmptyArray.INT; onBattery = mOnBattery; onBatteryScreenOff = mOnBatteryScreenOff; + screenState = mScreenState; useLatestStates = mUseLatestStates; mUpdateFlags = 0; mCurrentReason = null; @@ -360,7 +368,7 @@ class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStatsSync { } try { updateExternalStatsLocked(reason, updateFlags, onBattery, - onBatteryScreenOff, useLatestStates); + onBatteryScreenOff, screenState, useLatestStates); } finally { if (DEBUG) { Slog.d(TAG, "end updateExternalStatsSync"); @@ -402,13 +410,14 @@ class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStatsSync { }; @GuardedBy("mWorkerLock") - private void updateExternalStatsLocked(final String reason, int updateFlags, - boolean onBattery, boolean onBatteryScreenOff, boolean useLatestStates) { + private void updateExternalStatsLocked(final String reason, int updateFlags, boolean onBattery, + boolean onBatteryScreenOff, int screenState, boolean useLatestStates) { // We will request data from external processes asynchronously, and wait on a timeout. SynchronousResultReceiver wifiReceiver = null; SynchronousResultReceiver bluetoothReceiver = null; CompletableFuture<ModemActivityInfo> modemFuture = CompletableFuture.completedFuture(null); boolean railUpdated = false; + MeasuredEnergyArray energyArray = null; if ((updateFlags & BatteryStatsImpl.ExternalStatsSync.UPDATE_WIFI) != 0) { // We were asked to fetch WiFi data. @@ -486,6 +495,13 @@ class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStatsSync { } } + if ((updateFlags & UPDATE_ENERGY) != 0) { + synchronized (mStats) { + // TODO(b/172934873) evaluate a safe way to query the HAL without holding mStats + energyArray = mStats.getEnergyConsumptionDataLocked(); + } + } + final WifiActivityEnergyInfo wifiInfo = awaitControllerInfo(wifiReceiver); final BluetoothActivityEnergyInfo bluetoothInfo = awaitControllerInfo(bluetoothReceiver); ModemActivityInfo modemInfo = null; @@ -533,6 +549,11 @@ class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStatsSync { Slog.w(TAG, "bluetooth info is invalid: " + bluetoothInfo); } } + + if ((updateFlags & UPDATE_ENERGY) != 0 && energyArray != null) { + // Always use what BatteryExternalStatsWorker thinks screenState is. + mStats.updateMeasuredEnergyStatsLocked(energyArray, screenState); + } } // WiFi and Modem state are updated without the mStats lock held, because they diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java index ed2faf992e0e..46e16bcbb1b6 100644 --- a/services/core/java/com/android/server/am/BatteryStatsService.java +++ b/services/core/java/com/android/server/am/BatteryStatsService.java @@ -21,6 +21,8 @@ import android.content.ContentResolver; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; +import android.hardware.power.stats.EnergyConsumerId; +import android.hardware.power.stats.EnergyConsumerResult; import android.os.BatteryStats; import android.os.BatteryStatsInternal; import android.os.Binder; @@ -59,6 +61,7 @@ import com.android.internal.os.BinderCallsStats; import com.android.internal.os.PowerProfile; import com.android.internal.os.RailStats; import com.android.internal.os.RpmStats; +import com.android.internal.power.MeasuredEnergyArray; import com.android.internal.util.DumpUtils; import com.android.internal.util.FrameworkStatsLog; import com.android.internal.util.ParseUtils; @@ -66,6 +69,7 @@ import com.android.internal.util.function.pooled.PooledLambda; import com.android.server.LocalServices; import com.android.server.Watchdog; import com.android.server.pm.UserManagerInternal; +import com.android.server.powerstats.PowerStatsHALWrapper; import java.io.File; import java.io.FileDescriptor; @@ -90,7 +94,7 @@ import java.util.concurrent.Future; public final class BatteryStatsService extends IBatteryStats.Stub implements PowerManagerInternal.LowPowerModeListener, BatteryStatsImpl.PlatformIdleStateCallback, - BatteryStatsImpl.RailEnergyDataCallback, + BatteryStatsImpl.MeasuredEnergyRetriever, Watchdog.Monitor { static final String TAG = "BatteryStatsService"; static final boolean DBG = false; @@ -115,6 +119,8 @@ public final class BatteryStatsService extends IBatteryStats.Stub private CharBuffer mUtf16BufferStat = CharBuffer.allocate(MAX_LOW_POWER_STATS_SIZE); private static final int MAX_LOW_POWER_STATS_SIZE = 4096; + private final PowerStatsHALWrapper.IPowerStatsHALWrapper mPowerStatsHALWrapper; + private final HandlerThread mHandlerThread; private final Handler mHandler; private final Object mLock = new Object(); @@ -186,6 +192,43 @@ public final class BatteryStatsService extends IBatteryStats.Stub } } + @Override + public MeasuredEnergyArray getEnergyConsumptionData() { + final EnergyConsumerResult[] results = mPowerStatsHALWrapper.getEnergyConsumed(new int[0]); + if (results == null) return null; + final int size = results.length; + final int[] subsystems = new int[size]; + final long[] energyUJ = new long[size]; + + for (int i = 0; i < size; i++) { + final EnergyConsumerResult consumer = results[i]; + final int subsystem; + switch (consumer.energyConsumerId) { + case EnergyConsumerId.DISPLAY: + subsystem = MeasuredEnergyArray.SUBSYSTEM_DISPLAY; + break; + default: + continue; + } + subsystems[i] = subsystem; + energyUJ[i] = consumer.energyUWs; + } + return new MeasuredEnergyArray() { + @Override + public int getSubsystem(int index) { + return subsystems[index]; + } + @Override + public long getEnergy(int index) { + return energyUJ[index]; + } + @Override + public int size() { + return size; + } + }; + } + BatteryStatsService(Context context, File systemDir, Handler handler) { // BatteryStatsImpl expects the ActivityManagerService handler, so pass that one through. mContext = context; @@ -202,6 +245,12 @@ public final class BatteryStatsService extends IBatteryStats.Stub mHandlerThread = new HandlerThread("batterystats-handler"); mHandlerThread.start(); mHandler = new Handler(mHandlerThread.getLooper()); + + // TODO(b/173077356): Replace directly calling the HAL with PowerStatsService queries + // Make sure to init Hal Wrapper before creating BatteryStatsImpl. + mPowerStatsHALWrapper = new PowerStatsHALWrapper.PowerStatsHALWrapperImpl(); + mPowerStatsHALWrapper.initialize(); + mStats = new BatteryStatsImpl(systemDir, handler, this, this, mUserManagerUserInfoProvider); mWorker = new BatteryExternalStatsWorker(context, mStats); @@ -1963,6 +2012,15 @@ public final class BatteryStatsService extends IBatteryStats.Stub } } + private void dumpMeasuredEnergyStats(PrintWriter pw) { + // Wait for the completion of pending works if there is any + awaitCompletion(); + syncStats("dump", BatteryExternalStatsWorker.UPDATE_ENERGY); + synchronized (mStats) { + mStats.dumpMeasuredEnergyStatsLocked(pw); + } + } + private int doEnableOrDisable(PrintWriter pw, int i, String[] args, boolean enable) { i++; if (i >= args.length) { @@ -2103,6 +2161,9 @@ public final class BatteryStatsService extends IBatteryStats.Stub } else if ("--cpu".equals(arg)) { dumpCpuStats(pw); return; + } else if ("--measured-energy".equals(arg)) { + dumpMeasuredEnergyStats(pw); + return; } else if ("-a".equals(arg)) { flags |= BatteryStats.DUMP_VERBOSE; } else if (arg.length() > 0 && arg.charAt(0) == '-'){ diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java index 1b06dd90df83..cf4adc65a7fc 100644 --- a/services/core/java/com/android/server/am/ProcessRecord.java +++ b/services/core/java/com/android/server/am/ProcessRecord.java @@ -359,6 +359,8 @@ class ProcessRecord implements WindowProcessListener { // It must obtain the proc state from a persistent/top process or FGS, not transitive. int mAllowStartFgsState = PROCESS_STATE_NONEXISTENT; + private final ArraySet<Binder> mBackgroundFgsStartTokens = new ArraySet<>(); + void setStartParams(int startUid, HostingRecord hostingRecord, String seInfo, long startTime) { this.startUid = startUid; @@ -1965,6 +1967,18 @@ class ProcessRecord implements WindowProcessListener { } } + public void addAllowBackgroundFgsStartsToken(Binder entity) { + mBackgroundFgsStartTokens.add(entity); + } + + public void removeAllowBackgroundFgsStartsToken(Binder entity) { + mBackgroundFgsStartTokens.remove(entity); + } + + public boolean areBackgroundFgsStartsAllowedByToken() { + return !mBackgroundFgsStartTokens.isEmpty(); + } + ErrorDialogController getDialogController() { return mDialogController; } diff --git a/services/core/java/com/android/server/am/ServiceRecord.java b/services/core/java/com/android/server/am/ServiceRecord.java index 364ad21b93cf..e129561b8bc5 100644 --- a/services/core/java/com/android/server/am/ServiceRecord.java +++ b/services/core/java/com/android/server/am/ServiceRecord.java @@ -147,6 +147,10 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN @GuardedBy("ams") private List<IBinder> mBgActivityStartsByStartOriginatingTokens = new ArrayList<>(); + // any current binding to this service has BIND_ALLOW_FOREGROUND_SERVICE_STARTS_FROM_BACKGROUND + // flag? if true, the process can start FGS from background. + boolean mIsAllowedBgFgsStartsByBinding; + // allow while-in-use permissions in foreground service or not. // while-in-use permissions in FGS started from background might be restricted. boolean mAllowWhileInUsePermissionInFgs; @@ -418,6 +422,10 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN pw.print(prefix); pw.print("mIsAllowedBgActivityStartsByStart="); pw.println(mIsAllowedBgActivityStartsByStart); } + if (mIsAllowedBgFgsStartsByBinding) { + pw.print(prefix); pw.print("mIsAllowedBgFgsStartsByBinding="); + pw.println(mIsAllowedBgFgsStartsByBinding); + } pw.print(prefix); pw.print("allowWhileInUsePermissionInFgs="); pw.println(mAllowWhileInUsePermissionInFgs); pw.print(prefix); pw.print("recentCallingPackage="); @@ -600,6 +608,11 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN } else { _proc.removeAllowBackgroundActivityStartsToken(this); } + if (mIsAllowedBgFgsStartsByBinding) { + _proc.addAllowBackgroundFgsStartsToken(this); + } else { + _proc.removeAllowBackgroundFgsStartsToken(this); + } } if (app != null && app != _proc) { // If the old app is allowed to start bg activities because of a service start, leave it @@ -686,11 +699,34 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN setAllowedBgActivityStartsByBinding(isAllowedByBinding); } + void updateIsAllowedBgFgsStartsByBinding() { + boolean isAllowedByBinding = false; + for (int conni = connections.size() - 1; conni >= 0; conni--) { + ArrayList<ConnectionRecord> cr = connections.valueAt(conni); + for (int i = 0; i < cr.size(); i++) { + if ((cr.get(i).flags + & Context.BIND_ALLOW_FOREGROUND_SERVICE_STARTS_FROM_BACKGROUND) != 0) { + isAllowedByBinding = true; + break; + } + } + if (isAllowedByBinding) { + break; + } + } + setAllowedBgFgsStartsByBinding(isAllowedByBinding); + } + void setAllowedBgActivityStartsByBinding(boolean newValue) { mIsAllowedBgActivityStartsByBinding = newValue; updateParentProcessBgActivityStartsToken(); } + void setAllowedBgFgsStartsByBinding(boolean newValue) { + mIsAllowedBgFgsStartsByBinding = newValue; + updateParentProcessBgFgsStartsToken(); + } + /** * Called when the service is started with allowBackgroundActivityStarts set. We allow * it for background activity starts, setting up a callback to remove this ability after a @@ -777,6 +813,17 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN } } + private void updateParentProcessBgFgsStartsToken() { + if (app == null) { + return; + } + if (mIsAllowedBgFgsStartsByBinding) { + app.addAllowBackgroundFgsStartsToken(this); + } else { + app.removeAllowBackgroundFgsStartsToken(this); + } + } + /** * Returns the originating token if that's the only reason background activity starts are * allowed. In order for that to happen the service has to be allowed only due to starts, since diff --git a/services/core/java/com/android/server/biometrics/AuthSession.java b/services/core/java/com/android/server/biometrics/AuthSession.java index efc025dd7b0c..e4d90525fc68 100644 --- a/services/core/java/com/android/server/biometrics/AuthSession.java +++ b/services/core/java/com/android/server/biometrics/AuthSession.java @@ -142,6 +142,7 @@ public final class AuthSession implements IBinder.DeathRecipient { @NonNull PromptInfo promptInfo, boolean debugEnabled, @NonNull List<FingerprintSensorPropertiesInternal> fingerprintSensorProperties) { + Slog.d(TAG, "Creating AuthSession with: " + preAuthInfo); mContext = context; mStatusBarService = statusBarService; mSysuiReceiver = sysuiReceiver; diff --git a/services/core/java/com/android/server/biometrics/BiometricService.java b/services/core/java/com/android/server/biometrics/BiometricService.java index a471664b19b7..0194259d6289 100644 --- a/services/core/java/com/android/server/biometrics/BiometricService.java +++ b/services/core/java/com/android/server/biometrics/BiometricService.java @@ -500,7 +500,11 @@ public class BiometricService extends SystemService { final List<SensorPropertiesInternal> sensors = new ArrayList<>(); for (BiometricSensor sensor : mSensors) { - sensors.add(sensor.impl.getSensorProperties(opPackageName)); + // Explicitly re-create as the super class, since AIDL doesn't play nicely with + // "List<? extends SensorPropertiesInternal> ... + final SensorPropertiesInternal prop = SensorPropertiesInternal + .from(sensor.impl.getSensorProperties(opPackageName)); + sensors.add(prop); } return sensors; @@ -1043,7 +1047,7 @@ public class BiometricService extends SystemService { final Pair<Integer, Integer> preAuthStatus = preAuthInfo.getPreAuthenticateStatus(); Slog.d(TAG, "handleAuthenticate: modality(" + preAuthStatus.first - + "), status(" + preAuthStatus.second + ")"); + + "), status(" + preAuthStatus.second + "), preAuthInfo: " + preAuthInfo); if (preAuthStatus.second == BiometricConstants.BIOMETRIC_SUCCESS) { // If BIOMETRIC_WEAK or BIOMETRIC_STRONG are allowed, but not enrolled, but diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java index 36796b842410..cc9298603a3e 100644 --- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java +++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java @@ -65,7 +65,6 @@ import java.util.List; * Provider for a single instance of the {@link IFace} HAL. */ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider { - private static final String TAG = "FaceProvider"; private static final int ENROLL_TIMEOUT_SEC = 75; private boolean mTestHalEnabled; @@ -88,7 +87,7 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider { public void onTaskStackChanged() { mHandler.post(() -> { for (int i = 0; i < mSensors.size(); i++) { - final ClientMonitor<?> client = mSensors.get(i).getScheduler() + final ClientMonitor<?> client = mSensors.valueAt(i).getScheduler() .getCurrentClient(); if (!(client instanceof AuthenticationClient)) { Slog.e(getTag(), "Task stack changed for client: " + client); @@ -108,7 +107,7 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider { && !client.isAlreadyDone()) { Slog.e(getTag(), "Stopping background authentication, top: " + topPackage + " currentClient: " + client); - mSensors.get(i).getScheduler() + mSensors.valueAt(i).getScheduler() .cancelAuthentication(client.getToken()); } } @@ -550,12 +549,13 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider { JSONObject dump = new JSONObject(); try { - dump.put("service", "Face Manager"); + dump.put("service", getTag()); JSONArray sets = new JSONArray(); for (UserInfo user : UserManager.get(mContext).getUsers()) { final int userId = user.getUserHandle().getIdentifier(); - final int c = FaceUtils.getInstance().getBiometricsForUser(mContext, userId).size(); + final int c = FaceUtils.getInstance(sensorId) + .getBiometricsForUser(mContext, userId).size(); JSONObject set = new JSONObject(); set.put("id", userId); set.put("count", c); @@ -574,7 +574,7 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider { dump.put("prints", sets); } catch (JSONException e) { - Slog.e(TAG, "dump formatting failure", e); + Slog.e(getTag(), "dump formatting failure", e); } pw.println(dump); pw.println("HAL deaths since last reboot: " + performanceTracker.getHALDeathCount()); diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/TestSession.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/TestSession.java index 9707eddfee74..fbc26c6498b3 100644 --- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/TestSession.java +++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/TestSession.java @@ -24,7 +24,6 @@ import android.hardware.common.NativeHandle; import android.hardware.keymaster.HardwareAuthToken; import android.os.Binder; import android.os.IBinder; -import android.os.RemoteException; /** * Test session that provides mostly no-ops. @@ -59,7 +58,7 @@ public class TestSession extends ISession.Stub { public ICancellationSignal authenticate(int cookie, long operationId) { return new ICancellationSignal() { @Override - public void cancel() throws RemoteException { + public void cancel() { mHalSessionCallback.onError(Error.CANCELED, 0 /* vendorCode */); } diff --git a/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java b/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java index c57ab505ca2a..d384bc645d61 100644 --- a/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java +++ b/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java @@ -796,7 +796,7 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider { JSONObject dump = new JSONObject(); try { - dump.put("service", "Face Manager"); + dump.put("service", TAG); JSONArray sets = new JSONArray(); for (UserInfo user : UserManager.get(mContext).getUsers()) { diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java index db34d1444650..98c32cbcfc4a 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java @@ -53,6 +53,10 @@ import com.android.server.biometrics.sensors.fingerprint.GestureAvailabilityDisp import com.android.server.biometrics.sensors.fingerprint.ServiceProvider; import com.android.server.biometrics.sensors.fingerprint.Udfps; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; @@ -84,7 +88,7 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi public void onTaskStackChanged() { mHandler.post(() -> { for (int i = 0; i < mSensors.size(); i++) { - final ClientMonitor<?> client = mSensors.get(i).getScheduler() + final ClientMonitor<?> client = mSensors.valueAt(i).getScheduler() .getCurrentClient(); if (!(client instanceof AuthenticationClient)) { Slog.e(getTag(), "Task stack changed for client: " + client); @@ -104,7 +108,7 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi && !client.isAlreadyDone()) { Slog.e(getTag(), "Stopping background authentication, top: " + topPackage + " currentClient: " + client); - mSensors.get(i).getScheduler() + mSensors.valueAt(i).getScheduler() .cancelAuthentication(client.getToken()); } } @@ -593,7 +597,42 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi @Override public void dumpInternal(int sensorId, @NonNull PrintWriter pw) { + PerformanceTracker performanceTracker = + PerformanceTracker.getInstanceForSensorId(sensorId); + + JSONObject dump = new JSONObject(); + try { + dump.put("service", getTag()); + + JSONArray sets = new JSONArray(); + for (UserInfo user : UserManager.get(mContext).getUsers()) { + final int userId = user.getUserHandle().getIdentifier(); + final int c = FingerprintUtils.getInstance(sensorId) + .getBiometricsForUser(mContext, userId).size(); + JSONObject set = new JSONObject(); + set.put("id", userId); + set.put("count", c); + set.put("accept", performanceTracker.getAcceptForUser(userId)); + set.put("reject", performanceTracker.getRejectForUser(userId)); + set.put("acquire", performanceTracker.getAcquireForUser(userId)); + set.put("lockout", performanceTracker.getTimedLockoutForUser(userId)); + set.put("permanentLockout", performanceTracker.getPermanentLockoutForUser(userId)); + // cryptoStats measures statistics about secure fingerprint transactions + // (e.g. to unlock password storage, make secure purchases, etc.) + set.put("acceptCrypto", performanceTracker.getAcceptCryptoForUser(userId)); + set.put("rejectCrypto", performanceTracker.getRejectCryptoForUser(userId)); + set.put("acquireCrypto", performanceTracker.getAcquireCryptoForUser(userId)); + sets.put(set); + } + + dump.put("prints", sets); + } catch (JSONException e) { + Slog.e(getTag(), "dump formatting failure", e); + } + pw.println(dump); + pw.println("HAL deaths since last reboot: " + performanceTracker.getHALDeathCount()); + mSensors.get(sensorId).getScheduler().dump(pw); } @NonNull diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/TestSession.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/TestSession.java index d6378780594f..ddae1107ff77 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/TestSession.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/TestSession.java @@ -18,8 +18,11 @@ package com.android.server.biometrics.sensors.fingerprint.aidl; import android.annotation.NonNull; import android.hardware.biometrics.common.ICancellationSignal; +import android.hardware.biometrics.face.Error; import android.hardware.biometrics.fingerprint.ISession; import android.hardware.keymaster.HardwareAuthToken; +import android.os.Binder; +import android.os.IBinder; import android.util.Slog; /** @@ -37,24 +40,32 @@ class TestSession extends ISession.Stub { @Override public void generateChallenge(int cookie, int timeoutSec) { - + mHalSessionCallback.onChallengeGenerated(0 /* challenge */); } @Override public void revokeChallenge(int cookie, long challenge) { - + mHalSessionCallback.onChallengeRevoked(challenge); } @Override public ICancellationSignal enroll(int cookie, HardwareAuthToken hat) { - Slog.d(TAG, "enroll"); return null; } @Override public ICancellationSignal authenticate(int cookie, long operationId) { - Slog.d(TAG, "authenticate"); - return null; + return new ICancellationSignal() { + @Override + public void cancel() { + mHalSessionCallback.onError(Error.CANCELED, 0 /* vendorCode */); + } + + @Override + public IBinder asBinder() { + return new Binder(); + } + }; } @Override @@ -86,7 +97,7 @@ class TestSession extends ISession.Stub { @Override public void resetLockout(int cookie, HardwareAuthToken hat) { - + mHalSessionCallback.onLockoutCleared(); } @Override diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java index 11372a30599d..f38dd092007a 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java @@ -776,7 +776,7 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider JSONObject dump = new JSONObject(); try { - dump.put("service", "Fingerprint Manager"); + dump.put("service", TAG); JSONArray sets = new JSONArray(); for (UserInfo user : UserManager.get(mContext).getUsers()) { diff --git a/services/core/java/com/android/server/display/DisplayDeviceInfo.java b/services/core/java/com/android/server/display/DisplayDeviceInfo.java index fe6500e8942c..468d8259db18 100644 --- a/services/core/java/com/android/server/display/DisplayDeviceInfo.java +++ b/services/core/java/com/android/server/display/DisplayDeviceInfo.java @@ -22,6 +22,7 @@ import android.util.DisplayMetrics; import android.view.Display; import android.view.DisplayAddress; import android.view.DisplayCutout; +import android.view.DisplayEventReceiver; import android.view.Surface; import java.util.Arrays; @@ -333,6 +334,9 @@ final class DisplayDeviceInfo { */ public String ownerPackageName; + public DisplayEventReceiver.FrameRateOverride[] frameRateOverrides = + new DisplayEventReceiver.FrameRateOverride[0]; + public void setAssumedDensityForExternalDisplay(int width, int height) { densityDpi = Math.min(width, height) * DisplayMetrics.DENSITY_XHIGH / 1080; // Technically, these values should be smaller than the apparent density @@ -386,7 +390,8 @@ final class DisplayDeviceInfo { || !Objects.equals(address, other.address) || !Objects.equals(deviceProductInfo, other.deviceProductInfo) || ownerUid != other.ownerUid - || !Objects.equals(ownerPackageName, other.ownerPackageName)) { + || !Objects.equals(ownerPackageName, other.ownerPackageName) + || !Objects.equals(frameRateOverrides, other.frameRateOverrides)) { diff |= DIFF_OTHER; } return diff; @@ -425,6 +430,7 @@ final class DisplayDeviceInfo { state = other.state; ownerUid = other.ownerUid; ownerPackageName = other.ownerPackageName; + frameRateOverrides = other.frameRateOverrides; } // For debugging purposes @@ -461,6 +467,10 @@ final class DisplayDeviceInfo { sb.append(", owner ").append(ownerPackageName); sb.append(" (uid ").append(ownerUid).append(")"); } + sb.append(", frameRateOverride "); + for (DisplayEventReceiver.FrameRateOverride frameRateOverride : frameRateOverrides) { + sb.append(frameRateOverride).append(" "); + } sb.append(flagsToString(flags)); sb.append("}"); return sb.toString(); diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java index 4e60f1ff929e..29b413d921e1 100644 --- a/services/core/java/com/android/server/display/DisplayManagerService.java +++ b/services/core/java/com/android/server/display/DisplayManagerService.java @@ -37,6 +37,9 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; import android.app.AppOpsManager; +import android.app.compat.CompatChanges; +import android.compat.annotation.ChangeId; +import android.compat.annotation.EnabledSince; import android.content.Context; import android.content.pm.PackageManager; import android.content.pm.ParceledListSlice; @@ -83,7 +86,9 @@ import android.os.Trace; import android.os.UserHandle; import android.os.UserManager; import android.provider.Settings; +import android.sysprop.DisplayProperties; import android.text.TextUtils; +import android.util.ArraySet; import android.util.EventLog; import android.util.IntArray; import android.util.Pair; @@ -92,6 +97,7 @@ import android.util.SparseArray; import android.util.SparseIntArray; import android.util.Spline; import android.view.Display; +import android.view.DisplayEventReceiver; import android.view.DisplayInfo; import android.view.IDisplayFoldListener; import android.view.Surface; @@ -114,6 +120,7 @@ import com.android.server.wm.WindowManagerInternal; import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; +import java.util.Arrays; import java.util.Optional; import java.util.concurrent.CopyOnWriteArrayList; import java.util.function.Consumer; @@ -181,6 +188,7 @@ public final class DisplayManagerService extends SystemService { private static final int MSG_REQUEST_TRAVERSAL = 4; private static final int MSG_UPDATE_VIEWPORT = 5; private static final int MSG_LOAD_BRIGHTNESS_CONFIGURATION = 6; + private static final int MSG_DELIVER_DISPLAY_EVENT_FRAME_RATE_OVERRIDE = 7; private final Context mContext; private final DisplayManagerHandler mHandler; @@ -357,6 +365,30 @@ public final class DisplayManagerService extends SystemService { // Received notifications of the display-fold action private DisplayFoldListener mDisplayFoldListener; + private final boolean mAllowNonNativeRefreshRateOverride; + + private static final float THRESHOLD_FOR_REFRESH_RATES_DIVIDERS = 0.1f; + + /** + * Applications use {@link android.view.Display#getRefreshRate} and + * {@link android.view.Display.Mode#getRefreshRate} to know what is the display refresh rate. + * Starting with Android S, the platform might throttle down applications frame rate to a + * divisor of the refresh rate if it is more preferable (for example if the application called + * to {@link android.view.Surface#setFrameRate}). + * Applications will experience {@link android.view.Choreographer#postFrameCallback} callbacks + * and backpressure at the throttled frame rate. + * + * {@link android.view.Display#getRefreshRate} will always return the application frame rate + * and not the physical display refresh rate to allow applications to do frame pacing correctly. + * + * {@link android.view.Display.Mode#getRefreshRate} will return the application frame rate if + * compiled to a previous release and starting with Android S it will return the physical + * display refresh rate. + */ + @ChangeId + @EnabledSince(targetSdkVersion = android.os.Build.VERSION_CODES.S) + static final long DISPLAY_MODE_RETURNS_PHYSICAL_REFRESH_RATE = 170503758L; + public DisplayManagerService(Context context) { this(context, new Injector()); } @@ -389,6 +421,7 @@ public final class DisplayManagerService extends SystemService { mCurrentUserId = UserHandle.USER_SYSTEM; ColorSpace[] colorSpaces = SurfaceControl.getCompositionColorSpaces(); mWideColorSpace = colorSpaces[1]; + mAllowNonNativeRefreshRateOverride = mInjector.getAllowNonNativeRefreshRateOverride(); mSystemReady = false; } @@ -677,11 +710,82 @@ public final class DisplayManagerService extends SystemService { Settings.Secure.MINIMAL_POST_PROCESSING_ALLOWED, 1, UserHandle.USER_CURRENT) != 0; } + private DisplayInfo getDisplayInfoForFrameRateOverride(DisplayEventReceiver.FrameRateOverride[] + frameRateOverrides, DisplayInfo info, int callingUid) { + float frameRateHz = 0; + for (DisplayEventReceiver.FrameRateOverride frameRateOverride : frameRateOverrides) { + if (frameRateOverride.uid == callingUid) { + frameRateHz = frameRateOverride.frameRateHz; + break; + } + } + if (frameRateHz == 0) { + return info; + } + + // Override the refresh rate only if it is a divider of the current + // refresh rate. This calculation needs to be in sync with the native code + // in RefreshRateConfigs::getRefreshRateDividerForUid + Display.Mode currentMode = info.getMode(); + float numPeriods = currentMode.getRefreshRate() / frameRateHz; + float numPeriodsRound = Math.round(numPeriods); + if (Math.abs(numPeriods - numPeriodsRound) > THRESHOLD_FOR_REFRESH_RATES_DIVIDERS) { + return info; + } + frameRateHz = currentMode.getRefreshRate() / numPeriodsRound; + + DisplayInfo overriddenInfo = new DisplayInfo(); + overriddenInfo.copyFrom(info); + for (Display.Mode mode : info.supportedModes) { + if (!mode.equalsExceptRefreshRate(currentMode)) { + continue; + } + + if (mode.getRefreshRate() >= frameRateHz - THRESHOLD_FOR_REFRESH_RATES_DIVIDERS + && mode.getRefreshRate() + <= frameRateHz + THRESHOLD_FOR_REFRESH_RATES_DIVIDERS) { + if (DEBUG) { + Slog.d(TAG, "found matching modeId " + mode.getModeId()); + } + overriddenInfo.refreshRateOverride = mode.getRefreshRate(); + + if (!CompatChanges.isChangeEnabled(DISPLAY_MODE_RETURNS_PHYSICAL_REFRESH_RATE, + callingUid)) { + overriddenInfo.modeId = mode.getModeId(); + } + return overriddenInfo; + } + } + + if (mAllowNonNativeRefreshRateOverride) { + overriddenInfo.refreshRateOverride = frameRateHz; + if (!CompatChanges.isChangeEnabled(DISPLAY_MODE_RETURNS_PHYSICAL_REFRESH_RATE, + callingUid)) { + overriddenInfo.supportedModes = Arrays.copyOf(info.supportedModes, + info.supportedModes.length + 1); + overriddenInfo.supportedModes[overriddenInfo.supportedModes.length - 1] = + new Display.Mode(Display.DISPLAY_MODE_ID_FOR_FRAME_RATE_OVERRIDE, + currentMode.getPhysicalWidth(), currentMode.getPhysicalHeight(), + overriddenInfo.refreshRateOverride); + overriddenInfo.modeId = + overriddenInfo.supportedModes[overriddenInfo.supportedModes.length - 1] + .getModeId(); + } + return overriddenInfo; + } + + + + return info; + } + private DisplayInfo getDisplayInfoInternal(int displayId, int callingUid) { synchronized (mSyncRoot) { LogicalDisplay display = mLogicalDisplayMapper.getLocked(displayId); if (display != null) { - DisplayInfo info = display.getDisplayInfoLocked(); + DisplayInfo info = + getDisplayInfoForFrameRateOverride(display.getFrameRateOverrides(), + display.getDisplayInfoLocked(), callingUid); if (info.hasAccess(callingUid) || isUidPresentOnDisplayInternal(callingUid, displayId)) { return info; @@ -691,14 +795,15 @@ public final class DisplayManagerService extends SystemService { } } - private void registerCallbackInternal(IDisplayManagerCallback callback, int callingPid) { + private void registerCallbackInternal(IDisplayManagerCallback callback, int callingPid, + int callingUid) { synchronized (mSyncRoot) { if (mCallbacks.get(callingPid) != null) { throw new SecurityException("The calling process has already " + "registered an IDisplayManagerCallback."); } - CallbackRecord record = new CallbackRecord(callingPid, callback); + CallbackRecord record = new CallbackRecord(callingPid, callingUid, callback); try { IBinder binder = callback.asBinder(); binder.linkToDeath(record, 0); @@ -1034,6 +1139,16 @@ public final class DisplayManagerService extends SystemService { scheduleTraversalLocked(false); } + private void handleLogicalDisplayFrameRateOverridesChangedLocked( + @NonNull LogicalDisplay display) { + final int displayId = display.getDisplayIdLocked(); + // We don't bother invalidating the display info caches here because any changes to the + // display info will trigger a cache invalidation inside of LogicalDisplay before we hit + // this point. + sendDisplayEventFrameRateOverrideLocked(displayId); + scheduleTraversalLocked(false); + } + private void handleLogicalDisplayRemovedLocked(@NonNull LogicalDisplay display) { final int displayId = display.getDisplayIdLocked(); mDisplayPowerControllers.delete(displayId); @@ -1545,6 +1660,12 @@ public final class DisplayManagerService extends SystemService { mHandler.sendMessage(msg); } + private void sendDisplayEventFrameRateOverrideLocked(int displayId) { + Message msg = mHandler.obtainMessage(MSG_DELIVER_DISPLAY_EVENT_FRAME_RATE_OVERRIDE, + displayId, DisplayManagerGlobal.EVENT_DISPLAY_CHANGED); + mHandler.sendMessage(msg); + } + // Requests that performTraversals be called at a // later time to apply changes to surfaces and displays. private void scheduleTraversalLocked(boolean inTraversal) { @@ -1558,7 +1679,7 @@ public final class DisplayManagerService extends SystemService { // Runs on Handler thread. // Delivers display event notifications to callbacks. - private void deliverDisplayEvent(int displayId, int event) { + private void deliverDisplayEvent(int displayId, ArraySet<Integer> uids, int event) { if (DEBUG) { Slog.d(TAG, "Delivering display event: displayId=" + displayId + ", event=" + event); @@ -1570,12 +1691,14 @@ public final class DisplayManagerService extends SystemService { count = mCallbacks.size(); mTempCallbacks.clear(); for (int i = 0; i < count; i++) { - mTempCallbacks.add(mCallbacks.valueAt(i)); + if (uids == null || uids.contains(mCallbacks.valueAt(i).mUid)) { + mTempCallbacks.add(mCallbacks.valueAt(i)); + } } } // After releasing the lock, send the notifications out. - for (int i = 0; i < count; i++) { + for (int i = 0; i < mTempCallbacks.size(); i++) { mTempCallbacks.get(i).notifyDisplayEventAsync(displayId, event); } mTempCallbacks.clear(); @@ -1691,6 +1814,11 @@ public final class DisplayManagerService extends SystemService { long getDefaultDisplayDelayTimeout() { return WAIT_FOR_DEFAULT_DISPLAY_TIMEOUT; } + + boolean getAllowNonNativeRefreshRateOverride() { + return DisplayProperties + .debug_allow_non_native_refresh_rate_override().orElse(false); + } } @VisibleForTesting @@ -1760,7 +1888,7 @@ public final class DisplayManagerService extends SystemService { break; case MSG_DELIVER_DISPLAY_EVENT: - deliverDisplayEvent(msg.arg1, msg.arg2); + deliverDisplayEvent(msg.arg1, null, msg.arg2); break; case MSG_REQUEST_TRAVERSAL: @@ -1787,6 +1915,17 @@ public final class DisplayManagerService extends SystemService { case MSG_LOAD_BRIGHTNESS_CONFIGURATION: loadBrightnessConfiguration(); break; + + case MSG_DELIVER_DISPLAY_EVENT_FRAME_RATE_OVERRIDE: + ArraySet<Integer> uids; + synchronized (mSyncRoot) { + int displayId = msg.arg1; + LogicalDisplay display = mLogicalDisplayMapper.getLocked(displayId); + uids = display.getPendingFrameRateOverrideUids(); + display.clearPendingFrameRateOverrideUids(); + } + deliverDisplayEvent(msg.arg1, uids, msg.arg2); + break; } } } @@ -1810,6 +1949,10 @@ public final class DisplayManagerService extends SystemService { case LogicalDisplayMapper.LOGICAL_DISPLAY_EVENT_SWAPPED: handleLogicalDisplaySwappedLocked(display); break; + + case LogicalDisplayMapper.LOGICAL_DISPLAY_EVENT_FRAME_RATE_OVERRIDES_CHANGED: + handleLogicalDisplayFrameRateOverridesChangedLocked(display); + break; } } @@ -1823,12 +1966,14 @@ public final class DisplayManagerService extends SystemService { private final class CallbackRecord implements DeathRecipient { public final int mPid; + public final int mUid; private final IDisplayManagerCallback mCallback; public boolean mWifiDisplayScanRequested; - public CallbackRecord(int pid, IDisplayManagerCallback callback) { + CallbackRecord(int pid, int uid, IDisplayManagerCallback callback) { mPid = pid; + mUid = uid; mCallback = callback; } @@ -1918,9 +2063,10 @@ public final class DisplayManagerService extends SystemService { } final int callingPid = Binder.getCallingPid(); + final int callingUid = Binder.getCallingUid(); final long token = Binder.clearCallingIdentity(); try { - registerCallbackInternal(callback, callingPid); + registerCallbackInternal(callback, callingPid, callingUid); } finally { Binder.restoreCallingIdentity(token); } diff --git a/services/core/java/com/android/server/display/LocalDisplayAdapter.java b/services/core/java/com/android/server/display/LocalDisplayAdapter.java index f6578584cb18..74ea2d7114fc 100644 --- a/services/core/java/com/android/server/display/LocalDisplayAdapter.java +++ b/services/core/java/com/android/server/display/LocalDisplayAdapter.java @@ -208,6 +208,9 @@ final class LocalDisplayAdapter extends DisplayAdapter { private DisplayDeviceConfig mDisplayDeviceConfig; + private DisplayEventReceiver.FrameRateOverride[] mFrameRateOverrides = + new DisplayEventReceiver.FrameRateOverride[0]; + LocalDisplayDevice(IBinder displayToken, long physicalDisplayId, SurfaceControl.DisplayInfo info, SurfaceControl.DisplayConfig[] configs, int activeConfigId, SurfaceControl.DesiredDisplayConfigSpecs configSpecs, @@ -625,6 +628,8 @@ final class LocalDisplayAdapter extends DisplayAdapter { mInfo.name = getContext().getResources().getString( com.android.internal.R.string.display_manager_hdmi_display_name); } + mInfo.frameRateOverrides = mFrameRateOverrides; + // The display is trusted since it is created by system. mInfo.flags |= DisplayDeviceInfo.FLAG_TRUSTED; } @@ -882,6 +887,13 @@ final class LocalDisplayAdapter extends DisplayAdapter { } } + public void onFrameRateOverridesChanged( + DisplayEventReceiver.FrameRateOverride[] overrides) { + if (updateFrameRateOverridesLocked(overrides)) { + updateDeviceInfoLocked(); + } + } + public boolean updateActiveModeLocked(int activeConfigId) { if (mActiveConfigId == activeConfigId) { return false; @@ -895,6 +907,16 @@ final class LocalDisplayAdapter extends DisplayAdapter { return true; } + public boolean updateFrameRateOverridesLocked( + DisplayEventReceiver.FrameRateOverride[] overrides) { + if (overrides.equals(mFrameRateOverrides)) { + return false; + } + + mFrameRateOverrides = overrides; + return true; + } + public void requestColorModeLocked(int colorMode) { if (mActiveColorMode == colorMode) { return; @@ -1102,23 +1124,39 @@ final class LocalDisplayAdapter extends DisplayAdapter { public interface DisplayEventListener { void onHotplug(long timestampNanos, long physicalDisplayId, boolean connected); void onConfigChanged(long timestampNanos, long physicalDisplayId, int configId); + void onFrameRateOverridesChanged(long timestampNanos, long physicalDisplayId, + DisplayEventReceiver.FrameRateOverride[] overrides); + } public static final class ProxyDisplayEventReceiver extends DisplayEventReceiver { private final DisplayEventListener mListener; ProxyDisplayEventReceiver(Looper looper, DisplayEventListener listener) { - super(looper, VSYNC_SOURCE_APP, CONFIG_CHANGED_EVENT_DISPATCH); + super(looper, VSYNC_SOURCE_APP, + EVENT_REGISTRATION_CONFIG_CHANGED_FLAG + | EVENT_REGISTRATION_FRAME_RATE_OVERRIDE_FLAG); mListener = listener; } + + @Override public void onHotplug(long timestampNanos, long physicalDisplayId, boolean connected) { mListener.onHotplug(timestampNanos, physicalDisplayId, connected); } + + @Override public void onConfigChanged(long timestampNanos, long physicalDisplayId, int configId) { mListener.onConfigChanged(timestampNanos, physicalDisplayId, configId); } + + @Override + public void onFrameRateOverridesChanged(long timestampNanos, long physicalDisplayId, + DisplayEventReceiver.FrameRateOverride[] overrides) { + mListener.onFrameRateOverridesChanged(timestampNanos, physicalDisplayId, overrides); + } } private final class LocalDisplayEventListener implements DisplayEventListener { + @Override public void onHotplug(long timestampNanos, long physicalDisplayId, boolean connected) { synchronized (getSyncRoot()) { if (connected) { @@ -1128,6 +1166,8 @@ final class LocalDisplayAdapter extends DisplayAdapter { } } } + + @Override public void onConfigChanged(long timestampNanos, long physicalDisplayId, int configId) { if (DEBUG) { Slog.d(TAG, "onConfigChanged(" @@ -1147,5 +1187,26 @@ final class LocalDisplayAdapter extends DisplayAdapter { device.onActiveDisplayConfigChangedLocked(configId); } } + + @Override + public void onFrameRateOverridesChanged(long timestampNanos, long physicalDisplayId, + DisplayEventReceiver.FrameRateOverride[] overrides) { + if (DEBUG) { + Slog.d(TAG, "onFrameRateOverrideChanged(timestampNanos=" + timestampNanos + + ", physicalDisplayId=" + physicalDisplayId + " overrides=" + + Arrays.toString(overrides) + ")"); + } + synchronized (getSyncRoot()) { + LocalDisplayDevice device = mDevices.get(physicalDisplayId); + if (device == null) { + if (DEBUG) { + Slog.d(TAG, "Received frame rate override event for unhandled physical" + + " display: physicalDisplayId=" + physicalDisplayId); + } + return; + } + device.onFrameRateOverridesChanged(overrides); + } + } } } diff --git a/services/core/java/com/android/server/display/LogicalDisplay.java b/services/core/java/com/android/server/display/LogicalDisplay.java index 979c3b871284..d80e1687f67f 100644 --- a/services/core/java/com/android/server/display/LogicalDisplay.java +++ b/services/core/java/com/android/server/display/LogicalDisplay.java @@ -20,8 +20,11 @@ import android.annotation.NonNull; import android.graphics.Point; import android.graphics.Rect; import android.hardware.display.DisplayManagerInternal; +import android.util.ArraySet; import android.util.Slog; +import android.util.SparseArray; import android.view.Display; +import android.view.DisplayEventReceiver; import android.view.DisplayInfo; import android.view.Surface; import android.view.SurfaceControl; @@ -123,10 +126,27 @@ final class LogicalDisplay { */ private boolean mIsEnabled = true; + /** + * The UID mappings for refresh rate override + */ + private DisplayEventReceiver.FrameRateOverride[] mFrameRateOverrides; + + /** + * Holds a set of UIDs that their frame rate override changed and needs to be notified + */ + private ArraySet<Integer> mPendingFrameRateOverrideUids; + + /** + * Temporary frame rate override list, used when needed. + */ + private final SparseArray<Float> mTempFrameRateOverride; + public LogicalDisplay(int displayId, int layerStack, DisplayDevice primaryDisplayDevice) { mDisplayId = displayId; mLayerStack = layerStack; mPrimaryDisplayDevice = primaryDisplayDevice; + mPendingFrameRateOverrideUids = new ArraySet<>(); + mTempFrameRateOverride = new SparseArray<>(); } /** @@ -179,6 +199,27 @@ final class LogicalDisplay { } /** + * Returns the frame rate overrides list + */ + public DisplayEventReceiver.FrameRateOverride[] getFrameRateOverrides() { + return mFrameRateOverrides; + } + + /** + * Returns the list of uids that needs to be updated about their frame rate override + */ + public ArraySet<Integer> getPendingFrameRateOverrideUids() { + return mPendingFrameRateOverrideUids; + } + + /** + * Clears the list of uids that needs to be updated about their frame rate override + */ + public void clearPendingFrameRateOverrideUids() { + mPendingFrameRateOverrideUids = new ArraySet<>(); + } + + /** * @see DisplayManagerInternal#getNonOverrideDisplayInfo(int, DisplayInfo) */ void getNonOverrideDisplayInfoLocked(DisplayInfo outInfo) { @@ -324,12 +365,40 @@ final class LogicalDisplay { (deviceInfo.flags & DisplayDeviceInfo.FLAG_MASK_DISPLAY_CUTOUT) != 0; mBaseDisplayInfo.displayCutout = maskCutout ? null : deviceInfo.displayCutout; mBaseDisplayInfo.displayId = mDisplayId; + updateFrameRateOverrides(deviceInfo); mPrimaryDisplayDeviceInfo = deviceInfo; mInfo.set(null); } } + private void updateFrameRateOverrides(DisplayDeviceInfo deviceInfo) { + mTempFrameRateOverride.clear(); + if (mFrameRateOverrides != null) { + for (DisplayEventReceiver.FrameRateOverride frameRateOverride + : mFrameRateOverrides) { + mTempFrameRateOverride.put(frameRateOverride.uid, + frameRateOverride.frameRateHz); + } + } + mFrameRateOverrides = deviceInfo.frameRateOverrides; + if (mFrameRateOverrides != null) { + for (DisplayEventReceiver.FrameRateOverride frameRateOverride + : mFrameRateOverrides) { + float refreshRate = mTempFrameRateOverride.get(frameRateOverride.uid, 0f); + if (refreshRate == 0 || frameRateOverride.frameRateHz != refreshRate) { + mTempFrameRateOverride.put(frameRateOverride.uid, + frameRateOverride.frameRateHz); + } else { + mTempFrameRateOverride.delete(frameRateOverride.uid); + } + } + } + for (int i = 0; i < mTempFrameRateOverride.size(); i++) { + mPendingFrameRateOverrideUids.add(mTempFrameRateOverride.keyAt(i)); + } + } + /** * Return the insets currently applied to the display. * @@ -638,5 +707,7 @@ final class LogicalDisplay { pw.println("mBaseDisplayInfo=" + mBaseDisplayInfo); pw.println("mOverrideDisplayInfo=" + mOverrideDisplayInfo); pw.println("mRequestedMinimalPostProcessing=" + mRequestedMinimalPostProcessing); + pw.println("mFrameRateOverrides=" + Arrays.toString(mFrameRateOverrides)); + pw.println("mPendingFrameRateOverrideUids=" + mPendingFrameRateOverrideUids); } } diff --git a/services/core/java/com/android/server/display/LogicalDisplayMapper.java b/services/core/java/com/android/server/display/LogicalDisplayMapper.java index 6b741709321c..cdcbb4f123a1 100644 --- a/services/core/java/com/android/server/display/LogicalDisplayMapper.java +++ b/services/core/java/com/android/server/display/LogicalDisplayMapper.java @@ -23,6 +23,7 @@ import android.text.TextUtils; import android.util.Slog; import android.util.SparseArray; import android.view.Display; +import android.view.DisplayEventReceiver; import android.view.DisplayInfo; import com.android.internal.util.IndentingPrintWriter; @@ -52,6 +53,7 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { public static final int LOGICAL_DISPLAY_EVENT_CHANGED = 2; public static final int LOGICAL_DISPLAY_EVENT_REMOVED = 3; public static final int LOGICAL_DISPLAY_EVENT_SWAPPED = 4; + public static final int LOGICAL_DISPLAY_EVENT_FRAME_RATE_OVERRIDES_CHANGED = 5; /** * Temporary display info, used for comparing display configurations. @@ -342,6 +344,8 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { mTempDisplayInfo.copyFrom(display.getDisplayInfoLocked()); display.getNonOverrideDisplayInfoLocked(mTempNonOverrideDisplayInfo); + DisplayEventReceiver.FrameRateOverride[] frameRatesOverrides = + display.getFrameRateOverrides(); display.updateLocked(mDisplayDeviceRepo); if (!display.isValidLocked()) { mLogicalDisplays.removeAt(i); @@ -376,6 +380,9 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { final int eventMsg = TextUtils.equals(oldUniqueId, newUniqueId) ? LOGICAL_DISPLAY_EVENT_CHANGED : LOGICAL_DISPLAY_EVENT_SWAPPED; mListener.onLogicalDisplayEventLocked(display, eventMsg); + } else if (!display.getPendingFrameRateOverrideUids().isEmpty()) { + mListener.onLogicalDisplayEventLocked(display, + LogicalDisplayMapper.LOGICAL_DISPLAY_EVENT_FRAME_RATE_OVERRIDES_CHANGED); } else { // While applications shouldn't know nor care about the non-overridden info, we // still need to let WindowManager know so it can update its own internal state for diff --git a/services/core/java/com/android/server/display/OverlayDisplayWindow.java b/services/core/java/com/android/server/display/OverlayDisplayWindow.java index 49f0d35d2e78..cd3a453d5e64 100644 --- a/services/core/java/com/android/server/display/OverlayDisplayWindow.java +++ b/services/core/java/com/android/server/display/OverlayDisplayWindow.java @@ -16,8 +16,6 @@ package com.android.server.display; -import com.android.internal.util.DumpUtils; - import android.content.Context; import android.graphics.SurfaceTexture; import android.hardware.display.DisplayManager; @@ -30,12 +28,14 @@ import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.ScaleGestureDetector; import android.view.TextureView; +import android.view.TextureView.SurfaceTextureListener; import android.view.ThreadedRenderer; import android.view.View; import android.view.WindowManager; -import android.view.TextureView.SurfaceTextureListener; import android.widget.TextView; +import com.android.internal.util.DumpUtils; + import java.io.PrintWriter; /** @@ -319,7 +319,7 @@ final class OverlayDisplayWindow implements DumpUtils.Dump { public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int width, int height) { mListener.onWindowCreated(surfaceTexture, - mDefaultDisplayInfo.getMode().getRefreshRate(), + mDefaultDisplayInfo.getRefreshRate(), mDefaultDisplayInfo.presentationDeadlineNanos, mDefaultDisplayInfo.state); } diff --git a/services/core/java/com/android/server/hdmi/Constants.java b/services/core/java/com/android/server/hdmi/Constants.java index 42dcbeb73fff..d0e7e459e7f2 100644 --- a/services/core/java/com/android/server/hdmi/Constants.java +++ b/services/core/java/com/android/server/hdmi/Constants.java @@ -507,6 +507,15 @@ final class Constants { static final int ALL_DEVICE_TYPES_PLAYBACK = 4; static final int ALL_DEVICE_TYPES_AUDIO_SYSTEM = 3; static final int ALL_DEVICE_TYPES_SWITCH = 2; + @IntDef({ + ALL_DEVICE_TYPES_TV, + ALL_DEVICE_TYPES_RECORDER, + ALL_DEVICE_TYPES_TUNER, + ALL_DEVICE_TYPES_PLAYBACK, + ALL_DEVICE_TYPES_AUDIO_SYSTEM, + ALL_DEVICE_TYPES_SWITCH + }) + @interface DeviceType {} static final int DEVICE_FEATURE_TV_SUPPORTS_RECORD_TV_SCREEN = 6; static final int DEVICE_FEATURE_TV_SUPPORTS_SET_OSD_STRING = 5; @@ -514,21 +523,51 @@ final class Constants { static final int DEVICE_FEATURE_SUPPORTS_SET_AUDIO_RATE = 3; static final int DEVICE_FEATURE_SINK_SUPPORTS_ARC_TX = 2; static final int DEVICE_FEATURE_SOURCE_SUPPORTS_ARC_RX = 1; + @IntDef({ + DEVICE_FEATURE_TV_SUPPORTS_RECORD_TV_SCREEN, + DEVICE_FEATURE_TV_SUPPORTS_SET_OSD_STRING, + DEVICE_FEATURE_SUPPORTS_DECK_CONTROL, + DEVICE_FEATURE_SUPPORTS_SET_AUDIO_RATE, + DEVICE_FEATURE_SINK_SUPPORTS_ARC_TX, + DEVICE_FEATURE_SOURCE_SUPPORTS_ARC_RX + }) + @interface DeviceFeature {} static final int RC_PROFILE_TV = 0; static final int RC_PROFILE_SOURCE = 1; + @IntDef({ + RC_PROFILE_TV, + RC_PROFILE_SOURCE + }) + @interface RcProfile {} static final int RC_PROFILE_TV_NONE = 0x0; static final int RC_PROFILE_TV_ONE = 0x2; static final int RC_PROFILE_TV_TWO = 0x6; static final int RC_PROFILE_TV_THREE = 0xA; static final int RC_PROFILE_TV_FOUR = 0xE; + @IntDef({ + RC_PROFILE_TV_NONE, + RC_PROFILE_TV_ONE, + RC_PROFILE_TV_TWO, + RC_PROFILE_TV_THREE, + RC_PROFILE_TV_FOUR + }) + @interface RcProfileTv {} static final int RC_PROFILE_SOURCE_HANDLES_ROOT_MENU = 4; static final int RC_PROFILE_SOURCE_HANDLES_SETUP_MENU = 3; static final int RC_PROFILE_SOURCE_HANDLES_CONTENTS_MENU = 2; static final int RC_PROFILE_SOURCE_HANDLES_TOP_MENU = 1; static final int RC_PROFILE_SOURCE_HANDLES_MEDIA_CONTEXT_SENSITIVE_MENU = 0; + @IntDef({ + RC_PROFILE_SOURCE_HANDLES_ROOT_MENU, + RC_PROFILE_SOURCE_HANDLES_SETUP_MENU, + RC_PROFILE_SOURCE_HANDLES_CONTENTS_MENU, + RC_PROFILE_SOURCE_HANDLES_TOP_MENU, + RC_PROFILE_SOURCE_HANDLES_MEDIA_CONTEXT_SENSITIVE_MENU + }) + @interface RcProfileSource {} private Constants() { /* cannot be instantiated */ diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java index fb71d9510627..1cbbe2dc5b6a 100755 --- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java @@ -554,6 +554,7 @@ abstract class HdmiCecLocalDevice { return false; } + @Constants.RcProfile protected abstract int getRcProfile(); protected abstract List<Integer> getRcFeatures(); diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java index 46b09dc07e61..a945c90d30ef 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java @@ -47,8 +47,6 @@ import com.android.server.hdmi.HdmiAnnotations.ServiceThreadOnly; import com.android.server.hdmi.HdmiUtils.CodecSad; import com.android.server.hdmi.HdmiUtils.DeviceConfig; -import com.google.android.collect.Lists; - import org.xmlpull.v1.XmlPullParserException; import java.io.File; @@ -179,7 +177,13 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource { @Override protected List<Integer> getDeviceFeatures() { - return Lists.newArrayList(Constants.DEVICE_FEATURE_SOURCE_SUPPORTS_ARC_RX); + List<Integer> deviceFeatures = new ArrayList<>(); + + if (SystemProperties.getBoolean(Constants.PROPERTY_ARC_SUPPORT, true)) { + deviceFeatures.add(Constants.DEVICE_FEATURE_SOURCE_SUPPORTS_ARC_RX); + } + + return deviceFeatures; } @Override diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceSource.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceSource.java index 3b3ac747db6c..59ebdd597279 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceSource.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceSource.java @@ -296,6 +296,7 @@ abstract class HdmiCecLocalDeviceSource extends HdmiCecLocalDevice { // do nothing } + @Constants.RcProfile @Override protected int getRcProfile() { return Constants.RC_PROFILE_SOURCE; @@ -303,10 +304,8 @@ abstract class HdmiCecLocalDeviceSource extends HdmiCecLocalDevice { @Override protected List<Integer> getRcFeatures() { - return Lists.newArrayList(Constants.RC_PROFILE_SOURCE_HANDLES_CONTENTS_MENU, - Constants.RC_PROFILE_SOURCE_HANDLES_ROOT_MENU, - Constants.RC_PROFILE_SOURCE_HANDLES_SETUP_MENU, - Constants.RC_PROFILE_SOURCE_HANDLES_TOP_MENU); + return Lists.newArrayList(Constants.RC_PROFILE_SOURCE_HANDLES_ROOT_MENU, + Constants.RC_PROFILE_SOURCE_HANDLES_SETUP_MENU); } @Override diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java index 8cf6c9757fe8..11e18c54b1e4 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java @@ -53,6 +53,7 @@ import com.android.server.hdmi.HdmiControlService.SendMessageCallback; import com.google.android.collect.Lists; +import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; @@ -1480,6 +1481,7 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { return true; } + @Constants.RcProfile @Override protected int getRcProfile() { return Constants.RC_PROFILE_TV; @@ -1492,8 +1494,21 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { @Override protected List<Integer> getDeviceFeatures() { - return Lists.newArrayList(Constants.DEVICE_FEATURE_SINK_SUPPORTS_ARC_TX, - Constants.DEVICE_FEATURE_TV_SUPPORTS_RECORD_TV_SCREEN); + List<Integer> deviceFeatures = new ArrayList<>(); + + boolean hasArcPort = false; + List<HdmiPortInfo> ports = mService.getPortInfo(); + for (HdmiPortInfo port : ports) { + if (isArcFeatureEnabled(port.getId())) { + hasArcPort = true; + break; + } + } + if (hasArcPort) { + deviceFeatures.add(Constants.DEVICE_FEATURE_SINK_SUPPORTS_ARC_TX); + } + deviceFeatures.add(Constants.DEVICE_FEATURE_TV_SUPPORTS_RECORD_TV_SCREEN); + return deviceFeatures; } @Override diff --git a/services/core/java/com/android/server/hdmi/HdmiCecMessageBuilder.java b/services/core/java/com/android/server/hdmi/HdmiCecMessageBuilder.java index 96303ce9a76c..0a8621b3e726 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecMessageBuilder.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecMessageBuilder.java @@ -697,8 +697,10 @@ public class HdmiCecMessageBuilder { } static HdmiCecMessage buildReportFeatures(int src, - @HdmiControlManager.HdmiCecVersion int cecVersion, List<Integer> allDeviceTypes, - int rcProfile, List<Integer> rcFeatures, List<Integer> deviceFeatures) { + @HdmiControlManager.HdmiCecVersion int cecVersion, + List<Integer> allDeviceTypes, @Constants.RcProfile int rcProfile, + List<Integer> rcFeatures, + List<Integer> deviceFeatures) { byte cecVersionByte = (byte) (cecVersion & 0xFF); byte deviceTypes = 0; for (Integer deviceType : allDeviceTypes) { @@ -708,16 +710,16 @@ public class HdmiCecMessageBuilder { byte rcProfileByte = 0; rcProfileByte |= rcProfile << 6; if (rcProfile == Constants.RC_PROFILE_SOURCE) { - for (Integer rcFeature : rcFeatures) { + for (@Constants.RcProfileSource Integer rcFeature : rcFeatures) { rcProfileByte |= 1 << rcFeature; } } else { - byte rcProfileTv = (byte) (rcFeatures.get(0) & 0xFFFF); + @Constants.RcProfileTv byte rcProfileTv = (byte) (rcFeatures.get(0) & 0xFFFF); rcProfileByte |= rcProfileTv; } byte deviceFeaturesByte = 0; - for (Integer deviceFeature : deviceFeatures) { + for (@Constants.DeviceFeature Integer deviceFeature : deviceFeatures) { deviceFeaturesByte |= 1 << deviceFeature; } @@ -777,6 +779,7 @@ public class HdmiCecMessageBuilder { }; } + @Constants.DeviceType private static int hdmiDeviceInfoDeviceTypeToShiftValue(int deviceType) { switch (deviceType) { case HdmiDeviceInfo.DEVICE_TV: diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java index cfb5116c47f3..0ceaf7748eba 100644 --- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java +++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java @@ -15,6 +15,7 @@ package com.android.server.inputmethod; +import static android.inputmethodservice.InputMethodService.FINISH_INPUT_NO_FALLBACK_CONNECTION; import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_CRITICAL; import static android.os.IServiceManager.DUMP_FLAG_PROTO; import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER; @@ -45,6 +46,8 @@ import static android.server.inputmethod.InputMethodManagerServiceProto.SYSTEM_R import static android.util.imetracing.ImeTracing.IME_TRACING_FROM_IMMS; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.Display.INVALID_DISPLAY; +import static android.view.WindowManager.DISPLAY_IME_POLICY_HIDE; +import static android.view.WindowManager.DISPLAY_IME_POLICY_LOCAL; import static java.lang.annotation.RetentionPolicy.SOURCE; @@ -118,7 +121,6 @@ import android.util.ArrayMap; import android.util.ArraySet; import android.util.EventLog; import android.util.IndentingPrintWriter; -import android.util.Log; import android.util.LruCache; import android.util.Pair; import android.util.PrintWriterPrinter; @@ -131,6 +133,8 @@ import android.view.DisplayInfo; import android.view.IWindowManager; import android.view.InputChannel; import android.view.View; +import android.view.WindowManager; +import android.view.WindowManager.DisplayImePolicy; import android.view.WindowManager.LayoutParams; import android.view.WindowManager.LayoutParams.SoftInputModeFlags; import android.view.autofill.AutofillId; @@ -152,6 +156,7 @@ import android.view.inputmethod.InputMethodManager; import android.view.inputmethod.InputMethodSubtype; import com.android.internal.annotations.GuardedBy; +import com.android.internal.compat.IPlatformCompat; import com.android.internal.content.PackageMonitor; import com.android.internal.inputmethod.IInputContentUriToken; import com.android.internal.inputmethod.IInputMethodPrivilegedOperations; @@ -531,6 +536,13 @@ public class InputMethodManagerService extends IInputMethodManager.Stub int mCurSeq; /** + * {@code true} if the Ime policy has been set to {@link WindowManager#DISPLAY_IME_POLICY_HIDE}. + * + * This prevents the IME from showing when it otherwise may have shown. + */ + boolean mImeHiddenByDisplayPolicy; + + /** * The client that is currently bound to an input method. */ ClientState mCurClient; @@ -709,6 +721,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub */ boolean mIsInteractive = true; + private IPlatformCompat mPlatformCompat; + int mBackDisposition = InputMethodService.BACK_DISPOSITION_DEFAULT; /** @@ -1658,7 +1672,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class); mInputManagerInternal = LocalServices.getService(InputManagerInternal.class); mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class); - mImeDisplayValidator = displayId -> mWindowManagerInternal.shouldShowIme(displayId); + mImeDisplayValidator = displayId -> mWindowManagerInternal.getDisplayImePolicy(displayId); mCaller = new HandlerCaller(context, null, new HandlerCaller.Callback() { @Override public void executeMessage(Message msg) { @@ -1670,6 +1684,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub mUserManagerInternal = LocalServices.getService(UserManagerInternal.class); mHasFeature = context.getPackageManager().hasSystemFeature( PackageManager.FEATURE_INPUT_METHODS); + mPlatformCompat = IPlatformCompat.Stub.asInterface( + ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE)); mSlotIme = mContext.getString(com.android.internal.R.string.status_bar_ime); mIsLowRam = ActivityManager.isLowRamDeviceStatic(); @@ -2306,8 +2322,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } } - executeOrSendMessage(mCurClient.client, mCaller.obtainMessageIIO( - MSG_SET_ACTIVE, 0, 0, mCurClient)); + scheduleSetActiveToClient(mCurClient, false /* active */, false /* fullscreen */, + false /* reportToImeController */); executeOrSendMessage(mCurClient.client, mCaller.obtainMessageIIO( MSG_UNBIND_CLIENT, mCurSeq, unbindClientReason, mCurClient.client)); mCurClient.sessionRequested = false; @@ -2438,6 +2454,12 @@ public class InputMethodManagerService extends IInputMethodManager.Stub final int displayIdToShowIme = computeImeDisplayIdForTarget(cs.selfReportedDisplayId, mImeDisplayValidator); + if (displayIdToShowIme == INVALID_DISPLAY) { + mImeHiddenByDisplayPolicy = true; + return InputBindResult.NO_IME; + } + mImeHiddenByDisplayPolicy = false; + if (mCurClient != cs) { // Was the keyguard locked when switching over to the new client? mCurClientInKeyguard = isKeyguardLocked(); @@ -2449,7 +2471,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub // If the screen is on, inform the new client it is active if (mIsInteractive) { - executeOrSendMessage(cs.client, mCaller.obtainMessageIO(MSG_SET_ACTIVE, 1, cs)); + scheduleSetActiveToClient(cs, true /* active */, false /* fullscreen */, + false /* reportToImeController */); } } @@ -2549,7 +2572,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub @FunctionalInterface interface ImeDisplayValidator { - boolean displayCanShowIme(int displayId); + @DisplayImePolicy int getDisplayImePolicy(int displayId); } /** @@ -2558,7 +2581,9 @@ public class InputMethodManagerService extends IInputMethodManager.Stub * @param displayId the ID of the display where the IME client target is. * @param checker instance of {@link ImeDisplayValidator} which is used for * checking display config to adjust the final target display. - * @return The ID of the display where the IME should be shown. + * @return The ID of the display where the IME should be shown or + * {@link android.view.Display#INVALID_DISPLAY} if the display has an ImePolicy of + * {@link WindowManager#DISPLAY_IME_POLICY_HIDE}. */ static int computeImeDisplayIdForTarget(int displayId, @NonNull ImeDisplayValidator checker) { if (displayId == DEFAULT_DISPLAY || displayId == INVALID_DISPLAY) { @@ -2567,7 +2592,14 @@ public class InputMethodManagerService extends IInputMethodManager.Stub // Show IME window on fallback display when the display doesn't support system decorations // or the display is virtual and isn't owned by system for security concern. - return checker.displayCanShowIme(displayId) ? displayId : FALLBACK_DISPLAY_ID; + final int result = checker.getDisplayImePolicy(displayId); + if (result == DISPLAY_IME_POLICY_LOCAL) { + return displayId; + } else if (result == DISPLAY_IME_POLICY_HIDE) { + return INVALID_DISPLAY; + } else { + return FALLBACK_DISPLAY_ID; + } } @AnyThread @@ -4077,6 +4109,44 @@ public class InputMethodManagerService extends IInputMethodManager.Stub return ImeTracing.getInstance().isEnabled(); } + @BinderThread + @Override + public void startImeTrace() { + ImeTracing.getInstance().startTrace(null /* printwriter */); + ArrayMap<IBinder, ClientState> clients; + synchronized (mMethodMap) { + clients = new ArrayMap<>(mClients); + } + for (ClientState state : clients.values()) { + if (state != null) { + try { + state.client.setImeTraceEnabled(true /* enabled */); + } catch (RemoteException e) { + Slog.e(TAG, "Error while trying to enable ime trace on client window", e); + } + } + } + } + + @BinderThread + @Override + public void stopImeTrace() { + ImeTracing.getInstance().stopTrace(null /* printwriter */); + ArrayMap<IBinder, ClientState> clients; + synchronized (mMethodMap) { + clients = new ArrayMap<>(mClients); + } + for (ClientState state : clients.values()) { + if (state != null) { + try { + state.client.setImeTraceEnabled(false /* enabled */); + } catch (RemoteException e) { + Slog.e(TAG, "Error while trying to disable ime trace on client window", e); + } + } + } + } + @GuardedBy("mMethodMap") private void dumpDebug(ProtoOutputStream proto, long fieldId) { synchronized (mMethodMap) { @@ -4452,15 +4522,20 @@ public class InputMethodManagerService extends IInputMethodManager.Stub args.recycle(); return true; } - case MSG_SET_ACTIVE: + case MSG_SET_ACTIVE: { + args = (SomeArgs) msg.obj; + final ClientState clientState = (ClientState) args.arg1; try { - ((ClientState)msg.obj).client.setActive(msg.arg1 != 0, msg.arg2 != 0); + clientState.client.setActive(args.argi1 != 0 /* active */, + args.argi2 != 0 /* fullScreen */, + args.argi3 != 0 /* reportToImeController */); } catch (RemoteException e) { Slog.w(TAG, "Got RemoteException sending setActive(false) notification to pid " - + ((ClientState)msg.obj).pid + " uid " - + ((ClientState)msg.obj).uid); + + clientState.pid + " uid " + clientState.uid); } + args.recycle(); return true; + } case MSG_SET_INTERACTIVE: handleSetInteractive(msg.arg1 != 0); return true; @@ -4546,13 +4621,24 @@ public class InputMethodManagerService extends IInputMethodManager.Stub // Inform the current client of the change in active status if (mCurClient != null && mCurClient.client != null) { - executeOrSendMessage(mCurClient.client, mCaller.obtainMessageIIO( - MSG_SET_ACTIVE, mIsInteractive ? 1 : 0, mInFullscreenMode ? 1 : 0, - mCurClient)); + boolean reportToImeController = false; + try { + reportToImeController = mPlatformCompat.isChangeEnabledByUid( + FINISH_INPUT_NO_FALLBACK_CONNECTION, mCurMethodUid); + } catch (RemoteException e) { + } + scheduleSetActiveToClient(mCurClient, mIsInteractive, mInFullscreenMode, + reportToImeController); } } } + private void scheduleSetActiveToClient(ClientState state, boolean active, boolean fullscreen, + boolean reportToImeController) { + executeOrSendMessage(state.client, mCaller.obtainMessageIIIIO(MSG_SET_ACTIVE, + active ? 1 : 0, fullscreen ? 1 : 0, reportToImeController ? 1 : 0, 0, state)); + } + private boolean chooseNewDefaultIMELocked() { final InputMethodInfo imi = InputMethodUtils.getMostApplicableDefaultIME( mSettings.getEnabledInputMethodListLocked()); @@ -5181,6 +5267,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub p.println(" mInFullscreenMode=" + mInFullscreenMode); p.println(" mSystemReady=" + mSystemReady + " mInteractive=" + mIsInteractive); p.println(" mSettingsObserver=" + mSettingsObserver); + p.println(" mImeHiddenByDisplayPolicy=" + mImeHiddenByDisplayPolicy); p.println(" mSwitchingController:"); mSwitchingController.dump(p); p.println(" mSettings:"); @@ -5722,9 +5809,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub try { state.client.setImeTraceEnabled(isImeTraceEnabled); } catch (RemoteException e) { - Log.e(TAG, - "Error while trying to enable/disable ime " - + "trace on client window", e); + Slog.e(TAG, "Error while trying to enable/disable ime trace on client window", + e); } } } diff --git a/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java index 7af27ca46f68..62d817c22ae6 100644 --- a/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java +++ b/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java @@ -911,7 +911,8 @@ public final class MultiClientInputMethodManagerService { com.android.internal.R.string.input_method_binding_label) .putExtra(Intent.EXTRA_CLIENT_INTENT, PendingIntent.getActivity( context, 0, - new Intent(Settings.ACTION_INPUT_METHOD_SETTINGS), 0)); + new Intent(Settings.ACTION_INPUT_METHOD_SETTINGS), + PendingIntent.FLAG_MUTABLE)); // Note: Instead of re-dispatching callback from the main thread to the worker thread // where OnWorkerThreadCallback is running, we pass the Handler object here so that @@ -1338,7 +1339,7 @@ public final class MultiClientInputMethodManagerService { switch (clientInfo.mState) { case InputMethodClientState.WAITING_FOR_IME_SESSION: try { - clientInfo.mClient.setActive(true, false); + clientInfo.mClient.setActive(true, false, false); } catch (RemoteException e) { // TODO(yukawa): Remove this client. return; @@ -1400,7 +1401,7 @@ public final class MultiClientInputMethodManagerService { return; } try { - clientInfo.mClient.setActive(active, false /* fullscreen */); + clientInfo.mClient.setActive(active, false /* fullscreen */, false); } catch (RemoteException e) { return; } @@ -1816,5 +1817,15 @@ public final class MultiClientInputMethodManagerService { public boolean isImeTraceEnabled() { return false; } + + @BinderThread + @Override + public void startImeTrace() { + } + + @BinderThread + @Override + public void stopImeTrace() { + } } } diff --git a/services/core/java/com/android/server/location/timezone/BinderLocationTimeZoneProvider.java b/services/core/java/com/android/server/location/timezone/BinderLocationTimeZoneProvider.java index 280d59af7d2a..b4bcd7b10c42 100644 --- a/services/core/java/com/android/server/location/timezone/BinderLocationTimeZoneProvider.java +++ b/services/core/java/com/android/server/location/timezone/BinderLocationTimeZoneProvider.java @@ -25,10 +25,10 @@ import static com.android.server.location.timezone.LocationTimeZoneProvider.Prov import android.annotation.NonNull; import android.annotation.Nullable; -import android.location.timezone.LocationTimeZoneEvent; import android.util.IndentingPrintWriter; import android.util.Slog; +import com.android.internal.location.timezone.LocationTimeZoneEvent; import com.android.internal.location.timezone.LocationTimeZoneProviderRequest; import java.time.Duration; diff --git a/services/core/java/com/android/server/location/timezone/ControllerImpl.java b/services/core/java/com/android/server/location/timezone/ControllerImpl.java index 70c1aeff0ce8..07615ff58075 100644 --- a/services/core/java/com/android/server/location/timezone/ControllerImpl.java +++ b/services/core/java/com/android/server/location/timezone/ControllerImpl.java @@ -16,10 +16,9 @@ package com.android.server.location.timezone; -import static android.location.timezone.LocationTimeZoneEvent.EVENT_TYPE_PERMANENT_FAILURE; -import static android.location.timezone.LocationTimeZoneEvent.EVENT_TYPE_SUCCESS; -import static android.location.timezone.LocationTimeZoneEvent.EVENT_TYPE_UNCERTAIN; - +import static com.android.internal.location.timezone.LocationTimeZoneEvent.EVENT_TYPE_PERMANENT_FAILURE; +import static com.android.internal.location.timezone.LocationTimeZoneEvent.EVENT_TYPE_SUCCESS; +import static com.android.internal.location.timezone.LocationTimeZoneEvent.EVENT_TYPE_UNCERTAIN; import static com.android.server.location.timezone.LocationTimeZoneManagerService.debugLog; import static com.android.server.location.timezone.LocationTimeZoneManagerService.warnLog; import static com.android.server.location.timezone.LocationTimeZoneProvider.ProviderState; @@ -31,10 +30,10 @@ import static com.android.server.location.timezone.LocationTimeZoneProvider.Prov import android.annotation.NonNull; import android.annotation.Nullable; -import android.location.timezone.LocationTimeZoneEvent; import android.util.IndentingPrintWriter; import com.android.internal.annotations.GuardedBy; +import com.android.internal.location.timezone.LocationTimeZoneEvent; import com.android.server.location.timezone.ThreadingDomain.SingleRunnableQueue; import com.android.server.timezonedetector.ConfigurationInternal; import com.android.server.timezonedetector.GeolocationTimeZoneSuggestion; diff --git a/services/core/java/com/android/server/location/timezone/LocationTimeZoneManagerService.java b/services/core/java/com/android/server/location/timezone/LocationTimeZoneManagerService.java index 83f4ca2839fb..b7c7476844a5 100644 --- a/services/core/java/com/android/server/location/timezone/LocationTimeZoneManagerService.java +++ b/services/core/java/com/android/server/location/timezone/LocationTimeZoneManagerService.java @@ -42,7 +42,7 @@ import java.util.Objects; * A service class that acts as a container for the {@link LocationTimeZoneProviderController}, * which determines what {@link com.android.server.timezonedetector.GeolocationTimeZoneSuggestion} * are made to the {@link TimeZoneDetectorInternal}, and the {@link LocationTimeZoneProvider}s that - * offer {@link android.location.timezone.LocationTimeZoneEvent}s. + * (indirectly) generate {@link com.android.internal.location.timezone.LocationTimeZoneEvent}s. * * <p>For details of the time zone suggestion behavior, see {@link * LocationTimeZoneProviderController}. diff --git a/services/core/java/com/android/server/location/timezone/LocationTimeZoneProvider.java b/services/core/java/com/android/server/location/timezone/LocationTimeZoneProvider.java index 4bbda43d0e60..dc56238e2f48 100644 --- a/services/core/java/com/android/server/location/timezone/LocationTimeZoneProvider.java +++ b/services/core/java/com/android/server/location/timezone/LocationTimeZoneProvider.java @@ -16,10 +16,9 @@ package com.android.server.location.timezone; -import static android.location.timezone.LocationTimeZoneEvent.EVENT_TYPE_PERMANENT_FAILURE; -import static android.location.timezone.LocationTimeZoneEvent.EVENT_TYPE_SUCCESS; -import static android.location.timezone.LocationTimeZoneEvent.EVENT_TYPE_UNCERTAIN; - +import static com.android.internal.location.timezone.LocationTimeZoneEvent.EVENT_TYPE_PERMANENT_FAILURE; +import static com.android.internal.location.timezone.LocationTimeZoneEvent.EVENT_TYPE_SUCCESS; +import static com.android.internal.location.timezone.LocationTimeZoneEvent.EVENT_TYPE_UNCERTAIN; import static com.android.server.location.timezone.LocationTimeZoneManagerService.debugLog; import static com.android.server.location.timezone.LocationTimeZoneProvider.ProviderState.PROVIDER_STATE_DISABLED; import static com.android.server.location.timezone.LocationTimeZoneProvider.ProviderState.PROVIDER_STATE_ENABLED_CERTAIN; @@ -30,12 +29,12 @@ import static com.android.server.location.timezone.LocationTimeZoneProvider.Prov import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; -import android.location.timezone.LocationTimeZoneEvent; import android.os.Handler; import android.os.SystemClock; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.location.timezone.LocationTimeZoneEvent; import com.android.server.location.timezone.LocationTimeZoneProvider.ProviderState.ProviderStateEnum; import com.android.server.location.timezone.ThreadingDomain.SingleRunnableQueue; import com.android.server.timezonedetector.ConfigurationInternal; diff --git a/services/core/java/com/android/server/location/timezone/LocationTimeZoneProviderProxy.java b/services/core/java/com/android/server/location/timezone/LocationTimeZoneProviderProxy.java index 3d889ae1856a..1b4706f8801e 100644 --- a/services/core/java/com/android/server/location/timezone/LocationTimeZoneProviderProxy.java +++ b/services/core/java/com/android/server/location/timezone/LocationTimeZoneProviderProxy.java @@ -19,11 +19,11 @@ package com.android.server.location.timezone; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; -import android.location.timezone.LocationTimeZoneEvent; import android.os.Handler; import android.util.IndentingPrintWriter; import com.android.internal.annotations.GuardedBy; +import com.android.internal.location.timezone.LocationTimeZoneEvent; import com.android.internal.location.timezone.LocationTimeZoneProviderRequest; import com.android.server.timezonedetector.Dumpable; diff --git a/services/core/java/com/android/server/location/timezone/NullLocationTimeZoneProvider.java b/services/core/java/com/android/server/location/timezone/NullLocationTimeZoneProvider.java index 2bbae56e40c8..fbcc71fad20a 100644 --- a/services/core/java/com/android/server/location/timezone/NullLocationTimeZoneProvider.java +++ b/services/core/java/com/android/server/location/timezone/NullLocationTimeZoneProvider.java @@ -38,8 +38,8 @@ import java.time.Duration; * enters a {@link ProviderState#PROVIDER_STATE_PERM_FAILED} state immediately after being enabled * for the first time and sends the appropriate event, which ensures the {@link * LocationTimeZoneProviderController} won't expect any further {@link - * android.location.timezone.LocationTimeZoneEvent}s to come from it, and won't attempt to use it - * again. + * com.android.internal.location.timezone.LocationTimeZoneEvent}s to come from it, and won't attempt + * to use it again. */ class NullLocationTimeZoneProvider extends LocationTimeZoneProvider { diff --git a/services/core/java/com/android/server/location/timezone/RealLocationTimeZoneProviderProxy.java b/services/core/java/com/android/server/location/timezone/RealLocationTimeZoneProviderProxy.java index 94062faa7a1b..cd6d3592af0e 100644 --- a/services/core/java/com/android/server/location/timezone/RealLocationTimeZoneProviderProxy.java +++ b/services/core/java/com/android/server/location/timezone/RealLocationTimeZoneProviderProxy.java @@ -20,7 +20,6 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.content.ComponentName; import android.content.Context; -import android.location.timezone.LocationTimeZoneEvent; import android.os.IBinder; import android.os.RemoteException; import android.util.IndentingPrintWriter; @@ -28,6 +27,7 @@ import android.util.IndentingPrintWriter; import com.android.internal.annotations.GuardedBy; import com.android.internal.location.timezone.ILocationTimeZoneProvider; import com.android.internal.location.timezone.ILocationTimeZoneProviderManager; +import com.android.internal.location.timezone.LocationTimeZoneEvent; import com.android.internal.location.timezone.LocationTimeZoneProviderRequest; import com.android.server.ServiceWatcher; diff --git a/services/core/java/com/android/server/location/timezone/SimulatedBinderProviderEvent.java b/services/core/java/com/android/server/location/timezone/SimulatedBinderProviderEvent.java index 6bf6539f95dc..77253099d54f 100644 --- a/services/core/java/com/android/server/location/timezone/SimulatedBinderProviderEvent.java +++ b/services/core/java/com/android/server/location/timezone/SimulatedBinderProviderEvent.java @@ -16,19 +16,19 @@ package com.android.server.location.timezone; -import static android.location.timezone.LocationTimeZoneEvent.EVENT_TYPE_PERMANENT_FAILURE; -import static android.location.timezone.LocationTimeZoneEvent.EVENT_TYPE_SUCCESS; -import static android.location.timezone.LocationTimeZoneEvent.EVENT_TYPE_UNCERTAIN; - +import static com.android.internal.location.timezone.LocationTimeZoneEvent.EVENT_TYPE_PERMANENT_FAILURE; +import static com.android.internal.location.timezone.LocationTimeZoneEvent.EVENT_TYPE_SUCCESS; +import static com.android.internal.location.timezone.LocationTimeZoneEvent.EVENT_TYPE_UNCERTAIN; import static com.android.server.location.timezone.LocationTimeZoneManagerService.PRIMARY_PROVIDER_NAME; import static com.android.server.location.timezone.LocationTimeZoneManagerService.SECONDARY_PROVIDER_NAME; import android.annotation.NonNull; import android.annotation.Nullable; -import android.location.timezone.LocationTimeZoneEvent; import android.os.ShellCommand; import android.os.SystemClock; +import com.android.internal.location.timezone.LocationTimeZoneEvent; + import java.io.PrintWriter; import java.util.ArrayList; import java.util.Arrays; @@ -117,7 +117,7 @@ final class SimulatedBinderProviderEvent { private static LocationTimeZoneEvent parseLocationTimeZoneEventArgs(ShellCommand shellCommand) { LocationTimeZoneEvent.Builder eventBuilder = new LocationTimeZoneEvent.Builder() - .setElapsedRealtimeNanos(SystemClock.elapsedRealtime()); + .setElapsedRealtimeMillis(SystemClock.elapsedRealtime()); String eventTypeString = shellCommand.getNextArgRequired(); switch (eventTypeString.toUpperCase()) { diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java index 5c2c8e25f6c9..c10d394d6344 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerSession.java +++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java @@ -2544,6 +2544,10 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, "Full install must include a base package"); } + if (baseApk.isSplitRequired && stagedSplits.size() <= 1) { + throw new PackageManagerException(INSTALL_FAILED_MISSING_SPLIT, + "Missing split for " + mPackageName); + } } else { final ApplicationInfo appInfo = pkgInfo.applicationInfo; ParseResult<PackageLite> pkgLiteResult = ApkLiteParseUtils.parsePackageLite( @@ -2654,6 +2658,17 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { mResolvedInheritedFiles.addAll(libFilesToInherit); } } + // For the case of split required, failed if no splits existed + if (baseApk.isSplitRequired) { + final int existingSplits = ArrayUtils.size(existing.splitNames); + final boolean allSplitsRemoved = (existingSplits == removeSplitList.size()); + final boolean onlyBaseFileStaged = (stagedSplits.size() == 1 + && stagedSplits.contains(null)); + if (allSplitsRemoved && (stagedSplits.isEmpty() || onlyBaseFileStaged)) { + throw new PackageManagerException(INSTALL_FAILED_MISSING_SPLIT, + "Missing split for " + mPackageName); + } + } } if (baseApk.useEmbeddedDex) { for (File file : mResolvedStagedFiles) { @@ -2665,10 +2680,6 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } } } - if (baseApk.isSplitRequired && stagedSplits.size() <= 1) { - throw new PackageManagerException(INSTALL_FAILED_MISSING_SPLIT, - "Missing split for " + mPackageName); - } final boolean isInstallerShell = (mInstallerUid == Process.SHELL_UID); if (isInstallerShell && isIncrementalInstallation() && mIncrementalFileStorages != null) { diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 38807112576a..55f9feec10d3 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -141,6 +141,7 @@ import android.annotation.AppIdInt; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.StringRes; import android.annotation.UserIdInt; import android.annotation.WorkerThread; import android.app.ActivityManager; @@ -1203,6 +1204,7 @@ public class PackageManagerService extends IPackageManager.Stub public ViewCompiler viewCompiler; public @Nullable String wellbeingPackage; public @Nullable String retailDemoPackage; + public @Nullable String recentsPackage; public ComponentName resolveComponentName; public ArrayMap<String, AndroidPackage> packages; public boolean enableFreeCacheV2; @@ -1737,6 +1739,7 @@ public class PackageManagerService extends IPackageManager.Stub final @Nullable String mSharedSystemSharedLibraryPackageName; final @Nullable String mRetailDemoPackage; final @Nullable String mOverlayConfigSignaturePackage; + final @Nullable String mRecentsPackage; private final PackageUsage mPackageUsage = new PackageUsage(); private final CompilerStats mCompilerStats = new CompilerStats(); @@ -2980,6 +2983,7 @@ public class PackageManagerService extends IPackageManager.Stub mSystemTextClassifierPackageName = testParams.systemTextClassifierPackage; mWellbeingPackage = testParams.wellbeingPackage; mRetailDemoPackage = testParams.retailDemoPackage; + mRecentsPackage = testParams.recentsPackage; mDocumenterPackage = testParams.documenterPackage; mConfiguratorPackage = testParams.configuratorPackage; mAppPredictionServicePackage = testParams.appPredictionServicePackage; @@ -3564,6 +3568,7 @@ public class PackageManagerService extends IPackageManager.Stub mIncidentReportApproverPackage = getIncidentReportApproverPackageName(); mRetailDemoPackage = getRetailDemoPackageName(); mOverlayConfigSignaturePackage = getOverlayConfigSignaturePackageName(); + mRecentsPackage = getRecentsPackageName(); // Now that we know all of the shared libraries, update all clients to have // the correct library paths. @@ -21329,15 +21334,8 @@ public class PackageManagerService extends IPackageManager.Stub @Override public @Nullable String getAttentionServicePackageName() { - final String flattenedComponentName = - mContext.getString(R.string.config_defaultAttentionService); - if (flattenedComponentName != null) { - ComponentName componentName = ComponentName.unflattenFromString(flattenedComponentName); - if (componentName != null && componentName.getPackageName() != null) { - return ensureSystemPackageName(componentName.getPackageName()); - } - } - return null; + return ensureSystemPackageName( + getPackageFromComponentString(R.string.config_defaultAttentionService)); } private @Nullable String getDocumenterPackageName() { @@ -21372,17 +21370,8 @@ public class PackageManagerService extends IPackageManager.Stub @Override public String getAppPredictionServicePackageName() { - String flattenedAppPredictionServiceComponentName = - mContext.getString(R.string.config_defaultAppPredictionService); - if (flattenedAppPredictionServiceComponentName == null) { - return null; - } - ComponentName appPredictionServiceComponentName = - ComponentName.unflattenFromString(flattenedAppPredictionServiceComponentName); - if (appPredictionServiceComponentName == null) { - return null; - } - return ensureSystemPackageName(appPredictionServiceComponentName.getPackageName()); + return ensureSystemPackageName( + getPackageFromComponentString(R.string.config_defaultAppPredictionService)); } private @NonNull String[] dropNonSystemPackages(@NonNull String[] pkgNames) { @@ -21399,19 +21388,8 @@ public class PackageManagerService extends IPackageManager.Stub @Override public String getSystemCaptionsServicePackageName() { - String flattenedSystemCaptionsServiceComponentName = - mContext.getString(R.string.config_defaultSystemCaptionsService); - - if (TextUtils.isEmpty(flattenedSystemCaptionsServiceComponentName)) { - return null; - } - - ComponentName systemCaptionsServiceComponentName = - ComponentName.unflattenFromString(flattenedSystemCaptionsServiceComponentName); - if (systemCaptionsServiceComponentName == null) { - return null; - } - return ensureSystemPackageName(systemCaptionsServiceComponentName.getPackageName()); + return ensureSystemPackageName( + getPackageFromComponentString(R.string.config_defaultSystemCaptionsService)); } @Override @@ -21429,19 +21407,8 @@ public class PackageManagerService extends IPackageManager.Stub @Override public String getContentCaptureServicePackageName() { - final String flattenedContentCaptureService = - mContext.getString(R.string.config_defaultContentCaptureService); - - if (TextUtils.isEmpty(flattenedContentCaptureService)) { - return null; - } - - final ComponentName contentCaptureServiceComponentName = - ComponentName.unflattenFromString(flattenedContentCaptureService); - if (contentCaptureServiceComponentName == null) { - return null; - } - return ensureSystemPackageName(contentCaptureServiceComponentName.getPackageName()); + return ensureSystemPackageName( + getPackageFromComponentString(R.string.config_defaultContentCaptureService)); } public String getOverlayConfigSignaturePackageName() { @@ -21485,6 +21452,26 @@ public class PackageManagerService extends IPackageManager.Stub } @Nullable + private String getRecentsPackageName() { + return ensureSystemPackageName( + getPackageFromComponentString(R.string.config_recentsComponentName)); + + } + + @Nullable + private String getPackageFromComponentString(@StringRes int stringResId) { + final String componentString = mContext.getString(stringResId); + if (TextUtils.isEmpty(componentString)) { + return null; + } + final ComponentName component = ComponentName.unflattenFromString(componentString); + if (component == null) { + return null; + } + return component.getPackageName(); + } + + @Nullable private String ensureSystemPackageName(@Nullable String packageName) { if (packageName == null) { return null; @@ -25092,6 +25079,8 @@ public class PackageManagerService extends IPackageManager.Stub : new String[] {mRetailDemoPackage}; case PackageManagerInternal.PACKAGE_OVERLAY_CONFIG_SIGNATURE: return filterOnlySystemPackages(getOverlayConfigSignaturePackageName()); + case PackageManagerInternal.PACKAGE_RECENTS: + return filterOnlySystemPackages(mRecentsPackage); default: return ArrayUtils.emptyArray(String.class); } diff --git a/services/core/java/com/android/server/pm/permission/Permission.java b/services/core/java/com/android/server/pm/permission/Permission.java index 687e96c3c9dd..995b59e97e91 100644 --- a/services/core/java/com/android/server/pm/permission/Permission.java +++ b/services/core/java/com/android/server/pm/permission/Permission.java @@ -331,6 +331,10 @@ public final class Permission { return (mPermissionInfo.protectionLevel & PermissionInfo.PROTECTION_FLAG_RETAIL_DEMO) != 0; } + public boolean isRecents() { + return (mPermissionInfo.protectionLevel & PermissionInfo.PROTECTION_FLAG_RECENTS) != 0; + } + public void transfer(@NonNull String oldPackageName, @NonNull String newPackageName) { if (!oldPackageName.equals(mPermissionInfo.packageName)) { return; diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java index 1b35d29f0d6b..fb1ed2f6b58b 100644 --- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java +++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java @@ -3616,6 +3616,13 @@ public class PermissionManagerService extends IPermissionManager.Stub { // Special permission granted only to the OEM specified retail demo app allowed = true; } + if (!allowed && bp.isRecents() + && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames( + PackageManagerInternal.PACKAGE_RECENTS, UserHandle.USER_SYSTEM), + pkg.getPackageName())) { + // Special permission for the recents app. + allowed = true; + } return allowed; } diff --git a/services/core/java/com/android/server/policy/SoftRestrictedPermissionPolicy.java b/services/core/java/com/android/server/policy/SoftRestrictedPermissionPolicy.java index cc369356c1c9..9026262db897 100644 --- a/services/core/java/com/android/server/policy/SoftRestrictedPermissionPolicy.java +++ b/services/core/java/com/android/server/policy/SoftRestrictedPermissionPolicy.java @@ -127,9 +127,11 @@ public abstract class SoftRestrictedPermissionPolicy { final boolean isWhiteListed; boolean shouldApplyRestriction; final int targetSDK; + final boolean hasLegacyExternalStorage; final boolean hasRequestedLegacyExternalStorage; - final boolean shouldPreserveLegacyExternalStorage; + final boolean hasRequestedPreserveLegacyExternalStorage; final boolean hasWriteMediaStorageGrantedForUid; + final boolean isForcedScopedStorage; if (appInfo != null) { PackageManager pm = context.getPackageManager(); @@ -137,27 +139,27 @@ public abstract class SoftRestrictedPermissionPolicy { LocalServices.getService(StorageManagerInternal.class); int flags = pm.getPermissionFlags(permission, appInfo.packageName, user); isWhiteListed = (flags & FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT) != 0; + hasLegacyExternalStorage = smInternal.hasLegacyExternalStorage(appInfo.uid); hasRequestedLegacyExternalStorage = hasUidRequestedLegacyExternalStorage( appInfo.uid, context); hasWriteMediaStorageGrantedForUid = hasWriteMediaStorageGrantedForUid( appInfo.uid, context); - shouldPreserveLegacyExternalStorage = pkg.hasPreserveLegacyExternalStorage() - && smInternal.hasLegacyExternalStorage(appInfo.uid); + hasRequestedPreserveLegacyExternalStorage = + pkg.hasPreserveLegacyExternalStorage(); targetSDK = getMinimumTargetSDK(context, appInfo, user); - shouldApplyRestriction = (flags & FLAG_PERMISSION_APPLY_RESTRICTION) != 0 - || (targetSDK > Build.VERSION_CODES.Q - && !shouldPreserveLegacyExternalStorage) - // If the device is configured to force this app into scoped storage, - // then we should apply the restriction - || sForcedScopedStorageAppWhitelist.contains(appInfo.packageName); + shouldApplyRestriction = (flags & FLAG_PERMISSION_APPLY_RESTRICTION) != 0; + isForcedScopedStorage = sForcedScopedStorageAppWhitelist + .contains(appInfo.packageName); } else { isWhiteListed = false; shouldApplyRestriction = false; targetSDK = 0; + hasLegacyExternalStorage = false; hasRequestedLegacyExternalStorage = false; - shouldPreserveLegacyExternalStorage = false; + hasRequestedPreserveLegacyExternalStorage = false; hasWriteMediaStorageGrantedForUid = false; + isForcedScopedStorage = false; } // We have a check in PermissionPolicyService.PermissionToOpSynchroniser.setUidMode @@ -175,14 +177,53 @@ public abstract class SoftRestrictedPermissionPolicy { } @Override public boolean mayAllowExtraAppOp() { - return !shouldApplyRestriction - && (hasRequestedLegacyExternalStorage - || hasWriteMediaStorageGrantedForUid - || shouldPreserveLegacyExternalStorage); + // The only way to get LEGACY_STORAGE (if you didn't already have it) + // is that all of the following must be true: + // 1. The flag shouldn't be restricted + if (shouldApplyRestriction) { + return false; + } + + // 2. The app shouldn't be in sForcedScopedStorageAppWhitelist + if (isForcedScopedStorage) { + return false; + } + + // 3. The app has WRITE_MEDIA_STORAGE, OR + // the app already has legacy external storage or requested it, + // and is < R. + return hasWriteMediaStorageGrantedForUid + || ((hasLegacyExternalStorage || hasRequestedLegacyExternalStorage) + && targetSDK < Build.VERSION_CODES.R); } @Override public boolean mayDenyExtraAppOpIfGranted() { - return shouldApplyRestriction; + // If you're an app targeting < R, you can keep the app op for + // as long as you meet the conditions required to acquire it. + if (targetSDK < Build.VERSION_CODES.R) { + return !mayAllowExtraAppOp(); + } + + // For an app targeting R, the only way to lose LEGACY_STORAGE if you + // already had it is in one or more of the following conditions: + // 1. The flag became restricted + if (shouldApplyRestriction) { + return true; + } + + // The package is now a part of the forced scoped storage whitelist + if (isForcedScopedStorage) { + return true; + } + + // The package doesn't have WRITE_MEDIA_STORAGE, + // AND didn't request legacy storage to be preserved + if (!hasWriteMediaStorageGrantedForUid + && !hasRequestedPreserveLegacyExternalStorage) { + return true; + } + + return false; } }; } diff --git a/services/core/java/com/android/server/powerstats/PowerStatsHALWrapper.java b/services/core/java/com/android/server/powerstats/PowerStatsHALWrapper.java index 18646b9cc06c..88e5f69e02c4 100644 --- a/services/core/java/com/android/server/powerstats/PowerStatsHALWrapper.java +++ b/services/core/java/com/android/server/powerstats/PowerStatsHALWrapper.java @@ -38,11 +38,41 @@ public final class PowerStatsHALWrapper { */ public interface IPowerStatsHALWrapper { /** + * Returns information related to all supported PowerEntity(s) for which state residency + * data is available. + * + * A PowerEntity is defined as a platform subsystem, peripheral, or power domain that + * impacts the total device power consumption. + * + * @return List of information on each PowerEntity. + */ + android.hardware.power.stats.PowerEntityInfo[] getPowerEntityInfo(); + + /** + * Reports the accumulated state residency for each requested PowerEntity. + * + * Each PowerEntity may reside in one of multiple states. It may also transition from one + * state to another. StateResidency is defined as an accumulation of time that a + * PowerEntity resided in each of its possible states, the number of times that each state + * was entered, and a timestamp corresponding to the last time that state was entered. + * + * Data is accumulated starting at device boot. + * + * @param powerEntityIds List of IDs of PowerEntities for which data is requested. Passing + * an empty list will return state residency for all available + * PowerEntities. ID of each PowerEntity is contained in + * PowerEntityInfo. + * + * @return StateResidency since boot for each requested PowerEntity + */ + android.hardware.power.stats.StateResidencyResult[] getStateResidency(int[] powerEntityIds); + + /** * Returns the energy consumer IDs for all available energy consumers (power models) on the - * device. Examples of subsystems for which energy consumer results (power models) - * may be available are GPS, display, wifi, etc. The default list of energy - * consumers can be found in the PowerStats HAL definition (EnergyConsumerId.aidl). - * The availability of energy consumer IDs is hardware dependent. + * device. Examples of subsystems for which energy consumer results (power models) may be + * available are GPS, display, wifi, etc. The default list of energy consumers can be + * found in the PowerStats HAL definition (EnergyConsumerId.aidl). The availability of + * energy consumer IDs is hardware dependent. * * @return List of EnergyConsumerIds all available energy consumers. */ @@ -50,14 +80,19 @@ public final class PowerStatsHALWrapper { /** * Returns the energy consumer result for all available energy consumers (power models). - * Available consumers can be retrieved by calling getEnergyConsumerInfo(). The - * subsystem corresponding to the energy consumer result is defined by the energy - * consumer ID. + * Available consumers can be retrieved by calling getEnergyConsumerInfo(). The subsystem + * corresponding to the energy consumer result is defined by the energy consumer ID. + * + * @param energyConsumerIds Array of energy consumer IDs for which energy consumed is being + * requested. Energy consumers available on the device can be + * queried by calling getEnergyConsumerInfo(). Passing an empty + * array will return results for all energy consumers. * * @return List of EnergyConsumerResult objects containing energy consumer results for all * available energy consumers (power models). */ - android.hardware.power.stats.EnergyConsumerResult[] getEnergyConsumed(); + android.hardware.power.stats.EnergyConsumerResult[] getEnergyConsumed( + int[] energyConsumerIds); /** * Returns channel info for all available energy meters. @@ -69,17 +104,21 @@ public final class PowerStatsHALWrapper { /** * Returns energy measurements for all available energy meters. Available channels can be - * retrieved by calling getEnergyMeterInfo(). Energy measurements and channel info - * can be linked through the channelId field. + * retrieved by calling getEnergyMeterInfo(). Energy measurements and channel info can be + * linked through the channelId field. + * + * @param channelIds Array of channel IDs for which energy measurements are being requested. + * Channel IDs available on the device can be queried by calling + * getEnergyMeterInfo(). Passing an empty array will return energy + * measurements for all channels. * * @return List of EnergyMeasurement objects containing energy measurements for all * available energy meters. */ - android.hardware.power.stats.EnergyMeasurement[] readEnergyMeters(); + android.hardware.power.stats.EnergyMeasurement[] readEnergyMeters(int[] channelIds); /** - * Returns boolean indicating if connection to power stats HAL was - * established. + * Returns boolean indicating if connection to power stats HAL was established. * * @return true if connection to power stats HAL was correctly established. */ @@ -95,6 +134,38 @@ public final class PowerStatsHALWrapper { private static Supplier<IPowerStats> sVintfPowerStats; @Override + public android.hardware.power.stats.PowerEntityInfo[] getPowerEntityInfo() { + android.hardware.power.stats.PowerEntityInfo[] powerEntityInfoHAL = null; + + if (sVintfPowerStats != null) { + try { + powerEntityInfoHAL = sVintfPowerStats.get().getPowerEntityInfo(); + } catch (RemoteException e) { + Slog.e(TAG, "Failed to get power entity info from PowerStats HAL"); + } + } + + return powerEntityInfoHAL; + } + + @Override + public android.hardware.power.stats.StateResidencyResult[] getStateResidency( + int[] powerEntityIds) { + android.hardware.power.stats.StateResidencyResult[] stateResidencyResultHAL = null; + + if (sVintfPowerStats != null) { + try { + stateResidencyResultHAL = + sVintfPowerStats.get().getStateResidency(powerEntityIds); + } catch (RemoteException e) { + Slog.e(TAG, "Failed to get state residency from PowerStats HAL"); + } + } + + return stateResidencyResultHAL; + } + + @Override public int[] getEnergyConsumerInfo() { int[] energyConsumerInfoHAL = null; @@ -110,13 +181,14 @@ public final class PowerStatsHALWrapper { } @Override - public android.hardware.power.stats.EnergyConsumerResult[] getEnergyConsumed() { + public android.hardware.power.stats.EnergyConsumerResult[] getEnergyConsumed( + int[] energyConsumerIds) { android.hardware.power.stats.EnergyConsumerResult[] energyConsumedHAL = null; if (sVintfPowerStats != null) { try { energyConsumedHAL = - sVintfPowerStats.get().getEnergyConsumed(new int[0]); + sVintfPowerStats.get().getEnergyConsumed(energyConsumerIds); } catch (RemoteException e) { Slog.e(TAG, "Failed to get energy consumer results from PowerStats HAL"); } @@ -141,13 +213,13 @@ public final class PowerStatsHALWrapper { } @Override - public android.hardware.power.stats.EnergyMeasurement[] readEnergyMeters() { + public android.hardware.power.stats.EnergyMeasurement[] readEnergyMeters(int[] channelIds) { android.hardware.power.stats.EnergyMeasurement[] energyMeasurementHAL = null; if (sVintfPowerStats != null) { try { energyMeasurementHAL = - sVintfPowerStats.get().readEnergyMeters(new int[0]); + sVintfPowerStats.get().readEnergyMeters(channelIds); } catch (RemoteException e) { Slog.e(TAG, "Failed to get energy measurements from PowerStats HAL"); } diff --git a/services/core/java/com/android/server/powerstats/PowerStatsLogger.java b/services/core/java/com/android/server/powerstats/PowerStatsLogger.java index f5131c4b371d..409cd826b6bc 100644 --- a/services/core/java/com/android/server/powerstats/PowerStatsLogger.java +++ b/services/core/java/com/android/server/powerstats/PowerStatsLogger.java @@ -61,14 +61,15 @@ public final class PowerStatsLogger extends Handler { if (DEBUG) Slog.d(TAG, "Logging to data storage"); // Log power meter data. - EnergyMeasurement[] energyMeasurements = mPowerStatsHALWrapper.readEnergyMeters(); + EnergyMeasurement[] energyMeasurements = + mPowerStatsHALWrapper.readEnergyMeters(new int[0]); mPowerStatsMeterStorage.write( EnergyMeasurementUtils.getProtoBytes(energyMeasurements)); if (DEBUG) EnergyMeasurementUtils.print(energyMeasurements); // Log power model data. EnergyConsumerResult[] energyConsumerResults = - mPowerStatsHALWrapper.getEnergyConsumed(); + mPowerStatsHALWrapper.getEnergyConsumed(new int[0]); mPowerStatsModelStorage.write( EnergyConsumerResultUtils.getProtoBytes(energyConsumerResults)); if (DEBUG) EnergyConsumerResultUtils.print(energyConsumerResults); diff --git a/services/core/java/com/android/server/powerstats/PowerStatsService.java b/services/core/java/com/android/server/powerstats/PowerStatsService.java index bf3919e7344f..1150d4bbe770 100644 --- a/services/core/java/com/android/server/powerstats/PowerStatsService.java +++ b/services/core/java/com/android/server/powerstats/PowerStatsService.java @@ -19,6 +19,7 @@ package com.android.server.powerstats; import android.annotation.Nullable; import android.content.Context; import android.hardware.power.stats.ChannelInfo; +import android.hardware.power.stats.PowerEntityInfo; import android.os.Binder; import android.os.Environment; import android.os.UserHandle; @@ -31,6 +32,7 @@ import com.android.server.powerstats.PowerStatsHALWrapper.IPowerStatsHALWrapper; import com.android.server.powerstats.PowerStatsHALWrapper.PowerStatsHALWrapperImpl; import com.android.server.powerstats.ProtoStreamUtils.ChannelInfoUtils; import com.android.server.powerstats.ProtoStreamUtils.EnergyConsumerIdUtils; +import com.android.server.powerstats.ProtoStreamUtils.PowerEntityInfoUtils; import java.io.File; import java.io.FileDescriptor; @@ -110,6 +112,10 @@ public class PowerStatsService extends SystemService { mPowerStatsLogger.writeMeterDataToFile(fd); } } else if (args.length == 0) { + pw.println("PowerStatsService dumpsys: available PowerEntityInfos"); + PowerEntityInfo[] powerEntityInfo = mPowerStatsHALWrapper.getPowerEntityInfo(); + PowerEntityInfoUtils.dumpsys(powerEntityInfo, pw); + pw.println("PowerStatsService dumpsys: available ChannelInfos"); ChannelInfo[] channelInfo = mPowerStatsHALWrapper.getEnergyMeterInfo(); ChannelInfoUtils.dumpsys(channelInfo, pw); diff --git a/services/core/java/com/android/server/powerstats/ProtoStreamUtils.java b/services/core/java/com/android/server/powerstats/ProtoStreamUtils.java index 43afeed8b925..5a4256ac0264 100644 --- a/services/core/java/com/android/server/powerstats/ProtoStreamUtils.java +++ b/services/core/java/com/android/server/powerstats/ProtoStreamUtils.java @@ -19,6 +19,8 @@ package com.android.server.powerstats; import android.hardware.power.stats.ChannelInfo; import android.hardware.power.stats.EnergyConsumerResult; import android.hardware.power.stats.EnergyMeasurement; +import android.hardware.power.stats.PowerEntityInfo; +import android.hardware.power.stats.StateResidencyResult; import android.util.Slog; import android.util.proto.ProtoInputStream; import android.util.proto.ProtoOutputStream; @@ -42,6 +44,48 @@ import java.util.List; public class ProtoStreamUtils { private static final String TAG = ProtoStreamUtils.class.getSimpleName(); + static class PowerEntityInfoUtils { + public static void print(PowerEntityInfo[] powerEntityInfo) { + for (int i = 0; i < powerEntityInfo.length; i++) { + Slog.d(TAG, "PowerEntityId: " + powerEntityInfo[i].powerEntityId + + ", PowerEntityName: " + powerEntityInfo[i].powerEntityName); + for (int j = 0; j < powerEntityInfo[i].states.length; j++) { + Slog.d(TAG, " StateId: " + powerEntityInfo[i].states[j].stateId + + ", StateName: " + powerEntityInfo[i].states[j].stateName); + } + } + } + + public static void dumpsys(PowerEntityInfo[] powerEntityInfo, PrintWriter pw) { + for (int i = 0; i < powerEntityInfo.length; i++) { + pw.println("PowerEntityId: " + powerEntityInfo[i].powerEntityId + + ", PowerEntityName: " + powerEntityInfo[i].powerEntityName); + for (int j = 0; j < powerEntityInfo[i].states.length; j++) { + pw.println(" StateId: " + powerEntityInfo[i].states[j].stateId + + ", StateName: " + powerEntityInfo[i].states[j].stateName); + } + } + } + } + + static class StateResidencyResultUtils { + public static void print(StateResidencyResult[] stateResidencyResult) { + for (int i = 0; i < stateResidencyResult.length; i++) { + Slog.d(TAG, "PowerEntityId: " + stateResidencyResult[i].powerEntityId); + for (int j = 0; j < stateResidencyResult[i].stateResidencyData.length; j++) { + Slog.d(TAG, " StateId: " + + stateResidencyResult[i].stateResidencyData[j].stateId + + ", TotalTimeInStateMs: " + + stateResidencyResult[i].stateResidencyData[j].totalTimeInStateMs + + ", TotalStateEntryCount: " + + stateResidencyResult[i].stateResidencyData[j].totalStateEntryCount + + ", LastEntryTimestampMs: " + + stateResidencyResult[i].stateResidencyData[j].lastEntryTimestampMs); + } + } + } + } + static class ChannelInfoUtils { public static void packProtoMessage(ChannelInfo[] channelInfo, ProtoOutputStream pos) { long token; @@ -57,15 +101,15 @@ public class ProtoStreamUtils { public static void print(ChannelInfo[] channelInfo) { for (int i = 0; i < channelInfo.length; i++) { - Slog.d(TAG, "ChannelId = " + channelInfo[i].channelId - + ", ChannelName = " + channelInfo[i].channelName); + Slog.d(TAG, "ChannelId: " + channelInfo[i].channelId + + ", ChannelName: " + channelInfo[i].channelName); } } public static void dumpsys(ChannelInfo[] channelInfo, PrintWriter pw) { for (int i = 0; i < channelInfo.length; i++) { - pw.println("ChannelId = " + channelInfo[i].channelId - + ", ChannelName = " + channelInfo[i].channelName); + pw.println("ChannelId: " + channelInfo[i].channelId + + ", ChannelName: " + channelInfo[i].channelName); } } } @@ -157,9 +201,9 @@ public class ProtoStreamUtils { public static void print(EnergyMeasurement[] energyMeasurement) { for (int i = 0; i < energyMeasurement.length; i++) { - Slog.d(TAG, "ChannelId = " + energyMeasurement[i].channelId - + ", Timestamp (ms) = " + energyMeasurement[i].timestampMs - + ", Energy (uWs) = " + energyMeasurement[i].energyUWs); + Slog.d(TAG, "ChannelId: " + energyMeasurement[i].channelId + + ", Timestamp (ms): " + energyMeasurement[i].timestampMs + + ", Energy (uWs): " + energyMeasurement[i].energyUWs); } } } @@ -177,13 +221,13 @@ public class ProtoStreamUtils { public static void print(int[] energyConsumerId) { for (int i = 0; i < energyConsumerId.length; i++) { - Slog.d(TAG, "EnergyConsumerId = " + energyConsumerId[i]); + Slog.d(TAG, "EnergyConsumerId: " + energyConsumerId[i]); } } public static void dumpsys(int[] energyConsumerId, PrintWriter pw) { for (int i = 0; i < energyConsumerId.length; i++) { - pw.println("EnergyConsumerId = " + energyConsumerId[i]); + pw.println("EnergyConsumerId: " + energyConsumerId[i]); } } } @@ -278,9 +322,9 @@ public class ProtoStreamUtils { public static void print(EnergyConsumerResult[] energyConsumerResult) { for (int i = 0; i < energyConsumerResult.length; i++) { - Slog.d(TAG, "EnergyConsumerId = " + energyConsumerResult[i].energyConsumerId - + ", Timestamp (ms) = " + energyConsumerResult[i].timestampMs - + ", Energy (uWs) = " + energyConsumerResult[i].energyUWs); + Slog.d(TAG, "EnergyConsumerId: " + energyConsumerResult[i].energyConsumerId + + ", Timestamp (ms): " + energyConsumerResult[i].timestampMs + + ", Energy (uWs): " + energyConsumerResult[i].energyUWs); } } } diff --git a/services/core/java/com/android/server/rollback/Rollback.java b/services/core/java/com/android/server/rollback/Rollback.java index 2d51cf9a5083..63ed416f2859 100644 --- a/services/core/java/com/android/server/rollback/Rollback.java +++ b/services/core/java/com/android/server/rollback/Rollback.java @@ -141,11 +141,17 @@ class Rollback { /** * The current state of the rollback. - * ENABLING, AVAILABLE, or COMMITTED. + * ENABLING, AVAILABLE, DELETED, or COMMITTED. */ private @RollbackState int mState; /** + * The detailed description of the current state. For a DELETED state, it describes + * the reason why the rollback is deleted. + */ + private @NonNull String mStateDescription = ""; + + /** * True if we are expecting the package manager to call restoreUserData * for this rollback because it has just been committed but the rollback * has not yet been fully applied. @@ -231,7 +237,7 @@ class Rollback { * Constructs a pre-populated Rollback instance. */ Rollback(RollbackInfo info, File backupDir, Instant timestamp, int stagedSessionId, - @RollbackState int state, boolean restoreUserDataInProgress, + @RollbackState int state, String stateDescription, boolean restoreUserDataInProgress, int userId, String installerPackageName, SparseIntArray extensionVersions) { this.info = info; mUserId = userId; @@ -240,6 +246,7 @@ class Rollback { mTimestamp = timestamp; mStagedSessionId = stagedSessionId; mState = state; + mStateDescription = stateDescription; mRestoreUserDataInProgress = restoreUserDataInProgress; mExtensionVersions = Objects.requireNonNull(extensionVersions); // TODO(b/120200473): Include this field during persistence. This field will be used to @@ -478,7 +485,7 @@ class Rollback { Slog.w(TAG, "Cannot make deleted rollback available."); return; } - mState = ROLLBACK_STATE_AVAILABLE; + setState(ROLLBACK_STATE_AVAILABLE, ""); mTimestamp = Instant.now(); RollbackStore.saveRollback(this); } @@ -598,7 +605,7 @@ class Rollback { // Why would we expect commit not to fail again? // TODO: Could this cause a rollback to be resurrected // if it should otherwise have expired by now? - mState = ROLLBACK_STATE_AVAILABLE; + setState(ROLLBACK_STATE_AVAILABLE, "Commit failed"); mRestoreUserDataInProgress = false; info.setCommittedSessionId(-1); sendFailure(context, statusReceiver, @@ -642,7 +649,7 @@ class Rollback { }; final LocalIntentReceiver receiver = new LocalIntentReceiver(onResult); - mState = ROLLBACK_STATE_COMMITTED; + setState(ROLLBACK_STATE_COMMITTED, ""); info.setCommittedSessionId(parentSessionId); mRestoreUserDataInProgress = true; parentSession.commit(receiver.getIntentSender()); @@ -691,7 +698,7 @@ class Rollback { * Deletes app data snapshots associated with this rollback, and moves to the DELETED state. */ @WorkerThread - void delete(AppDataRollbackHelper dataHelper) { + void delete(AppDataRollbackHelper dataHelper, @NonNull String reason) { assertInWorkerThread(); boolean containsApex = false; Set<Integer> apexUsers = new ArraySet<>(); @@ -717,7 +724,7 @@ class Rollback { } RollbackStore.deleteRollback(this); - mState = ROLLBACK_STATE_DELETED; + setState(ROLLBACK_STATE_DELETED, reason); } /** @@ -847,6 +854,7 @@ class Rollback { case Rollback.ROLLBACK_STATE_ENABLING: return "enabling"; case Rollback.ROLLBACK_STATE_AVAILABLE: return "available"; case Rollback.ROLLBACK_STATE_COMMITTED: return "committed"; + case Rollback.ROLLBACK_STATE_DELETED: return "deleted"; } throw new AssertionError("Invalid rollback state: " + state); } @@ -858,6 +866,7 @@ class Rollback { case "enabling": return Rollback.ROLLBACK_STATE_ENABLING; case "available": return Rollback.ROLLBACK_STATE_AVAILABLE; case "committed": return Rollback.ROLLBACK_STATE_COMMITTED; + case "deleted": return Rollback.ROLLBACK_STATE_DELETED; } throw new ParseException("Invalid rollback state: " + state, 0); } @@ -926,6 +935,7 @@ class Rollback { ipw.println(info.getRollbackId() + ":"); ipw.increaseIndent(); ipw.println("-state: " + getStateAsString()); + ipw.println("-stateDescription: " + mStateDescription); ipw.println("-timestamp: " + getTimestamp()); if (getStagedSessionId() != -1) { ipw.println("-stagedSessionId: " + getStagedSessionId()); @@ -955,4 +965,17 @@ class Rollback { } ipw.decreaseIndent(); } + + @WorkerThread + String getStateDescription() { + assertInWorkerThread(); + return mStateDescription; + } + + @VisibleForTesting + void setState(@RollbackState int state, String description) { + assertInWorkerThread(); + mState = state; + mStateDescription = description; + } } diff --git a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java index b34d46ff1a0c..192a00303a30 100644 --- a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java +++ b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java @@ -179,7 +179,9 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub implements Rollba mInstaller = new Installer(mContext); mInstaller.onStart(); - mRollbackStore = new RollbackStore(new File(Environment.getDataDirectory(), "rollback")); + mRollbackStore = new RollbackStore( + new File(Environment.getDataDirectory(), "rollback"), + new File(Environment.getDataDirectory(), "rollback-history")); mPackageHealthObserver = new RollbackPackageHealthObserver(mContext); mAppDataRollbackHelper = new AppDataRollbackHelper(mInstaller); @@ -201,7 +203,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub implements Rollba } else { // Delete rollbacks when build fingerprint has changed. for (Rollback rollback : mRollbacks) { - rollback.delete(mAppDataRollbackHelper); + deleteRollback(rollback, "Fingerprint changed"); } mRollbacks.clear(); } @@ -271,7 +273,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub implements Rollba Rollback rollback = getRollbackForSession(sessionId); if (rollback != null && rollback.isEnabling()) { mRollbacks.remove(rollback); - rollback.delete(mAppDataRollbackHelper); + deleteRollback(rollback, "Rollback canceled"); } } } @@ -477,14 +479,14 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub implements Rollba } @WorkerThread - private void expireRollbackForPackageInternal(String packageName) { + private void expireRollbackForPackageInternal(String packageName, String reason) { assertInWorkerThread(); Iterator<Rollback> iter = mRollbacks.iterator(); while (iter.hasNext()) { Rollback rollback = iter.next(); if (rollback.includesPackage(packageName)) { iter.remove(); - rollback.delete(mAppDataRollbackHelper); + deleteRollback(rollback, reason); } } } @@ -496,7 +498,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub implements Rollba mContext.enforceCallingOrSelfPermission( Manifest.permission.TEST_MANAGE_ROLLBACKS, "expireRollbackForPackage"); - awaitResult(() -> expireRollbackForPackageInternal(packageName)); + awaitResult(() -> expireRollbackForPackageInternal(packageName, "Expired by API")); } @ExtThread @@ -612,7 +614,8 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub implements Rollba .getPackageInstaller().getSessionInfo(rollback.getStagedSessionId()); if (session == null || session.isStagedSessionFailed()) { iter.remove(); - rollback.delete(mAppDataRollbackHelper); + deleteRollback(rollback, + "Session " + session.getSessionId() + " not existed or failed"); continue; } @@ -666,7 +669,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub implements Rollba && rollback.includesPackageWithDifferentVersion(packageName, installedVersion)) { iter.remove(); - rollback.delete(mAppDataRollbackHelper); + deleteRollback(rollback, "Package " + packageName + " replaced"); } } } @@ -678,7 +681,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub implements Rollba @WorkerThread private void onPackageFullyRemoved(String packageName) { assertInWorkerThread(); - expireRollbackForPackageInternal(packageName); + expireRollbackForPackageInternal(packageName, "Package " + packageName + " removed"); } /** @@ -713,14 +716,14 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub implements Rollba Iterator<Rollback> iter = mRollbacks.iterator(); while (iter.hasNext()) { Rollback rollback = iter.next(); - if (!rollback.isAvailable()) { + if (!rollback.isAvailable() && !rollback.isCommitted()) { continue; } Instant rollbackTimestamp = rollback.getTimestamp(); if (!now.isBefore(rollbackTimestamp.plusMillis(mRollbackLifetimeDurationInMillis))) { Slog.i(TAG, "runExpiration id=" + rollback.info.getRollbackId()); iter.remove(); - rollback.delete(mAppDataRollbackHelper); + deleteRollback(rollback, "Expired by timeout"); } else if (oldest == null || oldest.isAfter(rollbackTimestamp)) { oldest = rollbackTimestamp; } @@ -1132,7 +1135,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub implements Rollba Slog.w(TAG, "Delete rollback id=" + rollback.info.getRollbackId() + " for failed session id=" + sessionId); mRollbacks.remove(rollback); - rollback.delete(mAppDataRollbackHelper); + deleteRollback(rollback, "Session " + sessionId + " failed"); } } } @@ -1159,7 +1162,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub implements Rollba if (!rollback.allPackagesEnabled()) { Slog.e(TAG, "Failed to enable rollback for all packages in session."); mRollbacks.remove(rollback); - rollback.delete(mAppDataRollbackHelper); + deleteRollback(rollback, "Failed to enable rollback for all packages in session"); return false; } @@ -1240,6 +1243,18 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub implements Rollba rollback.dump(ipw); } ipw.println(); + + List<Rollback> historicalRollbacks = mRollbackStore.loadHistorialRollbacks(); + if (!historicalRollbacks.isEmpty()) { + ipw.println("Historical rollbacks:"); + ipw.increaseIndent(); + for (Rollback rollback : historicalRollbacks) { + rollback.dump(ipw); + } + ipw.decreaseIndent(); + ipw.println(); + } + PackageWatchdog.getInstance(mContext).dump(ipw); }); } @@ -1329,4 +1344,11 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub implements Rollba } return null; } + + @WorkerThread + private void deleteRollback(Rollback rollback, String reason) { + assertInWorkerThread(); + rollback.delete(mAppDataRollbackHelper, reason); + mRollbackStore.saveRollbackToHistory(rollback); + } } diff --git a/services/core/java/com/android/server/rollback/RollbackStore.java b/services/core/java/com/android/server/rollback/RollbackStore.java index 2ee87e67e467..35c9f9ae6683 100644 --- a/services/core/java/com/android/server/rollback/RollbackStore.java +++ b/services/core/java/com/android/server/rollback/RollbackStore.java @@ -69,18 +69,20 @@ class RollbackStore { // * XXX, YYY are the rollbackIds for the corresponding rollbacks. // * rollback.json contains all relevant metadata for the rollback. private final File mRollbackDataDir; + private final File mRollbackHistoryDir; - RollbackStore(File rollbackDataDir) { + RollbackStore(File rollbackDataDir, File rollbackHistoryDir) { mRollbackDataDir = rollbackDataDir; + mRollbackHistoryDir = rollbackHistoryDir; } /** * Reads the rollbacks from persistent storage. */ - List<Rollback> loadRollbacks() { + private static List<Rollback> loadRollbacks(File rollbackDataDir) { List<Rollback> rollbacks = new ArrayList<>(); - mRollbackDataDir.mkdirs(); - for (File rollbackDir : mRollbackDataDir.listFiles()) { + rollbackDataDir.mkdirs(); + for (File rollbackDir : rollbackDataDir.listFiles()) { if (rollbackDir.isDirectory()) { try { rollbacks.add(loadRollback(rollbackDir)); @@ -93,6 +95,14 @@ class RollbackStore { return rollbacks; } + List<Rollback> loadRollbacks() { + return loadRollbacks(mRollbackDataDir); + } + + List<Rollback> loadHistorialRollbacks() { + return loadRollbacks(mRollbackHistoryDir); + } + /** * Converts a {@code JSONArray} of integers to a {@code List<Integer>}. */ @@ -258,15 +268,17 @@ class RollbackStore { /** * Saves the given rollback to persistent storage. */ - static void saveRollback(Rollback rollback) { + private static void saveRollback(Rollback rollback, File backDir) { FileOutputStream fos = null; - AtomicFile file = new AtomicFile(new File(rollback.getBackupDir(), "rollback.json")); + AtomicFile file = new AtomicFile(new File(backDir, "rollback.json")); try { + backDir.mkdirs(); JSONObject dataJson = new JSONObject(); dataJson.put("info", rollbackInfoToJson(rollback.info)); dataJson.put("timestamp", rollback.getTimestamp().toString()); dataJson.put("stagedSessionId", rollback.getStagedSessionId()); dataJson.put("state", rollback.getStateAsString()); + dataJson.put("stateDescription", rollback.getStateDescription()); dataJson.put("restoreUserDataInProgress", rollback.isRestoreUserDataInProgress()); dataJson.put("userId", rollback.getUserId()); dataJson.putOpt("installerPackageName", rollback.getInstallerPackageName()); @@ -286,6 +298,22 @@ class RollbackStore { } } + static void saveRollback(Rollback rollback) { + saveRollback(rollback, rollback.getBackupDir()); + } + + /** + * Saves the rollback to $mRollbackHistoryDir/ROLLBACKID-HEX for debugging purpose. + */ + void saveRollbackToHistory(Rollback rollback) { + // The same id might be allocated to different historical rollbacks. + // Let's add a suffix to avoid naming collision. + String suffix = Long.toHexString(rollback.getTimestamp().getEpochSecond()); + String dirName = Integer.toString(rollback.info.getRollbackId()); + File backupDir = new File(mRollbackHistoryDir, dirName + "-" + suffix); + saveRollback(rollback, backupDir); + } + /** * Removes all persistent storage associated with the given rollback. */ @@ -318,6 +346,7 @@ class RollbackStore { Instant.parse(dataJson.getString("timestamp")), dataJson.getInt("stagedSessionId"), rollbackStateFromString(dataJson.getString("state")), + dataJson.optString("stateDescription"), dataJson.getBoolean("restoreUserDataInProgress"), dataJson.optInt("userId", UserHandle.SYSTEM.getIdentifier()), dataJson.optString("installerPackageName", ""), diff --git a/services/core/java/com/android/server/storage/StorageUserConnection.java b/services/core/java/com/android/server/storage/StorageUserConnection.java index b79fc8dd1e1a..af2628971bdd 100644 --- a/services/core/java/com/android/server/storage/StorageUserConnection.java +++ b/services/core/java/com/android/server/storage/StorageUserConnection.java @@ -23,6 +23,7 @@ import static android.service.storage.ExternalStorageService.FLAG_SESSION_TYPE_F import static com.android.server.storage.StorageSessionController.ExternalStorageServiceException; import android.annotation.MainThread; +import android.annotation.NonNull; import android.annotation.Nullable; import android.content.ComponentName; import android.content.Context; @@ -34,28 +35,27 @@ import android.os.IBinder; import android.os.ParcelFileDescriptor; import android.os.ParcelableException; import android.os.RemoteCallback; +import android.os.RemoteException; import android.os.UserHandle; import android.os.storage.StorageManagerInternal; import android.os.storage.StorageVolume; import android.service.storage.ExternalStorageService; import android.service.storage.IExternalStorageService; -import android.text.TextUtils; import android.util.Slog; import com.android.internal.annotations.GuardedBy; import com.android.internal.util.Preconditions; import com.android.server.LocalServices; -import com.android.server.pm.UserManagerInternal; import java.io.IOException; +import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Objects; import java.util.Set; -import java.util.concurrent.CountDownLatch; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; /** * Controls the lifecycle of the {@link ActiveConnection} to an {@link ExternalStorageService} @@ -66,25 +66,20 @@ public final class StorageUserConnection { private static final int DEFAULT_REMOTE_TIMEOUT_SECONDS = 20; - private final Object mLock = new Object(); + private final Object mSessionsLock = new Object(); private final Context mContext; private final int mUserId; private final StorageSessionController mSessionController; private final ActiveConnection mActiveConnection = new ActiveConnection(); - private final boolean mIsDemoUser; @GuardedBy("mLock") private final Map<String, Session> mSessions = new HashMap<>(); - @GuardedBy("mLock") @Nullable private HandlerThread mHandlerThread; + private final HandlerThread mHandlerThread; public StorageUserConnection(Context context, int userId, StorageSessionController controller) { mContext = Objects.requireNonNull(context); mUserId = Preconditions.checkArgumentNonnegative(userId); mSessionController = controller; - mIsDemoUser = LocalServices.getService(UserManagerInternal.class) - .getUserInfo(userId).isDemo(); - if (mIsDemoUser) { - mHandlerThread = new HandlerThread("StorageUserConnectionThread-" + mUserId); - mHandlerThread.start(); - } + mHandlerThread = new HandlerThread("StorageUserConnectionThread-" + mUserId); + mHandlerThread.start(); } /** @@ -101,13 +96,12 @@ public final class StorageUserConnection { Objects.requireNonNull(upperPath); Objects.requireNonNull(lowerPath); - prepareRemote(); - synchronized (mLock) { + Session session = new Session(sessionId, upperPath, lowerPath); + synchronized (mSessionsLock) { Preconditions.checkArgument(!mSessions.containsKey(sessionId)); - Session session = new Session(sessionId, upperPath, lowerPath); mSessions.put(sessionId, session); - mActiveConnection.startSessionLocked(session, pfd); } + mActiveConnection.startSession(session, pfd); } /** @@ -121,10 +115,13 @@ public final class StorageUserConnection { Objects.requireNonNull(sessionId); Objects.requireNonNull(vol); - prepareRemote(); - synchronized (mLock) { - mActiveConnection.notifyVolumeStateChangedLocked(sessionId, vol); + synchronized (mSessionsLock) { + if (!mSessions.containsKey(sessionId)) { + Slog.i(TAG, "No session found for sessionId: " + sessionId); + return; + } } + mActiveConnection.notifyVolumeStateChanged(sessionId, vol); } /** @@ -135,7 +132,7 @@ public final class StorageUserConnection { * with {@link #waitForExit}. **/ public Session removeSession(String sessionId) { - synchronized (mLock) { + synchronized (mSessionsLock) { return mSessions.remove(sessionId); } } @@ -153,10 +150,7 @@ public final class StorageUserConnection { } Slog.i(TAG, "Waiting for session end " + session + " ..."); - prepareRemote(); - synchronized (mLock) { - mActiveConnection.endSessionLocked(session); - } + mActiveConnection.endSession(session); } /** Restarts all available sessions for a user without blocking. @@ -164,7 +158,7 @@ public final class StorageUserConnection { * Any failures will be ignored. **/ public void resetUserSessions() { - synchronized (mLock) { + synchronized (mSessionsLock) { if (mSessions.isEmpty()) { // Nothing to reset if we have no sessions to restart; we typically // hit this path if the user was consciously shut down. @@ -179,7 +173,7 @@ public final class StorageUserConnection { * Removes all sessions, without waiting. */ public void removeAllSessions() { - synchronized (mLock) { + synchronized (mSessionsLock) { Slog.i(TAG, "Removing " + mSessions.size() + " sessions for user: " + mUserId + "..."); mSessions.clear(); } @@ -191,68 +185,54 @@ public final class StorageUserConnection { */ public void close() { mActiveConnection.close(); - if (mIsDemoUser) { - mHandlerThread.quit(); - } + mHandlerThread.quit(); } /** Returns all created sessions. */ public Set<String> getAllSessionIds() { - synchronized (mLock) { + synchronized (mSessionsLock) { return new HashSet<>(mSessions.keySet()); } } - private void prepareRemote() throws ExternalStorageServiceException { - try { - waitForLatch(mActiveConnection.bind(), "remote_prepare_user " + mUserId); - } catch (IllegalStateException | TimeoutException e) { - throw new ExternalStorageServiceException("Failed to prepare remote", e); - } - } - - private void waitForLatch(CountDownLatch latch, String reason) throws TimeoutException { - try { - if (!latch.await(DEFAULT_REMOTE_TIMEOUT_SECONDS, TimeUnit.SECONDS)) { - // TODO(b/140025078): Call ActivityManager ANR API? - Slog.wtf(TAG, "Failed to bind to the ExternalStorageService for user " + mUserId); - throw new TimeoutException("Latch wait for " + reason + " elapsed"); - } - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - throw new IllegalStateException("Latch wait for " + reason + " interrupted"); - } + @FunctionalInterface + interface AsyncStorageServiceCall { + void run(@NonNull IExternalStorageService service, RemoteCallback callback) throws + RemoteException; } private final class ActiveConnection implements AutoCloseable { + private final Object mLock = new Object(); + // Lifecycle connection to the external storage service, needed to unbind. @GuardedBy("mLock") @Nullable private ServiceConnection mServiceConnection; - // True if we are connecting, either bound or binding - // False && mRemote != null means we are connected - // False && mRemote == null means we are neither connecting nor connected - @GuardedBy("mLock") @Nullable private boolean mIsConnecting; - // Binder object representing the external storage service. - // Non-null indicates we are connected - @GuardedBy("mLock") @Nullable private IExternalStorageService mRemote; - // Exception, if any, thrown from #startSessionLocked or #endSessionLocked - // Local variables cannot be referenced from a lambda expression :( so we - // save the exception received in the callback here. Since we guard access - // (and clear the exception state) with the same lock which we hold during - // the entire transaction, there is no risk of race. - @GuardedBy("mLock") @Nullable private ParcelableException mLastException; - // Not guarded by any lock intentionally and non final because we cannot - // reset latches so need to create a new one after one use - private CountDownLatch mLatch; + + // A future that holds the remote interface + @GuardedBy("mLock") + @Nullable private CompletableFuture<IExternalStorageService> mRemoteFuture; + + // A list of outstanding futures for async calls, for which we are still waiting + // for a callback. Used to unblock waiters if the service dies. + @GuardedBy("mLock") + private ArrayList<CompletableFuture<Void>> mOutstandingOps = new ArrayList<>(); @Override public void close() { ServiceConnection oldConnection = null; synchronized (mLock) { Slog.i(TAG, "Closing connection for user " + mUserId); - mIsConnecting = false; oldConnection = mServiceConnection; mServiceConnection = null; - mRemote = null; + if (mRemoteFuture != null) { + // Let folks who are waiting for the connection know it ain't gonna happen + mRemoteFuture.cancel(true); + mRemoteFuture = null; + } + // Let folks waiting for callbacks from the remote know it ain't gonna happen + for (CompletableFuture<Void> op : mOutstandingOps) { + op.cancel(true); + } + mOutstandingOps.clear(); } if (oldConnection != null) { @@ -266,37 +246,37 @@ public final class StorageUserConnection { } } - public boolean isActiveLocked(Session session) { - if (!session.isInitialisedLocked()) { - Slog.i(TAG, "Session not initialised " + session); - return false; - } + private void waitForAsync(AsyncStorageServiceCall asyncCall) throws Exception { + CompletableFuture<IExternalStorageService> serviceFuture = connectIfNeeded(); + CompletableFuture<Void> opFuture = new CompletableFuture<>(); - if (mRemote == null) { - throw new IllegalStateException("Valid session with inactive connection"); - } - return true; - } + try { + synchronized (mLock) { + mOutstandingOps.add(opFuture); + } + serviceFuture.thenCompose(service -> { + try { + asyncCall.run(service, + new RemoteCallback(result -> setResult(result, opFuture))); + } catch (RemoteException e) { + opFuture.completeExceptionally(e); + } - public void startSessionLocked(Session session, ParcelFileDescriptor fd) - throws ExternalStorageServiceException { - if (!isActiveLocked(session)) { - try { - fd.close(); - } catch (IOException e) { - // ignore + return opFuture; + }).get(DEFAULT_REMOTE_TIMEOUT_SECONDS, TimeUnit.SECONDS); + } finally { + synchronized (mLock) { + mOutstandingOps.remove(opFuture); } - return; } + } - CountDownLatch latch = new CountDownLatch(1); + public void startSession(Session session, ParcelFileDescriptor fd) + throws ExternalStorageServiceException { try { - mRemote.startSession(session.sessionId, + waitForAsync((service, callback) -> service.startSession(session.sessionId, FLAG_SESSION_TYPE_FUSE | FLAG_SESSION_ATTRIBUTE_INDEXABLE, - fd, session.upperPath, session.lowerPath, new RemoteCallback(result -> - setResultLocked(latch, result))); - waitForLatch(latch, "start_session " + session); - maybeThrowExceptionLocked(); + fd, session.upperPath, session.lowerPath, callback)); } catch (Exception e) { throw new ExternalStorageServiceException("Failed to start session: " + session, e); } finally { @@ -308,73 +288,49 @@ public final class StorageUserConnection { } } - public void endSessionLocked(Session session) throws ExternalStorageServiceException { - if (!isActiveLocked(session)) { - // Nothing to end, not started yet - return; - } - - CountDownLatch latch = new CountDownLatch(1); + public void endSession(Session session) throws ExternalStorageServiceException { try { - mRemote.endSession(session.sessionId, new RemoteCallback(result -> - setResultLocked(latch, result))); - waitForLatch(latch, "end_session " + session); - maybeThrowExceptionLocked(); + waitForAsync((service, callback) -> + service.endSession(session.sessionId, callback)); } catch (Exception e) { throw new ExternalStorageServiceException("Failed to end session: " + session, e); } } - public void notifyVolumeStateChangedLocked(String sessionId, StorageVolume vol) throws + + public void notifyVolumeStateChanged(String sessionId, StorageVolume vol) throws ExternalStorageServiceException { - CountDownLatch latch = new CountDownLatch(1); try { - mRemote.notifyVolumeStateChanged(sessionId, vol, new RemoteCallback( - result -> setResultLocked(latch, result))); - waitForLatch(latch, "notify_volume_state_changed " + vol); - maybeThrowExceptionLocked(); + waitForAsync((service, callback) -> + service.notifyVolumeStateChanged(sessionId, vol, callback)); } catch (Exception e) { throw new ExternalStorageServiceException("Failed to notify volume state changed " + "for vol : " + vol, e); } } - private void setResultLocked(CountDownLatch latch, Bundle result) { - mLastException = result.getParcelable(EXTRA_ERROR); - latch.countDown(); - } - - private void maybeThrowExceptionLocked() throws IOException { - if (mLastException != null) { - ParcelableException lastException = mLastException; - mLastException = null; - try { - lastException.maybeRethrow(IOException.class); - } catch (IOException e) { - throw e; - } - throw new RuntimeException(lastException); + private void setResult(Bundle result, CompletableFuture<Void> future) { + ParcelableException ex = result.getParcelable(EXTRA_ERROR); + if (ex != null) { + future.completeExceptionally(ex); + } else { + future.complete(null); } } - public CountDownLatch bind() throws ExternalStorageServiceException { + private CompletableFuture<IExternalStorageService> connectIfNeeded() throws + ExternalStorageServiceException { ComponentName name = mSessionController.getExternalStorageServiceComponentName(); if (name == null) { // Not ready to bind throw new ExternalStorageServiceException( "Not ready to bind to the ExternalStorageService for user " + mUserId); } - synchronized (mLock) { - if (mRemote != null || mIsConnecting) { - // Connected or connecting (bound or binding) - // Will wait on a latch that will countdown when we connect, unless we are - // connected and the latch has already countdown, yay! - return mLatch; - } // else neither connected nor connecting - - mLatch = new CountDownLatch(1); - mIsConnecting = true; + if (mRemoteFuture != null) { + return mRemoteFuture; + } + CompletableFuture<IExternalStorageService> future = new CompletableFuture<>(); mServiceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { @@ -406,16 +362,9 @@ public final class StorageUserConnection { private void handleConnection(IBinder service) { synchronized (mLock) { - if (mIsConnecting) { - mRemote = IExternalStorageService.Stub.asInterface(service); - mIsConnecting = false; - mLatch.countDown(); - // Separate thread so we don't block the main thead - return; - } + future.complete( + IExternalStorageService.Stub.asInterface(service)); } - Slog.wtf(TAG, "Connection closed to the ExternalStorageService for user " - + mUserId); } private void handleDisconnection() { @@ -429,32 +378,19 @@ public final class StorageUserConnection { }; Slog.i(TAG, "Binding to the ExternalStorageService for user " + mUserId); - if (mIsDemoUser) { - // Schedule on a worker thread for demo user to avoid deadlock - if (mContext.bindServiceAsUser(new Intent().setComponent(name), - mServiceConnection, - Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT, - mHandlerThread.getThreadHandler(), - UserHandle.of(mUserId))) { - Slog.i(TAG, "Bound to the ExternalStorageService for user " + mUserId); - return mLatch; - } else { - mIsConnecting = false; - throw new ExternalStorageServiceException( - "Failed to bind to the ExternalStorageService for user " + mUserId); - } + // Schedule on a worker thread, because the system server main thread can be + // very busy early in boot. + if (mContext.bindServiceAsUser(new Intent().setComponent(name), + mServiceConnection, + Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT, + mHandlerThread.getThreadHandler(), + UserHandle.of(mUserId))) { + Slog.i(TAG, "Bound to the ExternalStorageService for user " + mUserId); + mRemoteFuture = future; + return future; } else { - if (mContext.bindServiceAsUser(new Intent().setComponent(name), - mServiceConnection, - Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT, - UserHandle.of(mUserId))) { - Slog.i(TAG, "Bound to the ExternalStorageService for user " + mUserId); - return mLatch; - } else { - mIsConnecting = false; - throw new ExternalStorageServiceException( - "Failed to bind to the ExternalStorageService for user " + mUserId); - } + throw new ExternalStorageServiceException( + "Failed to bind to the ExternalStorageService for user " + mUserId); } } } @@ -476,10 +412,5 @@ public final class StorageUserConnection { return "[SessionId: " + sessionId + ". UpperPath: " + upperPath + ". LowerPath: " + lowerPath + "]"; } - - @GuardedBy("mLock") - public boolean isInitialisedLocked() { - return !TextUtils.isEmpty(upperPath) && !TextUtils.isEmpty(lowerPath); - } } } diff --git a/services/core/java/com/android/server/timedetector/TimeDetectorService.java b/services/core/java/com/android/server/timedetector/TimeDetectorService.java index 59cebf769a4e..789dd5273094 100644 --- a/services/core/java/com/android/server/timedetector/TimeDetectorService.java +++ b/services/core/java/com/android/server/timedetector/TimeDetectorService.java @@ -71,9 +71,8 @@ public final class TimeDetectorService extends ITimeDetectorService.Stub { @NonNull private final TimeDetectorStrategy mTimeDetectorStrategy; private static TimeDetectorService create(@NonNull Context context) { - TimeDetectorStrategy timeDetectorStrategy = new TimeDetectorStrategyImpl(); - TimeDetectorStrategyCallbackImpl callback = new TimeDetectorStrategyCallbackImpl(context); - timeDetectorStrategy.initialize(callback); + TimeDetectorStrategyImpl.Callback callback = new TimeDetectorStrategyCallbackImpl(context); + TimeDetectorStrategy timeDetectorStrategy = new TimeDetectorStrategyImpl(callback); Handler handler = FgThread.getHandler(); TimeDetectorService timeDetectorService = diff --git a/services/core/java/com/android/server/timedetector/TimeDetectorStrategy.java b/services/core/java/com/android/server/timedetector/TimeDetectorStrategy.java index e943978cfc14..3b2b992c15ba 100644 --- a/services/core/java/com/android/server/timedetector/TimeDetectorStrategy.java +++ b/services/core/java/com/android/server/timedetector/TimeDetectorStrategy.java @@ -37,46 +37,6 @@ import com.android.server.timezonedetector.Dumpable; */ public interface TimeDetectorStrategy extends Dumpable { - /** - * The interface used by the strategy to interact with the surrounding service. - * - * <p>Note: Because the system properties-derived value {@link #isAutoTimeDetectionEnabled()} - * can be modified independently and from different threads (and processes!). its use is prone - * to race conditions. That will be true until the responsibility for setting their values is - * moved to {@link TimeDetectorStrategy}. There are similar issues with - * {@link #systemClockMillis()} while any process can modify the system clock. - */ - interface Callback { - - /** - * The absolute threshold below which the system clock need not be updated. i.e. if setting - * the system clock would adjust it by less than this (either backwards or forwards) then it - * need not be set. - */ - int systemClockUpdateThresholdMillis(); - - /** Returns true if automatic time detection is enabled. */ - boolean isAutoTimeDetectionEnabled(); - - /** Acquire a suitable wake lock. Must be followed by {@link #releaseWakeLock()} */ - void acquireWakeLock(); - - /** Returns the elapsedRealtimeMillis clock value. */ - long elapsedRealtimeMillis(); - - /** Returns the system clock value. */ - long systemClockMillis(); - - /** Sets the device system clock. The WakeLock must be held. */ - void setSystemClock(long newTimeMillis); - - /** Release the wake lock acquired by a call to {@link #acquireWakeLock()}. */ - void releaseWakeLock(); - } - - /** Initialize the strategy. */ - void initialize(@NonNull Callback callback); - /** Process the suggested time from telephony sources. */ void suggestTelephonyTime(@NonNull TelephonyTimeSuggestion timeSuggestion); diff --git a/services/core/java/com/android/server/timedetector/TimeDetectorStrategyCallbackImpl.java b/services/core/java/com/android/server/timedetector/TimeDetectorStrategyCallbackImpl.java index 19484db149b1..6bd107fffeaa 100644 --- a/services/core/java/com/android/server/timedetector/TimeDetectorStrategyCallbackImpl.java +++ b/services/core/java/com/android/server/timedetector/TimeDetectorStrategyCallbackImpl.java @@ -20,24 +20,34 @@ import android.annotation.NonNull; import android.app.AlarmManager; import android.content.ContentResolver; import android.content.Context; +import android.os.Build; +import android.os.Environment; import android.os.PowerManager; import android.os.SystemClock; import android.os.SystemProperties; import android.provider.Settings; import android.util.Slog; +import java.time.Instant; import java.util.Objects; /** - * The real implementation of {@link TimeDetectorStrategy.Callback} used on device. + * The real implementation of {@link TimeDetectorStrategyImpl.Callback} used on device. */ -public final class TimeDetectorStrategyCallbackImpl implements TimeDetectorStrategy.Callback { +public final class TimeDetectorStrategyCallbackImpl implements TimeDetectorStrategyImpl.Callback { private final static String TAG = "timedetector.TimeDetectorStrategyCallbackImpl"; private static final int SYSTEM_CLOCK_UPDATE_THRESHOLD_MILLIS_DEFAULT = 2 * 1000; /** + * Time in the past. If automatic time suggestion is before this point, it's + * incorrect for sure. + */ + private static final Instant TIME_LOWER_BOUND = Instant.ofEpochMilli( + Long.max(Environment.getRootDirectory().lastModified(), Build.TIME)); + + /** * If a newly calculated system clock time and the current system clock time differs by this or * more the system clock will actually be updated. Used to prevent the system clock being set * for only minor differences. @@ -79,6 +89,11 @@ public final class TimeDetectorStrategyCallbackImpl implements TimeDetectorStrat } @Override + public Instant autoTimeLowerBound() { + return TIME_LOWER_BOUND; + } + + @Override public void acquireWakeLock() { if (mWakeLock.isHeld()) { Slog.wtf(TAG, "WakeLock " + mWakeLock + " already held"); diff --git a/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java b/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java index 9c18aadb79ec..6c5d2f2ab452 100644 --- a/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java +++ b/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java @@ -35,6 +35,7 @@ import com.android.server.timezonedetector.ReferenceWithHistory; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import java.time.Instant; /** * An implementation of {@link TimeDetectorStrategy} that passes telephony and manual suggestions to @@ -98,8 +99,8 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy { @NonNull private final LocalLog mTimeChangesLog = new LocalLog(30, false /* useLocalTimestamps */); - // @NonNull after initialize() - private Callback mCallback; + @NonNull + private final Callback mCallback; // Used to store the last time the system clock state was set automatically. It is used to // detect (and log) issues with the realtime clock or whether the clock is being set without @@ -121,8 +122,53 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy { private final ReferenceWithHistory<NetworkTimeSuggestion> mLastNetworkSuggestion = new ReferenceWithHistory<>(KEEP_SUGGESTION_HISTORY_SIZE); - @Override - public void initialize(@NonNull Callback callback) { + /** + * The interface used by the strategy to interact with the surrounding service. + * + * <p>Note: Because the system properties-derived value {@link #isAutoTimeDetectionEnabled()} + * can be modified independently and from different threads (and processes!), its use is prone + * to race conditions. That will be true until the responsibility for setting their values is + * moved to {@link TimeDetectorStrategy}. There are similar issues with + * {@link #systemClockMillis()} while any process can modify the system clock. + */ + public interface Callback { + + /** + * The absolute threshold below which the system clock need not be updated. i.e. if setting + * the system clock would adjust it by less than this (either backwards or forwards) then it + * need not be set. + */ + int systemClockUpdateThresholdMillis(); + + /** Returns true if automatic time detection is enabled. */ + boolean isAutoTimeDetectionEnabled(); + + /** + * Returns a lower bound for valid automatic times. It is guaranteed to be in the past, + * i.e. it is unrelated to the current system clock time. + * It holds no other meaning; it could be related to when the device system image was built, + * or could be updated by a mainline module. + */ + @NonNull + Instant autoTimeLowerBound(); + + /** Acquire a suitable wake lock. Must be followed by {@link #releaseWakeLock()} */ + void acquireWakeLock(); + + /** Returns the elapsedRealtimeMillis clock value. */ + long elapsedRealtimeMillis(); + + /** Returns the system clock value. */ + long systemClockMillis(); + + /** Sets the device system clock. The WakeLock must be held. */ + void setSystemClock(long newTimeMillis); + + /** Release the wake lock acquired by a call to {@link #acquireWakeLock()}. */ + void releaseWakeLock(); + } + + TimeDetectorStrategyImpl(@NonNull Callback callback) { mCallback = callback; } @@ -140,7 +186,7 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy { @Override public synchronized void suggestNetworkTime(@NonNull NetworkTimeSuggestion timeSuggestion) { - if (!validateSuggestionTime(timeSuggestion.getUtcTime(), timeSuggestion)) { + if (!validateAutoSuggestionTime(timeSuggestion.getUtcTime(), timeSuggestion)) { return; } @@ -174,9 +220,12 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy { return; } - // Perform validation / input filtering and record the validated suggestion against the - // slotIndex. - if (!validateAndStoreTelephonySuggestion(timeSuggestion)) { + if (!validateAutoSuggestionTime(timeSuggestion.getUtcTime(), timeSuggestion)) { + return; + } + + // Perform input filtering and record the validated suggestion against the slotIndex. + if (!storeTelephonySuggestion(timeSuggestion)) { return; } @@ -233,14 +282,9 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy { } @GuardedBy("this") - private boolean validateAndStoreTelephonySuggestion( + private boolean storeTelephonySuggestion( @NonNull TelephonyTimeSuggestion suggestion) { TimestampedValue<Long> newUtcTime = suggestion.getUtcTime(); - if (!validateSuggestionTime(newUtcTime, suggestion)) { - // There's probably nothing useful we can do: elsewhere we assume that reference - // times are in the past so just stop here. - return false; - } int slotIndex = suggestion.getSlotIndex(); TelephonyTimeSuggestion previousSuggestion = mSuggestionBySlotIndex.get(slotIndex); @@ -291,6 +335,26 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy { return true; } + private boolean validateAutoSuggestionTime( + @NonNull TimestampedValue<Long> newUtcTime, @NonNull Object suggestion) { + return validateSuggestionTime(newUtcTime, suggestion) + && validateSuggestionAgainstLowerBound(newUtcTime, suggestion); + } + + private boolean validateSuggestionAgainstLowerBound( + @NonNull TimestampedValue<Long> newUtcTime, @NonNull Object suggestion) { + Instant lowerBound = mCallback.autoTimeLowerBound(); + + // Suggestion is definitely wrong if it comes before lower time bound. + if (lowerBound.isAfter(Instant.ofEpochMilli(newUtcTime.getValue()))) { + Slog.w(LOG_TAG, "Suggestion points to time before lower bound, skipping it. " + + "suggestion=" + suggestion + ", lower bound=" + lowerBound); + return false; + } + + return true; + } + @GuardedBy("this") private void doAutoTimeDetection(@NonNull String detectionReason) { if (!mCallback.isAutoTimeDetectionEnabled()) { diff --git a/services/core/java/com/android/server/vibrator/InputDeviceDelegate.java b/services/core/java/com/android/server/vibrator/InputDeviceDelegate.java new file mode 100644 index 000000000000..edbc05802697 --- /dev/null +++ b/services/core/java/com/android/server/vibrator/InputDeviceDelegate.java @@ -0,0 +1,171 @@ +/* + * 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.server.vibrator; + +import android.content.Context; +import android.hardware.input.InputManager; +import android.os.Handler; +import android.os.VibrationAttributes; +import android.os.VibrationEffect; +import android.os.Vibrator; +import android.util.SparseArray; +import android.view.InputDevice; + +import com.android.internal.annotations.GuardedBy; + +/** Delegates vibrations to all connected {@link InputDevice} with available {@link Vibrator}. */ +// TODO(b/159207608): Make this package-private once vibrator services are moved to this package +public final class InputDeviceDelegate implements InputManager.InputDeviceListener { + private static final String TAG = "InputDeviceDelegate"; + + private final Object mLock = new Object(); + private final Handler mHandler; + private final InputManager mInputManager; + + @GuardedBy("mLock") + private final SparseArray<Vibrator> mInputDeviceVibrators = new SparseArray<>(); + + /** + * Flag updated via {@link #updateInputDeviceVibrators(boolean)}, holding the value of {@link + * android.provider.Settings.System#VIBRATE_INPUT_DEVICES}. + */ + @GuardedBy("mLock") + private boolean mShouldVibrateInputDevices; + + public InputDeviceDelegate(Context context, Handler handler) { + mHandler = handler; + mInputManager = context.getSystemService(InputManager.class); + } + + @Override + public void onInputDeviceAdded(int deviceId) { + updateInputDevice(deviceId); + } + + @Override + public void onInputDeviceChanged(int deviceId) { + updateInputDevice(deviceId); + } + + @Override + public void onInputDeviceRemoved(int deviceId) { + synchronized (mLock) { + mInputDeviceVibrators.remove(deviceId); + } + } + + /** + * Return {@code true} is there are input devices with vibrators available and vibrations should + * be delegated to them. + */ + public boolean isAvailable() { + synchronized (mLock) { + // mInputDeviceVibrators is cleared when settings are disabled, so this check is enough. + return mInputDeviceVibrators.size() > 0; + } + } + + /** + * Vibrate all {@link InputDevice} with {@link Vibrator} available using given effect. + * + * @return {@link #isAvailable()} + */ + public boolean vibrateIfAvailable(int uid, String opPkg, VibrationEffect effect, + String reason, VibrationAttributes attrs) { + synchronized (mLock) { + for (int i = 0; i < mInputDeviceVibrators.size(); i++) { + mInputDeviceVibrators.valueAt(i).vibrate(uid, opPkg, effect, reason, attrs); + } + return mInputDeviceVibrators.size() > 0; + } + } + + /** + * Cancel vibration on all {@link InputDevice} with {@link Vibrator} available. + * + * @return {@link #isAvailable()} + */ + public boolean cancelVibrateIfAvailable() { + synchronized (mLock) { + for (int i = 0; i < mInputDeviceVibrators.size(); i++) { + mInputDeviceVibrators.valueAt(i).cancel(); + } + return mInputDeviceVibrators.size() > 0; + } + } + + /** + * Updates the list of {@link InputDevice} vibrators based on the {@link + * VibrationSettings#shouldVibrateInputDevices()} setting current value and the + * devices currently available in {@link InputManager#getInputDeviceIds()}. + * + * @return true if there was any change in input devices available or related settings. + */ + public boolean updateInputDeviceVibrators(boolean vibrateInputDevices) { + synchronized (mLock) { + if (vibrateInputDevices == mShouldVibrateInputDevices) { + // No need to update if settings haven't changed. + return false; + } + + mShouldVibrateInputDevices = vibrateInputDevices; + mInputDeviceVibrators.clear(); + + if (vibrateInputDevices) { + // Register the listener first so any device added/updated/removed after the call to + // getInputDeviceIds() will trigger the callbacks (which will wait on the lock for + // this loop to finish). + mInputManager.registerInputDeviceListener(this, mHandler); + + for (int deviceId : mInputManager.getInputDeviceIds()) { + InputDevice device = mInputManager.getInputDevice(deviceId); + if (device == null) { + continue; + } + Vibrator vibrator = device.getVibrator(); + if (vibrator.hasVibrator()) { + mInputDeviceVibrators.put(device.getId(), vibrator); + } + } + } else { + mInputManager.unregisterInputDeviceListener(this); + } + } + + return true; + } + + private void updateInputDevice(int deviceId) { + synchronized (mLock) { + if (!mShouldVibrateInputDevices) { + // No need to keep this device vibrator if setting is off. + return; + } + InputDevice device = mInputManager.getInputDevice(deviceId); + if (device == null) { + mInputDeviceVibrators.remove(deviceId); + return; + } + Vibrator vibrator = device.getVibrator(); + if (vibrator.hasVibrator()) { + mInputDeviceVibrators.put(deviceId, vibrator); + } else { + mInputDeviceVibrators.remove(deviceId); + } + } + } +} diff --git a/services/core/java/com/android/server/vibrator/Vibration.java b/services/core/java/com/android/server/vibrator/Vibration.java new file mode 100644 index 000000000000..e2cdd02deab9 --- /dev/null +++ b/services/core/java/com/android/server/vibrator/Vibration.java @@ -0,0 +1,287 @@ +/* + * 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.server.vibrator; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.os.IBinder; +import android.os.SystemClock; +import android.os.VibrationAttributes; +import android.os.VibrationEffect; +import android.util.proto.ProtoOutputStream; + +import com.android.server.ComposedProto; +import com.android.server.OneShotProto; +import com.android.server.PrebakedProto; +import com.android.server.VibrationAttributesProto; +import com.android.server.VibrationEffectProto; +import com.android.server.VibrationProto; +import com.android.server.WaveformProto; + +import java.text.SimpleDateFormat; +import java.util.Date; + +/** Represents a vibration request to the vibrator service. */ +// TODO(b/159207608): Make this package-private once vibrator services are moved to this package +public class Vibration { + private static final String TAG = "Vibration"; + private static final SimpleDateFormat DEBUG_DATE_FORMAT = + new SimpleDateFormat("MM-dd HH:mm:ss.SSS"); + + public enum Status { + RUNNING, + FINISHED, + FORWARDED_TO_INPUT_DEVICES, + CANCELLED, + ERROR_APP_OPS, + IGNORED, + IGNORED_APP_OPS, + IGNORED_BACKGROUND, + IGNORED_RINGTONE, + IGNORED_UNKNOWN_VIBRATION, + IGNORED_UNSUPPORTED, + IGNORED_FOR_ALARM, + IGNORED_FOR_EXTERNAL, + IGNORED_FOR_ONGOING, + IGNORED_FOR_POWER, + IGNORED_FOR_SETTINGS, + } + + /** Start time in CLOCK_BOOTTIME base. */ + public final long startTime; + public final VibrationAttributes attrs; + public final long id; + public final int uid; + public final String opPkg; + public final String reason; + public final IBinder token; + + /** The actual effect to be played. */ + @Nullable + private VibrationEffect mEffect; + + /** + * The original effect that was requested. Typically these two things differ because the effect + * was scaled based on the users vibration intensity settings. + */ + @Nullable + private VibrationEffect mOriginalEffect; + + /** + * Start/end times in unix epoch time. Only to be used for debugging purposes and to correlate + * with other system events, any duration calculations should be done use {@link #startTime} so + * as not to be affected by discontinuities created by RTC adjustments. + */ + private final long mStartTimeDebug; + private long mEndTimeDebug; + private Status mStatus; + + public Vibration(IBinder token, int id, VibrationEffect effect, + VibrationAttributes attrs, int uid, String opPkg, String reason) { + this.token = token; + this.mEffect = effect; + this.id = id; + this.startTime = SystemClock.elapsedRealtime(); + this.attrs = attrs; + this.uid = uid; + this.opPkg = opPkg; + this.reason = reason; + mStartTimeDebug = System.currentTimeMillis(); + mStatus = Status.RUNNING; + } + + /** + * Set the {@link Status} of this vibration and the current system time as this + * vibration end time, for debugging purposes. + * + * <p>This method will only accept given value if the current status is {@link + * Status#RUNNING}. + */ + public void end(Status status) { + if (hasEnded()) { + // Vibration already ended, keep first ending status set and ignore this one. + return; + } + mStatus = status; + mEndTimeDebug = System.currentTimeMillis(); + } + + /** + * Replace this vibration effect if given {@code scaledEffect} is different, preserving the + * original one for debug purposes. + */ + public void updateEffect(@NonNull VibrationEffect newEffect) { + if (newEffect.equals(mEffect)) { + return; + } + mOriginalEffect = mEffect; + mEffect = newEffect; + } + + /** Return true is current status is different from {@link Status#RUNNING}. */ + public boolean hasEnded() { + return mStatus != Status.RUNNING; + } + + /** Return the effect that should be played by this vibration. */ + @Nullable + public VibrationEffect getEffect() { + return mEffect; + } + + /** Return {@link Vibration.DebugInfo} with read-only debug information about this vibration. */ + public Vibration.DebugInfo getDebugInfo() { + return new Vibration.DebugInfo( + mStartTimeDebug, mEndTimeDebug, mEffect, mOriginalEffect, /* scale= */ 0, attrs, + uid, opPkg, reason, mStatus); + } + + /** Debug information about vibrations. */ + public static final class DebugInfo { + private final long mStartTimeDebug; + private final long mEndTimeDebug; + private final VibrationEffect mEffect; + private final VibrationEffect mOriginalEffect; + private final float mScale; + private final VibrationAttributes mAttrs; + private final int mUid; + private final String mOpPkg; + private final String mReason; + private final Status mStatus; + + public DebugInfo(long startTimeDebug, long endTimeDebug, VibrationEffect effect, + VibrationEffect originalEffect, float scale, VibrationAttributes attrs, + int uid, String opPkg, String reason, Status status) { + mStartTimeDebug = startTimeDebug; + mEndTimeDebug = endTimeDebug; + mEffect = effect; + mOriginalEffect = originalEffect; + mScale = scale; + mAttrs = attrs; + mUid = uid; + mOpPkg = opPkg; + mReason = reason; + mStatus = status; + } + + @Override + public String toString() { + return new StringBuilder() + .append("startTime: ") + .append(DEBUG_DATE_FORMAT.format(new Date(mStartTimeDebug))) + .append(", endTime: ") + .append(mEndTimeDebug == 0 ? null + : DEBUG_DATE_FORMAT.format(new Date(mEndTimeDebug))) + .append(", status: ") + .append(mStatus.name().toLowerCase()) + .append(", effect: ") + .append(mEffect) + .append(", originalEffect: ") + .append(mOriginalEffect) + .append(", scale: ") + .append(String.format("%.2f", mScale)) + .append(", attrs: ") + .append(mAttrs) + .append(", uid: ") + .append(mUid) + .append(", opPkg: ") + .append(mOpPkg) + .append(", reason: ") + .append(mReason) + .toString(); + } + + /** Write this info into given {@code fieldId} on {@link ProtoOutputStream}. */ + public void dumpProto(ProtoOutputStream proto, long fieldId) { + final long token = proto.start(fieldId); + proto.write(VibrationProto.START_TIME, mStartTimeDebug); + proto.write(VibrationProto.END_TIME, mEndTimeDebug); + proto.write(VibrationProto.STATUS, mStatus.ordinal()); + + final long attrsToken = proto.start(VibrationProto.ATTRIBUTES); + proto.write(VibrationAttributesProto.USAGE, mAttrs.getUsage()); + proto.write(VibrationAttributesProto.AUDIO_USAGE, mAttrs.getAudioUsage()); + proto.write(VibrationAttributesProto.FLAGS, mAttrs.getFlags()); + proto.end(attrsToken); + + if (mEffect != null) { + dumpEffect(proto, VibrationProto.EFFECT, mEffect); + } + if (mOriginalEffect != null) { + dumpEffect(proto, VibrationProto.ORIGINAL_EFFECT, mOriginalEffect); + } + + proto.end(token); + } + + private void dumpEffect(ProtoOutputStream proto, long fieldId, VibrationEffect effect) { + final long token = proto.start(fieldId); + if (effect instanceof VibrationEffect.OneShot) { + dumpEffect(proto, VibrationEffectProto.ONESHOT, (VibrationEffect.OneShot) effect); + } else if (effect instanceof VibrationEffect.Waveform) { + dumpEffect(proto, VibrationEffectProto.WAVEFORM, (VibrationEffect.Waveform) effect); + } else if (effect instanceof VibrationEffect.Prebaked) { + dumpEffect(proto, VibrationEffectProto.PREBAKED, (VibrationEffect.Prebaked) effect); + } else if (effect instanceof VibrationEffect.Composed) { + dumpEffect(proto, VibrationEffectProto.COMPOSED, (VibrationEffect.Composed) effect); + } + proto.end(token); + } + + private void dumpEffect(ProtoOutputStream proto, long fieldId, + VibrationEffect.OneShot effect) { + final long token = proto.start(fieldId); + proto.write(OneShotProto.DURATION, (int) effect.getDuration()); + proto.write(OneShotProto.AMPLITUDE, effect.getAmplitude()); + proto.end(token); + } + + private void dumpEffect(ProtoOutputStream proto, long fieldId, + VibrationEffect.Waveform effect) { + final long token = proto.start(fieldId); + for (long timing : effect.getTimings()) { + proto.write(WaveformProto.TIMINGS, (int) timing); + } + for (int amplitude : effect.getAmplitudes()) { + proto.write(WaveformProto.AMPLITUDES, amplitude); + } + proto.write(WaveformProto.REPEAT, effect.getRepeatIndex() >= 0); + proto.end(token); + } + + private void dumpEffect(ProtoOutputStream proto, long fieldId, + VibrationEffect.Prebaked effect) { + final long token = proto.start(fieldId); + proto.write(PrebakedProto.EFFECT_ID, effect.getId()); + proto.write(PrebakedProto.EFFECT_STRENGTH, effect.getEffectStrength()); + proto.write(PrebakedProto.FALLBACK, effect.shouldFallback()); + proto.end(token); + } + + private void dumpEffect(ProtoOutputStream proto, long fieldId, + VibrationEffect.Composed effect) { + final long token = proto.start(fieldId); + for (VibrationEffect.Composition.PrimitiveEffect primitive : + effect.getPrimitiveEffects()) { + proto.write(ComposedProto.EFFECT_IDS, primitive.id); + proto.write(ComposedProto.EFFECT_SCALES, primitive.scale); + proto.write(ComposedProto.DELAYS, primitive.delay); + } + proto.end(token); + } + } +} diff --git a/services/core/java/com/android/server/vibrator/VibrationScaler.java b/services/core/java/com/android/server/vibrator/VibrationScaler.java index 42a0a706a1c7..5f7e47d6ca29 100644 --- a/services/core/java/com/android/server/vibrator/VibrationScaler.java +++ b/services/core/java/com/android/server/vibrator/VibrationScaler.java @@ -31,7 +31,6 @@ public final class VibrationScaler { // Scale levels. Each level, except MUTE, is defined as the delta between the current setting // and the default intensity for that type of vibration (i.e. current - default). - private static final int SCALE_MUTE = IExternalVibratorService.SCALE_MUTE; // -100 private static final int SCALE_VERY_LOW = IExternalVibratorService.SCALE_VERY_LOW; // -2 private static final int SCALE_LOW = IExternalVibratorService.SCALE_LOW; // -1 private static final int SCALE_NONE = IExternalVibratorService.SCALE_NONE; // 0 diff --git a/services/core/java/com/android/server/vibrator/VibrationSettings.java b/services/core/java/com/android/server/vibrator/VibrationSettings.java index 06a1f599f491..6a5d1c4173c9 100644 --- a/services/core/java/com/android/server/vibrator/VibrationSettings.java +++ b/services/core/java/com/android/server/vibrator/VibrationSettings.java @@ -17,14 +17,17 @@ package com.android.server.vibrator; import android.content.Context; +import android.content.res.Resources; import android.database.ContentObserver; import android.media.AudioManager; import android.net.Uri; import android.os.Handler; import android.os.UserHandle; import android.os.VibrationAttributes; +import android.os.VibrationEffect; import android.os.Vibrator; import android.provider.Settings; +import android.util.SparseArray; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; @@ -37,6 +40,8 @@ import java.util.List; public final class VibrationSettings { private static final String TAG = "VibrationSettings"; + private static final long[] DOUBLE_CLICK_EFFECT_FALLBACK_TIMINGS = {0, 30, 100, 30}; + /** Listener for changes on vibration settings. */ public interface OnVibratorSettingsChanged { /** Callback triggered when any of the vibrator settings change. */ @@ -51,6 +56,7 @@ public final class VibrationSettings { @GuardedBy("mLock") private final List<OnVibratorSettingsChanged> mListeners = new ArrayList<>(); + private final SparseArray<VibrationEffect> mFallbackEffects; @GuardedBy("mLock") private boolean mVibrateInputDevices; @@ -84,6 +90,23 @@ public final class VibrationSettings { registerSettingsObserver( Settings.System.getUriFor(Settings.System.RING_VIBRATION_INTENSITY)); + VibrationEffect clickEffect = createEffectFromResource( + com.android.internal.R.array.config_virtualKeyVibePattern); + VibrationEffect doubleClickEffect = VibrationEffect.createWaveform( + DOUBLE_CLICK_EFFECT_FALLBACK_TIMINGS, -1 /*repeatIndex*/); + VibrationEffect heavyClickEffect = createEffectFromResource( + com.android.internal.R.array.config_longPressVibePattern); + VibrationEffect tickEffect = createEffectFromResource( + com.android.internal.R.array.config_clockTickVibePattern); + + mFallbackEffects = new SparseArray<>(); + mFallbackEffects.put(VibrationEffect.EFFECT_CLICK, clickEffect); + mFallbackEffects.put(VibrationEffect.EFFECT_DOUBLE_CLICK, doubleClickEffect); + mFallbackEffects.put(VibrationEffect.EFFECT_TICK, tickEffect); + mFallbackEffects.put(VibrationEffect.EFFECT_HEAVY_CLICK, heavyClickEffect); + mFallbackEffects.put(VibrationEffect.EFFECT_TEXTURE_TICK, + VibrationEffect.get(VibrationEffect.EFFECT_TICK, false)); + // Update with current values from settings. updateSettings(); } @@ -150,6 +173,17 @@ public final class VibrationSettings { } /** + * Return a {@link VibrationEffect} that should be played if the device do not support given + * {@code effectId}. + * + * @param effectId one of VibrationEffect.EFFECT_* + * @return The effect to be played as a fallback + */ + public VibrationEffect getFallbackEffect(int effectId) { + return mFallbackEffects.get(effectId); + } + + /** * Return {@code true} if the device should vibrate for ringtones. * * <p>This checks the current {@link AudioManager#getRingerModeInternal()} against user settings @@ -270,6 +304,33 @@ public final class VibrationSettings { UserHandle.USER_ALL); } + private VibrationEffect createEffectFromResource(int resId) { + long[] timings = getLongIntArray(mContext.getResources(), resId); + return createEffectFromTimings(timings); + } + + private static VibrationEffect createEffectFromTimings(long[] timings) { + if (timings == null || timings.length == 0) { + return null; + } else if (timings.length == 1) { + return VibrationEffect.createOneShot(timings[0], VibrationEffect.DEFAULT_AMPLITUDE); + } else { + return VibrationEffect.createWaveform(timings, -1); + } + } + + private static long[] getLongIntArray(Resources r, int resid) { + int[] ar = r.getIntArray(resid); + if (ar == null) { + return null; + } + long[] out = new long[ar.length]; + for (int i = 0; i < ar.length; i++) { + out[i] = ar[i]; + } + return out; + } + /** Implementation of {@link ContentObserver} to be registered to a setting {@link Uri}. */ private final class SettingsObserver extends ContentObserver { SettingsObserver(Handler handler) { diff --git a/services/core/java/com/android/server/vibrator/VibratorController.java b/services/core/java/com/android/server/vibrator/VibratorController.java new file mode 100644 index 000000000000..f76c1a1b2b9d --- /dev/null +++ b/services/core/java/com/android/server/vibrator/VibratorController.java @@ -0,0 +1,472 @@ +/* + * 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.server.vibrator; + +import android.annotation.Nullable; +import android.hardware.vibrator.IVibrator; +import android.os.Binder; +import android.os.IVibratorStateListener; +import android.os.RemoteCallbackList; +import android.os.RemoteException; +import android.os.VibrationEffect; +import android.os.Vibrator; +import android.util.Slog; + +import com.android.internal.annotations.GuardedBy; +import com.android.internal.annotations.VisibleForTesting; + +import libcore.util.NativeAllocationRegistry; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +/** Controls a single vibrator. */ +// TODO(b/159207608): Make this package-private once vibrator services are moved to this package +public final class VibratorController { + private static final String TAG = "VibratorController"; + + private final Object mLock = new Object(); + private final NativeWrapper mNativeWrapper; + private final int mVibratorId; + private final long mCapabilities; + @Nullable + private final Set<Integer> mSupportedEffects; + @Nullable + private final Set<Integer> mSupportedPrimitives; + + @GuardedBy("mLock") + private final RemoteCallbackList<IVibratorStateListener> mVibratorStateListeners = + new RemoteCallbackList<>(); + @GuardedBy("mLock") + private boolean mIsVibrating; + @GuardedBy("mLock") + private boolean mIsUnderExternalControl; + + /** Listener for vibration completion callbacks from native. */ + public interface OnVibrationCompleteListener { + + /** Callback triggered when vibration is complete. */ + void onComplete(int vibratorId, long vibrationId); + } + + /** + * Initializes the native part of this controller, creating a global reference to given + * {@link OnVibrationCompleteListener} and returns a newly allocated native pointer. This + * wrapper is responsible for deleting this pointer by calling the method pointed + * by {@link #vibratorGetFinalizer()}. + * + * <p><b>Note:</b> Make sure the given implementation of {@link OnVibrationCompleteListener} + * do not hold any strong reference to the instance responsible for deleting the returned + * pointer, to avoid creating a cyclic GC root reference. + */ + static native long vibratorInit(int vibratorId, OnVibrationCompleteListener listener); + + /** + * Returns pointer to native function responsible for cleaning up the native pointer allocated + * and returned by {@link #vibratorInit(int, OnVibrationCompleteListener)}. + */ + static native long vibratorGetFinalizer(); + + static native boolean vibratorIsAvailable(long nativePtr); + + static native void vibratorOn(long nativePtr, long milliseconds, long vibrationId); + + static native void vibratorOff(long nativePtr); + + static native void vibratorSetAmplitude(long nativePtr, int amplitude); + + static native int[] vibratorGetSupportedEffects(long nativePtr); + + static native int[] vibratorGetSupportedPrimitives(long nativePtr); + + static native long vibratorPerformEffect( + long nativePtr, long effect, long strength, long vibrationId); + + static native void vibratorPerformComposedEffect(long nativePtr, + VibrationEffect.Composition.PrimitiveEffect[] effect, long vibrationId); + + static native void vibratorSetExternalControl(long nativePtr, boolean enabled); + + static native long vibratorGetCapabilities(long nativePtr); + + static native void vibratorAlwaysOnEnable(long nativePtr, long id, long effect, long strength); + + static native void vibratorAlwaysOnDisable(long nativePtr, long id); + + public VibratorController(int vibratorId, OnVibrationCompleteListener listener) { + this(vibratorId, listener, new NativeWrapper()); + } + + @VisibleForTesting + public VibratorController(int vibratorId, OnVibrationCompleteListener listener, + NativeWrapper nativeWrapper) { + mVibratorId = vibratorId; + mNativeWrapper = nativeWrapper; + + nativeWrapper.init(vibratorId, listener); + mCapabilities = nativeWrapper.getCapabilities(); + mSupportedEffects = asSet(nativeWrapper.getSupportedEffects()); + mSupportedPrimitives = asSet(nativeWrapper.getSupportedPrimitives()); + } + + /** Register state listener for this vibrator. */ + public boolean registerVibratorStateListener(IVibratorStateListener listener) { + synchronized (mLock) { + final long token = Binder.clearCallingIdentity(); + try { + if (!mVibratorStateListeners.register(listener)) { + return false; + } + // Notify its callback after new client registered. + notifyStateListenerLocked(listener); + return true; + } finally { + Binder.restoreCallingIdentity(token); + } + } + } + + /** Remove registered state listener for this vibrator. */ + public boolean unregisterVibratorStateListener(IVibratorStateListener listener) { + synchronized (mLock) { + final long token = Binder.clearCallingIdentity(); + try { + return mVibratorStateListeners.unregister(listener); + } finally { + Binder.restoreCallingIdentity(token); + } + } + } + + /** Return the id of the vibrator controlled by this instance. */ + public int getVibratorId() { + return mVibratorId; + } + + /** + * Return {@code true} is this vibrator is currently vibrating, false otherwise. + * + * <p>This state is controlled by calls to {@link #on} and {@link #off} methods, and is + * automatically notified to any registered {@link IVibratorStateListener} on change. + */ + public boolean isVibrating() { + synchronized (mLock) { + return mIsVibrating; + } + } + + /** Return {@code true} if this vibrator is under external control, false otherwise. */ + public boolean isUnderExternalControl() { + synchronized (mLock) { + return mIsUnderExternalControl; + } + } + + /** + * Check against this vibrator capabilities. + * + * @param capability one of IVibrator.CAP_* + * @return true if this vibrator has this capability, false otherwise + */ + public boolean hasCapability(long capability) { + return (mCapabilities & capability) == capability; + } + + /** + * Check against this vibrator supported effects. + * + * @param effectIds list of effects, one of VibrationEffect.EFFECT_* + * @return one entry per requested effectId, with one of Vibrator.VIBRATION_EFFECT_SUPPORT_* + */ + public int[] areEffectsSupported(int[] effectIds) { + int[] supported = new int[effectIds.length]; + if (mSupportedEffects == null) { + Arrays.fill(supported, Vibrator.VIBRATION_EFFECT_SUPPORT_UNKNOWN); + } else { + for (int i = 0; i < effectIds.length; i++) { + supported[i] = mSupportedEffects.contains(effectIds[i]) + ? Vibrator.VIBRATION_EFFECT_SUPPORT_YES + : Vibrator.VIBRATION_EFFECT_SUPPORT_NO; + } + } + return supported; + } + + /** + * Check against this vibrator supported primitives. + * + * @param primitiveIds list of primitives, one of VibrationEffect.Composition.EFFECT_* + * @return one entry per requested primitiveId, with true if it is supported + */ + public boolean[] arePrimitivesSupported(int[] primitiveIds) { + boolean[] supported = new boolean[primitiveIds.length]; + if (mSupportedPrimitives != null && hasCapability(IVibrator.CAP_COMPOSE_EFFECTS)) { + for (int i = 0; i < primitiveIds.length; i++) { + supported[i] = mSupportedPrimitives.contains(primitiveIds[i]); + } + } + return supported; + } + + /** Return {@code true} if the underlying vibrator is currently available, false otherwise. */ + public boolean isAvailable() { + return mNativeWrapper.isAvailable(); + } + + /** + * Set the vibrator control to be external or not, based on given flag. + * + * <p>This will affect the state of {@link #isUnderExternalControl()}. + */ + public void setExternalControl(boolean externalControl) { + if (!hasCapability(IVibrator.CAP_EXTERNAL_CONTROL)) { + return; + } + synchronized (mLock) { + mIsUnderExternalControl = externalControl; + mNativeWrapper.setExternalControl(externalControl); + } + } + + /** + * Update the predefined vibration effect saved with given id. This will remove the saved effect + * if given {@code effect} is {@code null}. + */ + public void updateAlwaysOn(int id, @Nullable VibrationEffect.Prebaked effect) { + if (!hasCapability(IVibrator.CAP_ALWAYS_ON_CONTROL)) { + return; + } + synchronized (mLock) { + if (effect == null) { + mNativeWrapper.alwaysOnDisable(id); + } else { + mNativeWrapper.alwaysOnEnable(id, effect.getId(), effect.getEffectStrength()); + } + } + } + + /** Set the vibration amplitude. This will NOT affect the state of {@link #isVibrating()}. */ + public void setAmplitude(int amplitude) { + synchronized (mLock) { + if (hasCapability(IVibrator.CAP_AMPLITUDE_CONTROL)) { + mNativeWrapper.setAmplitude(amplitude); + } + } + } + + /** + * Turn on the vibrator for {@code milliseconds} time, using {@code vibrationId} or completion + * callback to {@link OnVibrationCompleteListener}. + * + * <p>This will affect the state of {@link #isVibrating()}. + */ + public void on(long milliseconds, long vibrationId) { + synchronized (mLock) { + mNativeWrapper.on(milliseconds, vibrationId); + notifyVibratorOnLocked(); + } + } + + /** + * Plays predefined vibration effect, using {@code vibrationId} or completion callback to + * {@link OnVibrationCompleteListener}. + * + * <p>This will affect the state of {@link #isVibrating()}. + */ + public long on(VibrationEffect.Prebaked effect, long vibrationId) { + synchronized (mLock) { + long duration = mNativeWrapper.perform(effect.getId(), effect.getEffectStrength(), + vibrationId); + if (duration > 0) { + notifyVibratorOnLocked(); + } + return duration; + } + } + + /** + * Plays composited vibration effect, using {@code vibrationId} or completion callback to + * {@link OnVibrationCompleteListener}. + * + * <p>This will affect the state of {@link #isVibrating()}. + */ + public void on(VibrationEffect.Composed effect, long vibrationId) { + if (!hasCapability(IVibrator.CAP_COMPOSE_EFFECTS)) { + return; + } + synchronized (mLock) { + mNativeWrapper.compose(effect.getPrimitiveEffects().toArray( + new VibrationEffect.Composition.PrimitiveEffect[0]), vibrationId); + notifyVibratorOnLocked(); + } + } + + /** Turns off the vibrator.This will affect the state of {@link #isVibrating()}. */ + public void off() { + synchronized (mLock) { + mNativeWrapper.off(); + notifyVibratorOffLocked(); + } + } + + @Override + public String toString() { + return "VibratorController{" + + "mVibratorId=" + mVibratorId + + ", mCapabilities=" + mCapabilities + + ", mSupportedEffects=" + mSupportedEffects + + ", mSupportedPrimitives=" + mSupportedPrimitives + + ", mIsVibrating=" + mIsVibrating + + ", mIsUnderExternalControl=" + mIsUnderExternalControl + + ", mVibratorStateListeners count=" + + mVibratorStateListeners.getRegisteredCallbackCount() + + '}'; + } + + @GuardedBy("mLock") + private void notifyVibratorOnLocked() { + if (!mIsVibrating) { + mIsVibrating = true; + notifyStateListenersLocked(); + } + } + + @GuardedBy("mLock") + private void notifyVibratorOffLocked() { + if (mIsVibrating) { + mIsVibrating = false; + notifyStateListenersLocked(); + } + } + + @GuardedBy("mLock") + private void notifyStateListenersLocked() { + final int length = mVibratorStateListeners.beginBroadcast(); + try { + for (int i = 0; i < length; i++) { + notifyStateListenerLocked(mVibratorStateListeners.getBroadcastItem(i)); + } + } finally { + mVibratorStateListeners.finishBroadcast(); + } + } + + @GuardedBy("mLock") + private void notifyStateListenerLocked(IVibratorStateListener listener) { + try { + listener.onVibrating(mIsVibrating); + } catch (RemoteException | RuntimeException e) { + Slog.e(TAG, "Vibrator state listener failed to call", e); + } + } + + @Nullable + private static Set<Integer> asSet(int[] values) { + if (values == null) { + return null; + } + HashSet<Integer> set = new HashSet<>(); + for (int value : values) { + set.add(value); + } + return set; + } + + /** Wrapper around the static-native methods of {@link VibratorController} for tests. */ + @VisibleForTesting + public static class NativeWrapper { + + private long mNativePtr = 0; + + /** Initializes native controller and allocation registry to destroy native instances. */ + public void init(int vibratorId, OnVibrationCompleteListener listener) { + mNativePtr = VibratorController.vibratorInit(vibratorId, listener); + long finalizerPtr = VibratorController.vibratorGetFinalizer(); + + if (finalizerPtr != 0) { + NativeAllocationRegistry registry = + NativeAllocationRegistry.createMalloced( + VibratorController.class.getClassLoader(), finalizerPtr); + registry.registerNativeAllocation(this, mNativePtr); + } + } + + /** Check if the vibrator is currently available. */ + public boolean isAvailable() { + return VibratorController.vibratorIsAvailable(mNativePtr); + } + + /** Turns vibrator on for given time. */ + public void on(long milliseconds, long vibrationId) { + VibratorController.vibratorOn(mNativePtr, milliseconds, vibrationId); + } + + /** Turns vibrator off. */ + public void off() { + VibratorController.vibratorOff(mNativePtr); + } + + /** Sets the amplitude for the vibrator to run. */ + public void setAmplitude(int amplitude) { + VibratorController.vibratorSetAmplitude(mNativePtr, amplitude); + } + + /** Returns all predefined effects supported by the device vibrator. */ + public int[] getSupportedEffects() { + return VibratorController.vibratorGetSupportedEffects(mNativePtr); + } + + /** Returns all compose primitives supported by the device vibrator. */ + public int[] getSupportedPrimitives() { + return VibratorController.vibratorGetSupportedPrimitives(mNativePtr); + } + + /** Turns vibrator on to perform one of the supported effects. */ + public long perform(long effect, long strength, long vibrationId) { + return VibratorController.vibratorPerformEffect( + mNativePtr, effect, strength, vibrationId); + } + + /** Turns vibrator on to perform one of the supported composed effects. */ + public void compose( + VibrationEffect.Composition.PrimitiveEffect[] effect, long vibrationId) { + VibratorController.vibratorPerformComposedEffect(mNativePtr, effect, + vibrationId); + } + + /** Enabled the device vibrator to be controlled by another service. */ + public void setExternalControl(boolean enabled) { + VibratorController.vibratorSetExternalControl(mNativePtr, enabled); + } + + /** Returns all capabilities of the device vibrator. */ + public long getCapabilities() { + return VibratorController.vibratorGetCapabilities(mNativePtr); + } + + /** Enable always-on vibration with given id and effect. */ + public void alwaysOnEnable(long id, long effect, long strength) { + VibratorController.vibratorAlwaysOnEnable(mNativePtr, id, effect, strength); + } + + /** Disable always-on vibration for given id. */ + public void alwaysOnDisable(long id) { + VibratorController.vibratorAlwaysOnDisable(mNativePtr, id); + } + } +} diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index c2016decdbe9..913c3e580adf 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -7584,6 +7584,10 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A return (config.uiMode & UI_MODE_TYPE_MASK) == UI_MODE_TYPE_VR_HEADSET; } + String getProcessName() { + return info.applicationInfo.processName; + } + int getUid() { return info.applicationInfo.uid; } @@ -7596,6 +7600,14 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A return app != null ? app.getPid() : 0; } + int getLaunchedFromPid() { + return launchedFromPid; + } + + int getLaunchedFromUid() { + return launchedFromUid; + } + /** * Determines whether this ActivityRecord can turn the screen on. It checks whether the flag * {@link ActivityRecord#getTurnScreenOnFlag} is set and checks whether the ActivityRecord diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java index acee7b26725e..90cd682d6a8f 100644 --- a/services/core/java/com/android/server/wm/ActivityStarter.java +++ b/services/core/java/com/android/server/wm/ActivityStarter.java @@ -57,9 +57,6 @@ import static android.view.WindowManager.TRANSIT_OPEN; import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_CONFIGURATION; import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_TASKS; -import static com.android.server.wm.ActivityTaskSupervisor.DEFER_RESUME; -import static com.android.server.wm.ActivityTaskSupervisor.ON_TOP; -import static com.android.server.wm.ActivityTaskSupervisor.PRESERVE_WINDOWS; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ACTIVITY_STARTS; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RESULTS; @@ -71,6 +68,9 @@ import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_USER_ import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM; import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.server.wm.ActivityTaskManagerService.ANIMATE; +import static com.android.server.wm.ActivityTaskSupervisor.DEFER_RESUME; +import static com.android.server.wm.ActivityTaskSupervisor.ON_TOP; +import static com.android.server.wm.ActivityTaskSupervisor.PRESERVE_WINDOWS; import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.PHASE_BOUNDS; import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.PHASE_DISPLAY; import static com.android.server.wm.Task.ActivityState.RESUMED; @@ -1870,7 +1870,7 @@ class ActivityStarter { } mSupervisor.getLaunchParamsController().calculate(targetTask, r.info.windowLayout, r, - sourceRecord, mOptions, PHASE_BOUNDS, mLaunchParams); + sourceRecord, mOptions, PHASE_BOUNDS, mLaunchParams, mRequest); mPreferredTaskDisplayArea = mLaunchParams.hasPreferredTaskDisplayArea() ? mLaunchParams.mPreferredTaskDisplayArea : mRootWindowContainer.getDefaultTaskDisplayArea(); @@ -2254,7 +2254,7 @@ class ActivityStarter { // Preferred display id is the only state we need for now and it could be updated again // after we located a reusable task (which might be resided in another display). mSupervisor.getLaunchParamsController().calculate(inTask, r.info.windowLayout, r, - sourceRecord, options, PHASE_DISPLAY, mLaunchParams); + sourceRecord, options, PHASE_DISPLAY, mLaunchParams, mRequest); mPreferredTaskDisplayArea = mLaunchParams.hasPreferredTaskDisplayArea() ? mLaunchParams.mPreferredTaskDisplayArea : mRootWindowContainer.getDefaultTaskDisplayArea(); diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java index 27faf13e2999..e12dc2bd56a8 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java @@ -1056,7 +1056,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } @Override - public void onUserUnlocking(@NonNull TargetUser user) { + public void onUserUnlocked(@NonNull TargetUser user) { synchronized (mService.getGlobalLock()) { mService.mTaskSupervisor.onUserUnlocked(user.getUserIdentifier()); } diff --git a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java index 37f04cec071b..d0c26af82d99 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java +++ b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java @@ -186,7 +186,7 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { private static final int RESTART_ACTIVITY_PROCESS_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 13; private static final int REPORT_MULTI_WINDOW_MODE_CHANGED_MSG = FIRST_SUPERVISOR_STACK_MSG + 14; private static final int REPORT_PIP_MODE_CHANGED_MSG = FIRST_SUPERVISOR_STACK_MSG + 15; - private static final int REPORT_HOME_CHANGED_MSG = FIRST_SUPERVISOR_STACK_MSG + 16; + private static final int START_HOME_MSG = FIRST_SUPERVISOR_STACK_MSG + 16; private static final int TOP_RESUMED_STATE_LOSS_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 17; // Used to indicate that windows of activities should be preserved during the resize. @@ -446,6 +446,9 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { // unlocked. mPersisterQueue.startPersisting(); mLaunchParamsPersister.onUnlockUser(userId); + + // Need to launch home again for those displays that do not have encryption aware home app. + scheduleStartHome("userUnlocked"); } public ActivityMetricsLogger getActivityMetricsLogger() { @@ -956,13 +959,17 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { void updateHomeProcess(WindowProcessController app) { if (app != null && mService.mHomeProcess != app) { - if (!mHandler.hasMessages(REPORT_HOME_CHANGED_MSG)) { - mHandler.sendEmptyMessage(REPORT_HOME_CHANGED_MSG); - } + scheduleStartHome("homeChanged"); mService.mHomeProcess = app; } } + private void scheduleStartHome(String reason) { + if (!mHandler.hasMessages(START_HOME_MSG)) { + mHandler.obtainMessage(START_HOME_MSG, reason).sendToTarget(); + } + } + private void logIfTransactionTooLarge(Intent intent, Bundle icicle) { int extrasSize = 0; if (intent != null) { @@ -1315,6 +1322,7 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { if (mRootWindowContainer.allResumedActivitiesIdle()) { if (r != null) { mService.scheduleAppGcsLocked(); + mRecentTasks.onActivityIdle(r); } if (mLaunchingActivityWakeLock.isHeld()) { @@ -2472,11 +2480,11 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { handleLaunchTaskBehindCompleteLocked(r); } } break; - case REPORT_HOME_CHANGED_MSG: { - mHandler.removeMessages(REPORT_HOME_CHANGED_MSG); + case START_HOME_MSG: { + mHandler.removeMessages(START_HOME_MSG); // Start home activities on displays with no activities. - mRootWindowContainer.startHomeOnEmptyDisplays("homeChanged"); + mRootWindowContainer.startHomeOnEmptyDisplays((String) msg.obj); } break; case TOP_RESUMED_STATE_LOSS_TIMEOUT_MSG: { final ActivityRecord r = (ActivityRecord) msg.obj; diff --git a/services/core/java/com/android/server/wm/DisplayArea.java b/services/core/java/com/android/server/wm/DisplayArea.java index 8ad2958f9a76..48e030050b07 100644 --- a/services/core/java/com/android/server/wm/DisplayArea.java +++ b/services/core/java/com/android/server/wm/DisplayArea.java @@ -382,6 +382,13 @@ public class DisplayArea<T extends WindowContainer> extends WindowContainer<T> { @Nullable @Override + <R> R getItemFromDisplayAreas(Function<DisplayArea, R> callback) { + final R item = super.getItemFromDisplayAreas(callback); + return item != null ? item : callback.apply(this); + } + + @Nullable + @Override <R> R getItemFromTaskDisplayAreas(Function<TaskDisplayArea, R> callback, boolean traverseTopToBottom) { // Only DisplayArea of Type.ANY may contain TaskDisplayArea as children. diff --git a/services/core/java/com/android/server/wm/DisplayAreaOrganizerController.java b/services/core/java/com/android/server/wm/DisplayAreaOrganizerController.java index 43b9a218d072..c475da354dda 100644 --- a/services/core/java/com/android/server/wm/DisplayAreaOrganizerController.java +++ b/services/core/java/com/android/server/wm/DisplayAreaOrganizerController.java @@ -16,7 +16,10 @@ package com.android.server.wm; +import static android.window.DisplayAreaOrganizer.FEATURE_RUNTIME_TASK_CONTAINER_FIRST; + import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_WINDOW_ORGANIZER; +import static com.android.server.wm.DisplayArea.Type.ANY; import android.content.pm.ParceledListSlice; import android.os.Binder; @@ -26,6 +29,7 @@ import android.view.SurfaceControl; import android.window.DisplayAreaAppearedInfo; import android.window.IDisplayAreaOrganizer; import android.window.IDisplayAreaOrganizerController; +import android.window.WindowContainerToken; import com.android.internal.protolog.common.ProtoLog; @@ -36,6 +40,12 @@ import java.util.List; public class DisplayAreaOrganizerController extends IDisplayAreaOrganizerController.Stub { private static final String TAG = "DisplayAreaOrganizerController"; + /** + * Next available feature id for a runtime task display area. + * @see #createTaskDisplayArea(IDisplayAreaOrganizer organizer, int, int, String) + */ + private int mNextTaskDisplayAreaFeatureId = FEATURE_RUNTIME_TASK_CONTAINER_FIRST; + final ActivityTaskManagerService mService; private final WindowManagerGlobalLock mGlobalLock; private final HashMap<Integer, IDisplayAreaOrganizer> mOrganizersByFeatureIds = new HashMap(); @@ -92,10 +102,8 @@ public class DisplayAreaOrganizerController extends IDisplayAreaOrganizerControl final List<DisplayAreaAppearedInfo> displayAreaInfos = new ArrayList<>(); mService.mRootWindowContainer.forAllDisplayAreas((da) -> { if (da.mFeatureId != feature) return; - da.setOrganizer(organizer, true /* skipDisplayAreaAppeared */); - displayAreaInfos.add(new DisplayAreaAppearedInfo(da.getDisplayAreaInfo(), - new SurfaceControl(da.getSurfaceControl(), - "DisplayAreaOrganizerController.registerOrganizer"))); + displayAreaInfos.add(organizeDisplayArea(organizer, da, + "DisplayAreaOrganizerController.registerOrganizer")); }); mOrganizersByFeatureIds.put(feature, organizer); @@ -124,6 +132,77 @@ public class DisplayAreaOrganizerController extends IDisplayAreaOrganizerControl } } + @Override + public DisplayAreaAppearedInfo createTaskDisplayArea(IDisplayAreaOrganizer organizer, + int displayId, int rootFeatureId, String name) { + enforceTaskPermission("createTaskDisplayArea()"); + final long uid = Binder.getCallingUid(); + final long origId = Binder.clearCallingIdentity(); + try { + synchronized (mGlobalLock) { + ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "Create TaskDisplayArea uid=%d", uid); + + final DisplayContent display = + mService.mRootWindowContainer.getDisplayContent(displayId); + if (display == null) { + throw new IllegalArgumentException("createTaskDisplayArea unknown displayId=" + + displayId); + } + + final DisplayArea root = display.getItemFromDisplayAreas(da -> + da.asRootDisplayArea() != null && da.mFeatureId == rootFeatureId + ? da + : null); + if (root == null) { + throw new IllegalArgumentException("Can't find RootDisplayArea with featureId=" + + rootFeatureId); + } + + final int taskDisplayAreaFeatureId = mNextTaskDisplayAreaFeatureId++; + final DeathRecipient dr = new DeathRecipient(organizer, taskDisplayAreaFeatureId); + try { + organizer.asBinder().linkToDeath(dr, 0); + } catch (RemoteException e) { + // Oh well... + } + + final TaskDisplayArea tda = createTaskDisplayArea(root.asRootDisplayArea(), name, + taskDisplayAreaFeatureId); + return organizeDisplayArea(organizer, tda, + "DisplayAreaOrganizerController.createTaskDisplayArea"); + } + } finally { + Binder.restoreCallingIdentity(origId); + } + } + + @Override + public void deleteTaskDisplayArea(WindowContainerToken token) { + enforceTaskPermission("deleteTaskDisplayArea()"); + final long uid = Binder.getCallingUid(); + final long origId = Binder.clearCallingIdentity(); + try { + synchronized (mGlobalLock) { + ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "Delete TaskDisplayArea uid=%d", uid); + + final WindowContainer wc = WindowContainer.fromBinder(token.asBinder()); + if (wc == null || wc.asTaskDisplayArea() == null) { + throw new IllegalArgumentException("Can't resolve TaskDisplayArea from token"); + } + final TaskDisplayArea taskDisplayArea = wc.asTaskDisplayArea(); + if (!taskDisplayArea.mCreatedByOrganizer) { + throw new IllegalArgumentException( + "Attempt to delete TaskDisplayArea not created by organizer " + + "TaskDisplayArea=" + taskDisplayArea); + } + + deleteTaskDisplayArea(taskDisplayArea); + } + } finally { + Binder.restoreCallingIdentity(origId); + } + } + void onDisplayAreaAppeared(IDisplayAreaOrganizer organizer, DisplayArea da) { ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "DisplayArea appeared name=%s", da.getName()); try { @@ -157,8 +236,71 @@ public class DisplayAreaOrganizerController extends IDisplayAreaOrganizerControl IBinder organizerBinder = organizer.asBinder(); mService.mRootWindowContainer.forAllDisplayAreas((da) -> { if (da.mOrganizer != null && da.mOrganizer.asBinder().equals(organizerBinder)) { - da.setOrganizer(null); + if (da.isTaskDisplayArea() && da.asTaskDisplayArea().mCreatedByOrganizer) { + // Delete the organizer created TDA when unregister. + deleteTaskDisplayArea(da.asTaskDisplayArea()); + } else { + da.setOrganizer(null); + } + } + }); + } + + private DisplayAreaAppearedInfo organizeDisplayArea(IDisplayAreaOrganizer organizer, + DisplayArea displayArea, String callsite) { + displayArea.setOrganizer(organizer, true /* skipDisplayAreaAppeared */); + return new DisplayAreaAppearedInfo(displayArea.getDisplayAreaInfo(), + new SurfaceControl(displayArea.getSurfaceControl(), callsite)); + } + + private TaskDisplayArea createTaskDisplayArea(RootDisplayArea root, String name, + int taskDisplayAreaFeatureId) { + final TaskDisplayArea taskDisplayArea = new TaskDisplayArea(root.mDisplayContent, + root.mWmService, name, taskDisplayAreaFeatureId, true /* createdByOrganizer */); + + // Find the top most DA that can contain Task (either a TDA or a DisplayAreaGroup). + final DisplayArea topTaskContainer = root.getItemFromDisplayAreas(da -> { + if (da.mType != ANY) { + return null; + } + + final RootDisplayArea rootDA = da.getRootDisplayArea(); + if (rootDA == root || rootDA == da) { + // Either it is the top TDA below the root or it is a DisplayAreaGroup. + return da; } + return null; }); + if (topTaskContainer == null) { + throw new IllegalStateException("Root must either contain TDA or DAG root=" + root); + } + + // Insert the TaskDisplayArea as the top Task container. + final WindowContainer parent = topTaskContainer.getParent(); + final int index = parent.mChildren.indexOf(topTaskContainer) + 1; + parent.addChild(taskDisplayArea, index); + + return taskDisplayArea; + } + + private void deleteTaskDisplayArea(TaskDisplayArea taskDisplayArea) { + taskDisplayArea.setOrganizer(null); + mService.mRootWindowContainer.mTaskSupervisor.beginDeferResume(); + + // TaskDisplayArea#remove() move the stacks to the default TaskDisplayArea. + Task lastReparentedStack; + try { + lastReparentedStack = taskDisplayArea.remove(); + } finally { + mService.mRootWindowContainer.mTaskSupervisor.endDeferResume(); + } + + taskDisplayArea.removeImmediately(); + + // Only update focus/visibility for the last one because there may be many stacks are + // reparented and the intermediate states are unnecessary. + if (lastReparentedStack != null) { + lastReparentedStack.postReparent(); + } } } diff --git a/services/core/java/com/android/server/wm/DisplayAreaPolicyBuilder.java b/services/core/java/com/android/server/wm/DisplayAreaPolicyBuilder.java index 80ec722bc274..6a420874b924 100644 --- a/services/core/java/com/android/server/wm/DisplayAreaPolicyBuilder.java +++ b/services/core/java/com/android/server/wm/DisplayAreaPolicyBuilder.java @@ -172,10 +172,16 @@ class DisplayAreaPolicyBuilder { throw new IllegalStateException("Root must be set for the display area policy."); } + final Set<Integer> rootIdSet = new ArraySet<>(); + rootIdSet.add(mRootHierarchyBuilder.mRoot.mFeatureId); boolean containsImeContainer = mRootHierarchyBuilder.mImeContainer != null; boolean containsDefaultTda = containsDefaultTaskDisplayArea(mRootHierarchyBuilder); for (int i = 0; i < mDisplayAreaGroupHierarchyBuilders.size(); i++) { HierarchyBuilder hierarchyBuilder = mDisplayAreaGroupHierarchyBuilders.get(i); + if (!rootIdSet.add(hierarchyBuilder.mRoot.mFeatureId)) { + throw new IllegalStateException("There should not be two RootDisplayAreas with id " + + hierarchyBuilder.mRoot.mFeatureId); + } if (hierarchyBuilder.mTaskDisplayAreas.isEmpty()) { throw new IllegalStateException( "DisplayAreaGroup must contain at least one TaskDisplayArea."); diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 4133ea2b2a7b..ccc85f834bc1 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -73,6 +73,8 @@ import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG; import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ERROR; import static android.view.WindowManager.LayoutParams.TYPE_TOAST; import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER; +import static android.view.WindowManager.DISPLAY_IME_POLICY_LOCAL; +import static android.view.WindowManager.DISPLAY_IME_POLICY_FALLBACK_DISPLAY; import static android.view.WindowManager.TRANSIT_OPEN; import static android.view.WindowManager.TRANSIT_TO_FRONT; import static android.window.DisplayAreaOrganizer.FEATURE_ROOT; @@ -91,7 +93,7 @@ import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_C import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT; import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; import static com.android.server.wm.DisplayContentProto.APP_TRANSITION; -import static com.android.server.wm.DisplayContentProto.CAN_SHOW_IME; +import static com.android.server.wm.DisplayContentProto.IME_POLICY; import static com.android.server.wm.DisplayContentProto.CLOSING_APPS; import static com.android.server.wm.DisplayContentProto.CURRENT_FOCUS; import static com.android.server.wm.DisplayContentProto.DISPLAY_FRAMES; @@ -203,6 +205,7 @@ import android.view.SurfaceControl.Transaction; import android.view.SurfaceSession; import android.view.WindowInsets; import android.view.WindowManager; +import android.view.WindowManager.DisplayImePolicy; import android.view.WindowManagerPolicyConstants.PointerEventListener; import com.android.internal.annotations.VisibleForTesting; @@ -2930,7 +2933,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp mInsetsStateController.getImeSourceProvider().dumpDebug(proto, IME_INSETS_SOURCE_PROVIDER, logLevel); } - proto.write(CAN_SHOW_IME, canShowIme()); + proto.write(IME_POLICY, getImePolicy()); proto.end(token); } @@ -3561,7 +3564,8 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp * @return {@link InsetsControlTarget} that can host IME. */ InsetsControlTarget getImeHostOrFallback(WindowState target) { - if (target != null && target.getDisplayContent().canShowIme()) { + if (target != null + && target.getDisplayContent().getImePolicy() == DISPLAY_IME_POLICY_LOCAL) { return target; } return getImeFallback(); @@ -3575,12 +3579,17 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp return statusBar != null ? statusBar : defaultDc.mRemoteInsetsControlTarget; } - boolean canShowIme() { + @DisplayImePolicy int getImePolicy() { if (!isTrusted()) { - return false; + return DISPLAY_IME_POLICY_FALLBACK_DISPLAY; + } + final int imePolicy = mWmService.mDisplayWindowSettings.getImePolicyLocked(this); + if (imePolicy == DISPLAY_IME_POLICY_FALLBACK_DISPLAY && forceDesktopMode()) { + // If the display has not explicitly requested for the IME to be hidden then it shall + // show the IME locally. + return DISPLAY_IME_POLICY_LOCAL; } - return mWmService.mDisplayWindowSettings.shouldShowImeLocked(this) - || forceDesktopMode(); + return imePolicy; } boolean forceDesktopMode() { diff --git a/services/core/java/com/android/server/wm/DisplayWindowSettings.java b/services/core/java/com/android/server/wm/DisplayWindowSettings.java index 472678cf8e37..5d4dbc8388c4 100644 --- a/services/core/java/com/android/server/wm/DisplayWindowSettings.java +++ b/services/core/java/com/android/server/wm/DisplayWindowSettings.java @@ -19,6 +19,8 @@ package com.android.server.wm; import static android.view.WindowManager.REMOVE_CONTENT_MODE_DESTROY; import static android.view.WindowManager.REMOVE_CONTENT_MODE_MOVE_TO_PRIMARY; import static android.view.WindowManager.REMOVE_CONTENT_MODE_UNDEFINED; +import static android.view.WindowManager.DISPLAY_IME_POLICY_LOCAL; +import static android.view.WindowManager.DISPLAY_IME_POLICY_FALLBACK_DISPLAY; import static com.android.server.wm.DisplayContent.FORCE_SCALING_MODE_AUTO; import static com.android.server.wm.DisplayContent.FORCE_SCALING_MODE_DISABLED; @@ -31,6 +33,7 @@ import android.view.Display; import android.view.DisplayInfo; import android.view.IWindowManager; import android.view.Surface; +import android.view.WindowManager.DisplayImePolicy; import com.android.server.policy.WindowManagerPolicy; import com.android.server.wm.DisplayContent.ForceScalingMode; @@ -212,22 +215,23 @@ class DisplayWindowSettings { mSettingsProvider.updateOverrideSettings(displayInfo, overrideSettings); } - boolean shouldShowImeLocked(DisplayContent dc) { + @DisplayImePolicy int getImePolicyLocked(DisplayContent dc) { if (dc.getDisplayId() == Display.DEFAULT_DISPLAY) { // Default display should show IME. - return true; + return DISPLAY_IME_POLICY_LOCAL; } final DisplayInfo displayInfo = dc.getDisplayInfo(); final SettingsProvider.SettingsEntry settings = mSettingsProvider.getSettings(displayInfo); - return settings.mShouldShowIme != null ? settings.mShouldShowIme : false; + return settings.mImePolicy != null ? settings.mImePolicy + : DISPLAY_IME_POLICY_FALLBACK_DISPLAY; } - void setShouldShowImeLocked(DisplayContent dc, boolean shouldShow) { + void setDisplayImePolicy(DisplayContent dc, @DisplayImePolicy int imePolicy) { final DisplayInfo displayInfo = dc.getDisplayInfo(); final SettingsProvider.SettingsEntry overrideSettings = mSettingsProvider.getOverrideSettings(displayInfo); - overrideSettings.mShouldShowIme = shouldShow; + overrideSettings.mImePolicy = imePolicy; mSettingsProvider.updateOverrideSettings(displayInfo, overrideSettings); } @@ -343,7 +347,7 @@ class DisplayWindowSettings { @Nullable Boolean mShouldShowSystemDecors; @Nullable - Boolean mShouldShowIme; + Integer mImePolicy; @Nullable Integer mFixedToUserRotation; @Nullable @@ -406,8 +410,8 @@ class DisplayWindowSettings { mShouldShowSystemDecors = other.mShouldShowSystemDecors; changed = true; } - if (other.mShouldShowIme != mShouldShowIme) { - mShouldShowIme = other.mShouldShowIme; + if (!Objects.equals(other.mImePolicy, mImePolicy)) { + mImePolicy = other.mImePolicy; changed = true; } if (!Objects.equals(other.mFixedToUserRotation, mFixedToUserRotation)) { @@ -481,9 +485,9 @@ class DisplayWindowSettings { mShouldShowSystemDecors = delta.mShouldShowSystemDecors; changed = true; } - if (delta.mShouldShowIme != null - && delta.mShouldShowIme != mShouldShowIme) { - mShouldShowIme = delta.mShouldShowIme; + if (delta.mImePolicy != null + && !Objects.equals(delta.mImePolicy, mImePolicy)) { + mImePolicy = delta.mImePolicy; changed = true; } if (delta.mFixedToUserRotation != null @@ -509,7 +513,7 @@ class DisplayWindowSettings { && mRemoveContentMode == REMOVE_CONTENT_MODE_UNDEFINED && mShouldShowWithInsecureKeyguard == null && mShouldShowSystemDecors == null - && mShouldShowIme == null + && mImePolicy == null && mFixedToUserRotation == null && mIgnoreOrientationRequest == null; } @@ -530,7 +534,7 @@ class DisplayWindowSettings { && Objects.equals(mShouldShowWithInsecureKeyguard, that.mShouldShowWithInsecureKeyguard) && Objects.equals(mShouldShowSystemDecors, that.mShouldShowSystemDecors) - && Objects.equals(mShouldShowIme, that.mShouldShowIme) + && Objects.equals(mImePolicy, that.mImePolicy) && Objects.equals(mFixedToUserRotation, that.mFixedToUserRotation) && Objects.equals(mIgnoreOrientationRequest, that.mIgnoreOrientationRequest); @@ -540,7 +544,7 @@ class DisplayWindowSettings { public int hashCode() { return Objects.hash(mWindowingMode, mUserRotationMode, mUserRotation, mForcedWidth, mForcedHeight, mForcedDensity, mForcedScalingMode, mRemoveContentMode, - mShouldShowWithInsecureKeyguard, mShouldShowSystemDecors, mShouldShowIme, + mShouldShowWithInsecureKeyguard, mShouldShowSystemDecors, mImePolicy, mFixedToUserRotation, mIgnoreOrientationRequest); } @@ -557,7 +561,7 @@ class DisplayWindowSettings { + ", mRemoveContentMode=" + mRemoveContentMode + ", mShouldShowWithInsecureKeyguard=" + mShouldShowWithInsecureKeyguard + ", mShouldShowSystemDecors=" + mShouldShowSystemDecors - + ", mShouldShowIme=" + mShouldShowIme + + ", mShouldShowIme=" + mImePolicy + ", mFixedToUserRotation=" + mFixedToUserRotation + ", mIgnoreOrientationRequest=" + mIgnoreOrientationRequest + '}'; diff --git a/services/core/java/com/android/server/wm/DisplayWindowSettingsProvider.java b/services/core/java/com/android/server/wm/DisplayWindowSettingsProvider.java index 83da136e2005..78f1426348a7 100644 --- a/services/core/java/com/android/server/wm/DisplayWindowSettingsProvider.java +++ b/services/core/java/com/android/server/wm/DisplayWindowSettingsProvider.java @@ -16,7 +16,9 @@ package com.android.server.wm; +import static android.view.WindowManager.DISPLAY_IME_POLICY_LOCAL; import static android.view.WindowManager.REMOVE_CONTENT_MODE_UNDEFINED; +import static android.view.WindowManager.DISPLAY_IME_POLICY_FALLBACK_DISPLAY; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; @@ -35,13 +37,11 @@ import android.view.DisplayAddress; import android.view.DisplayInfo; import com.android.internal.annotations.VisibleForTesting; -import com.android.internal.util.FastXmlSerializer; import com.android.internal.util.XmlUtils; import com.android.server.wm.DisplayWindowSettings.SettingsProvider; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; -import org.xmlpull.v1.XmlSerializer; import java.io.File; import java.io.FileNotFoundException; @@ -49,7 +49,6 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.nio.charset.StandardCharsets; import java.util.HashMap; import java.util.Map; @@ -390,8 +389,15 @@ class DisplayWindowSettingsProvider implements SettingsProvider { "shouldShowWithInsecureKeyguard", null /* defaultValue */); settingsEntry.mShouldShowSystemDecors = getBooleanAttribute(parser, "shouldShowSystemDecors", null /* defaultValue */); - settingsEntry.mShouldShowIme = getBooleanAttribute(parser, "shouldShowIme", + final Boolean shouldShowIme = getBooleanAttribute(parser, "shouldShowIme", null /* defaultValue */); + if (shouldShowIme != null) { + settingsEntry.mImePolicy = shouldShowIme ? DISPLAY_IME_POLICY_LOCAL + : DISPLAY_IME_POLICY_FALLBACK_DISPLAY; + } else { + settingsEntry.mImePolicy = getIntegerAttribute(parser, "imePolicy", + null /* defaultValue */); + } settingsEntry.mFixedToUserRotation = getIntegerAttribute(parser, "fixedToUserRotation", null /* defaultValue */); settingsEntry.mIgnoreOrientationRequest = getBooleanAttribute(parser, @@ -478,9 +484,8 @@ class DisplayWindowSettingsProvider implements SettingsProvider { out.attribute(null, "shouldShowSystemDecors", settingsEntry.mShouldShowSystemDecors.toString()); } - if (settingsEntry.mShouldShowIme != null) { - out.attribute(null, "shouldShowIme", - settingsEntry.mShouldShowIme.toString()); + if (settingsEntry.mImePolicy != null) { + out.attributeInt(null, "imePolicy", settingsEntry.mImePolicy); } if (settingsEntry.mFixedToUserRotation != null) { out.attribute(null, "fixedToUserRotation", diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java index efd9e2a9ddd2..b49d83d93d54 100644 --- a/services/core/java/com/android/server/wm/InputMonitor.java +++ b/services/core/java/com/android/server/wm/InputMonitor.java @@ -523,9 +523,9 @@ final class InputMonitor { if (w.mInputChannelToken == null || w.mRemoved || (!w.canReceiveTouchInput() && !shouldApplyRecentsInputConsumer)) { if (w.mWinAnimator.hasSurface()) { - // Assign an InputInfo with type to the overlay window which can't receive input - // event. This is used to omit Surfaces from occlusion detection. - populateOverlayInputInfo(inputWindowHandle, w.isVisible()); + // Make sure the input info can't receive input event. It may be omitted from + // occlusion detection depending on the type or if it's a trusted overlay. + populateOverlayInputInfo(inputWindowHandle, w); setInputWindowInfoIfNeeded(mInputTransaction, w.mWinAnimator.mSurfaceController.mSurfaceControl, inputWindowHandle); return; @@ -603,6 +603,12 @@ final class InputMonitor { } } + static void populateOverlayInputInfo(InputWindowHandleWrapper inputWindowHandle, + WindowState w) { + populateOverlayInputInfo(inputWindowHandle, w.isVisible()); + inputWindowHandle.setTouchOcclusionMode(w.getTouchOcclusionMode()); + } + // This would reset InputWindowHandle fields to prevent it could be found by input event. // We need to check if any new field of InputWindowHandle could impact the result. @VisibleForTesting diff --git a/services/core/java/com/android/server/wm/KeyguardController.java b/services/core/java/com/android/server/wm/KeyguardController.java index c3b6149482e2..ebd91a093326 100644 --- a/services/core/java/com/android/server/wm/KeyguardController.java +++ b/services/core/java/com/android/server/wm/KeyguardController.java @@ -206,9 +206,8 @@ class KeyguardController { mAodShowing ? 1 : 0, 1 /* keyguardGoingAway */, "keyguardGoingAway"); - mRootWindowContainer.getDefaultDisplay() - .prepareAppTransition(TRANSIT_KEYGUARD_GOING_AWAY, - convertTransitFlags(flags)); + mRootWindowContainer.getDefaultDisplay().requestTransitionAndLegacyPrepare( + TRANSIT_KEYGUARD_GOING_AWAY, convertTransitFlags(flags)); updateKeyguardSleepToken(); // Some stack visibility might change (e.g. docked stack) diff --git a/services/core/java/com/android/server/wm/LaunchParamsController.java b/services/core/java/com/android/server/wm/LaunchParamsController.java index f1ae921c87f5..b6b172eeae5b 100644 --- a/services/core/java/com/android/server/wm/LaunchParamsController.java +++ b/services/core/java/com/android/server/wm/LaunchParamsController.java @@ -19,6 +19,7 @@ package com.android.server.wm; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static android.view.Display.INVALID_DISPLAY; +import static com.android.server.wm.ActivityStarter.Request; import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.PHASE_BOUNDS; import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.RESULT_CONTINUE; import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.RESULT_DONE; @@ -73,9 +74,10 @@ class LaunchParamsController { * @param source The {@link ActivityRecord} from which activity was started from. * @param options The {@link ActivityOptions} specified for the activity. * @param result The resulting params. + * @param request The optional request from the activity starter. */ - void calculate(Task task, WindowLayout layout, ActivityRecord activity, - ActivityRecord source, ActivityOptions options, int phase, LaunchParams result) { + void calculate(Task task, WindowLayout layout, ActivityRecord activity, ActivityRecord source, + ActivityOptions options, int phase, LaunchParams result, @Nullable Request request) { result.reset(); if (task != null || activity != null) { @@ -91,7 +93,7 @@ class LaunchParamsController { final LaunchParamsModifier modifier = mModifiers.get(i); switch(modifier.onCalculate(task, layout, activity, source, options, phase, mTmpCurrent, - mTmpResult)) { + mTmpResult, request)) { case RESULT_SKIP: // Do not apply any results when we are told to skip continue; @@ -128,7 +130,8 @@ class LaunchParamsController { boolean layoutTask(Task task, WindowLayout layout, ActivityRecord activity, ActivityRecord source, ActivityOptions options) { - calculate(task, layout, activity, source, options, PHASE_BOUNDS, mTmpParams); + calculate(task, layout, activity, source, options, PHASE_BOUNDS, mTmpParams, + null /* request */); // No changes, return. if (mTmpParams.isEmpty()) { @@ -305,15 +308,17 @@ class LaunchParamsController { * launched should have this be non-null. * @param source the Activity that launched a new task. Could be {@code null}. * @param options {@link ActivityOptions} used to start the activity with. - * @param phase the calculation phase, see {@link LaunchParamsModifier.Phase} + * @param phase the calculation phase, see {@link Phase} * @param currentParams launching params after the process of last {@link * LaunchParamsModifier}. * @param outParams the result params to be set. + * @param request Optional data to give more context on the launch * @return see {@link LaunchParamsModifier.Result} */ @Result - int onCalculate(Task task, WindowLayout layout, ActivityRecord activity, + int onCalculate(@Nullable Task task, WindowLayout layout, ActivityRecord activity, ActivityRecord source, ActivityOptions options, @Phase int phase, - LaunchParams currentParams, LaunchParams outParams); + LaunchParams currentParams, LaunchParams outParams, + @Nullable Request request); } } diff --git a/services/core/java/com/android/server/wm/RecentTasks.java b/services/core/java/com/android/server/wm/RecentTasks.java index a750e2c7c685..ba6b27ac3252 100644 --- a/services/core/java/com/android/server/wm/RecentTasks.java +++ b/services/core/java/com/android/server/wm/RecentTasks.java @@ -181,6 +181,9 @@ class RecentTasks { /** The non-empty tasks that are removed from recent tasks (see {@link #removeForAddTask}). */ private final ArrayList<Task> mHiddenTasks = new ArrayList<>(); + /** Whether to trim inactive tasks when activities are idle. */ + private boolean mCheckTrimmableTasksOnIdle; + // These values are generally loaded from resources, but can be set dynamically in the tests private boolean mHasVisibleRecentTasks; private int mGlobalMaxNumTasks; @@ -1045,16 +1048,6 @@ class RecentTasks { void add(Task task) { if (DEBUG_RECENTS_TRIM_TASKS) Slog.d(TAG, "add: task=" + task); - // Only allow trimming task if it is not updating visibility for activities, so the caller - // doesn't need to handle unexpected size and index when looping task containers. - final boolean canTrimTask = !mSupervisor.inActivityVisibilityUpdate(); - - // Clean up the hidden tasks when going to home because the user may not be unable to return - // to the task from recents. - if (canTrimTask && !mHiddenTasks.isEmpty() && task.isActivityTypeHome()) { - removeUnreachableHiddenTasks(task.getWindowingMode()); - } - final boolean isAffiliated = task.mAffiliatedTaskId != task.mTaskId || task.mNextAffiliateTaskId != INVALID_TASK_ID || task.mPrevAffiliateTaskId != INVALID_TASK_ID; @@ -1183,10 +1176,7 @@ class RecentTasks { cleanupLocked(task.mUserId); } - // Trim the set of tasks to the active set - if (canTrimTask) { - trimInactiveRecentTasks(); - } + mCheckTrimmableTasksOnIdle = true; notifyTaskPersisterLocked(task, false /* flush */); } @@ -1213,6 +1203,22 @@ class RecentTasks { } /** + * Called when an activity reports idle. The caller should not be in any loop that iterates + * window hierarchy. so it is safe (e.g. index out of bound) to remove inactive tasks. + */ + void onActivityIdle(ActivityRecord r) { + // Clean up the hidden tasks when going to home because the user may not be unable to return + // to the task from recents. + if (!mHiddenTasks.isEmpty() && r.isActivityTypeHome()) { + removeUnreachableHiddenTasks(r.getWindowingMode()); + } + if (mCheckTrimmableTasksOnIdle) { + mCheckTrimmableTasksOnIdle = false; + trimInactiveRecentTasks(); + } + } + + /** * Trims the recents task list to the global max number of recents. */ private void trimInactiveRecentTasks() { diff --git a/services/core/java/com/android/server/wm/RootDisplayArea.java b/services/core/java/com/android/server/wm/RootDisplayArea.java index 1e5d045e8680..da04f438a496 100644 --- a/services/core/java/com/android/server/wm/RootDisplayArea.java +++ b/services/core/java/com/android/server/wm/RootDisplayArea.java @@ -57,6 +57,11 @@ class RootDisplayArea extends DisplayArea<DisplayArea> { return this; } + @Override + RootDisplayArea asRootDisplayArea() { + return this; + } + /** Whether the orientation (based on dimensions) of this root is different from the Display. */ boolean isOrientationDifferentFromDisplay() { return false; diff --git a/services/core/java/com/android/server/wm/TaskDisplayArea.java b/services/core/java/com/android/server/wm/TaskDisplayArea.java index c02e7ad5b7c6..81b8200aa2b4 100644 --- a/services/core/java/com/android/server/wm/TaskDisplayArea.java +++ b/services/core/java/com/android/server/wm/TaskDisplayArea.java @@ -157,12 +157,24 @@ final class TaskDisplayArea extends DisplayArea<Task> { */ private int mLastLeafTaskToFrontId; + /** + * Whether this TaskDisplayArea was created by a {@link android.window.DisplayAreaOrganizer}. + * If {@code true}, this will be removed when the organizer is unregistered. + */ + final boolean mCreatedByOrganizer; + TaskDisplayArea(DisplayContent displayContent, WindowManagerService service, String name, int displayAreaFeature) { + this(displayContent, service, name, displayAreaFeature, false /* createdByOrganizer */); + } + + TaskDisplayArea(DisplayContent displayContent, WindowManagerService service, String name, + int displayAreaFeature, boolean createdByOrganizer) { super(service, Type.ANY, name, displayAreaFeature); mDisplayContent = displayContent; mRootWindowContainer = service.mRoot; mAtmService = service.mAtmService; + mCreatedByOrganizer = createdByOrganizer; } /** @@ -1914,6 +1926,11 @@ final class TaskDisplayArea extends DisplayArea<Task> { } @Override + TaskDisplayArea asTaskDisplayArea() { + return this; + } + + @Override void dump(PrintWriter pw, String prefix, boolean dumpAll) { pw.println(prefix + "TaskDisplayArea " + getName()); final String doublePrefix = prefix + " "; diff --git a/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java b/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java index 6dc957c1d118..8b2fa52afd22 100644 --- a/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java +++ b/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java @@ -35,6 +35,7 @@ import static android.util.DisplayMetrics.DENSITY_DEFAULT; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.Display.INVALID_DISPLAY; +import static com.android.server.wm.ActivityStarter.Request; import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM; import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME; @@ -99,23 +100,25 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier { ActivityRecord source, ActivityOptions options, LaunchParams currentParams, LaunchParams outParams) { return onCalculate(task, layout, activity, source, options, PHASE_BOUNDS, currentParams, - outParams); + outParams, null); } @Override - public int onCalculate(Task task, ActivityInfo.WindowLayout layout, - ActivityRecord activity, ActivityRecord source, ActivityOptions options, - int phase, LaunchParams currentParams, LaunchParams outParams) { + public int onCalculate(@Nullable Task task, @NonNull ActivityInfo.WindowLayout layout, + @NonNull ActivityRecord activity, @Nullable ActivityRecord source, + ActivityOptions options, int phase, LaunchParams currentParams, LaunchParams outParams, + @Nullable Request request) { initLogBuilder(task, activity); final int result = calculate(task, layout, activity, source, options, phase, currentParams, - outParams); + outParams, request); outputLog(); return result; } - private int calculate(Task task, ActivityInfo.WindowLayout layout, - ActivityRecord activity, ActivityRecord source, ActivityOptions options, int phase, - LaunchParams currentParams, LaunchParams outParams) { + private int calculate(@Nullable Task task, @NonNull ActivityInfo.WindowLayout layout, + @NonNull ActivityRecord activity, @Nullable ActivityRecord source, + ActivityOptions options, int phase, LaunchParams currentParams, LaunchParams outParams, + @Nullable Request request) { final ActivityRecord root; if (task != null) { root = task.getRootActivity() == null ? activity : task.getRootActivity(); @@ -138,7 +141,7 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier { // STEP 1: Determine the display area to launch the activity/task. final TaskDisplayArea taskDisplayArea = getPreferredLaunchTaskDisplayArea(task, - options, source, currentParams); + options, source, currentParams, activity, request); outParams.mPreferredTaskDisplayArea = taskDisplayArea; // TODO(b/152116619): Update the usages of display to use taskDisplayArea below. final DisplayContent display = taskDisplayArea.mDisplayContent; @@ -298,7 +301,8 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier { } private TaskDisplayArea getPreferredLaunchTaskDisplayArea(@Nullable Task task, - @Nullable ActivityOptions options, ActivityRecord source, LaunchParams currentParams) { + @Nullable ActivityOptions options, ActivityRecord source, LaunchParams currentParams, + @NonNull ActivityRecord activityRecord, @Nullable Request request) { TaskDisplayArea taskDisplayArea = null; final WindowContainerToken optionLaunchTaskDisplayAreaToken = options != null @@ -369,7 +373,7 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier { taskDisplayArea = currentParams.mPreferredTaskDisplayArea; } - // Fallback to default display if the device didn't declare support for multi-display + // Re-route to default display if the device didn't declare support for multi-display if (taskDisplayArea != null && !mSupervisor.mService.mSupportsMultiDisplay && taskDisplayArea.getDisplayId() != DEFAULT_DISPLAY) { taskDisplayArea = mSupervisor.mRootWindowContainer.getDefaultTaskDisplayArea(); @@ -377,7 +381,53 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier { return (taskDisplayArea != null) ? taskDisplayArea - : mSupervisor.mRootWindowContainer.getDefaultTaskDisplayArea(); + : getFallbackDisplayAreaForActivity(activityRecord, request); + } + + /** + * Calculates the default {@link TaskDisplayArea} for a task. We attempt to put the activity + * within the same display area if possible. The strategy is to find the display in the + * following order: + * + * <ol> + * <li>The display area of the top activity from the launching process will be used</li> + * <li>The display area of the top activity from the real launching process will be used + * </li> + * <li>Default display area from the associated root window container.</li> + * </ol> + * @param activityRecord the activity being started + * @param request optional {@link Request} made to start the activity record + * @return {@link TaskDisplayArea} to house the task + */ + private TaskDisplayArea getFallbackDisplayAreaForActivity( + @NonNull ActivityRecord activityRecord, @Nullable Request request) { + + WindowProcessController controllerFromLaunchingRecord = mSupervisor.mService + .getProcessController(activityRecord.launchedFromPid, + activityRecord.launchedFromUid); + final TaskDisplayArea displayAreaForLaunchingRecord = controllerFromLaunchingRecord == null + ? null : controllerFromLaunchingRecord.getTopActivityDisplayArea(); + if (displayAreaForLaunchingRecord != null) { + return displayAreaForLaunchingRecord; + } + + WindowProcessController controllerFromProcess = mSupervisor.mService.getProcessController( + activityRecord.getProcessName(), activityRecord.getUid()); + final TaskDisplayArea displayAreaForRecord = controllerFromProcess == null ? null + : controllerFromProcess.getTopActivityDisplayArea(); + if (displayAreaForRecord != null) { + return displayAreaForRecord; + } + + WindowProcessController controllerFromRequest = request == null ? null : mSupervisor + .mService.getProcessController(request.realCallingPid, request.realCallingUid); + final TaskDisplayArea displayAreaFromSourceProcess = controllerFromRequest == null ? null + : controllerFromRequest.getTopActivityDisplayArea(); + if (displayAreaFromSourceProcess != null) { + return displayAreaFromSourceProcess; + } + + return mSupervisor.mRootWindowContainer.getDefaultTaskDisplayArea(); } private boolean canInheritWindowingModeFromSource(@NonNull DisplayContent display, diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java index 341694d8ecb2..0cdd055d4052 100644 --- a/services/core/java/com/android/server/wm/Transition.java +++ b/services/core/java/com/android/server/wm/Transition.java @@ -26,6 +26,7 @@ import static android.view.WindowManager.TRANSIT_KEYGUARD_GOING_AWAY; import android.annotation.IntDef; import android.annotation.NonNull; +import android.graphics.Point; import android.graphics.Rect; import android.os.Binder; import android.os.IBinder; @@ -46,7 +47,6 @@ import com.android.internal.protolog.common.ProtoLog; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; -import java.util.Set; /** * Represents a logical transition. @@ -91,13 +91,24 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe private final BLASTSyncEngine mSyncEngine; /** + * This is a leash to put animating surfaces into flatly without clipping/ordering issues. It + * is a child of all the targets' shared ancestor. + */ + private SurfaceControl mRootLeash = null; + + /** * Contains change infos for both participants and all ancestors. We have to track ancestors * because they are all promotion candidates and thus we need their start-states * to be captured. */ final ArrayMap<WindowContainer, ChangeInfo> mChanges = new ArrayMap<>(); + /** The collected participants in the transition. */ final ArraySet<WindowContainer> mParticipants = new ArraySet<>(); + + /** The final animation targets derived from participants after promotion. */ + private ArraySet<WindowContainer> mTargets = null; + private @TransitionState int mState = STATE_COLLECTING; private boolean mReadyCalled = false; @@ -190,6 +201,42 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe if (mState < STATE_PLAYING) { throw new IllegalStateException("Can't finish a non-playing transition " + mSyncId); } + final Point tmpPos = new Point(); + // usually only size 1 + final ArraySet<DisplayContent> displays = new ArraySet<>(); + // Immediately apply all surface reparents, don't wait for pending/sync/etc. + SurfaceControl.Transaction t = mController.mAtm.mWindowManager.mTransactionFactory.get(); + for (int i = mTargets.size() - 1; i >= 0; --i) { + final WindowContainer target = mTargets.valueAt(i); + if (target.getParent() != null) { + // Ensure surfaceControls are re-parented back into the hierarchy. + t.reparent(target.getSurfaceControl(), target.getParent().getSurfaceControl()); + target.getRelativePosition(tmpPos); + t.setPosition(target.getSurfaceControl(), tmpPos.x, tmpPos.y); + displays.add(target.getDisplayContent()); + } + } + // Need to update layers on ALL displays (for now) since they were all paused while + // the animation played. + for (int i = displays.size() - 1; i >= 0; --i) { + if (displays.valueAt(i) == null) continue; + displays.valueAt(i).assignChildLayers(t); + } + // Also pro-actively hide going-invisible activity surfaces in same transaction to + // prevent flickers due to reparenting and animation z-order mismatch. + for (int i = mParticipants.size() - 1; i >= 0; --i) { + final ActivityRecord ar = mParticipants.valueAt(i).asActivityRecord(); + if (ar == null || ar.mVisibleRequested || !ar.isVisible()) continue; + t.hide(ar.getSurfaceControl()); + } + if (mRootLeash.isValid()) { + t.remove(mRootLeash); + } + mRootLeash = null; + t.apply(); + t.close(); + + // Commit all going-invisible containers for (int i = 0; i < mParticipants.size(); ++i) { final ActivityRecord ar = mParticipants.valueAt(i).asActivityRecord(); if (ar == null || ar.mVisibleRequested) { @@ -234,7 +281,11 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe mState = STATE_PLAYING; mController.moveToPlaying(this); - final TransitionInfo info = calculateTransitionInfo(mType, mParticipants, mChanges); + + // Resolve the animating targets from the participants + mTargets = calculateTargets(mParticipants, mChanges); + final TransitionInfo info = calculateTransitionInfo(mType, mTargets, mChanges); + mRootLeash = info.getRootLeash(); handleNonAppWindowsInTransition(displayId, mType, mFlags); @@ -245,11 +296,14 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe mController.getTransitionPlayer().onTransitionReady(this, info, transaction); } catch (RemoteException e) { // If there's an exception when trying to send the mergedTransaction to the - // client, we should immediately apply it here so the transactions aren't lost. + // client, we should finish and apply it here so the transactions aren't lost. transaction.apply(); + finishTransition(); } } else { + // No player registered, so just finish/apply immediately transaction.apply(); + finishTransition(); } mSyncId = -1; } @@ -325,10 +379,12 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe * * @return {@code true} if transition in target can be promoted to its parent. */ - private static boolean canPromote( - WindowContainer target, ArraySet<WindowContainer> topTargets) { + private static boolean canPromote(WindowContainer target, ArraySet<WindowContainer> topTargets, + ArrayMap<WindowContainer, ChangeInfo> changes) { final WindowContainer parent = target.getParent(); - if (parent == null || !parent.canCreateRemoteAnimationTarget()) { + final ChangeInfo parentChanges = parent != null ? changes.get(parent) : null; + if (parent == null || !parent.canCreateRemoteAnimationTarget() + || parentChanges == null || !parentChanges.hasChanged(parent)) { ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS, " SKIP: %s", parent == null ? "no parent" : ("parent can't be target " + parent)); return false; @@ -394,14 +450,14 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe // Go through each target until we find one that can be promoted. for (WindowContainer targ : topTargets) { ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS, " checking %s", targ); - if (!canPromote(targ, topTargets)) { + if (!canPromote(targ, topTargets, changes)) { continue; } - final WindowContainer parent = targ.getParent(); // No obstructions found to promotion, so promote + final WindowContainer parent = targ.getParent(); + final ChangeInfo parentInfo = changes.get(parent); ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS, " CAN PROMOTE: promoting to parent %s", parent); - final ChangeInfo parentInfo = changes.get(parent); targets.add(parent); // Go through all children of newly-promoted container and remove them from the @@ -443,10 +499,9 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe * animation targets to higher level in the window hierarchy if possible. */ @VisibleForTesting - static TransitionInfo calculateTransitionInfo(int type, Set<WindowContainer> participants, + @NonNull + static ArraySet<WindowContainer> calculateTargets(ArraySet<WindowContainer> participants, ArrayMap<WindowContainer, ChangeInfo> changes) { - final TransitionInfo out = new TransitionInfo(type); - ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS, "Start calculating TransitionInfo based on participants: %s", participants); @@ -470,6 +525,9 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe // Search through ancestors to find the top-most participant (if one exists) WindowContainer topParent = null; tmpList.clear(); + if (reportIfNotTop(wc)) { + tmpList.add(wc); + } for (WindowContainer p = wc.getParent(); p != null; p = p.getParent()) { if (participants.contains(p)) { topParent = p; @@ -479,8 +537,8 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe } } if (topParent != null) { - // There was an ancestor participant, so don't add wc to targets. However, continue - // to add any always-report parents along the way. + // There was an ancestor participant, so don't add wc to targets unless always- + // report. Similarly, add any always-report parents along the way. for (int i = 0; i < tmpList.size(); ++i) { targets.add(tmpList.get(i)); final ChangeInfo info = changes.get(tmpList.get(i)); @@ -508,10 +566,70 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe while (tryPromote(topTargets, targets, changes)) { // Empty on purpose } + return targets; + } - // Convert all the resolved ChangeInfos into a TransactionInfo object. - for (int i = targets.size() - 1; i >= 0; --i) { - final WindowContainer target = targets.valueAt(i); + /** Add any of `members` within `root` to `out` in top-to-bottom z-order. */ + private static void addMembersInOrder(WindowContainer root, ArraySet<WindowContainer> members, + ArrayList<WindowContainer> out) { + for (int i = root.getChildCount() - 1; i >= 0; --i) { + final WindowContainer child = root.getChildAt(i); + addMembersInOrder(child, members, out); + if (members.contains(child)) { + out.add(child); + } + } + } + + /** + * Construct a TransitionInfo object from a set of targets and changes. Also populates the + * root surface. + */ + @VisibleForTesting + @NonNull + static TransitionInfo calculateTransitionInfo(int type, ArraySet<WindowContainer> targets, + ArrayMap<WindowContainer, ChangeInfo> changes) { + final TransitionInfo out = new TransitionInfo(type); + if (targets.isEmpty()) { + out.setRootLeash(new SurfaceControl(), 0, 0); + return out; + } + + // Find the top-most shared ancestor + WindowContainer ancestor = targets.valueAt(0).getParent(); + // Go up ancestor parent chain until all topTargets are descendants. + ancestorLoop: + while (ancestor != null) { + for (int i = 1; i < targets.size(); ++i) { + if (!targets.valueAt(i).isDescendantOf(ancestor)) { + ancestor = ancestor.getParent(); + continue ancestorLoop; + } + } + break; + } + + // Sort targets top-to-bottom in Z. + ArrayList<WindowContainer> sortedTargets = new ArrayList<>(); + addMembersInOrder(ancestor, targets, sortedTargets); + + // make leash based on highest (z-order) direct child of ancestor with a participant. + WindowContainer leashReference = sortedTargets.get(0); + while (leashReference.getParent() != ancestor) { + leashReference = leashReference.getParent(); + } + final SurfaceControl rootLeash = leashReference.makeAnimationLeash().setName( + "Transition Root: " + leashReference.getName()).build(); + SurfaceControl.Transaction t = ancestor.mWmService.mTransactionFactory.get(); + t.setLayer(rootLeash, leashReference.getLastLayer()); + t.apply(); + t.close(); + out.setRootLeash(rootLeash, ancestor.getBounds().left, ancestor.getBounds().top); + + // Convert all the resolved ChangeInfos into TransactionInfo.Change objects in order. + final int count = sortedTargets.size(); + for (int i = 0; i < count; ++i) { + final WindowContainer target = sortedTargets.get(i); final ChangeInfo info = changes.get(target); final TransitionInfo.Change change = new TransitionInfo.Change( target.mRemoteToken != null ? target.mRemoteToken.toWindowContainerToken() @@ -520,8 +638,10 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe change.setParent(info.mParent.mRemoteToken.toWindowContainerToken()); } change.setMode(info.getTransitMode(target)); - change.setStartBounds(info.mAbsoluteBounds); - change.setEndBounds(target.getBounds()); + change.setStartAbsBounds(info.mAbsoluteBounds); + change.setEndAbsBounds(target.getBounds()); + change.setEndRelOffset(target.getBounds().left - target.getParent().getBounds().left, + target.getBounds().top - target.getParent().getBounds().top); out.addChange(change); } @@ -543,23 +663,26 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe // before change state boolean mVisible; int mWindowingMode; - Rect mAbsoluteBounds; + final Rect mAbsoluteBounds = new Rect(); ChangeInfo(@NonNull WindowContainer origState) { mVisible = origState.isVisibleRequested(); mWindowingMode = origState.getWindowingMode(); - mAbsoluteBounds = origState.getBounds(); + mAbsoluteBounds.set(origState.getBounds()); } @VisibleForTesting ChangeInfo(boolean visible, boolean existChange) { mVisible = visible; - mAbsoluteBounds = new Rect(); mExistenceChanged = existChange; } boolean hasChanged(@NonNull WindowContainer newState) { - return newState.isVisibleRequested() != mVisible + // If it's invisible and hasn't changed visibility, always return false since even if + // something changed, it wouldn't be a visible change. + final boolean currVisible = newState.isVisibleRequested(); + if (currVisible == mVisible && !mVisible) return false; + return currVisible != mVisible // if mWindowingMode is 0, this container wasn't attached at collect time, so // assume no change in windowing-mode. || (mWindowingMode != 0 && newState.getWindowingMode() != mWindowingMode) diff --git a/services/core/java/com/android/server/wm/TransitionController.java b/services/core/java/com/android/server/wm/TransitionController.java index 890ae8f2a434..2f5d10afe3da 100644 --- a/services/core/java/com/android/server/wm/TransitionController.java +++ b/services/core/java/com/android/server/wm/TransitionController.java @@ -109,10 +109,18 @@ class TransitionController { return mCollectingTransition != null; } + /** + * @return {@code true} if transition is actively playing. This is not necessarily {@code true} + * during collection. + */ + boolean isPlaying() { + return !mPlayingTransitions.isEmpty(); + } + /** @return {@code true} if a transition is running */ boolean inTransition() { // TODO(shell-transitions): eventually properly support multiple - return mCollectingTransition != null || !mPlayingTransitions.isEmpty(); + return isCollecting() || isPlaying(); } /** @return {@code true} if wc is in a participant subtree */ diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java index 4574be70674f..a1bb89d26f2f 100644 --- a/services/core/java/com/android/server/wm/WindowContainer.java +++ b/services/core/java/com/android/server/wm/WindowContainer.java @@ -1814,7 +1814,7 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< /** * For all {@link TaskDisplayArea} at or below this container call the callback. * @param callback Applies on each {@link TaskDisplayArea} found and stops the search if it - * returns {@code true}. + * returns {@code true}. * @param traverseTopToBottom If {@code true}, traverses the hierarchy from top-to-bottom in * terms of z-order, else from bottom-to-top. * @return {@code true} if the search ended before we reached the end of the hierarchy due to @@ -1837,7 +1837,7 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< * For all {@link TaskDisplayArea} at or below this container call the callback. Traverses from * top to bottom in terms of z-order. * @param callback Applies on each {@link TaskDisplayArea} found and stops the search if it - * returns {@code true}. + * returns {@code true}. * @return {@code true} if the search ended before we reached the end of the hierarchy due to * callback returning {@code true}. */ @@ -1873,7 +1873,7 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< * Performs a reduction on all {@link TaskDisplayArea} at or below this container, using the * provided initial value and an accumulation function, and returns the reduced value. * @param accumulator Applies on each {@link TaskDisplayArea} found with the accumulative result - * from the previous call. + * from the previous call. * @param initValue The initial value to pass to the accumulating function with the first * {@link TaskDisplayArea}. * @param traverseTopToBottom If {@code true}, traverses the hierarchy from top-to-bottom in @@ -1899,7 +1899,7 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< * provided initial value and an accumulation function, and returns the reduced value. Traverses * from top to bottom in terms of z-order. * @param accumulator Applies on each {@link TaskDisplayArea} found with the accumulative result - * from the previous call. + * from the previous call. * @param initValue The initial value to pass to the accumulating function with the first * {@link TaskDisplayArea}. * @return the accumulative result. @@ -1912,9 +1912,29 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< /** * Finds the first non {@code null} return value from calling the callback on all + * {@link DisplayArea} at or below this container. Traverses from top to bottom in terms of + * z-order. + * @param callback Applies on each {@link DisplayArea} found and stops the search if it + * returns non {@code null}. + * @return the first returned object that is not {@code null}. Returns {@code null} if not + * found. + */ + @Nullable + <R> R getItemFromDisplayAreas(Function<DisplayArea, R> callback) { + for (int i = mChildren.size() - 1; i >= 0; --i) { + R result = (R) mChildren.get(i).getItemFromDisplayAreas(callback); + if (result != null) { + return result; + } + } + return null; + } + + /** + * Finds the first non {@code null} return value from calling the callback on all * {@link TaskDisplayArea} at or below this container. * @param callback Applies on each {@link TaskDisplayArea} found and stops the search if it - * returns non {@code null}. + * returns non {@code null}. * @param traverseTopToBottom If {@code true}, traverses the hierarchy from top-to-bottom in * terms of z-order, else from bottom-to-top. * @return the first returned object that is not {@code null}. Returns {@code null} if not @@ -1941,7 +1961,7 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< * {@link TaskDisplayArea} at or below this container. Traverses from top to bottom in terms of * z-order. * @param callback Applies on each {@link TaskDisplayArea} found and stops the search if it - * returns non {@code null}. + * returns non {@code null}. * @return the first returned object that is not {@code null}. Returns {@code null} if not * found. */ @@ -2069,6 +2089,9 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< } void assignLayer(Transaction t, int layer) { + // Don't assign layers while a transition animation is playing + // TODO(b/173528115): establish robust best-practices around z-order fighting. + if (mWmService.mAtmService.getTransitionController().isPlaying()) return; final boolean changed = layer != mLastLayer || mLastRelativeToLayer != null; if (mSurfaceControl != null && changed) { setLayer(t, layer); @@ -2093,6 +2116,10 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< mSurfaceAnimator.setLayer(t, layer); } + int getLastLayer() { + return mLastLayer; + } + protected void setRelativeLayer(Transaction t, SurfaceControl relativeTo, int layer) { // Route through surface animator to accommodate that our surface control might be @@ -2884,6 +2911,16 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< return null; } + /** Cheap way of doing cast and instanceof. */ + RootDisplayArea asRootDisplayArea() { + return null; + } + + /** Cheap way of doing cast and instanceof. */ + TaskDisplayArea asTaskDisplayArea() { + return null; + } + /** * @return {@code true} if window container is manage by a * {@link android.window.WindowOrganizer} diff --git a/services/core/java/com/android/server/wm/WindowManagerInternal.java b/services/core/java/com/android/server/wm/WindowManagerInternal.java index d082778f50ba..a3a9eb773abf 100644 --- a/services/core/java/com/android/server/wm/WindowManagerInternal.java +++ b/services/core/java/com/android/server/wm/WindowManagerInternal.java @@ -30,6 +30,7 @@ import android.view.IWindow; import android.view.InputChannel; import android.view.MagnificationSpec; import android.view.WindowInfo; +import android.view.WindowManager.DisplayImePolicy; import com.android.internal.policy.KeyInterceptionInfo; import com.android.server.input.InputManagerService; @@ -506,12 +507,12 @@ public abstract class WindowManagerInternal { public abstract boolean shouldShowSystemDecorOnDisplay(int displayId); /** - * Indicates that the display should show IME. + * Indicates the policy for how the display should show IME. * * @param displayId The id of the display. - * @return {@code true} if the display should show IME when an input field become focused on it. + * @return The policy for how the display should show IME. */ - public abstract boolean shouldShowIme(int displayId); + public abstract @DisplayImePolicy int getDisplayImePolicy(int displayId); /** * Show IME on imeTargetWindow once IME has finished layout. diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 580c088ec133..80b021650c83 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -78,6 +78,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION; import static android.view.WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY; import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER; import static android.view.WindowManager.REMOVE_CONTENT_MODE_UNDEFINED; +import static android.view.WindowManager.DISPLAY_IME_POLICY_FALLBACK_DISPLAY; import static android.view.WindowManager.TRANSIT_NONE; import static android.view.WindowManager.TRANSIT_RELAUNCH; import static android.view.WindowManagerGlobal.ADD_OKAY; @@ -257,6 +258,7 @@ import android.view.WindowInsets; import android.view.WindowManager; import android.view.WindowManager.LayoutParams; import android.view.WindowManager.RemoveContentMode; +import android.view.WindowManager.DisplayImePolicy; import android.view.WindowManagerGlobal; import android.view.WindowManagerPolicyConstants.PointerEventListener; import android.window.ClientWindowFrames; @@ -7245,28 +7247,25 @@ public class WindowManagerService extends IWindowManager.Stub } @Override - public boolean shouldShowIme(int displayId) { - if (!checkCallingPermission(INTERNAL_SYSTEM_WINDOW, "shouldShowIme()")) { + public @DisplayImePolicy int getDisplayImePolicy(int displayId) { + if (!checkCallingPermission(INTERNAL_SYSTEM_WINDOW, "getDisplayImePolicy()")) { throw new SecurityException("Requires INTERNAL_SYSTEM_WINDOW permission"); } - boolean show; final DisplayContent dc = mRoot.getDisplayContent(displayId); if (dc == null) { ProtoLog.w(WM_ERROR, - "Attempted to get IME flag of a display that does not exist: %d", + "Attempted to get IME policy of a display that does not exist: %d", displayId); - return false; + return DISPLAY_IME_POLICY_FALLBACK_DISPLAY; } synchronized (mGlobalLock) { - show = dc.canShowIme(); + return dc.getImePolicy(); } - - return show; } @Override - public void setShouldShowIme(int displayId, boolean shouldShow) { - if (!checkCallingPermission(INTERNAL_SYSTEM_WINDOW, "setShouldShowIme()")) { + public void setDisplayImePolicy(int displayId, @DisplayImePolicy int imePolicy) { + if (!checkCallingPermission(INTERNAL_SYSTEM_WINDOW, "setDisplayImePolicy()")) { throw new SecurityException("Requires INTERNAL_SYSTEM_WINDOW permission"); } final long origId = Binder.clearCallingIdentity(); @@ -7274,16 +7273,16 @@ public class WindowManagerService extends IWindowManager.Stub synchronized (mGlobalLock) { final DisplayContent displayContent = getDisplayContentOrCreate(displayId, null); if (displayContent == null) { - ProtoLog.w(WM_ERROR, "Attempted to set IME flag to a display that does not " - + "exist: %d", displayId); + ProtoLog.w(WM_ERROR, "Attempted to set IME policy to a display" + + " that does not exist: %d", displayId); return; } if (!displayContent.isTrusted()) { - throw new SecurityException("Attempted to set IME flag to an untrusted " + throw new SecurityException("Attempted to set IME policy to an untrusted " + "virtual display: " + displayId); } - mDisplayWindowSettings.setShouldShowImeLocked(displayContent, shouldShow); + mDisplayWindowSettings.setDisplayImePolicy(displayContent, imePolicy); displayContent.reconfigureDisplayLocked(); } @@ -7765,9 +7764,9 @@ public class WindowManagerService extends IWindowManager.Stub } @Override - public boolean shouldShowIme(int displayId) { + public @DisplayImePolicy int getDisplayImePolicy(int displayId) { synchronized (mGlobalLock) { - return WindowManagerService.this.shouldShowIme(displayId); + return WindowManagerService.this.getDisplayImePolicy(displayId); } } diff --git a/services/core/java/com/android/server/wm/WindowProcessController.java b/services/core/java/com/android/server/wm/WindowProcessController.java index c55f059cae16..8f8fea34e620 100644 --- a/services/core/java/com/android/server/wm/WindowProcessController.java +++ b/services/core/java/com/android/server/wm/WindowProcessController.java @@ -730,6 +730,28 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio return mHasActivities || mHasRecentTasks; } + @Nullable + TaskDisplayArea getTopActivityDisplayArea() { + if (mActivities.isEmpty()) { + return null; + } + + final int lastIndex = mActivities.size() - 1; + ActivityRecord topRecord = mActivities.get(lastIndex); + TaskDisplayArea displayArea = topRecord.getDisplayArea(); + + for (int index = lastIndex - 1; index >= 0; --index) { + ActivityRecord nextRecord = mActivities.get(index); + TaskDisplayArea nextDisplayArea = nextRecord.getDisplayArea(); + if (nextRecord.compareTo(topRecord) > 0 && nextDisplayArea != null) { + topRecord = nextRecord; + displayArea = nextDisplayArea; + } + } + + return displayArea; + } + private boolean hasActivityInVisibleTask() { for (int i = mActivities.size() - 1; i >= 0; --i) { Task task = mActivities.get(i).getTask(); diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 0a8ff4dc71f5..c318fad4d0a0 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -127,6 +127,7 @@ import static com.android.server.wm.IdentifierProto.USER_ID; import static com.android.server.wm.MoveAnimationSpecProto.DURATION_MS; import static com.android.server.wm.MoveAnimationSpecProto.FROM; import static com.android.server.wm.MoveAnimationSpecProto.TO; +import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_ALL; import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_WINDOW_ANIMATION; import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS; import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION; @@ -972,6 +973,9 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP if (WindowManager.LayoutParams.isSystemAlertWindowType(mAttrs.type)) { return TouchOcclusionMode.USE_OPACITY; } + if (isAnimating(PARENTS | TRANSITION, ANIMATION_TYPE_ALL)) { + return TouchOcclusionMode.USE_OPACITY; + } return TouchOcclusionMode.BLOCK_UNTRUSTED; } @@ -5267,6 +5271,12 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP if (mSurfaceControl == null) { return; } + if (mWmService.mWindowPlacerLocked.isLayoutDeferred() || isGoneForLayout()) { + // Since this relies on mWindowFrames, changes made while layout is deferred are + // likely to be invalid. Similarly, if it's goneForLayout, mWindowFrames may not be + // up-to-date and thus can't be relied on. + return; + } transformFrameToSurfacePosition(mWindowFrames.mFrame.left, mWindowFrames.mFrame.top, mSurfacePosition); diff --git a/services/core/jni/Android.bp b/services/core/jni/Android.bp index da2c005d7332..6da9517743d2 100644 --- a/services/core/jni/Android.bp +++ b/services/core/jni/Android.bp @@ -53,8 +53,8 @@ cc_library_static { "com_android_server_UsbDescriptorParser.cpp", "com_android_server_UsbMidiDevice.cpp", "com_android_server_UsbHostManager.cpp", + "com_android_server_vibrator_VibratorController.cpp", "com_android_server_VibratorManagerService.cpp", - "com_android_server_VibratorService.cpp", "com_android_server_PersistentDataBlockService.cpp", "com_android_server_am_CachedAppOptimizer.cpp", "com_android_server_am_LowMemDetector.cpp", diff --git a/services/core/jni/OWNERS b/services/core/jni/OWNERS index 4c017f5513a2..6f74885b98e5 100644 --- a/services/core/jni/OWNERS +++ b/services/core/jni/OWNERS @@ -2,8 +2,8 @@ per-file com_android_server_lights_LightsService.cpp = michaelwr@google.com, santoscordon@google.com # Haptics +per-file com_android_server_vibrator_VibratorController.cpp = michaelwr@google.com per-file com_android_server_VibratorManagerService.cpp = michaelwr@google.com -per-file com_android_server_VibratorService.cpp = michaelwr@google.com # Input per-file com_android_server_input_InputManagerService.cpp = michaelwr@google.com, svv@google.com diff --git a/services/core/jni/com_android_server_am_BatteryStatsService.cpp b/services/core/jni/com_android_server_am_BatteryStatsService.cpp index 5d78f127f77f..c44cea38df1c 100644 --- a/services/core/jni/com_android_server_am_BatteryStatsService.cpp +++ b/services/core/jni/com_android_server_am_BatteryStatsService.cpp @@ -122,7 +122,7 @@ public: { std::unique_lock<std::mutex> reasonsLock(mReasonsMutex, std::defer_lock); if (reasonsLock.try_lock() && mWakeupReasons.empty()) { - mWakeupReasons = std::move(wakeupReasons); + mWakeupReasons = wakeupReasons; reasonsCaptured = true; } } diff --git a/services/core/jni/com_android_server_VibratorService.cpp b/services/core/jni/com_android_server_vibrator_VibratorController.cpp index 9aca84849fc6..afce5379febb 100644 --- a/services/core/jni/com_android_server_VibratorService.cpp +++ b/services/core/jni/com_android_server_vibrator_VibratorController.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009 The Android Open Source Project + * 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. @@ -14,20 +14,18 @@ * limitations under the License. */ -#define LOG_TAG "VibratorService" +#define LOG_TAG "VibratorController" #include <android/hardware/vibrator/1.3/IVibrator.h> #include <android/hardware/vibrator/IVibrator.h> -#include "jni.h" #include <nativehelper/JNIHelp.h> #include "android_runtime/AndroidRuntime.h" #include "core_jni_helpers.h" +#include "jni.h" -#include <utils/misc.h> #include <utils/Log.h> - -#include <inttypes.h> +#include <utils/misc.h> #include <vibratorservice/VibratorHalController.h> @@ -48,58 +46,59 @@ static struct { } sPrimitiveClassInfo; static_assert(static_cast<uint8_t>(V1_0::EffectStrength::LIGHT) == - static_cast<uint8_t>(aidl::EffectStrength::LIGHT)); + static_cast<uint8_t>(aidl::EffectStrength::LIGHT)); static_assert(static_cast<uint8_t>(V1_0::EffectStrength::MEDIUM) == - static_cast<uint8_t>(aidl::EffectStrength::MEDIUM)); + static_cast<uint8_t>(aidl::EffectStrength::MEDIUM)); static_assert(static_cast<uint8_t>(V1_0::EffectStrength::STRONG) == - static_cast<uint8_t>(aidl::EffectStrength::STRONG)); + static_cast<uint8_t>(aidl::EffectStrength::STRONG)); static_assert(static_cast<uint8_t>(V1_3::Effect::CLICK) == - static_cast<uint8_t>(aidl::Effect::CLICK)); + static_cast<uint8_t>(aidl::Effect::CLICK)); static_assert(static_cast<uint8_t>(V1_3::Effect::DOUBLE_CLICK) == - static_cast<uint8_t>(aidl::Effect::DOUBLE_CLICK)); -static_assert(static_cast<uint8_t>(V1_3::Effect::TICK) == - static_cast<uint8_t>(aidl::Effect::TICK)); -static_assert(static_cast<uint8_t>(V1_3::Effect::THUD) == - static_cast<uint8_t>(aidl::Effect::THUD)); -static_assert(static_cast<uint8_t>(V1_3::Effect::POP) == - static_cast<uint8_t>(aidl::Effect::POP)); + static_cast<uint8_t>(aidl::Effect::DOUBLE_CLICK)); +static_assert(static_cast<uint8_t>(V1_3::Effect::TICK) == static_cast<uint8_t>(aidl::Effect::TICK)); +static_assert(static_cast<uint8_t>(V1_3::Effect::THUD) == static_cast<uint8_t>(aidl::Effect::THUD)); +static_assert(static_cast<uint8_t>(V1_3::Effect::POP) == static_cast<uint8_t>(aidl::Effect::POP)); static_assert(static_cast<uint8_t>(V1_3::Effect::HEAVY_CLICK) == - static_cast<uint8_t>(aidl::Effect::HEAVY_CLICK)); + static_cast<uint8_t>(aidl::Effect::HEAVY_CLICK)); static_assert(static_cast<uint8_t>(V1_3::Effect::RINGTONE_1) == - static_cast<uint8_t>(aidl::Effect::RINGTONE_1)); + static_cast<uint8_t>(aidl::Effect::RINGTONE_1)); static_assert(static_cast<uint8_t>(V1_3::Effect::RINGTONE_2) == - static_cast<uint8_t>(aidl::Effect::RINGTONE_2)); + static_cast<uint8_t>(aidl::Effect::RINGTONE_2)); static_assert(static_cast<uint8_t>(V1_3::Effect::RINGTONE_15) == - static_cast<uint8_t>(aidl::Effect::RINGTONE_15)); + static_cast<uint8_t>(aidl::Effect::RINGTONE_15)); static_assert(static_cast<uint8_t>(V1_3::Effect::TEXTURE_TICK) == - static_cast<uint8_t>(aidl::Effect::TEXTURE_TICK)); + static_cast<uint8_t>(aidl::Effect::TEXTURE_TICK)); -class NativeVibratorService { +class VibratorControllerWrapper { public: - NativeVibratorService(JNIEnv* env, jobject callbackListener) - : mController(std::make_unique<vibrator::HalController>()), + VibratorControllerWrapper(JNIEnv* env, int32_t vibratorId, jobject callbackListener) + // TODO(b/167946816): use ManagerHalController to get vibrator by id + : mHal(std::make_unique<vibrator::HalController>()), + mVibratorId(vibratorId), mCallbackListener(env->NewGlobalRef(callbackListener)) { LOG_ALWAYS_FATAL_IF(mCallbackListener == nullptr, "Unable to create global reference to vibration callback handler"); } - ~NativeVibratorService() { + ~VibratorControllerWrapper() { auto jniEnv = GetOrAttachJNIEnvironment(sJvm); jniEnv->DeleteGlobalRef(mCallbackListener); } - vibrator::HalController* controller() const { return mController.get(); } + vibrator::HalController* hal() const { return mHal.get(); } std::function<void()> createCallback(jlong vibrationId) { return [vibrationId, this]() { auto jniEnv = GetOrAttachJNIEnvironment(sJvm); - jniEnv->CallVoidMethod(mCallbackListener, sMethodIdOnComplete, vibrationId); + jniEnv->CallVoidMethod(mCallbackListener, sMethodIdOnComplete, mVibratorId, + vibrationId); }; } private: - const std::unique_ptr<vibrator::HalController> mController; + const std::unique_ptr<vibrator::HalController> mHal; + const int32_t mVibratorId; const jobject mCallbackListener; }; @@ -112,80 +111,80 @@ static aidl::CompositeEffect effectFromJavaPrimitive(JNIEnv* env, jobject primit return effect; } -static void destroyNativeService(void* servicePtr) { - NativeVibratorService* service = reinterpret_cast<NativeVibratorService*>(servicePtr); - if (service) { - delete service; +static void destroyNativeWrapper(void* ptr) { + VibratorControllerWrapper* wrapper = reinterpret_cast<VibratorControllerWrapper*>(ptr); + if (wrapper) { + delete wrapper; } } -static jlong vibratorInit(JNIEnv* env, jclass /* clazz */, jobject callbackListener) { - std::unique_ptr<NativeVibratorService> service = - std::make_unique<NativeVibratorService>(env, callbackListener); - service->controller()->init(); - return reinterpret_cast<jlong>(service.release()); +static jlong vibratorInit(JNIEnv* env, jclass /* clazz */, jint vibratorId, + jobject callbackListener) { + std::unique_ptr<VibratorControllerWrapper> wrapper = + std::make_unique<VibratorControllerWrapper>(env, vibratorId, callbackListener); + wrapper->hal()->init(); + return reinterpret_cast<jlong>(wrapper.release()); } static jlong vibratorGetFinalizer(JNIEnv* /* env */, jclass /* clazz */) { - return static_cast<jlong>(reinterpret_cast<uintptr_t>(&destroyNativeService)); + return static_cast<jlong>(reinterpret_cast<uintptr_t>(&destroyNativeWrapper)); } -static jboolean vibratorExists(JNIEnv* env, jclass /* clazz */, jlong servicePtr) { - NativeVibratorService* service = reinterpret_cast<NativeVibratorService*>(servicePtr); - if (service == nullptr) { - ALOGE("vibratorExists failed because native service was not initialized"); +static jboolean vibratorIsAvailable(JNIEnv* env, jclass /* clazz */, jlong ptr) { + VibratorControllerWrapper* wrapper = reinterpret_cast<VibratorControllerWrapper*>(ptr); + if (wrapper == nullptr) { + ALOGE("vibratorIsAvailable failed because native wrapper was not initialized"); return JNI_FALSE; } - return service->controller()->ping().isOk() ? JNI_TRUE : JNI_FALSE; + return wrapper->hal()->ping().isOk() ? JNI_TRUE : JNI_FALSE; } -static void vibratorOn(JNIEnv* env, jclass /* clazz */, jlong servicePtr, jlong timeoutMs, +static void vibratorOn(JNIEnv* env, jclass /* clazz */, jlong ptr, jlong timeoutMs, jlong vibrationId) { - NativeVibratorService* service = reinterpret_cast<NativeVibratorService*>(servicePtr); - if (service == nullptr) { - ALOGE("vibratorOn failed because native service was not initialized"); + VibratorControllerWrapper* wrapper = reinterpret_cast<VibratorControllerWrapper*>(ptr); + if (wrapper == nullptr) { + ALOGE("vibratorOn failed because native wrapper was not initialized"); return; } - auto callback = service->createCallback(vibrationId); - service->controller()->on(std::chrono::milliseconds(timeoutMs), callback); + auto callback = wrapper->createCallback(vibrationId); + wrapper->hal()->on(std::chrono::milliseconds(timeoutMs), callback); } -static void vibratorOff(JNIEnv* env, jclass /* clazz */, jlong servicePtr) { - NativeVibratorService* service = reinterpret_cast<NativeVibratorService*>(servicePtr); - if (service == nullptr) { - ALOGE("vibratorOff failed because native service was not initialized"); +static void vibratorOff(JNIEnv* env, jclass /* clazz */, jlong ptr) { + VibratorControllerWrapper* wrapper = reinterpret_cast<VibratorControllerWrapper*>(ptr); + if (wrapper == nullptr) { + ALOGE("vibratorOff failed because native wrapper was not initialized"); return; } - service->controller()->off(); + wrapper->hal()->off(); } -static void vibratorSetAmplitude(JNIEnv* env, jclass /* clazz */, jlong servicePtr, - jint amplitude) { - NativeVibratorService* service = reinterpret_cast<NativeVibratorService*>(servicePtr); - if (service == nullptr) { - ALOGE("vibratorSetAmplitude failed because native service was not initialized"); +static void vibratorSetAmplitude(JNIEnv* env, jclass /* clazz */, jlong ptr, jint amplitude) { + VibratorControllerWrapper* wrapper = reinterpret_cast<VibratorControllerWrapper*>(ptr); + if (wrapper == nullptr) { + ALOGE("vibratorSetAmplitude failed because native wrapper was not initialized"); return; } - service->controller()->setAmplitude(static_cast<int32_t>(amplitude)); + wrapper->hal()->setAmplitude(static_cast<int32_t>(amplitude)); } -static void vibratorSetExternalControl(JNIEnv* env, jclass /* clazz */, jlong servicePtr, +static void vibratorSetExternalControl(JNIEnv* env, jclass /* clazz */, jlong ptr, jboolean enabled) { - NativeVibratorService* service = reinterpret_cast<NativeVibratorService*>(servicePtr); - if (service == nullptr) { - ALOGE("vibratorSetExternalControl failed because native service was not initialized"); + VibratorControllerWrapper* wrapper = reinterpret_cast<VibratorControllerWrapper*>(ptr); + if (wrapper == nullptr) { + ALOGE("vibratorSetExternalControl failed because native wrapper was not initialized"); return; } - service->controller()->setExternalControl(enabled); + wrapper->hal()->setExternalControl(enabled); } -static jintArray vibratorGetSupportedEffects(JNIEnv* env, jclass /* clazz */, jlong servicePtr) { - NativeVibratorService* service = reinterpret_cast<NativeVibratorService*>(servicePtr); - if (service == nullptr) { - ALOGE("vibratorGetSupportedEffects failed because native service was not initialized"); +static jintArray vibratorGetSupportedEffects(JNIEnv* env, jclass /* clazz */, jlong ptr) { + VibratorControllerWrapper* wrapper = reinterpret_cast<VibratorControllerWrapper*>(ptr); + if (wrapper == nullptr) { + ALOGE("vibratorGetSupportedEffects failed because native wrapper was not initialized"); return nullptr; } - auto result = service->controller()->getSupportedEffects(); + auto result = wrapper->hal()->getSupportedEffects(); if (!result.isOk()) { return nullptr; } @@ -196,13 +195,13 @@ static jintArray vibratorGetSupportedEffects(JNIEnv* env, jclass /* clazz */, jl return effects; } -static jintArray vibratorGetSupportedPrimitives(JNIEnv* env, jclass /* clazz */, jlong servicePtr) { - NativeVibratorService* service = reinterpret_cast<NativeVibratorService*>(servicePtr); - if (service == nullptr) { - ALOGE("vibratorGetSupportedPrimitives failed because native service was not initialized"); +static jintArray vibratorGetSupportedPrimitives(JNIEnv* env, jclass /* clazz */, jlong ptr) { + VibratorControllerWrapper* wrapper = reinterpret_cast<VibratorControllerWrapper*>(ptr); + if (wrapper == nullptr) { + ALOGE("vibratorGetSupportedPrimitives failed because native wrapper was not initialized"); return nullptr; } - auto result = service->controller()->getSupportedPrimitives(); + auto result = wrapper->hal()->getSupportedPrimitives(); if (!result.isOk()) { return nullptr; } @@ -213,25 +212,25 @@ static jintArray vibratorGetSupportedPrimitives(JNIEnv* env, jclass /* clazz */, return primitives; } -static jlong vibratorPerformEffect(JNIEnv* env, jclass /* clazz */, jlong servicePtr, jlong effect, +static jlong vibratorPerformEffect(JNIEnv* env, jclass /* clazz */, jlong ptr, jlong effect, jlong strength, jlong vibrationId) { - NativeVibratorService* service = reinterpret_cast<NativeVibratorService*>(servicePtr); - if (service == nullptr) { - ALOGE("vibratorPerformEffect failed because native service was not initialized"); + VibratorControllerWrapper* wrapper = reinterpret_cast<VibratorControllerWrapper*>(ptr); + if (wrapper == nullptr) { + ALOGE("vibratorPerformEffect failed because native wrapper was not initialized"); return -1; } aidl::Effect effectType = static_cast<aidl::Effect>(effect); aidl::EffectStrength effectStrength = static_cast<aidl::EffectStrength>(strength); - auto callback = service->createCallback(vibrationId); - auto result = service->controller()->performEffect(effectType, effectStrength, callback); + auto callback = wrapper->createCallback(vibrationId); + auto result = wrapper->hal()->performEffect(effectType, effectStrength, callback); return result.isOk() ? result.value().count() : -1; } -static void vibratorPerformComposedEffect(JNIEnv* env, jclass /* clazz */, jlong servicePtr, +static void vibratorPerformComposedEffect(JNIEnv* env, jclass /* clazz */, jlong ptr, jobjectArray composition, jlong vibrationId) { - NativeVibratorService* service = reinterpret_cast<NativeVibratorService*>(servicePtr); - if (service == nullptr) { - ALOGE("vibratorPerformComposedEffect failed because native service was not initialized"); + VibratorControllerWrapper* wrapper = reinterpret_cast<VibratorControllerWrapper*>(ptr); + if (wrapper == nullptr) { + ALOGE("vibratorPerformComposedEffect failed because native wrapper was not initialized"); return; } size_t size = env->GetArrayLength(composition); @@ -240,46 +239,46 @@ static void vibratorPerformComposedEffect(JNIEnv* env, jclass /* clazz */, jlong jobject element = env->GetObjectArrayElement(composition, i); effects.push_back(effectFromJavaPrimitive(env, element)); } - auto callback = service->createCallback(vibrationId); - service->controller()->performComposedEffect(effects, callback); + auto callback = wrapper->createCallback(vibrationId); + wrapper->hal()->performComposedEffect(effects, callback); } -static jlong vibratorGetCapabilities(JNIEnv* env, jclass /* clazz */, jlong servicePtr) { - NativeVibratorService* service = reinterpret_cast<NativeVibratorService*>(servicePtr); - if (service == nullptr) { - ALOGE("vibratorGetCapabilities failed because native service was not initialized"); +static jlong vibratorGetCapabilities(JNIEnv* env, jclass /* clazz */, jlong ptr) { + VibratorControllerWrapper* wrapper = reinterpret_cast<VibratorControllerWrapper*>(ptr); + if (wrapper == nullptr) { + ALOGE("vibratorGetCapabilities failed because native wrapper was not initialized"); return 0; } - auto result = service->controller()->getCapabilities(); + auto result = wrapper->hal()->getCapabilities(); return result.isOk() ? static_cast<jlong>(result.value()) : 0; } -static void vibratorAlwaysOnEnable(JNIEnv* env, jclass /* clazz */, jlong servicePtr, jlong id, +static void vibratorAlwaysOnEnable(JNIEnv* env, jclass /* clazz */, jlong ptr, jlong id, jlong effect, jlong strength) { - NativeVibratorService* service = reinterpret_cast<NativeVibratorService*>(servicePtr); - if (service == nullptr) { - ALOGE("vibratorAlwaysOnEnable failed because native service was not initialized"); + VibratorControllerWrapper* wrapper = reinterpret_cast<VibratorControllerWrapper*>(ptr); + if (wrapper == nullptr) { + ALOGE("vibratorAlwaysOnEnable failed because native wrapper was not initialized"); return; } - service->controller()->alwaysOnEnable(static_cast<int32_t>(id), - static_cast<aidl::Effect>(effect), - static_cast<aidl::EffectStrength>(strength)); + wrapper->hal()->alwaysOnEnable(static_cast<int32_t>(id), static_cast<aidl::Effect>(effect), + static_cast<aidl::EffectStrength>(strength)); } -static void vibratorAlwaysOnDisable(JNIEnv* env, jclass /* clazz */, jlong servicePtr, jlong id) { - NativeVibratorService* service = reinterpret_cast<NativeVibratorService*>(servicePtr); - if (service == nullptr) { - ALOGE("vibratorAlwaysOnDisable failed because native service was not initialized"); +static void vibratorAlwaysOnDisable(JNIEnv* env, jclass /* clazz */, jlong ptr, jlong id) { + VibratorControllerWrapper* wrapper = reinterpret_cast<VibratorControllerWrapper*>(ptr); + if (wrapper == nullptr) { + ALOGE("vibratorAlwaysOnDisable failed because native wrapper was not initialized"); return; } - service->controller()->alwaysOnDisable(static_cast<int32_t>(id)); + wrapper->hal()->alwaysOnDisable(static_cast<int32_t>(id)); } static const JNINativeMethod method_table[] = { - {"vibratorInit", "(Lcom/android/server/VibratorService$OnCompleteListener;)J", + {"vibratorInit", + "(ILcom/android/server/vibrator/VibratorController$OnVibrationCompleteListener;)J", (void*)vibratorInit}, {"vibratorGetFinalizer", "()J", (void*)vibratorGetFinalizer}, - {"vibratorExists", "(J)Z", (void*)vibratorExists}, + {"vibratorIsAvailable", "(J)Z", (void*)vibratorIsAvailable}, {"vibratorOn", "(JJJ)V", (void*)vibratorOn}, {"vibratorOff", "(J)V", (void*)vibratorOff}, {"vibratorSetAmplitude", "(JI)V", (void*)vibratorSetAmplitude}, @@ -295,11 +294,12 @@ static const JNINativeMethod method_table[] = { {"vibratorAlwaysOnDisable", "(JJ)V", (void*)vibratorAlwaysOnDisable}, }; -int register_android_server_VibratorService(JavaVM* jvm, JNIEnv* env) { +int register_android_server_vibrator_VibratorController(JavaVM* jvm, JNIEnv* env) { sJvm = jvm; - jclass listenerClass = - FindClassOrDie(env, "com/android/server/VibratorService$OnCompleteListener"); - sMethodIdOnComplete = GetMethodIDOrDie(env, listenerClass, "onComplete", "(J)V"); + auto listenerClassName = + "com/android/server/vibrator/VibratorController$OnVibrationCompleteListener"; + jclass listenerClass = FindClassOrDie(env, listenerClassName); + sMethodIdOnComplete = GetMethodIDOrDie(env, listenerClass, "onComplete", "(IJ)V"); jclass primitiveClass = FindClassOrDie(env, "android/os/VibrationEffect$Composition$PrimitiveEffect"); @@ -307,8 +307,8 @@ int register_android_server_VibratorService(JavaVM* jvm, JNIEnv* env) { sPrimitiveClassInfo.scale = GetFieldIDOrDie(env, primitiveClass, "scale", "F"); sPrimitiveClassInfo.delay = GetFieldIDOrDie(env, primitiveClass, "delay", "I"); - return jniRegisterNativeMethods(env, "com/android/server/VibratorService", method_table, - NELEM(method_table)); + return jniRegisterNativeMethods(env, "com/android/server/vibrator/VibratorController", + method_table, NELEM(method_table)); } }; // namespace android diff --git a/services/core/jni/onload.cpp b/services/core/jni/onload.cpp index 79b5fed3e448..5a0d08aeb6b3 100644 --- a/services/core/jni/onload.cpp +++ b/services/core/jni/onload.cpp @@ -37,8 +37,8 @@ int register_android_server_UsbDeviceManager(JNIEnv* env); int register_android_server_UsbMidiDevice(JNIEnv* env); int register_android_server_UsbHostManager(JNIEnv* env); int register_android_server_vr_VrManagerService(JNIEnv* env); +int register_android_server_vibrator_VibratorController(JavaVM* vm, JNIEnv* env); int register_android_server_VibratorManagerService(JNIEnv* env); -int register_android_server_VibratorService(JavaVM* vm, JNIEnv* env); int register_android_server_location_GnssLocationProvider(JNIEnv* env); int register_android_server_connectivity_Vpn(JNIEnv* env); int register_android_server_TestNetworkService(JNIEnv* env); @@ -90,8 +90,8 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */) register_android_server_UsbAlsaJackDetector(env); register_android_server_UsbHostManager(env); register_android_server_vr_VrManagerService(env); + register_android_server_vibrator_VibratorController(vm, env); register_android_server_VibratorManagerService(env); - register_android_server_VibratorService(vm, env); register_android_server_SystemServer(env); register_android_server_location_GnssLocationProvider(env); register_android_server_connectivity_Vpn(env); diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index a6466821ff38..6ca27b597987 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -1576,172 +1576,65 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { * Creates a new {@link CallerIdentity} object to represent the caller's identity. */ private CallerIdentity getCallerIdentity() { - final int callerUid = mInjector.binderGetCallingUid(); - return new CallerIdentity(callerUid, null, null); + return getCallerIdentity(null, null); } /** * Creates a new {@link CallerIdentity} object to represent the caller's identity. */ - private CallerIdentity getCallerIdentity(@NonNull String callerPackage) { - final int callerUid = mInjector.binderGetCallingUid(); - - if (!isCallingFromPackage(callerPackage, callerUid)) { - throw new SecurityException( - String.format("Caller with uid %d is not %s", callerUid, callerPackage)); - } + private CallerIdentity getCallerIdentity(@Nullable String callerPackage) { - return new CallerIdentity(callerUid, callerPackage, null); + return getCallerIdentity(null, callerPackage); } /** * Creates a new {@link CallerIdentity} object to represent the caller's identity. + * The component name should be an active admin for the calling user. */ @VisibleForTesting - protected CallerIdentity getCallerIdentity(@Nullable ComponentName adminComponent, - @NonNull String callerPackage) { - return adminComponent == null - ? getCallerIdentity(callerPackage) - : getCallerIdentity(adminComponent); + CallerIdentity getCallerIdentity(@Nullable ComponentName adminComponent) { + return getCallerIdentity(adminComponent, null); } /** * Creates a new {@link CallerIdentity} object to represent the caller's identity. - * The component name should be an active admin for the calling user. + * If {@code adminComponent} is provided, it's validated against the list of known + * active admins and caller uid. If {@code callerPackage} is provided, it's validated + * against the caller uid. If a valid {@code adminComponent} is provided but not + * {@code callerPackage}, the package name of the {@code adminComponent} is used instead. */ @VisibleForTesting - protected CallerIdentity getCallerIdentity(@NonNull ComponentName adminComponent) { + CallerIdentity getCallerIdentity(@Nullable ComponentName adminComponent, + @Nullable String callerPackage) { final int callerUid = mInjector.binderGetCallingUid(); - final DevicePolicyData policy = getUserData(UserHandle.getUserId(callerUid)); - ActiveAdmin admin = policy.mAdminMap.get(adminComponent); - - if (admin == null) { - throw new SecurityException(String.format("No active admin for %s", adminComponent)); - } - if (admin.getUid() != callerUid) { - throw new SecurityException( - String.format("Admin %s is not owned by uid %d", adminComponent, callerUid)); - } - - return new CallerIdentity(callerUid, adminComponent.getPackageName(), adminComponent); - } - - /** - * Creates a new {@link CallerIdentity} object to represent the caller's identity, which should - * be an admin of a profile on the device. If no component name is provided, look up the - * component name and fill it in for the caller. - * - * Note: this method should only be called when the expected caller is an admin. - * - * @throws SecurityException if the caller is not an active admin. - */ - private CallerIdentity getAdminCallerIdentity(@Nullable ComponentName adminComponent) { - if (adminComponent == null) { - ActiveAdmin admin = getActiveAdminOfCaller(); - if (admin != null) { - return getCallerIdentity(admin.info.getComponent()); - } - throw new SecurityException("Caller is not an active admin"); - } else { - return getCallerIdentity(adminComponent); - } - } - /** - * Creates a new {@link CallerIdentity} object to represent the caller's identity. If no - * component name is provided, look up the component name and fill it in for the caller. - * - * Note: this method should only be called when the caller may not be an admin. If the caller - * is not an admin, the ComponentName in the returned identity will be null. - */ - private CallerIdentity getNonPrivilegedOrAdminCallerIdentity( - @Nullable ComponentName adminComponent) { - if (adminComponent == null) { - ActiveAdmin admin = getActiveAdminOfCaller(); - if (admin != null) { - adminComponent = admin.info.getComponent(); - } else { - return getCallerIdentity(); + if (callerPackage != null) { + if (!isCallingFromPackage(callerPackage, callerUid)) { + throw new SecurityException( + String.format("Caller with uid %d is not %s", callerUid, callerPackage)); } } - return getCallerIdentity(adminComponent); - } + if (adminComponent != null) { + final DevicePolicyData policy = getUserData(UserHandle.getUserId(callerUid)); + ActiveAdmin admin = policy.mAdminMap.get(adminComponent); - /** - * Creates a new {@link CallerIdentity} object to represent the caller's identity. If no - * package name is provided, look up the package name and fill it in for the caller. - * - * Note: this method should only be called when the expected caller is an admin. - * - * @throws SecurityException if the caller is not an active admin. - */ - private CallerIdentity getAdminCallerIdentityUsingPackage(@Nullable String callerPackage) { - if (callerPackage == null) { - ActiveAdmin admin = getActiveAdminOfCaller(); - if (admin != null) { - return getCallerIdentity(admin.info.getPackageName()); + if (admin == null) { + throw new SecurityException(String.format( + "No active admin for %s", adminComponent)); } - throw new SecurityException("Caller is not an active admin"); - } - return getCallerIdentity(callerPackage); - } - - /** - * Creates a new {@link CallerIdentity} object to represent the caller's identity. If no - * package name is provided, look up the package name and fill it in for the caller. - */ - private CallerIdentity getNonPrivilegedOrAdminCallerIdentityUsingPackage( - @Nullable String callerPackage) { - if (callerPackage == null) { - ActiveAdmin admin = getActiveAdminOfCaller(); - if (admin != null) { - callerPackage = admin.info.getPackageName(); + if (admin.getUid() != callerUid) { + throw new SecurityException(String.format( + "Admin %s is not owned by uid %d", adminComponent, callerUid)); + } + if (callerPackage != null) { + Preconditions.checkArgument(callerPackage.equals(adminComponent.getPackageName())); } else { - return getCallerIdentity(); + callerPackage = adminComponent.getPackageName(); } } - return getCallerIdentity(callerPackage); - } - - /** - * Creates a new {@link CallerIdentity} object to represent the caller's identity. - * If an {@code adminComponent} is specified, then the caller must be an admin and - * the provided component name must match the caller's UID. - * - * If a package name is provided, then the caller doesn't have to be an admin, and the - * provided package must belong to the caller's UID. - * - * If neither is provided, the caller identity is returned as-is. - * - * Note: this method should only be called when the caller may not be an admin. If the caller - * is not an admin, the ComponentName in the returned identity will be null. - */ - private CallerIdentity getNonPrivilegedOrAdminCallerIdentity( - @Nullable ComponentName adminComponent, - @Nullable String callerPackage) { - if (adminComponent != null) { - return getCallerIdentity(adminComponent); - } - return getNonPrivilegedOrAdminCallerIdentityUsingPackage(callerPackage); - } - - /** - * Retrieves the active admin of the caller. This method should not be called directly and - * should only be called by {@link #getAdminCallerIdentity}, - * {@link #getNonPrivilegedOrAdminCallerIdentity}, {@link #getAdminCallerIdentityUsingPackage} - * or {@link #getNonPrivilegedOrAdminCallerIdentityUsingPackage}. - */ - private ActiveAdmin getActiveAdminOfCaller() { - final int callerUid = mInjector.binderGetCallingUid(); - final DevicePolicyData policy = getUserData(UserHandle.getUserId(callerUid)); - for (ActiveAdmin admin : policy.mAdminList) { - if (admin.getUid() == callerUid) { - return admin; - } - } - return null; + return new CallerIdentity(callerUid, callerPackage, adminComponent); } /** @@ -3192,6 +3085,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } } + private void checkAllUsersAreAffiliatedWithDevice() { + Preconditions.checkCallAuthorization(areAllUsersAffiliatedWithDeviceLocked(), + "operation not allowed when device has unaffiliated users"); + } + @Override public boolean isAdminActive(ComponentName adminReceiver, int userHandle) { if (!mHasFeature) { @@ -4307,7 +4205,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override @PasswordComplexity public int getPasswordComplexity(boolean parent) { - final CallerIdentity caller = getNonPrivilegedOrAdminCallerIdentity(null); + final CallerIdentity caller = getCallerIdentity(); DevicePolicyEventLogger .createEvent(DevicePolicyEnums.GET_USER_PASSWORD_COMPLEXITY_LEVEL) .setStrings(parent ? CALLED_FROM_PARENT : NOT_CALLED_FROM_PARENT, @@ -4315,15 +4213,18 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { mInjector.binderGetCallingUid())) .write(); - Preconditions.checkCallAuthorization(!parent || (isDeviceOwner(caller) - || isProfileOwner(caller) || isSystemUid(caller)), - "Only profile owner, device owner and system may call this method."); enforceUserUnlocked(caller.getUserId()); - Preconditions.checkCallAuthorization( - hasCallingOrSelfPermission(REQUEST_PASSWORD_COMPLEXITY) - || isDeviceOwner(caller) || isProfileOwner(caller), - "Must have " + REQUEST_PASSWORD_COMPLEXITY - + " permission, or be a profile owner or device owner."); + if (parent) { + Preconditions.checkCallAuthorization( + isDeviceOwner(caller) || isProfileOwner(caller) || isSystemUid(caller), + "Only profile owner, device owner and system may call this method on parent."); + } else { + Preconditions.checkCallAuthorization( + hasCallingOrSelfPermission(REQUEST_PASSWORD_COMPLEXITY) + || isDeviceOwner(caller) || isProfileOwner(caller), + "Must have " + REQUEST_PASSWORD_COMPLEXITY + + " permission, or be a profile owner or device owner."); + } synchronized (getLockObject()) { final int credentialOwner = getCredentialOwner(caller.getUserId(), parent); @@ -4342,7 +4243,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { Preconditions.checkArgument(allowedModes.contains(passwordComplexity), "Provided complexity is not one of the allowed values."); - final CallerIdentity caller = getAdminCallerIdentity(null); + final CallerIdentity caller = getCallerIdentity(); Preconditions.checkCallAuthorization(isDeviceOwner(caller) || isProfileOwner(caller)); Preconditions.checkArgument(!calledOnParent || isProfileOwner(caller)); @@ -4386,11 +4287,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { return PASSWORD_COMPLEXITY_NONE; } - final CallerIdentity caller = getAdminCallerIdentity(null); + final CallerIdentity caller = getCallerIdentity(); Preconditions.checkCallAuthorization( isDeviceOwner(caller) || isProfileOwner(caller)); - Preconditions.checkArgument(!calledOnParent || hasProfileOwner(caller.getUserId())); + Preconditions.checkArgument(!calledOnParent || isProfileOwner(caller)); synchronized (getLockObject()) { final ActiveAdmin requiredAdmin = getParentOfAdminIfRequired( @@ -5626,15 +5527,18 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { public List<String> getDelegatedScopes(ComponentName who, String delegatePackage) throws SecurityException { Objects.requireNonNull(delegatePackage, "Delegate package is null"); - final CallerIdentity caller = getNonPrivilegedOrAdminCallerIdentity(who, delegatePackage); + final CallerIdentity caller = getCallerIdentity(who); // Ensure the caller may call this method: - // * Either it's an admin - // * Or it's an app identified by its calling package name (the - // getNonPrivilegedOrAdminCallerIdentity method validated the UID and package match). - Preconditions.checkCallAuthorization( - (caller.hasAdminComponent() && (isProfileOwner(caller) || isDeviceOwner(caller))) - || delegatePackage != null); + // * Either it's a profile owner / device owner, if componentName is provided + // * Or it's an app querying its own delegation scopes + if (caller.hasAdminComponent()) { + Preconditions.checkCallAuthorization(isProfileOwner(caller) || isDeviceOwner(caller)); + } else { + Preconditions.checkCallAuthorization(isPackage(caller, delegatePackage), + String.format("Caller with uid %d is not %s", caller.getUid(), + delegatePackage)); + } synchronized (getLockObject()) { final DevicePolicyData policy = getUserData(caller.getUserId()); // Retrieve the scopes assigned to delegatePackage, or null if no scope was given. @@ -5924,12 +5828,16 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override public boolean isAlwaysOnVpnLockdownEnabled(ComponentName admin) throws SecurityException { - Objects.requireNonNull(admin, "ComponentName is null"); - - final CallerIdentity caller = getNonPrivilegedOrAdminCallerIdentity(admin); - Preconditions.checkCallAuthorization((caller.hasAdminComponent() - && (isDeviceOwner(caller) || isProfileOwner(caller))) - || hasCallingPermission(PERMISSION_MAINLINE_NETWORK_STACK)); + final CallerIdentity caller; + if (hasCallingPermission(PERMISSION_MAINLINE_NETWORK_STACK)) { + // TODO: CaptivePortalLoginActivity erroneously calls this method with a non-admin + // ComponentName, so we have to use a separate code path for it: + // getCallerIdentity(admin) will throw if the admin is not in the known admin list. + caller = getCallerIdentity(); + } else { + caller = getCallerIdentity(admin); + Preconditions.checkCallAuthorization(isDeviceOwner(caller) || isProfileOwner(caller)); + } return mInjector.binderWithCleanCallingIdentity( () -> mInjector.getConnectivityManager().isVpnLockdownEnabled(caller.getUserId())); @@ -6209,6 +6117,10 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { return getFrpManagementAgentUid() != -1; } + /** + * Called by a privileged caller holding {@code BIND_DEVICE_ADMIN} permission to retrieve + * the remove warning for the given device admin. + */ @Override public void getRemoveWarning(ComponentName comp, final RemoteCallback result, int userHandle) { if (!mHasFeature) { @@ -6649,13 +6561,13 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { * active admins. */ @Override - public boolean getStorageEncryption(ComponentName who, int userHandle) { + public boolean getStorageEncryption(@Nullable ComponentName who, int userHandle) { if (!mHasFeature) { return false; } Preconditions.checkArgumentNonnegative(userHandle, "Invalid userId"); - final CallerIdentity caller = getAdminCallerIdentity(who); + final CallerIdentity caller = getCallerIdentity(who); Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(caller, userHandle)); synchronized (getLockObject()) { @@ -6689,12 +6601,9 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } Preconditions.checkArgumentNonnegative(userHandle, "Invalid userId"); - final CallerIdentity caller = getAdminCallerIdentityUsingPackage(callerPackage); + final CallerIdentity caller = getCallerIdentity(callerPackage); Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(caller, userHandle)); - // It's not critical here, but let's make sure the package name is correct, in case - // we start using it for different purposes. - ensureCallerPackage(callerPackage); final ApplicationInfo ai; try { @@ -7034,7 +6943,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { // next boot? Might not be needed given that this still requires user consent. final CallerIdentity caller = getCallerIdentity(who); Preconditions.checkCallAuthorization(isDeviceOwner(caller)); - Preconditions.checkCallAuthorization(areAllUsersAffiliatedWithDeviceLocked()); + checkAllUsersAreAffiliatedWithDevice(); if (mBugreportCollectionManager.requestBugreport()) { DevicePolicyEventLogger @@ -7571,6 +7480,10 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { return isProfileOwner(caller) && caller.getUserHandle().isSystem(); } + private boolean isPackage(CallerIdentity caller, String packageName) { + return isCallingFromPackage(packageName, caller.getUid()); + } + @Override public ComponentName getDeviceOwnerComponent(boolean callingUserOnly) { if (!mHasFeature) { @@ -8521,8 +8434,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { return true; } - private void enforceCanCallLockTaskLocked(ComponentName who) { - final CallerIdentity caller = getAdminCallerIdentity(who); + private void enforceCanCallLockTaskLocked(CallerIdentity caller) { Preconditions.checkCallAuthorization(isProfileOwner(caller) || isDeviceOwner(caller)); final int userId = caller.getUserId(); @@ -8531,22 +8443,6 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } } - private void ensureCallerPackage(@Nullable String packageName) { - if (packageName == null) { - enforceSystemCaller("omit package name"); - } else { - final int callingUid = mInjector.binderGetCallingUid(); - final int userId = mInjector.userHandleGetCallingUserId(); - try { - final ApplicationInfo ai = mIPackageManager.getApplicationInfo( - packageName, 0, userId); - Preconditions.checkState(ai.uid == callingUid, "Unmatching package name"); - } catch (RemoteException e) { - // Shouldn't happen - } - } - } - private boolean isCallerWithSystemUid() { return UserHandle.isSameApp(mInjector.binderGetCallingUid(), Process.SYSTEM_UID); } @@ -8643,6 +8539,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { pw.println(policy.mUserControlDisabledPackages); pw.print("mAppsSuspended="); pw.println(policy.mAppsSuspended); pw.print("mUserSetupComplete="); pw.println(policy.mUserSetupComplete); + pw.print("mAffiliationIds="); pw.println(policy.mAffiliationIds); pw.decreaseIndent(); } } @@ -8842,7 +8739,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { Objects.requireNonNull(agent, "agent null"); Preconditions.checkArgumentNonnegative(userHandle, "Invalid userId"); - final CallerIdentity caller = getAdminCallerIdentity(admin); + final CallerIdentity caller = getCallerIdentity(); Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(caller, userHandle)); synchronized (getLockObject()) { @@ -10551,10 +10448,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { throws SecurityException { Objects.requireNonNull(who, "ComponentName is null"); Objects.requireNonNull(packages, "packages is null"); + final CallerIdentity caller = getCallerIdentity(who); synchronized (getLockObject()) { - enforceCanCallLockTaskLocked(who); - final int userHandle = mInjector.userHandleGetCallingUserId(); + enforceCanCallLockTaskLocked(caller); + final int userHandle = caller.getUserId(); setLockTaskPackagesLocked(userHandle, new ArrayList<>(Arrays.asList(packages))); } } @@ -10571,10 +10469,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override public String[] getLockTaskPackages(ComponentName who) { Objects.requireNonNull(who, "ComponentName is null"); + final CallerIdentity caller = getCallerIdentity(who); + final int userHandle = caller.getUserId(); - final int userHandle = mInjector.binderGetCallingUserHandle().getIdentifier(); synchronized (getLockObject()) { - enforceCanCallLockTaskLocked(who); + enforceCanCallLockTaskLocked(caller); final List<String> packages = getUserData(userHandle).mLockTaskPackages; return packages.toArray(new String[packages.size()]); } @@ -10601,9 +10500,10 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { Preconditions.checkArgument(hasHome || !hasNotification, "Cannot use LOCK_TASK_FEATURE_NOTIFICATIONS without LOCK_TASK_FEATURE_HOME"); - final int userHandle = mInjector.userHandleGetCallingUserId(); + final CallerIdentity caller = getCallerIdentity(who); + final int userHandle = caller.getUserId(); synchronized (getLockObject()) { - enforceCanCallLockTaskLocked(who); + enforceCanCallLockTaskLocked(caller); setLockTaskFeaturesLocked(userHandle, flags); } } @@ -10618,9 +10518,10 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override public int getLockTaskFeatures(ComponentName who) { Objects.requireNonNull(who, "ComponentName is null"); - final int userHandle = mInjector.userHandleGetCallingUserId(); + final CallerIdentity caller = getCallerIdentity(who); + final int userHandle = caller.getUserId(); synchronized (getLockObject()) { - enforceCanCallLockTaskLocked(who); + enforceCanCallLockTaskLocked(caller); return getUserData(userHandle).mLockTaskFeatures; } } @@ -11069,7 +10970,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override public boolean setStatusBarDisabled(ComponentName who, boolean disabled) { - final CallerIdentity caller = getAdminCallerIdentity(who); + final CallerIdentity caller = getCallerIdentity(who); Preconditions.checkCallAuthorization(isProfileOwner(caller) || isDeviceOwner(caller)); int userId = caller.getUserId(); @@ -12832,7 +12733,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } final Set<String> affiliationIds = new ArraySet<>(ids); - final CallerIdentity caller = getAdminCallerIdentity(admin); + final CallerIdentity caller = getCallerIdentity(admin); Preconditions.checkCallAuthorization(isProfileOwner(caller) || isDeviceOwner(caller)); final int callingUserId = caller.getUserId(); @@ -12925,13 +12826,6 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { }); } - private boolean canStartSecurityLogging() { - synchronized (getLockObject()) { - return isOrganizationOwnedDeviceWithManagedProfile() - || areAllUsersAffiliatedWithDeviceLocked(); - } - } - private @UserIdInt int getSecurityLoggingEnabledUser() { synchronized (getLockObject()) { if (mOwners.hasDeviceOwner()) { @@ -13651,7 +13545,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { final CallerIdentity caller = getCallerIdentity(admin, packageName); Preconditions.checkCallAuthorization((caller.hasAdminComponent() && isDeviceOwner(caller)) || (caller.hasPackage() && isCallerDelegate(caller, DELEGATION_NETWORK_LOGGING))); - Preconditions.checkCallAuthorization(areAllUsersAffiliatedWithDeviceLocked()); + checkAllUsersAreAffiliatedWithDevice(); synchronized (getLockObject()) { if (mNetworkLogger == null || !isNetworkLoggingEnabledInternalLocked()) { @@ -13787,7 +13681,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (token == null || token.length < 32) { throw new IllegalArgumentException("token must be at least 32-byte long"); } - final CallerIdentity caller = getAdminCallerIdentity(admin); + final CallerIdentity caller = getCallerIdentity(admin); Preconditions.checkCallAuthorization(isProfileOwner(caller) || isDeviceOwner(caller)); synchronized (getLockObject()) { @@ -13811,7 +13705,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (!mHasFeature || !mLockPatternUtils.hasSecureLockScreen()) { return false; } - final CallerIdentity caller = getAdminCallerIdentity(admin); + final CallerIdentity caller = getCallerIdentity(admin); Preconditions.checkCallAuthorization(isProfileOwner(caller) || isDeviceOwner(caller)); synchronized (getLockObject()) { @@ -13836,7 +13730,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (!mHasFeature || !mLockPatternUtils.hasSecureLockScreen()) { return false; } - final CallerIdentity caller = getAdminCallerIdentity(admin); + final CallerIdentity caller = getCallerIdentity(admin); Preconditions.checkCallAuthorization(isProfileOwner(caller) || isDeviceOwner(caller)); synchronized (getLockObject()) { @@ -13861,7 +13755,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } Objects.requireNonNull(token); - final CallerIdentity caller = getAdminCallerIdentity(admin); + final CallerIdentity caller = getCallerIdentity(admin); Preconditions.checkCallAuthorization(isProfileOwner(caller) || isDeviceOwner(caller)); synchronized (getLockObject()) { diff --git a/services/tests/mockingservicestests/Android.bp b/services/tests/mockingservicestests/Android.bp index a2e6698963a4..8fc5c085999e 100644 --- a/services/tests/mockingservicestests/Android.bp +++ b/services/tests/mockingservicestests/Android.bp @@ -20,6 +20,7 @@ android_test { static_libs: [ "services.core", "services.net", + "services.usage", "service-jobscheduler", "service-permission.impl", "service-blobstore", diff --git a/services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java b/services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java index ebd4a4c5378f..f375421043fd 100644 --- a/services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java @@ -16,6 +16,7 @@ package com.android.server; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.any; import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyBoolean; import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyInt; import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyLong; @@ -44,6 +45,7 @@ import android.os.SystemProperties; import android.os.UserHandle; import android.provider.DeviceConfig; import android.provider.Settings; +import android.util.ArraySet; import com.android.dx.mockito.inline.extended.ExtendedMockito; import com.android.server.PackageWatchdog.PackageHealthObserverImpact; @@ -63,6 +65,7 @@ import org.mockito.stubbing.Answer; import java.util.Arrays; import java.util.HashMap; +import java.util.HashSet; import java.util.List; /** @@ -79,9 +82,11 @@ public class RescuePartyTest { private static final String PROP_DISABLE_RESCUE = "persist.sys.disable_rescue"; private static final String CALLING_PACKAGE1 = "com.package.name1"; private static final String CALLING_PACKAGE2 = "com.package.name2"; + private static final String CALLING_PACKAGE3 = "com.package.name3"; private static final String NAMESPACE1 = "namespace1"; private static final String NAMESPACE2 = "namespace2"; private static final String NAMESPACE3 = "namespace3"; + private static final String NAMESPACE4 = "namespace4"; private static final String PROP_DEVICE_CONFIG_DISABLE_FLAG = "persist.device_config.configuration.disable_rescue_party"; private static final String PROP_DISABLE_FACTORY_RESET_FLAG = @@ -89,6 +94,8 @@ public class RescuePartyTest { private MockitoSession mSession; private HashMap<String, String> mSystemSettingsMap; + //Records the namespaces wiped by setProperties(). + private HashSet<String> mNamespacesWiped; @Mock(answer = Answers.RETURNS_DEEP_STUBS) private Context mMockContext; @@ -119,6 +126,7 @@ public class RescuePartyTest { .spyStatic(PackageWatchdog.class) .startMocking(); mSystemSettingsMap = new HashMap<>(); + mNamespacesWiped = new HashSet<>(); when(mMockContext.getContentResolver()).thenReturn(mMockContentResolver); // Reset observer instance to get new mock context on every run @@ -167,6 +175,16 @@ public class RescuePartyTest { anyBoolean())); doAnswer((Answer<Void>) invocationOnMock -> null) .when(() -> DeviceConfig.resetToDefaults(anyInt(), anyString())); + doAnswer((Answer<Boolean>) invocationOnMock -> { + DeviceConfig.Properties properties = invocationOnMock.getArgument(0); + String namespace = properties.getNamespace(); + // record a wipe + if (properties.getKeyset().isEmpty()) { + mNamespacesWiped.add(namespace); + } + return true; + } + ).when(() -> DeviceConfig.setProperties(any(DeviceConfig.Properties.class))); // Mock PackageWatchdog doAnswer((Answer<PackageWatchdog>) invocationOnMock -> mMockPackageWatchdog) @@ -174,8 +192,6 @@ public class RescuePartyTest { doReturn(CURRENT_NETWORK_TIME_MILLIS).when(() -> RescueParty.getElapsedRealtime()); - SystemProperties.set(RescueParty.PROP_RESCUE_LEVEL, - Integer.toString(RescueParty.LEVEL_NONE)); SystemProperties.set(RescueParty.PROP_RESCUE_BOOT_COUNT, Integer.toString(0)); SystemProperties.set(RescueParty.PROP_ENABLE_RESCUE, Boolean.toString(true)); SystemProperties.set(PROP_DEVICE_CONFIG_DISABLE_FLAG, Boolean.toString(false)); @@ -193,12 +209,10 @@ public class RescuePartyTest { mMonitorCallbackCaptor.capture())); HashMap<String, Integer> verifiedTimesMap = new HashMap<String, Integer>(); - noteBoot(); + noteBoot(1); verifySettingsResets(Settings.RESET_MODE_UNTRUSTED_DEFAULTS, /*resetNamespaces=*/ null, verifiedTimesMap); - assertEquals(RescueParty.LEVEL_RESET_SETTINGS_UNTRUSTED_DEFAULTS, - SystemProperties.getInt(RescueParty.PROP_RESCUE_LEVEL, RescueParty.LEVEL_NONE)); // Record DeviceConfig accesses RescuePartyObserver observer = RescuePartyObserver.getInstance(mMockContext); @@ -208,24 +222,19 @@ public class RescuePartyTest { final String[] expectedAllResetNamespaces = new String[]{NAMESPACE1, NAMESPACE2}; - noteBoot(); + noteBoot(2); verifySettingsResets(Settings.RESET_MODE_UNTRUSTED_CHANGES, expectedAllResetNamespaces, verifiedTimesMap); - assertEquals(RescueParty.LEVEL_RESET_SETTINGS_UNTRUSTED_CHANGES, - SystemProperties.getInt(RescueParty.PROP_RESCUE_LEVEL, RescueParty.LEVEL_NONE)); - noteBoot(); + noteBoot(3); verifySettingsResets(Settings.RESET_MODE_TRUSTED_DEFAULTS, expectedAllResetNamespaces, verifiedTimesMap); - assertEquals(RescueParty.LEVEL_RESET_SETTINGS_TRUSTED_DEFAULTS, - SystemProperties.getInt(RescueParty.PROP_RESCUE_LEVEL, RescueParty.LEVEL_NONE)); - noteBoot(); + noteBoot(4); - assertEquals(LEVEL_FACTORY_RESET, - SystemProperties.getInt(RescueParty.PROP_RESCUE_LEVEL, RescueParty.LEVEL_NONE)); + assertTrue(RescueParty.isAttemptingFactoryReset()); } @Test @@ -364,24 +373,12 @@ public class RescuePartyTest { @Test public void testIsAttemptingFactoryReset() { for (int i = 0; i < LEVEL_FACTORY_RESET; i++) { - noteBoot(); + noteBoot(i + 1); } assertTrue(RescueParty.isAttemptingFactoryReset()); } @Test - public void testOnSettingsProviderPublishedExecutesRescueLevels() { - SystemProperties.set(RescueParty.PROP_RESCUE_LEVEL, Integer.toString(1)); - - RescueParty.onSettingsProviderPublished(mMockContext); - - verifySettingsResets(Settings.RESET_MODE_UNTRUSTED_DEFAULTS, /*resetNamespaces=*/ null, - /*configResetVerifiedTimesMap=*/ null); - assertEquals(RescueParty.LEVEL_RESET_SETTINGS_UNTRUSTED_DEFAULTS, - SystemProperties.getInt(RescueParty.PROP_RESCUE_LEVEL, RescueParty.LEVEL_NONE)); - } - - @Test public void testNativeRescuePartyResets() { doReturn(true).when(() -> SettingsToPropertiesMapper.isNativeFlagsResetPerformed()); doReturn(FAKE_RESET_NATIVE_NAMESPACES).when( @@ -425,7 +422,7 @@ public class RescuePartyTest { SystemProperties.set(PROP_DISABLE_FACTORY_RESET_FLAG, Boolean.toString(true)); for (int i = 0; i < LEVEL_FACTORY_RESET; i++) { - noteBoot(); + noteBoot(i + 1); } assertFalse(RescueParty.isAttemptingFactoryReset()); @@ -463,29 +460,128 @@ public class RescuePartyTest { public void testBootLoopLevels() { RescuePartyObserver observer = RescuePartyObserver.getInstance(mMockContext); - /* - Ensure that the returned user impact corresponds with the user impact of the next available - rescue level, not the current one. - */ - SystemProperties.set(RescueParty.PROP_RESCUE_LEVEL, Integer.toString( - RescueParty.LEVEL_NONE)); - assertEquals(observer.onBootLoop(), PackageHealthObserverImpact.USER_IMPACT_LOW); - - SystemProperties.set(RescueParty.PROP_RESCUE_LEVEL, Integer.toString( - RescueParty.LEVEL_RESET_SETTINGS_UNTRUSTED_DEFAULTS)); - assertEquals(observer.onBootLoop(), PackageHealthObserverImpact.USER_IMPACT_LOW); - - SystemProperties.set(RescueParty.PROP_RESCUE_LEVEL, Integer.toString( - RescueParty.LEVEL_RESET_SETTINGS_UNTRUSTED_CHANGES)); - assertEquals(observer.onBootLoop(), PackageHealthObserverImpact.USER_IMPACT_HIGH); - - SystemProperties.set(RescueParty.PROP_RESCUE_LEVEL, Integer.toString( - RescueParty.LEVEL_RESET_SETTINGS_TRUSTED_DEFAULTS)); - assertEquals(observer.onBootLoop(), PackageHealthObserverImpact.USER_IMPACT_HIGH); - - SystemProperties.set(RescueParty.PROP_RESCUE_LEVEL, Integer.toString( - LEVEL_FACTORY_RESET)); - assertEquals(observer.onBootLoop(), PackageHealthObserverImpact.USER_IMPACT_HIGH); + assertEquals(observer.onBootLoop(0), PackageHealthObserverImpact.USER_IMPACT_NONE); + assertEquals(observer.onBootLoop(1), PackageHealthObserverImpact.USER_IMPACT_LOW); + assertEquals(observer.onBootLoop(2), PackageHealthObserverImpact.USER_IMPACT_LOW); + assertEquals(observer.onBootLoop(3), PackageHealthObserverImpact.USER_IMPACT_HIGH); + assertEquals(observer.onBootLoop(4), PackageHealthObserverImpact.USER_IMPACT_HIGH); + assertEquals(observer.onBootLoop(5), PackageHealthObserverImpact.USER_IMPACT_HIGH); + } + + @Test + public void testResetDeviceConfigForPackagesOnlyRuntimeMap() { + RescueParty.onSettingsProviderPublished(mMockContext); + verify(() -> Settings.Config.registerMonitorCallback(eq(mMockContentResolver), + mMonitorCallbackCaptor.capture())); + + // Record DeviceConfig accesses + RescuePartyObserver observer = RescuePartyObserver.getInstance(mMockContext); + RemoteCallback monitorCallback = mMonitorCallbackCaptor.getValue(); + monitorCallback.sendResult(getConfigAccessBundle(CALLING_PACKAGE1, NAMESPACE1)); + monitorCallback.sendResult(getConfigAccessBundle(CALLING_PACKAGE1, NAMESPACE2)); + monitorCallback.sendResult(getConfigAccessBundle(CALLING_PACKAGE2, NAMESPACE2)); + monitorCallback.sendResult(getConfigAccessBundle(CALLING_PACKAGE2, NAMESPACE3)); + // Fake DeviceConfig value changes + monitorCallback.sendResult(getConfigNamespaceUpdateBundle(NAMESPACE1)); + monitorCallback.sendResult(getConfigNamespaceUpdateBundle(NAMESPACE2)); + monitorCallback.sendResult(getConfigNamespaceUpdateBundle(NAMESPACE3)); + + doReturn("").when(() -> DeviceConfig.getString( + eq(RescueParty.NAMESPACE_CONFIGURATION), + eq(RescueParty.NAMESPACE_TO_PACKAGE_MAPPING_FLAG), + eq(""))); + + RescueParty.resetDeviceConfigForPackages(Arrays.asList(new String[]{CALLING_PACKAGE1})); + ArraySet<String> expectedNamespacesWiped = new ArraySet<String>( + Arrays.asList(new String[]{NAMESPACE1, NAMESPACE2})); + assertEquals(mNamespacesWiped, expectedNamespacesWiped); + } + + @Test + public void testResetDeviceConfigForPackagesOnlyPresetMap() { + RescueParty.onSettingsProviderPublished(mMockContext); + verify(() -> Settings.Config.registerMonitorCallback(eq(mMockContentResolver), + mMonitorCallbackCaptor.capture())); + + String presetMapping = NAMESPACE1 + ":" + CALLING_PACKAGE1 + "," + + NAMESPACE2 + ":" + CALLING_PACKAGE2 + "," + + NAMESPACE3 + ":" + CALLING_PACKAGE1; + doReturn(presetMapping).when(() -> DeviceConfig.getString( + eq(RescueParty.NAMESPACE_CONFIGURATION), + eq(RescueParty.NAMESPACE_TO_PACKAGE_MAPPING_FLAG), + eq(""))); + + RescueParty.resetDeviceConfigForPackages(Arrays.asList(new String[]{CALLING_PACKAGE1})); + ArraySet<String> expectedNamespacesWiped = new ArraySet<String>( + Arrays.asList(new String[]{NAMESPACE1, NAMESPACE3})); + assertEquals(mNamespacesWiped, expectedNamespacesWiped); + } + + @Test + public void testResetDeviceConfigForPackagesBothMaps() { + RescueParty.onSettingsProviderPublished(mMockContext); + verify(() -> Settings.Config.registerMonitorCallback(eq(mMockContentResolver), + mMonitorCallbackCaptor.capture())); + + // Record DeviceConfig accesses + RescuePartyObserver observer = RescuePartyObserver.getInstance(mMockContext); + RemoteCallback monitorCallback = mMonitorCallbackCaptor.getValue(); + monitorCallback.sendResult(getConfigAccessBundle(CALLING_PACKAGE1, NAMESPACE1)); + monitorCallback.sendResult(getConfigAccessBundle(CALLING_PACKAGE1, NAMESPACE2)); + monitorCallback.sendResult(getConfigAccessBundle(CALLING_PACKAGE2, NAMESPACE2)); + monitorCallback.sendResult(getConfigAccessBundle(CALLING_PACKAGE2, NAMESPACE3)); + monitorCallback.sendResult(getConfigAccessBundle(CALLING_PACKAGE3, NAMESPACE4)); + // Fake DeviceConfig value changes + monitorCallback.sendResult(getConfigNamespaceUpdateBundle(NAMESPACE1)); + monitorCallback.sendResult(getConfigNamespaceUpdateBundle(NAMESPACE2)); + monitorCallback.sendResult(getConfigNamespaceUpdateBundle(NAMESPACE3)); + monitorCallback.sendResult(getConfigNamespaceUpdateBundle(NAMESPACE4)); + + String presetMapping = NAMESPACE1 + ":" + CALLING_PACKAGE1 + "," + + NAMESPACE2 + ":" + CALLING_PACKAGE2 + "," + + NAMESPACE4 + ":" + CALLING_PACKAGE3; + doReturn(presetMapping).when(() -> DeviceConfig.getString( + eq(RescueParty.NAMESPACE_CONFIGURATION), + eq(RescueParty.NAMESPACE_TO_PACKAGE_MAPPING_FLAG), + eq(""))); + + RescueParty.resetDeviceConfigForPackages( + Arrays.asList(new String[]{CALLING_PACKAGE1, CALLING_PACKAGE2})); + ArraySet<String> expectedNamespacesWiped = new ArraySet<String>( + Arrays.asList(new String[]{NAMESPACE1, NAMESPACE2, NAMESPACE3})); + assertEquals(mNamespacesWiped, expectedNamespacesWiped); + } + + @Test + public void testResetDeviceConfigNoExceptionWhenFlagMalformed() { + RescueParty.onSettingsProviderPublished(mMockContext); + verify(() -> Settings.Config.registerMonitorCallback(eq(mMockContentResolver), + mMonitorCallbackCaptor.capture())); + + // Record DeviceConfig accesses + RescuePartyObserver observer = RescuePartyObserver.getInstance(mMockContext); + RemoteCallback monitorCallback = mMonitorCallbackCaptor.getValue(); + monitorCallback.sendResult(getConfigAccessBundle(CALLING_PACKAGE1, NAMESPACE1)); + monitorCallback.sendResult(getConfigAccessBundle(CALLING_PACKAGE2, NAMESPACE3)); + monitorCallback.sendResult(getConfigAccessBundle(CALLING_PACKAGE3, NAMESPACE4)); + // Fake DeviceConfig value changes + monitorCallback.sendResult(getConfigNamespaceUpdateBundle(NAMESPACE1)); + monitorCallback.sendResult(getConfigNamespaceUpdateBundle(NAMESPACE2)); + monitorCallback.sendResult(getConfigNamespaceUpdateBundle(NAMESPACE3)); + monitorCallback.sendResult(getConfigNamespaceUpdateBundle(NAMESPACE4)); + + String invalidPresetMapping = NAMESPACE2 + ":" + CALLING_PACKAGE2 + "," + + NAMESPACE1 + "." + CALLING_PACKAGE2; + doReturn(invalidPresetMapping).when(() -> DeviceConfig.getString( + eq(RescueParty.NAMESPACE_CONFIGURATION), + eq(RescueParty.NAMESPACE_TO_PACKAGE_MAPPING_FLAG), + eq(""))); + + RescueParty.resetDeviceConfigForPackages( + Arrays.asList(new String[]{CALLING_PACKAGE1, CALLING_PACKAGE2})); + ArraySet<String> expectedNamespacesWiped = new ArraySet<String>( + Arrays.asList(new String[]{NAMESPACE1, NAMESPACE3})); + assertEquals(mNamespacesWiped, expectedNamespacesWiped); } private void verifySettingsResets(int resetMode, String[] resetNamespaces, @@ -513,8 +609,8 @@ public class RescuePartyTest { } } - private void noteBoot() { - RescuePartyObserver.getInstance(mMockContext).executeBootLoopMitigation(); + private void noteBoot(int mitigationCount) { + RescuePartyObserver.getInstance(mMockContext).executeBootLoopMitigation(mitigationCount); } private void notePersistentAppCrash(int mitigationCount) { diff --git a/services/tests/mockingservicestests/src/com/android/server/usage/UsageStatsServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/usage/UsageStatsServiceTest.java new file mode 100644 index 000000000000..c9fcd0233bef --- /dev/null +++ b/services/tests/mockingservicestests/src/com/android/server/usage/UsageStatsServiceTest.java @@ -0,0 +1,134 @@ +/* + * 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.server.usage; + +import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; + +import static org.junit.Assert.assertNull; +import static org.junit.Assert.fail; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.Mockito.mock; + +import android.app.ActivityManager; +import android.app.IActivityManager; +import android.app.usage.UsageEvents; +import android.app.usage.UsageStatsManagerInternal; +import android.content.Context; +import android.os.RemoteException; + +import androidx.test.runner.AndroidJUnit4; + +import com.android.server.LocalServices; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoSession; +import org.mockito.quality.Strictness; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +@RunWith(AndroidJUnit4.class) +public class UsageStatsServiceTest { + private static final long TIMEOUT = 5000; + + private UsageStatsService mService; + + private MockitoSession mMockingSession; + @Mock + private Context mContext; + + private static class TestInjector extends UsageStatsService.Injector { + AppStandbyInternal getAppStandbyController(Context context) { + return mock(AppStandbyInternal.class); + } + } + + @Before + public void setUp() { + mMockingSession = mockitoSession() + .initMocks(this) + .strictness(Strictness.LENIENT) + .startMocking(); + IActivityManager activityManager = ActivityManager.getService(); + spyOn(activityManager); + try { + doNothing().when(activityManager).registerUidObserver(any(), anyInt(), anyInt(), any()); + } catch (RemoteException e) { + fail("registerUidObserver threw exception: " + e.getMessage()); + } + mService = new UsageStatsService(mContext, new TestInjector()); + spyOn(mService); + doNothing().when(mService).publishBinderServices(); + mService.onStart(); + } + + @Test + public void testUsageEventListener() throws Exception { + TestUsageEventListener listener = new TestUsageEventListener(); + UsageStatsManagerInternal usmi = LocalServices.getService(UsageStatsManagerInternal.class); + usmi.registerListener(listener); + + UsageEvents.Event event = new UsageEvents.Event(UsageEvents.Event.CONFIGURATION_CHANGE, 10); + usmi.reportEvent("com.android.test", 10, event.getEventType()); + listener.setExpectation(10, event); + listener.mCountDownLatch.await(TIMEOUT, TimeUnit.MILLISECONDS); + + usmi.unregisterListener(listener); + listener.reset(); + + usmi.reportEvent("com.android.test", 0, UsageEvents.Event.CHOOSER_ACTION); + Thread.sleep(TIMEOUT); + assertNull(listener.mLastReceivedEvent); + } + + private static class TestUsageEventListener implements + UsageStatsManagerInternal.UsageEventListener { + UsageEvents.Event mLastReceivedEvent; + int mLastReceivedUserId; + UsageEvents.Event mExpectedEvent; + int mExpectedUserId; + CountDownLatch mCountDownLatch; + + @Override + public void onUsageEvent(int userId, UsageEvents.Event event) { + mLastReceivedUserId = userId; + mLastReceivedEvent = event; + if (mCountDownLatch != null && userId == mExpectedUserId + && event.getEventType() == mExpectedEvent.getEventType()) { + mCountDownLatch.countDown(); + } + } + + private void setExpectation(int userId, UsageEvents.Event event) { + mExpectedUserId = userId; + mExpectedEvent = event; + mCountDownLatch = new CountDownLatch(1); + } + + private void reset() { + mLastReceivedUserId = mExpectedUserId = -1; + mLastReceivedEvent = mExpectedEvent = null; + mCountDownLatch = null; + } + } +} diff --git a/services/tests/servicestests/Android.bp b/services/tests/servicestests/Android.bp index f2bb91c66ac3..0c2fab83ee66 100644 --- a/services/tests/servicestests/Android.bp +++ b/services/tests/servicestests/Android.bp @@ -49,6 +49,8 @@ android_test { // TODO: remove once Android migrates to JUnit 4.12, // which provides assertThrows "testng", + "junit", + "platform-compat-test-rules", ], diff --git a/services/tests/servicestests/src/android/location/timezone/LocationTimeZoneEventTest.java b/services/tests/servicestests/src/com/android/internal/location/timezone/LocationTimeZoneEventTest.java index 80373ac66109..84b886eb4b3d 100644 --- a/services/tests/servicestests/src/android/location/timezone/LocationTimeZoneEventTest.java +++ b/services/tests/servicestests/src/com/android/internal/location/timezone/LocationTimeZoneEventTest.java @@ -14,9 +14,9 @@ * limitations under the License. */ -package android.location.timezone; +package com.android.internal.location.timezone; -import static android.location.timezone.ParcelableTestSupport.assertRoundTripParcelable; +import static com.android.internal.location.timezone.ParcelableTestSupport.assertRoundTripParcelable; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; @@ -29,7 +29,7 @@ import java.util.List; public class LocationTimeZoneEventTest { - private static final long ARBITRARY_ELAPSED_REALTIME_NANOS = 9999; + private static final long ARBITRARY_ELAPSED_REALTIME_MILLIS = 9999; private static final List<String> ARBITRARY_TIME_ZONE_IDS = singletonList("Europe/London"); @@ -42,7 +42,7 @@ public class LocationTimeZoneEventTest { public void testBuildUnsetEventType() { new LocationTimeZoneEvent.Builder() .setTimeZoneIds(ARBITRARY_TIME_ZONE_IDS) - .setElapsedRealtimeNanos(ARBITRARY_ELAPSED_REALTIME_NANOS) + .setElapsedRealtimeMillis(ARBITRARY_ELAPSED_REALTIME_MILLIS) .build(); } @@ -51,7 +51,7 @@ public class LocationTimeZoneEventTest { new LocationTimeZoneEvent.Builder() .setEventType(LocationTimeZoneEvent.EVENT_TYPE_UNCERTAIN) .setTimeZoneIds(ARBITRARY_TIME_ZONE_IDS) - .setElapsedRealtimeNanos(ARBITRARY_ELAPSED_REALTIME_NANOS) + .setElapsedRealtimeMillis(ARBITRARY_ELAPSED_REALTIME_MILLIS) .build(); } @@ -59,7 +59,7 @@ public class LocationTimeZoneEventTest { public void testEquals() { LocationTimeZoneEvent.Builder builder1 = new LocationTimeZoneEvent.Builder() .setEventType(LocationTimeZoneEvent.EVENT_TYPE_UNCERTAIN) - .setElapsedRealtimeNanos(ARBITRARY_ELAPSED_REALTIME_NANOS); + .setElapsedRealtimeMillis(ARBITRARY_ELAPSED_REALTIME_MILLIS); { LocationTimeZoneEvent one = builder1.build(); assertEquals(one, one); @@ -67,7 +67,7 @@ public class LocationTimeZoneEventTest { LocationTimeZoneEvent.Builder builder2 = new LocationTimeZoneEvent.Builder() .setEventType(LocationTimeZoneEvent.EVENT_TYPE_UNCERTAIN) - .setElapsedRealtimeNanos(ARBITRARY_ELAPSED_REALTIME_NANOS); + .setElapsedRealtimeMillis(ARBITRARY_ELAPSED_REALTIME_MILLIS); { LocationTimeZoneEvent one = builder1.build(); LocationTimeZoneEvent two = builder2.build(); @@ -75,7 +75,7 @@ public class LocationTimeZoneEventTest { assertEquals(two, one); } - builder1.setElapsedRealtimeNanos(ARBITRARY_ELAPSED_REALTIME_NANOS + 1); + builder1.setElapsedRealtimeMillis(ARBITRARY_ELAPSED_REALTIME_MILLIS + 1); { LocationTimeZoneEvent one = builder1.build(); LocationTimeZoneEvent two = builder2.build(); @@ -83,7 +83,7 @@ public class LocationTimeZoneEventTest { assertNotEquals(two, one); } - builder2.setElapsedRealtimeNanos(ARBITRARY_ELAPSED_REALTIME_NANOS + 1); + builder2.setElapsedRealtimeMillis(ARBITRARY_ELAPSED_REALTIME_MILLIS + 1); { LocationTimeZoneEvent one = builder1.build(); LocationTimeZoneEvent two = builder2.build(); @@ -128,7 +128,7 @@ public class LocationTimeZoneEventTest { public void testParcelable() { LocationTimeZoneEvent.Builder builder = new LocationTimeZoneEvent.Builder() .setEventType(LocationTimeZoneEvent.EVENT_TYPE_PERMANENT_FAILURE) - .setElapsedRealtimeNanos(ARBITRARY_ELAPSED_REALTIME_NANOS); + .setElapsedRealtimeMillis(ARBITRARY_ELAPSED_REALTIME_MILLIS); assertRoundTripParcelable(builder.build()); builder.setEventType(LocationTimeZoneEvent.EVENT_TYPE_SUCCESS) diff --git a/services/tests/servicestests/src/com/android/internal/location/timezone/LocationTimeZoneProviderRequestTest.java b/services/tests/servicestests/src/com/android/internal/location/timezone/LocationTimeZoneProviderRequestTest.java index 75696dac3b44..95daa36f2c40 100644 --- a/services/tests/servicestests/src/com/android/internal/location/timezone/LocationTimeZoneProviderRequestTest.java +++ b/services/tests/servicestests/src/com/android/internal/location/timezone/LocationTimeZoneProviderRequestTest.java @@ -16,7 +16,7 @@ package com.android.internal.location.timezone; -import static android.location.timezone.ParcelableTestSupport.assertRoundTripParcelable; +import static com.android.internal.location.timezone.ParcelableTestSupport.assertRoundTripParcelable; import org.junit.Test; diff --git a/services/tests/servicestests/src/android/location/timezone/ParcelableTestSupport.java b/services/tests/servicestests/src/com/android/internal/location/timezone/ParcelableTestSupport.java index 316a2e65fb30..ece5d004975d 100644 --- a/services/tests/servicestests/src/android/location/timezone/ParcelableTestSupport.java +++ b/services/tests/servicestests/src/com/android/internal/location/timezone/ParcelableTestSupport.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.location.timezone; +package com.android.internal.location.timezone; import static org.junit.Assert.assertEquals; @@ -24,7 +24,7 @@ import android.os.Parcelable; import java.lang.reflect.Field; /** Utility methods related to {@link Parcelable} objects used in several tests. */ -public final class ParcelableTestSupport { +final class ParcelableTestSupport { private ParcelableTestSupport() {} diff --git a/services/tests/servicestests/src/com/android/server/VibratorServiceTest.java b/services/tests/servicestests/src/com/android/server/VibratorServiceTest.java index eae4a0804971..64f31358ccb3 100644 --- a/services/tests/servicestests/src/com/android/server/VibratorServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/VibratorServiceTest.java @@ -43,6 +43,8 @@ import android.content.ContentResolver; import android.content.Context; import android.content.ContextWrapper; import android.content.pm.PackageManagerInternal; +import android.hardware.input.IInputManager; +import android.hardware.input.InputManager; import android.hardware.vibrator.IVibrator; import android.media.AudioAttributes; import android.media.AudioManager; @@ -63,11 +65,13 @@ import android.os.Vibrator; import android.os.test.TestLooper; import android.platform.test.annotations.Presubmit; import android.provider.Settings; +import android.view.InputDevice; import androidx.test.InstrumentationRegistry; import com.android.internal.util.test.FakeSettingsProvider; import com.android.internal.util.test.FakeSettingsProviderRule; +import com.android.server.vibrator.VibratorController; import org.junit.After; import org.junit.Before; @@ -118,8 +122,9 @@ public class VibratorServiceTest { // TODO(b/131311651): replace with a FakeVibrator instead. @Mock private Vibrator mVibratorMock; @Mock private AppOpsManager mAppOpsManagerMock; - @Mock private VibratorService.NativeWrapper mNativeWrapperMock; + @Mock private VibratorController.NativeWrapper mNativeWrapperMock; @Mock private IVibratorStateListener mVibratorStateListenerMock; + @Mock private IInputManager mIInputManagerMock; @Mock private IBinder mVibratorStateListenerBinderMock; private TestLooper mTestLooper; @@ -129,10 +134,12 @@ public class VibratorServiceTest { public void setUp() throws Exception { mTestLooper = new TestLooper(); mContextSpy = spy(new ContextWrapper(InstrumentationRegistry.getContext())); + InputManager inputManager = InputManager.resetInstance(mIInputManagerMock); ContentResolver contentResolver = mSettingsProviderRule.mockContentResolver(mContextSpy); when(mContextSpy.getContentResolver()).thenReturn(contentResolver); when(mContextSpy.getSystemService(eq(Context.VIBRATOR_SERVICE))).thenReturn(mVibratorMock); + when(mContextSpy.getSystemService(eq(Context.INPUT_SERVICE))).thenReturn(inputManager); when(mContextSpy.getSystemService(Context.APP_OPS_SERVICE)).thenReturn(mAppOpsManagerMock); when(mVibratorMock.getDefaultHapticFeedbackIntensity()) .thenReturn(Vibrator.VIBRATION_INTENSITY_MEDIUM); @@ -145,6 +152,7 @@ public class VibratorServiceTest { .thenReturn(new ComponentName("", "")); when(mPowerManagerInternalMock.getLowPowerState(PowerManager.ServiceType.VIBRATION)) .thenReturn(mPowerSaveStateMock); + when(mIInputManagerMock.getInputDeviceIds()).thenReturn(new int[0]); setUserSetting(Settings.System.VIBRATE_WHEN_RINGING, 1); setUserSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY, @@ -168,8 +176,9 @@ public class VibratorServiceTest { VibratorService service = new VibratorService(mContextSpy, new VibratorService.Injector() { @Override - VibratorService.NativeWrapper getNativeWrapper() { - return mNativeWrapperMock; + VibratorController createVibratorController( + VibratorController.OnVibrationCompleteListener listener) { + return new VibratorController(0, listener, mNativeWrapperMock); } @Override @@ -189,19 +198,19 @@ public class VibratorServiceTest { @Test public void createService_initializesNativeService() { createService(); - verify(mNativeWrapperMock).vibratorInit(notNull()); - verify(mNativeWrapperMock).vibratorOff(); + verify(mNativeWrapperMock).init(eq(0), notNull()); + verify(mNativeWrapperMock).off(); } @Test public void hasVibrator_withVibratorHalPresent_returnsTrue() { - when(mNativeWrapperMock.vibratorExists()).thenReturn(true); + when(mNativeWrapperMock.isAvailable()).thenReturn(true); assertTrue(createService().hasVibrator()); } @Test public void hasVibrator_withNoVibratorHalPresent_returnsFalse() { - when(mNativeWrapperMock.vibratorExists()).thenReturn(false); + when(mNativeWrapperMock.isAvailable()).thenReturn(false); assertFalse(createService().hasVibrator()); } @@ -217,8 +226,17 @@ public class VibratorServiceTest { } @Test + public void hasAmplitudeControl_withInputDevices_returnsTrue() throws Exception { + when(mIInputManagerMock.getInputDeviceIds()).thenReturn(new int[]{1}); + when(mIInputManagerMock.getInputDevice(1)).thenReturn(createInputDeviceWithVibrator(1)); + mockVibratorCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL); + setUserSetting(Settings.System.VIBRATE_INPUT_DEVICES, 1); + assertTrue(createService().hasAmplitudeControl()); + } + + @Test public void areEffectsSupported_withNullResultFromNative_returnsSupportUnknown() { - when(mNativeWrapperMock.vibratorGetSupportedEffects()).thenReturn(null); + when(mNativeWrapperMock.getSupportedEffects()).thenReturn(null); assertArrayEquals(new int[]{Vibrator.VIBRATION_EFFECT_SUPPORT_UNKNOWN}, createService().areEffectsSupported(new int[]{VibrationEffect.EFFECT_CLICK})); } @@ -227,7 +245,7 @@ public class VibratorServiceTest { public void areEffectsSupported_withSomeEffectsSupported_returnsSupportYesAndNoForEffects() { int[] effects = new int[]{VibrationEffect.EFFECT_CLICK, VibrationEffect.EFFECT_TICK}; - when(mNativeWrapperMock.vibratorGetSupportedEffects()) + when(mNativeWrapperMock.getSupportedEffects()) .thenReturn(new int[]{VibrationEffect.EFFECT_CLICK}); assertArrayEquals( new int[]{Vibrator.VIBRATION_EFFECT_SUPPORT_YES, @@ -247,7 +265,7 @@ public class VibratorServiceTest { @Test public void arePrimitivesSupported_withNullResultFromNative_returnsAlwaysFalse() { mockVibratorCapabilities(IVibrator.CAP_COMPOSE_EFFECTS); - when(mNativeWrapperMock.vibratorGetSupportedPrimitives()).thenReturn(null); + when(mNativeWrapperMock.getSupportedPrimitives()).thenReturn(null); assertArrayEquals(new boolean[]{false, false}, createService().arePrimitivesSupported(new int[]{ @@ -259,7 +277,7 @@ public class VibratorServiceTest { @Test public void arePrimitivesSupported_withSomeSupportedPrimitives_returnsBasedOnNativeResult() { mockVibratorCapabilities(IVibrator.CAP_COMPOSE_EFFECTS); - when(mNativeWrapperMock.vibratorGetSupportedPrimitives()) + when(mNativeWrapperMock.getSupportedPrimitives()) .thenReturn(new int[]{VibrationEffect.Composition.PRIMITIVE_CLICK}); assertArrayEquals(new boolean[]{true, false}, @@ -275,7 +293,7 @@ public class VibratorServiceTest { assertTrue(createService().setAlwaysOnEffect(UID, PACKAGE_NAME, 1, VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK), ALARM_ATTRS)); - verify(mNativeWrapperMock).vibratorAlwaysOnEnable( + verify(mNativeWrapperMock).alwaysOnEnable( eq(1L), eq((long) VibrationEffect.EFFECT_CLICK), eq((long) VibrationEffect.EFFECT_STRENGTH_STRONG)); } @@ -286,8 +304,8 @@ public class VibratorServiceTest { assertFalse(createService().setAlwaysOnEffect(UID, PACKAGE_NAME, 1, VibrationEffect.createOneShot(100, 255), ALARM_ATTRS)); - verify(mNativeWrapperMock, never()).vibratorAlwaysOnDisable(anyLong()); - verify(mNativeWrapperMock, never()).vibratorAlwaysOnEnable(anyLong(), anyLong(), anyLong()); + verify(mNativeWrapperMock, never()).alwaysOnDisable(anyLong()); + verify(mNativeWrapperMock, never()).alwaysOnEnable(anyLong(), anyLong(), anyLong()); } @Test @@ -295,15 +313,15 @@ public class VibratorServiceTest { mockVibratorCapabilities(IVibrator.CAP_ALWAYS_ON_CONTROL); assertTrue(createService().setAlwaysOnEffect(UID, PACKAGE_NAME, 1, null, ALARM_ATTRS)); - verify(mNativeWrapperMock).vibratorAlwaysOnDisable(eq(1L)); + verify(mNativeWrapperMock).alwaysOnDisable(eq(1L)); } @Test public void setAlwaysOnEffect_withoutCapability_ignoresEffect() { assertFalse(createService().setAlwaysOnEffect(UID, PACKAGE_NAME, 1, VibrationEffect.get(VibrationEffect.EFFECT_CLICK), ALARM_ATTRS)); - verify(mNativeWrapperMock, never()).vibratorAlwaysOnDisable(anyLong()); - verify(mNativeWrapperMock, never()).vibratorAlwaysOnEnable(anyLong(), anyLong(), anyLong()); + verify(mNativeWrapperMock, never()).alwaysOnDisable(anyLong()); + verify(mNativeWrapperMock, never()).alwaysOnEnable(anyLong(), anyLong(), anyLong()); } @Test @@ -322,9 +340,9 @@ public class VibratorServiceTest { vibrate(createService(), VibrationEffect.createOneShot(100, 100), RINGTONE_ATTRS); InOrder inOrderVerifier = inOrder(mNativeWrapperMock); - inOrderVerifier.verify(mNativeWrapperMock, never()).vibratorOn(eq(1L), anyLong()); - inOrderVerifier.verify(mNativeWrapperMock).vibratorOn(eq(10L), anyLong()); - inOrderVerifier.verify(mNativeWrapperMock).vibratorOn(eq(100L), anyLong()); + inOrderVerifier.verify(mNativeWrapperMock, never()).on(eq(1L), anyLong()); + inOrderVerifier.verify(mNativeWrapperMock).on(eq(10L), anyLong()); + inOrderVerifier.verify(mNativeWrapperMock).on(eq(100L), anyLong()); } @Test @@ -375,6 +393,22 @@ public class VibratorServiceTest { } @Test + public void vibrate_withOneShotAndInputDevices_vibratesInputDevices() throws Exception { + when(mIInputManagerMock.getInputDeviceIds()).thenReturn(new int[]{1}); + when(mIInputManagerMock.getInputDevice(1)).thenReturn(createInputDeviceWithVibrator(1)); + setUserSetting(Settings.System.VIBRATE_INPUT_DEVICES, 1); + VibratorService service = createService(); + Mockito.clearInvocations(mNativeWrapperMock); + + VibrationEffect effect = VibrationEffect.createOneShot(100, 128); + vibrate(service, effect); + assertFalse(service.isVibrating()); + + verify(mIInputManagerMock).vibrate(eq(1), eq(effect), any()); + verify(mNativeWrapperMock, never()).on(anyLong(), anyLong()); + } + + @Test public void vibrate_withOneShotAndAmplitudeControl_turnsVibratorOnAndSetsAmplitude() { mockVibratorCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL); VibratorService service = createService(); @@ -383,9 +417,9 @@ public class VibratorServiceTest { vibrate(service, VibrationEffect.createOneShot(100, 128)); assertTrue(service.isVibrating()); - verify(mNativeWrapperMock).vibratorOff(); - verify(mNativeWrapperMock).vibratorOn(eq(100L), gt(0L)); - verify(mNativeWrapperMock).vibratorSetAmplitude(eq(128)); + verify(mNativeWrapperMock).off(); + verify(mNativeWrapperMock).on(eq(100L), gt(0L)); + verify(mNativeWrapperMock).setAmplitude(eq(128)); } @Test @@ -396,26 +430,45 @@ public class VibratorServiceTest { vibrate(service, VibrationEffect.createOneShot(100, 128)); assertTrue(service.isVibrating()); - verify(mNativeWrapperMock).vibratorOff(); - verify(mNativeWrapperMock).vibratorOn(eq(100L), gt(0L)); - verify(mNativeWrapperMock, never()).vibratorSetAmplitude(anyInt()); + verify(mNativeWrapperMock).off(); + verify(mNativeWrapperMock).on(eq(100L), gt(0L)); + verify(mNativeWrapperMock, never()).setAmplitude(anyInt()); } @Test public void vibrate_withPrebaked_performsEffect() { - when(mNativeWrapperMock.vibratorGetSupportedEffects()) + when(mNativeWrapperMock.getSupportedEffects()) .thenReturn(new int[]{VibrationEffect.EFFECT_CLICK}); VibratorService service = createService(); Mockito.clearInvocations(mNativeWrapperMock); vibrate(service, VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK)); - verify(mNativeWrapperMock).vibratorOff(); - verify(mNativeWrapperMock).vibratorPerformEffect(eq((long) VibrationEffect.EFFECT_CLICK), + verify(mNativeWrapperMock).off(); + verify(mNativeWrapperMock).perform(eq((long) VibrationEffect.EFFECT_CLICK), eq((long) VibrationEffect.EFFECT_STRENGTH_STRONG), gt(0L)); } @Test + public void vibrate_withPrebakedAndInputDevices_vibratesFallbackWaveformOnInputDevices() + throws Exception { + when(mIInputManagerMock.getInputDeviceIds()).thenReturn(new int[]{1}); + when(mIInputManagerMock.getInputDevice(1)).thenReturn(createInputDeviceWithVibrator(1)); + setUserSetting(Settings.System.VIBRATE_INPUT_DEVICES, 1); + VibratorService service = createService(); + Mockito.clearInvocations(mNativeWrapperMock); + + vibrate(service, VibrationEffect.get(VibrationEffect.EFFECT_CLICK)); + assertFalse(service.isVibrating()); + + // Wait for VibrateThread to turn input device vibrator ON. + Thread.sleep(5); + verify(mIInputManagerMock).vibrate(eq(1), any(), any()); + verify(mNativeWrapperMock, never()).on(anyLong(), anyLong()); + verify(mNativeWrapperMock, never()).perform(anyLong(), anyLong(), anyLong()); + } + + @Test public void vibrate_withComposed_performsEffect() { mockVibratorCapabilities(IVibrator.CAP_COMPOSE_EFFECTS); VibratorService service = createService(); @@ -429,9 +482,8 @@ public class VibratorServiceTest { ArgumentCaptor<VibrationEffect.Composition.PrimitiveEffect[]> primitivesCaptor = ArgumentCaptor.forClass(VibrationEffect.Composition.PrimitiveEffect[].class); - verify(mNativeWrapperMock).vibratorOff(); - verify(mNativeWrapperMock).vibratorPerformComposedEffect( - primitivesCaptor.capture(), gt(0L)); + verify(mNativeWrapperMock).off(); + verify(mNativeWrapperMock).compose(primitivesCaptor.capture(), gt(0L)); // Check all primitive effect fields are passed down to the HAL. assertEquals(1, primitivesCaptor.getValue().length); @@ -442,6 +494,27 @@ public class VibratorServiceTest { } @Test + public void vibrate_withComposedAndInputDevices_vibratesInputDevices() + throws Exception { + when(mIInputManagerMock.getInputDeviceIds()).thenReturn(new int[]{1, 2}); + when(mIInputManagerMock.getInputDevice(1)).thenReturn(createInputDeviceWithVibrator(1)); + when(mIInputManagerMock.getInputDevice(2)).thenReturn(createInputDeviceWithVibrator(2)); + setUserSetting(Settings.System.VIBRATE_INPUT_DEVICES, 1); + VibratorService service = createService(); + Mockito.clearInvocations(mNativeWrapperMock); + + VibrationEffect effect = VibrationEffect.startComposition() + .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 0.5f, 10) + .compose(); + vibrate(service, effect); + assertFalse(service.isVibrating()); + + verify(mIInputManagerMock).vibrate(eq(1), eq(effect), any()); + verify(mIInputManagerMock).vibrate(eq(2), eq(effect), any()); + verify(mNativeWrapperMock, never()).compose(any(), anyLong()); + } + + @Test public void vibrate_withWaveform_controlsVibratorAmplitudeDuringTotalVibrationTime() throws Exception { mockVibratorCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL); @@ -455,12 +528,12 @@ public class VibratorServiceTest { // Wait for VibrateThread to finish: 10ms 100, 10ms 200, 10ms 50. Thread.sleep(40); InOrder inOrderVerifier = inOrder(mNativeWrapperMock); - inOrderVerifier.verify(mNativeWrapperMock).vibratorOff(); - inOrderVerifier.verify(mNativeWrapperMock).vibratorOn(eq(30L), anyLong()); - inOrderVerifier.verify(mNativeWrapperMock).vibratorSetAmplitude(eq(100)); - inOrderVerifier.verify(mNativeWrapperMock).vibratorSetAmplitude(eq(200)); - inOrderVerifier.verify(mNativeWrapperMock).vibratorSetAmplitude(eq(50)); - inOrderVerifier.verify(mNativeWrapperMock).vibratorOff(); + inOrderVerifier.verify(mNativeWrapperMock).off(); + inOrderVerifier.verify(mNativeWrapperMock).on(eq(30L), anyLong()); + inOrderVerifier.verify(mNativeWrapperMock).setAmplitude(eq(100)); + inOrderVerifier.verify(mNativeWrapperMock).setAmplitude(eq(200)); + inOrderVerifier.verify(mNativeWrapperMock).setAmplitude(eq(50)); + inOrderVerifier.verify(mNativeWrapperMock).off(); } @Test @@ -473,12 +546,12 @@ public class VibratorServiceTest { doAnswer(invocation -> { Thread.currentThread().sleep(stepDuration / 4); return null; - }).when(mNativeWrapperMock).vibratorOn(anyLong(), anyLong()); + }).when(mNativeWrapperMock).on(anyLong(), anyLong()); // 25% of each waveform step will be spent on the native setAmplitude() call.. doAnswer(invocation -> { Thread.currentThread().sleep(stepDuration / 4); return null; - }).when(mNativeWrapperMock).vibratorSetAmplitude(anyInt()); + }).when(mNativeWrapperMock).setAmplitude(anyInt()); VibratorService service = createService(); @@ -500,49 +573,71 @@ public class VibratorServiceTest { } @Test + public void vibrate_withWaveformAndInputDevices_vibratesInputDevices() throws Exception { + when(mIInputManagerMock.getInputDeviceIds()).thenReturn(new int[]{1}); + when(mIInputManagerMock.getInputDevice(1)).thenReturn(createInputDeviceWithVibrator(1)); + setUserSetting(Settings.System.VIBRATE_INPUT_DEVICES, 1); + VibratorService service = createService(); + Mockito.clearInvocations(mNativeWrapperMock); + + VibrationEffect effect = VibrationEffect.createWaveform( + new long[]{10, 10, 10}, new int[]{100, 200, 50}, -1); + vibrate(service, effect); + assertFalse(service.isVibrating()); + + // Wait for VibrateThread to turn input device vibrator ON. + Thread.sleep(5); + verify(mIInputManagerMock).vibrate(eq(1), eq(effect), any()); + verify(mNativeWrapperMock, never()).on(anyLong(), anyLong()); + } + + @Test public void vibrate_withOneShotAndNativeCallbackTriggered_finishesVibration() { VibratorService service = createService(); doAnswer(invocation -> { service.onVibrationComplete(invocation.getArgument(1)); return null; - }).when(mNativeWrapperMock).vibratorOn(anyLong(), anyLong()); + }).when(mNativeWrapperMock).on(anyLong(), anyLong()); Mockito.clearInvocations(mNativeWrapperMock); vibrate(service, VibrationEffect.createOneShot(100, VibrationEffect.DEFAULT_AMPLITUDE)); InOrder inOrderVerifier = inOrder(mNativeWrapperMock); - inOrderVerifier.verify(mNativeWrapperMock).vibratorOff(); - inOrderVerifier.verify(mNativeWrapperMock).vibratorOn(eq(100L), - gt(0L)); - inOrderVerifier.verify(mNativeWrapperMock).vibratorOff(); + inOrderVerifier.verify(mNativeWrapperMock).off(); + inOrderVerifier.verify(mNativeWrapperMock).on(eq(100L), gt(0L)); + inOrderVerifier.verify(mNativeWrapperMock).off(); } @Test public void vibrate_withPrebakedAndNativeCallbackTriggered_finishesVibration() { - when(mNativeWrapperMock.vibratorGetSupportedEffects()) + when(mNativeWrapperMock.getSupportedEffects()) .thenReturn(new int[]{VibrationEffect.EFFECT_CLICK}); VibratorService service = createService(); doAnswer(invocation -> { service.onVibrationComplete(invocation.getArgument(2)); return 10_000L; // 10s - }).when(mNativeWrapperMock).vibratorPerformEffect(anyLong(), anyLong(), anyLong()); + }).when(mNativeWrapperMock).perform(anyLong(), anyLong(), anyLong()); Mockito.clearInvocations(mNativeWrapperMock); vibrate(service, VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK)); InOrder inOrderVerifier = inOrder(mNativeWrapperMock); - inOrderVerifier.verify(mNativeWrapperMock).vibratorOff(); - inOrderVerifier.verify(mNativeWrapperMock).vibratorPerformEffect( + inOrderVerifier.verify(mNativeWrapperMock).off(); + inOrderVerifier.verify(mNativeWrapperMock).perform( eq((long) VibrationEffect.EFFECT_CLICK), eq((long) VibrationEffect.EFFECT_STRENGTH_STRONG), gt(0L)); - inOrderVerifier.verify(mNativeWrapperMock).vibratorOff(); + inOrderVerifier.verify(mNativeWrapperMock).off(); } @Test - public void vibrate_withWaveformAndNativeCallback_callbackCannotBeTriggeredByNative() + public void vibrate_withWaveformAndNativeCallback_callbackIgnoredAndWaveformPlaysCompletely() throws Exception { VibratorService service = createService(); + doAnswer(invocation -> { + service.onVibrationComplete(invocation.getArgument(1)); + return null; + }).when(mNativeWrapperMock).on(anyLong(), anyLong()); Mockito.clearInvocations(mNativeWrapperMock); VibrationEffect effect = VibrationEffect.createWaveform(new long[]{1, 3, 1, 2}, -1); @@ -551,10 +646,11 @@ public class VibratorServiceTest { // Wait for VibrateThread to finish: 1ms OFF, 3ms ON, 1ms OFF, 2ms ON. Thread.sleep(15); InOrder inOrderVerifier = inOrder(mNativeWrapperMock); - inOrderVerifier.verify(mNativeWrapperMock).vibratorOff(); - inOrderVerifier.verify(mNativeWrapperMock).vibratorOn(eq(3L), anyLong()); - inOrderVerifier.verify(mNativeWrapperMock).vibratorOn(eq(2L), anyLong()); - inOrderVerifier.verify(mNativeWrapperMock).vibratorOff(); + inOrderVerifier.verify(mNativeWrapperMock, times(2)).off(); + inOrderVerifier.verify(mNativeWrapperMock).on(eq(3L), anyLong()); + inOrderVerifier.verify(mNativeWrapperMock).off(); + inOrderVerifier.verify(mNativeWrapperMock).on(eq(2L), anyLong()); + inOrderVerifier.verify(mNativeWrapperMock).off(); } @Test @@ -564,7 +660,7 @@ public class VibratorServiceTest { doAnswer(invocation -> { service.onVibrationComplete(invocation.getArgument(1)); return null; - }).when(mNativeWrapperMock).vibratorPerformComposedEffect(any(), anyLong()); + }).when(mNativeWrapperMock).compose(any(), anyLong()); Mockito.clearInvocations(mNativeWrapperMock); VibrationEffect effect = VibrationEffect.startComposition() @@ -573,14 +669,14 @@ public class VibratorServiceTest { vibrate(service, effect); InOrder inOrderVerifier = inOrder(mNativeWrapperMock); - inOrderVerifier.verify(mNativeWrapperMock).vibratorOff(); - inOrderVerifier.verify(mNativeWrapperMock).vibratorPerformComposedEffect( + inOrderVerifier.verify(mNativeWrapperMock).off(); + inOrderVerifier.verify(mNativeWrapperMock).compose( any(VibrationEffect.Composition.PrimitiveEffect[].class), gt(0L)); - inOrderVerifier.verify(mNativeWrapperMock).vibratorOff(); + inOrderVerifier.verify(mNativeWrapperMock).off(); } @Test - public void cancelVibrate_withDeviceVibrating_callsVibratorOff() { + public void cancelVibrate_withDeviceVibrating_callsoff() { VibratorService service = createService(); vibrate(service, VibrationEffect.createOneShot(100, VibrationEffect.DEFAULT_AMPLITUDE)); assertTrue(service.isVibrating()); @@ -588,7 +684,7 @@ public class VibratorServiceTest { service.cancelVibrate(service); assertFalse(service.isVibrating()); - verify(mNativeWrapperMock).vibratorOff(); + verify(mNativeWrapperMock).off(); } @Test @@ -598,24 +694,23 @@ public class VibratorServiceTest { service.cancelVibrate(service); assertFalse(service.isVibrating()); - verify(mNativeWrapperMock, never()).vibratorOff(); + verify(mNativeWrapperMock, never()).off(); } @Test public void registerVibratorStateListener_callbacksAreTriggered() throws Exception { VibratorService service = createService(); - doAnswer(invocation -> { - service.onVibrationComplete(invocation.getArgument(1)); - return null; - }).when(mNativeWrapperMock).vibratorOn(anyLong(), anyLong()); service.registerVibratorStateListener(mVibratorStateListenerMock); - verify(mVibratorStateListenerMock).onVibrating(false); - Mockito.clearInvocations(mVibratorStateListenerMock); vibrate(service, VibrationEffect.createOneShot(10, VibrationEffect.DEFAULT_AMPLITUDE)); + service.cancelVibrate(service); + InOrder inOrderVerifier = inOrder(mVibratorStateListenerMock); + // First notification done when listener is registered. + inOrderVerifier.verify(mVibratorStateListenerMock).onVibrating(false); inOrderVerifier.verify(mVibratorStateListenerMock).onVibrating(eq(true)); inOrderVerifier.verify(mVibratorStateListenerMock).onVibrating(eq(false)); + inOrderVerifier.verifyNoMoreInteractions(); } @Test @@ -655,16 +750,16 @@ public class VibratorServiceTest { vibrate(service, VibrationEffect.createPredefined(VibrationEffect.EFFECT_HEAVY_CLICK), RINGTONE_ATTRS); - verify(mNativeWrapperMock).vibratorPerformEffect( + verify(mNativeWrapperMock).perform( eq((long) VibrationEffect.EFFECT_CLICK), eq((long) VibrationEffect.EFFECT_STRENGTH_STRONG), anyLong()); - verify(mNativeWrapperMock).vibratorPerformEffect( + verify(mNativeWrapperMock).perform( eq((long) VibrationEffect.EFFECT_TICK), eq((long) VibrationEffect.EFFECT_STRENGTH_MEDIUM), anyLong()); - verify(mNativeWrapperMock).vibratorPerformEffect( + verify(mNativeWrapperMock).perform( eq((long) VibrationEffect.EFFECT_DOUBLE_CLICK), eq((long) VibrationEffect.EFFECT_STRENGTH_LIGHT), anyLong()); - verify(mNativeWrapperMock, never()).vibratorPerformEffect( + verify(mNativeWrapperMock, never()).perform( eq((long) VibrationEffect.EFFECT_HEAVY_CLICK), anyLong(), anyLong()); } @@ -692,14 +787,14 @@ public class VibratorServiceTest { Thread.sleep(15); // Alarm vibration is never scaled. - verify(mNativeWrapperMock).vibratorSetAmplitude(eq(100)); + verify(mNativeWrapperMock).setAmplitude(eq(100)); // Notification vibrations will be scaled with SCALE_VERY_HIGH. - verify(mNativeWrapperMock).vibratorSetAmplitude(intThat(amplitude -> amplitude > 150)); + verify(mNativeWrapperMock).setAmplitude(intThat(amplitude -> amplitude > 150)); // Haptic feedback vibrations will be scaled with SCALE_LOW. - verify(mNativeWrapperMock).vibratorSetAmplitude( + verify(mNativeWrapperMock).setAmplitude( intThat(amplitude -> amplitude < 100 && amplitude > 50)); // Ringtone vibration is off. - verify(mNativeWrapperMock, never()).vibratorSetAmplitude(eq(255)); + verify(mNativeWrapperMock, never()).setAmplitude(eq(255)); } @Test @@ -729,7 +824,7 @@ public class VibratorServiceTest { vibrate(service, effect, RINGTONE_ATTRS); // Ringtone vibration is off, so only the other 3 are propagated to native. - verify(mNativeWrapperMock, times(3)).vibratorPerformComposedEffect( + verify(mNativeWrapperMock, times(3)).compose( primitivesCaptor.capture(), anyLong()); List<VibrationEffect.Composition.PrimitiveEffect[]> values = @@ -788,7 +883,12 @@ public class VibratorServiceTest { } private void mockVibratorCapabilities(int capabilities) { - when(mNativeWrapperMock.vibratorGetCapabilities()).thenReturn((long) capabilities); + when(mNativeWrapperMock.getCapabilities()).thenReturn((long) capabilities); + } + + private InputDevice createInputDeviceWithVibrator(int id) { + return new InputDevice(id, 0, 0, "name", 0, 0, "description", false, 0, 0, + null, /* hasVibrator= */ true, false, false); } private static <T> void addLocalServiceMock(Class<T> clazz, T mock) { diff --git a/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java index 026db42d4d7a..640d6e599736 100644 --- a/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java @@ -28,6 +28,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.app.PropertyInvalidatedCache; +import android.compat.testing.PlatformCompatChangeRule; import android.content.Context; import android.graphics.Insets; import android.graphics.Rect; @@ -44,8 +45,10 @@ import android.hardware.display.VirtualDisplayConfig; import android.hardware.input.InputManagerInternal; import android.os.Handler; import android.os.IBinder; +import android.os.Process; import android.view.Display; import android.view.DisplayCutout; +import android.view.DisplayEventReceiver; import android.view.DisplayInfo; import android.view.Surface; import android.view.SurfaceControl; @@ -57,13 +60,17 @@ import androidx.test.runner.AndroidJUnit4; import com.android.server.LocalServices; import com.android.server.SystemService; -import com.android.server.display.DisplayDeviceInfo; import com.android.server.display.DisplayManagerService.SyncRoot; import com.android.server.lights.LightsManager; import com.android.server.wm.WindowManagerInternal; +import libcore.junit.util.compat.CoreCompatChangeRule.DisableCompatChanges; +import libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges; + import org.junit.Before; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.TestRule; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; @@ -80,6 +87,9 @@ public class DisplayManagerServiceTest { private static final String VIRTUAL_DISPLAY_NAME = "Test Virtual Display"; private static final String PACKAGE_NAME = "com.android.frameworks.servicestests"; + @Rule + public TestRule compatChangeRule = new PlatformCompatChangeRule(); + private Context mContext; private final DisplayManagerService.Injector mShortMockedInjector = @@ -95,15 +105,31 @@ public class DisplayManagerServiceTest { return SHORT_DEFAULT_DISPLAY_TIMEOUT_MILLIS; } }; - private final DisplayManagerService.Injector mBasicInjector = - new DisplayManagerService.Injector() { + + class BasicInjector extends DisplayManagerService.Injector { + @Override + VirtualDisplayAdapter getVirtualDisplayAdapter(SyncRoot syncRoot, Context context, + Handler handler, DisplayAdapter.Listener displayAdapterListener) { + return new VirtualDisplayAdapter(syncRoot, context, handler, displayAdapterListener, + (String name, boolean secure) -> mMockDisplayToken); + } + } + + private final DisplayManagerService.Injector mBasicInjector = new BasicInjector(); + + private final DisplayManagerService.Injector mAllowNonNativeRefreshRateOverrideInjector = + new BasicInjector() { @Override - VirtualDisplayAdapter getVirtualDisplayAdapter(SyncRoot syncRoot, - Context context, Handler handler, - DisplayAdapter.Listener displayAdapterListener) { - return new VirtualDisplayAdapter(syncRoot, context, handler, - displayAdapterListener, - (String name, boolean secure) -> mMockDisplayToken); + boolean getAllowNonNativeRefreshRateOverride() { + return true; + } + }; + + private final DisplayManagerService.Injector mDenyNonNativeRefreshRateOverrideInjector = + new BasicInjector() { + @Override + boolean getAllowNonNativeRefreshRateOverride() { + return false; } }; @@ -575,6 +601,337 @@ public class DisplayManagerServiceTest { assertEquals(displayManager.getVirtualDisplaySurfaceInternal(mMockAppToken), surface); } + /** + * Tests that there should be a display change notification if the frame rate overrides + * list is updated. + */ + @Test + public void testShouldNotifyChangeWhenDisplayInfoFrameRateOverrideChanged() throws Exception { + DisplayManagerService displayManager = + new DisplayManagerService(mContext, mShortMockedInjector); + DisplayManagerService.BinderService displayManagerBinderService = + displayManager.new BinderService(); + registerDefaultDisplays(displayManager); + displayManager.onBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY); + + FakeDisplayDevice displayDevice = createFakeDisplayDevice(displayManager, new float[]{60f}); + FakeDisplayManagerCallback callback = registerDisplayListenerCallback(displayManager, + displayManagerBinderService, displayDevice); + + int myUid = Process.myUid(); + updateFrameRateOverride(displayManager, displayDevice, + new DisplayEventReceiver.FrameRateOverride[]{ + new DisplayEventReceiver.FrameRateOverride(myUid, 30f), + }); + assertTrue(callback.mCalled); + callback.clear(); + + updateFrameRateOverride(displayManager, displayDevice, + new DisplayEventReceiver.FrameRateOverride[]{ + new DisplayEventReceiver.FrameRateOverride(myUid, 30f), + new DisplayEventReceiver.FrameRateOverride(1234, 30f), + }); + assertFalse(callback.mCalled); + + updateFrameRateOverride(displayManager, displayDevice, + new DisplayEventReceiver.FrameRateOverride[]{ + new DisplayEventReceiver.FrameRateOverride(myUid, 20f), + new DisplayEventReceiver.FrameRateOverride(1234, 30f), + new DisplayEventReceiver.FrameRateOverride(5678, 30f), + }); + assertTrue(callback.mCalled); + callback.clear(); + + updateFrameRateOverride(displayManager, displayDevice, + new DisplayEventReceiver.FrameRateOverride[]{ + new DisplayEventReceiver.FrameRateOverride(1234, 30f), + new DisplayEventReceiver.FrameRateOverride(5678, 30f), + }); + assertTrue(callback.mCalled); + callback.clear(); + + updateFrameRateOverride(displayManager, displayDevice, + new DisplayEventReceiver.FrameRateOverride[]{ + new DisplayEventReceiver.FrameRateOverride(5678, 30f), + }); + assertFalse(callback.mCalled); + } + + /** + * Tests that the DisplayInfo is updated correctly with a frame rate override + */ + @Test + public void testDisplayInfoFrameRateOverride() throws Exception { + DisplayManagerService displayManager = + new DisplayManagerService(mContext, mShortMockedInjector); + DisplayManagerService.BinderService displayManagerBinderService = + displayManager.new BinderService(); + registerDefaultDisplays(displayManager); + displayManager.onBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY); + + FakeDisplayDevice displayDevice = createFakeDisplayDevice(displayManager, + new float[]{60f, 30f, 20f}); + int displayId = getDisplayIdForDisplayDevice(displayManager, displayManagerBinderService, + displayDevice); + DisplayInfo displayInfo = displayManagerBinderService.getDisplayInfo(displayId); + assertEquals(60f, displayInfo.getRefreshRate(), 0.01f); + + updateFrameRateOverride(displayManager, displayDevice, + new DisplayEventReceiver.FrameRateOverride[]{ + new DisplayEventReceiver.FrameRateOverride( + Process.myUid(), 20f), + new DisplayEventReceiver.FrameRateOverride( + Process.myUid() + 1, 30f) + }); + displayInfo = displayManagerBinderService.getDisplayInfo(displayId); + assertEquals(20f, displayInfo.getRefreshRate(), 0.01f); + + // Changing the mode to 30Hz should not override the refresh rate to 20Hz anymore + // as 20 is not a divider of 30. + updateModeId(displayManager, displayDevice, 2); + displayInfo = displayManagerBinderService.getDisplayInfo(displayId); + assertEquals(30f, displayInfo.getRefreshRate(), 0.01f); + } + + /** + * Tests that the frame rate override is updated accordingly to the + * allowNonNativeRefreshRateOverride policy. + */ + @Test + public void testDisplayInfoNonNativeFrameRateOverride() throws Exception { + testDisplayInfoNonNativeFrameRateOverride(mDenyNonNativeRefreshRateOverrideInjector); + testDisplayInfoNonNativeFrameRateOverride(mAllowNonNativeRefreshRateOverrideInjector); + } + + /** + * Tests that the mode reflects the frame rate override is in compat mode + */ + @Test + @DisableCompatChanges({DisplayManagerService.DISPLAY_MODE_RETURNS_PHYSICAL_REFRESH_RATE}) + public void testDisplayInfoFrameRateOverrideModeCompat() throws Exception { + testDisplayInfoFrameRateOverrideModeCompat(/*compatChangeEnabled*/ false); + } + + /** + * Tests that the mode reflects the physical display refresh rate when not in compat mode. + */ + @Test + @EnableCompatChanges({DisplayManagerService.DISPLAY_MODE_RETURNS_PHYSICAL_REFRESH_RATE}) + public void testDisplayInfoFrameRateOverrideMode() throws Exception { + testDisplayInfoFrameRateOverrideModeCompat(/*compatChangeEnabled*/ true); + } + + /** + * Tests that the mode reflects the frame rate override is in compat mode and accordingly to the + * allowNonNativeRefreshRateOverride policy. + */ + @Test + @DisableCompatChanges({DisplayManagerService.DISPLAY_MODE_RETURNS_PHYSICAL_REFRESH_RATE}) + public void testDisplayInfoNonNativeFrameRateOverrideModeCompat() throws Exception { + testDisplayInfoNonNativeFrameRateOverrideMode(mDenyNonNativeRefreshRateOverrideInjector, + /*compatChangeEnabled*/ false); + testDisplayInfoNonNativeFrameRateOverrideMode(mAllowNonNativeRefreshRateOverrideInjector, + /*compatChangeEnabled*/ false); + } + + /** + * Tests that the mode reflects the physical display refresh rate when not in compat mode. + */ + @Test + @EnableCompatChanges({DisplayManagerService.DISPLAY_MODE_RETURNS_PHYSICAL_REFRESH_RATE}) + public void testDisplayInfoNonNativeFrameRateOverrideMode() throws Exception { + testDisplayInfoNonNativeFrameRateOverrideMode(mDenyNonNativeRefreshRateOverrideInjector, + /*compatChangeEnabled*/ true); + testDisplayInfoNonNativeFrameRateOverrideMode(mAllowNonNativeRefreshRateOverrideInjector, + /*compatChangeEnabled*/ true); + } + + private void testDisplayInfoFrameRateOverrideModeCompat(boolean compatChangeEnabled) + throws Exception { + DisplayManagerService displayManager = + new DisplayManagerService(mContext, mShortMockedInjector); + DisplayManagerService.BinderService displayManagerBinderService = + displayManager.new BinderService(); + registerDefaultDisplays(displayManager); + displayManager.onBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY); + + FakeDisplayDevice displayDevice = createFakeDisplayDevice(displayManager, + new float[]{60f, 30f, 20f}); + int displayId = getDisplayIdForDisplayDevice(displayManager, displayManagerBinderService, + displayDevice); + DisplayInfo displayInfo = displayManagerBinderService.getDisplayInfo(displayId); + assertEquals(60f, displayInfo.getRefreshRate(), 0.01f); + + updateFrameRateOverride(displayManager, displayDevice, + new DisplayEventReceiver.FrameRateOverride[]{ + new DisplayEventReceiver.FrameRateOverride( + Process.myUid(), 20f), + new DisplayEventReceiver.FrameRateOverride( + Process.myUid() + 1, 30f) + }); + displayInfo = displayManagerBinderService.getDisplayInfo(displayId); + assertEquals(20f, displayInfo.getRefreshRate(), 0.01f); + Display.Mode expectedMode; + if (compatChangeEnabled) { + expectedMode = new Display.Mode(1, 100, 200, 60f); + } else { + expectedMode = new Display.Mode(3, 100, 200, 20f); + } + assertEquals(expectedMode, displayInfo.getMode()); + } + + private void testDisplayInfoNonNativeFrameRateOverrideMode( + DisplayManagerService.Injector injector, boolean compatChangeEnabled) { + DisplayManagerService displayManager = + new DisplayManagerService(mContext, injector); + DisplayManagerService.BinderService displayManagerBinderService = + displayManager.new BinderService(); + registerDefaultDisplays(displayManager); + displayManager.onBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY); + + FakeDisplayDevice displayDevice = createFakeDisplayDevice(displayManager, + new float[]{60f}); + int displayId = getDisplayIdForDisplayDevice(displayManager, displayManagerBinderService, + displayDevice); + DisplayInfo displayInfo = displayManagerBinderService.getDisplayInfo(displayId); + assertEquals(60f, displayInfo.getRefreshRate(), 0.01f); + + updateFrameRateOverride(displayManager, displayDevice, + new DisplayEventReceiver.FrameRateOverride[]{ + new DisplayEventReceiver.FrameRateOverride( + Process.myUid(), 20f) + }); + displayInfo = displayManagerBinderService.getDisplayInfo(displayId); + Display.Mode expectedMode; + if (compatChangeEnabled) { + expectedMode = new Display.Mode(1, 100, 200, 60f); + } else if (injector.getAllowNonNativeRefreshRateOverride()) { + expectedMode = new Display.Mode(255, 100, 200, 20f); + } else { + expectedMode = new Display.Mode(1, 100, 200, 60f); + } + assertEquals(expectedMode, displayInfo.getMode()); + } + + private void testDisplayInfoNonNativeFrameRateOverride( + DisplayManagerService.Injector injector) { + DisplayManagerService displayManager = + new DisplayManagerService(mContext, injector); + DisplayManagerService.BinderService displayManagerBinderService = + displayManager.new BinderService(); + registerDefaultDisplays(displayManager); + displayManager.onBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY); + + FakeDisplayDevice displayDevice = createFakeDisplayDevice(displayManager, + new float[]{60f}); + int displayId = getDisplayIdForDisplayDevice(displayManager, displayManagerBinderService, + displayDevice); + DisplayInfo displayInfo = displayManagerBinderService.getDisplayInfo(displayId); + assertEquals(60f, displayInfo.getRefreshRate(), 0.01f); + + updateFrameRateOverride(displayManager, displayDevice, + new DisplayEventReceiver.FrameRateOverride[]{ + new DisplayEventReceiver.FrameRateOverride( + Process.myUid(), 20f) + }); + displayInfo = displayManagerBinderService.getDisplayInfo(displayId); + float expectedRefreshRate = injector.getAllowNonNativeRefreshRateOverride() ? 20f : 60f; + assertEquals(expectedRefreshRate, displayInfo.getRefreshRate(), 0.01f); + } + + private int getDisplayIdForDisplayDevice( + DisplayManagerService displayManager, + DisplayManagerService.BinderService displayManagerBinderService, + FakeDisplayDevice displayDevice) { + + final int[] displayIds = displayManagerBinderService.getDisplayIds(); + assertTrue(displayIds.length > 0); + int displayId = Display.INVALID_DISPLAY; + for (int i = 0; i < displayIds.length; i++) { + DisplayDeviceInfo ddi = displayManager.getDisplayDeviceInfoInternal(displayIds[i]); + if (displayDevice.getDisplayDeviceInfoLocked().equals(ddi)) { + displayId = displayIds[i]; + break; + } + } + assertFalse(displayId == Display.INVALID_DISPLAY); + return displayId; + } + + private void updateDisplayDeviceInfo(DisplayManagerService displayManager, + FakeDisplayDevice displayDevice, + DisplayDeviceInfo displayDeviceInfo) { + displayDevice.setDisplayDeviceInfo(displayDeviceInfo); + displayManager.getDisplayDeviceRepository() + .onDisplayDeviceEvent(displayDevice, DisplayAdapter.DISPLAY_DEVICE_EVENT_CHANGED); + Handler handler = displayManager.getDisplayHandler(); + handler.runWithScissors(() -> { + }, 0 /* now */); + } + + private void updateFrameRateOverride(DisplayManagerService displayManager, + FakeDisplayDevice displayDevice, + DisplayEventReceiver.FrameRateOverride[] frameRateOverrides) { + DisplayDeviceInfo displayDeviceInfo = new DisplayDeviceInfo(); + displayDeviceInfo.copyFrom(displayDevice.getDisplayDeviceInfoLocked()); + displayDeviceInfo.frameRateOverrides = frameRateOverrides; + updateDisplayDeviceInfo(displayManager, displayDevice, displayDeviceInfo); + } + + private void updateModeId(DisplayManagerService displayManager, + FakeDisplayDevice displayDevice, + int modeId) { + DisplayDeviceInfo displayDeviceInfo = new DisplayDeviceInfo(); + displayDeviceInfo.copyFrom(displayDevice.getDisplayDeviceInfoLocked()); + displayDeviceInfo.modeId = modeId; + updateDisplayDeviceInfo(displayManager, displayDevice, displayDeviceInfo); + } + + private FakeDisplayManagerCallback registerDisplayListenerCallback( + DisplayManagerService displayManager, + DisplayManagerService.BinderService displayManagerBinderService, + FakeDisplayDevice displayDevice) { + // Find the display id of the added FakeDisplayDevice + DisplayDeviceInfo displayDeviceInfo = displayDevice.getDisplayDeviceInfoLocked(); + + int displayId = getDisplayIdForDisplayDevice(displayManager, displayManagerBinderService, + displayDevice); + + Handler handler = displayManager.getDisplayHandler(); + handler.runWithScissors(() -> { + }, 0 /* now */); + + // register display listener callback + FakeDisplayManagerCallback callback = new FakeDisplayManagerCallback(displayId); + displayManagerBinderService.registerCallback(callback); + return callback; + } + + private FakeDisplayDevice createFakeDisplayDevice(DisplayManagerService displayManager, + float[] refreshRates) { + FakeDisplayDevice displayDevice = new FakeDisplayDevice(); + DisplayDeviceInfo displayDeviceInfo = new DisplayDeviceInfo(); + int width = 100; + int height = 200; + displayDeviceInfo.supportedModes = new Display.Mode[refreshRates.length]; + for (int i = 0; i < refreshRates.length; i++) { + displayDeviceInfo.supportedModes[i] = + new Display.Mode(i + 1, width, height, refreshRates[i]); + } + displayDeviceInfo.modeId = 1; + displayDeviceInfo.width = width; + displayDeviceInfo.height = height; + final Rect zeroRect = new Rect(); + displayDeviceInfo.displayCutout = new DisplayCutout( + Insets.of(0, 10, 0, 0), + zeroRect, new Rect(0, 0, 10, 10), zeroRect, zeroRect); + displayDeviceInfo.flags = DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY; + displayDevice.setDisplayDeviceInfo(displayDeviceInfo); + displayManager.getDisplayDeviceRepository() + .onDisplayDeviceEvent(displayDevice, DisplayAdapter.DISPLAY_DEVICE_EVENT_ADDED); + return displayDevice; + } + private void registerDefaultDisplays(DisplayManagerService displayManager) { Handler handler = displayManager.getDisplayHandler(); // Would prefer to call displayManager.onStart() directly here but it performs binderService @@ -598,6 +955,10 @@ public class DisplayManagerServiceTest { mCalled = true; } } + + public void clear() { + mCalled = false; + } } private class FakeDisplayDevice extends DisplayDevice { diff --git a/services/tests/servicestests/src/com/android/server/inputmethod/InputMethodManagerServiceTests.java b/services/tests/servicestests/src/com/android/server/inputmethod/InputMethodManagerServiceTests.java index 8afc3d30efa3..1db5544871bf 100644 --- a/services/tests/servicestests/src/com/android/server/inputmethod/InputMethodManagerServiceTests.java +++ b/services/tests/servicestests/src/com/android/server/inputmethod/InputMethodManagerServiceTests.java @@ -18,6 +18,8 @@ package com.android.server.inputmethod; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.Display.INVALID_DISPLAY; +import static android.view.WindowManager.DISPLAY_IME_POLICY_LOCAL; +import static android.view.WindowManager.DISPLAY_IME_POLICY_FALLBACK_DISPLAY; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; @@ -38,9 +40,9 @@ public class InputMethodManagerServiceTests { (displayId) -> { switch (displayId) { case SYSTEM_DECORATION_SUPPORT_DISPLAY_ID: - return true; + return DISPLAY_IME_POLICY_LOCAL; case NO_SYSTEM_DECORATION_SUPPORT_DISPLAY_ID: - return false; + return DISPLAY_IME_POLICY_FALLBACK_DISPLAY; default: throw new IllegalArgumentException("Unknown displayId=" + displayId); } @@ -49,7 +51,7 @@ public class InputMethodManagerServiceTests { static InputMethodManagerService.ImeDisplayValidator sMustNotBeCalledChecker = (displayId) -> { fail("Should not pass to display config check for this test case."); - return false; + return DISPLAY_IME_POLICY_FALLBACK_DISPLAY; }; @Test diff --git a/services/tests/servicestests/src/com/android/server/location/timezone/ControllerImplTest.java b/services/tests/servicestests/src/com/android/server/location/timezone/ControllerImplTest.java index c4b19e84bccb..00cef8fb8481 100644 --- a/services/tests/servicestests/src/com/android/server/location/timezone/ControllerImplTest.java +++ b/services/tests/servicestests/src/com/android/server/location/timezone/ControllerImplTest.java @@ -15,10 +15,9 @@ */ package com.android.server.location.timezone; -import static android.location.timezone.LocationTimeZoneEvent.EVENT_TYPE_PERMANENT_FAILURE; -import static android.location.timezone.LocationTimeZoneEvent.EVENT_TYPE_SUCCESS; -import static android.location.timezone.LocationTimeZoneEvent.EVENT_TYPE_UNCERTAIN; - +import static com.android.internal.location.timezone.LocationTimeZoneEvent.EVENT_TYPE_PERMANENT_FAILURE; +import static com.android.internal.location.timezone.LocationTimeZoneEvent.EVENT_TYPE_SUCCESS; +import static com.android.internal.location.timezone.LocationTimeZoneEvent.EVENT_TYPE_UNCERTAIN; import static com.android.server.location.timezone.LocationTimeZoneProvider.ProviderState.PROVIDER_STATE_DISABLED; import static com.android.server.location.timezone.LocationTimeZoneProvider.ProviderState.PROVIDER_STATE_ENABLED_CERTAIN; import static com.android.server.location.timezone.LocationTimeZoneProvider.ProviderState.PROVIDER_STATE_ENABLED_INITIALIZING; @@ -37,10 +36,10 @@ import static java.util.Arrays.asList; import android.annotation.NonNull; import android.annotation.Nullable; -import android.location.timezone.LocationTimeZoneEvent; import android.platform.test.annotations.Presubmit; import android.util.IndentingPrintWriter; +import com.android.internal.location.timezone.LocationTimeZoneEvent; import com.android.server.location.timezone.LocationTimeZoneProvider.ProviderState.ProviderStateEnum; import com.android.server.timezonedetector.ConfigurationInternal; import com.android.server.timezonedetector.GeolocationTimeZoneSuggestion; @@ -60,7 +59,7 @@ import java.util.Objects; @Presubmit public class ControllerImplTest { - private static final long ARBITRARY_TIME = 12345L; + private static final long ARBITRARY_TIME_MILLIS = 12345L; private static final LocationTimeZoneEvent USER1_SUCCESS_LOCATION_TIME_ZONE_EVENT1 = createLocationTimeZoneEvent(EVENT_TYPE_SUCCESS, asList("Europe/London")); @@ -936,7 +935,7 @@ public class ControllerImplTest { private static LocationTimeZoneEvent createLocationTimeZoneEvent( int eventType, @Nullable List<String> timeZoneIds) { LocationTimeZoneEvent.Builder builder = new LocationTimeZoneEvent.Builder() - .setElapsedRealtimeNanos(ARBITRARY_TIME) + .setElapsedRealtimeMillis(ARBITRARY_TIME_MILLIS) .setEventType(eventType); if (timeZoneIds != null) { builder.setTimeZoneIds(timeZoneIds); diff --git a/services/tests/servicestests/src/com/android/server/powerstats/PowerStatsServiceTest.java b/services/tests/servicestests/src/com/android/server/powerstats/PowerStatsServiceTest.java index 59aff8d43755..b26d1efef2a8 100644 --- a/services/tests/servicestests/src/com/android/server/powerstats/PowerStatsServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/powerstats/PowerStatsServiceTest.java @@ -23,6 +23,10 @@ import android.content.Context; import android.hardware.power.stats.ChannelInfo; import android.hardware.power.stats.EnergyConsumerResult; import android.hardware.power.stats.EnergyMeasurement; +import android.hardware.power.stats.PowerEntityInfo; +import android.hardware.power.stats.StateInfo; +import android.hardware.power.stats.StateResidency; +import android.hardware.power.stats.StateResidencyResult; import androidx.test.InstrumentationRegistry; @@ -56,8 +60,13 @@ public class PowerStatsServiceTest { private static final String MODEL_FILENAME = "modeltest"; private static final String PROTO_OUTPUT_FILENAME = "powerstats.proto"; private static final String CHANNEL_NAME = "channelname"; + private static final String POWER_ENTITY_NAME = "powerentityinfo"; + private static final String STATE_NAME = "stateinfo"; private static final int ENERGY_METER_COUNT = 8; private static final int ENERGY_CONSUMER_COUNT = 2; + private static final int POWER_ENTITY_COUNT = 3; + private static final int STATE_INFO_COUNT = 5; + private static final int STATE_RESIDENCY_COUNT = 4; private final Context mContext = InstrumentationRegistry.getInstrumentation().getContext(); private PowerStatsService mService; @@ -118,6 +127,43 @@ public class PowerStatsServiceTest { public static final class TestPowerStatsHALWrapper implements IPowerStatsHALWrapper { @Override + public PowerEntityInfo[] getPowerEntityInfo() { + PowerEntityInfo[] powerEntityInfoList = new PowerEntityInfo[POWER_ENTITY_COUNT]; + for (int i = 0; i < powerEntityInfoList.length; i++) { + powerEntityInfoList[i] = new PowerEntityInfo(); + powerEntityInfoList[i].powerEntityId = i; + powerEntityInfoList[i].powerEntityName = new String(POWER_ENTITY_NAME + i); + powerEntityInfoList[i].states = new StateInfo[STATE_INFO_COUNT]; + for (int j = 0; j < powerEntityInfoList[i].states.length; j++) { + powerEntityInfoList[i].states[j] = new StateInfo(); + powerEntityInfoList[i].states[j].stateId = j; + powerEntityInfoList[i].states[j].stateName = new String(STATE_NAME + i); + } + } + return powerEntityInfoList; + } + + @Override + public StateResidencyResult[] getStateResidency(int[] powerEntityIds) { + StateResidencyResult[] stateResidencyResultList = + new StateResidencyResult[POWER_ENTITY_COUNT]; + for (int i = 0; i < stateResidencyResultList.length; i++) { + stateResidencyResultList[i] = new StateResidencyResult(); + stateResidencyResultList[i].powerEntityId = i; + stateResidencyResultList[i].stateResidencyData = + new StateResidency[STATE_RESIDENCY_COUNT]; + for (int j = 0; j < stateResidencyResultList[i].stateResidencyData.length; j++) { + stateResidencyResultList[i].stateResidencyData[j] = new StateResidency(); + stateResidencyResultList[i].stateResidencyData[j].totalTimeInStateMs = j; + stateResidencyResultList[i].stateResidencyData[j].totalStateEntryCount = j; + stateResidencyResultList[i].stateResidencyData[j].lastEntryTimestampMs = j; + } + } + + return stateResidencyResultList; + } + + @Override public int[] getEnergyConsumerInfo() { int[] energyConsumerInfoList = new int[ENERGY_CONSUMER_COUNT]; for (int i = 0; i < energyConsumerInfoList.length; i++) { @@ -127,7 +173,7 @@ public class PowerStatsServiceTest { } @Override - public EnergyConsumerResult[] getEnergyConsumed() { + public EnergyConsumerResult[] getEnergyConsumed(int[] energyConsumerIds) { EnergyConsumerResult[] energyConsumedList = new EnergyConsumerResult[ENERGY_CONSUMER_COUNT]; for (int i = 0; i < energyConsumedList.length; i++) { @@ -151,7 +197,7 @@ public class PowerStatsServiceTest { } @Override - public EnergyMeasurement[] readEnergyMeters() { + public EnergyMeasurement[] readEnergyMeters(int[] channelIds) { EnergyMeasurement[] energyMeasurementList = new EnergyMeasurement[ENERGY_METER_COUNT]; for (int i = 0; i < energyMeasurementList.length; i++) { energyMeasurementList[i] = new EnergyMeasurement(); diff --git a/services/tests/servicestests/src/com/android/server/rollback/RollbackStoreTest.java b/services/tests/servicestests/src/com/android/server/rollback/RollbackStoreTest.java index eedc9781aa40..c42f936d3ab4 100644 --- a/services/tests/servicestests/src/com/android/server/rollback/RollbackStoreTest.java +++ b/services/tests/servicestests/src/com/android/server/rollback/RollbackStoreTest.java @@ -110,6 +110,8 @@ public class RollbackStoreTest { @Rule public TemporaryFolder mFolder = new TemporaryFolder(); + @Rule + public TemporaryFolder mHistoryDir = new TemporaryFolder(); private File mRollbackDir; @@ -117,7 +119,7 @@ public class RollbackStoreTest { @Before public void setUp() throws Exception { - mRollbackStore = new RollbackStore(mFolder.getRoot()); + mRollbackStore = new RollbackStore(mFolder.getRoot(), mHistoryDir.getRoot()); mRollbackDir = mFolder.newFolder(ID + ""); mFolder.newFile("rollback.json"); } @@ -202,6 +204,8 @@ public class RollbackStoreTest { origRb.info.getPackages().add(pkgInfo1); origRb.info.getPackages().add(pkgInfo2); + origRb.setState(Rollback.ROLLBACK_STATE_AVAILABLE, "hello world"); + RollbackStore.saveRollback(origRb); List<Rollback> loadedRollbacks = mRollbackStore.loadRollbacks(); @@ -324,10 +328,26 @@ public class RollbackStoreTest { assertThat(expectedFile.exists()).isFalse(); } - private void assertRollbacksAreEquivalent(Rollback b, Rollback a) { - assertThat(b.info.getRollbackId()).isEqualTo(ID); + @Test + public void saveToHistoryAndLoad() { + Rollback origRb = mRollbackStore.createNonStagedRollback( + ID, USER, INSTALLER, null, new SparseIntArray(0)); + mRollbackStore.saveRollbackToHistory(origRb); + + List<Rollback> loadedRollbacks = mRollbackStore.loadHistorialRollbacks(); + assertThat(loadedRollbacks).hasSize(1); + Rollback loadedRb = loadedRollbacks.get(0); + + assertRollbacksAreEquivalentExcludingBackupDir(loadedRb, origRb); + } + private void assertRollbacksAreEquivalent(Rollback b, Rollback a) { assertThat(b.getBackupDir()).isEqualTo(a.getBackupDir()); + assertRollbacksAreEquivalentExcludingBackupDir(b, a); + } + + private void assertRollbacksAreEquivalentExcludingBackupDir(Rollback b, Rollback a) { + assertThat(b.info.getRollbackId()).isEqualTo(ID); assertThat(b.isRestoreUserDataInProgress()) .isEqualTo(a.isRestoreUserDataInProgress()); @@ -337,6 +357,7 @@ public class RollbackStoreTest { assertThat(b.isEnabling()).isEqualTo(a.isEnabling()); assertThat(b.isAvailable()).isEqualTo(a.isAvailable()); assertThat(b.isCommitted()).isEqualTo(a.isCommitted()); + assertThat(b.getStateDescription()).isEqualTo(a.getStateDescription()); assertThat(b.isStaged()).isEqualTo(a.isStaged()); diff --git a/services/tests/servicestests/src/com/android/server/rollback/RollbackUnitTest.java b/services/tests/servicestests/src/com/android/server/rollback/RollbackUnitTest.java index cd2c9230221c..cf1ed4815a74 100644 --- a/services/tests/servicestests/src/com/android/server/rollback/RollbackUnitTest.java +++ b/services/tests/servicestests/src/com/android/server/rollback/RollbackUnitTest.java @@ -123,7 +123,7 @@ public class RollbackUnitTest { public void deletedRollbackCannotBeMadeAvailable() { Rollback rollback = new Rollback(123, new File("/test/testing"), -1, USER, INSTALLER); - rollback.delete(mMockDataHelper); + rollback.delete(mMockDataHelper, "test"); assertThat(rollback.isDeleted()).isTrue(); @@ -221,7 +221,7 @@ public class RollbackUnitTest { PackageRollbackInfo pkgInfo2 = newPkgInfoFor(PKG_2, 18, 12, true); rollback.info.getPackages().addAll(Arrays.asList(pkgInfo1, pkgInfo2)); - rollback.delete(mMockDataHelper); + rollback.delete(mMockDataHelper, "test"); assertThat(rollback.isDeleted()).isTrue(); @@ -247,7 +247,7 @@ public class RollbackUnitTest { verify(mMockDataHelper).snapshotAppData(eq(123), pkgRollbackInfoFor(PKG_2), eq(userIds)); - rollback.delete(mMockDataHelper); + rollback.delete(mMockDataHelper, "test"); verify(mMockDataHelper).destroyAppDataSnapshot(eq(123), pkgRollbackInfoFor(PKG_2), eq(111)); verify(mMockDataHelper).destroyAppDataSnapshot(eq(123), pkgRollbackInfoFor(PKG_2), eq(222)); @@ -269,7 +269,7 @@ public class RollbackUnitTest { verify(mMockDataHelper).snapshotAppData(eq(123), pkgRollbackInfoFor(PKG_2), eq(userIds)); - rollback.delete(mMockDataHelper); + rollback.delete(mMockDataHelper, "test"); verify(mMockDataHelper, never()) .destroyAppDataSnapshot(anyInt(), pkgRollbackInfoFor(PKG_2), anyInt()); diff --git a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java index 9f59763cfa58..e101a06feb4e 100644 --- a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java @@ -229,10 +229,6 @@ public class TimeDetectorServiceTest { private boolean mDumpCalled; @Override - public void initialize(Callback ignored) { - } - - @Override public void suggestTelephonyTime(TelephonyTimeSuggestion timeSuggestion) { mLastTelephonySuggestion = timeSuggestion; } diff --git a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorStrategyImplTest.java b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorStrategyImplTest.java index 1d79d0d3b86e..217de55fb400 100644 --- a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorStrategyImplTest.java +++ b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorStrategyImplTest.java @@ -25,9 +25,6 @@ import static org.junit.Assert.fail; import android.app.timedetector.ManualTimeSuggestion; import android.app.timedetector.NetworkTimeSuggestion; import android.app.timedetector.TelephonyTimeSuggestion; -import android.icu.util.Calendar; -import android.icu.util.GregorianCalendar; -import android.icu.util.TimeZone; import android.os.TimestampedValue; import androidx.test.runner.AndroidJUnit4; @@ -37,20 +34,25 @@ import org.junit.Test; import org.junit.runner.RunWith; import java.time.Duration; +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneOffset; @RunWith(AndroidJUnit4.class) public class TimeDetectorStrategyImplTest { - private static final TimestampedValue<Long> ARBITRARY_CLOCK_INITIALIZATION_INFO = + private static final Instant TIME_LOWER_BOUND = createUtcTime(2009, 1, 1, 12, 0, 0); + + private static final TimestampedValue<Instant> ARBITRARY_CLOCK_INITIALIZATION_INFO = new TimestampedValue<>( 123456789L /* realtimeClockMillis */, - createUtcTime(2008, 5, 23, 12, 0, 0)); + createUtcTime(2010, 5, 23, 12, 0, 0)); /** * An arbitrary time, very different from the {@link #ARBITRARY_CLOCK_INITIALIZATION_INFO} * time. Can be used as the basis for time suggestions. */ - private static final long ARBITRARY_TEST_TIME_MILLIS = createUtcTime(2018, 1, 1, 12, 0, 0); + private static final Instant ARBITRARY_TEST_TIME = createUtcTime(2018, 1, 1, 12, 0, 0); private static final int ARBITRARY_SLOT_INDEX = 123456; @@ -67,10 +69,10 @@ public class TimeDetectorStrategyImplTest { .pokeAutoTimeDetectionEnabled(true); int slotIndex = ARBITRARY_SLOT_INDEX; - long testTimeMillis = ARBITRARY_TEST_TIME_MILLIS; + Instant testTime = ARBITRARY_TEST_TIME; TelephonyTimeSuggestion timeSuggestion = - mScript.generateTelephonyTimeSuggestion(slotIndex, testTimeMillis); + mScript.generateTelephonyTimeSuggestion(slotIndex, testTime); mScript.simulateTimePassing() .simulateTelephonyTimeSuggestion(timeSuggestion); @@ -106,9 +108,9 @@ public class TimeDetectorStrategyImplTest { // Send the first time signal. It should be used. { TelephonyTimeSuggestion timeSuggestion1 = - mScript.generateTelephonyTimeSuggestion(slotIndex, ARBITRARY_TEST_TIME_MILLIS); + mScript.generateTelephonyTimeSuggestion(slotIndex, ARBITRARY_TEST_TIME); - // Increment the the device clocks to simulate the passage of time. + // Increment the device clocks to simulate the passage of time. mScript.simulateTimePassing(clockIncrementMillis); long expectedSystemClockMillis1 = @@ -157,13 +159,13 @@ public class TimeDetectorStrategyImplTest { // uses the lowest slotIndex when multiple telephony suggestions are available. int slotIndex1 = ARBITRARY_SLOT_INDEX; int slotIndex2 = ARBITRARY_SLOT_INDEX + 1; - long slotIndex1TimeMillis = ARBITRARY_TEST_TIME_MILLIS; - long slotIndex2TimeMillis = ARBITRARY_TEST_TIME_MILLIS + Duration.ofDays(1).toMillis(); + Instant slotIndex1Time = ARBITRARY_TEST_TIME; + Instant slotIndex2Time = ARBITRARY_TEST_TIME.plus(Duration.ofDays(1)); // Make a suggestion with slotIndex2. { TelephonyTimeSuggestion slotIndex2TimeSuggestion = - mScript.generateTelephonyTimeSuggestion(slotIndex2, slotIndex2TimeMillis); + mScript.generateTelephonyTimeSuggestion(slotIndex2, slotIndex2Time); mScript.simulateTimePassing(); long expectedSystemClockMillis = @@ -180,7 +182,7 @@ public class TimeDetectorStrategyImplTest { // Now make a different suggestion with slotIndex1. { TelephonyTimeSuggestion slotIndex1TimeSuggestion = - mScript.generateTelephonyTimeSuggestion(slotIndex1, slotIndex1TimeMillis); + mScript.generateTelephonyTimeSuggestion(slotIndex1, slotIndex1Time); mScript.simulateTimePassing(); long expectedSystemClockMillis = @@ -198,7 +200,7 @@ public class TimeDetectorStrategyImplTest { // slotIndex1 suggestion will still "win". { TelephonyTimeSuggestion slotIndex2TimeSuggestion = - mScript.generateTelephonyTimeSuggestion(slotIndex2, slotIndex2TimeMillis); + mScript.generateTelephonyTimeSuggestion(slotIndex2, slotIndex2Time); mScript.simulateTimePassing(); mScript.simulateTelephonyTimeSuggestion(slotIndex2TimeSuggestion) @@ -213,7 +215,7 @@ public class TimeDetectorStrategyImplTest { // is in an older "bucket". { TelephonyTimeSuggestion slotIndex2TimeSuggestion = - mScript.generateTelephonyTimeSuggestion(slotIndex2, slotIndex2TimeMillis); + mScript.generateTelephonyTimeSuggestion(slotIndex2, slotIndex2Time); mScript.simulateTimePassing(); long expectedSystemClockMillis = @@ -232,7 +234,7 @@ public class TimeDetectorStrategyImplTest { int slotIndex = ARBITRARY_SLOT_INDEX; TelephonyTimeSuggestion timeSuggestion = - mScript.generateTelephonyTimeSuggestion(slotIndex, ARBITRARY_TEST_TIME_MILLIS); + mScript.generateTelephonyTimeSuggestion(slotIndex, ARBITRARY_TEST_TIME); mScript.simulateTimePassing() .simulateTelephonyTimeSuggestion(timeSuggestion) .verifySystemClockWasNotSetAndResetCallTracking() @@ -246,11 +248,11 @@ public class TimeDetectorStrategyImplTest { .pokeThresholds(systemClockUpdateThreshold) .pokeAutoTimeDetectionEnabled(true); - long testTimeMillis = ARBITRARY_TEST_TIME_MILLIS; + Instant testTime = ARBITRARY_TEST_TIME; int slotIndex = ARBITRARY_SLOT_INDEX; TelephonyTimeSuggestion timeSuggestion1 = - mScript.generateTelephonyTimeSuggestion(slotIndex, testTimeMillis); + mScript.generateTelephonyTimeSuggestion(slotIndex, testTime); TimestampedValue<Long> utcTime1 = timeSuggestion1.getUtcTime(); // Initialize the strategy / device with a time set from a telephony suggestion. @@ -300,6 +302,23 @@ public class TimeDetectorStrategyImplTest { } @Test + public void telephonyTimeSuggestion_ignoredWhenReferencedTimeIsInThePast() { + mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO) + .pokeAutoTimeDetectionEnabled(true); + + int slotIndex = ARBITRARY_SLOT_INDEX; + Instant suggestedTime = TIME_LOWER_BOUND.minus(Duration.ofDays(1)); + + TelephonyTimeSuggestion timeSuggestion = + mScript.generateTelephonyTimeSuggestion( + slotIndex, suggestedTime); + + mScript.simulateTelephonyTimeSuggestion(timeSuggestion) + .verifySystemClockWasNotSetAndResetCallTracking() + .assertLatestTelephonySuggestion(slotIndex, null); + } + + @Test public void testSuggestTelephonyTime_timeDetectionToggled() { final int clockIncrementMillis = 100; final int systemClockUpdateThreshold = 2000; @@ -308,9 +327,9 @@ public class TimeDetectorStrategyImplTest { .pokeAutoTimeDetectionEnabled(false); int slotIndex = ARBITRARY_SLOT_INDEX; - long testTimeMillis = ARBITRARY_TEST_TIME_MILLIS; + Instant testTime = ARBITRARY_TEST_TIME; TelephonyTimeSuggestion timeSuggestion1 = - mScript.generateTelephonyTimeSuggestion(slotIndex, testTimeMillis); + mScript.generateTelephonyTimeSuggestion(slotIndex, testTime); TimestampedValue<Long> utcTime1 = timeSuggestion1.getUtcTime(); // Simulate time passing. @@ -366,9 +385,9 @@ public class TimeDetectorStrategyImplTest { .pokeAutoTimeDetectionEnabled(true); int slotIndex = ARBITRARY_SLOT_INDEX; - long testTimeMillis = ARBITRARY_TEST_TIME_MILLIS; + Instant testTime = ARBITRARY_TEST_TIME; TelephonyTimeSuggestion telephonySuggestion = - mScript.generateTelephonyTimeSuggestion(slotIndex, testTimeMillis); + mScript.generateTelephonyTimeSuggestion(slotIndex, testTime); mScript.simulateTimePassing(); @@ -397,7 +416,7 @@ public class TimeDetectorStrategyImplTest { .pokeAutoTimeDetectionEnabled(false); ManualTimeSuggestion timeSuggestion = - mScript.generateManualTimeSuggestion(ARBITRARY_TEST_TIME_MILLIS); + mScript.generateManualTimeSuggestion(ARBITRARY_TEST_TIME); mScript.simulateTimePassing(); @@ -416,9 +435,9 @@ public class TimeDetectorStrategyImplTest { int slotIndex = ARBITRARY_SLOT_INDEX; // Simulate a telephony suggestion. - long testTimeMillis = ARBITRARY_TEST_TIME_MILLIS; + Instant testTime = ARBITRARY_TEST_TIME; TelephonyTimeSuggestion telephonyTimeSuggestion = - mScript.generateTelephonyTimeSuggestion(slotIndex, testTimeMillis); + mScript.generateTelephonyTimeSuggestion(slotIndex, testTime); // Simulate the passage of time. mScript.simulateTimePassing(); @@ -441,9 +460,9 @@ public class TimeDetectorStrategyImplTest { mScript.simulateTimePassing(); // Simulate a manual suggestion 1 day different from the auto suggestion. - long manualTimeMillis = testTimeMillis + Duration.ofDays(1).toMillis(); + Instant manualTime = testTime.plus(Duration.ofDays(1)); ManualTimeSuggestion manualTimeSuggestion = - mScript.generateManualTimeSuggestion(manualTimeMillis); + mScript.generateManualTimeSuggestion(manualTime); mScript.simulateTimePassing(); long expectedManualClockMillis = @@ -478,7 +497,7 @@ public class TimeDetectorStrategyImplTest { .pokeAutoTimeDetectionEnabled(true); ManualTimeSuggestion timeSuggestion = - mScript.generateManualTimeSuggestion(ARBITRARY_TEST_TIME_MILLIS); + mScript.generateManualTimeSuggestion(ARBITRARY_TEST_TIME); mScript.simulateTimePassing() .simulateManualTimeSuggestion(timeSuggestion, false /* expectedResult */) @@ -486,12 +505,25 @@ public class TimeDetectorStrategyImplTest { } @Test + public void suggestManualTime_ignoresTimeLowerBound() { + mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO) + .pokeAutoTimeDetectionEnabled(false); + Instant suggestedTime = TIME_LOWER_BOUND.minus(Duration.ofDays(1)); + + ManualTimeSuggestion timeSuggestion = + mScript.generateManualTimeSuggestion(suggestedTime); + + mScript.simulateManualTimeSuggestion(timeSuggestion, true /* expectedResult */) + .verifySystemClockWasSetAndResetCallTracking(suggestedTime.toEpochMilli()); + } + + @Test public void testSuggestNetworkTime_autoTimeEnabled() { mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO) .pokeAutoTimeDetectionEnabled(true); NetworkTimeSuggestion timeSuggestion = - mScript.generateNetworkTimeSuggestion(ARBITRARY_TEST_TIME_MILLIS); + mScript.generateNetworkTimeSuggestion(ARBITRARY_TEST_TIME); mScript.simulateTimePassing(); @@ -507,7 +539,7 @@ public class TimeDetectorStrategyImplTest { .pokeAutoTimeDetectionEnabled(false); NetworkTimeSuggestion timeSuggestion = - mScript.generateNetworkTimeSuggestion(ARBITRARY_TEST_TIME_MILLIS); + mScript.generateNetworkTimeSuggestion(ARBITRARY_TEST_TIME); mScript.simulateTimePassing() .simulateNetworkTimeSuggestion(timeSuggestion) @@ -520,16 +552,16 @@ public class TimeDetectorStrategyImplTest { .pokeAutoTimeDetectionEnabled(true); // Three obviously different times that could not be mistaken for each other. - long networkTimeMillis1 = ARBITRARY_TEST_TIME_MILLIS; - long networkTimeMillis2 = ARBITRARY_TEST_TIME_MILLIS + Duration.ofDays(30).toMillis(); - long telephonyTimeMillis = ARBITRARY_TEST_TIME_MILLIS + Duration.ofDays(60).toMillis(); + Instant networkTime1 = ARBITRARY_TEST_TIME; + Instant networkTime2 = ARBITRARY_TEST_TIME.plus(Duration.ofDays(30)); + Instant telephonyTime = ARBITRARY_TEST_TIME.plus(Duration.ofDays(60)); // A small increment used to simulate the passage of time, but not enough to interfere with // macro-level time changes associated with suggestion age. final long smallTimeIncrementMillis = 101; // A network suggestion is made. It should be used because there is no telephony suggestion. NetworkTimeSuggestion networkTimeSuggestion1 = - mScript.generateNetworkTimeSuggestion(networkTimeMillis1); + mScript.generateNetworkTimeSuggestion(networkTime1); mScript.simulateTimePassing(smallTimeIncrementMillis) .simulateNetworkTimeSuggestion(networkTimeSuggestion1) .verifySystemClockWasSetAndResetCallTracking( @@ -548,7 +580,7 @@ public class TimeDetectorStrategyImplTest { // Now a telephony suggestion is made. Telephony suggestions are prioritized over network // suggestions so it should "win". TelephonyTimeSuggestion telephonyTimeSuggestion = - mScript.generateTelephonyTimeSuggestion(ARBITRARY_SLOT_INDEX, telephonyTimeMillis); + mScript.generateTelephonyTimeSuggestion(ARBITRARY_SLOT_INDEX, telephonyTime); mScript.simulateTimePassing(smallTimeIncrementMillis) .simulateTelephonyTimeSuggestion(telephonyTimeSuggestion) .verifySystemClockWasSetAndResetCallTracking( @@ -568,7 +600,7 @@ public class TimeDetectorStrategyImplTest { // Now another network suggestion is made. Telephony suggestions are prioritized over // network suggestions so the latest telephony suggestion should still "win". NetworkTimeSuggestion networkTimeSuggestion2 = - mScript.generateNetworkTimeSuggestion(networkTimeMillis2); + mScript.generateNetworkTimeSuggestion(networkTime2); mScript.simulateTimePassing(smallTimeIncrementMillis) .simulateNetworkTimeSuggestion(networkTimeSuggestion2) .verifySystemClockWasNotSetAndResetCallTracking(); @@ -612,11 +644,25 @@ public class TimeDetectorStrategyImplTest { assertNull(mScript.peekBestTelephonySuggestion()); } + @Test + public void networkTimeSuggestion_ignoredWhenReferencedTimeIsInThePast() { + mScript.pokeFakeClocks(ARBITRARY_CLOCK_INITIALIZATION_INFO) + .pokeAutoTimeDetectionEnabled(true); + + Instant suggestedTime = TIME_LOWER_BOUND.minus(Duration.ofDays(1)); + NetworkTimeSuggestion timeSuggestion = mScript + .generateNetworkTimeSuggestion(suggestedTime); + + mScript.simulateNetworkTimeSuggestion(timeSuggestion) + .verifySystemClockWasNotSetAndResetCallTracking() + .assertLatestNetworkSuggestion(null); + } + /** * A fake implementation of TimeDetectorStrategy.Callback. Besides tracking changes and behaving * like the real thing should, it also asserts preconditions. */ - private static class FakeCallback implements TimeDetectorStrategy.Callback { + private static class FakeCallback implements TimeDetectorStrategyImpl.Callback { private boolean mAutoTimeDetectionEnabled; private boolean mWakeLockAcquired; private long mElapsedRealtimeMillis; @@ -637,6 +683,11 @@ public class TimeDetectorStrategyImplTest { } @Override + public Instant autoTimeLowerBound() { + return TIME_LOWER_BOUND; + } + + @Override public void acquireWakeLock() { if (mWakeLockAcquired) { fail("Wake lock already acquired"); @@ -703,7 +754,10 @@ public class TimeDetectorStrategyImplTest { } void verifySystemClockNotSet() { - assertFalse(mSystemClockWasSet); + assertFalse( + String.format("System clock was manipulated and set to %s(=%s)", + Instant.ofEpochMilli(mSystemClockMillis), mSystemClockMillis), + mSystemClockWasSet); } void verifySystemClockWasSet(long expectedSystemClockMillis) { @@ -731,9 +785,7 @@ public class TimeDetectorStrategyImplTest { Script() { mFakeCallback = new FakeCallback(); - mTimeDetectorStrategy = new TimeDetectorStrategyImpl(); - mTimeDetectorStrategy.initialize(mFakeCallback); - + mTimeDetectorStrategy = new TimeDetectorStrategyImpl(mFakeCallback); } Script pokeAutoTimeDetectionEnabled(boolean enabled) { @@ -741,9 +793,9 @@ public class TimeDetectorStrategyImplTest { return this; } - Script pokeFakeClocks(TimestampedValue<Long> timeInfo) { + Script pokeFakeClocks(TimestampedValue<Instant> timeInfo) { mFakeCallback.pokeElapsedRealtimeMillis(timeInfo.getReferenceTimeMillis()); - mFakeCallback.pokeSystemClockMillis(timeInfo.getValue()); + mFakeCallback.pokeSystemClockMillis(timeInfo.getValue().toEpochMilli()); return this; } @@ -767,7 +819,13 @@ public class TimeDetectorStrategyImplTest { Script simulateManualTimeSuggestion( ManualTimeSuggestion timeSuggestion, boolean expectedResult) { - assertEquals(expectedResult, mTimeDetectorStrategy.suggestManualTime(timeSuggestion)); + String errorMessage = expectedResult + ? "Manual time suggestion was ignored, but expected to be accepted." + : "Manual time suggestion was accepted, but expected to be ignored."; + assertEquals( + errorMessage, + expectedResult, + mTimeDetectorStrategy.suggestManualTime(timeSuggestion)); return this; } @@ -810,7 +868,10 @@ public class TimeDetectorStrategyImplTest { * White box test info: Asserts the latest suggestion for the slotIndex is as expected. */ Script assertLatestTelephonySuggestion(int slotIndex, TelephonyTimeSuggestion expected) { - assertEquals(expected, mTimeDetectorStrategy.getLatestTelephonySuggestion(slotIndex)); + assertEquals( + "Expected to see " + expected + " at slotIndex=" + slotIndex + ", but got " + + mTimeDetectorStrategy.getLatestTelephonySuggestion(slotIndex), + expected, mTimeDetectorStrategy.getLatestTelephonySuggestion(slotIndex)); return this; } @@ -842,9 +903,11 @@ public class TimeDetectorStrategyImplTest { * Generates a ManualTimeSuggestion using the current elapsed realtime clock for the * reference time. */ - ManualTimeSuggestion generateManualTimeSuggestion(long timeMillis) { + ManualTimeSuggestion generateManualTimeSuggestion(Instant suggestedTime) { TimestampedValue<Long> utcTime = - new TimestampedValue<>(mFakeCallback.peekElapsedRealtimeMillis(), timeMillis); + new TimestampedValue<>( + mFakeCallback.peekElapsedRealtimeMillis(), + suggestedTime.toEpochMilli()); return new ManualTimeSuggestion(utcTime); } @@ -852,21 +915,33 @@ public class TimeDetectorStrategyImplTest { * Generates a {@link TelephonyTimeSuggestion} using the current elapsed realtime clock for * the reference time. */ - TelephonyTimeSuggestion generateTelephonyTimeSuggestion(int slotIndex, Long timeMillis) { - TimestampedValue<Long> time = null; - if (timeMillis != null) { - time = new TimestampedValue<>(peekElapsedRealtimeMillis(), timeMillis); - } + TelephonyTimeSuggestion generateTelephonyTimeSuggestion(int slotIndex, long timeMillis) { + TimestampedValue<Long> time = + new TimestampedValue<>(peekElapsedRealtimeMillis(), timeMillis); return createTelephonyTimeSuggestion(slotIndex, time); } /** + * Generates a {@link TelephonyTimeSuggestion} using the current elapsed realtime clock for + * the reference time. + */ + TelephonyTimeSuggestion generateTelephonyTimeSuggestion( + int slotIndex, Instant suggestedTime) { + if (suggestedTime == null) { + return createTelephonyTimeSuggestion(slotIndex, null); + } + return generateTelephonyTimeSuggestion(slotIndex, suggestedTime.toEpochMilli()); + } + + /** * Generates a NetworkTimeSuggestion using the current elapsed realtime clock for the * reference time. */ - NetworkTimeSuggestion generateNetworkTimeSuggestion(long timeMillis) { + NetworkTimeSuggestion generateNetworkTimeSuggestion(Instant suggestedTime) { TimestampedValue<Long> utcTime = - new TimestampedValue<>(mFakeCallback.peekElapsedRealtimeMillis(), timeMillis); + new TimestampedValue<>( + mFakeCallback.peekElapsedRealtimeMillis(), + suggestedTime.toEpochMilli()); return new NetworkTimeSuggestion(utcTime); } @@ -886,11 +961,9 @@ public class TimeDetectorStrategyImplTest { .build(); } - private static long createUtcTime(int year, int monthInYear, int day, int hourOfDay, int minute, - int second) { - Calendar cal = new GregorianCalendar(TimeZone.getTimeZone("Etc/UTC")); - cal.clear(); - cal.set(year, monthInYear - 1, day, hourOfDay, minute, second); - return cal.getTimeInMillis(); + private static Instant createUtcTime(int year, int monthInYear, int day, int hourOfDay, + int minute, int second) { + return LocalDateTime.of(year, monthInYear, day, hourOfDay, minute, second) + .toInstant(ZoneOffset.UTC); } } diff --git a/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java b/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java index 0ad669f32060..11fb0021be62 100644 --- a/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java +++ b/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java @@ -65,6 +65,7 @@ import android.annotation.NonNull; import android.app.ActivityManager; import android.app.usage.AppStandbyInfo; import android.app.usage.UsageEvents; +import android.app.usage.UsageStatsManagerInternal; import android.appwidget.AppWidgetManager; import android.content.Context; import android.content.ContextWrapper; @@ -86,9 +87,11 @@ import androidx.test.InstrumentationRegistry; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; +import com.android.server.LocalServices; import com.android.server.SystemService; import com.android.server.usage.AppStandbyInternal.AppIdleStateChangeListener; +import org.junit.After; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; @@ -425,11 +428,18 @@ public class AppStandbyControllerTests { @Before public void setUp() throws Exception { + LocalServices.addService( + UsageStatsManagerInternal.class, mock(UsageStatsManagerInternal.class)); MyContextWrapper myContext = new MyContextWrapper(InstrumentationRegistry.getContext()); mInjector = new MyInjector(myContext, Looper.getMainLooper()); mController = setupController(); } + @After + public void tearDown() { + LocalServices.removeServiceForTest(UsageStatsManagerInternal.class); + } + @Test public void testBoundWidgetPackageExempt() throws Exception { assumeTrue(mInjector.getContext().getSystemService(AppWidgetManager.class) != null); @@ -562,7 +572,7 @@ public class AppStandbyControllerTests { UsageEvents.Event ev = new UsageEvents.Event(); ev.mPackage = packageName; ev.mEventType = eventType; - controller.reportEvent(ev, USER_ID); + controller.onUsageEvent(USER_ID, ev); } private int getStandbyBucket(AppStandbyController controller, String packageName) { diff --git a/services/tests/servicestests/src/com/android/server/vibrator/InputDeviceDelegateTest.java b/services/tests/servicestests/src/com/android/server/vibrator/InputDeviceDelegateTest.java new file mode 100644 index 000000000000..fa8e36741bcc --- /dev/null +++ b/services/tests/servicestests/src/com/android/server/vibrator/InputDeviceDelegateTest.java @@ -0,0 +1,291 @@ +/* + * 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.server.vibrator; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.same; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.content.Context; +import android.content.ContextWrapper; +import android.hardware.input.IInputDevicesChangedListener; +import android.hardware.input.IInputManager; +import android.hardware.input.InputManager; +import android.os.Handler; +import android.os.Process; +import android.os.VibrationAttributes; +import android.os.VibrationEffect; +import android.os.test.TestLooper; +import android.platform.test.annotations.Presubmit; +import android.view.InputDevice; + +import androidx.test.InstrumentationRegistry; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; + +/** + * Tests for {@link InputDeviceDelegate}. + * + * Build/Install/Run: + * atest FrameworksServicesTests:InputDeviceDelegateTest + */ +@Presubmit +public class InputDeviceDelegateTest { + + private static final int UID = Process.ROOT_UID; + private static final String PACKAGE_NAME = "package"; + private static final String REASON = "some reason"; + private static final VibrationAttributes VIBRATION_ATTRIBUTES = + new VibrationAttributes.Builder().setUsage(VibrationAttributes.USAGE_ALARM).build(); + + @Rule public MockitoRule rule = MockitoJUnit.rule(); + + @Mock private IInputManager mIInputManagerMock; + + private TestLooper mTestLooper; + private ContextWrapper mContextSpy; + private InputDeviceDelegate mInputDeviceDelegate; + private IInputDevicesChangedListener mIInputDevicesChangedListener; + + @Before + public void setUp() throws Exception { + mTestLooper = new TestLooper(); + mContextSpy = spy(new ContextWrapper(InstrumentationRegistry.getContext())); + InputManager inputManager = InputManager.resetInstance(mIInputManagerMock); + + when(mContextSpy.getSystemService(eq(Context.INPUT_SERVICE))).thenReturn(inputManager); + doAnswer(invocation -> mIInputDevicesChangedListener = invocation.getArgument(0)) + .when(mIInputManagerMock).registerInputDevicesChangedListener(any()); + + mInputDeviceDelegate = new InputDeviceDelegate( + mContextSpy, new Handler(mTestLooper.getLooper())); + } + + @Test + public void onInputDeviceAdded_withSettingsDisabled_ignoresNewDevice() throws Exception { + when(mIInputManagerMock.getInputDeviceIds()).thenReturn(new int[0]); + mInputDeviceDelegate.updateInputDeviceVibrators(/* vibrateInputDevices= */ false); + assertFalse(mInputDeviceDelegate.isAvailable()); + + when(mIInputManagerMock.getInputDevice(eq(1))).thenReturn(createInputDeviceWithVibrator(1)); + mInputDeviceDelegate.onInputDeviceAdded(1); + + assertFalse(mInputDeviceDelegate.isAvailable()); + verify(mIInputManagerMock, never()).getInputDevice(anyInt()); + } + + @Test + public void onInputDeviceAdded_withDeviceWithoutVibrator_ignoresNewDevice() throws Exception { + when(mIInputManagerMock.getInputDeviceIds()).thenReturn(new int[0]); + mInputDeviceDelegate.updateInputDeviceVibrators(/* vibrateInputDevices= */ true); + assertFalse(mInputDeviceDelegate.isAvailable()); + + when(mIInputManagerMock.getInputDevice(eq(1))) + .thenReturn(createInputDeviceWithoutVibrator(1)); + updateInputDevices(new int[]{1}); + + assertFalse(mInputDeviceDelegate.isAvailable()); + verify(mIInputManagerMock).getInputDevice(eq(1)); + } + + @Test + public void onInputDeviceAdded_withDeviceWithVibrator_addsNewDevice() throws Exception { + when(mIInputManagerMock.getInputDeviceIds()).thenReturn(new int[0]); + mInputDeviceDelegate.updateInputDeviceVibrators(/* vibrateInputDevices= */ true); + assertFalse(mInputDeviceDelegate.isAvailable()); + + when(mIInputManagerMock.getInputDevice(eq(1))).thenReturn(createInputDeviceWithVibrator(1)); + updateInputDevices(new int[]{1}); + + assertTrue(mInputDeviceDelegate.isAvailable()); + verify(mIInputManagerMock).getInputDevice(eq(1)); + } + + @Test + public void onInputDeviceChanged_withSettingsDisabled_ignoresDevice() throws Exception { + when(mIInputManagerMock.getInputDeviceIds()).thenReturn(new int[]{1}); + when(mIInputManagerMock.getInputDevice(eq(1))).thenReturn(createInputDeviceWithVibrator(1)); + mInputDeviceDelegate.updateInputDeviceVibrators(/* vibrateInputDevices= */ false); + + updateInputDevices(new int[]{1}); + assertFalse(mInputDeviceDelegate.isAvailable()); + verify(mIInputManagerMock, never()).getInputDevice(anyInt()); + } + + @Test + public void onInputDeviceChanged_deviceLosesVibrator_removesDevice() throws Exception { + when(mIInputManagerMock.getInputDeviceIds()).thenReturn(new int[]{1}); + when(mIInputManagerMock.getInputDevice(eq(1))) + .thenReturn(createInputDeviceWithVibrator(1), createInputDeviceWithoutVibrator(1)); + + mInputDeviceDelegate.updateInputDeviceVibrators(/* vibrateInputDevices= */ true); + assertTrue(mInputDeviceDelegate.isAvailable()); + + updateInputDevices(new int[]{1}); + assertFalse(mInputDeviceDelegate.isAvailable()); + verify(mIInputManagerMock, times(2)).getInputDevice(eq(1)); + } + + @Test + public void onInputDeviceChanged_deviceLost_removesDevice() throws Exception { + when(mIInputManagerMock.getInputDeviceIds()).thenReturn(new int[]{1}); + when(mIInputManagerMock.getInputDevice(eq(1))) + .thenReturn(createInputDeviceWithVibrator(1), (InputDevice) null); + + mInputDeviceDelegate.updateInputDeviceVibrators(/* vibrateInputDevices= */ true); + assertTrue(mInputDeviceDelegate.isAvailable()); + + updateInputDevices(new int[]{1}); + assertFalse(mInputDeviceDelegate.isAvailable()); + verify(mIInputManagerMock, times(2)).getInputDevice(eq(1)); + } + + @Test + public void onInputDeviceChanged_deviceAddsVibrator_addsDevice() throws Exception { + when(mIInputManagerMock.getInputDeviceIds()).thenReturn(new int[]{1}); + when(mIInputManagerMock.getInputDevice(eq(1))) + .thenReturn(createInputDeviceWithoutVibrator(1), createInputDeviceWithVibrator(1)); + + mInputDeviceDelegate.updateInputDeviceVibrators(/* vibrateInputDevices= */ true); + assertFalse(mInputDeviceDelegate.isAvailable()); + + updateInputDevices(new int[]{1}); + assertTrue(mInputDeviceDelegate.isAvailable()); + verify(mIInputManagerMock, times(2)).getInputDevice(eq(1)); + } + + @Test + public void onInputDeviceRemoved_removesDevice() throws Exception { + when(mIInputManagerMock.getInputDeviceIds()).thenReturn(new int[]{1, 2}); + when(mIInputManagerMock.getInputDevice(eq(1))).thenReturn( + createInputDeviceWithoutVibrator(1)); + when(mIInputManagerMock.getInputDevice(eq(2))).thenReturn(createInputDeviceWithVibrator(2)); + + mInputDeviceDelegate.updateInputDeviceVibrators(/* vibrateInputDevices= */ true); + assertTrue(mInputDeviceDelegate.isAvailable()); + + updateInputDevices(new int[]{1}); + assertFalse(mInputDeviceDelegate.isAvailable()); + } + + @Test + public void updateInputDeviceVibrators_usesFlagToLoadDeviceList() throws Exception { + when(mIInputManagerMock.getInputDeviceIds()).thenReturn(new int[]{1, 2}); + when(mIInputManagerMock.getInputDevice(eq(1))).thenReturn(createInputDeviceWithVibrator(1)); + when(mIInputManagerMock.getInputDevice(eq(2))).thenReturn(createInputDeviceWithVibrator(2)); + + mInputDeviceDelegate.updateInputDeviceVibrators(/* vibrateInputDevices= */ true); + assertTrue(mInputDeviceDelegate.isAvailable()); + + mInputDeviceDelegate.updateInputDeviceVibrators(/* vibrateInputDevices= */ false); + assertFalse(mInputDeviceDelegate.isAvailable()); + } + + @Test + public void updateInputDeviceVibrators_withDeviceWithoutVibrator_deviceIsIgnored() + throws Exception { + when(mIInputManagerMock.getInputDeviceIds()).thenReturn(new int[]{1}); + when(mIInputManagerMock.getInputDevice(eq(1))) + .thenReturn(createInputDeviceWithoutVibrator(1)); + mInputDeviceDelegate.updateInputDeviceVibrators(/* vibrateInputDevices= */ true); + assertFalse(mInputDeviceDelegate.isAvailable()); + } + + @Test + public void vibrateIfAvailable_withNoInputDevice_returnsFalse() { + VibrationEffect effect = VibrationEffect.createOneShot(100, 255); + assertFalse(mInputDeviceDelegate.isAvailable()); + assertFalse(mInputDeviceDelegate.vibrateIfAvailable( + UID, PACKAGE_NAME, effect, REASON, VIBRATION_ATTRIBUTES)); + } + + @Test + public void vibrateIfAvailable_withInputDevices_returnsTrueAndVibratesAllDevices() + throws Exception { + when(mIInputManagerMock.getInputDeviceIds()).thenReturn(new int[]{1, 2}); + when(mIInputManagerMock.getInputDevice(eq(1))).thenReturn(createInputDeviceWithVibrator(1)); + when(mIInputManagerMock.getInputDevice(eq(2))).thenReturn(createInputDeviceWithVibrator(2)); + mInputDeviceDelegate.updateInputDeviceVibrators(/* vibrateInputDevices= */ true); + + VibrationEffect effect = VibrationEffect.createOneShot(100, 255); + assertTrue(mInputDeviceDelegate.vibrateIfAvailable( + UID, PACKAGE_NAME, effect, REASON, VIBRATION_ATTRIBUTES)); + verify(mIInputManagerMock).vibrate(eq(1), same(effect), any()); + verify(mIInputManagerMock).vibrate(eq(2), same(effect), any()); + } + + @Test + public void cancelVibrateIfAvailable_withNoInputDevice_returnsFalse() throws Exception { + assertFalse(mInputDeviceDelegate.isAvailable()); + assertFalse(mInputDeviceDelegate.cancelVibrateIfAvailable()); + verify(mIInputManagerMock, never()).cancelVibrate(anyInt(), any()); + } + + @Test + public void cancelVibrateIfAvailable_withInputDevices_returnsTrueAndStopsAllDevices() + throws Exception { + when(mIInputManagerMock.getInputDeviceIds()).thenReturn(new int[]{1, 2}); + when(mIInputManagerMock.getInputDevice(eq(1))).thenReturn(createInputDeviceWithVibrator(1)); + when(mIInputManagerMock.getInputDevice(eq(2))).thenReturn(createInputDeviceWithVibrator(2)); + mInputDeviceDelegate.updateInputDeviceVibrators(/* vibrateInputDevices= */ true); + + assertTrue(mInputDeviceDelegate.isAvailable()); + assertTrue(mInputDeviceDelegate.cancelVibrateIfAvailable()); + verify(mIInputManagerMock).cancelVibrate(eq(1), any()); + verify(mIInputManagerMock).cancelVibrate(eq(2), any()); + } + + private void updateInputDevices(int[] deviceIds) throws Exception { + int[] deviceIdsAndGenerations = new int[deviceIds.length * 2]; + for (int i = 0; i < deviceIdsAndGenerations.length; i += 2) { + deviceIdsAndGenerations[i] = deviceIds[i / 2]; + deviceIdsAndGenerations[i + 1] = 2; // update by increasing it's generation to 2. + } + // Force initialization of mIInputDevicesChangedListener, if it still haven't + InputManager.getInstance().getInputDeviceIds(); + mIInputDevicesChangedListener.onInputDevicesChanged(deviceIdsAndGenerations); + // Makes sure all callbacks from InputDeviceDelegate are executed. + mTestLooper.dispatchAll(); + } + + private InputDevice createInputDeviceWithVibrator(int id) { + return createInputDevice(id, /* hasVibrator= */ true); + } + + private InputDevice createInputDeviceWithoutVibrator(int id) { + return createInputDevice(id, /* hasVibrator= */ false); + } + + private InputDevice createInputDevice(int id, boolean hasVibrator) { + return new InputDevice(id, 0, 0, "name", 0, 0, "description", false, 0, 0, + null, hasVibrator, false, false); + } +} diff --git a/services/tests/servicestests/src/com/android/server/vibrator/VibrationSettingsTest.java b/services/tests/servicestests/src/com/android/server/vibrator/VibrationSettingsTest.java index 2cc999283184..04c2cb3b1148 100644 --- a/services/tests/servicestests/src/com/android/server/vibrator/VibrationSettingsTest.java +++ b/services/tests/servicestests/src/com/android/server/vibrator/VibrationSettingsTest.java @@ -18,6 +18,7 @@ package com.android.server.vibrator; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.spy; @@ -33,6 +34,7 @@ import android.media.AudioManager; import android.os.Handler; import android.os.UserHandle; import android.os.VibrationAttributes; +import android.os.VibrationEffect; import android.os.Vibrator; import android.os.test.TestLooper; import android.platform.test.annotations.Presubmit; @@ -271,6 +273,15 @@ public class VibrationSettingsTest { mVibrationSettings.getCurrentIntensity(VibrationAttributes.USAGE_RINGTONE)); } + @Test + public void getFallbackEffect_returnsEffectsFromSettings() { + assertNotNull(mVibrationSettings.getFallbackEffect(VibrationEffect.EFFECT_TICK)); + assertNotNull(mVibrationSettings.getFallbackEffect(VibrationEffect.EFFECT_TEXTURE_TICK)); + assertNotNull(mVibrationSettings.getFallbackEffect(VibrationEffect.EFFECT_CLICK)); + assertNotNull(mVibrationSettings.getFallbackEffect(VibrationEffect.EFFECT_HEAVY_CLICK)); + assertNotNull(mVibrationSettings.getFallbackEffect(VibrationEffect.EFFECT_DOUBLE_CLICK)); + } + private void setUserSetting(String settingName, int value) { Settings.System.putIntForUser( mContextSpy.getContentResolver(), settingName, value, UserHandle.USER_CURRENT); diff --git a/services/tests/servicestests/src/com/android/server/vibrator/VibratorControllerTest.java b/services/tests/servicestests/src/com/android/server/vibrator/VibratorControllerTest.java new file mode 100644 index 000000000000..1f163bd3282b --- /dev/null +++ b/services/tests/servicestests/src/com/android/server/vibrator/VibratorControllerTest.java @@ -0,0 +1,342 @@ +/* + * 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.server.vibrator; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.notNull; +import static org.mockito.Mockito.inOrder; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.when; + +import android.content.ContentResolver; +import android.content.ContextWrapper; +import android.hardware.vibrator.IVibrator; +import android.os.IBinder; +import android.os.IVibratorStateListener; +import android.os.VibrationEffect; +import android.os.Vibrator; +import android.os.test.TestLooper; +import android.platform.test.annotations.Presubmit; + +import androidx.test.InstrumentationRegistry; + +import com.android.internal.util.test.FakeSettingsProvider; +import com.android.internal.util.test.FakeSettingsProviderRule; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.InOrder; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; + +/** + * Tests for {@link VibratorController}. + * + * Build/Install/Run: + * atest FrameworksServicesTests:VibratorControllerTest + */ +@Presubmit +public class VibratorControllerTest { + + @Rule public MockitoRule rule = MockitoJUnit.rule(); + @Rule public FakeSettingsProviderRule mSettingsProviderRule = FakeSettingsProvider.rule(); + + @Mock private VibratorController.OnVibrationCompleteListener mOnCompleteListenerMock; + @Mock private VibratorController.NativeWrapper mNativeWrapperMock; + @Mock private IVibratorStateListener mVibratorStateListenerMock; + @Mock private IBinder mVibratorStateListenerBinderMock; + + private TestLooper mTestLooper; + private ContextWrapper mContextSpy; + + @Before + public void setUp() throws Exception { + mTestLooper = new TestLooper(); + mContextSpy = spy(new ContextWrapper(InstrumentationRegistry.getContext())); + + ContentResolver contentResolver = mSettingsProviderRule.mockContentResolver(mContextSpy); + when(mContextSpy.getContentResolver()).thenReturn(contentResolver); + when(mVibratorStateListenerMock.asBinder()).thenReturn(mVibratorStateListenerBinderMock); + } + + private VibratorController createController() { + return new VibratorController(/* vibratorId= */ 0, mOnCompleteListenerMock, + mNativeWrapperMock); + } + + private VibratorController createController(int vibratorId) { + return new VibratorController(vibratorId, mOnCompleteListenerMock, mNativeWrapperMock); + } + + @Test + public void createController_initializesNativeWrapper() { + int vibratorId = 13; + VibratorController controller = createController(vibratorId); + assertEquals(vibratorId, controller.getVibratorId()); + verify(mNativeWrapperMock).init(eq(vibratorId), notNull()); + } + + @Test + public void isAvailable_withVibratorHalPresent_returnsTrue() { + when(mNativeWrapperMock.isAvailable()).thenReturn(true); + assertTrue(createController().isAvailable()); + } + + @Test + public void isAvailable_withNoVibratorHalPresent_returnsFalse() { + when(mNativeWrapperMock.isAvailable()).thenReturn(false); + assertFalse(createController().isAvailable()); + } + + @Test + public void hasCapability_withSupport_returnsTrue() { + mockVibratorCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL); + assertTrue(createController().hasCapability(IVibrator.CAP_AMPLITUDE_CONTROL)); + } + + @Test + public void hasCapability_withNoSupport_returnsFalse() { + assertFalse(createController().hasCapability(IVibrator.CAP_ALWAYS_ON_CONTROL)); + assertFalse(createController().hasCapability(IVibrator.CAP_AMPLITUDE_CONTROL)); + assertFalse(createController().hasCapability(IVibrator.CAP_COMPOSE_EFFECTS)); + assertFalse(createController().hasCapability(IVibrator.CAP_EXTERNAL_CONTROL)); + assertFalse(createController().hasCapability(IVibrator.CAP_ON_CALLBACK)); + } + + @Test + public void areEffectsSupported_withNullResultFromNative_returnsSupportUnknown() { + when(mNativeWrapperMock.getSupportedEffects()).thenReturn(null); + assertArrayEquals(new int[]{Vibrator.VIBRATION_EFFECT_SUPPORT_UNKNOWN}, + createController().areEffectsSupported(new int[]{VibrationEffect.EFFECT_CLICK})); + } + + @Test + public void areEffectsSupported_withSomeEffectsSupported_returnsSupportYesAndNoForEffects() { + int[] effects = new int[]{VibrationEffect.EFFECT_CLICK, VibrationEffect.EFFECT_TICK}; + + when(mNativeWrapperMock.getSupportedEffects()) + .thenReturn(new int[]{VibrationEffect.EFFECT_CLICK}); + assertArrayEquals( + new int[]{Vibrator.VIBRATION_EFFECT_SUPPORT_YES, + Vibrator.VIBRATION_EFFECT_SUPPORT_NO}, + createController().areEffectsSupported(effects)); + } + + @Test + public void arePrimitivesSupported_withoutComposeCapability_returnsAlwaysFalse() { + assertArrayEquals(new boolean[]{false, false}, + createController().arePrimitivesSupported(new int[]{ + VibrationEffect.Composition.PRIMITIVE_CLICK, + VibrationEffect.Composition.PRIMITIVE_TICK + })); + } + + @Test + public void arePrimitivesSupported_withNullResultFromNative_returnsAlwaysFalse() { + mockVibratorCapabilities(IVibrator.CAP_COMPOSE_EFFECTS); + when(mNativeWrapperMock.getSupportedPrimitives()).thenReturn(null); + + assertArrayEquals(new boolean[]{false, false}, + createController().arePrimitivesSupported(new int[]{ + VibrationEffect.Composition.PRIMITIVE_CLICK, + VibrationEffect.Composition.PRIMITIVE_QUICK_RISE + })); + } + + @Test + public void arePrimitivesSupported_withSomeSupportedPrimitives_returnsBasedOnNativeResult() { + mockVibratorCapabilities(IVibrator.CAP_COMPOSE_EFFECTS); + when(mNativeWrapperMock.getSupportedPrimitives()) + .thenReturn(new int[]{VibrationEffect.Composition.PRIMITIVE_CLICK}); + + assertArrayEquals(new boolean[]{true, false}, + createController().arePrimitivesSupported(new int[]{ + VibrationEffect.Composition.PRIMITIVE_CLICK, + VibrationEffect.Composition.PRIMITIVE_QUICK_RISE + })); + } + + @Test + public void setExternalControl_withCapability_enablesExternalControl() { + mockVibratorCapabilities(IVibrator.CAP_EXTERNAL_CONTROL); + VibratorController controller = createController(); + assertFalse(controller.isUnderExternalControl()); + + controller.setExternalControl(true); + assertTrue(controller.isUnderExternalControl()); + + controller.setExternalControl(false); + assertFalse(controller.isUnderExternalControl()); + + InOrder inOrderVerifier = inOrder(mNativeWrapperMock); + inOrderVerifier.verify(mNativeWrapperMock).setExternalControl(eq(true)); + inOrderVerifier.verify(mNativeWrapperMock).setExternalControl(eq(false)); + } + + @Test + public void setExternalControl_withNoCapability_ignoresExternalControl() { + VibratorController controller = createController(); + assertFalse(controller.isUnderExternalControl()); + + controller.setExternalControl(true); + assertFalse(controller.isUnderExternalControl()); + + verify(mNativeWrapperMock, never()).setExternalControl(anyBoolean()); + } + + @Test + public void updateAlwaysOn_withCapability_enablesAlwaysOnEffect() { + mockVibratorCapabilities(IVibrator.CAP_ALWAYS_ON_CONTROL); + VibrationEffect.Prebaked effect = (VibrationEffect.Prebaked) + VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK); + createController().updateAlwaysOn(1, effect); + + verify(mNativeWrapperMock).alwaysOnEnable( + eq(1L), eq((long) VibrationEffect.EFFECT_CLICK), + eq((long) VibrationEffect.EFFECT_STRENGTH_MEDIUM)); + } + + @Test + public void updateAlwaysOn_withNullEffect_disablesAlwaysOnEffect() { + mockVibratorCapabilities(IVibrator.CAP_ALWAYS_ON_CONTROL); + createController().updateAlwaysOn(1, null); + verify(mNativeWrapperMock).alwaysOnDisable(eq(1L)); + } + + @Test + public void updateAlwaysOn_withoutCapability_ignoresEffect() { + VibrationEffect.Prebaked effect = (VibrationEffect.Prebaked) + VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK); + createController().updateAlwaysOn(1, effect); + + verify(mNativeWrapperMock, never()).alwaysOnDisable(anyLong()); + verify(mNativeWrapperMock, never()).alwaysOnEnable(anyLong(), anyLong(), anyLong()); + } + + @Test + public void on_withDuration_turnsVibratorOn() { + VibratorController controller = createController(); + controller.on(100, 10); + + assertTrue(controller.isVibrating()); + verify(mNativeWrapperMock).on(eq(100L), eq(10L)); + } + + @Test + public void on_withPrebaked_performsEffect() { + when(mNativeWrapperMock.perform(anyLong(), anyLong(), anyLong())).thenReturn(10L); + VibratorController controller = createController(); + + VibrationEffect.Prebaked effect = (VibrationEffect.Prebaked) + VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK); + controller.on(effect, 11); + + assertTrue(controller.isVibrating()); + verify(mNativeWrapperMock).perform(eq((long) VibrationEffect.EFFECT_CLICK), + eq((long) VibrationEffect.EFFECT_STRENGTH_MEDIUM), eq(11L)); + } + + @Test + public void on_withComposed_performsEffect() { + mockVibratorCapabilities(IVibrator.CAP_COMPOSE_EFFECTS); + VibratorController controller = createController(); + + VibrationEffect.Composed effect = (VibrationEffect.Composed) + VibrationEffect.startComposition() + .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 0.5f, 10) + .compose(); + controller.on(effect, 12); + + ArgumentCaptor<VibrationEffect.Composition.PrimitiveEffect[]> primitivesCaptor = + ArgumentCaptor.forClass(VibrationEffect.Composition.PrimitiveEffect[].class); + + assertTrue(controller.isVibrating()); + verify(mNativeWrapperMock).compose(primitivesCaptor.capture(), eq(12L)); + + // Check all primitive effect fields are passed down to the HAL. + assertEquals(1, primitivesCaptor.getValue().length); + VibrationEffect.Composition.PrimitiveEffect primitive = primitivesCaptor.getValue()[0]; + assertEquals(VibrationEffect.Composition.PRIMITIVE_CLICK, primitive.id); + assertEquals(0.5f, primitive.scale, /* delta= */ 1e-2); + assertEquals(10, primitive.delay); + } + + @Test + public void off_turnsOffVibrator() { + VibratorController controller = createController(); + controller.on(100, 1); + assertTrue(controller.isVibrating()); + + controller.off(); + controller.off(); + assertFalse(controller.isVibrating()); + verify(mNativeWrapperMock, times(2)).off(); + } + + @Test + public void registerVibratorStateListener_callbacksAreTriggered() throws Exception { + VibratorController controller = createController(); + + controller.registerVibratorStateListener(mVibratorStateListenerMock); + controller.on(10, 1); + controller.on(100, 2); + controller.off(); + controller.off(); + + InOrder inOrderVerifier = inOrder(mVibratorStateListenerMock); + // First notification done when listener is registered. + inOrderVerifier.verify(mVibratorStateListenerMock).onVibrating(false); + inOrderVerifier.verify(mVibratorStateListenerMock).onVibrating(eq(true)); + inOrderVerifier.verify(mVibratorStateListenerMock).onVibrating(eq(false)); + inOrderVerifier.verifyNoMoreInteractions(); + } + + @Test + public void unregisterVibratorStateListener_callbackNotTriggeredAfter() throws Exception { + VibratorController controller = createController(); + + controller.registerVibratorStateListener(mVibratorStateListenerMock); + verify(mVibratorStateListenerMock).onVibrating(false); + + controller.on(10, 1); + verify(mVibratorStateListenerMock).onVibrating(true); + + controller.unregisterVibratorStateListener(mVibratorStateListenerMock); + Mockito.clearInvocations(mVibratorStateListenerMock); + + controller.on(10, 1); + verifyNoMoreInteractions(mVibratorStateListenerMock); + } + + private void mockVibratorCapabilities(int capabilities) { + when(mNativeWrapperMock.getCapabilities()).thenReturn((long) capabilities); + } +} diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java index bded3f9de9ba..565bf8b615c7 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java @@ -422,7 +422,7 @@ public class ActivityStarterTests extends WindowTestsBase { // verify that values are passed to the modifier. Values are passed thrice -- two for // setting initial state, another when task is created. verify(modifier, times(3)).onCalculate(any(), eq(windowLayout), any(), any(), eq(options), - anyInt(), any(), any()); + anyInt(), any(), any(), any()); } /** diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskSupervisorTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskSupervisorTests.java index 017ed883e2bd..475e462bdd3d 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskSupervisorTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskSupervisorTests.java @@ -34,6 +34,7 @@ import static org.junit.Assert.assertNull; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.timeout; import android.app.WaitResult; import android.content.pm.ActivityInfo; @@ -45,6 +46,8 @@ import androidx.test.filters.MediumTest; import org.junit.Test; import org.junit.runner.RunWith; +import java.util.concurrent.TimeUnit; + /** * Tests for the {@link ActivityTaskSupervisor} class. * @@ -190,4 +193,16 @@ public class ActivityTaskSupervisorTests extends WindowTestsBase { assertThat(allowedOnUntrusted).isFalse(); } + + /** + * We need to launch home again after user unlocked for those displays that do not have + * encryption aware home app. + */ + @Test + public void testStartHomeAfterUserUnlocked() { + mSupervisor.onUserUnlocked(0); + waitHandlerIdle(mAtm.mH); + verify(mRootWindowContainer, timeout(TimeUnit.SECONDS.toMillis(10))) + .startHomeOnEmptyDisplays("userUnlocked"); + } } diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayAreaOrganizerTest.java b/services/tests/wmtests/src/com/android/server/wm/DisplayAreaOrganizerTest.java index 3220d1d6a990..1198ee2ba5f4 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayAreaOrganizerTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayAreaOrganizerTest.java @@ -16,8 +16,13 @@ package com.android.server.wm; +import static android.view.Display.DEFAULT_DISPLAY; +import static android.window.DisplayAreaOrganizer.FEATURE_ROOT; +import static android.window.DisplayAreaOrganizer.FEATURE_RUNTIME_TASK_CONTAINER_FIRST; import static android.window.DisplayAreaOrganizer.FEATURE_VENDOR_FIRST; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; + import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; @@ -25,6 +30,7 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import static org.testng.Assert.assertThrows; import android.content.res.Configuration; import android.graphics.Rect; @@ -55,9 +61,12 @@ import java.util.List; public class DisplayAreaOrganizerTest extends WindowTestsBase { private DisplayArea mTestDisplayArea; + private DisplayAreaOrganizerController mOrganizerController; @Before public void setUp() { + mOrganizerController = + mWm.mAtmService.mWindowOrganizerController.mDisplayAreaOrganizerController; WindowContainer parentWindow = mDisplayContent.getDefaultTaskDisplayArea().getParent(); mTestDisplayArea = new DisplayArea(mWm, DisplayArea.Type.ANY, "TestDisplayArea", FEATURE_VENDOR_FIRST); @@ -76,8 +85,7 @@ public class DisplayAreaOrganizerTest extends WindowTestsBase { private IDisplayAreaOrganizer registerMockOrganizer(int feature, Binder binder) { final IDisplayAreaOrganizer organizer = createMockOrganizer(binder); - mWm.mAtmService.mWindowOrganizerController.mDisplayAreaOrganizerController - .registerOrganizer(organizer, feature); + mOrganizerController.registerOrganizer(organizer, feature); return organizer; } @@ -87,16 +95,10 @@ public class DisplayAreaOrganizerTest extends WindowTestsBase { return organizer; } - private void unregisterMockOrganizer(IDisplayAreaOrganizer organizer) { - mWm.mAtmService.mWindowOrganizerController.mDisplayAreaOrganizerController - .unregisterOrganizer(organizer); - } - @Test public void testRegisterOrganizer() throws RemoteException { - IDisplayAreaOrganizer organizer = createMockOrganizer(new Binder()); - List<DisplayAreaAppearedInfo> infos = mWm.mAtmService.mWindowOrganizerController - .mDisplayAreaOrganizerController + final IDisplayAreaOrganizer organizer = createMockOrganizer(new Binder()); + List<DisplayAreaAppearedInfo> infos = mOrganizerController .registerOrganizer(organizer, FEATURE_VENDOR_FIRST).getList(); // Return a list contains the DA, and no onDisplayAreaAppeared triggered. @@ -108,16 +110,135 @@ public class DisplayAreaOrganizerTest extends WindowTestsBase { } @Test + public void testRegisterOrganizer_alreadyRegisteredFeature() { + registerMockOrganizer(FEATURE_VENDOR_FIRST); + assertThrows(IllegalStateException.class, + () -> registerMockOrganizer(FEATURE_VENDOR_FIRST)); + } + + @Test + public void testCreateTaskDisplayArea() { + final String newTdaName = "testTda"; + final IDisplayAreaOrganizer organizer = createMockOrganizer(new Binder()); + final DisplayAreaAppearedInfo tdaInfo = mOrganizerController.createTaskDisplayArea( + organizer, DEFAULT_DISPLAY, FEATURE_ROOT, newTdaName); + + final int newTdaIndex = + mTestDisplayArea.getParent().mChildren.indexOf(mTestDisplayArea) + 1; + final WindowContainer wc = mTestDisplayArea.getParent().getChildAt(newTdaIndex); + + // A new TaskDisplayArea is created on the top. + assertThat(wc).isInstanceOf(TaskDisplayArea.class); + assertThat(tdaInfo.getDisplayAreaInfo().displayId).isEqualTo(DEFAULT_DISPLAY); + assertThat(tdaInfo.getDisplayAreaInfo().token) + .isEqualTo(wc.mRemoteToken.toWindowContainerToken()); + + final TaskDisplayArea tda = wc.asTaskDisplayArea(); + + assertThat(tda.getName()).isEqualTo(newTdaName); + assertThat(tda.mFeatureId).isEqualTo(tdaInfo.getDisplayAreaInfo().featureId); + assertThat(tda.mCreatedByOrganizer).isTrue(); + assertThat(tda.mOrganizer).isEqualTo(organizer); + } + + @Test + public void testCreateTaskDisplayArea_incrementalTdaFeatureId() { + final String newTdaName = "testTda"; + final IDisplayAreaOrganizer organizer = createMockOrganizer(new Binder()); + final DisplayAreaAppearedInfo tdaInfo1 = mOrganizerController.createTaskDisplayArea( + organizer, DEFAULT_DISPLAY, FEATURE_ROOT, newTdaName); + final DisplayAreaAppearedInfo tdaInfo2 = mOrganizerController.createTaskDisplayArea( + organizer, DEFAULT_DISPLAY, FEATURE_ROOT, newTdaName); + + // New created TDA has unique feature id starting from FEATURE_RUNTIME_TASK_CONTAINER_FIRST. + assertThat(tdaInfo1.getDisplayAreaInfo().featureId).isEqualTo( + FEATURE_RUNTIME_TASK_CONTAINER_FIRST); + assertThat(tdaInfo2.getDisplayAreaInfo().featureId).isEqualTo( + FEATURE_RUNTIME_TASK_CONTAINER_FIRST + 1); + } + + + @Test + public void testCreateTaskDisplayArea_invalidDisplayAndRoot() { + final IDisplayAreaOrganizer organizer = createMockOrganizer(new Binder()); + assertThrows(IllegalArgumentException.class, () -> + mOrganizerController.createTaskDisplayArea( + organizer, SystemServicesTestRule.sNextDisplayId + 1, FEATURE_ROOT, + "testTda")); + assertThrows(IllegalArgumentException.class, () -> + mOrganizerController.createTaskDisplayArea( + organizer, DEFAULT_DISPLAY, FEATURE_ROOT - 1, "testTda")); + } + + @Test + public void testDeleteTaskDisplayArea() { + final String newTdaName = "testTda"; + final IDisplayAreaOrganizer organizer = createMockOrganizer(new Binder()); + final DisplayAreaAppearedInfo tdaInfo = mOrganizerController.createTaskDisplayArea( + organizer, DEFAULT_DISPLAY, FEATURE_ROOT, newTdaName); + final int tdaFeatureId = tdaInfo.getDisplayAreaInfo().featureId; + + final TaskDisplayArea newTda = mDisplayContent.getItemFromDisplayAreas( + da -> da.mFeatureId == tdaFeatureId ? da.asTaskDisplayArea() : null); + spyOn(newTda); + + mOrganizerController.deleteTaskDisplayArea(newTda.mRemoteToken.toWindowContainerToken()); + + verify(newTda).remove(); + verify(newTda).removeImmediately(); + assertThat(newTda.mOrganizer).isNull(); + assertThat(newTda.isRemoved()).isTrue(); + + final TaskDisplayArea curTda = mDisplayContent.getItemFromDisplayAreas( + da -> da.mFeatureId == tdaFeatureId ? da.asTaskDisplayArea() : null); + + assertThat(curTda).isNull(); + } + + @Test + public void testUnregisterOrganizer_deleteNewCreatedTaskDisplayArea() { + final String newTdaName = "testTda"; + final IDisplayAreaOrganizer organizer = createMockOrganizer(new Binder()); + final DisplayAreaAppearedInfo tdaInfo = mOrganizerController.createTaskDisplayArea( + organizer, DEFAULT_DISPLAY, FEATURE_ROOT, newTdaName); + final int tdaFeatureId = tdaInfo.getDisplayAreaInfo().featureId; + + final TaskDisplayArea newTda = mDisplayContent.getItemFromDisplayAreas( + da -> da.mFeatureId == tdaFeatureId ? da.asTaskDisplayArea() : null); + spyOn(newTda); + + mOrganizerController.unregisterOrganizer(organizer); + + verify(newTda).remove(); + verify(newTda).removeImmediately(); + assertThat(newTda.mOrganizer).isNull(); + assertThat(newTda.isRemoved()).isTrue(); + + final TaskDisplayArea curTda = mDisplayContent.getItemFromDisplayAreas( + da -> da.mFeatureId == tdaFeatureId ? da.asTaskDisplayArea() : null); + + assertThat(curTda).isNull(); + } + + @Test + public void testDeleteTaskDisplayArea_invalidTaskDisplayArea() { + final TaskDisplayArea tda = mDisplayContent.getDefaultTaskDisplayArea(); + assertThrows(IllegalArgumentException.class, () -> + mOrganizerController.deleteTaskDisplayArea( + tda.mRemoteToken.toWindowContainerToken())); + } + + @Test public void testAppearedVanished() throws RemoteException { - IDisplayAreaOrganizer organizer = registerMockOrganizer(FEATURE_VENDOR_FIRST); - unregisterMockOrganizer(organizer); + final IDisplayAreaOrganizer organizer = registerMockOrganizer(FEATURE_VENDOR_FIRST); + mOrganizerController.unregisterOrganizer(organizer); verify(organizer).onDisplayAreaVanished(any()); } @Test public void testChanged() throws RemoteException { - IDisplayAreaOrganizer organizer = registerMockOrganizer(FEATURE_VENDOR_FIRST); + final IDisplayAreaOrganizer organizer = registerMockOrganizer(FEATURE_VENDOR_FIRST); mDisplayContent.setBounds(new Rect(0, 0, 1000, 1000)); verify(organizer).onDisplayAreaInfoChanged(any()); @@ -137,7 +258,7 @@ public class DisplayAreaOrganizerTest extends WindowTestsBase { assertThat(mTestDisplayArea.mOrganizer).isNotNull(); - unregisterMockOrganizer(createMockOrganizer(binder)); + mOrganizerController.unregisterOrganizer(createMockOrganizer(binder)); assertThat(mTestDisplayArea.mOrganizer).isNull(); } diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsProviderTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsProviderTests.java index b346bb810b2e..eaedd58001c1 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsProviderTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsProviderTests.java @@ -17,6 +17,7 @@ package com.android.server.wm; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; +import static android.view.WindowManager.DISPLAY_IME_POLICY_LOCAL; import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation; @@ -167,7 +168,7 @@ public class DisplayWindowSettingsProviderTests extends WindowTestsBase { mBaseSettingsStorage, mOverrideSettingsStorage); SettingsEntry overrideSettings = provider.getOverrideSettings(secondaryDisplayInfo); overrideSettings.mShouldShowSystemDecors = true; - overrideSettings.mShouldShowIme = true; + overrideSettings.mImePolicy = DISPLAY_IME_POLICY_LOCAL; provider.updateOverrideSettings(secondaryDisplayInfo, overrideSettings); assertTrue(mOverrideSettingsStorage.wasWriteSuccessful()); @@ -176,8 +177,8 @@ public class DisplayWindowSettingsProviderTests extends WindowTestsBase { getStoredDisplayAttributeValue(mOverrideSettingsStorage, "name")); assertEquals("Attribute value must be stored", "true", getStoredDisplayAttributeValue(mOverrideSettingsStorage, "shouldShowSystemDecors")); - assertEquals("Attribute value must be stored", "true", - getStoredDisplayAttributeValue(mOverrideSettingsStorage, "shouldShowIme")); + assertEquals("Attribute value must be stored", "0", + getStoredDisplayAttributeValue(mOverrideSettingsStorage, "imePolicy")); } @Test @@ -195,7 +196,7 @@ public class DisplayWindowSettingsProviderTests extends WindowTestsBase { mBaseSettingsStorage, mOverrideSettingsStorage); SettingsEntry overrideSettings = provider.getOverrideSettings(secondaryDisplayInfo); overrideSettings.mShouldShowSystemDecors = true; - overrideSettings.mShouldShowIme = true; + overrideSettings.mImePolicy = DISPLAY_IME_POLICY_LOCAL; provider.updateOverrideSettings(secondaryDisplayInfo, overrideSettings); assertTrue(mOverrideSettingsStorage.wasWriteSuccessful()); @@ -204,8 +205,8 @@ public class DisplayWindowSettingsProviderTests extends WindowTestsBase { getStoredDisplayAttributeValue(mOverrideSettingsStorage, "name")); assertEquals("Attribute value must be stored", "true", getStoredDisplayAttributeValue(mOverrideSettingsStorage, "shouldShowSystemDecors")); - assertEquals("Attribute value must be stored", "true", - getStoredDisplayAttributeValue(mOverrideSettingsStorage, "shouldShowIme")); + assertEquals("Attribute value must be stored", "0", + getStoredDisplayAttributeValue(mOverrideSettingsStorage, "imePolicy")); } /** diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsTests.java index 2ca5583c48c3..9e4cd161c478 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsTests.java @@ -22,6 +22,8 @@ import static android.view.IWindowManager.FIXED_TO_USER_ROTATION_DISABLED; import static android.view.IWindowManager.FIXED_TO_USER_ROTATION_ENABLED; import static android.view.WindowManager.REMOVE_CONTENT_MODE_DESTROY; import static android.view.WindowManager.REMOVE_CONTENT_MODE_MOVE_TO_PRIMARY; +import static android.view.WindowManager.DISPLAY_IME_POLICY_LOCAL; +import static android.view.WindowManager.DISPLAY_IME_POLICY_FALLBACK_DISPLAY; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; @@ -49,7 +51,6 @@ import androidx.test.filters.SmallTest; import com.android.server.LocalServices; import com.android.server.policy.WindowManagerPolicy; -import com.android.server.wm.DisplayWindowSettings.SettingsProvider.SettingsEntry; import org.junit.Before; import org.junit.Test; @@ -319,17 +320,21 @@ public class DisplayWindowSettingsTests extends WindowTestsBase { } @Test - public void testPrimaryDisplayShouldShowIme() { - assertTrue(mDisplayWindowSettings.shouldShowImeLocked(mPrimaryDisplay)); + public void testPrimaryDisplayImePolicy() { + assertEquals(DISPLAY_IME_POLICY_LOCAL, + mDisplayWindowSettings.getImePolicyLocked(mPrimaryDisplay)); - mDisplayWindowSettings.setShouldShowImeLocked(mPrimaryDisplay, false); + mDisplayWindowSettings.setDisplayImePolicy(mPrimaryDisplay, + DISPLAY_IME_POLICY_FALLBACK_DISPLAY); - assertTrue(mDisplayWindowSettings.shouldShowImeLocked(mPrimaryDisplay)); + assertEquals(DISPLAY_IME_POLICY_LOCAL, + mDisplayWindowSettings.getImePolicyLocked(mPrimaryDisplay)); } @Test - public void testSecondaryDisplayDefaultToNotShowIme() { - assertFalse(mDisplayWindowSettings.shouldShowImeLocked(mSecondaryDisplay)); + public void testSecondaryDisplayDefaultToShowImeOnFallbackDisplay() { + assertEquals(DISPLAY_IME_POLICY_FALLBACK_DISPLAY, + mDisplayWindowSettings.getImePolicyLocked(mSecondaryDisplay)); } @Test @@ -400,17 +405,18 @@ public class DisplayWindowSettingsTests extends WindowTestsBase { } @Test - public void testShouldShowImeWithinForceDesktopMode() { + public void testShouldShowImeOnDisplayWithinForceDesktopMode() { try { // Presume display enabled force desktop mode from developer options. final DisplayContent dc = createMockSimulatedDisplay(); mWm.setForceDesktopModeOnExternalDisplays(true); final WindowManagerInternal wmInternal = LocalServices.getService( WindowManagerInternal.class); - // Make sure WindowManagerInter#shouldShowIme as true is due to - // mForceDesktopModeOnExternalDisplays as true. - assertFalse(mWm.mDisplayWindowSettings.shouldShowImeLocked(dc)); - assertTrue(wmInternal.shouldShowIme(dc.getDisplayId())); + // Make sure WindowManagerInter#getDisplayImePolicy is SHOW_IME_ON_DISPLAY is due to + // mForceDesktopModeOnExternalDisplays being SHOW_IME_ON_DISPLAY. + assertEquals(DISPLAY_IME_POLICY_FALLBACK_DISPLAY, + mWm.mDisplayWindowSettings.getImePolicyLocked(dc)); + assertEquals(DISPLAY_IME_POLICY_LOCAL, wmInternal.getDisplayImePolicy(dc.getDisplayId())); } finally { mWm.setForceDesktopModeOnExternalDisplays(false); } diff --git a/services/tests/wmtests/src/com/android/server/wm/InputMethodMenuControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/InputMethodMenuControllerTest.java index a9f6b50d4be5..f75c98f39323 100644 --- a/services/tests/wmtests/src/com/android/server/wm/InputMethodMenuControllerTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/InputMethodMenuControllerTest.java @@ -18,14 +18,28 @@ package com.android.server.wm; import static android.view.Display.DEFAULT_DISPLAY; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; + import static com.google.common.truth.Truth.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import android.content.Context; +import android.content.res.Resources; import android.graphics.Rect; +import android.hardware.display.DisplayManagerGlobal; +import android.os.IBinder; import android.platform.test.annotations.Presubmit; +import android.view.Display; +import android.view.IWindowManager; import android.view.WindowManager; +import android.view.WindowManagerGlobal; import com.android.server.inputmethod.InputMethodManagerService; import com.android.server.inputmethod.InputMethodMenuController; @@ -45,10 +59,34 @@ import org.junit.runner.RunWith; public class InputMethodMenuControllerTest extends WindowTestsBase { private InputMethodMenuController mController; + private TestDisplayContent mSecondaryDisplay; @Before - public void setUp() { + public void setUp() throws Exception { mController = new InputMethodMenuController(mock(InputMethodManagerService.class)); + + // Mock addWindowTokenWithOptions to create a test window token. + IWindowManager wms = WindowManagerGlobal.getWindowManagerService(); + spyOn(wms); + doAnswer(invocation -> { + Object[] args = invocation.getArguments(); + final IBinder token = (IBinder) args[0]; + final int windowType = (int) args[1]; + new WindowToken(mWm, token, windowType, true /* persistOnEmpty */, + mDefaultDisplay, true /* ownerCanManageAppTokens */, 1000 /* ownerUid */, + false /* roundedCornerOverlay */, true /* fromClientToken */); + return WindowManagerGlobal.ADD_OKAY; + }).when(wms).addWindowTokenWithOptions(any(), anyInt(), anyInt(), any(), anyString()); + + mSecondaryDisplay = new TestDisplayContent.Builder(mAtm, 1000, 1000).build(); + + // Mock DisplayManagerGlobal to return test display when obtaining Display instance. + final int displayId = mSecondaryDisplay.getDisplayId(); + final Display display = mSecondaryDisplay.getDisplay(); + DisplayManagerGlobal displayManagerGlobal = DisplayManagerGlobal.getInstance(); + spyOn(displayManagerGlobal); + doReturn(display).when(displayManagerGlobal).getCompatibleDisplay(eq(displayId), + (Resources) any()); } @Test @@ -60,9 +98,9 @@ public class InputMethodMenuControllerTest extends WindowTestsBase { // Obtain the context again and check they are the same instance and match the display // metrics of the secondary display. final Context contextOnSecondaryDisplay = mController.getSettingsContext( - mDisplayContent.getDisplayId()); + mSecondaryDisplay.getDisplayId()); - assertImeSwitchContextMetricsValidity(contextOnSecondaryDisplay, mDisplayContent); + assertImeSwitchContextMetricsValidity(contextOnSecondaryDisplay, mSecondaryDisplay); assertThat(contextOnDefaultDisplay.getWindowContextToken()) .isEqualTo(contextOnSecondaryDisplay.getWindowContextToken()); } diff --git a/services/tests/wmtests/src/com/android/server/wm/LaunchParamsControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/LaunchParamsControllerTests.java index e514ac04efbe..cd428e10a437 100644 --- a/services/tests/wmtests/src/com/android/server/wm/LaunchParamsControllerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/LaunchParamsControllerTests.java @@ -33,6 +33,7 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.times; import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; +import static com.android.server.wm.ActivityStarter.Request; import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.PHASE_BOUNDS; import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.RESULT_CONTINUE; import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.RESULT_DONE; @@ -92,11 +93,12 @@ public class LaunchParamsControllerTests extends WindowTestsBase { final ActivityRecord source = new ActivityBuilder(mAtm).build(); final WindowLayout layout = new WindowLayout(0, 0, 0, 0, 0, 0, 0); final ActivityOptions options = mock(ActivityOptions.class); + final Request request = new Request(); mController.calculate(record.getTask(), layout, record, source, options, PHASE_BOUNDS, - new LaunchParams()); + new LaunchParams(), request); verify(positioner, times(1)).onCalculate(eq(record.getTask()), eq(layout), eq(record), - eq(source), eq(options), anyInt(), any(), any()); + eq(source), eq(options), anyInt(), any(), any(), eq(request)); } /** @@ -119,9 +121,9 @@ public class LaunchParamsControllerTests extends WindowTestsBase { mPersister.putLaunchParams(userId, name, expected); mController.calculate(activity.getTask(), null /*layout*/, activity, null /*source*/, - null /*options*/, PHASE_BOUNDS, new LaunchParams()); + null /*options*/, PHASE_BOUNDS, new LaunchParams(), null /* request */); verify(positioner, times(1)).onCalculate(any(), any(), any(), any(), any(), anyInt(), - eq(expected), any()); + eq(expected), any(), any()); } /** @@ -132,16 +134,17 @@ public class LaunchParamsControllerTests extends WindowTestsBase { final LaunchParamsModifier ignoredPositioner = mock(LaunchParamsModifier.class); final LaunchParamsModifier earlyExitPositioner = - (task, layout, activity, source, options, phase, currentParams, outParams) + (task, layout, activity, source, options, phase, currentParams, outParams, request) -> RESULT_DONE; mController.registerModifier(ignoredPositioner); mController.registerModifier(earlyExitPositioner); mController.calculate(null /*task*/, null /*layout*/, null /*activity*/, - null /*source*/, null /*options*/, PHASE_BOUNDS, new LaunchParams()); + null /*source*/, null /*options*/, PHASE_BOUNDS, new LaunchParams(), + null /* request */); verify(ignoredPositioner, never()).onCalculate(any(), any(), any(), any(), any(), anyInt(), - any(), any()); + any(), any(), any()); } /** @@ -157,20 +160,22 @@ public class LaunchParamsControllerTests extends WindowTestsBase { mController.registerModifier(firstPositioner); mController.calculate(null /*task*/, null /*layout*/, null /*activity*/, - null /*source*/, null /*options*/, PHASE_BOUNDS, new LaunchParams()); + null /*source*/, null /*options*/, PHASE_BOUNDS, new LaunchParams(), + null /* request */); verify(firstPositioner, times(1)).onCalculate(any(), any(), any(), any(), any(), anyInt(), - any(), any()); + any(), any(), any()); final LaunchParamsModifier secondPositioner = spy(earlyExitPositioner); mController.registerModifier(secondPositioner); mController.calculate(null /*task*/, null /*layout*/, null /*activity*/, - null /*source*/, null /*options*/, PHASE_BOUNDS, new LaunchParams()); + null /*source*/, null /*options*/, PHASE_BOUNDS, new LaunchParams(), + null /* request */); verify(firstPositioner, times(1)).onCalculate(any(), any(), any(), any(), any(), anyInt(), - any(), any()); + any(), any(), any()); verify(secondPositioner, times(1)).onCalculate(any(), any(), any(), any(), any(), anyInt(), - any(), any()); + any(), any(), any()); } /** @@ -192,10 +197,10 @@ public class LaunchParamsControllerTests extends WindowTestsBase { mController.registerModifier(positioner2); mController.calculate(null /*task*/, null /*layout*/, null /*activity*/, null /*source*/, - null /*options*/, PHASE_BOUNDS, new LaunchParams()); + null /*options*/, PHASE_BOUNDS, new LaunchParams(), null /* request */); verify(positioner1, times(1)).onCalculate(any(), any(), any(), any(), any(), anyInt(), - eq(positioner2.getLaunchParams()), any()); + eq(positioner2.getLaunchParams()), any(), any()); } /** @@ -218,7 +223,7 @@ public class LaunchParamsControllerTests extends WindowTestsBase { final LaunchParams result = new LaunchParams(); mController.calculate(null /*task*/, null /*layout*/, null /*activity*/, null /*source*/, - null /*options*/, PHASE_BOUNDS, result); + null /*options*/, PHASE_BOUNDS, result, null /* request */); assertEquals(result, positioner2.getLaunchParams()); } @@ -237,17 +242,17 @@ public class LaunchParamsControllerTests extends WindowTestsBase { // VR activities should always land on default display. mController.calculate(null /*task*/, null /*layout*/, vrActivity /*activity*/, - null /*source*/, null /*options*/, PHASE_BOUNDS, result); + null /*source*/, null /*options*/, PHASE_BOUNDS, result, null /* request */); assertEquals(mRootWindowContainer.getDefaultTaskDisplayArea(), result.mPreferredTaskDisplayArea); // Otherwise, always lands on VR 2D display. final ActivityRecord vr2dActivity = new ActivityBuilder(mAtm).build(); mController.calculate(null /*task*/, null /*layout*/, vr2dActivity /*activity*/, - null /*source*/, null /*options*/, PHASE_BOUNDS, result); + null /*source*/, null /*options*/, PHASE_BOUNDS, result, null /* request */); assertEquals(vrDisplay.getDefaultTaskDisplayArea(), result.mPreferredTaskDisplayArea); mController.calculate(null /*task*/, null /*layout*/, null /*activity*/, null /*source*/, - null /*options*/, PHASE_BOUNDS, result); + null /*options*/, PHASE_BOUNDS, result, null /* request */); assertEquals(vrDisplay.getDefaultTaskDisplayArea(), result.mPreferredTaskDisplayArea); mAtm.mVr2dDisplayId = INVALID_DISPLAY; @@ -269,9 +274,9 @@ public class LaunchParamsControllerTests extends WindowTestsBase { final ActivityOptions options = mock(ActivityOptions.class); mController.calculate(record.getTask(), layout, record, source, options, PHASE_BOUNDS, - new LaunchParams()); + new LaunchParams(), null /* request */); verify(positioner, times(1)).onCalculate(eq(record.getTask()), eq(layout), eq(record), - eq(source), eq(options), eq(PHASE_BOUNDS), any(), any()); + eq(source), eq(options), eq(PHASE_BOUNDS), any(), any(), any()); } /** @@ -403,8 +408,9 @@ public class LaunchParamsControllerTests extends WindowTestsBase { @Override public int onCalculate(Task task, WindowLayout layout, ActivityRecord activity, - ActivityRecord source, ActivityOptions options, int phase, - LaunchParams currentParams, LaunchParams outParams) { + ActivityRecord source, ActivityOptions options, int phase, + LaunchParams currentParams, LaunchParams outParams, + Request request) { outParams.set(mParams); return mReturnVal; } diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java index d919d58a4f95..7812934bb52f 100644 --- a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java @@ -17,7 +17,6 @@ package com.android.server.wm; import static android.app.ActivityManager.RECENT_WITH_EXCLUDED; -import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; @@ -48,7 +47,7 @@ import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.reset; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -58,12 +57,10 @@ import static java.lang.Integer.MAX_VALUE; import android.app.ActivityManager.RecentTaskInfo; import android.app.ActivityManager.RunningTaskInfo; import android.app.ActivityTaskManager; -import android.app.WindowConfiguration; import android.content.ComponentName; import android.content.pm.PackageManager; import android.content.pm.ParceledListSlice; import android.content.pm.UserInfo; -import android.content.res.Configuration; import android.graphics.Rect; import android.os.Bundle; import android.os.RemoteException; @@ -100,14 +97,14 @@ public class RecentTasksTest extends WindowTestsBase { private static final int TEST_USER_0_ID = 0; private static final int TEST_USER_1_ID = 10; private static final int TEST_QUIET_USER_ID = 20; - private static final UserInfo DEFAULT_USER_INFO = new UserInfo(); + private static final UserInfo DEFAULT_USER_INFO = new UserInfo(TEST_USER_0_ID, + "default", 0 /* flags */); private static final UserInfo QUIET_PROFILE_USER_INFO = new UserInfo(TEST_QUIET_USER_ID, "quiet_profile", null /* iconPath */, UserInfo.FLAG_QUIET_MODE, UserManager.USER_TYPE_PROFILE_MANAGED); private static final int INVALID_STACK_ID = 999; private TaskDisplayArea mTaskContainer; - private Task mStack; private TestTaskPersister mTaskPersister; private TestRecentTasks mRecentTasks; private TestRunningTasks mRunningTasks; @@ -133,8 +130,6 @@ public class RecentTasksTest extends WindowTestsBase { mRunningTasks = new TestRunningTasks(); mAtm.mTaskSupervisor.setRunningTasks(mRunningTasks); - mStack = mTaskContainer.createStack( - WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); mCallbacksRecorder = new CallbacksRecorder(); mRecentTasks.registerCallback(mCallbacksRecorder); @@ -214,9 +209,9 @@ public class RecentTasksTest extends WindowTestsBase { // Add N+1 tasks to ensure the previous task is trimmed mRecentTasks.add(mTasks.get(1)); + triggerTrimAndAssertTrimmed(mTasks.get(0)); verify(mTaskPersister, times(1)).wakeup(eq(mTasks.get(0)), anyBoolean()); verify(mTaskPersister, times(1)).wakeup(eq(mTasks.get(1)), anyBoolean()); - assertTrimmed(mTasks.get(0)); } @Test @@ -279,31 +274,6 @@ public class RecentTasksTest extends WindowTestsBase { } @Test - public void testAddTasksInVisibilityUpdate_expectNoTrim() { - mRecentTasks.setOnlyTestVisibleRange(); - mRecentTasks.setParameters(-1 /* min */, 1 /* max */, -1 /* ms */); - mRecentTasks.add(mTasks.get(0)); - - doAnswer(invocation -> { - assertTrue(mSupervisor.inActivityVisibilityUpdate()); - // Simulate an activity is resumed by EnsureActivitiesVisibleHelper. If its state is - // change to RESUMED, it will also be added to recents. - mRecentTasks.add(mTasks.get(1)); - invocation.callRealMethod(); - return null; - }).when(mSupervisor).endActivityVisibilityUpdate(); - - mTaskContainer.ensureActivitiesVisible(null /* starting */, 0 /* configChanges */, - false /* preserveWindows */, false /* notifyClients */, false /* userLeaving */); - - assertFalse(mSupervisor.inActivityVisibilityUpdate()); - assertThat(mCallbacksRecorder.mAdded).hasSize(2); - // Expect nothing is trimmed because we don't want the loop of ensure-visibility to be - // impacted by the arbitrary number of task removals. - assertNoTasksTrimmed(); - } - - @Test public void testAddTasksMultipleTasks_expectRemovedNoTrim() { // Add multiple same-affinity non-document tasks, ensure that it removes the other task, // but that it does not trim it @@ -336,7 +306,7 @@ public class RecentTasksTest extends WindowTestsBase { .setParentTask(mTaskContainer.getRootHomeTask()).build(); Task task2 = createTaskBuilder(".Task1") .setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK) - .setParentTask(mStack).build(); + .build(); mRecentTasks.add(task1); mRecentTasks.add(task2); assertThat(mCallbacksRecorder.mAdded).hasSize(2); @@ -351,17 +321,15 @@ public class RecentTasksTest extends WindowTestsBase { // Test with undefined activity type since the type is not persisted by the task persister // and we want to ensure that a new task will match a restored task Task task1 = createTaskBuilder(".Task1") + .setActivityType(ACTIVITY_TYPE_UNDEFINED) .setFlags(FLAG_ACTIVITY_NEW_TASK) - .setParentTask(mStack) .build(); - setTaskActivityType(task1, ACTIVITY_TYPE_UNDEFINED); assertThat(task1.getActivityType()).isEqualTo(ACTIVITY_TYPE_UNDEFINED); mRecentTasks.add(task1); mCallbacksRecorder.clear(); Task task2 = createTaskBuilder(".Task1") .setFlags(FLAG_ACTIVITY_NEW_TASK) - .setParentTask(mStack) .build(); assertEquals(ACTIVITY_TYPE_STANDARD, task2.getActivityType()); mRecentTasks.add(task2); @@ -375,18 +343,16 @@ public class RecentTasksTest extends WindowTestsBase { @Test public void testAddTaskCompatibleActivityTypeDifferentUser_expectNoRemove() { Task task1 = createTaskBuilder(".Task1") + .setActivityType(ACTIVITY_TYPE_UNDEFINED) .setFlags(FLAG_ACTIVITY_NEW_TASK) - .setParentTask(mStack) .setUserId(TEST_USER_0_ID) .build(); - setTaskActivityType(task1, ACTIVITY_TYPE_UNDEFINED); assertEquals(ACTIVITY_TYPE_UNDEFINED, task1.getActivityType()); mRecentTasks.add(task1); mCallbacksRecorder.clear(); Task task2 = createTaskBuilder(".Task1") .setFlags(FLAG_ACTIVITY_NEW_TASK) - .setParentTask(mStack) .setUserId(TEST_USER_1_ID) .build(); assertEquals(ACTIVITY_TYPE_STANDARD, task2.getActivityType()); @@ -401,18 +367,15 @@ public class RecentTasksTest extends WindowTestsBase { public void testAddTaskCompatibleWindowingMode_expectRemove() { Task task1 = createTaskBuilder(".Task1") .setFlags(FLAG_ACTIVITY_NEW_TASK) - .setParentTask(mStack) .build(); - setTaskWindowingMode(task1, WINDOWING_MODE_UNDEFINED); - assertEquals(WINDOWING_MODE_UNDEFINED, task1.getWindowingMode()); + doReturn(WINDOWING_MODE_UNDEFINED).when(task1).getWindowingMode(); mRecentTasks.add(task1); mCallbacksRecorder.clear(); Task task2 = createTaskBuilder(".Task1") + .setWindowingMode(WINDOWING_MODE_FULLSCREEN) .setFlags(FLAG_ACTIVITY_NEW_TASK) - .setParentTask(mStack) .build(); - setTaskWindowingMode(task2, WINDOWING_MODE_FULLSCREEN); assertEquals(WINDOWING_MODE_FULLSCREEN, task2.getWindowingMode()); mRecentTasks.add(task2); @@ -426,18 +389,16 @@ public class RecentTasksTest extends WindowTestsBase { @Test public void testAddTaskIncompatibleWindowingMode_expectNoRemove() { Task task1 = createTaskBuilder(".Task1") + .setWindowingMode(WINDOWING_MODE_FULLSCREEN) .setFlags(FLAG_ACTIVITY_NEW_TASK) - .setParentTask(mStack) .build(); - setTaskWindowingMode(task1, WINDOWING_MODE_FULLSCREEN); assertEquals(WINDOWING_MODE_FULLSCREEN, task1.getWindowingMode()); mRecentTasks.add(task1); Task task2 = createTaskBuilder(".Task1") + .setWindowingMode(WINDOWING_MODE_PINNED) .setFlags(FLAG_ACTIVITY_NEW_TASK) - .setParentTask(mStack) .build(); - setTaskWindowingMode(task2, WINDOWING_MODE_PINNED); assertEquals(WINDOWING_MODE_PINNED, task2.getWindowingMode()); mRecentTasks.add(task2); @@ -453,19 +414,19 @@ public class RecentTasksTest extends WindowTestsBase { // Add task to recents final String taskAffinity = "affinity"; final int uid = 10123; - final Task task1 = createTaskBuilder(".Task1").setParentTask(mStack).build(); + final Task task1 = createTaskBuilder(".Task1").build(); task1.affinity = ActivityRecord.computeTaskAffinity(taskAffinity, uid, LAUNCH_MULTIPLE); mRecentTasks.add(task1); // Add another task to recents, and make sure the previous task was removed. - final Task task2 = createTaskBuilder(".Task2").setParentTask(mStack).build(); + final Task task2 = createTaskBuilder(".Task2").build(); task2.affinity = ActivityRecord.computeTaskAffinity(taskAffinity, uid, LAUNCH_MULTIPLE); mRecentTasks.add(task2); assertEquals(1, mRecentTasks.getRecentTasks(MAX_VALUE, 0 /* flags */, true /* getTasksAllowed */, TEST_USER_0_ID, 0).getList().size()); // Add another single-instance task to recents, and make sure no task is removed. - final Task task3 = createTaskBuilder(".Task3").setParentTask(mStack).build(); + final Task task3 = createTaskBuilder(".Task3").build(); task3.affinity = ActivityRecord.computeTaskAffinity(taskAffinity, uid, LAUNCH_SINGLE_INSTANCE); mRecentTasks.add(task3); @@ -521,6 +482,7 @@ public class RecentTasksTest extends WindowTestsBase { // Go home to trigger the removal of untracked tasks. mRecentTasks.add(createTaskBuilder(".Home").setParentTask(mTaskContainer.getRootHomeTask()) .build()); + triggerIdleToTrim(); // The task was added into recents again so it is not hidden and shouldn't be removed. assertNotNull(task1.getTopNonFinishingActivity()); @@ -615,7 +577,7 @@ public class RecentTasksTest extends WindowTestsBase { mRecentTasks.add(mTasks.get(2)); // Ensure that the last task was trimmed as an inactive task - assertTrimmed(mTasks.get(0)); + triggerTrimAndAssertTrimmed(mTasks.get(0)); } @Test @@ -630,7 +592,7 @@ public class RecentTasksTest extends WindowTestsBase { mRecentTasks.add(mTasks.get(1)); // Ensure that the quiet user's tasks was trimmed once the new tasks were added - assertTrimmed(qt1, qt2); + triggerTrimAndAssertTrimmed(qt1, qt2); } @Test @@ -645,12 +607,8 @@ public class RecentTasksTest extends WindowTestsBase { // Force a small sleep just beyond the session duration SystemClock.sleep(75); - Task t2 = createTaskBuilder(".Task2").build(); - t2.touchActiveTime(); - mRecentTasks.add(t2); - // Assert that the old task has been removed due to being out of the active session - assertTrimmed(t1); + triggerTrimAndAssertTrimmed(t1); } @Test @@ -672,15 +630,15 @@ public class RecentTasksTest extends WindowTestsBase { mRecentTasks.add(excludedTask2); // The last excluded task should be trimmed, while the first-most excluded task should not - assertTrimmed(excludedTask1); + triggerTrimAndAssertTrimmed(excludedTask1); } @Test public void testVisibleTasks_excludedFromRecents_firstTaskNotVisible() { // Create some set of tasks, some of which are visible and some are not - Task homeTask = setTaskActivityType( - createTaskBuilder("com.android.pkg1", ".HomeTask").build(), - ACTIVITY_TYPE_HOME); + Task homeTask = createTaskBuilder("com.android.pkg1", ".HomeTask") + .setParentTask(mTaskContainer.getRootHomeTask()) + .build(); homeTask.mUserSetupComplete = true; mRecentTasks.add(homeTask); Task excludedTask1 = createTaskBuilder(".ExcludedTask1") @@ -699,9 +657,9 @@ public class RecentTasksTest extends WindowTestsBase { Task t1 = createTaskBuilder("com.android.pkg1", ".Task1").build(); t1.mUserSetupComplete = true; mRecentTasks.add(t1); - Task homeTask = setTaskActivityType( - createTaskBuilder("com.android.pkg1", ".HomeTask").build(), - ACTIVITY_TYPE_HOME); + Task homeTask = createTaskBuilder("com.android.pkg1", ".HomeTask") + .setParentTask(mTaskContainer.getRootHomeTask()) + .build(); homeTask.mUserSetupComplete = true; mRecentTasks.add(homeTask); Task excludedTask1 = createTaskBuilder(".ExcludedTask1") @@ -739,7 +697,7 @@ public class RecentTasksTest extends WindowTestsBase { mRecentTasks.add(mTasks.get(4)); // Ensure that there are a minimum number of tasks regardless of session length - assertNoTasksTrimmed(); + triggerTrimAndAssertNoTasksTrimmed(); } @Test @@ -754,7 +712,7 @@ public class RecentTasksTest extends WindowTestsBase { } // Ensure that only the last number of max tasks are kept - assertTrimmed(mTasks.get(0), mTasks.get(1)); + triggerTrimAndAssertTrimmed(mTasks.get(0), mTasks.get(1)); } /** @@ -782,12 +740,12 @@ public class RecentTasksTest extends WindowTestsBase { mRecentTasks.add(mTasks.get(3)); // excludedTask is not trimmed. - assertTrimmed(mTasks.get(0)); + triggerTrimAndAssertTrimmed(mTasks.get(0)); mRecentTasks.removeAllVisibleTasks(TEST_USER_0_ID); // Only visible tasks removed. - assertTrimmed(mTasks.get(0), mTasks.get(1), mTasks.get(2), mTasks.get(3)); + triggerTrimAndAssertTrimmed(mTasks.get(0), mTasks.get(1), mTasks.get(2), mTasks.get(3)); } @Test @@ -910,7 +868,7 @@ public class RecentTasksTest extends WindowTestsBase { mRecentTasks.add(createTaskBuilder(".Task2").setParentTask(aboveHomeStack).build()); mRecentTasks.add(createTaskBuilder(".Task3").setParentTask(aboveHomeStack).build()); - assertNoTasksTrimmed(); + triggerTrimAndAssertNoTasksTrimmed(); } @Test @@ -932,7 +890,7 @@ public class RecentTasksTest extends WindowTestsBase { mRecentTasks.add(createTaskBuilder(".HomeTask1").setParentTask(homeStack).build()); mRecentTasks.add(createTaskBuilder(".Task2").setParentTask(aboveHomeStack).build()); - assertTrimmed(behindHomeTask); + triggerTrimAndAssertTrimmed(behindHomeTask); } @Test @@ -951,7 +909,7 @@ public class RecentTasksTest extends WindowTestsBase { mRecentTasks.add(createTaskBuilder(".Task2").setParentTask(otherDisplayStack).build()); mRecentTasks.add(createTaskBuilder(".HomeTask2").setParentTask(homeStack).build()); - assertNoTasksTrimmed(); + triggerTrimAndAssertNoTasksTrimmed(); } @Test @@ -978,14 +936,12 @@ public class RecentTasksTest extends WindowTestsBase { // Create some set of tasks, some of which are visible and some are not Task t1 = createTaskBuilder("com.android.pkg1", ".Task1").build(); mRecentTasks.add(t1); - mRecentTasks.add(setTaskActivityType( - createTaskBuilder("com.android.pkg1", ".HomeTask").build(), - ACTIVITY_TYPE_HOME)); + mRecentTasks.add(createTaskBuilder("com.android.pkg1", ".HomeTask") + .setParentTask(mTaskContainer.getRootHomeTask()).build()); Task t2 = createTaskBuilder("com.android.pkg2", ".Task2").build(); mRecentTasks.add(t2); - mRecentTasks.add(setTaskWindowingMode( - createTaskBuilder("com.android.pkg1", ".PipTask").build(), - WINDOWING_MODE_PINNED)); + mRecentTasks.add(createTaskBuilder("com.android.pkg1", ".PipTask") + .setWindowingMode(WINDOWING_MODE_PINNED).build()); Task t3 = createTaskBuilder("com.android.pkg3", ".Task3").build(); mRecentTasks.add(t3); @@ -1005,7 +961,7 @@ public class RecentTasksTest extends WindowTestsBase { // Remove all the visible tasks and ensure that they are removed mRecentTasks.removeAllVisibleTasks(TEST_USER_0_ID); - assertTrimmed(t1, t2, t3, t4, t5, t6, t7); + triggerTrimAndAssertTrimmed(t1, t2, t3, t4, t5, t6, t7); } @Test @@ -1030,7 +986,7 @@ public class RecentTasksTest extends WindowTestsBase { // Remove all the visible tasks and ensure that they are removed mRecentTasks.removeAllVisibleTasks(TEST_USER_0_ID); - assertTrimmed(t1, t2); + triggerTrimAndAssertTrimmed(t1, t2); } @Test @@ -1040,7 +996,6 @@ public class RecentTasksTest extends WindowTestsBase { mRecentTasks.add(task); // Only keep the task in RecentTasks. task.removeIfPossible(); - mStack.removeIfPossible(); // The following APIs should not restore task from recents to the active list. assertNotRestoreTask(() -> mAtm.setFocusedTask(taskId)); @@ -1236,7 +1191,6 @@ public class RecentTasksTest extends WindowTestsBase { private TaskBuilder createTaskBuilder(String packageName, String className) { return new TaskBuilder(mAtm.mTaskSupervisor) .setComponent(new ComponentName(packageName, className)) - .setParentTask(mStack) .setUserId(TEST_USER_0_ID); } @@ -1253,27 +1207,19 @@ public class RecentTasksTest extends WindowTestsBase { return task; } - private Task setTaskActivityType(Task task, - @WindowConfiguration.ActivityType int activityType) { - Configuration config1 = new Configuration(); - config1.windowConfiguration.setActivityType(activityType); - task.onConfigurationChanged(config1); - return task; - } - - private Task setTaskWindowingMode(Task task, - @WindowConfiguration.WindowingMode int windowingMode) { - Configuration config1 = new Configuration(); - config1.windowConfiguration.setWindowingMode(windowingMode); - task.onConfigurationChanged(config1); - return task; + private void triggerIdleToTrim() { + doNothing().when(mAtm).scheduleAppGcsLocked(); + final ActivityRecord r = mRootWindowContainer.topRunningActivity(); + mSupervisor.activityIdleInternal(r != null ? r : mock(ActivityRecord.class), + false /* fromTimeout */, false /* processPausingActivities */, null /* config */); } - private void assertNoTasksTrimmed() { - assertTrimmed(); + private void triggerTrimAndAssertNoTasksTrimmed() { + triggerTrimAndAssertTrimmed(); } - private void assertTrimmed(Task... tasks) { + private void triggerTrimAndAssertTrimmed(Task... tasks) { + triggerIdleToTrim(); final ArrayList<Task> trimmed = mCallbacksRecorder.mTrimmed; final ArrayList<Task> removed = mCallbacksRecorder.mRemoved; assertWithMessage("Expected " + tasks.length + " trimmed tasks, got " + trimmed.size()) diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java index 98520bb7a20b..4f55322e2085 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java @@ -35,6 +35,7 @@ import static android.view.InsetsState.ITYPE_STATUS_BAR; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; +import static com.android.server.wm.ActivityStarter.Request; import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.RESULT_CONTINUE; import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.RESULT_SKIP; @@ -42,6 +43,9 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; import android.app.ActivityOptions; import android.content.pm.ActivityInfo; @@ -265,6 +269,180 @@ public class TaskLaunchParamsModifierTests extends WindowTestsBase { mResult.mPreferredTaskDisplayArea); } + @Test + public void testUsesDisplayAreaFromTopMostActivityInApplicationIfAvailable() { + final String processName = "processName"; + final int uid = 124214; + final TestDisplayContent firstScreen = createNewDisplayContent(WINDOWING_MODE_FULLSCREEN); + final TestDisplayContent secondScreen = createNewDisplayContent(WINDOWING_MODE_FULLSCREEN); + final TaskDisplayArea expectedDisplayArea = secondScreen.getDefaultTaskDisplayArea(); + final WindowProcessController controller = mock(WindowProcessController.class); + + when(controller.getTopActivityDisplayArea()).thenReturn(expectedDisplayArea); + + when(mActivity.getProcessName()).thenReturn(processName); + when(mActivity.getUid()).thenReturn(uid); + doReturn(controller) + .when(mSupervisor.mService) + .getProcessController(processName, uid); + + assertEquals(RESULT_CONTINUE, mTarget.onCalculate( + null /* task */, + null /* layout */, + mActivity /* activity */, + null /* source */, + null /* options */, + -1 /* phase */, + mCurrent, + mResult, + null /* request */ + )); + + assertEquals(expectedDisplayArea, mResult.mPreferredTaskDisplayArea); + } + + @Test + public void testUsesDisplayAreaFromLaunchingActivityIfApplicationLaunching() { + final String processName = "processName"; + final int uid = 124214; + final TestDisplayContent firstScreen = createNewDisplayContent(WINDOWING_MODE_FULLSCREEN); + final TestDisplayContent secondScreen = createNewDisplayContent(WINDOWING_MODE_FULLSCREEN); + final TaskDisplayArea expectedTaskDisplayArea = secondScreen.getDefaultTaskDisplayArea(); + final WindowProcessController controller = mock(WindowProcessController.class); + + when(controller.getTopActivityDisplayArea()).thenReturn(expectedTaskDisplayArea); + + when(mActivity.getProcessName()).thenReturn(processName); + when(mActivity.getUid()).thenReturn(uid); + doReturn(null) + .when(mSupervisor.mService) + .getProcessController(processName, uid); + + doReturn(controller) + .when(mSupervisor.mService) + .getProcessController(mActivity.launchedFromPid, mActivity.launchedFromUid); + + assertEquals(RESULT_CONTINUE, mTarget.onCalculate( + null /* task */, + null /* layout */, + mActivity /* activity */, + null /* source */, + null /* options */, + -1 /* phase */, + mCurrent, + mResult, + null /* request */ + )); + + assertEquals(expectedTaskDisplayArea, mResult.mPreferredTaskDisplayArea); + } + + @Test + public void testDisplayAreaFromLaunchingActivityTakesPrecedence() { + final String processName = "processName"; + final int uid = 124214; + final TestDisplayContent firstScreen = createNewDisplayContent(WINDOWING_MODE_FULLSCREEN); + final TestDisplayContent secondScreen = createNewDisplayContent(WINDOWING_MODE_FULLSCREEN); + final TaskDisplayArea firstTaskDisplayArea = firstScreen.getDefaultTaskDisplayArea(); + final TaskDisplayArea expectedTaskDisplayArea = secondScreen.getDefaultTaskDisplayArea(); + final WindowProcessController controllerForLaunching = mock(WindowProcessController.class); + final WindowProcessController controllerForApplication = + mock(WindowProcessController.class); + + when(mActivity.getProcessName()).thenReturn(processName); + when(mActivity.getUid()).thenReturn(uid); + + when(controllerForApplication.getTopActivityDisplayArea()).thenReturn(firstTaskDisplayArea); + when(controllerForLaunching.getTopActivityDisplayArea()) + .thenReturn(expectedTaskDisplayArea); + + doReturn(controllerForApplication) + .when(mSupervisor.mService) + .getProcessController(processName, uid); + doReturn(controllerForLaunching) + .when(mSupervisor.mService) + .getProcessController(mActivity.launchedFromPid, mActivity.launchedFromUid); + + assertEquals(RESULT_CONTINUE, mTarget.onCalculate( + null /* task */, + null /* layout */, + mActivity /* activity */, + null /* source */, + null /* options */, + -1 /* phase */, + mCurrent, + mResult, + null /* request */ + )); + + assertEquals(expectedTaskDisplayArea, mResult.mPreferredTaskDisplayArea); + } + + @Test + public void testUsesDisplayAreaOriginalProcessAsLastResort() { + final TestDisplayContent firstScreen = createNewDisplayContent(WINDOWING_MODE_FULLSCREEN); + final TestDisplayContent secondScreen = createNewDisplayContent(WINDOWING_MODE_FULLSCREEN); + final TaskDisplayArea expectedTaskDisplayArea = secondScreen.getDefaultTaskDisplayArea(); + final Request request = new Request(); + request.realCallingPid = 12412413; + request.realCallingUid = 235424; + + final WindowProcessController controller = mock(WindowProcessController.class); + + when(controller.getTopActivityDisplayArea()).thenReturn(expectedTaskDisplayArea); + + doReturn(null) + .when(mSupervisor.mService) + .getProcessController(mActivity.processName, mActivity.info.applicationInfo.uid); + + doReturn(null) + .when(mSupervisor.mService) + .getProcessController(mActivity.launchedFromPid, mActivity.launchedFromUid); + + doReturn(controller) + .when(mSupervisor.mService) + .getProcessController(request.realCallingPid, request.realCallingUid); + + assertEquals(RESULT_CONTINUE, mTarget.onCalculate( + null /* task */, + null /* layout */, + mActivity /* activity */, + null /* source */, + null /* options */, + -1 /* phase */, + mCurrent, + mResult, + request + )); + + assertEquals(expectedTaskDisplayArea, mResult.mPreferredTaskDisplayArea); + } + + @Test + public void testUsesDefaultDisplayAreaIfWindowProcessControllerIsNotPresent() { + doReturn(null) + .when(mSupervisor.mService) + .getProcessController(mActivity.processName, mActivity.info.applicationInfo.uid); + + doReturn(null) + .when(mSupervisor.mService) + .getProcessController(mActivity.launchedFromPid, mActivity.launchedFromUid); + + assertEquals(RESULT_CONTINUE, mTarget.onCalculate( + null /* task */, + null /* layout */, + mActivity /* activity */, + null /* source */, + null /* options */, + -1 /* phase */, + mCurrent, + mResult, + null /* request */ + )); + + assertEquals(DEFAULT_DISPLAY, mResult.mPreferredTaskDisplayArea.getDisplayId()); + } + // ===================================== // Launch Windowing Mode Related Tests // ===================================== diff --git a/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java b/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java index 165d4681c9e0..4909b1d7629e 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java @@ -17,6 +17,7 @@ package com.android.server.wm; import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; +import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.view.WindowManager.TRANSIT_OLD_TASK_OPEN; import static android.window.TransitionInfo.TRANSIT_HIDE; @@ -46,16 +47,24 @@ import org.junit.runner.RunWith; @RunWith(WindowTestRunner.class) public class TransitionTests extends WindowTestsBase { + private Transition createTestTransition(int transitType) { + TransitionController controller = mock(TransitionController.class); + BLASTSyncEngine sync = new BLASTSyncEngine(mWm); + return new Transition(transitType, 0 /* flags */, controller, sync); + } + @Test public void testCreateInfo_NewTask() { + final Transition transition = createTestTransition(TRANSIT_OLD_TASK_OPEN); + ArrayMap<WindowContainer, Transition.ChangeInfo> changes = transition.mChanges; + ArraySet<WindowContainer> participants = transition.mParticipants; + final Task newTask = createTaskStackOnDisplay(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, mDisplayContent); final Task oldTask = createTaskStackOnDisplay(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, mDisplayContent); final ActivityRecord closing = createActivityRecord(oldTask); final ActivityRecord opening = createActivityRecord(newTask); - ArrayMap<WindowContainer, Transition.ChangeInfo> changes = new ArrayMap<>(); - ArraySet<WindowContainer> participants = new ArraySet(); // Start states. changes.put(newTask, new Transition.ChangeInfo(false /* vis */, true /* exChg */)); changes.put(oldTask, new Transition.ChangeInfo(true /* vis */, true /* exChg */)); @@ -70,29 +79,32 @@ public class TransitionTests extends WindowTestsBase { // Check basic both tasks participating participants.add(oldTask); participants.add(newTask); - TransitionInfo info = - Transition.calculateTransitionInfo(transitType, participants, changes); + ArraySet<WindowContainer> targets = Transition.calculateTargets(participants, changes); + TransitionInfo info = Transition.calculateTransitionInfo(transitType, targets, changes); assertEquals(2, info.getChanges().size()); assertEquals(transitType, info.getType()); // Check that children are pruned participants.add(opening); participants.add(closing); - info = Transition.calculateTransitionInfo(transitType, participants, changes); + targets = Transition.calculateTargets(participants, changes); + info = Transition.calculateTransitionInfo(transitType, targets, changes); assertEquals(2, info.getChanges().size()); assertNotNull(info.getChange(newTask.mRemoteToken.toWindowContainerToken())); assertNotNull(info.getChange(oldTask.mRemoteToken.toWindowContainerToken())); // Check combined prune and promote participants.remove(newTask); - info = Transition.calculateTransitionInfo(transitType, participants, changes); + targets = Transition.calculateTargets(participants, changes); + info = Transition.calculateTransitionInfo(transitType, targets, changes); assertEquals(2, info.getChanges().size()); assertNotNull(info.getChange(newTask.mRemoteToken.toWindowContainerToken())); assertNotNull(info.getChange(oldTask.mRemoteToken.toWindowContainerToken())); // Check multi promote participants.remove(oldTask); - info = Transition.calculateTransitionInfo(transitType, participants, changes); + targets = Transition.calculateTargets(participants, changes); + info = Transition.calculateTransitionInfo(transitType, targets, changes); assertEquals(2, info.getChanges().size()); assertNotNull(info.getChange(newTask.mRemoteToken.toWindowContainerToken())); assertNotNull(info.getChange(oldTask.mRemoteToken.toWindowContainerToken())); @@ -100,6 +112,10 @@ public class TransitionTests extends WindowTestsBase { @Test public void testCreateInfo_NestedTasks() { + final Transition transition = createTestTransition(TRANSIT_OLD_TASK_OPEN); + ArrayMap<WindowContainer, Transition.ChangeInfo> changes = transition.mChanges; + ArraySet<WindowContainer> participants = transition.mParticipants; + final Task newTask = createTaskStackOnDisplay(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, mDisplayContent); final Task newNestedTask = createTaskInStack(newTask, 0); @@ -109,8 +125,6 @@ public class TransitionTests extends WindowTestsBase { final ActivityRecord closing = createActivityRecord(oldTask); final ActivityRecord opening = createActivityRecord(newNestedTask); final ActivityRecord opening2 = createActivityRecord(newNestedTask2); - ArrayMap<WindowContainer, Transition.ChangeInfo> changes = new ArrayMap<>(); - ArraySet<WindowContainer> participants = new ArraySet(); // Start states. changes.put(newTask, new Transition.ChangeInfo(false /* vis */, true /* exChg */)); changes.put(newNestedTask, new Transition.ChangeInfo(false /* vis */, true /* exChg */)); @@ -130,8 +144,8 @@ public class TransitionTests extends WindowTestsBase { participants.add(oldTask); participants.add(opening); participants.add(opening2); - TransitionInfo info = - Transition.calculateTransitionInfo(transitType, participants, changes); + ArraySet<WindowContainer> targets = Transition.calculateTargets(participants, changes); + TransitionInfo info = Transition.calculateTransitionInfo(transitType, targets, changes); assertEquals(2, info.getChanges().size()); assertEquals(transitType, info.getType()); assertNotNull(info.getChange(newTask.mRemoteToken.toWindowContainerToken())); @@ -139,7 +153,8 @@ public class TransitionTests extends WindowTestsBase { // Check that unchanging but visible descendant of sibling prevents promotion participants.remove(opening2); - info = Transition.calculateTransitionInfo(transitType, participants, changes); + targets = Transition.calculateTargets(participants, changes); + info = Transition.calculateTransitionInfo(transitType, targets, changes); assertEquals(2, info.getChanges().size()); assertNotNull(info.getChange(newNestedTask.mRemoteToken.toWindowContainerToken())); assertNotNull(info.getChange(oldTask.mRemoteToken.toWindowContainerToken())); @@ -147,6 +162,9 @@ public class TransitionTests extends WindowTestsBase { @Test public void testCreateInfo_DisplayArea() { + final Transition transition = createTestTransition(TRANSIT_OLD_TASK_OPEN); + ArrayMap<WindowContainer, Transition.ChangeInfo> changes = transition.mChanges; + ArraySet<WindowContainer> participants = transition.mParticipants; final Task showTask = createTaskStackOnDisplay(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, mDisplayContent); final Task showNestedTask = createTaskInStack(showTask, 0); @@ -155,8 +173,6 @@ public class TransitionTests extends WindowTestsBase { final DisplayArea tda = showTask.getDisplayArea(); final ActivityRecord showing = createActivityRecord(showNestedTask); final ActivityRecord showing2 = createActivityRecord(showTask2); - ArrayMap<WindowContainer, Transition.ChangeInfo> changes = new ArrayMap<>(); - ArraySet<WindowContainer> participants = new ArraySet(); // Start states. changes.put(showTask, new Transition.ChangeInfo(false /* vis */, true /* exChg */)); changes.put(showNestedTask, new Transition.ChangeInfo(false /* vis */, true /* exChg */)); @@ -173,8 +189,8 @@ public class TransitionTests extends WindowTestsBase { // Check promotion to DisplayArea participants.add(showing); participants.add(showing2); - TransitionInfo info = - Transition.calculateTransitionInfo(transitType, participants, changes); + ArraySet<WindowContainer> targets = Transition.calculateTargets(participants, changes); + TransitionInfo info = Transition.calculateTransitionInfo(transitType, targets, changes); assertEquals(1, info.getChanges().size()); assertEquals(transitType, info.getType()); assertNotNull(info.getChange(tda.mRemoteToken.toWindowContainerToken())); @@ -182,22 +198,21 @@ public class TransitionTests extends WindowTestsBase { ITaskOrganizer mockOrg = mock(ITaskOrganizer.class); // Check that organized tasks get reported even if not top showTask.mTaskOrganizer = mockOrg; - info = Transition.calculateTransitionInfo(transitType, participants, changes); + targets = Transition.calculateTargets(participants, changes); + info = Transition.calculateTransitionInfo(transitType, targets, changes); assertEquals(2, info.getChanges().size()); assertNotNull(info.getChange(tda.mRemoteToken.toWindowContainerToken())); assertNotNull(info.getChange(showTask.mRemoteToken.toWindowContainerToken())); // Even if DisplayArea explicitly participating participants.add(tda); - info = Transition.calculateTransitionInfo(transitType, participants, changes); + targets = Transition.calculateTargets(participants, changes); + info = Transition.calculateTransitionInfo(transitType, targets, changes); assertEquals(2, info.getChanges().size()); } @Test public void testCreateInfo_existenceChange() { - TransitionController controller = mock(TransitionController.class); - BLASTSyncEngine sync = new BLASTSyncEngine(mWm); - Transition transition = new Transition( - TRANSIT_OLD_TASK_OPEN, 0 /* flags */, controller, sync); + final Transition transition = createTestTransition(TRANSIT_OLD_TASK_OPEN); final Task openTask = createTaskStackOnDisplay(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, mDisplayContent); @@ -214,8 +229,9 @@ public class TransitionTests extends WindowTestsBase { opening.mVisibleRequested = true; closing.mVisibleRequested = false; - TransitionInfo info = Transition.calculateTransitionInfo( - 0, transition.mParticipants, transition.mChanges); + ArraySet<WindowContainer> targets = Transition.calculateTargets( + transition.mParticipants, transition.mChanges); + TransitionInfo info = Transition.calculateTransitionInfo(0, targets, transition.mChanges); assertEquals(2, info.getChanges().size()); // There was an existence change on open, so it should be OPEN rather than SHOW assertEquals(TRANSIT_OPEN, @@ -224,4 +240,39 @@ public class TransitionTests extends WindowTestsBase { assertEquals(TRANSIT_HIDE, info.getChange(closeTask.mRemoteToken.toWindowContainerToken()).getMode()); } + + @Test + public void testCreateInfo_ordering() { + final Transition transition = createTestTransition(TRANSIT_OLD_TASK_OPEN); + // pick some number with a high enough chance of being out-of-order when added to set. + final int taskCount = 6; + + final Task[] tasks = new Task[taskCount]; + for (int i = 0; i < taskCount; ++i) { + // Each add goes on top, so at the end of this, task[9] should be on top + tasks[i] = createTaskStackOnDisplay(WINDOWING_MODE_FREEFORM, + ACTIVITY_TYPE_STANDARD, mDisplayContent); + final ActivityRecord act = createActivityRecord(tasks[i]); + // alternate so that the transition doesn't get promoted to the display area + act.mVisibleRequested = (i % 2) == 0; // starts invisible + } + + // doesn't matter which order collected since participants is a set + for (int i = 0; i < taskCount; ++i) { + transition.collectExistenceChange(tasks[i]); + final ActivityRecord act = tasks[i].getTopMostActivity(); + transition.collect(act); + tasks[i].getTopMostActivity().mVisibleRequested = (i % 2) != 0; + } + + ArraySet<WindowContainer> targets = Transition.calculateTargets( + transition.mParticipants, transition.mChanges); + TransitionInfo info = Transition.calculateTransitionInfo(0, targets, transition.mChanges); + assertEquals(taskCount, info.getChanges().size()); + // verify order is top-to-bottem + for (int i = 0; i < taskCount; ++i) { + assertEquals(tasks[taskCount - i - 1].mRemoteToken.toWindowContainerToken(), + info.getChanges().get(i).getContainer()); + } + } } diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java index 5afcedb10dd6..3057558a6e98 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java @@ -27,10 +27,13 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; +import static org.mockito.Mockito.when; import android.Manifest; import android.app.IApplicationThread; @@ -327,6 +330,45 @@ public class WindowProcessControllerTests extends WindowTestsBase { return new ActivityBuilder(mAtm).setCreateTask(true).setUseProcess(wpc).build(); } + @Test + public void testTopActivityDisplayAreaMatchesTopMostActivity_noActivities() { + assertNull(mWpc.getTopActivityDisplayArea()); + } + + @Test + public void testTopActivityDisplayAreaMatchesTopMostActivity_singleActivity() { + final ActivityRecord activityRecord = new ActivityBuilder(mSupervisor.mService).build(); + final TaskDisplayArea expectedDisplayArea = mock(TaskDisplayArea.class); + + when(activityRecord.getDisplayArea()) + .thenReturn(expectedDisplayArea); + + mWpc.addActivityIfNeeded(activityRecord); + + assertEquals(expectedDisplayArea, mWpc.getTopActivityDisplayArea()); + } + + /** + * Test that top most activity respects z-order. + */ + @Test + public void testTopActivityDisplayAreaMatchesTopMostActivity_multipleActivities() { + final ActivityRecord bottomRecord = new ActivityBuilder(mSupervisor.mService).build(); + final TaskDisplayArea bottomDisplayArea = mock(TaskDisplayArea.class); + final ActivityRecord topRecord = new ActivityBuilder(mSupervisor.mService).build(); + final TaskDisplayArea topDisplayArea = mock(TaskDisplayArea.class); + + when(bottomRecord.getDisplayArea()).thenReturn(bottomDisplayArea); + when(topRecord.getDisplayArea()).thenReturn(topDisplayArea); + doReturn(-1).when(bottomRecord).compareTo(topRecord); + doReturn(1).when(topRecord).compareTo(bottomRecord); + + mWpc.addActivityIfNeeded(topRecord); + mWpc.addActivityIfNeeded(bottomRecord); + + assertEquals(topDisplayArea, mWpc.getTopActivityDisplayArea()); + } + private TestDisplayContent createTestDisplayContentInContainer() { return new TestDisplayContent.Builder(mAtm, 1000, 1500).build(); } diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java index 1d498bd3253b..227eba2a041b 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java @@ -648,6 +648,8 @@ public class WindowStateTests extends WindowTestsBase { win1.mSurfaceControl = mock(SurfaceControl.class); win1.mAttrs.surfaceInsets.set(1, 2, 3, 4); win1.getFrame().offsetTo(WINDOW_OFFSET, 0); + // Simulate layout + win1.mRelayoutCalled = true; win1.updateSurfacePosition(t); win1.getTransformationMatrix(values, matrix); diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java index 83053813116b..6c046bda1444 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java @@ -40,6 +40,8 @@ import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR; import static android.view.WindowManager.LayoutParams.TYPE_NOTIFICATION_SHADE; import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR; import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER; +import static android.view.WindowManager.DISPLAY_IME_POLICY_LOCAL; +import static android.view.WindowManager.DISPLAY_IME_POLICY_FALLBACK_DISPLAY; import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation; @@ -80,6 +82,7 @@ import android.view.SurfaceControl; import android.view.SurfaceControl.Transaction; import android.view.View; import android.view.WindowManager; +import android.view.WindowManager.DisplayImePolicy; import android.window.ITaskOrganizer; import com.android.internal.util.ArrayUtils; @@ -174,7 +177,7 @@ class WindowTestsBase extends SystemServiceTestsBase { private void createTestDisplay(UseTestDisplay annotation) { beforeCreateTestDisplay(); - mDisplayContent = createNewDisplay(true /* supportIme */); + mDisplayContent = createNewDisplayWithImeSupport(DISPLAY_IME_POLICY_LOCAL); final boolean addAll = annotation.addAllCommonWindows(); final @CommonTypes int[] requestedWindows = annotation.addWindows(); @@ -482,26 +485,26 @@ class WindowTestsBase extends SystemServiceTestsBase { /** Creates a {@link DisplayContent} that supports IME and adds it to the system. */ DisplayContent createNewDisplay() { - return createNewDisplay(true /* supportIme */); + return createNewDisplayWithImeSupport(DISPLAY_IME_POLICY_LOCAL); } /** Creates a {@link DisplayContent} and adds it to the system. */ - private DisplayContent createNewDisplay(boolean supportIme) { - return createNewDisplay(mDisplayInfo, supportIme); + private DisplayContent createNewDisplayWithImeSupport(@DisplayImePolicy int imePolicy) { + return createNewDisplay(mDisplayInfo, imePolicy); } /** Creates a {@link DisplayContent} that supports IME and adds it to the system. */ DisplayContent createNewDisplay(DisplayInfo info) { - return createNewDisplay(info, true /* supportIme */); + return createNewDisplay(info, DISPLAY_IME_POLICY_LOCAL); } /** Creates a {@link DisplayContent} and adds it to the system. */ - private DisplayContent createNewDisplay(DisplayInfo info, boolean supportIme) { + private DisplayContent createNewDisplay(DisplayInfo info, @DisplayImePolicy int imePolicy) { final DisplayContent display = new TestDisplayContent.Builder(mAtm, info).build(); final DisplayContent dc = display.mDisplayContent; // this display can show IME. - dc.mWmService.mDisplayWindowSettings.setShouldShowImeLocked(dc, supportIme); + dc.mWmService.mDisplayWindowSettings.setDisplayImePolicy(dc, imePolicy); return dc; } @@ -516,7 +519,7 @@ class WindowTestsBase extends SystemServiceTestsBase { DisplayInfo displayInfo = new DisplayInfo(); displayInfo.copyFrom(mDisplayInfo); displayInfo.state = displayState; - return createNewDisplay(displayInfo, true /* supportIme */); + return createNewDisplay(displayInfo, DISPLAY_IME_POLICY_LOCAL); } /** Creates a {@link TestWindowState} */ @@ -532,7 +535,7 @@ class WindowTestsBase extends SystemServiceTestsBase { displayInfo.copyFrom(mDisplayInfo); displayInfo.type = Display.TYPE_VIRTUAL; displayInfo.ownerUid = SYSTEM_UID; - return createNewDisplay(displayInfo, false /* supportIme */); + return createNewDisplay(displayInfo, DISPLAY_IME_POLICY_FALLBACK_DISPLAY); } IDisplayWindowInsetsController createDisplayWindowInsetsController() { diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java index 8e56e5bb2d85..aa36e47a359b 100644 --- a/services/usage/java/com/android/server/usage/UsageStatsService.java +++ b/services/usage/java/com/android/server/usage/UsageStatsService.java @@ -82,6 +82,7 @@ import android.util.SparseArray; import android.util.SparseBooleanArray; import android.util.SparseIntArray; +import com.android.internal.annotations.VisibleForTesting; import com.android.internal.content.PackageMonitor; import com.android.internal.os.BackgroundThread; import com.android.internal.util.CollectionUtils; @@ -90,7 +91,6 @@ import com.android.internal.util.FrameworkStatsLog; import com.android.internal.util.IndentingPrintWriter; import com.android.server.LocalServices; import com.android.server.SystemService; -import com.android.server.SystemService.TargetUser; import com.android.server.usage.AppStandbyInternal.AppIdleStateChangeListener; import java.io.BufferedReader; @@ -178,6 +178,8 @@ public class UsageStatsService extends SystemService implements private final SparseArray<LinkedList<Event>> mReportedEvents = new SparseArray<>(); final SparseArray<ArraySet<String>> mUsageReporters = new SparseArray(); final SparseArray<ActivityData> mVisibleActivities = new SparseArray(); + private final ArraySet<UsageStatsManagerInternal.UsageEventListener> mUsageEventListeners = + new ArraySet<>(); private static class ActivityData { private final String mTaskRootPackage; @@ -202,8 +204,24 @@ public class UsageStatsService extends SystemService implements } }; + @VisibleForTesting + static class Injector { + AppStandbyInternal getAppStandbyController(Context context) { + return AppStandbyInternal.newAppStandbyController( + UsageStatsService.class.getClassLoader(), context); + } + } + + private final Injector mInjector; + public UsageStatsService(Context context) { + this(context, new Injector()); + } + + @VisibleForTesting + UsageStatsService(Context context, Injector injector) { super(context); + mInjector = injector; } @Override @@ -214,8 +232,7 @@ public class UsageStatsService extends SystemService implements mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class); mHandler = new H(BackgroundThread.get().getLooper()); - mAppStandby = AppStandbyInternal.newAppStandbyController( - UsageStatsService.class.getClassLoader(), getContext()); + mAppStandby = mInjector.getAppStandbyController(getContext()); mAppTimeLimit = new AppTimeLimitController( new AppTimeLimitController.TimeLimitCallbackListener() { @@ -262,6 +279,11 @@ public class UsageStatsService extends SystemService implements publishLocalService(UsageStatsManagerInternal.class, new LocalService()); publishLocalService(AppStandbyInternal.class, mAppStandby); + publishBinderServices(); + } + + @VisibleForTesting + void publishBinderServices() { publishBinderService(Context.USAGE_STATS_SERVICE, new BinderService()); } @@ -928,7 +950,10 @@ public class UsageStatsService extends SystemService implements service.reportEvent(event); } - mAppStandby.reportEvent(event, userId); + final int size = mUsageEventListeners.size(); + for (int i = 0; i < size; ++i) { + mUsageEventListeners.valueAt(i).onUsageEvent(userId, event); + } } /** @@ -1151,6 +1176,25 @@ public class UsageStatsService extends SystemService implements } } + /** + * Called via the local interface. + */ + private void registerListener(@NonNull UsageStatsManagerInternal.UsageEventListener listener) { + synchronized (mLock) { + mUsageEventListeners.add(listener); + } + } + + /** + * Called via the local interface. + */ + private void unregisterListener( + @NonNull UsageStatsManagerInternal.UsageEventListener listener) { + synchronized (mLock) { + mUsageEventListeners.remove(listener); + } + } + private String buildFullToken(String packageName, String token) { final StringBuilder sb = new StringBuilder(packageName.length() + token.length() + 1); sb.append(packageName); @@ -2317,6 +2361,22 @@ public class UsageStatsService extends SystemService implements public boolean updatePackageMappingsData() { return UsageStatsService.this.updatePackageMappingsData(); } + + /** + * Register a listener that will be notified of every new usage event. + */ + @Override + public void registerListener(@NonNull UsageEventListener listener) { + UsageStatsService.this.registerListener(listener); + } + + /** + * Unregister a listener from being notified of every new usage event. + */ + @Override + public void unregisterListener(@NonNull UsageEventListener listener) { + UsageStatsService.this.unregisterListener(listener); + } } private class MyPackageMonitor extends PackageMonitor { diff --git a/telecomm/java/android/telecom/PhoneAccount.java b/telecomm/java/android/telecom/PhoneAccount.java index 5024ae27ee49..835ecaa8c90d 100644 --- a/telecomm/java/android/telecom/PhoneAccount.java +++ b/telecomm/java/android/telecom/PhoneAccount.java @@ -361,7 +361,13 @@ public final class PhoneAccount implements Parcelable { */ public static final int CAPABILITY_ADHOC_CONFERENCE_CALLING = 0x4000; - /* NEXT CAPABILITY: 0x8000 */ + /** + * Flag indicating whether this {@link PhoneAccount} is capable of supporting the call composer + * functionality for enriched calls. + */ + public static final int CAPABILITY_CALL_COMPOSER = 0x8000; + + /* NEXT CAPABILITY: 0x10000 */ /** * URI scheme for telephone number URIs. @@ -1088,6 +1094,9 @@ public final class PhoneAccount implements Parcelable { if (hasCapabilities(CAPABILITY_ADHOC_CONFERENCE_CALLING)) { sb.append("AdhocConf"); } + if (hasCapabilities(CAPABILITY_CALL_COMPOSER)) { + sb.append("CallComposer "); + } return sb.toString(); } diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java index 902dc0619014..dad18ffe4fa7 100644 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -1881,9 +1881,8 @@ public class CarrierConfigManager { * "APN_1, ERROR_CODE_1 : CARRIER_ACTION_IDX_1, CARRIER_ACTION_IDX_2...", * "APN_1, ERROR_CODE_2 : CARRIER_ACTION_IDX_1 " * } - * Where {@code APN_1} is a string defined in - * com.android.internal.telephony.PhoneConstants - * Example: "default" + * Where {@code APN_1} is an integer defined in {@link android.telephony.data.ApnSetting} + * (e.g. {@link android.telephony.data.ApnSetting#TYPE_DEFAULT} * * {@code ERROR_CODE_1} is an integer defined in android.telephony.DataFailCause * Example: diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index e341e0c19cf5..643d8c8ba2a5 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -1575,177 +1575,157 @@ public class TelephonyManager { "android.telephony.extra.PHONE_IN_ECM_STATE"; /** - * <p>Broadcast Action: when data connections get redirected with validation failure. - * intended for sim/account status checks and only sent to the specified carrier app - * The intent will have the following extra values:</p> + * Broadcast action sent when a data connection is redirected with validation failure. + * + * This action is intended for sim/account status checks and only sent to the carrier apps + * specified in the carrier config for the subscription ID that's attached to this intent. + * + * The intent will have the following extra values: * <ul> - * <li>{@link #EXTRA_APN_TYPE}</li><dd>A string with the apn type.</dd> - * <li>{@link #EXTRA_APN_TYPE_INT}</li><dd>A integer with the apn type.</dd> - * <li>{@link #EXTRA_REDIRECTION_URL}</li><dd>redirection url string</dd> - * <li>subId</li><dd>Sub Id which associated the data connection failure.</dd> + * <li>{@link #EXTRA_APN_TYPE}</li><dd>An integer indicating the apn type.</dd> + * <li>{@link #EXTRA_REDIRECTION_URL}</li><dd>A string indicating the redirection url</dd> + * <li>{@link SubscriptionManager#EXTRA_SUBSCRIPTION_INDEX}</li> + * <dd>The subscription ID on which the validation failure happened.</dd> * </ul> * <p class="note">This is a protected intent that can only be sent by the system.</p> - * @hide */ - @SuppressLint("ActionValue") + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String ACTION_CARRIER_SIGNAL_REDIRECTED = - "com.android.internal.telephony.CARRIER_SIGNAL_REDIRECTED"; + "android.telephony.action.CARRIER_SIGNAL_REDIRECTED"; /** - * <p>Broadcast Action: when data connections setup fails. - * intended for sim/account status checks and only sent to the specified carrier app - * The intent will have the following extra values:</p> + * Broadcast action sent when a data connection setup fails. + * + * This action is intended for sim/account status checks and only sent to the carrier apps + * specified in the carrier config for the subscription ID that's attached to this intent. + * + * The intent will have the following extra values: * <ul> - * <li>{@link #EXTRA_APN_TYPE}</li><dd>A string with the apn type.</dd> - * <li>{@link #EXTRA_APN_TYPE_INT}</li><dd>A integer with the apn type.</dd> - * <li>{@link #EXTRA_ERROR_CODE}</li><dd>A integer with dataFailCause.</dd> - * <li>subId</li><dd>Sub Id which associated the data connection failure.</dd> + * <li>{@link #EXTRA_APN_TYPE}</li><dd>An integer indicating the apn type.</dd> + * <li>{@link #EXTRA_DATA_FAIL_CAUSE}</li><dd>A integer indicating the data fail cause.</dd> + * <li>{@link SubscriptionManager#EXTRA_SUBSCRIPTION_INDEX}</li> + * <dd>The subscription ID on which the data setup failure happened.</dd> * </ul> * <p class="note">This is a protected intent that can only be sent by the system. </p> - * @hide */ - @SuppressLint("ActionValue") + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String ACTION_CARRIER_SIGNAL_REQUEST_NETWORK_FAILED = - "com.android.internal.telephony.CARRIER_SIGNAL_REQUEST_NETWORK_FAILED"; + "android.telephony.action.CARRIER_SIGNAL_REQUEST_NETWORK_FAILED"; /** - * <p>Broadcast Action: when pco value is available. - * intended for sim/account status checks and only sent to the specified carrier app + * Broadcast action sent when a PCO value becomes available from the modem. + * + * This action is intended for sim/account status checks and only sent to the carrier apps + * specified in the carrier config for the subscription ID that's attached to this intent. + * * The intent will have the following extra values:</p> * <ul> - * <li>{@link #EXTRA_APN_TYPE}</li><dd>A string with the apn type.</dd> - * <li>{@link #EXTRA_APN_TYPE_INT}</li><dd>A integer with the apn type.</dd> - * <li>{@link #EXTRA_APN_PROTOCOL}</li><dd>A string with the protocol of the apn connection - * (IP,IPV6, IPV4V6)</dd> - * <li>{@link #EXTRA_APN_PROTOCOL_INT}</li><dd>A integer with the protocol of the apn - * connection (IP,IPV6, IPV4V6)</dd> - * <li>{@link #EXTRA_PCO_ID}</li><dd>An integer indicating the pco id for the data.</dd> - * <li>{@link #EXTRA_PCO_VALUE}</li><dd>A byte array of pco data read from modem.</dd> - * <li>subId</li><dd>Sub Id which associated the data connection.</dd> + * <li>{@link #EXTRA_APN_TYPE}</li><dd>An integer indicating the apn type.</dd> + * <li>{@link #EXTRA_APN_PROTOCOL}</li><dd>An integer indicating the protocol of the apn + * connection</dd> + * <li>{@link #EXTRA_PCO_ID}</li><dd>An integer indicating the PCO id for the data.</dd> + * <li>{@link #EXTRA_PCO_VALUE}</li><dd>A byte array of PCO data read from modem.</dd> + * <li>{@link SubscriptionManager#EXTRA_SUBSCRIPTION_INDEX}</li> + * <dd>The subscription ID for which the PCO info was received.</dd> * </ul> * <p class="note">This is a protected intent that can only be sent by the system. </p> - * @hide */ - @SuppressLint("ActionValue") + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String ACTION_CARRIER_SIGNAL_PCO_VALUE = - "com.android.internal.telephony.CARRIER_SIGNAL_PCO_VALUE"; + "android.telephony.action.CARRIER_SIGNAL_PCO_VALUE"; /** - * <p>Broadcast Action: when system default network available/unavailable with - * carrier-disabled mobile data. Intended for carrier apps to set/reset carrier actions when - * other network becomes system default network, Wi-Fi for example. + * Broadcast action sent when the availability of the system default network changes. + * + * @see ConnectivityManager#registerDefaultNetworkCallback(ConnectivityManager.NetworkCallback) + * + * This action is intended for carrier apps to set/reset carrier actions. It is only sent to the + * carrier apps specified in the carrier config for the subscription ID attached to this intent. + * * The intent will have the following extra values:</p> * <ul> * <li>{@link #EXTRA_DEFAULT_NETWORK_AVAILABLE}</li> - * <dd>A boolean indicates default network available.</dd> - * <li>subId</li><dd>Sub Id which associated the default data.</dd> + * <dd>{@code true} if the default network is now available, {@code false} otherwise.</dd> + * <li>{@link SubscriptionManager#EXTRA_SUBSCRIPTION_INDEX}</li> + * <dd>The subscription ID on which the default network availability changed.</dd> * </ul> * <p class="note">This is a protected intent that can only be sent by the system. </p> - * @hide */ - @SuppressLint("ActionValue") + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String ACTION_CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE = - "com.android.internal.telephony.CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE"; + "android.telephony.action.CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE"; /** - * <p>Broadcast Action: when framework reset all carrier actions on sim load or absent. - * intended for carrier apps clean up (clear UI e.g.) and only sent to the specified carrier app + * Broadcast action sent when carrier apps should reset their internal state. + * + * Sent when certain events such as turning on/off mobile data, removing the SIM, etc. require + * carrier apps to reset their state. + * + * This action is intended to signal carrier apps to perform cleanup operations. It is only sent + * to the carrier apps specified in the carrier config for the subscription ID attached to + * this intent. + * * The intent will have the following extra values:</p> * <ul> - * <li>subId</li><dd>Sub Id which associated the data connection failure.</dd> + * <li>{@link SubscriptionManager#EXTRA_SUBSCRIPTION_INDEX}</li> + * <dd>The subscription ID for which state should be reset.</dd> * </ul> * <p class="note">This is a protected intent that can only be sent by the system.</p> - * @hide */ - @SuppressLint("ActionValue") + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String ACTION_CARRIER_SIGNAL_RESET = - "com.android.internal.telephony.CARRIER_SIGNAL_RESET"; + "android.telephony.action.CARRIER_SIGNAL_RESET"; - // CARRIER_SIGNAL_ACTION extra keys /** - * An string extra of redirected url upon {@link #ACTION_CARRIER_SIGNAL_REDIRECTED}. - * @hide + * String extra containing the redirection URL sent with + * {@link #ACTION_CARRIER_SIGNAL_REDIRECTED}. */ - @SuppressLint("ActionValue") - public static final String EXTRA_REDIRECTION_URL = "redirectionUrl"; + public static final String EXTRA_REDIRECTION_URL = "android.telephony.extra.REDIRECTION_URL"; /** - * An integer extra of error code upon {@link #ACTION_CARRIER_SIGNAL_REQUEST_NETWORK_FAILED}. - * Check {@link DataFailCause} for all possible values. - * @hide - */ - @SuppressLint("ActionValue") - public static final String EXTRA_ERROR_CODE = "errorCode"; - - /** - * An string extra of corresponding apn type upon - * {@link #ACTION_CARRIER_SIGNAL_REQUEST_NETWORK_FAILED}, - * {@link #ACTION_CARRIER_SIGNAL_REDIRECTED} and - * {@link #ACTION_CARRIER_SIGNAL_PCO_VALUE} broadcasts. - * @deprecated This is kept for backward compatibility reason. Use {@link #EXTRA_APN_TYPE_INT} - * instead. + * An integer extra containing the data fail cause. * - * @hide + * Sent with {@link #ACTION_CARRIER_SIGNAL_REQUEST_NETWORK_FAILED}. See {@link DataFailCause} + * for a list of possible values. */ - @Deprecated - @SuppressLint("ActionValue") - public static final String EXTRA_APN_TYPE = "apnType"; + public static final String EXTRA_DATA_FAIL_CAUSE = "android.telephony.extra.DATA_FAIL_CAUSE"; /** - * An string integer of corresponding apn type upon - * {@link #ACTION_CARRIER_SIGNAL_REQUEST_NETWORK_FAILED}, - * {@link #ACTION_CARRIER_SIGNAL_REDIRECTED} and - * {@link #ACTION_CARRIER_SIGNAL_PCO_VALUE} broadcasts. - * Check {@link ApnSetting} TYPE_* for its values. - * @hide - */ - @SuppressLint("ActionValue") - public static final String EXTRA_APN_TYPE_INT = "apnTypeInt"; - - /** - * An string extra with the protocol of the apn connection (IP,IPV6, IPV4V6) upon - * {@link #ACTION_CARRIER_SIGNAL_PCO_VALUE} broadcasts. - * @deprecated This is kept for backward compatibility reason. - * Use {@link #EXTRA_APN_PROTOCOL_INT} instead. + * An integer extra containing the APN type. * - * @hide + * Sent with the {@link #ACTION_CARRIER_SIGNAL_REQUEST_NETWORK_FAILED}, + * {@link #ACTION_CARRIER_SIGNAL_REDIRECTED}, and {@link #ACTION_CARRIER_SIGNAL_PCO_VALUE} + * broadcasts. + * See the {@code TYPE_} constants in {@link ApnSetting} for a list of possible values. */ - @Deprecated - @SuppressLint("ActionValue") - public static final String EXTRA_APN_PROTOCOL = "apnProto"; + public static final String EXTRA_APN_TYPE = "android.telephony.extra.APN_TYPE"; /** - * An integer extra with the protocol of the apn connection (IP,IPV6, IPV4V6) upon - * {@link #ACTION_CARRIER_SIGNAL_PCO_VALUE} broadcasts. - * Check {@link ApnSetting} PROTOCOL_* for its values. - * @hide + * An integer extra containing the protocol of the apn connection. + * + * Sent with the {@link #ACTION_CARRIER_SIGNAL_PCO_VALUE} broadcast. + * See the {@code PROTOCOL_*} constants in {@link ApnSetting} for a list of possible values. */ - @SuppressLint("ActionValue") - public static final String EXTRA_APN_PROTOCOL_INT = "apnProtoInt"; + public static final String EXTRA_APN_PROTOCOL = "android.telephony.extra.APN_PROTOCOL"; /** - * An integer extra indicating the pco id for the data upon - * {@link #ACTION_CARRIER_SIGNAL_PCO_VALUE} broadcasts. - * @hide + * An integer extra indicating the ID for the PCO data. + * Sent with the {@link #ACTION_CARRIER_SIGNAL_PCO_VALUE} broadcast. */ - @SuppressLint("ActionValue") - public static final String EXTRA_PCO_ID = "pcoId"; + public static final String EXTRA_PCO_ID = "android.telephony.extra.PCO_ID"; /** - * An extra of byte array of pco data read from modem upon - * {@link #ACTION_CARRIER_SIGNAL_PCO_VALUE} broadcasts. - * @hide + * A byte array extra containing PCO data read from the modem. + * Sent with the {@link #ACTION_CARRIER_SIGNAL_PCO_VALUE} broadcast. */ - @SuppressLint("ActionValue") - public static final String EXTRA_PCO_VALUE = "pcoValue"; + public static final String EXTRA_PCO_VALUE = "android.telephony.extra.PCO_VALUE"; /** - * An boolean extra indicating default network available upon - * {@link #ACTION_CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE} broadcasts. - * @hide + * A boolean extra indicating the availability of the default network. + * Sent with the {@link #ACTION_CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE} broadcast. */ - @SuppressLint("ActionValue") - public static final String EXTRA_DEFAULT_NETWORK_AVAILABLE = "defaultNetworkAvailable"; + public static final String EXTRA_DEFAULT_NETWORK_AVAILABLE = + "android.telephony.extra.DEFAULT_NETWORK_AVAILABLE"; /** * <p>Broadcast Action: The emergency call state is changed. diff --git a/telephony/java/android/telephony/ims/RcsUceAdapter.java b/telephony/java/android/telephony/ims/RcsUceAdapter.java index ada069666547..8d7742b7510b 100644 --- a/telephony/java/android/telephony/ims/RcsUceAdapter.java +++ b/telephony/java/android/telephony/ims/RcsUceAdapter.java @@ -76,39 +76,46 @@ public class RcsUceAdapter { * @hide */ public static final int ERROR_GENERIC_FAILURE = 1; + /** * The carrier network does not have UCE support enabled for this subscriber. * @hide */ public static final int ERROR_NOT_ENABLED = 2; + /** * The data network that the device is connected to does not support UCE currently (e.g. it is * 1x only currently). * @hide */ public static final int ERROR_NOT_AVAILABLE = 3; + /** * The network has responded with SIP 403 error and a reason "User not registered." * @hide */ public static final int ERROR_NOT_REGISTERED = 4; + /** * The network has responded to this request with a SIP 403 error and reason "not authorized for * presence" for this subscriber. * @hide */ public static final int ERROR_NOT_AUTHORIZED = 5; + /** * The network has responded to this request with a SIP 403 error and no reason. * @hide */ public static final int ERROR_FORBIDDEN = 6; + /** * The contact URI requested is not provisioned for VoLTE or it is not known as an IMS * subscriber to the carrier network. * @hide */ public static final int ERROR_NOT_FOUND = 7; + /** * The capabilities request contained too many URIs for the carrier network to handle. Retry * with a lower number of contact numbers. The number varies per carrier. @@ -116,22 +123,32 @@ public class RcsUceAdapter { */ // TODO: Try to integrate this into the API so that the service will split based on carrier. public static final int ERROR_REQUEST_TOO_LARGE = 8; + /** * The network did not respond to the capabilities request before the request timed out. * @hide */ public static final int ERROR_REQUEST_TIMEOUT = 10; + /** * The request failed due to the service having insufficient memory. * @hide */ public static final int ERROR_INSUFFICIENT_MEMORY = 11; + /** * The network was lost while trying to complete the request. * @hide */ public static final int ERROR_LOST_NETWORK = 12; + /** + * The network is temporarily unavailable or busy. Retries should only be done after the retry + * time returned in {@link CapabilitiesCallback#onError} has elapsed. + * @hide + */ + public static final int ERROR_SERVER_UNAVAILABLE = 13; + /**@hide*/ @Retention(RetentionPolicy.SOURCE) @IntDef(prefix = "ERROR_", value = { @@ -145,7 +162,8 @@ public class RcsUceAdapter { ERROR_REQUEST_TOO_LARGE, ERROR_REQUEST_TIMEOUT, ERROR_INSUFFICIENT_MEMORY, - ERROR_LOST_NETWORK + ERROR_LOST_NETWORK, + ERROR_SERVER_UNAVAILABLE }) public @interface ErrorCode {} @@ -369,8 +387,10 @@ public class RcsUceAdapter { * The pending request has resulted in an error and may need to be retried, depending on the * error code. * @param errorCode The reason for the framework being unable to process the request. + * @param retryAfterMilliseconds The time in milliseconds the requesting application should + * wait before retrying, if non-zero. */ - void onError(@ErrorCode int errorCode); + void onError(@ErrorCode int errorCode, long retryAfterMilliseconds); } private final Context mContext; @@ -451,10 +471,10 @@ public class RcsUceAdapter { } } @Override - public void onError(int errorCode) { + public void onError(int errorCode, long retryAfterMilliseconds) { final long callingIdentity = Binder.clearCallingIdentity(); try { - executor.execute(() -> c.onError(errorCode)); + executor.execute(() -> c.onError(errorCode, retryAfterMilliseconds)); } finally { restoreCallingIdentity(callingIdentity); } @@ -535,10 +555,10 @@ public class RcsUceAdapter { } } @Override - public void onError(int errorCode) { + public void onError(int errorCode, long retryAfterMilliseconds) { final long callingIdentity = Binder.clearCallingIdentity(); try { - executor.execute(() -> c.onError(errorCode)); + executor.execute(() -> c.onError(errorCode, retryAfterMilliseconds)); } finally { restoreCallingIdentity(callingIdentity); } diff --git a/telephony/java/android/telephony/ims/aidl/IRcsUceControllerCallback.aidl b/telephony/java/android/telephony/ims/aidl/IRcsUceControllerCallback.aidl index 0bd3e5ed354e..0f627b92a24c 100644 --- a/telephony/java/android/telephony/ims/aidl/IRcsUceControllerCallback.aidl +++ b/telephony/java/android/telephony/ims/aidl/IRcsUceControllerCallback.aidl @@ -26,5 +26,5 @@ import android.telephony.ims.RcsContactUceCapability; oneway interface IRcsUceControllerCallback { void onCapabilitiesReceived(in List<RcsContactUceCapability> contactCapabilities); void onComplete(); - void onError(int errorCode); + void onError(int errorCode, long retryAfterMilliseconds); } diff --git a/telephony/java/com/android/internal/telephony/TelephonyIntents.java b/telephony/java/com/android/internal/telephony/TelephonyIntents.java index d216162cc257..b905212a9100 100644 --- a/telephony/java/com/android/internal/telephony/TelephonyIntents.java +++ b/telephony/java/com/android/internal/telephony/TelephonyIntents.java @@ -321,4 +321,107 @@ public class TelephonyIntents { */ public static final String ACTION_USER_ACTIVITY_NOTIFICATION = "android.intent.action.USER_ACTIVITY_NOTIFICATION"; + + /** + * Kept for backwards compatibility. + * @deprecated @see TelephonyManager#ACTION_CARRIER_SIGNAL_REDIRECTED + */ + @Deprecated + public static final String ACTION_CARRIER_SIGNAL_REDIRECTED = + "com.android.internal.telephony.CARRIER_SIGNAL_REDIRECTED"; + + /** + * Kept for backwards compatibility. + * @deprecated @see TelephonyManager#ACTION_CARRIER_SIGNAL_REQUEST_NETWORK_FAILED + */ + @Deprecated + public static final String ACTION_CARRIER_SIGNAL_REQUEST_NETWORK_FAILED = + "com.android.internal.telephony.CARRIER_SIGNAL_REQUEST_NETWORK_FAILED"; + + /** + * Kept for backwards compatibility. + * @deprecated @see TelephonyManager#ACTION_CARRIER_SIGNAL_PCO_VALUE + */ + @Deprecated + public static final String ACTION_CARRIER_SIGNAL_PCO_VALUE = + "com.android.internal.telephony.CARRIER_SIGNAL_PCO_VALUE"; + + /** + * Kept for backwards compatibility. + * @deprecated @see TelephonyManager#ACTION_CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE + */ + @Deprecated + public static final String ACTION_CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE = + "com.android.internal.telephony.CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE"; + + /** + * Kept for backwards compatibility. + * @deprecated @see TelephonyManager#ACTION_CARRIER_SIGNAL_RESET + */ + @Deprecated + public static final String ACTION_CARRIER_SIGNAL_RESET = + "com.android.internal.telephony.CARRIER_SIGNAL_RESET"; + + /** + * Kept for backwards compatibility. + * @deprecated @see TelephonyManager#EXTRA_REDIRECTION_URL + */ + @Deprecated + public static final String EXTRA_REDIRECTION_URL = "redirectionUrl"; + + /** + * Kept for backwards compatibility. + * @deprecated @see TelephonyManager#EXTRA_DATA_FAIL_CAUSE + */ + @Deprecated + public static final String EXTRA_ERROR_CODE = "errorCode"; + + /** + * Kept for backwards compatibility. + * @deprecated @see TelephonyManager#EXTRA_APN_TYPE + */ + @Deprecated + public static final String EXTRA_APN_TYPE = "apnType"; + + /** + * Kept for backwards compatibility. + * @deprecated @see TelephonyManager#EXTRA_APN_TYPE + */ + @Deprecated + public static final String EXTRA_APN_TYPE_INT = "apnTypeInt"; + + /** + * Kept for backwards compatibility. + * @deprecated @see TelephonyManager#EXTRA_APN_PROTOCOL + */ + @Deprecated + public static final String EXTRA_APN_PROTOCOL = "apnProto"; + + /** + * Kept for backwards compatibility. + * @deprecated @see TelephonyManager#EXTRA_APN_PROTOCOL + */ + @Deprecated + public static final String EXTRA_APN_PROTOCOL_INT = "apnProtoInt"; + + /** + * Kept for backwards compatibility. + * @deprecated @see TelephonyManager#EXTRA_PCO_ID + */ + @Deprecated + public static final String EXTRA_PCO_ID = "pcoId"; + + /** + * Kept for backwards compatibility. + * @deprecated @see TelephonyManager#EXTRA_PCO_VALUE + */ + @Deprecated + public static final String EXTRA_PCO_VALUE = "pcoValue"; + + /** + * Kept for backwards compatibility. + * @deprecated @see TelephonyManager#EXTRA_DEFAULT_NETWORK_AVAILABLE + */ + @Deprecated + public static final String EXTRA_DEFAULT_NETWORK_AVAILABLE = "defaultNetworkAvailable"; } diff --git a/tests/BootImageProfileTest/TEST_MAPPING b/tests/BootImageProfileTest/TEST_MAPPING deleted file mode 100644 index 1b569f9455bf..000000000000 --- a/tests/BootImageProfileTest/TEST_MAPPING +++ /dev/null @@ -1,7 +0,0 @@ -{ - "presubmit": [ - { - "name": "BootImageProfileTest" - } - ] -} diff --git a/tests/FlickerTests/Android.bp b/tests/FlickerTests/Android.bp index 3b9bec9ad0a7..1a83655ed8d3 100644 --- a/tests/FlickerTests/Android.bp +++ b/tests/FlickerTests/Android.bp @@ -59,7 +59,10 @@ android_test { java_library { name: "wm-flicker-common-assertions", platform_apis: true, - srcs: ["src/**/*Assertions.java", "src/**/*Assertions.kt"], + srcs: [ + "src/**/*Assertions.java", + "src/**/*Assertions.kt", + ], exclude_srcs: [ "**/helpers/*", ], @@ -68,4 +71,17 @@ java_library { "truth-prebuilt", "app-helpers-core" ], +} + +java_library { + name: "wm-flicker-common-app-helpers", + platform_apis: true, + srcs: [ + "**/helpers/*" + ], + static_libs: [ + "flickerlib", + "truth-prebuilt", + "app-helpers-core" + ], }
\ No newline at end of file diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/PipAppHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/PipAppHelper.kt deleted file mode 100644 index 0572a7813819..000000000000 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/PipAppHelper.kt +++ /dev/null @@ -1,43 +0,0 @@ -/* - * 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.server.wm.flicker.helpers - -import android.app.Instrumentation -import android.support.test.launcherhelper.ILauncherStrategy -import android.support.test.launcherhelper.LauncherStrategyFactory -import androidx.test.uiautomator.By -import androidx.test.uiautomator.UiDevice -import org.junit.Assert - -class PipAppHelper( - instr: Instrumentation, - launcherStrategy: ILauncherStrategy = LauncherStrategyFactory - .getInstance(instr) - .launcherStrategy -) : StandardAppHelper(instr, "PipApp", launcherStrategy) { - fun clickEnterPipButton(device: UiDevice) { - val enterPipButton = device.findObject(By.res(getPackage(), "enter_pip")) - Assert.assertNotNull("Pip button not found, this usually happens when the device " + - "was left in an unknown state (e.g. in split screen)", enterPipButton) - enterPipButton.click() - device.hasPipWindow() - } - - fun closePipWindow(device: UiDevice) { - device.closePipWindow() - } -} diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/pip/EnterPipTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/pip/EnterPipTest.kt deleted file mode 100644 index 89539fd1a9ec..000000000000 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/pip/EnterPipTest.kt +++ /dev/null @@ -1,133 +0,0 @@ -/* - * 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.server.wm.flicker.pip - -import android.platform.test.annotations.Presubmit -import android.view.Surface -import androidx.test.filters.FlakyTest -import androidx.test.filters.RequiresDevice -import androidx.test.platform.app.InstrumentationRegistry -import com.android.server.wm.flicker.Flicker -import com.android.server.wm.flicker.FlickerTestRunner -import com.android.server.wm.flicker.FlickerTestRunnerFactory -import com.android.server.wm.flicker.helpers.PipAppHelper -import com.android.server.wm.flicker.helpers.buildTestTag -import com.android.server.wm.flicker.helpers.closePipWindow -import com.android.server.wm.flicker.helpers.expandPipWindow -import com.android.server.wm.flicker.helpers.hasPipWindow -import com.android.server.wm.flicker.helpers.setRotation -import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen -import com.android.server.wm.flicker.navBarLayerIsAlwaysVisible -import com.android.server.wm.flicker.navBarLayerRotatesAndScales -import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible -import com.android.server.wm.flicker.noUncoveredRegions -import com.android.server.wm.flicker.repetitions -import com.android.server.wm.flicker.startRotation -import com.android.server.wm.flicker.statusBarLayerIsAlwaysVisible -import com.android.server.wm.flicker.statusBarLayerRotatesScales -import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible -import org.junit.FixMethodOrder -import org.junit.runner.RunWith -import org.junit.runners.MethodSorters -import org.junit.runners.Parameterized - -/** - * Test Pip launch. - * To run this test: `atest FlickerTests:PipToAppTest` - */ -@Presubmit -@RequiresDevice -@RunWith(Parameterized::class) -@FixMethodOrder(MethodSorters.NAME_ASCENDING) -@FlakyTest(bugId = 152738416) -class EnterPipTest( - testName: String, - flickerSpec: Flicker -) : FlickerTestRunner(testName, flickerSpec) { - companion object { - @Parameterized.Parameters(name = "{0}") - @JvmStatic - fun getParams(): List<Array<Any>> { - val instrumentation = InstrumentationRegistry.getInstrumentation() - val testApp = PipAppHelper(instrumentation) - return FlickerTestRunnerFactory(instrumentation, listOf(Surface.ROTATION_0)) - .buildTest { configuration -> - withTestName { buildTestTag("enterPip", testApp, configuration) } - repeat { configuration.repetitions } - setup { - test { - device.wakeUpAndGoToHomeScreen() - } - eachRun { - device.pressHome() - testApp.open() - this.setRotation(configuration.startRotation) - } - } - teardown { - eachRun { - if (device.hasPipWindow()) { - device.closePipWindow() - } - testApp.exit() - this.setRotation(Surface.ROTATION_0) - } - test { - if (device.hasPipWindow()) { - device.closePipWindow() - } - } - } - transitions { - testApp.clickEnterPipButton(device) - device.expandPipWindow() - } - assertions { - windowManagerTrace { - navBarWindowIsAlwaysVisible() - statusBarWindowIsAlwaysVisible() - - all("pipWindowBecomesVisible") { - this.showsAppWindow(testApp.`package`) - .then() - .showsAppWindow(PIP_WINDOW_TITLE) - } - } - - layersTrace { - navBarLayerIsAlwaysVisible(bugId = 140855415) - statusBarLayerIsAlwaysVisible() - noUncoveredRegions(configuration.startRotation, Surface.ROTATION_0, - enabled = false) - navBarLayerRotatesAndScales(configuration.startRotation, - Surface.ROTATION_0, bugId = 140855415) - statusBarLayerRotatesScales(configuration.startRotation, - Surface.ROTATION_0) - } - - layersTrace { - all("pipLayerBecomesVisible") { - this.showsLayer(testApp.launcherName) - .then() - .showsLayer(PIP_WINDOW_TITLE) - } - } - } - } - } - } -}
\ No newline at end of file diff --git a/tests/FlickerTests/test-apps/flickerapp/AndroidManifest.xml b/tests/FlickerTests/test-apps/flickerapp/AndroidManifest.xml index 4d2144061ad4..1599ed4b280f 100644 --- a/tests/FlickerTests/test-apps/flickerapp/AndroidManifest.xml +++ b/tests/FlickerTests/test-apps/flickerapp/AndroidManifest.xml @@ -49,18 +49,6 @@ <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> - <activity android:name=".PipActivity" - android:resizeableActivity="true" - android:supportsPictureInPicture="true" - android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation" - android:taskAffinity="com.android.server.wm.flicker.testapp.PipActivity" - android:label="PipApp" - android:exported="true"> - <intent-filter> - <action android:name="android.intent.action.MAIN"/> - <category android:name="android.intent.category.LAUNCHER"/> - </intent-filter> - </activity> <activity android:name=".SeamlessRotationActivity" android:taskAffinity="com.android.server.wm.flicker.testapp.SeamlessRotationActivity" android:configChanges="orientation|screenSize" diff --git a/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java b/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java index fa0574a503f1..9738e58543e1 100644 --- a/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java +++ b/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java @@ -1064,6 +1064,31 @@ public class PackageWatchdogTest { } /** + * Ensure that the correct mitigation counts are sent to the boot loop observer. + */ + @Test + public void testMultipleBootLoopMitigation() { + PackageWatchdog watchdog = createWatchdog(); + TestObserver bootObserver = new TestObserver(OBSERVER_NAME_1); + watchdog.registerHealthObserver(bootObserver); + for (int i = 0; i < 4; i++) { + for (int j = 0; j < PackageWatchdog.DEFAULT_BOOT_LOOP_TRIGGER_COUNT; j++) { + watchdog.noteBoot(); + } + } + + moveTimeForwardAndDispatch(PackageWatchdog.DEFAULT_DEESCALATION_WINDOW_MS + 1); + + for (int i = 0; i < 4; i++) { + for (int j = 0; j < PackageWatchdog.DEFAULT_BOOT_LOOP_TRIGGER_COUNT; j++) { + watchdog.noteBoot(); + } + } + + assertThat(bootObserver.mBootMitigationCounts).isEqualTo(List.of(1, 2, 3, 4, 1, 2, 3, 4)); + } + + /** * Ensure that passing a null list of failed packages does not cause any mitigation logic to * execute. */ @@ -1267,6 +1292,7 @@ public class PackageWatchdogTest { final List<String> mHealthCheckFailedPackages = new ArrayList<>(); final List<String> mMitigatedPackages = new ArrayList<>(); final List<Integer> mMitigationCounts = new ArrayList<>(); + final List<Integer> mBootMitigationCounts = new ArrayList<>(); TestObserver(String name) { mName = name; @@ -1304,12 +1330,13 @@ public class PackageWatchdogTest { return mMayObservePackages; } - public int onBootLoop() { + public int onBootLoop(int level) { return mImpact; } - public boolean executeBootLoopMitigation() { + public boolean executeBootLoopMitigation(int level) { mMitigatedBootLoop = true; + mBootMitigationCounts.add(level); return true; } diff --git a/tests/net/common/java/android/net/MatchAllNetworkSpecifierTest.kt b/tests/net/common/java/android/net/MatchAllNetworkSpecifierTest.kt index a67156a74d18..a5e44d59fcab 100644 --- a/tests/net/common/java/android/net/MatchAllNetworkSpecifierTest.kt +++ b/tests/net/common/java/android/net/MatchAllNetworkSpecifierTest.kt @@ -53,8 +53,13 @@ class MatchAllNetworkSpecifierTest { assertParcelSane(MatchAllNetworkSpecifier(), 0) } - @Test @IgnoreAfter(Build.VERSION_CODES.R) - fun testCanBeSatisfiedBy_BeforeS() { + @Test + @IgnoreUpTo(Build.VERSION_CODES.Q) + @IgnoreAfter(Build.VERSION_CODES.R) + // Only run this test on Android R. + // The method - satisfiedBy() has changed to canBeSatisfiedBy() starting from Android R, so the + // method - canBeSatisfiedBy() cannot be found when running this test on Android Q. + fun testCanBeSatisfiedBy_OnlyForR() { // MatchAllNetworkSpecifier didn't follow its parent class to change the satisfiedBy() to // canBeSatisfiedBy(), so if a caller calls MatchAllNetworkSpecifier#canBeSatisfiedBy(), the // NetworkSpecifier#canBeSatisfiedBy() will be called actually, and false will be returned. diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java index 2758f6156c16..b7804b86c63f 100644 --- a/tests/net/java/com/android/server/ConnectivityServiceTest.java +++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java @@ -18,6 +18,8 @@ package com.android.server; import static android.Manifest.permission.CHANGE_NETWORK_STATE; import static android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS; +import static android.content.Intent.ACTION_USER_ADDED; +import static android.content.Intent.ACTION_USER_REMOVED; import static android.content.pm.PackageInfo.REQUESTED_PERMISSION_GRANTED; import static android.content.pm.PackageManager.GET_PERMISSIONS; import static android.content.pm.PackageManager.MATCH_ANY_USER; @@ -4944,8 +4946,6 @@ public class ConnectivityServiceTest { final Network[] cellAndVpn = new Network[] { mCellNetworkAgent.getNetwork(), mMockVpn.getNetwork()}; - Network[] cellAndWifi = new Network[] { - mCellNetworkAgent.getNetwork(), mWiFiNetworkAgent.getNetwork()}; // A VPN with default (null) underlying networks sets the underlying network's interfaces... expectForceUpdateIfaces(cellAndVpn, MOBILE_IFNAME, Process.myUid(), VPN_IFNAME, @@ -4955,10 +4955,13 @@ public class ConnectivityServiceTest { mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); mWiFiNetworkAgent.connect(false); mWiFiNetworkAgent.sendLinkProperties(wifiLp); + final Network[] onlyNull = new Network[]{null}; final Network[] wifiAndVpn = new Network[] { mWiFiNetworkAgent.getNetwork(), mMockVpn.getNetwork()}; - cellAndWifi = new Network[] { + final Network[] cellAndWifi = new Network[] { mCellNetworkAgent.getNetwork(), mWiFiNetworkAgent.getNetwork()}; + final Network[] cellNullAndWifi = new Network[] { + mCellNetworkAgent.getNetwork(), null, mWiFiNetworkAgent.getNetwork()}; waitForIdle(); assertEquals(wifiLp, mService.getActiveLinkProperties()); @@ -4984,6 +4987,13 @@ public class ConnectivityServiceTest { new String[]{MOBILE_IFNAME, WIFI_IFNAME}); reset(mStatsService); + // Null underlying networks are ignored. + mService.setUnderlyingNetworksForVpn(cellNullAndWifi); + waitForIdle(); + expectForceUpdateIfaces(wifiAndVpn, MOBILE_IFNAME, Process.myUid(), VPN_IFNAME, + new String[]{MOBILE_IFNAME, WIFI_IFNAME}); + reset(mStatsService); + // If an underlying network disconnects, that interface should no longer be underlying. // This doesn't actually work because disconnectAndDestroyNetwork only notifies // NetworkStatsService before the underlying network is actually removed. So the underlying @@ -5018,6 +5028,7 @@ public class ConnectivityServiceTest { argThat(vpnInfos -> vpnInfos[0].underlyingIfaces.length == 1 && WIFI_IFNAME.equals(vpnInfos[0].underlyingIfaces[0]))); mEthernetNetworkAgent.disconnect(); + waitForIdle(); reset(mStatsService); // When a VPN declares no underlying networks (i.e., no connectivity), getAllVpnInfo @@ -5030,6 +5041,18 @@ public class ConnectivityServiceTest { waitForIdle(); expectForceUpdateIfaces(wifiAndVpn, null); reset(mStatsService); + + // Specifying only a null underlying network is the same as no networks. + mService.setUnderlyingNetworksForVpn(onlyNull); + waitForIdle(); + expectForceUpdateIfaces(wifiAndVpn, null); + reset(mStatsService); + + // Specifying networks that are all disconnected is the same as specifying no networks. + mService.setUnderlyingNetworksForVpn(onlyCell); + waitForIdle(); + expectForceUpdateIfaces(wifiAndVpn, null); + reset(mStatsService); } @Test @@ -5471,6 +5494,7 @@ public class ConnectivityServiceTest { final Set<UidRange> ranges = uidRangesForUid(uid); mMockVpn.registerAgent(ranges); + mService.setUnderlyingNetworksForVpn(new Network[0]); // VPN networks do not satisfy the default request and are automatically validated // by NetworkMonitor @@ -5479,19 +5503,12 @@ public class ConnectivityServiceTest { mMockVpn.getAgent().setNetworkValid(false /* isStrictMode */); mMockVpn.connect(false); - mService.setUnderlyingNetworksForVpn(new Network[0]); - genericNetworkCallback.expectAvailableCallbacksUnvalidated(mMockVpn); + genericNetworkCallback.expectAvailableThenValidatedCallbacks(mMockVpn); genericNotVpnNetworkCallback.assertNoCallback(); wifiNetworkCallback.assertNoCallback(); - vpnNetworkCallback.expectAvailableCallbacksUnvalidated(mMockVpn); - defaultCallback.expectAvailableCallbacksUnvalidated(mMockVpn); - assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); - - genericNetworkCallback.expectCallback(CallbackEntry.NETWORK_CAPS_UPDATED, mMockVpn); - genericNotVpnNetworkCallback.assertNoCallback(); - vpnNetworkCallback.expectCapabilitiesThat(mMockVpn, nc -> null == nc.getUids()); - defaultCallback.expectCallback(CallbackEntry.NETWORK_CAPS_UPDATED, mMockVpn); + vpnNetworkCallback.expectAvailableThenValidatedCallbacks(mMockVpn); + defaultCallback.expectAvailableThenValidatedCallbacks(mMockVpn); assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); ranges.clear(); @@ -5884,6 +5901,75 @@ public class ConnectivityServiceTest { } @Test + public void testVpnRestrictedUsers() throws Exception { + // NETWORK_SETTINGS is necessary to see the UID ranges in NetworkCapabilities. + mServiceContext.setPermission(Manifest.permission.NETWORK_SETTINGS, + PERMISSION_GRANTED); + + final NetworkRequest request = new NetworkRequest.Builder() + .removeCapability(NET_CAPABILITY_NOT_VPN) + .build(); + final TestNetworkCallback callback = new TestNetworkCallback(); + mCm.registerNetworkCallback(request, callback); + + // Bring up a VPN + mMockVpn.establishForMyUid(); + callback.expectAvailableThenValidatedCallbacks(mMockVpn); + callback.assertNoCallback(); + + final int uid = Process.myUid(); + NetworkCapabilities nc = mCm.getNetworkCapabilities(mMockVpn.getNetwork()); + assertNotNull("nc=" + nc, nc.getUids()); + assertEquals(nc.getUids(), uidRangesForUid(uid)); + + // Set an underlying network and expect to see the VPN transports change. + mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); + mWiFiNetworkAgent.connect(true); + callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); + callback.expectCapabilitiesThat(mMockVpn, (caps) + -> caps.hasTransport(TRANSPORT_VPN) + && caps.hasTransport(TRANSPORT_WIFI)); + callback.expectCapabilitiesThat(mWiFiNetworkAgent, (caps) + -> caps.hasCapability(NET_CAPABILITY_VALIDATED)); + + // Create a fake restricted profile whose parent is our user ID. + final int userId = UserHandle.getUserId(uid); + final int restrictedUserId = userId + 1; + final UserInfo info = new UserInfo(restrictedUserId, "user", UserInfo.FLAG_RESTRICTED); + info.restrictedProfileParentId = userId; + assertTrue(info.isRestricted()); + when(mUserManager.getUserInfo(restrictedUserId)).thenReturn(info); + final Intent addedIntent = new Intent(ACTION_USER_ADDED); + addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, restrictedUserId); + + // Send a USER_ADDED broadcast for it. + // The BroadcastReceiver for this broadcast checks that is being run on the handler thread. + final Handler handler = new Handler(mCsHandlerThread.getLooper()); + handler.post(() -> mServiceContext.sendBroadcast(addedIntent)); + + // Expect that the VPN UID ranges contain both |uid| and the UID range for the newly-added + // restricted user. + callback.expectCapabilitiesThat(mMockVpn, (caps) + -> caps.getUids().size() == 2 + && caps.getUids().contains(new UidRange(uid, uid)) + && caps.getUids().contains(UidRange.createForUser(restrictedUserId)) + && caps.hasTransport(TRANSPORT_VPN) + && caps.hasTransport(TRANSPORT_WIFI)); + + // Send a USER_REMOVED broadcast and expect to lose the UID range for the restricted user. + final Intent removedIntent = new Intent(ACTION_USER_REMOVED); + removedIntent.putExtra(Intent.EXTRA_USER_HANDLE, restrictedUserId); + handler.post(() -> mServiceContext.sendBroadcast(removedIntent)); + + // Expect that the VPN gains the UID range for the restricted user. + callback.expectCapabilitiesThat(mMockVpn, (caps) + -> caps.getUids().size() == 1 + && caps.getUids().contains(new UidRange(uid, uid)) + && caps.hasTransport(TRANSPORT_VPN) + && caps.hasTransport(TRANSPORT_WIFI)); + } + + @Test public void testIsActiveNetworkMeteredOverWifi() throws Exception { // Returns true by default when no network is available. assertTrue(mCm.isActiveNetworkMetered()); diff --git a/tools/codegen/src/com/android/codegen/Generators.kt b/tools/codegen/src/com/android/codegen/Generators.kt index 6c6d011cfede..5fc800b09ee9 100644 --- a/tools/codegen/src/com/android/codegen/Generators.kt +++ b/tools/codegen/src/com/android/codegen/Generators.kt @@ -5,8 +5,6 @@ import com.github.javaparser.ast.body.MethodDeclaration import com.github.javaparser.ast.body.VariableDeclarator import com.github.javaparser.ast.expr.AnnotationExpr import com.github.javaparser.ast.expr.ArrayInitializerExpr -import com.github.javaparser.ast.expr.LiteralExpr -import com.github.javaparser.ast.expr.UnaryExpr import java.io.File @@ -163,7 +161,12 @@ fun ClassPrinter.generateCopyConstructor() { return } - +"/** Copy constructor */" + +"/**" + +" * Copy constructor" + if (FeatureFlag.COPY_CONSTRUCTOR.hidden) { + +" * @hide" + } + +" */" +GENERATED_MEMBER_HEADER "public $ClassName(@$NonNull $ClassName orig)" { fields.forEachApply { diff --git a/tools/codegen/src/com/android/codegen/SharedConstants.kt b/tools/codegen/src/com/android/codegen/SharedConstants.kt index 2e176c3d3bec..6a635d0e6181 100644 --- a/tools/codegen/src/com/android/codegen/SharedConstants.kt +++ b/tools/codegen/src/com/android/codegen/SharedConstants.kt @@ -1,7 +1,7 @@ package com.android.codegen const val CODEGEN_NAME = "codegen" -const val CODEGEN_VERSION = "1.0.20" +const val CODEGEN_VERSION = "1.0.21" const val CANONICAL_BUILDER_CLASS = "Builder" const val BASE_BUILDER_CLASS = "BaseBuilder" diff --git a/tools/hiddenapi/exclude.sh b/tools/hiddenapi/exclude.sh index 18c40546fd02..73eacc0641e5 100755 --- a/tools/hiddenapi/exclude.sh +++ b/tools/hiddenapi/exclude.sh @@ -35,7 +35,7 @@ TEAMS=LIBCORE PACKAGES=$(for t in $TEAMS; do echo $(eval echo \${${t}_PACKAGES}); done) RE=$(echo ${PACKAGES} | sed "s/ /|/g") git show --name-only --pretty=format: $1 | grep "config/hiddenapi-.*txt" | while read file; do - ENTRIES=$(grep -E "^L(${RE})/" <(git show $1:$file)) + ENTRIES=$(grep -E "^L(${RE})/" || true <(git show $1:$file)) if [[ -n "${ENTRIES}" ]]; then echo -e "\e[1m\e[31m$file $1 contains the following entries\e[0m" echo -e "\e[1m\e[31mfor packages that are handled using UnsupportedAppUsage. Please remove\e[0m" diff --git a/tools/stats_log_api_gen/Collation.cpp b/tools/stats_log_api_gen/Collation.cpp index fe6ca558a0ee..56f4db0b2aed 100644 --- a/tools/stats_log_api_gen/Collation.cpp +++ b/tools/stats_log_api_gen/Collation.cpp @@ -20,7 +20,7 @@ #include <map> -#include "frameworks/base/cmds/statsd/src/atoms.pb.h" +#include "frameworks/proto_logging/stats/atoms.pb.h" namespace android { namespace stats_log_api_gen { diff --git a/tools/stats_log_api_gen/Collation.h b/tools/stats_log_api_gen/Collation.h index 5d196c4b8290..b13851c07d04 100644 --- a/tools/stats_log_api_gen/Collation.h +++ b/tools/stats_log_api_gen/Collation.h @@ -24,7 +24,7 @@ #include <set> #include <vector> -#include "frameworks/base/cmds/statsd/src/atom_field_options.pb.h" +#include "frameworks/proto_logging/stats/atom_field_options.pb.h" namespace android { namespace stats_log_api_gen { diff --git a/tools/stats_log_api_gen/main.cpp b/tools/stats_log_api_gen/main.cpp index 28302493a8e1..50f81760e8ef 100644 --- a/tools/stats_log_api_gen/main.cpp +++ b/tools/stats_log_api_gen/main.cpp @@ -9,7 +9,7 @@ #include <vector> #include "Collation.h" -#include "frameworks/base/cmds/statsd/src/atoms.pb.h" +#include "frameworks/proto_logging/stats/atoms.pb.h" #include "java_writer.h" #include "java_writer_q.h" #include "native_writer.h" diff --git a/tools/stats_log_api_gen/test.proto b/tools/stats_log_api_gen/test.proto index e658b62b8daa..18c52bfab2a4 100644 --- a/tools/stats_log_api_gen/test.proto +++ b/tools/stats_log_api_gen/test.proto @@ -16,8 +16,8 @@ syntax = "proto2"; -import "frameworks/base/cmds/statsd/src/atoms.proto"; -import "frameworks/base/cmds/statsd/src/atom_field_options.proto"; +import "frameworks/proto_logging/stats/atoms.proto"; +import "frameworks/proto_logging/stats/atom_field_options.proto"; package android.stats_log_api_gen; diff --git a/wifi/java/android/net/wifi/SoftApConfiguration.java b/wifi/java/android/net/wifi/SoftApConfiguration.java index 9f9d7f3c3051..fddc8899a0c8 100644 --- a/wifi/java/android/net/wifi/SoftApConfiguration.java +++ b/wifi/java/android/net/wifi/SoftApConfiguration.java @@ -538,6 +538,15 @@ public final class SoftApConfiguration implements Parcelable { if (!SdkLevel.isAtLeastS()) { throw new UnsupportedOperationException(); } + return getChannelsInternal(); + } + + /** + * Internal version bypassing SdkLevel checks + * TODO(b/173791707): find a better way to allow Wifi to call its own new S APIs. + * @hide + */ + public @NonNull SparseIntArray getChannelsInternal() { return mChannels.clone(); } diff --git a/wifi/java/android/net/wifi/SoftApInfo.java b/wifi/java/android/net/wifi/SoftApInfo.java index 9a16facfec26..55c2f1759952 100644 --- a/wifi/java/android/net/wifi/SoftApInfo.java +++ b/wifi/java/android/net/wifi/SoftApInfo.java @@ -183,6 +183,15 @@ public final class SoftApInfo implements Parcelable { if (!SdkLevel.isAtLeastS()) { throw new UnsupportedOperationException(); } + return getWifiStandardInternal(); + } + + /** + * Internal version bypassing SdkLevel checks + * TODO(b/173791707): find a better way to allow Wifi to call its own new S APIs. + * @hide + */ + public @WifiAnnotations.WifiStandard int getWifiStandardInternal() { return mWifiStandard; } |