diff options
187 files changed, 2686 insertions, 1712 deletions
diff --git a/Android.bp b/Android.bp index 5070b5ea2403..e7a3efcf398f 100644 --- a/Android.bp +++ b/Android.bp @@ -916,28 +916,6 @@ python_binary_host { ], } -// TODO: Don't rely on this list by switching package.html into package-info.java -frameworks_base_subdirs = [ - "core/java", - "graphics/java", - "location/java", - "media/java", - "media/mca/effect/java", - "media/mca/filterfw/java", - "media/mca/filterpacks/java", - "drm/java", - "mms/java", - "opengl/java", - "sax/java", - "telecomm/java", - "telephony/common", - "telephony/java", - "wifi/java", - "lowpan/java", - "keystore/java", - "rs/java", -] - // Make the api/current.txt file available for use by modules in other // directories. filegroup { @@ -1042,7 +1020,6 @@ stubs_defaults { "test-runner/src/**/*.java", ], libs: framework_docs_only_libs, - local_sourcepaths: frameworks_base_subdirs, create_doc_stubs: true, annotations_enabled: true, api_levels_annotations_enabled: true, @@ -1103,7 +1080,6 @@ stubs_defaults { ":updatable-media-srcs", ], libs: ["framework-internal-utils"], - local_sourcepaths: frameworks_base_subdirs, installable: false, annotations_enabled: true, previous_api: ":last-released-public-api-for-metalava-annotations", diff --git a/apex/blobstore/framework/java/android/app/blob/BlobStoreManagerFrameworkInitializer.java b/apex/blobstore/framework/java/android/app/blob/BlobStoreManagerFrameworkInitializer.java index 6e6d6aee60fa..56c419ab0591 100644 --- a/apex/blobstore/framework/java/android/app/blob/BlobStoreManagerFrameworkInitializer.java +++ b/apex/blobstore/framework/java/android/app/blob/BlobStoreManagerFrameworkInitializer.java @@ -26,7 +26,7 @@ import android.content.Context; public class BlobStoreManagerFrameworkInitializer { /** Register the BlobStoreManager wrapper class */ public static void initialize() { - SystemServiceRegistry.registerCachedService( + SystemServiceRegistry.registerContextAwareService( Context.BLOB_STORE_SERVICE, BlobStoreManager.class, (context, service) -> new BlobStoreManager(context, IBlobStoreManager.Stub.asInterface(service))); diff --git a/apex/jobscheduler/framework/java/android/app/DeviceIdleFrameworkInitializer.java b/apex/jobscheduler/framework/java/android/app/DeviceIdleFrameworkInitializer.java deleted file mode 100644 index c264531c3947..000000000000 --- a/apex/jobscheduler/framework/java/android/app/DeviceIdleFrameworkInitializer.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.app; - -import android.content.Context; -import android.os.DeviceIdleManager; -import android.os.IDeviceIdleController; - -/** - * @hide - */ -public class DeviceIdleFrameworkInitializer { - private static IDeviceIdleController sIDeviceIdleController; - - public static void initialize() { - SystemServiceRegistry.registerCachedService( - Context.DEVICE_IDLE_CONTROLLER, DeviceIdleManager.class, - (context, b) -> new DeviceIdleManager( - context, IDeviceIdleController.Stub.asInterface(b))); - } -} diff --git a/apex/jobscheduler/framework/java/android/app/job/JobSchedulerFrameworkInitializer.java b/apex/jobscheduler/framework/java/android/app/job/JobSchedulerFrameworkInitializer.java index 175e5f23f761..f3ec5e5752a0 100644 --- a/apex/jobscheduler/framework/java/android/app/job/JobSchedulerFrameworkInitializer.java +++ b/apex/jobscheduler/framework/java/android/app/job/JobSchedulerFrameworkInitializer.java @@ -19,14 +19,34 @@ package android.app.job; import android.app.JobSchedulerImpl; import android.app.SystemServiceRegistry; import android.content.Context; +import android.os.DeviceIdleManager; +import android.os.IDeviceIdleController; /** + * Class holding initialization code for the job scheduler module. + * * @hide */ public class JobSchedulerFrameworkInitializer { - public static void initialize() { + private JobSchedulerFrameworkInitializer() { + } + + /** + * Called by {@link SystemServiceRegistry}'s static initializer and registers + * {@link JobScheduler} and other services to {@link Context}, so + * {@link Context#getSystemService} can return them. + * + * <p>If this is called from other places, it throws a {@link IllegalStateException). + * + * TODO Make it a system API + */ + public static void registerServiceWrappers() { SystemServiceRegistry.registerStaticService( Context.JOB_SCHEDULER_SERVICE, JobScheduler.class, (b) -> new JobSchedulerImpl(IJobScheduler.Stub.asInterface(b))); + SystemServiceRegistry.registerContextAwareService( + Context.DEVICE_IDLE_CONTROLLER, DeviceIdleManager.class, + (context, b) -> new DeviceIdleManager( + context, IDeviceIdleController.Stub.asInterface(b))); } } diff --git a/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java b/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java index 4ee46f453bca..dfe7a90ba246 100644 --- a/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java +++ b/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java @@ -1390,8 +1390,10 @@ public class DeviceIdleController extends SystemService private static final int MSG_FINISH_IDLE_OP = 8; private static final int MSG_REPORT_TEMP_APP_WHITELIST_CHANGED = 9; private static final int MSG_SEND_CONSTRAINT_MONITORING = 10; - private static final int MSG_UPDATE_PRE_IDLE_TIMEOUT_FACTOR = 11; - private static final int MSG_RESET_PRE_IDLE_TIMEOUT_FACTOR = 12; + @VisibleForTesting + static final int MSG_UPDATE_PRE_IDLE_TIMEOUT_FACTOR = 11; + @VisibleForTesting + static final int MSG_RESET_PRE_IDLE_TIMEOUT_FACTOR = 12; final class MyHandler extends Handler { MyHandler(Looper looper) { @@ -3327,8 +3329,7 @@ public class DeviceIdleController extends SystemService mHandler.sendEmptyMessage(MSG_RESET_PRE_IDLE_TIMEOUT_FACTOR); } - @VisibleForTesting - void updatePreIdleFactor() { + private void updatePreIdleFactor() { synchronized (this) { if (!shouldUseIdleTimeoutFactorLocked()) { return; @@ -3350,8 +3351,7 @@ public class DeviceIdleController extends SystemService } } - @VisibleForTesting - void maybeDoImmediateMaintenance() { + private void maybeDoImmediateMaintenance() { synchronized (this) { if (mState == STATE_IDLE) { long duration = SystemClock.elapsedRealtime() - mIdleStartTime; @@ -3377,6 +3377,7 @@ public class DeviceIdleController extends SystemService void setIdleStartTimeForTest(long idleStartTime) { synchronized (this) { mIdleStartTime = idleStartTime; + maybeDoImmediateMaintenance(); } } diff --git a/apex/statsd/service/java/com/android/server/stats/StatsCompanionService.java b/apex/statsd/service/java/com/android/server/stats/StatsCompanionService.java index a0615aac9a54..8a00c8318d58 100644 --- a/apex/statsd/service/java/com/android/server/stats/StatsCompanionService.java +++ b/apex/statsd/service/java/com/android/server/stats/StatsCompanionService.java @@ -1179,7 +1179,7 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { long token = Binder.clearCallingIdentity(); synchronized (this) { if (mTelephony == null) { - mTelephony = TelephonyManager.from(mContext); + mTelephony = mContext.getSystemService(TelephonyManager.class); } } if (mTelephony != null) { diff --git a/api/current.txt b/api/current.txt index 44a6229254c0..8b1df00f2f99 100644 --- a/api/current.txt +++ b/api/current.txt @@ -8445,6 +8445,7 @@ package android.bluetooth { method public int describeContents(); method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public boolean fetchUuidsWithSdp(); method public String getAddress(); + method @Nullable @RequiresPermission(android.Manifest.permission.BLUETOOTH) public String getAlias(); method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public android.bluetooth.BluetoothClass getBluetoothClass(); method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public int getBondState(); method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public String getName(); @@ -8456,6 +8457,7 @@ package android.bluetooth { field public static final String ACTION_ACL_CONNECTED = "android.bluetooth.device.action.ACL_CONNECTED"; field public static final String ACTION_ACL_DISCONNECTED = "android.bluetooth.device.action.ACL_DISCONNECTED"; field public static final String ACTION_ACL_DISCONNECT_REQUESTED = "android.bluetooth.device.action.ACL_DISCONNECT_REQUESTED"; + field public static final String ACTION_ALIAS_CHANGED = "android.bluetooth.action.ALIAS_CHANGED"; field public static final String ACTION_BOND_STATE_CHANGED = "android.bluetooth.device.action.BOND_STATE_CHANGED"; field public static final String ACTION_CLASS_CHANGED = "android.bluetooth.device.action.CLASS_CHANGED"; field public static final String ACTION_FOUND = "android.bluetooth.device.action.FOUND"; @@ -9475,6 +9477,7 @@ package android.content { method @Nullable public android.net.Uri canonicalize(@NonNull android.net.Uri); method @NonNull public final android.content.ContentProvider.CallingIdentity clearCallingIdentity(); method public abstract int delete(@NonNull android.net.Uri, @Nullable String, @Nullable String[]); + method public int delete(@NonNull android.net.Uri, @Nullable android.os.Bundle); method public void dump(java.io.FileDescriptor, java.io.PrintWriter, String[]); method @Nullable public final String getCallingFeatureId(); method @Nullable public final String getCallingPackage(); @@ -9485,6 +9488,7 @@ package android.content { method @Nullable public abstract String getType(@NonNull android.net.Uri); method @Nullable public final String getWritePermission(); method @Nullable public abstract android.net.Uri insert(@NonNull android.net.Uri, @Nullable android.content.ContentValues); + method @Nullable public android.net.Uri insert(@NonNull android.net.Uri, @Nullable android.content.ContentValues, @Nullable android.os.Bundle); method protected boolean isTemporary(); method public void onConfigurationChanged(android.content.res.Configuration); method public abstract boolean onCreate(); @@ -9510,6 +9514,7 @@ package android.content { method public void shutdown(); method @Nullable public android.net.Uri uncanonicalize(@NonNull android.net.Uri); method public abstract int update(@NonNull android.net.Uri, @Nullable android.content.ContentValues, @Nullable String, @Nullable String[]); + method public int update(@NonNull android.net.Uri, @Nullable android.content.ContentValues, @Nullable android.os.Bundle); } public final class ContentProvider.CallingIdentity { @@ -9528,10 +9533,12 @@ package android.content { method @Nullable public final android.net.Uri canonicalize(@NonNull android.net.Uri) throws android.os.RemoteException; method public void close(); method public int delete(@NonNull android.net.Uri, @Nullable String, @Nullable String[]) throws android.os.RemoteException; + method public int delete(@NonNull android.net.Uri, @Nullable android.os.Bundle) throws android.os.RemoteException; method @Nullable public android.content.ContentProvider getLocalContentProvider(); method @Nullable public String[] getStreamTypes(@NonNull android.net.Uri, @NonNull String) throws android.os.RemoteException; method @Nullable public String getType(@NonNull android.net.Uri) throws android.os.RemoteException; method @Nullable public android.net.Uri insert(@NonNull android.net.Uri, @Nullable android.content.ContentValues) throws android.os.RemoteException; + method @Nullable public android.net.Uri insert(@NonNull android.net.Uri, @Nullable android.content.ContentValues, @Nullable android.os.Bundle) throws android.os.RemoteException; method @Nullable public android.content.res.AssetFileDescriptor openAssetFile(@NonNull android.net.Uri, @NonNull String) throws java.io.FileNotFoundException, android.os.RemoteException; method @Nullable public android.content.res.AssetFileDescriptor openAssetFile(@NonNull android.net.Uri, @NonNull String, @Nullable android.os.CancellationSignal) throws java.io.FileNotFoundException, android.os.RemoteException; method @Nullable public android.os.ParcelFileDescriptor openFile(@NonNull android.net.Uri, @NonNull String) throws java.io.FileNotFoundException, android.os.RemoteException; @@ -9546,6 +9553,7 @@ package android.content { method @Deprecated public boolean release(); method @Nullable public final android.net.Uri uncanonicalize(@NonNull android.net.Uri) throws android.os.RemoteException; method public int update(@NonNull android.net.Uri, @Nullable android.content.ContentValues, @Nullable String, @Nullable String[]) throws android.os.RemoteException; + method public int update(@NonNull android.net.Uri, @Nullable android.content.ContentValues, @Nullable android.os.Bundle) throws android.os.RemoteException; } public class ContentProviderOperation implements android.os.Parcelable { @@ -9633,6 +9641,7 @@ package android.content { method public static void cancelSync(android.content.SyncRequest); method @Nullable public final android.net.Uri canonicalize(@NonNull android.net.Uri); method public final int delete(@NonNull @RequiresPermission.Write android.net.Uri, @Nullable String, @Nullable String[]); + method public final int delete(@NonNull @RequiresPermission.Write android.net.Uri, @Nullable android.os.Bundle); method @Deprecated public static android.content.SyncInfo getCurrentSync(); method public static java.util.List<android.content.SyncInfo> getCurrentSyncs(); method public static int getIsSyncable(android.accounts.Account, String); @@ -9646,6 +9655,7 @@ package android.content { method @Nullable public final String getType(@NonNull android.net.Uri); method @NonNull public final android.content.ContentResolver.MimeTypeInfo getTypeInfo(@NonNull String); method @Nullable public final android.net.Uri insert(@NonNull @RequiresPermission.Write android.net.Uri, @Nullable android.content.ContentValues); + method @Nullable public final android.net.Uri insert(@NonNull @RequiresPermission.Write android.net.Uri, @Nullable android.content.ContentValues, @Nullable android.os.Bundle); method public static boolean isSyncActive(android.accounts.Account, String); method public static boolean isSyncPending(android.accounts.Account, String); method @NonNull public android.graphics.Bitmap loadThumbnail(@NonNull android.net.Uri, @NonNull android.util.Size, @Nullable android.os.CancellationSignal) throws java.io.IOException; @@ -9683,6 +9693,7 @@ package android.content { method @Nullable public final android.net.Uri uncanonicalize(@NonNull android.net.Uri); method public final void unregisterContentObserver(@NonNull android.database.ContentObserver); method public final int update(@NonNull @RequiresPermission.Write android.net.Uri, @Nullable android.content.ContentValues, @Nullable String, @Nullable String[]); + method public final int update(@NonNull @RequiresPermission.Write android.net.Uri, @Nullable android.content.ContentValues, @Nullable android.os.Bundle); method public static void validateSyncExtrasBundle(android.os.Bundle); method @NonNull public static android.content.ContentResolver wrap(@NonNull android.content.ContentProvider); method @NonNull public static android.content.ContentResolver wrap(@NonNull android.content.ContentProviderClient); @@ -9695,12 +9706,16 @@ package android.content { field public static final String EXTRA_TOTAL_COUNT = "android.content.extra.TOTAL_COUNT"; field public static final int NOTIFY_SKIP_NOTIFY_FOR_DESCENDANTS = 2; // 0x2 field public static final int NOTIFY_SYNC_TO_NETWORK = 1; // 0x1 + field public static final String QUERY_ARG_GROUP_COLUMNS = "android:query-arg-group-columns"; field public static final String QUERY_ARG_LIMIT = "android:query-arg-limit"; field public static final String QUERY_ARG_OFFSET = "android:query-arg-offset"; field public static final String QUERY_ARG_SORT_COLLATION = "android:query-arg-sort-collation"; field public static final String QUERY_ARG_SORT_COLUMNS = "android:query-arg-sort-columns"; field public static final String QUERY_ARG_SORT_DIRECTION = "android:query-arg-sort-direction"; field public static final String QUERY_ARG_SORT_LOCALE = "android:query-arg-sort-locale"; + field public static final String QUERY_ARG_SQL_GROUP_BY = "android:query-arg-sql-group-by"; + field public static final String QUERY_ARG_SQL_HAVING = "android:query-arg-sql-having"; + field public static final String QUERY_ARG_SQL_LIMIT = "android:query-arg-sql-limit"; field public static final String QUERY_ARG_SQL_SELECTION = "android:query-arg-sql-selection"; field public static final String QUERY_ARG_SQL_SELECTION_ARGS = "android:query-arg-sql-selection-args"; field public static final String QUERY_ARG_SQL_SORT_ORDER = "android:query-arg-sql-sort-order"; @@ -30511,6 +30526,9 @@ package android.net.wifi.p2p { field public static final int GROUP_OWNER_BAND_2GHZ = 1; // 0x1 field public static final int GROUP_OWNER_BAND_5GHZ = 2; // 0x2 field public static final int GROUP_OWNER_BAND_AUTO = 0; // 0x0 + field public static final int GROUP_OWNER_INTENT_AUTO = -1; // 0xffffffff + field public static final int GROUP_OWNER_INTENT_MAX = 15; // 0xf + field public static final int GROUP_OWNER_INTENT_MIN = 0; // 0x0 field public String deviceAddress; field public int groupOwnerIntent; field public android.net.wifi.WpsInfo wps; @@ -30531,6 +30549,7 @@ package android.net.wifi.p2p { ctor public WifiP2pDevice(); ctor public WifiP2pDevice(android.net.wifi.p2p.WifiP2pDevice); method public int describeContents(); + method @Nullable public android.net.wifi.p2p.WifiP2pWfdInfo getWfdInfo(); method public boolean isGroupOwner(); method public boolean isServiceDiscoveryCapable(); method public boolean wpsDisplaySupported(); @@ -30567,6 +30586,7 @@ package android.net.wifi.p2p { method public java.util.Collection<android.net.wifi.p2p.WifiP2pDevice> getClientList(); method public int getFrequency(); method public String getInterface(); + method public int getNetworkId(); method public String getNetworkName(); method public android.net.wifi.p2p.WifiP2pDevice getOwner(); method public String getPassphrase(); @@ -30691,6 +30711,28 @@ package android.net.wifi.p2p { method public void onUpnpServiceAvailable(java.util.List<java.lang.String>, android.net.wifi.p2p.WifiP2pDevice); } + public final class WifiP2pWfdInfo implements android.os.Parcelable { + ctor public WifiP2pWfdInfo(); + ctor public WifiP2pWfdInfo(@Nullable android.net.wifi.p2p.WifiP2pWfdInfo); + method public int describeContents(); + method public int getControlPort(); + method public int getDeviceType(); + method public int getMaxThroughput(); + method public boolean isSessionAvailable(); + method public boolean isWfdEnabled(); + method public void setControlPort(int); + method public boolean setDeviceType(int); + method public void setMaxThroughput(int); + method public void setSessionAvailable(boolean); + method public void setWfdEnabled(boolean); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.p2p.WifiP2pWfdInfo> CREATOR; + field public static final int DEVICE_TYPE_PRIMARY_SINK = 1; // 0x1 + field public static final int DEVICE_TYPE_SECONDARY_SINK = 2; // 0x2 + field public static final int DEVICE_TYPE_SOURCE_OR_PRIMARY_SINK = 3; // 0x3 + field public static final int DEVICE_TYPE_WFD_SOURCE = 0; // 0x0 + } + } package android.net.wifi.p2p.nsd { @@ -39009,10 +39051,14 @@ package android.provider { field public static final String ACTION_VPN_SETTINGS = "android.settings.VPN_SETTINGS"; field public static final String ACTION_VR_LISTENER_SETTINGS = "android.settings.VR_LISTENER_SETTINGS"; field public static final String ACTION_WEBVIEW_SETTINGS = "android.settings.WEBVIEW_SETTINGS"; + field public static final String ACTION_WIFI_ADD_NETWORKS = "android.settings.WIFI_ADD_NETWORKS"; field public static final String ACTION_WIFI_IP_SETTINGS = "android.settings.WIFI_IP_SETTINGS"; field public static final String ACTION_WIFI_SETTINGS = "android.settings.WIFI_SETTINGS"; field public static final String ACTION_WIRELESS_SETTINGS = "android.settings.WIRELESS_SETTINGS"; field public static final String ACTION_ZEN_MODE_PRIORITY_SETTINGS = "android.settings.ZEN_MODE_PRIORITY_SETTINGS"; + field public static final int ADD_WIFI_RESULT_ADD_OR_UPDATE_FAILED = 1; // 0x1 + field public static final int ADD_WIFI_RESULT_ALREADY_EXISTS = 2; // 0x2 + field public static final int ADD_WIFI_RESULT_SUCCESS = 0; // 0x0 field public static final String AUTHORITY = "settings"; field public static final String EXTRA_ACCOUNT_TYPES = "account_types"; field public static final String EXTRA_AIRPLANE_MODE_ENABLED = "airplane_mode_enabled"; @@ -39025,6 +39071,8 @@ package android.provider { field public static final String EXTRA_INPUT_METHOD_ID = "input_method_id"; field public static final String EXTRA_NOTIFICATION_LISTENER_COMPONENT_NAME = "android.provider.extra.NOTIFICATION_LISTENER_COMPONENT_NAME"; field public static final String EXTRA_SUB_ID = "android.provider.extra.SUB_ID"; + field public static final String EXTRA_WIFI_CONFIGURATION_LIST = "android.provider.extra.WIFI_CONFIGURATION_LIST"; + field public static final String EXTRA_WIFI_CONFIGURATION_RESULT_LIST = "android.provider.extra.WIFI_CONFIGURATION_RESULT_LIST"; field public static final String INTENT_CATEGORY_USAGE_ACCESS_CONFIG = "android.intent.category.USAGE_ACCESS_CONFIG"; field public static final String METADATA_USAGE_ACCESS_REASON = "android.settings.metadata.USAGE_ACCESS_REASON"; } diff --git a/api/system-current.txt b/api/system-current.txt index 427c150541e7..fd6afea8a91b 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -57,6 +57,7 @@ package android { field public static final String CHANGE_DEVICE_IDLE_TEMP_WHITELIST = "android.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST"; field public static final String CLEAR_APP_USER_DATA = "android.permission.CLEAR_APP_USER_DATA"; field public static final String CONFIGURE_DISPLAY_BRIGHTNESS = "android.permission.CONFIGURE_DISPLAY_BRIGHTNESS"; + field public static final String CONFIGURE_WIFI_DISPLAY = "android.permission.CONFIGURE_WIFI_DISPLAY"; field public static final String CONNECTIVITY_INTERNAL = "android.permission.CONNECTIVITY_INTERNAL"; field public static final String CONNECTIVITY_USE_RESTRICTED_NETWORKS = "android.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS"; field public static final String CONTROL_DISPLAY_COLOR_TRANSFORMS = "android.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS"; @@ -125,8 +126,10 @@ package android { field public static final String NETWORK_CARRIER_PROVISIONING = "android.permission.NETWORK_CARRIER_PROVISIONING"; field public static final String NETWORK_MANAGED_PROVISIONING = "android.permission.NETWORK_MANAGED_PROVISIONING"; field public static final String NETWORK_SCAN = "android.permission.NETWORK_SCAN"; + field public static final String NETWORK_SETTINGS = "android.permission.NETWORK_SETTINGS"; field public static final String NETWORK_SETUP_WIZARD = "android.permission.NETWORK_SETUP_WIZARD"; field public static final String NETWORK_SIGNAL_STRENGTH_WAKEUP = "android.permission.NETWORK_SIGNAL_STRENGTH_WAKEUP"; + field public static final String NETWORK_STACK = "android.permission.NETWORK_STACK"; field public static final String NOTIFICATION_DURING_SETUP = "android.permission.NOTIFICATION_DURING_SETUP"; field public static final String NOTIFY_TV_INPUTS = "android.permission.NOTIFY_TV_INPUTS"; field public static final String OBSERVE_APP_USAGE = "android.permission.OBSERVE_APP_USAGE"; @@ -1306,6 +1309,7 @@ package android.bluetooth { method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public boolean isEncrypted(); method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean isInSilenceMode(); method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean removeBond(); + method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public boolean setAlias(@NonNull String); method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setMetadata(int, @NonNull byte[]); method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setPhonebookAccessPermission(int); method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setSilenceMode(boolean); @@ -2000,6 +2004,7 @@ package android.hardware.display { method @Nullable public android.hardware.display.BrightnessCorrection getCorrectionByCategory(int); method @Nullable public android.hardware.display.BrightnessCorrection getCorrectionByPackageName(@NonNull String); method public android.util.Pair<float[],float[]> getCurve(); + method public boolean shouldCollectColorSamples(); method public void writeToParcel(android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.hardware.display.BrightnessConfiguration> CREATOR; } @@ -2012,6 +2017,7 @@ package android.hardware.display { method public int getMaxCorrectionsByCategory(); method public int getMaxCorrectionsByPackageName(); method @NonNull public android.hardware.display.BrightnessConfiguration.Builder setDescription(@Nullable String); + method @NonNull public android.hardware.display.BrightnessConfiguration.Builder setShouldCollectColorSamples(boolean); } public final class BrightnessCorrection implements android.os.Parcelable { @@ -4120,8 +4126,8 @@ package android.net { method @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void getLatestTetheringEntitlementResult(int, boolean, @NonNull java.util.concurrent.Executor, @NonNull android.net.ConnectivityManager.OnTetheringEntitlementResultListener); method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS}) public boolean isTetheringSupported(); method @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void registerTetheringEventCallback(@NonNull java.util.concurrent.Executor, @NonNull android.net.ConnectivityManager.OnTetheringEventCallback); - method @RequiresPermission(anyOf={"android.permission.NETWORK_SETTINGS", android.Manifest.permission.NETWORK_SETUP_WIZARD, "android.permission.NETWORK_STACK"}) public void setAirplaneMode(boolean); - method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, "android.permission.NETWORK_STACK"}) public boolean shouldAvoidBadWifi(); + method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_STACK}) public void setAirplaneMode(boolean); + method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK}) public boolean shouldAvoidBadWifi(); method @RequiresPermission(android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK) public void startCaptivePortalApp(@NonNull android.net.Network, @NonNull android.os.Bundle); method @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void startTethering(int, boolean, android.net.ConnectivityManager.OnStartTetheringCallback); method @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void startTethering(int, boolean, android.net.ConnectivityManager.OnStartTetheringCallback, android.os.Handler); @@ -4829,14 +4835,14 @@ package android.net.wifi { public class WifiManager { method @RequiresPermission("android.permission.WIFI_UPDATE_USABILITY_STATS_SCORE") public void addOnWifiUsabilityStatsListener(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.OnWifiUsabilityStatsListener); - method @RequiresPermission("android.permission.NETWORK_SETTINGS") public void allowAutojoin(int, boolean); - method @RequiresPermission(anyOf={"android.permission.NETWORK_SETTINGS", android.Manifest.permission.NETWORK_SETUP_WIZARD, "android.permission.NETWORK_STACK"}) public void connect(@NonNull android.net.wifi.WifiConfiguration, @Nullable android.net.wifi.WifiManager.ActionListener); - method @RequiresPermission(anyOf={"android.permission.NETWORK_SETTINGS", android.Manifest.permission.NETWORK_SETUP_WIZARD, "android.permission.NETWORK_STACK"}) public void connect(int, @Nullable android.net.wifi.WifiManager.ActionListener); - method @Deprecated @RequiresPermission(anyOf={"android.permission.NETWORK_SETTINGS", android.Manifest.permission.NETWORK_SETUP_WIZARD, "android.permission.NETWORK_STACK"}) public void disable(int, @Nullable android.net.wifi.WifiManager.ActionListener); - method @RequiresPermission(anyOf={"android.permission.NETWORK_SETTINGS", android.Manifest.permission.NETWORK_SETUP_WIZARD, "android.permission.NETWORK_STACK"}) public void forget(int, @Nullable android.net.wifi.WifiManager.ActionListener); - method @NonNull @RequiresPermission(anyOf={"android.permission.NETWORK_SETTINGS", android.Manifest.permission.NETWORK_SETUP_WIZARD}) public java.util.List<android.util.Pair<android.net.wifi.WifiConfiguration,java.util.Map<java.lang.Integer,java.util.List<android.net.wifi.ScanResult>>>> getAllMatchingWifiConfigs(@NonNull java.util.List<android.net.wifi.ScanResult>); - method @NonNull @RequiresPermission(anyOf={"android.permission.NETWORK_SETTINGS", android.Manifest.permission.NETWORK_SETUP_WIZARD}) public java.util.Map<android.net.wifi.hotspot2.OsuProvider,java.util.List<android.net.wifi.ScanResult>> getMatchingOsuProviders(@Nullable java.util.List<android.net.wifi.ScanResult>); - method @NonNull @RequiresPermission(anyOf={"android.permission.NETWORK_SETTINGS", android.Manifest.permission.NETWORK_SETUP_WIZARD}) public java.util.Map<android.net.wifi.hotspot2.OsuProvider,android.net.wifi.hotspot2.PasspointConfiguration> getMatchingPasspointConfigsForOsuProviders(@NonNull java.util.Set<android.net.wifi.hotspot2.OsuProvider>); + method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void allowAutojoin(int, boolean); + method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_STACK}) public void connect(@NonNull android.net.wifi.WifiConfiguration, @Nullable android.net.wifi.WifiManager.ActionListener); + method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_STACK}) public void connect(int, @Nullable android.net.wifi.WifiManager.ActionListener); + method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_STACK}) public void disable(int, @Nullable android.net.wifi.WifiManager.ActionListener); + method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_STACK}) public void forget(int, @Nullable android.net.wifi.WifiManager.ActionListener); + method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public java.util.List<android.util.Pair<android.net.wifi.WifiConfiguration,java.util.Map<java.lang.Integer,java.util.List<android.net.wifi.ScanResult>>>> getAllMatchingWifiConfigs(@NonNull java.util.List<android.net.wifi.ScanResult>); + method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public java.util.Map<android.net.wifi.hotspot2.OsuProvider,java.util.List<android.net.wifi.ScanResult>> getMatchingOsuProviders(@Nullable java.util.List<android.net.wifi.ScanResult>); + method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public java.util.Map<android.net.wifi.hotspot2.OsuProvider,android.net.wifi.hotspot2.PasspointConfiguration> getMatchingPasspointConfigsForOsuProviders(@NonNull java.util.Set<android.net.wifi.hotspot2.OsuProvider>); method @RequiresPermission(allOf={android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.ACCESS_WIFI_STATE, android.Manifest.permission.READ_WIFI_CREDENTIAL}) public java.util.List<android.net.wifi.WifiConfiguration> getPrivilegedConfiguredNetworks(); method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public android.net.wifi.WifiConfiguration getWifiApConfiguration(); method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public int getWifiApState(); @@ -4846,20 +4852,20 @@ package android.net.wifi { method public boolean isPortableHotspotSupported(); method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public boolean isWifiApEnabled(); method public boolean isWifiScannerSupported(); - method @RequiresPermission("android.permission.NETWORK_SETTINGS") public void registerSoftApCallback(@Nullable java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.SoftApCallback); + method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void registerSoftApCallback(@Nullable java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.SoftApCallback); method @RequiresPermission("android.permission.WIFI_UPDATE_USABILITY_STATS_SCORE") public void removeOnWifiUsabilityStatsListener(@NonNull android.net.wifi.WifiManager.OnWifiUsabilityStatsListener); - method @RequiresPermission(anyOf={"android.permission.NETWORK_SETTINGS", android.Manifest.permission.NETWORK_SETUP_WIZARD, "android.permission.NETWORK_STACK"}) public void save(@NonNull android.net.wifi.WifiConfiguration, @Nullable android.net.wifi.WifiManager.ActionListener); + method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_STACK}) public void save(@NonNull android.net.wifi.WifiConfiguration, @Nullable android.net.wifi.WifiManager.ActionListener); method @RequiresPermission("android.permission.WIFI_SET_DEVICE_MOBILITY_STATE") public void setDeviceMobilityState(int); method @RequiresPermission(android.Manifest.permission.CHANGE_WIFI_STATE) public boolean setWifiApConfiguration(android.net.wifi.WifiConfiguration); - method @RequiresPermission(anyOf={"android.permission.NETWORK_SETTINGS", android.Manifest.permission.NETWORK_SETUP_WIZARD}) public void startEasyConnectAsConfiguratorInitiator(@NonNull String, int, int, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.EasyConnectStatusCallback); - method @RequiresPermission(anyOf={"android.permission.NETWORK_SETTINGS", android.Manifest.permission.NETWORK_SETUP_WIZARD}) public void startEasyConnectAsEnrolleeInitiator(@NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.EasyConnectStatusCallback); - method @RequiresPermission(anyOf={"android.permission.NETWORK_SETTINGS", android.Manifest.permission.NETWORK_SETUP_WIZARD}) public void startLocalOnlyHotspot(@NonNull android.net.wifi.SoftApConfiguration, @Nullable java.util.concurrent.Executor, @Nullable android.net.wifi.WifiManager.LocalOnlyHotspotCallback); + method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public void startEasyConnectAsConfiguratorInitiator(@NonNull String, int, int, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.EasyConnectStatusCallback); + method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public void startEasyConnectAsEnrolleeInitiator(@NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.EasyConnectStatusCallback); + method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public void startLocalOnlyHotspot(@NonNull android.net.wifi.SoftApConfiguration, @Nullable java.util.concurrent.Executor, @Nullable android.net.wifi.WifiManager.LocalOnlyHotspotCallback); method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public boolean startScan(android.os.WorkSource); - method @RequiresPermission(anyOf={"android.permission.NETWORK_STACK", android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public boolean startSoftAp(@Nullable android.net.wifi.WifiConfiguration); - method @RequiresPermission(anyOf={"android.permission.NETWORK_SETTINGS", android.Manifest.permission.NETWORK_SETUP_WIZARD}) public void startSubscriptionProvisioning(@NonNull android.net.wifi.hotspot2.OsuProvider, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.hotspot2.ProvisioningCallback); - method @RequiresPermission(anyOf={"android.permission.NETWORK_SETTINGS", android.Manifest.permission.NETWORK_SETUP_WIZARD}) public void stopEasyConnectSession(); - method @RequiresPermission(anyOf={"android.permission.NETWORK_STACK", android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public boolean stopSoftAp(); - method @RequiresPermission(anyOf={"android.permission.NETWORK_STACK", android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void updateInterfaceIpState(@Nullable String, int); + method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public boolean startSoftAp(@Nullable android.net.wifi.WifiConfiguration); + method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public void startSubscriptionProvisioning(@NonNull android.net.wifi.hotspot2.OsuProvider, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.hotspot2.ProvisioningCallback); + method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public void stopEasyConnectSession(); + method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public boolean stopSoftAp(); + method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void updateInterfaceIpState(@Nullable String, int); method @RequiresPermission("android.permission.WIFI_UPDATE_USABILITY_STATS_SCORE") public void updateWifiUsabilityScore(int, int, int); field public static final int CHANGE_REASON_ADDED = 0; // 0x0 field public static final int CHANGE_REASON_CONFIG_CHANGE = 2; // 0x2 @@ -5151,6 +5157,36 @@ package android.net.wifi.hotspot2 { } +package android.net.wifi.p2p { + + public final class WifiP2pGroupList implements android.os.Parcelable { + method public int describeContents(); + method @NonNull public java.util.Collection<android.net.wifi.p2p.WifiP2pGroup> getGroupList(); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.p2p.WifiP2pGroupList> CREATOR; + } + + public class WifiP2pManager { + method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.OVERRIDE_WIFI_CONFIG}) public void deletePersistentGroup(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, int, @Nullable android.net.wifi.p2p.WifiP2pManager.ActionListener); + method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void factoryReset(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, @Nullable android.net.wifi.p2p.WifiP2pManager.ActionListener); + method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void listen(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, boolean, @Nullable android.net.wifi.p2p.WifiP2pManager.ActionListener); + method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.READ_WIFI_CREDENTIAL}) public void requestPersistentGroupInfo(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, @Nullable android.net.wifi.p2p.WifiP2pManager.PersistentGroupInfoListener); + method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.OVERRIDE_WIFI_CONFIG}) public void setDeviceName(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, @NonNull String, @Nullable android.net.wifi.p2p.WifiP2pManager.ActionListener); + method @RequiresPermission(allOf={android.Manifest.permission.CONNECTIVITY_INTERNAL, android.Manifest.permission.CONFIGURE_WIFI_DISPLAY}) public void setMiracastMode(int); + method @RequiresPermission(android.Manifest.permission.CONFIGURE_WIFI_DISPLAY) public void setWfdInfo(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, @NonNull android.net.wifi.p2p.WifiP2pWfdInfo, @Nullable android.net.wifi.p2p.WifiP2pManager.ActionListener); + method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.OVERRIDE_WIFI_CONFIG}) public void setWifiP2pChannels(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, int, int, @Nullable android.net.wifi.p2p.WifiP2pManager.ActionListener); + field public static final String ACTION_WIFI_P2P_PERSISTENT_GROUPS_CHANGED = "android.net.wifi.p2p.action.WIFI_P2P_PERSISTENT_GROUPS_CHANGED"; + field public static final int MIRACAST_DISABLED = 0; // 0x0 + field public static final int MIRACAST_SINK = 2; // 0x2 + field public static final int MIRACAST_SOURCE = 1; // 0x1 + } + + public static interface WifiP2pManager.PersistentGroupInfoListener { + method public void onPersistentGroupInfoAvailable(@NonNull android.net.wifi.p2p.WifiP2pGroupList); + } + +} + package android.net.wifi.rtt { public static final class RangingRequest.Builder { diff --git a/api/system-lint-baseline.txt b/api/system-lint-baseline.txt index 21526d007dc5..6c659c880b34 100644 --- a/api/system-lint-baseline.txt +++ b/api/system-lint-baseline.txt @@ -7,6 +7,22 @@ ArrayReturn: android.view.contentcapture.ViewNode#getAutofillOptions(): +ExecutorRegistration: android.net.wifi.p2p.WifiP2pManager#deletePersistentGroup(android.net.wifi.p2p.WifiP2pManager.Channel, int, android.net.wifi.p2p.WifiP2pManager.ActionListener): + Registration methods should have overload that accepts delivery Executor: `deletePersistentGroup` +ExecutorRegistration: android.net.wifi.p2p.WifiP2pManager#factoryReset(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pManager.ActionListener): + Registration methods should have overload that accepts delivery Executor: `factoryReset` +ExecutorRegistration: android.net.wifi.p2p.WifiP2pManager#listen(android.net.wifi.p2p.WifiP2pManager.Channel, boolean, android.net.wifi.p2p.WifiP2pManager.ActionListener): + Registration methods should have overload that accepts delivery Executor: `listen` +ExecutorRegistration: android.net.wifi.p2p.WifiP2pManager#requestPersistentGroupInfo(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pManager.PersistentGroupInfoListener): + Registration methods should have overload that accepts delivery Executor: `requestPersistentGroupInfo` +ExecutorRegistration: android.net.wifi.p2p.WifiP2pManager#setDeviceName(android.net.wifi.p2p.WifiP2pManager.Channel, String, android.net.wifi.p2p.WifiP2pManager.ActionListener): + Registration methods should have overload that accepts delivery Executor: `setDeviceName` +ExecutorRegistration: android.net.wifi.p2p.WifiP2pManager#setWfdInfo(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pWfdInfo, android.net.wifi.p2p.WifiP2pManager.ActionListener): + Registration methods should have overload that accepts delivery Executor: `setWfdInfo` +ExecutorRegistration: android.net.wifi.p2p.WifiP2pManager#setWifiP2pChannels(android.net.wifi.p2p.WifiP2pManager.Channel, int, int, android.net.wifi.p2p.WifiP2pManager.ActionListener): + Registration methods should have overload that accepts delivery Executor: `setWifiP2pChannels` + + GenericException: android.app.prediction.AppPredictor#finalize(): GenericException: android.hardware.location.ContextHubClient#finalize(): @@ -17,8 +33,7 @@ GenericException: android.service.autofill.augmented.FillWindow#finalize(): -InterfaceConstant: android.service.storage.ExternalStorageService#SERVICE_INTERFACE: - + KotlinKeyword: android.app.Notification#when: @@ -198,9 +213,9 @@ SamShouldBeLast: android.app.AlarmManager#setExact(int, long, String, android.ap SamShouldBeLast: android.app.AlarmManager#setWindow(int, long, long, String, android.app.AlarmManager.OnAlarmListener, android.os.Handler): SamShouldBeLast: android.app.WallpaperInfo#dump(android.util.Printer, String): - + SamShouldBeLast: android.app.admin.DevicePolicyManager#installSystemUpdate(android.content.ComponentName, android.net.Uri, java.util.concurrent.Executor, android.app.admin.DevicePolicyManager.InstallSystemUpdateCallback): - + SamShouldBeLast: android.content.Context#bindIsolatedService(android.content.Intent, int, String, java.util.concurrent.Executor, android.content.ServiceConnection): SamShouldBeLast: android.content.Context#bindService(android.content.Intent, int, java.util.concurrent.Executor, android.content.ServiceConnection): diff --git a/api/test-current.txt b/api/test-current.txt index 44f736ca918a..c6b02b9e649b 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -1018,6 +1018,7 @@ package android.hardware.display { method @Nullable public android.hardware.display.BrightnessCorrection getCorrectionByCategory(int); method @Nullable public android.hardware.display.BrightnessCorrection getCorrectionByPackageName(@NonNull String); method public android.util.Pair<float[],float[]> getCurve(); + method public boolean shouldCollectColorSamples(); method public void writeToParcel(android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.hardware.display.BrightnessConfiguration> CREATOR; } @@ -1030,6 +1031,7 @@ package android.hardware.display { method public int getMaxCorrectionsByCategory(); method public int getMaxCorrectionsByPackageName(); method @NonNull public android.hardware.display.BrightnessConfiguration.Builder setDescription(@Nullable String); + method @NonNull public android.hardware.display.BrightnessConfiguration.Builder setShouldCollectColorSamples(boolean); } public final class BrightnessCorrection implements android.os.Parcelable { diff --git a/cmds/content/src/com/android/commands/content/Content.java b/cmds/content/src/com/android/commands/content/Content.java index 7e278e964ab5..59544a971e5f 100644 --- a/cmds/content/src/com/android/commands/content/Content.java +++ b/cmds/content/src/com/android/commands/content/Content.java @@ -508,7 +508,7 @@ public class Content { @Override public void onExecute(IContentProvider provider) throws Exception { - provider.insert(resolveCallingPackage(), null, mUri, mContentValues); + provider.insert(resolveCallingPackage(), null, mUri, mContentValues, null); } } @@ -522,7 +522,8 @@ public class Content { @Override public void onExecute(IContentProvider provider) throws Exception { - provider.delete(resolveCallingPackage(), null, mUri, mWhere, null); + provider.delete(resolveCallingPackage(), null, mUri, + ContentResolver.createSqlQueryBundle(mWhere, null)); } } @@ -679,7 +680,8 @@ public class Content { @Override public void onExecute(IContentProvider provider) throws Exception { - provider.update(resolveCallingPackage(), null, mUri, mContentValues, mWhere, null); + provider.update(resolveCallingPackage(), null, mUri, mContentValues, + ContentResolver.createSqlQueryBundle(mWhere, null)); } } diff --git a/core/java/android/app/IWallpaperManager.aidl b/core/java/android/app/IWallpaperManager.aidl index 7f5350ddd4e0..4cb8d936aa9c 100644 --- a/core/java/android/app/IWallpaperManager.aidl +++ b/core/java/android/app/IWallpaperManager.aidl @@ -58,14 +58,22 @@ interface IWallpaperManager { @UnsupportedAppUsage void setWallpaperComponent(in ComponentName name); + /** - * Get the wallpaper for a given user. + * @deprecated Use {@link #getWallpaperWithFeature(String, IWallpaperManagerCallback, int, + * Bundle, int)} */ @UnsupportedAppUsage ParcelFileDescriptor getWallpaper(String callingPkg, IWallpaperManagerCallback cb, int which, out Bundle outParams, int userId); /** + * Get the wallpaper for a given user. + */ + ParcelFileDescriptor getWallpaperWithFeature(String callingPkg, String callingFeatureId, + IWallpaperManagerCallback cb, int which, out Bundle outParams, int userId); + + /** * Retrieve the given user's current wallpaper ID of the given kind. */ int getWallpaperIdForUser(int which, int userId); diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java index 4fb2196d4e26..33ea32b7e31e 100644 --- a/core/java/android/app/SystemServiceRegistry.java +++ b/core/java/android/app/SystemServiceRegistry.java @@ -18,6 +18,7 @@ package android.app; import android.accounts.AccountManager; import android.accounts.IAccountManager; +import android.annotation.NonNull; import android.app.ContextImpl.ServiceInitializationState; import android.app.admin.DevicePolicyManager; import android.app.admin.IDevicePolicyManager; @@ -194,10 +195,9 @@ import com.android.internal.appwidget.IAppWidgetService; import com.android.internal.net.INetworkWatchlistManager; import com.android.internal.os.IDropBoxManagerService; import com.android.internal.policy.PhoneLayoutInflater; +import com.android.internal.util.Preconditions; import java.util.Map; -import java.util.function.BiFunction; -import java.util.function.Function; /** * Manages all of the system services that can be returned by {@link Context#getSystemService}. @@ -216,6 +216,8 @@ public final class SystemServiceRegistry { new ArrayMap<String, ServiceFetcher<?>>(); private static int sServiceCacheSize; + private static volatile boolean sInitializing; + // Not instantiable. private SystemServiceRegistry() { } @@ -1292,14 +1294,28 @@ public final class SystemServiceRegistry { }}); //CHECKSTYLE:ON IndentationCheck - JobSchedulerFrameworkInitializer.initialize(); - DeviceIdleFrameworkInitializer.initialize(); - - BlobStoreManagerFrameworkInitializer.initialize(); + sInitializing = true; + try { + // Note: the following functions need to be @SystemApis, once they become mainline + // modules. + + JobSchedulerFrameworkInitializer.registerServiceWrappers(); + BlobStoreManagerFrameworkInitializer.initialize(); + } finally { + // If any of the above code throws, we're in a pretty bad shape and the process + // will likely crash, but we'll reset it just in case there's an exception handler... + sInitializing = false; + } } + /** Throws {@link IllegalStateException} if not during a static initialization. */ + private static void ensureInitializing(String methodName) { + Preconditions.checkState(sInitializing, "Internal error: " + methodName + + " can only be called during class initialization."); + } /** * Creates an array which is used to cache per-Context service instances. + * @hide */ public static Object[] createServiceCache() { return new Object[sServiceCacheSize]; @@ -1307,6 +1323,7 @@ public final class SystemServiceRegistry { /** * Gets a system service from a given context. + * @hide */ public static Object getSystemService(ContextImpl ctx, String name) { ServiceFetcher<?> fetcher = SYSTEM_SERVICE_FETCHERS.get(name); @@ -1315,6 +1332,7 @@ public final class SystemServiceRegistry { /** * Gets the name of the system-level service that is represented by the specified class. + * @hide */ public static String getSystemServiceName(Class<?> serviceClass) { return SYSTEM_SERVICE_NAMES.get(serviceClass); @@ -1324,41 +1342,204 @@ public final class SystemServiceRegistry { * Statically registers a system service with the context. * This method must be called during static initialization only. */ - private static <T> void registerService(String serviceName, Class<T> serviceClass, - ServiceFetcher<T> serviceFetcher) { + private static <T> void registerService(@NonNull String serviceName, + @NonNull Class<T> serviceClass, @NonNull ServiceFetcher<T> serviceFetcher) { SYSTEM_SERVICE_NAMES.put(serviceClass, serviceName); SYSTEM_SERVICE_FETCHERS.put(serviceName, serviceFetcher); } /** - * APEX modules will use it to register their service wrapper. + * Callback interface used as a parameter to {@link #registerStaticService( + * String, Class, StaticServiceProducerNoBinder)}, which generates a service wrapper instance + * that's not tied to any context and does not take a service binder object in the constructor. + * + * @param <TServiceClass> type of the service wrapper class. + * + * @hide + */ + //@SystemApi TODO Make it a system API. + public interface StaticServiceProducerNoBinder<TServiceClass> { + /** + * Return a new service wrapper of type {@code TServiceClass}. + */ + TServiceClass createService(); + } + + /** + * Callback interface used as a parameter to {@link #registerStaticService( + * String, Class, StaticServiceProducerWithBinder)}, which generates a service wrapper instance + * that's not tied to any context and takes a service binder object in the constructor. + * + * @param <TServiceClass> type of the service wrapper class. + * + * @hide + */ + //@SystemApi TODO Make it a system API. + public interface StaticServiceProducerWithBinder<TServiceClass> { + /** + * Return a new service wrapper of type {@code TServiceClass} backed by a given + * service binder object. + */ + TServiceClass createService(IBinder serviceBinder); + } + + /** + * Callback interface used as a parameter to {@link #registerContextAwareService( + * String, Class, ContextAwareServiceProducerNoBinder)}, + * which generates a service wrapper instance + * that's tied to a specific context and does not take a service binder object in the + * constructor. + * + * @param <TServiceClass> type of the service wrapper class. + * + * @hide + */ + //@SystemApi TODO Make it a system API. + public interface ContextAwareServiceProducerNoBinder<TServiceClass> { + /** + * Return a new service wrapper of type {@code TServiceClass} tied to a given + * {@code context}. + * + * TODO Do we need to pass the "base context" too? + */ + TServiceClass createService(Context context); + } + + /** + * Callback interface used as a parameter to {@link #registerContextAwareService( + * String, Class, ContextAwareServiceProducerWithBinder)}, + * which generates a service wrapper instance + * that's tied to a specific context and takes a service binder object in the constructor. + * + * @param <TServiceClass> type of the service wrapper class. * * @hide */ - public static <T> void registerStaticService(String serviceName, Class<T> serviceWrapperClass, - Function<IBinder, T> serviceFetcher) { + //@SystemApi TODO Make it a system API. + public interface ContextAwareServiceProducerWithBinder<TServiceClass> { + /** + * Return a new service wrapper of type {@code TServiceClass} backed by a given + * service binder object that's tied to a given {@code context}. + * + * TODO Do we need to pass the "base context" too? + */ + TServiceClass createService(Context context, IBinder serviceBinder); + } + + /** + * Used by apex modules to register a "service wrapper" that is not tied to any {@link Context}. + * + * <p>This can only be called from the methods called by the static initializer of + * {@link SystemServiceRegistry}. (Otherwise it throws a {@link IllegalStateException}.) + * + * @param serviceName the name of the binder object, such as + * {@link Context#JOB_SCHEDULER_SERVICE}. + * @param serviceWrapperClass the wrapper class, such as the class of + * {@link android.app.job.JobScheduler}. + * @param serviceProducer Callback that takes the service binder object with the name + * {@code serviceName} and returns an actual service wrapper instance. + * + * @hide + */ + //@SystemApi TODO Make it a system API. + public static <TServiceClass> void registerStaticService( + @NonNull String serviceName, @NonNull Class<TServiceClass> serviceWrapperClass, + @NonNull StaticServiceProducerWithBinder<TServiceClass> serviceProducer) { + ensureInitializing("registerStaticService"); + Preconditions.checkStringNotEmpty(serviceName); + Preconditions.checkNotNull(serviceWrapperClass); + Preconditions.checkNotNull(serviceProducer); + registerService(serviceName, serviceWrapperClass, - new StaticServiceFetcher<T>() { + new StaticServiceFetcher<TServiceClass>() { @Override - public T createService() throws ServiceNotFoundException { - IBinder b = ServiceManager.getServiceOrThrow(serviceName); - return serviceFetcher.apply(b); + public TServiceClass createService() throws ServiceNotFoundException { + return serviceProducer.createService( + ServiceManager.getServiceOrThrow(serviceName)); }}); } /** - * APEX modules will use it to register their service wrapper. + * Similar to {@link #registerStaticService(String, Class, StaticServiceProducerWithBinder)}, + * but used for a "service wrapper" that doesn't take a service binder in its constructor. * * @hide */ - public static <T> void registerCachedService(String serviceName, Class<T> serviceWrapperClass, - BiFunction<Context, IBinder, T> serviceFetcher) { + //@SystemApi TODO Make it a system API. + public static <TServiceClass> void registerStaticService( + @NonNull String serviceName, @NonNull Class<TServiceClass> serviceWrapperClass, + @NonNull StaticServiceProducerNoBinder<TServiceClass> serviceProducer) { + ensureInitializing("registerStaticService"); + Preconditions.checkStringNotEmpty(serviceName); + Preconditions.checkNotNull(serviceWrapperClass); + Preconditions.checkNotNull(serviceProducer); + + registerService(serviceName, serviceWrapperClass, + new StaticServiceFetcher<TServiceClass>() { + @Override + public TServiceClass createService() { + return serviceProducer.createService(); + }}); + } + + /** + * Used by apex modules to register a "service wrapper" that is tied to a specific + * {@link Context}. + * + * <p>This can only be called from the methods called by the static initializer of + * {@link SystemServiceRegistry}. (Otherwise it throws a {@link IllegalStateException}.) + * + * @param serviceName the name of the binder object, such as + * {@link Context#JOB_SCHEDULER_SERVICE}. + * @param serviceWrapperClass the wrapper class, such as the class of + * {@link android.app.job.JobScheduler}. + * @param serviceProducer lambda that takes the service binder object with the name + * {@code serviceName}, a {@link Context} and returns an actual service wrapper instance. + * + * @hide + */ + //@SystemApi TODO Make it a system API. + public static <TServiceClass> void registerContextAwareService( + @NonNull String serviceName, @NonNull Class<TServiceClass> serviceWrapperClass, + @NonNull ContextAwareServiceProducerWithBinder<TServiceClass> serviceProducer) { + ensureInitializing("registerContextAwareService"); + Preconditions.checkStringNotEmpty(serviceName); + Preconditions.checkNotNull(serviceWrapperClass); + Preconditions.checkNotNull(serviceProducer); + + registerService(serviceName, serviceWrapperClass, + new CachedServiceFetcher<TServiceClass>() { + @Override + public TServiceClass createService(ContextImpl ctx) + throws ServiceNotFoundException { + return serviceProducer.createService( + ctx.getOuterContext(), + ServiceManager.getServiceOrThrow(serviceName)); + }}); + } + + + /** + * Similar to {@link #registerContextAwareService(String, Class, + * ContextAwareServiceProducerWithBinder)}, + * but used for a "service wrapper" that doesn't take a service binder in its constructor. + * + * @hide + */ + //@SystemApi TODO Make it a system API. + public static <TServiceClass> void registerContextAwareService( + @NonNull String serviceName, @NonNull Class<TServiceClass> serviceWrapperClass, + @NonNull ContextAwareServiceProducerNoBinder<TServiceClass> serviceProducer) { + ensureInitializing("registerContextAwareService"); + Preconditions.checkStringNotEmpty(serviceName); + Preconditions.checkNotNull(serviceWrapperClass); + Preconditions.checkNotNull(serviceProducer); + registerService(serviceName, serviceWrapperClass, - new CachedServiceFetcher<T>() { + new CachedServiceFetcher<TServiceClass>() { @Override - public T createService(ContextImpl ctx) throws ServiceNotFoundException { - IBinder b = ServiceManager.getServiceOrThrow(serviceName); - return serviceFetcher.apply(ctx.getOuterContext(), b); + public TServiceClass createService(ContextImpl ctx) { + return serviceProducer.createService(ctx.getOuterContext()); }}); } @@ -1517,6 +1698,7 @@ public final class SystemServiceRegistry { public abstract T createService(Context applicationContext) throws ServiceNotFoundException; } + /** @hide */ public static void onServiceNotFound(ServiceNotFoundException e) { // We're mostly interested in tracking down long-lived core system // components that might stumble if they obtain bad references; just diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java index 59ecf4aa6e8a..41604ec97867 100644 --- a/core/java/android/app/WallpaperManager.java +++ b/core/java/android/app/WallpaperManager.java @@ -458,8 +458,9 @@ public class WallpaperManager { try { Bundle params = new Bundle(); - ParcelFileDescriptor fd = mService.getWallpaper(context.getOpPackageName(), - this, FLAG_SYSTEM, params, userId); + ParcelFileDescriptor fd = mService.getWallpaperWithFeature( + context.getOpPackageName(), context.getFeatureId(), this, FLAG_SYSTEM, + params, userId); if (fd != null) { try { BitmapFactory.Options options = new BitmapFactory.Options(); @@ -985,8 +986,8 @@ public class WallpaperManager { } else { try { Bundle outParams = new Bundle(); - return sGlobals.mService.getWallpaper(mContext.getOpPackageName(), null, which, - outParams, userId); + return sGlobals.mService.getWallpaperWithFeature(mContext.getOpPackageName(), + mContext.getFeatureId(), null, which, outParams, userId); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } catch (SecurityException e) { diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java index c6160446c798..19f42b6a4c9e 100644 --- a/core/java/android/bluetooth/BluetoothDevice.java +++ b/core/java/android/bluetooth/BluetoothDevice.java @@ -173,13 +173,10 @@ public final class BluetoothDevice implements Parcelable { * changed. * <p>Always contains the extra field {@link #EXTRA_DEVICE}. * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive. - * - * @hide */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) - @UnsupportedAppUsage public static final String ACTION_ALIAS_CHANGED = - "android.bluetooth.device.action.ALIAS_CHANGED"; + "android.bluetooth.action.ALIAS_CHANGED"; /** * Broadcast Action: Indicates a change in the bond state of a remote @@ -1048,10 +1045,11 @@ public final class BluetoothDevice implements Parcelable { * Get the Bluetooth alias of the remote device. * <p>Alias is the locally modified name of a remote device. * - * @return the Bluetooth alias, or null if no alias or there was a problem - * @hide + * @return the Bluetooth alias, the friendly device name if no alias, or + * null if there was a problem */ - @UnsupportedAppUsage(publicAlternatives = "Use {@link #getName()} instead.") + @Nullable + @RequiresPermission(Manifest.permission.BLUETOOTH) public String getAlias() { final IBluetooth service = sService; if (service == null) { @@ -1059,7 +1057,11 @@ public final class BluetoothDevice implements Parcelable { return null; } try { - return service.getRemoteAlias(this); + String alias = service.getRemoteAlias(this); + if (alias == null) { + return getName(); + } + return alias; } catch (RemoteException e) { Log.e(TAG, "", e); } @@ -1076,8 +1078,9 @@ public final class BluetoothDevice implements Parcelable { * @return true on success, false on error * @hide */ - @UnsupportedAppUsage - public boolean setAlias(String alias) { + @SystemApi + @RequiresPermission(Manifest.permission.BLUETOOTH) + public boolean setAlias(@NonNull String alias) { final IBluetooth service = sService; if (service == null) { Log.e(TAG, "BT not enabled. Cannot set Remote Device name"); diff --git a/core/java/android/companion/BluetoothDeviceFilterUtils.java b/core/java/android/companion/BluetoothDeviceFilterUtils.java index 75e726bfad0d..0f67f6b50251 100644 --- a/core/java/android/companion/BluetoothDeviceFilterUtils.java +++ b/core/java/android/companion/BluetoothDeviceFilterUtils.java @@ -129,7 +129,7 @@ public class BluetoothDeviceFilterUtils { @UnsupportedAppUsage public static String getDeviceDisplayNameInternal(@NonNull BluetoothDevice device) { - return firstNotEmpty(device.getAliasName(), device.getAddress()); + return firstNotEmpty(device.getAlias(), device.getAddress()); } @UnsupportedAppUsage diff --git a/core/java/android/content/ContentInterface.java b/core/java/android/content/ContentInterface.java index 197de9711296..5988dd3914f1 100644 --- a/core/java/android/content/ContentInterface.java +++ b/core/java/android/content/ContentInterface.java @@ -53,23 +53,22 @@ public interface ContentInterface { public @Nullable Uri uncanonicalize(@NonNull Uri uri) throws RemoteException; - public boolean refresh(@NonNull Uri uri, @Nullable Bundle args, + public boolean refresh(@NonNull Uri uri, @Nullable Bundle extras, @Nullable CancellationSignal cancellationSignal) throws RemoteException; public int checkUriPermission(@NonNull Uri uri, int uid, @Intent.AccessUriMode int modeFlags) throws RemoteException; - public @Nullable Uri insert(@NonNull Uri uri, @Nullable ContentValues initialValues) - throws RemoteException; + public @Nullable Uri insert(@NonNull Uri uri, @Nullable ContentValues initialValues, + @Nullable Bundle extras) throws RemoteException; public int bulkInsert(@NonNull Uri uri, @NonNull ContentValues[] initialValues) throws RemoteException; - public int delete(@NonNull Uri uri, @Nullable String selection, - @Nullable String[] selectionArgs) throws RemoteException; + public int delete(@NonNull Uri uri, @Nullable Bundle extras) throws RemoteException; - public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection, - @Nullable String[] selectionArgs) throws RemoteException; + public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable Bundle extras) + throws RemoteException; public @Nullable ParcelFileDescriptor openFile(@NonNull Uri uri, @NonNull String mode, @Nullable CancellationSignal signal) throws RemoteException, FileNotFoundException; diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java index 17f1a07d6e01..2240823ebe92 100644 --- a/core/java/android/content/ContentProvider.java +++ b/core/java/android/content/ContentProvider.java @@ -299,7 +299,7 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall @Override public Uri insert(String callingPkg, @Nullable String featureId, Uri uri, - ContentValues initialValues) { + ContentValues initialValues, Bundle extras) { uri = validateIncomingUri(uri); int userId = getUserIdFromUri(uri); uri = maybeGetUriWithoutUserId(uri); @@ -317,7 +317,7 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall final Pair<String, String> original = setCallingPackage( new Pair<>(callingPkg, featureId)); try { - return maybeAddUserId(mInterface.insert(uri, initialValues), userId); + return maybeAddUserId(mInterface.insert(uri, initialValues, extras), userId); } catch (RemoteException e) { throw e.rethrowAsRuntimeException(); } finally { @@ -403,8 +403,7 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall } @Override - public int delete(String callingPkg, @Nullable String featureId, Uri uri, String selection, - String[] selectionArgs) { + public int delete(String callingPkg, @Nullable String featureId, Uri uri, Bundle extras) { uri = validateIncomingUri(uri); uri = maybeGetUriWithoutUserId(uri); if (enforceWritePermission(callingPkg, featureId, uri, null) @@ -415,7 +414,7 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall final Pair<String, String> original = setCallingPackage( new Pair<>(callingPkg, featureId)); try { - return mInterface.delete(uri, selection, selectionArgs); + return mInterface.delete(uri, extras); } catch (RemoteException e) { throw e.rethrowAsRuntimeException(); } finally { @@ -426,7 +425,7 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall @Override public int update(String callingPkg, @Nullable String featureId, Uri uri, - ContentValues values, String selection, String[] selectionArgs) { + ContentValues values, Bundle extras) { uri = validateIncomingUri(uri); uri = maybeGetUriWithoutUserId(uri); if (enforceWritePermission(callingPkg, featureId, uri, null) @@ -437,7 +436,7 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall final Pair<String, String> original = setCallingPackage( new Pair<>(callingPkg, featureId)); try { - return mInterface.update(uri, values, selection, selectionArgs); + return mInterface.update(uri, values, extras); } catch (RemoteException e) { throw e.rethrowAsRuntimeException(); } finally { @@ -593,7 +592,7 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall } @Override - public boolean refresh(String callingPkg, String featureId, Uri uri, Bundle args, + public boolean refresh(String callingPkg, String featureId, Uri uri, Bundle extras, ICancellationSignal cancellationSignal) throws RemoteException { uri = validateIncomingUri(uri); uri = getUriWithoutUserId(uri); @@ -605,7 +604,7 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall final Pair<String, String> original = setCallingPackage( new Pair<>(callingPkg, featureId)); try { - return mInterface.refresh(uri, args, + return mInterface.refresh(uri, extras, CancellationSignal.fromTransport(cancellationSignal)); } finally { setCallingPackage(original); @@ -1494,29 +1493,34 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall } /** - * Implement this to support refresh of content identified by {@code uri}. By default, this - * method returns false; providers who wish to implement this should return true to signal the - * client that the provider has tried refreshing with its own implementation. + * Implement this to support refresh of content identified by {@code uri}. + * By default, this method returns false; providers who wish to implement + * this should return true to signal the client that the provider has tried + * refreshing with its own implementation. * <p> - * This allows clients to request an explicit refresh of content identified by {@code uri}. + * This allows clients to request an explicit refresh of content identified + * by {@code uri}. * <p> - * Client code should only invoke this method when there is a strong indication (such as a user - * initiated pull to refresh gesture) that the content is stale. + * Client code should only invoke this method when there is a strong + * indication (such as a user initiated pull to refresh gesture) that the + * content is stale. * <p> - * Remember to send {@link ContentResolver#notifyChange(Uri, android.database.ContentObserver)} + * Remember to send + * {@link ContentResolver#notifyChange(Uri, android.database.ContentObserver)} * notifications when content changes. * * @param uri The Uri identifying the data to refresh. - * @param args Additional options from the client. The definitions of these are specific to the - * content provider being called. - * @param cancellationSignal A signal to cancel the operation in progress, or {@code null} if - * none. For example, if you called refresh on a particular uri, you should call - * {@link CancellationSignal#throwIfCanceled()} to check whether the client has - * canceled the refresh request. + * @param extras Additional options from the client. The definitions of + * these are specific to the content provider being called. + * @param cancellationSignal A signal to cancel the operation in progress, + * or {@code null} if none. For example, if you called refresh on + * a particular uri, you should call + * {@link CancellationSignal#throwIfCanceled()} to check whether + * the client has canceled the refresh request. * @return true if the provider actually tried refreshing. */ @Override - public boolean refresh(Uri uri, @Nullable Bundle args, + public boolean refresh(Uri uri, @Nullable Bundle extras, @Nullable CancellationSignal cancellationSignal) { return false; } @@ -1545,20 +1549,42 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall } /** - * Implement this to handle requests to insert a new row. - * As a courtesy, call {@link ContentResolver#notifyChange(android.net.Uri ,android.database.ContentObserver) notifyChange()} - * after inserting. - * This method can be called from multiple threads, as described in - * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes + * Implement this to handle requests to insert a new row. As a courtesy, + * call + * {@link ContentResolver#notifyChange(android.net.Uri ,android.database.ContentObserver) + * notifyChange()} after inserting. This method can be called from multiple + * threads, as described in <a href=" + * {@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes * and Threads</a>. + * * @param uri The content:// URI of the insertion request. * @param values A set of column_name/value pairs to add to the database. * @return The URI for the newly inserted item. */ - @Override public abstract @Nullable Uri insert(@NonNull Uri uri, @Nullable ContentValues values); /** + * Implement this to handle requests to insert a new row. As a courtesy, + * call + * {@link ContentResolver#notifyChange(android.net.Uri ,android.database.ContentObserver) + * notifyChange()} after inserting. This method can be called from multiple + * threads, as described in <a href=" + * {@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes + * and Threads</a>. + * + * @param uri The content:// URI of the insertion request. + * @param values A set of column_name/value pairs to add to the database. + * @param extras A Bundle containing all additional information necessary + * for the insert. + * @return The URI for the newly inserted item. + */ + @Override + public @Nullable Uri insert(@NonNull Uri uri, @Nullable ContentValues values, + @Nullable Bundle extras) { + return insert(uri, values); + } + + /** * Override this to handle requests to insert a set of new rows, or the * default implementation will iterate over the values and call * {@link #insert} on each of them. @@ -1583,50 +1609,111 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall } /** - * Implement this to handle requests to delete one or more rows. - * The implementation should apply the selection clause when performing + * Implement this to handle requests to delete one or more rows. The + * implementation should apply the selection clause when performing * deletion, allowing the operation to affect multiple rows in a directory. - * As a courtesy, call {@link ContentResolver#notifyChange(android.net.Uri ,android.database.ContentObserver) notifyChange()} - * after deleting. - * This method can be called from multiple threads, as described in - * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes + * As a courtesy, call + * {@link ContentResolver#notifyChange(android.net.Uri ,android.database.ContentObserver) + * notifyChange()} after deleting. This method can be called from multiple + * threads, as described in <a href=" + * {@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes * and Threads</a>. - * - * <p>The implementation is responsible for parsing out a row ID at the end - * of the URI, if a specific row is being deleted. That is, the client would - * pass in <code>content://contacts/people/22</code> and the implementation is - * responsible for parsing the record number (22) when creating a SQL statement. - * - * @param uri The full URI to query, including a row ID (if a specific record is requested). + * <p> + * The implementation is responsible for parsing out a row ID at the end of + * the URI, if a specific row is being deleted. That is, the client would + * pass in <code>content://contacts/people/22</code> and the implementation + * is responsible for parsing the record number (22) when creating a SQL + * statement. + * + * @param uri The full URI to query, including a row ID (if a specific + * record is requested). * @param selection An optional restriction to apply to rows when deleting. * @return The number of rows affected. * @throws SQLException */ - @Override public abstract int delete(@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs); /** - * Implement this to handle requests to update one or more rows. - * The implementation should update all rows matching the selection - * to set the columns according to the provided values map. - * As a courtesy, call {@link ContentResolver#notifyChange(android.net.Uri ,android.database.ContentObserver) notifyChange()} - * after updating. - * This method can be called from multiple threads, as described in - * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes + * Implement this to handle requests to delete one or more rows. The + * implementation should apply the selection clause when performing + * deletion, allowing the operation to affect multiple rows in a directory. + * As a courtesy, call + * {@link ContentResolver#notifyChange(android.net.Uri ,android.database.ContentObserver) + * notifyChange()} after deleting. This method can be called from multiple + * threads, as described in <a href=" + * {@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes + * and Threads</a>. + * <p> + * The implementation is responsible for parsing out a row ID at the end of + * the URI, if a specific row is being deleted. That is, the client would + * pass in <code>content://contacts/people/22</code> and the implementation + * is responsible for parsing the record number (22) when creating a SQL + * statement. + * + * @param uri The full URI to query, including a row ID (if a specific + * record is requested). + * @param extras A Bundle containing all additional information necessary + * for the delete. Values in the Bundle may include SQL style + * arguments. + * @return The number of rows affected. + * @throws SQLException + */ + @Override + public int delete(@NonNull Uri uri, @Nullable Bundle extras) { + extras = (extras != null) ? extras : Bundle.EMPTY; + return delete(uri, + extras.getString(ContentResolver.QUERY_ARG_SQL_SELECTION), + extras.getStringArray(ContentResolver.QUERY_ARG_SQL_SELECTION_ARGS)); + } + + /** + * Implement this to handle requests to update one or more rows. The + * implementation should update all rows matching the selection to set the + * columns according to the provided values map. As a courtesy, call + * {@link ContentResolver#notifyChange(android.net.Uri ,android.database.ContentObserver) + * notifyChange()} after updating. This method can be called from multiple + * threads, as described in <a href=" + * {@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes * and Threads</a>. * - * @param uri The URI to query. This can potentially have a record ID if this - * is an update request for a specific record. + * @param uri The URI to query. This can potentially have a record ID if + * this is an update request for a specific record. * @param values A set of column_name/value pairs to update in the database. * @param selection An optional filter to match rows to update. * @return the number of rows affected. */ - @Override public abstract int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection, @Nullable String[] selectionArgs); /** + * Implement this to handle requests to update one or more rows. The + * implementation should update all rows matching the selection to set the + * columns according to the provided values map. As a courtesy, call + * {@link ContentResolver#notifyChange(android.net.Uri ,android.database.ContentObserver) + * notifyChange()} after updating. This method can be called from multiple + * threads, as described in <a href=" + * {@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes + * and Threads</a>. + * + * @param uri The URI to query. This can potentially have a record ID if + * this is an update request for a specific record. + * @param values A set of column_name/value pairs to update in the database. + * @param extras A Bundle containing all additional information necessary + * for the update. Values in the Bundle may include SQL style + * arguments. + * @return the number of rows affected. + */ + @Override + public int update(@NonNull Uri uri, @Nullable ContentValues values, + @Nullable Bundle extras) { + extras = (extras != null) ? extras : Bundle.EMPTY; + return update(uri, values, + extras.getString(ContentResolver.QUERY_ARG_SQL_SELECTION), + extras.getStringArray(ContentResolver.QUERY_ARG_SQL_SELECTION_ARGS)); + } + + /** * Override this to handle requests to open a file blob. * The default implementation always throws {@link FileNotFoundException}. * This method can be called from multiple threads, as described in diff --git a/core/java/android/content/ContentProviderClient.java b/core/java/android/content/ContentProviderClient.java index d2632e78c00c..bb65aa013f72 100644 --- a/core/java/android/content/ContentProviderClient.java +++ b/core/java/android/content/ContentProviderClient.java @@ -286,7 +286,7 @@ public class ContentProviderClient implements ContentInterface, AutoCloseable { /** See {@link ContentProvider#refresh} */ @Override - public boolean refresh(Uri url, @Nullable Bundle args, + public boolean refresh(Uri url, @Nullable Bundle extras, @Nullable CancellationSignal cancellationSignal) throws RemoteException { Preconditions.checkNotNull(url, "url"); @@ -298,7 +298,7 @@ public class ContentProviderClient implements ContentInterface, AutoCloseable { remoteCancellationSignal = mContentProvider.createCancellationSignal(); cancellationSignal.setRemote(remoteCancellationSignal); } - return mContentProvider.refresh(mPackageName, mFeatureId, url, args, + return mContentProvider.refresh(mPackageName, mFeatureId, url, extras, remoteCancellationSignal); } catch (DeadObjectException e) { if (!mStable) { @@ -331,14 +331,20 @@ public class ContentProviderClient implements ContentInterface, AutoCloseable { } /** See {@link ContentProvider#insert ContentProvider.insert} */ - @Override public @Nullable Uri insert(@NonNull Uri url, @Nullable ContentValues initialValues) throws RemoteException { + return insert(url, initialValues, null); + } + + /** See {@link ContentProvider#insert ContentProvider.insert} */ + @Override + public @Nullable Uri insert(@NonNull Uri url, @Nullable ContentValues initialValues, + @Nullable Bundle extras) throws RemoteException { Preconditions.checkNotNull(url, "url"); beforeRemote(); try { - return mContentProvider.insert(mPackageName, mFeatureId, url, initialValues); + return mContentProvider.insert(mPackageName, mFeatureId, url, initialValues, extras); } catch (DeadObjectException e) { if (!mStable) { mContentResolver.unstableProviderDied(mContentProvider); @@ -370,15 +376,19 @@ public class ContentProviderClient implements ContentInterface, AutoCloseable { } /** See {@link ContentProvider#delete ContentProvider.delete} */ - @Override public int delete(@NonNull Uri url, @Nullable String selection, @Nullable String[] selectionArgs) throws RemoteException { + return delete(url, ContentResolver.createSqlQueryBundle(selection, selectionArgs)); + } + + /** See {@link ContentProvider#delete ContentProvider.delete} */ + @Override + public int delete(@NonNull Uri url, @Nullable Bundle extras) throws RemoteException { Preconditions.checkNotNull(url, "url"); beforeRemote(); try { - return mContentProvider.delete(mPackageName, mFeatureId, url, selection, - selectionArgs); + return mContentProvider.delete(mPackageName, mFeatureId, url, extras); } catch (DeadObjectException e) { if (!mStable) { mContentResolver.unstableProviderDied(mContentProvider); @@ -390,15 +400,20 @@ public class ContentProviderClient implements ContentInterface, AutoCloseable { } /** See {@link ContentProvider#update ContentProvider.update} */ - @Override public int update(@NonNull Uri url, @Nullable ContentValues values, @Nullable String selection, @Nullable String[] selectionArgs) throws RemoteException { + return update(url, values, ContentResolver.createSqlQueryBundle(selection, selectionArgs)); + } + + /** See {@link ContentProvider#update ContentProvider.update} */ + @Override + public int update(@NonNull Uri url, @Nullable ContentValues values, @Nullable Bundle extras) + throws RemoteException { Preconditions.checkNotNull(url, "url"); beforeRemote(); try { - return mContentProvider.update(mPackageName, mFeatureId, url, values, selection, - selectionArgs); + return mContentProvider.update(mPackageName, mFeatureId, url, values, extras); } catch (DeadObjectException e) { if (!mStable) { mContentResolver.unstableProviderDied(mContentProvider); diff --git a/core/java/android/content/ContentProviderNative.java b/core/java/android/content/ContentProviderNative.java index f082690e2ceb..dfa71f88fa0a 100644 --- a/core/java/android/content/ContentProviderNative.java +++ b/core/java/android/content/ContentProviderNative.java @@ -153,8 +153,9 @@ abstract public class ContentProviderNative extends Binder implements IContentPr String featureId = data.readString(); Uri url = Uri.CREATOR.createFromParcel(data); ContentValues values = ContentValues.CREATOR.createFromParcel(data); + Bundle extras = data.readBundle(); - Uri out = insert(callingPkg, featureId, url, values); + Uri out = insert(callingPkg, featureId, url, values, extras); reply.writeNoException(); Uri.writeToParcel(reply, out); return true; @@ -199,10 +200,9 @@ abstract public class ContentProviderNative extends Binder implements IContentPr String callingPkg = data.readString(); String featureId = data.readString(); Uri url = Uri.CREATOR.createFromParcel(data); - String selection = data.readString(); - String[] selectionArgs = data.readStringArray(); + Bundle extras = data.readBundle(); - int count = delete(callingPkg, featureId, url, selection, selectionArgs); + int count = delete(callingPkg, featureId, url, extras); reply.writeNoException(); reply.writeInt(count); @@ -216,11 +216,9 @@ abstract public class ContentProviderNative extends Binder implements IContentPr String featureId = data.readString(); Uri url = Uri.CREATOR.createFromParcel(data); ContentValues values = ContentValues.CREATOR.createFromParcel(data); - String selection = data.readString(); - String[] selectionArgs = data.readStringArray(); + Bundle extras = data.readBundle(); - int count = update(callingPkg, featureId, url, values, selection, - selectionArgs); + int count = update(callingPkg, featureId, url, values, extras); reply.writeNoException(); reply.writeInt(count); @@ -283,10 +281,10 @@ abstract public class ContentProviderNative extends Binder implements IContentPr String authority = data.readString(); String method = data.readString(); String stringArg = data.readString(); - Bundle args = data.readBundle(); + Bundle extras = data.readBundle(); Bundle responseBundle = call(callingPkg, featureId, authority, method, - stringArg, args); + stringArg, extras); reply.writeNoException(); reply.writeBundle(responseBundle); @@ -370,11 +368,11 @@ abstract public class ContentProviderNative extends Binder implements IContentPr String callingPkg = data.readString(); String featureId = data.readString(); Uri url = Uri.CREATOR.createFromParcel(data); - Bundle args = data.readBundle(); + Bundle extras = data.readBundle(); ICancellationSignal signal = ICancellationSignal.Stub.asInterface( data.readStrongBinder()); - boolean out = refresh(callingPkg, featureId, url, args, signal); + boolean out = refresh(callingPkg, featureId, url, extras, signal); reply.writeNoException(); reply.writeInt(out ? 0 : -1); return true; @@ -498,7 +496,7 @@ final class ContentProviderProxy implements IContentProvider @Override public Uri insert(String callingPkg, @Nullable String featureId, Uri url, - ContentValues values) throws RemoteException + ContentValues values, Bundle extras) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); @@ -509,6 +507,7 @@ final class ContentProviderProxy implements IContentProvider data.writeString(featureId); url.writeToParcel(data, 0); values.writeToParcel(data, 0); + data.writeBundle(extras); mRemote.transact(IContentProvider.INSERT_TRANSACTION, data, reply, 0); @@ -573,8 +572,8 @@ final class ContentProviderProxy implements IContentProvider } @Override - public int delete(String callingPkg, @Nullable String featureId, Uri url, String selection, - String[] selectionArgs) throws RemoteException { + public int delete(String callingPkg, @Nullable String featureId, Uri url, Bundle extras) + throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); try { @@ -583,8 +582,7 @@ final class ContentProviderProxy implements IContentProvider data.writeString(callingPkg); data.writeString(featureId); url.writeToParcel(data, 0); - data.writeString(selection); - data.writeStringArray(selectionArgs); + data.writeBundle(extras); mRemote.transact(IContentProvider.DELETE_TRANSACTION, data, reply, 0); @@ -599,7 +597,7 @@ final class ContentProviderProxy implements IContentProvider @Override public int update(String callingPkg, @Nullable String featureId, Uri url, - ContentValues values, String selection, String[] selectionArgs) throws RemoteException { + ContentValues values, Bundle extras) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); try { @@ -609,8 +607,7 @@ final class ContentProviderProxy implements IContentProvider data.writeString(featureId); url.writeToParcel(data, 0); values.writeToParcel(data, 0); - data.writeString(selection); - data.writeStringArray(selectionArgs); + data.writeBundle(extras); mRemote.transact(IContentProvider.UPDATE_TRANSACTION, data, reply, 0); @@ -682,7 +679,7 @@ final class ContentProviderProxy implements IContentProvider @Override public Bundle call(String callingPkg, @Nullable String featureId, String authority, - String method, String request, Bundle args) throws RemoteException { + String method, String request, Bundle extras) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); try { @@ -693,7 +690,7 @@ final class ContentProviderProxy implements IContentProvider data.writeString(authority); data.writeString(method); data.writeString(request); - data.writeBundle(args); + data.writeBundle(extras); mRemote.transact(IContentProvider.CALL_TRANSACTION, data, reply, 0); @@ -824,7 +821,7 @@ final class ContentProviderProxy implements IContentProvider } @Override - public boolean refresh(String callingPkg, @Nullable String featureId, Uri url, Bundle args, + public boolean refresh(String callingPkg, @Nullable String featureId, Uri url, Bundle extras, ICancellationSignal signal) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); @@ -834,7 +831,7 @@ final class ContentProviderProxy implements IContentProvider data.writeString(callingPkg); data.writeString(featureId); url.writeToParcel(data, 0); - data.writeBundle(args); + data.writeBundle(extras); data.writeStrongBinder(signal != null ? signal.asBinder() : null); mRemote.transact(IContentProvider.REFRESH_TRANSACTION, data, reply, 0); diff --git a/core/java/android/content/ContentProviderOperation.java b/core/java/android/content/ContentProviderOperation.java index 5c2de57d77a5..93f42879d946 100644 --- a/core/java/android/content/ContentProviderOperation.java +++ b/core/java/android/content/ContentProviderOperation.java @@ -357,11 +357,22 @@ public class ContentProviderOperation implements Parcelable { ContentProviderResult[] backRefs, int numBackRefs) throws OperationApplicationException { final ContentValues values = resolveValueBackReferences(backRefs, numBackRefs); - final Bundle extras = resolveExtrasBackReferences(backRefs, numBackRefs); - final String[] selectionArgs = resolveSelectionArgsBackReferences(backRefs, numBackRefs); + + // If the creator requested explicit selection or selectionArgs, it + // should take precedence over similar values they defined in extras + Bundle extras = resolveExtrasBackReferences(backRefs, numBackRefs); + if (mSelection != null) { + extras = (extras != null) ? extras : new Bundle(); + extras.putString(ContentResolver.QUERY_ARG_SQL_SELECTION, mSelection); + } + if (mSelectionArgs != null) { + extras = (extras != null) ? extras : new Bundle(); + extras.putStringArray(ContentResolver.QUERY_ARG_SQL_SELECTION_ARGS, + resolveSelectionArgsBackReferences(backRefs, numBackRefs)); + } if (mType == TYPE_INSERT) { - final Uri newUri = provider.insert(mUri, values); + final Uri newUri = provider.insert(mUri, values, extras); if (newUri != null) { return new ContentProviderResult(newUri); } else { @@ -375,9 +386,9 @@ public class ContentProviderOperation implements Parcelable { final int numRows; if (mType == TYPE_DELETE) { - numRows = provider.delete(mUri, mSelection, selectionArgs); + numRows = provider.delete(mUri, extras); } else if (mType == TYPE_UPDATE) { - numRows = provider.update(mUri, values, mSelection, selectionArgs); + numRows = provider.update(mUri, values, extras); } else if (mType == TYPE_ASSERT) { // Assert that all rows match expected values String[] projection = null; @@ -389,7 +400,7 @@ public class ContentProviderOperation implements Parcelable { } projection = projectionList.toArray(new String[projectionList.size()]); } - final Cursor cursor = provider.query(mUri, projection, mSelection, selectionArgs, null); + final Cursor cursor = provider.query(mUri, projection, extras, null); try { numRows = cursor.getCount(); if (projection != null) { @@ -1013,6 +1024,10 @@ public class ContentProviderOperation implements Parcelable { private void assertExtrasAllowed() { switch (mType) { + case TYPE_INSERT: + case TYPE_UPDATE: + case TYPE_DELETE: + case TYPE_ASSERT: case TYPE_CALL: break; default: diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java index 61c8db5db124..d4280f8992c2 100644 --- a/core/java/android/content/ContentResolver.java +++ b/core/java/android/content/ContentResolver.java @@ -304,31 +304,61 @@ public abstract class ContentResolver implements ContentInterface { */ public static final String QUERY_ARG_SQL_SORT_ORDER = "android:query-arg-sql-sort-order"; - /** {@hide} */ + /** + * Key for an SQL style {@code GROUP BY} string that may be present in the + * query Bundle argument passed to + * {@link ContentProvider#query(Uri, String[], Bundle, CancellationSignal)}. + * + * <p><b>Apps targeting {@link android.os.Build.VERSION_CODES#O} or higher are strongly + * encourage to use structured query arguments in lieu of opaque SQL query clauses.</b> + * + * @see #QUERY_ARG_GROUP_COLUMNS + */ public static final String QUERY_ARG_SQL_GROUP_BY = "android:query-arg-sql-group-by"; - /** {@hide} */ - public static final String QUERY_ARG_SQL_HAVING = "android:query-arg-sql-having"; - /** {@hide} */ - public static final String QUERY_ARG_SQL_LIMIT = "android:query-arg-sql-limit"; /** - * Specifies the list of columns against which to sort results. When first column values - * are identical, records are then sorted based on second column values, and so on. + * Key for an SQL style {@code HAVING} string that may be present in the + * query Bundle argument passed to + * {@link ContentProvider#query(Uri, String[], Bundle, CancellationSignal)}. * - * <p>Columns present in this list must also be included in the projection - * supplied to {@link ContentResolver#query(Uri, String[], Bundle, CancellationSignal)}. + * <p><b>Apps targeting {@link android.os.Build.VERSION_CODES#O} or higher are strongly + * encourage to use structured query arguments in lieu of opaque SQL query clauses.</b> + */ + public static final String QUERY_ARG_SQL_HAVING = "android:query-arg-sql-having"; + + /** + * Key for an SQL style {@code LIMIT} string that may be present in the + * query Bundle argument passed to + * {@link ContentProvider#query(Uri, String[], Bundle, CancellationSignal)}. * - * <p>Apps targeting {@link android.os.Build.VERSION_CODES#O} or higher: + * <p><b>Apps targeting {@link android.os.Build.VERSION_CODES#O} or higher are strongly + * encourage to use structured query arguments in lieu of opaque SQL query clauses.</b> * + * @see #QUERY_ARG_LIMIT + * @see #QUERY_ARG_OFFSET + */ + public static final String QUERY_ARG_SQL_LIMIT = "android:query-arg-sql-limit"; + + /** + * Specifies the list of columns (stored as a {@code String[]}) against + * which to sort results. When first column values are identical, records + * are then sorted based on second column values, and so on. + * <p> + * Columns present in this list must also be included in the projection + * supplied to + * {@link ContentResolver#query(Uri, String[], Bundle, CancellationSignal)}. + * <p> + * Apps targeting {@link android.os.Build.VERSION_CODES#O} or higher: * <li>{@link ContentProvider} implementations: When preparing data in - * {@link ContentProvider#query(Uri, String[], Bundle, CancellationSignal)}, if sort columns - * is reflected in the returned Cursor, it is strongly recommended that - * {@link #QUERY_ARG_SORT_COLUMNS} then be included in the array of honored arguments - * reflected in {@link Cursor} extras {@link Bundle} under {@link #EXTRA_HONORED_ARGS}. - * - * <li>When querying a provider, where no QUERY_ARG_SQL* otherwise exists in the - * arguments {@link Bundle}, the Content framework will attempt to synthesize - * an QUERY_ARG_SQL* argument using the corresponding QUERY_ARG_SORT* values. + * {@link ContentProvider#query(Uri, String[], Bundle, CancellationSignal)}, + * if sort columns is reflected in the returned Cursor, it is strongly + * recommended that {@link #QUERY_ARG_SORT_COLUMNS} then be included in the + * array of honored arguments reflected in {@link Cursor} extras + * {@link Bundle} under {@link #EXTRA_HONORED_ARGS}. + * <li>When querying a provider, where no QUERY_ARG_SQL* otherwise exists in + * the arguments {@link Bundle}, the Content framework will attempt to + * synthesize an QUERY_ARG_SQL* argument using the corresponding + * QUERY_ARG_SORT* values. */ public static final String QUERY_ARG_SORT_COLUMNS = "android:query-arg-sort-columns"; @@ -402,6 +432,29 @@ public abstract class ContentResolver implements ContentInterface { public static final String QUERY_ARG_SORT_LOCALE = "android:query-arg-sort-locale"; /** + * Specifies the list of columns (stored as a {@code String[]}) against + * which to group results. When column values are identical, multiple + * records are collapsed together into a single record. + * <p> + * Columns present in this list must also be included in the projection + * supplied to + * {@link ContentResolver#query(Uri, String[], Bundle, CancellationSignal)}. + * <p> + * Apps targeting {@link android.os.Build.VERSION_CODES#R} or higher: + * <li>{@link ContentProvider} implementations: When preparing data in + * {@link ContentProvider#query(Uri, String[], Bundle, CancellationSignal)}, + * if group columns is reflected in the returned Cursor, it is strongly + * recommended that {@link #QUERY_ARG_SORT_COLUMNS} then be included in the + * array of honored arguments reflected in {@link Cursor} extras + * {@link Bundle} under {@link #EXTRA_HONORED_ARGS}. + * <li>When querying a provider, where no QUERY_ARG_SQL* otherwise exists in + * the arguments {@link Bundle}, the Content framework will attempt to + * synthesize an QUERY_ARG_SQL* argument using the corresponding + * QUERY_ARG_SORT* values. + */ + public static final String QUERY_ARG_GROUP_COLUMNS = "android:query-arg-group-columns"; + + /** * Allows provider to report back to client which query keys are honored in a Cursor. * * <p>Key identifying a {@code String[]} containing all QUERY_ARG_SORT* arguments @@ -415,6 +468,7 @@ public abstract class ContentResolver implements ContentInterface { * @see #QUERY_ARG_SORT_DIRECTION * @see #QUERY_ARG_SORT_COLLATION * @see #QUERY_ARG_SORT_LOCALE + * @see #QUERY_ARG_GROUP_COLUMNS */ public static final String EXTRA_HONORED_ARGS = "android.content.extra.HONORED_ARGS"; @@ -1127,28 +1181,31 @@ public abstract class ContentResolver implements ContentInterface { } /** - * This allows clients to request an explicit refresh of content identified by {@code uri}. + * This allows clients to request an explicit refresh of content identified + * by {@code uri}. * <p> - * Client code should only invoke this method when there is a strong indication (such as a user - * initiated pull to refresh gesture) that the content is stale. + * Client code should only invoke this method when there is a strong + * indication (such as a user initiated pull to refresh gesture) that the + * content is stale. * <p> * * @param url The Uri identifying the data to refresh. - * @param args Additional options from the client. The definitions of these are specific to the - * content provider being called. - * @param cancellationSignal A signal to cancel the operation in progress, or {@code null} if - * none. For example, if you called refresh on a particular uri, you should call - * {@link CancellationSignal#throwIfCanceled()} to check whether the client has - * canceled the refresh request. + * @param extras Additional options from the client. The definitions of + * these are specific to the content provider being called. + * @param cancellationSignal A signal to cancel the operation in progress, + * or {@code null} if none. For example, if you called refresh on + * a particular uri, you should call + * {@link CancellationSignal#throwIfCanceled()} to check whether + * the client has canceled the refresh request. * @return true if the provider actually tried refreshing. */ @Override - public final boolean refresh(@NonNull Uri url, @Nullable Bundle args, + public final boolean refresh(@NonNull Uri url, @Nullable Bundle extras, @Nullable CancellationSignal cancellationSignal) { Preconditions.checkNotNull(url, "url"); try { - if (mWrapped != null) return mWrapped.refresh(url, args, cancellationSignal); + if (mWrapped != null) return mWrapped.refresh(url, extras, cancellationSignal); } catch (RemoteException e) { return false; } @@ -1165,7 +1222,7 @@ public abstract class ContentResolver implements ContentInterface { remoteCancellationSignal = provider.createCancellationSignal(); cancellationSignal.setRemote(remoteCancellationSignal); } - return provider.refresh(mPackageName, mFeatureId, url, args, + return provider.refresh(mPackageName, mFeatureId, url, extras, remoteCancellationSignal); } catch (RemoteException e) { // Arbitrary and not worth documenting, as Activity @@ -1856,13 +1913,30 @@ public abstract class ContentResolver implements ContentInterface { * @return the URL of the newly created row. May return <code>null</code> if the underlying * content provider returns <code>null</code>, or if it crashes. */ - @Override public final @Nullable Uri insert(@RequiresPermission.Write @NonNull Uri url, @Nullable ContentValues values) { + return insert(url, values, null); + } + + /** + * Inserts a row into a table at the given URL. + * + * If the content provider supports transactions the insertion will be atomic. + * + * @param url The URL of the table to insert into. + * @param values The initial values for the newly inserted row. The key is the column name for + * the field. Passing an empty ContentValues will create an empty row. + * @param extras A Bundle containing all additional information necessary for the insert. + * @return the URL of the newly created row. May return <code>null</code> if the underlying + * content provider returns <code>null</code>, or if it crashes. + */ + @Override + public final @Nullable Uri insert(@RequiresPermission.Write @NonNull Uri url, + @Nullable ContentValues values, @Nullable Bundle extras) { Preconditions.checkNotNull(url, "url"); try { - if (mWrapped != null) return mWrapped.insert(url, values); + if (mWrapped != null) return mWrapped.insert(url, values, extras); } catch (RemoteException e) { return null; } @@ -1873,7 +1947,7 @@ public abstract class ContentResolver implements ContentInterface { } try { long startTime = SystemClock.uptimeMillis(); - Uri createdRow = provider.insert(mPackageName, mFeatureId, url, values); + Uri createdRow = provider.insert(mPackageName, mFeatureId, url, values, extras); long durationMillis = SystemClock.uptimeMillis() - startTime; maybeLogUpdateToEventLog(durationMillis, url, "insert", null /* where */); return createdRow; @@ -1977,13 +2051,27 @@ public abstract class ContentResolver implements ContentInterface { (excluding the WHERE itself). * @return The number of rows deleted. */ - @Override public final int delete(@RequiresPermission.Write @NonNull Uri url, @Nullable String where, @Nullable String[] selectionArgs) { + return delete(url, createSqlQueryBundle(where, selectionArgs)); + } + + /** + * Deletes row(s) specified by a content URI. + * + * If the content provider supports transactions, the deletion will be atomic. + * + * @param url The URL of the row to delete. + * @param extras A Bundle containing all additional information necessary for the delete. + * Values in the Bundle may include SQL style arguments. + * @return The number of rows deleted. + */ + @Override + public final int delete(@RequiresPermission.Write @NonNull Uri url, @Nullable Bundle extras) { Preconditions.checkNotNull(url, "url"); try { - if (mWrapped != null) return mWrapped.delete(url, where, selectionArgs); + if (mWrapped != null) return mWrapped.delete(url, extras); } catch (RemoteException e) { return 0; } @@ -1994,10 +2082,9 @@ public abstract class ContentResolver implements ContentInterface { } try { long startTime = SystemClock.uptimeMillis(); - int rowsDeleted = provider.delete(mPackageName, mFeatureId, url, where, - selectionArgs); + int rowsDeleted = provider.delete(mPackageName, mFeatureId, url, extras); long durationMillis = SystemClock.uptimeMillis() - startTime; - maybeLogUpdateToEventLog(durationMillis, url, "delete", where); + maybeLogUpdateToEventLog(durationMillis, url, "delete", null); return rowsDeleted; } catch (RemoteException e) { // Arbitrary and not worth documenting, as Activity @@ -2021,14 +2108,32 @@ public abstract class ContentResolver implements ContentInterface { * @return the number of rows updated. * @throws NullPointerException if uri or values are null */ - @Override public final int update(@RequiresPermission.Write @NonNull Uri uri, @Nullable ContentValues values, @Nullable String where, @Nullable String[] selectionArgs) { + return update(uri, values, createSqlQueryBundle(where, selectionArgs)); + } + + /** + * Update row(s) in a content URI. + * + * If the content provider supports transactions the update will be atomic. + * + * @param uri The URI to modify. + * @param values The new field values. The key is the column name for the field. + A null value will remove an existing field value. + * @param extras A Bundle containing all additional information necessary for the update. + * Values in the Bundle may include SQL style arguments. + * @return the number of rows updated. + * @throws NullPointerException if uri or values are null + */ + @Override + public final int update(@RequiresPermission.Write @NonNull Uri uri, + @Nullable ContentValues values, @Nullable Bundle extras) { Preconditions.checkNotNull(uri, "uri"); try { - if (mWrapped != null) return mWrapped.update(uri, values, where, selectionArgs); + if (mWrapped != null) return mWrapped.update(uri, values, extras); } catch (RemoteException e) { return 0; } @@ -2039,10 +2144,9 @@ public abstract class ContentResolver implements ContentInterface { } try { long startTime = SystemClock.uptimeMillis(); - int rowsUpdated = provider.update(mPackageName, mFeatureId, uri, values, where, - selectionArgs); + int rowsUpdated = provider.update(mPackageName, mFeatureId, uri, values, extras); long durationMillis = SystemClock.uptimeMillis() - startTime; - maybeLogUpdateToEventLog(durationMillis, uri, "update", where); + maybeLogUpdateToEventLog(durationMillis, uri, "update", null); return rowsUpdated; } catch (RemoteException e) { // Arbitrary and not worth documenting, as Activity @@ -3589,6 +3693,15 @@ public abstract class ContentResolver implements ContentInterface { */ public static @Nullable Bundle createSqlQueryBundle( @Nullable String selection, + @Nullable String[] selectionArgs) { + return createSqlQueryBundle(selection, selectionArgs, null); + } + + /** + * @hide + */ + public static @Nullable Bundle createSqlQueryBundle( + @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder) { diff --git a/core/java/android/content/IContentProvider.java b/core/java/android/content/IContentProvider.java index d2c97c4ebdd3..1fb29586e15b 100644 --- a/core/java/android/content/IContentProvider.java +++ b/core/java/android/content/IContentProvider.java @@ -48,10 +48,10 @@ public interface IContentProvider extends IInterface { + "instead") public default Uri insert(String callingPkg, Uri url, ContentValues initialValues) throws RemoteException { - return insert(callingPkg, null, url, initialValues); + return insert(callingPkg, null, url, initialValues, null); } - public Uri insert(String callingPkg, String featureId, Uri url, ContentValues initialValues) - throws RemoteException; + public Uri insert(String callingPkg, String featureId, Uri url, ContentValues initialValues, + Bundle extras) throws RemoteException; @Deprecated @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "Use {@link " + "ContentProviderClient#bulkInsert(android.net.Uri, android.content.ContentValues[])" @@ -68,20 +68,22 @@ public interface IContentProvider extends IInterface { + ".String[])} instead") public default int delete(String callingPkg, Uri url, String selection, String[] selectionArgs) throws RemoteException { - return delete(callingPkg, null, url, selection, selectionArgs); + return delete(callingPkg, null, url, + ContentResolver.createSqlQueryBundle(selection, selectionArgs)); } - public int delete(String callingPkg, String featureId, Uri url, String selection, - String[] selectionArgs) throws RemoteException; + public int delete(String callingPkg, String featureId, Uri url, Bundle extras) + throws RemoteException; @Deprecated @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "Use {@link " + "ContentProviderClient#update(android.net.Uri, android.content.ContentValues, java" + ".lang.String, java.lang.String[])} instead") public default int update(String callingPkg, Uri url, ContentValues values, String selection, String[] selectionArgs) throws RemoteException { - return update(callingPkg, null, url, values, selection, selectionArgs); + return update(callingPkg, null, url, values, + ContentResolver.createSqlQueryBundle(selection, selectionArgs)); } public int update(String callingPkg, String featureId, Uri url, ContentValues values, - String selection, String[] selectionArgs) throws RemoteException; + Bundle extras) throws RemoteException; public ParcelFileDescriptor openFile(String callingPkg, @Nullable String featureId, Uri url, String mode, ICancellationSignal signal, IBinder callerToken) @@ -119,7 +121,7 @@ public interface IContentProvider extends IInterface { throws RemoteException; public boolean refresh(String callingPkg, @Nullable String featureId, Uri url, - @Nullable Bundle args, ICancellationSignal cancellationSignal) throws RemoteException; + @Nullable Bundle extras, ICancellationSignal cancellationSignal) throws RemoteException; // Data interchange. public String[] getStreamTypes(Uri url, String mimeTypeFilter) throws RemoteException; diff --git a/core/java/android/content/LoggingContentInterface.java b/core/java/android/content/LoggingContentInterface.java index 1df1c4faf2fe..3bd083268d45 100644 --- a/core/java/android/content/LoggingContentInterface.java +++ b/core/java/android/content/LoggingContentInterface.java @@ -178,11 +178,11 @@ public class LoggingContentInterface implements ContentInterface { } @Override - public @Nullable Uri insert(@NonNull Uri uri, @Nullable ContentValues initialValues) - throws RemoteException { - try (Logger l = new Logger("insert", uri, initialValues)) { + public @Nullable Uri insert(@NonNull Uri uri, @Nullable ContentValues initialValues, + @Nullable Bundle extras) throws RemoteException { + try (Logger l = new Logger("insert", uri, initialValues, extras)) { try { - return l.setResult(delegate.insert(uri, initialValues)); + return l.setResult(delegate.insert(uri, initialValues, extras)); } catch (Exception res) { l.setResult(res); throw res; @@ -204,11 +204,10 @@ public class LoggingContentInterface implements ContentInterface { } @Override - public int delete(@NonNull Uri uri, @Nullable String selection, - @Nullable String[] selectionArgs) throws RemoteException { - try (Logger l = new Logger("delete", uri, selection, selectionArgs)) { + public int delete(@NonNull Uri uri, @Nullable Bundle extras) throws RemoteException { + try (Logger l = new Logger("delete", uri, extras)) { try { - return l.setResult(delegate.delete(uri, selection, selectionArgs)); + return l.setResult(delegate.delete(uri, extras)); } catch (Exception res) { l.setResult(res); throw res; @@ -217,11 +216,11 @@ public class LoggingContentInterface implements ContentInterface { } @Override - public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection, - @Nullable String[] selectionArgs) throws RemoteException { - try (Logger l = new Logger("update", uri, values, selection, selectionArgs)) { + public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable Bundle extras) + throws RemoteException { + try (Logger l = new Logger("update", uri, values, extras)) { try { - return l.setResult(delegate.update(uri, values, selection, selectionArgs)); + return l.setResult(delegate.update(uri, values, extras)); } catch (Exception res) { l.setResult(res); throw res; diff --git a/core/java/android/hardware/display/BrightnessChangeEvent.java b/core/java/android/hardware/display/BrightnessChangeEvent.java index 21fcc63c76fb..a6a44bea816b 100644 --- a/core/java/android/hardware/display/BrightnessChangeEvent.java +++ b/core/java/android/hardware/display/BrightnessChangeEvent.java @@ -79,7 +79,8 @@ public final class BrightnessChangeEvent implements Parcelable { /** * Histogram counting how many times a pixel of a given value was displayed onscreen for the * Value component of HSV if the device supports color sampling, if the device does not support - * color sampling the value will be null. + * color sampling or {@link BrightnessConfiguration#shouldCollectColorSamples()} is false the + * value will be null. * * The buckets of the histogram are evenly weighted, the number of buckets is device specific. * The units are in pixels * milliseconds, with 1 pixel millisecond being 1 pixel displayed @@ -94,7 +95,8 @@ public final class BrightnessChangeEvent implements Parcelable { /** * How many milliseconds of data are contained in the colorValueBuckets, if the device does - * not support color sampling the value will be 0L. + * not support color sampling or {@link BrightnessConfiguration#shouldCollectColorSamples()} is + * false the value will be 0L. * * {@see #colorValueBuckets} */ diff --git a/core/java/android/hardware/display/BrightnessConfiguration.java b/core/java/android/hardware/display/BrightnessConfiguration.java index 4c2e297d2133..139be8ee4d7b 100644 --- a/core/java/android/hardware/display/BrightnessConfiguration.java +++ b/core/java/android/hardware/display/BrightnessConfiguration.java @@ -49,26 +49,31 @@ public final class BrightnessConfiguration implements Parcelable { private static final String TAG_BRIGHTNESS_POINT = "brightness-point"; private static final String TAG_BRIGHTNESS_CORRECTIONS = "brightness-corrections"; private static final String TAG_BRIGHTNESS_CORRECTION = "brightness-correction"; + private static final String TAG_BRIGHTNESS_PARAMS = "brightness-params"; private static final String ATTR_LUX = "lux"; private static final String ATTR_NITS = "nits"; private static final String ATTR_DESCRIPTION = "description"; private static final String ATTR_PACKAGE_NAME = "package-name"; private static final String ATTR_CATEGORY = "category"; + private static final String ATTR_COLLECT_COLOR = "collect-color"; private final float[] mLux; private final float[] mNits; private final Map<String, BrightnessCorrection> mCorrectionsByPackageName; private final Map<Integer, BrightnessCorrection> mCorrectionsByCategory; private final String mDescription; + private final boolean mShouldCollectColorSamples; private BrightnessConfiguration(float[] lux, float[] nits, Map<String, BrightnessCorrection> correctionsByPackageName, - Map<Integer, BrightnessCorrection> correctionsByCategory, String description) { + Map<Integer, BrightnessCorrection> correctionsByCategory, String description, + boolean shouldCollectColorSamples) { mLux = lux; mNits = nits; mCorrectionsByPackageName = correctionsByPackageName; mCorrectionsByCategory = correctionsByCategory; mDescription = description; + mShouldCollectColorSamples = shouldCollectColorSamples; } /** @@ -119,6 +124,14 @@ public final class BrightnessConfiguration implements Parcelable { return mDescription; } + /** + * Returns whether color samples should be collected in + * {@link BrightnessChangeEvent#colorValueBuckets}. + */ + public boolean shouldCollectColorSamples() { + return mShouldCollectColorSamples; + } + @Override public void writeToParcel(Parcel dest, int flags) { dest.writeFloatArray(mLux); @@ -138,6 +151,7 @@ public final class BrightnessConfiguration implements Parcelable { correction.writeToParcel(dest, flags); } dest.writeString(mDescription); + dest.writeBoolean(mShouldCollectColorSamples); } @Override @@ -167,6 +181,7 @@ public final class BrightnessConfiguration implements Parcelable { if (mDescription != null) { sb.append(mDescription); } + sb.append(", shouldCollectColorSamples = " + mShouldCollectColorSamples); sb.append("'}"); return sb.toString(); } @@ -181,6 +196,7 @@ public final class BrightnessConfiguration implements Parcelable { if (mDescription != null) { result = result * 31 + mDescription.hashCode(); } + result = result * 31 + Boolean.hashCode(mShouldCollectColorSamples); return result; } @@ -196,7 +212,8 @@ public final class BrightnessConfiguration implements Parcelable { return Arrays.equals(mLux, other.mLux) && Arrays.equals(mNits, other.mNits) && mCorrectionsByPackageName.equals(other.mCorrectionsByPackageName) && mCorrectionsByCategory.equals(other.mCorrectionsByCategory) - && Objects.equals(mDescription, other.mDescription); + && Objects.equals(mDescription, other.mDescription) + && mShouldCollectColorSamples == other.mShouldCollectColorSamples; } public static final @android.annotation.NonNull Creator<BrightnessConfiguration> CREATOR = @@ -224,6 +241,8 @@ public final class BrightnessConfiguration implements Parcelable { final String description = in.readString(); builder.setDescription(description); + final boolean shouldCollectColorSamples = in.readBoolean(); + builder.setShouldCollectColorSamples(shouldCollectColorSamples); return builder.build(); } @@ -252,6 +271,7 @@ public final class BrightnessConfiguration implements Parcelable { serializer.endTag(null, TAG_BRIGHTNESS_POINT); } serializer.endTag(null, TAG_BRIGHTNESS_CURVE); + serializer.startTag(null, TAG_BRIGHTNESS_CORRECTIONS); for (Map.Entry<String, BrightnessCorrection> entry : mCorrectionsByPackageName.entrySet()) { @@ -271,6 +291,12 @@ public final class BrightnessConfiguration implements Parcelable { serializer.endTag(null, TAG_BRIGHTNESS_CORRECTION); } serializer.endTag(null, TAG_BRIGHTNESS_CORRECTIONS); + + serializer.startTag(null, TAG_BRIGHTNESS_PARAMS); + if (mShouldCollectColorSamples) { + serializer.attribute(null, ATTR_COLLECT_COLOR, Boolean.toString(true)); + } + serializer.endTag(null, TAG_BRIGHTNESS_PARAMS); } /** @@ -293,6 +319,7 @@ public final class BrightnessConfiguration implements Parcelable { List<Float> nitsList = new ArrayList<>(); Map<String, BrightnessCorrection> correctionsByPackageName = new HashMap<>(); Map<Integer, BrightnessCorrection> correctionsByCategory = new HashMap<>(); + boolean shouldCollectColorSamples = false; final int configDepth = parser.getDepth(); while (XmlUtils.nextElementWithin(parser, configDepth)) { if (TAG_BRIGHTNESS_CURVE.equals(parser.getName())) { @@ -307,8 +334,7 @@ public final class BrightnessConfiguration implements Parcelable { luxList.add(lux); nitsList.add(nits); } - } - if (TAG_BRIGHTNESS_CORRECTIONS.equals(parser.getName())) { + } else if (TAG_BRIGHTNESS_CORRECTIONS.equals(parser.getName())) { final int correctionsDepth = parser.getDepth(); while (XmlUtils.nextElementWithin(parser, correctionsDepth)) { if (!TAG_BRIGHTNESS_CORRECTION.equals(parser.getName())) { @@ -328,6 +354,9 @@ public final class BrightnessConfiguration implements Parcelable { } } } + } else if (TAG_BRIGHTNESS_PARAMS.equals(parser.getName())) { + shouldCollectColorSamples = + Boolean.parseBoolean(parser.getAttributeValue(null, ATTR_COLLECT_COLOR)); } } final int n = luxList.size(); @@ -350,6 +379,7 @@ public final class BrightnessConfiguration implements Parcelable { final BrightnessCorrection correction = entry.getValue(); builder.addCorrectionByCategory(category, correction); } + builder.setShouldCollectColorSamples(shouldCollectColorSamples); return builder.build(); } @@ -374,6 +404,7 @@ public final class BrightnessConfiguration implements Parcelable { private Map<String, BrightnessCorrection> mCorrectionsByPackageName; private Map<Integer, BrightnessCorrection> mCorrectionsByCategory; private String mDescription; + private boolean mShouldCollectColorSamples; /** * Constructs the builder with the control points for the brightness curve. @@ -498,6 +529,19 @@ public final class BrightnessConfiguration implements Parcelable { } /** + * Control whether screen color samples should be returned in + * {@link BrightnessChangeEvent#colorValueBuckets} if supported by the device. + * + * @param shouldCollectColorSamples true if color samples should be collected. + * @return + */ + @NonNull + public Builder setShouldCollectColorSamples(boolean shouldCollectColorSamples) { + mShouldCollectColorSamples = shouldCollectColorSamples; + return this; + } + + /** * Builds the {@link BrightnessConfiguration}. */ @NonNull @@ -506,7 +550,7 @@ public final class BrightnessConfiguration implements Parcelable { throw new IllegalStateException("A curve must be set!"); } return new BrightnessConfiguration(mCurveLux, mCurveNits, mCorrectionsByPackageName, - mCorrectionsByCategory, mDescription); + mCorrectionsByCategory, mDescription, mShouldCollectColorSamples); } private static void checkMonotonic(float[] vals, boolean strictlyIncreasing, String name) { diff --git a/core/java/android/net/StaticIpConfiguration.java b/core/java/android/net/StaticIpConfiguration.java index 5bc9953e0d05..990c1142284c 100644 --- a/core/java/android/net/StaticIpConfiguration.java +++ b/core/java/android/net/StaticIpConfiguration.java @@ -25,6 +25,8 @@ import android.net.shared.InetAddressUtils; import android.os.Parcel; import android.os.Parcelable; +import com.android.internal.util.Preconditions; + import java.net.InetAddress; import java.util.ArrayList; import java.util.List; @@ -152,6 +154,7 @@ public final class StaticIpConfiguration implements Parcelable { * @return The {@link Builder} for chaining. */ public @NonNull Builder setDnsServers(@NonNull Iterable<InetAddress> dnsServers) { + Preconditions.checkNotNull(dnsServers); mDnsServers = dnsServers; return this; } @@ -175,8 +178,10 @@ public final class StaticIpConfiguration implements Parcelable { final StaticIpConfiguration config = new StaticIpConfiguration(); config.ipAddress = mIpAddress; config.gateway = mGateway; - for (InetAddress server : mDnsServers) { - config.dnsServers.add(server); + if (mDnsServers != null) { + for (InetAddress server : mDnsServers) { + config.dnsServers.add(server); + } } config.domains = mDomains; return config; diff --git a/core/java/android/net/util/MultinetworkPolicyTracker.java b/core/java/android/net/util/MultinetworkPolicyTracker.java index 4e88149b8095..aa0f6220036c 100644 --- a/core/java/android/net/util/MultinetworkPolicyTracker.java +++ b/core/java/android/net/util/MultinetworkPolicyTracker.java @@ -94,7 +94,8 @@ public class MultinetworkPolicyTracker { } }; - TelephonyManager.from(ctx).listen(new PhoneStateListener(handler.getLooper()) { + ctx.getSystemService(TelephonyManager.class).listen( + new PhoneStateListener(handler.getLooper()) { @Override public void onActiveDataSubscriptionIdChanged(int subId) { mActiveSubId = subId; diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java index ed21b7200707..bb62eb25b1a4 100644 --- a/core/java/android/os/UserManager.java +++ b/core/java/android/os/UserManager.java @@ -1359,8 +1359,11 @@ public class UserManager { mContext.getContentResolver(), Settings.Global.ALLOW_USER_SWITCHING_WHEN_SYSTEM_USER_LOCKED, 0) != 0; boolean isSystemUserUnlocked = isUserUnlocked(UserHandle.SYSTEM); - boolean inCall = TelephonyManager.getDefault().getCallState() - != TelephonyManager.CALL_STATE_IDLE; + boolean inCall = false; + TelephonyManager telephonyManager = mContext.getSystemService(TelephonyManager.class); + if (telephonyManager != null) { + inCall = telephonyManager.getCallState() != TelephonyManager.CALL_STATE_IDLE; + } boolean isUserSwitchDisallowed = hasUserRestriction(DISALLOW_USER_SWITCH); return (allowUserSwitchingWhenSystemUserLocked || isSystemUserUnlocked) && !inCall && !isUserSwitchDisallowed; diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java index ac7a0a8d8b5c..deeeddc5fb71 100644 --- a/core/java/android/os/storage/StorageManager.java +++ b/core/java/android/os/storage/StorageManager.java @@ -1645,10 +1645,10 @@ public class StorageManager { * Check that given app holds both permission and appop. * @hide */ - public static boolean checkPermissionAndAppOp(Context context, boolean enforce, - int pid, int uid, String packageName, String permission, int op) { - return checkPermissionAndAppOp(context, enforce, pid, uid, packageName, permission, op, - true); + public static boolean checkPermissionAndAppOp(Context context, boolean enforce, int pid, + int uid, String packageName, @NonNull String featureId, String permission, int op) { + return checkPermissionAndAppOp(context, enforce, pid, uid, packageName, featureId, + permission, op, true); } /** @@ -1657,16 +1657,17 @@ public class StorageManager { */ public static boolean checkPermissionAndCheckOp(Context context, boolean enforce, int pid, int uid, String packageName, String permission, int op) { - return checkPermissionAndAppOp(context, enforce, pid, uid, packageName, permission, op, - false); + return checkPermissionAndAppOp(context, enforce, pid, uid, packageName, + null /* featureId is not needed when not noting */, permission, op, false); } /** * Check that given app holds both permission and appop. * @hide */ - private static boolean checkPermissionAndAppOp(Context context, boolean enforce, - int pid, int uid, String packageName, String permission, int op, boolean note) { + private static boolean checkPermissionAndAppOp(Context context, boolean enforce, int pid, + int uid, String packageName, @Nullable String featureId, String permission, int op, + boolean note) { if (context.checkPermission(permission, pid, uid) != PERMISSION_GRANTED) { if (enforce) { throw new SecurityException( @@ -1679,7 +1680,7 @@ public class StorageManager { AppOpsManager appOps = context.getSystemService(AppOpsManager.class); final int mode; if (note) { - mode = appOps.noteOpNoThrow(op, uid, packageName); + mode = appOps.noteOpNoThrow(op, uid, packageName, featureId, null); } else { try { appOps.checkPackage(uid, packageName); @@ -1711,14 +1712,15 @@ public class StorageManager { } } - private boolean checkPermissionAndAppOp(boolean enforce, - int pid, int uid, String packageName, String permission, int op) { - return checkPermissionAndAppOp(mContext, enforce, pid, uid, packageName, permission, op); + private boolean checkPermissionAndAppOp(boolean enforce, int pid, int uid, String packageName, + @Nullable String featureId, String permission, int op) { + return checkPermissionAndAppOp(mContext, enforce, pid, uid, packageName, featureId, + permission, op); } private boolean noteAppOpAllowingLegacy(boolean enforce, - int pid, int uid, String packageName, int op) { - final int mode = mAppOps.noteOpNoThrow(op, uid, packageName); + int pid, int uid, String packageName, @Nullable String featureId, int op) { + final int mode = mAppOps.noteOpNoThrow(op, uid, packageName, featureId, null); switch (mode) { case AppOpsManager.MODE_ALLOWED: return true; @@ -1749,50 +1751,68 @@ public class StorageManager { /** {@hide} */ public boolean checkPermissionReadAudio(boolean enforce, - int pid, int uid, String packageName) { - if (!checkPermissionAndAppOp(enforce, pid, uid, packageName, - READ_EXTERNAL_STORAGE, OP_READ_EXTERNAL_STORAGE)) return false; - return noteAppOpAllowingLegacy(enforce, pid, uid, packageName, OP_READ_MEDIA_AUDIO); + int pid, int uid, String packageName, @Nullable String featureId) { + if (!checkPermissionAndAppOp(enforce, pid, uid, packageName, featureId, + READ_EXTERNAL_STORAGE, OP_READ_EXTERNAL_STORAGE)) { + return false; + } + return noteAppOpAllowingLegacy(enforce, pid, uid, packageName, featureId, + OP_READ_MEDIA_AUDIO); } /** {@hide} */ public boolean checkPermissionWriteAudio(boolean enforce, - int pid, int uid, String packageName) { - if (!checkPermissionAndAppOp(enforce, pid, uid, packageName, - WRITE_EXTERNAL_STORAGE, OP_WRITE_EXTERNAL_STORAGE)) return false; - return noteAppOpAllowingLegacy(enforce, pid, uid, packageName, OP_WRITE_MEDIA_AUDIO); + int pid, int uid, String packageName, @Nullable String featureId) { + if (!checkPermissionAndAppOp(enforce, pid, uid, packageName, featureId, + WRITE_EXTERNAL_STORAGE, OP_WRITE_EXTERNAL_STORAGE)) { + return false; + } + return noteAppOpAllowingLegacy(enforce, pid, uid, packageName, featureId, + OP_WRITE_MEDIA_AUDIO); } /** {@hide} */ public boolean checkPermissionReadVideo(boolean enforce, - int pid, int uid, String packageName) { - if (!checkPermissionAndAppOp(enforce, pid, uid, packageName, - READ_EXTERNAL_STORAGE, OP_READ_EXTERNAL_STORAGE)) return false; - return noteAppOpAllowingLegacy(enforce, pid, uid, packageName, OP_READ_MEDIA_VIDEO); + int pid, int uid, String packageName, @Nullable String featureId) { + if (!checkPermissionAndAppOp(enforce, pid, uid, packageName, featureId, + READ_EXTERNAL_STORAGE, OP_READ_EXTERNAL_STORAGE)) { + return false; + } + return noteAppOpAllowingLegacy(enforce, pid, uid, packageName, featureId, + OP_READ_MEDIA_VIDEO); } /** {@hide} */ public boolean checkPermissionWriteVideo(boolean enforce, - int pid, int uid, String packageName) { - if (!checkPermissionAndAppOp(enforce, pid, uid, packageName, - WRITE_EXTERNAL_STORAGE, OP_WRITE_EXTERNAL_STORAGE)) return false; - return noteAppOpAllowingLegacy(enforce, pid, uid, packageName, OP_WRITE_MEDIA_VIDEO); + int pid, int uid, String packageName, @Nullable String featureId) { + if (!checkPermissionAndAppOp(enforce, pid, uid, packageName, featureId, + WRITE_EXTERNAL_STORAGE, OP_WRITE_EXTERNAL_STORAGE)) { + return false; + } + return noteAppOpAllowingLegacy(enforce, pid, uid, packageName, featureId, + OP_WRITE_MEDIA_VIDEO); } /** {@hide} */ public boolean checkPermissionReadImages(boolean enforce, - int pid, int uid, String packageName) { - if (!checkPermissionAndAppOp(enforce, pid, uid, packageName, - READ_EXTERNAL_STORAGE, OP_READ_EXTERNAL_STORAGE)) return false; - return noteAppOpAllowingLegacy(enforce, pid, uid, packageName, OP_READ_MEDIA_IMAGES); + int pid, int uid, String packageName, @Nullable String featureId) { + if (!checkPermissionAndAppOp(enforce, pid, uid, packageName, featureId, + READ_EXTERNAL_STORAGE, OP_READ_EXTERNAL_STORAGE)) { + return false; + } + return noteAppOpAllowingLegacy(enforce, pid, uid, packageName, featureId, + OP_READ_MEDIA_IMAGES); } /** {@hide} */ public boolean checkPermissionWriteImages(boolean enforce, - int pid, int uid, String packageName) { - if (!checkPermissionAndAppOp(enforce, pid, uid, packageName, - WRITE_EXTERNAL_STORAGE, OP_WRITE_EXTERNAL_STORAGE)) return false; - return noteAppOpAllowingLegacy(enforce, pid, uid, packageName, OP_WRITE_MEDIA_IMAGES); + int pid, int uid, String packageName, @Nullable String featureId) { + if (!checkPermissionAndAppOp(enforce, pid, uid, packageName, featureId, + WRITE_EXTERNAL_STORAGE, OP_WRITE_EXTERNAL_STORAGE)) { + return false; + } + return noteAppOpAllowingLegacy(enforce, pid, uid, packageName, featureId, + OP_WRITE_MEDIA_IMAGES); } /** {@hide} */ diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 50dac46d0597..3ac7deb0db08 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -14099,6 +14099,77 @@ public final class Settings { "android.settings.panel.action.VOLUME"; } + /** + * Activity Action: Show setting page to process the addition of Wi-Fi networks to the user's + * saved network list. The app should send a new intent with an extra that holds a maximum of + * five {@link android.net.wifi.WifiConfiguration} that specify credentials for the networks to + * be added to the user's database. The Intent should be sent via the {@link + * android.app.Activity#startActivityForResult(Intent, int)} API. + * <p> + * Note: The app sending the Intent to add the credentials doesn't get any ownership over the + * newly added network(s). For the Wi-Fi stack, these networks will look like the user + * manually added them from the Settings UI. + * <p> + * Input: The app should put parcelable array list to + * {@link android.net.wifi.WifiConfiguration} into the + * {@link #EXTRA_WIFI_CONFIGURATION_LIST} extra. + * <p> + * Output: After {@link android.app.Activity#startActivityForResult(Intent, int)}, the + * callback {@link android.app.Activity#onActivityResult(int, int, Intent)} will have a + * result code {@link android.app.Activity#RESULT_OK} to indicate user pressed the save + * button to save the networks or {@link android.app.Activity#RESULT_CANCELED} to indicate + * that the user rejected the request. Additionally, an integer array list, stored in + * {@link #EXTRA_WIFI_CONFIGURATION_RESULT_LIST}, will indicate the process result of + * each network. + */ + @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) + public static final String ACTION_WIFI_ADD_NETWORKS = + "android.settings.WIFI_ADD_NETWORKS"; + + /** + * A bundle extra of {@link #ACTION_WIFI_ADD_NETWORKS} intent action that indicates all the + * {@link android.net.wifi.WifiConfiguration} that would be saved. + */ + public static final String EXTRA_WIFI_CONFIGURATION_LIST = + "android.provider.extra.WIFI_CONFIGURATION_LIST"; + + /** + * A bundle extra of the result of {@link #ACTION_WIFI_ADD_NETWORKS} intent action that + * indicates the action result of the saved {@link android.net.wifi.WifiConfiguration}. It's + * value of AddWifiResult interface, and will be 1:1 mapping to the element in {@link + * #EXTRA_WIFI_CONFIGURATION_LIST}. + */ + public static final String EXTRA_WIFI_CONFIGURATION_RESULT_LIST = + "android.provider.extra.WIFI_CONFIGURATION_RESULT_LIST"; + + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = {"ADD_WIFI_RESULT_"}, value = { + ADD_WIFI_RESULT_SUCCESS, + ADD_WIFI_RESULT_ADD_OR_UPDATE_FAILED, + ADD_WIFI_RESULT_ALREADY_EXISTS + }) + public @interface AddWifiResult { + } + + /** + * A result of {@link #ACTION_WIFI_ADD_NETWORKS} intent action that saving or updating the + * corresponding Wi-Fi network was successful. + */ + public static final int ADD_WIFI_RESULT_SUCCESS = 0; + + /** + * A result of {@link #ACTION_WIFI_ADD_NETWORKS} intent action that saving the corresponding + * Wi-Fi network failed. + */ + public static final int ADD_WIFI_RESULT_ADD_OR_UPDATE_FAILED = 1; + + /** + * A result of {@link #ACTION_WIFI_ADD_NETWORKS} intent action that indicates the Wi-Fi network + * already exists. + */ + public static final int ADD_WIFI_RESULT_ALREADY_EXISTS = 2; + private static final String[] PM_WRITE_SETTINGS = { android.Manifest.permission.WRITE_SETTINGS }; diff --git a/core/java/com/android/internal/app/LocaleStore.java b/core/java/com/android/internal/app/LocaleStore.java index c11089ba19bd..49f77e11cf80 100644 --- a/core/java/com/android/internal/app/LocaleStore.java +++ b/core/java/com/android/internal/app/LocaleStore.java @@ -194,7 +194,7 @@ public class LocaleStore { private static Set<String> getSimCountries(Context context) { Set<String> result = new HashSet<>(); - TelephonyManager tm = TelephonyManager.from(context); + TelephonyManager tm = context.getSystemService(TelephonyManager.class); if (tm != null) { String iso = tm.getSimCountryIso().toUpperCase(Locale.US); diff --git a/core/java/com/android/internal/compat/IPlatformCompat.aidl b/core/java/com/android/internal/compat/IPlatformCompat.aidl index 5857642cbd4e..045a6800bb13 100644 --- a/core/java/com/android/internal/compat/IPlatformCompat.aidl +++ b/core/java/com/android/internal/compat/IPlatformCompat.aidl @@ -133,7 +133,7 @@ interface IPlatformCompat boolean isChangeEnabledByUid(long changeId, int uid); /** - * Add overrides to compatibility changes. + * Add overrides to compatibility changes. Kills the app to allow the changes to take effect. * * @param overrides Parcelable containing the compat change overrides to be applied. * @param packageName The package name of the app whose changes will be overridden. @@ -142,7 +142,28 @@ interface IPlatformCompat void setOverrides(in CompatibilityChangeConfig overrides, in String packageName); /** - * Revert overrides to compatibility changes. + * Add overrides to compatibility changes. Doesn't kill the app, to be only used in tests. + * + * @param overrides Parcelable containing the compat change overrides to be applied. + * @param packageName The package name of the app whose changes will be overridden. + * + */ + void setOverridesForTest(in CompatibilityChangeConfig overrides, in String packageName); + + /** + * Removes an override previously added via {@link #setOverrides(CompatibilityChangeConfig, + * String)}. This restores the default behaviour for the given change and app, once any app + * processes have been restarted. + * Kills the app to allow the changes to take effect. + * + * @param changeId The ID of the change that was overridden. + * @param packageName The app package name that was overridden. + * @return {@code true} if an override existed; + */ + boolean clearOverride(long changeId, String packageName); + + /** + * Revert overrides to compatibility changes. Kills the app to allow the changes to take effect. * * @param packageName The package name of the app whose overrides will be cleared. * diff --git a/core/java/com/android/internal/package-info.java b/core/java/com/android/internal/package-info.java new file mode 100644 index 000000000000..8a226dbdc9fe --- /dev/null +++ b/core/java/com/android/internal/package-info.java @@ -0,0 +1,4 @@ +/** + * @hide + */ +package com.android.internal; diff --git a/core/java/com/android/internal/util/ScreenshotHelper.java b/core/java/com/android/internal/util/ScreenshotHelper.java index cac691cf7d45..f6f187fd27c5 100644 --- a/core/java/com/android/internal/util/ScreenshotHelper.java +++ b/core/java/com/android/internal/util/ScreenshotHelper.java @@ -6,6 +6,7 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; +import android.net.Uri; import android.os.Handler; import android.os.IBinder; import android.os.Message; @@ -58,7 +59,7 @@ public class ScreenshotHelper { */ public void takeScreenshot(final int screenshotType, final boolean hasStatus, final boolean hasNav, @NonNull Handler handler, - @Nullable Consumer<Boolean> completionConsumer) { + @Nullable Consumer<Uri> completionConsumer) { takeScreenshot(screenshotType, hasStatus, hasNav, SCREENSHOT_TIMEOUT_MS, handler, completionConsumer); } @@ -88,7 +89,7 @@ public class ScreenshotHelper { */ public void takeScreenshot(final int screenshotType, final boolean hasStatus, final boolean hasNav, long timeoutMs, @NonNull Handler handler, - @Nullable Consumer<Boolean> completionConsumer) { + @Nullable Consumer<Uri> completionConsumer) { synchronized (mScreenshotLock) { if (mScreenshotConnection != null) { return; @@ -108,7 +109,7 @@ public class ScreenshotHelper { } } if (completionConsumer != null) { - completionConsumer.accept(false); + completionConsumer.accept(null); } } }; @@ -135,7 +136,7 @@ public class ScreenshotHelper { } } if (completionConsumer != null) { - completionConsumer.accept(true); + completionConsumer.accept((Uri) msg.obj); } } }; @@ -148,7 +149,7 @@ public class ScreenshotHelper { } catch (RemoteException e) { Log.e(TAG, "Couldn't take screenshot: " + e); if (completionConsumer != null) { - completionConsumer.accept(false); + completionConsumer.accept(null); } } } diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 9f77407b2391..e1ca1f6f346c 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -142,7 +142,7 @@ <protected-broadcast android:name="android.bluetooth.adapter.action.CONNECTION_STATE_CHANGED" /> <protected-broadcast android:name="android.bluetooth.device.action.UUID" /> <protected-broadcast android:name="android.bluetooth.device.action.MAS_INSTANCE" /> - <protected-broadcast android:name="android.bluetooth.device.action.ALIAS_CHANGED" /> + <protected-broadcast android:name="android.bluetooth.action.ALIAS_CHANGED" /> <protected-broadcast android:name="android.bluetooth.device.action.FOUND" /> <protected-broadcast android:name="android.bluetooth.device.action.CLASS_CHANGED" /> <protected-broadcast android:name="android.bluetooth.device.action.ACL_CONNECTED" /> @@ -375,7 +375,7 @@ <protected-broadcast android:name="android.net.wifi.p2p.THIS_DEVICE_CHANGED" /> <protected-broadcast android:name="android.net.wifi.p2p.PEERS_CHANGED" /> <protected-broadcast android:name="android.net.wifi.p2p.CONNECTION_STATE_CHANGE" /> - <protected-broadcast android:name="android.net.wifi.p2p.PERSISTENT_GROUPS_CHANGED" /> + <protected-broadcast android:name="android.net.wifi.p2p.action.WIFI_P2P_PERSISTENT_GROUPS_CHANGED" /> <protected-broadcast android:name="android.net.conn.TETHER_STATE_CHANGED" /> <protected-broadcast android:name="android.net.conn.INET_CONDITION_ACTION" /> <protected-broadcast android:name="android.net.conn.NETWORK_CONDITIONS_MEASURED" /> @@ -660,7 +660,6 @@ android:icon="@drawable/perm_group_contacts" android:label="@string/permgrouplab_contacts" android:description="@string/permgroupdesc_contacts" - android:request="@string/permgrouprequest_contacts" android:priority="100" /> <!-- Allows an application to read the user's contacts data. @@ -691,7 +690,6 @@ android:icon="@drawable/perm_group_calendar" android:label="@string/permgrouplab_calendar" android:description="@string/permgroupdesc_calendar" - android:request="@string/permgrouprequest_calendar" android:priority="200" /> <!-- Allows an application to read the user's calendar data. @@ -722,7 +720,6 @@ android:icon="@drawable/perm_group_sms" android:label="@string/permgrouplab_sms" android:description="@string/permgroupdesc_sms" - android:request="@string/permgrouprequest_sms" android:priority="300" /> <!-- Allows an application to send SMS messages. @@ -841,7 +838,6 @@ android:icon="@drawable/perm_group_storage" android:label="@string/permgrouplab_storage" android:description="@string/permgroupdesc_storage" - android:request="@string/permgrouprequest_storage" android:priority="900" /> <!-- Allows an application to read from external storage. @@ -930,10 +926,6 @@ android:icon="@drawable/perm_group_location" android:label="@string/permgrouplab_location" android:description="@string/permgroupdesc_location" - android:request="@string/permgrouprequest_location" - android:requestDetail="@string/permgrouprequestdetail_location" - android:backgroundRequest="@string/permgroupbackgroundrequest_location" - android:backgroundRequestDetail="@string/permgroupbackgroundrequestdetail_location" android:priority="400" /> <!-- Allows an app to access precise location. @@ -985,7 +977,6 @@ android:icon="@drawable/perm_group_call_log" android:label="@string/permgrouplab_calllog" android:description="@string/permgroupdesc_calllog" - android:request="@string/permgrouprequest_calllog" android:priority="450" /> <!-- Allows an application to access the IMS call service: making and @@ -1074,7 +1065,6 @@ android:icon="@drawable/perm_group_phone_calls" android:label="@string/permgrouplab_phone" android:description="@string/permgroupdesc_phone" - android:request="@string/permgrouprequest_phone" android:priority="500" /> <!-- Allows read only access to phone state, including the phone number of the device, @@ -1195,7 +1185,6 @@ android:icon="@drawable/perm_group_microphone" android:label="@string/permgrouplab_microphone" android:description="@string/permgroupdesc_microphone" - android:request="@string/permgrouprequest_microphone" android:priority="600" /> <!-- Allows an application to record audio. @@ -1217,7 +1206,6 @@ android:icon="@drawable/perm_group_activity_recognition" android:label="@string/permgrouplab_activityRecognition" android:description="@string/permgroupdesc_activityRecognition" - android:request="@string/permgrouprequest_activityRecognition" android:priority="1000" /> <!-- Allows an application to recognize physical activity. @@ -1260,7 +1248,6 @@ android:icon="@drawable/perm_group_camera" android:label="@string/permgrouplab_camera" android:description="@string/permgroupdesc_camera" - android:request="@string/permgrouprequest_camera" android:priority="700" /> <!-- Required to be able to access the camera device. @@ -1299,7 +1286,6 @@ android:icon="@drawable/perm_group_sensors" android:label="@string/permgrouplab_sensors" android:description="@string/permgroupdesc_sensors" - android:request="@string/permgrouprequest_sensors" android:priority="800" /> <!-- Allows an application to access data from sensors that the user uses to @@ -1615,6 +1601,7 @@ <!-- Allows network stack services (Connectivity and Wifi) to coordinate <p>Not for use by third-party or privileged applications. + @SystemApi @hide This should only be used by Connectivity and Wifi Services. --> <permission android:name="android.permission.NETWORK_STACK" @@ -1622,6 +1609,7 @@ <!-- Allows Settings and SystemUI to call methods in Networking services <p>Not for use by third-party or privileged applications. + @SystemApi @hide This should only be used by Settings and SystemUI. --> <permission android:name="android.permission.NETWORK_SETTINGS" @@ -3583,7 +3571,8 @@ android:protectionLevel="signature" /> <!-- Allows an application to configure and connect to Wifi displays - @hide --> + @hide + @SystemApi --> <permission android:name="android.permission.CONFIGURE_WIFI_DISPLAY" android:protectionLevel="signature" /> diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index 42e62d740edd..22b5707143c0 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -704,96 +704,57 @@ <string name="permgrouplab_contacts">Contacts</string> <!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. --> <string name="permgroupdesc_contacts">access your contacts</string> - <!-- Message shown to the user when the apps requests permission from this group. If ever possible this should stay below 80 characters (assuming the parameters takes 20 characters). Don't abbreviate until the message reaches 120 characters though. [CHAR LIMIT=120] --> - <string name="permgrouprequest_contacts">Allow - <b><xliff:g id="app_name" example="Gmail">%1$s</xliff:g></b> to access your contacts?</string> <!-- Title of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. --> <string name="permgrouplab_location">Location</string> <!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. --> <string name="permgroupdesc_location">access this device\'s location</string> - <!-- Message shown to the user when the apps requests permission from this group. If ever possible this should stay below 80 characters (assuming the parameters takes 20 characters). Don't abbreviate until the message reaches 120 characters though. [CHAR LIMIT=120] --> - <string name="permgrouprequest_location">Allow - <b><xliff:g id="app_name" example="Gmail">%1$s</xliff:g></b> to access this device\'s location?</string> - <!-- Subtitle of the message shown to the user when the apps requests permission to use the location only while app is in foreground [CHAR LIMIT=150]--> - <string name="permgrouprequestdetail_location">The app will only have access to the location while you\u2019re using the app</string> - <!-- Message shown to the user when the apps requests permission to use the location while app is in foreground and background. If ever possible this should stay below 80 characters (assuming the parameters takes 20 characters). Don't abbreviate until the message reaches 120 characters though. [CHAR LIMIT=120] --> - <string name="permgroupbackgroundrequest_location">Allow - <b><xliff:g id="app_name" example="Gmail">%1$s</xliff:g></b> to access this device\u2019s location <b>all the time</b>?</string> - <!-- Subtitle of the message shown to the user when the apps requests permission to use the location while app is in foreground and background. Try to keep the link annotation at the end of the string [CHAR LIMIT=150] --> - <string name="permgroupbackgroundrequestdetail_location">This app may want to access your location all the time, even when you\u2019re not using the app. Allow in <annotation id="link">settings</annotation>.</string> <!-- Title of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. --> <string name="permgrouplab_calendar">Calendar</string> <!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. --> <string name="permgroupdesc_calendar">access your calendar</string> - <!-- Message shown to the user when the apps requests permission from this group. If ever possible this should stay below 80 characters (assuming the parameters takes 20 characters). Don't abbreviate until the message reaches 120 characters though. [CHAR LIMIT=120] --> - <string name="permgrouprequest_calendar">Allow - <b><xliff:g id="app_name" example="Gmail">%1$s</xliff:g></b> to access your calendar?</string> <!-- Title of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. --> <string name="permgrouplab_sms">SMS</string> <!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. --> <string name="permgroupdesc_sms">send and view SMS messages</string> - <!-- Message shown to the user when the apps requests permission from this group. If ever possible this should stay below 80 characters (assuming the parameters takes 20 characters). Don't abbreviate until the message reaches 120 characters though. [CHAR LIMIT=120] --> - <string name="permgrouprequest_sms">Allow - <b><xliff:g id="app_name" example="Gmail">%1$s</xliff:g></b> to send and view SMS messages?</string> <!-- Title of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. --> <string name="permgrouplab_storage">Storage</string> <!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. --> <string name="permgroupdesc_storage">access photos, media, and files on your device</string> - <!-- Message shown to the user when the apps requests permission from this group. If ever possible this should stay below 80 characters (assuming the parameters takes 20 characters). Don't abbreviate until the message reaches 120 characters though. [CHAR LIMIT=120] --> - <string name="permgrouprequest_storage">Allow - <b><xliff:g id="app_name" example="Gmail">%1$s</xliff:g></b> to access photos, media, and files on your device?</string> <!-- Title of a category of application permissioncds, listed so the user can choose whether they want to allow the application to do this. --> <string name="permgrouplab_microphone">Microphone</string> <!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. --> <string name="permgroupdesc_microphone">record audio</string> - <!-- Message shown to the user when the apps requests permission from this group. If ever possible this should stay below 80 characters (assuming the parameters takes 20 characters). Don't abbreviate until the message reaches 120 characters though. [CHAR LIMIT=120] --> - <string name="permgrouprequest_microphone">Allow - <b><xliff:g id="app_name" example="Gmail">%1$s</xliff:g></b> to record audio?</string> <!-- Title of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. [CHAR LIMIT=40]--> <string name="permgrouplab_activityRecognition">Physical activity</string> <!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. [CHAR LIMIT=40]--> <string name="permgroupdesc_activityRecognition">access your physical activity</string> - <!-- Message shown to the user when the apps requests permission from this group. If ever possible this should stay below 80 characters (assuming the parameters takes 20 characters). Don't abbreviate until the message reaches 120 characters though. [CHAR LIMIT=120] --> - <string name="permgrouprequest_activityRecognition">Allow - <b><xliff:g id="app_name" example="Gmail">%1$s</xliff:g></b> to access your physical activity?</string> <!-- Title of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. --> <string name="permgrouplab_camera">Camera</string> <!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. --> <string name="permgroupdesc_camera">take pictures and record video</string> - <!-- Message shown to the user when the apps requests permission from this group. If ever possible this should stay below 80 characters (assuming the parameters takes 20 characters). Don't abbreviate until the message reaches 120 characters though. [CHAR LIMIT=120] --> - <string name="permgrouprequest_camera">Allow - <b><xliff:g id="app_name" example="Gmail">%1$s</xliff:g></b> to take pictures and record video?</string> <!-- Title of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. --> <string name="permgrouplab_calllog">Call logs</string> <!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. --> <string name="permgroupdesc_calllog">read and write phone call log</string> - <!-- Message shown to the user when the apps requests permission from this group. If ever possible this should stay below 80 characters (assuming the parameters takes 20 characters). Don't abbreviate until the message reaches 120 characters though. [CHAR LIMIT=120] --> - <string name="permgrouprequest_calllog">Allow - <b><xliff:g id="app_name" example="Gmail">%1$s</xliff:g></b> to access your phone call logs?</string> <!-- Title of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. --> <string name="permgrouplab_phone">Phone</string> <!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. --> <string name="permgroupdesc_phone">make and manage phone calls</string> <!-- Message shown to the user when the apps requests permission from this group. If ever possible this should stay below 80 characters (assuming the parameters takes 20 characters). Don't abbreviate until the message reaches 120 characters though. [CHAR LIMIT=120] --> - <string name="permgrouprequest_phone">Allow - <b><xliff:g id="app_name" example="Gmail">%1$s</xliff:g></b> to make and manage phone calls?</string> <!-- Title of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. --> <string name="permgrouplab_sensors">Body sensors</string> <!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. --> <string name="permgroupdesc_sensors">access sensor data about your vital signs</string> - <!-- Message shown to the user when the apps requests permission from this group. If ever possible this should stay below 80 characters (assuming the parameters takes 20 characters). Don't abbreviate until the message reaches 120 characters though. [CHAR LIMIT=120] --> - <string name="permgrouprequest_sensors">Allow - <b><xliff:g id="app_name" example="Gmail">%1$s</xliff:g></b> to access sensor data about your vital signs?</string> <!-- Title for the capability of an accessibility service to retrieve window content. --> <string name="capability_title_canRetrieveWindowContent">Retrieve window content</string> diff --git a/core/tests/coretests/src/android/hardware/display/BrightnessConfigurationTest.java b/core/tests/coretests/src/android/hardware/display/BrightnessConfigurationTest.java index 823fca5a68ad..85aa1184c501 100644 --- a/core/tests/coretests/src/android/hardware/display/BrightnessConfigurationTest.java +++ b/core/tests/coretests/src/android/hardware/display/BrightnessConfigurationTest.java @@ -23,13 +23,23 @@ import static org.junit.Assert.fail; import android.os.Parcel; import android.util.Pair; +import android.util.Xml; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; +import com.android.internal.util.FastXmlSerializer; + import org.junit.Test; import org.junit.runner.RunWith; - +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; +import org.xmlpull.v1.XmlSerializer; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.charset.StandardCharsets; import java.util.Arrays; @SmallTest @@ -104,11 +114,15 @@ public class BrightnessConfigurationTest { }); } - @Test public void testParceledConfigIsEquivalent() { BrightnessConfiguration.Builder builder = new BrightnessConfiguration.Builder(LUX_LEVELS, NITS_LEVELS); + builder.setShouldCollectColorSamples(true); + builder.addCorrectionByCategory(3, + BrightnessCorrection.createScaleAndTranslateLog(1.0f, 2.0f)); + builder.addCorrectionByPackageName("a.package.name", + BrightnessCorrection.createScaleAndTranslateLog(1.0f, 2.0f)); BrightnessConfiguration config = builder.build(); Parcel p = Parcel.obtain(); p.writeParcelable(config, 0 /*flags*/); @@ -119,12 +133,49 @@ public class BrightnessConfigurationTest { } @Test + public void testWriteReadXml() throws IOException, XmlPullParserException { + BrightnessConfiguration.Builder builder = + new BrightnessConfiguration.Builder(LUX_LEVELS, NITS_LEVELS); + builder.setShouldCollectColorSamples(true); + builder.addCorrectionByCategory(3, + BrightnessCorrection.createScaleAndTranslateLog(1.0f, 2.0f)); + builder.addCorrectionByPackageName("a.package.name", + BrightnessCorrection.createScaleAndTranslateLog(1.0f, 2.0f)); + BrightnessConfiguration config = builder.build(); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + XmlSerializer out = new FastXmlSerializer(); + out.setOutput(baos, StandardCharsets.UTF_8.name()); + out.startDocument(null, true); + config.saveToXml(out); + out.endDocument(); + baos.flush(); + + ByteArrayInputStream input = new ByteArrayInputStream(baos.toByteArray()); + XmlPullParser parser = Xml.newPullParser(); + parser.setInput(input, StandardCharsets.UTF_8.name()); + BrightnessConfiguration loadedConfig = BrightnessConfiguration.loadFromXml(parser); + + assertEquals(config, loadedConfig); + } + + @Test public void testEquals() { BrightnessConfiguration.Builder builder = new BrightnessConfiguration.Builder(LUX_LEVELS, NITS_LEVELS); + builder.setShouldCollectColorSamples(true); + builder.addCorrectionByCategory(3, + BrightnessCorrection.createScaleAndTranslateLog(1.0f, 2.0f)); + builder.addCorrectionByPackageName("a.package.name", + BrightnessCorrection.createScaleAndTranslateLog(1.0f, 2.0f)); BrightnessConfiguration baseConfig = builder.build(); builder = new BrightnessConfiguration.Builder(LUX_LEVELS, NITS_LEVELS); + builder.setShouldCollectColorSamples(true); + builder.addCorrectionByCategory(3, + BrightnessCorrection.createScaleAndTranslateLog(1.0f, 2.0f)); + builder.addCorrectionByPackageName("a.package.name", + BrightnessCorrection.createScaleAndTranslateLog(1.0f, 2.0f)); BrightnessConfiguration identicalConfig = builder.build(); assertEquals(baseConfig, identicalConfig); assertEquals("hashCodes must be equal for identical configs", @@ -133,14 +184,37 @@ public class BrightnessConfigurationTest { float[] lux = Arrays.copyOf(LUX_LEVELS, LUX_LEVELS.length); lux[lux.length - 1] = lux[lux.length - 1] * 2; builder = new BrightnessConfiguration.Builder(lux, NITS_LEVELS); + builder.setShouldCollectColorSamples(true); + builder.addCorrectionByCategory(3, + BrightnessCorrection.createScaleAndTranslateLog(1.0f, 2.0f)); + builder.addCorrectionByPackageName("a.package.name", + BrightnessCorrection.createScaleAndTranslateLog(1.0f, 2.0f)); BrightnessConfiguration luxDifferConfig = builder.build(); assertNotEquals(baseConfig, luxDifferConfig); float[] nits = Arrays.copyOf(NITS_LEVELS, NITS_LEVELS.length); nits[nits.length - 1] = nits[nits.length - 1] * 2; builder = new BrightnessConfiguration.Builder(LUX_LEVELS, nits); + builder.setShouldCollectColorSamples(true); + builder.addCorrectionByCategory(3, + BrightnessCorrection.createScaleAndTranslateLog(1.0f, 2.0f)); + builder.addCorrectionByPackageName("a.package.name", + BrightnessCorrection.createScaleAndTranslateLog(1.0f, 2.0f)); BrightnessConfiguration nitsDifferConfig = builder.build(); assertNotEquals(baseConfig, nitsDifferConfig); + + builder = new BrightnessConfiguration.Builder(LUX_LEVELS, NITS_LEVELS); + builder.addCorrectionByCategory(3, + BrightnessCorrection.createScaleAndTranslateLog(1.0f, 2.0f)); + builder.addCorrectionByPackageName("a.package.name", + BrightnessCorrection.createScaleAndTranslateLog(1.0f, 2.0f)); + BrightnessConfiguration colorCollectionDiffers = builder.build(); + assertNotEquals(baseConfig, colorCollectionDiffers); + + builder = new BrightnessConfiguration.Builder(LUX_LEVELS, NITS_LEVELS); + builder.setShouldCollectColorSamples(true); + BrightnessConfiguration correctionsDiffer = builder.build(); + assertNotEquals(baseConfig, correctionsDiffer); } private static void assertArrayEquals(float[] expected, float[] actual, String name) { diff --git a/core/tests/screenshothelpertests/src/com/android/internal/util/ScreenshotHelperTest.java b/core/tests/screenshothelpertests/src/com/android/internal/util/ScreenshotHelperTest.java index 848364584ef3..e16d1caa98eb 100644 --- a/core/tests/screenshothelpertests/src/com/android/internal/util/ScreenshotHelperTest.java +++ b/core/tests/screenshothelpertests/src/com/android/internal/util/ScreenshotHelperTest.java @@ -19,7 +19,7 @@ package com.android.internal.util; import static android.view.WindowManager.TAKE_SCREENSHOT_FULLSCREEN; import static android.view.WindowManager.TAKE_SCREENSHOT_SELECTED_REGION; -import static junit.framework.Assert.assertFalse; +import static junit.framework.Assert.assertNull; import static junit.framework.Assert.fail; import static org.mockito.ArgumentMatchers.any; @@ -80,8 +80,8 @@ public final class ScreenshotHelperTest { CountDownLatch lock = new CountDownLatch(1); mScreenshotHelper.takeScreenshot(TAKE_SCREENSHOT_FULLSCREEN, false, false, timeoutMs, mHandler, - worked -> { - assertFalse(worked); + uri -> { + assertNull(uri); lock.countDown(); }); diff --git a/media/java/android/media/tv/OWNER b/media/java/android/media/tv/OWNER deleted file mode 100644 index 64c0bb53e894..000000000000 --- a/media/java/android/media/tv/OWNER +++ /dev/null @@ -1,5 +0,0 @@ -amyjojo@google.com -nchalko@google.com -shubang@google.com -quxiangfang@google.com - diff --git a/media/java/android/media/tv/OWNERS b/media/java/android/media/tv/OWNERS index 4a03b3c6852e..64c0bb53e894 100644 --- a/media/java/android/media/tv/OWNERS +++ b/media/java/android/media/tv/OWNERS @@ -1,2 +1,5 @@ +amyjojo@google.com nchalko@google.com +shubang@google.com +quxiangfang@google.com diff --git a/media/java/android/media/tv/tuner/FrontendSettings.java b/media/java/android/media/tv/tuner/FrontendSettings.java new file mode 100644 index 000000000000..3782cc6c6ec3 --- /dev/null +++ b/media/java/android/media/tv/tuner/FrontendSettings.java @@ -0,0 +1,274 @@ +/* + * 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. + */ + +package android.media.tv.tuner; + +import android.media.tv.tuner.TunerConstants.FrontendSettingsType; + +import java.util.List; + +/** + * @hide + */ +public abstract class FrontendSettings { + protected int mFrequency; + + /** + * Returns the frontend type. + */ + @FrontendSettingsType + public abstract int getType(); + + public int getFrequency() { + return mFrequency; + } + + // TODO: use hal constants for enum fields + // TODO: javaDoc + // TODO: add builders and getters for other settings type + + /** + * Frontend settings for analog. + */ + public static class FrontendAnalogSettings extends FrontendSettings { + private int mAnalogType; + private int mSifStandard; + + @Override + public int getType() { + return TunerConstants.FRONTEND_TYPE_ANALOG; + } + + public int getAnalogType() { + return mAnalogType; + } + + public int getSifStandard() { + return mSifStandard; + } + + /** + * Creates a new builder object. + */ + public static Builder newBuilder() { + return new Builder(); + } + + private FrontendAnalogSettings(int frequency, int analogType, int sifStandard) { + mFrequency = frequency; + mAnalogType = analogType; + mSifStandard = sifStandard; + } + + /** + * Builder for FrontendAnalogSettings. + */ + public static class Builder { + private int mFrequency; + private int mAnalogType; + private int mSifStandard; + + private Builder() {} + + /** + * Sets frequency. + */ + public Builder setFrequency(int frequency) { + mFrequency = frequency; + return this; + } + + /** + * Sets analog type. + */ + public Builder setAnalogType(int analogType) { + mAnalogType = analogType; + return this; + } + + /** + * Sets sif standard. + */ + public Builder setSifStandard(int sifStandard) { + mSifStandard = sifStandard; + return this; + } + + /** + * Builds a FrontendAnalogSettings instance. + */ + public FrontendAnalogSettings build() { + return new FrontendAnalogSettings(mFrequency, mAnalogType, mSifStandard); + } + } + } + + /** + * Frontend settings for ATSC. + */ + public static class FrontendAtscSettings extends FrontendSettings { + public int modulation; + + @Override + public int getType() { + return TunerConstants.FRONTEND_TYPE_ATSC; + } + } + + /** + * Frontend settings for ATSC-3. + */ + public static class FrontendAtsc3Settings extends FrontendSettings { + public int bandwidth; + public byte demodOutputFormat; + public List<FrontendAtsc3PlpSettings> plpSettings; + + @Override + public int getType() { + return TunerConstants.FRONTEND_TYPE_ATSC3; + } + } + + /** + * Frontend settings for DVBS. + */ + public static class FrontendDvbsSettings extends FrontendSettings { + public int modulation; + public FrontendDvbsCodeRate coderate; + public int symbolRate; + public int rolloff; + public int pilot; + public int inputStreamId; + public byte standard; + + @Override + public int getType() { + return TunerConstants.FRONTEND_TYPE_DVBS; + } + } + + /** + * Frontend settings for DVBC. + */ + public static class FrontendDvbcSettings extends FrontendSettings { + public int modulation; + public long fec; + public int symbolRate; + public int outerFec; + public byte annex; + public int spectralInversion; + + @Override + public int getType() { + return TunerConstants.FRONTEND_TYPE_DVBC; + } + } + + /** + * Frontend settings for DVBT. + */ + public static class FrontendDvbtSettings extends FrontendSettings { + public int transmissionMode; + public int bandwidth; + public int constellation; + public int hierarchy; + public int hpCoderate; + public int lpCoderate; + public int guardInterval; + public boolean isHighPriority; + public byte standard; + public boolean isMiso; + public int plpMode; + public byte plpId; + public byte plpGroupId; + + @Override + public int getType() { + return TunerConstants.FRONTEND_TYPE_DVBT; + } + } + + /** + * Frontend settings for ISDBS. + */ + public static class FrontendIsdbsSettings extends FrontendSettings { + public int streamId; + public int streamIdType; + public int modulation; + public int coderate; + public int symbolRate; + public int rolloff; + + @Override + public int getType() { + return TunerConstants.FRONTEND_TYPE_ISDBS; + } + } + + /** + * Frontend settings for ISDBS-3. + */ + public static class FrontendIsdbs3Settings extends FrontendSettings { + public int streamId; + public int streamIdType; + public int modulation; + public int coderate; + public int symbolRate; + public int rolloff; + + @Override + public int getType() { + return TunerConstants.FRONTEND_TYPE_ISDBS3; + } + } + + /** + * Frontend settings for ISDBT. + */ + public static class FrontendIsdbtSettings extends FrontendSettings { + public int modulation; + public int bandwidth; + public int coderate; + public int guardInterval; + public int serviceAreaId; + + @Override + public int getType() { + return TunerConstants.FRONTEND_TYPE_ISDBT; + } + } + + /** + * PLP settings for ATSC-3. + */ + public static class FrontendAtsc3PlpSettings { + public byte plpId; + public int modulation; + public int interleaveMode; + public int codeRate; + public int fec; + } + + /** + * Code rate for DVBS. + */ + public static class FrontendDvbsCodeRate { + public long fec; + public boolean isLinear; + public boolean isShortFrames; + public int bitsPer1000Symbol; + } +} diff --git a/media/java/android/media/tv/tuner/Tuner.java b/media/java/android/media/tv/tuner/Tuner.java index c91325aa9a09..82cef2e43307 100644 --- a/media/java/android/media/tv/tuner/Tuner.java +++ b/media/java/android/media/tv/tuner/Tuner.java @@ -16,6 +16,7 @@ package android.media.tv.tuner; +import android.annotation.NonNull; import android.annotation.Nullable; import android.media.tv.tuner.TunerConstants.DemuxPidType; import android.os.Handler; @@ -78,6 +79,7 @@ public final class Tuner implements AutoCloseable { * Native method to open frontend of the given ID. */ private native Frontend nativeOpenFrontendById(int id); + private native int nativeTune(int type, FrontendSettings settings); private native Filter nativeOpenFilter(int type, int subType, int bufferSize); @@ -207,6 +209,13 @@ public final class Tuner implements AutoCloseable { } } + /** + * Tunes the frontend to using the settings given. + */ + public int tune(@NonNull FrontendSettings settings) { + return nativeTune(settings.getType(), settings); + } + private List<Integer> getFrontendIds() { mFrontendIds = nativeGetFrontendIds(); return mFrontendIds; diff --git a/media/java/android/media/tv/tuner/TunerConstants.java b/media/java/android/media/tv/tuner/TunerConstants.java index 01f9367dd4f3..458cb1678ded 100644 --- a/media/java/android/media/tv/tuner/TunerConstants.java +++ b/media/java/android/media/tv/tuner/TunerConstants.java @@ -75,6 +75,21 @@ final class TunerConstants { public static final int DEMUX_T_PID = 1; public static final int DEMUX_MMPT_PID = 2; + @IntDef({FRONTEND_SETTINGS_ANALOG, FRONTEND_SETTINGS_ATSC, FRONTEND_SETTINGS_ATSC3, + FRONTEND_SETTINGS_DVBS, FRONTEND_SETTINGS_DVBC, FRONTEND_SETTINGS_DVBT, + FRONTEND_SETTINGS_ISDBS, FRONTEND_SETTINGS_ISDBS3, FRONTEND_SETTINGS_ISDBT}) + public @interface FrontendSettingsType {} + + public static final int FRONTEND_SETTINGS_ANALOG = 1; + public static final int FRONTEND_SETTINGS_ATSC = 2; + public static final int FRONTEND_SETTINGS_ATSC3 = 3; + public static final int FRONTEND_SETTINGS_DVBS = 4; + public static final int FRONTEND_SETTINGS_DVBC = 5; + public static final int FRONTEND_SETTINGS_DVBT = 6; + public static final int FRONTEND_SETTINGS_ISDBS = 7; + public static final int FRONTEND_SETTINGS_ISDBS3 = 8; + public static final int FRONTEND_SETTINGS_ISDBT = 9; + private TunerConstants() { } } diff --git a/media/jni/android_media_tv_Tuner.cpp b/media/jni/android_media_tv_Tuner.cpp index f5202fc17f71..5216906d5ec5 100644 --- a/media/jni/android_media_tv_Tuner.cpp +++ b/media/jni/android_media_tv_Tuner.cpp @@ -31,6 +31,9 @@ using ::android::hardware::tv::tuner::V1_0::DemuxFilterMainType; using ::android::hardware::tv::tuner::V1_0::DemuxMmtpPid; using ::android::hardware::tv::tuner::V1_0::DemuxTpid; using ::android::hardware::tv::tuner::V1_0::DemuxTsFilterType; +using ::android::hardware::tv::tuner::V1_0::FrontendAnalogSettings; +using ::android::hardware::tv::tuner::V1_0::FrontendAnalogSifStandard; +using ::android::hardware::tv::tuner::V1_0::FrontendAnalogType; using ::android::hardware::tv::tuner::V1_0::ITuner; using ::android::hardware::tv::tuner::V1_0::Result; @@ -263,6 +266,15 @@ jobject JTuner::openLnbById(int id) { id); } +int JTuner::tune(const FrontendSettings& settings) { + if (mFe == NULL) { + ALOGE("frontend is not initialized"); + return (int)Result::INVALID_STATE; + } + Result result = mFe->tune(settings); + return (int)result; +} + bool JTuner::openDemux() { if (mTuner == nullptr) { return false; @@ -417,6 +429,32 @@ static DemuxPid getDemuxPid(int pidType, int pid) { return demuxPid; } +static FrontendSettings getFrontendSettings(JNIEnv *env, int type, jobject settings) { + FrontendSettings frontendSettings; + jclass clazz = env->FindClass("android/media/tv/tuner/FrontendSettings"); + jfieldID freqField = env->GetFieldID(clazz, "frequency", "I"); + uint32_t freq = static_cast<uint32_t>(env->GetIntField(clazz, freqField)); + + // TODO: handle the other 8 types of settings + if (type == 1) { + // analog + clazz = env->FindClass("android/media/tv/tuner/FrontendSettings$FrontendAnalogSettings"); + FrontendAnalogType analogType = + static_cast<FrontendAnalogType>( + env->GetIntField(settings, env->GetFieldID(clazz, "mAnalogType", "I"))); + FrontendAnalogSifStandard sifStandard = + static_cast<FrontendAnalogSifStandard>( + env->GetIntField(settings, env->GetFieldID(clazz, "mSifStandard", "I"))); + FrontendAnalogSettings frontendAnalogSettings { + .frequency = freq, + .type = analogType, + .sifStandard = sifStandard, + }; + frontendSettings.analog(frontendAnalogSettings); + } + return frontendSettings; +} + static sp<IFilter> getFilter(JNIEnv *env, jobject filter) { return (IFilter *)env->GetLongField(filter, gFields.filterContext); } @@ -476,6 +514,11 @@ static jobject android_media_tv_Tuner_open_frontend_by_id(JNIEnv *env, jobject t return tuner->openFrontendById(id); } +static int android_media_tv_Tuner_tune(JNIEnv *env, jobject thiz, jint type, jobject settings) { + sp<JTuner> tuner = getTuner(env, thiz); + return tuner->tune(getFrontendSettings(env, type, settings)); +} + static jobject android_media_tv_Tuner_get_lnb_ids(JNIEnv *env, jobject thiz) { sp<JTuner> tuner = getTuner(env, thiz); return tuner->getLnbIds(); @@ -612,6 +655,8 @@ static const JNINativeMethod gTunerMethods[] = { (void *)android_media_tv_Tuner_get_frontend_ids }, { "nativeOpenFrontendById", "(I)Landroid/media/tv/tuner/Tuner$Frontend;", (void *)android_media_tv_Tuner_open_frontend_by_id }, + { "nativeTune", "(ILandroid/media/tv/tuner/FrontendSettings;)I", + (void *)android_media_tv_Tuner_tune }, { "nativeOpenFilter", "(III)Landroid/media/tv/tuner/Tuner$Filter;", (void *)android_media_tv_Tuner_open_filter }, { "nativeGetLnbIds", "()Ljava/util/List;", diff --git a/media/jni/android_media_tv_Tuner.h b/media/jni/android_media_tv_Tuner.h index 3bf6ec84c8f7..f856791e2618 100644 --- a/media/jni/android_media_tv_Tuner.h +++ b/media/jni/android_media_tv_Tuner.h @@ -34,6 +34,7 @@ using ::android::hardware::tv::tuner::V1_0::FrontendEventType; using ::android::hardware::tv::tuner::V1_0::FrontendId; using ::android::hardware::tv::tuner::V1_0::FrontendScanMessage; using ::android::hardware::tv::tuner::V1_0::FrontendScanMessageType; +using ::android::hardware::tv::tuner::V1_0::FrontendSettings; using ::android::hardware::tv::tuner::V1_0::IDemux; using ::android::hardware::tv::tuner::V1_0::IDescrambler; using ::android::hardware::tv::tuner::V1_0::IDvr; @@ -95,6 +96,7 @@ struct JTuner : public RefBase { sp<ITuner> getTunerService(); jobject getFrontendIds(); jobject openFrontendById(int id); + int tune(const FrontendSettings& settings); jobject getLnbIds(); jobject openLnbById(int id); jobject openFilter(DemuxFilterType type, int bufferSize); diff --git a/packages/CarSystemUI/res/layout/car_ongoing_privacy_chip.xml b/packages/CarSystemUI/res/layout/car_ongoing_privacy_chip.xml deleted file mode 100644 index 918abd962dc2..000000000000 --- a/packages/CarSystemUI/res/layout/car_ongoing_privacy_chip.xml +++ /dev/null @@ -1,37 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - 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. ---> - -<com.android.systemui.statusbar.car.privacy.OngoingPrivacyChip - xmlns:android="http://schemas.android.com/apk/res/android" - android:id="@+id/car_privacy_chip" - android:layout_width="wrap_content" - android:layout_height="match_parent" - android:layout_margin="@dimen/ongoing_appops_chip_margin" - android:layout_toStartOf="@+id/clock_container" - android:focusable="true" - android:gravity="center_vertical|end" - android:orientation="horizontal" - android:paddingEnd="@dimen/ongoing_appops_chip_side_padding" - android:paddingStart="@dimen/ongoing_appops_chip_side_padding" - android:visibility="visible"> - - <LinearLayout - android:id="@+id/icons_container" - android:layout_width="wrap_content" - android:layout_height="match_parent" - android:gravity="center_vertical|start"/> -</com.android.systemui.statusbar.car.privacy.OngoingPrivacyChip>
\ No newline at end of file diff --git a/packages/CarSystemUI/res/layout/car_top_navigation_bar.xml b/packages/CarSystemUI/res/layout/car_top_navigation_bar.xml index 7299ddfd8688..ce0d31c6cc47 100644 --- a/packages/CarSystemUI/res/layout/car_top_navigation_bar.xml +++ b/packages/CarSystemUI/res/layout/car_top_navigation_bar.xml @@ -65,8 +65,6 @@ /> </FrameLayout> - <include layout="@layout/car_ongoing_privacy_chip"/> - <FrameLayout android:id="@+id/clock_container" android:layout_width="wrap_content" diff --git a/packages/CarSystemUI/res/values/dimens.xml b/packages/CarSystemUI/res/values/dimens.xml index e2da91b6d746..ee79653d92ac 100644 --- a/packages/CarSystemUI/res/values/dimens.xml +++ b/packages/CarSystemUI/res/values/dimens.xml @@ -59,18 +59,6 @@ <dimen name="car_keyline_1">24dp</dimen> <dimen name="car_keyline_2">96dp</dimen> <dimen name="car_keyline_3">128dp</dimen> - <dimen name="privacy_chip_icon_height">36dp</dimen> - <dimen name="privacy_chip_icon_padding_left">0dp</dimen> - <dimen name="privacy_chip_icon_padding_right">0dp</dimen> - <dimen name="privacy_chip_icon_padding_top">0dp</dimen> - <dimen name="privacy_chip_icon_padding_bottom">0dp</dimen> - - <dimen name="privacy_chip_text_padding_left">0dp</dimen> - <dimen name="privacy_chip_text_padding_right">0dp</dimen> - <dimen name="privacy_chip_text_padding_top">0dp</dimen> - <dimen name="privacy_chip_text_padding_bottom">0dp</dimen> - - <dimen name="privacy_chip_icon_max_height">100dp</dimen> <!-- Height of icons in Ongoing App Ops dialog. Both App Op icon and application icon --> <dimen name="ongoing_appops_dialog_icon_height">48dp</dimen> @@ -86,16 +74,6 @@ <dimen name="ongoing_appops_chip_bg_padding">4dp</dimen> <!-- Radius of Ongoing App Ops chip corners --> <dimen name="ongoing_appops_chip_bg_corner_radius">12dp</dimen> - <!-- Start padding for the app icon displayed in the dialog --> - <dimen name="privacy_dialog_app_icon_padding_start">40dp</dimen> - <!-- End padding for the app opps icon displayed in the dialog --> - <dimen name="privacy_dialog_app_ops_icon_padding_end">40dp</dimen> - <!-- Top padding for the list of application displayed in the dialog --> - <dimen name="privacy_dialog_app_list_padding_top">20dp</dimen> - <!-- Top padding for the dialog container--> - <dimen name="privacy_dialog_container_padding_top">10dp</dimen> - <!-- Top padding for the dialog title--> - <dimen name="privacy_dialog_title_padding_start">10dp</dimen> <!-- Car volume dimens. --> <dimen name="car_volume_item_icon_size">@dimen/car_primary_icon_size</dimen> diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/privacy/OngoingPrivacyChip.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/privacy/OngoingPrivacyChip.java deleted file mode 100644 index 88d641e8bb36..000000000000 --- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/privacy/OngoingPrivacyChip.java +++ /dev/null @@ -1,225 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.systemui.statusbar.car.privacy; - -import android.app.ActivityManager; -import android.app.AppOpsManager; -import android.content.Context; -import android.content.Intent; -import android.os.Handler; -import android.os.Looper; -import android.os.UserHandle; -import android.os.UserManager; -import android.util.AttributeSet; -import android.view.View; -import android.widget.ImageView; -import android.widget.LinearLayout; - -import com.android.systemui.Dependency; -import com.android.systemui.R; -import com.android.systemui.appops.AppOpItem; -import com.android.systemui.appops.AppOpsController; -import com.android.systemui.plugins.ActivityStarter; - -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; -import java.util.stream.Collectors; - -/** - * Layout defining the privacy chip that will be displayed in CarStatusRar with the information for - * which applications are using AppOpps permission fpr camera, mic and location. - */ -public class OngoingPrivacyChip extends LinearLayout implements View.OnClickListener { - - private Context mContext; - private Handler mHandler; - - private LinearLayout mIconsContainer; - private List<PrivacyItem> mPrivacyItems; - private static AppOpsController sAppOpsController; - private UserManager mUserManager; - private int mCurrentUser; - private List<Integer> mCurrentUserIds; - private boolean mListening = false; - PrivacyDialogBuilder mPrivacyDialogBuilder; - private LinearLayout mPrivacyChip; - private ActivityStarter mActivityStarter; - - protected static final int[] OPS = new int[]{ - AppOpsManager.OP_CAMERA, - AppOpsManager.OP_RECORD_AUDIO, - AppOpsManager.OP_COARSE_LOCATION, - AppOpsManager.OP_FINE_LOCATION - }; - - public OngoingPrivacyChip(Context context) { - super(context, null); - init(context); - } - - public OngoingPrivacyChip(Context context, AttributeSet attr) { - super(context, attr); - init(context); - } - - public OngoingPrivacyChip(Context context, AttributeSet attr, int defStyle) { - super(context, attr, defStyle); - init(context); - } - - public OngoingPrivacyChip(Context context, AttributeSet attr, int defStyle, int a) { - super(context, attr, defStyle, a); - init(context); - } - - private void init(Context context) { - mContext = context; - mHandler = new Handler(Looper.getMainLooper()); - mPrivacyItems = new ArrayList<>(); - sAppOpsController = Dependency.get(AppOpsController.class); - mUserManager = mContext.getSystemService(UserManager.class); - mActivityStarter = Dependency.get(ActivityStarter.class); - mCurrentUser = ActivityManager.getCurrentUser(); - mCurrentUserIds = mUserManager.getProfiles(mCurrentUser).stream().map( - userInfo -> userInfo.id).collect(Collectors.toList()); - - mPrivacyDialogBuilder = new PrivacyDialogBuilder(context, mPrivacyItems); - } - - private AppOpsController.Callback mCallback = new AppOpsController.Callback() { - - @Override - public void onActiveStateChanged(int code, int uid, String packageName, boolean active) { - int userId = UserHandle.getUserId(uid); - if (mCurrentUserIds.contains(userId)) { - updatePrivacyList(); - } - } - }; - - @Override - public void onFinishInflate() { - mIconsContainer = findViewById(R.id.icons_container); - mPrivacyChip = (LinearLayout) findViewById(R.id.car_privacy_chip); - if (mPrivacyChip != null) { - mPrivacyChip.setOnClickListener(this); - setListening(true); - } - } - - @Override - public void onDetachedFromWindow() { - if (mPrivacyChip != null) { - setListening(false); - } - super.onDetachedFromWindow(); - } - - @Override - public void onClick(View v) { - updatePrivacyList(); - mHandler.post(() -> { - mActivityStarter.postStartActivityDismissingKeyguard( - new Intent(Intent.ACTION_REVIEW_ONGOING_PERMISSION_USAGE), 0); - }); - } - - private void setListening(boolean listen) { - if (mListening == listen) { - return; - } - mListening = listen; - if (mListening) { - sAppOpsController.addCallback(OPS, mCallback); - updatePrivacyList(); - } else { - sAppOpsController.removeCallback(OPS, mCallback); - } - } - - private void updatePrivacyList() { - List<PrivacyItem> privacyItems = mCurrentUserIds.stream() - .flatMap(item -> sAppOpsController.getActiveAppOpsForUser(item).stream()) - .filter(Objects::nonNull) - .map(item -> toPrivacyItem(item)) - .filter(Objects::nonNull) - .collect(Collectors.toList()); - if (!privacyItems.equals(mPrivacyItems)) { - mPrivacyItems = privacyItems; - mPrivacyDialogBuilder = new PrivacyDialogBuilder(mContext, mPrivacyItems); - mHandler.post(this::updateView); - } - } - - private PrivacyItem toPrivacyItem(AppOpItem appOpItem) { - PrivacyType type; - switch (appOpItem.getCode()) { - case AppOpsManager.OP_CAMERA: - type = PrivacyType.TYPE_CAMERA; - break; - case AppOpsManager.OP_COARSE_LOCATION: - type = PrivacyType.TYPE_LOCATION; - break; - case AppOpsManager.OP_FINE_LOCATION: - type = PrivacyType.TYPE_LOCATION; - break; - case AppOpsManager.OP_RECORD_AUDIO: - type = PrivacyType.TYPE_MICROPHONE; - break; - default: - return null; - } - PrivacyApplication app = new PrivacyApplication(appOpItem.getPackageName(), mContext); - return new PrivacyItem(type, app, appOpItem.getTimeStarted()); - } - - // Should only be called if the mPrivacyDialogBuilder icons or app changed - private void updateView() { - if (mPrivacyItems.isEmpty()) { - mPrivacyChip.setVisibility(GONE); - return; - } - mPrivacyChip.setVisibility(VISIBLE); - setIcons(mPrivacyDialogBuilder); - - requestLayout(); - } - - private void setIcons(PrivacyDialogBuilder dialogBuilder) { - mIconsContainer.removeAllViews(); - dialogBuilder.generateIcons().forEach(item -> { - int size = mContext.getResources().getDimensionPixelSize( - R.dimen.privacy_chip_icon_height); - ImageView image = new ImageView(mContext); - image.setImageDrawable(item); - LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(size, size); - - int leftPadding = mContext.getResources().getDimensionPixelSize( - R.dimen.privacy_chip_icon_padding_left); - int topPadding = mContext.getResources().getDimensionPixelSize( - R.dimen.privacy_chip_icon_padding_top); - int rightPadding = mContext.getResources().getDimensionPixelSize( - R.dimen.privacy_chip_icon_padding_right); - int bottomPadding = mContext.getResources().getDimensionPixelSize( - R.dimen.privacy_chip_icon_padding_bottom); - image.setLayoutParams(layoutParams); - image.setPadding(leftPadding, topPadding, rightPadding, bottomPadding); - mIconsContainer.addView(image); - }); - } -} diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/privacy/PrivacyApplication.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/privacy/PrivacyApplication.java deleted file mode 100644 index a5d3bf7cc9c1..000000000000 --- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/privacy/PrivacyApplication.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.systemui.statusbar.car.privacy; - -import android.app.ActivityManager; -import android.content.Context; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageManager; -import android.graphics.drawable.Drawable; -import android.util.Log; - -import java.util.Objects; - -/** - * Class to hold the data for the applications that are using the AppOps permissions. - */ -public class PrivacyApplication { - private static final String TAG = "PrivacyApplication"; - - private String mPackageName; - private Drawable mIcon; - private String mApplicationName; - - public PrivacyApplication(String packageName, Context context) { - mPackageName = packageName; - try { - ApplicationInfo app = context.getPackageManager() - .getApplicationInfoAsUser(packageName, 0, - ActivityManager.getCurrentUser()); - mIcon = context.getPackageManager().getApplicationIcon(app); - mApplicationName = context.getPackageManager().getApplicationLabel(app).toString(); - } catch (PackageManager.NameNotFoundException e) { - mApplicationName = packageName; - Log.e(TAG, "Failed to to find package name", e); - } - } - - /** - * Gets the application name. - */ - public Drawable getIcon() { - return mIcon; - } - - /** - * Gets the application name. - */ - public String getApplicationName() { - return mApplicationName; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - PrivacyApplication that = (PrivacyApplication) o; - return mPackageName.equals(that.mPackageName); - } - - @Override - public int hashCode() { - return Objects.hash(mPackageName); - } -} diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/privacy/PrivacyDialogBuilder.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/privacy/PrivacyDialogBuilder.java deleted file mode 100644 index 3b83e7cc0623..000000000000 --- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/privacy/PrivacyDialogBuilder.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.systemui.statusbar.car.privacy; - -import android.content.Context; -import android.graphics.drawable.Drawable; - -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.stream.Collectors; - -/** - * Helper class to build the {@link OngoingPrivacyDialog} - */ -public class PrivacyDialogBuilder { - - private Map<PrivacyType, List<PrivacyItem>> mItemsByType; - private PrivacyApplication mApplication; - private Context mContext; - - public PrivacyDialogBuilder(Context context, List<PrivacyItem> itemsList) { - mContext = context; - mItemsByType = itemsList.stream().filter(Objects::nonNull).collect( - Collectors.groupingBy(PrivacyItem::getPrivacyType)); - List<PrivacyApplication> apps = itemsList.stream().filter(Objects::nonNull).map( - PrivacyItem::getPrivacyApplication).distinct().collect(Collectors.toList()); - mApplication = apps.size() == 1 ? apps.get(0) : null; - } - - /** - * Gets the icon id for all the {@link PrivacyItem} in the same order as of itemList. - */ - public List<Drawable> generateIcons() { - return mItemsByType.keySet().stream().map(item -> item.getIconId(mContext)).collect( - Collectors.toList()); - } - - /** - * Gets the application object. - */ - public PrivacyApplication getApplication() { - return mApplication; - } -} diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/privacy/PrivacyItem.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/privacy/PrivacyItem.java deleted file mode 100644 index d3e123ed8c25..000000000000 --- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/privacy/PrivacyItem.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.systemui.statusbar.car.privacy; - -import java.util.Objects; - -/** - * Class for holding the data of each privacy item displayed in {@link OngoingPrivacyDialog} - */ -public class PrivacyItem { - - private PrivacyType mPrivacyType; - private PrivacyApplication mPrivacyApplication; - - public PrivacyItem(PrivacyType privacyType, PrivacyApplication privacyApplication, - long timeStarted) { - this.mPrivacyType = privacyType; - this.mPrivacyApplication = privacyApplication; - } - - /** - * Gets the application object. - */ - public PrivacyApplication getPrivacyApplication() { - return mPrivacyApplication; - } - - /** - * Gets the privacy type for the application. - */ - public PrivacyType getPrivacyType() { - return mPrivacyType; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - PrivacyItem that = (PrivacyItem) o; - return mPrivacyType == that.mPrivacyType - && mPrivacyApplication.equals(that.mPrivacyApplication); - } - - @Override - public int hashCode() { - return Objects.hash(mPrivacyType, mPrivacyApplication); - } -} diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/privacy/PrivacyType.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/privacy/PrivacyType.java deleted file mode 100644 index 8955c87bbff4..000000000000 --- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/privacy/PrivacyType.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.systemui.statusbar.car.privacy; - -import android.content.Context; -import android.graphics.drawable.Drawable; - -import com.android.systemui.R; - -/** - * Enum for storing data for camera, mic and location. - */ -public enum PrivacyType { - TYPE_CAMERA(R.string.privacy_type_camera, com.android.internal.R.drawable.ic_camera), - TYPE_LOCATION(R.string.privacy_type_location, R.drawable.stat_sys_location), - TYPE_MICROPHONE(R.string.privacy_type_microphone, R.drawable.ic_mic_white); - - private int mNameId; - private int mIconId; - - PrivacyType(int nameId, int iconId) { - mNameId = nameId; - mIconId = iconId; - } - - /** - * Get the icon Id. - */ - public Drawable getIconId(Context context) { - return context.getResources().getDrawable(mIconId, null); - } - - /** - * Get the name Id. - */ - public String getNameId(Context context) { - return context.getResources().getString(mNameId); - } -} diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml index 97b2cb5733b2..3ff5cf490811 100644 --- a/packages/SettingsLib/res/values-af/strings.xml +++ b/packages/SettingsLib/res/values-af/strings.xml @@ -61,8 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"Middelmatig"</string> <string name="speed_label_fast" msgid="2677719134596044051">"Vinnig"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"Baie vinnig"</string> - <!-- no translation found for wifi_passpoint_expired (6540867261754427561) --> - <skip /> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Verval"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"Ontkoppel"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Ontkoppel tans…"</string> diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml index 62d5dca4541c..264d8de17872 100644 --- a/packages/SettingsLib/res/values-am/strings.xml +++ b/packages/SettingsLib/res/values-am/strings.xml @@ -61,8 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"መካከለኛ"</string> <string name="speed_label_fast" msgid="2677719134596044051">"ፈጣን"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"እጅግ በጣም ፈጣን"</string> - <!-- no translation found for wifi_passpoint_expired (6540867261754427561) --> - <skip /> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"ጊዜው አልፏል"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"ተለያይቷል"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"በመለያየት ላይ..."</string> diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml index c786e0900199..c23023671c73 100644 --- a/packages/SettingsLib/res/values-ar/strings.xml +++ b/packages/SettingsLib/res/values-ar/strings.xml @@ -61,8 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"متوسطة"</string> <string name="speed_label_fast" msgid="2677719134596044051">"سريعة"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"سريعة جدًا"</string> - <!-- no translation found for wifi_passpoint_expired (6540867261754427561) --> - <skip /> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"منتهية الصلاحية"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"غير متصل"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"جارٍ قطع الاتصال..."</string> diff --git a/packages/SettingsLib/res/values-as/strings.xml b/packages/SettingsLib/res/values-as/strings.xml index 552fbb871f51..ab0ed2976508 100644 --- a/packages/SettingsLib/res/values-as/strings.xml +++ b/packages/SettingsLib/res/values-as/strings.xml @@ -61,8 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"মধ্যমীয়া"</string> <string name="speed_label_fast" msgid="2677719134596044051">"দ্ৰুত"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"অতি দ্ৰুত"</string> - <!-- no translation found for wifi_passpoint_expired (6540867261754427561) --> - <skip /> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"ম্যাদ উকলিছে"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"সংযোগ বিচ্ছিন্ন কৰা হ’ল"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"সংযোগ বিচ্ছিন্ন কৰি থকা হৈছে…"</string> diff --git a/packages/SettingsLib/res/values-az/strings.xml b/packages/SettingsLib/res/values-az/strings.xml index 3af2e2559969..fe62d3139b40 100644 --- a/packages/SettingsLib/res/values-az/strings.xml +++ b/packages/SettingsLib/res/values-az/strings.xml @@ -61,8 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"Orta"</string> <string name="speed_label_fast" msgid="2677719134596044051">"Sürətli"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"Çox Sürətli"</string> - <!-- no translation found for wifi_passpoint_expired (6540867261754427561) --> - <skip /> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Vaxtı keçib"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"Ayrıldı"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Ayrılır..."</string> diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml index 8a76242fd5f0..1619584883bd 100644 --- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml +++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml @@ -61,8 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"Srednja"</string> <string name="speed_label_fast" msgid="2677719134596044051">"Brza"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"Veoma brza"</string> - <!-- no translation found for wifi_passpoint_expired (6540867261754427561) --> - <skip /> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Isteklo"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g>/<xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"Veza je prekinuta"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Prekidanje veze..."</string> diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml index 5ed4495cd62f..0f2df493696a 100644 --- a/packages/SettingsLib/res/values-be/strings.xml +++ b/packages/SettingsLib/res/values-be/strings.xml @@ -61,8 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"Сярэдняя"</string> <string name="speed_label_fast" msgid="2677719134596044051">"Хуткая"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"Вельмі хуткая"</string> - <!-- no translation found for wifi_passpoint_expired (6540867261754427561) --> - <skip /> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Тэрмін скончыўся"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"Адключана"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Адключэнне..."</string> diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml index f7a715343ee9..a3be2812ee2e 100644 --- a/packages/SettingsLib/res/values-bg/strings.xml +++ b/packages/SettingsLib/res/values-bg/strings.xml @@ -61,8 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"Средна"</string> <string name="speed_label_fast" msgid="2677719134596044051">"Бърза"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"Много бърза"</string> - <!-- no translation found for wifi_passpoint_expired (6540867261754427561) --> - <skip /> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Изтекло"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g>/<xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"Изкл."</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Изключва се..."</string> diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml index f4c677fe69ec..743de50fbb44 100644 --- a/packages/SettingsLib/res/values-bn/strings.xml +++ b/packages/SettingsLib/res/values-bn/strings.xml @@ -61,8 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"মাঝারি"</string> <string name="speed_label_fast" msgid="2677719134596044051">"দ্রুত"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"খুব দ্রুত"</string> - <!-- no translation found for wifi_passpoint_expired (6540867261754427561) --> - <skip /> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"মেয়াদ শেষ হয়ে গেছে"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"ডিসকানেক্ট করা হয়েছে"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"ডিসকানেক্ট হচ্ছে..."</string> diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml index fc653b7b1ab5..75a4047bedab 100644 --- a/packages/SettingsLib/res/values-bs/strings.xml +++ b/packages/SettingsLib/res/values-bs/strings.xml @@ -61,8 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"Srednja brzina"</string> <string name="speed_label_fast" msgid="2677719134596044051">"Brzo"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"Veoma brzo"</string> - <!-- no translation found for wifi_passpoint_expired (6540867261754427561) --> - <skip /> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Istekao"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"Isključen"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Prekidanje veze…"</string> diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml index f79375e5d765..8627cf30f707 100644 --- a/packages/SettingsLib/res/values-ca/strings.xml +++ b/packages/SettingsLib/res/values-ca/strings.xml @@ -61,8 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"Mitjana"</string> <string name="speed_label_fast" msgid="2677719134596044051">"Ràpida"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"Molt ràpida"</string> - <!-- no translation found for wifi_passpoint_expired (6540867261754427561) --> - <skip /> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Caducat"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"Desconnectat"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"S\'està desconnectant..."</string> diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml index 64400a4958dc..6fef07a566f2 100644 --- a/packages/SettingsLib/res/values-cs/strings.xml +++ b/packages/SettingsLib/res/values-cs/strings.xml @@ -61,8 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"Střední"</string> <string name="speed_label_fast" msgid="2677719134596044051">"Rychlá"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"Velmi rychlá"</string> - <!-- no translation found for wifi_passpoint_expired (6540867261754427561) --> - <skip /> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Platnost vypršela"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"Odpojeno"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Odpojování..."</string> diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml index de7a2289f083..80ee95e40a28 100644 --- a/packages/SettingsLib/res/values-da/strings.xml +++ b/packages/SettingsLib/res/values-da/strings.xml @@ -61,8 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"Middel"</string> <string name="speed_label_fast" msgid="2677719134596044051">"Hurtig"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"Meget hurtig"</string> - <!-- no translation found for wifi_passpoint_expired (6540867261754427561) --> - <skip /> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Udløbet"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> – <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"Afbrudt"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Afbryder ..."</string> diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml index eafe9d0b500d..7dee120826bd 100644 --- a/packages/SettingsLib/res/values-el/strings.xml +++ b/packages/SettingsLib/res/values-el/strings.xml @@ -61,8 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"Μέτρια"</string> <string name="speed_label_fast" msgid="2677719134596044051">"Γρήγορη"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"Πολύ γρήγορη"</string> - <!-- no translation found for wifi_passpoint_expired (6540867261754427561) --> - <skip /> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Έληξε"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"Αποσυνδέθηκε"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Αποσύνδεση..."</string> diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml index 840f5eede087..41c817e0f6db 100644 --- a/packages/SettingsLib/res/values-es-rUS/strings.xml +++ b/packages/SettingsLib/res/values-es-rUS/strings.xml @@ -61,8 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"Media"</string> <string name="speed_label_fast" msgid="2677719134596044051">"Rápida"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"Muy rápida"</string> - <!-- no translation found for wifi_passpoint_expired (6540867261754427561) --> - <skip /> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Vencido"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g>/<xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"Desconectado"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Desconectando…"</string> diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml index c86eb34d94b2..897eaa3ffb7f 100644 --- a/packages/SettingsLib/res/values-es/strings.xml +++ b/packages/SettingsLib/res/values-es/strings.xml @@ -61,8 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"Media"</string> <string name="speed_label_fast" msgid="2677719134596044051">"Rápida"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"Muy rápida"</string> - <!-- no translation found for wifi_passpoint_expired (6540867261754427561) --> - <skip /> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Caducado"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g>/<xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"Desconectado"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Desconectando…"</string> diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml index f59b96aabc02..9b94222a8fa5 100644 --- a/packages/SettingsLib/res/values-et/strings.xml +++ b/packages/SettingsLib/res/values-et/strings.xml @@ -61,8 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"Keskmine"</string> <string name="speed_label_fast" msgid="2677719134596044051">"Kiire"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"Väga kiire"</string> - <!-- no translation found for wifi_passpoint_expired (6540867261754427561) --> - <skip /> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Aegunud"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"Ühendus katkestatud"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Ühenduse katkestamine ..."</string> diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml index 9648139c9136..b0e4b2623a8c 100644 --- a/packages/SettingsLib/res/values-eu/strings.xml +++ b/packages/SettingsLib/res/values-eu/strings.xml @@ -61,8 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"Tartekoa"</string> <string name="speed_label_fast" msgid="2677719134596044051">"Bizkorra"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"Oso bizkorra"</string> - <!-- no translation found for wifi_passpoint_expired (6540867261754427561) --> - <skip /> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Iraungita"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"Deskonektatuta"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Deskonektatzen…"</string> @@ -455,7 +454,7 @@ <string name="cancel" msgid="5665114069455378395">"Utzi"</string> <string name="okay" msgid="949938843324579502">"Ados"</string> <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Aktibatu"</string> - <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Aktibatu \"Ez molestatu\" modua"</string> + <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Aktibatu ez molestatzeko modua"</string> <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Inoiz ez"</string> <string name="zen_interruption_level_priority" msgid="5392140786447823299">"Lehentasuna dutenak soilik"</string> <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string> diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml index 3e8de9795e95..7298826f2614 100644 --- a/packages/SettingsLib/res/values-fa/strings.xml +++ b/packages/SettingsLib/res/values-fa/strings.xml @@ -61,8 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"متوسط"</string> <string name="speed_label_fast" msgid="2677719134596044051">"سریع"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"خیلی سریع"</string> - <!-- no translation found for wifi_passpoint_expired (6540867261754427561) --> - <skip /> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"منقضیشده"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"اتصال قطع شد"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"در حال قطع اتصال..."</string> diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml index 68ddf7df9639..6f58f0352a0a 100644 --- a/packages/SettingsLib/res/values-fi/strings.xml +++ b/packages/SettingsLib/res/values-fi/strings.xml @@ -61,8 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"Kohtuullinen"</string> <string name="speed_label_fast" msgid="2677719134596044051">"Nopea"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"Hyvin nopea"</string> - <!-- no translation found for wifi_passpoint_expired (6540867261754427561) --> - <skip /> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Vanhentunut"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"Yhteys katkaistu"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Katkaistaan yhteyttä..."</string> diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml index ef4800cda193..a5526f3a41b7 100644 --- a/packages/SettingsLib/res/values-fr-rCA/strings.xml +++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml @@ -61,8 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"Moyenne"</string> <string name="speed_label_fast" msgid="2677719134596044051">"Élevée"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"Très rapide"</string> - <!-- no translation found for wifi_passpoint_expired (6540867261754427561) --> - <skip /> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Expiré"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> : <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"Déconnecté"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Déconnexion…"</string> diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml index 256ea03ac55a..eaab027a5659 100644 --- a/packages/SettingsLib/res/values-gl/strings.xml +++ b/packages/SettingsLib/res/values-gl/strings.xml @@ -61,8 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"Media"</string> <string name="speed_label_fast" msgid="2677719134596044051">"Rápida"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"Moi rápida"</string> - <!-- no translation found for wifi_passpoint_expired (6540867261754427561) --> - <skip /> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Caducou"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g>/<xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"Desconectado"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Desconectando..."</string> diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml index ed50f4b2a8cb..00fd024c1323 100644 --- a/packages/SettingsLib/res/values-gu/strings.xml +++ b/packages/SettingsLib/res/values-gu/strings.xml @@ -61,8 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"મધ્યમ"</string> <string name="speed_label_fast" msgid="2677719134596044051">"ઝડપી"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"ખૂબ ઝડપી"</string> - <!-- no translation found for wifi_passpoint_expired (6540867261754427561) --> - <skip /> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"સમય સમાપ્ત થયો"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"ડિસ્કનેક્ટ કર્યું"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"ડિસ્કનેક્ટ થઈ રહ્યું છે..."</string> diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml index 550eaf82d60f..96aec94808e3 100644 --- a/packages/SettingsLib/res/values-hi/strings.xml +++ b/packages/SettingsLib/res/values-hi/strings.xml @@ -61,8 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"मध्यम"</string> <string name="speed_label_fast" msgid="2677719134596044051">"तेज़"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"अत्यधिक तेज़"</string> - <!-- no translation found for wifi_passpoint_expired (6540867261754427561) --> - <skip /> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"समयसीमा खत्म हो गई"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"डिसकनेक्ट किया गया"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"डिस्कनेक्ट हो रहा है..."</string> diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml index 18ea1de4e92b..6df46ca407c0 100644 --- a/packages/SettingsLib/res/values-hr/strings.xml +++ b/packages/SettingsLib/res/values-hr/strings.xml @@ -61,8 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"Srednje"</string> <string name="speed_label_fast" msgid="2677719134596044051">"Brzo"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"Vrlo brzo"</string> - <!-- no translation found for wifi_passpoint_expired (6540867261754427561) --> - <skip /> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Isteklo"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g>/<xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"Niste povezani"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Isključivanje…"</string> diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml index 7baa0442d9da..6b5b05e6f00d 100644 --- a/packages/SettingsLib/res/values-hu/strings.xml +++ b/packages/SettingsLib/res/values-hu/strings.xml @@ -61,8 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"Közepes"</string> <string name="speed_label_fast" msgid="2677719134596044051">"Gyors"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"Nagyon gyors"</string> - <!-- no translation found for wifi_passpoint_expired (6540867261754427561) --> - <skip /> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Lejárt"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"Szétkapcsolva"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Szétkapcsolás..."</string> diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml index a5b03eafb965..c4002b9a1446 100644 --- a/packages/SettingsLib/res/values-hy/strings.xml +++ b/packages/SettingsLib/res/values-hy/strings.xml @@ -61,8 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"Միջին"</string> <string name="speed_label_fast" msgid="2677719134596044051">"Արագ"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"Շատ արագ"</string> - <!-- no translation found for wifi_passpoint_expired (6540867261754427561) --> - <skip /> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Սպառվել է"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"Անջատված է"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Անջատվում է..."</string> diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml index dea51a889520..753f225491db 100644 --- a/packages/SettingsLib/res/values-in/strings.xml +++ b/packages/SettingsLib/res/values-in/strings.xml @@ -61,8 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"Sedang"</string> <string name="speed_label_fast" msgid="2677719134596044051">"Cepat"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"Sangat Cepat"</string> - <!-- no translation found for wifi_passpoint_expired (6540867261754427561) --> - <skip /> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Sudah tidak berlaku"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g>/<xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"Sambungan terputus"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Memutus sambungan..."</string> diff --git a/packages/SettingsLib/res/values-is/strings.xml b/packages/SettingsLib/res/values-is/strings.xml index 0a85d06e7ad2..b1d40bfbe923 100644 --- a/packages/SettingsLib/res/values-is/strings.xml +++ b/packages/SettingsLib/res/values-is/strings.xml @@ -61,8 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"Miðlungshratt"</string> <string name="speed_label_fast" msgid="2677719134596044051">"Hratt"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"Mjög hratt"</string> - <!-- no translation found for wifi_passpoint_expired (6540867261754427561) --> - <skip /> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Útrunninn"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"Aftengt"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Aftengist…"</string> diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml index 980bdf9446b6..7f2bd3e9198b 100644 --- a/packages/SettingsLib/res/values-it/strings.xml +++ b/packages/SettingsLib/res/values-it/strings.xml @@ -61,8 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"Media"</string> <string name="speed_label_fast" msgid="2677719134596044051">"Veloce"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"Molto veloce"</string> - <!-- no translation found for wifi_passpoint_expired (6540867261754427561) --> - <skip /> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Scaduto"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g>/<xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"Disconnesso"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Disconnessione..."</string> diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml index 77fd156e6698..bdd1babefa32 100644 --- a/packages/SettingsLib/res/values-iw/strings.xml +++ b/packages/SettingsLib/res/values-iw/strings.xml @@ -61,8 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"בינונית"</string> <string name="speed_label_fast" msgid="2677719134596044051">"מהירה"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"מהירה מאוד"</string> - <!-- no translation found for wifi_passpoint_expired (6540867261754427561) --> - <skip /> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"התוקף פג"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"מנותק"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"מתנתק..."</string> diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml index 1d6b3d596c36..a6192a458ca8 100644 --- a/packages/SettingsLib/res/values-ja/strings.xml +++ b/packages/SettingsLib/res/values-ja/strings.xml @@ -61,8 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"普通"</string> <string name="speed_label_fast" msgid="2677719134596044051">"速い"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"非常に速い"</string> - <!-- no translation found for wifi_passpoint_expired (6540867261754427561) --> - <skip /> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"期限切れ"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"切断"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"切断中..."</string> diff --git a/packages/SettingsLib/res/values-ka/strings.xml b/packages/SettingsLib/res/values-ka/strings.xml index a69713a7a955..a3633f64a9f8 100644 --- a/packages/SettingsLib/res/values-ka/strings.xml +++ b/packages/SettingsLib/res/values-ka/strings.xml @@ -61,8 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"საშუალო"</string> <string name="speed_label_fast" msgid="2677719134596044051">"სწრაფი"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"ძალიან სწრაფი"</string> - <!-- no translation found for wifi_passpoint_expired (6540867261754427561) --> - <skip /> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"ვადაგასულია"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"კავშირი გაწყვეტილია"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"მიმდინარეობს გათიშვა…"</string> diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml index 380d648e24ab..0962e55e2dda 100644 --- a/packages/SettingsLib/res/values-kk/strings.xml +++ b/packages/SettingsLib/res/values-kk/strings.xml @@ -61,8 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"Орташа"</string> <string name="speed_label_fast" msgid="2677719134596044051">"Жылдам"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"Өте жылдам"</string> - <!-- no translation found for wifi_passpoint_expired (6540867261754427561) --> - <skip /> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Мерзімі өтті."</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"Ажыратылған"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Ажыратылуда…"</string> diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml index 478e036204eb..45620e831f9c 100644 --- a/packages/SettingsLib/res/values-km/strings.xml +++ b/packages/SettingsLib/res/values-km/strings.xml @@ -61,8 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"មធ្យម"</string> <string name="speed_label_fast" msgid="2677719134596044051">"លឿន"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"លឿនណាស់"</string> - <!-- no translation found for wifi_passpoint_expired (6540867261754427561) --> - <skip /> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"ផុតកំណត់"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"បានផ្ដាច់"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"កំពុងផ្ដាច់…"</string> diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml index 73aa99851c5e..1fc2e4a91081 100644 --- a/packages/SettingsLib/res/values-kn/strings.xml +++ b/packages/SettingsLib/res/values-kn/strings.xml @@ -61,8 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"ಮಧ್ಯಮ"</string> <string name="speed_label_fast" msgid="2677719134596044051">"ವೇಗ"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"ತುಂಬಾ ವೇಗವಾಗಿದೆ"</string> - <!-- no translation found for wifi_passpoint_expired (6540867261754427561) --> - <skip /> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"ಅವಧಿ ಮುಕ್ತಾಯವಾಗಿದೆ"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"ಸಂಪರ್ಕ ಕಡಿತಗೊಳಿಸಲಾಗಿದೆ"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"ಸಂಪರ್ಕ ಕಡಿತಗೊಳಿಸಲಾಗುತ್ತಿದೆ..."</string> diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml index 3ecde32aaa36..8e7c6977245f 100644 --- a/packages/SettingsLib/res/values-ko/strings.xml +++ b/packages/SettingsLib/res/values-ko/strings.xml @@ -61,8 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"보통"</string> <string name="speed_label_fast" msgid="2677719134596044051">"빠름"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"매우 빠름"</string> - <!-- no translation found for wifi_passpoint_expired (6540867261754427561) --> - <skip /> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"만료됨"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g>/<xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"연결 끊김"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"연결을 끊는 중…"</string> diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml index ca8992f63f0b..18a1468f2d75 100644 --- a/packages/SettingsLib/res/values-ky/strings.xml +++ b/packages/SettingsLib/res/values-ky/strings.xml @@ -61,8 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"Орто"</string> <string name="speed_label_fast" msgid="2677719134596044051">"Ылдам"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"Абдан ылдам"</string> - <!-- no translation found for wifi_passpoint_expired (6540867261754427561) --> - <skip /> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Мөөнөтү бүткөн"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g>/<xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"Ажыратылган"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Ажыратылууда…"</string> diff --git a/packages/SettingsLib/res/values-lo/strings.xml b/packages/SettingsLib/res/values-lo/strings.xml index b8a93229af06..808d5a796a48 100644 --- a/packages/SettingsLib/res/values-lo/strings.xml +++ b/packages/SettingsLib/res/values-lo/strings.xml @@ -61,8 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"ປານກາງ"</string> <string name="speed_label_fast" msgid="2677719134596044051">"ໄວ"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"ໄວຫຼາຍ"</string> - <!-- no translation found for wifi_passpoint_expired (6540867261754427561) --> - <skip /> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"ໝົດອາຍຸແລ້ວ"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"ຕັດການເຊື່ອມຕໍ່ແລ້ວ"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"ກຳລັງຢຸດການເຊື່ອມຕໍ່..."</string> diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml index 3d6dfbb4aaa7..78d1b1bf0c5c 100644 --- a/packages/SettingsLib/res/values-lt/strings.xml +++ b/packages/SettingsLib/res/values-lt/strings.xml @@ -61,8 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"Vidutinis"</string> <string name="speed_label_fast" msgid="2677719134596044051">"Greitas"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"Labai greitas"</string> - <!-- no translation found for wifi_passpoint_expired (6540867261754427561) --> - <skip /> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Baigėsi galiojimo laikas"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"Atsijungęs (-usi)"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Atjungiama..."</string> diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml index bf0c97d6d3d5..0ae10aa6c43c 100644 --- a/packages/SettingsLib/res/values-lv/strings.xml +++ b/packages/SettingsLib/res/values-lv/strings.xml @@ -61,8 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"Vidējs"</string> <string name="speed_label_fast" msgid="2677719134596044051">"Ātrs"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"Ļoti ātrs"</string> - <!-- no translation found for wifi_passpoint_expired (6540867261754427561) --> - <skip /> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Beidzies derīguma termiņš"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"Atvienots"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Notiek atvienošana..."</string> diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml index 53b0d4c35090..9850ac5b4ed9 100644 --- a/packages/SettingsLib/res/values-mk/strings.xml +++ b/packages/SettingsLib/res/values-mk/strings.xml @@ -61,8 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"Средна"</string> <string name="speed_label_fast" msgid="2677719134596044051">"Брза"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"Многу брза"</string> - <!-- no translation found for wifi_passpoint_expired (6540867261754427561) --> - <skip /> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Истечено"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g>/<xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"Исклучено"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Се исклучува..."</string> diff --git a/packages/SettingsLib/res/values-ml/strings.xml b/packages/SettingsLib/res/values-ml/strings.xml index 66ff005ee286..2692a30a85d2 100644 --- a/packages/SettingsLib/res/values-ml/strings.xml +++ b/packages/SettingsLib/res/values-ml/strings.xml @@ -61,8 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"ഇടത്തരം"</string> <string name="speed_label_fast" msgid="2677719134596044051">"വേഗത്തിൽ"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"വളരെ വേഗത്തിൽ"</string> - <!-- no translation found for wifi_passpoint_expired (6540867261754427561) --> - <skip /> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"കാലഹരണപ്പെട്ടത്"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"വിച്ഛേദിച്ചു"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"വിച്ഛേദിക്കുന്നു..."</string> diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml index 75633ab01803..966cdffe729b 100644 --- a/packages/SettingsLib/res/values-mr/strings.xml +++ b/packages/SettingsLib/res/values-mr/strings.xml @@ -61,8 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"मध्यम"</string> <string name="speed_label_fast" msgid="2677719134596044051">"जलद"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"खूप जलद"</string> - <!-- no translation found for wifi_passpoint_expired (6540867261754427561) --> - <skip /> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"मुदत संपली"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"डिस्कनेक्ट केले"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"डिस्कनेक्ट करत आहे..."</string> diff --git a/packages/SettingsLib/res/values-ms/strings.xml b/packages/SettingsLib/res/values-ms/strings.xml index fad37fe13d06..88d7c7d6fd6f 100644 --- a/packages/SettingsLib/res/values-ms/strings.xml +++ b/packages/SettingsLib/res/values-ms/strings.xml @@ -61,8 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"Sederhana"</string> <string name="speed_label_fast" msgid="2677719134596044051">"Laju"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"Sangat Laju"</string> - <!-- no translation found for wifi_passpoint_expired (6540867261754427561) --> - <skip /> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Tamat tempoh"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"Diputuskan sambungan"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Memutuskan sambungan..."</string> diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml index fd626f6c1536..6dfd2909efd5 100644 --- a/packages/SettingsLib/res/values-my/strings.xml +++ b/packages/SettingsLib/res/values-my/strings.xml @@ -61,8 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"အတော်အသင့်"</string> <string name="speed_label_fast" msgid="2677719134596044051">"မြန်"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"အလွန်မြန်"</string> - <!-- no translation found for wifi_passpoint_expired (6540867261754427561) --> - <skip /> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"သက်တမ်းကုန်သွားပါပြီ"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"ချိတ်ဆက်မှုပြတ်တောက်သည်"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"အဆက်အသွယ်ဖြတ်တောက်သည်"</string> diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml index baf3c64b5c28..760c409c0048 100644 --- a/packages/SettingsLib/res/values-nb/strings.xml +++ b/packages/SettingsLib/res/values-nb/strings.xml @@ -61,8 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"Middels"</string> <string name="speed_label_fast" msgid="2677719134596044051">"Rask"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"Veldig rask"</string> - <!-- no translation found for wifi_passpoint_expired (6540867261754427561) --> - <skip /> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Utløpt"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"Frakoblet"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Kobler fra…"</string> diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml index 00a30220acdb..77f87ffc4ea8 100644 --- a/packages/SettingsLib/res/values-ne/strings.xml +++ b/packages/SettingsLib/res/values-ne/strings.xml @@ -61,8 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"मध्यम"</string> <string name="speed_label_fast" msgid="2677719134596044051">"छिटो"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"धेरै छिटो"</string> - <!-- no translation found for wifi_passpoint_expired (6540867261754427561) --> - <skip /> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"म्याद सकियो"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"विच्छेदन गरियो"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"जडान हटाइँदै ..."</string> diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml index 533b0f23c28f..55f56d98483b 100644 --- a/packages/SettingsLib/res/values-nl/strings.xml +++ b/packages/SettingsLib/res/values-nl/strings.xml @@ -61,8 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"Gemiddeld"</string> <string name="speed_label_fast" msgid="2677719134596044051">"Snel"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"Zeer snel"</string> - <!-- no translation found for wifi_passpoint_expired (6540867261754427561) --> - <skip /> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Verlopen"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g>/<xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"Verbinding verbroken"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Verbinding verbreken..."</string> diff --git a/packages/SettingsLib/res/values-or/strings.xml b/packages/SettingsLib/res/values-or/strings.xml index 4a2ab808fc7e..98c302db0c7d 100644 --- a/packages/SettingsLib/res/values-or/strings.xml +++ b/packages/SettingsLib/res/values-or/strings.xml @@ -61,8 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"ମଧ୍ୟମ"</string> <string name="speed_label_fast" msgid="2677719134596044051">"ଦ୍ରୁତ"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"ଅତି ଦ୍ରୁତ"</string> - <!-- no translation found for wifi_passpoint_expired (6540867261754427561) --> - <skip /> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"ମିଆଦ ଶେଷ ହୋଇଯାଇଛି"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"ବିଛିନ୍ନ ହେଲା"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"ବିଚ୍ଛିନ୍ନ କରୁଛି…"</string> diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml index 62da49b0bc4d..525ad2e9a8fb 100644 --- a/packages/SettingsLib/res/values-pa/strings.xml +++ b/packages/SettingsLib/res/values-pa/strings.xml @@ -61,8 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"ਔਸਤ"</string> <string name="speed_label_fast" msgid="2677719134596044051">"ਤੇਜ਼"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"ਬਹੁਤ ਤੇਜ਼"</string> - <!-- no translation found for wifi_passpoint_expired (6540867261754427561) --> - <skip /> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"ਮਿਆਦ ਮੁੱਕ ਗਈ"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"ਡਿਸਕਨੈਕਟ ਕੀਤਾ"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"ਡਿਸਕਨੈਕਟ ਕਰ ਰਿਹਾ ਹੈ..."</string> diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml index 027afc31d28a..69ebc595f9b6 100644 --- a/packages/SettingsLib/res/values-pl/strings.xml +++ b/packages/SettingsLib/res/values-pl/strings.xml @@ -61,8 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"Średnia"</string> <string name="speed_label_fast" msgid="2677719134596044051">"Szybka"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"Bardzo szybka"</string> - <!-- no translation found for wifi_passpoint_expired (6540867261754427561) --> - <skip /> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Ważność wygasła"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"Rozłączona"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Rozłączanie..."</string> diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml index 9259c035985b..62017f103241 100644 --- a/packages/SettingsLib/res/values-pt-rBR/strings.xml +++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml @@ -61,8 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"Média"</string> <string name="speed_label_fast" msgid="2677719134596044051">"Rápida"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"Muito rápida"</string> - <!-- no translation found for wifi_passpoint_expired (6540867261754427561) --> - <skip /> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Expirado"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"Desconectado"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Desconectando…"</string> diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml index 0961b27d5512..8304768462f6 100644 --- a/packages/SettingsLib/res/values-pt-rPT/strings.xml +++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml @@ -61,8 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"Média"</string> <string name="speed_label_fast" msgid="2677719134596044051">"Rápida"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"Muito rápida"</string> - <!-- no translation found for wifi_passpoint_expired (6540867261754427561) --> - <skip /> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Expirado"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g>/<xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"Desligado"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"A desligar..."</string> diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml index 9259c035985b..62017f103241 100644 --- a/packages/SettingsLib/res/values-pt/strings.xml +++ b/packages/SettingsLib/res/values-pt/strings.xml @@ -61,8 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"Média"</string> <string name="speed_label_fast" msgid="2677719134596044051">"Rápida"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"Muito rápida"</string> - <!-- no translation found for wifi_passpoint_expired (6540867261754427561) --> - <skip /> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Expirado"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"Desconectado"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Desconectando…"</string> diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml index 1fc1d35a5b71..50ea4a00e5cd 100644 --- a/packages/SettingsLib/res/values-ro/strings.xml +++ b/packages/SettingsLib/res/values-ro/strings.xml @@ -61,8 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"Medie"</string> <string name="speed_label_fast" msgid="2677719134596044051">"Rapidă"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"Foarte rapidă"</string> - <!-- no translation found for wifi_passpoint_expired (6540867261754427561) --> - <skip /> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Expirat"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g>/<xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"Deconectat"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"În curs de deconectare..."</string> diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml index c3baea2dc665..0582a0cde4f7 100644 --- a/packages/SettingsLib/res/values-ru/strings.xml +++ b/packages/SettingsLib/res/values-ru/strings.xml @@ -61,8 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"Средняя"</string> <string name="speed_label_fast" msgid="2677719134596044051">"Быстрая"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"Очень быстрая"</string> - <!-- no translation found for wifi_passpoint_expired (6540867261754427561) --> - <skip /> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Срок действия истек"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"Нет подключения"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Отключение..."</string> diff --git a/packages/SettingsLib/res/values-si/strings.xml b/packages/SettingsLib/res/values-si/strings.xml index f8d2d08abea1..43a49781eeca 100644 --- a/packages/SettingsLib/res/values-si/strings.xml +++ b/packages/SettingsLib/res/values-si/strings.xml @@ -61,8 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"මධ්යම"</string> <string name="speed_label_fast" msgid="2677719134596044051">"වේගවත්"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"ඉතා වේගවත්"</string> - <!-- no translation found for wifi_passpoint_expired (6540867261754427561) --> - <skip /> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"කල් ඉකුත් විය"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"විසන්ධි වුණි"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"විසන්ධි වෙමින්…"</string> diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml index 0d576b4d5456..3a3958f3a441 100644 --- a/packages/SettingsLib/res/values-sk/strings.xml +++ b/packages/SettingsLib/res/values-sk/strings.xml @@ -61,8 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"Stredná"</string> <string name="speed_label_fast" msgid="2677719134596044051">"Vysoká"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"Veľmi vysoká"</string> - <!-- no translation found for wifi_passpoint_expired (6540867261754427561) --> - <skip /> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Platnosť vypršala"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"Odpojený"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Prebieha odpájanie..."</string> diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml index 7c62d52e816b..068f2214659c 100644 --- a/packages/SettingsLib/res/values-sl/strings.xml +++ b/packages/SettingsLib/res/values-sl/strings.xml @@ -61,8 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"Srednje hitra"</string> <string name="speed_label_fast" msgid="2677719134596044051">"Hitra"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"Zelo hitra"</string> - <!-- no translation found for wifi_passpoint_expired (6540867261754427561) --> - <skip /> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Poteklo"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g>/<xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"Prekinjena povezava"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Prekinjanje povezave ..."</string> diff --git a/packages/SettingsLib/res/values-sq/strings.xml b/packages/SettingsLib/res/values-sq/strings.xml index 7a1bdb55084b..54d463775535 100644 --- a/packages/SettingsLib/res/values-sq/strings.xml +++ b/packages/SettingsLib/res/values-sq/strings.xml @@ -61,8 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"Mesatare"</string> <string name="speed_label_fast" msgid="2677719134596044051">"E shpejtë"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"Shumë e shpejtë"</string> - <!-- no translation found for wifi_passpoint_expired (6540867261754427561) --> - <skip /> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Skaduar"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"Shkëputur"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Po shkëputet..."</string> diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml index e809ab9a9091..ab081ae21a9b 100644 --- a/packages/SettingsLib/res/values-sr/strings.xml +++ b/packages/SettingsLib/res/values-sr/strings.xml @@ -61,8 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"Средња"</string> <string name="speed_label_fast" msgid="2677719134596044051">"Брза"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"Веома брза"</string> - <!-- no translation found for wifi_passpoint_expired (6540867261754427561) --> - <skip /> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Истекло"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g>/<xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"Веза је прекинута"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Прекидање везе..."</string> diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml index 52a82dbfae02..cab971f8ae1e 100644 --- a/packages/SettingsLib/res/values-sv/strings.xml +++ b/packages/SettingsLib/res/values-sv/strings.xml @@ -61,8 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"Medelsnabb"</string> <string name="speed_label_fast" msgid="2677719134596044051">"Snabb"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"Mycket snabb"</string> - <!-- no translation found for wifi_passpoint_expired (6540867261754427561) --> - <skip /> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Har upphört att gälla"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g>/<xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"Kopplas ifrån"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Kopplar ifrån…"</string> diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml index c83388a083f9..df71b826f4b9 100644 --- a/packages/SettingsLib/res/values-sw/strings.xml +++ b/packages/SettingsLib/res/values-sw/strings.xml @@ -61,8 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"Wastani"</string> <string name="speed_label_fast" msgid="2677719134596044051">"Haraka"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"Haraka Sana"</string> - <!-- no translation found for wifi_passpoint_expired (6540867261754427561) --> - <skip /> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Muda umeisha"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"Haijaunganishwa"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Inatenganisha..."</string> diff --git a/packages/SettingsLib/res/values-ta/strings.xml b/packages/SettingsLib/res/values-ta/strings.xml index 856fd4f6eafb..084ec16ec05b 100644 --- a/packages/SettingsLib/res/values-ta/strings.xml +++ b/packages/SettingsLib/res/values-ta/strings.xml @@ -61,8 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"நடுத்தரம்"</string> <string name="speed_label_fast" msgid="2677719134596044051">"வேகம்"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"மிகவும் வேகமானது"</string> - <!-- no translation found for wifi_passpoint_expired (6540867261754427561) --> - <skip /> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"காலாவதியாகிவிட்டது"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"தொடர்பு துண்டிக்கப்பட்டது"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"துண்டிக்கிறது..."</string> diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml index cc172473b3b2..cbcaf1a8ddfc 100644 --- a/packages/SettingsLib/res/values-te/strings.xml +++ b/packages/SettingsLib/res/values-te/strings.xml @@ -61,8 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"మధ్యస్థం"</string> <string name="speed_label_fast" msgid="2677719134596044051">"వేగవంతం"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"చాలా వేగవంతం"</string> - <!-- no translation found for wifi_passpoint_expired (6540867261754427561) --> - <skip /> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"గడువు ముగిసింది"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"డిస్కనెక్ట్ చేయబడింది"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"డిస్కనెక్ట్ చేస్తోంది..."</string> diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml index 4feb0d6862e8..fa8caa17b824 100644 --- a/packages/SettingsLib/res/values-th/strings.xml +++ b/packages/SettingsLib/res/values-th/strings.xml @@ -61,8 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"ปานกลาง"</string> <string name="speed_label_fast" msgid="2677719134596044051">"เร็ว"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"เร็วมาก"</string> - <!-- no translation found for wifi_passpoint_expired (6540867261754427561) --> - <skip /> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"หมดอายุแล้ว"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g>/<xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"ตัดการเชื่อมต่อ"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"กำลังตัดการเชื่อมต่อ..."</string> diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml index e6963b96f851..21fe58c2db28 100644 --- a/packages/SettingsLib/res/values-tl/strings.xml +++ b/packages/SettingsLib/res/values-tl/strings.xml @@ -61,8 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"Katamtaman"</string> <string name="speed_label_fast" msgid="2677719134596044051">"Mabilis"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"Napakabilis"</string> - <!-- no translation found for wifi_passpoint_expired (6540867261754427561) --> - <skip /> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Nag-expire na"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"Hindi nakakonekta"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Nadidiskonekta..."</string> diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml index bd457d3ef9e2..4e7f38dca25b 100644 --- a/packages/SettingsLib/res/values-tr/strings.xml +++ b/packages/SettingsLib/res/values-tr/strings.xml @@ -61,8 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"Orta"</string> <string name="speed_label_fast" msgid="2677719134596044051">"Hızlı"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"Çok Hızlı"</string> - <!-- no translation found for wifi_passpoint_expired (6540867261754427561) --> - <skip /> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Süresi sona erdi"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"Bağlantı kesildi"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Bağlantı kesiliyor…"</string> diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml index 36a82ea1e92f..98074173f5c9 100644 --- a/packages/SettingsLib/res/values-uk/strings.xml +++ b/packages/SettingsLib/res/values-uk/strings.xml @@ -61,8 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"Середня"</string> <string name="speed_label_fast" msgid="2677719134596044051">"Швидка"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"Дуже швидка"</string> - <!-- no translation found for wifi_passpoint_expired (6540867261754427561) --> - <skip /> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Термін дії минув"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g>: <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"Роз’єднано"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Відключення..."</string> diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml index 50dc72e2218e..e17b0b05838f 100644 --- a/packages/SettingsLib/res/values-ur/strings.xml +++ b/packages/SettingsLib/res/values-ur/strings.xml @@ -61,8 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"متوسط"</string> <string name="speed_label_fast" msgid="2677719134596044051">"تیز"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"بہت تیز"</string> - <!-- no translation found for wifi_passpoint_expired (6540867261754427561) --> - <skip /> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"میعاد ختم ہو گئی"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"منقطع"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"منقطع کیا جارہا ہے…"</string> diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml index 38edb6d0dcdb..ea51eba747a3 100644 --- a/packages/SettingsLib/res/values-uz/strings.xml +++ b/packages/SettingsLib/res/values-uz/strings.xml @@ -61,8 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"O‘rtacha"</string> <string name="speed_label_fast" msgid="2677719134596044051">"Tez"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"Juda tez"</string> - <!-- no translation found for wifi_passpoint_expired (6540867261754427561) --> - <skip /> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Muddati tugagan"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"Uzildi"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Uzilyapti…"</string> diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml index e0798aa54d14..0b71a8c6243a 100644 --- a/packages/SettingsLib/res/values-vi/strings.xml +++ b/packages/SettingsLib/res/values-vi/strings.xml @@ -61,8 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"Trung bình"</string> <string name="speed_label_fast" msgid="2677719134596044051">"Nhanh"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"Rất nhanh"</string> - <!-- no translation found for wifi_passpoint_expired (6540867261754427561) --> - <skip /> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Đã hết hạn"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"Đã ngắt kết nối"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Đang ngắt kết nối…"</string> diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml index 4303615591b9..1805694c3b1f 100644 --- a/packages/SettingsLib/res/values-zh-rCN/strings.xml +++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml @@ -61,8 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"适中"</string> <string name="speed_label_fast" msgid="2677719134596044051">"快"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"很快"</string> - <!-- no translation found for wifi_passpoint_expired (6540867261754427561) --> - <skip /> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"已失效"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"已断开连接"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"正在断开连接..."</string> diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml index f3b8653cf4e9..1d217b500cc9 100644 --- a/packages/SettingsLib/res/values-zh-rHK/strings.xml +++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml @@ -61,8 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"適中"</string> <string name="speed_label_fast" msgid="2677719134596044051">"快"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"非常快"</string> - <!-- no translation found for wifi_passpoint_expired (6540867261754427561) --> - <skip /> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"已過期"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g>/<xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"已中斷連線"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"正在中斷連線..."</string> diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml index 53b54c4092b6..ee6866505bdb 100644 --- a/packages/SettingsLib/res/values-zh-rTW/strings.xml +++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml @@ -61,8 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"適中"</string> <string name="speed_label_fast" msgid="2677719134596044051">"快"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"非常快"</string> - <!-- no translation found for wifi_passpoint_expired (6540867261754427561) --> - <skip /> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"已失效"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"已中斷連線"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"正在中斷連線…"</string> diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml index 249e73ccfa0d..820aa772e7e6 100644 --- a/packages/SettingsLib/res/values-zu/strings.xml +++ b/packages/SettingsLib/res/values-zu/strings.xml @@ -61,8 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"Okumaphakathi"</string> <string name="speed_label_fast" msgid="2677719134596044051">"Sheshayo"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"Kushesha kakhulu"</string> - <!-- no translation found for wifi_passpoint_expired (6540867261754427561) --> - <skip /> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Iphelelwe isikhathi"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"Ayixhunyiwe"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Inqamula uxhumano kwi-inthanethi..."</string> diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml index a1ef831523b1..80240affc1c1 100644 --- a/packages/SettingsLib/res/values/strings.xml +++ b/packages/SettingsLib/res/values/strings.xml @@ -609,6 +609,9 @@ <string name="bluetooth_select_a2dp_codec_sample_rate">Bluetooth Audio Sample Rate</string> <!-- UI debug setting: Trigger Bluetooth Audio Codec Selection: Sample Rate --> <string name="bluetooth_select_a2dp_codec_sample_rate_dialog_title">Trigger Bluetooth Audio Codec\u000ASelection: Sample Rate</string> + <!-- UI debug setting: Label for unsupported Bluetooth Audio Codec. [CHAR LIMIT=none] --> + <string name="bluetooth_select_a2dp_codec_type_help_info">Gray-out means not supported by phone + or headset</string> <!-- UI debug setting: Trigger Bluetooth Audio Bits Per Sample Selection --> <string name="bluetooth_select_a2dp_codec_bits_per_sample">Bluetooth Audio Bits Per Sample</string> diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java index 2507a3486f2b..0095692336e7 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java @@ -442,12 +442,12 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> /** * Get name from remote device - * @return {@link BluetoothDevice#getAliasName()} if - * {@link BluetoothDevice#getAliasName()} is not null otherwise return + * @return {@link BluetoothDevice#getAlias()} if + * {@link BluetoothDevice#getAlias()} is not null otherwise return * {@link BluetoothDevice#getAddress()} */ public String getName() { - final String aliasName = mDevice.getAliasName(); + final String aliasName = mDevice.getAlias(); return TextUtils.isEmpty(aliasName) ? getAddress() : aliasName; } @@ -505,7 +505,7 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> * @return true if device's alias name is not null nor empty, false otherwise */ public boolean hasHumanReadableName() { - return !TextUtils.isEmpty(mDevice.getAliasName()); + return !TextUtils.isEmpty(mDevice.getAlias()); } /** @@ -652,7 +652,7 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> } if (BluetoothUtils.D) { - Log.e(TAG, "updating profiles for " + mDevice.getAliasName() + ", " + mDevice); + Log.e(TAG, "updating profiles for " + mDevice.getAlias() + ", " + mDevice); BluetoothClass bluetoothClass = mDevice.getBluetoothClass(); if (bluetoothClass != null) Log.v(TAG, "Class: " + bluetoothClass.toString()); diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java index 9f71033de758..cca9cfac2d22 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java @@ -168,7 +168,7 @@ public class CachedBluetoothDeviceManager { return cachedDevice.getName(); } - String name = device.getAliasName(); + String name = device.getAlias(); if (name != null) { return name; } diff --git a/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java b/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java index ea3c1d95925c..092cbf3c7c12 100644 --- a/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java +++ b/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java @@ -222,7 +222,8 @@ public class DataUsageController { } } - return TelephonyManager.from(mContext).createForSubscriptionId(subscriptionId); + return mContext.getSystemService( + TelephonyManager.class).createForSubscriptionId(subscriptionId); } public void setMobileDataEnabled(boolean enabled) { diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java index aef7fae8ee0b..2c4f57fa77be 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java @@ -92,9 +92,9 @@ public class CachedBluetoothDeviceManagerTest { when(mDevice1.getName()).thenReturn(DEVICE_NAME_1); when(mDevice2.getName()).thenReturn(DEVICE_NAME_2); when(mDevice3.getName()).thenReturn(DEVICE_NAME_3); - when(mDevice1.getAliasName()).thenReturn(DEVICE_ALIAS_1); - when(mDevice2.getAliasName()).thenReturn(DEVICE_ALIAS_2); - when(mDevice3.getAliasName()).thenReturn(DEVICE_ALIAS_3); + when(mDevice1.getAlias()).thenReturn(DEVICE_ALIAS_1); + when(mDevice2.getAlias()).thenReturn(DEVICE_ALIAS_2); + when(mDevice3.getAlias()).thenReturn(DEVICE_ALIAS_3); when(mDevice1.getBluetoothClass()).thenReturn(DEVICE_CLASS_1); when(mDevice2.getBluetoothClass()).thenReturn(DEVICE_CLASS_2); when(mDevice3.getBluetoothClass()).thenReturn(DEVICE_CLASS_2); @@ -240,7 +240,7 @@ public class CachedBluetoothDeviceManagerTest { assertThat(cachedDevice1.getName()).isEqualTo(DEVICE_ALIAS_1); final String newAliasName = "NewAliasName"; - when(mDevice1.getAliasName()).thenReturn(newAliasName); + when(mDevice1.getAlias()).thenReturn(newAliasName); mCachedDeviceManager.onDeviceNameUpdated(mDevice1); assertThat(cachedDevice1.getName()).isEqualTo(newAliasName); } diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java index 5c89a019bf82..53ff1a10b6ff 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java @@ -702,7 +702,7 @@ public class CachedBluetoothDeviceTest { @Test public void deviceName_testAliasNameAvailable() { - when(mDevice.getAliasName()).thenReturn(DEVICE_ALIAS); + when(mDevice.getAlias()).thenReturn(DEVICE_ALIAS); when(mDevice.getName()).thenReturn(DEVICE_NAME); CachedBluetoothDevice cachedBluetoothDevice = new CachedBluetoothDevice(mContext, mProfileManager, mDevice); @@ -725,7 +725,7 @@ public class CachedBluetoothDeviceTest { @Test public void deviceName_testRenameDevice() { final String[] alias = {DEVICE_ALIAS}; - doAnswer(invocation -> alias[0]).when(mDevice).getAliasName(); + doAnswer(invocation -> alias[0]).when(mDevice).getAlias(); doAnswer(invocation -> { alias[0] = (String) invocation.getArguments()[0]; return true; @@ -842,14 +842,14 @@ public class CachedBluetoothDeviceTest { @Test public void getName_aliasNameNotNull_returnAliasName() { - when(mDevice.getAliasName()).thenReturn(DEVICE_NAME); + when(mDevice.getAlias()).thenReturn(DEVICE_NAME); assertThat(mCachedDevice.getName()).isEqualTo(DEVICE_NAME); } @Test public void getName_aliasNameIsNull_returnAddress() { - when(mDevice.getAliasName()).thenReturn(null); + when(mDevice.getAlias()).thenReturn(null); assertThat(mCachedDevice.getName()).isEqualTo(DEVICE_ADDRESS); } @@ -857,7 +857,7 @@ public class CachedBluetoothDeviceTest { @Test public void setName_setDeviceNameIsNotNull() { final String name = "test name"; - when(mDevice.getAliasName()).thenReturn(DEVICE_NAME); + when(mDevice.getAlias()).thenReturn(DEVICE_NAME); mCachedDevice.setName(name); diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HearingAidDeviceManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HearingAidDeviceManagerTest.java index 2b5466c4161f..7be176a37bb4 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HearingAidDeviceManagerTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HearingAidDeviceManagerTest.java @@ -75,8 +75,8 @@ public class HearingAidDeviceManagerTest { when(mDevice2.getAddress()).thenReturn(DEVICE_ADDRESS_2); when(mDevice1.getName()).thenReturn(DEVICE_NAME_1); when(mDevice2.getName()).thenReturn(DEVICE_NAME_2); - when(mDevice1.getAliasName()).thenReturn(DEVICE_ALIAS_1); - when(mDevice2.getAliasName()).thenReturn(DEVICE_ALIAS_2); + when(mDevice1.getAlias()).thenReturn(DEVICE_ALIAS_1); + when(mDevice2.getAlias()).thenReturn(DEVICE_ALIAS_2); when(mDevice1.getBluetoothClass()).thenReturn(DEVICE_CLASS); when(mDevice2.getBluetoothClass()).thenReturn(DEVICE_CLASS); when(mLocalBluetoothManager.getEventManager()).thenReturn(mBluetoothEventManager); diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/DataUsageControllerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/DataUsageControllerTest.java index 3da5e766c389..f7bee30a087f 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/DataUsageControllerTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/DataUsageControllerTest.java @@ -75,7 +75,7 @@ public class DataUsageControllerTest { public void setUp() throws RemoteException { MockitoAnnotations.initMocks(this); when(mTelephonyManager.createForSubscriptionId(anyInt())).thenReturn(mTelephonyManager); - when(mContext.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(mTelephonyManager); + when(mContext.getSystemService(TelephonyManager.class)).thenReturn(mTelephonyManager); when(mContext.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE)) .thenReturn(mSubscriptionManager); when(mContext.getSystemService(NetworkStatsManager.class)).thenReturn(mNetworkStatsManager); diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/NavigationEdgeBackPlugin.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/NavigationEdgeBackPlugin.java new file mode 100644 index 000000000000..bd86407222bc --- /dev/null +++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/NavigationEdgeBackPlugin.java @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.plugins; + +import android.graphics.Point; +import android.view.MotionEvent; +import android.view.WindowManager; + +import com.android.systemui.plugins.annotations.ProvidesInterface; + +/** Plugin to handle navigation edge gestures for Back. */ +@ProvidesInterface( + action = NavigationEdgeBackPlugin.ACTION, + version = NavigationEdgeBackPlugin.VERSION) +public interface NavigationEdgeBackPlugin extends Plugin { + String ACTION = "com.android.systemui.action.PLUGIN_NAVIGATION_EDGE_BACK_ACTION"; + int VERSION = 1; + + + /** Specifies if the UI should be rendered on the left side of the screen. */ + void setIsLeftPanel(boolean isLeftPanel); + + /** Sets the insets for the gesture handling area. */ + void setInsets(int leftInset, int rightInset); + + /** Sets the display size. */ + void setDisplaySize(Point displaySize); + + /** Sets the callback that should be invoked when a Back gesture is detected. */ + void setBackCallback(BackCallback callback); + + /** Sets the base LayoutParams for the UI. */ + void setLayoutParams(WindowManager.LayoutParams layoutParams); + + /** Updates the UI based on the motion events passed in device coordinates. */ + void onMotionEvent(MotionEvent motionEvent); + + /** Callback to let the system react to the detected back gestures. */ + interface BackCallback { + /** Indicates that a Back gesture was recognized and the system should go back. */ + void triggerBack(); + + /** Indicates that the gesture was cancelled and the system should not go back. */ + void cancelBack(); + } +} diff --git a/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java b/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java index 741c95f4b566..87fe3a21186d 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java +++ b/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java @@ -103,14 +103,12 @@ public class DependencyProvider { return Looper.getMainLooper(); } - @Singleton @Provides @BgHandler public Handler provideBgHandler(@BgLooper Looper bgLooper) { return new Handler(bgLooper); } - @Singleton @Provides @MainHandler public Handler provideMainHandler(@MainLooper Looper mainLooper) { diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java index 79632039c832..e790c1d071ce 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java @@ -87,6 +87,7 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; +import java.util.function.Consumer; import java.util.function.Function; import javax.inject.Inject; @@ -107,7 +108,7 @@ public class GlobalScreenshot { public Context context; public Bitmap image; public Uri imageUri; - public Runnable finisher; + public Consumer<Uri> finisher; public Function<PendingIntent, Void> onEditReady; public int iconSize; public int previewWidth; @@ -260,7 +261,7 @@ public class GlobalScreenshot { * Creates a new worker thread and saves the screenshot to the media store. */ private void saveScreenshotInWorkerThread( - Runnable finisher, @Nullable Function<PendingIntent, Void> onEditReady) { + Consumer<Uri> finisher, @Nullable Function<PendingIntent, Void> onEditReady) { SaveImageInBackgroundData data = new SaveImageInBackgroundData(); data.context = mContext; data.image = mScreenBitmap; @@ -276,15 +277,15 @@ public class GlobalScreenshot { .execute(); } - private void saveScreenshotInWorkerThread(Runnable finisher) { + private void saveScreenshotInWorkerThread(Consumer<Uri> finisher) { saveScreenshotInWorkerThread(finisher, null); } /** * Takes a screenshot of the current display and shows an animation. */ - private void takeScreenshot(Runnable finisher, boolean statusBarVisible, boolean navBarVisible, - Rect crop) { + private void takeScreenshot(Consumer<Uri> finisher, boolean statusBarVisible, + boolean navBarVisible, Rect crop) { int rot = mDisplay.getRotation(); int width = crop.width(); int height = crop.height(); @@ -294,7 +295,7 @@ public class GlobalScreenshot { if (mScreenBitmap == null) { notifyScreenshotError(mContext, mNotificationManager, R.string.screenshot_failed_to_capture_text); - finisher.run(); + finisher.accept(null); return; } @@ -307,7 +308,7 @@ public class GlobalScreenshot { statusBarVisible, navBarVisible); } - void takeScreenshot(Runnable finisher, boolean statusBarVisible, boolean navBarVisible) { + void takeScreenshot(Consumer<Uri> finisher, boolean statusBarVisible, boolean navBarVisible) { mDisplay.getRealMetrics(mDisplayMetrics); takeScreenshot(finisher, statusBarVisible, navBarVisible, new Rect(0, 0, mDisplayMetrics.widthPixels, mDisplayMetrics.heightPixels)); @@ -316,7 +317,7 @@ public class GlobalScreenshot { /** * Displays a screenshot selector */ - void takeScreenshotPartial(final Runnable finisher, final boolean statusBarVisible, + void takeScreenshotPartial(final Consumer<Uri> finisher, final boolean statusBarVisible, final boolean navBarVisible) { mWindowManager.addView(mScreenshotLayout, mWindowLayoutParams); mScreenshotSelectorView.setOnTouchListener(new View.OnTouchListener() { @@ -392,8 +393,8 @@ public class GlobalScreenshot { /** * Starts the animation after taking the screenshot */ - private void startAnimation(final Runnable finisher, int w, int h, boolean statusBarVisible, - boolean navBarVisible) { + private void startAnimation(final Consumer<Uri> finisher, int w, int h, + boolean statusBarVisible, boolean navBarVisible) { // If power save is on, show a toast so there is some visual indication that a screenshot // has been taken. PowerManager powerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java b/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java index 083f9712d705..e9dbe02371d5 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java @@ -453,7 +453,7 @@ class SaveImageInBackgroundTask extends AsyncTask<Void, Void, Void> { mNotificationBuilder.build()); } } - mParams.finisher.run(); + mParams.finisher.accept(mParams.imageUri); mParams.clearContext(); } @@ -462,7 +462,7 @@ class SaveImageInBackgroundTask extends AsyncTask<Void, Void, Void> { // If we are cancelled while the task is running in the background, we may get null // params. The finisher is expected to always be called back, so just use the baked-in // params from the ctor in any case. - mParams.finisher.run(); + mParams.finisher.accept(null); mParams.clearImage(); mParams.clearContext(); diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java b/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java index fd63506ef983..6243b4b41e73 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java @@ -18,6 +18,7 @@ package com.android.systemui.screenshot; import android.app.Service; import android.content.Intent; +import android.net.Uri; import android.os.Handler; import android.os.IBinder; import android.os.Message; @@ -27,6 +28,8 @@ import android.os.UserManager; import android.util.Log; import android.view.WindowManager; +import java.util.function.Consumer; + import javax.inject.Inject; public class TakeScreenshotService extends Service { @@ -39,10 +42,10 @@ public class TakeScreenshotService extends Service { @Override public void handleMessage(Message msg) { final Messenger callback = msg.replyTo; - Runnable finisher = new Runnable() { + Consumer<Uri> finisher = new Consumer<Uri>() { @Override - public void run() { - Message reply = Message.obtain(null, 1); + public void accept(Uri uri) { + Message reply = Message.obtain(null, 1, uri); try { callback.send(reply); } catch (RemoteException e) { @@ -55,7 +58,7 @@ public class TakeScreenshotService extends Service { // animation and error notification. if (!mUserManager.isUserUnlocked()) { Log.w(TAG, "Skipping screenshot because storage is locked!"); - post(finisher); + post(() -> finisher.accept(null)); return; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/EdgeBackGestureHandler.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/EdgeBackGestureHandler.java index 1c8e832d03d2..8ee964f3f771 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/EdgeBackGestureHandler.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/EdgeBackGestureHandler.java @@ -22,7 +22,6 @@ import android.content.res.Resources; import android.graphics.PixelFormat; import android.graphics.Point; import android.graphics.PointF; -import android.graphics.Rect; import android.graphics.Region; import android.hardware.display.DisplayManager; import android.hardware.display.DisplayManager.DisplayListener; @@ -32,9 +31,7 @@ import android.os.RemoteException; import android.os.SystemClock; import android.os.SystemProperties; import android.util.Log; -import android.util.MathUtils; import android.util.StatsLog; -import android.view.Gravity; import android.view.ISystemGestureExclusionListener; import android.view.InputChannel; import android.view.InputDevice; @@ -44,7 +41,6 @@ import android.view.InputMonitor; import android.view.KeyCharacterMap; import android.view.KeyEvent; import android.view.MotionEvent; -import android.view.View; import android.view.ViewConfiguration; import android.view.WindowManager; import android.view.WindowManagerGlobal; @@ -53,7 +49,10 @@ import com.android.systemui.Dependency; import com.android.systemui.R; import com.android.systemui.bubbles.BubbleController; import com.android.systemui.model.SysUiState; +import com.android.systemui.plugins.NavigationEdgeBackPlugin; +import com.android.systemui.plugins.PluginListener; import com.android.systemui.recents.OverviewProxyService; +import com.android.systemui.shared.plugins.PluginManager; import com.android.systemui.shared.system.QuickStepContract; import java.io.PrintWriter; @@ -62,7 +61,8 @@ import java.util.concurrent.Executor; /** * Utility class to handle edge swipes for back gesture */ -public class EdgeBackGestureHandler implements DisplayListener { +public class EdgeBackGestureHandler implements DisplayListener, + PluginListener<NavigationEdgeBackPlugin> { private static final String TAG = "EdgeBackGestureHandler"; private static final int MAX_LONG_PRESS_TIMEOUT = SystemProperties.getInt( @@ -85,6 +85,7 @@ public class EdgeBackGestureHandler implements DisplayListener { private final Context mContext; private final OverviewProxyService mOverviewProxyService; + private PluginManager mPluginManager; private final Point mDisplaySize = new Point(); private final int mDisplayId; @@ -100,14 +101,6 @@ public class EdgeBackGestureHandler implements DisplayListener { private final float mTouchSlop; // Duration after which we consider the event as longpress. private final int mLongPressTimeout; - // The threshold where the touch needs to be at most, such that the arrow is displayed above the - // finger, otherwise it will be below - private final int mMinArrowPosition; - // The amount by which the arrow is shifted to avoid the finger - private final int mFingerOffset; - - - private final int mNavBarHeight; private final PointF mDownPoint = new PointF(); private boolean mThresholdCrossed = false; @@ -123,24 +116,49 @@ public class EdgeBackGestureHandler implements DisplayListener { private InputMonitor mInputMonitor; private InputEventReceiver mInputEventReceiver; - private final WindowManager mWm; - - private NavigationBarEdgePanel mEdgePanel; - private WindowManager.LayoutParams mEdgePanelLp; - private final Rect mSamplingRect = new Rect(); - private RegionSamplingHelper mRegionSamplingHelper; + private NavigationEdgeBackPlugin mEdgeBackPlugin; private int mLeftInset; private int mRightInset; private int mSysUiFlags; + private final NavigationEdgeBackPlugin.BackCallback mBackCallback = + new NavigationEdgeBackPlugin.BackCallback() { + @Override + public void triggerBack() { + sendEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK); + sendEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_BACK); + + mOverviewProxyService.notifyBackAction(true, (int) mDownPoint.x, + (int) mDownPoint.y, false /* isButton */, !mIsOnLeftEdge); + int backtype = (mInRejectedExclusion + ? StatsLog.BACK_GESTURE__TYPE__COMPLETED_REJECTED : + StatsLog.BACK_GESTURE__TYPE__COMPLETED); + StatsLog.write(StatsLog.BACK_GESTURE_REPORTED_REPORTED, backtype, + (int) mDownPoint.y, mIsOnLeftEdge + ? StatsLog.BACK_GESTURE__X_LOCATION__LEFT : + StatsLog.BACK_GESTURE__X_LOCATION__RIGHT); + } + + @Override + public void cancelBack() { + mOverviewProxyService.notifyBackAction(false, (int) mDownPoint.x, + (int) mDownPoint.y, false /* isButton */, !mIsOnLeftEdge); + int backtype = StatsLog.BACK_GESTURE__TYPE__INCOMPLETE; + StatsLog.write(StatsLog.BACK_GESTURE_REPORTED_REPORTED, backtype, + (int) mDownPoint.y, mIsOnLeftEdge + ? StatsLog.BACK_GESTURE__X_LOCATION__LEFT : + StatsLog.BACK_GESTURE__X_LOCATION__RIGHT); + } + }; + public EdgeBackGestureHandler(Context context, OverviewProxyService overviewProxyService, - SysUiState sysUiFlagContainer) { + SysUiState sysUiFlagContainer, PluginManager pluginManager) { final Resources res = context.getResources(); mContext = context; mDisplayId = context.getDisplayId(); mMainExecutor = context.getMainExecutor(); - mWm = context.getSystemService(WindowManager.class); mOverviewProxyService = overviewProxyService; + mPluginManager = pluginManager; // Reduce the default touch slop to ensure that we can intercept the gesture // before the app starts to react to it. @@ -149,9 +167,6 @@ public class EdgeBackGestureHandler implements DisplayListener { mLongPressTimeout = Math.min(MAX_LONG_PRESS_TIMEOUT, ViewConfiguration.getLongPressTimeout()); - mNavBarHeight = res.getDimensionPixelSize(R.dimen.navigation_bar_frame_height); - mMinArrowPosition = res.getDimensionPixelSize(R.dimen.navigation_edge_arrow_min_y); - mFingerOffset = res.getDimensionPixelSize(R.dimen.navigation_edge_finger_offset); updateCurrentUserResources(res); sysUiFlagContainer.addCallback(sysUiFlags -> mSysUiFlags = sysUiFlags); } @@ -206,15 +221,14 @@ public class EdgeBackGestureHandler implements DisplayListener { mIsEnabled = isEnabled; disposeInputChannel(); - if (mEdgePanel != null) { - mWm.removeView(mEdgePanel); - mEdgePanel = null; - mRegionSamplingHelper.stop(); - mRegionSamplingHelper = null; + if (mEdgeBackPlugin != null) { + mEdgeBackPlugin.onDestroy(); + mEdgeBackPlugin = null; } if (!mIsEnabled) { mContext.getSystemService(DisplayManager.class).unregisterDisplayListener(this); + mPluginManager.removePluginListener(this); try { WindowManagerGlobal.getWindowManagerService() @@ -244,39 +258,49 @@ public class EdgeBackGestureHandler implements DisplayListener { mInputMonitor.getInputChannel(), Looper.getMainLooper()); // Add a nav bar panel window - mEdgePanel = new NavigationBarEdgePanel(mContext); - mEdgePanelLp = new WindowManager.LayoutParams( - mContext.getResources() - .getDimensionPixelSize(R.dimen.navigation_edge_panel_width), - mContext.getResources() - .getDimensionPixelSize(R.dimen.navigation_edge_panel_height), - WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL, - WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE - | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL - | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH - | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN, - PixelFormat.TRANSLUCENT); - mEdgePanelLp.privateFlags |= - WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS; - mEdgePanelLp.setTitle(TAG + mDisplayId); - mEdgePanelLp.accessibilityTitle = mContext.getString(R.string.nav_bar_edge_panel); - mEdgePanelLp.windowAnimations = 0; - mEdgePanel.setLayoutParams(mEdgePanelLp); - mWm.addView(mEdgePanel, mEdgePanelLp); - mRegionSamplingHelper = new RegionSamplingHelper(mEdgePanel, - new RegionSamplingHelper.SamplingCallback() { - @Override - public void onRegionDarknessChanged(boolean isRegionDark) { - mEdgePanel.setIsDark(!isRegionDark, true /* animate */); - } - - @Override - public Rect getSampledRegion(View sampledView) { - return mSamplingRect; - } - }); - mRegionSamplingHelper.setWindowVisible(true); + setEdgeBackPlugin(new NavigationBarEdgePanel(mContext)); + mPluginManager.addPluginListener( + this, NavigationEdgeBackPlugin.class, /*allowMultiple=*/ false); + } + } + + @Override + public void onPluginConnected(NavigationEdgeBackPlugin plugin, Context context) { + setEdgeBackPlugin(plugin); + } + + @Override + public void onPluginDisconnected(NavigationEdgeBackPlugin plugin) { + setEdgeBackPlugin(new NavigationBarEdgePanel(mContext)); + } + + private void setEdgeBackPlugin(NavigationEdgeBackPlugin edgeBackPlugin) { + if (mEdgeBackPlugin != null) { + mEdgeBackPlugin.onDestroy(); } + mEdgeBackPlugin = edgeBackPlugin; + mEdgeBackPlugin.setBackCallback(mBackCallback); + mEdgeBackPlugin.setLayoutParams(createLayoutParams()); + updateDisplaySize(); + } + + private WindowManager.LayoutParams createLayoutParams() { + Resources resources = mContext.getResources(); + WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams( + resources.getDimensionPixelSize(R.dimen.navigation_edge_panel_width), + resources.getDimensionPixelSize(R.dimen.navigation_edge_panel_height), + WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL, + WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE + | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL + | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH + | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN, + PixelFormat.TRANSLUCENT); + layoutParams.privateFlags |= + WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS; + layoutParams.setTitle(TAG + mContext.getDisplayId()); + layoutParams.accessibilityTitle = mContext.getString(R.string.nav_bar_edge_panel); + layoutParams.windowAnimations = 0; + return layoutParams; } private void onInputEvent(InputEvent ev) { @@ -316,7 +340,7 @@ public class EdgeBackGestureHandler implements DisplayListener { mInRejectedExclusion = false; MotionEvent cancelEv = MotionEvent.obtain(ev); cancelEv.setAction(MotionEvent.ACTION_CANCEL); - mEdgePanel.handleTouch(cancelEv); + mEdgeBackPlugin.onMotionEvent(cancelEv); cancelEv.recycle(); } @@ -330,14 +354,8 @@ public class EdgeBackGestureHandler implements DisplayListener { mAllowGesture = !QuickStepContract.isBackGestureDisabled(mSysUiFlags) && isWithinTouchRegion((int) ev.getX(), (int) ev.getY()); if (mAllowGesture) { - mEdgePanelLp.gravity = mIsOnLeftEdge - ? (Gravity.LEFT | Gravity.TOP) - : (Gravity.RIGHT | Gravity.TOP); - mEdgePanel.setIsLeftPanel(mIsOnLeftEdge); - mEdgePanel.handleTouch(ev); - updateEdgePanelPosition(ev.getY()); - mWm.updateViewLayout(mEdgePanel, mEdgePanelLp); - mRegionSamplingHelper.start(mSamplingRect); + mEdgeBackPlugin.setIsLeftPanel(mIsOnLeftEdge); + mEdgeBackPlugin.onMotionEvent(ev); mDownPoint.set(ev.getX(), ev.getY()); mThresholdCrossed = false; @@ -369,53 +387,10 @@ public class EdgeBackGestureHandler implements DisplayListener { } // forward touch - mEdgePanel.handleTouch(ev); - - boolean isUp = action == MotionEvent.ACTION_UP; - if (isUp) { - boolean performAction = mEdgePanel.shouldTriggerBack(); - if (performAction) { - // Perform back - sendEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK); - sendEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_BACK); - } - mOverviewProxyService.notifyBackAction(performAction, (int) mDownPoint.x, - (int) mDownPoint.y, false /* isButton */, !mIsOnLeftEdge); - int backtype = performAction ? (mInRejectedExclusion - ? StatsLog.BACK_GESTURE__TYPE__COMPLETED_REJECTED : - StatsLog.BACK_GESTURE__TYPE__COMPLETED) : - StatsLog.BACK_GESTURE__TYPE__INCOMPLETE; - StatsLog.write(StatsLog.BACK_GESTURE_REPORTED_REPORTED, backtype, - (int) mDownPoint.y, mIsOnLeftEdge - ? StatsLog.BACK_GESTURE__X_LOCATION__LEFT : - StatsLog.BACK_GESTURE__X_LOCATION__RIGHT); - } - if (isUp || action == MotionEvent.ACTION_CANCEL) { - mRegionSamplingHelper.stop(); - } else { - updateSamplingRect(); - mRegionSamplingHelper.updateSamplingRect(); - } + mEdgeBackPlugin.onMotionEvent(ev); } } - private void updateEdgePanelPosition(float touchY) { - float position = touchY - mFingerOffset; - position = Math.max(position, mMinArrowPosition); - position = (position - mEdgePanelLp.height / 2.0f); - mEdgePanelLp.y = MathUtils.constrain((int) position, 0, mDisplaySize.y); - updateSamplingRect(); - } - - private void updateSamplingRect() { - int top = mEdgePanelLp.y; - int left = mIsOnLeftEdge ? mLeftInset : mDisplaySize.x - mRightInset - mEdgePanelLp.width; - int right = left + mEdgePanelLp.width; - int bottom = top + mEdgePanelLp.height; - mSamplingRect.set(left, top, right, bottom); - mEdgePanel.adjustRectToBoundingBox(mSamplingRect); - } - @Override public void onDisplayAdded(int displayId) { } @@ -433,6 +408,9 @@ public class EdgeBackGestureHandler implements DisplayListener { mContext.getSystemService(DisplayManager.class) .getDisplay(mDisplayId) .getRealSize(mDisplaySize); + if (mEdgeBackPlugin != null) { + mEdgeBackPlugin.setDisplaySize(mDisplaySize); + } } private void sendEvent(int action, int code) { @@ -454,6 +432,9 @@ public class EdgeBackGestureHandler implements DisplayListener { public void setInsets(int leftInset, int rightInset) { mLeftInset = leftInset; mRightInset = rightInset; + if (mEdgeBackPlugin != null) { + mEdgeBackPlugin.setInsets(leftInset, rightInset); + } } public void dump(PrintWriter pw) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarEdgePanel.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarEdgePanel.java index 4f223c385eb4..23573095e037 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarEdgePanel.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarEdgePanel.java @@ -19,34 +19,40 @@ package com.android.systemui.statusbar.phone; import android.animation.ValueAnimator; import android.content.Context; import android.content.res.Configuration; -import android.graphics.Canvas;; +import android.content.res.Resources; +import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Path; +import android.graphics.Point; import android.graphics.Rect; import android.os.SystemClock; import android.os.VibrationEffect; -import android.util.DisplayMetrics; import android.util.MathUtils; import android.view.ContextThemeWrapper; +import android.view.Gravity; import android.view.MotionEvent; import android.view.VelocityTracker; import android.view.View; +import android.view.WindowManager; import android.view.animation.Interpolator; import android.view.animation.PathInterpolator; +import androidx.core.graphics.ColorUtils; +import androidx.dynamicanimation.animation.DynamicAnimation; +import androidx.dynamicanimation.animation.FloatPropertyCompat; +import androidx.dynamicanimation.animation.SpringAnimation; +import androidx.dynamicanimation.animation.SpringForce; + import com.android.settingslib.Utils; import com.android.systemui.Dependency; import com.android.systemui.Interpolators; import com.android.systemui.R; +import com.android.systemui.plugins.NavigationEdgeBackPlugin; import com.android.systemui.statusbar.VibratorHelper; -import androidx.core.graphics.ColorUtils; -import androidx.dynamicanimation.animation.DynamicAnimation; -import androidx.dynamicanimation.animation.FloatPropertyCompat; -import androidx.dynamicanimation.animation.SpringAnimation; -import androidx.dynamicanimation.animation.SpringForce; +public class NavigationBarEdgePanel extends View implements NavigationEdgeBackPlugin { -public class NavigationBarEdgePanel extends View { + private static final String TAG = "NavigationBarEdgePanel"; private static final long COLOR_ANIMATION_DURATION_MS = 120; private static final long DISAPPEAR_FADE_ANIMATION_DURATION_MS = 80; @@ -114,6 +120,7 @@ public class NavigationBarEdgePanel extends View { private static final Interpolator RUBBER_BAND_INTERPOLATOR_APPEAR = new PathInterpolator(1.0f / RUBBER_BAND_AMOUNT_APPEAR, 1.0f, 1.0f, 1.0f); + private final WindowManager mWindowManager; private final VibratorHelper mVibratorHelper; /** @@ -134,9 +141,14 @@ public class NavigationBarEdgePanel extends View { * The minimum delta needed in movement for the arrow to change direction / stop triggering back */ private final float mMinDeltaForSwitch; + // The closest to y = 0 that the arrow will be displayed. + private int mMinArrowPosition; + // The amount the arrow is shifted to avoid the finger. + private int mFingerOffset; private final float mSwipeThreshold; private final Path mArrowPath = new Path(); + private final Point mDisplaySize = new Point(); private final SpringAnimation mAngleAnimation; private final SpringAnimation mTranslationAnimation; @@ -158,6 +170,11 @@ public class NavigationBarEdgePanel extends View { private int mArrowColorDark; private int mProtectionColor; private int mArrowColor; + private RegionSamplingHelper mRegionSamplingHelper; + private final Rect mSamplingRect = new Rect(); + private WindowManager.LayoutParams mLayoutParams; + private int mLeftInset; + private int mRightInset; /** * True if the panel is currently on the left of the screen @@ -242,10 +259,12 @@ public class NavigationBarEdgePanel extends View { return object.getVerticalTranslation(); } }; + private BackCallback mBackCallback; public NavigationBarEdgePanel(Context context) { super(context); + mWindowManager = context.getSystemService(WindowManager.class); mVibratorHelper = Dependency.get(VibratorHelper.class); mDensity = context.getResources().getDisplayMetrics().density; @@ -263,13 +282,10 @@ public class NavigationBarEdgePanel extends View { mArrowColorAnimator = ValueAnimator.ofFloat(0.0f, 1.0f); mArrowColorAnimator.setDuration(COLOR_ANIMATION_DURATION_MS); - mArrowColorAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(ValueAnimator animation) { - int newColor = ColorUtils.blendARGB(mArrowStartColor, mArrowColor, - animation.getAnimatedFraction()); - setCurrentArrowColor(newColor); - } + mArrowColorAnimator.addUpdateListener(animation -> { + int newColor = ColorUtils.blendARGB( + mArrowStartColor, mArrowColor, animation.getAnimatedFraction()); + setCurrentArrowColor(newColor); }); mArrowDisappearAnimation = ValueAnimator.ofFloat(0.0f, 1.0f); @@ -317,37 +333,79 @@ public class NavigationBarEdgePanel extends View { mSwipeThreshold = context.getResources() .getDimension(R.dimen.navigation_edge_action_drag_threshold); setVisibility(GONE); + + mRegionSamplingHelper = new RegionSamplingHelper(this, + new RegionSamplingHelper.SamplingCallback() { + @Override + public void onRegionDarknessChanged(boolean isRegionDark) { + setIsDark(!isRegionDark, true /* animate */); + } + + @Override + public Rect getSampledRegion(View sampledView) { + return mSamplingRect; + } + }); + mRegionSamplingHelper.setWindowVisible(true); } @Override - public boolean hasOverlappingRendering() { - return false; + public void onDestroy() { + mWindowManager.removeView(this); + mRegionSamplingHelper.stop(); + mRegionSamplingHelper = null; } - public boolean shouldTriggerBack() { - return mTriggerBack; + @Override + public boolean hasOverlappingRendering() { + return false; } - public void setIsDark(boolean isDark, boolean animate) { + private void setIsDark(boolean isDark, boolean animate) { mIsDark = isDark; updateIsDark(animate); } - public void setShowProtection(boolean showProtection) { + private void setShowProtection(boolean showProtection) { mShowProtection = showProtection; invalidate(); } + @Override public void setIsLeftPanel(boolean isLeftPanel) { mIsLeftPanel = isLeftPanel; + mLayoutParams.gravity = mIsLeftPanel + ? (Gravity.LEFT | Gravity.TOP) + : (Gravity.RIGHT | Gravity.TOP); + } + + @Override + public void setInsets(int leftInset, int rightInset) { + mLeftInset = leftInset; + mRightInset = rightInset; + } + + @Override + public void setDisplaySize(Point displaySize) { + mDisplaySize.set(displaySize.x, displaySize.y); + mScreenSize = Math.min(mDisplaySize.x, mDisplaySize.y); + } + + @Override + public void setBackCallback(BackCallback callback) { + mBackCallback = callback; + } + + @Override + public void setLayoutParams(WindowManager.LayoutParams layoutParams) { + mLayoutParams = layoutParams; + mWindowManager.addView(this, mLayoutParams); } /** - * Adjust the rect to conform the the actual visible bounding box of the arrow. - * - * @param samplingRect the existing bounding box in screen coordinates, to be modified + * Adjusts the sampling rect to conform to the actual visible bounding box of the arrow. */ - public void adjustRectToBoundingBox(Rect samplingRect) { + private void adjustSamplingRectToBoundingBox() { float translation = mDesiredTranslation; if (!mTriggerBack) { // Let's take the resting position and bounds as the sampling rect, since we are not @@ -361,7 +419,7 @@ public class NavigationBarEdgePanel extends View { } } float left = translation - mArrowThickness / 2.0f; - left = mIsLeftPanel ? left : samplingRect.width() - left; + left = mIsLeftPanel ? left : mSamplingRect.width() - left; // Let's calculate the position of the end based on the angle float width = getStaticArrowWidth(); @@ -371,49 +429,49 @@ public class NavigationBarEdgePanel extends View { } float top = (getHeight() * 0.5f) + mDesiredVerticalTranslation - height / 2.0f; - samplingRect.offset((int) left, (int) top); - samplingRect.set(samplingRect.left, samplingRect.top, - (int) (samplingRect.left + width), - (int) (samplingRect.top + height)); + mSamplingRect.offset((int) left, (int) top); + mSamplingRect.set(mSamplingRect.left, mSamplingRect.top, + (int) (mSamplingRect.left + width), + (int) (mSamplingRect.top + height)); + mRegionSamplingHelper.updateSamplingRect(); } - /** - * Updates the UI based on the motion events passed in device co-ordinates - */ - public void handleTouch(MotionEvent event) { + @Override + public void onMotionEvent(MotionEvent event) { if (mVelocityTracker == null) { mVelocityTracker = VelocityTracker.obtain(); } mVelocityTracker.addMovement(event); switch (event.getActionMasked()) { - case MotionEvent.ACTION_DOWN : { + case MotionEvent.ACTION_DOWN: mDragSlopPassed = false; resetOnDown(); mStartX = event.getX(); mStartY = event.getY(); setVisibility(VISIBLE); + updatePosition(event.getY()); + mRegionSamplingHelper.start(mSamplingRect); + mWindowManager.updateViewLayout(this, mLayoutParams); break; - } - case MotionEvent.ACTION_MOVE: { + case MotionEvent.ACTION_MOVE: handleMoveEvent(event); break; - } - // Fall through case MotionEvent.ACTION_UP: - case MotionEvent.ACTION_CANCEL: { if (mTriggerBack) { triggerBack(); } else { - if (mTranslationAnimation.isRunning()) { - mTranslationAnimation.addEndListener(mSetGoneEndListener); - } else { - setVisibility(GONE); - } + cancelBack(); } + mRegionSamplingHelper.stop(); + mVelocityTracker.recycle(); + mVelocityTracker = null; + break; + case MotionEvent.ACTION_CANCEL: + cancelBack(); + mRegionSamplingHelper.stop(); mVelocityTracker.recycle(); mVelocityTracker = null; break; - } } } @@ -452,10 +510,10 @@ public class NavigationBarEdgePanel extends View { } private void loadDimens() { - mArrowPaddingEnd = getContext().getResources().getDimensionPixelSize( - R.dimen.navigation_edge_panel_padding); - DisplayMetrics metrics = getResources().getDisplayMetrics(); - mScreenSize = Math.min(metrics.widthPixels, metrics.heightPixels); + Resources res = getResources(); + mArrowPaddingEnd = res.getDimensionPixelSize(R.dimen.navigation_edge_panel_padding); + mMinArrowPosition = res.getDimensionPixelSize(R.dimen.navigation_edge_arrow_min_y); + mFingerOffset = res.getDimensionPixelSize(R.dimen.navigation_edge_finger_offset); } private void updateArrowDirection() { @@ -531,6 +589,11 @@ public class NavigationBarEdgePanel extends View { } private void triggerBack() { + mBackCallback.triggerBack(); + + if (mVelocityTracker == null) { + mVelocityTracker = VelocityTracker.obtain(); + } mVelocityTracker.computeCurrentVelocity(1000); // Only do the extra translation if we're not already flinging boolean isSlow = Math.abs(mVelocityTracker.getXVelocity()) < 500; @@ -573,7 +636,16 @@ public class NavigationBarEdgePanel extends View { } else { translationEnd.run(); } + } + + private void cancelBack() { + mBackCallback.cancelBack(); + if (mTranslationAnimation.isRunning()) { + mTranslationAnimation.addEndListener(mSetGoneEndListener); + } else { + setVisibility(GONE); + } } private void resetOnDown() { @@ -680,6 +752,24 @@ public class NavigationBarEdgePanel extends View { float verticalTranslation = RUBBER_BAND_INTERPOLATOR.getInterpolation(progress) * maxYOffset * Math.signum(yOffset); setDesiredVerticalTransition(verticalTranslation, true /* animated */); + updateSamplingRect(); + } + + private void updatePosition(float touchY) { + float position = touchY - mFingerOffset; + position = Math.max(position, mMinArrowPosition); + position -= mLayoutParams.height / 2.0f; + mLayoutParams.y = MathUtils.constrain((int) position, 0, mDisplaySize.y); + updateSamplingRect(); + } + + private void updateSamplingRect() { + int top = mLayoutParams.y; + int left = mIsLeftPanel ? mLeftInset : mDisplaySize.x - mRightInset - mLayoutParams.width; + int right = left + mLayoutParams.width; + int bottom = top + mLayoutParams.height; + mSamplingRect.set(left, top, right, bottom); + adjustSamplingRectToBoundingBox(); } private void setDesiredVerticalTransition(float verticalTranslation, boolean animated) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java index d3c79404863e..5a1b20dd1e71 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java @@ -72,6 +72,7 @@ import com.android.systemui.model.SysUiState; import com.android.systemui.recents.OverviewProxyService; import com.android.systemui.recents.Recents; import com.android.systemui.recents.RecentsOnboarding; +import com.android.systemui.shared.plugins.PluginManager; import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.shared.system.QuickStepContract; import com.android.systemui.shared.system.WindowManagerWrapper; @@ -96,6 +97,7 @@ public class NavigationBarView extends FrameLayout implements private final RegionSamplingHelper mRegionSamplingHelper; private final int mNavColorSampleMargin; private final SysUiState mSysUiFlagContainer; + private final PluginManager mPluginManager; View mCurrentView = null; private View mVertical; @@ -272,6 +274,7 @@ public class NavigationBarView extends FrameLayout implements boolean isGesturalMode = isGesturalMode(mNavBarMode); mSysUiFlagContainer = Dependency.get(SysUiState.class); + mPluginManager = Dependency.get(PluginManager.class); // Set up the context group of buttons mContextualButtonGroup = new ContextualButtonGroup(R.id.menu_container); final ContextualButton imeSwitcherButton = new ContextualButton(R.id.ime_switcher, @@ -315,8 +318,8 @@ public class NavigationBarView extends FrameLayout implements mNavColorSampleMargin = getResources() .getDimensionPixelSize(R.dimen.navigation_handle_sample_horizontal_margin); - mEdgeBackGestureHandler = - new EdgeBackGestureHandler(context, mOverviewProxyService, mSysUiFlagContainer); + mEdgeBackGestureHandler = new EdgeBackGestureHandler( + context, mOverviewProxyService, mSysUiFlagContainer, mPluginManager); mRegionSamplingHelper = new RegionSamplingHelper(this, new RegionSamplingHelper.SamplingCallback() { @Override diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowViewController.java index c1328ec2a060..6d6a1fe4d0b1 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowViewController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowViewController.java @@ -188,6 +188,7 @@ public class StatusBarWindowViewController { boolean isUp = ev.getActionMasked() == MotionEvent.ACTION_UP; boolean isCancel = ev.getActionMasked() == MotionEvent.ACTION_CANCEL; + boolean expandingBelowNotch = mExpandingBelowNotch; if (isUp || isCancel) { mExpandingBelowNotch = false; } @@ -236,8 +237,9 @@ public class StatusBarWindowViewController { // regular view bounds. if (isDown && ev.getY() >= mView.getBottom()) { mExpandingBelowNotch = true; + expandingBelowNotch = true; } - if (mExpandingBelowNotch) { + if (expandingBelowNotch) { return mStatusBarView.dispatchTouchEvent(ev); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java index f0f94201f3af..dc809066524f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java @@ -33,13 +33,13 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.settingslib.fuelgauge.BatterySaverUtils; import com.android.settingslib.fuelgauge.Estimate; import com.android.settingslib.utils.PowerUtil; -import com.android.systemui.Dependency; import com.android.systemui.broadcast.BroadcastDispatcher; +import com.android.systemui.dagger.qualifiers.BgHandler; +import com.android.systemui.dagger.qualifiers.MainHandler; import com.android.systemui.power.EnhancedEstimates; import java.io.FileDescriptor; import java.io.PrintWriter; -import java.text.NumberFormat; import java.util.ArrayList; import javax.inject.Inject; @@ -53,42 +53,39 @@ import javax.inject.Singleton; public class BatteryControllerImpl extends BroadcastReceiver implements BatteryController { private static final String TAG = "BatteryController"; - public static final String ACTION_LEVEL_TEST = "com.android.systemui.BATTERY_LEVEL_TEST"; + private static final String ACTION_LEVEL_TEST = "com.android.systemui.BATTERY_LEVEL_TEST"; private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); - private static final int UPDATE_GRANULARITY_MSEC = 1000 * 60; private final EnhancedEstimates mEstimates; private final BroadcastDispatcher mBroadcastDispatcher; - private final ArrayList<BatteryController.BatteryStateChangeCallback> mChangeCallbacks = new ArrayList<>(); + private final ArrayList<BatteryController.BatteryStateChangeCallback> + mChangeCallbacks = new ArrayList<>(); private final ArrayList<EstimateFetchCompletion> mFetchCallbacks = new ArrayList<>(); private final PowerManager mPowerManager; - private final Handler mHandler; + private final Handler mMainHandler; + private final Handler mBgHandler; private final Context mContext; - protected int mLevel; - protected boolean mPluggedIn; - protected boolean mCharging; - protected boolean mCharged; - protected boolean mPowerSave; - protected boolean mAodPowerSave; + private int mLevel; + private boolean mPluggedIn; + private boolean mCharging; + private boolean mCharged; + private boolean mPowerSave; + private boolean mAodPowerSave; private boolean mTestmode = false; private boolean mHasReceivedBattery = false; private Estimate mEstimate; private boolean mFetchingEstimate = false; - @Inject - public BatteryControllerImpl(Context context, EnhancedEstimates enhancedEstimates, - BroadcastDispatcher broadcastDispatcher) { - this(context, enhancedEstimates, context.getSystemService(PowerManager.class), - broadcastDispatcher); - } - @VisibleForTesting + @Inject BatteryControllerImpl(Context context, EnhancedEstimates enhancedEstimates, - PowerManager powerManager, BroadcastDispatcher broadcastDispatcher) { + PowerManager powerManager, BroadcastDispatcher broadcastDispatcher, + @MainHandler Handler mainHandler, @BgHandler Handler bgHandler) { mContext = context; - mHandler = new Handler(); + mMainHandler = mainHandler; + mBgHandler = bgHandler; mPowerManager = powerManager; mEstimates = enhancedEstimates; mBroadcastDispatcher = broadcastDispatcher; @@ -162,7 +159,7 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC setPowerSave(intent.getBooleanExtra(PowerManager.EXTRA_POWER_SAVE_MODE, false)); } else if (action.equals(ACTION_LEVEL_TEST)) { mTestmode = true; - mHandler.post(new Runnable() { + mMainHandler.post(new Runnable() { int curLevel = 0; int incr = 1; int saveLevel = mLevel; @@ -189,7 +186,7 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC if (curLevel == 100) { incr *= -1; } - mHandler.postDelayed(this, 200); + mMainHandler.postDelayed(this, 200); } }); } @@ -222,7 +219,6 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC return null; } - String percentage = NumberFormat.getPercentInstance().format((double) mLevel / 100.0); return PowerUtil.getBatteryRemainingShortStringFormatted( mContext, mEstimate.getEstimateMillis()); } @@ -235,7 +231,7 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC } mFetchingEstimate = true; - Dependency.get(Dependency.BG_HANDLER).post(() -> { + mBgHandler.post(() -> { // Only fetch the estimate if they are enabled synchronized (mFetchCallbacks) { mEstimate = null; @@ -244,7 +240,7 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC } } mFetchingEstimate = false; - Dependency.get(Dependency.MAIN_HANDLER).post(this::notifyEstimateFetchCallbacks); + mMainHandler.post(this::notifyEstimateFetchCallbacks); }); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifListBuilderImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifListBuilderImplTest.java index 7326cd4002bb..a25af84ca28e 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifListBuilderImplTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifListBuilderImplTest.java @@ -34,7 +34,6 @@ import static org.mockito.Mockito.verify; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.util.ArrayMap; -import android.util.Log; import androidx.test.filters.SmallTest; @@ -121,7 +120,7 @@ public class NotifListBuilderImplTest extends SysuiTestCase { addNotif(6, PACKAGE_1).setRank(0); dispatchBuild(); - // The final output is sorted based on rank + // The final output is sorted based first by rank and then by when verifyBuiltList( notif(6), notif(5), @@ -204,7 +203,7 @@ public class NotifListBuilderImplTest extends SysuiTestCase { addGroupSummary(6, PACKAGE_1, GROUP_1).setRank(3); dispatchBuild(); - // THEN the notifs are grouped together + // THEN the children are sorted by rank and when verifyBuiltList( group( summary(6), @@ -503,10 +502,6 @@ public class NotifListBuilderImplTest extends SysuiTestCase { addNotif(5, PACKAGE_3); dispatchBuild(); - for (NotificationEntry entry : mEntrySet) { - Log.d("pizza", "entry: " + entry.getKey() + " " + entry); - } - // THEN both promoters are called on each child, except for children that a previous // promoter has already promoted verify(promoter1).shouldPromoteToTopLevel(mEntrySet.get(1)); @@ -840,6 +835,9 @@ public class NotifListBuilderImplTest extends SysuiTestCase { notif(0) ); assertNull(group.getParent()); + + // but its previous parent indicates that it was added in the previous iteration + assertEquals(GroupEntry.ROOT_ENTRY, group.getPreviousParent()); } @Test(expected = IllegalStateException.class) @@ -860,14 +858,14 @@ public class NotifListBuilderImplTest extends SysuiTestCase { @Test(expected = IllegalStateException.class) public void testOutOfOrderPrompterInvalidationThrows() { - // GIVEN a NotifFilter that gets invalidated during the grouping stage + // GIVEN a NotifPromoter that gets invalidated during the sorting stage NotifPromoter promoter = new IdPromoter(47); OnBeforeSortListener listener = (list) -> promoter.invalidateList(); mListBuilder.addPromoter(promoter); mListBuilder.addOnBeforeSortListener(listener); - // WHEN we try to run the pipeline and the filter is invalidated + // WHEN we try to run the pipeline and the promoter is invalidated addNotif(0, PACKAGE_1); dispatchBuild(); @@ -876,14 +874,14 @@ public class NotifListBuilderImplTest extends SysuiTestCase { @Test(expected = IllegalStateException.class) public void testOutOfOrderComparatorInvalidationThrows() { - // GIVEN a NotifFilter that gets invalidated during the grouping stage + // GIVEN a NotifComparator that gets invalidated during the finalizing stage NotifComparator comparator = new HypeComparator(PACKAGE_5); OnBeforeRenderListListener listener = (list) -> comparator.invalidateList(); mListBuilder.setComparators(Collections.singletonList(comparator)); mListBuilder.addOnBeforeRenderListListener(listener); - // WHEN we try to run the pipeline and the filter is invalidated + // WHEN we try to run the pipeline and the comparator is invalidated addNotif(0, PACKAGE_1); dispatchBuild(); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BatteryControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BatteryControllerTest.java index 48ed4ba2224c..05a48678c8d7 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BatteryControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BatteryControllerTest.java @@ -20,6 +20,7 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import android.content.Intent; +import android.os.Handler; import android.os.PowerManager; import android.os.PowerSaveState; import android.test.suitebuilder.annotation.SmallTest; @@ -53,7 +54,7 @@ public class BatteryControllerTest extends SysuiTestCase { public void setUp() { MockitoAnnotations.initMocks(this); mBatteryController = new BatteryControllerImpl(getContext(), mock(EnhancedEstimates.class), - mPowerManager, mBroadcastDispatcher); + mPowerManager, mBroadcastDispatcher, new Handler(), new Handler()); } @Test diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 4bb29f014d0e..3dc745b0cb95 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -346,7 +346,6 @@ import com.android.server.ThreadPriorityBooster; import com.android.server.Watchdog; import com.android.server.am.ActivityManagerServiceDumpProcessesProto.UidObserverRegistrationProto; import com.android.server.appop.AppOpsService; -import com.android.server.compat.CompatConfig; import com.android.server.compat.PlatformCompat; import com.android.server.contentcapture.ContentCaptureManagerInternal; import com.android.server.firewall.IntentFirewall; @@ -5032,8 +5031,9 @@ public class ActivityManagerService extends IActivityManager.Stub bindApplicationTimeMillis = SystemClock.elapsedRealtime(); mAtmInternal.preBindApplication(app.getWindowProcessController()); final ActiveInstrumentation instr2 = app.getActiveInstrumentation(); - long[] disabledCompatChanges = CompatConfig.get().getDisabledChanges(app.info); + long[] disabledCompatChanges = {}; if (mPlatformCompat != null) { + disabledCompatChanges = mPlatformCompat.getDisabledChanges(app.info); mPlatformCompat.resetReporting(app.info); } if (app.isolatedEntryPoint != null) { diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java index 1f56176bf00d..908ec6b844c2 100644 --- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java +++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java @@ -37,11 +37,13 @@ import android.app.IStopUserCallback; import android.app.IUidObserver; import android.app.KeyguardManager; import android.app.ProfilerInfo; +import android.app.UserSwitchObserver; import android.app.WaitResult; import android.app.usage.AppStandbyInfo; import android.app.usage.ConfigurationStats; import android.app.usage.IUsageStatsManager; import android.app.usage.UsageStatsManager; +import android.compat.Compatibility; import android.content.ComponentCallbacks2; import android.content.ComponentName; import android.content.Context; @@ -80,15 +82,17 @@ import android.os.UserHandle; import android.os.UserManager; import android.text.TextUtils; import android.util.ArrayMap; +import android.util.ArraySet; import android.util.DebugUtils; import android.util.DisplayMetrics; import android.util.proto.ProtoOutputStream; import android.view.Display; +import com.android.internal.compat.CompatibilityChangeConfig; import com.android.internal.util.HexDump; import com.android.internal.util.MemInfoReader; import com.android.internal.util.Preconditions; -import com.android.server.compat.CompatConfig; +import com.android.server.compat.PlatformCompat; import java.io.BufferedReader; import java.io.File; @@ -1729,6 +1733,30 @@ final class ActivityManagerShellCommand extends ShellCommand { return 0; } + private void switchUserAndWaitForComplete(int userId) throws RemoteException { + // Register switch observer. + final CountDownLatch switchLatch = new CountDownLatch(1); + mInterface.registerUserSwitchObserver( + new UserSwitchObserver() { + @Override + public void onUserSwitchComplete(int newUserId) { + if (userId == newUserId) { + switchLatch.countDown(); + } + } + }, ActivityManagerShellCommand.class.getName()); + + // Switch. + mInterface.switchUser(userId); + + // Wait. + try { + switchLatch.await(USER_OPERATION_TIMEOUT_MS, TimeUnit.MILLISECONDS); + } catch (InterruptedException e) { + getErrPrintWriter().println("Thread interrupted unexpectedly."); + } + } + int runSwitchUser(PrintWriter pw) throws RemoteException { UserManager userManager = mInternal.mContext.getSystemService(UserManager.class); final int userSwitchable = userManager.getUserSwitchability(); @@ -1736,8 +1764,23 @@ final class ActivityManagerShellCommand extends ShellCommand { getErrPrintWriter().println("Error: " + userSwitchable); return -1; } - String user = getNextArgRequired(); - mInterface.switchUser(Integer.parseInt(user)); + boolean wait = false; + String opt; + while ((opt = getNextOption()) != null) { + if ("-w".equals(opt)) { + wait = true; + } else { + getErrPrintWriter().println("Error: unknown option: " + opt); + return -1; + } + } + + int userId = Integer.parseInt(getNextArgRequired()); + if (wait) { + switchUserAndWaitForComplete(userId); + } else { + mInterface.switchUser(userId); + } return 0; } @@ -2862,56 +2905,49 @@ final class ActivityManagerShellCommand extends ShellCommand { return 0; } - private void killPackage(String packageName, PrintWriter pw) throws RemoteException { - int uid = mPm.getPackageUid(packageName, 0, mUserId); - if (uid < 0) { - // uid is negative if the package wasn't found. - pw.println("Didn't find package " + packageName + " on device."); - } else { - pw.println("Killing package " + packageName + " (UID " + uid + ")."); - final long origId = Binder.clearCallingIdentity(); - mInterface.killUid(UserHandle.getAppId(uid), - UserHandle.USER_ALL, "killPackage"); - Binder.restoreCallingIdentity(origId); - } - } - private int runCompat(PrintWriter pw) throws RemoteException { - final CompatConfig config = CompatConfig.get(); + final PlatformCompat platformCompat = (PlatformCompat) + ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE); String toggleValue = getNextArgRequired(); long changeId; String changeIdString = getNextArgRequired(); try { changeId = Long.parseLong(changeIdString); } catch (NumberFormatException e) { - changeId = config.lookupChangeId(changeIdString); + changeId = platformCompat.lookupChangeId(changeIdString); } if (changeId == -1) { pw.println("Unknown or invalid change: '" + changeIdString + "'."); + return -1; } String packageName = getNextArgRequired(); + if (!platformCompat.isKnownChangeId(changeId)) { + pw.println("Warning! Change " + changeId + " is not known yet. Enabling/disabling it" + + " could have no effect."); + } + ArraySet<Long> enabled = new ArraySet<>(); + ArraySet<Long> disabled = new ArraySet<>(); switch (toggleValue) { case "enable": - if (!config.addOverride(changeId, packageName, true)) { - pw.println("Warning! Change " + changeId + " is not known yet. Enabling it" - + " could have no effect."); - } + enabled.add(changeId); pw.println("Enabled change " + changeId + " for " + packageName + "."); - killPackage(packageName, pw); + CompatibilityChangeConfig overrides = + new CompatibilityChangeConfig( + new Compatibility.ChangeConfig(enabled, disabled)); + platformCompat.setOverrides(overrides, packageName); return 0; case "disable": - if (!config.addOverride(changeId, packageName, false)) { - pw.println("Warning! Change " + changeId + " is not known yet. Disabling it" - + " could have no effect."); - } + disabled.add(changeId); pw.println("Disabled change " + changeId + " for " + packageName + "."); - killPackage(packageName, pw); + overrides = + new CompatibilityChangeConfig( + new Compatibility.ChangeConfig(enabled, disabled)); + platformCompat.setOverrides(overrides, packageName); return 0; case "reset": - if (config.removeOverride(changeId, packageName)) { + if (platformCompat.clearOverride(changeId, packageName)) { pw.println("Reset change " + changeId + " for " + packageName + " to default value."); - killPackage(packageName, pw); } else { pw.println("No override exists for changeId " + changeId + "."); } diff --git a/services/core/java/com/android/server/compat/CompatConfig.java b/services/core/java/com/android/server/compat/CompatConfig.java index d6ec22b078ea..490cce347188 100644 --- a/services/core/java/com/android/server/compat/CompatConfig.java +++ b/services/core/java/com/android/server/compat/CompatConfig.java @@ -43,13 +43,14 @@ import java.util.HashSet; import java.util.Set; import javax.xml.datatype.DatatypeConfigurationException; + /** * This class maintains state relating to platform compatibility changes. * * <p>It stores the default configuration for each change, and any per-package overrides that have * been configured. */ -public final class CompatConfig { +final class CompatConfig { private static final String TAG = "CompatConfig"; @@ -61,13 +62,13 @@ public final class CompatConfig { private final LongSparseArray<CompatChange> mChanges = new LongSparseArray<>(); @VisibleForTesting - public CompatConfig() { + CompatConfig() { } /** * @return The static instance of this class to be used within the system server. */ - public static CompatConfig get() { + static CompatConfig get() { return sInstance; } @@ -77,7 +78,7 @@ public final class CompatConfig { * * @param change The change to add. Any change with the same ID will be overwritten. */ - public void addChange(CompatChange change) { + void addChange(CompatChange change) { synchronized (mChanges) { mChanges.put(change.getId(), change); } @@ -89,10 +90,10 @@ public final class CompatConfig { * * @param app The app in question * @return A sorted long array of change IDs. We use a primitive array to minimize memory - * footprint: Every app process will store this array statically so we aim to reduce - * overhead as much as possible. + * footprint: Every app process will store this array statically so we aim to reduce + * overhead as much as possible. */ - public long[] getDisabledChanges(ApplicationInfo app) { + long[] getDisabledChanges(ApplicationInfo app) { LongArray disabled = new LongArray(); synchronized (mChanges) { for (int i = 0; i < mChanges.size(); ++i) { @@ -113,7 +114,7 @@ public final class CompatConfig { * @param name Name of the change to look up * @return The change ID, or {@code -1} if no change with that name exists. */ - public long lookupChangeId(String name) { + long lookupChangeId(String name) { synchronized (mChanges) { for (int i = 0; i < mChanges.size(); ++i) { if (TextUtils.equals(mChanges.valueAt(i).getName(), name)) { @@ -128,11 +129,11 @@ public final class CompatConfig { * Find if a given change is enabled for a given application. * * @param changeId The ID of the change in question - * @param app App to check for + * @param app App to check for * @return {@code true} if the change is enabled for this app. Also returns {@code true} if the - * change ID is not known, as unknown changes are enabled by default. + * change ID is not known, as unknown changes are enabled by default. */ - public boolean isChangeEnabled(long changeId, ApplicationInfo app) { + boolean isChangeEnabled(long changeId, ApplicationInfo app) { synchronized (mChanges) { CompatChange c = mChanges.get(changeId); if (c == null) { @@ -150,14 +151,15 @@ public final class CompatConfig { * * <p>Note, package overrides are not persistent and will be lost on system or runtime restart. * - * @param changeId The ID of the change to be overridden. Note, this call will succeed even if - * this change is not known; it will only have any effect if any code in the - * platform is gated on the ID given. + * @param changeId The ID of the change to be overridden. Note, this call will succeed even + * if + * this change is not known; it will only have any effect if any code in the + * platform is gated on the ID given. * @param packageName The app package name to override the change for. - * @param enabled If the change should be enabled or disabled. + * @param enabled If the change should be enabled or disabled. * @return {@code true} if the change existed before adding the override. */ - public boolean addOverride(long changeId, String packageName, boolean enabled) { + boolean addOverride(long changeId, String packageName, boolean enabled) { boolean alreadyKnown = true; synchronized (mChanges) { CompatChange c = mChanges.get(changeId); @@ -172,15 +174,27 @@ public final class CompatConfig { } /** + * Check whether the change is known to the compat config. + * + * @return {@code true} if the change is known. + */ + boolean isKnownChangeId(long changeId) { + synchronized (mChanges) { + CompatChange c = mChanges.get(changeId); + return c != null; + } + } + + /** * Removes an override previously added via {@link #addOverride(long, String, boolean)}. This * restores the default behaviour for the given change and app, once any app processes have been * restarted. * - * @param changeId The ID of the change that was overridden. + * @param changeId The ID of the change that was overridden. * @param packageName The app package name that was overridden. * @return {@code true} if an override existed; */ - public boolean removeOverride(long changeId, String packageName) { + boolean removeOverride(long changeId, String packageName) { boolean overrideExists = false; synchronized (mChanges) { CompatChange c = mChanges.get(changeId); @@ -191,22 +205,22 @@ public final class CompatConfig { } return overrideExists; } + /** * Overrides the enabled state for a given change and app. This method is intended to be used * *only* for debugging purposes. * * <p>Note, package overrides are not persistent and will be lost on system or runtime restart. * - * @param overrides list of overrides to default changes config. + * @param overrides list of overrides to default changes config. * @param packageName app for which the overrides will be applied. */ - public void addOverrides( - CompatibilityChangeConfig overrides, String packageName) { + void addOverrides(CompatibilityChangeConfig overrides, String packageName) { synchronized (mChanges) { - for (Long changeId: overrides.enabledChanges()) { + for (Long changeId : overrides.enabledChanges()) { addOverride(changeId, packageName, true); } - for (Long changeId: overrides.disabledChanges()) { + for (Long changeId : overrides.disabledChanges()) { addOverride(changeId, packageName, false); } } @@ -221,7 +235,7 @@ public final class CompatConfig { * * @param packageName The package for which the overrides should be purged. */ - public void removePackageOverrides(String packageName) { + void removePackageOverrides(String packageName) { synchronized (mChanges) { for (int i = 0; i < mChanges.size(); ++i) { mChanges.valueAt(i).removePackageOverride(packageName); @@ -230,11 +244,11 @@ public final class CompatConfig { } /** - * Dumps the current list of compatibility config information. - * - * @param pw The {@link PrintWriter} instance to which the information will be dumped. - */ - public void dumpConfig(PrintWriter pw) { + * Dumps the current list of compatibility config information. + * + * @param pw The {@link PrintWriter} instance to which the information will be dumped. + */ + void dumpConfig(PrintWriter pw) { synchronized (mChanges) { if (mChanges.size() == 0) { pw.println("No compat overrides."); @@ -252,10 +266,10 @@ public final class CompatConfig { * * @param applicationInfo the {@link ApplicationInfo} for which the info should be dumped. * @return A {@link CompatibilityChangeConfig} which contains the compat config info for the - * given app. + * given app. */ - public CompatibilityChangeConfig getAppConfig(ApplicationInfo applicationInfo) { + CompatibilityChangeConfig getAppConfig(ApplicationInfo applicationInfo) { Set<Long> enabled = new HashSet<>(); Set<Long> disabled = new HashSet<>(); synchronized (mChanges) { @@ -276,15 +290,15 @@ public final class CompatConfig { * * @return An array of {@link CompatibilityChangeInfo} with the current changes. */ - public CompatibilityChangeInfo[] dumpChanges() { + CompatibilityChangeInfo[] dumpChanges() { synchronized (mChanges) { CompatibilityChangeInfo[] changeInfos = new CompatibilityChangeInfo[mChanges.size()]; for (int i = 0; i < mChanges.size(); ++i) { CompatChange change = mChanges.valueAt(i); changeInfos[i] = new CompatibilityChangeInfo(change.getId(), - change.getName(), - change.getEnableAfterTargetSdk(), - change.getDisabled()); + change.getName(), + change.getEnableAfterTargetSdk(), + change.getDisabled()); } return changeInfos; } diff --git a/services/core/java/com/android/server/compat/PlatformCompat.java b/services/core/java/com/android/server/compat/PlatformCompat.java index 75e2d220898d..709f3f82d4c5 100644 --- a/services/core/java/com/android/server/compat/PlatformCompat.java +++ b/services/core/java/com/android/server/compat/PlatformCompat.java @@ -16,9 +16,13 @@ package com.android.server.compat; +import android.app.ActivityManager; +import android.app.IActivityManager; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; +import android.os.Binder; +import android.os.RemoteException; import android.os.UserHandle; import android.util.Slog; import android.util.StatsLog; @@ -106,12 +110,26 @@ public class PlatformCompat extends IPlatformCompat.Stub { @Override public void setOverrides(CompatibilityChangeConfig overrides, String packageName) { CompatConfig.get().addOverrides(overrides, packageName); + killPackage(packageName); + } + + @Override + public void setOverridesForTest(CompatibilityChangeConfig overrides, String packageName) { + CompatConfig.get().addOverrides(overrides, packageName); } @Override public void clearOverrides(String packageName) { CompatConfig config = CompatConfig.get(); config.removePackageOverrides(packageName); + killPackage(packageName); + } + + @Override + public boolean clearOverride(long changeId, String packageName) { + boolean existed = CompatConfig.get().removeOverride(changeId, packageName); + killPackage(packageName); + return existed; } @Override @@ -124,6 +142,39 @@ public class PlatformCompat extends IPlatformCompat.Stub { return CompatConfig.get().dumpChanges(); } + /** + * Check whether the change is known to the compat config. + * @param changeId + * @return {@code true} if the change is known. + */ + public boolean isKnownChangeId(long changeId) { + return CompatConfig.get().isKnownChangeId(changeId); + + } + + /** + * Retrieves the set of disabled changes for a given app. Any change ID not in the returned + * array is by default enabled for the app. + * + * @param appInfo The app in question + * @return A sorted long array of change IDs. We use a primitive array to minimize memory + * footprint: Every app process will store this array statically so we aim to reduce + * overhead as much as possible. + */ + public long[] getDisabledChanges(ApplicationInfo appInfo) { + return CompatConfig.get().getDisabledChanges(appInfo); + } + + /** + * Look up a change ID by name. + * + * @param name Name of the change to look up + * @return The change ID, or {@code -1} if no change with that name exists. + */ + public long lookupChangeId(String name) { + return CompatConfig.get().lookupChangeId(name); + } + @Override protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, "platform_compat", pw)) return; @@ -151,4 +202,34 @@ public class PlatformCompat extends IPlatformCompat.Stub { private void reportChange(long changeId, int uid, int state) { mChangeReporter.reportChange(uid, changeId, state); } + + private void killPackage(String packageName) { + int uid = -1; + try { + uid = mContext.getPackageManager().getPackageUid(packageName, 0); + } catch (PackageManager.NameNotFoundException e) { + Slog.w(TAG, "Didn't find package " + packageName + " on device.", e); + return; + } + + Slog.d(TAG, "Killing package " + packageName + " (UID " + uid + ")."); + killUid(UserHandle.getAppId(uid), + UserHandle.USER_ALL, "PlatformCompat overrides"); + } + + private void killUid(int appId, int userId, String reason) { + final long identity = Binder.clearCallingIdentity(); + try { + IActivityManager am = ActivityManager.getService(); + if (am != null) { + try { + am.killUid(appId, userId, reason); + } catch (RemoteException e) { + /* ignore - same process */ + } + } + } finally { + Binder.restoreCallingIdentity(identity); + } + } } diff --git a/services/core/java/com/android/server/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java index b3804c4d7ec5..acedc3635730 100644 --- a/services/core/java/com/android/server/connectivity/Tethering.java +++ b/services/core/java/com/android/server/connectivity/Tethering.java @@ -286,8 +286,8 @@ public class Tethering extends BaseNetworkObserver { private void startStateMachineUpdaters(Handler handler) { mCarrierConfigChange.startListening(); - TelephonyManager.from(mContext).listen(mPhoneStateListener, - PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE); + mContext.getSystemService(TelephonyManager.class).listen( + mPhoneStateListener, PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE); IntentFilter filter = new IntentFilter(); filter.addAction(UsbManager.ACTION_USB_STATE); diff --git a/services/core/java/com/android/server/display/BrightnessTracker.java b/services/core/java/com/android/server/display/BrightnessTracker.java index 126beeffbb96..eea1980012a4 100644 --- a/services/core/java/com/android/server/display/BrightnessTracker.java +++ b/services/core/java/com/android/server/display/BrightnessTracker.java @@ -34,6 +34,7 @@ import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.hardware.display.AmbientBrightnessDayStats; import android.hardware.display.BrightnessChangeEvent; +import android.hardware.display.BrightnessConfiguration; import android.hardware.display.ColorDisplayManager; import android.hardware.display.DisplayManager; import android.hardware.display.DisplayManagerInternal; @@ -125,6 +126,7 @@ public class BrightnessTracker { private static final int MSG_BRIGHTNESS_CHANGED = 1; private static final int MSG_STOP_SENSOR_LISTENER = 2; private static final int MSG_START_SENSOR_LISTENER = 3; + private static final int MSG_BRIGHTNESS_CONFIG_CHANGED = 4; private static final SimpleDateFormat FORMAT = new SimpleDateFormat("MM-dd HH:mm:ss.SSS"); @@ -158,6 +160,7 @@ public class BrightnessTracker { private boolean mColorSamplingEnabled; private int mNoFramesToSample; private float mFrameRate; + private BrightnessConfiguration mBrightnessConfiguration; // End of block of members that should only be accessed on the mBgHandler thread. private @UserIdInt int mCurrentUserId = UserHandle.USER_NULL; @@ -202,6 +205,14 @@ public class BrightnessTracker { mBgHandler.obtainMessage(MSG_BACKGROUND_START, (Float) initialBrightness).sendToTarget(); } + /** + * Update tracker with new brightness configuration. + */ + public void setBrightnessConfiguration(BrightnessConfiguration brightnessConfiguration) { + mBgHandler.obtainMessage(MSG_BRIGHTNESS_CONFIG_CHANGED, + brightnessConfiguration).sendToTarget(); + } + private void backgroundStart(float initialBrightness) { readEvents(); readAmbientBrightnessStats(); @@ -759,7 +770,9 @@ public class BrightnessTracker { private void enableColorSampling() { if (!mInjector.isBrightnessModeAutomatic(mContentResolver) || !mInjector.isInteractive(mContext) - || mColorSamplingEnabled) { + || mColorSamplingEnabled + || mBrightnessConfiguration == null + || !mBrightnessConfiguration.shouldCollectColorSamples()) { return; } @@ -977,6 +990,18 @@ public class BrightnessTracker { stopSensorListener(); disableColorSampling(); break; + case MSG_BRIGHTNESS_CONFIG_CHANGED: + mBrightnessConfiguration = (BrightnessConfiguration) msg.obj; + boolean shouldCollectColorSamples = + mBrightnessConfiguration != null + && mBrightnessConfiguration.shouldCollectColorSamples(); + if (shouldCollectColorSamples && !mColorSamplingEnabled) { + enableColorSampling(); + } else if (!shouldCollectColorSamples && mColorSamplingEnabled) { + disableColorSampling(); + } + break; + } } } diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java index 5804fc8ba72f..e42545e111ed 100644 --- a/services/core/java/com/android/server/display/DisplayPowerController.java +++ b/services/core/java/com/android/server/display/DisplayPowerController.java @@ -931,6 +931,10 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call autoBrightnessAdjustmentChanged, mPowerRequest.policy); } + if (mBrightnessTracker != null) { + mBrightnessTracker.setBrightnessConfiguration(mBrightnessConfiguration); + } + // Apply auto-brightness. boolean slowChange = false; if (brightness < 0) { diff --git a/services/core/java/com/android/server/display/WifiDisplayController.java b/services/core/java/com/android/server/display/WifiDisplayController.java index d9d46b8d1f3b..283a78b4e8b4 100644 --- a/services/core/java/com/android/server/display/WifiDisplayController.java +++ b/services/core/java/com/android/server/display/WifiDisplayController.java @@ -16,8 +16,6 @@ package com.android.server.display; -import com.android.internal.util.DumpUtils; - import android.content.BroadcastReceiver; import android.content.ContentResolver; import android.content.Context; @@ -36,16 +34,18 @@ import android.net.wifi.p2p.WifiP2pDevice; import android.net.wifi.p2p.WifiP2pDeviceList; import android.net.wifi.p2p.WifiP2pGroup; import android.net.wifi.p2p.WifiP2pManager; -import android.net.wifi.p2p.WifiP2pWfdInfo; import android.net.wifi.p2p.WifiP2pManager.ActionListener; import android.net.wifi.p2p.WifiP2pManager.Channel; import android.net.wifi.p2p.WifiP2pManager.GroupInfoListener; import android.net.wifi.p2p.WifiP2pManager.PeerListListener; +import android.net.wifi.p2p.WifiP2pWfdInfo; import android.os.Handler; import android.provider.Settings; import android.util.Slog; import android.view.Surface; +import com.android.internal.util.DumpUtils; + import java.io.PrintWriter; import java.net.Inet4Address; import java.net.InetAddress; @@ -292,11 +292,11 @@ final class WifiDisplayController implements DumpUtils.Dump { WifiP2pWfdInfo wfdInfo = new WifiP2pWfdInfo(); wfdInfo.setWfdEnabled(true); - wfdInfo.setDeviceType(WifiP2pWfdInfo.WFD_SOURCE); + wfdInfo.setDeviceType(WifiP2pWfdInfo.DEVICE_TYPE_WFD_SOURCE); wfdInfo.setSessionAvailable(true); wfdInfo.setControlPort(DEFAULT_CONTROL_PORT); wfdInfo.setMaxThroughput(MAX_THROUGHPUT); - mWifiP2pManager.setWFDInfo(mWifiP2pChannel, wfdInfo, new ActionListener() { + mWifiP2pManager.setWfdInfo(mWifiP2pChannel, wfdInfo, new ActionListener() { @Override public void onSuccess() { if (DEBUG) { @@ -324,7 +324,7 @@ final class WifiDisplayController implements DumpUtils.Dump { if (mWfdEnabled || mWfdEnabling) { WifiP2pWfdInfo wfdInfo = new WifiP2pWfdInfo(); wfdInfo.setWfdEnabled(false); - mWifiP2pManager.setWFDInfo(mWifiP2pChannel, wfdInfo, new ActionListener() { + mWifiP2pManager.setWfdInfo(mWifiP2pChannel, wfdInfo, new ActionListener() { @Override public void onSuccess() { if (DEBUG) { @@ -508,7 +508,8 @@ final class WifiDisplayController implements DumpUtils.Dump { Slog.d(TAG, "updateDesiredDevice: new information " + describeWifiP2pDevice(device)); } - mDesiredDevice.update(device); + mDesiredDevice.updateSupplicantDetails(device); + mDesiredDevice.status = device.status; if (mAdvertisedDisplay != null && mAdvertisedDisplay.getDeviceAddress().equals(address)) { readvertiseDisplay(createWifiDisplay(mDesiredDevice)); @@ -694,7 +695,7 @@ final class WifiDisplayController implements DumpUtils.Dump { config.wps = wps; config.deviceAddress = mConnectingDevice.deviceAddress; // Helps with STA & P2P concurrency - config.groupOwnerIntent = WifiP2pConfig.MIN_GROUP_OWNER_INTENT; + config.groupOwnerIntent = WifiP2pConfig.GROUP_OWNER_INTENT_MIN; WifiDisplay display = createWifiDisplay(mConnectingDevice); advertiseDisplay(display, null, 0, 0, 0); @@ -824,6 +825,10 @@ final class WifiDisplayController implements DumpUtils.Dump { requestPeers(); } + private static boolean contains(WifiP2pGroup group, WifiP2pDevice device) { + return group.getOwner().equals(device) || group.getClientList().contains(device); + } + private void handleConnectionChanged(NetworkInfo networkInfo) { mNetworkInfo = networkInfo; if (mWfdEnabled && networkInfo.isConnected()) { @@ -835,7 +840,7 @@ final class WifiDisplayController implements DumpUtils.Dump { Slog.d(TAG, "Received group info: " + describeWifiP2pGroup(info)); } - if (mConnectingDevice != null && !info.contains(mConnectingDevice)) { + if (mConnectingDevice != null && !contains(info, mConnectingDevice)) { Slog.i(TAG, "Aborting connection to Wifi display because " + "the current P2P group does not contain the device " + "we expected to find: " + mConnectingDevice.deviceName @@ -844,7 +849,7 @@ final class WifiDisplayController implements DumpUtils.Dump { return; } - if (mDesiredDevice != null && !info.contains(mDesiredDevice)) { + if (mDesiredDevice != null && !contains(info, mDesiredDevice)) { disconnect(); return; } @@ -1038,14 +1043,15 @@ final class WifiDisplayController implements DumpUtils.Dump { } private static boolean isWifiDisplay(WifiP2pDevice device) { - return device.wfdInfo != null - && device.wfdInfo.isWfdEnabled() - && isPrimarySinkDeviceType(device.wfdInfo.getDeviceType()); + WifiP2pWfdInfo wfdInfo = device.getWfdInfo(); + return wfdInfo != null + && wfdInfo.isWfdEnabled() + && isPrimarySinkDeviceType(wfdInfo.getDeviceType()); } private static boolean isPrimarySinkDeviceType(int deviceType) { - return deviceType == WifiP2pWfdInfo.PRIMARY_SINK - || deviceType == WifiP2pWfdInfo.SOURCE_OR_PRIMARY_SINK; + return deviceType == WifiP2pWfdInfo.DEVICE_TYPE_PRIMARY_SINK + || deviceType == WifiP2pWfdInfo.DEVICE_TYPE_SOURCE_OR_PRIMARY_SINK; } private static String describeWifiP2pDevice(WifiP2pDevice device) { @@ -1058,7 +1064,7 @@ final class WifiDisplayController implements DumpUtils.Dump { private static WifiDisplay createWifiDisplay(WifiP2pDevice device) { return new WifiDisplay(device.deviceAddress, device.deviceName, null, - true, device.wfdInfo.isSessionAvailable(), false); + true, device.getWfdInfo().isSessionAvailable(), false); } private final BroadcastReceiver mWifiP2pReceiver = new BroadcastReceiver() { diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java index 8d2fc17b94d6..637bcae7007e 100644 --- a/services/core/java/com/android/server/location/GnssLocationProvider.java +++ b/services/core/java/com/android/server/location/GnssLocationProvider.java @@ -301,6 +301,7 @@ public class GnssLocationProvider extends AbstractLocationProvider implements // Timeout when holding wakelocks for downloading PSDS data. private static final long DOWNLOAD_PSDS_DATA_TIMEOUT_MS = 60 * 1000; + private static final long WAKELOCK_TIMEOUT_MILLIS = 30 * 1000; private final ExponentialBackOff mPsdsBackOff = new ExponentialBackOff(RETRY_INTERVAL, MAX_RETRY_INTERVAL); @@ -901,13 +902,8 @@ public class GnssLocationProvider extends AbstractLocationProvider implements if (mDownloadPsdsWakeLock.isHeld()) { // This wakelock may have time-out, if a timeout was specified. // Catch (and ignore) any timeout exceptions. - try { - mDownloadPsdsWakeLock.release(); - if (DEBUG) Log.d(TAG, "WakeLock released by handleDownloadPsdsData()"); - } catch (Exception e) { - Log.i(TAG, "Wakelock timeout & release race exception in " - + "handleDownloadPsdsData()", e); - } + mDownloadPsdsWakeLock.release(); + if (DEBUG) Log.d(TAG, "WakeLock released by handleDownloadPsdsData()"); } else { Log.e(TAG, "WakeLock expired before release in " + "handleDownloadPsdsData()"); @@ -2009,7 +2005,7 @@ public class GnssLocationProvider extends AbstractLocationProvider implements // hold a wake lock until this message is delivered // note that this assumes the message will not be removed from the queue before // it is handled (otherwise the wake lock would be leaked). - mWakeLock.acquire(); + mWakeLock.acquire(WAKELOCK_TIMEOUT_MILLIS); if (DEBUG) { Log.d(TAG, "WakeLock acquired by sendMessage(" + messageIdAsString(message) + ", " + arg + ", " + obj + ")"); diff --git a/services/core/java/com/android/server/location/GnssNetworkConnectivityHandler.java b/services/core/java/com/android/server/location/GnssNetworkConnectivityHandler.java index 2e72fbd95931..93227bd78a81 100644 --- a/services/core/java/com/android/server/location/GnssNetworkConnectivityHandler.java +++ b/services/core/java/com/android/server/location/GnssNetworkConnectivityHandler.java @@ -321,7 +321,11 @@ class GnssNetworkConnectivityHandler { private void handleUpdateNetworkState(Network network, boolean isConnected, NetworkCapabilities capabilities) { - boolean networkAvailable = isConnected && TelephonyManager.getDefault().getDataEnabled(); + boolean networkAvailable = false; + TelephonyManager telephonyManager = mContext.getSystemService(TelephonyManager.class); + if (telephonyManager != null) { + networkAvailable = isConnected && telephonyManager.getDataEnabled(); + } NetworkAttributes networkAttributes = updateTrackedNetworksState(isConnected, network, capabilities); String apn = networkAttributes.mApn; diff --git a/services/core/java/com/android/server/location/NtpTimeHelper.java b/services/core/java/com/android/server/location/NtpTimeHelper.java index 296b500eacee..67841aca1605 100644 --- a/services/core/java/com/android/server/location/NtpTimeHelper.java +++ b/services/core/java/com/android/server/location/NtpTimeHelper.java @@ -181,11 +181,7 @@ class NtpTimeHelper { mHandler.postDelayed(this::retrieveAndInjectNtpTime, delay); } } - try { - // release wake lock held by task - mWakeLock.release(); - } catch (Exception e) { - // This happens when the WakeLock is already released. - } + // release wake lock held by task + mWakeLock.release(); } } diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java index 41806cabef3f..08c94267e969 100644 --- a/services/core/java/com/android/server/net/NetworkStatsService.java +++ b/services/core/java/com/android/server/net/NetworkStatsService.java @@ -337,7 +337,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG); NetworkStatsService service = new NetworkStatsService(context, networkManager, alarmManager, - wakeLock, getDefaultClock(), TelephonyManager.getDefault(), + wakeLock, getDefaultClock(), context.getSystemService(TelephonyManager.class), new DefaultNetworkStatsSettings(context), new NetworkStatsFactory(), new NetworkStatsObservers(), getDefaultSystemDir(), getDefaultBaseDir()); service.registerLocalService(); diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 5b39fb687d0d..ec53157fd8e2 100755 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -7724,7 +7724,7 @@ public class NotificationManagerService extends SystemService { } private void listenForCallState() { - TelephonyManager.from(getContext()).listen(new PhoneStateListener() { + getContext().getSystemService(TelephonyManager.class).listen(new PhoneStateListener() { @Override public void onCallStateChanged(int state, String incomingNumber) { if (mCallState == state) return; diff --git a/services/core/java/com/android/server/pm/permission/PermissionsState.java b/services/core/java/com/android/server/pm/permission/PermissionsState.java index 505a0e22eac4..b68d5418d0eb 100644 --- a/services/core/java/com/android/server/pm/permission/PermissionsState.java +++ b/services/core/java/com/android/server/pm/permission/PermissionsState.java @@ -23,6 +23,7 @@ import android.util.ArraySet; import android.util.SparseArray; import android.util.SparseBooleanArray; +import com.android.internal.annotations.GuardedBy; import com.android.internal.util.ArrayUtils; import java.util.ArrayList; @@ -30,7 +31,6 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Set; -import com.android.internal.annotations.GuardedBy; /** * This class encapsulates the permissions for a package or a shared user. @@ -708,7 +708,11 @@ public final class PermissionsState { } private static final class PermissionData { + + private final Object mLock = new Object(); + private final BasePermission mPerm; + @GuardedBy("mLock") private SparseArray<PermissionState> mUserStates = new SparseArray<>(); public PermissionData(BasePermission perm) { @@ -717,11 +721,14 @@ public final class PermissionsState { public PermissionData(PermissionData other) { this(other.mPerm); - final int otherStateCount = other.mUserStates.size(); - for (int i = 0; i < otherStateCount; i++) { - final int otherUserId = other.mUserStates.keyAt(i); - PermissionState otherState = other.mUserStates.valueAt(i); - mUserStates.put(otherUserId, new PermissionState(otherState)); + + synchronized (mLock) { + final int otherStateCount = other.mUserStates.size(); + for (int i = 0; i < otherStateCount; i++) { + final int otherUserId = other.mUserStates.keyAt(i); + PermissionState otherState = other.mUserStates.valueAt(i); + mUserStates.put(otherUserId, new PermissionState(otherState)); + } } } @@ -730,71 +737,83 @@ public final class PermissionsState { } public boolean isGranted(int userId) { - if (isInstallPermission()) { - userId = UserHandle.USER_ALL; - } + synchronized (mLock) { + if (isInstallPermission()) { + userId = UserHandle.USER_ALL; + } - PermissionState userState = mUserStates.get(userId); - if (userState == null) { - return false; - } + PermissionState userState = mUserStates.get(userId); + if (userState == null) { + return false; + } - return userState.mGranted; + return userState.mGranted; + } } public boolean grant(int userId) { - if (!isCompatibleUserId(userId)) { - return false; - } + synchronized (mLock) { + if (!isCompatibleUserId(userId)) { + return false; + } - if (isGranted(userId)) { - return false; - } + if (isGranted(userId)) { + return false; + } - PermissionState userState = mUserStates.get(userId); - if (userState == null) { - userState = new PermissionState(mPerm.getName()); - mUserStates.put(userId, userState); - } + PermissionState userState = mUserStates.get(userId); + if (userState == null) { + userState = new PermissionState(mPerm.getName()); + mUserStates.put(userId, userState); + } - userState.mGranted = true; + userState.mGranted = true; - return true; + return true; + } } public boolean revoke(int userId) { - if (!isCompatibleUserId(userId)) { - return false; - } + synchronized (mLock) { + if (!isCompatibleUserId(userId)) { + return false; + } - if (!isGranted(userId)) { - return false; - } + if (!isGranted(userId)) { + return false; + } - PermissionState userState = mUserStates.get(userId); - userState.mGranted = false; + PermissionState userState = mUserStates.get(userId); + userState.mGranted = false; - if (userState.isDefault()) { - mUserStates.remove(userId); - } + if (userState.isDefault()) { + mUserStates.remove(userId); + } - return true; + return true; + } } public PermissionState getPermissionState(int userId) { - return mUserStates.get(userId); + synchronized (mLock) { + return mUserStates.get(userId); + } } public int getFlags(int userId) { - PermissionState userState = mUserStates.get(userId); - if (userState != null) { - return userState.mFlags; + synchronized (mLock) { + PermissionState userState = mUserStates.get(userId); + if (userState != null) { + return userState.mFlags; + } + return 0; } - return 0; } public boolean isDefault() { - return mUserStates.size() <= 0; + synchronized (mLock) { + return mUserStates.size() <= 0; + } } public static boolean isInstallPermissionKey(int userId) { @@ -802,32 +821,34 @@ public final class PermissionsState { } public boolean updateFlags(int userId, int flagMask, int flagValues) { - if (isInstallPermission()) { - userId = UserHandle.USER_ALL; - } + synchronized (mLock) { + if (isInstallPermission()) { + userId = UserHandle.USER_ALL; + } - if (!isCompatibleUserId(userId)) { - return false; - } + if (!isCompatibleUserId(userId)) { + return false; + } - final int newFlags = flagValues & flagMask; + final int newFlags = flagValues & flagMask; - PermissionState userState = mUserStates.get(userId); - if (userState != null) { - final int oldFlags = userState.mFlags; - userState.mFlags = (userState.mFlags & ~flagMask) | newFlags; - if (userState.isDefault()) { - mUserStates.remove(userId); + PermissionState userState = mUserStates.get(userId); + if (userState != null) { + final int oldFlags = userState.mFlags; + userState.mFlags = (userState.mFlags & ~flagMask) | newFlags; + if (userState.isDefault()) { + mUserStates.remove(userId); + } + return userState.mFlags != oldFlags; + } else if (newFlags != 0) { + userState = new PermissionState(mPerm.getName()); + userState.mFlags = newFlags; + mUserStates.put(userId, userState); + return true; } - return userState.mFlags != oldFlags; - } else if (newFlags != 0) { - userState = new PermissionState(mPerm.getName()); - userState.mFlags = newFlags; - mUserStates.put(userId, userState); - return true; - } - return false; + return false; + } } private boolean isCompatibleUserId(int userId) { diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java index dd561e10874f..d66aa18950d0 100644 --- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java +++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java @@ -2170,14 +2170,21 @@ public class WallpaperManagerService extends IWallpaperManager.Stub } } + @Deprecated @Override public ParcelFileDescriptor getWallpaper(String callingPkg, IWallpaperManagerCallback cb, final int which, Bundle outParams, int wallpaperUserId) { + return getWallpaperWithFeature(callingPkg, null, cb, which, outParams, wallpaperUserId); + } + + @Override + public ParcelFileDescriptor getWallpaperWithFeature(String callingPkg, String callingFeatureId, + IWallpaperManagerCallback cb, final int which, Bundle outParams, int wallpaperUserId) { final int hasPrivilege = mContext.checkCallingOrSelfPermission( android.Manifest.permission.READ_WALLPAPER_INTERNAL); if (hasPrivilege != PackageManager.PERMISSION_GRANTED) { mContext.getSystemService(StorageManager.class).checkPermissionReadImages(true, - Binder.getCallingPid(), Binder.getCallingUid(), callingPkg); + Binder.getCallingPid(), Binder.getCallingUid(), callingPkg, callingFeatureId); } wallpaperUserId = ActivityManager.handleIncomingUser(Binder.getCallingPid(), diff --git a/services/core/java/com/android/server/wm/TaskPositioner.java b/services/core/java/com/android/server/wm/TaskPositioner.java index f7b802da8860..a867a5d41e24 100644 --- a/services/core/java/com/android/server/wm/TaskPositioner.java +++ b/services/core/java/com/android/server/wm/TaskPositioner.java @@ -133,14 +133,15 @@ class TaskPositioner implements IBinder.DeathRecipient { @Override public void onInputEvent(InputEvent event) { - if (!(event instanceof MotionEvent) - || (event.getSource() & InputDevice.SOURCE_CLASS_POINTER) == 0) { - return; - } - final MotionEvent motionEvent = (MotionEvent) event; boolean handled = false; - try { + // All returns need to be in the try block to make sure the finishInputEvent is + // called correctly. + if (!(event instanceof MotionEvent) + || (event.getSource() & InputDevice.SOURCE_CLASS_POINTER) == 0) { + return; + } + final MotionEvent motionEvent = (MotionEvent) event; if (mDragEnded) { // The drag has ended but the clean-up message has not been processed by // window manager. Drop events that occur after this until window manager diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index f1dbd7b8c28d..99f484e2d90f 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -1945,7 +1945,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } TelephonyManager getTelephonyManager() { - return TelephonyManager.from(mContext); + return mContext.getSystemService(TelephonyManager.class); } TrustManager getTrustManager() { diff --git a/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java index 9c9730501a78..45de451e5bea 100644 --- a/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java @@ -33,6 +33,8 @@ import static com.android.server.DeviceIdleController.LIGHT_STATE_OVERRIDE; import static com.android.server.DeviceIdleController.LIGHT_STATE_PRE_IDLE; import static com.android.server.DeviceIdleController.LIGHT_STATE_WAITING_FOR_NETWORK; import static com.android.server.DeviceIdleController.MSG_REPORT_STATIONARY_STATUS; +import static com.android.server.DeviceIdleController.MSG_RESET_PRE_IDLE_TIMEOUT_FACTOR; +import static com.android.server.DeviceIdleController.MSG_UPDATE_PRE_IDLE_TIMEOUT_FACTOR; import static com.android.server.DeviceIdleController.STATE_ACTIVE; import static com.android.server.DeviceIdleController.STATE_IDLE; import static com.android.server.DeviceIdleController.STATE_IDLE_MAINTENANCE; @@ -180,7 +182,9 @@ public class DeviceIdleControllerTest { mHandler = controller.new MyHandler(getContext().getMainLooper()); spyOn(mHandler); doNothing().when(mHandler).handleMessage(argThat((message) -> - message.what != MSG_REPORT_STATIONARY_STATUS)); + message.what != MSG_REPORT_STATIONARY_STATUS + && message.what != MSG_UPDATE_PRE_IDLE_TIMEOUT_FACTOR + && message.what != MSG_RESET_PRE_IDLE_TIMEOUT_FACTOR)); doAnswer(new Answer<Boolean>() { @Override public Boolean answer(InvocationOnMock invocation) throws Throwable { @@ -189,7 +193,9 @@ public class DeviceIdleControllerTest { return true; } }).when(mHandler).sendMessageDelayed( - argThat((message) -> message.what == MSG_REPORT_STATIONARY_STATUS), + argThat((message) -> message.what == MSG_REPORT_STATIONARY_STATUS + || message.what == MSG_UPDATE_PRE_IDLE_TIMEOUT_FACTOR + || message.what == MSG_RESET_PRE_IDLE_TIMEOUT_FACTOR), anyLong()); } @@ -1734,13 +1740,11 @@ public class DeviceIdleControllerTest { } //TODO(b/123045185): Mocked Handler of DeviceIdleController to make message loop //workable in this test class - mDeviceIdleController.updatePreIdleFactor(); float expectedfactor = mDeviceIdleController.getPreIdleTimeoutByMode(mode); float curfactor = mDeviceIdleController.getPreIdleTimeoutFactor(); assertEquals("Pre idle time factor of mode [" + mode + "].", expectedfactor, curfactor, delta); mDeviceIdleController.resetPreIdleTimeoutMode(); - mDeviceIdleController.updatePreIdleFactor(); checkNextAlarmTimeWithNewPreIdleFactor(expectedfactor, STATE_INACTIVE); checkNextAlarmTimeWithNewPreIdleFactor(expectedfactor, STATE_IDLE_PENDING); @@ -2088,14 +2092,11 @@ public class DeviceIdleControllerTest { mDeviceIdleController.SET_IDLE_FACTOR_RESULT_OK, ret); } if (ret == mDeviceIdleController.SET_IDLE_FACTOR_RESULT_OK) { - mDeviceIdleController.updatePreIdleFactor(); long newAlarm = mDeviceIdleController.getNextAlarmTime(); long newDelay = (long) ((alarm - now) * factor); assertTrue("setPreIdleTimeoutFactor: " + factor, Math.abs(newDelay - (newAlarm - now)) < errorTolerance); mDeviceIdleController.resetPreIdleTimeoutMode(); - mDeviceIdleController.updatePreIdleFactor(); - mDeviceIdleController.maybeDoImmediateMaintenance(); newAlarm = mDeviceIdleController.getNextAlarmTime(); assertTrue("resetPreIdleTimeoutMode from: " + factor, Math.abs(newAlarm - alarm) < errorTolerance); @@ -2106,19 +2107,14 @@ public class DeviceIdleControllerTest { assertTrue("setPreIdleTimeoutFactor: " + factor + " before step to idle", Math.abs(newDelay - (newAlarm - now)) < errorTolerance); mDeviceIdleController.resetPreIdleTimeoutMode(); - mDeviceIdleController.updatePreIdleFactor(); - mDeviceIdleController.maybeDoImmediateMaintenance(); } } else { mDeviceIdleController.setPreIdleTimeoutFactor(factor); - mDeviceIdleController.updatePreIdleFactor(); long newAlarm = mDeviceIdleController.getNextAlarmTime(); assertTrue("setPreIdleTimeoutFactor: " + factor + " shounld not change next alarm" , (newAlarm == alarm)); mDeviceIdleController.resetPreIdleTimeoutMode(); - mDeviceIdleController.updatePreIdleFactor(); - mDeviceIdleController.maybeDoImmediateMaintenance(); } } @@ -2138,18 +2134,15 @@ public class DeviceIdleControllerTest { long alarm = mDeviceIdleController.getNextAlarmTime(); mDeviceIdleController.setIdleStartTimeForTest( now - (long) (mConstants.IDLE_TIMEOUT * 0.6)); - mDeviceIdleController.maybeDoImmediateMaintenance(); long newAlarm = mDeviceIdleController.getNextAlarmTime(); assertTrue("maintenance not reschedule IDLE_TIMEOUT * 0.6", newAlarm == alarm); mDeviceIdleController.setIdleStartTimeForTest( now - (long) (mConstants.IDLE_TIMEOUT * 1.2)); - mDeviceIdleController.maybeDoImmediateMaintenance(); newAlarm = mDeviceIdleController.getNextAlarmTime(); assertTrue("maintenance not reschedule IDLE_TIMEOUT * 1.2", (newAlarm - now) < minuteInMillis); mDeviceIdleController.resetPreIdleTimeoutMode(); - mDeviceIdleController.updatePreIdleFactor(); } } } diff --git a/services/tests/servicestests/src/com/android/server/display/BrightnessTrackerTest.java b/services/tests/servicestests/src/com/android/server/display/BrightnessTrackerTest.java index 7081d2e3b370..1d04c8397ffa 100644 --- a/services/tests/servicestests/src/com/android/server/display/BrightnessTrackerTest.java +++ b/services/tests/servicestests/src/com/android/server/display/BrightnessTrackerTest.java @@ -37,6 +37,7 @@ import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.display.AmbientBrightnessDayStats; import android.hardware.display.BrightnessChangeEvent; +import android.hardware.display.BrightnessConfiguration; import android.hardware.display.DisplayManager; import android.hardware.display.DisplayedContentSample; import android.hardware.display.DisplayedContentSamplingAttributes; @@ -78,6 +79,7 @@ import java.util.concurrent.TimeUnit; @RunWith(AndroidJUnit4.class) public class BrightnessTrackerTest { private static final float DEFAULT_INITIAL_BRIGHTNESS = 2.5f; + private static final boolean DEFAULT_COLOR_SAMPLING_ENABLED = true; private static final float FLOAT_DELTA = 0.01f; private BrightnessTracker mTracker; @@ -151,6 +153,40 @@ public class BrightnessTrackerTest { } @Test + public void testModifyBrightnessConfiguration() { + mInjector.mInteractive = true; + // Start with tracker not listening for color samples. + startTracker(mTracker, DEFAULT_INITIAL_BRIGHTNESS, /* collectColorSamples= */ false); + assertFalse(mInjector.mColorSamplingEnabled); + + // Update brightness config to enabled color sampling. + mTracker.setBrightnessConfiguration(buildBrightnessConfiguration( + /* collectColorSamples= */ true)); + mInjector.waitForHandler(); + assertTrue(mInjector.mColorSamplingEnabled); + + // Update brightness config to disable color sampling. + mTracker.setBrightnessConfiguration(buildBrightnessConfiguration( + /* collectColorSamples= */ false)); + mInjector.waitForHandler(); + assertFalse(mInjector.mColorSamplingEnabled); + + // Pretend screen is off, update config to turn on color sampling. + mInjector.sendScreenChange(/*screen on */ false); + mTracker.setBrightnessConfiguration(buildBrightnessConfiguration( + /* collectColorSamples= */ true)); + mInjector.waitForHandler(); + assertFalse(mInjector.mColorSamplingEnabled); + + // Pretend screen is on. + mInjector.sendScreenChange(/*screen on */ true); + assertTrue(mInjector.mColorSamplingEnabled); + + mTracker.stop(); + assertFalse(mInjector.mColorSamplingEnabled); + } + + @Test public void testNoColorSampling_WrongPixelFormat() { mInjector.mDefaultSamplingAttributes = new DisplayedContentSamplingAttributes( @@ -278,7 +314,7 @@ public class BrightnessTrackerTest { mInjector.mSecureIntSettings.put(Settings.Secure.NIGHT_DISPLAY_ACTIVATED, 1); mInjector.mSecureIntSettings.put(Settings.Secure.NIGHT_DISPLAY_COLOR_TEMPERATURE, 3333); - startTracker(mTracker, initialBrightness); + startTracker(mTracker, initialBrightness, DEFAULT_COLOR_SAMPLING_ENABLED); mInjector.mBroadcastReceiver.onReceive(InstrumentationRegistry.getContext(), batteryChangeEvent(30, 60)); mInjector.mSensorListener.onSensorChanged(createSensorEvent(1000.0f)); @@ -311,7 +347,7 @@ public class BrightnessTrackerTest { @Test public void testIgnoreAutomaticBrightnessChange() { final int initialBrightness = 30; - startTracker(mTracker, initialBrightness); + startTracker(mTracker, initialBrightness, DEFAULT_COLOR_SAMPLING_ENABLED); mInjector.mSensorListener.onSensorChanged(createSensorEvent(1.0f)); mInjector.incrementTime(TimeUnit.SECONDS.toMillis(1)); @@ -750,11 +786,13 @@ public class BrightnessTrackerTest { } private void startTracker(BrightnessTracker tracker) { - startTracker(tracker, DEFAULT_INITIAL_BRIGHTNESS); + startTracker(tracker, DEFAULT_INITIAL_BRIGHTNESS, DEFAULT_COLOR_SAMPLING_ENABLED); } - private void startTracker(BrightnessTracker tracker, float initialBrightness) { + private void startTracker(BrightnessTracker tracker, float initialBrightness, + boolean collectColorSamples) { tracker.start(initialBrightness); + tracker.setBrightnessConfiguration(buildBrightnessConfiguration(collectColorSamples)); mInjector.waitForHandler(); } @@ -772,6 +810,14 @@ public class BrightnessTrackerTest { mInjector.waitForHandler(); } + private BrightnessConfiguration buildBrightnessConfiguration(boolean collectColorSamples) { + BrightnessConfiguration.Builder builder = new BrightnessConfiguration.Builder( + /* lux = */ new float[] {0f, 10f, 100f}, + /* nits = */ new float[] {1f, 90f, 100f}); + builder.setShouldCollectColorSamples(collectColorSamples); + return builder.build(); + } + private static final class Idle implements MessageQueue.IdleHandler { private boolean mIdle; 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 e0ffb0d03f89..4f2d5d23f83d 100644 --- a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java @@ -61,6 +61,7 @@ import android.graphics.Rect; import android.os.Bundle; import android.os.RemoteException; import android.os.SystemClock; +import android.os.UserManager; import android.platform.test.annotations.Presubmit; import android.util.ArraySet; import android.util.SparseBooleanArray; @@ -92,7 +93,9 @@ public class RecentTasksTest extends ActivityTestsBase { 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 QUIET_USER_INFO = new UserInfo(); + 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 ActivityDisplay mDisplay; @@ -125,7 +128,6 @@ public class RecentTasksTest extends ActivityTestsBase { WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); mCallbacksRecorder = new CallbacksRecorder(); mRecentTasks.registerCallback(mCallbacksRecorder); - QUIET_USER_INFO.flags = UserInfo.FLAG_MANAGED_PROFILE | UserInfo.FLAG_QUIET_MODE; mTasks = new ArrayList<>(); mTasks.add(createTaskBuilder(".Task1").build()); @@ -1220,7 +1222,7 @@ public class RecentTasksTest extends ActivityTestsBase { case TEST_USER_1_ID: return DEFAULT_USER_INFO; case TEST_QUIET_USER_ID: - return QUIET_USER_INFO; + return QUIET_PROFILE_USER_INFO; } return null; } diff --git a/startop/apps/test/Android.bp b/startop/apps/test/Android.bp index c7c70db60a72..f42c755e3efd 100644 --- a/startop/apps/test/Android.bp +++ b/startop/apps/test/Android.bp @@ -17,6 +17,7 @@ android_app { name: "startop_test_app", srcs: [ + "src/ApplicationBenchmarks.java", "src/ComplexLayoutInflationActivity.java", "src/CPUIntensiveBenchmarkActivity.java", "src/CPUIntensiveBenchmarks.java", diff --git a/startop/apps/test/src/ApplicationBenchmarks.java b/startop/apps/test/src/ApplicationBenchmarks.java new file mode 100644 index 000000000000..7d71916e6d8d --- /dev/null +++ b/startop/apps/test/src/ApplicationBenchmarks.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.startop.test; + +import android.app.Activity; +import android.view.LayoutInflater; + +final class ApplicationBenchmarks { + + public static final void initializeBenchmarks(Activity parent, BenchmarkRunner benchmarks) { + LayoutInflater inflater = LayoutInflater.from(parent); + + benchmarks.addBenchmark("Complex Layout", () -> { + inflater.inflate(R.layout.activity_main, null); + }); + + benchmarks.addBenchmark("TextView List Layout", () -> { + inflater.inflate(R.layout.textview_list, null); + }); + + benchmarks.addBenchmark("FrameLayout List Layout", () -> { + inflater.inflate(R.layout.framelayout_list, null); + }); + } +} diff --git a/startop/apps/test/src/InteractiveMicrobenchmarkActivity.java b/startop/apps/test/src/InteractiveMicrobenchmarkActivity.java index 8ed7f6ae2109..c3839c17e4d8 100644 --- a/startop/apps/test/src/InteractiveMicrobenchmarkActivity.java +++ b/startop/apps/test/src/InteractiveMicrobenchmarkActivity.java @@ -36,6 +36,8 @@ public class InteractiveMicrobenchmarkActivity extends Activity implements Bench addBenchmark("Empty", () -> { }); addHeader("Application Benchmarks"); + ApplicationBenchmarks.initializeBenchmarks(this, this); + addHeader("CPU Intensive Benchmarks"); CPUIntensiveBenchmarks.initializeBenchmarks(this, this); addHeader("Init Check Overhead Benchmarks"); InitCheckOverheadBenchmarks.initializeBenchmarks(this, this); diff --git a/telephony/java/android/telephony/SmsManager.java b/telephony/java/android/telephony/SmsManager.java index 3f95a810fe10..89c4e905f503 100644 --- a/telephony/java/android/telephony/SmsManager.java +++ b/telephony/java/android/telephony/SmsManager.java @@ -514,7 +514,6 @@ public final class SmsManager { throw new IllegalArgumentException("Invalid message body"); } - final Context context = ActivityThread.currentApplication().getApplicationContext(); // We will only show the SMS disambiguation dialog in the case that the message is being // persisted. This is for two reasons: // 1) Messages that are not persisted are sent by carrier/OEM apps for a specific @@ -623,7 +622,6 @@ public final class SmsManager { final int finalPriority = priority; final int finalValidity = validityPeriod; - final Context context = ActivityThread.currentApplication().getApplicationContext(); // We will only show the SMS disambiguation dialog in the case that the message is being // persisted. This is for two reasons: // 1) Messages that are not persisted are sent by carrier/OEM apps for a specific @@ -927,7 +925,6 @@ public final class SmsManager { } if (parts.size() > 1) { - final Context context = ActivityThread.currentApplication().getApplicationContext(); // We will only show the SMS disambiguation dialog in the case that the message is being // persisted. This is for two reasons: // 1) Messages that are not persisted are sent by carrier/OEM apps for a specific @@ -1168,7 +1165,6 @@ public final class SmsManager { if (parts.size() > 1) { final int finalPriority = priority; final int finalValidity = validityPeriod; - final Context context = ActivityThread.currentApplication().getApplicationContext(); if (persistMessage) { resolveSubscriptionForOperation(new SubscriptionResolverResult() { @Override @@ -1325,7 +1321,6 @@ public final class SmsManager { throw new IllegalArgumentException("Invalid message data"); } - final Context context = ActivityThread.currentApplication().getApplicationContext(); resolveSubscriptionForOperation(new SubscriptionResolverResult() { @Override public void onSuccess(int subId) { diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java index e6fe5f671b5a..3d63e4a37604 100644 --- a/telephony/java/android/telephony/SubscriptionManager.java +++ b/telephony/java/android/telephony/SubscriptionManager.java @@ -1297,7 +1297,7 @@ public class SubscriptionManager { * * @return Sorted list of the currently available {@link SubscriptionInfo} * records on the device. - * This is similar to {@link getActiveSubscriptionInfoList} except that it will return + * This is similar to {@link #getActiveSubscriptionInfoList} except that it will return * both active and hidden SubscriptionInfos. * */ diff --git a/test-mock/src/android/test/mock/MockContentProvider.java b/test-mock/src/android/test/mock/MockContentProvider.java index 9d3e12050193..85e5916a63df 100644 --- a/test-mock/src/android/test/mock/MockContentProvider.java +++ b/test-mock/src/android/test/mock/MockContentProvider.java @@ -71,8 +71,8 @@ public class MockContentProvider extends ContentProvider { @Override public int delete(String callingPackage, @Nullable String featureId, Uri url, - String selection, String[] selectionArgs) throws RemoteException { - return MockContentProvider.this.delete(url, selection, selectionArgs); + Bundle extras) throws RemoteException { + return MockContentProvider.this.delete(url, extras); } @Override @@ -82,8 +82,8 @@ public class MockContentProvider extends ContentProvider { @Override public Uri insert(String callingPackage, @Nullable String featureId, Uri url, - ContentValues initialValues) throws RemoteException { - return MockContentProvider.this.insert(url, initialValues); + ContentValues initialValues, Bundle extras) throws RemoteException { + return MockContentProvider.this.insert(url, initialValues, extras); } @Override @@ -109,9 +109,8 @@ public class MockContentProvider extends ContentProvider { @Override public int update(String callingPackage, @Nullable String featureId, Uri url, - ContentValues values, String selection, String[] selectionArgs) - throws RemoteException { - return MockContentProvider.this.update(url, values, selection, selectionArgs); + ContentValues values, Bundle extras) throws RemoteException { + return MockContentProvider.this.update(url, values, extras); } @Override diff --git a/test-mock/src/android/test/mock/MockIContentProvider.java b/test-mock/src/android/test/mock/MockIContentProvider.java index e512b52643f3..464abfb1a514 100644 --- a/test-mock/src/android/test/mock/MockIContentProvider.java +++ b/test-mock/src/android/test/mock/MockIContentProvider.java @@ -51,7 +51,7 @@ public class MockIContentProvider implements IContentProvider { @Override @SuppressWarnings("unused") public int delete(String callingPackage, @Nullable String featureId, Uri url, - String selection, String[] selectionArgs) throws RemoteException { + Bundle extras) throws RemoteException { throw new UnsupportedOperationException("unimplemented mock method"); } @@ -63,7 +63,7 @@ public class MockIContentProvider implements IContentProvider { @Override @SuppressWarnings("unused") public Uri insert(String callingPackage, @Nullable String featureId, Uri url, - ContentValues initialValues) throws RemoteException { + ContentValues initialValues, Bundle extras) throws RemoteException { throw new UnsupportedOperationException("unimplemented mock method"); } @@ -99,7 +99,7 @@ public class MockIContentProvider implements IContentProvider { @Override public int update(String callingPackage, @Nullable String featureId, Uri url, - ContentValues values, String selection, String[] selectionArgs) throws RemoteException { + ContentValues values, Bundle extras) throws RemoteException { throw new UnsupportedOperationException("unimplemented mock method"); } diff --git a/tests/net/java/com/android/server/connectivity/TetheringTest.java b/tests/net/java/com/android/server/connectivity/TetheringTest.java index 5f62c08f55f3..9e5717b4bd64 100644 --- a/tests/net/java/com/android/server/connectivity/TetheringTest.java +++ b/tests/net/java/com/android/server/connectivity/TetheringTest.java @@ -208,6 +208,12 @@ public class TetheringTest { if (Context.TELEPHONY_SERVICE.equals(name)) return mTelephonyManager; return super.getSystemService(name); } + + @Override + public String getSystemServiceName(Class<?> serviceClass) { + if (TelephonyManager.class.equals(serviceClass)) return Context.TELEPHONY_SERVICE; + return super.getSystemServiceName(serviceClass); + } } public class MockIpServerDependencies extends IpServer.Dependencies { diff --git a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java index 1d29a824d10d..4d42a612030d 100644 --- a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java +++ b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java @@ -192,8 +192,8 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { mService = new NetworkStatsService( mServiceContext, mNetManager, mAlarmManager, wakeLock, mClock, - TelephonyManager.getDefault(), mSettings, mStatsFactory, - new NetworkStatsObservers(), mStatsDir, getBaseDir(mStatsDir)); + mServiceContext.getSystemService(TelephonyManager.class), mSettings, + mStatsFactory, new NetworkStatsObservers(), mStatsDir, getBaseDir(mStatsDir)); mHandlerThread = new HandlerThread("HandlerThread"); mHandlerThread.start(); Handler.Callback callback = new NetworkStatsService.HandlerCallback(mService); diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java b/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java index c3cfb0266328..767055fe6e29 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java @@ -66,12 +66,6 @@ public class WifiP2pConfig implements Parcelable { public int groupOwnerBand = GROUP_OWNER_BAND_AUTO; /** @hide */ - public static final int MAX_GROUP_OWNER_INTENT = 15; - /** @hide */ - @UnsupportedAppUsage - public static final int MIN_GROUP_OWNER_INTENT = 0; - - /** @hide */ @IntDef(flag = false, prefix = { "GROUP_OWNER_BAND_" }, value = { GROUP_OWNER_BAND_AUTO, GROUP_OWNER_BAND_2GHZ, @@ -94,13 +88,35 @@ public class WifiP2pConfig implements Parcelable { public static final int GROUP_OWNER_BAND_5GHZ = 2; /** - * This is an integer value between 0 and 15 where 0 indicates the least - * inclination to be a group owner and 15 indicates the highest inclination - * to be a group owner. + * The least inclination to be a group owner, to be filled in the field + * {@link #groupOwnerIntent}. + */ + public static final int GROUP_OWNER_INTENT_MIN = 0; + + /** + * The most inclination to be a group owner, to be filled in the field + * {@link #groupOwnerIntent}. + */ + public static final int GROUP_OWNER_INTENT_MAX = 15; + + /** + * The system can choose an appropriate owner intent value, to be filled in the field + * {@link #groupOwnerIntent}. + */ + public static final int GROUP_OWNER_INTENT_AUTO = -1; + + /** + * This is an integer value between {@link #GROUP_OWNER_INTENT_MIN} and + * {@link #GROUP_OWNER_INTENT_MAX} where + * {@link #GROUP_OWNER_INTENT_MIN} indicates the least inclination to be a group owner and + * {@link #GROUP_OWNER_INTENT_MAX} indicates the highest inclination to be a group owner. + * + * A value of {@link #GROUP_OWNER_INTENT_AUTO} indicates the system can choose an appropriate + * value. * - * A value of -1 indicates the system can choose an appropriate value. + * By default this field is set to {@link #GROUP_OWNER_INTENT_AUTO}. */ - public int groupOwnerIntent = -1; + public int groupOwnerIntent = GROUP_OWNER_INTENT_AUTO; /** @hide */ @UnsupportedAppUsage diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java b/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java index c5318a9e275a..13b25209990e 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java @@ -16,6 +16,8 @@ package android.net.wifi.p2p; +import android.annotation.NonNull; +import android.annotation.Nullable; import android.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; @@ -237,6 +239,12 @@ public class WifiP2pDevice implements Parcelable { } } + /** The Wifi Display information for this device, or null if unavailable. */ + @Nullable + public WifiP2pWfdInfo getWfdInfo() { + return wfdInfo; + } + /** Returns true if WPS push button configuration is supported */ public boolean wpsPbcSupported() { return (wpsConfigMethodsSupported & WPS_CONFIG_PUSHBUTTON) != 0; @@ -278,14 +286,15 @@ public class WifiP2pDevice implements Parcelable { } /** - * Update device details. This will be throw an exception if the device address - * does not match. + * Update device details. This will throw an exception if the device address does not match. + * * @param device to be updated - * @throws IllegalArgumentException if the device is null or device address does not match + * @throws IllegalArgumentException if the device is null or the device address does not match + * * @hide */ @UnsupportedAppUsage - public void update(WifiP2pDevice device) { + public void update(@NonNull WifiP2pDevice device) { updateSupplicantDetails(device); status = device.status; } diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java b/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java index 4866bd4b2ce9..f9d1266cf804 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java @@ -16,6 +16,7 @@ package android.net.wifi.p2p; +import android.annotation.Nullable; import android.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; @@ -36,15 +37,21 @@ import java.util.regex.Pattern; */ public class WifiP2pGroup implements Parcelable { - /** The temporary network id. - * {@hide} */ + /** + * The temporary network id. + * + * @hide + */ @UnsupportedAppUsage public static final int TEMPORARY_NET_ID = -1; - /** The persistent network id. + /** + * The persistent network id. * If a matching persistent profile is found, use it. * Otherwise, create a new persistent profile. - * {@hide} */ + * + * @hide + */ public static final int PERSISTENT_NET_ID = -2; /** The network name */ @@ -64,7 +71,7 @@ public class WifiP2pGroup implements Parcelable { private String mInterface; - /** The network id in the wpa_supplicant */ + /** The network ID in wpa_supplicant */ private int mNetId; /** The frequency (in MHz) used by this group */ @@ -225,10 +232,13 @@ public class WifiP2pGroup implements Parcelable { return mClients.size() == 0; } - /** @hide Returns {@code true} if the device is part of the group */ - public boolean contains(WifiP2pDevice device) { - if (mOwner.equals(device) || mClients.contains(device)) return true; - return false; + /** + * Returns {@code true} if the device is part of the group, {@code false} otherwise. + * + * @hide + */ + public boolean contains(@Nullable WifiP2pDevice device) { + return mOwner.equals(device) || mClients.contains(device); } /** Get the list of clients currently part of the p2p group */ @@ -261,8 +271,7 @@ public class WifiP2pGroup implements Parcelable { return mInterface; } - /** @hide */ - @UnsupportedAppUsage + /** The network ID of the P2P group in wpa_supplicant. */ public int getNetworkId() { return mNetId; } diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pGroupList.java b/wifi/java/android/net/wifi/p2p/WifiP2pGroupList.java index 62524d9c2bd6..10fd09aa638f 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pGroupList.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pGroupList.java @@ -15,14 +15,16 @@ */ package android.net.wifi.p2p; -import java.util.Collection; -import java.util.Map; - +import android.annotation.NonNull; +import android.annotation.SystemApi; import android.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; import android.util.LruCache; +import java.util.Collection; +import java.util.Map; + /** * A class representing a Wi-Fi P2p group list @@ -30,7 +32,8 @@ import android.util.LruCache; * {@see WifiP2pManager} * @hide */ -public class WifiP2pGroupList implements Parcelable { +@SystemApi +public final class WifiP2pGroupList implements Parcelable { private static final int CREDENTIAL_MAX_NUM = 32; @@ -40,6 +43,7 @@ public class WifiP2pGroupList implements Parcelable { private boolean isClearCalled = false; + /** @hide */ public interface GroupDeleteListener { public void onDeleteGroup(int netId); } @@ -71,11 +75,9 @@ public class WifiP2pGroupList implements Parcelable { } /** - * Return the list of p2p group. - * - * @return the list of p2p group. + * Get the list of P2P groups. */ - @UnsupportedAppUsage + @NonNull public Collection<WifiP2pGroup> getGroupList() { return mGroups.snapshot().values(); } @@ -206,6 +208,7 @@ public class WifiP2pGroupList implements Parcelable { return false; } + @Override public String toString() { StringBuffer sbuf = new StringBuffer(); @@ -217,12 +220,14 @@ public class WifiP2pGroupList implements Parcelable { } /** Implement the Parcelable interface */ + @Override public int describeContents() { return 0; } /** Implement the Parcelable interface */ - public void writeToParcel(Parcel dest, int flags) { + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { final Collection<WifiP2pGroup> groups = mGroups.snapshot().values(); dest.writeInt(groups.size()); for(WifiP2pGroup group : groups) { @@ -231,7 +236,7 @@ public class WifiP2pGroupList implements Parcelable { } /** Implement the Parcelable interface */ - public static final @android.annotation.NonNull Creator<WifiP2pGroupList> CREATOR = + public static final @NonNull Creator<WifiP2pGroupList> CREATOR = new Creator<WifiP2pGroupList>() { public WifiP2pGroupList createFromParcel(Parcel in) { WifiP2pGroupList grpList = new WifiP2pGroupList(); diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java index 3178519a6739..1c2067980a79 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java @@ -22,6 +22,7 @@ import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; +import android.annotation.SystemApi; import android.annotation.SystemService; import android.annotation.UnsupportedAppUsage; import android.content.Context; @@ -327,8 +328,9 @@ public class WifiP2pManager { * Broadcast intent action indicating that remembered persistent groups have changed. * @hide */ - public static final String WIFI_P2P_PERSISTENT_GROUPS_CHANGED_ACTION = - "android.net.wifi.p2p.PERSISTENT_GROUPS_CHANGED"; + @SystemApi + public static final String ACTION_WIFI_P2P_PERSISTENT_GROUPS_CHANGED = + "android.net.wifi.p2p.action.WIFI_P2P_PERSISTENT_GROUPS_CHANGED"; /** * The lookup key for a handover message returned by the WifiP2pService. @@ -756,13 +758,18 @@ public class WifiP2pManager { } - /** Interface for callback invocation when stored group info list is available {@hide}*/ + /** + * Interface for callback invocation when stored group info list is available + * + * @hide + */ + @SystemApi public interface PersistentGroupInfoListener { /** * The requested stored p2p group info list is available * @param groups Wi-Fi p2p group info list */ - public void onPersistentGroupInfoAvailable(WifiP2pGroupList groups); + void onPersistentGroupInfoAvailable(@NonNull WifiP2pGroupList groups); } /** @@ -1202,7 +1209,7 @@ public class WifiP2pManager { c.mAsyncChannel.sendMessage(DISCOVER_PEERS, 0, c.putListener(listener)); } - /** + /** * Stop an ongoing peer discovery * * <p> The function call immediately returns after sending a stop request @@ -1347,20 +1354,36 @@ public class WifiP2pManager { * * @hide */ + @SystemApi @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) - public void listen(Channel c, boolean enable, ActionListener listener) { + public void listen(@NonNull Channel c, boolean enable, @Nullable ActionListener listener) { checkChannel(c); c.mAsyncChannel.sendMessage(enable ? START_LISTEN : STOP_LISTEN, 0, c.putListener(listener)); } - /** @hide */ - @UnsupportedAppUsage - public void setWifiP2pChannels(Channel c, int lc, int oc, ActionListener listener) { + /** + * Set P2P listening and operating channel. + * + * @param c is the channel created at {@link #initialize} + * @param listeningChannel the listening channel's Wifi channel number. e.g. 1, 6, 11. + * @param operatingChannel the operating channel's Wifi channel number. e.g. 1, 6, 11. + * @param listener for callbacks on success or failure. Can be null. + * + * @hide + */ + @SystemApi + @RequiresPermission(anyOf = { + android.Manifest.permission.NETWORK_SETTINGS, + android.Manifest.permission.NETWORK_STACK, + android.Manifest.permission.OVERRIDE_WIFI_CONFIG + }) + public void setWifiP2pChannels(@NonNull Channel c, int listeningChannel, int operatingChannel, + @Nullable ActionListener listener) { checkChannel(c); Bundle p2pChannels = new Bundle(); - p2pChannels.putInt("lc", lc); - p2pChannels.putInt("oc", oc); + p2pChannels.putInt("lc", listeningChannel); + p2pChannels.putInt("oc", operatingChannel); c.mAsyncChannel.sendMessage(SET_CHANNEL, 0, c.putListener(listener), p2pChannels); } @@ -1618,23 +1641,47 @@ public class WifiP2pManager { /** * Set p2p device name. - * @hide + * * @param c is the channel created at {@link #initialize} * @param listener for callback when group info is available. Can be null. + * + * @hide */ - @UnsupportedAppUsage - public void setDeviceName(Channel c, String devName, ActionListener listener) { + @SystemApi + @RequiresPermission(anyOf = { + android.Manifest.permission.NETWORK_SETTINGS, + android.Manifest.permission.NETWORK_STACK, + android.Manifest.permission.OVERRIDE_WIFI_CONFIG + }) + public void setDeviceName(@NonNull Channel c, @NonNull String devName, + @Nullable ActionListener listener) { checkChannel(c); WifiP2pDevice d = new WifiP2pDevice(); d.deviceName = devName; c.mAsyncChannel.sendMessage(SET_DEVICE_NAME, 0, c.putListener(listener), d); } + /** + * Set Wifi Display information. + * + * @param c is the channel created at {@link #initialize} + * @param wfdInfo the Wifi Display information to set + * @param listener for callbacks on success or failure. Can be null. + * + * @hide + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.CONFIGURE_WIFI_DISPLAY) + public void setWfdInfo(@NonNull Channel c, @NonNull WifiP2pWfdInfo wfdInfo, + @Nullable ActionListener listener) { + setWFDInfo(c, wfdInfo, listener); + } + /** @hide */ @UnsupportedAppUsage - public void setWFDInfo( - Channel c, WifiP2pWfdInfo wfdInfo, - ActionListener listener) { + @RequiresPermission(android.Manifest.permission.CONFIGURE_WIFI_DISPLAY) + public void setWFDInfo(@NonNull Channel c, @NonNull WifiP2pWfdInfo wfdInfo, + @Nullable ActionListener listener) { checkChannel(c); try { mService.checkConfigureWifiDisplayPermission(); @@ -1658,12 +1705,19 @@ public class WifiP2pManager { * a network id can be obtained by {@link WifiP2pGroup#getNetworkId()}. * * @param c is the channel created at {@link #initialize} - * @param netId he network id of the p2p group. + * @param netId the network id of the p2p group. * @param listener for callbacks on success or failure. Can be null. + * * @hide */ - @UnsupportedAppUsage - public void deletePersistentGroup(Channel c, int netId, ActionListener listener) { + @SystemApi + @RequiresPermission(anyOf = { + android.Manifest.permission.NETWORK_SETTINGS, + android.Manifest.permission.NETWORK_STACK, + android.Manifest.permission.OVERRIDE_WIFI_CONFIG + }) + public void deletePersistentGroup(@NonNull Channel c, int netId, + @Nullable ActionListener listener) { checkChannel(c); c.mAsyncChannel.sendMessage(DELETE_PERSISTENT_GROUP, netId, c.putListener(listener)); } @@ -1673,23 +1727,68 @@ public class WifiP2pManager { * * @param c is the channel created at {@link #initialize} * @param listener for callback when persistent group info list is available. Can be null. + * * @hide */ - @UnsupportedAppUsage - public void requestPersistentGroupInfo(Channel c, PersistentGroupInfoListener listener) { + @SystemApi + @RequiresPermission(anyOf = { + android.Manifest.permission.NETWORK_SETTINGS, + android.Manifest.permission.NETWORK_STACK, + android.Manifest.permission.READ_WIFI_CREDENTIAL + }) + public void requestPersistentGroupInfo(@NonNull Channel c, + @Nullable PersistentGroupInfoListener listener) { checkChannel(c); c.mAsyncChannel.sendMessage(REQUEST_PERSISTENT_GROUP_INFO, 0, c.putListener(listener)); } /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = {"MIRACAST_"}, value = { + MIRACAST_DISABLED, + MIRACAST_SOURCE, + MIRACAST_SINK}) + public @interface MiracastMode {} + + /** + * Miracast is disabled. + * @hide + */ + @SystemApi public static final int MIRACAST_DISABLED = 0; - /** @hide */ + /** + * Device acts as a Miracast source. + * @hide + */ + @SystemApi public static final int MIRACAST_SOURCE = 1; - /** @hide */ + /** + * Device acts as a Miracast sink. + * @hide + */ + @SystemApi public static final int MIRACAST_SINK = 2; - /** Internal use only @hide */ - @UnsupportedAppUsage - public void setMiracastMode(int mode) { + + /** + * This is used to provide information to drivers to optimize performance depending + * on the current mode of operation. + * {@link #MIRACAST_DISABLED} - disabled + * {@link #MIRACAST_SOURCE} - source operation + * {@link #MIRACAST_SINK} - sink operation + * + * As an example, the driver could reduce the channel dwell time during scanning + * when acting as a source or sink to minimize impact on Miracast. + * + * @param mode mode of operation. One of {@link #MIRACAST_DISABLED}, {@link #MIRACAST_SOURCE}, + * or {@link #MIRACAST_SINK} + * + * @hide + */ + @SystemApi + @RequiresPermission(allOf = { + android.Manifest.permission.CONNECTIVITY_INTERNAL, + android.Manifest.permission.CONFIGURE_WIFI_DISPLAY}) + public void setMiracastMode(@MiracastMode int mode) { try { mService.setMiracastMode(mode); } catch (RemoteException e) { @@ -1778,8 +1877,10 @@ public class WifiP2pManager { * * @param c is the channel created at {@link #initialize}. * @param listener for callback on success or failure. Can be null. + * * @hide */ + @SystemApi @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void factoryReset(@NonNull Channel c, @Nullable ActionListener listener) { checkChannel(c); diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pWfdInfo.java b/wifi/java/android/net/wifi/p2p/WifiP2pWfdInfo.java index 3caa280ef62a..48b07032162b 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pWfdInfo.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pWfdInfo.java @@ -16,49 +16,68 @@ package android.net.wifi.p2p; +import android.annotation.IntDef; +import android.annotation.NonNull; +import android.annotation.Nullable; import android.annotation.UnsupportedAppUsage; -import android.os.Build; -import android.os.Parcelable; import android.os.Parcel; +import android.os.Parcelable; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.util.Locale; /** - * A class representing Wifi Display information for a device - * @hide + * A class representing Wifi Display information for a device. + * + * See Wifi Display technical specification v1.0.0, section 5.1.2. */ -public class WifiP2pWfdInfo implements Parcelable { - - private static final String TAG = "WifiP2pWfdInfo"; +public final class WifiP2pWfdInfo implements Parcelable { private boolean mWfdEnabled; + /** Device information bitmap */ private int mDeviceInfo; - public static final int WFD_SOURCE = 0; - public static final int PRIMARY_SINK = 1; - public static final int SECONDARY_SINK = 2; - public static final int SOURCE_OR_PRIMARY_SINK = 3; - - /* Device information bitmap */ - /** One of {@link #WFD_SOURCE}, {@link #PRIMARY_SINK}, {@link #SECONDARY_SINK} - * or {@link #SOURCE_OR_PRIMARY_SINK} + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = { "DEVICE_TYPE_" }, value = { + DEVICE_TYPE_WFD_SOURCE, + DEVICE_TYPE_PRIMARY_SINK, + DEVICE_TYPE_SECONDARY_SINK, + DEVICE_TYPE_SOURCE_OR_PRIMARY_SINK}) + public @interface DeviceType {} + + /** The device is a Wifi Display Source. */ + public static final int DEVICE_TYPE_WFD_SOURCE = 0; + /** The device is a primary sink. */ + public static final int DEVICE_TYPE_PRIMARY_SINK = 1; + /** The device is a secondary sink. */ + public static final int DEVICE_TYPE_SECONDARY_SINK = 2; + /** The device is dual-role capable i.e. either a WFD source or a primary sink. */ + public static final int DEVICE_TYPE_SOURCE_OR_PRIMARY_SINK = 3; + + /** + * {@link #mDeviceInfo} & {@link #DEVICE_TYPE} is one of {@link #DEVICE_TYPE_WFD_SOURCE}, + * {@link #DEVICE_TYPE_PRIMARY_SINK}, {@link #DEVICE_TYPE_SECONDARY_SINK} or + * {@link #DEVICE_TYPE_SOURCE_OR_PRIMARY_SINK}. */ - private static final int DEVICE_TYPE = 0x3; - private static final int COUPLED_SINK_SUPPORT_AT_SOURCE = 0x4; - private static final int COUPLED_SINK_SUPPORT_AT_SINK = 0x8; - private static final int SESSION_AVAILABLE = 0x30; - private static final int SESSION_AVAILABLE_BIT1 = 0x10; - private static final int SESSION_AVAILABLE_BIT2 = 0x20; + private static final int DEVICE_TYPE = 1 << 1 | 1 << 0; + private static final int COUPLED_SINK_SUPPORT_AT_SOURCE = 1 << 2; + private static final int COUPLED_SINK_SUPPORT_AT_SINK = 1 << 3; + private static final int SESSION_AVAILABLE_BIT1 = 1 << 4; + private static final int SESSION_AVAILABLE_BIT2 = 1 << 5; + private static final int SESSION_AVAILABLE = + SESSION_AVAILABLE_BIT2 | SESSION_AVAILABLE_BIT1; private int mCtrlPort; private int mMaxThroughput; - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) - public WifiP2pWfdInfo() { - } + /** Default constructor. */ + public WifiP2pWfdInfo() {} + /** @hide */ @UnsupportedAppUsage public WifiP2pWfdInfo(int devInfo, int ctrlPort, int maxTput) { mWfdEnabled = true; @@ -67,24 +86,40 @@ public class WifiP2pWfdInfo implements Parcelable { mMaxThroughput = maxTput; } - @UnsupportedAppUsage + /** Returns true is Wifi Display is enabled, false otherwise. */ public boolean isWfdEnabled() { return mWfdEnabled; } - @UnsupportedAppUsage + /** + * Sets whether Wifi Display should be enabled. + * + * @param enabled true to enable Wifi Display, false to disable + */ public void setWfdEnabled(boolean enabled) { mWfdEnabled = enabled; } - @UnsupportedAppUsage + /** + * Get the type of the device. + * One of {@link #DEVICE_TYPE_WFD_SOURCE}, {@link #DEVICE_TYPE_PRIMARY_SINK}, + * {@link #DEVICE_TYPE_SECONDARY_SINK}, {@link #DEVICE_TYPE_SOURCE_OR_PRIMARY_SINK} + */ + @DeviceType public int getDeviceType() { - return (mDeviceInfo & DEVICE_TYPE); + return mDeviceInfo & DEVICE_TYPE; } - @UnsupportedAppUsage - public boolean setDeviceType(int deviceType) { - if (deviceType >= WFD_SOURCE && deviceType <= SOURCE_OR_PRIMARY_SINK) { + /** + * Sets the type of the device. + * + * @param deviceType One of {@link #DEVICE_TYPE_WFD_SOURCE}, {@link #DEVICE_TYPE_PRIMARY_SINK}, + * {@link #DEVICE_TYPE_SECONDARY_SINK}, {@link #DEVICE_TYPE_SOURCE_OR_PRIMARY_SINK} + * @return true if the device type was successfully set, false otherwise + */ + public boolean setDeviceType(@DeviceType int deviceType) { + if (DEVICE_TYPE_WFD_SOURCE <= deviceType + && deviceType <= DEVICE_TYPE_SOURCE_OR_PRIMARY_SINK) { mDeviceInfo &= ~DEVICE_TYPE; mDeviceInfo |= deviceType; return true; @@ -92,35 +127,16 @@ public class WifiP2pWfdInfo implements Parcelable { return false; } - public boolean isCoupledSinkSupportedAtSource() { - return (mDeviceInfo & COUPLED_SINK_SUPPORT_AT_SINK) != 0; - } - - public void setCoupledSinkSupportAtSource(boolean enabled) { - if (enabled ) { - mDeviceInfo |= COUPLED_SINK_SUPPORT_AT_SINK; - } else { - mDeviceInfo &= ~COUPLED_SINK_SUPPORT_AT_SINK; - } - } - - public boolean isCoupledSinkSupportedAtSink() { - return (mDeviceInfo & COUPLED_SINK_SUPPORT_AT_SINK) != 0; - } - - public void setCoupledSinkSupportAtSink(boolean enabled) { - if (enabled ) { - mDeviceInfo |= COUPLED_SINK_SUPPORT_AT_SINK; - } else { - mDeviceInfo &= ~COUPLED_SINK_SUPPORT_AT_SINK; - } - } - + /** Returns true if a session is available, false otherwise. */ public boolean isSessionAvailable() { return (mDeviceInfo & SESSION_AVAILABLE) != 0; } - @UnsupportedAppUsage + /** + * Sets whether a session is available. + * + * @param enabled true to indicate that a session is available, false otherwise. + */ public void setSessionAvailable(boolean enabled) { if (enabled) { mDeviceInfo |= SESSION_AVAILABLE_BIT1; @@ -130,29 +146,33 @@ public class WifiP2pWfdInfo implements Parcelable { } } + /** Returns the TCP port at which the WFD Device listens for RTSP messages. */ public int getControlPort() { return mCtrlPort; } - @UnsupportedAppUsage + /** Sets the TCP port at which the WFD Device listens for RTSP messages. */ public void setControlPort(int port) { mCtrlPort = port; } - @UnsupportedAppUsage + /** Sets the maximum average throughput capability of the WFD Device, in megabits/second. */ public void setMaxThroughput(int maxThroughput) { mMaxThroughput = maxThroughput; } + /** Returns the maximum average throughput capability of the WFD Device, in megabits/second. */ public int getMaxThroughput() { return mMaxThroughput; } + /** @hide */ public String getDeviceInfoHex() { return String.format( Locale.US, "%04x%04x%04x", mDeviceInfo, mCtrlPort, mMaxThroughput); } + @Override public String toString() { StringBuffer sbuf = new StringBuffer(); sbuf.append("WFD enabled: ").append(mWfdEnabled); @@ -167,9 +187,8 @@ public class WifiP2pWfdInfo implements Parcelable { return 0; } - /** copy constructor */ - @UnsupportedAppUsage - public WifiP2pWfdInfo(WifiP2pWfdInfo source) { + /** Copy constructor. */ + public WifiP2pWfdInfo(@Nullable WifiP2pWfdInfo source) { if (source != null) { mWfdEnabled = source.mWfdEnabled; mDeviceInfo = source.mDeviceInfo; @@ -179,14 +198,15 @@ public class WifiP2pWfdInfo implements Parcelable { } /** Implement the Parcelable interface */ - public void writeToParcel(Parcel dest, int flags) { + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { dest.writeInt(mWfdEnabled ? 1 : 0); dest.writeInt(mDeviceInfo); dest.writeInt(mCtrlPort); dest.writeInt(mMaxThroughput); } - public void readFromParcel(Parcel in) { + private void readFromParcel(Parcel in) { mWfdEnabled = (in.readInt() == 1); mDeviceInfo = in.readInt(); mCtrlPort = in.readInt(); @@ -194,8 +214,7 @@ public class WifiP2pWfdInfo implements Parcelable { } /** Implement the Parcelable interface */ - @UnsupportedAppUsage - public static final @android.annotation.NonNull Creator<WifiP2pWfdInfo> CREATOR = + public static final @NonNull Creator<WifiP2pWfdInfo> CREATOR = new Creator<WifiP2pWfdInfo>() { public WifiP2pWfdInfo createFromParcel(Parcel in) { WifiP2pWfdInfo device = new WifiP2pWfdInfo(); diff --git a/wifi/tests/src/android/net/wifi/p2p/WifiP2pWfdInfoTest.java b/wifi/tests/src/android/net/wifi/p2p/WifiP2pWfdInfoTest.java index d2f11688e4e5..cea73efc88d0 100644 --- a/wifi/tests/src/android/net/wifi/p2p/WifiP2pWfdInfoTest.java +++ b/wifi/tests/src/android/net/wifi/p2p/WifiP2pWfdInfoTest.java @@ -43,7 +43,7 @@ public class WifiP2pWfdInfoTest { @Before public void setUp() { // initialize device info flags. - mSourceInfo.setDeviceType(WifiP2pWfdInfo.WFD_SOURCE); + mSourceInfo.setDeviceType(WifiP2pWfdInfo.DEVICE_TYPE_WFD_SOURCE); mSourceInfo.setSessionAvailable(true); } @@ -57,14 +57,8 @@ public class WifiP2pWfdInfoTest { info.setWfdEnabled(true); assertTrue(info.isWfdEnabled()); - info.setDeviceType(WifiP2pWfdInfo.WFD_SOURCE); - assertEquals(WifiP2pWfdInfo.WFD_SOURCE, info.getDeviceType()); - - info.setCoupledSinkSupportAtSource(true); - assertTrue(info.isCoupledSinkSupportedAtSource()); - - info.setCoupledSinkSupportAtSink(true); - assertTrue(info.isCoupledSinkSupportedAtSink()); + info.setDeviceType(WifiP2pWfdInfo.DEVICE_TYPE_WFD_SOURCE); + assertEquals(WifiP2pWfdInfo.DEVICE_TYPE_WFD_SOURCE, info.getDeviceType()); info.setSessionAvailable(true); assertTrue(info.isSessionAvailable()); @@ -75,7 +69,7 @@ public class WifiP2pWfdInfoTest { info.setMaxThroughput(TEST_MAX_TPUT); assertEquals(TEST_MAX_TPUT, info.getMaxThroughput()); - assertEquals("0018270f0400", info.getDeviceInfoHex()); + assertEquals("0010270f0400", info.getDeviceInfoHex()); } /** |