Merge "Provide text locations to accessibility services."
diff --git a/Android.mk b/Android.mk
index 22323c5..a1e9ed9 100644
--- a/Android.mk
+++ b/Android.mk
@@ -265,8 +265,9 @@
core/java/android/security/keymaster/IKeyAttestationApplicationIdProvider.aidl \
core/java/android/service/autofill/IAutoFillAppCallback.aidl \
core/java/android/service/autofill/IAutoFillManagerService.aidl \
- core/java/android/service/autofill/IAutoFillServerCallback.aidl \
core/java/android/service/autofill/IAutoFillService.aidl \
+ core/java/android/service/autofill/IFillCallback.aidl \
+ core/java/android/service/autofill/ISaveCallback.aidl \
core/java/android/service/carrier/ICarrierService.aidl \
core/java/android/service/carrier/ICarrierMessagingCallback.aidl \
core/java/android/service/carrier/ICarrierMessagingService.aidl \
@@ -294,6 +295,10 @@
core/java/android/print/IWriteResultCallback.aidl \
core/java/android/printservice/IPrintService.aidl \
core/java/android/printservice/IPrintServiceClient.aidl \
+ core/java/android/companion/ICompanionDeviceManager.aidl \
+ core/java/android/companion/ICompanionDeviceManagerService.aidl \
+ core/java/android/companion/ICompanionDeviceManagerServiceCallback.aidl \
+ core/java/android/companion/IOnAssociateCallback.aidl \
core/java/android/service/dreams/IDreamManager.aidl \
core/java/android/service/dreams/IDreamService.aidl \
core/java/android/service/persistentdata/IPersistentDataBlockService.aidl \
diff --git a/api/current.txt b/api/current.txt
index ea17655..56a69d6 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -203,7 +203,6 @@
public static final class R.attr {
ctor public R.attr();
- field public static final int __removed0 = 16844097; // 0x1010541
field public static final int __removed1 = 16844099; // 0x1010543
field public static final int absListViewStyle = 16842858; // 0x101006a
field public static final int accessibilityEventTypes = 16843648; // 0x1010380
@@ -1270,6 +1269,7 @@
field public static final int targetId = 16843740; // 0x10103dc
field public static final int targetName = 16843853; // 0x101044d
field public static final int targetPackage = 16842785; // 0x1010021
+ field public static final int targetProcess = 16844097; // 0x1010541
field public static final int targetSandboxVersion = 16844110; // 0x101054e
field public static final int targetSdkVersion = 16843376; // 0x1010270
field public static final int taskAffinity = 16842770; // 0x1010012
@@ -2688,11 +2688,25 @@
package android.accessibilityservice {
+ public final class AccessibilityButtonController {
+ method public boolean isAccessibilityButtonAvailable();
+ method public void registerAccessibilityButtonCallback(android.accessibilityservice.AccessibilityButtonController.AccessibilityButtonCallback);
+ method public void registerAccessibilityButtonCallback(android.accessibilityservice.AccessibilityButtonController.AccessibilityButtonCallback, android.os.Handler);
+ method public void unregisterAccessibilityButtonCallback(android.accessibilityservice.AccessibilityButtonController.AccessibilityButtonCallback);
+ }
+
+ public static abstract class AccessibilityButtonController.AccessibilityButtonCallback {
+ ctor public AccessibilityButtonController.AccessibilityButtonCallback();
+ method public void onAvailabilityChanged(android.accessibilityservice.AccessibilityButtonController, boolean);
+ method public void onClicked(android.accessibilityservice.AccessibilityButtonController);
+ }
+
public abstract class AccessibilityService extends android.app.Service {
ctor public AccessibilityService();
method public final void disableSelf();
method public final boolean dispatchGesture(android.accessibilityservice.GestureDescription, android.accessibilityservice.AccessibilityService.GestureResultCallback, android.os.Handler);
method public android.view.accessibility.AccessibilityNodeInfo findFocus(int);
+ method public final android.accessibilityservice.AccessibilityButtonController getAccessibilityButtonController();
method public final android.accessibilityservice.FingerprintGestureController getFingerprintGestureController();
method public final android.accessibilityservice.AccessibilityService.MagnificationController getMagnificationController();
method public android.view.accessibility.AccessibilityNodeInfo getRootInActiveWindow();
@@ -2805,6 +2819,7 @@
field public static final int FLAG_ENABLE_ACCESSIBILITY_VOLUME = 128; // 0x80
field public static final int FLAG_INCLUDE_NOT_IMPORTANT_VIEWS = 2; // 0x2
field public static final int FLAG_REPORT_VIEW_IDS = 16; // 0x10
+ field public static final int FLAG_REQUEST_ACCESSIBILITY_BUTTON = 256; // 0x100
field public static final int FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY = 8; // 0x8
field public static final int FLAG_REQUEST_FILTER_KEY_EVENTS = 32; // 0x20
field public static final int FLAG_REQUEST_TOUCH_EXPLORATION_MODE = 4; // 0x4
@@ -2909,7 +2924,7 @@
public class AccountManager {
method public android.accounts.AccountManagerFuture<android.os.Bundle> addAccount(java.lang.String, java.lang.String, java.lang.String[], android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
method public boolean addAccountExplicitly(android.accounts.Account, java.lang.String, android.os.Bundle);
- method public boolean addAccountExplicitly(android.accounts.Account, java.lang.String, android.os.Bundle, java.util.Map<java.lang.Integer, java.lang.Integer>);
+ method public boolean addAccountExplicitly(android.accounts.Account, java.lang.String, android.os.Bundle, java.util.Map<java.lang.String, java.lang.Integer>);
method public void addOnAccountsUpdatedListener(android.accounts.OnAccountsUpdateListener, android.os.Handler, boolean);
method public void addOnAccountsUpdatedListener(android.accounts.OnAccountsUpdateListener, android.os.Handler, boolean, java.lang.String[]);
method public java.lang.String blockingGetAuthToken(android.accounts.Account, java.lang.String, boolean) throws android.accounts.AuthenticatorException, java.io.IOException, android.accounts.OperationCanceledException;
@@ -2918,7 +2933,7 @@
method public android.accounts.AccountManagerFuture<android.os.Bundle> editProperties(java.lang.String, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
method public android.accounts.AccountManagerFuture<android.os.Bundle> finishSession(android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
method public static android.accounts.AccountManager get(android.content.Context);
- method public int getAccountVisibility(android.accounts.Account, int);
+ method public int getAccountVisibility(android.accounts.Account, java.lang.String);
method public android.accounts.Account[] getAccounts();
method public java.util.Map<android.accounts.Account, java.lang.Integer> getAccountsAndVisibilityForPackage(java.lang.String, java.lang.String);
method public android.accounts.Account[] getAccountsByType(java.lang.String);
@@ -2929,9 +2944,9 @@
method public android.accounts.AccountManagerFuture<android.os.Bundle> getAuthToken(android.accounts.Account, java.lang.String, android.os.Bundle, boolean, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
method public android.accounts.AccountManagerFuture<android.os.Bundle> getAuthTokenByFeatures(java.lang.String, java.lang.String, java.lang.String[], android.app.Activity, android.os.Bundle, android.os.Bundle, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
method public android.accounts.AuthenticatorDescription[] getAuthenticatorTypes();
+ method public java.util.Map<java.lang.String, java.lang.Integer> getPackagesAndVisibilityForAccount(android.accounts.Account);
method public java.lang.String getPassword(android.accounts.Account);
method public java.lang.String getPreviousName(android.accounts.Account);
- method public java.util.Map<java.lang.Integer, java.lang.Integer> getUidsAndVisibilityForAccount(android.accounts.Account);
method public java.lang.String getUserData(android.accounts.Account, java.lang.String);
method public android.accounts.AccountManagerFuture<java.lang.Boolean> hasFeatures(android.accounts.Account, java.lang.String[], android.accounts.AccountManagerCallback<java.lang.Boolean>, android.os.Handler);
method public void invalidateAuthToken(java.lang.String, java.lang.String);
@@ -2945,7 +2960,7 @@
method public boolean removeAccountExplicitly(android.accounts.Account);
method public void removeOnAccountsUpdatedListener(android.accounts.OnAccountsUpdateListener);
method public android.accounts.AccountManagerFuture<android.accounts.Account> renameAccount(android.accounts.Account, java.lang.String, android.accounts.AccountManagerCallback<android.accounts.Account>, android.os.Handler);
- method public boolean setAccountVisibility(android.accounts.Account, int, int);
+ method public boolean setAccountVisibility(android.accounts.Account, java.lang.String, int);
method public void setAuthToken(android.accounts.Account, java.lang.String, java.lang.String);
method public void setPassword(android.accounts.Account, java.lang.String);
method public void setUserData(android.accounts.Account, java.lang.String, java.lang.String);
@@ -2985,8 +3000,8 @@
field public static final java.lang.String KEY_PASSWORD = "password";
field public static final java.lang.String KEY_USERDATA = "userdata";
field public static final deprecated java.lang.String LOGIN_ACCOUNTS_CHANGED_ACTION = "android.accounts.LOGIN_ACCOUNTS_CHANGED";
- field public static final int UID_KEY_DEFAULT_LEGACY_VISIBILITY = -3; // 0xfffffffd
- field public static final int UID_KEY_DEFAULT_VISIBILITY = -2; // 0xfffffffe
+ field public static final java.lang.String PACKAGE_NAME_KEY_LEGACY_NOT_VISIBLE = "android.accounts.key_legacy_not_visible";
+ field public static final java.lang.String PACKAGE_NAME_KEY_LEGACY_VISIBLE = "android.accounts.key_legacy_visible";
field public static final int VISIBILITY_NOT_VISIBLE = 3; // 0x3
field public static final int VISIBILITY_UNDEFINED = 0; // 0x0
field public static final int VISIBILITY_USER_MANAGED_NOT_VISIBLE = 4; // 0x4
@@ -4171,7 +4186,6 @@
method public abstract void onActivityCreated(android.app.Activity, android.os.Bundle);
method public abstract void onActivityDestroyed(android.app.Activity);
method public abstract void onActivityPaused(android.app.Activity);
- method public default void onActivityPreCreated(android.app.Activity, android.os.Bundle);
method public abstract void onActivityResumed(android.app.Activity);
method public abstract void onActivitySaveInstanceState(android.app.Activity, android.os.Bundle);
method public abstract void onActivityStarted(android.app.Activity);
@@ -4805,6 +4819,7 @@
method public void addMonitor(android.app.Instrumentation.ActivityMonitor);
method public android.app.Instrumentation.ActivityMonitor addMonitor(android.content.IntentFilter, android.app.Instrumentation.ActivityResult, boolean);
method public android.app.Instrumentation.ActivityMonitor addMonitor(java.lang.String, android.app.Instrumentation.ActivityResult, boolean);
+ method public void addResults(android.os.Bundle);
method public void callActivityOnCreate(android.app.Activity, android.os.Bundle);
method public void callActivityOnCreate(android.app.Activity, android.os.Bundle, android.os.PersistableBundle);
method public void callActivityOnDestroy(android.app.Activity);
@@ -4829,6 +4844,7 @@
method public android.os.Bundle getBinderCounts();
method public android.content.ComponentName getComponentName();
method public android.content.Context getContext();
+ method public java.lang.String getProcessName();
method public android.content.Context getTargetContext();
method public android.app.UiAutomation getUiAutomation();
method public android.app.UiAutomation getUiAutomation(int);
@@ -5045,14 +5061,19 @@
ctor public Notification(android.os.Parcel);
method public android.app.Notification clone();
method public int describeContents();
+ method public int getBadgeIcon();
method public java.lang.String getChannel();
method public java.lang.String getGroup();
method public android.graphics.drawable.Icon getLargeIcon();
+ method public java.lang.String getShortcutId();
method public android.graphics.drawable.Icon getSmallIcon();
method public java.lang.String getSortKey();
method public long getTimeout();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.media.AudioAttributes AUDIO_ATTRIBUTES_DEFAULT;
+ field public static final int BADGE_ICON_LARGE = 2; // 0x2
+ field public static final int BADGE_ICON_NONE = 0; // 0x0
+ field public static final int BADGE_ICON_SMALL = 1; // 0x1
field public static final java.lang.String CATEGORY_ALARM = "alarm";
field public static final java.lang.String CATEGORY_CALL = "call";
field public static final java.lang.String CATEGORY_EMAIL = "email";
@@ -5144,7 +5165,7 @@
field public deprecated int ledARGB;
field public deprecated int ledOffMS;
field public deprecated int ledOnMS;
- field public deprecated int number;
+ field public int number;
field public deprecated int priority;
field public android.app.Notification publicVersion;
field public deprecated android.net.Uri sound;
@@ -5232,6 +5253,7 @@
method public android.app.Notification.Builder addExtras(android.os.Bundle);
method public android.app.Notification.Builder addPerson(java.lang.String);
method public android.app.Notification build();
+ method public android.app.Notification.Builder chooseBadgeIcon(int);
method public android.widget.RemoteViews createBigContentView();
method public android.widget.RemoteViews createContentView();
method public android.widget.RemoteViews createHeadsUpContentView();
@@ -5264,13 +5286,14 @@
method public android.app.Notification.Builder setLargeIcon(android.graphics.drawable.Icon);
method public deprecated android.app.Notification.Builder setLights(int, int, int);
method public android.app.Notification.Builder setLocalOnly(boolean);
- method public deprecated android.app.Notification.Builder setNumber(int);
+ method public android.app.Notification.Builder setNumber(int);
method public android.app.Notification.Builder setOngoing(boolean);
method public android.app.Notification.Builder setOnlyAlertOnce(boolean);
method public deprecated android.app.Notification.Builder setPriority(int);
method public android.app.Notification.Builder setProgress(int, int, boolean);
method public android.app.Notification.Builder setPublicVersion(android.app.Notification);
method public android.app.Notification.Builder setRemoteInputHistory(java.lang.CharSequence[]);
+ method public android.app.Notification.Builder setShortcutId(java.lang.String);
method public android.app.Notification.Builder setShowWhen(boolean);
method public android.app.Notification.Builder setSmallIcon(int);
method public android.app.Notification.Builder setSmallIcon(int, int);
@@ -6194,6 +6217,7 @@
method public java.lang.CharSequence getDeviceOwnerLockScreenInfo();
method public java.util.List<byte[]> getInstalledCaCerts(android.content.ComponentName);
method public int getKeyguardDisabledFeatures(android.content.ComponentName);
+ method public java.lang.String[] getLockTaskPackages(android.content.ComponentName);
method public java.lang.CharSequence getLongSupportMessage(android.content.ComponentName);
method public int getMaximumFailedPasswordsForWipe(android.content.ComponentName);
method public long getMaximumTimeToLock(android.content.ComponentName);
@@ -6509,6 +6533,7 @@
method public float getAlpha();
method public android.view.autofill.AutoFillId getAutoFillId();
method public android.view.autofill.AutoFillType getAutoFillType();
+ method public android.view.autofill.AutoFillValue getAutoFillValue();
method public android.app.assist.AssistStructure.ViewNode getChildAt(int);
method public int getChildCount();
method public java.lang.String getClassName();
@@ -7941,6 +7966,65 @@
}
+package android.companion {
+
+ public final class AssociationRequest<F extends android.companion.DeviceFilter> implements android.os.Parcelable {
+ method public int describeContents();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.companion.AssociationRequest> CREATOR;
+ }
+
+ public static final class AssociationRequest.Builder<F extends android.companion.DeviceFilter> {
+ method public android.companion.AssociationRequest<F> build();
+ method public static android.companion.AssociationRequest.Builder<android.companion.BluetoothDeviceFilter> createForBluetoothDevice();
+ method public static android.companion.AssociationRequest.Builder<android.companion.BluetoothLEDeviceFilter> createForBluetoothLEDevice();
+ method public android.companion.AssociationRequest.Builder<F> setDeviceFilter(F);
+ method public android.companion.AssociationRequest.Builder<F> setSingleDevice(boolean);
+ }
+
+ public final class BluetoothDeviceFilter implements android.companion.DeviceFilter {
+ method public int describeContents();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.companion.BluetoothDeviceFilter> CREATOR;
+ }
+
+ public static final class BluetoothDeviceFilter.Builder {
+ ctor public BluetoothDeviceFilter.Builder();
+ method public android.companion.BluetoothDeviceFilter.Builder addServiceUuid(android.os.ParcelUuid, android.os.ParcelUuid);
+ method public android.companion.BluetoothDeviceFilter build();
+ method public android.companion.BluetoothDeviceFilter.Builder setAddress(java.lang.String);
+ method public android.companion.BluetoothDeviceFilter.Builder setNamePattern(java.util.regex.Pattern);
+ }
+
+ public final class BluetoothLEDeviceFilter implements android.companion.DeviceFilter {
+ method public int describeContents();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.companion.BluetoothLEDeviceFilter> CREATOR;
+ }
+
+ public static final class BluetoothLEDeviceFilter.Builder {
+ ctor public BluetoothLEDeviceFilter.Builder();
+ method public android.companion.BluetoothLEDeviceFilter build();
+ method public android.companion.BluetoothLEDeviceFilter.Builder setNamePattern(java.util.regex.Pattern);
+ method public android.companion.BluetoothLEDeviceFilter.Builder setScanFilter(android.bluetooth.le.ScanFilter);
+ }
+
+ public final class CompanionDeviceManager {
+ method public void associate(android.companion.AssociationRequest<?>, android.companion.CompanionDeviceManager.Callback, android.os.Handler);
+ field public static final java.lang.String EXTRA_DEVICE = "android.companion.extra.DEVICE";
+ }
+
+ public static abstract class CompanionDeviceManager.Callback {
+ ctor public CompanionDeviceManager.Callback();
+ method public abstract void onDeviceFound(android.content.IntentSender);
+ method public abstract void onFailure(java.lang.CharSequence);
+ }
+
+ public abstract interface DeviceFilter<D extends android.os.Parcelable> implements android.os.Parcelable {
+ }
+
+}
+
package android.content {
public abstract class AbstractThreadedSyncAdapter {
@@ -8553,6 +8637,7 @@
field public static final java.lang.String CAPTIONING_SERVICE = "captioning";
field public static final java.lang.String CARRIER_CONFIG_SERVICE = "carrier_config";
field public static final java.lang.String CLIPBOARD_SERVICE = "clipboard";
+ field public static final java.lang.String COMPANION_DEVICE_SERVICE = "companion_device";
field public static final java.lang.String CONNECTIVITY_SERVICE = "connectivity";
field public static final java.lang.String CONSUMER_IR_SERVICE = "consumer_ir";
field public static final int CONTEXT_IGNORE_SECURITY = 2; // 0x2
@@ -9090,6 +9175,10 @@
field public static final java.lang.String EXTRA_ASSIST_INPUT_HINT_KEYBOARD = "android.intent.extra.ASSIST_INPUT_HINT_KEYBOARD";
field public static final java.lang.String EXTRA_ASSIST_PACKAGE = "android.intent.extra.ASSIST_PACKAGE";
field public static final java.lang.String EXTRA_ASSIST_UID = "android.intent.extra.ASSIST_UID";
+ field public static final java.lang.String EXTRA_AUTO_FILL_ASSIST_STRUCTURE = "android.intent.extra.AUTO_FILL_ASSIST_STRUCTURE";
+ field public static final java.lang.String EXTRA_AUTO_FILL_CALLBACK = "android.intent.extra.AUTO_FILL_CALLBACK";
+ field public static final java.lang.String EXTRA_AUTO_FILL_EXTRAS = "android.intent.extra.AUTO_FILL_EXTRAS";
+ field public static final java.lang.String EXTRA_AUTO_FILL_ITEM_ID = "android.intent.extra.AUTO_FILL_ITEM_ID";
field public static final java.lang.String EXTRA_BCC = "android.intent.extra.BCC";
field public static final java.lang.String EXTRA_BUG_REPORT = "android.intent.extra.BUG_REPORT";
field public static final java.lang.String EXTRA_CC = "android.intent.extra.CC";
@@ -9126,6 +9215,7 @@
field public static final java.lang.String EXTRA_PHONE_NUMBER = "android.intent.extra.PHONE_NUMBER";
field public static final java.lang.String EXTRA_PROCESS_TEXT = "android.intent.extra.PROCESS_TEXT";
field public static final java.lang.String EXTRA_PROCESS_TEXT_READONLY = "android.intent.extra.PROCESS_TEXT_READONLY";
+ field public static final java.lang.String EXTRA_QUICK_VIEW_PLAIN = "android.intent.extra.QUICK_VIEW_PLAIN";
field public static final java.lang.String EXTRA_QUIET_MODE = "android.intent.extra.QUIET_MODE";
field public static final java.lang.String EXTRA_REFERRER = "android.intent.extra.REFERRER";
field public static final java.lang.String EXTRA_REFERRER_NAME = "android.intent.extra.REFERRER_NAME";
@@ -9902,6 +9992,7 @@
field public java.lang.String[] splitPublicSourceDirs;
field public java.lang.String[] splitSourceDirs;
field public java.lang.String targetPackage;
+ field public java.lang.String targetProcess;
}
public class LabeledIntent extends android.content.Intent {
@@ -10323,6 +10414,7 @@
field public static final java.lang.String FEATURE_VERIFIED_BOOT = "android.software.verified_boot";
field public static final java.lang.String FEATURE_VR_MODE = "android.software.vr.mode";
field public static final java.lang.String FEATURE_VR_MODE_HIGH_PERFORMANCE = "android.hardware.vr.high_performance";
+ field public static final java.lang.String FEATURE_VULKAN_HARDWARE_COMPUTE = "android.hardware.vulkan.compute";
field public static final java.lang.String FEATURE_VULKAN_HARDWARE_LEVEL = "android.hardware.vulkan.level";
field public static final java.lang.String FEATURE_VULKAN_HARDWARE_VERSION = "android.hardware.vulkan.version";
field public static final java.lang.String FEATURE_WATCH = "android.hardware.type.watch";
@@ -20439,6 +20531,7 @@
method public int getContentType();
method public int getFlags();
method public int getUsage();
+ method public static int getVolumeControlStream(android.media.AudioAttributes);
method public void writeToParcel(android.os.Parcel, int);
field public static final int CONTENT_TYPE_MOVIE = 3; // 0x3
field public static final int CONTENT_TYPE_MUSIC = 2; // 0x2
@@ -22161,6 +22254,7 @@
}
public static final class MediaMuxer.OutputFormat {
+ field public static final int MUXER_OUTPUT_3GPP = 2; // 0x2
field public static final int MUXER_OUTPUT_MPEG_4 = 0; // 0x0
field public static final int MUXER_OUTPUT_WEBM = 1; // 0x1
}
@@ -23581,6 +23675,8 @@
public final class MediaController {
ctor public MediaController(android.content.Context, android.media.session.MediaSession.Token);
+ method public void addQueueItem(android.media.MediaDescription);
+ method public void addQueueItem(android.media.MediaDescription, int);
method public void adjustVolume(int, int);
method public boolean dispatchMediaButtonEvent(android.view.KeyEvent);
method public android.os.Bundle getExtras();
@@ -23599,6 +23695,8 @@
method public boolean isShuffleModeEnabled();
method public void registerCallback(android.media.session.MediaController.Callback);
method public void registerCallback(android.media.session.MediaController.Callback, android.os.Handler);
+ method public void removeQueueItem(android.media.MediaDescription);
+ method public void removeQueueItemAt(int);
method public void sendCommand(java.lang.String, android.os.Bundle, android.os.ResultReceiver);
method public void setVolumeTo(int, int);
method public void unregisterCallback(android.media.session.MediaController.Callback);
@@ -23676,11 +23774,14 @@
method public void setSessionActivity(android.app.PendingIntent);
method public void setShuffleModeEnabled(boolean);
field public static final int FLAG_HANDLES_MEDIA_BUTTONS = 1; // 0x1
+ field public static final int FLAG_HANDLES_QUEUE_COMMANDS = 4; // 0x4
field public static final int FLAG_HANDLES_TRANSPORT_CONTROLS = 2; // 0x2
}
public static abstract class MediaSession.Callback {
ctor public MediaSession.Callback();
+ method public void onAddQueueItem(android.media.MediaDescription);
+ method public void onAddQueueItem(android.media.MediaDescription, int);
method public void onCommand(java.lang.String, android.os.Bundle, android.os.ResultReceiver);
method public void onCustomAction(java.lang.String, android.os.Bundle);
method public void onFastForward();
@@ -23694,6 +23795,8 @@
method public void onPrepareFromMediaId(java.lang.String, android.os.Bundle);
method public void onPrepareFromSearch(java.lang.String, android.os.Bundle);
method public void onPrepareFromUri(android.net.Uri, android.os.Bundle);
+ method public void onRemoveQueueItem(android.media.MediaDescription);
+ method public void onRemoveQueueItemAt(int);
method public void onRewind();
method public void onSeekTo(long);
method public void onSetRating(android.media.Rating);
@@ -23941,6 +24044,7 @@
field public static final java.lang.String AVAILABILITY_AVAILABLE = "AVAILABILITY_AVAILABLE";
field public static final java.lang.String AVAILABILITY_FREE_WITH_SUBSCRIPTION = "AVAILABILITY_FREE_WITH_SUBSCRIPTION";
field public static final java.lang.String AVAILABILITY_PAID_CONTENT = "AVAILABILITY_PAID_CONTENT";
+ field public static final java.lang.String COLUMN_APP_LINK_INTENT_URI = "app_link_intent_uri";
field public static final java.lang.String COLUMN_AUDIO_LANGUAGE = "audio_language";
field public static final java.lang.String COLUMN_AUTHOR = "author";
field public static final java.lang.String COLUMN_AVAILABILITY = "availability";
@@ -23948,6 +24052,7 @@
field public static final java.lang.String COLUMN_CANONICAL_GENRE = "canonical_genre";
field public static final java.lang.String COLUMN_CHANNEL_ID = "channel_id";
field public static final java.lang.String COLUMN_CONTENT_RATING = "content_rating";
+ field public static final java.lang.String COLUMN_DURATION_MILLIS = "duration_millis";
field public static final java.lang.String COLUMN_END_TIME_UTC_MILLIS = "end_time_utc_millis";
field public static final java.lang.String COLUMN_EPISODE_DISPLAY_NUMBER = "episode_display_number";
field public static final deprecated java.lang.String COLUMN_EPISODE_NUMBER = "episode_number";
@@ -23961,17 +24066,14 @@
field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG4 = "internal_provider_flag4";
field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_ID = "internal_provider_id";
field public static final java.lang.String COLUMN_ITEM_COUNT = "item_count";
+ field public static final java.lang.String COLUMN_LAST_PLAYBACK_POSITION_MILLIS = "last_playback_position_millis";
field public static final java.lang.String COLUMN_LIVE = "live";
- field public static final java.lang.String COLUMN_LOGO = "logo";
+ field public static final java.lang.String COLUMN_LOGO_URI = "logo_uri";
field public static final java.lang.String COLUMN_LONG_DESCRIPTION = "long_description";
field public static final java.lang.String COLUMN_OFFER_PRICE = "offer_price";
field public static final java.lang.String COLUMN_POSTER_ART_ASPECT_RATIO = "poster_art_aspect_ratio";
field public static final java.lang.String COLUMN_POSTER_ART_URI = "poster_art_uri";
- field public static final java.lang.String COLUMN_PREVIEW_DURATION = "preview_duration";
- field public static final java.lang.String COLUMN_PREVIEW_INTENT_URI = "preview_intent_uri";
- field public static final java.lang.String COLUMN_PREVIEW_LAST_PLAYBACK_POSITION = "preview_last_playback_position";
field public static final java.lang.String COLUMN_PREVIEW_VIDEO_URI = "preview_video_uri";
- field public static final java.lang.String COLUMN_PREVIEW_WEIGHT = "preview_weight";
field public static final java.lang.String COLUMN_RECORDING_PROHIBITED = "recording_prohibited";
field public static final java.lang.String COLUMN_RELEASE_DATE = "release_date";
field public static final java.lang.String COLUMN_REVIEW_RATING = "review_rating";
@@ -23991,6 +24093,7 @@
field public static final java.lang.String COLUMN_VIDEO_HEIGHT = "video_height";
field public static final java.lang.String COLUMN_VIDEO_WIDTH = "video_width";
field public static final java.lang.String COLUMN_WATCH_NEXT_TYPE = "watch_next_type";
+ field public static final java.lang.String COLUMN_WEIGHT = "weight";
field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/program";
field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/program";
field public static final android.net.Uri CONTENT_URI;
@@ -25736,6 +25839,7 @@
public class WifiManager {
method public int addNetwork(android.net.wifi.WifiConfiguration);
+ method public boolean addOrUpdatePasspointConfiguration(android.net.wifi.hotspot2.PasspointConfiguration);
method public static int calculateSignalLevel(int, int);
method public void cancelWps(android.net.wifi.WifiManager.WpsCallback);
method public static int compareSignalLevel(int, int);
@@ -25748,6 +25852,7 @@
method public java.util.List<android.net.wifi.WifiConfiguration> getConfiguredNetworks();
method public android.net.wifi.WifiInfo getConnectionInfo();
method public android.net.DhcpInfo getDhcpInfo();
+ method public java.util.List<android.net.wifi.hotspot2.PasspointConfiguration> getPasspointConfigurations();
method public java.util.List<android.net.wifi.ScanResult> getScanResults();
method public int getWifiState();
method public boolean is5GHzBandSupported();
@@ -25763,6 +25868,7 @@
method public boolean reassociate();
method public boolean reconnect();
method public boolean removeNetwork(int);
+ method public boolean removePasspointConfiguration(java.lang.String);
method public boolean saveConfiguration();
method public void setTdlsEnabled(java.net.InetAddress, boolean);
method public void setTdlsEnabledWithMacAddress(java.lang.String, boolean);
@@ -25977,6 +26083,241 @@
}
+package android.net.wifi.hotspot2 {
+
+ public final class ConfigParser {
+ method public static android.net.wifi.hotspot2.PasspointConfiguration parsePasspointConfig(java.lang.String, byte[]);
+ }
+
+ public final class PasspointConfiguration implements android.os.Parcelable {
+ ctor public PasspointConfiguration();
+ ctor public PasspointConfiguration(android.net.wifi.hotspot2.PasspointConfiguration);
+ method public int describeContents();
+ method public android.net.wifi.hotspot2.pps.Credential getCredential();
+ method public int getCredentialPriority();
+ method public android.net.wifi.hotspot2.pps.HomeSp getHomeSp();
+ method public android.net.wifi.hotspot2.pps.Policy getPolicy();
+ method public long getSubscriptionCreationTimeInMs();
+ method public long getSubscriptionExpirationTimeInMs();
+ method public java.lang.String getSubscriptionType();
+ method public android.net.wifi.hotspot2.pps.UpdateParameter getSubscriptionUpdate();
+ method public java.util.Map<java.lang.String, byte[]> getTrustRootCertList();
+ method public int getUpdateIdentififer();
+ method public long getUsageLimitDataLimit();
+ method public long getUsageLimitStartTimeInMs();
+ method public long getUsageLimitTimeLimitInMinutes();
+ method public long getUsageLimitUsageTimePeriodInMinutes();
+ method public void setCredential(android.net.wifi.hotspot2.pps.Credential);
+ method public void setCredentialPriority(int);
+ method public void setHomeSp(android.net.wifi.hotspot2.pps.HomeSp);
+ method public void setPolicy(android.net.wifi.hotspot2.pps.Policy);
+ method public void setSubscriptionCreationTimeInMs(long);
+ method public void setSubscriptionExpirationTimeInMs(long);
+ method public void setSubscriptionType(java.lang.String);
+ method public void setSubscriptionUpdate(android.net.wifi.hotspot2.pps.UpdateParameter);
+ method public void setTrustRootCertList(java.util.Map<java.lang.String, byte[]>);
+ method public void setUpdateIdentifier(int);
+ method public void setUsageLimitDataLimit(long);
+ method public void setUsageLimitStartTimeInMs(long);
+ method public void setUsageLimitTimeLimitInMinutes(long);
+ method public void setUsageLimitUsageTimePeriodInMinutes(long);
+ method public boolean validate();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.PasspointConfiguration> CREATOR;
+ }
+
+}
+
+package android.net.wifi.hotspot2.omadm {
+
+ public final class PpsMoParser {
+ method public static android.net.wifi.hotspot2.PasspointConfiguration parseMoText(java.lang.String);
+ }
+
+}
+
+package android.net.wifi.hotspot2.pps {
+
+ public final class Credential implements android.os.Parcelable {
+ ctor public Credential();
+ ctor public Credential(android.net.wifi.hotspot2.pps.Credential);
+ method public int describeContents();
+ method public java.security.cert.X509Certificate getCaCertificate();
+ method public android.net.wifi.hotspot2.pps.Credential.CertificateCredential getCertCredential();
+ method public boolean getCheckAaaServerStatus();
+ method public java.security.cert.X509Certificate[] getClientCertificateChain();
+ method public java.security.PrivateKey getClientPrivateKey();
+ method public long getCreationTimeInMs();
+ method public long getExpirationTimeInMs();
+ method public java.lang.String getRealm();
+ method public android.net.wifi.hotspot2.pps.Credential.SimCredential getSimCredential();
+ method public android.net.wifi.hotspot2.pps.Credential.UserCredential getUserCredential();
+ method public void setCaCertificate(java.security.cert.X509Certificate);
+ method public void setCertCredential(android.net.wifi.hotspot2.pps.Credential.CertificateCredential);
+ method public void setCheckAaaServerCertStatus(boolean);
+ method public void setClientCertificateChain(java.security.cert.X509Certificate[]);
+ method public void setClientPrivateKey(java.security.PrivateKey);
+ method public void setCreationTimeInMs(long);
+ method public void setExpirationTimeInMs(long);
+ method public void setRealm(java.lang.String);
+ method public void setSimCredential(android.net.wifi.hotspot2.pps.Credential.SimCredential);
+ method public void setUserCredential(android.net.wifi.hotspot2.pps.Credential.UserCredential);
+ method public boolean validate();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.Credential> CREATOR;
+ }
+
+ public static final class Credential.CertificateCredential implements android.os.Parcelable {
+ ctor public Credential.CertificateCredential();
+ ctor public Credential.CertificateCredential(android.net.wifi.hotspot2.pps.Credential.CertificateCredential);
+ method public int describeContents();
+ method public byte[] getCertSha256Fingerprint();
+ method public java.lang.String getCertType();
+ method public void setCertSha256Fingerprint(byte[]);
+ method public void setCertType(java.lang.String);
+ method public boolean validate();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.Credential.CertificateCredential> CREATOR;
+ }
+
+ public static final class Credential.SimCredential implements android.os.Parcelable {
+ ctor public Credential.SimCredential();
+ ctor public Credential.SimCredential(android.net.wifi.hotspot2.pps.Credential.SimCredential);
+ method public int describeContents();
+ method public int getEapType();
+ method public java.lang.String getImsi();
+ method public void setEapType(int);
+ method public void setImsi(java.lang.String);
+ method public boolean validate();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.Credential.SimCredential> CREATOR;
+ }
+
+ public static final class Credential.UserCredential implements android.os.Parcelable {
+ ctor public Credential.UserCredential();
+ ctor public Credential.UserCredential(android.net.wifi.hotspot2.pps.Credential.UserCredential);
+ method public int describeContents();
+ method public boolean getAbleToShare();
+ method public int getEapType();
+ method public boolean getMachineManaged();
+ method public java.lang.String getNonEapInnerMethod();
+ method public java.lang.String getPassword();
+ method public java.lang.String getSoftTokenApp();
+ method public java.lang.String getUsername();
+ method public void setAbleToShare(boolean);
+ method public void setEapType(int);
+ method public void setMachineManaged(boolean);
+ method public void setNonEapInnerMethod(java.lang.String);
+ method public void setPassword(java.lang.String);
+ method public void setSoftTokenApp(java.lang.String);
+ method public void setUsername(java.lang.String);
+ method public boolean validate();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.Credential.UserCredential> CREATOR;
+ }
+
+ public final class HomeSp implements android.os.Parcelable {
+ ctor public HomeSp();
+ ctor public HomeSp(android.net.wifi.hotspot2.pps.HomeSp);
+ method public int describeContents();
+ method public java.lang.String getFqdn();
+ method public java.lang.String getFriendlyName();
+ method public java.util.Map<java.lang.String, java.lang.Long> getHomeNetworkIds();
+ method public java.lang.String getIconUrl();
+ method public long[] getMatchAllOis();
+ method public long[] getMatchAnysOis();
+ method public java.lang.String[] getOtherHomePartners();
+ method public long[] getRoamingConsortiumOis();
+ method public void setFqdn(java.lang.String);
+ method public void setFriendlyName(java.lang.String);
+ method public void setHomeNetworkIds(java.util.Map<java.lang.String, java.lang.Long>);
+ method public void setIconUrl(java.lang.String);
+ method public void setMatchAllOis(long[]);
+ method public void setMatchAnyOis(long[]);
+ method public void setOtherHomePartners(java.lang.String[]);
+ method public void setRoamingConsortiumOis(long[]);
+ method public boolean validate();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.HomeSp> CREATOR;
+ }
+
+ public final class Policy implements android.os.Parcelable {
+ ctor public Policy();
+ ctor public Policy(android.net.wifi.hotspot2.pps.Policy);
+ method public int describeContents();
+ method public java.lang.String[] getExcludedSsidList();
+ method public int getMaximumBssLoadValue();
+ method public long getMinHomeDownlinkBandWidht();
+ method public long getMinHomeUplinkBandwidth();
+ method public long getMinRoamingDownlinkBandwidth();
+ method public long getMinRoamingUplinkBandwidth();
+ method public android.net.wifi.hotspot2.pps.UpdateParameter getPolicyUpdate();
+ method public java.util.List<android.net.wifi.hotspot2.pps.Policy.RoamingPartner> getPreferredRoamingPartnerList();
+ method public java.util.Map<java.lang.Integer, java.lang.String> getRequiredProtoPortMap();
+ method public void setExcludedSsidList(java.lang.String[]);
+ method public void setMaximumBssLoadValue(int);
+ method public void setMinHomeDownlinkBandwidth(long);
+ method public void setMinHomeUplinkBandwidth(long);
+ method public void setMinRoamingDownlinkBandwidth(long);
+ method public void setMinRoamingUplinkBandwidth(long);
+ method public void setPolicyUpdate(android.net.wifi.hotspot2.pps.UpdateParameter);
+ method public void setPreferredRoamingPartnerList(java.util.List<android.net.wifi.hotspot2.pps.Policy.RoamingPartner>);
+ method public void setRequiredProtoPortMap(java.util.Map<java.lang.Integer, java.lang.String>);
+ method public boolean validate();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.Policy> CREATOR;
+ }
+
+ public static final class Policy.RoamingPartner implements android.os.Parcelable {
+ ctor public Policy.RoamingPartner();
+ ctor public Policy.RoamingPartner(android.net.wifi.hotspot2.pps.Policy.RoamingPartner);
+ method public int describeContents();
+ method public java.lang.String getCountries();
+ method public java.lang.String getFqdn();
+ method public boolean getFqdnExactMatch();
+ method public int getPriority();
+ method public void setCountries(java.lang.String);
+ method public void setFqdn(java.lang.String);
+ method public void setFqdnExactMatch(boolean);
+ method public void setPriority(int);
+ method public boolean validate();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.Policy.RoamingPartner> CREATOR;
+ }
+
+ public final class UpdateParameter implements android.os.Parcelable {
+ ctor public UpdateParameter();
+ ctor public UpdateParameter(android.net.wifi.hotspot2.pps.UpdateParameter);
+ method public int describeContents();
+ method public java.lang.String getBase64EncodedPassword();
+ method public java.lang.String getRestriction();
+ method public java.lang.String getServerUri();
+ method public byte[] getTrustRootCertSha256Fingerprint();
+ method public java.lang.String getTrustRootCertUrl();
+ method public long getUpdateIntervalInMinutes();
+ method public java.lang.String getUpdateMethod();
+ method public java.lang.String getUsername();
+ method public void setBase64EncodedPassword(java.lang.String);
+ method public void setRestriction(java.lang.String);
+ method public void setServerUri(java.lang.String);
+ method public void setTrustRootCertSha256Fingerprint(byte[]);
+ method public void setTrustRootCertUrl(java.lang.String);
+ method public void setUpdateIntervalInMinutes(long);
+ method public void setUpdateMethod(java.lang.String);
+ method public void setUsername(java.lang.String);
+ method public boolean validate();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.UpdateParameter> CREATOR;
+ field public static final long UPDATE_CHECK_INTERVAL_NEVER = 4294967295L; // 0xffffffffL
+ field public static final java.lang.String UPDATE_METHOD_OMADM = "OMA-DM-ClientInitiated";
+ field public static final java.lang.String UPDATE_METHOD_SSP = "SSP-ClientInitiated";
+ field public static final java.lang.String UPDATE_RESTRICTION_HOMESP = "HomeSP";
+ field public static final java.lang.String UPDATE_RESTRICTION_ROAMING_PARTNER = "RoamingPartner";
+ field public static final java.lang.String UPDATE_RESTRICTION_UNRESTRICTED = "Unrestricted";
+ }
+
+}
+
package android.net.wifi.p2p {
public class WifiP2pConfig implements android.os.Parcelable {
@@ -35853,31 +36194,24 @@
ctor public AutoFillService();
method public final android.os.IBinder onBind(android.content.Intent);
method public void onConnected();
- method public void onDatasetAuthenticationRequest(android.os.Bundle, int);
method public void onDisconnected();
method public abstract void onFillRequest(android.app.assist.AssistStructure, android.os.Bundle, android.os.CancellationSignal, android.service.autofill.FillCallback);
- method public void onFillResponseAuthenticationRequest(android.os.Bundle, int);
method public abstract void onSaveRequest(android.app.assist.AssistStructure, android.os.Bundle, android.service.autofill.SaveCallback);
- field public static final java.lang.String EXTRA_DATASET_EXTRAS = "android.service.autofill.extra.DATASET_EXTRAS";
- field public static final java.lang.String EXTRA_RESPONSE_EXTRAS = "android.service.autofill.extra.RESPONSE_EXTRAS";
- field public static final int FLAG_AUTHENTICATION_ERROR = 4; // 0x4
- field public static final int FLAG_AUTHENTICATION_REQUESTED = 1; // 0x1
- field public static final int FLAG_AUTHENTICATION_SUCCESS = 2; // 0x2
- field public static final int FLAG_FINGERPRINT_AUTHENTICATION_NOT_AVAILABLE = 8; // 0x8
field public static final java.lang.String SERVICE_INTERFACE = "android.service.autofill.AutoFillService";
field public static final java.lang.String SERVICE_META_DATA = "android.autofill";
}
- public final class FillCallback {
- method public void onDatasetAuthentication(android.view.autofill.Dataset, int);
+ public final class FillCallback implements android.os.Parcelable {
+ method public int describeContents();
method public void onFailure(java.lang.CharSequence);
- method public void onFillResponseAuthentication(int);
method public void onSuccess(android.view.autofill.FillResponse);
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.service.autofill.FillCallback> CREATOR;
}
public final class SaveCallback {
method public void onFailure(java.lang.CharSequence);
- method public void onSuccess(android.view.autofill.AutoFillId[]);
+ method public void onSuccess();
}
}
@@ -41709,6 +42043,15 @@
method public android.transition.TransitionManager inflateTransitionManager(int, android.view.ViewGroup);
}
+ public abstract class TransitionListenerAdapter implements android.transition.Transition.TransitionListener {
+ ctor public TransitionListenerAdapter();
+ method public void onTransitionCancel(android.transition.Transition);
+ method public void onTransitionEnd(android.transition.Transition);
+ method public void onTransitionPause(android.transition.Transition);
+ method public void onTransitionResume(android.transition.Transition);
+ method public void onTransitionStart(android.transition.Transition);
+ }
+
public class TransitionManager {
ctor public TransitionManager();
method public static void beginDelayedTransition(android.view.ViewGroup);
@@ -44108,8 +44451,8 @@
method public void drawableHotspotChanged(float, float);
method protected void drawableStateChanged();
method public android.view.View findFocus();
- method public final <T extends android.view.View> T findViewById(int);
- method public final <T extends android.view.View> T findViewWithTag(java.lang.Object);
+ method public final android.view.View findViewById(int);
+ method public final android.view.View findViewWithTag(java.lang.Object);
method public void findViewsWithText(java.util.ArrayList<android.view.View>, java.lang.CharSequence, int);
method protected deprecated boolean fitSystemWindows(android.graphics.Rect);
method public android.view.View focusSearch(int);
@@ -44125,7 +44468,8 @@
method public android.view.animation.Animation getAnimation();
method public android.os.IBinder getApplicationWindowToken();
method public android.view.autofill.AutoFillType getAutoFillType();
- method public android.view.autofill.VirtualViewDelegate getAutoFillVirtualViewDelegate(android.view.autofill.VirtualViewDelegate.Callback);
+ method public android.view.autofill.AutoFillValue getAutoFillValue();
+ method public android.view.autofill.VirtualViewDelegate getAutoFillVirtualViewDelegate();
method public android.graphics.drawable.Drawable getBackground();
method public android.content.res.ColorStateList getBackgroundTintList();
method public android.graphics.PorterDuff.Mode getBackgroundTintMode();
@@ -44578,8 +44922,6 @@
field public static final int ACCESSIBILITY_LIVE_REGION_NONE = 0; // 0x0
field public static final int ACCESSIBILITY_LIVE_REGION_POLITE = 1; // 0x1
field public static final android.util.Property<android.view.View, java.lang.Float> ALPHA;
- field public static final int AUTO_FILL_FLAG_TYPE_FILL = 268435456; // 0x10000000
- field public static final int AUTO_FILL_FLAG_TYPE_SAVE = 536870912; // 0x20000000
field public static final int DRAG_FLAG_GLOBAL = 256; // 0x100
field public static final int DRAG_FLAG_GLOBAL_PERSISTABLE_URI_PERMISSION = 64; // 0x40
field public static final int DRAG_FLAG_GLOBAL_PREFIX_URI_PERMISSION = 128; // 0x80
@@ -45216,7 +45558,7 @@
method public abstract int addChildCount(int);
method public abstract void asyncCommit();
method public abstract android.view.ViewStructure asyncNewChild(int);
- method public abstract android.view.ViewStructure asyncNewChild(int, int);
+ method public abstract android.view.ViewStructure asyncNewChild(int, int, int);
method public abstract int getChildCount();
method public abstract android.os.Bundle getExtras();
method public abstract java.lang.CharSequence getHint();
@@ -45225,11 +45567,12 @@
method public abstract int getTextSelectionStart();
method public abstract boolean hasExtras();
method public abstract android.view.ViewStructure newChild(int);
- method public abstract android.view.ViewStructure newChild(int, int);
+ method public abstract android.view.ViewStructure newChild(int, int, int);
method public abstract void setAccessibilityFocused(boolean);
method public abstract void setActivated(boolean);
method public abstract void setAlpha(float);
method public abstract void setAutoFillType(android.view.autofill.AutoFillType);
+ method public abstract void setAutoFillValue(android.view.autofill.AutoFillValue);
method public abstract void setCheckable(boolean);
method public abstract void setChecked(boolean);
method public abstract void setChildCount(int);
@@ -45252,6 +45595,7 @@
method public abstract void setTextStyle(float, int, int, int);
method public abstract void setTransformation(android.graphics.Matrix);
method public abstract void setVisibility(int);
+ field public static final int AUTO_FILL_FLAG_SANITIZED = 1; // 0x1
}
public final class ViewStub extends android.view.View {
@@ -45685,6 +46029,7 @@
field public static final int TYPE_APPLICATION = 2; // 0x2
field public static final int TYPE_APPLICATION_ATTACHED_DIALOG = 1003; // 0x3eb
field public static final int TYPE_APPLICATION_MEDIA = 1001; // 0x3e9
+ field public static final int TYPE_APPLICATION_OVERLAY = 2038; // 0x7f6
field public static final int TYPE_APPLICATION_PANEL = 1000; // 0x3e8
field public static final int TYPE_APPLICATION_STARTING = 3; // 0x3
field public static final int TYPE_APPLICATION_SUB_PANEL = 1002; // 0x3ea
@@ -45694,17 +46039,17 @@
field public static final int TYPE_INPUT_METHOD = 2011; // 0x7db
field public static final int TYPE_INPUT_METHOD_DIALOG = 2012; // 0x7dc
field public static final int TYPE_KEYGUARD_DIALOG = 2009; // 0x7d9
- field public static final int TYPE_PHONE = 2002; // 0x7d2
- field public static final int TYPE_PRIORITY_PHONE = 2007; // 0x7d7
+ field public static final deprecated int TYPE_PHONE = 2002; // 0x7d2
+ field public static final deprecated int TYPE_PRIORITY_PHONE = 2007; // 0x7d7
field public static final int TYPE_PRIVATE_PRESENTATION = 2030; // 0x7ee
field public static final int TYPE_SEARCH_BAR = 2001; // 0x7d1
field public static final int TYPE_STATUS_BAR = 2000; // 0x7d0
field public static final int TYPE_STATUS_BAR_PANEL = 2014; // 0x7de
- field public static final int TYPE_SYSTEM_ALERT = 2003; // 0x7d3
+ field public static final deprecated int TYPE_SYSTEM_ALERT = 2003; // 0x7d3
field public static final int TYPE_SYSTEM_DIALOG = 2008; // 0x7d8
- field public static final int TYPE_SYSTEM_ERROR = 2010; // 0x7da
- field public static final int TYPE_SYSTEM_OVERLAY = 2006; // 0x7d6
- field public static final int TYPE_TOAST = 2005; // 0x7d5
+ field public static final deprecated int TYPE_SYSTEM_ERROR = 2010; // 0x7da
+ field public static final deprecated int TYPE_SYSTEM_OVERLAY = 2006; // 0x7d6
+ field public static final deprecated int TYPE_TOAST = 2005; // 0x7d5
field public static final int TYPE_WALLPAPER = 2013; // 0x7dd
field public float alpha;
field public float buttonBrightness;
@@ -46481,10 +46826,11 @@
}
public final class AutoFillManager {
- method public void updateAutoFillInput(android.view.View, int);
- method public void updateAutoFillInput(android.view.View, int, android.graphics.Rect, int);
- field public static final int FLAG_UPDATE_UI_HIDE = 2; // 0x2
- field public static final int FLAG_UPDATE_UI_SHOW = 1; // 0x1
+ method public void focusChanged(android.view.View, boolean);
+ method public void reset();
+ method public void valueChanged(android.view.View);
+ method public void virtualFocusChanged(android.view.View, int, android.graphics.Rect, android.view.autofill.AutoFillValue, boolean);
+ method public void virtualValueChanged(android.view.View, int, android.view.autofill.AutoFillValue);
}
public final class AutoFillType implements android.os.Parcelable {
@@ -46519,10 +46865,9 @@
}
public static final class Dataset.Builder {
- ctor public Dataset.Builder(java.lang.CharSequence);
+ ctor public Dataset.Builder(java.lang.String, java.lang.CharSequence);
method public android.view.autofill.Dataset build();
- method public android.view.autofill.Dataset.Builder requiresCustomAuthentication(android.os.Bundle, int);
- method public android.view.autofill.Dataset.Builder requiresFingerprintAuthentication(android.hardware.fingerprint.FingerprintManager.CryptoObject, android.os.Bundle, int);
+ method public android.view.autofill.Dataset.Builder setAuthentication(android.content.IntentSender);
method public android.view.autofill.Dataset.Builder setExtras(android.os.Bundle);
method public android.view.autofill.Dataset.Builder setValue(android.view.autofill.AutoFillId, android.view.autofill.AutoFillValue);
}
@@ -46534,12 +46879,11 @@
}
public static final class FillResponse.Builder {
- ctor public FillResponse.Builder();
+ ctor public FillResponse.Builder(java.lang.String);
method public android.view.autofill.FillResponse.Builder addDataset(android.view.autofill.Dataset);
method public android.view.autofill.FillResponse.Builder addSavableFields(android.view.autofill.AutoFillId...);
method public android.view.autofill.FillResponse build();
- method public android.view.autofill.FillResponse.Builder requiresCustomAuthentication(android.os.Bundle, int);
- method public android.view.autofill.FillResponse.Builder requiresFingerprintAuthentication(android.hardware.fingerprint.FingerprintManager.CryptoObject, android.os.Bundle, int);
+ method public android.view.autofill.FillResponse.Builder setAuthentication(android.content.IntentSender);
method public android.view.autofill.FillResponse.Builder setExtras(android.os.Bundle);
}
@@ -46548,13 +46892,6 @@
method public abstract void autoFill(int, android.view.autofill.AutoFillValue);
}
- public static abstract class VirtualViewDelegate.Callback {
- ctor public VirtualViewDelegate.Callback();
- method public void onAutoFillInputUpdated(int, android.graphics.Rect, int);
- method public void onNodeRemoved(int...);
- method public void onValueChanged(int);
- }
-
}
package android.view.inputmethod {
@@ -46965,7 +47302,7 @@
public final class TextClassificationManager {
method public java.util.List<android.view.textclassifier.TextLanguage> detectLanguages(java.lang.CharSequence);
- method public android.view.textclassifier.TextClassifier getDefaultTextClassifier();
+ method public synchronized android.view.textclassifier.TextClassifier getDefaultTextClassifier();
}
public final class TextClassificationResult {
@@ -50296,6 +50633,7 @@
method public void setIs24HourView(java.lang.Boolean);
method public void setMinute(int);
method public void setOnTimeChangedListener(android.widget.TimePicker.OnTimeChangedListener);
+ method public boolean validateInput();
}
public static abstract interface TimePicker.OnTimeChangedListener {
@@ -50694,6 +51032,8 @@
field public static final int OP_INVOKE_INTERFACE = 114; // 0x72
field public static final int OP_INVOKE_INTERFACE_JUMBO = 9983; // 0x26ff
field public static final int OP_INVOKE_INTERFACE_RANGE = 120; // 0x78
+ field public static final int OP_INVOKE_POLYMORPHIC = 250; // 0xfa
+ field public static final int OP_INVOKE_POLYMORPHIC_RANGE = 251; // 0xfb
field public static final int OP_INVOKE_STATIC = 113; // 0x71
field public static final int OP_INVOKE_STATIC_JUMBO = 9727; // 0x25ff
field public static final int OP_INVOKE_STATIC_RANGE = 119; // 0x77
@@ -53988,12 +54328,15 @@
}
public abstract class MethodHandle {
+ method public java.lang.invoke.MethodHandle asCollector(java.lang.Class<?>, int);
method public java.lang.invoke.MethodHandle asFixedArity();
+ method public java.lang.invoke.MethodHandle asSpreader(java.lang.Class<?>, int);
method public java.lang.invoke.MethodHandle asType(java.lang.invoke.MethodType);
method public java.lang.invoke.MethodHandle asVarargsCollector(java.lang.Class<?>);
method public java.lang.invoke.MethodHandle bindTo(java.lang.Object);
method public final java.lang.Object invoke(java.lang.Object...) throws java.lang.Throwable;
method public final java.lang.Object invokeExact(java.lang.Object...) throws java.lang.Throwable;
+ method public java.lang.Object invokeWithArguments(java.lang.Object...) throws java.lang.Throwable;
method public java.lang.Object invokeWithArguments(java.util.List<?>) throws java.lang.Throwable;
method public boolean isVarargsCollector();
method public java.lang.invoke.MethodType type();
@@ -54027,17 +54370,23 @@
method public static java.lang.invoke.MethodHandle arrayElementGetter(java.lang.Class<?>) throws java.lang.IllegalArgumentException;
method public static java.lang.invoke.MethodHandle arrayElementSetter(java.lang.Class<?>) throws java.lang.IllegalArgumentException;
method public static java.lang.invoke.MethodHandle catchException(java.lang.invoke.MethodHandle, java.lang.Class<? extends java.lang.Throwable>, java.lang.invoke.MethodHandle);
+ method public static java.lang.invoke.MethodHandle collectArguments(java.lang.invoke.MethodHandle, int, java.lang.invoke.MethodHandle);
method public static java.lang.invoke.MethodHandle constant(java.lang.Class<?>, java.lang.Object);
method public static java.lang.invoke.MethodHandle dropArguments(java.lang.invoke.MethodHandle, int, java.util.List<java.lang.Class<?>>);
method public static java.lang.invoke.MethodHandle dropArguments(java.lang.invoke.MethodHandle, int, java.lang.Class<?>...);
method public static java.lang.invoke.MethodHandle exactInvoker(java.lang.invoke.MethodType);
+ method public static java.lang.invoke.MethodHandle filterArguments(java.lang.invoke.MethodHandle, int, java.lang.invoke.MethodHandle...);
method public static java.lang.invoke.MethodHandle filterReturnValue(java.lang.invoke.MethodHandle, java.lang.invoke.MethodHandle);
+ method public static java.lang.invoke.MethodHandle foldArguments(java.lang.invoke.MethodHandle, java.lang.invoke.MethodHandle);
method public static java.lang.invoke.MethodHandle guardWithTest(java.lang.invoke.MethodHandle, java.lang.invoke.MethodHandle, java.lang.invoke.MethodHandle);
method public static java.lang.invoke.MethodHandle identity(java.lang.Class<?>);
+ method public static java.lang.invoke.MethodHandle insertArguments(java.lang.invoke.MethodHandle, int, java.lang.Object...);
method public static java.lang.invoke.MethodHandle invoker(java.lang.invoke.MethodType);
method public static java.lang.invoke.MethodHandles.Lookup lookup();
method public static java.lang.invoke.MethodHandle permuteArguments(java.lang.invoke.MethodHandle, java.lang.invoke.MethodType, int...);
method public static java.lang.invoke.MethodHandles.Lookup publicLookup();
+ method public static <T extends java.lang.reflect.Member> T reflectAs(java.lang.Class<T>, java.lang.invoke.MethodHandle);
+ method public static java.lang.invoke.MethodHandle spreadInvoker(java.lang.invoke.MethodType, int);
method public static java.lang.invoke.MethodHandle throwException(java.lang.Class<?>, java.lang.Class<? extends java.lang.Throwable>);
}
@@ -54054,6 +54403,7 @@
method public java.lang.invoke.MethodHandles.Lookup in(java.lang.Class<?>);
method public java.lang.Class<?> lookupClass();
method public int lookupModes();
+ method public java.lang.invoke.MethodHandleInfo revealDirect(java.lang.invoke.MethodHandle);
method public void throwMakeAccessException(java.lang.String, java.lang.Object) throws java.lang.IllegalAccessException;
method public java.lang.invoke.MethodHandle unreflect(java.lang.reflect.Method) throws java.lang.IllegalAccessException;
method public java.lang.invoke.MethodHandle unreflectConstructor(java.lang.reflect.Constructor<?>) throws java.lang.IllegalAccessException;
diff --git a/api/system-current.txt b/api/system-current.txt
index 73b5c35..fedae78 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -315,7 +315,6 @@
public static final class R.attr {
ctor public R.attr();
- field public static final int __removed0 = 16844097; // 0x1010541
field public static final int __removed1 = 16844099; // 0x1010543
field public static final int absListViewStyle = 16842858; // 0x101006a
field public static final int accessibilityEventTypes = 16843648; // 0x1010380
@@ -1386,6 +1385,7 @@
field public static final int targetId = 16843740; // 0x10103dc
field public static final int targetName = 16843853; // 0x101044d
field public static final int targetPackage = 16842785; // 0x1010021
+ field public static final int targetProcess = 16844097; // 0x1010541
field public static final int targetSandboxVersion = 16844110; // 0x101054e
field public static final int targetSdkVersion = 16843376; // 0x1010270
field public static final int taskAffinity = 16842770; // 0x1010012
@@ -2807,11 +2807,25 @@
package android.accessibilityservice {
+ public final class AccessibilityButtonController {
+ method public boolean isAccessibilityButtonAvailable();
+ method public void registerAccessibilityButtonCallback(android.accessibilityservice.AccessibilityButtonController.AccessibilityButtonCallback);
+ method public void registerAccessibilityButtonCallback(android.accessibilityservice.AccessibilityButtonController.AccessibilityButtonCallback, android.os.Handler);
+ method public void unregisterAccessibilityButtonCallback(android.accessibilityservice.AccessibilityButtonController.AccessibilityButtonCallback);
+ }
+
+ public static abstract class AccessibilityButtonController.AccessibilityButtonCallback {
+ ctor public AccessibilityButtonController.AccessibilityButtonCallback();
+ method public void onAvailabilityChanged(android.accessibilityservice.AccessibilityButtonController, boolean);
+ method public void onClicked(android.accessibilityservice.AccessibilityButtonController);
+ }
+
public abstract class AccessibilityService extends android.app.Service {
ctor public AccessibilityService();
method public final void disableSelf();
method public final boolean dispatchGesture(android.accessibilityservice.GestureDescription, android.accessibilityservice.AccessibilityService.GestureResultCallback, android.os.Handler);
method public android.view.accessibility.AccessibilityNodeInfo findFocus(int);
+ method public final android.accessibilityservice.AccessibilityButtonController getAccessibilityButtonController();
method public final android.accessibilityservice.FingerprintGestureController getFingerprintGestureController();
method public final android.accessibilityservice.AccessibilityService.MagnificationController getMagnificationController();
method public android.view.accessibility.AccessibilityNodeInfo getRootInActiveWindow();
@@ -2924,6 +2938,7 @@
field public static final int FLAG_ENABLE_ACCESSIBILITY_VOLUME = 128; // 0x80
field public static final int FLAG_INCLUDE_NOT_IMPORTANT_VIEWS = 2; // 0x2
field public static final int FLAG_REPORT_VIEW_IDS = 16; // 0x10
+ field public static final int FLAG_REQUEST_ACCESSIBILITY_BUTTON = 256; // 0x100
field public static final int FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY = 8; // 0x8
field public static final int FLAG_REQUEST_FILTER_KEY_EVENTS = 32; // 0x20
field public static final int FLAG_REQUEST_TOUCH_EXPLORATION_MODE = 4; // 0x4
@@ -3028,7 +3043,7 @@
public class AccountManager {
method public android.accounts.AccountManagerFuture<android.os.Bundle> addAccount(java.lang.String, java.lang.String, java.lang.String[], android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
method public boolean addAccountExplicitly(android.accounts.Account, java.lang.String, android.os.Bundle);
- method public boolean addAccountExplicitly(android.accounts.Account, java.lang.String, android.os.Bundle, java.util.Map<java.lang.Integer, java.lang.Integer>);
+ method public boolean addAccountExplicitly(android.accounts.Account, java.lang.String, android.os.Bundle, java.util.Map<java.lang.String, java.lang.Integer>);
method public void addOnAccountsUpdatedListener(android.accounts.OnAccountsUpdateListener, android.os.Handler, boolean);
method public void addOnAccountsUpdatedListener(android.accounts.OnAccountsUpdateListener, android.os.Handler, boolean, java.lang.String[]);
method public java.lang.String blockingGetAuthToken(android.accounts.Account, java.lang.String, boolean) throws android.accounts.AuthenticatorException, java.io.IOException, android.accounts.OperationCanceledException;
@@ -3038,7 +3053,7 @@
method public android.accounts.AccountManagerFuture<android.os.Bundle> finishSession(android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
method public android.accounts.AccountManagerFuture<android.os.Bundle> finishSessionAsUser(android.os.Bundle, android.app.Activity, android.os.UserHandle, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
method public static android.accounts.AccountManager get(android.content.Context);
- method public int getAccountVisibility(android.accounts.Account, int);
+ method public int getAccountVisibility(android.accounts.Account, java.lang.String);
method public android.accounts.Account[] getAccounts();
method public java.util.Map<android.accounts.Account, java.lang.Integer> getAccountsAndVisibilityForPackage(java.lang.String, java.lang.String);
method public android.accounts.Account[] getAccountsByType(java.lang.String);
@@ -3049,9 +3064,9 @@
method public android.accounts.AccountManagerFuture<android.os.Bundle> getAuthToken(android.accounts.Account, java.lang.String, android.os.Bundle, boolean, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
method public android.accounts.AccountManagerFuture<android.os.Bundle> getAuthTokenByFeatures(java.lang.String, java.lang.String, java.lang.String[], android.app.Activity, android.os.Bundle, android.os.Bundle, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
method public android.accounts.AuthenticatorDescription[] getAuthenticatorTypes();
+ method public java.util.Map<java.lang.String, java.lang.Integer> getPackagesAndVisibilityForAccount(android.accounts.Account);
method public java.lang.String getPassword(android.accounts.Account);
method public java.lang.String getPreviousName(android.accounts.Account);
- method public java.util.Map<java.lang.Integer, java.lang.Integer> getUidsAndVisibilityForAccount(android.accounts.Account);
method public java.lang.String getUserData(android.accounts.Account, java.lang.String);
method public android.accounts.AccountManagerFuture<java.lang.Boolean> hasFeatures(android.accounts.Account, java.lang.String[], android.accounts.AccountManagerCallback<java.lang.Boolean>, android.os.Handler);
method public void invalidateAuthToken(java.lang.String, java.lang.String);
@@ -3065,7 +3080,7 @@
method public boolean removeAccountExplicitly(android.accounts.Account);
method public void removeOnAccountsUpdatedListener(android.accounts.OnAccountsUpdateListener);
method public android.accounts.AccountManagerFuture<android.accounts.Account> renameAccount(android.accounts.Account, java.lang.String, android.accounts.AccountManagerCallback<android.accounts.Account>, android.os.Handler);
- method public boolean setAccountVisibility(android.accounts.Account, int, int);
+ method public boolean setAccountVisibility(android.accounts.Account, java.lang.String, int);
method public void setAuthToken(android.accounts.Account, java.lang.String, java.lang.String);
method public void setPassword(android.accounts.Account, java.lang.String);
method public void setUserData(android.accounts.Account, java.lang.String, java.lang.String);
@@ -3105,8 +3120,8 @@
field public static final java.lang.String KEY_PASSWORD = "password";
field public static final java.lang.String KEY_USERDATA = "userdata";
field public static final deprecated java.lang.String LOGIN_ACCOUNTS_CHANGED_ACTION = "android.accounts.LOGIN_ACCOUNTS_CHANGED";
- field public static final int UID_KEY_DEFAULT_LEGACY_VISIBILITY = -3; // 0xfffffffd
- field public static final int UID_KEY_DEFAULT_VISIBILITY = -2; // 0xfffffffe
+ field public static final java.lang.String PACKAGE_NAME_KEY_LEGACY_NOT_VISIBLE = "android.accounts.key_legacy_not_visible";
+ field public static final java.lang.String PACKAGE_NAME_KEY_LEGACY_VISIBLE = "android.accounts.key_legacy_visible";
field public static final int VISIBILITY_NOT_VISIBLE = 3; // 0x3
field public static final int VISIBILITY_UNDEFINED = 0; // 0x0
field public static final int VISIBILITY_USER_MANAGED_NOT_VISIBLE = 4; // 0x4
@@ -4313,7 +4328,6 @@
method public abstract void onActivityCreated(android.app.Activity, android.os.Bundle);
method public abstract void onActivityDestroyed(android.app.Activity);
method public abstract void onActivityPaused(android.app.Activity);
- method public default void onActivityPreCreated(android.app.Activity, android.os.Bundle);
method public abstract void onActivityResumed(android.app.Activity);
method public abstract void onActivitySaveInstanceState(android.app.Activity, android.os.Bundle);
method public abstract void onActivityStarted(android.app.Activity);
@@ -4965,6 +4979,7 @@
method public void addMonitor(android.app.Instrumentation.ActivityMonitor);
method public android.app.Instrumentation.ActivityMonitor addMonitor(android.content.IntentFilter, android.app.Instrumentation.ActivityResult, boolean);
method public android.app.Instrumentation.ActivityMonitor addMonitor(java.lang.String, android.app.Instrumentation.ActivityResult, boolean);
+ method public void addResults(android.os.Bundle);
method public void callActivityOnCreate(android.app.Activity, android.os.Bundle);
method public void callActivityOnCreate(android.app.Activity, android.os.Bundle, android.os.PersistableBundle);
method public void callActivityOnDestroy(android.app.Activity);
@@ -4989,6 +5004,7 @@
method public android.os.Bundle getBinderCounts();
method public android.content.ComponentName getComponentName();
method public android.content.Context getContext();
+ method public java.lang.String getProcessName();
method public android.content.Context getTargetContext();
method public android.app.UiAutomation getUiAutomation();
method public android.app.UiAutomation getUiAutomation(int);
@@ -5205,15 +5221,20 @@
ctor public Notification(android.os.Parcel);
method public android.app.Notification clone();
method public int describeContents();
+ method public int getBadgeIcon();
method public java.lang.String getChannel();
method public java.lang.String getGroup();
method public android.graphics.drawable.Icon getLargeIcon();
method public static java.lang.Class<? extends android.app.Notification.Style> getNotificationStyleClass(java.lang.String);
+ method public java.lang.String getShortcutId();
method public android.graphics.drawable.Icon getSmallIcon();
method public java.lang.String getSortKey();
method public long getTimeout();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.media.AudioAttributes AUDIO_ATTRIBUTES_DEFAULT;
+ field public static final int BADGE_ICON_LARGE = 2; // 0x2
+ field public static final int BADGE_ICON_NONE = 0; // 0x0
+ field public static final int BADGE_ICON_SMALL = 1; // 0x1
field public static final java.lang.String CATEGORY_ALARM = "alarm";
field public static final java.lang.String CATEGORY_CALL = "call";
field public static final java.lang.String CATEGORY_EMAIL = "email";
@@ -5307,7 +5328,7 @@
field public deprecated int ledARGB;
field public deprecated int ledOffMS;
field public deprecated int ledOnMS;
- field public deprecated int number;
+ field public int number;
field public deprecated int priority;
field public android.app.Notification publicVersion;
field public deprecated android.net.Uri sound;
@@ -5395,6 +5416,7 @@
method public android.app.Notification.Builder addExtras(android.os.Bundle);
method public android.app.Notification.Builder addPerson(java.lang.String);
method public android.app.Notification build();
+ method public android.app.Notification.Builder chooseBadgeIcon(int);
method public android.widget.RemoteViews createBigContentView();
method public android.widget.RemoteViews createContentView();
method public android.widget.RemoteViews createHeadsUpContentView();
@@ -5427,13 +5449,14 @@
method public android.app.Notification.Builder setLargeIcon(android.graphics.drawable.Icon);
method public deprecated android.app.Notification.Builder setLights(int, int, int);
method public android.app.Notification.Builder setLocalOnly(boolean);
- method public deprecated android.app.Notification.Builder setNumber(int);
+ method public android.app.Notification.Builder setNumber(int);
method public android.app.Notification.Builder setOngoing(boolean);
method public android.app.Notification.Builder setOnlyAlertOnce(boolean);
method public deprecated android.app.Notification.Builder setPriority(int);
method public android.app.Notification.Builder setProgress(int, int, boolean);
method public android.app.Notification.Builder setPublicVersion(android.app.Notification);
method public android.app.Notification.Builder setRemoteInputHistory(java.lang.CharSequence[]);
+ method public android.app.Notification.Builder setShortcutId(java.lang.String);
method public android.app.Notification.Builder setShowWhen(boolean);
method public android.app.Notification.Builder setSmallIcon(int);
method public android.app.Notification.Builder setSmallIcon(int, int);
@@ -6203,6 +6226,10 @@
method public void onDetached();
}
+ public class VrManager {
+ method public void setPersistentVrModeEnabled(boolean);
+ }
+
public final class WallpaperInfo implements android.os.Parcelable {
ctor public WallpaperInfo(android.content.Context, android.content.pm.ResolveInfo) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
method public int describeContents();
@@ -6401,6 +6428,7 @@
method public java.lang.CharSequence getDeviceOwnerOrganizationName();
method public java.util.List<byte[]> getInstalledCaCerts(android.content.ComponentName);
method public int getKeyguardDisabledFeatures(android.content.ComponentName);
+ method public java.lang.String[] getLockTaskPackages(android.content.ComponentName);
method public java.lang.CharSequence getLongSupportMessage(android.content.ComponentName);
method public int getMaximumFailedPasswordsForWipe(android.content.ComponentName);
method public long getMaximumTimeToLock(android.content.ComponentName);
@@ -6742,6 +6770,7 @@
method public float getAlpha();
method public android.view.autofill.AutoFillId getAutoFillId();
method public android.view.autofill.AutoFillType getAutoFillType();
+ method public android.view.autofill.AutoFillValue getAutoFillValue();
method public android.app.assist.AssistStructure.ViewNode getChildAt(int);
method public int getChildCount();
method public java.lang.String getClassName();
@@ -8327,6 +8356,65 @@
}
+package android.companion {
+
+ public final class AssociationRequest<F extends android.companion.DeviceFilter> implements android.os.Parcelable {
+ method public int describeContents();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.companion.AssociationRequest> CREATOR;
+ }
+
+ public static final class AssociationRequest.Builder<F extends android.companion.DeviceFilter> {
+ method public android.companion.AssociationRequest<F> build();
+ method public static android.companion.AssociationRequest.Builder<android.companion.BluetoothDeviceFilter> createForBluetoothDevice();
+ method public static android.companion.AssociationRequest.Builder<android.companion.BluetoothLEDeviceFilter> createForBluetoothLEDevice();
+ method public android.companion.AssociationRequest.Builder<F> setDeviceFilter(F);
+ method public android.companion.AssociationRequest.Builder<F> setSingleDevice(boolean);
+ }
+
+ public final class BluetoothDeviceFilter implements android.companion.DeviceFilter {
+ method public int describeContents();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.companion.BluetoothDeviceFilter> CREATOR;
+ }
+
+ public static final class BluetoothDeviceFilter.Builder {
+ ctor public BluetoothDeviceFilter.Builder();
+ method public android.companion.BluetoothDeviceFilter.Builder addServiceUuid(android.os.ParcelUuid, android.os.ParcelUuid);
+ method public android.companion.BluetoothDeviceFilter build();
+ method public android.companion.BluetoothDeviceFilter.Builder setAddress(java.lang.String);
+ method public android.companion.BluetoothDeviceFilter.Builder setNamePattern(java.util.regex.Pattern);
+ }
+
+ public final class BluetoothLEDeviceFilter implements android.companion.DeviceFilter {
+ method public int describeContents();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.companion.BluetoothLEDeviceFilter> CREATOR;
+ }
+
+ public static final class BluetoothLEDeviceFilter.Builder {
+ ctor public BluetoothLEDeviceFilter.Builder();
+ method public android.companion.BluetoothLEDeviceFilter build();
+ method public android.companion.BluetoothLEDeviceFilter.Builder setNamePattern(java.util.regex.Pattern);
+ method public android.companion.BluetoothLEDeviceFilter.Builder setScanFilter(android.bluetooth.le.ScanFilter);
+ }
+
+ public final class CompanionDeviceManager {
+ method public void associate(android.companion.AssociationRequest<?>, android.companion.CompanionDeviceManager.Callback, android.os.Handler);
+ field public static final java.lang.String EXTRA_DEVICE = "android.companion.extra.DEVICE";
+ }
+
+ public static abstract class CompanionDeviceManager.Callback {
+ ctor public CompanionDeviceManager.Callback();
+ method public abstract void onDeviceFound(android.content.IntentSender);
+ method public abstract void onFailure(java.lang.CharSequence);
+ }
+
+ public abstract interface DeviceFilter<D extends android.os.Parcelable> implements android.os.Parcelable {
+ }
+
+}
+
package android.content {
public abstract class AbstractThreadedSyncAdapter {
@@ -8946,6 +9034,7 @@
field public static final java.lang.String CAPTIONING_SERVICE = "captioning";
field public static final java.lang.String CARRIER_CONFIG_SERVICE = "carrier_config";
field public static final java.lang.String CLIPBOARD_SERVICE = "clipboard";
+ field public static final java.lang.String COMPANION_DEVICE_SERVICE = "companion_device";
field public static final java.lang.String CONNECTIVITY_SERVICE = "connectivity";
field public static final java.lang.String CONSUMER_IR_SERVICE = "consumer_ir";
field public static final java.lang.String CONTEXTHUB_SERVICE = "contexthub";
@@ -9004,6 +9093,7 @@
field public static final java.lang.String USB_SERVICE = "usb";
field public static final java.lang.String USER_SERVICE = "user";
field public static final java.lang.String VIBRATOR_SERVICE = "vibrator";
+ field public static final java.lang.String VR_SERVICE = "vrmanager";
field public static final java.lang.String WALLPAPER_SERVICE = "wallpaper";
field public static final java.lang.String WIFI_AWARE_SERVICE = "wifiaware";
field public static final java.lang.String WIFI_P2P_SERVICE = "wifip2p";
@@ -9502,6 +9592,10 @@
field public static final java.lang.String EXTRA_ASSIST_INPUT_HINT_KEYBOARD = "android.intent.extra.ASSIST_INPUT_HINT_KEYBOARD";
field public static final java.lang.String EXTRA_ASSIST_PACKAGE = "android.intent.extra.ASSIST_PACKAGE";
field public static final java.lang.String EXTRA_ASSIST_UID = "android.intent.extra.ASSIST_UID";
+ field public static final java.lang.String EXTRA_AUTO_FILL_ASSIST_STRUCTURE = "android.intent.extra.AUTO_FILL_ASSIST_STRUCTURE";
+ field public static final java.lang.String EXTRA_AUTO_FILL_CALLBACK = "android.intent.extra.AUTO_FILL_CALLBACK";
+ field public static final java.lang.String EXTRA_AUTO_FILL_EXTRAS = "android.intent.extra.AUTO_FILL_EXTRAS";
+ field public static final java.lang.String EXTRA_AUTO_FILL_ITEM_ID = "android.intent.extra.AUTO_FILL_ITEM_ID";
field public static final java.lang.String EXTRA_BCC = "android.intent.extra.BCC";
field public static final java.lang.String EXTRA_BUG_REPORT = "android.intent.extra.BUG_REPORT";
field public static final java.lang.String EXTRA_CC = "android.intent.extra.CC";
@@ -9542,6 +9636,7 @@
field public static final java.lang.String EXTRA_PHONE_NUMBER = "android.intent.extra.PHONE_NUMBER";
field public static final java.lang.String EXTRA_PROCESS_TEXT = "android.intent.extra.PROCESS_TEXT";
field public static final java.lang.String EXTRA_PROCESS_TEXT_READONLY = "android.intent.extra.PROCESS_TEXT_READONLY";
+ field public static final java.lang.String EXTRA_QUICK_VIEW_PLAIN = "android.intent.extra.QUICK_VIEW_PLAIN";
field public static final java.lang.String EXTRA_QUIET_MODE = "android.intent.extra.QUIET_MODE";
field public static final java.lang.String EXTRA_REFERRER = "android.intent.extra.REFERRER";
field public static final java.lang.String EXTRA_REFERRER_NAME = "android.intent.extra.REFERRER_NAME";
@@ -10357,6 +10452,7 @@
field public java.lang.String[] splitPublicSourceDirs;
field public java.lang.String[] splitSourceDirs;
field public java.lang.String targetPackage;
+ field public java.lang.String targetProcess;
}
public final class IntentFilterVerificationInfo implements android.os.Parcelable {
@@ -10811,6 +10907,7 @@
field public static final java.lang.String FEATURE_VERIFIED_BOOT = "android.software.verified_boot";
field public static final java.lang.String FEATURE_VR_MODE = "android.software.vr.mode";
field public static final java.lang.String FEATURE_VR_MODE_HIGH_PERFORMANCE = "android.hardware.vr.high_performance";
+ field public static final java.lang.String FEATURE_VULKAN_HARDWARE_COMPUTE = "android.hardware.vulkan.compute";
field public static final java.lang.String FEATURE_VULKAN_HARDWARE_LEVEL = "android.hardware.vulkan.level";
field public static final java.lang.String FEATURE_VULKAN_HARDWARE_VERSION = "android.hardware.vulkan.version";
field public static final java.lang.String FEATURE_WATCH = "android.hardware.type.watch";
@@ -21995,6 +22092,7 @@
method public int getContentType();
method public int getFlags();
method public int getUsage();
+ method public static int getVolumeControlStream(android.media.AudioAttributes);
method public void writeToParcel(android.os.Parcel, int);
field public static final int CONTENT_TYPE_MOVIE = 3; // 0x3
field public static final int CONTENT_TYPE_MUSIC = 2; // 0x2
@@ -23767,6 +23865,7 @@
}
public static final class MediaMuxer.OutputFormat {
+ field public static final int MUXER_OUTPUT_3GPP = 2; // 0x2
field public static final int MUXER_OUTPUT_MPEG_4 = 0; // 0x0
field public static final int MUXER_OUTPUT_WEBM = 1; // 0x1
}
@@ -25270,6 +25369,8 @@
public final class MediaController {
ctor public MediaController(android.content.Context, android.media.session.MediaSession.Token);
+ method public void addQueueItem(android.media.MediaDescription);
+ method public void addQueueItem(android.media.MediaDescription, int);
method public void adjustVolume(int, int);
method public boolean dispatchMediaButtonEvent(android.view.KeyEvent);
method public android.os.Bundle getExtras();
@@ -25288,6 +25389,8 @@
method public boolean isShuffleModeEnabled();
method public void registerCallback(android.media.session.MediaController.Callback);
method public void registerCallback(android.media.session.MediaController.Callback, android.os.Handler);
+ method public void removeQueueItem(android.media.MediaDescription);
+ method public void removeQueueItemAt(int);
method public void sendCommand(java.lang.String, android.os.Bundle, android.os.ResultReceiver);
method public void setVolumeTo(int, int);
method public void unregisterCallback(android.media.session.MediaController.Callback);
@@ -25365,11 +25468,14 @@
method public void setSessionActivity(android.app.PendingIntent);
method public void setShuffleModeEnabled(boolean);
field public static final int FLAG_HANDLES_MEDIA_BUTTONS = 1; // 0x1
+ field public static final int FLAG_HANDLES_QUEUE_COMMANDS = 4; // 0x4
field public static final int FLAG_HANDLES_TRANSPORT_CONTROLS = 2; // 0x2
}
public static abstract class MediaSession.Callback {
ctor public MediaSession.Callback();
+ method public void onAddQueueItem(android.media.MediaDescription);
+ method public void onAddQueueItem(android.media.MediaDescription, int);
method public void onCommand(java.lang.String, android.os.Bundle, android.os.ResultReceiver);
method public void onCustomAction(java.lang.String, android.os.Bundle);
method public void onFastForward();
@@ -25383,6 +25489,8 @@
method public void onPrepareFromMediaId(java.lang.String, android.os.Bundle);
method public void onPrepareFromSearch(java.lang.String, android.os.Bundle);
method public void onPrepareFromUri(android.net.Uri, android.os.Bundle);
+ method public void onRemoveQueueItem(android.media.MediaDescription);
+ method public void onRemoveQueueItemAt(int);
method public void onRewind();
method public void onSeekTo(long);
method public void onSetRating(android.media.Rating);
@@ -25626,6 +25734,7 @@
field public static final java.lang.String COLUMN_SEARCHABLE = "searchable";
field public static final java.lang.String COLUMN_SERVICE_ID = "service_id";
field public static final java.lang.String COLUMN_SERVICE_TYPE = "service_type";
+ field public static final java.lang.String COLUMN_SYSTEM_APPROVED = "system_approved";
field public static final java.lang.String COLUMN_TRANSIENT = "transient";
field public static final java.lang.String COLUMN_TRANSPORT_STREAM_ID = "transport_stream_id";
field public static final java.lang.String COLUMN_TYPE = "type";
@@ -25692,6 +25801,7 @@
field public static final java.lang.String AVAILABILITY_AVAILABLE = "AVAILABILITY_AVAILABLE";
field public static final java.lang.String AVAILABILITY_FREE_WITH_SUBSCRIPTION = "AVAILABILITY_FREE_WITH_SUBSCRIPTION";
field public static final java.lang.String AVAILABILITY_PAID_CONTENT = "AVAILABILITY_PAID_CONTENT";
+ field public static final java.lang.String COLUMN_APP_LINK_INTENT_URI = "app_link_intent_uri";
field public static final java.lang.String COLUMN_AUDIO_LANGUAGE = "audio_language";
field public static final java.lang.String COLUMN_AUTHOR = "author";
field public static final java.lang.String COLUMN_AVAILABILITY = "availability";
@@ -25699,6 +25809,7 @@
field public static final java.lang.String COLUMN_CANONICAL_GENRE = "canonical_genre";
field public static final java.lang.String COLUMN_CHANNEL_ID = "channel_id";
field public static final java.lang.String COLUMN_CONTENT_RATING = "content_rating";
+ field public static final java.lang.String COLUMN_DURATION_MILLIS = "duration_millis";
field public static final java.lang.String COLUMN_END_TIME_UTC_MILLIS = "end_time_utc_millis";
field public static final java.lang.String COLUMN_EPISODE_DISPLAY_NUMBER = "episode_display_number";
field public static final deprecated java.lang.String COLUMN_EPISODE_NUMBER = "episode_number";
@@ -25712,17 +25823,14 @@
field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG4 = "internal_provider_flag4";
field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_ID = "internal_provider_id";
field public static final java.lang.String COLUMN_ITEM_COUNT = "item_count";
+ field public static final java.lang.String COLUMN_LAST_PLAYBACK_POSITION_MILLIS = "last_playback_position_millis";
field public static final java.lang.String COLUMN_LIVE = "live";
- field public static final java.lang.String COLUMN_LOGO = "logo";
+ field public static final java.lang.String COLUMN_LOGO_URI = "logo_uri";
field public static final java.lang.String COLUMN_LONG_DESCRIPTION = "long_description";
field public static final java.lang.String COLUMN_OFFER_PRICE = "offer_price";
field public static final java.lang.String COLUMN_POSTER_ART_ASPECT_RATIO = "poster_art_aspect_ratio";
field public static final java.lang.String COLUMN_POSTER_ART_URI = "poster_art_uri";
- field public static final java.lang.String COLUMN_PREVIEW_DURATION = "preview_duration";
- field public static final java.lang.String COLUMN_PREVIEW_INTENT_URI = "preview_intent_uri";
- field public static final java.lang.String COLUMN_PREVIEW_LAST_PLAYBACK_POSITION = "preview_last_playback_position";
field public static final java.lang.String COLUMN_PREVIEW_VIDEO_URI = "preview_video_uri";
- field public static final java.lang.String COLUMN_PREVIEW_WEIGHT = "preview_weight";
field public static final java.lang.String COLUMN_RECORDING_PROHIBITED = "recording_prohibited";
field public static final java.lang.String COLUMN_RELEASE_DATE = "release_date";
field public static final java.lang.String COLUMN_REVIEW_RATING = "review_rating";
@@ -25743,6 +25851,7 @@
field public static final java.lang.String COLUMN_VIDEO_HEIGHT = "video_height";
field public static final java.lang.String COLUMN_VIDEO_WIDTH = "video_width";
field public static final java.lang.String COLUMN_WATCH_NEXT_TYPE = "watch_next_type";
+ field public static final java.lang.String COLUMN_WEIGHT = "weight";
field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/program";
field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/program";
field public static final android.net.Uri CONTENT_URI;
@@ -28251,6 +28360,7 @@
public class WifiManager {
method public int addNetwork(android.net.wifi.WifiConfiguration);
+ method public boolean addOrUpdatePasspointConfiguration(android.net.wifi.hotspot2.PasspointConfiguration);
method public static int calculateSignalLevel(int, int);
method public void cancelWps(android.net.wifi.WifiManager.WpsCallback);
method public static int compareSignalLevel(int, int);
@@ -28266,6 +28376,7 @@
method public android.net.wifi.WifiInfo getConnectionInfo();
method public android.net.wifi.WifiConnectionStatistics getConnectionStatistics();
method public android.net.DhcpInfo getDhcpInfo();
+ method public java.util.List<android.net.wifi.hotspot2.PasspointConfiguration> getPasspointConfigurations();
method public java.util.List<android.net.wifi.WifiConfiguration> getPrivilegedConfiguredNetworks();
method public java.util.List<android.net.wifi.ScanResult> getScanResults();
method public android.net.wifi.WifiConfiguration getWifiApConfiguration();
@@ -28289,6 +28400,7 @@
method public boolean reassociate();
method public boolean reconnect();
method public boolean removeNetwork(int);
+ method public boolean removePasspointConfiguration(java.lang.String);
method public boolean saveConfiguration();
method public void setTdlsEnabled(java.net.InetAddress, boolean);
method public void setTdlsEnabledWithMacAddress(java.lang.String, boolean);
@@ -28672,6 +28784,241 @@
}
+package android.net.wifi.hotspot2 {
+
+ public final class ConfigParser {
+ method public static android.net.wifi.hotspot2.PasspointConfiguration parsePasspointConfig(java.lang.String, byte[]);
+ }
+
+ public final class PasspointConfiguration implements android.os.Parcelable {
+ ctor public PasspointConfiguration();
+ ctor public PasspointConfiguration(android.net.wifi.hotspot2.PasspointConfiguration);
+ method public int describeContents();
+ method public android.net.wifi.hotspot2.pps.Credential getCredential();
+ method public int getCredentialPriority();
+ method public android.net.wifi.hotspot2.pps.HomeSp getHomeSp();
+ method public android.net.wifi.hotspot2.pps.Policy getPolicy();
+ method public long getSubscriptionCreationTimeInMs();
+ method public long getSubscriptionExpirationTimeInMs();
+ method public java.lang.String getSubscriptionType();
+ method public android.net.wifi.hotspot2.pps.UpdateParameter getSubscriptionUpdate();
+ method public java.util.Map<java.lang.String, byte[]> getTrustRootCertList();
+ method public int getUpdateIdentififer();
+ method public long getUsageLimitDataLimit();
+ method public long getUsageLimitStartTimeInMs();
+ method public long getUsageLimitTimeLimitInMinutes();
+ method public long getUsageLimitUsageTimePeriodInMinutes();
+ method public void setCredential(android.net.wifi.hotspot2.pps.Credential);
+ method public void setCredentialPriority(int);
+ method public void setHomeSp(android.net.wifi.hotspot2.pps.HomeSp);
+ method public void setPolicy(android.net.wifi.hotspot2.pps.Policy);
+ method public void setSubscriptionCreationTimeInMs(long);
+ method public void setSubscriptionExpirationTimeInMs(long);
+ method public void setSubscriptionType(java.lang.String);
+ method public void setSubscriptionUpdate(android.net.wifi.hotspot2.pps.UpdateParameter);
+ method public void setTrustRootCertList(java.util.Map<java.lang.String, byte[]>);
+ method public void setUpdateIdentifier(int);
+ method public void setUsageLimitDataLimit(long);
+ method public void setUsageLimitStartTimeInMs(long);
+ method public void setUsageLimitTimeLimitInMinutes(long);
+ method public void setUsageLimitUsageTimePeriodInMinutes(long);
+ method public boolean validate();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.PasspointConfiguration> CREATOR;
+ }
+
+}
+
+package android.net.wifi.hotspot2.omadm {
+
+ public final class PpsMoParser {
+ method public static android.net.wifi.hotspot2.PasspointConfiguration parseMoText(java.lang.String);
+ }
+
+}
+
+package android.net.wifi.hotspot2.pps {
+
+ public final class Credential implements android.os.Parcelable {
+ ctor public Credential();
+ ctor public Credential(android.net.wifi.hotspot2.pps.Credential);
+ method public int describeContents();
+ method public java.security.cert.X509Certificate getCaCertificate();
+ method public android.net.wifi.hotspot2.pps.Credential.CertificateCredential getCertCredential();
+ method public boolean getCheckAaaServerStatus();
+ method public java.security.cert.X509Certificate[] getClientCertificateChain();
+ method public java.security.PrivateKey getClientPrivateKey();
+ method public long getCreationTimeInMs();
+ method public long getExpirationTimeInMs();
+ method public java.lang.String getRealm();
+ method public android.net.wifi.hotspot2.pps.Credential.SimCredential getSimCredential();
+ method public android.net.wifi.hotspot2.pps.Credential.UserCredential getUserCredential();
+ method public void setCaCertificate(java.security.cert.X509Certificate);
+ method public void setCertCredential(android.net.wifi.hotspot2.pps.Credential.CertificateCredential);
+ method public void setCheckAaaServerCertStatus(boolean);
+ method public void setClientCertificateChain(java.security.cert.X509Certificate[]);
+ method public void setClientPrivateKey(java.security.PrivateKey);
+ method public void setCreationTimeInMs(long);
+ method public void setExpirationTimeInMs(long);
+ method public void setRealm(java.lang.String);
+ method public void setSimCredential(android.net.wifi.hotspot2.pps.Credential.SimCredential);
+ method public void setUserCredential(android.net.wifi.hotspot2.pps.Credential.UserCredential);
+ method public boolean validate();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.Credential> CREATOR;
+ }
+
+ public static final class Credential.CertificateCredential implements android.os.Parcelable {
+ ctor public Credential.CertificateCredential();
+ ctor public Credential.CertificateCredential(android.net.wifi.hotspot2.pps.Credential.CertificateCredential);
+ method public int describeContents();
+ method public byte[] getCertSha256Fingerprint();
+ method public java.lang.String getCertType();
+ method public void setCertSha256Fingerprint(byte[]);
+ method public void setCertType(java.lang.String);
+ method public boolean validate();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.Credential.CertificateCredential> CREATOR;
+ }
+
+ public static final class Credential.SimCredential implements android.os.Parcelable {
+ ctor public Credential.SimCredential();
+ ctor public Credential.SimCredential(android.net.wifi.hotspot2.pps.Credential.SimCredential);
+ method public int describeContents();
+ method public int getEapType();
+ method public java.lang.String getImsi();
+ method public void setEapType(int);
+ method public void setImsi(java.lang.String);
+ method public boolean validate();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.Credential.SimCredential> CREATOR;
+ }
+
+ public static final class Credential.UserCredential implements android.os.Parcelable {
+ ctor public Credential.UserCredential();
+ ctor public Credential.UserCredential(android.net.wifi.hotspot2.pps.Credential.UserCredential);
+ method public int describeContents();
+ method public boolean getAbleToShare();
+ method public int getEapType();
+ method public boolean getMachineManaged();
+ method public java.lang.String getNonEapInnerMethod();
+ method public java.lang.String getPassword();
+ method public java.lang.String getSoftTokenApp();
+ method public java.lang.String getUsername();
+ method public void setAbleToShare(boolean);
+ method public void setEapType(int);
+ method public void setMachineManaged(boolean);
+ method public void setNonEapInnerMethod(java.lang.String);
+ method public void setPassword(java.lang.String);
+ method public void setSoftTokenApp(java.lang.String);
+ method public void setUsername(java.lang.String);
+ method public boolean validate();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.Credential.UserCredential> CREATOR;
+ }
+
+ public final class HomeSp implements android.os.Parcelable {
+ ctor public HomeSp();
+ ctor public HomeSp(android.net.wifi.hotspot2.pps.HomeSp);
+ method public int describeContents();
+ method public java.lang.String getFqdn();
+ method public java.lang.String getFriendlyName();
+ method public java.util.Map<java.lang.String, java.lang.Long> getHomeNetworkIds();
+ method public java.lang.String getIconUrl();
+ method public long[] getMatchAllOis();
+ method public long[] getMatchAnysOis();
+ method public java.lang.String[] getOtherHomePartners();
+ method public long[] getRoamingConsortiumOis();
+ method public void setFqdn(java.lang.String);
+ method public void setFriendlyName(java.lang.String);
+ method public void setHomeNetworkIds(java.util.Map<java.lang.String, java.lang.Long>);
+ method public void setIconUrl(java.lang.String);
+ method public void setMatchAllOis(long[]);
+ method public void setMatchAnyOis(long[]);
+ method public void setOtherHomePartners(java.lang.String[]);
+ method public void setRoamingConsortiumOis(long[]);
+ method public boolean validate();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.HomeSp> CREATOR;
+ }
+
+ public final class Policy implements android.os.Parcelable {
+ ctor public Policy();
+ ctor public Policy(android.net.wifi.hotspot2.pps.Policy);
+ method public int describeContents();
+ method public java.lang.String[] getExcludedSsidList();
+ method public int getMaximumBssLoadValue();
+ method public long getMinHomeDownlinkBandWidht();
+ method public long getMinHomeUplinkBandwidth();
+ method public long getMinRoamingDownlinkBandwidth();
+ method public long getMinRoamingUplinkBandwidth();
+ method public android.net.wifi.hotspot2.pps.UpdateParameter getPolicyUpdate();
+ method public java.util.List<android.net.wifi.hotspot2.pps.Policy.RoamingPartner> getPreferredRoamingPartnerList();
+ method public java.util.Map<java.lang.Integer, java.lang.String> getRequiredProtoPortMap();
+ method public void setExcludedSsidList(java.lang.String[]);
+ method public void setMaximumBssLoadValue(int);
+ method public void setMinHomeDownlinkBandwidth(long);
+ method public void setMinHomeUplinkBandwidth(long);
+ method public void setMinRoamingDownlinkBandwidth(long);
+ method public void setMinRoamingUplinkBandwidth(long);
+ method public void setPolicyUpdate(android.net.wifi.hotspot2.pps.UpdateParameter);
+ method public void setPreferredRoamingPartnerList(java.util.List<android.net.wifi.hotspot2.pps.Policy.RoamingPartner>);
+ method public void setRequiredProtoPortMap(java.util.Map<java.lang.Integer, java.lang.String>);
+ method public boolean validate();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.Policy> CREATOR;
+ }
+
+ public static final class Policy.RoamingPartner implements android.os.Parcelable {
+ ctor public Policy.RoamingPartner();
+ ctor public Policy.RoamingPartner(android.net.wifi.hotspot2.pps.Policy.RoamingPartner);
+ method public int describeContents();
+ method public java.lang.String getCountries();
+ method public java.lang.String getFqdn();
+ method public boolean getFqdnExactMatch();
+ method public int getPriority();
+ method public void setCountries(java.lang.String);
+ method public void setFqdn(java.lang.String);
+ method public void setFqdnExactMatch(boolean);
+ method public void setPriority(int);
+ method public boolean validate();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.Policy.RoamingPartner> CREATOR;
+ }
+
+ public final class UpdateParameter implements android.os.Parcelable {
+ ctor public UpdateParameter();
+ ctor public UpdateParameter(android.net.wifi.hotspot2.pps.UpdateParameter);
+ method public int describeContents();
+ method public java.lang.String getBase64EncodedPassword();
+ method public java.lang.String getRestriction();
+ method public java.lang.String getServerUri();
+ method public byte[] getTrustRootCertSha256Fingerprint();
+ method public java.lang.String getTrustRootCertUrl();
+ method public long getUpdateIntervalInMinutes();
+ method public java.lang.String getUpdateMethod();
+ method public java.lang.String getUsername();
+ method public void setBase64EncodedPassword(java.lang.String);
+ method public void setRestriction(java.lang.String);
+ method public void setServerUri(java.lang.String);
+ method public void setTrustRootCertSha256Fingerprint(byte[]);
+ method public void setTrustRootCertUrl(java.lang.String);
+ method public void setUpdateIntervalInMinutes(long);
+ method public void setUpdateMethod(java.lang.String);
+ method public void setUsername(java.lang.String);
+ method public boolean validate();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.UpdateParameter> CREATOR;
+ field public static final long UPDATE_CHECK_INTERVAL_NEVER = 4294967295L; // 0xffffffffL
+ field public static final java.lang.String UPDATE_METHOD_OMADM = "OMA-DM-ClientInitiated";
+ field public static final java.lang.String UPDATE_METHOD_SSP = "SSP-ClientInitiated";
+ field public static final java.lang.String UPDATE_RESTRICTION_HOMESP = "HomeSP";
+ field public static final java.lang.String UPDATE_RESTRICTION_ROAMING_PARTNER = "RoamingPartner";
+ field public static final java.lang.String UPDATE_RESTRICTION_UNRESTRICTED = "Unrestricted";
+ }
+
+}
+
package android.net.wifi.p2p {
public class WifiP2pConfig implements android.os.Parcelable {
@@ -38884,31 +39231,24 @@
ctor public AutoFillService();
method public final android.os.IBinder onBind(android.content.Intent);
method public void onConnected();
- method public void onDatasetAuthenticationRequest(android.os.Bundle, int);
method public void onDisconnected();
method public abstract void onFillRequest(android.app.assist.AssistStructure, android.os.Bundle, android.os.CancellationSignal, android.service.autofill.FillCallback);
- method public void onFillResponseAuthenticationRequest(android.os.Bundle, int);
method public abstract void onSaveRequest(android.app.assist.AssistStructure, android.os.Bundle, android.service.autofill.SaveCallback);
- field public static final java.lang.String EXTRA_DATASET_EXTRAS = "android.service.autofill.extra.DATASET_EXTRAS";
- field public static final java.lang.String EXTRA_RESPONSE_EXTRAS = "android.service.autofill.extra.RESPONSE_EXTRAS";
- field public static final int FLAG_AUTHENTICATION_ERROR = 4; // 0x4
- field public static final int FLAG_AUTHENTICATION_REQUESTED = 1; // 0x1
- field public static final int FLAG_AUTHENTICATION_SUCCESS = 2; // 0x2
- field public static final int FLAG_FINGERPRINT_AUTHENTICATION_NOT_AVAILABLE = 8; // 0x8
field public static final java.lang.String SERVICE_INTERFACE = "android.service.autofill.AutoFillService";
field public static final java.lang.String SERVICE_META_DATA = "android.autofill";
}
- public final class FillCallback {
- method public void onDatasetAuthentication(android.view.autofill.Dataset, int);
+ public final class FillCallback implements android.os.Parcelable {
+ method public int describeContents();
method public void onFailure(java.lang.CharSequence);
- method public void onFillResponseAuthentication(int);
method public void onSuccess(android.view.autofill.FillResponse);
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.service.autofill.FillCallback> CREATOR;
}
public final class SaveCallback {
method public void onFailure(java.lang.CharSequence);
- method public void onSuccess(android.view.autofill.AutoFillId[]);
+ method public void onSuccess();
}
}
@@ -42377,11 +42717,6 @@
field public static final int PHONE_TYPE_GSM = 1; // 0x1
field public static final int PHONE_TYPE_NONE = 0; // 0x0
field public static final int PHONE_TYPE_SIP = 3; // 0x3
- field public static final int SIM_ACTIVATION_RESULT_CANCELED = 4; // 0x4
- field public static final int SIM_ACTIVATION_RESULT_COMPLETE = 0; // 0x0
- field public static final int SIM_ACTIVATION_RESULT_FAILED = 3; // 0x3
- field public static final int SIM_ACTIVATION_RESULT_IN_PROGRESS = 2; // 0x2
- field public static final int SIM_ACTIVATION_RESULT_NOT_SUPPORTED = 1; // 0x1
field public static final int SIM_STATE_ABSENT = 1; // 0x1
field public static final int SIM_STATE_CARD_IO_ERROR = 8; // 0x8
field public static final int SIM_STATE_CARD_RESTRICTED = 9; // 0x9
@@ -45114,6 +45449,15 @@
method public android.transition.TransitionManager inflateTransitionManager(int, android.view.ViewGroup);
}
+ public abstract class TransitionListenerAdapter implements android.transition.Transition.TransitionListener {
+ ctor public TransitionListenerAdapter();
+ method public void onTransitionCancel(android.transition.Transition);
+ method public void onTransitionEnd(android.transition.Transition);
+ method public void onTransitionPause(android.transition.Transition);
+ method public void onTransitionResume(android.transition.Transition);
+ method public void onTransitionStart(android.transition.Transition);
+ }
+
public class TransitionManager {
ctor public TransitionManager();
method public static void beginDelayedTransition(android.view.ViewGroup);
@@ -47514,8 +47858,8 @@
method public void drawableHotspotChanged(float, float);
method protected void drawableStateChanged();
method public android.view.View findFocus();
- method public final <T extends android.view.View> T findViewById(int);
- method public final <T extends android.view.View> T findViewWithTag(java.lang.Object);
+ method public final android.view.View findViewById(int);
+ method public final android.view.View findViewWithTag(java.lang.Object);
method public void findViewsWithText(java.util.ArrayList<android.view.View>, java.lang.CharSequence, int);
method protected deprecated boolean fitSystemWindows(android.graphics.Rect);
method public android.view.View focusSearch(int);
@@ -47531,7 +47875,8 @@
method public android.view.animation.Animation getAnimation();
method public android.os.IBinder getApplicationWindowToken();
method public android.view.autofill.AutoFillType getAutoFillType();
- method public android.view.autofill.VirtualViewDelegate getAutoFillVirtualViewDelegate(android.view.autofill.VirtualViewDelegate.Callback);
+ method public android.view.autofill.AutoFillValue getAutoFillValue();
+ method public android.view.autofill.VirtualViewDelegate getAutoFillVirtualViewDelegate();
method public android.graphics.drawable.Drawable getBackground();
method public android.content.res.ColorStateList getBackgroundTintList();
method public android.graphics.PorterDuff.Mode getBackgroundTintMode();
@@ -47984,8 +48329,6 @@
field public static final int ACCESSIBILITY_LIVE_REGION_NONE = 0; // 0x0
field public static final int ACCESSIBILITY_LIVE_REGION_POLITE = 1; // 0x1
field public static final android.util.Property<android.view.View, java.lang.Float> ALPHA;
- field public static final int AUTO_FILL_FLAG_TYPE_FILL = 268435456; // 0x10000000
- field public static final int AUTO_FILL_FLAG_TYPE_SAVE = 536870912; // 0x20000000
field public static final int DRAG_FLAG_GLOBAL = 256; // 0x100
field public static final int DRAG_FLAG_GLOBAL_PERSISTABLE_URI_PERMISSION = 64; // 0x40
field public static final int DRAG_FLAG_GLOBAL_PREFIX_URI_PERMISSION = 128; // 0x80
@@ -48622,7 +48965,7 @@
method public abstract int addChildCount(int);
method public abstract void asyncCommit();
method public abstract android.view.ViewStructure asyncNewChild(int);
- method public abstract android.view.ViewStructure asyncNewChild(int, int);
+ method public abstract android.view.ViewStructure asyncNewChild(int, int, int);
method public abstract int getChildCount();
method public abstract android.os.Bundle getExtras();
method public abstract java.lang.CharSequence getHint();
@@ -48631,11 +48974,12 @@
method public abstract int getTextSelectionStart();
method public abstract boolean hasExtras();
method public abstract android.view.ViewStructure newChild(int);
- method public abstract android.view.ViewStructure newChild(int, int);
+ method public abstract android.view.ViewStructure newChild(int, int, int);
method public abstract void setAccessibilityFocused(boolean);
method public abstract void setActivated(boolean);
method public abstract void setAlpha(float);
method public abstract void setAutoFillType(android.view.autofill.AutoFillType);
+ method public abstract void setAutoFillValue(android.view.autofill.AutoFillValue);
method public abstract void setCheckable(boolean);
method public abstract void setChecked(boolean);
method public abstract void setChildCount(int);
@@ -48658,6 +49002,7 @@
method public abstract void setTextStyle(float, int, int, int);
method public abstract void setTransformation(android.graphics.Matrix);
method public abstract void setVisibility(int);
+ field public static final int AUTO_FILL_FLAG_SANITIZED = 1; // 0x1
}
public final class ViewStub extends android.view.View {
@@ -49094,6 +49439,7 @@
field public static final int TYPE_APPLICATION = 2; // 0x2
field public static final int TYPE_APPLICATION_ATTACHED_DIALOG = 1003; // 0x3eb
field public static final int TYPE_APPLICATION_MEDIA = 1001; // 0x3e9
+ field public static final int TYPE_APPLICATION_OVERLAY = 2038; // 0x7f6
field public static final int TYPE_APPLICATION_PANEL = 1000; // 0x3e8
field public static final int TYPE_APPLICATION_STARTING = 3; // 0x3
field public static final int TYPE_APPLICATION_SUB_PANEL = 1002; // 0x3ea
@@ -49103,17 +49449,17 @@
field public static final int TYPE_INPUT_METHOD = 2011; // 0x7db
field public static final int TYPE_INPUT_METHOD_DIALOG = 2012; // 0x7dc
field public static final int TYPE_KEYGUARD_DIALOG = 2009; // 0x7d9
- field public static final int TYPE_PHONE = 2002; // 0x7d2
- field public static final int TYPE_PRIORITY_PHONE = 2007; // 0x7d7
+ field public static final deprecated int TYPE_PHONE = 2002; // 0x7d2
+ field public static final deprecated int TYPE_PRIORITY_PHONE = 2007; // 0x7d7
field public static final int TYPE_PRIVATE_PRESENTATION = 2030; // 0x7ee
field public static final int TYPE_SEARCH_BAR = 2001; // 0x7d1
field public static final int TYPE_STATUS_BAR = 2000; // 0x7d0
field public static final int TYPE_STATUS_BAR_PANEL = 2014; // 0x7de
- field public static final int TYPE_SYSTEM_ALERT = 2003; // 0x7d3
+ field public static final deprecated int TYPE_SYSTEM_ALERT = 2003; // 0x7d3
field public static final int TYPE_SYSTEM_DIALOG = 2008; // 0x7d8
- field public static final int TYPE_SYSTEM_ERROR = 2010; // 0x7da
- field public static final int TYPE_SYSTEM_OVERLAY = 2006; // 0x7d6
- field public static final int TYPE_TOAST = 2005; // 0x7d5
+ field public static final deprecated int TYPE_SYSTEM_ERROR = 2010; // 0x7da
+ field public static final deprecated int TYPE_SYSTEM_OVERLAY = 2006; // 0x7d6
+ field public static final deprecated int TYPE_TOAST = 2005; // 0x7d5
field public static final int TYPE_WALLPAPER = 2013; // 0x7dd
field public float alpha;
field public float buttonBrightness;
@@ -49890,10 +50236,11 @@
}
public final class AutoFillManager {
- method public void updateAutoFillInput(android.view.View, int);
- method public void updateAutoFillInput(android.view.View, int, android.graphics.Rect, int);
- field public static final int FLAG_UPDATE_UI_HIDE = 2; // 0x2
- field public static final int FLAG_UPDATE_UI_SHOW = 1; // 0x1
+ method public void focusChanged(android.view.View, boolean);
+ method public void reset();
+ method public void valueChanged(android.view.View);
+ method public void virtualFocusChanged(android.view.View, int, android.graphics.Rect, android.view.autofill.AutoFillValue, boolean);
+ method public void virtualValueChanged(android.view.View, int, android.view.autofill.AutoFillValue);
}
public final class AutoFillType implements android.os.Parcelable {
@@ -49928,10 +50275,9 @@
}
public static final class Dataset.Builder {
- ctor public Dataset.Builder(java.lang.CharSequence);
+ ctor public Dataset.Builder(java.lang.String, java.lang.CharSequence);
method public android.view.autofill.Dataset build();
- method public android.view.autofill.Dataset.Builder requiresCustomAuthentication(android.os.Bundle, int);
- method public android.view.autofill.Dataset.Builder requiresFingerprintAuthentication(android.hardware.fingerprint.FingerprintManager.CryptoObject, android.os.Bundle, int);
+ method public android.view.autofill.Dataset.Builder setAuthentication(android.content.IntentSender);
method public android.view.autofill.Dataset.Builder setExtras(android.os.Bundle);
method public android.view.autofill.Dataset.Builder setValue(android.view.autofill.AutoFillId, android.view.autofill.AutoFillValue);
}
@@ -49943,12 +50289,11 @@
}
public static final class FillResponse.Builder {
- ctor public FillResponse.Builder();
+ ctor public FillResponse.Builder(java.lang.String);
method public android.view.autofill.FillResponse.Builder addDataset(android.view.autofill.Dataset);
method public android.view.autofill.FillResponse.Builder addSavableFields(android.view.autofill.AutoFillId...);
method public android.view.autofill.FillResponse build();
- method public android.view.autofill.FillResponse.Builder requiresCustomAuthentication(android.os.Bundle, int);
- method public android.view.autofill.FillResponse.Builder requiresFingerprintAuthentication(android.hardware.fingerprint.FingerprintManager.CryptoObject, android.os.Bundle, int);
+ method public android.view.autofill.FillResponse.Builder setAuthentication(android.content.IntentSender);
method public android.view.autofill.FillResponse.Builder setExtras(android.os.Bundle);
}
@@ -49957,13 +50302,6 @@
method public abstract void autoFill(int, android.view.autofill.AutoFillValue);
}
- public static abstract class VirtualViewDelegate.Callback {
- ctor public VirtualViewDelegate.Callback();
- method public void onAutoFillInputUpdated(int, android.graphics.Rect, int);
- method public void onNodeRemoved(int...);
- method public void onValueChanged(int);
- }
-
}
package android.view.inputmethod {
@@ -50374,7 +50712,7 @@
public final class TextClassificationManager {
method public java.util.List<android.view.textclassifier.TextLanguage> detectLanguages(java.lang.CharSequence);
- method public android.view.textclassifier.TextClassifier getDefaultTextClassifier();
+ method public synchronized android.view.textclassifier.TextClassifier getDefaultTextClassifier();
}
public final class TextClassificationResult {
@@ -54066,6 +54404,7 @@
method public void setIs24HourView(java.lang.Boolean);
method public void setMinute(int);
method public void setOnTimeChangedListener(android.widget.TimePicker.OnTimeChangedListener);
+ method public boolean validateInput();
}
public static abstract interface TimePicker.OnTimeChangedListener {
@@ -54464,6 +54803,8 @@
field public static final int OP_INVOKE_INTERFACE = 114; // 0x72
field public static final int OP_INVOKE_INTERFACE_JUMBO = 9983; // 0x26ff
field public static final int OP_INVOKE_INTERFACE_RANGE = 120; // 0x78
+ field public static final int OP_INVOKE_POLYMORPHIC = 250; // 0xfa
+ field public static final int OP_INVOKE_POLYMORPHIC_RANGE = 251; // 0xfb
field public static final int OP_INVOKE_STATIC = 113; // 0x71
field public static final int OP_INVOKE_STATIC_JUMBO = 9727; // 0x25ff
field public static final int OP_INVOKE_STATIC_RANGE = 119; // 0x77
@@ -57758,12 +58099,15 @@
}
public abstract class MethodHandle {
+ method public java.lang.invoke.MethodHandle asCollector(java.lang.Class<?>, int);
method public java.lang.invoke.MethodHandle asFixedArity();
+ method public java.lang.invoke.MethodHandle asSpreader(java.lang.Class<?>, int);
method public java.lang.invoke.MethodHandle asType(java.lang.invoke.MethodType);
method public java.lang.invoke.MethodHandle asVarargsCollector(java.lang.Class<?>);
method public java.lang.invoke.MethodHandle bindTo(java.lang.Object);
method public final java.lang.Object invoke(java.lang.Object...) throws java.lang.Throwable;
method public final java.lang.Object invokeExact(java.lang.Object...) throws java.lang.Throwable;
+ method public java.lang.Object invokeWithArguments(java.lang.Object...) throws java.lang.Throwable;
method public java.lang.Object invokeWithArguments(java.util.List<?>) throws java.lang.Throwable;
method public boolean isVarargsCollector();
method public java.lang.invoke.MethodType type();
@@ -57797,17 +58141,23 @@
method public static java.lang.invoke.MethodHandle arrayElementGetter(java.lang.Class<?>) throws java.lang.IllegalArgumentException;
method public static java.lang.invoke.MethodHandle arrayElementSetter(java.lang.Class<?>) throws java.lang.IllegalArgumentException;
method public static java.lang.invoke.MethodHandle catchException(java.lang.invoke.MethodHandle, java.lang.Class<? extends java.lang.Throwable>, java.lang.invoke.MethodHandle);
+ method public static java.lang.invoke.MethodHandle collectArguments(java.lang.invoke.MethodHandle, int, java.lang.invoke.MethodHandle);
method public static java.lang.invoke.MethodHandle constant(java.lang.Class<?>, java.lang.Object);
method public static java.lang.invoke.MethodHandle dropArguments(java.lang.invoke.MethodHandle, int, java.util.List<java.lang.Class<?>>);
method public static java.lang.invoke.MethodHandle dropArguments(java.lang.invoke.MethodHandle, int, java.lang.Class<?>...);
method public static java.lang.invoke.MethodHandle exactInvoker(java.lang.invoke.MethodType);
+ method public static java.lang.invoke.MethodHandle filterArguments(java.lang.invoke.MethodHandle, int, java.lang.invoke.MethodHandle...);
method public static java.lang.invoke.MethodHandle filterReturnValue(java.lang.invoke.MethodHandle, java.lang.invoke.MethodHandle);
+ method public static java.lang.invoke.MethodHandle foldArguments(java.lang.invoke.MethodHandle, java.lang.invoke.MethodHandle);
method public static java.lang.invoke.MethodHandle guardWithTest(java.lang.invoke.MethodHandle, java.lang.invoke.MethodHandle, java.lang.invoke.MethodHandle);
method public static java.lang.invoke.MethodHandle identity(java.lang.Class<?>);
+ method public static java.lang.invoke.MethodHandle insertArguments(java.lang.invoke.MethodHandle, int, java.lang.Object...);
method public static java.lang.invoke.MethodHandle invoker(java.lang.invoke.MethodType);
method public static java.lang.invoke.MethodHandles.Lookup lookup();
method public static java.lang.invoke.MethodHandle permuteArguments(java.lang.invoke.MethodHandle, java.lang.invoke.MethodType, int...);
method public static java.lang.invoke.MethodHandles.Lookup publicLookup();
+ method public static <T extends java.lang.reflect.Member> T reflectAs(java.lang.Class<T>, java.lang.invoke.MethodHandle);
+ method public static java.lang.invoke.MethodHandle spreadInvoker(java.lang.invoke.MethodType, int);
method public static java.lang.invoke.MethodHandle throwException(java.lang.Class<?>, java.lang.Class<? extends java.lang.Throwable>);
}
@@ -57824,6 +58174,7 @@
method public java.lang.invoke.MethodHandles.Lookup in(java.lang.Class<?>);
method public java.lang.Class<?> lookupClass();
method public int lookupModes();
+ method public java.lang.invoke.MethodHandleInfo revealDirect(java.lang.invoke.MethodHandle);
method public void throwMakeAccessException(java.lang.String, java.lang.Object) throws java.lang.IllegalAccessException;
method public java.lang.invoke.MethodHandle unreflect(java.lang.reflect.Method) throws java.lang.IllegalAccessException;
method public java.lang.invoke.MethodHandle unreflectConstructor(java.lang.reflect.Constructor<?>) throws java.lang.IllegalAccessException;
diff --git a/api/test-current.txt b/api/test-current.txt
index 958c054..4c487e1 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -203,7 +203,6 @@
public static final class R.attr {
ctor public R.attr();
- field public static final int __removed0 = 16844097; // 0x1010541
field public static final int __removed1 = 16844099; // 0x1010543
field public static final int absListViewStyle = 16842858; // 0x101006a
field public static final int accessibilityEventTypes = 16843648; // 0x1010380
@@ -1270,6 +1269,7 @@
field public static final int targetId = 16843740; // 0x10103dc
field public static final int targetName = 16843853; // 0x101044d
field public static final int targetPackage = 16842785; // 0x1010021
+ field public static final int targetProcess = 16844097; // 0x1010541
field public static final int targetSandboxVersion = 16844110; // 0x101054e
field public static final int targetSdkVersion = 16843376; // 0x1010270
field public static final int taskAffinity = 16842770; // 0x1010012
@@ -2688,11 +2688,25 @@
package android.accessibilityservice {
+ public final class AccessibilityButtonController {
+ method public boolean isAccessibilityButtonAvailable();
+ method public void registerAccessibilityButtonCallback(android.accessibilityservice.AccessibilityButtonController.AccessibilityButtonCallback);
+ method public void registerAccessibilityButtonCallback(android.accessibilityservice.AccessibilityButtonController.AccessibilityButtonCallback, android.os.Handler);
+ method public void unregisterAccessibilityButtonCallback(android.accessibilityservice.AccessibilityButtonController.AccessibilityButtonCallback);
+ }
+
+ public static abstract class AccessibilityButtonController.AccessibilityButtonCallback {
+ ctor public AccessibilityButtonController.AccessibilityButtonCallback();
+ method public void onAvailabilityChanged(android.accessibilityservice.AccessibilityButtonController, boolean);
+ method public void onClicked(android.accessibilityservice.AccessibilityButtonController);
+ }
+
public abstract class AccessibilityService extends android.app.Service {
ctor public AccessibilityService();
method public final void disableSelf();
method public final boolean dispatchGesture(android.accessibilityservice.GestureDescription, android.accessibilityservice.AccessibilityService.GestureResultCallback, android.os.Handler);
method public android.view.accessibility.AccessibilityNodeInfo findFocus(int);
+ method public final android.accessibilityservice.AccessibilityButtonController getAccessibilityButtonController();
method public final android.accessibilityservice.FingerprintGestureController getFingerprintGestureController();
method public final android.accessibilityservice.AccessibilityService.MagnificationController getMagnificationController();
method public android.view.accessibility.AccessibilityNodeInfo getRootInActiveWindow();
@@ -2805,6 +2819,7 @@
field public static final int FLAG_ENABLE_ACCESSIBILITY_VOLUME = 128; // 0x80
field public static final int FLAG_INCLUDE_NOT_IMPORTANT_VIEWS = 2; // 0x2
field public static final int FLAG_REPORT_VIEW_IDS = 16; // 0x10
+ field public static final int FLAG_REQUEST_ACCESSIBILITY_BUTTON = 256; // 0x100
field public static final int FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY = 8; // 0x8
field public static final int FLAG_REQUEST_FILTER_KEY_EVENTS = 32; // 0x20
field public static final int FLAG_REQUEST_TOUCH_EXPLORATION_MODE = 4; // 0x4
@@ -2909,7 +2924,7 @@
public class AccountManager {
method public android.accounts.AccountManagerFuture<android.os.Bundle> addAccount(java.lang.String, java.lang.String, java.lang.String[], android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
method public boolean addAccountExplicitly(android.accounts.Account, java.lang.String, android.os.Bundle);
- method public boolean addAccountExplicitly(android.accounts.Account, java.lang.String, android.os.Bundle, java.util.Map<java.lang.Integer, java.lang.Integer>);
+ method public boolean addAccountExplicitly(android.accounts.Account, java.lang.String, android.os.Bundle, java.util.Map<java.lang.String, java.lang.Integer>);
method public void addOnAccountsUpdatedListener(android.accounts.OnAccountsUpdateListener, android.os.Handler, boolean);
method public void addOnAccountsUpdatedListener(android.accounts.OnAccountsUpdateListener, android.os.Handler, boolean, java.lang.String[]);
method public java.lang.String blockingGetAuthToken(android.accounts.Account, java.lang.String, boolean) throws android.accounts.AuthenticatorException, java.io.IOException, android.accounts.OperationCanceledException;
@@ -2918,7 +2933,7 @@
method public android.accounts.AccountManagerFuture<android.os.Bundle> editProperties(java.lang.String, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
method public android.accounts.AccountManagerFuture<android.os.Bundle> finishSession(android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
method public static android.accounts.AccountManager get(android.content.Context);
- method public int getAccountVisibility(android.accounts.Account, int);
+ method public int getAccountVisibility(android.accounts.Account, java.lang.String);
method public android.accounts.Account[] getAccounts();
method public java.util.Map<android.accounts.Account, java.lang.Integer> getAccountsAndVisibilityForPackage(java.lang.String, java.lang.String);
method public android.accounts.Account[] getAccountsByType(java.lang.String);
@@ -2929,9 +2944,9 @@
method public android.accounts.AccountManagerFuture<android.os.Bundle> getAuthToken(android.accounts.Account, java.lang.String, android.os.Bundle, boolean, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
method public android.accounts.AccountManagerFuture<android.os.Bundle> getAuthTokenByFeatures(java.lang.String, java.lang.String, java.lang.String[], android.app.Activity, android.os.Bundle, android.os.Bundle, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
method public android.accounts.AuthenticatorDescription[] getAuthenticatorTypes();
+ method public java.util.Map<java.lang.String, java.lang.Integer> getPackagesAndVisibilityForAccount(android.accounts.Account);
method public java.lang.String getPassword(android.accounts.Account);
method public java.lang.String getPreviousName(android.accounts.Account);
- method public java.util.Map<java.lang.Integer, java.lang.Integer> getUidsAndVisibilityForAccount(android.accounts.Account);
method public java.lang.String getUserData(android.accounts.Account, java.lang.String);
method public android.accounts.AccountManagerFuture<java.lang.Boolean> hasFeatures(android.accounts.Account, java.lang.String[], android.accounts.AccountManagerCallback<java.lang.Boolean>, android.os.Handler);
method public void invalidateAuthToken(java.lang.String, java.lang.String);
@@ -2945,7 +2960,7 @@
method public boolean removeAccountExplicitly(android.accounts.Account);
method public void removeOnAccountsUpdatedListener(android.accounts.OnAccountsUpdateListener);
method public android.accounts.AccountManagerFuture<android.accounts.Account> renameAccount(android.accounts.Account, java.lang.String, android.accounts.AccountManagerCallback<android.accounts.Account>, android.os.Handler);
- method public boolean setAccountVisibility(android.accounts.Account, int, int);
+ method public boolean setAccountVisibility(android.accounts.Account, java.lang.String, int);
method public void setAuthToken(android.accounts.Account, java.lang.String, java.lang.String);
method public void setPassword(android.accounts.Account, java.lang.String);
method public void setUserData(android.accounts.Account, java.lang.String, java.lang.String);
@@ -2985,8 +3000,8 @@
field public static final java.lang.String KEY_PASSWORD = "password";
field public static final java.lang.String KEY_USERDATA = "userdata";
field public static final deprecated java.lang.String LOGIN_ACCOUNTS_CHANGED_ACTION = "android.accounts.LOGIN_ACCOUNTS_CHANGED";
- field public static final int UID_KEY_DEFAULT_LEGACY_VISIBILITY = -3; // 0xfffffffd
- field public static final int UID_KEY_DEFAULT_VISIBILITY = -2; // 0xfffffffe
+ field public static final java.lang.String PACKAGE_NAME_KEY_LEGACY_NOT_VISIBLE = "android.accounts.key_legacy_not_visible";
+ field public static final java.lang.String PACKAGE_NAME_KEY_LEGACY_VISIBLE = "android.accounts.key_legacy_visible";
field public static final int VISIBILITY_NOT_VISIBLE = 3; // 0x3
field public static final int VISIBILITY_UNDEFINED = 0; // 0x0
field public static final int VISIBILITY_USER_MANAGED_NOT_VISIBLE = 4; // 0x4
@@ -4181,7 +4196,6 @@
method public abstract void onActivityCreated(android.app.Activity, android.os.Bundle);
method public abstract void onActivityDestroyed(android.app.Activity);
method public abstract void onActivityPaused(android.app.Activity);
- method public default void onActivityPreCreated(android.app.Activity, android.os.Bundle);
method public abstract void onActivityResumed(android.app.Activity);
method public abstract void onActivitySaveInstanceState(android.app.Activity, android.os.Bundle);
method public abstract void onActivityStarted(android.app.Activity);
@@ -4815,6 +4829,7 @@
method public void addMonitor(android.app.Instrumentation.ActivityMonitor);
method public android.app.Instrumentation.ActivityMonitor addMonitor(android.content.IntentFilter, android.app.Instrumentation.ActivityResult, boolean);
method public android.app.Instrumentation.ActivityMonitor addMonitor(java.lang.String, android.app.Instrumentation.ActivityResult, boolean);
+ method public void addResults(android.os.Bundle);
method public void callActivityOnCreate(android.app.Activity, android.os.Bundle);
method public void callActivityOnCreate(android.app.Activity, android.os.Bundle, android.os.PersistableBundle);
method public void callActivityOnDestroy(android.app.Activity);
@@ -4839,6 +4854,7 @@
method public android.os.Bundle getBinderCounts();
method public android.content.ComponentName getComponentName();
method public android.content.Context getContext();
+ method public java.lang.String getProcessName();
method public android.content.Context getTargetContext();
method public android.app.UiAutomation getUiAutomation();
method public android.app.UiAutomation getUiAutomation(int);
@@ -5055,14 +5071,19 @@
ctor public Notification(android.os.Parcel);
method public android.app.Notification clone();
method public int describeContents();
+ method public int getBadgeIcon();
method public java.lang.String getChannel();
method public java.lang.String getGroup();
method public android.graphics.drawable.Icon getLargeIcon();
+ method public java.lang.String getShortcutId();
method public android.graphics.drawable.Icon getSmallIcon();
method public java.lang.String getSortKey();
method public long getTimeout();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.media.AudioAttributes AUDIO_ATTRIBUTES_DEFAULT;
+ field public static final int BADGE_ICON_LARGE = 2; // 0x2
+ field public static final int BADGE_ICON_NONE = 0; // 0x0
+ field public static final int BADGE_ICON_SMALL = 1; // 0x1
field public static final java.lang.String CATEGORY_ALARM = "alarm";
field public static final java.lang.String CATEGORY_CALL = "call";
field public static final java.lang.String CATEGORY_EMAIL = "email";
@@ -5154,7 +5175,7 @@
field public deprecated int ledARGB;
field public deprecated int ledOffMS;
field public deprecated int ledOnMS;
- field public deprecated int number;
+ field public int number;
field public deprecated int priority;
field public android.app.Notification publicVersion;
field public deprecated android.net.Uri sound;
@@ -5242,6 +5263,7 @@
method public android.app.Notification.Builder addExtras(android.os.Bundle);
method public android.app.Notification.Builder addPerson(java.lang.String);
method public android.app.Notification build();
+ method public android.app.Notification.Builder chooseBadgeIcon(int);
method public android.widget.RemoteViews createBigContentView();
method public android.widget.RemoteViews createContentView();
method public android.widget.RemoteViews createHeadsUpContentView();
@@ -5274,13 +5296,14 @@
method public android.app.Notification.Builder setLargeIcon(android.graphics.drawable.Icon);
method public deprecated android.app.Notification.Builder setLights(int, int, int);
method public android.app.Notification.Builder setLocalOnly(boolean);
- method public deprecated android.app.Notification.Builder setNumber(int);
+ method public android.app.Notification.Builder setNumber(int);
method public android.app.Notification.Builder setOngoing(boolean);
method public android.app.Notification.Builder setOnlyAlertOnce(boolean);
method public deprecated android.app.Notification.Builder setPriority(int);
method public android.app.Notification.Builder setProgress(int, int, boolean);
method public android.app.Notification.Builder setPublicVersion(android.app.Notification);
method public android.app.Notification.Builder setRemoteInputHistory(java.lang.CharSequence[]);
+ method public android.app.Notification.Builder setShortcutId(java.lang.String);
method public android.app.Notification.Builder setShowWhen(boolean);
method public android.app.Notification.Builder setSmallIcon(int);
method public android.app.Notification.Builder setSmallIcon(int, int);
@@ -6215,6 +6238,7 @@
method public long getLastBugReportRequestTime();
method public long getLastNetworkLogRetrievalTime();
method public long getLastSecurityLogRetrievalTime();
+ method public java.lang.String[] getLockTaskPackages(android.content.ComponentName);
method public java.lang.CharSequence getLongSupportMessage(android.content.ComponentName);
method public int getMaximumFailedPasswordsForWipe(android.content.ComponentName);
method public long getMaximumTimeToLock(android.content.ComponentName);
@@ -6532,6 +6556,7 @@
method public float getAlpha();
method public android.view.autofill.AutoFillId getAutoFillId();
method public android.view.autofill.AutoFillType getAutoFillType();
+ method public android.view.autofill.AutoFillValue getAutoFillValue();
method public android.app.assist.AssistStructure.ViewNode getChildAt(int);
method public int getChildCount();
method public java.lang.String getClassName();
@@ -7964,6 +7989,65 @@
}
+package android.companion {
+
+ public final class AssociationRequest<F extends android.companion.DeviceFilter> implements android.os.Parcelable {
+ method public int describeContents();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.companion.AssociationRequest> CREATOR;
+ }
+
+ public static final class AssociationRequest.Builder<F extends android.companion.DeviceFilter> {
+ method public android.companion.AssociationRequest<F> build();
+ method public static android.companion.AssociationRequest.Builder<android.companion.BluetoothDeviceFilter> createForBluetoothDevice();
+ method public static android.companion.AssociationRequest.Builder<android.companion.BluetoothLEDeviceFilter> createForBluetoothLEDevice();
+ method public android.companion.AssociationRequest.Builder<F> setDeviceFilter(F);
+ method public android.companion.AssociationRequest.Builder<F> setSingleDevice(boolean);
+ }
+
+ public final class BluetoothDeviceFilter implements android.companion.DeviceFilter {
+ method public int describeContents();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.companion.BluetoothDeviceFilter> CREATOR;
+ }
+
+ public static final class BluetoothDeviceFilter.Builder {
+ ctor public BluetoothDeviceFilter.Builder();
+ method public android.companion.BluetoothDeviceFilter.Builder addServiceUuid(android.os.ParcelUuid, android.os.ParcelUuid);
+ method public android.companion.BluetoothDeviceFilter build();
+ method public android.companion.BluetoothDeviceFilter.Builder setAddress(java.lang.String);
+ method public android.companion.BluetoothDeviceFilter.Builder setNamePattern(java.util.regex.Pattern);
+ }
+
+ public final class BluetoothLEDeviceFilter implements android.companion.DeviceFilter {
+ method public int describeContents();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.companion.BluetoothLEDeviceFilter> CREATOR;
+ }
+
+ public static final class BluetoothLEDeviceFilter.Builder {
+ ctor public BluetoothLEDeviceFilter.Builder();
+ method public android.companion.BluetoothLEDeviceFilter build();
+ method public android.companion.BluetoothLEDeviceFilter.Builder setNamePattern(java.util.regex.Pattern);
+ method public android.companion.BluetoothLEDeviceFilter.Builder setScanFilter(android.bluetooth.le.ScanFilter);
+ }
+
+ public final class CompanionDeviceManager {
+ method public void associate(android.companion.AssociationRequest<?>, android.companion.CompanionDeviceManager.Callback, android.os.Handler);
+ field public static final java.lang.String EXTRA_DEVICE = "android.companion.extra.DEVICE";
+ }
+
+ public static abstract class CompanionDeviceManager.Callback {
+ ctor public CompanionDeviceManager.Callback();
+ method public abstract void onDeviceFound(android.content.IntentSender);
+ method public abstract void onFailure(java.lang.CharSequence);
+ }
+
+ public abstract interface DeviceFilter<D extends android.os.Parcelable> implements android.os.Parcelable {
+ }
+
+}
+
package android.content {
public abstract class AbstractThreadedSyncAdapter {
@@ -8578,6 +8662,7 @@
field public static final java.lang.String CAPTIONING_SERVICE = "captioning";
field public static final java.lang.String CARRIER_CONFIG_SERVICE = "carrier_config";
field public static final java.lang.String CLIPBOARD_SERVICE = "clipboard";
+ field public static final java.lang.String COMPANION_DEVICE_SERVICE = "companion_device";
field public static final java.lang.String CONNECTIVITY_SERVICE = "connectivity";
field public static final java.lang.String CONSUMER_IR_SERVICE = "consumer_ir";
field public static final int CONTEXT_IGNORE_SECURITY = 2; // 0x2
@@ -9116,6 +9201,10 @@
field public static final java.lang.String EXTRA_ASSIST_INPUT_HINT_KEYBOARD = "android.intent.extra.ASSIST_INPUT_HINT_KEYBOARD";
field public static final java.lang.String EXTRA_ASSIST_PACKAGE = "android.intent.extra.ASSIST_PACKAGE";
field public static final java.lang.String EXTRA_ASSIST_UID = "android.intent.extra.ASSIST_UID";
+ field public static final java.lang.String EXTRA_AUTO_FILL_ASSIST_STRUCTURE = "android.intent.extra.AUTO_FILL_ASSIST_STRUCTURE";
+ field public static final java.lang.String EXTRA_AUTO_FILL_CALLBACK = "android.intent.extra.AUTO_FILL_CALLBACK";
+ field public static final java.lang.String EXTRA_AUTO_FILL_EXTRAS = "android.intent.extra.AUTO_FILL_EXTRAS";
+ field public static final java.lang.String EXTRA_AUTO_FILL_ITEM_ID = "android.intent.extra.AUTO_FILL_ITEM_ID";
field public static final java.lang.String EXTRA_BCC = "android.intent.extra.BCC";
field public static final java.lang.String EXTRA_BUG_REPORT = "android.intent.extra.BUG_REPORT";
field public static final java.lang.String EXTRA_CC = "android.intent.extra.CC";
@@ -9152,6 +9241,7 @@
field public static final java.lang.String EXTRA_PHONE_NUMBER = "android.intent.extra.PHONE_NUMBER";
field public static final java.lang.String EXTRA_PROCESS_TEXT = "android.intent.extra.PROCESS_TEXT";
field public static final java.lang.String EXTRA_PROCESS_TEXT_READONLY = "android.intent.extra.PROCESS_TEXT_READONLY";
+ field public static final java.lang.String EXTRA_QUICK_VIEW_PLAIN = "android.intent.extra.QUICK_VIEW_PLAIN";
field public static final java.lang.String EXTRA_QUIET_MODE = "android.intent.extra.QUIET_MODE";
field public static final java.lang.String EXTRA_REFERRER = "android.intent.extra.REFERRER";
field public static final java.lang.String EXTRA_REFERRER_NAME = "android.intent.extra.REFERRER_NAME";
@@ -9930,6 +10020,7 @@
field public java.lang.String[] splitPublicSourceDirs;
field public java.lang.String[] splitSourceDirs;
field public java.lang.String targetPackage;
+ field public java.lang.String targetProcess;
}
public class LabeledIntent extends android.content.Intent {
@@ -10355,6 +10446,7 @@
field public static final java.lang.String FEATURE_VERIFIED_BOOT = "android.software.verified_boot";
field public static final java.lang.String FEATURE_VR_MODE = "android.software.vr.mode";
field public static final java.lang.String FEATURE_VR_MODE_HIGH_PERFORMANCE = "android.hardware.vr.high_performance";
+ field public static final java.lang.String FEATURE_VULKAN_HARDWARE_COMPUTE = "android.hardware.vulkan.compute";
field public static final java.lang.String FEATURE_VULKAN_HARDWARE_LEVEL = "android.hardware.vulkan.level";
field public static final java.lang.String FEATURE_VULKAN_HARDWARE_VERSION = "android.hardware.vulkan.version";
field public static final java.lang.String FEATURE_WATCH = "android.hardware.type.watch";
@@ -20531,6 +20623,7 @@
method public int getContentType();
method public int getFlags();
method public int getUsage();
+ method public static int getVolumeControlStream(android.media.AudioAttributes);
method public void writeToParcel(android.os.Parcel, int);
field public static final int CONTENT_TYPE_MOVIE = 3; // 0x3
field public static final int CONTENT_TYPE_MUSIC = 2; // 0x2
@@ -22253,6 +22346,7 @@
}
public static final class MediaMuxer.OutputFormat {
+ field public static final int MUXER_OUTPUT_3GPP = 2; // 0x2
field public static final int MUXER_OUTPUT_MPEG_4 = 0; // 0x0
field public static final int MUXER_OUTPUT_WEBM = 1; // 0x1
}
@@ -23673,6 +23767,8 @@
public final class MediaController {
ctor public MediaController(android.content.Context, android.media.session.MediaSession.Token);
+ method public void addQueueItem(android.media.MediaDescription);
+ method public void addQueueItem(android.media.MediaDescription, int);
method public void adjustVolume(int, int);
method public boolean dispatchMediaButtonEvent(android.view.KeyEvent);
method public android.os.Bundle getExtras();
@@ -23691,6 +23787,8 @@
method public boolean isShuffleModeEnabled();
method public void registerCallback(android.media.session.MediaController.Callback);
method public void registerCallback(android.media.session.MediaController.Callback, android.os.Handler);
+ method public void removeQueueItem(android.media.MediaDescription);
+ method public void removeQueueItemAt(int);
method public void sendCommand(java.lang.String, android.os.Bundle, android.os.ResultReceiver);
method public void setVolumeTo(int, int);
method public void unregisterCallback(android.media.session.MediaController.Callback);
@@ -23768,11 +23866,14 @@
method public void setSessionActivity(android.app.PendingIntent);
method public void setShuffleModeEnabled(boolean);
field public static final int FLAG_HANDLES_MEDIA_BUTTONS = 1; // 0x1
+ field public static final int FLAG_HANDLES_QUEUE_COMMANDS = 4; // 0x4
field public static final int FLAG_HANDLES_TRANSPORT_CONTROLS = 2; // 0x2
}
public static abstract class MediaSession.Callback {
ctor public MediaSession.Callback();
+ method public void onAddQueueItem(android.media.MediaDescription);
+ method public void onAddQueueItem(android.media.MediaDescription, int);
method public void onCommand(java.lang.String, android.os.Bundle, android.os.ResultReceiver);
method public void onCustomAction(java.lang.String, android.os.Bundle);
method public void onFastForward();
@@ -23786,6 +23887,8 @@
method public void onPrepareFromMediaId(java.lang.String, android.os.Bundle);
method public void onPrepareFromSearch(java.lang.String, android.os.Bundle);
method public void onPrepareFromUri(android.net.Uri, android.os.Bundle);
+ method public void onRemoveQueueItem(android.media.MediaDescription);
+ method public void onRemoveQueueItemAt(int);
method public void onRewind();
method public void onSeekTo(long);
method public void onSetRating(android.media.Rating);
@@ -24033,6 +24136,7 @@
field public static final java.lang.String AVAILABILITY_AVAILABLE = "AVAILABILITY_AVAILABLE";
field public static final java.lang.String AVAILABILITY_FREE_WITH_SUBSCRIPTION = "AVAILABILITY_FREE_WITH_SUBSCRIPTION";
field public static final java.lang.String AVAILABILITY_PAID_CONTENT = "AVAILABILITY_PAID_CONTENT";
+ field public static final java.lang.String COLUMN_APP_LINK_INTENT_URI = "app_link_intent_uri";
field public static final java.lang.String COLUMN_AUDIO_LANGUAGE = "audio_language";
field public static final java.lang.String COLUMN_AUTHOR = "author";
field public static final java.lang.String COLUMN_AVAILABILITY = "availability";
@@ -24040,6 +24144,7 @@
field public static final java.lang.String COLUMN_CANONICAL_GENRE = "canonical_genre";
field public static final java.lang.String COLUMN_CHANNEL_ID = "channel_id";
field public static final java.lang.String COLUMN_CONTENT_RATING = "content_rating";
+ field public static final java.lang.String COLUMN_DURATION_MILLIS = "duration_millis";
field public static final java.lang.String COLUMN_END_TIME_UTC_MILLIS = "end_time_utc_millis";
field public static final java.lang.String COLUMN_EPISODE_DISPLAY_NUMBER = "episode_display_number";
field public static final deprecated java.lang.String COLUMN_EPISODE_NUMBER = "episode_number";
@@ -24053,17 +24158,14 @@
field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG4 = "internal_provider_flag4";
field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_ID = "internal_provider_id";
field public static final java.lang.String COLUMN_ITEM_COUNT = "item_count";
+ field public static final java.lang.String COLUMN_LAST_PLAYBACK_POSITION_MILLIS = "last_playback_position_millis";
field public static final java.lang.String COLUMN_LIVE = "live";
- field public static final java.lang.String COLUMN_LOGO = "logo";
+ field public static final java.lang.String COLUMN_LOGO_URI = "logo_uri";
field public static final java.lang.String COLUMN_LONG_DESCRIPTION = "long_description";
field public static final java.lang.String COLUMN_OFFER_PRICE = "offer_price";
field public static final java.lang.String COLUMN_POSTER_ART_ASPECT_RATIO = "poster_art_aspect_ratio";
field public static final java.lang.String COLUMN_POSTER_ART_URI = "poster_art_uri";
- field public static final java.lang.String COLUMN_PREVIEW_DURATION = "preview_duration";
- field public static final java.lang.String COLUMN_PREVIEW_INTENT_URI = "preview_intent_uri";
- field public static final java.lang.String COLUMN_PREVIEW_LAST_PLAYBACK_POSITION = "preview_last_playback_position";
field public static final java.lang.String COLUMN_PREVIEW_VIDEO_URI = "preview_video_uri";
- field public static final java.lang.String COLUMN_PREVIEW_WEIGHT = "preview_weight";
field public static final java.lang.String COLUMN_RECORDING_PROHIBITED = "recording_prohibited";
field public static final java.lang.String COLUMN_RELEASE_DATE = "release_date";
field public static final java.lang.String COLUMN_REVIEW_RATING = "review_rating";
@@ -24083,6 +24185,7 @@
field public static final java.lang.String COLUMN_VIDEO_HEIGHT = "video_height";
field public static final java.lang.String COLUMN_VIDEO_WIDTH = "video_width";
field public static final java.lang.String COLUMN_WATCH_NEXT_TYPE = "watch_next_type";
+ field public static final java.lang.String COLUMN_WEIGHT = "weight";
field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/program";
field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/program";
field public static final android.net.Uri CONTENT_URI;
@@ -25828,6 +25931,7 @@
public class WifiManager {
method public int addNetwork(android.net.wifi.WifiConfiguration);
+ method public boolean addOrUpdatePasspointConfiguration(android.net.wifi.hotspot2.PasspointConfiguration);
method public static int calculateSignalLevel(int, int);
method public void cancelWps(android.net.wifi.WifiManager.WpsCallback);
method public static int compareSignalLevel(int, int);
@@ -25840,6 +25944,7 @@
method public java.util.List<android.net.wifi.WifiConfiguration> getConfiguredNetworks();
method public android.net.wifi.WifiInfo getConnectionInfo();
method public android.net.DhcpInfo getDhcpInfo();
+ method public java.util.List<android.net.wifi.hotspot2.PasspointConfiguration> getPasspointConfigurations();
method public java.util.List<android.net.wifi.ScanResult> getScanResults();
method public int getWifiState();
method public boolean is5GHzBandSupported();
@@ -25855,6 +25960,7 @@
method public boolean reassociate();
method public boolean reconnect();
method public boolean removeNetwork(int);
+ method public boolean removePasspointConfiguration(java.lang.String);
method public boolean saveConfiguration();
method public void setTdlsEnabled(java.net.InetAddress, boolean);
method public void setTdlsEnabledWithMacAddress(java.lang.String, boolean);
@@ -26069,6 +26175,241 @@
}
+package android.net.wifi.hotspot2 {
+
+ public final class ConfigParser {
+ method public static android.net.wifi.hotspot2.PasspointConfiguration parsePasspointConfig(java.lang.String, byte[]);
+ }
+
+ public final class PasspointConfiguration implements android.os.Parcelable {
+ ctor public PasspointConfiguration();
+ ctor public PasspointConfiguration(android.net.wifi.hotspot2.PasspointConfiguration);
+ method public int describeContents();
+ method public android.net.wifi.hotspot2.pps.Credential getCredential();
+ method public int getCredentialPriority();
+ method public android.net.wifi.hotspot2.pps.HomeSp getHomeSp();
+ method public android.net.wifi.hotspot2.pps.Policy getPolicy();
+ method public long getSubscriptionCreationTimeInMs();
+ method public long getSubscriptionExpirationTimeInMs();
+ method public java.lang.String getSubscriptionType();
+ method public android.net.wifi.hotspot2.pps.UpdateParameter getSubscriptionUpdate();
+ method public java.util.Map<java.lang.String, byte[]> getTrustRootCertList();
+ method public int getUpdateIdentififer();
+ method public long getUsageLimitDataLimit();
+ method public long getUsageLimitStartTimeInMs();
+ method public long getUsageLimitTimeLimitInMinutes();
+ method public long getUsageLimitUsageTimePeriodInMinutes();
+ method public void setCredential(android.net.wifi.hotspot2.pps.Credential);
+ method public void setCredentialPriority(int);
+ method public void setHomeSp(android.net.wifi.hotspot2.pps.HomeSp);
+ method public void setPolicy(android.net.wifi.hotspot2.pps.Policy);
+ method public void setSubscriptionCreationTimeInMs(long);
+ method public void setSubscriptionExpirationTimeInMs(long);
+ method public void setSubscriptionType(java.lang.String);
+ method public void setSubscriptionUpdate(android.net.wifi.hotspot2.pps.UpdateParameter);
+ method public void setTrustRootCertList(java.util.Map<java.lang.String, byte[]>);
+ method public void setUpdateIdentifier(int);
+ method public void setUsageLimitDataLimit(long);
+ method public void setUsageLimitStartTimeInMs(long);
+ method public void setUsageLimitTimeLimitInMinutes(long);
+ method public void setUsageLimitUsageTimePeriodInMinutes(long);
+ method public boolean validate();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.PasspointConfiguration> CREATOR;
+ }
+
+}
+
+package android.net.wifi.hotspot2.omadm {
+
+ public final class PpsMoParser {
+ method public static android.net.wifi.hotspot2.PasspointConfiguration parseMoText(java.lang.String);
+ }
+
+}
+
+package android.net.wifi.hotspot2.pps {
+
+ public final class Credential implements android.os.Parcelable {
+ ctor public Credential();
+ ctor public Credential(android.net.wifi.hotspot2.pps.Credential);
+ method public int describeContents();
+ method public java.security.cert.X509Certificate getCaCertificate();
+ method public android.net.wifi.hotspot2.pps.Credential.CertificateCredential getCertCredential();
+ method public boolean getCheckAaaServerStatus();
+ method public java.security.cert.X509Certificate[] getClientCertificateChain();
+ method public java.security.PrivateKey getClientPrivateKey();
+ method public long getCreationTimeInMs();
+ method public long getExpirationTimeInMs();
+ method public java.lang.String getRealm();
+ method public android.net.wifi.hotspot2.pps.Credential.SimCredential getSimCredential();
+ method public android.net.wifi.hotspot2.pps.Credential.UserCredential getUserCredential();
+ method public void setCaCertificate(java.security.cert.X509Certificate);
+ method public void setCertCredential(android.net.wifi.hotspot2.pps.Credential.CertificateCredential);
+ method public void setCheckAaaServerCertStatus(boolean);
+ method public void setClientCertificateChain(java.security.cert.X509Certificate[]);
+ method public void setClientPrivateKey(java.security.PrivateKey);
+ method public void setCreationTimeInMs(long);
+ method public void setExpirationTimeInMs(long);
+ method public void setRealm(java.lang.String);
+ method public void setSimCredential(android.net.wifi.hotspot2.pps.Credential.SimCredential);
+ method public void setUserCredential(android.net.wifi.hotspot2.pps.Credential.UserCredential);
+ method public boolean validate();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.Credential> CREATOR;
+ }
+
+ public static final class Credential.CertificateCredential implements android.os.Parcelable {
+ ctor public Credential.CertificateCredential();
+ ctor public Credential.CertificateCredential(android.net.wifi.hotspot2.pps.Credential.CertificateCredential);
+ method public int describeContents();
+ method public byte[] getCertSha256Fingerprint();
+ method public java.lang.String getCertType();
+ method public void setCertSha256Fingerprint(byte[]);
+ method public void setCertType(java.lang.String);
+ method public boolean validate();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.Credential.CertificateCredential> CREATOR;
+ }
+
+ public static final class Credential.SimCredential implements android.os.Parcelable {
+ ctor public Credential.SimCredential();
+ ctor public Credential.SimCredential(android.net.wifi.hotspot2.pps.Credential.SimCredential);
+ method public int describeContents();
+ method public int getEapType();
+ method public java.lang.String getImsi();
+ method public void setEapType(int);
+ method public void setImsi(java.lang.String);
+ method public boolean validate();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.Credential.SimCredential> CREATOR;
+ }
+
+ public static final class Credential.UserCredential implements android.os.Parcelable {
+ ctor public Credential.UserCredential();
+ ctor public Credential.UserCredential(android.net.wifi.hotspot2.pps.Credential.UserCredential);
+ method public int describeContents();
+ method public boolean getAbleToShare();
+ method public int getEapType();
+ method public boolean getMachineManaged();
+ method public java.lang.String getNonEapInnerMethod();
+ method public java.lang.String getPassword();
+ method public java.lang.String getSoftTokenApp();
+ method public java.lang.String getUsername();
+ method public void setAbleToShare(boolean);
+ method public void setEapType(int);
+ method public void setMachineManaged(boolean);
+ method public void setNonEapInnerMethod(java.lang.String);
+ method public void setPassword(java.lang.String);
+ method public void setSoftTokenApp(java.lang.String);
+ method public void setUsername(java.lang.String);
+ method public boolean validate();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.Credential.UserCredential> CREATOR;
+ }
+
+ public final class HomeSp implements android.os.Parcelable {
+ ctor public HomeSp();
+ ctor public HomeSp(android.net.wifi.hotspot2.pps.HomeSp);
+ method public int describeContents();
+ method public java.lang.String getFqdn();
+ method public java.lang.String getFriendlyName();
+ method public java.util.Map<java.lang.String, java.lang.Long> getHomeNetworkIds();
+ method public java.lang.String getIconUrl();
+ method public long[] getMatchAllOis();
+ method public long[] getMatchAnysOis();
+ method public java.lang.String[] getOtherHomePartners();
+ method public long[] getRoamingConsortiumOis();
+ method public void setFqdn(java.lang.String);
+ method public void setFriendlyName(java.lang.String);
+ method public void setHomeNetworkIds(java.util.Map<java.lang.String, java.lang.Long>);
+ method public void setIconUrl(java.lang.String);
+ method public void setMatchAllOis(long[]);
+ method public void setMatchAnyOis(long[]);
+ method public void setOtherHomePartners(java.lang.String[]);
+ method public void setRoamingConsortiumOis(long[]);
+ method public boolean validate();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.HomeSp> CREATOR;
+ }
+
+ public final class Policy implements android.os.Parcelable {
+ ctor public Policy();
+ ctor public Policy(android.net.wifi.hotspot2.pps.Policy);
+ method public int describeContents();
+ method public java.lang.String[] getExcludedSsidList();
+ method public int getMaximumBssLoadValue();
+ method public long getMinHomeDownlinkBandWidht();
+ method public long getMinHomeUplinkBandwidth();
+ method public long getMinRoamingDownlinkBandwidth();
+ method public long getMinRoamingUplinkBandwidth();
+ method public android.net.wifi.hotspot2.pps.UpdateParameter getPolicyUpdate();
+ method public java.util.List<android.net.wifi.hotspot2.pps.Policy.RoamingPartner> getPreferredRoamingPartnerList();
+ method public java.util.Map<java.lang.Integer, java.lang.String> getRequiredProtoPortMap();
+ method public void setExcludedSsidList(java.lang.String[]);
+ method public void setMaximumBssLoadValue(int);
+ method public void setMinHomeDownlinkBandwidth(long);
+ method public void setMinHomeUplinkBandwidth(long);
+ method public void setMinRoamingDownlinkBandwidth(long);
+ method public void setMinRoamingUplinkBandwidth(long);
+ method public void setPolicyUpdate(android.net.wifi.hotspot2.pps.UpdateParameter);
+ method public void setPreferredRoamingPartnerList(java.util.List<android.net.wifi.hotspot2.pps.Policy.RoamingPartner>);
+ method public void setRequiredProtoPortMap(java.util.Map<java.lang.Integer, java.lang.String>);
+ method public boolean validate();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.Policy> CREATOR;
+ }
+
+ public static final class Policy.RoamingPartner implements android.os.Parcelable {
+ ctor public Policy.RoamingPartner();
+ ctor public Policy.RoamingPartner(android.net.wifi.hotspot2.pps.Policy.RoamingPartner);
+ method public int describeContents();
+ method public java.lang.String getCountries();
+ method public java.lang.String getFqdn();
+ method public boolean getFqdnExactMatch();
+ method public int getPriority();
+ method public void setCountries(java.lang.String);
+ method public void setFqdn(java.lang.String);
+ method public void setFqdnExactMatch(boolean);
+ method public void setPriority(int);
+ method public boolean validate();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.Policy.RoamingPartner> CREATOR;
+ }
+
+ public final class UpdateParameter implements android.os.Parcelable {
+ ctor public UpdateParameter();
+ ctor public UpdateParameter(android.net.wifi.hotspot2.pps.UpdateParameter);
+ method public int describeContents();
+ method public java.lang.String getBase64EncodedPassword();
+ method public java.lang.String getRestriction();
+ method public java.lang.String getServerUri();
+ method public byte[] getTrustRootCertSha256Fingerprint();
+ method public java.lang.String getTrustRootCertUrl();
+ method public long getUpdateIntervalInMinutes();
+ method public java.lang.String getUpdateMethod();
+ method public java.lang.String getUsername();
+ method public void setBase64EncodedPassword(java.lang.String);
+ method public void setRestriction(java.lang.String);
+ method public void setServerUri(java.lang.String);
+ method public void setTrustRootCertSha256Fingerprint(byte[]);
+ method public void setTrustRootCertUrl(java.lang.String);
+ method public void setUpdateIntervalInMinutes(long);
+ method public void setUpdateMethod(java.lang.String);
+ method public void setUsername(java.lang.String);
+ method public boolean validate();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.UpdateParameter> CREATOR;
+ field public static final long UPDATE_CHECK_INTERVAL_NEVER = 4294967295L; // 0xffffffffL
+ field public static final java.lang.String UPDATE_METHOD_OMADM = "OMA-DM-ClientInitiated";
+ field public static final java.lang.String UPDATE_METHOD_SSP = "SSP-ClientInitiated";
+ field public static final java.lang.String UPDATE_RESTRICTION_HOMESP = "HomeSP";
+ field public static final java.lang.String UPDATE_RESTRICTION_ROAMING_PARTNER = "RoamingPartner";
+ field public static final java.lang.String UPDATE_RESTRICTION_UNRESTRICTED = "Unrestricted";
+ }
+
+}
+
package android.net.wifi.p2p {
public class WifiP2pConfig implements android.os.Parcelable {
@@ -35988,31 +36329,24 @@
ctor public AutoFillService();
method public final android.os.IBinder onBind(android.content.Intent);
method public void onConnected();
- method public void onDatasetAuthenticationRequest(android.os.Bundle, int);
method public void onDisconnected();
method public abstract void onFillRequest(android.app.assist.AssistStructure, android.os.Bundle, android.os.CancellationSignal, android.service.autofill.FillCallback);
- method public void onFillResponseAuthenticationRequest(android.os.Bundle, int);
method public abstract void onSaveRequest(android.app.assist.AssistStructure, android.os.Bundle, android.service.autofill.SaveCallback);
- field public static final java.lang.String EXTRA_DATASET_EXTRAS = "android.service.autofill.extra.DATASET_EXTRAS";
- field public static final java.lang.String EXTRA_RESPONSE_EXTRAS = "android.service.autofill.extra.RESPONSE_EXTRAS";
- field public static final int FLAG_AUTHENTICATION_ERROR = 4; // 0x4
- field public static final int FLAG_AUTHENTICATION_REQUESTED = 1; // 0x1
- field public static final int FLAG_AUTHENTICATION_SUCCESS = 2; // 0x2
- field public static final int FLAG_FINGERPRINT_AUTHENTICATION_NOT_AVAILABLE = 8; // 0x8
field public static final java.lang.String SERVICE_INTERFACE = "android.service.autofill.AutoFillService";
field public static final java.lang.String SERVICE_META_DATA = "android.autofill";
}
- public final class FillCallback {
- method public void onDatasetAuthentication(android.view.autofill.Dataset, int);
+ public final class FillCallback implements android.os.Parcelable {
+ method public int describeContents();
method public void onFailure(java.lang.CharSequence);
- method public void onFillResponseAuthentication(int);
method public void onSuccess(android.view.autofill.FillResponse);
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.service.autofill.FillCallback> CREATOR;
}
public final class SaveCallback {
method public void onFailure(java.lang.CharSequence);
- method public void onSuccess(android.view.autofill.AutoFillId[]);
+ method public void onSuccess();
}
}
@@ -41848,6 +42182,15 @@
method public android.transition.TransitionManager inflateTransitionManager(int, android.view.ViewGroup);
}
+ public abstract class TransitionListenerAdapter implements android.transition.Transition.TransitionListener {
+ ctor public TransitionListenerAdapter();
+ method public void onTransitionCancel(android.transition.Transition);
+ method public void onTransitionEnd(android.transition.Transition);
+ method public void onTransitionPause(android.transition.Transition);
+ method public void onTransitionResume(android.transition.Transition);
+ method public void onTransitionStart(android.transition.Transition);
+ }
+
public class TransitionManager {
ctor public TransitionManager();
method public static void beginDelayedTransition(android.view.ViewGroup);
@@ -44414,8 +44757,8 @@
method public void drawableHotspotChanged(float, float);
method protected void drawableStateChanged();
method public android.view.View findFocus();
- method public final <T extends android.view.View> T findViewById(int);
- method public final <T extends android.view.View> T findViewWithTag(java.lang.Object);
+ method public final android.view.View findViewById(int);
+ method public final android.view.View findViewWithTag(java.lang.Object);
method public void findViewsWithText(java.util.ArrayList<android.view.View>, java.lang.CharSequence, int);
method protected deprecated boolean fitSystemWindows(android.graphics.Rect);
method public android.view.View focusSearch(int);
@@ -44431,7 +44774,8 @@
method public android.view.animation.Animation getAnimation();
method public android.os.IBinder getApplicationWindowToken();
method public android.view.autofill.AutoFillType getAutoFillType();
- method public android.view.autofill.VirtualViewDelegate getAutoFillVirtualViewDelegate(android.view.autofill.VirtualViewDelegate.Callback);
+ method public android.view.autofill.AutoFillValue getAutoFillValue();
+ method public android.view.autofill.VirtualViewDelegate getAutoFillVirtualViewDelegate();
method public android.graphics.drawable.Drawable getBackground();
method public android.content.res.ColorStateList getBackgroundTintList();
method public android.graphics.PorterDuff.Mode getBackgroundTintMode();
@@ -44885,8 +45229,6 @@
field public static final int ACCESSIBILITY_LIVE_REGION_NONE = 0; // 0x0
field public static final int ACCESSIBILITY_LIVE_REGION_POLITE = 1; // 0x1
field public static final android.util.Property<android.view.View, java.lang.Float> ALPHA;
- field public static final int AUTO_FILL_FLAG_TYPE_FILL = 268435456; // 0x10000000
- field public static final int AUTO_FILL_FLAG_TYPE_SAVE = 536870912; // 0x20000000
field public static final int DRAG_FLAG_GLOBAL = 256; // 0x100
field public static final int DRAG_FLAG_GLOBAL_PERSISTABLE_URI_PERMISSION = 64; // 0x40
field public static final int DRAG_FLAG_GLOBAL_PREFIX_URI_PERMISSION = 128; // 0x80
@@ -45527,7 +45869,7 @@
method public abstract int addChildCount(int);
method public abstract void asyncCommit();
method public abstract android.view.ViewStructure asyncNewChild(int);
- method public abstract android.view.ViewStructure asyncNewChild(int, int);
+ method public abstract android.view.ViewStructure asyncNewChild(int, int, int);
method public abstract int getChildCount();
method public abstract android.os.Bundle getExtras();
method public abstract java.lang.CharSequence getHint();
@@ -45536,11 +45878,12 @@
method public abstract int getTextSelectionStart();
method public abstract boolean hasExtras();
method public abstract android.view.ViewStructure newChild(int);
- method public abstract android.view.ViewStructure newChild(int, int);
+ method public abstract android.view.ViewStructure newChild(int, int, int);
method public abstract void setAccessibilityFocused(boolean);
method public abstract void setActivated(boolean);
method public abstract void setAlpha(float);
method public abstract void setAutoFillType(android.view.autofill.AutoFillType);
+ method public abstract void setAutoFillValue(android.view.autofill.AutoFillValue);
method public abstract void setCheckable(boolean);
method public abstract void setChecked(boolean);
method public abstract void setChildCount(int);
@@ -45563,6 +45906,7 @@
method public abstract void setTextStyle(float, int, int, int);
method public abstract void setTransformation(android.graphics.Matrix);
method public abstract void setVisibility(int);
+ field public static final int AUTO_FILL_FLAG_SANITIZED = 1; // 0x1
}
public final class ViewStub extends android.view.View {
@@ -45996,6 +46340,7 @@
field public static final int TYPE_APPLICATION = 2; // 0x2
field public static final int TYPE_APPLICATION_ATTACHED_DIALOG = 1003; // 0x3eb
field public static final int TYPE_APPLICATION_MEDIA = 1001; // 0x3e9
+ field public static final int TYPE_APPLICATION_OVERLAY = 2038; // 0x7f6
field public static final int TYPE_APPLICATION_PANEL = 1000; // 0x3e8
field public static final int TYPE_APPLICATION_STARTING = 3; // 0x3
field public static final int TYPE_APPLICATION_SUB_PANEL = 1002; // 0x3ea
@@ -46005,17 +46350,17 @@
field public static final int TYPE_INPUT_METHOD = 2011; // 0x7db
field public static final int TYPE_INPUT_METHOD_DIALOG = 2012; // 0x7dc
field public static final int TYPE_KEYGUARD_DIALOG = 2009; // 0x7d9
- field public static final int TYPE_PHONE = 2002; // 0x7d2
- field public static final int TYPE_PRIORITY_PHONE = 2007; // 0x7d7
+ field public static final deprecated int TYPE_PHONE = 2002; // 0x7d2
+ field public static final deprecated int TYPE_PRIORITY_PHONE = 2007; // 0x7d7
field public static final int TYPE_PRIVATE_PRESENTATION = 2030; // 0x7ee
field public static final int TYPE_SEARCH_BAR = 2001; // 0x7d1
field public static final int TYPE_STATUS_BAR = 2000; // 0x7d0
field public static final int TYPE_STATUS_BAR_PANEL = 2014; // 0x7de
- field public static final int TYPE_SYSTEM_ALERT = 2003; // 0x7d3
+ field public static final deprecated int TYPE_SYSTEM_ALERT = 2003; // 0x7d3
field public static final int TYPE_SYSTEM_DIALOG = 2008; // 0x7d8
- field public static final int TYPE_SYSTEM_ERROR = 2010; // 0x7da
- field public static final int TYPE_SYSTEM_OVERLAY = 2006; // 0x7d6
- field public static final int TYPE_TOAST = 2005; // 0x7d5
+ field public static final deprecated int TYPE_SYSTEM_ERROR = 2010; // 0x7da
+ field public static final deprecated int TYPE_SYSTEM_OVERLAY = 2006; // 0x7d6
+ field public static final deprecated int TYPE_TOAST = 2005; // 0x7d5
field public static final int TYPE_WALLPAPER = 2013; // 0x7dd
field public float alpha;
field public float buttonBrightness;
@@ -46794,10 +47139,11 @@
}
public final class AutoFillManager {
- method public void updateAutoFillInput(android.view.View, int);
- method public void updateAutoFillInput(android.view.View, int, android.graphics.Rect, int);
- field public static final int FLAG_UPDATE_UI_HIDE = 2; // 0x2
- field public static final int FLAG_UPDATE_UI_SHOW = 1; // 0x1
+ method public void focusChanged(android.view.View, boolean);
+ method public void reset();
+ method public void valueChanged(android.view.View);
+ method public void virtualFocusChanged(android.view.View, int, android.graphics.Rect, android.view.autofill.AutoFillValue, boolean);
+ method public void virtualValueChanged(android.view.View, int, android.view.autofill.AutoFillValue);
}
public final class AutoFillType implements android.os.Parcelable {
@@ -46832,10 +47178,9 @@
}
public static final class Dataset.Builder {
- ctor public Dataset.Builder(java.lang.CharSequence);
+ ctor public Dataset.Builder(java.lang.String, java.lang.CharSequence);
method public android.view.autofill.Dataset build();
- method public android.view.autofill.Dataset.Builder requiresCustomAuthentication(android.os.Bundle, int);
- method public android.view.autofill.Dataset.Builder requiresFingerprintAuthentication(android.hardware.fingerprint.FingerprintManager.CryptoObject, android.os.Bundle, int);
+ method public android.view.autofill.Dataset.Builder setAuthentication(android.content.IntentSender);
method public android.view.autofill.Dataset.Builder setExtras(android.os.Bundle);
method public android.view.autofill.Dataset.Builder setValue(android.view.autofill.AutoFillId, android.view.autofill.AutoFillValue);
}
@@ -46847,12 +47192,11 @@
}
public static final class FillResponse.Builder {
- ctor public FillResponse.Builder();
+ ctor public FillResponse.Builder(java.lang.String);
method public android.view.autofill.FillResponse.Builder addDataset(android.view.autofill.Dataset);
method public android.view.autofill.FillResponse.Builder addSavableFields(android.view.autofill.AutoFillId...);
method public android.view.autofill.FillResponse build();
- method public android.view.autofill.FillResponse.Builder requiresCustomAuthentication(android.os.Bundle, int);
- method public android.view.autofill.FillResponse.Builder requiresFingerprintAuthentication(android.hardware.fingerprint.FingerprintManager.CryptoObject, android.os.Bundle, int);
+ method public android.view.autofill.FillResponse.Builder setAuthentication(android.content.IntentSender);
method public android.view.autofill.FillResponse.Builder setExtras(android.os.Bundle);
}
@@ -46861,13 +47205,6 @@
method public abstract void autoFill(int, android.view.autofill.AutoFillValue);
}
- public static abstract class VirtualViewDelegate.Callback {
- ctor public VirtualViewDelegate.Callback();
- method public void onAutoFillInputUpdated(int, android.graphics.Rect, int);
- method public void onNodeRemoved(int...);
- method public void onValueChanged(int);
- }
-
}
package android.view.inputmethod {
@@ -47278,7 +47615,7 @@
public final class TextClassificationManager {
method public java.util.List<android.view.textclassifier.TextLanguage> detectLanguages(java.lang.CharSequence);
- method public android.view.textclassifier.TextClassifier getDefaultTextClassifier();
+ method public synchronized android.view.textclassifier.TextClassifier getDefaultTextClassifier();
}
public final class TextClassificationResult {
@@ -50621,6 +50958,7 @@
method public void setIs24HourView(java.lang.Boolean);
method public void setMinute(int);
method public void setOnTimeChangedListener(android.widget.TimePicker.OnTimeChangedListener);
+ method public boolean validateInput();
field public static final int MODE_CLOCK = 2; // 0x2
field public static final int MODE_SPINNER = 1; // 0x1
}
@@ -51022,6 +51360,8 @@
field public static final int OP_INVOKE_INTERFACE = 114; // 0x72
field public static final int OP_INVOKE_INTERFACE_JUMBO = 9983; // 0x26ff
field public static final int OP_INVOKE_INTERFACE_RANGE = 120; // 0x78
+ field public static final int OP_INVOKE_POLYMORPHIC = 250; // 0xfa
+ field public static final int OP_INVOKE_POLYMORPHIC_RANGE = 251; // 0xfb
field public static final int OP_INVOKE_STATIC = 113; // 0x71
field public static final int OP_INVOKE_STATIC_JUMBO = 9727; // 0x25ff
field public static final int OP_INVOKE_STATIC_RANGE = 119; // 0x77
@@ -54316,12 +54656,15 @@
}
public abstract class MethodHandle {
+ method public java.lang.invoke.MethodHandle asCollector(java.lang.Class<?>, int);
method public java.lang.invoke.MethodHandle asFixedArity();
+ method public java.lang.invoke.MethodHandle asSpreader(java.lang.Class<?>, int);
method public java.lang.invoke.MethodHandle asType(java.lang.invoke.MethodType);
method public java.lang.invoke.MethodHandle asVarargsCollector(java.lang.Class<?>);
method public java.lang.invoke.MethodHandle bindTo(java.lang.Object);
method public final java.lang.Object invoke(java.lang.Object...) throws java.lang.Throwable;
method public final java.lang.Object invokeExact(java.lang.Object...) throws java.lang.Throwable;
+ method public java.lang.Object invokeWithArguments(java.lang.Object...) throws java.lang.Throwable;
method public java.lang.Object invokeWithArguments(java.util.List<?>) throws java.lang.Throwable;
method public boolean isVarargsCollector();
method public java.lang.invoke.MethodType type();
@@ -54355,17 +54698,23 @@
method public static java.lang.invoke.MethodHandle arrayElementGetter(java.lang.Class<?>) throws java.lang.IllegalArgumentException;
method public static java.lang.invoke.MethodHandle arrayElementSetter(java.lang.Class<?>) throws java.lang.IllegalArgumentException;
method public static java.lang.invoke.MethodHandle catchException(java.lang.invoke.MethodHandle, java.lang.Class<? extends java.lang.Throwable>, java.lang.invoke.MethodHandle);
+ method public static java.lang.invoke.MethodHandle collectArguments(java.lang.invoke.MethodHandle, int, java.lang.invoke.MethodHandle);
method public static java.lang.invoke.MethodHandle constant(java.lang.Class<?>, java.lang.Object);
method public static java.lang.invoke.MethodHandle dropArguments(java.lang.invoke.MethodHandle, int, java.util.List<java.lang.Class<?>>);
method public static java.lang.invoke.MethodHandle dropArguments(java.lang.invoke.MethodHandle, int, java.lang.Class<?>...);
method public static java.lang.invoke.MethodHandle exactInvoker(java.lang.invoke.MethodType);
+ method public static java.lang.invoke.MethodHandle filterArguments(java.lang.invoke.MethodHandle, int, java.lang.invoke.MethodHandle...);
method public static java.lang.invoke.MethodHandle filterReturnValue(java.lang.invoke.MethodHandle, java.lang.invoke.MethodHandle);
+ method public static java.lang.invoke.MethodHandle foldArguments(java.lang.invoke.MethodHandle, java.lang.invoke.MethodHandle);
method public static java.lang.invoke.MethodHandle guardWithTest(java.lang.invoke.MethodHandle, java.lang.invoke.MethodHandle, java.lang.invoke.MethodHandle);
method public static java.lang.invoke.MethodHandle identity(java.lang.Class<?>);
+ method public static java.lang.invoke.MethodHandle insertArguments(java.lang.invoke.MethodHandle, int, java.lang.Object...);
method public static java.lang.invoke.MethodHandle invoker(java.lang.invoke.MethodType);
method public static java.lang.invoke.MethodHandles.Lookup lookup();
method public static java.lang.invoke.MethodHandle permuteArguments(java.lang.invoke.MethodHandle, java.lang.invoke.MethodType, int...);
method public static java.lang.invoke.MethodHandles.Lookup publicLookup();
+ method public static <T extends java.lang.reflect.Member> T reflectAs(java.lang.Class<T>, java.lang.invoke.MethodHandle);
+ method public static java.lang.invoke.MethodHandle spreadInvoker(java.lang.invoke.MethodType, int);
method public static java.lang.invoke.MethodHandle throwException(java.lang.Class<?>, java.lang.Class<? extends java.lang.Throwable>);
}
@@ -54382,6 +54731,7 @@
method public java.lang.invoke.MethodHandles.Lookup in(java.lang.Class<?>);
method public java.lang.Class<?> lookupClass();
method public int lookupModes();
+ method public java.lang.invoke.MethodHandleInfo revealDirect(java.lang.invoke.MethodHandle);
method public void throwMakeAccessException(java.lang.String, java.lang.Object) throws java.lang.IllegalAccessException;
method public java.lang.invoke.MethodHandle unreflect(java.lang.reflect.Method) throws java.lang.IllegalAccessException;
method public java.lang.invoke.MethodHandle unreflectConstructor(java.lang.reflect.Constructor<?>) throws java.lang.IllegalAccessException;
diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp
index c773275..7901737 100644
--- a/cmds/bootanimation/BootAnimation.cpp
+++ b/cmds/bootanimation/BootAnimation.cpp
@@ -18,6 +18,7 @@
#define LOG_TAG "BootAnimation"
#include <stdint.h>
+#include <inttypes.h>
#include <sys/inotify.h>
#include <sys/poll.h>
#include <sys/stat.h>
@@ -35,6 +36,7 @@
#include <utils/Atomic.h>
#include <utils/Errors.h>
#include <utils/Log.h>
+#include <utils/SystemClock.h>
#include <ui/PixelFormat.h>
#include <ui/Rect.h>
@@ -350,6 +352,7 @@
bool BootAnimation::android()
{
+ ALOGD("BootAnimationShownTiming: BootAnimation start time: %" PRId64 "ms", elapsedRealtime());
initTexture(&mAndroid[0], mAssets, "images/android-logo-mask.png");
initTexture(&mAndroid[1], mAssets, "images/android-logo-shine.png");
@@ -854,8 +857,8 @@
mTimeCheckThread = nullptr;
}
+ // We should have joined mInitAudioThread thread in playAnimation
if (mInitAudioThread != nullptr) {
- mInitAudioThread->requestExit();
mInitAudioThread = nullptr;
}
@@ -875,6 +878,7 @@
const int animationX = (mWidth - animation.width) / 2;
const int animationY = (mHeight - animation.height) / 2;
+ ALOGD("BootAnimationShownTiming: BootAnimation start time: %" PRId64 "ms", elapsedRealtime());
for (size_t i=0 ; i<pcount ; i++) {
const Animation::Part& part(animation.parts[i]);
const size_t fcount = part.frames.size();
diff --git a/compiled-classes-phone b/compiled-classes-phone
index e4ffaa3..ea8f4a4 100644
--- a/compiled-classes-phone
+++ b/compiled-classes-phone
@@ -1,5 +1,5 @@
#
-# Copyright (C) 2016 The Android Open Source Project
+# Copyright (C) 2017 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -31,7 +31,6 @@
android.R$styleable
android.accessibilityservice.AccessibilityServiceInfo
android.accessibilityservice.AccessibilityServiceInfo$1
-android.accessibilityservice.AccessibilityServiceInfo$CapabilityInfo
android.accessibilityservice.IAccessibilityServiceClient
android.accessibilityservice.IAccessibilityServiceConnection
android.accessibilityservice.IAccessibilityServiceConnection$Stub
@@ -58,6 +57,8 @@
android.accounts.AccountManager$Future2Task$1
android.accounts.AccountManagerCallback
android.accounts.AccountManagerFuture
+android.accounts.AccountManagerInternal
+android.accounts.AccountManagerInternal$OnAppPermissionChangeListener
android.accounts.AccountsException
android.accounts.AuthenticatorDescription
android.accounts.AuthenticatorDescription$1
@@ -78,7 +79,6 @@
android.accounts.OperationCanceledException
android.animation.AnimationHandler
android.animation.AnimationHandler$1
-android.animation.AnimationHandler$2
android.animation.AnimationHandler$AnimationFrameCallback
android.animation.AnimationHandler$AnimationFrameCallbackProvider
android.animation.AnimationHandler$MyFrameCallbackProvider
@@ -90,9 +90,13 @@
android.animation.AnimatorInflater$PathDataEvaluator
android.animation.AnimatorListenerAdapter
android.animation.AnimatorSet
-android.animation.AnimatorSet$AnimatorSetListener
+android.animation.AnimatorSet$1
+android.animation.AnimatorSet$2
+android.animation.AnimatorSet$3
+android.animation.AnimatorSet$AnimationEvent
android.animation.AnimatorSet$Builder
android.animation.AnimatorSet$Node
+android.animation.AnimatorSet$SeekState
android.animation.ArgbEvaluator
android.animation.FloatArrayEvaluator
android.animation.FloatEvaluator
@@ -119,14 +123,15 @@
android.animation.PathKeyframes
android.animation.PathKeyframes$1
android.animation.PathKeyframes$2
-android.animation.PathKeyframes$3
-android.animation.PathKeyframes$4
android.animation.PathKeyframes$FloatKeyframesBase
android.animation.PathKeyframes$IntKeyframesBase
android.animation.PathKeyframes$SimpleKeyframes
android.animation.PropertyValuesHolder
+android.animation.PropertyValuesHolder$1
android.animation.PropertyValuesHolder$FloatPropertyValuesHolder
android.animation.PropertyValuesHolder$IntPropertyValuesHolder
+android.animation.PropertyValuesHolder$PropertyValues
+android.animation.PropertyValuesHolder$PropertyValues$DataSource
android.animation.RectEvaluator
android.animation.RevealAnimator
android.animation.StateListAnimator
@@ -139,22 +144,25 @@
android.animation.TypeEvaluator
android.animation.ValueAnimator
android.animation.ValueAnimator$AnimatorUpdateListener
-android.annotation.TargetApi
+android.app.-$Lambda$36$c44uHH2WE4sJvw5tZZB6gRzEaHI
+android.app.-$Lambda$39$c44uHH2WE4sJvw5tZZB6gRzEaHI
+android.app.-$Lambda$57$vZ1qb742P9hE4drBY-TrOZB_qKo
+android.app.-$Lambda$7$u_rp3dnwvfyMTggc6hVftcuYJ3E
+android.app.-$Lambda$71$3eJ3p8XnIxdVOnT82Ns3R0V5ZQE
+android.app.-$Lambda$76$3eJ3p8XnIxdVOnT82Ns3R0V5ZQE
android.app.ActionBar
android.app.ActionBar$LayoutParams
android.app.ActionBar$OnMenuVisibilityListener
-android.app.ActionBar$OnNavigationListener
android.app.ActionBar$Tab
android.app.ActionBar$TabListener
android.app.Activity
android.app.Activity$HostCallbacks
-android.app.Activity$NonConfigurationInstances
android.app.ActivityManager
+android.app.ActivityManager$1
android.app.ActivityManager$AppTask
android.app.ActivityManager$MemoryInfo
android.app.ActivityManager$MemoryInfo$1
-android.app.ActivityManager$ProcessErrorStateInfo
-android.app.ActivityManager$ProcessErrorStateInfo$1
+android.app.ActivityManager$OnUidImportanceListener
android.app.ActivityManager$RecentTaskInfo
android.app.ActivityManager$RecentTaskInfo$1
android.app.ActivityManager$RunningAppProcessInfo
@@ -168,10 +176,12 @@
android.app.ActivityManager$StackInfo$1
android.app.ActivityManager$TaskDescription
android.app.ActivityManager$TaskDescription$1
+android.app.ActivityManager$TaskSnapshot
+android.app.ActivityManager$TaskSnapshot$1
android.app.ActivityManager$TaskThumbnail
-android.app.ActivityManager$TaskThumbnail$1
android.app.ActivityManager$TaskThumbnailInfo
android.app.ActivityManager$TaskThumbnailInfo$1
+android.app.ActivityManager$UidObserver
android.app.ActivityManagerInternal
android.app.ActivityManagerInternal$SleepToken
android.app.ActivityOptions
@@ -189,6 +199,7 @@
android.app.ActivityThread$ContextCleanupInfo
android.app.ActivityThread$CreateServiceData
android.app.ActivityThread$DropBoxReporter
+android.app.ActivityThread$DumpComponentInfo
android.app.ActivityThread$EventLoggingReporter
android.app.ActivityThread$GcIdler
android.app.ActivityThread$H
@@ -199,18 +210,13 @@
android.app.ActivityThread$ProviderKey
android.app.ActivityThread$ProviderRefCount
android.app.ActivityThread$ReceiverData
+android.app.ActivityThread$RequestAssistContextExtras
android.app.ActivityThread$ResultData
android.app.ActivityThread$ServiceArgsData
android.app.ActivityThread$StopInfo
-android.app.ActivityTransitionCoordinator
-android.app.ActivityTransitionCoordinator$1
-android.app.ActivityTransitionCoordinator$2
-android.app.ActivityTransitionCoordinator$ContinueTransitionListener
-android.app.ActivityTransitionCoordinator$FixedEpicenterCallback
-android.app.ActivityTransitionCoordinator$SharedElementOriginalState
android.app.ActivityTransitionState
+android.app.AlarmManager
android.app.AlarmManager$AlarmClockInfo
-android.app.AlarmManager$AlarmClockInfo$1
android.app.AlarmManager$ListenerWrapper
android.app.AlarmManager$OnAlarmListener
android.app.AlertDialog
@@ -227,71 +233,59 @@
android.app.Application
android.app.Application$ActivityLifecycleCallbacks
android.app.ApplicationErrorReport
-android.app.ApplicationErrorReport$1
android.app.ApplicationErrorReport$CrashInfo
+android.app.ApplicationErrorReport$ParcelableCrashInfo
android.app.ApplicationLoaders
android.app.ApplicationPackageManager
android.app.ApplicationPackageManager$MoveCallbackDelegate
android.app.ApplicationPackageManager$OnPermissionsChangeListenerDelegate
android.app.ApplicationPackageManager$ResourceName
-android.app.ApplicationThreadProxy
android.app.AutomaticZenRule
android.app.BackStackRecord
android.app.BackStackRecord$Op
-android.app.BackStackRecord$TransitionState
-android.app.BackStackState
-android.app.BackStackState$1
android.app.BroadcastOptions
android.app.ContentProviderHolder
android.app.ContentProviderHolder$1
android.app.ContextImpl
-android.app.ContextImpl$1
android.app.ContextImpl$ApplicationContentResolver
android.app.DatePickerDialog
android.app.DatePickerDialog$OnDateSetListener
android.app.Dialog
-android.app.Dialog$-void__init__android_content_Context_context_int_themeResId_boolean_createContextThemeWrapper_LambdaImpl0
android.app.Dialog$ListenersHandler
android.app.DialogFragment
android.app.DownloadManager
android.app.DownloadManager$CursorTranslator
android.app.DownloadManager$Query
android.app.DownloadManager$Request
-android.app.EnterTransitionCoordinator
-android.app.EnterTransitionCoordinator$1
-android.app.EnterTransitionCoordinator$4
-android.app.EnterTransitionCoordinator$5
-android.app.EnterTransitionCoordinator$5$1
-android.app.EnterTransitionCoordinator$5$1$1
-android.app.EnterTransitionCoordinator$6
-android.app.EnterTransitionCoordinator$7
-android.app.EnterTransitionCoordinator$8
-android.app.ExitTransitionCoordinator
-android.app.ExitTransitionCoordinator$10
-android.app.ExitTransitionCoordinator$11
-android.app.ExitTransitionCoordinator$4
android.app.Fragment
android.app.Fragment$1
+android.app.Fragment$AnimationInfo
+android.app.Fragment$OnStartEnterTransitionListener
android.app.Fragment$SavedState
-android.app.FragmentBreadCrumbs
android.app.FragmentContainer
android.app.FragmentController
android.app.FragmentHostCallback
android.app.FragmentManager
android.app.FragmentManager$BackStackEntry
+android.app.FragmentManager$FragmentLifecycleCallbacks
android.app.FragmentManager$OnBackStackChangedListener
android.app.FragmentManagerImpl
android.app.FragmentManagerImpl$1
android.app.FragmentManagerImpl$2
-android.app.FragmentManagerImpl$3
-android.app.FragmentManagerImpl$4
-android.app.FragmentManagerImpl$5
android.app.FragmentManagerImpl$AnimateOnHWLayerIfNeededListener
+android.app.FragmentManagerImpl$OpGenerator
+android.app.FragmentManagerImpl$PopBackStackState
+android.app.FragmentManagerImpl$StartEnterTransitionListener
android.app.FragmentManagerState
android.app.FragmentManagerState$1
android.app.FragmentState
android.app.FragmentState$1
android.app.FragmentTransaction
+android.app.FragmentTransition
+android.app.FragmentTransition$3
+android.app.FragmentTransition$4
+android.app.FragmentTransition$5
+android.app.FragmentTransition$FragmentContainerTransition
android.app.IActivityContainer
android.app.IActivityContainer$Stub
android.app.IActivityContainerCallback
@@ -356,12 +350,11 @@
android.app.JobSchedulerImpl
android.app.KeyguardManager
android.app.ListActivity
-android.app.ListActivity$1
-android.app.ListActivity$2
android.app.ListFragment
android.app.ListFragment$1
android.app.ListFragment$2
android.app.LoadedApk
+android.app.LoadedApk$DexLoadReporter
android.app.LoadedApk$ReceiverDispatcher
android.app.LoadedApk$ReceiverDispatcher$Args
android.app.LoadedApk$ReceiverDispatcher$InnerReceiver
@@ -391,26 +384,34 @@
android.app.Notification$InboxStyle
android.app.Notification$MediaStyle
android.app.Notification$MessagingStyle
+android.app.Notification$MessagingStyle$Message
+android.app.Notification$StandardTemplateParams
android.app.Notification$Style
android.app.Notification$WearableExtender
+android.app.NotificationChannel
+android.app.NotificationChannel$1
android.app.NotificationManager
android.app.NotificationManager$Policy
android.app.NotificationManager$Policy$1
android.app.OnActivityPausedListener
-android.app.PackageDeleteObserver
-android.app.PackageDeleteObserver$1
-android.app.PackageInstallObserver
-android.app.PackageInstallObserver$1
android.app.PendingIntent
android.app.PendingIntent$1
android.app.PendingIntent$CanceledException
android.app.PendingIntent$FinishedDispatcher
android.app.PendingIntent$OnFinished
+android.app.PendingIntent$OnMarshaledListener
+android.app.PictureInPictureArgs
+android.app.PictureInPictureArgs$1
android.app.Presentation
android.app.ProfilerInfo
android.app.ProgressDialog
android.app.QueuedWork
+android.app.QueuedWork$QueuedWorkHandler
android.app.ReceiverRestrictedContext
+android.app.RemoteAction
+android.app.RemoteAction$1
+android.app.RemoteAction$2
+android.app.RemoteAction$OnActionListener
android.app.RemoteInput
android.app.RemoteInput$1
android.app.RemoteInput$Builder
@@ -419,13 +420,14 @@
android.app.ResourcesManager$ActivityResources
android.app.ResultInfo
android.app.ResultInfo$1
+android.app.RetailDemoModeServiceInternal
+android.app.SearchManager
android.app.SearchableInfo
android.app.SearchableInfo$1
android.app.Service
android.app.ServiceConnectionLeaked
android.app.SharedElementCallback
android.app.SharedElementCallback$1
-android.app.SharedElementCallback$OnSharedElementsReadyListener
android.app.SharedPreferencesImpl
android.app.SharedPreferencesImpl$1
android.app.SharedPreferencesImpl$2
@@ -509,6 +511,11 @@
android.app.SystemServiceRegistry$72
android.app.SystemServiceRegistry$73
android.app.SystemServiceRegistry$74
+android.app.SystemServiceRegistry$75
+android.app.SystemServiceRegistry$76
+android.app.SystemServiceRegistry$77
+android.app.SystemServiceRegistry$78
+android.app.SystemServiceRegistry$79
android.app.SystemServiceRegistry$8
android.app.SystemServiceRegistry$9
android.app.SystemServiceRegistry$CachedServiceFetcher
@@ -516,29 +523,43 @@
android.app.SystemServiceRegistry$StaticApplicationContextServiceFetcher
android.app.SystemServiceRegistry$StaticServiceFetcher
android.app.TaskStackBuilder
-android.app.TimePickerDialog
+android.app.TaskStackListener
android.app.TimePickerDialog$OnTimeSetListener
android.app.UiModeManager
-android.app.WaitResult;
+android.app.UserSwitchObserver
+android.app.VoiceInteractor$PickOptionRequest$Option
+android.app.WaitResult
android.app.WallpaperInfo
+android.app.WallpaperInfo$1
android.app.WallpaperManager
android.app.WallpaperManager$Globals
-android.app.admin.DeviceAdminInfo
-android.app.admin.DeviceAdminInfo$1
-android.app.admin.DeviceAdminInfo$PolicyInfo
android.app.admin.DevicePolicyManager
android.app.admin.DevicePolicyManagerInternal
android.app.admin.DevicePolicyManagerInternal$OnCrossProfileWidgetProvidersChangeListener
android.app.admin.IDevicePolicyManager
android.app.admin.IDevicePolicyManager$Stub
android.app.admin.IDevicePolicyManager$Stub$Proxy
+android.app.admin.PasswordMetrics
+android.app.admin.PasswordMetrics$1
android.app.admin.SecurityLog
android.app.admin.SecurityLog$SecurityEvent
android.app.admin.SecurityLog$SecurityEvent$1
+android.app.admin.SystemUpdateInfo
+android.app.admin.SystemUpdateInfo$1
android.app.admin.SystemUpdatePolicy
android.app.admin.SystemUpdatePolicy$1
android.app.assist.AssistContent
+android.app.assist.AssistContent$1
android.app.assist.AssistStructure
+android.app.assist.AssistStructure$1
+android.app.assist.AssistStructure$ParcelTransferReader
+android.app.assist.AssistStructure$ParcelTransferWriter
+android.app.assist.AssistStructure$SendChannel
+android.app.assist.AssistStructure$ViewNode
+android.app.assist.AssistStructure$ViewNodeBuilder
+android.app.assist.AssistStructure$ViewNodeText
+android.app.assist.AssistStructure$ViewStackEntry
+android.app.assist.AssistStructure$WindowNode
android.app.backup.BackupAgent
android.app.backup.BackupAgentHelper
android.app.backup.BackupDataInput
@@ -559,6 +580,7 @@
android.app.backup.IBackupObserver
android.app.backup.IFullBackupRestoreObserver
android.app.backup.IRestoreSession
+android.app.backup.ISelectBackupTransportCallback
android.app.backup.RestoreDescription
android.app.backup.RestoreSet
android.app.backup.SharedPreferencesBackupHelper
@@ -597,10 +619,15 @@
android.app.trust.TrustManager$TrustListener
android.app.usage.ConfigurationStats
android.app.usage.ConfigurationStats$1
+android.app.usage.ExternalStorageStats
+android.app.usage.IStorageStatsManager
+android.app.usage.IStorageStatsManager$Stub
android.app.usage.IUsageStatsManager
android.app.usage.IUsageStatsManager$Stub
android.app.usage.IUsageStatsManager$Stub$Proxy
android.app.usage.NetworkStatsManager
+android.app.usage.StorageStats
+android.app.usage.StorageStatsManager
android.app.usage.TimeSparseArray
android.app.usage.UsageEvents
android.app.usage.UsageEvents$1
@@ -626,18 +653,15 @@
android.bluetooth.BluetoothActivityEnergyInfo$1
android.bluetooth.BluetoothAdapter
android.bluetooth.BluetoothAdapter$1
-android.bluetooth.BluetoothAdapter$2
-android.bluetooth.BluetoothAdapter$BluetoothStateChangeCallback
-android.bluetooth.BluetoothAdapter$LeScanCallback
-android.bluetooth.BluetoothAudioConfig
android.bluetooth.BluetoothClass
android.bluetooth.BluetoothClass$1
android.bluetooth.BluetoothCodecConfig
+android.bluetooth.BluetoothCodecConfig$1
android.bluetooth.BluetoothCodecStatus
+android.bluetooth.BluetoothCodecStatus$1
android.bluetooth.BluetoothDevice
android.bluetooth.BluetoothDevice$1
android.bluetooth.BluetoothDevice$2
-android.bluetooth.BluetoothGattCallbackWrapper
android.bluetooth.BluetoothGattCharacteristic
android.bluetooth.BluetoothGattDescriptor
android.bluetooth.BluetoothGattService
@@ -674,8 +698,6 @@
android.bluetooth.IBluetoothA2dp
android.bluetooth.IBluetoothA2dp$Stub
android.bluetooth.IBluetoothA2dp$Stub$Proxy
-android.bluetooth.IBluetoothA2dpSink
-android.bluetooth.IBluetoothA2dpSink$Stub
android.bluetooth.IBluetoothCallback
android.bluetooth.IBluetoothCallback$Stub
android.bluetooth.IBluetoothCallback$Stub$Proxy
@@ -683,14 +705,10 @@
android.bluetooth.IBluetoothGatt$Stub
android.bluetooth.IBluetoothGatt$Stub$Proxy
android.bluetooth.IBluetoothGattCallback
-android.bluetooth.IBluetoothGattCallback$Stub
-android.bluetooth.IBluetoothGattCallback$Stub$Proxy
android.bluetooth.IBluetoothGattServerCallback
android.bluetooth.IBluetoothHeadset
android.bluetooth.IBluetoothHeadset$Stub
android.bluetooth.IBluetoothHeadset$Stub$Proxy
-android.bluetooth.IBluetoothHeadsetClient
-android.bluetooth.IBluetoothHeadsetClient$Stub
android.bluetooth.IBluetoothHeadsetPhone
android.bluetooth.IBluetoothHeadsetPhone$Stub
android.bluetooth.IBluetoothHeadsetPhone$Stub$Proxy
@@ -715,8 +733,6 @@
android.bluetooth.IBluetoothPbap
android.bluetooth.IBluetoothPbap$Stub
android.bluetooth.IBluetoothPbap$Stub$Proxy
-android.bluetooth.IBluetoothPbapClient
-android.bluetooth.IBluetoothPbapClient$Stub
android.bluetooth.IBluetoothProfileServiceConnection
android.bluetooth.IBluetoothProfileServiceConnection$Stub
android.bluetooth.IBluetoothProfileServiceConnection$Stub$Proxy
@@ -736,11 +752,15 @@
android.bluetooth.UidTraffic$1
android.bluetooth.le.AdvertiseData
android.bluetooth.le.AdvertiseSettings
-android.bluetooth.le.BluetoothLeAdvertiser
android.bluetooth.le.BluetoothLeScanner
android.bluetooth.le.BluetoothLeScanner$BleScanCallbackWrapper
android.bluetooth.le.BluetoothLeScanner$BleScanCallbackWrapper$1
+android.bluetooth.le.BluetoothLeScanner$BleScanCallbackWrapper$2
android.bluetooth.le.BluetoothLeUtils
+android.bluetooth.le.IAdvertiserCallback
+android.bluetooth.le.IScannerCallback
+android.bluetooth.le.IScannerCallback$Stub
+android.bluetooth.le.IScannerCallback$Stub$Proxy
android.bluetooth.le.ScanCallback
android.bluetooth.le.ScanFilter
android.bluetooth.le.ScanFilter$1
@@ -826,6 +846,7 @@
android.content.IIntentSender$Stub$Proxy
android.content.IOnPrimaryClipChangedListener
android.content.IOnPrimaryClipChangedListener$Stub
+android.content.IOnPrimaryClipChangedListener$Stub$Proxy
android.content.IRestrictionsManager
android.content.IRestrictionsManager$Stub
android.content.IRestrictionsManager$Stub$Proxy
@@ -841,14 +862,11 @@
android.content.Intent
android.content.Intent$1
android.content.Intent$FilterComparison
-android.content.Intent$ShortcutIconResource
-android.content.Intent$ShortcutIconResource$1
android.content.IntentFilter
android.content.IntentFilter$1
android.content.IntentFilter$AuthorityEntry
android.content.IntentFilter$MalformedMimeTypeException
android.content.IntentSender
-android.content.IntentSender$1
android.content.IntentSender$SendIntentException
android.content.Loader
android.content.Loader$ForceLoadContentObserver
@@ -893,11 +911,14 @@
android.content.UriPermission
android.content.pm.ActivityInfo
android.content.pm.ActivityInfo$1
+android.content.pm.ActivityInfo$WindowLayout
android.content.pm.ApplicationInfo
android.content.pm.ApplicationInfo$1
android.content.pm.ComponentInfo
android.content.pm.ConfigurationInfo
android.content.pm.ConfigurationInfo$1
+android.content.pm.EphemeralResponse
+android.content.pm.FallbackCategoryProvider
android.content.pm.FeatureGroupInfo
android.content.pm.FeatureGroupInfo$1
android.content.pm.FeatureInfo
@@ -914,16 +935,9 @@
android.content.pm.IOtaDexopt
android.content.pm.IOtaDexopt$Stub
android.content.pm.IPackageDataObserver
-android.content.pm.IPackageDataObserver$Stub
-android.content.pm.IPackageDataObserver$Stub$Proxy
android.content.pm.IPackageDeleteObserver
-android.content.pm.IPackageDeleteObserver$Stub
android.content.pm.IPackageDeleteObserver2
-android.content.pm.IPackageDeleteObserver2$Stub
-android.content.pm.IPackageInstallObserver
-android.content.pm.IPackageInstallObserver$Stub
android.content.pm.IPackageInstallObserver2
-android.content.pm.IPackageInstallObserver2$Stub
android.content.pm.IPackageInstaller
android.content.pm.IPackageInstaller$Stub
android.content.pm.IPackageInstaller$Stub$Proxy
@@ -931,8 +945,6 @@
android.content.pm.IPackageInstallerCallback$Stub
android.content.pm.IPackageInstallerCallback$Stub$Proxy
android.content.pm.IPackageInstallerSession
-android.content.pm.IPackageInstallerSession$Stub
-android.content.pm.IPackageInstallerSession$Stub$Proxy
android.content.pm.IPackageManager
android.content.pm.IPackageManager$Stub
android.content.pm.IPackageManager$Stub$Proxy
@@ -944,6 +956,7 @@
android.content.pm.IPackageStatsObserver$Stub$Proxy
android.content.pm.IShortcutService
android.content.pm.IShortcutService$Stub
+android.content.pm.IShortcutService$Stub$Proxy
android.content.pm.InstrumentationInfo
android.content.pm.InstrumentationInfo$1
android.content.pm.IntentFilterVerificationInfo
@@ -956,46 +969,49 @@
android.content.pm.LauncherApps$Callback
android.content.pm.LauncherApps$CallbackMessageHandler
android.content.pm.LauncherApps$CallbackMessageHandler$CallbackInfo
+android.content.pm.LauncherApps$ShortcutQuery
android.content.pm.PackageCleanItem
-android.content.pm.PackageCleanItem$1
android.content.pm.PackageInfo
android.content.pm.PackageInfo$1
android.content.pm.PackageInfoLite
-android.content.pm.PackageInfoLite$1
android.content.pm.PackageInstaller
android.content.pm.PackageInstaller$Session
android.content.pm.PackageInstaller$SessionCallback
android.content.pm.PackageInstaller$SessionCallbackDelegate
android.content.pm.PackageInstaller$SessionInfo
-android.content.pm.PackageInstaller$SessionInfo$1
android.content.pm.PackageInstaller$SessionParams
-android.content.pm.PackageInstaller$SessionParams$1
android.content.pm.PackageItemInfo
android.content.pm.PackageManager
-android.content.pm.PackageManager$LegacyPackageDeleteObserver
android.content.pm.PackageManager$MoveCallback
android.content.pm.PackageManager$NameNotFoundException
android.content.pm.PackageManager$OnPermissionsChangedListener
android.content.pm.PackageManagerInternal
+android.content.pm.PackageManagerInternal$ExternalSourcesPolicy
android.content.pm.PackageManagerInternal$PackagesProvider
android.content.pm.PackageManagerInternal$SyncAdapterPackagesProvider
android.content.pm.PackageParser
android.content.pm.PackageParser$Activity
+android.content.pm.PackageParser$Activity$1
android.content.pm.PackageParser$ActivityIntentInfo
android.content.pm.PackageParser$ApkLite
android.content.pm.PackageParser$Component
android.content.pm.PackageParser$IntentInfo
android.content.pm.PackageParser$NewPermissionInfo
android.content.pm.PackageParser$Package
+android.content.pm.PackageParser$Package$1
android.content.pm.PackageParser$PackageLite
android.content.pm.PackageParser$PackageParserException
android.content.pm.PackageParser$ParseComponentArgs
android.content.pm.PackageParser$ParsePackageItemArgs
android.content.pm.PackageParser$Permission
+android.content.pm.PackageParser$Permission$1
android.content.pm.PackageParser$PermissionGroup
+android.content.pm.PackageParser$PermissionGroup$1
android.content.pm.PackageParser$Provider
+android.content.pm.PackageParser$Provider$1
android.content.pm.PackageParser$ProviderIntentInfo
android.content.pm.PackageParser$Service
+android.content.pm.PackageParser$Service$1
android.content.pm.PackageParser$ServiceIntentInfo
android.content.pm.PackageParser$SplitNameComparator
android.content.pm.PackageParser$SplitPermissionInfo
@@ -1024,6 +1040,11 @@
android.content.pm.ResolveInfo$1
android.content.pm.ServiceInfo
android.content.pm.ServiceInfo$1
+android.content.pm.SharedLibraryInfo
+android.content.pm.SharedLibraryInfo$1
+android.content.pm.ShortcutInfo
+android.content.pm.ShortcutInfo$1
+android.content.pm.ShortcutInfo$Builder
android.content.pm.ShortcutManager
android.content.pm.ShortcutServiceInternal
android.content.pm.ShortcutServiceInternal$ShortcutChangeListener
@@ -1033,7 +1054,18 @@
android.content.pm.UserInfo$1
android.content.pm.VerifierDeviceIdentity
android.content.pm.VerifierInfo
+android.content.pm.VersionedPackage
+android.content.pm.VersionedPackage$1
android.content.pm.XmlSerializerAndParser
+android.content.pm.permission.IRuntimePermissionPresenter
+android.content.pm.permission.IRuntimePermissionPresenter$Stub
+android.content.pm.permission.IRuntimePermissionPresenter$Stub$Proxy
+android.content.pm.permission.RuntimePermissionPresentationInfo
+android.content.pm.permission.RuntimePermissionPresentationInfo$1
+android.content.pm.permission.RuntimePermissionPresenter
+android.content.pm.permission.RuntimePermissionPresenter$OnResultCallback
+android.content.pm.permission.RuntimePermissionPresenter$RemoteService
+android.content.pm.permission.RuntimePermissionPresenter$RemoteService$1
android.content.res.AssetFileDescriptor
android.content.res.AssetFileDescriptor$1
android.content.res.AssetFileDescriptor$AutoCloseInputStream
@@ -1109,6 +1141,7 @@
android.database.SQLException
android.database.sqlite.DatabaseObjectNotClosedException
android.database.sqlite.SQLiteAbortException
+android.database.sqlite.SQLiteAccessPermException
android.database.sqlite.SQLiteCantOpenDatabaseException
android.database.sqlite.SQLiteClosable
android.database.sqlite.SQLiteConnection
@@ -1144,6 +1177,7 @@
android.database.sqlite.SQLiteProgram
android.database.sqlite.SQLiteQuery
android.database.sqlite.SQLiteQueryBuilder
+android.database.sqlite.SQLiteReadOnlyDatabaseException
android.database.sqlite.SQLiteSession
android.database.sqlite.SQLiteSession$Transaction
android.database.sqlite.SQLiteStatement
@@ -1170,6 +1204,7 @@
android.drm.DrmManagerClient$OnInfoListener
android.drm.DrmOutputStream
android.drm.DrmSupportInfo
+android.graphics.BaseCanvas
android.graphics.Bitmap
android.graphics.Bitmap$1
android.graphics.Bitmap$CompressFormat
@@ -1196,23 +1231,20 @@
android.graphics.DiscretePathEffect
android.graphics.DrawFilter
android.graphics.EmbossMaskFilter
-android.graphics.FontConfig
-android.graphics.FontConfig$Alias
-android.graphics.FontConfig$Axis
-android.graphics.FontConfig$Family
-android.graphics.FontConfig$Font
android.graphics.FontFamily
android.graphics.FontListParser
+android.graphics.GraphicBuffer
+android.graphics.GraphicBuffer$1
android.graphics.ImageFormat
android.graphics.Insets
android.graphics.Interpolator
android.graphics.Interpolator$Result
-android.graphics.LayerRasterizer
android.graphics.LightingColorFilter
android.graphics.LinearGradient
android.graphics.MaskFilter
android.graphics.Matrix
android.graphics.Matrix$1
+android.graphics.Matrix$NoImagePreloadHolder
android.graphics.Matrix$ScaleToFit
android.graphics.Movie
android.graphics.NinePatch
@@ -1246,7 +1278,6 @@
android.graphics.PorterDuffColorFilter
android.graphics.PorterDuffXfermode
android.graphics.RadialGradient
-android.graphics.Rasterizer
android.graphics.Rect
android.graphics.Rect$1
android.graphics.Rect$UnflattenHelper
@@ -1270,7 +1301,6 @@
android.graphics.YuvImage
android.graphics.drawable.Animatable
android.graphics.drawable.Animatable2
-android.graphics.drawable.Animatable2$AnimationCallback
android.graphics.drawable.AnimatedRotateDrawable
android.graphics.drawable.AnimatedRotateDrawable$1
android.graphics.drawable.AnimatedRotateDrawable$AnimatedRotateState
@@ -1282,7 +1312,6 @@
android.graphics.drawable.AnimatedStateListDrawable$Transition
android.graphics.drawable.AnimatedVectorDrawable
android.graphics.drawable.AnimatedVectorDrawable$1
-android.graphics.drawable.AnimatedVectorDrawable$2
android.graphics.drawable.AnimatedVectorDrawable$AnimatedVectorDrawableState
android.graphics.drawable.AnimatedVectorDrawable$AnimatedVectorDrawableState$PendingAnimator
android.graphics.drawable.AnimatedVectorDrawable$VectorDrawableAnimator
@@ -1301,6 +1330,7 @@
android.graphics.drawable.Drawable$ConstantState
android.graphics.drawable.DrawableContainer
android.graphics.drawable.DrawableContainer$1
+android.graphics.drawable.DrawableContainer$BlockInvalidateCallback
android.graphics.drawable.DrawableContainer$DrawableContainerState
android.graphics.drawable.DrawableInflater
android.graphics.drawable.DrawableWrapper
@@ -1349,13 +1379,31 @@
android.graphics.drawable.VectorDrawable$VClipPath
android.graphics.drawable.VectorDrawable$VFullPath
android.graphics.drawable.VectorDrawable$VFullPath$1
+android.graphics.drawable.VectorDrawable$VFullPath$10
+android.graphics.drawable.VectorDrawable$VFullPath$2
+android.graphics.drawable.VectorDrawable$VFullPath$3
+android.graphics.drawable.VectorDrawable$VFullPath$4
+android.graphics.drawable.VectorDrawable$VFullPath$5
+android.graphics.drawable.VectorDrawable$VFullPath$6
+android.graphics.drawable.VectorDrawable$VFullPath$7
+android.graphics.drawable.VectorDrawable$VFullPath$8
+android.graphics.drawable.VectorDrawable$VFullPath$9
android.graphics.drawable.VectorDrawable$VGroup
android.graphics.drawable.VectorDrawable$VGroup$1
+android.graphics.drawable.VectorDrawable$VGroup$2
+android.graphics.drawable.VectorDrawable$VGroup$3
+android.graphics.drawable.VectorDrawable$VGroup$4
+android.graphics.drawable.VectorDrawable$VGroup$5
+android.graphics.drawable.VectorDrawable$VGroup$6
+android.graphics.drawable.VectorDrawable$VGroup$7
+android.graphics.drawable.VectorDrawable$VGroup$8
+android.graphics.drawable.VectorDrawable$VGroup$9
android.graphics.drawable.VectorDrawable$VObject
android.graphics.drawable.VectorDrawable$VPath
+android.graphics.drawable.VectorDrawable$VPath$1
android.graphics.drawable.VectorDrawable$VectorDrawableState
+android.graphics.drawable.VectorDrawable$VectorDrawableState$1
android.graphics.drawable.shapes.OvalShape
-android.graphics.drawable.shapes.PathShape
android.graphics.drawable.shapes.RectShape
android.graphics.drawable.shapes.RoundRectShape
android.graphics.drawable.shapes.Shape
@@ -1363,7 +1411,6 @@
android.graphics.pdf.PdfEditor
android.graphics.pdf.PdfRenderer
android.hardware.Camera
-android.hardware.Camera$Area
android.hardware.Camera$AutoFocusCallback
android.hardware.Camera$AutoFocusMoveCallback
android.hardware.Camera$CameraInfo
@@ -1377,9 +1424,13 @@
android.hardware.Camera$PreviewCallback
android.hardware.Camera$ShutterCallback
android.hardware.Camera$Size
+android.hardware.CameraStatus
+android.hardware.CameraStatus$1
android.hardware.ConsumerIrManager
android.hardware.GeomagneticField
android.hardware.GeomagneticField$LegendreTable
+android.hardware.HardwareBuffer
+android.hardware.HardwareBuffer$1
android.hardware.ICameraService
android.hardware.ICameraService$Stub
android.hardware.ICameraService$Stub$Proxy
@@ -1419,8 +1470,11 @@
android.hardware.camera2.CameraManager
android.hardware.camera2.CameraManager$AvailabilityCallback
android.hardware.camera2.CameraManager$CameraManagerGlobal
+android.hardware.camera2.CameraManager$CameraManagerGlobal$1
+android.hardware.camera2.CameraManager$CameraManagerGlobal$2
android.hardware.camera2.CameraManager$CameraManagerGlobal$3
android.hardware.camera2.CameraManager$CameraManagerGlobal$4
+android.hardware.camera2.CameraManager$CameraManagerGlobal$5
android.hardware.camera2.CameraManager$TorchCallback
android.hardware.camera2.CameraMetadata
android.hardware.camera2.CaptureFailure
@@ -1461,6 +1515,7 @@
android.hardware.camera2.impl.CameraDeviceImpl
android.hardware.camera2.impl.CameraDeviceImpl$1
android.hardware.camera2.impl.CameraDeviceImpl$10
+android.hardware.camera2.impl.CameraDeviceImpl$11
android.hardware.camera2.impl.CameraDeviceImpl$2
android.hardware.camera2.impl.CameraDeviceImpl$3
android.hardware.camera2.impl.CameraDeviceImpl$4
@@ -1472,7 +1527,6 @@
android.hardware.camera2.impl.CameraDeviceImpl$CameraDeviceCallbacks$2
android.hardware.camera2.impl.CameraDeviceImpl$CameraDeviceCallbacks$3
android.hardware.camera2.impl.CameraDeviceImpl$CameraDeviceCallbacks$4
-android.hardware.camera2.impl.CameraDeviceImpl$CameraDeviceCallbacks$5
android.hardware.camera2.impl.CameraDeviceImpl$CameraDeviceCallbacks$6
android.hardware.camera2.impl.CameraDeviceImpl$CaptureCallback
android.hardware.camera2.impl.CameraDeviceImpl$CaptureCallbackHolder
@@ -1565,7 +1619,6 @@
android.hardware.camera2.params.StreamConfigurationDuration
android.hardware.camera2.params.StreamConfigurationMap
android.hardware.camera2.params.TonemapCurve
-android.hardware.camera2.utils.ArrayUtils
android.hardware.camera2.utils.HashCodeHelpers
android.hardware.camera2.utils.SubmitInfo
android.hardware.camera2.utils.SubmitInfo$1
@@ -1605,21 +1658,11 @@
android.hardware.fingerprint.FingerprintManager
android.hardware.fingerprint.FingerprintManager$1
android.hardware.fingerprint.FingerprintManager$2
-android.hardware.fingerprint.FingerprintManager$2$1
android.hardware.fingerprint.FingerprintManager$AuthenticationCallback
android.hardware.fingerprint.FingerprintManager$AuthenticationResult
-android.hardware.fingerprint.FingerprintManager$CryptoObject
-android.hardware.fingerprint.FingerprintManager$EnrollmentCallback
android.hardware.fingerprint.FingerprintManager$LockoutResetCallback
android.hardware.fingerprint.FingerprintManager$MyHandler
-android.hardware.fingerprint.FingerprintManager$OnAuthenticationCancelListener
-android.hardware.fingerprint.FingerprintManager$OnEnrollCancelListener
-android.hardware.fingerprint.FingerprintManager$RemovalCallback
-android.hardware.fingerprint.IFingerprintDaemon
-android.hardware.fingerprint.IFingerprintDaemon$Stub
-android.hardware.fingerprint.IFingerprintDaemon$Stub$Proxy
-android.hardware.fingerprint.IFingerprintDaemonCallback
-android.hardware.fingerprint.IFingerprintDaemonCallback$Stub
+android.hardware.fingerprint.IFingerprintClientActiveCallback
android.hardware.fingerprint.IFingerprintService
android.hardware.fingerprint.IFingerprintService$Stub
android.hardware.fingerprint.IFingerprintService$Stub$Proxy
@@ -1628,14 +1671,8 @@
android.hardware.fingerprint.IFingerprintServiceLockoutResetCallback$Stub$Proxy
android.hardware.fingerprint.IFingerprintServiceReceiver
android.hardware.fingerprint.IFingerprintServiceReceiver$Stub
-android.hardware.fingerprint.IFingerprintServiceReceiver$Stub$Proxy
-android.hardware.hdmi.HdmiClient
android.hardware.hdmi.HdmiControlManager
-android.hardware.hdmi.HdmiPlaybackClient
android.hardware.hdmi.HdmiPlaybackClient$DisplayStatusCallback
-android.hardware.hdmi.HdmiTvClient
-android.hardware.hdmi.IHdmiControlService
-android.hardware.hdmi.IHdmiControlService$Stub
android.hardware.input.IInputDevicesChangedListener
android.hardware.input.IInputDevicesChangedListener$Stub
android.hardware.input.IInputDevicesChangedListener$Stub$Proxy
@@ -1655,13 +1692,15 @@
android.hardware.input.KeyboardLayout$1
android.hardware.input.TouchCalibration
android.hardware.input.TouchCalibration$1
-android.hardware.location.ActivityChangedEvent
android.hardware.location.ActivityRecognitionHardware
-android.hardware.location.ActivityRecognitionHardware$SinkList
android.hardware.location.ContextHubInfo
android.hardware.location.ContextHubInfo$1
android.hardware.location.ContextHubManager
-android.hardware.location.ContextHubService
+android.hardware.location.ContextHubManager$1
+android.hardware.location.ContextHubManager$Callback
+android.hardware.location.ContextHubManager$ICallback
+android.hardware.location.ContextHubMessage
+android.hardware.location.ContextHubMessage$1
android.hardware.location.GeofenceHardware
android.hardware.location.GeofenceHardware$GeofenceHardwareMonitorCallbackWrapper
android.hardware.location.GeofenceHardwareCallback
@@ -1671,27 +1710,21 @@
android.hardware.location.GeofenceHardwareImpl$3
android.hardware.location.GeofenceHardwareImpl$Reaper
android.hardware.location.GeofenceHardwareMonitorCallback
-android.hardware.location.GeofenceHardwareRequestParcelable
android.hardware.location.GeofenceHardwareService
android.hardware.location.GeofenceHardwareService$1
android.hardware.location.IActivityRecognitionHardware
android.hardware.location.IActivityRecognitionHardware$Stub
-android.hardware.location.IActivityRecognitionHardware$Stub$Proxy
android.hardware.location.IActivityRecognitionHardwareClient
android.hardware.location.IActivityRecognitionHardwareClient$Stub
android.hardware.location.IActivityRecognitionHardwareClient$Stub$Proxy
-android.hardware.location.IActivityRecognitionHardwareSink
-android.hardware.location.IActivityRecognitionHardwareSink$Stub
-android.hardware.location.IActivityRecognitionHardwareSink$Stub$Proxy
android.hardware.location.IActivityRecognitionHardwareWatcher
+android.hardware.location.IContextHubCallback
+android.hardware.location.IContextHubCallback$Stub
+android.hardware.location.IContextHubCallback$Stub$Proxy
android.hardware.location.IContextHubService
android.hardware.location.IContextHubService$Stub
+android.hardware.location.IContextHubService$Stub$Proxy
android.hardware.location.IFusedLocationHardware
-android.hardware.location.IFusedLocationHardware$Stub
-android.hardware.location.IFusedLocationHardware$Stub$Proxy
-android.hardware.location.IFusedLocationHardwareSink
-android.hardware.location.IFusedLocationHardwareSink$Stub
-android.hardware.location.IFusedLocationHardwareSink$Stub$Proxy
android.hardware.location.IGeofenceHardware
android.hardware.location.IGeofenceHardware$Stub
android.hardware.location.IGeofenceHardware$Stub$Proxy
@@ -1699,6 +1732,10 @@
android.hardware.location.IGeofenceHardwareMonitorCallback$Stub
android.hardware.location.IGeofenceHardwareMonitorCallback$Stub$Proxy
android.hardware.location.MemoryRegion
+android.hardware.location.MemoryRegion$1
+android.hardware.location.NanoApp
+android.hardware.location.NanoAppFilter
+android.hardware.location.NanoAppFilter$1
android.hardware.location.NanoAppInstanceInfo
android.hardware.location.NanoAppInstanceInfo$1
android.hardware.radio.RadioManager
@@ -1722,6 +1759,21 @@
android.hardware.radio.RadioMetadata$1
android.hardware.radio.RadioModule
android.hardware.radio.RadioTuner
+android.hardware.radio.V1_0.Call
+android.hardware.radio.V1_0.CardStatus
+android.hardware.radio.V1_0.CdmaSignalStrength
+android.hardware.radio.V1_0.EvdoSignalStrength
+android.hardware.radio.V1_0.GsmSignalStrength
+android.hardware.radio.V1_0.IRadio
+android.hardware.radio.V1_0.IRadio$Proxy
+android.hardware.radio.V1_0.IRadioIndication
+android.hardware.radio.V1_0.IRadioIndication$Stub
+android.hardware.radio.V1_0.IRadioResponse
+android.hardware.radio.V1_0.IRadioResponse$Stub
+android.hardware.radio.V1_0.LteSignalStrength
+android.hardware.radio.V1_0.RadioResponseInfo
+android.hardware.radio.V1_0.SignalStrength
+android.hardware.radio.V1_0.TdScdmaSignalStrength
android.hardware.soundtrigger.IRecognitionStatusCallback
android.hardware.soundtrigger.IRecognitionStatusCallback$Stub
android.hardware.soundtrigger.KeyphraseEnrollmentInfo
@@ -1757,21 +1809,28 @@
android.hardware.usb.UsbAccessory
android.hardware.usb.UsbDevice
android.hardware.usb.UsbDeviceConnection
-android.hardware.usb.UsbInterface
android.hardware.usb.UsbManager
android.hardware.usb.UsbPort
android.hardware.usb.UsbPort$1
android.hardware.usb.UsbPortStatus
android.hardware.usb.UsbPortStatus$1
android.hardware.usb.UsbRequest
+android.hidl.base.V1_0.IBase
android.icu.impl.BMPSet
android.icu.impl.CacheBase
android.icu.impl.CacheValue
android.icu.impl.CacheValue$NullValue
android.icu.impl.CacheValue$SoftValue
android.icu.impl.CacheValue$Strength
-android.icu.impl.CalendarData
+android.icu.impl.CalendarAstronomer
+android.icu.impl.CalendarAstronomer$2
+android.icu.impl.CalendarAstronomer$CoordFunc
+android.icu.impl.CalendarAstronomer$Equatorial
+android.icu.impl.CalendarAstronomer$MoonAge
+android.icu.impl.CalendarAstronomer$SolarLongitude
android.icu.impl.CalendarUtil
+android.icu.impl.CalendarUtil$CalendarPreferences
+android.icu.impl.CaseMap$StringContextIterator
android.icu.impl.CharTrie
android.icu.impl.CharacterIteration
android.icu.impl.ClassLoaderUtil
@@ -1779,6 +1838,8 @@
android.icu.impl.CurrencyData$CurrencyDisplayInfo
android.icu.impl.CurrencyData$CurrencyDisplayInfoProvider
android.icu.impl.CurrencyData$CurrencySpacingInfo
+android.icu.impl.CurrencyData$CurrencySpacingInfo$SpacingPattern
+android.icu.impl.CurrencyData$CurrencySpacingInfo$SpacingType
android.icu.impl.DateNumberFormat
android.icu.impl.DontCareFieldPosition
android.icu.impl.Grego
@@ -1792,6 +1853,7 @@
android.icu.impl.ICUConfig
android.icu.impl.ICUCurrencyDisplayInfoProvider
android.icu.impl.ICUCurrencyDisplayInfoProvider$ICUCurrencyDisplayInfo
+android.icu.impl.ICUCurrencyDisplayInfoProvider$ICUCurrencyDisplayInfo$SpacingInfoSink
android.icu.impl.ICUCurrencyMetaInfo
android.icu.impl.ICUCurrencyMetaInfo$Collector
android.icu.impl.ICUCurrencyMetaInfo$CurrencyCollector
@@ -1809,8 +1871,11 @@
android.icu.impl.ICUResourceBundle
android.icu.impl.ICUResourceBundle$1
android.icu.impl.ICUResourceBundle$2
-android.icu.impl.ICUResourceBundle$2$1
+android.icu.impl.ICUResourceBundle$3
+android.icu.impl.ICUResourceBundle$3$1
+android.icu.impl.ICUResourceBundle$4
android.icu.impl.ICUResourceBundle$AvailEntry
+android.icu.impl.ICUResourceBundle$Loader
android.icu.impl.ICUResourceBundle$OpenType
android.icu.impl.ICUResourceBundle$WholeBundle
android.icu.impl.ICUResourceBundleImpl
@@ -1844,6 +1909,7 @@
android.icu.impl.JavaTimeZone
android.icu.impl.LocaleDisplayNamesImpl
android.icu.impl.LocaleDisplayNamesImpl$Cache
+android.icu.impl.LocaleDisplayNamesImpl$CapitalizationContextSink
android.icu.impl.LocaleDisplayNamesImpl$CapitalizationContextUsage
android.icu.impl.LocaleDisplayNamesImpl$DataTable
android.icu.impl.LocaleDisplayNamesImpl$DataTables
@@ -1875,21 +1941,10 @@
android.icu.impl.ReplaceableUCharacterIterator
android.icu.impl.RuleCharacterIterator
android.icu.impl.SimpleCache
-android.icu.impl.SimplePatternFormatter
+android.icu.impl.SimpleFormatterImpl
android.icu.impl.SoftCache
android.icu.impl.StandardPlural
android.icu.impl.StringPrepDataReader
-android.icu.impl.TextTrieMap
-android.icu.impl.TextTrieMap$CharIterator
-android.icu.impl.TextTrieMap$Node
-android.icu.impl.TimeZoneNamesFactoryImpl
-android.icu.impl.TimeZoneNamesImpl
-android.icu.impl.TimeZoneNamesImpl$MZ2TZsCache
-android.icu.impl.TimeZoneNamesImpl$MZMapEntry
-android.icu.impl.TimeZoneNamesImpl$NameInfo
-android.icu.impl.TimeZoneNamesImpl$TZ2MZsCache
-android.icu.impl.TimeZoneNamesImpl$ZNames
-android.icu.impl.TimeZoneNamesImpl$ZNamesLoader
android.icu.impl.Trie
android.icu.impl.Trie$DataManipulate
android.icu.impl.Trie$DefaultGetFoldingOffset
@@ -1942,8 +1997,10 @@
android.icu.impl.UPropertyAliases
android.icu.impl.UPropertyAliases$IsAcceptable
android.icu.impl.URLHandler$URLVisitor
+android.icu.impl.UResource$Array
android.icu.impl.UResource$Key
-android.icu.impl.UResource$TableSink
+android.icu.impl.UResource$Sink
+android.icu.impl.UResource$Table
android.icu.impl.UResource$Value
android.icu.impl.USerializedSet
android.icu.impl.Utility
@@ -1979,7 +2036,6 @@
android.icu.impl.locale.LocaleObjectCache$CacheEntry
android.icu.impl.locale.LocaleSyntaxException
android.icu.lang.UCharacter
-android.icu.lang.UCharacter$StringContextIterator
android.icu.lang.UCharacterEnums$ECharacterCategory
android.icu.lang.UCharacterEnums$ECharacterDirection
android.icu.lang.UScript
@@ -2014,26 +2070,36 @@
android.icu.text.DateFormat$BooleanAttribute
android.icu.text.DateFormat$Field
android.icu.text.DateFormatSymbols
+android.icu.text.DateFormatSymbols$1
+android.icu.text.DateFormatSymbols$CalendarDataSink
+android.icu.text.DateFormatSymbols$CalendarDataSink$AliasType
android.icu.text.DateFormatSymbols$CapitalizationContextUsage
android.icu.text.DateIntervalFormat
android.icu.text.DateIntervalFormat$BestMatchInfo
android.icu.text.DateIntervalFormat$SkeletonAndItsBestMatch
android.icu.text.DateIntervalInfo
+android.icu.text.DateIntervalInfo$DateIntervalSink
android.icu.text.DateIntervalInfo$PatternInfo
android.icu.text.DateTimePatternGenerator
+android.icu.text.DateTimePatternGenerator$AppendItemFormatsSink
+android.icu.text.DateTimePatternGenerator$AppendItemNamesSink
+android.icu.text.DateTimePatternGenerator$AvailableFormatsSink
android.icu.text.DateTimePatternGenerator$DTPGflags
android.icu.text.DateTimePatternGenerator$DateTimeMatcher
+android.icu.text.DateTimePatternGenerator$DayPeriodAllowedHoursSink
android.icu.text.DateTimePatternGenerator$DistanceInfo
android.icu.text.DateTimePatternGenerator$FormatParser
android.icu.text.DateTimePatternGenerator$PatternInfo
android.icu.text.DateTimePatternGenerator$PatternWithMatcher
android.icu.text.DateTimePatternGenerator$PatternWithSkeletonFlag
+android.icu.text.DateTimePatternGenerator$SkeletonFields
android.icu.text.DateTimePatternGenerator$VariableField
android.icu.text.DecimalFormat
android.icu.text.DecimalFormat$Unit
android.icu.text.DecimalFormatSymbols
android.icu.text.DecimalFormatSymbols$1
android.icu.text.DecimalFormatSymbols$CacheData
+android.icu.text.DecimalFormatSymbols$DecFmtDataSink
android.icu.text.DigitList
android.icu.text.DisplayContext
android.icu.text.DisplayContext$Type
@@ -2045,14 +2111,6 @@
android.icu.text.ListFormatter$Style
android.icu.text.LocaleDisplayNames
android.icu.text.LocaleDisplayNames$DialectHandling
-android.icu.text.MessageFormat
-android.icu.text.MessageFormat$AppendableWrapper
-android.icu.text.MessageFormat$Field
-android.icu.text.MessagePattern
-android.icu.text.MessagePattern$ApostropheMode
-android.icu.text.MessagePattern$ArgType
-android.icu.text.MessagePattern$Part
-android.icu.text.MessagePattern$Part$Type
android.icu.text.Normalizer
android.icu.text.Normalizer$FCDMode
android.icu.text.Normalizer$Mode
@@ -2074,6 +2132,9 @@
android.icu.text.NumberFormatServiceShim$NFService
android.icu.text.NumberFormatServiceShim$NFService$1RBNumberFormatFactory
android.icu.text.NumberingSystem
+android.icu.text.NumberingSystem$1
+android.icu.text.NumberingSystem$2
+android.icu.text.NumberingSystem$LocaleLookupData
android.icu.text.PluralRanges
android.icu.text.PluralRanges$Matrix
android.icu.text.PluralRules
@@ -2101,20 +2162,18 @@
android.icu.text.RelativeDateTimeFormatter
android.icu.text.RelativeDateTimeFormatter$AbsoluteUnit
android.icu.text.RelativeDateTimeFormatter$Cache
+android.icu.text.RelativeDateTimeFormatter$Cache$1
android.icu.text.RelativeDateTimeFormatter$Direction
android.icu.text.RelativeDateTimeFormatter$Loader
-android.icu.text.RelativeDateTimeFormatter$RelDateTimeFmtDataSink
-android.icu.text.RelativeDateTimeFormatter$RelDateTimeFmtDataSink$DateTimeUnit
-android.icu.text.RelativeDateTimeFormatter$RelDateTimeFmtDataSink$RelativeSink
-android.icu.text.RelativeDateTimeFormatter$RelDateTimeFmtDataSink$RelativeTimeDetailSink
-android.icu.text.RelativeDateTimeFormatter$RelDateTimeFmtDataSink$RelativeTimeSink
-android.icu.text.RelativeDateTimeFormatter$RelDateTimeFmtDataSink$UnitSink
+android.icu.text.RelativeDateTimeFormatter$RelDateTimeDataSink
+android.icu.text.RelativeDateTimeFormatter$RelDateTimeDataSink$DateTimeUnit
android.icu.text.RelativeDateTimeFormatter$RelativeDateTimeFormatterData
android.icu.text.RelativeDateTimeFormatter$RelativeUnit
android.icu.text.RelativeDateTimeFormatter$Style
android.icu.text.Replaceable
android.icu.text.ReplaceableString
android.icu.text.RuleBasedBreakIterator
+android.icu.text.RuleBasedBreakIterator$LookAheadResults
android.icu.text.RuleBasedCollator
android.icu.text.RuleBasedCollator$CollationBuffer
android.icu.text.RuleBasedCollator$CollationKeyByteSink
@@ -2125,9 +2184,6 @@
android.icu.text.SimpleDateFormat$PatternItem
android.icu.text.StringPrep
android.icu.text.StringPrepParseException
-android.icu.text.TimeZoneNames
-android.icu.text.TimeZoneNames$Cache
-android.icu.text.TimeZoneNames$Factory
android.icu.text.TimeZoneNames$NameType
android.icu.text.UCharacterIterator
android.icu.text.UFieldPosition
@@ -2156,12 +2212,19 @@
android.icu.util.CharsTrie
android.icu.util.CharsTrie$Entry
android.icu.util.CharsTrie$Iterator
+android.icu.util.ChineseCalendar
android.icu.util.Currency
+android.icu.util.Currency$1
android.icu.util.Currency$CurrencyUsage
android.icu.util.Currency$EquivalenceRelation
android.icu.util.CurrencyAmount
android.icu.util.Freezable
android.icu.util.GregorianCalendar
+android.icu.util.HebrewCalendar
+android.icu.util.ICUException
+android.icu.util.IndianCalendar
+android.icu.util.IslamicCalendar
+android.icu.util.IslamicCalendar$CalculationType
android.icu.util.LocaleData
android.icu.util.Measure
android.icu.util.MeasureUnit
@@ -2175,11 +2238,13 @@
android.icu.util.TimeZone
android.icu.util.TimeZone$ConstantZone
android.icu.util.ULocale
+android.icu.util.ULocale$1
+android.icu.util.ULocale$2
android.icu.util.ULocale$Category
android.icu.util.ULocale$JDKLocaleHelper
android.icu.util.ULocale$Type
android.icu.util.UResourceBundle
-android.icu.util.UResourceBundle$ResourceCacheKey
+android.icu.util.UResourceBundle$RootType
android.icu.util.UResourceBundleIterator
android.icu.util.UResourceTypeMismatchException
android.icu.util.VersionInfo
@@ -2197,26 +2262,17 @@
android.inputmethodservice.InputMethodService$InputMethodSessionImpl
android.inputmethodservice.InputMethodService$Insets
android.inputmethodservice.InputMethodService$SettingsObserver
-android.inputmethodservice.Keyboard
-android.inputmethodservice.Keyboard$Key
-android.inputmethodservice.Keyboard$Row
-android.inputmethodservice.KeyboardView
-android.inputmethodservice.KeyboardView$1
-android.inputmethodservice.KeyboardView$2
-android.inputmethodservice.KeyboardView$OnKeyboardActionListener
-android.inputmethodservice.KeyboardView$SwipeTracker
android.inputmethodservice.SoftInputWindow
+android.inputmethodservice.SoftInputWindow$Callback
android.location.Address
android.location.Address$1
android.location.Country
android.location.Country$1
android.location.CountryDetector
android.location.CountryDetector$ListenerTransport
+android.location.CountryDetector$ListenerTransport$1
android.location.CountryListener
android.location.Criteria
-android.location.Criteria$1
-android.location.FusedBatchOptions
-android.location.FusedBatchOptions$1
android.location.Geocoder
android.location.GeocoderParams
android.location.GeocoderParams$1
@@ -2238,11 +2294,8 @@
android.location.ICountryListener
android.location.ICountryListener$Stub
android.location.ICountryListener$Stub$Proxy
-android.location.IFusedGeofenceHardware
-android.location.IFusedGeofenceHardware$Stub
android.location.IFusedProvider
android.location.IFusedProvider$Stub
-android.location.IFusedProvider$Stub$Proxy
android.location.IGeocodeProvider
android.location.IGeocodeProvider$Stub
android.location.IGeocodeProvider$Stub$Proxy
@@ -2284,7 +2337,6 @@
android.location.LocationProvider
android.location.LocationRequest
android.location.LocationRequest$1
-android.media.AmrInputStream
android.media.AudioAttributes
android.media.AudioAttributes$1
android.media.AudioAttributes$Builder
@@ -2303,6 +2355,7 @@
android.media.AudioManager
android.media.AudioManager$1
android.media.AudioManager$2
+android.media.AudioManager$3
android.media.AudioManager$NativeEventHandlerDelegate
android.media.AudioManager$NativeEventHandlerDelegate$1
android.media.AudioManager$OnAmPortUpdateListener
@@ -2315,6 +2368,10 @@
android.media.AudioMixPort
android.media.AudioMixPortConfig
android.media.AudioPatch
+android.media.AudioPlaybackConfiguration
+android.media.AudioPlaybackConfiguration$1
+android.media.AudioPlaybackConfiguration$IPlayerShell
+android.media.AudioPlaybackConfiguration$PlayerDeathMonitor
android.media.AudioPort
android.media.AudioPortConfig
android.media.AudioPortEventHandler
@@ -2331,6 +2388,8 @@
android.media.AudioSystem$ErrorCallback
android.media.AudioTimestamp
android.media.AudioTrack
+android.media.BufferingParams
+android.media.BufferingParams$1
android.media.CamcorderProfile
android.media.CameraProfile
android.media.Cea708CaptionRenderer
@@ -2339,11 +2398,9 @@
android.media.DeniedByServerException
android.media.EncoderCapabilities
android.media.ExifInterface
-android.media.ExifInterface$ByteOrderAwarenessDataInputStream
-android.media.ExifInterface$ByteOrderAwarenessDataOutputStream
+android.media.ExifInterface$ByteOrderedDataInputStream
android.media.ExifInterface$ExifAttribute
android.media.ExifInterface$ExifTag
-android.media.ExifInterface$Rational
android.media.IAudioFocusDispatcher
android.media.IAudioFocusDispatcher$Stub
android.media.IAudioFocusDispatcher$Stub$Proxy
@@ -2357,12 +2414,23 @@
android.media.IMediaHTTPConnection$Stub
android.media.IMediaHTTPService
android.media.IMediaHTTPService$Stub
+android.media.IMediaResourceMonitor
+android.media.IMediaResourceMonitor$Stub
android.media.IMediaRouterClient
android.media.IMediaRouterClient$Stub
android.media.IMediaRouterClient$Stub$Proxy
android.media.IMediaRouterService
android.media.IMediaRouterService$Stub
android.media.IMediaRouterService$Stub$Proxy
+android.media.IMediaScannerListener
+android.media.IMediaScannerListener$Stub
+android.media.IMediaScannerService
+android.media.IMediaScannerService$Stub
+android.media.IPlaybackConfigDispatcher
+android.media.IPlaybackConfigDispatcher$Stub
+android.media.IPlayer
+android.media.IPlayer$Stub
+android.media.IPlayer$Stub$Proxy
android.media.IRecordingConfigDispatcher
android.media.IRecordingConfigDispatcher$Stub
android.media.IRemoteVolumeController
@@ -2390,14 +2458,10 @@
android.media.ImageWriter$WriterSurfaceImage
android.media.ImageWriter$WriterSurfaceImage$SurfacePlane
android.media.JetPlayer
-android.media.MediaActionSound
-android.media.MediaActionSound$1
-android.media.MediaActionSound$SoundState
android.media.MediaCodec
android.media.MediaCodec$BufferInfo
android.media.MediaCodec$BufferMap
android.media.MediaCodec$BufferMap$CodecBuffer
-android.media.MediaCodec$Callback
android.media.MediaCodec$CodecException
android.media.MediaCodec$CryptoException
android.media.MediaCodec$CryptoInfo
@@ -2413,7 +2477,6 @@
android.media.MediaCodecInfo$VideoCapabilities
android.media.MediaCodecList
android.media.MediaCrypto
-android.media.MediaCryptoException
android.media.MediaDescription
android.media.MediaDescription$1
android.media.MediaDescription$Builder
@@ -2423,7 +2486,6 @@
android.media.MediaDrm$EventHandler
android.media.MediaDrm$KeyRequest
android.media.MediaDrm$MediaDrmStateException
-android.media.MediaDrm$OnEventListener
android.media.MediaDrm$ProvisionRequest
android.media.MediaDrmException
android.media.MediaExtractor
@@ -2441,7 +2503,8 @@
android.media.MediaPlayer
android.media.MediaPlayer$1
android.media.MediaPlayer$2
-android.media.MediaPlayer$2$1
+android.media.MediaPlayer$3
+android.media.MediaPlayer$3$1
android.media.MediaPlayer$EventHandler
android.media.MediaPlayer$OnBufferingUpdateListener
android.media.MediaPlayer$OnCompletionListener
@@ -2473,6 +2536,7 @@
android.media.MediaRouter$Static$Client$1
android.media.MediaRouter$UserRouteInfo
android.media.MediaRouter$VolumeCallback
+android.media.MediaRouter$VolumeCallbackInfo
android.media.MediaRouter$VolumeChangeReceiver
android.media.MediaRouter$WifiDisplayStatusChangedReceiver
android.media.MediaRouterClientState
@@ -2480,7 +2544,13 @@
android.media.MediaRouterClientState$RouteInfo
android.media.MediaRouterClientState$RouteInfo$1
android.media.MediaScanner
+android.media.MediaScanner$FileEntry
+android.media.MediaScanner$MediaBulkDeleter
+android.media.MediaScanner$MyMediaScannerClient
+android.media.MediaScannerClient
android.media.MediaScannerConnection
+android.media.MediaScannerConnection$1
+android.media.MediaScannerConnection$ClientProxy
android.media.MediaScannerConnection$MediaScannerConnectionClient
android.media.MediaScannerConnection$OnScanCompletedListener
android.media.MediaSync
@@ -2493,6 +2563,9 @@
android.media.PlaybackParams$1
android.media.PlayerBase
android.media.PlayerBase$1
+android.media.PlayerBase$2
+android.media.PlayerBase$PlayerIdCard
+android.media.PlayerBase$PlayerIdCard$1
android.media.Rating
android.media.Rating$1
android.media.RemoteControlClient
@@ -2504,7 +2577,6 @@
android.media.Ringtone$MyOnCompletionListener
android.media.RingtoneManager
android.media.SoundPool
-android.media.SoundPool$1
android.media.SoundPool$Builder
android.media.SoundPool$EventHandler
android.media.SoundPool$OnLoadCompleteListener
@@ -2520,7 +2592,6 @@
android.media.ThumbnailUtils$SizedThumbnailBitmap
android.media.ToneGenerator
android.media.TtmlRenderer
-android.media.UnsupportedSchemeException
android.media.Utils
android.media.Utils$1
android.media.Utils$2
@@ -2528,10 +2599,8 @@
android.media.VolumePolicy$1
android.media.VolumeProvider
android.media.WebVttRenderer
-android.media.audiofx.AcousticEchoCanceler
android.media.audiofx.AudioEffect
android.media.audiofx.AudioEffect$Descriptor
-android.media.audiofx.AutomaticGainControl
android.media.audiofx.BassBoost
android.media.audiofx.BassBoost$Settings
android.media.audiofx.Equalizer
@@ -2541,12 +2610,20 @@
android.media.audiofx.Virtualizer
android.media.audiofx.Virtualizer$Settings
android.media.audiofx.Visualizer
+android.media.audiofx.Visualizer$OnDataCaptureListener
android.media.audiopolicy.AudioMix
android.media.audiopolicy.AudioMixingRule
android.media.audiopolicy.AudioMixingRule$AudioMixMatchCriterion
android.media.audiopolicy.AudioPolicyConfig
android.media.audiopolicy.IAudioPolicyCallback
android.media.audiopolicy.IAudioPolicyCallback$Stub
+android.media.browse.MediaBrowser
+android.media.browse.MediaBrowser$10
+android.media.browse.MediaBrowser$ConnectionCallback
+android.media.browse.MediaBrowser$MediaItem
+android.media.browse.MediaBrowser$MediaServiceConnection
+android.media.browse.MediaBrowser$MediaServiceConnection$1
+android.media.browse.MediaBrowser$ServiceCallbacks
android.media.midi.IMidiDeviceListener
android.media.midi.IMidiDeviceOpenCallback
android.media.midi.IMidiDeviceServer
@@ -2569,6 +2646,8 @@
android.media.session.IActiveSessionsListener
android.media.session.IActiveSessionsListener$Stub
android.media.session.IActiveSessionsListener$Stub$Proxy
+android.media.session.IOnMediaKeyListener
+android.media.session.IOnVolumeKeyLongPressListener
android.media.session.ISession
android.media.session.ISession$Stub
android.media.session.ISession$Stub$Proxy
@@ -2617,12 +2696,12 @@
android.media.tv.TvInputManager
android.media.tv.TvStreamConfig
android.media.tv.TvStreamConfig$Builder
+android.metrics.LogMaker
android.mtp.MtpDatabase
android.mtp.MtpDevice
android.mtp.MtpDeviceInfo
android.mtp.MtpEvent
android.mtp.MtpObjectInfo
-android.mtp.MtpObjectInfo$Builder
android.mtp.MtpPropertyGroup
android.mtp.MtpPropertyList
android.mtp.MtpServer
@@ -2632,14 +2711,13 @@
android.net.ConnectivityManager$CallbackHandler
android.net.ConnectivityManager$NetworkCallback
android.net.ConnectivityManager$OnNetworkActiveListener
-android.net.ConnectivityManager$OnStartTetheringCallback
android.net.ConnectivityManager$PacketKeepalive
android.net.ConnectivityManager$PacketKeepaliveCallback
android.net.ConnectivityMetricsEvent
android.net.ConnectivityMetricsEvent$1
android.net.ConnectivityMetricsEvent$Reference
-android.net.ConnectivityMetricsLogger
android.net.ConnectivityThread
+android.net.ConnectivityThread$Singleton
android.net.Credentials
android.net.DataUsageRequest
android.net.DhcpInfo
@@ -2649,16 +2727,22 @@
android.net.EthernetManager
android.net.EthernetManager$1
android.net.EthernetManager$2
+android.net.EventLogTags
android.net.IConnectivityManager
android.net.IConnectivityManager$Stub
android.net.IConnectivityManager$Stub$Proxy
android.net.IConnectivityMetricsLogger
android.net.IConnectivityMetricsLogger$Stub
-android.net.IConnectivityMetricsLogger$Stub$Proxy
android.net.IEthernetManager
android.net.IEthernetManager$Stub
android.net.IEthernetServiceListener
android.net.IEthernetServiceListener$Stub
+android.net.IIpConnectivityMetrics
+android.net.IIpConnectivityMetrics$Stub
+android.net.INetd
+android.net.INetd$Stub
+android.net.INetd$Stub$Proxy
+android.net.INetdEventCallback
android.net.INetworkManagementEventObserver
android.net.INetworkManagementEventObserver$Stub
android.net.INetworkPolicyListener
@@ -2669,6 +2753,7 @@
android.net.INetworkPolicyManager$Stub$Proxy
android.net.INetworkScoreCache
android.net.INetworkScoreCache$Stub
+android.net.INetworkScoreCache$Stub$Proxy
android.net.INetworkScoreService
android.net.INetworkScoreService$Stub
android.net.INetworkScoreService$Stub$Proxy
@@ -2704,6 +2789,7 @@
android.net.Network$2
android.net.Network$NetworkBoundSocketFactory
android.net.NetworkAgent
+android.net.NetworkBadging
android.net.NetworkCapabilities
android.net.NetworkCapabilities$1
android.net.NetworkConfig
@@ -2725,6 +2811,7 @@
android.net.NetworkRequest
android.net.NetworkRequest$1
android.net.NetworkRequest$Builder
+android.net.NetworkRequest$Type
android.net.NetworkScoreManager
android.net.NetworkScorerAppManager
android.net.NetworkState
@@ -2745,13 +2832,17 @@
android.net.Proxy
android.net.ProxyInfo
android.net.ProxyInfo$1
+android.net.RecommendationRequest
+android.net.RecommendationResult
android.net.RouteInfo
android.net.RouteInfo$1
android.net.RssiCurve
+android.net.RssiCurve$1
android.net.SSLCertificateSocketFactory
android.net.SSLCertificateSocketFactory$1
android.net.SSLSessionCache
android.net.ScoredNetwork
+android.net.ScoredNetwork$1
android.net.SntpClient
android.net.StaticIpConfiguration
android.net.StaticIpConfiguration$1
@@ -2771,7 +2862,7 @@
android.net.Uri$PathSegmentsBuilder
android.net.Uri$StringUri
android.net.UrlQuerySanitizer
-android.net.UrlQuerySanitizer$ValueSanitizer
+android.net.VpnService
android.net.WebAddress
android.net.WifiKey
android.net.WifiKey$1
@@ -2784,19 +2875,23 @@
android.net.http.SslCertificate
android.net.http.SslError
android.net.http.X509TrustManagerExtensions
+android.net.metrics.ApfProgramEvent
+android.net.metrics.ApfProgramEvent$1
+android.net.metrics.ConnectStats
android.net.metrics.DefaultNetworkEvent
android.net.metrics.DefaultNetworkEvent$1
android.net.metrics.DhcpClientEvent
android.net.metrics.DhcpClientEvent$1
android.net.metrics.DnsEvent
android.net.metrics.DnsEvent$1
-android.net.metrics.IpConnectivityEvent
+android.net.metrics.IpConnectivityLog
android.net.metrics.IpManagerEvent
android.net.metrics.IpManagerEvent$1
-android.net.metrics.IpReachabilityEvent
-android.net.metrics.IpReachabilityEvent$1
android.net.metrics.NetworkEvent
android.net.metrics.NetworkEvent$1
+android.net.metrics.RaEvent
+android.net.metrics.RaEvent$1
+android.net.metrics.RaEvent$Builder
android.net.metrics.ValidationProbeEvent
android.net.metrics.ValidationProbeEvent$1
android.net.metrics.ValidationProbeEvent$Decoder
@@ -2806,8 +2901,6 @@
android.net.sip.ISipService
android.net.sip.ISipService$Stub
android.net.sip.SipManager
-android.net.sip.SipProfile
-android.net.sip.SipProfile$Builder
android.net.wifi.IRttManager
android.net.wifi.IRttManager$Stub
android.net.wifi.IRttManager$Stub$Proxy
@@ -2817,9 +2910,10 @@
android.net.wifi.IWifiScanner
android.net.wifi.IWifiScanner$Stub
android.net.wifi.IWifiScanner$Stub$Proxy
+android.net.wifi.ParcelUtil
+android.net.wifi.RssiPacketCountInfo
android.net.wifi.RttManager
android.net.wifi.RttManager$RttCapabilities
-android.net.wifi.RttManager$RttCapabilities$1
android.net.wifi.RttManager$RttListener
android.net.wifi.RttManager$RttResult
android.net.wifi.RttManager$ServiceHandler
@@ -2831,6 +2925,7 @@
android.net.wifi.SupplicantState$1
android.net.wifi.WifiActivityEnergyInfo
android.net.wifi.WifiActivityEnergyInfo$1
+android.net.wifi.WifiChannel
android.net.wifi.WifiConfiguration
android.net.wifi.WifiConfiguration$1
android.net.wifi.WifiConfiguration$AuthAlgorithm
@@ -2844,9 +2939,6 @@
android.net.wifi.WifiConnectionStatistics$1
android.net.wifi.WifiEnterpriseConfig
android.net.wifi.WifiEnterpriseConfig$1
-android.net.wifi.WifiEnterpriseConfig$Eap
-android.net.wifi.WifiEnterpriseConfig$Phase2
-android.net.wifi.WifiEnterpriseConfig$SupplicantLoader
android.net.wifi.WifiInfo
android.net.wifi.WifiInfo$1
android.net.wifi.WifiLinkLayerStats
@@ -2855,25 +2947,30 @@
android.net.wifi.WifiManager$ActionListener
android.net.wifi.WifiManager$MulticastLock
android.net.wifi.WifiManager$WifiLock
+android.net.wifi.WifiNetworkScoreCache
+android.net.wifi.WifiNetworkScoreCache$CacheListener
android.net.wifi.WifiScanner
android.net.wifi.WifiScanner$ActionListener
android.net.wifi.WifiScanner$ChannelSpec
-android.net.wifi.WifiScanner$OperationResult
-android.net.wifi.WifiScanner$OperationResult$1
android.net.wifi.WifiScanner$ParcelableScanData
android.net.wifi.WifiScanner$ParcelableScanData$1
+android.net.wifi.WifiScanner$ParcelableScanResults
+android.net.wifi.WifiScanner$ParcelableScanResults$1
android.net.wifi.WifiScanner$PnoScanListener
android.net.wifi.WifiScanner$ScanData
android.net.wifi.WifiScanner$ScanData$1
android.net.wifi.WifiScanner$ScanListener
android.net.wifi.WifiScanner$ScanSettings
android.net.wifi.WifiScanner$ScanSettings$1
+android.net.wifi.WifiScanner$ScanSettings$HiddenNetwork
android.net.wifi.WifiScanner$ServiceHandler
android.net.wifi.WifiSsid
android.net.wifi.WifiSsid$1
+android.net.wifi.WifiWakeReasonAndCounts
android.net.wifi.WpsInfo
android.net.wifi.WpsInfo$1
-android.net.wifi.nan.WifiNanManager
+android.net.wifi.aware.WifiAwareManager
+android.net.wifi.hotspot2.PasspointConfiguration
android.net.wifi.p2p.IWifiP2pManager
android.net.wifi.p2p.IWifiP2pManager$Stub
android.net.wifi.p2p.WifiP2pConfig
@@ -2925,7 +3022,6 @@
android.nfc.NfcAdapter$1
android.nfc.NfcAdapter$CreateBeamUrisCallback
android.nfc.NfcAdapter$CreateNdefMessageCallback
-android.nfc.NfcAdapter$NfcUnlockHandler
android.nfc.NfcAdapter$OnNdefPushCompleteCallback
android.nfc.NfcEvent
android.nfc.NfcManager
@@ -2976,11 +3072,17 @@
android.opengl.GLSurfaceView$GLThread
android.opengl.GLSurfaceView$GLThreadManager
android.opengl.GLSurfaceView$Renderer
+android.opengl.GLSurfaceView$SimpleEGLConfigChooser
android.opengl.GLU
android.opengl.GLUtils
android.opengl.Matrix
android.opengl.Visibility
+android.os.-$Lambda$0$-dncxFEc2F2bgG2fsIoC6FC6WNE
+android.os.-$Lambda$1$-dncxFEc2F2bgG2fsIoC6FC6WNE
+android.os.-$Lambda$5$6x30vPJhBKUfNY8tswxuZo3DCe0
+android.os.-$Lambda$67$OsaxDBgigpqjZN1F4C6nYRYm1YQ
android.os.AsyncResult
+android.os.AsyncTask
android.os.AsyncTask$1
android.os.AsyncTask$2
android.os.AsyncTask$3
@@ -3000,12 +3102,14 @@
android.os.BatteryStats
android.os.BatteryStats$BitDescription
android.os.BatteryStats$ControllerActivityCounter
+android.os.BatteryStats$Counter
android.os.BatteryStats$DailyItem
android.os.BatteryStats$HistoryEventTracker
android.os.BatteryStats$HistoryItem
android.os.BatteryStats$HistoryPrinter
android.os.BatteryStats$HistoryStepDetails
android.os.BatteryStats$HistoryTag
+android.os.BatteryStats$IntToString
android.os.BatteryStats$LevelStepTracker
android.os.BatteryStats$LongCounter
android.os.BatteryStats$PackageChange
@@ -3014,6 +3118,7 @@
android.os.BatteryStats$Uid$Pid
android.os.BatteryStats$Uid$Pkg
android.os.BatteryStats$Uid$Pkg$Serv
+android.os.BatteryStats$Uid$Proc
android.os.BatteryStats$Uid$Sensor
android.os.BatteryStats$Uid$Wakelock
android.os.Binder
@@ -3042,16 +3147,20 @@
android.os.Environment
android.os.Environment$UserEnvironment
android.os.FactoryTest
-android.os.FileBridge
-android.os.FileBridge$FileBridgeOutputStream
+android.os.FileObserver
android.os.FileObserver$ObserverThread
android.os.FileUtils
+android.os.GraphicsEnvironment
android.os.Handler
android.os.Handler$BlockingRunnable
android.os.Handler$Callback
android.os.Handler$MessengerImpl
android.os.HandlerThread
android.os.HardwarePropertiesManager
+android.os.HwBinder
+android.os.HwBlob
+android.os.HwParcel
+android.os.HwRemoteBinder
android.os.IBatteryPropertiesListener
android.os.IBatteryPropertiesListener$Stub
android.os.IBatteryPropertiesRegistrar
@@ -3062,11 +3171,22 @@
android.os.ICancellationSignal
android.os.ICancellationSignal$Stub
android.os.ICancellationSignal$Stub$Proxy
+android.os.IDeviceIdentifiersPolicyService
+android.os.IDeviceIdentifiersPolicyService$Stub
android.os.IDeviceIdleController
android.os.IDeviceIdleController$Stub
android.os.IDeviceIdleController$Stub$Proxy
android.os.IHardwarePropertiesManager
android.os.IHardwarePropertiesManager$Stub
+android.os.IHardwarePropertiesManager$Stub$Proxy
+android.os.IHwBinder
+android.os.IHwBinder$DeathRecipient
+android.os.IHwInterface
+android.os.IIncidentManager
+android.os.IIncidentManager$Stub
+android.os.IInstalld
+android.os.IInstalld$Stub
+android.os.IInstalld$Stub$Proxy
android.os.IInterface
android.os.IMaintenanceActivityListener
android.os.IMessenger
@@ -3084,10 +3204,8 @@
android.os.IProcessInfoService
android.os.IProcessInfoService$Stub
android.os.IProgressListener
-android.os.IProgressListener$Stub
android.os.IRecoverySystem
android.os.IRecoverySystem$Stub
-android.os.IRecoverySystem$Stub$Proxy
android.os.IRecoverySystemProgressListener
android.os.IRemoteCallback
android.os.IRemoteCallback$Stub
@@ -3103,6 +3221,7 @@
android.os.IVibratorService
android.os.IVibratorService$Stub
android.os.IVibratorService$Stub$Proxy
+android.os.IncidentManager
android.os.LocaleList
android.os.LocaleList$1
android.os.Looper
@@ -3115,7 +3234,6 @@
android.os.MessageQueue$OnFileDescriptorEventListener
android.os.Messenger
android.os.Messenger$1
-android.os.NetworkOnMainThreadException
android.os.NullVibrator
android.os.OperationCanceledException
android.os.Parcel
@@ -3141,6 +3259,8 @@
android.os.PersistableBundle
android.os.PersistableBundle$1
android.os.PersistableBundle$MyReadMapCallback
+android.os.PooledStringReader
+android.os.PooledStringWriter
android.os.PowerManager
android.os.PowerManager$WakeLock
android.os.PowerManager$WakeLock$1
@@ -3148,12 +3268,14 @@
android.os.PowerManagerInternal$LowPowerModeListener
android.os.Process
android.os.Process$ProcessStartResult
-android.os.Process$ZygoteState
android.os.RecoverySystem
-android.os.RecoverySystem$ProgressListener
android.os.Registrant
android.os.RegistrantList
android.os.RemoteCallback
+android.os.RemoteCallback$1
+android.os.RemoteCallback$2
+android.os.RemoteCallback$3
+android.os.RemoteCallback$OnResultListener
android.os.RemoteCallbackList
android.os.RemoteCallbackList$Callback
android.os.RemoteException
@@ -3163,9 +3285,13 @@
android.os.ResultReceiver$MyRunnable
android.os.SELinux
android.os.ServiceManager
+android.os.ServiceManager$ServiceNotFoundException
android.os.ServiceManagerNative
android.os.ServiceManagerProxy
android.os.ServiceSpecificException
+android.os.ShellCallback
+android.os.ShellCallback$1
+android.os.ShellCommand
android.os.StatFs
android.os.StrictMode
android.os.StrictMode$1
@@ -3191,6 +3317,7 @@
android.os.StrictMode$ThreadPolicy$Builder
android.os.StrictMode$ThreadSpanState
android.os.StrictMode$ViolationInfo
+android.os.StrictMode$ViolationInfo$1
android.os.StrictMode$VmPolicy
android.os.StrictMode$VmPolicy$Builder
android.os.SynchronousResultReceiver
@@ -3203,11 +3330,9 @@
android.os.SystemVibrator
android.os.TokenWatcher
android.os.TokenWatcher$1
-android.os.TokenWatcher$Death
android.os.Trace
android.os.Trace$1
android.os.TransactionTooLargeException
-android.os.TransactionTracker
android.os.UEventObserver
android.os.UEventObserver$UEvent
android.os.UEventObserver$UEventThread
@@ -3220,26 +3345,30 @@
android.os.Vibrator
android.os.WorkSource
android.os.WorkSource$1
+android.os.ZygoteProcess
+android.os.ZygoteProcess$ZygoteState
android.os.ZygoteStartFailedEx
+android.os.health.HealthStats
android.os.health.HealthStatsParceler
android.os.health.SystemHealthManager
+android.os.health.TimerStat
android.os.storage.DiskInfo
android.os.storage.DiskInfo$1
-android.os.storage.IStorageManager
-android.os.storage.IStorageManager$Stub
-android.os.storage.IStorageManager$Stub$Proxy
+android.os.storage.IObbActionListener
+android.os.storage.IObbActionListener$Stub
android.os.storage.IStorageEventListener
android.os.storage.IStorageEventListener$Stub
android.os.storage.IStorageEventListener$Stub$Proxy
+android.os.storage.IStorageManager
+android.os.storage.IStorageManager$Stub
+android.os.storage.IStorageManager$Stub$Proxy
android.os.storage.IStorageShutdownObserver
-android.os.storage.IObbActionListener
-android.os.storage.IObbActionListener$Stub
-android.os.storage.StorageManagerInternal
-android.os.storage.StorageManagerInternal$ExternalStorageMountPolicy
android.os.storage.StorageEventListener
android.os.storage.StorageManager
android.os.storage.StorageManager$ObbActionListener
android.os.storage.StorageManager$StorageEventListenerDelegate
+android.os.storage.StorageManagerInternal
+android.os.storage.StorageManagerInternal$ExternalStorageMountPolicy
android.os.storage.StorageVolume
android.os.storage.StorageVolume$1
android.os.storage.VolumeInfo
@@ -3247,30 +3376,30 @@
android.os.storage.VolumeInfo$2
android.os.storage.VolumeRecord
android.os.storage.VolumeRecord$1
+android.permissionpresenterservice.RuntimePermissionPresenterService
+android.permissionpresenterservice.RuntimePermissionPresenterService$1
+android.permissionpresenterservice.RuntimePermissionPresenterService$MyHandler
+android.preference.CheckBoxPreference
android.preference.DialogPreference
-android.preference.GenericInflater
android.preference.GenericInflater$Parent
android.preference.ListPreference
android.preference.Preference
+android.preference.Preference$BaseSavedState
+android.preference.Preference$BaseSavedState$1
android.preference.Preference$OnPreferenceChangeInternalListener
android.preference.Preference$OnPreferenceChangeListener
android.preference.Preference$OnPreferenceClickListener
android.preference.PreferenceActivity
-android.preference.PreferenceActivity$1
-android.preference.PreferenceActivity$Header
-android.preference.PreferenceActivity$Header$1
android.preference.PreferenceFragment
android.preference.PreferenceFragment$1
android.preference.PreferenceFragment$2
android.preference.PreferenceFragment$3
android.preference.PreferenceFragment$OnPreferenceStartFragmentCallback
android.preference.PreferenceFrameLayout
-android.preference.PreferenceFrameLayout$LayoutParams
android.preference.PreferenceGroup
android.preference.PreferenceGroupAdapter
android.preference.PreferenceGroupAdapter$1
android.preference.PreferenceGroupAdapter$PreferenceLayout
-android.preference.PreferenceInflater
android.preference.PreferenceManager
android.preference.PreferenceManager$OnActivityDestroyListener
android.preference.PreferenceManager$OnPreferenceTreeClickListener
@@ -3285,8 +3414,6 @@
android.preference.TwoStatePreference
android.print.IPrintDocumentAdapter
android.print.IPrintJobStateChangeListener
-android.print.IPrintJobStateChangeListener$Stub
-android.print.IPrintJobStateChangeListener$Stub$Proxy
android.print.IPrintManager
android.print.IPrintManager$Stub
android.print.IPrintManager$Stub$Proxy
@@ -3298,7 +3425,6 @@
android.print.IPrintSpooler$Stub$Proxy
android.print.IPrintSpoolerCallbacks
android.print.IPrintSpoolerCallbacks$Stub
-android.print.IPrintSpoolerCallbacks$Stub$Proxy
android.print.IPrintSpoolerClient
android.print.IPrintSpoolerClient$Stub
android.print.IPrintSpoolerClient$Stub$Proxy
@@ -3314,31 +3440,25 @@
android.print.PrintDocumentAdapter$WriteResultCallback
android.print.PrintDocumentInfo
android.print.PrintDocumentInfo$Builder
-android.print.PrintJob
android.print.PrintJobId
android.print.PrintJobInfo
-android.print.PrintJobInfo$1
android.print.PrintManager
android.print.PrintManager$1
-android.print.PrintManager$PrintJobStateChangeListener
-android.print.PrintManager$PrintJobStateChangeListenerWrapper
android.print.PrintManager$PrintServicesChangeListener
android.print.PrintManager$PrintServicesChangeListenerWrapper
android.print.PrintServicesLoader
android.print.PrintServicesLoader$1
android.print.PrintServicesLoader$MyHandler
android.print.PrinterId
-android.print.pdf.PrintedPdfDocument
android.printservice.IPrintServiceClient
android.printservice.IPrintServiceClient$Stub
android.printservice.PrintServiceInfo
android.printservice.PrintServiceInfo$1
android.printservice.recommendation.IRecommendationsChangeListener
+android.provider.-$Lambda$46$87WmhkvObehVg0OMBzwa_MTVV8g
android.provider.BaseColumns
android.provider.BlockedNumberContract
android.provider.BlockedNumberContract$BlockedNumbers
-android.provider.BlockedNumberContract$SystemContract
-android.provider.BlockedNumberContract$SystemContract$BlockSuppressionStatus
android.provider.CalendarContract
android.provider.CalendarContract$Attendees
android.provider.CalendarContract$AttendeesColumns
@@ -3367,12 +3487,16 @@
android.provider.CallLog
android.provider.CallLog$Calls
android.provider.Contacts
+android.provider.Contacts$ContactMethods
+android.provider.Contacts$ContactMethodsColumns
+android.provider.Contacts$PeopleColumns
android.provider.ContactsContract
android.provider.ContactsContract$AggregationExceptions
android.provider.ContactsContract$BaseSyncColumns
android.provider.ContactsContract$CommonDataKinds$BaseTypes
android.provider.ContactsContract$CommonDataKinds$Callable
android.provider.ContactsContract$CommonDataKinds$CommonColumns
+android.provider.ContactsContract$CommonDataKinds$Contactables
android.provider.ContactsContract$CommonDataKinds$Email
android.provider.ContactsContract$CommonDataKinds$Event
android.provider.ContactsContract$CommonDataKinds$Im
@@ -3385,7 +3509,6 @@
android.provider.ContactsContract$ContactOptionsColumns
android.provider.ContactsContract$ContactStatusColumns
android.provider.ContactsContract$Contacts
-android.provider.ContactsContract$Contacts$AggregationSuggestions$Builder
android.provider.ContactsContract$ContactsColumns
android.provider.ContactsContract$Data
android.provider.ContactsContract$DataColumns
@@ -3397,7 +3520,6 @@
android.provider.ContactsContract$Directory
android.provider.ContactsContract$DisplayPhoto
android.provider.ContactsContract$Groups
-android.provider.ContactsContract$Groups$EntityIteratorImpl
android.provider.ContactsContract$GroupsColumns
android.provider.ContactsContract$MetadataSync
android.provider.ContactsContract$MetadataSyncColumns
@@ -3408,7 +3530,6 @@
android.provider.ContactsContract$ProviderStatus
android.provider.ContactsContract$QuickContact
android.provider.ContactsContract$RawContacts
-android.provider.ContactsContract$RawContacts$EntityIteratorImpl
android.provider.ContactsContract$RawContactsColumns
android.provider.ContactsContract$RawContactsEntity
android.provider.ContactsContract$Settings
@@ -3418,8 +3539,8 @@
android.provider.ContactsContract$StreamItemsColumns
android.provider.ContactsContract$SyncColumns
android.provider.ContactsContract$SyncState
+android.provider.ContactsInternal
android.provider.DocumentsContract
-android.provider.DocumentsContract$Root
android.provider.DocumentsProvider
android.provider.Downloads
android.provider.Downloads$Impl
@@ -3450,12 +3571,11 @@
android.provider.SearchIndexablesContract
android.provider.SearchIndexablesProvider
android.provider.SearchRecentSuggestions
-android.provider.SearchRecentSuggestions$1
android.provider.Settings
+android.provider.Settings$ContentProviderHolder
android.provider.Settings$GenerationTracker
android.provider.Settings$Global
android.provider.Settings$NameValueCache
-android.provider.Settings$NameValueCache$-java_lang_String_getStringForUser_android_content_ContentResolver_cr_java_lang_String_name_int_userHandle_LambdaImpl0
android.provider.Settings$NameValueTable
android.provider.Settings$Secure
android.provider.Settings$SettingNotFoundException
@@ -3492,18 +3612,21 @@
android.provider.VoicemailContract$Status
android.provider.VoicemailContract$Voicemails
android.renderscript.Allocation
+android.renderscript.Allocation$MipmapControl
android.renderscript.BaseObj
android.renderscript.Element
-android.renderscript.Matrix4f
-android.renderscript.RSRuntimeException
+android.renderscript.Element$DataKind
+android.renderscript.Element$DataType
android.renderscript.RenderScript
+android.renderscript.RenderScript$ContextType
+android.renderscript.RenderScript$MessageThread
android.renderscript.RenderScriptCacheDir
android.renderscript.Script
android.renderscript.ScriptIntrinsic
android.renderscript.ScriptIntrinsicBlur
android.renderscript.Type
-android.security.Credentials
-android.security.FrameworkNetworkSecurityPolicy
+android.renderscript.Type$Builder
+android.renderscript.Type$CubemapFace
android.security.GateKeeper
android.security.IKeyChainService
android.security.IKeyChainService$Stub
@@ -3514,10 +3637,11 @@
android.security.KeyChain
android.security.KeyChain$1
android.security.KeyChain$KeyChainConnection
-android.security.KeyChainAliasCallback
android.security.KeyStore
-android.security.KeyStore$State
android.security.NetworkSecurityPolicy
+android.security.keymaster.IKeyAttestationApplicationIdProvider
+android.security.keymaster.IKeyAttestationApplicationIdProvider$Stub
+android.security.keymaster.KeyAttestationApplicationId
android.security.keymaster.KeymasterArguments
android.security.keymaster.KeymasterArguments$1
android.security.keystore.AndroidKeyStoreBCWorkaroundProvider
@@ -3559,12 +3683,20 @@
android.security.net.config.RootTrustManager
android.security.net.config.RootTrustManagerFactorySpi
android.security.net.config.SystemCertificateSource
-android.security.net.config.TrustAnchor
+android.security.net.config.SystemCertificateSource$NoPreloadHolder
android.security.net.config.TrustedCertificateStoreAdapter
android.security.net.config.UserCertificateSource
+android.security.net.config.UserCertificateSource$NoPreloadHolder
+android.security.net.config.XmlConfigSource
+android.security.net.config.XmlConfigSource$ParserException
+android.service.autofill.IAutoFillManagerService
+android.service.autofill.IAutoFillManagerService$Stub
+android.service.autofill.IAutoFillManagerService$Stub$Proxy
android.service.carrier.CarrierIdentifier
+android.service.carrier.CarrierIdentifier$1
android.service.carrier.ICarrierService
android.service.carrier.ICarrierService$Stub
+android.service.carrier.ICarrierService$Stub$Proxy
android.service.chooser.ChooserTarget
android.service.chooser.ChooserTargetService
android.service.dreams.DreamManagerInternal
@@ -3580,13 +3712,22 @@
android.service.dreams.IDreamService
android.service.dreams.IDreamService$Stub
android.service.dreams.IDreamService$Stub$Proxy
-android.service.gatekeeper.GateKeeperResponse
-android.service.gatekeeper.GateKeeperResponse$1
android.service.gatekeeper.IGateKeeperService
android.service.gatekeeper.IGateKeeperService$Stub
android.service.gatekeeper.IGateKeeperService$Stub$Proxy
-android.service.media.CameraPrewarmService
+android.service.media.IMediaBrowserService
+android.service.media.IMediaBrowserService$Stub
+android.service.media.IMediaBrowserService$Stub$Proxy
+android.service.media.IMediaBrowserServiceCallbacks
+android.service.media.IMediaBrowserServiceCallbacks$Stub
+android.service.media.IMediaBrowserServiceCallbacks$Stub$Proxy
android.service.media.MediaBrowserService
+android.service.media.MediaBrowserService$1
+android.service.media.MediaBrowserService$BrowserRoot
+android.service.media.MediaBrowserService$ConnectionRecord
+android.service.media.MediaBrowserService$Result
+android.service.media.MediaBrowserService$ServiceBinder
+android.service.media.MediaBrowserService$ServiceBinder$1
android.service.notification.Adjustment
android.service.notification.Condition
android.service.notification.Condition$1
@@ -3597,6 +3738,7 @@
android.service.notification.IConditionListener$Stub
android.service.notification.IConditionProvider
android.service.notification.IConditionProvider$Stub
+android.service.notification.IConditionProvider$Stub$Proxy
android.service.notification.INotificationListener
android.service.notification.INotificationListener$Stub
android.service.notification.INotificationListener$Stub$Proxy
@@ -3609,9 +3751,6 @@
android.service.notification.NotificationListenerService$Ranking
android.service.notification.NotificationListenerService$RankingMap
android.service.notification.NotificationListenerService$RankingMap$1
-android.service.notification.NotificationAssistantService
-android.service.notification.NotificationAssistantService$MyHandler
-android.service.notification.NotificationAssistantService$NotificationRankingServiceWrapper
android.service.notification.NotificationRankingUpdate
android.service.notification.NotificationRankingUpdate$1
android.service.notification.StatusBarNotification
@@ -3620,9 +3759,7 @@
android.service.notification.ZenModeConfig$1
android.service.notification.ZenModeConfig$Diff
android.service.notification.ZenModeConfig$EventInfo
-android.service.notification.ZenModeConfig$Migration
android.service.notification.ZenModeConfig$ScheduleInfo
-android.service.notification.ZenModeConfig$XmlV1
android.service.notification.ZenModeConfig$ZenRule
android.service.notification.ZenModeConfig$ZenRule$1
android.service.persistentdata.IPersistentDataBlockService
@@ -3633,6 +3770,7 @@
android.service.quicksettings.IQSService$Stub
android.service.quicksettings.IQSTileService
android.service.quicksettings.Tile
+android.service.quicksettings.Tile$1
android.service.quicksettings.TileService
android.service.textservice.SpellCheckerService
android.service.textservice.SpellCheckerService$InternalISpellCheckerSession
@@ -3641,16 +3779,6 @@
android.service.textservice.SpellCheckerService$SentenceLevelAdapter$SentenceWordItem
android.service.textservice.SpellCheckerService$Session
android.service.textservice.SpellCheckerService$SpellCheckerServiceBinder
-android.service.trust.ITrustAgentService
-android.service.trust.ITrustAgentService$Stub
-android.service.trust.ITrustAgentService$Stub$Proxy
-android.service.trust.ITrustAgentServiceCallback
-android.service.trust.ITrustAgentServiceCallback$Stub
-android.service.trust.ITrustAgentServiceCallback$Stub$Proxy
-android.service.trust.TrustAgentService
-android.service.trust.TrustAgentService$1
-android.service.trust.TrustAgentService$ConfigurationData
-android.service.trust.TrustAgentService$TrustAgentServiceWrapper
android.service.voice.AlwaysOnHotwordDetector
android.service.voice.AlwaysOnHotwordDetector$Callback
android.service.voice.AlwaysOnHotwordDetector$EventPayload
@@ -3661,12 +3789,33 @@
android.service.voice.IVoiceInteractionService$Stub
android.service.voice.IVoiceInteractionService$Stub$Proxy
android.service.voice.IVoiceInteractionSession
+android.service.voice.IVoiceInteractionSession$Stub
+android.service.voice.IVoiceInteractionSession$Stub$Proxy
+android.service.voice.IVoiceInteractionSessionService
+android.service.voice.IVoiceInteractionSessionService$Stub
+android.service.voice.IVoiceInteractionSessionService$Stub$Proxy
android.service.voice.VoiceInteractionManagerInternal
android.service.voice.VoiceInteractionService
android.service.voice.VoiceInteractionService$1
android.service.voice.VoiceInteractionService$MyHandler
android.service.voice.VoiceInteractionServiceInfo
android.service.voice.VoiceInteractionSession
+android.service.voice.VoiceInteractionSession$1
+android.service.voice.VoiceInteractionSession$2
+android.service.voice.VoiceInteractionSession$2$1
+android.service.voice.VoiceInteractionSession$3
+android.service.voice.VoiceInteractionSession$4
+android.service.voice.VoiceInteractionSession$AbortVoiceRequest
+android.service.voice.VoiceInteractionSession$CommandRequest
+android.service.voice.VoiceInteractionSession$CompleteVoiceRequest
+android.service.voice.VoiceInteractionSession$ConfirmationRequest
+android.service.voice.VoiceInteractionSession$Insets
+android.service.voice.VoiceInteractionSession$MyCallbacks
+android.service.voice.VoiceInteractionSession$PickOptionRequest
+android.service.voice.VoiceInteractionSession$Request
+android.service.voice.VoiceInteractionSessionService
+android.service.voice.VoiceInteractionSessionService$1
+android.service.voice.VoiceInteractionSessionService$2
android.service.vr.IVrManager
android.service.vr.IVrManager$Stub
android.service.vr.IVrManager$Stub$Proxy
@@ -3733,6 +3882,7 @@
android.system.StructFlock
android.system.StructGroupReq
android.system.StructGroupSourceReq
+android.system.StructIfaddrs
android.system.StructLinger
android.system.StructPasswd
android.system.StructPollfd
@@ -3742,6 +3892,7 @@
android.system.StructUcred
android.system.StructUtsname
android.system.UnixSocketAddress
+android.telecom.-$Lambda$3$afyb_ODGzn3xMew6fjs8ANSIdVo
android.telecom.AudioState
android.telecom.AudioState$1
android.telecom.Call
@@ -3760,8 +3911,8 @@
android.telecom.Connection
android.telecom.Connection$1
android.telecom.Connection$2
+android.telecom.Connection$FailureSignalingConnection
android.telecom.Connection$Listener
-android.telecom.Connection$VideoProvider
android.telecom.ConnectionRequest
android.telecom.ConnectionRequest$1
android.telecom.ConnectionService
@@ -3783,12 +3934,29 @@
android.telecom.InCallService$2
android.telecom.InCallService$InCallServiceBinder
android.telecom.InCallService$VideoCall
-android.telecom.InCallService$VideoCall$Callback
android.telecom.Log
android.telecom.Log$1
+android.telecom.Logging.-$Lambda$2$OwO3BlCgqcOx28O1BaOAPVPor24
+android.telecom.Logging.-$Lambda$35$OwO3BlCgqcOx28O1BaOAPVPor24
+android.telecom.Logging.-$Lambda$47$OwO3BlCgqcOx28O1BaOAPVPor24
+android.telecom.Logging.EventManager
+android.telecom.Logging.EventManager$Event
+android.telecom.Logging.EventManager$EventListener
+android.telecom.Logging.EventManager$EventRecord
+android.telecom.Logging.EventManager$Loggable
+android.telecom.Logging.EventManager$TimedEventPair
+android.telecom.Logging.Runnable
+android.telecom.Logging.Runnable$1
+android.telecom.Logging.Session
+android.telecom.Logging.Session$Info
+android.telecom.Logging.Session$Info$1
+android.telecom.Logging.SessionManager
+android.telecom.Logging.SessionManager$ICurrentThreadId
+android.telecom.Logging.SessionManager$ISessionCleanupTimeoutMs
+android.telecom.Logging.SessionManager$ISessionIdQueryHandler
+android.telecom.Logging.SessionManager$ISessionListener
android.telecom.ParcelableCall
android.telecom.ParcelableCall$1
-android.telecom.ParcelableCallAnalytics
android.telecom.ParcelableConference
android.telecom.ParcelableConnection
android.telecom.ParcelableConnection$1
@@ -3800,40 +3968,41 @@
android.telecom.PhoneAccountHandle
android.telecom.PhoneAccountHandle$1
android.telecom.RemoteConnectionManager
-android.telecom.Response
android.telecom.StatusHints
+android.telecom.TelecomAnalytics
+android.telecom.TelecomAnalytics$SessionTiming
+android.telecom.TelecomAnalytics$SessionTiming$1
android.telecom.TelecomManager
+android.telecom.TimedEvent
android.telecom.VideoProfile
android.telecom.VideoProfile$1
-android.telecom.Voicemail
-android.telecom.Voicemail$Builder
android.telephony.CarrierConfigManager
android.telephony.CellBroadcastMessage
android.telephony.CellIdentityCdma
android.telephony.CellIdentityGsm
android.telephony.CellIdentityLte
-android.telephony.CellIdentityLte$1
android.telephony.CellIdentityWcdma
+android.telephony.CellIdentityWcdma$1
android.telephony.CellInfo
android.telephony.CellInfo$1
android.telephony.CellInfoCdma
android.telephony.CellInfoGsm
android.telephony.CellInfoLte
-android.telephony.CellInfoLte$1
android.telephony.CellInfoWcdma
+android.telephony.CellInfoWcdma$1
android.telephony.CellLocation
android.telephony.CellSignalStrength
android.telephony.CellSignalStrengthCdma
android.telephony.CellSignalStrengthGsm
android.telephony.CellSignalStrengthLte
-android.telephony.CellSignalStrengthLte$1
android.telephony.CellSignalStrengthWcdma
+android.telephony.CellSignalStrengthWcdma$1
+android.telephony.ClientRequestStats
+android.telephony.ClientRequestStats$1
android.telephony.DisconnectCause
android.telephony.IccOpenLogicalChannelResponse
android.telephony.ModemActivityInfo
android.telephony.ModemActivityInfo$1
-android.telephony.NeighboringCellInfo
-android.telephony.NeighboringCellInfo$1
android.telephony.PhoneNumberFormattingTextWatcher
android.telephony.PhoneNumberUtils
android.telephony.PhoneStateListener
@@ -3844,7 +4013,6 @@
android.telephony.PreciseDataConnectionState
android.telephony.PreciseDataConnectionState$1
android.telephony.RadioAccessFamily
-android.telephony.RadioAccessFamily$1
android.telephony.Rlog
android.telephony.ServiceState
android.telephony.ServiceState$1
@@ -3859,26 +4027,41 @@
android.telephony.SubscriptionManager$OnSubscriptionsChangedListener
android.telephony.SubscriptionManager$OnSubscriptionsChangedListener$1
android.telephony.SubscriptionManager$OnSubscriptionsChangedListener$2
+android.telephony.TelephonyHistogram
+android.telephony.TelephonyHistogram$1
android.telephony.TelephonyManager
android.telephony.TelephonyManager$MultiSimVariants
+android.telephony.VisualVoicemailSmsFilterSettings
android.telephony.VoLteServiceState
android.telephony.VoLteServiceState$1
android.telephony.cdma.CdmaCellLocation
+android.telephony.cdma.CdmaSmsCbProgramData
android.telephony.gsm.GsmCellLocation
android.telephony.gsm.SmsMessage
android.text.AndroidBidi
android.text.AndroidCharacter
android.text.Annotation
-android.text.AutoText
android.text.BidiFormatter
android.text.BidiFormatter$DirectionalityEstimator
android.text.BoringLayout
android.text.BoringLayout$Metrics
+android.text.CharSequenceCharacterIterator
android.text.ClipboardManager
android.text.DynamicLayout
android.text.DynamicLayout$ChangeWatcher
android.text.Editable
android.text.Editable$Factory
+android.text.FontConfig
+android.text.FontConfig$1
+android.text.FontConfig$Alias
+android.text.FontConfig$Alias$1
+android.text.FontConfig$Axis
+android.text.FontConfig$Axis$1
+android.text.FontConfig$Family
+android.text.FontConfig$Family$1
+android.text.FontConfig$Font
+android.text.FontConfig$Font$1
+android.text.FontManager
android.text.GetChars
android.text.GraphicsOperations
android.text.Html
@@ -3889,6 +4072,8 @@
android.text.HtmlToSpannedConverter$Bold
android.text.HtmlToSpannedConverter$Href
android.text.Hyphenator
+android.text.ITextClassificationService
+android.text.ITextClassificationService$Stub
android.text.InputFilter
android.text.InputFilter$LengthFilter
android.text.InputType
@@ -3948,16 +4133,12 @@
android.text.method.BaseKeyListener
android.text.method.BaseMovementMethod
android.text.method.DialerKeyListener
-android.text.method.DigitsKeyListener
android.text.method.KeyListener
android.text.method.LinkMovementMethod
android.text.method.MetaKeyKeyListener
android.text.method.MovementMethod
android.text.method.NumberKeyListener
android.text.method.PasswordTransformationMethod
-android.text.method.PasswordTransformationMethod$PasswordCharSequence
-android.text.method.PasswordTransformationMethod$ViewReference
-android.text.method.PasswordTransformationMethod$Visible
android.text.method.QwertyKeyListener
android.text.method.QwertyKeyListener$Replaced
android.text.method.ReplacementTransformationMethod
@@ -3975,7 +4156,6 @@
android.text.method.WordIterator
android.text.style.AbsoluteSizeSpan
android.text.style.AlignmentSpan
-android.text.style.AlignmentSpan$Standard
android.text.style.BackgroundColorSpan
android.text.style.BulletSpan
android.text.style.CharacterStyle
@@ -3994,7 +4174,6 @@
android.text.style.MetricAffectingSpan
android.text.style.MetricAffectingSpan$Passthrough
android.text.style.ParagraphStyle
-android.text.style.QuoteSpan
android.text.style.RelativeSizeSpan
android.text.style.ReplacementSpan
android.text.style.SpellCheckSpan
@@ -4002,7 +4181,6 @@
android.text.style.StyleSpan
android.text.style.SubscriptSpan
android.text.style.SuggestionSpan
-android.text.style.SuggestionSpan$1
android.text.style.SuperscriptSpan
android.text.style.TabStopSpan
android.text.style.TextAppearanceSpan
@@ -4012,7 +4190,6 @@
android.text.style.TtsSpan$SemioticClassBuilder
android.text.style.TtsSpan$TelephoneBuilder
android.text.style.TtsSpan$TextBuilder
-android.text.style.TtsSpan$VerbatimBuilder
android.text.style.TypefaceSpan
android.text.style.URLSpan
android.text.style.UnderlineSpan
@@ -4028,7 +4205,6 @@
android.text.util.Linkify$TransformFilter
android.text.util.Rfc822Token
android.text.util.Rfc822Tokenizer
-android.transition.ArcMotion
android.transition.AutoTransition
android.transition.ChangeBounds
android.transition.ChangeBounds$1
@@ -4051,8 +4227,6 @@
android.transition.ChangeTransform$GhostListener
android.transition.ChangeTransform$PathAnimatorMatrix
android.transition.ChangeTransform$Transforms
-android.transition.CircularPropagation
-android.transition.Explode
android.transition.Fade
android.transition.Fade$1
android.transition.Fade$FadeAnimatorListener
@@ -4074,7 +4248,6 @@
android.transition.Transition$2
android.transition.Transition$3
android.transition.Transition$AnimationInfo
-android.transition.Transition$ArrayListManager
android.transition.Transition$EpicenterCallback
android.transition.Transition$TransitionListener
android.transition.Transition$TransitionListenerAdapter
@@ -4087,7 +4260,6 @@
android.transition.TransitionSet$1
android.transition.TransitionSet$TransitionSetListener
android.transition.TransitionUtils
-android.transition.TransitionUtils$MatrixEvaluator
android.transition.TransitionValues
android.transition.TransitionValuesMaps
android.transition.TranslationAnimationCreator
@@ -4109,7 +4281,7 @@
android.util.Base64$Coder
android.util.Base64$Decoder
android.util.Base64$Encoder
-android.util.Base64DataException
+android.util.BootTimingsTraceLog
android.util.ContainerHelpers
android.util.DebugUtils
android.util.DisplayMetrics
@@ -4130,12 +4302,14 @@
android.util.Log
android.util.Log$1
android.util.Log$ImmediateLogWriter
-android.util.Log$TerribleFailure
+android.util.Log$NoPreloadHolder
android.util.Log$TerribleFailureHandler
android.util.LogPrinter
+android.util.LongArray
android.util.LongSparseArray
android.util.LongSparseLongArray
android.util.LruCache
+android.util.MalformedJsonException
android.util.MapCollections
android.util.MapCollections$ArrayIterator
android.util.MapCollections$EntrySet
@@ -4161,6 +4335,7 @@
android.util.Property
android.util.Range
android.util.Rational
+android.util.ReflectiveProperty
android.util.Singleton
android.util.Size
android.util.SizeF
@@ -4172,7 +4347,6 @@
android.util.Spline
android.util.Spline$MonotoneCubicSpline
android.util.StateSet
-android.util.StringBuilderPrinter
android.util.SuperNotCalledException
android.util.TimeFormatException
android.util.TimeUtils
@@ -4184,18 +4358,17 @@
android.util.Xml$Encoding
android.util.Xml$XmlSerializerFactory
android.util.apk.ApkSignatureSchemeV2Verifier
+android.util.apk.ApkSignatureSchemeV2Verifier$ByteBufferDataSource
+android.util.apk.ApkSignatureSchemeV2Verifier$DataSource
+android.util.apk.ApkSignatureSchemeV2Verifier$MemoryMappedFileDataSource
+android.util.apk.ApkSignatureSchemeV2Verifier$SignatureInfo
android.util.apk.ApkSignatureSchemeV2Verifier$SignatureNotFoundException
+android.util.apk.ApkSignatureSchemeV2Verifier$VerbatimX509Certificate
+android.util.apk.ApkSignatureSchemeV2Verifier$WrappedX509Certificate
android.util.apk.ZipUtils
android.util.jar.StrictJarFile
-android.util.jar.StrictJarFile$EntryIterator
-android.util.jar.StrictJarFile$JarFileInputStream
-android.util.jar.StrictJarFile$RAFStream
-android.util.jar.StrictJarFile$ZipInflaterInputStream
-android.util.jar.StrictJarManifest
-android.util.jar.StrictJarManifest$Chunk
-android.util.jar.StrictJarManifestReader
-android.util.jar.StrictJarVerifier
-android.util.jar.StrictJarVerifier$VerifierEntry
+android.view.-$Lambda$48$iU_USrtPm1XIm5H9QYQvXfBGDE4
+android.view.-$Lambda$49$iU_USrtPm1XIm5H9QYQvXfBGDE4
android.view.AbsSavedState
android.view.AbsSavedState$1
android.view.AbsSavedState$2
@@ -4219,8 +4392,6 @@
android.view.ContextMenu$ContextMenuInfo
android.view.ContextThemeWrapper
android.view.Display
-android.view.Display$ColorTransform
-android.view.Display$ColorTransform$1
android.view.Display$HdrCapabilities
android.view.Display$HdrCapabilities$1
android.view.Display$Mode
@@ -4247,8 +4418,6 @@
android.view.GestureDetector$OnGestureListener
android.view.GestureDetector$SimpleOnGestureListener
android.view.GhostView
-android.view.GraphicBuffer
-android.view.GraphicBuffer$1
android.view.Gravity
android.view.HandlerActionQueue
android.view.HandlerActionQueue$HandlerAction
@@ -4266,8 +4435,15 @@
android.view.IGraphicsStats$Stub$Proxy
android.view.IInputFilter
android.view.IOnKeyguardExitResult
+android.view.IPinnedStackController
+android.view.IPinnedStackController$Stub
+android.view.IPinnedStackController$Stub$Proxy
+android.view.IPinnedStackListener
+android.view.IPinnedStackListener$Stub
+android.view.IPinnedStackListener$Stub$Proxy
android.view.IRotationWatcher
android.view.IRotationWatcher$Stub
+android.view.IRotationWatcher$Stub$Proxy
android.view.IWindow
android.view.IWindow$Stub
android.view.IWindow$Stub$Proxy
@@ -4307,8 +4483,6 @@
android.view.KeyEvent$1
android.view.KeyEvent$Callback
android.view.KeyEvent$DispatcherState
-android.view.KeyboardShortcutGroup
-android.view.KeyboardShortcutInfo
android.view.LayoutInflater
android.view.LayoutInflater$Factory
android.view.LayoutInflater$Factory2
@@ -4327,16 +4501,20 @@
android.view.MotionEvent$PointerProperties
android.view.NotificationHeaderView
android.view.NotificationHeaderView$1
+android.view.NotificationHeaderView$2
android.view.NotificationHeaderView$HeaderTouchListener
android.view.OrientationEventListener
android.view.OrientationEventListener$SensorEventListenerImpl
android.view.PointerIcon
android.view.PointerIcon$1
+android.view.RecordingCanvas
android.view.RemotableViewMethod
android.view.RenderNode
+android.view.RenderNode$NoImagePreloadHolder
android.view.RenderNodeAnimator
android.view.RenderNodeAnimator$1
android.view.RenderNodeAnimator$DelayedAnimationHelper
+android.view.RenderNodeAnimatorSetHelper
android.view.ScaleGestureDetector
android.view.ScaleGestureDetector$1
android.view.ScaleGestureDetector$OnScaleGestureListener
@@ -4347,6 +4525,7 @@
android.view.Surface
android.view.Surface$1
android.view.Surface$CompatibleCanvas
+android.view.Surface$HwuiContext
android.view.Surface$OutOfResourcesException
android.view.SurfaceControl
android.view.SurfaceControl$PhysicalDisplayInfo
@@ -4364,7 +4543,7 @@
android.view.TextureView$1
android.view.TextureView$SurfaceTextureListener
android.view.ThreadedRenderer
-android.view.ThreadedRenderer$HardwareDrawCallbacks
+android.view.ThreadedRenderer$DrawCallbacks
android.view.ThreadedRenderer$ProcessInitializer
android.view.TouchDelegate
android.view.VelocityTracker
@@ -4412,21 +4591,24 @@
android.view.View$PerformClick
android.view.View$ScrollabilityCache
android.view.View$TintInfo
+android.view.View$TooltipInfo
android.view.View$TransformationInfo
android.view.View$UnsetPressedState
android.view.ViewAnimationUtils
android.view.ViewConfiguration
+android.view.ViewDebug$CapturedViewProperty
+android.view.ViewDebug$ExportedProperty
android.view.ViewDebug$HierarchyHandler
android.view.ViewGroup
android.view.ViewGroup$1
android.view.ViewGroup$2
android.view.ViewGroup$3
+android.view.ViewGroup$4
android.view.ViewGroup$LayoutParams
android.view.ViewGroup$MarginLayoutParams
android.view.ViewGroup$OnHierarchyChangeListener
android.view.ViewGroup$TouchTarget
android.view.ViewGroupOverlay
-android.view.ViewHierarchyEncoder
android.view.ViewManager
android.view.ViewOutlineProvider
android.view.ViewOutlineProvider$1
@@ -4489,6 +4671,7 @@
android.view.Window
android.view.Window$Callback
android.view.Window$OnWindowDismissedCallback
+android.view.Window$OnWindowSwipeDismissedCallback
android.view.Window$WindowControllerCallback
android.view.WindowAnimationFrameStats
android.view.WindowAnimationFrameStats$1
@@ -4520,18 +4703,20 @@
android.view.WindowManagerPolicy$OnKeyguardExitResult
android.view.WindowManagerPolicy$PointerEventListener
android.view.WindowManagerPolicy$ScreenOnListener
+android.view.WindowManagerPolicy$StartingSurface
android.view.WindowManagerPolicy$WindowManagerFuncs
android.view.WindowManagerPolicy$WindowState
android.view.accessibility.AccessibilityEvent
-android.view.accessibility.AccessibilityEvent$1
android.view.accessibility.AccessibilityEventSource
android.view.accessibility.AccessibilityManager
android.view.accessibility.AccessibilityManager$1
+android.view.accessibility.AccessibilityManager$AccessibilityServicesStateChangeListener
android.view.accessibility.AccessibilityManager$AccessibilityStateChangeListener
android.view.accessibility.AccessibilityManager$HighTextContrastChangeListener
android.view.accessibility.AccessibilityManager$MyHandler
android.view.accessibility.AccessibilityManager$TouchExplorationStateChangeListener
android.view.accessibility.AccessibilityNodeInfo
+android.view.accessibility.AccessibilityNodeInfo$1
android.view.accessibility.AccessibilityNodeInfo$AccessibilityAction
android.view.accessibility.AccessibilityNodeInfo$CollectionInfo
android.view.accessibility.AccessibilityNodeInfo$CollectionItemInfo
@@ -4561,6 +4746,8 @@
android.view.animation.Animation$NoImagePreloadHolder
android.view.animation.AnimationSet
android.view.animation.AnimationUtils
+android.view.animation.AnimationUtils$1
+android.view.animation.AnimationUtils$AnimationState
android.view.animation.BaseInterpolator
android.view.animation.ClipRectAnimation
android.view.animation.CycleInterpolator
@@ -4576,12 +4763,16 @@
android.view.animation.ScaleAnimation
android.view.animation.Transformation
android.view.animation.TranslateAnimation
+android.view.autofill.AutoFillId
+android.view.autofill.AutoFillId$1
+android.view.autofill.AutoFillManager
+android.view.autofill.AutoFillType
+android.view.autofill.AutoFillType$1
android.view.inputmethod.BaseInputConnection
android.view.inputmethod.CompletionInfo
android.view.inputmethod.CompletionInfo$1
android.view.inputmethod.ComposingText
android.view.inputmethod.CorrectionInfo
-android.view.inputmethod.CorrectionInfo$1
android.view.inputmethod.CursorAnchorInfo
android.view.inputmethod.CursorAnchorInfo$Builder
android.view.inputmethod.EditorInfo
@@ -4595,6 +4786,7 @@
android.view.inputmethod.InputConnection
android.view.inputmethod.InputConnectionInspector
android.view.inputmethod.InputConnectionWrapper
+android.view.inputmethod.InputContentInfo
android.view.inputmethod.InputMethod
android.view.inputmethod.InputMethod$SessionCallback
android.view.inputmethod.InputMethodInfo
@@ -4614,6 +4806,8 @@
android.view.inputmethod.InputMethodSubtype$1
android.view.inputmethod.InputMethodSubtype$InputMethodSubtypeBuilder
android.view.inputmethod.InputMethodSubtypeArray
+android.view.textclassifier.TextClassificationManager
+android.view.textclassifier.TextLanguage
android.view.textservice.SentenceSuggestionsInfo
android.view.textservice.SentenceSuggestionsInfo$1
android.view.textservice.SpellCheckerInfo
@@ -4645,10 +4839,13 @@
android.webkit.JsPromptResult
android.webkit.JsResult
android.webkit.MimeTypeMap
+android.webkit.ServiceWorkerClient
android.webkit.ServiceWorkerController
+android.webkit.ServiceWorkerWebSettings
android.webkit.SslErrorHandler
android.webkit.TokenBindingService
android.webkit.URLUtil
+android.webkit.UserPackage
android.webkit.ValueCallback
android.webkit.WebBackForwardList
android.webkit.WebChromeClient
@@ -4657,7 +4854,6 @@
android.webkit.WebIconDatabase
android.webkit.WebMessage
android.webkit.WebMessagePort
-android.webkit.WebResourceError
android.webkit.WebResourceRequest
android.webkit.WebResourceResponse
android.webkit.WebSettings
@@ -4693,12 +4889,13 @@
android.webkit.WebViewProviderInfo$1
android.webkit.WebViewProviderResponse
android.webkit.WebViewProviderResponse$1
+android.webkit.WebViewZygote
+android.widget.-$Lambda$50$tfOQKOmkDz_xLYaBQX_cysn8vbE
android.widget.AbsListView
android.widget.AbsListView$3
android.widget.AbsListView$4
android.widget.AbsListView$AbsPositionScroller
android.widget.AbsListView$AdapterDataSetObserver
-android.widget.AbsListView$CheckForLongPress
android.widget.AbsListView$CheckForTap
android.widget.AbsListView$FlingRunnable
android.widget.AbsListView$FlingRunnable$1
@@ -4709,6 +4906,7 @@
android.widget.AbsListView$OnScrollListener
android.widget.AbsListView$PerformClick
android.widget.AbsListView$PositionScroller
+android.widget.AbsListView$PositionScroller$1
android.widget.AbsListView$RecycleBin
android.widget.AbsListView$RecyclerListener
android.widget.AbsListView$SavedState
@@ -4746,7 +4944,6 @@
android.widget.AdapterView$OnItemLongClickListener
android.widget.AdapterView$OnItemSelectedListener
android.widget.AdapterView$SelectionNotifier
-android.widget.Advanceable
android.widget.ArrayAdapter
android.widget.AutoCompleteTextView
android.widget.AutoCompleteTextView$DropDownItemClickListener
@@ -4768,7 +4965,6 @@
android.widget.CompoundButton$SavedState$1
android.widget.CursorAdapter
android.widget.CursorFilter$CursorFilterClient
-android.widget.DatePicker
android.widget.DatePicker$OnDateChangedListener
android.widget.DateTimeView
android.widget.DateTimeView$ReceiverInfo
@@ -4781,7 +4977,6 @@
android.widget.Editor$1
android.widget.Editor$2
android.widget.Editor$Blink
-android.widget.Editor$CorrectionHighlighter
android.widget.Editor$CursorAnchorInfoNotifier
android.widget.Editor$CursorController
android.widget.Editor$EditOperation
@@ -4794,6 +4989,7 @@
android.widget.Editor$InsertionPointCursorController
android.widget.Editor$PositionListener
android.widget.Editor$ProcessTextIntentActionsHandler
+android.widget.Editor$SelectionHandleView
android.widget.Editor$SelectionModifierCursorController
android.widget.Editor$SpanController
android.widget.Editor$SuggestionHelper
@@ -4802,7 +4998,6 @@
android.widget.Editor$TextViewPositionListener
android.widget.Editor$UndoInputFilter
android.widget.ExpandableListConnector
-android.widget.ExpandableListView
android.widget.FastScroller
android.widget.FastScroller$1
android.widget.FastScroller$2
@@ -4896,7 +5091,6 @@
android.widget.PopupWindow$1
android.widget.PopupWindow$2
android.widget.PopupWindow$3
-android.widget.PopupWindow$4
android.widget.PopupWindow$OnDismissListener
android.widget.PopupWindow$PopupBackgroundView
android.widget.PopupWindow$PopupDecorView
@@ -4904,6 +5098,7 @@
android.widget.PopupWindow$PopupDecorView$2
android.widget.PopupWindow$PopupDecorView$2$1
android.widget.PopupWindow$PopupDecorView$3
+android.widget.PopupWindow$PopupDecorView$4
android.widget.ProgressBar
android.widget.ProgressBar$1
android.widget.ProgressBar$ProgressTintInfo
@@ -4943,10 +5138,7 @@
android.widget.RemoteViews$SetDrawableParameters
android.widget.RemoteViews$SetOnClickPendingIntent
android.widget.RemoteViews$SetOnClickPendingIntent$1
-android.widget.RemoteViews$SetRemoteInputsAction
-android.widget.RemoteViews$TextViewDrawableAction
android.widget.RemoteViews$ViewGroupAction
-android.widget.RemoteViews$ViewPaddingAction
android.widget.RemoteViewsAdapter$RemoteAdapterConnectionCallback
android.widget.RemoteViewsService
android.widget.RemoteViewsService$RemoteViewsFactory
@@ -4973,11 +5165,10 @@
android.widget.SearchView$OnCloseListener
android.widget.SearchView$OnQueryTextListener
android.widget.SearchView$SearchAutoComplete
+android.widget.SearchView$UpdatableTouchDelegate
android.widget.SectionIndexer
android.widget.SeekBar
android.widget.SeekBar$OnSeekBarChangeListener
-android.widget.SimpleAdapter
-android.widget.SimpleAdapter$ViewBinder
android.widget.SimpleCursorAdapter
android.widget.Space
android.widget.SpellChecker
@@ -4985,7 +5176,6 @@
android.widget.SpellChecker$SpellParser
android.widget.Spinner
android.widget.Spinner$1
-android.widget.Spinner$DialogPopup
android.widget.Spinner$DropDownAdapter
android.widget.Spinner$DropdownPopup
android.widget.Spinner$DropdownPopup$1
@@ -5035,7 +5225,6 @@
android.widget.Toast
android.widget.Toast$TN
android.widget.Toast$TN$1
-android.widget.Toast$TN$2
android.widget.ToggleButton
android.widget.Toolbar
android.widget.Toolbar$1
@@ -5059,6 +5248,7 @@
android.widget.ViewFlipper$2
android.widget.ViewSwitcher
android.widget.WrapperListAdapter
+android.widget.ZoomButtonsController
com.android.dex.ClassData
com.android.dex.ClassData$Method
com.android.dex.ClassDef
@@ -5085,9 +5275,19 @@
com.android.dex.util.ByteOutput
com.android.dex.util.ExceptionWithContext
com.android.dex.util.FileUtils
+com.android.framework.protobuf.nano.CodedInputByteBufferNano
+com.android.framework.protobuf.nano.CodedOutputByteBufferNano
+com.android.framework.protobuf.nano.ExtendableMessageNano
+com.android.framework.protobuf.nano.InternalNano
+com.android.framework.protobuf.nano.InvalidProtocolBufferNanoException
+com.android.framework.protobuf.nano.MessageNano
+com.android.framework.protobuf.nano.WireFormatNano
+com.android.i18n.phonenumbers.AlternateFormatsCountryCodeSet
com.android.i18n.phonenumbers.AsYouTypeFormatter
com.android.i18n.phonenumbers.CountryCodeToRegionCodeMap
com.android.i18n.phonenumbers.MetadataLoader
+com.android.i18n.phonenumbers.MetadataManager
+com.android.i18n.phonenumbers.MetadataManager$1
com.android.i18n.phonenumbers.MetadataSource
com.android.i18n.phonenumbers.MultiFileMetadataSourceImpl
com.android.i18n.phonenumbers.NumberParseException
@@ -5096,7 +5296,6 @@
com.android.i18n.phonenumbers.PhoneNumberMatcher$State
com.android.i18n.phonenumbers.PhoneNumberUtil
com.android.i18n.phonenumbers.PhoneNumberUtil$1
-com.android.i18n.phonenumbers.PhoneNumberUtil$2
com.android.i18n.phonenumbers.PhoneNumberUtil$Leniency
com.android.i18n.phonenumbers.PhoneNumberUtil$Leniency$1
com.android.i18n.phonenumbers.PhoneNumberUtil$Leniency$2
@@ -5114,19 +5313,13 @@
com.android.i18n.phonenumbers.RegexCache
com.android.i18n.phonenumbers.RegexCache$LRUCache
com.android.i18n.phonenumbers.RegexCache$LRUCache$1
+com.android.i18n.phonenumbers.ShortNumbersRegionCodeSet
com.android.i18n.phonenumbers.geocoding.PhoneNumberOfflineGeocoder
-com.android.i18n.phonenumbers.prefixmapper.DefaultMapStorage
com.android.i18n.phonenumbers.prefixmapper.MappingFileProvider
-com.android.i18n.phonenumbers.prefixmapper.PhonePrefixMap
-com.android.i18n.phonenumbers.prefixmapper.PhonePrefixMapStorageStrategy
com.android.i18n.phonenumbers.prefixmapper.PrefixFileReader
-com.android.ims.ImsCall
-com.android.ims.ImsCall$ImsCallSessionListenerProxy
com.android.ims.ImsCall$Listener
com.android.ims.ImsCallForwardInfo
com.android.ims.ImsCallProfile
-com.android.ims.ImsCallProfile$1
-com.android.ims.ImsConferenceState
com.android.ims.ImsConfig
com.android.ims.ImsConfigListener
com.android.ims.ImsConfigListener$Stub
@@ -5141,37 +5334,77 @@
com.android.ims.ImsManager$2
com.android.ims.ImsManager$ImsRegistrationListenerProxy
com.android.ims.ImsManager$ImsServiceDeathRecipient
+com.android.ims.ImsMultiEndpoint
+com.android.ims.ImsMultiEndpoint$ImsExternalCallStateListenerProxy
com.android.ims.ImsReasonInfo
com.android.ims.ImsReasonInfo$1
com.android.ims.ImsSsInfo
-com.android.ims.ImsStreamMediaProfile
-com.android.ims.ImsStreamMediaProfile$1
-com.android.ims.ImsSuppServiceNotification
-com.android.ims.internal.ICall
com.android.ims.internal.IImsCallSession
-com.android.ims.internal.IImsCallSession$Stub
com.android.ims.internal.IImsCallSessionListener
-com.android.ims.internal.IImsCallSessionListener$Stub
com.android.ims.internal.IImsConfig
com.android.ims.internal.IImsConfig$Stub
+com.android.ims.internal.IImsConfig$Stub$Proxy
com.android.ims.internal.IImsEcbm
com.android.ims.internal.IImsEcbm$Stub
com.android.ims.internal.IImsEcbmListener
com.android.ims.internal.IImsEcbmListener$Stub
+com.android.ims.internal.IImsExternalCallStateListener
+com.android.ims.internal.IImsExternalCallStateListener$Stub
com.android.ims.internal.IImsMultiEndpoint
+com.android.ims.internal.IImsMultiEndpoint$Stub
com.android.ims.internal.IImsRegistrationListener
com.android.ims.internal.IImsRegistrationListener$Stub
+com.android.ims.internal.IImsRegistrationListener$Stub$Proxy
com.android.ims.internal.IImsService
com.android.ims.internal.IImsService$Stub
+com.android.ims.internal.IImsService$Stub$Proxy
+com.android.ims.internal.IImsServiceController
+com.android.ims.internal.IImsServiceFeatureListener
com.android.ims.internal.IImsUt
com.android.ims.internal.IImsUt$Stub
com.android.ims.internal.IImsUtListener
com.android.ims.internal.IImsUtListener$Stub
-com.android.ims.internal.IImsVideoCallProvider
-com.android.ims.internal.ImsCallSession
-com.android.ims.internal.ImsCallSession$IImsCallSessionListenerProxy
-com.android.ims.internal.ImsCallSession$Listener
-com.android.ims.internal.ImsCallSession$State
+com.android.ims.internal.uce.common.CapInfo
+com.android.ims.internal.uce.common.CapInfo$1
+com.android.ims.internal.uce.common.StatusCode
+com.android.ims.internal.uce.common.StatusCode$1
+com.android.ims.internal.uce.common.UceLong
+com.android.ims.internal.uce.common.UceLong$1
+com.android.ims.internal.uce.options.IOptionsListener
+com.android.ims.internal.uce.options.IOptionsService
+com.android.ims.internal.uce.presence.IPresenceListener
+com.android.ims.internal.uce.presence.IPresenceListener$Stub
+com.android.ims.internal.uce.presence.IPresenceListener$Stub$Proxy
+com.android.ims.internal.uce.presence.IPresenceService
+com.android.ims.internal.uce.presence.IPresenceService$Stub
+com.android.ims.internal.uce.presence.IPresenceService$Stub$Proxy
+com.android.ims.internal.uce.presence.PresCapInfo
+com.android.ims.internal.uce.presence.PresCmdId
+com.android.ims.internal.uce.presence.PresCmdId$1
+com.android.ims.internal.uce.presence.PresCmdStatus
+com.android.ims.internal.uce.presence.PresCmdStatus$1
+com.android.ims.internal.uce.presence.PresPublishTriggerType
+com.android.ims.internal.uce.presence.PresPublishTriggerType$1
+com.android.ims.internal.uce.presence.PresResInfo
+com.android.ims.internal.uce.presence.PresResInfo$1
+com.android.ims.internal.uce.presence.PresResInstanceInfo
+com.android.ims.internal.uce.presence.PresResInstanceInfo$1
+com.android.ims.internal.uce.presence.PresRlmiInfo
+com.android.ims.internal.uce.presence.PresRlmiInfo$1
+com.android.ims.internal.uce.presence.PresServiceInfo
+com.android.ims.internal.uce.presence.PresSipResponse
+com.android.ims.internal.uce.presence.PresSipResponse$1
+com.android.ims.internal.uce.presence.PresSubscriptionState
+com.android.ims.internal.uce.presence.PresSubscriptionState$1
+com.android.ims.internal.uce.presence.PresTupleInfo
+com.android.ims.internal.uce.presence.PresTupleInfo$1
+com.android.ims.internal.uce.uceservice.IUceListener
+com.android.ims.internal.uce.uceservice.IUceListener$Stub
+com.android.ims.internal.uce.uceservice.IUceService
+com.android.ims.internal.uce.uceservice.IUceService$Stub
+com.android.ims.internal.uce.uceservice.IUceService$Stub$Proxy
+com.android.ims.internal.uce.uceservice.ImsUceManager
+com.android.ims.internal.uce.uceservice.ImsUceManager$UceServiceDeathRecipient
com.android.internal.R$styleable
com.android.internal.alsa.AlsaCardsParser
com.android.internal.alsa.AlsaCardsParser$AlsaCardRecord
@@ -5186,17 +5419,6 @@
com.android.internal.app.AlertController$CheckedItemAdapter
com.android.internal.app.AlertController$RecycleListView
com.android.internal.app.AssistUtils
-com.android.internal.app.ChooserActivity
-com.android.internal.app.ChooserActivity$1
-com.android.internal.app.ChooserActivity$BaseChooserTargetComparator
-com.android.internal.app.ChooserActivity$ChooserListAdapter
-com.android.internal.app.ChooserActivity$ChooserRowAdapter
-com.android.internal.app.ChooserActivity$ChooserRowAdapter$1
-com.android.internal.app.ChooserActivity$ChooserRowAdapter$2
-com.android.internal.app.ChooserActivity$ChooserRowAdapter$3
-com.android.internal.app.ChooserActivity$OffsetDataSetObserver
-com.android.internal.app.ChooserActivity$RowScale
-com.android.internal.app.ChooserActivity$RowViewHolder
com.android.internal.app.IAppOpsCallback
com.android.internal.app.IAppOpsCallback$Stub
com.android.internal.app.IAppOpsCallback$Stub$Proxy
@@ -5204,6 +5426,7 @@
com.android.internal.app.IAppOpsService$Stub
com.android.internal.app.IAppOpsService$Stub$Proxy
com.android.internal.app.IAssistScreenshotReceiver
+com.android.internal.app.IAssistScreenshotReceiver$Stub
com.android.internal.app.IBatteryStats
com.android.internal.app.IBatteryStats$Stub
com.android.internal.app.IBatteryStats$Stub$Proxy
@@ -5215,41 +5438,34 @@
com.android.internal.app.IVoiceInteractionManagerService
com.android.internal.app.IVoiceInteractionManagerService$Stub
com.android.internal.app.IVoiceInteractionManagerService$Stub$Proxy
+com.android.internal.app.IVoiceInteractionSessionListener
+com.android.internal.app.IVoiceInteractionSessionListener$Stub
+com.android.internal.app.IVoiceInteractionSessionListener$Stub$Proxy
com.android.internal.app.IVoiceInteractionSessionShowCallback
com.android.internal.app.IVoiceInteractionSessionShowCallback$Stub
+com.android.internal.app.IVoiceInteractionSessionShowCallback$Stub$Proxy
com.android.internal.app.IVoiceInteractor
com.android.internal.app.IVoiceInteractor$Stub
-com.android.internal.app.IntentForwarderActivity
+com.android.internal.app.IVoiceInteractor$Stub$Proxy
com.android.internal.app.LocaleHelper
com.android.internal.app.LocalePicker
com.android.internal.app.LocalePickerWithRegion$LocaleSelectedListener
-com.android.internal.app.PlatLogoActivity
+com.android.internal.app.NightDisplayController
+com.android.internal.app.NightDisplayController$1
+com.android.internal.app.NightDisplayController$Callback
+com.android.internal.app.NightDisplayController$LocalTime
com.android.internal.app.ProcessMap
com.android.internal.app.ResolverActivity
-com.android.internal.app.ResolverActivity$1
-com.android.internal.app.ResolverActivity$2
-com.android.internal.app.ResolverActivity$3
-com.android.internal.app.ResolverActivity$DisplayResolveInfo
-com.android.internal.app.ResolverActivity$LoadAdapterIconTask
-com.android.internal.app.ResolverActivity$LoadIconTask
-com.android.internal.app.ResolverActivity$ResolveListAdapter
-com.android.internal.app.ResolverActivity$ResolvedComponentInfo
-com.android.internal.app.ResolverActivity$TargetInfo
-com.android.internal.app.ResolverActivity$ViewHolder
-com.android.internal.app.ResolverComparator
-com.android.internal.app.ResolverComparator$ScoredTarget
com.android.internal.app.ToolbarActionBar
com.android.internal.app.ToolbarActionBar$1
com.android.internal.app.ToolbarActionBar$2
com.android.internal.app.ToolbarActionBar$ActionMenuPresenterCallback
com.android.internal.app.ToolbarActionBar$MenuBuilderCallback
com.android.internal.app.ToolbarActionBar$ToolbarCallbackWrapper
-com.android.internal.app.UnlaunchableAppActivity
com.android.internal.app.WindowDecorActionBar
com.android.internal.app.WindowDecorActionBar$1
com.android.internal.app.WindowDecorActionBar$2
com.android.internal.app.WindowDecorActionBar$3
-com.android.internal.app.WindowDecorActionBar$ActionModeImpl
com.android.internal.app.procstats.DumpUtils
com.android.internal.app.procstats.DurationsTable
com.android.internal.app.procstats.IProcessStats
@@ -5281,11 +5497,16 @@
com.android.internal.backup.LocalTransport
com.android.internal.backup.LocalTransportService
com.android.internal.content.NativeLibraryHelper
-com.android.internal.content.NativeLibraryHelper$Handle
com.android.internal.content.PackageHelper
com.android.internal.content.PackageMonitor
com.android.internal.content.ReferrerIntent
com.android.internal.content.ReferrerIntent$1
+com.android.internal.font.IFontManager
+com.android.internal.font.IFontManager$Stub
+com.android.internal.graphics.drawable.AnimationScaleListDrawable
+com.android.internal.graphics.drawable.AnimationScaleListDrawable$AnimationScaleListState
+com.android.internal.hardware.AmbientDisplayConfiguration
+com.android.internal.inputmethod.IInputContentUriToken
com.android.internal.inputmethod.InputMethodSubtypeHandle
com.android.internal.inputmethod.InputMethodSubtypeSwitchingController
com.android.internal.inputmethod.InputMethodSubtypeSwitchingController$ControllerImpl
@@ -5296,6 +5517,7 @@
com.android.internal.inputmethod.InputMethodSubtypeSwitchingController$StaticRotationList
com.android.internal.inputmethod.InputMethodUtils
com.android.internal.inputmethod.InputMethodUtils$1
+com.android.internal.inputmethod.InputMethodUtils$InputMethodListBuilder
com.android.internal.inputmethod.InputMethodUtils$InputMethodSettings
com.android.internal.inputmethod.LocaleUtils
com.android.internal.inputmethod.LocaleUtils$LocaleExtractor
@@ -5321,6 +5543,7 @@
com.android.internal.net.VpnInfo
com.android.internal.net.VpnProfile
com.android.internal.os.AndroidPrintStream
+com.android.internal.os.AppFuseMount
com.android.internal.os.AtomicFile
com.android.internal.os.BackgroundThread
com.android.internal.os.BatterySipper
@@ -5334,6 +5557,8 @@
com.android.internal.os.BatteryStatsImpl$BatteryCallback
com.android.internal.os.BatteryStatsImpl$Clocks
com.android.internal.os.BatteryStatsImpl$ControllerActivityCounterImpl
+com.android.internal.os.BatteryStatsImpl$Counter
+com.android.internal.os.BatteryStatsImpl$DurationTimer
com.android.internal.os.BatteryStatsImpl$ExternalStatsSync
com.android.internal.os.BatteryStatsImpl$LongSamplingCounter
com.android.internal.os.BatteryStatsImpl$MyHandler
@@ -5351,6 +5576,7 @@
com.android.internal.os.BatteryStatsImpl$Uid$3
com.android.internal.os.BatteryStatsImpl$Uid$Pkg
com.android.internal.os.BatteryStatsImpl$Uid$Pkg$Serv
+com.android.internal.os.BatteryStatsImpl$Uid$Proc
com.android.internal.os.BatteryStatsImpl$Uid$Sensor
com.android.internal.os.BatteryStatsImpl$Uid$Wakelock
com.android.internal.os.BinderInternal
@@ -5359,6 +5585,9 @@
com.android.internal.os.CameraPowerCalculator
com.android.internal.os.CpuPowerCalculator
com.android.internal.os.FlashlightPowerCalculator
+com.android.internal.os.FuseAppLoop
+com.android.internal.os.FuseAppLoop$1
+com.android.internal.os.FuseAppLoop$UnmountedException
com.android.internal.os.HandlerCaller
com.android.internal.os.HandlerCaller$Callback
com.android.internal.os.HandlerCaller$MyHandler
@@ -5369,15 +5598,18 @@
com.android.internal.os.IResultReceiver
com.android.internal.os.IResultReceiver$Stub
com.android.internal.os.IResultReceiver$Stub$Proxy
-com.android.internal.os.InstallerConnection
-com.android.internal.os.InstallerConnection$InstallerException
+com.android.internal.os.IShellCallback
+com.android.internal.os.IShellCallback$Stub
+com.android.internal.os.IShellCallback$Stub$Proxy
com.android.internal.os.KernelCpuSpeedReader
+com.android.internal.os.KernelMemoryBandwidthStats
com.android.internal.os.KernelUidCpuTimeReader
com.android.internal.os.KernelWakelockReader
com.android.internal.os.KernelWakelockStats
com.android.internal.os.KernelWakelockStats$Entry
com.android.internal.os.LoggingPrintStream
com.android.internal.os.LoggingPrintStream$1
+com.android.internal.os.MemoryPowerCalculator
com.android.internal.os.MobileRadioPowerCalculator
com.android.internal.os.PathClassLoaderFactory
com.android.internal.os.PowerCalculator
@@ -5385,31 +5617,35 @@
com.android.internal.os.PowerProfile$CpuClusterKey
com.android.internal.os.ProcessCpuTracker
com.android.internal.os.ProcessCpuTracker$1
+com.android.internal.os.ProcessCpuTracker$FilterStats
com.android.internal.os.ProcessCpuTracker$Stats
+com.android.internal.os.RoSystemProperties
com.android.internal.os.RuntimeInit
com.android.internal.os.RuntimeInit$1
com.android.internal.os.RuntimeInit$Arguments
-com.android.internal.os.RuntimeInit$UncaughtHandler
+com.android.internal.os.RuntimeInit$KillApplicationHandler
+com.android.internal.os.RuntimeInit$LoggingHandler
com.android.internal.os.SamplingProfilerIntegration
com.android.internal.os.SensorPowerCalculator
com.android.internal.os.SomeArgs
+com.android.internal.os.TransferPipe
com.android.internal.os.WakelockPowerCalculator
-com.android.internal.os.WifiPowerEstimator
+com.android.internal.os.WifiPowerCalculator
com.android.internal.os.Zygote
+com.android.internal.os.Zygote$MethodAndArgsCaller
com.android.internal.os.ZygoteConnection
com.android.internal.os.ZygoteConnection$Arguments
com.android.internal.os.ZygoteInit
-com.android.internal.os.ZygoteInit$MethodAndArgsCaller
com.android.internal.os.ZygoteSecurityException
+com.android.internal.os.ZygoteServer
com.android.internal.policy.DecorContext
com.android.internal.policy.DecorView
com.android.internal.policy.DecorView$1
-com.android.internal.policy.DecorView$4
-com.android.internal.policy.DecorView$ActionModeCallback2Wrapper
com.android.internal.policy.DecorView$ColorViewState
com.android.internal.policy.DividerSnapAlgorithm
com.android.internal.policy.DividerSnapAlgorithm$SnapTarget
com.android.internal.policy.DockedDividerUtils
+com.android.internal.policy.IKeyguardDismissCallback
com.android.internal.policy.IKeyguardDrawnCallback
com.android.internal.policy.IKeyguardDrawnCallback$Stub
com.android.internal.policy.IKeyguardDrawnCallback$Stub$Proxy
@@ -5434,6 +5670,8 @@
com.android.internal.policy.PhoneWindow$PhoneWindowMenuCallback
com.android.internal.policy.PhoneWindow$RotationWatcher
com.android.internal.policy.PhoneWindow$RotationWatcher$1
+com.android.internal.policy.PipMotionHelper
+com.android.internal.policy.PipSnapAlgorithm
com.android.internal.statusbar.IStatusBar
com.android.internal.statusbar.IStatusBar$Stub
com.android.internal.statusbar.IStatusBar$Stub$Proxy
@@ -5464,10 +5702,8 @@
com.android.internal.telecom.RemoteServiceCallback
com.android.internal.telecom.RemoteServiceCallback$Stub
com.android.internal.telecom.RemoteServiceCallback$Stub$Proxy
-com.android.internal.telephony.ATParseEx
-com.android.internal.telephony.AsyncEmergencyContactNotifier
+com.android.internal.telephony.AppSmsManager
com.android.internal.telephony.BaseCommands
-com.android.internal.telephony.BlockChecker
com.android.internal.telephony.Call
com.android.internal.telephony.Call$SrvccState
com.android.internal.telephony.Call$State
@@ -5481,28 +5717,30 @@
com.android.internal.telephony.CallerInfoAsyncQuery$CallerInfoAsyncQueryHandler$CallerInfoWorkerHandler
com.android.internal.telephony.CallerInfoAsyncQuery$CookieWrapper
com.android.internal.telephony.CallerInfoAsyncQuery$OnQueryCompleteListener
+com.android.internal.telephony.CarrierActionAgent
com.android.internal.telephony.CarrierAppUtils
com.android.internal.telephony.CarrierServiceBindHelper
com.android.internal.telephony.CarrierServiceBindHelper$1
com.android.internal.telephony.CarrierServiceBindHelper$2
com.android.internal.telephony.CarrierServiceBindHelper$AppBinding
com.android.internal.telephony.CarrierServiceBindHelper$CarrierServicePackageMonitor
+com.android.internal.telephony.CarrierServiceStateTracker
+com.android.internal.telephony.CarrierServiceStateTracker$1
+com.android.internal.telephony.CarrierSignalAgent
+com.android.internal.telephony.CarrierSignalAgent$1
com.android.internal.telephony.CellBroadcastHandler
com.android.internal.telephony.CellNetworkScanResult
+com.android.internal.telephony.ClientWakelockAccountant
+com.android.internal.telephony.ClientWakelockTracker
com.android.internal.telephony.CommandException
com.android.internal.telephony.CommandException$Error
com.android.internal.telephony.CommandsInterface
com.android.internal.telephony.CommandsInterface$RadioState
com.android.internal.telephony.Connection
-com.android.internal.telephony.Connection$Listener
-com.android.internal.telephony.Connection$ListenerBase
-com.android.internal.telephony.Connection$PostDialListener
-com.android.internal.telephony.Connection$PostDialState
com.android.internal.telephony.DctConstants$Activity
com.android.internal.telephony.DctConstants$State
com.android.internal.telephony.DebugService
com.android.internal.telephony.DefaultPhoneNotifier
-com.android.internal.telephony.DriverCall
com.android.internal.telephony.EncodeException
com.android.internal.telephony.GsmAlphabet
com.android.internal.telephony.GsmAlphabet$TextEncodingDetails
@@ -5514,6 +5752,7 @@
com.android.internal.telephony.GsmCdmaPhone$1
com.android.internal.telephony.GsmCdmaPhone$2
com.android.internal.telephony.HardwareConfig
+com.android.internal.telephony.HbpcdUtils
com.android.internal.telephony.ICarrierConfigLoader
com.android.internal.telephony.ICarrierConfigLoader$Stub
com.android.internal.telephony.ICarrierConfigLoader$Stub$Proxy
@@ -5521,7 +5760,6 @@
com.android.internal.telephony.IIccPhoneBook$Stub
com.android.internal.telephony.IMms
com.android.internal.telephony.IMms$Stub
-com.android.internal.telephony.IMms$Stub$Proxy
com.android.internal.telephony.IOnSubscriptionsChangedListener
com.android.internal.telephony.IOnSubscriptionsChangedListener$Stub
com.android.internal.telephony.IOnSubscriptionsChangedListener$Stub$Proxy
@@ -5555,20 +5793,16 @@
com.android.internal.telephony.IccSmsInterfaceManager$CellBroadcastRangeManager
com.android.internal.telephony.ImsSMSDispatcher
com.android.internal.telephony.InboundSmsHandler
+com.android.internal.telephony.InboundSmsHandler$1
com.android.internal.telephony.InboundSmsHandler$DefaultState
com.android.internal.telephony.InboundSmsHandler$DeliveringState
com.android.internal.telephony.InboundSmsHandler$IdleState
-com.android.internal.telephony.InboundSmsHandler$SmsBroadcastReceiver
+com.android.internal.telephony.InboundSmsHandler$NewMessageNotificationActionReceiver
com.android.internal.telephony.InboundSmsHandler$StartupState
com.android.internal.telephony.InboundSmsHandler$WaitingState
-com.android.internal.telephony.InboundSmsTracker
com.android.internal.telephony.IntRangeManager
-com.android.internal.telephony.IntRangeManager$ClientRange
-com.android.internal.telephony.IntRangeManager$IntRange
com.android.internal.telephony.MccTable
com.android.internal.telephony.MccTable$MccEntry
-com.android.internal.telephony.MmiCode
-com.android.internal.telephony.MmiCode$State
com.android.internal.telephony.OperatorInfo
com.android.internal.telephony.Phone
com.android.internal.telephony.Phone$1
@@ -5577,7 +5811,6 @@
com.android.internal.telephony.PhoneFactory
com.android.internal.telephony.PhoneInternalInterface
com.android.internal.telephony.PhoneInternalInterface$DataActivityState
-com.android.internal.telephony.PhoneInternalInterface$SuppService
com.android.internal.telephony.PhoneNotifier
com.android.internal.telephony.PhoneStateIntentReceiver
com.android.internal.telephony.PhoneSubInfoController
@@ -5593,43 +5826,39 @@
com.android.internal.telephony.RIL$2
com.android.internal.telephony.RIL$RILReceiver
com.android.internal.telephony.RIL$RILSender
+com.android.internal.telephony.RIL$RadioProxyDeathRecipient
+com.android.internal.telephony.RIL$RilHandler
com.android.internal.telephony.RILConstants
com.android.internal.telephony.RILRequest
com.android.internal.telephony.RadioCapability
+com.android.internal.telephony.RadioIndication
+com.android.internal.telephony.RadioResponse
+com.android.internal.telephony.RatRatcheter
+com.android.internal.telephony.RatRatcheter$1
com.android.internal.telephony.RestrictedState
com.android.internal.telephony.RetryManager
-com.android.internal.telephony.RetryManager$RetryRec
+com.android.internal.telephony.RilWakelockInfo
com.android.internal.telephony.SMSDispatcher
com.android.internal.telephony.SMSDispatcher$SettingsObserver
-com.android.internal.telephony.SMSDispatcher$SmsTracker
com.android.internal.telephony.ServiceStateTracker
com.android.internal.telephony.ServiceStateTracker$1
com.android.internal.telephony.ServiceStateTracker$2
com.android.internal.telephony.ServiceStateTracker$3
com.android.internal.telephony.ServiceStateTracker$CellInfoResult
com.android.internal.telephony.ServiceStateTracker$SstSubscriptionsChangedListener
-com.android.internal.telephony.SmsAddress
com.android.internal.telephony.SmsApplication
com.android.internal.telephony.SmsApplication$SmsApplicationData
com.android.internal.telephony.SmsApplication$SmsPackageMonitor
com.android.internal.telephony.SmsBroadcastUndelivered
com.android.internal.telephony.SmsBroadcastUndelivered$1
com.android.internal.telephony.SmsBroadcastUndelivered$ScanRawTableThread
-com.android.internal.telephony.SmsConstants$MessageClass
-com.android.internal.telephony.SmsHeader
-com.android.internal.telephony.SmsHeader$PortAddrs
com.android.internal.telephony.SmsMessageBase
-com.android.internal.telephony.SmsMessageBase$SubmitPduBase
-com.android.internal.telephony.SmsNumberUtils
-com.android.internal.telephony.SmsResponse
com.android.internal.telephony.SmsStorageMonitor
com.android.internal.telephony.SmsStorageMonitor$1
com.android.internal.telephony.SmsUsageMonitor
com.android.internal.telephony.SmsUsageMonitor$SettingsObserver
com.android.internal.telephony.SmsUsageMonitor$SettingsObserverHandler
-com.android.internal.telephony.SmsUsageMonitor$ShortCodePatternMatcher
com.android.internal.telephony.SubscriptionController
-com.android.internal.telephony.SubscriptionController$1
com.android.internal.telephony.SubscriptionController$ScLocalLog
com.android.internal.telephony.SubscriptionInfoUpdater
com.android.internal.telephony.SubscriptionInfoUpdater$1
@@ -5640,10 +5869,8 @@
com.android.internal.telephony.TelephonyCapabilities
com.android.internal.telephony.TelephonyComponentFactory
com.android.internal.telephony.TelephonyDevController
-com.android.internal.telephony.TelephonyEventLog
com.android.internal.telephony.TelephonyTester
com.android.internal.telephony.TelephonyTester$1
-com.android.internal.telephony.UUSInfo
com.android.internal.telephony.UiccPhoneBookController
com.android.internal.telephony.UiccSmsController
com.android.internal.telephony.WakeLockStateMachine
@@ -5652,45 +5879,36 @@
com.android.internal.telephony.WakeLockStateMachine$IdleState
com.android.internal.telephony.WakeLockStateMachine$WaitingState
com.android.internal.telephony.WapPushOverSms
+com.android.internal.telephony.WapPushOverSms$1
+com.android.internal.telephony.WapPushOverSms$BindServiceThread
com.android.internal.telephony.cat.AppInterface
-com.android.internal.telephony.cat.CatException
+com.android.internal.telephony.cat.AppInterface$CommandType
+com.android.internal.telephony.cat.CatCmdMessage
+com.android.internal.telephony.cat.CatCmdMessage$BrowserSettings
+com.android.internal.telephony.cat.CatCmdMessage$CallSettings
+com.android.internal.telephony.cat.CatCmdMessage$SetupEventListSettings
com.android.internal.telephony.cat.CatLog
+com.android.internal.telephony.cat.CatResponseMessage
com.android.internal.telephony.cat.CatService
-com.android.internal.telephony.cat.CommandParamsFactory
-com.android.internal.telephony.cat.IconLoader
-com.android.internal.telephony.cat.ResultException
-com.android.internal.telephony.cat.RilMessageDecoder
-com.android.internal.telephony.cat.RilMessageDecoder$StateCmdParamsReady
-com.android.internal.telephony.cat.RilMessageDecoder$StateStart
-com.android.internal.telephony.cdma.CdmaCallWaitingNotification
+com.android.internal.telephony.cat.Input
+com.android.internal.telephony.cat.Item
+com.android.internal.telephony.cat.LaunchBrowserMode
+com.android.internal.telephony.cat.Menu
+com.android.internal.telephony.cat.ResultCode
+com.android.internal.telephony.cat.TextMessage
+com.android.internal.telephony.cat.ToneSettings
com.android.internal.telephony.cdma.CdmaInboundSmsHandler
-com.android.internal.telephony.cdma.CdmaInformationRecords$CdmaDisplayInfoRec
-com.android.internal.telephony.cdma.CdmaInformationRecords$CdmaSignalInfoRec
com.android.internal.telephony.cdma.CdmaSMSDispatcher
com.android.internal.telephony.cdma.CdmaServiceCategoryProgramHandler
com.android.internal.telephony.cdma.CdmaServiceCategoryProgramHandler$1
-com.android.internal.telephony.cdma.CdmaSmsBroadcastConfigInfo
com.android.internal.telephony.cdma.CdmaSubscriptionSourceManager
com.android.internal.telephony.cdma.EriInfo
com.android.internal.telephony.cdma.EriManager
+com.android.internal.telephony.cdma.EriManager$EriDisplayInformation
com.android.internal.telephony.cdma.EriManager$EriFile
-com.android.internal.telephony.cdma.SignalToneUtil
com.android.internal.telephony.dataconnection.ApnContext
-com.android.internal.telephony.dataconnection.ApnSetting
-com.android.internal.telephony.dataconnection.DataCallResponse
-com.android.internal.telephony.dataconnection.DataCallResponse$SetupResult
com.android.internal.telephony.dataconnection.DataConnection
-com.android.internal.telephony.dataconnection.DataConnection$ConnectionParams
-com.android.internal.telephony.dataconnection.DataConnection$DcActivatingState
-com.android.internal.telephony.dataconnection.DataConnection$DcActiveState
-com.android.internal.telephony.dataconnection.DataConnection$DcDefaultState
-com.android.internal.telephony.dataconnection.DataConnection$DcDisconnectingState
-com.android.internal.telephony.dataconnection.DataConnection$DcDisconnectionErrorCreatingConnection
-com.android.internal.telephony.dataconnection.DataConnection$DcInactiveState
-com.android.internal.telephony.dataconnection.DataConnection$DcNetworkAgent
-com.android.internal.telephony.dataconnection.DataConnection$DisconnectParams
-com.android.internal.telephony.dataconnection.DataConnection$UpdateLinkPropertyResult
-com.android.internal.telephony.dataconnection.DcAsyncChannel
+com.android.internal.telephony.dataconnection.DataEnabledSettings
com.android.internal.telephony.dataconnection.DcController
com.android.internal.telephony.dataconnection.DcController$1
com.android.internal.telephony.dataconnection.DcController$DccDefaultState
@@ -5717,19 +5935,24 @@
com.android.internal.telephony.gsm.GsmCellBroadcastHandler
com.android.internal.telephony.gsm.GsmInboundSmsHandler
com.android.internal.telephony.gsm.GsmSMSDispatcher
-com.android.internal.telephony.gsm.GsmSmsAddress
-com.android.internal.telephony.gsm.SimTlv
-com.android.internal.telephony.gsm.SmsBroadcastConfigInfo
com.android.internal.telephony.gsm.SmsMessage
-com.android.internal.telephony.gsm.SmsMessage$PduParser
-com.android.internal.telephony.gsm.SmsMessage$SubmitPdu
-com.android.internal.telephony.gsm.SuppServiceNotification
com.android.internal.telephony.gsm.UsimDataDownloadHandler
-com.android.internal.telephony.gsm.UsimPhoneBookManager
+com.android.internal.telephony.ims.-$Lambda$2$6hDwuvYxqWrzW_Ex5wc53XnUOpg
+com.android.internal.telephony.ims.-$Lambda$3$6hDwuvYxqWrzW_Ex5wc53XnUOpg
+com.android.internal.telephony.ims.-$Lambda$4$6hDwuvYxqWrzW_Ex5wc53XnUOpg
+com.android.internal.telephony.ims.ImsResolver
+com.android.internal.telephony.ims.ImsResolver$1
+com.android.internal.telephony.ims.ImsResolver$2
+com.android.internal.telephony.ims.ImsResolver$3
+com.android.internal.telephony.ims.ImsResolver$ImsServiceControllerFactory
+com.android.internal.telephony.ims.ImsResolver$SubscriptionManagerProxy
+com.android.internal.telephony.ims.ImsServiceController$ImsServiceControllerCallbacks
com.android.internal.telephony.imsphone.ImsExternalCallTracker
+com.android.internal.telephony.imsphone.ImsExternalCallTracker$1
+com.android.internal.telephony.imsphone.ImsExternalCallTracker$2
com.android.internal.telephony.imsphone.ImsExternalCallTracker$ExternalCallStateListener
com.android.internal.telephony.imsphone.ImsExternalCallTracker$ExternalConnectionListener
-com.android.internal.telephony.imsphone.ImsExternalConnection
+com.android.internal.telephony.imsphone.ImsExternalCallTracker$ImsCallNotify
com.android.internal.telephony.imsphone.ImsExternalConnection$Listener
com.android.internal.telephony.imsphone.ImsPhone
com.android.internal.telephony.imsphone.ImsPhone$1
@@ -5743,64 +5966,43 @@
com.android.internal.telephony.imsphone.ImsPhoneCallTracker$3
com.android.internal.telephony.imsphone.ImsPhoneCallTracker$4
com.android.internal.telephony.imsphone.ImsPhoneCallTracker$5
-com.android.internal.telephony.imsphone.ImsPhoneCallTracker$6
+com.android.internal.telephony.imsphone.ImsPhoneCallTracker$PhoneStateListener
com.android.internal.telephony.imsphone.ImsPhoneCommandInterface
-com.android.internal.telephony.imsphone.ImsPhoneConnection
-com.android.internal.telephony.imsphone.ImsPhoneConnection$MyHandler
com.android.internal.telephony.imsphone.ImsPhoneFactory
-com.android.internal.telephony.imsphone.ImsPhoneMmiCode
com.android.internal.telephony.imsphone.ImsPullCall
-com.android.internal.telephony.sip.SipPhone
-com.android.internal.telephony.sip.SipPhoneBase
+com.android.internal.telephony.metrics.CallSessionEventBuilder
+com.android.internal.telephony.metrics.InProgressCallSession
+com.android.internal.telephony.metrics.InProgressSmsSession
+com.android.internal.telephony.metrics.SmsSessionEventBuilder
+com.android.internal.telephony.metrics.TelephonyEventBuilder
+com.android.internal.telephony.metrics.TelephonyMetrics
+com.android.internal.telephony.nano.TelephonyProto$ImsCapabilities
+com.android.internal.telephony.nano.TelephonyProto$ImsConnectionState
+com.android.internal.telephony.nano.TelephonyProto$ImsReasonInfo
+com.android.internal.telephony.nano.TelephonyProto$RilDataCall
+com.android.internal.telephony.nano.TelephonyProto$SmsSession$Event
+com.android.internal.telephony.nano.TelephonyProto$TelephonyCallSession$Event
+com.android.internal.telephony.nano.TelephonyProto$TelephonyCallSession$Event$RilCall
+com.android.internal.telephony.nano.TelephonyProto$TelephonyEvent
+com.android.internal.telephony.nano.TelephonyProto$TelephonyServiceState
+com.android.internal.telephony.nano.TelephonyProto$TelephonyServiceState$TelephonyOperator
+com.android.internal.telephony.nano.TelephonyProto$TelephonySettings
com.android.internal.telephony.test.SimulatedRadioControl
-com.android.internal.telephony.uicc.AdnRecord
-com.android.internal.telephony.uicc.AdnRecord$1
-com.android.internal.telephony.uicc.AdnRecordCache
-com.android.internal.telephony.uicc.AdnRecordLoader
com.android.internal.telephony.uicc.IccCardApplicationStatus
-com.android.internal.telephony.uicc.IccCardApplicationStatus$AppState
com.android.internal.telephony.uicc.IccCardApplicationStatus$AppType
-com.android.internal.telephony.uicc.IccCardApplicationStatus$PersoSubState
com.android.internal.telephony.uicc.IccCardProxy
com.android.internal.telephony.uicc.IccCardStatus
com.android.internal.telephony.uicc.IccCardStatus$CardState
com.android.internal.telephony.uicc.IccCardStatus$PinState
com.android.internal.telephony.uicc.IccConstants
-com.android.internal.telephony.uicc.IccFileHandler
-com.android.internal.telephony.uicc.IccFileHandler$LoadLinearFixedContext
-com.android.internal.telephony.uicc.IccIoResult
com.android.internal.telephony.uicc.IccRecords
-com.android.internal.telephony.uicc.IccRecords$IccRecordLoaded
-com.android.internal.telephony.uicc.IccServiceTable
+com.android.internal.telephony.uicc.IccRefreshResponse
com.android.internal.telephony.uicc.IccUtils
-com.android.internal.telephony.uicc.IsimFileHandler
-com.android.internal.telephony.uicc.IsimRecords
-com.android.internal.telephony.uicc.IsimUiccRecords
-com.android.internal.telephony.uicc.IsimUiccRecords$EfIsimDomainLoaded
-com.android.internal.telephony.uicc.IsimUiccRecords$EfIsimImpiLoaded
-com.android.internal.telephony.uicc.IsimUiccRecords$EfIsimImpuLoaded
-com.android.internal.telephony.uicc.IsimUiccRecords$EfIsimIstLoaded
-com.android.internal.telephony.uicc.IsimUiccRecords$EfIsimPcscfLoaded
-com.android.internal.telephony.uicc.SIMRecords
-com.android.internal.telephony.uicc.SIMRecords$1
-com.android.internal.telephony.uicc.SIMRecords$EfPlLoaded
-com.android.internal.telephony.uicc.SIMRecords$EfUsimLiLoaded
-com.android.internal.telephony.uicc.SIMRecords$GetSpnFsmState
-com.android.internal.telephony.uicc.SpnOverride
com.android.internal.telephony.uicc.UiccCard
com.android.internal.telephony.uicc.UiccCard$1
com.android.internal.telephony.uicc.UiccCardApplication
-com.android.internal.telephony.uicc.UiccCardApplication$1
-com.android.internal.telephony.uicc.UiccCarrierPrivilegeRules
-com.android.internal.telephony.uicc.UiccCarrierPrivilegeRules$1
com.android.internal.telephony.uicc.UiccController
-com.android.internal.telephony.uicc.UiccPkcs15
-com.android.internal.telephony.uicc.UiccPkcs15$FileHandler
-com.android.internal.telephony.uicc.UiccPkcs15$Pkcs15Selector
-com.android.internal.telephony.uicc.UsimFileHandler
-com.android.internal.telephony.uicc.UsimServiceTable
-com.android.internal.telephony.uicc.UsimServiceTable$UsimService
-com.android.internal.telephony.uicc.VoiceMailConstants
+com.android.internal.telephony.uicc.UiccStateChangedLauncher
com.android.internal.textservice.ISpellCheckerService
com.android.internal.textservice.ISpellCheckerService$Stub
com.android.internal.textservice.ISpellCheckerService$Stub$Proxy
@@ -5828,6 +6030,9 @@
com.android.internal.util.AsyncChannel$DeathMonitor
com.android.internal.util.AsyncChannel$SyncMessenger
com.android.internal.util.AsyncChannel$SyncMessenger$SyncHandler
+com.android.internal.util.ConcurrentUtils
+com.android.internal.util.ConcurrentUtils$1
+com.android.internal.util.ConcurrentUtils$1$1
com.android.internal.util.DumpUtils$Dump
com.android.internal.util.FastMath
com.android.internal.util.FastPrintWriter
@@ -5850,7 +6055,6 @@
com.android.internal.util.MessageUtils
com.android.internal.util.NotificationColorUtil
com.android.internal.util.NotificationColorUtil$ColorUtilsFromCompat
-com.android.internal.util.ParcelableString
com.android.internal.util.Preconditions
com.android.internal.util.Predicate
com.android.internal.util.ProcFileReader
@@ -5865,7 +6069,8 @@
com.android.internal.util.StateMachine$SmHandler$HaltingState
com.android.internal.util.StateMachine$SmHandler$QuittingState
com.android.internal.util.StateMachine$SmHandler$StateInfo
-com.android.internal.util.UserIcons
+com.android.internal.util.ToBooleanFunction
+com.android.internal.util.TokenBucket
com.android.internal.util.VirtualRefBasePtr
com.android.internal.util.WakeupMessage
com.android.internal.util.XmlUtils
@@ -5874,12 +6079,6 @@
com.android.internal.view.ActionBarPolicy
com.android.internal.view.BaseIWindow
com.android.internal.view.BaseSurfaceHolder
-com.android.internal.view.FloatingActionMode
-com.android.internal.view.FloatingActionMode$1
-com.android.internal.view.FloatingActionMode$2
-com.android.internal.view.FloatingActionMode$3
-com.android.internal.view.FloatingActionMode$4
-com.android.internal.view.FloatingActionMode$FloatingToolbarVisibilityHelper
com.android.internal.view.IInputConnectionWrapper
com.android.internal.view.IInputConnectionWrapper$MyHandler
com.android.internal.view.IInputConnectionWrapper$SomeArgs
@@ -5908,11 +6107,13 @@
com.android.internal.view.InputBindResult$1
com.android.internal.view.InputConnectionWrapper
com.android.internal.view.InputConnectionWrapper$InputContextCallback
+com.android.internal.view.OneShotPreDrawListener
com.android.internal.view.RootViewSurfaceTaker
com.android.internal.view.RotationPolicy
-com.android.internal.view.RotationPolicy$1
com.android.internal.view.RotationPolicy$RotationPolicyListener
com.android.internal.view.RotationPolicy$RotationPolicyListener$1
+com.android.internal.view.SurfaceCallbackHelper
+com.android.internal.view.SurfaceCallbackHelper$1
com.android.internal.view.WindowManagerPolicyThread
com.android.internal.view.animation.FallbackLUTInterpolator
com.android.internal.view.animation.HasNativeInterpolator
@@ -5922,7 +6123,6 @@
com.android.internal.view.menu.ActionMenuItemView
com.android.internal.view.menu.ActionMenuItemView$PopupCallback
com.android.internal.view.menu.BaseMenuPresenter
-com.android.internal.view.menu.ContextMenuBuilder
com.android.internal.view.menu.ListMenuItemView
com.android.internal.view.menu.MenuAdapter
com.android.internal.view.menu.MenuBuilder
@@ -5942,12 +6142,12 @@
com.android.internal.view.menu.StandardMenuPopup$1
com.android.internal.view.menu.StandardMenuPopup$2
com.android.internal.view.menu.SubMenuBuilder
+com.android.internal.widget.-$Lambda$6$LaTFiUorkqfcqmu-zMQbCLeO77c
com.android.internal.widget.AbsActionBarView
com.android.internal.widget.AbsActionBarView$VisibilityAnimListener
com.android.internal.widget.ActionBarContainer
com.android.internal.widget.ActionBarContainer$ActionBarBackgroundDrawable
com.android.internal.widget.ActionBarContextView
-com.android.internal.widget.ActionBarContextView$1
com.android.internal.widget.ActionBarOverlayLayout
com.android.internal.widget.ActionBarOverlayLayout$1
com.android.internal.widget.ActionBarOverlayLayout$2
@@ -5959,60 +6159,29 @@
com.android.internal.widget.AlertDialogLayout
com.android.internal.widget.BackgroundFallback
com.android.internal.widget.ButtonBarLayout
+com.android.internal.widget.CachingIconView
com.android.internal.widget.DecorContentParent
com.android.internal.widget.DecorToolbar
com.android.internal.widget.DialogTitle
com.android.internal.widget.EditableInputConnection
-com.android.internal.widget.FloatingToolbar
-com.android.internal.widget.FloatingToolbar$1
-com.android.internal.widget.FloatingToolbar$2
-com.android.internal.widget.FloatingToolbar$FloatingToolbarPopup
-com.android.internal.widget.FloatingToolbar$FloatingToolbarPopup$1
-com.android.internal.widget.FloatingToolbar$FloatingToolbarPopup$12
-com.android.internal.widget.FloatingToolbar$FloatingToolbarPopup$13
-com.android.internal.widget.FloatingToolbar$FloatingToolbarPopup$14
-com.android.internal.widget.FloatingToolbar$FloatingToolbarPopup$15
-com.android.internal.widget.FloatingToolbar$FloatingToolbarPopup$16
-com.android.internal.widget.FloatingToolbar$FloatingToolbarPopup$2
-com.android.internal.widget.FloatingToolbar$FloatingToolbarPopup$3
-com.android.internal.widget.FloatingToolbar$FloatingToolbarPopup$4
-com.android.internal.widget.FloatingToolbar$FloatingToolbarPopup$5
-com.android.internal.widget.FloatingToolbar$FloatingToolbarPopup$LogAccelerateInterpolator
-com.android.internal.widget.FloatingToolbar$FloatingToolbarPopup$OverflowPanel
-com.android.internal.widget.FloatingToolbar$FloatingToolbarPopup$OverflowPanelViewHelper
+com.android.internal.widget.ICheckCredentialProgressCallback
com.android.internal.widget.ILockSettings
com.android.internal.widget.ILockSettings$Stub
com.android.internal.widget.ILockSettings$Stub$Proxy
com.android.internal.widget.ImageFloatingTextView
-com.android.internal.widget.LinearLayoutWithDefaultTouchRecepient
-com.android.internal.widget.LockPatternChecker
-com.android.internal.widget.LockPatternChecker$3
-com.android.internal.widget.LockPatternChecker$5
-com.android.internal.widget.LockPatternChecker$OnCheckCallback
-com.android.internal.widget.LockPatternChecker$OnVerifyCallback
com.android.internal.widget.LockPatternUtils
-com.android.internal.widget.LockPatternUtils$1
com.android.internal.widget.LockPatternUtils$RequestThrottledException
com.android.internal.widget.LockPatternUtils$StrongAuthTracker
com.android.internal.widget.LockPatternUtils$StrongAuthTracker$1
com.android.internal.widget.LockPatternUtils$StrongAuthTracker$H
com.android.internal.widget.MediaNotificationView
com.android.internal.widget.NotificationActionListLayout
-com.android.internal.widget.NotificationActionListLayout$-void__clinit___LambdaImpl0
+com.android.internal.widget.NotificationExpandButton
com.android.internal.widget.PreferenceImageView
-com.android.internal.widget.ResolverDrawerLayout
-com.android.internal.widget.ResolverDrawerLayout$1
-com.android.internal.widget.ResolverDrawerLayout$LayoutParams
-com.android.internal.widget.ResolverDrawerLayout$OnDismissedListener
com.android.internal.widget.ScrollBarUtils
-com.android.internal.widget.TextViewInputDisabler
-com.android.internal.widget.TextViewInputDisabler$1
com.android.internal.widget.ToolbarWidgetWrapper
com.android.internal.widget.ToolbarWidgetWrapper$1
-com.android.internal.widget.ToolbarWidgetWrapper$2
-com.android.internal.widget.ToolbarWidgetWrapper$3
com.android.internal.widget.VerifyCredentialResponse
-com.android.internal.widget.VerifyCredentialResponse$1
com.android.okhttp.Address
com.android.okhttp.AndroidInternal
com.android.okhttp.AndroidShimResponseCache
@@ -6032,6 +6201,8 @@
com.android.okhttp.ConnectionSpec
com.android.okhttp.ConnectionSpec$Builder
com.android.okhttp.Dispatcher
+com.android.okhttp.Dns
+com.android.okhttp.Dns$1
com.android.okhttp.Handshake
com.android.okhttp.Headers
com.android.okhttp.Headers$Builder
@@ -6060,12 +6231,11 @@
com.android.okhttp.internal.DiskLruCache$1
com.android.okhttp.internal.DiskLruCache$2
com.android.okhttp.internal.DiskLruCache$3
+com.android.okhttp.internal.DiskLruCache$Editor
com.android.okhttp.internal.DiskLruCache$Entry
com.android.okhttp.internal.FaultHidingSink
com.android.okhttp.internal.Internal
com.android.okhttp.internal.InternalCache
-com.android.okhttp.internal.Network
-com.android.okhttp.internal.Network$1
com.android.okhttp.internal.OptionalMethod
com.android.okhttp.internal.Platform
com.android.okhttp.internal.RouteDatabase
@@ -6076,17 +6246,17 @@
com.android.okhttp.internal.http.CacheStrategy
com.android.okhttp.internal.http.CacheStrategy$Factory
com.android.okhttp.internal.http.HeaderParser
-com.android.okhttp.internal.http.HttpConnection
-com.android.okhttp.internal.http.HttpConnection$AbstractSource
-com.android.okhttp.internal.http.HttpConnection$ChunkedSink
-com.android.okhttp.internal.http.HttpConnection$ChunkedSource
-com.android.okhttp.internal.http.HttpConnection$FixedLengthSink
-com.android.okhttp.internal.http.HttpConnection$FixedLengthSource
-com.android.okhttp.internal.http.HttpConnection$UnknownLengthSource
+com.android.okhttp.internal.http.Http1xStream
+com.android.okhttp.internal.http.Http1xStream$AbstractSource
+com.android.okhttp.internal.http.Http1xStream$ChunkedSink
+com.android.okhttp.internal.http.Http1xStream$ChunkedSource
+com.android.okhttp.internal.http.Http1xStream$FixedLengthSink
+com.android.okhttp.internal.http.Http1xStream$FixedLengthSource
+com.android.okhttp.internal.http.Http1xStream$UnknownLengthSource
com.android.okhttp.internal.http.HttpEngine
com.android.okhttp.internal.http.HttpEngine$1
com.android.okhttp.internal.http.HttpMethod
-com.android.okhttp.internal.http.HttpTransport
+com.android.okhttp.internal.http.HttpStream
com.android.okhttp.internal.http.OkHeaders
com.android.okhttp.internal.http.OkHeaders$1
com.android.okhttp.internal.http.RealResponseBody
@@ -6096,12 +6266,13 @@
com.android.okhttp.internal.http.RouteException
com.android.okhttp.internal.http.RouteSelector
com.android.okhttp.internal.http.StatusLine
-com.android.okhttp.internal.http.Transport
+com.android.okhttp.internal.http.StreamAllocation
com.android.okhttp.internal.huc.DelegatingHttpsURLConnection
com.android.okhttp.internal.huc.HttpURLConnectionImpl
com.android.okhttp.internal.huc.HttpsURLConnectionImpl
com.android.okhttp.internal.io.FileSystem
com.android.okhttp.internal.io.FileSystem$1
+com.android.okhttp.internal.io.RealConnection
com.android.okhttp.internal.tls.OkHostnameVerifier
com.android.okhttp.okio.AsyncTimeout
com.android.okhttp.okio.AsyncTimeout$1
@@ -6145,20 +6316,34 @@
com.android.org.bouncycastle.asn1.x509.X509ObjectIdentifiers
com.android.org.bouncycastle.asn1.x9.X9ObjectIdentifiers
com.android.org.bouncycastle.crypto.AsymmetricBlockCipher
+com.android.org.bouncycastle.crypto.BlockCipher
+com.android.org.bouncycastle.crypto.BufferedBlockCipher
com.android.org.bouncycastle.crypto.CipherKeyGenerator
+com.android.org.bouncycastle.crypto.CipherParameters
com.android.org.bouncycastle.crypto.CryptoException
+com.android.org.bouncycastle.crypto.DataLengthException
com.android.org.bouncycastle.crypto.Digest
com.android.org.bouncycastle.crypto.ExtendedDigest
com.android.org.bouncycastle.crypto.InvalidCipherTextException
com.android.org.bouncycastle.crypto.KeyGenerationParameters
+com.android.org.bouncycastle.crypto.OutputLengthException
+com.android.org.bouncycastle.crypto.RuntimeCryptoException
com.android.org.bouncycastle.crypto.digests.AndroidDigestFactory
com.android.org.bouncycastle.crypto.digests.AndroidDigestFactoryInterface
com.android.org.bouncycastle.crypto.digests.AndroidDigestFactoryOpenSSL
com.android.org.bouncycastle.crypto.digests.OpenSSLDigest
com.android.org.bouncycastle.crypto.digests.OpenSSLDigest$SHA1
com.android.org.bouncycastle.crypto.encodings.OAEPEncoding
+com.android.org.bouncycastle.crypto.engines.AESEngine
com.android.org.bouncycastle.crypto.engines.RSABlindedEngine
com.android.org.bouncycastle.crypto.engines.RSACoreEngine
+com.android.org.bouncycastle.crypto.paddings.BlockCipherPadding
+com.android.org.bouncycastle.crypto.paddings.PKCS7Padding
+com.android.org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher
+com.android.org.bouncycastle.crypto.params.KeyParameter
+com.android.org.bouncycastle.crypto.params.ParametersWithRandom
+com.android.org.bouncycastle.jcajce.PBKDFKey
+com.android.org.bouncycastle.jcajce.PKCS12Key
com.android.org.bouncycastle.jcajce.provider.asymmetric.DH$Mappings
com.android.org.bouncycastle.jcajce.provider.asymmetric.DSA$Mappings
com.android.org.bouncycastle.jcajce.provider.asymmetric.EC$Mappings
@@ -6196,6 +6381,8 @@
com.android.org.bouncycastle.jcajce.provider.keystore.bc.BcKeyStoreSpi
com.android.org.bouncycastle.jcajce.provider.keystore.bc.BcKeyStoreSpi$Std
com.android.org.bouncycastle.jcajce.provider.symmetric.AES
+com.android.org.bouncycastle.jcajce.provider.symmetric.AES$ECB
+com.android.org.bouncycastle.jcajce.provider.symmetric.AES$ECB$1
com.android.org.bouncycastle.jcajce.provider.symmetric.AES$KeyGen
com.android.org.bouncycastle.jcajce.provider.symmetric.AES$Mappings
com.android.org.bouncycastle.jcajce.provider.symmetric.ARC4
@@ -6206,18 +6393,31 @@
com.android.org.bouncycastle.jcajce.provider.symmetric.DES$Mappings
com.android.org.bouncycastle.jcajce.provider.symmetric.DESede
com.android.org.bouncycastle.jcajce.provider.symmetric.DESede$Mappings
+com.android.org.bouncycastle.jcajce.provider.symmetric.PBEPBKDF2
+com.android.org.bouncycastle.jcajce.provider.symmetric.PBEPBKDF2$Mappings
com.android.org.bouncycastle.jcajce.provider.symmetric.PBEPKCS12
com.android.org.bouncycastle.jcajce.provider.symmetric.PBEPKCS12$Mappings
+com.android.org.bouncycastle.jcajce.provider.symmetric.PBES2AlgorithmParameters
+com.android.org.bouncycastle.jcajce.provider.symmetric.PBES2AlgorithmParameters$Mappings
com.android.org.bouncycastle.jcajce.provider.symmetric.RC2
com.android.org.bouncycastle.jcajce.provider.symmetric.RC2$Mappings
com.android.org.bouncycastle.jcajce.provider.symmetric.SymmetricAlgorithmProvider
com.android.org.bouncycastle.jcajce.provider.symmetric.Twofish
com.android.org.bouncycastle.jcajce.provider.symmetric.Twofish$Mappings
+com.android.org.bouncycastle.jcajce.provider.symmetric.util.BCPBEKey
+com.android.org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher
+com.android.org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher$AEADGenericBlockCipher
+com.android.org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher$BufferedGenericBlockCipher
+com.android.org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher$GenericBlockCipher
com.android.org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator
+com.android.org.bouncycastle.jcajce.provider.symmetric.util.BaseWrapCipher
+com.android.org.bouncycastle.jcajce.provider.symmetric.util.BlockCipherProvider
+com.android.org.bouncycastle.jcajce.provider.symmetric.util.PBE
com.android.org.bouncycastle.jcajce.provider.util.AlgorithmProvider
com.android.org.bouncycastle.jcajce.provider.util.AsymmetricAlgorithmProvider
com.android.org.bouncycastle.jcajce.provider.util.AsymmetricKeyInfoConverter
com.android.org.bouncycastle.jcajce.provider.util.DigestFactory
+com.android.org.bouncycastle.jcajce.spec.AEADParameterSpec
com.android.org.bouncycastle.jcajce.util.BCJcaJceHelper
com.android.org.bouncycastle.jcajce.util.JcaJceHelper
com.android.org.bouncycastle.jcajce.util.ProviderJcaJceHelper
@@ -6227,19 +6427,25 @@
com.android.org.bouncycastle.jce.provider.BouncyCastleProviderConfiguration
com.android.org.bouncycastle.util.Arrays
com.android.org.bouncycastle.util.Encodable
+com.android.org.bouncycastle.util.Pack
com.android.org.bouncycastle.util.Strings
com.android.org.bouncycastle.util.Strings$1
+com.android.org.conscrypt.AbstractOpenSSLSession
com.android.org.conscrypt.AbstractSessionContext
com.android.org.conscrypt.AbstractSessionContext$1
com.android.org.conscrypt.AddressUtils
com.android.org.conscrypt.ByteArray
-com.android.org.conscrypt.CertPinManager
+com.android.org.conscrypt.CertBlacklist
com.android.org.conscrypt.CertificatePriorityComparator
com.android.org.conscrypt.ChainStrengthAnalyzer
com.android.org.conscrypt.ClientSessionContext
com.android.org.conscrypt.ClientSessionContext$HostAndPort
com.android.org.conscrypt.CryptoUpcalls
+com.android.org.conscrypt.EvpMdRef$MD5
+com.android.org.conscrypt.EvpMdRef$SHA1
+com.android.org.conscrypt.EvpMdRef$SHA256
com.android.org.conscrypt.FileClientSessionCache
+com.android.org.conscrypt.FileClientSessionCache$CacheFile
com.android.org.conscrypt.FileClientSessionCache$Impl
com.android.org.conscrypt.Hex
com.android.org.conscrypt.JSSEProvider
@@ -6278,7 +6484,6 @@
com.android.org.conscrypt.OpenSSLMessageDigestJDK$MD5
com.android.org.conscrypt.OpenSSLMessageDigestJDK$SHA1
com.android.org.conscrypt.OpenSSLMessageDigestJDK$SHA256
-com.android.org.conscrypt.OpenSSLMessageDigestJDK$SHA512
com.android.org.conscrypt.OpenSSLProvider
com.android.org.conscrypt.OpenSSLRSAKeyFactory
com.android.org.conscrypt.OpenSSLRSAKeyPairGenerator
@@ -6305,10 +6510,8 @@
com.android.org.conscrypt.OpenSSLX509CertificateFactory$2
com.android.org.conscrypt.OpenSSLX509CertificateFactory$Parser
com.android.org.conscrypt.OpenSSLX509CertificateFactory$ParsingException
-com.android.org.conscrypt.PinEntryException
-com.android.org.conscrypt.PinListEntry
-com.android.org.conscrypt.PinManagerException
com.android.org.conscrypt.Platform
+com.android.org.conscrypt.Platform$NoPreloadHolder
com.android.org.conscrypt.SSLClientSessionCache
com.android.org.conscrypt.SSLParametersImpl
com.android.org.conscrypt.SSLParametersImpl$AliasChooser
@@ -6326,12 +6529,20 @@
com.android.org.conscrypt.TrustedCertificateStore$4
com.android.org.conscrypt.TrustedCertificateStore$5
com.android.org.conscrypt.TrustedCertificateStore$CertSelector
+com.android.org.conscrypt.ct.CTLogInfo
+com.android.org.conscrypt.ct.CTLogStore
+com.android.org.conscrypt.ct.CTLogStoreImpl
+com.android.org.conscrypt.ct.CTLogStoreImpl$InvalidLogFileException
+com.android.org.conscrypt.ct.CTPolicy
+com.android.org.conscrypt.ct.CTPolicyImpl
+com.android.org.conscrypt.ct.CTVerifier
+com.android.org.conscrypt.ct.KnownLogs
+com.android.org.conscrypt.ct.SerializationException
com.android.org.conscrypt.util.ArrayUtils
com.android.org.conscrypt.util.EmptyArray
com.android.server.AppWidgetBackupBridge
com.android.server.BootReceiver
com.android.server.BootReceiver$1
-com.android.server.BootReceiver$2
com.android.server.LocalServices
com.android.server.NetworkManagementSocketTagger
com.android.server.NetworkManagementSocketTagger$1
@@ -6341,6 +6552,7 @@
com.android.server.WidgetBackupProvider
com.android.server.backup.AccountSyncSettingsBackupHelper
com.android.server.net.BaseNetworkObserver
+com.android.server.net.DnsServerEntry
com.android.server.net.DnsServerRepository
com.android.server.net.NetlinkTracker
com.android.server.net.NetlinkTracker$Callback
@@ -6350,6 +6562,17 @@
com.android.server.sip.SipWakeLock
com.android.server.sip.SipWakeupTimer
com.android.server.sip.SipWakeupTimer$MyEventComparator
+com.android.server.wifi.nano.WifiMetricsProto$AlertReasonCount
+com.android.server.wifi.nano.WifiMetricsProto$ConnectionEvent
+com.android.server.wifi.nano.WifiMetricsProto$RouterFingerPrint
+com.android.server.wifi.nano.WifiMetricsProto$RssiPollCount
+com.android.server.wifi.nano.WifiMetricsProto$SoftApDurationBucket
+com.android.server.wifi.nano.WifiMetricsProto$SoftApReturnCodeCount
+com.android.server.wifi.nano.WifiMetricsProto$WifiLog
+com.android.server.wifi.nano.WifiMetricsProto$WifiLog$ScanReturnEntry
+com.android.server.wifi.nano.WifiMetricsProto$WifiLog$WifiSystemStateEntry
+com.android.server.wifi.nano.WifiMetricsProto$WifiScoreCount
+com.android.server.wm.nano.WindowManagerProtos$TaskSnapshotProto
com.google.android.collect.Lists
com.google.android.collect.Maps
com.google.android.collect.Sets
@@ -6363,15 +6586,21 @@
com.google.android.mms.pdu.GenericPdu
com.google.android.mms.pdu.PduComposer
com.google.android.mms.pdu.PduPersister
+dalvik.annotation.optimization.CriticalNative
+dalvik.annotation.optimization.FastNative
dalvik.system.BaseDexClassLoader
+dalvik.system.BaseDexClassLoader$Reporter
dalvik.system.BlockGuard
dalvik.system.BlockGuard$1
dalvik.system.BlockGuard$2
dalvik.system.BlockGuard$BlockGuardPolicyException
dalvik.system.BlockGuard$Policy
+dalvik.system.ClassExt
dalvik.system.CloseGuard
dalvik.system.CloseGuard$DefaultReporter
+dalvik.system.CloseGuard$DefaultTracker
dalvik.system.CloseGuard$Reporter
+dalvik.system.CloseGuard$Tracker
dalvik.system.DalvikLogHandler
dalvik.system.DalvikLogging
dalvik.system.DexClassLoader
@@ -6379,6 +6608,10 @@
dalvik.system.DexFile$DFEnum
dalvik.system.DexPathList
dalvik.system.DexPathList$Element
+dalvik.system.DexPathList$NativeLibraryElement
+dalvik.system.EmulatedStackFrame
+dalvik.system.EmulatedStackFrame$Range
+dalvik.system.InMemoryDexClassLoader$DexData
dalvik.system.PathClassLoader
dalvik.system.SocketTagger
dalvik.system.SocketTagger$1
@@ -6386,11 +6619,6 @@
dalvik.system.VMRuntime
dalvik.system.VMStack
dalvik.system.ZygoteHooks
-java.beans.ChangeListenerMap
-java.beans.PropertyChangeEvent
-java.beans.PropertyChangeListener
-java.beans.PropertyChangeSupport
-java.beans.PropertyChangeSupport$PropertyChangeListenerMap
java.io.Bits
java.io.BufferedInputStream
java.io.BufferedOutputStream
@@ -6407,6 +6635,7 @@
java.io.DataInputStream
java.io.DataOutput
java.io.DataOutputStream
+java.io.DefaultFileSystem
java.io.EOFException
java.io.ExpiringCache
java.io.ExpiringCache$1
@@ -6414,7 +6643,9 @@
java.io.Externalizable
java.io.File
java.io.File$PathStatus
+java.io.File$TempDirectory
java.io.FileDescriptor
+java.io.FileDescriptor$1
java.io.FileFilter
java.io.FileInputStream
java.io.FileInputStream$UseManualSkipException
@@ -6434,6 +6665,7 @@
java.io.InterruptedIOException
java.io.InvalidClassException
java.io.InvalidObjectException
+java.io.NotSerializableException
java.io.ObjectInput
java.io.ObjectInputStream
java.io.ObjectInputStream$BlockDataInputStream
@@ -6445,6 +6677,7 @@
java.io.ObjectOutputStream
java.io.ObjectOutputStream$BlockDataOutputStream
java.io.ObjectOutputStream$HandleTable
+java.io.ObjectOutputStream$PutField
java.io.ObjectOutputStream$ReplaceTable
java.io.ObjectStreamClass
java.io.ObjectStreamClass$1
@@ -6475,13 +6708,17 @@
java.io.SerialCallbackContext
java.io.Serializable
java.io.SerializablePermission
+java.io.StreamCorruptedException
java.io.StringBufferInputStream
java.io.StringReader
java.io.StringWriter
+java.io.SyncFailedException
java.io.UTFDataFormatException
java.io.UnixFileSystem
java.io.UnsupportedEncodingException
java.io.Writer
+java.lang.-$Lambda$250$S9HjrJh0nDg7IyU6wZdPArnZWRQ
+java.lang.-$Lambda$251$S9HjrJh0nDg7IyU6wZdPArnZWRQ
java.lang.AbstractMethodError
java.lang.AbstractStringBuilder
java.lang.AndroidHardcodedSystemProperties
@@ -6498,8 +6735,6 @@
java.lang.CaseMapper
java.lang.CaseMapper$1
java.lang.CharSequence
-java.lang.CharSequence$-java_util_stream_IntStream_chars__LambdaImpl0
-java.lang.CharSequence$-java_util_stream_IntStream_codePoints__LambdaImpl0
java.lang.CharSequence$1CharIterator
java.lang.CharSequence$1CodePointIterator
java.lang.Character
@@ -6531,9 +6766,6 @@
java.lang.Exception
java.lang.ExceptionInInitializerError
java.lang.Float
-java.lang.FloatingDecimal
-java.lang.FloatingDecimal$1
-java.lang.FloatingDecimal$2
java.lang.IllegalAccessError
java.lang.IllegalAccessException
java.lang.IllegalArgumentException
@@ -6543,6 +6775,7 @@
java.lang.IncompatibleClassChangeError
java.lang.IndexOutOfBoundsException
java.lang.InheritableThreadLocal
+java.lang.InstantiationError
java.lang.InstantiationException
java.lang.Integer
java.lang.Integer$IntegerCache
@@ -6554,7 +6787,8 @@
java.lang.Long
java.lang.Long$LongCache
java.lang.Math
-java.lang.Math$NoImagePreloadHolder
+java.lang.Math$RandomNumberGeneratorHolder
+java.lang.NegativeArraySizeException
java.lang.NoClassDefFoundError
java.lang.NoSuchFieldError
java.lang.NoSuchFieldException
@@ -6586,7 +6820,6 @@
java.lang.SecurityManager
java.lang.Short
java.lang.Short$ShortCache
-java.lang.Shutdown
java.lang.StackOverflowError
java.lang.StackTraceElement
java.lang.StrictMath
@@ -6594,7 +6827,6 @@
java.lang.String$CaseInsensitiveComparator
java.lang.StringBuffer
java.lang.StringBuilder
-java.lang.StringCoding
java.lang.StringFactory
java.lang.StringIndexOutOfBoundsException
java.lang.System
@@ -6636,6 +6868,22 @@
java.lang.annotation.Inherited
java.lang.annotation.Retention
java.lang.annotation.Target
+java.lang.invoke.MethodHandle
+java.lang.invoke.MethodHandleImpl
+java.lang.invoke.MethodHandleImpl$HandleInfo
+java.lang.invoke.MethodHandleInfo
+java.lang.invoke.MethodHandleStatics
+java.lang.invoke.MethodHandles
+java.lang.invoke.MethodType
+java.lang.invoke.MethodType$ConcurrentWeakInternSet
+java.lang.invoke.MethodType$ConcurrentWeakInternSet$WeakEntry
+java.lang.invoke.MethodTypeForm
+java.lang.invoke.Transformers$BindTo
+java.lang.invoke.Transformers$Collector
+java.lang.invoke.Transformers$Spreader
+java.lang.invoke.Transformers$Transformer
+java.lang.invoke.Transformers$VarargsCollector
+java.lang.invoke.WrongMethodTypeException
java.lang.ref.FinalizerReference
java.lang.ref.FinalizerReference$Sentinel
java.lang.ref.PhantomReference
@@ -6643,27 +6891,40 @@
java.lang.ref.ReferenceQueue
java.lang.ref.SoftReference
java.lang.ref.WeakReference
-java.lang.reflect.AbstractMethod
-java.lang.reflect.AbstractMethod$GenericInfo
java.lang.reflect.AccessibleObject
java.lang.reflect.AnnotatedElement
java.lang.reflect.Array
java.lang.reflect.Constructor
+java.lang.reflect.Executable
+java.lang.reflect.Executable$GenericInfo
java.lang.reflect.Field
java.lang.reflect.GenericArrayType
java.lang.reflect.GenericDeclaration
java.lang.reflect.InvocationHandler
java.lang.reflect.InvocationTargetException
+java.lang.reflect.MalformedParametersException
java.lang.reflect.Member
java.lang.reflect.Method
java.lang.reflect.Method$1
java.lang.reflect.Modifier
+java.lang.reflect.Parameter
java.lang.reflect.ParameterizedType
java.lang.reflect.Proxy
java.lang.reflect.Proxy$1
+java.lang.reflect.Proxy$Key1
+java.lang.reflect.Proxy$Key2
+java.lang.reflect.Proxy$KeyFactory
+java.lang.reflect.Proxy$KeyX
+java.lang.reflect.Proxy$ProxyClassFactory
java.lang.reflect.Type
java.lang.reflect.TypeVariable
java.lang.reflect.UndeclaredThrowableException
+java.lang.reflect.WeakCache
+java.lang.reflect.WeakCache$CacheKey
+java.lang.reflect.WeakCache$CacheValue
+java.lang.reflect.WeakCache$Factory
+java.lang.reflect.WeakCache$LookupValue
+java.lang.reflect.WeakCache$Value
java.lang.reflect.WildcardType
java.math.BigDecimal
java.math.BigInt
@@ -6671,7 +6932,6 @@
java.math.BitLevel
java.math.Conversion
java.math.Division
-java.math.Logical
java.math.MathContext
java.math.Multiplication
java.math.NativeBN
@@ -6718,6 +6978,7 @@
java.net.InMemoryCookieStore
java.net.Inet4Address
java.net.Inet6Address
+java.net.Inet6Address$Inet6AddressHolder
java.net.Inet6AddressImpl
java.net.InetAddress
java.net.InetAddress$1
@@ -6730,7 +6991,6 @@
java.net.MalformedURLException
java.net.MulticastSocket
java.net.NetworkInterface
-java.net.NetworkInterface$1
java.net.NetworkInterface$1checkedAddresses
java.net.NoRouteToHostException
java.net.Parts
@@ -6739,14 +6999,12 @@
java.net.PlainSocketImpl
java.net.PortUnreachableException
java.net.ProtocolException
-java.net.ProtocolFamily
java.net.Proxy
java.net.Proxy$Type
java.net.ProxySelector
java.net.ResponseCache
java.net.ServerSocket
java.net.Socket
-java.net.Socket$1
java.net.Socket$2
java.net.Socket$3
java.net.SocketAddress
@@ -6758,8 +7016,6 @@
java.net.SocketTimeoutException
java.net.SocksConsts
java.net.SocksSocketImpl
-java.net.SocksSocketImpl$3
-java.net.StandardProtocolFamily
java.net.URI
java.net.URI$Parser
java.net.URISyntaxException
@@ -6805,7 +7061,6 @@
java.nio.channels.CancelledKeyException
java.nio.channels.Channel
java.nio.channels.Channels
-java.nio.channels.Channels$1
java.nio.channels.Channels$ReadableByteChannelImpl
java.nio.channels.ClosedByInterruptException
java.nio.channels.ClosedChannelException
@@ -6815,6 +7070,7 @@
java.nio.channels.FileLock
java.nio.channels.GatheringByteChannel
java.nio.channels.InterruptibleChannel
+java.nio.channels.MulticastChannel
java.nio.channels.NetworkChannel
java.nio.channels.NonWritableChannelException
java.nio.channels.OverlappingFileLockException
@@ -6822,19 +7078,12 @@
java.nio.channels.ScatteringByteChannel
java.nio.channels.SeekableByteChannel
java.nio.channels.SelectableChannel
-java.nio.channels.SelectionKey
-java.nio.channels.Selector
java.nio.channels.ServerSocketChannel
java.nio.channels.SocketChannel
java.nio.channels.WritableByteChannel
java.nio.channels.spi.AbstractInterruptibleChannel
java.nio.channels.spi.AbstractInterruptibleChannel$1
java.nio.channels.spi.AbstractSelectableChannel
-java.nio.channels.spi.AbstractSelectionKey
-java.nio.channels.spi.AbstractSelector
-java.nio.channels.spi.AbstractSelector$1
-java.nio.channels.spi.SelectorProvider
-java.nio.channels.spi.SelectorProvider$1
java.nio.charset.CharacterCodingException
java.nio.charset.Charset
java.nio.charset.CharsetDecoder
@@ -6850,6 +7099,21 @@
java.nio.charset.IllegalCharsetNameException
java.nio.charset.StandardCharsets
java.nio.charset.UnsupportedCharsetException
+java.nio.file.FileAlreadyExistsException
+java.nio.file.FileSystem
+java.nio.file.FileSystemException
+java.nio.file.FileSystems
+java.nio.file.FileSystems$DefaultFileSystemHolder
+java.nio.file.FileSystems$DefaultFileSystemHolder$1
+java.nio.file.Files
+java.nio.file.NoSuchFileException
+java.nio.file.OpenOption
+java.nio.file.Path
+java.nio.file.Watchable
+java.nio.file.attribute.BasicFileAttributes
+java.nio.file.attribute.FileAttribute
+java.nio.file.attribute.PosixFileAttributes
+java.nio.file.spi.FileSystemProvider
java.security.AccessControlContext
java.security.AccessControlException
java.security.AccessController
@@ -6912,6 +7176,7 @@
java.security.cert.CRL
java.security.cert.CRLException
java.security.cert.CertPath
+java.security.cert.CertPathBuilderException
java.security.cert.CertPathChecker
java.security.cert.CertPathHelperImpl
java.security.cert.CertPathParameters
@@ -6950,7 +7215,6 @@
java.security.interfaces.RSAPublicKey
java.security.spec.AlgorithmParameterSpec
java.security.spec.ECField
-java.security.spec.ECFieldF2m
java.security.spec.ECFieldFp
java.security.spec.ECGenParameterSpec
java.security.spec.ECParameterSpec
@@ -6964,6 +7228,8 @@
java.security.spec.KeySpec
java.security.spec.MGF1ParameterSpec
java.security.spec.PKCS8EncodedKeySpec
+java.security.spec.RSAPrivateCrtKeySpec
+java.security.spec.RSAPrivateKeySpec
java.security.spec.RSAPublicKeySpec
java.security.spec.X509EncodedKeySpec
java.sql.Date
@@ -6999,17 +7265,23 @@
java.text.RuleBasedCollator
java.text.SimpleDateFormat
java.text.StringCharacterIterator
-java.text.spi.DateFormatProvider
-java.text.spi.DateFormatSymbolsProvider
-java.text.spi.DecimalFormatSymbolsProvider
-java.text.spi.NumberFormatProvider
+java.time.DateTimeException
+java.util.-$Lambda$181$4EqhxufgNKat19m0CB0-toH_lzo
+java.util.-$Lambda$182$4EqhxufgNKat19m0CB0-toH_lzo
+java.util.-$Lambda$183$4EqhxufgNKat19m0CB0-toH_lzo
+java.util.-$Lambda$184$4EqhxufgNKat19m0CB0-toH_lzo
+java.util.-$Lambda$267$4EqhxufgNKat19m0CB0-toH_lzo
+java.util.-$Lambda$268$4EqhxufgNKat19m0CB0-toH_lzo
+java.util.-$Lambda$291$aUGKT4ItCOku5-JSG-x8Aqj2pJw
+java.util.-$Lambda$292$aUGKT4ItCOku5-JSG-x8Aqj2pJw
+java.util.-$Lambda$293$aUGKT4ItCOku5-JSG-x8Aqj2pJw
+java.util.-$Lambda$294$aUGKT4ItCOku5-JSG-x8Aqj2pJw
java.util.AbstractCollection
java.util.AbstractList
java.util.AbstractList$Itr
java.util.AbstractList$ListItr
java.util.AbstractMap
java.util.AbstractMap$1
-java.util.AbstractMap$1$1
java.util.AbstractMap$2
java.util.AbstractMap$2$1
java.util.AbstractMap$SimpleEntry
@@ -7019,14 +7291,31 @@
java.util.AbstractSet
java.util.ArrayDeque
java.util.ArrayDeque$DeqIterator
+java.util.ArrayDeque$DescendingIterator
java.util.ArrayList
java.util.ArrayList$ArrayListSpliterator
java.util.ArrayList$Itr
java.util.ArrayList$ListItr
java.util.ArrayList$SubList
java.util.ArrayList$SubList$1
+java.util.ArrayPrefixHelpers$CumulateTask
+java.util.ArrayPrefixHelpers$DoubleCumulateTask
+java.util.ArrayPrefixHelpers$IntCumulateTask
+java.util.ArrayPrefixHelpers$LongCumulateTask
java.util.Arrays
java.util.Arrays$ArrayList
+java.util.Arrays$NaturalOrder
+java.util.ArraysParallelSortHelpers$FJByte$Sorter
+java.util.ArraysParallelSortHelpers$FJChar$Sorter
+java.util.ArraysParallelSortHelpers$FJDouble$Sorter
+java.util.ArraysParallelSortHelpers$FJFloat$Sorter
+java.util.ArraysParallelSortHelpers$FJInt$Sorter
+java.util.ArraysParallelSortHelpers$FJLong$Sorter
+java.util.ArraysParallelSortHelpers$FJObject$Sorter
+java.util.ArraysParallelSortHelpers$FJShort$Sorter
+java.util.Base64
+java.util.Base64$Decoder
+java.util.Base64$Encoder
java.util.BitSet
java.util.Calendar
java.util.Collection
@@ -7038,6 +7327,9 @@
java.util.Collections$CheckedCollection
java.util.Collections$CheckedList
java.util.Collections$CheckedMap
+java.util.Collections$CheckedNavigableMap
+java.util.Collections$CheckedNavigableSet
+java.util.Collections$CheckedQueue
java.util.Collections$CheckedRandomAccessList
java.util.Collections$CheckedSet
java.util.Collections$CheckedSortedMap
@@ -7058,6 +7350,8 @@
java.util.Collections$SynchronizedCollection
java.util.Collections$SynchronizedList
java.util.Collections$SynchronizedMap
+java.util.Collections$SynchronizedNavigableMap
+java.util.Collections$SynchronizedNavigableSet
java.util.Collections$SynchronizedRandomAccessList
java.util.Collections$SynchronizedSet
java.util.Collections$SynchronizedSortedMap
@@ -7070,18 +7364,16 @@
java.util.Collections$UnmodifiableMap$UnmodifiableEntrySet
java.util.Collections$UnmodifiableMap$UnmodifiableEntrySet$1
java.util.Collections$UnmodifiableMap$UnmodifiableEntrySet$UnmodifiableEntry
+java.util.Collections$UnmodifiableNavigableMap
+java.util.Collections$UnmodifiableNavigableMap$EmptyNavigableMap
+java.util.Collections$UnmodifiableNavigableSet
+java.util.Collections$UnmodifiableNavigableSet$EmptyNavigableSet
java.util.Collections$UnmodifiableRandomAccessList
java.util.Collections$UnmodifiableSet
java.util.Collections$UnmodifiableSortedMap
java.util.Collections$UnmodifiableSortedSet
java.util.ComparableTimSort
java.util.Comparator
-java.util.Comparator$-java_util_Comparator_comparingDouble_java_util_function_ToDoubleFunction_keyExtractor_LambdaImpl0
-java.util.Comparator$-java_util_Comparator_comparingInt_java_util_function_ToIntFunction_keyExtractor_LambdaImpl0
-java.util.Comparator$-java_util_Comparator_comparingLong_java_util_function_ToLongFunction_keyExtractor_LambdaImpl0
-java.util.Comparator$-java_util_Comparator_comparing_java_util_function_Function_keyExtractor_LambdaImpl0
-java.util.Comparator$-java_util_Comparator_comparing_java_util_function_Function_keyExtractor_java_util_Comparator_keyComparator_LambdaImpl0
-java.util.Comparator$-java_util_Comparator_thenComparing_java_util_Comparator_other_LambdaImpl0
java.util.Comparators$NaturalOrderComparator
java.util.Comparators$NullComparator
java.util.ConcurrentModificationException
@@ -7105,8 +7397,6 @@
java.util.EnumSet$SerializationProxy
java.util.Enumeration
java.util.EventListener
-java.util.EventObject
-java.util.FormatFlagsConversionMismatchException
java.util.Formattable
java.util.Formatter
java.util.Formatter$Conversion
@@ -7121,9 +7411,10 @@
java.util.HashMap$EntryIterator
java.util.HashMap$EntrySet
java.util.HashMap$HashIterator
-java.util.HashMap$HashMapEntry
java.util.HashMap$KeyIterator
java.util.HashMap$KeySet
+java.util.HashMap$Node
+java.util.HashMap$TreeNode
java.util.HashMap$ValueIterator
java.util.HashMap$Values
java.util.HashSet
@@ -7148,11 +7439,14 @@
java.util.JumboEnumSet
java.util.JumboEnumSet$EnumSetIterator
java.util.LinkedHashMap
-java.util.LinkedHashMap$EntryIterator
-java.util.LinkedHashMap$KeyIterator
+java.util.LinkedHashMap$LinkedEntryIterator
+java.util.LinkedHashMap$LinkedEntrySet
java.util.LinkedHashMap$LinkedHashIterator
java.util.LinkedHashMap$LinkedHashMapEntry
-java.util.LinkedHashMap$ValueIterator
+java.util.LinkedHashMap$LinkedKeyIterator
+java.util.LinkedHashMap$LinkedKeySet
+java.util.LinkedHashMap$LinkedValueIterator
+java.util.LinkedHashMap$LinkedValues
java.util.LinkedHashSet
java.util.LinkedList
java.util.LinkedList$DescendingIterator
@@ -7160,10 +7454,13 @@
java.util.LinkedList$Node
java.util.List
java.util.ListIterator
+java.util.ListResourceBundle
java.util.Locale
java.util.Locale$Builder
java.util.Locale$Cache
java.util.Locale$Category
+java.util.Locale$FilteringMode
+java.util.Locale$LanguageRange
java.util.Locale$LocaleKey
java.util.Map
java.util.Map$Entry
@@ -7197,14 +7494,8 @@
java.util.ResourceBundle$Control$1
java.util.ResourceBundle$Control$CandidateListCache
java.util.ResourceBundle$LoaderReference
-java.util.ResourceBundle$RBClassLoader
-java.util.ResourceBundle$RBClassLoader$1
java.util.Scanner
java.util.Scanner$1
-java.util.ServiceConfigurationError
-java.util.ServiceLoader
-java.util.ServiceLoader$1
-java.util.ServiceLoader$LazyIterator
java.util.Set
java.util.SimpleTimeZone
java.util.SortedMap
@@ -7220,6 +7511,7 @@
java.util.Spliterators$EmptySpliterator$OfInt
java.util.Spliterators$EmptySpliterator$OfLong
java.util.Spliterators$EmptySpliterator$OfRef
+java.util.Spliterators$IteratorSpliterator
java.util.Stack
java.util.StringJoiner
java.util.StringTokenizer
@@ -7264,6 +7556,7 @@
java.util.WeakHashMap$KeySet
java.util.WeakHashMap$ValueIterator
java.util.WeakHashMap$Values
+java.util.concurrent.-$Lambda$269$xR9BLpu6SifNikvFgr4lEiECBsk
java.util.concurrent.AbstractExecutorService
java.util.concurrent.ArrayBlockingQueue
java.util.concurrent.BlockingDeque
@@ -7279,15 +7572,48 @@
java.util.concurrent.CompletionStage
java.util.concurrent.ConcurrentHashMap
java.util.concurrent.ConcurrentHashMap$BaseIterator
+java.util.concurrent.ConcurrentHashMap$BulkTask
java.util.concurrent.ConcurrentHashMap$CollectionView
java.util.concurrent.ConcurrentHashMap$CounterCell
java.util.concurrent.ConcurrentHashMap$EntryIterator
java.util.concurrent.ConcurrentHashMap$EntrySetView
+java.util.concurrent.ConcurrentHashMap$ForEachEntryTask
+java.util.concurrent.ConcurrentHashMap$ForEachKeyTask
+java.util.concurrent.ConcurrentHashMap$ForEachMappingTask
+java.util.concurrent.ConcurrentHashMap$ForEachTransformedEntryTask
+java.util.concurrent.ConcurrentHashMap$ForEachTransformedKeyTask
+java.util.concurrent.ConcurrentHashMap$ForEachTransformedMappingTask
+java.util.concurrent.ConcurrentHashMap$ForEachTransformedValueTask
+java.util.concurrent.ConcurrentHashMap$ForEachValueTask
java.util.concurrent.ConcurrentHashMap$ForwardingNode
java.util.concurrent.ConcurrentHashMap$KeyIterator
java.util.concurrent.ConcurrentHashMap$KeySetView
java.util.concurrent.ConcurrentHashMap$MapEntry
+java.util.concurrent.ConcurrentHashMap$MapReduceEntriesTask
+java.util.concurrent.ConcurrentHashMap$MapReduceEntriesToDoubleTask
+java.util.concurrent.ConcurrentHashMap$MapReduceEntriesToIntTask
+java.util.concurrent.ConcurrentHashMap$MapReduceEntriesToLongTask
+java.util.concurrent.ConcurrentHashMap$MapReduceKeysTask
+java.util.concurrent.ConcurrentHashMap$MapReduceKeysToDoubleTask
+java.util.concurrent.ConcurrentHashMap$MapReduceKeysToIntTask
+java.util.concurrent.ConcurrentHashMap$MapReduceKeysToLongTask
+java.util.concurrent.ConcurrentHashMap$MapReduceMappingsTask
+java.util.concurrent.ConcurrentHashMap$MapReduceMappingsToDoubleTask
+java.util.concurrent.ConcurrentHashMap$MapReduceMappingsToIntTask
+java.util.concurrent.ConcurrentHashMap$MapReduceMappingsToLongTask
+java.util.concurrent.ConcurrentHashMap$MapReduceValuesTask
+java.util.concurrent.ConcurrentHashMap$MapReduceValuesToDoubleTask
+java.util.concurrent.ConcurrentHashMap$MapReduceValuesToIntTask
+java.util.concurrent.ConcurrentHashMap$MapReduceValuesToLongTask
java.util.concurrent.ConcurrentHashMap$Node
+java.util.concurrent.ConcurrentHashMap$ReduceEntriesTask
+java.util.concurrent.ConcurrentHashMap$ReduceKeysTask
+java.util.concurrent.ConcurrentHashMap$ReduceValuesTask
+java.util.concurrent.ConcurrentHashMap$ReservationNode
+java.util.concurrent.ConcurrentHashMap$SearchEntriesTask
+java.util.concurrent.ConcurrentHashMap$SearchKeysTask
+java.util.concurrent.ConcurrentHashMap$SearchMappingsTask
+java.util.concurrent.ConcurrentHashMap$SearchValuesTask
java.util.concurrent.ConcurrentHashMap$Segment
java.util.concurrent.ConcurrentHashMap$Traverser
java.util.concurrent.ConcurrentHashMap$TreeBin
@@ -7306,15 +7632,15 @@
java.util.concurrent.ConcurrentSkipListMap$KeyIterator
java.util.concurrent.ConcurrentSkipListMap$KeySet
java.util.concurrent.ConcurrentSkipListMap$Node
-java.util.concurrent.ConcurrentSkipListMap$SubMap
java.util.concurrent.ConcurrentSkipListMap$ValueIterator
java.util.concurrent.ConcurrentSkipListMap$Values
java.util.concurrent.ConcurrentSkipListSet
java.util.concurrent.CopyOnWriteArrayList
-java.util.concurrent.CopyOnWriteArrayList$CowIterator
+java.util.concurrent.CopyOnWriteArrayList$COWIterator
java.util.concurrent.CopyOnWriteArraySet
java.util.concurrent.CountDownLatch
java.util.concurrent.CountDownLatch$Sync
+java.util.concurrent.CountedCompleter
java.util.concurrent.DelayQueue
java.util.concurrent.Delayed
java.util.concurrent.ExecutionException
@@ -7346,6 +7672,8 @@
java.util.concurrent.LinkedBlockingQueue
java.util.concurrent.LinkedBlockingQueue$Itr
java.util.concurrent.LinkedBlockingQueue$Node
+java.util.concurrent.Phaser
+java.util.concurrent.Phaser$QNode
java.util.concurrent.PriorityBlockingQueue
java.util.concurrent.RejectedExecutionException
java.util.concurrent.RejectedExecutionHandler
@@ -7368,6 +7696,7 @@
java.util.concurrent.ThreadLocalRandom$1
java.util.concurrent.ThreadPoolExecutor
java.util.concurrent.ThreadPoolExecutor$AbortPolicy
+java.util.concurrent.ThreadPoolExecutor$DiscardOldestPolicy
java.util.concurrent.ThreadPoolExecutor$DiscardPolicy
java.util.concurrent.ThreadPoolExecutor$Worker
java.util.concurrent.TimeUnit
@@ -7412,21 +7741,35 @@
java.util.concurrent.locks.ReentrantReadWriteLock$Sync$HoldCounter
java.util.concurrent.locks.ReentrantReadWriteLock$Sync$ThreadLocalHoldCounter
java.util.concurrent.locks.ReentrantReadWriteLock$WriteLock
+java.util.function.-$Lambda$276$1MZdIZ-DL_fjy9l0o8IMJk57T2g
java.util.function.BiConsumer
java.util.function.BiFunction
+java.util.function.BinaryOperator
java.util.function.Consumer
+java.util.function.DoubleBinaryOperator
java.util.function.Function
+java.util.function.IntBinaryOperator
+java.util.function.IntConsumer
+java.util.function.IntFunction
+java.util.function.IntToDoubleFunction
+java.util.function.IntToLongFunction
+java.util.function.IntUnaryOperator
+java.util.function.LongBinaryOperator
+java.util.function.LongUnaryOperator
java.util.function.Predicate
java.util.function.Supplier
+java.util.function.ToDoubleBiFunction
java.util.function.ToDoubleFunction
+java.util.function.ToIntBiFunction
java.util.function.ToIntFunction
+java.util.function.ToLongBiFunction
java.util.function.ToLongFunction
java.util.function.UnaryOperator
java.util.jar.Attributes
java.util.jar.Attributes$Name
java.util.jar.JarEntry
java.util.jar.JarFile
-java.util.jar.JarFile$1
+java.util.jar.JarFile$JarEntryIterator
java.util.jar.JarFile$JarFileEntry
java.util.jar.JarVerifier
java.util.jar.JarVerifier$1
@@ -7434,9 +7777,6 @@
java.util.jar.Manifest
java.util.jar.Manifest$FastInputStream
java.util.logging.ErrorManager
-java.util.logging.FileHandler
-java.util.logging.FileHandler$InitializationErrorManager
-java.util.logging.FileHandler$MeteredStream
java.util.logging.Filter
java.util.logging.Formatter
java.util.logging.Handler
@@ -7445,7 +7785,8 @@
java.util.logging.LogManager
java.util.logging.LogManager$1
java.util.logging.LogManager$2
-java.util.logging.LogManager$4
+java.util.logging.LogManager$3
+java.util.logging.LogManager$5
java.util.logging.LogManager$Cleaner
java.util.logging.LogManager$LogNode
java.util.logging.LogManager$LoggerContext
@@ -7456,31 +7797,71 @@
java.util.logging.LogRecord
java.util.logging.Logger
java.util.logging.Logger$1
+java.util.logging.Logger$LoggerBundle
java.util.logging.LoggingPermission
java.util.logging.LoggingProxyImpl
-java.util.logging.SimpleFormatter
-java.util.logging.StreamHandler
-java.util.logging.XMLFormatter
java.util.prefs.AbstractPreferences
java.util.prefs.FileSystemPreferences
java.util.prefs.Preferences
java.util.regex.MatchResult
java.util.regex.Matcher
+java.util.regex.Matcher$OffsetBasedMatchResult
java.util.regex.Pattern
java.util.regex.PatternSyntaxException
-java.util.spi.LocaleServiceProvider
+java.util.stream.-$Lambda$155$qTstLJg88fs2C3g6LH-R51vCVP0
+java.util.stream.-$Lambda$41$qTstLJg88fs2C3g6LH-R51vCVP0
+java.util.stream.-$Lambda$67$qTstLJg88fs2C3g6LH-R51vCVP0
+java.util.stream.-$Lambda$89$qTstLJg88fs2C3g6LH-R51vCVP0
+java.util.stream.AbstractPipeline
java.util.stream.BaseStream
+java.util.stream.Collector
+java.util.stream.Collector$Characteristics
+java.util.stream.Collectors
+java.util.stream.Collectors$CollectorImpl
+java.util.stream.DoubleStream
+java.util.stream.ForEachOps
+java.util.stream.ForEachOps$ForEachOp
+java.util.stream.ForEachOps$ForEachOp$OfRef
java.util.stream.IntStream
+java.util.stream.LongStream
+java.util.stream.PipelineHelper
+java.util.stream.ReduceOps
+java.util.stream.ReduceOps$3
+java.util.stream.ReduceOps$3ReducingSink
+java.util.stream.ReduceOps$AccumulatingSink
+java.util.stream.ReduceOps$Box
+java.util.stream.ReduceOps$ReduceOp
+java.util.stream.ReferencePipeline
+java.util.stream.ReferencePipeline$2
+java.util.stream.ReferencePipeline$2$1
+java.util.stream.ReferencePipeline$Head
+java.util.stream.ReferencePipeline$StatefulOp
+java.util.stream.ReferencePipeline$StatelessOp
+java.util.stream.Sink
+java.util.stream.Sink$ChainedReference
+java.util.stream.SliceOps
+java.util.stream.SliceOps$1
+java.util.stream.SliceOps$1$1
java.util.stream.Stream
+java.util.stream.StreamOpFlag
+java.util.stream.StreamOpFlag$MaskBuilder
+java.util.stream.StreamOpFlag$Type
+java.util.stream.StreamShape
+java.util.stream.StreamSpliterators$InfiniteSupplyingSpliterator
+java.util.stream.StreamSpliterators$InfiniteSupplyingSpliterator$OfRef
java.util.stream.StreamSupport
+java.util.stream.TerminalOp
+java.util.stream.TerminalSink
java.util.zip.Adler32
java.util.zip.CRC32
java.util.zip.CheckedInputStream
+java.util.zip.CheckedOutputStream
java.util.zip.Checksum
java.util.zip.DataFormatException
java.util.zip.Deflater
java.util.zip.DeflaterOutputStream
java.util.zip.GZIPInputStream
+java.util.zip.GZIPInputStream$1
java.util.zip.GZIPOutputStream
java.util.zip.Inflater
java.util.zip.InflaterInputStream
@@ -7488,13 +7869,15 @@
java.util.zip.ZipCoder
java.util.zip.ZipConstants
java.util.zip.ZipEntry
+java.util.zip.ZipError
java.util.zip.ZipException
java.util.zip.ZipFile
-java.util.zip.ZipFile$1
+java.util.zip.ZipFile$ZipEntryIterator
java.util.zip.ZipFile$ZipFileInflaterInputStream
java.util.zip.ZipFile$ZipFileInputStream
java.util.zip.ZipInputStream
java.util.zip.ZipOutputStream
+java.util.zip.ZipUtils
javax.crypto.BadPaddingException
javax.crypto.Cipher
javax.crypto.Cipher$CipherSpiAndProvider
@@ -7506,7 +7889,6 @@
javax.crypto.CipherInputStream
javax.crypto.CipherOutputStream
javax.crypto.CipherSpi
-javax.crypto.EncryptedPrivateKeyInfo
javax.crypto.IllegalBlockSizeException
javax.crypto.JarVerifier
javax.crypto.JceSecurity
@@ -7518,11 +7900,11 @@
javax.crypto.NoSuchPaddingException
javax.crypto.NullCipher
javax.crypto.SecretKey
-javax.crypto.SecretKeyFactory
javax.crypto.ShortBufferException
+javax.crypto.interfaces.PBEKey
+javax.crypto.spec.GCMParameterSpec
javax.crypto.spec.IvParameterSpec
javax.crypto.spec.OAEPParameterSpec
-javax.crypto.spec.PBEKeySpec
javax.crypto.spec.PBEParameterSpec
javax.crypto.spec.PSource
javax.crypto.spec.PSource$PSpecified
@@ -7546,6 +7928,7 @@
javax.net.ssl.HandshakeCompletedListener
javax.net.ssl.HostnameVerifier
javax.net.ssl.HttpsURLConnection
+javax.net.ssl.HttpsURLConnection$NoPreloadHolder
javax.net.ssl.KeyManager
javax.net.ssl.KeyManagerFactory
javax.net.ssl.KeyManagerFactory$1
@@ -7574,9 +7957,11 @@
javax.net.ssl.X509ExtendedTrustManager
javax.net.ssl.X509KeyManager
javax.net.ssl.X509TrustManager
+javax.security.auth.Destroyable
javax.security.auth.callback.UnsupportedCallbackException
javax.security.auth.x500.X500Principal
javax.security.cert.Certificate
+javax.security.cert.CertificateEncodingException
javax.security.cert.CertificateException
javax.security.cert.X509Certificate
javax.sip.SipException
@@ -7607,8 +7992,6 @@
libcore.icu.TimeZoneNames$ZoneStringsCache
libcore.internal.StringPool
libcore.io.AsynchronousCloseMonitor
-libcore.io.Base64
-libcore.io.Base64$InvalidBase64ByteException
libcore.io.BlockGuardOs
libcore.io.BufferIterator
libcore.io.ClassPathURLStreamHandler
@@ -7622,6 +8005,8 @@
libcore.io.EventLogger$Reporter
libcore.io.ForwardingOs
libcore.io.IoBridge
+libcore.io.IoTracker
+libcore.io.IoTracker$Mode
libcore.io.IoUtils
libcore.io.IoUtils$FileReader
libcore.io.Libcore
@@ -7638,6 +8023,8 @@
libcore.net.UriCodec
libcore.net.event.NetworkEventDispatcher
libcore.net.event.NetworkEventListener
+libcore.net.http.HttpDate
+libcore.net.http.HttpDate$1
libcore.reflect.AnnotatedElements
libcore.reflect.AnnotationFactory
libcore.reflect.AnnotationMember
@@ -7683,21 +8070,16 @@
org.apache.harmony.xml.ExpatParser$ExpatLocator
org.apache.harmony.xml.ExpatReader
org.apache.harmony.xml.dom.AttrImpl
-org.apache.harmony.xml.dom.CDATASectionImpl
org.apache.harmony.xml.dom.CharacterDataImpl
-org.apache.harmony.xml.dom.CommentImpl
org.apache.harmony.xml.dom.DOMImplementationImpl
org.apache.harmony.xml.dom.DocumentImpl
-org.apache.harmony.xml.dom.DocumentTypeImpl
org.apache.harmony.xml.dom.ElementImpl
org.apache.harmony.xml.dom.ElementImpl$ElementAttrNamedNodeMapImpl
-org.apache.harmony.xml.dom.EntityReferenceImpl
org.apache.harmony.xml.dom.InnerNodeImpl
org.apache.harmony.xml.dom.LeafNodeImpl
org.apache.harmony.xml.dom.NodeImpl
org.apache.harmony.xml.dom.NodeImpl$1
org.apache.harmony.xml.dom.NodeListImpl
-org.apache.harmony.xml.dom.ProcessingInstructionImpl
org.apache.harmony.xml.dom.TextImpl
org.apache.harmony.xml.parsers.DocumentBuilderFactoryImpl
org.apache.harmony.xml.parsers.DocumentBuilderImpl
@@ -7736,7 +8118,6 @@
org.apache.http.ReasonPhraseCatalog
org.apache.http.RequestLine
org.apache.http.StatusLine
-org.apache.http.TokenIterator
org.apache.http.auth.AuthSchemeFactory
org.apache.http.auth.AuthSchemeRegistry
org.apache.http.auth.AuthState
@@ -7774,7 +8155,6 @@
org.apache.http.client.utils.URLEncodedUtils
org.apache.http.conn.BasicManagedEntity
org.apache.http.conn.ClientConnectionManager
-org.apache.http.conn.ClientConnectionManagerFactory
org.apache.http.conn.ClientConnectionOperator
org.apache.http.conn.ClientConnectionRequest
org.apache.http.conn.ConnectTimeoutException
@@ -7829,7 +8209,6 @@
org.apache.http.entity.BasicHttpEntity
org.apache.http.entity.ByteArrayEntity
org.apache.http.entity.ContentLengthStrategy
-org.apache.http.entity.FileEntity
org.apache.http.entity.HttpEntityWrapper
org.apache.http.entity.InputStreamEntity
org.apache.http.entity.StringEntity
@@ -7849,7 +8228,6 @@
org.apache.http.impl.client.AbstractHttpClient
org.apache.http.impl.client.BasicCookieStore
org.apache.http.impl.client.BasicCredentialsProvider
-org.apache.http.impl.client.BasicResponseHandler
org.apache.http.impl.client.ClientParamsStack
org.apache.http.impl.client.DefaultConnectionKeepAliveStrategy
org.apache.http.impl.client.DefaultHttpClient
@@ -7860,6 +8238,7 @@
org.apache.http.impl.client.DefaultTargetAuthenticationHandler
org.apache.http.impl.client.DefaultUserTokenHandler
org.apache.http.impl.client.EntityEnclosingRequestWrapper
+org.apache.http.impl.client.RedirectLocations
org.apache.http.impl.client.RequestWrapper
org.apache.http.impl.client.RoutedRequest
org.apache.http.impl.client.TunnelRefusedException
@@ -7872,10 +8251,6 @@
org.apache.http.impl.conn.IdleConnectionHandler
org.apache.http.impl.conn.IdleConnectionHandler$TimeValues
org.apache.http.impl.conn.ProxySelectorRoutePlanner
-org.apache.http.impl.conn.SingleClientConnManager
-org.apache.http.impl.conn.SingleClientConnManager$1
-org.apache.http.impl.conn.SingleClientConnManager$ConnAdapter
-org.apache.http.impl.conn.SingleClientConnManager$PoolEntry
org.apache.http.impl.conn.tsccm.AbstractConnPool
org.apache.http.impl.conn.tsccm.BasicPoolEntry
org.apache.http.impl.conn.tsccm.BasicPoolEntryRef
@@ -7951,7 +8326,6 @@
org.apache.http.message.BasicHeaderElement
org.apache.http.message.BasicHeaderElementIterator
org.apache.http.message.BasicHeaderValueParser
-org.apache.http.message.BasicHttpEntityEnclosingRequest
org.apache.http.message.BasicHttpRequest
org.apache.http.message.BasicHttpResponse
org.apache.http.message.BasicLineFormatter
@@ -7960,7 +8334,6 @@
org.apache.http.message.BasicNameValuePair
org.apache.http.message.BasicRequestLine
org.apache.http.message.BasicStatusLine
-org.apache.http.message.BasicTokenIterator
org.apache.http.message.BufferedHeader
org.apache.http.message.HeaderGroup
org.apache.http.message.HeaderValueParser
@@ -8002,7 +8375,6 @@
org.apache.http.util.EncodingUtils
org.apache.http.util.EntityUtils
org.apache.http.util.LangUtils
-org.apache.http.util.VersionInfo
org.ccil.cowan.tagsoup.AttributesImpl
org.ccil.cowan.tagsoup.AutoDetector
org.ccil.cowan.tagsoup.Element
@@ -8027,16 +8399,12 @@
org.kxml2.io.KXmlParser$ValueContext
org.kxml2.io.KXmlSerializer
org.w3c.dom.Attr
-org.w3c.dom.CDATASection
org.w3c.dom.CharacterData
-org.w3c.dom.Comment
-org.w3c.dom.DOMException
org.w3c.dom.DOMImplementation
org.w3c.dom.Document
org.w3c.dom.DocumentFragment
org.w3c.dom.DocumentType
org.w3c.dom.Element
-org.w3c.dom.EntityReference
org.w3c.dom.NamedNodeMap
org.w3c.dom.Node
org.w3c.dom.NodeList
@@ -8055,9 +8423,6 @@
org.xml.sax.SAXNotSupportedException
org.xml.sax.SAXParseException
org.xml.sax.XMLReader
-org.xml.sax.ext.DeclHandler
-org.xml.sax.ext.DefaultHandler2
-org.xml.sax.ext.EntityResolver2
org.xml.sax.ext.LexicalHandler
org.xml.sax.helpers.AttributesImpl
org.xml.sax.helpers.DefaultHandler
@@ -8065,22 +8430,28 @@
org.xmlpull.v1.XmlPullParserException
org.xmlpull.v1.XmlPullParserFactory
org.xmlpull.v1.XmlSerializer
+sun.invoke.util.BytecodeDescriptor
+sun.invoke.util.Wrapper
sun.misc.ASCIICaseInsensitiveComparator
-sun.misc.BASE64Decoder
-sun.misc.CEStreamExhausted
-sun.misc.CharacterDecoder
sun.misc.Cleaner
sun.misc.CompoundEnumeration
-sun.misc.FDBigInt
+sun.misc.FDBigInteger
+sun.misc.FloatingDecimal
+sun.misc.FloatingDecimal$1
+sun.misc.FloatingDecimal$ASCIIToBinaryBuffer
+sun.misc.FloatingDecimal$ASCIIToBinaryConverter
+sun.misc.FloatingDecimal$BinaryToASCIIBuffer
+sun.misc.FloatingDecimal$BinaryToASCIIConverter
+sun.misc.FloatingDecimal$ExceptionalBinaryToASCIIBuffer
+sun.misc.FloatingDecimal$PreparedASCIIToBinaryBuffer
sun.misc.FormattedFloatingDecimal
sun.misc.FormattedFloatingDecimal$1
sun.misc.FormattedFloatingDecimal$Form
-sun.misc.FpUtils
-sun.misc.Hashing
sun.misc.IOUtils
-sun.misc.IoTrace
+sun.misc.JavaIOFileDescriptorAccess
sun.misc.LRUCache
sun.misc.REException
+sun.misc.SharedSecrets
sun.misc.Unsafe
sun.misc.VM
sun.misc.Version
@@ -8097,17 +8468,13 @@
sun.net.www.ParseUtil
sun.net.www.protocol.file.Handler
sun.net.www.protocol.jar.Handler
-sun.nio.ch.AbstractPollArrayWrapper
-sun.nio.ch.AbstractPollSelectorImpl
-sun.nio.ch.AllocatedNativeObject
sun.nio.ch.ChannelInputStream
sun.nio.ch.DatagramChannelImpl
sun.nio.ch.DatagramDispatcher
-sun.nio.ch.DefaultSelectorProvider
sun.nio.ch.DirectBuffer
+sun.nio.ch.EPollArrayWrapper
sun.nio.ch.FileChannelImpl
sun.nio.ch.FileChannelImpl$Unmapper
-sun.nio.ch.FileDescriptorHolderSocketImpl
sun.nio.ch.FileDispatcher
sun.nio.ch.FileDispatcherImpl
sun.nio.ch.FileKey
@@ -8115,33 +8482,18 @@
sun.nio.ch.FileLockTable
sun.nio.ch.IOStatus
sun.nio.ch.IOUtil
-sun.nio.ch.InheritedChannel
sun.nio.ch.Interruptible
sun.nio.ch.NativeDispatcher
-sun.nio.ch.NativeObject
sun.nio.ch.NativeThread
sun.nio.ch.NativeThreadSet
sun.nio.ch.Net
-sun.nio.ch.Net$1
-sun.nio.ch.PollArrayWrapper
-sun.nio.ch.PollSelectorImpl
-sun.nio.ch.PollSelectorProvider
sun.nio.ch.SelChImpl
-sun.nio.ch.SelectionKeyImpl
-sun.nio.ch.SelectorImpl
-sun.nio.ch.SelectorProviderImpl
sun.nio.ch.ServerSocketChannelImpl
sun.nio.ch.SharedFileLockTable
sun.nio.ch.SharedFileLockTable$FileLockReference
-sun.nio.ch.SocketAdaptor
-sun.nio.ch.SocketAdaptor$1
-sun.nio.ch.SocketAdaptor$2
-sun.nio.ch.SocketAdaptor$SocketInputStream
sun.nio.ch.SocketChannelImpl
-sun.nio.ch.SocketDispatcher
sun.nio.ch.Util
sun.nio.ch.Util$1
-sun.nio.ch.Util$2
sun.nio.ch.Util$BufferCache
sun.nio.cs.ArrayDecoder
sun.nio.cs.ArrayEncoder
@@ -8151,15 +8503,30 @@
sun.nio.cs.ThreadLocalCoders$1
sun.nio.cs.ThreadLocalCoders$2
sun.nio.cs.ThreadLocalCoders$Cache
-sun.reflect.annotation.AnnotationType
+sun.nio.fs.AbstractFileSystemProvider
+sun.nio.fs.AbstractPath
+sun.nio.fs.DefaultFileSystemProvider
+sun.nio.fs.LinuxFileSystem
+sun.nio.fs.LinuxFileSystemProvider
+sun.nio.fs.NativeBuffer
+sun.nio.fs.NativeBuffer$Deallocator
+sun.nio.fs.NativeBuffers
+sun.nio.fs.UnixChannelFactory
+sun.nio.fs.UnixChannelFactory$Flags
+sun.nio.fs.UnixConstants
+sun.nio.fs.UnixException
+sun.nio.fs.UnixFileAttributes
+sun.nio.fs.UnixFileModeAttribute
+sun.nio.fs.UnixFileStoreAttributes
+sun.nio.fs.UnixFileSystem
+sun.nio.fs.UnixFileSystemProvider
+sun.nio.fs.UnixMountEntry
+sun.nio.fs.UnixNativeDispatcher
+sun.nio.fs.UnixPath
+sun.nio.fs.Util
sun.reflect.misc.ReflectUtil
sun.security.action.GetBooleanAction
sun.security.action.GetPropertyAction
-sun.security.ec.ECKeyFactory
-sun.security.ec.ECKeyFactory$1
-sun.security.ec.ECKeyFactory$2
-sun.security.ec.ECParameters
-sun.security.ec.NamedCurve
sun.security.jca.GetInstance
sun.security.jca.GetInstance$Instance
sun.security.jca.JCAUtil
@@ -8175,8 +8542,9 @@
sun.security.jca.ServiceId
sun.security.pkcs.ContentInfo
sun.security.pkcs.PKCS7
+sun.security.pkcs.PKCS7$VerbatimX509Certificate
+sun.security.pkcs.PKCS7$WrappedX509Certificate
sun.security.pkcs.PKCS9Attribute
-sun.security.pkcs.ParsingException
sun.security.pkcs.SignerInfo
sun.security.provider.CertPathProvider
sun.security.provider.X509Factory
@@ -8192,7 +8560,9 @@
sun.security.provider.certpath.PKIXMasterCertPathValidator
sun.security.provider.certpath.PolicyChecker
sun.security.provider.certpath.PolicyNodeImpl
-sun.security.provider.certpath.UntrustedChecker
+sun.security.util.-$Lambda$179$Kli5xKA4dAwmFO1sy_hpNWmbfH4
+sun.security.util.AbstractAlgorithmConstraints
+sun.security.util.AlgorithmDecomposer
sun.security.util.BitArray
sun.security.util.ByteArrayLexOrder
sun.security.util.ByteArrayTagOrder
@@ -8206,7 +8576,6 @@
sun.security.util.DerOutputStream
sun.security.util.DerValue
sun.security.util.DisabledAlgorithmConstraints
-sun.security.util.DisabledAlgorithmConstraints$1
sun.security.util.DisabledAlgorithmConstraints$KeySizeConstraint
sun.security.util.DisabledAlgorithmConstraints$KeySizeConstraint$Operator
sun.security.util.DisabledAlgorithmConstraints$KeySizeConstraints
@@ -8221,9 +8590,7 @@
sun.security.util.MemoryCache$CacheEntry
sun.security.util.MemoryCache$SoftCacheEntry
sun.security.util.ObjectIdentifier
-sun.security.util.SecurityConstants
sun.security.util.SignatureFileVerifier
-sun.security.util.UntrustedCertificates
sun.security.x509.AVA
sun.security.x509.AVAKeyword
sun.security.x509.AccessDescription
@@ -8280,25 +8647,19 @@
sun.security.x509.X509CertImpl
sun.security.x509.X509CertInfo
sun.security.x509.X509Key
-sun.util.LocaleServiceProviderPool
-sun.util.LocaleServiceProviderPool$1
sun.util.calendar.AbstractCalendar
sun.util.calendar.BaseCalendar
sun.util.calendar.BaseCalendar$Date
sun.util.calendar.CalendarDate
sun.util.calendar.CalendarSystem
sun.util.calendar.CalendarUtils
-sun.util.calendar.Era
sun.util.calendar.Gregorian
sun.util.calendar.Gregorian$Date
-sun.util.calendar.ImmutableGregorianDate
sun.util.calendar.JulianCalendar
-sun.util.calendar.JulianCalendar$Date
sun.util.calendar.LocalGregorianCalendar
sun.util.locale.BaseLocale
sun.util.locale.BaseLocale$Cache
sun.util.locale.BaseLocale$Key
-sun.util.locale.Extension
sun.util.locale.InternalLocaleBuilder
sun.util.locale.InternalLocaleBuilder$CaseInsensitiveChar
sun.util.locale.LanguageTag
@@ -8309,11 +8670,9 @@
sun.util.locale.LocaleUtils
sun.util.locale.ParseStatus
sun.util.locale.StringTokenIterator
-sun.util.locale.UnicodeLocaleExtension
sun.util.logging.LoggingProxy
sun.util.logging.LoggingSupport
sun.util.logging.LoggingSupport$1
-sun.util.logging.LoggingSupport$2
sun.util.logging.PlatformLogger
sun.util.logging.PlatformLogger$1
sun.util.logging.PlatformLogger$JavaLoggerProxy
diff --git a/core/java/android/accessibilityservice/AccessibilityButtonController.java b/core/java/android/accessibilityservice/AccessibilityButtonController.java
new file mode 100644
index 0000000..c3a5dab
--- /dev/null
+++ b/core/java/android/accessibilityservice/AccessibilityButtonController.java
@@ -0,0 +1,223 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.accessibilityservice;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.Handler;
+import android.os.RemoteException;
+import android.util.ArrayMap;
+import android.util.Slog;
+
+/**
+ * Controller for the accessibility button within the system's navigation area
+ * <p>
+ * This class may be used to query the accessibility button's state and register
+ * callbacks for interactions with and state changes to the accessibility button when
+ * {@link AccessibilityServiceInfo#FLAG_REQUEST_ACCESSIBILITY_BUTTON} is set.
+ * </p>
+ * <p>
+ * <strong>Note:</strong> This class and
+ * {@link AccessibilityServiceInfo#FLAG_REQUEST_ACCESSIBILITY_BUTTON} should not be used as
+ * the sole means for offering functionality to users via an {@link AccessibilityService}.
+ * Some device implementations may choose not to provide a software-rendered system
+ * navigation area, making this affordance permanently unavailable.
+ * </p>
+ * <p>
+ * <strong>Note:</strong> On device implementations where the accessibility button is
+ * supported, it may not be available at all times, such as when a foreground application uses
+ * {@link android.view.View#SYSTEM_UI_FLAG_HIDE_NAVIGATION}. A user may also choose to assign
+ * this button to another accessibility service or feature. In each of these cases, a
+ * registered {@link AccessibilityButtonCallback}'s
+ * {@link AccessibilityButtonCallback#onAvailabilityChanged(AccessibilityButtonController, boolean)}
+ * method will be invoked to provide notifications of changes in the accessibility button's
+ * availability to the registering service.
+ * </p>
+ */
+public final class AccessibilityButtonController {
+ private static final String LOG_TAG = "A11yButtonController";
+
+ private final IAccessibilityServiceConnection mServiceConnection;
+ private final Object mLock;
+ private ArrayMap<AccessibilityButtonCallback, Handler> mCallbacks;
+
+ AccessibilityButtonController(@NonNull IAccessibilityServiceConnection serviceConnection) {
+ mServiceConnection = serviceConnection;
+ mLock = new Object();
+ }
+
+ /**
+ * Retrieves whether the accessibility button in the system's navigation area is
+ * available to the calling service.
+ * <p>
+ * <strong>Note:</strong> If the service is not yet connected (e.g.
+ * {@link AccessibilityService#onServiceConnected()} has not yet been called) or the
+ * service has been disconnected, this method will have no effect and return {@code false}.
+ * </p>
+ *
+ * @return {@code true} if the accessibility button in the system's navigation area is
+ * available to the calling service, {@code false} otherwise
+ */
+ public boolean isAccessibilityButtonAvailable() {
+ try {
+ return mServiceConnection.isAccessibilityButtonAvailable();
+ } catch (RemoteException re) {
+ Slog.w(LOG_TAG, "Failed to get accessibility button availability.", re);
+ re.rethrowFromSystemServer();
+ return false;
+ }
+ }
+
+ /**
+ * Registers the provided {@link AccessibilityButtonCallback} for interaction and state
+ * changes callbacks related to the accessibility button.
+ *
+ * @param callback the callback to add, must be non-null
+ */
+ public void registerAccessibilityButtonCallback(@NonNull AccessibilityButtonCallback callback) {
+ registerAccessibilityButtonCallback(callback, null);
+ }
+
+ /**
+ * Registers the provided {@link AccessibilityButtonCallback} for interaction and state
+ * change callbacks related to the accessibility button. The callback will occur on the
+ * specified {@link Handler}'s thread, or on the services's main thread if the handler is
+ * {@code null}.
+ *
+ * @param callback the callback to add, must be non-null
+ * @param handler the handler on which to callback should execute, or {@code null} to
+ * execute on the service's main thread
+ */
+ public void registerAccessibilityButtonCallback(@NonNull AccessibilityButtonCallback callback,
+ @Nullable Handler handler) {
+ synchronized (mLock) {
+ if (mCallbacks == null) {
+ mCallbacks = new ArrayMap<>();
+ }
+
+ mCallbacks.put(callback, handler);
+ }
+ }
+
+ /**
+ * Unregisters the provided {@link AccessibilityButtonCallback} for interaction and state
+ * change callbacks related to the accessibility button.
+ *
+ * @param callback the callback to remove, must be non-null
+ */
+ public void unregisterAccessibilityButtonCallback(
+ @NonNull AccessibilityButtonCallback callback) {
+ synchronized (mLock) {
+ if (mCallbacks == null) {
+ return;
+ }
+
+ final int keyIndex = mCallbacks.indexOfKey(callback);
+ final boolean hasKey = keyIndex >= 0;
+ if (hasKey) {
+ mCallbacks.removeAt(keyIndex);
+ }
+ }
+ }
+
+ /**
+ * Dispatches the accessibility button click to any registered callbacks. This should
+ * be called on the service's main thread.
+ */
+ void dispatchAccessibilityButtonClicked() {
+ final ArrayMap<AccessibilityButtonCallback, Handler> entries;
+ synchronized (mLock) {
+ if (mCallbacks == null || mCallbacks.isEmpty()) {
+ Slog.w(LOG_TAG, "Received accessibility button click with no callbacks!");
+ return;
+ }
+
+ // Callbacks may remove themselves. Perform a shallow copy to avoid concurrent
+ // modification.
+ entries = new ArrayMap<>(mCallbacks);
+ }
+
+ for (int i = 0, count = entries.size(); i < count; i++) {
+ final AccessibilityButtonCallback callback = entries.keyAt(i);
+ final Handler handler = entries.valueAt(i);
+ if (handler != null) {
+ handler.post(() -> callback.onClicked(this));
+ } else {
+ // We're already on the main thread, just run the callback.
+ callback.onClicked(this);
+ }
+ }
+ }
+
+ /**
+ * Dispatches the accessibility button availability changes to any registered callbacks.
+ * This should be called on the service's main thread.
+ */
+ void dispatchAccessibilityButtonAvailabilityChanged(boolean available) {
+ final ArrayMap<AccessibilityButtonCallback, Handler> entries;
+ synchronized (mLock) {
+ if (mCallbacks == null || mCallbacks.isEmpty()) {
+ Slog.w(LOG_TAG,
+ "Received accessibility button availability change with no callbacks!");
+ return;
+ }
+
+ // Callbacks may remove themselves. Perform a shallow copy to avoid concurrent
+ // modification.
+ entries = new ArrayMap<>(mCallbacks);
+ }
+
+ for (int i = 0, count = entries.size(); i < count; i++) {
+ final AccessibilityButtonCallback callback = entries.keyAt(i);
+ final Handler handler = entries.valueAt(i);
+ if (handler != null) {
+ handler.post(() -> callback.onAvailabilityChanged(this, available));
+ } else {
+ // We're already on the main thread, just run the callback.
+ callback.onAvailabilityChanged(this, available);
+ }
+ }
+ }
+
+ /**
+ * Callback for interaction with and changes to state of the accessibility button
+ * within the system's navigation area.
+ */
+ public static abstract class AccessibilityButtonCallback {
+
+ /**
+ * Called when the accessibility button in the system's navigation area is clicked.
+ *
+ * @param controller the controller used to register for this callback
+ */
+ public void onClicked(AccessibilityButtonController controller) {}
+
+ /**
+ * Called when the availability of the accessibility button in the system's
+ * navigation area has changed. The accessibility button may become unavailable
+ * because the device shopped showing the button, the button was assigned to another
+ * service, or for other reasons.
+ *
+ * @param controller the controller used to register for this callback
+ * @param available {@code true} if the accessibility button is available to this
+ * service, {@code false} otherwise
+ */
+ public void onAvailabilityChanged(AccessibilityButtonController controller,
+ boolean available) {
+ }
+ }
+}
diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java
index a036b6a..9e486d5 100644
--- a/core/java/android/accessibilityservice/AccessibilityService.java
+++ b/core/java/android/accessibilityservice/AccessibilityService.java
@@ -378,6 +378,8 @@
void onPerformGestureResult(int sequence, boolean completedSuccessfully);
void onFingerprintCapturingGesturesChanged(boolean active);
void onFingerprintGesture(int gesture);
+ void onAccessibilityButtonClicked();
+ void onAccessibilityButtonAvailabilityChanged(boolean available);
}
/**
@@ -400,6 +402,7 @@
private MagnificationController mMagnificationController;
private SoftKeyboardController mSoftKeyboardController;
+ private AccessibilityButtonController mAccessibilityButtonController;
private int mGestureStatusCallbackSequence;
@@ -431,6 +434,9 @@
if (mMagnificationController != null) {
mMagnificationController.onServiceConnected();
}
+ if (mSoftKeyboardController != null) {
+ mSoftKeyboardController.onServiceConnected();
+ }
// The client gets to handle service connection last, after we've set
// up any state upon which their code may rely.
@@ -809,12 +815,10 @@
}
/**
- * Removes all instances of the specified change listener from the list
- * of magnification change listeners.
+ * Removes the specified change listener from the list of magnification change listeners.
*
* @param listener the listener to remove, must be non-null
- * @return {@code true} if at least one instance of the listener was
- * removed
+ * @return {@code true} if the listener was removed, {@code false} otherwise
*/
public boolean removeListener(@NonNull OnMagnificationChangedListener listener) {
if (mListeners == null) {
@@ -1203,11 +1207,11 @@
}
/**
- * Removes all instances of the specified change listener from the list of magnification
- * change listeners.
+ * Removes the specified change listener from the list of keyboard show mode change
+ * listeners.
*
* @param listener the listener to remove, must be non-null
- * @return {@code true} if at least one instance of the listener was removed
+ * @return {@code true} if the listener was removed, {@code false} otherwise
*/
public boolean removeOnShowModeChangedListener(@NonNull OnShowModeChangedListener listener) {
if (mListeners == null) {
@@ -1252,7 +1256,7 @@
final ArrayMap<OnShowModeChangedListener, Handler> entries;
synchronized (mLock) {
if (mListeners == null || mListeners.isEmpty()) {
- Slog.d(LOG_TAG, "Received soft keyboard show mode changed callback"
+ Slog.w(LOG_TAG, "Received soft keyboard show mode changed callback"
+ " with no listeners registered!");
setSoftKeyboardCallbackEnabled(false);
return;
@@ -1308,9 +1312,9 @@
* The lastto this method will be honored, regardless of any previous calls (including those
* made by other AccessibilityServices).
* <p>
- * <strong>Note:</strong> If the service is not yet conected (e.g.
+ * <strong>Note:</strong> If the service is not yet connected (e.g.
* {@link AccessibilityService#onServiceConnected()} has not yet been called) or the
- * service has been disconnected, this method will hav no effect and return {@code false}.
+ * service has been disconnected, this method will have no effect and return {@code false}.
*
* @param showMode the new show mode for the soft keyboard
* @return {@code true} on success
@@ -1349,6 +1353,39 @@
}
/**
+ * Returns the controller for the accessibility button within the system's navigation area.
+ * This instance may be used to query the accessibility button's state and register listeners
+ * for interactions with and state changes for the accessibility button when
+ * {@link AccessibilityServiceInfo#FLAG_REQUEST_ACCESSIBILITY_BUTTON} is set.
+ * <p>
+ * <strong>Note:</strong> Not all devices are capable of displaying the accessibility button
+ * within a navigation area, and as such, use of this class should be considered only as an
+ * optional feature or shortcut on supported device implementations.
+ * </p>
+ *
+ * @return the accessibility button controller for this {@link AccessibilityService}
+ */
+ @NonNull
+ public final AccessibilityButtonController getAccessibilityButtonController() {
+ synchronized (mLock) {
+ if (mAccessibilityButtonController == null) {
+ mAccessibilityButtonController = new AccessibilityButtonController(
+ AccessibilityInteractionClient.getInstance().getConnection(mConnectionId));
+ }
+ return mAccessibilityButtonController;
+ }
+ }
+
+ private void onAccessibilityButtonClicked() {
+ getAccessibilityButtonController().dispatchAccessibilityButtonClicked();
+ }
+
+ private void onAccessibilityButtonAvailabilityChanged(boolean available) {
+ getAccessibilityButtonController().dispatchAccessibilityButtonAvailabilityChanged(
+ available);
+ }
+
+ /**
* Performs a global action. Such an action can be performed
* at any moment regardless of the current application or user
* location in that application. For example going back, going
@@ -1543,6 +1580,16 @@
public void onFingerprintGesture(int gesture) {
AccessibilityService.this.onFingerprintGesture(gesture);
}
+
+ @Override
+ public void onAccessibilityButtonClicked() {
+ AccessibilityService.this.onAccessibilityButtonClicked();
+ }
+
+ @Override
+ public void onAccessibilityButtonAvailabilityChanged(boolean available) {
+ AccessibilityService.this.onAccessibilityButtonAvailabilityChanged(available);
+ }
});
}
@@ -1565,6 +1612,8 @@
private static final int DO_GESTURE_COMPLETE = 9;
private static final int DO_ON_FINGERPRINT_ACTIVE_CHANGED = 10;
private static final int DO_ON_FINGERPRINT_GESTURE = 11;
+ private static final int DO_ACCESSIBILITY_BUTTON_CLICKED = 12;
+ private static final int DO_ACCESSIBILITY_BUTTON_AVAILABILITY_CHANGED = 13;
private final HandlerCaller mCaller;
@@ -1645,6 +1694,17 @@
mCaller.sendMessage(mCaller.obtainMessageI(DO_ON_FINGERPRINT_GESTURE, gesture));
}
+ public void onAccessibilityButtonClicked() {
+ final Message message = mCaller.obtainMessage(DO_ACCESSIBILITY_BUTTON_CLICKED);
+ mCaller.sendMessage(message);
+ }
+
+ public void onAccessibilityButtonAvailabilityChanged(boolean available) {
+ final Message message = mCaller.obtainMessageI(
+ DO_ACCESSIBILITY_BUTTON_AVAILABILITY_CHANGED, (available ? 1 : 0));
+ mCaller.sendMessage(message);
+ }
+
@Override
public void executeMessage(Message message) {
switch (message.what) {
@@ -1750,6 +1810,15 @@
mCallback.onFingerprintGesture(message.arg1);
} return;
+ case (DO_ACCESSIBILITY_BUTTON_CLICKED): {
+ mCallback.onAccessibilityButtonClicked();
+ } return;
+
+ case (DO_ACCESSIBILITY_BUTTON_AVAILABILITY_CHANGED): {
+ final boolean available = (message.arg1 != 0);
+ mCallback.onAccessibilityButtonAvailabilityChanged(available);
+ } return;
+
default :
Log.w(LOG_TAG, "Unknown message type " + message.what);
}
diff --git a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
index 18e57cb..e135ffd 100644
--- a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
+++ b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
@@ -306,6 +306,12 @@
*/
public static final int FLAG_ENABLE_ACCESSIBILITY_VOLUME = 0x00000080;
+ /**
+ * This flag indicates to the system that the accessibility service requests that an
+ * accessibility button be shown within the system's navigation area, if available.
+ */
+ public static final int FLAG_REQUEST_ACCESSIBILITY_BUTTON = 0x00000100;
+
/**
* This flag requests that all fingerprint gestures be sent to the accessibility service.
* It is handled in {@link FingerprintGestureController}
@@ -396,6 +402,8 @@
* @see #FLAG_REQUEST_FILTER_KEY_EVENTS
* @see #FLAG_REPORT_VIEW_IDS
* @see #FLAG_RETRIEVE_INTERACTIVE_WINDOWS
+ * @see #FLAG_ENABLE_ACCESSIBILITY_VOLUME
+ * @see #FLAG_REQUEST_ACCESSIBILITY_BUTTON
*/
public int flags;
@@ -631,7 +639,7 @@
* @see #CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT
* @see #CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION
* @see #CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY
- * @see #CAPABILITY_FILTER_KEY_EVENTS
+ * @see #CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS
* @see #CAPABILITY_CAN_CONTROL_MAGNIFICATION
* @see #CAPABILITY_CAN_PERFORM_GESTURES
*/
@@ -648,7 +656,7 @@
* @see #CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT
* @see #CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION
* @see #CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY
- * @see #CAPABILITY_FILTER_KEY_EVENTS
+ * @see #CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS
* @see #CAPABILITY_CAN_CONTROL_MAGNIFICATION
* @see #CAPABILITY_CAN_PERFORM_GESTURES
*
@@ -936,6 +944,8 @@
return "FLAG_RETRIEVE_INTERACTIVE_WINDOWS";
case FLAG_ENABLE_ACCESSIBILITY_VOLUME:
return "FLAG_ENABLE_ACCESSIBILITY_VOLUME";
+ case FLAG_REQUEST_ACCESSIBILITY_BUTTON:
+ return "FLAG_REQUEST_ACCESSIBILITY_BUTTON";
case FLAG_CAPTURE_FINGERPRINT_GESTURES:
return "FLAG_CAPTURE_FINGERPRINT_GESTURES";
default:
@@ -960,7 +970,7 @@
case CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY:
return "CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY";
case CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS:
- return "CAPABILITY_CAN_FILTER_KEY_EVENTS";
+ return "CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS";
case CAPABILITY_CAN_CONTROL_MAGNIFICATION:
return "CAPABILITY_CAN_CONTROL_MAGNIFICATION";
case CAPABILITY_CAN_PERFORM_GESTURES:
diff --git a/core/java/android/accessibilityservice/IAccessibilityServiceClient.aidl b/core/java/android/accessibilityservice/IAccessibilityServiceClient.aidl
index 3f778ad..4e96b8f 100644
--- a/core/java/android/accessibilityservice/IAccessibilityServiceClient.aidl
+++ b/core/java/android/accessibilityservice/IAccessibilityServiceClient.aidl
@@ -50,4 +50,8 @@
void onFingerprintCapturingGesturesChanged(boolean capturing);
void onFingerprintGesture(int gesture);
+
+ void onAccessibilityButtonClicked();
+
+ void onAccessibilityButtonAvailabilityChanged(boolean available);
}
diff --git a/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl b/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
index 7dab222..7a1931718 100644
--- a/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
+++ b/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
@@ -89,6 +89,8 @@
void setSoftKeyboardCallbackEnabled(boolean enabled);
+ boolean isAccessibilityButtonAvailable();
+
void sendGesture(int sequence, in ParceledListSlice gestureSteps);
boolean isFingerprintGestureDetectionAvailable();
diff --git a/core/java/android/accounts/AccountManager.java b/core/java/android/accounts/AccountManager.java
index def0ff9..0263681 100644
--- a/core/java/android/accounts/AccountManager.java
+++ b/core/java/android/accounts/AccountManager.java
@@ -338,21 +338,24 @@
"android.accounts.LOGIN_ACCOUNTS_CHANGED";
/**
- * Uid key to set default visibility for applications targeting API level
+ * Key to set default visibility for applications targeting API level
* {@link android.os.Build.VERSION_CODES#O} or above and don't have the same signature as
* authenticator See {@link #getAccountVisibility}. If the value was not set by authenticator
- * USER_MANAGED_NOT_VISIBLE is used.
+ * {@link #VISIBILITY_USER_MANAGED_NOT_VISIBLE} is used.
*/
- public static final int UID_KEY_DEFAULT_VISIBILITY = -2;
+ public static final String PACKAGE_NAME_KEY_LEGACY_VISIBLE =
+ "android.accounts.key_legacy_visible";
/**
- * Uid key to set visibility for applications targeting API level below
- * {@link android.os.Build.VERSION_CODES#O} with GET_ACCOUNS permission, or applications with
- * any targeting API level with the same signature as authenticator. See
- * {@link #getAccountVisibility}. If the value was not set by authenticator USER_MANAGED_VISIBLE
- * is used.
+ * Key to set visibility for applications targeting API level below
+ * {@link android.os.Build.VERSION_CODES#O} with
+ * {@link android.Manifest.permission#GET_ACCOUNTS} permission, or applications with any
+ * targeting API level with the same signature as authenticator. See
+ * {@link #getAccountVisibility}. If the value was not set by authenticator
+ * {@link #VISIBILITY_USER_MANAGED_VISIBLE} is used.
*/
- public static final int UID_KEY_DEFAULT_LEGACY_VISIBILITY = -3;
+ public static final String PACKAGE_NAME_KEY_LEGACY_NOT_VISIBLE =
+ "android.accounts.key_legacy_not_visible";
/**
* @hide
@@ -565,12 +568,14 @@
}
/**
- * Returns the accounts visible to the specified package, in an environment where some apps
- * are not authorized to view all accounts. This method can only be called by system apps.
+ * Returns the accounts visible to the specified package, in an environment where some apps are
+ * not authorized to view all accounts. This method can only be called by system apps and
+ * authenticators managing the type
+ *
* @param type The type of accounts to return, null to retrieve all accounts
* @param packageName The package name of the app for which the accounts are to be returned
- * @return An array of {@link Account}, one per matching account. Empty
- * (never null) if no accounts of the specified type have been added.
+ * @return An array of {@link Account}, one per matching account. Empty (never null) if no
+ * accounts of the specified type have been added.
*/
@NonNull
public Account[] getAccountsByTypeForPackage(String type, String packageName) {
@@ -609,7 +614,8 @@
*
* <p>
* <b>NOTE:</b> If targeting your app to work on API level
- * {@link android.os.Build.VERSION_CODES#LOLLIPOP_MR1} and before, GET_ACCOUNTS permission is
+ * {@link android.os.Build.VERSION_CODES#LOLLIPOP_MR1} and before,
+ * {@link android.Manifest.permission#GET_ACCOUNTS} permission is
* needed for those platforms, irrespective of uid or signature match. See docs for this
* function in API level {@link android.os.Build.VERSION_CODES#LOLLIPOP_MR1}.
*
@@ -750,7 +756,8 @@
* accounts managed by AbstractAccountAuthenticators whose signature matches the client.
* <p>
* <b>NOTE:</b> If targeting your app to work on API level
- * {@link android.os.Build.VERSION_CODES#LOLLIPOP_MR1} and before, GET_ACCOUNTS permission is
+ * {@link android.os.Build.VERSION_CODES#LOLLIPOP_MR1} and before,
+ * {@link android.Manifest.permission#GET_ACCOUNTS} permission is
* needed for those platforms, irrespective of uid or signature match. See docs for this
* function in API level {@link android.os.Build.VERSION_CODES#LOLLIPOP_MR1}.
*
@@ -822,9 +829,8 @@
}
/**
- * Adds an account directly to the AccountManager. Additionally this makes the Account visible
- * to desired UIDs of applications on the device, and sends directed broadcasts to these
- * individual applications.
+ * Adds an account directly to the AccountManager. Additionally it specifies Account visiblity
+ * for given list of packages.
* <p>
* Normally used by sign-up wizards associated with authenticators, not directly by
* applications.
@@ -841,14 +847,14 @@
* @param account The {@link Account} to add
* @param password The password to associate with the account, null for none
* @param extras String values to use for the account's userdata, null for none
- * @param visibility Map from uid to visibility values which will be set before account is
- * added. See getAccountVisibility for possilbe values.
+ * @param visibility Map from packageName to visibility values which will be set before account
+ * is added. See {@link #getAccountVisibility} for possible values.
*
* @return True if the account was successfully added, false if the account already exists, the
* account is null, or another error occurs.
*/
public boolean addAccountExplicitly(Account account, String password, Bundle extras,
- Map<Integer, Integer> visibility) {
+ Map<String, Integer> visibility) {
if (account == null)
throw new IllegalArgumentException("account is null");
try {
@@ -860,20 +866,22 @@
}
/**
- * Returns UIDs of applications for which visibility of given account was explicitly set.
+ * Returns package names and visibility which were explicitly set for given account.
* <p>
* This method requires the caller to have a signature match with the authenticator that owns
* the specified account.
*
* @param account The account for which visibility data should be returned.
*
- * @return Map from uid to visibility for given account.
+ * @return Map from package names to visibility for given account.
*/
- public Map<Integer, Integer> getUidsAndVisibilityForAccount(Account account) {
+ public Map<String, Integer> getPackagesAndVisibilityForAccount(Account account) {
try {
+ if (account == null)
+ throw new IllegalArgumentException("account is null");
@SuppressWarnings("unchecked")
- Map<Integer, Integer> result = (Map<Integer, Integer>) mService
- .getUidsAndVisibilityForAccount(account);
+ Map<String, Integer> result = (Map<String, Integer>) mService
+ .getPackagesAndVisibilityForAccount(account);
return result;
} catch (RemoteException re) {
throw re.rethrowFromSystemServer();
@@ -907,30 +915,34 @@
}
/**
- * Set visibility value of given account to certain UID.
+ * Set visibility value of given account to certain packageName.
+ * Package name must match installed application, or be equal to
+ * {@link #PACKAGE_NAME_KEY_LEGACY_VISIBLE} or {@link #PACKAGE_NAME_KEY_LEGACY_NOT_VISIBLE}.
* <p>
* See {@link #getAccountVisibility} for possible values.
* <p>
* This method requires the caller to have a signature match with the authenticator that owns
* the specified account.
*
- * @param account Account to make visible.
- * @param uid The UID of the application to modify account visibility.
+ * @param account Account to update visibility
+ * @param packageName Package name of the application to modify account visibility.
* @param visibility - new visibility value.
*
* @return True if visibility value was succesfully updated.
*/
- public boolean setAccountVisibility(Account account, int uid,
+ public boolean setAccountVisibility(Account account, String packageName,
@AccountVisibility int visibility) {
+ if (account == null)
+ throw new IllegalArgumentException("account is null");
try {
- return mService.setAccountVisibility(account, uid, visibility);
+ return mService.setAccountVisibility(account, packageName, visibility);
} catch (RemoteException re) {
throw re.rethrowFromSystemServer();
}
}
/**
- * Gets visibility of certain account for given UID. Possible returned values are:
+ * Get visibility of certain account for given application. Possible returned values are:
* <ul>
* <li>{@link #VISIBILITY_UNDEFINED}</li>
* <li>{@link #VISIBILITY_VISIBLE}</li>
@@ -944,13 +956,15 @@
* the specified account.
*
* @param account Account to get visibility.
- * @param uid The UID of the application to get account visibility.
+ * @param packageName Package name of the application to get account visibility
*
- * @return int Visibility for given account and uid.
+ * @return int Visibility for given account and package.
*/
- public @AccountVisibility int getAccountVisibility(Account account, int uid) {
+ public @AccountVisibility int getAccountVisibility(Account account, String packageName) {
+ if (account == null)
+ throw new IllegalArgumentException("account is null");
try {
- return mService.getAccountVisibility(account, uid);
+ return mService.getAccountVisibility(account, packageName);
} catch (RemoteException re) {
throw re.rethrowFromSystemServer();
}
diff --git a/core/java/android/accounts/ChooseTypeAndAccountActivity.java b/core/java/android/accounts/ChooseTypeAndAccountActivity.java
index 95fdfef..35011b5 100644
--- a/core/java/android/accounts/ChooseTypeAndAccountActivity.java
+++ b/core/java/android/accounts/ChooseTypeAndAccountActivity.java
@@ -437,7 +437,7 @@
}
if (oldVisibility != null
&& oldVisibility == AccountManager.VISIBILITY_USER_MANAGED_NOT_VISIBLE) {
- AccountManager.get(this).setAccountVisibility(account, mCallingUid,
+ AccountManager.get(this).setAccountVisibility(account, mCallingPackage,
AccountManager.VISIBILITY_USER_MANAGED_VISIBLE);
}
Bundle bundle = new Bundle();
diff --git a/core/java/android/accounts/IAccountManager.aidl b/core/java/android/accounts/IAccountManager.aidl
index 63a0919..e0fdac1 100644
--- a/core/java/android/accounts/IAccountManager.aidl
+++ b/core/java/android/accounts/IAccountManager.aidl
@@ -108,15 +108,12 @@
void isCredentialsUpdateSuggested(in IAccountManagerResponse response, in Account account,
String statusToken);
- /* Returns Map<Integer, Integer> from UID to visibility with all values stored for given account*/
- Map getUidsAndVisibilityForAccount(in Account account);
-
+ /* Returns Map<String, Integer> from package name to visibility with all values stored for given account */
+ Map getPackagesAndVisibilityForAccount(in Account account);
boolean addAccountExplicitlyWithVisibility(in Account account, String password, in Bundle extras,
in Map visibility);
-
- boolean setAccountVisibility(in Account a, int uid, int newVisibility);
- int getAccountVisibility(in Account a, int uid);
-
+ boolean setAccountVisibility(in Account a, in String packageName, int newVisibility);
+ int getAccountVisibility(in Account a, in String packageName);
/* Type may be null returns Map <Account, Integer>*/
Map getAccountsAndVisibilityForPackage(in String packageName, in String accountType);
diff --git a/core/java/android/animation/ValueAnimator.java b/core/java/android/animation/ValueAnimator.java
index 55ac1f4..558fdc6 100644
--- a/core/java/android/animation/ValueAnimator.java
+++ b/core/java/android/animation/ValueAnimator.java
@@ -637,13 +637,16 @@
public void setCurrentFraction(float fraction) {
initAnimation();
fraction = clampFraction(fraction);
- long seekTime = (long) (getScaledDuration() * fraction);
- long currentTime = AnimationUtils.currentAnimationTimeMillis();
- mStartTime = currentTime - seekTime;
mStartTimeCommitted = true; // do not allow start time to be compensated for jank
- if (!isPulsingInternal()) {
- // If the animation loop hasn't started, the startTime will be adjusted in the first
- // frame based on seek fraction.
+ if (isPulsingInternal()) {
+ long seekTime = (long) (getScaledDuration() * fraction);
+ long currentTime = AnimationUtils.currentAnimationTimeMillis();
+ // Only modify the start time when the animation is running. Seek fraction will ensure
+ // non-running animations skip to the correct start time.
+ mStartTime = currentTime - seekTime;
+ } else {
+ // If the animation loop hasn't started, or during start delay, the startTime will be
+ // adjusted once the delay has passed based on seek fraction.
mSeekFraction = fraction;
}
mOverallFraction = fraction;
@@ -1028,7 +1031,7 @@
// started-but-not-yet-reached-the-first-frame phase.
mLastFrameTime = -1;
mFirstFrameTime = -1;
- addAnimationCallback((long) (mStartDelay * sDurationScale));
+ addAnimationCallback(0);
if (mStartDelay == 0 || mSeekFraction >= 0 || mReversing) {
// If there's no start delay, init the animation and notify start listeners right away
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 0ac30de..6a1e74e 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -49,7 +49,6 @@
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.pm.ParceledListSlice;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.content.res.TypedArray;
@@ -74,8 +73,6 @@
import android.os.StrictMode;
import android.os.SystemProperties;
import android.os.UserHandle;
-import android.service.autofill.AutoFillService;
-import android.service.autofill.IAutoFillAppCallback;
import android.text.Selection;
import android.text.SpannableStringBuilder;
import android.text.TextUtils;
@@ -116,7 +113,6 @@
import android.view.WindowManager;
import android.view.WindowManagerGlobal;
import android.view.accessibility.AccessibilityEvent;
-import android.view.autofill.AutoFillId;
import android.view.autofill.AutoFillManager;
import android.view.autofill.AutoFillSession;
import android.widget.AdapterView;
@@ -127,7 +123,6 @@
import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
-import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -969,9 +964,7 @@
? mLastNonConfigurationInstances.fragments : null);
}
mFragments.dispatchCreate();
- if (!isAtLeastO()) {
- getApplication().dispatchActivityCreated(this, savedInstanceState);
- }
+ getApplication().dispatchActivityCreated(this, savedInstanceState);
if (mVoiceInteractor != null) {
mVoiceInteractor.attachActivity(this);
}
@@ -1199,9 +1192,8 @@
mCalled = true;
mFragments.doLoaderStart();
- if (!isAtLeastO()) {
- getApplication().dispatchActivityStarted(this);
- }
+
+ getApplication().dispatchActivityStarted(this);
}
/**
@@ -1262,9 +1254,7 @@
@CallSuper
protected void onResume() {
if (DEBUG_LIFECYCLE) Slog.v(TAG, "onResume " + this);
- if (!isAtLeastO()) {
- getApplication().dispatchActivityResumed(this);
- }
+ getApplication().dispatchActivityResumed(this);
mActivityTransitionState.onResume(this, isTopOfTask());
mCalled = true;
}
@@ -1431,9 +1421,6 @@
saveManagedDialogs(outState);
mActivityTransitionState.saveState(outState);
storeHasCurrentPermissionRequest(outState);
- if (isAtLeastO()) {
- getApplication().dispatchActivitySaveInstanceState(this, outState);
- }
if (DEBUG_LIFECYCLE) Slog.v(TAG, "onSaveInstanceState " + this + ": " + outState);
}
@@ -1450,9 +1437,6 @@
onSaveInstanceState(outState, outPersistentState);
saveManagedDialogs(outState);
storeHasCurrentPermissionRequest(outState);
- if (isAtLeastO()) {
- getApplication().dispatchActivitySaveInstanceState(this, outState);
- }
if (DEBUG_LIFECYCLE) Slog.v(TAG, "onSaveInstanceState " + this + ": " + outState +
", " + outPersistentState);
}
@@ -1508,9 +1492,7 @@
if (p != null) {
outState.putParcelable(FRAGMENTS_TAG, p);
}
- if (!isAtLeastO()) {
- getApplication().dispatchActivitySaveInstanceState(this, outState);
- }
+ getApplication().dispatchActivitySaveInstanceState(this, outState);
}
/**
@@ -1608,9 +1590,7 @@
@CallSuper
protected void onPause() {
if (DEBUG_LIFECYCLE) Slog.v(TAG, "onPause " + this);
- if (!isAtLeastO()) {
- getApplication().dispatchActivityPaused(this);
- }
+ getApplication().dispatchActivityPaused(this);
mCalled = true;
}
@@ -1715,16 +1695,21 @@
}
/**
- * Lazily gets the {@link IAutoFillAppCallback} for this activitity.
- *
- * <p>This callback is used by the {@link AutoFillService} app to auto-fill the activity fields.
+ * Lazily attachs the activity to the current {@link AutoFillSession} (if any).
*/
- IAutoFillAppCallback getAutoFillCallback() {
+ void attachToAutoFillSession() {
synchronized (this) {
if (mAutoFillSession == null) {
- mAutoFillSession = new AutoFillSession(this);
+ final AutoFillManager afm = getSystemService(AutoFillManager.class);
+ if (afm != null) {
+ mAutoFillSession = afm.getSession();
+ if (mAutoFillSession != null) {
+ mAutoFillSession.attachActivity(this);
+ } else {
+ Log.w(TAG, "attachToAutoFillSession(): not in a session");
+ }
+ }
}
- return mAutoFillSession.getCallback();
}
}
@@ -1810,11 +1795,13 @@
if (DEBUG_LIFECYCLE) Slog.v(TAG, "onStop " + this);
if (mActionBar != null) mActionBar.setShowHideAnimationEnabled(false);
mActivityTransitionState.onStop();
- if (!isAtLeastO()) {
- getApplication().dispatchActivityStopped(this);
- }
+ getApplication().dispatchActivityStopped(this);
mTranslucentCallback = null;
mCalled = true;
+ if (mAutoFillSession != null && isFinishing()) {
+ mAutoFillSession.finishSession();
+ mAutoFillSession = null;
+ }
}
/**
@@ -1882,9 +1869,8 @@
if (mActionBar != null) {
mActionBar.onDestroy();
}
- if (!isAtLeastO()) {
- getApplication().dispatchActivityDestroyed(this);
- }
+
+ getApplication().dispatchActivityDestroyed(this);
}
/**
@@ -6768,33 +6754,25 @@
return mParent != null ? mParent.getActivityToken() : mToken;
}
- final void performCreateCommon(Bundle icicle) {
- mActivityTransitionState.readState(icicle);
+ final void performCreateCommon() {
mVisibleFromClient = !mWindow.getWindowStyle().getBoolean(
com.android.internal.R.styleable.Window_windowNoDisplay, false);
mFragments.dispatchActivityCreated();
mActivityTransitionState.setEnterActivityOptions(this, getActivityOptions());
- if (isAtLeastO()) {
- getApplication().dispatchActivityCreated(this, icicle);
- }
}
final void performCreate(Bundle icicle) {
restoreHasCurrentPermissionRequest(icicle);
- if (isAtLeastO()) {
- getApplication().dispatchActivityPreCreated(this, icicle);
- }
onCreate(icicle);
- performCreateCommon(icicle);
+ mActivityTransitionState.readState(icicle);
+ performCreateCommon();
}
final void performCreate(Bundle icicle, PersistableBundle persistentState) {
restoreHasCurrentPermissionRequest(icicle);
- if (isAtLeastO()) {
- getApplication().dispatchActivityPreCreated(this, icicle);
- }
onCreate(icicle, persistentState);
- performCreateCommon(icicle);
+ mActivityTransitionState.readState(icicle);
+ performCreateCommon();
}
final void performStart() {
@@ -6837,9 +6815,6 @@
}
mActivityTransitionState.enterReady(this);
- if (isAtLeastO()) {
- getApplication().dispatchActivityStarted(this);
- }
}
final void performRestart() {
@@ -6915,9 +6890,7 @@
mFragments.dispatchResume();
mFragments.execPendingActions();
- if (isAtLeastO()) {
- getApplication().dispatchActivityResumed(this);
- }
+
onPostResume();
if (!mCalled) {
throw new SuperNotCalledException(
@@ -6932,15 +6905,13 @@
mCalled = false;
onPause();
mResumed = false;
- if (isAtLeastO()) {
- getApplication().dispatchActivityPaused(this);
- }
if (!mCalled && getApplicationInfo().targetSdkVersion
>= android.os.Build.VERSION_CODES.GINGERBREAD) {
throw new SuperNotCalledException(
"Activity " + mComponent.toShortString() +
" did not call through to super.onPause()");
}
+ mResumed = false;
}
final void performUserLeaving() {
@@ -6951,7 +6922,7 @@
final void performStop(boolean preserveWindow) {
mDoReportFullyDrawn = false;
mFragments.doLoaderStop(mChangingConfigurations /*retain*/);
- boolean dispatchActivityStopped = !mStopped;
+
if (!mStopped) {
if (mWindow != null) {
mWindow.closeAllPanels();
@@ -6988,9 +6959,6 @@
mStopped = true;
}
mResumed = false;
- if (dispatchActivityStopped && isAtLeastO()) {
- getApplication().dispatchActivityStopped(this);
- }
}
final void performDestroy() {
@@ -7002,13 +6970,6 @@
if (mVoiceInteractor != null) {
mVoiceInteractor.detachActivity();
}
- if (isAtLeastO()) {
- getApplication().dispatchActivityDestroyed(this);
- }
- }
-
- private boolean isAtLeastO() {
- return getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.O;
}
final void dispatchMultiWindowModeChanged(boolean isInMultiWindowMode) {
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index b367d0c..5b05d58 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -505,9 +505,6 @@
/** @hide requestType for assist context: generate full AssistStructure for auto-fill. */
public static final int ASSIST_CONTEXT_AUTO_FILL = 2;
- /** @hide requestType for assist context: generate full AssistStructure for auto-fill save. */
- public static final int ASSIST_CONTEXT_AUTO_FILL_SAVE = 3;
-
/** @hide Flag for registerUidObserver: report changes in process state. */
public static final int UID_OBSERVER_PROCSTATE = 1<<0;
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java
index e848080..89510d9 100644
--- a/core/java/android/app/ActivityManagerInternal.java
+++ b/core/java/android/app/ActivityManagerInternal.java
@@ -154,12 +154,6 @@
public abstract List<IBinder> getTopVisibleActivities();
/**
- * Returns the top, focused activity of the currently visible stack, but only if it belongs to
- * the given UID.
- */
- public abstract IBinder getTopVisibleActivity(int uid);
-
- /**
* Callback for window manager to let activity manager know that docked stack changes its
* minimized state.
*/
diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java
index 04510da..0b9479d 100644
--- a/core/java/android/app/ActivityOptions.java
+++ b/core/java/android/app/ActivityOptions.java
@@ -33,6 +33,7 @@
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.transition.Transition;
+import android.transition.TransitionListenerAdapter;
import android.transition.TransitionManager;
import android.util.Pair;
import android.util.Slog;
@@ -1342,7 +1343,7 @@
+ mStartY + ", mWidth=" + mWidth + ", mHeight=" + mHeight;
}
- private static class HideWindowListener extends Transition.TransitionListenerAdapter
+ private static class HideWindowListener extends TransitionListenerAdapter
implements ExitTransitionCoordinator.HideSharedElementsCallback {
private final Window mWindow;
private final ExitTransitionCoordinator mExit;
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index cf20b68..dffd81f 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -91,7 +91,6 @@
import android.security.net.config.NetworkSecurityConfigProvider;
import android.service.autofill.AutoFillService;
import android.service.autofill.IAutoFillAppCallback;
-import android.service.voice.VoiceInteractionSession;
import android.util.AndroidRuntimeException;
import android.util.ArrayMap;
import android.util.DisplayMetrics;
@@ -641,7 +640,6 @@
IBinder requestToken;
int requestType;
int sessionId;
- int flags;
}
static final class ActivityConfigChangeData {
@@ -1249,13 +1247,12 @@
@Override
public void requestAssistContextExtras(IBinder activityToken, IBinder requestToken,
- int requestType, int sessionId, int flags) {
+ int requestType, int sessionId) {
RequestAssistContextExtras cmd = new RequestAssistContextExtras();
cmd.activityToken = activityToken;
cmd.requestToken = requestToken;
cmd.requestType = requestType;
cmd.sessionId = sessionId;
- cmd.flags = flags;
sendMessage(H.REQUEST_ASSIST_CONTEXT_EXTRAS, cmd);
}
@@ -2905,9 +2902,7 @@
// - it does not need an AssistContent
// - it does not call onProvideAssistData()
// - it needs an IAutoFillCallback
- // - it sets the flags so views can provide autofill-specific data (such as passwords)
- boolean forAutoFill = cmd.requestType == ActivityManager.ASSIST_CONTEXT_AUTO_FILL
- || cmd.requestType == ActivityManager.ASSIST_CONTEXT_AUTO_FILL_SAVE;
+ boolean forAutoFill = cmd.requestType == ActivityManager.ASSIST_CONTEXT_AUTO_FILL;
// TODO(b/33197203): decide if lastSessionId logic applies to auto-fill sessions
if (mLastSessionId != cmd.sessionId) {
@@ -2934,12 +2929,9 @@
referrer = r.activity.onProvideReferrer();
}
if (cmd.requestType == ActivityManager.ASSIST_CONTEXT_FULL || forAutoFill) {
- structure = new AssistStructure(r.activity, cmd.flags);
+ structure = new AssistStructure(r.activity, forAutoFill);
Intent activityIntent = r.activity.getIntent();
- if (forAutoFill) {
- data.putInt(VoiceInteractionSession.KEY_FLAGS, cmd.flags);
- }
- boolean addAutoFillCallback = false;
+ boolean attachToSession = false;
// TODO(b/33197203): re-evaluate conditions below for auto-fill. In particular,
// FLAG_SECURE might be allowed on AUTO_FILL but not on AUTO_FILL_SAVE)
boolean notSecure = r.window == null ||
@@ -2947,7 +2939,7 @@
& WindowManager.LayoutParams.FLAG_SECURE) == 0;
if (activityIntent != null && notSecure) {
if (forAutoFill) {
- addAutoFillCallback = true;
+ attachToSession = true;
} else {
Intent intent = new Intent(activityIntent);
intent.setFlags(intent.getFlags() & ~(Intent.FLAG_GRANT_WRITE_URI_PERMISSION
@@ -2961,24 +2953,20 @@
} else {
// activityIntent is unlikely to be null, but if it is, we should still
// set the auto-fill callback.
- addAutoFillCallback = notSecure;
+ attachToSession = notSecure;
}
}
if (!forAutoFill) {
r.activity.onProvideAssistContent(content);
- } else if (addAutoFillCallback) {
- IAutoFillAppCallback cb = r.activity.getAutoFillCallback();
- if (cb != null) {
- data.putBinder(AutoFillService.KEY_CALLBACK, cb.asBinder());
- } else {
- Slog.w(TAG, "handleRequestAssistContextExtras(): callback was GCed");
- }
+ } else if (attachToSession) {
+ r.activity.attachToAutoFillSession();
}
}
}
if (structure == null) {
structure = new AssistStructure();
}
+
// TODO(b/33197203): decide if lastSessionId logic applies to auto-fill sessions
mLastAssistStructures.add(new WeakReference<>(structure));
IActivityManager mgr = ActivityManager.getService();
diff --git a/core/java/android/app/ActivityTransitionCoordinator.java b/core/java/android/app/ActivityTransitionCoordinator.java
index 1eaf029..a512350 100644
--- a/core/java/android/app/ActivityTransitionCoordinator.java
+++ b/core/java/android/app/ActivityTransitionCoordinator.java
@@ -24,6 +24,7 @@
import android.os.Parcelable;
import android.os.ResultReceiver;
import android.transition.Transition;
+import android.transition.TransitionListenerAdapter;
import android.transition.TransitionSet;
import android.transition.Visibility;
import android.util.ArrayMap;
@@ -916,7 +917,7 @@
protected void onTransitionsComplete() {}
- protected class ContinueTransitionListener extends Transition.TransitionListenerAdapter {
+ protected class ContinueTransitionListener extends TransitionListenerAdapter {
@Override
public void onTransitionStart(Transition transition) {
mIsStartingTransition = false;
diff --git a/core/java/android/app/Application.java b/core/java/android/app/Application.java
index 03efe68..156df36 100644
--- a/core/java/android/app/Application.java
+++ b/core/java/android/app/Application.java
@@ -55,7 +55,6 @@
public LoadedApk mLoadedApk;
public interface ActivityLifecycleCallbacks {
- default void onActivityPreCreated(Activity activity, Bundle savedInstanceState) {}
void onActivityCreated(Activity activity, Bundle savedInstanceState);
void onActivityStarted(Activity activity);
void onActivityResumed(Activity activity);
@@ -191,16 +190,6 @@
mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;
}
- /* package */ void dispatchActivityPreCreated(Activity activity, Bundle savedInstanceState) {
- Object[] callbacks = collectActivityLifecycleCallbacks();
- if (callbacks != null) {
- for (int i = 0; i < callbacks.length; i++) {
- ((ActivityLifecycleCallbacks) callbacks[i]).onActivityPreCreated(activity,
- savedInstanceState);
- }
- }
- }
-
/* package */ void dispatchActivityCreated(Activity activity, Bundle savedInstanceState) {
Object[] callbacks = collectActivityLifecycleCallbacks();
if (callbacks != null) {
diff --git a/core/java/android/app/EnterTransitionCoordinator.java b/core/java/android/app/EnterTransitionCoordinator.java
index 0454acb..445b687 100644
--- a/core/java/android/app/EnterTransitionCoordinator.java
+++ b/core/java/android/app/EnterTransitionCoordinator.java
@@ -26,6 +26,7 @@
import android.os.ResultReceiver;
import android.text.TextUtils;
import android.transition.Transition;
+import android.transition.TransitionListenerAdapter;
import android.transition.TransitionManager;
import android.util.ArrayMap;
import android.view.View;
@@ -491,7 +492,7 @@
sharedElementTransitionStarted();
sharedElementTransitionComplete();
} else {
- sharedElementTransition.addListener(new Transition.TransitionListenerAdapter() {
+ sharedElementTransition.addListener(new TransitionListenerAdapter() {
@Override
public void onTransitionStart(Transition transition) {
sharedElementTransitionStarted();
@@ -592,7 +593,7 @@
});
mBackgroundAnimator.start();
} else if (transition != null) {
- transition.addListener(new Transition.TransitionListenerAdapter() {
+ transition.addListener(new TransitionListenerAdapter() {
@Override
public void onTransitionEnd(Transition transition) {
transition.removeListener(this);
diff --git a/core/java/android/app/ExitTransitionCoordinator.java b/core/java/android/app/ExitTransitionCoordinator.java
index f04eef2..29e10d8 100644
--- a/core/java/android/app/ExitTransitionCoordinator.java
+++ b/core/java/android/app/ExitTransitionCoordinator.java
@@ -31,6 +31,7 @@
import android.os.Message;
import android.os.ResultReceiver;
import android.transition.Transition;
+import android.transition.TransitionListenerAdapter;
import android.transition.TransitionManager;
import android.view.View;
import android.view.ViewGroup;
@@ -161,7 +162,7 @@
private void startSharedElementExit(final ViewGroup decorView) {
Transition transition = getSharedElementExitTransition();
- transition.addListener(new Transition.TransitionListenerAdapter() {
+ transition.addListener(new TransitionListenerAdapter() {
@Override
public void onTransitionEnd(Transition transition) {
transition.removeListener(this);
diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java
index 4f68ec7..b7c0737 100644
--- a/core/java/android/app/FragmentManager.java
+++ b/core/java/android/app/FragmentManager.java
@@ -2077,8 +2077,6 @@
} else {
record.trackAddedFragmentsInPop(mTmpAddedFragments);
}
- final int bumpAmount = isPop ? -1 : 1;
- record.bumpBackStackNesting(bumpAmount);
addToBackStack = addToBackStack || record.mAddToBackStack;
}
mTmpAddedFragments.clear();
@@ -2281,8 +2279,10 @@
final BackStackRecord record = records.get(i);
final boolean isPop = isRecordPop.get(i);
if (isPop) {
+ record.bumpBackStackNesting(-1);
record.executePopOps();
} else {
+ record.bumpBackStackNesting(1);
record.executeOps();
}
}
diff --git a/core/java/android/app/FragmentTransition.java b/core/java/android/app/FragmentTransition.java
index 2570d92..f62ab8d 100644
--- a/core/java/android/app/FragmentTransition.java
+++ b/core/java/android/app/FragmentTransition.java
@@ -18,6 +18,7 @@
import android.graphics.Rect;
import android.os.Build;
import android.transition.Transition;
+import android.transition.TransitionListenerAdapter;
import android.transition.TransitionManager;
import android.transition.TransitionSet;
import android.util.ArrayMap;
@@ -332,7 +333,7 @@
OneShotPreDrawListener.add(exitingFragment.mContainer, () -> {
setViewVisibility(exitingViews, View.INVISIBLE);
});
- exitTransition.addListener(new Transition.TransitionListenerAdapter() {
+ exitTransition.addListener(new TransitionListenerAdapter() {
@Override
public void onTransitionEnd(Transition transition) {
transition.removeListener(this);
@@ -995,7 +996,7 @@
final Transition enterTransition, final ArrayList<View> enteringViews,
final Transition exitTransition, final ArrayList<View> exitingViews,
final TransitionSet sharedElementTransition, final ArrayList<View> sharedElementsIn) {
- overalTransition.addListener(new Transition.TransitionListenerAdapter() {
+ overalTransition.addListener(new TransitionListenerAdapter() {
@Override
public void onTransitionStart(Transition transition) {
if (enterTransition != null) {
diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl
index 0a2f804..c842f78 100644
--- a/core/java/android/app/IActivityManager.aidl
+++ b/core/java/android/app/IActivityManager.aidl
@@ -145,6 +145,7 @@
int flags, in Bundle arguments, in IInstrumentationWatcher watcher,
in IUiAutomationConnection connection, int userId,
in String abiOverride);
+ void addInstrumentationResults(in IApplicationThread target, in Bundle results);
void finishInstrumentation(in IApplicationThread target, int resultCode,
in Bundle results);
/**
@@ -584,7 +585,7 @@
void unregisterTaskStackListener(ITaskStackListener listener);
void moveStackToDisplay(int stackId, int displayId);
boolean requestAutoFillData(in IResultReceiver receiver, in Bundle receiverExtras,
- int resultCode, in IBinder activityToken, int flags);
+ in IBinder activityToken);
void dismissKeyguard(in IBinder token, in IKeyguardDismissCallback callback);
int restartUserInBackground(int userId);
diff --git a/core/java/android/app/IApplicationThread.aidl b/core/java/android/app/IApplicationThread.aidl
index 41d1255..4fc6fb9 100644
--- a/core/java/android/app/IApplicationThread.aidl
+++ b/core/java/android/app/IApplicationThread.aidl
@@ -134,7 +134,7 @@
void dumpDbInfo(in ParcelFileDescriptor fd, in String[] args);
void unstableProviderDied(IBinder provider);
void requestAssistContextExtras(IBinder activityToken, IBinder requestToken,
- int requestType, int sessionId, int flags);
+ int requestType, int sessionId);
void scheduleTranslucentConversionComplete(IBinder token, boolean timeout);
void setProcessState(int state);
void scheduleInstallProvider(in ProviderInfo provider);
diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java
index b1bdea1..4db29fb 100644
--- a/core/java/android/app/Instrumentation.java
+++ b/core/java/android/app/Instrumentation.java
@@ -186,11 +186,25 @@
}
}
}
-
+
+ /**
+ * Report some results in the middle of instrumentation execution. Later results (including
+ * those provided by {@link #finish}) will be combined with {@link Bundle#putAll}.
+ */
+ public void addResults(Bundle results) {
+ IActivityManager am = ActivityManager.getService();
+ try {
+ am.addInstrumentationResults(mThread.getApplicationThread(), results);
+ } catch (RemoteException ex) {
+ throw ex.rethrowFromSystemServer();
+ }
+ }
+
/**
* Terminate instrumentation of the application. This will cause the
* application process to exit, removing this instrumentation from the next
- * time the application is started.
+ * time the application is started. If multiple processes are currently running
+ * for this instrumentation, all of those processes will be killed.
*
* @param resultCode Overall success/failure of instrumentation.
* @param results Any results to send back to the code that started the
@@ -278,6 +292,18 @@
}
/**
+ * Return the name of the process this instrumentation is running in. Note this should
+ * only be used for testing and debugging. If you are thinking about using this to,
+ * for example, conditionalize what is initialized in an Application class, it is strongly
+ * recommended to instead use lazy initialization (such as a getter for the state that
+ * only creates it when requested). This can greatly reduce the work your process does
+ * when created for secondary things, such as to receive a broadcast.
+ */
+ public String getProcessName() {
+ return mThread.getProcessName();
+ }
+
+ /**
* Check whether this instrumentation was started with profiling enabled.
*
* @return Returns true if profiling was enabled when starting, else false.
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index b7eda25..44e328e 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -28,6 +28,7 @@
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.ShortcutInfo;
import android.content.res.ColorStateList;
import android.graphics.Bitmap;
import android.graphics.Canvas;
@@ -48,6 +49,7 @@
import android.os.SystemClock;
import android.os.SystemProperties;
import android.os.UserHandle;
+import android.service.notification.StatusBarNotification;
import android.text.BidiFormatter;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
@@ -222,13 +224,11 @@
* superimposed over the icon in the status bar. Starting with
* {@link android.os.Build.VERSION_CODES#HONEYCOMB}, the template used by
* {@link Notification.Builder} has displayed the number in the expanded notification view.
+ * Starting with {@link android.os.Build.VERSION_CODES#O}, the number may be displayed as a
+ * badge icon in Launchers that support badging.
*
- * If the number is 0 or negative, it is never shown.
- *
- * @deprecated this number is not shown anymore
*/
- @Deprecated
- public int number;
+ public int number = 1;
/**
* The intent to execute when the expanded status entry is clicked. If
@@ -633,9 +633,10 @@
/**
* Special value of {@link #color} used as a place holder for an invalid color.
+ * @hide
*/
@ColorInt
- private static final int COLOR_INVALID = 1;
+ public static final int COLOR_INVALID = 1;
/**
* Sphere of visibility of this notification, which affects how and when the SystemUI reveals
@@ -1073,6 +1074,26 @@
private String mChannelId;
private long mTimeout;
+ private String mShortcutId;
+
+ /**
+ * If this notification is being shown as a badge, always show as a number.
+ */
+ public static final int BADGE_ICON_NONE = 0;
+
+ /**
+ * If this notification is being shown as a badge, use the {@link #getSmallIcon()} to
+ * represent this notification.
+ */
+ public static final int BADGE_ICON_SMALL = 1;
+
+ /**
+ * If this notification is being shown as a badge, use the {@link #getLargeIcon()} to
+ * represent this notification.
+ */
+ public static final int BADGE_ICON_LARGE = 2;
+ private int mBadgeIcon = BADGE_ICON_LARGE;
+
/**
* Structure to encapsulate a named action that can be shown as part of this notification.
* It must include an icon, a label, and a {@link PendingIntent} to be fired when the action is
@@ -1817,6 +1838,12 @@
mChannelId = parcel.readString();
}
mTimeout = parcel.readLong();
+
+ if (parcel.readInt() != 0) {
+ mShortcutId = parcel.readString();
+ }
+
+ mBadgeIcon = parcel.readInt();
}
@Override
@@ -2041,7 +2068,7 @@
}
try {
// IMPORTANT: Add marshaling code in writeToParcelImpl as we
- // want to intercept all pending events written to the pacel.
+ // want to intercept all pending events written to the parcel.
writeToParcelImpl(parcel, flags);
// Must be written last!
parcel.writeArraySet(allPendingIntents);
@@ -2184,6 +2211,15 @@
parcel.writeInt(0);
}
parcel.writeLong(mTimeout);
+
+ if (mShortcutId != null) {
+ parcel.writeInt(1);
+ parcel.writeString(mShortcutId);
+ } else {
+ parcel.writeInt(0);
+ }
+
+ parcel.writeInt(mBadgeIcon);
}
/**
@@ -2381,13 +2417,30 @@
}
/**
- * Returns the time at which this notification should be canceled, if it's not canceled already.
+ * Returns the time at which this notification should be canceled by the system, if it's not
+ * canceled already.
*/
public long getTimeout() {
return mTimeout;
}
/**
+ * Returns what icon should be shown for this notification if it is being displayed in a
+ * Launcher that supports badging. Will be one of {@link #BADGE_ICON_NONE},
+ * {@link #BADGE_ICON_SMALL}, or {@link #BADGE_ICON_LARGE}.
+ */
+ public int getBadgeIcon() {
+ return mBadgeIcon;
+ }
+
+ /**
+ * Returns the {@link ShortcutInfo#getId() id} that this notification supersedes, if any.
+ */
+ public String getShortcutId() {
+ return mShortcutId;
+ }
+
+ /**
* The small icon representing this notification in the status bar and content view.
*
* @return the small icon representing this notification.
@@ -2482,7 +2535,6 @@
private NotificationColorUtil mColorUtil;
private boolean mIsLegacy;
private boolean mIsLegacyInitialized;
- private boolean mColorUtilInited = false;
/**
* Caches a contrast-enhanced version of {@link #mCachedContrastColorIsFor}.
@@ -2600,16 +2652,42 @@
}
private NotificationColorUtil getColorUtil() {
- if (!mColorUtilInited) {
- mColorUtilInited = true;
- if (isLegacy() || isColorized()) {
- mColorUtil = NotificationColorUtil.getInstance(mContext);
- }
+ if (mColorUtil == null) {
+ mColorUtil = NotificationColorUtil.getInstance(mContext);
}
return mColorUtil;
}
/**
+ * If this notification is duplicative of a Launcher shortcut, sets the
+ * {@link ShortcutInfo#getId() id} of the shortcut, in case the Launcher wants to hide
+ * the shortcut.
+ *
+ * This field will be ignored by Launchers that don't support badging or
+ * {@link android.content.pm.ShortcutManager shortcuts}.
+ *
+ * @param shortcutId the {@link ShortcutInfo#getId() id} of the shortcut this notification
+ * supersedes
+ */
+ public Builder setShortcutId(String shortcutId) {
+ mN.mShortcutId = shortcutId;
+ return this;
+ }
+
+ /**
+ * Sets which icon to display as a badge for this notification.
+ *
+ * Must be one of {@link #BADGE_ICON_NONE}, {@link #BADGE_ICON_SMALL},
+ * {@link #BADGE_ICON_LARGE}.
+ *
+ * Note: This value might be ignored, for launchers that don't support badge icons.
+ */
+ public Builder chooseBadgeIcon(int icon) {
+ mN.mBadgeIcon = icon;
+ return this;
+ }
+
+ /**
* Specifies the channel the notification should be delivered on.
*/
public Builder setChannel(String channelId) {
@@ -2804,13 +2882,9 @@
}
/**
- * Set the large number at the right-hand side of the notification. This is
- * equivalent to setContentInfo, although it might show the number in a different
- * font size for readability.
- *
- * @deprecated this number is not shown anywhere anymore
+ * Sets the number of items this notification represents. May be displayed as a badge count
+ * for Launchers that support badging.
*/
- @Deprecated
public Builder setNumber(int number) {
mN.number = number;
return this;
@@ -3095,12 +3169,16 @@
* Set whether this notification should be colorized. When set, the color set with
* {@link #setColor(int)} will be used as the background color of this notification.
* <p>
- * The coloring will only be applied if the notification is ongoing.
* This should only be used for high priority ongoing tasks like navigation, an ongoing
* call, or other similarly high-priority events for the user.
+ * <p>
+ * For most styles, the coloring will only be applied if the notification is ongoing.
+ * However, for {@link MediaStyle} and {@link DecoratedMediaCustomViewStyle} notifications
+ * that have a media session attached there is no requirement for it to be ongoing.
*
* @see Builder#setOngoing(boolean)
* @see Builder#setColor(int)
+ * @see MediaStyle#setMediaSession(MediaSession.Token)
*/
public Builder setColorized(boolean colorize) {
mN.extras.putBoolean(EXTRA_COLORIZED, colorize);
@@ -3681,13 +3759,21 @@
}
private void bindExpandButton(RemoteViews contentView) {
- int color = isColorized() ? getPrimaryTextColor() : resolveContrastColor();
+ int color = getPrimaryHighlightColor();
contentView.setDrawableParameters(R.id.expand_button, false, -1, color,
PorterDuff.Mode.SRC_ATOP, -1);
contentView.setInt(R.id.notification_header, "setOriginalNotificationColor",
color);
}
+ /**
+ * @return the color that is used as the first primary highlight color. This is applied
+ * in several places like the action buttons or the app name in the header.
+ */
+ private int getPrimaryHighlightColor() {
+ return isColorized() ? getPrimaryTextColor() : resolveContrastColor();
+ }
+
private void bindHeaderChronometerAndTime(RemoteViews contentView) {
if (showsTimeOrChronometer()) {
contentView.setViewVisibility(R.id.time_divider, View.VISIBLE);
@@ -3903,10 +3989,24 @@
* 3. Standard template view
*/
public RemoteViews createContentView() {
+ return createContentView(false /* increasedheight */ );
+ }
+
+ /**
+ * Construct a RemoteViews for the smaller content view.
+ *
+ * @param increasedHeight true if this layout be created with an increased height. Some
+ * styles may support showing more then just that basic 1U size
+ * and the system may decide to render important notifications
+ * slightly bigger even when collapsed.
+ *
+ * @hide
+ */
+ public RemoteViews createContentView(boolean increasedHeight) {
if (mN.contentView != null && (mStyle == null || !mStyle.displayCustomViewInline())) {
return mN.contentView;
} else if (mStyle != null) {
- final RemoteViews styleView = mStyle.makeContentView();
+ final RemoteViews styleView = mStyle.makeContentView(increasedHeight);
if (styleView != null) {
return styleView;
}
@@ -4250,7 +4350,7 @@
}
private CharSequence processLegacyText(CharSequence charSequence) {
- if (isLegacy() || isColorized()) {
+ if (isLegacy() || textColorsNeedInversion()) {
return getColorUtil().invertCharSequenceColors(charSequence);
} else {
return charSequence;
@@ -4263,7 +4363,7 @@
private void processSmallIconColor(Icon smallIcon, RemoteViews contentView,
boolean ambient) {
boolean colorable = !isLegacy() || getColorUtil().isGrayscaleIcon(mContext, smallIcon);
- int color = ambient ? resolveAmbientColor() : resolveContrastColor();
+ int color = ambient ? resolveAmbientColor() : getPrimaryHighlightColor();
if (colorable) {
contentView.setDrawableParameters(R.id.icon, false, -1, color,
PorterDuff.Mode.SRC_ATOP, -1);
@@ -4524,6 +4624,15 @@
private boolean isColorized() {
return mN.isColorized();
}
+
+ private boolean textColorsNeedInversion() {
+ if (mStyle == null || !MediaStyle.class.equals(mStyle.getClass())) {
+ return false;
+ }
+ int targetSdkVersion = mContext.getApplicationInfo().targetSdkVersion;
+ return targetSdkVersion > Build.VERSION_CODES.M
+ && targetSdkVersion < Build.VERSION_CODES.O;
+ }
}
/**
@@ -4536,12 +4645,44 @@
}
/**
- * @return true if this notification is colorized. This also factors in wheather the
+ * @return whether this notification has a media session attached
+ * @hide
+ */
+ public boolean hasMediaSession() {
+ return extras.getParcelable(Notification.EXTRA_MEDIA_SESSION) != null;
+ }
+
+ /**
+ * @return the style class of this notification
+ * @hide
+ */
+ public Class<? extends Notification.Style> getNotificationStyle() {
+ String templateClass = extras.getString(Notification.EXTRA_TEMPLATE);
+
+ if (!TextUtils.isEmpty(templateClass)) {
+ return Notification.getNotificationStyleClass(templateClass);
+ }
+ return null;
+ }
+
+ /**
+ * @return true if this notification is colorized. This also factors in whether the
* notification is ongoing.
*
* @hide
*/
public boolean isColorized() {
+ Class<? extends Style> style = getNotificationStyle();
+ if (MediaStyle.class.equals(style)) {
+ Boolean colorized = (Boolean) extras.get(EXTRA_COLORIZED);
+ if ((colorized == null || colorized) && hasMediaSession()) {
+ return true;
+ }
+ } else if (DecoratedMediaCustomViewStyle.class.equals(style)) {
+ if (extras.getBoolean(EXTRA_COLORIZED) && hasMediaSession()) {
+ return true;
+ }
+ }
return extras.getBoolean(EXTRA_COLORIZED) && isOngoing();
}
@@ -4656,11 +4797,13 @@
}
/**
- * Construct a Style-specific RemoteViews for the final 1U notification layout.
+ * Construct a Style-specific RemoteViews for the collapsed notification layout.
* The default implementation has nothing additional to add.
+ *
+ * @param increasedHeight true if this layout be created with an increased height.
* @hide
*/
- public RemoteViews makeContentView() {
+ public RemoteViews makeContentView(boolean increasedHeight) {
return null;
}
@@ -5006,6 +5149,23 @@
}
/**
+ * @param increasedHeight true if this layout be created with an increased height.
+ *
+ * @hide
+ */
+ @Override
+ public RemoteViews makeContentView(boolean increasedHeight) {
+ if (increasedHeight) {
+ ArrayList<Action> actions = mBuilder.mActions;
+ mBuilder.mActions = new ArrayList<>();
+ RemoteViews remoteViews = makeBigContentView();
+ mBuilder.mActions = actions;
+ return remoteViews;
+ }
+ return super.makeContentView(increasedHeight);
+ }
+
+ /**
* @hide
*/
public RemoteViews makeBigContentView() {
@@ -5269,17 +5429,25 @@
* @hide
*/
@Override
- public RemoteViews makeContentView() {
- Message m = findLatestIncomingMessage();
- CharSequence title = mConversationTitle != null
- ? mConversationTitle
- : (m == null) ? null : m.mSender;
- CharSequence text = (m == null)
- ? null
- : mConversationTitle != null ? makeMessageLine(m, mBuilder) : m.mText;
+ public RemoteViews makeContentView(boolean increasedHeight) {
+ if (!increasedHeight) {
+ Message m = findLatestIncomingMessage();
+ CharSequence title = mConversationTitle != null
+ ? mConversationTitle
+ : (m == null) ? null : m.mSender;
+ CharSequence text = (m == null)
+ ? null
+ : mConversationTitle != null ? makeMessageLine(m, mBuilder) : m.mText;
- return mBuilder.applyStandardTemplateWithActions(mBuilder.getBaseLayoutResource(),
- mBuilder.mParams.reset().hasProgress(false).title(title).text(text));
+ return mBuilder.applyStandardTemplate(mBuilder.getBaseLayoutResource(),
+ mBuilder.mParams.reset().hasProgress(false).title(title).text(text));
+ } else {
+ ArrayList<Action> actions = mBuilder.mActions;
+ mBuilder.mActions = new ArrayList<>();
+ RemoteViews remoteViews = makeBigContentView();
+ mBuilder.mActions = actions;
+ return remoteViews;
+ }
}
private Message findLatestIncomingMessage() {
@@ -5760,21 +5928,27 @@
* shown as icon-only pushbuttons, suitable for transport controls. The Bitmap given to
* {@link Notification.Builder#setLargeIcon(android.graphics.Bitmap) setLargeIcon()} will be
* treated as album artwork.
- *
+ * <p>
* Unlike the other styles provided here, MediaStyle can also modify the standard-size
* {@link Notification#contentView}; by providing action indices to
* {@link #setShowActionsInCompactView(int...)} you can promote up to 3 actions to be displayed
* in the standard view alongside the usual content.
- *
+ * <p>
* Notifications created with MediaStyle will have their category set to
* {@link Notification#CATEGORY_TRANSPORT CATEGORY_TRANSPORT} unless you set a different
* category using {@link Notification.Builder#setCategory(String) setCategory()}.
- *
+ * <p>
* Finally, if you attach a {@link android.media.session.MediaSession.Token} using
* {@link android.app.Notification.MediaStyle#setMediaSession(MediaSession.Token)},
* the System UI can identify this as a notification representing an active media session
* and respond accordingly (by showing album artwork in the lockscreen, for example).
*
+ * <p>
+ * Starting at {@link android.os.Build.VERSION_CODES#O Android O} any notification that has a
+ * media session attached with {@link #setMediaSession(MediaSession.Token)} will be colorized.
+ * You can opt-out of this behavior by using {@link Notification.Builder#setColorized(boolean)}.
+ * <p>
+ *
* To use this style with your Notification, feed it to
* {@link Notification.Builder#setStyle(android.app.Notification.Style)} like so:
* <pre class="prettyprint">
@@ -5789,6 +5963,7 @@
* </pre>
*
* @see Notification#bigContentView
+ * @see Notification.Builder#setColorized(boolean)
*/
public static class MediaStyle extends Style {
static final int MAX_MEDIA_BUTTONS_IN_COMPACT = 3;
@@ -5844,7 +6019,7 @@
* @hide
*/
@Override
- public RemoteViews makeContentView() {
+ public RemoteViews makeContentView(boolean increasedHeight) {
return makeMediaContentView();
}
@@ -5926,7 +6101,7 @@
final Action action = mBuilder.mActions.get(mActionsToShowInCompact[i]);
final RemoteViews button = generateMediaActionButton(action,
- mBuilder.resolveContrastColor());
+ getPrimaryHighlightColor());
view.addView(com.android.internal.R.id.media_actions, button);
}
}
@@ -5940,6 +6115,10 @@
return view;
}
+ private int getPrimaryHighlightColor() {
+ return mBuilder.getPrimaryHighlightColor();
+ }
+
private RemoteViews makeMediaBigContentView() {
final int actionCount = Math.min(mBuilder.mActions.size(), MAX_MEDIA_BUTTONS);
// Dont add an expanded view if there is no more content to be revealed
@@ -5957,7 +6136,7 @@
big.removeAllViews(com.android.internal.R.id.media_actions);
for (int i = 0; i < actionCount; i++) {
final RemoteViews button = generateMediaActionButton(mBuilder.mActions.get(i),
- mBuilder.resolveContrastColor());
+ getPrimaryHighlightColor());
big.addView(com.android.internal.R.id.media_actions, button);
}
}
@@ -6020,7 +6199,7 @@
* @hide
*/
@Override
- public RemoteViews makeContentView() {
+ public RemoteViews makeContentView(boolean increasedHeight) {
return makeStandardTemplateWithCustomContent(mBuilder.mN.contentView);
}
@@ -6102,7 +6281,10 @@
* {@link android.app.Notification.Builder#setCustomBigContentView(RemoteViews)} and
* {@link android.app.Notification.Builder#setCustomHeadsUpContentView(RemoteViews)} to set the
* corresponding custom views to display.
- *
+ * <p>
+ * Contrary to {@link MediaStyle} a developer has to opt-in to the colorizing of the
+ * notification by using {@link Notification.Builder#setColorized(boolean)}.
+ * <p>
* To use this style with your Notification, feed it to
* {@link Notification.Builder#setStyle(android.app.Notification.Style)} like so:
* <pre class="prettyprint">
@@ -6134,8 +6316,8 @@
* @hide
*/
@Override
- public RemoteViews makeContentView() {
- RemoteViews remoteViews = super.makeContentView();
+ public RemoteViews makeContentView(boolean increasedHeight) {
+ RemoteViews remoteViews = super.makeContentView(false /* increasedHeight */);
return buildIntoRemoteView(remoteViews, R.id.notification_content_container,
mBuilder.mN.contentView);
}
@@ -6157,7 +6339,7 @@
return buildIntoRemoteView(remoteViews, R.id.notification_main_column,
customRemoteView);
} else if (customRemoteView != mBuilder.mN.contentView){
- remoteViews = super.makeContentView();
+ remoteViews = super.makeContentView(false /* increasedHeight */);
return buildIntoRemoteView(remoteViews, R.id.notification_content_container,
customRemoteView);
} else {
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index 5a75a67..44db326 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -30,6 +30,8 @@
import android.app.usage.UsageStatsManager;
import android.appwidget.AppWidgetManager;
import android.bluetooth.BluetoothManager;
+import android.companion.CompanionDeviceManager;
+import android.companion.ICompanionDeviceManager;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.IRestrictionsManager;
@@ -115,6 +117,7 @@
import android.service.autofill.IAutoFillManagerService;
import android.service.persistentdata.IPersistentDataBlockService;
import android.service.persistentdata.PersistentDataBlockManager;
+import android.service.vr.IVrManager;
import android.telecom.TelecomManager;
import android.telephony.CarrierConfigManager;
import android.telephony.SubscriptionManager;
@@ -633,6 +636,18 @@
UserHandle.getAppId(Process.myUid()));
}});
+ registerService(Context.COMPANION_DEVICE_SERVICE, CompanionDeviceManager.class,
+ new CachedServiceFetcher<CompanionDeviceManager>() {
+ @Override
+ public CompanionDeviceManager createService(ContextImpl ctx)
+ throws ServiceNotFoundException {
+ IBinder iBinder =
+ ServiceManager.getServiceOrThrow(Context.COMPANION_DEVICE_SERVICE);
+ ICompanionDeviceManager service =
+ ICompanionDeviceManager.Stub.asInterface(iBinder);
+ return new CompanionDeviceManager(service, ctx);
+ }});
+
registerService(Context.CONSUMER_IR_SERVICE, ConsumerIrManager.class,
new CachedServiceFetcher<ConsumerIrManager>() {
@Override
@@ -814,6 +829,14 @@
IAutoFillManagerService service = IAutoFillManagerService.Stub.asInterface(b);
return new AutoFillManager(ctx, service);
}});
+
+ registerService(Context.VR_SERVICE, VrManager.class, new CachedServiceFetcher<VrManager>() {
+ @Override
+ public VrManager createService(ContextImpl ctx) throws ServiceNotFoundException {
+ IBinder b = ServiceManager.getServiceOrThrow(Context.VR_SERVICE);
+ return new VrManager(IVrManager.Stub.asInterface(b));
+ }
+ });
}
/**
diff --git a/core/java/android/app/TimePickerDialog.java b/core/java/android/app/TimePickerDialog.java
index 3f467a0..b219f2a 100644
--- a/core/java/android/app/TimePickerDialog.java
+++ b/core/java/android/app/TimePickerDialog.java
@@ -145,14 +145,25 @@
}
@Override
+ public void show() {
+ super.show();
+ getButton(BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ if (mTimePicker.validateInput()) {
+ if (mTimeSetListener != null) {
+ mTimeSetListener.onTimeSet(mTimePicker, mTimePicker.getCurrentHour(),
+ mTimePicker.getCurrentMinute());
+ }
+ dismiss();
+ }
+ }
+ });
+ }
+
+ @Override
public void onClick(DialogInterface dialog, int which) {
switch (which) {
- case BUTTON_POSITIVE:
- if (mTimeSetListener != null) {
- mTimeSetListener.onTimeSet(mTimePicker, mTimePicker.getCurrentHour(),
- mTimePicker.getCurrentMinute());
- }
- break;
case BUTTON_NEGATIVE:
cancel();
break;
diff --git a/core/java/android/app/UiAutomation.java b/core/java/android/app/UiAutomation.java
index 6d1d1a3..1d6f42e 100644
--- a/core/java/android/app/UiAutomation.java
+++ b/core/java/android/app/UiAutomation.java
@@ -1118,6 +1118,16 @@
public void onFingerprintGesture(int gesture) {
/* do nothing */
}
+
+ @Override
+ public void onAccessibilityButtonClicked() {
+ /* do nothing */
+ }
+
+ @Override
+ public void onAccessibilityButtonAvailabilityChanged(boolean available) {
+ /* do nothing */
+ }
});
}
}
diff --git a/core/java/android/app/VrManager.java b/core/java/android/app/VrManager.java
new file mode 100644
index 0000000..a0b0eea
--- /dev/null
+++ b/core/java/android/app/VrManager.java
@@ -0,0 +1,44 @@
+package android.app;
+
+
+import android.annotation.SystemApi;
+import android.content.ComponentName;
+import android.os.RemoteException;
+import android.service.vr.IVrManager;
+
+/**
+ * Used to control aspects of a devices Virtual Reality (VR) capabilities.
+ * <p>
+ * You do not instantiate this class directly; instead, retrieve it through
+ * {@link android.content.Context#getSystemService}.
+ * @hide
+ */
+@SystemApi
+public class VrManager {
+ private final IVrManager mService;
+
+ /**
+ * {@hide}
+ */
+ public VrManager(IVrManager service) {
+ mService = service;
+ }
+
+ /**
+ * Sets the persistent VR mode state of a device. When a device is in persistent VR mode it will
+ * remain in VR mode even if the foreground does not specify Vr mode being enabled. Mainly used
+ * by VR viewers to indicate that a device is placed in a VR viewer.
+ *
+ * <p>Requires {@link android.Manifest.permission#ACCESS_VR_MANAGER} permission.</p>
+ *
+ * @see Activity#setVrModeEnabled(boolean, ComponentName)
+ * @param enabled true if the device should be placed in persistent VR mode.
+ */
+ public void setPersistentVrModeEnabled(boolean enabled) {
+ try {
+ mService.setPersistentVrModeEnabled(enabled);
+ } catch (RemoteException e) {
+ e.rethrowFromSystemServer();
+ }
+ }
+}
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 52d7386..f1ccabe 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -377,7 +377,7 @@
* @hide
*/
public static final String ACTION_BUGREPORT_SHARING_ACCEPTED =
- "com.android.server.action.BUGREPORT_SHARING_ACCEPTED";
+ "com.android.server.action.REMOTE_BUGREPORT_SHARING_ACCEPTED";
/**
* Action: Bugreport sharing with device owner has been declined by the user.
@@ -385,7 +385,7 @@
* @hide
*/
public static final String ACTION_BUGREPORT_SHARING_DECLINED =
- "com.android.server.action.BUGREPORT_SHARING_DECLINED";
+ "com.android.server.action.REMOTE_BUGREPORT_SHARING_DECLINED";
/**
* Action: Bugreport has been collected and is dispatched to {@code DevicePolicyManagerService}.
@@ -6073,20 +6073,24 @@
/**
* Sets which packages may enter lock task mode.
* <p>
- * Any packages that shares uid with an allowed package will also be allowed to activate lock
+ * Any packages that share uid with an allowed package will also be allowed to activate lock
* task. From {@link android.os.Build.VERSION_CODES#M} removing packages from the lock task
- * package list results in locked tasks belonging to those packages to be finished. This
- * function can only be called by the device owner.
+ * package list results in locked tasks belonging to those packages to be finished.
+ * <p>
+ * This function can only be called by the device owner or by a profile owner of a user/profile
+ * that is affiliated with the device owner user. See {@link #setAffiliationIds}. Any packages
+ * set via this method will be cleared if the user becomes unaffiliated.
*
* @param packages The list of packages allowed to enter lock task mode
* @param admin Which {@link DeviceAdminReceiver} this request is associated with.
- * @throws SecurityException if {@code admin} is not a device owner.
+ * @throws SecurityException if {@code admin} is not the device owner, or the profile owner of
+ * an affiliated user or profile.
* @see Activity#startLockTask()
* @see DeviceAdminReceiver#onLockTaskModeEntering(Context, Intent, String)
* @see DeviceAdminReceiver#onLockTaskModeExiting(Context, Intent)
* @see UserManager#DISALLOW_CREATE_WINDOWS
*/
- public void setLockTaskPackages(@NonNull ComponentName admin, String[] packages)
+ public void setLockTaskPackages(@NonNull ComponentName admin, @NonNull String[] packages)
throws SecurityException {
throwIfParentInstance("setLockTaskPackages");
if (mService != null) {
@@ -6099,10 +6103,11 @@
}
/**
- * This function returns the list of packages allowed to start the lock task mode.
+ * Returns the list of packages allowed to start the lock task mode.
*
- * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
- * @hide
+ * @throws SecurityException if {@code admin} is not the device owner, or the profile owner of
+ * an affiliated user or profile.
+ * @see #setLockTaskPackages
*/
public @NonNull String[] getLockTaskPackages(@NonNull ComponentName admin) {
throwIfParentInstance("getLockTaskPackages");
@@ -6113,7 +6118,7 @@
throw e.rethrowFromSystemServer();
}
}
- return null;
+ return new String[0];
}
/**
diff --git a/core/java/android/app/admin/SecurityLog.java b/core/java/android/app/admin/SecurityLog.java
index 2858991..91b87d7 100644
--- a/core/java/android/app/admin/SecurityLog.java
+++ b/core/java/android/app/admin/SecurityLog.java
@@ -144,8 +144,7 @@
}
/**
- * Returns the payload contained in this log. Each call to this method will
- * retrieve the next payload item. If no more payload exists, it returns {@code null}.
+ * Returns the payload contained in this log entry or {@code null} if there is no payload.
*/
public Object getData() {
return mEvent.getData();
diff --git a/core/java/android/app/assist/AssistStructure.java b/core/java/android/app/assist/AssistStructure.java
index b94264e..08aa5f2 100644
--- a/core/java/android/app/assist/AssistStructure.java
+++ b/core/java/android/app/assist/AssistStructure.java
@@ -22,6 +22,7 @@
import android.view.WindowManager;
import android.view.WindowManagerGlobal;
import android.view.autofill.AutoFillType;
+import android.view.autofill.AutoFillValue;
import android.view.autofill.AutoFillId;
import java.util.ArrayList;
@@ -53,6 +54,8 @@
Rect mTmpRect = new Rect();
+ boolean mSanitizeOnWrite = false;
+
static final int TRANSACTION_XFER = Binder.FIRST_CALL_TRANSACTION+1;
static final String DESCRIPTOR = "android.app.AssistStructure";
@@ -113,8 +116,10 @@
int mNumWrittenWindows;
int mNumWrittenViews;
final float[] mTmpMatrix = new float[9];
+ final boolean mSanitizeOnWrite;
ParcelTransferWriter(AssistStructure as, Parcel out) {
+ mSanitizeOnWrite = as.mSanitizeOnWrite;
mWriteStructure = as.waitForReady();
ComponentName.writeToParcel(as.mActivityComponent, out);
mNumWindows = as.mWindowNodes.size();
@@ -186,7 +191,7 @@
+ ", views=" + mNumWrittenViews
+ ", level=" + (mCurViewStackPos+levelAdj));
out.writeInt(VALIDATE_VIEW_TOKEN);
- int flags = child.writeSelfToParcel(out, pwriter, mTmpMatrix);
+ int flags = child.writeSelfToParcel(out, pwriter, mSanitizeOnWrite, mTmpMatrix);
mNumWrittenViews++;
// If the child has children, push it on the stack to write them next.
if ((flags&ViewNode.FLAGS_HAS_CHILDREN) != 0) {
@@ -374,8 +379,8 @@
}
}
- void writeToParcel(Parcel out, boolean simple) {
- TextUtils.writeToParcel(mText, out, 0);
+ void writeToParcel(Parcel out, boolean simple, boolean writeSensitive) {
+ TextUtils.writeToParcel(writeSensitive ? mText : "", out, 0);
out.writeFloat(mTextSize);
out.writeInt(mTextStyle);
out.writeInt(mTextColor);
@@ -402,7 +407,7 @@
final int mDisplayId;
final ViewNode mRoot;
- WindowNode(AssistStructure assist, ViewRootImpl root, int flags) {
+ WindowNode(AssistStructure assist, ViewRootImpl root, boolean forAutoFill) {
View view = root.getView();
Rect rect = new Rect();
view.getBoundsOnScreen(rect);
@@ -414,19 +419,14 @@
mDisplayId = root.getDisplayId();
mRoot = new ViewNode();
- // Must explicitly call the proper method based on flags since we don't know which
- // method (if any) was overridden by the View subclass.
- boolean forAutoFill = (flags
- & (View.AUTO_FILL_FLAG_TYPE_FILL
- | View.AUTO_FILL_FLAG_TYPE_SAVE)) != 0;
-
- ViewNodeBuilder builder = new ViewNodeBuilder(assist, mRoot, false);
+ ViewNodeBuilder builder = new ViewNodeBuilder(assist, mRoot, false, 0);
if ((root.getWindowFlags()& WindowManager.LayoutParams.FLAG_SECURE) != 0) {
// This is a secure window, so it doesn't want a screenshot, and that
// means we should also not copy out its view hierarchy.
if (forAutoFill) {
- view.onProvideAutoFillStructure(builder, flags);
+ // NOTE: flags are currently not supported, hence 0
+ view.onProvideAutoFillStructure(builder, 0);
} else {
view.onProvideStructure(builder);
}
@@ -434,7 +434,8 @@
return;
}
if (forAutoFill) {
- view.dispatchProvideAutoFillStructure(builder, flags);
+ // NOTE: flags are currently not supported, hence 0
+ view.dispatchProvideAutoFillStructure(builder, 0);
} else {
view.dispatchProvideStructure(builder);
}
@@ -537,6 +538,8 @@
// fields (viewId and childId) of the field.
AutoFillId mAutoFillId;
AutoFillType mAutoFillType;
+ AutoFillValue mAutoFillValue;
+ boolean mSanitized;
int mX;
int mY;
int mScrollX;
@@ -610,8 +613,10 @@
}
}
if ((flags&FLAGS_HAS_AUTO_FILL_DATA) != 0) {
+ mSanitized = in.readInt() == 1;
mAutoFillId = in.readParcelable(null);
mAutoFillType = in.readParcelable(null);
+ mAutoFillValue = in.readParcelable(null);
}
if ((flags&FLAGS_HAS_LARGE_COORDS) != 0) {
mX = in.readInt();
@@ -663,7 +668,11 @@
}
}
- int writeSelfToParcel(Parcel out, PooledStringWriter pwriter, float[] tmpMatrix) {
+ int writeSelfToParcel(Parcel out, PooledStringWriter pwriter, boolean sanitizeOnWrite,
+ float[] tmpMatrix) {
+ // Guard used to skip non-sanitized data when writing for auto-fill.
+ boolean writeSensitive = true;
+
int flags = mFlags & ~FLAGS_ALL_CONTROL;
if (mId != View.NO_ID) {
flags |= FLAGS_HAS_ID;
@@ -716,8 +725,12 @@
}
}
if ((flags&FLAGS_HAS_AUTO_FILL_DATA) != 0) {
+ writeSensitive = mSanitized || !sanitizeOnWrite;
+ out.writeInt(mSanitized ? 1 : 0);
out.writeParcelable(mAutoFillId, 0);
out.writeParcelable(mAutoFillType, 0);
+ final AutoFillValue sanitizedValue = writeSensitive ? mAutoFillValue : null;
+ out.writeParcelable(sanitizedValue, 0);
}
if ((flags&FLAGS_HAS_LARGE_COORDS) != 0) {
out.writeInt(mX);
@@ -746,7 +759,7 @@
TextUtils.writeToParcel(mContentDescription, out, 0);
}
if ((flags&FLAGS_HAS_TEXT) != 0) {
- mText.writeToParcel(out, (flags&FLAGS_HAS_COMPLEX_TEXT) == 0);
+ mText.writeToParcel(out, (flags&FLAGS_HAS_COMPLEX_TEXT) == 0, writeSensitive);
}
if ((flags&FLAGS_HAS_EXTRAS) != 0) {
out.writeBundle(mExtras);
@@ -794,6 +807,7 @@
* <p>It's only set when the {@link AssistStructure} is used for auto-filling purposes, not
* for assist.
*/
+ // TODO(b/33197203, b/33802548): add CTS/unit test
public AutoFillId getAutoFillId() {
return mAutoFillId;
}
@@ -804,11 +818,47 @@
* <p>It's only set when the {@link AssistStructure} is used for auto-filling purposes, not
* for assist.
*/
+ // TODO(b/33197203, b/33802548): add CTS/unit test
public AutoFillType getAutoFillType() {
return mAutoFillType;
}
/**
+ * Gets the the value of this view.
+ *
+ * <p>It's only set when the {@link AssistStructure} is used for auto-filling purposes, not
+ * for assist.
+ */
+ // TODO(b/33197203, b/33802548): add CTS/unit test
+ public AutoFillValue getAutoFillValue() {
+ return mAutoFillValue;
+ }
+
+ /** @hide */
+ public boolean isSanitized() {
+ return mSanitized;
+ }
+
+ /**
+ * Updates the {@link AutoFillValue} of this structure.
+ *
+ * <p>Should be used just before sending the structure to the
+ * {@link android.service.autofill.AutoFillService} for saving, since it will override the
+ * initial value.
+ *
+ * @hide
+ */
+ public void updateAutoFillValue(AutoFillValue value) {
+ mAutoFillValue = value;
+ // TODO(b/33197203, b/33802548): decide whether to set text as well (so it would work
+ // with "legacy" views) or just the auto-fill value
+ final CharSequence text = value.getTextValue();
+ if (text != null) {
+ mText.mText = text;
+ }
+ }
+
+ /**
* Returns the left edge of this view, in pixels, relative to the left edge of its parent.
*/
public int getLeft() {
@@ -1113,10 +1163,11 @@
final ViewNode mNode;
final boolean mAsync;
- ViewNodeBuilder(AssistStructure assist, ViewNode node, boolean async) {
+ ViewNodeBuilder(AssistStructure assist, ViewNode node, boolean async, int flags) {
mAssist = assist;
mNode = node;
mAsync = async;
+ mNode.mSanitized = (flags & AUTO_FILL_FLAG_SANITIZED) != 0;
}
@Override
@@ -1350,19 +1401,20 @@
}
}
- private ViewStructure newChild(int index, boolean forAutoFill, int virtualId) {
+ private ViewStructure newChild(int index, boolean forAutoFill, int virtualId, int flags) {
ViewNode node = new ViewNode();
setAutoFillId(node, forAutoFill, virtualId);
mNode.mChildren[index] = node;
- return new ViewNodeBuilder(mAssist, node, false);
+ return new ViewNodeBuilder(mAssist, node, false, flags);
}
- private ViewStructure asyncNewChild(int index, boolean forAutoFill, int virtualId) {
+ private ViewStructure asyncNewChild(int index, boolean forAutoFill, int virtualId,
+ int flags) {
synchronized (mAssist) {
ViewNode node = new ViewNode();
setAutoFillId(node, forAutoFill, virtualId);
mNode.mChildren[index] = node;
- ViewNodeBuilder builder = new ViewNodeBuilder(mAssist, node, true);
+ ViewNodeBuilder builder = new ViewNodeBuilder(mAssist, node, true, flags);
mAssist.mPendingAsyncChildren.add(builder);
return builder;
}
@@ -1370,22 +1422,23 @@
@Override
public ViewStructure newChild(int index) {
- return newChild(index, false, 0);
+ return newChild(index, false, 0, 0);
}
+ // TODO(b/33197203, b/33802548): add CTS/unit test
@Override
- public ViewStructure newChild(int index, int virtualId) {
- return newChild(index, true, virtualId);
+ public ViewStructure newChild(int index, int virtualId, int flags) {
+ return newChild(index, true, virtualId, flags);
}
@Override
public ViewStructure asyncNewChild(int index) {
- return asyncNewChild(index, false, 0);
+ return asyncNewChild(index, false, 0, 0);
}
@Override
- public ViewStructure asyncNewChild(int index, int virtualId) {
- return asyncNewChild(index, true, virtualId);
+ public ViewStructure asyncNewChild(int index, int virtualId, int flags) {
+ return asyncNewChild(index, true, virtualId, flags);
}
@Override
@@ -1422,17 +1475,29 @@
mNode.mAutoFillType = type;
}
+ @Override
+ public void setAutoFillValue(AutoFillValue value) {
+ mNode.mAutoFillValue = value;
+ }
+
+ /**
+ * @hide
+ */
+ @Override
+ public void setSanitized(boolean sanitized) {
+ mNode.mSanitized = sanitized;
+ }
}
/** @hide */
- public AssistStructure(Activity activity, int flags) {
+ public AssistStructure(Activity activity, boolean forAutoFill) {
mHaveData = true;
mActivityComponent = activity.getComponentName();
ArrayList<ViewRootImpl> views = WindowManagerGlobal.getInstance().getRootViews(
activity.getActivityToken());
for (int i=0; i<views.size(); i++) {
ViewRootImpl root = views.get(i);
- mWindowNodes.add(new WindowNode(this, root, flags));
+ mWindowNodes.add(new WindowNode(this, root, forAutoFill));
}
}
@@ -1446,9 +1511,24 @@
mReceiveChannel = in.readStrongBinder();
}
+ /**
+ * Helper method used to sanitize the structure before it's written to a parcel.
+ *
+ * <p>Used just on auto-fill.
+ * @hide
+ */
+ public void sanitizeForParceling(boolean sanitize) {
+ mSanitizeOnWrite = sanitize;
+ }
+
/** @hide */
public void dump() {
+ if (mActivityComponent == null) {
+ Log.i(TAG, "dump(): calling ensureData() first");
+ ensureData();
+ }
Log.i(TAG, "Activity: " + mActivityComponent.flattenToShortString());
+ Log.i(TAG, "Sanitize on write: " + mSanitizeOnWrite);
final int N = getWindowNodeCount();
for (int i=0; i<N; i++) {
WindowNode node = getWindowNodeAt(i);
@@ -1515,6 +1595,16 @@
if (node.isAssistBlocked()) {
Log.i(TAG, prefix + " BLOCKED");
}
+ AutoFillId autoFillId = node.getAutoFillId();
+ if (autoFillId == null) {
+ Log.i(TAG, prefix + " NO AUTO-FILL ID");
+ } else {
+ Log.i(TAG, prefix + "AutoFill info: id= " + autoFillId
+ + ", type=" + node.getAutoFillType()
+ + ", value=" + node.getAutoFillValue()
+ + ", sanitized=" + node.isSanitized());
+ }
+
final int NCHILDREN = node.getChildCount();
if (NCHILDREN > 0) {
Log.i(TAG, prefix + " Children:");
@@ -1589,10 +1679,12 @@
}
}
+ @Override
public int describeContents() {
return 0;
}
+ @Override
public void writeToParcel(Parcel out, int flags) {
if (mHaveData) {
// This object holds its data. We want to write a send channel that the
@@ -1609,10 +1701,12 @@
public static final Parcelable.Creator<AssistStructure> CREATOR
= new Parcelable.Creator<AssistStructure>() {
+ @Override
public AssistStructure createFromParcel(Parcel in) {
return new AssistStructure(in);
}
+ @Override
public AssistStructure[] newArray(int size) {
return new AssistStructure[size];
}
diff --git a/core/java/android/bluetooth/BluetoothCodecConfig.java b/core/java/android/bluetooth/BluetoothCodecConfig.java
index a482103..176e48f 100644
--- a/core/java/android/bluetooth/BluetoothCodecConfig.java
+++ b/core/java/android/bluetooth/BluetoothCodecConfig.java
@@ -37,9 +37,11 @@
public static final int SOURCE_CODEC_TYPE_APTX = 2;
public static final int SOURCE_CODEC_TYPE_APTX_HD = 3;
public static final int SOURCE_CODEC_TYPE_LDAC = 4;
+ public static final int SOURCE_CODEC_TYPE_MAX = 5;
public static final int SOURCE_CODEC_TYPE_INVALID = 1000 * 1000;
+ public static final int CODEC_PRIORITY_DISABLED = -1;
public static final int CODEC_PRIORITY_DEFAULT = 0;
public static final int CODEC_PRIORITY_HIGHEST = 1000 * 1000;
@@ -72,7 +74,7 @@
public BluetoothCodecConfig(int codecType, int codecPriority,
int sampleRate, int bitsPerSample,
- int channelMode,long codecSpecific1,
+ int channelMode, long codecSpecific1,
long codecSpecific2, long codecSpecific3,
long codecSpecific4) {
mCodecType = codecType;
diff --git a/core/java/android/bluetooth/le/ScanFilter.java b/core/java/android/bluetooth/le/ScanFilter.java
index 17a802d..b89c64a 100644
--- a/core/java/android/bluetooth/le/ScanFilter.java
+++ b/core/java/android/bluetooth/le/ScanFilter.java
@@ -67,7 +67,9 @@
private final byte[] mManufacturerData;
@Nullable
private final byte[] mManufacturerDataMask;
- private static final ScanFilter EMPTY = new ScanFilter.Builder().build() ;
+
+ /** @hide */
+ public static final ScanFilter EMPTY = new ScanFilter.Builder().build() ;
private ScanFilter(String name, String deviceAddress, ParcelUuid uuid,
@@ -318,8 +320,12 @@
return true;
}
- // Check if the uuid pattern is contained in a list of parcel uuids.
- private boolean matchesServiceUuids(ParcelUuid uuid, ParcelUuid parcelUuidMask,
+ /**
+ * Check if the uuid pattern is contained in a list of parcel uuids.
+ *
+ * @hide
+ */
+ public static boolean matchesServiceUuids(ParcelUuid uuid, ParcelUuid parcelUuidMask,
List<ParcelUuid> uuids) {
if (uuid == null) {
return true;
@@ -338,7 +344,7 @@
}
// Check if the uuid pattern matches the particular service uuid.
- private boolean matchesServiceUuid(UUID uuid, UUID mask, UUID data) {
+ private static boolean matchesServiceUuid(UUID uuid, UUID mask, UUID data) {
if (mask == null) {
return uuid.equals(data);
}
diff --git a/wifi/java/android/net/wifi/hotspot2/pps/HomeSP.aidl b/core/java/android/companion/AssociationRequest.aidl
similarity index 74%
copy from wifi/java/android/net/wifi/hotspot2/pps/HomeSP.aidl
copy to core/java/android/companion/AssociationRequest.aidl
index 62d5603..6c91062 100644
--- a/wifi/java/android/net/wifi/hotspot2/pps/HomeSP.aidl
+++ b/core/java/android/companion/AssociationRequest.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2016, The Android Open Source Project
+/*
+ * Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * 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,
@@ -14,6 +14,6 @@
* limitations under the License.
*/
-package android.net.wifi.hotspot2.pps;
+package android.companion;
-parcelable HomeSP;
+parcelable AssociationRequest;
diff --git a/core/java/android/companion/AssociationRequest.java b/core/java/android/companion/AssociationRequest.java
new file mode 100644
index 0000000..d477f43
--- /dev/null
+++ b/core/java/android/companion/AssociationRequest.java
@@ -0,0 +1,191 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.companion;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.provider.OneTimeUseBuilder;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * A request for the user to select a companion device to associate with.
+ *
+ * You can optionally set a {@link Builder#setDeviceFilter filter} for which devices to show to the
+ * user to select from.
+ * The exact type and fields of the filter you can set depend on the
+ * medium type. See {@link Builder}'s static factory methods for specific protocols that are
+ * supported.
+ *
+ * You can also set {@link Builder#setSingleDevice single device} to request a popup with single
+ * device to be shown instead of a list to choose from
+ *
+ * @param <F> Device filter type
+ */
+public final class AssociationRequest<F extends DeviceFilter> implements Parcelable {
+
+ /** @hide */
+ public static final int MEDIUM_TYPE_BLUETOOTH = 0;
+ /** @hide */
+ public static final int MEDIUM_TYPE_BLUETOOTH_LE = 1;
+ /** @hide */
+ public static final int MEDIUM_TYPE_WIFI = 2;
+
+ /** @hide */
+ @IntDef({MEDIUM_TYPE_BLUETOOTH, MEDIUM_TYPE_BLUETOOTH_LE, MEDIUM_TYPE_WIFI})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface MediumType {}
+
+ private final boolean mSingleDevice;
+ private final int mMediumType;
+ private final F mDeviceFilter;
+
+ private AssociationRequest(boolean singleDevice, int mMediumType, F deviceFilter) {
+ this.mSingleDevice = singleDevice;
+ this.mMediumType = mMediumType;
+ this.mDeviceFilter = deviceFilter;
+ }
+
+ private AssociationRequest(Parcel in) {
+ this(
+ in.readByte() != 0,
+ in.readInt(),
+ in.readParcelable(AssociationRequest.class.getClassLoader()));
+ }
+
+ /** @hide */
+ public boolean isSingleDevice() {
+ return mSingleDevice;
+ }
+
+ /** @hide */
+ @MediumType
+ public int getMediumType() {
+ return mMediumType;
+ }
+
+ /** @hide */
+ @Nullable
+ public F getDeviceFilter() {
+ return mDeviceFilter;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeByte((byte) (mSingleDevice ? 1 : 0));
+ dest.writeInt(mMediumType);
+ dest.writeParcelable(mDeviceFilter, flags);
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ public static final Creator<AssociationRequest> CREATOR = new Creator<AssociationRequest>() {
+ @Override
+ public AssociationRequest createFromParcel(Parcel in) {
+ return new AssociationRequest(in);
+ }
+
+ @Override
+ public AssociationRequest[] newArray(int size) {
+ return new AssociationRequest[size];
+ }
+ };
+
+ /**
+ * A builder for {@link AssociationRequest}
+ *
+ * @param <F> the type of filter for the request.
+ */
+ public static final class Builder<F extends DeviceFilter>
+ extends OneTimeUseBuilder<AssociationRequest<F>> {
+ private boolean mSingleDevice = false;
+ @MediumType private int mMediumType;
+ @Nullable private F mDeviceFilter = null;
+
+ private Builder() {}
+
+ /**
+ * Create a new builder for an association request with a Bluetooth LE device
+ */
+ @NonNull
+ public static Builder<BluetoothLEDeviceFilter> createForBluetoothLEDevice() {
+ return new Builder<BluetoothLEDeviceFilter>()
+ .setMediumType(MEDIUM_TYPE_BLUETOOTH_LE);
+ }
+
+ /**
+ * Create a new builder for an association request with a Bluetooth(non-LE) device
+ */
+ @NonNull
+ public static Builder<BluetoothDeviceFilter> createForBluetoothDevice() {
+ return new Builder<BluetoothDeviceFilter>()
+ .setMediumType(MEDIUM_TYPE_BLUETOOTH);
+ }
+
+ //TODO implement, once specific filter classes are available
+// public static Builder<> createForWiFiDevice()
+// public static Builder<> createForNanDevice()
+
+ /**
+ * @param singleDevice if true, scanning for a device will stop as soon as at least one
+ * fitting device is found
+ */
+ @NonNull
+ public Builder<F> setSingleDevice(boolean singleDevice) {
+ checkNotUsed();
+ this.mSingleDevice = singleDevice;
+ return this;
+ }
+
+ /**
+ * @param deviceFilter if set, only devices matching the given filter will be shown to the
+ * user
+ */
+ @NonNull
+ public Builder<F> setDeviceFilter(@Nullable F deviceFilter) {
+ checkNotUsed();
+ this.mDeviceFilter = deviceFilter;
+ return this;
+ }
+
+ /**
+ * @param deviceType A type of medium over which to discover devices
+ *
+ * @see MediumType
+ */
+ @NonNull
+ private Builder<F> setMediumType(@MediumType int deviceType) {
+ mMediumType = deviceType;
+ return this;
+ }
+
+ /** @inheritDoc */
+ @NonNull
+ @Override
+ public AssociationRequest<F> build() {
+ markUsed();
+ return new AssociationRequest<>(mSingleDevice, mMediumType, mDeviceFilter);
+ }
+ }
+}
diff --git a/core/java/android/companion/BluetoothDeviceFilter.java b/core/java/android/companion/BluetoothDeviceFilter.java
new file mode 100644
index 0000000..5a69955
--- /dev/null
+++ b/core/java/android/companion/BluetoothDeviceFilter.java
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.companion;
+
+import static android.companion.BluetoothDeviceFilterUtils.matchesAddress;
+import static android.companion.BluetoothDeviceFilterUtils.matchesName;
+import static android.companion.BluetoothDeviceFilterUtils.matchesServiceUuids;
+import static android.companion.BluetoothDeviceFilterUtils.patternFromString;
+import static android.companion.BluetoothDeviceFilterUtils.patternToString;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.bluetooth.BluetoothDevice;
+import android.os.Parcel;
+import android.os.ParcelUuid;
+import android.provider.OneTimeUseBuilder;
+
+import com.android.internal.util.ArrayUtils;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Pattern;
+
+/**
+ * A filter for Bluetooth(non-LE) devices
+ */
+public final class BluetoothDeviceFilter implements DeviceFilter<BluetoothDevice> {
+
+ private static BluetoothDeviceFilter NO_OP;
+
+ private final Pattern mNamePattern;
+ private final String mAddress;
+ private final List<ParcelUuid> mServiceUuids;
+ private final List<ParcelUuid> mServiceUuidMasks;
+
+ private BluetoothDeviceFilter(
+ Pattern namePattern,
+ String address,
+ List<ParcelUuid> serviceUuids,
+ List<ParcelUuid> serviceUuidMasks) {
+ mNamePattern = namePattern;
+ mAddress = address;
+ mServiceUuids = ArrayUtils.emptyIfNull(serviceUuids);
+ mServiceUuidMasks = ArrayUtils.emptyIfNull(serviceUuidMasks);
+ }
+
+ private BluetoothDeviceFilter(Parcel in) {
+ this(
+ patternFromString(in.readString()),
+ in.readString(),
+ readUuids(in),
+ readUuids(in));
+ }
+
+ private static List<ParcelUuid> readUuids(Parcel in) {
+ final ArrayList<ParcelUuid> list = new ArrayList<>();
+ in.readParcelableList(list, ParcelUuid.class.getClassLoader());
+ return list;
+ }
+
+ /** @hide */
+ @NonNull
+ public static BluetoothDeviceFilter nullsafe(@Nullable BluetoothDeviceFilter nullable) {
+ return nullable != null ? nullable : noOp();
+ }
+
+ /** @hide */
+ @NonNull
+ public static BluetoothDeviceFilter noOp() {
+ if (NO_OP == null) NO_OP = new Builder().build();
+ return NO_OP;
+ }
+
+ /** @hide */
+ @Override
+ public boolean matches(BluetoothDevice device) {
+ return matchesAddress(mAddress, device)
+ && matchesServiceUuids(mServiceUuids, mServiceUuidMasks, device)
+ && matchesName(getNamePattern(), device);
+ }
+
+ /** @hide */
+ @Nullable
+ public Pattern getNamePattern() {
+ return mNamePattern;
+ }
+
+ /** @hide */
+ @Nullable
+ public String getAddress() {
+ return mAddress;
+ }
+
+ /** @hide */
+ @NonNull
+ public List<ParcelUuid> getServiceUuids() {
+ return mServiceUuids;
+ }
+
+ /** @hide */
+ @NonNull
+ public List<ParcelUuid> getServiceUuidMasks() {
+ return mServiceUuidMasks;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeString(patternToString(getNamePattern()));
+ dest.writeString(mAddress);
+ dest.writeParcelableList(mServiceUuids, flags);
+ dest.writeParcelableList(mServiceUuidMasks, flags);
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ public static final Creator<BluetoothDeviceFilter> CREATOR
+ = new Creator<BluetoothDeviceFilter>() {
+ @Override
+ public BluetoothDeviceFilter createFromParcel(Parcel in) {
+ return new BluetoothDeviceFilter(in);
+ }
+
+ @Override
+ public BluetoothDeviceFilter[] newArray(int size) {
+ return new BluetoothDeviceFilter[size];
+ }
+ };
+
+ /**
+ * A builder for {@link BluetoothDeviceFilter}
+ */
+ public static final class Builder extends OneTimeUseBuilder<BluetoothDeviceFilter> {
+ private Pattern mNamePattern;
+ private String mAddress;
+ private ArrayList<ParcelUuid> mServiceUuid;
+ private ArrayList<ParcelUuid> mServiceUuidMask;
+
+ /**
+ * @param regex if set, only devices with {@link BluetoothDevice#getName name} matching the
+ * given regular expression will be shown
+ */
+ public Builder setNamePattern(@Nullable Pattern regex) {
+ checkNotUsed();
+ mNamePattern = regex;
+ return this;
+ }
+
+ /**
+ * @param address if set, only devices with MAC address exactly matching the given one will
+ * pass the filter
+ */
+ @NonNull
+ public Builder setAddress(@Nullable String address) {
+ checkNotUsed();
+ mAddress = address;
+ return this;
+ }
+
+ /**
+ * Add filtering by certain bits of {@link BluetoothDevice#getUuids()}
+ *
+ * A device with any uuid matching the given bits is considered passing
+ *
+ * @param serviceUuid the values for the bits to match
+ * @param serviceUuidMask if provided, only those bits would have to match.
+ */
+ @NonNull
+ public Builder addServiceUuid(
+ @Nullable ParcelUuid serviceUuid, @Nullable ParcelUuid serviceUuidMask) {
+ checkNotUsed();
+ mServiceUuid = ArrayUtils.add(mServiceUuid, serviceUuid);
+ mServiceUuidMask = ArrayUtils.add(mServiceUuidMask, serviceUuidMask);
+ return this;
+ }
+
+ /** @inheritDoc */
+ @Override
+ @NonNull
+ public BluetoothDeviceFilter build() {
+ markUsed();
+ return new BluetoothDeviceFilter(
+ mNamePattern, mAddress, mServiceUuid, mServiceUuidMask);
+ }
+ }
+}
diff --git a/core/java/android/companion/BluetoothDeviceFilterUtils.java b/core/java/android/companion/BluetoothDeviceFilterUtils.java
new file mode 100644
index 0000000..289f995
--- /dev/null
+++ b/core/java/android/companion/BluetoothDeviceFilterUtils.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package android.companion;
+
+import static android.text.TextUtils.firstNotEmpty;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.le.ScanFilter;
+import android.os.ParcelUuid;
+import android.util.Log;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.regex.Pattern;
+
+/** @hide */
+public class BluetoothDeviceFilterUtils {
+ private BluetoothDeviceFilterUtils() {}
+
+ private static final boolean DEBUG = false;
+ private static final String LOG_TAG = "BluetoothDeviceFilterUtil";
+
+ @Nullable
+ static String patternToString(@Nullable Pattern p) {
+ return p == null ? null : p.pattern();
+ }
+
+ @Nullable
+ static Pattern patternFromString(@Nullable String s) {
+ return s == null ? null : Pattern.compile(s);
+ }
+
+ static boolean matches(ScanFilter filter, BluetoothDevice device) {
+ return matchesAddress(filter.getDeviceAddress(), device)
+ && matchesServiceUuid(filter.getServiceUuid(), filter.getServiceUuidMask(), device);
+ }
+
+ static boolean matchesAddress(String deviceAddress, BluetoothDevice device) {
+ final boolean result = deviceAddress == null
+ || (device == null || !deviceAddress.equals(device.getAddress()));
+ if (DEBUG) debugLogMatchResult(result, device, deviceAddress);
+ return result;
+ }
+
+ static boolean matchesServiceUuids(List<ParcelUuid> serviceUuids,
+ List<ParcelUuid> serviceUuidMasks, BluetoothDevice device) {
+ for (int i = 0; i < serviceUuids.size(); i++) {
+ ParcelUuid uuid = serviceUuids.get(i);
+ ParcelUuid uuidMask = serviceUuidMasks.get(i);
+ if (!matchesServiceUuid(uuid, uuidMask, device)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ static boolean matchesServiceUuid(ParcelUuid serviceUuid, ParcelUuid serviceUuidMask,
+ BluetoothDevice device) {
+ final boolean result = serviceUuid == null ||
+ ScanFilter.matchesServiceUuids(
+ serviceUuid,
+ serviceUuidMask,
+ Arrays.asList(device.getUuids()));
+ if (DEBUG) debugLogMatchResult(result, device, serviceUuid);
+ return result;
+ }
+
+ static boolean matchesName(@Nullable Pattern namePattern, BluetoothDevice device) {
+ boolean result;
+ if (namePattern == null) {
+ result = true;
+ } else if (device == null) {
+ result = false;
+ } else {
+ final String name = device.getName();
+ result = name != null && namePattern.matcher(name).find();
+ }
+ if (DEBUG) debugLogMatchResult(result, device, namePattern);
+ return result;
+ }
+
+ private static void debugLogMatchResult(
+ boolean result, BluetoothDevice device, Object criteria) {
+ Log.i(LOG_TAG, getDeviceDisplayName(device) + (result ? " ~ " : " !~ ") + criteria);
+ }
+
+ public static String getDeviceDisplayName(@NonNull BluetoothDevice device) {
+ return firstNotEmpty(device.getAliasName(), device.getAddress());
+ }
+}
diff --git a/wifi/java/android/net/wifi/hotspot2/pps/HomeSP.aidl b/core/java/android/companion/BluetoothLEDeviceFilter.aidl
similarity index 74%
copy from wifi/java/android/net/wifi/hotspot2/pps/HomeSP.aidl
copy to core/java/android/companion/BluetoothLEDeviceFilter.aidl
index 62d5603..628cf7b 100644
--- a/wifi/java/android/net/wifi/hotspot2/pps/HomeSP.aidl
+++ b/core/java/android/companion/BluetoothLEDeviceFilter.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2016, The Android Open Source Project
+/*
+ * Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * 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,
@@ -14,6 +14,6 @@
* limitations under the License.
*/
-package android.net.wifi.hotspot2.pps;
+package android.companion;
-parcelable HomeSP;
+parcelable BluetoothLEDeviceFilter;
diff --git a/core/java/android/companion/BluetoothLEDeviceFilter.java b/core/java/android/companion/BluetoothLEDeviceFilter.java
new file mode 100644
index 0000000..4a481ca
--- /dev/null
+++ b/core/java/android/companion/BluetoothLEDeviceFilter.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.companion;
+
+import static android.companion.BluetoothDeviceFilterUtils.patternFromString;
+import static android.companion.BluetoothDeviceFilterUtils.patternToString;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SuppressLint;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.le.ScanFilter;
+import android.os.Parcel;
+import android.provider.OneTimeUseBuilder;
+
+import com.android.internal.util.ObjectUtils;
+
+import java.util.regex.Pattern;
+
+/**
+ * A filter for Bluetooth LE devices
+ *
+ * @see ScanFilter
+ */
+public final class BluetoothLEDeviceFilter implements DeviceFilter<BluetoothDevice> {
+
+ private static BluetoothLEDeviceFilter NO_OP;
+
+ private final Pattern mNamePattern;
+ private final ScanFilter mScanFilter;
+
+ private BluetoothLEDeviceFilter(Pattern namePattern, ScanFilter scanFilter) {
+ mNamePattern = namePattern;
+ mScanFilter = ObjectUtils.firstNotNull(scanFilter, ScanFilter.EMPTY);
+ }
+
+ @SuppressLint("ParcelClassLoader")
+ private BluetoothLEDeviceFilter(Parcel in) {
+ this(
+ patternFromString(in.readString()),
+ in.readParcelable(null));
+ }
+
+ /** @hide */
+ @NonNull
+ public static BluetoothLEDeviceFilter nullsafe(@Nullable BluetoothLEDeviceFilter nullable) {
+ return nullable != null ? nullable : noOp();
+ }
+
+ /** @hide */
+ @NonNull
+ public static BluetoothLEDeviceFilter noOp() {
+ if (NO_OP == null) NO_OP = new Builder().build();
+ return NO_OP;
+ }
+
+ /** @hide */
+ @Nullable
+ public Pattern getNamePattern() {
+ return mNamePattern;
+ }
+
+ /** @hide */
+ @NonNull
+ public ScanFilter getScanFilter() {
+ return mScanFilter;
+ }
+
+ /** @hide */
+ @Override
+ public boolean matches(BluetoothDevice device) {
+ return BluetoothDeviceFilterUtils.matches(getScanFilter(), device)
+ && BluetoothDeviceFilterUtils.matchesName(getNamePattern(), device);
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeString(patternToString(getNamePattern()));
+ dest.writeParcelable(mScanFilter, flags);
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ public static final Creator<BluetoothLEDeviceFilter> CREATOR
+ = new Creator<BluetoothLEDeviceFilter>() {
+ @Override
+ public BluetoothLEDeviceFilter createFromParcel(Parcel in) {
+ return new BluetoothLEDeviceFilter(in);
+ }
+
+ @Override
+ public BluetoothLEDeviceFilter[] newArray(int size) {
+ return new BluetoothLEDeviceFilter[size];
+ }
+ };
+
+ /**
+ * Builder for {@link BluetoothLEDeviceFilter}
+ */
+ public static final class Builder extends OneTimeUseBuilder<BluetoothLEDeviceFilter> {
+ private ScanFilter mScanFilter;
+ private Pattern mNamePattern;
+
+ /**
+ * @param regex if set, only devices with {@link BluetoothDevice#getName name} matching the
+ * given regular expression will be shown
+ */
+ public Builder setNamePattern(@Nullable Pattern regex) {
+ checkNotUsed();
+ mNamePattern = regex;
+ return this;
+ }
+
+ /**
+ * @param scanFilter a {@link ScanFilter} to filter devices by
+ *
+ * @see ScanFilter for specific details on its various fields
+ */
+ @NonNull
+ public Builder setScanFilter(@Nullable ScanFilter scanFilter) {
+ checkNotUsed();
+ mScanFilter = scanFilter;
+ return this;
+ }
+
+ /** @inheritDoc */
+ @Override
+ @NonNull
+ public BluetoothLEDeviceFilter build() {
+ markUsed();
+ return new BluetoothLEDeviceFilter(mNamePattern, mScanFilter);
+ }
+ }
+}
diff --git a/core/java/android/companion/CompanionDeviceManager.java b/core/java/android/companion/CompanionDeviceManager.java
new file mode 100644
index 0000000..b379c7c
--- /dev/null
+++ b/core/java/android/companion/CompanionDeviceManager.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.companion;
+
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.IntentSender;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.RemoteException;
+
+/**
+ * System level service for managing companion devices
+ *
+ * Usage:
+ * To obtain an instance call
+ * {@link Context#getSystemService}({@link Context#COMPANION_DEVICE_SERVICE})
+ *
+ * Then, call {@link #associate} to initiate the flow of associating current package
+ * with a device selected by user
+ *
+ * @see AssociationRequest
+ */
+public final class CompanionDeviceManager {
+
+ /**
+ * A device, returned in the activity result of the {@link IntentSender} received in
+ * {@link Callback#onDeviceFound}
+ */
+ public static final String EXTRA_DEVICE = "android.companion.extra.DEVICE";
+
+ /**
+ * A callback to receive once at least one suitable device is found, or the search failed
+ * (e.g. timed out)
+ */
+ public abstract static class Callback {
+
+ /**
+ * Called once at least one suitable device is found
+ *
+ * @param chooserLauncher a {@link IntentSender} to launch the UI for user to select a
+ * device
+ */
+ public abstract void onDeviceFound(IntentSender chooserLauncher);
+
+ /**
+ * Called if there was an error looking for device(s), e.g. timeout
+ *
+ * @param error the cause of the error
+ */
+ public abstract void onFailure(CharSequence error);
+ }
+
+ private final ICompanionDeviceManager mService;
+ private final Context mContext;
+
+ /** @hide */
+ public CompanionDeviceManager(
+ @NonNull ICompanionDeviceManager service, @NonNull Context context) {
+ mService = service;
+ mContext = context;
+ }
+
+ /**
+ * Associate this app with a companion device, selected by user
+ *
+ * Once at least one appropriate device is found, {@code callback} will be called with a
+ * {@link PendingIntent} that can be used to show the list of available devices for the user
+ * to select.
+ * It should be started for result (i.e. using
+ * {@link android.app.Activity#startIntentSenderForResult}), as the resulting
+ * {@link android.content.Intent} will contain extra {@link #EXTRA_DEVICE}, with the selected
+ * device. (e.g. {@link android.bluetooth.BluetoothDevice})
+ *
+ * @param request specific details about this request
+ * @param callback will be called once there's at least one device found for user to choose from
+ * @param handler A handler to control which thread the callback will be delivered on, or null,
+ * to deliver it on main thread
+ *
+ * @see AssociationRequest
+ */
+ public void associate(
+ @NonNull AssociationRequest<?> request,
+ @NonNull Callback callback,
+ @Nullable Handler handler) {
+ final Handler finalHandler = handler != null
+ ? handler
+ : new Handler(Looper.getMainLooper());
+ try {
+ mService.associate(
+ request,
+ new IOnAssociateCallback.Stub() {
+
+ @Override
+ public void onSuccess(PendingIntent launcher) throws RemoteException {
+ finalHandler.post(() -> {
+ callback.onDeviceFound(launcher.getIntentSender());
+ });
+ }
+
+ @Override
+ public void onFailure(CharSequence reason) throws RemoteException {
+ finalHandler.post(() -> callback.onFailure(reason));
+ }
+ },
+ mContext.getPackageName());
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /** @hide */
+ public void requestNotificationAccess() {
+ //TODO implement
+ throw new UnsupportedOperationException("Not yet implemented");
+ }
+
+ /** @hide */
+ public boolean haveNotificationAccess() {
+ //TODO implement
+ throw new UnsupportedOperationException("Not yet implemented");
+ }
+
+}
diff --git a/core/java/android/companion/DeviceFilter.java b/core/java/android/companion/DeviceFilter.java
new file mode 100644
index 0000000..8362b2d
--- /dev/null
+++ b/core/java/android/companion/DeviceFilter.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package android.companion;
+
+import android.annotation.Nullable;
+import android.os.Parcelable;
+
+/**
+ * A filter for companion devices of type {@code D}
+ *
+ * @param <D> Type of devices, filtered by this filter,
+ * e.g. {@link android.bluetooth.BluetoothDevice}, {@link android.net.wifi.WifiInfo}
+ */
+public interface DeviceFilter<D extends Parcelable> extends Parcelable {
+
+ /**
+ * @return whether the given device matches this filter
+ *
+ * @hide
+ */
+ boolean matches(D device);
+
+ /**
+ * A nullsafe {@link #matches(Parcelable)}, returning true if the filter is null
+ *
+ * @hide
+ */
+ static <D extends Parcelable> boolean matches(@Nullable DeviceFilter<D> filter, D device) {
+ return filter == null || filter.matches(device);
+ }
+}
diff --git a/core/java/android/companion/ICompanionDeviceManager.aidl b/core/java/android/companion/ICompanionDeviceManager.aidl
new file mode 100644
index 0000000..065e31b
--- /dev/null
+++ b/core/java/android/companion/ICompanionDeviceManager.aidl
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.companion;
+
+import android.companion.IOnAssociateCallback;
+import android.companion.AssociationRequest;
+
+/**
+ * Interface for communication with the core companion device manager service.
+ *
+ * @hide
+ */
+interface ICompanionDeviceManager {
+ void associate(in AssociationRequest request,
+ in IOnAssociateCallback callback,
+ in String callingPackage); //TODO int userId?
+
+ //TODO add these
+// boolean haveNotificationAccess(String packageName);
+// oneway void requestNotificationAccess(String packageName);
+}
diff --git a/core/java/android/service/autofill/CallbackHelper.java b/core/java/android/companion/ICompanionDeviceManagerService.aidl
similarity index 65%
copy from core/java/android/service/autofill/CallbackHelper.java
copy to core/java/android/companion/ICompanionDeviceManagerService.aidl
index ded8f97..ff2a7eb 100644
--- a/core/java/android/service/autofill/CallbackHelper.java
+++ b/core/java/android/companion/ICompanionDeviceManagerService.aidl
@@ -13,18 +13,17 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package android.service.autofill;
-import java.io.PrintWriter;
+package android.companion;
-final class CallbackHelper {
+import android.companion.AssociationRequest;
+import android.companion.IOnAssociateCallback;
- static interface Dumpable {
- void dump(String prefix, PrintWriter pw);
- void setFinalizer(Finalizer f);
- }
- static interface Finalizer {
- void gone();
- }
+/** @hide */
+interface ICompanionDeviceManagerService {
+ void startDiscovery(
+ in AssociationRequest request,
+ in IOnAssociateCallback callback,
+ in String callingPackage);
}
diff --git a/core/java/android/service/autofill/CallbackHelper.java b/core/java/android/companion/ICompanionDeviceManagerServiceCallback.aidl
similarity index 60%
copy from core/java/android/service/autofill/CallbackHelper.java
copy to core/java/android/companion/ICompanionDeviceManagerServiceCallback.aidl
index ded8f97..c9dd345 100644
--- a/core/java/android/service/autofill/CallbackHelper.java
+++ b/core/java/android/companion/ICompanionDeviceManagerServiceCallback.aidl
@@ -10,21 +10,15 @@
* 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
+ * See the License for the specific language governing per missions and
* limitations under the License.
*/
-package android.service.autofill;
-import java.io.PrintWriter;
+package android.companion;
-final class CallbackHelper {
+import android.bluetooth.BluetoothDevice;
- static interface Dumpable {
- void dump(String prefix, PrintWriter pw);
- void setFinalizer(Finalizer f);
- }
-
- static interface Finalizer {
- void gone();
- }
+/** @hide */
+interface ICompanionDeviceManagerServiceCallback {
+ void onDeviceSelected(in BluetoothDevice device);
}
diff --git a/core/java/android/service/autofill/CallbackHelper.java b/core/java/android/companion/IOnAssociateCallback.aidl
similarity index 60%
copy from core/java/android/service/autofill/CallbackHelper.java
copy to core/java/android/companion/IOnAssociateCallback.aidl
index ded8f97..4867eadd 100644
--- a/core/java/android/service/autofill/CallbackHelper.java
+++ b/core/java/android/companion/IOnAssociateCallback.aidl
@@ -10,21 +10,16 @@
* 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
+ * See the License for the specific language governing per missions and
* limitations under the License.
*/
-package android.service.autofill;
-import java.io.PrintWriter;
+package android.companion;
-final class CallbackHelper {
+import android.app.PendingIntent;
- static interface Dumpable {
- void dump(String prefix, PrintWriter pw);
- void setFinalizer(Finalizer f);
- }
-
- static interface Finalizer {
- void gone();
- }
+/** @hide */
+interface IOnAssociateCallback {
+ void onSuccess(in PendingIntent launcher);
+ void onFailure(in CharSequence reason);
}
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index f610a29..06f7303 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -35,6 +35,7 @@
import android.app.IApplicationThread;
import android.app.IServiceConnection;
import android.app.Notification;
+import android.app.VrManager;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.res.AssetManager;
@@ -3599,6 +3600,14 @@
public static final String PRINT_SERVICE = "print";
/**
+ * {@link android.companion.CompanionDeviceManager} for managing companion devices
+ *
+ * @see #getSystemService
+ * @see android.companion.CompanionDeviceManager
+ */
+ public static final String COMPANION_DEVICE_SERVICE = "companion_device";
+
+ /**
* Use with {@link #getSystemService} to retrieve a
* {@link android.hardware.ConsumerIrManager} for transmitting infrared
* signals from the device.
@@ -3764,6 +3773,16 @@
public static final String OVERLAY_SERVICE = "overlay";
/**
+ * Use with {@link #getSystemService} to retrieve a
+ * {@link VrManager} for accessing the VR service.
+ *
+ * @see #getSystemService
+ * @hide
+ */
+ @SystemApi
+ public static final String VR_SERVICE = "vrmanager";
+
+ /**
* Determine whether the given permission is allowed for a particular
* process and user ID running in the system.
*
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 6a0da33..6a8141f 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -669,7 +669,14 @@
* preview. {@link #getClipData} contains an optional list of content URIs
* if there is more than one item to preview. {@link #EXTRA_INDEX} is an
* optional index of the URI in the clip data to show first.
+ * If {@link #EXTRA_QUICK_VIEW_PLAIN} is true, then the quick viewer should show
+ * basic UI without any extra features other than quick viewing the passed items.
+ * Especially, the quick viewer should not let users open the passed files
+ * in other apps, which includes sharing, opening, editing, printing, etc in the
+ * plain mode.
* <p>Output: nothing.
+ * @see #EXTRA_QUICK_VIEW_HIDE_DEFAULT_ACTIONS
+ * @see #EXTRA_INDEX
*/
@SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
public static final String ACTION_QUICK_VIEW = "android.intent.action.QUICK_VIEW";
@@ -1799,6 +1806,41 @@
@SystemApi
public static final String EXTRA_PERMISSION_NAME = "android.intent.extra.PERMISSION_NAME";
+ /**
+ * Intent extra: An id if an autofill item ({@link
+ * android.view.autofill.Dataset} or {@link android.view.autofill.FillResponse}).
+ * <p>
+ * Type: String
+ * </p>
+ */
+ public static final String EXTRA_AUTO_FILL_ITEM_ID = "android.intent.extra.AUTO_FILL_ITEM_ID";
+
+ /**
+ * Intent extra: The assist structure which captures the filled screen.
+ * <p>
+ * Type: {@link android.app.assist.AssistStructure}
+ * </p>
+ */
+ public static final String EXTRA_AUTO_FILL_ASSIST_STRUCTURE =
+ "android.intent.extra.AUTO_FILL_ASSIST_STRUCTURE";
+
+ /**
+ * Intent extra: The metadata associated with the authenticated entity ({@link
+ * android.view.autofill.Dataset} or {@link android.view.autofill.FillResponse}).
+ * <p>
+ * Type: {@link android.os.Bundle}
+ * </p>
+ */
+ public static final String EXTRA_AUTO_FILL_EXTRAS = "android.intent.extra.AUTO_FILL_EXTRAS";
+
+ /**
+ * Intent extra: A callback to report an authentication result.
+ * <p>
+ * Type: {@link android.view.autofill.FillResponse}
+ * </p>
+ */
+ public static final String EXTRA_AUTO_FILL_CALLBACK = "android.intent.extra.AUTO_FILL_CALLBACK";
+
// ---------------------------------------------------------------------
// ---------------------------------------------------------------------
// Standard intent broadcast actions (see action variable).
@@ -4401,10 +4443,26 @@
* Optional index with semantics depending on the intent action.
*
* <p>The value must be an integer greater or equal to 0.
+ * @see ACTION_QUICK_VIEW
*/
public static final String EXTRA_INDEX = "android.intent.extra.INDEX";
/**
+ * Shows a plain quick viewer UI which doesn't provide any extra features other than
+ * quick viewing the items.
+ *
+ * <p>Especially, the quick viewer should not let users open the quick viewed files
+ * in other apps, which includes sharing, opening, editing, printing, etc.
+ *
+ * <p>This feature is optional, and may not be handled by all quick viewers.
+ *
+ * <p>The value is boolean. By default false.
+ * @see ACTION_QUICK_VIEW
+ */
+ public static final String EXTRA_QUICK_VIEW_PLAIN =
+ "android.intent.extra.QUICK_VIEW_PLAIN";
+
+ /**
* Optional boolean extra indicating whether quiet mode has been switched on or off.
* When a profile goes into quiet mode, all apps in the profile are killed and the
* profile user is stopped. Widgets originating from the profile are masked, and app
diff --git a/core/java/android/content/SyncRequest.java b/core/java/android/content/SyncRequest.java
index dd53eac..74d2f11 100644
--- a/core/java/android/content/SyncRequest.java
+++ b/core/java/android/content/SyncRequest.java
@@ -351,7 +351,7 @@
* @param requiresCharging true if sync requires the phone to be plugged in. Default false.
*/
public Builder setRequiresCharging(boolean requiresCharging) {
- mRequiresCharging = true;
+ mRequiresCharging = requiresCharging;
return this;
}
diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java
index 92cb709..9a8eff0 100644
--- a/core/java/android/content/pm/ActivityInfo.java
+++ b/core/java/android/content/pm/ActivityInfo.java
@@ -397,14 +397,6 @@
public static final int FLAG_ALWAYS_FOCUSABLE = 0x40000;
/**
- * Bit in {@link #flags} indicating if the activity is a launcher activity which should always
- * show up on the top of others.
- * See android.R.attr#onTopLauncher.
- * @hide
- */
- public static final int FLAG_ON_TOP_LAUNCHER = 0x80000;
-
- /**
* Bit in {@link #flags} indicating if the activity is visible to ephemeral applications.
* @hide
*/
diff --git a/core/java/android/content/pm/InstrumentationInfo.java b/core/java/android/content/pm/InstrumentationInfo.java
index a135d8f..59c5307 100644
--- a/core/java/android/content/pm/InstrumentationInfo.java
+++ b/core/java/android/content/pm/InstrumentationInfo.java
@@ -34,6 +34,13 @@
public String targetPackage;
/**
+ * Names of the process(es) this instrumentation will run in. If not specified, only
+ * runs in the main process of the targetPackage. Can either be a comma-separated list
+ * of process names or '*' for any process that launches to run targetPackage code.
+ */
+ public String targetProcess;
+
+ /**
* Full path to the base APK for this application.
*/
public String sourceDir;
@@ -113,6 +120,7 @@
public InstrumentationInfo(InstrumentationInfo orig) {
super(orig);
targetPackage = orig.targetPackage;
+ targetProcess = orig.targetProcess;
sourceDir = orig.sourceDir;
publicSourceDir = orig.publicSourceDir;
splitNames = orig.splitNames;
@@ -141,6 +149,7 @@
public void writeToParcel(Parcel dest, int parcelableFlags) {
super.writeToParcel(dest, parcelableFlags);
dest.writeString(targetPackage);
+ dest.writeString(targetProcess);
dest.writeString(sourceDir);
dest.writeString(publicSourceDir);
dest.writeStringArray(splitNames);
@@ -170,6 +179,7 @@
private InstrumentationInfo(Parcel source) {
super(source);
targetPackage = source.readString();
+ targetProcess = source.readString();
sourceDir = source.readString();
publicSourceDir = source.readString();
splitNames = source.readStringArray();
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index ab641c9..b20b5e2 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -1741,6 +1741,22 @@
/**
* Feature for {@link #getSystemAvailableFeatures} and
+ * {@link #hasSystemFeature(String, int)}: If this feature is supported, the Vulkan native API
+ * will enumerate at least one {@code VkPhysicalDevice}, and the feature version will indicate
+ * what level of optional compute features are supported beyond the Vulkan 1.0 requirements.
+ * <p>
+ * Compute level 0 indicates support for:
+ * <ul>
+ * <li>Ability to use pointers to buffer data from shaders</li>
+ * <li>Ability to load/store 16-bit values from buffers</li>
+ * <li>Ability to control shader floating point rounding mode</li>
+ * </ul>
+ */
+ @SdkConstant(SdkConstantType.FEATURE)
+ public static final String FEATURE_VULKAN_HARDWARE_COMPUTE = "android.hardware.vulkan.compute";
+
+ /**
+ * Feature for {@link #getSystemAvailableFeatures} and
* {@link #hasSystemFeature(String, int)}: The version of this feature indicates the highest
* {@code VkPhysicalDeviceProperties::apiVersion} supported by the physical devices that support
* the hardware level indicated by {@link #FEATURE_VULKAN_HARDWARE_LEVEL}. The feature version
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 13907ba..7cef781 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -17,7 +17,6 @@
package android.content.pm;
import static android.content.pm.ActivityInfo.FLAG_ALWAYS_FOCUSABLE;
-import static android.content.pm.ActivityInfo.FLAG_ON_TOP_LAUNCHER;
import static android.content.pm.ActivityInfo.FLAG_SUPPORTS_PICTURE_IN_PICTURE;
import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZABLE_LANDSCAPE_ONLY;
import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZABLE_PORTRAIT_ONLY;
@@ -1623,6 +1622,7 @@
return parseApkLite(apkPath, parser, attrs, flags, signatures, certificates);
} catch (XmlPullParserException | IOException | RuntimeException e) {
+ Slog.w(TAG, "Failed to parse " + apkPath, e);
throw new PackageParserException(INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION,
"Failed to parse " + apkPath, e);
} finally {
@@ -2747,15 +2747,15 @@
String cls = clsSeq.toString();
char c = cls.charAt(0);
if (c == '.') {
- return (pkg + cls).intern();
+ return pkg + cls;
}
if (cls.indexOf('.') < 0) {
StringBuilder b = new StringBuilder(pkg);
b.append('.');
b.append(cls);
- return b.toString().intern();
+ return b.toString();
}
- return cls.intern();
+ return cls;
}
private static String buildCompoundName(String pkg,
@@ -2775,7 +2775,7 @@
+ pkg + ": " + nameError;
return null;
}
- return (pkg + proc).intern();
+ return pkg + proc;
}
String nameError = validateName(proc, true, false);
if (nameError != null && !"system".equals(proc)) {
@@ -2783,7 +2783,7 @@
+ pkg + ": " + nameError;
return null;
}
- return proc.intern();
+ return proc;
}
private static String buildProcessName(String pkg, String defProc,
@@ -3160,6 +3160,10 @@
com.android.internal.R.styleable.AndroidManifestInstrumentation_targetPackage);
a.info.targetPackage = str != null ? str.intern() : null;
+ str = sa.getNonResourceString(
+ com.android.internal.R.styleable.AndroidManifestInstrumentation_targetProcess);
+ a.info.targetProcess = str != null ? str.intern() : null;
+
a.info.handleProfiling = sa.getBoolean(
com.android.internal.R.styleable.AndroidManifestInstrumentation_handleProfiling,
false);
@@ -4105,10 +4109,6 @@
a.info.flags |= FLAG_ALWAYS_FOCUSABLE;
}
- if (sa.getBoolean(R.styleable.AndroidManifestActivity_onTopLauncher, false)) {
- a.info.flags |= FLAG_ON_TOP_LAUNCHER;
- }
-
a.info.lockTaskLaunchMode =
sa.getInt(R.styleable.AndroidManifestActivity_lockTaskMode, 0);
@@ -5033,9 +5033,7 @@
}
private boolean isWebBrowsableIntent(IntentInfo intent) {
- return intent.hasAction(Intent.ACTION_VIEW)
- && intent.hasCategory(Intent.CATEGORY_BROWSABLE)
- && (intent.hasDataScheme("http") || intent.hasDataScheme("https"));
+ return intent.hasCategory(Intent.CATEGORY_BROWSABLE);
}
private boolean parseAllMetaData(Resources res, XmlResourceParser parser, String tag,
@@ -5103,7 +5101,7 @@
if (v != null) {
if (v.type == TypedValue.TYPE_STRING) {
CharSequence cs = v.coerceToString();
- data.putString(name, cs != null ? cs.toString().intern() : null);
+ data.putString(name, cs != null ? cs.toString() : null);
} else if (v.type == TypedValue.TYPE_INT_BOOLEAN) {
data.putBoolean(name, v.data != 0);
} else if (v.type >= TypedValue.TYPE_FIRST_INT
diff --git a/core/java/android/content/res/FontResourcesParser.java b/core/java/android/content/res/FontResourcesParser.java
index 15f3a09..7ea62db 100644
--- a/core/java/android/content/res/FontResourcesParser.java
+++ b/core/java/android/content/res/FontResourcesParser.java
@@ -33,7 +33,7 @@
*/
public class FontResourcesParser {
private static final int NORMAL_WEIGHT = 400;
- private static final String ITALIC = "italic";
+ private static final int ITALIC = 1;
public static FontConfig parse(XmlPullParser parser, Resources resources)
throws XmlPullParserException, IOException {
@@ -82,9 +82,12 @@
AttributeSet attrs = Xml.asAttributeSet(parser);
TypedArray array = resources.obtainAttributes(attrs, R.styleable.FontFamilyFont);
int weight = array.getInt(R.styleable.FontFamilyFont_fontWeight, NORMAL_WEIGHT);
- boolean isItalic = ITALIC.equals(array.getString(R.styleable.FontFamilyFont_fontStyle));
+ boolean isItalic = ITALIC == array.getInt(R.styleable.FontFamilyFont_fontStyle, 0);
String filename = array.getString(R.styleable.FontFamilyFont_font);
array.recycle();
+ while (parser.next() != XmlPullParser.END_TAG) {
+ skip(parser);
+ }
return new FontConfig.Font(filename, 0, null, weight, isItalic);
}
diff --git a/core/java/android/content/res/ResourcesImpl.java b/core/java/android/content/res/ResourcesImpl.java
index 3cf36d7..bf81096 100644
--- a/core/java/android/content/res/ResourcesImpl.java
+++ b/core/java/android/content/res/ResourcesImpl.java
@@ -753,7 +753,7 @@
}
final String file = value.string.toString();
- Typeface cached = Typeface.createFromCache(mAssets, file);
+ Typeface cached = Typeface.findFromCache(mAssets, file);
if (cached != null) {
return cached;
}
diff --git a/core/java/android/hardware/camera2/params/OutputConfiguration.java b/core/java/android/hardware/camera2/params/OutputConfiguration.java
index 522575f..d951294 100644
--- a/core/java/android/hardware/camera2/params/OutputConfiguration.java
+++ b/core/java/android/hardware/camera2/params/OutputConfiguration.java
@@ -259,10 +259,6 @@
throw new IllegalArgumentException("Unknow surface source class type");
}
- if (surfaceSize.getWidth() == 0 || surfaceSize.getHeight() == 0) {
- throw new IllegalArgumentException("Surface size needs to be non-zero");
- }
-
mSurfaceGroupId = SURFACE_GROUP_ID_NONE;
mSurfaces = new ArrayList<Surface>();
mRotation = ROTATION_0;
diff --git a/core/java/android/hardware/display/DisplayManagerInternal.java b/core/java/android/hardware/display/DisplayManagerInternal.java
index 3eb5844..98a5749 100644
--- a/core/java/android/hardware/display/DisplayManagerInternal.java
+++ b/core/java/android/hardware/display/DisplayManagerInternal.java
@@ -230,9 +230,6 @@
public int dozeScreenBrightness;
public int dozeScreenState;
- // If true, use twilight to affect the brightness.
- public boolean useTwilight;
-
public DisplayPowerRequest() {
policy = POLICY_BRIGHT;
useProximitySensor = false;
@@ -268,7 +265,6 @@
boostScreenBrightness = other.boostScreenBrightness;
dozeScreenBrightness = other.dozeScreenBrightness;
dozeScreenState = other.dozeScreenState;
- useTwilight = other.useTwilight;
}
@Override
@@ -289,8 +285,7 @@
&& lowPowerMode == other.lowPowerMode
&& boostScreenBrightness == other.boostScreenBrightness
&& dozeScreenBrightness == other.dozeScreenBrightness
- && dozeScreenState == other.dozeScreenState
- && useTwilight == other.useTwilight;
+ && dozeScreenState == other.dozeScreenState;
}
@Override
@@ -310,8 +305,7 @@
+ ", lowPowerMode=" + lowPowerMode
+ ", boostScreenBrightness=" + boostScreenBrightness
+ ", dozeScreenBrightness=" + dozeScreenBrightness
- + ", dozeScreenState=" + Display.stateToString(dozeScreenState)
- + ", useTwilight=" + useTwilight;
+ + ", dozeScreenState=" + Display.stateToString(dozeScreenState);
}
public static String policyToString(int policy) {
diff --git a/core/java/android/hardware/fingerprint/FingerprintManager.java b/core/java/android/hardware/fingerprint/FingerprintManager.java
index 2c9e6c7..7947620 100644
--- a/core/java/android/hardware/fingerprint/FingerprintManager.java
+++ b/core/java/android/hardware/fingerprint/FingerprintManager.java
@@ -766,7 +766,7 @@
/**
* Retrieves the authenticator token for binding keys to the lifecycle
- * of the current set of fingerprints. Used only by internal clients.
+ * of the calling user's fingerprints. Used only by internal clients.
*
* @hide
*/
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index beed6e9..5996fe2 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -1084,8 +1084,10 @@
final int currentHeight = mWindow.getWindow().getAttributes().height;
final int newHeight = isFullscreen ? MATCH_PARENT : WRAP_CONTENT;
if (mIsInputViewShown && currentHeight != newHeight) {
- Log.w(TAG, "Window size has been changed. This may cause jankiness of resizing window: "
- + currentHeight + " -> " + newHeight);
+ if (DEBUG) {
+ Log.w(TAG,"Window size has been changed. This may cause jankiness of resizing "
+ + "window: " + currentHeight + " -> " + newHeight);
+ }
}
mWindow.getWindow().setLayout(MATCH_PARENT, newHeight);
}
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 222953e..dc5750d 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -46,6 +46,7 @@
import android.util.ArrayMap;
import android.util.Log;
import android.util.SparseArray;
+import android.util.SparseIntArray;
import com.android.internal.telephony.ITelephony;
import com.android.internal.telephony.PhoneConstants;
@@ -1240,36 +1241,27 @@
private NetworkCapabilities networkCapabilitiesForFeature(int networkType, String feature) {
if (networkType == TYPE_MOBILE) {
- int cap = -1;
- if ("enableMMS".equals(feature)) {
- cap = NetworkCapabilities.NET_CAPABILITY_MMS;
- } else if ("enableSUPL".equals(feature)) {
- cap = NetworkCapabilities.NET_CAPABILITY_SUPL;
- } else if ("enableDUN".equals(feature) || "enableDUNAlways".equals(feature)) {
- cap = NetworkCapabilities.NET_CAPABILITY_DUN;
- } else if ("enableHIPRI".equals(feature)) {
- cap = NetworkCapabilities.NET_CAPABILITY_INTERNET;
- } else if ("enableFOTA".equals(feature)) {
- cap = NetworkCapabilities.NET_CAPABILITY_FOTA;
- } else if ("enableIMS".equals(feature)) {
- cap = NetworkCapabilities.NET_CAPABILITY_IMS;
- } else if ("enableCBS".equals(feature)) {
- cap = NetworkCapabilities.NET_CAPABILITY_CBS;
- } else {
- return null;
+ switch (feature) {
+ case "enableCBS":
+ return networkCapabilitiesForType(TYPE_MOBILE_CBS);
+ case "enableDUN":
+ case "enableDUNAlways":
+ return networkCapabilitiesForType(TYPE_MOBILE_DUN);
+ case "enableFOTA":
+ return networkCapabilitiesForType(TYPE_MOBILE_FOTA);
+ case "enableHIPRI":
+ return networkCapabilitiesForType(TYPE_MOBILE_HIPRI);
+ case "enableIMS":
+ return networkCapabilitiesForType(TYPE_MOBILE_IMS);
+ case "enableMMS":
+ return networkCapabilitiesForType(TYPE_MOBILE_MMS);
+ case "enableSUPL":
+ return networkCapabilitiesForType(TYPE_MOBILE_SUPL);
+ default:
+ return null;
}
- NetworkCapabilities netCap = new NetworkCapabilities();
- netCap.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR).addCapability(cap);
- netCap.maybeMarkCapabilitiesRestricted();
- return netCap;
- } else if (networkType == TYPE_WIFI) {
- if ("p2p".equals(feature)) {
- NetworkCapabilities netCap = new NetworkCapabilities();
- netCap.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
- netCap.addCapability(NetworkCapabilities.NET_CAPABILITY_WIFI_P2P);
- netCap.maybeMarkCapabilitiesRestricted();
- return netCap;
- }
+ } else if (networkType == TYPE_WIFI && "p2p".equals(feature)) {
+ return networkCapabilitiesForType(TYPE_WIFI_P2P);
}
return null;
}
@@ -1477,6 +1469,59 @@
return true;
}
+ private static final SparseIntArray sLegacyTypeToTransport = new SparseIntArray();
+ static {
+ sLegacyTypeToTransport.put(TYPE_MOBILE, NetworkCapabilities.TRANSPORT_CELLULAR);
+ sLegacyTypeToTransport.put(TYPE_MOBILE_CBS, NetworkCapabilities.TRANSPORT_CELLULAR);
+ sLegacyTypeToTransport.put(TYPE_MOBILE_DUN, NetworkCapabilities.TRANSPORT_CELLULAR);
+ sLegacyTypeToTransport.put(TYPE_MOBILE_FOTA, NetworkCapabilities.TRANSPORT_CELLULAR);
+ sLegacyTypeToTransport.put(TYPE_MOBILE_HIPRI, NetworkCapabilities.TRANSPORT_CELLULAR);
+ sLegacyTypeToTransport.put(TYPE_MOBILE_IMS, NetworkCapabilities.TRANSPORT_CELLULAR);
+ sLegacyTypeToTransport.put(TYPE_MOBILE_MMS, NetworkCapabilities.TRANSPORT_CELLULAR);
+ sLegacyTypeToTransport.put(TYPE_MOBILE_SUPL, NetworkCapabilities.TRANSPORT_CELLULAR);
+ sLegacyTypeToTransport.put(TYPE_WIFI, NetworkCapabilities.TRANSPORT_WIFI);
+ sLegacyTypeToTransport.put(TYPE_WIFI_P2P, NetworkCapabilities.TRANSPORT_WIFI);
+ sLegacyTypeToTransport.put(TYPE_BLUETOOTH, NetworkCapabilities.TRANSPORT_BLUETOOTH);
+ sLegacyTypeToTransport.put(TYPE_ETHERNET, NetworkCapabilities.TRANSPORT_ETHERNET);
+ }
+
+ private static final SparseIntArray sLegacyTypeToCapability = new SparseIntArray();
+ static {
+ sLegacyTypeToCapability.put(TYPE_MOBILE_CBS, NetworkCapabilities.NET_CAPABILITY_CBS);
+ sLegacyTypeToCapability.put(TYPE_MOBILE_DUN, NetworkCapabilities.NET_CAPABILITY_DUN);
+ sLegacyTypeToCapability.put(TYPE_MOBILE_FOTA, NetworkCapabilities.NET_CAPABILITY_FOTA);
+ sLegacyTypeToCapability.put(TYPE_MOBILE_IMS, NetworkCapabilities.NET_CAPABILITY_IMS);
+ sLegacyTypeToCapability.put(TYPE_MOBILE_MMS, NetworkCapabilities.NET_CAPABILITY_MMS);
+ sLegacyTypeToCapability.put(TYPE_MOBILE_SUPL, NetworkCapabilities.NET_CAPABILITY_SUPL);
+ sLegacyTypeToCapability.put(TYPE_WIFI_P2P, NetworkCapabilities.NET_CAPABILITY_WIFI_P2P);
+ }
+
+ /**
+ * Given a legacy type (TYPE_WIFI, ...) returns a NetworkCapabilities
+ * instance suitable for registering a request or callback. Throws an
+ * IllegalArgumentException if no mapping from the legacy type to
+ * NetworkCapabilities is known.
+ *
+ * @hide
+ */
+ public static NetworkCapabilities networkCapabilitiesForType(int type) {
+ final NetworkCapabilities nc = new NetworkCapabilities();
+
+ // Map from type to transports.
+ final int NOT_FOUND = -1;
+ final int transport = sLegacyTypeToTransport.get(type, NOT_FOUND);
+ if (transport == NOT_FOUND) {
+ throw new IllegalArgumentException("unknown legacy type: " + type);
+ }
+ nc.addTransportType(transport);
+
+ // Map from type to capabilities.
+ nc.addCapability(sLegacyTypeToCapability.get(
+ type, NetworkCapabilities.NET_CAPABILITY_INTERNET));
+ nc.maybeMarkCapabilitiesRestricted();
+ return nc;
+ }
+
/** @hide */
public static class PacketKeepaliveCallback {
/** The requested keepalive was successfully started. */
diff --git a/core/java/android/net/NetworkRequest.java b/core/java/android/net/NetworkRequest.java
index ae72470..cb78009 100644
--- a/core/java/android/net/NetworkRequest.java
+++ b/core/java/android/net/NetworkRequest.java
@@ -178,6 +178,20 @@
}
/**
+ * Set the {@code NetworkCapabilities} for this builder instance,
+ * overriding any capabilities that had been previously set.
+ *
+ * @param nc The superseding {@code NetworkCapabilities} instance.
+ * @return The builder to facilitate chaining.
+ * @hide
+ */
+ public Builder setCapabilities(NetworkCapabilities nc) {
+ mNetworkCapabilities.clearAll();
+ mNetworkCapabilities.combineCapabilities(nc);
+ return this;
+ }
+
+ /**
* Completely clears all the {@code NetworkCapabilities} from this builder instance,
* removing even the capabilities that are set by default when the object is constructed.
*
diff --git a/core/java/android/net/NetworkScorerAppManager.java b/core/java/android/net/NetworkScorerAppManager.java
index 9e4dd87..9dcf4f4 100644
--- a/core/java/android/net/NetworkScorerAppManager.java
+++ b/core/java/android/net/NetworkScorerAppManager.java
@@ -18,6 +18,7 @@
import android.Manifest.permission;
import android.annotation.Nullable;
+import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
@@ -33,6 +34,7 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import java.util.Objects;
/**
* Internal class for discovering and managing the network scorer/recommendation application.
@@ -53,33 +55,43 @@
* Holds metadata about a discovered network scorer/recommendation application.
*/
public static class NetworkScorerAppData {
- /** Package name of this scorer app. */
- public final String packageName;
-
/** UID of the scorer app. */
public final int packageUid;
+ private final ComponentName mRecommendationService;
- /**
- * Name of the recommendation service we can bind to.
- */
- public final String recommendationServiceClassName;
-
- public NetworkScorerAppData(String packageName, int packageUid,
- String recommendationServiceClassName) {
- this.packageName = packageName;
+ public NetworkScorerAppData(int packageUid, ComponentName recommendationServiceComp) {
this.packageUid = packageUid;
- this.recommendationServiceClassName = recommendationServiceClassName;
+ this.mRecommendationService = recommendationServiceComp;
+ }
+
+ public String getRecommendationServicePackageName() {
+ return mRecommendationService.getPackageName();
+ }
+
+ public ComponentName getRecommendationServiceComponent() {
+ return mRecommendationService;
}
@Override
public String toString() {
- final StringBuilder sb = new StringBuilder("NetworkScorerAppData{");
- sb.append("mPackageName='").append(packageName).append('\'');
- sb.append(", packageUid=").append(packageUid);
- sb.append(", recommendationServiceClassName='")
- .append(recommendationServiceClassName).append('\'');
- sb.append('}');
- return sb.toString();
+ return "NetworkScorerAppData{" +
+ "packageUid=" + packageUid +
+ ", mRecommendationService=" + mRecommendationService +
+ '}';
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ NetworkScorerAppData that = (NetworkScorerAppData) o;
+ return packageUid == that.packageUid &&
+ Objects.equals(mRecommendationService, that.mRecommendationService);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(packageUid, mRecommendationService);
}
}
@@ -110,16 +122,16 @@
return null;
}
- final PackageManager pm = mContext.getPackageManager();
for (int i = 0; i < potentialPkgs.size(); i++) {
final String potentialPkg = potentialPkgs.get(i);
// Look for the recommendation service class and required receiver.
final ResolveInfo resolveServiceInfo = findRecommendationService(potentialPkg);
if (resolveServiceInfo != null) {
- return new NetworkScorerAppData(potentialPkg,
- resolveServiceInfo.serviceInfo.applicationInfo.uid,
- resolveServiceInfo.serviceInfo.name);
+ final ComponentName componentName =
+ new ComponentName(potentialPkg, resolveServiceInfo.serviceInfo.name);
+ return new NetworkScorerAppData(resolveServiceInfo.serviceInfo.applicationInfo.uid,
+ componentName);
} else {
if (DEBUG) {
Log.d(TAG, potentialPkg + " does not have the required components, skipping.");
diff --git a/core/java/android/net/RecommendationRequest.java b/core/java/android/net/RecommendationRequest.java
index b89a245..9f97c5a 100644
--- a/core/java/android/net/RecommendationRequest.java
+++ b/core/java/android/net/RecommendationRequest.java
@@ -50,7 +50,7 @@
private WifiConfiguration mDefaultConfig;
private WifiConfiguration mConnectedConfig;
private WifiConfiguration[] mConnectableConfigs;
- private int mLastSelectedNetworkId;
+ private int mLastSelectedNetworkId = -1;
private long mLastSelectedTimestamp;
public Builder setScanResults(ScanResult[] scanResults) {
@@ -161,7 +161,7 @@
/**
* @return The {@link WifiConfiguration#networkId} of the last user selected network.
- * {@code 0} if not set.
+ * {@code -1} if not set.
*/
public int getLastSelectedNetworkId() {
return mLastSelectedNetworkId;
diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java
index e99d303..f94e89a 100644
--- a/core/java/android/os/Parcel.java
+++ b/core/java/android/os/Parcel.java
@@ -17,6 +17,7 @@
package android.os;
import android.annotation.IntegerRes;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.text.TextUtils;
import android.util.ArrayMap;
@@ -1339,7 +1340,7 @@
}
/**
- * Flatten a heterogeneous array containing a particular object type into
+ * Flatten a homogeneous array containing a particular object type into
* the parcel, at
* the current dataPosition() and growing dataCapacity() if needed. The
* type of the objects in the array must be one that implements Parcelable.
@@ -1361,7 +1362,7 @@
if (val != null) {
int N = val.length;
writeInt(N);
- for (int i=0; i<N; i++) {
+ for (int i = 0; i < N; i++) {
T item = val[i];
if (item != null) {
writeInt(1);
@@ -1376,6 +1377,146 @@
}
/**
+ * Write a uniform (all items are null or the same class) array list of
+ * parcelables.
+ *
+ * @param list The list to write.
+ *
+ * @hide
+ */
+ public final <T extends Parcelable> void writeTypedArrayList(@Nullable ArrayList<T> list,
+ int parcelableFlags) {
+ if (list != null) {
+ int N = list.size();
+ writeInt(N);
+ boolean wroteCreator = false;
+ for (int i = 0; i < N; i++) {
+ T item = list.get(i);
+ if (item != null) {
+ writeInt(1);
+ if (!wroteCreator) {
+ writeParcelableCreator(item);
+ wroteCreator = true;
+ }
+ item.writeToParcel(this, parcelableFlags);
+ } else {
+ writeInt(0);
+ }
+ }
+ } else {
+ writeInt(-1);
+ }
+ }
+
+ /**
+ * Reads a uniform (all items are null or the same class) array list of
+ * parcelables.
+ *
+ * @return The list or null.
+ *
+ * @hide
+ */
+ public final @Nullable <T> ArrayList<T> readTypedArrayList(@Nullable ClassLoader loader) {
+ int N = readInt();
+ if (N <= 0) {
+ return null;
+ }
+ Parcelable.Creator<?> creator = null;
+ ArrayList<T> result = new ArrayList<T>(N);
+ for (int i = 0; i < N; i++) {
+ if (readInt() != 0) {
+ if (creator == null) {
+ creator = readParcelableCreator(loader);
+ if (creator == null) {
+ return null;
+ }
+ }
+ final T parcelable;
+ if (creator instanceof Parcelable.ClassLoaderCreator<?>) {
+ Parcelable.ClassLoaderCreator<?> classLoaderCreator =
+ (Parcelable.ClassLoaderCreator<?>) creator;
+ parcelable = (T) classLoaderCreator.createFromParcel(this, loader);
+ } else {
+ parcelable = (T) creator.createFromParcel(this);
+ }
+ result.add(parcelable);
+ } else {
+ result.add(null);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Write a uniform (all items are null or the same class) array set of
+ * parcelables.
+ *
+ * @param set The set to write.
+ *
+ * @hide
+ */
+ public final <T extends Parcelable> void writeTypedArraySet(@Nullable ArraySet<T> set,
+ int parcelableFlags) {
+ if (set != null) {
+ int N = set.size();
+ writeInt(N);
+ boolean wroteCreator = false;
+ for (int i = 0; i < N; i++) {
+ T item = set.valueAt(i);
+ if (item != null) {
+ writeInt(1);
+ if (!wroteCreator) {
+ writeParcelableCreator(item);
+ wroteCreator = true;
+ }
+ item.writeToParcel(this, parcelableFlags);
+ } else {
+ writeInt(0);
+ }
+ }
+ } else {
+ writeInt(-1);
+ }
+ }
+
+ /**
+ * Reads a uniform (all items are null or the same class) array set of
+ * parcelables.
+ *
+ * @return The set or null.
+ *
+ * @hide
+ */
+ public final @Nullable <T> ArraySet<T> readTypedArraySet(@Nullable ClassLoader loader) {
+ int N = readInt();
+ if (N <= 0) {
+ return null;
+ }
+ Parcelable.Creator<?> creator = null;
+ ArraySet<T> result = new ArraySet<T>(N);
+ for (int i = 0; i < N; i++) {
+ T parcelable = null;
+ if (readInt() != 0) {
+ if (creator == null) {
+ creator = readParcelableCreator(loader);
+ if (creator == null) {
+ return null;
+ }
+ }
+ if (creator instanceof Parcelable.ClassLoaderCreator<?>) {
+ Parcelable.ClassLoaderCreator<?> classLoaderCreator =
+ (Parcelable.ClassLoaderCreator<?>) creator;
+ parcelable = (T) classLoaderCreator.createFromParcel(this, loader);
+ } else {
+ parcelable = (T) creator.createFromParcel(this);
+ }
+ }
+ result.append(parcelable);
+ }
+ return result;
+ }
+
+ /**
* Flatten the Parcelable object into the parcel.
*
* @param val The Parcelable object to be written.
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index dff0a28..31b3bc9 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -508,15 +508,6 @@
}
/**
- * Returns true if the twilight service should be used to adjust screen brightness
- * policy. This setting is experimental and disabled by default.
- * @hide
- */
- public static boolean useTwilightAdjustmentFeature() {
- return SystemProperties.getBoolean("persist.power.usetwilightadj", false);
- }
-
- /**
* Creates a new wake lock with the specified level and flags.
* <p>
* The {@code levelAndFlags} parameter specifies a wake lock level and optional flags
diff --git a/wifi/java/android/net/wifi/hotspot2/pps/HomeSP.aidl b/core/java/android/os/Seccomp.java
similarity index 69%
copy from wifi/java/android/net/wifi/hotspot2/pps/HomeSP.aidl
copy to core/java/android/os/Seccomp.java
index 62d5603..f14e93f 100644
--- a/wifi/java/android/net/wifi/hotspot2/pps/HomeSP.aidl
+++ b/core/java/android/os/Seccomp.java
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2016, The Android Open Source Project
+/*
+ * Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * 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,
@@ -14,6 +14,11 @@
* limitations under the License.
*/
-package android.net.wifi.hotspot2.pps;
+package android.os;
-parcelable HomeSP;
+/**
+ * @hide
+ */
+public final class Seccomp {
+ public static final native void setPolicy();
+}
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 388054d..dfcab3d 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -516,6 +516,7 @@
* <li>{@link LayoutParams#TYPE_SYSTEM_ALERT}</li>
* <li>{@link LayoutParams#TYPE_SYSTEM_ERROR}</li>
* <li>{@link LayoutParams#TYPE_SYSTEM_OVERLAY}</li>
+ * <li>{@link LayoutParams#TYPE_APPLICATION_OVERLAY}</li>
*
* <p>This can only be set by device owners and profile owners on the primary user.
* The default value is <code>false</code>.
diff --git a/core/java/android/preference/PreferenceActivity.java b/core/java/android/preference/PreferenceActivity.java
index 06666f4..5e7f68b 100644
--- a/core/java/android/preference/PreferenceActivity.java
+++ b/core/java/android/preference/PreferenceActivity.java
@@ -16,6 +16,7 @@
package android.preference;
+import android.animation.LayoutTransition;
import android.annotation.Nullable;
import android.annotation.StringRes;
import android.annotation.XmlRes;
@@ -87,7 +88,7 @@
* items. Doing this implicitly switches the class into its new "headers
* + fragments" mode rather than the old style of just showing a single
* preferences list.
- *
+ *
* <div class="special reference">
* <h3>Developer Guides</h3>
* <p>For information about using {@code PreferenceActivity},
@@ -199,6 +200,9 @@
private ViewGroup mPrefsContainer;
+ // Null if in legacy mode.
+ private ViewGroup mHeadersContainer;
+
private FragmentBreadCrumbs mFragmentBreadCrumbs;
private boolean mSinglePane;
@@ -292,7 +296,7 @@
holder = (HeaderViewHolder) view.getTag();
}
- // All view fields must be updated every time, because the view may be recycled
+ // All view fields must be updated every time, because the view may be recycled
Header header = getItem(position);
if (mRemoveIconIfEmpty) {
if (header.iconRes == 0) {
@@ -469,7 +473,7 @@
}
return breadCrumbShortTitle;
}
-
+
@Override
public int describeContents() {
return 0;
@@ -558,6 +562,7 @@
mListFooter = (FrameLayout)findViewById(com.android.internal.R.id.list_footer);
mPrefsContainer = (ViewGroup) findViewById(com.android.internal.R.id.prefs_frame);
+ mHeadersContainer = (ViewGroup) findViewById(com.android.internal.R.id.headers);
boolean hidingHeaders = onIsHidingHeaders();
mSinglePane = hidingHeaders || !onIsMultiPane();
String initialFragment = getIntent().getStringExtra(EXTRA_SHOW_FRAGMENT);
@@ -575,66 +580,39 @@
(int) HEADER_ID_UNDEFINED);
if (curHeader >= 0 && curHeader < mHeaders.size()) {
setSelectedHeader(mHeaders.get(curHeader));
+ } else if (!mSinglePane && initialFragment == null) {
+ switchToHeader(onGetInitialHeader());
}
+ } else {
+ // This will for instance hide breadcrumbs for single pane.
+ showBreadCrumbs(getTitle(), null);
+ }
+ } else {
+ if (!onIsHidingHeaders()) {
+ onBuildHeaders(mHeaders);
}
- } else {
- if (initialFragment != null && mSinglePane) {
- // If we are just showing a fragment, we want to run in
- // new fragment mode, but don't need to compute and show
- // the headers.
+ if (initialFragment != null) {
switchToHeader(initialFragment, initialArguments);
- if (initialTitle != 0) {
- CharSequence initialTitleStr = getText(initialTitle);
- CharSequence initialShortTitleStr = initialShortTitle != 0
- ? getText(initialShortTitle) : null;
- showBreadCrumbs(initialTitleStr, initialShortTitleStr);
- }
-
- } else {
- // We need to try to build the headers.
- onBuildHeaders(mHeaders);
-
- // If there are headers, then at this point we need to show
- // them and, depending on the screen, we may also show in-line
- // the currently selected preference fragment.
- if (mHeaders.size() > 0) {
- if (!mSinglePane) {
- if (initialFragment == null) {
- Header h = onGetInitialHeader();
- switchToHeader(h);
- } else {
- switchToHeader(initialFragment, initialArguments);
- }
- }
- }
+ } else if (!mSinglePane && mHeaders.size() > 0) {
+ switchToHeader(onGetInitialHeader());
}
}
- // The default configuration is to only show the list view. Adjust
- // visibility for other configurations.
- if (initialFragment != null && mSinglePane) {
- // Single pane, showing just a prefs fragment.
- findViewById(com.android.internal.R.id.headers).setVisibility(View.GONE);
- mPrefsContainer.setVisibility(View.VISIBLE);
- if (initialTitle != 0) {
- CharSequence initialTitleStr = getText(initialTitle);
- CharSequence initialShortTitleStr = initialShortTitle != 0
- ? getText(initialShortTitle) : null;
- showBreadCrumbs(initialTitleStr, initialShortTitleStr);
- }
- } else if (mHeaders.size() > 0) {
+ if (mHeaders.size() > 0) {
setListAdapter(new HeaderAdapter(this, mHeaders, mPreferenceHeaderItemResId,
mPreferenceHeaderRemoveEmptyIcon));
- if (!mSinglePane) {
- // Multi-pane.
- getListView().setChoiceMode(AbsListView.CHOICE_MODE_SINGLE);
- if (mCurHeader != null) {
- setSelectedHeader(mCurHeader);
- }
- mPrefsContainer.setVisibility(View.VISIBLE);
- }
- } else {
+ getListView().setChoiceMode(AbsListView.CHOICE_MODE_SINGLE);
+ }
+
+ if (mSinglePane && initialFragment != null && initialTitle != 0) {
+ CharSequence initialTitleStr = getText(initialTitle);
+ CharSequence initialShortTitleStr = initialShortTitle != 0
+ ? getText(initialShortTitle) : null;
+ showBreadCrumbs(initialTitleStr, initialShortTitleStr);
+ }
+
+ if (mHeaders.size() == 0 && initialFragment == null) {
// If there are no headers, we are in the old "just show a screen
// of preferences" mode.
setContentView(com.android.internal.R.layout.preference_list_content_single);
@@ -642,6 +620,25 @@
mPrefsContainer = (ViewGroup) findViewById(com.android.internal.R.id.prefs);
mPreferenceManager = new PreferenceManager(this, FIRST_REQUEST_CODE);
mPreferenceManager.setOnPreferenceTreeClickListener(this);
+ mHeadersContainer = null;
+ } else if (mSinglePane) {
+ // Single-pane so one of the header or prefs containers must be hidden.
+ if (initialFragment != null || mCurHeader != null) {
+ mHeadersContainer.setVisibility(View.GONE);
+ } else {
+ mPrefsContainer.setVisibility(View.GONE);
+ }
+
+ // This animates our manual transitions between headers and prefs panel in single-pane.
+ // It also comes last so we don't animate any initial layout changes done above.
+ ViewGroup container = (ViewGroup) findViewById(
+ com.android.internal.R.id.prefs_container);
+ container.setLayoutTransition(new LayoutTransition());
+ } else {
+ // Multi-pane
+ if (mHeaders.size() > 0 && mCurHeader != null) {
+ setSelectedHeader(mCurHeader);
+ }
}
// see if we should show Back/Next buttons
@@ -697,12 +694,25 @@
}
}
+ @Override
+ public void onBackPressed() {
+ if (mCurHeader != null && mSinglePane && getFragmentManager().getBackStackEntryCount() == 0
+ && getIntent().getStringExtra(EXTRA_SHOW_FRAGMENT) == null) {
+ mCurHeader = null;
+
+ mPrefsContainer.setVisibility(View.GONE);
+ mHeadersContainer.setVisibility(View.VISIBLE);
+ getListView().clearChoices();
+ } else {
+ super.onBackPressed();
+ }
+ }
+
/**
* Returns true if this activity is currently showing the header list.
*/
public boolean hasHeaders() {
- return getListView().getVisibility() == View.VISIBLE
- && mPreferenceManager == null;
+ return mHeadersContainer != null && mHeadersContainer.getVisibility() == View.VISIBLE;
}
/**
@@ -718,7 +728,7 @@
* and a preference fragment.
*/
public boolean isMultiPane() {
- return hasHeaders() && mPrefsContainer.getVisibility() == View.VISIBLE;
+ return !mSinglePane;
}
/**
@@ -820,14 +830,14 @@
if (!"preference-headers".equals(nodeName)) {
throw new RuntimeException(
"XML document must start with <preference-headers> tag; found"
- + nodeName + " at " + parser.getPositionDescription());
+ + nodeName + " at " + parser.getPositionDescription());
}
Bundle curBundle = null;
final int outerDepth = parser.getDepth();
while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
- && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
+ && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
continue;
}
@@ -889,7 +899,7 @@
final int innerDepth = parser.getDepth();
while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
- && (type != XmlPullParser.END_TAG || parser.getDepth() > innerDepth)) {
+ && (type != XmlPullParser.END_TAG || parser.getDepth() > innerDepth)) {
if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
continue;
}
@@ -939,8 +949,9 @@
if (getApplicationInfo().targetSdkVersion >= android.os.Build.VERSION_CODES.KITKAT) {
throw new RuntimeException(
"Subclasses of PreferenceActivity must override isValidFragment(String)"
- + " to verify that the Fragment class is valid! " + this.getClass().getName()
- + " has not checked if fragment " + fragmentName + " is valid.");
+ + " to verify that the Fragment class is valid! "
+ + this.getClass().getName()
+ + " has not checked if fragment " + fragmentName + " is valid.");
} else {
return true;
}
@@ -1017,6 +1028,13 @@
// Only call this if we didn't save the instance state for later.
// If we did save it, it will be restored when we bind the adapter.
super.onRestoreInstanceState(state);
+
+ if (!mSinglePane) {
+ // Multi-pane.
+ if (mCurHeader != null) {
+ setSelectedHeader(mCurHeader);
+ }
+ }
}
@Override
@@ -1061,18 +1079,7 @@
*/
public void onHeaderClick(Header header, int position) {
if (header.fragment != null) {
- if (mSinglePane) {
- int titleRes = header.breadCrumbTitleRes;
- int shortTitleRes = header.breadCrumbShortTitleRes;
- if (titleRes == 0) {
- titleRes = header.titleRes;
- shortTitleRes = 0;
- }
- startWithFragment(header.fragment, header.fragmentArguments, null, 0,
- titleRes, shortTitleRes);
- } else {
- switchToHeader(header);
- }
+ switchToHeader(header);
} else if (header.intent != null) {
startActivity(header.intent);
}
@@ -1084,7 +1091,7 @@
* the selected fragment. The default implementation constructs an Intent
* that re-launches the current activity with the appropriate arguments to
* display the fragment.
- *
+ *
* @param fragmentName The name of the fragment to display.
* @param args Optional arguments to supply to the fragment.
* @param titleRes Optional resource ID of title to show for this item.
@@ -1103,7 +1110,7 @@
intent.putExtra(EXTRA_NO_HEADERS, true);
return intent;
}
-
+
/**
* Like {@link #startWithFragment(String, Bundle, Fragment, int, int, int)}
* but uses a 0 titleRes.
@@ -1223,11 +1230,21 @@
throw new IllegalArgumentException("Invalid fragment for this activity: "
+ fragmentName);
}
+
Fragment f = Fragment.instantiate(this, fragmentName, args);
FragmentTransaction transaction = getFragmentManager().beginTransaction();
- transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
+ transaction.setTransition(mSinglePane
+ ? FragmentTransaction.TRANSIT_NONE
+ : FragmentTransaction.TRANSIT_FRAGMENT_FADE);
transaction.replace(com.android.internal.R.id.prefs, f);
transaction.commitAllowingStateLoss();
+
+ if (mSinglePane && mPrefsContainer.getVisibility() == View.GONE) {
+ // We are transitioning from headers to preferences panel in single-pane so we need
+ // to hide headers and show the prefs container.
+ mPrefsContainer.setVisibility(View.VISIBLE);
+ mHeadersContainer.setVisibility(View.GONE);
+ }
}
/**
@@ -1340,7 +1357,7 @@
* be instantiated and placed in the appropriate pane. If running in
* single-pane mode, a new activity will be launched in which to show the
* fragment.
- *
+ *
* @param fragmentClass Full name of the class implementing the fragment.
* @param args Any desired arguments to supply to the fragment.
* @param titleRes Optional resource identifier of the title of this
@@ -1355,29 +1372,25 @@
*/
public void startPreferencePanel(String fragmentClass, Bundle args, @StringRes int titleRes,
CharSequence titleText, Fragment resultTo, int resultRequestCode) {
- if (mSinglePane) {
- startWithFragment(fragmentClass, args, resultTo, resultRequestCode, titleRes, 0);
- } else {
- Fragment f = Fragment.instantiate(this, fragmentClass, args);
- if (resultTo != null) {
- f.setTargetFragment(resultTo, resultRequestCode);
- }
- FragmentTransaction transaction = getFragmentManager().beginTransaction();
- transaction.replace(com.android.internal.R.id.prefs, f);
- if (titleRes != 0) {
- transaction.setBreadCrumbTitle(titleRes);
- } else if (titleText != null) {
- transaction.setBreadCrumbTitle(titleText);
- }
- transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
- transaction.addToBackStack(BACK_STACK_PREFS);
- transaction.commitAllowingStateLoss();
+ Fragment f = Fragment.instantiate(this, fragmentClass, args);
+ if (resultTo != null) {
+ f.setTargetFragment(resultTo, resultRequestCode);
}
+ FragmentTransaction transaction = getFragmentManager().beginTransaction();
+ transaction.replace(com.android.internal.R.id.prefs, f);
+ if (titleRes != 0) {
+ transaction.setBreadCrumbTitle(titleRes);
+ } else if (titleText != null) {
+ transaction.setBreadCrumbTitle(titleText);
+ }
+ transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
+ transaction.addToBackStack(BACK_STACK_PREFS);
+ transaction.commitAllowingStateLoss();
}
/**
* Called by a preference panel fragment to finish itself.
- *
+ *
* @param caller The fragment that is asking to be finished.
* @param resultCode Optional result code to send back to the original
* launching fragment.
@@ -1385,21 +1398,16 @@
* launching fragment.
*/
public void finishPreferencePanel(Fragment caller, int resultCode, Intent resultData) {
- if (mSinglePane) {
- setResult(resultCode, resultData);
- finish();
- } else {
- // XXX be smarter about popping the stack.
- onBackPressed();
- if (caller != null) {
- if (caller.getTargetFragment() != null) {
- caller.getTargetFragment().onActivityResult(caller.getTargetRequestCode(),
- resultCode, resultData);
- }
+ // TODO: be smarter about popping the stack.
+ onBackPressed();
+ if (caller != null) {
+ if (caller.getTargetFragment() != null) {
+ caller.getTargetFragment().onActivityResult(caller.getTargetRequestCode(),
+ resultCode, resultData);
}
}
}
-
+
@Override
public boolean onPreferenceStartFragment(PreferenceFragment caller, Preference pref) {
startPreferencePanel(pref.getFragment(), pref.getExtras(), pref.getTitleRes(),
diff --git a/core/java/android/provider/OneTimeUseBuilder.java b/core/java/android/provider/OneTimeUseBuilder.java
new file mode 100644
index 0000000..682e9c7
--- /dev/null
+++ b/core/java/android/provider/OneTimeUseBuilder.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package android.provider;
+
+/**
+ * A builder that facilitates prohibiting its use after an instance was created with it.
+ *
+ * Suggested usage:
+ * call {@link #checkNotUsed} in each setter, and {@link #markUsed} in {@link #build}
+ *
+ * @param <T> Type of object being built
+ * @hide
+ */
+public abstract class OneTimeUseBuilder<T> {
+ private boolean used = false;
+
+ protected void markUsed() {
+ checkNotUsed();
+ used = true;
+ }
+
+ protected void checkNotUsed() {
+ if (used) {
+ throw new IllegalStateException(
+ "This Builder should not be reused. Use a new Builder instance instead");
+ }
+ }
+
+ /**
+ * Builds the instance
+ *
+ * Once this method is called, this builder should no longer be used. Any subsequent calls to a
+ * setter or {@code build()} will throw an exception
+ */
+ public abstract T build();
+}
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index d83f2cb..2936dfb 100755
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -6721,12 +6721,6 @@
public static final String NIGHT_DISPLAY_CUSTOM_END_TIME = "night_display_custom_end_time";
/**
- * Whether brightness should automatically adjust based on twilight state.
- * @hide
- */
- public static final String BRIGHTNESS_USE_TWILIGHT = "brightness_use_twilight";
-
- /**
* Names of the service components that the current user has explicitly allowed to
* be a VR mode listener, separated by ':'.
*
diff --git a/core/java/android/provider/SettingsStringUtil.java b/core/java/android/provider/SettingsStringUtil.java
new file mode 100644
index 0000000..f242d79
--- /dev/null
+++ b/core/java/android/provider/SettingsStringUtil.java
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package android.provider;
+
+import android.content.ComponentName;
+import android.content.ContentResolver;
+import android.text.TextUtils;
+
+import com.android.internal.util.ArrayUtils;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.function.Function;
+
+/**
+ * Utilities for dealing with {@link String} values in {@link Settings}
+ *
+ * @hide
+ */
+public class SettingsStringUtil {
+ private SettingsStringUtil() {}
+
+ public static final String DELIMITER = ":";
+
+ /**
+ * A {@link HashSet} of items, that uses a common convention of setting string
+ * serialization/deserialization of separating multiple items with {@link #DELIMITER}
+ */
+ public static abstract class ColonDelimitedSet<T> extends HashSet<T> {
+
+ public ColonDelimitedSet(String colonSeparatedItems) {
+ for (String cn :
+ TextUtils.split(TextUtils.emptyIfNull(colonSeparatedItems), DELIMITER)) {
+ add(itemFromString(cn));
+ }
+ }
+
+ protected abstract T itemFromString(String s);
+ protected String itemToString(T item) {
+ return String.valueOf(item);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ Iterator<T> it = iterator();
+ if (it.hasNext()) {
+ sb.append(it.next());
+ while (it.hasNext()) {
+ sb.append(DELIMITER);
+ sb.append(itemToString(it.next()));
+ }
+ }
+ return sb.toString();
+ }
+
+
+ public static class OfStrings extends ColonDelimitedSet<String> {
+ public OfStrings(String colonSeparatedItems) {
+ super(colonSeparatedItems);
+ }
+
+ @Override
+ protected String itemFromString(String s) {
+ return s;
+ }
+
+ public static String add(String delimitedElements, String element) {
+ final ColonDelimitedSet<String> set
+ = new ColonDelimitedSet.OfStrings(delimitedElements);
+ if (set.contains(element)) {
+ return delimitedElements;
+ }
+ set.add(element);
+ return set.toString();
+ }
+
+ public static String remove(String delimitedElements, String element) {
+ final ColonDelimitedSet<String> set
+ = new ColonDelimitedSet.OfStrings(delimitedElements);
+ if (!set.contains(element)) {
+ return delimitedElements;
+ }
+ set.remove(element);
+ return set.toString();
+ }
+
+ public static boolean contains(String delimitedElements, String element) {
+ final String[] elements = TextUtils.split(delimitedElements, DELIMITER);
+ return ArrayUtils.indexOf(elements, element) != -1;
+ }
+ }
+ }
+
+ public static class ComponentNameSet extends ColonDelimitedSet<ComponentName> {
+ public ComponentNameSet(String colonSeparatedPackageNames) {
+ super(colonSeparatedPackageNames);
+ }
+
+ @Override
+ protected ComponentName itemFromString(String s) {
+ return ComponentName.unflattenFromString(s);
+ }
+
+ @Override
+ protected String itemToString(ComponentName item) {
+ return item.flattenToString();
+ }
+
+ public static String add(String delimitedElements, ComponentName element) {
+ final ComponentNameSet set = new ComponentNameSet(delimitedElements);
+ if (set.contains(element)) {
+ return delimitedElements;
+ }
+ set.add(element);
+ return set.toString();
+ }
+
+ public static String remove(String delimitedElements, ComponentName element) {
+ final ComponentNameSet set = new ComponentNameSet(delimitedElements);
+ if (!set.contains(element)) {
+ return delimitedElements;
+ }
+ set.remove(element);
+ return set.toString();
+ }
+
+ public static boolean contains(String delimitedElements, ComponentName element) {
+ return ColonDelimitedSet.OfStrings.contains(
+ delimitedElements, element.flattenToString());
+ }
+ }
+
+ public static class SettingStringHelper {
+ private final ContentResolver mContentResolver;
+ private final String mSettingName;
+ private final int mUserId;
+
+ public SettingStringHelper(ContentResolver contentResolver, String name, int userId) {
+ mContentResolver = contentResolver;
+ mUserId = userId;
+ mSettingName = name;
+ }
+
+ public String read() {
+ return Settings.Secure.getStringForUser(
+ mContentResolver, mSettingName, mUserId);
+ }
+
+ public boolean write(String value) {
+ return Settings.Secure.putStringForUser(
+ mContentResolver, mSettingName, value, mUserId);
+ }
+
+ public boolean modify(Function<String, String> change) {
+ return write(change.apply(read()));
+ }
+ }
+}
diff --git a/core/java/android/service/autofill/AutoFillService.java b/core/java/android/service/autofill/AutoFillService.java
index 1e4f90d..ab80aa3 100644
--- a/core/java/android/service/autofill/AutoFillService.java
+++ b/core/java/android/service/autofill/AutoFillService.java
@@ -15,9 +15,10 @@
*/
package android.service.autofill;
-import static android.view.View.AUTO_FILL_FLAG_TYPE_FILL;
-import static android.view.View.AUTO_FILL_FLAG_TYPE_SAVE;
-
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.RemoteException;
+import com.android.internal.os.HandlerCaller;
import android.annotation.SdkConstant;
import android.app.Activity;
import android.app.Service;
@@ -26,21 +27,13 @@
import android.os.Bundle;
import android.os.CancellationSignal;
import android.os.IBinder;
+import android.os.ICancellationSignal;
import android.os.Looper;
-import android.os.Message;
import android.util.Log;
-import android.view.autofill.AutoFillId;
-import android.view.autofill.Dataset;
import android.view.autofill.FillResponse;
-import com.android.internal.os.HandlerCaller;
import com.android.internal.os.SomeArgs;
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.List;
-
//TODO(b/33197203): improve javadoc (of both class and methods); in particular, make sure the
//life-cycle (and how state could be maintained on server-side) is well documented.
@@ -50,12 +43,7 @@
* <p>Apps providing auto-fill capabilities must extend this service.
*/
public abstract class AutoFillService extends Service {
-
private static final String TAG = "AutoFillService";
- static final boolean DEBUG = true; // TODO(b/33197203): set to false once stable
-
- // TODO(b/33197203): check for device's memory size instead of DEBUG?
- static final boolean DEBUG_PENDING_CALLBACKS = DEBUG;
/**
* The {@link Intent} that must be declared as handled by the service.
@@ -79,79 +67,37 @@
*/
public static final String SERVICE_META_DATA = "android.autofill";
- // Internal bundle keys.
- /** @hide */ public static final String KEY_CALLBACK = "callback";
- /** @hide */ public static final String KEY_SAVABLE_IDS = "savable_ids";
- /** @hide */ public static final String EXTRA_CRYPTO_OBJECT_ID = "crypto_object_id";
-
- // Prefix for public bundle keys.
- private static final String KEY_PREFIX = "android.service.autofill.extra.";
-
- /**
- * Key of the {@link Bundle} passed to methods such as
- * {@link #onSaveRequest(AssistStructure, Bundle, SaveCallback)} containing the extras set by
- * {@link android.view.autofill.FillResponse.Builder#setExtras(Bundle)}.
- */
- public static final String EXTRA_RESPONSE_EXTRAS = KEY_PREFIX + "RESPONSE_EXTRAS";
-
- /**
- * Key of the {@link Bundle} passed to methods such as
- * {@link #onSaveRequest(AssistStructure, Bundle, SaveCallback)} containing the extras set by
- * {@link android.view.autofill.Dataset.Builder#setExtras(Bundle)}.
- */
- public static final String EXTRA_DATASET_EXTRAS = KEY_PREFIX + "DATASET_EXTRAS";
-
- /**
- * Used to indicate the user selected an action that requires authentication.
- */
- public static final int FLAG_AUTHENTICATION_REQUESTED = 1 << 0;
-
- /**
- * Used to indicate the user authentication succeeded.
- */
- public static final int FLAG_AUTHENTICATION_SUCCESS = 1 << 1;
-
- /**
- * Used to indicate the user authentication failed.
- */
- public static final int FLAG_AUTHENTICATION_ERROR = 1 << 2;
-
- /**
- * Used when the service requested Fingerprint authentication but such option is not available.
- */
- public static final int FLAG_FINGERPRINT_AUTHENTICATION_NOT_AVAILABLE = 1 << 3;
+ // Internal extras
+ /** @hide */
+ public static final String EXTRA_ACTIVITY_TOKEN =
+ "android.service.autofill.EXTRA_ACTIVITY_TOKEN";
// Handler messages.
private static final int MSG_CONNECT = 1;
private static final int MSG_DISCONNECT = 2;
- private static final int MSG_AUTO_FILL_ACTIVITY = 3;
- private static final int MSG_AUTHENTICATE_FILL_RESPONSE = 4;
- private static final int MSG_AUTHENTICATE_DATASET = 5;
+ private static final int MSG_ON_FILL_REQUEST = 3;
+ private static final int MSG_ON_SAVE_REQUEST = 4;
private final IAutoFillService mInterface = new IAutoFillService.Stub() {
-
@Override
- public void autoFill(AssistStructure structure, IAutoFillServerCallback callback,
- int flags) {
- mHandlerCaller
- .obtainMessageIOO(MSG_AUTO_FILL_ACTIVITY, flags, structure, callback)
+ public void onFillRequest(AssistStructure structure, Bundle extras,
+ IFillCallback callback) {
+ ICancellationSignal transport = CancellationSignal.createTransport();
+ try {
+ callback.onCancellable(transport);
+ } catch (RemoteException e) {
+ e.rethrowFromSystemServer();
+ }
+ mHandlerCaller.obtainMessageOOOO(MSG_ON_FILL_REQUEST, structure,
+ CancellationSignal.fromTransport(transport), extras, callback)
.sendToTarget();
}
@Override
- public void authenticateFillResponse(Bundle extras, int flags) {
- final Message msg = mHandlerCaller.obtainMessage(MSG_AUTHENTICATE_FILL_RESPONSE);
- msg.arg1 = flags;
- msg.obj = extras;
- mHandlerCaller.sendMessage(msg);
- }
-
- @Override
- public void authenticateDataset(Bundle extras, int flags) {
- final Message msg = mHandlerCaller.obtainMessage(MSG_AUTHENTICATE_DATASET);
- msg.arg1 = flags;
- msg.obj = extras;
- mHandlerCaller.sendMessage(msg);
+ public void onSaveRequest(AssistStructure structure, Bundle extras,
+ ISaveCallback callback) {
+ mHandlerCaller.obtainMessageOOO(MSG_ON_SAVE_REQUEST, structure,
+ extras, callback).sendToTarget();
}
@Override
@@ -165,47 +111,41 @@
}
};
- private final HandlerCaller.Callback mHandlerCallback = new HandlerCaller.Callback() {
-
- @Override
- public void executeMessage(Message msg) {
- switch (msg.what) {
- case MSG_CONNECT: {
- onConnected();
- break;
- } case MSG_AUTO_FILL_ACTIVITY: {
- final SomeArgs args = (SomeArgs) msg.obj;
- final int flags = msg.arg1;
- final AssistStructure structure = (AssistStructure) args.arg1;
- final IAutoFillServerCallback callback = (IAutoFillServerCallback) args.arg2;
- requestAutoFill(callback, structure, flags);
- break;
- } case MSG_AUTHENTICATE_FILL_RESPONSE: {
- final int flags = msg.arg1;
- final Bundle extras = (Bundle) msg.obj;
- onFillResponseAuthenticationRequest(extras, flags);
- break;
- } case MSG_AUTHENTICATE_DATASET: {
- final int flags = msg.arg1;
- final Bundle extras = (Bundle) msg.obj;
- onDatasetAuthenticationRequest(extras, flags);
- break;
- } case MSG_DISCONNECT: {
- onDisconnected();
- break;
- } default: {
- Log.w(TAG, "MyCallbacks received invalid message type: " + msg);
- }
+ private final HandlerCaller.Callback mHandlerCallback = (msg) -> {
+ switch (msg.what) {
+ case MSG_CONNECT: {
+ onConnected();
+ break;
+ } case MSG_ON_FILL_REQUEST: {
+ final SomeArgs args = (SomeArgs) msg.obj;
+ final AssistStructure structure = (AssistStructure) args.arg1;
+ final CancellationSignal cancellation = (CancellationSignal) args.arg2;
+ final Bundle extras = (Bundle) args.arg3;
+ final IFillCallback callback = (IFillCallback) args.arg4;
+ final FillCallback fillCallback = new FillCallback(callback);
+ args.recycle();
+ onFillRequest(structure, extras, cancellation, fillCallback);
+ break;
+ } case MSG_ON_SAVE_REQUEST: {
+ final SomeArgs args = (SomeArgs) msg.obj;
+ final AssistStructure structure = (AssistStructure) args.arg1;
+ final Bundle extras = (Bundle) args.arg2;
+ final ISaveCallback callback = (ISaveCallback) args.arg3;
+ final SaveCallback saveCallback = new SaveCallback(callback);
+ args.recycle();
+ onSaveRequest(structure, extras, saveCallback);
+ break;
+ } case MSG_DISCONNECT: {
+ onDisconnected();
+ break;
+ } default: {
+ Log.w(TAG, "MyCallbacks received invalid message type: " + msg);
}
}
};
private HandlerCaller mHandlerCaller;
- // User for debugging purposes
- private final List<CallbackHelper.Dumpable> mPendingCallbacks =
- DEBUG_PENDING_CALLBACKS ? new ArrayList<>() : null;
-
/**
* {@inheritDoc}
*
@@ -214,7 +154,6 @@
@Override
public void onCreate() {
super.onCreate();
-
mHandlerCaller = new HandlerCaller(null, Looper.getMainLooper(), mHandlerCallback, true);
}
@@ -233,7 +172,7 @@
* <p>You should generally do initialization here rather than in {@link #onCreate}.
*/
public void onConnected() {
- if (DEBUG) Log.d(TAG, "onConnected()");
+
}
/**
@@ -245,132 +184,36 @@
* to notify the result of the request.
*
* @param structure {@link Activity}'s view structure.
- * @param data bundle containing additional arguments set by the Android system (currently none)
- * or data passed by the service on previous calls to fullfill other sections of this activity
- * (see {@link FillResponse} Javadoc for examples of multiple-sections requests).
- * @param cancellationSignal signal for observing cancel requests.
+ * @param data bundle containing data passed by the service on previous calls to fill.
+ * This bundle allows your service to keep state between fill and save requests
+ * as well as when filling different sections of the UI as the system will try to
+ * aggressively unbind from the service to conserve resources. See {@link FillResponse}
+ * Javadoc for examples of multiple-sections requests.
+ * @param cancellationSignal signal for observing cancellation requests. The system will use
+ * this to notify you that the fill result is no longer needed and you should stop
+ * handling this fill request in order to save resources.
* @param callback object used to notify the result of the request.
*/
- public abstract void onFillRequest(AssistStructure structure, Bundle data,
- CancellationSignal cancellationSignal, FillCallback callback);
+ public abstract void onFillRequest(@NonNull AssistStructure structure, @Nullable Bundle data,
+ @NonNull CancellationSignal cancellationSignal, @NonNull FillCallback callback);
/**
* Called when user requests service to save the fields of an {@link Activity}.
*
* <p>Service must call one of the {@link SaveCallback} methods (like
- * {@link SaveCallback#onSuccess(AutoFillId[])} or {@link SaveCallback#onFailure(CharSequence)})
+ * {@link SaveCallback#onSuccess()} or {@link SaveCallback#onFailure(CharSequence)})
* to notify the result of the request.
*
* @param structure {@link Activity}'s view structure.
- * @param data bundle containing additional arguments set by the Android system (currently none)
- * or data passed by the service in the {@link FillResponse} that originated this call.
+ * @param data bundle containing data passed by the service on previous calls to fill.
+ * This bundle allows your service to keep state between fill and save requests
+ * as well as when filling different sections of the UI as the system will try to
+ * aggressively unbind from the service to conserve resources. See {@link FillResponse}
+ * Javadoc for examples of multiple-sections requests.
* @param callback object used to notify the result of the request.
*/
- public abstract void onSaveRequest(AssistStructure structure, Bundle data,
- SaveCallback callback);
-
- /**
- * Called as result of the user action for a {@link FillResponse} that required authentication.
- *
- * <p>When the {@link FillResponse} required authentication through
- * {@link android.view.autofill.FillResponse.Builder#requiresCustomAuthentication(Bundle, int)},
- * this call indicates the user is requesting the service to authenticate him/her (and
- * {@code flags} contains {@link #FLAG_AUTHENTICATION_REQUESTED}), and {@code extras} contains
- * the {@link Bundle} passed to that method.
- *
- * <p>When the {@link FillResponse} required authentication through
- * {@link android.view.autofill.FillResponse.Builder#requiresFingerprintAuthentication(
- * android.hardware.fingerprint.FingerprintManager.CryptoObject, Bundle, int)},
- * {@code flags} this call contains the result of the fingerprint authentication (such as
- * {@link #FLAG_AUTHENTICATION_SUCCESS}, {@link #FLAG_AUTHENTICATION_ERROR}, and
- * {@link #FLAG_FINGERPRINT_AUTHENTICATION_NOT_AVAILABLE}) and {@code extras} contains the
- * {@link Bundle} passed to that method.
- */
- public void onFillResponseAuthenticationRequest(@SuppressWarnings("unused") Bundle extras,
- int flags) {
- if (DEBUG) Log.d(TAG, "onFillResponseAuthenticationRequest(): flags=" + flags);
- }
-
- /**
- * Called as result of the user action for a {@link Dataset} that required authentication.
- *
- * <p>When the {@link Dataset} required authentication through
- * {@link android.view.autofill.Dataset.Builder#requiresCustomAuthentication(Bundle, int)}, this
- * call indicates the user is requesting the service to authenticate him/her (and {@code flags}
- * contains {@link #FLAG_AUTHENTICATION_REQUESTED}), and {@code extras} contains the
- * {@link Bundle} passed to that method.
- *
- * <p>When the {@link Dataset} required authentication through
- * {@link android.view.autofill.Dataset.Builder#requiresFingerprintAuthentication(
- * android.hardware.fingerprint.FingerprintManager.CryptoObject, Bundle, int)},
- * {@code flags} this call contains the result of the fingerprint authentication (such as
- * {@link #FLAG_AUTHENTICATION_SUCCESS}, {@link #FLAG_AUTHENTICATION_ERROR}, and
- * {@link #FLAG_FINGERPRINT_AUTHENTICATION_NOT_AVAILABLE}) and {@code extras} contains the
- * {@link Bundle} passed to that method.
- */
- public void onDatasetAuthenticationRequest(@SuppressWarnings("unused") Bundle extras,
- int flags) {
- if (DEBUG) Log.d(TAG, "onDatasetAuthenticationRequest(): flags=" + flags);
- }
-
- // TODO(b/33197203): make it final and create another method classes could extend so it's
- // guaranteed to dump the pending callbacks?
- @Override
- protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (mPendingCallbacks != null) {
- pw.print("Number of pending callbacks: "); pw.println(mPendingCallbacks.size());
- final String prefix = " ";
- for (int i = 0; i < mPendingCallbacks.size(); i++) {
- final CallbackHelper.Dumpable cb = mPendingCallbacks.get(i);
- pw.print('#'); pw.print(i + 1); pw.println(':');
- cb.dump(prefix, pw);
- }
- pw.println();
- } else {
- pw.println("Dumping disabled");
- }
- }
-
- private void requestAutoFill(IAutoFillServerCallback callback, AssistStructure structure,
- int flags) {
- if (DEBUG) Log.d(TAG, "requestAutoFill(): flags=" + flags);
-
- if ((flags & AUTO_FILL_FLAG_TYPE_FILL) != 0) {
- final FillCallback fillCallback = new FillCallback(callback);
- if (DEBUG_PENDING_CALLBACKS) {
- addPendingCallback(fillCallback);
- }
- // TODO(b/33197203): hook up the cancelationSignal
- onFillRequest(structure, null, new CancellationSignal(), fillCallback);
- return;
- }
- if ((flags & AUTO_FILL_FLAG_TYPE_SAVE) != 0) {
- final SaveCallback saveCallback = new SaveCallback(callback);
- if (DEBUG_PENDING_CALLBACKS) {
- addPendingCallback(saveCallback);
- }
- onSaveRequest(structure, null, saveCallback);
- return;
- }
-
- Log.w(TAG, "invalid flags on requestAutoFill(): " + flags);
- }
-
- private void addPendingCallback(CallbackHelper.Dumpable callback) {
- if (mPendingCallbacks == null) {
- // Shouldn't happend since call is controlled by DEBUG_PENDING_CALLBACKS guard.
- Log.wtf(TAG, "addPendingCallback(): mPendingCallbacks not set");
- return;
- }
-
- if (DEBUG) Log.d(TAG, "Adding pending callback: " + callback);
-
- callback.setFinalizer(() -> {
- if (DEBUG) Log.d(TAG, "Removing pending callback: " + callback);
- mPendingCallbacks.remove(callback);
- });
- mPendingCallbacks.add(callback);
- }
+ public abstract void onSaveRequest(@NonNull AssistStructure structure, @Nullable Bundle data,
+ @NonNull SaveCallback callback);
/**
* Called when the Android system disconnects from the service.
@@ -378,6 +221,6 @@
* <p> At this point this service may no longer be an active {@link AutoFillService}.
*/
public void onDisconnected() {
- if (DEBUG) Log.d(TAG, "onDisconnected()");
+
}
}
diff --git a/core/java/android/service/autofill/AutoFillServiceInfo.java b/core/java/android/service/autofill/AutoFillServiceInfo.java
index fd957f1..985e32f 100644
--- a/core/java/android/service/autofill/AutoFillServiceInfo.java
+++ b/core/java/android/service/autofill/AutoFillServiceInfo.java
@@ -16,6 +16,7 @@
package android.service.autofill;
import android.Manifest;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.AppGlobals;
import android.content.ComponentName;
@@ -25,7 +26,6 @@
import android.content.res.TypedArray;
import android.content.res.XmlResourceParser;
import android.os.RemoteException;
-import android.util.AndroidException;
import android.util.AttributeSet;
import android.util.Log;
import android.util.Xml;
@@ -40,13 +40,10 @@
/**
* {@link ServiceInfo} and meta-data about an {@link AutoFillService}.
*
- * <p>Upon construction, if {@link #getParseError()} is {@code null}, then the service is configured
- * correctly. Otherwise, {@link #getParseError()} indicates the parsing error.
- *
* @hide
*/
public final class AutoFillServiceInfo {
- static final String TAG = "AutoFillServiceInfo";
+ private static final String TAG = "AutoFillServiceInfo";
private static ServiceInfo getServiceInfoOrThrow(ComponentName comp, int userHandle)
throws PackageManager.NameNotFoundException {
@@ -63,10 +60,9 @@
throw new PackageManager.NameNotFoundException(comp.toString());
}
- @Nullable
- private final String mParseError;
-
+ @NonNull
private final ServiceInfo mServiceInfo;
+
@Nullable
private final String mSettingsActivity;
@@ -77,17 +73,7 @@
public AutoFillServiceInfo(PackageManager pm, ServiceInfo si) {
mServiceInfo = si;
- TypedArray metaDataArray;
- try {
- metaDataArray = getMetaDataArray(pm, si);
- } catch (AndroidException e) {
- mParseError = e.getMessage();
- mSettingsActivity = null;
- Log.w(TAG, mParseError, e);
- return;
- }
-
- mParseError = null;
+ final TypedArray metaDataArray = getMetaDataArray(pm, si);
if (metaDataArray != null) {
mSettingsActivity =
metaDataArray.getString(R.styleable.AutoFillService_settingsActivity);
@@ -101,12 +87,11 @@
* Gets the meta-data as a TypedArray, or null if not provided, or throws if invalid.
*/
@Nullable
- private static TypedArray getMetaDataArray(PackageManager pm, ServiceInfo si)
- throws AndroidException {
+ private static TypedArray getMetaDataArray(PackageManager pm, ServiceInfo si) {
// Check for permissions.
if (!Manifest.permission.BIND_AUTO_FILL.equals(si.permission)) {
- throw new AndroidException(
- "Service does not require permission " + Manifest.permission.BIND_AUTO_FILL);
+ Log.e(TAG, "Service does not require permission " + Manifest.permission.BIND_AUTO_FILL);
+ return null;
}
// Get the AutoFill metadata, if declared.
@@ -125,11 +110,13 @@
&& type != XmlPullParser.START_TAG) {
}
} catch (XmlPullParserException | IOException e) {
- throw new AndroidException("Error parsing auto fill service meta-data: " + e, e);
+ Log.e(TAG, "Error parsing auto fill service meta-data", e);
+ return null;
}
if (!"autofill-service".equals(parser.getName())) {
- throw new AndroidException("Meta-data does not start with autofill-service tag");
+ Log.e(TAG, "Meta-data does not start with autofill-service tag");
+ return null;
}
attrs = Xml.asAttributeSet(parser);
@@ -138,7 +125,8 @@
try {
res = pm.getResourcesForApplication(si.applicationInfo);
} catch (PackageManager.NameNotFoundException e) {
- throw new AndroidException("Error getting application resources: " + e, e);
+ Log.e(TAG, "Error getting application resources", e);
+ return null;
}
return res.obtainAttributes(attrs, R.styleable.AutoFillService);
@@ -147,11 +135,6 @@
}
}
- @Nullable
- public String getParseError() {
- return mParseError;
- }
-
public ServiceInfo getServiceInfo() {
return mServiceInfo;
}
diff --git a/core/java/android/service/autofill/FillCallback.java b/core/java/android/service/autofill/FillCallback.java
index 7cab7ae..a306809 100644
--- a/core/java/android/service/autofill/FillCallback.java
+++ b/core/java/android/service/autofill/FillCallback.java
@@ -16,56 +16,32 @@
package android.service.autofill;
-import static android.service.autofill.AutoFillService.DEBUG;
-import static android.util.DebugUtils.flagsToString;
-
import android.annotation.Nullable;
import android.app.Activity;
import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
import android.os.RemoteException;
-import android.service.autofill.CallbackHelper.Dumpable;
-import android.service.autofill.CallbackHelper.Finalizer;
-import android.util.Log;
-import android.view.autofill.Dataset;
import android.view.autofill.FillResponse;
-import com.android.internal.annotations.GuardedBy;
-import com.android.internal.util.Preconditions;
-
-import java.io.PrintWriter;
-
/**
* Handles auto-fill requests from the {@link AutoFillService} into the {@link Activity} being
* auto-filled.
- *
- * <p>This class is thread safe.
*/
-public final class FillCallback implements Dumpable {
-
- private static final String TAG = "FillCallback";
-
- // NOTE: constants below are public so they can be used by flagsToString()
- /** @hide */ public static final int STATE_INITIAL = 1 << 0;
- /** @hide */ public static final int STATE_WAITING_FILL_RESPONSE_AUTH_RESPONSE = 1 << 1;
- /** @hide */ public static final int STATE_WAITING_DATASET_AUTH_RESPONSE = 1 << 2;
- /** @hide */ public static final int STATE_FINISHED_OK = 1 << 3;
- /** @hide */ public static final int STATE_FINISHED_FAILURE = 1 << 4;
- /** @hide */ public static final int STATE_FINISHED_ERROR = 1 << 5;
- /** @hide */ public static final int STATE_FINISHED_AUTHENTICATED = 1 << 6;
-
- private final IAutoFillServerCallback mCallback;
-
- @GuardedBy("mCallback")
- private int mState = STATE_INITIAL;
-
- @GuardedBy("mCallback")
- private Finalizer mFinalizer;
+public final class FillCallback implements Parcelable {
+ private final IFillCallback mCallback;
+ private boolean mCalled;
/** @hide */
- FillCallback(IAutoFillServerCallback callback) {
+ public FillCallback(IFillCallback callback) {
mCallback = callback;
}
+ /** @hide */
+ private FillCallback(Parcel parcel) {
+ mCallback = IFillCallback.Stub.asInterface(parcel.readStrongBinder());
+ }
+
/**
* Notifies the Android System that an
* {@link AutoFillService#onFillRequest(android.app.assist.AssistStructure, Bundle,
@@ -76,43 +52,12 @@
* {@link FillResponse} for examples.
*/
public void onSuccess(@Nullable FillResponse response) {
- final boolean authRequired = response != null && response.isAuthRequired();
-
- if (DEBUG) Log.d(TAG, "onSuccess(): authReq= " + authRequired + ", resp=" + response);
-
- synchronized (mCallback) {
- if (authRequired) {
- assertOnStateLocked(STATE_INITIAL);
- } else {
- assertOnStateLocked(STATE_INITIAL | STATE_WAITING_FILL_RESPONSE_AUTH_RESPONSE
- | STATE_WAITING_DATASET_AUTH_RESPONSE);
- }
-
- try {
- mCallback.showResponse(response);
- if (authRequired) {
- mState = STATE_WAITING_FILL_RESPONSE_AUTH_RESPONSE;
- } else {
- // Check if at least one dataset requires authentication.
- boolean waitingAuth = false;
- if (response != null) {
- for (Dataset dataset : response.getDatasets()) {
- if (dataset.isAuthRequired()) {
- waitingAuth = true;
- break;
- }
- }
- }
- if (waitingAuth) {
- mState = STATE_WAITING_DATASET_AUTH_RESPONSE;
- } else {
- setFinalStateLocked(STATE_FINISHED_OK);
- }
- }
- } catch (RemoteException e) {
- setFinalStateLocked(STATE_FINISHED_ERROR);
- e.rethrowAsRuntimeException();
- }
+ assertNotCalled();
+ mCalled = true;
+ try {
+ mCallback.onSuccess(response);
+ } catch (RemoteException e) {
+ e.rethrowAsRuntimeException();
}
}
@@ -124,118 +69,43 @@
*
* @param message error message to be displayed to the user.
*/
- public void onFailure(CharSequence message) {
- if (DEBUG) Log.d(TAG, "onFailure(): message=" + message);
-
- Preconditions.checkArgument(message != null, "message cannot be null");
-
- synchronized (mCallback) {
- assertOnStateLocked(STATE_INITIAL | STATE_WAITING_FILL_RESPONSE_AUTH_RESPONSE
- | STATE_WAITING_DATASET_AUTH_RESPONSE);
-
- try {
- mCallback.showError(message);
- setFinalStateLocked(STATE_FINISHED_FAILURE);
- } catch (RemoteException e) {
- setFinalStateLocked(STATE_FINISHED_ERROR);
- e.rethrowAsRuntimeException();
- }
+ public void onFailure(@Nullable CharSequence message) {
+ assertNotCalled();
+ mCalled = true;
+ try {
+ mCallback.onFailure(message);
+ } catch (RemoteException e) {
+ e.rethrowAsRuntimeException();
}
}
- /**
- * Notifies the Android System when the user authenticated a {@link FillResponse} previously
- * passed to {@link #onSuccess(FillResponse)}.
- *
- * @param flags must contain either
- * {@link android.service.autofill.AutoFillService#FLAG_AUTHENTICATION_ERROR} or
- * {@link android.service.autofill.AutoFillService#FLAG_AUTHENTICATION_SUCCESS}.
- */
- public void onFillResponseAuthentication(int flags) {
- if (DEBUG) Log.d(TAG, "onFillResponseAuthentication(): flags=" + flags);
-
- synchronized (mCallback) {
- assertOnStateLocked(STATE_WAITING_FILL_RESPONSE_AUTH_RESPONSE);
-
- try {
- mCallback.unlockFillResponse(flags);
- setFinalStateLocked(STATE_FINISHED_AUTHENTICATED);
- } catch (RemoteException e) {
- setFinalStateLocked(STATE_FINISHED_ERROR);
- e.rethrowAsRuntimeException();
- }
- }
- }
-
- /**
- * Notifies the Android System when the user authenticated a {@link Dataset} previously passed
- * to {@link #onSuccess(FillResponse)}.
- *
- * @param dataset values to fill the activity with in case of successful authentication of a
- * previously locked (and empty) dataset).
- * @param flags must contain either
- * {@link android.service.autofill.AutoFillService#FLAG_AUTHENTICATION_ERROR} or
- * {@link android.service.autofill.AutoFillService#FLAG_AUTHENTICATION_SUCCESS}.
- */
- public void onDatasetAuthentication(@Nullable Dataset dataset, int flags) {
- if (DEBUG) Log.d(TAG, "onDatasetAuthentication(): dataset=" + dataset + ", flags=" + flags);
-
- synchronized (mCallback) {
- assertOnStateLocked(STATE_WAITING_DATASET_AUTH_RESPONSE);
-
- try {
- mCallback.unlockDataset(dataset, flags);
- setFinalStateLocked(STATE_FINISHED_AUTHENTICATED);
- } catch (RemoteException e) {
- setFinalStateLocked(STATE_FINISHED_ERROR);
- e.rethrowAsRuntimeException();
- }
- }
- }
-
- @Override
- public String toString() {
- if (!DEBUG) return super.toString();
-
- return "FillCallback: [mState = " + mState + "]";
- }
-
/** @hide */
@Override
- public void dump(String prefix, PrintWriter pw) {
- pw.print(prefix); pw.print("FillCallback: mState="); pw.println(mState);
+ public int describeContents() {
+ return 0;
}
/** @hide */
@Override
- public void setFinalizer(Finalizer f) {
- synchronized (mCallback) {
- mFinalizer = f;
+ public void writeToParcel(Parcel parcel, int flags) {
+ parcel.writeStrongBinder(mCallback.asBinder());
+ }
+
+ private void assertNotCalled() {
+ if (mCalled) {
+ throw new IllegalStateException("Already called");
}
}
- /**
- * Sets a final state (where the callback cannot be used anymore) and notifies the
- * {@link Finalizer} (if any).
- */
- private void setFinalStateLocked(int state) {
- if (DEBUG) Log.d(TAG, "setFinalState(): " + state);
- mState = state;
-
- if (mFinalizer != null) {
- mFinalizer.gone();
+ public static final Creator<FillCallback> CREATOR = new Creator<FillCallback>() {
+ @Override
+ public FillCallback createFromParcel(Parcel parcel) {
+ return new FillCallback(parcel);
}
- }
- // TODO(b/33197203): move and/or re-add state check logic on server side to avoid malicious app
- // calling the callback on wrong state.
-
- // Make sure callback method is called during the proper lifecycle state.
- private void assertOnStateLocked(int flags) {
- if (DEBUG) Log.d(TAG, "assertOnState(): current=" + mState + ", required=" + flags);
-
- Preconditions.checkState((flags & mState) != 0,
- "invalid state: required " + flagsToString(FillCallback.class, "STATE_", flags)
- + ", current is " + flagsToString(FillCallback.class, "STATE_", mState));
- }
+ @Override
+ public FillCallback[] newArray(int size) {
+ return new FillCallback[size];
+ }
+ };
}
diff --git a/core/java/android/service/autofill/IAutoFillAppCallback.aidl b/core/java/android/service/autofill/IAutoFillAppCallback.aidl
index 8c3898a..c2e72e8 100644
--- a/core/java/android/service/autofill/IAutoFillAppCallback.aidl
+++ b/core/java/android/service/autofill/IAutoFillAppCallback.aidl
@@ -18,6 +18,8 @@
import java.util.List;
+import android.content.Intent;
+import android.content.IntentSender;
import android.view.autofill.Dataset;
/**
@@ -31,4 +33,15 @@
* Auto-fills the activity with the contents of a dataset.
*/
void autoFill(in Dataset dataset);
+
+ /**
+ * Start an intent sender from the context of the filled app
+ */
+ void startIntentSender(in IntentSender intent, in Intent fillInIntent);
+
+ /**
+ * Called by system_service to enable auto-fill in a session, after it was asynchronously
+ * started by the manager.
+ */
+ void enableSession();
}
diff --git a/core/java/android/service/autofill/IAutoFillManagerService.aidl b/core/java/android/service/autofill/IAutoFillManagerService.aidl
index ace5411..b39c0c8 100644
--- a/core/java/android/service/autofill/IAutoFillManagerService.aidl
+++ b/core/java/android/service/autofill/IAutoFillManagerService.aidl
@@ -18,7 +18,9 @@
import android.graphics.Rect;
import android.os.Bundle;
+import android.os.IBinder;
import android.view.autofill.AutoFillId;
+import android.view.autofill.AutoFillValue;
/**
* Mediator between apps being auto-filled and auto-fill service implementations.
@@ -26,10 +28,13 @@
* {@hide}
*/
oneway interface IAutoFillManagerService {
+ // Methods called by AutoFillManager
+ void startSession(in IBinder activityToken, in IBinder appCallback, in AutoFillId autoFillId,
+ in Rect bounds, in AutoFillValue value);
+ void updateSession(in IBinder activityToken, in AutoFillId id, in Rect bounds,
+ in AutoFillValue value, int flags);
+ void finishSession(in IBinder activityToken);
- // Called by AutoFillManager (app).
- void requestAutoFill(in AutoFillId id, in Rect bounds, int flags);
-
- // Called by ShellCommand only.
- void requestAutoFillForUser(int userId, int flags);
+ // Methods called by ShellCommand
+ void requestSaveForUser(int userId);
}
diff --git a/core/java/android/service/autofill/IAutoFillServerCallback.aidl b/core/java/android/service/autofill/IAutoFillServerCallback.aidl
deleted file mode 100644
index f7d5064..0000000
--- a/core/java/android/service/autofill/IAutoFillServerCallback.aidl
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2016 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.service.autofill;
-
-import java.util.List;
-
-import android.os.Bundle;
-import android.view.autofill.AutoFillId;
-import android.view.autofill.Dataset;
-import android.view.autofill.FillResponse;
-
-/**
- * Object running in the AutoFillService process and used to communicate back with system_server.
- *
- * @hide
- */
-// TODO(b/33197203): rename to IAutoFillServerSession
-oneway interface IAutoFillServerCallback {
- // TODO(b/33197203): document methods
- void showResponse(in FillResponse response);
- void showError(CharSequence message);
- void highlightSavedFields(in AutoFillId[] ids);
- void unlockFillResponse(int flags);
- void unlockDataset(in Dataset dataset, int flags);
-}
diff --git a/core/java/android/service/autofill/IAutoFillService.aidl b/core/java/android/service/autofill/IAutoFillService.aidl
index 3e8087b..fa1ea65 100644
--- a/core/java/android/service/autofill/IAutoFillService.aidl
+++ b/core/java/android/service/autofill/IAutoFillService.aidl
@@ -18,18 +18,20 @@
import android.app.assist.AssistStructure;
import android.os.Bundle;
-import android.service.autofill.IAutoFillServerCallback;
+import android.service.autofill.IFillCallback;
+import android.service.autofill.ISaveCallback;
import com.android.internal.os.IResultReceiver;
/**
+ * Interface from the system to an auto fill service.
+ *
* @hide
*/
-// TODO(b/33197203): document class and methods
oneway interface IAutoFillService {
- // TODO(b/33197203): rename method to make them more consistent
- void autoFill(in AssistStructure structure, in IAutoFillServerCallback callback, int flags);
- void authenticateFillResponse(in Bundle extras, int flags);
- void authenticateDataset(in Bundle extras, int flags);
+ void onFillRequest(in AssistStructure structure, in Bundle extras,
+ in IFillCallback callback);
+ void onSaveRequest(in AssistStructure structure, in Bundle extras,
+ in ISaveCallback callback);
void onConnected();
void onDisconnected();
}
diff --git a/core/java/android/service/autofill/CallbackHelper.java b/core/java/android/service/autofill/IFillCallback.aidl
similarity index 66%
copy from core/java/android/service/autofill/CallbackHelper.java
copy to core/java/android/service/autofill/IFillCallback.aidl
index ded8f97..537403e 100644
--- a/core/java/android/service/autofill/CallbackHelper.java
+++ b/core/java/android/service/autofill/IFillCallback.aidl
@@ -13,18 +13,20 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package android.service.autofill;
-import java.io.PrintWriter;
+import android.os.ICancellationSignal;
-final class CallbackHelper {
+import android.view.autofill.FillResponse;
- static interface Dumpable {
- void dump(String prefix, PrintWriter pw);
- void setFinalizer(Finalizer f);
- }
-
- static interface Finalizer {
- void gone();
- }
+/**
+ * Interface to receive the result of a save request.
+ *
+ * @hide
+ */
+interface IFillCallback {
+ void onCancellable(in ICancellationSignal cancellation);
+ void onSuccess(in FillResponse response);
+ void onFailure(CharSequence message);
}
diff --git a/core/java/android/service/autofill/CallbackHelper.java b/core/java/android/service/autofill/ISaveCallback.aidl
similarity index 72%
rename from core/java/android/service/autofill/CallbackHelper.java
rename to core/java/android/service/autofill/ISaveCallback.aidl
index ded8f97..e260c73 100644
--- a/core/java/android/service/autofill/CallbackHelper.java
+++ b/core/java/android/service/autofill/ISaveCallback.aidl
@@ -13,18 +13,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package android.service.autofill;
-import java.io.PrintWriter;
-
-final class CallbackHelper {
-
- static interface Dumpable {
- void dump(String prefix, PrintWriter pw);
- void setFinalizer(Finalizer f);
- }
-
- static interface Finalizer {
- void gone();
- }
+/**
+ * Interface to receive the result of a save request.
+ *
+ * @hide
+ */
+interface ISaveCallback {
+ void onSuccess();
+ void onFailure(CharSequence message);
}
diff --git a/core/java/android/service/autofill/SaveCallback.java b/core/java/android/service/autofill/SaveCallback.java
index e2fb588..46b3072 100644
--- a/core/java/android/service/autofill/SaveCallback.java
+++ b/core/java/android/service/autofill/SaveCallback.java
@@ -16,21 +16,9 @@
package android.service.autofill;
-import static android.service.autofill.AutoFillService.DEBUG;
-
import android.app.Activity;
-import android.app.assist.AssistStructure.ViewNode;
import android.os.Bundle;
import android.os.RemoteException;
-import android.service.autofill.CallbackHelper.Dumpable;
-import android.service.autofill.CallbackHelper.Finalizer;
-import android.util.Log;
-import android.view.autofill.AutoFillId;
-
-import com.android.internal.annotations.GuardedBy;
-import com.android.internal.util.Preconditions;
-
-import java.io.PrintWriter;
/**
* Handles save requests from the {@link AutoFillService} into the {@link Activity} being
@@ -38,47 +26,29 @@
*
* <p>This class is thread safe.
*/
-public final class SaveCallback implements Dumpable {
-
- private static final String TAG = "SaveCallback";
-
- private final IAutoFillServerCallback mCallback;
-
- @GuardedBy("mCallback")
- private boolean mReplied = false;
-
- @GuardedBy("mCallback")
- private Finalizer mFinalizer;
+public final class SaveCallback {
+ private final ISaveCallback mCallback;
+ private boolean mCalled;
/** @hide */
- SaveCallback(IAutoFillServerCallback callback) {
+ SaveCallback(ISaveCallback callback) {
mCallback = callback;
}
/**
* Notifies the Android System that an
- * {@link AutoFillService#onSaveRequest(android.app.assist.AssistStructure, Bundle,
+ * {@link AutoFillService#onSaveRequest (android.app.assist.AssistStructure, Bundle,
* SaveCallback)} was successfully fulfilled by the service.
*
- * @param ids ids ({@link ViewNode#getAutoFillId()}) of the fields that were saved.
- *
* @throws RuntimeException if an error occurred while calling the Android System.
*/
- public void onSuccess(AutoFillId[] ids) {
- if (DEBUG) Log.d(TAG, "onSuccess(): ids=" + ((ids == null) ? "null" : ids.length));
-
- Preconditions.checkArgument(ids != null, "ids cannot be null");
- Preconditions.checkArgument(ids.length > 0, "ids cannot be empty");
-
- synchronized (mCallback) {
- checkNotRepliedYetLocked();
- try {
- mCallback.highlightSavedFields(ids);
- } catch (RemoteException e) {
- e.rethrowAsRuntimeException();
- } finally {
- setRepliedLocked();
- }
+ public void onSuccess() {
+ assertNotCalled();
+ mCalled = true;
+ try {
+ mCallback.onSuccess();
+ } catch (RemoteException e) {
+ e.rethrowAsRuntimeException();
}
}
@@ -92,56 +62,18 @@
* @throws RuntimeException if an error occurred while calling the Android System.
*/
public void onFailure(CharSequence message) {
- if (DEBUG) Log.d(TAG, "onFailure(): message=" + message);
-
- Preconditions.checkArgument(message != null, "message cannot be null");
-
- synchronized (mCallback) {
- checkNotRepliedYetLocked();
-
- try {
- mCallback.showError(message);
- } catch (RemoteException e) {
- e.rethrowAsRuntimeException();
- } finally {
- setRepliedLocked();
- }
+ assertNotCalled();
+ mCalled = true;
+ try {
+ mCallback.onFailure(message);
+ } catch (RemoteException e) {
+ e.rethrowAsRuntimeException();
}
}
- /** @hide */
- @Override
- public void dump(String prefix, PrintWriter pw) {
- pw.print(prefix); pw.print("SaveCallback: mReplied="); pw.println(mReplied);
- }
-
- /** @hide */
- @Override
- public void setFinalizer(Finalizer f) {
- synchronized (mCallback) {
- mFinalizer = f;
- }
- }
-
- @Override
- public String toString() {
- if (!DEBUG) return super.toString();
-
- return "SaveCallback: [mReplied= " + mReplied + "]";
- }
-
- // There can be only one!!
- private void checkNotRepliedYetLocked() {
- Preconditions.checkState(!mReplied, "already replied");
- }
-
- private void setRepliedLocked() {
- if (DEBUG) Log.d(TAG, "setReplied()");
-
- mReplied = true;
-
- if (mFinalizer != null) {
- mFinalizer.gone();
+ private void assertNotCalled() {
+ if (mCalled) {
+ throw new IllegalStateException("Already called");
}
}
}
diff --git a/core/java/android/service/quicksettings/TileService.java b/core/java/android/service/quicksettings/TileService.java
index 887f4b6..1781c2a 100644
--- a/core/java/android/service/quicksettings/TileService.java
+++ b/core/java/android/service/quicksettings/TileService.java
@@ -130,6 +130,11 @@
*/
public static final String EXTRA_COMPONENT = "android.service.quicksettings.extra.COMPONENT";
+ /**
+ * @hide
+ */
+ public static final String EXTRA_STATE = "state";
+
private final H mHandler = new H(Looper.getMainLooper());
private boolean mListening = false;
diff --git a/core/java/android/service/voice/VoiceInteractionSession.java b/core/java/android/service/voice/VoiceInteractionSession.java
index 48f3ac3..e9bbc2d 100644
--- a/core/java/android/service/voice/VoiceInteractionSession.java
+++ b/core/java/android/service/voice/VoiceInteractionSession.java
@@ -119,8 +119,6 @@
public static final String KEY_CONTENT = "content";
/** @hide */
public static final String KEY_RECEIVER_EXTRAS = "receiverExtras";
- /** @hide */
- public static final String KEY_FLAGS = "flags";
final Context mContext;
final HandlerCaller mHandlerCaller;
diff --git a/core/java/android/service/vr/IVrManager.aidl b/core/java/android/service/vr/IVrManager.aidl
index 62ecab3..10e4177 100644
--- a/core/java/android/service/vr/IVrManager.aidl
+++ b/core/java/android/service/vr/IVrManager.aidl
@@ -42,5 +42,13 @@
*/
boolean getVrModeState();
+ /**
+ * Sets the persistent VR mode state of a device. When a device is in persistent VR mode it will
+ * remain in VR mode even if the foreground does not specify VR mode being enabled. Mainly used
+ * by VR viewers to indicate that a device is placed in a VR viewer.
+ *
+ * @param enabled true if the device should be placed in persistent VR mode.
+ */
+ void setPersistentVrModeEnabled(in boolean enabled);
}
diff --git a/core/java/android/text/TextUtils.java b/core/java/android/text/TextUtils.java
index bb952ab..55aeb1e 100644
--- a/core/java/android/text/TextUtils.java
+++ b/core/java/android/text/TextUtils.java
@@ -62,6 +62,7 @@
import com.android.internal.R;
import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.Preconditions;
import java.lang.reflect.Array;
import java.util.Iterator;
@@ -466,6 +467,16 @@
return isEmpty(str) ? null : str;
}
+ /** {@hide} */
+ public static String emptyIfNull(@Nullable String str) {
+ return str == null ? "" : str;
+ }
+
+ /** {@hide} */
+ public static String firstNotEmpty(@Nullable String a, @NonNull String b) {
+ return !isEmpty(a) ? a : Preconditions.checkStringNotEmpty(b);
+ }
+
/**
* Returns the length that the specified CharSequence would have if
* spaces and ASCII control characters were trimmed from the start and end,
diff --git a/core/java/android/text/style/ClickableSpan.java b/core/java/android/text/style/ClickableSpan.java
index a183427..b098f16 100644
--- a/core/java/android/text/style/ClickableSpan.java
+++ b/core/java/android/text/style/ClickableSpan.java
@@ -22,7 +22,7 @@
/**
* If an object of this type is attached to the text of a TextView
* with a movement method of LinkMovementMethod, the affected spans of
- * text can be selected. If clicked, the {@link #onClick} method will
+ * text can be selected. If selected and clicked, the {@link #onClick} method will
* be called.
*/
public abstract class ClickableSpan extends CharacterStyle implements UpdateAppearance {
diff --git a/core/java/android/transition/ChangeTransform.java b/core/java/android/transition/ChangeTransform.java
index 4b0b065..5303855 100644
--- a/core/java/android/transition/ChangeTransform.java
+++ b/core/java/android/transition/ChangeTransform.java
@@ -141,9 +141,10 @@
* child view will be relative to its parent's final position, so it may appear to "jump"
* at the beginning.</p>
*
- * @return <code>true</code> when a changed parent should execute the transition
- * inside the scene root's overlay or <code>false</code> if a parent change only
- * affects the transform of the transitioning view.
+ * @param reparentWithOverlay <code>true</code> when a changed parent should execute the
+ * transition inside the scene root's overlay or <code>false</code>
+ * if a parent change only affects the transform of the transitioning
+ * view.
* @attr ref android.R.styleable#ChangeTransform_reparentWithOverlay
*/
public void setReparentWithOverlay(boolean reparentWithOverlay) {
@@ -465,7 +466,7 @@
}
}
- private static class GhostListener extends Transition.TransitionListenerAdapter {
+ private static class GhostListener extends TransitionListenerAdapter {
private View mView;
private View mStartView;
private GhostView mGhostView;
diff --git a/core/java/android/transition/Transition.java b/core/java/android/transition/Transition.java
index 8823605..af2547e 100644
--- a/core/java/android/transition/Transition.java
+++ b/core/java/android/transition/Transition.java
@@ -2342,34 +2342,6 @@
}
/**
- * Utility adapter class to avoid having to override all three methods
- * whenever someone just wants to listen for a single event.
- *
- * @hide
- * */
- public static class TransitionListenerAdapter implements TransitionListener {
- @Override
- public void onTransitionStart(Transition transition) {
- }
-
- @Override
- public void onTransitionEnd(Transition transition) {
- }
-
- @Override
- public void onTransitionCancel(Transition transition) {
- }
-
- @Override
- public void onTransitionPause(Transition transition) {
- }
-
- @Override
- public void onTransitionResume(Transition transition) {
- }
- }
-
- /**
* Holds information about each animator used when a new transition starts
* while other transitions are still running to determine whether a running
* animation should be canceled or a new animation noop'd. The structure holds
diff --git a/core/java/android/transition/TransitionListenerAdapter.java b/core/java/android/transition/TransitionListenerAdapter.java
new file mode 100644
index 0000000..c217949
--- /dev/null
+++ b/core/java/android/transition/TransitionListenerAdapter.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2016 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.transition;
+
+/**
+ * This adapter class provides empty implementations of the methods from {@link
+ * android.transition.Transition.TransitionListener}.
+ * Any custom listener that cares only about a subset of the methods of this listener can
+ * simply subclass this adapter class instead of implementing the interface directly.
+ */
+public abstract class TransitionListenerAdapter implements Transition.TransitionListener {
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void onTransitionStart(Transition transition) {
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void onTransitionEnd(Transition transition) {
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void onTransitionCancel(Transition transition) {
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void onTransitionPause(Transition transition) {
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void onTransitionResume(Transition transition) {
+ }
+}
diff --git a/core/java/android/transition/TransitionManager.java b/core/java/android/transition/TransitionManager.java
index 6e4d78d..325ff38 100644
--- a/core/java/android/transition/TransitionManager.java
+++ b/core/java/android/transition/TransitionManager.java
@@ -298,7 +298,7 @@
previousRunningTransitions = new ArrayList<Transition>(currentTransitions);
}
currentTransitions.add(mTransition);
- mTransition.addListener(new Transition.TransitionListenerAdapter() {
+ mTransition.addListener(new TransitionListenerAdapter() {
@Override
public void onTransitionEnd(Transition transition) {
ArrayList<Transition> currentTransitions =
diff --git a/core/java/android/view/NotificationHeaderView.java b/core/java/android/view/NotificationHeaderView.java
index 0da710a..c3d3f39 100644
--- a/core/java/android/view/NotificationHeaderView.java
+++ b/core/java/android/view/NotificationHeaderView.java
@@ -17,6 +17,7 @@
package android.view;
import android.annotation.Nullable;
+import android.app.Notification;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Outline;
@@ -39,7 +40,7 @@
*/
@RemoteViews.RemoteView
public class NotificationHeaderView extends ViewGroup {
- public static final int NO_COLOR = -1;
+ public static final int NO_COLOR = Notification.COLOR_INVALID;
private final int mChildMinWidth;
private final int mContentEndMargin;
private View mAppName;
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index d2f8818..ee97984 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -39,7 +39,6 @@
import android.annotation.Size;
import android.annotation.TestApi;
import android.annotation.UiThread;
-import android.app.Application.OnProvideAssistDataListener;
import android.content.ClipData;
import android.content.Context;
import android.content.ContextWrapper;
@@ -4023,39 +4022,6 @@
int mLayerType = LAYER_TYPE_NONE;
Paint mLayerPaint;
-
- /**
- * Set when a request was made to decide if views in an {@link android.app.Activity} can be
- * auto-filled by an {@link android.service.autofill.AutoFillService}.
- *
- * <p>Since this request is made without a explicit user consent, the resulting
- * {@link android.app.assist.AssistStructure} should not contain any PII
- * (Personally Identifiable Information).
- *
- * <p>Examples:
- * <ul>
- * <li>{@link android.widget.TextView} texts should only be included when they were set by
- * static resources.
- * <li>{@link android.webkit.WebView} virtual children should be restricted to a subset of
- * input fields and tags (like {@code id}).
- * </ul>
- */
- // TODO(b/33197203): cannot conflict with flags defined on AutoFillManager until they're removed
- // (when save is refactored).
- public static final int AUTO_FILL_FLAG_TYPE_FILL = 0x10000000;
-
- /**
- * Set when the user explicitly asked a {@link android.service.autofill.AutoFillService} to save
- * the value of the {@link View}s in an {@link android.app.Activity}.
- *
- * <p>The resulting {@link android.app.assist.AssistStructure} can contain any kind of PII
- * (Personally Identifiable Information). For example, the text of password fields should be
- * included since that's what's typically saved.
- */
- // TODO(b/33197203): cannot conflict with flags defined on AutoFillManager until they're removed
- // (when save is refactored).
- public static final int AUTO_FILL_FLAG_TYPE_SAVE = 0x20000000;
-
/**
* Set to true when drawing cache is enabled and cannot be created.
*
@@ -6409,7 +6375,9 @@
if ((mViewFlags & VISIBILITY_MASK) != VISIBLE) {
return false;
}
- return allowAutoFocus ? getFocusable() != NOT_FOCUSABLE : getFocusable() == FOCUSABLE;
+ return (allowAutoFocus
+ ? getFocusable() != NOT_FOCUSABLE
+ : getFocusable() == FOCUSABLE) && isFocusable();
}
/**
@@ -6456,9 +6424,7 @@
if (isAutoFillable()) {
AutoFillManager afm = getAutoFillManager();
if (afm != null) {
- afm.updateAutoFillInput(this, gainFocus
- ? AutoFillManager.FLAG_UPDATE_UI_SHOW
- : AutoFillManager.FLAG_UPDATE_UI_HIDE);
+ afm.focusChanged(this, gainFocus);
}
}
@@ -6912,7 +6878,7 @@
* fills in all data that can be inferred from the view itself.
*/
public void onProvideStructure(ViewStructure structure) {
- onProvideStructureForAssistOrAutoFill(structure, 0);
+ onProvideStructureForAssistOrAutoFill(structure, false);
}
/**
@@ -6923,19 +6889,14 @@
*
* @param structure Fill in with structured view data. The default implementation
* fills in all data that can be inferred from the view itself.
- * @param flags optional flags (see {@link #AUTO_FILL_FLAG_TYPE_FILL} and
- * {@link #AUTO_FILL_FLAG_TYPE_SAVE} for more info).
+ * @param flags optional flags (currently {@code 0}).
*/
public void onProvideAutoFillStructure(ViewStructure structure, int flags) {
- onProvideStructureForAssistOrAutoFill(structure, flags);
+ onProvideStructureForAssistOrAutoFill(structure, true);
}
- private void onProvideStructureForAssistOrAutoFill(ViewStructure structure, int flags) {
- // NOTE: currently flags are only used for AutoFill; if they're used for Assist as well,
- // this method should take a boolean with the type of request.
- boolean forAutoFill = (flags
- & (View.AUTO_FILL_FLAG_TYPE_FILL
- | View.AUTO_FILL_FLAG_TYPE_SAVE)) != 0;
+ private void onProvideStructureForAssistOrAutoFill(ViewStructure structure,
+ boolean forAutoFill) {
final int id = mID;
if (id != NO_ID && !isViewIdGenerated(id)) {
String pkg, type, entry;
@@ -6953,10 +6914,16 @@
}
if (forAutoFill) {
- // The auto-fill id needs to be unique, but its value doesn't matter, so it's better to
- // reuse the accessibility id to save space.
- structure.setAutoFillId(getAccessibilityViewId());
- structure.setAutoFillType(getAutoFillType());
+ final AutoFillType autoFillType = getAutoFillType();
+ // Don't need to fill auto-fill info if view does not support it.
+ // For example, only TextViews that are editable support auto-fill
+ if (autoFillType != null) {
+ // The auto-fill id needs to be unique, but its value doesn't matter, so it's better
+ // to reuse the accessibility id to save space.
+ structure.setAutoFillId(getAccessibilityViewId());
+ structure.setAutoFillType(autoFillType);
+ structure.setAutoFillValue(getAutoFillValue());
+ }
}
structure.setDimens(mLeft, mTop, mScrollX, mScrollY, mRight - mLeft, mBottom - mTop);
@@ -7009,7 +6976,7 @@
* optimal implementation providing this data.
*/
public void onProvideVirtualStructure(ViewStructure structure) {
- onProvideVirtualStructureForAssistOrAutoFill(structure, 0);
+ onProvideVirtualStructureForAssistOrAutoFill(structure, false);
}
/**
@@ -7024,14 +6991,14 @@
* {@code flags} parameter - see the documentation on each flag for more details.
*
* @param structure Fill in with structured view data.
- * @param flags optional flags (see {@link #AUTO_FILL_FLAG_TYPE_FILL} and
- * {@link #AUTO_FILL_FLAG_TYPE_SAVE} for more info).
+ * @param flags optional flags (currently {@code 0}).
*/
public void onProvideAutoFillVirtualStructure(ViewStructure structure, int flags) {
- onProvideVirtualStructureForAssistOrAutoFill(structure, flags);
+ onProvideVirtualStructureForAssistOrAutoFill(structure, true);
}
- private void onProvideVirtualStructureForAssistOrAutoFill(ViewStructure structure, int flags) {
+ private void onProvideVirtualStructureForAssistOrAutoFill(ViewStructure structure,
+ boolean forAutoFill) {
// NOTE: currently flags are only used for AutoFill; if they're used for Assist as well,
// this method should take a boolean with the type of request.
AccessibilityNodeProvider provider = getAccessibilityNodeProvider();
@@ -7039,7 +7006,7 @@
AccessibilityNodeInfo info = createAccessibilityNodeInfo();
structure.setChildCount(1);
ViewStructure root = structure.newChild(0);
- populateVirtualStructure(root, provider, info, flags);
+ populateVirtualStructure(root, provider, info, forAutoFill);
info.recycle();
}
}
@@ -7049,21 +7016,18 @@
* this view.
*
* <p>By default returns {@code null} but should be overridden when view provides a virtual
- * hierachy on {@link OnProvideAssistDataListener} that takes flags used by the AutoFill
- * Framework (such as {@link #AUTO_FILL_FLAG_TYPE_FILL} and
- * {@link #AUTO_FILL_FLAG_TYPE_SAVE}).
+ * hierachy on {@link #onProvideAutoFillVirtualStructure(ViewStructure, int)}.
*/
@Nullable
- public VirtualViewDelegate getAutoFillVirtualViewDelegate(
- @SuppressWarnings("unused") VirtualViewDelegate.Callback callback) {
+ public VirtualViewDelegate getAutoFillVirtualViewDelegate() {
return null;
}
/**
* Automatically fills the content of this view with the {@code value}.
*
- * <p>By default does nothing, but views should override it (and {@link #getAutoFillType()} to
- * support the AutoFill Framework.
+ * <p>By default does nothing, but views should override it (and {@link #getAutoFillType()
+ * and #getAutoFillValue()} to support the AutoFill Framework.
*
* <p>Typically, it is implemented by:
*
@@ -7097,6 +7061,18 @@
return null;
}
+ /**
+ * Gets the {@link View}'s current auto-fill value.
+ *
+ * <p>By default returns {@code null}, but views should override it,
+ * {@link #autoFill(AutoFillValue)}, and {@link #getAutoFillType()} to support the AutoFill
+ * Framework.
+ */
+ @Nullable
+ public AutoFillValue getAutoFillValue() {
+ return null;
+ }
+
@Nullable
private AutoFillManager getAutoFillManager() {
return mContext.getSystemService(AutoFillManager.class);
@@ -7107,12 +7083,7 @@
}
private void populateVirtualStructure(ViewStructure structure,
- AccessibilityNodeProvider provider, AccessibilityNodeInfo info, int flags) {
- // NOTE: currently flags are only used for AutoFill; if they're used for Assist as well,
- // this method should take a boolean with the type of request.
-
- final boolean sanitized = (flags & View.AUTO_FILL_FLAG_TYPE_FILL) != 0;
-
+ AccessibilityNodeProvider provider, AccessibilityNodeInfo info, boolean forAutoFill) {
structure.setId(AccessibilityNodeInfo.getVirtualDescendantId(info.getSourceNodeId()),
null, null, null);
Rect rect = structure.getTempRect();
@@ -7150,7 +7121,7 @@
CharSequence cname = info.getClassName();
structure.setClassName(cname != null ? cname.toString() : null);
structure.setContentDescription(info.getContentDescription());
- if (!sanitized && (info.getText() != null || info.getError() != null)) {
+ if (!forAutoFill && (info.getText() != null || info.getError() != null)) {
// TODO(b/33197203) (b/33269702): when sanitized, try to use the Accessibility API to
// just set sanitized values (like text coming from resource files), rather than not
// setting it at all.
@@ -7164,7 +7135,7 @@
AccessibilityNodeInfo cinfo = provider.createAccessibilityNodeInfo(
AccessibilityNodeInfo.getVirtualDescendantId(info.getChildId(i)));
ViewStructure child = structure.newChild(i);
- populateVirtualStructure(child, provider, cinfo, flags);
+ populateVirtualStructure(child, provider, cinfo, forAutoFill);
cinfo.recycle();
}
}
@@ -7176,7 +7147,7 @@
* {@link #onProvideVirtualStructure}.
*/
public void dispatchProvideStructure(ViewStructure structure) {
- dispatchProvideStructureForAssistOrAutoFill(structure, 0);
+ dispatchProvideStructureForAssistOrAutoFill(structure, false);
}
/**
@@ -7189,25 +7160,20 @@
* and {@link #onProvideAutoFillVirtualStructure(ViewStructure, int)}.
*
* @param structure Fill in with structured view data.
- * @param flags optional flags (see {@link #AUTO_FILL_FLAG_TYPE_FILL} and
- * {@link #AUTO_FILL_FLAG_TYPE_SAVE} for more info).
+ * @param flags optional flags (currently {@code 0}).
*/
public void dispatchProvideAutoFillStructure(ViewStructure structure, int flags) {
- dispatchProvideStructureForAssistOrAutoFill(structure, flags);
+ dispatchProvideStructureForAssistOrAutoFill(structure, true);
}
- private void dispatchProvideStructureForAssistOrAutoFill(ViewStructure structure, int flags) {
- // NOTE: currently flags are only used for AutoFill; if they're used for Assist as well,
- // this method should take a boolean with the type of request.
- boolean forAutoFill = (flags
- & (View.AUTO_FILL_FLAG_TYPE_FILL
- | View.AUTO_FILL_FLAG_TYPE_SAVE)) != 0;
-
+ private void dispatchProvideStructureForAssistOrAutoFill(ViewStructure structure,
+ boolean forAutoFill) {
boolean blocked = forAutoFill ? isAutoFillBlocked() : isAssistBlocked();
if (!blocked) {
if (forAutoFill) {
- onProvideAutoFillStructure(structure, flags);
- onProvideAutoFillVirtualStructure(structure, flags);
+ // NOTE: flags are not currently supported, hence 0
+ onProvideAutoFillStructure(structure, 0);
+ onProvideAutoFillVirtualStructure(structure, 0);
} else {
onProvideStructure(structure);
onProvideVirtualStructure(structure);
@@ -20010,9 +19976,9 @@
* @return the view of the specified id, null if cannot be found
* @hide
*/
- protected <T extends View> T findViewTraversal(@IdRes int id) {
+ protected View findViewTraversal(@IdRes int id) {
if (id == mID) {
- return (T) this;
+ return this;
}
return null;
}
@@ -20022,9 +19988,9 @@
* @return the view of specified tag, null if cannot be found
* @hide
*/
- protected <T extends View> T findViewWithTagTraversal(Object tag) {
+ protected View findViewWithTagTraversal(Object tag) {
if (tag != null && tag.equals(mTag)) {
- return (T) this;
+ return this;
}
return null;
}
@@ -20035,10 +20001,9 @@
* @return The first view that matches the predicate or null.
* @hide
*/
- protected <T extends View> T findViewByPredicateTraversal(Predicate<View> predicate,
- View childToSkip) {
+ protected View findViewByPredicateTraversal(Predicate<View> predicate, View childToSkip) {
if (predicate.apply(this)) {
- return (T) this;
+ return this;
}
return null;
}
@@ -20051,7 +20016,7 @@
* @return The view that has the given id in the hierarchy or null
*/
@Nullable
- public final <T extends View> T findViewById(@IdRes int id) {
+ public final View findViewById(@IdRes int id) {
if (id < 0) {
return null;
}
@@ -20064,11 +20029,11 @@
* @param accessibilityId The searched accessibility id.
* @return The found view.
*/
- final <T extends View> T findViewByAccessibilityId(int accessibilityId) {
+ final View findViewByAccessibilityId(int accessibilityId) {
if (accessibilityId < 0) {
return null;
}
- T view = findViewByAccessibilityIdTraversal(accessibilityId);
+ View view = findViewByAccessibilityIdTraversal(accessibilityId);
if (view != null) {
return view.includeForAccessibility() ? view : null;
}
@@ -20087,11 +20052,12 @@
*
* @param accessibilityId The accessibility id.
* @return The found view.
+ *
* @hide
*/
- public <T extends View> T findViewByAccessibilityIdTraversal(int accessibilityId) {
+ public View findViewByAccessibilityIdTraversal(int accessibilityId) {
if (getAccessibilityViewId() == accessibilityId) {
- return (T) this;
+ return this;
}
return null;
}
@@ -20103,7 +20069,7 @@
* @param tag The tag to search for, using "tag.equals(getTag())".
* @return The View that has the given tag in the hierarchy or null
*/
- public final <T extends View> T findViewWithTag(Object tag) {
+ public final View findViewWithTag(Object tag) {
if (tag == null) {
return null;
}
@@ -20118,7 +20084,7 @@
* @return The first view that matches the predicate or null.
* @hide
*/
- public final <T extends View> T findViewByPredicate(Predicate<View> predicate) {
+ public final View findViewByPredicate(Predicate<View> predicate) {
return findViewByPredicateTraversal(predicate, null);
}
@@ -20138,11 +20104,10 @@
* @return The first view that matches the predicate or null.
* @hide
*/
- public final <T extends View> T findViewByPredicateInsideOut(
- View start, Predicate<View> predicate) {
+ public final View findViewByPredicateInsideOut(View start, Predicate<View> predicate) {
View childToSkip = null;
for (;;) {
- T view = start.findViewByPredicateTraversal(predicate, childToSkip);
+ View view = start.findViewByPredicateTraversal(predicate, childToSkip);
if (view != null || start == this) {
return view;
}
@@ -24754,7 +24719,7 @@
* Determine if this view is rendered on a round wearable device and is the main view
* on the screen.
*/
- private boolean shouldDrawRoundScrollbar() {
+ boolean shouldDrawRoundScrollbar() {
if (!mResources.getConfiguration().isScreenRound() || mAttachInfo == null) {
return false;
}
@@ -24771,7 +24736,7 @@
return false;
}
- getLocationOnScreen(mAttachInfo.mTmpLocation);
+ getLocationInWindow(mAttachInfo.mTmpLocation);
return mAttachInfo.mTmpLocation[0] == insets.getStableInsetLeft()
&& mAttachInfo.mTmpLocation[1] == insets.getStableInsetTop();
}
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index ab10ac1..aa580fa 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -1114,7 +1114,8 @@
}
// TODO This should probably be super.hasFocusable, but that would change behavior
- if (allowAutoFocus ? getFocusable() != NOT_FOCUSABLE : getFocusable() == FOCUSABLE) {
+ if ((allowAutoFocus ? getFocusable() != NOT_FOCUSABLE : getFocusable() == FOCUSABLE)
+ && isFocusable()) {
return true;
}
@@ -3206,7 +3207,7 @@
@Override
public void dispatchProvideStructure(ViewStructure structure) {
super.dispatchProvideStructure(structure);
- dispatchProvideStructureForAssistOrAutoFill(structure, 0);
+ dispatchProvideStructureForAssistOrAutoFill(structure, false);
}
/**
@@ -3218,16 +3219,11 @@
@Override
public void dispatchProvideAutoFillStructure(ViewStructure structure, int flags) {
super.dispatchProvideAutoFillStructure(structure, flags);
- dispatchProvideStructureForAssistOrAutoFill(structure, flags);
+ dispatchProvideStructureForAssistOrAutoFill(structure, true);
}
- private void dispatchProvideStructureForAssistOrAutoFill(ViewStructure structure, int flags) {
- // NOTE: currently flags are only used for AutoFill; if they're used for Assist as well,
- // this method should take a boolean with the type of request.
- boolean forAutoFill = (flags
- & (View.AUTO_FILL_FLAG_TYPE_FILL
- | View.AUTO_FILL_FLAG_TYPE_SAVE)) != 0;
-
+ private void dispatchProvideStructureForAssistOrAutoFill(ViewStructure structure,
+ boolean forAutoFill) {
boolean blocked = forAutoFill ? isAutoFillBlocked() : isAssistBlocked();
if (!blocked) {
@@ -3294,7 +3290,8 @@
// Must explicitly check which recursive method to call.
if (forAutoFill) {
- child.dispatchProvideAutoFillStructure(cstructure, flags);
+ // NOTE: flags are not currently supported, hence 0
+ child.dispatchProvideAutoFillStructure(cstructure, 0);
} else {
child.dispatchProvideStructure(cstructure);
}
@@ -4211,9 +4208,9 @@
* {@hide}
*/
@Override
- protected <T extends View> T findViewTraversal(@IdRes int id) {
+ protected View findViewTraversal(@IdRes int id) {
if (id == mID) {
- return (T) this;
+ return this;
}
final View[] where = mChildren;
@@ -4226,7 +4223,7 @@
v = v.findViewById(id);
if (v != null) {
- return (T) v;
+ return v;
}
}
}
@@ -4238,9 +4235,9 @@
* {@hide}
*/
@Override
- protected <T extends View> T findViewWithTagTraversal(Object tag) {
+ protected View findViewWithTagTraversal(Object tag) {
if (tag != null && tag.equals(mTag)) {
- return (T) this;
+ return this;
}
final View[] where = mChildren;
@@ -4253,7 +4250,7 @@
v = v.findViewWithTag(tag);
if (v != null) {
- return (T) v;
+ return v;
}
}
}
@@ -4265,10 +4262,9 @@
* {@hide}
*/
@Override
- protected <T extends View> T findViewByPredicateTraversal(Predicate<View> predicate,
- View childToSkip) {
+ protected View findViewByPredicateTraversal(Predicate<View> predicate, View childToSkip) {
if (predicate.apply(this)) {
- return (T) this;
+ return this;
}
final View[] where = mChildren;
@@ -4281,7 +4277,7 @@
v = v.findViewByPredicate(predicate);
if (v != null) {
- return (T) v;
+ return v;
}
}
}
diff --git a/core/java/android/view/ViewStructure.java b/core/java/android/view/ViewStructure.java
index 839e11c..5bae594 100644
--- a/core/java/android/view/ViewStructure.java
+++ b/core/java/android/view/ViewStructure.java
@@ -29,6 +29,15 @@
* View.onProvideStructure}.
*/
public abstract class ViewStructure {
+
+ /**
+ * Flag used when adding virtual views for auto-fill, it indicates the contents of the view
+ * (such as * {@link android.app.assist.AssistStructure.ViewNode#getText()} and
+ * {@link android.app.assist.AssistStructure.ViewNode#getAutoFillValue()})
+ * can be passed to the {@link android.service.autofill.AutoFillService}.
+ */
+ public static final int AUTO_FILL_FLAG_SANITIZED = 0x1;
+
/**
* Set the identifier for this view.
*
@@ -264,8 +273,14 @@
/**
* Like {@link #newChild(int)}, but providing a {@code virtualId} to the child so it can be
* auto-filled by {@link VirtualViewDelegate#autoFill(int, AutoFillValue)}.
+ *
+ * @param index child index
+ * @param virtualId child's id as defined by {@link VirtualViewDelegate#autoFill(int,
+ * AutoFillValue)}.
+ * @param flags currently either {@code 0} or {@link #AUTO_FILL_FLAG_SANITIZED}.
*/
- public abstract ViewStructure newChild(int index, int virtualId);
+ // TODO(b/33197203, b/33802548): add CTS/unit test
+ public abstract ViewStructure newChild(int index, int virtualId, int flags);
/**
* Like {@link #newChild}, but allows the caller to asynchronously populate the returned
@@ -280,15 +295,36 @@
/**
* Like {@link #asyncNewChild(int)}, but providing a {@code virtualId} to the child so it can be
* auto-filled by {@link VirtualViewDelegate#autoFill(int, AutoFillValue)}.
+ *
+ * @param index child index
+ * @param virtualId child's id as defined by {@link VirtualViewDelegate#autoFill(int,
+ * AutoFillValue)}.
+ * @param flags currently either {@code 0} or {@link #AUTO_FILL_FLAG_SANITIZED}.
*/
- public abstract ViewStructure asyncNewChild(int index, int virtualId);
+ // TODO(b/33197203, b/33802548): add CTS/unit test
+ public abstract ViewStructure asyncNewChild(int index, int virtualId, int flags);
/**
* Sets the {@link AutoFillType} that can be used to auto-fill this node.
*/
+ // TODO(b/33197203, b/33802548): add CTS/unit test
public abstract void setAutoFillType(AutoFillType info);
/**
+ * Sets the {@link AutoFillValue} representing the current value of this node.
+ */
+ // TODO(b/33197203, b/33802548): add CTS/unit test
+ public abstract void setAutoFillValue(AutoFillValue value);
+
+ /**
+ * @hide
+ *
+ * TODO(b/33197203, b/33269702): temporary set it as not sanitized until
+ * AssistStructure automaticaly sets sanitization based on text coming from resources
+ */
+ public abstract void setSanitized(boolean sensitive);
+
+ /**
* Call when done populating a {@link ViewStructure} returned by
* {@link #asyncNewChild}.
*/
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index bf840e5..5a640fa 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -335,7 +335,9 @@
@ViewDebug.IntToString(from = TYPE_QS_DIALOG,
to = "TYPE_QS_DIALOG"),
@ViewDebug.IntToString(from = TYPE_SCREENSHOT,
- to = "TYPE_SCREENSHOT")
+ to = "TYPE_SCREENSHOT"),
+ @ViewDebug.IntToString(from = TYPE_APPLICATION_OVERLAY,
+ to = "TYPE_APPLICATION_OVERLAY")
})
public int type;
@@ -462,14 +464,18 @@
* These windows are normally placed above all applications, but behind
* the status bar.
* In multiuser systems shows on all users' windows.
+ * @deprecated for non-system apps. Use {@link #TYPE_APPLICATION_OVERLAY} instead.
*/
+ @Deprecated
public static final int TYPE_PHONE = FIRST_SYSTEM_WINDOW+2;
/**
* Window type: system window, such as low power alert. These windows
* are always on top of application windows.
* In multiuser systems shows only on the owning user's window.
+ * @deprecated for non-system apps. Use {@link #TYPE_APPLICATION_OVERLAY} instead.
*/
+ @Deprecated
public static final int TYPE_SYSTEM_ALERT = FIRST_SYSTEM_WINDOW+3;
/**
@@ -482,7 +488,9 @@
/**
* Window type: transient notifications.
* In multiuser systems shows only on the owning user's window.
+ * @deprecated for non-system apps. Use {@link #TYPE_APPLICATION_OVERLAY} instead.
*/
+ @Deprecated
public static final int TYPE_TOAST = FIRST_SYSTEM_WINDOW+5;
/**
@@ -490,7 +498,9 @@
* on top of everything else. These windows must not take input
* focus, or they will interfere with the keyguard.
* In multiuser systems shows only on the owning user's window.
+ * @deprecated for non-system apps. Use {@link #TYPE_APPLICATION_OVERLAY} instead.
*/
+ @Deprecated
public static final int TYPE_SYSTEM_OVERLAY = FIRST_SYSTEM_WINDOW+6;
/**
@@ -498,7 +508,9 @@
* the keyguard is active. These windows must not take input
* focus, or they will interfere with the keyguard.
* In multiuser systems shows on all users' windows.
+ * @deprecated for non-system apps. Use {@link #TYPE_APPLICATION_OVERLAY} instead.
*/
+ @Deprecated
public static final int TYPE_PRIORITY_PHONE = FIRST_SYSTEM_WINDOW+7;
/**
@@ -517,7 +529,9 @@
* Window type: internal system error windows, appear on top of
* everything they can.
* In multiuser systems shows only on the owning user's window.
+ * @deprecated for non-system apps. Use {@link #TYPE_APPLICATION_OVERLAY} instead.
*/
+ @Deprecated
public static final int TYPE_SYSTEM_ERROR = FIRST_SYSTEM_WINDOW+10;
/**
@@ -703,10 +717,44 @@
public static final int TYPE_PRESENTATION = FIRST_SYSTEM_WINDOW + 37;
/**
+ * Window type: Application overlay windows are displayed above all activity windows
+ * (types between {@link #FIRST_APPLICATION_WINDOW} and {@link #LAST_APPLICATION_WINDOW})
+ * but below critical system windows like the status bar or IME.
+ * <p>
+ * The system may change the position, size, or visibility of these windows at anytime
+ * to reduce visual clutter to the user and also manage resources.
+ * <p>
+ * Requires {@link android.Manifest.permission#SYSTEM_ALERT_WINDOW} permission.
+ * <p>
+ * In mult-iuser systems shows only on the owning user's screen.
+ */
+ public static final int TYPE_APPLICATION_OVERLAY = FIRST_SYSTEM_WINDOW + 38;
+
+ /**
* End of types of system windows.
*/
public static final int LAST_SYSTEM_WINDOW = 2999;
+ /**
+ * Return true if the window type is an alert window.
+ *
+ * @param type The window type.
+ * @return If the window type is an alert window.
+ * @hide
+ */
+ public static boolean isSystemAlertWindowType(int type) {
+ switch (type) {
+ case TYPE_PHONE:
+ case TYPE_PRIORITY_PHONE:
+ case TYPE_SYSTEM_ALERT:
+ case TYPE_SYSTEM_ERROR:
+ case TYPE_SYSTEM_OVERLAY:
+ case TYPE_APPLICATION_OVERLAY:
+ return true;
+ }
+ return false;
+ }
+
/** @deprecated this is ignored, this value is set automatically when needed. */
@Deprecated
public static final int MEMORY_TYPE_NORMAL = 0;
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index bc4ae6d..8e597dc 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -16,6 +16,51 @@
package android.view;
+import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
+import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
+import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ABOVE_SUB_PANEL;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_PANEL;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL;
+import static android.view.WindowManager.LayoutParams.TYPE_BOOT_PROGRESS;
+import static android.view.WindowManager.LayoutParams.TYPE_DISPLAY_OVERLAY;
+import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
+import static android.view.WindowManager.LayoutParams.TYPE_DRAG;
+import static android.view.WindowManager.LayoutParams.TYPE_DREAM;
+import static android.view.WindowManager.LayoutParams.TYPE_INPUT_CONSUMER;
+import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
+import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
+import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG;
+import static android.view.WindowManager.LayoutParams.TYPE_MAGNIFICATION_OVERLAY;
+import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
+import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL;
+import static android.view.WindowManager.LayoutParams.TYPE_PHONE;
+import static android.view.WindowManager.LayoutParams.TYPE_POINTER;
+import static android.view.WindowManager.LayoutParams.TYPE_PRESENTATION;
+import static android.view.WindowManager.LayoutParams.TYPE_PRIORITY_PHONE;
+import static android.view.WindowManager.LayoutParams.TYPE_PRIVATE_PRESENTATION;
+import static android.view.WindowManager.LayoutParams.TYPE_QS_DIALOG;
+import static android.view.WindowManager.LayoutParams.TYPE_SCREENSHOT;
+import static android.view.WindowManager.LayoutParams.TYPE_SEARCH_BAR;
+import static android.view.WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
+import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
+import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL;
+import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL;
+import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
+import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG;
+import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
+import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;
+import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
+import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION;
+import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION_STARTING;
+import static android.view.WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY;
+import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
+import static android.view.WindowManager.LayoutParams.isSystemAlertWindowType;
+
import android.annotation.IntDef;
import android.annotation.Nullable;
import android.annotation.SystemApi;
@@ -30,6 +75,7 @@
import android.os.IBinder;
import android.os.Looper;
import android.os.RemoteException;
+import android.util.Slog;
import android.view.animation.Animation;
import com.android.internal.policy.IKeyguardDismissCallback;
@@ -423,6 +469,14 @@
public boolean isInputMethodWindow();
public int getDisplayId();
+
+ /**
+ * Returns true if the window owner can add internal system windows.
+ * That is, they have {@link android.Manifest.permission#INTERNAL_SYSTEM_WINDOW}.
+ */
+ default boolean canAddInternalSystemWindow() {
+ return false;
+ }
}
/**
@@ -659,27 +713,181 @@
int navigationPresence);
/**
- * Assign a window type to a layer. Allows you to control how different
+ * Returns the layer assignment for the window state. Allows you to control how different
+ * kinds of windows are ordered on-screen.
+ *
+ * @param win The window state
+ * @return int An arbitrary integer used to order windows, with lower numbers below higher ones.
+ */
+ default int getWindowLayerLw(WindowState win) {
+ return getWindowLayerFromTypeLw(win.getBaseType(), win.canAddInternalSystemWindow());
+ }
+
+ /**
+ * Returns the layer assignment for the window type. Allows you to control how different
* kinds of windows are ordered on-screen.
*
* @param type The type of window being assigned.
- *
- * @return int An arbitrary integer used to order windows, with lower
- * numbers below higher ones.
+ * @return int An arbitrary integer used to order windows, with lower numbers below higher ones.
*/
- public int windowTypeToLayerLw(int type);
+ default int getWindowLayerFromTypeLw(int type) {
+ if (isSystemAlertWindowType(type)) {
+ throw new IllegalArgumentException("Use getWindowLayerFromTypeLw() or"
+ + " getWindowLayerLw() for alert window types");
+ }
+ return getWindowLayerFromTypeLw(type, false /* canAddInternalSystemWindow */);
+ }
/**
- * Return how to Z-order sub-windows in relation to the window they are
- * attached to. Return positive to have them ordered in front, negative for
- * behind.
+ * Returns the layer assignment for the window type. Allows you to control how different
+ * kinds of windows are ordered on-screen.
+ *
+ * @param type The type of window being assigned.
+ * @param canAddInternalSystemWindow If the owner window associated with the type we are
+ * evaluating can add internal system windows. I.e they have
+ * {@link android.Manifest.permission#INTERNAL_SYSTEM_WINDOW}. If true, alert window
+ * types {@link android.view.WindowManager.LayoutParams#isSystemAlertWindowType(int)}
+ * can be assigned layers greater than the layer for
+ * {@link android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY} Else, their
+ * layers would be lesser.
+ * @return int An arbitrary integer used to order windows, with lower numbers below higher ones.
+ */
+ default int getWindowLayerFromTypeLw(int type, boolean canAddInternalSystemWindow) {
+ if (type >= FIRST_APPLICATION_WINDOW && type <= LAST_APPLICATION_WINDOW) {
+ return APPLICATION_LAYER;
+ }
+
+ switch (type) {
+ case TYPE_WALLPAPER:
+ // wallpaper is at the bottom, though the window manager may move it.
+ return 1;
+ case TYPE_PRESENTATION:
+ case TYPE_PRIVATE_PRESENTATION:
+ return APPLICATION_LAYER;
+ case TYPE_DOCK_DIVIDER:
+ return APPLICATION_LAYER;
+ case TYPE_QS_DIALOG:
+ return APPLICATION_LAYER;
+ case TYPE_PHONE:
+ return 3;
+ case TYPE_SEARCH_BAR:
+ case TYPE_VOICE_INTERACTION_STARTING:
+ return 4;
+ case TYPE_VOICE_INTERACTION:
+ // voice interaction layer is almost immediately above apps.
+ return 5;
+ case TYPE_INPUT_CONSUMER:
+ return 6;
+ case TYPE_SYSTEM_DIALOG:
+ return 7;
+ case TYPE_TOAST:
+ // toasts and the plugged-in battery thing
+ return 8;
+ case TYPE_PRIORITY_PHONE:
+ // SIM errors and unlock. Not sure if this really should be in a high layer.
+ return 9;
+ case TYPE_DREAM:
+ // used for Dreams (screensavers with TYPE_DREAM windows)
+ return 10;
+ case TYPE_SYSTEM_ALERT:
+ // like the ANR / app crashed dialogs
+ return canAddInternalSystemWindow ? 11 : 10;
+ case TYPE_APPLICATION_OVERLAY:
+ return 13;
+ case TYPE_INPUT_METHOD:
+ // on-screen keyboards and other such input method user interfaces go here.
+ return 14;
+ case TYPE_INPUT_METHOD_DIALOG:
+ // on-screen keyboards and other such input method user interfaces go here.
+ return 15;
+ case TYPE_STATUS_BAR_SUB_PANEL:
+ return 17;
+ case TYPE_STATUS_BAR:
+ return 18;
+ case TYPE_STATUS_BAR_PANEL:
+ return 19;
+ case TYPE_KEYGUARD_DIALOG:
+ return 20;
+ case TYPE_VOLUME_OVERLAY:
+ // the on-screen volume indicator and controller shown when the user
+ // changes the device volume
+ return 21;
+ case TYPE_SYSTEM_OVERLAY:
+ // the on-screen volume indicator and controller shown when the user
+ // changes the device volume
+ return canAddInternalSystemWindow ? 22 : 11;
+ case TYPE_NAVIGATION_BAR:
+ // the navigation bar, if available, shows atop most things
+ return 23;
+ case TYPE_NAVIGATION_BAR_PANEL:
+ // some panels (e.g. search) need to show on top of the navigation bar
+ return 24;
+ case TYPE_SCREENSHOT:
+ // screenshot selection layer shouldn't go above system error, but it should cover
+ // navigation bars at the very least.
+ return 25;
+ case TYPE_SYSTEM_ERROR:
+ // system-level error dialogs
+ return canAddInternalSystemWindow ? 26 : 10;
+ case TYPE_MAGNIFICATION_OVERLAY:
+ // used to highlight the magnified portion of a display
+ return 27;
+ case TYPE_DISPLAY_OVERLAY:
+ // used to simulate secondary display devices
+ return 28;
+ case TYPE_DRAG:
+ // the drag layer: input for drag-and-drop is associated with this window,
+ // which sits above all other focusable windows
+ return 29;
+ case TYPE_ACCESSIBILITY_OVERLAY:
+ // overlay put by accessibility services to intercept user interaction
+ return 30;
+ case TYPE_SECURE_SYSTEM_OVERLAY:
+ return 31;
+ case TYPE_BOOT_PROGRESS:
+ return 32;
+ case TYPE_POINTER:
+ // the (mouse) pointer layer
+ return 33;
+ default:
+ Slog.e("WindowManager", "Unknown window type: " + type);
+ return APPLICATION_LAYER;
+ }
+ }
+
+ int APPLICATION_LAYER = 2;
+ int APPLICATION_MEDIA_SUBLAYER = -2;
+ int APPLICATION_MEDIA_OVERLAY_SUBLAYER = -1;
+ int APPLICATION_PANEL_SUBLAYER = 1;
+ int APPLICATION_SUB_PANEL_SUBLAYER = 2;
+ int APPLICATION_ABOVE_SUB_PANEL_SUBLAYER = 3;
+
+ /**
+ * Return how to Z-order sub-windows in relation to the window they are attached to.
+ * Return positive to have them ordered in front, negative for behind.
*
* @param type The sub-window type code.
*
* @return int Layer in relation to the attached window, where positive is
* above and negative is below.
*/
- public int subWindowTypeToLayerLw(int type);
+ default int getSubWindowLayerFromTypeLw(int type) {
+ switch (type) {
+ case TYPE_APPLICATION_PANEL:
+ case TYPE_APPLICATION_ATTACHED_DIALOG:
+ return APPLICATION_PANEL_SUBLAYER;
+ case TYPE_APPLICATION_MEDIA:
+ return APPLICATION_MEDIA_SUBLAYER;
+ case TYPE_APPLICATION_MEDIA_OVERLAY:
+ return APPLICATION_MEDIA_OVERLAY_SUBLAYER;
+ case TYPE_APPLICATION_SUB_PANEL:
+ return APPLICATION_SUB_PANEL_SUBLAYER;
+ case TYPE_APPLICATION_ABOVE_SUB_PANEL:
+ return APPLICATION_ABOVE_SUB_PANEL_SUBLAYER;
+ }
+ Slog.e("WindowManager", "Unknown sub-window type: " + type);
+ return 0;
+ }
/**
* Get the highest layer (actually one more than) that the wallpaper is
diff --git a/core/java/android/view/accessibility/AccessibilityManager.java b/core/java/android/view/accessibility/AccessibilityManager.java
index 1ef0d17..45302b6 100644
--- a/core/java/android/view/accessibility/AccessibilityManager.java
+++ b/core/java/android/view/accessibility/AccessibilityManager.java
@@ -779,6 +779,49 @@
}
}
+ /**
+ * Notifies that the accessibility button in the system's navigation area has been clicked
+ *
+ * @hide
+ */
+ public void notifyAccessibilityButtonClicked() {
+ final IAccessibilityManager service;
+ synchronized (mLock) {
+ service = getServiceLocked();
+ if (service == null) {
+ return;
+ }
+ }
+ try {
+ service.notifyAccessibilityButtonClicked();
+ } catch (RemoteException re) {
+ Log.e(LOG_TAG, "Error while dispatching accessibility button click", re);
+ }
+ }
+
+ /**
+ * Notifies that the availability of the accessibility button in the system's navigation area
+ * has changed.
+ *
+ * @param available {@code true} if the accessibility button is available within the system
+ * navigation area, {@code false} otherwise
+ * @hide
+ */
+ public void notifyAccessibilityButtonAvailabilityChanged(boolean available) {
+ final IAccessibilityManager service;
+ synchronized (mLock) {
+ service = getServiceLocked();
+ if (service == null) {
+ return;
+ }
+ }
+ try {
+ service.notifyAccessibilityButtonAvailabilityChanged(available);
+ } catch (RemoteException re) {
+ Log.e(LOG_TAG, "Error while dispatching accessibility button availability change", re);
+ }
+ }
+
private IAccessibilityManager getServiceLocked() {
if (mService == null) {
tryConnectToServiceLocked(null);
diff --git a/core/java/android/view/accessibility/IAccessibilityManager.aidl b/core/java/android/view/accessibility/IAccessibilityManager.aidl
index 136bbbe..8fde47a 100644
--- a/core/java/android/view/accessibility/IAccessibilityManager.aidl
+++ b/core/java/android/view/accessibility/IAccessibilityManager.aidl
@@ -59,6 +59,10 @@
IBinder getWindowToken(int windowId, int userId);
+ void notifyAccessibilityButtonClicked();
+
+ void notifyAccessibilityButtonAvailabilityChanged(boolean available);
+
// Requires WRITE_SECURE_SETTINGS
void performAccessibilityShortcut();
diff --git a/core/java/android/view/autofill/AutoFillId.java b/core/java/android/view/autofill/AutoFillId.java
index e9c1c3b..3dbf5a8 100644
--- a/core/java/android/view/autofill/AutoFillId.java
+++ b/core/java/android/view/autofill/AutoFillId.java
@@ -29,6 +29,7 @@
private boolean mVirtual;
private int mVirtualId;
+ // TODO(b/33197203): use factory and cache values, since they're immutable
/** @hide */
public AutoFillId(int id) {
mVirtual = false;
diff --git a/core/java/android/view/autofill/AutoFillManager.java b/core/java/android/view/autofill/AutoFillManager.java
index cf56e0e9..6c20f07 100644
--- a/core/java/android/view/autofill/AutoFillManager.java
+++ b/core/java/android/view/autofill/AutoFillManager.java
@@ -16,9 +16,12 @@
package android.view.autofill;
+import static android.view.autofill.Helper.VERBOSE;
+
import android.annotation.Nullable;
import android.content.Context;
import android.graphics.Rect;
+import android.os.IBinder;
import android.os.RemoteException;
import android.service.autofill.IAutoFillManagerService;
import android.util.Log;
@@ -28,76 +31,184 @@
* App entry point to the AutoFill Framework.
*/
// TODO(b/33197203): improve this javadoc
+//TODO(b/33197203): restrict manager calls to activity
public final class AutoFillManager {
private static final String TAG = "AutoFillManager";
- private static final boolean DEBUG = true; // TODO(b/33197203): change to false once stable
- /**
- * Flag used to show the auto-fill UI affordance for a view.
- */
- // TODO(b/33197203): cannot conflict with flags defined on View until they're removed (when
- // save is refactored).
- public static final int FLAG_UPDATE_UI_SHOW = 0x1;
-
- /**
- * Flag used to hide the auto-fill UI affordance for a view.
- */
- // TODO(b/33197203): cannot conflict with flags defined on View until they're removed (when
- // save is refactored).
- public static final int FLAG_UPDATE_UI_HIDE = 0x2;
+ /** @hide */ public static final int FLAG_START_SESSION = 0x1;
+ /** @hide */ public static final int FLAG_FOCUS_GAINED = 0x2;
+ /** @hide */ public static final int FLAG_FOCUS_LOST = 0x4;
+ /** @hide */ public static final int FLAG_VALUE_CHANGED = 0x8;
private final IAutoFillManagerService mService;
+ private final Context mContext;
+
+ private AutoFillSession mSession;
/**
* @hide
*/
- public AutoFillManager(@SuppressWarnings("unused") Context context,
- IAutoFillManagerService service) {
+ public AutoFillManager(Context context, IAutoFillManagerService service) {
+ mContext = context;
mService = service;
}
/**
- * Updates the auto-fill bar for a given {@link View}.
+ * Called to indicate the focus on an auto-fillable {@link View} changed.
*
- * <b>Typically called twice, with different flags ({@link #FLAG_UPDATE_UI_SHOW} and
- * {@link #FLAG_UPDATE_UI_HIDE} respectively), as the user "entered" and "exited" a view.
- *
- * @param view view to be updated.
- * @param flags either {@link #FLAG_UPDATE_UI_SHOW} or
- * {@link #FLAG_UPDATE_UI_HIDE}.
+ * @param view view whose focus changed.
+ * @param gainFocus whether focus was gained or lost.
*/
- public void updateAutoFillInput(View view, int flags) {
+ public void focusChanged(View view, boolean gainFocus) {
+ if (mSession == null) {
+ // Starts new session.
+ final Rect bounds = new Rect();
+ view.getBoundsOnScreen(bounds);
+ final AutoFillId id = getAutoFillId(view);
+ final AutoFillValue value = view.getAutoFillValue();
+ startSession(id, bounds, value);
+ return;
+ }
+
+ if (!mSession.isEnabled()) {
+ // Auto-fill is disabled for this session.
+ return;
+ }
+
+ // Update focus on existing session.
final Rect bounds = new Rect();
view.getBoundsOnScreen(bounds);
-
- requestAutoFill(new AutoFillId(view.getAccessibilityViewId()), bounds, flags);
+ final AutoFillId id = getAutoFillId(view);
+ final AutoFillValue value = view.getAutoFillValue();
+ updateSession(id, bounds, value, gainFocus ? FLAG_FOCUS_GAINED : FLAG_FOCUS_LOST);
}
/**
- * Updates the auto-fill bar for a virtual child of a given {@link View}.
+ * Called to indicate the focus on an auto-fillable virtual {@link View} changed.
*
- * <b>Typically called twice, with different flags ({@link #FLAG_UPDATE_UI_SHOW} and
- * {@link #FLAG_UPDATE_UI_HIDE} respectively), as the user "entered" and "exited" a view.
- *
- * @param parent parent view.
+ * @param parent parent view whose focus changed.
* @param childId id identifying the virtual child inside the parent view.
- * @param bounds absolute boundaries of the child in the window (could be {@code null} when
- * flag is {@link #FLAG_UPDATE_UI_HIDE}.
- * @param flags either {@link #FLAG_UPDATE_UI_SHOW} or
- * {@link #FLAG_UPDATE_UI_HIDE}.
+ * @param bounds child boundaries, relative to the top window.
+ * @param value current value of the child; can be {@code null} when focus is lost, but must be
+ * set when focus is gained.
+ * @param gainFocus whether focus was gained or lost.
*/
- public void updateAutoFillInput(View parent, int childId, @Nullable Rect bounds,
- int flags) {
- requestAutoFill(new AutoFillId(parent.getAccessibilityViewId(), childId), bounds, flags);
+ public void virtualFocusChanged(View parent, int childId, Rect bounds,
+ @Nullable AutoFillValue value, boolean gainFocus) {
+ if (mSession == null) {
+ // Starts new session.
+ final AutoFillId id = getAutoFillId(parent, childId);
+ startSession(id, bounds, value);
+ return;
+ }
+
+ if (!mSession.isEnabled()) {
+ // Auto-fill is disabled for this session.
+ return;
+ }
+
+ // Update focus on existing session.
+ final AutoFillId id = getAutoFillId(parent, childId);
+ updateSession(id, bounds, value, gainFocus ? FLAG_FOCUS_GAINED : FLAG_FOCUS_LOST);
}
- private void requestAutoFill(AutoFillId id, Rect bounds, int flags) {
- if (DEBUG) {
- Log.v(TAG, "requestAutoFill(): id=" + id + ", bounds=" + bounds + ", flags=" + flags);
+ /**
+ * Called to indicate the value of an auto-fillable {@link View} changed.
+ *
+ * @param view view whose focus changed.
+ */
+ public void valueChanged(View view) {
+ if (mSession == null) return;
+
+ final AutoFillId id = getAutoFillId(view);
+ final AutoFillValue value = view.getAutoFillValue();
+ updateSession(id, null, value, FLAG_VALUE_CHANGED);
+ }
+
+
+ /**
+ * Called to indicate the value of an auto-fillable virtual {@link View} changed.
+ *
+ * @param parent parent view whose value changed.
+ * @param childId id identifying the virtual child inside the parent view.
+ * @param value new value of the child.
+ */
+ public void virtualValueChanged(View parent, int childId, AutoFillValue value) {
+ if (mSession == null) return;
+
+ final AutoFillId id = getAutoFillId(parent, childId);
+ updateSession(id, null, value, FLAG_VALUE_CHANGED);
+ }
+
+ /**
+ * Called to indicate the current auto-fill context should be reset.
+ *
+ * <p>For example, when a virtual view is rendering an {@code HTML} page with a form, it should
+ * call this method after the form is submitted and another page is rendered.
+ */
+ public void reset() {
+ if (mSession == null) return;
+
+ final IBinder activityToken = mSession.mToken.get();
+ if (activityToken == null) {
+ Log.wtf(TAG, "finishSession(): token already GC'ed");
+ return;
}
try {
- mService.requestAutoFill(id, bounds, flags);
+ mService.finishSession(activityToken);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ } finally {
+ mSession = null;
+ }
+ }
+
+ /**
+ * Gets the current session, if any.
+ *
+ * @hide
+ */
+ @Nullable
+ public AutoFillSession getSession() {
+ return mSession;
+ }
+
+ private AutoFillId getAutoFillId(View view) {
+ return new AutoFillId(view.getAccessibilityViewId());
+ }
+
+ private AutoFillId getAutoFillId(View parent, int childId) {
+ return new AutoFillId(parent.getAccessibilityViewId(), childId);
+ }
+
+ private void startSession(AutoFillId id, Rect bounds, AutoFillValue value) {
+ if (VERBOSE) {
+ Log.v(TAG, "startSession(): id=" + id + ", bounds=" + bounds + ", value=" + value);
+ }
+
+ final IBinder activityToken = mContext.getActivityToken();
+ mSession = new AutoFillSession(this, activityToken);
+ final IBinder appCallback = mSession.getCallback().asBinder();
+ try {
+ mService.startSession(activityToken, appCallback, id, bounds, value);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ private void updateSession(AutoFillId id, Rect bounds, AutoFillValue value, int flags) {
+ if (VERBOSE) {
+ Log.v(TAG, "updateSession(): id=" + id + ", bounds=" + bounds + ", value=" + value
+ + ", flags=" + flags);
+ }
+
+ final IBinder activityToken = mSession.mToken.get();
+ if (activityToken == null) {
+ return;
+ }
+ try {
+ mService.updateSession(activityToken, id, bounds, value, flags);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/core/java/android/view/autofill/AutoFillSession.java b/core/java/android/view/autofill/AutoFillSession.java
index eec7a82..e10ba37 100644
--- a/core/java/android/view/autofill/AutoFillSession.java
+++ b/core/java/android/view/autofill/AutoFillSession.java
@@ -19,13 +19,13 @@
import static android.view.autofill.Helper.DEBUG;
import android.app.Activity;
-import android.os.RemoteException;
+import android.content.Intent;
+import android.content.IntentSender;
+import android.os.IBinder;
import android.service.autofill.IAutoFillAppCallback;
import android.util.Log;
import android.view.View;
-import com.android.internal.annotations.GuardedBy;
-
import java.lang.ref.WeakReference;
/**
@@ -38,8 +38,16 @@
private static final String TAG = "AutoFillSession";
private final IAutoFillAppCallback mCallback = new IAutoFillAppCallback.Stub() {
+
@Override
- public void autoFill(Dataset dataset) throws RemoteException {
+ public void enableSession() {
+ if (DEBUG) Log.d(TAG, "enableSession()");
+
+ mEnabled = true;
+ }
+
+ @Override
+ public void autoFill(Dataset dataset) {
final Activity activity = mActivity.get();
if (activity == null) {
if (DEBUG) Log.d(TAG, "autoFill(): activity already GCed");
@@ -49,12 +57,10 @@
// dataset.extras to service
activity.runOnUiThread(() -> {
final View root = activity.getWindow().getDecorView().getRootView();
- for (DatasetField field : dataset.getFields()) {
- final AutoFillId id = field.getId();
- if (id == null) {
- Log.w(TAG, "autoFill(): null id on " + field);
- continue;
- }
+ final int itemCount = dataset.getFieldIds().size();
+ for (int i = 0; i < itemCount; i++) {
+ final AutoFillId id = dataset.getFieldIds().get(i);
+ final AutoFillValue value = dataset.getFieldValues().get(i);
final int viewId = id.getViewId();
final View view = root.findViewByAccessibilityIdTraversal(viewId);
if (view == null) {
@@ -65,10 +71,8 @@
// TODO(b/33197203): handle protected value (like credit card)
if (id.isVirtual()) {
// Delegate virtual fields.
- setAutoFillDelegateCallback();
final VirtualViewDelegate delegate = view
- .getAutoFillVirtualViewDelegate(
- mAutoFillDelegateCallback);
+ .getAutoFillVirtualViewDelegate();
if (delegate == null) {
Log.w(TAG, "autoFill(): cannot fill virtual " + id
+ "; no VirtualViewDelegate for view "
@@ -79,40 +83,84 @@
Log.d(TAG, "autoFill(): delegating " + id
+ " to VirtualViewDelegate " + delegate);
}
- delegate.autoFill(id.getVirtualChildId(), field.getValue());
+ delegate.autoFill(id.getVirtualChildId(), value);
} else {
// Handle non-virtual fields itself.
- view.autoFill(field.getValue());
+ view.autoFill(value);
}
}
});
}
+
+ @Override
+ public void startIntentSender(IntentSender intent, Intent fillInIntent) {
+ final Activity activity = mActivity.get();
+ if (activity != null) {
+ activity.runOnUiThread(() -> {
+ try {
+ activity.startIntentSender(intent, fillInIntent, 0, 0, 0);
+ } catch (IntentSender.SendIntentException e) {
+ Log.e(TAG, "startIntentSender() failed for intent:" + intent, e);
+ }
+ });
+ }
+ }
};
- private final WeakReference<Activity> mActivity;
+ private final AutoFillManager mAfm;
+ private WeakReference<Activity> mActivity;
- @GuardedBy("this")
- private VirtualViewDelegate.Callback mAutoFillDelegateCallback;
+ // Reference to the token, which is used by the server.
+ final WeakReference<IBinder> mToken;
- public AutoFillSession(Activity activity) {
+ private boolean mEnabled;
+
+ public AutoFillSession(AutoFillManager afm, IBinder token) {
+ mToken = new WeakReference<>(token);
+ mAfm = afm;
+ }
+
+ /**
+ * Called by the {@link Activity} when it was asked to provider auto-fill data.
+ */
+ public void attachActivity(Activity activity) {
+ if (mActivity != null) {
+ Log.w(TAG, "attachActivity(): already attached");
+ return;
+ }
mActivity = new WeakReference<>(activity);
}
+ /**
+ * Checks whether auto-fill is enabled for this session, as decided by the
+ * {@code AutoFillManagerService}.
+ */
+ public boolean isEnabled() {
+ return mEnabled;
+ }
+
+ /**
+ * Notifies the manager that a session finished.
+ */
+ // TODO(b/33197203): hook it to other lifecycle events like fragments transition
+ public void finishSession() {
+ if (mAfm != null) {
+ try {
+ mAfm.reset();
+ } catch (RuntimeException e) {
+ Log.w(TAG, "Failed to finish session for " + mToken.get() + ": " + e);
+ }
+ }
+ }
+
public IAutoFillAppCallback getCallback() {
return mCallback;
}
- /**
- * Lazily sets the {@link #mAutoFillDelegateCallback}.
- */
- private void setAutoFillDelegateCallback() {
- synchronized (this) {
- if (mAutoFillDelegateCallback == null) {
- mAutoFillDelegateCallback = new VirtualViewDelegate.Callback() {
- // TODO(b/33197203): implement
- };
- }
- }
- }
+ @Override
+ public String toString() {
+ if (!DEBUG) return super.toString();
+ return "AutoFillSession[activityoken=" + mToken.get() + "]";
+ }
}
diff --git a/core/java/android/view/autofill/AutoFillValue.java b/core/java/android/view/autofill/AutoFillValue.java
index c39f26b..b31f4af 100644
--- a/core/java/android/view/autofill/AutoFillValue.java
+++ b/core/java/android/view/autofill/AutoFillValue.java
@@ -18,6 +18,7 @@
import static android.view.autofill.Helper.DEBUG;
+import android.annotation.Nullable;
import android.os.Parcel;
import android.os.Parcelable;
import android.view.View;
@@ -32,12 +33,12 @@
*/
public final class AutoFillValue implements Parcelable {
- private final CharSequence mText;
+ private final String mText;
private final int mListIndex;
private final boolean mToggle;
private AutoFillValue(CharSequence text, int listIndex, boolean toggle) {
- mText = text;
+ mText = (text == null) ? null : text.toString();
mListIndex = listIndex;
mToggle = toggle;
}
@@ -74,6 +75,32 @@
/////////////////////////////////////
@Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + mListIndex;
+ result = prime * result + ((mText == null) ? 0 : mText.hashCode());
+ result = prime * result + (mToggle ? 1231 : 1237);
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) return true;
+ if (obj == null) return false;
+ if (getClass() != obj.getClass()) return false;
+ final AutoFillValue other = (AutoFillValue) obj;
+ if (mListIndex != other.mListIndex) return false;
+ if (mText == null) {
+ if (other.mText != null) return false;
+ } else {
+ if (!mText.equals(other.mText)) return false;
+ }
+ if (mToggle != other.mToggle) return false;
+ return true;
+ }
+
+ @Override
public String toString() {
if (!DEBUG) return super.toString();
@@ -92,13 +119,13 @@
@Override
public void writeToParcel(Parcel parcel, int flags) {
- parcel.writeCharSequence(mText);
+ parcel.writeString(mText);
parcel.writeInt(mListIndex);
parcel.writeInt(mToggle ? 1 : 0);
}
private AutoFillValue(Parcel parcel) {
- mText = parcel.readCharSequence();
+ mText = parcel.readString();
mListIndex = parcel.readInt();
mToggle = parcel.readInt() == 1;
}
@@ -126,8 +153,10 @@
*
* <p>See {@link AutoFillType#isText()} for more info.
*/
- public static AutoFillValue forText(CharSequence value) {
- return new AutoFillValue(value, 0, false);
+ // TODO(b/33197203): use cache
+ @Nullable
+ public static AutoFillValue forText(@Nullable CharSequence value) {
+ return value == null ? null : new AutoFillValue(value, 0, false);
}
/**
diff --git a/core/java/android/view/autofill/Dataset.java b/core/java/android/view/autofill/Dataset.java
index 18a08f9..2708358 100644
--- a/core/java/android/view/autofill/Dataset.java
+++ b/core/java/android/view/autofill/Dataset.java
@@ -17,12 +17,12 @@
package android.view.autofill;
import static android.view.autofill.Helper.DEBUG;
-import static android.view.autofill.Helper.append;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.Activity;
import android.app.assist.AssistStructure.ViewNode;
-import android.hardware.fingerprint.FingerprintManager.CryptoObject;
+import android.content.IntentSender;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
@@ -30,8 +30,6 @@
import com.android.internal.util.Preconditions;
import java.util.ArrayList;
-import java.util.List;
-import java.util.Objects;
/**
* A set of data that can be used to auto-fill an {@link Activity}.
@@ -44,221 +42,184 @@
* <li>An optional {@link Bundle} with extras (used only by the service creating it).
* </ol>
*
- * See {@link FillResponse} for examples.
+ * @see FillResponse for examples.
*/
public final class Dataset implements Parcelable {
-
+ private final String mId;
private final CharSequence mName;
- private final ArrayList<DatasetField> mFields;
+ private final ArrayList<AutoFillId> mFieldIds;
+ private final ArrayList<AutoFillValue> mFieldValues;
private final Bundle mExtras;
- private final int mFlags;
- private final boolean mRequiresAuth;
- private final boolean mHasCryptoObject;
- private final long mCryptoOpId;
+ private final IntentSender mAuthentication;
- private Dataset(Dataset.Builder builder) {
+ private Dataset(Builder builder) {
+ mId = builder.mId;
mName = builder.mName;
- // TODO(b/33197203): make an immutable copy of mFields?
- mFields = builder.mFields;
+ mFieldIds = builder.mFieldIds;
+ mFieldValues = builder.mFieldValues;
mExtras = builder.mExtras;
- mFlags = builder.mFlags;
- mRequiresAuth = builder.mRequiresAuth;
- mHasCryptoObject = builder.mHasCryptoObject;
- mCryptoOpId = builder.mCryptoOpId;
+ mAuthentication = builder.mAuthentication;
}
/** @hide */
- public CharSequence getName() {
+ public @NonNull String getId() {
+ return mId;
+ }
+
+ /** @hide */
+ public @NonNull CharSequence getName() {
return mName;
}
/** @hide */
- public List<DatasetField> getFields() {
- return mFields;
+ public @Nullable ArrayList<AutoFillId> getFieldIds() {
+ return mFieldIds;
}
/** @hide */
- public Bundle getExtras() {
+ public @Nullable ArrayList<AutoFillValue> getFieldValues() {
+ return mFieldValues;
+ }
+
+ /** @hide */
+ public @Nullable Bundle getExtras() {
return mExtras;
}
/** @hide */
- public int getFlags() {
- return mFlags;
- }
-
- /** @hide */
- public boolean isAuthRequired() {
- return mRequiresAuth;
+ public @Nullable IntentSender getAuthentication() {
+ return mAuthentication;
}
/** @hide */
public boolean isEmpty() {
- return mFields.isEmpty();
- }
-
- /** @hide */
- public boolean hasCryptoObject() {
- return mHasCryptoObject;
- }
-
- /** @hide */
- public long getCryptoObjectOpId() {
- return mCryptoOpId;
+ return mFieldIds == null || mFieldIds.isEmpty();
}
@Override
public String toString() {
if (!DEBUG) return super.toString();
- final StringBuilder builder = new StringBuilder("Dataset [name=").append(mName)
- .append(", fields=").append(mFields).append(", extras=");
- append(builder, mExtras)
- .append(", flags=").append(mFlags)
- .append(", requiresAuth: ").append(mRequiresAuth)
- .append(", hasCrypto: ").append(mHasCryptoObject);
+ final StringBuilder builder = new StringBuilder("Dataset [id=").append(mId)
+ .append(", name=").append(mName)
+ .append(", fieldIds=").append(mFieldIds)
+ .append(", fieldValues=").append(mFieldValues)
+ .append(", hasAuthentication=").append(mAuthentication != null)
+ .append(", hasExtras=").append(mExtras != null);
return builder.append(']').toString();
}
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ final Dataset other = (Dataset) obj;
+ if (mId == null) {
+ if (other.mId != null) {
+ return false;
+ }
+ } else if (!mId.equals(other.mId)) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return mId != null ? mId.hashCode() : 0;
+ }
+
/**
- * A builder for {@link Dataset} objects.
+ * A builder for {@link Dataset} objects. You must to provide at least
+ * one value for a field or set an authentication intent.
*/
public static final class Builder {
+ private String mId;
private CharSequence mName;
- private final ArrayList<DatasetField> mFields = new ArrayList<>();
+ private ArrayList<AutoFillId> mFieldIds;
+ private ArrayList<AutoFillValue> mFieldValues;
private Bundle mExtras;
- private int mFlags;
- private boolean mRequiresAuth;
- private boolean mHasCryptoObject;
- private long mCryptoOpId;
+ private IntentSender mAuthentication;
+ private boolean mDestroyed;
+
+ /** @hide */
+ // TODO(b/33197203): Remove once GCore migrates
+ public Builder(@NonNull CharSequence name) {
+ this(String.valueOf(System.currentTimeMillis()), name);
+ }
/**
* Creates a new builder.
*
+ * @param id A required id to identify this dataset for future interactions related to it.
* @param name Name used to identify the dataset in the UI. Typically it's the same value as
- * the first field in the dataset (like username or email address) or an user-provided name
+ * the first field in the dataset (like username or email address) or a user-provided name
* (like "My Work Address").
*/
- public Builder(CharSequence name) {
+ public Builder(@NonNull String id, @NonNull CharSequence name) {
+ mId = Preconditions.checkStringNotEmpty(id, "id cannot be empty or null");
mName = Preconditions.checkStringNotEmpty(name, "name cannot be empty or null");
}
/**
- * Requires dataset authentication through the {@link
- * android.service.autofill.AutoFillService} before auto-filling the activity with this
- * dataset.
+ * Requires a dataset authentication before auto-filling the activity with this dataset.
*
- * <p>This method is typically called when the device (or the service) does not support
- * fingerprint authentication (and hence it cannot use {@link
- * #requiresFingerprintAuthentication(CryptoObject, Bundle, int)}) or when the service needs
- * to use a custom authentication UI for the dataset. For example, when a dataset contains
- * credit card information (such as number, expiration date, and verification code), the
- * service displays an authentication dialog asking for the verification code to unlock the
- * rest of the data).
+ * <p>This method is called when you need to provide an authentication
+ * UI for the dataset. For example, when a dataset contains credit card information
+ * (such as number, expiration date, and verification code), you can display UI
+ * asking for the verification code to before filing in the data). Even if the
+ * dataset is completely populated the system will launch the specified authentication
+ * intent and will need your approval to fill it in. Since the dataset is "locked"
+ * until the user authenticates it, typically this dataset name is masked
+ * (for example, "VISA....1234"). Typically you would want to store the dataset
+ * labels non-encypted and the actual sensitive data encrypted and not in memory.
+ * This allows showing the labels in the UI while involving the user if one of
+ * the items with these labels is chosen. Note that if you use sensitive data as
+ * a label, for example an email address, then it should also be encrypted.
+ *</p>
*
- * <p>Since the dataset is "locked" until the user authenticates it, typically this dataset
- * name is masked (for example, "VISA....1234").
+ * <p>When a user selects this dataset, the system triggers the provided intent
+ * whose extras will have the {@link android.content.Intent#EXTRA_AUTO_FILL_ITEM_ID id}
+ * of the {@link android.view.autofill.Dataset dataset} to authenticate, the {@link
+ * android.content.Intent#EXTRA_AUTO_FILL_EXTRAS extras} associated with this
+ * dataset, and a {@link android.content.Intent#EXTRA_AUTO_FILL_CALLBACK callback}
+ * to dispatch the authentication result.</p>
*
- * <p>When the user selects this dataset, the Android System calls {@link
- * android.service.autofill.AutoFillService#onDatasetAuthenticationRequest(Bundle, int)}
- * passing {@link android.service.autofill.AutoFillService#FLAG_AUTHENTICATION_REQUESTED} in
- * the flags and the same {@code extras} passed to this method. The service can then
- * displays its custom authentication UI, and then call the proper method on {@link
- * android.service.autofill.FillCallback} depending on the authentication result and whether
- * this dataset already contains the fields needed to auto-fill the activity:
+ * <p>Once you complete your authentication flow you should use the provided callback
+ * to notify for a failure or a success. In case of a success you need to provide
+ * only the fully populated dataset that is being authenticated. For example, if you
+ * provided a {@link FillResponse} with two {@link Dataset}s and marked that
+ * only the first dataset needs an authentication then in the provided response
+ * you need to provide only the fully populated dataset being authenticated instead
+ * of both of them.
+ * </p>
*
- * <ul>
- * <li>If authentication failed, call
- * {@link android.service.autofill.FillCallback#onDatasetAuthentication(Dataset,
- * int)} passing {@link
- * android.service.autofill.AutoFillService#FLAG_AUTHENTICATION_ERROR} in the flags.
- * <li>If authentication succeeded and this datast is empty (no fields), call {@link
- * android.service.autofill.FillCallback#onSuccess(FillResponse)} with a new dataset
- * (with the proper fields).
- * <li>If authentication succeeded and this response is not empty, call {@link
- * android.service.autofill.FillCallback#onDatasetAuthentication(Dataset, int)}
- * passing
- * {@link android.service.autofill.AutoFillService#FLAG_AUTHENTICATION_SUCCESS} in the
- * {@code flags} and {@code null} as the {@code dataset}.
- * </ul>
+ * <p>The indent sender mechanism allows you to have your authentication UI
+ * implemented as an activity or a service or a receiver. However, the recommended
+ * way is to do this is with an activity which the system will start in the
+ * filled activity's task meaning it will properly work with back, recent apps, and
+ * free-form multi-window, while avoiding the need for the "draw on top of other"
+ * apps special permission. You can still theme your authentication activity's
+ * UI to look like a dialog if desired.</p>
*
- * @param extras when set, will be passed back in the {@link
- * android.service.autofill.AutoFillService#onDatasetAuthenticationRequest(Bundle,
- * int)}, call so it could be used by the service to handle state.
- * @param flags optional parameters, currently ignored.
+ * <p></><strong>Note:</strong> Do not make the provided intent sender
+ * immutable by using {@link android.app.PendingIntent#FLAG_IMMUTABLE} as the
+ * platform needs to fill in the authentication arguments.</p>
+ *
+ * @param authentication Intent to trigger your authentication flow.
+ *
+ * @see android.app.PendingIntent#getIntentSender()
*/
- public Builder requiresCustomAuthentication(@Nullable Bundle extras, int flags) {
- return requiresAuthentication(null, extras, flags);
- }
-
- /**
- * Requires dataset authentication through the Fingerprint sensor before auto-filling the
- * activity with this dataset.
- *
- * <p>This method is typically called when the dataset contains sensitive information (for
- * example, credit card information) and the provider requires the user to re-authenticate
- * before using it.
- *
- * <p>Since the dataset is "locked" until the user authenticates it, typically this dataset
- * name is masked (for example, "VISA....1234").
- *
- * <p>When the user selects this dataset, the Android System displays an UI affordance
- * asking the user to use the fingerprint sensor unlock the dataset, and what happens after
- * a successful fingerprint authentication depends on whether the dataset is empty (no
- * fields, only the masked name) or not:
- *
- * <ul>
- * <li>If it's empty, the Android System will call {@link
- * android.service.autofill.AutoFillService#onDatasetAuthenticationRequest(Bundle,
- * int)} passing {@link
- * android.service.autofill.AutoFillService#FLAG_AUTHENTICATION_SUCCESS}} in the
- * flags.
- * <li>If it's not empty, the activity will be auto-filled with its data.
- * </ul>
- *
- * <p>If the fingerprint authentication fails, the Android System will call {@link
- * android.service.autofill.AutoFillService#onDatasetAuthenticationRequest(Bundle, int)}
- * passing {@link android.service.autofill.AutoFillService#FLAG_AUTHENTICATION_ERROR} in the
- * flags.
- *
- * <p><strong>NOTE: </note> the {@link android.service.autofill.AutoFillService} should use
- * the {@link android.hardware.fingerprint.FingerprintManager} to check if fingerpint
- * authentication is available before using this method, and use other alternatives (such as
- * {@link #requiresCustomAuthentication(Bundle, int)}) if it is not: if this method is
- * called when fingerprint is not available, Android System will call {@link
- * android.service.autofill.AutoFillService#onDatasetAuthenticationRequest(Bundle, int)}
- * passing {@link
- * android.service.autofill.AutoFillService#FLAG_FINGERPRINT_AUTHENTICATION_NOT_AVAILABLE}
- * in the flags, but it would be wasting system resources (and worsening the user
- * experience) in the process.
- *
- * @param crypto object that will be authenticated.
- * @param extras when set, will be passed back in the {@link
- * android.service.autofill.AutoFillService#onDatasetAuthenticationRequest(Bundle, int)}
- * call so it could be used by the service to handle state.
- * @param flags optional parameters, currently ignored.
- */
- public Builder requiresFingerprintAuthentication(CryptoObject crypto,
- @Nullable Bundle extras, int flags) {
- // TODO(b/33197203): should we allow crypto to be null?
- Preconditions.checkArgument(crypto != null, "must pass a CryptoObject");
- return requiresAuthentication(crypto, extras, flags);
- }
-
- private Builder requiresAuthentication(CryptoObject cryptoObject, Bundle extras,
- int flags) {
- // There can be only one!
- Preconditions.checkState(!mRequiresAuth,
- "requires-authentication methods already called");
- // TODO(b/33197203): make sure that either this method or setExtras() is called, but
- // not both
- mExtras = extras;
- mFlags = flags;
- mRequiresAuth = true;
- if (cryptoObject != null) {
- mHasCryptoObject = true;
- mCryptoOpId = cryptoObject.getOpId();
- }
+ public @NonNull Builder setAuthentication(@Nullable IntentSender authentication) {
+ throwIfDestroyed();
+ mAuthentication = authentication;
return this;
}
@@ -268,41 +229,55 @@
* @param id id returned by {@link ViewNode#getAutoFillId()}.
* @param value value to be auto filled.
*/
- public Dataset.Builder setValue(AutoFillId id, AutoFillValue value) {
- putField(new DatasetField(id, value));
+ public @NonNull Builder setValue(@NonNull AutoFillId id, @NonNull AutoFillValue value) {
+ throwIfDestroyed();
+ Preconditions.checkNotNull(id, "id cannot be null");
+ Preconditions.checkNotNull(value, "value cannot be null");
+ if (mFieldIds != null) {
+ final int existingIdx = mFieldIds.indexOf(id);
+ if (existingIdx >= 0) {
+ mFieldValues.set(existingIdx, value);
+ return this;
+ }
+ } else {
+ mFieldIds = new ArrayList<>();
+ mFieldValues = new ArrayList<>();
+ }
+ mFieldIds.add(id);
+ mFieldValues.add(value);
return this;
}
/**
- * Creates a new {@link Dataset} instance.
+ * Sets a {@link Bundle} that will be passed to subsequent APIs that
+ * manipulate this dataset. For example, they are passed in as {@link
+ * android.content.Intent#EXTRA_AUTO_FILL_EXTRAS extras} to your
+ * authentication flow.
*/
- public Dataset build() {
+ public @NonNull Builder setExtras(@Nullable Bundle extras) {
+ throwIfDestroyed();
+ mExtras = extras;
+ return this;
+ }
+
+ /**
+ * Creates a new {@link Dataset} instance. You should not interact
+ * with this builder once this method is called.
+ */
+ public @NonNull Dataset build() {
+ throwIfDestroyed();
+ mDestroyed = true;
+ if (mFieldIds == null && mAuthentication == null) {
+ throw new IllegalArgumentException(
+ "at least one value or an authentication must be set");
+ }
return new Dataset(this);
}
- /**
- * Sets a {@link Bundle} that will be passed to subsequent calls to
- * {@link android.service.autofill.AutoFillService} methods such as
- * {@link android.service.autofill.AutoFillService#onSaveRequest(android.app.assist.AssistStructure,
- * Bundle, android.service.autofill.SaveCallback)}, using
- * {@link android.service.autofill.AutoFillService#EXTRA_DATASET_EXTRAS} as the key.
- *
- * <p>It can be used to keep service state in between calls.
- */
- public Builder setExtras(Bundle extras) {
- // TODO(b/33197203): make sure that either this method or the requires-Authentication
- // ones are called, but not both
- mExtras = Objects.requireNonNull(extras, "extras cannot be null");
- return this;
- }
-
- /**
- * Emulates {@code Map.put()} by adding a new field to the list if its id is not the yet,
- * or replacing the existing one.
- */
- private void putField(DatasetField field) {
- // TODO(b/33197203): check if already exists and replaces it if so
- mFields.add(field);
+ private void throwIfDestroyed() {
+ if (mDestroyed) {
+ throw new IllegalStateException("Already called #build()");
+ }
}
}
@@ -317,32 +292,33 @@
@Override
public void writeToParcel(Parcel parcel, int flags) {
+ parcel.writeString(mId);
parcel.writeCharSequence(mName);
- parcel.writeList(mFields);
+ parcel.writeTypedArrayList(mFieldIds, 0);
+ parcel.writeTypedArrayList(mFieldValues, 0);
parcel.writeBundle(mExtras);
- parcel.writeInt(mFlags);
- parcel.writeInt(mRequiresAuth ? 1 : 0);
- parcel.writeInt(mHasCryptoObject ? 1 : 0);
- if (mHasCryptoObject) {
- parcel.writeLong(mCryptoOpId);
- }
- }
-
- @SuppressWarnings("unchecked")
- private Dataset(Parcel parcel) {
- mName = parcel.readCharSequence();
- mFields = parcel.readArrayList(null);
- mExtras = parcel.readBundle();
- mFlags = parcel.readInt();
- mRequiresAuth = parcel.readInt() == 1;
- mHasCryptoObject = parcel.readInt() == 1;
- mCryptoOpId = mHasCryptoObject ? parcel.readLong() : 0;
+ parcel.writeParcelable(mAuthentication, flags);
}
public static final Parcelable.Creator<Dataset> CREATOR = new Parcelable.Creator<Dataset>() {
@Override
- public Dataset createFromParcel(Parcel source) {
- return new Dataset(source);
+ public Dataset createFromParcel(Parcel parcel) {
+ // Always go through the builder to ensure the data ingested by
+ // the system obeys the contract of the builder to avoid attacks
+ // using specially crafted parcels.
+ final Builder builder = new Builder(parcel.readString(), parcel.readCharSequence());
+ final ArrayList<AutoFillId> ids = parcel.readTypedArrayList(null);
+ final ArrayList<AutoFillValue> values = parcel.readTypedArrayList(null);
+ final int idCount = (ids != null) ? ids.size() : 0;
+ final int valueCount = (values != null) ? values.size() : 0;
+ for (int i = 0; i < idCount; i++) {
+ AutoFillId id = ids.get(i);
+ AutoFillValue value = (valueCount > i) ? values.get(i) : null;
+ builder.setValue(id, value);
+ }
+ builder.setExtras(parcel.readBundle());
+ builder.setAuthentication(parcel.readParcelable(null));
+ return builder.build();
}
@Override
diff --git a/core/java/android/view/autofill/DatasetField.java b/core/java/android/view/autofill/DatasetField.java
deleted file mode 100644
index c6b92ac..0000000
--- a/core/java/android/view/autofill/DatasetField.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (C) 2016 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.view.autofill;
-
-import static android.view.autofill.Helper.DEBUG;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/** @hide */
-public final class DatasetField implements Parcelable {
-
- private final AutoFillId mId;
- private final AutoFillValue mValue;
-
- DatasetField(AutoFillId id, AutoFillValue value) {
- mId = id;
- mValue = value;
- }
-
- public AutoFillId getId() {
- return mId;
- }
-
- public AutoFillValue getValue() {
- return mValue;
- }
-
- /////////////////////////////////
- // Object "contract" methods. //
- /////////////////////////////////
-
- @Override
- public String toString() {
- if (!DEBUG) return super.toString();
-
- return "DatasetField [id=" + mId + ", value=" + mValue + "]";
- }
-
- /////////////////////////////////////
- // Parcelable "contract" methods. //
- /////////////////////////////////////
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel parcel, int flags) {
- parcel.writeParcelable(mId, 0);
- parcel.writeParcelable(mValue, 0);
- }
-
- private DatasetField(Parcel parcel) {
- mId = parcel.readParcelable(null);
- mValue = parcel.readParcelable(null);
- }
-
- public static final Parcelable.Creator<DatasetField> CREATOR =
- new Parcelable.Creator<DatasetField>() {
- @Override
- public DatasetField createFromParcel(Parcel source) {
- return new DatasetField(source);
- }
-
- @Override
- public DatasetField[] newArray(int size) {
- return new DatasetField[size];
- }
- };
-}
diff --git a/core/java/android/view/autofill/FillResponse.java b/core/java/android/view/autofill/FillResponse.java
index 48dbb84..596a06c 100644
--- a/core/java/android/view/autofill/FillResponse.java
+++ b/core/java/android/view/autofill/FillResponse.java
@@ -16,36 +16,30 @@
package android.view.autofill;
import static android.view.autofill.Helper.DEBUG;
-import static android.view.autofill.Helper.append;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.Activity;
-import android.hardware.fingerprint.FingerprintManager.CryptoObject;
+import android.content.IntentSender;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
-import android.service.autofill.FillCallback;
+import android.util.ArraySet;
import com.android.internal.util.Preconditions;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Objects;
-import java.util.Set;
-
/**
* Response for a {@link
* android.service.autofill.AutoFillService#onFillRequest(android.app.assist.AssistStructure,
- * Bundle, android.os.CancellationSignal, android.service.autofill.FillCallback)} request.
+ * Bundle, android.os.CancellationSignal, android.service.autofill.FillCallback)} and
+ * authentication requests.
*
* <p>The response typically contains one or more {@link Dataset}s, each representing a set of
- * fields that can be auto-filled together, and the Android System displays a dataset picker UI
+ * fields that can be auto-filled together, and the Android system displays a dataset picker UI
* affordance that the user must use before the {@link Activity} is filled with the dataset.
*
* <p>For example, for a login page with username/password where the user only has one account in
- * the service, the response could be:
+ * the response could be:
*
* <pre class="prettyprint">
* new FillResponse.Builder()
@@ -102,12 +96,17 @@
* <p>Notice that the ids that are part of a dataset (ids 1 to 4, in this example) are automatically
* added to the {@code savableIds} list.
*
- * <p>If the service has multiple {@link Dataset}s with multiple options for some fields on each
- * dataset (for example, multiple accounts with both a home and work address), then it should
- * "partition" the {@link Activity} in sections and populate the response with just a subset of the
- * data that would fulfill the first section; then once the user fills the first section and taps a
- * field from the next section, the Android system would issue another request for that section, and
- * so on. For example, the first response could be:
+ * <p>If the service has multiple {@link Dataset}s for different sections of the activity,
+ * for example, a user section for which there are two datasets followed by an address
+ * section for which there are two datasets for each user user, then it should "partition"
+ * the activity in sections and populate the response with just a subset of the data that would
+ * fulfill the first section (the name in our example); then once the user fills the first
+ * section and taps a field from the next section (the address in our example), the Android
+ * system would issue another request for that section, and so on. Note that if the user
+ * chooses to populate the first section with a service provided dataset, the subsequent request
+ * would contain the populated values so you don't try to provide suggestions for the first
+ * section but ony for the second one based on the context of what was already filled. For
+ * example, the first response could be:
*
* <pre class="prettyprint">
* new FillResponse.Builder()
@@ -132,236 +131,182 @@
* .setTextFieldValue(id4, "Springfield")
* .build())
* .add(new Dataset.Builder("Work")
- * .setTextFieldValue(id3, "Springfield Nuclear Power Plant")
+ * .setTextFieldValue(id3, "Springfield Power Plant")
* .setTextFieldValue(id4, "Springfield")
* .build())
* .build();
* </pre>
*
- * <p>The service could require user authentication, either at the {@link FillResponse} or {@link
- * Dataset} levels, prior to auto-filling the activity - see {@link
- * FillResponse.Builder#requiresFingerprintAuthentication(CryptoObject, Bundle, int)}, {@link
- * FillResponse.Builder#requiresCustomAuthentication(Bundle, int)}, {@link
- * Dataset.Builder#requiresFingerprintAuthentication(CryptoObject, Bundle, int)}, and {@link
- * Dataset.Builder#requiresCustomAuthentication(Bundle, int)} for details.
+ * <p>The service could require user authentication at the {@link FillResponse} or the
+ * {@link Dataset} level, prior to auto-filling an activity - see {@link FillResponse.Builder
+ * #setAuthentication(IntentSender)} and {@link Dataset.Builder#setAuthentication(IntentSender)}.
+ * It is recommended that you encrypt only the sensitive data but leave the labels unencrypted
+ * which would allow you to provide the dataset names to the user and if they choose one
+ * them challenge the user to authenticate. For example, if the user has a home and a work
+ * address the Home and Work labels could be stored unencrypted as they don't have any sensitive
+ * data while the address data is in an encrypted storage. If the user chooses Home, then the
+ * platform will start your authentication flow. If you encrypt all data and require auth
+ * at the response level the user will have to interact with the fill UI to trigger a request
+ * for the datasets as they don't see Home and Work options which will trigger your auth
+ * flow and after successfully authenticating the user will be presented with the Home and
+ * Work options where they can pick one. Hence, you have flexibility how to implement your
+ * auth while storing labels non-encrypted and data encrypted provides a better user
+ * experience.</p>
*
- * <p>Finally, the service can use the {@link FillResponse.Builder#setExtras(Bundle)} and/or {@link
- * Dataset.Builder#setExtras(Bundle)} methods to pass {@link Bundle}s with service-specific data use
- * to identify this response on future calls (like {@link
- * android.service.autofill.AutoFillService#onSaveRequest(android.app.assist.AssistStructure,
- * Bundle, android.service.autofill.SaveCallback)}) - such bundles will be available as the
- * {@link android.service.autofill.AutoFillService#EXTRA_RESPONSE_EXTRAS} and
- * {@link android.service.autofill.AutoFillService#EXTRA_DATASET_EXTRAS} extras in that method's
- * {@code extras} argument.
+ * <p>Finally, the service can use {@link Dataset.Builder#setExtras(Bundle)} methods
+ * to pass {@link Bundle extras} provided to all future calls related to a dataset,
+ * for example during authentication and saving.</p>
*/
public final class FillResponse implements Parcelable {
-
- private final List<Dataset> mDatasets;
- private final AutoFillId[] mSavableIds;
+ private final String mId;
+ private final ArraySet<Dataset> mDatasets;
+ private final ArraySet<AutoFillId> mSavableIds;
private final Bundle mExtras;
- private final int mFlags;
- private final boolean mRequiresAuth;
- private final boolean mHasCryptoObject;
- private final long mCryptoOpId;
+ private final IntentSender mAuthentication;
- private FillResponse(Builder builder) {
- // TODO(b/33197203): make it immutable?
+ private FillResponse(@NonNull Builder builder) {
+ mId = builder.mId;
mDatasets = builder.mDatasets;
- final int size = builder.mSavableIds.size();
- mSavableIds = new AutoFillId[size];
- int i = 0;
- for (AutoFillId id : builder.mSavableIds) {
- mSavableIds[i++] = id;
- }
+ mSavableIds = builder.mSavableIds;
mExtras = builder.mExtras;
- mFlags = builder.mFlags;
- mRequiresAuth = builder.mRequiresAuth;
- mHasCryptoObject = builder.mHasCryptoObject;
- mCryptoOpId = builder.mCryptoOpId;
+ mAuthentication = builder.mAuthentication;
}
/** @hide */
- public List<Dataset> getDatasets() {
- return mDatasets;
+ public @NonNull String getId() {
+ return mId;
}
/** @hide */
- public AutoFillId[] getSavableIds() {
- return mSavableIds;
- }
-
- /** @hide */
- public Bundle getExtras() {
+ public @Nullable Bundle getExtras() {
return mExtras;
}
/** @hide */
- public int getFlags() {
- return mFlags;
+ public @Nullable ArraySet<Dataset> getDatasets() {
+ return mDatasets;
}
/** @hide */
- public boolean isAuthRequired() {
- return mRequiresAuth;
+ public @Nullable ArraySet<AutoFillId> getSavableIds() {
+ return mSavableIds;
}
/** @hide */
- public boolean hasCryptoObject() {
- return mHasCryptoObject;
- }
-
- /** @hide */
- public long getCryptoObjectOpId() {
- return mCryptoOpId;
+ public @Nullable IntentSender getAuthentication() {
+ return mAuthentication;
}
/**
- * Builder for {@link FillResponse} objects.
+ * Builder for {@link FillResponse} objects. You must to provide at least
+ * one dataset or set an authentication intent.
*/
public static final class Builder {
- private final List<Dataset> mDatasets = new ArrayList<>();
- private final Set<AutoFillId> mSavableIds = new HashSet<>();
+ private final String mId;
+ private ArraySet<Dataset> mDatasets;
+ private ArraySet<AutoFillId> mSavableIds;
private Bundle mExtras;
- private int mFlags;
- private boolean mRequiresAuth;
- private boolean mHasCryptoObject;
- private long mCryptoOpId;
+ private IntentSender mAuthentication;
+ private boolean mDestroyed;
- /**
- * Requires user authentication through the {@link android.service.autofill.AutoFillService}
- * before handling an auto-fill request.
- *
- * <p>This method is typically called when the device (or the service) does not support
- * fingerprint authentication (and hence it cannot use {@link
- * #requiresFingerprintAuthentication(CryptoObject, Bundle, int)}) or when the service needs
- * to use a custom authentication UI and is used in 2 scenarios:
- *
- * <ol>
- * <li>When the user data is encrypted and the service must authenticate an object that
- * will be used to decrypt it.
- * <li>When the service already acquired the user data but wants to confirm the user's
- * identity before the activity is filled with it.
- * </ol>
- *
- * <p>When this method is called, the Android System displays an UI affordance asking the
- * user to tap it to auto-fill the activity; if the user taps it, the Android System calls
- * {@link
- * android.service.autofill.AutoFillService#onFillResponseAuthenticationRequest(Bundle,
- * int)} passing {@link
- * android.service.autofill.AutoFillService#FLAG_AUTHENTICATION_REQUESTED} in the flags and
- * the same {@code extras} passed to this method. The service can then displays its custom
- * authentication UI, and then call the proper method on {@link FillCallback} depending on
- * the authentication result and whether this response already contains the {@link Dataset}s
- * need to auto-fill the activity:
- *
- * <ul>
- * <li>If authentication failed, call {@link
- * FillCallback#onFillResponseAuthentication(int)} passing {@link
- * android.service.autofill.AutoFillService#FLAG_AUTHENTICATION_ERROR} in the flags.
- * <li>If authentication succeeded and this response is empty (no datasets), call {@link
- * FillCallback#onSuccess(FillResponse)} with a new dataset (that does not require
- * authentication).
- * <li>If authentication succeeded and this response is not empty, call {@link
- * FillCallback#onFillResponseAuthentication(int)} passing {@link
- * android.service.autofill.AutoFillService#FLAG_AUTHENTICATION_SUCCESS} in the flags.
- * </ul>
- *
- * @param extras when set, will be passed back in the {@link
- * android.service.autofill.AutoFillService#onFillResponseAuthenticationRequest(Bundle,
- * int)} call so it could be used by the service to handle state.
- * @param flags optional parameters, currently ignored.
- */
- public Builder requiresCustomAuthentication(@Nullable Bundle extras, int flags) {
- return requiresAuthentication(null, extras, flags);
+ /** @hide */
+ // TODO(b/33197203): Remove once GCore migrates
+ public Builder() {
+ this(String.valueOf(System.currentTimeMillis()));
}
/**
- * Requires user authentication through the Fingerprint sensor before handling an auto-fill
- * request.
+ * Creates a new {@link FillResponse} builder.
*
- * <p>The {@link android.service.autofill.AutoFillService} typically uses this method in 2
- * situations:
- *
- * <ol>
- * <li>When the user data is encrypted and the service must authenticate an object that
- * will be used to decrypt it.
- * <li>When the service already acquired the user data but wants to confirm the user's
- * identity before the activity is filled with it.
- * </ol>
- *
- * <p>When this method is called, the Android System displays an UI affordance asking the
- * user to use the fingerprint sensor to auto-fill the activity, and what happens after a
- * successful fingerprint authentication depends on the number of {@link Dataset}s included
- * in this response:
- *
- * <ul>
- * <li>If it's empty (scenario #1 above), the Android System will call {@link
- * android.service.autofill.AutoFillService#onFillResponseAuthenticationRequest(Bundle,
- * int)} passing {@link
- * android.service.autofill.AutoFillService#FLAG_AUTHENTICATION_SUCCESS}} in the
- * flags.
- * <li>If it contains one dataset, the activity will be auto-filled right away.
- * <li>If it contains many datasets, the Android System will show dataset picker UI, and
- * then auto-fill the activity once the user select the proper datased.
- * </ul>
- *
- * <p>If the fingerprint authentication fails, the Android System will call {@link
- * android.service.autofill.AutoFillService#onFillResponseAuthenticationRequest(Bundle,
- * int)} passing {@link android.service.autofill.AutoFillService#FLAG_AUTHENTICATION_ERROR}
- * in the flags.
- *
- * <p><strong>NOTE: </note> the {@link android.service.autofill.AutoFillService} should use
- * the {@link android.hardware.fingerprint.FingerprintManager} to check if fingerpint
- * authentication is available before using this method, and use other alternatives (such as
- * {@link #requiresCustomAuthentication(Bundle, int)}) if it is not: if this method is
- * called when fingerprint is not available, Android System will call {@link
- * android.service.autofill.AutoFillService#onFillResponseAuthenticationRequest(Bundle,
- * int)} passing {@link
- * android.service.autofill.AutoFillService#FLAG_FINGERPRINT_AUTHENTICATION_NOT_AVAILABLE}
- * in the flags, but it would be wasting system resources (and worsening the user
- * experience) in the process.
- *
- * @param crypto object that will be authenticated.
- * @param extras when set, will be passed back in the {@link
- * android.service.autofill.AutoFillService#onFillResponseAuthenticationRequest(Bundle,
- * int)} call so it could be used by the service to handle state.
- * @param flags optional parameters, currently ignored.
+ * @param id A required id to identify this dataset for future interactions related to it.
*/
- public Builder requiresFingerprintAuthentication(CryptoObject crypto,
- @Nullable Bundle extras, int flags) {
- // TODO(b/33197203): should we allow crypto to be null?
- Preconditions.checkArgument(crypto != null, "must pass a CryptoObject");
- return requiresAuthentication(crypto, extras, flags);
+ public Builder(@NonNull String id) {
+ mId = Preconditions.checkStringNotEmpty(id, "id cannot be empty or null");
}
- private Builder requiresAuthentication(CryptoObject cryptoObject, Bundle extras,
- int flags) {
- // There can be only one!
- Preconditions.checkState(!mRequiresAuth,
- "requires-authentication methods already called");
- // TODO(b/33197203): make sure that either this method or setExtras() is called, but
- // not both
- mExtras = extras;
- mFlags = flags;
- mRequiresAuth = true;
- if (cryptoObject != null) {
- mHasCryptoObject = true;
- mCryptoOpId = cryptoObject.getOpId();
- }
+ /**
+ * Requires a fill response authentication before auto-filling the activity with
+ * any dataset in this response. This is typically useful when a user interaction
+ * is required to unlock their data vault if you encrypt the dataset labels and
+ * dataset data. It is recommended to encrypt only the sensitive data and not the
+ * dataset labels which would allow auth on the dataset level leading to a better
+ * user experience. Note that if you use sensitive data as a label, for example an
+ * email address, then it should also be encrypted.
+ *
+ * <p>This method is called when you need to provide an authentication
+ * UI for the fill response. For example, when the user's data is stored
+ * encrypted and needs a user interaction to decrypt before offering fill
+ * suggestions.</p>
+ *
+ * <p>When a user initiates an auto fill, the system triggers the provided
+ * intent whose extras will have the {@link android.content.Intent
+ * #EXTRA_AUTO_FILL_ITEM_ID id} of the {@link android.view.autofill.FillResponse})
+ * to authenticate, the {@link android.content.Intent#EXTRA_AUTO_FILL_EXTRAS extras}
+ * associated with this response, and a {@link android.content.Intent
+ * #EXTRA_AUTO_FILL_CALLBACK callback} to dispatch the authentication result.</p>
+ *
+ * <p>Once you complete your authentication flow you should use the provided callback
+ * to notify for a failure or a success. In case of a success you need to provide
+ * the fully populated response that is being authenticated. For example, if you
+ * provided an empty {@link FillResponse} because the user's data was locked and
+ * marked that the response needs an authentication then in the response returned
+ * if authentication succeeds you need to provide all available datasets some of
+ * which may need to be further authenticated, for example a credit card whose
+ * CVV needs to be entered.</p>
+ *
+ * <p>The indent sender mechanism allows you to have your authentication UI
+ * implemented as an activity or a service or a receiver. However, the recommended
+ * way is to do this is with an activity which the system will start in the
+ * filled activity's task meaning it will properly work with back, recent apps, and
+ * free-form multi-window, while avoiding the need for the "draw on top of other"
+ * apps special permission. You can still theme your authentication activity's
+ * UI to look like a dialog if desired.</p>
+ *
+ * <p></><strong>Note:</strong> Do not make the provided intent sender
+ * immutable by using {@link android.app.PendingIntent#FLAG_IMMUTABLE} as the
+ * platform needs to fill in the authentication arguments.</p>
+ *
+ * @param authentication Intent to trigger your authentication flow.
+ *
+ * @see android.app.PendingIntent#getIntentSender()
+ */
+ public @NonNull Builder setAuthentication(@Nullable IntentSender authentication) {
+ throwIfDestroyed();
+ mAuthentication = authentication;
return this;
}
/**
- * Adds a new {@link Dataset} to this response.
+ * Adds a new {@link Dataset} to this response. Adding a dataset with the
+ * same id updates the existing one.
*
* @throws IllegalArgumentException if a dataset with same {@code name} already exists.
*/
- public Builder addDataset(Dataset dataset) {
- Preconditions.checkNotNull(dataset, "dataset cannot be null");
- // TODO(b/33197203): check if name already exists
- mDatasets.add(dataset);
- for (DatasetField field : dataset.getFields()) {
- mSavableIds.add(field.getId());
+ public@NonNull Builder addDataset(@Nullable Dataset dataset) {
+ throwIfDestroyed();
+ if (dataset == null) {
+ return this;
+ }
+ if (mDatasets == null) {
+ mDatasets = new ArraySet<>();
+ }
+ final int datasetCount = mDatasets.size();
+ for (int i = 0; i < datasetCount; i++) {
+ if (mDatasets.valueAt(i).getName().equals(dataset.getName())) {
+ throw new IllegalArgumentException("Duplicate dataset name: "
+ + dataset.getName());
+ }
+ }
+ if (!mDatasets.add(dataset)) {
+ return this;
+ }
+ final int fieldCount = dataset.getFieldIds().size();
+ for (int i = 0; i < fieldCount; i++) {
+ final AutoFillId id = dataset.getFieldIds().get(i);
+ if (mSavableIds == null) {
+ mSavableIds = new ArraySet<>();
+ }
+ mSavableIds.add(id);
}
return this;
}
@@ -374,27 +319,35 @@
*
* <p>See {@link FillResponse} for examples.
*/
- public Builder addSavableFields(AutoFillId... ids) {
+ public @NonNull Builder addSavableFields(@Nullable AutoFillId... ids) {
+ throwIfDestroyed();
+ if (ids == null) {
+ return this;
+ }
for (AutoFillId id : ids) {
+ if (mSavableIds == null) {
+ mSavableIds = new ArraySet<>();
+ }
mSavableIds.add(id);
}
return this;
}
/**
- * Sets a {@link Bundle} that will be passed to subsequent calls to {@link
- * android.service.autofill.AutoFillService} methods such as {@link
+ * Sets a {@link Bundle} that will be passed to subsequent APIs that
+ * manipulate this response. For example, they are passed in as {@link
+ * android.content.Intent#EXTRA_AUTO_FILL_EXTRAS extras} to your
+ * authentication flow and to subsequent calls to {@link
+ * android.service.autofill.AutoFillService#onFillRequest(
+ * android.app.assist.AssistStructure, Bundle, android.os.CancellationSignal,
+ * android.service.autofill.FillCallback)} and {@link
* android.service.autofill.AutoFillService#onSaveRequest(
- * android.app.assist.AssistStructure, Bundle, android.service.autofill.SaveCallback)},
- * using {@link
- * android.service.autofill.AutoFillService#EXTRA_RESPONSE_EXTRAS} as the key.
- *
- * <p>It can be used when to keep service state in between calls.
+ * android.app.assist.AssistStructure, Bundle,
+ * android.service.autofill.SaveCallback)}.
*/
public Builder setExtras(Bundle extras) {
- // TODO(b/33197203): make sure that either this method or the requires-Authentication
- // ones are called, but not both
- mExtras = Objects.requireNonNull(extras, "extras cannot be null");
+ throwIfDestroyed();
+ mExtras = extras;
return this;
}
@@ -402,8 +355,16 @@
* Builds a new {@link FillResponse} instance.
*/
public FillResponse build() {
+ throwIfDestroyed();
+ mDestroyed = true;
return new FillResponse(this);
}
+
+ private void throwIfDestroyed() {
+ if (mDestroyed) {
+ throw new IllegalStateException("Already called #build()");
+ }
+ }
}
/////////////////////////////////////
@@ -412,14 +373,12 @@
@Override
public String toString() {
if (!DEBUG) return super.toString();
-
- final StringBuilder builder = new StringBuilder("FillResponse: [datasets=")
- .append(mDatasets).append(", savableIds=").append(Arrays.toString(mSavableIds))
- .append(", extras=");
- append(builder, mExtras)
- .append(", flags=").append(mFlags)
- .append(", requiresAuth: ").append(mRequiresAuth)
- .append(", hasCrypto: ").append(mHasCryptoObject);
+ final StringBuilder builder = new StringBuilder(
+ "FillResponse: [id=").append(mId)
+ .append(", datasets=").append(mDatasets)
+ .append(", savableIds=").append(mSavableIds)
+ .append(", hasExtras=").append(mExtras != null)
+ .append(", hasAuthentication=").append(mAuthentication != null);
return builder.append(']').toString();
}
@@ -434,33 +393,34 @@
@Override
public void writeToParcel(Parcel parcel, int flags) {
- parcel.writeList(mDatasets);
- parcel.writeParcelableArray(mSavableIds, 0);
- parcel.writeBundle(mExtras);
- parcel.writeInt(mFlags);
- parcel.writeInt(mRequiresAuth ? 1 : 0);
- parcel.writeInt(mHasCryptoObject ? 1 : 0);
- if (mHasCryptoObject) {
- parcel.writeLong(mCryptoOpId);
- }
- }
-
- private FillResponse(Parcel parcel) {
- mDatasets = new ArrayList<>();
- parcel.readList(mDatasets, null);
- mSavableIds = parcel.readParcelableArray(null, AutoFillId.class);
- mExtras = parcel.readBundle();
- mFlags = parcel.readInt();
- mRequiresAuth = parcel.readInt() == 1;
- mHasCryptoObject = parcel.readInt() == 1;
- mCryptoOpId = mHasCryptoObject ? parcel.readLong() : 0;
+ parcel.writeString(mId);
+ parcel.writeTypedArraySet(mDatasets, 0);
+ parcel.writeTypedArraySet(mSavableIds, 0);
+ parcel.writeParcelable(mExtras, 0);
+ parcel.writeParcelable(mAuthentication, 0);
}
public static final Parcelable.Creator<FillResponse> CREATOR =
new Parcelable.Creator<FillResponse>() {
@Override
- public FillResponse createFromParcel(Parcel source) {
- return new FillResponse(source);
+ public FillResponse createFromParcel(Parcel parcel) {
+ // Always go through the builder to ensure the data ingested by
+ // the system obeys the contract of the builder to avoid attacks
+ // using specially crafted parcels.
+ final Builder builder = new Builder(parcel.readString());
+ final ArraySet<Dataset> datasets = parcel.readTypedArraySet(null);
+ final int datasetCount = (datasets != null) ? datasets.size() : 0;
+ for (int i = 0; i < datasetCount; i++) {
+ builder.addDataset(datasets.valueAt(i));
+ }
+ final ArraySet<AutoFillId> fillIds = parcel.readTypedArraySet(null);
+ final int fillIdCount = (fillIds != null) ? fillIds.size() : 0;
+ for (int i = 0; i < fillIdCount; i++) {
+ builder.addSavableFields(fillIds.valueAt(i));
+ }
+ builder.setExtras(parcel.readParcelable(null));
+ builder.setAuthentication(parcel.readParcelable(null));
+ return builder.build();
}
@Override
diff --git a/core/java/android/view/autofill/Helper.java b/core/java/android/view/autofill/Helper.java
index 14cf9e8..a9844d7 100644
--- a/core/java/android/view/autofill/Helper.java
+++ b/core/java/android/view/autofill/Helper.java
@@ -26,6 +26,7 @@
public final class Helper {
static final boolean DEBUG = true; // TODO(b/33197203): set to false when stable
+ static final boolean VERBOSE = false;
static final String REDACTED = "[REDACTED]";
static StringBuilder append(StringBuilder builder, Bundle bundle) {
diff --git a/core/java/android/view/autofill/VirtualViewDelegate.java b/core/java/android/view/autofill/VirtualViewDelegate.java
index 278bf4f..3dda7f7 100644
--- a/core/java/android/view/autofill/VirtualViewDelegate.java
+++ b/core/java/android/view/autofill/VirtualViewDelegate.java
@@ -15,9 +15,6 @@
*/
package android.view.autofill;
-import android.annotation.Nullable;
-import android.graphics.Rect;
-import android.util.Log;
import android.view.View;
import android.view.ViewStructure;
@@ -27,12 +24,13 @@
*
* <p>The view hierarchy is typically created through the
* {@link View#onProvideAutoFillVirtualStructure(android.view.ViewStructure, int)} call and client
- * add virtual children by calling {@link ViewStructure#newChild(int, int)} or
- * {@link ViewStructure#asyncNewChild(int, int)}, where the client provides the {@code virtualId}
- * of the children - the same {@code virtualId} is used in the methods of this class.
+ * add virtual children by calling {@link ViewStructure#newChild(int, int, int)} or
+ * {@link ViewStructure#asyncNewChild(int, int, int)}, where the client provides the
+ * {@code virtualId} of the children - the same {@code virtualId} is used in the methods of this
+ * class.
*
* <p>Objects of this class are typically created by overriding
- * {@link View#getAutoFillVirtualViewDelegate(Callback)} and saving the passed callback, which must
+ * {@link View#getAutoFillVirtualViewDelegate()} and saving the passed callback, which must
* be notified upon changes on the hierarchy.
*
* <p>The main use case of these API is to enable custom views that draws its content - such as
@@ -42,82 +40,22 @@
* <li>Client populates the virtual hierarchy on
* {@link View#onProvideAutoFillVirtualStructure(android.view.ViewStructure, int)}
* <li>Android System generates the proper {@link AutoFillId} - encapsulating the view and the
- * virtual node ids - and pass it to the {@link android.service.autofill.AutoFillService}.
+ * virtual child ids - and pass it to the {@link android.service.autofill.AutoFillService}.
* <li>The service uses the {@link AutoFillId} to populate the auto-fill {@link Dataset}s and pass
* it back to the Android System.
* <li>Android System uses the {@link AutoFillId} to find the proper custom view and calls
* {@link #autoFill(int, AutoFillValue)} on that view passing the virtual id.
- * <li>This provider than finds the node in the hierarchy and auto-fills it.
+ * <li>This provider than finds the child in the hierarchy and auto-fills it.
* </ol>
*
*/
public abstract class VirtualViewDelegate {
- // TODO(b/33197203): set to false once stable
- private static final boolean DEBUG = true;
-
- private static final String TAG = "VirtualViewDelegate";
-
/**
* Auto-fills a virtual view with the {@code value}.
*
- * @param virtualId id identifying the virtual node inside the custom view.
+ * @param virtualId id identifying the virtual child inside the custom view.
* @param value value to be auto-filled.
*/
public abstract void autoFill(int virtualId, AutoFillValue value);
-
- /**
- * Callback used to notify the AutoFill Framework of changes made on the view hierarchy while
- * an {@link android.app.Activity} is being auto filled.
- */
- public abstract static class Callback {
-
- /**
- * Sent when the auto-fill bar for a child must be updated.
- *
- * See {@link AutoFillManager#updateAutoFillInput(View, int, android.graphics.Rect, int)}
- * for more details.
- */
- // TODO(b/33197203): do we really need it, or should the parent view just call
- // AutoFillManager.updateAutoFillInput() directly?
- public void onAutoFillInputUpdated(int virtualId, @Nullable Rect boundaries, int flags) {
- if (DEBUG) {
- Log.v(TAG, "onAutoFillInputUpdated(): virtualId=" + virtualId + ", boundaries="
- + boundaries + ", flags=" + flags);
- }
- }
-
- /**
- * Sent when the value of a node was changed.
- *
- * <p>This method should only be called when the change was not caused by the AutoFill
- * Framework itselft (i.e, through {@link VirtualViewDelegate#autoFill(int, AutoFillValue)},
- * but by external causes (for example, when the user changed the value through the view's
- * UI).
- *
- * @param virtualId id of the node whose value changed.
- */
- public void onValueChanged(int virtualId) {
- if (DEBUG) Log.d(TAG, "onValueChanged() for" + virtualId);
- }
-
- /**
- * Sent when nodes were removed (or had their ids changed) after the hierarchy has been
- * committed to
- * {@link View#onProvideAutoFillVirtualStructure(android.view.ViewStructure, int)}.
- *
- * <p>For example, when the view is rendering an {@code HTML} page, it should call this
- * method when:
- * <ul>
- * <li>User navigated to another page and some (or all) nodes are gone.
- * <li>The page's {@code DOM} was changed by {@code JavaScript} and some nodes moved (and
- * are now identified by different ids).
- * </ul>
- *
- * @param virtualIds id of the nodes that were removed.
- */
- public void onNodeRemoved(int... virtualIds) {
- if (DEBUG) Log.d(TAG, "onNodeRemoved(): " + virtualIds);
- }
- }
}
diff --git a/core/java/android/view/inputmethod/InputMethodInfo.java b/core/java/android/view/inputmethod/InputMethodInfo.java
index b6da1d8..71809bd 100644
--- a/core/java/android/view/inputmethod/InputMethodInfo.java
+++ b/core/java/android/view/inputmethod/InputMethodInfo.java
@@ -16,6 +16,7 @@
package android.view.inputmethod;
+import android.annotation.NonNull;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.ApplicationInfo;
@@ -42,7 +43,6 @@
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
-import java.util.Map;
/**
* This class is used to specify meta information of an input method.
@@ -110,6 +110,19 @@
private final boolean mSupportsDismissingWindow;
/**
+ * @param service the {@link ResolveInfo} corresponds in which the IME is implemented.
+ * @return a unique ID to be returned by {@link #getId()}. We have used
+ * {@link ComponentName#flattenToShortString()} for this purpose (and it is already
+ * unrealistic to switch to a different scheme as it is already implicitly assumed in
+ * many places).
+ * @hide
+ */
+ public static String computeId(@NonNull ResolveInfo service) {
+ final ServiceInfo si = service.serviceInfo;
+ return new ComponentName(si.packageName, si.name).flattenToShortString();
+ }
+
+ /**
* Constructor.
*
* @param context The Context in which we are parsing the input method.
@@ -127,15 +140,15 @@
* @param context The Context in which we are parsing the input method.
* @param service The ResolveInfo returned from the package manager about
* this input method's component.
- * @param additionalSubtypesMap additional subtypes being added to this InputMethodInfo
+ * @param additionalSubtypes additional subtypes being added to this InputMethodInfo
* @hide
*/
public InputMethodInfo(Context context, ResolveInfo service,
- Map<String, List<InputMethodSubtype>> additionalSubtypesMap)
+ List<InputMethodSubtype> additionalSubtypes)
throws XmlPullParserException, IOException {
mService = service;
ServiceInfo si = service.serviceInfo;
- mId = new ComponentName(si.packageName, si.name).flattenToShortString();
+ mId = computeId(service);
boolean isAuxIme = true;
boolean supportsSwitchingToNextInputMethod = false; // false as default
boolean supportsDismissingWindow = false; // false as default
@@ -233,8 +246,7 @@
isAuxIme = false;
}
- if (additionalSubtypesMap != null && additionalSubtypesMap.containsKey(mId)) {
- final List<InputMethodSubtype> additionalSubtypes = additionalSubtypesMap.get(mId);
+ if (additionalSubtypes != null) {
final int N = additionalSubtypes.size();
for (int i = 0; i < N; ++i) {
final InputMethodSubtype subtype = additionalSubtypes.get(i);
diff --git a/core/java/android/view/textclassifier/TextClassificationManager.java b/core/java/android/view/textclassifier/TextClassificationManager.java
index 4673c50..a85dea9 100644
--- a/core/java/android/view/textclassifier/TextClassificationManager.java
+++ b/core/java/android/view/textclassifier/TextClassificationManager.java
@@ -55,7 +55,7 @@
/**
* Returns the default text classifier.
*/
- public TextClassifier getDefaultTextClassifier() {
+ public synchronized TextClassifier getDefaultTextClassifier() {
if (mDefault == null) {
try {
mFd = ParcelFileDescriptor.open(
@@ -95,7 +95,7 @@
return Collections.emptyList();
}
- private LangId getLanguageDetector() {
+ private synchronized LangId getLanguageDetector() {
if (mLangId == null) {
// TODO: Use a file descriptor as soon as we start to depend on a model file
// for language detection.
diff --git a/core/java/android/view/textclassifier/TextClassifierImpl.java b/core/java/android/view/textclassifier/TextClassifierImpl.java
index 0657067..7838918 100644
--- a/core/java/android/view/textclassifier/TextClassifierImpl.java
+++ b/core/java/android/view/textclassifier/TextClassifierImpl.java
@@ -18,6 +18,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
@@ -157,18 +158,29 @@
.setEntityType(type, 1.0f /* confidence */)
.setIntent(intent)
.setOnClickListener(TextClassificationResult.createStartActivityOnClick(
- mContext, intent))
- .setLabel(IntentFactory.getLabel(mContext, type));
+ mContext, intent));
final PackageManager pm = mContext.getPackageManager();
final ResolveInfo resolveInfo = pm.resolveActivity(intent, 0);
- // TODO: If the resolveInfo is the "chooser", do not set the package name and use a default
- // icon for this classification type.
- intent.setPackage(resolveInfo.activityInfo.packageName);
- Drawable icon = resolveInfo.activityInfo.loadIcon(pm);
- if (icon == null) {
- icon = resolveInfo.loadIcon(pm);
+ if (resolveInfo != null && resolveInfo.activityInfo != null) {
+ final String packageName = resolveInfo.activityInfo.packageName;
+ if ("android".equals(packageName)) {
+ // Requires the chooser to find an activity to handle the intent.
+ builder.setLabel(IntentFactory.getLabel(mContext, type));
+ } else {
+ // A default activity will handle the intent.
+ intent.setComponent(new ComponentName(packageName, resolveInfo.activityInfo.name));
+ Drawable icon = resolveInfo.activityInfo.loadIcon(pm);
+ if (icon == null) {
+ icon = resolveInfo.loadIcon(pm);
+ }
+ builder.setIcon(icon);
+ CharSequence label = resolveInfo.activityInfo.loadLabel(pm);
+ if (label == null) {
+ label = resolveInfo.loadLabel(pm);
+ }
+ builder.setLabel(label != null ? label.toString() : null);
+ }
}
- builder.setIcon(icon);
return builder.build();
}
@@ -211,9 +223,12 @@
final String type =
smartSelection.classifyText(text, selectionStart, selectionEnd);
if (matches(type, linkMask)) {
- final ClickableSpan span = createSpan(
- context, type, text.substring(selectionStart, selectionEnd));
- spans.add(new SpanSpec(selectionStart, selectionEnd, span));
+ final Intent intent = IntentFactory.create(
+ type, text.substring(selectionStart, selectionEnd));
+ if (hasActivityHandler(context, intent)) {
+ final ClickableSpan span = createSpan(context, intent);
+ spans.add(new SpanSpec(selectionStart, selectionEnd, span));
+ }
}
}
start = end;
@@ -279,17 +294,24 @@
return result;
}
- private static ClickableSpan createSpan(
- final Context context, final String type, final String text) {
+ private static ClickableSpan createSpan(final Context context, final Intent intent) {
return new ClickableSpan() {
// TODO: Style this span.
@Override
public void onClick(View widget) {
- context.startActivity(IntentFactory.create(type, text));
+ context.startActivity(intent);
}
};
}
+ private static boolean hasActivityHandler(Context context, @Nullable Intent intent) {
+ if (intent == null) {
+ return false;
+ }
+ final ResolveInfo resolveInfo = context.getPackageManager().resolveActivity(intent, 0);
+ return resolveInfo != null && resolveInfo.activityInfo != null;
+ }
+
/**
* Implementation of LinksInfo that adds ClickableSpans to the specified text.
*/
diff --git a/core/java/android/webkit/UserPackage.java b/core/java/android/webkit/UserPackage.java
index 404bcf4..f53b5d6 100644
--- a/core/java/android/webkit/UserPackage.java
+++ b/core/java/android/webkit/UserPackage.java
@@ -20,6 +20,7 @@
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.UserInfo;
+import android.os.Build;
import android.os.UserManager;
import java.util.ArrayList;
@@ -77,6 +78,15 @@
& ApplicationInfo.PRIVATE_FLAG_HIDDEN) == 0));
}
+ /**
+ * Returns whether the package represented by {@param packageInfo} targets a sdk version
+ * supported by the current framework version.
+ */
+ public static boolean hasCorrectTargetSdkVersion(PackageInfo packageInfo) {
+ // TODO(gsennton) use Build.VERSION_CODES.O when that has been updated.
+ return packageInfo.applicationInfo.targetSdkVersion > Build.VERSION_CODES.N_MR1;
+ }
+
public UserInfo getUserInfo() {
return mUserInfo;
}
diff --git a/core/java/android/webkit/WebViewFactory.java b/core/java/android/webkit/WebViewFactory.java
index d7a49e4..0906d1a 100644
--- a/core/java/android/webkit/WebViewFactory.java
+++ b/core/java/android/webkit/WebViewFactory.java
@@ -145,18 +145,10 @@
/**
* @hide
*/
- public static Class<WebViewFactoryProvider> getWebViewProviderClass( ClassLoader clazzLoader)
- throws ClassNotFoundException{
- try {
- return (Class<WebViewFactoryProvider>) Class.forName(CHROMIUM_WEBVIEW_FACTORY,
- true, clazzLoader);
- } catch (ClassNotFoundException e) {
- // TODO: This loads the provider which is not built for O, should be removed
- // before the release.
- return (Class<WebViewFactoryProvider>) Class.forName(
- "com.android.webview.chromium.WebViewChromiumFactoryProvider",
- true, clazzLoader);
- }
+ public static Class<WebViewFactoryProvider> getWebViewProviderClass(ClassLoader clazzLoader)
+ throws ClassNotFoundException {
+ return (Class<WebViewFactoryProvider>) Class.forName(CHROMIUM_WEBVIEW_FACTORY,
+ true, clazzLoader);
}
/**
@@ -225,15 +217,10 @@
}
}
- Trace.traceBegin(Trace.TRACE_TAG_WEBVIEW, "providerClass.newInstance()");
+ Trace.traceBegin(Trace.TRACE_TAG_WEBVIEW, "WebViewFactoryProvider invocation");
try {
- if (staticFactory != null) {
- sProviderInstance = (WebViewFactoryProvider)
- staticFactory.invoke(null, new WebViewDelegate());
- } else {
- sProviderInstance = providerClass.getConstructor(WebViewDelegate.class)
- .newInstance(new WebViewDelegate());
- }
+ sProviderInstance = (WebViewFactoryProvider)
+ staticFactory.invoke(null, new WebViewDelegate());
if (DEBUG) Log.v(LOGTAG, "Loaded provider: " + sProviderInstance);
return sProviderInstance;
} catch (Exception e) {
@@ -384,8 +371,7 @@
Trace.traceBegin(Trace.TRACE_TAG_WEBVIEW, "Class.forName()");
try {
return getWebViewProviderClass(clazzLoader);
- }
- finally {
+ } finally {
Trace.traceEnd(Trace.TRACE_TAG_WEBVIEW);
}
} catch (ClassNotFoundException e) {
diff --git a/core/java/android/widget/ActivityChooserView.java b/core/java/android/widget/ActivityChooserView.java
index 9a39a17..51587a7 100644
--- a/core/java/android/widget/ActivityChooserView.java
+++ b/core/java/android/widget/ActivityChooserView.java
@@ -250,7 +250,7 @@
mDefaultActivityButton = (FrameLayout) findViewById(R.id.default_activity_button);
mDefaultActivityButton.setOnClickListener(mCallbacks);
mDefaultActivityButton.setOnLongClickListener(mCallbacks);
- mDefaultActivityButtonImage = mDefaultActivityButton.findViewById(R.id.image);
+ mDefaultActivityButtonImage = (ImageView) mDefaultActivityButton.findViewById(R.id.image);
final FrameLayout expandButton = (FrameLayout) findViewById(R.id.expand_activities_button);
expandButton.setOnClickListener(mCallbacks);
@@ -282,7 +282,7 @@
mExpandActivityOverflowButton = expandButton;
mExpandActivityOverflowButtonImage =
- expandButton.findViewById(R.id.image);
+ (ImageView) expandButton.findViewById(R.id.image);
mExpandActivityOverflowButtonImage.setImageDrawable(expandActivityOverflowButtonDrawable);
mAdapter = new ActivityChooserViewAdapter();
@@ -760,7 +760,7 @@
convertView = LayoutInflater.from(getContext()).inflate(
R.layout.activity_chooser_view_list_item, parent, false);
convertView.setId(ITEM_VIEW_TYPE_FOOTER);
- TextView titleView = convertView.findViewById(R.id.title);
+ TextView titleView = (TextView) convertView.findViewById(R.id.title);
titleView.setText(mContext.getString(
R.string.activity_chooser_view_see_all));
}
@@ -772,11 +772,11 @@
}
PackageManager packageManager = mContext.getPackageManager();
// Set the icon
- ImageView iconView = convertView.findViewById(R.id.icon);
+ ImageView iconView = (ImageView) convertView.findViewById(R.id.icon);
ResolveInfo activity = (ResolveInfo) getItem(position);
iconView.setImageDrawable(activity.loadIcon(packageManager));
// Set the title.
- TextView titleView = convertView.findViewById(R.id.title);
+ TextView titleView = (TextView) convertView.findViewById(R.id.title);
titleView.setText(activity.loadLabel(packageManager));
// Highlight the default.
if (mShowDefaultActivity && position == 0 && mHighlightDefaultActivity) {
diff --git a/core/java/android/widget/AppSecurityPermissions.java b/core/java/android/widget/AppSecurityPermissions.java
index 06d4868..68e6809 100644
--- a/core/java/android/widget/AppSecurityPermissions.java
+++ b/core/java/android/widget/AppSecurityPermissions.java
@@ -451,7 +451,7 @@
private View getPermissionsView(int which, boolean showRevokeUI) {
LinearLayout permsView = (LinearLayout) mInflater.inflate(R.layout.app_perms_summary, null);
- LinearLayout displayList = permsView.findViewById(R.id.perms_list);
+ LinearLayout displayList = (LinearLayout) permsView.findViewById(R.id.perms_list);
View noPermsView = permsView.findViewById(R.id.no_permissions);
displayPermissions(mPermGroupsList, displayList, which, showRevokeUI);
@@ -517,8 +517,8 @@
CharSequence grpName, CharSequence permList, boolean dangerous, Drawable icon) {
View permView = inflater.inflate(R.layout.app_permission_item_old, null);
- TextView permGrpView = permView.findViewById(R.id.permission_group);
- TextView permDescView = permView.findViewById(R.id.permission_list);
+ TextView permGrpView = (TextView) permView.findViewById(R.id.permission_group);
+ TextView permDescView = (TextView) permView.findViewById(R.id.permission_list);
ImageView imgView = (ImageView)permView.findViewById(R.id.perm_icon);
imgView.setImageDrawable(icon);
diff --git a/core/java/android/widget/ArrayAdapter.java b/core/java/android/widget/ArrayAdapter.java
index 81f0d3d..bbc50da 100644
--- a/core/java/android/widget/ArrayAdapter.java
+++ b/core/java/android/widget/ArrayAdapter.java
@@ -388,7 +388,7 @@
text = (TextView) view;
} else {
// Otherwise, find the TextView field within the layout
- text = view.findViewById(mFieldId);
+ text = (TextView) view.findViewById(mFieldId);
if (text == null) {
throw new RuntimeException("Failed to find view with ID "
diff --git a/core/java/android/widget/CalendarViewLegacyDelegate.java b/core/java/android/widget/CalendarViewLegacyDelegate.java
index 1b899db..557d411 100644
--- a/core/java/android/widget/CalendarViewLegacyDelegate.java
+++ b/core/java/android/widget/CalendarViewLegacyDelegate.java
@@ -316,9 +316,9 @@
View content = layoutInflater.inflate(R.layout.calendar_view, null, false);
mDelegator.addView(content);
- mListView = mDelegator.findViewById(R.id.list);
- mDayNamesHeader = content.findViewById(R.id.day_names);
- mMonthName = content.findViewById(R.id.month_name);
+ mListView = (ListView) mDelegator.findViewById(R.id.list);
+ mDayNamesHeader = (ViewGroup) content.findViewById(R.id.day_names);
+ mMonthName = (TextView) content.findViewById(R.id.month_name);
setUpHeader();
setUpListView();
diff --git a/core/java/android/widget/CompoundButton.java b/core/java/android/widget/CompoundButton.java
index 718070d..6f687fe 100644
--- a/core/java/android/widget/CompoundButton.java
+++ b/core/java/android/widget/CompoundButton.java
@@ -561,10 +561,14 @@
stream.addProperty("checked", isChecked());
}
- // TODO(b/33197203): add unit/CTS tests for auto-fill methods
+ // TODO(b/33197203): add unit/CTS tests for auto-fill methods (and make sure they handle enable)
+
+ // TODO(b/33197203): override onProvideAutoFillStructure and add a change listener
@Override
public void autoFill(AutoFillValue value) {
+ if (!isEnabled()) return;
+
setChecked(value.getToggleValue());
}
@@ -572,4 +576,9 @@
public AutoFillType getAutoFillType() {
return AutoFillType.forToggle();
}
+
+ @Override
+ public AutoFillValue getAutoFillValue() {
+ return isEnabled() ? null : AutoFillValue.forToggle(isChecked());
+ }
}
diff --git a/core/java/android/widget/DatePickerCalendarDelegate.java b/core/java/android/widget/DatePickerCalendarDelegate.java
index 907250a..f712685 100755
--- a/core/java/android/widget/DatePickerCalendarDelegate.java
+++ b/core/java/android/widget/DatePickerCalendarDelegate.java
@@ -115,10 +115,10 @@
mDelegator.addView(mContainer);
// Set up header views.
- final ViewGroup header = mContainer.findViewById(R.id.date_picker_header);
- mHeaderYear = header.findViewById(R.id.date_picker_header_year);
+ final ViewGroup header = (ViewGroup) mContainer.findViewById(R.id.date_picker_header);
+ mHeaderYear = (TextView) header.findViewById(R.id.date_picker_header_year);
mHeaderYear.setOnClickListener(mOnHeaderClickListener);
- mHeaderMonthDay = header.findViewById(R.id.date_picker_header_date);
+ mHeaderMonthDay = (TextView) header.findViewById(R.id.date_picker_header_date);
mHeaderMonthDay.setOnClickListener(mOnHeaderClickListener);
// For the sake of backwards compatibility, attempt to extract the text
@@ -154,10 +154,10 @@
a.recycle();
// Set up picker container.
- mAnimator = mContainer.findViewById(R.id.animator);
+ mAnimator = (ViewAnimator) mContainer.findViewById(R.id.animator);
// Set up day picker view.
- mDayPickerView = mAnimator.findViewById(R.id.date_picker_day_picker);
+ mDayPickerView = (DayPickerView) mAnimator.findViewById(R.id.date_picker_day_picker);
mDayPickerView.setFirstDayOfWeek(mFirstDayOfWeek);
mDayPickerView.setMinDate(mMinDate.getTimeInMillis());
mDayPickerView.setMaxDate(mMaxDate.getTimeInMillis());
@@ -165,7 +165,7 @@
mDayPickerView.setOnDaySelectedListener(mOnDaySelectedListener);
// Set up year picker view.
- mYearPickerView = mAnimator.findViewById(R.id.date_picker_year_picker);
+ mYearPickerView = (YearPickerView) mAnimator.findViewById(R.id.date_picker_year_picker);
mYearPickerView.setRange(mMinDate, mMaxDate);
mYearPickerView.setYear(mCurrentDate.get(Calendar.YEAR));
mYearPickerView.setOnYearSelectedListener(mOnYearSelectedListener);
diff --git a/core/java/android/widget/DayPickerPagerAdapter.java b/core/java/android/widget/DayPickerPagerAdapter.java
index 63621e1..8d5bf8f 100644
--- a/core/java/android/widget/DayPickerPagerAdapter.java
+++ b/core/java/android/widget/DayPickerPagerAdapter.java
@@ -225,7 +225,7 @@
public Object instantiateItem(ViewGroup container, int position) {
final View itemView = mInflater.inflate(mLayoutResId, container, false);
- final SimpleMonthView v = itemView.findViewById(mCalendarViewId);
+ final SimpleMonthView v = (SimpleMonthView) itemView.findViewById(mCalendarViewId);
v.setOnDayClickListener(mOnDayClickListener);
v.setMonthTextAppearance(mMonthTextAppearance);
v.setDayOfWeekTextAppearance(mDayOfWeekTextAppearance);
diff --git a/core/java/android/widget/DayPickerViewPager.java b/core/java/android/widget/DayPickerViewPager.java
index 058baa6..94022ae 100644
--- a/core/java/android/widget/DayPickerViewPager.java
+++ b/core/java/android/widget/DayPickerViewPager.java
@@ -137,10 +137,9 @@
}
@Override
- protected <T extends View> T findViewByPredicateTraversal(Predicate<View> predicate,
- View childToSkip) {
+ protected View findViewByPredicateTraversal(Predicate<View> predicate, View childToSkip) {
if (predicate.apply(this)) {
- return (T) this;
+ return this;
}
// Always try the selected view first.
@@ -149,7 +148,7 @@
if (current != childToSkip && current != null) {
final View v = current.findViewByPredicate(predicate);
if (v != null) {
- return (T) v;
+ return v;
}
}
@@ -161,7 +160,7 @@
final View v = child.findViewByPredicate(predicate);
if (v != null) {
- return (T) v;
+ return v;
}
}
}
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index da3e364..76ed80f 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -3876,12 +3876,18 @@
private void updateAssistMenuItem(
Menu menu, TextClassificationResult textClassificationResult) {
menu.removeItem(TextView.ID_ASSIST);
- if (textClassificationResult != null
- && textClassificationResult.getIcon() != null
- && textClassificationResult.getOnClickListener() != null) {
- menu.add(Menu.NONE, TextView.ID_ASSIST, MENU_ITEM_ORDER_ASSIST, null)
- .setIcon(textClassificationResult.getIcon())
- .setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
+ if (textClassificationResult != null) {
+ final Drawable icon = textClassificationResult.getIcon();
+ final CharSequence label = textClassificationResult.getLabel();
+ final OnClickListener onClickListener =
+ textClassificationResult.getOnClickListener();
+ final Intent intent = textClassificationResult.getIntent();
+ if ((icon != null || !TextUtils.isEmpty(label))
+ && (onClickListener != null || intent != null)) {
+ menu.add(Menu.NONE, TextView.ID_ASSIST, MENU_ITEM_ORDER_ASSIST, label)
+ .setIcon(icon)
+ .setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
+ }
}
}
@@ -3894,9 +3900,22 @@
if (customCallback != null && customCallback.onActionItemClicked(mode, item)) {
return true;
}
- if (TextView.ID_ASSIST == item.getItemId() && mTextClassificationResult != null) {
- mTextClassificationResult.getOnClickListener().onClick(mTextView);
+ final TextClassificationResult textClassificationResult = mTextClassificationResult;
+ if (TextView.ID_ASSIST == item.getItemId() && textClassificationResult != null) {
+ final OnClickListener onClickListener =
+ textClassificationResult.getOnClickListener();
+ if (onClickListener != null) {
+ onClickListener.onClick(mTextView);
+ } else {
+ final Intent intent = textClassificationResult.getIntent();
+ if (intent != null) {
+ TextClassificationResult.createStartActivityOnClick(
+ mTextView.getContext(), intent)
+ .onClick(mTextView);
+ }
+ }
stopTextActionMode();
+ return true;
}
return mTextView.onTextContextMenuItem(item.getItemId());
}
diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java
index b7da04e..80780a6 100644
--- a/core/java/android/widget/ListView.java
+++ b/core/java/android/widget/ListView.java
@@ -3740,21 +3740,20 @@
* @removed For internal use only. This should have been hidden.
*/
@Override
- protected <T extends View> T findViewTraversal(@IdRes int id) {
- // First look in our children, then in any header and footer views that
- // may be scrolled off.
- View v = super.findViewTraversal(id);
+ protected View findViewTraversal(@IdRes int id) {
+ View v;
+ v = super.findViewTraversal(id);
if (v == null) {
v = findViewInHeadersOrFooters(mHeaderViewInfos, id);
if (v != null) {
- return (T) v;
+ return v;
}
v = findViewInHeadersOrFooters(mFooterViewInfos, id);
if (v != null) {
- return (T) v;
+ return v;
}
}
- return (T) v;
+ return v;
}
View findViewInHeadersOrFooters(ArrayList<FixedViewInfo> where, int id) {
@@ -3783,22 +3782,21 @@
* @removed For internal use only. This should have been hidden.
*/
@Override
- protected <T extends View> T findViewWithTagTraversal(Object tag) {
- // First look in our children, then in any header and footer views that
- // may be scrolled off.
- View v = super.findViewWithTagTraversal(tag);
+ protected View findViewWithTagTraversal(Object tag) {
+ View v;
+ v = super.findViewWithTagTraversal(tag);
if (v == null) {
v = findViewWithTagInHeadersOrFooters(mHeaderViewInfos, tag);
if (v != null) {
- return (T) v;
+ return v;
}
v = findViewWithTagInHeadersOrFooters(mFooterViewInfos, tag);
if (v != null) {
- return (T) v;
+ return v;
}
}
- return (T) v;
+ return v;
}
View findViewWithTagInHeadersOrFooters(ArrayList<FixedViewInfo> where, Object tag) {
@@ -3831,21 +3829,21 @@
* @hide
*/
@Override
- protected <T extends View> T findViewByPredicateTraversal(
- Predicate<View> predicate, View childToSkip) {
- View v = super.findViewByPredicateTraversal(predicate, childToSkip);
+ protected View findViewByPredicateTraversal(Predicate<View> predicate, View childToSkip) {
+ View v;
+ v = super.findViewByPredicateTraversal(predicate, childToSkip);
if (v == null) {
v = findViewByPredicateInHeadersOrFooters(mHeaderViewInfos, predicate, childToSkip);
if (v != null) {
- return (T) v;
+ return v;
}
v = findViewByPredicateInHeadersOrFooters(mFooterViewInfos, predicate, childToSkip);
if (v != null) {
- return (T) v;
+ return v;
}
}
- return (T) v;
+ return v;
}
/**
diff --git a/core/java/android/widget/MediaController.java b/core/java/android/widget/MediaController.java
index 8e04f1c..8008637 100644
--- a/core/java/android/widget/MediaController.java
+++ b/core/java/android/widget/MediaController.java
@@ -257,13 +257,13 @@
.getText(com.android.internal.R.string.lockscreen_transport_play_description);
mPauseDescription = res
.getText(com.android.internal.R.string.lockscreen_transport_pause_description);
- mPauseButton = v.findViewById(com.android.internal.R.id.pause);
+ mPauseButton = (ImageButton) v.findViewById(com.android.internal.R.id.pause);
if (mPauseButton != null) {
mPauseButton.requestFocus();
mPauseButton.setOnClickListener(mPauseListener);
}
- mFfwdButton = v.findViewById(com.android.internal.R.id.ffwd);
+ mFfwdButton = (ImageButton) v.findViewById(com.android.internal.R.id.ffwd);
if (mFfwdButton != null) {
mFfwdButton.setOnClickListener(mFfwdListener);
if (!mFromXml) {
@@ -271,7 +271,7 @@
}
}
- mRewButton = v.findViewById(com.android.internal.R.id.rew);
+ mRewButton = (ImageButton) v.findViewById(com.android.internal.R.id.rew);
if (mRewButton != null) {
mRewButton.setOnClickListener(mRewListener);
if (!mFromXml) {
@@ -280,16 +280,16 @@
}
// By default these are hidden. They will be enabled when setPrevNextListeners() is called
- mNextButton = v.findViewById(com.android.internal.R.id.next);
+ mNextButton = (ImageButton) v.findViewById(com.android.internal.R.id.next);
if (mNextButton != null && !mFromXml && !mListenersSet) {
mNextButton.setVisibility(View.GONE);
}
- mPrevButton = v.findViewById(com.android.internal.R.id.prev);
+ mPrevButton = (ImageButton) v.findViewById(com.android.internal.R.id.prev);
if (mPrevButton != null && !mFromXml && !mListenersSet) {
mPrevButton.setVisibility(View.GONE);
}
- mProgress = v.findViewById(com.android.internal.R.id.mediacontroller_progress);
+ mProgress = (ProgressBar) v.findViewById(com.android.internal.R.id.mediacontroller_progress);
if (mProgress != null) {
if (mProgress instanceof SeekBar) {
SeekBar seeker = (SeekBar) mProgress;
@@ -298,8 +298,8 @@
mProgress.setMax(1000);
}
- mEndTime = v.findViewById(com.android.internal.R.id.time);
- mCurrentTime = v.findViewById(com.android.internal.R.id.time_current);
+ mEndTime = (TextView) v.findViewById(com.android.internal.R.id.time);
+ mCurrentTime = (TextView) v.findViewById(com.android.internal.R.id.time_current);
mFormatBuilder = new StringBuilder();
mFormatter = new Formatter(mFormatBuilder, Locale.getDefault());
diff --git a/core/java/android/widget/PopupWindow.java b/core/java/android/widget/PopupWindow.java
index 5199b26..989927e 100644
--- a/core/java/android/widget/PopupWindow.java
+++ b/core/java/android/widget/PopupWindow.java
@@ -35,8 +35,8 @@
import android.transition.Transition;
import android.transition.Transition.EpicenterCallback;
import android.transition.Transition.TransitionListener;
-import android.transition.Transition.TransitionListenerAdapter;
import android.transition.TransitionInflater;
+import android.transition.TransitionListenerAdapter;
import android.transition.TransitionManager;
import android.transition.TransitionSet;
import android.util.AttributeSet;
diff --git a/core/java/android/widget/RadioGroup.java b/core/java/android/widget/RadioGroup.java
index 45fd9e6..8ba4694 100644
--- a/core/java/android/widget/RadioGroup.java
+++ b/core/java/android/widget/RadioGroup.java
@@ -403,10 +403,14 @@
}
}
- // TODO(b/33197203): add unit/CTS tests for auto-fill methods
+ // TODO(b/33197203): add unit/CTS tests for auto-fill methods (and make sure they handle enable)
+
+ // TODO(b/33197203): override onProvideAutoFillStructure and add a change listener
@Override
public void autoFill(AutoFillValue value) {
+ if (!isEnabled()) return;
+
final int index = value.getListValue();
final View child = getChildAt(index);
if (child == null) {
@@ -420,4 +424,9 @@
public AutoFillType getAutoFillType() {
return AutoFillType.forList();
}
+
+ @Override
+ public AutoFillValue getAutoFillValue() {
+ return isEnabled() ? AutoFillValue.forList(getCheckedRadioButtonId()) : null;
+ }
}
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index 5505f2f..359d04e 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -1578,7 +1578,7 @@
@Override
public void apply(View root, ViewGroup rootParent, OnClickHandler handler) {
final Context context = root.getContext();
- final ViewGroup target = root.findViewById(viewId);
+ final ViewGroup target = (ViewGroup) root.findViewById(viewId);
if (target == null) return;
if (nestedViews != null) {
// Inflate nested views and add as children
@@ -1757,7 +1757,7 @@
@Override
public void apply(View root, ViewGroup rootParent, OnClickHandler handler) {
- final TextView target = root.findViewById(viewId);
+ final TextView target = (TextView) root.findViewById(viewId);
if (target == null) return;
if (drawablesLoaded) {
if (isRelative) {
@@ -1857,7 +1857,7 @@
@Override
public void apply(View root, ViewGroup rootParent, OnClickHandler handler) {
- final TextView target = root.findViewById(viewId);
+ final TextView target = (TextView) root.findViewById(viewId);
if (target == null) return;
target.setTextSize(units, size);
}
@@ -2045,7 +2045,7 @@
@Override
public void apply(View root, ViewGroup rootParent, OnClickHandler handler) {
- final TextView target = root.findViewById(viewId);
+ final TextView target = (TextView) root.findViewById(viewId);
if (target == null) return;
Drawable[] drawables = isRelative
? target.getCompoundDrawablesRelative()
diff --git a/core/java/android/widget/SuggestionsAdapter.java b/core/java/android/widget/SuggestionsAdapter.java
index fbb8993..f833d1b 100644
--- a/core/java/android/widget/SuggestionsAdapter.java
+++ b/core/java/android/widget/SuggestionsAdapter.java
@@ -286,7 +286,7 @@
v.setTag(new ChildViewCache(v));
// Set up icon.
- final ImageView iconRefine = v.findViewById(R.id.edit_query);
+ final ImageView iconRefine = (ImageView) v.findViewById(R.id.edit_query);
iconRefine.setImageResource(mCommitIconResId);
return v;
@@ -304,11 +304,11 @@
public final ImageView mIconRefine;
public ChildViewCache(View v) {
- mText1 = v.findViewById(com.android.internal.R.id.text1);
- mText2 = v.findViewById(com.android.internal.R.id.text2);
- mIcon1 = v.findViewById(com.android.internal.R.id.icon1);
- mIcon2 = v.findViewById(com.android.internal.R.id.icon2);
- mIconRefine = v.findViewById(com.android.internal.R.id.edit_query);
+ mText1 = (TextView) v.findViewById(com.android.internal.R.id.text1);
+ mText2 = (TextView) v.findViewById(com.android.internal.R.id.text2);
+ mIcon1 = (ImageView) v.findViewById(com.android.internal.R.id.icon1);
+ mIcon2 = (ImageView) v.findViewById(com.android.internal.R.id.icon2);
+ mIconRefine = (ImageView) v.findViewById(com.android.internal.R.id.edit_query);
}
}
diff --git a/core/java/android/widget/TabHost.java b/core/java/android/widget/TabHost.java
index 7e2cadf..32418cd 100644
--- a/core/java/android/widget/TabHost.java
+++ b/core/java/android/widget/TabHost.java
@@ -619,7 +619,7 @@
mTabWidget, // tab widget is the parent
false); // no inflate params
- final TextView tv = tabIndicator.findViewById(R.id.title);
+ final TextView tv = (TextView) tabIndicator.findViewById(R.id.title);
tv.setText(mLabel);
if (context.getApplicationInfo().targetSdkVersion <= Build.VERSION_CODES.DONUT) {
@@ -653,8 +653,8 @@
mTabWidget, // tab widget is the parent
false); // no inflate params
- final TextView tv = tabIndicator.findViewById(R.id.title);
- final ImageView iconView = tabIndicator.findViewById(R.id.icon);
+ final TextView tv = (TextView) tabIndicator.findViewById(R.id.title);
+ final ImageView iconView = (ImageView) tabIndicator.findViewById(R.id.icon);
// when icon is gone by default, we're in exclusive mode
final boolean exclusive = iconView.getVisibility() == View.GONE;
diff --git a/core/java/android/widget/TextInputTimePickerView.java b/core/java/android/widget/TextInputTimePickerView.java
new file mode 100644
index 0000000..ef91576
--- /dev/null
+++ b/core/java/android/widget/TextInputTimePickerView.java
@@ -0,0 +1,249 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.widget;
+
+import android.content.Context;
+import android.text.Editable;
+import android.text.InputFilter;
+import android.text.TextWatcher;
+import android.util.AttributeSet;
+import android.util.MathUtils;
+import android.view.View;
+
+import com.android.internal.R;
+
+/**
+ * View to show text input based time picker with hour and minute fields and an optional AM/PM
+ * spinner.
+ *
+ * @hide
+ */
+public class TextInputTimePickerView extends RelativeLayout {
+ public static final int HOURS = 0;
+ public static final int MINUTES = 1;
+ public static final int AMPM = 2;
+
+ private static final int AM = 0;
+ private static final int PM = 1;
+
+ private final EditText mHourEditText;
+ private final EditText mMinuteEditText;
+ private final TextView mInputSeparatorView;
+ private final Spinner mAmPmSpinner;
+ private final TextView mErrorLabel;
+ private final TextView mHourLabel;
+ private final TextView mMinuteLabel;
+
+ private boolean mIs24Hour;
+ private boolean mHourFormatStartsAtZero;
+ private OnValueTypedListener mListener;
+
+ private boolean mErrorShowing;
+
+ interface OnValueTypedListener {
+ void onValueChanged(int inputType, int newValue);
+ }
+
+ public TextInputTimePickerView(Context context) {
+ this(context, null);
+ }
+
+ public TextInputTimePickerView(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public TextInputTimePickerView(Context context, AttributeSet attrs, int defStyle) {
+ this(context, attrs, defStyle, 0);
+ }
+
+ public TextInputTimePickerView(Context context, AttributeSet attrs, int defStyle,
+ int defStyleRes) {
+ super(context, attrs, defStyle, defStyleRes);
+
+ inflate(context, R.layout.time_picker_text_input_material, this);
+
+ mHourEditText = (EditText) findViewById(R.id.input_hour);
+ mMinuteEditText = (EditText) findViewById(R.id.input_minute);
+ mInputSeparatorView = (TextView) findViewById(R.id.input_separator);
+ mErrorLabel = (TextView) findViewById(R.id.label_error);
+ mHourLabel = (TextView) findViewById(R.id.label_hour);
+ mMinuteLabel = (TextView) findViewById(R.id.label_minute);
+
+ mHourEditText.addTextChangedListener(new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {}
+
+ @Override
+ public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {}
+
+ @Override
+ public void afterTextChanged(Editable editable) {
+ parseAndSetHourInternal(editable.toString());
+ }
+ });
+
+ mMinuteEditText.addTextChangedListener(new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {}
+
+ @Override
+ public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {}
+
+ @Override
+ public void afterTextChanged(Editable editable) {
+ parseAndSetMinuteInternal(editable.toString());
+ }
+ });
+
+ mAmPmSpinner = (Spinner) findViewById(R.id.am_pm_spinner);
+ final String[] amPmStrings = TimePicker.getAmPmStrings(context);
+ ArrayAdapter<CharSequence> adapter =
+ new ArrayAdapter<CharSequence>(context, R.layout.simple_spinner_dropdown_item);
+ adapter.add(TimePickerClockDelegate.obtainVerbatim(amPmStrings[0]));
+ adapter.add(TimePickerClockDelegate.obtainVerbatim(amPmStrings[1]));
+ mAmPmSpinner.setAdapter(adapter);
+ mAmPmSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
+ @Override
+ public void onItemSelected(AdapterView<?> adapterView, View view, int position,
+ long id) {
+ if (position == 0) {
+ mListener.onValueChanged(AMPM, AM);
+ } else {
+ mListener.onValueChanged(AMPM, PM);
+ }
+ }
+
+ @Override
+ public void onNothingSelected(AdapterView<?> adapterView) {}
+ });
+ }
+
+ void setListener(OnValueTypedListener listener) {
+ mListener = listener;
+ }
+
+ void setHourFormat(int maxCharLength) {
+ mHourEditText.setFilters(new InputFilter[] {
+ new InputFilter.LengthFilter(maxCharLength)});
+ mMinuteEditText.setFilters(new InputFilter[] {
+ new InputFilter.LengthFilter(maxCharLength)});
+ }
+
+ boolean validateInput() {
+ final boolean inputValid = parseAndSetHourInternal(mHourEditText.getText().toString())
+ && parseAndSetMinuteInternal(mMinuteEditText.getText().toString());
+ setError(!inputValid);
+ return inputValid;
+ }
+
+ void updateSeparator(String separatorText) {
+ mInputSeparatorView.setText(separatorText);
+ }
+
+ private void setError(boolean enabled) {
+ mErrorShowing = enabled;
+
+ mErrorLabel.setVisibility(enabled ? View.VISIBLE : View.INVISIBLE);
+ mHourLabel.setVisibility(enabled ? View.INVISIBLE : View.VISIBLE);
+ mMinuteLabel.setVisibility(enabled ? View.INVISIBLE : View.VISIBLE);
+ }
+
+ /**
+ * Computes the display value and updates the text of the view.
+ * <p>
+ * This method should be called whenever the current value or display
+ * properties (leading zeroes, max digits) change.
+ */
+ void updateTextInputValues(int localizedHour, int minute, int amOrPm, boolean is24Hour,
+ boolean hourFormatStartsAtZero) {
+ final String format = "%d";
+
+ mIs24Hour = is24Hour;
+ mHourFormatStartsAtZero = hourFormatStartsAtZero;
+
+ mAmPmSpinner.setVisibility(is24Hour ? View.INVISIBLE : View.VISIBLE);
+
+ mHourEditText.setText(String.format(format, localizedHour));
+ mMinuteEditText.setText(String.format(format, minute));
+
+ if (amOrPm == AM) {
+ mAmPmSpinner.setSelection(0);
+ } else {
+ mAmPmSpinner.setSelection(1);
+ }
+
+ if (mErrorShowing) {
+ validateInput();
+ }
+ }
+
+ private boolean parseAndSetHourInternal(String input) {
+ try {
+ final int hour = Integer.parseInt(input);
+ if (!isValidLocalizedHour(hour)) {
+ final int minHour = mHourFormatStartsAtZero ? 0 : 1;
+ final int maxHour = mIs24Hour ? 23 : 11 + minHour;
+ mListener.onValueChanged(HOURS, getHourOfDayFromLocalizedHour(
+ MathUtils.constrain(hour, minHour, maxHour)));
+ return false;
+ }
+ mListener.onValueChanged(HOURS, getHourOfDayFromLocalizedHour(hour));
+ return true;
+ } catch (NumberFormatException e) {
+ // Do nothing since we cannot parse the input.
+ return false;
+ }
+ }
+
+ private boolean parseAndSetMinuteInternal(String input) {
+ try {
+ final int minutes = Integer.parseInt(input);
+ if (minutes < 0 || minutes > 59) {
+ mListener.onValueChanged(MINUTES, MathUtils.constrain(minutes, 0, 59));
+ return false;
+ }
+ mListener.onValueChanged(MINUTES, minutes);
+ return true;
+ } catch (NumberFormatException e) {
+ // Do nothing since we cannot parse the input.
+ return false;
+ }
+ }
+
+ private boolean isValidLocalizedHour(int localizedHour) {
+ final int minHour = mHourFormatStartsAtZero ? 0 : 1;
+ final int maxHour = (mIs24Hour ? 23 : 11) + minHour;
+ return localizedHour >= minHour && localizedHour <= maxHour;
+ }
+
+ private int getHourOfDayFromLocalizedHour(int localizedHour) {
+ int hourOfDay = localizedHour;
+ if (mIs24Hour) {
+ if (!mHourFormatStartsAtZero && localizedHour == 24) {
+ hourOfDay = 0;
+ }
+ } else {
+ if (!mHourFormatStartsAtZero && localizedHour == 12) {
+ hourOfDay = 0;
+ }
+ if (mAmPmSpinner.getSelectedItemPosition() == 1) {
+ hourOfDay += 12;
+ }
+ }
+ return hourOfDay;
+ }
+}
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index e66b5e7..b18ca45 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -718,6 +718,9 @@
// Contains the sorted set of desired text sizes in pixels to pick from when auto-sizing text.
private int[] mAutoSizeTextSizesInPx;
+ // Watcher used to notify changes to auto-fill manager.
+ private AutoFillChangeWatcher mAutoFillChangeWatcher;
+
/**
* Kick-start the font cache for the zygote process (to pay the cost of
* initializing freetype for our default font only once).
@@ -9643,7 +9646,7 @@
return new GestureDetector(mContext,
new GestureDetector.SimpleOnGestureListener() {
@Override
- public boolean onSingleTapConfirmed(MotionEvent e) {
+ public boolean onSingleTapUp(MotionEvent e) {
if (shouldUseClickableSpanOnClickGestureDetector()) {
ClickableSpan[] links = ((Spannable) mText).getSpans(
getSelectionStart(), getSelectionEnd(),
@@ -9706,24 +9709,31 @@
@Override
public void onProvideStructure(ViewStructure structure) {
super.onProvideStructure(structure);
- onProvideAutoStructureForAssistOrAutoFill(structure, 0);
+ onProvideAutoStructureForAssistOrAutoFill(structure, false);
}
@Override
public void onProvideAutoFillStructure(ViewStructure structure, int flags) {
super.onProvideAutoFillStructure(structure, flags);
- onProvideAutoStructureForAssistOrAutoFill(structure, flags);
+ onProvideAutoStructureForAssistOrAutoFill(structure, true);
}
- private void onProvideAutoStructureForAssistOrAutoFill(ViewStructure structure, int flags) {
- // NOTE: currently flags are only used for AutoFill; if they're used for Assist as well,
- // this method should take a boolean with the type of request.
- final boolean forAutoFillSave =
- (flags & AUTO_FILL_FLAG_TYPE_SAVE) != 0;
-
+ private void onProvideAutoStructureForAssistOrAutoFill(ViewStructure structure,
+ boolean forAutoFill) {
final boolean isPassword = hasPasswordTransformationMethod()
|| isPasswordInputType(getInputType());
- if (!isPassword || forAutoFillSave) {
+ if (forAutoFill) {
+ // TODO(b/33197203, b/33269702): temporary set it as not sanitized until
+ // AssistStructure automaticaly sets sanitization based on text coming from resources
+ structure.setSanitized(!isPassword);
+ if (mAutoFillChangeWatcher == null && isTextEditable()) {
+ mAutoFillChangeWatcher = new AutoFillChangeWatcher();
+ addTextChangedListener(mAutoFillChangeWatcher);
+ // TODO(b/33197203): remove mAutoFillValueListener auto-fill session is finished
+ }
+ }
+
+ if (!isPassword || forAutoFill) {
if (mLayout == null) {
assumeLayout();
}
@@ -9731,7 +9741,8 @@
final int lineCount = layout.getLineCount();
if (lineCount <= 1) {
// Simple case: this is a single line.
- structure.setText(getText(), getSelectionStart(), getSelectionEnd());
+ final CharSequence text = getText();
+ structure.setText(text, getSelectionStart(), getSelectionEnd());
} else {
// Complex case: multi-line, could be scrolled or within a scroll container
// so some lines are not visible.
@@ -9835,7 +9846,7 @@
final CharSequence text = value.getTextValue();
if (text != null && isTextEditable()) {
- setText(text);
+ setText(text, mBufferType, true, 0);
}
}
@@ -9845,6 +9856,12 @@
return isTextEditable() ? AutoFillType.forText(getInputType()) : null;
}
+ @Override
+ @Nullable
+ public AutoFillValue getAutoFillValue() {
+ return isTextEditable() ? AutoFillValue.forText(getText()) : null;
+ }
+
/** @hide */
@Override
public void onInitializeAccessibilityEventInternal(AccessibilityEvent event) {
@@ -10864,14 +10881,6 @@
* @hide
*/
protected void viewClicked(InputMethodManager imm) {
- final AutoFillManager afm = mContext.getSystemService(AutoFillManager.class);
- if (afm != null) {
- if (DEBUG_AUTOFILL) Log.v(LOG_TAG, "viewClicked(): id=" + getAccessibilityViewId());
-
- // TODO(b/33197203): integrate with onFocus and/or move to view?
- afm.updateAutoFillInput(this, AutoFillManager.FLAG_UPDATE_UI_SHOW);
- }
-
if (imm != null) {
imm.viewClicked(this);
}
@@ -11350,6 +11359,30 @@
}
}
+ // TODO(b/33197203): implements SpanWatcher too?
+ private final class AutoFillChangeWatcher implements TextWatcher {
+
+ private final AutoFillManager mAfm = mContext.getSystemService(AutoFillManager.class);
+
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+ }
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
+ }
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ if (mAfm != null) {
+ if (DEBUG_AUTOFILL) {
+ Log.v(LOG_TAG, "AutoFillChangeWatcher.afterTextChanged(): s=" + s);
+ }
+ mAfm.valueChanged(TextView.this);
+ }
+ }
+ }
+
private class ChangeWatcher implements TextWatcher, SpanWatcher {
private CharSequence mBeforeText;
diff --git a/core/java/android/widget/TimePicker.java b/core/java/android/widget/TimePicker.java
index e6cd798..9f38b04 100644
--- a/core/java/android/widget/TimePicker.java
+++ b/core/java/android/widget/TimePicker.java
@@ -278,6 +278,16 @@
return mDelegate.getBaseline();
}
+ /**
+ * Validates whether current input by the user is a valid time based on the locale. TimePicker
+ * will show an error message to the user if the time is not valid.
+ *
+ * @return {@code true} if the input is valid, {@code false} otherwise
+ */
+ public boolean validateInput() {
+ return mDelegate.validateInput();
+ }
+
@Override
protected Parcelable onSaveInstanceState() {
Parcelable superState = super.onSaveInstanceState();
@@ -341,6 +351,8 @@
void setIs24Hour(boolean is24Hour);
boolean is24Hour();
+ boolean validateInput();
+
void setOnTimeChangedListener(OnTimeChangedListener onTimeChangedListener);
void setEnabled(boolean enabled);
diff --git a/core/java/android/widget/TimePickerClockDelegate.java b/core/java/android/widget/TimePickerClockDelegate.java
index 1d37a21..3a09063 100644
--- a/core/java/android/widget/TimePickerClockDelegate.java
+++ b/core/java/android/widget/TimePickerClockDelegate.java
@@ -16,12 +16,14 @@
package android.widget;
+import android.annotation.IntDef;
import android.annotation.Nullable;
import android.annotation.TestApi;
import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.content.res.TypedArray;
+import android.icu.text.DecimalFormatSymbols;
import android.os.Parcelable;
import android.text.SpannableStringBuilder;
import android.text.format.DateFormat;
@@ -40,11 +42,14 @@
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
import android.widget.RadialTimePickerView.OnValueSelectedListener;
+import android.widget.TextInputTimePickerView.OnValueTypedListener;
import com.android.internal.R;
import com.android.internal.widget.NumericTextView;
import com.android.internal.widget.NumericTextView.OnValueChangedListener;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.Calendar;
/**
@@ -58,6 +63,13 @@
*/
private static final long DELAY_COMMIT_MILLIS = 2000;
+ @IntDef({FROM_EXTERNAL_API, FROM_RADIAL_PICKER, FROM_INPUT_PICKER})
+ @Retention(RetentionPolicy.SOURCE)
+ private @interface ChangeSource {}
+ private static final int FROM_EXTERNAL_API = 0;
+ private static final int FROM_RADIAL_PICKER = 1;
+ private static final int FROM_INPUT_PICKER = 2;
+
// Index used by RadialPickerLayout
private static final int HOUR_INDEX = RadialTimePickerView.HOURS;
private static final int MINUTE_INDEX = RadialTimePickerView.MINUTES;
@@ -78,6 +90,15 @@
private final RadialTimePickerView mRadialTimePickerView;
private final TextView mSeparatorView;
+ private boolean mRadialPickerModeEnabled = true;
+ private final ImageButton mRadialTimePickerModeButton;
+ private final String mRadialTimePickerModeEnabledDescription;
+ private final String mTextInputPickerModeEnabledDescription;
+ private final View mRadialTimePickerHeader;
+ private final View mTextInputPickerHeader;
+
+ private final TextInputTimePickerView mTextInputPickerView;
+
private final Calendar mTempCalendar;
// Accessibility strings.
@@ -116,8 +137,8 @@
final int layoutResourceId = a.getResourceId(R.styleable.TimePicker_internalLayout,
R.layout.time_picker_material);
final View mainView = inflater.inflate(layoutResourceId, delegator);
- final View headerView = mainView.findViewById(R.id.time_header);
- headerView.setOnTouchListener(new NearestTouchDelegate());
+ mRadialTimePickerHeader = mainView.findViewById(R.id.time_header);
+ mRadialTimePickerHeader.setOnTouchListener(new NearestTouchDelegate());
// Set up hour/minute labels.
mHourView = (NumericTextView) mainView.findViewById(R.id.hours);
@@ -170,6 +191,8 @@
headerTextColor = a.getColorStateList(R.styleable.TimePicker_headerTextColor);
}
+ mTextInputPickerHeader = mainView.findViewById(R.id.input_header);
+
if (headerTextColor != null) {
mHourView.setTextColor(headerTextColor);
mSeparatorView.setTextColor(headerTextColor);
@@ -180,7 +203,10 @@
// Set up header background, if available.
if (a.hasValueOrEmpty(R.styleable.TimePicker_headerBackground)) {
- headerView.setBackground(a.getDrawable(R.styleable.TimePicker_headerBackground));
+ mRadialTimePickerHeader.setBackground(a.getDrawable(
+ R.styleable.TimePicker_headerBackground));
+ mTextInputPickerHeader.setBackground(a.getDrawable(
+ R.styleable.TimePicker_headerBackground));
}
a.recycle();
@@ -189,6 +215,22 @@
mRadialTimePickerView.applyAttributes(attrs, defStyleAttr, defStyleRes);
mRadialTimePickerView.setOnValueSelectedListener(mOnValueSelectedListener);
+ mTextInputPickerView = (TextInputTimePickerView) mainView.findViewById(R.id.input_mode);
+ mTextInputPickerView.setListener(mOnValueTypedListener);
+
+ mRadialTimePickerModeButton =
+ (ImageButton) mainView.findViewById(R.id.toggle_mode);
+ mRadialTimePickerModeButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ toggleRadialPickerMode();
+ }
+ });
+ mRadialTimePickerModeEnabledDescription = context.getResources().getString(
+ R.string.time_picker_radial_mode_description);
+ mTextInputPickerModeEnabledDescription = context.getResources().getString(
+ R.string.time_picker_text_input_mode_description);
+
mAllowAutoAdvance = true;
updateHourFormat();
@@ -200,6 +242,34 @@
initialize(currentHour, currentMinute, mIs24Hour, HOUR_INDEX);
}
+ private void toggleRadialPickerMode() {
+ if (mRadialPickerModeEnabled) {
+ mRadialTimePickerView.setVisibility(View.GONE);
+ mRadialTimePickerHeader.setVisibility(View.GONE);
+ mTextInputPickerHeader.setVisibility(View.VISIBLE);
+ mTextInputPickerView.setVisibility(View.VISIBLE);
+ mRadialTimePickerModeButton.setImageResource(R.drawable.btn_event_material);
+ mRadialTimePickerModeButton.setContentDescription(
+ mRadialTimePickerModeEnabledDescription);
+ mRadialPickerModeEnabled = false;
+ } else {
+ mRadialTimePickerView.setVisibility(View.VISIBLE);
+ mRadialTimePickerHeader.setVisibility(View.VISIBLE);
+ mTextInputPickerHeader.setVisibility(View.GONE);
+ mTextInputPickerView.setVisibility(View.GONE);
+ mRadialTimePickerModeButton.setImageResource(R.drawable.btn_keyboard_key_material);
+ mRadialTimePickerModeButton.setContentDescription(
+ mTextInputPickerModeEnabledDescription);
+ updateTextInputPicker();
+ mRadialPickerModeEnabled = true;
+ }
+ }
+
+ @Override
+ public boolean validateInput() {
+ return mTextInputPickerView.validateInput();
+ }
+
/**
* Ensures that a TextView is wide enough to contain its text without
* wrapping or clipping. Measures the specified view and sets the minimum
@@ -249,9 +319,16 @@
final int maxHour = (mIs24Hour ? 23 : 11) + minHour;
mHourView.setRange(minHour, maxHour);
mHourView.setShowLeadingZeroes(mHourFormatShowLeadingZero);
+
+ final String[] digits = DecimalFormatSymbols.getInstance(mLocale).getDigitStrings();
+ int maxCharLength = 0;
+ for (int i = 0; i < 10; i++) {
+ maxCharLength = Math.max(maxCharLength, digits[i].length());
+ }
+ mTextInputPickerView.setHourFormat(maxCharLength * 2);
}
- private static final CharSequence obtainVerbatim(String text) {
+ static final CharSequence obtainVerbatim(String text) {
return new SpannableStringBuilder().append(text,
new TtsSpan.VerbatimBuilder(text).build(), 0);
}
@@ -333,10 +410,16 @@
updateHeaderSeparator();
updateHeaderMinute(mCurrentMinute, false);
updateRadialPicker(index);
+ updateTextInputPicker();
mDelegator.invalidate();
}
+ private void updateTextInputPicker() {
+ mTextInputPickerView.updateTextInputValues(getLocalizedHour(mCurrentHour), mCurrentMinute,
+ mCurrentHour < 12 ? AM : PM, mIs24Hour, mHourFormatStartsAtZero);
+ }
+
private void updateRadialPicker(int index) {
mRadialTimePickerView.initialize(mCurrentHour, mCurrentMinute, mIs24Hour);
setCurrentItemShowing(index, false, true);
@@ -381,10 +464,10 @@
*/
@Override
public void setHour(int hour) {
- setHourInternal(hour, false, true);
+ setHourInternal(hour, FROM_EXTERNAL_API, true);
}
- private void setHourInternal(int hour, boolean isFromPicker, boolean announce) {
+ private void setHourInternal(int hour, @ChangeSource int source, boolean announce) {
if (mCurrentHour == hour) {
return;
}
@@ -393,10 +476,13 @@
updateHeaderHour(hour, announce);
updateHeaderAmPm();
- if (!isFromPicker) {
+ if (source != FROM_RADIAL_PICKER) {
mRadialTimePickerView.setCurrentHour(hour);
mRadialTimePickerView.setAmOrPm(hour < 12 ? AM : PM);
}
+ if (source != FROM_INPUT_PICKER) {
+ updateTextInputPicker();
+ }
mDelegator.invalidate();
onTimeChanged();
@@ -424,10 +510,10 @@
*/
@Override
public void setMinute(int minute) {
- setMinuteInternal(minute, false);
+ setMinuteInternal(minute, FROM_EXTERNAL_API);
}
- private void setMinuteInternal(int minute, boolean isFromPicker) {
+ private void setMinuteInternal(int minute, @ChangeSource int source) {
if (mCurrentMinute == minute) {
return;
}
@@ -435,9 +521,12 @@
mCurrentMinute = minute;
updateHeaderMinute(minute, true);
- if (!isFromPicker) {
+ if (source != FROM_RADIAL_PICKER) {
mRadialTimePickerView.setCurrentMinute(minute);
}
+ if (source != FROM_INPUT_PICKER) {
+ updateTextInputPicker();
+ }
mDelegator.invalidate();
onTimeChanged();
@@ -661,6 +750,7 @@
separatorText = Character.toString(bestDateTimePattern.charAt(hIndex + 1));
}
mSeparatorView.setText(separatorText);
+ mTextInputPickerView.updateSeparator(separatorText);
}
static private int lastIndexOfAny(String str, char[] any) {
@@ -712,7 +802,7 @@
if (mRadialTimePickerView.setAmOrPm(amOrPm)) {
mCurrentHour = getHour();
-
+ updateTextInputPicker();
if (mOnTimeChangedListener != null) {
mOnTimeChangedListener.onTimeChanged(mDelegator, getHour(), getMinute());
}
@@ -726,7 +816,7 @@
switch (pickerType) {
case RadialTimePickerView.HOURS:
final boolean isTransition = mAllowAutoAdvance && autoAdvance;
- setHourInternal(newValue, true, !isTransition);
+ setHourInternal(newValue, FROM_RADIAL_PICKER, !isTransition);
if (isTransition) {
setCurrentItemShowing(MINUTE_INDEX, true, false);
@@ -735,7 +825,7 @@
}
break;
case RadialTimePickerView.MINUTES:
- setMinuteInternal(newValue, true);
+ setMinuteInternal(newValue, FROM_RADIAL_PICKER);
break;
}
@@ -745,6 +835,23 @@
}
};
+ private final OnValueTypedListener mOnValueTypedListener = new OnValueTypedListener() {
+ @Override
+ public void onValueChanged(int pickerType, int newValue) {
+ switch (pickerType) {
+ case TextInputTimePickerView.HOURS:
+ setHourInternal(newValue, FROM_INPUT_PICKER, false);
+ break;
+ case TextInputTimePickerView.MINUTES:
+ setMinuteInternal(newValue, FROM_INPUT_PICKER);
+ break;
+ case TextInputTimePickerView.AMPM:
+ setAmOrPm(newValue);
+ break;
+ }
+ }
+ };
+
/** Listener for keyboard interaction. */
private final OnValueChangedListener mDigitEnteredListener = new OnValueChangedListener() {
@Override
diff --git a/core/java/android/widget/TimePickerSpinnerDelegate.java b/core/java/android/widget/TimePickerSpinnerDelegate.java
index 4634631..7ef54a5 100644
--- a/core/java/android/widget/TimePickerSpinnerDelegate.java
+++ b/core/java/android/widget/TimePickerSpinnerDelegate.java
@@ -86,7 +86,7 @@
inflater.inflate(layoutResourceId, mDelegator, true);
// hour
- mHourSpinner = delegator.findViewById(R.id.hour);
+ mHourSpinner = (NumberPicker) delegator.findViewById(R.id.hour);
mHourSpinner.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
public void onValueChange(NumberPicker spinner, int oldVal, int newVal) {
updateInputState();
@@ -100,17 +100,17 @@
onTimeChanged();
}
});
- mHourSpinnerInput = mHourSpinner.findViewById(R.id.numberpicker_input);
+ mHourSpinnerInput = (EditText) mHourSpinner.findViewById(R.id.numberpicker_input);
mHourSpinnerInput.setImeOptions(EditorInfo.IME_ACTION_NEXT);
// divider (only for the new widget style)
- mDivider = mDelegator.findViewById(R.id.divider);
+ mDivider = (TextView) mDelegator.findViewById(R.id.divider);
if (mDivider != null) {
setDividerText();
}
// minute
- mMinuteSpinner = mDelegator.findViewById(R.id.minute);
+ mMinuteSpinner = (NumberPicker) mDelegator.findViewById(R.id.minute);
mMinuteSpinner.setMinValue(0);
mMinuteSpinner.setMaxValue(59);
mMinuteSpinner.setOnLongPressUpdateInterval(100);
@@ -138,7 +138,7 @@
onTimeChanged();
}
});
- mMinuteSpinnerInput = mMinuteSpinner.findViewById(R.id.numberpicker_input);
+ mMinuteSpinnerInput = (EditText) mMinuteSpinner.findViewById(R.id.numberpicker_input);
mMinuteSpinnerInput.setImeOptions(EditorInfo.IME_ACTION_NEXT);
// Get the localized am/pm strings and use them in the spinner.
@@ -173,13 +173,13 @@
onTimeChanged();
}
});
- mAmPmSpinnerInput = mAmPmSpinner.findViewById(R.id.numberpicker_input);
+ mAmPmSpinnerInput = (EditText) mAmPmSpinner.findViewById(R.id.numberpicker_input);
mAmPmSpinnerInput.setImeOptions(EditorInfo.IME_ACTION_DONE);
}
if (isAmPmAtStart()) {
// Move the am/pm view to the beginning
- ViewGroup amPmParent = delegator.findViewById(R.id.timePickerLayout);
+ ViewGroup amPmParent = (ViewGroup) delegator.findViewById(R.id.timePickerLayout);
amPmParent.removeView(amPmView);
amPmParent.addView(amPmView, 0);
// Swap layout margins if needed. They may be not symmetrical (Old Standard Theme
@@ -219,6 +219,11 @@
}
}
+ @Override
+ public boolean validateInput() {
+ return true;
+ }
+
private void getHourFormatData() {
final String bestDateTimePattern = DateFormat.getBestDateTimePattern(mLocale,
(mIs24HourView) ? "Hm" : "hm");
diff --git a/core/java/android/widget/Toast.java b/core/java/android/widget/Toast.java
index bf0601d..789e60b 100644
--- a/core/java/android/widget/Toast.java
+++ b/core/java/android/widget/Toast.java
@@ -299,7 +299,7 @@
if (mNextView == null) {
throw new RuntimeException("This Toast was not created with Toast.makeText()");
}
- TextView tv = mNextView.findViewById(com.android.internal.R.id.message);
+ TextView tv = (TextView) mNextView.findViewById(com.android.internal.R.id.message);
if (tv == null) {
throw new RuntimeException("This Toast was not created with Toast.makeText()");
}
diff --git a/core/java/android/widget/ZoomButtonsController.java b/core/java/android/widget/ZoomButtonsController.java
index 1a3ca86..69b79971 100644
--- a/core/java/android/widget/ZoomButtonsController.java
+++ b/core/java/android/widget/ZoomButtonsController.java
@@ -264,7 +264,7 @@
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(com.android.internal.R.layout.zoom_container, container);
- mControls = container.findViewById(com.android.internal.R.id.zoomControls);
+ mControls = (ZoomControls) container.findViewById(com.android.internal.R.id.zoomControls);
mControls.setOnZoomInClickListener(new OnClickListener() {
public void onClick(View v) {
dismissControlsDelayed(ZOOM_CONTROLS_TIMEOUT);
diff --git a/core/java/com/android/internal/app/procstats/PssTable.java b/core/java/com/android/internal/app/procstats/PssTable.java
index b6df983..de5f673 100644
--- a/core/java/com/android/internal/app/procstats/PssTable.java
+++ b/core/java/com/android/internal/app/procstats/PssTable.java
@@ -96,7 +96,7 @@
}
val = getValue(key, PSS_USS_AVERAGE);
- setValue(key, PSS_AVERAGE,
+ setValue(key, PSS_USS_AVERAGE,
(long)(((val*(double)count)+(avgUss*(double)inCount)) / (count+inCount)));
val = getValue(key, PSS_USS_MAXIMUM);
diff --git a/core/java/com/android/internal/logging/legacy/EventLogCollector.java b/core/java/com/android/internal/logging/legacy/EventLogCollector.java
index 46e70ea..598f0d5 100644
--- a/core/java/com/android/internal/logging/legacy/EventLogCollector.java
+++ b/core/java/com/android/internal/logging/legacy/EventLogCollector.java
@@ -45,8 +45,6 @@
private EventLogCollector() {
mTagParsers = new ArrayMap<>();
- addParser(new LockscreenGestureParser());
- addParser(new StatusBarStateParser());
addParser(new PowerScreenStateParser());
addParser(new SysuiMultiActionParser());
diff --git a/core/java/com/android/internal/logging/legacy/LegacyConversionLogger.java b/core/java/com/android/internal/logging/legacy/LegacyConversionLogger.java
index 91e968b..1209e4d 100644
--- a/core/java/com/android/internal/logging/legacy/LegacyConversionLogger.java
+++ b/core/java/com/android/internal/logging/legacy/LegacyConversionLogger.java
@@ -24,14 +24,6 @@
/** @hide */
public class LegacyConversionLogger implements TronLogger {
- public static final String VIEW_KEY = "view";
- public static final String TYPE_KEY = "type";
- public static final String EVENT_KEY = "data";
-
- public static final int TYPE_COUNTER = 1;
- public static final int TYPE_HISTOGRAM = 2;
- public static final int TYPE_EVENT = 3;
-
private final Queue<LogMaker> mQueue;
private HashMap<String, Boolean> mConfig;
diff --git a/core/java/com/android/internal/logging/legacy/LockscreenGestureParser.java b/core/java/com/android/internal/logging/legacy/LockscreenGestureParser.java
deleted file mode 100644
index df08ee0..0000000
--- a/core/java/com/android/internal/logging/legacy/LockscreenGestureParser.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.internal.logging.legacy;
-
-import android.util.Log;
-
-import android.metrics.LogMaker;
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-
-/**
- * Parse the Android lockscreen gesture logs.
- * @hide
- */
-public class LockscreenGestureParser extends TagParser {
- private static final String TAG = "LockscreenGestureParser";
- private static final int EVENTLOG_TAG = 36021;
-
- // source of truth is com.android.systemui.EventLogConstants
- public static final int[] GESTURE_TYPE_MAP = {
- MetricsEvent.VIEW_UNKNOWN, // there is no type 0
- MetricsEvent.ACTION_LS_UNLOCK, // SYSUI_LOCKSCREEN_GESTURE_SWIPE_UP_UNLOCK = 1
- MetricsEvent.ACTION_LS_SHADE, // SYSUI_LOCKSCREEN_GESTURE_SWIPE_DOWN_FULL_SHADE = 2
- MetricsEvent.ACTION_LS_HINT, // SYSUI_LOCKSCREEN_GESTURE_TAP_UNLOCK_HINT = 3
- MetricsEvent.ACTION_LS_CAMERA, // SYSUI_LOCKSCREEN_GESTURE_SWIPE_CAMERA = 4
- MetricsEvent.ACTION_LS_DIALER, // SYSUI_LOCKSCREEN_GESTURE_SWIPE_DIALER = 5
- MetricsEvent.ACTION_LS_LOCK, // SYSUI_LOCKSCREEN_GESTURE_TAP_LOCK = 6
- MetricsEvent.ACTION_LS_NOTE, // SYSUI_LOCKSCREEN_GESTURE_TAP_NOTIFICATION_ACTIVATE = 7
- MetricsEvent.ACTION_LS_QS, // SYSUI_LOCKSCREEN_GESTURE_SWIPE_DOWN_QS = 8
- MetricsEvent.ACTION_SHADE_QS_PULL, // SYSUI_SHADE_GESTURE_SWIPE_DOWN_QS = 9
- MetricsEvent.ACTION_SHADE_QS_TAP // SYSUI_TAP_TO_OPEN_QS = 10
- };
-
- @Override
- public int getTag() {
- return EVENTLOG_TAG;
- }
-
- @Override
- public void parseEvent(TronLogger logger, long eventTimeMs, Object[] operands) {
- final boolean debug = Util.debug();
- if (operands.length >= 1) {
- try {
- int type = ((Integer) operands[0]).intValue();
- // ignore gesture length in operands[1]
- // ignore gesture velocity in operands[2]
-
- int category = MetricsEvent.VIEW_UNKNOWN;
- if (type < GESTURE_TYPE_MAP.length) {
- category = GESTURE_TYPE_MAP[type];
- }
- if (category != MetricsEvent.VIEW_UNKNOWN) {
- LogMaker proto = logger.obtain();
- proto.setCategory(category);
- proto.setType(MetricsEvent.TYPE_ACTION);
- proto.setTimestamp(eventTimeMs);
- logger.addEvent(proto);
- }
- } catch (ClassCastException e) {
- if (debug) {
- Log.e(TAG, "unexpected operand type: ", e);
- }
- }
- } else if (debug) {
- Log.w(TAG, "wrong number of operands: " + operands.length);
- }
- }
-}
diff --git a/core/java/com/android/internal/logging/legacy/StatusBarStateParser.java b/core/java/com/android/internal/logging/legacy/StatusBarStateParser.java
deleted file mode 100644
index 226253f..0000000
--- a/core/java/com/android/internal/logging/legacy/StatusBarStateParser.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.internal.logging.legacy;
-
-import android.util.Log;
-
-import android.metrics.LogMaker;
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-
-/**
- * Parse the Android lockscreen gesture logs.
- * @hide
- */
-public class StatusBarStateParser extends TagParser {
- private static final String TAG = "StatusBarStateParser";
- private static final int EVENTLOG_TAG = 36004;
-
- // source of truth is com.android.systemui.statusbar.StatusBarState
- public static final int SHADE = 0;
- public static final int KEYGUARD = 1;
- public static final int SHADE_LOCKED = 2;
-
- @Override
- public int getTag() {
- return EVENTLOG_TAG;
- }
-
- @Override
- public void parseEvent(TronLogger logger, long eventTimeMs, Object[] operands) {
- final boolean debug = Util.debug();
- if (operands.length >= 6) {
- try {
- // [state, isShowing, isOccluded, isBouncerShowing, isSecure, isCurrentlyInsecure]
- int state = ((Integer) operands[0]).intValue();
- boolean isBouncerShowing = (((Integer) operands[3]).intValue()) == 1;
- int isSecure = ((Integer) operands[4]).intValue();
-
- int view = MetricsEvent.LOCKSCREEN;
- int type = MetricsEvent.TYPE_OPEN;
- if (state == SHADE) {
- type = MetricsEvent.TYPE_CLOSE;
- } else if (isBouncerShowing) {
- view = MetricsEvent.BOUNCER;
- }
-
- LogMaker proto = logger.obtain();
- proto.setCategory(view);
- proto.setType(type);
- proto.setTimestamp(eventTimeMs);
- proto.setSubtype(isSecure);
- logger.addEvent(proto);
- } catch (ClassCastException e) {
- if (debug) {
- Log.e(TAG, "unexpected operand type: ", e);
- }
- }
- } else if (debug) {
- Log.w(TAG, "wrong number of operands: " + operands.length);
- }
- }
-}
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index c34c379..63622f1 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -377,6 +377,8 @@
int mScreenBrightnessBin = -1;
final StopwatchTimer[] mScreenBrightnessTimer = new StopwatchTimer[NUM_SCREEN_BRIGHTNESS_BINS];
+ boolean mPretendScreenOff;
+
boolean mInteractive;
StopwatchTimer mInteractiveTimer;
@@ -3395,6 +3397,11 @@
mNoAutoReset = enabled;
}
+ public void setPretendScreenOff(boolean pretendScreenOff) {
+ mPretendScreenOff = pretendScreenOff;
+ noteScreenStateLocked(pretendScreenOff ? Display.STATE_OFF : Display.STATE_ON);
+ }
+
private String mInitialAcquireWakeName;
private int mInitialAcquireWakeUid = -1;
@@ -3698,6 +3705,7 @@
}
public void noteScreenStateLocked(int state) {
+ state = mPretendScreenOff ? Display.STATE_OFF : state;
if (mScreenState != state) {
recordDailyStatsIfNeededLocked(true);
final int oldState = mScreenState;
@@ -9711,7 +9719,7 @@
}
doWrite = true;
resetAllStatsLocked();
- if (chargeUAh > 0) {
+ if (chargeUAh > 0 && level > 0) {
// Only use the reported coulomb charge value if it is supported and reported.
mEstimatedBatteryCapacity = (int) ((chargeUAh / 1000) / (level / 100.0));
}
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index a3b066a..5049738 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -28,6 +28,7 @@
import android.os.IInstalld;
import android.os.Process;
import android.os.RemoteException;
+import android.os.Seccomp;
import android.os.ServiceManager;
import android.os.ServiceSpecificException;
import android.os.SystemClock;
@@ -712,6 +713,9 @@
// Zygote process unmounts root storage spaces.
Zygote.nativeUnmountStorageOnInit();
+ // Set seccomp policy
+ Seccomp.setPolicy();
+
ZygoteHooks.stopZygoteNoThreadCreation();
if (startSystemServer) {
diff --git a/core/java/com/android/internal/statusbar/IStatusBar.aidl b/core/java/com/android/internal/statusbar/IStatusBar.aidl
index 20f10b3..9cbbc5a 100644
--- a/core/java/com/android/internal/statusbar/IStatusBar.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBar.aidl
@@ -53,9 +53,6 @@
void setImeWindowStatus(in IBinder token, int vis, int backDisposition,
boolean showImeSwitcher);
void setWindowState(int window, int state);
- void buzzBeepBlinked();
- void notificationLightOff();
- void notificationLightPulse(int argb, int millisOn, int millisOff);
void showRecentApps(boolean triggeredFromAltTab, boolean fromHome);
void hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHomeKey);
diff --git a/core/java/com/android/internal/util/ArrayUtils.java b/core/java/com/android/internal/util/ArrayUtils.java
index a9a6364..cb3a250 100644
--- a/core/java/com/android/internal/util/ArrayUtils.java
+++ b/core/java/com/android/internal/util/ArrayUtils.java
@@ -435,10 +435,6 @@
}
}
- public static <T> boolean contains(@Nullable ArraySet<T> cur, T val) {
- return (cur != null) ? cur.contains(val) : false;
- }
-
public static @NonNull <T> ArrayList<T> add(@Nullable ArrayList<T> cur, T val) {
if (cur == null) {
cur = new ArrayList<>();
@@ -459,6 +455,16 @@
}
}
+ /**
+ * Returns the given list, or an immutable empty list if the provided list is null
+ *
+ * @see Collections#emptyList
+ */
+
+ public static @NonNull <T> List<T> emptyIfNull(@Nullable List<T> cur) {
+ return cur == null ? Collections.emptyList() : cur;
+ }
+
public static <T> boolean contains(@Nullable Collection<T> cur, T val) {
return (cur != null) ? cur.contains(val) : false;
}
diff --git a/core/java/com/android/internal/util/NotificationMessagingUtil.java b/core/java/com/android/internal/util/NotificationMessagingUtil.java
new file mode 100644
index 0000000..518cf41
--- /dev/null
+++ b/core/java/com/android/internal/util/NotificationMessagingUtil.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.internal.util;
+
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.content.Context;
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.service.notification.StatusBarNotification;
+import android.text.TextUtils;
+import android.util.ArrayMap;
+
+import java.util.Objects;
+
+/**
+ * A util to look up messaging related functions for notifications. This is used for both the
+ * ranking and the actual layout.
+ */
+public class NotificationMessagingUtil {
+
+ private static final String DEFAULT_SMS_APP_SETTING = Settings.Secure.SMS_DEFAULT_APPLICATION;
+ private final Context mContext;
+ private ArrayMap<Integer, String> mDefaultSmsApp = new ArrayMap<>();
+
+ public NotificationMessagingUtil(Context context) {
+ mContext = context;
+ mContext.getContentResolver().registerContentObserver(
+ Settings.Secure.getUriFor(DEFAULT_SMS_APP_SETTING), false, mSmsContentObserver);
+ }
+
+ @SuppressWarnings("deprecation")
+ private boolean isDefaultMessagingApp(StatusBarNotification sbn) {
+ final int userId = sbn.getUserId();
+ if (userId == UserHandle.USER_NULL || userId == UserHandle.USER_ALL) return false;
+ if (mDefaultSmsApp.get(userId) == null) {
+ cacheDefaultSmsApp(userId);
+ }
+ return Objects.equals(mDefaultSmsApp.get(userId), sbn.getPackageName());
+ }
+
+ private void cacheDefaultSmsApp(int userId) {
+ mDefaultSmsApp.put(userId, Settings.Secure.getStringForUser(
+ mContext.getContentResolver(),
+ Settings.Secure.SMS_DEFAULT_APPLICATION, userId));
+ }
+
+ private final ContentObserver mSmsContentObserver = new ContentObserver(
+ new Handler(Looper.getMainLooper())) {
+ @Override
+ public void onChange(boolean selfChange, Uri uri, int userId) {
+ if (Settings.Secure.getUriFor(DEFAULT_SMS_APP_SETTING).equals(uri)) {
+ cacheDefaultSmsApp(userId);
+ }
+ }
+ };
+
+ public boolean isImportantMessaging(StatusBarNotification sbn, int importance) {
+ if (importance < NotificationManager.IMPORTANCE_LOW) {
+ return false;
+ }
+
+ Class<? extends Notification.Style> style = sbn.getNotification().getNotificationStyle();
+ if (Notification.MessagingStyle.class.equals(style)) {
+ return true;
+ }
+
+ if (Notification.CATEGORY_MESSAGE.equals(sbn.getNotification().category)
+ && isDefaultMessagingApp(sbn)) {
+ return true;
+ }
+
+ return false;
+ }
+}
diff --git a/core/java/android/service/autofill/CallbackHelper.java b/core/java/com/android/internal/util/ObjectUtils.java
similarity index 65%
copy from core/java/android/service/autofill/CallbackHelper.java
copy to core/java/com/android/internal/util/ObjectUtils.java
index ded8f97..d109a5a 100644
--- a/core/java/android/service/autofill/CallbackHelper.java
+++ b/core/java/com/android/internal/util/ObjectUtils.java
@@ -13,18 +13,19 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package android.service.autofill;
-import java.io.PrintWriter;
-final class CallbackHelper {
+package com.android.internal.util;
- static interface Dumpable {
- void dump(String prefix, PrintWriter pw);
- void setFinalizer(Finalizer f);
- }
+import android.annotation.NonNull;
+import android.annotation.Nullable;
- static interface Finalizer {
- void gone();
+/** @hide */
+public class ObjectUtils {
+ private ObjectUtils() {}
+
+ @NonNull
+ public static <T> T firstNotNull(@Nullable T a, @NonNull T b) {
+ return a != null ? a : Preconditions.checkNotNull(b);
}
}
diff --git a/core/java/com/android/internal/widget/DrawingSpace.java b/core/java/com/android/internal/widget/DrawingSpace.java
deleted file mode 100644
index b8222db..0000000
--- a/core/java/com/android/internal/widget/DrawingSpace.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.widget;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.View;
-
-/**
- * Implementation of {@link android.widget.Space} that uses normal View drawing
- * rather than a no-op. Useful for dialogs and other places where the base View
- * class is too greedy when measured with AT_MOST.
- */
-public final class DrawingSpace extends View {
- public DrawingSpace(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
- super(context, attrs, defStyleAttr, defStyleRes);
- }
-
- public DrawingSpace(Context context, AttributeSet attrs, int defStyleAttr) {
- this(context, attrs, defStyleAttr, 0);
- }
-
- public DrawingSpace(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
- }
-
- public DrawingSpace(Context context) {
- this(context, null);
- }
-
- /**
- * Compare to: {@link View#getDefaultSize(int, int)}
- * <p>
- * If mode is AT_MOST, return the child size instead of the parent size
- * (unless it is too big).
- */
- private static int getDefaultSizeNonGreedy(int size, int measureSpec) {
- int result = size;
- int specMode = MeasureSpec.getMode(measureSpec);
- int specSize = MeasureSpec.getSize(measureSpec);
-
- switch (specMode) {
- case MeasureSpec.UNSPECIFIED:
- result = size;
- break;
- case MeasureSpec.AT_MOST:
- result = Math.min(size, specSize);
- break;
- case MeasureSpec.EXACTLY:
- result = specSize;
- break;
- }
- return result;
- }
-
- @Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- setMeasuredDimension(
- getDefaultSizeNonGreedy(getSuggestedMinimumWidth(), widthMeasureSpec),
- getDefaultSizeNonGreedy(getSuggestedMinimumHeight(), heightMeasureSpec));
- }
-}
diff --git a/core/java/com/android/internal/widget/WatchHeaderListView.java b/core/java/com/android/internal/widget/WatchHeaderListView.java
index 53fa7ab..4fd19c3 100644
--- a/core/java/com/android/internal/widget/WatchHeaderListView.java
+++ b/core/java/com/android/internal/widget/WatchHeaderListView.java
@@ -92,14 +92,13 @@
}
@Override
- protected <T extends View> T findViewByPredicateTraversal(
- Predicate<View> predicate, View childToSkip) {
+ protected View findViewByPredicateTraversal(Predicate<View> predicate, View childToSkip) {
View v = super.findViewByPredicateTraversal(predicate, childToSkip);
if (v == null && mTopPanel != null && mTopPanel != childToSkip
&& !mTopPanel.isRootNamespace()) {
- return (T) mTopPanel.findViewByPredicate(predicate);
+ return mTopPanel.findViewByPredicate(predicate);
}
- return (T) v;
+ return v;
}
@Override
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index cf9441b..db3ea8c 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -91,6 +91,7 @@
android_os_MessageQueue.cpp \
android_os_Parcel.cpp \
android_os_SELinux.cpp \
+ android_os_seccomp.cpp \
android_os_SystemClock.cpp \
android_os_SystemProperties.cpp \
android_os_Trace.cpp \
@@ -230,6 +231,7 @@
LOCAL_STATIC_LIBRARIES := \
libgif \
+ libseccomp_policy \
LOCAL_SHARED_LIBRARIES := \
libmemtrack \
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 340f2ee..407e69c 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -159,6 +159,7 @@
extern int register_android_os_MessageQueue(JNIEnv* env);
extern int register_android_os_Parcel(JNIEnv* env);
extern int register_android_os_SELinux(JNIEnv* env);
+extern int register_android_os_seccomp(JNIEnv* env);
extern int register_android_os_SystemProperties(JNIEnv *env);
extern int register_android_os_SystemClock(JNIEnv* env);
extern int register_android_os_Trace(JNIEnv* env);
@@ -1360,6 +1361,7 @@
REG_JNI(register_android_os_GraphicsEnvironment),
REG_JNI(register_android_os_MessageQueue),
REG_JNI(register_android_os_SELinux),
+ REG_JNI(register_android_os_seccomp),
REG_JNI(register_android_os_Trace),
REG_JNI(register_android_os_UEventObserver),
REG_JNI(register_android_net_LocalSocketImpl),
diff --git a/core/jni/android_os_HwBlob.cpp b/core/jni/android_os_HwBlob.cpp
index b2dee06..8590ecf 100644
--- a/core/jni/android_os_HwBlob.cpp
+++ b/core/jni/android_os_HwBlob.cpp
@@ -382,7 +382,7 @@
s = nullptr;
hidl_string tmp;
- tmp.setToExternal(static_cast<const char *>(subBlob->data()), size);
+ tmp.setToExternal(static_cast<const char *>(subBlob->data()), size - 1);
sp<JHwBlob> blob = JHwBlob::GetNativeContext(env, thiz);
blob->write(offset, &tmp, sizeof(tmp));
diff --git a/core/jni/android_os_seccomp.cpp b/core/jni/android_os_seccomp.cpp
new file mode 100644
index 0000000..3f7bab2
--- /dev/null
+++ b/core/jni/android_os_seccomp.cpp
@@ -0,0 +1,245 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "JNIHelp.h"
+#include "core_jni_helpers.h"
+#include "JniConstants.h"
+#include "utils/Log.h"
+#include "utils/misc.h"
+
+#if defined __arm__ || defined __aarch64__
+
+#include <vector>
+
+#include <sys/prctl.h>
+
+#include <linux/unistd.h>
+#include <linux/audit.h>
+#include <linux/filter.h>
+#include <linux/seccomp.h>
+
+#include "seccomp_policy.h"
+
+#define syscall_nr (offsetof(struct seccomp_data, nr))
+#define arch_nr (offsetof(struct seccomp_data, arch))
+
+typedef std::vector<sock_filter> filter;
+
+// We want to keep the below inline functions for debugging and future
+// development even though they are not all sed currently.
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wunused-function"
+
+static inline void Kill(filter& f) {
+ f.push_back(BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_KILL));
+}
+
+static inline void Trap(filter& f) {
+ f.push_back(BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_TRAP));
+}
+
+static inline void Error(filter& f, __u16 retcode) {
+ f.push_back(BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ERRNO + retcode));
+}
+
+inline static void Trace(filter& f) {
+ f.push_back(BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_TRACE));
+}
+
+inline static void Allow(filter& f) {
+ f.push_back(BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW));
+}
+
+#pragma clang diagnostic pop
+
+inline static void AllowSyscall(filter& f, __u32 num) {
+ f.push_back(BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, num, 0, 1));
+ Allow(f);
+}
+
+inline static void ExamineSyscall(filter& f) {
+ f.push_back(BPF_STMT(BPF_LD|BPF_W|BPF_ABS, syscall_nr));
+}
+
+inline static int SetValidateArchitectureJumpTarget(size_t offset, filter& f) {
+ size_t jump_length = f.size() - offset - 1;
+ auto u8_jump_length = (__u8) jump_length;
+ if (u8_jump_length != jump_length) {
+ ALOGE("Can't set jump greater than 255 - actual jump is %zu",
+ jump_length);
+ return -1;
+ }
+ f[offset] = BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, AUDIT_ARCH_ARM, u8_jump_length, 0);
+ return 0;
+}
+
+inline static size_t ValidateArchitectureAndJumpIfNeeded(filter& f) {
+ f.push_back(BPF_STMT(BPF_LD|BPF_W|BPF_ABS, arch_nr));
+
+ f.push_back(BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, AUDIT_ARCH_AARCH64, 2, 0));
+ f.push_back(BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, AUDIT_ARCH_ARM, 1, 0));
+ Trap(f);
+ return f.size() - 2;
+}
+
+static bool install_filter(filter const& f) {
+ struct sock_fprog prog = {
+ (unsigned short) f.size(),
+ (struct sock_filter*) &f[0],
+ };
+
+ if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog) < 0) {
+ ALOGE("SECCOMP: Could not set seccomp filter of size %zu: %s", f.size(), strerror(errno));
+ return false;
+ }
+
+ ALOGI("SECCOMP: Global filter of size %zu installed", f.size());
+ return true;
+}
+
+bool set_seccomp_filter() {
+ filter f;
+
+ // Note that for mixed 64/32 bit architectures, ValidateArchitecture inserts a
+ // jump that must be changed to point to the start of the 32-bit policy
+ // 32 bit syscalls will not hit the policy between here and the call to SetJump
+ auto offset_to_32bit_filter =
+ ValidateArchitectureAndJumpIfNeeded(f);
+
+ // 64-bit filter
+ ExamineSyscall(f);
+
+ // arm64-only filter - autogenerated from bionic syscall usage
+ for (size_t i = 0; i < arm64_filter_size; ++i)
+ f.push_back(arm64_filter[i]);
+
+ // Syscalls needed to boot Android
+ AllowSyscall(f, 41); // __NR_pivot_root
+ AllowSyscall(f, 31); // __NR_ioprio_get
+ AllowSyscall(f, 30); // __NR_ioprio_set
+ AllowSyscall(f, 178); // __NR_gettid
+ AllowSyscall(f, 98); // __NR_futex
+ AllowSyscall(f, 220); // __NR_clone
+ AllowSyscall(f, 139); // __NR_rt_sigreturn
+ AllowSyscall(f, 240); // __NR_rt_tgsigqueueinfo
+ AllowSyscall(f, 128); // __NR_restart_syscall
+ AllowSyscall(f, 278); // __NR_getrandom
+
+ // Needed for performance tools
+ AllowSyscall(f, 241); // __NR_perf_event_open
+
+ // Needed for strace
+ AllowSyscall(f, 130); // __NR_tkill
+
+ // Needed for kernel to restart syscalls
+ AllowSyscall(f, 128); // __NR_restart_syscall
+
+ // b/35034743
+ AllowSyscall(f, 267); // __NR_fstatfs64
+
+ Trap(f);
+
+ if (SetValidateArchitectureJumpTarget(offset_to_32bit_filter, f) != 0)
+ return -1;
+
+ // 32-bit filter
+ ExamineSyscall(f);
+
+ // arm32 filter - autogenerated from bionic syscall usage
+ for (size_t i = 0; i < arm_filter_size; ++i)
+ f.push_back(arm_filter[i]);
+
+ // Syscalls needed to boot android
+ AllowSyscall(f, 120); // __NR_clone
+ AllowSyscall(f, 240); // __NR_futex
+ AllowSyscall(f, 119); // __NR_sigreturn
+ AllowSyscall(f, 173); // __NR_rt_sigreturn
+ AllowSyscall(f, 363); // __NR_rt_tgsigqueueinfo
+ AllowSyscall(f, 224); // __NR_gettid
+
+ // Syscalls needed to run Chrome
+ AllowSyscall(f, 383); // __NR_seccomp - needed to start Chrome
+ AllowSyscall(f, 384); // __NR_getrandom - needed to start Chrome
+
+ // Syscalls needed to run GFXBenchmark
+ AllowSyscall(f, 190); // __NR_vfork
+
+ // Needed for strace
+ AllowSyscall(f, 238); // __NR_tkill
+
+ // Needed for kernel to restart syscalls
+ AllowSyscall(f, 0); // __NR_restart_syscall
+
+ // Needed for debugging 32-bit Chrome
+ AllowSyscall(f, 42); // __NR_pipe
+
+ // b/34732712
+ AllowSyscall(f, 364); // __NR_perf_event_open
+
+ // b/34651972
+ AllowSyscall(f, 33); // __NR_access
+ AllowSyscall(f, 195); // __NR_stat64
+
+ // b/34813887
+ AllowSyscall(f, 5); // __NR_open
+ AllowSyscall(f, 141); // __NR_getdents
+ AllowSyscall(f, 217); // __NR_getdents64
+
+ // b/34719286
+ AllowSyscall(f, 351); // __NR_eventfd
+
+ // b/34817266
+ AllowSyscall(f, 252); // __NR_epoll_wait
+
+ // Needed by sanitizers (b/34606909)
+ // 5 (__NR_open) and 195 (__NR_stat64) are also required, but they are
+ // already allowed.
+ AllowSyscall(f, 85); // __NR_readlink
+
+ // b/34908783
+ AllowSyscall(f, 250); // __NR_epoll_create
+
+ Trap(f);
+
+ return install_filter(f);
+}
+
+static void Seccomp_setPolicy(JNIEnv* /*env*/) {
+ if (!set_seccomp_filter()) {
+ ALOGE("Failed to set seccomp policy - killing");
+ exit(1);
+ }
+}
+
+#else // #if defined __arm__ || defined __aarch64__
+
+static void Seccomp_setPolicy(JNIEnv* /*env*/) {
+}
+
+#endif
+
+static const JNINativeMethod method_table[] = {
+ NATIVE_METHOD(Seccomp, setPolicy, "()V"),
+};
+
+namespace android {
+
+int register_android_os_seccomp(JNIEnv* env) {
+ return android::RegisterMethodsOrDie(env, "android/os/Seccomp",
+ method_table, NELEM(method_table));
+}
+
+}
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index 5c65241..e2fc444 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -247,24 +247,42 @@
static void DropCapabilitiesBoundingSet(JNIEnv* env) {
for (int i = 0; prctl(PR_CAPBSET_READ, i, 0, 0, 0) >= 0; i++) {
- // Keep CAP_SYS_PTRACE in our bounding set so crash_dump can gain it.
- if (i == CAP_SYS_PTRACE) {
- continue;
- }
-
int rc = prctl(PR_CAPBSET_DROP, i, 0, 0, 0);
if (rc == -1) {
if (errno == EINVAL) {
ALOGE("prctl(PR_CAPBSET_DROP) failed with EINVAL. Please verify "
"your kernel is compiled with file capabilities support");
} else {
+ ALOGE("prctl(PR_CAPBSET_DROP, %d) failed: %s", i, strerror(errno));
RuntimeAbort(env, __LINE__, "prctl(PR_CAPBSET_DROP) failed");
}
}
}
}
-static void SetCapabilities(JNIEnv* env, int64_t permitted, int64_t effective) {
+static void SetInheritable(JNIEnv* env, uint64_t inheritable) {
+ __user_cap_header_struct capheader;
+ memset(&capheader, 0, sizeof(capheader));
+ capheader.version = _LINUX_CAPABILITY_VERSION_3;
+ capheader.pid = 0;
+
+ __user_cap_data_struct capdata[2];
+ if (capget(&capheader, &capdata[0]) == -1) {
+ ALOGE("capget failed: %s", strerror(errno));
+ RuntimeAbort(env, __LINE__, "capget failed");
+ }
+
+ capdata[0].inheritable = inheritable;
+ capdata[1].inheritable = inheritable >> 32;
+
+ if (capset(&capheader, &capdata[0]) == -1) {
+ ALOGE("capset(inh=%" PRIx64 ") failed: %s", inheritable, strerror(errno));
+ RuntimeAbort(env, __LINE__, "capset failed");
+ }
+}
+
+static void SetCapabilities(JNIEnv* env, uint64_t permitted, uint64_t effective,
+ uint64_t inheritable) {
__user_cap_header_struct capheader;
memset(&capheader, 0, sizeof(capheader));
capheader.version = _LINUX_CAPABILITY_VERSION_3;
@@ -276,9 +294,12 @@
capdata[1].effective = effective >> 32;
capdata[0].permitted = permitted;
capdata[1].permitted = permitted >> 32;
+ capdata[0].inheritable = inheritable;
+ capdata[1].inheritable = inheritable >> 32;
if (capset(&capheader, &capdata[0]) == -1) {
- ALOGE("capset(%" PRId64 ", %" PRId64 ") failed", permitted, effective);
+ ALOGE("capset(perm=%" PRIx64 ", eff=%" PRIx64 ", inh=%" PRIx64 ") failed: %s", permitted,
+ effective, inheritable, strerror(errno));
RuntimeAbort(env, __LINE__, "capset failed");
}
}
@@ -532,6 +553,7 @@
EnableKeepCapabilities(env);
}
+ SetInheritable(env, permittedCapabilities);
DropCapabilitiesBoundingSet(env);
bool use_native_bridge = !is_system_server && (instructionSet != NULL)
@@ -604,7 +626,7 @@
}
}
- SetCapabilities(env, permittedCapabilities, effectiveCapabilities);
+ SetCapabilities(env, permittedCapabilities, effectiveCapabilities, permittedCapabilities);
SetSchedulerPolicy(env);
diff --git a/core/proto/android/service/battery.proto b/core/proto/android/service/battery.proto
new file mode 100644
index 0000000..33ad682b
--- /dev/null
+++ b/core/proto/android/service/battery.proto
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto3";
+
+package android.service.battery;
+
+option java_multiple_files = true;
+option java_outer_classname = "BatteryServiceProto";
+
+message BatteryServiceDumpProto {
+ enum BatteryPlugged {
+ BATTERY_PLUGGED_NONE = 0;
+ BATTERY_PLUGGED_AC = 1;
+ BATTERY_PLUGGED_USB = 2;
+ BATTERY_PLUGGED_WIRELESS = 4;
+ }
+ enum BatteryStatus {
+ BATTERY_STATUS_INVALID = 0;
+ BATTERY_STATUS_UNKNOWN = 1;
+ BATTERY_STATUS_CHARGING = 2;
+ BATTERY_STATUS_DISCHARGING = 3;
+ BATTERY_STATUS_NOT_CHARGING = 4;
+ BATTERY_STATUS_FULL = 5;
+ }
+ enum BatteryHealth {
+ BATTERY_HEALTH_INVALID = 0;
+ BATTERY_HEALTH_UNKNOWN = 1;
+ BATTERY_HEALTH_GOOD = 2;
+ BATTERY_HEALTH_OVERHEAT = 3;
+ BATTERY_HEALTH_DEAD = 4;
+ BATTERY_HEALTH_OVER_VOLTAGE = 5;
+ BATTERY_HEALTH_UNSPECIFIED_FAILURE = 6;
+ BATTERY_HEALTH_COLD = 7;
+ }
+
+ // If true: UPDATES STOPPED -- use 'reset' to restart
+ bool are_updates_stopped = 1;
+ // Plugged status of power sources
+ BatteryPlugged plugged = 2;
+ // Max current in microamperes
+ int32 max_charging_current = 3;
+ // Max voltage
+ int32 max_charging_voltage = 4;
+ // Battery capacity in microampere-hours
+ int32 charge_counter = 5;
+ // Charging status
+ BatteryStatus status = 6;
+ // Battery health
+ BatteryHealth health = 7;
+ // True if the battery is present
+ bool is_present = 8;
+ // Charge level, from 0 through "scale" inclusive
+ int32 level = 9;
+ // The maximum value for the charge level
+ int32 scale = 10;
+ // Battery voltage in millivolts
+ int32 voltage = 11;
+ // Battery temperature in tenths of a degree Centigrade
+ int32 temperature = 12;
+ // The type of battery installed, e.g. "Li-ion"
+ string technology = 13;
+}
diff --git a/core/proto/android/service/netstats.proto b/core/proto/android/service/netstats.proto
index 5cca6ab..5a577b1 100644
--- a/core/proto/android/service/netstats.proto
+++ b/core/proto/android/service/netstats.proto
@@ -27,12 +27,16 @@
repeated NetworkInterfaceProto active_uid_interfaces = 2;
+ // Device level network stats, which may include non-IP layer traffic.
NetworkStatsRecorderProto dev_stats = 3;
+ // IP-layer traffic stats.
NetworkStatsRecorderProto xt_stats = 4;
+ // Per-UID network stats.
NetworkStatsRecorderProto uid_stats = 5;
+ // Per-UID, per-tag network stats, excluding the default tag (i.e. tag=0).
NetworkStatsRecorderProto uid_tag_stats = 6;
}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 11eb47b..a6e43ff 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -2365,6 +2365,11 @@
<permission android:name="android.permission.BIND_PRINT_SPOOLER_SERVICE"
android:protectionLevel="signature" />
+ <!-- Must be required by the CompanionDeviceManager to ensure that only the system can bind to it.
+ @hide -->
+ <permission android:name="android.permission.BIND_COMPANION_DEVICE_MANAGER_SERVICE"
+ android:protectionLevel="signature" />
+
<!-- @SystemApi Must be required by the RuntimePermissionPresenterService to ensure
that only the system can bind to it.
@hide -->
diff --git a/core/res/res/drawable/btn_event_material.xml b/core/res/res/drawable/btn_event_material.xml
new file mode 100644
index 0000000..47c49cf
--- /dev/null
+++ b/core/res/res/drawable/btn_event_material.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:fillColor="#90ffffff"
+ android:pathData="M17 12h-5v5h5v-5zM16 1v2H8V1H6v2H5c-1.11 0-1.99 .9 -1.99 2L3 19c0 1.1 .89 2 2
+2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2h-1V1h-2zm3 18H5V8h14v11z" />
+ <path android:pathData="M0 0h24v24H0z" />
+</vector>
\ No newline at end of file
diff --git a/core/res/res/drawable/btn_keyboard_key_material.xml b/core/res/res/drawable/btn_keyboard_key_material.xml
new file mode 100644
index 0000000..14a9492f
--- /dev/null
+++ b/core/res/res/drawable/btn_keyboard_key_material.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:fillColor="#90ffffff"
+ android:pathData="M20 5H4c-1.1 0-1.99 .9 -1.99 2L2 17c0 1.1 .9 2 2 2h16c1.1 0 2-.9
+2-2V7c0-1.1-.9-2-2-2zm-9 3h2v2h-2V8zm0 3h2v2h-2v-2zM8 8h2v2H8V8zm0
+3h2v2H8v-2zm-1 2H5v-2h2v2zm0-3H5V8h2v2zm9
+7H8v-2h8v2zm0-4h-2v-2h2v2zm0-3h-2V8h2v2zm3 3h-2v-2h2v2zm0-3h-2V8h2v2z" />
+ <path
+ android:pathData="M0 0h24v24H0zm0 0h24v24H0z" />
+</vector>
\ No newline at end of file
diff --git a/core/res/res/layout-land/time_picker_material.xml b/core/res/res/layout-land/time_picker_material.xml
index 70833d6..8b95f9f 100644
--- a/core/res/res/layout-land/time_picker_material.xml
+++ b/core/res/res/layout-land/time_picker_material.xml
@@ -15,28 +15,17 @@
limitations under the License.
-->
-<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layoutDirection="ltr">
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
- <!-- Provides a background for the time layout that extends into the button bar area. -->
- <com.android.internal.widget.DrawingSpace
+ <LinearLayout
android:id="@+id/time_header"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_column="@dimen/time_picker_column_start_material"
- android:layout_row="0"
- android:layout_rowSpan="3"
- android:layout_gravity="center|fill"
- android:layoutDirection="locale" />
-
- <RelativeLayout
android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_column="@dimen/time_picker_column_start_material"
- android:layout_row="1"
- android:layout_gravity="center|fill"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:gravity="center"
android:paddingStart="?attr/dialogPreferredPadding"
android:paddingEnd="?attr/dialogPreferredPadding">
@@ -44,10 +33,8 @@
android:id="@+id/time_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:orientation="horizontal"
- android:layout_centerInParent="true"
android:paddingTop="@dimen/timepicker_radial_picker_top_margin"
- android:layout_marginBottom="-12dp">
+ android:orientation="horizontal">
<!-- The hour should always be to the left of the separator,
regardless of the current locale's layout direction. -->
@@ -125,38 +112,71 @@
android:includeFontPadding="false"
android:button="@null" />
</RadioGroup>
- </RelativeLayout>
+ </LinearLayout>
- <ViewStub
- android:id="@id/topPanel"
- android:layout="@layout/alert_dialog_title_material"
+ <TextView
+ android:visibility="gone"
+ android:id="@+id/input_header"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:gravity="center"
+ android:paddingStart="@dimen/dialog_padding_material"
+ android:paddingEnd="@dimen/dialog_padding_material"
+ android:paddingTop="20dp"
+ android:paddingBottom="20dp"
+ android:includeFontPadding="false"
+ android:textAppearance="@style/TextAppearance.Material.TimePicker.InputHeader"
+ android:text="@string/time_picker_header_text"/>
+
+ <LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_column="@dimen/time_picker_column_end_material"
- android:layout_row="0"
- android:layout_gravity="top|fill_horizontal"
- android:layoutDirection="locale" />
+ android:orientation="vertical">
- <android.widget.RadialTimePickerView
- android:id="@+id/radial_picker"
- android:layout_width="@dimen/timepicker_radial_picker_dimen"
- android:layout_height="@dimen/timepicker_radial_picker_dimen"
- android:layout_column="@dimen/time_picker_column_end_material"
- android:layout_row="1"
- android:layout_rowWeight="1"
- android:layout_gravity="center|fill"
- android:layout_marginTop="@dimen/timepicker_radial_picker_top_margin"
- android:layout_marginStart="@dimen/timepicker_radial_picker_horizontal_margin"
- android:layout_marginEnd="@dimen/timepicker_radial_picker_horizontal_margin"
- android:layoutDirection="locale" />
+ <android.widget.RadialTimePickerView
+ android:id="@+id/radial_picker"
+ android:layout_width="@dimen/timepicker_radial_picker_dimen"
+ android:layout_height="@dimen/timepicker_radial_picker_dimen"
+ android:layout_gravity="center|fill"
+ android:layout_marginTop="@dimen/timepicker_radial_picker_top_margin"
+ android:layout_marginStart="@dimen/timepicker_radial_picker_horizontal_margin"
+ android:layout_marginEnd="@dimen/timepicker_radial_picker_horizontal_margin"
+ android:layoutDirection="locale" />
- <ViewStub
- android:id="@id/buttonPanel"
- android:layout="@layout/alert_dialog_button_bar_material"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_column="@dimen/time_picker_column_end_material"
- android:layout_row="2"
- android:layout_gravity="bottom|fill_horizontal"
- android:layoutDirection="locale" />
-</GridLayout>
+ <android.widget.TextInputTimePickerView
+ android:id="@+id/input_mode"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingStart="?attr/dialogPreferredPadding"
+ android:paddingEnd="?attr/dialogPreferredPadding"
+ android:visibility="gone" />
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+ <ImageButton
+ android:id="@+id/toggle_mode"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_vertical"
+ android:layout_marginStart="12dp"
+ android:layout_marginEnd="12dp"
+ android:padding="12dp"
+ android:background="?attr/selectableItemBackgroundBorderless"
+ android:tint="?attr/colorControlNormal"
+ android:src="@drawable/btn_keyboard_key_material"
+ android:contentDescription="@string/time_picker_text_input_mode_description" />
+ <Space
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_weight="1" />
+ <ViewStub
+ android:id="@id/buttonPanel"
+ android:layout="@layout/alert_dialog_button_bar_material"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layoutDirection="locale" />
+ </LinearLayout>
+ </LinearLayout>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/core/res/res/layout/preference_list_content.xml b/core/res/res/layout/preference_list_content.xml
index 02cd8cd..bed80ed 100644
--- a/core/res/res/layout/preference_list_content.xml
+++ b/core/res/res/layout/preference_list_content.xml
@@ -24,6 +24,7 @@
android:layout_width="match_parent">
<LinearLayout
+ android:id="@+id/prefs_container"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="0px"
@@ -61,8 +62,7 @@
android:layout_width="0px"
android:layout_height="match_parent"
android:layout_weight="@integer/preferences_right_pane_weight"
- android:orientation="vertical"
- android:visibility="gone" >
+ android:orientation="vertical">
<!-- Breadcrumb inserted here, in certain screen sizes. In others, it will be an
empty layout or just padding, and PreferenceActivity will put the breadcrumbs in
diff --git a/core/res/res/layout/preference_list_content_material.xml b/core/res/res/layout/preference_list_content_material.xml
index 1bc527e..37b4119 100644
--- a/core/res/res/layout/preference_list_content_material.xml
+++ b/core/res/res/layout/preference_list_content_material.xml
@@ -24,6 +24,7 @@
android:layout_width="match_parent">
<LinearLayout
+ android:id="@+id/prefs_container"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="0px"
@@ -64,8 +65,7 @@
android:layout_width="0px"
android:layout_height="match_parent"
android:layout_weight="@integer/preferences_right_pane_weight"
- android:orientation="vertical"
- android:visibility="gone" >
+ android:orientation="vertical">
<!-- Breadcrumb inserted here, in certain screen sizes. In others, it will be an
empty layout or just padding, and PreferenceActivity will put the breadcrumbs in
diff --git a/core/res/res/layout/time_picker_material.xml b/core/res/res/layout/time_picker_material.xml
index 37a7384..7597379 100644
--- a/core/res/res/layout/time_picker_material.xml
+++ b/core/res/res/layout/time_picker_material.xml
@@ -34,4 +34,53 @@
android:layout_marginTop="@dimen/timepicker_radial_picker_top_margin"
android:layout_marginStart="@dimen/timepicker_radial_picker_horizontal_margin"
android:layout_marginEnd="@dimen/timepicker_radial_picker_horizontal_margin" />
+ <TextView
+ android:visibility="gone"
+ android:id="@+id/input_header"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingStart="@dimen/dialog_padding_material"
+ android:paddingEnd="@dimen/dialog_padding_material"
+ android:paddingTop="20dp"
+ android:paddingBottom="20dp"
+ android:includeFontPadding="false"
+ android:fontFamily="sans-serif-medium"
+ android:textSize="34sp"
+ android:textColor="@color/white"
+ android:text="@string/time_picker_header_text"/>
+ <android.widget.TextInputTimePickerView
+ android:id="@+id/input_mode"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingStart="?attr/dialogPreferredPadding"
+ android:paddingEnd="?attr/dialogPreferredPadding"
+ android:visibility="gone" />
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+ <ImageButton
+ android:id="@+id/toggle_mode"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_vertical"
+ android:layout_marginStart="12dp"
+ android:layout_marginEnd="12dp"
+ android:padding="12dp"
+ android:background="?attr/selectableItemBackgroundBorderless"
+ android:tint="?attr/colorControlNormal"
+ android:src="@drawable/btn_keyboard_key_material"
+ android:contentDescription="@string/time_picker_text_input_mode_description" />
+ <Space
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_weight="1" />
+ <ViewStub
+ android:id="@id/buttonPanel"
+ android:layout="@layout/alert_dialog_button_bar_material"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layoutDirection="locale" />
+ </LinearLayout>
+
</LinearLayout>
diff --git a/core/res/res/layout/time_picker_text_input_material.xml b/core/res/res/layout/time_picker_text_input_material.xml
new file mode 100644
index 0000000..f17b80e
--- /dev/null
+++ b/core/res/res/layout/time_picker_text_input_material.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<merge xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <TextView
+ android:id="@+id/top_label"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="26dp"
+ android:layout_marginBottom="8dp"
+ android:text="@string/time_picker_prompt_label"
+ android:textAppearance="@style/TextAppearance.Material.TimePicker.PromptLabel" />
+
+ <RelativeLayout
+ android:id="@+id/input_block"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_below="@id/top_label"
+ android:layoutDirection="ltr">
+ <EditText
+ android:id="@+id/input_hour"
+ android:layout_width="50dp"
+ android:layout_height="wrap_content"
+ android:inputType="number"
+ android:textAppearance="@style/TextAppearance.Material.TimePicker.InputField" />
+ <TextView
+ android:id="@+id/label_hour"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_below="@id/input_hour"
+ android:layout_alignStart="@id/input_hour"
+ android:text="@string/time_picker_hour_label"/>
+
+ <TextView
+ android:id="@+id/input_separator"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignEnd="@id/input_hour"
+ android:layout_alignBaseline="@id/input_hour"
+ android:textAppearance="@style/TextAppearance.Material.TimePicker.InputField" />
+
+ <EditText
+ android:id="@+id/input_minute"
+ android:layout_width="50dp"
+ android:layout_height="wrap_content"
+ android:layout_alignBaseline="@id/input_hour"
+ android:layout_toEndOf="@id/input_separator"
+ android:inputType="number"
+ android:textAppearance="@style/TextAppearance.Material.TimePicker.InputField" />
+ <TextView
+ android:id="@+id/label_minute"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_below="@id/input_minute"
+ android:layout_alignStart="@id/input_minute"
+ android:text="@string/time_picker_minute_label"/>
+
+ <TextView
+ android:visibility="invisible"
+ android:id="@+id/label_error"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_below="@id/input_hour"
+ android:layout_alignStart="@id/input_hour"
+ android:textColor="?attr/textColorError"
+ android:text="@string/time_picker_input_error" />
+ </RelativeLayout>
+ <Spinner
+ android:id="@+id/am_pm_spinner"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignBaseline="@id/input_block"
+ android:layout_alignParentEnd="true"/>
+
+</merge>
\ No newline at end of file
diff --git a/core/res/res/values-af-watch/styles_material.xml b/core/res/res/values-af-watch/styles_material.xml
deleted file mode 100644
index 80a5fa6..0000000
--- a/core/res/res/values-af-watch/styles_material.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 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.
- -->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see styles_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"kandidate"</font></string>
-</resources>
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 9be3635..46d0745 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -278,6 +278,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Beheer die vertoonskerm se zoemvlak en posisionering."</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Voer gebare uit"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Kan tik, swiep, knyp en ander gebare uitvoer."</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"Vingerafdrukgebare"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"Kan gebare wat op die toestel se vingerafdruksensor uitgevoer word, vasvang"</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"deaktiveer of verander statusbalk"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"Laat die program toe om die statusbalk te deaktiveer en stelselikone by te voeg of te verwyder."</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"wees die statusbalk"</string>
@@ -1146,6 +1148,7 @@
<string name="usb_notification_message" msgid="3370903770828407960">"Tik vir meer opsies."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB-ontfouter gekoppel"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Tik om USB-ontfouting te deaktiveer."</string>
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Kies om USB-ontfouting te deaktiveer."</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Neem tans foutverslag …"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Deel foutverslag?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Deel tans foutverslag …"</string>
@@ -1689,4 +1692,7 @@
<string name="app_category_news" msgid="7496506240743986873">"Nuus en tydskrifte"</string>
<string name="app_category_maps" msgid="5878491404538024367">"Kaarte en navigasie"</string>
<string name="app_category_productivity" msgid="3742083261781538852">"Produktiwiteit"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"Toestelberging"</string>
+ <!-- no translation found for adb_debugging_notification_channel_tv (5537766997350092316) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-am-watch/styles_material.xml b/core/res/res/values-am-watch/styles_material.xml
deleted file mode 100644
index 5ec383a8..0000000
--- a/core/res/res/values-am-watch/styles_material.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 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.
- -->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see styles_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"እጩዎች"</font></string>
-</resources>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 41dff04..45206873 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -278,6 +278,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"የማሳያውን የማጉያ ደረጃ እና አቀማመጥ ይቆጣጠሩ።"</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"የጣት ምልክቶችን ያከናውኑ"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"መታ ማድረግ፣ ማንሸራተት፣ መቆንጠጥ እና ሌሎች የጣት ምልክቶችን ማከናወን ይችላል።"</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"የጣት አሻራ ምልክቶች"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"በመሣሪያዎቹ የጣት አሻራ ዳሳሽ ላይ የተከናወኑ የጣት ምልክቶችን መያዝ ይችላል።"</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"የሁኔቴ አሞሌ አቦዝን ወይም ቀይር"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"የስርዓት አዶዎችን ወደ ሁኔታ አሞሌ ላለማስቻል ወይም ለማከል እና ለማስወገድ ለመተግበሪያው ይፈቅዳሉ፡፡"</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"የሁኔታ አሞሌ መሆን"</string>
@@ -1146,6 +1148,7 @@
<string name="usb_notification_message" msgid="3370903770828407960">"ለተጨማሪ አማራጮች መታ ያድርጉ።"</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB አድስ ተያይዟል"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"የዩኤስቢ ማረሚያን ለማሰናከል መታ ያድርጉ።"</string>
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB ማረሚያ ላለማንቃት ምረጥ።"</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"የሳንካ ሪፖርትን በመውሰድ ላይ…"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"የሳንካ ሪፖርት ይጋራ?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"የሳንካ ሪፖርትን በማጋራት ላይ…"</string>
@@ -1689,4 +1692,7 @@
<string name="app_category_news" msgid="7496506240743986873">"ዜና እና መጽሔቶች"</string>
<string name="app_category_maps" msgid="5878491404538024367">"ካርታዎች እና ዳሰሳ"</string>
<string name="app_category_productivity" msgid="3742083261781538852">"ውጤታማነት"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"የመሣሪያ ማከማቻ"</string>
+ <!-- no translation found for adb_debugging_notification_channel_tv (5537766997350092316) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ar-watch/styles_material.xml b/core/res/res/values-ar-watch/styles_material.xml
deleted file mode 100644
index 36a459d..0000000
--- a/core/res/res/values-ar-watch/styles_material.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 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.
- -->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see styles_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"candidates"</font></string>
-</resources>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 07e1699..95118c2 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -290,6 +290,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"يمكنك التحكم في مستوى التكبير/التصغير للشاشة وتحديد الموضع."</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"تنفيذ إيماءات"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"يمكن النقر والتمرير بسرعة والتصغير وتنفيذ إيماءات أخرى."</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"إيماءات بصمات الإصبع"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"يمكن أن تلتقط الإيماءات التي تم تنفيذها على مستشعر بصمات الإصبع في الأجهزة."</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"تعطيل شريط الحالة أو تعديله"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"للسماح للتطبيق بتعطيل شريط الحالة أو إضافة رموز نظام وإزالتها."</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"العمل كشريط للحالة"</string>
@@ -1226,6 +1228,7 @@
<string name="usb_notification_message" msgid="3370903770828407960">"انقر للحصول على المزيد من الخيارات."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"تم توصيل تصحيح أخطاء USB"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"انقر لتعطيل تصحيح أخطاء USB."</string>
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"اختيار تعطيل تصحيح أخطاء USB."</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"جارٍ الحصول على تقرير الخطأ…"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"هل تريد مشاركة تقرير الخطأ؟"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"جارٍ مشاركة تقرير الخطأ…"</string>
@@ -1813,4 +1816,7 @@
<string name="app_category_news" msgid="7496506240743986873">"الأخبار والمجلات"</string>
<string name="app_category_maps" msgid="5878491404538024367">"الخرائط والتنقل"</string>
<string name="app_category_productivity" msgid="3742083261781538852">"الإنتاجية"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"السعة التخزينية للجهاز"</string>
+ <!-- no translation found for adb_debugging_notification_channel_tv (5537766997350092316) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-az-watch/styles_material.xml b/core/res/res/values-az-watch/styles_material.xml
deleted file mode 100644
index b621266..0000000
--- a/core/res/res/values-az-watch/styles_material.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 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.
- -->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see styles_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"namizədlər"</font></string>
-</resources>
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
index ebc4eed..cf377b2d 100644
--- a/core/res/res/values-az/strings.xml
+++ b/core/res/res/values-az/strings.xml
@@ -278,6 +278,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Ekran yaxınlaşdırma səviyyəsi və yerləşdirməsinə nəzarət edin."</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Jestlər ilə əməliyyat aparın"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Digər jestlərə tıklaya, sürüşdürə və əməliyyat apara bilərsiniz."</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"Barmaq izi işarələri"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"Cihazların barmaq izi sensorunda olan işarələri əldə edə bilər"</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"status panelini deaktivləşdir və ya dəyişdir"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"Tətbiqə status panelini deaktiv etməyə və ya sistem ikonalarını əlavə etmək və ya silmək imkanı verir."</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"status paneli edin"</string>
@@ -1146,6 +1148,7 @@
<string name="usb_notification_message" msgid="3370903770828407960">"Əlavə seçimlər üçün tıklayın."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB sazlama qoşuludur"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"USB debaqı deaktivasiya etmək üçün tıklayın."</string>
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USb debaqı deaktivasiya etməyi seçin."</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Baq hesabatı verilir..."</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Baq hesabatı paylaşılsın?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Baq hesabatı paylaşılır..."</string>
@@ -1689,4 +1692,7 @@
<string name="app_category_news" msgid="7496506240743986873">"Xəbər və Jurnallar"</string>
<string name="app_category_maps" msgid="5878491404538024367">"Xəritə və Naviqasiya"</string>
<string name="app_category_productivity" msgid="3742083261781538852">"Məhsuldarlıq"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"Cihaz yaddaşı"</string>
+ <!-- no translation found for adb_debugging_notification_channel_tv (5537766997350092316) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-b+sr+Latn-watch/styles_material.xml b/core/res/res/values-b+sr+Latn-watch/styles_material.xml
deleted file mode 100644
index 36a459d..0000000
--- a/core/res/res/values-b+sr+Latn-watch/styles_material.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 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.
- -->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see styles_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"candidates"</font></string>
-</resources>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index 810ed0f..e56d938 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -281,6 +281,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Upravlja nivoom zumiranja prikaza i određivanjem položaja."</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Obavljanje pokreta"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Može da dodiruje, lista, skuplja prikaz i obavlja druge pokrete."</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"Pokreti za otisak prsta"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"Može da registruje pokrete na senzoru za otisak prsta na uređaju."</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"onemogućavanje ili izmena statusne trake"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"Dozvoljava aplikaciji da onemogući statusnu traku ili da dodaje i uklanja sistemske ikone."</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"funkcionisanje kao statusna traka"</string>
@@ -1166,6 +1168,7 @@
<string name="usb_notification_message" msgid="3370903770828407960">"Dodirnite za još opcija."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"Otklanjanje grešaka sa USB-a je uspostavljeno"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Dodirnite da biste onemogućili otklanjanje grešaka sa USB-a."</string>
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Izaberite da biste onemogućili otklanjanja grešaka sa USB-a."</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Izveštaj o grešci se generiše…"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Želite li da podelite izveštaj o grešci?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Deli se izveštaj o grešci…"</string>
@@ -1720,4 +1723,7 @@
<string name="app_category_news" msgid="7496506240743986873">"Novosti i časopisi"</string>
<string name="app_category_maps" msgid="5878491404538024367">"Mape i navigacija"</string>
<string name="app_category_productivity" msgid="3742083261781538852">"Produktivnost"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"Memorijski prostor uređaja"</string>
+ <!-- no translation found for adb_debugging_notification_channel_tv (5537766997350092316) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-be-watch/styles_material.xml b/core/res/res/values-be-watch/styles_material.xml
deleted file mode 100644
index 36a459d..0000000
--- a/core/res/res/values-be-watch/styles_material.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 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.
- -->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see styles_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"candidates"</font></string>
-</resources>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index 7ad40c4..6383c39 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -284,6 +284,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Кіраваць маштабам дысплэя і пазіцыянаваннем."</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Выконваць жэсты"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Можна кранаць, праводзіць пальцам, маштабаваць шчыпком, а таксама выконваць іншыя жэсты."</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"Жэсты адбіткаў пальцаў"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"Можа распазнаваць жэсты на сканеры адбіткаў пальцаў прылады."</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"адключаць ці змяняць радок стану"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"Дазваляе прыкладанням адключаць радок стану або дадаваць і выдаляць сістэмныя значкі."</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"быць панэллю стану"</string>
@@ -1186,6 +1188,7 @@
<string name="usb_notification_message" msgid="3370903770828407960">"Дакраніцеся, каб атрымаць іншыя параметры."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"Адладка па USB падключана"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Дакраніцеся, каб адключыць адладку па USB."</string>
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Выберыце, каб адключыць адладку USB."</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Стварэнне справаздачы пра памылку…"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Падзяліцца справаздачай пра памылку?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Перадача справаздачы пра памылку..."</string>
@@ -1751,4 +1754,7 @@
<string name="app_category_news" msgid="7496506240743986873">"Навіны і часопісы"</string>
<string name="app_category_maps" msgid="5878491404538024367">"Карты і навігацыя"</string>
<string name="app_category_productivity" msgid="3742083261781538852">"Прадукцыйнасць"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"Сховішча на прыладзе"</string>
+ <!-- no translation found for adb_debugging_notification_channel_tv (5537766997350092316) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-bg-watch/styles_material.xml b/core/res/res/values-bg-watch/styles_material.xml
deleted file mode 100644
index 89c3366..0000000
--- a/core/res/res/values-bg-watch/styles_material.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 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.
- -->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see styles_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"кандидати"</font></string>
-</resources>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 9afed47..1238e2c 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -278,6 +278,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Управление на нивото на мащаба и позиционирането на дисплея."</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Извършване на жестове"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Можете да докосвате, да прекарвате пръст, да събирате пръсти и да извършвате други жестове."</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"Жестове за отпечатък"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"Може да улавя жестовете, извършени върху сензора за отпечатъци на устройството."</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"деактивиране или промяна на лентата на състоянието"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"Разрешава на приложението да деактивира лентата на състоянието или да добавя и премахва системни икони."</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"изпълняване на ролята на лента на състоянието"</string>
@@ -1146,6 +1148,7 @@
<string name="usb_notification_message" msgid="3370903770828407960">"Докоснете за още опции."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"Отстраняване на грешки през USB"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Докоснете, за да деактивирате отстраняването на грешки през USB."</string>
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Изберете, за да деактивирате отстраняването на грешки през USB."</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Сигналът за програмна грешка се извлича…"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Да се сподели ли сигналът за програмна грешка?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Сигналът за програмна грешка се споделя…"</string>
@@ -1689,4 +1692,7 @@
<string name="app_category_news" msgid="7496506240743986873">"Новини и списания"</string>
<string name="app_category_maps" msgid="5878491404538024367">"Карти и навигация"</string>
<string name="app_category_productivity" msgid="3742083261781538852">"Производителност"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"Хранилище на устройството"</string>
+ <!-- no translation found for adb_debugging_notification_channel_tv (5537766997350092316) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-bn-watch/styles_material.xml b/core/res/res/values-bn-watch/styles_material.xml
deleted file mode 100644
index cd59902..0000000
--- a/core/res/res/values-bn-watch/styles_material.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 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.
- -->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see styles_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"প্রার্থীরা"</font></string>
-</resources>
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index 6522537..9bedf58 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -63,8 +63,8 @@
<string name="needPuk2" msgid="4526033371987193070">"সিম কার্ড অবরোধ মুক্ত করতে PUK2 লিখুন৷"</string>
<string name="enablePin" msgid="209412020907207950">"অসফল, সিম/RUIM লক সক্ষম করুন৷"</string>
<plurals name="pinpuk_attempts" formatted="false" msgid="1251012001539225582">
- <item quantity="one">আপনার কাছে আর <xliff:g id="NUMBER_1">%d</xliff:g>টি প্রচেষ্টা বাকি রয়েছে এটির পরেই আপনার SIM লক হয়ে যাবে৷</item>
- <item quantity="other">আপনার কাছে আর <xliff:g id="NUMBER_1">%d</xliff:g>টি প্রচেষ্টা বাকি রয়েছে এটির পরেই আপনার SIM লক হয়ে যাবে৷</item>
+ <item quantity="one">আপনার কাছে আর <xliff:g id="NUMBER_1">%d</xliff:g>টি প্রচেষ্টা বাকি রয়েছে এটির পরেই আপনার সিম লক হয়ে যাবে৷</item>
+ <item quantity="other">আপনার কাছে আর <xliff:g id="NUMBER_1">%d</xliff:g>টি প্রচেষ্টা বাকি রয়েছে এটির পরেই আপনার সিম লক হয়ে যাবে৷</item>
</plurals>
<string name="imei" msgid="2625429890869005782">"IMEI"</string>
<string name="meid" msgid="4841221237681254195">"MEID"</string>
@@ -255,7 +255,7 @@
<string name="permgrouplab_calendar" msgid="5863508437783683902">"ক্যালেন্ডার"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"আপনার ক্যালেন্ডারে অ্যাক্সেস"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
- <string name="permgroupdesc_sms" msgid="4656988620100940350">"SMS বার্তাগুলি পাঠাতে এবং দেখতে"</string>
+ <string name="permgroupdesc_sms" msgid="4656988620100940350">"এসএমএসগুলি পাঠাতে এবং দেখতে"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"সঞ্চয়স্থান"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"আপনার ডিভাইসে ফটো, মিডিয়া এবং ফাইলগুলিতে অ্যাক্সেস"</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"মাইক্রোফোন"</string>
@@ -278,6 +278,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"প্রদর্শনের জুমের স্তর এবং অবস্থান নির্ধারন নিয়ন্ত্রণ করুন৷"</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"অঙ্গভঙ্গির কাজগুলি সম্পাদন করুন"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"আলতো চাপ দেওয়া, সোয়াইপ, পিঞ্চ করা এবং অন্যান্য অঙ্গভঙ্গির কাজগুলি সম্পাদন করতে পারবেন৷"</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"ফিঙ্গারপ্রিন্ট সেন্সরের উপর করা অঙ্গভঙ্গিগুলি"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"ডিভাইসের ফিঙ্গারপ্রিন্ট সেন্সরের উপর আঙ্গুলের অঙ্গভঙ্গি ক্যাপচার করতে পারে।"</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"স্থিতি দন্ড নিষ্ক্রিয় অথবা সংশোধন করে"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"অ্যাপ্লিকেশানকে স্থিতি দন্ড অক্ষম করতে এবং সিস্টেম আইকনগুলি সরাতে দেয়৷"</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"স্থিতি দন্ডে থাকুন"</string>
@@ -291,7 +293,7 @@
<string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"আউটগোয়িং কলগুলি পুনঃচালিত করুন"</string>
<string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"অ্যাপ্লিকেশানকে কল চলাকালীন অন্য একটি নম্বরে কল পুনঃনির্দেশ বা কলটি একসথে বন্ধ করার সাথে ডায়াল করা নম্বরটি দেখতে দেয়৷"</string>
<string name="permlab_receiveSms" msgid="8673471768947895082">"পাঠ্য বার্তা পান (SMS)"</string>
- <string name="permdesc_receiveSms" msgid="6424387754228766939">"অ্যাপ্লিকেশানটিকে SMS বার্তা প্রাপ্ত করার এবং প্রক্রিয়া করার অনুমতি দেয়৷ এর মানে হল অ্যাপ্লিকেশানটি আপনার ডিভাইস থেকে পাঠানো বার্তাগুলিকে পর্যবেক্ষণ করতে পারে এবং মুছতে পারে সেগুলিকে আপনাকে না দেখিয়ে৷"</string>
+ <string name="permdesc_receiveSms" msgid="6424387754228766939">"অ্যাপ্লিকেশানটিকে এসএমএস প্রাপ্ত করার এবং প্রক্রিয়া করার অনুমতি দেয়৷ এর মানে হল অ্যাপ্লিকেশানটি আপনার ডিভাইস থেকে পাঠানো বার্তাগুলিকে পর্যবেক্ষণ করতে পারে এবং মুছতে পারে সেগুলিকে আপনাকে না দেখিয়ে৷"</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"পাঠ্য বার্তা পান (MMS)"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"অ্যাপ্লিকেশানটিকে MMS বার্তা প্রাপ্ত করার এবং প্রক্রিয়া করার অনুমতি দেয়৷ এর মানে হল অ্যাপ্লিকেশানটি আপনার ডিভাইস থেকে পাঠানো বার্তাগুলিকে পর্যবেক্ষণ করতে পারে এবং মুছতে পারে সেগুলিকে আপনাকে না দেখিয়ে৷"</string>
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"সেল সম্প্রচার বার্তা পড়ুন"</string>
@@ -299,7 +301,7 @@
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"গ্রাহক হিসাবে নেওয়া ফিডগুলি পড়ে"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"অ্যাপ্লিকেশানকে বর্তমানে সিঙ্ক করা ফিডগুলির সম্পর্কে বিবরণ পেতে দেয়৷"</string>
<string name="permlab_sendSms" msgid="7544599214260982981">"SMS পাঠানো ও দেখা,আপনি কি পরিচিতি কে এগুলি করার অনুমতি দেবেন?"</string>
- <string name="permdesc_sendSms" msgid="7094729298204937667">"অ্যাপ্লিকেশানটিকে SMS বার্তাগুলি পাঠাতে অনুমতি দেয়৷ এর জন্য অপ্রত্যাশিত চার্জ কাটা হতে পারে৷ ক্ষতিকারক অ্যাপ্লিকেশানগুলি আপনার নিশ্চিতকরণ ছাড়া বার্তা পাঠানোর মাধ্যমে আপনাকে অর্থ চার্জ করতে পারে৷"</string>
+ <string name="permdesc_sendSms" msgid="7094729298204937667">"অ্যাপ্লিকেশানটিকে এসএমএসগুলি পাঠাতে অনুমতি দেয়৷ এর জন্য অপ্রত্যাশিত চার্জ কাটা হতে পারে৷ ক্ষতিকারক অ্যাপ্লিকেশানগুলি আপনার নিশ্চিতকরণ ছাড়া বার্তা পাঠানোর মাধ্যমে আপনাকে অর্থ চার্জ করতে পারে৷"</string>
<string name="permlab_readSms" msgid="8745086572213270480">"আপনার পাঠ্য বার্তা পড়ুন (SMS বা MMS)"</string>
<string name="permdesc_readSms" product="tablet" msgid="4741697454888074891">"এই অ্যাপটি আপনার ট্যাবলেটে সংরক্ষিত সমস্ত SMS (পাঠ্য) বার্তা পড়তে পারে৷"</string>
<string name="permdesc_readSms" product="tv" msgid="5796670395641116592">"এই অ্যাপটি আপনার টিভিতে সংরক্ষিত সমস্ত SMS (পাঠ্য) বার্তা পড়তে পারে৷"</string>
@@ -370,7 +372,7 @@
<string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"ভলিউম এবং যেখানে স্পিকার আউটপুট সামগ্রী হিসাবে ব্যবহৃত হয় সেই সব ক্ষেত্রে গ্লোবাল অডিও সেটিংসের সংশোধন করতে অ্যাপ্লিকেশানটিকে মঞ্জুর করে৷"</string>
<string name="permlab_recordAudio" msgid="3876049771427466323">"অডিও রেকর্ড"</string>
<string name="permdesc_recordAudio" msgid="4245930455135321433">"এই অ্যাপটি মাইক্রোফোন ব্যবহার করে যে কোনো সময় অডিও রেকর্ড করতে পারে৷"</string>
- <string name="permlab_sim_communication" msgid="2935852302216852065">"SIM এ আদেশগুলি পাঠান"</string>
+ <string name="permlab_sim_communication" msgid="2935852302216852065">"সিম এ আদেশগুলি পাঠান"</string>
<string name="permdesc_sim_communication" msgid="5725159654279639498">"অ্যাপ্লিকেশানটিকে সিম কার্ডে কমান্ডগুলি পাঠানোর অনুমতি দেয়৷ এটি খুবই বিপজ্জনক৷"</string>
<string name="permlab_camera" msgid="3616391919559751192">"ছবি এবং ভিডিও তোলে"</string>
<string name="permdesc_camera" msgid="5392231870049240670">"এই অ্যাপটি যে কোনো সময় ক্যামেরা ব্যবহার করে ছবি তুলতে বা ভিডিও রেকর্ড করতে পারে৷"</string>
@@ -479,8 +481,8 @@
<string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"অ্যাপ্লিকেশানকে SD কার্ডে লেখার অনুমতি দেয়৷"</string>
<string name="permlab_use_sip" msgid="2052499390128979920">"SIP কল করুন/গ্রহণ করুন"</string>
<string name="permdesc_use_sip" msgid="2297804849860225257">"অ্যাপ্লিকেশানকে SIP কল করতে ও গ্রহণ করতে অনুমতি দেয়।"</string>
- <string name="permlab_register_sim_subscription" msgid="3166535485877549177">"নতুন টেলিকম SIM সংযোগগুলির নিবন্ধন"</string>
- <string name="permdesc_register_sim_subscription" msgid="2138909035926222911">"অ্যাপ্লিকেশানটিকে নতুন টেলিকম SIM সংযোগগুলি নিবন্ধিত করতে অনুমোদিত করে৷"</string>
+ <string name="permlab_register_sim_subscription" msgid="3166535485877549177">"নতুন টেলিকম সিম সংযোগগুলির নিবন্ধন"</string>
+ <string name="permdesc_register_sim_subscription" msgid="2138909035926222911">"অ্যাপ্লিকেশানটিকে নতুন টেলিকম সিম সংযোগগুলি নিবন্ধিত করতে অনুমোদিত করে৷"</string>
<string name="permlab_register_call_provider" msgid="108102120289029841">"নতুন টেলিকম সংযোগগুলির নিবন্ধন"</string>
<string name="permdesc_register_call_provider" msgid="7034310263521081388">"নতুন টেলিকম সংযোগ নিবন্ধিত করতে অ্যাপ্লিকেশানটিকে অনুমোদিত করে৷"</string>
<string name="permlab_connection_manager" msgid="1116193254522105375">"টেলিকম সংযোগগুলি পরিচালনা করুন"</string>
@@ -692,7 +694,7 @@
<string name="faceunlock_multiple_failures" msgid="754137583022792429">"মুখের সাহায্যে আনলক করার প্রচেষ্টা যতবার করা যায় তার সীমা পেরিয়ে গেছে"</string>
<string name="lockscreen_missing_sim_message_short" msgid="5099439277819215399">"কোনো সিম কার্ড নেই"</string>
<string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"ট্যাবলেটের মধ্যে কোনো সিম কার্ড নেই৷"</string>
- <string name="lockscreen_missing_sim_message" product="tv" msgid="1943633865476989599">"টিভির মধ্যে কোনো SIM কার্ড নেই৷"</string>
+ <string name="lockscreen_missing_sim_message" product="tv" msgid="1943633865476989599">"টিভির মধ্যে কোনো সিম কার্ড নেই৷"</string>
<string name="lockscreen_missing_sim_message" product="default" msgid="2186920585695169078">"ফোনের মধ্যে কোনো সিম কার্ড নেই৷"</string>
<string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"একটি সিম কার্ড ঢোকান৷"</string>
<string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"সিম কার্ডটি অনুপস্থিত বা পাঠযোগ্য নয়৷ একটি সিম কার্ড ঢোকান৷"</string>
@@ -1104,8 +1106,8 @@
<string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="3087858235069421128">"আপনার টিভি <xliff:g id="DEVICE_NAME">%1$s</xliff:g> এ সংযুক্ত থাকার সময় ওয়াই-ফাই থেকে সাময়িকভাবে সংযোগ বিচ্ছিন্ন হবে৷"</string>
<string name="wifi_p2p_frequency_conflict_message" product="default" msgid="7363907213787469151">"ফোনটি যখন <xliff:g id="DEVICE_NAME">%1$s</xliff:g> এ সংযুক্ত হবে তখন এটি ওয়াই-ফাই থেকে সাময়িকভাবে সংযোগ বিচ্ছিন্ন হবে"</string>
<string name="select_character" msgid="3365550120617701745">"অক্ষর ঢোকান"</string>
- <string name="sms_control_title" msgid="7296612781128917719">"SMS বার্তা পাঠানো হচ্ছে"</string>
- <string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> অনেকগুলি SMS বার্তা পাঠাচ্ছে৷ আপনি কি এই অ্যাপ্লিকেশানটিকে বার্তা পাঠানো চালিয়ে যাওয়ার অনুমতি দিতে চান?"</string>
+ <string name="sms_control_title" msgid="7296612781128917719">"এসএমএস পাঠানো হচ্ছে"</string>
+ <string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> অনেকগুলি এসএমএস পাঠাচ্ছে৷ আপনি কি এই অ্যাপ্লিকেশানটিকে বার্তা পাঠানো চালিয়ে যাওয়ার অনুমতি দিতে চান?"</string>
<string name="sms_control_yes" msgid="3663725993855816807">"অনুমতি দিন"</string>
<string name="sms_control_no" msgid="625438561395534982">"আস্বীকার করুন"</string>
<string name="sms_short_code_confirm_message" msgid="1645436466285310855">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b> এ একটি বার্তা পাঠাতে চায়৷"</string>
@@ -1123,10 +1125,10 @@
<string name="sim_added_title" msgid="3719670512889674693">"সিম কার্ড যোগ করা হয়েছে"</string>
<string name="sim_added_message" msgid="7797975656153714319">"সেলুলার নেটওয়ার্ক অ্যাক্সেস করতে আপনার ডিভাইস পুনর্সূচনা করুন"</string>
<string name="sim_restart_button" msgid="4722407842815232347">"পুনর্সূচনা"</string>
- <string name="carrier_app_dialog_message" msgid="7066156088266319533">"যাতে আপনার নতুন SIM সঠিকভাবে কাজ করে, তার জন্য আপনাকে আপনার পরিষেবা প্রদানকারীর থেকে একটি অ্যাপ্লিকেশান ইনস্টল করতে এবং খুলতে হবে৷"</string>
+ <string name="carrier_app_dialog_message" msgid="7066156088266319533">"যাতে আপনার নতুন সিম সঠিকভাবে কাজ করে, তার জন্য আপনাকে আপনার পরিষেবা প্রদানকারীর থেকে একটি অ্যাপ্লিকেশান ইনস্টল করতে এবং খুলতে হবে৷"</string>
<string name="carrier_app_dialog_button" msgid="7900235513678617329">"অ্যাপ্লিকেশানটি পান"</string>
<string name="carrier_app_dialog_not_now" msgid="6361378684292268027">"এখনই নয়"</string>
- <string name="carrier_app_notification_title" msgid="8921767385872554621">"নতুন SIM ঢোকানো হয়েছে"</string>
+ <string name="carrier_app_notification_title" msgid="8921767385872554621">"নতুন সিম ঢোকানো হয়েছে"</string>
<string name="carrier_app_notification_text" msgid="1132487343346050225">"এটিকে সেট আপ করতে আলতো চাপুন"</string>
<string name="time_picker_dialog_title" msgid="8349362623068819295">"সময় সেট করুন"</string>
<string name="date_picker_dialog_title" msgid="5879450659453782278">"তারিখ সেট করুন"</string>
@@ -1146,6 +1148,8 @@
<string name="usb_notification_message" msgid="3370903770828407960">"আরো বিকল্পের জন্য আলতো চাপুন৷"</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB ডিবাগিং সংযুক্ত হয়েছে"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"USB ডিবাগিং অক্ষম করতে আলতো চাপুন৷"</string>
+ <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
+ <skip />
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"ত্রুটির প্রতিবেদন নেওয়া হচ্ছে..."</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"ত্রুটির প্রতিবেদন শেয়ার করবেন?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"ত্রুটির প্রতিবেদন শেয়ার করা হচ্ছে..."</string>
@@ -1689,4 +1693,7 @@
<string name="app_category_news" msgid="7496506240743986873">"খবর ও পত্রিকাগুলি"</string>
<string name="app_category_maps" msgid="5878491404538024367">"মানচিত্র ও নেভিগেশান"</string>
<string name="app_category_productivity" msgid="3742083261781538852">"উৎপাদনশীলতা"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"ডিভাইসের সঞ্চয়স্থান"</string>
+ <!-- no translation found for adb_debugging_notification_channel_tv (5537766997350092316) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-bs-watch/styles_material.xml b/core/res/res/values-bs-watch/styles_material.xml
deleted file mode 100644
index 88e5751..0000000
--- a/core/res/res/values-bs-watch/styles_material.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 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.
- -->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see styles_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"kandidati"</font></string>
-</resources>
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index c6d70f3..66ef19a33 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -281,6 +281,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Kontrolira stepen uvećanja prikaza na ekranu i podešavanje položaja."</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Praviti pokrete"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Može dodirivati, prevlačiti, hvatati prstima i praviti druge pokrete."</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"Pokreti otiska prsta"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"Moguće je zabilježiti pokrete na senzoru za otisak prsta uređaja."</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"onemogućavanje ili mijenjanje statusne trake"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"Dozvoljava aplikaciji onemogućavanje statusne trake ili dodavanje i uklanjanje sistemskih ikona."</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"funkcioniranje u vidu statusne trake"</string>
@@ -1168,6 +1170,8 @@
<string name="usb_notification_message" msgid="3370903770828407960">"Dodirnite za više opcija."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"Otklanjanje grešaka putem uređaja spojenog na USB je uspostavljeno"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Dodirnite da onemogućite otklanjanje grešaka putem uređaja spojenog na USB."</string>
+ <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
+ <skip />
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Prijem izvještaja o grešci..."</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Podijeliti izvještaj o grešci?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Dijeljenje izvještaja o grešci..."</string>
@@ -1722,4 +1726,7 @@
<string name="app_category_news" msgid="7496506240743986873">"Vijesti i časopisi"</string>
<string name="app_category_maps" msgid="5878491404538024367">"Mape i navigacija"</string>
<string name="app_category_productivity" msgid="3742083261781538852">"Produktivnost"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"Memorija uređaja"</string>
+ <!-- no translation found for adb_debugging_notification_channel_tv (5537766997350092316) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ca-watch/styles_material.xml b/core/res/res/values-ca-watch/styles_material.xml
deleted file mode 100644
index 36a459d..0000000
--- a/core/res/res/values-ca-watch/styles_material.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 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.
- -->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see styles_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"candidates"</font></string>
-</resources>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index eebe75f..b01f382 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -278,6 +278,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Controla el nivell i el posicionament del zoom de la pantalla."</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Utilitza gestos"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Pot tocar, lliscar, pessigar i utilitzar altres gestos."</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"Gestos amb les empremtes digitals"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"Captura gestos realitzats en el sensor d\'empremtes digitals del dispositiu."</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"desactivar o modificar la barra d\'estat"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"Permet que l\'aplicació desactivi la barra d\'estat o afegeixi i elimini icones del sistema."</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"aparèixer a la barra d\'estat"</string>
@@ -950,7 +952,7 @@
<string name="inputMethod" msgid="1653630062304567879">"Mètode d\'introducció de text"</string>
<string name="editTextMenuTitle" msgid="4909135564941815494">"Accions de text"</string>
<string name="email" msgid="4560673117055050403">"Correu electrònic"</string>
- <string name="dial" msgid="2275093056198652749">"Marcatge"</string>
+ <string name="dial" msgid="2275093056198652749">"Telèfon"</string>
<string name="map" msgid="5441053548030107189">"Mapa"</string>
<string name="low_internal_storage_view_title" msgid="5576272496365684834">"L\'espai d\'emmagatzematge s\'està esgotant"</string>
<string name="low_internal_storage_view_text" msgid="6640505817617414371">"És possible que algunes funcions del sistema no funcionin"</string>
@@ -1146,6 +1148,7 @@
<string name="usb_notification_message" msgid="3370903770828407960">"Toca per veure més opcions."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"Depuració USB activada"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Toca per desactivar la depuració USB."</string>
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Selecciona per desactivar la depuració USB"</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"S\'està creant l\'informe d\'errors…"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Vols compartir l\'informe d\'errors?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"S\'està compartint l\'informe d\'errors…"</string>
@@ -1689,4 +1692,7 @@
<string name="app_category_news" msgid="7496506240743986873">"Notícies i revistes"</string>
<string name="app_category_maps" msgid="5878491404538024367">"Mapes i navegació"</string>
<string name="app_category_productivity" msgid="3742083261781538852">"Productivitat"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"Emmagatzematge del dispositiu"</string>
+ <!-- no translation found for adb_debugging_notification_channel_tv (5537766997350092316) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-cs-watch/styles_material.xml b/core/res/res/values-cs-watch/styles_material.xml
deleted file mode 100644
index 5b604e8..0000000
--- a/core/res/res/values-cs-watch/styles_material.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 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.
- -->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see styles_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"kandidáti"</font></string>
-</resources>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 68cc583..b8717d5 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -284,6 +284,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Určuje umístění a úroveň přiblížení displeje."</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Provádění gest"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Může provádět gesta klepnutí, přejetí, stažení prstů a další."</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"Gesta otiskem prstu"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"Dokáže rozpoznat gesta zadaná na snímači otisků prstů."</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"zakázání či změny stavového řádku"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"Umožňuje aplikaci zakázat stavový řádek nebo přidat či odebrat systémové ikony."</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"vydávání se za stavový řádek"</string>
@@ -1186,6 +1188,7 @@
<string name="usb_notification_message" msgid="3370903770828407960">"Klepnutím zobrazíte další možnosti."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"Ladění přes USB připojeno"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Klepnutím zakážete ladění USB."</string>
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Vyberte, chcete-li zakázat ladění USB."</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Vytváření zprávy o chybě…"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Sdílet zprávu o chybě?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Sdílení zprávy o chybě…"</string>
@@ -1751,4 +1754,7 @@
<string name="app_category_news" msgid="7496506240743986873">"Zprávy a časopisy"</string>
<string name="app_category_maps" msgid="5878491404538024367">"Mapy a navigace"</string>
<string name="app_category_productivity" msgid="3742083261781538852">"Produktivita"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"Úložiště zařízení"</string>
+ <!-- no translation found for adb_debugging_notification_channel_tv (5537766997350092316) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-da-watch/styles_material.xml b/core/res/res/values-da-watch/styles_material.xml
deleted file mode 100644
index 36a459d..0000000
--- a/core/res/res/values-da-watch/styles_material.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 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.
- -->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see styles_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"candidates"</font></string>
-</resources>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index f2b6be9..ebcd48e 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -278,6 +278,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Kontrollér skærmens zoomniveau og position."</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Udfør bevægelser"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Kan trykke, stryge, knibe sammen og udføre andre bevægelser."</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"Fingeraftryksbevægelser"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"Kan registrere bevægelser, der foretages på enhedernes fingeraftrykslæser."</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"deaktiver eller rediger statuslinje"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"Tillader, at appen kan deaktivere statusbjælken eller tilføje og fjerne systemikoner."</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"vær statusbjælken"</string>
@@ -1146,6 +1148,7 @@
<string name="usb_notification_message" msgid="3370903770828407960">"Tryk for at se flere muligheder."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB-fejlretning er tilsluttet"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Tryk for at deaktivere fejlretning via USB."</string>
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Vælg for at deaktivere USB-fejlretning."</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Opretter fejlrapport…"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Vil du dele fejlrapporten?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Deler fejlrapport…"</string>
@@ -1395,7 +1398,7 @@
<string name="kg_wrong_pin" msgid="1131306510833563801">"Forkert pinkode"</string>
<string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Prøv igen om <xliff:g id="NUMBER">%1$d</xliff:g> sekunder."</string>
<string name="kg_pattern_instructions" msgid="398978611683075868">"Tegn dit mønster"</string>
- <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Indtast pinkode til SIM"</string>
+ <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Indtast pinkode til SIM-kort"</string>
<string name="kg_pin_instructions" msgid="2377242233495111557">"Indtast pinkode"</string>
<string name="kg_password_instructions" msgid="5753646556186936819">"Angiv adgangskode"</string>
<string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"SIM-kortet er nu deaktiveret. Indtast PUK-koden for at fortsætte. Kontakt mobiloperatøren for at få flere oplysninger."</string>
@@ -1689,4 +1692,7 @@
<string name="app_category_news" msgid="7496506240743986873">"Aviser og blade"</string>
<string name="app_category_maps" msgid="5878491404538024367">"Kort og navigation"</string>
<string name="app_category_productivity" msgid="3742083261781538852">"Produktivitet"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"Lagerplads på enheden"</string>
+ <!-- no translation found for adb_debugging_notification_channel_tv (5537766997350092316) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-de-watch/styles_material.xml b/core/res/res/values-de-watch/styles_material.xml
deleted file mode 100644
index 891a647..0000000
--- a/core/res/res/values-de-watch/styles_material.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 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.
- -->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see styles_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"Kandidaten"</font></string>
-</resources>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 5ba5464..7e31748 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -278,6 +278,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Legt die Zoom-Stufe des Displays und die Zoom-Position auf dem Display fest."</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Bewegungen möglich"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Tippen, Wischen, Zusammenziehen und andere Bewegungen möglich."</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"Bewegungen auf dem Fingerabdrucksensor"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"Erfasst Bewegungen auf dem Fingerabdrucksensor des Geräts."</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"Statusleiste deaktivieren oder ändern"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"Ermöglicht der App, die Statusleiste zu deaktivieren oder Systemsymbole hinzuzufügen oder zu entfernen"</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"Statusleiste darstellen"</string>
@@ -1146,6 +1148,7 @@
<string name="usb_notification_message" msgid="3370903770828407960">"Für weitere Optionen tippen."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB-Debugging aktiviert"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Zum Deaktivieren von USB-Debugging tippen."</string>
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB-Debugging deaktivieren: auswählen"</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Fehlerbericht wird abgerufen…"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Fehlerbericht teilen?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Fehlerbericht wird geteilt…"</string>
@@ -1689,4 +1692,7 @@
<string name="app_category_news" msgid="7496506240743986873">"Nachrichten & Zeitschriften"</string>
<string name="app_category_maps" msgid="5878491404538024367">"Karten & Navigation"</string>
<string name="app_category_productivity" msgid="3742083261781538852">"Effizienz"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"Gerätespeicher"</string>
+ <!-- no translation found for adb_debugging_notification_channel_tv (5537766997350092316) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-el-watch/styles_material.xml b/core/res/res/values-el-watch/styles_material.xml
deleted file mode 100644
index a02b85e..0000000
--- a/core/res/res/values-el-watch/styles_material.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 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.
- -->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see styles_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"υποψήφιοι"</font></string>
-</resources>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 409b573..7458e04 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -278,6 +278,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Ελέγξτε το επίπεδο ζουμ και τη θέση της οθόνης."</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Εκτέλεση κινήσεων"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Επιτρέπει το πάτημα, την ολίσθηση, το πλησίασμα και άλλες κινήσεις."</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"Κινήσεις δακτυλικών αποτυπωμάτων"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"Μπορεί να αναγνωρίσει κινήσεις που εκτελούνται στον αισθητήρα δακτυλικών αποτυπωμάτων των συσκευών."</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"απενεργοποιεί ή να τροποποιεί την γραμμή κατάστασης"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"Επιτρέπει στην εφαρμογή να απενεργοποιεί τη γραμμή κατάστασης ή να προσθέτει και να αφαιρεί εικονίδια συστήματος."</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"ορίζεται ως γραμμή κατάστασης"</string>
@@ -1146,6 +1148,7 @@
<string name="usb_notification_message" msgid="3370903770828407960">"Πατήστε για περισσότερες επιλογές."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"Συνδέθηκε ο εντοπισμός σφαλμάτων USB"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Πατήστε για απενεργοποίηση του εντοπισμού σφαλμάτων USB."</string>
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Επιλογή για απενεργοποίηση του εντοπισμού σφαλμάτων USB."</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Λήψη αναφοράς σφάλματος…"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Κοινή χρήση αναφοράς σφάλματος;"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Κοινή χρήση αναφοράς σφάλματος…"</string>
@@ -1689,4 +1692,7 @@
<string name="app_category_news" msgid="7496506240743986873">"Ειδήσεις και περιοδικά"</string>
<string name="app_category_maps" msgid="5878491404538024367">"Χάρτες και πλοήγηση"</string>
<string name="app_category_productivity" msgid="3742083261781538852">"Παραγωγικότητα"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"Αποθηκευτικός χώρος συσκευής"</string>
+ <!-- no translation found for adb_debugging_notification_channel_tv (5537766997350092316) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-en-rAU-watch/styles_material.xml b/core/res/res/values-en-rAU-watch/styles_material.xml
deleted file mode 100644
index 36a459d..0000000
--- a/core/res/res/values-en-rAU-watch/styles_material.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 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.
- -->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see styles_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"candidates"</font></string>
-</resources>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index 02860cf..107f247 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -278,6 +278,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Control the display\'s zoom level and positioning."</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Perform gestures"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Can tap, swipe, pinch and perform other gestures."</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"Fingerprint gestures"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"Can capture gestures performed on the devices fingerprint sensor."</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"disable or modify status bar"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"Allows the app to disable the status bar or add and remove system icons."</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"be the status bar"</string>
@@ -1146,6 +1148,7 @@
<string name="usb_notification_message" msgid="3370903770828407960">"Tap for more options."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB debugging connected"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Tap to disable USB debugging."</string>
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Select to disable USB debugging."</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Taking bug report…"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Share bug report?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Sharing bug report…"</string>
@@ -1689,4 +1692,7 @@
<string name="app_category_news" msgid="7496506240743986873">"News & Magazines"</string>
<string name="app_category_maps" msgid="5878491404538024367">"Maps & Navigation"</string>
<string name="app_category_productivity" msgid="3742083261781538852">"Productivity"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"Device storage"</string>
+ <!-- no translation found for adb_debugging_notification_channel_tv (5537766997350092316) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-en-rGB-watch/styles_material.xml b/core/res/res/values-en-rGB-watch/styles_material.xml
deleted file mode 100644
index 36a459d..0000000
--- a/core/res/res/values-en-rGB-watch/styles_material.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 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.
- -->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see styles_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"candidates"</font></string>
-</resources>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 02860cf..107f247 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -278,6 +278,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Control the display\'s zoom level and positioning."</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Perform gestures"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Can tap, swipe, pinch and perform other gestures."</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"Fingerprint gestures"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"Can capture gestures performed on the devices fingerprint sensor."</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"disable or modify status bar"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"Allows the app to disable the status bar or add and remove system icons."</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"be the status bar"</string>
@@ -1146,6 +1148,7 @@
<string name="usb_notification_message" msgid="3370903770828407960">"Tap for more options."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB debugging connected"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Tap to disable USB debugging."</string>
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Select to disable USB debugging."</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Taking bug report…"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Share bug report?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Sharing bug report…"</string>
@@ -1689,4 +1692,7 @@
<string name="app_category_news" msgid="7496506240743986873">"News & Magazines"</string>
<string name="app_category_maps" msgid="5878491404538024367">"Maps & Navigation"</string>
<string name="app_category_productivity" msgid="3742083261781538852">"Productivity"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"Device storage"</string>
+ <!-- no translation found for adb_debugging_notification_channel_tv (5537766997350092316) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-en-rIN-watch/styles_material.xml b/core/res/res/values-en-rIN-watch/styles_material.xml
deleted file mode 100644
index 36a459d..0000000
--- a/core/res/res/values-en-rIN-watch/styles_material.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 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.
- -->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see styles_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"candidates"</font></string>
-</resources>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index 02860cf..107f247 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -278,6 +278,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Control the display\'s zoom level and positioning."</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Perform gestures"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Can tap, swipe, pinch and perform other gestures."</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"Fingerprint gestures"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"Can capture gestures performed on the devices fingerprint sensor."</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"disable or modify status bar"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"Allows the app to disable the status bar or add and remove system icons."</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"be the status bar"</string>
@@ -1146,6 +1148,7 @@
<string name="usb_notification_message" msgid="3370903770828407960">"Tap for more options."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB debugging connected"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Tap to disable USB debugging."</string>
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Select to disable USB debugging."</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Taking bug report…"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Share bug report?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Sharing bug report…"</string>
@@ -1689,4 +1692,7 @@
<string name="app_category_news" msgid="7496506240743986873">"News & Magazines"</string>
<string name="app_category_maps" msgid="5878491404538024367">"Maps & Navigation"</string>
<string name="app_category_productivity" msgid="3742083261781538852">"Productivity"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"Device storage"</string>
+ <!-- no translation found for adb_debugging_notification_channel_tv (5537766997350092316) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-es-rUS-watch/styles_material.xml b/core/res/res/values-es-rUS-watch/styles_material.xml
deleted file mode 100644
index 898d2fd..0000000
--- a/core/res/res/values-es-rUS-watch/styles_material.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 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.
- -->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see styles_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"candidatos"</font></string>
-</resources>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index bd3ac31..2749b35 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -278,6 +278,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Controla el posicionamiento y el nivel de zoom de la pantalla."</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Usar gestos"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Permite presionar, deslizar, pellizcar y usar otros gestos."</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"Gestos del sensor de huellas digitales"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"Captura los gestos que se hacen en el sensor de huellas digitales de los dispositivos."</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"desactivar o modificar la barra de estado"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"Permite que la aplicación inhabilite la barra de estado o que agregue y elimine íconos del sistema."</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"aparecer en la barra de estado"</string>
@@ -1146,6 +1148,7 @@
<string name="usb_notification_message" msgid="3370903770828407960">"Presiona para ver más opciones."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"Depuración por USB conectada"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Presiona para inhabilitar la depuración por USB."</string>
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Seleccionar para desactivar la depuración por USB"</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Realizando un informe de errores…"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"¿Compartir informe de errores?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Compartiendo informe de errores…"</string>
@@ -1689,4 +1692,7 @@
<string name="app_category_news" msgid="7496506240743986873">"Noticias y revistas"</string>
<string name="app_category_maps" msgid="5878491404538024367">"Mapas y navegación"</string>
<string name="app_category_productivity" msgid="3742083261781538852">"Productividad"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"Almacenamiento del dispositivo"</string>
+ <!-- no translation found for adb_debugging_notification_channel_tv (5537766997350092316) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-es-watch/styles_material.xml b/core/res/res/values-es-watch/styles_material.xml
deleted file mode 100644
index 898d2fd..0000000
--- a/core/res/res/values-es-watch/styles_material.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 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.
- -->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see styles_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"candidatos"</font></string>
-</resources>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 26f6005..bdb1381 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -278,6 +278,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Controla el posicionamiento y el nivel de zoom de la pantalla."</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Realizar gestos"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Puedes tocar y pellizcar la pantalla, deslizar el dedo y hacer otros gestos."</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"Gestos de huellas digitales"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"Puede capturar los gestos realizados en el sensor de huellas digitales del dispositivo."</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"inhabilitar o modificar la barra de estado"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"Permite que la aplicación inhabilite la barra de estado o añada y elimine iconos del sistema."</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"aparecer en la barra de estado"</string>
@@ -949,12 +951,9 @@
<string name="deleteText" msgid="6979668428458199034">"Eliminar"</string>
<string name="inputMethod" msgid="1653630062304567879">"Método de introducción de texto"</string>
<string name="editTextMenuTitle" msgid="4909135564941815494">"Acciones de texto"</string>
- <!-- no translation found for email (4560673117055050403) -->
- <skip />
- <!-- no translation found for dial (2275093056198652749) -->
- <skip />
- <!-- no translation found for map (5441053548030107189) -->
- <skip />
+ <string name="email" msgid="4560673117055050403">"Correo electrónico"</string>
+ <string name="dial" msgid="2275093056198652749">"Marcar"</string>
+ <string name="map" msgid="5441053548030107189">"Mapa"</string>
<string name="low_internal_storage_view_title" msgid="5576272496365684834">"Queda poco espacio"</string>
<string name="low_internal_storage_view_text" msgid="6640505817617414371">"Es posible que algunas funciones del sistema no funcionen."</string>
<string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"No hay espacio suficiente para el sistema. Comprueba que haya 250 MB libres y reinicia el dispositivo."</string>
@@ -1149,6 +1148,7 @@
<string name="usb_notification_message" msgid="3370903770828407960">"Toca para ver más opciones."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"Depuración USB habilitada"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Toca para inhabilitar la depuración USB."</string>
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Seleccionar para inhabilitar la depuración USB"</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Creando informe de errores…"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"¿Compartir informe de errores?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Compartiendo informe de errores…"</string>
@@ -1205,10 +1205,8 @@
<string name="permdesc_readInstallSessions" msgid="2049771699626019849">"Permite que una aplicación consulte sesiones de instalación para ver detalles sobre instalaciones de paquetes activos."</string>
<string name="permlab_requestInstallPackages" msgid="5782013576218172577">"solicitar instalación de paquetes"</string>
<string name="permdesc_requestInstallPackages" msgid="5740101072486783082">"Permite a una aplicación solicitar la instalación de paquetes."</string>
- <!-- no translation found for permlab_requestDeletePackages (1703686454657781242) -->
- <skip />
- <!-- no translation found for permdesc_requestDeletePackages (3406172963097595270) -->
- <skip />
+ <string name="permlab_requestDeletePackages" msgid="1703686454657781242">"solicitar eliminación de paquetes"</string>
+ <string name="permdesc_requestDeletePackages" msgid="3406172963097595270">"Permite a una aplicación solicitar la eliminación de paquetes."</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="8021256345643918264">"solicitar permiso para ignorar las optimizaciones de la batería"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="8359147856007447638">"Permite que una aplicación solicite permiso para ignorar las optimizaciones de la batería."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1311810005957319690">"Da dos toques para acceder al control de zoom."</string>
@@ -1694,4 +1692,7 @@
<string name="app_category_news" msgid="7496506240743986873">"Noticias y revistas"</string>
<string name="app_category_maps" msgid="5878491404538024367">"Mapas y navegación"</string>
<string name="app_category_productivity" msgid="3742083261781538852">"Productividad"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"Almacenamiento del dispositivo"</string>
+ <!-- no translation found for adb_debugging_notification_channel_tv (5537766997350092316) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-et-watch/styles_material.xml b/core/res/res/values-et-watch/styles_material.xml
deleted file mode 100644
index 36a459d..0000000
--- a/core/res/res/values-et-watch/styles_material.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 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.
- -->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see styles_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"candidates"</font></string>
-</resources>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index 30e73d8..5b532b4 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -278,6 +278,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Saate juhtida ekraani suumitaset ja asendit."</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Liigutuste tegemine"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Saate puudutada, pühkida, sõrmi kokku-lahku liigutada ja teisi liigutusi teha."</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"Sõrmejälje liigutused"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"Teil on võimalik jäädvustada liigutused, mis on tehtud seadmete sõrmejäljeanduri abil."</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"keela või muuda olekuriba"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"Võimaldab rakendusel keelata olekuriba või lisada ja eemaldada süsteemiikoone."</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"olekuribana kuvamine"</string>
@@ -1146,6 +1148,7 @@
<string name="usb_notification_message" msgid="3370903770828407960">"Puudutage lisavalikute nägemiseks."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB-silumine ühendatud"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Puudutage USB-silumise keelamiseks."</string>
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Valige USB silumise keelamiseks"</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Veaaruande võtmine …"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Kas jagada veaaruannet?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Veaaruande jagamine …"</string>
@@ -1689,4 +1692,7 @@
<string name="app_category_news" msgid="7496506240743986873">"Uudised ja ajakirjad"</string>
<string name="app_category_maps" msgid="5878491404538024367">"Kaardid ja navigeerimine"</string>
<string name="app_category_productivity" msgid="3742083261781538852">"Produktiivsus"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"Seadme salvestusruum"</string>
+ <!-- no translation found for adb_debugging_notification_channel_tv (5537766997350092316) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-eu-watch/styles_material.xml b/core/res/res/values-eu-watch/styles_material.xml
deleted file mode 100644
index 36a459d..0000000
--- a/core/res/res/values-eu-watch/styles_material.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 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.
- -->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see styles_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"candidates"</font></string>
-</resources>
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index a49f94f..afb0a9c 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -278,6 +278,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Kontrolatu pantailaren zoom-maila eta kokapena."</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Keinuak egin"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Sakatu, lerratu, atximurkatu eta beste hainbat keinu egin ditzake."</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"Hatz-marken keinuak"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"Gailuaren hatz-marken sentsorean egindako keinuak antzeman ditzake."</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"Desgaitu edo aldatu egoera-barra"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"Egoera-barra desgaitzea edo sistema-ikonoak gehitzea edo kentzea baimentzen die aplikazioei."</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"Bihurtu egoera-barra"</string>
@@ -1146,6 +1148,8 @@
<string name="usb_notification_message" msgid="3370903770828407960">"Sakatu aukera gehiago ikusteko."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB arazketa konektatuta"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Sakatu USB arazketa desgaitzeko."</string>
+ <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
+ <skip />
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Akatsen txostena sortzen…"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Akatsen txostena partekatu nahi duzu?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Akatsen txostena partekatzen…"</string>
@@ -1232,7 +1236,7 @@
<string name="wallpaper_binding_label" msgid="1240087844304687662">"Horma-papera"</string>
<string name="chooser_wallpaper" msgid="7873476199295190279">"Aldatu horma-papera"</string>
<string name="notification_listener_binding_label" msgid="2014162835481906429">"Jakinarazpenak hautemateko zerbitzua"</string>
- <string name="vr_listener_binding_label" msgid="4316591939343607306">"Errealitate birtualeko hautemailea"</string>
+ <string name="vr_listener_binding_label" msgid="4316591939343607306">"EB hautemailea"</string>
<string name="condition_provider_service_binding_label" msgid="1321343352906524564">"Baldintza-hornitzailea"</string>
<string name="notification_ranker_binding_label" msgid="774540592299064747">"Jakinarazpenen sailkapen-zerbitzua"</string>
<string name="vpn_title" msgid="19615213552042827">"VPN eginbidea aktibatuta"</string>
@@ -1689,4 +1693,7 @@
<string name="app_category_news" msgid="7496506240743986873">"Albisteak eta aldizkariak"</string>
<string name="app_category_maps" msgid="5878491404538024367">"Mapak eta nabigazioa"</string>
<string name="app_category_productivity" msgid="3742083261781538852">"Produktibitatea"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"Gailuaren memoria"</string>
+ <!-- no translation found for adb_debugging_notification_channel_tv (5537766997350092316) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-fa-watch/styles_material.xml b/core/res/res/values-fa-watch/styles_material.xml
deleted file mode 100644
index 23b9a7e..0000000
--- a/core/res/res/values-fa-watch/styles_material.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 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.
- -->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see styles_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"کاندیدها"</font></string>
-</resources>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 3880caa..1e1c8fa 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -278,6 +278,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"سطح و موقعیت بزرگنمایی نمایشگر را کنترل کنید."</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"اجرای اشارهها"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"میتوانید ضربه بزنید، انگشتتان را تند بکشید، انگشتانتان را به هم نزدیک یا از هم دور کنید و اشارههای دیگری اجرا کنید."</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"اشارههای اثر انگشت"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"میتواند اشارههای انجامشده روی حسگر اثرانگشت دستگاهها را ثبت کند."</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"غیرفعال کردن یا تغییر نوار وضعیت"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"به برنامه اجازه میدهد تا نوار وضعیت را غیرفعال کند یا نمادهای سیستم را اضافه یا حذف کند."</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"نوار وضعیت باشد"</string>
@@ -1146,6 +1148,7 @@
<string name="usb_notification_message" msgid="3370903770828407960">"برای گزینههای بیشتر ضربه بزنید."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"اشکالزدایی USB متصل شد"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"برای غیرفعال کردن اشکالزدایی USB ضربه بزنید."</string>
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"انتخاب کنید تا رفع عیب USB غیرفعال شود."</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"درحال گرفتن گزارش اشکال…"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"گزارش اشکال به اشتراک گذاشته شود؟"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"درحال اشتراکگذاری گزارش اشکال…"</string>
@@ -1689,4 +1692,7 @@
<string name="app_category_news" msgid="7496506240743986873">"اخبار و مجله"</string>
<string name="app_category_maps" msgid="5878491404538024367">"نقشه و پیمایش"</string>
<string name="app_category_productivity" msgid="3742083261781538852">"بهرهوری"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"حافظه دستگاه"</string>
+ <!-- no translation found for adb_debugging_notification_channel_tv (5537766997350092316) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-fi-watch/styles_material.xml b/core/res/res/values-fi-watch/styles_material.xml
deleted file mode 100644
index 36a459d..0000000
--- a/core/res/res/values-fi-watch/styles_material.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 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.
- -->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see styles_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"candidates"</font></string>
-</resources>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index f0afbc8..c3c2c65 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -278,6 +278,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Hallinnoi näytön zoomaustasoa ja asettelua."</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Eleiden käyttäminen"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Lupa napauttaa, pyyhkäistä, nipistää ja käyttää muita eleitä."</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"Sormenjälkieleet"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"Voi tallentaa laitteen sormenjälkitunnistimella tehtyjä eleitä."</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"poista tilapalkki käytöstä tai muokkaa tilapalkkia"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"Antaa sovelluksen poistaa tilapalkin käytöstä ja lisätä tai poistaa järjestelmäkuvakkeita."</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"sijaita tilapalkissa"</string>
@@ -1146,6 +1148,7 @@
<string name="usb_notification_message" msgid="3370903770828407960">"Näet lisää vaihtoehtoja napauttamalla."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB-vianetsintä yhdistetty"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Poista USB-vianetsintä käytöstä napauttamalla."</string>
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Poista USB-vianetsintä käytöstä valitsemalla tämä."</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Luodaan virheraporttia…"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Jaetaanko virheraportti?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Jaetaan virheraporttia…"</string>
@@ -1689,4 +1692,7 @@
<string name="app_category_news" msgid="7496506240743986873">"Uutiset ja lehdet"</string>
<string name="app_category_maps" msgid="5878491404538024367">"Kartat ja navigointi"</string>
<string name="app_category_productivity" msgid="3742083261781538852">"Tuottavuus"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"Laitteen tallennustila"</string>
+ <!-- no translation found for adb_debugging_notification_channel_tv (5537766997350092316) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-fr-rCA-watch/styles_material.xml b/core/res/res/values-fr-rCA-watch/styles_material.xml
deleted file mode 100644
index f692d5c..0000000
--- a/core/res/res/values-fr-rCA-watch/styles_material.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 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.
- -->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see styles_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"candidats"</font></string>
-</resources>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 65609f4..7e051c9 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -278,6 +278,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Contrôler le niveau de zoom et le positionnement de l\'écran."</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Effectuer des gestes"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Peut toucher, balayer, pincer et effectuer d\'autres gestes."</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"Gestes sur le capteur d\'empreintes digitales"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"Peut capturer des gestes effectués sur le capteur d\'empreintes digitales des appareils."</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"désactiver ou modifier la barre d\'état"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"Permet à l\'application de désactiver la barre d\'état, ou d\'ajouter et de supprimer des icônes système."</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"servir de barre d\'état"</string>
@@ -1146,6 +1148,7 @@
<string name="usb_notification_message" msgid="3370903770828407960">"Touchez pour afficher plus d\'options."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"Débogage USB connecté"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Touchez pour désactiver le débogage USB."</string>
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Sélectionnez cette option pour désactiver le débogage USB."</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Création d\'un rapport de bogue en cours..."</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Partager le rapport de bogue?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Partage du rapport de bogue en cours..."</string>
@@ -1689,4 +1692,7 @@
<string name="app_category_news" msgid="7496506240743986873">"Actualités et magazines"</string>
<string name="app_category_maps" msgid="5878491404538024367">"Cartes et navigation"</string>
<string name="app_category_productivity" msgid="3742083261781538852">"Productivité"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"Mémoire de l\'appareil"</string>
+ <!-- no translation found for adb_debugging_notification_channel_tv (5537766997350092316) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-fr-watch/styles_material.xml b/core/res/res/values-fr-watch/styles_material.xml
deleted file mode 100644
index f692d5c..0000000
--- a/core/res/res/values-fr-watch/styles_material.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 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.
- -->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see styles_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"candidats"</font></string>
-</resources>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 66fb5b4..b8fcf28 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -278,6 +278,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Contrôler le niveau de zoom et le positionnement de l\'écran"</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Effectuer des gestes"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Permet d\'appuyer sur l\'écran, de le balayer, de le pincer et d\'effectuer d\'autres gestes."</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"Gestes avec l\'empreinte digitale"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"Peut enregistrer des gestes effectués sur le lecteur d\'empreinte digitale de l\'appareil."</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"Désactivation ou modification de la barre d\'état"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"Permet à l\'application de désactiver la barre d\'état, ou d\'ajouter et de supprimer des icônes système."</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"remplacer la barre d\'état"</string>
@@ -1146,6 +1148,7 @@
<string name="usb_notification_message" msgid="3370903770828407960">"Appuyez ici pour plus d\'options."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"Débogage USB activé"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Appuyez ici pour désactiver le débogage USB."</string>
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Sélectionnez cette option pour désactiver le débogage USB."</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Création du rapport de bug…"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Partager le rapport de bug ?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Partage du rapport de bug…"</string>
@@ -1689,4 +1692,7 @@
<string name="app_category_news" msgid="7496506240743986873">"Actualités et magazines"</string>
<string name="app_category_maps" msgid="5878491404538024367">"Plans et navigation"</string>
<string name="app_category_productivity" msgid="3742083261781538852">"Productivité"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"Mémoire de l\'appareil"</string>
+ <!-- no translation found for adb_debugging_notification_channel_tv (5537766997350092316) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-gl-watch/styles_material.xml b/core/res/res/values-gl-watch/styles_material.xml
deleted file mode 100644
index 898d2fd..0000000
--- a/core/res/res/values-gl-watch/styles_material.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 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.
- -->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see styles_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"candidatos"</font></string>
-</resources>
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index 9b335a1..5d316f6 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -278,6 +278,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Controlar o nivel do zoom e o posicionamento da pantalla"</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Realizar xestos"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Podes tocar, pasar o dedo, beliscar e realizar outros xestos."</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"Xestos de impresión dixital"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"Pode rexistrar os xestos realizados no sensor de impresión dixital dos dispositivos."</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"desactivar ou modificar a barra de estado"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"Permite á aplicación desactivar a barra de estado ou engadir e eliminar as iconas do sistema."</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"actuar como a barra de estado"</string>
@@ -1146,6 +1148,8 @@
<string name="usb_notification_message" msgid="3370903770828407960">"Toca para ver máis opcións."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"Depuración USB conectada"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Toca para desactivar a depuración de erros de USB."</string>
+ <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
+ <skip />
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Creando informe de erros…"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Queres compartir o informe de erros?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Compartindo informe de erros..."</string>
@@ -1689,4 +1693,7 @@
<string name="app_category_news" msgid="7496506240743986873">"Noticias e revistas"</string>
<string name="app_category_maps" msgid="5878491404538024367">"Mapas e navegación"</string>
<string name="app_category_productivity" msgid="3742083261781538852">"Produtividade"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"Almacenamento do dispositivo"</string>
+ <!-- no translation found for adb_debugging_notification_channel_tv (5537766997350092316) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-gu-watch/styles_material.xml b/core/res/res/values-gu-watch/styles_material.xml
deleted file mode 100644
index 21c6871..0000000
--- a/core/res/res/values-gu-watch/styles_material.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 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.
- -->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see styles_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"ઉમેદવારો"</font></string>
-</resources>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index 2bd3e41..b5c243b 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -278,6 +278,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"પ્રદર્શનનું ઝૂમ સ્તર અને સ્થિતિનિર્ધારણ નિયંત્રિત કરો."</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"હાવભાવ કરો"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"ટૅપ, સ્વાઇપ, પિંચ કરી અને અન્ય હાવભાવ કરી શકે છે."</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"ફિંગરપ્રિન્ટ હાવભાવો"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"ઉપકરણોનાં ફિંગરપ્રિન્ટ સેન્સર પર ભજવેલા હાવભાવ કૅપ્ચર કરી શકે છે."</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"સ્થિતિ બાર અક્ષમ કરો અથવા સંશોધિત કરો"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"એપ્લિકેશનને સ્થિતિ બાર અક્ષમ કરવાની અથવા સિસ્ટમ આયકન્સ ઉમેરવા અને દૂર કરવાની મંજૂરી આપે છે."</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"સ્થિતિ બાર થાઓ"</string>
@@ -1146,6 +1148,8 @@
<string name="usb_notification_message" msgid="3370903770828407960">"વધુ વિકલ્પો માટે ટૅપ કરો."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB ડીબગિંગ કનેક્ટ થયું."</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"USB ડીબગિંગ અક્ષમ કરવા માટે ટૅપ કરો."</string>
+ <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
+ <skip />
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"બગ રિપોર્ટ લઈ રહ્યાં છે…"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"બગ રિપોર્ટ શેર કરીએ?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"બગ રિપોર્ટ શેર કરી રહ્યાં છે…"</string>
@@ -1689,4 +1693,7 @@
<string name="app_category_news" msgid="7496506240743986873">"સમાચાર અને સામાયિકો"</string>
<string name="app_category_maps" msgid="5878491404538024367">"નકશા અને નેવિગેશન"</string>
<string name="app_category_productivity" msgid="3742083261781538852">"ઉત્પાદકતા"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"ઉપકરણ સ્ટૉરેજ"</string>
+ <!-- no translation found for adb_debugging_notification_channel_tv (5537766997350092316) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-hi-watch/styles_material.xml b/core/res/res/values-hi-watch/styles_material.xml
deleted file mode 100644
index 36a459d..0000000
--- a/core/res/res/values-hi-watch/styles_material.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 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.
- -->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see styles_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"candidates"</font></string>
-</resources>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 6300703..f2c3d43 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -278,6 +278,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"प्रदर्शन का ज़ूम स्तर और स्थिति निर्धारण नियंत्रित करें."</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"हावभाव निष्पादित करें"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"इस सेवा के द्वारा टैप किया जा सकता है, स्वाइप किया जा सकता है, पिंच किया जा सकता है और अन्य हावभाव निष्पादित किए जा सकते हैं."</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"फ़िंगरप्रिंट हावभाव"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"डिवाइस फ़िंगरप्रिंट सेंसर पर किए गए हावभाव कैप्चर किए जा सकते हैं."</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"स्थिति बार अक्षम या बदलें"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"ऐप्स को स्थिति बार अक्षम करने या सिस्टम आइकन को जोड़ने या निकालने देता है."</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"स्थिति बार होने दें"</string>
@@ -951,7 +953,7 @@
<string name="editTextMenuTitle" msgid="4909135564941815494">"लेख क्रियाएं"</string>
<string name="email" msgid="4560673117055050403">"ईमेल करें"</string>
<string name="dial" msgid="2275093056198652749">"डायल करें"</string>
- <string name="map" msgid="5441053548030107189">"नक्शा"</string>
+ <string name="map" msgid="5441053548030107189">"मानचित्र"</string>
<string name="low_internal_storage_view_title" msgid="5576272496365684834">"मेमोरी स्थान समाप्त हो रहा है"</string>
<string name="low_internal_storage_view_text" msgid="6640505817617414371">"हो सकता है कुछ सिस्टम फ़ंक्शन कार्य न करें"</string>
<string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"सिस्टम के लिए पर्याप्त मेमोरी नहीं है. सुनिश्चित करें कि आपके पास 250MB का खाली स्थान है और फिर से प्रारंभ करें."</string>
@@ -1146,6 +1148,7 @@
<string name="usb_notification_message" msgid="3370903770828407960">"अधिक विकल्पों के लिए टैप करें."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB डीबग कनेक्ट किया गया"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"USB डीबग करना अक्षम करने के लिए टैप करें."</string>
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB डीबग करना अक्षम करने के लिए चुनें."</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"बग रिपोर्ट प्राप्त की जा रही है…"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"बग रिपोर्ट साझा करें?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"बग रिपोर्ट साझा की जा रही है…"</string>
@@ -1689,4 +1692,7 @@
<string name="app_category_news" msgid="7496506240743986873">"समाचार और पत्रिकाएं"</string>
<string name="app_category_maps" msgid="5878491404538024367">"मानचित्र और मार्गदर्शक"</string>
<string name="app_category_productivity" msgid="3742083261781538852">"उत्पादकता"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"डिवाइस में जगह"</string>
+ <!-- no translation found for adb_debugging_notification_channel_tv (5537766997350092316) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-hr-watch/styles_material.xml b/core/res/res/values-hr-watch/styles_material.xml
deleted file mode 100644
index 88e5751..0000000
--- a/core/res/res/values-hr-watch/styles_material.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 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.
- -->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see styles_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"kandidati"</font></string>
-</resources>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index ee3ab30..11864c6 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -281,6 +281,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Kontrolira razinu zumiranja i položaj zaslona."</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Izvođenje pokreta"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Može dodirnuti, prijeći prstom, spojiti prste i izvoditi druge pokrete."</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"Pokreti za otisak prsta"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"Može snimati pokrete izvršene na senzoru otiska prsta na uređaju."</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"onemogućavanje ili izmjena trake statusa"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"Aplikaciji omogućuje onemogućavanje trake statusa ili dodavanje i uklanjanje sistemskih ikona."</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"biti traka statusa"</string>
@@ -1166,6 +1168,7 @@
<string name="usb_notification_message" msgid="3370903770828407960">"Dodirnite za više opcija."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"Priključen je alat za otklanjanje pogrešaka USB-om"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Dodirnite da biste onemogućili otklanjanje pogrešaka putem USB-a."</string>
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Odaberite da biste onemogućili rješavanje programske pogreške na USB-u."</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Izrada izvješća o programskoj pogrešci…"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Želite li podijeliti izvješće o programskoj pogrešci?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Dijeljenje izvješća o programskoj pogrešci…"</string>
@@ -1720,4 +1723,7 @@
<string name="app_category_news" msgid="7496506240743986873">"Vijesti i časopisi"</string>
<string name="app_category_maps" msgid="5878491404538024367">"Karte i navigacija"</string>
<string name="app_category_productivity" msgid="3742083261781538852">"Produktivnost"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"Pohrana na uređaju"</string>
+ <!-- no translation found for adb_debugging_notification_channel_tv (5537766997350092316) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-hu-watch/styles_material.xml b/core/res/res/values-hu-watch/styles_material.xml
deleted file mode 100644
index 36a459d..0000000
--- a/core/res/res/values-hu-watch/styles_material.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 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.
- -->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see styles_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"candidates"</font></string>
-</resources>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 943dbc0..4c6d440 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -278,6 +278,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"A kijelző nagyítási/kicsinyítési szintjének és pozíciójának vezérlése"</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Kézmozdulatok végrehajtása"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Koppintás, ujjak gyors csúsztatása és összehúzása, illetve egyéb kézmozdulatok végrehajtása."</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"Kézmozdulatok az ujjlenyomat-érzékelőn"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"Érzékeli az ujjlenyomat-érzékelőn végzett kézmozdulatokat."</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"állapotsor kikapcsolása vagy módosítása"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"Lehetővé teszi az alkalmazás számára az állapotsor kikapcsolását, illetve rendszerikonok hozzáadását és eltávolítását."</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"az állapotsor szerepének átvétele"</string>
@@ -1146,6 +1148,7 @@
<string name="usb_notification_message" msgid="3370903770828407960">"Koppintson a további beállítások megjelenítéséhez."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB hibakereső csatlakoztatva"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Koppintson az USB fejlesztő mód kikapcsolásához."</string>
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Válassza ezt az USB hibakeresés kikapcsolásához."</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Hibajelentés készítése…"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Megosztja a hibajelentést?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Hibajelentés megosztása…"</string>
@@ -1689,4 +1692,7 @@
<string name="app_category_news" msgid="7496506240743986873">"Hírlapok és folyóiratok"</string>
<string name="app_category_maps" msgid="5878491404538024367">"Térképek és navigáció"</string>
<string name="app_category_productivity" msgid="3742083261781538852">"Irodai alkalmazások"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"Eszköztárhely"</string>
+ <!-- no translation found for adb_debugging_notification_channel_tv (5537766997350092316) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-hy-watch/styles_material.xml b/core/res/res/values-hy-watch/styles_material.xml
deleted file mode 100644
index 36a459d..0000000
--- a/core/res/res/values-hy-watch/styles_material.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 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.
- -->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see styles_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"candidates"</font></string>
-</resources>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index 7c579d1..276a326 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -278,6 +278,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Ցուցասարքի մասշտաբավորման և դիրքավորման կառավարում:"</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Կատարել ժեստեր"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Կարող է հպել, թերթել, պտղունցել և կատարել այլ ժեստեր:"</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"Մատնահետքերի սկաների ժեստեր"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"Կարող է նկարահանել մատնահետքերի սկաների վրա կատարվող ժեստերը"</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"անջատել կամ փոփոխել կարգավիճակի գոտին"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"Թույլ է տալիս հավելվածին անջատել կարգավիճակի գոտին կամ ավելացնել ու հեռացնել համակարգի պատկերակները:"</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"լինել կարգավիճակի գոտի"</string>
@@ -1146,6 +1148,7 @@
<string name="usb_notification_message" msgid="3370903770828407960">"Հպեք՝ լրացուցիչ ընտրանքների համար:"</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB վրիպազերծումը միացված է"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Հպեք՝ USB վրիպազերծումն անջատելու համար:"</string>
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Ընտրել` USB կարգաբերումը կասեցնելու համար:"</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Վրիպակի զեկույցի ստեղծում…"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Տրամադրե՞լ վրիպակի զեկույցը:"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Վրիպակի զեկույցի տրամադրում…"</string>
@@ -1689,4 +1692,7 @@
<string name="app_category_news" msgid="7496506240743986873">"Նորություններ և ամսագրեր"</string>
<string name="app_category_maps" msgid="5878491404538024367">"Քարտեզներ և նավարկում"</string>
<string name="app_category_productivity" msgid="3742083261781538852">"Աշխատանք"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"Սարքի հիշողություն"</string>
+ <!-- no translation found for adb_debugging_notification_channel_tv (5537766997350092316) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-in-watch/styles_material.xml b/core/res/res/values-in-watch/styles_material.xml
deleted file mode 100644
index 36a459d..0000000
--- a/core/res/res/values-in-watch/styles_material.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 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.
- -->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see styles_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"candidates"</font></string>
-</resources>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index b9771d6..839fc04 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -278,6 +278,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Mengontrol tingkat zoom dan pemosisian layar."</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Melakukan isyarat"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Dapat mengetuk, menggesek, mencubit, dan melakukan isyarat lainnya."</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"Gestur sidik jari"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"Dapat merekam gestur yang dilakukan di sensor sidik jari perangkat."</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"nonaktifkan atau ubah bilah status"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"Mengizinkan apl menonaktifkan bilah status atau menambah dan menghapus ikon sistem."</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"jadikan bilah status"</string>
@@ -1146,6 +1148,7 @@
<string name="usb_notification_message" msgid="3370903770828407960">"Ketuk untuk opsi lainnya."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"Debugging USB terhubung"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Ketuk untuk menonaktifkan debug USB."</string>
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Pilih untuk menonaktifkan debugging USB."</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Mengambil laporan bug…"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Bagikan laporan bug?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Membagikan laporan bug..."</string>
@@ -1689,4 +1692,7 @@
<string name="app_category_news" msgid="7496506240743986873">"Berita & Majalah"</string>
<string name="app_category_maps" msgid="5878491404538024367">"Peta & Navigasi"</string>
<string name="app_category_productivity" msgid="3742083261781538852">"Produktivitas"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"Penyimpanan perangkat"</string>
+ <!-- no translation found for adb_debugging_notification_channel_tv (5537766997350092316) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-is-watch/styles_material.xml b/core/res/res/values-is-watch/styles_material.xml
deleted file mode 100644
index 36a459d..0000000
--- a/core/res/res/values-is-watch/styles_material.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 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.
- -->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see styles_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"candidates"</font></string>
-</resources>
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index 775c50e..1e2beb0 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -278,6 +278,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Stjórnaðu aðdrætti og afstöðu skjásins."</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Nota bendingar"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Getur ýtt, strokið, fært fingur saman og gert ýmsar aðrar bendingar."</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"Fingrafarabendingar"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"Getur fangað bendingar sem eru gerðar á fingrafaraskynjara tækisins."</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"slökkva á eða breyta stöðustiku"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"Leyfir forriti að slökkva á stöðustikunni eða bæta við og fjarlægja kerfistákn."</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"vera stöðustikan"</string>
@@ -1146,6 +1148,8 @@
<string name="usb_notification_message" msgid="3370903770828407960">"Ýttu til að sjá fleiri valkosti."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB-villuleit tengd"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Ýttu til að slökkva á USB-villuleit."</string>
+ <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
+ <skip />
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Tekur við villutilkynningu…"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Deila villutilkynningu?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Deilir villutilkynningu..."</string>
@@ -1689,4 +1693,7 @@
<string name="app_category_news" msgid="7496506240743986873">"Fréttir og tímarit"</string>
<string name="app_category_maps" msgid="5878491404538024367">"Kort og leiðsögn"</string>
<string name="app_category_productivity" msgid="3742083261781538852">"Aðstoð"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"Geymslurými tækis"</string>
+ <!-- no translation found for adb_debugging_notification_channel_tv (5537766997350092316) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-it-watch/styles_material.xml b/core/res/res/values-it-watch/styles_material.xml
deleted file mode 100644
index 36a459d..0000000
--- a/core/res/res/values-it-watch/styles_material.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 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.
- -->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see styles_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"candidates"</font></string>
-</resources>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index cb4769c..0b7820e 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -278,6 +278,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Controlla il livello di zoom e la posizione del display."</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Esegui gesti"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Consente di toccare, far scorrere, pizzicare ed eseguire altri gesti."</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"Gesti con sensore di impronte digitali"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"È in grado di rilevare i gesti compiuti con il sensore di impronte digitali dei dispositivi."</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"disattivare o modificare la barra di stato"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"Consente all\'applicazione di disattivare la barra di stato o di aggiungere e rimuovere icone di sistema."</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"ruolo di barra di stato"</string>
@@ -1146,6 +1148,7 @@
<string name="usb_notification_message" msgid="3370903770828407960">"Tocca per altre opzioni."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"Debug USB collegato"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Tocca per disattivare il debug USB."</string>
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Seleziona per disattivare il debug USB."</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Recupero della segnalazione di bug…"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Condividere la segnalazione di bug?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Condivisione della segnalazione di bug…"</string>
@@ -1689,4 +1692,7 @@
<string name="app_category_news" msgid="7496506240743986873">"Notizie e riviste"</string>
<string name="app_category_maps" msgid="5878491404538024367">"Maps e Navigatore"</string>
<string name="app_category_productivity" msgid="3742083261781538852">"Produttività"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"Memoria dispositivo"</string>
+ <!-- no translation found for adb_debugging_notification_channel_tv (5537766997350092316) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-iw-watch/styles_material.xml b/core/res/res/values-iw-watch/styles_material.xml
deleted file mode 100644
index f44b272..0000000
--- a/core/res/res/values-iw-watch/styles_material.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 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.
- -->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see styles_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"מועמדים"</font></string>
-</resources>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index d33cd08..4361ff2 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -284,6 +284,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"קבע את המרחק מהתצוגה ואת מיקום התצוגה."</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"ביצוע תנועות"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"יכול להקיש, להחליק, לעשות תנועת צביטה ולבצע תנועות אחרות."</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"תנועות"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"אפשרות לזהות תנועות בזמן נגיעה בחיישן טביעות האצבע של המכשיר"</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"השבת או שנה את שורת המצב"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"מאפשר לאפליקציה להשבית את שורת המצב או להוסיף ולהסיר סמלי מערכת."</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"להיות שורת הסטטוס"</string>
@@ -1186,6 +1188,7 @@
<string name="usb_notification_message" msgid="3370903770828407960">"הקש לקבלת אפשרויות נוספות."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"ניפוי באגים של USB מחובר"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"הקש כדי להשבית ניפוי באגים של USB."</string>
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"בחר להשבית ניפוי באגים ב-USB."</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"עיבוד דוח על באג..."</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"האם לשתף דוח על באג?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"שיתוף דוח על באג…"</string>
@@ -1751,4 +1754,7 @@
<string name="app_category_news" msgid="7496506240743986873">"חדשות וכתבי עת"</string>
<string name="app_category_maps" msgid="5878491404538024367">"מפות וניווט"</string>
<string name="app_category_productivity" msgid="3742083261781538852">"פרודוקטיביות"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"שטח האחסון במכשיר"</string>
+ <!-- no translation found for adb_debugging_notification_channel_tv (5537766997350092316) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ja-watch/styles_material.xml b/core/res/res/values-ja-watch/styles_material.xml
deleted file mode 100644
index 7712090..0000000
--- a/core/res/res/values-ja-watch/styles_material.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 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.
- -->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see styles_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"候補"</font></string>
-</resources>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 3992e6e..f3a22ce 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -278,6 +278,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"画面のズームレベルと位置を制御します。"</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"操作の実行"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"タップ、スワイプ、ピンチ、その他の操作を行えます。"</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"指紋認証センサーでの操作"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"端末の指紋認証センサーで行われた操作をキャプチャできます。"</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"ステータスバーの無効化や変更"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"ステータスバーの無効化、システムアイコンの追加や削除をアプリに許可します。"</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"ステータスバーへの表示"</string>
@@ -1146,6 +1148,7 @@
<string name="usb_notification_message" msgid="3370903770828407960">"タップしてその他のオプションを表示します。"</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USBデバッグが接続されました"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"タップして USB デバッグを無効にします。"</string>
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USBデバッグを無効にする場合に選択します。"</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"バグレポートを取得しています…"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"バグレポートを共有しますか?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"バグレポートの共有中…"</string>
@@ -1689,4 +1692,7 @@
<string name="app_category_news" msgid="7496506240743986873">"ニュース&雑誌"</string>
<string name="app_category_maps" msgid="5878491404538024367">"地図&ナビ"</string>
<string name="app_category_productivity" msgid="3742083261781538852">"仕事効率化"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"端末のストレージ"</string>
+ <!-- no translation found for adb_debugging_notification_channel_tv (5537766997350092316) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ka-watch/styles_material.xml b/core/res/res/values-ka-watch/styles_material.xml
deleted file mode 100644
index 36a459d..0000000
--- a/core/res/res/values-ka-watch/styles_material.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 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.
- -->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see styles_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"candidates"</font></string>
-</resources>
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
index 1fb7d13..9d3b288 100644
--- a/core/res/res/values-ka/strings.xml
+++ b/core/res/res/values-ka/strings.xml
@@ -278,6 +278,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"ეკრანის მასშტაბირების დონისა და პოზიციის მართვა."</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"ჟესტების შესრულება"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"შეუძლია შეხება, გადაფურცვლა, მასშტაბირება და სხვა ჟესტების შესრულება."</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"თითის ანაბეჭდის ჟესტები"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"შეუძლია აღბეჭდოს მოწყობილობის თითის ანაბეჭდის სენსორზე განხორციელებული ჟესტები."</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"სტატუსის ზოლის გათიშვა ან ცვლილება"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"აპს შეეძლება სტატუსების ზოლის გათიშვა და სისტემის ხატულების დამატება/წაშლა."</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"სტატუსის ზოლის ჩანაცვლება"</string>
@@ -1146,6 +1148,7 @@
<string name="usb_notification_message" msgid="3370903770828407960">"შეეხეთ დამატებითი ვარიანტების სანახავად."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB გამართვა შეერთებულია"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"შეეხეთ USB-გამართვის გასათიშად."</string>
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"მონიშნეთ რათა შეწყვიტოთ USB-ის გამართვა"</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"მიმდინარეობს ხარვეზის შესახებ ანგარიშის შექმნა…"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"გსურთ ხარვეზის შესახებ ანგარიშის გაზიარება?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"მიმდინარეობს ხარვეზის შესახებ ანგარიშის გაზიარება…"</string>
@@ -1689,4 +1692,7 @@
<string name="app_category_news" msgid="7496506240743986873">"ახალი ამბები და ჟურნალები"</string>
<string name="app_category_maps" msgid="5878491404538024367">"რუკები და ნავიგაცია"</string>
<string name="app_category_productivity" msgid="3742083261781538852">"პროდუქტიულობა"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"მოწყობილობის მეხსიერება"</string>
+ <!-- no translation found for adb_debugging_notification_channel_tv (5537766997350092316) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-kk-watch/styles_material.xml b/core/res/res/values-kk-watch/styles_material.xml
deleted file mode 100644
index 36a459d..0000000
--- a/core/res/res/values-kk-watch/styles_material.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 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.
- -->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see styles_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"candidates"</font></string>
-</resources>
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index 87958c7..b168b6f 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -278,6 +278,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Дисплейдің масштабтау деңгейін және орналастыруды басқару."</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Қимылдарды орындау"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Түртуге, сырғытуға, қысуға және басқа қимылдарды орындауға болады."</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"Саусақ ізі датчигіндегі қимылдар"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"Құрылғының саусақ ізі датчигінде орындалған қимылдарды сақтайды"</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"күйін көрсету тақтасын өшіру немесе өзгерту"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"Қолданбаға күй жолағын өшіруге немесе жүйелік белгішелерді қосуға және жоюға рұқсат береді."</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"күй жолағы болу"</string>
@@ -1146,6 +1148,8 @@
<string name="usb_notification_message" msgid="3370903770828407960">"Қосымша опциялар үшін түртіңіз."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB жөндеу қосылған"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"USB түзетуін өшіру үшін түртіңіз."</string>
+ <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
+ <skip />
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Қате туралы есеп алынуда…"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Қате туралы есепті бөлісу керек пе?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Қате туралы есеп бөлісілуде…"</string>
@@ -1689,4 +1693,7 @@
<string name="app_category_news" msgid="7496506240743986873">"Газеттер және журналдар"</string>
<string name="app_category_maps" msgid="5878491404538024367">"Карта және навигация"</string>
<string name="app_category_productivity" msgid="3742083261781538852">"Өнімділік"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"Құрылғы жады"</string>
+ <!-- no translation found for adb_debugging_notification_channel_tv (5537766997350092316) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-km-watch/styles_material.xml b/core/res/res/values-km-watch/styles_material.xml
deleted file mode 100644
index e54cb00..0000000
--- a/core/res/res/values-km-watch/styles_material.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 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.
- -->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see styles_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"បេក្ខជន"</font></string>
-</resources>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index f92eff52..0a57834 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -278,6 +278,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"គ្រប់គ្រងការកំណត់ទីតាំង និងកម្រិតពង្រីករបស់អេក្រង់"</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"ធ្វើកាយវិការ"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"អាចប៉ះ អូស ច្បិច និងធ្វើកាយវិការផ្សេងទៀត"</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"ចលនាស្នាមម្រាមដៃ"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"អាចថតចលនាដែលមានសកម្មភាពនៅលើឧបករណ៍ចាប់ស្នាមម្រាមដៃរបស់ឧបករណ៍។"</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"បិទ ឬកែរបារស្ថានភាព"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"ឲ្យកម្មវិធីបិទរបារស្ថានភាព ឬបន្ថែម និងលុបរូបតំណាងប្រព័ន្ធ។"</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"ធ្វើជារបារស្ថានភាព"</string>
@@ -1148,6 +1150,7 @@
<string name="usb_notification_message" msgid="3370903770828407960">"ប៉ះសម្រាប់ជម្រើសជាច្រើនទៀត"</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"បានភ្ជាប់ការកែកំហុសយូអេសប៊ី"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"ប៉ះដើម្បីបិទដំណើរការកែកំហុសយូអេសប៊ី"</string>
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"ជ្រើស ដើម្បីបិទការកែកំហុសយូអេសប៊ី។"</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"កំពុងទទួលយករបាយការណ៍កំហុស…"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"ចែករំលែករបាយការណ៍កំហុសឬ?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"កំពុងចែករំលែករបាយកំហុស…"</string>
@@ -1691,4 +1694,7 @@
<string name="app_category_news" msgid="7496506240743986873">"ព័ត៌មាន និងទស្សនាវដ្ដី"</string>
<string name="app_category_maps" msgid="5878491404538024367">"ផែនទី និងការរុករក"</string>
<string name="app_category_productivity" msgid="3742083261781538852">"ផលិតភាព"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"ទំហំផ្ទុកឧបករណ៍"</string>
+ <!-- no translation found for adb_debugging_notification_channel_tv (5537766997350092316) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-kn-watch/styles_material.xml b/core/res/res/values-kn-watch/styles_material.xml
deleted file mode 100644
index 1ec23a4..0000000
--- a/core/res/res/values-kn-watch/styles_material.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 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.
- -->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see styles_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"ಅಭ್ಯರ್ಥಿಗಳು"</font></string>
-</resources>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index 5c53b1c..07400f5 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -278,6 +278,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"ಪ್ರದರ್ಶನದ ಝೂಮ್ ಮಟ್ಟ ಮತ್ತು ಸ್ಥಾನ ನಿರ್ಧಾರವನ್ನು ನಿಯಂತ್ರಿಸಿ."</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"ಗೆಸ್ಚರ್ಗಳನ್ನು ಮಾಡಿ"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"ಟ್ಯಾಪ್ ಮಾಡಬಹುದು, ಸ್ವೈಪ್ ಮಾಡಬಹುದು, ಪಿಂಚ್ ಮಾಡಬಹುದು ಮತ್ತು ಇತರ ಗೆಸ್ಚರ್ಗಳನ್ನು ಮಾಡಬಹುದು."</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"ಫಿಂಗರ್ಪ್ರಿಂಟ್ ಸೂಚಕಗಳು"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"ಸಾಧನದ ಫಿಂಗರ್ಪ್ರಿಂಟ್ ಸೆನ್ಸರ್ನಲ್ಲಿ ನಡೆಸಿದ ಸೂಚಕಗಳನ್ನು ಕ್ಯಾಪ್ಚರ್ ಮಾಡಿ."</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"ಸ್ಥಿತಿ ಪಟ್ಟಿಯನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿ ಇಲ್ಲವೇ ಮಾರ್ಪಡಿಸಿ"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"ಸ್ಥಿತಿ ಪಟ್ಟಿಯನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲು ಅಥವಾ ಸೇರಿಸಲು ಮತ್ತು ಸಿಸ್ಟಂ ಐಕಾನ್ಗಳನ್ನು ತೆಗೆದುಹಾಕಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅವಕಾಶ ನೀಡುತ್ತದೆ."</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"ಸ್ಥಿತಿ ಪಟ್ಟಿಯಾಗಿರಲು"</string>
@@ -1146,6 +1148,8 @@
<string name="usb_notification_message" msgid="3370903770828407960">"ಹೆಚ್ಚಿನ ಆಯ್ಕೆಗಳಿಗೆ ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB ಡೀಬಗಿಂಗ್ ಸಂಪರ್ಕ"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"USB ಡೀಬಗ್ ಮಾಡುವಿಕೆಯನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
+ <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
+ <skip />
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"ದೋಷದ ವರದಿಯನ್ನು ತೆಗೆದುಕೊಳ್ಳಲಾಗುತ್ತಿದೆ…"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"ಬಗ್ ವರದಿಯನ್ನು ಹಂಚುವುದೇ?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"ಬಗ್ ವರದಿಯನ್ನು ಹಂಚಿಕೊಳ್ಳಲಾಗುತ್ತಿದೆ…"</string>
@@ -1689,4 +1693,7 @@
<string name="app_category_news" msgid="7496506240743986873">"ಸುದ್ದಿ ಮತ್ತು ನಿಯತಕಾಲಿಕೆಗಳು"</string>
<string name="app_category_maps" msgid="5878491404538024367">"ನಕ್ಷೆಗಳು ಮತ್ತು ನ್ಯಾವಿಗೇಶನ್"</string>
<string name="app_category_productivity" msgid="3742083261781538852">"ಉತ್ಪಾದಕತೆ"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"ಸಾಧನ ಸಂಗ್ರಹಣೆ"</string>
+ <!-- no translation found for adb_debugging_notification_channel_tv (5537766997350092316) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ko-watch/styles_material.xml b/core/res/res/values-ko-watch/styles_material.xml
deleted file mode 100644
index 36a459d..0000000
--- a/core/res/res/values-ko-watch/styles_material.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 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.
- -->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see styles_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"candidates"</font></string>
-</resources>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index ca70e45..b74094e 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -278,6 +278,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"디스플레이의 확대/축소 수준 및 위치를 제어합니다."</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"동작 실행"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"탭, 스와이프, 확대/축소 및 기타 동작을 실행할 수 있습니다."</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"지문 동작"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"기기 지문 센서에서 동작을 캡처합니다."</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"상태 표시줄 사용 중지 또는 수정"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"앱이 상태 표시줄을 사용중지하거나 시스템 아이콘을 추가 및 제거할 수 있도록 허용합니다."</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"상태 표시줄에 위치"</string>
@@ -1146,6 +1148,7 @@
<string name="usb_notification_message" msgid="3370903770828407960">"옵션을 더 보려면 탭하세요."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB 디버깅 연결됨"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"USB 디버깅을 사용하지 않으려면 탭하세요."</string>
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB 디버깅을 사용하지 않으려면 선택합니다."</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"버그 보고서 가져오는 중..."</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"버그 보고서를 공유하시겠습니까?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"버그 신고서 공유 중..."</string>
@@ -1689,4 +1692,7 @@
<string name="app_category_news" msgid="7496506240743986873">"뉴스/잡지"</string>
<string name="app_category_maps" msgid="5878491404538024367">"지도/내비게이션"</string>
<string name="app_category_productivity" msgid="3742083261781538852">"생산성"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"기기 저장용량"</string>
+ <!-- no translation found for adb_debugging_notification_channel_tv (5537766997350092316) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ky-watch/styles_material.xml b/core/res/res/values-ky-watch/styles_material.xml
deleted file mode 100644
index 36a459d..0000000
--- a/core/res/res/values-ky-watch/styles_material.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 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.
- -->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see styles_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"candidates"</font></string>
-</resources>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index 94b84f2..7b1d126 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -278,6 +278,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Экрандагы сүрөттүн өлчөмүн өзгөртүү жана жайгаштыруу."</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Жаңсоолорду аткаруу"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Таптап, серпип, чымчып жана башка жаңсоолорду аткара алат."</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"Манжа изинин жаңсоолору"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"Түзмөктөрдөгү манжа изинин сенсорунда жасалган жаңсоолорду жаздырып алат."</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"абал тилкесин өчүрүү же өзгөртүү"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"Колдонмого абал тилкесин өчүрүү же тутум сүрөтчөлөрүн кошуу же алып салуу мүмкүнчүлүгүн берет."</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"абал тилкесинин милдетин аткаруу"</string>
@@ -1146,6 +1148,8 @@
<string name="usb_notification_message" msgid="3370903770828407960">"Кошумча параметрлерди ачуу үчүн таптап коюңуз."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB аркылуу мүчүлүштүктөрдү оңдоо туташтырылган"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"USB арклуу мүчүлштктрдү жоюну өчр үчн тийп коюңуз."</string>
+ <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
+ <skip />
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Мүчүлүштүк тууралуу кабар алынууда…"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Мүчүлүштүк тууралуу баяндама бөлүшүлсүнбү?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Мүчүлүштүк тууралуу баяндама бөлүшүлүүдө…"</string>
@@ -1689,4 +1693,7 @@
<string name="app_category_news" msgid="7496506240743986873">"Жаңылыктар жана журналдар"</string>
<string name="app_category_maps" msgid="5878491404538024367">"Карталар жана чабыттоо"</string>
<string name="app_category_productivity" msgid="3742083261781538852">"Өндүрүш категориясы"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"Түзмөктүн сактагычы"</string>
+ <!-- no translation found for adb_debugging_notification_channel_tv (5537766997350092316) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-lo-watch/styles_material.xml b/core/res/res/values-lo-watch/styles_material.xml
deleted file mode 100644
index 1f845b9..0000000
--- a/core/res/res/values-lo-watch/styles_material.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 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.
- -->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see styles_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"ແຄນດິເດດ"</font></string>
-</resources>
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index 816eea2..5d7b4c3 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -278,6 +278,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"ຄວບຄຸມລະດັບການຊູມ ແລະການວາງຕຳແໜ່ງຂອງຈໍສະແດງຜົນ."</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"ດຳເນີນທ່າທາງຕ່າງໆ"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"ສາມາດແຕະ, ປັດນີ້ວມື, ຢິບນິ້ວມື ແລະ ດຳເນີນທ່າທາງອື່ນ."</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"ທ່າທາງລາຍນິ້ວມື"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"ສາມາດບັນທຶກທ່າທາງທີ່ເກີດຂຶ້ນໃນອຸປະກອນເຊັນເຊີລາຍນິ້ວມືໄດ້."</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"ປິດການນນຳໃຊ້ ຫຼື ແກ້ໄຂແຖບສະຖານະ"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"ອະນຸຍາດໃຫ້ແອັບຯປິດການເຮັດວຽກຂອງແຖບສະຖານະ ຫຼືເພີ່ມ ແລະລຶບໄອຄອນລະບົບອອກໄດ້."</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"ເປັນແຖບສະຖານະ"</string>
@@ -1146,6 +1148,7 @@
<string name="usb_notification_message" msgid="3370903770828407960">"ແຕະເພື່ອເບິ່ງຕົວເລືອກເພີ່ມເຕີມ."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"ເຊື່ອມຕໍ່ການດີບັ໊ກຜ່ານ USB ແລ້ວ"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"ແຕະເພື່ອປິດການດີບັກຜ່ານ USB."</string>
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"ເລືອກເພື່ອປິດການດີບັ໊ກຜ່ານ USB."</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"ກຳລັງຂໍລາຍງານຂໍ້ຜິດພາດ…"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"ແບ່ງປັນລາຍງານບັນຫາບໍ?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"ກຳລັງແບ່ງປັນລາຍງານບັນຫາ…"</string>
@@ -1202,8 +1205,8 @@
<string name="permdesc_readInstallSessions" msgid="2049771699626019849">"ອະນຸຍາດໃຫ້ແອັບພລິເຄຊັນອ່ານເຊດຊັນການຕິດຕັ້ງໄດ້. ນີ້ຈະອະນຸຍາດໃຫ້ມັນເບິ່ງເຫັນລາຍລະອຽດກ່ຽວກັບການຕິດຕັ້ງແພັກເກດທີ່ເຮັດວຽກຢູ່ໄດ້."</string>
<string name="permlab_requestInstallPackages" msgid="5782013576218172577">"ຂໍຕິດຕັ້ງແພັກເກດ"</string>
<string name="permdesc_requestInstallPackages" msgid="5740101072486783082">"ອະນຸຍາດໃຫ້ແອັບພລິເຄຊັນຂອງການຕິດຕັ້ງແພັກເກດ."</string>
- <string name="permlab_requestDeletePackages" msgid="1703686454657781242">"request delete packages"</string>
- <string name="permdesc_requestDeletePackages" msgid="3406172963097595270">"ອະນຸຍາດໃຫ້ແອັບພລິເຄຊັນຂອງການຕິດຕັ້ງແພັກເກດ."</string>
+ <string name="permlab_requestDeletePackages" msgid="1703686454657781242">"ຮ້ອງຂໍການລຶບແພັກເກດ"</string>
+ <string name="permdesc_requestDeletePackages" msgid="3406172963097595270">"ອະນຸຍາດໃຫ້ແອັບພລິເຄຊັນຮ້ອງຂໍການລຶບແພັກເກດ."</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="8021256345643918264">"ຖາມເພື່ອໃຫ້ເພີກເສີຍການປັບແຕ່ງແບັດເຕີຣີ"</string>
<string name="permdesc_requestIgnoreBatteryOptimizations" msgid="8359147856007447638">"ອະນຸຍາດໃຫ້ແອັບຖາມສິດອະນຸຍາດເພື່ອເພີກເສີຍຕໍ່ການປັບແຕ່ງແບັດເຕີຣີສຳລັບແອັບນັ້ນ."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1311810005957319690">"ແຕະສອງເທື່ອເພື່ອຄວບຄຸມການຊູມ"</string>
@@ -1689,4 +1692,7 @@
<string name="app_category_news" msgid="7496506240743986873">"News & Magazines"</string>
<string name="app_category_maps" msgid="5878491404538024367">"Maps & Navigation"</string>
<string name="app_category_productivity" msgid="3742083261781538852">"ຜະລິດຕະພາບ"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"ບ່ອນຈັດເກັບຂໍ້ມູນອຸປະກອນ"</string>
+ <!-- no translation found for adb_debugging_notification_channel_tv (5537766997350092316) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-lt-watch/styles_material.xml b/core/res/res/values-lt-watch/styles_material.xml
deleted file mode 100644
index 36a459d..0000000
--- a/core/res/res/values-lt-watch/styles_material.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 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.
- -->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see styles_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"candidates"</font></string>
-</resources>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 837134c..89ac3f2 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -284,6 +284,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Valdykite ekrano mastelio keitimo lygį ir pozicijos nustatymą."</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Veiksmai gestais"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Galima paliesti, perbraukti, suimti ir atlikti kitus veiksmus gestais."</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"Kontrolinio kodo gestai"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"Gali užfiksuoti gestus, atliktus naudojant įrenginio kontrolinio kodo jutiklį."</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"išjungti ar keisti būsenos juostą"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"Leidžiama programai neleisti būsenos juostos arba pridėti ir pašalinti sistemos piktogramas."</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"būti būsenos juosta"</string>
@@ -1186,6 +1188,7 @@
<string name="usb_notification_message" msgid="3370903770828407960">"Palieskite, kad būtų rodoma daugiau parinkčių."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB derinimas prijungtas"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Palieskite, kad išjungtumėte USB derinimą."</string>
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Pasirinkite, kas išjungtumėte USB derinimą."</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Pateikiamas pranešimas apie riktą…"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Bendrinti pranešimą apie riktą?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Bendrinamas pranešimas apie riktą..."</string>
@@ -1751,4 +1754,7 @@
<string name="app_category_news" msgid="7496506240743986873">"Naujienos ir žurnalai"</string>
<string name="app_category_maps" msgid="5878491404538024367">"Žemėlapiai ir navigacija"</string>
<string name="app_category_productivity" msgid="3742083261781538852">"Produktyvumas"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"Įrenginio saugykla"</string>
+ <!-- no translation found for adb_debugging_notification_channel_tv (5537766997350092316) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-lv-watch/styles_material.xml b/core/res/res/values-lv-watch/styles_material.xml
deleted file mode 100644
index 36a459d..0000000
--- a/core/res/res/values-lv-watch/styles_material.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 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.
- -->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see styles_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"candidates"</font></string>
-</resources>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 7510e77..5163334 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -281,6 +281,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Kontrolējiet displeja tālummaiņas līmeni un pozicionēšanu."</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Žestu izpilde"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Atbalsta pieskaršanos, vilkšanu, savilkšanu un citus žestus."</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"Pirksta nospieduma žesti"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"Var uztvert žestus ierīces pirksta nospieduma sensorā."</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"atspējot vai pārveidot statusa joslu"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"Ļauj lietotnei atspējot statusa joslu vai pievienot un noņemt sistēmas ikonas."</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"Būt par statusa joslu"</string>
@@ -1166,6 +1168,7 @@
<string name="usb_notification_message" msgid="3370903770828407960">"Pieskarieties, lai skatītu citas iespējas."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB atkļūdošana ir pievienota."</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Pieskarieties, lai atspējotu USB atkļūdošanu."</string>
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Atlasiet, lai atspējotu USB atkļūdošanu."</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Notiek kļūdas pārskata izveide…"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Vai kopīgot kļūdas pārskatu?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Notiek kļūdas pārskata kopīgošana…"</string>
@@ -1720,4 +1723,7 @@
<string name="app_category_news" msgid="7496506240743986873">"Ziņas un žurnāli"</string>
<string name="app_category_maps" msgid="5878491404538024367">"Kartes un navigācija"</string>
<string name="app_category_productivity" msgid="3742083261781538852">"Produktivitāte"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"Ierīces krātuve"</string>
+ <!-- no translation found for adb_debugging_notification_channel_tv (5537766997350092316) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-mk-watch/styles_material.xml b/core/res/res/values-mk-watch/styles_material.xml
deleted file mode 100644
index 89c3366..0000000
--- a/core/res/res/values-mk-watch/styles_material.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 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.
- -->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see styles_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"кандидати"</font></string>
-</resources>
diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml
index 0e3862f..66d5387 100644
--- a/core/res/res/values-mk/strings.xml
+++ b/core/res/res/values-mk/strings.xml
@@ -278,6 +278,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Контролирајте го нивото на зумирање и позиционирање на екранот."</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Користете движења"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Може да допрете, повлечете, штипнете и да користите други движења."</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"Движења за отпечатоци"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"Може да сними движења што се направени на сензорот за отпечатоци на уредите."</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"оневозможи или измени статусна лента"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"Дозволува апликацијата да ја оневозможи статусната лента или да додава или отстранува системски икони."</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"да стане статусна лента"</string>
@@ -1146,6 +1148,8 @@
<string name="usb_notification_message" msgid="3370903770828407960">"Допрете за повеќе опции."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"Поврзано е отстранување грешки преку УСБ"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Допрете за да се оневозможи отстранувањето грешки преку USB."</string>
+ <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
+ <skip />
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Се зема извештајот за грешки…"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Да се сподели извештајот за грешки?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Се споделува извештај за грешки…"</string>
@@ -1691,4 +1695,7 @@
<string name="app_category_news" msgid="7496506240743986873">"Вести и списанија"</string>
<string name="app_category_maps" msgid="5878491404538024367">"Карти и навигација"</string>
<string name="app_category_productivity" msgid="3742083261781538852">"Продуктивност"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"Простор на уредот"</string>
+ <!-- no translation found for adb_debugging_notification_channel_tv (5537766997350092316) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ml-watch/styles_material.xml b/core/res/res/values-ml-watch/styles_material.xml
deleted file mode 100644
index 9d38c0d..0000000
--- a/core/res/res/values-ml-watch/styles_material.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 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.
- -->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see styles_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"കാൻഡിഡേറ്റുകൾ"</font></string>
-</resources>
diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml
index da97cf5..bb5455d 100644
--- a/core/res/res/values-ml/strings.xml
+++ b/core/res/res/values-ml/strings.xml
@@ -278,6 +278,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"ഡിസ്പ്ലേയുടെ സൂം നിലയും പൊസിഷനിംഗും നിയന്ത്രിക്കുക."</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"ജെസ്റ്ററുകൾ നിർവഹിക്കുക"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"ടാപ്പുചെയ്യാനോ സ്വൈപ്പുചെയ്യാനോ പിഞ്ചുചെയ്യാനോ മറ്റ് ജെസ്റ്ററുകൾ നിർവഹിക്കാനോ കഴിയും."</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"ഫിംഗർപ്രിന്റ് ജെസ്റ്ററുകൾ"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"ഉപകരണത്തിന്റെ ഫിംഗർപ്രിന്റ് സെൻസറിൽ ചെയ്ത ജെസ്റ്ററുകൾ ക്യാപ്ചർ ചെയ്യാനാകും."</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"സ്റ്റാറ്റസ് ബാർ പ്രവർത്തനരഹിതമാക്കുക അല്ലെങ്കിൽ പരിഷ്ക്കരിക്കുക"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"നില ബാർ പ്രവർത്തരഹിതമാക്കുന്നതിന് അല്ലെങ്കിൽ സിസ്റ്റം ഐക്കണുകൾ ചേർക്കുന്നതിനും നീക്കംചെയ്യുന്നതിനും അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു."</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"സ്റ്റാറ്റസ് ബാർ ആയിരിക്കുക"</string>
@@ -1146,6 +1148,8 @@
<string name="usb_notification_message" msgid="3370903770828407960">"കൂടുതൽ ഓപ്ഷനുകൾക്ക് ടാപ്പുചെയ്യുക."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB ഡീബഗ്ഗിംഗ് കണക്റ്റുചെയ്തു"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"USB ഡീബഗ്ഗിംഗ് പ്രവർത്തനരഹിതമാക്കാൻ ടാപ്പുചെയ്യുക."</string>
+ <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
+ <skip />
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"ബഗ് റിപ്പോർട്ട് എടുക്കുന്നു…"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"ബഗ് റിപ്പോർട്ട് പങ്കിടണോ?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"ബഗ് റിപ്പോർട്ട് പങ്കിടുന്നു…"</string>
@@ -1689,4 +1693,7 @@
<string name="app_category_news" msgid="7496506240743986873">"വാർത്തകളും മാസികകളും"</string>
<string name="app_category_maps" msgid="5878491404538024367">"മാപ്സും നാവിഗേഷനും"</string>
<string name="app_category_productivity" msgid="3742083261781538852">"ഉല്പ്പാദനക്ഷമത"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"ഉപകരണ സ്റ്റോറേജ്"</string>
+ <!-- no translation found for adb_debugging_notification_channel_tv (5537766997350092316) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-mn-watch/styles_material.xml b/core/res/res/values-mn-watch/styles_material.xml
deleted file mode 100644
index f65ea48..0000000
--- a/core/res/res/values-mn-watch/styles_material.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 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.
- -->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see styles_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"нэр дэвшигч"</font></string>
-</resources>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index 2af81c4..0f7d43a 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -278,6 +278,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Дэлгэцийн томруулах түвшин болон байршлыг хянах."</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Зангах"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Товших, шудрах, жижигрүүлэх болон бусад зангааг хийх боломжтой."</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"Хурууны хээний зангаа"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"Төхөөрөмжийн хурууны хээ мэдрэгчид зангасан зангааг танина."</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"статус самбарыг идэвхгүй болгох болон өөрчлөх"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"Апп нь статус самбарыг идэвхгүй болгох эсвэл систем дүрсийг нэмэх, хасах боломжтой."</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"статусын хэсэг болох"</string>
@@ -1146,6 +1148,7 @@
<string name="usb_notification_message" msgid="3370903770828407960">"Бусад сонголтыг харахын тулд товшино уу."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB дебаг холбогдсон"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"USB-н алдаа засварлахыг идэвхгүй болгохын тулд товшино уу."</string>
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB дебаг хийхийг идэвхгүй болгох бол сонгоно уу."</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Алдааны тайланг авч байна..."</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Алдааны тайланг хуваалцах уу?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Алдааны тайланг хуваалцаж байна..."</string>
@@ -1687,4 +1690,7 @@
<string name="app_category_news" msgid="7496506240743986873">"Мэдээ & сэтгүүл"</string>
<string name="app_category_maps" msgid="5878491404538024367">"Газрын зураг & зүг чиг"</string>
<string name="app_category_productivity" msgid="3742083261781538852">"Бүтээмж"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"Төхөөрөмжийн сан"</string>
+ <!-- no translation found for adb_debugging_notification_channel_tv (5537766997350092316) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-mr-watch/styles_material.xml b/core/res/res/values-mr-watch/styles_material.xml
deleted file mode 100644
index 36a459d..0000000
--- a/core/res/res/values-mr-watch/styles_material.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 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.
- -->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see styles_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"candidates"</font></string>
-</resources>
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index 1be89c2..69cf831 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -278,6 +278,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"प्रदर्शनाचा झूम स्तर आणि स्थिती निर्धारण नियंत्रित करा."</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"जेश्चर करा"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"टॅप, स्वाइप, पिंच आणि इतर जेश्चर करू शकते."</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"फिंगरप्रिंट जेश्चर"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"डिव्हाइसच्या फिंगरप्रिंट सेंसरवर केलेले जेश्चर कॅप्चर करू शकते."</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"स्टेटस बार अक्षम करा किंवा सुधारित करा"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"स्टेटस बार अक्षम करण्यासाठी किंवा सिस्टीम चिन्हे जोडण्यासाठी आणि काढण्यासाठी अॅप ला अनुमती देते."</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"स्टेटस बार होऊ द्या"</string>
@@ -1146,6 +1148,8 @@
<string name="usb_notification_message" msgid="3370903770828407960">"अधिक पर्यायांसाठी टॅप करा."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB डीबग करणे कनेक्ट केले"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"USB डीबग करणे अक्षम करण्यासाठी टॅप करा."</string>
+ <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
+ <skip />
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"दोष अहवाल घेत आहे..."</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"बग अहवाल सामायिक करायचा?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"दोष अहवाल सामायिक करीत आहे..."</string>
@@ -1689,4 +1693,7 @@
<string name="app_category_news" msgid="7496506240743986873">"बातम्या आणि मासिके"</string>
<string name="app_category_maps" msgid="5878491404538024367">"नकाशे आणि नेव्हिगेशन"</string>
<string name="app_category_productivity" msgid="3742083261781538852">"उत्पादनक्षमता"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"डिव्हाइस संचय"</string>
+ <!-- no translation found for adb_debugging_notification_channel_tv (5537766997350092316) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ms-watch/styles_material.xml b/core/res/res/values-ms-watch/styles_material.xml
deleted file mode 100644
index 3f5e687..0000000
--- a/core/res/res/values-ms-watch/styles_material.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 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.
- -->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see styles_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"calon"</font></string>
-</resources>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index ad1f4cb..ad053b9 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -278,6 +278,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Kawal tahap zum dan kedudukan paparan."</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Lakukan gerak isyarat"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Boleh ketik, leret, cubit dan laksanakan gerak isyarat lain."</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"Gerak isyarat cap jari"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"Boleh menangkap gerak isyarat yang dilakukan pada penderia cap jari peranti."</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"lumpuhkan atau ubah suai bar status"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"Membenarkan apl melumpuhkan bar status atau menambah dan mengalih keluar ikon sistem."</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"jadi bar status"</string>
@@ -1146,6 +1148,7 @@
<string name="usb_notification_message" msgid="3370903770828407960">"Ketik untuk mendapatkan lagi pilihan."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"Penyahpepijatan USB disambungkan"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Ketik untuk melumpuhkan penyahpepijatan USB."</string>
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Pilih untuk melumpuhkan penyahpepijatan USB."</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Mengambil laporan pepijat…"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Kongsi laporan pepijat?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Berkongsi laporan pepijat…"</string>
@@ -1689,4 +1692,7 @@
<string name="app_category_news" msgid="7496506240743986873">"Berita & Majalah"</string>
<string name="app_category_maps" msgid="5878491404538024367">"Peta & Navigasi"</string>
<string name="app_category_productivity" msgid="3742083261781538852">"Produktiviti"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"Storan peranti"</string>
+ <!-- no translation found for adb_debugging_notification_channel_tv (5537766997350092316) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-my-watch/styles_material.xml b/core/res/res/values-my-watch/styles_material.xml
deleted file mode 100644
index 36a459d..0000000
--- a/core/res/res/values-my-watch/styles_material.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 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.
- -->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see styles_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"candidates"</font></string>
-</resources>
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index 129eefd..4454c2b5 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -278,6 +278,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"မျက်နှာပြင် ဇူးမ်အရွယ်နှင့် နေရာချထားခြင်းကို ထိန်းချုပ်ပါ။"</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"လက်ဟန်များ အသုံးပြုပါ"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"တို့ခြင်း၊ ပွတ်ဆွဲခြင်း၊ နှင့် အခြား လက်ဟန်များကို အသုံးပြုနိုင်ပါသည်။"</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"လက်ဗွေရာများ"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"ကိရိယာ၏ လက်ဗွေအာရုံခံကိရိယာတွင် နှိပ်ထားသည်များကို မှတ်သားထားနိုင်သည်။"</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"အခြေအနေပြဘားအား အလုပ်မလုပ်ခိုင်းရန်သို့မဟုတ် မွမ်းမံရန်"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"အက်ပ်အား အခြေအနေပြ ဘားကို ပိတ်ခွင့် သို့မဟတ် စနစ် အိုင်ကွန်များကို ထည့်ခြင်း ဖယ်ရှားခြင်း ပြုလုပ်ခွင့် ပြုသည်။"</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"အခြေအနေပြ ဘားဖြစ်ပါစေ"</string>
@@ -1146,6 +1148,8 @@
<string name="usb_notification_message" msgid="3370903770828407960">"နောက်ထပ်ရွေးချယ်စရာများအတွက် တို့ပါ။"</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB အမှားစစ်ခြင်းအား ချိတ်ဆက်ထားသည်"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"USB ဆက်သွယ်ရေးစနစ်ကို ပိတ်ရန် တို့ပါ။"</string>
+ <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
+ <skip />
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"ချွတ်ယွင်းချက် အစီရင်ခံစာပြုစုနေသည်..."</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"ချွတ်ယွင်းချက် အစီရင်ခံစာကို မျှဝေမလား။"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"ချွတ်ယွင်းမှုအစီရင်ခံစာ မျှဝေနေသည်…"</string>
@@ -1689,4 +1693,7 @@
<string name="app_category_news" msgid="7496506240743986873">"သတင်းနှင့် မဂ္ဂဇင်းများ"</string>
<string name="app_category_maps" msgid="5878491404538024367">"မြေပုံနှင့် ခရီးလမ်းညွှန်ချက်"</string>
<string name="app_category_productivity" msgid="3742083261781538852">"ထုတ်လုပ်နိုင်မှု"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"စက်ပစ္စည်း သိုလှောင်ခန်း"</string>
+ <!-- no translation found for adb_debugging_notification_channel_tv (5537766997350092316) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-nb-watch/styles_material.xml b/core/res/res/values-nb-watch/styles_material.xml
deleted file mode 100644
index 36a459d..0000000
--- a/core/res/res/values-nb-watch/styles_material.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 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.
- -->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see styles_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"candidates"</font></string>
-</resources>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 9ef1bb3..d23441f 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -278,6 +278,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Kontrollér zoomenivået og plasseringen for skjermen."</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Gjøre bevegelser"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Kan trykke, sveipe, klype og gjøre andre bevegelser."</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"Bevegelser på fingeravtrykkssensor"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"Kan fange inn bevegelser som utføres på enhetens fingeravtrykkssensor."</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"deaktivere eller endre statusfeltet"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"Lar appen deaktivere statusfeltet eller legge til og fjerne systemikoner."</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"vise appen i statusfeltet"</string>
@@ -1146,6 +1148,7 @@
<string name="usb_notification_message" msgid="3370903770828407960">"Trykk for å få flere alternativ."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB-feilsøking tilkoblet"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Trykk for å slå av feilsøking via USB."</string>
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Velg for å deaktivere USB-debugging."</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Kjører feilrapport …"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Vil du dele feilrapporten?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Deler feilrapporten …"</string>
@@ -1689,4 +1692,7 @@
<string name="app_category_news" msgid="7496506240743986873">"Nyheter og tidsskrifter"</string>
<string name="app_category_maps" msgid="5878491404538024367">"Kart og navigering"</string>
<string name="app_category_productivity" msgid="3742083261781538852">"Produktivitet"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"Lagring på enheten"</string>
+ <!-- no translation found for adb_debugging_notification_channel_tv (5537766997350092316) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ne-watch/styles_material.xml b/core/res/res/values-ne-watch/styles_material.xml
deleted file mode 100644
index 36a459d..0000000
--- a/core/res/res/values-ne-watch/styles_material.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 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.
- -->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see styles_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"candidates"</font></string>
-</resources>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index 6ebbc93..d513ff3 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -278,6 +278,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"प्रदर्शनको जुम स्तर र स्थिति नियन्त्रण गर्नुहोस्।"</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"इसाराहरू सम्बन्धी कार्य गर्नुहोस्"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"ट्याप, स्वाइप गर्न, थिच्न र अन्य इसाराहरू सम्बन्धी कार्य गर्न सक्छ"</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"फिंगरप्रिन्टका इसाराहरू"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"यन्त्रहरूको फिंगरप्रिन्ट सेन्सरमा गरिएका इसाराहरू कैद गर्न सक्छ।"</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"स्थिति पट्टिलाई अक्षम वा संशोधित गर्नुहोस्"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"स्थिति पट्टि असक्षम पार्न वा प्रणाली आइकनहरू थप्न र हटाउन अनुप्रयोगलाई अनुमति दिन्छ।"</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"वस्तुस्थिति पट्टी हुन दिनुहोस्"</string>
@@ -1152,6 +1154,7 @@
<string name="usb_notification_message" msgid="3370903770828407960">"थप विकल्पहरूका लागि ट्याप गर्नुहोस्।"</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB डिबग गर्ने जडित छ"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"USB डिबगिङलाई असक्षम गर्न ट्याप गर्नुहोस्।"</string>
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB डिबगिङ असक्षम पार्न चयन गर्नुहोस्।"</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"बग रिपोर्ट लिँदै..."</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"बग रिपोर्टलाई साझेदारी गर्ने हो?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"बग रिपोर्टलाई साझेदारी गर्दै ..."</string>
@@ -1695,4 +1698,7 @@
<string name="app_category_news" msgid="7496506240743986873">"समाचार तथा पत्रिकाहरू"</string>
<string name="app_category_maps" msgid="5878491404538024367">"नक्सा तथा नेभिगेसन"</string>
<string name="app_category_productivity" msgid="3742083261781538852">"उत्पादकत्व"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"यन्त्रको भण्डारण"</string>
+ <!-- no translation found for adb_debugging_notification_channel_tv (5537766997350092316) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-nl-watch/styles_material.xml b/core/res/res/values-nl-watch/styles_material.xml
deleted file mode 100644
index b821347..0000000
--- a/core/res/res/values-nl-watch/styles_material.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 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.
- -->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see styles_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"kandidaten"</font></string>
-</resources>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 8ece49e..f3e0274 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -278,6 +278,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Bedien het zoomniveau en de positionering van het scherm."</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Gebaren uitvoeren"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Kan tikken, vegen, samenknijpen en andere gebaren uitvoeren."</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"Vingerafdrukgebaren"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"Kan gebaren registreren die op de vingerafdruksensor van het apparaat worden getekend."</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"statusbalk uitschakelen of wijzigen"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"Hiermee kan de app de statusbalk uitschakelen of systeempictogrammen toevoegen en verwijderen."</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"de statusbalk zijn"</string>
@@ -1146,6 +1148,7 @@
<string name="usb_notification_message" msgid="3370903770828407960">"Tik voor meer opties."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB-foutopsporing verbonden"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Tik om USB-foutopsporing uit te schakelen."</string>
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Selecteer deze optie om USB-foutopsporing uit te schakelen."</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Bugrapport genereren…"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Bugrapport delen?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Bugrapport delen…"</string>
@@ -1689,4 +1692,7 @@
<string name="app_category_news" msgid="7496506240743986873">"Nieuws en tijdschriften"</string>
<string name="app_category_maps" msgid="5878491404538024367">"Maps en navigatie"</string>
<string name="app_category_productivity" msgid="3742083261781538852">"Productiviteit"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"Apparaatopslag"</string>
+ <!-- no translation found for adb_debugging_notification_channel_tv (5537766997350092316) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-pa-watch/styles_material.xml b/core/res/res/values-pa-watch/styles_material.xml
deleted file mode 100644
index 36a459d..0000000
--- a/core/res/res/values-pa-watch/styles_material.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 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.
- -->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see styles_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"candidates"</font></string>
-</resources>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index 8438fb9..788efb8 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -278,6 +278,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"ਡਿਸਪਲੇ ਦੇ ਜ਼ੂਮ ਪੱਧਰ ਅਤੇ ਸਥਿਤੀ ਨੂੰ ਨਿਯੰਤ੍ਰਿਤ ਕਰੋ।"</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"ਸੰਕੇਤ ਕਰਦੀ ਹੈ"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"ਟੈਪ ਕਰ ਸਕਦੀ ਹੈ, ਸਵਾਈਪ ਕਰ ਸਕਦੀ ਹੈ, ਪਿੰਚ ਕਰ ਸਕਦੀ ਹੈ, ਅਤੇ ਹੋਰ ਸੰਕੇਤ ਕਰ ਸਕਦੀ ਹੈ।"</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਸੰਕੇਤ"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"ਡੀਵਾਈਸਾਂ ਦੇ ਫਿੰਗਰਪ੍ਰਿੰਟ ਸੈਂਸਰ \'ਤੇ ਕੀਤੇ ਗਏ ਸੰਕੇਤਾਂ ਨੂੰ ਕੈਪਚਰ ਕਰ ਸਕਦੀ ਹੈ।"</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"ਸਥਿਤੀ ਬਾਰ ਅਸਮਰੱਥ ਬਣਾਓ ਜਾਂ ਸੰਸ਼ੋਧਿਤ ਕਰੋ"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"ਐਪ ਨੂੰ ਸਥਿਤੀ ਬਾਰ ਨੂੰ ਅਸਮਰੱਥ ਬਣਾਉਣ ਜਾਂ ਸਿਸਟਮ ਆਈਕਨਾਂ ਨੂੰ ਜੋੜਨ ਅਤੇ ਹਟਾਉਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"ਸਥਿਤੀ ਪੱਟੀ ਬਣਨ ਦਿਓ"</string>
@@ -1146,6 +1148,8 @@
<string name="usb_notification_message" msgid="3370903770828407960">"ਹੋਰ ਵਿਕਲਪਾਂ ਲਈ ਟੈਪ ਕਰੋ।"</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB ਡੀਬਗਿੰਗ ਕਨੈਕਟ ਕੀਤੀ"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"USB ਡੀਬੱਗਿੰਗ ਨੂੰ ਅਯੋਗ ਬਣਾਉਣ ਲਈ ਟੈਪ ਕਰੋ।"</string>
+ <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
+ <skip />
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"ਬੱਗ ਰਿਪਰੋਟ ਪ੍ਰਾਪਤ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ..."</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"ਕੀ ਬੱਗ ਰਿਪੋਰਟ ਸਾਂਝੀ ਕਰਨੀ ਹੈ?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"ਬੱਗ ਰਿਪੋਰਟ ਸਾਂਝੀ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ…"</string>
@@ -1689,4 +1693,7 @@
<string name="app_category_news" msgid="7496506240743986873">"ਖਬਰਾਂ ਅਤੇ ਰਸਾਲੇ"</string>
<string name="app_category_maps" msgid="5878491404538024367">"ਨਕਸ਼ੇ ਅਤੇ ਆਵਾਗੌਣ"</string>
<string name="app_category_productivity" msgid="3742083261781538852">"ਉਤਪਾਦਕਤਾ"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"ਡੀਵਾਈਸ ਸਟੋਰੇਜ"</string>
+ <!-- no translation found for adb_debugging_notification_channel_tv (5537766997350092316) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-pl-watch/styles_material.xml b/core/res/res/values-pl-watch/styles_material.xml
deleted file mode 100644
index 384d91c..0000000
--- a/core/res/res/values-pl-watch/styles_material.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 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.
- -->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see styles_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"elementy"</font></string>
-</resources>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 125f3f2..3814f80 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -284,6 +284,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Regulowanie poziomu i obszaru powiększenia ekranu."</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Obsługa gestów"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Obsługuje kliknięcia, przesunięcia, ściągnięcia palców i inne gesty."</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"Gesty związane z odciskiem palca"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"Może przechwytywać gesty wykonywane na czytniku linii papilarnych w urządzeniu."</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"wyłączanie lub zmienianie paska stanu"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"Pozwala aplikacji na wyłączanie paska stanu oraz dodawanie i usuwanie ikon systemowych."</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"działanie jako pasek stanu"</string>
@@ -1186,6 +1188,7 @@
<string name="usb_notification_message" msgid="3370903770828407960">"Kliknij, by wyświetlić więcej opcji."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"Podłączono moduł debugowania USB"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Kliknij, by wyłączyć debugowanie USB."</string>
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Wybierz, aby wyłączyć debugowanie USB."</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Zgłaszam błąd…"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Udostępnić raport o błędzie?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Udostępniam raport o błędzie…"</string>
@@ -1751,4 +1754,7 @@
<string name="app_category_news" msgid="7496506240743986873">"Wiadomości i czasopisma"</string>
<string name="app_category_maps" msgid="5878491404538024367">"Mapy i nawigacja"</string>
<string name="app_category_productivity" msgid="3742083261781538852">"Produktywność"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"Pamięć urządzenia"</string>
+ <!-- no translation found for adb_debugging_notification_channel_tv (5537766997350092316) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-pt-rBR-watch/styles_material.xml b/core/res/res/values-pt-rBR-watch/styles_material.xml
deleted file mode 100644
index 898d2fd..0000000
--- a/core/res/res/values-pt-rBR-watch/styles_material.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 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.
- -->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see styles_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"candidatos"</font></string>
-</resources>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index c6d217a..a7a763f 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -278,6 +278,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Controlar o posicionamento e nível de zoom da tela."</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Fazer gestos"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Toque, deslize, faça gestos de pinça e faça outros gestos."</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"Gestos de impressão digital"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"Pode captar gestos realizados no sensor de impressão digital do dispositivo."</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"desativar ou modificar a barra de status"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"Permite que o app desative a barra de status ou adicione e remova ícones do sistema."</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"ser a barra de status"</string>
@@ -1146,6 +1148,7 @@
<string name="usb_notification_message" msgid="3370903770828407960">"Toque para ver mais opções."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"Depuração USB conectada"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Toque para desativar a depuração do USB."</string>
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Selecione para desativar a depuração USB."</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Gerando relatório do bug..."</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Compartilhar relatório do bug?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Compartilhando relatório do bug…"</string>
@@ -1689,4 +1692,7 @@
<string name="app_category_news" msgid="7496506240743986873">"Notícias e revistas"</string>
<string name="app_category_maps" msgid="5878491404538024367">"Mapas e navegação"</string>
<string name="app_category_productivity" msgid="3742083261781538852">"Produtividade"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"Armazenamento do dispositivo"</string>
+ <!-- no translation found for adb_debugging_notification_channel_tv (5537766997350092316) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-pt-rPT-watch/styles_material.xml b/core/res/res/values-pt-rPT-watch/styles_material.xml
deleted file mode 100644
index 898d2fd..0000000
--- a/core/res/res/values-pt-rPT-watch/styles_material.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 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.
- -->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see styles_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"candidatos"</font></string>
-</resources>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index eabc2f4..b87fe9e 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -278,6 +278,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Controlar o nível de zoom e o posicionamento do ecrã."</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Realizar gestos"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"É possível tocar, deslizar rapidamente, juntar os dedos e realizar outros gestos"</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"Gestos de impressão digital"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"Pode capturar gestos realizados no sensor de impressões digitais do dispositivo."</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"desativar ou modificar barra de estado"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"Permite à aplicação desativar a barra de estado ou adicionar e remover ícones do sistema."</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"ser apresentada na barra de estado"</string>
@@ -1146,6 +1148,7 @@
<string name="usb_notification_message" msgid="3370903770828407960">"Toque para obter mais opções."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"Depuração USB ligada"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Toque para desativar a depuração USB."</string>
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Seleccione para desativar depuração USB."</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"A criar relatório de erro…"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Pretende partilhar o relatório de erro?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"A partilhar relatório de erro…"</string>
@@ -1689,4 +1692,7 @@
<string name="app_category_news" msgid="7496506240743986873">"Notícias e revistas"</string>
<string name="app_category_maps" msgid="5878491404538024367">"Mapas e navegação"</string>
<string name="app_category_productivity" msgid="3742083261781538852">"Produtividade"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"Armazenamento do dispositivo"</string>
+ <!-- no translation found for adb_debugging_notification_channel_tv (5537766997350092316) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-pt-watch/styles_material.xml b/core/res/res/values-pt-watch/styles_material.xml
deleted file mode 100644
index 898d2fd..0000000
--- a/core/res/res/values-pt-watch/styles_material.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 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.
- -->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see styles_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"candidatos"</font></string>
-</resources>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index c6d217a..a7a763f 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -278,6 +278,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Controlar o posicionamento e nível de zoom da tela."</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Fazer gestos"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Toque, deslize, faça gestos de pinça e faça outros gestos."</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"Gestos de impressão digital"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"Pode captar gestos realizados no sensor de impressão digital do dispositivo."</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"desativar ou modificar a barra de status"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"Permite que o app desative a barra de status ou adicione e remova ícones do sistema."</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"ser a barra de status"</string>
@@ -1146,6 +1148,7 @@
<string name="usb_notification_message" msgid="3370903770828407960">"Toque para ver mais opções."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"Depuração USB conectada"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Toque para desativar a depuração do USB."</string>
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Selecione para desativar a depuração USB."</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Gerando relatório do bug..."</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Compartilhar relatório do bug?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Compartilhando relatório do bug…"</string>
@@ -1689,4 +1692,7 @@
<string name="app_category_news" msgid="7496506240743986873">"Notícias e revistas"</string>
<string name="app_category_maps" msgid="5878491404538024367">"Mapas e navegação"</string>
<string name="app_category_productivity" msgid="3742083261781538852">"Produtividade"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"Armazenamento do dispositivo"</string>
+ <!-- no translation found for adb_debugging_notification_channel_tv (5537766997350092316) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ro-watch/styles_material.xml b/core/res/res/values-ro-watch/styles_material.xml
deleted file mode 100644
index 36a459d..0000000
--- a/core/res/res/values-ro-watch/styles_material.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 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.
- -->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see styles_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"candidates"</font></string>
-</resources>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 5e7df4b..b407ae0 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -281,6 +281,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Controlați nivelul de zoom și poziționarea afișajului."</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Folosiți gesturi"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Se poate atinge, glisa, ciupi și se pot folosi alte gesturi."</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"Gesturi ce implică amprente"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"Poate reda gesturile făcute pe senzorul de amprentă al dispozitivelor."</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"dezactivare sau modificare bare de stare"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"Permite aplicației să dezactiveze bara de stare sau să adauge și să elimine pictograme de sistem."</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"să fie bara de stare"</string>
@@ -1166,6 +1168,7 @@
<string name="usb_notification_message" msgid="3370903770828407960">"Atingeți pentru mai multe opțiuni."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"Depanarea USB este conectată"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Atingeți ca să dezactivați remedierea erorilor prin USB."</string>
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Selectați pentru a dezactiva depanarea USB."</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Se creează un raport de eroare…"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Trimiteți raportul de eroare?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Se trimite raportul de eroare…"</string>
@@ -1720,4 +1723,7 @@
<string name="app_category_news" msgid="7496506240743986873">"Știri și reviste"</string>
<string name="app_category_maps" msgid="5878491404538024367">"Hărți și navigare"</string>
<string name="app_category_productivity" msgid="3742083261781538852">"Productivitate"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"Stocare pe dispozitiv"</string>
+ <!-- no translation found for adb_debugging_notification_channel_tv (5537766997350092316) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ru-watch/styles_material.xml b/core/res/res/values-ru-watch/styles_material.xml
deleted file mode 100644
index 36a459d..0000000
--- a/core/res/res/values-ru-watch/styles_material.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 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.
- -->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see styles_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"candidates"</font></string>
-</resources>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 5aabe4d..2e2bd0b 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -284,6 +284,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Управлять позиционированием и размером изображения на экране."</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Жесты"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Может выполнять жесты нажатия, пролистывания, масштабирования и т. д."</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"Жесты для отпечатков пальцев"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"Сохраняет жесты, выполненные на сканере отпечатков пальцев."</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"Отключение/изменение строки состояния"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"Приложение сможет отключать строку состояния, а также добавлять и удалять системные значки."</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"Замена строки состояния"</string>
@@ -1186,6 +1188,7 @@
<string name="usb_notification_message" msgid="3370903770828407960">"Нажмите, чтобы показать дополнительные параметры."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"Отладка по USB разрешена"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Нажмите, чтобы отключить отладку по USB."</string>
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Нажмите, чтобы отключить отладку USB."</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Подготовка отчета об ошибке"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Разрешить доступ к информации об ошибке?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Отправка отчета об ошибке"</string>
@@ -1751,4 +1754,7 @@
<string name="app_category_news" msgid="7496506240743986873">"Новости и журналы"</string>
<string name="app_category_maps" msgid="5878491404538024367">"Карты и навигация"</string>
<string name="app_category_productivity" msgid="3742083261781538852">"Работа"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"Хранилище устройства"</string>
+ <!-- no translation found for adb_debugging_notification_channel_tv (5537766997350092316) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-si-watch/styles_material.xml b/core/res/res/values-si-watch/styles_material.xml
deleted file mode 100644
index 37b4afe..0000000
--- a/core/res/res/values-si-watch/styles_material.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 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.
- -->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see styles_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"අපේක්ෂකයන්"</font></string>
-</resources>
diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml
index d776aaa..7440888 100644
--- a/core/res/res/values-si/strings.xml
+++ b/core/res/res/values-si/strings.xml
@@ -278,6 +278,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"සංදර්ශනයේ විශාලන මට්ටම සහ පිහිටීම පාලනය කරන්න."</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"අභින සිදු කරන්න"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"තට්ටු කිරීමට, ස්වයිප් කිරීමට, පින්ච් කිරීමට, සහ වෙනත් අභින සිදු කිරීමට හැකිය."</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"ඇඟිලි සලකුණු ඉංගිත"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"උපාංග ඇඟිලි සලකුණු සංවේදකය මත සිදු කරන ඉංගිත ග්රහණය කළ හැකිය."</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"තත්ව තීරුව අබල කරන්න හෝ වෙනස් කරන්න"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"තත්ව තීරුව අක්රිය කිරීමට හෝ පද්ධති නිරූපක එකතු හෝ ඉවත් කිරීමට යෙදුමට අවසර දේ."</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"තත්ත්ව තීරුව බවට පත්වීම"</string>
@@ -1148,6 +1150,7 @@
<string name="usb_notification_message" msgid="3370903770828407960">"තවත් විකල්ප සඳහා තට්ටු කරන්න."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB නිදොස්කරණය සම්බන්ධිතයි"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"USB නිදොස්කරණය අබල කිරීමට තට්ටු කරන්න."</string>
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB නිදොස්කරණය අබල කිරීමට තෝරන්න."</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"දෝෂ වාර්තාවක් ගනිමින්…"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"දෝෂ වාර්තාව බෙදා ගන්නද?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"දෝෂ වාර්තාවක් බෙදා ගනිමින්..."</string>
@@ -1691,4 +1694,7 @@
<string name="app_category_news" msgid="7496506240743986873">"පුවත් සහ සඟරා"</string>
<string name="app_category_maps" msgid="5878491404538024367">"සිතියම් සහ සංචලනය"</string>
<string name="app_category_productivity" msgid="3742083261781538852">"ඵලදායිතාව"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"උපාංග ගබඩාව"</string>
+ <!-- no translation found for adb_debugging_notification_channel_tv (5537766997350092316) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-sk-watch/styles_material.xml b/core/res/res/values-sk-watch/styles_material.xml
deleted file mode 100644
index 5b604e8..0000000
--- a/core/res/res/values-sk-watch/styles_material.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 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.
- -->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see styles_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"kandidáti"</font></string>
-</resources>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index c7b094a..47716da 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -284,6 +284,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Ovládajte úroveň priblíženia/oddialenia obrazovky a umiestnenie"</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Gestá"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Je možné použiť klepnutie, prejdenie, stiahnutie prstami a ďalšie gestá."</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"Gestá odtlačkov prstov"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"Dokáže zaznamenať gestá vykonané na senzore odtlačkov prstov."</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"zakázanie alebo zmeny stavového riadka"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"Umožňuje aplikácii vypnúť stavový riadok alebo pridať a odstrániť systémové ikony."</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"vydávanie sa za stavový riadok"</string>
@@ -1186,6 +1188,7 @@
<string name="usb_notification_message" msgid="3370903770828407960">"Klepnutím zobrazíte ďalšie možnosti."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"Ladenie cez USB pripojené"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Klepnutím zakážete ladenie cez USB."</string>
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Výberom zakážete ladenie USB."</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Preberá sa hlásenie chyby…"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Chcete zdieľať hlásenie chyby?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Zdieľa sa hlásenie chyby…"</string>
@@ -1751,4 +1754,7 @@
<string name="app_category_news" msgid="7496506240743986873">"Noviny a časopisy"</string>
<string name="app_category_maps" msgid="5878491404538024367">"Mapy a navigácia"</string>
<string name="app_category_productivity" msgid="3742083261781538852">"Produktivita"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"Úložisko zariadenia"</string>
+ <!-- no translation found for adb_debugging_notification_channel_tv (5537766997350092316) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-sl-watch/styles_material.xml b/core/res/res/values-sl-watch/styles_material.xml
deleted file mode 100644
index 36a459d..0000000
--- a/core/res/res/values-sl-watch/styles_material.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 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.
- -->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see styles_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"candidates"</font></string>
-</resources>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index ab8264c..13102b5 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -284,6 +284,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Nadziranje stopnje povečave in položaja prikaza."</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Izvajanje potez"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Mogoče je izvajanje dotikov, vlečenja, primikanja in razmikanja prstov ter drugih potez."</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"Poteze po tipalu prstnih odtisov"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"Prepoznava poteze, narejene po tipalu prstnih odtisov naprave."</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"onemogočanje ali spreminjanje vrstice stanja"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"Aplikacijam omogoča onemogočenje vrstice stanja ali dodajanje in odstranjevanje ikon sistema."</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"postane vrstica stanja"</string>
@@ -1186,6 +1188,7 @@
<string name="usb_notification_message" msgid="3370903770828407960">"Dotaknite se za več možnosti."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"Iskanje napak prek USB je povezano"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Dotaknite se za izklop odpravljanja napak prek USB."</string>
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Izberite, če želite onemogočiti iskanje in odpravljanje napak prek vrat USB."</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Zajemanje poročila o napakah …"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Želite poslati poročilo o napakah?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Pošiljanje poročila o napakah …"</string>
@@ -1751,4 +1754,7 @@
<string name="app_category_news" msgid="7496506240743986873">"Novice in revije"</string>
<string name="app_category_maps" msgid="5878491404538024367">"Zemljevidi in navigacija"</string>
<string name="app_category_productivity" msgid="3742083261781538852">"Storilnost"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"Shramba naprave"</string>
+ <!-- no translation found for adb_debugging_notification_channel_tv (5537766997350092316) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-sq-watch/styles_material.xml b/core/res/res/values-sq-watch/styles_material.xml
deleted file mode 100644
index 36a459d..0000000
--- a/core/res/res/values-sq-watch/styles_material.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 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.
- -->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see styles_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"candidates"</font></string>
-</resources>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index fc9384c..fd76f7d 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -278,6 +278,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Kontrollo nivelin dhe pozicionimin e zmadhimit të ekranit."</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Kryen gjeste"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Mund të trokasë, rrëshqasë, bashkojë gishtat dhe kryejë gjeste të tjera."</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"Gjestet e gjurmës së gishtit"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"Mund të kapë gjestet e kryera në sensorin e gjurmës së gishtit të pajisjeve."</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"çaktivizo ose modifiko shiritin e statusit"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"Lejon aplikacionin të çaktivizojë shiritin e statusit dhe të heqë ikonat e sistemit."</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"të bëhet shiriti i statusit"</string>
@@ -1146,6 +1148,8 @@
<string name="usb_notification_message" msgid="3370903770828407960">"Trokit për më shumë opsione."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"Korrigjuesi i USB-së i lidhur"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Trokit për të çaktivizuar korrigjimin e gabimeve të USB-së."</string>
+ <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
+ <skip />
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Po merret raporti i defekteve në kod…"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Të ndahet raporti i defektit në kod?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Po ndan raportin e defekteve në kod..."</string>
@@ -1689,4 +1693,7 @@
<string name="app_category_news" msgid="7496506240743986873">"Lajme dhe revista"</string>
<string name="app_category_maps" msgid="5878491404538024367">"Harta dhe navigim"</string>
<string name="app_category_productivity" msgid="3742083261781538852">"Produktivitet"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"Hapësira ruajtëse e pajisjes"</string>
+ <!-- no translation found for adb_debugging_notification_channel_tv (5537766997350092316) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-sr-watch/styles_material.xml b/core/res/res/values-sr-watch/styles_material.xml
deleted file mode 100644
index 36a459d..0000000
--- a/core/res/res/values-sr-watch/styles_material.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 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.
- -->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see styles_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"candidates"</font></string>
-</resources>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 93253c2..54b0fae 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -281,6 +281,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Управља нивоом зумирања приказа и одређивањем положаја."</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Обављање покрета"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Може да додирује, листа, скупља приказ и обавља друге покрете."</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"Покрети за отисак прста"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"Може да региструје покрете на сензору за отисак прста на уређају."</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"онемогућавање или измена статусне траке"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"Дозвољава апликацији да онемогући статусну траку или да додаје и уклања системске иконе."</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"функционисање као статусна трака"</string>
@@ -1166,6 +1168,7 @@
<string name="usb_notification_message" msgid="3370903770828407960">"Додирните за још опција."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"Отклањање грешака са USB-а је успостављено"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Додирните да бисте онемогућили отклањање грешака са USB-а."</string>
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Изаберите да бисте онемогућили отклањања грешака са USB-а."</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Извештај о грешци се генерише…"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Желите ли да поделите извештај о грешци?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Дели се извештај о грешци…"</string>
@@ -1720,4 +1723,7 @@
<string name="app_category_news" msgid="7496506240743986873">"Новости и часописи"</string>
<string name="app_category_maps" msgid="5878491404538024367">"Мапе и навигација"</string>
<string name="app_category_productivity" msgid="3742083261781538852">"Продуктивност"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"Меморијски простор уређаја"</string>
+ <!-- no translation found for adb_debugging_notification_channel_tv (5537766997350092316) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-sv-watch/styles_material.xml b/core/res/res/values-sv-watch/styles_material.xml
deleted file mode 100644
index f2ab18a..0000000
--- a/core/res/res/values-sv-watch/styles_material.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 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.
- -->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see styles_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"kandidater"</font></string>
-</resources>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 88089b9..e010b96 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -278,6 +278,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Styr skärmens zoomnivå och positionering."</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Göra rörelser"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Kan trycka, svepa, nypa och göra andra rörelser."</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"Fingeravtrycksrörelser"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"Kan registrera rörelser som utförs med hjälp av enhetens fingeravtryckssensor."</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"inaktivera eller ändra statusfält"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"Tillåter att appen inaktiverar statusfältet eller lägger till och tar bort systemikoner."</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"visas i statusfältet"</string>
@@ -1146,6 +1148,7 @@
<string name="usb_notification_message" msgid="3370903770828407960">"Tryck för fler alternativ."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB-felsökning ansluten"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Tryck om du vill inaktivera USB-felsökning."</string>
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Välj att inaktivera USB-felsökning."</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Felrapporten överförs …"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Vill du dela felrapporten?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Felrapporten delas …"</string>
@@ -1689,4 +1692,7 @@
<string name="app_category_news" msgid="7496506240743986873">"Nyheter och tidskrifter"</string>
<string name="app_category_maps" msgid="5878491404538024367">"Kartor och navigation"</string>
<string name="app_category_productivity" msgid="3742083261781538852">"Produktivitet"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"Enhetens lagringsutrymme"</string>
+ <!-- no translation found for adb_debugging_notification_channel_tv (5537766997350092316) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-sw-watch/styles_material.xml b/core/res/res/values-sw-watch/styles_material.xml
deleted file mode 100644
index 01392b2..0000000
--- a/core/res/res/values-sw-watch/styles_material.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 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.
- -->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see styles_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"yanayopendekezwa"</font></string>
-</resources>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index db6f8cf..c363a2216 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -276,6 +276,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Dhibiti kiwango cha kukuza na nafasi cha onyesho."</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Tekeleza ishara"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Unaweza kugonga, kutelezesha kidole, kubana na kutekeleza ishara zingine."</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"Ishara za alama ya kidole"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"Inaweza kurekodi ishara zinazotekelezwa kwenye kitambua alama ya kidole."</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"zima au rekebisha mwambaa hali"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"Inaruhusu programu kulemaza upau wa hali au kuongeza na kutoa ikoni za mfumo."</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"kuwa sehemu ya arifa"</string>
@@ -1144,6 +1146,7 @@
<string name="usb_notification_message" msgid="3370903770828407960">"Gonga ili upate chaguo zaidi."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"Utatuaji wa USB umeunganishwa"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Gonga ili uzime utatuaji wa USB."</string>
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Chagua ili kulemaza utatuaji USB."</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Inatayarisha ripoti ya hitilafu…"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Ungependa kushiriki ripoti ya hitilafu?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Inashiriki ripoti ya hitilafu…"</string>
@@ -1687,4 +1690,7 @@
<string name="app_category_news" msgid="7496506240743986873">"Habari na Magazeti"</string>
<string name="app_category_maps" msgid="5878491404538024367">"Ramani na Maelekezo"</string>
<string name="app_category_productivity" msgid="3742083261781538852">"Uzalishaji"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"Hifadhi ya kifaa"</string>
+ <!-- no translation found for adb_debugging_notification_channel_tv (5537766997350092316) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ta-watch/styles_material.xml b/core/res/res/values-ta-watch/styles_material.xml
deleted file mode 100644
index d4605e6..0000000
--- a/core/res/res/values-ta-watch/styles_material.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 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.
- -->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see styles_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"கேன்டிடேட்ஸ்"</font></string>
-</resources>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index e259a39..8a70c4e 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -278,6 +278,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"திரையின் ஜூம் அளவையும் நிலையையும் கட்டுப்படுத்தலாம்."</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"சைகைகளைச் செயல்படுத்துதல்"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"தட்டலாம், ஸ்வைப் செய்யலாம், பின்ச் செய்யலாம் மற்றும் பிற சைகைகளைச் செயல்படுத்தலாம்."</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"கைரேகை சைகைகள்"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"சாதனத்தின் கைரேகை உணர்வி மேல் செய்யப்படும் சைகைகளைப் படமெடுக்க முடியும்."</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"நிலைப் பட்டியை முடக்குதல் அல்லது மாற்றுதல்"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"நிலைப் பட்டியை முடக்க அல்லது முறைமையில் ஐகான்களைச் சேர்க்க மற்றும் அகற்ற பயன்பாட்டை அனுமதிக்கிறது."</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"நிலைப் பட்டியில் இருக்கும்"</string>
@@ -1146,6 +1148,8 @@
<string name="usb_notification_message" msgid="3370903770828407960">"மேலும் விருப்பங்களுக்கு, தட்டவும்."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB பிழைதிருத்தம் இணைக்கப்பட்டது"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"USB பிழை திருத்தத்தை முடக்க, தட்டவும்."</string>
+ <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
+ <skip />
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"பிழை அறிக்கையை எடுக்கிறது…"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"பிழை அறிக்கையைப் பகிரவா?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"பிழை அறிக்கையைப் பகிர்கிறது…"</string>
@@ -1689,4 +1693,7 @@
<string name="app_category_news" msgid="7496506240743986873">"செய்திகளும் பத்திரிகைகளும்"</string>
<string name="app_category_maps" msgid="5878491404538024367">"வரைபடங்களும் வழிசெலுத்தலும்"</string>
<string name="app_category_productivity" msgid="3742083261781538852">"உற்பத்தித்திறன்"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"சாதனச் சேமிப்பகம்"</string>
+ <!-- no translation found for adb_debugging_notification_channel_tv (5537766997350092316) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-te-watch/styles_material.xml b/core/res/res/values-te-watch/styles_material.xml
deleted file mode 100644
index 877cd58..0000000
--- a/core/res/res/values-te-watch/styles_material.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 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.
- -->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see styles_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"క్యాండిడేట్లు"</font></string>
-</resources>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index dc5653c..4d22092 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -278,6 +278,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"డిస్ప్లే జూమ్ స్థాయి మరియు స్థానాన్ని నియంత్రిస్తుంది."</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"సంజ్ఞలను చేయడం"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"నొక్కగలరు, స్వైప్ చేయగలరు, స్క్రీన్పై రెండు వేళ్లను ఉంచి ఆ వేళ్లను దగ్గరకు లేదా దూరానికి లాగగలరు మరియు ఇతర సంజ్ఞలను చేయగలరు."</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"వేలిముద్ర సంజ్ఞలు"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"పరికరాల వేలిముద్ర సెన్సార్లో నిర్వహించిన సంజ్ఞలను క్యాప్చర్ చేయవచ్చు."</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"స్థితి బార్ను నిలిపివేయడం లేదా సవరించడం"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"స్థితి బార్ను నిలిపివేయడానికి లేదా సిస్టమ్ చిహ్నాలను జోడించడానికి మరియు తీసివేయడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"స్థితి పట్టీగా ఉండటం"</string>
@@ -1146,6 +1148,8 @@
<string name="usb_notification_message" msgid="3370903770828407960">"మరిన్ని ఎంపికల కోసం నొక్కండి."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB డీబగ్గింగ్ కనెక్ట్ చేయబడింది"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"USB డీబగ్గింగ్ను నిలిపివేయడానికి నొక్కండి."</string>
+ <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
+ <skip />
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"బగ్ నివేదికను తీస్తోంది…"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"బగ్ నివేదికను భాగస్వామ్యం చేయాలా?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"బగ్ నివేదికను భాగస్వామ్యం చేస్తోంది..."</string>
@@ -1689,4 +1693,7 @@
<string name="app_category_news" msgid="7496506240743986873">"వార్తలు & వార్తాపత్రికలు"</string>
<string name="app_category_maps" msgid="5878491404538024367">"మ్యాప్స్ & నావిగేషన్"</string>
<string name="app_category_productivity" msgid="3742083261781538852">"ఉత్పాదకత"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"పరికర నిల్వ"</string>
+ <!-- no translation found for adb_debugging_notification_channel_tv (5537766997350092316) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-th-watch/styles_material.xml b/core/res/res/values-th-watch/styles_material.xml
deleted file mode 100644
index 3227ced..0000000
--- a/core/res/res/values-th-watch/styles_material.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 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.
- -->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see styles_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"ผู้สมัคร"</font></string>
-</resources>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index ae84073..38dfd84 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -278,6 +278,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"ควบคุมระดับการซูมและการวางตำแหน่งของการแสดงผล"</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"ทำท่าทางสัมผัส"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"สามารถแตะ เลื่อน บีบ และทำท่าทางสัมผัสอื่นๆ"</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"ท่าทางสัมผัสลายนิ้วมือ"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"สามารถจับท่าทางสัมผัสที่เกิดขึ้นบนเซ็นเซอร์ลายนิ้วมือของอุปกรณ์"</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"ปิดการใช้งานหรือแก้ไขแถบสถานะ"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"อนุญาตให้แอปพลิเคชันปิดใช้งานแถบสถานะหรือเพิ่มและนำไอคอนระบบออก"</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"เป็นแถบสถานะ"</string>
@@ -1146,6 +1148,7 @@
<string name="usb_notification_message" msgid="3370903770828407960">"แตะเพื่อดูตัวเลือกเพิ่มเติม"</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"เชื่อมต่อการแก้ไขข้อบกพร่อง USB แล้ว"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"แตะเพื่อปิดใช้การแก้ไขข้อบกพร่องของ USB"</string>
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"เลือกเพื่อปิดใช้งานการแก้ไขข้อบกพร่อง USB"</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"กำลังสร้างรายงานข้อบกพร่อง…"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"แชร์รายงานข้อบกพร่องไหม"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"กำลังแชร์รายงานข้อบกพร่อง…"</string>
@@ -1689,4 +1692,7 @@
<string name="app_category_news" msgid="7496506240743986873">"ข่าวสารและนิตยสาร"</string>
<string name="app_category_maps" msgid="5878491404538024367">"แผนที่และการนำทาง"</string>
<string name="app_category_productivity" msgid="3742083261781538852">"ประสิทธิภาพการทำงาน"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"พื้นที่เก็บข้อมูลของอุปกรณ์"</string>
+ <!-- no translation found for adb_debugging_notification_channel_tv (5537766997350092316) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-tl-watch/styles_material.xml b/core/res/res/values-tl-watch/styles_material.xml
deleted file mode 100644
index 70e7a7a..0000000
--- a/core/res/res/values-tl-watch/styles_material.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 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.
- -->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see styles_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"mga kandidato"</font></string>
-</resources>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 3ca68da..06c6aa7 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -278,6 +278,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Kontrolin ang antas ng pag-zoom at pagpoposisyon ng display."</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Magsagawa ng mga galaw"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"May kakayahang mag-tap, mag-swipe, mag-pinch at magsagawa ng iba pang mga galaw."</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"Mga galaw gamit ang fingerprint"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"Makukunan ang mga galaw na ginawa sa sensor para sa fingerprint ng mga device."</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"i-disable o baguhin ang status bar"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"Pinapayagan ang app na i-disable ang status bar o magdagdag at mag-alis ng mga icon ng system."</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"maging status bar"</string>
@@ -1146,6 +1148,7 @@
<string name="usb_notification_message" msgid="3370903770828407960">"I-tap para sa higit pang mga opsyon."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"Konektado ang debugging ng USB"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"I-tap upang i-disable ang pag-debug ng USB."</string>
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Piliin upang i-disable ang debugging ng USB."</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Kinukuha ang ulat ng bug…"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Gusto mo bang ibahagi ang ulat ng bug?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Ibinabahagi ang ulat ng bug…"</string>
@@ -1689,4 +1692,7 @@
<string name="app_category_news" msgid="7496506240743986873">"Balita at Mga Magazine"</string>
<string name="app_category_maps" msgid="5878491404538024367">"Mga Mapa at Navigation"</string>
<string name="app_category_productivity" msgid="3742083261781538852">"Productivity"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"Storage ng device"</string>
+ <!-- no translation found for adb_debugging_notification_channel_tv (5537766997350092316) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-tr-watch/styles_material.xml b/core/res/res/values-tr-watch/styles_material.xml
deleted file mode 100644
index 36a459d..0000000
--- a/core/res/res/values-tr-watch/styles_material.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 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.
- -->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see styles_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"candidates"</font></string>
-</resources>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 70183a1..c6dd402 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -278,6 +278,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Ekranın yakınlaştırma seviyesini ve konumunu kontrol edin."</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Haraketleri yapma"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Hafifçe dokunabilir, hızlıca kaydırabilir, sıkıştırabilir ve diğer hareketleri yapabilirsiniz."</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"Parmak izi hareketleri"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"Cihazların parmak izi sensörlerinde gerçekleştirilen hareketleri yakalayabilir."</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"durum çubuğunu devre dışı bırak veya değiştir"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"Uygulamaya, durum çubuğunu devre dışı bırakma ve sistem simgelerini ekleyip kaldırma izni verir."</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"durum çubuğunda olma"</string>
@@ -1146,6 +1148,7 @@
<string name="usb_notification_message" msgid="3370903770828407960">"Diğer seçenekler için dokunun."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB hata ayıklaması bağlandı"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"USB hata ayıklama özelliğini devre dışı bırakmak için dokunun."</string>
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB hata ayıklamasını devre dışı bırakmak için tıklayın."</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Hata raporu alınıyor…"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Hata raporu paylaşılsın mı?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Hata raporu paylaşılıyor..."</string>
@@ -1232,7 +1235,7 @@
<string name="wallpaper_binding_label" msgid="1240087844304687662">"Duvar Kağıdı"</string>
<string name="chooser_wallpaper" msgid="7873476199295190279">"Duvar kağıdını değiştir"</string>
<string name="notification_listener_binding_label" msgid="2014162835481906429">"Bildirim dinleyici"</string>
- <string name="vr_listener_binding_label" msgid="4316591939343607306">"Sanal Gerçeklik dinleyici"</string>
+ <string name="vr_listener_binding_label" msgid="4316591939343607306">"VR dinleyici"</string>
<string name="condition_provider_service_binding_label" msgid="1321343352906524564">"Durum sağlayıcı"</string>
<string name="notification_ranker_binding_label" msgid="774540592299064747">"Bildirim sıralama hizmeti"</string>
<string name="vpn_title" msgid="19615213552042827">"VPN etkinleştirildi"</string>
@@ -1689,4 +1692,7 @@
<string name="app_category_news" msgid="7496506240743986873">"Haberler ve Dergiler"</string>
<string name="app_category_maps" msgid="5878491404538024367">"Haritalar ve Navigasyon"</string>
<string name="app_category_productivity" msgid="3742083261781538852">"Verimlilik"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"Cihazdaki depolama alanı"</string>
+ <!-- no translation found for adb_debugging_notification_channel_tv (5537766997350092316) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-uk-watch/styles_material.xml b/core/res/res/values-uk-watch/styles_material.xml
deleted file mode 100644
index 698d5b0..0000000
--- a/core/res/res/values-uk-watch/styles_material.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 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.
- -->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see styles_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"варіанти"</font></string>
-</resources>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 3fd1f23..6b5070a 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -284,6 +284,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Контролювати масштаб і розташування екрана."</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Виконання жестів"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Можна торкатися, проводити пальцем, стискати пальці та виконувати інші жести."</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"Жести на сканері відбитків пальців"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"Фіксуються жести на сканері відбитків пальців."</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"вимикати чи змін. рядок стану"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"Дозволяє програмі вимикати рядок стану чи додавати та видаляти піктограми системи."</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"відображатися як рядок стану"</string>
@@ -1186,6 +1188,7 @@
<string name="usb_notification_message" msgid="3370903770828407960">"Торкніться, щоб переглянути більше опцій."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"Налагодження USB завершено"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Торкніться, щоб вимкнути налагодження USB."</string>
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Вибер., щоб вимкн. налагодж. USB."</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Створюється повідомлення про помилку…"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Надіслати звіт про помилку?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Надсилається звіт про помилку…"</string>
@@ -1751,4 +1754,7 @@
<string name="app_category_news" msgid="7496506240743986873">"Новини та журнали"</string>
<string name="app_category_maps" msgid="5878491404538024367">"Карти й навігація"</string>
<string name="app_category_productivity" msgid="3742083261781538852">"Продуктивність"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"Пам’ять пристрою"</string>
+ <!-- no translation found for adb_debugging_notification_channel_tv (5537766997350092316) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ur-watch/styles_material.xml b/core/res/res/values-ur-watch/styles_material.xml
deleted file mode 100644
index e569c7c..0000000
--- a/core/res/res/values-ur-watch/styles_material.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 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.
- -->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see styles_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"امیدواران"</font></string>
-</resources>
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index 86515b3..9f77dbb 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -278,6 +278,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"ڈسپلے کے زوم کی سطح اور پوزیشن کو کنٹرول کریں۔"</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"اشارے انجام دیں"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"تھپتھپانا، سوائپ کرنا، چٹکی بھرنا اور دیگر اشارے انجام دے سکتی ہے"</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"فنگرپرنٹ کے اشارے"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"آلات کے فنگر پرنٹ سینسر پر کیے گئے اشاروں کو کیپچر کر سکتا ہے۔"</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"اسٹیٹس بار کو غیر فعال یا اس میں ترمیم کریں"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"ایپ کو اسٹیٹس بار غیر فعال کرنے یا سسٹم آئیکنز شامل کرنے اور ہٹانے کی اجازت دیتا ہے۔"</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"بطور اسٹیٹس بار کام لیں"</string>
@@ -1146,6 +1148,8 @@
<string name="usb_notification_message" msgid="3370903770828407960">"مزید اختیارات کیلئے تھپتھپائیں۔"</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB ڈیبگ کرنا مربوط ہو گیا"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"USB ڈیبگنگ کو غیر فعال کرنے کیلئے تھپتھپائیں۔"</string>
+ <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
+ <skip />
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"بگ رپورٹ لی جا رہی ہے…"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"بگ رپورٹ کا اشتراک کریں؟"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"بگ رپورٹ کا اشتراک ہو رہا ہے…"</string>
@@ -1689,4 +1693,7 @@
<string name="app_category_news" msgid="7496506240743986873">"خبریں اور میگزین"</string>
<string name="app_category_maps" msgid="5878491404538024367">"نقشے اور نیویگیشن"</string>
<string name="app_category_productivity" msgid="3742083261781538852">"پروڈکٹیوٹی"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"آلہ کی اسٹوریج"</string>
+ <!-- no translation found for adb_debugging_notification_channel_tv (5537766997350092316) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-uz-watch/styles_material.xml b/core/res/res/values-uz-watch/styles_material.xml
deleted file mode 100644
index 3cb38d6..0000000
--- a/core/res/res/values-uz-watch/styles_material.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 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.
- -->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see styles_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"nomzodlar"</font></string>
-</resources>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index 5f978c6..6f07869 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -278,6 +278,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Ekranni kattalashtirish darajasi va joylashuvini boshqaradi."</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Imo-ishoralar bilan boshqarish"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Bosish, surish; jipslashtirish va boshqa imo-ishoralarni amalga oshirish mumkin."</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"Barmoq izi ishoralari"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"Barmoq izi skanerlarida kiritilgan ishoralarni taniy oladi."</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"holat panelini o‘zgartirish yoki o‘chirish"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"Ilova holat panelini o‘chirib qo‘yishi hamda tizim ikonkalarini qo‘shishi yoki olib tashlashi mumkin."</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"holat qatorida ko‘rinishi"</string>
@@ -1146,6 +1148,8 @@
<string name="usb_notification_message" msgid="3370903770828407960">"Boshqa parametrlarini ko‘rish uchun bosing."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB orqali nosozliklarni tuzatish"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"O‘chirib qo‘yish uchun bu yerga bosing."</string>
+ <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
+ <skip />
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Xatoliklar hisoboti olinmoqda…"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Xatoliklar hisoboti yuborilsinmi?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Xatoliklar hisoboti yuborilmoqda…"</string>
@@ -1689,4 +1693,7 @@
<string name="app_category_news" msgid="7496506240743986873">"Yangiliklar va jurnallar"</string>
<string name="app_category_maps" msgid="5878491404538024367">"Xaritalar va navigatsiya"</string>
<string name="app_category_productivity" msgid="3742083261781538852">"Ish va unumdorlik"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"Qurilma xotirasi"</string>
+ <!-- no translation found for adb_debugging_notification_channel_tv (5537766997350092316) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-vi-watch/styles_material.xml b/core/res/res/values-vi-watch/styles_material.xml
deleted file mode 100644
index 36a459d..0000000
--- a/core/res/res/values-vi-watch/styles_material.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 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.
- -->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see styles_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"candidates"</font></string>
-</resources>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index e2c6e32..f2d9c8f 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -278,6 +278,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Kiểm soát vị trí và mức thu phóng của màn hình."</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Thực hiện cử chỉ"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Có thể nhấn, vuốt, chụm và thực hiện các cử chỉ khác."</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"Cử chỉ vân tay"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"Có thể ghi lại các cử chỉ được thực hiện trên cảm biến vân tay của thiết bị."</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"vô hiệu hóa hoặc sửa đổi thanh trạng thái"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"Cho phép ứng dụng vô hiệu hóa thanh trạng thái hoặc thêm và xóa biểu tượng hệ thống."</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"trở thành thanh trạng thái"</string>
@@ -1146,6 +1148,7 @@
<string name="usb_notification_message" msgid="3370903770828407960">"Nhấn để biết thêm tùy chọn."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"Gỡ lỗi USB đã được kết nối"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Nhấn để vô hiệu hóa gỡ lỗi USB."</string>
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Chọn để vô hiệu hóa gỡ lỗi USB."</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Đang thu thập báo cáo lỗi…"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Chia sẻ báo cáo lỗi?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Đang chia sẻ báo cáo lỗi…"</string>
@@ -1689,4 +1692,7 @@
<string name="app_category_news" msgid="7496506240743986873">"Tin tức và tạp chí"</string>
<string name="app_category_maps" msgid="5878491404538024367">"Bản đồ và dẫn đường"</string>
<string name="app_category_productivity" msgid="3742083261781538852">"Sản xuất"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"Bộ nhớ của thiết bị"</string>
+ <!-- no translation found for adb_debugging_notification_channel_tv (5537766997350092316) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-zh-rCN-watch/styles_material.xml b/core/res/res/values-zh-rCN-watch/styles_material.xml
deleted file mode 100644
index 36a459d..0000000
--- a/core/res/res/values-zh-rCN-watch/styles_material.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 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.
- -->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see styles_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"candidates"</font></string>
-</resources>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 12f419b..96eba47 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -278,6 +278,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"控制显示内容的缩放级别和位置。"</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"执行手势"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"可执行点按、滑动、双指张合等手势。"</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"指纹手势"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"可以捕获在设备指纹传感器上执行的手势。"</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"停用或修改状态栏"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"允许应用停用状态栏或者增删系统图标。"</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"用作状态栏"</string>
@@ -1146,6 +1148,7 @@
<string name="usb_notification_message" msgid="3370903770828407960">"点按即可查看更多选项。"</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"已连接到USB调试"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"点按即可停用 USB 调试功能。"</string>
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"选择停用USB调试。"</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"正在生成错误报告…"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"要分享错误报告吗?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"正在分享错误报告…"</string>
@@ -1689,4 +1692,7 @@
<string name="app_category_news" msgid="7496506240743986873">"新闻和杂志"</string>
<string name="app_category_maps" msgid="5878491404538024367">"地图和导航"</string>
<string name="app_category_productivity" msgid="3742083261781538852">"办公"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"设备存储空间"</string>
+ <!-- no translation found for adb_debugging_notification_channel_tv (5537766997350092316) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-zh-rHK-watch/styles_material.xml b/core/res/res/values-zh-rHK-watch/styles_material.xml
deleted file mode 100644
index 36a459d..0000000
--- a/core/res/res/values-zh-rHK-watch/styles_material.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 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.
- -->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see styles_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"candidates"</font></string>
-</resources>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index 9996617..234d45b 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -278,6 +278,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"控制顯示屏的縮放程度和位置。"</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"執行手勢"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"可以輕按、快速滑動和兩指縮放,並執行其他手勢。"</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"指紋手勢"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"可擷取裝置指紋感應器上執行的手勢。"</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"停用或修改狀態列"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"允許應用程式停用狀態列,並可新增或移除系統圖示。"</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"成為狀態列"</string>
@@ -1146,6 +1148,7 @@
<string name="usb_notification_message" msgid="3370903770828407960">"輕按即可查看更多選項。"</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"已連接 USB 偵錯工具"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"輕按即可停用 USB 偵錯功能。"</string>
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"選取即可停用 USB 偵錯。"</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"正在取得錯誤報告…"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"要分享錯誤報告嗎?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"正在分享錯誤報告…"</string>
@@ -1689,4 +1692,7 @@
<string name="app_category_news" msgid="7496506240743986873">"新聞和雜誌"</string>
<string name="app_category_maps" msgid="5878491404538024367">"地圖和導航"</string>
<string name="app_category_productivity" msgid="3742083261781538852">"生產力應用程式"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"裝置儲存空間"</string>
+ <!-- no translation found for adb_debugging_notification_channel_tv (5537766997350092316) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-zh-rTW-watch/styles_material.xml b/core/res/res/values-zh-rTW-watch/styles_material.xml
deleted file mode 100644
index 36a459d..0000000
--- a/core/res/res/values-zh-rTW-watch/styles_material.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 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.
- -->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see styles_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"candidates"</font></string>
-</resources>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 04c5a8e..0f0f176 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -278,6 +278,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"控管顯示畫面的縮放等級和位置。"</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"使用手勢"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"可使用輕觸、滑動和雙指撥動等手勢。"</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"指紋手勢"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"可以擷取在裝置指紋感應器上執行的手勢。"</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"停用或變更狀態列"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"允許應用程式停用狀態列,並可新增或移除系統圖示。"</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"以狀態列顯示"</string>
@@ -1146,6 +1148,7 @@
<string name="usb_notification_message" msgid="3370903770828407960">"輕觸即可查看更多選項。"</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"已連接 USB 偵錯工具"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"輕觸即可停用 USB 偵錯。"</string>
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"選取以停用 USB 偵錯。"</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"正在接收錯誤報告…"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"要分享錯誤報告嗎?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"正在分享錯誤報告…"</string>
@@ -1689,4 +1692,7 @@
<string name="app_category_news" msgid="7496506240743986873">"新聞和雜誌"</string>
<string name="app_category_maps" msgid="5878491404538024367">"地圖和導航"</string>
<string name="app_category_productivity" msgid="3742083261781538852">"生產應用"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"裝置儲存空間"</string>
+ <!-- no translation found for adb_debugging_notification_channel_tv (5537766997350092316) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-zu-watch/styles_material.xml b/core/res/res/values-zu-watch/styles_material.xml
deleted file mode 100644
index 8b69fef..0000000
--- a/core/res/res/values-zu-watch/styles_material.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 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.
- -->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Material themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see styles_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="candidates_style" msgid="8052530148128607468"><font color="#80cbc4">"amakhandidethi"</font></string>
-</resources>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 095341a..938b332 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -278,6 +278,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Lawula ileveli yokusondeza yesibonisi nendawo."</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Yenza ukuthinta"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Ingathepha, iswayiphe, incinze, futhi yenze okunye ukuthintwa."</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"Ukuthinta kwezigxivizo zeminwe"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="7102111919385702482">"Ingathatha ukuthinta okwenziwe kunzwa yezigxivizo zeminwe zamadivayisi."</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"khubaza noma guqula ibha yomumo"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"Ivumela uhlelo lokusebenza ukuthi yenze umudwa ochaza ngesimo ukuthi ungasebenzi noma ukufaka noma ukukhipha izithonjana zohlelo."</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"yiba yibha yesimo"</string>
@@ -1146,6 +1148,7 @@
<string name="usb_notification_message" msgid="3370903770828407960">"Thepha ngezinketho eziningi."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"Ukulungisa iphutha le-USB kuxhunyiwe"</string>
<string name="adb_active_notification_message" msgid="4948470599328424059">"Thepha ukuze ukhubaze ukususa isiphazamisi se-USB."</string>
+ <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Khetha ukuvimbela ukulungisa iphutha le-USB."</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Ithatha umbiko wesiphazamisi..."</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Yabelana ngombiko wesiphazamisi?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Yabelana ngombiko wesiphazamisi..."</string>
@@ -1689,4 +1692,7 @@
<string name="app_category_news" msgid="7496506240743986873">"Izindaba nomagazini"</string>
<string name="app_category_maps" msgid="5878491404538024367">"Amamephu nokuzula"</string>
<string name="app_category_productivity" msgid="3742083261781538852">"Ukukhiqiza"</string>
+ <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"Isitoreji sedivayisi"</string>
+ <!-- no translation found for adb_debugging_notification_channel_tv (5537766997350092316) -->
+ <skip />
</resources>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index c548219..7f49f05 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -3392,6 +3392,8 @@
<flag name="flagRetrieveInteractiveWindows" value="0x00000040" />
<!-- Has flag {@link android.accessibilityservice.AccessibilityServiceInfo#FLAG_ENABLE_ACCESSIBILITY_VOLUME} -->
<flag name="flagEnableAccessibilityVolume" value="0x00000080" />
+ <!-- Has flag {@link android.accessibilityservice.AccessibilityServiceInfo#FLAG_REQUEST_ACCESSIBILITY_BUTTON} -->
+ <flag name="flagRequestAccessibilityButton" value="0x00000100" />
<!-- Has flag {@link android.accessibilityservice.AccessibilityServiceInfo#FLAG_CAPTURE_FINGERPRINT_GESTURES} -->
<flag name="flagCaptureFingerprintGestures" value="0x00000200" />
</attr>
@@ -3429,18 +3431,9 @@
<attr name="canRequestFilterKeyEvents" format="boolean" />
<!-- Attribute whether the accessibility service wants to be able to control
display magnification.
- <p>
- Required to allow setting the {@link android.accessibilityservice
- #AccessibilityServiceInfo#FLAG_CAN_CONTROL_MAGNIFICATION} flag.
- </p>
-->
<attr name="canControlMagnification" format="boolean" />
- <!-- Attribute whether the accessibility service wants to be able to perform gestures.
- <p>
- Required to allow setting the {@link android.accessibilityservice
- #AccessibilityServiceInfo#FLAG_CAN_PERFORM_GESTURES} flag.
- </p>
- -->
+ <!-- Attribute whether the accessibility service wants to be able to perform gestures. -->
<attr name="canPerformGestures" format="boolean" />
<!-- Attribute whether the accessibility service wants to be able to capture gestures from
the fingerprint sensor.
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 6d0fdb6..76f4a76 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -885,6 +885,12 @@
will run against. -->
<attr name="targetPackage" format="string" />
+ <!-- The name of an application's processes that an Instrumentation object
+ will run against. If not specified, only runs in the main process of the targetPackage.
+ Can either be a comma-separated list of process names or '*' for any process that
+ launches to run targetPackage code. -->
+ <attr name="targetProcess" format="string" />
+
<!-- Flag indicating that an Instrumentation class wants to take care
of starting/stopping profiling itself, rather than relying on
the default behavior of profiling the complete time it is running.
@@ -2050,9 +2056,6 @@
in a task/stack that isn't focusable. This flag allows them to be focusable.-->
<attr name="alwaysFocusable" format="boolean" />
<attr name="enableVrMode" />
- <!-- @hide This activity is a launcher which should always show up on the top of others.
- This attribute is ignored if the activity isn't a launcher. -->
- <attr name="onTopLauncher" format="boolean" />
<attr name="rotationAnimation" />
<attr name="visibleToInstantApps" />
<!-- The code for this component is located in the given split. -->
@@ -2297,6 +2300,7 @@
is a period then it is appended to your package name. -->
<attr name="name" />
<attr name="targetPackage" />
+ <attr name="targetProcess" />
<attr name="label" />
<attr name="icon" />
<attr name="roundIcon" />
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index 927988f..9824051 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -475,9 +475,6 @@
<dimen name="chooser_grid_padding">0dp</dimen>
- <item type="dimen" format="integer" name="time_picker_column_start_material">0</item>
- <item type="dimen" format="integer" name="time_picker_column_end_material">1</item>
-
<item type="dimen" name="aerr_padding_list_top">15dp</item>
<item type="dimen" name="aerr_padding_list_bottom">8dp</item>
diff --git a/core/res/res/values/dimens_material.xml b/core/res/res/values/dimens_material.xml
index ebe577c..e3fdcec 100644
--- a/core/res/res/values/dimens_material.xml
+++ b/core/res/res/values/dimens_material.xml
@@ -149,6 +149,7 @@
<dimen name="timepicker_radial_picker_dimen">296dp</dimen>
<dimen name="timepicker_radial_picker_top_margin">16dp</dimen>
<dimen name="timepicker_radial_picker_horizontal_margin">16dp</dimen>
+ <dimen name="timepicker_edit_text_size">24sp</dimen>
<!-- Used by RadialTimePicker in clock-style TimePicker. -->
<dimen name="timepicker_selector_radius">20dp</dimen>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index d795d80..1b48469 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2777,7 +2777,7 @@
<public name="paddingVertical" />
<public name="visibleToInstantApps" />
<public name="keyboardNavigationCluster" />
- <public name="__removed0" />
+ <public name="targetProcess" />
<public name="nextClusterForward" />
<public name="__removed1" />
<public name="textColorError" />
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 8b9b3b2..19c5643 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -3064,6 +3064,7 @@
<string name="adb_active_notification_title">USB debugging connected</string>
<!-- Message of notification shown when ADB is actively connected to the phone. -->
<string name="adb_active_notification_message">Tap to disable USB debugging.</string>
+ <string name="adb_active_notification_message" product="tv">Select to disable USB debugging.</string>
<!-- Title of notification shown to indicate that bug report is being collected. -->
<string name="taking_remote_bugreport_notification_title">Taking bug report\u2026</string>
@@ -4468,4 +4469,22 @@
<!-- Channel name for DeviceStorageMonitor notifications -->
<string name="device_storage_monitor_notification_channel">Device storage</string>
+ <!-- Channel name for UsbDeviceManager adb debugging notifications -->
+ <string name="adb_debugging_notification_channel_tv">USB debugging</string>
+
+ <!-- Label for the time picker hour input field. [CHAR LIMIT=20] -->
+ <string name="time_picker_hour_label">hour</string>
+ <!-- Label for the time picker minute input field. [CHAR LIMIT=20] -->
+ <string name="time_picker_minute_label">minute</string>
+ <!-- The title for the time picker dialog. [CHAR LIMIT=NONE] -->
+ <string name="time_picker_header_text">Set time</string>
+ <!-- Error shown to the user if they type in invalid hour or minute in the time picker. [CHAR LIMIT=NONE] -->
+ <string name="time_picker_input_error">Enter a valid time</string>
+ <!-- Label shown to the user in time picker to let them know that should type in time. [CHAR LIMIT=NONE] -->
+ <string name="time_picker_prompt_label">Type in time</string>
+ <!-- Accessibility string used for describing the button in time picker that changes the dialog to text input mode. [CHAR LIMIT=NONE] -->
+ <string name="time_picker_text_input_mode_description">Switch to text input mode for the time input.</string>
+ <!-- Accessibility string used for describing the button in time picker that changes the dialog to circular clock mode. [CHAR LIMIT=NONE] -->
+ <string name="time_picker_radial_mode_description">Switch to clock mode for the time input.</string>
+
</resources>
diff --git a/core/res/res/values/styles_material.xml b/core/res/res/values/styles_material.xml
index 1e15348..8f061a3 100644
--- a/core/res/res/values/styles_material.xml
+++ b/core/res/res/values/styles_material.xml
@@ -426,6 +426,21 @@
<item name="textColor">@color/primary_text_secondary_when_activated_material_inverse</item>
</style>
+ <style name="TextAppearance.Material.TimePicker.InputHeader" parent="TextAppearance.Material">
+ <item name="textSize">@dimen/text_size_display_1_material</item>
+ <item name="textColor">@color/white</item>
+ <item name="fontFamily">sans-serif-medium</item>
+ </style>
+
+ <style name="TextAppearance.Material.TimePicker.InputField" parent="TextAppearance.Material">
+ <item name="textSize">@dimen/timepicker_edit_text_size</item>
+ </style>
+
+ <style name="TextAppearance.Material.TimePicker.PromptLabel" parent="TextAppearance.Material">
+ <item name="textSize">@dimen/timepicker_text_size_normal</item>
+ <item name="fontFamily">sans-serif-medium</item>
+ </style>
+
<style name="TextAppearance.Material.DatePicker.YearLabel" parent="TextAppearance.Material">
<item name="textColor">@color/primary_text_secondary_when_activated_material_inverse</item>
<item name="textSize">@dimen/date_picker_year_label_size</item>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 571aa17..4143355 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -120,6 +120,7 @@
<java-symbol type="id" name="permission_list" />
<java-symbol type="id" name="pickers" />
<java-symbol type="id" name="prefs" />
+ <java-symbol type="id" name="prefs_container" />
<java-symbol type="id" name="prefs_frame" />
<java-symbol type="id" name="prev" />
<java-symbol type="id" name="progress" />
@@ -1914,6 +1915,7 @@
<java-symbol type="string" name="smv_process" />
<java-symbol type="string" name="tethered_notification_message" />
<java-symbol type="string" name="tethered_notification_title" />
+ <java-symbol type="string" name="adb_debugging_notification_channel_tv" />
<java-symbol type="string" name="usb_accessory_notification_title" />
<java-symbol type="string" name="usb_mtp_notification_title" />
<java-symbol type="string" name="usb_charging_notification_title" />
@@ -2841,4 +2843,21 @@
<!-- Accessibility fingerprint gestures -->
<java-symbol type="string" name="capability_title_canCaptureFingerprintGestures" />
<java-symbol type="string" name="capability_desc_canCaptureFingerprintGestures" />
+
+ <!-- Time picker -->
+ <java-symbol type="id" name="toggle_mode"/>
+ <java-symbol type="id" name="input_mode"/>
+ <java-symbol type="id" name="input_header"/>
+ <java-symbol type="id" name="input_separator"/>
+ <java-symbol type="id" name="input_hour"/>
+ <java-symbol type="id" name="input_minute"/>
+ <java-symbol type="id" name="am_pm_spinner"/>
+ <java-symbol type="id" name="label_hour"/>
+ <java-symbol type="id" name="label_minute"/>
+ <java-symbol type="id" name="label_error"/>
+ <java-symbol type="layout" name="time_picker_text_input_material"/>
+ <java-symbol type="drawable" name="btn_keyboard_key_material"/>
+ <java-symbol type="drawable" name="btn_event_material"/>
+ <java-symbol type="string" name="time_picker_text_input_mode_description"/>
+ <java-symbol type="string" name="time_picker_radial_mode_description"/>
</resources>
diff --git a/core/tests/coretests/res/font/samplefont.ttf b/core/tests/coretests/res/font/samplefont.ttf
new file mode 100644
index 0000000..2852302
--- /dev/null
+++ b/core/tests/coretests/res/font/samplefont.ttf
Binary files differ
diff --git a/core/tests/coretests/res/font/samplefont2.ttf b/core/tests/coretests/res/font/samplefont2.ttf
new file mode 100644
index 0000000..2852302
--- /dev/null
+++ b/core/tests/coretests/res/font/samplefont2.ttf
Binary files differ
diff --git a/core/tests/coretests/res/font/samplefont3.ttf b/core/tests/coretests/res/font/samplefont3.ttf
new file mode 100644
index 0000000..2852302
--- /dev/null
+++ b/core/tests/coretests/res/font/samplefont3.ttf
Binary files differ
diff --git a/core/tests/coretests/res/font/samplefont4.ttf b/core/tests/coretests/res/font/samplefont4.ttf
new file mode 100644
index 0000000..2852302
--- /dev/null
+++ b/core/tests/coretests/res/font/samplefont4.ttf
Binary files differ
diff --git a/core/tests/coretests/res/font/samplexmlfont.xml b/core/tests/coretests/res/font/samplexmlfont.xml
new file mode 100644
index 0000000..bb813e1
--- /dev/null
+++ b/core/tests/coretests/res/font/samplexmlfont.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<font-family xmlns:android="http://schemas.android.com/apk/res/android">
+ <font android:fontStyle="normal" android:fontWeight="400" android:font="@font/samplefont" />
+ <font android:fontStyle="italic" android:fontWeight="400" android:font="@font/samplefont2" />
+ <font android:fontStyle="normal" android:fontWeight="800" android:font="@font/samplefont3" />
+ <font android:fontStyle="italic" android:fontWeight="800" android:font="@font/samplefont4" />
+</font-family>
\ No newline at end of file
diff --git a/core/tests/coretests/src/android/content/res/FontResourcesParserTest.java b/core/tests/coretests/src/android/content/res/FontResourcesParserTest.java
new file mode 100644
index 0000000..380a28774
--- /dev/null
+++ b/core/tests/coretests/src/android/content/res/FontResourcesParserTest.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.content.res;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import android.app.Instrumentation;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.text.FontConfig;
+
+import com.android.frameworks.coretests.R;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * Tests for {@link FontResourcesParser}.
+ */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class FontResourcesParserTest {
+
+ private Instrumentation mInstrumentation;
+ private Resources mResources;
+
+ @Before
+ public void setup() {
+ mInstrumentation = InstrumentationRegistry.getInstrumentation();
+ mResources = mInstrumentation.getContext().getResources();
+ }
+
+ @Test
+ public void testParse() throws XmlPullParserException, IOException {
+ XmlResourceParser parser = mResources.getXml(R.font.samplexmlfont);
+
+ FontConfig result = FontResourcesParser.parse(parser, mResources);
+
+ assertNotNull(result);
+ List<FontConfig.Family> families = result.getFamilies();
+ assertEquals(1, families.size());
+ List<FontConfig.Font> fonts = families.get(0).getFonts();
+ assertEquals(4, fonts.size());
+ FontConfig.Font font1 = fonts.get(0);
+ assertEquals(400, font1.getWeight());
+ assertEquals(false, font1.isItalic());
+ assertEquals("res/font/samplefont.ttf", font1.getFontName());
+ FontConfig.Font font2 = fonts.get(1);
+ assertEquals(400, font2.getWeight());
+ assertEquals(true, font2.isItalic());
+ assertEquals("res/font/samplefont2.ttf", font2.getFontName());
+ FontConfig.Font font3 = fonts.get(2);
+ assertEquals(800, font3.getWeight());
+ assertEquals(false, font3.isItalic());
+ assertEquals("res/font/samplefont3.ttf", font3.getFontName());
+ FontConfig.Font font4 = fonts.get(3);
+ assertEquals(800, font4.getWeight());
+ assertEquals(true, font4.isItalic());
+ assertEquals("res/font/samplefont4.ttf", font4.getFontName());
+ }
+}
diff --git a/core/tests/coretests/src/android/net/NetworkScorerAppManagerTest.java b/core/tests/coretests/src/android/net/NetworkScorerAppManagerTest.java
index 5bfff26..ce5d3ef 100644
--- a/core/tests/coretests/src/android/net/NetworkScorerAppManagerTest.java
+++ b/core/tests/coretests/src/android/net/NetworkScorerAppManagerTest.java
@@ -19,6 +19,7 @@
import static org.mockito.Mockito.when;
import android.Manifest.permission;
+import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
@@ -30,13 +31,16 @@
import android.net.NetworkScorerAppManager.NetworkScorerAppData;
import android.provider.Settings;
import android.test.InstrumentationTestCase;
+
import com.android.internal.R;
-import java.util.List;
+
import org.mockito.ArgumentMatcher;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
+import java.util.List;
+
public class NetworkScorerAppManagerTest extends InstrumentationTestCase {
@Mock private Context mMockContext;
@Mock private PackageManager mMockPm;
@@ -114,39 +118,40 @@
public void testGetNetworkRecommendationProviderData_scoreNetworksNotGranted()
throws Exception {
- setNetworkRecommendationPackageNames("package1");
- mockScoreNetworksDenied("package1");
- mockRecommendationServiceAvailable("package1", 924 /* packageUid */);
+ final ComponentName recoComponent = new ComponentName("package1", "class1");
+ setNetworkRecommendationPackageNames(recoComponent.getPackageName());
+ mockScoreNetworksDenied(recoComponent.getPackageName());
+ mockRecommendationServiceAvailable(recoComponent, 924 /* packageUid */);
assertNull(mNetworkScorerAppManager.getNetworkRecommendationProviderData());
}
public void testGetNetworkRecommendationProviderData_available() throws Exception {
- setNetworkRecommendationPackageNames("package1");
- mockScoreNetworksGranted("package1");
- mockRecommendationServiceAvailable("package1", 924 /* packageUid */);
+ final ComponentName recoComponent = new ComponentName("package1", "class1");
+ setNetworkRecommendationPackageNames(recoComponent.getPackageName());
+ mockScoreNetworksGranted(recoComponent.getPackageName());
+ mockRecommendationServiceAvailable(recoComponent, 924 /* packageUid */);
NetworkScorerAppData appData =
mNetworkScorerAppManager.getNetworkRecommendationProviderData();
assertNotNull(appData);
- assertEquals("package1", appData.packageName);
+ assertEquals(recoComponent, appData.getRecommendationServiceComponent());
assertEquals(924, appData.packageUid);
- assertEquals(".RecommendationService", appData.recommendationServiceClassName);
}
public void testGetActiveScorer_providerAvailable() throws Exception {
- setNetworkRecommendationPackageNames("package1");
- mockScoreNetworksGranted("package1");
- mockRecommendationServiceAvailable("package1", 924 /* packageUid */);
+ final ComponentName recoComponent = new ComponentName("package1", "class1");
+ setNetworkRecommendationPackageNames(recoComponent.getPackageName());
+ mockScoreNetworksGranted(recoComponent.getPackageName());
+ mockRecommendationServiceAvailable(recoComponent, 924 /* packageUid */);
ContentResolver cr = mTargetContext.getContentResolver();
Settings.Global.putInt(cr, Settings.Global.NETWORK_RECOMMENDATIONS_ENABLED, 1);
final NetworkScorerAppData activeScorer = mNetworkScorerAppManager.getActiveScorer();
assertNotNull(activeScorer);
- assertEquals("package1", activeScorer.packageName);
+ assertEquals(recoComponent, activeScorer.getRecommendationServiceComponent());
assertEquals(924, activeScorer.packageUid);
- assertEquals(".RecommendationService", activeScorer.recommendationServiceClassName);
}
public void testGetActiveScorer_providerNotAvailable()
@@ -159,9 +164,10 @@
}
public void testGetActiveScorer_recommendationsDisabled() throws Exception {
- setNetworkRecommendationPackageNames("package1");
- mockScoreNetworksGranted("package1");
- mockRecommendationServiceAvailable("package1", 924 /* packageUid */);
+ final ComponentName recoComponent = new ComponentName("package1", "class1");
+ setNetworkRecommendationPackageNames(recoComponent.getPackageName());
+ mockScoreNetworksGranted(recoComponent.getPackageName());
+ mockRecommendationServiceAvailable(recoComponent, 924 /* packageUid */);
ContentResolver cr = mTargetContext.getContentResolver();
Settings.Global.putInt(cr, Settings.Global.NETWORK_RECOMMENDATIONS_ENABLED, 0);
@@ -187,11 +193,11 @@
.thenReturn(PackageManager.PERMISSION_DENIED);
}
- private void mockRecommendationServiceAvailable(final String packageName, int packageUid) {
+ private void mockRecommendationServiceAvailable(final ComponentName compName, int packageUid) {
final ResolveInfo serviceInfo = new ResolveInfo();
serviceInfo.serviceInfo = new ServiceInfo();
- serviceInfo.serviceInfo.name = ".RecommendationService";
- serviceInfo.serviceInfo.packageName = packageName;
+ serviceInfo.serviceInfo.name = compName.getClassName();
+ serviceInfo.serviceInfo.packageName = compName.getPackageName();
serviceInfo.serviceInfo.applicationInfo = new ApplicationInfo();
serviceInfo.serviceInfo.applicationInfo.uid = packageUid;
@@ -203,7 +209,7 @@
Intent intent = (Intent) object;
return NetworkScoreManager.ACTION_RECOMMEND_NETWORKS
.equals(intent.getAction())
- && packageName.equals(intent.getPackage());
+ && compName.getPackageName().equals(intent.getPackage());
}
}), Mockito.eq(flags))).thenReturn(serviceInfo);
}
diff --git a/core/tests/coretests/src/android/net/RecommendationRequestTest.java b/core/tests/coretests/src/android/net/RecommendationRequestTest.java
index bd25500..e2e6883 100644
--- a/core/tests/coretests/src/android/net/RecommendationRequestTest.java
+++ b/core/tests/coretests/src/android/net/RecommendationRequestTest.java
@@ -96,7 +96,7 @@
RecommendationRequest parceled = passThroughParcel(request);
- assertEquals(0, parceled.getLastSelectedNetworkId());
+ assertEquals(-1, parceled.getLastSelectedNetworkId());
assertEquals(0, parceled.getLastSelectedNetworkTimestamp());
}
diff --git a/core/tests/coretests/src/android/provider/SettingsTest.java b/core/tests/coretests/src/android/provider/SettingsTest.java
index d76980a..1ff2056 100644
--- a/core/tests/coretests/src/android/provider/SettingsTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsTest.java
@@ -392,7 +392,6 @@
Settings.Secure.BACKUP_PROVISIONED,
Settings.Secure.BACKUP_TRANSPORT,
Settings.Secure.BLUETOOTH_HCI_LOG,
- Settings.Secure.BRIGHTNESS_USE_TWILIGHT, // Candidate for backup?
Settings.Secure.CARRIER_APPS_HANDLED,
Settings.Secure.COMPLETED_CATEGORY_PREFIX,
Settings.Secure.CONNECTIVITY_RELEASE_PENDING_INTENT_DELAY_MS,
diff --git a/core/tests/coretests/src/android/transition/FadeTransitionTest.java b/core/tests/coretests/src/android/transition/FadeTransitionTest.java
index dc60423..7e7e815 100644
--- a/core/tests/coretests/src/android/transition/FadeTransitionTest.java
+++ b/core/tests/coretests/src/android/transition/FadeTransitionTest.java
@@ -21,7 +21,7 @@
import android.test.ActivityInstrumentationTestCase2;
import android.test.suitebuilder.annotation.SmallTest;
import android.transition.Transition.TransitionListener;
-import android.transition.Transition.TransitionListenerAdapter;
+import android.transition.TransitionListenerAdapter;
import android.view.View;
import android.view.ViewGroup;
diff --git a/core/tests/coretests/src/android/view/ViewAttachTest.java b/core/tests/coretests/src/android/view/ViewAttachTest.java
index a73f5a6..44fcd13 100644
--- a/core/tests/coretests/src/android/view/ViewAttachTest.java
+++ b/core/tests/coretests/src/android/view/ViewAttachTest.java
@@ -16,9 +16,17 @@
package android.view;
+import android.content.Context;
import android.content.pm.ActivityInfo;
+import android.graphics.PixelFormat;
import android.os.SystemClock;
import android.test.ActivityInstrumentationTestCase2;
+import android.test.UiThreadTest;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.WindowManager;
+
+import com.android.frameworks.coretests.R;
public class ViewAttachTest extends
ActivityInstrumentationTestCase2<ViewAttachTestActivity> {
@@ -51,4 +59,38 @@
SystemClock.sleep(250);
}
}
+
+ /**
+ * Make sure that on any attached view, if the view is full-screen and hosted
+ * on a round device, the round scrollbars will be displayed even if the activity
+ * window is offset.
+ *
+ * @throws Throwable
+ */
+ @UiThreadTest
+ public void testRoundScrollbars() throws Throwable {
+ final ViewAttachTestActivity activity = getActivity();
+ final View rootView = activity.getWindow().getDecorView();
+ final WindowManager.LayoutParams params =
+ new WindowManager.LayoutParams(
+ rootView.getWidth(),
+ rootView.getHeight(),
+ 50, /* xPosition */
+ 0, /* yPosition */
+ WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
+ WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
+ PixelFormat.TRANSLUCENT);
+
+ rootView.setLayoutParams(params);
+
+ View contentView = activity.findViewById(R.id.view_attach_view);
+ boolean shouldDrawRoundScrollbars = contentView.shouldDrawRoundScrollbar();
+
+ if (activity.getResources().getConfiguration().isScreenRound()) {
+ assertTrue(shouldDrawRoundScrollbars);
+ } else {
+ // Never draw round scrollbars on non-round devices.
+ assertFalse(shouldDrawRoundScrollbars);
+ }
+ }
}
diff --git a/core/tests/coretests/src/com/android/internal/logging/legacy/LockscreenGestureParserTest.java b/core/tests/coretests/src/com/android/internal/logging/legacy/LockscreenGestureParserTest.java
deleted file mode 100644
index c023b57..0000000
--- a/core/tests/coretests/src/com/android/internal/logging/legacy/LockscreenGestureParserTest.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.internal.logging.legacy;
-
-import static org.mockito.Matchers.anyObject;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-import android.metrics.LogMaker;
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-
-public class LockscreenGestureParserTest extends ParserTest {
-
- public LockscreenGestureParserTest() {
- mParser = new LockscreenGestureParser();
- }
-
- public void testSwipeUpUnlock() throws Throwable {
- validate(MetricsEvent.ACTION_LS_UNLOCK, 1, 359, 6382);
- }
-
- public void testSwipeToShade() throws Throwable {
- validate(MetricsEvent.ACTION_LS_SHADE, 2, 324, 0);
- }
-
- public void testTapLockHint() throws Throwable {
- validate(MetricsEvent.ACTION_LS_HINT, 3, 0, 0);
- }
-
- public void testCamera() throws Throwable {
- validate(MetricsEvent.ACTION_LS_CAMERA, 4, 223, 1756);
- }
-
- public void testDialer() throws Throwable {
- validate(MetricsEvent.ACTION_LS_DIALER, 5, 163, 861);
- }
-
- public void testTapToLock() throws Throwable {
- validate(MetricsEvent.ACTION_LS_LOCK, 6, 0, 0);
- }
-
- public void testTapOnNotification() throws Throwable {
- validate(MetricsEvent.ACTION_LS_NOTE, 7, 0, 0);
- }
-
- public void testLockscreenQuickSettings() throws Throwable {
- validate(MetricsEvent.ACTION_LS_QS, 8, 284, 3824);
- }
-
- public void testShadePullQuickSettings() throws Throwable {
- validate(MetricsEvent.ACTION_SHADE_QS_PULL, 9, 175, 3444);
- }
-
- public void testShadeTapQuickSettings() throws Throwable {
- validate(MetricsEvent.ACTION_SHADE_QS_TAP, 10, 0, 0);
- }
-
- private void validate(int view, int type, int len, int vel) {
- int t = 1000;
- Object[] objects = new Object[3];
- objects[0] = type;
- objects[1] = len;
- objects[2] = vel;
-
- mParser.parseEvent(mLogger, t, objects);
-
- verify(mLogger, times(1)).addEvent(mProtoCaptor.capture());
-
- LogMaker proto = mProtoCaptor.getValue();
- assertEquals(t, proto.getTimestamp());
- assertEquals(view, proto.getCategory());
- assertEquals(MetricsEvent.TYPE_ACTION, proto.getType());
- }
-
- public void testIgnoreUnexpectedData() throws Throwable {
- int t = 1000;
- Object[] objects = new Object[4];
- objects[0] = 1;
- objects[1] = 0;
- objects[2] = 0;
- objects[3] = "foo";
-
- mParser.parseEvent(mLogger, t, objects);
-
- verify(mLogger, times(1)).addEvent((LogMaker) anyObject());
- }
-}
diff --git a/core/tests/coretests/src/com/android/internal/logging/legacy/StatusBarStateParserTest.java b/core/tests/coretests/src/com/android/internal/logging/legacy/StatusBarStateParserTest.java
deleted file mode 100644
index def9628..0000000
--- a/core/tests/coretests/src/com/android/internal/logging/legacy/StatusBarStateParserTest.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.internal.logging.legacy;
-
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-
-import android.metrics.LogMaker;
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-
-public class StatusBarStateParserTest extends ParserTest {
-
- public StatusBarStateParserTest() {
- mParser = new StatusBarStateParser();
- }
-
- public void testLockScreen() throws Throwable {
- validate(MetricsEvent.LOCKSCREEN, MetricsEvent.TYPE_OPEN, 1, "1,1,0,0,1,0");
- }
-
- public void testBounce() throws Throwable {
- validate(MetricsEvent.BOUNCER, MetricsEvent.TYPE_OPEN, 1, "1,1,0,1,1,0");
- }
-
- public void testUnlock() throws Throwable {
- validate(MetricsEvent.LOCKSCREEN, MetricsEvent.TYPE_CLOSE, 1, "0,0,0,0,1,0");
- }
-
- public void testSecure() throws Throwable {
- validate(MetricsEvent.BOUNCER, MetricsEvent.TYPE_OPEN, 1, "2,1,0,1,1,0");
- }
-
- public void testInsecure() throws Throwable {
- validate(MetricsEvent.LOCKSCREEN, MetricsEvent.TYPE_OPEN, 0, "1,1,0,0,0,0");
- }
-
- public void testIgnoreUnexpectedData() throws Throwable {
- validate(MetricsEvent.LOCKSCREEN, MetricsEvent.TYPE_OPEN, 0, "1,1,0,0,0,0,5");
- }
-
- private void validate(int view, int type, int subType, String log) {
- String[] parts = log.split(",");
- int t = 1000;
- Object[] objects = new Object[parts.length];
- for (int i = 0; i < parts.length; i++) {
- objects[i] = Integer.valueOf(parts[i]);
- }
-
- mParser.parseEvent(mLogger, t, objects);
-
- verify(mLogger, times(1)).addEvent(mProtoCaptor.capture());
-
- LogMaker proto = mProtoCaptor.getValue();
- assertEquals(t, proto.getTimestamp());
- assertEquals(view, proto.getCategory());
- assertEquals(type, proto.getType());
- assertEquals(subType, proto.getSubtype());
- }
-}
diff --git a/data/etc/platform.xml b/data/etc/platform.xml
index e46f166..9cdc660 100644
--- a/data/etc/platform.xml
+++ b/data/etc/platform.xml
@@ -155,6 +155,7 @@
<assign-permission name="android.permission.WAKE_LOCK" uid="cameraserver" />
<assign-permission name="android.permission.UPDATE_DEVICE_STATS" uid="cameraserver" />
<assign-permission name="android.permission.UPDATE_APP_OPS_STATS" uid="cameraserver" />
+ <assign-permission name="android.permission.GET_PROCESS_STATE_AND_OOM_SCORE" uid="cameraserver" />
<assign-permission name="android.permission.ACCESS_SURFACE_FLINGER" uid="graphics" />
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index c5961ab..039ab1f 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -132,6 +132,7 @@
<permission name="android.permission.ACCESS_IMS_CALL_SERVICE"/>
<permission name="android.permission.BIND_CARRIER_MESSAGING_SERVICE"/>
<permission name="android.permission.BIND_CARRIER_SERVICES"/>
+ <permission name="android.permission.BIND_IMS_SERVICE"/>
<permission name="android.permission.BIND_VISUAL_VOICEMAIL_SERVICE"/>
<permission name="android.permission.CALL_PRIVILEGED"/>
<permission name="android.permission.CHANGE_COMPONENT_ENABLED_STATE"/>
@@ -339,4 +340,4 @@
<permission name="android.permission.CONTROL_VPN"/>
</privapp-permissions>
-</permissions>
\ No newline at end of file
+</permissions>
diff --git a/graphics/java/android/graphics/Typeface.java b/graphics/java/android/graphics/Typeface.java
index 5531871..750ef3f 100644
--- a/graphics/java/android/graphics/Typeface.java
+++ b/graphics/java/android/graphics/Typeface.java
@@ -198,9 +198,10 @@
}
/**
+ * Used by resources for cached loading if the font is available.
* @hide
*/
- public static Typeface createFromCache(AssetManager mgr, String path) {
+ public static Typeface findFromCache(AssetManager mgr, String path) {
synchronized (sDynamicTypefaceCache) {
final String key = createAssetUid(mgr, path);
Typeface typeface = sDynamicTypefaceCache.get(key);
@@ -221,6 +222,15 @@
* @param callback A callback that will be triggered when results are obtained. May not be null.
*/
public static void create(@NonNull FontRequest request, @NonNull FontRequestCallback callback) {
+ // Check the cache first
+ // TODO: would the developer want to avoid a cache hit and always ask for the freshest
+ // result?
+ Typeface cachedTypeface = findFromCache(
+ request.getProviderAuthority(), request.getQuery());
+ if (cachedTypeface != null) {
+ mHandler.post(() -> callback.onTypefaceRetrieved(cachedTypeface));
+ return;
+ }
synchronized (sLock) {
if (sFontsContract == null) {
sFontsContract = new FontsContract();
@@ -229,20 +239,34 @@
final ResultReceiver receiver = new ResultReceiver(null) {
@Override
public void onReceiveResult(int resultCode, Bundle resultData) {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- receiveResult(request, callback, resultCode, resultData);
- }
- });
+ mHandler.post(() -> receiveResult(request, callback, resultCode, resultData));
}
};
sFontsContract.getFont(request, receiver);
}
}
+ private static Typeface findFromCache(String providerAuthority, String query) {
+ synchronized (sDynamicTypefaceCache) {
+ final String key = createProviderUid(providerAuthority, query);
+ Typeface typeface = sDynamicTypefaceCache.get(key);
+ if (typeface != null) {
+ return typeface;
+ }
+ }
+ return null;
+ }
+
private static void receiveResult(FontRequest request, FontRequestCallback callback,
int resultCode, Bundle resultData) {
+ Typeface cachedTypeface = findFromCache(
+ request.getProviderAuthority(), request.getQuery());
+ if (cachedTypeface != null) {
+ // We already know the result.
+ // Probably the requester requests the same font again in a short interval.
+ callback.onTypefaceRetrieved(cachedTypeface);
+ return;
+ }
if (resultCode == FontsContract.RESULT_CODE_PROVIDER_NOT_FOUND) {
callback.onTypefaceRequestFailed(
FontRequestCallback.FAIL_REASON_PROVIDER_NOT_FOUND);
@@ -296,8 +320,12 @@
}
}
fontFamily.freeze();
- callback.onTypefaceRetrieved(Typeface.createFromFamiliesWithDefault(
- new FontFamily[] {fontFamily}));
+ Typeface typeface = Typeface.createFromFamiliesWithDefault(new FontFamily[] { fontFamily });
+ synchronized (sDynamicTypefaceCache) {
+ String key = createProviderUid(request.getProviderAuthority(), request.getQuery());
+ sDynamicTypefaceCache.put(key, typeface);
+ }
+ callback.onTypefaceRetrieved(typeface);
}
/**
@@ -464,6 +492,7 @@
private static String createAssetUid(final AssetManager mgr, String path) {
final SparseArray<String> pkgs = mgr.getAssignedPackageIdentifiers();
final StringBuilder builder = new StringBuilder();
+ builder.append("asset:");
final int size = pkgs.size();
for (int i = 0; i < size; i++) {
builder.append(pkgs.valueAt(i));
@@ -474,6 +503,18 @@
}
/**
+ * Creates a unique id for a given font provider and query.
+ */
+ private static String createProviderUid(String authority, String query) {
+ final StringBuilder builder = new StringBuilder();
+ builder.append("provider:");
+ builder.append(authority);
+ builder.append("-");
+ builder.append(query);
+ return builder.toString();
+ }
+
+ /**
* Create a new typeface from the specified font file.
*
* @param path The path to the font data.
diff --git a/graphics/java/android/graphics/drawable/MaskableIconDrawable.java b/graphics/java/android/graphics/drawable/MaskableIconDrawable.java
index 3467b1a..043f092 100644
--- a/graphics/java/android/graphics/drawable/MaskableIconDrawable.java
+++ b/graphics/java/android/graphics/drawable/MaskableIconDrawable.java
@@ -726,6 +726,9 @@
int width = -1;
for (int i = 0; i < mLayerState.N_CHILDREN; i++) {
final ChildDrawable r = mLayerState.mChildren[i];
+ if (r.mDrawable == null) {
+ continue;
+ }
final int w = r.mDrawable.getIntrinsicWidth();
if (w > width) {
width = w;
@@ -743,6 +746,9 @@
int height = -1;
for (int i = 0; i < mLayerState.N_CHILDREN; i++) {
final ChildDrawable r = mLayerState.mChildren[i];
+ if (r.mDrawable == null) {
+ continue;
+ }
final int h = r.mDrawable.getIntrinsicHeight();
if (h > height) {
height = h;
diff --git a/keystore/java/android/security/GateKeeper.java b/keystore/java/android/security/GateKeeper.java
index 7a2cbd0..03df5de 100644
--- a/keystore/java/android/security/GateKeeper.java
+++ b/keystore/java/android/security/GateKeeper.java
@@ -29,6 +29,8 @@
*/
public abstract class GateKeeper {
+ public static final long INVALID_SECURE_USER_ID = 0;
+
private GateKeeper() {}
public static IGateKeeperService getService() {
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java
index b234d0f..9701b0e 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java
@@ -17,6 +17,7 @@
package android.security.keystore;
import android.security.Credentials;
+import android.security.GateKeeper;
import android.security.KeyStore;
import android.security.keymaster.KeyCharacteristics;
import android.security.keymaster.KeymasterArguments;
@@ -235,7 +236,8 @@
spec.isUserAuthenticationRequired(),
spec.getUserAuthenticationValidityDurationSeconds(),
spec.isUserAuthenticationValidWhileOnBody(),
- spec.isInvalidatedByBiometricEnrollment());
+ spec.isInvalidatedByBiometricEnrollment(),
+ GateKeeper.INVALID_SECURE_USER_ID /* boundToSpecificSecureUserId */);
} catch (IllegalStateException | IllegalArgumentException e) {
throw new InvalidAlgorithmParameterException(e);
}
@@ -275,7 +277,8 @@
spec.isUserAuthenticationRequired(),
spec.getUserAuthenticationValidityDurationSeconds(),
spec.isUserAuthenticationValidWhileOnBody(),
- spec.isInvalidatedByBiometricEnrollment());
+ spec.isInvalidatedByBiometricEnrollment(),
+ GateKeeper.INVALID_SECURE_USER_ID /* boundToSpecificSecureUserId */);
KeymasterUtils.addMinMacLengthAuthorizationIfNecessary(
args,
mKeymasterAlgorithm,
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java
index 1818f52..dba3949 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java
@@ -18,6 +18,7 @@
import android.annotation.Nullable;
import android.security.Credentials;
+import android.security.GateKeeper;
import android.security.KeyPairGeneratorSpec;
import android.security.KeyStore;
import android.security.keymaster.KeyCharacteristics;
@@ -346,7 +347,8 @@
mSpec.isUserAuthenticationRequired(),
mSpec.getUserAuthenticationValidityDurationSeconds(),
mSpec.isUserAuthenticationValidWhileOnBody(),
- mSpec.isInvalidatedByBiometricEnrollment());
+ mSpec.isInvalidatedByBiometricEnrollment(),
+ GateKeeper.INVALID_SECURE_USER_ID /* boundToSpecificSecureUserId */);
} catch (IllegalArgumentException | IllegalStateException e) {
throw new InvalidAlgorithmParameterException(e);
}
@@ -533,7 +535,8 @@
mSpec.isUserAuthenticationRequired(),
mSpec.getUserAuthenticationValidityDurationSeconds(),
mSpec.isUserAuthenticationValidWhileOnBody(),
- mSpec.isInvalidatedByBiometricEnrollment());
+ mSpec.isInvalidatedByBiometricEnrollment(),
+ GateKeeper.INVALID_SECURE_USER_ID /* boundToSpecificSecureUserId */);
args.addDateIfNotNull(KeymasterDefs.KM_TAG_ACTIVE_DATETIME, mSpec.getKeyValidityStart());
args.addDateIfNotNull(KeymasterDefs.KM_TAG_ORIGINATION_EXPIRE_DATETIME,
mSpec.getKeyValidityForOriginationEnd());
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java
index fcbb553..64b10ab 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java
@@ -500,7 +500,8 @@
spec.isUserAuthenticationRequired(),
spec.getUserAuthenticationValidityDurationSeconds(),
spec.isUserAuthenticationValidWhileOnBody(),
- spec.isInvalidatedByBiometricEnrollment());
+ spec.isInvalidatedByBiometricEnrollment(),
+ spec.getBoundToSpecificSecureUserId());
importArgs.addDateIfNotNull(KeymasterDefs.KM_TAG_ACTIVE_DATETIME,
spec.getKeyValidityStart());
importArgs.addDateIfNotNull(KeymasterDefs.KM_TAG_ORIGINATION_EXPIRE_DATETIME,
@@ -696,7 +697,8 @@
params.isUserAuthenticationRequired(),
params.getUserAuthenticationValidityDurationSeconds(),
params.isUserAuthenticationValidWhileOnBody(),
- params.isInvalidatedByBiometricEnrollment());
+ params.isInvalidatedByBiometricEnrollment(),
+ params.getBoundToSpecificSecureUserId());
KeymasterUtils.addMinMacLengthAuthorizationIfNecessary(
args,
keymasterAlgorithm,
diff --git a/keystore/java/android/security/keystore/KeyProtection.java b/keystore/java/android/security/keystore/KeyProtection.java
index e70d33a..2592a97 100644
--- a/keystore/java/android/security/keystore/KeyProtection.java
+++ b/keystore/java/android/security/keystore/KeyProtection.java
@@ -21,6 +21,7 @@
import android.annotation.Nullable;
import android.app.KeyguardManager;
import android.hardware.fingerprint.FingerprintManager;
+import android.security.GateKeeper;
import java.security.Key;
import java.security.Signature;
@@ -225,6 +226,7 @@
private final int mUserAuthenticationValidityDurationSeconds;
private final boolean mUserAuthenticationValidWhileOnBody;
private final boolean mInvalidatedByBiometricEnrollment;
+ private final long mBoundToSecureUserId;
private KeyProtection(
Date keyValidityStart,
@@ -239,7 +241,8 @@
boolean userAuthenticationRequired,
int userAuthenticationValidityDurationSeconds,
boolean userAuthenticationValidWhileOnBody,
- boolean invalidatedByBiometricEnrollment) {
+ boolean invalidatedByBiometricEnrollment,
+ long boundToSecureUserId) {
mKeyValidityStart = Utils.cloneIfNotNull(keyValidityStart);
mKeyValidityForOriginationEnd = Utils.cloneIfNotNull(keyValidityForOriginationEnd);
mKeyValidityForConsumptionEnd = Utils.cloneIfNotNull(keyValidityForConsumptionEnd);
@@ -255,6 +258,7 @@
mUserAuthenticationValidityDurationSeconds = userAuthenticationValidityDurationSeconds;
mUserAuthenticationValidWhileOnBody = userAuthenticationValidWhileOnBody;
mInvalidatedByBiometricEnrollment = invalidatedByBiometricEnrollment;
+ mBoundToSecureUserId = boundToSecureUserId;
}
/**
@@ -436,6 +440,24 @@
}
/**
+ * Return the secure user id that this key should be bound to.
+ *
+ * Normally an authentication-bound key is tied to the secure user id of the current user
+ * (either the root SID from GateKeeper for auth-bound keys with a timeout, or the authenticator
+ * id of the current fingerprint set for keys requiring explicit fingerprint authorization).
+ * If this parameter is set (this method returning non-zero value), the key should be tied to
+ * the specified secure user id, overriding the logic above.
+ *
+ * This is only applicable when {@link #isUserAuthenticationRequired} is {@code true}
+ *
+ * @see KeymasterUtils#addUserAuthArgs
+ * @hide
+ */
+ public long getBoundToSpecificSecureUserId() {
+ return mBoundToSecureUserId;
+ }
+
+ /**
* Builder of {@link KeyProtection} instances.
*/
public final static class Builder {
@@ -454,6 +476,7 @@
private boolean mUserAuthenticationValidWhileOnBody;
private boolean mInvalidatedByBiometricEnrollment = true;
+ private long mBoundToSecureUserId = GateKeeper.INVALID_SECURE_USER_ID;
/**
* Creates a new instance of the {@code Builder}.
*
@@ -774,6 +797,26 @@
}
/**
+ * Set the secure user id that this key should be bound to.
+ *
+ * Normally an authentication-bound key is tied to the secure user id of the current user
+ * (either the root SID from GateKeeper for auth-bound keys with a timeout, or the
+ * authenticator id of the current fingerprint set for keys requiring explicit fingerprint
+ * authorization). If this parameter is set (this method returning non-zero value), the key
+ * should be tied to the specified secure user id, overriding the logic above.
+ *
+ * This is only applicable when {@link #setUserAuthenticationRequired} is set to
+ * {@code true}
+ *
+ * @see KeyProtection#getBoundToSpecificSecureUserId()
+ * @hide
+ */
+ public Builder setBoundToSpecificSecureUserId(long secureUserId) {
+ mBoundToSecureUserId = secureUserId;
+ return this;
+ }
+
+ /**
* Builds an instance of {@link KeyProtection}.
*
* @throws IllegalArgumentException if a required field is missing
@@ -793,7 +836,8 @@
mUserAuthenticationRequired,
mUserAuthenticationValidityDurationSeconds,
mUserAuthenticationValidWhileOnBody,
- mInvalidatedByBiometricEnrollment);
+ mInvalidatedByBiometricEnrollment,
+ mBoundToSecureUserId);
}
}
}
diff --git a/keystore/java/android/security/keystore/KeymasterUtils.java b/keystore/java/android/security/keystore/KeymasterUtils.java
index f5272aa..34c8d1f 100644
--- a/keystore/java/android/security/keystore/KeymasterUtils.java
+++ b/keystore/java/android/security/keystore/KeymasterUtils.java
@@ -89,7 +89,10 @@
* @param userAuthenticationValidityDurationSeconds duration of time (seconds) for which user
* authentication is valid as authorization for using the key or {@code -1} if every
* use of the key needs authorization.
- *
+ * @param boundToSpecificSecureUserId if non-zero, specify which SID the key will be bound to,
+ * overriding the default logic in this method where the key is bound to either the root
+ * SID of the current user, or the fingerprint SID if explicit fingerprint authorization
+ * is requested.
* @throws IllegalStateException if user authentication is required but the system is in a wrong
* state (e.g., secure lock screen not set up) for generating or importing keys that
* require user authentication.
@@ -98,7 +101,8 @@
boolean userAuthenticationRequired,
int userAuthenticationValidityDurationSeconds,
boolean userAuthenticationValidWhileOnBody,
- boolean invalidatedByBiometricEnrollment) {
+ boolean invalidatedByBiometricEnrollment,
+ long boundToSpecificSecureUserId) {
if (!userAuthenticationRequired) {
args.addBoolean(KeymasterDefs.KM_TAG_NO_AUTH_REQUIRED);
return;
@@ -120,7 +124,9 @@
}
long sid;
- if (invalidatedByBiometricEnrollment) {
+ if (boundToSpecificSecureUserId != GateKeeper.INVALID_SECURE_USER_ID) {
+ sid = boundToSpecificSecureUserId;
+ } else if (invalidatedByBiometricEnrollment) {
// The fingerprint-only SID will change on fingerprint enrollment or removal of all,
// enrolled fingerprints, invalidating the key.
sid = fingerprintOnlySid;
@@ -138,11 +144,16 @@
+ "supported for keys requiring fingerprint authentication");
}
} else {
- // The key is authorized for use for the specified amount of time after the user has
- // authenticated. Whatever unlocks the secure lock screen should authorize this key.
- long rootSid = getRootSid();
+ long sid;
+ if (boundToSpecificSecureUserId != GateKeeper.INVALID_SECURE_USER_ID) {
+ sid = boundToSpecificSecureUserId;
+ } else {
+ // The key is authorized for use for the specified amount of time after the user has
+ // authenticated. Whatever unlocks the secure lock screen should authorize this key.
+ sid = getRootSid();
+ }
args.addUnsignedLong(KeymasterDefs.KM_TAG_USER_SECURE_ID,
- KeymasterArguments.toUint64(rootSid));
+ KeymasterArguments.toUint64(sid));
args.addEnum(KeymasterDefs.KM_TAG_USER_AUTH_TYPE,
KeymasterDefs.HW_AUTH_PASSWORD | KeymasterDefs.HW_AUTH_FINGERPRINT);
args.addUnsignedInt(KeymasterDefs.KM_TAG_AUTH_TIMEOUT,
diff --git a/libs/androidfw/ApkAssets.cpp b/libs/androidfw/ApkAssets.cpp
index 9a08f63..fe68ec01 100644
--- a/libs/androidfw/ApkAssets.cpp
+++ b/libs/androidfw/ApkAssets.cpp
@@ -27,16 +27,17 @@
namespace android {
-std::unique_ptr<ApkAssets> ApkAssets::Load(const std::string& path) {
- return ApkAssets::LoadImpl(path, false /*load_as_shared_library*/);
+std::unique_ptr<const ApkAssets> ApkAssets::Load(const std::string& path, bool system) {
+ return ApkAssets::LoadImpl(path, system, false /*load_as_shared_library*/);
}
-std::unique_ptr<ApkAssets> ApkAssets::LoadAsSharedLibrary(const std::string& path) {
- return ApkAssets::LoadImpl(path, true /*load_as_shared_library*/);
+std::unique_ptr<const ApkAssets> ApkAssets::LoadAsSharedLibrary(const std::string& path,
+ bool system) {
+ return ApkAssets::LoadImpl(path, system, true /*load_as_shared_library*/);
}
-std::unique_ptr<ApkAssets> ApkAssets::LoadImpl(const std::string& path,
- bool load_as_shared_library) {
+std::unique_ptr<const ApkAssets> ApkAssets::LoadImpl(const std::string& path, bool system,
+ bool load_as_shared_library) {
ATRACE_CALL();
::ZipArchiveHandle unmanaged_handle;
int32_t result = ::OpenArchive(path.c_str(), &unmanaged_handle);
@@ -70,11 +71,13 @@
loaded_apk->path_ = path;
loaded_apk->loaded_arsc_ =
LoadedArsc::Load(loaded_apk->resources_asset_->getBuffer(true /*wordAligned*/),
- loaded_apk->resources_asset_->getLength(), load_as_shared_library);
+ loaded_apk->resources_asset_->getLength(), system, load_as_shared_library);
if (loaded_apk->loaded_arsc_ == nullptr) {
return {};
}
- return loaded_apk;
+
+ // Need to force a move for mingw32.
+ return std::move(loaded_apk);
}
std::unique_ptr<Asset> ApkAssets::Open(const std::string& path, Asset::AccessMode /*mode*/) const {
diff --git a/libs/androidfw/AssetManager2.cpp b/libs/androidfw/AssetManager2.cpp
index d2eff65..542a125 100644
--- a/libs/androidfw/AssetManager2.cpp
+++ b/libs/androidfw/AssetManager2.cpp
@@ -18,6 +18,8 @@
#include "androidfw/AssetManager2.h"
+#include <set>
+
#include "android-base/logging.h"
#include "android-base/stringprintf.h"
#include "utils/ByteOrder.h"
@@ -143,6 +145,36 @@
}
}
+std::set<ResTable_config> AssetManager2::GetResourceConfigurations(bool exclude_system,
+ bool exclude_mipmap) {
+ ATRACE_CALL();
+ std::set<ResTable_config> configurations;
+ for (const PackageGroup& package_group : package_groups_) {
+ for (const LoadedPackage* package : package_group.packages_) {
+ if (exclude_system && package->IsSystem()) {
+ continue;
+ }
+ package->CollectConfigurations(exclude_mipmap, &configurations);
+ }
+ }
+ return configurations;
+}
+
+std::set<std::string> AssetManager2::GetResourceLocales(bool exclude_system,
+ bool merge_equivalent_languages) {
+ ATRACE_CALL();
+ std::set<std::string> locales;
+ for (const PackageGroup& package_group : package_groups_) {
+ for (const LoadedPackage* package : package_group.packages_) {
+ if (exclude_system && package->IsSystem()) {
+ continue;
+ }
+ package->CollectLocales(merge_equivalent_languages, &locales);
+ }
+ }
+ return locales;
+}
+
std::unique_ptr<Asset> AssetManager2::Open(const std::string& filename, Asset::AccessMode mode) {
const std::string new_path = "assets/" + filename;
return OpenNonAsset(new_path, mode);
@@ -325,8 +357,15 @@
if (dtohl(entry.entry->flags) & ResTable_entry::FLAG_COMPLEX) {
if (!may_be_bag) {
LOG(ERROR) << base::StringPrintf("Resource %08x is a complex map type.", resid);
+ return kInvalidCookie;
}
- return kInvalidCookie;
+
+ // Create a reference since we can't represent this complex type as a Res_value.
+ out_value->dataType = Res_value::TYPE_REFERENCE;
+ out_value->data = resid;
+ *out_selected_config = config;
+ *out_flags = flags;
+ return cookie;
}
const Res_value* device_value = reinterpret_cast<const Res_value*>(
@@ -341,6 +380,37 @@
return cookie;
}
+ApkAssetsCookie AssetManager2::ResolveReference(ApkAssetsCookie cookie, Res_value* in_out_value,
+ ResTable_config* in_out_selected_config,
+ uint32_t* in_out_flags,
+ ResTable_ref* out_last_reference) {
+ ATRACE_CALL();
+ constexpr const int kMaxIterations = 20;
+
+ out_last_reference->ident = 0u;
+ for (size_t iteration = 0u; in_out_value->dataType == Res_value::TYPE_REFERENCE &&
+ in_out_value->data != 0u && iteration < kMaxIterations;
+ iteration++) {
+ if (out_last_reference != nullptr) {
+ out_last_reference->ident = in_out_value->data;
+ }
+ uint32_t new_flags = 0u;
+ cookie = GetResource(in_out_value->data, true /*may_be_bag*/, 0u /*density_override*/,
+ in_out_value, in_out_selected_config, &new_flags);
+ if (cookie == kInvalidCookie) {
+ return kInvalidCookie;
+ }
+ if (in_out_flags != nullptr) {
+ *in_out_flags |= new_flags;
+ }
+ if (out_last_reference->ident == in_out_value->data) {
+ // This reference can't be resolved, so exit now and let the caller deal with it.
+ return cookie;
+ }
+ }
+ return cookie;
+}
+
const ResolvedBag* AssetManager2::GetBag(uint32_t resid) {
ATRACE_CALL();
@@ -501,6 +571,15 @@
return result;
}
+uint32_t AssetManager2::GetResourceId(const std::string& resource_name,
+ const std::string& fallback_type,
+ const std::string& fallback_package) {
+ (void)resource_name;
+ (void)fallback_type;
+ (void)fallback_package;
+ return 0u;
+}
+
void AssetManager2::InvalidateCaches(uint32_t diff) {
if (diff == 0xffffffffu) {
// Everything must go.
diff --git a/libs/androidfw/LoadedArsc.cpp b/libs/androidfw/LoadedArsc.cpp
index c7d0fa5..cb589ec 100644
--- a/libs/androidfw/LoadedArsc.cpp
+++ b/libs/androidfw/LoadedArsc.cpp
@@ -321,6 +321,57 @@
return true;
}
+void LoadedPackage::CollectConfigurations(bool exclude_mipmap,
+ std::set<ResTable_config>* out_configs) const {
+ const static std::u16string kMipMap = u"mipmap";
+ const size_t type_count = type_specs_.size();
+ for (size_t i = 0; i < type_count; i++) {
+ const util::unique_cptr<TypeSpec>& type_spec = type_specs_[i];
+ if (type_spec != nullptr) {
+ if (exclude_mipmap) {
+ const int type_idx = type_spec->type_spec->id - 1;
+ size_t type_name_len;
+ const char16_t* type_name16 = type_string_pool_.stringAt(type_idx, &type_name_len);
+ if (type_name16 != nullptr) {
+ if (kMipMap.compare(0, std::u16string::npos, type_name16, type_name_len) == 0) {
+ // This is a mipmap type, skip collection.
+ continue;
+ }
+ }
+ const char* type_name = type_string_pool_.string8At(type_idx, &type_name_len);
+ if (type_name != nullptr) {
+ if (strncmp(type_name, "mipmap", type_name_len) == 0) {
+ // This is a mipmap type, skip collection.
+ continue;
+ }
+ }
+ }
+
+ for (size_t j = 0; j < type_spec->type_count; j++) {
+ out_configs->insert(type_spec->types[j].configuration);
+ }
+ }
+ }
+}
+
+void LoadedPackage::CollectLocales(bool canonicalize, std::set<std::string>* out_locales) const {
+ char temp_locale[RESTABLE_MAX_LOCALE_LEN];
+ const size_t type_count = type_specs_.size();
+ for (size_t i = 0; i < type_count; i++) {
+ const util::unique_cptr<TypeSpec>& type_spec = type_specs_[i];
+ if (type_spec != nullptr) {
+ for (size_t j = 0; j < type_spec->type_count; j++) {
+ const ResTable_config& configuration = type_spec->types[j].configuration;
+ if (configuration.locale != 0) {
+ configuration.getBcp47Locale(temp_locale, canonicalize);
+ std::string locale(temp_locale);
+ out_locales->insert(std::move(locale));
+ }
+ }
+ }
+ }
+}
+
std::unique_ptr<LoadedPackage> LoadedPackage::Load(const Chunk& chunk) {
ATRACE_CALL();
std::unique_ptr<LoadedPackage> loaded_package{new LoadedPackage()};
@@ -574,6 +625,7 @@
if (loaded_package->package_id_ == kAppPackageId) {
loaded_package->dynamic_ = load_as_shared_library;
}
+ loaded_package->system_ = system_;
packages_.push_back(std::move(loaded_package));
} break;
@@ -590,12 +642,13 @@
return true;
}
-std::unique_ptr<LoadedArsc> LoadedArsc::Load(const void* data, size_t len,
- bool load_as_shared_library) {
+std::unique_ptr<const LoadedArsc> LoadedArsc::Load(const void* data, size_t len, bool system,
+ bool load_as_shared_library) {
ATRACE_CALL();
// Not using make_unique because the constructor is private.
std::unique_ptr<LoadedArsc> loaded_arsc(new LoadedArsc());
+ loaded_arsc->system_ = system;
ChunkIterator iter(data, len);
while (iter.HasNext()) {
@@ -617,7 +670,9 @@
LOG(ERROR) << iter.GetLastError();
return {};
}
- return loaded_arsc;
+
+ // Need to force a move for mingw32.
+ return std::move(loaded_arsc);
}
} // namespace android
diff --git a/libs/androidfw/include/androidfw/ApkAssets.h b/libs/androidfw/include/androidfw/ApkAssets.h
index 9d4fd29..6d1578c 100644
--- a/libs/androidfw/include/androidfw/ApkAssets.h
+++ b/libs/androidfw/include/androidfw/ApkAssets.h
@@ -31,8 +31,9 @@
// Holds an APK.
class ApkAssets {
public:
- static std::unique_ptr<ApkAssets> Load(const std::string& path);
- static std::unique_ptr<ApkAssets> LoadAsSharedLibrary(const std::string& path);
+ static std::unique_ptr<const ApkAssets> Load(const std::string& path, bool system = false);
+ static std::unique_ptr<const ApkAssets> LoadAsSharedLibrary(const std::string& path,
+ bool system = false);
std::unique_ptr<Asset> Open(const std::string& path,
Asset::AccessMode mode = Asset::AccessMode::ACCESS_RANDOM) const;
@@ -44,7 +45,8 @@
private:
DISALLOW_COPY_AND_ASSIGN(ApkAssets);
- static std::unique_ptr<ApkAssets> LoadImpl(const std::string& path, bool load_as_shared_library);
+ static std::unique_ptr<const ApkAssets> LoadImpl(const std::string& path, bool system,
+ bool load_as_shared_library);
ApkAssets() = default;
@@ -57,7 +59,7 @@
ZipArchivePtr zip_handle_;
std::string path_;
std::unique_ptr<Asset> resources_asset_;
- std::unique_ptr<LoadedArsc> loaded_arsc_;
+ std::unique_ptr<const LoadedArsc> loaded_arsc_;
};
} // namespace android
diff --git a/libs/androidfw/include/androidfw/AssetManager2.h b/libs/androidfw/include/androidfw/AssetManager2.h
index 8655339..81cdc46 100644
--- a/libs/androidfw/include/androidfw/AssetManager2.h
+++ b/libs/androidfw/include/androidfw/AssetManager2.h
@@ -21,6 +21,7 @@
#include <array>
#include <limits>
+#include <set>
#include <unordered_map>
#include "androidfw/ApkAssets.h"
@@ -112,6 +113,24 @@
inline const ResTable_config& GetConfiguration() const { return configuration_; }
+ // Returns all configurations for which there are resources defined. This includes resource
+ // configurations in all the ApkAssets set for this AssetManager.
+ // If `exclude_system` is set to true, resource configurations from system APKs
+ // ('android' package, other libraries) will be excluded from the list.
+ // If `exclude_mipmap` is set to true, resource configurations defined for resource type 'mipmap'
+ // will be excluded from the list.
+ std::set<ResTable_config> GetResourceConfigurations(bool exclude_system = false,
+ bool exclude_mipmap = false);
+
+ // Returns all the locales for which there are resources defined. This includes resource
+ // locales in all the ApkAssets set for this AssetManager.
+ // If `exclude_system` is set to true, resource locales from system APKs
+ // ('android' package, other libraries) will be excluded from the list.
+ // If `merge_equivalent_languages` is set to true, resource locales will be canonicalized
+ // and de-duped in the resulting list.
+ std::set<std::string> GetResourceLocales(bool exclude_system = false,
+ bool merge_equivalent_languages = false);
+
// Searches the set of APKs loaded by this AssetManager and opens the first one found located
// in the assets/ directory.
// `mode` controls how the file is opened.
@@ -149,6 +168,14 @@
// Returns false if the resource was not found.
bool GetResourceFlags(uint32_t resid, uint32_t* out_flags);
+ // Finds the resource ID assigned to `resource_name`.
+ // `resource_name` must be of the form '[package:][type/]entry'.
+ // If no package is specified in `resource_name`, then `fallback_package` is used as the package.
+ // If no type is specified in `resource_name`, then `fallback_type` is used as the type.
+ // Returns 0x0 if no resource by that name was found.
+ uint32_t GetResourceId(const std::string& resource_name, const std::string& fallback_type = {},
+ const std::string& fallback_package = {});
+
// Retrieves the best matching resource with ID `resid`. The resource value is filled into
// `out_value` and the configuration for the selected value is populated in `out_selected_config`.
// `out_flags` holds the same flags as retrieved with GetResourceFlags().
@@ -162,6 +189,22 @@
Res_value* out_value, ResTable_config* out_selected_config,
uint32_t* out_flags);
+ // Resolves the resource reference in `in_out_value` if the data type is
+ // Res_value::TYPE_REFERENCE.
+ // `cookie` is the ApkAssetsCookie of the reference in `in_out_value`.
+ // `in_out_value` is the reference to resolve. The result is placed back into this object.
+ // `in_out_flags` is the type spec flags returned from calls to GetResource() or
+ // GetResourceFlags(). Configuration flags of the values pointed to by the reference
+ // are OR'd together with `in_out_flags`.
+ // `in_out_config` is populated with the configuration for which the resolved value was defined.
+ // `out_last_reference` is populated with the last reference ID before resolving to an actual
+ // value.
+ // Returns the cookie of the APK the resolved resource was defined in, or kInvalidCookie if
+ // it was not found.
+ ApkAssetsCookie ResolveReference(ApkAssetsCookie cookie, Res_value* in_out_value,
+ ResTable_config* in_out_selected_config, uint32_t* in_out_flags,
+ ResTable_ref* out_last_reference);
+
// Retrieves the best matching bag/map resource with ID `resid`.
// This method will resolve all parent references for this bag and merge keys with the child.
// To iterate over the keys, use the following idiom:
diff --git a/libs/androidfw/include/androidfw/LoadedArsc.h b/libs/androidfw/include/androidfw/LoadedArsc.h
index e8cb164..91a7cb7 100644
--- a/libs/androidfw/include/androidfw/LoadedArsc.h
+++ b/libs/androidfw/include/androidfw/LoadedArsc.h
@@ -18,6 +18,7 @@
#define LOADEDARSC_H_
#include <memory>
+#include <set>
#include <vector>
#include "android-base/macros.h"
@@ -68,20 +69,38 @@
LoadedArscEntry* out_entry, ResTable_config* out_selected_config,
uint32_t* out_flags) const;
+ // Returns the string pool where type names are stored.
inline const ResStringPool* GetTypeStringPool() const { return &type_string_pool_; }
+ // Returns the string pool where the names of resource entries are stored.
inline const ResStringPool* GetKeyStringPool() const { return &key_string_pool_; }
inline const std::string& GetPackageName() const { return package_name_; }
inline int GetPackageId() const { return package_id_; }
+ // Returns true if this package is dynamic (shared library) and needs to have an ID assigned.
inline bool IsDynamic() const { return dynamic_; }
+ // Returns true if this package originates from a system provided resource.
+ inline bool IsSystem() const { return system_; }
+
+ // Returns the map of package name to package ID used in this LoadedPackage. At runtime, a
+ // package could have been assigned a different package ID than what this LoadedPackage was
+ // compiled with. AssetManager rewrites the package IDs so that they are compatible at runtime.
inline const std::vector<DynamicPackageEntry>& GetDynamicPackageMap() const {
return dynamic_package_map_;
}
+ // Populates a set of ResTable_config structs, possibly excluding configurations defined for
+ // the mipmap type.
+ void CollectConfigurations(bool exclude_mipmap, std::set<ResTable_config>* out_configs) const;
+
+ // Populates a set of strings representing locales.
+ // If `canonicalize` is set to true, each locale is transformed into its canonical format
+ // before being inserted into the set. This may cause some equivalent locales to de-dupe.
+ void CollectLocales(bool canonicalize, std::set<std::string>* out_locales) const;
+
private:
DISALLOW_COPY_AND_ASSIGN(LoadedPackage);
@@ -93,8 +112,9 @@
ResStringPool key_string_pool_;
std::string package_name_;
int package_id_ = -1;
- bool dynamic_ = false;
int type_id_offset_ = 0;
+ bool dynamic_ = false;
+ bool system_ = false;
ByteBucketArray<util::unique_cptr<TypeSpec>> type_specs_;
std::vector<DynamicPackageEntry> dynamic_package_map_;
@@ -104,10 +124,14 @@
// when loading, including offsets and lengths.
class LoadedArsc {
public:
- // Load the resource table from memory. The data's lifetime must out-live the
- // object returned from this method.
- static std::unique_ptr<LoadedArsc> Load(const void* data, size_t len,
- bool load_as_shared_library = false);
+ // Load a resource table from memory pointed to by `data` of size `len`.
+ // The lifetime of `data` must out-live the LoadedArsc returned from this method.
+ // If `system` is set to true, the LoadedArsc is considered as a system provided resource.
+ // If `load_as_shared_library` is set to true, the application package (0x7f) is treated
+ // as a shared library (0x00). When loaded into an AssetManager, the package will be assigned an
+ // ID.
+ static std::unique_ptr<const LoadedArsc> Load(const void* data, size_t len, bool system = false,
+ bool load_as_shared_library = false);
~LoadedArsc();
@@ -125,6 +149,10 @@
// Gets a pointer to the name of the package in `resid`, or nullptr if the package doesn't exist.
const LoadedPackage* GetPackageForId(uint32_t resid) const;
+ // Returns true if this is a system provided resource.
+ inline bool IsSystem() const { return system_; }
+
+ // Returns a vector of LoadedPackage pointers, representing the packages in this LoadedArsc.
inline const std::vector<std::unique_ptr<const LoadedPackage>>& GetPackages() const {
return packages_;
}
@@ -137,6 +165,7 @@
ResStringPool global_string_pool_;
std::vector<std::unique_ptr<const LoadedPackage>> packages_;
+ bool system_ = false;
};
} // namespace android
diff --git a/libs/androidfw/include/androidfw/ResourceTypes.h b/libs/androidfw/include/androidfw/ResourceTypes.h
index 56c22e6..04a5d95 100644
--- a/libs/androidfw/include/androidfw/ResourceTypes.h
+++ b/libs/androidfw/include/androidfw/ResourceTypes.h
@@ -1188,6 +1188,8 @@
int compare(const ResTable_config& o) const;
int compareLogical(const ResTable_config& o) const;
+ inline bool operator<(const ResTable_config& o) const { return compare(o) < 0; }
+
// Flags indicating a set of config values. These flag constants must
// match the corresponding ones in android.content.pm.ActivityInfo and
// attrs_manifest.xml.
diff --git a/libs/androidfw/include/androidfw/Util.h b/libs/androidfw/include/androidfw/Util.h
index fd96730..96b42bf 100644
--- a/libs/androidfw/include/androidfw/Util.h
+++ b/libs/androidfw/include/androidfw/Util.h
@@ -94,8 +94,12 @@
inline bool operator==(const unique_cptr& o) const { return ptr_ == o.ptr_; }
+ inline bool operator!=(const unique_cptr& o) const { return ptr_ != o.ptr_; }
+
inline bool operator==(std::nullptr_t) const { return ptr_ == nullptr; }
+ inline bool operator!=(std::nullptr_t) const { return ptr_ != nullptr; }
+
private:
DISALLOW_COPY_AND_ASSIGN(unique_cptr);
diff --git a/libs/androidfw/tests/ApkAssets_test.cpp b/libs/androidfw/tests/ApkAssets_test.cpp
index 0203712..6b4a719 100644
--- a/libs/androidfw/tests/ApkAssets_test.cpp
+++ b/libs/androidfw/tests/ApkAssets_test.cpp
@@ -24,7 +24,8 @@
namespace android {
TEST(ApkAssetsTest, LoadApk) {
- std::unique_ptr<ApkAssets> loaded_apk = ApkAssets::Load(GetTestDataPath() + "/basic/basic.apk");
+ std::unique_ptr<const ApkAssets> loaded_apk =
+ ApkAssets::Load(GetTestDataPath() + "/basic/basic.apk");
ASSERT_NE(nullptr, loaded_apk);
EXPECT_NE(nullptr, loaded_apk->GetLoadedArsc());
@@ -33,7 +34,7 @@
}
TEST(ApkAssetsTest, LoadApkAsSharedLibrary) {
- std::unique_ptr<ApkAssets> loaded_apk =
+ std::unique_ptr<const ApkAssets> loaded_apk =
ApkAssets::Load(GetTestDataPath() + "/appaslib/appaslib.apk");
ASSERT_NE(nullptr, loaded_apk);
const LoadedArsc* loaded_arsc = loaded_apk->GetLoadedArsc();
diff --git a/libs/androidfw/tests/AssetManager2_bench.cpp b/libs/androidfw/tests/AssetManager2_bench.cpp
index b3c2dc3..273290a 100644
--- a/libs/androidfw/tests/AssetManager2_bench.cpp
+++ b/libs/androidfw/tests/AssetManager2_bench.cpp
@@ -38,7 +38,7 @@
static void BM_AssetManagerLoadAssets(benchmark::State& state) {
std::string path = GetTestDataPath() + "/basic/basic.apk";
while (state.KeepRunning()) {
- std::unique_ptr<ApkAssets> apk = ApkAssets::Load(path);
+ std::unique_ptr<const ApkAssets> apk = ApkAssets::Load(path);
AssetManager2 assets;
assets.SetApkAssets({apk.get()});
}
@@ -61,7 +61,7 @@
static void BM_AssetManagerLoadFrameworkAssets(benchmark::State& state) {
std::string path = kFrameworkPath;
while (state.KeepRunning()) {
- std::unique_ptr<ApkAssets> apk = ApkAssets::Load(path);
+ std::unique_ptr<const ApkAssets> apk = ApkAssets::Load(path);
AssetManager2 assets;
assets.SetApkAssets({apk.get()});
}
@@ -84,10 +84,10 @@
static void GetResourceBenchmark(const std::vector<std::string>& paths,
const ResTable_config* config, uint32_t resid,
benchmark::State& state) {
- std::vector<std::unique_ptr<ApkAssets>> apk_assets;
+ std::vector<std::unique_ptr<const ApkAssets>> apk_assets;
std::vector<const ApkAssets*> apk_assets_ptrs;
for (const std::string& path : paths) {
- std::unique_ptr<ApkAssets> apk = ApkAssets::Load(path);
+ std::unique_ptr<const ApkAssets> apk = ApkAssets::Load(path);
if (apk == nullptr) {
state.SkipWithError(base::StringPrintf("Failed to load assets %s", path.c_str()).c_str());
return;
@@ -187,7 +187,7 @@
BENCHMARK(BM_AssetManagerGetResourceFrameworkLocaleOld);
static void BM_AssetManagerGetBag(benchmark::State& state) {
- std::unique_ptr<ApkAssets> apk = ApkAssets::Load(GetTestDataPath() + "/styles/styles.apk");
+ std::unique_ptr<const ApkAssets> apk = ApkAssets::Load(GetTestDataPath() + "/styles/styles.apk");
if (apk == nullptr) {
state.SkipWithError("Failed to load assets");
return;
@@ -234,4 +234,40 @@
}
BENCHMARK(BM_AssetManagerGetBagOld);
+static void BM_AssetManagerGetResourceLocales(benchmark::State& state) {
+ std::unique_ptr<const ApkAssets> apk = ApkAssets::Load(kFrameworkPath);
+ if (apk == nullptr) {
+ state.SkipWithError("Failed to load assets");
+ return;
+ }
+
+ AssetManager2 assets;
+ assets.SetApkAssets({apk.get()});
+
+ while (state.KeepRunning()) {
+ std::set<std::string> locales =
+ assets.GetResourceLocales(false /*exclude_system*/, true /*merge_equivalent_languages*/);
+ benchmark::DoNotOptimize(locales);
+ }
+}
+BENCHMARK(BM_AssetManagerGetResourceLocales);
+
+static void BM_AssetManagerGetResourceLocalesOld(benchmark::State& state) {
+ AssetManager assets;
+ if (!assets.addAssetPath(String8(kFrameworkPath), nullptr /*cookie*/, false /*appAsLib*/,
+ false /*isSystemAssets*/)) {
+ state.SkipWithError("Failed to load assets");
+ return;
+ }
+
+ const ResTable& table = assets.getResources(true);
+
+ while (state.KeepRunning()) {
+ Vector<String8> locales;
+ table.getLocales(&locales, true /*includeSystemLocales*/, true /*mergeEquivalentLangs*/);
+ benchmark::DoNotOptimize(locales);
+ }
+}
+BENCHMARK(BM_AssetManagerGetResourceLocalesOld);
+
} // namespace android
diff --git a/libs/androidfw/tests/AssetManager2_test.cpp b/libs/androidfw/tests/AssetManager2_test.cpp
index 543456a..557d8d4 100644
--- a/libs/androidfw/tests/AssetManager2_test.cpp
+++ b/libs/androidfw/tests/AssetManager2_test.cpp
@@ -26,6 +26,7 @@
#include "data/lib_two/R.h"
#include "data/libclient/R.h"
#include "data/styles/R.h"
+#include "data/system/R.h"
namespace app = com::android::app;
namespace appaslib = com::android::appaslib::app;
@@ -59,16 +60,20 @@
appaslib_assets_ = ApkAssets::Load(GetTestDataPath() + "/appaslib/appaslib.apk");
ASSERT_NE(nullptr, appaslib_assets_);
+
+ system_assets_ = ApkAssets::Load(GetTestDataPath() + "/system/system.apk", true /*system*/);
+ ASSERT_NE(nullptr, system_assets_);
}
protected:
- std::unique_ptr<ApkAssets> basic_assets_;
- std::unique_ptr<ApkAssets> basic_de_fr_assets_;
- std::unique_ptr<ApkAssets> style_assets_;
- std::unique_ptr<ApkAssets> lib_one_assets_;
- std::unique_ptr<ApkAssets> lib_two_assets_;
- std::unique_ptr<ApkAssets> libclient_assets_;
- std::unique_ptr<ApkAssets> appaslib_assets_;
+ std::unique_ptr<const ApkAssets> basic_assets_;
+ std::unique_ptr<const ApkAssets> basic_de_fr_assets_;
+ std::unique_ptr<const ApkAssets> style_assets_;
+ std::unique_ptr<const ApkAssets> lib_one_assets_;
+ std::unique_ptr<const ApkAssets> lib_two_assets_;
+ std::unique_ptr<const ApkAssets> libclient_assets_;
+ std::unique_ptr<const ApkAssets> appaslib_assets_;
+ std::unique_ptr<const ApkAssets> system_assets_;
};
TEST_F(AssetManager2Test, FindsResourceFromSingleApkAssets) {
@@ -291,6 +296,131 @@
EXPECT_EQ(0, bag_two->entries[4].cookie);
}
+TEST_F(AssetManager2Test, ResolveReferenceToResource) {
+ AssetManager2 assetmanager;
+ assetmanager.SetApkAssets({basic_assets_.get()});
+
+ Res_value value;
+ ResTable_config selected_config;
+ uint32_t flags;
+ ApkAssetsCookie cookie =
+ assetmanager.GetResource(basic::R::integer::ref1, false /*may_be_bag*/,
+ 0u /*density_override*/, &value, &selected_config, &flags);
+ ASSERT_NE(kInvalidCookie, cookie);
+
+ EXPECT_EQ(Res_value::TYPE_REFERENCE, value.dataType);
+ EXPECT_EQ(basic::R::integer::ref2, value.data);
+
+ ResTable_ref last_ref;
+ cookie = assetmanager.ResolveReference(cookie, &value, &selected_config, &flags, &last_ref);
+ ASSERT_NE(kInvalidCookie, cookie);
+ EXPECT_EQ(Res_value::TYPE_INT_DEC, value.dataType);
+ EXPECT_EQ(12000u, value.data);
+ EXPECT_EQ(basic::R::integer::ref2, last_ref.ident);
+}
+
+TEST_F(AssetManager2Test, ResolveReferenceToBag) {
+ AssetManager2 assetmanager;
+ assetmanager.SetApkAssets({basic_assets_.get()});
+
+ Res_value value;
+ ResTable_config selected_config;
+ uint32_t flags;
+ ApkAssetsCookie cookie =
+ assetmanager.GetResource(basic::R::integer::number2, true /*may_be_bag*/,
+ 0u /*density_override*/, &value, &selected_config, &flags);
+ ASSERT_NE(kInvalidCookie, cookie);
+
+ EXPECT_EQ(Res_value::TYPE_REFERENCE, value.dataType);
+ EXPECT_EQ(basic::R::array::integerArray1, value.data);
+
+ ResTable_ref last_ref;
+ cookie = assetmanager.ResolveReference(cookie, &value, &selected_config, &flags, &last_ref);
+ ASSERT_NE(kInvalidCookie, cookie);
+ EXPECT_EQ(Res_value::TYPE_REFERENCE, value.dataType);
+ EXPECT_EQ(basic::R::array::integerArray1, value.data);
+ EXPECT_EQ(basic::R::array::integerArray1, last_ref.ident);
+}
+
+static bool IsConfigurationPresent(const std::set<ResTable_config>& configurations,
+ const ResTable_config& configuration) {
+ return configurations.count(configuration) > 0;
+}
+
+TEST_F(AssetManager2Test, GetResourceConfigurations) {
+ AssetManager2 assetmanager;
+ assetmanager.SetApkAssets({system_assets_.get(), basic_de_fr_assets_.get()});
+
+ std::set<ResTable_config> configurations = assetmanager.GetResourceConfigurations();
+
+ // We expect the locale sv from the system assets, and de and fr from basic_de_fr assets.
+ // And one extra for the default configuration.
+ EXPECT_EQ(4u, configurations.size());
+
+ ResTable_config expected_config;
+ memset(&expected_config, 0, sizeof(expected_config));
+ expected_config.language[0] = 's';
+ expected_config.language[1] = 'v';
+ EXPECT_TRUE(IsConfigurationPresent(configurations, expected_config));
+
+ expected_config.language[0] = 'd';
+ expected_config.language[1] = 'e';
+ EXPECT_TRUE(IsConfigurationPresent(configurations, expected_config));
+
+ expected_config.language[0] = 'f';
+ expected_config.language[1] = 'r';
+ EXPECT_TRUE(IsConfigurationPresent(configurations, expected_config));
+
+ // Take out the system assets.
+ configurations = assetmanager.GetResourceConfigurations(true /* exclude_system */);
+
+ // We expect de and fr from basic_de_fr assets.
+ EXPECT_EQ(2u, configurations.size());
+
+ expected_config.language[0] = 's';
+ expected_config.language[1] = 'v';
+ EXPECT_FALSE(IsConfigurationPresent(configurations, expected_config));
+
+ expected_config.language[0] = 'd';
+ expected_config.language[1] = 'e';
+ EXPECT_TRUE(IsConfigurationPresent(configurations, expected_config));
+
+ expected_config.language[0] = 'f';
+ expected_config.language[1] = 'r';
+ EXPECT_TRUE(IsConfigurationPresent(configurations, expected_config));
+}
+
+TEST_F(AssetManager2Test, GetResourceLocales) {
+ AssetManager2 assetmanager;
+ assetmanager.SetApkAssets({system_assets_.get(), basic_de_fr_assets_.get()});
+
+ std::set<std::string> locales = assetmanager.GetResourceLocales();
+
+ // We expect the locale sv from the system assets, and de and fr from basic_de_fr assets.
+ EXPECT_EQ(3u, locales.size());
+ EXPECT_GT(locales.count("sv"), 0u);
+ EXPECT_GT(locales.count("de"), 0u);
+ EXPECT_GT(locales.count("fr"), 0u);
+
+ locales = assetmanager.GetResourceLocales(true /*exclude_system*/);
+ // We expect the de and fr locales from basic_de_fr assets.
+ EXPECT_EQ(2u, locales.size());
+ EXPECT_GT(locales.count("de"), 0u);
+ EXPECT_GT(locales.count("fr"), 0u);
+}
+
+TEST_F(AssetManager2Test, GetResourceId) {
+ AssetManager2 assetmanager;
+ assetmanager.SetApkAssets({basic_assets_.get()});
+
+ EXPECT_EQ(basic::R::layout::main,
+ assetmanager.GetResourceId("com.android.basic:layout/main", "", ""));
+ EXPECT_EQ(basic::R::layout::main,
+ assetmanager.GetResourceId("layout/main", "", "com.android.basic"));
+ EXPECT_EQ(basic::R::layout::main,
+ assetmanager.GetResourceId("main", "layout", "com.android.basic"));
+}
+
TEST_F(AssetManager2Test, OpensFileFromSingleApkAssets) {}
TEST_F(AssetManager2Test, OpensFileFromMultipleApkAssets) {}
diff --git a/libs/androidfw/tests/LoadedArsc_test.cpp b/libs/androidfw/tests/LoadedArsc_test.cpp
index f8aa61a..756869f 100644
--- a/libs/androidfw/tests/LoadedArsc_test.cpp
+++ b/libs/androidfw/tests/LoadedArsc_test.cpp
@@ -32,7 +32,8 @@
ASSERT_TRUE(ReadFileFromZipToString(GetTestDataPath() + "/styles/styles.apk", "resources.arsc",
&contents));
- std::unique_ptr<LoadedArsc> loaded_arsc = LoadedArsc::Load(contents.data(), contents.size());
+ std::unique_ptr<const LoadedArsc> loaded_arsc =
+ LoadedArsc::Load(contents.data(), contents.size());
ASSERT_NE(nullptr, loaded_arsc);
const std::vector<std::unique_ptr<const LoadedPackage>>& packages = loaded_arsc->GetPackages();
@@ -58,7 +59,8 @@
ASSERT_TRUE(
ReadFileFromZipToString(GetTestDataPath() + "/basic/basic.apk", "resources.arsc", &contents));
- std::unique_ptr<LoadedArsc> loaded_arsc = LoadedArsc::Load(contents.data(), contents.size());
+ std::unique_ptr<const LoadedArsc> loaded_arsc =
+ LoadedArsc::Load(contents.data(), contents.size());
ASSERT_NE(nullptr, loaded_arsc);
ResTable_config desired_config;
@@ -80,7 +82,8 @@
ASSERT_TRUE(ReadFileFromZipToString(GetTestDataPath() + "/lib_one/lib_one.apk", "resources.arsc",
&contents));
- std::unique_ptr<LoadedArsc> loaded_arsc = LoadedArsc::Load(contents.data(), contents.size());
+ std::unique_ptr<const LoadedArsc> loaded_arsc =
+ LoadedArsc::Load(contents.data(), contents.size());
ASSERT_NE(nullptr, loaded_arsc);
const auto& packages = loaded_arsc->GetPackages();
@@ -101,7 +104,8 @@
ASSERT_TRUE(ReadFileFromZipToString(GetTestDataPath() + "/libclient/libclient.apk",
"resources.arsc", &contents));
- std::unique_ptr<LoadedArsc> loaded_arsc = LoadedArsc::Load(contents.data(), contents.size());
+ std::unique_ptr<const LoadedArsc> loaded_arsc =
+ LoadedArsc::Load(contents.data(), contents.size());
ASSERT_NE(nullptr, loaded_arsc);
const auto& packages = loaded_arsc->GetPackages();
@@ -128,8 +132,8 @@
ASSERT_TRUE(ReadFileFromZipToString(GetTestDataPath() + "/appaslib/appaslib.apk",
"resources.arsc", &contents));
- std::unique_ptr<LoadedArsc> loaded_arsc =
- LoadedArsc::Load(contents.data(), contents.size(), true /*load_as_shared_library*/);
+ std::unique_ptr<const LoadedArsc> loaded_arsc = LoadedArsc::Load(
+ contents.data(), contents.size(), false /*system*/, true /*load_as_shared_library*/);
ASSERT_NE(nullptr, loaded_arsc);
const auto& packages = loaded_arsc->GetPackages();
@@ -143,7 +147,8 @@
std::string contents;
ASSERT_TRUE(ReadFileFromZipToString(GetTestDataPath() + "/feature/feature.apk", "resources.arsc",
&contents));
- std::unique_ptr<LoadedArsc> loaded_arsc = LoadedArsc::Load(contents.data(), contents.size());
+ std::unique_ptr<const LoadedArsc> loaded_arsc =
+ LoadedArsc::Load(contents.data(), contents.size());
ASSERT_NE(nullptr, loaded_arsc);
ResTable_config desired_config;
diff --git a/libs/androidfw/tests/Theme_bench.cpp b/libs/androidfw/tests/Theme_bench.cpp
index c471be6..594c39e 100644
--- a/libs/androidfw/tests/Theme_bench.cpp
+++ b/libs/androidfw/tests/Theme_bench.cpp
@@ -28,7 +28,7 @@
constexpr const static uint32_t kAttrId = 0x01010030u; // android:attr/colorForeground
static void BM_ThemeApplyStyleFramework(benchmark::State& state) {
- std::unique_ptr<ApkAssets> apk = ApkAssets::Load(kFrameworkPath);
+ std::unique_ptr<const ApkAssets> apk = ApkAssets::Load(kFrameworkPath);
if (apk == nullptr) {
state.SkipWithError("Failed to load assets");
return;
@@ -62,7 +62,7 @@
BENCHMARK(BM_ThemeApplyStyleFrameworkOld);
static void BM_ThemeGetAttribute(benchmark::State& state) {
- std::unique_ptr<ApkAssets> apk = ApkAssets::Load(kFrameworkPath);
+ std::unique_ptr<const ApkAssets> apk = ApkAssets::Load(kFrameworkPath);
AssetManager2 assets;
assets.SetApkAssets({apk.get()});
diff --git a/libs/androidfw/tests/Theme_test.cpp b/libs/androidfw/tests/Theme_test.cpp
index 59cb18a..daed28b0 100644
--- a/libs/androidfw/tests/Theme_test.cpp
+++ b/libs/androidfw/tests/Theme_test.cpp
@@ -46,10 +46,10 @@
}
protected:
- std::unique_ptr<ApkAssets> style_assets_;
- std::unique_ptr<ApkAssets> libclient_assets_;
- std::unique_ptr<ApkAssets> lib_one_assets_;
- std::unique_ptr<ApkAssets> lib_two_assets_;
+ std::unique_ptr<const ApkAssets> style_assets_;
+ std::unique_ptr<const ApkAssets> libclient_assets_;
+ std::unique_ptr<const ApkAssets> lib_one_assets_;
+ std::unique_ptr<const ApkAssets> lib_two_assets_;
};
TEST_F(ThemeTest, EmptyTheme) {
diff --git a/libs/androidfw/tests/data/basic/R.h b/libs/androidfw/tests/data/basic/R.h
index 9352b5c..8e9741e 100644
--- a/libs/androidfw/tests/data/basic/R.h
+++ b/libs/androidfw/tests/data/basic/R.h
@@ -53,6 +53,8 @@
enum : uint32_t {
number1 = 0x7f040000,
number2 = 0x7f040001,
+ ref1 = 0x7f040002,
+ ref2 = 0x7f040003,
// From feature
number3 = 0x7f090000,
diff --git a/libs/androidfw/tests/data/basic/basic.apk b/libs/androidfw/tests/data/basic/basic.apk
index 2c9771b..7ee6734 100644
--- a/libs/androidfw/tests/data/basic/basic.apk
+++ b/libs/androidfw/tests/data/basic/basic.apk
Binary files differ
diff --git a/libs/androidfw/tests/data/basic/basic_de_fr.apk b/libs/androidfw/tests/data/basic/basic_de_fr.apk
index 0481444..e45258c 100644
--- a/libs/androidfw/tests/data/basic/basic_de_fr.apk
+++ b/libs/androidfw/tests/data/basic/basic_de_fr.apk
Binary files differ
diff --git a/libs/androidfw/tests/data/basic/basic_hdpi-v4.apk b/libs/androidfw/tests/data/basic/basic_hdpi-v4.apk
index a8d06e7..4ae1a7c 100644
--- a/libs/androidfw/tests/data/basic/basic_hdpi-v4.apk
+++ b/libs/androidfw/tests/data/basic/basic_hdpi-v4.apk
Binary files differ
diff --git a/libs/androidfw/tests/data/basic/basic_xhdpi-v4.apk b/libs/androidfw/tests/data/basic/basic_xhdpi-v4.apk
index d1dfb14..a240d4c 100644
--- a/libs/androidfw/tests/data/basic/basic_xhdpi-v4.apk
+++ b/libs/androidfw/tests/data/basic/basic_xhdpi-v4.apk
Binary files differ
diff --git a/libs/androidfw/tests/data/basic/basic_xxhdpi-v4.apk b/libs/androidfw/tests/data/basic/basic_xxhdpi-v4.apk
index dca6f2f..fd3d9b2 100644
--- a/libs/androidfw/tests/data/basic/basic_xxhdpi-v4.apk
+++ b/libs/androidfw/tests/data/basic/basic_xxhdpi-v4.apk
Binary files differ
diff --git a/libs/androidfw/tests/data/basic/res/values/values.xml b/libs/androidfw/tests/data/basic/res/values/values.xml
index 11f6b8a..638c983 100644
--- a/libs/androidfw/tests/data/basic/res/values/values.xml
+++ b/libs/androidfw/tests/data/basic/res/values/values.xml
@@ -37,6 +37,12 @@
<public type="integer" name="number2" id="0x7f040001" />
<integer name="number2">@array/integerArray1</integer>
+ <public type="integer" name="ref1" id="0x7f040002" />
+ <integer name="ref1">@integer/ref2</integer>
+
+ <public type="integer" name="ref2" id="0x7f040003" />
+ <integer name="ref2">12000</integer>
+
<public type="style" name="Theme1" id="0x7f050000" />
<style name="Theme1">
<item name="com.android.basic:attr1">100</item>
diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk
index 138a5ef..692199d 100644
--- a/libs/hwui/Android.mk
+++ b/libs/hwui/Android.mk
@@ -192,7 +192,7 @@
ifneq (false,$(ANDROID_ENABLE_RENDERSCRIPT))
hwui_cflags += -DANDROID_ENABLE_RENDERSCRIPT
hwui_c_includes += \
- $(call intermediates-dir-for,STATIC_LIBRARIES,libRS,TARGET,) \
+ $(call intermediates-dir-for,STATIC_LIBRARIES,TARGET,) \
frameworks/rs/cpp \
frameworks/rs
endif
@@ -316,6 +316,7 @@
tests/unit/StringUtilsTests.cpp \
tests/unit/TestUtilsTests.cpp \
tests/unit/TextDropShadowCacheTests.cpp \
+ tests/unit/TextureCacheTests.cpp \
tests/unit/VectorDrawableTests.cpp \
include $(LOCAL_PATH)/hwui_static_deps.mk
diff --git a/libs/hwui/BakedOpDispatcher.cpp b/libs/hwui/BakedOpDispatcher.cpp
index 6079d5d..03a397c 100644
--- a/libs/hwui/BakedOpDispatcher.cpp
+++ b/libs/hwui/BakedOpDispatcher.cpp
@@ -18,6 +18,7 @@
#include "BakedOpRenderer.h"
#include "Caches.h"
+#include "DeferredLayerUpdater.h"
#include "Glop.h"
#include "GlopBuilder.h"
#include "Patch.h"
@@ -762,15 +763,19 @@
}
void BakedOpDispatcher::onTextureLayerOp(BakedOpRenderer& renderer, const TextureLayerOp& op, const BakedOpState& state) {
- const bool tryToSnap = !op.layer->getForceFilter();
- float alpha = (op.layer->getAlpha() / 255.0f) * state.alpha;
+ GlLayer* layer = static_cast<GlLayer*>(op.layerHandle->backingLayer());
+ if (!layer) {
+ return;
+ }
+ const bool tryToSnap = layer->getForceFilter();
+ float alpha = (layer->getAlpha() / 255.0f) * state.alpha;
Glop glop;
GlopBuilder(renderer.renderState(), renderer.caches(), &glop)
.setRoundRectClipState(state.roundRectClipState)
.setMeshTexturedUvQuad(nullptr, Rect(0, 1, 1, 0)) // TODO: simplify with VBO
- .setFillTextureLayer(*(op.layer), alpha)
+ .setFillTextureLayer(*(layer), alpha)
.setTransform(state.computedState.transform, TransformFlags::None)
- .setModelViewMapUnitToRectOptionalSnap(tryToSnap, Rect(op.layer->getWidth(), op.layer->getHeight()))
+ .setModelViewMapUnitToRectOptionalSnap(tryToSnap, Rect(layer->getWidth(), layer->getHeight()))
.build();
renderer.renderGlop(state, glop);
}
diff --git a/libs/hwui/DeferredLayerUpdater.cpp b/libs/hwui/DeferredLayerUpdater.cpp
index 0ae50e9..415e850 100644
--- a/libs/hwui/DeferredLayerUpdater.cpp
+++ b/libs/hwui/DeferredLayerUpdater.cpp
@@ -17,6 +17,7 @@
#include "GlLayer.h"
#include "VkLayer.h"
+#include "renderstate/RenderState.h"
#include "renderthread/EglManager.h"
#include "renderthread/RenderTask.h"
#include "utils/PaintUtils.h"
@@ -24,25 +25,32 @@
namespace android {
namespace uirenderer {
-DeferredLayerUpdater::DeferredLayerUpdater(Layer* layer)
- : mSurfaceTexture(nullptr)
+DeferredLayerUpdater::DeferredLayerUpdater(RenderState& renderState, CreateLayerFn createLayerFn,
+ Layer::Api layerApi)
+ : mRenderState(renderState)
+ , mBlend(false)
+ , mSurfaceTexture(nullptr)
, mTransform(nullptr)
, mNeedsGLContextAttach(false)
, mUpdateTexImage(false)
- , mLayer(layer) {
- mWidth = mLayer->getWidth();
- mHeight = mLayer->getHeight();
- mBlend = mLayer->isBlend();
- mColorFilter = SkSafeRef(mLayer->getColorFilter());
- mAlpha = mLayer->getAlpha();
- mMode = mLayer->getMode();
+ , mLayer(nullptr)
+ , mLayerApi(layerApi)
+ , mCreateLayerFn(createLayerFn) {
+ renderState.registerDeferredLayerUpdater(this);
}
DeferredLayerUpdater::~DeferredLayerUpdater() {
SkSafeUnref(mColorFilter);
setTransform(nullptr);
- mLayer->postDecStrong();
- mLayer = nullptr;
+ mRenderState.unregisterDeferredLayerUpdater(this);
+ destroyLayer();
+}
+
+void DeferredLayerUpdater::destroyLayer() {
+ if (mLayer) {
+ mLayer->postDecStrong();
+ mLayer = nullptr;
+ }
}
void DeferredLayerUpdater::setPaint(const SkPaint* paint) {
@@ -53,6 +61,10 @@
}
void DeferredLayerUpdater::apply() {
+ if (!mLayer) {
+ mLayer = mCreateLayerFn(mRenderState, mWidth, mHeight, mColorFilter, mAlpha, mMode, mBlend);
+ }
+
mLayer->setColorFilter(mColorFilter);
mLayer->setAlpha(mAlpha, mMode);
@@ -157,13 +169,15 @@
void DeferredLayerUpdater::detachSurfaceTexture() {
if (mSurfaceTexture.get()) {
- if (mLayer->getApi() == Layer::Api::OpenGL) {
+ if (mLayerApi == Layer::Api::OpenGL) {
status_t err = mSurfaceTexture->detachFromContext();
if (err != 0) {
// TODO: Elevate to fatal exception
ALOGE("Failed to detach SurfaceTexture from context %d", err);
}
- static_cast<GlLayer*>(mLayer)->clearTexture();
+ if (mLayer) {
+ static_cast<GlLayer*>(mLayer)->clearTexture();
+ }
}
mSurfaceTexture = nullptr;
}
diff --git a/libs/hwui/DeferredLayerUpdater.h b/libs/hwui/DeferredLayerUpdater.h
index 3814be2c..064b724 100644
--- a/libs/hwui/DeferredLayerUpdater.h
+++ b/libs/hwui/DeferredLayerUpdater.h
@@ -32,13 +32,20 @@
namespace android {
namespace uirenderer {
+class RenderState;
+
// Container to hold the properties a layer should be set to at the start
// of a render pass
class DeferredLayerUpdater : public VirtualLightRefBase {
public:
// Note that DeferredLayerUpdater assumes it is taking ownership of the layer
// and will not call incrementRef on it as a result.
- ANDROID_API explicit DeferredLayerUpdater(Layer* layer);
+ typedef std::function<Layer*(RenderState& renderState, uint32_t layerWidth,
+ uint32_t layerHeight, SkColorFilter* colorFilter, int alpha,
+ SkBlendMode mode, bool blend)> CreateLayerFn;
+ ANDROID_API explicit DeferredLayerUpdater(RenderState& renderState,
+ CreateLayerFn createLayerFn, Layer::Api layerApi);
+
ANDROID_API ~DeferredLayerUpdater();
ANDROID_API bool setSize(int width, int height) {
@@ -97,20 +104,30 @@
void updateLayer(bool forceFilter, GLenum renderTarget, const float* textureTransform);
+ void destroyLayer();
+
+ Layer::Api getBackingLayerApi() {
+ return mLayerApi;
+ }
+
private:
+ RenderState& mRenderState;
+
// Generic properties
- int mWidth;
- int mHeight;
- bool mBlend;
- SkColorFilter* mColorFilter;
- int mAlpha;
- SkBlendMode mMode;
+ int mWidth = 0;
+ int mHeight = 0;
+ bool mBlend = false;
+ SkColorFilter* mColorFilter = nullptr;
+ int mAlpha = 255;
+ SkBlendMode mMode = SkBlendMode::kSrcOver;
sp<GLConsumer> mSurfaceTexture;
SkMatrix* mTransform;
bool mNeedsGLContextAttach;
bool mUpdateTexImage;
Layer* mLayer;
+ Layer::Api mLayerApi;
+ CreateLayerFn mCreateLayerFn;
void doUpdateTexImage();
void doUpdateVkTexImage();
diff --git a/libs/hwui/FrameBuilder.cpp b/libs/hwui/FrameBuilder.cpp
index 1d8b021..35ff635 100644
--- a/libs/hwui/FrameBuilder.cpp
+++ b/libs/hwui/FrameBuilder.cpp
@@ -16,6 +16,7 @@
#include "FrameBuilder.h"
+#include "DeferredLayerUpdater.h"
#include "LayerUpdateQueue.h"
#include "RenderNode.h"
#include "VectorDrawable.h"
@@ -784,14 +785,15 @@
}
void FrameBuilder::deferTextureLayerOp(const TextureLayerOp& op) {
- if (CC_UNLIKELY(!op.layer->isRenderable())) return;
+ GlLayer* layer = static_cast<GlLayer*>(op.layerHandle->backingLayer());
+ if (CC_UNLIKELY(!layer || !layer->isRenderable())) return;
const TextureLayerOp* textureLayerOp = &op;
// Now safe to access transform (which was potentially unready at record time)
- if (!op.layer->getTransform().isIdentity()) {
+ if (!layer->getTransform().isIdentity()) {
// non-identity transform present, so 'inject it' into op by copying + replacing matrix
Matrix4 combinedMatrix(op.localMatrix);
- combinedMatrix.multiply(op.layer->getTransform());
+ combinedMatrix.multiply(layer->getTransform());
textureLayerOp = mAllocator.create<TextureLayerOp>(op, combinedMatrix);
}
BakedOpState* bakedState = tryBakeOpState(*textureLayerOp);
diff --git a/libs/hwui/GlLayer.cpp b/libs/hwui/GlLayer.cpp
index c0ab895..8174bcc 100644
--- a/libs/hwui/GlLayer.cpp
+++ b/libs/hwui/GlLayer.cpp
@@ -32,12 +32,14 @@
namespace android {
namespace uirenderer {
-GlLayer::GlLayer(RenderState& renderState, uint32_t layerWidth, uint32_t layerHeight)
- : Layer(renderState, Api::OpenGL)
+GlLayer::GlLayer(RenderState& renderState, uint32_t layerWidth, uint32_t layerHeight,
+ SkColorFilter* colorFilter, int alpha, SkBlendMode mode, bool blend)
+ : Layer(renderState, Api::OpenGL, colorFilter, alpha, mode)
, caches(Caches::getInstance())
, texture(caches) {
texture.mWidth = layerWidth;
texture.mHeight = layerHeight;
+ texture.blend = blend;
}
GlLayer::~GlLayer() {
diff --git a/libs/hwui/GlLayer.h b/libs/hwui/GlLayer.h
index 54bf5ad..23dfd9d 100644
--- a/libs/hwui/GlLayer.h
+++ b/libs/hwui/GlLayer.h
@@ -31,7 +31,8 @@
*/
class GlLayer : public Layer {
public:
- GlLayer(RenderState& renderState, uint32_t layerWidth, uint32_t layerHeight);
+ GlLayer(RenderState& renderState, uint32_t layerWidth, uint32_t layerHeight,
+ SkColorFilter* colorFilter, int alpha, SkBlendMode mode, bool blend);
virtual ~GlLayer();
uint32_t getWidth() const override {
diff --git a/libs/hwui/Layer.cpp b/libs/hwui/Layer.cpp
index 331bb81..b58dfce 100644
--- a/libs/hwui/Layer.cpp
+++ b/libs/hwui/Layer.cpp
@@ -23,10 +23,14 @@
namespace android {
namespace uirenderer {
-Layer::Layer(RenderState& renderState, Api api)
+Layer::Layer(RenderState& renderState, Api api, SkColorFilter* colorFilter, int alpha,
+ SkBlendMode mode)
: GpuMemoryTracker(GpuObjectType::Layer)
, mRenderState(renderState)
- , mApi(api) {
+ , mApi(api)
+ , colorFilter(nullptr)
+ , alpha(alpha)
+ , mode(mode) {
// TODO: This is a violation of Android's typical ref counting, but it
// preserves the old inc/dec ref locations. This should be changed...
incStrong(nullptr);
diff --git a/libs/hwui/Layer.h b/libs/hwui/Layer.h
index 3b639ee..e5520ea 100644
--- a/libs/hwui/Layer.h
+++ b/libs/hwui/Layer.h
@@ -105,7 +105,8 @@
void postDecStrong();
protected:
- Layer(RenderState& renderState, Api api);
+ Layer(RenderState& renderState, Api api, SkColorFilter* colorFilter, int alpha,
+ SkBlendMode mode);
RenderState& mRenderState;
@@ -115,7 +116,7 @@
/**
* Color filter used to draw this layer. Optional.
*/
- SkColorFilter* colorFilter = nullptr;
+ SkColorFilter* colorFilter;
/**
* Indicates raster data backing the layer is scaled, requiring filtration.
@@ -125,12 +126,12 @@
/**
* Opacity of the layer.
*/
- int alpha = 255;
+ int alpha;
/**
* Blending mode of the layer.
*/
- SkBlendMode mode = SkBlendMode::kSrcOver;
+ SkBlendMode mode;
/**
* Optional texture coordinates transform.
diff --git a/libs/hwui/RecordedOp.h b/libs/hwui/RecordedOp.h
index dea2be6..3b87aef 100644
--- a/libs/hwui/RecordedOp.h
+++ b/libs/hwui/RecordedOp.h
@@ -37,6 +37,8 @@
struct ClipBase;
class OffscreenBuffer;
class RenderNode;
+class DeferredLayerUpdater;
+
struct Vertex;
namespace VectorDrawable {
@@ -414,18 +416,18 @@
};
struct TextureLayerOp : RecordedOp {
- TextureLayerOp(BASE_PARAMS_PAINTLESS, GlLayer* layer)
+ TextureLayerOp(BASE_PARAMS_PAINTLESS, DeferredLayerUpdater* layer)
: SUPER_PAINTLESS(TextureLayerOp)
- , layer(layer) {}
+ , layerHandle(layer) {}
// Copy an existing TextureLayerOp, replacing the underlying matrix
TextureLayerOp(const TextureLayerOp& op, const Matrix4& replacementMatrix)
: RecordedOp(RecordedOpId::TextureLayerOp, op.unmappedBounds, replacementMatrix,
op.localClip, op.paint)
- , layer(op.layer) {
+ , layerHandle(op.layerHandle) {
}
- GlLayer* layer;
+ DeferredLayerUpdater* layerHandle;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/libs/hwui/RecordingCanvas.cpp b/libs/hwui/RecordingCanvas.cpp
index b5e5d68..2e33609 100644
--- a/libs/hwui/RecordingCanvas.cpp
+++ b/libs/hwui/RecordingCanvas.cpp
@@ -606,14 +606,13 @@
// We ref the DeferredLayerUpdater due to its thread-safe ref-counting semantics.
mDisplayList->ref(layerHandle);
- LOG_ALWAYS_FATAL_IF(layerHandle->backingLayer()->getApi() != Layer::Api::OpenGL);
+ LOG_ALWAYS_FATAL_IF(layerHandle->getBackingLayerApi() != Layer::Api::OpenGL);
// Note that the backing layer has *not* yet been updated, so don't trust
// its width, height, transform, etc...!
addOp(alloc().create_trivial<TextureLayerOp>(
Rect(layerHandle->getWidth(), layerHandle->getHeight()),
*(mState.currentSnapshot()->transform),
- getRecordedClip(),
- static_cast<GlLayer*>(layerHandle->backingLayer())));
+ getRecordedClip(), layerHandle));
}
void RecordingCanvas::callDrawGLFunction(Functor* functor,
diff --git a/libs/hwui/TextureCache.cpp b/libs/hwui/TextureCache.cpp
index 1aeb8d6..63a6a2c 100644
--- a/libs/hwui/TextureCache.cpp
+++ b/libs/hwui/TextureCache.cpp
@@ -46,7 +46,7 @@
}
TextureCache::~TextureCache() {
- mCache.clear();
+ this->clear();
}
///////////////////////////////////////////////////////////////////////////////
@@ -214,6 +214,10 @@
void TextureCache::clear() {
mCache.clear();
+ for(auto& iter: mHardwareTextures) {
+ iter.second->deleteTexture();
+ }
+ mHardwareTextures.clear();
TEXTURE_LOGD("TextureCache:clear(), mSize = %d", mSize);
}
diff --git a/libs/hwui/VkLayer.h b/libs/hwui/VkLayer.h
index 39522b3..7e41ad1 100644
--- a/libs/hwui/VkLayer.h
+++ b/libs/hwui/VkLayer.h
@@ -27,8 +27,12 @@
*/
class VkLayer : public Layer {
public:
- VkLayer(RenderState& renderState, uint32_t layerWidth, uint32_t layerHeight)
- : Layer(renderState, Api::Vulkan) {}
+ VkLayer(RenderState& renderState, uint32_t layerWidth, uint32_t layerHeight,
+ SkColorFilter* colorFilter, int alpha, SkBlendMode mode, bool blend)
+ : Layer(renderState, Api::Vulkan, colorFilter, alpha, mode)
+ , mWidth(layerWidth)
+ , mHeight(layerHeight)
+ , mBlend(blend) {}
virtual ~VkLayer() {}
diff --git a/libs/hwui/debug/nullegl.cpp b/libs/hwui/debug/nullegl.cpp
index 1ce180dd..2ae71df 100644
--- a/libs/hwui/debug/nullegl.cpp
+++ b/libs/hwui/debug/nullegl.cpp
@@ -22,6 +22,7 @@
#include <string.h>
static EGLDisplay gDisplay = (EGLDisplay) 1;
+static EGLSyncKHR gFence = (EGLSyncKHR) 1;
typedef struct {
EGLSurface surface;
@@ -159,6 +160,18 @@
return (EGLImageKHR) malloc(sizeof(EGLImageKHR));
}
+EGLSyncKHR eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list) {
+ return gFence;
+}
+
+EGLBoolean eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync) {
+ return EGL_TRUE;
+}
+
+EGLint eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout) {
+ return EGL_CONDITION_SATISFIED_KHR;
+}
+
EGLBoolean eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR image) {
free(image);
return EGL_TRUE;
diff --git a/libs/hwui/hwui/Bitmap.cpp b/libs/hwui/hwui/Bitmap.cpp
index a34b61b..3e10b36 100644
--- a/libs/hwui/hwui/Bitmap.cpp
+++ b/libs/hwui/hwui/Bitmap.cpp
@@ -152,6 +152,23 @@
EGLDisplay mDisplay = EGL_NO_DISPLAY;
};
+class AutoGlTexture {
+public:
+ AutoGlTexture(uirenderer::Caches& caches)
+ : mCaches(caches) {
+ glGenTextures(1, &mTexture);
+ caches.textureState().bindTexture(mTexture);
+ }
+
+ ~AutoGlTexture() {
+ mCaches.textureState().deleteTexture(mTexture);
+ }
+
+private:
+ uirenderer::Caches& mCaches;
+ GLuint mTexture = 0;
+};
+
static bool uploadBitmapToGraphicBuffer(uirenderer::Caches& caches, SkBitmap& bitmap,
GraphicBuffer& buffer, GLint format, GLint type) {
SkAutoLockPixels alp(bitmap);
@@ -159,10 +176,6 @@
LOG_ALWAYS_FATAL_IF(display == EGL_NO_DISPLAY,
"Failed to get EGL_DEFAULT_DISPLAY! err=%s",
uirenderer::renderthread::EglManager::eglErrorString());
- // These objects are initialized below but the default "null"
- // values are used to cleanup properly at any point in the
- // initialization sequenc
- GLuint texture = 0;
// We use an EGLImage to access the content of the GraphicBuffer
// The EGL image is later bound to a 2D texture
EGLClientBuffer clientBuffer = (EGLClientBuffer) buffer.getNativeBuffer();
@@ -172,8 +185,7 @@
uirenderer::renderthread::EglManager::eglErrorString());
return false;
}
- glGenTextures(1, &texture);
- caches.textureState().bindTexture(texture);
+ AutoGlTexture glTexture(caches);
glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, autoImage.image);
GL_CHECKPOINT(MODERATE);
diff --git a/libs/hwui/hwui_static_deps.mk b/libs/hwui/hwui_static_deps.mk
index 37126a6..f69da48 100644
--- a/libs/hwui/hwui_static_deps.mk
+++ b/libs/hwui/hwui_static_deps.mk
@@ -29,5 +29,5 @@
libandroidfw
ifneq (false,$(ANDROID_ENABLE_RENDERSCRIPT))
- LOCAL_SHARED_LIBRARIES += libRS libRScpp
+ LOCAL_SHARED_LIBRARIES += libRScpp
endif
diff --git a/libs/hwui/pipeline/skia/ReorderBarrierDrawables.cpp b/libs/hwui/pipeline/skia/ReorderBarrierDrawables.cpp
index d05e7f6..2ead5c5 100644
--- a/libs/hwui/pipeline/skia/ReorderBarrierDrawables.cpp
+++ b/libs/hwui/pipeline/skia/ReorderBarrierDrawables.cpp
@@ -24,6 +24,7 @@
#include <SkGaussianEdgeShader.h>
#include <SkPathOps.h>
#include <SkRRectsGaussianEdgeMaskFilter.h>
+#include <SkShadowUtils.h>
namespace android {
namespace uirenderer {
@@ -115,498 +116,6 @@
}
}
-/**
- * @param canvas the destination for the shadow draws
- * @param shape the shape casting the shadow
- * @param casterZValue the Z value of the caster RRect
- * @param ambientAlpha the maximum alpha value to use when drawing the ambient shadow
- * @param draw the function used to draw 'shape'
- */
-template <typename Shape, typename F>
-static void DrawAmbientShadowGeneral(SkCanvas* canvas, const Shape& shape, float casterZValue,
- float ambientAlpha, F&& draw) {
- if (ambientAlpha <= 0) {
- return;
- }
-
- const float kHeightFactor = 1.f/128.f;
- const float kGeomFactor = 64;
-
- float umbraAlpha = 1 / (1 + SkMaxScalar(casterZValue*kHeightFactor, 0));
- float radius = casterZValue*kHeightFactor*kGeomFactor;
-
- sk_sp<SkMaskFilter> mf = SkBlurMaskFilter::Make(kNormal_SkBlurStyle,
- SkBlurMask::ConvertRadiusToSigma(radius), SkBlurMaskFilter::kNone_BlurFlag);
- SkPaint paint;
- paint.setAntiAlias(true);
- paint.setMaskFilter(std::move(mf));
- paint.setARGB(ambientAlpha*umbraAlpha, 0, 0, 0);
-
- draw(shape, paint);
-}
-
-/**
- * @param canvas the destination for the shadow draws
- * @param shape the shape casting the shadow
- * @param casterZValue the Z value of the caster RRect
- * @param lightPos the position of the light casting the shadow
- * @param lightWidth
- * @param spotAlpha the maximum alpha value to use when drawing the spot shadow
- * @param draw the function used to draw 'shape'
- */
-template <typename Shape, typename F>
-static void DrawSpotShadowGeneral(SkCanvas* canvas, const Shape& shape, float casterZValue,
- float spotAlpha, F&& draw) {
- if (spotAlpha <= 0) {
- return;
- }
-
- const Vector3 lightPos = SkiaPipeline::getLightCenter();
- float zRatio = casterZValue / (lightPos.z - casterZValue);
- // clamp
- if (zRatio < 0.0f) {
- zRatio = 0.0f;
- } else if (zRatio > 0.95f) {
- zRatio = 0.95f;
- }
-
- float blurRadius = SkiaPipeline::getLightRadius()*zRatio;
-
- SkAutoCanvasRestore acr(canvas, true);
-
- sk_sp<SkMaskFilter> mf = SkBlurMaskFilter::Make(kNormal_SkBlurStyle,
- SkBlurMask::ConvertRadiusToSigma(blurRadius), SkBlurMaskFilter::kNone_BlurFlag);
-
- SkPaint paint;
- paint.setAntiAlias(true);
- paint.setMaskFilter(std::move(mf));
- paint.setARGB(spotAlpha, 0, 0, 0);
-
- // approximate projection by translating and scaling projected offset of bounds center
- // TODO: compute the actual 2D projection
- SkScalar scale = lightPos.z / (lightPos.z - casterZValue);
- canvas->scale(scale, scale);
- SkPoint center = SkPoint::Make(shape.getBounds().centerX(), shape.getBounds().centerY());
- SkMatrix ctmInverse;
- if (!canvas->getTotalMatrix().invert(&ctmInverse)) {
- ALOGW("Matrix is degenerate. Will not render shadow!");
- return;
- }
- SkPoint lightPos2D = SkPoint::Make(lightPos.x, lightPos.y);
- ctmInverse.mapPoints(&lightPos2D, 1);
- canvas->translate(zRatio*(center.fX - lightPos2D.fX), zRatio*(center.fY - lightPos2D.fY));
-
- draw(shape, paint);
-}
-
-#define MAX_BLUR_RADIUS 16383.75f
-#define MAX_PAD 64
-
-/**
- * @param casterRect the rectangle bounds of the RRect casting the shadow
- * @param casterCornerRadius the x&y radius for all the corners of the RRect casting the shadow
- * @param ambientAlpha the maximum alpha value to use when drawing the ambient shadow
- * @param spotAlpha the maximum alpha value to use when drawing the spot shadow
- * @param casterAlpha the alpha value of the RRect casting the shadow (0.0-1.0 range)
- * @param casterZValue the Z value of the caster RRect
- * @param scaleFactor the scale needed to map from src-space to device-space
- * @param canvas the destination for the shadow draws
- */
-static void DrawRRectShadows(const SkRect& casterRect, SkScalar casterCornerRadius,
- SkScalar ambientAlpha, SkScalar spotAlpha, SkScalar casterAlpha, SkScalar casterZValue,
- SkScalar scaleFactor, SkCanvas* canvas) {
- SkASSERT(casterCornerRadius >= 0.0f);
-
- // For all of these, we need to ensure we have a rrect with radius >= 0.5f in device space
- const SkScalar minRadius = 0.5f / scaleFactor;
-
- const bool isOval = casterCornerRadius >= std::max(SkScalarHalf(casterRect.width()),
- SkScalarHalf(casterRect.height()));
- const bool isRect = casterCornerRadius <= minRadius;
-
- sk_sp<SkShader> edgeShader(SkGaussianEdgeShader::Make());
-
- if (ambientAlpha > 0.0f) {
- static const float kHeightFactor = 1.0f / 128.0f;
- static const float kGeomFactor = 64.0f;
-
- SkScalar srcSpaceAmbientRadius = casterZValue * kHeightFactor * kGeomFactor;
- // the device-space radius sent to the blur shader must fit in 14.2 fixed point
- if (srcSpaceAmbientRadius*scaleFactor > MAX_BLUR_RADIUS) {
- srcSpaceAmbientRadius = MAX_BLUR_RADIUS/scaleFactor;
- }
- const float umbraAlpha = 1.0f / (1.0f + std::max(casterZValue * kHeightFactor, 0.0f));
- const SkScalar ambientOffset = srcSpaceAmbientRadius * umbraAlpha;
-
- // For the ambient rrect, we inset the offset rect by half the srcSpaceAmbientRadius
- // to get our stroke shape.
- SkScalar ambientPathOutset = std::max(ambientOffset - srcSpaceAmbientRadius * 0.5f,
- minRadius);
-
- SkRRect ambientRRect;
- const SkRect temp = casterRect.makeOutset(ambientPathOutset, ambientPathOutset);
- if (isOval) {
- ambientRRect = SkRRect::MakeOval(temp);
- } else if (isRect) {
- ambientRRect = SkRRect::MakeRectXY(temp, ambientPathOutset, ambientPathOutset);
- } else {
- ambientRRect = SkRRect::MakeRectXY(temp, casterCornerRadius + ambientPathOutset,
- casterCornerRadius + ambientPathOutset);
- }
-
- SkPaint paint;
- paint.setAntiAlias(true);
- paint.setStyle(SkPaint::kStroke_Style);
- // we outset the stroke a little to cover up AA on the interior edge
- float pad = 0.5f;
- paint.setStrokeWidth(srcSpaceAmbientRadius + 2.0f * pad);
- // handle scale of radius and pad due to CTM
- pad *= scaleFactor;
- const SkScalar devSpaceAmbientRadius = srcSpaceAmbientRadius * scaleFactor;
- SkASSERT(devSpaceAmbientRadius <= MAX_BLUR_RADIUS);
- SkASSERT(pad < MAX_PAD);
- // convert devSpaceAmbientRadius to 14.2 fixed point and place in the R & G components
- // convert pad to 6.2 fixed point and place in the B component
- uint16_t iDevSpaceAmbientRadius = (uint16_t)(4.0f * devSpaceAmbientRadius);
- paint.setColor(SkColorSetARGB((unsigned char) ambientAlpha, iDevSpaceAmbientRadius >> 8,
- iDevSpaceAmbientRadius & 0xff, (unsigned char)(4.0f * pad)));
-
- paint.setShader(edgeShader);
- canvas->drawRRect(ambientRRect, paint);
- }
-
- if (spotAlpha > 0.0f) {
- const Vector3 lightPos = SkiaPipeline::getLightCenter();
- float zRatio = casterZValue / (lightPos.z - casterZValue);
- // clamp
- if (zRatio < 0.0f) {
- zRatio = 0.0f;
- } else if (zRatio > 0.95f) {
- zRatio = 0.95f;
- }
-
- const SkScalar lightWidth = SkiaPipeline::getLightRadius();
- SkScalar srcSpaceSpotRadius = 2.0f * lightWidth * zRatio;
- // the device-space radius sent to the blur shader must fit in 14.2 fixed point
- if (srcSpaceSpotRadius*scaleFactor > MAX_BLUR_RADIUS) {
- srcSpaceSpotRadius = MAX_BLUR_RADIUS/scaleFactor;
- }
-
- SkRRect spotRRect;
- if (isOval) {
- spotRRect = SkRRect::MakeOval(casterRect);
- } else if (isRect) {
- spotRRect = SkRRect::MakeRectXY(casterRect, minRadius, minRadius);
- } else {
- spotRRect = SkRRect::MakeRectXY(casterRect, casterCornerRadius, casterCornerRadius);
- }
-
- SkRRect spotShadowRRect;
- // Compute the scale and translation for the spot shadow.
- const SkScalar scale = lightPos.z / (lightPos.z - casterZValue);
- spotRRect.transform(SkMatrix::MakeScale(scale, scale), &spotShadowRRect);
-
- SkPoint center = SkPoint::Make(spotShadowRRect.rect().centerX(),
- spotShadowRRect.rect().centerY());
- SkMatrix ctmInverse;
- if (!canvas->getTotalMatrix().invert(&ctmInverse)) {
- ALOGW("Matrix is degenerate. Will not render spot shadow!");
- return;
- }
- SkPoint lightPos2D = SkPoint::Make(lightPos.x, lightPos.y);
- ctmInverse.mapPoints(&lightPos2D, 1);
- const SkPoint spotOffset = SkPoint::Make(zRatio*(center.fX - lightPos2D.fX),
- zRatio*(center.fY - lightPos2D.fY));
-
- SkAutoCanvasRestore acr(canvas, true);
-
- // We want to extend the stroked area in so that it meets up with the caster
- // geometry. The stroked geometry will, by definition already be inset half the
- // stroke width but we also have to account for the scaling.
- // We also add 1/2 to cover up AA on the interior edge.
- SkScalar scaleOffset = (scale - 1.0f) * SkTMax(SkTMax(SkTAbs(casterRect.fLeft),
- SkTAbs(casterRect.fRight)), SkTMax(SkTAbs(casterRect.fTop),
- SkTAbs(casterRect.fBottom)));
- SkScalar insetAmount = spotOffset.length() - (0.5f * srcSpaceSpotRadius) +
- scaleOffset + 0.5f;
-
- // Compute area
- SkScalar strokeWidth = srcSpaceSpotRadius + insetAmount;
- SkScalar strokedArea = 2.0f*strokeWidth * (spotShadowRRect.width()
- + spotShadowRRect.height());
- SkScalar filledArea = (spotShadowRRect.height() + srcSpaceSpotRadius)
- * (spotShadowRRect.width() + srcSpaceSpotRadius);
-
- SkPaint paint;
- paint.setAntiAlias(true);
-
- // If the area of the stroked geometry is larger than the fill geometry, just fill it.
- if (strokedArea > filledArea || casterAlpha < 1.0f || insetAmount < 0.0f) {
- paint.setStyle(SkPaint::kStrokeAndFill_Style);
- paint.setStrokeWidth(srcSpaceSpotRadius);
- } else {
- // Since we can't have unequal strokes, inset the shadow rect so the inner
- // and outer edges of the stroke will land where we want.
- SkRect insetRect = spotShadowRRect.rect().makeInset(insetAmount/2.0f, insetAmount/2.0f);
- SkScalar insetRad = SkTMax(spotShadowRRect.getSimpleRadii().fX - insetAmount/2.0f,
- minRadius);
- spotShadowRRect = SkRRect::MakeRectXY(insetRect, insetRad, insetRad);
- paint.setStyle(SkPaint::kStroke_Style);
- paint.setStrokeWidth(strokeWidth);
- }
-
- // handle scale of radius and pad due to CTM
- const SkScalar devSpaceSpotRadius = srcSpaceSpotRadius * scaleFactor;
- SkASSERT(devSpaceSpotRadius <= MAX_BLUR_RADIUS);
-
- const SkScalar devSpaceSpotPad = 0;
- SkASSERT(devSpaceSpotPad < MAX_PAD);
-
- // convert devSpaceSpotRadius to 14.2 fixed point and place in the R & G
- // components convert devSpaceSpotPad to 6.2 fixed point and place in the B component
- uint16_t iDevSpaceSpotRadius = (uint16_t)(4.0f * devSpaceSpotRadius);
- paint.setColor(SkColorSetARGB((unsigned char) spotAlpha, iDevSpaceSpotRadius >> 8,
- iDevSpaceSpotRadius & 0xff, (unsigned char)(4.0f * devSpaceSpotPad)));
- paint.setShader(edgeShader);
-
- canvas->translate(spotOffset.fX, spotOffset.fY);
- canvas->drawRRect(spotShadowRRect, paint);
- }
-}
-
-/**
- * @param casterRect the rectangle bounds of the RRect casting the shadow
- * @param casterCornerRadius the x&y radius for all the corners of the RRect casting the shadow
- * @param ambientAlpha the maximum alpha value to use when drawing the ambient shadow
- * @param spotAlpha the maximum alpha value to use when drawing the spot shadow
- * @param casterZValue the Z value of the caster RRect
- * @param scaleFactor the scale needed to map from src-space to device-space
- * @param clipRR the oval or rect with which the drawn roundrect must be intersected
- * @param canvas the destination for the shadow draws
- */
-static void DrawRRectShadowsWithClip(const SkRect& casterRect, SkScalar casterCornerRadius,
- SkScalar ambientAlpha, SkScalar spotAlpha, SkScalar casterZValue, SkScalar scaleFactor,
- const SkRRect& clipRR, SkCanvas* canvas) {
- SkASSERT(casterCornerRadius >= 0.0f);
-
- const bool isOval = casterCornerRadius >= std::max(SkScalarHalf(casterRect.width()),
- SkScalarHalf(casterRect.height()));
-
- if (ambientAlpha > 0.0f) {
- static const float kHeightFactor = 1.0f / 128.0f;
- static const float kGeomFactor = 64.0f;
-
- const SkScalar srcSpaceAmbientRadius = casterZValue * kHeightFactor * kGeomFactor;
- const SkScalar devSpaceAmbientRadius = srcSpaceAmbientRadius * scaleFactor;
-
- const float umbraAlpha = 1.0f / (1.0f + std::max(casterZValue * kHeightFactor, 0.0f));
- const SkScalar ambientOffset = srcSpaceAmbientRadius * umbraAlpha;
-
- const SkRect srcSpaceAmbientRect = casterRect.makeOutset(ambientOffset, ambientOffset);
- SkRect devSpaceAmbientRect;
- canvas->getTotalMatrix().mapRect(&devSpaceAmbientRect, srcSpaceAmbientRect);
-
- SkRRect devSpaceAmbientRRect;
- if (isOval) {
- devSpaceAmbientRRect = SkRRect::MakeOval(devSpaceAmbientRect);
- } else {
- const SkScalar devSpaceCornerRadius = scaleFactor * (casterCornerRadius + ambientOffset);
- devSpaceAmbientRRect = SkRRect::MakeRectXY(devSpaceAmbientRect, devSpaceCornerRadius,
- devSpaceCornerRadius);
- }
-
- const SkRect srcSpaceAmbClipRect = clipRR.rect().makeOutset(ambientOffset, ambientOffset);
- SkRect devSpaceAmbClipRect;
- canvas->getTotalMatrix().mapRect(&devSpaceAmbClipRect, srcSpaceAmbClipRect);
- SkRRect devSpaceAmbientClipRR;
- if (clipRR.isOval()) {
- devSpaceAmbientClipRR = SkRRect::MakeOval(devSpaceAmbClipRect);
- } else {
- SkASSERT(clipRR.isRect());
- devSpaceAmbientClipRR = SkRRect::MakeRect(devSpaceAmbClipRect);
- }
-
- SkRect cover = srcSpaceAmbClipRect;
- if (!cover.intersect(srcSpaceAmbientRect)) {
- return;
- }
-
- SkPaint paint;
- paint.setColor(SkColorSetARGB((unsigned char) ambientAlpha, 0, 0, 0));
- paint.setMaskFilter(SkRRectsGaussianEdgeMaskFilter::Make(devSpaceAmbientRRect,
- devSpaceAmbientClipRR, devSpaceAmbientRadius));
- canvas->drawRect(cover, paint);
- }
-
- if (spotAlpha > 0.0f) {
- const Vector3 lightPos = SkiaPipeline::getLightCenter();
- float zRatio = casterZValue / (lightPos.z - casterZValue);
- // clamp
- if (zRatio < 0.0f) {
- zRatio = 0.0f;
- } else if (zRatio > 0.95f) {
- zRatio = 0.95f;
- }
-
- const SkScalar lightWidth = SkiaPipeline::getLightRadius();
- const SkScalar srcSpaceSpotRadius = 2.0f * lightWidth * zRatio;
- const SkScalar devSpaceSpotRadius = srcSpaceSpotRadius * scaleFactor;
-
- // Compute the scale and translation for the spot shadow.
- const SkScalar scale = lightPos.z / (lightPos.z - casterZValue);
- const SkMatrix spotMatrix = SkMatrix::MakeScale(scale, scale);
-
- SkRect srcSpaceScaledRect = casterRect;
- spotMatrix.mapRect(&srcSpaceScaledRect);
- srcSpaceScaledRect.outset(SkScalarHalf(srcSpaceSpotRadius),
- SkScalarHalf(srcSpaceSpotRadius));
-
- SkRRect srcSpaceSpotRRect;
- if (isOval) {
- srcSpaceSpotRRect = SkRRect::MakeOval(srcSpaceScaledRect);
- } else {
- srcSpaceSpotRRect = SkRRect::MakeRectXY(srcSpaceScaledRect, casterCornerRadius * scale,
- casterCornerRadius * scale);
- }
-
- SkPoint center = SkPoint::Make(srcSpaceSpotRRect.rect().centerX(),
- srcSpaceSpotRRect.rect().centerY());
- SkMatrix ctmInverse;
- if (!canvas->getTotalMatrix().invert(&ctmInverse)) {
- ALOGW("Matrix is degenerate. Will not render spot shadow!");
- return;
- }
- SkPoint lightPos2D = SkPoint::Make(lightPos.x, lightPos.y);
- ctmInverse.mapPoints(&lightPos2D, 1);
- const SkPoint spotOffset = SkPoint::Make(zRatio*(center.fX - lightPos2D.fX),
- zRatio*(center.fY - lightPos2D.fY));
-
- SkAutoCanvasRestore acr(canvas, true);
- canvas->translate(spotOffset.fX, spotOffset.fY);
-
- SkRect devSpaceScaledRect;
- canvas->getTotalMatrix().mapRect(&devSpaceScaledRect, srcSpaceScaledRect);
-
- SkRRect devSpaceSpotRRect;
- if (isOval) {
- devSpaceSpotRRect = SkRRect::MakeOval(devSpaceScaledRect);
- } else {
- const SkScalar devSpaceScaledCornerRadius = casterCornerRadius * scale * scaleFactor;
- devSpaceSpotRRect = SkRRect::MakeRectXY(devSpaceScaledRect, devSpaceScaledCornerRadius,
- devSpaceScaledCornerRadius);
- }
-
- SkPaint paint;
- paint.setColor(SkColorSetARGB((unsigned char) spotAlpha, 0, 0, 0));
-
- SkRect srcSpaceScaledClipRect = clipRR.rect();
- spotMatrix.mapRect(&srcSpaceScaledClipRect);
- srcSpaceScaledClipRect.outset(SkScalarHalf(srcSpaceSpotRadius),
- SkScalarHalf(srcSpaceSpotRadius));
-
- SkRect devSpaceScaledClipRect;
- canvas->getTotalMatrix().mapRect(&devSpaceScaledClipRect, srcSpaceScaledClipRect);
- SkRRect devSpaceSpotClipRR;
- if (clipRR.isOval()) {
- devSpaceSpotClipRR = SkRRect::MakeOval(devSpaceScaledClipRect);
- } else {
- SkASSERT(clipRR.isRect());
- devSpaceSpotClipRR = SkRRect::MakeRect(devSpaceScaledClipRect);
- }
-
- paint.setMaskFilter(SkRRectsGaussianEdgeMaskFilter::Make(devSpaceSpotRRect,
- devSpaceSpotClipRR, devSpaceSpotRadius));
-
- SkRect cover = srcSpaceScaledClipRect;
- if (!cover.intersect(srcSpaceSpotRRect.rect())) {
- return;
- }
-
- canvas->drawRect(cover, paint);
- }
-}
-
-/**
- * @param casterRect the rectangle bounds of the RRect casting the shadow
- * @param casterCornerRadius the x&y radius for all the corners of the RRect casting the shadow
- * @param casterClipRect a rectangular clip that must be intersected with the
- * shadow-casting RRect prior to casting the shadow
- * @param revealClip a circular clip that must be interested with the castClipRect
- * and the shadow-casting rect prior to casting the shadow
- * @param ambientAlpha the maximum alpha value to use when drawing the ambient shadow
- * @param spotAlpha the maximum alpha value to use when drawing the spot shadow
- * @param casterAlpha the alpha value of the RRect casting the shadow (0.0-1.0 range)
- * @param casterZValue the Z value of the caster RRect
- * @param canvas the destination for the shadow draws
- *
- * We have special cases for 4 round rect shadow draws:
- * 1) a RRect clipped by a reveal animation
- * 2) a RRect clipped by a rectangle
- * 3) an unclipped RRect with non-uniform scale
- * 4) an unclipped RRect with uniform scale
- * 1,2 and 4 require that the scale is uniform.
- * 1 and 2 require that rects stay rects.
- */
-static bool DrawShadowsAsRRects(const SkRect& casterRect, SkScalar casterCornerRadius,
- const SkRect& casterClipRect, const RevealClip& revealClip, SkScalar ambientAlpha,
- SkScalar spotAlpha, SkScalar casterAlpha, SkScalar casterZValue, SkCanvas* canvas) {
- SkScalar scaleFactors[2];
- if (!canvas->getTotalMatrix().getMinMaxScales(scaleFactors)) {
- ALOGW("Matrix is degenerate. Will not render shadow!");
- return false;
- }
-
- // The casterClipRect will be empty when bounds clipping is disabled
- bool casterIsClippedByRect = !casterClipRect.isEmpty();
- bool uniformScale = scaleFactors[0] == scaleFactors[1];
-
- if (revealClip.willClip()) {
- if (casterIsClippedByRect || !uniformScale || !canvas->getTotalMatrix().rectStaysRect()) {
- return false; // Fall back to the slow path since PathOps are required
- }
-
- const float revealRadius = revealClip.getRadius();
- SkRect revealClipRect = SkRect::MakeLTRB(revealClip.getX()-revealRadius,
- revealClip.getY()-revealRadius, revealClip.getX()+revealRadius,
- revealClip.getY()+revealRadius);
- SkRRect revealClipRR = SkRRect::MakeOval(revealClipRect);
-
- DrawRRectShadowsWithClip(casterRect, casterCornerRadius, ambientAlpha, spotAlpha,
- casterZValue, scaleFactors[0], revealClipRR, canvas);
- return true;
- }
-
- if (casterIsClippedByRect) {
- if (!uniformScale || !canvas->getTotalMatrix().rectStaysRect()) {
- return false; // Fall back to the slow path since PathOps are required
- }
-
- SkRRect casterClipRR = SkRRect::MakeRect(casterClipRect);
-
- DrawRRectShadowsWithClip(casterRect, casterCornerRadius, ambientAlpha, spotAlpha,
- casterZValue, scaleFactors[0], casterClipRR, canvas);
- return true;
- }
-
- // The fast path needs uniform scale
- if (!uniformScale) {
- SkRRect casterRR = SkRRect::MakeRectXY(casterRect, casterCornerRadius, casterCornerRadius);
- DrawAmbientShadowGeneral(canvas, casterRR, casterZValue, ambientAlpha,
- [&](const SkRRect& rrect, const SkPaint& paint) {
- canvas->drawRRect(rrect, paint);
- });
- DrawSpotShadowGeneral(canvas, casterRR, casterZValue, spotAlpha,
- [&](const SkRRect& rrect, const SkPaint& paint) {
- canvas->drawRRect(rrect, paint);
- });
- return true;
- }
-
- DrawRRectShadows(casterRect, casterCornerRadius, ambientAlpha, spotAlpha, casterAlpha,
- casterZValue, scaleFactors[0], canvas);
- return true;
-}
-
// copied from FrameBuilder::deferShadow
void EndReorderBarrierDrawable::drawShadow(SkCanvas* canvas, RenderNodeDrawable* caster) {
const RenderProperties& casterProperties = caster->getNodeProperties();
@@ -626,8 +135,8 @@
return;
}
- float ambientAlpha = SkiaPipeline::getAmbientShadowAlpha()*casterAlpha;
- float spotAlpha = SkiaPipeline::getSpotShadowAlpha()*casterAlpha;
+ float ambientAlpha = (SkiaPipeline::getAmbientShadowAlpha()/255.f)*casterAlpha;
+ float spotAlpha = (SkiaPipeline::getSpotShadowAlpha()/255.f)*casterAlpha;
const float casterZValue = casterProperties.getZ();
const RevealClip& revealClip = casterProperties.getRevealClip();
@@ -659,19 +168,7 @@
hwuiMatrix.copyTo(shadowMatrix);
canvas->concat(shadowMatrix);
- const Outline& casterOutline = casterProperties.getOutline();
- Rect possibleRect;
- float radius;
- if (casterOutline.getAsRoundRect(&possibleRect, &radius)) {
- if (DrawShadowsAsRRects(possibleRect.toSkRect(), radius, casterClipRect, revealClip,
- ambientAlpha, spotAlpha, casterAlpha, casterZValue, canvas)) {
- return;
- }
- }
-
- // Hard cases and calls to general shadow code
const SkPath* casterOutlinePath = casterProperties.getOutline().getPath();
-
// holds temporary SkPath to store the result of intersections
SkPath tmpPath;
const SkPath* casterPath = casterOutlinePath;
@@ -691,16 +188,11 @@
Op(*casterPath, clipBoundsPath, kIntersect_SkPathOp, &tmpPath);
casterPath = &tmpPath;
}
-
- DrawAmbientShadowGeneral(canvas, *casterPath, casterZValue, ambientAlpha,
- [&](const SkPath& path, const SkPaint& paint) {
- canvas->drawPath(path, paint);
- });
-
- DrawSpotShadowGeneral(canvas, *casterPath, casterZValue, spotAlpha,
- [&](const SkPath& path, const SkPaint& paint) {
- canvas->drawPath(path, paint);
- });
+ const Vector3 lightPos = SkiaPipeline::getLightCenter();
+ SkPoint3 skiaLightPos = SkPoint3::Make(lightPos.x, lightPos.y, lightPos.z);
+ SkShadowUtils::DrawShadow(canvas, *casterPath, casterZValue, skiaLightPos,
+ SkiaPipeline::getLightRadius(), ambientAlpha, spotAlpha, SK_ColorBLACK,
+ casterAlpha < 1.0f ? SkShadowFlags::kTransparentOccluder_ShadowFlag : 0);
}
}; // namespace skiapipeline
diff --git a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp
index 65a1dc3..de80ee3 100644
--- a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp
@@ -135,11 +135,17 @@
return LayerDrawable::DrawLayer(mRenderThread.getGrContext(), &canvas, layer);
}
+static Layer* createLayer(RenderState& renderState, uint32_t layerWidth, uint32_t layerHeight,
+ SkColorFilter* colorFilter, int alpha, SkBlendMode mode, bool blend) {
+ GlLayer* layer = new GlLayer(renderState, layerWidth, layerHeight, colorFilter, alpha,
+ mode, blend);
+ layer->generateTexture();
+ return layer;
+}
+
DeferredLayerUpdater* SkiaOpenGLPipeline::createTextureLayer() {
mEglManager.initialize();
- GlLayer* layer = new GlLayer(mRenderThread.renderState(), 0, 0);
- layer->generateTexture();
- return new DeferredLayerUpdater(layer);
+ return new DeferredLayerUpdater(mRenderThread.renderState(), createLayer, Layer::Api::OpenGL);
}
void SkiaOpenGLPipeline::onStop() {
diff --git a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp
index 910c339..c63dce1 100644
--- a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp
@@ -118,11 +118,15 @@
return false;
}
+static Layer* createLayer(RenderState& renderState, uint32_t layerWidth, uint32_t layerHeight,
+ SkColorFilter* colorFilter, int alpha, SkBlendMode mode, bool blend) {
+ return new VkLayer(renderState, layerWidth, layerHeight, colorFilter, alpha, mode, blend);
+}
+
DeferredLayerUpdater* SkiaVulkanPipeline::createTextureLayer() {
mVkManager.initialize();
- VkLayer* layer = new VkLayer(mRenderThread.renderState(), 0, 0);
- return new DeferredLayerUpdater(layer);
+ return new DeferredLayerUpdater(mRenderThread.renderState(), createLayer, Layer::Api::Vulkan);
}
void SkiaVulkanPipeline::onStop() {
diff --git a/libs/hwui/renderstate/RenderState.cpp b/libs/hwui/renderstate/RenderState.cpp
index 17ee390..7dfc2ee 100644
--- a/libs/hwui/renderstate/RenderState.cpp
+++ b/libs/hwui/renderstate/RenderState.cpp
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#include "DeferredLayerUpdater.h"
#include "GlLayer.h"
#include "VkLayer.h"
#include <GpuMemoryTracker.h>
@@ -79,6 +80,7 @@
delete mStencil;
mStencil = nullptr;
+ destroyLayersInUpdater();
GpuMemoryTracker::onGpuContextDestroyed();
}
@@ -209,6 +211,14 @@
}
}
+static void destroyLayerInUpdater(DeferredLayerUpdater* layerUpdater) {
+ layerUpdater->destroyLayer();
+}
+
+void RenderState::destroyLayersInUpdater() {
+ std::for_each(mActiveLayerUpdaters.begin(), mActiveLayerUpdaters.end(), destroyLayerInUpdater);
+}
+
class DecStrongTask : public renderthread::RenderTask {
public:
explicit DecStrongTask(VirtualLightRefBase* object) : mObject(object) {}
diff --git a/libs/hwui/renderstate/RenderState.h b/libs/hwui/renderstate/RenderState.h
index d183a15..f78bf7a 100644
--- a/libs/hwui/renderstate/RenderState.h
+++ b/libs/hwui/renderstate/RenderState.h
@@ -42,6 +42,7 @@
class Caches;
class Layer;
+class DeferredLayerUpdater;
namespace renderthread {
class CanvasContext;
@@ -90,6 +91,14 @@
mRegisteredContexts.erase(context);
}
+ void registerDeferredLayerUpdater(DeferredLayerUpdater* layerUpdater) {
+ mActiveLayerUpdaters.insert(layerUpdater);
+ }
+
+ void unregisterDeferredLayerUpdater(DeferredLayerUpdater* layerUpdater) {
+ mActiveLayerUpdaters.erase(layerUpdater);
+ }
+
// TODO: This system is a little clunky feeling, this could use some
// more thinking...
void postDecStrong(VirtualLightRefBase* object);
@@ -110,6 +119,7 @@
private:
void interruptForFunctorInvoke();
void resumeFromFunctorInvoke();
+ void destroyLayersInUpdater();
explicit RenderState(renderthread::RenderThread& thread);
~RenderState();
@@ -126,6 +136,7 @@
OffscreenBufferPool mLayerPool;
std::set<Layer*> mActiveLayers;
+ std::set<DeferredLayerUpdater*> mActiveLayerUpdaters;
std::set<renderthread::CanvasContext*> mRegisteredContexts;
GLsizei mViewportWidth;
diff --git a/libs/hwui/renderthread/OpenGLPipeline.cpp b/libs/hwui/renderthread/OpenGLPipeline.cpp
index df40a44..8a5d9cc 100644
--- a/libs/hwui/renderthread/OpenGLPipeline.cpp
+++ b/libs/hwui/renderthread/OpenGLPipeline.cpp
@@ -125,13 +125,18 @@
static_cast<GlLayer&>(*layer->backingLayer()), bitmap);
}
-DeferredLayerUpdater* OpenGLPipeline::createTextureLayer() {
- mEglManager.initialize();
- GlLayer* layer = new GlLayer(mRenderThread.renderState(), 0, 0);
+static Layer* createLayer(RenderState& renderState, uint32_t layerWidth, uint32_t layerHeight,
+ SkColorFilter* colorFilter, int alpha, SkBlendMode mode, bool blend) {
+ GlLayer* layer = new GlLayer(renderState, layerWidth, layerHeight, colorFilter, alpha,
+ mode, blend);
Caches::getInstance().textureState().activateTexture(0);
layer->generateTexture();
+ return layer;
+}
- return new DeferredLayerUpdater(layer);
+DeferredLayerUpdater* OpenGLPipeline::createTextureLayer() {
+ mEglManager.initialize();
+ return new DeferredLayerUpdater(mRenderThread.renderState(), createLayer, Layer::Api::OpenGL);
}
void OpenGLPipeline::onStop() {
diff --git a/libs/hwui/renderthread/VulkanManager.cpp b/libs/hwui/renderthread/VulkanManager.cpp
index 454ce4d..c2c2f22 100644
--- a/libs/hwui/renderthread/VulkanManager.cpp
+++ b/libs/hwui/renderthread/VulkanManager.cpp
@@ -603,6 +603,11 @@
}
void VulkanManager::swapBuffers(VulkanSurface* surface) {
+ if (CC_UNLIKELY(Properties::waitForGpuCompletion)) {
+ ATRACE_NAME("Finishing GPU work");
+ mDeviceWaitIdle(mBackendContext->fDevice);
+ }
+
VulkanSurface::BackbufferInfo* backbuffer = surface->mBackbuffers +
surface->mCurrentBackbufferIndex;
GrVkImageInfo* imageInfo;
diff --git a/libs/hwui/tests/common/TestUtils.cpp b/libs/hwui/tests/common/TestUtils.cpp
index 0916d72..3e52c39 100644
--- a/libs/hwui/tests/common/TestUtils.cpp
+++ b/libs/hwui/tests/common/TestUtils.cpp
@@ -60,6 +60,7 @@
pipeline = new skiapipeline::SkiaVulkanPipeline(renderThread);
}
sp<DeferredLayerUpdater> layerUpdater = pipeline->createTextureLayer();
+ layerUpdater->apply();
delete pipeline;
return layerUpdater;
}
diff --git a/libs/hwui/tests/unit/TextureCacheTests.cpp b/libs/hwui/tests/unit/TextureCacheTests.cpp
new file mode 100644
index 0000000..72384bf
--- /dev/null
+++ b/libs/hwui/tests/unit/TextureCacheTests.cpp
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gtest/gtest.h>
+
+#include "Extensions.h"
+#include "TextureCache.h"
+#include "tests/common/TestUtils.h"
+
+using namespace android;
+using namespace android::uirenderer;
+
+RENDERTHREAD_OPENGL_PIPELINE_TEST(TextureCache, clear) {
+ TextureCache cache;
+ ASSERT_EQ(cache.getSize(), 0u);
+ // it is not 0, because FontRenderer allocates one texture
+ int initialCount = GpuMemoryTracker::getInstanceCount(GpuObjectType::Texture);
+ SkBitmap skBitmap;
+ SkImageInfo info = SkImageInfo::Make(100, 100, kN32_SkColorType, kPremul_SkAlphaType);
+ skBitmap.setInfo(info);
+ sk_sp<Bitmap> hwBitmap(Bitmap::allocateHardwareBitmap(renderThread, skBitmap));
+ cache.get(hwBitmap.get());
+ ASSERT_EQ(GpuMemoryTracker::getInstanceCount(GpuObjectType::Texture), initialCount + 1);
+ cache.clear();
+ ASSERT_EQ(GpuMemoryTracker::getInstanceCount(GpuObjectType::Texture), initialCount);
+}
diff --git a/media/java/android/media/AudioAttributes.java b/media/java/android/media/AudioAttributes.java
index 391a905..ce58a9c 100644
--- a/media/java/android/media/AudioAttributes.java
+++ b/media/java/android/media/AudioAttributes.java
@@ -913,13 +913,13 @@
}
}
/**
- * @hide
- * CANDIDATE FOR PUBLIC (or at least SYSTEM) API
* Returns the stream type matching the given attributes for volume control.
* Use this method to derive the stream type needed to configure the volume
- * control slider in an {@link Activity} with {@link Activity#setVolumeControlStream(int)}.
+ * control slider in an {@link android.app.Activity} with
+ * {@link android.app.Activity#setVolumeControlStream(int)}.
* <BR>Do not use this method to set the stream type on an audio player object
- * (e.g. {@link AudioTrack}, {@link MediaPlayer}), use <code>AudioAttributes</code> instead.
+ * (e.g. {@link AudioTrack}, {@link MediaPlayer}) as this is deprecated,
+ * use <code>AudioAttributes</code> instead.
* @param aa non-null AudioAttributes.
* @return a valid stream type for <code>Activity</code> or stream volume control that matches
* the attributes, or {@link AudioManager#USE_DEFAULT_STREAM_TYPE} if there isn't a direct
diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java
index 5c9f270..cd38b50 100644
--- a/media/java/android/media/AudioTrack.java
+++ b/media/java/android/media/AudioTrack.java
@@ -27,6 +27,7 @@
import android.annotation.IntDef;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.app.ActivityThread;
import android.content.Context;
import android.os.Handler;
@@ -538,6 +539,15 @@
throw new IllegalArgumentException("Illegal null AudioFormat");
}
+ // Check if we should enable deep buffer mode
+ if (shouldEnablePowerSaving(mAttributes, format, bufferSizeInBytes, mode)) {
+ mAttributes = new AudioAttributes.Builder(mAttributes)
+ .replaceFlags((mAttributes.getAllFlags()
+ | AudioAttributes.FLAG_DEEP_BUFFER)
+ & ~AudioAttributes.FLAG_LOW_LATENCY)
+ .build();
+ }
+
// remember which looper is associated with the AudioTrack instantiation
Looper looper;
if ((looper = Looper.myLooper()) == null) {
@@ -861,7 +871,10 @@
.build();
break;
case PERFORMANCE_MODE_NONE:
- break;
+ if (!shouldEnablePowerSaving(mAttributes, mFormat, mBufferSizeInBytes, mMode)) {
+ break; // do not enable deep buffer mode.
+ }
+ // permitted to fall through to enable deep buffer
case PERFORMANCE_MODE_POWER_SAVING:
mAttributes = new AudioAttributes.Builder(mAttributes)
.replaceFlags((mAttributes.getAllFlags()
@@ -912,6 +925,56 @@
AudioFormat.CHANNEL_OUT_SIDE_LEFT |
AudioFormat.CHANNEL_OUT_SIDE_RIGHT;
+ // Returns a boolean whether the attributes, format, bufferSizeInBytes, mode allow
+ // power saving to be automatically enabled for an AudioTrack. Returns false if
+ // power saving is already enabled in the attributes parameter.
+ private static boolean shouldEnablePowerSaving(
+ @Nullable AudioAttributes attributes, @Nullable AudioFormat format,
+ int bufferSizeInBytes, int mode) {
+ // If no attributes, OK
+ // otherwise check attributes for USAGE_MEDIA and CONTENT_UNKNOWN, MUSIC, or MOVIE.
+ if (attributes != null &&
+ (attributes.getAllFlags() != 0 // cannot have any special flags
+ || attributes.getUsage() != AudioAttributes.USAGE_MEDIA
+ || (attributes.getContentType() != AudioAttributes.CONTENT_TYPE_UNKNOWN
+ && attributes.getContentType() != AudioAttributes.CONTENT_TYPE_MUSIC
+ && attributes.getContentType() != AudioAttributes.CONTENT_TYPE_MOVIE))) {
+ return false;
+ }
+
+ // Format must be fully specified and be linear pcm
+ if (format == null
+ || format.getSampleRate() == AudioFormat.SAMPLE_RATE_UNSPECIFIED
+ || !AudioFormat.isEncodingLinearPcm(format.getEncoding())
+ || !AudioFormat.isValidEncoding(format.getEncoding())
+ || format.getChannelCount() < 1) {
+ return false;
+ }
+
+ // Mode must be streaming
+ if (mode != MODE_STREAM) {
+ return false;
+ }
+
+ // A buffer size of 0 is always compatible with deep buffer (when called from the Builder)
+ // but for app compatibility we only use deep buffer power saving for large buffer sizes.
+ if (bufferSizeInBytes != 0) {
+ final long BUFFER_TARGET_MODE_STREAM_MS = 100;
+ final int MILLIS_PER_SECOND = 1000;
+ final long bufferTargetSize =
+ BUFFER_TARGET_MODE_STREAM_MS
+ * format.getChannelCount()
+ * format.getBytesPerSample(format.getEncoding())
+ * format.getSampleRate()
+ / MILLIS_PER_SECOND;
+ if (bufferSizeInBytes < bufferTargetSize) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
// Convenience method for the constructor's parameter checks.
// This is where constructor IllegalArgumentException-s are thrown
// postconditions:
diff --git a/media/java/android/media/MediaMuxer.java b/media/java/android/media/MediaMuxer.java
index a1f816b..80832f8 100644
--- a/media/java/android/media/MediaMuxer.java
+++ b/media/java/android/media/MediaMuxer.java
@@ -83,13 +83,17 @@
private OutputFormat() {}
/** MPEG4 media file format*/
public static final int MUXER_OUTPUT_MPEG_4 = 0;
+ /** WEBM media file format*/
public static final int MUXER_OUTPUT_WEBM = 1;
+ /** 3GPP media file format*/
+ public static final int MUXER_OUTPUT_3GPP = 2;
};
/** @hide */
@IntDef({
OutputFormat.MUXER_OUTPUT_MPEG_4,
OutputFormat.MUXER_OUTPUT_WEBM,
+ OutputFormat.MUXER_OUTPUT_3GPP,
})
@Retention(RetentionPolicy.SOURCE)
public @interface Format {}
@@ -166,8 +170,8 @@
}
private void setUpMediaMuxer(@NonNull FileDescriptor fd, @Format int format) throws IOException {
- if (format != OutputFormat.MUXER_OUTPUT_MPEG_4 &&
- format != OutputFormat.MUXER_OUTPUT_WEBM) {
+ if (format != OutputFormat.MUXER_OUTPUT_MPEG_4 && format != OutputFormat.MUXER_OUTPUT_WEBM
+ && format != OutputFormat.MUXER_OUTPUT_3GPP) {
throw new IllegalArgumentException("format: " + format + " is invalid");
}
mNativeObject = nativeSetup(fd, format);
diff --git a/media/java/android/media/session/IOnMediaKeyListener.aidl b/media/java/android/media/session/IOnMediaKeyListener.aidl
index 7752357..aa98ea31 100644
--- a/media/java/android/media/session/IOnMediaKeyListener.aidl
+++ b/media/java/android/media/session/IOnMediaKeyListener.aidl
@@ -22,7 +22,7 @@
* Listener to handle media key.
* @hide
*/
-interface IOnMediaKeyListener {
+oneway interface IOnMediaKeyListener {
void onMediaKey(in KeyEvent event, in ResultReceiver result);
}
diff --git a/media/java/android/media/session/ISessionCallback.aidl b/media/java/android/media/session/ISessionCallback.aidl
index 2f6e260..a146c62 100644
--- a/media/java/android/media/session/ISessionCallback.aidl
+++ b/media/java/android/media/session/ISessionCallback.aidl
@@ -16,6 +16,7 @@
package android.media.session;
import android.content.Intent;
+import android.media.MediaDescription;
import android.media.Rating;
import android.net.Uri;
import android.os.Bundle;
@@ -49,6 +50,10 @@
void onRepeatMode(int repeatMode);
void onShuffleMode(boolean enabled);
void onCustomAction(String action, in Bundle args);
+ void onAddQueueItem(in MediaDescription description);
+ void onAddQueueItemAt(in MediaDescription description, int index);
+ void onRemoveQueueItem(in MediaDescription description);
+ void onRemoveQueueItemAt(int index);
// These callbacks are for volume handling
void onAdjustVolume(int direction);
diff --git a/media/java/android/media/session/ISessionController.aidl b/media/java/android/media/session/ISessionController.aidl
index e92758c..7b5233a 100644
--- a/media/java/android/media/session/ISessionController.aidl
+++ b/media/java/android/media/session/ISessionController.aidl
@@ -18,6 +18,7 @@
import android.app.PendingIntent;
import android.content.Intent;
import android.content.pm.ParceledListSlice;
+import android.media.MediaDescription;
import android.media.MediaMetadata;
import android.media.Rating;
import android.media.session.ISessionControllerCallback;
@@ -51,6 +52,11 @@
MediaMetadata getMetadata();
PlaybackState getPlaybackState();
ParceledListSlice getQueue();
+ void addQueueItem(in MediaDescription description);
+ void addQueueItemAt(in MediaDescription description, int index);
+ void removeQueueItem(in MediaDescription description);
+ void removeQueueItemAt(int index);
+
CharSequence getQueueTitle();
Bundle getExtras();
int getRatingType();
diff --git a/media/java/android/media/session/MediaController.java b/media/java/android/media/session/MediaController.java
index 8cbf8e1..bab2af2 100644
--- a/media/java/android/media/session/MediaController.java
+++ b/media/java/android/media/session/MediaController.java
@@ -23,6 +23,7 @@
import android.content.pm.ParceledListSlice;
import android.media.AudioAttributes;
import android.media.AudioManager;
+import android.media.MediaDescription;
import android.media.MediaMetadata;
import android.media.Rating;
import android.media.VolumeProvider;
@@ -38,6 +39,7 @@
import android.view.KeyEvent;
import java.lang.ref.WeakReference;
+import java.lang.UnsupportedOperationException;
import java.util.ArrayList;
import java.util.List;
@@ -111,8 +113,7 @@
}
/**
- * Get a {@link TransportControls} instance to send transport actions to
- * the associated session.
+ * Get a {@link TransportControls} instance to send transport actions to this session.
*
* @return A transport controls instance.
*/
@@ -151,7 +152,7 @@
try {
return mSessionBinder.getPlaybackState();
} catch (RemoteException e) {
- Log.wtf(TAG, "Error calling getPlaybackState.", e);
+ Log.wtf(TAG, "Error calling getPlaybackState", e);
return null;
}
}
@@ -165,7 +166,7 @@
try {
return mSessionBinder.getMetadata();
} catch (RemoteException e) {
- Log.wtf(TAG, "Error calling getMetadata.", e);
+ Log.wtf(TAG, "Error calling getMetadata", e);
return null;
}
}
@@ -183,12 +184,103 @@
return queue.getList();
}
} catch (RemoteException e) {
- Log.wtf(TAG, "Error calling getQueue.", e);
+ Log.wtf(TAG, "Error calling getQueue", e);
}
return null;
}
/**
+ * Add a queue item from the given {@code description} at the end of the play queue
+ * of this session. Not all sessions may support this.
+ *
+ * @param description The {@link MediaDescription} for creating the
+ * {@link MediaSession.QueueItem} to be inserted.
+ * @throws UnsupportedOperationException If this session doesn't support this.
+ * @see MediaSession#FLAG_HANDLES_QUEUE_COMMANDS
+ */
+ public void addQueueItem(MediaDescription description) {
+ try {
+ long flags = mSessionBinder.getFlags();
+ if ((flags & MediaSession.FLAG_HANDLES_QUEUE_COMMANDS) == 0) {
+ throw new UnsupportedOperationException(
+ "This session doesn't support queue management operations");
+ }
+ mSessionBinder.addQueueItem(description);
+ } catch (RemoteException e) {
+ Log.wtf(TAG, "Error calling addQueueItem", e);
+ }
+ }
+
+ /**
+ * Add a queue item from the given {@code description} at the specified position
+ * in the play queue of this session. Shifts the queue item currently at that position
+ * (if any) and any subsequent queue items to the right (adds one to their indices).
+ * Not all sessions may support this.
+ *
+ * @param description The {@link MediaDescription} for creating the
+ * {@link MediaSession.QueueItem} to be inserted.
+ * @param index The index at which the created {@link MediaSession.QueueItem} is to be inserted.
+ * @throws UnsupportedOperationException If this session doesn't support this.
+ * @see MediaSession#FLAG_HANDLES_QUEUE_COMMANDS
+ */
+ public void addQueueItem(MediaDescription description, int index) {
+ try {
+ long flags = mSessionBinder.getFlags();
+ if ((flags & MediaSession.FLAG_HANDLES_QUEUE_COMMANDS) == 0) {
+ throw new UnsupportedOperationException(
+ "This session doesn't support queue management operations");
+ }
+ mSessionBinder.addQueueItemAt(description, index);
+ } catch (RemoteException e) {
+ Log.wtf(TAG, "Error calling addQueueItemAt", e);
+ }
+ }
+
+ /**
+ * Remove the first occurrence of the specified {@link MediaSession.QueueItem}
+ * with the given {@link MediaDescription description} in the play queue of the associated
+ * session. Not all sessions may support this.
+ *
+ * @param description The {@link MediaDescription} for denoting the
+ * {@link MediaSession.QueueItem} to be removed.
+ * @throws UnsupportedOperationException If this session doesn't support this.
+ * @see MediaSession#FLAG_HANDLES_QUEUE_COMMANDS
+ */
+ public void removeQueueItem(MediaDescription description) {
+ try {
+ long flags = mSessionBinder.getFlags();
+ if ((flags & MediaSession.FLAG_HANDLES_QUEUE_COMMANDS) == 0) {
+ throw new UnsupportedOperationException(
+ "This session doesn't support queue management operations");
+ }
+ mSessionBinder.removeQueueItem(description);
+ } catch (RemoteException e) {
+ Log.wtf(TAG, "Error calling removeQueueItem", e);
+ }
+ }
+
+ /**
+ * Remove an queue item at the specified position in the play queue
+ * of this session. Not all sessions may support this.
+ *
+ * @param index The index of the element to be removed.
+ * @throws UnsupportedOperationException If this session doesn't support this.
+ * @see MediaSession#FLAG_HANDLES_QUEUE_COMMANDS
+ */
+ public void removeQueueItemAt(int index) {
+ try {
+ long flags = mSessionBinder.getFlags();
+ if ((flags & MediaSession.FLAG_HANDLES_QUEUE_COMMANDS) == 0) {
+ throw new UnsupportedOperationException(
+ "This session doesn't support queue management operations");
+ }
+ mSessionBinder.removeQueueItemAt(index);
+ } catch (RemoteException e) {
+ Log.wtf(TAG, "Error calling removeQueueItemAt", e);
+ }
+ }
+
+ /**
* Get the queue title for this session.
*/
public @Nullable CharSequence getQueueTitle() {
@@ -230,7 +322,7 @@
try {
return mSessionBinder.getRatingType();
} catch (RemoteException e) {
- Log.wtf(TAG, "Error calling getRatingType.", e);
+ Log.wtf(TAG, "Error calling getRatingType", e);
return Rating.RATING_NONE;
}
}
@@ -245,7 +337,7 @@
try {
return mSessionBinder.getRepeatMode();
} catch (RemoteException e) {
- Log.wtf(TAG, "Error calling getRepeatMode.", e);
+ Log.wtf(TAG, "Error calling getRepeatMode", e);
return PlaybackState.REPEAT_MODE_NONE;
}
}
@@ -259,7 +351,7 @@
try {
return mSessionBinder.isShuffleModeEnabled();
} catch (RemoteException e) {
- Log.wtf(TAG, "Error calling isShuffleModeEnabled.", e);
+ Log.wtf(TAG, "Error calling isShuffleModeEnabled", e);
return false;
}
}
@@ -273,7 +365,7 @@
try {
return mSessionBinder.getFlags();
} catch (RemoteException e) {
- Log.wtf(TAG, "Error calling getFlags.", e);
+ Log.wtf(TAG, "Error calling getFlags", e);
}
return 0;
}
@@ -290,7 +382,7 @@
result.maxVolume, result.currentVolume);
} catch (RemoteException e) {
- Log.wtf(TAG, "Error calling getAudioInfo.", e);
+ Log.wtf(TAG, "Error calling getAudioInfo", e);
}
return null;
}
@@ -305,7 +397,7 @@
try {
return mSessionBinder.getLaunchPendingIntent();
} catch (RemoteException e) {
- Log.wtf(TAG, "Error calling getPendingIntent.", e);
+ Log.wtf(TAG, "Error calling getPendingIntent", e);
}
return null;
}
@@ -334,7 +426,7 @@
try {
mSessionBinder.setVolumeTo(value, flags, mContext.getPackageName());
} catch (RemoteException e) {
- Log.wtf(TAG, "Error calling setVolumeTo.", e);
+ Log.wtf(TAG, "Error calling setVolumeTo", e);
}
}
@@ -355,7 +447,7 @@
try {
mSessionBinder.adjustVolume(direction, flags, mContext.getPackageName());
} catch (RemoteException e) {
- Log.wtf(TAG, "Error calling adjustVolumeBy.", e);
+ Log.wtf(TAG, "Error calling adjustVolumeBy", e);
}
}
@@ -421,7 +513,7 @@
try {
mSessionBinder.sendCommand(command, args, cb);
} catch (RemoteException e) {
- Log.d(TAG, "Dead object in sendCommand.", e);
+ Log.d(TAG, "Dead object in sendCommand", e);
}
}
@@ -435,7 +527,7 @@
try {
mPackageName = mSessionBinder.getPackageName();
} catch (RemoteException e) {
- Log.d(TAG, "Dead object in getPackageName.", e);
+ Log.d(TAG, "Dead object in getPackageName", e);
}
}
return mPackageName;
@@ -452,7 +544,7 @@
try {
mTag = mSessionBinder.getTag();
} catch (RemoteException e) {
- Log.d(TAG, "Dead object in getTag.", e);
+ Log.d(TAG, "Dead object in getTag", e);
}
}
return mTag;
@@ -652,7 +744,7 @@
try {
mSessionBinder.prepare();
} catch (RemoteException e) {
- Log.wtf(TAG, "Error calling prepare.", e);
+ Log.wtf(TAG, "Error calling prepare", e);
}
}
@@ -671,12 +763,12 @@
public void prepareFromMediaId(String mediaId, Bundle extras) {
if (TextUtils.isEmpty(mediaId)) {
throw new IllegalArgumentException(
- "You must specify a non-empty String for prepareFromMediaId.");
+ "You must specify a non-empty String for prepareFromMediaId");
}
try {
mSessionBinder.prepareFromMediaId(mediaId, extras);
} catch (RemoteException e) {
- Log.wtf(TAG, "Error calling prepare(" + mediaId + ").", e);
+ Log.wtf(TAG, "Error calling prepare(" + mediaId + ")", e);
}
}
@@ -702,7 +794,7 @@
try {
mSessionBinder.prepareFromSearch(query, extras);
} catch (RemoteException e) {
- Log.wtf(TAG, "Error calling prepare(" + query + ").", e);
+ Log.wtf(TAG, "Error calling prepare(" + query + ")", e);
}
}
@@ -721,12 +813,12 @@
public void prepareFromUri(Uri uri, Bundle extras) {
if (uri == null || Uri.EMPTY.equals(uri)) {
throw new IllegalArgumentException(
- "You must specify a non-empty Uri for prepareFromUri.");
+ "You must specify a non-empty Uri for prepareFromUri");
}
try {
mSessionBinder.prepareFromUri(uri, extras);
} catch (RemoteException e) {
- Log.wtf(TAG, "Error calling prepare(" + uri + ").", e);
+ Log.wtf(TAG, "Error calling prepare(" + uri + ")", e);
}
}
@@ -737,7 +829,7 @@
try {
mSessionBinder.play();
} catch (RemoteException e) {
- Log.wtf(TAG, "Error calling play.", e);
+ Log.wtf(TAG, "Error calling play", e);
}
}
@@ -751,12 +843,12 @@
public void playFromMediaId(String mediaId, Bundle extras) {
if (TextUtils.isEmpty(mediaId)) {
throw new IllegalArgumentException(
- "You must specify a non-empty String for playFromMediaId.");
+ "You must specify a non-empty String for playFromMediaId");
}
try {
mSessionBinder.playFromMediaId(mediaId, extras);
} catch (RemoteException e) {
- Log.wtf(TAG, "Error calling play(" + mediaId + ").", e);
+ Log.wtf(TAG, "Error calling play(" + mediaId + ")", e);
}
}
@@ -778,7 +870,7 @@
try {
mSessionBinder.playFromSearch(query, extras);
} catch (RemoteException e) {
- Log.wtf(TAG, "Error calling play(" + query + ").", e);
+ Log.wtf(TAG, "Error calling play(" + query + ")", e);
}
}
@@ -792,12 +884,12 @@
public void playFromUri(Uri uri, Bundle extras) {
if (uri == null || Uri.EMPTY.equals(uri)) {
throw new IllegalArgumentException(
- "You must specify a non-empty Uri for playFromUri.");
+ "You must specify a non-empty Uri for playFromUri");
}
try {
mSessionBinder.playFromUri(uri, extras);
} catch (RemoteException e) {
- Log.wtf(TAG, "Error calling play(" + uri + ").", e);
+ Log.wtf(TAG, "Error calling play(" + uri + ")", e);
}
}
@@ -809,7 +901,7 @@
try {
mSessionBinder.skipToQueueItem(id);
} catch (RemoteException e) {
- Log.wtf(TAG, "Error calling skipToItem(" + id + ").", e);
+ Log.wtf(TAG, "Error calling skipToItem(" + id + ")", e);
}
}
@@ -821,7 +913,7 @@
try {
mSessionBinder.pause();
} catch (RemoteException e) {
- Log.wtf(TAG, "Error calling pause.", e);
+ Log.wtf(TAG, "Error calling pause", e);
}
}
@@ -833,7 +925,7 @@
try {
mSessionBinder.stop();
} catch (RemoteException e) {
- Log.wtf(TAG, "Error calling stop.", e);
+ Log.wtf(TAG, "Error calling stop", e);
}
}
@@ -846,7 +938,7 @@
try {
mSessionBinder.seekTo(pos);
} catch (RemoteException e) {
- Log.wtf(TAG, "Error calling seekTo.", e);
+ Log.wtf(TAG, "Error calling seekTo", e);
}
}
@@ -858,7 +950,7 @@
try {
mSessionBinder.fastForward();
} catch (RemoteException e) {
- Log.wtf(TAG, "Error calling fastForward.", e);
+ Log.wtf(TAG, "Error calling fastForward", e);
}
}
@@ -869,7 +961,7 @@
try {
mSessionBinder.next();
} catch (RemoteException e) {
- Log.wtf(TAG, "Error calling next.", e);
+ Log.wtf(TAG, "Error calling next", e);
}
}
@@ -881,7 +973,7 @@
try {
mSessionBinder.rewind();
} catch (RemoteException e) {
- Log.wtf(TAG, "Error calling rewind.", e);
+ Log.wtf(TAG, "Error calling rewind", e);
}
}
@@ -892,7 +984,7 @@
try {
mSessionBinder.previous();
} catch (RemoteException e) {
- Log.wtf(TAG, "Error calling previous.", e);
+ Log.wtf(TAG, "Error calling previous", e);
}
}
@@ -907,7 +999,7 @@
try {
mSessionBinder.rate(rating);
} catch (RemoteException e) {
- Log.wtf(TAG, "Error calling rate.", e);
+ Log.wtf(TAG, "Error calling rate", e);
}
}
@@ -923,7 +1015,7 @@
try {
mSessionBinder.repeatMode(repeatMode);
} catch (RemoteException e) {
- Log.wtf(TAG, "Error calling setRepeatMode.", e);
+ Log.wtf(TAG, "Error calling setRepeatMode", e);
}
}
@@ -936,7 +1028,7 @@
try {
mSessionBinder.shuffleMode(enabled);
} catch (RemoteException e) {
- Log.wtf(TAG, "Error calling shuffleMode.", e);
+ Log.wtf(TAG, "Error calling shuffleMode", e);
}
}
@@ -950,7 +1042,7 @@
public void sendCustomAction(@NonNull PlaybackState.CustomAction customAction,
@Nullable Bundle args) {
if (customAction == null) {
- throw new IllegalArgumentException("CustomAction cannot be null.");
+ throw new IllegalArgumentException("CustomAction cannot be null");
}
sendCustomAction(customAction.getAction(), args);
}
@@ -966,12 +1058,12 @@
*/
public void sendCustomAction(@NonNull String action, @Nullable Bundle args) {
if (TextUtils.isEmpty(action)) {
- throw new IllegalArgumentException("CustomAction cannot be null.");
+ throw new IllegalArgumentException("CustomAction cannot be null");
}
try {
mSessionBinder.sendCustomAction(action, args);
} catch (RemoteException e) {
- Log.d(TAG, "Dead object in sendCustomAction.", e);
+ Log.d(TAG, "Dead object in sendCustomAction", e);
}
}
}
diff --git a/media/java/android/media/session/MediaSession.java b/media/java/android/media/session/MediaSession.java
index 84dc93a..bee3f52 100644
--- a/media/java/android/media/session/MediaSession.java
+++ b/media/java/android/media/session/MediaSession.java
@@ -87,6 +87,12 @@
public static final int FLAG_HANDLES_TRANSPORT_CONTROLS = 1 << 1;
/**
+ * Set this flag on the session to indicate that it handles queue
+ * management commands through its {@link Callback}.
+ */
+ public static final int FLAG_HANDLES_QUEUE_COMMANDS = 1 << 2;
+
+ /**
* System only flag for a session that needs to have priority over all other
* sessions. This flag ensures this session will receive media button events
* regardless of the current ordering in the system.
@@ -100,6 +106,7 @@
@IntDef(flag = true, value = {
FLAG_HANDLES_MEDIA_BUTTONS,
FLAG_HANDLES_TRANSPORT_CONTROLS,
+ FLAG_HANDLES_QUEUE_COMMANDS,
FLAG_EXCLUSIVE_GLOBAL_PRIORITY })
public @interface SessionFlags { }
@@ -645,6 +652,22 @@
postToCallback(CallbackMessageHandler.MSG_CUSTOM_ACTION, action, args);
}
+ private void dispatchAddQueueItem(MediaDescription description) {
+ postToCallback(CallbackMessageHandler.MSG_ADD_QUEUE_ITEM, description);
+ }
+
+ private void dispatchAddQueueItem(MediaDescription description, int index) {
+ postToCallback(CallbackMessageHandler.MSG_ADD_QUEUE_ITEM_AT, description, index);
+ }
+
+ private void dispatchRemoveQueueItem(MediaDescription description) {
+ postToCallback(CallbackMessageHandler.MSG_REMOVE_QUEUE_ITEM, description);
+ }
+
+ private void dispatchRemoveQueueItemAt(int index) {
+ postToCallback(CallbackMessageHandler.MSG_REMOVE_QUEUE_ITEM_AT, index);
+ }
+
private void dispatchMediaButton(Intent mediaButtonIntent) {
postToCallback(CallbackMessageHandler.MSG_MEDIA_BUTTON, mediaButtonIntent);
}
@@ -666,10 +689,22 @@
postToCallback(CallbackMessageHandler.MSG_COMMAND, cmd);
}
+ private void postToCallback(int what, int arg1) {
+ postToCallback(what, null, arg1);
+ }
+
private void postToCallback(int what, Object obj) {
postToCallback(what, obj, null);
}
+ private void postToCallback(int what, Object obj, int arg1) {
+ synchronized (mLock) {
+ if (mCallback != null) {
+ mCallback.post(what, obj, arg1);
+ }
+ }
+ }
+
private void postToCallback(int what, Object obj, Bundle extras) {
synchronized (mLock) {
if (mCallback != null) {
@@ -1043,6 +1078,47 @@
*/
public void onCustomAction(@NonNull String action, @Nullable Bundle extras) {
}
+
+ /**
+ * Called when a {@link MediaController} wants to add a {@link QueueItem} with the given
+ * {@link MediaDescription description} at the end of the play queue.
+ *
+ * @param description The {@link MediaDescription} for creating the {@link QueueItem} to be
+ * inserted.
+ */
+ public void onAddQueueItem(MediaDescription description) {
+ }
+
+ /**
+ * Called when a {@link MediaController} wants to add a {@link QueueItem} with the given
+ * {@link MediaDescription description} at the specified position in the play queue.
+ *
+ * @param description The {@link MediaDescription} for creating the {@link QueueItem} to be
+ * inserted.
+ * @param index The index at which the created {@link QueueItem} is to be inserted.
+ */
+ public void onAddQueueItem(MediaDescription description, int index) {
+ }
+
+ /**
+ * Called when a {@link MediaController} wants to remove the first occurrence of the
+ * specified {@link QueueItem} with the given {@link MediaDescription description}
+ * in the play queue.
+ *
+ * @param description The {@link MediaDescription} for denoting the {@link QueueItem} to be
+ * removed.
+ */
+ public void onRemoveQueueItem(MediaDescription description) {
+ }
+
+ /**
+ * Called when a {@link MediaController} wants to remove a {@link QueueItem} at the
+ * specified position in the play queue.
+ *
+ * @param index The index of the element to be removed.
+ */
+ public void onRemoveQueueItemAt(int index) {
+ }
}
/**
@@ -1239,6 +1315,38 @@
}
@Override
+ public void onAddQueueItem(MediaDescription description) {
+ MediaSession session = mMediaSession.get();
+ if (session != null) {
+ session.dispatchAddQueueItem(description);
+ }
+ }
+
+ @Override
+ public void onAddQueueItemAt(MediaDescription description, int index) {
+ MediaSession session = mMediaSession.get();
+ if (session != null) {
+ session.dispatchAddQueueItem(description, index);
+ }
+ }
+
+ @Override
+ public void onRemoveQueueItem(MediaDescription description) {
+ MediaSession session = mMediaSession.get();
+ if (session != null) {
+ session.dispatchRemoveQueueItem(description);
+ }
+ }
+
+ @Override
+ public void onRemoveQueueItemAt(int index) {
+ MediaSession session = mMediaSession.get();
+ if (session != null) {
+ session.dispatchRemoveQueueItemAt(index);
+ }
+ }
+
+ @Override
public void onAdjustVolume(int direction) {
MediaSession session = mMediaSession.get();
if (session != null) {
@@ -1376,6 +1484,10 @@
private static final int MSG_CUSTOM_ACTION = 22;
private static final int MSG_ADJUST_VOLUME = 23;
private static final int MSG_SET_VOLUME = 24;
+ private static final int MSG_ADD_QUEUE_ITEM = 25;
+ private static final int MSG_ADD_QUEUE_ITEM_AT = 26;
+ private static final int MSG_REMOVE_QUEUE_ITEM = 27;
+ private static final int MSG_REMOVE_QUEUE_ITEM_AT = 28;
private MediaSession.Callback mCallback;
@@ -1465,7 +1577,7 @@
mCallback.onSetRating((Rating) msg.obj);
break;
case MSG_REPEAT_MODE:
- mCallback.onSetRepeatMode((int) msg.obj);
+ mCallback.onSetRepeatMode(msg.arg1);
break;
case MSG_SHUFFLE_MODE:
mCallback.onSetShuffleModeEnabled((boolean) msg.obj);
@@ -1473,12 +1585,24 @@
case MSG_CUSTOM_ACTION:
mCallback.onCustomAction((String) msg.obj, msg.getData());
break;
+ case MSG_ADD_QUEUE_ITEM:
+ mCallback.onAddQueueItem((MediaDescription) msg.obj);
+ break;
+ case MSG_ADD_QUEUE_ITEM_AT:
+ mCallback.onAddQueueItem((MediaDescription) msg.obj, msg.arg1);
+ break;
+ case MSG_REMOVE_QUEUE_ITEM:
+ mCallback.onRemoveQueueItem((MediaDescription) msg.obj);
+ break;
+ case MSG_REMOVE_QUEUE_ITEM_AT:
+ mCallback.onRemoveQueueItemAt(msg.arg1);
+ break;
case MSG_ADJUST_VOLUME:
synchronized (mLock) {
vp = mVolumeProvider;
}
if (vp != null) {
- vp.onAdjustVolume((int) msg.obj);
+ vp.onAdjustVolume(msg.arg1);
}
break;
case MSG_SET_VOLUME:
@@ -1486,7 +1610,7 @@
vp = mVolumeProvider;
}
if (vp != null) {
- vp.onSetVolumeTo((int) msg.obj);
+ vp.onSetVolumeTo(msg.arg1);
}
break;
}
diff --git a/media/java/android/media/tv/TvContract.java b/media/java/android/media/tv/TvContract.java
index 9a08fbe..b0df0e4 100644
--- a/media/java/android/media/tv/TvContract.java
+++ b/media/java/android/media/tv/TvContract.java
@@ -18,6 +18,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.StringDef;
import android.annotation.SystemApi;
import android.content.ComponentName;
import android.content.ContentResolver;
@@ -29,6 +30,8 @@
import android.text.TextUtils;
import android.util.ArraySet;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -372,6 +375,37 @@
/** The MIME type of a single TV channel. */
public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/channel";
+ /** @hide */
+ @StringDef({
+ TYPE_OTHER,
+ TYPE_NTSC,
+ TYPE_PAL,
+ TYPE_SECAM,
+ TYPE_DVB_T,
+ TYPE_DVB_T2,
+ TYPE_DVB_S,
+ TYPE_DVB_S2,
+ TYPE_DVB_C,
+ TYPE_DVB_C2,
+ TYPE_DVB_H,
+ TYPE_DVB_SH,
+ TYPE_ATSC_T,
+ TYPE_ATSC_C,
+ TYPE_ATSC_M_H,
+ TYPE_ISDB_T,
+ TYPE_ISDB_TB,
+ TYPE_ISDB_S,
+ TYPE_ISDB_C,
+ TYPE_1SEG,
+ TYPE_DTMB,
+ TYPE_CMMB,
+ TYPE_T_DMB,
+ TYPE_S_DMB,
+ TYPE_PREVIEW,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface Type {}
+
/**
* A generic channel type.
*
@@ -554,6 +588,15 @@
*/
public static final String TYPE_PREVIEW = "TYPE_PREVIEW";
+ /** @hide */
+ @StringDef({
+ SERVICE_TYPE_OTHER,
+ SERVICE_TYPE_AUDIO_VIDEO,
+ SERVICE_TYPE_AUDIO,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface ServiceType {}
+
/** A generic service type. */
public static final String SERVICE_TYPE_OTHER = "SERVICE_TYPE_OTHER";
@@ -563,6 +606,22 @@
/** The service type for radio channels that have audio only. */
public static final String SERVICE_TYPE_AUDIO = "SERVICE_TYPE_AUDIO";
+ /** @hide */
+ @StringDef({
+ VIDEO_FORMAT_240P,
+ VIDEO_FORMAT_360P,
+ VIDEO_FORMAT_480I,
+ VIDEO_FORMAT_576I,
+ VIDEO_FORMAT_576P,
+ VIDEO_FORMAT_720P,
+ VIDEO_FORMAT_1080I,
+ VIDEO_FORMAT_1080P,
+ VIDEO_FORMAT_2160P,
+ VIDEO_FORMAT_4320P,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface VideoFormat {}
+
/** The video format for 240p. */
public static final String VIDEO_FORMAT_240P = "VIDEO_FORMAT_240P";
@@ -596,6 +655,17 @@
/** The video format for 4320p. */
public static final String VIDEO_FORMAT_4320P = "VIDEO_FORMAT_4320P";
+ /** @hide */
+ @StringDef({
+ VIDEO_RESOLUTION_SD,
+ VIDEO_RESOLUTION_ED,
+ VIDEO_RESOLUTION_HD,
+ VIDEO_RESOLUTION_FHD,
+ VIDEO_RESOLUTION_UHD,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface VideoResolution {}
+
/** The video resolution for standard-definition. */
public static final String VIDEO_RESOLUTION_SD = "VIDEO_RESOLUTION_SD";
@@ -634,7 +704,7 @@
* @see #COLUMN_VIDEO_FORMAT
*/
@Nullable
- public static final String getVideoResolution(String videoFormat) {
+ public static final String getVideoResolution(@VideoFormat String videoFormat) {
return VIDEO_FORMAT_TO_RESOLUTION_MAP.get(videoFormat);
}
@@ -1026,6 +1096,19 @@
@SystemApi
public static final String COLUMN_TRANSIENT = "transient";
+ /**
+ * The flag indicating whether this TV channel is approved to be shown by the system.
+ *
+ * <p>A value of 1 indicates that the channel is approved to be shown by the system, and a
+ * value of 0 indicates that the channel is blocked by system. If not specified, this value
+ * is set to 0 (not approved) by default.
+ *
+ * <p>Type: INTEGER (boolean)
+ * @hide
+ */
+ @SystemApi
+ public static final String COLUMN_SYSTEM_APPROVED = "system_approved";
+
private Channels() {}
/**
@@ -1087,6 +1170,24 @@
/** The MIME type of a single TV program. */
public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/program";
+ /** @hide */
+ @StringDef({
+ TYPE_MOVIE,
+ TYPE_TV_SERIES,
+ TYPE_TV_SEASON,
+ TYPE_TV_EPISODE,
+ TYPE_CLIP,
+ TYPE_EVENT,
+ TYPE_CHANNEL,
+ TYPE_TRACK,
+ TYPE_ALBUM,
+ TYPE_ARTIST,
+ TYPE_PLAYLIST,
+ TYPE_STATION,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface Type {}
+
/**
* The program type for movie.
*
@@ -1171,6 +1272,15 @@
*/
public static final String TYPE_STATION = "TYPE_STATION";
+ /** @hide */
+ @StringDef({
+ WATCH_NEXT_TYPE_CONTINUE,
+ WATCH_NEXT_TYPE_NEXT,
+ WATCH_NEXT_TYPE_NEW,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface WatchNextType {}
+
/**
* The watch next type for CONTINUE.
*
@@ -1192,6 +1302,16 @@
*/
public static final String WATCH_NEXT_TYPE_NEW = "WATCH_NEXT_TYPE_NEW";
+ /** @hide */
+ @StringDef({
+ ASPECT_RATIO_16_9,
+ ASPECT_RATIO_3_2,
+ ASPECT_RATIO_1_1,
+ ASPECT_RATIO_2_3,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface AspectRatio {}
+
/**
* The aspect ratio for 16:9.
*
@@ -1224,6 +1344,15 @@
*/
public static final String ASPECT_RATIO_2_3 = "ASPECT_RATIO_2_3";
+ /** @hide */
+ @StringDef({
+ AVAILABILITY_AVAILABLE,
+ AVAILABILITY_FREE_WITH_SUBSCRIPTION,
+ AVAILABILITY_PAID_CONTENT,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface Availability {}
+
/**
* The availability for "available to this user".
*
@@ -1247,6 +1376,19 @@
*/
public static final String AVAILABILITY_PAID_CONTENT = "AVAILABILITY_PAID_CONTENT";
+ /** @hide */
+ @StringDef({
+ INTERACTION_TYPE_LISTENS,
+ INTERACTION_TYPE_FOLLOWERS,
+ INTERACTION_TYPE_FANS,
+ INTERACTION_TYPE_LIKES,
+ INTERACTION_TYPE_THUMBS,
+ INTERACTION_TYPE_VIEWS,
+ INTERACTION_TYPE_VIEWERS,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface InteractionType {}
+
/**
* The interaction type for "listens".
*
@@ -1296,6 +1438,15 @@
*/
public static final String INTERACTION_TYPE_VIEWERS = "INTERACTION_TYPE_VIEWERS";
+ /** @hide */
+ @StringDef({
+ REVIEW_RATING_STYLE_STARS,
+ REVIEW_RATING_STYLE_THUMBS_UP_DOWN,
+ REVIEW_RATING_STYLE_PERCENTAGE,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface ReviewRatingStyle {}
+
/**
* The review rating style for five star rating.
*
@@ -1665,7 +1816,7 @@
*
* <p>Type: TEXT
*/
- public static final String COLUMN_LOGO = "logo";
+ public static final String COLUMN_LOGO_URI = "logo_uri";
/**
* The availability of this TV program.
@@ -1860,8 +2011,8 @@
*
* <p>Type: INTEGER
*/
- public static final String COLUMN_PREVIEW_LAST_PLAYBACK_POSITION =
- "preview_last_playback_position";
+ public static final String COLUMN_LAST_PLAYBACK_POSITION_MILLIS =
+ "last_playback_position_millis";
/**
* The duration (in milliseconds) of the preview video.
@@ -1872,7 +2023,7 @@
*
* <p>Type: INTEGER
*/
- public static final String COLUMN_PREVIEW_DURATION = "preview_duration";
+ public static final String COLUMN_DURATION_MILLIS = "duration_millis";
/**
* The intent URI which is launched when the preview video is selected.
@@ -1885,8 +2036,8 @@
*
* <p>Type: TEXT
*/
- public static final String COLUMN_PREVIEW_INTENT_URI =
- "preview_intent_uri";
+ public static final String COLUMN_APP_LINK_INTENT_URI =
+ "app_link_intent_uri";
/**
* The weight of the preview program within the channel.
@@ -1900,7 +2051,7 @@
*
* <p>Type: INTEGER
*/
- public static final String COLUMN_PREVIEW_WEIGHT = "preview_weight";
+ public static final String COLUMN_WEIGHT = "weight";
/**
* The flag indicating whether this program is transient or not.
@@ -1981,6 +2132,29 @@
/** Canonical genres for TV programs. */
public static final class Genres {
+ /** @hide */
+ @StringDef({
+ FAMILY_KIDS,
+ SPORTS,
+ SHOPPING,
+ MOVIES,
+ COMEDY,
+ TRAVEL,
+ DRAMA,
+ EDUCATION,
+ ANIMAL_WILDLIFE,
+ NEWS,
+ GAMING,
+ ARTS,
+ ENTERTAINMENT,
+ LIFE_STYLE,
+ MUSIC,
+ PREMIER,
+ TECH_SCIENCE,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface Genre {}
+
/** The genre for Family/Kids. */
public static final String FAMILY_KIDS = "FAMILY_KIDS";
@@ -2068,7 +2242,7 @@
* @return an encoded genre string that can be inserted into the
* {@link #COLUMN_BROADCAST_GENRE} or {@link #COLUMN_CANONICAL_GENRE} column.
*/
- public static String encode(@NonNull String... genres) {
+ public static String encode(@NonNull @Genre String... genres) {
if (genres == null) {
// MNC and before will throw a NPE.
return null;
@@ -2107,7 +2281,7 @@
* {@link #COLUMN_BROADCAST_GENRE} or {@link #COLUMN_CANONICAL_GENRE} column.
* @return genre strings.
*/
- public static String[] decode(@NonNull String genres) {
+ public static @Genre String[] decode(@NonNull String genres) {
if (TextUtils.isEmpty(genres)) {
// MNC and before will throw a NPE for {@code null} genres.
return EMPTY_STRING_ARRAY;
diff --git a/native/android/Android.mk b/native/android/Android.mk
index 355f52e..f510b48 100644
--- a/native/android/Android.mk
+++ b/native/android/Android.mk
@@ -1,6 +1,8 @@
BASE_PATH := $(call my-dir)
LOCAL_PATH:= $(call my-dir)
+common_cflags := -Wall -Werror -Wunused -Wunreachable-code
+
include $(CLEAR_VARS)
# our source files
@@ -43,6 +45,23 @@
LOCAL_MODULE := libandroid
-LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code
+LOCAL_CFLAGS += $(common_cflags)
+
+include $(BUILD_SHARED_LIBRARY)
+
+# Network library.
+include $(CLEAR_VARS)
+LOCAL_MODULE := libandroid_net
+LOCAL_CFLAGS := $(common_cflags)
+LOCAL_SRC_FILES:= \
+ net.c \
+
+LOCAL_SHARED_LIBRARIES := \
+ libnetd_client \
+
+LOCAL_C_INCLUDES += \
+ frameworks/base/native/include \
+ bionic/libc/dns/include \
+ system/netd/include \
include $(BUILD_SHARED_LIBRARY)
diff --git a/opengl/java/android/opengl/GLU.java b/opengl/java/android/opengl/GLU.java
index ed64556..ef9bf167 100644
--- a/opengl/java/android/opengl/GLU.java
+++ b/opengl/java/android/opengl/GLU.java
@@ -203,8 +203,8 @@
* @param view the current view, {x, y, width, height}
* @param viewOffset the offset into the view array where the view vector
* data starts.
- * @param obj the output vector {objX, objY, objZ}, that returns the
- * computed object coordinates.
+ * @param obj the output vector {objX, objY, objZ, objW}, that returns the
+ * computed homogeneous object coordinates.
* @param objOffset the offset into the obj array where the obj vector data
* starts.
* @return A return value of GL10.GL_TRUE indicates success, a return value
diff --git a/packages/CompanionDeviceManager/Android.mk b/packages/CompanionDeviceManager/Android.mk
new file mode 100644
index 0000000..f730356
--- /dev/null
+++ b/packages/CompanionDeviceManager/Android.mk
@@ -0,0 +1,27 @@
+# Copyright (C) 2017 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := CompanionDeviceManager
+
+include $(BUILD_PACKAGE)
+
+include $(call all-makefiles-under, $(LOCAL_PATH))
diff --git a/packages/CompanionDeviceManager/AndroidManifest.xml b/packages/CompanionDeviceManager/AndroidManifest.xml
new file mode 100644
index 0000000..3eede54
--- /dev/null
+++ b/packages/CompanionDeviceManager/AndroidManifest.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (c) 2017 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.companiondevicemanager">
+
+ <permission
+ android:name="com.android.companiondevicemanager.permission.BIND"
+ android:protectionLevel="signature" />
+
+ <uses-permission android:name="android.permission.BLUETOOTH"/>
+ <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
+ <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
+
+ <application
+ android:allowClearUserData="true"
+ android:label="@string/app_label"
+ android:allowBackup="false"
+ android:supportsRtl="true">
+
+ <service
+ android:name=".DeviceDiscoveryService"
+ android:permission="android.permission.BIND_COMPANION_DEVICE_MANAGER_SERVICE"
+ android:exported="true">
+ </service>
+
+ <activity
+ android:name=".DeviceChooserActivity"
+ android:theme="@*android:style/Theme.Dialog.NoFrame"
+ android:permission="android.permission.BIND_COMPANION_DEVICE_MANAGER_SERVICE">
+ <!--TODO include url scheme filter similar to PrintSpooler -->
+ <intent-filter>
+ <action android:name="android.companiondevice.START_DISCOVERY" />
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ </activity>
+
+ </application>
+
+</manifest>
diff --git a/packages/CompanionDeviceManager/MODULE_LICENSE_APACHE2 b/packages/CompanionDeviceManager/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/packages/CompanionDeviceManager/MODULE_LICENSE_APACHE2
diff --git a/packages/CompanionDeviceManager/NOTICE b/packages/CompanionDeviceManager/NOTICE
new file mode 100644
index 0000000..c5b1efa
--- /dev/null
+++ b/packages/CompanionDeviceManager/NOTICE
@@ -0,0 +1,190 @@
+
+ Copyright (c) 2005-2008, 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.
+
+ 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.
+
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
diff --git a/packages/CompanionDeviceManager/res/layout/device_chooser.xml b/packages/CompanionDeviceManager/res/layout/device_chooser.xml
new file mode 100644
index 0000000..ee08582
--- /dev/null
+++ b/packages/CompanionDeviceManager/res/layout/device_chooser.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<RelativeLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_weight="0.1"
+ >
+
+ <TextView
+ android:id="@+id/title"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textColor="@android:color/black"
+ style="@*android:style/TextAppearance.Widget.Toolbar.Title"
+ />
+
+ <ListView
+ android:id="@+id/device_list"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_below="@+id/title"
+ android:layout_above="@+id/buttons"
+ style="@android:style/Widget.Material.Light.ListView"
+ />
+
+ <LinearLayout
+ android:id="@+id/buttons"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:layout_alignParentBottom="true"
+ android:layout_alignParentEnd="true"
+ android:gravity="end"
+ >
+ <Button
+ android:id="@+id/button_cancel"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Cancel"
+ style="@android:style/Widget.Material.Light.Button.Borderless.Colored"
+ />
+ <Button
+ android:id="@+id/button_pair"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Pair"
+ style="@android:style/Widget.Material.Light.Button.Borderless.Colored"
+ />
+ </LinearLayout>
+
+</RelativeLayout>
\ No newline at end of file
diff --git a/packages/CompanionDeviceManager/res/values/dimens.xml b/packages/CompanionDeviceManager/res/values/dimens.xml
new file mode 100644
index 0000000..da7b0d1
--- /dev/null
+++ b/packages/CompanionDeviceManager/res/values/dimens.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+ <!-- Padding applied on most UI elements -->
+ <dimen name="padding">12dp</dimen>
+
+</resources>
\ No newline at end of file
diff --git a/packages/CompanionDeviceManager/res/values/strings.xml b/packages/CompanionDeviceManager/res/values/strings.xml
new file mode 100644
index 0000000..c4195b50
--- /dev/null
+++ b/packages/CompanionDeviceManager/res/values/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+ <!-- Title of the CompanionDeviceManager application. [CHAR LIMIT=50] -->
+ <string name="app_label">Companion Device Manager</string>
+
+ <!-- Title of the device selection dialog. -->
+ <string name="chooser_title">Pair with <strong><xliff:g id="app_name" example="Android Wear">%1$s</xliff:g></strong> via Bluetooth?</string>
+
+</resources>
diff --git a/core/res/res/values-ldrtl/dimens.xml b/packages/CompanionDeviceManager/res/values/themes.xml
similarity index 62%
copy from core/res/res/values-ldrtl/dimens.xml
copy to packages/CompanionDeviceManager/res/values/themes.xml
index 807c042..465f8fc 100644
--- a/core/res/res/values-ldrtl/dimens.xml
+++ b/packages/CompanionDeviceManager/res/values/themes.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
+<!-- Copyright (C) 2017 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -15,6 +15,11 @@
-->
<resources>
- <item type="dimen" format="integer" name="time_picker_column_start_material">1</item>
- <item type="dimen" format="integer" name="time_picker_column_end_material">0</item>
+
+ <!--TODO-->
+ <!--<style name="Theme.ChooserActivity" parent="@*android:style/Theme.Dialog.NoFrame">-->
+ <!--<!–<item name="android:windowBackground">@android:color/light_grey</item>–>-->
+ <!--<item name="android:backgroundColor">@android:color/light_grey</item>-->
+ <!--</style>-->
+
</resources>
diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceChooserActivity.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceChooserActivity.java
new file mode 100644
index 0000000..c95f940
--- /dev/null
+++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceChooserActivity.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.companiondevicemanager;
+
+import android.app.Activity;
+import android.bluetooth.BluetoothDevice;
+import android.companion.CompanionDeviceManager;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
+import android.database.DataSetObserver;
+import android.graphics.Color;
+import android.os.Bundle;
+import android.text.Html;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.View;
+import android.widget.ListView;
+import android.widget.ProgressBar;
+import android.widget.TextView;
+import android.widget.Toast;
+
+public class DeviceChooserActivity extends Activity {
+
+ private static final boolean DEBUG = false;
+ private static final String LOG_TAG = "DeviceChooserActivity";
+
+ private ListView mDeviceListView;
+ private View mPairButton;
+ private View mCancelButton;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ if (DEBUG) Log.i(LOG_TAG, "Started with intent " + getIntent());
+
+ setContentView(R.layout.device_chooser);
+ setTitle(Html.fromHtml(getString(R.string.chooser_title, getCallingAppName()), 0));
+ getWindow().getDecorView().getRootView().setBackgroundColor(Color.LTGRAY); //TODO theme
+
+ if (getService().mDevicesFound.isEmpty()) {
+ Log.e(LOG_TAG, "About to show UI, but no devices to show");
+ }
+
+ final DeviceDiscoveryService.DevicesAdapter adapter = getService().mDevicesAdapter;
+ mDeviceListView = (ListView) findViewById(R.id.device_list);
+ mDeviceListView.setAdapter(adapter);
+ mDeviceListView.addFooterView(getProgressBar(), null, false);
+
+ mPairButton = findViewById(R.id.button_pair);
+ mPairButton.setOnClickListener((view) ->
+ onPairTapped(getService().mSelectedDevice));
+ adapter.registerDataSetObserver(new DataSetObserver() {
+ @Override
+ public void onChanged() {
+ updatePairButtonEnabled();
+ }
+ });
+ updatePairButtonEnabled();
+ mCancelButton = findViewById(R.id.button_cancel);
+ mCancelButton.setOnClickListener((view) -> {
+ setResult(RESULT_CANCELED);
+ finish();
+ });
+ }
+
+ private CharSequence getCallingAppName() {
+ try {
+ final PackageManager packageManager = getPackageManager();
+ return packageManager.getApplicationLabel(
+ packageManager.getApplicationInfo(getService().mCallingPackage, 0));
+ } catch (PackageManager.NameNotFoundException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public void setTitle(CharSequence title) {
+ final TextView titleView = (TextView) findViewById(R.id.title);
+ final int padding = getPadding(getResources());
+ titleView.setPadding(padding, padding, padding, padding);
+ titleView.setText(title);
+ }
+
+ //TODO put in resources xmls
+ private ProgressBar getProgressBar() {
+ final ProgressBar progressBar = new ProgressBar(this);
+ progressBar.setForegroundGravity(Gravity.CENTER_HORIZONTAL);
+ final int padding = getPadding(getResources());
+ progressBar.setPadding(padding, padding, padding, padding);
+ return progressBar;
+ }
+
+ static int getPadding(Resources r) {
+ return r.getDimensionPixelSize(R.dimen.padding);
+ //TODO
+// final float dp = r.getDisplayMetrics().density;
+// return (int)(12 * dp);
+ }
+
+ private void updatePairButtonEnabled() {
+ mPairButton.setEnabled(getService().mSelectedDevice != null);
+ }
+
+ private DeviceDiscoveryService getService() {
+ return DeviceDiscoveryService.sInstance;
+ }
+
+ protected void onPairTapped(BluetoothDevice selectedDevice) {
+ setResult(RESULT_OK,
+ new Intent().putExtra(CompanionDeviceManager.EXTRA_DEVICE, selectedDevice));
+ finish();
+ }
+
+ private void toast(String msg) {
+ Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
+ }
+}
\ No newline at end of file
diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java
new file mode 100644
index 0000000..a3eec0d
--- /dev/null
+++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java
@@ -0,0 +1,273 @@
+/*
+ * Copyright (C) 2013 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.companiondevicemanager;
+
+import static android.companion.BluetoothDeviceFilterUtils.getDeviceDisplayName;
+import static android.companion.BluetoothLEDeviceFilter.nullsafe;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.app.PendingIntent;
+import android.app.Service;
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothManager;
+import android.bluetooth.le.BluetoothLeScanner;
+import android.bluetooth.le.ScanCallback;
+import android.bluetooth.le.ScanFilter;
+import android.bluetooth.le.ScanResult;
+import android.bluetooth.le.ScanSettings;
+import android.companion.AssociationRequest;
+import android.companion.BluetoothDeviceFilterUtils;
+import android.companion.BluetoothLEDeviceFilter;
+import android.companion.ICompanionDeviceManagerService;
+import android.companion.IOnAssociateCallback;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.graphics.Color;
+import android.graphics.PorterDuff;
+import android.graphics.drawable.Drawable;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.util.Log;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.TextView;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+public class DeviceDiscoveryService extends Service {
+
+ private static final boolean DEBUG = false;
+ private static final String LOG_TAG = "DeviceDiscoveryService";
+
+ static DeviceDiscoveryService sInstance;
+
+ private BluetoothAdapter mBluetoothAdapter;
+ private BluetoothLEDeviceFilter mFilter;
+ private ScanFilter mScanFilter;
+ private ScanSettings mDefaultScanSettings = new ScanSettings.Builder().build();
+ List<BluetoothDevice> mDevicesFound;
+ BluetoothDevice mSelectedDevice;
+ DevicesAdapter mDevicesAdapter;
+ IOnAssociateCallback mCallback;
+ String mCallingPackage;
+
+ private final ICompanionDeviceManagerService mBinder =
+ new ICompanionDeviceManagerService.Stub() {
+ @Override
+ public void startDiscovery(AssociationRequest request,
+ IOnAssociateCallback callback,
+ String callingPackage) throws RemoteException {
+ if (DEBUG) {
+ Log.i(LOG_TAG,
+ "startDiscovery() called with: filter = [" + request + "], callback = ["
+ + callback + "]");
+ }
+ mCallback = callback;
+ mCallingPackage = callingPackage;
+ DeviceDiscoveryService.this.startDiscovery(request);
+ }
+ };
+
+ private final ScanCallback mBLEScanCallback = new ScanCallback() {
+ @Override
+ public void onScanResult(int callbackType, ScanResult result) {
+ final BluetoothDevice device = result.getDevice();
+ if (callbackType == ScanSettings.CALLBACK_TYPE_MATCH_LOST) {
+ onDeviceLost(device);
+ } else {
+ onDeviceFound(device);
+ }
+ }
+ };
+
+ private BluetoothLeScanner mBLEScanner;
+
+ private BroadcastReceiver mBluetoothDeviceFoundBroadcastReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ final BluetoothDevice device = intent.getParcelableExtra(
+ BluetoothDevice.EXTRA_DEVICE);
+ if (!mFilter.matches(device)) return; // ignore device
+
+ if (intent.getAction().equals(BluetoothDevice.ACTION_FOUND)) {
+ onDeviceFound(device);
+ } else {
+ onDeviceLost(device);
+ }
+ }
+ };
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ if (DEBUG) Log.i(LOG_TAG, "onBind(" + intent + ")");
+ return mBinder.asBinder();
+ }
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+
+ if (DEBUG) Log.i(LOG_TAG, "onCreate()");
+
+ mBluetoothAdapter = getSystemService(BluetoothManager.class).getAdapter();
+ mBLEScanner = mBluetoothAdapter.getBluetoothLeScanner();
+
+ mDevicesFound = new ArrayList<>();
+ mDevicesAdapter = new DevicesAdapter();
+
+ sInstance = this;
+ }
+
+ private void startDiscovery(AssociationRequest<?> request) {
+ //TODO support other protocols as well
+ mFilter = nullsafe((BluetoothLEDeviceFilter) request.getDeviceFilter());
+ mScanFilter = mFilter.getScanFilter();
+
+ reset();
+
+ final IntentFilter intentFilter = new IntentFilter();
+ intentFilter.addAction(BluetoothDevice.ACTION_FOUND);
+ intentFilter.addAction(BluetoothDevice.ACTION_DISAPPEARED);
+
+ registerReceiver(mBluetoothDeviceFoundBroadcastReceiver, intentFilter);
+ mBluetoothAdapter.startDiscovery();
+
+ mBLEScanner.startScan(
+ Collections.singletonList(mScanFilter), mDefaultScanSettings, mBLEScanCallback);
+ }
+
+ private void reset() {
+ mDevicesFound.clear();
+ mSelectedDevice = null;
+ mDevicesAdapter.notifyDataSetChanged();
+ }
+
+ @Override
+ public boolean onUnbind(Intent intent) {
+ stopScan();
+ return super.onUnbind(intent);
+ }
+
+ private void stopScan() {
+ if (DEBUG) Log.i(LOG_TAG, "stopScan() called");
+ mBluetoothAdapter.cancelDiscovery();
+ mBLEScanner.stopScan(mBLEScanCallback);
+ unregisterReceiver(mBluetoothDeviceFoundBroadcastReceiver);
+ stopSelf();
+ }
+
+ private void onDeviceFound(BluetoothDevice device) {
+ if (mDevicesFound.contains(device)) {
+ return;
+ }
+
+ if (DEBUG) {
+ Log.i(LOG_TAG, "Considering device " + getDeviceDisplayName(device));
+ }
+
+ if (!mFilter.matches(device)) {
+ return;
+ }
+
+ if (DEBUG) {
+ Log.i(LOG_TAG, "Found device " + getDeviceDisplayName(device));
+ }
+ if (mDevicesFound.isEmpty()) {
+ onReadyToShowUI();
+ }
+ mDevicesFound.add(device);
+ mDevicesAdapter.notifyDataSetChanged();
+ }
+
+ //TODO also, on timeout -> call onFailure
+ private void onReadyToShowUI() {
+ try {
+ mCallback.onSuccess(PendingIntent.getActivity(
+ this, 0,
+ new Intent(this, DeviceChooserActivity.class),
+ PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_CANCEL_CURRENT
+ | PendingIntent.FLAG_IMMUTABLE));
+ } catch (RemoteException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private void onDeviceLost(BluetoothDevice device) {
+ mDevicesFound.remove(device);
+ mDevicesAdapter.notifyDataSetChanged();
+ if (DEBUG) {
+ Log.i(LOG_TAG, "Lost device " + getDeviceDisplayName(device));
+ }
+ }
+
+ class DevicesAdapter extends ArrayAdapter<BluetoothDevice> {
+ private Drawable BLUETOOTH_ICON = icon(android.R.drawable.stat_sys_data_bluetooth);
+
+ private Drawable icon(int drawableRes) {
+ Drawable icon = getResources().getDrawable(drawableRes, null);
+ icon.setTint(Color.DKGRAY);
+ return icon;
+ }
+
+ public DevicesAdapter() {
+ super(DeviceDiscoveryService.this, 0, mDevicesFound);
+ }
+
+ @Override
+ public View getView(
+ int position,
+ @Nullable View convertView,
+ @NonNull ViewGroup parent) {
+ TextView view = convertView instanceof TextView
+ ? (TextView) convertView
+ : newView();
+ bind(view, getItem(position));
+ return view;
+ }
+
+ private void bind(TextView textView, BluetoothDevice device) {
+ textView.setText(getDeviceDisplayName(device));
+ textView.setBackgroundColor(
+ device.equals(mSelectedDevice)
+ ? Color.GRAY
+ : Color.TRANSPARENT);
+ textView.setOnClickListener((view) -> {
+ mSelectedDevice = device;
+ notifyDataSetChanged();
+ });
+ }
+
+ //TODO move to a layout file
+ private TextView newView() {
+ final TextView textView = new TextView(DeviceDiscoveryService.this);
+ textView.setTextColor(Color.BLACK);
+ final int padding = DeviceChooserActivity.getPadding(getResources());
+ textView.setPadding(padding, padding, padding, padding);
+ textView.setCompoundDrawablesWithIntrinsicBounds(
+ BLUETOOTH_ICON, null, null, null);
+ textView.setCompoundDrawablePadding(padding);
+ return textView;
+ }
+ }
+}
diff --git a/packages/Keyguard/res/values-bn/strings.xml b/packages/Keyguard/res/values-bn/strings.xml
index 1a2a8dd..64c01bb 100644
--- a/packages/Keyguard/res/values-bn/strings.xml
+++ b/packages/Keyguard/res/values-bn/strings.xml
@@ -47,8 +47,8 @@
<string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"সিম কার্ডটি PUK কোড দিয়ে লক করা আছে৷"</string>
<string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"সিম কার্ড আনলক করা হচ্ছে…"</string>
<string name="keyguard_accessibility_pin_area" msgid="7903959476607833485">"পিন অঞ্চল"</string>
- <string name="keyguard_accessibility_sim_pin_area" msgid="3887780775111719336">"SIM পিন অঞ্চল"</string>
- <string name="keyguard_accessibility_sim_puk_area" msgid="1880823406954996207">"SIM PUK অঞ্চল"</string>
+ <string name="keyguard_accessibility_sim_pin_area" msgid="3887780775111719336">"সিম পিন অঞ্চল"</string>
+ <string name="keyguard_accessibility_sim_puk_area" msgid="1880823406954996207">"সিম PUK অঞ্চল"</string>
<string name="keyguard_accessibility_next_alarm" msgid="7269583073750518672">"<xliff:g id="ALARM">%1$s</xliff:g> এ পরবর্তী অ্যালার্ম সেট করা হয়েছে"</string>
<string name="keyboardview_keycode_delete" msgid="3337914833206635744">"মুছুন"</string>
<string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
@@ -59,11 +59,11 @@
<string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"<xliff:g id="NUMBER">%d</xliff:g> সেকেন্ডের মধ্যে আবার চেষ্টা করুন৷"</string>
<string name="kg_pattern_instructions" msgid="398978611683075868">"আপনার প্যাটার্ন আঁকুন"</string>
<string name="kg_sim_pin_instructions" msgid="2319508550934557331">"সিম পিন লিখুন"</string>
- <string name="kg_sim_pin_instructions_multi" msgid="7818515973197201434">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" এর জন্য SIM পিন লিখুন"</string>
+ <string name="kg_sim_pin_instructions_multi" msgid="7818515973197201434">"\"<xliff:g id="CARRIER">%1$s</xliff:g>\" এর জন্য সিম পিন লিখুন"</string>
<string name="kg_pin_instructions" msgid="2377242233495111557">"পিন লিখুন"</string>
<string name="kg_password_instructions" msgid="5753646556186936819">"পাসওয়ার্ড লিখুন"</string>
<string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"সিম এখন অক্ষম করা হয়েছে৷ অবিরত থাকতে PUK কোডটি লিখুন৷ বিশদ বিবরণের জন্য ক্যারিয়ারের সাথে যোগাযোগ করুন৷"</string>
- <string name="kg_puk_enter_puk_hint_multi" msgid="363822494559783025">"SIM \"<xliff:g id="CARRIER">%1$s</xliff:g>\" এখন অক্ষম করা হয়েছে৷ চালিয়ে যেতে PUK কোড লিখুন৷ বিস্তারিত জানার জন্য ক্যারিয়ারের সাথে যোগাযোগ করুন৷"</string>
+ <string name="kg_puk_enter_puk_hint_multi" msgid="363822494559783025">"সিম \"<xliff:g id="CARRIER">%1$s</xliff:g>\" এখন অক্ষম করা হয়েছে৷ চালিয়ে যেতে PUK কোড লিখুন৷ বিস্তারিত জানার জন্য ক্যারিয়ারের সাথে যোগাযোগ করুন৷"</string>
<string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"কাঙ্ক্ষিত পিন কোড লিখুন"</string>
<string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"কাঙ্ক্ষিত পিন কোড নিশ্চিত করুন"</string>
<string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"সিম কার্ড আনলক করা হচ্ছে…"</string>
@@ -91,13 +91,13 @@
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"আপনি আপনার আনলকের প্যাটার্ন আঁকার ক্ষেত্রে <xliff:g id="NUMBER_0">%1$d</xliff:g> বার ভুল করেছেন৷ আর <xliff:g id="NUMBER_1">%2$d</xliff:g> বার অসফল প্রচেষ্টা করা হলে আপনাকে একটি ইমেল অ্যাকাউন্ট মারফত আপনার ফোন আনলক করতে বলা হবে৷\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> সেকেন্ডের মধ্যে আবার চেষ্টা করুন৷"</string>
<string name="kg_password_wrong_pin_code_pukked" msgid="30531039455764924">"ভুল সিম পিন কোড, আপনার ডিভাইসটি আনলক করতে এখন আপনাকে অবশ্যই আপনার ক্যারিয়ারের সাথে যোগাযোগ করতে হবে৷"</string>
<plurals name="kg_password_wrong_pin_code" formatted="false" msgid="6721575017538162249">
- <item quantity="one">ভুল SIM পিন কোড, আপনার কাছে আর <xliff:g id="NUMBER_1">%d</xliff:g>টি প্রচেষ্টা বাকি রয়েছে৷</item>
- <item quantity="other">ভুল SIM পিন কোড, আপনার কাছে আর <xliff:g id="NUMBER_1">%d</xliff:g>টি প্রচেষ্টা বাকি রয়েছে৷</item>
+ <item quantity="one">ভুল সিম পিন কোড, আপনার কাছে আর <xliff:g id="NUMBER_1">%d</xliff:g>টি প্রচেষ্টা বাকি রয়েছে৷</item>
+ <item quantity="other">ভুল সিম পিন কোড, আপনার কাছে আর <xliff:g id="NUMBER_1">%d</xliff:g>টি প্রচেষ্টা বাকি রয়েছে৷</item>
</plurals>
<string name="kg_password_wrong_puk_code_dead" msgid="7077536808291316208">"SIMটি ব্যবহারের অযোগ্য৷ আপনার ক্যারিয়ারের সাথে যোগাযোগ করুন৷"</string>
<plurals name="kg_password_wrong_puk_code" formatted="false" msgid="7576227366999858780">
- <item quantity="one">ভুল SIM PUK কোড, আপনার কাছে আর <xliff:g id="NUMBER_1">%d</xliff:g>টি প্রচেষ্টা বাকি রয়েছে এটির পরেই আপনার SIM স্থায়ীভাবে অব্যবহারযোগ্য হবে৷</item>
- <item quantity="other">ভুল SIM PUK কোড, আপনার কাছে আর <xliff:g id="NUMBER_1">%d</xliff:g>টি প্রচেষ্টা বাকি রয়েছে এটির পরেই আপনার SIM স্থায়ীভাবে অব্যবহারযোগ্য হবে৷</item>
+ <item quantity="one">ভুল সিম PUK কোড, আপনার কাছে আর <xliff:g id="NUMBER_1">%d</xliff:g>টি প্রচেষ্টা বাকি রয়েছে এটির পরেই আপনার সিম স্থায়ীভাবে অব্যবহারযোগ্য হবে৷</item>
+ <item quantity="other">ভুল সিম PUK কোড, আপনার কাছে আর <xliff:g id="NUMBER_1">%d</xliff:g>টি প্রচেষ্টা বাকি রয়েছে এটির পরেই আপনার সিম স্থায়ীভাবে অব্যবহারযোগ্য হবে৷</item>
</plurals>
<string name="kg_password_pin_failed" msgid="6268288093558031564">"সিম পিন ক্রিয়াকলাপটি ব্যর্থ হয়েছে!"</string>
<string name="kg_password_puk_failed" msgid="2838824369502455984">"সিম PUK ক্রিয়াকলাপটি ব্যর্থ হয়েছে!"</string>
diff --git a/packages/Keyguard/res/values-da/strings.xml b/packages/Keyguard/res/values-da/strings.xml
index b98a253..0fb7416 100644
--- a/packages/Keyguard/res/values-da/strings.xml
+++ b/packages/Keyguard/res/values-da/strings.xml
@@ -58,7 +58,7 @@
<string name="kg_wrong_pin" msgid="1131306510833563801">"Forkert pinkode"</string>
<string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Prøv igen om <xliff:g id="NUMBER">%d</xliff:g> sekunder."</string>
<string name="kg_pattern_instructions" msgid="398978611683075868">"Tegn dit mønster"</string>
- <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Indtast pinkode til SIM"</string>
+ <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Indtast pinkode til SIM-kort"</string>
<string name="kg_sim_pin_instructions_multi" msgid="7818515973197201434">"Indtast SIM-pinkoden for \"<xliff:g id="CARRIER">%1$s</xliff:g>\""</string>
<string name="kg_pin_instructions" msgid="2377242233495111557">"Indtast pinkode"</string>
<string name="kg_password_instructions" msgid="5753646556186936819">"Angiv adgangskode"</string>
@@ -105,13 +105,13 @@
<string name="keyguard_carrier_default" msgid="8700650403054042153">"Ingen dækning."</string>
<string name="accessibility_ime_switch_button" msgid="2829803408288433429">"Skift indtastningsmetode"</string>
<string name="airplane_mode" msgid="3122107900897202805">"Flytilstand"</string>
- <string name="kg_prompt_reason_restart_pattern" msgid="5519822969283306009">"Du skal indtaste et mønster efter genstart af enheden"</string>
+ <string name="kg_prompt_reason_restart_pattern" msgid="5519822969283306009">"Du skal angive et mønster efter genstart af enheden"</string>
<string name="kg_prompt_reason_restart_pin" msgid="4411398237158448198">"Der skal indtaste en pinkode efter genstart af enheden"</string>
<string name="kg_prompt_reason_restart_password" msgid="6504585392626524695">"Du skal indtaste en adgangskode efter genstart af enheden"</string>
<string name="kg_prompt_reason_timeout_pattern" msgid="3717506169674397620">"Der kræves et mønster som ekstra beskyttelse"</string>
<string name="kg_prompt_reason_timeout_pin" msgid="6951483704195396341">"Der kræves en pinkode som ekstra beskyttelse"</string>
<string name="kg_prompt_reason_timeout_password" msgid="7306667546971345027">"Der kræves en adgangskode som ekstra beskyttelse"</string>
- <string name="kg_prompt_reason_switch_profiles_pattern" msgid="8476293962695171574">"Du skal indtaste et mønster, når du skifter profil"</string>
+ <string name="kg_prompt_reason_switch_profiles_pattern" msgid="8476293962695171574">"Du skal angive et mønster, når du skifter profil"</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="2343607138520460043">"Du skal indtaste en pinkode, når du skifter profil"</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="1295960907951965927">"Du skal indtaste en adgangskode, når du skifter profil"</string>
<string name="kg_prompt_reason_device_admin" msgid="5838877342219587193">"Enhedsadministratoren har låst enheden"</string>
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java
index 8b0e610..b8c10a6 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java
@@ -509,7 +509,7 @@
final DeviceToolkit toolkit =
new DeviceToolkit(mMtpManager, mResolver, mDatabase, device);
mDeviceToolkits.put(deviceId, toolkit);
- mIntentSender.sendUpdateNotificationIntent();
+ mIntentSender.sendUpdateNotificationIntent(device);
try {
mRootScanner.resume().await();
} catch (InterruptedException error) {
@@ -526,7 +526,7 @@
closeDeviceInternal(deviceId);
}
mRootScanner.resume();
- mIntentSender.sendUpdateNotificationIntent();
+ mIntentSender.sendUpdateNotificationIntent(null);
}
MtpDeviceRecord[] getOpenedDeviceRecordsCache() {
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsService.java b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsService.java
index c8846ce..664d3c9 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsService.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsService.java
@@ -19,13 +19,12 @@
import android.app.Notification;
import android.app.Service;
import android.app.NotificationManager;
-import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
-import android.util.Log;
-
-import java.io.IOException;
+import android.service.notification.StatusBarNotification;
+import java.util.HashSet;
+import java.util.Set;
/**
* Service to manage lifetime of DocumentsProvider's process.
@@ -33,12 +32,10 @@
* starts to run when the first MTP device is opened, and stops when the last MTP device is closed.
*/
public class MtpDocumentsService extends Service {
- static final String ACTION_OPEN_DEVICE = "com.android.mtp.OPEN_DEVICE";
- static final String ACTION_CLOSE_DEVICE = "com.android.mtp.CLOSE_DEVICE";
static final String ACTION_UPDATE_NOTIFICATION = "com.android.mtp.UPDATE_NOTIFICATION";
static final String EXTRA_DEVICE = "device";
- NotificationManager mNotificationManager;
+ private NotificationManager mNotificationManager;
@Override
public IBinder onBind(Intent intent) {
@@ -67,39 +64,53 @@
*/
private boolean updateForegroundState() {
final MtpDocumentsProvider provider = MtpDocumentsProvider.getInstance();
- int notificationId = 0;
- Notification notification = null;
- // TODO: Hide notification if the device has already been removed.
+ final Set<Integer> openedNotification = new HashSet<>();
+ boolean hasForegroundNotification = false;
+
+ final StatusBarNotification[] activeNotifications =
+ mNotificationManager.getActiveNotifications();
+
for (final MtpDeviceRecord record : provider.getOpenedDeviceRecordsCache()) {
- final String title = getResources().getString(
- R.string.accessing_notification_title,
- record.name);
- notificationId = record.deviceId;
- notification = new Notification.Builder(this)
- .setLocalOnly(true)
- .setContentTitle(title)
- .setSmallIcon(com.android.internal.R.drawable.stat_sys_data_usb)
- .setCategory(Notification.CATEGORY_SYSTEM)
- .setPriority(Notification.PRIORITY_LOW)
- .build();
- mNotificationManager.notify(record.deviceId, notification);
+ openedNotification.add(record.deviceId);
+ if (!hasForegroundNotification) {
+ // Mark this service as foreground with the notification so that the process is not
+ // killed by the system while a MTP device is opened.
+ startForeground(record.deviceId, createNotification(this, record));
+ hasForegroundNotification = true;
+ } else {
+ // Only one notification can be shown as a foreground notification. We need to show
+ // the rest as normal notification.
+ mNotificationManager.notify(record.deviceId, createNotification(this, record));
+ }
}
- if (notification != null) {
- startForeground(notificationId, notification);
- return true;
- } else {
+ for (final StatusBarNotification notification : activeNotifications) {
+ if (!openedNotification.contains(notification.getId())) {
+ mNotificationManager.cancel(notification.getId());
+ }
+ }
+
+ if (!hasForegroundNotification) {
+ // There is no opened device.
stopForeground(true /* removeNotification */);
stopSelf();
return false;
}
+
+ return true;
}
- private static void logErrorMessage(Exception exp) {
- if (exp.getMessage() != null) {
- Log.e(MtpDocumentsProvider.TAG, exp.getMessage());
- } else {
- Log.e(MtpDocumentsProvider.TAG, exp.toString());
- }
+ public static Notification createNotification(Context context, MtpDeviceRecord device) {
+ final String title = context.getResources().getString(
+ R.string.accessing_notification_title,
+ device.name);
+ return new Notification.Builder(context)
+ .setLocalOnly(true)
+ .setContentTitle(title)
+ .setSmallIcon(com.android.internal.R.drawable.stat_sys_data_usb)
+ .setCategory(Notification.CATEGORY_SYSTEM)
+ .setPriority(Notification.PRIORITY_LOW)
+ .setFlag(Notification.FLAG_NO_CLEAR, true)
+ .build();
}
}
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/ServiceIntentSender.java b/packages/MtpDocumentsProvider/src/com/android/mtp/ServiceIntentSender.java
index a1bb2c1..d8c3d35 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/ServiceIntentSender.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/ServiceIntentSender.java
@@ -16,6 +16,8 @@
package com.android.mtp;
+import android.annotation.Nullable;
+import android.app.NotificationManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -30,9 +32,22 @@
mContext = context;
}
- void sendUpdateNotificationIntent() {
+ /**
+ * Notify the change of opened device set.
+ * @param record If a new device is opened, pass the device record. If a device is closed, pass
+ * null.
+ */
+ void sendUpdateNotificationIntent(@Nullable MtpDeviceRecord record) {
final Intent intent = new Intent(MtpDocumentsService.ACTION_UPDATE_NOTIFICATION);
intent.setComponent(new ComponentName(mContext, MtpDocumentsService.class));
- mContext.startService(intent);
+ final NotificationManager manager = mContext.getSystemService(NotificationManager.class);
+ if (record != null) {
+ manager.startServiceInForeground(
+ intent,
+ record.deviceId,
+ MtpDocumentsService.createNotification(mContext, record));
+ } else {
+ mContext.startService(intent);
+ }
}
}
diff --git a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestServiceIntentSender.java b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestServiceIntentSender.java
index d4a4a48..74dd429 100644
--- a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestServiceIntentSender.java
+++ b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestServiceIntentSender.java
@@ -16,11 +16,13 @@
package com.android.mtp;
+import android.annotation.Nullable;
+
class TestServiceIntentSender extends ServiceIntentSender {
TestServiceIntentSender() {
super(null);
}
@Override
- void sendUpdateNotificationIntent() {}
+ void sendUpdateNotificationIntent(@Nullable MtpDeviceRecord record) {}
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/SuggestionParser.java b/packages/SettingsLib/src/com/android/settingslib/SuggestionParser.java
index 13bbc33..4b0ab59 100644
--- a/packages/SettingsLib/src/com/android/settingslib/SuggestionParser.java
+++ b/packages/SettingsLib/src/com/android/settingslib/SuggestionParser.java
@@ -94,16 +94,27 @@
private static final long MILLIS_IN_DAY = 24 * 60 * 60 * 1000;
+ // Default dismiss control for smart suggestions.
+ private static final String DEFAULT_SMART_DISMISS_CONTROL = "0,10";
+
private final Context mContext;
private final List<SuggestionCategory> mSuggestionList;
private final ArrayMap<Pair<String, String>, Tile> mAddCache = new ArrayMap<>();
private final SharedPreferences mSharedPrefs;
+ private final String mSmartDismissControl;
- public SuggestionParser(Context context, SharedPreferences sharedPrefs, int orderXml) {
+
+ public SuggestionParser(
+ Context context, SharedPreferences sharedPrefs, int orderXml, String smartDismissControl) {
mContext = context;
mSuggestionList = (List<SuggestionCategory>) new SuggestionOrderInflater(mContext)
.parse(orderXml);
mSharedPrefs = sharedPrefs;
+ mSmartDismissControl = smartDismissControl;
+ }
+
+ public SuggestionParser(Context context, SharedPreferences sharedPrefs, int orderXml) {
+ this(context, sharedPrefs, orderXml, DEFAULT_SMART_DISMISS_CONTROL);
}
@VisibleForTesting
@@ -111,26 +122,35 @@
mContext = context;
mSuggestionList = new ArrayList<SuggestionCategory>();
mSharedPrefs = sharedPrefs;
+ mSmartDismissControl = DEFAULT_SMART_DISMISS_CONTROL;
Log.wtf(TAG, "Only use this constructor for testing");
}
public List<Tile> getSuggestions() {
+ return getSuggestions(false);
+ }
+
+ public List<Tile> getSuggestions(boolean isSmartSuggestionEnabled) {
List<Tile> suggestions = new ArrayList<>();
final int N = mSuggestionList.size();
for (int i = 0; i < N; i++) {
- readSuggestions(mSuggestionList.get(i), suggestions);
+ readSuggestions(mSuggestionList.get(i), suggestions, isSmartSuggestionEnabled);
}
return suggestions;
}
+ public boolean dismissSuggestion(Tile suggestion) {
+ return dismissSuggestion(suggestion, false);
+ }
+
/**
* Dismisses a suggestion, returns true if the suggestion has no more dismisses left and should
* be disabled.
*/
- public boolean dismissSuggestion(Tile suggestion) {
+ public boolean dismissSuggestion(Tile suggestion, boolean isSmartSuggestionEnabled) {
String keyBase = suggestion.intent.getComponent().flattenToShortString();
int index = mSharedPrefs.getInt(keyBase + DISMISS_INDEX, 0);
- String dismissControl = suggestion.metaData.getString(META_DATA_DISMISS_CONTROL);
+ String dismissControl = getDismissControl(suggestion, isSmartSuggestionEnabled);
if (dismissControl == null || parseDismissString(dismissControl).length == index) {
return true;
}
@@ -141,20 +161,23 @@
}
@VisibleForTesting
- public void filterSuggestions(List<Tile> suggestions, int countBefore) {
+ public void filterSuggestions(
+ List<Tile> suggestions, int countBefore, boolean isSmartSuggestionEnabled) {
for (int i = countBefore; i < suggestions.size(); i++) {
if (!isAvailable(suggestions.get(i)) ||
!isSupported(suggestions.get(i)) ||
!satisifesRequiredUserType(suggestions.get(i)) ||
!satisfiesRequiredAccount(suggestions.get(i)) ||
!satisfiesConnectivity(suggestions.get(i)) ||
- isDismissed(suggestions.get(i))) {
+ isDismissed(suggestions.get(i), isSmartSuggestionEnabled)) {
suggestions.remove(i--);
}
}
}
- private void readSuggestions(SuggestionCategory category, List<Tile> suggestions) {
+ @VisibleForTesting
+ void readSuggestions(
+ SuggestionCategory category, List<Tile> suggestions, boolean isSmartSuggestionEnabled) {
int countBefore = suggestions.size();
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(category.category);
@@ -163,7 +186,7 @@
}
TileUtils.getTilesForIntent(mContext, new UserHandle(UserHandle.myUserId()), intent,
mAddCache, null, suggestions, true, false);
- filterSuggestions(suggestions, countBefore);
+ filterSuggestions(suggestions, countBefore, isSmartSuggestionEnabled);
if (!category.multiple && suggestions.size() > (countBefore + 1)) {
// If there are too many, remove them all and only re-add the one with the highest
// priority.
@@ -288,12 +311,11 @@
Settings.Secure.putInt(mContext.getContentResolver(), name, 1);
}
- private boolean isDismissed(Tile suggestion) {
- Object dismissObj = suggestion.metaData.get(META_DATA_DISMISS_CONTROL);
- if (dismissObj == null) {
+ private boolean isDismissed(Tile suggestion, boolean isSmartSuggestionEnabled) {
+ String dismissControl = getDismissControl(suggestion, isSmartSuggestionEnabled);
+ if (dismissControl == null) {
return false;
}
- String dismissControl = String.valueOf(dismissObj);
String keyBase = suggestion.intent.getComponent().flattenToShortString();
if (!mSharedPrefs.contains(keyBase + SETUP_TIME)) {
mSharedPrefs.edit()
@@ -333,7 +355,16 @@
return dismisses;
}
- private static class SuggestionCategory {
+ private String getDismissControl(Tile suggestion, boolean isSmartSuggestionEnabled) {
+ if (isSmartSuggestionEnabled) {
+ return mSmartDismissControl;
+ } else {
+ return suggestion.metaData.getString(META_DATA_DISMISS_CONTROL);
+ }
+ }
+
+ @VisibleForTesting
+ static class SuggestionCategory {
public String category;
public String pkg;
public boolean multiple;
diff --git a/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryKey.java b/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryKey.java
index 7e3f67b..d6bde81 100644
--- a/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryKey.java
+++ b/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryKey.java
@@ -36,7 +36,6 @@
public static final String CATEGORY_SECURITY = "com.android.settings.category.ia.security";
public static final String CATEGORY_ACCOUNT = "com.android.settings.category.ia.accounts";
public static final String CATEGORY_SYSTEM = "com.android.settings.category.ia.system";
- public static final String CATEGORY_SYSTEM_INPUT = "com.android.settings.category.ia.input";
public static final String CATEGORY_SYSTEM_LANGUAGE =
"com.android.settings.category.ia.language";
public static final String CATEGORY_SYSTEM_DEVELOPMENT =
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
index 06ea445..82e69d8 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
@@ -222,21 +222,21 @@
if (isActive() && !other.isActive()) return -1;
if (!isActive() && other.isActive()) return 1;
- // Higher scores go before lower scores
- if (mRankingScore != other.mRankingScore) {
- return (mRankingScore > other.mRankingScore) ? -1 : 1;
- }
-
// Reachable one goes before unreachable one.
if (mRssi != Integer.MAX_VALUE && other.mRssi == Integer.MAX_VALUE) return -1;
if (mRssi == Integer.MAX_VALUE && other.mRssi != Integer.MAX_VALUE) return 1;
- // Configured one goes before unconfigured one.
+ // Configured (saved) one goes before unconfigured one.
if (networkId != WifiConfiguration.INVALID_NETWORK_ID
&& other.networkId == WifiConfiguration.INVALID_NETWORK_ID) return -1;
if (networkId == WifiConfiguration.INVALID_NETWORK_ID
&& other.networkId != WifiConfiguration.INVALID_NETWORK_ID) return 1;
+ // Higher scores go before lower scores
+ if (mRankingScore != other.mRankingScore) {
+ return (mRankingScore > other.mRankingScore) ? -1 : 1;
+ }
+
// Sort by signal strength, bucketed by level
int difference = WifiManager.calculateSignalLevel(other.mRssi, SIGNAL_LEVELS)
- WifiManager.calculateSignalLevel(mRssi, SIGNAL_LEVELS);
diff --git a/packages/SettingsLib/tests/robotests/Android.mk b/packages/SettingsLib/tests/robotests/Android.mk
index 7a89884a..596d614 100644
--- a/packages/SettingsLib/tests/robotests/Android.mk
+++ b/packages/SettingsLib/tests/robotests/Android.mk
@@ -43,6 +43,12 @@
LOCAL_SRC_FILES := \
$(call all-java-files-under, src)
+LOCAL_JAR_EXCLUDE_FILES := none
+
+LOCAL_RESOURCE_DIR := \
+ $(LOCAL_PATH)/res
+
+
include frameworks/base/packages/SettingsLib/common.mk
include $(BUILD_PACKAGE)
diff --git a/packages/SettingsLib/tests/robotests/res/xml/suggestion_ordering.xml b/packages/SettingsLib/tests/robotests/res/xml/suggestion_ordering.xml
new file mode 100644
index 0000000..1eeafba
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/res/xml/suggestion_ordering.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 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.
+-->
+
+<optional-steps>
+ <step category="com.android.settings.suggested.category.LOCK_SCREEN" />
+ <step category="com.android.settings.suggested.category.EMAIL" />
+ <step category="com.android.settings.suggested.category.PARTNER_ACCOUNT"
+ multiple="true" />
+ <step category="com.android.settings.suggested.category.HOTWORD" />
+ <step category="com.android.settings.suggested.category.DEFAULT"
+ multiple="true" />
+ <step category="com.android.settings.suggested.category.SETTINGS_ONLY"
+ multiple="true" />
+</optional-steps>
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/SettingLibRobolectricTestRunner.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/SettingLibRobolectricTestRunner.java
new file mode 100644
index 0000000..11c925e
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/SettingLibRobolectricTestRunner.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.settingslib;
+
+import org.junit.runners.model.InitializationError;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.annotation.Config;
+import org.robolectric.manifest.AndroidManifest;
+import org.robolectric.res.Fs;
+import org.robolectric.res.ResourcePath;
+
+import java.util.List;
+
+public class SettingLibRobolectricTestRunner extends RobolectricTestRunner {
+
+ public SettingLibRobolectricTestRunner(Class<?> testClass) throws InitializationError {
+ super(testClass);
+ }
+
+ @Override
+ protected AndroidManifest getAppManifest(Config config) {
+ // Using the manifest file's relative path, we can figure out the application directory.
+ final String appRoot = "frameworks/base/packages/SettingsLib";
+ final String manifestPath = appRoot + "/AndroidManifest.xml";
+ final String resDir = appRoot + "/tests/robotests/res";
+ final String assetsDir = appRoot + config.assetDir();
+
+ final AndroidManifest manifest = new AndroidManifest(Fs.fileFromPath(manifestPath),
+ Fs.fileFromPath(resDir), Fs.fileFromPath(assetsDir));
+
+ manifest.setPackageName("com.android.settingslib");
+ return manifest;
+ }
+
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/SuggestionParserTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/SuggestionParserTest.java
new file mode 100644
index 0000000..0032cf0
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/SuggestionParserTest.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib;
+
+import android.util.Log;
+import android.content.Context;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.preference.PreferenceManager;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.annotation.Config;
+
+import com.android.settingslib.drawer.Tile;
+import com.android.settingslib.drawer.TileUtilsTest;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import org.robolectric.RuntimeEnvironment;
+
+@RunWith(SettingLibRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class SuggestionParserTest {
+
+ @Mock
+ private PackageManager mPackageManager;
+ private Context mContext;
+ private SuggestionParser mSuggestionParser;
+ private SuggestionParser.SuggestionCategory mSuggestioCategory;
+ private List<Tile> mSuggestionsBeforeDismiss;
+ private List<Tile> mSuggestionsAfterDismiss;
+ private SharedPreferences mPrefs;
+ private Tile mSuggestion;
+ private List<ResolveInfo> mInfo;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mContext = spy(RuntimeEnvironment.application);
+ when(mContext.getPackageManager()).thenReturn(mPackageManager);
+ mPrefs = PreferenceManager.getDefaultSharedPreferences(mContext);
+ mSuggestion = new Tile();
+ mSuggestion.intent = new Intent("action");
+ mSuggestion.intent.setComponent(new ComponentName("pkg", "cls"));
+ mSuggestion.metaData = new Bundle();
+ mSuggestionParser = new SuggestionParser(
+ mContext, mPrefs, R.xml.suggestion_ordering, "0,0");
+ mSuggestioCategory = new SuggestionParser.SuggestionCategory();
+ mSuggestioCategory.category = "category1";
+ mSuggestioCategory.multiple = true;
+ mInfo = new ArrayList<>();
+ ResolveInfo info1 = TileUtilsTest.newInfo(true, "category1");
+ info1.activityInfo.packageName = "pkg";
+ ResolveInfo info2 = TileUtilsTest.newInfo(true, "category1");
+ info2.activityInfo.packageName = "pkg2";
+ mInfo.add(info1);
+ mInfo.add(info2);
+ when(mPackageManager.queryIntentActivitiesAsUser(
+ any(Intent.class), anyInt(), anyInt())).thenReturn(mInfo);
+ }
+
+ @Test
+ public void testDismissSuggestion_withoutSmartSuggestion() {
+ assertThat(mSuggestionParser.dismissSuggestion(mSuggestion, false)).isTrue();
+ }
+
+ @Test
+ public void testDismissSuggestion_withSmartSuggestion() {
+ assertThat(mSuggestionParser.dismissSuggestion(mSuggestion, true)).isFalse();
+ }
+
+ @Test
+ public void testGetSuggestions_withoutSmartSuggestions() {
+ readAndDismissSuggestion(false);
+ mSuggestionParser.readSuggestions(mSuggestioCategory, mSuggestionsAfterDismiss, false);
+ assertThat(mSuggestionsBeforeDismiss.size()).isEqualTo(2);
+ assertThat(mSuggestionsAfterDismiss.size()).isEqualTo(1);
+ assertThat(mSuggestionsBeforeDismiss.get(1)).isEqualTo(mSuggestionsAfterDismiss.get(0));
+ }
+
+ @Test
+ public void testGetSuggestions_withSmartSuggestions() {
+ readAndDismissSuggestion(true);
+ assertThat(mSuggestionsBeforeDismiss.size()).isEqualTo(2);
+ assertThat(mSuggestionsAfterDismiss.size()).isEqualTo(2);
+ assertThat(mSuggestionsBeforeDismiss).isEqualTo(mSuggestionsAfterDismiss);
+ }
+
+ private void readAndDismissSuggestion(boolean isSmartSuggestionEnabled) {
+ mSuggestionsBeforeDismiss = new ArrayList<Tile>();
+ mSuggestionsAfterDismiss = new ArrayList<Tile>();
+ mSuggestionParser.readSuggestions(
+ mSuggestioCategory, mSuggestionsBeforeDismiss, isSmartSuggestionEnabled);
+ if (mSuggestionParser.dismissSuggestion(
+ mSuggestionsBeforeDismiss.get(0), isSmartSuggestionEnabled)) {
+ mInfo.remove(0);
+ }
+ mSuggestionParser.readSuggestions(
+ mSuggestioCategory, mSuggestionsAfterDismiss, isSmartSuggestionEnabled);
+ }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/CategoryKeyTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/CategoryKeyTest.java
index b209f4e..40353e7 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/CategoryKeyTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/CategoryKeyTest.java
@@ -56,12 +56,11 @@
allKeys.add(CategoryKey.CATEGORY_SECURITY);
allKeys.add(CategoryKey.CATEGORY_ACCOUNT);
allKeys.add(CategoryKey.CATEGORY_SYSTEM);
- allKeys.add(CategoryKey.CATEGORY_SYSTEM_INPUT);
allKeys.add(CategoryKey.CATEGORY_SYSTEM_LANGUAGE);
allKeys.add(CategoryKey.CATEGORY_SYSTEM_DEVELOPMENT);
// DO NOT REMOVE ANYTHING ABOVE
- assertThat(allKeys.size()).isEqualTo(14);
+ assertThat(allKeys.size()).isEqualTo(13);
}
}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java
index 021a96c..1683901 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java
@@ -40,6 +40,7 @@
import com.android.settingslib.SuggestionParser;
import com.android.settingslib.TestConfig;
+import com.android.settingslib.drawer.TileUtilsTest;
import static org.mockito.Mockito.atLeastOnce;
import org.junit.Before;
@@ -179,7 +180,7 @@
assertThat(outTiles.size()).isEqualTo(1);
SuggestionParser parser = new SuggestionParser(mContext, null);
- parser.filterSuggestions(outTiles, 0);
+ parser.filterSuggestions(outTiles, 0, false);
assertThat(outTiles.size()).isEqualTo(0);
}
@@ -303,16 +304,16 @@
assertThat(outTiles.get(0).summary).isEqualTo("dynamic-summary");
}
- private ResolveInfo newInfo(boolean systemApp, String category) {
+ public static ResolveInfo newInfo(boolean systemApp, String category) {
return newInfo(systemApp, category, null);
}
- private ResolveInfo newInfo(boolean systemApp, String category, String keyHint) {
+ private static ResolveInfo newInfo(boolean systemApp, String category, String keyHint) {
return newInfo(systemApp, category, keyHint, null, null);
}
- private ResolveInfo newInfo(boolean systemApp, String category, String keyHint, String iconUri,
- String summaryUri) {
+ private static ResolveInfo newInfo(boolean systemApp, String category, String keyHint,
+ String iconUri, String summaryUri) {
ResolveInfo info = new ResolveInfo();
info.system = systemApp;
info.activityInfo = new ActivityInfo();
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index 8bbc8c9..4ddafac 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -1399,9 +1399,6 @@
Settings.Secure.NIGHT_DISPLAY_CUSTOM_END_TIME,
SecureSettingsProto.NIGHT_DISPLAY_CUSTOM_END_TIME);
dumpSetting(s, p,
- Settings.Secure.BRIGHTNESS_USE_TWILIGHT,
- SecureSettingsProto.BRIGHTNESS_USE_TWILIGHT);
- dumpSetting(s, p,
Settings.Secure.ENABLED_VR_LISTENERS,
SecureSettingsProto.ENABLED_VR_LISTENERS);
dumpSetting(s, p,
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginInstanceManager.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginInstanceManager.java
index d71b6bd..dd1614b 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginInstanceManager.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginInstanceManager.java
@@ -51,9 +51,6 @@
private static final String TAG = "PluginInstanceManager";
private static final String PLUGIN_PERMISSION = "com.android.systemui.permission.PLUGIN";
- // must be one of the channels created in NotificationChannels.java
- private static final String NOTIFICATION_CHANNEL_ID = "ALR";
-
private final Context mContext;
private final PluginListener<T> mListener;
private final String mAction;
@@ -310,14 +307,14 @@
mContext.getPackageName());
final int color = Resources.getSystem().getIdentifier(
"system_notification_accent_color", "color", "android");
- final Notification.Builder nb = new Notification.Builder(mContext)
- .setStyle(new Notification.BigTextStyle())
- .setSmallIcon(icon)
- .setWhen(0)
- .setShowWhen(false)
- .setChannel(NOTIFICATION_CHANNEL_ID)
- .setVisibility(Notification.VISIBILITY_PUBLIC)
- .setColor(mContext.getColor(color));
+ final Notification.Builder nb = new Notification.Builder(mContext,
+ PluginManager.NOTIFICATION_CHANNEL_ID)
+ .setStyle(new Notification.BigTextStyle())
+ .setSmallIcon(icon)
+ .setWhen(0)
+ .setShowWhen(false)
+ .setVisibility(Notification.VISIBILITY_PUBLIC)
+ .setColor(mContext.getColor(color));
String label = cls;
try {
label = mPm.getServiceInfo(component, 0).loadLabel(mPm).toString();
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginManager.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginManager.java
index 4714547..cef485e 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginManager.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginManager.java
@@ -55,6 +55,9 @@
static final String DISABLE_PLUGIN = "com.android.systemui.action.DISABLE_PLUGIN";
+ // must be one of the channels created in NotificationChannels.java
+ static final String NOTIFICATION_CHANNEL_ID = "ALR";
+
private static PluginManager sInstance;
private final HandlerThread mBackgroundThread;
@@ -70,7 +73,7 @@
private boolean mListening;
private boolean mHasOneShot;
- private PluginManager(Context context) {
+ public PluginManager(Context context) {
this(context, new PluginInstanceManagerFactory(),
Build.IS_DEBUGGABLE, Thread.getDefaultUncaughtExceptionHandler());
}
@@ -191,15 +194,16 @@
} catch (NameNotFoundException e) {
}
// Localization not required as this will never ever appear in a user build.
- final Notification.Builder nb = new Notification.Builder(mContext)
- .setSmallIcon(icon)
- .setWhen(0)
- .setShowWhen(false)
- .setPriority(Notification.PRIORITY_MAX)
- .setVisibility(Notification.VISIBILITY_PUBLIC)
- .setColor(mContext.getColor(color))
- .setContentTitle("Plugin \"" + label + "\" has updated")
- .setContentText("Restart SysUI for changes to take effect.");
+ final Notification.Builder nb =
+ new Notification.Builder(mContext, NOTIFICATION_CHANNEL_ID)
+ .setSmallIcon(icon)
+ .setWhen(0)
+ .setShowWhen(false)
+ .setPriority(Notification.PRIORITY_MAX)
+ .setVisibility(Notification.VISIBILITY_PUBLIC)
+ .setColor(mContext.getColor(color))
+ .setContentTitle("Plugin \"" + label + "\" has updated")
+ .setContentText("Restart SysUI for changes to take effect.");
Intent i = new Intent("com.android.systemui.action.RESTART").setData(
Uri.parse("package://" + pkg));
PendingIntent pi = PendingIntent.getBroadcast(mContext, 0, i, 0);
@@ -252,13 +256,6 @@
return new PluginContextWrapper(mContext.createApplicationContext(info, 0), classLoader);
}
- public static PluginManager getInstance(Context context) {
- if (sInstance == null) {
- sInstance = new PluginManager(context.getApplicationContext());
- }
- return sInstance;
- }
-
private class AllPluginClassLoader extends ClassLoader {
public AllPluginClassLoader(ClassLoader classLoader) {
super(classLoader);
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/phone/NavGesture.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/phone/NavGesture.java
index 0728482..918d6e9 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/phone/NavGesture.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/phone/NavGesture.java
@@ -32,6 +32,8 @@
public boolean onInterceptTouchEvent(MotionEvent event);
public void setBarState(boolean vertical, boolean isRtl);
+
+ public default void destroy() { }
}
}
diff --git a/packages/SystemUI/proguard.flags b/packages/SystemUI/proguard.flags
index 6d76798..8cc2ce2 100644
--- a/packages/SystemUI/proguard.flags
+++ b/packages/SystemUI/proguard.flags
@@ -38,5 +38,5 @@
-keep class ** extends android.support.v14.preference.PreferenceFragment
-keep class com.android.systemui.tuner.*
-keep class com.android.systemui.plugins.** {
- public protected **;
+ public protected *;
}
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_accessibility_button.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_accessibility_button.png
new file mode 100644
index 0000000..0615668
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_accessibility_button.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_accessibility_button_dark.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_accessibility_button_dark.png
new file mode 100644
index 0000000..839e5ed
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_accessibility_button_dark.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_accessibility_button.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_accessibility_button.png
new file mode 100644
index 0000000..1480c865
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_accessibility_button.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_accessibility_button_dark.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_accessibility_button_dark.png
new file mode 100644
index 0000000..66e11fb
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_accessibility_button_dark.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_accessibility_button.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_accessibility_button.png
new file mode 100644
index 0000000..d2fe0c3
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_accessibility_button.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_accessibility_button_dark.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_accessibility_button_dark.png
new file mode 100644
index 0000000..5923269
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_accessibility_button_dark.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_accessibility_button.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_accessibility_button.png
new file mode 100644
index 0000000..d0196e5
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_accessibility_button.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_accessibility_button_dark.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_accessibility_button_dark.png
new file mode 100644
index 0000000..d3a2b39
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_accessibility_button_dark.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_accessibility_button.png b/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_accessibility_button.png
new file mode 100644
index 0000000..726643c
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_accessibility_button.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_accessibility_button_dark.png b/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_accessibility_button_dark.png
new file mode 100644
index 0000000..31078f6
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_accessibility_button_dark.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable/pip_dismiss_background.xml b/packages/SystemUI/res/drawable/pip_dismiss_background.xml
index 3a75296..8f50231 100644
--- a/packages/SystemUI/res/drawable/pip_dismiss_background.xml
+++ b/packages/SystemUI/res/drawable/pip_dismiss_background.xml
@@ -1,22 +1,22 @@
<!--
-Copyright (C) 2016 The Android Open Source Project
+ Copyright (C) 2017 The Android Open Source Project
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
+ http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- 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.
+ 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.
-->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="oval">
- <corners
- android:radius="100dp" />
- <solid
- android:color="#66000000" />
+ android:shape="rectangle">
+ <gradient
+ android:startColor="#B3000000"
+ android:endColor="#00000000"
+ android:angle="90"/>
</shape>
\ No newline at end of file
diff --git a/core/res/res/values-ldrtl/dimens.xml b/packages/SystemUI/res/layout/divider.xml
similarity index 67%
rename from core/res/res/values-ldrtl/dimens.xml
rename to packages/SystemUI/res/layout/divider.xml
index 807c042..95814371 100644
--- a/core/res/res/values-ldrtl/dimens.xml
+++ b/packages/SystemUI/res/layout/divider.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
+<!-- Copyright (C) 2017 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -13,8 +13,8 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-
-<resources>
- <item type="dimen" format="integer" name="time_picker_column_start_material">1</item>
- <item type="dimen" format="integer" name="time_picker_column_end_material">0</item>
-</resources>
+<View xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="72dp"
+ android:layout_height="1dp"
+ android:background="?android:attr/colorForeground"
+ android:alpha="?android:attr/disabledAlpha" />
diff --git a/packages/SystemUI/res/layout/menu_ime.xml b/packages/SystemUI/res/layout/menu_ime.xml
index 5e85ba0..6bd79a4 100644
--- a/packages/SystemUI/res/layout/menu_ime.xml
+++ b/packages/SystemUI/res/layout/menu_ime.xml
@@ -39,4 +39,13 @@
android:contentDescription="@string/accessibility_ime_switch_button"
android:scaleType="centerInside"
/>
+ <com.android.systemui.statusbar.policy.KeyButtonView
+ android:id="@+id/accessibility_button"
+ android:layout_width="@dimen/navigation_extra_key_width"
+ android:layout_height="match_parent"
+ android:layout_marginEnd="2dp"
+ android:visibility="invisible"
+ android:contentDescription="@string/accessibility_accessibility_button"
+ android:scaleType="centerInside"
+ />
</FrameLayout>
diff --git a/packages/SystemUI/res/layout/pip_dismiss_view.xml b/packages/SystemUI/res/layout/pip_dismiss_view.xml
index 141e610..f02a56c 100644
--- a/packages/SystemUI/res/layout/pip_dismiss_view.xml
+++ b/packages/SystemUI/res/layout/pip_dismiss_view.xml
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2016 The Android Open Source Project
+<!--
+ Copyright (C) 2016 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.
@@ -13,12 +14,44 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<FrameLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/pip_dismiss_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:background="@drawable/pip_dismiss_background"
- android:foreground="@drawable/pip_dismiss"
- android:alpha="0"
- android:forceHasOverlappingRendering="false" />
+ android:alpha="0">
+
+ <!-- The height of the below view needs to be animated from a window
+ so it needs to be in a container to resize smoothly -->
+ <View
+ android:id="@+id/gradient_view"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_gravity="bottom"
+ android:background="@drawable/pip_dismiss_background" />
+
+ <LinearLayout
+ android:id="@+id/pip_dismiss_container"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="bottom|center_horizontal"
+ android:orientation="horizontal"
+ android:paddingBottom="32dp" >
+
+ <ImageView
+ android:id="@+id/pip_dismiss_icon"
+ android:layout_width="24dp"
+ android:layout_height="24dp"
+ android:padding="2dp"
+ android:src="@drawable/pip_dismiss"
+ android:tint="#FFFFFFFF" />
+
+ <TextView
+ android:id="@+id/pip_dismiss_text"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/pip_phone_close"
+ android:textColor="#FFFFFFFF"
+ android:textSize="16sp" />
+ </LinearLayout>
+
+</FrameLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/pip_menu_activity.xml b/packages/SystemUI/res/layout/pip_menu_activity.xml
index cf65f4a..0f5ca9b 100644
--- a/packages/SystemUI/res/layout/pip_menu_activity.xml
+++ b/packages/SystemUI/res/layout/pip_menu_activity.xml
@@ -27,7 +27,7 @@
android:layout_height="48dp"
android:layout_gravity="top|end"
android:padding="10dp"
- android:contentDescription="@string/pip_phone_dismiss"
+ android:contentDescription="@string/pip_phone_close"
android:src="@drawable/ic_close_white"
android:background="?android:selectableItemBackgroundBorderless" />
diff --git a/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml b/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml
index 174776c..3e8e72a 100644
--- a/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml
+++ b/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml
@@ -2,23 +2,22 @@
<!--
** Copyright 2012, 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
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
**
-** http://www.apache.org/licenses/LICENSE-2.0
+** http://www.apache.org/licenses/LICENSE-2.0
**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
+** 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.
-->
<!-- Extends RelativeLayout -->
<com.android.systemui.statusbar.phone.QuickStatusBarHeader
xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:systemui="http://schemas.android.com/apk/res-auto"
android:id="@+id/header"
android:layout_width="match_parent"
android:layout_height="@dimen/status_bar_header_height"
@@ -29,8 +28,7 @@
android:clipToPadding="false"
android:paddingTop="0dp"
android:paddingEnd="0dp"
- android:paddingStart="0dp"
- >
+ android:paddingStart="0dp">
<LinearLayout
android:layout_width="wrap_content"
@@ -190,8 +188,7 @@
android:layout_alignParentBottom="true"
android:alpha="0"
android:background="@color/qs_detail_progress_track"
- android:src="@drawable/indeterminate_anim"
- />
+ android:src="@drawable/indeterminate_anim"/>
<TextView
android:id="@+id/header_debug_info"
@@ -203,7 +200,6 @@
android:textColor="#00A040"
android:textSize="11dp"
android:textStyle="bold"
- android:visibility="invisible"
- />
+ android:visibility="invisible"/>
</com.android.systemui.statusbar.phone.QuickStatusBarHeader>
diff --git a/packages/SystemUI/res/layout/status_bar_expanded.xml b/packages/SystemUI/res/layout/status_bar_expanded.xml
index f09657f..0852020 100644
--- a/packages/SystemUI/res/layout/status_bar_expanded.xml
+++ b/packages/SystemUI/res/layout/status_bar_expanded.xml
@@ -3,28 +3,27 @@
**
** Copyright 2006, 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
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
**
-** http://www.apache.org/licenses/LICENSE-2.0
+** http://www.apache.org/licenses/LICENSE-2.0
**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
+** 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.phone.NotificationPanelView
+<com.android.systemui.statusbar.phone.NotificationPanelView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:systemui="http://schemas.android.com/apk/res-auto"
android:id="@+id/notification_panel"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:background="@android:color/transparent"
- >
+ android:background="@android:color/transparent" >
<include
layout="@layout/keyguard_status_view"
@@ -77,8 +76,8 @@
</com.android.systemui.statusbar.phone.NotificationsQuickSettingsContainer>
<include
- layout="@layout/keyguard_bottom_area"
- android:visibility="gone" />
+ layout="@layout/keyguard_bottom_area"
+ android:visibility="gone" />
<com.android.systemui.statusbar.AlphaOptimizedView
android:id="@+id/qs_navbar_scrim"
@@ -88,4 +87,4 @@
android:visibility="invisible"
android:background="@drawable/qs_navbar_scrim" />
-</com.android.systemui.statusbar.phone.NotificationPanelView><!-- end of sliding panel -->
+</com.android.systemui.statusbar.phone.NotificationPanelView>
diff --git a/packages/SystemUI/res/layout/super_status_bar.xml b/packages/SystemUI/res/layout/super_status_bar.xml
index 285a8ec..c2686f8 100644
--- a/packages/SystemUI/res/layout/super_status_bar.xml
+++ b/packages/SystemUI/res/layout/super_status_bar.xml
@@ -48,6 +48,7 @@
android:layout_height="match_parent"
android:importantForAccessibility="no"
sysui:ignoreRightInset="true"
+ sysui:scrimColor="@color/scrim_behind_color"
/>
<com.android.systemui.statusbar.AlphaOptimizedView
@@ -72,7 +73,7 @@
<include layout="@layout/status_bar_expanded"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:visibility="gone" />
+ android:visibility="invisible" />
<com.android.systemui.statusbar.ScrimView android:id="@+id/scrim_in_front"
android:layout_width="match_parent"
diff --git a/packages/SystemUI/res/values/attrs.xml b/packages/SystemUI/res/values/attrs.xml
index 7fb513c..7632f87 100644
--- a/packages/SystemUI/res/values/attrs.xml
+++ b/packages/SystemUI/res/values/attrs.xml
@@ -115,5 +115,9 @@
<declare-styleable name="PluginInflateContainer">
<attr name="viewType" format="string" />
</declare-styleable>
+ <declare-styleable name="ScrimView">
+ <!-- The initial color for the scrim. -->
+ <attr name="scrimColor" format="color" />
+ </declare-styleable>
</resources>
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index 1ec611a..ad5b108 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -36,6 +36,7 @@
<color name="qs_detail_button">@*android:color/quaternary_device_default_settings</color>
<color name="qs_detail_button_white">#B3FFFFFF</color><!-- 70% white -->
<color name="qs_detail_transition">#66FFFFFF</color>
+ <color name="scrim_behind_color">@android:color/black</color>
<color name="status_bar_clock_color">#FFFFFFFF</color>
<color name="qs_user_detail_icon_muted">#FFFFFFFF</color> <!-- not so muted after all -->
<color name="qs_tile_disabled_color">#9E9E9E</color> <!-- 38% black -->
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 2f39d1d..64cac3c 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -106,7 +106,7 @@
<!-- The default tiles to display in QuickSettings -->
<string name="quick_settings_tiles_default" translatable="false">
- wifi,cell,battery,dnd,flashlight,rotation,bt,airplane
+ wifi,cell,bt,dnd,flashlight,rotation,battery,airplane
</string>
<!-- Tiles native to System UI. Order should match "quick_settings_tiles_default" -->
@@ -302,4 +302,34 @@
<item type="id" name="action_split_task_to_right" />
<item type="id" name="action_split_task_to_top" />
+ <!-- Whether or not the gear icon on notifications should be shown. The gear is shown when the
+ the notification is not swiped enough to dismiss it. -->
+ <bool name="config_showNotificationGear">true</bool>
+
+ <!-- Whether or not a background should be drawn behind a notification. -->
+ <bool name="config_drawNotificationBackground">true</bool>
+
+ <!-- Whether or not the edit icon on the quick settings header is shown. -->
+ <bool name="config_showQuickSettingsEditingIcon">true</bool>
+
+ <!-- Whether or not the multi-user switcher should be visible even if the quick settings are
+ not expanded. If there are not multiple users on the system, the switcher will still
+ hide itself. -->
+ <bool name="config_alwaysShowMultiUserSwitcher">false</bool>
+
+ <!-- Whether or not the expand indicator is visible for manually expanding the quick settings
+ panel. -->
+ <bool name="config_showQuickSettingsExpandIndicator">true</bool>
+
+ <!-- Whether or not to display the row of quick settings icons separate from the full quick
+ settings panel. -->
+ <bool name="config_showQuickSettingsRow">true</bool>
+
+ <!-- Whether or not the quick settings should be revealed on an overscroll of the
+ notifications panel. -->
+ <bool name="config_enableQuickSettingsOverscrollExpansion">true</bool>
+
+ <!-- Whether or the notifications can be shown and dismissed with a drag. -->
+ <bool name="config_enableNotificationShadeDrag">true</bool>
+
</resources>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index ddcc4baf..b768f90 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -69,6 +69,9 @@
<!-- Height of a small notification in the status bar-->
<dimen name="notification_min_height">92dp</dimen>
+ <!-- Height of a small notification in the status bar if it is a large (like messaging)-->
+ <dimen name="notification_min_height_large">132dp</dimen>
+
<!-- Height of a small notification in the status bar which was used before android N -->
<dimen name="notification_min_height_legacy">64dp</dimen>
@@ -347,6 +350,8 @@
<dimen name="keyguard_clock_notifications_margin_max">42dp</dimen>
<dimen name="heads_up_scrim_height">250dp</dimen>
+ <item name="scrim_behind_alpha" format="float" type="dimen">0.62</item>
+
<!-- The minimum amount the user needs to swipe to go to the camera / phone. -->
<dimen name="keyguard_min_swipe_amount">110dp</dimen>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index d3e965a..2cc2621 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -207,6 +207,8 @@
<string name="accessibility_home">Home</string>
<!-- Content description of the menu button for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
<string name="accessibility_menu">Menu</string>
+ <!-- Content description of the accessibility button in the navigation bar (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_accessibility_button">Accessibility</string>
<!-- Content description of the recents button for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
<string name="accessibility_recent">Overview</string>
<!-- Content description of the search button for accessibility. [CHAR LIMIT=NONE] -->
@@ -1746,8 +1748,8 @@
<!-- Label for PIP action to Minimize the PIP [CHAR LIMIT=25] -->
<string name="pip_phone_minimize">Minimize</string>
- <!-- Label for PIP action to Dismiss the PIP -->
- <string name="pip_phone_dismiss">Dismiss</string>
+ <!-- Label for PIP the drag to close zone [CHAR LIMIT=NONE]-->
+ <string name="pip_phone_close">Close</string>
<!-- PIP section of the tuner. Non-translatable since it should
not appear on production builds ever. -->
@@ -1802,10 +1804,8 @@
<string name="notification_channel_alerts">Alerts</string>
<!-- Title for the notification channel dedicated to screenshot progress. [CHAR LIMIT=NONE] -->
<string name="notification_channel_screenshot">Screenshots</string>
- <!-- Title for the notification channel for urgent security issues. [CHAR LIMIT=NONE] -->
- <string name="notification_channel_security">Security</string>
- <!-- Title for the notification channel containing multi-user status information. [CHAR LIMIT=NONE] -->
- <string name="notification_channel_user_status">User status</string>
+ <!-- Title for the notification channel for miscellaneous notices. [CHAR LIMIT=NONE] -->
+ <string name="notification_channel_general">General Messages</string>
<!-- Title for the notification channel for problems with storage (i.e. low disk). [CHAR LIMIT=NONE] -->
<string name="notification_channel_storage">Storage</string>
diff --git a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
index b30b596..29a8da0 100644
--- a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
+++ b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
@@ -76,7 +76,7 @@
mDrawable.setBatteryController(mBatteryController);
mBatteryController.addCallback(this);
mDrawable.startListening();
- TunerService.get(getContext()).addTunable(this, StatusBarIconController.ICON_BLACKLIST);
+ Dependency.get(TunerService.class).addTunable(this, StatusBarIconController.ICON_BLACKLIST);
}
@Override
@@ -84,7 +84,7 @@
super.onDetachedFromWindow();
mBatteryController.removeCallback(this);
mDrawable.stopListening();
- TunerService.get(getContext()).removeTunable(this);
+ Dependency.get(TunerService.class).removeTunable(this);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java
index 135b129..e1f3176 100644
--- a/packages/SystemUI/src/com/android/systemui/Dependency.java
+++ b/packages/SystemUI/src/com/android/systemui/Dependency.java
@@ -14,6 +14,7 @@
package com.android.systemui;
+import android.content.Context;
import android.content.res.Configuration;
import android.os.Handler;
import android.os.HandlerThread;
@@ -23,6 +24,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.systemui.assist.AssistManager;
+import com.android.systemui.plugins.PluginManager;
import com.android.systemui.statusbar.phone.ManagedProfileController;
import com.android.systemui.statusbar.phone.ManagedProfileControllerImpl;
import com.android.systemui.statusbar.policy.AccessibilityController;
@@ -56,9 +58,11 @@
import com.android.systemui.statusbar.policy.UserSwitcherController;
import com.android.systemui.statusbar.policy.ZenModeController;
import com.android.systemui.statusbar.policy.ZenModeControllerImpl;
+import com.android.systemui.tuner.TunerService;
import java.io.FileDescriptor;
import java.io.PrintWriter;
+import java.util.HashMap;
/**
* Class to handle ugly dependencies throughout sysui until we determine the
@@ -167,12 +171,18 @@
mProviders.put(DeviceProvisionedController.class.getName(), () ->
new DeviceProvisionedControllerImpl(mContext));
+ mProviders.put(PluginManager.class.getName(), () ->
+ new PluginManager(mContext));
+
mProviders.put(AssistManager.class.getName(), () ->
new AssistManager(getDependency(DeviceProvisionedController.class), mContext));
mProviders.put(SecurityController.class.getName(), () ->
new SecurityControllerImpl(mContext));
+ mProviders.put(TunerService.class.getName(), () ->
+ new TunerService(mContext));
+
// Put all dependencies above here so the factory can override them if it wants.
SystemUIFactory.getInstance().injectDependencies(mProviders, mContext);
}
@@ -220,6 +230,17 @@
T createDependency();
}
+ /**
+ * Used in separate processes (like tuner settings) to init the dependencies.
+ */
+ public static void initDependencies(Context context) {
+ if (sDependency != null) return;
+ Dependency d = new Dependency();
+ d.mContext = context.getApplicationContext();
+ d.mComponents = new HashMap<>();
+ d.start();
+ }
+
public static <T> T get(Class<T> cls) {
return sDependency.getDependency(cls.getName());
}
diff --git a/packages/SystemUI/src/com/android/systemui/EventLogConstants.java b/packages/SystemUI/src/com/android/systemui/EventLogConstants.java
index 9238928..def3c40 100644
--- a/packages/SystemUI/src/com/android/systemui/EventLogConstants.java
+++ b/packages/SystemUI/src/com/android/systemui/EventLogConstants.java
@@ -16,30 +16,46 @@
package com.android.systemui;
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+
/**
* Constants to be passed as sysui_* eventlog parameters.
*/
public class EventLogConstants {
/** The user swiped up on the lockscreen, unlocking the device. */
- public static final int SYSUI_LOCKSCREEN_GESTURE_SWIPE_UP_UNLOCK = 1;
+ private static final int SYSUI_LOCKSCREEN_GESTURE_SWIPE_UP_UNLOCK = 1;
/** The user swiped down on the lockscreen, going to the full shade. */
- public static final int SYSUI_LOCKSCREEN_GESTURE_SWIPE_DOWN_FULL_SHADE = 2;
+ private static final int SYSUI_LOCKSCREEN_GESTURE_SWIPE_DOWN_FULL_SHADE = 2;
/** The user tapped in an empty area, causing the unlock hint to be shown. */
- public static final int SYSUI_LOCKSCREEN_GESTURE_TAP_UNLOCK_HINT = 3;
+ private static final int SYSUI_LOCKSCREEN_GESTURE_TAP_UNLOCK_HINT = 3;
/** The user swiped inward on the camera icon, launching the camera. */
- public static final int SYSUI_LOCKSCREEN_GESTURE_SWIPE_CAMERA = 4;
+ private static final int SYSUI_LOCKSCREEN_GESTURE_SWIPE_CAMERA = 4;
/** The user swiped inward on the dialer icon, launching the dialer. */
- public static final int SYSUI_LOCKSCREEN_GESTURE_SWIPE_DIALER = 5;
+ private static final int SYSUI_LOCKSCREEN_GESTURE_SWIPE_DIALER = 5;
/** The user tapped the lock, locking the device. */
- public static final int SYSUI_LOCKSCREEN_GESTURE_TAP_LOCK = 6;
+ private static final int SYSUI_LOCKSCREEN_GESTURE_TAP_LOCK = 6;
/** The user tapped a notification, needs to tap again to launch. */
- public static final int SYSUI_LOCKSCREEN_GESTURE_TAP_NOTIFICATION_ACTIVATE = 7;
+ private static final int SYSUI_LOCKSCREEN_GESTURE_TAP_NOTIFICATION_ACTIVATE = 7;
/** The user swiped down to open quick settings, from keyguard. */
- public static final int SYSUI_LOCKSCREEN_GESTURE_SWIPE_DOWN_QS = 8;
+ private static final int SYSUI_LOCKSCREEN_GESTURE_SWIPE_DOWN_QS = 8;
/** The user swiped down to open quick settings, from shade. */
- public static final int SYSUI_SHADE_GESTURE_SWIPE_DOWN_QS = 9;
+ private static final int SYSUI_SHADE_GESTURE_SWIPE_DOWN_QS = 9;
/** The user tapped on the status bar to open quick settings, from shade. */
- public static final int SYSUI_TAP_TO_OPEN_QS = 10;
+ private static final int SYSUI_TAP_TO_OPEN_QS = 10;
+
+ public static final int[] METRICS_GESTURE_TYPE_MAP = {
+ MetricsEvent.VIEW_UNKNOWN, // there is no type 0
+ MetricsEvent.ACTION_LS_UNLOCK, // SYSUI_LOCKSCREEN_GESTURE_SWIPE_UP_UNLOCK
+ MetricsEvent.ACTION_LS_SHADE, // SYSUI_LOCKSCREEN_GESTURE_SWIPE_DOWN_FULL_SHADE
+ MetricsEvent.ACTION_LS_HINT, // SYSUI_LOCKSCREEN_GESTURE_TAP_UNLOCK_HINT
+ MetricsEvent.ACTION_LS_CAMERA, // SYSUI_LOCKSCREEN_GESTURE_SWIPE_CAMERA
+ MetricsEvent.ACTION_LS_DIALER, // SYSUI_LOCKSCREEN_GESTURE_SWIPE_DIALER
+ MetricsEvent.ACTION_LS_LOCK, // SYSUI_LOCKSCREEN_GESTURE_TAP_LOCK
+ MetricsEvent.ACTION_LS_NOTE, // SYSUI_LOCKSCREEN_GESTURE_TAP_NOTIFICATION_ACTIVATE
+ MetricsEvent.ACTION_LS_QS, // SYSUI_LOCKSCREEN_GESTURE_SWIPE_DOWN_QS
+ MetricsEvent.ACTION_SHADE_QS_PULL, // SYSUI_SHADE_GESTURE_SWIPE_DOWN_QS
+ MetricsEvent.ACTION_SHADE_QS_TAP // SYSUI_TAP_TO_OPEN_QS
+ };
/** Secondary user tries binding to the system sysui service */
public static final int SYSUI_RECENTS_CONNECTION_USER_BIND_SERVICE = 1;
diff --git a/packages/SystemUI/src/com/android/systemui/PluginInflateContainer.java b/packages/SystemUI/src/com/android/systemui/PluginInflateContainer.java
index efddf20..9cc6613 100644
--- a/packages/SystemUI/src/com/android/systemui/PluginInflateContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/PluginInflateContainer.java
@@ -76,7 +76,7 @@
protected void onAttachedToWindow() {
super.onAttachedToWindow();
if (mAction != null) {
- PluginManager.getInstance(getContext()).addPluginListener(mAction, this, mVersion);
+ Dependency.get(PluginManager.class).addPluginListener(mAction, this, mVersion);
}
}
@@ -84,7 +84,7 @@
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
if (mAction != null) {
- PluginManager.getInstance(getContext()).removePluginListener(this);
+ Dependency.get(PluginManager.class).removePluginListener(this);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/RecentsComponent.java b/packages/SystemUI/src/com/android/systemui/RecentsComponent.java
index 94b2fdb..9b74cd6 100644
--- a/packages/SystemUI/src/com/android/systemui/RecentsComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/RecentsComponent.java
@@ -21,11 +21,10 @@
import android.view.View;
public interface RecentsComponent {
- void showRecents(boolean triggeredFromAltTab, boolean fromHome);
- void hideRecents(boolean triggeredFromAltTab, boolean triggeredFromHomeKey);
+ void showRecentApps(boolean triggeredFromAltTab, boolean fromHome);
+ void hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHomeKey);
void toggleRecents(Display display);
void preloadRecents();
- void cancelPreloadingRecents();
void showNextAffiliatedTask();
void showPrevAffiliatedTask();
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
index 9515585..27070ed 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
@@ -65,7 +65,6 @@
private final Class<?>[] SERVICES = new Class[] {
Dependency.class,
FragmentService.class,
- TunerService.class,
NotificationChannels.class,
CommandQueue.CommandQueueStart.class,
KeyguardViewMediator.class,
@@ -88,6 +87,7 @@
* above.
*/
private final Class<?>[] SERVICES_PER_USER = new Class[] {
+ Dependency.class,
Recents.class,
PipUI.class
};
@@ -205,7 +205,7 @@
mServices[i].onBootCompleted();
}
}
- PluginManager.getInstance(this).addPluginListener(OverlayPlugin.ACTION,
+ Dependency.get(PluginManager.class).addPluginListener(OverlayPlugin.ACTION,
new PluginListener<OverlayPlugin>() {
@Override
public void onPluginConnected(OverlayPlugin plugin, Context pluginContext) {
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java b/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java
index aa22618..7c15096 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java
@@ -16,6 +16,7 @@
package com.android.systemui.doze;
+import android.app.AlarmManager;
import android.app.Application;
import android.app.PendingIntent;
import android.content.Context;
@@ -25,10 +26,7 @@
import android.os.SystemClock;
import com.android.internal.hardware.AmbientDisplayConfiguration;
-import com.android.systemui.SystemUI;
import com.android.systemui.SystemUIApplication;
-import com.android.systemui.plugins.PluginListener;
-import com.android.systemui.plugins.PluginManager;
import com.android.systemui.plugins.doze.DozeProvider;
import com.android.systemui.statusbar.phone.DozeParameters;
@@ -45,6 +43,7 @@
Context context = dozeService;
SensorManager sensorManager = context.getSystemService(SensorManager.class);
PowerManager powerManager = context.getSystemService(PowerManager.class);
+ AlarmManager alarmManager = context.getSystemService(AlarmManager.class);
DozeHost host = getHost(dozeService);
AmbientDisplayConfiguration config = new AmbientDisplayConfiguration(context);
@@ -57,7 +56,7 @@
machine.setParts(new DozeMachine.Part[]{
createDozeTriggers(context, sensorManager, host, config, params, handler, wakeLock,
machine),
- createDozeUi(context, host, wakeLock, machine),
+ createDozeUi(context, host, wakeLock, machine, handler, alarmManager),
});
return machine;
@@ -72,7 +71,7 @@
}
private DozeMachine.Part createDozeUi(Context context, DozeHost host, WakeLock wakeLock,
- DozeMachine machine) {
+ DozeMachine machine, Handler handler, AlarmManager alarmManager) {
if (mDozePlugin != null) {
DozeProvider.DozeUi dozeUi = mDozePlugin.provideDozeUi(context,
pluginMachine(context, machine, host),
@@ -82,7 +81,7 @@
pluginState(newState));
};
} else {
- return new DozeUi(context, machine, wakeLock, host);
+ return new DozeUi(context, alarmManager, machine, wakeLock, host, handler);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java b/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java
index 00d2298..f3fb1ef 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java
@@ -30,15 +30,12 @@
void stopDozing();
void dozeTimeTick();
boolean isPowerSaveActive();
- boolean isNotificationLightOn();
boolean isPulsingBlocked();
void startPendingIntentDismissingKeyguard(PendingIntent intent);
interface Callback {
- default void onNewNotifications() {}
default void onNotificationHeadsUp() {}
- default void onNotificationLight(boolean on) {}
default void onPowerSaveChanged(boolean active) {}
}
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeService.java b/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
index 828728f..94dc9a3 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
@@ -19,6 +19,7 @@
import android.service.dreams.DreamService;
import android.util.Log;
+import com.android.systemui.Dependency;
import com.android.systemui.plugins.Plugin;
import com.android.systemui.plugins.PluginManager;
import com.android.systemui.plugins.doze.DozeProvider;
@@ -47,7 +48,7 @@
return;
}
- DozeProvider provider = PluginManager.getInstance(this)
+ DozeProvider provider = Dependency.get(PluginManager.class)
.getOneShotPlugin(DozeProvider.ACTION, DozeProvider.VERSION);
mDozeMachine = new DozeFactory(provider).assembleMachine(this);
}
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
index 95e49ce..76e0283 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
@@ -16,7 +16,13 @@
package com.android.systemui.doze;
+import android.app.AlarmManager;
import android.content.Context;
+import android.os.Handler;
+import android.os.SystemClock;
+
+import java.util.Calendar;
+import java.util.GregorianCalendar;
/**
* The policy controlling doze.
@@ -24,16 +30,25 @@
public class DozeUi implements DozeMachine.Part {
private final Context mContext;
+ private final AlarmManager mAlarmManager;
private final DozeHost mHost;
- private DozeFactory.WakeLock mWakeLock;
- private DozeMachine mMachine;
+ private final Handler mHandler;
+ private final DozeFactory.WakeLock mWakeLock;
+ private final DozeMachine mMachine;
+ private final AlarmManager.OnAlarmListener mTimeTick;
- public DozeUi(Context context, DozeMachine machine, DozeFactory.WakeLock wakeLock,
- DozeHost host) {
+ private boolean mTimeTickScheduled = false;
+
+ public DozeUi(Context context, AlarmManager alarmManager, DozeMachine machine,
+ DozeFactory.WakeLock wakeLock, DozeHost host, Handler handler) {
mContext = context;
+ mAlarmManager = alarmManager;
mMachine = machine;
mWakeLock = wakeLock;
mHost = host;
+ mHandler = handler;
+
+ mTimeTick = this::onTimeTick;
}
private void pulseWhileDozing(int reason) {
@@ -54,6 +69,12 @@
@Override
public void transitionTo(DozeMachine.State oldState, DozeMachine.State newState) {
switch (newState) {
+ case DOZE_AOD:
+ scheduleTimeTick();
+ break;
+ case DOZE:
+ unscheduleTimeTick();
+ break;
case DOZE_REQUEST_PULSE:
pulseWhileDozing(DozeLog.PULSE_REASON_NOTIFICATION /* TODO */);
break;
@@ -62,7 +83,52 @@
break;
case FINISH:
mHost.stopDozing();
+ unscheduleTimeTick();
break;
}
}
+
+ private void scheduleTimeTick() {
+ if (mTimeTickScheduled) {
+ return;
+ }
+
+ long delta = roundToNextMinute(System.currentTimeMillis()) - System.currentTimeMillis();
+ mAlarmManager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP,
+ SystemClock.elapsedRealtime() + delta, "doze_time_tick", mTimeTick, mHandler);
+
+ mTimeTickScheduled = true;
+ }
+
+ private void unscheduleTimeTick() {
+ if (!mTimeTickScheduled) {
+ return;
+ }
+ mAlarmManager.cancel(mTimeTick);
+ }
+
+ private long roundToNextMinute(long timeInMillis) {
+ Calendar calendar = GregorianCalendar.getInstance();
+ calendar.setTimeInMillis(timeInMillis);
+ calendar.set(Calendar.MILLISECOND, 0);
+ calendar.set(Calendar.SECOND, 0);
+ calendar.add(Calendar.MINUTE, 1);
+
+ return calendar.getTimeInMillis();
+ }
+
+ private void onTimeTick() {
+ if (!mTimeTickScheduled) {
+ // Alarm was canceled, but we still got the callback. Ignore.
+ return;
+ }
+
+ mHost.dozeTimeTick();
+
+ // Keep wakelock until a frame has been pushed.
+ mHandler.post(mWakeLock.wrap(() -> {}));
+
+ mTimeTickScheduled = false;
+ scheduleTimeTick();
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/fragments/PluginFragmentListener.java b/packages/SystemUI/src/com/android/systemui/fragments/PluginFragmentListener.java
index 2e6de4a..1eaca6f 100644
--- a/packages/SystemUI/src/com/android/systemui/fragments/PluginFragmentListener.java
+++ b/packages/SystemUI/src/com/android/systemui/fragments/PluginFragmentListener.java
@@ -19,6 +19,7 @@
import android.util.Log;
import android.view.View;
+import com.android.systemui.Dependency;
import com.android.systemui.plugins.FragmentBase;
import com.android.systemui.plugins.Plugin;
import com.android.systemui.plugins.PluginListener;
@@ -38,7 +39,7 @@
Class<? extends FragmentBase> expectedInterface) {
mTag = tag;
mFragmentHostManager = FragmentHostManager.get(view);
- mPluginManager = PluginManager.getInstance(view.getContext());
+ mPluginManager = Dependency.get(PluginManager.class);
mExpectedInterface = expectedInterface;
mDefaultClass = defaultFragment;
}
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipDismissViewController.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipDismissViewController.java
index a7ac719..e182176 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipDismissViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipDismissViewController.java
@@ -17,13 +17,19 @@
package com.android.systemui.pip.phone;
import android.content.Context;
+import android.content.res.Resources;
import android.graphics.PixelFormat;
+import android.graphics.Point;
+import android.graphics.PointF;
import android.graphics.Rect;
import android.view.Gravity;
import android.view.LayoutInflater;
+import android.view.TouchDelegate;
import android.view.View;
import android.view.View.OnLayoutChangeListener;
import android.view.WindowManager;
+import android.view.WindowManager.LayoutParams;
+import android.widget.FrameLayout;
import com.android.systemui.Interpolators;
import com.android.systemui.R;
@@ -35,12 +41,22 @@
private static final int SHOW_TARGET_DELAY = 100;
private static final int SHOW_TARGET_DURATION = 200;
+ private static final float DISMISS_TEXT_MAX_SCALE = 2f;
+ private static final float DISMISS_GRADIENT_MIN_HEIGHT_PERCENT = 0.33f;
+ private static final float DISMISS_GRADIENT_MAX_HEIGHT_PERCENT = 0.5f;
+ private static final float DISMISS_THRESHOLD = 0.55f;
+
private Context mContext;
private WindowManager mWindowManager;
private View mDismissView;
private Rect mDismissTargetScreenBounds = new Rect();
+ private View mDismissContainer;
+ private View mGradientView;
+ private float mMinHeight;
+ private float mMaxHeight;
+
public PipDismissViewController(Context context) {
mContext = context;
mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
@@ -51,25 +67,37 @@
*/
public void createDismissTarget() {
if (mDismissView == null) {
+ // Determine sizes for the gradient
+ Point windowSize = new Point();
+ mWindowManager.getDefaultDisplay().getSize(windowSize);
+ mMinHeight = windowSize.y * DISMISS_GRADIENT_MIN_HEIGHT_PERCENT;
+ mMaxHeight = windowSize.y * DISMISS_GRADIENT_MAX_HEIGHT_PERCENT;
+
// Create a new view for the dismiss target
- int dismissTargetSize = mContext.getResources().getDimensionPixelSize(
- R.dimen.pip_dismiss_target_size);
LayoutInflater inflater = LayoutInflater.from(mContext);
mDismissView = inflater.inflate(R.layout.pip_dismiss_view, null);
- mDismissView.addOnLayoutChangeListener(new OnLayoutChangeListener() {
+ mGradientView = mDismissView.findViewById(R.id.gradient_view);
+ FrameLayout.LayoutParams glp = (android.widget.FrameLayout.LayoutParams) mGradientView
+ .getLayoutParams();
+ glp.height = (int) mMaxHeight;
+ mGradientView.setLayoutParams(glp);
+ mGradientView.setPivotY(windowSize.y);
+ mGradientView.setScaleY(mMaxHeight / mMinHeight); // Set to min height via scaling
+ mDismissContainer = mDismissView.findViewById(R.id.pip_dismiss_container);
+ mDismissContainer.addOnLayoutChangeListener(new OnLayoutChangeListener() {
@Override
public void onLayoutChange(View v, int left, int top, int right, int bottom,
int oldLeft, int oldTop, int oldRight, int oldBottom) {
- if (mDismissView != null) {
- mDismissView.getBoundsOnScreen(mDismissTargetScreenBounds);
+ if (mDismissContainer != null) {
+ mDismissContainer.getBoundsOnScreen(mDismissTargetScreenBounds);
}
}
});
// Add the target to the window
WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
- dismissTargetSize,
- dismissTargetSize,
+ windowSize.x,
+ (int) mMaxHeight,
WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG,
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
@@ -84,7 +112,8 @@
/**
* Shows the dismiss target.
*/
- public void showDismissTarget() {
+ public void showDismissTarget(Rect pinnedStack) {
+ updateDismissTarget(pinnedStack);
mDismissView.animate()
.alpha(1f)
.setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN)
@@ -115,10 +144,46 @@
}
/**
+ * Updates the appearance of the dismiss target based on how close the PIP is.
+ */
+ public void updateDismissTarget(Rect pinnedStack) {
+ // As PIP moves over / away from delete target it grows / shrinks
+ final float scalePercent = calculateDistancePercent(pinnedStack);
+ final float newScale = 1 + (DISMISS_TEXT_MAX_SCALE - 1) * scalePercent;
+ final float minGradientScale = mMinHeight / mMaxHeight;
+ final float newHeight = Math.max(minGradientScale, scalePercent);
+ mGradientView.setScaleY(newHeight);
+ mDismissContainer.setScaleX(newScale);
+ mDismissContainer.setScaleY(newScale);
+ }
+
+ /**
+ * @return the percentage of distance the PIP is away from the dismiss target point.
+ */
+ private float calculateDistancePercent(Rect pinnedStack) {
+ final int distance = mDismissTargetScreenBounds.height();
+ final int textX = mDismissTargetScreenBounds.centerX();
+ final int textY = mDismissTargetScreenBounds.bottom;
+ final float pipCurrX = pinnedStack.centerX();
+ final float pipCurrY = pinnedStack.bottom;
+ final float currentDistance = PointF.length(pipCurrX - textX, pipCurrY - textY);
+ if (currentDistance <= distance) {
+ return 1 - (currentDistance / distance);
+ }
+ return 0;
+ }
+
+ /**
* @return the dismiss target screen bounds.
*/
public Rect getDismissBounds() {
return mDismissTargetScreenBounds;
}
+ /**
+ * @return whether the PIP is positioned on the dismiss target enough to be dismissed.
+ */
+ public boolean shouldDismiss(Rect pinnedStack) {
+ return calculateDistancePercent(pinnedStack) >= DISMISS_THRESHOLD;
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java
index 6ef30c0..f3dc339 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java
@@ -77,7 +77,7 @@
void onPipMinimize();
/**
- * Called when the PIP requested to be expanded.
+ * Called when the PIP requested to be dismissed.
*/
void onPipDismiss();
}
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
index 5727684..10393c6 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
@@ -33,6 +33,7 @@
import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.Rect;
+import android.os.Handler;
import android.os.Looper;
import android.os.RemoteException;
import android.util.Log;
@@ -44,9 +45,12 @@
import android.view.MotionEvent;
import android.view.ViewConfiguration;
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.os.BackgroundThread;
import com.android.internal.policy.PipMotionHelper;
import com.android.internal.policy.PipSnapAlgorithm;
+import com.android.systemui.Dependency;
import com.android.systemui.statusbar.FlingAnimationUtils;
import com.android.systemui.tuner.TunerService;
@@ -58,6 +62,10 @@
private static final String TAG = "PipTouchHandler";
private static final boolean DEBUG_ALLOW_OUT_OF_BOUNDS_STACK = false;
+ // These values are used for metrics and should never change
+ private static final int METRIC_VALUE_DISMISSED_BY_TAP = 0;
+ private static final int METRIC_VALUE_DISMISSED_BY_DRAG = 1;
+
private static final String TUNER_KEY_DRAG_TO_DISMISS = "pip_drag_to_dismiss";
private static final String TUNER_KEY_ALLOW_MINIMIZE = "pip_allow_minimize";
@@ -65,6 +73,7 @@
private static final int DISMISS_STACK_DURATION = 375;
private static final int EXPAND_STACK_DURATION = 225;
private static final int MINIMIZE_STACK_MAX_DURATION = 200;
+ private static final int SHOW_DISMISS_AFFORDANCE_DELAY = 200;
// The fraction of the stack width that the user has to drag offscreen to minimize the PIP
private static final float MINIMIZE_OFFSCREEN_FRACTION = 0.2f;
@@ -99,6 +108,16 @@
}
};
+ private Handler mHandler = new Handler();
+ private Runnable mShowDismissAffordance = new Runnable() {
+ @Override
+ public void run() {
+ if (mEnableDragToDismiss) {
+ mDismissViewController.showDismissTarget(mPinnedStackBounds);
+ }
+ }
+ };
+
// Behaviour states
private boolean mIsTappingThrough;
private boolean mIsMinimized;
@@ -147,6 +166,8 @@
} else {
unregisterInputConsumer();
}
+ MetricsLogger.visibility(mContext, MetricsEvent.ACTION_PICTURE_IN_PICTURE_MENU,
+ visible);
}
@Override
@@ -165,6 +186,8 @@
@Override
public void onPipDismiss() {
BackgroundThread.getHandler().post(PipTouchHandler.this::dismissPinnedStack);
+ MetricsLogger.action(mContext, MetricsEvent.ACTION_PICTURE_IN_PICTURE_DISMISSED,
+ METRIC_VALUE_DISMISSED_BY_TAP);
}
}
@@ -183,14 +206,14 @@
mTouchState = new PipTouchState(mViewConfig);
mFlingAnimationUtils = new FlingAnimationUtils(context, 2f);
mGestures = new PipTouchGesture[] {
- mDragToDismissGesture, mDefaultMovementGesture
+ mDefaultMovementGesture
};
mMotionHelper = new PipMotionHelper(BackgroundThread.getHandler());
registerInputConsumer();
setSnapToEdge(true);
// Register any tuner settings changes
- TunerService.get(context).addTunable(this, TUNER_KEY_DRAG_TO_DISMISS,
+ Dependency.get(TunerService.class).addTunable(this, TUNER_KEY_DRAG_TO_DISMISS,
TUNER_KEY_ALLOW_MINIMIZE);
}
@@ -230,6 +253,10 @@
}
public void onMinimizedStateChanged(boolean isMinimized) {
+ if (mIsMinimized != isMinimized) {
+ MetricsLogger.action(mContext, MetricsEvent.ACTION_PICTURE_IN_PICTURE_MINIMIZED,
+ isMinimized);
+ }
mIsMinimized = isMinimized;
mSnapAlgorithm.setMinimized(isMinimized);
}
@@ -439,7 +466,7 @@
/**
* Flings the PIP to the closest snap target.
*/
- private void flingToSnapTarget(float velocity, float velocityX, float velocityY) {
+ private Rect flingToSnapTarget(float velocity, float velocityX, float velocityY) {
Rect toBounds = mSnapAlgorithm.findClosestSnapBounds(mBoundedPinnedStackBounds,
mPinnedStackBounds, velocityX, velocityY);
if (!mPinnedStackBounds.equals(toBounds)) {
@@ -450,12 +477,13 @@
velocity);
mPinnedStackBoundsAnimator.start();
}
+ return toBounds;
}
/**
* Animates the PIP to the closest snap target.
*/
- private void animateToClosestSnapTarget() {
+ private Rect animateToClosestSnapTarget() {
Rect toBounds = mSnapAlgorithm.findClosestSnapBounds(mBoundedPinnedStackBounds,
mPinnedStackBounds);
if (!mPinnedStackBounds.equals(toBounds)) {
@@ -463,6 +491,7 @@
toBounds, SNAP_STACK_DURATION, FAST_OUT_SLOW_IN, mUpdatePinnedStackBoundsListener);
mPinnedStackBoundsAnimator.start();
}
+ return toBounds;
}
/**
@@ -505,6 +534,9 @@
private void movePinnedStack(Rect bounds) {
if (!bounds.equals(mPinnedStackBounds)) {
mPinnedStackBounds.set(bounds);
+ if (mEnableDragToDismiss) {
+ mDismissViewController.updateDismissTarget(bounds);
+ }
mMotionHelper.resizeToBounds(mPinnedStackBounds);
}
}
@@ -547,54 +579,25 @@
}
/**
- * Gesture controlling dragging over a target to dismiss the PIP.
- */
- private PipTouchGesture mDragToDismissGesture = new PipTouchGesture() {
- @Override
- public void onDown(PipTouchState touchState) {
- if (mEnableDragToDismiss) {
- // TODO: Consider setting a timer such at after X time, we show the dismiss
- // target if the user hasn't already dragged some distance
- mDismissViewController.createDismissTarget();
- }
- }
-
- @Override
- boolean onMove(PipTouchState touchState) {
- if (mEnableDragToDismiss && touchState.startedDragging()) {
- mDismissViewController.showDismissTarget();
- }
- return false;
- }
-
- @Override
- public boolean onUp(PipTouchState touchState) {
- if (mEnableDragToDismiss) {
- try {
- if (touchState.isDragging()) {
- Rect dismissBounds = mDismissViewController.getDismissBounds();
- PointF lastTouch = touchState.getLastTouchPosition();
- if (dismissBounds.contains((int) lastTouch.x, (int) lastTouch.y)) {
- animateDismissPinnedStack(dismissBounds);
- return true;
- }
- }
- } finally {
- mDismissViewController.destroyDismissTarget();
- }
- }
- return false;
- }
- };
-
- /**** Gestures ****/
-
- /**
* Gesture controlling normal movement of the PIP.
*/
private PipTouchGesture mDefaultMovementGesture = new PipTouchGesture() {
+
+ @Override
+ public void onDown(PipTouchState touchState) {
+ if (mEnableDragToDismiss) {
+ mDismissViewController.createDismissTarget();
+ mHandler.postDelayed(mShowDismissAffordance, SHOW_DISMISS_AFFORDANCE_DELAY);
+ }
+ }
+
@Override
boolean onMove(PipTouchState touchState) {
+ if (touchState.startedDragging() && mEnableDragToDismiss) {
+ mHandler.removeCallbacks(mShowDismissAffordance);
+ mDismissViewController.showDismissTarget(mPinnedStackBounds);
+ }
+
if (touchState.isDragging()) {
// Move the pinned stack freely
PointF lastDelta = touchState.getLastTouchDelta();
@@ -616,6 +619,23 @@
@Override
public boolean onUp(PipTouchState touchState) {
+ try {
+ if (mEnableDragToDismiss) {
+ mHandler.removeCallbacks(mShowDismissAffordance);
+ PointF vel = mTouchState.getVelocity();
+ final float velocity = PointF.length(vel.x, vel.y);
+ if (touchState.isDragging()
+ && velocity < mFlingAnimationUtils.getMinVelocityPxPerSecond()) {
+ if (mDismissViewController.shouldDismiss(mPinnedStackBounds)) {
+ Rect dismissBounds = mDismissViewController.getDismissBounds();
+ animateDismissPinnedStack(dismissBounds);
+ return true;
+ }
+ }
+ }
+ } finally {
+ mDismissViewController.destroyDismissTarget();
+ }
if (touchState.isDragging()) {
PointF vel = mTouchState.getVelocity();
if (!mIsMinimized && (shouldMinimizedPinnedStack()
diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
index 82ec69d..09ce2ad 100644
--- a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
+++ b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
@@ -145,16 +145,16 @@
}
private void showInvalidChargerNotification() {
- final Notification.Builder nb = new Notification.Builder(mContext)
- .setSmallIcon(R.drawable.ic_power_low)
- .setWhen(0)
- .setShowWhen(false)
- .setOngoing(true)
- .setContentTitle(mContext.getString(R.string.invalid_charger_title))
- .setContentText(mContext.getString(R.string.invalid_charger_text))
- .setChannel(NotificationChannels.ALERTS)
- .setColor(mContext.getColor(
- com.android.internal.R.color.system_notification_accent_color));
+ final Notification.Builder nb =
+ new Notification.Builder(mContext, NotificationChannels.ALERTS)
+ .setSmallIcon(R.drawable.ic_power_low)
+ .setWhen(0)
+ .setShowWhen(false)
+ .setOngoing(true)
+ .setContentTitle(mContext.getString(R.string.invalid_charger_title))
+ .setContentText(mContext.getString(R.string.invalid_charger_text))
+ .setColor(mContext.getColor(
+ com.android.internal.R.color.system_notification_accent_color));
SystemUI.overrideNotificationAppName(mContext, nb);
final Notification n = nb.build();
mNoMan.cancelAsUser(TAG_BATTERY, SystemMessage.NOTE_POWER_LOW, UserHandle.ALL);
@@ -164,19 +164,19 @@
private void showWarningNotification() {
final int textRes = R.string.battery_low_percent_format;
final String percentage = NumberFormat.getPercentInstance().format((double) mBatteryLevel / 100.0);
- final Notification.Builder nb = new Notification.Builder(mContext)
- .setSmallIcon(R.drawable.ic_power_low)
- // Bump the notification when the bucket dropped.
- .setWhen(mBucketDroppedNegativeTimeMs)
- .setShowWhen(false)
- .setContentTitle(mContext.getString(R.string.battery_low_title))
- .setContentText(mContext.getString(textRes, percentage))
- .setOnlyAlertOnce(true)
- .setDeleteIntent(pendingBroadcast(ACTION_DISMISSED_WARNING))
- .setChannel(NotificationChannels.ALERTS)
- .setVisibility(Notification.VISIBILITY_PUBLIC)
- .setColor(mContext.getColor(
- com.android.internal.R.color.battery_saver_mode_color));
+ final Notification.Builder nb =
+ new Notification.Builder(mContext, NotificationChannels.ALERTS)
+ .setSmallIcon(R.drawable.ic_power_low)
+ // Bump the notification when the bucket dropped.
+ .setWhen(mBucketDroppedNegativeTimeMs)
+ .setShowWhen(false)
+ .setContentTitle(mContext.getString(R.string.battery_low_title))
+ .setContentText(mContext.getString(textRes, percentage))
+ .setOnlyAlertOnce(true)
+ .setDeleteIntent(pendingBroadcast(ACTION_DISMISSED_WARNING))
+ .setVisibility(Notification.VISIBILITY_PUBLIC)
+ .setColor(mContext.getColor(
+ com.android.internal.R.color.battery_saver_mode_color));
if (hasBatterySettings()) {
nb.setContentIntent(pendingBroadcast(ACTION_SHOW_BATTERY_SETTINGS));
}
@@ -235,18 +235,18 @@
return;
}
mTempWarning = true;
- final Notification.Builder nb = new Notification.Builder(mContext)
- .setSmallIcon(R.drawable.ic_device_thermostat_24)
- .setWhen(0)
- .setShowWhen(false)
- .setContentTitle(mContext.getString(R.string.high_temp_title))
- .setContentText(mContext.getString(R.string.high_temp_notif_message))
- .setChannel(NotificationChannels.ALERTS)
- .setVisibility(Notification.VISIBILITY_PUBLIC)
- .setContentIntent(pendingBroadcast(ACTION_CLICKED_TEMP_WARNING))
- .setDeleteIntent(pendingBroadcast(ACTION_DISMISSED_TEMP_WARNING))
- .setColor(mContext.getColor(
- com.android.internal.R.color.battery_saver_mode_color));
+ final Notification.Builder nb =
+ new Notification.Builder(mContext, NotificationChannels.ALERTS)
+ .setSmallIcon(R.drawable.ic_device_thermostat_24)
+ .setWhen(0)
+ .setShowWhen(false)
+ .setContentTitle(mContext.getString(R.string.high_temp_title))
+ .setContentText(mContext.getString(R.string.high_temp_notif_message))
+ .setVisibility(Notification.VISIBILITY_PUBLIC)
+ .setContentIntent(pendingBroadcast(ACTION_CLICKED_TEMP_WARNING))
+ .setDeleteIntent(pendingBroadcast(ACTION_DISMISSED_TEMP_WARNING))
+ .setColor(mContext.getColor(
+ com.android.internal.R.color.battery_saver_mode_color));
SystemUI.overrideNotificationAppName(mContext, nb);
final Notification n = nb.build();
mNoMan.notifyAsUser(TAG_TEMPERATURE, SystemMessage.NOTE_HIGH_TEMP, n, UserHandle.ALL);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
index 602f9bf..c85f83b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
@@ -20,6 +20,7 @@
import android.view.View.OnLayoutChangeListener;
import android.widget.TextView;
+import com.android.systemui.Dependency;
import com.android.systemui.plugins.qs.QS;
import com.android.systemui.qs.PagedTileLayout.PageListener;
import com.android.systemui.qs.QSPanel.QSTileLayout;
@@ -105,7 +106,7 @@
@Override
public void onViewAttachedToWindow(View v) {
- TunerService.get(mQs.getContext()).addTunable(this, ALLOW_FANCY_ANIMATION,
+ Dependency.get(TunerService.class).addTunable(this, ALLOW_FANCY_ANIMATION,
MOVE_FULL_ROWS, QuickQSPanel.NUM_QUICK_TILES);
}
@@ -114,7 +115,7 @@
if (mHost != null) {
mHost.removeCallback(this);
}
- TunerService.get(mQs.getContext()).removeTunable(this);
+ Dependency.get(TunerService.class).removeTunable(this);
}
@Override
@@ -194,7 +195,6 @@
translationYBuilder.addFloat(label, "translationY", -yDiff, 0);
mTopFiveQs.add(tileView.getIcon());
- mTopFiveQs.add(tileView.getBgCicle());
mAllViews.add(tileView.getIcon());
mAllViews.add(quickTileView);
} else if (mFullRows && isIconInAnimatedRow(count)) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
index c8f1670..95e0301 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
@@ -74,8 +74,14 @@
mContainer = (QSContainerImpl) view;
mQSDetail.setQsPanel(mQSPanel, mHeader);
- mQSAnimator = new QSAnimator(this, (QuickQSPanel) mHeader.findViewById(R.id.quick_qs_panel),
- mQSPanel);
+
+ // If the quick settings row is not shown, then there is no need for the animation from
+ // the row to the full QS panel.
+ if (getResources().getBoolean(R.bool.config_showQuickSettingsRow)) {
+ mQSAnimator = new QSAnimator(this,
+ (QuickQSPanel) mHeader.findViewById(R.id.quick_qs_panel), mQSPanel);
+ }
+
mQSCustomizer = (QSCustomizer) view.findViewById(R.id.qs_customize);
mQSCustomizer.setQs(this);
}
@@ -89,7 +95,10 @@
super.onConfigurationChanged(newConfig);
if (newConfig.getLayoutDirection() != mLayoutDirection) {
mLayoutDirection = newConfig.getLayoutDirection();
- mQSAnimator.onRtlChanged();
+
+ if (mQSAnimator != null) {
+ mQSAnimator.onRtlChanged();
+ }
}
}
@@ -108,7 +117,10 @@
mQSPanel.setHost(qsh, mQSCustomizer);
mHeader.setQSPanel(mQSPanel);
mQSDetail.setHost(qsh);
- mQSAnimator.setHost(qsh);
+
+ if (mQSAnimator != null) {
+ mQSAnimator.setHost(qsh);
+ }
}
private void updateQsState() {
@@ -155,7 +167,11 @@
public void setKeyguardShowing(boolean keyguardShowing) {
if (DEBUG) Log.d(TAG, "setKeyguardShowing " + keyguardShowing);
mKeyguardShowing = keyguardShowing;
- mQSAnimator.setOnKeyguard(keyguardShowing);
+
+ if (mQSAnimator != null) {
+ mQSAnimator.setOnKeyguard(keyguardShowing);
+ }
+
updateQsState();
}
@@ -187,7 +203,10 @@
mHeader.setExpansion(mKeyguardShowing ? 1 : expansion);
mQSPanel.setTranslationY(translationScaleY * mQSPanel.getHeight());
mQSDetail.setFullyExpanded(expansion == 1);
- mQSAnimator.setPosition(expansion);
+
+ if (mQSAnimator != null) {
+ mQSAnimator.setPosition(expansion);
+ }
// Set bounds on the QS panel so it doesn't run over the header.
mQsBounds.top = (int) (mQSPanel.getHeight() * (1 - expansion));
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index e004828..504678c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -29,6 +29,7 @@
import android.widget.LinearLayout;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.plugins.qs.QS;
import com.android.systemui.plugins.qs.QS.DetailAdapter;
@@ -126,7 +127,7 @@
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
- TunerService.get(mContext).addTunable(this, QS_SHOW_BRIGHTNESS);
+ Dependency.get(TunerService.class).addTunable(this, QS_SHOW_BRIGHTNESS);
if (mHost != null) {
setTiles(mHost.getTiles());
}
@@ -134,8 +135,10 @@
@Override
protected void onDetachedFromWindow() {
- TunerService.get(mContext).removeTunable(this);
- mHost.removeCallback(this);
+ Dependency.get(TunerService.class).removeTunable(this);
+ if (mHost != null) {
+ mHost.removeCallback(this);
+ }
for (TileRecord record : mRecords) {
record.tile.removeCallbacks();
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTile.java b/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
index e18654e..0829ae5 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
@@ -323,9 +323,10 @@
return Utils.getDisabled(context,
Utils.getColorAttr(context, android.R.attr.textColorTertiary));
case Tile.STATE_INACTIVE:
- return Utils.getColorAttr(context, android.R.attr.textColorSecondary);
+ return Utils.getDisabled(context,
+ Utils.getColorAttr(context, android.R.attr.colorForeground));
case Tile.STATE_ACTIVE:
- return Utils.getColorAttr(context, android.R.attr.colorPrimary);
+ return Utils.getColorAttr(context, android.R.attr.colorForeground);
default:
Log.e("QSTile", "Invalid state " + state);
return 0;
@@ -548,6 +549,7 @@
public CharSequence minimalContentDescription;
public boolean autoMirrorDrawable = true;
public boolean disabledByPolicy;
+ public boolean dualTarget = false;
public EnforcedAdmin enforcedAdmin;
public String minimalAccessibilityClassName;
public String expandedAccessibilityClassName;
@@ -569,7 +571,8 @@
expandedAccessibilityClassName)
|| !Objects.equals(other.disabledByPolicy, disabledByPolicy)
|| !Objects.equals(other.state, state)
- || !Objects.equals(other.enforcedAdmin, enforcedAdmin);
+ || !Objects.equals(other.enforcedAdmin, enforcedAdmin)
+ || !Objects.equals(other.dualTarget, dualTarget);
other.icon = icon;
other.label = label;
other.contentDescription = contentDescription;
@@ -580,6 +583,7 @@
other.autoMirrorDrawable = autoMirrorDrawable;
other.disabledByPolicy = disabledByPolicy;
other.state = state;
+ other.dualTarget = dualTarget;
if (enforcedAdmin == null) {
other.enforcedAdmin = null;
} else if (other.enforcedAdmin == null) {
@@ -607,6 +611,7 @@
sb.append(",autoMirrorDrawable=").append(autoMirrorDrawable);
sb.append(",disabledByPolicy=").append(disabledByPolicy);
sb.append(",enforcedAdmin=").append(enforcedAdmin);
+ sb.append(",dualTarget=").append(dualTarget);
sb.append(",state=").append(state);
return sb.append(']');
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTileBaseView.java b/packages/SystemUI/src/com/android/systemui/qs/QSTileBaseView.java
index a177cc3..0e04d0a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTileBaseView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTileBaseView.java
@@ -47,17 +47,12 @@
private static final String TAG = "QSTileBaseView";
private final H mHandler = new H();
- private final ImageView mBg;
protected QSIconView mIcon;
protected RippleDrawable mRipple;
private Drawable mTileBackground;
private String mAccessibilityClass;
private boolean mTileState;
private boolean mCollapsedView;
- private final int mColorActive;
- private final int mColorInactive;
- private final int mColorDisabled;
- private int mCircleColor;
public QSTileBaseView(Context context, QSIconView icon) {
this(context, icon, false);
@@ -72,19 +67,11 @@
frame.setForegroundGravity(Gravity.CENTER);
int size = context.getResources().getDimensionPixelSize(R.dimen.qs_quick_tile_size);
addView(frame, new LayoutParams(size, size));
- mBg = new ImageView(getContext());
- mBg.setScaleType(ScaleType.FIT_CENTER);
- mBg.setImageResource(R.drawable.ic_qs_circle);
- frame.addView(mBg);
mIcon = icon;
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
params.setMargins(0, padding, 0, padding);
frame.addView(mIcon, params);
- mColorActive = Utils.getColorAttr(context, android.R.attr.textColorPrimary);
- mColorDisabled = Utils.getDisabled(context,
- Utils.getColorAttr(context, android.R.attr.textColorTertiary));
- mColorInactive = Utils.getColorAttr(context, android.R.attr.textColorSecondary);
mTileBackground = newTileBackground();
if (mTileBackground instanceof RippleDrawable) {
@@ -100,10 +87,6 @@
setFocusable(true);
}
- public View getBgCicle() {
- return mBg;
- }
-
protected Drawable newTileBackground() {
final int[] attrs = new int[]{android.R.attr.selectableItemBackgroundBorderless};
final TypedArray ta = getContext().obtainStyledAttributes(attrs);
@@ -167,16 +150,6 @@
}
protected void handleStateChanged(QSTile.State state) {
- int circleColor = getCircleColor(state.state);
- if (circleColor != mCircleColor) {
- if (mBg.isShown()) {
- QSIconView.animateGrayScale(mCircleColor, circleColor, mBg);
- } else {
- QSIconView.setTint(mBg, circleColor);
- }
- mCircleColor = circleColor;
- }
-
mIcon.setIcon(state);
if (mCollapsedView && !TextUtils.isEmpty(state.minimalContentDescription)) {
setContentDescription(state.minimalContentDescription);
@@ -193,19 +166,6 @@
}
}
- private int getCircleColor(int state) {
- switch (state) {
- case Tile.STATE_ACTIVE:
- return mColorActive;
- case Tile.STATE_INACTIVE:
- case Tile.STATE_UNAVAILABLE:
- return mColorDisabled;
- default:
- Log.e(TAG, "Invalid state " + state);
- return 0;
- }
- }
-
public QSIconView getIcon() {
return mIcon;
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java b/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java
index 7126f3c..232941d 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java
@@ -39,6 +39,7 @@
/** View that represents a standard quick settings tile. **/
public class QSTileView extends QSTileBaseView {
+ private final View mDivider;
protected TextView mLabel;
private ImageView mPadLock;
private int mState;
@@ -57,6 +58,8 @@
setClickable(true);
setId(View.generateViewId());
+ mDivider = LayoutInflater.from(context).inflate(R.layout.divider, this, false);
+ addView(mDivider);
createLabel();
setOrientation(VERTICAL);
setGravity(Gravity.CENTER);
@@ -95,6 +98,7 @@
mState = state.state;
mLabel.setText(state.label);
}
+ mDivider.setVisibility(state.dualTarget ? View.VISIBLE : View.INVISIBLE);
mLabel.setEnabled(!state.disabledByPolicy);
mPadLock.setVisibility(state.disabledByPolicy ? View.VISIBLE : View.GONE);
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
index 16b351e..d789b44 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
@@ -24,6 +24,7 @@
import android.widget.LinearLayout;
import android.widget.Space;
+import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.qs.QSTile.SignalState;
import com.android.systemui.qs.QSTile.State;
@@ -62,13 +63,13 @@
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
- TunerService.get(mContext).addTunable(mNumTiles, NUM_QUICK_TILES);
+ Dependency.get(TunerService.class).addTunable(mNumTiles, NUM_QUICK_TILES);
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
- TunerService.get(mContext).removeTunable(mNumTiles);
+ Dependency.get(TunerService.class).removeTunable(mNumTiles);
}
public void setQSPanelAndHeader(QSPanel fullPanel, View header) {
@@ -141,7 +142,7 @@
};
public int getNumQuickTiles(Context context) {
- return TunerService.get(context).getValue(NUM_QUICK_TILES, 6);
+ return Dependency.get(TunerService.class).getValue(NUM_QUICK_TILES, 6);
}
private static class HeaderTileLayout extends LinearLayout implements QSTileLayout {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java
index a5a1eaa..3b9e7bc 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java
@@ -99,8 +99,9 @@
record.tileView.measure(exactly(mCellWidth), exactly(mCellHeight));
previousView = record.tileView.updateAccessibilityOrder(previousView);
}
- setMeasuredDimension(width,
- (mCellHeight + mCellMargin) * rows + (mCellMarginTop - mCellMargin));
+ int height = (mCellHeight + mCellMargin) * rows + (mCellMarginTop - mCellMargin);
+ if (height < 0) height = 0;
+ setMeasuredDimension(width, height);
}
private static int exactly(int size) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java b/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java
index 3afbc35..dea56aa1 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java
@@ -237,6 +237,8 @@
i.setPackage(mComponent.getPackageName());
i = resolveIntent(i);
if (i != null) {
+ i.putExtra(TileService.EXTRA_COMPONENT, mComponent);
+ i.putExtra(TileService.EXTRA_STATE, mTile.getState());
return i;
}
return new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).setData(
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatteryTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatteryTile.java
index 06f4d9d..6f1f977 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatteryTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatteryTile.java
@@ -118,6 +118,7 @@
int level = (arg != null) ? (Integer) arg : mLevel;
String percentage = NumberFormat.getPercentInstance().format((double) level / 100.0);
+ state.dualTarget = true;
state.state = mCharging ? Tile.STATE_UNAVAILABLE
: mPowerSave ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE;
state.icon = ResourceIcon.get(R.drawable.ic_qs_battery_saver);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
index 91e76ca..4b56ecd 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
@@ -115,6 +115,7 @@
final boolean enabled = mController.isBluetoothEnabled();
final boolean connected = mController.isBluetoothConnected();
final boolean connecting = mController.isBluetoothConnecting();
+ state.dualTarget = true;
state.value = enabled;
state.autoMirrorDrawable = false;
state.minimalContentDescription =
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
index 7415765..a4cd14d 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
@@ -123,6 +123,7 @@
@Override
protected void handleUpdateState(BooleanState state, Object arg) {
+ state.dualTarget = true;
state.label = mContext.getString(R.string.quick_settings_cast_title);
state.contentDescription = state.label;
state.value = false;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
index bdc95c0..bae163f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
@@ -126,6 +126,7 @@
} else {
state.icon = ResourceIcon.get(iconId);
}
+ state.dualTarget = true;
state.isOverlayIconWide = cb.isDataTypeIconWide;
state.autoMirrorDrawable = !cb.noSim;
state.filter = iconId != R.drawable.ic_qs_no_sim;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
index 3c1f504..4072b44 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
@@ -159,6 +159,7 @@
final int zen = arg instanceof Integer ? (Integer) arg : mController.getZen();
final boolean newValue = zen != Global.ZEN_MODE_OFF;
final boolean valueChanged = state.value != newValue;
+ state.dualTarget = true;
state.value = newValue;
state.state = state.value ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE;
checkIfRestrictionEnforcedByAdminOnly(state, UserManager.DISALLOW_ADJUST_VOLUME);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
index 70f8109..dab5967 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
@@ -16,6 +16,9 @@
package com.android.systemui.qs.tiles;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.UserManager;
@@ -37,6 +40,9 @@
/** Quick settings tile: Hotspot **/
public class HotspotTile extends QSTile<QSTile.AirplaneBooleanState> {
+ static final Intent TETHER_SETTINGS = new Intent().setComponent(new ComponentName(
+ "com.android.settings", "com.android.settings.TetherSettings"));
+
private final AnimationIcon mEnable =
new AnimationIcon(R.drawable.ic_hotspot_enable_animation,
R.drawable.ic_hotspot_disable);
@@ -94,7 +100,7 @@
@Override
public Intent getLongClickIntent() {
- return new Intent(Settings.ACTION_WIRELESS_SETTINGS);
+ return new Intent(TETHER_SETTINGS);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
index 2d61857..90a9db6 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
@@ -150,6 +150,7 @@
mDetailAdapter.setItemsVisible(cb.enabled);
fireToggleStateChanged(cb.enabled);
}
+ state.dualTarget = true;
state.value = cb.enabled;
state.connected = wifiConnected;
state.activityIn = cb.enabled && cb.activityIn;
diff --git a/packages/SystemUI/src/com/android/systemui/recents/Recents.java b/packages/SystemUI/src/com/android/systemui/recents/Recents.java
index 8d18a75..e635162 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/Recents.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/Recents.java
@@ -16,6 +16,8 @@
package com.android.systemui.recents;
+import static com.android.systemui.statusbar.phone.StatusBar.SYSTEM_DIALOG_REASON_RECENT_APPS;
+
import android.app.ActivityManager;
import android.app.UiModeManager;
import android.content.ComponentName;
@@ -38,6 +40,7 @@
import android.util.EventLog;
import android.util.Log;
import android.view.Display;
+import android.view.WindowManager;
import android.widget.Toast;
import com.android.internal.logging.MetricsLogger;
@@ -59,6 +62,7 @@
import com.android.systemui.recents.model.RecentsTaskLoader;
import com.android.systemui.recents.tv.RecentsTvImpl;
import com.android.systemui.stackdivider.Divider;
+import com.android.systemui.statusbar.CommandQueue;
import java.util.ArrayList;
import java.util.HashSet;
@@ -70,7 +74,7 @@
* users.
*/
public class Recents extends SystemUI
- implements RecentsComponent {
+ implements RecentsComponent, CommandQueue.Callbacks {
private final static String TAG = "Recents";
private final static boolean DEBUG = false;
@@ -229,6 +233,7 @@
if (sSystemServicesProxy.isSystemUser(processUser)) {
// For the system user, initialize an instance of the interface that we can pass to the
// secondary user
+ getComponent(CommandQueue.class).addCallbacks(this);
mSystemToUserCallbacks = new RecentsSystemUser(mContext, mImpl);
} else {
// For the secondary user, bind to the primary user's service to get a persistent
@@ -247,7 +252,7 @@
* Shows the Recents.
*/
@Override
- public void showRecents(boolean triggeredFromAltTab, boolean fromHome) {
+ public void showRecentApps(boolean triggeredFromAltTab, boolean fromHome) {
// Ensure the device has been provisioned before allowing the user to interact with
// recents
if (!isUserSetup()) {
@@ -257,6 +262,10 @@
if (proxyToOverridePackage(ACTION_SHOW_RECENTS)) {
return;
}
+ try {
+ ActivityManager.getService().closeSystemDialogs(SYSTEM_DIALOG_REASON_RECENT_APPS);
+ } catch (RemoteException e) {
+ }
int recentsGrowTarget = getComponent(Divider.class).getView().growsRecents();
@@ -287,7 +296,7 @@
* Hides the Recents.
*/
@Override
- public void hideRecents(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) {
+ public void hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) {
// Ensure the device has been provisioned before allowing the user to interact with
// recents
if (!isUserSetup()) {
@@ -318,6 +327,11 @@
}
}
+ @Override
+ public void toggleRecentApps() {
+ toggleRecents(mContext.getSystemService(WindowManager.class).getDefaultDisplay());
+ }
+
/**
* Toggles the Recents activity.
*/
@@ -387,7 +401,7 @@
}
@Override
- public void cancelPreloadingRecents() {
+ public void cancelPreloadRecentApps() {
// Ensure the device has been provisioned before allowing the user to interact with
// recents
if (!isUserSetup()) {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
index 9a8b267..8091199 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
@@ -53,6 +53,7 @@
import com.android.systemui.recents.events.activity.EnterRecentsWindowLastAnimationFrameEvent;
import com.android.systemui.recents.events.activity.HideRecentsEvent;
import com.android.systemui.recents.events.activity.IterateRecentsEvent;
+import com.android.systemui.recents.events.activity.LaunchMostRecentTaskRequestEvent;
import com.android.systemui.recents.events.activity.LaunchNextTaskRequestEvent;
import com.android.systemui.recents.events.activity.RecentsActivityStartingEvent;
import com.android.systemui.recents.events.activity.ToggleRecentsEvent;
@@ -75,6 +76,7 @@
import com.android.systemui.recents.views.TaskStackViewScroller;
import com.android.systemui.recents.views.TaskViewHeader;
import com.android.systemui.recents.views.TaskViewTransform;
+import com.android.systemui.recents.views.grid.TaskGridLayoutAlgorithm;
import com.android.systemui.stackdivider.DividerView;
import com.android.systemui.statusbar.phone.NavigationBarGestureHelper;
import com.android.systemui.statusbar.phone.StatusBar;
@@ -311,15 +313,23 @@
RecentsConfiguration config = Recents.getConfiguration();
RecentsActivityLaunchState launchState = config.getLaunchState();
if (!launchState.launchedWithAltTab) {
- // If the user taps quickly
- if (!debugFlags.isPagingEnabled() ||
- (ViewConfiguration.getDoubleTapMinTime() < elapsedTime &&
- elapsedTime < ViewConfiguration.getDoubleTapTimeout())) {
- // Launch the next focused task
- EventBus.getDefault().post(new LaunchNextTaskRequestEvent());
+ // Has the user tapped quickly?
+ boolean isQuickTap = ViewConfiguration.getDoubleTapMinTime() < elapsedTime &&
+ elapsedTime < ViewConfiguration.getDoubleTapTimeout();
+ if (Recents.getConfiguration().isGridEnabled) {
+ if (isQuickTap) {
+ EventBus.getDefault().post(new LaunchNextTaskRequestEvent());
+ } else {
+ EventBus.getDefault().post(new LaunchMostRecentTaskRequestEvent());
+ }
} else {
- // Notify recents to move onto the next task
- EventBus.getDefault().post(new IterateRecentsEvent());
+ if (!debugFlags.isPagingEnabled() || isQuickTap) {
+ // Launch the next focused task
+ EventBus.getDefault().post(new LaunchNextTaskRequestEvent());
+ } else {
+ // Notify recents to move onto the next task
+ EventBus.getDefault().post(new IterateRecentsEvent());
+ }
}
} else {
// If the user has toggled it too quickly, then just eat up the event here (it's
@@ -628,10 +638,21 @@
stackLayout.initialize(displayRect, windowRect, mTaskStackBounds,
TaskStackLayoutAlgorithm.StackState.getStackStateForStack(stack));
mDummyStackView.setTasks(stack, false /* allowNotifyStackChanges */);
+ // Get the width of a task view so that we know how wide to draw the header bar.
+ int taskViewWidth = 0;
+ if (mDummyStackView.useGridLayout()) {
+ TaskGridLayoutAlgorithm gridLayout = mDummyStackView.getGridAlgorithm();
+ gridLayout.initialize(windowRect);
+ taskViewWidth = (int) gridLayout.getTransform(0 /* taskIndex */,
+ stack.getTaskCount(), new TaskViewTransform(), stackLayout).rect.width();
+ } else {
+ Rect taskViewBounds = stackLayout.getUntransformedTaskViewBounds();
+ if (!taskViewBounds.isEmpty()) {
+ taskViewWidth = taskViewBounds.width();
+ }
+ }
- Rect taskViewBounds = stackLayout.getUntransformedTaskViewBounds();
- if (!taskViewBounds.isEmpty()) {
- int taskViewWidth = taskViewBounds.width();
+ if (taskViewWidth > 0) {
synchronized (mHeaderBarLock) {
if (mHeaderBar.getMeasuredWidth() != taskViewWidth ||
mHeaderBar.getMeasuredHeight() != mTaskBarHeight) {
@@ -743,11 +764,7 @@
Task toTask = new Task();
TaskViewTransform toTransform = getThumbnailTransitionTransform(stackView, toTask,
windowOverrideRect);
- // When using a grid layout, the header is already visible on screen at the target
- // location, making it unnecessary to draw it in the transition thumbnail.
- Bitmap thumbnail = stackView.useGridLayout()
- ? mThumbTransitionBitmapCache.createAshmemBitmap()
- : drawThumbnailTransitionBitmap(toTask, toTransform,
+ Bitmap thumbnail = drawThumbnailTransitionBitmap(toTask, toTransform,
mThumbTransitionBitmapCache);
if (thumbnail != null) {
RectF toTaskRect = toTransform.rect;
diff --git a/core/java/android/service/autofill/CallbackHelper.java b/packages/SystemUI/src/com/android/systemui/recents/events/activity/LaunchMostRecentTaskRequestEvent.java
similarity index 68%
copy from core/java/android/service/autofill/CallbackHelper.java
copy to packages/SystemUI/src/com/android/systemui/recents/events/activity/LaunchMostRecentTaskRequestEvent.java
index ded8f97..24913a4 100644
--- a/core/java/android/service/autofill/CallbackHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/events/activity/LaunchMostRecentTaskRequestEvent.java
@@ -13,18 +13,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package android.service.autofill;
-import java.io.PrintWriter;
+package com.android.systemui.recents.events.activity;
-final class CallbackHelper {
+import com.android.systemui.recents.events.EventBus;
- static interface Dumpable {
- void dump(String prefix, PrintWriter pw);
- void setFinalizer(Finalizer f);
- }
-
- static interface Finalizer {
- void gone();
- }
+/**
+ * This event is sent to request that the most recent task is launched.
+ */
+public class LaunchMostRecentTaskRequestEvent extends EventBus.Event {
+ // Simple event
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackAnimationHelper.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackAnimationHelper.java
index a2ee4c5..f1314aba 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackAnimationHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackAnimationHelper.java
@@ -619,7 +619,7 @@
postAnimationTrigger.addLastDecrementRunnable(() -> {
mStackView.getTouchHandler().onChildDismissed(deleteTaskView);
});
- deleteTaskView.animate().setDuration(300).scaleX(0).scaleY(0).alpha(0).setListener(
+ deleteTaskView.animate().setDuration(300).scaleX(0.9f).scaleY(0.9f).alpha(0).setListener(
new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
index 8ae7a83..0160eb7 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
@@ -64,6 +64,7 @@
import com.android.systemui.recents.events.activity.HideRecentsEvent;
import com.android.systemui.recents.events.activity.HideStackActionButtonEvent;
import com.android.systemui.recents.events.activity.IterateRecentsEvent;
+import com.android.systemui.recents.events.activity.LaunchMostRecentTaskRequestEvent;
import com.android.systemui.recents.events.activity.LaunchNextTaskRequestEvent;
import com.android.systemui.recents.events.activity.LaunchTaskEvent;
import com.android.systemui.recents.events.activity.LaunchTaskStartedEvent;
@@ -95,6 +96,7 @@
import com.android.systemui.recents.model.TaskStack;
import com.android.systemui.recents.views.grid.GridTaskView;
+import com.android.systemui.recents.views.grid.TaskGridLayoutAlgorithm;
import com.android.systemui.recents.views.grid.TaskViewFocusFrame;
import java.io.PrintWriter;
import java.lang.annotation.Retention;
@@ -446,6 +448,11 @@
return mLayoutAlgorithm;
}
+ /** Returns the grid algorithm for this task stack. */
+ public TaskGridLayoutAlgorithm getGridAlgorithm() {
+ return mLayoutAlgorithm.mTaskGridLayoutAlgorithm;
+ }
+
/**
* Returns the touch handler for this task stack.
*/
@@ -1733,6 +1740,13 @@
mUIDozeTrigger.stopDozing();
}
+ public final void onBusEvent(LaunchMostRecentTaskRequestEvent event) {
+ if (mStack.getTaskCount() > 0) {
+ Task mostRecentTask = mStack.getStackFrontMostTask(true /* includeFreefromTasks */);
+ launchTask(mostRecentTask);
+ }
+ }
+
public final void onBusEvent(LaunchNextTaskRequestEvent event) {
if (mAwaitingFirstLayout) {
mLaunchNextAfterFirstMeasure = true;
@@ -1741,29 +1755,7 @@
final Task launchTask = mStack.getNextLaunchTarget();
if (launchTask != null) {
- // Stop all animations
- cancelAllTaskViewAnimations();
-
- float curScroll = mStackScroller.getStackScroll();
- float targetScroll = mLayoutAlgorithm.getStackScrollForTaskAtInitialOffset(launchTask);
- float absScrollDiff = Math.abs(targetScroll - curScroll);
- if (getChildViewForTask(launchTask) == null || absScrollDiff > 0.35f) {
- int duration = (int) (LAUNCH_NEXT_SCROLL_BASE_DURATION +
- absScrollDiff * LAUNCH_NEXT_SCROLL_INCR_DURATION);
- mStackScroller.animateScroll(targetScroll,
- duration, new Runnable() {
- @Override
- public void run() {
- EventBus.getDefault().send(new LaunchTaskEvent(
- getChildViewForTask(launchTask), launchTask, null,
- INVALID_STACK_ID, false /* screenPinningRequested */));
- }
- });
- } else {
- EventBus.getDefault().send(new LaunchTaskEvent(getChildViewForTask(launchTask),
- launchTask, null, INVALID_STACK_ID, false /* screenPinningRequested */));
- }
-
+ launchTask(launchTask);
MetricsLogger.action(getContext(), MetricsEvent.OVERVIEW_LAUNCH_PREVIOUS_TASK,
launchTask.key.getComponent().toString());
} else if (mStack.getTaskCount() == 0) {
@@ -2215,6 +2207,31 @@
return -1;
}
+ private void launchTask(Task task) {
+ // Stop all animations
+ cancelAllTaskViewAnimations();
+
+ float curScroll = mStackScroller.getStackScroll();
+ float targetScroll = mLayoutAlgorithm.getStackScrollForTaskAtInitialOffset(task);
+ float absScrollDiff = Math.abs(targetScroll - curScroll);
+ if (getChildViewForTask(task) == null || absScrollDiff > 0.35f) {
+ int duration = (int) (LAUNCH_NEXT_SCROLL_BASE_DURATION +
+ absScrollDiff * LAUNCH_NEXT_SCROLL_INCR_DURATION);
+ mStackScroller.animateScroll(targetScroll,
+ duration, new Runnable() {
+ @Override
+ public void run() {
+ EventBus.getDefault().send(new LaunchTaskEvent(
+ getChildViewForTask(task), task, null,
+ INVALID_STACK_ID, false /* screenPinningRequested */));
+ }
+ });
+ } else {
+ EventBus.getDefault().send(new LaunchTaskEvent(getChildViewForTask(task),
+ task, null, INVALID_STACK_ID, false /* screenPinningRequested */));
+ }
+ }
+
/**
* Check whether we should use the grid layout.
*/
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
index 7135caf..9a4b45a 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
@@ -178,20 +178,19 @@
.bigPicture(picture.createAshmemBitmap());
// The public notification will show similar info but with the actual screenshot omitted
- mPublicNotificationBuilder = new Notification.Builder(context)
- .setChannel(NotificationChannels.SCREENSHOTS)
- .setContentTitle(r.getString(R.string.screenshot_saving_title))
- .setContentText(r.getString(R.string.screenshot_saving_text))
- .setSmallIcon(R.drawable.stat_notify_image)
- .setCategory(Notification.CATEGORY_PROGRESS)
- .setWhen(now)
- .setShowWhen(true)
- .setColor(r.getColor(
- com.android.internal.R.color.system_notification_accent_color));
+ mPublicNotificationBuilder =
+ new Notification.Builder(context, NotificationChannels.SCREENSHOTS)
+ .setContentTitle(r.getString(R.string.screenshot_saving_title))
+ .setContentText(r.getString(R.string.screenshot_saving_text))
+ .setSmallIcon(R.drawable.stat_notify_image)
+ .setCategory(Notification.CATEGORY_PROGRESS)
+ .setWhen(now)
+ .setShowWhen(true)
+ .setColor(r.getColor(
+ com.android.internal.R.color.system_notification_accent_color));
SystemUI.overrideNotificationAppName(context, mPublicNotificationBuilder);
- mNotificationBuilder = new Notification.Builder(context)
- .setChannel(NotificationChannels.SCREENSHOTS)
+ mNotificationBuilder = new Notification.Builder(context, NotificationChannels.SCREENSHOTS)
.setTicker(r.getString(R.string.screenshot_saving_ticker)
+ (mTickerAddSpace ? " " : ""))
.setContentTitle(r.getString(R.string.screenshot_saving_title))
@@ -335,7 +334,6 @@
// Update the text and the icon for the existing notification
mPublicNotificationBuilder
- .setChannel(NotificationChannels.SCREENSHOTS)
.setContentTitle(r.getString(R.string.screenshot_saved_title))
.setContentText(r.getString(R.string.screenshot_saved_text))
.setContentIntent(PendingIntent.getActivity(mParams.context, 0, launchIntent, 0))
@@ -344,7 +342,6 @@
.setColor(context.getColor(
com.android.internal.R.color.system_notification_accent_color));
mNotificationBuilder
- .setChannel(NotificationChannels.SCREENSHOTS)
.setContentTitle(r.getString(R.string.screenshot_saved_title))
.setContentText(r.getString(R.string.screenshot_saved_text))
.setContentIntent(PendingIntent.getActivity(mParams.context, 0, launchIntent, 0))
@@ -858,7 +855,7 @@
String errorMsg = r.getString(msgResId);
// Repurpose the existing notification to notify the user of the error
- Notification.Builder b = new Notification.Builder(context)
+ Notification.Builder b = new Notification.Builder(context, NotificationChannels.ALERTS)
.setTicker(r.getString(R.string.screenshot_failed_title))
.setContentTitle(r.getString(R.string.screenshot_failed_title))
.setContentText(errorMsg)
diff --git a/packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyDispatcher.java b/packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyDispatcher.java
index 19eefec..7699bb9 100644
--- a/packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyDispatcher.java
+++ b/packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyDispatcher.java
@@ -107,7 +107,7 @@
List<ActivityManager.RecentTaskInfo> taskList =
SystemServicesProxy.getInstance(mContext).getRecentTasks(1,
UserHandle.USER_CURRENT, false, new ArraySet<>());
- recents.showRecents(
+ recents.showRecentApps(
false /* triggeredFromAltTab */,
false /* fromHome */);
if (!taskList.isEmpty()) {
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java b/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java
index b9a0f74..0b09acc 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java
@@ -72,6 +72,10 @@
return mMinimized;
}
+ public boolean isHomeStackResizable() {
+ return mHomeStackResizable;
+ }
+
private void addDivider(Configuration configuration) {
mView = (DividerView)
LayoutInflater.from(mContext).inflate(R.layout.docked_stack_divider, null);
@@ -119,6 +123,7 @@
mView.post(new Runnable() {
@Override
public void run() {
+ mHomeStackResizable = isHomeStackResizable;
if (mMinimized != minimized) {
mMinimized = minimized;
updateTouchable();
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
index 49035ba..6f59fe2 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
@@ -1241,7 +1241,8 @@
public final void onBusEvent(UndockingTaskEvent undockingTaskEvent) {
int dockSide = mWindowManagerProxy.getDockSide();
- if (dockSide != WindowManager.DOCKED_INVALID && !mDockedStackMinimized) {
+ if (dockSide != WindowManager.DOCKED_INVALID && (mHomeStackResizable
+ || !mDockedStackMinimized)) {
startDragging(false /* animate */, false /* touching */);
SnapTarget target = dockSideTopLeft(dockSide)
? mSnapAlgorithm.getDismissEndTarget()
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
index b9ed725..0bd6491 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
@@ -38,7 +38,6 @@
import com.android.systemui.classifier.FalsingManager;
import com.android.systemui.statusbar.notification.FakeShadowView;
import com.android.systemui.statusbar.notification.NotificationUtils;
-import com.android.systemui.statusbar.policy.AccessibilityController;
import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
import com.android.systemui.statusbar.stack.StackStateAnimator;
@@ -106,7 +105,7 @@
private boolean mDimmed;
private boolean mDark;
- private int mBgTint = NO_COLOR;
+ protected int mBgTint = NO_COLOR;
private float mBgAlpha = 1f;
/**
@@ -140,8 +139,6 @@
private ValueAnimator mBackgroundColorAnimator;
private float mAppearAnimationFraction = -1.0f;
private float mAppearAnimationTranslation;
- private boolean mShowingLegacyBackground;
- private final int mLegacyColor;
private final int mNormalColor;
private final int mLowPriorityColor;
private boolean mIsBelowSpeedBump;
@@ -192,7 +189,6 @@
mSlowOutLinearInInterpolator = new PathInterpolator(0.8f, 0.0f, 1.0f, 1.0f);
setClipChildren(false);
setClipToPadding(false);
- mLegacyColor = context.getColor(R.color.notification_legacy_background_color);
mNormalColor = context.getColor(R.color.notification_material_background_color);
mLowPriorityColor = context.getColor(
R.color.notification_material_background_low_priority_color);
@@ -489,11 +485,6 @@
updateOutlineAlpha();
}
- public void setShowingLegacyBackground(boolean showing) {
- mShowingLegacyBackground = showing;
- updateBackgroundTint();
- }
-
@Override
public void setBelowSpeedBump(boolean below) {
super.setBelowSpeedBump(below);
@@ -950,8 +941,6 @@
}
if (withTint && mBgTint != NO_COLOR) {
return mBgTint;
- } else if (mShowingLegacyBackground) {
- return mLegacyColor;
} else if (mIsBelowSpeedBump) {
return mLowPriorityColor;
} else {
@@ -962,8 +951,6 @@
protected int getRippleColor() {
if (mBgTint != 0) {
return mTintedRippleColor;
- } else if (mShowingLegacyBackground) {
- return mTintedRippleColor;
} else if (mIsBelowSpeedBump) {
return mLowPriorityRippleColor;
} else {
@@ -1009,7 +996,6 @@
public void reset() {
setTintColor(0);
resetBackgroundAlpha();
- setShowingLegacyBackground(false);
setBelowSpeedBump(false);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
index 477701c..9245df0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
@@ -63,9 +63,6 @@
private static final int MSG_SET_WINDOW_STATE = 12 << MSG_SHIFT;
private static final int MSG_SHOW_RECENT_APPS = 13 << MSG_SHIFT;
private static final int MSG_HIDE_RECENT_APPS = 14 << MSG_SHIFT;
- private static final int MSG_BUZZ_BEEP_BLINKED = 15 << MSG_SHIFT;
- private static final int MSG_NOTIFICATION_LIGHT_OFF = 16 << MSG_SHIFT;
- private static final int MSG_NOTIFICATION_LIGHT_PULSE = 17 << MSG_SHIFT;
private static final int MSG_SHOW_SCREEN_PIN_REQUEST = 18 << MSG_SHIFT;
private static final int MSG_APP_TRANSITION_PENDING = 19 << MSG_SHIFT;
private static final int MSG_APP_TRANSITION_CANCELLED = 20 << MSG_SHIFT;
@@ -121,9 +118,6 @@
default void toggleKeyboardShortcutsMenu(int deviceId) { }
default void cancelPreloadRecentApps() { }
default void setWindowState(int window, int state) { }
- default void buzzBeepBlinked() { }
- default void notificationLightOff() { }
- default void notificationLightPulse(int argb, int onMillis, int offMillis) { }
default void showScreenPinningRequest(int taskId) { }
default void appTransitionPending() { }
default void appTransitionCancelled() { }
@@ -313,26 +307,6 @@
}
}
- public void buzzBeepBlinked() {
- synchronized (mLock) {
- mHandler.removeMessages(MSG_BUZZ_BEEP_BLINKED);
- mHandler.sendEmptyMessage(MSG_BUZZ_BEEP_BLINKED);
- }
- }
-
- public void notificationLightOff() {
- synchronized (mLock) {
- mHandler.sendEmptyMessage(MSG_NOTIFICATION_LIGHT_OFF);
- }
- }
-
- public void notificationLightPulse(int argb, int onMillis, int offMillis) {
- synchronized (mLock) {
- mHandler.obtainMessage(MSG_NOTIFICATION_LIGHT_PULSE, onMillis, offMillis, argb)
- .sendToTarget();
- }
- }
-
public void showScreenPinningRequest(int taskId) {
synchronized (mLock) {
mHandler.obtainMessage(MSG_SHOW_SCREEN_PIN_REQUEST, taskId, 0, null)
@@ -524,21 +498,6 @@
mCallbacks.get(i).setWindowState(msg.arg1, msg.arg2);
}
break;
- case MSG_BUZZ_BEEP_BLINKED:
- for (int i = 0; i < mCallbacks.size(); i++) {
- mCallbacks.get(i).buzzBeepBlinked();
- }
- break;
- case MSG_NOTIFICATION_LIGHT_OFF:
- for (int i = 0; i < mCallbacks.size(); i++) {
- mCallbacks.get(i).notificationLightOff();
- }
- break;
- case MSG_NOTIFICATION_LIGHT_PULSE:
- for (int i = 0; i < mCallbacks.size(); i++) {
- mCallbacks.get(i).notificationLightPulse((Integer) msg.obj, msg.arg1, msg.arg2);
- }
- break;
case MSG_SHOW_SCREEN_PIN_REQUEST:
for (int i = 0; i < mCallbacks.size(); i++) {
mCallbacks.get(i).showScreenPinningRequest(msg.arg1);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
index d1245b1..2e9c7fd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
@@ -77,6 +77,7 @@
private int mMaxHeadsUpHeightLegacy;
private int mMaxHeadsUpHeight;
private int mNotificationMinHeight;
+ private int mNotificationMinHeightLarge;
private int mNotificationMaxHeight;
private int mNotificationAmbientHeight;
private int mIncreasedPaddingBetweenElements;
@@ -207,6 +208,7 @@
private Runnable mOnDismissRunnable;
private boolean mIsLowPriority;
private boolean mIsColorized;
+ private boolean mUseIncreasedCollapsedHeight;
@Override
public boolean isGroupExpansionChanging() {
@@ -341,8 +343,14 @@
boolean customView = layout.getContractedChild().getId()
!= com.android.internal.R.id.status_bar_latest_event_content;
boolean beforeN = mEntry.targetSdk < Build.VERSION_CODES.N;
- int minHeight = customView && beforeN && !mIsSummaryWithChildren ?
- mNotificationMinHeightLegacy : mNotificationMinHeight;
+ int minHeight;
+ if (customView && beforeN && !mIsSummaryWithChildren) {
+ minHeight = mNotificationMinHeightLegacy;
+ } else if (mUseIncreasedCollapsedHeight && layout == mPrivateLayout) {
+ minHeight = mNotificationMinHeightLarge;
+ } else {
+ minHeight = mNotificationMinHeight;
+ }
boolean headsUpCustom = layout.getHeadsUpChild() != null &&
layout.getHeadsUpChild().getId()
!= com.android.internal.R.id.status_bar_latest_event_content;
@@ -979,6 +987,10 @@
}
}
+ public void setUseIncreasedCollapsedHeight(boolean use) {
+ mUseIncreasedCollapsedHeight = use;
+ }
+
public interface ExpansionLogger {
public void logNotificationExpansion(String key, boolean userAction, boolean expanded);
}
@@ -992,6 +1004,8 @@
private void initDimens() {
mNotificationMinHeightLegacy = getFontScaledHeight(R.dimen.notification_min_height_legacy);
mNotificationMinHeight = getFontScaledHeight(R.dimen.notification_min_height);
+ mNotificationMinHeightLarge = getFontScaledHeight(
+ R.dimen.notification_min_height_large);
mNotificationMaxHeight = getFontScaledHeight(R.dimen.notification_max_height);
mNotificationAmbientHeight = getFontScaledHeight(R.dimen.notification_ambient_height);
mMaxHeadsUpHeightLegacy = getFontScaledHeight(
@@ -1782,9 +1796,7 @@
return mShowingPublic ? mPublicLayout : mPrivateLayout;
}
- @Override
public void setShowingLegacyBackground(boolean showing) {
- super.setShowingLegacyBackground(showing);
for (NotificationContentView l : mLayouts) {
l.setShowingLegacyBackground(showing);
}
@@ -1868,14 +1880,14 @@
} else if (isUserLocked()) {
return mChildrenContainer.getGroupExpandFraction();
}
- } else if (isColorized()) {
+ } else if (isColorized() && (!mIsLowPriority || isExpanded())) {
return -1.0f;
}
return 0.0f;
}
private boolean isColorized() {
- return mIsColorized;
+ return mIsColorized && mBgTint != NO_COLOR;
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
index e0ddf13..57d2e1c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
@@ -505,7 +505,8 @@
isTransitioningFromTo(VISIBLE_TYPE_HEADSUP, VISIBLE_TYPE_EXPANDED) ||
isTransitioningFromTo(VISIBLE_TYPE_EXPANDED, VISIBLE_TYPE_HEADSUP);
boolean pinned = !isVisibleOrTransitioning(VISIBLE_TYPE_CONTRACTED)
- && (mIsHeadsUp || mHeadsUpAnimatingAway);
+ && (mIsHeadsUp || mHeadsUpAnimatingAway)
+ && !mContainingNotification.isOnKeyguard();
if (transitioningBetweenHunAndExpanded || pinned) {
return Math.min(mHeadsUpChild.getHeight(), mExpandedChild.getHeight());
}
@@ -611,7 +612,7 @@
public int getMaxHeight() {
if (mExpandedChild != null) {
return mExpandedChild.getHeight();
- } else if (mIsHeadsUp && mHeadsUpChild != null) {
+ } else if (mIsHeadsUp && mHeadsUpChild != null && !mContainingNotification.isOnKeyguard()) {
return mHeadsUpChild.getHeight();
}
return mContractedChild.getHeight();
@@ -921,7 +922,8 @@
return VISIBLE_TYPE_SINGLELINE;
}
- if ((mIsHeadsUp || mHeadsUpAnimatingAway) && mHeadsUpChild != null) {
+ if ((mIsHeadsUp || mHeadsUpAnimatingAway) && mHeadsUpChild != null
+ && !mContainingNotification.isOnKeyguard()) {
if (viewHeight <= mHeadsUpChild.getHeight() || noExpandedChild) {
return VISIBLE_TYPE_HEADSUP;
} else {
@@ -1174,7 +1176,7 @@
mExpandable = expandable;
// if the expanded child has the same height as the collapsed one we hide it.
if (mExpandedChild != null && mExpandedChild.getHeight() != 0) {
- if ((!mIsHeadsUp || mHeadsUpChild == null)) {
+ if (!mIsHeadsUp || mHeadsUpChild == null || mContainingNotification.isOnKeyguard()) {
if (mExpandedChild.getHeight() == mContractedChild.getHeight()) {
expandable = false;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
index b49ba0c..f73a5ea 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
@@ -126,13 +126,13 @@
}
public boolean cacheContentViews(Context ctx, Notification updatedNotification,
- boolean isLowPriority) {
+ boolean isLowPriority, boolean useIncreasedCollapsedView) {
boolean applyInPlace = false;
if (updatedNotification != null) {
final Notification.Builder updatedNotificationBuilder
= Notification.Builder.recoverBuilder(ctx, updatedNotification);
final RemoteViews newContentView = createContentView(updatedNotificationBuilder,
- isLowPriority);
+ isLowPriority, useIncreasedCollapsedView);
final RemoteViews newBigContentView = createBigContentView(
updatedNotificationBuilder, isLowPriority);
final RemoteViews newHeadsUpContentView =
@@ -162,7 +162,8 @@
final Notification.Builder builder
= Notification.Builder.recoverBuilder(ctx, notification.getNotification());
- cachedContentView = createContentView(builder, isLowPriority);
+ cachedContentView = createContentView(builder, isLowPriority,
+ useIncreasedCollapsedView);
cachedBigContentView = createBigContentView(builder, isLowPriority);
cachedHeadsUpContentView = builder.createHeadsUpContentView();
cachedPublicContentView = builder.makePublicContentView();
@@ -188,11 +189,11 @@
}
private RemoteViews createContentView(Notification.Builder builder,
- boolean isAmbient) {
- if (isAmbient) {
+ boolean isLowPriority, boolean useLarge) {
+ if (isLowPriority) {
return builder.makeLowPriorityContentView(false /* useRegularSubtext */);
}
- return builder.createContentView();
+ return builder.createContentView(useLarge);
}
// Returns true if the RemoteViews are the same.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMenuRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMenuRow.java
index fad63dd..355022f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMenuRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMenuRow.java
@@ -30,6 +30,7 @@
import java.util.ArrayList;
+import com.android.systemui.Dependency;
import com.android.systemui.Interpolators;
import com.android.systemui.R;
import com.android.systemui.plugins.PluginListener;
@@ -82,10 +83,21 @@
public NotificationMenuRow(Context context, AttributeSet attrs, int defStyleAttr,
int defStyleRes) {
super(context, attrs);
- PluginManager.getInstance(getContext()).addPluginListener(
+ mMenuItems.addAll(getDefaultNotificationMenuItems());
+ }
+
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ Dependency.get(PluginManager.class).addPluginListener(
NotificationMenuRowProvider.ACTION, this,
NotificationMenuRowProvider.VERSION, false /* Allow multiple */);
- mMenuItems.addAll(getDefaultNotificationMenuItems());
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ Dependency.get(PluginManager.class).removePluginListener(this);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
index e8e9d4e..2425076 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
@@ -68,6 +68,7 @@
private float mMaxShelfEnd;
private int mRelativeOffset;
private boolean mInteractive;
+ private boolean mAnimationsEnabled = true;
public NotificationShelf(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -388,12 +389,13 @@
View rowIcon = row.getNotificationIcon();
float notificationIconPosition = row.getTranslationY() + row.getContentTranslation();
- if (usingLinearInterpolation) {
+ boolean stayingInShelf = row.isInShelf() && !row.isTransformingIntoShelf();
+ if (usingLinearInterpolation && !stayingInShelf) {
// If we interpolate from the notification position, this might lead to a slightly
// odd interpolation, since the notification position changes as well. Let's interpolate
// from a fixed distance. We can only do this if we don't animate and the icon is
// always in the interpolated positon.
- notificationIconPosition = mMaxShelfEnd - getIntrinsicHeight() - iconTransformDistance;
+ notificationIconPosition = getTranslationY() - iconTransformDistance;
}
float notificationIconSize = 0.0f;
int iconTopPadding;
@@ -426,7 +428,7 @@
iconState.hidden = transitionAmount == 0.0f;
iconState.alpha = alpha;
iconState.yTranslation = iconYTranslation;
- if (row.isInShelf() && !row.isTransformingIntoShelf()) {
+ if (stayingInShelf) {
iconState.iconAppearAmount = 1.0f;
iconState.alpha = 1.0f;
iconState.scaleX = 1.0f;
@@ -573,6 +575,15 @@
mMaxShelfEnd = maxShelfEnd;
}
+ public void setAnimationsEnabled(boolean enabled) {
+ mAnimationsEnabled = enabled;
+ mCollapsedIcons.setAnimationsEnabled(enabled);
+ if (!enabled) {
+ // we need to wait with enabling the animations until the first frame has passed
+ mShelfIcons.setAnimationsEnabled(false);
+ }
+ }
+
private class ShelfState extends ExpandableViewState {
private float openedAmount;
private boolean hasItemsInStableShelf;
@@ -585,6 +596,7 @@
setOpenedAmount(openedAmount);
updateAppearance();
setHasItemsInStableShelf(hasItemsInStableShelf);
+ mShelfIcons.setAnimationsEnabled(mAnimationsEnabled);
}
@Override
@@ -594,6 +606,7 @@
setOpenedAmount(openedAmount);
updateAppearance();
setHasItemsInStableShelf(hasItemsInStableShelf);
+ mShelfIcons.setAnimationsEnabled(mAnimationsEnabled);
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ScrimView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ScrimView.java
index dba7130..f9d0cd6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ScrimView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ScrimView.java
@@ -20,6 +20,7 @@
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.content.Context;
+import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
@@ -29,6 +30,7 @@
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.Interpolator;
+import com.android.systemui.R;
/**
* A view which can draw a scrim
@@ -73,6 +75,14 @@
public ScrimView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
+
+ TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.ScrimView);
+
+ try {
+ mScrimColor = ta.getColor(R.styleable.ScrimView_scrimColor, Color.BLACK);
+ } finally {
+ ta.recycle();
+ }
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
index 9a76ad6..45eb5df 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
@@ -220,7 +220,7 @@
int endPadding = mMobileSignalGroup.getChildCount() > 0 ? mMobileSignalGroupEndPadding : 0;
mMobileSignalGroup.setPaddingRelative(0, 0, endPadding, 0);
- TunerService.get(mContext).addTunable(this, StatusBarIconController.ICON_BLACKLIST);
+ Dependency.get(TunerService.class).addTunable(this, StatusBarIconController.ICON_BLACKLIST);
apply();
applyIconTint();
@@ -231,7 +231,7 @@
@Override
protected void onDetachedFromWindow() {
mMobileSignalGroup.removeAllViews();
- TunerService.get(mContext).removeTunable(this);
+ Dependency.get(TunerService.class).removeTunable(this);
mSecurityController.removeCallback(this);
mNetworkController.removeCallback(this);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
index 399b0d2..6283148 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
@@ -256,9 +256,16 @@
if (mIcon == null) {
return false;
}
- Drawable drawable = getIcon(mIcon);
+ Drawable drawable;
+ try {
+ drawable = getIcon(mIcon);
+ } catch (OutOfMemoryError e) {
+ Log.w(TAG, "OOM while inflating " + mIcon.icon + " for slot " + mSlot);
+ return false;
+ }
+
if (drawable == null) {
- Log.w(TAG, "No icon for slot " + mSlot);
+ Log.w(TAG, "No icon for slot " + mSlot + "; " + mIcon.icon);
return false;
}
if (withClear) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationBarController.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationBarController.java
index 3bbda4b..7e08d56 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationBarController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationBarController.java
@@ -24,24 +24,22 @@
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.support.v4.util.SimpleArrayMap;
+import android.text.TextUtils;
import android.util.Log;
import android.util.SparseBooleanArray;
import android.view.View;
import android.widget.LinearLayout;
-
import com.android.systemui.R;
-import com.android.systemui.ActivityStarter;
import java.net.URISyntaxException;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.List;
/**
* A controller to populate data for CarNavigationBarView and handle user interactions.
- * <p/>
- * Each button inside the navigation bar is defined by data in arrays_car.xml. OEMs can customize
- * the navigation buttons by updating arrays_car.xml appropriately in an overlay.
+ *
+ * <p>Each button inside the navigation bar is defined by data in arrays_car.xml. OEMs can
+ * customize the navigation buttons by updating arrays_car.xml appropriately in an overlay.
*/
class CarNavigationBarController {
private static final String TAG = "CarNavBarController";
@@ -51,48 +49,49 @@
private static final String EXTRA_FACET_ID = "filter_id";
private static final String EXTRA_FACET_LAUNCH_PICKER = "launch_picker";
- // Each facet of the navigation bar maps to a set of package names or categories defined in
- // arrays_car.xml. Package names for a given facet are delimited by ";"
- private static final String FACET_FILTER_DEMILITER = ";";
+ /**
+ * Each facet of the navigation bar maps to a set of package names or categories defined in
+ * arrays_car.xml. Package names for a given facet are delimited by ";".
+ */
+ private static final String FACET_FILTER_DELIMITER = ";";
- private Context mContext;
- private CarNavigationBarView mNavBar;
- private CarStatusBar mStatusBar;
+ private final Context mContext;
+ private final CarNavigationBarView mNavBar;
+ private final CarStatusBar mStatusBar;
- // Set of categories each facet will filter on.
- private List<String[]> mFacetCategories = new ArrayList<String[]>();
- // Set of package names each facet will filter on.
- private List<String[]> mFacetPackages = new ArrayList<String[]>();
+ /**
+ * Set of categories each facet will filter on.
+ */
+ private final List<String[]> mFacetCategories = new ArrayList<>();
- private SimpleArrayMap<String, Integer> mFacetCategoryMap
- = new SimpleArrayMap<String, Integer>();
- private SimpleArrayMap<String, Integer> mFacetPackageMap
- = new SimpleArrayMap<String, Integer>();
+ /**
+ * Set of package names each facet will filter on.
+ */
+ private final List<String[]> mFacetPackages = new ArrayList<>();
- private List<Intent> mIntents;
- private List<Intent> mLongPressIntents;
+ private final SimpleArrayMap<String, Integer> mFacetCategoryMap = new SimpleArrayMap<>();
+ private final SimpleArrayMap<String, Integer> mFacetPackageMap = new SimpleArrayMap<>();
- private List<CarNavigationButton> mNavButtons = new ArrayList<CarNavigationButton>();
+ private final List<CarNavigationButton> mNavButtons = new ArrayList<>();
+
+ private final SparseBooleanArray mFacetHasMultipleAppsCache = new SparseBooleanArray();
private int mCurrentFacetIndex;
- private SparseBooleanArray mFacetHasMultipleAppsCache = new SparseBooleanArray();
-
private Intent mPersistentTaskIntent;
- public CarNavigationBarController(Context context,
- CarNavigationBarView navBar,
- CarStatusBar activityStarter) {
+ public CarNavigationBarController(Context context, CarNavigationBarView navBar,
+ CarStatusBar activityStarter) {
mContext = context;
mNavBar = navBar;
mStatusBar = activityStarter;
bind();
if (context.getResources().getBoolean(R.bool.config_enablePersistentDockedActivity)) {
- setupPersistentDockedTask(context);
+ setupPersistentDockedTask();
}
}
- private void setupPersistentDockedTask(Context context) {
+ private void setupPersistentDockedTask() {
try {
mPersistentTaskIntent = Intent.parseUri(
mContext.getString(R.string.config_persistentDockedActivityIntentUri),
@@ -137,64 +136,85 @@
}
}
+ /**
+ * Iterates through the items in arrays_car.xml and sets up the facet bar buttons to
+ * perform the task in that configuration file when clicked or long-pressed.
+ */
private void bind() {
- // Read up arrays_car.xml and populate the navigation bar here.
- Resources r = mContext.getResources();
- TypedArray icons = r.obtainTypedArray(R.array.car_facet_icons);
- TypedArray intents = r.obtainTypedArray(R.array.car_facet_intent_uris);
- TypedArray longpressIntents =
- r.obtainTypedArray(R.array.car_facet_longpress_intent_uris);
- TypedArray facetPackageNames = r.obtainTypedArray(R.array.car_facet_package_filters);
+ Resources res = mContext.getResources();
- TypedArray facetCategories = r.obtainTypedArray(R.array.car_facet_category_filters);
+ TypedArray icons = res.obtainTypedArray(R.array.car_facet_icons);
+ TypedArray intents = res.obtainTypedArray(R.array.car_facet_intent_uris);
+ TypedArray longPressIntents = res.obtainTypedArray(R.array.car_facet_longpress_intent_uris);
+ TypedArray facetPackageNames = res.obtainTypedArray(R.array.car_facet_package_filters);
+ TypedArray facetCategories = res.obtainTypedArray(R.array.car_facet_category_filters);
- if (icons.length() != intents.length()
- || icons.length() != longpressIntents.length()
- || icons.length() != facetPackageNames.length()
- || icons.length() != facetCategories.length()) {
- throw new RuntimeException("car_facet array lengths do not match");
- }
-
- mIntents = createEmptyIntentList(icons.length());
- mLongPressIntents = createEmptyIntentList(icons.length());
-
- for (int i = 0; i < icons.length(); i++) {
- Drawable icon = icons.getDrawable(i);
- try {
- mIntents.set(i,
- Intent.parseUri(intents.getString(i), Intent.URI_INTENT_SCHEME));
-
- String longpressUri = longpressIntents.getString(i);
- boolean hasLongpress = !longpressUri.isEmpty();
- if (hasLongpress) {
- mLongPressIntents.set(i,
- Intent.parseUri(longpressUri, Intent.URI_INTENT_SCHEME));
- }
-
- CarNavigationButton button = createNavButton(icon, i, hasLongpress);
- mNavButtons.add(button);
- mNavBar.addButton(button,
- createNavButton(icon, i, hasLongpress) /* lightsOutButton */);
-
- initFacetFilterMaps(i,
- facetPackageNames.getString(i).split(FACET_FILTER_DEMILITER),
- facetCategories.getString(i).split(FACET_FILTER_DEMILITER));
- mFacetHasMultipleAppsCache.put(i, facetHasMultiplePackages(i));
- } catch (URISyntaxException e) {
- throw new RuntimeException("Malformed intent uri", e);
+ try {
+ if (icons.length() != intents.length()
+ || icons.length() != longPressIntents.length()
+ || icons.length() != facetPackageNames.length()
+ || icons.length() != facetCategories.length()) {
+ throw new RuntimeException("car_facet array lengths do not match");
}
+
+ for (int i = 0, size = icons.length(); i < size; i++) {
+ Drawable icon = icons.getDrawable(i);
+ CarNavigationButton button = createNavButton(icon);
+ initClickListeners(button, i, intents.getString(i), longPressIntents.getString(i));
+
+ mNavButtons.add(button);
+ mNavBar.addButton(button, createNavButton(icon) /* lightsOutButton */);
+
+ initFacetFilterMaps(i, facetPackageNames.getString(i).split(FACET_FILTER_DELIMITER),
+ facetCategories.getString(i).split(FACET_FILTER_DELIMITER));
+ mFacetHasMultipleAppsCache.put(i, facetHasMultiplePackages(i));
+ }
+ } finally {
+ // Clean up all the TypedArrays.
+ icons.recycle();
+ intents.recycle();
+ longPressIntents.recycle();
+ facetPackageNames.recycle();
+ facetCategories.recycle();
+ }
+ }
+
+ /**
+ * Recreates each of the buttons on a density or font scale change. This manual process is
+ * necessary since this class is not part of an activity that automatically gets recreated.
+ */
+ public void onDensityOrFontScaleChanged() {
+ TypedArray icons = mContext.getResources().obtainTypedArray(R.array.car_facet_icons);
+
+ try {
+ int length = icons.length();
+ if (length != mNavButtons.size()) {
+ // This should not happen since the mNavButtons list is created from the length
+ // of the icons array in bind().
+ throw new RuntimeException("car_facet array lengths do not match number of "
+ + "created buttons.");
+ }
+
+ for (int i = 0; i < length; i++) {
+ Drawable icon = icons.getDrawable(i);
+
+ // Setting a new icon will trigger a requestLayout() call if necessary.
+ mNavButtons.get(i).setResources(icon);
+ }
+ } finally {
+ icons.recycle();
}
}
private void initFacetFilterMaps(int id, String[] packageNames, String[] categories) {
mFacetCategories.add(categories);
- for (int i = 0; i < categories.length; i++) {
- mFacetCategoryMap.put(categories[i], id);
+ for (String category : categories) {
+ mFacetCategoryMap.put(category, id);
}
mFacetPackages.add(packageNames);
- for (int i = 0; i < packageNames.length; i++) {
- mFacetPackageMap.put(packageNames[i], id);
+ for (String packageName : packageNames) {
+ mFacetPackageMap.put(packageName, id);
}
}
@@ -223,8 +243,10 @@
}
/**
- * Helper method to check if a given facet has multiple packages associated with it.
- * This can be resource defined package names or package names filtered by facet category.
+ * Helper method to check if a given facet has multiple packages associated with it. This can
+ * be resource defined package names or package names filtered by facet category.
+ *
+ * @return {@code true} if the facet at the given index has more than one package.
*/
private boolean facetHasMultiplePackages(int index) {
PackageManager pm = mContext.getPackageManager();
@@ -259,6 +281,10 @@
return false;
}
+ /**
+ * Sets the facet at the given index to be the facet that is currently active. The button will
+ * be highlighted appropriately.
+ */
private void setCurrentFacet(int index) {
if (index == mCurrentFacetIndex) {
return;
@@ -273,11 +299,16 @@
mNavButtons.get(index).setSelected(true /* selected */,
mFacetHasMultipleAppsCache.get(index) /* showMoreIcon */);
}
+
mCurrentFacetIndex = index;
}
- private CarNavigationButton createNavButton(Drawable icon, final int id,
- boolean longClickEnabled) {
+ /**
+ * Creates the View that is used for the buttons along the navigation bar.
+ *
+ * @param icon The icon to be used for the button.
+ */
+ private CarNavigationButton createNavButton(Drawable icon) {
CarNavigationButton button = (CarNavigationButton) View.inflate(mContext,
R.layout.car_navigation_button, null);
button.setResources(icon);
@@ -285,37 +316,49 @@
new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.MATCH_PARENT, 1);
button.setLayoutParams(lp);
- button.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- onFacetClicked(id);
- }
- });
-
- if (longClickEnabled) {
- button.setLongClickable(true);
- button.setOnLongClickListener(new View.OnLongClickListener() {
- @Override
- public boolean onLongClick(View v) {
- onFacetLongClicked(id);
- return true;
- }
- });
- } else {
- button.setLongClickable(false);
- }
-
return button;
}
- private void startActivity(Intent intent, ActivityStarter.Callback callback) {
- if (mStatusBar != null && intent != null) {
- mStatusBar.startActivity(intent, false, callback);
+ /**
+ * Initializes the click and long click listeners that correspond to the given command string.
+ * The click listeners are attached to the given button.
+ */
+ private void initClickListeners(View button, int index, String clickString,
+ String longPressString) {
+ // Each button at least have an action when pressed.
+ if (TextUtils.isEmpty(clickString)) {
+ throw new RuntimeException("Facet at index " + index + " does not have click action.");
+ }
+
+ try {
+ Intent intent = Intent.parseUri(clickString, Intent.URI_INTENT_SCHEME);
+ button.setOnClickListener(v -> onFacetClicked(intent, index));
+ } catch (URISyntaxException e) {
+ throw new RuntimeException("Malformed intent uri", e);
+ }
+
+ if (TextUtils.isEmpty(longPressString)) {
+ button.setLongClickable(false);
+ return;
+ }
+
+ try {
+ Intent intent = Intent.parseUri(longPressString, Intent.URI_INTENT_SCHEME);
+ button.setOnLongClickListener(v -> {
+ onFacetLongClicked(intent, index);
+ return true;
+ });
+ } catch (URISyntaxException e) {
+ throw new RuntimeException("Malformed long-press intent uri", e);
}
}
- private void onFacetClicked(int index) {
- Intent intent = mIntents.get(index);
+ /**
+ * Handles a click on a facet. A click will trigger the given Intent.
+ *
+ * @param index The index of the facet that was clicked.
+ */
+ private void onFacetClicked(Intent intent, int index) {
String packageName = intent.getPackage();
if (packageName == null) {
@@ -341,13 +384,13 @@
mStatusBar.startActivityOnStack(intent, stackId);
}
- private void onFacetLongClicked(int index) {
+ /**
+ * Handles a long-press on a facet. The long-press will trigger the given Intent.
+ *
+ * @param index The index of the facet that was clicked.
+ */
+ private void onFacetLongClicked(Intent intent, int index) {
setCurrentFacet(index);
- mStatusBar.startActivityOnStack(mLongPressIntents.get(index),
- StackId.FULLSCREEN_WORKSPACE_STACK_ID);
- }
-
- private List<Intent> createEmptyIntentList(int size) {
- return Arrays.asList(new Intent[size]);
+ mStatusBar.startActivityOnStack(intent, StackId.FULLSCREEN_WORKSPACE_STACK_ID);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
index f6a5687..4161389 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
@@ -35,10 +35,12 @@
import com.android.systemui.BatteryMeterView;
import com.android.systemui.Dependency;
import com.android.systemui.R;
+import com.android.systemui.SwipeHelper;
import com.android.systemui.recents.Recents;
import com.android.systemui.recents.misc.SystemServicesProxy;
import com.android.systemui.recents.misc.SystemServicesProxy.TaskStackListener;
import com.android.systemui.statusbar.StatusBarState;
+import com.android.systemui.statusbar.phone.NavigationBarView;
import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.phone.PhoneStatusBarView;
import com.android.systemui.statusbar.policy.BatteryController;
@@ -51,10 +53,8 @@
CarBatteryController.BatteryViewHandler {
private static final String TAG = "CarStatusBar";
- private SystemServicesProxy mSystemServicesProxy;
private TaskStackListenerImpl mTaskStackListener;
- private CarNavigationBarView mCarNavigationBar;
private CarNavigationBarController mController;
private FullscreenUserSwitcher mFullscreenUserSwitcher;
@@ -62,7 +62,6 @@
private BatteryMeterView mBatteryMeterView;
private ConnectedDeviceSignalController mConnectedDeviceSignalController;
- private View mSignalsView;
private CarNavigationBarView mNavigationBarView;
@Override
@@ -72,6 +71,8 @@
SystemServicesProxy.getInstance(mContext).registerTaskStackListener(mTaskStackListener);
registerPackageChangeReceivers();
+ mStackScroller.setScrollingEnabled(true);
+
createBatteryController();
mCarBatteryController.startListening();
mConnectedDeviceSignalController.startListening();
@@ -96,16 +97,16 @@
mBatteryMeterView.setVisibility(View.GONE);
ViewStub stub = (ViewStub) statusBarView.findViewById(R.id.connected_device_signals_stub);
- mSignalsView = stub.inflate();
+ View signalsView = stub.inflate();
// When a ViewStub if inflated, it does not respect the margins on the inflated view.
// As a result, manually add the ending margin.
- ((LinearLayout.LayoutParams) mSignalsView.getLayoutParams()).setMarginEnd(
+ ((LinearLayout.LayoutParams) signalsView.getLayoutParams()).setMarginEnd(
mContext.getResources().getDimensionPixelOffset(
R.dimen.status_bar_connected_device_signal_margin_end));
mConnectedDeviceSignalController = new ConnectedDeviceSignalController(mContext,
- mSignalsView);
+ signalsView);
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "makeStatusBarView(). mBatteryMeterView: " + mBatteryMeterView);
@@ -126,12 +127,11 @@
return;
}
- mCarNavigationBar =
- (CarNavigationBarView) View.inflate(mContext, R.layout.car_navigation_bar, null);
- mController = new CarNavigationBarController(mContext, mCarNavigationBar,
+ mNavigationBarView = (CarNavigationBarView) View.inflate(mContext,
+ R.layout.car_navigation_bar, null);
+ mController = new CarNavigationBarController(mContext, mNavigationBarView,
this /* ActivityStarter*/);
- mNavigationBarView = mCarNavigationBar;
- mCarNavigationBar.getBarTransitions().setAlwaysOpaque(true);
+ mNavigationBarView.getBarTransitions().setAlwaysOpaque(true);
WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.TYPE_NAVIGATION_BAR,
@@ -148,6 +148,31 @@
}
@Override
+ public NavigationBarView getNavigationBarView() {
+ return mNavigationBarView;
+ }
+
+ @Override
+ protected View.OnTouchListener getStatusBarWindowTouchListener() {
+ // Usually, a touch on the background window will dismiss the notification shade. However,
+ // for the car use-case, the shade should remain unless the user switches to a different
+ // facet (e.g. phone).
+ return null;
+ }
+
+ /**
+ * Returns the {@link com.android.systemui.SwipeHelper.LongPressListener} that will be
+ * triggered when a notification card is long-pressed.
+ */
+ @Override
+ protected SwipeHelper.LongPressListener getNotificationLongClicker() {
+ // For the automative use case, we do not want to the user to be able to interact with
+ // a notification other than a regular click. As a result, just return null for the
+ // long click listener.
+ return null;
+ }
+
+ @Override
public void showBatteryView() {
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "showBatteryView(). mBatteryMeterView: " + mBatteryMeterView);
@@ -272,4 +297,14 @@
options.setLaunchStackId(stackId);
return startActivityWithOptions(intent, options.toBundle());
}
+
+ /**
+ * Ensures that relevant child views are appropriately recreated when the device's density
+ * changes.
+ */
+ @Override
+ protected void onDensityOrFontScaleChanged() {
+ super.onDensityOrFontScaleChanged();
+ mController.onDensityOrFontScaleChanged();
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationCustomViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationCustomViewWrapper.java
index 3b18886..e5f32df 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationCustomViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationCustomViewWrapper.java
@@ -41,10 +41,12 @@
private final ViewInvertHelper mInvertHelper;
private final Paint mGreyPaint = new Paint();
private boolean mShowingLegacyBackground;
+ private int mLegacyColor;
protected NotificationCustomViewWrapper(View view, ExpandableNotificationRow row) {
super(view, row);
mInvertHelper = new ViewInvertHelper(view, NotificationPanelView.DOZE_ANIMATION_DURATION);
+ mLegacyColor = row.getContext().getColor(R.color.notification_legacy_background_color);
}
@Override
@@ -103,6 +105,20 @@
}
@Override
+ protected boolean shouldClearBackgroundOnReapply() {
+ return false;
+ }
+
+ @Override
+ public int getCustomBackgroundColor() {
+ int customBackgroundColor = super.getCustomBackgroundColor();
+ if (customBackgroundColor == 0 && mShowingLegacyBackground) {
+ return mLegacyColor;
+ }
+ return customBackgroundColor;
+ }
+
+ @Override
public void setShowingLegacyBackground(boolean showing) {
super.setShowingLegacyBackground(showing);
mShowingLegacyBackground = showing;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationViewWrapper.java
index 836482a..5f5e1e4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationViewWrapper.java
@@ -93,7 +93,9 @@
public void notifyContentUpdated(StatusBarNotification notification, boolean isLowPriority) {
mDarkInitialized = false;
Drawable background = mView.getBackground();
- mBackgroundColor = 0;
+ if (shouldClearBackgroundOnReapply()) {
+ mBackgroundColor = 0;
+ }
if (background instanceof ColorDrawable) {
mBackgroundColor = ((ColorDrawable) background).getColor();
mView.setBackground(null);
@@ -101,6 +103,10 @@
mShouldInvertDark = mBackgroundColor == 0 || isColorLight(mBackgroundColor);
}
+ protected boolean shouldClearBackgroundOnReapply() {
+ return true;
+ }
+
private boolean isColorLight(int backgroundColor) {
return Color.alpha(backgroundColor) == 0
|| ColorUtils.calculateLuminance(backgroundColor) > 0.5;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
index bfc0a80..14f9919 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
@@ -35,6 +35,7 @@
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
+import android.content.res.AssetFileDescriptor.AutoCloseOutputStream;
import android.content.res.Configuration;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
@@ -58,6 +59,7 @@
import android.widget.FrameLayout;
import android.widget.TextView;
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.widget.LockPatternUtils;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitorCallback;
@@ -164,6 +166,7 @@
private IntentButton mLeftDefault = mLeftButton;
private IntentButton mLeftPlugin;
private String mLeftButtonStr;
+ private LockscreenGestureLogger mLockscreenGestureLogger = new LockscreenGestureLogger();
public KeyguardBottomAreaView(Context context) {
this(context, null);
@@ -257,11 +260,11 @@
protected void onAttachedToWindow() {
super.onAttachedToWindow();
mAccessibilityController.addStateChangedCallback(this);
- PluginManager.getInstance(getContext()).addPluginListener(RIGHT_BUTTON_PLUGIN,
+ Dependency.get(PluginManager.class).addPluginListener(RIGHT_BUTTON_PLUGIN,
mRightListener, IntentButtonProvider.VERSION, false /* Only allow one */);
- PluginManager.getInstance(getContext()).addPluginListener(LEFT_BUTTON_PLUGIN,
+ Dependency.get(PluginManager.class).addPluginListener(LEFT_BUTTON_PLUGIN,
mLeftListener, IntentButtonProvider.VERSION, false /* Only allow one */);
- TunerService.get(getContext()).addTunable(this, LockscreenFragment.LOCKSCREEN_LEFT_BUTTON,
+ Dependency.get(TunerService.class).addTunable(this, LockscreenFragment.LOCKSCREEN_LEFT_BUTTON,
LockscreenFragment.LOCKSCREEN_RIGHT_BUTTON);
}
@@ -269,9 +272,9 @@
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
mAccessibilityController.removeStateChangedCallback(this);
- PluginManager.getInstance(getContext()).removePluginListener(mRightListener);
- PluginManager.getInstance(getContext()).removePluginListener(mLeftListener);
- TunerService.get(getContext()).removeTunable(this);
+ Dependency.get(PluginManager.class).removePluginListener(mRightListener);
+ Dependency.get(PluginManager.class).removePluginListener(mLeftListener);
+ Dependency.get(TunerService.class).removeTunable(this);
}
private void initAccessibility() {
@@ -445,8 +448,7 @@
}
private void handleTrustCircleClick() {
- EventLogTags.writeSysuiLockscreenGesture(
- EventLogConstants.SYSUI_LOCKSCREEN_GESTURE_TAP_LOCK, 0 /* lengthDp - N/A */,
+ mLockscreenGestureLogger.write(MetricsEvent.ACTION_LS_LOCK, 0 /* lengthDp - N/A */,
0 /* velocityDp - N/A */);
mIndicationController.showTransientIndication(
R.string.keyguard_indication_trust_disabled);
@@ -573,7 +575,7 @@
AsyncTask.execute(runnable);
} else {
boolean dismissShade = !TextUtils.isEmpty(mRightButtonStr)
- && TunerService.get(getContext()).getValue(LOCKSCREEN_RIGHT_UNLOCK, 1) != 0;
+ && Dependency.get(TunerService.class).getValue(LOCKSCREEN_RIGHT_UNLOCK, 1) != 0;
mStatusBar.executeRunnableDismissingKeyguard(runnable, null /* cancelAction */,
dismissShade, false /* afterKeyguardGone */, true /* deferred */);
}
@@ -594,7 +596,7 @@
});
} else {
boolean dismissShade = !TextUtils.isEmpty(mLeftButtonStr)
- && TunerService.get(getContext()).getValue(LOCKSCREEN_LEFT_UNLOCK, 1) != 0;
+ && Dependency.get(TunerService.class).getValue(LOCKSCREEN_LEFT_UNLOCK, 1) != 0;
mActivityStarter.startActivity(mLeftButton.getIntent(), dismissShade);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java
index 4535992..7c458898 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java
@@ -20,15 +20,19 @@
import android.view.View;
import com.android.systemui.Dependency;
+import com.android.systemui.Dumpable;
import com.android.systemui.statusbar.policy.BatteryController;
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+
import static com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT_TRANSPARENT;
import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSPARENT;
/**
* Controls how light status bar flag applies to the icons.
*/
-public class LightBarController implements BatteryController.BatteryStateChangeCallback {
+public class LightBarController implements BatteryController.BatteryStateChangeCallback, Dumpable {
private static final float NAV_BAR_INVERSION_SCRIM_ALPHA_THRESHOLD = 0.1f;
@@ -203,4 +207,37 @@
public void onPowerSaveChanged(boolean isPowerSave) {
reevaluate();
}
+
+ @Override
+ public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ pw.println("LightBarController: ");
+ pw.print(" mSystemUiVisibility=0x"); pw.print(
+ Integer.toHexString(mSystemUiVisibility));
+ pw.print(" mFullscreenStackVisibility=0x"); pw.print(
+ Integer.toHexString(mFullscreenStackVisibility));
+ pw.print(" mDockedStackVisibility=0x"); pw.println(
+ Integer.toHexString(mDockedStackVisibility));
+
+ pw.print(" mFullscreenLight="); pw.print(mFullscreenLight);
+ pw.print(" mDockedLight="); pw.println(mDockedLight);
+
+ pw.print(" mLastFullscreenBounds="); pw.print(mLastFullscreenBounds);
+ pw.print(" mLastDockedBounds="); pw.println(mLastDockedBounds);
+
+ pw.print(" mNavigationLight="); pw.print(mNavigationLight);
+ pw.print(" mHasLightNavigationBar="); pw.println(mHasLightNavigationBar);
+
+ pw.print(" mLastStatusBarMode="); pw.print(mLastStatusBarMode);
+ pw.print(" mLastNavigationBarMode="); pw.println(mLastNavigationBarMode);
+
+ pw.print(" mScrimAlpha="); pw.print(mScrimAlpha);
+ pw.print(" mScrimAlphaBelowThreshold="); pw.println(mScrimAlphaBelowThreshold);
+ pw.println();
+ pw.println(" StatusBarTransitionsController:");
+ mStatusBarIconController.getTransitionsController().dump(fd, pw, args);
+ pw.println();
+ pw.println(" NavigationBarTransitionsController:");
+ mNavigationBarController.dump(fd, pw, args);
+ pw.println();
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarTransitionsController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarTransitionsController.java
index 0f9f056..07f37ab 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarTransitionsController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarTransitionsController.java
@@ -20,13 +20,18 @@
import android.os.Bundle;
import android.os.Handler;
import android.os.SystemClock;
+import android.util.TimeUtils;
+import com.android.systemui.Dumpable;
import com.android.systemui.Interpolators;
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+
/**
* Class to control all aspects about light bar changes.
*/
-public class LightBarTransitionsController {
+public class LightBarTransitionsController implements Dumpable {
public static final long DEFAULT_TINT_ANIMATION_DURATION = 120;
private static final String EXTRA_DARK_INTENSITY = "dark_intensity";
@@ -147,6 +152,26 @@
mApplier.applyDarkIntensity(darkIntensity);
}
+ @Override
+ public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ pw.print(" mTransitionDeferring="); pw.print(mTransitionDeferring);
+ if (mTransitionDeferring) {
+ pw.println();
+ pw.print(" mTransitionDeferringStartTime=");
+ pw.println(TimeUtils.formatUptime(mTransitionDeferringStartTime));
+
+ pw.print(" mTransitionDeferringDuration=");
+ TimeUtils.formatDuration(mTransitionDeferringDuration, pw);
+ pw.println();
+ }
+ pw.print(" mTransitionPending="); pw.print(mTransitionPending);
+ pw.print(" mTintChangePending="); pw.println(mTintChangePending);
+
+ pw.print(" mPendingDarkIntensity="); pw.print(mPendingDarkIntensity);
+ pw.print(" mDarkIntensity="); pw.print(mDarkIntensity);
+ pw.print(" mNextDarkIntensity="); pw.println(mNextDarkIntensity);
+ }
+
/**
* Interface to apply a specific dark intensity.
*/
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenGestureLogger.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenGestureLogger.java
new file mode 100644
index 0000000..83b96bf
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenGestureLogger.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.statusbar.phone;
+
+import android.metrics.LogMaker;
+import android.util.ArrayMap;
+
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.systemui.EventLogConstants;
+import com.android.systemui.EventLogTags;
+
+/**
+ * Wrapper that emits both new- and old-style gesture logs.
+ * TODO: delete this once the old logs are no longer needed.
+ */
+public class LockscreenGestureLogger {
+ private ArrayMap<Integer, Integer> mLegacyMap;
+ private LogMaker mLogMaker = new LogMaker(MetricsEvent.VIEW_UNKNOWN)
+ .setType(MetricsEvent.TYPE_ACTION);
+
+ public LockscreenGestureLogger() {
+ mLegacyMap = new ArrayMap<>(EventLogConstants.METRICS_GESTURE_TYPE_MAP.length);
+ for (int i = 0; i < EventLogConstants.METRICS_GESTURE_TYPE_MAP.length ; i++) {
+ mLegacyMap.put(EventLogConstants.METRICS_GESTURE_TYPE_MAP[i], i);
+ }
+ }
+
+ public void write(int gesture, int length, int velocity) {
+ MetricsLogger.action(mLogMaker.setCategory(gesture)
+ .setType(MetricsEvent.TYPE_ACTION)
+ .addTaggedData(MetricsEvent.FIELD_GESTURE_LENGTH, length)
+ .addTaggedData(MetricsEvent.FIELD_GESTURE_VELOCITY, velocity));
+ // also write old-style logs for backward-0compatibility
+ EventLogTags.writeSysuiLockscreenGesture(safeLookup(gesture), length, velocity);
+ }
+
+ private int safeLookup(int gesture) {
+ Integer value = mLegacyMap.get(gesture);
+ if (value == null) {
+ return MetricsEvent.VIEW_UNKNOWN;
+ }
+ return value;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
index 62b536e..808cd21 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
@@ -23,6 +23,7 @@
import static com.android.systemui.statusbar.phone.StatusBar.DEBUG_WINDOW_STATE;
import static com.android.systemui.statusbar.phone.StatusBar.dumpBarTransitions;
+import android.accessibilityservice.AccessibilityServiceInfo;
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.ActivityManagerNative;
@@ -79,6 +80,7 @@
import java.io.FileDescriptor;
import java.io.PrintWriter;
+import java.util.List;
import java.util.Locale;
/**
@@ -101,7 +103,7 @@
private int mNavigationIconHints = 0;
private int mNavigationBarMode;
- protected AccessibilityManager mAccessibilityManager;
+ private AccessibilityManager mAccessibilityManager;
private int mDisabledFlags1;
private StatusBar mStatusBar;
@@ -132,6 +134,8 @@
mDivider = SysUiServiceProvider.getComponent(getContext(), Divider.class);
mWindowManager = getContext().getSystemService(WindowManager.class);
mAccessibilityManager = getContext().getSystemService(AccessibilityManager.class);
+ mAccessibilityManager.addAccessibilityServicesStateChangeListener(
+ this::updateAccessibilityServicesState);
if (savedInstanceState != null) {
mDisabledFlags1 = savedInstanceState.getInt(EXTRA_DISABLE_STATE, 0);
}
@@ -149,6 +153,8 @@
public void onDestroy() {
super.onDestroy();
mCommandQueue.removeCallbacks(this);
+ mAccessibilityManager.removeAccessibilityServicesStateChangeListener(
+ this::updateAccessibilityServicesState);
try {
WindowManagerGlobal.getWindowManagerService()
.removeRotationWatcher(mRotationWatcher);
@@ -402,6 +408,10 @@
ButtonDispatcher homeButton = mNavigationBarView.getHomeButton();
homeButton.setOnTouchListener(this::onHomeTouch);
homeButton.setOnLongClickListener(this::onHomeLongClick);
+
+ ButtonDispatcher accessibilityButton = mNavigationBarView.getAccessibilityButton();
+ accessibilityButton.setOnClickListener(this::onAccessibilityClick);
+ accessibilityButton.setOnLongClickListener(this::onAccessibilityLongClick);
}
private boolean onHomeTouch(View v, MotionEvent event) {
@@ -553,6 +563,34 @@
MetricsEvent.ACTION_WINDOW_UNDOCK_LONGPRESS);
}
+ private void onAccessibilityClick(View v) {
+ mAccessibilityManager.notifyAccessibilityButtonClicked();
+ }
+
+ private boolean onAccessibilityLongClick(View v) {
+ // TODO(b/34720082): Target service selection via long click
+ android.widget.Toast.makeText(getContext(), "Service selection coming soon...",
+ android.widget.Toast.LENGTH_LONG).show();
+ return true;
+ }
+
+ private void updateAccessibilityServicesState() {
+ final List<AccessibilityServiceInfo> services =
+ mAccessibilityManager.getEnabledAccessibilityServiceList(
+ AccessibilityServiceInfo.FEEDBACK_ALL_MASK);
+ int requestingServices = 0;
+ for (int i = services.size() - 1; i >= 0; --i) {
+ AccessibilityServiceInfo info = services.get(i);
+ if ((info.flags & AccessibilityServiceInfo.FLAG_REQUEST_ACCESSIBILITY_BUTTON) != 0) {
+ requestingServices++;
+ }
+ }
+
+ final boolean showAccessibilityButton = requestingServices >= 1;
+ final boolean targetSelection = requestingServices >= 2;
+ mNavigationBarView.setAccessibilityButtonState(showAccessibilityButton, targetSelection);
+ }
+
// ----- Methods that StatusBar talks to (should be minimized) -----
public void setLightBarController(LightBarController lightBarController) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarGestureHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarGestureHelper.java
index 228e8ea..ee9a791 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarGestureHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarGestureHelper.java
@@ -29,6 +29,7 @@
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.policy.DividerSnapAlgorithm.SnapTarget;
+import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.RecentsComponent;
import com.android.systemui.plugins.statusbar.phone.NavGesture.GestureHelper;
@@ -87,7 +88,11 @@
mScrollTouchSlop = r.getDimensionPixelSize(R.dimen.navigation_bar_min_swipe_distance);
mMinFlingVelocity = configuration.getScaledMinimumFlingVelocity();
mTaskSwitcherDetector = new GestureDetector(context, this);
- TunerService.get(context).addTunable(this, KEY_DOCK_WINDOW_GESTURE);
+ Dependency.get(TunerService.class).addTunable(this, KEY_DOCK_WINDOW_GESTURE);
+ }
+
+ public void destroy() {
+ Dependency.get(TunerService.class).removeTunable(this);
}
public void setComponents(RecentsComponent recentsComponent, Divider divider,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java
index 9b4867e..5fb99da 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java
@@ -30,6 +30,7 @@
import android.widget.LinearLayout;
import android.widget.Space;
+import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.plugins.PluginListener;
import com.android.systemui.plugins.PluginManager;
@@ -135,15 +136,16 @@
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
- TunerService.get(getContext()).addTunable(this, NAV_BAR_VIEWS, NAV_BAR_LEFT,
+ Dependency.get(TunerService.class).addTunable(this, NAV_BAR_VIEWS, NAV_BAR_LEFT,
NAV_BAR_RIGHT);
- PluginManager.getInstance(getContext()).addPluginListener(NavBarButtonProvider.ACTION, this,
+ Dependency.get(PluginManager.class).addPluginListener(NavBarButtonProvider.ACTION, this,
NavBarButtonProvider.VERSION, true /* Allow multiple */);
}
@Override
protected void onDetachedFromWindow() {
- TunerService.get(getContext()).removeTunable(this);
+ Dependency.get(TunerService.class).removeTunable(this);
+ Dependency.get(PluginManager.class).removePluginListener(this);
super.onDetachedFromWindow();
}
@@ -278,10 +280,10 @@
View v = null;
String button = extractButton(buttonSpec);
if (LEFT.equals(button)) {
- buttonSpec = TunerService.get(mContext).getValue(NAV_BAR_LEFT, NAVSPACE);
+ buttonSpec = Dependency.get(TunerService.class).getValue(NAV_BAR_LEFT, NAVSPACE);
button = extractButton(buttonSpec);
} else if (RIGHT.equals(button)) {
- buttonSpec = TunerService.get(mContext).getValue(NAV_BAR_RIGHT, MENU_IME);
+ buttonSpec = Dependency.get(TunerService.class).getValue(NAV_BAR_RIGHT, MENU_IME);
button = extractButton(buttonSpec);
}
// Let plugins go first so they can override a standard view if they want.
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 5e988fc..5d13289 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -46,6 +46,7 @@
import android.view.inputmethod.InputMethodManager;
import android.widget.FrameLayout;
+import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.RecentsComponent;
import com.android.systemui.plugins.PluginListener;
@@ -77,6 +78,8 @@
private int mCurrentRotation = -1;
boolean mShowMenu;
+ boolean mShowAccessibilityButton;
+ boolean mLongClickableAccessibilityButton;
int mDisabledFlags = 0;
int mNavigationIconHints = 0;
@@ -88,6 +91,7 @@
private KeyButtonDrawable mDockedIcon;
private KeyButtonDrawable mImeIcon;
private KeyButtonDrawable mMenuIcon;
+ private KeyButtonDrawable mAccessibilityIcon;
private GestureHelper mGestureHelper;
private DeadZone mDeadZone;
@@ -200,7 +204,9 @@
mVertical = false;
mShowMenu = false;
- mGestureHelper = new NavigationBarGestureHelper(context);
+
+ mShowAccessibilityButton = false;
+ mLongClickableAccessibilityButton = false;
mConfiguration = new Configuration();
mConfiguration.updateFrom(context.getResources().getConfiguration());
@@ -213,6 +219,8 @@
mButtonDispatchers.put(R.id.recent_apps, new ButtonDispatcher(R.id.recent_apps));
mButtonDispatchers.put(R.id.menu, new ButtonDispatcher(R.id.menu));
mButtonDispatchers.put(R.id.ime_switcher, new ButtonDispatcher(R.id.ime_switcher));
+ mButtonDispatchers.put(R.id.accessibility_button,
+ new ButtonDispatcher(R.id.accessibility_button));
}
public BarTransitions getBarTransitions() {
@@ -287,6 +295,10 @@
return mButtonDispatchers.get(R.id.ime_switcher);
}
+ public ButtonDispatcher getAccessibilityButton() {
+ return mButtonDispatchers.get(R.id.accessibility_button);
+ }
+
public SparseArray<ButtonDispatcher> getButtonDispatchers() {
return mButtonDispatchers;
}
@@ -320,6 +332,8 @@
mRecentIcon = getDrawable(ctx,
R.drawable.ic_sysbar_recent, R.drawable.ic_sysbar_recent_dark);
mMenuIcon = getDrawable(ctx, R.drawable.ic_sysbar_menu, R.drawable.ic_sysbar_menu_dark);
+ mAccessibilityIcon = getDrawable(ctx, R.drawable.ic_sysbar_accessibility_button,
+ R.drawable.ic_sysbar_accessibility_button_dark);
Context darkContext = new ContextThemeWrapper(ctx, R.style.DualToneDarkTheme);
Context lightContext = new ContextThemeWrapper(ctx, R.style.DualToneLightTheme);
@@ -411,6 +425,9 @@
setMenuVisibility(mShowMenu, true);
getMenuButton().setImageDrawable(mMenuIcon);
+ setAccessibilityButtonState(mShowAccessibilityButton, mLongClickableAccessibilityButton);
+ getAccessibilityButton().setImageDrawable(mAccessibilityIcon);
+
setDisabledFlags(mDisabledFlags, true);
mBarTransitions.reapplyDarkIntensity();
@@ -517,13 +534,25 @@
mShowMenu = show;
- // Only show Menu if IME switcher not shown.
- final boolean shouldShow = mShowMenu &&
+ // Only show Menu if IME switcher and Accessibility button not shown.
+ final boolean shouldShow = mShowMenu && !mShowAccessibilityButton &&
((mNavigationIconHints & StatusBarManager.NAVIGATION_HINT_IME_SHOWN) == 0);
getMenuButton().setVisibility(shouldShow ? View.VISIBLE : View.INVISIBLE);
}
+ public void setAccessibilityButtonState(final boolean visible, final boolean longClickable) {
+ mShowAccessibilityButton = visible;
+ mLongClickableAccessibilityButton = longClickable;
+ if (visible) {
+ // Accessibility button overrides Menu button.
+ setMenuVisibility(false, true);
+ }
+
+ getAccessibilityButton().setVisibility(visible ? View.VISIBLE : View.INVISIBLE);
+ getAccessibilityButton().setLongClickable(longClickable);
+ }
+
@Override
public void onFinishInflate() {
mNavigationInflaterView = (NavigationBarInflaterView) findViewById(
@@ -633,6 +662,7 @@
}
private void updateTaskSwitchHelper() {
+ if (mGestureHelper == null) return;
boolean isRtl = (getLayoutDirection() == View.LAYOUT_DIRECTION_RTL);
mGestureHelper.setBarState(mVertical, isRtl);
}
@@ -752,14 +782,18 @@
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
- PluginManager.getInstance(getContext()).addPluginListener(NavGesture.ACTION, this,
+ onPluginDisconnected(null); // Create default gesture helper
+ Dependency.get(PluginManager.class).addPluginListener(NavGesture.ACTION, this,
NavGesture.VERSION, false /* Only one */);
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
- PluginManager.getInstance(getContext()).removePluginListener(this);
+ Dependency.get(PluginManager.class).removePluginListener(this);
+ if (mGestureHelper != null) {
+ mGestureHelper.destroy();
+ }
}
@Override
@@ -772,6 +806,9 @@
public void onPluginDisconnected(NavGesture plugin) {
NavigationBarGestureHelper defaultHelper = new NavigationBarGestureHelper(getContext());
defaultHelper.setComponents(mRecentsComponent, mDivider, this);
+ if (mGestureHelper != null) {
+ mGestureHelper.destroy();
+ }
mGestureHelper = defaultHelper;
updateTaskSwitchHelper();
}
@@ -806,6 +843,7 @@
dumpButton(pw, "home", getHomeButton());
dumpButton(pw, "rcnt", getRecentsButton());
dumpButton(pw, "menu", getMenuButton());
+ dumpButton(pw, "a11y", getAccessibilityButton());
pw.println(" }");
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
index c25a45c..571ae26 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
@@ -104,6 +104,7 @@
private float mOpenedAmount = 0.0f;
private float mVisualOverflowAdaption;
private boolean mDisallowNextAnimation;
+ private boolean mAnimationsEnabled = true;
public NotificationIconContainer(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -255,7 +256,7 @@
iconState.visibleState = StatusBarIconView.STATE_ICON;
if (firstOverflowIndex == -1 && (isAmbient
|| (translationX >= (noOverflowAfter ? layoutEnd - mIconSize : overflowStart)))) {
- firstOverflowIndex = noOverflowAfter ? i - 1 : i;
+ firstOverflowIndex = noOverflowAfter && !isAmbient ? i - 1 : i;
int totalDotLength = mStaticDotRadius * 6 + 2 * mDotPadding;
visualOverflowStart = overflowStart + mIconSize * (1 + OVERFLOW_EARLY_AMOUNT)
- totalDotLength / 2
@@ -422,6 +423,20 @@
return mIconSize;
}
+ public void setAnimationsEnabled(boolean enabled) {
+ if (!enabled && mAnimationsEnabled) {
+ for (int i = 0; i < getChildCount(); i++) {
+ View child = getChildAt(i);
+ ViewState childState = mIconStates.get(child);
+ if (childState != null) {
+ childState.cancelAnimations(child);
+ childState.applyToView(child);
+ }
+ }
+ }
+ mAnimationsEnabled = enabled;
+ }
+
public class IconState extends ViewState {
public float iconAppearAmount = 1.0f;
public float clampedAppearAmount = 1.0f;
@@ -438,52 +453,59 @@
StatusBarIconView icon = (StatusBarIconView) view;
boolean animate = false;
AnimationProperties animationProperties = null;
- if (justAdded) {
- super.applyToView(icon);
- icon.setAlpha(0.0f);
- icon.setVisibleState(StatusBarIconView.STATE_HIDDEN, false /* animate */);
- animationProperties = ADD_ICON_PROPERTIES;
- animate = true;
- } else if (visibleState != icon.getVisibleState()) {
- animationProperties = DOT_ANIMATION_PROPERTIES;
- animate = true;
- }
- if (!animate && mAddAnimationStartIndex >= 0
- && indexOfChild(view) >= mAddAnimationStartIndex
- && (icon.getVisibleState() != StatusBarIconView.STATE_HIDDEN
- || visibleState != StatusBarIconView.STATE_HIDDEN)) {
- animationProperties = DOT_ANIMATION_PROPERTIES;
- animate = true;
- }
- if (needsCannedAnimation) {
- AnimationFilter animationFilter = mTempProperties.getAnimationFilter();
- animationFilter.reset();
- animationFilter.combineFilter(ICON_ANIMATION_PROPERTIES.getAnimationFilter());
- mTempProperties.resetCustomInterpolators();
- mTempProperties.combineCustomInterpolators(ICON_ANIMATION_PROPERTIES);
- if (animationProperties != null) {
- animationFilter.combineFilter(animationProperties.getAnimationFilter());
- mTempProperties.combineCustomInterpolators(animationProperties);
+ boolean animationsAllowed = mAnimationsEnabled && !mDisallowNextAnimation;
+ if (animationsAllowed) {
+ if (justAdded) {
+ super.applyToView(icon);
+ if (iconAppearAmount != 0.0f) {
+ icon.setAlpha(0.0f);
+ icon.setVisibleState(StatusBarIconView.STATE_HIDDEN,
+ false /* animate */);
+ animationProperties = ADD_ICON_PROPERTIES;
+ animate = true;
+ }
+ } else if (visibleState != icon.getVisibleState()) {
+ animationProperties = DOT_ANIMATION_PROPERTIES;
+ animate = true;
}
- animationProperties = mTempProperties;
- animationProperties.setDuration(CANNED_ANIMATION_DURATION);
- animate = true;
- mCannedAnimationStartIndex = indexOfChild(view);
+ if (!animate && mAddAnimationStartIndex >= 0
+ && indexOfChild(view) >= mAddAnimationStartIndex
+ && (icon.getVisibleState() != StatusBarIconView.STATE_HIDDEN
+ || visibleState != StatusBarIconView.STATE_HIDDEN)) {
+ animationProperties = DOT_ANIMATION_PROPERTIES;
+ animate = true;
+ }
+ if (needsCannedAnimation) {
+ AnimationFilter animationFilter = mTempProperties.getAnimationFilter();
+ animationFilter.reset();
+ animationFilter.combineFilter(
+ ICON_ANIMATION_PROPERTIES.getAnimationFilter());
+ mTempProperties.resetCustomInterpolators();
+ mTempProperties.combineCustomInterpolators(ICON_ANIMATION_PROPERTIES);
+ if (animationProperties != null) {
+ animationFilter.combineFilter(animationProperties.getAnimationFilter());
+ mTempProperties.combineCustomInterpolators(animationProperties);
+ }
+ animationProperties = mTempProperties;
+ animationProperties.setDuration(CANNED_ANIMATION_DURATION);
+ animate = true;
+ mCannedAnimationStartIndex = indexOfChild(view);
+ }
+ if (!animate && mCannedAnimationStartIndex >= 0
+ && indexOfChild(view) > mCannedAnimationStartIndex
+ && (icon.getVisibleState() != StatusBarIconView.STATE_HIDDEN
+ || visibleState != StatusBarIconView.STATE_HIDDEN)) {
+ AnimationFilter animationFilter = mTempProperties.getAnimationFilter();
+ animationFilter.reset();
+ animationFilter.animateX();
+ mTempProperties.resetCustomInterpolators();
+ animationProperties = mTempProperties;
+ animationProperties.setDuration(CANNED_ANIMATION_DURATION);
+ animate = true;
+ }
}
- if (!animate && mCannedAnimationStartIndex >= 0
- && indexOfChild(view) > mCannedAnimationStartIndex
- && (icon.getVisibleState() != StatusBarIconView.STATE_HIDDEN
- || visibleState != StatusBarIconView.STATE_HIDDEN)) {
- AnimationFilter animationFilter = mTempProperties.getAnimationFilter();
- animationFilter.reset();
- animationFilter.animateX();
- mTempProperties.resetCustomInterpolators();
- animationProperties = mTempProperties;
- animationProperties.setDuration(CANNED_ANIMATION_DURATION);
- animate = true;
- }
- icon.setVisibleState(visibleState);
- if (animate && !mDisallowNextAnimation) {
+ icon.setVisibleState(visibleState, animationsAllowed);
+ if (animate) {
animateTo(icon, animationProperties);
} else {
super.applyToView(view);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index fe7e915..5da3a10 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -26,6 +26,7 @@
import android.content.Context;
import android.content.pm.ResolveInfo;
import android.content.res.Configuration;
+import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
@@ -43,6 +44,7 @@
import android.widget.TextView;
import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.keyguard.KeyguardStatusView;
import com.android.systemui.DejankUtils;
import com.android.systemui.EventLogConstants;
@@ -137,6 +139,7 @@
protected int mQsMinExpansionHeight;
protected int mQsMaxExpansionHeight;
private int mQsPeekHeight;
+ private boolean mQsOverscrollExpansionEnabled;
private boolean mStackScrollerOverscrolling;
private boolean mQsExpansionFromOverscroll;
private float mLastOverscroll;
@@ -212,11 +215,14 @@
private int mIndicationBottomPadding;
private boolean mIsFullWidth;
private boolean mDark;
+ private LockscreenGestureLogger mLockscreenGestureLogger = new LockscreenGestureLogger();
public NotificationPanelView(Context context, AttributeSet attrs) {
super(context, attrs);
setWillNotDraw(!DEBUG);
mFalsingManager = FalsingManager.getInstance(context);
+ mQsOverscrollExpansionEnabled =
+ getResources().getBoolean(R.bool.config_enableQuickSettingsOverscrollExpansion);
}
public void setStatusBar(StatusBar bar) {
@@ -596,7 +602,8 @@
MetricsLogger.count(mContext, COUNTER_PANEL_OPEN_PEEK, 1);
return true;
}
- if (!isFullyCollapsed() && onQsIntercept(event)) {
+
+ if (mQsOverscrollExpansionEnabled && !isFullyCollapsed() && onQsIntercept(event)) {
return true;
}
return super.onInterceptTouchEvent(event);
@@ -710,10 +717,9 @@
private void logQsSwipeDown(float y) {
float vel = getCurrentQSVelocity();
final int gesture = mStatusBarState == StatusBarState.KEYGUARD
- ? EventLogConstants.SYSUI_LOCKSCREEN_GESTURE_SWIPE_DOWN_QS
- : EventLogConstants.SYSUI_SHADE_GESTURE_SWIPE_DOWN_QS;
- EventLogTags.writeSysuiLockscreenGesture(
- gesture,
+ ? MetricsEvent.ACTION_LS_QS
+ : MetricsEvent.ACTION_SHADE_QS_PULL;
+ mLockscreenGestureLogger.write(gesture,
(int) ((y - mInitialTouchY) / mStatusBar.getDisplayDensity()),
(int) (vel / mStatusBar.getDisplayDensity()));
}
@@ -770,7 +776,9 @@
return true;
}
mHeadsUpTouchHelper.onTouchEvent(event);
- if (!mHeadsUpTouchHelper.isTrackingHeadsUp() && handleQsTouch(event)) {
+
+ if (mQsOverscrollExpansionEnabled && !mHeadsUpTouchHelper.isTrackingHeadsUp()
+ && handleQsTouch(event)) {
return true;
}
if (event.getActionMasked() == MotionEvent.ACTION_DOWN && isFullyCollapsed()) {
@@ -953,6 +961,10 @@
@Override
public void onOverscrollTopChanged(float amount, boolean isRubberbanded) {
+ if (!mQsOverscrollExpansionEnabled) {
+ return;
+ }
+
cancelQsAnimation();
if (!mQsExpansionEnabled) {
amount = 0f;
@@ -967,6 +979,10 @@
@Override
public void flingTopOverscroll(float velocity, boolean open) {
+ if (!mQsOverscrollExpansionEnabled) {
+ return;
+ }
+
mLastOverscroll = 0f;
mQsExpansionFromOverscroll = false;
setQsExpansion(mQsExpansionHeight);
@@ -1819,9 +1835,7 @@
if (mQsExpanded) {
flingSettings(0 /* vel */, false /* expand */, null, true /* isClick */);
} else if (mQsExpansionEnabled) {
- EventLogTags.writeSysuiLockscreenGesture(
- EventLogConstants.SYSUI_TAP_TO_OPEN_QS,
- 0, 0);
+ mLockscreenGestureLogger.write(MetricsEvent.ACTION_SHADE_QS_TAP, 0, 0);
flingSettings(0 /* vel */, true /* expand */, null, true /* isClick */);
}
}
@@ -1836,8 +1850,7 @@
int lengthDp = Math.abs((int) (translation / displayDensity));
int velocityDp = Math.abs((int) (vel / displayDensity));
if (start) {
- EventLogTags.writeSysuiLockscreenGesture(
- EventLogConstants.SYSUI_LOCKSCREEN_GESTURE_SWIPE_DIALER, lengthDp, velocityDp);
+ mLockscreenGestureLogger.write(MetricsEvent.ACTION_LS_DIALER, lengthDp, velocityDp);
mFalsingManager.onLeftAffordanceOn();
if (mFalsingManager.shouldEnforceBouncer()) {
@@ -1855,9 +1868,7 @@
} else {
if (KeyguardBottomAreaView.CAMERA_LAUNCH_SOURCE_AFFORDANCE.equals(
mLastCameraLaunchSource)) {
- EventLogTags.writeSysuiLockscreenGesture(
- EventLogConstants.SYSUI_LOCKSCREEN_GESTURE_SWIPE_CAMERA,
- lengthDp, velocityDp);
+ mLockscreenGestureLogger.write(MetricsEvent.ACTION_LS_CAMERA, lengthDp, velocityDp);
}
mFalsingManager.onCameraOn();
if (mFalsingManager.shouldEnforceBouncer()) {
@@ -2152,8 +2163,8 @@
switch (mStatusBar.getBarState()) {
case StatusBarState.KEYGUARD:
if (!mDozingOnDown) {
- EventLogTags.writeSysuiLockscreenGesture(
- EventLogConstants.SYSUI_LOCKSCREEN_GESTURE_TAP_UNLOCK_HINT,
+ mLockscreenGestureLogger.write(
+ MetricsEvent.ACTION_LS_HINT,
0 /* lengthDp - N/A */, 0 /* velocityDp - N/A */);
startUnlockHintAnimation();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
index 5f67468..48a8329 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
@@ -33,6 +33,7 @@
import android.view.animation.Interpolator;
import android.widget.FrameLayout;
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.systemui.DejankUtils;
import com.android.systemui.EventLogConstants;
import com.android.systemui.EventLogTags;
@@ -55,6 +56,7 @@
private static final int PEEK_ANIMATION_DURATION = 360;
private long mDownTime;
private float mMinExpandHeight;
+ private LockscreenGestureLogger mLockscreenGestureLogger = new LockscreenGestureLogger();
private final void logf(String fmt, Object... args) {
Log.v(TAG, (mViewName != null ? (mViewName + ": ") : "") + String.format(fmt, args));
@@ -110,6 +112,11 @@
private float mInitialTouchX;
private boolean mTouchDisabled;
+ /**
+ * Whether or not the PanelView can be expanded or collapsed with a drag.
+ */
+ private boolean mNotificationsDragEnabled;
+
private Interpolator mBounceInterpolator;
protected KeyguardBottomAreaView mKeyguardBottomArea;
@@ -190,6 +197,8 @@
0.84f /* y2 */);
mBounceInterpolator = new BounceInterpolator();
mFalsingManager = FalsingManager.getInstance(context);
+ mNotificationsDragEnabled =
+ getResources().getBoolean(R.bool.config_enableNotificationShadeDrag);
}
protected void loadDimens() {
@@ -232,6 +241,15 @@
return false;
}
+ // If dragging should not expand the notifications shade, then return false.
+ if (!mNotificationsDragEnabled) {
+ if (mTracking) {
+ // Turn off tracking if it's on or the shade can get stuck in the down position.
+ onTrackingStopped(true /* expand */);
+ }
+ return false;
+ }
+
// On expanding, single mouse click expands the panel instead of dragging.
if (isFullyCollapsed() && event.isFromSource(InputDevice.SOURCE_MOUSE)) {
if (event.getAction() == MotionEvent.ACTION_UP) {
@@ -423,8 +441,8 @@
float displayDensity = mStatusBar.getDisplayDensity();
int heightDp = (int) Math.abs((y - mInitialTouchY) / displayDensity);
int velocityDp = (int) Math.abs(vel / displayDensity);
- EventLogTags.writeSysuiLockscreenGesture(
- EventLogConstants.SYSUI_LOCKSCREEN_GESTURE_SWIPE_UP_UNLOCK,
+ mLockscreenGestureLogger.write(
+ MetricsEvent.ACTION_LS_UNLOCK,
heightDp, velocityDp);
}
fling(vel, expand, isFalseTouch(x, y));
@@ -487,7 +505,7 @@
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
- if (mInstantExpanding
+ if (mInstantExpanding || !mNotificationsDragEnabled
|| (mMotionAborted && event.getActionMasked() != MotionEvent.ACTION_DOWN)) {
return false;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
index dd567e8..a1022c4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
@@ -89,7 +89,7 @@
mServices = new TileServices(this, Dependency.get(Dependency.BG_LOOPER));
- TunerService.get(mContext).addTunable(this, TILES_SETTING);
+ Dependency.get(TunerService.class).addTunable(this, TILES_SETTING);
// AutoTileManager can modify mTiles so make sure mTiles has already been initialized.
mAutoTiles = new AutoTileManager(context, this);
}
@@ -101,7 +101,7 @@
public void destroy() {
mTiles.values().forEach(tile -> tile.destroy());
mAutoTiles.destroy();
- TunerService.get(mContext).removeTunable(this);
+ Dependency.get(TunerService.class).removeTunable(this);
mServices.destroy();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java
index c0e9653..4307a2e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java
@@ -21,12 +21,14 @@
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
+import android.content.res.Resources;
import android.graphics.Color;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.RippleDrawable;
import android.icu.text.NumberFormat;
import android.os.UserManager;
+import android.support.annotation.Nullable;
import android.support.annotation.VisibleForTesting;
import android.util.AttributeSet;
import android.util.SparseBooleanArray;
@@ -67,9 +69,6 @@
public class QuickStatusBarHeader extends BaseStatusBarHeader implements
NextAlarmChangeCallback, OnClickListener, OnUserInfoChangedListener, EmergencyListener,
BatteryStateChangeCallback, SignalCallback {
-
- private static final String TAG = "QuickStatusBarHeader";
-
private static final float EXPAND_INDICATOR_THRESHOLD = .93f;
private ActivityStarter mActivityStarter;
@@ -99,13 +98,16 @@
private boolean mShowEmergencyCallsOnly;
protected MultiUserSwitch mMultiUserSwitch;
private ImageView mMultiUserAvatar;
-
+ private boolean mAlwaysShowMultiUserSwitch;
private TouchAnimator mAnimator;
protected TouchAnimator mSettingsAlpha;
private float mExpansionAmount;
protected QSTileHost mHost;
+
protected View mEdit;
+ private boolean mShowEditIcon;
+
private boolean mShowFullAlarm;
private float mDateTimeTranslation;
private TextView mBatteryLevel;
@@ -119,25 +121,37 @@
@Override
protected void onFinishInflate() {
super.onFinishInflate();
+ Resources res = getResources();
mEmergencyOnly = (TextView) findViewById(R.id.header_emergency_calls_only);
+ mShowEditIcon = res.getBoolean(R.bool.config_showQuickSettingsEditingIcon);
+
mEdit = findViewById(android.R.id.edit);
- findViewById(android.R.id.edit).setOnClickListener(view ->
- Dependency.get(ActivityStarter.class).postQSRunnableDismissingKeyguard(() ->
- mQsPanel.showEdit(view)));
+ mEdit.setVisibility(mShowEditIcon ? VISIBLE : GONE);
+
+ if (mShowEditIcon) {
+ findViewById(android.R.id.edit).setOnClickListener(view ->
+ Dependency.get(ActivityStarter.class).postQSRunnableDismissingKeyguard(() ->
+ mQsPanel.showEdit(view)));
+ }
mDateTimeAlarmGroup = (ViewGroup) findViewById(R.id.date_time_alarm_group);
mDateTimeAlarmGroup.findViewById(R.id.empty_time_view).setVisibility(View.GONE);
mDateTimeGroup = (ViewGroup) findViewById(R.id.date_time_group);
mDateTimeGroup.setPivotX(0);
mDateTimeGroup.setPivotY(0);
- mDateTimeTranslation = getResources().getDimension(R.dimen.qs_date_time_translation);
- mShowFullAlarm = getResources().getBoolean(R.bool.quick_settings_show_full_alarm);
+ mDateTimeTranslation = res.getDimension(R.dimen.qs_date_time_translation);
+ mShowFullAlarm = res.getBoolean(R.bool.quick_settings_show_full_alarm);
mExpandIndicator = (ExpandableIndicator) findViewById(R.id.expand_indicator);
+ mExpandIndicator.setVisibility(
+ res.getBoolean(R.bool.config_showQuickSettingsExpandIndicator)
+ ? VISIBLE : GONE);
mHeaderQsPanel = (QuickQSPanel) findViewById(R.id.quick_qs_panel);
+ mHeaderQsPanel.setVisibility(res.getBoolean(R.bool.config_showQuickSettingsRow)
+ ? VISIBLE : GONE);
mSettingsButton = (SettingsButton) findViewById(R.id.settings_button);
mSettingsContainer = findViewById(R.id.settings_button_container);
@@ -151,6 +165,7 @@
mMultiUserSwitch = (MultiUserSwitch) findViewById(R.id.multi_user_switch);
mMultiUserAvatar = (ImageView) mMultiUserSwitch.findViewById(R.id.multi_user_avatar);
+ mAlwaysShowMultiUserSwitch = res.getBoolean(R.bool.config_alwaysShowMultiUserSwitcher);
// RenderThread is doing more harm than good when touching the header (to expand quick
// settings), so disable it for this view
@@ -200,11 +215,8 @@
updateSettingsAnimator();
}
- protected void updateSettingsAnimator() {
- mSettingsAlpha = new TouchAnimator.Builder()
- .addFloat(mEdit, "alpha", 0, 1)
- .addFloat(mMultiUserSwitch, "alpha", 0, 1)
- .build();
+ private void updateSettingsAnimator() {
+ mSettingsAlpha = createSettingsAlphaAnimator();
final boolean isRtl = isLayoutRtl();
if (isRtl && mDateTimeGroup.getWidth() == 0) {
@@ -221,6 +233,27 @@
}
}
+ @Nullable
+ private TouchAnimator createSettingsAlphaAnimator() {
+ // If the settings icon is not shown and the user switcher is always shown, then there
+ // is nothing to animate.
+ if (!mShowEditIcon && mAlwaysShowMultiUserSwitch) {
+ return null;
+ }
+
+ TouchAnimator.Builder animatorBuilder = new TouchAnimator.Builder();
+
+ if (mShowEditIcon) {
+ animatorBuilder.addFloat(mEdit, "alpha", 0, 1);
+ }
+
+ if (!mAlwaysShowMultiUserSwitch) {
+ animatorBuilder.addFloat(mMultiUserSwitch, "alpha", 0, 1);
+ }
+
+ return animatorBuilder.build();
+ }
+
@Override
public int getCollapsedHeight() {
return getHeight();
@@ -261,7 +294,10 @@
mExpansionAmount = headerExpansionFraction;
updateDateTimePosition();
mAnimator.setPosition(headerExpansionFraction);
- mSettingsAlpha.setPosition(headerExpansionFraction);
+
+ if (mSettingsAlpha != null) {
+ mSettingsAlpha.setPosition(headerExpansionFraction);
+ }
updateAlarmVisibilities();
@@ -302,7 +338,7 @@
});
}
- protected void updateVisibilities() {
+ private void updateVisibilities() {
updateAlarmVisibilities();
updateDateTimePosition();
mEmergencyOnly.setVisibility(mExpanded && (mShowEmergencyCallsOnly || mIsRoaming)
@@ -310,9 +346,14 @@
mSettingsContainer.findViewById(R.id.tuner_icon).setVisibility(
TunerService.isTunerEnabled(mContext) ? View.VISIBLE : View.INVISIBLE);
final boolean isDemo = UserManager.isDeviceInDemoMode(mContext);
- mMultiUserSwitch.setVisibility(mExpanded && mMultiUserSwitch.hasMultipleUsers() && !isDemo
+
+ mMultiUserSwitch.setVisibility((mExpanded || mAlwaysShowMultiUserSwitch)
+ && mMultiUserSwitch.hasMultipleUsers() && !isDemo
? View.VISIBLE : View.INVISIBLE);
- mEdit.setVisibility(isDemo || !mExpanded ? View.INVISIBLE : View.VISIBLE);
+
+ if (mShowEditIcon) {
+ mEdit.setVisibility(isDemo || !mExpanded ? View.INVISIBLE : View.VISIBLE);
+ }
}
private void updateDateTimePosition() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index 8fcbf38..b30d3ab 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -23,13 +23,13 @@
import android.content.Context;
import android.graphics.Rect;
import android.support.v4.graphics.ColorUtils;
+import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;
import android.view.animation.PathInterpolator;
-
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.R;
import com.android.systemui.statusbar.ExpandableNotificationRow;
@@ -49,7 +49,6 @@
= new PathInterpolator(0f, 0, 0.7f, 1f);
public static final Interpolator KEYGUARD_FADE_OUT_INTERPOLATOR_LOCKED
= new PathInterpolator(0.3f, 0f, 0.8f, 1f);
- private static final float SCRIM_BEHIND_ALPHA = 0.62f;
protected static final float SCRIM_BEHIND_ALPHA_KEYGUARD = 0.45f;
protected static final float SCRIM_BEHIND_ALPHA_UNLOCKING = 0.2f;
private static final float SCRIM_IN_FRONT_ALPHA = 0.75f;
@@ -66,7 +65,7 @@
private final View mHeadsUpScrim;
private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
- protected float mScrimBehindAlpha = SCRIM_BEHIND_ALPHA;
+ protected float mScrimBehindAlpha;
protected float mScrimBehindAlphaKeyguard = SCRIM_BEHIND_ALPHA_KEYGUARD;
protected float mScrimBehindAlphaUnlocking = SCRIM_BEHIND_ALPHA_UNLOCKING;
@@ -109,6 +108,8 @@
mUnlockMethodCache = UnlockMethodCache.getInstance(context);
mKeyguardUpdateMonitor = KeyguardUpdateMonitor.getInstance(context);
mLightBarController = lightBarController;
+ mScrimBehindAlpha = context.getResources().getFloat(R.dimen.scrim_behind_alpha);
+
updateHeadsUpScrim(false);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index 270476e..54c67d2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -1,3 +1,5 @@
+
+
/*
* Copyright (C) 2010 The Android Open Source Project
*
@@ -69,6 +71,7 @@
import android.media.session.MediaSession;
import android.media.session.MediaSessionManager;
import android.media.session.PlaybackState;
+import android.metrics.LogMaker;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
@@ -112,6 +115,7 @@
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.statusbar.NotificationVisibility;
import com.android.internal.statusbar.StatusBarIcon;
+import com.android.internal.util.NotificationMessagingUtil;
import com.android.keyguard.KeyguardHostView.OnDismissAction;
import com.android.keyguard.KeyguardStatusView;
import com.android.keyguard.KeyguardUpdateMonitor;
@@ -269,8 +273,6 @@
protected static final int MSG_TOGGLE_RECENTS_APPS = 1021;
protected static final int MSG_PRELOAD_RECENT_APPS = 1022;
protected static final int MSG_CANCEL_PRELOAD_RECENT_APPS = 1023;
- protected static final int MSG_SHOW_NEXT_AFFILIATED_TASK = 1024;
- protected static final int MSG_SHOW_PREV_AFFILIATED_TASK = 1025;
protected static final int MSG_TOGGLE_KEYBOARD_SHORTCUTS_MENU = 1026;
protected static final int MSG_DISMISS_KEYBOARD_SHORTCUTS_MENU = 1027;
@@ -280,8 +282,8 @@
private static final String PERMISSION_SELF = "com.android.systemui.permission.SELF";
// Should match the values in PhoneWindowManager
- public static final String SYSTEM_DIALOG_REASON_RECENT_APPS = "recentapps";
public static final String SYSTEM_DIALOG_REASON_HOME_KEY = "homekey";
+ public static final String SYSTEM_DIALOG_REASON_RECENT_APPS = "recentapps";
private static final String BANNER_ACTION_CANCEL =
"com.android.systemui.statusbar.banner_action_cancel";
@@ -406,7 +408,7 @@
protected PhoneStatusBarView mStatusBarView;
private int mStatusBarWindowState = WINDOW_STATE_SHOWING;
protected StatusBarWindowManager mStatusBarWindowManager;
- private UnlockMethodCache mUnlockMethodCache;
+ protected UnlockMethodCache mUnlockMethodCache;
private DozeServiceHost mDozeServiceHost;
private boolean mWakeUpComingFromTouch;
private PointF mWakeUpTouchLocation;
@@ -601,8 +603,6 @@
new ArraySet<>();
private long mLastVisibilityReportUptimeMs;
- private final ShadeUpdates mShadeUpdates = new ShadeUpdates();
-
private Runnable mLaunchTransitionEndRunnable;
protected boolean mLaunchTransitionFadingAway;
private ExpandableNotificationRow mDraggedDownRow;
@@ -701,11 +701,14 @@
}
};
+ private NotificationMessagingUtil mMessagingUtil;
private KeyguardUserSwitcher mKeyguardUserSwitcher;
private UserSwitcherController mUserSwitcherController;
private NetworkController mNetworkController;
private KeyguardMonitorImpl mKeyguardMonitor;
private BatteryController mBatteryController;
+ private LogMaker mStatusBarStateLog;
+ private LockscreenGestureLogger mLockscreenGestureLogger = new LockscreenGestureLogger();
private void recycleAllVisibilityObjects(ArraySet<NotificationVisibility> array) {
final int N = array.size();
@@ -763,6 +766,7 @@
Context.DEVICE_POLICY_SERVICE);
mNotificationData = new NotificationData(this);
+ mMessagingUtil = new NotificationMessagingUtil(mContext);
mAccessibilityManager = (AccessibilityManager)
mContext.getSystemService(Context.ACCESSIBILITY_SERVICE);
@@ -948,19 +952,7 @@
inflateStatusBarWindow(context);
mStatusBarWindow.setService(this);
- mStatusBarWindow.setOnTouchListener(new View.OnTouchListener() {
- @Override
- public boolean onTouch(View v, MotionEvent event) {
- checkUserAutohide(v, event);
- checkRemoteInputOutside(event);
- if (event.getAction() == MotionEvent.ACTION_DOWN) {
- if (mExpandedVisible) {
- animateCollapsePanels();
- }
- }
- return mStatusBarWindow.onTouchEvent(event);
- }
- });
+ mStatusBarWindow.setOnTouchListener(getStatusBarWindowTouchListener());
mNotificationPanel = (NotificationPanelView) mStatusBarWindow.findViewById(
R.id.notification_panel);
@@ -1223,6 +1215,23 @@
}
}
+ /**
+ * Returns the {@link android.view.View.OnTouchListener} that will be invoked when the
+ * background window of the status bar is clicked.
+ */
+ protected View.OnTouchListener getStatusBarWindowTouchListener() {
+ return (v, event) -> {
+ checkUserAutohide(v, event);
+ checkRemoteInputOutside(event);
+ if (event.getAction() == MotionEvent.ACTION_DOWN) {
+ if (mExpandedVisible) {
+ animateCollapsePanels();
+ }
+ }
+ return mStatusBarWindow.onTouchEvent(event);
+ };
+ }
+
private void inflateShelf() {
mNotificationShelf =
(NotificationShelf) LayoutInflater.from(mContext).inflate(
@@ -1490,7 +1499,7 @@
ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT, null, metricsDockAction);
} else {
Divider divider = getComponent(Divider.class);
- if (divider != null && divider.isMinimized()) {
+ if (divider != null && divider.isMinimized() && !divider.isHomeStackResizable()) {
// Undocking from the minimized state is not supported
return false;
} else {
@@ -1883,7 +1892,6 @@
updateEmptyShadeView();
updateQsExpansionEnabled();
- mShadeUpdates.check();
// Let's also update the icons
mIconController.updateNotificationIcons(mNotificationData);
@@ -2752,28 +2760,6 @@
@Override
public void handleMessage(Message m) {
switch (m.what) {
- // start old BaseStatusBar.H handling.
- case MSG_SHOW_RECENT_APPS:
- showRecents(m.arg1 > 0, m.arg2 != 0);
- break;
- case MSG_HIDE_RECENT_APPS:
- hideRecents(m.arg1 > 0, m.arg2 > 0);
- break;
- case MSG_TOGGLE_RECENTS_APPS:
- toggleRecents();
- break;
- case MSG_PRELOAD_RECENT_APPS:
- preloadRecents();
- break;
- case MSG_CANCEL_PRELOAD_RECENT_APPS:
- cancelPreloadingRecents();
- break;
- case MSG_SHOW_NEXT_AFFILIATED_TASK:
- showRecentsNextAffiliatedTask();
- break;
- case MSG_SHOW_PREV_AFFILIATED_TASK:
- showRecentsPreviousAffiliatedTask();
- break;
case MSG_TOGGLE_KEYBOARD_SHORTCUTS_MENU:
toggleKeyboardShortcuts(m.arg1);
break;
@@ -3082,24 +3068,6 @@
}
@Override // CommandQueue
- public void buzzBeepBlinked() {
- }
-
- @Override
- public void notificationLightOff() {
- if (mDozeServiceHost != null) {
- mDozeServiceHost.fireNotificationLight(false);
- }
- }
-
- @Override
- public void notificationLightPulse(int argb, int onMillis, int offMillis) {
- if (mDozeServiceHost != null) {
- mDozeServiceHost.fireNotificationLight(true);
- }
- }
-
- @Override // CommandQueue
public void setSystemUiVisibility(int vis, int fullscreenStackVis, int dockedStackVis,
int mask, Rect fullscreenStackBounds, Rect dockedStackBounds) {
final int oldVal = mSystemUiVisibility;
@@ -3427,6 +3395,9 @@
} else {
pw.println(" mGroupManager: null");
}
+
+ mLightBarController.dump(fd, pw, args);
+
if (KeyguardUpdateMonitor.getInstance(mContext) != null) {
KeyguardUpdateMonitor.getInstance(mContext).dump(fd, pw, args);
}
@@ -3828,6 +3799,13 @@
isSecure,
canSkipBouncer);
if (stateFingerprint != mLastLoggedStateFingerprint) {
+ if (mStatusBarStateLog == null) {
+ mStatusBarStateLog = new LogMaker(MetricsEvent.VIEW_UNKNOWN);
+ }
+ MetricsLogger.action(mStatusBarStateLog
+ .setCategory(isBouncerShowing ? MetricsEvent.BOUNCER : MetricsEvent.LOCKSCREEN)
+ .setType(isShowing ? MetricsEvent.TYPE_OPEN : MetricsEvent.TYPE_CLOSE)
+ .setSubtype(isSecure ? 1 : 0));
EventLogTags.writeSysuiStatusBarState(mState,
isShowing ? 1 : 0,
isOccluded ? 1 : 0,
@@ -4508,8 +4486,8 @@
@Override
public void onActivated(ActivatableNotificationView view) {
- EventLogTags.writeSysuiLockscreenGesture(
- EventLogConstants.SYSUI_LOCKSCREEN_GESTURE_TAP_NOTIFICATION_ACTIVATE,
+ mLockscreenGestureLogger.write(
+ MetricsEvent.ACTION_LS_NOTE,
0 /* lengthDp - N/A */, 0 /* velocityDp - N/A */);
mKeyguardIndicationController.showTransientIndication(R.string.notification_tap_again);
ActivatableNotificationView previousView = mStackScroller.getActivatedChild();
@@ -4626,8 +4604,8 @@
@Override
public boolean onDraggedDown(View startingChild, int dragLengthY) {
if (hasActiveNotifications() && (!isDozing() || isPulsing())) {
- EventLogTags.writeSysuiLockscreenGesture(
- EventLogConstants.SYSUI_LOCKSCREEN_GESTURE_SWIPE_DOWN_FULL_SHADE,
+ mLockscreenGestureLogger.write(
+ MetricsEvent.ACTION_LS_SHADE,
(int) (dragLengthY / mDisplayMetrics.density),
0 /* velocityDp - N/A */);
@@ -5060,44 +5038,9 @@
return mStatusBarKeyguardViewManager.isShowing();
}
- private final class ShadeUpdates {
- private final ArraySet<String> mVisibleNotifications = new ArraySet<String>();
- private final ArraySet<String> mNewVisibleNotifications = new ArraySet<String>();
-
- public void check() {
- mNewVisibleNotifications.clear();
- ArrayList<Entry> activeNotifications = mNotificationData.getActiveNotifications();
- for (int i = 0; i < activeNotifications.size(); i++) {
- final Entry entry = activeNotifications.get(i);
- final boolean visible = entry.row != null
- && entry.row.getVisibility() == View.VISIBLE;
- if (visible) {
- mNewVisibleNotifications.add(entry.key + entry.notification.getPostTime());
- }
- }
- final boolean updates = !mVisibleNotifications.containsAll(mNewVisibleNotifications);
- mVisibleNotifications.clear();
- mVisibleNotifications.addAll(mNewVisibleNotifications);
-
- // We have new notifications
- if (updates && mDozeServiceHost != null) {
- mDozeServiceHost.fireNewNotifications();
- }
- }
- }
-
private final class DozeServiceHost implements DozeHost {
- // Amount of time to allow to update the time shown on the screen before releasing
- // the wakelock. This timeout is design to compensate for the fact that we don't
- // currently have a way to know when time display contents have actually been
- // refreshed once we've finished rendering a new frame.
- private static final long PROCESSING_TIME = 500;
-
private final ArrayList<Callback> mCallbacks = new ArrayList<Callback>();
- // Keeps the last reported state by fireNotificationLight.
- private boolean mNotificationLightOn;
-
@Override
public String toString() {
return "PSB.DozeServiceHost[mCallbacks=" + mCallbacks.size() + "]";
@@ -5115,19 +5058,6 @@
}
}
- public void fireNotificationLight(boolean on) {
- mNotificationLightOn = on;
- for (Callback callback : mCallbacks) {
- callback.onNotificationLight(on);
- }
- }
-
- public void fireNewNotifications() {
- for (Callback callback : mCallbacks) {
- callback.onNewNotifications();
- }
- }
-
@Override
public void addCallback(@NonNull Callback callback) {
mCallbacks.add(callback);
@@ -5193,11 +5123,6 @@
}
@Override
- public boolean isNotificationLightOn() {
- return mNotificationLightOn;
- }
-
- @Override
public void startPendingIntentDismissingKeyguard(PendingIntent intent) {
StatusBar.this.startPendingIntentDismissingKeyguard(intent);
}
@@ -5779,20 +5704,21 @@
PendingIntent.FLAG_CANCEL_CURRENT);
final int colorRes = com.android.internal.R.color.system_notification_accent_color;
- Notification.Builder note = new Notification.Builder(mContext)
- .setSmallIcon(R.drawable.ic_android)
- .setContentTitle(mContext.getString(R.string.hidden_notifications_title))
- .setContentText(mContext.getString(R.string.hidden_notifications_text))
- .setChannel(NotificationChannels.SECURITY)
- .setOngoing(true)
- .setColor(mContext.getColor(colorRes))
- .setContentIntent(setupIntent)
- .addAction(R.drawable.ic_close,
- mContext.getString(R.string.hidden_notifications_cancel),
- cancelIntent)
- .addAction(R.drawable.ic_settings,
- mContext.getString(R.string.hidden_notifications_setup),
- setupIntent);
+ Notification.Builder note =
+ new Notification.Builder(mContext, NotificationChannels.GENERAL)
+ .setSmallIcon(R.drawable.ic_android)
+ .setContentTitle(mContext.getString(
+ R.string.hidden_notifications_title))
+ .setContentText(mContext.getString(R.string.hidden_notifications_text))
+ .setOngoing(true)
+ .setColor(mContext.getColor(colorRes))
+ .setContentIntent(setupIntent)
+ .addAction(R.drawable.ic_close,
+ mContext.getString(R.string.hidden_notifications_cancel),
+ cancelIntent)
+ .addAction(R.drawable.ic_settings,
+ mContext.getString(R.string.hidden_notifications_setup),
+ setupIntent);
overrideNotificationAppName(mContext, note);
NotificationManager noMan =
@@ -6072,26 +5998,6 @@
}
@Override
- public void showRecentApps(boolean triggeredFromAltTab, boolean fromHome) {
- int msg = MSG_SHOW_RECENT_APPS;
- mHandler.removeMessages(msg);
- mHandler.obtainMessage(msg, triggeredFromAltTab ? 1 : 0, fromHome ? 1 : 0).sendToTarget();
- }
-
- @Override
- public void hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) {
- int msg = MSG_HIDE_RECENT_APPS;
- mHandler.removeMessages(msg);
- mHandler.obtainMessage(msg, triggeredFromAltTab ? 1 : 0,
- triggeredFromHomeKey ? 1 : 0).sendToTarget();
- }
-
- @Override
- public void toggleRecentApps() {
- toggleRecents();
- }
-
- @Override
public void toggleSplitScreen() {
toggleSplitScreenMode(-1 /* metricsDockAction */, -1 /* metricsUndockAction */);
}
@@ -6124,20 +6030,6 @@
mHandler.obtainMessage(msg, deviceId, 0).sendToTarget();
}
- /** Jumps to the next affiliated task in the group. */
- public void showNextAffiliatedTask() {
- int msg = MSG_SHOW_NEXT_AFFILIATED_TASK;
- mHandler.removeMessages(msg);
- mHandler.sendEmptyMessage(msg);
- }
-
- /** Jumps to the previous affiliated task in the group. */
- public void showPreviousAffiliatedTask() {
- int msg = MSG_SHOW_PREV_AFFILIATED_TASK;
- mHandler.removeMessages(msg);
- mHandler.sendEmptyMessage(msg);
- }
-
protected void sendCloseSystemWindows(String reason) {
try {
ActivityManager.getService().closeSystemDialogs(reason);
@@ -6145,33 +6037,6 @@
}
}
- /** Proxy for RecentsComponent */
-
- protected void showRecents(boolean triggeredFromAltTab, boolean fromHome) {
- if (mRecents != null) {
- sendCloseSystemWindows(SYSTEM_DIALOG_REASON_RECENT_APPS);
- mRecents.showRecents(triggeredFromAltTab, fromHome);
- }
- }
-
- protected void hideRecents(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) {
- if (mRecents != null) {
- mRecents.hideRecents(triggeredFromAltTab, triggeredFromHomeKey);
- }
- }
-
- protected void toggleRecents() {
- if (mRecents != null) {
- mRecents.toggleRecents(mDisplay);
- }
- }
-
- protected void preloadRecents() {
- if (mRecents != null) {
- mRecents.preloadRecents();
- }
- }
-
protected void toggleKeyboardShortcuts(int deviceId) {
KeyboardShortcuts.toggle(mContext, deviceId);
}
@@ -6180,24 +6045,6 @@
KeyboardShortcuts.dismiss();
}
- protected void cancelPreloadingRecents() {
- if (mRecents != null) {
- mRecents.cancelPreloadingRecents();
- }
- }
-
- protected void showRecentsNextAffiliatedTask() {
- if (mRecents != null) {
- mRecents.showNextAffiliatedTask();
- }
- }
-
- protected void showRecentsPreviousAffiliatedTask() {
- if (mRecents != null) {
- mRecents.showPrevAffiliatedTask();
- }
- }
-
/**
* Save the current "public" (locked and secure) state of the lockscreen.
*/
@@ -6321,8 +6168,10 @@
final StatusBarNotification sbn = entry.notification;
boolean isLowPriority = mNotificationData.isAmbient(sbn.getKey());
+ boolean useIncreasedCollapsedHeight = mMessagingUtil.isImportantMessaging(sbn,
+ mNotificationData.getImportance(sbn.getKey()));
try {
- entry.cacheContentViews(mContext, null, isLowPriority);
+ entry.cacheContentViews(mContext, null, isLowPriority, useIncreasedCollapsedHeight);
} catch (RuntimeException e) {
Log.e(TAG, "Unable to get notification remote views", e);
return false;
@@ -6492,6 +6341,7 @@
row.setUserExpanded(userExpanded);
}
row.setUserLocked(userLocked);
+ row.setUseIncreasedCollapsedHeight(useIncreasedCollapsedHeight);
row.onNotificationUpdated(entry);
return true;
}
@@ -6981,10 +6831,13 @@
Notification n = notification.getNotification();
mNotificationData.updateRanking(ranking);
+ boolean useIncreasedCollapsedHeight = mMessagingUtil.isImportantMessaging(notification,
+ mNotificationData.getImportance(notification.getKey()));
+ entry.row.setUseIncreasedCollapsedHeight(useIncreasedCollapsedHeight);
boolean applyInPlace;
try {
applyInPlace = entry.cacheContentViews(mContext, notification.getNotification(),
- mNotificationData.isAmbient(key));
+ mNotificationData.isAmbient(key), useIncreasedCollapsedHeight);
} catch (RuntimeException e) {
Log.e(TAG, "Unable to get notification remote views", e);
applyInPlace = false;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
index 46ca3c6..41f8a91 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
@@ -36,6 +36,7 @@
import android.widget.TextView;
import com.android.internal.statusbar.StatusBarIcon;
import com.android.systemui.BatteryMeterView;
+import com.android.systemui.Dependency;
import com.android.systemui.FontSizeUtils;
import com.android.systemui.Interpolators;
import com.android.systemui.R;
@@ -127,7 +128,7 @@
mLightModeIconColorSingleTone = context.getColor(R.color.light_mode_icon_color_single_tone);
loadDimens();
- TunerService.get(mContext).addTunable(this, ICON_BLACKLIST);
+ Dependency.get(TunerService.class).addTunable(this, ICON_BLACKLIST);
mTransitionsController = new LightBarTransitionsController(this::setIconTintInternal);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
index 9cc9749..ffc0d97 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
@@ -108,7 +108,7 @@
getContext().registerReceiverAsUser(mIntentReceiver, UserHandle.ALL, filter,
null, Dependency.get(Dependency.TIME_TICK_HANDLER));
- TunerService.get(getContext()).addTunable(this, CLOCK_SECONDS,
+ Dependency.get(TunerService.class).addTunable(this, CLOCK_SECONDS,
StatusBarIconController.ICON_BLACKLIST);
}
@@ -129,7 +129,7 @@
if (mAttached) {
getContext().unregisterReceiver(mIntentReceiver);
mAttached = false;
- TunerService.get(getContext()).removeTunable(this);
+ Dependency.get(TunerService.class).removeTunable(this);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
index fd71f43..7a32bf1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
@@ -560,18 +560,20 @@
private void showLogoutNotification(int userId) {
PendingIntent logoutPI = PendingIntent.getBroadcastAsUser(mContext,
0, new Intent(ACTION_LOGOUT_USER), 0, UserHandle.SYSTEM);
- Notification.Builder builder = new Notification.Builder(mContext)
- .setVisibility(Notification.VISIBILITY_SECRET)
- .setChannel(NotificationChannels.USER)
- .setSmallIcon(R.drawable.ic_person)
- .setContentTitle(mContext.getString(R.string.user_logout_notification_title))
- .setContentText(mContext.getString(R.string.user_logout_notification_text))
- .setContentIntent(logoutPI)
- .setOngoing(true)
- .setShowWhen(false)
- .addAction(R.drawable.ic_delete,
- mContext.getString(R.string.user_logout_notification_action),
- logoutPI);
+ Notification.Builder builder =
+ new Notification.Builder(mContext, NotificationChannels.GENERAL)
+ .setVisibility(Notification.VISIBILITY_SECRET)
+ .setSmallIcon(R.drawable.ic_person)
+ .setContentTitle(mContext.getString(
+ R.string.user_logout_notification_title))
+ .setContentText(mContext.getString(
+ R.string.user_logout_notification_text))
+ .setContentIntent(logoutPI)
+ .setOngoing(true)
+ .setShowWhen(false)
+ .addAction(R.drawable.ic_delete,
+ mContext.getString(R.string.user_logout_notification_action),
+ logoutPI);
SystemUI.overrideNotificationAppName(mContext, builder);
NotificationManager.from(mContext).notifyAsUser(TAG_LOGOUT_USER,
SystemMessage.NOTE_LOGOUT_USER, builder.build(), new UserHandle(userId));
@@ -584,17 +586,17 @@
PendingIntent removeGuestPI = canSwitchUsers ? PendingIntent.getBroadcastAsUser(mContext,
0, new Intent(ACTION_REMOVE_GUEST), 0, UserHandle.SYSTEM) : null;
- Notification.Builder builder = new Notification.Builder(mContext)
- .setVisibility(Notification.VISIBILITY_SECRET)
- .setChannel(NotificationChannels.USER)
- .setSmallIcon(R.drawable.ic_person)
- .setContentTitle(mContext.getString(R.string.guest_notification_title))
- .setContentText(mContext.getString(R.string.guest_notification_text))
- .setContentIntent(removeGuestPI)
- .setShowWhen(false)
- .addAction(R.drawable.ic_delete,
- mContext.getString(R.string.guest_notification_remove_action),
- removeGuestPI);
+ Notification.Builder builder =
+ new Notification.Builder(mContext, NotificationChannels.GENERAL)
+ .setVisibility(Notification.VISIBILITY_SECRET)
+ .setSmallIcon(R.drawable.ic_person)
+ .setContentTitle(mContext.getString(R.string.guest_notification_title))
+ .setContentText(mContext.getString(R.string.guest_notification_text))
+ .setContentIntent(removeGuestPI)
+ .setShowWhen(false)
+ .addAction(R.drawable.ic_delete,
+ mContext.getString(R.string.guest_notification_remove_action),
+ removeGuestPI);
SystemUI.overrideNotificationAppName(mContext, builder);
NotificationManager.from(mContext).notifyAsUser(TAG_REMOVE_GUEST,
SystemMessage.NOTE_REMOVE_GUEST, builder.build(), new UserHandle(guestUserId));
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
index 85b1c32..11927729 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -27,6 +27,7 @@
import android.annotation.Nullable;
import android.content.Context;
import android.content.res.Configuration;
+import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
@@ -55,7 +56,6 @@
import android.view.animation.Interpolator;
import android.widget.OverScroller;
import android.widget.ScrollView;
-
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.systemui.ExpandHelper;
@@ -114,6 +114,7 @@
private boolean mSwipingInProgress;
private int mCurrentStackHeight = Integer.MAX_VALUE;
private final Paint mBackgroundPaint = new Paint();
+ private boolean mShouldDrawNotificationBackground;
private float mExpandedHeight;
private int mOwnScrollY;
@@ -229,6 +230,7 @@
private NotificationMenuRow mCurrIconRow;
private View mTranslatingParentView;
private View mGearExposedView;
+ private boolean mShouldShowGear;
/**
* Should in this touch motion only be scrolling allowed? It's true when the scroller was
@@ -378,10 +380,12 @@
public NotificationStackScrollLayout(Context context, AttributeSet attrs, int defStyleAttr,
int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
+ Resources res = getResources();
+
mAmbientState = new AmbientState(context);
mBgColor = context.getColor(R.color.notification_shade_background_color);
- int minHeight = getResources().getDimensionPixelSize(R.dimen.notification_min_height);
- int maxHeight = getResources().getDimensionPixelSize(R.dimen.notification_max_height);
+ int minHeight = res.getDimensionPixelSize(R.dimen.notification_min_height);
+ int maxHeight = res.getDimensionPixelSize(R.dimen.notification_max_height);
mExpandHelper = new ExpandHelper(getContext(), this,
minHeight, maxHeight);
mExpandHelper.setEventSource(this);
@@ -390,14 +394,18 @@
mSwipeHelper.setLongPressListener(mLongPressListener);
mStackScrollAlgorithm = createStackScrollAlgorithm(context);
initView(context);
- setWillNotDraw(false);
+ mFalsingManager = FalsingManager.getInstance(context);
+ mShouldShowGear = res.getBoolean(R.bool.config_showNotificationGear);
+ mShouldDrawNotificationBackground =
+ res.getBoolean(R.bool.config_drawNotificationBackground);
+
+ updateWillNotDraw();
if (DEBUG) {
mDebugPaint = new Paint();
mDebugPaint.setColor(0xffff0000);
mDebugPaint.setStrokeWidth(2);
mDebugPaint.setStyle(Paint.Style.STROKE);
}
- mFalsingManager = FalsingManager.getInstance(context);
}
@Override
@@ -424,10 +432,11 @@
@Override
protected void onDraw(Canvas canvas) {
- if (mCurrentBounds.top < mCurrentBounds.bottom) {
+ if (mShouldDrawNotificationBackground && mCurrentBounds.top < mCurrentBounds.bottom) {
canvas.drawRect(0, mCurrentBounds.top, getWidth(), mCurrentBounds.bottom,
mBackgroundPaint);
}
+
if (DEBUG) {
int y = mTopPadding;
canvas.drawLine(0, y, getWidth(), y, mDebugPaint);
@@ -439,6 +448,11 @@
}
private void updateBackgroundDimming() {
+ // No need to update the background color if it's not being drawn.
+ if (!mShouldDrawNotificationBackground) {
+ return;
+ }
+
float alpha = BACKGROUND_ALPHA_DIMMED + (1 - BACKGROUND_ALPHA_DIMMED) * (1.0f - mDimAmount);
alpha *= mBackgroundFadeAmount;
// We need to manually blend in the background color
@@ -487,6 +501,10 @@
}
private void updateSrcDrawing() {
+ if (!mShouldDrawNotificationBackground) {
+ return;
+ }
+
mBackgroundPaint.setXfermode(mDrawBackgroundAsSrc && !mFadingOut && !mParentNotFullyVisible
? mSrcMode : null);
invalidate();
@@ -1967,9 +1985,11 @@
}
private void updateBackground() {
- if (mAmbientState.isDark()) {
+ // No need to update the background color if it's not being drawn.
+ if (!mShouldDrawNotificationBackground || mAmbientState.isDark()) {
return;
}
+
updateBackgroundBounds();
if (!mCurrentBounds.equals(mBackgroundBounds)) {
boolean animate = mAnimateNextBackgroundTop || mAnimateNextBackgroundBottom
@@ -2119,6 +2139,12 @@
}
private void applyCurrentBackgroundBounds() {
+ // If the background of the notification is not being drawn, then there is no need to
+ // exclude an area in the scrim. Rather, the scrim's color should serve as the background.
+ if (!mShouldDrawNotificationBackground) {
+ return;
+ }
+
mScrimController.setExcludedBackgroundArea(
mFadingOut || mParentNotFullyVisible || mAmbientState.isDark() || mIsClipped ? null
: mCurrentBounds);
@@ -2740,6 +2766,7 @@
private void updateNotificationAnimationStates() {
boolean running = mAnimationsEnabled || mPulsing;
+ mShelf.setAnimationsEnabled(running);
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
@@ -3545,16 +3572,29 @@
}
requestChildrenUpdate();
if (dark) {
- setWillNotDraw(!DEBUG);
mScrimController.setExcludedBackgroundArea(null);
} else {
updateBackground();
- setWillNotDraw(false);
}
+
+ updateWillNotDraw();
updateContentHeight();
notifyHeightChangeListener(mShelf);
}
+ /**
+ * Updates whether or not this Layout will perform its own custom drawing (i.e. whether or
+ * not {@link #onDraw(Canvas)} is called). This method should be called whenever the
+ * {@link #mAmbientState}'s dark mode is toggled.
+ */
+ private void updateWillNotDraw() {
+ if (mAmbientState.isDark()) {
+ setWillNotDraw(!DEBUG);
+ } else {
+ setWillNotDraw(!mShouldDrawNotificationBackground && !DEBUG);
+ }
+ }
+
private void setBackgroundFadeAmount(float fadeAmount) {
mBackgroundFadeAmount = fadeAmount;
updateBackgroundDimming();
@@ -4106,14 +4146,14 @@
* A listener that is notified when some child locations might have changed.
*/
public interface OnChildLocationsChangedListener {
- public void onChildLocationsChanged(NotificationStackScrollLayout stackScrollLayout);
+ void onChildLocationsChanged(NotificationStackScrollLayout stackScrollLayout);
}
/**
* A listener that is notified when the empty space below the notifications is clicked on
*/
public interface OnEmptySpaceClickListener {
- public void onEmptySpaceClicked(float x, float y);
+ void onEmptySpaceClicked(float x, float y);
}
/**
@@ -4129,7 +4169,7 @@
* unrubberbanded motion to directly expand overscroll view (e.g expand
* QS)
*/
- public void onOverscrollTopChanged(float amount, boolean isRubberbanded);
+ void onOverscrollTopChanged(float amount, boolean isRubberbanded);
/**
* Notify a listener that the scroller wants to escape from the scrolling motion and
@@ -4138,7 +4178,7 @@
* @param velocity The velocity that the Scroller had when over flinging
* @param open Should the fling open or close the overscroll view.
*/
- public void flingTopOverscroll(float velocity, boolean open);
+ void flingTopOverscroll(float velocity, boolean open);
}
private class NotificationSwipeHelper extends SwipeHelper {
@@ -4216,7 +4256,7 @@
final boolean gutsExposed = (view instanceof ExpandableNotificationRow)
&& ((ExpandableNotificationRow) view).areGutsExposed();
- if (!isPinnedHeadsUp(view) && !gutsExposed) {
+ if (mShouldShowGear && !isPinnedHeadsUp(view) && !gutsExposed) {
// Only show the gear if we're not a heads up view and guts aren't exposed.
checkForDrag();
}
@@ -4259,11 +4299,19 @@
return false; // Let SwipeHelper handle it.
}
+ // If the gear icon should not be shown, then there is no need to check if the a swipe
+ // should result in a snapping to the gear icon. As a result, just check if the swipe
+ // was enough to dismiss the notification.
+ if (!mShouldShowGear) {
+ dismissOrSnapBack(animView, velocity, ev);
+ return true;
+ }
+
boolean gestureTowardsGear = isTowardsGear(velocity, mCurrIconRow.isMenuOnLeft());
boolean gestureFastEnough = Math.abs(velocity) > getEscapeVelocity();
final double timeForGesture = ev.getEventTime() - ev.getDownTime();
final boolean showGearForSlowOnGoing = !canChildBeDismissed(animView)
- && timeForGesture >= SWIPE_GEAR_TIMING;
+ && timeForGesture >= SWIPE_GEAR_TIMING;
if (mGearSnappedTo && mCurrIconRow.isVisible()) {
if (mGearSnappedOnLeft == mCurrIconRow.isMenuOnLeft()) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
index ab562d1..5d11ef3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
@@ -42,104 +42,11 @@
private IStatusBarService mBarService;
@Override
- public void setIcon(String slot, StatusBarIcon icon) {
- }
-
- @Override
- public void removeIcon(String slot) {
- }
-
- public void removeNotification(String key, RankingMap ranking) {
- }
-
- @Override
- public void disable(int state1, int state2, boolean animate) {
- }
-
- @Override
- public void animateExpandNotificationsPanel() {
- }
-
- @Override
- public void animateCollapsePanels(int flags) {
- }
-
- @Override
- public void setSystemUiVisibility(int vis, int fullscreenStackVis, int dockedStackVis,
- int mask, Rect fullscreenStackBounds, Rect dockedStackBounds) {
- }
-
- @Override
- public void topAppWindowChanged(boolean visible) {
- }
-
- @Override
- public void setImeWindowStatus(IBinder token, int vis, int backDisposition,
- boolean showImeSwitcher) {
- }
-
- @Override // CommandQueue
- public void setWindowState(int window, int state) {
- }
-
- @Override // CommandQueue
- public void buzzBeepBlinked() {
- }
-
- @Override // CommandQueue
- public void notificationLightOff() {
- }
-
- @Override // CommandQueue
- public void notificationLightPulse(int argb, int onMillis, int offMillis) {
- }
-
- @Override
- public void animateExpandSettingsPanel(String subPanel) {
- }
-
- @Override
- public void showScreenPinningRequest(int taskId) {
- }
-
- @Override
- public void appTransitionPending() {
- }
-
- @Override
- public void appTransitionCancelled() {
- }
-
- @Override
- public void appTransitionStarting(long startTime, long duration) {
- }
-
- @Override
- public void appTransitionFinished() {
- }
-
- @Override
- public void onCameraLaunchGestureDetected(int source) {
- }
-
- @Override
public void showTvPictureInPictureMenu() {
PipManager.getInstance().showTvPictureInPictureMenu();
}
@Override
- public void addQsTile(ComponentName tile) {
- }
-
- @Override
- public void remQsTile(ComponentName tile) {
- }
-
- @Override
- public void clickTile(ComponentName tile) {
- }
-
- @Override
public void start() {
putComponent(TvStatusBar.class, this);
CommandQueue commandQueue = getComponent(CommandQueue.class);
@@ -160,8 +67,4 @@
}
}
- @Override
- public void handleSystemNavigationKey(int arg1) {
- // Not implemented
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/BatteryPreference.java b/packages/SystemUI/src/com/android/systemui/tuner/BatteryPreference.java
index 9998283..3058c0a 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/BatteryPreference.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/BatteryPreference.java
@@ -22,6 +22,7 @@
import android.util.AttributeSet;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.systemui.Dependency;
import com.android.systemui.statusbar.phone.StatusBarIconController;
import static com.android.systemui.BatteryMeterDrawable.SHOW_PERCENT_SETTING;
@@ -49,12 +50,12 @@
super.onAttached();
mHasPercentage = Settings.System.getInt(getContext().getContentResolver(),
SHOW_PERCENT_SETTING, 0) != 0;
- TunerService.get(getContext()).addTunable(this, StatusBarIconController.ICON_BLACKLIST);
+ Dependency.get(TunerService.class).addTunable(this, StatusBarIconController.ICON_BLACKLIST);
}
@Override
public void onDetached() {
- TunerService.get(getContext()).removeTunable(this);
+ Dependency.get(TunerService.class).removeTunable(this);
super.onDetached();
}
@@ -89,7 +90,7 @@
} else {
mBlacklist.remove(mBattery);
}
- TunerService.get(getContext()).setValue(StatusBarIconController.ICON_BLACKLIST,
+ Dependency.get(TunerService.class).setValue(StatusBarIconController.ICON_BLACKLIST,
TextUtils.join(",", mBlacklist));
return true;
}
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/ClockPreference.java b/packages/SystemUI/src/com/android/systemui/tuner/ClockPreference.java
index caa0527..014ec92 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/ClockPreference.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/ClockPreference.java
@@ -18,6 +18,8 @@
import android.text.TextUtils;
import android.util.ArraySet;
import android.util.AttributeSet;
+
+import com.android.systemui.Dependency;
import com.android.systemui.statusbar.phone.StatusBarIconController;
import com.android.systemui.statusbar.policy.Clock;
@@ -44,13 +46,13 @@
@Override
public void onAttached() {
super.onAttached();
- TunerService.get(getContext()).addTunable(this, StatusBarIconController.ICON_BLACKLIST,
+ Dependency.get(TunerService.class).addTunable(this, StatusBarIconController.ICON_BLACKLIST,
Clock.CLOCK_SECONDS);
}
@Override
public void onDetached() {
- TunerService.get(getContext()).removeTunable(this);
+ Dependency.get(TunerService.class).removeTunable(this);
super.onDetached();
}
@@ -81,13 +83,14 @@
@Override
protected boolean persistString(String value) {
- TunerService.get(getContext()).setValue(Clock.CLOCK_SECONDS, SECONDS.equals(value) ? 1 : 0);
+ Dependency.get(TunerService.class).setValue(Clock.CLOCK_SECONDS, SECONDS.equals(value) ? 1
+ : 0);
if (DISABLED.equals(value)) {
mBlacklist.add(mClock);
} else {
mBlacklist.remove(mClock);
}
- TunerService.get(getContext()).setValue(StatusBarIconController.ICON_BLACKLIST,
+ Dependency.get(TunerService.class).setValue(StatusBarIconController.ICON_BLACKLIST,
TextUtils.join(",", mBlacklist));
return true;
}
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/LockscreenFragment.java b/packages/SystemUI/src/com/android/systemui/tuner/LockscreenFragment.java
index 41786b5..9d579f5 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/LockscreenFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/LockscreenFragment.java
@@ -43,6 +43,7 @@
import android.widget.ImageView;
import android.widget.TextView;
+import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.plugins.IntentButtonProvider.IntentButton;
import com.android.systemui.statusbar.phone.ExpandableIndicator;
@@ -71,7 +72,7 @@
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
- mTunerService = TunerService.get(getContext());
+ mTunerService = Dependency.get(TunerService.class);
mHandler = new Handler();
addPreferencesFromResource(R.xml.lockscreen_settings);
setupGroup((PreferenceGroup) findPreference(KEY_LEFT), LOCKSCREEN_LEFT_BUTTON,
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/NavBarTuner.java b/packages/SystemUI/src/com/android/systemui/tuner/NavBarTuner.java
index 9593c45..28a0057 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/NavBarTuner.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/NavBarTuner.java
@@ -51,6 +51,7 @@
import android.view.KeyEvent;
import android.widget.EditText;
+import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.statusbar.phone.NavigationBarInflaterView;
import com.android.systemui.tuner.TunerService.Tunable;
@@ -104,12 +105,12 @@
@Override
public void onDestroy() {
super.onDestroy();
- mTunables.forEach(t -> TunerService.get(getContext()).removeTunable(t));
+ mTunables.forEach(t -> Dependency.get(TunerService.class).removeTunable(t));
}
private void addTunable(Tunable tunable, String... keys) {
mTunables.add(tunable);
- TunerService.get(getContext()).addTunable(tunable, keys);
+ Dependency.get(TunerService.class).addTunable(tunable, keys);
}
private void bindLayout(ListPreference preference) {
@@ -123,7 +124,7 @@
preference.setOnPreferenceChangeListener((preference1, newValue) -> {
String val = (String) newValue;
if ("default".equals(val)) val = null;
- TunerService.get(getContext()).setValue(NAV_BAR_VIEWS, val);
+ Dependency.get(TunerService.class).setValue(NAV_BAR_VIEWS, val);
return true;
});
}
@@ -215,7 +216,7 @@
}
button = button + KEY_CODE_START + code + KEY_IMAGE_DELIM + uri + KEY_CODE_END;
}
- TunerService.get(getContext()).setValue(setting, button);
+ Dependency.get(TunerService.class).setValue(setting, button);
}
private void setupIcons(ListPreference icon) {
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/PreviewNavInflater.java b/packages/SystemUI/src/com/android/systemui/tuner/PreviewNavInflater.java
index e6e8f4e..e7a695f 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/PreviewNavInflater.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/PreviewNavInflater.java
@@ -18,6 +18,7 @@
import android.util.AttributeSet;
import android.view.MotionEvent;
+import com.android.systemui.Dependency;
import com.android.systemui.statusbar.phone.NavigationBarInflaterView;
public class PreviewNavInflater extends NavigationBarInflaterView {
@@ -31,7 +32,7 @@
super.onAttachedToWindow();
// Immediately remove tuner listening, since this is a preview, all values will be injected
// manually.
- TunerService.get(getContext()).removeTunable(this);
+ Dependency.get(TunerService.class).removeTunable(this);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/StatusBarSwitch.java b/packages/SystemUI/src/com/android/systemui/tuner/StatusBarSwitch.java
index dea2f50..8a2407a 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/StatusBarSwitch.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/StatusBarSwitch.java
@@ -25,6 +25,7 @@
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.systemui.Dependency;
import com.android.systemui.statusbar.phone.StatusBarIconController;
import com.android.systemui.tuner.TunerService.Tunable;
@@ -41,12 +42,12 @@
@Override
public void onAttached() {
super.onAttached();
- TunerService.get(getContext()).addTunable(this, StatusBarIconController.ICON_BLACKLIST);
+ Dependency.get(TunerService.class).addTunable(this, StatusBarIconController.ICON_BLACKLIST);
}
@Override
public void onDetached() {
- TunerService.get(getContext()).removeTunable(this);
+ Dependency.get(TunerService.class).removeTunable(this);
super.onDetached();
}
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerActivity.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerActivity.java
index 3b14e60..74280a3 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/TunerActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerActivity.java
@@ -24,6 +24,7 @@
import android.util.Log;
import com.android.settingslib.drawer.SettingsDrawerActivity;
+import com.android.systemui.Dependency;
import com.android.systemui.R;
public class TunerActivity extends SettingsDrawerActivity implements
@@ -36,6 +37,7 @@
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ Dependency.initDependencies(this);
if (getFragmentManager().findFragmentByTag(TAG_TUNER) == null) {
final String action = getIntent().getAction();
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerService.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerService.java
index fb94061..ca582b3 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/TunerService.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerService.java
@@ -40,6 +40,7 @@
import com.android.systemui.BatteryMeterDrawable;
import com.android.systemui.DemoMode;
+import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.SystemUI;
import com.android.systemui.SystemUIApplication;
@@ -51,7 +52,7 @@
import java.util.Set;
-public class TunerService extends SystemUI {
+public class TunerService {
public static final String ACTION_CLEAR = "com.android.systemui.action.CLEAR_TUNER";
@@ -64,13 +65,14 @@
private final ArrayMap<Uri, String> mListeningUris = new ArrayMap<>();
// Map of settings keys to the listener.
private final HashMap<String, Set<Tunable>> mTunableLookup = new HashMap<>();
+ private final Context mContext;
private ContentResolver mContentResolver;
private int mCurrentUser;
private CurrentUserTracker mUserTracker;
- @Override
- public void start() {
+ public TunerService(Context context) {
+ mContext = context;
mContentResolver = mContext.getContentResolver();
for (UserInfo user : UserManager.get(mContext).getUsers()) {
@@ -79,7 +81,6 @@
upgradeTuner(getValue(TUNER_VERSION, 0), CURRENT_TUNER_VERSION);
}
}
- putComponent(TunerService.class, this);
mCurrentUser = ActivityManager.getCurrentUser();
mUserTracker = new CurrentUserTracker(mContext) {
@@ -209,32 +210,6 @@
}
}
- // Only used in other processes, such as the tuner.
- private static TunerService sInstance;
-
- public static TunerService get(Context context) {
- TunerService service = null;
- if (context.getApplicationContext() instanceof SystemUIApplication) {
- SystemUIApplication sysUi = (SystemUIApplication) context.getApplicationContext();
- service = sysUi.getComponent(TunerService.class);
- }
- if (service == null) {
- // Can't get it as a component, must in the tuner, lets just create one for now.
- return getStaticService(context);
- }
- return service;
- }
-
- private static TunerService getStaticService(Context context) {
- if (sInstance == null) {
- sInstance = new TunerService();
- sInstance.mContext = context.getApplicationContext();
- sInstance.mComponents = new HashMap<>();
- sInstance.start();
- }
- return sInstance;
- }
-
public static final void showResetRequest(final Context context, final Runnable onDisabled) {
SystemUIDialog dialog = new SystemUIDialog(context);
dialog.setShowForAllUsers(true);
@@ -310,7 +285,7 @@
@Override
public void onReceive(Context context, Intent intent) {
if (ACTION_CLEAR.equals(intent.getAction())) {
- get(context).clearAll();
+ Dependency.get(TunerService.class).clearAll();
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerSwitch.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerSwitch.java
index 5b9ebd7..d5b6ccd 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/TunerSwitch.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerSwitch.java
@@ -7,6 +7,7 @@
import android.util.AttributeSet;
import com.android.internal.logging.MetricsLogger;
+import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.tuner.TunerService.Tunable;
@@ -26,12 +27,12 @@
@Override
public void onAttached() {
super.onAttached();
- TunerService.get(getContext()).addTunable(this, getKey().split(","));
+ Dependency.get(TunerService.class).addTunable(this, getKey().split(","));
}
@Override
public void onDetached() {
- TunerService.get(getContext()).removeTunable(this);
+ Dependency.get(TunerService.class).removeTunable(this);
super.onDetached();
}
diff --git a/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java b/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
index 9a16d6d..43727e0 100644
--- a/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
+++ b/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
@@ -198,18 +198,19 @@
rec.getNickname());
final CharSequence text = mContext.getString(R.string.ext_media_missing_message);
- Notification.Builder builder = new Notification.Builder(mContext)
- .setSmallIcon(R.drawable.ic_sd_card_48dp)
- .setColor(mContext.getColor(R.color.system_notification_accent_color))
- .setContentTitle(title)
- .setContentText(text)
- .setContentIntent(buildForgetPendingIntent(rec))
- .setStyle(new Notification.BigTextStyle().bigText(text))
- .setVisibility(Notification.VISIBILITY_PUBLIC)
- .setLocalOnly(true)
- .setChannel(NotificationChannels.STORAGE)
- .setCategory(Notification.CATEGORY_SYSTEM)
- .setDeleteIntent(buildSnoozeIntent(fsUuid));
+ Notification.Builder builder =
+ new Notification.Builder(mContext, NotificationChannels.STORAGE)
+ .setSmallIcon(R.drawable.ic_sd_card_48dp)
+ .setColor(mContext.getColor(
+ R.color.system_notification_accent_color))
+ .setContentTitle(title)
+ .setContentText(text)
+ .setContentIntent(buildForgetPendingIntent(rec))
+ .setStyle(new Notification.BigTextStyle().bigText(text))
+ .setVisibility(Notification.VISIBILITY_PUBLIC)
+ .setLocalOnly(true)
+ .setCategory(Notification.CATEGORY_SYSTEM)
+ .setDeleteIntent(buildSnoozeIntent(fsUuid));
SystemUI.overrideNotificationAppName(mContext, builder);
mNotificationManager.notifyAsUser(fsUuid, SystemMessage.NOTE_STORAGE_PRIVATE,
@@ -226,17 +227,17 @@
final CharSequence text = mContext.getString(
R.string.ext_media_unsupported_notification_message, disk.getDescription());
- Notification.Builder builder = new Notification.Builder(mContext)
- .setChannel(NotificationChannels.STORAGE)
- .setSmallIcon(getSmallIcon(disk, VolumeInfo.STATE_UNMOUNTABLE))
- .setColor(mContext.getColor(R.color.system_notification_accent_color))
- .setContentTitle(title)
- .setContentText(text)
- .setContentIntent(buildInitPendingIntent(disk))
- .setStyle(new Notification.BigTextStyle().bigText(text))
- .setVisibility(Notification.VISIBILITY_PUBLIC)
- .setLocalOnly(true)
- .setCategory(Notification.CATEGORY_ERROR);
+ Notification.Builder builder =
+ new Notification.Builder(mContext, NotificationChannels.STORAGE)
+ .setSmallIcon(getSmallIcon(disk, VolumeInfo.STATE_UNMOUNTABLE))
+ .setColor(mContext.getColor(R.color.system_notification_accent_color))
+ .setContentTitle(title)
+ .setContentText(text)
+ .setContentIntent(buildInitPendingIntent(disk))
+ .setStyle(new Notification.BigTextStyle().bigText(text))
+ .setVisibility(Notification.VISIBILITY_PUBLIC)
+ .setLocalOnly(true)
+ .setCategory(Notification.CATEGORY_ERROR);
SystemUI.overrideNotificationAppName(mContext, builder);
mNotificationManager.notifyAsUser(disk.getId(), SystemMessage.NOTE_STORAGE_DISK,
@@ -475,19 +476,19 @@
intent = buildWizardMigratePendingIntent(move);
}
- Notification.Builder builder = new Notification.Builder(mContext)
- .setSmallIcon(R.drawable.ic_sd_card_48dp)
- .setColor(mContext.getColor(R.color.system_notification_accent_color))
- .setContentTitle(title)
- .setContentText(text)
- .setContentIntent(intent)
- .setStyle(new Notification.BigTextStyle().bigText(text))
- .setVisibility(Notification.VISIBILITY_PUBLIC)
- .setLocalOnly(true)
- .setChannel(NotificationChannels.STORAGE)
- .setCategory(Notification.CATEGORY_PROGRESS)
- .setProgress(100, status, false)
- .setOngoing(true);
+ Notification.Builder builder =
+ new Notification.Builder(mContext, NotificationChannels.STORAGE)
+ .setSmallIcon(R.drawable.ic_sd_card_48dp)
+ .setColor(mContext.getColor(R.color.system_notification_accent_color))
+ .setContentTitle(title)
+ .setContentText(text)
+ .setContentIntent(intent)
+ .setStyle(new Notification.BigTextStyle().bigText(text))
+ .setVisibility(Notification.VISIBILITY_PUBLIC)
+ .setLocalOnly(true)
+ .setCategory(Notification.CATEGORY_PROGRESS)
+ .setProgress(100, status, false)
+ .setOngoing(true);
SystemUI.overrideNotificationAppName(mContext, builder);
mNotificationManager.notifyAsUser(move.packageName, SystemMessage.NOTE_STORAGE_MOVE,
@@ -526,18 +527,18 @@
intent = null;
}
- Notification.Builder builder = new Notification.Builder(mContext)
- .setSmallIcon(R.drawable.ic_sd_card_48dp)
- .setColor(mContext.getColor(R.color.system_notification_accent_color))
- .setContentTitle(title)
- .setContentText(text)
- .setContentIntent(intent)
- .setStyle(new Notification.BigTextStyle().bigText(text))
- .setVisibility(Notification.VISIBILITY_PUBLIC)
- .setLocalOnly(true)
- .setCategory(Notification.CATEGORY_SYSTEM)
- .setChannel(NotificationChannels.STORAGE)
- .setAutoCancel(true);
+ Notification.Builder builder =
+ new Notification.Builder(mContext, NotificationChannels.STORAGE)
+ .setSmallIcon(R.drawable.ic_sd_card_48dp)
+ .setColor(mContext.getColor(R.color.system_notification_accent_color))
+ .setContentTitle(title)
+ .setContentText(text)
+ .setContentIntent(intent)
+ .setStyle(new Notification.BigTextStyle().bigText(text))
+ .setVisibility(Notification.VISIBILITY_PUBLIC)
+ .setLocalOnly(true)
+ .setCategory(Notification.CATEGORY_SYSTEM)
+ .setAutoCancel(true);
SystemUI.overrideNotificationAppName(mContext, builder);
mNotificationManager.notifyAsUser(move.packageName, SystemMessage.NOTE_STORAGE_MOVE,
@@ -562,15 +563,15 @@
private Notification.Builder buildNotificationBuilder(VolumeInfo vol, CharSequence title,
CharSequence text) {
- Notification.Builder builder = new Notification.Builder(mContext)
- .setChannel(NotificationChannels.STORAGE)
- .setSmallIcon(getSmallIcon(vol.getDisk(), vol.getState()))
- .setColor(mContext.getColor(R.color.system_notification_accent_color))
- .setContentTitle(title)
- .setContentText(text)
- .setStyle(new Notification.BigTextStyle().bigText(text))
- .setVisibility(Notification.VISIBILITY_PUBLIC)
- .setLocalOnly(true);
+ Notification.Builder builder =
+ new Notification.Builder(mContext, NotificationChannels.STORAGE)
+ .setSmallIcon(getSmallIcon(vol.getDisk(), vol.getState()))
+ .setColor(mContext.getColor(R.color.system_notification_accent_color))
+ .setContentTitle(title)
+ .setContentText(text)
+ .setStyle(new Notification.BigTextStyle().bigText(text))
+ .setVisibility(Notification.VISIBILITY_PUBLIC)
+ .setLocalOnly(true);
overrideNotificationAppName(mContext, builder);
return builder;
}
diff --git a/packages/SystemUI/src/com/android/systemui/util/NotificationChannels.java b/packages/SystemUI/src/com/android/systemui/util/NotificationChannels.java
index 6bb8aea..15ad0ce 100644
--- a/packages/SystemUI/src/com/android/systemui/util/NotificationChannels.java
+++ b/packages/SystemUI/src/com/android/systemui/util/NotificationChannels.java
@@ -27,8 +27,7 @@
public class NotificationChannels extends SystemUI {
public static String ALERTS = "ALR";
public static String SCREENSHOTS = "SCN";
- public static String SECURITY = "SEC";
- public static String USER = "USR";
+ public static String GENERAL = "GEN";
public static String STORAGE = "DSK";
@VisibleForTesting
@@ -42,14 +41,10 @@
new NotificationChannel(
SCREENSHOTS,
context.getString(R.string.notification_channel_screenshot),
- NotificationManager.IMPORTANCE_DEFAULT),
+ NotificationManager.IMPORTANCE_LOW),
new NotificationChannel(
- SECURITY,
- context.getString(R.string.notification_channel_security),
- NotificationManager.IMPORTANCE_HIGH),
- new NotificationChannel(
- USER,
- context.getString(R.string.notification_channel_user_status),
+ GENERAL,
+ context.getString(R.string.notification_channel_general),
NotificationManager.IMPORTANCE_MIN),
new NotificationChannel(
STORAGE,
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java
index d057d863..b9cb575 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java
@@ -69,6 +69,7 @@
import android.widget.TextView;
import com.android.settingslib.Utils;
+import com.android.systemui.Dependency;
import com.android.systemui.Interpolators;
import com.android.systemui.R;
import com.android.systemui.statusbar.policy.ZenModeController;
@@ -165,7 +166,7 @@
controller.addCallback(mControllerCallbackH, mHandler);
controller.getState();
- TunerService.get(mContext).addTunable(this, SHOW_FULL_ZEN);
+ Dependency.get(TunerService.class).addTunable(this, SHOW_FULL_ZEN);
final Configuration currentConfig = mContext.getResources().getConfiguration();
mDensity = currentConfig.densityDpi;
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogComponent.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogComponent.java
index 78145fe..0a1d34f 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogComponent.java
@@ -72,7 +72,7 @@
mDialog = new VolumeDialog(context, WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY,
mController, mZenModeController, mVolumeDialogCallback);
applyConfiguration();
- TunerService.get(mContext).addTunable(this, VOLUME_DOWN_SILENT, VOLUME_UP_SILENT,
+ Dependency.get(TunerService.class).addTunable(this, VOLUME_DOWN_SILENT, VOLUME_UP_SILENT,
VOLUME_SILENT_DO_NOT_DISTURB);
}
diff --git a/packages/SystemUI/tests/Android.mk b/packages/SystemUI/tests/Android.mk
index c627e22..cefade0 100644
--- a/packages/SystemUI/tests/Android.mk
+++ b/packages/SystemUI/tests/Android.mk
@@ -43,6 +43,7 @@
android-support-v17-leanback
LOCAL_STATIC_JAVA_LIBRARIES := \
+ metrics-helper-lib \
android-support-test \
mockito-updated-target-minus-junit4 \
SystemUI-proto \
diff --git a/packages/SystemUI/tests/AndroidManifest.xml b/packages/SystemUI/tests/AndroidManifest.xml
index 408e8f3..6d62435 100644
--- a/packages/SystemUI/tests/AndroidManifest.xml
+++ b/packages/SystemUI/tests/AndroidManifest.xml
@@ -17,6 +17,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.systemui.tests">
+ <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.ACCESS_VOICE_INTERACTION_SERVICE" />
<uses-permission android:name="android.permission.INJECT_EVENTS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
diff --git a/packages/SystemUI/tests/res/layout/custom_view_dark.xml b/packages/SystemUI/tests/res/layout/custom_view_dark.xml
new file mode 100644
index 0000000..9e460a5
--- /dev/null
+++ b/packages/SystemUI/tests/res/layout/custom_view_dark.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="#ff000000"
+ />
diff --git a/packages/SystemUI/tests/src/com/android/systemui/FragmentTestCase.java b/packages/SystemUI/tests/src/com/android/systemui/FragmentTestCase.java
index 447edac..f8f67bb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/FragmentTestCase.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/FragmentTestCase.java
@@ -19,13 +19,17 @@
import android.app.FragmentController;
import android.app.FragmentHostCallback;
import android.app.FragmentManagerNonConfig;
+import android.graphics.PixelFormat;
import android.os.Handler;
-import android.os.HandlerThread;
+import android.os.Looper;
import android.os.Parcelable;
import android.view.LayoutInflater;
import android.view.View;
+import android.view.WindowManager;
+import android.view.WindowManager.LayoutParams;
import android.widget.FrameLayout;
+import com.android.systemui.utils.ViewUtils;
import com.android.systemui.utils.leaks.LeakCheckedTest;
import org.junit.After;
@@ -45,7 +49,6 @@
private static final int VIEW_ID = 42;
private final Class<? extends Fragment> mCls;
- private HandlerThread mHandlerThread;
private Handler mHandler;
private FrameLayout mView;
protected FragmentController mFragments;
@@ -59,9 +62,7 @@
public void setupFragment() throws IllegalAccessException, InstantiationException {
mView = new FrameLayout(mContext);
mView.setId(VIEW_ID);
- mHandlerThread = new HandlerThread("FragmentTestThread");
- mHandlerThread.start();
- mHandler = new Handler(mHandlerThread.getLooper());
+ mHandler = new Handler(Looper.getMainLooper());
mFragment = mCls.newInstance();
postAndWait(() -> {
mFragments = FragmentController.createController(new HostCallbacks());
@@ -78,7 +79,6 @@
// Set mFragments to null to let it know not to destroy.
postAndWait(() -> mFragments.dispatchDestroy());
}
- mHandlerThread.quit();
}
@Test
@@ -100,6 +100,26 @@
}
@Test
+ public void testAttachDetach() {
+ WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
+ LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT,
+ LayoutParams.TYPE_SYSTEM_ALERT,
+ 0, PixelFormat.TRANSLUCENT);
+ postAndWait(() -> mFragments.dispatchResume());
+ attachFragmentToWindow();
+ detachFragmentToWindow();
+ postAndWait(() -> mFragments.dispatchPause());
+ }
+
+ protected void attachFragmentToWindow() {
+ ViewUtils.attachView(mView);
+ }
+
+ protected void detachFragmentToWindow() {
+ ViewUtils.detachView(mView);
+ }
+
+ @Test
public void testRecreate() {
postAndWait(() -> mFragments.dispatchResume());
postAndWait(() -> {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java b/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java
index f258e5d..81a50d9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java
@@ -65,7 +65,7 @@
waitForIdleSync(mHandler);
}
- protected void waitForIdleSync(Handler h) {
+ public static void waitForIdleSync(Handler h) {
validateThread(h.getLooper());
Idler idler = new Idler(null);
h.getLooper().getQueue().addIdleHandler(idler);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
index 5345031..f22c1af 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
@@ -15,11 +15,6 @@
package com.android.systemui.qs;
import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import android.os.Handler;
-import android.os.Looper;
-import android.support.test.runner.AndroidJUnit4;
import com.android.systemui.Dependency;
import com.android.systemui.FragmentTestCase;
@@ -27,27 +22,16 @@
import com.android.systemui.statusbar.phone.QSTileHost;
import com.android.systemui.statusbar.phone.QuickStatusBarHeader;
import com.android.systemui.statusbar.phone.StatusBarIconController;
-import com.android.systemui.statusbar.policy.BatteryController;
-import com.android.systemui.statusbar.policy.BluetoothController;
-import com.android.systemui.statusbar.policy.CastController;
-import com.android.systemui.statusbar.policy.FlashlightController;
-import com.android.systemui.statusbar.policy.HotspotController;
-import com.android.systemui.statusbar.policy.KeyguardMonitor;
-import com.android.systemui.statusbar.policy.LocationController;
-import com.android.systemui.statusbar.policy.NetworkController;
-import com.android.systemui.statusbar.policy.NextAlarmController;
-import com.android.systemui.statusbar.policy.RotationLockController;
-import com.android.systemui.statusbar.policy.SecurityController;
-import com.android.systemui.statusbar.policy.UserInfoController;
import com.android.systemui.statusbar.policy.UserSwitcherController;
-import com.android.systemui.statusbar.policy.ZenModeController;
import com.android.systemui.tuner.TunerService;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import java.util.ArrayList;
+import android.os.Handler;
+import android.os.Looper;
+import android.support.test.runner.AndroidJUnit4;
@RunWith(AndroidJUnit4.class)
public class QSFragmentTest extends FragmentTestCase {
@@ -60,11 +44,7 @@
public void addLeakCheckDependencies() {
injectTestDependency(Dependency.BG_LOOPER, Looper.getMainLooper());
injectMockDependency(UserSwitcherController.class);
- injectLeakCheckedDependencies(BluetoothController.class, LocationController.class,
- RotationLockController.class, NetworkController.class, ZenModeController.class,
- HotspotController.class, CastController.class, FlashlightController.class,
- UserInfoController.class, KeyguardMonitor.class, SecurityController.class,
- BatteryController.class, NextAlarmController.class);
+ injectLeakCheckedDependencies(ALL_SUPPORTED_CLASSES);
}
@Test
@@ -88,6 +68,6 @@
host.destroy();
// Ensure the tuner cleans up its persistent listeners.
- TunerService.get(mContext).destroy();
+ Dependency.get(TunerService.class).destroy();
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/TileLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/TileLayoutTest.java
index 5401c30..95190e3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/TileLayoutTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/TileLayoutTest.java
@@ -161,4 +161,10 @@
assertEquals(top1.getValue().intValue(), top2.getValue().intValue());
assertEquals(bottom1.getValue().intValue(), bottom2.getValue().intValue());
}
+
+ @Test
+ public void testEmptyHeight() {
+ mTileLayout.measure(mLayoutSizeForOneTile, mLayoutSizeForOneTile);
+ assertEquals(0, mTileLayout.getMeasuredHeight());
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java
index 43f8629..5b22986 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java
@@ -171,27 +171,6 @@
}
@Test
- public void testBuzzBeepBlink() {
- mCommandQueue.buzzBeepBlinked();
- waitForIdleSync();
- verify(mCallbacks).buzzBeepBlinked();
- }
-
- @Test
- public void testNotificationLightOff() {
- mCommandQueue.notificationLightOff();
- waitForIdleSync();
- verify(mCallbacks).notificationLightOff();
- }
-
- @Test
- public void testNotificationLightPulse() {
- mCommandQueue.notificationLightPulse(1, 2, 3);
- waitForIdleSync();
- verify(mCallbacks).notificationLightPulse(eq(1), eq(2), eq(3));
- }
-
- @Test
public void testScreenPinRequest() {
mCommandQueue.showScreenPinningRequest(1);
waitForIdleSync();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationContentViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationContentViewTest.java
index 3bb9f5f..77f96b8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationContentViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationContentViewTest.java
@@ -16,9 +16,6 @@
package com.android.systemui.statusbar;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
import android.content.Context;
import android.support.test.InstrumentationRegistry;
import android.support.test.annotation.UiThreadTest;
@@ -31,6 +28,11 @@
import org.junit.Test;
import org.junit.runner.RunWith;
+import static org.mockito.ArgumentMatchers.anyFloat;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+
@SmallTest
@RunWith(AndroidJUnit4.class)
public class NotificationContentViewTest {
@@ -39,13 +41,16 @@
Context mContext;
@Before
+ @UiThreadTest
public void setup() {
- ExpandableNotificationRow rowMock = mock(ExpandableNotificationRow.class);
- when(rowMock.getIntrinsicHeight()).thenReturn(10);
-
mContext = InstrumentationRegistry.getTargetContext();
mView = new NotificationContentView(mContext, null);
- mView.setContainingNotification(rowMock);
+ ExpandableNotificationRow row = new ExpandableNotificationRow(mContext, null);
+ ExpandableNotificationRow mockRow = spy(row);
+ doNothing().when(mockRow).updateBackgroundAlpha(anyFloat());
+ doReturn(10).when(mockRow).getIntrinsicHeight();
+
+ mView.setContainingNotification(mockRow);
mView.setHeights(10, 20, 30, 40);
mView.setContractedChild(createViewWithHeight(10));
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationCustomViewWrapperTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationCustomViewWrapperTest.java
new file mode 100644
index 0000000..d07cea1d
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationCustomViewWrapperTest.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.statusbar;
+
+import android.content.Context;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.annotation.UiThreadTest;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.view.View;
+import android.widget.RemoteViews;
+
+import com.android.systemui.R;
+import com.android.systemui.statusbar.notification.NotificationCustomViewWrapper;
+import com.android.systemui.statusbar.notification.NotificationViewWrapper;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class NotificationCustomViewWrapperTest {
+
+ private Context mContext;
+ private ExpandableNotificationRow mRow;
+
+ @Before
+ @UiThreadTest
+ public void setUp() {
+ mContext = InstrumentationRegistry.getTargetContext();
+ mRow = new ExpandableNotificationRow(mContext, null);
+ }
+
+ @Test
+ public void testBackgroundPersists() {
+ RemoteViews views = new RemoteViews(mContext.getPackageName(), R.layout.custom_view_dark);
+ View v = views.apply(mContext, null);
+ NotificationViewWrapper wrap = NotificationCustomViewWrapper.wrap(mContext, v, mRow);
+ wrap.notifyContentUpdated(null, false /* isLowPriority */);
+ Assert.assertTrue(wrap.getCustomBackgroundColor() != 0);
+ views.reapply(mContext, v);
+ wrap.notifyContentUpdated(null, false /* isLowPriority */);
+ Assert.assertTrue(wrap.getCustomBackgroundColor() != 0);
+ }
+
+}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationMenuRowTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationMenuRowTest.java
new file mode 100644
index 0000000..7141170
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationMenuRowTest.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.systemui.statusbar;
+
+import com.android.systemui.utils.ViewUtils;
+import com.android.systemui.utils.leaks.LeakCheckedTest;
+
+import org.junit.Before;
+import org.junit.Test;
+
+public class NotificationMenuRowTest extends LeakCheckedTest {
+
+ @Before
+ public void setup() {
+ injectLeakCheckedDependencies(ALL_SUPPORTED_CLASSES);
+ }
+
+ @Test
+ public void testAttachDetach() {
+ NotificationMenuRow row = new NotificationMenuRow(mContext);
+ ViewUtils.attachView(row);
+ ViewUtils.detachView(row);
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarIconViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarIconViewTest.java
index 7d9e073..68f9cb05 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarIconViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarIconViewTest.java
@@ -16,36 +16,74 @@
package com.android.systemui.statusbar;
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertNull;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.argThat;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.content.ContextWrapper;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
import android.graphics.drawable.Icon;
-import android.os.Debug;
import android.os.UserHandle;
+import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
-import android.test.suitebuilder.annotation.SmallTest;
import com.android.internal.statusbar.StatusBarIcon;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
+import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
-
-import static junit.framework.Assert.assertNull;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
+import org.mockito.ArgumentMatcher;
@SmallTest
@RunWith(AndroidJUnit4.class)
public class StatusBarIconViewTest extends SysuiTestCase {
+ @Rule
+ public ExpectedException mThrown = ExpectedException.none();
+
private StatusBarIconView mIconView;
private StatusBarIcon mStatusBarIcon = mock(StatusBarIcon.class);
+ private PackageManager mPackageManagerSpy;
+ private Context mContext;
+ private Resources mMockResources;
+
@Before
- public void setUp() {
- mIconView = new StatusBarIconView(getContext(), "slot", null);
- mStatusBarIcon = new StatusBarIcon(UserHandle.ALL, getContext().getPackageName(),
- Icon.createWithResource(getContext(), R.drawable.ic_android), 0, 0, "");
+ public void setUp() throws Exception {
+ // Set up context such that asking for "mockPackage" resources returns mMockResources.
+ mMockResources = mock(Resources.class);
+ mPackageManagerSpy = spy(getContext().getPackageManager());
+ doReturn(mMockResources).when(mPackageManagerSpy)
+ .getResourcesForApplicationAsUser(eq("mockPackage"), anyInt());
+ doReturn(mMockResources).when(mPackageManagerSpy)
+ .getResourcesForApplication(eq("mockPackage"));
+ doReturn(mMockResources).when(mPackageManagerSpy).getResourcesForApplication(argThat(
+ (ArgumentMatcher<ApplicationInfo>) o -> "mockPackage".equals(o.packageName)));
+ mContext = new ContextWrapper(getContext()) {
+ @Override
+ public PackageManager getPackageManager() {
+ return mPackageManagerSpy;
+ }
+ };
+
+ mIconView = new StatusBarIconView(mContext, "test_slot", null);
+ mStatusBarIcon = new StatusBarIcon(UserHandle.ALL, "mockPackage",
+ Icon.createWithResource(mContext, R.drawable.ic_android), 0, 0, "");
}
@Test
@@ -55,4 +93,11 @@
assertNull(mIconView.getTag(R.id.icon_is_grayscale));
}
+ @Test
+ public void testSettingOomingIconDoesNotThrowOom() {
+ when(mMockResources.getDrawable(anyInt(), any())).thenThrow(new OutOfMemoryError("mocked"));
+ mStatusBarIcon.icon = Icon.createWithResource("mockPackage", R.drawable.ic_android);
+
+ assertFalse(mIconView.set(mStatusBarIcon));
+ }
}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarFragmentTest.java
index e28d077..a9d6df7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarFragmentTest.java
@@ -40,6 +40,7 @@
mContext.putComponent(Recents.class, mock(Recents.class));
mContext.putComponent(Divider.class, mock(Divider.class));
mContext.addMockSystemService(Context.WINDOW_SERVICE, mock(WindowManager.class));
+ injectLeakCheckedDependencies(ALL_SUPPORTED_CLASSES);
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
index 309559b..21c7fce 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
@@ -22,11 +22,20 @@
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
+import android.metrics.LogMaker;
+import android.metrics.MetricsReader;
import android.support.test.filters.SmallTest;
+import android.support.test.metricshelper.MetricsAsserts;
import android.support.test.runner.AndroidJUnit4;
+import android.util.DisplayMetrics;
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.keyguard.KeyguardHostView.OnDismissAction;
import com.android.systemui.SysuiTestCase;
+import com.android.systemui.statusbar.ActivatableNotificationView;
+import com.android.systemui.statusbar.KeyguardIndicationController;
+import com.android.systemui.statusbar.NotificationData;
+import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
import org.junit.Before;
import org.junit.Test;
@@ -37,12 +46,22 @@
public class StatusBarTest extends SysuiTestCase {
StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
+ UnlockMethodCache mUnlockMethodCache;
+ KeyguardIndicationController mKeyguardIndicationController;
+ NotificationStackScrollLayout mStackScroller;
StatusBar mStatusBar;
+ private MetricsReader mMetricsReader;
+ private DisplayMetrics mDisplayMetrics = new DisplayMetrics();
+
@Before
public void setup() {
mStatusBarKeyguardViewManager = mock(StatusBarKeyguardViewManager.class);
- mStatusBar = new TestableStatusBar(mStatusBarKeyguardViewManager);
+ mUnlockMethodCache = mock(UnlockMethodCache.class);
+ mKeyguardIndicationController = mock(KeyguardIndicationController.class);
+ mStackScroller = mock(NotificationStackScrollLayout.class);
+ mStatusBar = new TestableStatusBar(mStatusBarKeyguardViewManager, mUnlockMethodCache,
+ mKeyguardIndicationController, mStackScroller);
doAnswer(invocation -> {
OnDismissAction onDismissAction = (OnDismissAction) invocation.getArguments()[0];
@@ -55,6 +74,11 @@
runnable.run();
return null;
}).when(mStatusBarKeyguardViewManager).addAfterKeyguardGoneRunnable(any());
+
+ when(mStackScroller.getActivatedChild()).thenReturn(null);
+
+ mMetricsReader = new MetricsReader();
+ mMetricsReader.checkpoint(); // clear out old logs
}
@Test
@@ -81,9 +105,114 @@
mStatusBar.executeRunnableDismissingKeyguard(null, null, false, false, false);
}
+ @Test
+ public void lockscreenStateMetrics_notShowing() {
+ // uninteresting state, except that fingerprint must be non-zero
+ when(mStatusBarKeyguardViewManager.isOccluded()).thenReturn(false);
+ when(mUnlockMethodCache.canSkipBouncer()).thenReturn(true);
+ // interesting state
+ when(mStatusBarKeyguardViewManager.isShowing()).thenReturn(false);
+ when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false);
+ when(mUnlockMethodCache.isMethodSecure()).thenReturn(false);
+
+ mStatusBar.onKeyguardViewManagerStatesUpdated();
+
+ MetricsAsserts.assertHasLog("missing hidden insecure lockscreen log", mMetricsReader,
+ new LogMaker(MetricsEvent.LOCKSCREEN)
+ .setType(MetricsEvent.TYPE_CLOSE)
+ .setSubtype(0));
+ }
+
+ @Test
+ public void lockscreenStateMetrics_notShowing_secure() {
+ // uninteresting state, except that fingerprint must be non-zero
+ when(mStatusBarKeyguardViewManager.isOccluded()).thenReturn(false);
+ when(mUnlockMethodCache.canSkipBouncer()).thenReturn(true);
+ // interesting state
+ when(mStatusBarKeyguardViewManager.isShowing()).thenReturn(false);
+ when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false);
+ when(mUnlockMethodCache.isMethodSecure()).thenReturn(true);
+
+ mStatusBar.onKeyguardViewManagerStatesUpdated();
+
+ MetricsAsserts.assertHasLog("missing hidden secure lockscreen log", mMetricsReader,
+ new LogMaker(MetricsEvent.LOCKSCREEN)
+ .setType(MetricsEvent.TYPE_CLOSE)
+ .setSubtype(1));
+ }
+
+ @Test
+ public void lockscreenStateMetrics_isShowing() {
+ // uninteresting state, except that fingerprint must be non-zero
+ when(mStatusBarKeyguardViewManager.isOccluded()).thenReturn(false);
+ when(mUnlockMethodCache.canSkipBouncer()).thenReturn(true);
+ // interesting state
+ when(mStatusBarKeyguardViewManager.isShowing()).thenReturn(true);
+ when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false);
+ when(mUnlockMethodCache.isMethodSecure()).thenReturn(false);
+
+ mStatusBar.onKeyguardViewManagerStatesUpdated();
+
+ MetricsAsserts.assertHasLog("missing insecure lockscreen showing", mMetricsReader,
+ new LogMaker(MetricsEvent.LOCKSCREEN)
+ .setType(MetricsEvent.TYPE_OPEN)
+ .setSubtype(0));
+ }
+
+ @Test
+ public void lockscreenStateMetrics_isShowing_secure() {
+ // uninteresting state, except that fingerprint must be non-zero
+ when(mStatusBarKeyguardViewManager.isOccluded()).thenReturn(false);
+ when(mUnlockMethodCache.canSkipBouncer()).thenReturn(true);
+ // interesting state
+ when(mStatusBarKeyguardViewManager.isShowing()).thenReturn(true);
+ when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false);
+ when(mUnlockMethodCache.isMethodSecure()).thenReturn(true);
+
+ mStatusBar.onKeyguardViewManagerStatesUpdated();
+
+ MetricsAsserts.assertHasLog("missing secure lockscreen showing log", mMetricsReader,
+ new LogMaker(MetricsEvent.LOCKSCREEN)
+ .setType(MetricsEvent.TYPE_OPEN)
+ .setSubtype(1));
+ }
+
+ @Test
+ public void lockscreenStateMetrics_isShowingBouncer() {
+ // uninteresting state, except that fingerprint must be non-zero
+ when(mStatusBarKeyguardViewManager.isOccluded()).thenReturn(false);
+ when(mUnlockMethodCache.canSkipBouncer()).thenReturn(true);
+ // interesting state
+ when(mStatusBarKeyguardViewManager.isShowing()).thenReturn(true);
+ when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(true);
+ when(mUnlockMethodCache.isMethodSecure()).thenReturn(true);
+
+ mStatusBar.onKeyguardViewManagerStatesUpdated();
+
+ MetricsAsserts.assertHasLog("missing bouncer log", mMetricsReader,
+ new LogMaker(MetricsEvent.BOUNCER)
+ .setType(MetricsEvent.TYPE_OPEN)
+ .setSubtype(1));
+ }
+
+ @Test
+ public void onActivatedMetrics() {
+ ActivatableNotificationView view = mock(ActivatableNotificationView.class);
+ mStatusBar.onActivated(view);
+
+ MetricsAsserts.assertHasLog("missing lockscreen note tap log", mMetricsReader,
+ new LogMaker(MetricsEvent.ACTION_LS_NOTE)
+ .setType(MetricsEvent.TYPE_ACTION));
+ }
+
static class TestableStatusBar extends StatusBar {
- public TestableStatusBar(StatusBarKeyguardViewManager man) {
+ public TestableStatusBar(StatusBarKeyguardViewManager man,
+ UnlockMethodCache unlock, KeyguardIndicationController key,
+ NotificationStackScrollLayout stack) {
mStatusBarKeyguardViewManager = man;
+ mUnlockMethodCache = unlock;
+ mKeyguardIndicationController = key;
+ mStackScroller = stack;
}
@Override
diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/ChannelsTest.java b/packages/SystemUI/tests/src/com/android/systemui/util/ChannelsTest.java
index 8949598..f67296d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/util/ChannelsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/util/ChannelsTest.java
@@ -55,9 +55,8 @@
Set<String> ALL_CHANNELS = new ArraySet<>(Arrays.asList(
NotificationChannels.ALERTS,
NotificationChannels.SCREENSHOTS,
- NotificationChannels.SECURITY,
- NotificationChannels.USER,
- NotificationChannels.STORAGE
+ NotificationChannels.STORAGE,
+ NotificationChannels.GENERAL
));
NotificationChannels.createAll(mContext);
ArgumentCaptor<List> captor = ArgumentCaptor.forClass(List.class);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/utils/ViewUtils.java b/packages/SystemUI/tests/src/com/android/systemui/utils/ViewUtils.java
new file mode 100644
index 0000000..202c4cf
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/utils/ViewUtils.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.systemui.utils;
+
+import android.graphics.PixelFormat;
+import android.os.Handler;
+import android.os.Looper;
+import android.view.View;
+import android.view.WindowManager;
+import android.view.WindowManager.LayoutParams;
+import android.support.test.InstrumentationRegistry;
+
+import com.android.systemui.SysuiTestCase;
+
+public class ViewUtils {
+
+ public static void attachView(View view) {
+ WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
+ LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT,
+ LayoutParams.TYPE_APPLICATION_OVERLAY,
+ 0, PixelFormat.TRANSLUCENT);
+ Handler handler = new Handler(Looper.getMainLooper());
+ handler.post(() -> InstrumentationRegistry.getContext()
+ .getSystemService(WindowManager.class).addView(view, lp));
+ SysuiTestCase.waitForIdleSync(handler);
+ }
+
+ public static void detachView(View view) {
+ Handler handler = new Handler(Looper.getMainLooper());
+ handler.post(() -> InstrumentationRegistry.getContext()
+ .getSystemService(WindowManager.class).removeView(view));
+ SysuiTestCase.waitForIdleSync(handler);
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakePluginManager.java b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakePluginManager.java
new file mode 100644
index 0000000..d1abcca
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakePluginManager.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.systemui.utils.leaks;
+
+import android.content.Context;
+
+import com.android.systemui.plugins.Plugin;
+import com.android.systemui.plugins.PluginListener;
+import com.android.systemui.plugins.PluginManager;
+
+public class FakePluginManager extends PluginManager {
+
+ private final BaseLeakChecker<PluginListener> mLeakChecker;
+
+ public FakePluginManager(Context context, LeakCheckedTest test) {
+ super(context);
+ mLeakChecker = new BaseLeakChecker<>(test, "Plugin");
+ }
+
+ @Override
+ public <T extends Plugin> void addPluginListener(String action, PluginListener<T> listener,
+ int version) {
+ mLeakChecker.addCallback(listener);
+ }
+
+ @Override
+ public <T extends Plugin> void addPluginListener(String action, PluginListener<T> listener,
+ int version, boolean allowMultiple) {
+ mLeakChecker.addCallback(listener);
+ }
+
+ @Override
+ public void removePluginListener(PluginListener<?> listener) {
+ mLeakChecker.removeCallback(listener);
+ }
+
+ @Override
+ public <T extends Plugin> T getOneShotPlugin(String action, int version) {
+ return null;
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeTunerService.java b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeTunerService.java
new file mode 100644
index 0000000..b841ce9
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeTunerService.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.systemui.utils.leaks;
+
+import android.content.Context;
+
+import com.android.systemui.tuner.TunerService;
+
+public class FakeTunerService extends TunerService {
+
+ private final BaseLeakChecker<Tunable> mBaseLeakChecker;
+
+ public FakeTunerService(Context context, LeakCheckedTest test) {
+ super(context);
+ mBaseLeakChecker = new BaseLeakChecker<>(test, "tunable");
+ destroy();
+ }
+
+ @Override
+ public void addTunable(Tunable tunable, String... keys) {
+ for (String key : keys) {
+ tunable.onTuningChanged(key, null);
+ }
+ mBaseLeakChecker.addCallback(tunable);
+ }
+
+ @Override
+ public void removeTunable(Tunable tunable) {
+ mBaseLeakChecker.removeCallback(tunable);
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/LeakCheckedTest.java b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/LeakCheckedTest.java
index c182493..c2048c7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/LeakCheckedTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/LeakCheckedTest.java
@@ -20,6 +20,7 @@
import android.util.ArrayMap;
import com.android.systemui.SysuiTestCase;
+import com.android.systemui.plugins.PluginManager;
import com.android.systemui.statusbar.phone.ManagedProfileController;
import com.android.systemui.statusbar.policy.BatteryController;
import com.android.systemui.statusbar.policy.BluetoothController;
@@ -35,6 +36,7 @@
import com.android.systemui.statusbar.policy.SecurityController;
import com.android.systemui.statusbar.policy.UserInfoController;
import com.android.systemui.statusbar.policy.ZenModeController;
+import com.android.systemui.tuner.TunerService;
import org.junit.Assert;
import org.junit.Rule;
@@ -56,6 +58,25 @@
private final Map<String, Tracker> mTrackers = new HashMap<>();
private final Map<Class, Object> mLeakCheckers = new ArrayMap<>();
+ public static final Class<?>[] ALL_SUPPORTED_CLASSES = new Class[] {
+ BluetoothController.class,
+ LocationController.class,
+ RotationLockController.class,
+ ZenModeController.class,
+ CastController.class,
+ HotspotController.class,
+ FlashlightController.class,
+ UserInfoController.class,
+ KeyguardMonitor.class,
+ BatteryController.class,
+ SecurityController.class,
+ ManagedProfileController.class,
+ NextAlarmController.class,
+ NetworkController.class,
+ PluginManager.class,
+ TunerService.class,
+ };
+
@Rule
public TestWatcher successWatcher = new TestWatcher() {
@Override
@@ -96,6 +117,10 @@
obj = new FakeNextAlarmController(this);
} else if (cls == NetworkController.class) {
obj = new FakeNetworkController(this);
+ } else if (cls == PluginManager.class) {
+ obj = new FakePluginManager(mContext, this);
+ } else if (cls == TunerService.class) {
+ obj = new FakeTunerService(mContext, this);
} else {
Assert.fail(cls.getName() + " is not supported by LeakCheckedTest yet");
}
diff --git a/preloaded-classes b/preloaded-classes
index 2fad5dd..7dc5a25 100644
--- a/preloaded-classes
+++ b/preloaded-classes
@@ -1,3 +1,28 @@
+#
+# Copyright (C) 2017 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+#
+#
+# Preloaded-classes filter file for phones.
+#
+# Classes in this file will be allocated into the boot image, and forcibly initialized in
+# the zygote during initialization. This is a trade-off, using virtual address space to share
+# common heap between apps.
+#
+# This file has been derived for mainline phone (and tablet) usage.
+#
[B
[C
[D
@@ -9,7 +34,6 @@
[Landroid.animation.Keyframe$FloatKeyframe;
[Landroid.animation.Keyframe$IntKeyframe;
[Landroid.animation.Keyframe$ObjectKeyframe;
-[Landroid.animation.Keyframe;
[Landroid.animation.PropertyValuesHolder;
[Landroid.app.LoaderManagerImpl;
[Landroid.content.ContentProviderResult;
@@ -57,45 +81,45 @@
[Landroid.hardware.soundtrigger.SoundTrigger$Keyphrase;
[Landroid.hardware.soundtrigger.SoundTrigger$KeyphraseRecognitionExtra;
[Landroid.icu.impl.CacheValue$Strength;
+[Landroid.icu.impl.CacheValue;
+[Landroid.icu.impl.CurrencyData$CurrencySpacingInfo$SpacingPattern;
+[Landroid.icu.impl.CurrencyData$CurrencySpacingInfo$SpacingType;
[Landroid.icu.impl.ICUResourceBundle$OpenType;
[Landroid.icu.impl.StandardPlural;
[Landroid.icu.impl.Trie2$ValueWidth;
[Landroid.icu.impl.UCharacterProperty$BinaryProperty;
[Landroid.icu.impl.UCharacterProperty$IntProperty;
-[Landroid.icu.lang.UScript$ScriptUsage;
-[Landroid.icu.text.DateFormat$BooleanAttribute;
-[Landroid.icu.text.DateFormat$Field;
+[Landroid.icu.text.DateFormatSymbols$CalendarDataSink$AliasType;
[Landroid.icu.text.DateFormatSymbols$CapitalizationContextUsage;
-[Landroid.icu.text.DateTimePatternGenerator$DTPGflags;
[Landroid.icu.text.DisplayContext$Type;
[Landroid.icu.text.DisplayContext;
-[Landroid.icu.text.MessagePattern$ApostropheMode;
-[Landroid.icu.text.MessagePattern$ArgType;
-[Landroid.icu.text.MessagePattern$Part$Type;
[Landroid.icu.text.PluralRules$Operand;
[Landroid.icu.text.PluralRules$PluralType;
[Landroid.icu.text.PluralRules$SampleType;
+[Landroid.icu.text.TimeZoneNames$NameType;
[Landroid.icu.text.UnicodeSet;
[Landroid.icu.util.BytesTrie$Result;
-[Landroid.icu.util.Calendar$CalType;
[Landroid.icu.util.Currency$CurrencyUsage;
[Landroid.icu.util.ULocale$Category;
[Landroid.icu.util.ULocale;
+[Landroid.icu.util.UResourceBundle$RootType;
[Landroid.media.AudioGain;
+[Landroid.media.MediaCodecInfo$CodecProfileLevel;
[Landroid.net.Network;
[Landroid.net.NetworkInfo$DetailedState;
[Landroid.net.NetworkInfo$State;
+[Landroid.net.NetworkRequest$Type;
[Landroid.net.Uri;
[Landroid.net.wifi.SupplicantState;
[Landroid.os.AsyncTask$Status;
-[Landroid.os.Bundle;
+[Landroid.os.IBinder;
[Landroid.os.MessageQueue$IdleHandler;
[Landroid.os.Parcel;
-[Landroid.os.ParcelFileDescriptor;
[Landroid.os.Parcelable;
[Landroid.os.PatternMatcher;
[Landroid.os.storage.StorageVolume;
[Landroid.system.StructPollfd;
+[Landroid.telephony.TelephonyManager$MultiSimVariants;
[Landroid.text.DynamicLayout$ChangeWatcher;
[Landroid.text.InputFilter;
[Landroid.text.Layout$Alignment;
@@ -124,9 +148,7 @@
[Landroid.util.Range;
[Landroid.util.Rational;
[Landroid.view.Choreographer$CallbackQueue;
-[Landroid.view.Display$ColorTransform;
[Landroid.view.Display$Mode;
-[Landroid.view.Display;
[Landroid.view.HandlerActionQueue$HandlerAction;
[Landroid.view.MenuItem;
[Landroid.view.View;
@@ -146,18 +168,22 @@
[Lcom.android.org.bouncycastle.asn1.ASN1ObjectIdentifier;
[Lcom.android.org.conscrypt.OpenSSLX509CertPath$Encoding;
[Lcom.android.org.conscrypt.OpenSSLX509Certificate;
+[Lcom.android.org.conscrypt.ct.CTLogInfo;
[Ldalvik.system.DexPathList$Element;
-[Ljava.beans.PropertyChangeListener;
+[Ldalvik.system.DexPathList$NativeLibraryElement;
[Ljava.io.File$PathStatus;
[Ljava.io.File;
[Ljava.io.FileDescriptor;
[Ljava.io.IOException;
+[Ljava.io.ObjectInputStream$HandleTable$HandleList;
[Ljava.io.ObjectStreamField;
+[Ljava.lang.Boolean;
[Ljava.lang.Byte;
[Ljava.lang.CharSequence;
[Ljava.lang.Character$UnicodeBlock;
[Ljava.lang.Character;
[Ljava.lang.Class;
+[Ljava.lang.Comparable;
[Ljava.lang.Enum;
[Ljava.lang.Integer;
[Ljava.lang.Long;
@@ -174,21 +200,20 @@
[Ljava.lang.Throwable;
[Ljava.lang.Void;
[Ljava.lang.annotation.Annotation;
-[Ljava.lang.ref.SoftReference;
+[Ljava.lang.invoke.MethodType;
[Ljava.lang.ref.WeakReference;
[Ljava.lang.reflect.AccessibleObject;
[Ljava.lang.reflect.Constructor;
[Ljava.lang.reflect.Field;
[Ljava.lang.reflect.Method;
+[Ljava.lang.reflect.Parameter;
[Ljava.lang.reflect.Type;
[Ljava.lang.reflect.TypeVariable;
-[Ljava.math.BigDecimal;
[Ljava.math.BigInteger;
[Ljava.math.RoundingMode;
[Ljava.net.InetAddress;
-[Ljava.net.InterfaceAddress;
-[Ljava.net.NetworkInterface;
[Ljava.net.Proxy$Type;
+[Ljava.nio.file.attribute.FileAttribute;
[Ljava.security.CryptoPrimitive;
[Ljava.security.Provider;
[Ljava.security.cert.Certificate;
@@ -200,30 +225,31 @@
[Ljava.util.Enumeration;
[Ljava.util.Formatter$Flags;
[Ljava.util.Formatter$FormatString;
-[Ljava.util.HashMap$HashMapEntry;
+[Ljava.util.HashMap$Node;
[Ljava.util.Hashtable$HashtableEntry;
-[Ljava.util.List;
[Ljava.util.Locale$Category;
[Ljava.util.Locale;
[Ljava.util.Map$Entry;
[Ljava.util.WeakHashMap$Entry;
+[Ljava.util.concurrent.ConcurrentHashMap$CounterCell;
[Ljava.util.concurrent.ConcurrentHashMap$Node;
[Ljava.util.concurrent.ConcurrentHashMap$Segment;
+[Ljava.util.concurrent.ForkJoinTask$ExceptionNode;
[Ljava.util.concurrent.RunnableScheduledFuture;
[Ljava.util.concurrent.TimeUnit;
[Ljava.util.logging.Handler;
[Ljava.util.regex.Pattern;
-[Ljavax.crypto.Cipher$InitType;
-[Ljavax.crypto.Cipher$NeedToSet;
[Ljavax.net.ssl.KeyManager;
[Ljavax.net.ssl.TrustManager;
[Ljavax.security.cert.X509Certificate;
[Llibcore.io.ClassPathURLStreamHandler;
+[Llibcore.io.IoTracker$Mode;
[Llibcore.reflect.AnnotationMember$DefaultValues;
[Llibcore.reflect.AnnotationMember;
[Lorg.apache.http.Header;
[Lorg.json.JSONStringer$Scope;
[Lorg.kxml2.io.KXmlParser$ValueContext;
+[Lsun.misc.FDBigInteger;
[Lsun.misc.FormattedFloatingDecimal$Form;
[Lsun.security.jca.ProviderConfig;
[Lsun.security.jca.ServiceId;
@@ -244,31 +270,22 @@
[[Ljava.lang.Object;
[[Ljava.lang.String;
[[Ljava.lang.annotation.Annotation;
-[[S
[[[I
android.R$styleable
android.accounts.Account
android.accounts.Account$1
android.accounts.AccountManager
android.accounts.AccountManager$1
-android.accounts.AccountManager$11
-android.accounts.AccountManager$AmsTask
-android.accounts.AccountManager$AmsTask$1
-android.accounts.AccountManager$AmsTask$Response
-android.accounts.AccountManagerCallback
android.accounts.AccountManagerFuture
android.accounts.AccountsException
android.accounts.AuthenticatorException
android.accounts.IAccountManager
android.accounts.IAccountManager$Stub
android.accounts.IAccountManager$Stub$Proxy
-android.accounts.IAccountManagerResponse
-android.accounts.IAccountManagerResponse$Stub
android.accounts.OnAccountsUpdateListener
android.accounts.OperationCanceledException
android.animation.AnimationHandler
android.animation.AnimationHandler$1
-android.animation.AnimationHandler$2
android.animation.AnimationHandler$AnimationFrameCallback
android.animation.AnimationHandler$AnimationFrameCallbackProvider
android.animation.AnimationHandler$MyFrameCallbackProvider
@@ -277,12 +294,15 @@
android.animation.Animator$AnimatorListener
android.animation.Animator$AnimatorPauseListener
android.animation.AnimatorInflater
-android.animation.AnimatorInflater$PathDataEvaluator
android.animation.AnimatorListenerAdapter
android.animation.AnimatorSet
-android.animation.AnimatorSet$AnimatorSetListener
+android.animation.AnimatorSet$1
+android.animation.AnimatorSet$2
+android.animation.AnimatorSet$3
+android.animation.AnimatorSet$AnimationEvent
android.animation.AnimatorSet$Builder
android.animation.AnimatorSet$Node
+android.animation.AnimatorSet$SeekState
android.animation.ArgbEvaluator
android.animation.FloatEvaluator
android.animation.FloatKeyframeSet
@@ -299,14 +319,13 @@
android.animation.LayoutTransition
android.animation.LayoutTransition$TransitionListener
android.animation.ObjectAnimator
-android.animation.PathKeyframes
-android.animation.PathKeyframes$1
-android.animation.PathKeyframes$2
android.animation.PathKeyframes$FloatKeyframesBase
+android.animation.PathKeyframes$IntKeyframesBase
android.animation.PathKeyframes$SimpleKeyframes
android.animation.PropertyValuesHolder
android.animation.PropertyValuesHolder$FloatPropertyValuesHolder
android.animation.PropertyValuesHolder$IntPropertyValuesHolder
+android.animation.PropertyValuesHolder$PropertyValues
android.animation.RectEvaluator
android.animation.StateListAnimator
android.animation.StateListAnimator$1
@@ -316,12 +335,15 @@
android.animation.TypeEvaluator
android.animation.ValueAnimator
android.animation.ValueAnimator$AnimatorUpdateListener
+android.app.-$Lambda$36$c44uHH2WE4sJvw5tZZB6gRzEaHI
+android.app.-$Lambda$39$c44uHH2WE4sJvw5tZZB6gRzEaHI
+android.app.-$Lambda$7$u_rp3dnwvfyMTggc6hVftcuYJ3E
android.app.ActionBar
android.app.ActionBar$LayoutParams
android.app.Activity
android.app.Activity$HostCallbacks
android.app.ActivityManager
-android.app.ActivityManager$MemoryInfo
+android.app.ActivityManager$1
android.app.ActivityManager$RunningAppProcessInfo
android.app.ActivityManager$RunningAppProcessInfo$1
android.app.ActivityManager$StackId
@@ -357,20 +379,17 @@
android.app.AppOpsManager
android.app.Application
android.app.Application$ActivityLifecycleCallbacks
-android.app.ApplicationErrorReport
android.app.ApplicationErrorReport$CrashInfo
android.app.ApplicationLoaders
android.app.ApplicationPackageManager
android.app.ApplicationPackageManager$ResourceName
android.app.BackStackRecord
android.app.BackStackRecord$Op
-android.app.BackStackRecord$TransitionState
android.app.ContentProviderHolder
android.app.ContentProviderHolder$1
android.app.ContextImpl
android.app.ContextImpl$ApplicationContentResolver
android.app.Dialog
-android.app.Dialog$-void__init__android_content_Context_context_int_themeResId_boolean_createContextThemeWrapper_LambdaImpl0
android.app.Dialog$ListenersHandler
android.app.DialogFragment
android.app.DownloadManager
@@ -383,7 +402,10 @@
android.app.FragmentManager$BackStackEntry
android.app.FragmentManagerImpl
android.app.FragmentManagerImpl$1
+android.app.FragmentManagerImpl$OpGenerator
android.app.FragmentTransaction
+android.app.FragmentTransition
+android.app.FragmentTransition$FragmentContainerTransition
android.app.IActivityManager
android.app.IActivityManager$Stub
android.app.IActivityManager$Stub$Proxy
@@ -392,7 +414,6 @@
android.app.IAlarmManager$Stub$Proxy
android.app.IApplicationThread
android.app.IApplicationThread$Stub
-android.app.IApplicationThread$Stub$Proxy
android.app.IInstrumentationWatcher
android.app.IInstrumentationWatcher$Stub
android.app.INotificationManager
@@ -409,10 +430,10 @@
android.app.IntentReceiverLeaked
android.app.IntentService
android.app.IntentService$ServiceHandler
-android.app.JobSchedulerImpl
android.app.KeyguardManager
android.app.ListActivity
android.app.LoadedApk
+android.app.LoadedApk$DexLoadReporter
android.app.LoadedApk$ReceiverDispatcher
android.app.LoadedApk$ReceiverDispatcher$Args
android.app.LoadedApk$ReceiverDispatcher$InnerReceiver
@@ -426,19 +447,17 @@
android.app.LoaderManagerImpl
android.app.NativeActivity
android.app.Notification
-android.app.Notification$1
android.app.Notification$Action
android.app.Notification$BigTextStyle
android.app.Notification$Builder
-android.app.Notification$BuilderRemoteViews
android.app.Notification$Style
android.app.NotificationManager
-android.app.OnActivityPausedListener
android.app.PendingIntent
android.app.PendingIntent$1
android.app.PendingIntent$CanceledException
-android.app.ProgressDialog
+android.app.PendingIntent$OnMarshaledListener
android.app.QueuedWork
+android.app.QueuedWork$QueuedWorkHandler
android.app.ReceiverRestrictedContext
android.app.ResourcesManager
android.app.ResourcesManager$1
@@ -530,6 +549,11 @@
android.app.SystemServiceRegistry$72
android.app.SystemServiceRegistry$73
android.app.SystemServiceRegistry$74
+android.app.SystemServiceRegistry$75
+android.app.SystemServiceRegistry$76
+android.app.SystemServiceRegistry$77
+android.app.SystemServiceRegistry$78
+android.app.SystemServiceRegistry$79
android.app.SystemServiceRegistry$8
android.app.SystemServiceRegistry$9
android.app.SystemServiceRegistry$CachedServiceFetcher
@@ -550,13 +574,11 @@
android.app.backup.BackupDataOutput
android.app.backup.BackupHelperDispatcher
android.app.backup.BackupHelperDispatcher$Header
+android.app.backup.BackupManager
android.app.backup.FileBackupHelperBase
android.app.backup.FullBackup
android.app.backup.FullBackupDataOutput
-android.app.job.IJobScheduler
-android.app.job.IJobScheduler$Stub
android.app.job.JobInfo
-android.app.job.JobInfo$Builder
android.app.job.JobScheduler
android.app.job.JobService
android.app.trust.ITrustManager
@@ -564,14 +586,15 @@
android.app.trust.ITrustManager$Stub$Proxy
android.app.trust.TrustManager
android.app.usage.NetworkStatsManager
+android.app.usage.StorageStatsManager
android.app.usage.UsageStatsManager
android.appwidget.AppWidgetManager
-android.appwidget.AppWidgetProvider
android.bluetooth.BluetoothAdapter
android.bluetooth.BluetoothAdapter$1
android.bluetooth.BluetoothManager
android.bluetooth.IBluetooth
android.bluetooth.IBluetooth$Stub
+android.bluetooth.IBluetooth$Stub$Proxy
android.bluetooth.IBluetoothManager
android.bluetooth.IBluetoothManager$Stub
android.bluetooth.IBluetoothManager$Stub$Proxy
@@ -582,8 +605,6 @@
android.content.BroadcastReceiver$PendingResult
android.content.BroadcastReceiver$PendingResult$1
android.content.ClipData
-android.content.ClipData$Item
-android.content.ClipDescription
android.content.ClipboardManager
android.content.ComponentCallbacks
android.content.ComponentCallbacks2
@@ -594,7 +615,6 @@
android.content.ContentProviderClient
android.content.ContentProviderNative
android.content.ContentProviderOperation
-android.content.ContentProviderOperation$Builder
android.content.ContentProviderProxy
android.content.ContentProviderResult
android.content.ContentResolver
@@ -618,10 +638,6 @@
android.content.IIntentSender
android.content.IIntentSender$Stub
android.content.IIntentSender$Stub$Proxy
-android.content.ISyncAdapter
-android.content.ISyncAdapter$Stub
-android.content.ISyncContext
-android.content.ISyncContext$Stub
android.content.Intent
android.content.Intent$1
android.content.IntentFilter
@@ -635,13 +651,7 @@
android.content.SharedPreferences
android.content.SharedPreferences$Editor
android.content.SharedPreferences$OnSharedPreferenceChangeListener
-android.content.SyncResult
-android.content.SyncResult$1
-android.content.SyncStats
-android.content.SyncStats$1
android.content.UndoManager
-android.content.UndoManager$UndoState
-android.content.UndoOperation
android.content.UndoOwner
android.content.UriMatcher
android.content.pm.ActivityInfo
@@ -714,7 +724,6 @@
android.content.res.ResourcesImpl$ThemeImpl
android.content.res.ResourcesKey
android.content.res.StringBlock
-android.content.res.StringBlock$StyleIDs
android.content.res.ThemedResourceCache
android.content.res.TypedArray
android.content.res.XmlBlock
@@ -752,7 +761,6 @@
android.database.IContentObserver$Stub
android.database.IContentObserver$Stub$Proxy
android.database.MatrixCursor
-android.database.MatrixCursor$RowBuilder
android.database.Observable
android.database.SQLException
android.database.sqlite.DatabaseObjectNotClosedException
@@ -796,6 +804,7 @@
android.ddm.DdmHandleThread
android.ddm.DdmHandleViewDebug
android.ddm.DdmRegister
+android.graphics.BaseCanvas
android.graphics.Bitmap
android.graphics.Bitmap$1
android.graphics.Bitmap$CompressFormat
@@ -812,7 +821,6 @@
android.graphics.CanvasProperty
android.graphics.Color
android.graphics.ColorFilter
-android.graphics.ColorMatrix
android.graphics.ColorMatrixColorFilter
android.graphics.ComposePathEffect
android.graphics.ComposeShader
@@ -823,15 +831,17 @@
android.graphics.EmbossMaskFilter
android.graphics.FontFamily
android.graphics.FontListParser
+android.graphics.GraphicBuffer
+android.graphics.GraphicBuffer$1
android.graphics.Insets
android.graphics.Interpolator
android.graphics.Interpolator$Result
-android.graphics.LayerRasterizer
android.graphics.LightingColorFilter
android.graphics.LinearGradient
android.graphics.MaskFilter
android.graphics.Matrix
android.graphics.Matrix$1
+android.graphics.Matrix$NoImagePreloadHolder
android.graphics.Matrix$ScaleToFit
android.graphics.Movie
android.graphics.NinePatch
@@ -863,7 +873,6 @@
android.graphics.PorterDuffColorFilter
android.graphics.PorterDuffXfermode
android.graphics.RadialGradient
-android.graphics.Rasterizer
android.graphics.Rect
android.graphics.Rect$1
android.graphics.RectF
@@ -876,7 +885,6 @@
android.graphics.Shader$TileMode
android.graphics.SumPathEffect
android.graphics.SurfaceTexture
-android.graphics.SurfaceTexture$OnFrameAvailableListener
android.graphics.SweepGradient
android.graphics.TableMaskFilter
android.graphics.TemporaryBuffer
@@ -893,7 +901,6 @@
android.graphics.drawable.AnimatedVectorDrawable$AnimatedVectorDrawableState$PendingAnimator
android.graphics.drawable.AnimatedVectorDrawable$VectorDrawableAnimator
android.graphics.drawable.AnimatedVectorDrawable$VectorDrawableAnimatorRT
-android.graphics.drawable.AnimatedVectorDrawable$VectorDrawableAnimatorUI
android.graphics.drawable.AnimationDrawable
android.graphics.drawable.AnimationDrawable$AnimationState
android.graphics.drawable.BitmapDrawable
@@ -904,6 +911,7 @@
android.graphics.drawable.Drawable$Callback
android.graphics.drawable.Drawable$ConstantState
android.graphics.drawable.DrawableContainer
+android.graphics.drawable.DrawableContainer$BlockInvalidateCallback
android.graphics.drawable.DrawableContainer$DrawableContainerState
android.graphics.drawable.DrawableInflater
android.graphics.drawable.DrawableWrapper
@@ -943,11 +951,30 @@
android.graphics.drawable.VectorDrawable
android.graphics.drawable.VectorDrawable$VFullPath
android.graphics.drawable.VectorDrawable$VFullPath$1
+android.graphics.drawable.VectorDrawable$VFullPath$10
+android.graphics.drawable.VectorDrawable$VFullPath$2
+android.graphics.drawable.VectorDrawable$VFullPath$3
+android.graphics.drawable.VectorDrawable$VFullPath$4
+android.graphics.drawable.VectorDrawable$VFullPath$5
+android.graphics.drawable.VectorDrawable$VFullPath$6
+android.graphics.drawable.VectorDrawable$VFullPath$7
+android.graphics.drawable.VectorDrawable$VFullPath$8
+android.graphics.drawable.VectorDrawable$VFullPath$9
android.graphics.drawable.VectorDrawable$VGroup
android.graphics.drawable.VectorDrawable$VGroup$1
+android.graphics.drawable.VectorDrawable$VGroup$2
+android.graphics.drawable.VectorDrawable$VGroup$3
+android.graphics.drawable.VectorDrawable$VGroup$4
+android.graphics.drawable.VectorDrawable$VGroup$5
+android.graphics.drawable.VectorDrawable$VGroup$6
+android.graphics.drawable.VectorDrawable$VGroup$7
+android.graphics.drawable.VectorDrawable$VGroup$8
+android.graphics.drawable.VectorDrawable$VGroup$9
android.graphics.drawable.VectorDrawable$VObject
android.graphics.drawable.VectorDrawable$VPath
+android.graphics.drawable.VectorDrawable$VPath$1
android.graphics.drawable.VectorDrawable$VectorDrawableState
+android.graphics.drawable.VectorDrawable$VectorDrawableState$1
android.graphics.drawable.shapes.OvalShape
android.graphics.drawable.shapes.RectShape
android.graphics.drawable.shapes.Shape
@@ -958,6 +985,8 @@
android.hardware.Camera$CameraInfo
android.hardware.Camera$Face
android.hardware.ConsumerIrManager
+android.hardware.HardwareBuffer
+android.hardware.HardwareBuffer$1
android.hardware.Sensor
android.hardware.SensorEvent
android.hardware.SensorEventListener
@@ -966,7 +995,6 @@
android.hardware.SerialPort
android.hardware.SystemSensorManager
android.hardware.SystemSensorManager$BaseEventQueue
-android.hardware.SystemSensorManager$SensorEventQueue
android.hardware.camera2.CameraCharacteristics$Key
android.hardware.camera2.CameraManager
android.hardware.camera2.CaptureRequest$Key
@@ -996,9 +1024,10 @@
android.hardware.input.InputDeviceIdentifier$1
android.hardware.input.InputManager
android.hardware.input.InputManager$InputDevicesChangedListener
+android.hardware.location.ActivityRecognitionHardware
android.hardware.location.ContextHubManager
-android.hardware.location.IContextHubService
-android.hardware.location.IContextHubService$Stub
+android.hardware.location.IActivityRecognitionHardware
+android.hardware.location.IActivityRecognitionHardware$Stub
android.hardware.radio.RadioManager
android.hardware.radio.RadioManager$AmBandConfig
android.hardware.radio.RadioManager$AmBandConfig$1
@@ -1044,8 +1073,6 @@
android.hardware.soundtrigger.SoundTrigger$SoundModelEvent
android.hardware.soundtrigger.SoundTrigger$SoundModelEvent$1
android.hardware.soundtrigger.SoundTriggerModule
-android.hardware.usb.IUsbManager
-android.hardware.usb.IUsbManager$Stub
android.hardware.usb.UsbDevice
android.hardware.usb.UsbDeviceConnection
android.hardware.usb.UsbManager
@@ -1056,16 +1083,16 @@
android.icu.impl.CacheValue$NullValue
android.icu.impl.CacheValue$SoftValue
android.icu.impl.CacheValue$Strength
-android.icu.impl.CalendarData
android.icu.impl.CalendarUtil
+android.icu.impl.CalendarUtil$CalendarPreferences
android.icu.impl.CharTrie
android.icu.impl.ClassLoaderUtil
android.icu.impl.CurrencyData
android.icu.impl.CurrencyData$CurrencyDisplayInfo
android.icu.impl.CurrencyData$CurrencyDisplayInfoProvider
android.icu.impl.CurrencyData$CurrencySpacingInfo
-android.icu.impl.DateNumberFormat
-android.icu.impl.Grego
+android.icu.impl.CurrencyData$CurrencySpacingInfo$SpacingPattern
+android.icu.impl.CurrencyData$CurrencySpacingInfo$SpacingType
android.icu.impl.ICUBinary
android.icu.impl.ICUBinary$Authenticate
android.icu.impl.ICUBinary$DatPackageReader
@@ -1076,6 +1103,7 @@
android.icu.impl.ICUConfig
android.icu.impl.ICUCurrencyDisplayInfoProvider
android.icu.impl.ICUCurrencyDisplayInfoProvider$ICUCurrencyDisplayInfo
+android.icu.impl.ICUCurrencyDisplayInfoProvider$ICUCurrencyDisplayInfo$SpacingInfoSink
android.icu.impl.ICUCurrencyMetaInfo
android.icu.impl.ICUCurrencyMetaInfo$Collector
android.icu.impl.ICUCurrencyMetaInfo$CurrencyCollector
@@ -1091,13 +1119,15 @@
android.icu.impl.ICUResourceBundle
android.icu.impl.ICUResourceBundle$1
android.icu.impl.ICUResourceBundle$2
-android.icu.impl.ICUResourceBundle$2$1
+android.icu.impl.ICUResourceBundle$3
+android.icu.impl.ICUResourceBundle$3$1
+android.icu.impl.ICUResourceBundle$4
android.icu.impl.ICUResourceBundle$AvailEntry
+android.icu.impl.ICUResourceBundle$Loader
android.icu.impl.ICUResourceBundle$OpenType
android.icu.impl.ICUResourceBundle$WholeBundle
android.icu.impl.ICUResourceBundleImpl
android.icu.impl.ICUResourceBundleImpl$ResourceArray
-android.icu.impl.ICUResourceBundleImpl$ResourceBinary
android.icu.impl.ICUResourceBundleImpl$ResourceContainer
android.icu.impl.ICUResourceBundleImpl$ResourceInt
android.icu.impl.ICUResourceBundleImpl$ResourceIntVector
@@ -1111,6 +1141,7 @@
android.icu.impl.ICUResourceBundleReader$IsAcceptable
android.icu.impl.ICUResourceBundleReader$ReaderCache
android.icu.impl.ICUResourceBundleReader$ReaderCacheKey
+android.icu.impl.ICUResourceBundleReader$ReaderValue
android.icu.impl.ICUResourceBundleReader$ResourceCache
android.icu.impl.ICUResourceBundleReader$ResourceCache$Level
android.icu.impl.ICUResourceBundleReader$Table
@@ -1121,7 +1152,6 @@
android.icu.impl.ICUService$Factory
android.icu.impl.ICUService$Key
android.icu.impl.IDNA2003
-android.icu.impl.JavaTimeZone
android.icu.impl.LocaleIDParser
android.icu.impl.LocaleIDs
android.icu.impl.Norm2AllModes
@@ -1129,7 +1159,6 @@
android.icu.impl.Norm2AllModes$ComposeNormalizer2
android.icu.impl.Norm2AllModes$DecomposeNormalizer2
android.icu.impl.Norm2AllModes$FCDNormalizer2
-android.icu.impl.Norm2AllModes$NFCSingleton
android.icu.impl.Norm2AllModes$NFKCSingleton
android.icu.impl.Norm2AllModes$NoopNormalizer2
android.icu.impl.Norm2AllModes$Norm2AllModesSingleton
@@ -1137,14 +1166,13 @@
android.icu.impl.Normalizer2Impl
android.icu.impl.Normalizer2Impl$1
android.icu.impl.Normalizer2Impl$IsAcceptable
-android.icu.impl.OlsonTimeZone
android.icu.impl.Pair
android.icu.impl.PatternProps
-android.icu.impl.PatternTokenizer
android.icu.impl.PluralRulesLoader
android.icu.impl.ReplaceableUCharacterIterator
android.icu.impl.RuleCharacterIterator
android.icu.impl.SimpleCache
+android.icu.impl.SimpleFormatterImpl
android.icu.impl.SoftCache
android.icu.impl.StandardPlural
android.icu.impl.StringPrepDataReader
@@ -1159,7 +1187,6 @@
android.icu.impl.Trie2$ValueMapper
android.icu.impl.Trie2$ValueWidth
android.icu.impl.Trie2_16
-android.icu.impl.Trie2_32
android.icu.impl.UBiDiProps
android.icu.impl.UBiDiProps$IsAcceptable
android.icu.impl.UCharacterProperty
@@ -1194,24 +1221,13 @@
android.icu.impl.UCharacterProperty$IsAcceptable
android.icu.impl.UCharacterProperty$NormInertBinaryProperty
android.icu.impl.UCharacterProperty$NormQuickCheckIntProperty
-android.icu.impl.UPropertyAliases
-android.icu.impl.UPropertyAliases$IsAcceptable
android.icu.impl.URLHandler$URLVisitor
-android.icu.impl.USerializedSet
+android.icu.impl.UResource$Array
+android.icu.impl.UResource$Key
+android.icu.impl.UResource$Sink
+android.icu.impl.UResource$Table
+android.icu.impl.UResource$Value
android.icu.impl.Utility
-android.icu.impl.ZoneMeta
-android.icu.impl.ZoneMeta$CustomTimeZoneCache
-android.icu.impl.ZoneMeta$SystemTimeZoneCache
-android.icu.impl.coll.CollationData
-android.icu.impl.coll.CollationDataReader
-android.icu.impl.coll.CollationDataReader$IsAcceptable
-android.icu.impl.coll.CollationFastLatin
-android.icu.impl.coll.CollationLoader
-android.icu.impl.coll.CollationRoot
-android.icu.impl.coll.CollationSettings
-android.icu.impl.coll.CollationTailoring
-android.icu.impl.coll.SharedObject
-android.icu.impl.coll.SharedObject$Reference
android.icu.impl.locale.AsciiUtil
android.icu.impl.locale.BaseLocale
android.icu.impl.locale.BaseLocale$Cache
@@ -1222,8 +1238,6 @@
android.icu.lang.UCharacter
android.icu.lang.UCharacterEnums$ECharacterCategory
android.icu.lang.UCharacterEnums$ECharacterDirection
-android.icu.lang.UScript
-android.icu.lang.UScript$ScriptUsage
android.icu.math.BigDecimal
android.icu.math.MathContext
android.icu.text.BreakIterator
@@ -1232,51 +1246,26 @@
android.icu.text.BreakIteratorFactory
android.icu.text.BreakIteratorFactory$BFService
android.icu.text.BreakIteratorFactory$BFService$1RBBreakIteratorFactory
-android.icu.text.Collator
-android.icu.text.Collator$ServiceShim
-android.icu.text.CollatorServiceShim
-android.icu.text.CollatorServiceShim$CService
-android.icu.text.CollatorServiceShim$CService$1CollatorFactory
android.icu.text.CurrencyDisplayNames
android.icu.text.CurrencyMetaInfo
android.icu.text.CurrencyMetaInfo$CurrencyDigits
android.icu.text.CurrencyMetaInfo$CurrencyFilter
-android.icu.text.DateFormat
-android.icu.text.DateFormat$BooleanAttribute
-android.icu.text.DateFormat$Field
android.icu.text.DateFormatSymbols
+android.icu.text.DateFormatSymbols$1
+android.icu.text.DateFormatSymbols$CalendarDataSink
+android.icu.text.DateFormatSymbols$CalendarDataSink$AliasType
android.icu.text.DateFormatSymbols$CapitalizationContextUsage
-android.icu.text.DateIntervalFormat
-android.icu.text.DateIntervalFormat$BestMatchInfo
-android.icu.text.DateIntervalInfo
-android.icu.text.DateIntervalInfo$PatternInfo
-android.icu.text.DateTimePatternGenerator
-android.icu.text.DateTimePatternGenerator$DTPGflags
-android.icu.text.DateTimePatternGenerator$DateTimeMatcher
-android.icu.text.DateTimePatternGenerator$DistanceInfo
-android.icu.text.DateTimePatternGenerator$FormatParser
-android.icu.text.DateTimePatternGenerator$PatternInfo
-android.icu.text.DateTimePatternGenerator$PatternWithMatcher
-android.icu.text.DateTimePatternGenerator$PatternWithSkeletonFlag
-android.icu.text.DateTimePatternGenerator$VariableField
android.icu.text.DecimalFormat
android.icu.text.DecimalFormat$Unit
android.icu.text.DecimalFormatSymbols
android.icu.text.DecimalFormatSymbols$1
android.icu.text.DecimalFormatSymbols$CacheData
+android.icu.text.DecimalFormatSymbols$DecFmtDataSink
android.icu.text.DigitList
android.icu.text.DisplayContext
android.icu.text.DisplayContext$Type
android.icu.text.IDNA
android.icu.text.LanguageBreakEngine
-android.icu.text.MessageFormat
-android.icu.text.MessageFormat$AppendableWrapper
-android.icu.text.MessageFormat$Field
-android.icu.text.MessagePattern
-android.icu.text.MessagePattern$ApostropheMode
-android.icu.text.MessagePattern$ArgType
-android.icu.text.MessagePattern$Part
-android.icu.text.MessagePattern$Part$Type
android.icu.text.Normalizer
android.icu.text.Normalizer$FCDMode
android.icu.text.Normalizer$Mode
@@ -1292,6 +1281,9 @@
android.icu.text.NumberFormat
android.icu.text.NumberFormat$Field
android.icu.text.NumberingSystem
+android.icu.text.NumberingSystem$1
+android.icu.text.NumberingSystem$2
+android.icu.text.NumberingSystem$LocaleLookupData
android.icu.text.PluralRanges
android.icu.text.PluralRanges$Matrix
android.icu.text.PluralRules
@@ -1317,11 +1309,10 @@
android.icu.text.Replaceable
android.icu.text.ReplaceableString
android.icu.text.RuleBasedBreakIterator
-android.icu.text.RuleBasedCollator
-android.icu.text.SimpleDateFormat
-android.icu.text.SimpleDateFormat$PatternItem
+android.icu.text.RuleBasedBreakIterator$LookAheadResults
android.icu.text.StringPrep
android.icu.text.StringPrepParseException
+android.icu.text.TimeZoneNames$NameType
android.icu.text.UCharacterIterator
android.icu.text.UFieldPosition
android.icu.text.UFormat
@@ -1331,48 +1322,36 @@
android.icu.text.UnicodeFilter
android.icu.text.UnicodeMatcher
android.icu.text.UnicodeSet
-android.icu.text.UnicodeSet$Filter
-android.icu.text.UnicodeSet$GeneralCategoryMaskFilter
-android.icu.text.UnicodeSet$IntPropertyFilter
-android.icu.util.BasicTimeZone
-android.icu.util.BytesTrie
android.icu.util.BytesTrie$Result
-android.icu.util.Calendar
-android.icu.util.Calendar$CalType
-android.icu.util.Calendar$FormatConfiguration
-android.icu.util.Calendar$PatternData
-android.icu.util.Calendar$WeekData
-android.icu.util.Calendar$WeekDataCache
android.icu.util.Currency
+android.icu.util.Currency$1
android.icu.util.Currency$CurrencyUsage
android.icu.util.Currency$EquivalenceRelation
android.icu.util.Freezable
-android.icu.util.GregorianCalendar
android.icu.util.MeasureUnit
android.icu.util.MeasureUnit$1
android.icu.util.MeasureUnit$2
android.icu.util.MeasureUnit$3
android.icu.util.MeasureUnit$Factory
-android.icu.util.Output
-android.icu.util.SimpleTimeZone
android.icu.util.TimeUnit
android.icu.util.TimeZone
android.icu.util.TimeZone$ConstantZone
android.icu.util.ULocale
+android.icu.util.ULocale$1
+android.icu.util.ULocale$2
android.icu.util.ULocale$Category
android.icu.util.ULocale$JDKLocaleHelper
android.icu.util.ULocale$Type
android.icu.util.UResourceBundle
-android.icu.util.UResourceBundle$ResourceCacheKey
+android.icu.util.UResourceBundle$RootType
android.icu.util.UResourceBundleIterator
android.icu.util.UResourceTypeMismatchException
android.icu.util.VersionInfo
android.location.CountryDetector
-android.location.ILocationManager
-android.location.ILocationManager$Stub
android.location.Location
+android.location.Location$1
+android.location.Location$2
android.location.LocationManager
-android.media.AmrInputStream
android.media.AudioAttributes
android.media.AudioAttributes$1
android.media.AudioAttributes$Builder
@@ -1386,7 +1365,7 @@
android.media.AudioManager
android.media.AudioManager$1
android.media.AudioManager$2
-android.media.AudioManager$OnAudioFocusChangeListener
+android.media.AudioManager$3
android.media.AudioManager$ServiceEventHandlerDelegate
android.media.AudioManager$ServiceEventHandlerDelegate$1
android.media.AudioMixPort
@@ -1404,7 +1383,6 @@
android.media.CameraProfile
android.media.DecoderCapabilities
android.media.EncoderCapabilities
-android.media.ExifInterface
android.media.IAudioFocusDispatcher
android.media.IAudioFocusDispatcher$Stub
android.media.IAudioService
@@ -1412,6 +1390,10 @@
android.media.IAudioService$Stub$Proxy
android.media.IMediaHTTPConnection
android.media.IMediaHTTPConnection$Stub
+android.media.IPlaybackConfigDispatcher
+android.media.IPlaybackConfigDispatcher$Stub
+android.media.IPlayer
+android.media.IPlayer$Stub
android.media.IRecordingConfigDispatcher
android.media.IRecordingConfigDispatcher$Stub
android.media.Image
@@ -1422,6 +1404,8 @@
android.media.JetPlayer
android.media.MediaCodec
android.media.MediaCodecInfo
+android.media.MediaCodecInfo$CodecCapabilities
+android.media.MediaCodecInfo$CodecProfileLevel
android.media.MediaCodecList
android.media.MediaCrypto
android.media.MediaDrm
@@ -1432,21 +1416,17 @@
android.media.MediaMuxer
android.media.MediaPlayer
android.media.MediaPlayer$OnCompletionListener
-android.media.MediaPlayer$OnErrorListener
-android.media.MediaPlayer$OnPreparedListener
-android.media.MediaPlayer$OnSeekCompleteListener
-android.media.MediaPlayer$OnVideoSizeChangedListener
android.media.MediaRecorder
android.media.MediaRouter
-android.media.MediaRouter$Callback
-android.media.MediaRouter$RouteCategory
-android.media.MediaRouter$RouteInfo
android.media.MediaScanner
android.media.MediaSync
android.media.PlaybackParams
android.media.PlaybackParams$1
android.media.PlayerBase
android.media.PlayerBase$1
+android.media.PlayerBase$2
+android.media.PlayerBase$PlayerIdCard
+android.media.PlayerBase$PlayerIdCard$1
android.media.RemoteDisplay
android.media.ResampleInputStream
android.media.SubtitleController$Listener
@@ -1456,12 +1436,10 @@
android.media.audiopolicy.AudioMixingRule$AudioMixMatchCriterion
android.media.midi.MidiManager
android.media.projection.MediaProjectionManager
-android.media.session.MediaController
-android.media.session.MediaController$TransportControls
-android.media.session.MediaSession$Token
android.media.session.MediaSessionManager
android.media.soundtrigger.SoundTriggerManager
android.media.tv.TvInputManager
+android.metrics.LogMaker
android.mtp.MtpDatabase
android.mtp.MtpDevice
android.mtp.MtpDeviceInfo
@@ -1476,6 +1454,8 @@
android.net.ConnectivityManager$CallbackHandler
android.net.ConnectivityManager$NetworkCallback
android.net.ConnectivityThread
+# Must not be initialized, creates a thread.
+# android.net.ConnectivityThread$Singleton
android.net.Credentials
android.net.EthernetManager
android.net.IConnectivityManager
@@ -1504,6 +1484,7 @@
android.net.NetworkRequest
android.net.NetworkRequest$1
android.net.NetworkRequest$Builder
+android.net.NetworkRequest$Type
android.net.NetworkScoreManager
android.net.NetworkStats
android.net.NetworkStats$1
@@ -1512,9 +1493,6 @@
android.net.ProxyInfo
android.net.RouteInfo
android.net.RouteInfo$1
-android.net.SSLCertificateSocketFactory
-android.net.SSLCertificateSocketFactory$1
-android.net.SSLSessionCache
android.net.TrafficStats
android.net.Uri
android.net.Uri$1
@@ -1539,29 +1517,13 @@
android.net.wifi.WifiInfo
android.net.wifi.WifiInfo$1
android.net.wifi.WifiManager
-android.net.wifi.WifiManager$WifiLock
android.net.wifi.WifiScanner
android.net.wifi.WifiSsid
android.net.wifi.WifiSsid$1
-android.net.wifi.nan.WifiNanManager
+android.net.wifi.aware.WifiAwareManager
android.net.wifi.p2p.WifiP2pManager
-android.nfc.IAppCallback
-android.nfc.IAppCallback$Stub
android.nfc.INfcAdapter
android.nfc.INfcAdapter$Stub
-android.nfc.INfcAdapter$Stub$Proxy
-android.nfc.INfcCardEmulation
-android.nfc.INfcCardEmulation$Stub
-android.nfc.INfcCardEmulation$Stub$Proxy
-android.nfc.INfcFCardEmulation
-android.nfc.INfcFCardEmulation$Stub
-android.nfc.INfcFCardEmulation$Stub$Proxy
-android.nfc.INfcTag
-android.nfc.INfcTag$Stub
-android.nfc.INfcTag$Stub$Proxy
-android.nfc.NfcActivityManager
-android.nfc.NfcAdapter
-android.nfc.NfcAdapter$1
android.nfc.NfcManager
android.opengl.EGL14
android.opengl.EGLConfig
@@ -1583,6 +1545,7 @@
android.opengl.GLUtils
android.opengl.Matrix
android.opengl.Visibility
+android.os.-$Lambda$5$6x30vPJhBKUfNY8tswxuZo3DCe0
android.os.AsyncTask$1
android.os.AsyncTask$2
android.os.AsyncTask$3
@@ -1614,17 +1577,24 @@
android.os.DropBoxManager
android.os.Environment
android.os.Environment$UserEnvironment
+android.os.FactoryTest
android.os.FileObserver$ObserverThread
android.os.FileUtils
+android.os.GraphicsEnvironment
android.os.Handler
android.os.Handler$Callback
android.os.Handler$MessengerImpl
android.os.HandlerThread
android.os.HardwarePropertiesManager
+android.os.HwBinder
+android.os.HwBlob
+android.os.HwParcel
+android.os.HwRemoteBinder
android.os.IBinder
android.os.IBinder$DeathRecipient
android.os.ICancellationSignal
android.os.ICancellationSignal$Stub
+android.os.IHwBinder
android.os.IInterface
android.os.IMessenger
android.os.IMessenger$Stub
@@ -1641,7 +1611,7 @@
android.os.IUserManager$Stub$Proxy
android.os.IVibratorService
android.os.IVibratorService$Stub
-android.os.IVibratorService$Stub$Proxy
+android.os.IncidentManager
android.os.LocaleList
android.os.LocaleList$1
android.os.Looper
@@ -1658,7 +1628,6 @@
android.os.ParcelFileDescriptor
android.os.ParcelFileDescriptor$1
android.os.ParcelFileDescriptor$AutoCloseInputStream
-android.os.ParcelFileDescriptor$AutoCloseOutputStream
android.os.Parcelable
android.os.Parcelable$ClassLoaderCreator
android.os.Parcelable$Creator
@@ -1677,8 +1646,11 @@
android.os.ResultReceiver
android.os.SELinux
android.os.ServiceManager
+android.os.ServiceManager$ServiceNotFoundException
android.os.ServiceManagerNative
android.os.ServiceManagerProxy
+android.os.ServiceSpecificException
+android.os.ShellCallback
android.os.StatFs
android.os.StrictMode
android.os.StrictMode$1
@@ -1704,6 +1676,7 @@
android.os.StrictMode$ThreadPolicy$Builder
android.os.StrictMode$ThreadSpanState
android.os.StrictMode$ViolationInfo
+android.os.StrictMode$ViolationInfo$1
android.os.StrictMode$VmPolicy
android.os.StrictMode$VmPolicy$Builder
android.os.SystemClock
@@ -1716,6 +1689,7 @@
android.os.UserHandle$1
android.os.UserManager
android.os.Vibrator
+android.os.ZygoteProcess
android.os.ZygoteStartFailedEx
android.os.health.SystemHealthManager
android.os.storage.IStorageManager
@@ -1724,17 +1698,16 @@
android.os.storage.StorageManager
android.os.storage.StorageVolume
android.os.storage.StorageVolume$1
-android.preference.Preference$OnPreferenceChangeListener
android.preference.PreferenceActivity
android.preference.PreferenceFragment$OnPreferenceStartFragmentCallback
android.preference.PreferenceManager
android.preference.PreferenceManager$OnPreferenceTreeClickListener
android.print.PrintManager
+android.provider.-$Lambda$46$87WmhkvObehVg0OMBzwa_MTVV8g
android.provider.BaseColumns
android.provider.ContactsContract
android.provider.ContactsContract$CommonDataKinds$BaseTypes
android.provider.ContactsContract$CommonDataKinds$CommonColumns
-android.provider.ContactsContract$CommonDataKinds$Email
android.provider.ContactsContract$CommonDataKinds$Phone
android.provider.ContactsContract$ContactCounts
android.provider.ContactsContract$ContactNameColumns
@@ -1748,13 +1721,12 @@
android.provider.ContactsContract$DataUsageStatColumns
android.provider.ContactsContract$RawContactsColumns
android.provider.ContactsContract$StatusColumns
-android.provider.MediaStore$Images$ImageColumns
-android.provider.MediaStore$Images$Media
android.provider.MediaStore$MediaColumns
+android.provider.Settings
+android.provider.Settings$ContentProviderHolder
android.provider.Settings$GenerationTracker
android.provider.Settings$Global
android.provider.Settings$NameValueCache
-android.provider.Settings$NameValueCache$-java_lang_String_getStringForUser_android_content_ContentResolver_cr_java_lang_String_name_int_userHandle_LambdaImpl0
android.provider.Settings$NameValueTable
android.provider.Settings$Secure
android.provider.Settings$SettingNotFoundException
@@ -1773,8 +1745,6 @@
android.provider.Settings$System$InclusiveIntegerRangeValidator
android.provider.Settings$System$Validator
android.renderscript.RenderScriptCacheDir
-android.security.FrameworkNetworkSecurityPolicy
-android.security.NetworkSecurityPolicy
android.security.keystore.AndroidKeyStoreBCWorkaroundProvider
android.security.keystore.AndroidKeyStoreProvider
android.security.net.config.ApplicationConfig
@@ -1797,9 +1767,7 @@
android.security.net.config.RootTrustManager
android.security.net.config.RootTrustManagerFactorySpi
android.security.net.config.SystemCertificateSource
-android.security.net.config.TrustAnchor
android.security.net.config.TrustedCertificateStoreAdapter
-android.security.net.config.UserCertificateSource
android.service.persistentdata.PersistentDataBlockManager
android.system.ErrnoException
android.system.GaiException
@@ -1811,6 +1779,7 @@
android.system.StructFlock
android.system.StructGroupReq
android.system.StructGroupSourceReq
+android.system.StructIfaddrs
android.system.StructLinger
android.system.StructPasswd
android.system.StructPollfd
@@ -1824,11 +1793,11 @@
android.telephony.CarrierConfigManager
android.telephony.PhoneNumberUtils
android.telephony.PhoneStateListener
-android.telephony.PhoneStateListener$1
-android.telephony.PhoneStateListener$IPhoneStateListenerStub
android.telephony.Rlog
+android.telephony.ServiceState
android.telephony.SubscriptionManager
android.telephony.TelephonyManager
+android.telephony.TelephonyManager$MultiSimVariants
android.text.AndroidBidi
android.text.AndroidCharacter
android.text.BoringLayout
@@ -1839,15 +1808,19 @@
android.text.Editable
android.text.Editable$Factory
android.text.FontConfig
+android.text.FontConfig$1
android.text.FontConfig$Alias
+android.text.FontConfig$Alias$1
android.text.FontConfig$Axis
+android.text.FontConfig$Axis$1
android.text.FontConfig$Family
+android.text.FontConfig$Family$1
android.text.FontConfig$Font
+android.text.FontConfig$Font$1
+android.text.FontManager
android.text.GetChars
android.text.GraphicsOperations
android.text.Html
-android.text.Html$HtmlParser
-android.text.HtmlToSpannedConverter
android.text.Hyphenator
android.text.InputFilter
android.text.InputType
@@ -1889,15 +1862,11 @@
android.text.TextUtils
android.text.TextUtils$1
android.text.TextUtils$EllipsizeCallback
-android.text.TextUtils$SimpleStringSplitter
-android.text.TextUtils$StringSplitter
android.text.TextUtils$TruncateAt
android.text.TextWatcher
android.text.format.DateFormat
android.text.format.DateUtils
-android.text.format.Formatter
android.text.format.Time
-android.text.format.Time$TimeCalculator
android.text.method.AllCapsTransformationMethod
android.text.method.ArrowKeyMovementMethod
android.text.method.BaseKeyListener
@@ -1919,10 +1888,8 @@
android.text.style.AlignmentSpan
android.text.style.CharacterStyle
android.text.style.ClickableSpan
-android.text.style.DynamicDrawableSpan
android.text.style.EasyEditSpan
android.text.style.ForegroundColorSpan
-android.text.style.ImageSpan
android.text.style.LeadingMarginSpan
android.text.style.LineBackgroundSpan
android.text.style.LineHeightSpan
@@ -1933,9 +1900,7 @@
android.text.style.StyleSpan
android.text.style.SuggestionSpan
android.text.style.TabStopSpan
-android.text.style.TextAppearanceSpan
android.text.style.URLSpan
-android.text.style.UnderlineSpan
android.text.style.UpdateAppearance
android.text.style.UpdateLayout
android.text.style.WrapTogetherSpan
@@ -1956,7 +1921,6 @@
android.transition.ChangeTransform$2
android.transition.Fade
android.transition.PathMotion
-android.transition.Scene
android.transition.Transition
android.transition.Transition$1
android.transition.Transition$EpicenterCallback
@@ -1976,18 +1940,20 @@
android.util.Base64$Coder
android.util.Base64$Decoder
android.util.Base64$Encoder
+android.util.BootTimingsTraceLog
android.util.ContainerHelpers
android.util.DisplayMetrics
android.util.EventLog
android.util.EventLog$Event
android.util.FloatProperty
+android.util.IntArray
android.util.IntProperty
-android.util.JsonReader
android.util.Log
android.util.Log$1
android.util.Log$ImmediateLogWriter
android.util.Log$TerribleFailureHandler
android.util.LogPrinter
+android.util.LongArray
android.util.LongSparseArray
android.util.LongSparseLongArray
android.util.LruCache
@@ -2002,6 +1968,7 @@
android.util.Pair
android.util.PathParser
android.util.PathParser$PathData
+android.util.Patterns
android.util.Pools$Pool
android.util.Pools$SimplePool
android.util.Pools$SynchronizedPool
@@ -2011,24 +1978,24 @@
android.util.Rational
android.util.Singleton
android.util.Size
+android.util.SizeF
android.util.Slog
android.util.SparseArray
android.util.SparseBooleanArray
android.util.SparseIntArray
-android.util.SparseLongArray
android.util.StateSet
android.util.SuperNotCalledException
-android.util.TimeFormatException
android.util.TypedValue
android.util.Xml
android.util.jar.StrictJarFile
+android.view.-$Lambda$48$iU_USrtPm1XIm5H9QYQvXfBGDE4
+android.view.-$Lambda$49$iU_USrtPm1XIm5H9QYQvXfBGDE4
android.view.AbsSavedState
android.view.AbsSavedState$1
android.view.AbsSavedState$2
android.view.ActionMode
android.view.ActionMode$Callback
android.view.ActionProvider
-android.view.ActionProvider$SubUiVisibilityListener
android.view.Choreographer
android.view.Choreographer$1
android.view.Choreographer$2
@@ -2041,8 +2008,6 @@
android.view.ContextMenu$ContextMenuInfo
android.view.ContextThemeWrapper
android.view.Display
-android.view.Display$ColorTransform
-android.view.Display$ColorTransform$1
android.view.Display$HdrCapabilities
android.view.Display$HdrCapabilities$1
android.view.Display$Mode
@@ -2052,6 +2017,7 @@
android.view.DisplayInfo
android.view.DisplayInfo$1
android.view.DisplayListCanvas
+android.view.DragEvent
android.view.FallbackEventHandler
android.view.FocusFinder
android.view.FocusFinder$1
@@ -2066,8 +2032,6 @@
android.view.GestureDetector$OnDoubleTapListener
android.view.GestureDetector$OnGestureListener
android.view.GestureDetector$SimpleOnGestureListener
-android.view.GraphicBuffer
-android.view.GraphicBuffer$1
android.view.Gravity
android.view.HandlerActionQueue
android.view.HandlerActionQueue$HandlerAction
@@ -2092,7 +2056,6 @@
android.view.InputChannel$1
android.view.InputDevice
android.view.InputDevice$1
-android.view.InputDevice$MotionRange
android.view.InputEvent
android.view.InputEvent$1
android.view.InputEventConsistencyVerifier
@@ -2125,9 +2088,12 @@
android.view.MotionEvent$PointerProperties
android.view.PointerIcon
android.view.PointerIcon$1
+android.view.RecordingCanvas
android.view.RenderNode
+android.view.RenderNode$NoImagePreloadHolder
android.view.RenderNodeAnimator
android.view.RenderNodeAnimator$1
+android.view.RenderNodeAnimatorSetHelper
android.view.SearchEvent
android.view.SoundEffectConstants
android.view.SubMenu
@@ -2143,9 +2109,8 @@
android.view.SurfaceSession
android.view.SurfaceView
android.view.TextureView
-android.view.TextureView$SurfaceTextureListener
android.view.ThreadedRenderer
-android.view.ThreadedRenderer$HardwareDrawCallbacks
+android.view.ThreadedRenderer$DrawCallbacks
android.view.ThreadedRenderer$ProcessInitializer
android.view.VelocityTracker
android.view.VelocityTracker$Estimator
@@ -2182,6 +2147,7 @@
android.view.View$OnTouchListener
android.view.View$PerformClick
android.view.View$ScrollabilityCache
+android.view.View$TooltipInfo
android.view.View$TransformationInfo
android.view.View$UnsetPressedState
android.view.ViewConfiguration
@@ -2193,11 +2159,13 @@
android.view.ViewGroup$MarginLayoutParams
android.view.ViewGroup$OnHierarchyChangeListener
android.view.ViewGroup$TouchTarget
+android.view.ViewGroupOverlay
android.view.ViewManager
android.view.ViewOutlineProvider
android.view.ViewOutlineProvider$1
android.view.ViewOutlineProvider$2
android.view.ViewOutlineProvider$3
+android.view.ViewOverlay
android.view.ViewParent
android.view.ViewPropertyAnimator
android.view.ViewPropertyAnimator$1
@@ -2245,6 +2213,7 @@
android.view.Window
android.view.Window$Callback
android.view.Window$OnWindowDismissedCallback
+android.view.Window$OnWindowSwipeDismissedCallback
android.view.Window$WindowControllerCallback
android.view.WindowAnimationFrameStats
android.view.WindowAnimationFrameStats$1
@@ -2254,7 +2223,6 @@
android.view.WindowInsets
android.view.WindowLeaked
android.view.WindowManager
-android.view.WindowManager$BadTokenException
android.view.WindowManager$LayoutParams
android.view.WindowManager$LayoutParams$1
android.view.WindowManagerGlobal
@@ -2272,9 +2240,6 @@
android.view.accessibility.AccessibilityNodeProvider
android.view.accessibility.AccessibilityRecord
android.view.accessibility.CaptioningManager
-android.view.accessibility.CaptioningManager$1
-android.view.accessibility.CaptioningManager$CaptioningChangeListener
-android.view.accessibility.CaptioningManager$MyContentObserver
android.view.accessibility.IAccessibilityManager
android.view.accessibility.IAccessibilityManager$Stub
android.view.accessibility.IAccessibilityManager$Stub$Proxy
@@ -2291,24 +2256,23 @@
android.view.animation.Animation$NoImagePreloadHolder
android.view.animation.AnimationSet
android.view.animation.AnimationUtils
+android.view.animation.AnimationUtils$1
+android.view.animation.AnimationUtils$AnimationState
android.view.animation.BaseInterpolator
android.view.animation.DecelerateInterpolator
android.view.animation.Interpolator
android.view.animation.LinearInterpolator
-android.view.animation.OvershootInterpolator
android.view.animation.PathInterpolator
android.view.animation.ScaleAnimation
android.view.animation.Transformation
android.view.animation.TranslateAnimation
+android.view.autofill.AutoFillManager
android.view.inputmethod.BaseInputConnection
android.view.inputmethod.ComposingText
android.view.inputmethod.CursorAnchorInfo$Builder
android.view.inputmethod.EditorInfo
android.view.inputmethod.EditorInfo$1
-android.view.inputmethod.ExtractedText
-android.view.inputmethod.ExtractedText$1
android.view.inputmethod.InputConnection
-android.view.inputmethod.InputConnectionInspector
android.view.inputmethod.InputMethodManager
android.view.inputmethod.InputMethodManager$1
android.view.inputmethod.InputMethodManager$ControlledInputConnectionWrapper
@@ -2316,6 +2280,7 @@
android.view.inputmethod.InputMethodManager$H
android.view.inputmethod.InputMethodManager$ImeInputEventSender
android.view.inputmethod.InputMethodManager$PendingEvent
+android.view.textclassifier.TextClassificationManager
android.view.textservice.SpellCheckerSubtype
android.view.textservice.SpellCheckerSubtype$1
android.view.textservice.TextServicesManager
@@ -2323,7 +2288,6 @@
android.webkit.IWebViewUpdateService$Stub
android.webkit.IWebViewUpdateService$Stub$Proxy
android.webkit.MimeTypeMap
-android.webkit.WebSettings
android.webkit.WebView
android.webkit.WebViewFactory
android.webkit.WebViewFactory$MissingWebViewPackageException
@@ -2339,14 +2303,6 @@
android.widget.AbsSeekBar
android.widget.AbsSpinner
android.widget.AbsoluteLayout
-android.widget.ActionMenuPresenter
-android.widget.ActionMenuPresenter$1
-android.widget.ActionMenuPresenter$2
-android.widget.ActionMenuPresenter$OverflowMenuButton
-android.widget.ActionMenuPresenter$OverflowMenuButton$1
-android.widget.ActionMenuPresenter$PopupPresenterCallback
-android.widget.ActionMenuView
-android.widget.ActionMenuView$ActionMenuChildView
android.widget.ActionMenuView$OnMenuItemClickListener
android.widget.Adapter
android.widget.AdapterView
@@ -2367,24 +2323,16 @@
android.widget.Editor
android.widget.Editor$1
android.widget.Editor$2
-android.widget.Editor$Blink
android.widget.Editor$CursorAnchorInfoNotifier
-android.widget.Editor$CursorController
-android.widget.Editor$EditOperation
-android.widget.Editor$EditOperation$1
android.widget.Editor$InputContentType
-android.widget.Editor$InputMethodState
-android.widget.Editor$InsertionPointCursorController
android.widget.Editor$PositionListener
android.widget.Editor$ProcessTextIntentActionsHandler
-android.widget.Editor$SelectionModifierCursorController
android.widget.Editor$SpanController
android.widget.Editor$SuggestionHelper
android.widget.Editor$SuggestionHelper$SuggestionSpanComparator
android.widget.Editor$TextRenderNode
android.widget.Editor$TextViewPositionListener
android.widget.Editor$UndoInputFilter
-android.widget.Filter
android.widget.Filter$FilterListener
android.widget.Filterable
android.widget.ForwardingListener
@@ -2392,8 +2340,6 @@
android.widget.FrameLayout$LayoutParams
android.widget.HeaderViewListAdapter
android.widget.HorizontalScrollView
-android.widget.HorizontalScrollView$SavedState
-android.widget.HorizontalScrollView$SavedState$1
android.widget.ImageButton
android.widget.ImageView
android.widget.ImageView$ScaleType
@@ -2402,12 +2348,12 @@
android.widget.ListAdapter
android.widget.ListPopupWindow
android.widget.ListPopupWindow$ListSelectorHider
+android.widget.ListPopupWindow$PopupDataSetObserver
android.widget.ListPopupWindow$PopupScrollListener
android.widget.ListPopupWindow$PopupTouchInterceptor
android.widget.ListPopupWindow$ResizePopupRunnable
android.widget.ListView
android.widget.ListView$ArrowScrollFocusResult
-android.widget.ListView$FixedViewInfo
android.widget.MultiAutoCompleteTextView
android.widget.OverScroller
android.widget.OverScroller$SplineOverScroller
@@ -2415,8 +2361,6 @@
android.widget.PopupWindow$1
android.widget.PopupWindow$2
android.widget.PopupWindow$OnDismissListener
-android.widget.PopupWindow$PopupDecorView
-android.widget.PopupWindow$PopupDecorView$1
android.widget.ProgressBar
android.widget.ProgressBar$1
android.widget.ProgressBar$SavedState
@@ -2428,30 +2372,17 @@
android.widget.RelativeLayout$DependencyGraph$Node
android.widget.RelativeLayout$LayoutParams
android.widget.RemoteViews
-android.widget.RemoteViews$1
-android.widget.RemoteViews$2
-android.widget.RemoteViews$3
-android.widget.RemoteViews$Action
-android.widget.RemoteViews$ActionException
-android.widget.RemoteViews$BitmapCache
-android.widget.RemoteViews$MemoryUsageCounter
-android.widget.RemoteViews$MutablePair
-android.widget.RemoteViews$OnClickHandler
-android.widget.RemoteViews$ReflectionAction
-android.widget.RemoteViews$RuntimeAction
-android.widget.RemoteViews$SetOnClickPendingIntent
+android.widget.RemoteViews$RemoteView
android.widget.RemoteViewsAdapter$RemoteAdapterConnectionCallback
android.widget.RtlSpacingHelper
android.widget.ScrollBarDrawable
android.widget.ScrollView
android.widget.Scroller
android.widget.Scroller$ViscousFluidInterpolator
-android.widget.SectionIndexer
android.widget.SeekBar
android.widget.Space
android.widget.Spinner
android.widget.SpinnerAdapter
-android.widget.Switch
android.widget.TextView
android.widget.TextView$BufferType
android.widget.TextView$ChangeWatcher
@@ -2465,7 +2396,6 @@
android.widget.Toolbar
android.widget.Toolbar$1
android.widget.Toolbar$2
-android.widget.Toolbar$ExpandedActionViewMenuPresenter
android.widget.Toolbar$LayoutParams
android.widget.WrapperListAdapter
com.android.dex.ClassData
@@ -2497,9 +2427,6 @@
com.android.i18n.phonenumbers.NumberParseException
com.android.i18n.phonenumbers.PhoneNumberUtil
com.android.internal.R$styleable
-com.android.internal.app.AlertController
-com.android.internal.app.AlertController$1
-com.android.internal.app.AlertController$ButtonHandler
com.android.internal.app.IAppOpsCallback
com.android.internal.app.IAppOpsCallback$Stub
com.android.internal.app.IAppOpsService
@@ -2507,42 +2434,47 @@
com.android.internal.app.IAppOpsService$Stub$Proxy
com.android.internal.app.IBatteryStats
com.android.internal.app.IBatteryStats$Stub
+com.android.internal.app.IBatteryStats$Stub$Proxy
com.android.internal.app.IVoiceInteractor
com.android.internal.app.IVoiceInteractor$Stub
-com.android.internal.appwidget.IAppWidgetService
-com.android.internal.appwidget.IAppWidgetService$Stub
-com.android.internal.appwidget.IAppWidgetService$Stub$Proxy
com.android.internal.content.NativeLibraryHelper
com.android.internal.content.ReferrerIntent
com.android.internal.content.ReferrerIntent$1
+com.android.internal.graphics.drawable.AnimationScaleListDrawable
+com.android.internal.graphics.drawable.AnimationScaleListDrawable$AnimationScaleListState
com.android.internal.inputmethod.InputMethodUtils
com.android.internal.inputmethod.InputMethodUtils$1
com.android.internal.inputmethod.LocaleUtils$LocaleExtractor
com.android.internal.logging.AndroidConfig
com.android.internal.logging.AndroidHandler
com.android.internal.logging.AndroidHandler$1
+com.android.internal.logging.EventLogTags
+com.android.internal.logging.MetricsLogger
com.android.internal.net.NetworkStatsFactory
com.android.internal.os.AndroidPrintStream
com.android.internal.os.BinderInternal
com.android.internal.os.BinderInternal$GcWatcher
-com.android.internal.os.InstallerConnection$InstallerException
+com.android.internal.os.FuseAppLoop
+com.android.internal.os.FuseAppLoop$1
+com.android.internal.os.FuseAppLoop$UnmountedException
com.android.internal.os.LoggingPrintStream
com.android.internal.os.LoggingPrintStream$1
com.android.internal.os.PathClassLoaderFactory
+com.android.internal.os.RoSystemProperties
com.android.internal.os.RuntimeInit
com.android.internal.os.RuntimeInit$1
com.android.internal.os.RuntimeInit$Arguments
com.android.internal.os.RuntimeInit$KillApplicationHandler
com.android.internal.os.RuntimeInit$LoggingHandler
-com.android.internal.os.RoSystemProperties
com.android.internal.os.SamplingProfilerIntegration
com.android.internal.os.SomeArgs
com.android.internal.os.Zygote
+com.android.internal.os.Zygote$MethodAndArgsCaller
com.android.internal.os.ZygoteConnection
com.android.internal.os.ZygoteConnection$Arguments
com.android.internal.os.ZygoteInit
-com.android.internal.os.ZygoteInit$MethodAndArgsCaller
com.android.internal.os.ZygoteSecurityException
+com.android.internal.os.ZygoteServer
com.android.internal.policy.DecorContext
com.android.internal.policy.DecorView
com.android.internal.policy.DecorView$ColorViewState
@@ -2554,8 +2486,6 @@
com.android.internal.policy.PhoneWindow$PhoneWindowMenuCallback
com.android.internal.policy.PhoneWindow$RotationWatcher
com.android.internal.policy.PhoneWindow$RotationWatcher$1
-com.android.internal.telephony.IPhoneStateListener
-com.android.internal.telephony.IPhoneStateListener$Stub
com.android.internal.telephony.ISub
com.android.internal.telephony.ISub$Stub
com.android.internal.telephony.ISub$Stub$Proxy
@@ -2569,6 +2499,8 @@
com.android.internal.textservice.ITextServicesManager
com.android.internal.textservice.ITextServicesManager$Stub
com.android.internal.textservice.ITextServicesManager$Stub$Proxy
+com.android.internal.transition.EpicenterTranslateClipReveal
+com.android.internal.transition.TransitionConstants
com.android.internal.util.ArrayUtils
com.android.internal.util.FastPrintWriter
com.android.internal.util.FastPrintWriter$DummyWriter
@@ -2579,15 +2511,10 @@
com.android.internal.util.VirtualRefBasePtr
com.android.internal.util.XmlUtils
com.android.internal.util.XmlUtils$WriteMapCallback
-com.android.internal.view.ActionBarPolicy
com.android.internal.view.IInputConnectionWrapper
com.android.internal.view.IInputConnectionWrapper$MyHandler
-com.android.internal.view.IInputConnectionWrapper$SomeArgs
com.android.internal.view.IInputContext
com.android.internal.view.IInputContext$Stub
-com.android.internal.view.IInputContextCallback
-com.android.internal.view.IInputContextCallback$Stub
-com.android.internal.view.IInputContextCallback$Stub$Proxy
com.android.internal.view.IInputMethodClient
com.android.internal.view.IInputMethodClient$Stub
com.android.internal.view.IInputMethodManager
@@ -2603,23 +2530,13 @@
com.android.internal.view.animation.HasNativeInterpolator
com.android.internal.view.animation.NativeInterpolatorFactory
com.android.internal.view.animation.NativeInterpolatorFactoryHelper
-com.android.internal.view.menu.ActionMenuItem
-com.android.internal.view.menu.BaseMenuPresenter
com.android.internal.view.menu.MenuBuilder
com.android.internal.view.menu.MenuBuilder$Callback
-com.android.internal.view.menu.MenuBuilder$ItemInvoker
com.android.internal.view.menu.MenuItemImpl
-com.android.internal.view.menu.MenuPresenter
com.android.internal.view.menu.MenuPresenter$Callback
-com.android.internal.view.menu.MenuView
com.android.internal.view.menu.ShowableListMenu
com.android.internal.widget.BackgroundFallback
com.android.internal.widget.DecorContentParent
-com.android.internal.widget.DecorToolbar
-com.android.internal.widget.EditableInputConnection
-com.android.internal.widget.ScrollBarUtils
-com.android.internal.widget.ToolbarWidgetWrapper
-com.android.internal.widget.ToolbarWidgetWrapper$1
com.android.okhttp.Address
com.android.okhttp.Authenticator
com.android.okhttp.CacheControl
@@ -2635,6 +2552,8 @@
com.android.okhttp.ConnectionSpec
com.android.okhttp.ConnectionSpec$Builder
com.android.okhttp.Dispatcher
+com.android.okhttp.Dns
+com.android.okhttp.Dns$1
com.android.okhttp.Handshake
com.android.okhttp.Headers
com.android.okhttp.Headers$Builder
@@ -2659,8 +2578,6 @@
com.android.okhttp.TlsVersion
com.android.okhttp.internal.ConnectionSpecSelector
com.android.okhttp.internal.Internal
-com.android.okhttp.internal.Network
-com.android.okhttp.internal.Network$1
com.android.okhttp.internal.OptionalMethod
com.android.okhttp.internal.Platform
com.android.okhttp.internal.RouteDatabase
@@ -2670,14 +2587,14 @@
com.android.okhttp.internal.http.AuthenticatorAdapter
com.android.okhttp.internal.http.CacheStrategy
com.android.okhttp.internal.http.CacheStrategy$Factory
-com.android.okhttp.internal.http.HttpConnection
-com.android.okhttp.internal.http.HttpConnection$AbstractSource
-com.android.okhttp.internal.http.HttpConnection$ChunkedSource
-com.android.okhttp.internal.http.HttpConnection$FixedLengthSource
+com.android.okhttp.internal.http.Http1xStream
+com.android.okhttp.internal.http.Http1xStream$AbstractSource
+com.android.okhttp.internal.http.Http1xStream$ChunkedSource
+com.android.okhttp.internal.http.Http1xStream$FixedLengthSource
com.android.okhttp.internal.http.HttpEngine
com.android.okhttp.internal.http.HttpEngine$1
com.android.okhttp.internal.http.HttpMethod
-com.android.okhttp.internal.http.HttpTransport
+com.android.okhttp.internal.http.HttpStream
com.android.okhttp.internal.http.OkHeaders
com.android.okhttp.internal.http.OkHeaders$1
com.android.okhttp.internal.http.RealResponseBody
@@ -2687,10 +2604,11 @@
com.android.okhttp.internal.http.RouteException
com.android.okhttp.internal.http.RouteSelector
com.android.okhttp.internal.http.StatusLine
-com.android.okhttp.internal.http.Transport
+com.android.okhttp.internal.http.StreamAllocation
com.android.okhttp.internal.huc.DelegatingHttpsURLConnection
com.android.okhttp.internal.huc.HttpURLConnectionImpl
com.android.okhttp.internal.huc.HttpsURLConnectionImpl
+com.android.okhttp.internal.io.RealConnection
com.android.okhttp.internal.tls.OkHostnameVerifier
com.android.okhttp.okio.AsyncTimeout
com.android.okhttp.okio.AsyncTimeout$1
@@ -2771,8 +2689,12 @@
com.android.org.bouncycastle.jcajce.provider.symmetric.DES$Mappings
com.android.org.bouncycastle.jcajce.provider.symmetric.DESede
com.android.org.bouncycastle.jcajce.provider.symmetric.DESede$Mappings
+com.android.org.bouncycastle.jcajce.provider.symmetric.PBEPBKDF2
+com.android.org.bouncycastle.jcajce.provider.symmetric.PBEPBKDF2$Mappings
com.android.org.bouncycastle.jcajce.provider.symmetric.PBEPKCS12
com.android.org.bouncycastle.jcajce.provider.symmetric.PBEPKCS12$Mappings
+com.android.org.bouncycastle.jcajce.provider.symmetric.PBES2AlgorithmParameters
+com.android.org.bouncycastle.jcajce.provider.symmetric.PBES2AlgorithmParameters$Mappings
com.android.org.bouncycastle.jcajce.provider.symmetric.RC2
com.android.org.bouncycastle.jcajce.provider.symmetric.RC2$Mappings
com.android.org.bouncycastle.jcajce.provider.symmetric.SymmetricAlgorithmProvider
@@ -2792,18 +2714,20 @@
com.android.org.bouncycastle.util.Encodable
com.android.org.bouncycastle.util.Strings
com.android.org.bouncycastle.util.Strings$1
+com.android.org.conscrypt.AbstractOpenSSLSession
com.android.org.conscrypt.AbstractSessionContext
com.android.org.conscrypt.AbstractSessionContext$1
com.android.org.conscrypt.AddressUtils
com.android.org.conscrypt.ByteArray
-com.android.org.conscrypt.CertPinManager
+com.android.org.conscrypt.CertBlacklist
com.android.org.conscrypt.CertificatePriorityComparator
com.android.org.conscrypt.ChainStrengthAnalyzer
com.android.org.conscrypt.ClientSessionContext
com.android.org.conscrypt.ClientSessionContext$HostAndPort
com.android.org.conscrypt.CryptoUpcalls
-com.android.org.conscrypt.FileClientSessionCache
-com.android.org.conscrypt.FileClientSessionCache$Impl
+com.android.org.conscrypt.EvpMdRef$MD5
+com.android.org.conscrypt.EvpMdRef$SHA1
+com.android.org.conscrypt.EvpMdRef$SHA256
com.android.org.conscrypt.Hex
com.android.org.conscrypt.JSSEProvider
com.android.org.conscrypt.KeyManagerFactoryImpl
@@ -2817,10 +2741,7 @@
com.android.org.conscrypt.NativeRef$EVP_MD_CTX
com.android.org.conscrypt.NativeRef$EVP_PKEY
com.android.org.conscrypt.OpenSSLBIOInputStream
-com.android.org.conscrypt.OpenSSLContextImpl
-com.android.org.conscrypt.OpenSSLContextImpl$TLSv12
com.android.org.conscrypt.OpenSSLECGroupContext
-com.android.org.conscrypt.OpenSSLECKeyFactory
com.android.org.conscrypt.OpenSSLECPointContext
com.android.org.conscrypt.OpenSSLECPublicKey
com.android.org.conscrypt.OpenSSLExtendedSessionImpl
@@ -2829,6 +2750,7 @@
com.android.org.conscrypt.OpenSSLMessageDigestJDK
com.android.org.conscrypt.OpenSSLMessageDigestJDK$MD5
com.android.org.conscrypt.OpenSSLMessageDigestJDK$SHA1
+com.android.org.conscrypt.OpenSSLMessageDigestJDK$SHA256
com.android.org.conscrypt.OpenSSLProvider
com.android.org.conscrypt.OpenSSLRSAKeyFactory
com.android.org.conscrypt.OpenSSLRSAPublicKey
@@ -2847,11 +2769,7 @@
com.android.org.conscrypt.OpenSSLX509CertificateFactory$2
com.android.org.conscrypt.OpenSSLX509CertificateFactory$Parser
com.android.org.conscrypt.OpenSSLX509CertificateFactory$ParsingException
-com.android.org.conscrypt.PinEntryException
-com.android.org.conscrypt.PinListEntry
-com.android.org.conscrypt.PinManagerException
com.android.org.conscrypt.Platform
-com.android.org.conscrypt.SSLClientSessionCache
com.android.org.conscrypt.SSLParametersImpl
com.android.org.conscrypt.SSLParametersImpl$AliasChooser
com.android.org.conscrypt.SSLParametersImpl$PSKCallbacks
@@ -2863,6 +2781,17 @@
com.android.org.conscrypt.TrustedCertificateIndex
com.android.org.conscrypt.TrustedCertificateKeyStoreSpi
com.android.org.conscrypt.TrustedCertificateStore
+com.android.org.conscrypt.TrustedCertificateStore$1
+com.android.org.conscrypt.TrustedCertificateStore$CertSelector
+com.android.org.conscrypt.ct.CTLogInfo
+com.android.org.conscrypt.ct.CTLogStore
+com.android.org.conscrypt.ct.CTLogStoreImpl
+com.android.org.conscrypt.ct.CTLogStoreImpl$InvalidLogFileException
+com.android.org.conscrypt.ct.CTPolicy
+com.android.org.conscrypt.ct.CTPolicyImpl
+com.android.org.conscrypt.ct.CTVerifier
+com.android.org.conscrypt.ct.KnownLogs
+com.android.org.conscrypt.ct.SerializationException
com.android.org.conscrypt.util.ArrayUtils
com.android.server.NetworkManagementSocketTagger
com.android.server.NetworkManagementSocketTagger$1
@@ -2871,20 +2800,31 @@
com.google.android.collect.Maps
com.google.android.gles_jni.EGLImpl
com.google.android.gles_jni.GLImpl
+dalvik.annotation.optimization.CriticalNative
+dalvik.annotation.optimization.FastNative
dalvik.system.BaseDexClassLoader
+dalvik.system.BaseDexClassLoader$Reporter
dalvik.system.BlockGuard
dalvik.system.BlockGuard$1
dalvik.system.BlockGuard$2
dalvik.system.BlockGuard$BlockGuardPolicyException
dalvik.system.BlockGuard$Policy
+dalvik.system.ClassExt
dalvik.system.CloseGuard
dalvik.system.CloseGuard$DefaultReporter
+dalvik.system.CloseGuard$DefaultTracker
dalvik.system.CloseGuard$Reporter
+dalvik.system.CloseGuard$Tracker
dalvik.system.DalvikLogHandler
+dalvik.system.DexClassLoader
dalvik.system.DexFile
dalvik.system.DexFile$DFEnum
dalvik.system.DexPathList
dalvik.system.DexPathList$Element
+dalvik.system.DexPathList$NativeLibraryElement
+dalvik.system.EmulatedStackFrame
+dalvik.system.EmulatedStackFrame$Range
+dalvik.system.InMemoryDexClassLoader$DexData
dalvik.system.PathClassLoader
dalvik.system.SocketTagger
dalvik.system.SocketTagger$1
@@ -2892,11 +2832,6 @@
dalvik.system.VMRuntime
dalvik.system.VMStack
dalvik.system.ZygoteHooks
-java.beans.ChangeListenerMap
-java.beans.PropertyChangeEvent
-java.beans.PropertyChangeListener
-java.beans.PropertyChangeSupport
-java.beans.PropertyChangeSupport$PropertyChangeListenerMap
java.io.Bits
java.io.BufferedInputStream
java.io.BufferedOutputStream
@@ -2911,6 +2846,7 @@
java.io.DataInputStream
java.io.DataOutput
java.io.DataOutputStream
+java.io.DefaultFileSystem
java.io.EOFException
java.io.ExpiringCache
java.io.ExpiringCache$1
@@ -2919,6 +2855,7 @@
java.io.File
java.io.File$PathStatus
java.io.FileDescriptor
+java.io.FileDescriptor$1
java.io.FileFilter
java.io.FileInputStream
java.io.FileInputStream$UseManualSkipException
@@ -2930,18 +2867,33 @@
java.io.FilenameFilter
java.io.FilterInputStream
java.io.FilterOutputStream
-java.io.FilterReader
java.io.Flushable
java.io.IOException
java.io.InputStream
java.io.InputStreamReader
java.io.InterruptedIOException
+java.io.InvalidClassException
java.io.InvalidObjectException
java.io.ObjectInput
java.io.ObjectInputStream
+java.io.ObjectInputStream$BlockDataInputStream
+java.io.ObjectInputStream$HandleTable
+java.io.ObjectInputStream$HandleTable$HandleList
+java.io.ObjectInputStream$PeekInputStream
+java.io.ObjectInputStream$ValidationList
java.io.ObjectOutput
java.io.ObjectOutputStream
+java.io.ObjectOutputStream$BlockDataOutputStream
+java.io.ObjectOutputStream$HandleTable
+java.io.ObjectOutputStream$PutField
+java.io.ObjectOutputStream$ReplaceTable
java.io.ObjectStreamClass
+java.io.ObjectStreamClass$2
+java.io.ObjectStreamClass$Caches
+java.io.ObjectStreamClass$EntryFuture
+java.io.ObjectStreamClass$FieldReflector
+java.io.ObjectStreamClass$FieldReflectorKey
+java.io.ObjectStreamClass$WeakClassKey
java.io.ObjectStreamConstants
java.io.ObjectStreamException
java.io.ObjectStreamField
@@ -2950,7 +2902,6 @@
java.io.PrintStream
java.io.PrintWriter
java.io.PushbackInputStream
-java.io.PushbackReader
java.io.RandomAccessFile
java.io.Reader
java.io.SequenceInputStream
@@ -2962,10 +2913,13 @@
java.io.UnixFileSystem
java.io.UnsupportedEncodingException
java.io.Writer
+java.lang.-$Lambda$250$S9HjrJh0nDg7IyU6wZdPArnZWRQ
+java.lang.-$Lambda$251$S9HjrJh0nDg7IyU6wZdPArnZWRQ
java.lang.AbstractMethodError
java.lang.AbstractStringBuilder
java.lang.AndroidHardcodedSystemProperties
java.lang.Appendable
+java.lang.ArithmeticException
java.lang.ArrayIndexOutOfBoundsException
java.lang.ArrayStoreException
java.lang.AssertionError
@@ -2977,8 +2931,6 @@
java.lang.CaseMapper
java.lang.CaseMapper$1
java.lang.CharSequence
-java.lang.CharSequence$-java_util_stream_IntStream_chars__LambdaImpl0
-java.lang.CharSequence$-java_util_stream_IntStream_codePoints__LambdaImpl0
java.lang.CharSequence$1CharIterator
java.lang.CharSequence$1CodePointIterator
java.lang.Character
@@ -3008,9 +2960,7 @@
java.lang.Error
java.lang.Exception
java.lang.Float
-java.lang.FloatingDecimal
-java.lang.FloatingDecimal$1
-java.lang.FloatingDecimal$2
+java.lang.IllegalAccessError
java.lang.IllegalAccessException
java.lang.IllegalArgumentException
java.lang.IllegalStateException
@@ -3029,7 +2979,7 @@
java.lang.Long
java.lang.Long$LongCache
java.lang.Math
-java.lang.Math$NoImagePreloadHolder
+java.lang.Math$RandomNumberGeneratorHolder
java.lang.NoClassDefFoundError
java.lang.NoSuchFieldError
java.lang.NoSuchFieldException
@@ -3042,6 +2992,7 @@
java.lang.OutOfMemoryError
java.lang.Package
java.lang.Process
+java.lang.ProcessBuilder
java.lang.ProcessEnvironment
java.lang.Readable
java.lang.ReflectiveOperationException
@@ -3053,7 +3004,6 @@
java.lang.SecurityManager
java.lang.Short
java.lang.Short$ShortCache
-java.lang.Shutdown
java.lang.StackOverflowError
java.lang.StackTraceElement
java.lang.StrictMath
@@ -3061,7 +3011,6 @@
java.lang.String$CaseInsensitiveComparator
java.lang.StringBuffer
java.lang.StringBuilder
-java.lang.StringCoding
java.lang.StringFactory
java.lang.StringIndexOutOfBoundsException
java.lang.System
@@ -3095,6 +3044,22 @@
java.lang.annotation.Inherited
java.lang.annotation.Retention
java.lang.annotation.Target
+java.lang.invoke.MethodHandle
+java.lang.invoke.MethodHandleImpl
+java.lang.invoke.MethodHandleImpl$HandleInfo
+java.lang.invoke.MethodHandleInfo
+java.lang.invoke.MethodHandleStatics
+java.lang.invoke.MethodHandles
+java.lang.invoke.MethodType
+java.lang.invoke.MethodType$ConcurrentWeakInternSet
+java.lang.invoke.MethodType$ConcurrentWeakInternSet$WeakEntry
+java.lang.invoke.MethodTypeForm
+java.lang.invoke.Transformers$BindTo
+java.lang.invoke.Transformers$Collector
+java.lang.invoke.Transformers$Spreader
+java.lang.invoke.Transformers$Transformer
+java.lang.invoke.Transformers$VarargsCollector
+java.lang.invoke.WrongMethodTypeException
java.lang.ref.FinalizerReference
java.lang.ref.FinalizerReference$Sentinel
java.lang.ref.PhantomReference
@@ -3102,47 +3067,54 @@
java.lang.ref.ReferenceQueue
java.lang.ref.SoftReference
java.lang.ref.WeakReference
-java.lang.reflect.AbstractMethod
-java.lang.reflect.AbstractMethod$GenericInfo
java.lang.reflect.AccessibleObject
java.lang.reflect.AnnotatedElement
java.lang.reflect.Array
java.lang.reflect.Constructor
+java.lang.reflect.Executable
+java.lang.reflect.Executable$GenericInfo
java.lang.reflect.Field
-java.lang.reflect.GenericArrayType
java.lang.reflect.GenericDeclaration
java.lang.reflect.InvocationHandler
java.lang.reflect.InvocationTargetException
+java.lang.reflect.MalformedParametersException
java.lang.reflect.Member
java.lang.reflect.Method
java.lang.reflect.Method$1
java.lang.reflect.Modifier
+java.lang.reflect.Parameter
java.lang.reflect.ParameterizedType
java.lang.reflect.Proxy
java.lang.reflect.Proxy$1
+java.lang.reflect.Proxy$Key1
+java.lang.reflect.Proxy$Key2
+java.lang.reflect.Proxy$KeyFactory
+java.lang.reflect.Proxy$KeyX
+java.lang.reflect.Proxy$ProxyClassFactory
java.lang.reflect.Type
java.lang.reflect.TypeVariable
-java.lang.reflect.WildcardType
+java.lang.reflect.WeakCache
+java.lang.reflect.WeakCache$CacheKey
+java.lang.reflect.WeakCache$CacheValue
+java.lang.reflect.WeakCache$Factory
+java.lang.reflect.WeakCache$LookupValue
+java.lang.reflect.WeakCache$Value
java.math.BigDecimal
java.math.BigInt
java.math.BigInteger
-java.math.BitLevel
java.math.NativeBN
java.math.RoundingMode
-java.net.AbstractPlainDatagramSocketImpl
java.net.AbstractPlainSocketImpl
java.net.AddressCache
java.net.AddressCache$AddressCacheEntry
java.net.AddressCache$AddressCacheKey
java.net.ConnectException
java.net.CookieHandler
-java.net.DatagramPacket
-java.net.DatagramSocketImpl
-java.net.DefaultInterface
java.net.HttpURLConnection
java.net.IDN
java.net.Inet4Address
java.net.Inet6Address
+java.net.Inet6Address$Inet6AddressHolder
java.net.Inet6AddressImpl
java.net.InetAddress
java.net.InetAddress$1
@@ -3150,12 +3122,10 @@
java.net.InetAddressImpl
java.net.InetSocketAddress
java.net.InetSocketAddress$InetSocketAddressHolder
-java.net.InterfaceAddress
java.net.JarURLConnection
java.net.MalformedURLException
java.net.NetworkInterface
java.net.Parts
-java.net.PlainDatagramSocketImpl
java.net.PlainSocketImpl
java.net.ProtocolException
java.net.Proxy
@@ -3164,6 +3134,8 @@
java.net.ResponseCache
java.net.ServerSocket
java.net.Socket
+java.net.Socket$2
+java.net.Socket$3
java.net.SocketAddress
java.net.SocketException
java.net.SocketImpl
@@ -3173,7 +3145,6 @@
java.net.SocketTimeoutException
java.net.SocksConsts
java.net.SocksSocketImpl
-java.net.SocksSocketImpl$3
java.net.URI
java.net.URI$Parser
java.net.URISyntaxException
@@ -3222,6 +3193,7 @@
java.nio.channels.FileLock
java.nio.channels.GatheringByteChannel
java.nio.channels.InterruptibleChannel
+java.nio.channels.MulticastChannel
java.nio.channels.NetworkChannel
java.nio.channels.ReadableByteChannel
java.nio.channels.ScatteringByteChannel
@@ -3248,6 +3220,7 @@
java.nio.charset.IllegalCharsetNameException
java.nio.charset.StandardCharsets
java.nio.charset.UnsupportedCharsetException
+java.nio.file.attribute.FileAttribute
java.security.AccessControlContext
java.security.AccessControlException
java.security.AccessController
@@ -3338,7 +3311,6 @@
java.security.interfaces.RSAPublicKey
java.security.spec.AlgorithmParameterSpec
java.security.spec.ECField
-java.security.spec.ECFieldF2m
java.security.spec.ECFieldFp
java.security.spec.ECParameterSpec
java.security.spec.ECPoint
@@ -3346,15 +3318,12 @@
java.security.spec.EllipticCurve
java.security.spec.EncodedKeySpec
java.security.spec.InvalidKeySpecException
-java.security.spec.InvalidParameterSpecException
java.security.spec.KeySpec
java.security.spec.RSAPublicKeySpec
java.security.spec.X509EncodedKeySpec
-java.sql.Timestamp
java.text.AttributedCharacterIterator$Attribute
java.text.CalendarBuilder
java.text.CharacterIterator
-java.text.Collator
java.text.DateFormat
java.text.DateFormat$Field
java.text.DateFormatSymbols
@@ -3371,13 +3340,19 @@
java.text.NumberFormat
java.text.ParseException
java.text.ParsePosition
-java.text.RuleBasedCollator
java.text.SimpleDateFormat
java.text.StringCharacterIterator
-java.text.spi.DateFormatProvider
-java.text.spi.DateFormatSymbolsProvider
-java.text.spi.DecimalFormatSymbolsProvider
-java.text.spi.NumberFormatProvider
+java.time.DateTimeException
+java.util.-$Lambda$181$4EqhxufgNKat19m0CB0-toH_lzo
+java.util.-$Lambda$182$4EqhxufgNKat19m0CB0-toH_lzo
+java.util.-$Lambda$183$4EqhxufgNKat19m0CB0-toH_lzo
+java.util.-$Lambda$184$4EqhxufgNKat19m0CB0-toH_lzo
+java.util.-$Lambda$267$4EqhxufgNKat19m0CB0-toH_lzo
+java.util.-$Lambda$268$4EqhxufgNKat19m0CB0-toH_lzo
+java.util.-$Lambda$291$aUGKT4ItCOku5-JSG-x8Aqj2pJw
+java.util.-$Lambda$292$aUGKT4ItCOku5-JSG-x8Aqj2pJw
+java.util.-$Lambda$293$aUGKT4ItCOku5-JSG-x8Aqj2pJw
+java.util.-$Lambda$294$aUGKT4ItCOku5-JSG-x8Aqj2pJw
java.util.AbstractCollection
java.util.AbstractList
java.util.AbstractList$Itr
@@ -3397,8 +3372,21 @@
java.util.ArrayList$ListItr
java.util.ArrayList$SubList
java.util.ArrayList$SubList$1
+java.util.ArrayPrefixHelpers$CumulateTask
+java.util.ArrayPrefixHelpers$DoubleCumulateTask
+java.util.ArrayPrefixHelpers$IntCumulateTask
+java.util.ArrayPrefixHelpers$LongCumulateTask
java.util.Arrays
java.util.Arrays$ArrayList
+java.util.Arrays$NaturalOrder
+java.util.ArraysParallelSortHelpers$FJByte$Sorter
+java.util.ArraysParallelSortHelpers$FJChar$Sorter
+java.util.ArraysParallelSortHelpers$FJDouble$Sorter
+java.util.ArraysParallelSortHelpers$FJFloat$Sorter
+java.util.ArraysParallelSortHelpers$FJInt$Sorter
+java.util.ArraysParallelSortHelpers$FJLong$Sorter
+java.util.ArraysParallelSortHelpers$FJObject$Sorter
+java.util.ArraysParallelSortHelpers$FJShort$Sorter
java.util.BitSet
java.util.Calendar
java.util.Collection
@@ -3410,6 +3398,9 @@
java.util.Collections$CheckedCollection
java.util.Collections$CheckedList
java.util.Collections$CheckedMap
+java.util.Collections$CheckedNavigableMap
+java.util.Collections$CheckedNavigableSet
+java.util.Collections$CheckedQueue
java.util.Collections$CheckedRandomAccessList
java.util.Collections$CheckedSet
java.util.Collections$CheckedSortedMap
@@ -3430,6 +3421,8 @@
java.util.Collections$SynchronizedCollection
java.util.Collections$SynchronizedList
java.util.Collections$SynchronizedMap
+java.util.Collections$SynchronizedNavigableMap
+java.util.Collections$SynchronizedNavigableSet
java.util.Collections$SynchronizedRandomAccessList
java.util.Collections$SynchronizedSet
java.util.Collections$SynchronizedSortedMap
@@ -3442,18 +3435,16 @@
java.util.Collections$UnmodifiableMap$UnmodifiableEntrySet
java.util.Collections$UnmodifiableMap$UnmodifiableEntrySet$1
java.util.Collections$UnmodifiableMap$UnmodifiableEntrySet$UnmodifiableEntry
+java.util.Collections$UnmodifiableNavigableMap
+java.util.Collections$UnmodifiableNavigableMap$EmptyNavigableMap
+java.util.Collections$UnmodifiableNavigableSet
+java.util.Collections$UnmodifiableNavigableSet$EmptyNavigableSet
java.util.Collections$UnmodifiableRandomAccessList
java.util.Collections$UnmodifiableSet
java.util.Collections$UnmodifiableSortedMap
java.util.Collections$UnmodifiableSortedSet
java.util.ComparableTimSort
java.util.Comparator
-java.util.Comparator$-java_util_Comparator_comparingDouble_java_util_function_ToDoubleFunction_keyExtractor_LambdaImpl0
-java.util.Comparator$-java_util_Comparator_comparingInt_java_util_function_ToIntFunction_keyExtractor_LambdaImpl0
-java.util.Comparator$-java_util_Comparator_comparingLong_java_util_function_ToLongFunction_keyExtractor_LambdaImpl0
-java.util.Comparator$-java_util_Comparator_comparing_java_util_function_Function_keyExtractor_LambdaImpl0
-java.util.Comparator$-java_util_Comparator_comparing_java_util_function_Function_keyExtractor_java_util_Comparator_keyComparator_LambdaImpl0
-java.util.Comparator$-java_util_Comparator_thenComparing_java_util_Comparator_other_LambdaImpl0
java.util.Comparators$NaturalOrderComparator
java.util.Comparators$NullComparator
java.util.ConcurrentModificationException
@@ -3467,7 +3458,6 @@
java.util.EnumSet
java.util.Enumeration
java.util.EventListener
-java.util.EventObject
java.util.Formattable
java.util.Formatter
java.util.Formatter$Conversion
@@ -3481,14 +3471,14 @@
java.util.HashMap$EntryIterator
java.util.HashMap$EntrySet
java.util.HashMap$HashIterator
-java.util.HashMap$HashMapEntry
java.util.HashMap$KeyIterator
java.util.HashMap$KeySet
+java.util.HashMap$Node
+java.util.HashMap$TreeNode
java.util.HashMap$ValueIterator
java.util.HashMap$Values
java.util.HashSet
java.util.Hashtable
-java.util.Hashtable$EntrySet
java.util.Hashtable$Enumerator
java.util.Hashtable$HashtableEntry
java.util.IdentityHashMap
@@ -3498,11 +3488,14 @@
java.util.IllformedLocaleException
java.util.Iterator
java.util.LinkedHashMap
-java.util.LinkedHashMap$EntryIterator
-java.util.LinkedHashMap$KeyIterator
+java.util.LinkedHashMap$LinkedEntryIterator
+java.util.LinkedHashMap$LinkedEntrySet
java.util.LinkedHashMap$LinkedHashIterator
java.util.LinkedHashMap$LinkedHashMapEntry
-java.util.LinkedHashMap$ValueIterator
+java.util.LinkedHashMap$LinkedKeyIterator
+java.util.LinkedHashMap$LinkedKeySet
+java.util.LinkedHashMap$LinkedValueIterator
+java.util.LinkedHashMap$LinkedValues
java.util.LinkedHashSet
java.util.LinkedList
java.util.LinkedList$ListItr
@@ -3513,6 +3506,8 @@
java.util.Locale$Builder
java.util.Locale$Cache
java.util.Locale$Category
+java.util.Locale$FilteringMode
+java.util.Locale$LanguageRange
java.util.Locale$LocaleKey
java.util.Map
java.util.Map$Entry
@@ -3524,30 +3519,16 @@
java.util.PrimitiveIterator
java.util.PrimitiveIterator$OfInt
java.util.PriorityQueue
-java.util.PriorityQueue$Itr
java.util.Properties
java.util.Properties$LineReader
-java.util.PropertyResourceBundle
java.util.Queue
java.util.Random
java.util.RandomAccess
java.util.RandomAccessSubList
java.util.RegularEnumSet
-java.util.RegularEnumSet$EnumSetIterator
java.util.ResourceBundle
java.util.ResourceBundle$1
-java.util.ResourceBundle$BundleReference
-java.util.ResourceBundle$CacheKey
-java.util.ResourceBundle$CacheKeyReference
-java.util.ResourceBundle$Control
-java.util.ResourceBundle$Control$1
-java.util.ResourceBundle$Control$CandidateListCache
-java.util.ResourceBundle$LoaderReference
-java.util.ResourceBundle$RBClassLoader
-java.util.ResourceBundle$RBClassLoader$1
-java.util.ServiceLoader
-java.util.ServiceLoader$1
-java.util.ServiceLoader$LazyIterator
+java.util.Scanner
java.util.Set
java.util.SimpleTimeZone
java.util.SortedMap
@@ -3564,12 +3545,11 @@
java.util.Spliterators$EmptySpliterator$OfLong
java.util.Spliterators$EmptySpliterator$OfRef
java.util.Stack
+java.util.StringJoiner
java.util.StringTokenizer
java.util.SubList
java.util.TimSort
java.util.TimeZone
-java.util.Timer
-java.util.TimerTask
java.util.TreeMap
java.util.TreeMap$EntryIterator
java.util.TreeMap$EntrySet
@@ -3591,31 +3571,69 @@
java.util.WeakHashMap$KeyIterator
java.util.WeakHashMap$KeySet
java.util.WeakHashMap$Values
+java.util.concurrent.-$Lambda$269$xR9BLpu6SifNikvFgr4lEiECBsk
java.util.concurrent.AbstractExecutorService
java.util.concurrent.BlockingQueue
java.util.concurrent.Callable
java.util.concurrent.CancellationException
java.util.concurrent.ConcurrentHashMap
java.util.concurrent.ConcurrentHashMap$BaseIterator
+java.util.concurrent.ConcurrentHashMap$BulkTask
java.util.concurrent.ConcurrentHashMap$CollectionView
+java.util.concurrent.ConcurrentHashMap$CounterCell
java.util.concurrent.ConcurrentHashMap$EntryIterator
java.util.concurrent.ConcurrentHashMap$EntrySetView
+java.util.concurrent.ConcurrentHashMap$ForEachEntryTask
+java.util.concurrent.ConcurrentHashMap$ForEachKeyTask
+java.util.concurrent.ConcurrentHashMap$ForEachMappingTask
+java.util.concurrent.ConcurrentHashMap$ForEachTransformedEntryTask
+java.util.concurrent.ConcurrentHashMap$ForEachTransformedKeyTask
+java.util.concurrent.ConcurrentHashMap$ForEachTransformedMappingTask
+java.util.concurrent.ConcurrentHashMap$ForEachTransformedValueTask
+java.util.concurrent.ConcurrentHashMap$ForEachValueTask
java.util.concurrent.ConcurrentHashMap$ForwardingNode
java.util.concurrent.ConcurrentHashMap$KeyIterator
java.util.concurrent.ConcurrentHashMap$KeySetView
+java.util.concurrent.ConcurrentHashMap$MapReduceEntriesTask
+java.util.concurrent.ConcurrentHashMap$MapReduceEntriesToDoubleTask
+java.util.concurrent.ConcurrentHashMap$MapReduceEntriesToIntTask
+java.util.concurrent.ConcurrentHashMap$MapReduceEntriesToLongTask
+java.util.concurrent.ConcurrentHashMap$MapReduceKeysTask
+java.util.concurrent.ConcurrentHashMap$MapReduceKeysToDoubleTask
+java.util.concurrent.ConcurrentHashMap$MapReduceKeysToIntTask
+java.util.concurrent.ConcurrentHashMap$MapReduceKeysToLongTask
+java.util.concurrent.ConcurrentHashMap$MapReduceMappingsTask
+java.util.concurrent.ConcurrentHashMap$MapReduceMappingsToDoubleTask
+java.util.concurrent.ConcurrentHashMap$MapReduceMappingsToIntTask
+java.util.concurrent.ConcurrentHashMap$MapReduceMappingsToLongTask
+java.util.concurrent.ConcurrentHashMap$MapReduceValuesTask
+java.util.concurrent.ConcurrentHashMap$MapReduceValuesToDoubleTask
+java.util.concurrent.ConcurrentHashMap$MapReduceValuesToIntTask
+java.util.concurrent.ConcurrentHashMap$MapReduceValuesToLongTask
java.util.concurrent.ConcurrentHashMap$Node
+java.util.concurrent.ConcurrentHashMap$ReduceEntriesTask
+java.util.concurrent.ConcurrentHashMap$ReduceKeysTask
+java.util.concurrent.ConcurrentHashMap$ReduceValuesTask
+java.util.concurrent.ConcurrentHashMap$ReservationNode
+java.util.concurrent.ConcurrentHashMap$SearchEntriesTask
+java.util.concurrent.ConcurrentHashMap$SearchKeysTask
+java.util.concurrent.ConcurrentHashMap$SearchMappingsTask
+java.util.concurrent.ConcurrentHashMap$SearchValuesTask
java.util.concurrent.ConcurrentHashMap$Segment
java.util.concurrent.ConcurrentHashMap$Traverser
java.util.concurrent.ConcurrentHashMap$TreeBin
java.util.concurrent.ConcurrentHashMap$TreeNode
+java.util.concurrent.ConcurrentHashMap$ValueIterator
+java.util.concurrent.ConcurrentHashMap$ValuesView
java.util.concurrent.ConcurrentLinkedQueue
java.util.concurrent.ConcurrentLinkedQueue$Node
java.util.concurrent.ConcurrentMap
java.util.concurrent.CopyOnWriteArrayList
-java.util.concurrent.CopyOnWriteArrayList$CowIterator
+java.util.concurrent.CopyOnWriteArrayList$COWIterator
java.util.concurrent.CopyOnWriteArraySet
java.util.concurrent.CountDownLatch
java.util.concurrent.CountDownLatch$Sync
+java.util.concurrent.CountedCompleter
java.util.concurrent.Delayed
java.util.concurrent.ExecutionException
java.util.concurrent.Executor
@@ -3626,6 +3644,9 @@
java.util.concurrent.Executors$DelegatedScheduledExecutorService
java.util.concurrent.Executors$FinalizableDelegatedExecutorService
java.util.concurrent.Executors$RunnableAdapter
+java.util.concurrent.ForkJoinPool
+java.util.concurrent.ForkJoinTask
+java.util.concurrent.ForkJoinTask$ExceptionNode
java.util.concurrent.Future
java.util.concurrent.FutureTask
java.util.concurrent.FutureTask$WaitNode
@@ -3649,6 +3670,7 @@
java.util.concurrent.SynchronousQueue$TransferStack$SNode
java.util.concurrent.SynchronousQueue$Transferer
java.util.concurrent.ThreadFactory
+java.util.concurrent.ThreadLocalRandom
java.util.concurrent.ThreadPoolExecutor
java.util.concurrent.ThreadPoolExecutor$AbortPolicy
java.util.concurrent.ThreadPoolExecutor$Worker
@@ -3684,19 +3706,33 @@
java.util.concurrent.locks.ReentrantReadWriteLock$Sync
java.util.concurrent.locks.ReentrantReadWriteLock$Sync$ThreadLocalHoldCounter
java.util.concurrent.locks.ReentrantReadWriteLock$WriteLock
+java.util.function.-$Lambda$276$1MZdIZ-DL_fjy9l0o8IMJk57T2g
java.util.function.BiConsumer
java.util.function.BiFunction
+java.util.function.BinaryOperator
java.util.function.Consumer
+java.util.function.DoubleBinaryOperator
java.util.function.Function
+java.util.function.IntBinaryOperator
+java.util.function.IntConsumer
+java.util.function.IntFunction
+java.util.function.IntToDoubleFunction
+java.util.function.IntToLongFunction
+java.util.function.IntUnaryOperator
+java.util.function.LongBinaryOperator
+java.util.function.LongUnaryOperator
java.util.function.Predicate
java.util.function.Supplier
+java.util.function.ToDoubleBiFunction
java.util.function.ToDoubleFunction
+java.util.function.ToIntBiFunction
java.util.function.ToIntFunction
+java.util.function.ToLongBiFunction
java.util.function.ToLongFunction
java.util.function.UnaryOperator
java.util.jar.JarEntry
java.util.jar.JarFile
-java.util.jar.JarFile$1
+java.util.jar.JarFile$JarEntryIterator
java.util.jar.JarFile$JarFileEntry
java.util.logging.ErrorManager
java.util.logging.Formatter
@@ -3706,7 +3742,8 @@
java.util.logging.LogManager
java.util.logging.LogManager$1
java.util.logging.LogManager$2
-java.util.logging.LogManager$4
+java.util.logging.LogManager$3
+java.util.logging.LogManager$5
java.util.logging.LogManager$Cleaner
java.util.logging.LogManager$LogNode
java.util.logging.LogManager$LoggerContext
@@ -3714,8 +3751,8 @@
java.util.logging.LogManager$LoggerWeakRef
java.util.logging.LogManager$RootLogger
java.util.logging.LogManager$SystemLoggerContext
-java.util.logging.LogRecord
java.util.logging.Logger
+java.util.logging.Logger$LoggerBundle
java.util.logging.LoggingPermission
java.util.logging.LoggingProxyImpl
java.util.prefs.AbstractPreferences
@@ -3725,9 +3762,10 @@
java.util.regex.Matcher
java.util.regex.Pattern
java.util.regex.PatternSyntaxException
-java.util.spi.LocaleServiceProvider
java.util.stream.BaseStream
+java.util.stream.DoubleStream
java.util.stream.IntStream
+java.util.stream.LongStream
java.util.stream.Stream
java.util.stream.StreamSupport
java.util.zip.Adler32
@@ -3746,24 +3784,15 @@
java.util.zip.ZipConstants
java.util.zip.ZipEntry
java.util.zip.ZipFile
-java.util.zip.ZipFile$1
+java.util.zip.ZipFile$ZipEntryIterator
java.util.zip.ZipFile$ZipFileInflaterInputStream
java.util.zip.ZipFile$ZipFileInputStream
+java.util.zip.ZipUtils
javax.crypto.BadPaddingException
javax.crypto.Cipher
-javax.crypto.Cipher$CipherSpiAndProvider
-javax.crypto.Cipher$InitParams
-javax.crypto.Cipher$InitType
-javax.crypto.Cipher$NeedToSet
-javax.crypto.Cipher$SpiAndProviderUpdater
-javax.crypto.Cipher$Transform
-javax.crypto.CipherSpi
javax.crypto.IllegalBlockSizeException
-javax.crypto.JceSecurity
javax.crypto.NoSuchPaddingException
-javax.crypto.NullCipher
javax.crypto.SecretKey
-javax.crypto.ShortBufferException
javax.crypto.spec.IvParameterSpec
javax.crypto.spec.SecretKeySpec
javax.microedition.khronos.egl.EGL
@@ -3799,7 +3828,6 @@
javax.net.ssl.SSLSessionContext
javax.net.ssl.SSLSocket
javax.net.ssl.SSLSocketFactory
-javax.net.ssl.SSLSocketFactory$1
javax.net.ssl.TrustManager
javax.net.ssl.TrustManagerFactory
javax.net.ssl.TrustManagerFactory$1
@@ -3808,13 +3836,12 @@
javax.net.ssl.X509ExtendedTrustManager
javax.net.ssl.X509KeyManager
javax.net.ssl.X509TrustManager
+javax.security.auth.Destroyable
javax.security.auth.callback.UnsupportedCallbackException
javax.security.auth.x500.X500Principal
javax.security.cert.Certificate
javax.security.cert.CertificateException
javax.security.cert.X509Certificate
-libcore.icu.DateIntervalFormat
-libcore.icu.DateUtilsBridge
libcore.icu.ICU
libcore.icu.LocaleData
libcore.icu.NativeConverter
@@ -3834,8 +3861,9 @@
libcore.io.EventLogger$Reporter
libcore.io.ForwardingOs
libcore.io.IoBridge
+libcore.io.IoTracker
+libcore.io.IoTracker$Mode
libcore.io.IoUtils
-libcore.io.IoUtils$FileReader
libcore.io.Libcore
libcore.io.Memory
libcore.io.MemoryMappedFile
@@ -3854,8 +3882,6 @@
libcore.reflect.GenericSignatureParser
libcore.reflect.InternalNames
libcore.reflect.ListOfTypes
-libcore.reflect.ListOfVariables
-libcore.reflect.ParameterizedTypeImpl
libcore.reflect.Types
libcore.util.BasicLruCache
libcore.util.CharsetUtils
@@ -3865,8 +3891,6 @@
libcore.util.NativeAllocationRegistry$CleanerRunner
libcore.util.NativeAllocationRegistry$CleanerThunk
libcore.util.ZoneInfo
-libcore.util.ZoneInfo$CheckedArithmeticException
-libcore.util.ZoneInfo$WallTime
libcore.util.ZoneInfoDB
libcore.util.ZoneInfoDB$TzData
libcore.util.ZoneInfoDB$TzData$1
@@ -3879,54 +3903,22 @@
org.apache.harmony.xml.ExpatAttributes
org.apache.harmony.xml.ExpatParser
org.apache.http.Header
-org.apache.http.HeaderIterator
org.apache.http.HttpEntity
org.apache.http.HttpEntityEnclosingRequest
-org.apache.http.HttpHost
org.apache.http.HttpMessage
org.apache.http.HttpRequest
org.apache.http.HttpResponse
-org.apache.http.HttpVersion
-org.apache.http.NameValuePair
org.apache.http.ProtocolVersion
org.apache.http.StatusLine
org.apache.http.client.HttpClient
-org.apache.http.client.ResponseHandler
-org.apache.http.client.methods.AbortableHttpRequest
-org.apache.http.client.methods.HttpEntityEnclosingRequestBase
-org.apache.http.client.methods.HttpPost
-org.apache.http.client.methods.HttpRequestBase
org.apache.http.client.methods.HttpUriRequest
-org.apache.http.client.utils.URLEncodedUtils
-org.apache.http.conn.ClientConnectionManager
org.apache.http.conn.ConnectTimeoutException
org.apache.http.entity.AbstractHttpEntity
-org.apache.http.entity.BasicHttpEntity
-org.apache.http.impl.cookie.DateParseException
-org.apache.http.impl.cookie.DateUtils
org.apache.http.message.AbstractHttpMessage
org.apache.http.message.BasicHeader
org.apache.http.message.BasicHttpResponse
org.apache.http.message.BasicStatusLine
org.apache.http.message.HeaderGroup
-org.apache.http.params.AbstractHttpParams
-org.apache.http.params.BasicHttpParams
-org.apache.http.params.CoreConnectionPNames
-org.apache.http.params.HttpConnectionParams
-org.apache.http.params.HttpParams
-org.apache.http.protocol.HttpContext
-org.ccil.cowan.tagsoup.AttributesImpl
-org.ccil.cowan.tagsoup.AutoDetector
-org.ccil.cowan.tagsoup.Element
-org.ccil.cowan.tagsoup.ElementType
-org.ccil.cowan.tagsoup.HTMLModels
-org.ccil.cowan.tagsoup.HTMLScanner
-org.ccil.cowan.tagsoup.HTMLSchema
-org.ccil.cowan.tagsoup.Parser
-org.ccil.cowan.tagsoup.Parser$1
-org.ccil.cowan.tagsoup.ScanHandler
-org.ccil.cowan.tagsoup.Scanner
-org.ccil.cowan.tagsoup.Schema
org.json.JSON
org.json.JSONArray
org.json.JSONException
@@ -3938,31 +3930,30 @@
org.kxml2.io.KXmlParser
org.kxml2.io.KXmlParser$ValueContext
org.xml.sax.Attributes
-org.xml.sax.ContentHandler
-org.xml.sax.DTDHandler
-org.xml.sax.EntityResolver
-org.xml.sax.ErrorHandler
-org.xml.sax.InputSource
-org.xml.sax.Locator
org.xml.sax.SAXException
-org.xml.sax.SAXNotRecognizedException
-org.xml.sax.SAXNotSupportedException
-org.xml.sax.XMLReader
-org.xml.sax.ext.LexicalHandler
-org.xml.sax.helpers.DefaultHandler
org.xmlpull.v1.XmlPullParser
org.xmlpull.v1.XmlPullParserException
org.xmlpull.v1.XmlSerializer
+sun.invoke.util.BytecodeDescriptor
+sun.invoke.util.Wrapper
sun.misc.Cleaner
sun.misc.CompoundEnumeration
+sun.misc.FDBigInteger
+sun.misc.FloatingDecimal
+sun.misc.FloatingDecimal$1
+sun.misc.FloatingDecimal$ASCIIToBinaryBuffer
+sun.misc.FloatingDecimal$ASCIIToBinaryConverter
+sun.misc.FloatingDecimal$BinaryToASCIIBuffer
+sun.misc.FloatingDecimal$BinaryToASCIIConverter
+sun.misc.FloatingDecimal$ExceptionalBinaryToASCIIBuffer
+sun.misc.FloatingDecimal$PreparedASCIIToBinaryBuffer
sun.misc.FormattedFloatingDecimal
sun.misc.FormattedFloatingDecimal$1
sun.misc.FormattedFloatingDecimal$Form
-sun.misc.FpUtils
-sun.misc.Hashing
sun.misc.IOUtils
-sun.misc.IoTrace
+sun.misc.JavaIOFileDescriptorAccess
sun.misc.REException
+sun.misc.SharedSecrets
sun.misc.Unsafe
sun.misc.VM
sun.misc.Version
@@ -3978,10 +3969,10 @@
sun.net.www.ParseUtil
sun.net.www.protocol.file.Handler
sun.net.www.protocol.jar.Handler
-sun.nio.ch.AbstractPollArrayWrapper
sun.nio.ch.DatagramChannelImpl
sun.nio.ch.DatagramDispatcher
sun.nio.ch.DirectBuffer
+sun.nio.ch.EPollArrayWrapper
sun.nio.ch.FileChannelImpl
sun.nio.ch.FileChannelImpl$Unmapper
sun.nio.ch.FileDispatcher
@@ -3991,13 +3982,11 @@
sun.nio.ch.FileLockTable
sun.nio.ch.IOStatus
sun.nio.ch.IOUtil
-sun.nio.ch.InheritedChannel
sun.nio.ch.Interruptible
sun.nio.ch.NativeDispatcher
sun.nio.ch.NativeThread
sun.nio.ch.NativeThreadSet
sun.nio.ch.Net
-sun.nio.ch.PollArrayWrapper
sun.nio.ch.SelChImpl
sun.nio.ch.ServerSocketChannelImpl
sun.nio.ch.SharedFileLockTable
@@ -4006,14 +3995,8 @@
sun.nio.cs.ArrayEncoder
sun.nio.cs.StreamDecoder
sun.nio.cs.StreamEncoder
-sun.reflect.annotation.AnnotationType
sun.security.action.GetBooleanAction
sun.security.action.GetPropertyAction
-sun.security.ec.ECKeyFactory
-sun.security.ec.ECKeyFactory$1
-sun.security.ec.ECKeyFactory$2
-sun.security.ec.ECParameters
-sun.security.ec.NamedCurve
sun.security.jca.GetInstance
sun.security.jca.GetInstance$Instance
sun.security.jca.ProviderConfig
@@ -4027,7 +4010,6 @@
sun.security.jca.Providers
sun.security.jca.ServiceId
sun.security.pkcs.PKCS9Attribute
-sun.security.pkcs.ParsingException
sun.security.pkcs.SignerInfo
sun.security.provider.CertPathProvider
sun.security.provider.X509Factory
@@ -4043,7 +4025,9 @@
sun.security.provider.certpath.PKIXMasterCertPathValidator
sun.security.provider.certpath.PolicyChecker
sun.security.provider.certpath.PolicyNodeImpl
-sun.security.provider.certpath.UntrustedChecker
+sun.security.util.-$Lambda$179$Kli5xKA4dAwmFO1sy_hpNWmbfH4
+sun.security.util.AbstractAlgorithmConstraints
+sun.security.util.AlgorithmDecomposer
sun.security.util.BitArray
sun.security.util.ByteArrayLexOrder
sun.security.util.ByteArrayTagOrder
@@ -4057,7 +4041,6 @@
sun.security.util.DerOutputStream
sun.security.util.DerValue
sun.security.util.DisabledAlgorithmConstraints
-sun.security.util.DisabledAlgorithmConstraints$1
sun.security.util.DisabledAlgorithmConstraints$KeySizeConstraint
sun.security.util.DisabledAlgorithmConstraints$KeySizeConstraint$Operator
sun.security.util.DisabledAlgorithmConstraints$KeySizeConstraints
@@ -4067,7 +4050,6 @@
sun.security.util.MemoryCache$CacheEntry
sun.security.util.MemoryCache$SoftCacheEntry
sun.security.util.ObjectIdentifier
-sun.security.util.UntrustedCertificates
sun.security.x509.AVA
sun.security.x509.AVAKeyword
sun.security.x509.AccessDescription
@@ -4124,8 +4106,6 @@
sun.security.x509.X509CertImpl
sun.security.x509.X509CertInfo
sun.security.x509.X509Key
-sun.util.LocaleServiceProviderPool
-sun.util.LocaleServiceProviderPool$1
sun.util.calendar.AbstractCalendar
sun.util.calendar.BaseCalendar
sun.util.calendar.BaseCalendar$Date
@@ -4139,18 +4119,15 @@
sun.util.locale.BaseLocale
sun.util.locale.BaseLocale$Cache
sun.util.locale.BaseLocale$Key
-sun.util.locale.Extension
sun.util.locale.InternalLocaleBuilder
sun.util.locale.InternalLocaleBuilder$CaseInsensitiveChar
sun.util.locale.LanguageTag
-sun.util.locale.LocaleExtensions
sun.util.locale.LocaleObjectCache
sun.util.locale.LocaleObjectCache$CacheEntry
sun.util.locale.LocaleSyntaxException
sun.util.locale.LocaleUtils
sun.util.locale.ParseStatus
sun.util.locale.StringTokenIterator
-sun.util.locale.UnicodeLocaleExtension
sun.util.logging.LoggingProxy
sun.util.logging.LoggingSupport
sun.util.logging.LoggingSupport$1
diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index f906ee2..a590805 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -3275,7 +3275,6 @@
// OPEN: Settings > Apps > Default Apps > Warning dialog to confirm selection
DEFAULT_APP_PICKER_CONFIRMATION_DIALOG = 791;
-
// OPEN: Settings > Apps > Default Apps > Default autofill app
DEFAULT_AUTOFILL_PICKER = 792;
@@ -3351,6 +3350,44 @@
// OS: O
BACKUP_SETTINGS = 818;
+ // ACTION: Picture-in-picture was explicitly entered for an activity
+ // VALUE: true if it was entered while hiding as a result of moving to
+ // another task, false otherwise
+ ACTION_PICTURE_IN_PICTURE_ENTERED = 819;
+
+ // ACTION: The activity currently in picture-in-picture was expanded back to fullscreen
+ // PACKAGE: The package name of the activity that was expanded back to fullscreen
+ ACTION_PICTURE_IN_PICTURE_EXPANDED_TO_FULLSCREEN = 820;
+
+ // ACTION: The activity currently in picture-in-picture was minimized
+ // VALUE: True if the PiP was minimized, false otherwise
+ ACTION_PICTURE_IN_PICTURE_MINIMIZED = 821;
+
+ // ACTION: Picture-in-picture was dismissed via the dismiss button
+ // VALUE: 0 if dismissed by tap, 1 if dismissed by drag
+ ACTION_PICTURE_IN_PICTURE_DISMISSED = 822;
+
+ // ACTION: The visibility of the picture-in-picture meny
+ // VALUE: Whether or not the menu is visible
+ ACTION_PICTURE_IN_PICTURE_MENU = 823;
+
+ // Enclosing category for group of PICTURE_IN_PICTURE_ASPECT_RATIO_FOO events,
+ // logged when the aspect ratio changes
+ ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED = 824;
+
+ // The current aspect ratio of the PiP, logged when it changes.
+ PICTURE_IN_PICTURE_ASPECT_RATIO = 825;
+
+ // FIELD - length in dp of ACTION_LS_* gestures, or zero if not applicable
+ // CATEGORY: GLOBAL_SYSTEM_UI
+ // OS: O
+ FIELD_GESTURE_LENGTH = 826;
+
+ // FIELD - velocity in dp (per second?) of ACTION_LS_* gestures, or zero if not applicable
+ // CATEGORY: GLOBAL_SYSTEM_UI
+ // OS: O
+ FIELD_GESTURE_VELOCITY = 827;
+
// ---- End O Constants, all O constants go above this line ----
// Add new aosp constants above this line.
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 4f82b01..aae5dd8 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -70,6 +70,8 @@
import android.os.UserManagerInternal;
import android.provider.Settings;
import android.hardware.fingerprint.IFingerprintService;
+import android.provider.SettingsStringUtil.ComponentNameSet;
+import android.provider.SettingsStringUtil.SettingStringHelper;
import android.text.TextUtils;
import android.text.TextUtils.SimpleStringSplitter;
import android.util.Slog;
@@ -98,9 +100,9 @@
import com.android.internal.content.PackageMonitor;
import com.android.internal.os.SomeArgs;
import com.android.server.LocalServices;
-
import com.android.server.policy.AccessibilityShortcutController;
import com.android.server.statusbar.StatusBarManagerInternal;
+
import org.xmlpull.v1.XmlPullParserException;
import java.io.FileDescriptor;
@@ -445,7 +447,7 @@
}
return userState.getClientState();
} else {
- userState.mClients.register(client);
+ userState.mUserClients.register(client);
// If this client is not for the current user we do not
// return a state since it is not for the foreground user.
// We will send the state to the client on a user switch.
@@ -813,6 +815,42 @@
}
}
+ /**
+ * Invoked remotely over AIDL by SysUi when the accessibility button within the system's
+ * navigation area has been clicked.
+ */
+ @Override
+ public void notifyAccessibilityButtonClicked() {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Caller does not hold permission "
+ + android.Manifest.permission.STATUS_BAR);
+ }
+ synchronized (mLock) {
+ notifyAccessibilityButtonClickedLocked();
+ }
+ }
+
+ /**
+ * Invoked remotely over AIDL by SysUi when the availability of the accessibility
+ * button within the system's navigation area has changed.
+ *
+ * @param available {@code true} if the accessibility button is available to the
+ * user, {@code false} otherwise
+ */
+ @Override
+ public void notifyAccessibilityButtonAvailabilityChanged(boolean available) {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Caller does not hold permission "
+ + android.Manifest.permission.STATUS_BAR);
+ }
+ synchronized (mLock) {
+ notifyAccessibilityButtonAvailabilityChangedLocked(available);
+ }
+ }
+
+
boolean onGesture(int gestureId) {
synchronized (mLock) {
boolean handled = notifyGestureLocked(gestureId, false);
@@ -927,7 +965,7 @@
oldUserState.onSwitchToAnotherUser();
// Disable the local managers for the old user.
- if (oldUserState.mClients.getRegisteredCallbackCount() > 0) {
+ if (oldUserState.mUserClients.getRegisteredCallbackCount() > 0) {
mMainHandler.obtainMessage(MainHandler.MSG_SEND_CLEARED_STATE_TO_CLIENTS_FOR_USER,
oldUserState.mUserId, 0).sendToTarget();
}
@@ -1044,6 +1082,28 @@
}
}
+ private void notifyAccessibilityButtonClickedLocked() {
+ final UserState state = getCurrentUserStateLocked();
+ for (int i = state.mBoundServices.size() - 1; i >= 0; i--) {
+ final Service service = state.mBoundServices.get(i);
+ // TODO(b/34720082): Only notify a single user-defined service
+ if (service.mRequestAccessibilityButton) {
+ service.notifyAccessibilityButtonClickedLocked();
+ }
+ }
+ }
+
+ private void notifyAccessibilityButtonAvailabilityChangedLocked(boolean available) {
+ final UserState state = getCurrentUserStateLocked();
+ state.mIsAccessibilityButtonAvailable = available;
+ for (int i = state.mBoundServices.size() - 1; i >= 0; i--) {
+ final Service service = state.mBoundServices.get(i);
+ if (service.mRequestAccessibilityButton) {
+ service.notifyAccessibilityButtonAvailabilityChangedLocked(available);
+ }
+ }
+ }
+
/**
* Removes an AccessibilityInteractionConnection.
*
@@ -1178,7 +1238,7 @@
service.onAdded();
userState.mBoundServices.add(service);
userState.mComponentNameToServiceMap.put(service.mComponentName, service);
- scheduleNotifyClientsOfServicesStateChange();
+ scheduleNotifyClientsOfServicesStateChange(userState);
}
} catch (RemoteException re) {
/* do nothing */
@@ -1200,7 +1260,7 @@
Service boundService = userState.mBoundServices.get(i);
userState.mComponentNameToServiceMap.put(boundService.mComponentName, boundService);
}
- scheduleNotifyClientsOfServicesStateChange();
+ scheduleNotifyClientsOfServicesStateChange(userState);
}
/**
@@ -1362,16 +1422,16 @@
final int clientState = userState.getClientState();
if (userState.mLastSentClientState != clientState
&& (mGlobalClients.getRegisteredCallbackCount() > 0
- || userState.mClients.getRegisteredCallbackCount() > 0)) {
+ || userState.mUserClients.getRegisteredCallbackCount() > 0)) {
userState.mLastSentClientState = clientState;
mMainHandler.obtainMessage(MainHandler.MSG_SEND_STATE_TO_CLIENTS,
clientState, userState.mUserId).sendToTarget();
}
}
- private void scheduleNotifyClientsOfServicesStateChange() {
- mMainHandler.obtainMessage(MainHandler.MSG_SEND_SERVICES_STATE_CHANGED_TO_CLIENTS)
- .sendToTarget();
+ private void scheduleNotifyClientsOfServicesStateChange(UserState userState) {
+ mMainHandler.obtainMessage(MainHandler.MSG_SEND_SERVICES_STATE_CHANGED_TO_CLIENTS,
+ userState.mUserId).sendToTarget();
}
private void scheduleUpdateInputFilter(UserState userState) {
@@ -2013,10 +2073,12 @@
* Enables accessibility service specified by {@param componentName} for the {@param userId}.
*/
private void enableAccessibilityServiceLocked(ComponentName componentName, int userId) {
- SettingsStringHelper settingsHelper = new SettingsStringHelper(
- Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, userId);
- settingsHelper.addService(componentName);
- settingsHelper.writeToSettings();
+ final SettingStringHelper setting =
+ new SettingStringHelper(
+ mContext.getContentResolver(),
+ Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
+ userId);
+ setting.write(ComponentNameSet.add(setting.read(), componentName));
UserState userState = getUserStateLocked(userId);
if (userState.mEnabledServices.add(componentName)) {
@@ -2028,10 +2090,12 @@
* Disables accessibility service specified by {@param componentName} for the {@param userId}.
*/
private void disableAccessibilityServiceLocked(ComponentName componentName, int userId) {
- SettingsStringHelper settingsHelper = new SettingsStringHelper(
- Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, userId);
- settingsHelper.deleteService(componentName);
- settingsHelper.writeToSettings();
+ final SettingStringHelper setting =
+ new SettingStringHelper(
+ mContext.getContentResolver(),
+ Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
+ userId);
+ setting.write(ComponentNameSet.remove(setting.read(), componentName));
UserState userState = getUserStateLocked(userId);
if (userState.mEnabledServices.remove(componentName)) {
@@ -2060,45 +2124,6 @@
return mFingerprintGestureDispatcher.onFingerprintGesture(gestureKeyCode);
}
- private class SettingsStringHelper {
- private static final String SETTINGS_DELIMITER = ":";
- private ContentResolver mContentResolver;
- private final String mSettingsName;
- private Set<String> mServices;
- private final int mUserId;
-
- public SettingsStringHelper(String name, int userId) {
- mUserId = userId;
- mSettingsName = name;
- mContentResolver = mContext.getContentResolver();
- String servicesString = Settings.Secure.getStringForUser(
- mContentResolver, mSettingsName, userId);
- mServices = new HashSet();
- if (!TextUtils.isEmpty(servicesString)) {
- final TextUtils.SimpleStringSplitter colonSplitter =
- new TextUtils.SimpleStringSplitter(SETTINGS_DELIMITER.charAt(0));
- colonSplitter.setString(servicesString);
- while (colonSplitter.hasNext()) {
- final String serviceName = colonSplitter.next();
- mServices.add(serviceName);
- }
- }
- }
-
- public void addService(ComponentName component) {
- mServices.add(component.flattenToString());
- }
-
- public void deleteService(ComponentName component) {
- mServices.remove(component.flattenToString());
- }
-
- public void writeToSettings() {
- Settings.Secure.putStringForUser(mContentResolver, mSettingsName,
- TextUtils.join(SETTINGS_DELIMITER, mServices), mUserId);
- }
- }
-
@Override
public void dump(FileDescriptor fd, final PrintWriter pw, String[] args) {
mSecurityPolicy.enforceCallingPermission(Manifest.permission.DUMP, FUNCTION_DUMP);
@@ -2225,12 +2250,12 @@
final int clientState = msg.arg1;
final int userId = msg.arg2;
sendStateToClients(clientState, mGlobalClients);
- sendStateToClientsForUser(clientState, userId);
+ sendStateToClients(clientState, getUserClientsForId(userId));
} break;
case MSG_SEND_CLEARED_STATE_TO_CLIENTS_FOR_USER: {
final int userId = msg.arg1;
- sendStateToClientsForUser(0, userId);
+ sendStateToClients(0, getUserClientsForId(userId));
} break;
case MSG_ANNOUNCE_NEW_USER_IF_NEEDED: {
@@ -2257,7 +2282,9 @@
} break;
case MSG_SEND_SERVICES_STATE_CHANGED_TO_CLIENTS: {
- notifyClientsOfServicesStateChange();
+ final int userId = msg.arg1;
+ notifyClientsOfServicesStateChange(mGlobalClients);
+ notifyClientsOfServicesStateChange(getUserClientsForId(userId));
} break;
case MSG_UPDATE_FINGERPRINT: {
@@ -2282,12 +2309,12 @@
}
}
- private void sendStateToClientsForUser(int clientState, int userId) {
+ private RemoteCallbackList<IAccessibilityManagerClient> getUserClientsForId(int userId) {
final UserState userState;
synchronized (mLock) {
userState = getUserStateLocked(userId);
}
- sendStateToClients(clientState, userState.mClients);
+ return userState.mUserClients;
}
private void sendStateToClients(int clientState,
@@ -2307,11 +2334,8 @@
}
}
- private void notifyClientsOfServicesStateChange() {
- RemoteCallbackList<IAccessibilityManagerClient> clients;
- synchronized (mLock) {
- clients = getCurrentUserStateLocked().mClients;
- }
+ private void notifyClientsOfServicesStateChange(
+ RemoteCallbackList<IAccessibilityManagerClient> clients) {
try {
final int userClientCount = clients.beginBroadcast();
for (int i = 0; i < userClientCount; i++) {
@@ -2426,6 +2450,8 @@
boolean mCaptureFingerprintGestures;
+ boolean mRequestAccessibilityButton;
+
int mFetchFlags;
long mNotificationTimeout;
@@ -2581,6 +2607,8 @@
& AccessibilityServiceInfo.FLAG_RETRIEVE_INTERACTIVE_WINDOWS) != 0;
mCaptureFingerprintGestures = (info.flags
& AccessibilityServiceInfo.FLAG_CAPTURE_FINGERPRINT_GESTURES) != 0;
+ mRequestAccessibilityButton = (info.flags
+ & AccessibilityServiceInfo.FLAG_REQUEST_ACCESSIBILITY_BUTTON) != 0;
}
/**
@@ -2694,7 +2722,7 @@
}
UserState userState = getUserStateLocked(mUserId);
onUserStateChangedLocked(userState);
- scheduleNotifyClientsOfServicesStateChange();
+ scheduleNotifyClientsOfServicesStateChange(userState);
}
} finally {
Binder.restoreCallingIdentity(identity);
@@ -3332,6 +3360,19 @@
}
@Override
+ public boolean isAccessibilityButtonAvailable() {
+ final UserState userState;
+ synchronized (mLock) {
+ if (!isCalledForCurrentUserLocked()) {
+ return false;
+ }
+ userState = getCurrentUserStateLocked();
+ }
+
+ return mRequestAccessibilityButton && userState.mIsAccessibilityButtonAvailable;
+ }
+
+ @Override
public void dump(FileDescriptor fd, final PrintWriter pw, String[] args) {
mSecurityPolicy.enforceCallingPermission(Manifest.permission.DUMP, FUNCTION_DUMP);
synchronized (mLock) {
@@ -3544,6 +3585,14 @@
mInvocationHandler.notifySoftKeyboardShowModeChangedLocked(showState);
}
+ public void notifyAccessibilityButtonClickedLocked() {
+ mInvocationHandler.notifyAccessibilityButtonClickedLocked();
+ }
+
+ public void notifyAccessibilityButtonAvailabilityChangedLocked(boolean available) {
+ mInvocationHandler.notifyAccessibilityButtonAvailabilityChangedLocked(available);
+ }
+
/**
* Called by the invocation handler to notify the service that the
* state of magnification has changed.
@@ -3582,6 +3631,36 @@
}
}
+ private void notifyAccessibilityButtonClickedInternal() {
+ final IAccessibilityServiceClient listener;
+ synchronized (mLock) {
+ listener = mServiceInterface;
+ }
+ if (listener != null) {
+ try {
+ listener.onAccessibilityButtonClicked();
+ } catch (RemoteException re) {
+ Slog.e(LOG_TAG, "Error sending accessibility button click to " + mService, re);
+ }
+ }
+ }
+
+ private void notifyAccessibilityButtonAvailabilityChangedInternal(boolean available) {
+ final IAccessibilityServiceClient listener;
+ synchronized (mLock) {
+ listener = mServiceInterface;
+ }
+ if (listener != null) {
+ try {
+ listener.onAccessibilityButtonAvailabilityChanged(available);
+ } catch (RemoteException re) {
+ Slog.e(LOG_TAG,
+ "Error sending accessibility button availability change to " + mService,
+ re);
+ }
+ }
+ }
+
private void notifyGestureInternal(int gestureId) {
final IAccessibilityServiceClient listener;
synchronized (mLock) {
@@ -3723,6 +3802,8 @@
private static final int MSG_ON_MAGNIFICATION_CHANGED = 5;
private static final int MSG_ON_SOFT_KEYBOARD_STATE_CHANGED = 6;
+ private static final int MSG_ON_ACCESSIBILITY_BUTTON_CLICKED = 7;
+ private static final int MSG_ON_ACCESSIBILITY_BUTTON_AVAILABILITY_CHANGED = 8;
private boolean mIsMagnificationCallbackEnabled = false;
private boolean mIsSoftKeyboardCallbackEnabled = false;
@@ -3758,6 +3839,15 @@
notifySoftKeyboardShowModeChangedInternal(showState);
} break;
+ case MSG_ON_ACCESSIBILITY_BUTTON_CLICKED: {
+ notifyAccessibilityButtonClickedInternal();
+ } break;
+
+ case MSG_ON_ACCESSIBILITY_BUTTON_AVAILABILITY_CHANGED: {
+ final boolean available = (message.arg1 != 0);
+ notifyAccessibilityButtonAvailabilityChangedInternal(available);
+ } break;
+
default: {
throw new IllegalArgumentException("Unknown message: " + type);
}
@@ -3797,6 +3887,17 @@
public void setSoftKeyboardCallbackEnabled(boolean enabled) {
mIsSoftKeyboardCallbackEnabled = enabled;
}
+
+ public void notifyAccessibilityButtonClickedLocked() {
+ final Message msg = obtainMessage(MSG_ON_ACCESSIBILITY_BUTTON_CLICKED);
+ msg.sendToTarget();
+ }
+
+ public void notifyAccessibilityButtonAvailabilityChangedLocked(boolean available) {
+ final Message msg = obtainMessage(MSG_ON_ACCESSIBILITY_BUTTON_AVAILABILITY_CHANGED,
+ (available ? 1 : 0), 0);
+ msg.sendToTarget();
+ }
}
}
@@ -3899,6 +4000,7 @@
case WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG:
case WindowManager.LayoutParams.TYPE_SYSTEM_ERROR:
case WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY:
+ case WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY:
case WindowManager.LayoutParams.TYPE_SCREENSHOT: {
return AccessibilityWindowInfo.TYPE_SYSTEM;
}
@@ -4466,7 +4568,7 @@
// Non-transient state.
- public final RemoteCallbackList<IAccessibilityManagerClient> mClients =
+ public final RemoteCallbackList<IAccessibilityManagerClient> mUserClients =
new RemoteCallbackList<>();
public final SparseArray<AccessibilityConnectionWrapper> mInteractionConnections =
@@ -4500,6 +4602,8 @@
public int mSoftKeyboardShowMode = 0;
+ public boolean mIsAccessibilityButtonAvailable;
+
public boolean mIsTouchExplorationEnabled;
public boolean mIsTextHighContrastEnabled;
public boolean mIsEnhancedWebAccessibilityEnabled;
@@ -4574,6 +4678,9 @@
mIsDisplayMagnificationEnabled = false;
mIsAutoclickEnabled = false;
mSoftKeyboardShowMode = 0;
+
+ // Clear state tracked from system UI
+ mIsAccessibilityButtonAvailable = false;
}
public void destroyUiAutomationService() {
diff --git a/services/autofill/java/com/android/server/autofill/AnchoredWindow.java b/services/autofill/java/com/android/server/autofill/AnchoredWindow.java
index ecfd9b3..c68ac60 100644
--- a/services/autofill/java/com/android/server/autofill/AnchoredWindow.java
+++ b/services/autofill/java/com/android/server/autofill/AnchoredWindow.java
@@ -64,7 +64,7 @@
* @param bounds the rectangular region this window should be anchored to
*/
void show(Rect bounds) {
- LayoutParams params = createBaseLayoutParams();
+ final LayoutParams params = createBaseLayoutParams();
params.x = bounds.left;
params.y = bounds.bottom;
@@ -83,6 +83,7 @@
*/
void hide() {
if (DEBUG) Slog.d(TAG, "removing view " + mView);
+
if (mIsShowing) {
mWm.removeView(mRootView);
}
@@ -93,13 +94,13 @@
* Wraps a view with a SelfRemovingView and sets its requested width and height.
*/
private View wrapView(View view, int width, int height) {
- ViewGroup viewGroup = new SelfRemovingView(view.getContext());
+ final ViewGroup viewGroup = new SelfRemovingView(view.getContext());
viewGroup.addView(view, new ViewGroup.LayoutParams(width, height));
return viewGroup;
}
private static LayoutParams createBaseLayoutParams() {
- LayoutParams params = new LayoutParams();
+ final LayoutParams params = new LayoutParams();
// TODO(b/33197203): LayoutParams.TYPE_AUTOFILL
params.type = LayoutParams.TYPE_SYSTEM_ALERT;
params.flags =
@@ -115,6 +116,13 @@
return params;
}
+ @Override
+ public String toString() {
+ if (!DEBUG) return super.toString();
+
+ return "AnchoredWindow: [width=" + mWidth + ", height=" + mHeight + ", view=" + mView + "]";
+ }
+
void dump(PrintWriter pw) {
pw.println("Anchored Window");
final String prefix = " ";
diff --git a/services/autofill/java/com/android/server/autofill/AutoFillManagerService.java b/services/autofill/java/com/android/server/autofill/AutoFillManagerService.java
index 58edadc..9347350 100644
--- a/services/autofill/java/com/android/server/autofill/AutoFillManagerService.java
+++ b/services/autofill/java/com/android/server/autofill/AutoFillManagerService.java
@@ -18,9 +18,11 @@
import static android.Manifest.permission.MANAGE_AUTO_FILL;
import static android.content.Context.AUTO_FILL_MANAGER_SERVICE;
-import static android.view.View.AUTO_FILL_FLAG_TYPE_FILL;
+import static com.android.server.autofill.Helper.DEBUG;
+import static com.android.server.autofill.Helper.VERBOSE;
import android.Manifest;
+import android.annotation.Nullable;
import android.app.ActivityManagerInternal;
import android.app.AppGlobals;
import android.content.ComponentName;
@@ -35,8 +37,6 @@
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
-import android.os.Message;
-import android.os.Process;
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.ShellCallback;
@@ -44,18 +44,17 @@
import android.provider.Settings;
import android.service.autofill.IAutoFillManagerService;
import android.text.TextUtils;
-import android.text.format.DateUtils;
import android.util.LocalLog;
import android.util.Log;
import android.util.Slog;
import android.util.SparseArray;
import android.view.autofill.AutoFillId;
+import android.view.autofill.AutoFillValue;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.os.BackgroundThread;
import com.android.internal.os.HandlerCaller;
import com.android.internal.os.SomeArgs;
-import com.android.server.FgThread;
import com.android.server.LocalServices;
import com.android.server.SystemService;
@@ -73,47 +72,47 @@
public final class AutoFillManagerService extends SystemService {
private static final String TAG = "AutoFillManagerService";
- static final boolean DEBUG = true; // TODO(b/33197203): change to false once stable
- private static final long SERVICE_BINDING_LIFETIME_MS = 5 * DateUtils.MINUTE_IN_MILLIS;
+ private static final int MSG_START_SESSION = 1;
+ private static final int MSG_UPDATE_SESSION = 2;
+ private static final int MSG_FINISH_SESSION = 3;
+ private static final int MSG_REQUEST_SAVE_FOR_USER = 4;
- protected static final int MSG_UNBIND = 1;
- protected static final int MSG_REQUEST_AUTO_FILL_FOR_USER = 2;
- protected static final int MSG_REQUEST_AUTO_FILL = 3;
-
- private final AutoFillManagerServiceStub mServiceStub;
private final Context mContext;
- private final ContentResolver mResolver;
+ private final AutoFillUI mUi;
private final Object mLock = new Object();
- private final HandlerCaller.Callback mHandlerCallback = new HandlerCaller.Callback() {
-
- @Override
- public void executeMessage(Message msg) {
- switch (msg.what) {
- case MSG_UNBIND: {
- synchronized (mLock) {
- removeCachedServiceLocked(msg.arg1);
- }
- return;
- } case MSG_REQUEST_AUTO_FILL_FOR_USER: {
- final int userId = msg.arg1;
- final int flags = msg.arg2;
- handleAutoFillForUser(userId, flags);
- return;
- } case MSG_REQUEST_AUTO_FILL: {
- final SomeArgs args = (SomeArgs) msg.obj;
- final int userId = msg.arg1;
- final int flags = msg.arg2;
- final IBinder activityToken = (IBinder) args.arg1;
- final AutoFillId autoFillId = (AutoFillId) args.arg2;
- final Rect bounds = (Rect) args.arg3;
- handleAutoFill(activityToken, userId, autoFillId, bounds, flags);
- return;
- } default: {
- Slog.w(TAG, "Invalid message: " + msg);
- }
+ private final HandlerCaller.Callback mHandlerCallback = (msg) -> {
+ switch (msg.what) {
+ case MSG_START_SESSION: {
+ final SomeArgs args = (SomeArgs) msg.obj;
+ final int userId = msg.arg1;
+ final IBinder activityToken = (IBinder) args.arg1;
+ final IBinder appCallback = (IBinder) args.arg2;
+ final AutoFillId autoFillId = (AutoFillId) args.arg3;
+ final Rect bounds = (Rect) args.arg4;
+ final AutoFillValue value = (AutoFillValue) args.arg5;
+ handleStartSession(userId, activityToken, appCallback, autoFillId, bounds, value);
+ return;
+ } case MSG_FINISH_SESSION: {
+ handleFinishSession(msg.arg1, (IBinder) msg.obj);
+ return;
+ } case MSG_REQUEST_SAVE_FOR_USER: {
+ handleSaveForUser(msg.arg1);
+ return;
+ } case MSG_UPDATE_SESSION: {
+ final SomeArgs args = (SomeArgs) msg.obj;
+ final IBinder activityToken = (IBinder) args.arg1;
+ final AutoFillId autoFillId = (AutoFillId) args.arg2;
+ final Rect bounds = (Rect) args.arg3;
+ final AutoFillValue value = (AutoFillValue) args.arg4;
+ final int userId = args.argi5;
+ final int flags = args.argi6;
+ handleUpdateSession(userId, activityToken, autoFillId, bounds, value, flags);
+ return;
+ } default: {
+ Slog.w(TAG, "Invalid message: " + msg);
}
}
};
@@ -130,10 +129,10 @@
* Entries on this cache are added on demand and removed when:
* <ol>
* <li>An auto-fill service app is removed.
- * <li>The {@link android.provider.Settings.Secure#AUTO_FILL_SERVICE} for an user change.
- * <li>It has not been interacted with for {@link #SERVICE_BINDING_LIFETIME_MS} ms.
+ * <li>The {@link android.provider.Settings.Secure#AUTO_FILL_SERVICE} for an user change.\
* </ol>
*/
+ // TODO(b/33197203): Update the above comment
@GuardedBy("mLock")
private SparseArray<AutoFillManagerServiceImpl> mServicesCache = new SparseArray<>();
@@ -142,19 +141,14 @@
public AutoFillManagerService(Context context) {
super(context);
-
mHandlerCaller = new HandlerCaller(null, Looper.getMainLooper(), mHandlerCallback, true);
-
mContext = context;
-
- mResolver = context.getContentResolver();
- mServiceStub = new AutoFillManagerServiceStub();
+ mUi = new AutoFillUI(mContext);
}
@Override
public void onStart() {
- if (DEBUG) Slog.d(TAG, "onStart(): binding as " + AUTO_FILL_MANAGER_SERVICE);
- publishBinderService(AUTO_FILL_MANAGER_SERVICE, mServiceStub);
+ publishBinderService(AUTO_FILL_MANAGER_SERVICE, new AutoFillManagerServiceStub());
}
@Override
@@ -168,58 +162,44 @@
ComponentName serviceComponent = null;
ServiceInfo serviceInfo = null;
final String componentName = Settings.Secure.getStringForUser(
- mResolver, Settings.Secure.AUTO_FILL_SERVICE, userId);
+ mContext.getContentResolver(), Settings.Secure.AUTO_FILL_SERVICE, userId);
if (!TextUtils.isEmpty(componentName)) {
try {
serviceComponent = ComponentName.unflattenFromString(componentName);
- serviceInfo =
- AppGlobals.getPackageManager().getServiceInfo(serviceComponent, 0, userId);
+ serviceInfo = AppGlobals.getPackageManager().getServiceInfo(serviceComponent, 0,
+ userId);
} catch (RuntimeException | RemoteException e) {
- Slog.wtf(TAG, "Bad auto-fill service name " + componentName, e);
+ Slog.e(TAG, "Bad auto-fill service name " + componentName, e);
return null;
}
}
- if (DEBUG) Slog.d(TAG, "getServiceComponentForUser(" + userId + "): component="
- + serviceComponent + ", info: " + serviceInfo);
if (serviceInfo == null) {
- if (DEBUG) Slog.d(TAG, "no service info for " + serviceComponent);
return null;
}
- return new AutoFillManagerServiceImpl(this, mContext, mLock, mRequestsHistory,
- FgThread.getHandler(), userId, serviceInfo.applicationInfo.uid, serviceComponent,
- SERVICE_BINDING_LIFETIME_MS);
+
+ try {
+ return new AutoFillManagerServiceImpl(mContext, mLock, mRequestsHistory,
+ userId, serviceComponent, mUi);
+ } catch (PackageManager.NameNotFoundException e) {
+ Slog.w(TAG, "Auto-fill service not found: " + serviceComponent, e);
+ }
+
+ return null;
}
/**
* Gets the service instance for an user.
*
- * <p>First it tries to return the existing instance from the cache; if it's not cached, it
- * creates a new instance and caches it.
+ * @return service instance or {@code null} if user does not have a service set.
*/
- // TODO(b/33197203): make private once AutoFillUi does not uses notifications
+ @Nullable
AutoFillManagerServiceImpl getServiceForUserLocked(int userId) {
AutoFillManagerServiceImpl service = mServicesCache.get(userId);
- if (service != null) {
- if (DEBUG) Log.d(TAG, "reusing cached service for userId " + userId);
- service.setLifeExpectancy(SERVICE_BINDING_LIFETIME_MS);
- } else {
+ if (service == null) {
service = newServiceForUser(userId);
- if (service == null) {
- // Already logged
- return null;
- }
- if (DEBUG) Log.d(TAG, "creating new cached service for userId " + userId);
- service.startLocked();
mServicesCache.put(userId, service);
}
- // Keep service connection alive for a while, in case user needs to interact with it
- // (for example, to save the data that was inputted in)
- if (mHandlerCaller.hasMessages(MSG_UNBIND)) {
- mHandlerCaller.removeMessages(MSG_UNBIND);
- }
- mHandlerCaller.sendMessageDelayed(mHandlerCaller.obtainMessageI(MSG_UNBIND, userId),
- SERVICE_BINDING_LIFETIME_MS);
return service;
}
@@ -227,85 +207,121 @@
* Removes a cached service for a given user.
*/
void removeCachedServiceLocked(int userId) {
- if (DEBUG) Log.d(TAG, "removing cached service for userId " + userId);
final AutoFillManagerServiceImpl service = mServicesCache.get(userId);
- if (service == null) {
- if (DEBUG) {
- Log.d(TAG, "removeCachedServiceForUser(): no cached service for userId " + userId);
- }
- return;
- }
- mServicesCache.delete(userId);
- service.stopLocked();
- }
-
- private void handleAutoFill(IBinder activityToken, int userId, AutoFillId autoFillId,
- Rect bounds, int flags) {
- synchronized (mLock) {
- final AutoFillManagerServiceImpl service = getServiceForUserLocked(userId);
- if (service != null) {
- // TODO(b/33197203): must pass AUTO_FILL_FLAG_TYPE_FILL because AM is expecting
- // either that flag or AUTO_FILL_FLAG_TYPE_SAVE; should go away once save is
- // refactored
- flags |= AUTO_FILL_FLAG_TYPE_FILL;
- service.requestAutoFillLocked(activityToken, autoFillId, bounds, flags);
- }
+ if (service != null) {
+ mServicesCache.delete(userId);
+ service.destroyLocked();
}
}
- private void handleAutoFillForUser(int userId, int flags) {
- if (DEBUG) {
- Slog.d(TAG, "handler.requestAutoFillForUser(): id=" + userId + ", flags=" + flags);
- }
- final List<IBinder> topActivities = LocalServices
- .getService(ActivityManagerInternal.class).getTopVisibleActivities();
- if (DEBUG)
- Slog.d(TAG, "Top activities (" + topActivities.size() + "): " + topActivities);
- if (topActivities.isEmpty()) {
- Slog.w(TAG, "Could not get top activity");
- return;
- }
- final IBinder activityToken = topActivities.get(0);
+ private void handleStartSession(int userId, IBinder activityToken, IBinder appCallback,
+ AutoFillId autoFillId, Rect bounds, AutoFillValue value) {
synchronized (mLock) {
final AutoFillManagerServiceImpl service = getServiceForUserLocked(userId);
if (service == null) {
- Slog.w(TAG, "no service for user " + userId);
return;
}
- service.requestAutoFillLocked(activityToken, null, null, flags);
+ service.startSessionLocked(activityToken, appCallback, autoFillId, bounds, value);
+ }
+ }
+
+ private void handleFinishSession(int userId, IBinder activityToken) {
+ synchronized (mLock) {
+ final AutoFillManagerServiceImpl service = mServicesCache.get(userId);
+ if (service == null) {
+ return;
+ }
+ service.finishSessionLocked(activityToken);
+ }
+ }
+
+ private void handleUpdateSession(int userId, IBinder activityToken, AutoFillId autoFillId,
+ Rect bounds, AutoFillValue value, int flags) {
+ synchronized (mLock) {
+ final AutoFillManagerServiceImpl service = mServicesCache.get(userId);
+ if (service == null) {
+ return;
+ }
+
+ service.updateSessionLocked(activityToken, autoFillId, bounds, value, flags);
+ }
+ }
+
+ private IBinder getTopActivityForUser() {
+ final List<IBinder> topActivities = LocalServices
+ .getService(ActivityManagerInternal.class).getTopVisibleActivities();
+ if (DEBUG) Slog.d(TAG, "Top activities (" + topActivities.size() + "): " + topActivities);
+ if (topActivities.isEmpty()) {
+ Slog.w(TAG, "Could not get top activity");
+ return null;
+ }
+ return topActivities.get(0);
+ }
+
+ private void handleSaveForUser(int userId) {
+ final IBinder activityToken = getTopActivityForUser();
+ if (activityToken != null) {
+ synchronized (mLock) {
+ final AutoFillManagerServiceImpl service = mServicesCache.get(userId);
+ if (service == null) {
+ Log.w(TAG, "handleSaveForUser(): no cached service for userId " + userId);
+ return;
+ }
+
+ service.requestSaveForUserLocked(activityToken);
+ }
}
}
final class AutoFillManagerServiceStub extends IAutoFillManagerService.Stub {
@Override
- public void requestAutoFill(AutoFillId id, Rect bounds, int flags) {
- if (DEBUG) Slog.d(TAG, "requestAutoFill: flags=" + flags + ", autoFillId=" + id
- + ", bounds=" + bounds);
+ public void startSession(IBinder activityToken, IBinder appCallback, AutoFillId autoFillId,
+ Rect bounds, AutoFillValue value) throws RemoteException {
+ // TODO(b/33197203): make sure it's called by resumed / focused activity
- // Make sure its called by the top activity.
- final int uid = Binder.getCallingUid();
- final IBinder activityToken = LocalServices.getService(ActivityManagerInternal.class)
- .getTopVisibleActivity(uid);
- if (activityToken == null) {
- // TODO(b/33197203, b/34819567, b/34171325): figure out proper way to handle it
- if (uid == Process.SYSTEM_UID) {
- if (DEBUG) Log.w(TAG, "requestAutoFill(): ignoring call from system");
- return;
- }
- throw new SecurityException("uid " + uid + " does not own the top activity");
+ final int userId = UserHandle.getCallingUserId();
+ if (VERBOSE) {
+ Slog.v(TAG, "startSession: autoFillId=" + autoFillId + ", bounds=" + bounds
+ + ", value=" + value);
}
- mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageIIOOO(MSG_REQUEST_AUTO_FILL,
- UserHandle.getCallingUserId(), flags, activityToken, id, bounds));
+ final SomeArgs args = SomeArgs.obtain();
+ args.arg1 = activityToken;
+ args.arg2 = appCallback;
+ args.arg3 = autoFillId;
+ args.arg4 = bounds;
+ args.arg5 = value;
+
+ mHandlerCaller.sendMessage(mHandlerCaller.getHandler().obtainMessage(MSG_START_SESSION,
+ userId, 0, args));
}
@Override
- public void requestAutoFillForUser(int userId, int flags) {
- mContext.enforceCallingPermission(MANAGE_AUTO_FILL, TAG);
+ public void updateSession(IBinder activityToken, AutoFillId id, Rect bounds,
+ AutoFillValue value, int flags) throws RemoteException {
+ if (DEBUG) {
+ Slog.d(TAG, "updateSession: flags=" + flags + ", autoFillId=" + id
+ + ", bounds=" + bounds + ", value=" + value);
+ }
- mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageII(
- MSG_REQUEST_AUTO_FILL_FOR_USER, userId, flags));
+ mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageOOOOII(MSG_UPDATE_SESSION,
+ activityToken, id, bounds, value, UserHandle.getCallingUserId(), flags));
+ }
+
+ @Override
+ public void finishSession(IBinder activityToken) throws RemoteException {
+ if (VERBOSE) Slog.v(TAG, "finishSession(): " + activityToken);
+
+ mHandlerCaller.sendMessage(mHandlerCaller.getHandler().obtainMessage(MSG_FINISH_SESSION,
+ UserHandle.getCallingUserId(), 0, activityToken));
+ }
+
+ @Override
+ public void requestSaveForUser(int userId) {
+ mContext.enforceCallingPermission(MANAGE_AUTO_FILL, TAG);
+ mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageI(MSG_REQUEST_SAVE_FOR_USER,
+ userId));
}
@Override
@@ -330,6 +346,7 @@
impl.dumpLocked(" ", pw);
}
}
+ mUi.dump(pw);
}
pw.println("Requests history:");
mRequestsHistory.reverseDump(fd, pw, args);
@@ -353,7 +370,6 @@
@Override
public void onChange(boolean selfChange, Uri uri, int userId) {
- if (DEBUG) Slog.d(TAG, "settings (" + uri + " changed for " + userId);
synchronized (mLock) {
removeCachedServiceLocked(userId);
}
diff --git a/services/autofill/java/com/android/server/autofill/AutoFillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutoFillManagerServiceImpl.java
index 2dcb31c..88f1bda 100644
--- a/services/autofill/java/com/android/server/autofill/AutoFillManagerServiceImpl.java
+++ b/services/autofill/java/com/android/server/autofill/AutoFillManagerServiceImpl.java
@@ -16,69 +16,62 @@
package com.android.server.autofill;
-import static android.service.autofill.AutoFillService.FLAG_AUTHENTICATION_ERROR;
-import static android.service.autofill.AutoFillService.FLAG_AUTHENTICATION_REQUESTED;
-import static android.service.autofill.AutoFillService.FLAG_AUTHENTICATION_SUCCESS;
-import static android.view.View.AUTO_FILL_FLAG_TYPE_FILL;
-import static android.view.View.AUTO_FILL_FLAG_TYPE_SAVE;
-import static android.view.autofill.AutoFillManager.FLAG_UPDATE_UI_SHOW;
-import static android.view.autofill.AutoFillManager.FLAG_UPDATE_UI_HIDE;
+import static android.service.autofill.AutoFillService.EXTRA_ACTIVITY_TOKEN;
+import static android.service.voice.VoiceInteractionSession.KEY_RECEIVER_EXTRAS;
+import static android.service.voice.VoiceInteractionSession.KEY_STRUCTURE;
+import static android.view.autofill.AutoFillManager.FLAG_FOCUS_GAINED;
+import static android.view.autofill.AutoFillManager.FLAG_FOCUS_LOST;
+import static android.view.autofill.AutoFillManager.FLAG_START_SESSION;
+import static android.view.autofill.AutoFillManager.FLAG_VALUE_CHANGED;
import static com.android.server.autofill.Helper.DEBUG;
-import static com.android.server.autofill.Helper.bundleToString;
+import static com.android.server.autofill.Helper.VERBOSE;
+import static com.android.server.autofill.Helper.findValue;
import android.annotation.Nullable;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.IActivityManager;
import android.app.assist.AssistStructure;
+import android.app.assist.AssistStructure.ViewNode;
+import android.app.assist.AssistStructure.WindowNode;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
-import android.content.ServiceConnection;
+import android.content.IntentSender;
import android.content.pm.PackageManager;
import android.graphics.Rect;
-import android.hardware.fingerprint.Fingerprint;
-import android.hardware.fingerprint.IFingerprintService;
-import android.hardware.fingerprint.IFingerprintServiceReceiver;
-import android.os.Binder;
import android.os.Bundle;
-import android.os.DeadObjectException;
-import android.os.Handler;
import android.os.IBinder;
+import android.os.ICancellationSignal;
+import android.os.Looper;
import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.os.SystemClock;
-import android.os.UserHandle;
import android.service.autofill.AutoFillService;
import android.service.autofill.AutoFillServiceInfo;
+import android.service.autofill.FillCallback;
import android.service.autofill.IAutoFillAppCallback;
-import android.service.autofill.IAutoFillServerCallback;
import android.service.autofill.IAutoFillService;
-import android.service.voice.VoiceInteractionSession;
+import android.service.autofill.IFillCallback;
import android.util.ArrayMap;
+import android.util.ArraySet;
import android.util.LocalLog;
-import android.util.Log;
import android.util.PrintWriterPrinter;
import android.util.Slog;
-import android.util.SparseArray;
-import android.util.TimeUtils;
import android.view.autofill.AutoFillId;
import android.view.autofill.AutoFillValue;
import android.view.autofill.Dataset;
import android.view.autofill.FillResponse;
import com.android.internal.annotations.GuardedBy;
+import com.android.internal.os.HandlerCaller;
import com.android.internal.os.IResultReceiver;
+import com.android.server.FgThread;
import java.io.PrintWriter;
-import java.lang.ref.WeakReference;
-import java.util.Arrays;
-import java.util.LinkedList;
-import java.util.List;
import java.util.Map;
+import java.util.Map.Entry;
/**
* Bridge between the {@code system_server}'s {@link AutoFillManagerService} and the
@@ -89,28 +82,16 @@
private static final String TAG = "AutoFillManagerServiceImpl";
- /** Used do assign ids to new ServerCallback instances. */
- private static int sSessionIdCounter = 0;
+ private static final int MSG_SERVICE_SAVE = 1;
private final int mUserId;
- private final int mUid;
private final ComponentName mComponent;
private final String mComponentName;
private final Context mContext;
private final IActivityManager mAm;
private final Object mLock;
private final AutoFillServiceInfo mInfo;
- private final AutoFillManagerService mManagerService;
-
- // Token used for fingerprint authentication
- // TODO(b/33197203): create on demand?
- private final IBinder mAuthToken = new Binder();
-
- private final IFingerprintService mFingerprintService =
- IFingerprintService.Stub.asInterface(ServiceManager.getService("fingerprint"));
-
- @GuardedBy("mLock")
- private final List<QueuedRequest> mQueuedRequests = new LinkedList<>();
+ private final AutoFillUI mUi;
private final LocalLog mRequestsHistory;
@@ -120,14 +101,25 @@
if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(intent.getAction())) {
final String reason = intent.getStringExtra("reason");
if (DEBUG) Slog.d(TAG, "close system dialogs: " + reason);
- // TODO(b/33197203): close any pending UI like account selection (or remove this
- // receiver)
+ mUi.hideAll();
}
}
};
+ private final HandlerCaller.Callback mHandlerCallback = (msg) -> {
+ switch (msg.what) {
+ case MSG_SERVICE_SAVE:
+ handleSessionSave((IBinder) msg.obj);
+ break;
+ default:
+ Slog.d(TAG, "invalid msg: " + msg);
+ }
+ };
+
+ private final HandlerCaller mHandlerCaller = new HandlerCaller(null, Looper.getMainLooper(),
+ mHandlerCallback, true);
/**
- * Cache of pending {@link Session}s, keyed by {@link Session#mId}.
+ * Cache of pending {@link Session}s, keyed by {@code activityToken}.
*
* <p>They're kept until the {@link AutoFillService} finished handling a request, an error
* occurs, or the session times out.
@@ -135,199 +127,116 @@
// TODO(b/33197203): need to make sure service is bound while callback is pending and/or
// use WeakReference
@GuardedBy("mLock")
- private static final SparseArray<Session> mSessions = new SparseArray<>();
-
- private final ServiceConnection mConnection = new ServiceConnection() {
- @Override
- public void onServiceConnected(ComponentName name, IBinder service) {
- if (DEBUG) Slog.d(TAG, "onServiceConnected():" + name);
- synchronized (mLock) {
- mService = IAutoFillService.Stub.asInterface(service);
- try {
- mService.onConnected();
- } catch (RemoteException e) {
- Slog.w(TAG, "Exception on service.onConnected(): " + e);
- return;
- }
- if (!mQueuedRequests.isEmpty()) {
- if (DEBUG) Slog.d(TAG, "queued requests:" + mQueuedRequests.size());
- }
- for (final QueuedRequest request: mQueuedRequests) {
- requestAutoFillLocked(request.activityToken, request.autoFillId,
- request.bounds, request.flags, false);
- }
- mQueuedRequests.clear();
- }
- }
-
- @Override
- public void onServiceDisconnected(ComponentName name) {
- if (DEBUG) Slog.d(TAG, name + " disconnected");
- synchronized (mLock) {
- mService = null;
- mManagerService.removeCachedServiceLocked(mUserId);
- }
- }
- };
+ private final ArrayMap<IBinder, Session> mSessions = new ArrayMap<>();
/**
- * Receiver of assist data from the app's {@link Activity}, uses the {@code resultData} as
- * the {@link Session#mId}.
+ * Receiver of assist data from the app's {@link Activity}.
*/
private final IResultReceiver mAssistReceiver = new IResultReceiver.Stub() {
@Override
public void send(int resultCode, Bundle resultData) throws RemoteException {
if (DEBUG) Slog.d(TAG, "resultCode on mAssistReceiver: " + resultCode);
- final IBinder appBinder = resultData.getBinder(AutoFillService.KEY_CALLBACK);
- if (appBinder == null) {
- Slog.w(TAG, "no app callback on mAssistReceiver's resultData");
+ final AssistStructure structure = resultData.getParcelable(KEY_STRUCTURE);
+
+ if (structure == null) {
+ Slog.w(TAG, "no assist structure for id " + resultCode);
return;
}
- final AssistStructure structure = resultData
- .getParcelable(VoiceInteractionSession.KEY_STRUCTURE);
- final int flags = resultData.getInt(VoiceInteractionSession.KEY_FLAGS, 0);
+ final Bundle receiverExtras = resultData.getBundle(KEY_RECEIVER_EXTRAS);
+ if (receiverExtras == null) {
+ // Should not happen
+ Slog.wtf(TAG, "No " + KEY_RECEIVER_EXTRAS + " on receiver");
+ return;
+ }
+
+ final IBinder activityToken = receiverExtras.getBinder(EXTRA_ACTIVITY_TOKEN);
final Session session;
synchronized (mLock) {
- session = mSessions.get(resultCode);
+ session = mSessions.get(activityToken);
if (session == null) {
- Slog.w(TAG, "no server callback for id " + resultCode);
+ Slog.w(TAG, "no server session for activityToken " + activityToken);
return;
}
- session.setAppCallback(appBinder);
+ // TODO(b/33197203): since service is fetching the data (to use for save later),
+ // we should optimize what's sent (for example, remove layout containers,
+ // color / font info, etc...)
+ session.mStructure = structure;
}
- mService.autoFill(structure, session.mServerCallback, flags);
+
+ // TODO(b/33197203): Need to pipe the bundle
+ session.mRemoteFillService.onFillRequest(structure, null);
}
};
- @GuardedBy("mLock")
- private IAutoFillService mService;
- @GuardedBy("mLock")
- private boolean mBound;
- @GuardedBy("mLock")
- private boolean mValid;
-
- // Estimated time when the service will be evicted from the cache.
- long mEstimateTimeOfDeath;
-
- AutoFillManagerServiceImpl(AutoFillManagerService managerService, Context context, Object lock,
- LocalLog requestsHistory, Handler handler, int userId, int uid, ComponentName component,
- long ttl) {
- mManagerService = managerService;
+ AutoFillManagerServiceImpl(Context context, Object lock, LocalLog requestsHistory,
+ int userId, ComponentName component, AutoFillUI ui)
+ throws PackageManager.NameNotFoundException {
mContext = context;
mLock = lock;
mRequestsHistory = requestsHistory;
mUserId = userId;
- mUid = uid;
mComponent = component;
mComponentName = mComponent.flattenToShortString();
mAm = ActivityManager.getService();
- setLifeExpectancy(ttl);
+ mUi = ui;
+ mInfo = new AutoFillServiceInfo(context.getPackageManager(), component, mUserId);
- final AutoFillServiceInfo info;
- try {
- info = new AutoFillServiceInfo(context.getPackageManager(), component, mUserId);
- } catch (PackageManager.NameNotFoundException e) {
- Slog.w(TAG, "Auto-fill service not found: " + component, e);
- mInfo = null;
- mValid = false;
- return;
- }
- mInfo = info;
- if (mInfo.getParseError() != null) {
- Slog.w(TAG, "Bad auto-fill service: " + mInfo.getParseError());
- mValid = false;
- return;
- }
-
- mValid = true;
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
- mContext.registerReceiver(mBroadcastReceiver, filter, null, handler);
+ mContext.registerReceiver(mBroadcastReceiver, filter, null, FgThread.getHandler());
}
- void setLifeExpectancy(long ttl) {
- mEstimateTimeOfDeath = SystemClock.uptimeMillis() + ttl;
- }
-
- void startLocked() {
- if (DEBUG) Slog.d(TAG, "startLocked()");
-
- final Intent intent = new Intent(AutoFillService.SERVICE_INTERFACE);
- intent.setComponent(mComponent);
- mBound = mContext.bindServiceAsUser(intent, mConnection,
- Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE, new UserHandle(mUserId));
-
- if (!mBound) {
- Slog.w(TAG, "Failed binding to auto-fill service " + mComponent);
- return;
- }
- if (DEBUG) Slog.d(TAG, "Bound to " + mComponent);
- }
/**
- * Asks service to auto-fill an activity.
- *
- * @param activityToken activity token.
- * @param autoFillId id of the view that requested auto-fill.
- * @param flags optional flags.
+ * Used by {@link AutoFillManagerServiceShellCommand} to request save for the current top app.
*/
- void requestAutoFillLocked(IBinder activityToken, @Nullable AutoFillId autoFillId,
- @Nullable Rect bounds, int flags) {
- if (!mBound) {
- Slog.w(TAG, "requestAutoFill() failed because it's not bound to service");
+ void requestSaveForUserLocked(IBinder activityToken) {
+ final Session session = mSessions.get(activityToken);
+ if (session == null) {
+ Slog.w(TAG, "requestSaveForUserLocked(): no session for " + activityToken);
return;
}
- requestAutoFillLocked(activityToken, autoFillId, bounds, flags, true);
+ session.callSaveLocked();
}
- private void requestAutoFillLocked(IBinder activityToken, @Nullable AutoFillId autoFillId,
- @Nullable Rect bounds, int flags, boolean queueIfNecessary) {
- if (mService == null) {
- if (!queueIfNecessary) {
- Slog.w(TAG, "requestAutoFillLocked(): service is null");
- return;
- }
- if (DEBUG) Slog.d(TAG, "requestAutoFillLocked(): service not set yet, queuing it");
- mQueuedRequests.add(new QueuedRequest(activityToken, autoFillId, bounds, flags));
- return;
- }
- if (activityToken == null) {
- // Sanity check
- Slog.wtf(TAG, "requestAutoFillLocked(): null activityToken");
- return;
- }
-
- final String historyItem = "s=" + mComponentName + " u=" + mUserId + " f=" + flags
- + " a=" + activityToken + " i=" + autoFillId + " b=" + bounds;
+ void startSessionLocked(IBinder activityToken, IBinder appCallbackToken, AutoFillId autoFillId,
+ Rect bounds, AutoFillValue value) {
+ final String historyItem = "s=" + mComponentName + " u=" + mUserId + " a=" + activityToken
+ + " i=" + autoFillId + " b=" + bounds + " v=" + value;
mRequestsHistory.log(historyItem);
// TODO(b/33197203): Handle partitioning
- Session session = getOrCreateSessionByTokenLocked(activityToken);
- if (DEBUG) Slog.d(TAG, "using Session: " + session.mId);
-
- session.updateAutoFillInput(flags, autoFillId, null, bounds);
- }
-
- private Session getOrCreateSessionByTokenLocked(IBinder activityToken) {
- final int size = mSessions.size();
- for (int i = 0; i < size; i++) {
- final Session session = mSessions.valueAt(i);
- if (activityToken.equals(session.mActivityToken.get())) {
- return session;
- }
+ final Session session = mSessions.get(activityToken);
+ if (session != null) {
+ // Already started...
+ return;
}
- return createSessionByTokenLocked(activityToken);
+
+ final Session newSession = createSessionByTokenLocked(activityToken, appCallbackToken);
+ newSession.updateLocked(autoFillId, bounds, value, FLAG_START_SESSION);
+ newSession.enableSessionLocked();
}
- private Session createSessionByTokenLocked(IBinder activityToken) {
- final int sessionId = ++sSessionIdCounter;
- if (DEBUG) Slog.d(TAG, "creating Session: " + sessionId);
+ void finishSessionLocked(IBinder activityToken) {
+ if (DEBUG) Slog.d(TAG, "finishSessionLocked(): " + activityToken);
+ final Session session = mSessions.get(activityToken);
- final Session newSession = new Session(sessionId, activityToken);
- mSessions.put(sessionId, newSession);
+ if (session == null) {
+ Slog.w(TAG, "finishSessionLocked(): no session for " + activityToken);
+ return;
+ }
+
+ mUi.hideFillUi();
+ session.showSaveLocked();
+ }
+
+ private Session createSessionByTokenLocked(IBinder activityToken, IBinder appCallbackToken) {
+
+ final Session newSession = new Session(mContext, activityToken, appCallbackToken);
+ mSessions.put(activityToken, newSession);
/*
* TODO(b/33197203): apply security checks below:
@@ -338,8 +247,9 @@
*/
try {
// TODO(b/33197203): add MetricsLogger call
- if (!mAm.requestAutoFillData(
- mAssistReceiver, null, sessionId, activityToken, AUTO_FILL_FLAG_TYPE_FILL)) {
+ final Bundle receiverExtras = new Bundle();
+ receiverExtras.putBinder(EXTRA_ACTIVITY_TOKEN, activityToken);
+ if (!mAm.requestAutoFillData(mAssistReceiver, receiverExtras, activityToken)) {
// TODO(b/33197203): might need a way to warn user (perhaps a new method on
// AutoFillService).
Slog.w(TAG, "failed to request auto-fill data for " + activityToken);
@@ -350,79 +260,53 @@
return newSession;
}
- void stopLocked() {
- if (DEBUG) Slog.d(TAG, "stopLocked()");
+ void updateSessionLocked(IBinder activityToken, AutoFillId autoFillId, Rect bounds,
+ AutoFillValue value, int flags) {
- // Sanity check.
- if (mService == null) {
- Slog.w(TAG, "service already null on shutdown");
+ // TODO(b/33197203): add MetricsLogger call
+ final Session session = mSessions.get(activityToken);
+ if (session == null) {
+ Slog.w(TAG, "updateSessionLocked(): session gone for " + activityToken);
return;
}
- try {
- mService.onDisconnected();
- } catch (RemoteException e) {
- if (! (e instanceof DeadObjectException)) {
- Slog.w(TAG, "Exception calling service.onDisconnected(): " + e);
- }
- } finally {
- mService = null;
- }
- if (mBound) {
- mContext.unbindService(mConnection);
- mBound = false;
- }
- if (mValid) {
- mContext.unregisterReceiver(mBroadcastReceiver);
+ session.updateLocked(autoFillId, bounds, value, flags);
+ }
+
+ private void handleSessionSave(IBinder activityToken) {
+
+ synchronized (mLock) {
+ final Session session = mSessions.get(activityToken);
+ if (session == null) {
+ Slog.w(TAG, "handleSessionSave(): already gone: " + activityToken);
+
+ return;
+ }
+ session.callSaveLocked();
}
}
- void removeSessionLocked(int id) {
- if (DEBUG) Slog.d(TAG, "Removing session " + id);
- mSessions.remove(id);
+ void destroyLocked() {
+ if (VERBOSE) Slog.v(TAG, "destroyLocked()");
- // TODO(b/33197203): notify mService so it can invalidate the FillCallback / SaveCallback?
+ mContext.unregisterReceiver(mBroadcastReceiver);
+ for (Session session : mSessions.values()) {
+ session.destroyLocked();
+ }
+ mSessions.clear();
}
void dumpLocked(String prefix, PrintWriter pw) {
- if (!mValid) {
- pw.print(" NOT VALID: ");
- if (mInfo == null) {
- pw.println("no info");
- } else {
- pw.println(mInfo.getParseError());
- }
- return;
- }
-
final String prefix2 = prefix + " ";
- pw.print(prefix); pw.print("mUserId="); pw.println(mUserId);
- pw.print(prefix); pw.print("mUid="); pw.println(mUid);
- pw.print(prefix); pw.print("mComponent="); pw.println(mComponentName);
- pw.print(prefix); pw.print("mService: "); pw.println(mService);
- pw.print(prefix); pw.print("mBound="); pw.println(mBound);
- pw.print(prefix); pw.print("mEstimateTimeOfDeath=");
- TimeUtils.formatDuration(mEstimateTimeOfDeath, SystemClock.uptimeMillis(), pw);
- pw.println();
- pw.print(prefix); pw.print("mAuthToken: "); pw.println(mAuthToken);
+ pw.print(prefix); pw.println("Component:"); pw.println(mComponentName);
- if (DEBUG) {
+ if (VERBOSE) {
// ServiceInfo dump is too noisy and redundant (it can be obtained through other dumps)
pw.print(prefix); pw.println("ServiceInfo:");
mInfo.getServiceInfo().dump(new PrintWriterPrinter(pw), prefix + prefix);
}
- if (mQueuedRequests.isEmpty()) {
- pw.print(prefix); pw.println("No queued requests");
- } else {
- pw.print(prefix); pw.println("Queued requests:");
- for (int i = 0; i < mQueuedRequests.size(); i++) {
- pw.print(prefix2); pw.print(i); pw.print(": "); pw.println(mQueuedRequests.get(i));
- }
- }
-
- pw.print(prefix); pw.print("sSessionIdCounter="); pw.println(sSessionIdCounter);
final int size = mSessions.size();
if (size == 0) {
pw.print(prefix); pw.println("No sessions");
@@ -437,32 +321,10 @@
@Override
public String toString() {
- return "AutoFillManagerServiceImpl: [userId=" + mUserId + ", uid=" + mUid
+ return "AutoFillManagerServiceImpl: [userId=" + mUserId
+ ", component=" + mComponentName + "]";
}
- private static final class QueuedRequest {
- final IBinder activityToken;
- final AutoFillId autoFillId;
- final Rect bounds;
- final int flags;
-
- QueuedRequest(IBinder activityToken, AutoFillId autoFillId, Rect bounds, int flags) {
- this.activityToken = activityToken;
- this.autoFillId = autoFillId;
- this.bounds = bounds;
- this.flags = flags;
- }
-
- @Override
- public String toString() {
- if (!DEBUG) return super.toString();
-
- return "QueuedRequest: [flags=" + flags + ", token=" + activityToken
- + ", id=" + autoFillId + ", bounds=" + bounds;
- }
- }
-
/**
* State for a given view with a AutoFillId.
*
@@ -478,13 +340,17 @@
@Nullable AutoFillValue value);
}
+ final AutoFillId mId;
private final Listener mListener;
- @Nullable
+ // // TODO(b/33197203): does it really need a reference to the session's response?
private FillResponse mResponse;
private AutoFillValue mAutoFillValue;
private Rect mBounds;
- ViewState(Listener listener) {
+ private boolean mValueUpdated;
+
+ ViewState(AutoFillId id, Listener listener) {
+ mId = id;
mListener = listener;
}
@@ -492,15 +358,13 @@
* Response should only be set once.
*/
void setResponse(FillResponse response) {
- if (mResponse != null) {
- Slog.e(TAG, "ViewState response set more than once");
- return;
- }
mResponse = response;
-
maybeCallOnFillReady();
}
+ // TODO(b/33197203): need to refactor / rename / document this method to make it clear that
+ // it can change the value and update the UI; similarly, should replace code that
+ // directly sets mAutoFilLValue to use encapsulation.
void update(@Nullable AutoFillValue autoFillValue, @Nullable Rect bounds) {
if (autoFillValue != null) {
mAutoFillValue = autoFillValue;
@@ -526,16 +390,24 @@
public String toString() {
if (!DEBUG) return super.toString();
- return "ViewState: [response=" + mResponse + ", value=" + mAutoFillValue
- + ", bounds=" + mBounds + "]";
+ return "ViewState: [id=" + mId + ", value=" + mAutoFillValue + ", bounds=" + mBounds
+ + ", updated = " + mValueUpdated + "]";
}
+
+ void dump(String prefix, PrintWriter pw) {
+ pw.print(prefix); pw.print("id:" ); pw.println(mId);
+ pw.print(prefix); pw.print("value:" ); pw.println(mAutoFillValue);
+ pw.print(prefix); pw.print("updated:" ); pw.println(mValueUpdated);
+ pw.print(prefix); pw.print("bounds:" ); pw.println(mBounds);
+ }
+
}
/**
* A session for a given activity.
*
* <p>This class manages the multiple {@link ViewState}s for each view it has, and keeps track
- * of the current view session to display the appropriate UI.
+ * of the current {@link ViewState} to display the appropriate UI.
*
* <p>Although the auto-fill requests and callbacks are stateless from the service's point of
* view, we need to keep state in the framework side for cases such as authentication. For
@@ -547,242 +419,283 @@
// - On all authentication scenarios.
// - When user does not interact back after a while.
// - When service is unbound.
- final class Session implements ViewState.Listener {
-
- private final AutoFillUI mUi;
- final int mId;
- private final WeakReference<IBinder> mActivityToken;
+ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState.Listener,
+ AutoFillUI.AutoFillUiCallback {
+ private final IBinder mActivityToken;
@GuardedBy("mLock")
private final Map<AutoFillId, ViewState> mViewStates = new ArrayMap<>();
+
@GuardedBy("mLock")
@Nullable
private ViewState mCurrentViewState;
- private IAutoFillAppCallback mAppCallback;
+ private final IAutoFillAppCallback mAppCallback;
+
+ @GuardedBy("mLock")
+ RemoteFillService mRemoteFillService;
// TODO(b/33197203): Get a response per view instead of per activity.
@GuardedBy("mLock")
private FillResponse mCurrentResponse;
+
+ /**
+ * Used to remember which {@link Dataset} filled the session.
+ */
+ // TODO(b/33197203): might need more than one once we support partitions
@GuardedBy("mLock")
- private FillResponse mResponseRequiringAuth;
+ private Dataset mAutoFilledDataset;
+
+ /**
+ * Assist structure sent by the app; it will be updated (sanitized, change values for save)
+ * before sent to {@link AutoFillService}.
+ */
@GuardedBy("mLock")
- private Dataset mDatasetRequiringAuth;
+ private AssistStructure mStructure;
- // Used to auto-fill the activity directly when the FillCallback.onResponse() is called as
- // the result of a successful user authentication on service's side.
- @GuardedBy("mLock")
- private boolean mAutoFillDirectly;
+ private Session(Context context, IBinder activityToken, IBinder appCallback) {
+ mRemoteFillService = new RemoteFillService(context, mComponent, mUserId, this);
+ mActivityToken = activityToken;
- // TODO(b/33197203): use handler to handle results?
- // TODO(b/33197203): handle all callback methods and/or cancelation?
- private IFingerprintServiceReceiver mServiceReceiver =
- new IFingerprintServiceReceiver.Stub() {
-
- @Override
- public void onEnrollResult(long deviceId, int fingerId, int groupId, int remaining) {
- if (DEBUG) Slog.d(TAG, "onEnrollResult()");
- }
-
- @Override
- public void onAcquired(long deviceId, int acquiredInfo, int vendorCode) {
- if (DEBUG) Slog.d(TAG, "onAcquired()");
- }
-
- @Override
- public void onAuthenticationSucceeded(long deviceId, Fingerprint fp, int userId) {
- if (DEBUG) Slog.d(TAG, "onAuthenticationSucceeded(): " + fp.getGroupId());
-
- // First, check what was authenticated, a response or a dataset.
- // Then, decide how to handle it:
- // - If service provided data, handle them directly.
- // - Otherwise, notify service.
-
- mAutoFillDirectly = true;
-
- if (mDatasetRequiringAuth != null) {
- if (mDatasetRequiringAuth.isEmpty()) {
- notifyDatasetAuthenticationResult(mDatasetRequiringAuth.getExtras(),
- FLAG_AUTHENTICATION_SUCCESS);
- } else {
- autoFillApp(mDatasetRequiringAuth);
- }
- } else if (mResponseRequiringAuth != null) {
- final List<Dataset> datasets = mResponseRequiringAuth.getDatasets();
- if (datasets.isEmpty()) {
- notifyResponseAuthenticationResult(mResponseRequiringAuth.getExtras(),
- FLAG_AUTHENTICATION_SUCCESS);
- } else {
- showResponseLocked(mResponseRequiringAuth, true);
- }
- } else {
- Slog.w(TAG, "onAuthenticationSucceeded(): no response or dataset");
- }
-
- mUi.dismissFingerprintRequest(true);
- }
-
- @Override
- public void onAuthenticationFailed(long deviceId) {
- if (DEBUG) Slog.d(TAG, "onAuthenticationFailed()");
- // Do nothing - onError() will be called after a few failures...
- }
-
- @Override
- public void onError(long deviceId, int error, int vendorCode) {
- if (DEBUG) Slog.d(TAG, "onError()");
-
- // Notify service so it can fallback to its own authentication
- if (mDatasetRequiringAuth != null) {
- notifyDatasetAuthenticationResult(mDatasetRequiringAuth.getExtras(),
- FLAG_AUTHENTICATION_ERROR);
- } else if (mResponseRequiringAuth != null) {
- notifyResponseAuthenticationResult(mResponseRequiringAuth.getExtras(),
- FLAG_AUTHENTICATION_ERROR);
- } else {
- Slog.w(TAG, "onError(): no response or dataset");
- }
-
- mUi.dismissFingerprintRequest(false);
- }
-
- @Override
- public void onRemoved(long deviceId, int fingerId, int groupId, int remaining) {
- if (DEBUG) Slog.d(TAG, "onRemoved()");
- }
-
- @Override
- public void onEnumerated(long deviceId, int fingerId, int groupId, int remaining) {
- if (DEBUG) Slog.d(TAG, "onEnumerated()");
- }
- };
-
- private IAutoFillServerCallback mServerCallback = new IAutoFillServerCallback.Stub() {
- @Override
- public void showResponse(FillResponse response) {
- // TODO(b/33197203): add MetricsLogger call
- if (response == null) {
- if (DEBUG) Slog.d(TAG, "showResponse(): null response");
- removeSelf();
- return;
- }
-
- synchronized (mLock) {
- showResponseLocked(response, response.isAuthRequired());
- }
- }
-
- @Override
- public void showError(CharSequence message) {
- // TODO(b/33197203): add MetricsLogger call
- if (DEBUG) Slog.d(TAG, "showError(): " + message);
-
- mUi.showError(message);
-
- removeSelf();
- }
-
- @Override
- public void highlightSavedFields(AutoFillId[] ids) {
- // TODO(b/33197203): add MetricsLogger call
- if (DEBUG) Slog.d(TAG, "highlightSavedFields(): " + Arrays.toString(ids));
-
- mUi.highlightSavedFields(ids);
-
- removeSelf();
- }
-
- @Override
- public void unlockFillResponse(int flags) {
- // TODO(b/33197203): add proper MetricsLogger calls?
- if (DEBUG) Log.d(TAG, "unlockUser(): flags=" + flags);
-
- synchronized (mLock) {
- if ((flags & FLAG_AUTHENTICATION_SUCCESS) != 0) {
- if (mResponseRequiringAuth == null) {
- Log.wtf(TAG, "unlockUser(): no mResponseRequiringAuth on flags "
- + flags);
- removeSelf();
- return;
- }
- final List<Dataset> datasets = mResponseRequiringAuth.getDatasets();
- if (datasets.isEmpty()) {
- Log.w(TAG, "unlockUser(): no dataset on previous response: "
- + mResponseRequiringAuth);
- removeSelf();
- return;
- }
- mAutoFillDirectly = true;
- showResponseLocked(mResponseRequiringAuth, false);
- }
- // TODO(b/33197203): show UI error on authentication failure?
- // Or let service handle it?
- }
- }
-
- @Override
- public void unlockDataset(Dataset dataset, int flags) {
- // TODO(b/33197203): add proper MetricsLogger calls?
- if (DEBUG) Log.d(TAG, "unlockDataset(): dataset=" + dataset + ", flags=" + flags);
-
- if ((flags & FLAG_AUTHENTICATION_SUCCESS) != 0) {
- autoFillApp(dataset != null ? dataset : mDatasetRequiringAuth);
- return;
- }
- }
- };
-
- private Session(int id, IBinder activityToken) {
- mUi = new AutoFillUI(mContext, this);
- mId = id;
- mActivityToken = new WeakReference<>(activityToken);
- }
-
- void setAppCallback(IBinder appBinder) {
+ mAppCallback = IAutoFillAppCallback.Stub.asInterface(appCallback);
try {
- appBinder.linkToDeath(() -> {
- if (DEBUG) Slog.d(TAG, "app callback died");
- // TODO(b/33197203): more cleanup here?
- mAppCallback = null;
+ appCallback.linkToDeath(() -> {
+ if (DEBUG) Slog.d(TAG, "app binder died");
+
+ removeSelf();
}, 0);
} catch (RemoteException e) {
- Slog.w(TAG, "linkToDeath() failed: " + e);
+ Slog.w(TAG, "linkToDeath() on mAppCallback failed: " + e);
}
- mAppCallback = IAutoFillAppCallback.Stub.asInterface(appBinder);
}
- void updateAutoFillInput(int flags, AutoFillId autoFillId,
- @Nullable AutoFillValue autoFillValue, @Nullable Rect bounds) {
+
+ // FillServiceCallbacks
+ @Override
+ public void onFillRequestSuccess(FillResponse response) {
+ // TODO(b/33197203): add MetricsLogger call
+ if (response == null) {
+ removeSelf();
+ return;
+ }
synchronized (mLock) {
- ViewState viewState = mViewStates.get(autoFillId);
- if (viewState == null) {
- viewState = new ViewState(this);
- mViewStates.put(autoFillId, viewState);
- }
+ processResponseLocked(response);
+ }
+ }
- if ((flags & FLAG_UPDATE_UI_SHOW) != 0) {
- // Remove the UI if the ViewState has changed.
- if (mCurrentViewState != viewState) {
- mUi.hideFillUi();
- mCurrentViewState = viewState;
+ // FillServiceCallbacks
+ @Override
+ public void onFillRequestFailure(CharSequence message) {
+ // TODO(b/33197203): add MetricsLogger call
+ getUiForShowing().showError(message);
+ removeSelf();
+ }
+
+ // FillServiceCallbacks
+ @Override
+ public void onSaveRequestSuccess() {
+ // TODO(b/33197203): add MetricsLogger call
+ // Nothing left to do...
+ removeSelf();
+ }
+
+ // FillServiceCallbacks
+ @Override
+ public void onSaveRequestFailure(CharSequence message) {
+ // TODO(b/33197203): add MetricsLogger call
+ getUiForShowing().showError(message);
+ removeSelf();
+ }
+
+ // FillServiceCallbacks
+ @Override
+ public void authenticate(IntentSender intent, Intent fillInIntent) {
+ startAuthIntent(intent, fillInIntent);
+ }
+
+ // FillServiceCallbacks
+ @Override
+ public void onServiceDied(RemoteFillService service) {
+ // TODO(b/33197203): implement
+ }
+
+ // AutoFillUiCallback
+ @Override
+ public void fill(Dataset dataset) {
+ autoFill(dataset);
+ }
+
+ // AutoFillUiCallback
+ @Override
+ public void save() {
+ mHandlerCaller.getHandler().obtainMessage(MSG_SERVICE_SAVE, mActivityToken)
+ .sendToTarget();
+ }
+
+ /**
+ * Show the save UI, when session can be saved.
+ */
+ public void showSaveLocked() {
+ if (mStructure == null) {
+ // Sanity check; should not happen...
+ Slog.wtf(TAG, "showSaveLocked(): no mStructure");
+ return;
+ }
+ final ArraySet<AutoFillId> savableIds = mCurrentResponse.getSavableIds();
+ if (VERBOSE) Slog.v(TAG, "showSaveLocked(): savableIds=" + savableIds);
+
+ if (savableIds.isEmpty()) {
+ if (DEBUG) Slog.d(TAG, "showSaveLocked(): service doesn't want to save");
+ return;
+ }
+
+ final int size = savableIds.size();
+ for (int i = 0; i < size; i++) {
+ final AutoFillId id = savableIds.valueAt(i);
+ final ViewState state = mViewStates.get(id);
+ if (state != null && state.mValueUpdated) {
+ final AutoFillValue filledValue = findValue(mAutoFilledDataset, id);
+ if (state.mAutoFillValue == null || state.mAutoFillValue.equals(filledValue)) {
+ continue;
+ }
+ if (DEBUG) {
+ Slog.d(TAG, "finishSessionLocked(): found a change on " + id + ": "
+ + state.mAutoFillValue);
}
- // If the ViewState is ready to be displayed, onReady() will be called.
- viewState.update(autoFillValue, bounds);
-
- // TODO(b/33197203): Remove when there is a response per activity.
- if (mCurrentResponse != null) {
- viewState.setResponse(mCurrentResponse);
- }
- } else if ((flags & FLAG_UPDATE_UI_HIDE) != 0) {
- if (mCurrentViewState == viewState) {
- mUi.hideFillUi();
- mCurrentViewState = null;
- }
- } else {
- Slog.w(TAG, "unknown flags " + flags);
+ mUi.showSaveUi();
+ return;
}
}
+ // Nothing changed...
+ if (DEBUG) Slog.d(TAG, "showSaveLocked(): with no changes, comes no responsibilities");
+ }
+
+ /**
+ * Calls service when user requested save.
+ */
+ private void callSaveLocked() {
+ if (DEBUG) Slog.d(TAG, "callSaveLocked(): mViewStates=" + mViewStates);
+
+ // TODO(b/33197203): hookup extras and make sure they're tested by CTS
+ final Bundle extras = null;
+// // TODO(b/33197203): make sure the extras are tested by CTS
+// final Bundle responseExtras = mCurrentResponse == null ? null
+// : mCurrentResponse.getExtras();
+// final Bundle datasetExtras = mAutoFilledDataset == null ? null
+// : mAutoFilledDataset.getExtras();
+// final Bundle extras = (responseExtras == null && datasetExtras == null)
+// ? null : new Bundle();
+// if (responseExtras != null) {
+// if (DEBUG) {
+// Slog.d(TAG, "response extras on save extras: "
+// + bundleToString(responseExtras));
+// }
+// extras.putBundle(AutoFillService.EXTRA_RESPONSE_EXTRAS, responseExtras);
+// }
+// if (datasetExtras != null) {
+// if (DEBUG) {
+// Slog.d(TAG, "dataset extras on save extras: " + bundleToString(datasetExtras));
+// }
+// extras.putBundle(AutoFillService.EXTRA_DATASET_EXTRAS, datasetExtras);
+// }
+
+
+ for (Entry<AutoFillId, ViewState> entry : mViewStates.entrySet()) {
+ final AutoFillValue value = entry.getValue().mAutoFillValue;
+ if (value == null) {
+ if (VERBOSE) Slog.v(TAG, "callSaveLocked(): skipping " + entry.getKey());
+ continue;
+ }
+ final AutoFillId id = entry.getKey();
+ final ViewNode node = findViewNodeByIdLocked(id);
+ if (node == null) {
+ Slog.w(TAG, "callSaveLocked(): did not find node with id " + id);
+ continue;
+ }
+ if (DEBUG) Slog.d(TAG, "callSaveLocked(): updating " + id + " to " + value);
+
+ node.updateAutoFillValue(value);
+ }
+
+ mStructure.sanitizeForParceling(false);
+
+ if (VERBOSE) {
+ Slog.v(TAG, "Dumping " + mStructure + " before calling service.save()");
+ mStructure.dump();
+ }
+
+ mRemoteFillService.onSaveRequest(mStructure, extras);
+ }
+
+ void updateLocked(AutoFillId id, Rect bounds, AutoFillValue value, int flags) {
+ if (DEBUG) Slog.d(TAG, "updateLocked(): id=" + id + ", flags=" + flags);
+
+ if (mAutoFilledDataset != null && (flags & FLAG_VALUE_CHANGED) == 0) {
+ // TODO(b/33197203): ignoring because we don't support partitions yet
+ if (DEBUG) Slog.d(TAG, "updateLocked(): ignoring " + flags + " after auto-filled");
+ return;
+ }
+
+ ViewState viewState = mViewStates.get(id);
+ if (viewState == null) {
+ viewState = new ViewState(id, this);
+ mViewStates.put(id, viewState);
+ }
+
+ if ((flags & FLAG_START_SESSION) != 0 ) {
+ // View is triggering auto-fill.
+ mCurrentViewState = viewState;
+ viewState.update(value, bounds);
+ return;
+ }
+
+ if ((flags & FLAG_VALUE_CHANGED) != 0 && value != null &&
+ !value.equals(viewState.mAutoFillValue)) {
+ viewState.mValueUpdated = true;
+
+ // Must check if this update was caused by auto-filling the view, in which
+ // case we just update the value, but not the UI.
+ if (mAutoFilledDataset != null) {
+ final AutoFillValue filledValue = findValue(mAutoFilledDataset, id);
+ if (value.equals(filledValue)) {
+ viewState.mAutoFillValue = value;
+ return;
+ }
+ }
+
+ // Just change value, don't update the UI
+ viewState.mAutoFillValue = value;
+ return;
+ }
+
+ if ((flags & FLAG_FOCUS_GAINED) != 0) {
+ // Remove the UI if the ViewState has changed.
+ if (mCurrentViewState != viewState) {
+ mUi.hideFillUi();
+ mCurrentViewState = viewState;
+ }
+
+ // If the ViewState is ready to be displayed, onReady() will be called.
+ viewState.update(value, bounds);
+
+ // TODO(b/33197203): Remove when there is a response per activity.
+ if (mCurrentResponse != null) {
+ viewState.setResponse(mCurrentResponse);
+ }
+
+ return;
+ }
+
+ if ((flags & FLAG_FOCUS_LOST) != 0) {
+ if (mCurrentViewState == viewState) {
+ mUi.hideFillUi();
+ mCurrentViewState = null;
+ }
+ return;
+ }
+
+ Slog.w(TAG, "unknown flags " + flags);
}
@Override
@@ -796,218 +709,292 @@
filterText = text.toString();
}
}
- mUi.showFillUi(viewState, response.getDatasets(), bounds, filterText);
+ getUiForShowing().showFillUi(viewState, response.getDatasets(), bounds, filterText);
}
- private void showResponseLocked(FillResponse response, boolean authRequired) {
- if (DEBUG) Slog.d(TAG, "showResponse(directly=" + mAutoFillDirectly
- + ", authRequired=" + authRequired +"):" + response);
+ private void processResponseLocked(FillResponse response) {
+ if (DEBUG) Slog.d(TAG, "processResponseLocked(authRequired="
+ + response.getAuthentication() +"):" + response);
- if (mAutoFillDirectly && response != null) {
- final List<Dataset> datasets = response.getDatasets();
- if (datasets.size() == 1) {
- // User authenticated and provider returned just 1 dataset - auto-fill it now!
- final Dataset dataset = datasets.get(0);
- if (DEBUG) Slog.d(TAG, "auto-filling directly from auth: " + dataset);
+ // TODO(b/33197203): add MetricsLogger calls
- autoFillApp(dataset);
- return;
- }
+ mCurrentResponse = response;
+
+ if (mCurrentResponse.getAuthentication() != null) {
+ // Handle authentication.
+ final Intent fillInIntent = createAuthFillInIntent(response.getId(), mStructure,
+ new Bundle(), new FillCallback(new IFillCallback.Stub() {
+ @Override
+ public void onCancellable(ICancellationSignal cancellation) {
+ // TODO(b/33197203): Handle cancellation
+ }
+
+ @Override
+ public void onSuccess(FillResponse response) {
+ mCurrentResponse = createAuthenticatedResponse(
+ mCurrentResponse, response);
+ processResponseLocked(mCurrentResponse);
+ }
+
+ @Override
+ public void onFailure(CharSequence message) {
+ getUiForShowing().showError(message);
+ removeSelf();
+ }
+ }));
+
+ getUiForShowing().showFillResponseAuthRequest(
+ mCurrentResponse.getAuthentication(), fillInIntent);
+ return;
}
- if (!authRequired) {
- // TODO(b/33197203): add MetricsLogger call
- mCurrentResponse = response;
- // TODO(b/33197203): Consider using mCurrentResponse, depends on partitioning design
- if (mCurrentViewState != null) {
- mCurrentViewState.setResponse(mCurrentResponse);
- }
+ final ArraySet<AutoFillId> savableIds = mCurrentResponse.getSavableIds();
+ if (savableIds == null || savableIds.isEmpty()) {
+ // NOTE: it's assuming the response has no datasets, since when a dataset is added
+ // it's view id is automatically added to savable_ids
+ if (DEBUG) Slog.d(TAG, "processResponseLocked(): nothing to do");
+
+ removeSelf();
return;
}
- // Handles response that requires authentication.
- // TODO(b/33197203): add MetricsLogger call, including if fingerprint requested
-
- mResponseRequiringAuth = response;
- final boolean requiresFingerprint = response.hasCryptoObject();
- if (requiresFingerprint) {
- // TODO(b/33197203): check if fingerprint is available first and call error callback
- // with FLAG_FINGERPRINT_AUTHENTICATION_NOT_AVAILABLE if it's not.
- // Start scanning for the fingerprint.
- scanFingerprint(response.getCryptoObjectOpId());
+ // TODO(b/33197203): Consider using mCurrentResponse, depends on partitioning design
+ if (mCurrentViewState != null) {
+ mCurrentViewState.setResponse(mCurrentResponse);
}
- // Displays the message asking the user to tap (or fingerprint) for AutoFill.
- mUi.showFillResponseAuthenticationRequest(requiresFingerprint,
- response.getExtras(), response.getFlags());
}
void autoFill(Dataset dataset) {
synchronized (mLock) {
// Autofill it directly...
- if (!dataset.isAuthRequired()) {
+ if (dataset.getAuthentication() == null) {
autoFillApp(dataset);
return;
}
// ...or handle authentication.
-
- mDatasetRequiringAuth = dataset;
- final boolean requiresFingerprint = dataset.hasCryptoObject();
- if (requiresFingerprint) {
- // TODO(b/33197203): check if fingerprint is available first and call error
- // callback with FLAG_FINGERPRINT_AUTHENTICATION_NOT_AVAILABLE if it's not.
- // Start scanning for the fingerprint.
- scanFingerprint(dataset.getCryptoObjectOpId());
- // Displays the message asking the user to tap (or fingerprint) for AutoFill.
- mUi.showDatasetFingerprintAuthenticationRequest(dataset);
- } else {
- try {
- mService.authenticateDataset(dataset.getExtras(),
- FLAG_AUTHENTICATION_REQUESTED);
- } catch (RemoteException e) {
- Slog.w(TAG, "Error authenticating dataset: " + e);
+ Intent fillInIntent = createAuthFillInIntent(dataset.getId(), mStructure,
+ new Bundle(), new FillCallback(new IFillCallback.Stub() {
+ @Override
+ public void onCancellable(ICancellationSignal cancellation) {
+ // TODO(b/33197203): Handle cancellation
}
- }
+
+ @Override
+ public void onSuccess(FillResponse response) {
+ mCurrentResponse = createAuthenticatedResponse(
+ mCurrentResponse, response);
+ final Dataset augmentedDataset = Helper.findDatasetById(dataset.getId(),
+ mCurrentResponse);
+ if (augmentedDataset != null) {
+ autoFill(augmentedDataset);
+ }
+ }
+
+ @Override
+ public void onFailure(CharSequence message) {
+ getUiForShowing().showError(message);
+ removeSelf();
+ }
+ }));
+
+ startAuthIntent(dataset.getAuthentication(), fillInIntent);
+ }
+ }
+
+ private Intent createAuthFillInIntent(String itemId, AssistStructure structure,
+ Bundle extras, FillCallback fillCallback) {
+ Intent fillInIntent = new Intent();
+ fillInIntent.putExtra(Intent.EXTRA_AUTO_FILL_ITEM_ID, itemId);
+ fillInIntent.putExtra(Intent.EXTRA_AUTO_FILL_ASSIST_STRUCTURE, structure);
+ fillInIntent.putExtra(Intent.EXTRA_AUTO_FILL_EXTRAS, extras);
+ fillInIntent.putExtra(Intent.EXTRA_AUTO_FILL_CALLBACK, fillCallback);
+ return fillInIntent;
+ }
+
+ private void startAuthIntent(IntentSender intent, Intent fillInIntent) {
+ try {
+ mAppCallback.startIntentSender(intent, fillInIntent);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Error launching auth intent", e);
}
}
void dumpLocked(String prefix, PrintWriter pw) {
- pw.print(prefix); pw.print("mId: "); pw.println(mId);
- pw.print(prefix); pw.print("mActivityToken: "); pw.println(mActivityToken.get());
+ pw.print(prefix); pw.print("mActivityToken: "); pw.println(mActivityToken);
pw.print(prefix); pw.print("mCurrentResponse: "); pw.println(mCurrentResponse);
- pw.print(prefix);
- pw.print("mResponseRequiringAuth: "); pw.println(mResponseRequiringAuth);
- pw.print(prefix);
- pw.print("mDatasetRequiringAuth: "); pw.println(mDatasetRequiringAuth);
- pw.print(prefix); pw.print("mAutoFillDirectly: "); pw.println(mAutoFillDirectly);
+ pw.print(prefix); pw.print("mAutoFilledDataset: "); pw.println(mAutoFilledDataset);
pw.print(prefix); pw.print("mCurrentViewStates: "); pw.println(mCurrentViewState);
pw.print(prefix); pw.print("mViewStates: "); pw.println(mViewStates.size());
final String prefix2 = prefix + " ";
for (Map.Entry<AutoFillId, ViewState> entry : mViewStates.entrySet()) {
- pw.print(prefix2);
- pw.print(entry.getKey()); pw.print(": " ); pw.println(entry.getValue());
+ pw.print(prefix); pw.print("State for id "); pw.println(entry.getKey());
+ entry.getValue().dump(prefix2, pw);
}
- }
-
- /**
- * Notifies the result of a {@link FillResponse} authentication request to the service.
- *
- * <p>Typically called by the UI after user taps the "Tap to autofill" affordance, or after user
- * used the fingerprint sensors to authenticate.
- */
- void notifyResponseAuthenticationResult(Bundle extras, int flags) {
- if (DEBUG) Slog.d(TAG, "notifyResponseAuthenticationResult(): flags=" + flags
- + ", extras=" + bundleToString(extras));
- synchronized (mLock) {
- try {
- mService.authenticateFillResponse(extras, flags);
- } catch (RemoteException e) {
- Slog.w(TAG, "Error sending authentication result back to service: " + e);
+ if (VERBOSE) {
+ pw.print(prefix); pw.print("mStructure: " );
+ // TODO(b/33197203): add method do dump AssistStructure on pw
+ if (mStructure != null) {
+ pw.println("look at logcat" );
+ mStructure.dump(); // dumps to logcat
+ } else {
+ pw.println("null");
}
}
- }
- /**
- * Notifies the result of a {@link Dataset} authentication request to the service.
- *
- * <p>Typically called by the UI after user taps the "Tap to autofill" affordance, or after
- * it gets the results from a fingerprint authentication.
- */
- void notifyDatasetAuthenticationResult(Bundle extras, int flags) {
- if (DEBUG) Slog.d(TAG, "notifyDatasetAuthenticationResult(): flags=" + flags
- + ", extras=" + bundleToString(extras));
- synchronized (mLock) {
- try {
- mService.authenticateDataset(extras, flags);
- } catch (RemoteException e) {
- Slog.w(TAG, "Error sending authentication result back to service: " + e);
- }
- }
+ mRemoteFillService.dump(prefix, pw);
}
void autoFillApp(Dataset dataset) {
synchronized (mLock) {
try {
if (DEBUG) Slog.d(TAG, "autoFillApp(): the buck is on the app: " + dataset);
+
mAppCallback.autoFill(dataset);
+ mAutoFilledDataset = dataset;
} catch (RemoteException e) {
Slog.w(TAG, "Error auto-filling activity: " + e);
}
}
}
- void requestSave() {
+ void enableSessionLocked() {
+ if (DEBUG) Slog.d(TAG, "enableSessionLocked()");
+
+ try {
+ mAppCallback.enableSession();
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Error enabling session: " + e);
+ }
+ }
+
+ private AutoFillUI getUiForShowing() {
+ mUi.setCallback(this, mActivityToken);
+ return mUi;
+ }
+
+ private ViewNode findViewNodeByIdLocked(AutoFillId id) {
+ final int size = mStructure.getWindowNodeCount();
+ for (int i = 0; i < size; i++) {
+ final WindowNode window = mStructure.getWindowNodeAt(i);
+ final ViewNode root = window.getRootViewNode();
+ if (id.equals(root.getAutoFillId())) {
+ return root;
+ }
+ final ViewNode child = findViewNodeByIdLocked(root, id);
+ if (child != null) {
+ return child;
+ }
+ }
+ return null;
+ }
+
+ private ViewNode findViewNodeByIdLocked(ViewNode parent, AutoFillId id) {
+ final int childrenSize = parent.getChildCount();
+ if (childrenSize > 0) {
+ for (int i = 0; i < childrenSize; i++) {
+ final ViewNode child = parent.getChildAt(i);
+ if (id.equals(child.getAutoFillId())) {
+ return child;
+ }
+ final ViewNode grandChild = findViewNodeByIdLocked(child, id);
+ if (grandChild != null && id.equals(grandChild.getAutoFillId())) {
+ return grandChild;
+ }
+ }
+ }
+ return null;
+ }
+
+ private void destroyLocked() {
+ mRemoteFillService.destroy();
+ mUi.hideAll();
+ mUi.setCallback(null, null);
+ }
+
+ private void removeSelf() {
+ if (VERBOSE) Slog.v(TAG, "removeSelf()");
+
synchronized (mLock) {
- requestSaveLocked(mId);
+ destroyLocked();
+ mSessions.remove(mActivityToken);
}
}
/**
- * Called by UI to trigger a save request to the service.
+ * Creates a response from the {@code original} and an {@code update} by
+ * replacing all items that needed authentication (response or datasets)
+ * with their updated version if the latter does not need authentication.
+ * New datasets that don't require auth are appended.
+ *
+ * @param original The original response requiring auth at some level.
+ * @param update An updated response with auth not needed anymore at some level.
+ * @return A new response with updated items where auth is not needed anymore.
*/
- void requestSaveLocked(int sessionId) {
- // TODO(b/33197203): add MetricsLogger call
- // TODO(b/33197203): use handler?
- // TODO(b/33197203): show error on UI on Slog.w situations below???
-
- if (mService == null) {
- Slog.w(TAG, "requestSave(): service is null");
- return;
- }
- final Session session = mSessions.get(sessionId);
- if (session == null) {
- Slog.w(TAG, "requestSave(): no session with id " + sessionId);
- return;
- }
- final IBinder activityToken = session.mActivityToken.get();
- if (activityToken == null) {
- Slog.w(TAG, "activity token for session " + sessionId + " already GCed");
- return;
+ // TODO(b/33197203) Unit test
+ FillResponse createAuthenticatedResponse(FillResponse original, FillResponse update) {
+ // Can update only if ids match
+ if (!original.getId().equals(update.getId())) {
+ return original;
}
- /*
- * TODO(b/33197203): apply security checks below:
- * - checks if disabled by secure settings / device policy
- * - log operation using noteOp()
- * - check flags
- * - display disclosure if needed
- */
- try {
- /* TODO(b/33197203): refactor save logic so it uses a cached AssistStructure, and
- get the extras to be sent to the service based on the response / dataset in the
- session. */
- if (!mAm.requestAutoFillData(mAssistReceiver, null, sessionId, activityToken,
- AUTO_FILL_FLAG_TYPE_SAVE)) {
- Slog.w(TAG, "failed to save for " + activityToken);
+ // If the original required auth and the update doesn't, the update wins
+ // but only if none of the update's datasets requires authentication.
+ if (original.getAuthentication() != null && update.getAuthentication() == null) {
+ ArraySet<Dataset> updateDatasets = update.getDatasets();
+ final int udpateDatasetCount = updateDatasets.size();
+ for (int i = 0; i < udpateDatasetCount; i++) {
+ Dataset updateDataset = updateDatasets.valueAt(i);
+ if (updateDataset.getAuthentication() != null) {
+ return original;
+ }
}
- } catch (RemoteException e) {
- // Should not happen, it's a local call.
+ return update;
}
- }
- private void scanFingerprint(long opId) {
- // TODO(b/33197203): add MetricsLogger call
- if (DEBUG) Slog.d(TAG, "Starting fingerprint scan for op id: " + opId);
+ // If no auth on response level we create a response that has all
+ // datasets from the original with the ones that required auth but
+ // not anymore updated and new ones not requiring auth appended.
- // TODO(b/33197203): since we're clearing the AutoFillService's identity, make sure
- // this method is only called at the proper times, otherwise a malicious provider could
- // keep the callback refence to bypass the check
- final long token = Binder.clearCallingIdentity();
- try {
- // TODO(b/33197203): set a timeout?
- mFingerprintService.authenticate(mAuthToken, opId, mUserId, mServiceReceiver, 0,
- null);
- } catch (RemoteException e) {
- // Local call, shouldn't happen.
- } finally {
- Binder.restoreCallingIdentity(token);
+ // The update shouldn't require auth
+ if (update.getAuthentication() != null) {
+ return original;
}
- }
- private void removeSelf() {
- synchronized (mLock) {
- removeSessionLocked(mId);
+ final FillResponse.Builder builder = new FillResponse.Builder(original.getId());
+
+ // Update existing datasets
+ final ArraySet<Dataset> origDatasets = original.getDatasets();
+ final int origDatasetCount = origDatasets.size();
+ for (int i = 0; i < origDatasetCount; i++) {
+ Dataset origDataset = origDatasets.valueAt(i);
+ ArraySet<Dataset> updateDatasets = update.getDatasets();
+ final int updateDatasetCount = updateDatasets.size();
+ for (int j = 0; j < updateDatasetCount; j++) {
+ Dataset updateDataset = updateDatasets.valueAt(j);
+ if (origDataset.getId().equals(updateDataset.getId())) {
+ // The update shouldn't require auth
+ if (updateDataset.getAuthentication() == null) {
+ origDataset = updateDataset;
+ updateDatasets.removeAt(j);
+ }
+ break;
+ }
+ }
+ builder.addDataset(origDataset);
}
+
+ // Add new datasets
+ final ArraySet<Dataset> updateDatasets = update.getDatasets();
+ final int updateDatasetCount = updateDatasets.size();
+ for (int i = 0; i < updateDatasetCount; i++) {
+ final Dataset updateDataset = updateDatasets.valueAt(i);
+ builder.addDataset(updateDataset);
+ }
+
+ // For now no extras and savable id updates.
+
+ return builder.build();
}
}
}
diff --git a/services/autofill/java/com/android/server/autofill/AutoFillManagerServiceShellCommand.java b/services/autofill/java/com/android/server/autofill/AutoFillManagerServiceShellCommand.java
index 4998e3f..201a889 100644
--- a/services/autofill/java/com/android/server/autofill/AutoFillManagerServiceShellCommand.java
+++ b/services/autofill/java/com/android/server/autofill/AutoFillManagerServiceShellCommand.java
@@ -16,11 +16,7 @@
package com.android.server.autofill;
-import static android.view.View.AUTO_FILL_FLAG_TYPE_FILL;
-import static android.view.View.AUTO_FILL_FLAG_TYPE_SAVE;
-
import android.app.ActivityManager;
-import android.os.Bundle;
import android.os.RemoteException;
import android.os.ShellCommand;
import android.os.UserHandle;
@@ -44,10 +40,8 @@
final PrintWriter pw = getOutPrintWriter();
try {
switch (cmd) {
- case "fill":
- return requestAutoFill(AUTO_FILL_FLAG_TYPE_FILL);
case "save":
- return requestAutoFill(AUTO_FILL_FLAG_TYPE_SAVE);
+ return requestSave();
default:
return handleDefaultCommands(cmd);
}
@@ -64,17 +58,15 @@
pw.println(" help");
pw.println(" Prints this help text.");
pw.println("");
- pw.println(" fill [--user USER_ID]");
- pw.println(" Request provider to auto-fill the top activity. ");
pw.println(" save [--user USER_ID]");
pw.println(" Request provider to save contents of the top activity. ");
pw.println("");
}
}
- private int requestAutoFill(int flags) throws RemoteException {
+ private int requestSave() throws RemoteException {
final int userId = getUserIdFromArgs();
- mService.requestAutoFillForUser(userId, flags);
+ mService.requestSaveForUser(userId);
return 0;
}
diff --git a/services/autofill/java/com/android/server/autofill/AutoFillUI.java b/services/autofill/java/com/android/server/autofill/AutoFillUI.java
index 86e04cc..c482c40 100644
--- a/services/autofill/java/com/android/server/autofill/AutoFillUI.java
+++ b/services/autofill/java/com/android/server/autofill/AutoFillUI.java
@@ -15,13 +15,9 @@
*/
package com.android.server.autofill;
-
import static com.android.server.autofill.Helper.DEBUG;
-import android.annotation.Nullable;
-import android.app.Activity;
import android.app.Notification;
-import android.app.Notification.Action;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.StatusBarManager;
@@ -29,41 +25,48 @@
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.IntentSender;
import android.graphics.Rect;
-import android.graphics.PixelFormat;
import android.os.Binder;
-import android.os.Bundle;
+import android.os.IBinder;
+import android.util.ArraySet;
+import android.os.Looper;
+import android.text.format.DateUtils;
import android.util.Slog;
-import android.view.autofill.AutoFillId;
import android.view.autofill.Dataset;
import android.view.autofill.FillResponse;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
+import android.view.WindowManager.LayoutParams;
import android.widget.Toast;
-import com.android.internal.annotations.GuardedBy;
+import com.android.internal.os.HandlerCaller;
import com.android.server.UiThread;
-import com.android.server.autofill.AutoFillManagerServiceImpl.Session;
import com.android.server.autofill.AutoFillManagerServiceImpl.ViewState;
import java.io.PrintWriter;
-import java.util.Arrays;
-import java.util.List;
/**
* Handles all auto-fill related UI tasks.
*/
// TODO(b/33197203): document exactly what once the auto-fill bar is implemented
final class AutoFillUI {
-
private static final String TAG = "AutoFillUI";
+ private static final long SNACK_BAR_LIFETIME_MS = 30 * DateUtils.SECOND_IN_MILLIS;
+ private static final int MSG_HIDE_SNACK_BAR = 1;
+
+ private static final String EXTRA_AUTH_INTENT_SENDER =
+ "com.android.server.autofill.extra.AUTH_INTENT_SENDER";
+ private static final String EXTRA_AUTH_FILL_IN_INTENT =
+ "com.android.server.autofill.extra.AUTH_FILL_IN_INTENT";
private final Context mContext;
- private final Session mSession;
private final WindowManager mWm;
+ // TODO(b/33197203) Fix locking - some state requires lock and some not - requires refactoring
+
// Fill UI variables
private AnchoredWindow mFillWindow;
private DatasetPicker mFillView;
@@ -71,21 +74,47 @@
private Rect mBounds;
private String mFilterText;
+ private AutoFillUiCallback mCallback;
+ private IBinder mActivityToken;
+
+ private final HandlerCaller.Callback mHandlerCallback = (msg) -> {
+ switch (msg.what) {
+ case MSG_HIDE_SNACK_BAR: {
+ hideSnackbarUiThread();
+ return;
+ }
+ default: {
+ Slog.w(TAG, "Invalid message: " + msg);
+ }
+ }
+ };
+ private final HandlerCaller mHandlerCaller = new HandlerCaller(null, Looper.getMainLooper(),
+ mHandlerCallback, true);
+
/**
* Custom snackbar UI used for saving autofill or other informational messages.
*/
private View mSnackbar;
- AutoFillUI(Context context, Session session) {
+ AutoFillUI(Context context) {
mContext = context;
- mSession = session;
mWm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
}
+ void setCallback(AutoFillUiCallback callback, IBinder activityToken) {
+ hideAll();
+ mCallback = callback;
+ mActivityToken = activityToken;
+ }
+
/**
* Displays an error message to the user.
*/
void showError(CharSequence message) {
+ if (!hasCallback()) {
+ return;
+ }
+ hideAll();
// TODO(b/33197203): proper implementation
UiThread.getHandler().runWithScissors(() -> {
Toast.makeText(mContext, "AutoFill error: " + message, Toast.LENGTH_LONG).show();
@@ -93,63 +122,75 @@
}
/**
- * Highlights in the {@link Activity} the fields saved by the service.
- */
- void highlightSavedFields(AutoFillId[] ids) {
- // TODO(b/33197203): proper implementation (must be handled by activity)
- UiThread.getHandler().runWithScissors(() -> {
- Toast.makeText(mContext, "AutoFill: service saved ids " + Arrays.toString(ids),
- Toast.LENGTH_LONG).show();
- }, 0);
- }
-
- /**
* Hides the fill UI.
*/
void hideFillUi() {
UiThread.getHandler().runWithScissors(() -> {
- if (mFillWindow != null) {
- if (DEBUG) Slog.d(TAG, "remove FillUi remove " + mFillWindow);
- mFillWindow.hide();
- }
-
- mViewState = null;
- mBounds = null;
- mFilterText = null;
- mFillView = null;
- mFillWindow = null;
+ hideFillUiUiThread();
}, 0);
}
+ @android.annotation.UiThread
+ private void hideFillUiUiThread() {
+ if (mFillWindow != null) {
+ if (DEBUG) Slog.d(TAG, "hideFillUiUiThread(): hide" + mFillWindow);
+ mFillWindow.hide();
+ }
+
+ mViewState = null;
+ mBounds = null;
+ mFilterText = null;
+ mFillView = null;
+ mFillWindow = null;
+ }
+
/**
* Shows the fill UI, removing the previous fill UI if the has changed.
*
* @param viewState the view state, compared by reference to know if new UI should be shown
- * @param response the response to show, not used if viewState is the same
+ * @param datasets the datasets to show, not used if viewState is the same
* @param bounds bounds of the view to be filled, used if changed
* @param filterText text of the view to be filled, used if changed
*/
- void showFillUi(ViewState viewState, List<Dataset> datasets, Rect bounds,
+ void showFillUi(ViewState viewState, ArraySet<Dataset> datasets, Rect bounds,
String filterText) {
- UiThread.getHandler().runWithScissors(() -> {
- if (mViewState != viewState) {
- // new
- hideFillUi();
+ if (!hasCallback()) {
+ return;
+ }
+ if (datasets == null) {
+ // TODO(b/33197203): shouldn't be called, but keeping the WTF for a while just to be
+ // safe, otherwise it would crash system server...
+ Slog.wtf(TAG, "showFillUI(): no dataset");
+ return;
+ }
+
+ // TODO(b/33197203): call to hideAll() was making it janky because then mViewState is set
+ // to null and hence the first check inside the lambada fails, causing it to be displayed
+ // twice in some cases.
+ hideAll();
+
+ UiThread.getHandler().runWithScissors(() -> {
+ if (mViewState == null || !mViewState.mId.equals(viewState.mId)) {
mViewState = viewState;
mFillView = new DatasetPicker(mContext, datasets,
(dataset) -> {
- mSession.autoFillApp(dataset);
+ final AutoFillUiCallback callback;
+ synchronized (mLock) {
+ callback = mCallback;
+ }
+ callback.fill(dataset);
hideFillUi();
- showSaveUi();
});
+ // TODO(b/33197203): No magical numbers
mFillWindow = new AnchoredWindow(
mWm, mFillView, 800, ViewGroup.LayoutParams.WRAP_CONTENT);
- if (DEBUG) Slog.d(TAG, "show FillUi");
+ if (DEBUG) Slog.d(TAG, "show FillUi: " + viewState.mId);
}
+ // TODO(b/33197203): If bounds are the same we would not show, fix this
if (!bounds.equals(mBounds)) {
if (DEBUG) Slog.d(TAG, "update FillUi bounds: " + mBounds);
mBounds = bounds;
@@ -171,27 +212,14 @@
* <p>It typically replaces the auto-fill bar with a message saying "Press fingerprint or tap to
* autofill" or "Tap to autofill", depending on the value of {@code usesFingerprint}.
*/
- void showFillResponseAuthenticationRequest(boolean usesFingerprint,
- Bundle extras, int flags) {
- // TODO(b/33197203): proper implementation
- showAuthNotification(usesFingerprint, extras, flags);
- }
-
- /**
- * Shows an UI affordance asking indicating that user action is required before a
- * {@link Dataset} can be used.
- *
- * <p>It typically replaces the auto-fill bar with a message saying "Press fingerprint to
- * autofill".
- */
- void showDatasetFingerprintAuthenticationRequest(Dataset dataset) {
- if (DEBUG) Slog.d(TAG, "showDatasetAuthenticationRequest(): dataset=" + dataset);
-
- // TODO(b/33197203): proper implementation (either pop up a fingerprint dialog or replace
- // the auto-fill bar with a new message.
+ void showFillResponseAuthRequest(IntentSender intent, Intent fillInIntent) {
+ if (!hasCallback()) {
+ return;
+ }
+ hideAll();
UiThread.getHandler().runWithScissors(() -> {
- Toast.makeText(mContext, "AutoFill: press fingerprint to unlock " + dataset.getName(),
- Toast.LENGTH_LONG).show();
+ // TODO(b/33197203): proper implementation
+ showFillResponseAuthUiUiThread(intent, fillInIntent);
}, 0);
}
@@ -199,41 +227,45 @@
* Shows the UI asking the user to save for auto-fill.
*/
void showSaveUi() {
- showSnackbar(new SavePrompt(mContext, new SavePrompt.OnSaveListener() {
- @Override
- public void onSaveClick() {
- hideSnackbar();
+ if (!hasCallback()) {
+ return;
+ }
+ hideAll();
+ UiThread.getHandler().runWithScissors(() -> {
+ showSnackbarUiThread(new SavePrompt(mContext,
+ new SavePrompt.OnSaveListener() {
+ @Override
+ public void onSaveClick() {
+ hideSnackbarUiThread();
+ // TODO(b/33197203): add MetricsLogger call
+ mCallback.save();
+ }
- mSession.requestSave();
- }
- @Override
- public void onCancelClick() {
- hideSnackbar();
- }
- }));
+ @Override
+ public void onCancelClick() {
+ // TODO(b/33197203): add MetricsLogger call
+ hideSnackbarUiThread();
+ }
+ }));
+ }, 0);
}
/**
- * Called by service after the user user the fingerprint sensors to authenticate.
+ * Hides all UI affordances.
*/
- void dismissFingerprintRequest(boolean success) {
- if (DEBUG) Slog.d(TAG, "dismissFingerprintRequest(): ok=" + success);
-
- dismissAuthNotification();
-
- if (!success) {
- // TODO(b/33197203): proper implementation (snack bar / i18n string)
- UiThread.getHandler().runWithScissors(() -> {
- Toast.makeText(mContext, "AutoFill: fingerprint failed", Toast.LENGTH_LONG).show();
- }, 0);
- }
+ void hideAll() {
+ UiThread.getHandler().runWithScissors(() -> {
+ hideSnackbarUiThread();
+ hideFillUiUiThread();
+ hideFillResponseAuthUiUiThread();
+ }, 0);
}
void dump(PrintWriter pw) {
pw.println("AufoFill UI");
final String prefix = " ";
pw.print(prefix); pw.print("sResultCode: "); pw.println(sResultCode);
- pw.print(prefix); pw.print("mSessionId: "); pw.println(mSession.mId);
+ pw.print(prefix); pw.print("mActivityToken: "); pw.println(mActivityToken);
pw.print(prefix); pw.print("mSnackBar: "); pw.println(mSnackbar);
pw.print(prefix); pw.print("mViewState: "); pw.println(mViewState);
pw.print(prefix); pw.print("mBounds: "); pw.println(mBounds);
@@ -242,30 +274,50 @@
//similar to a snackbar, but can be a bit custom since it is more than just text. This will
//allow two buttons for saving or not saving the autofill for instance as well.
- private void showSnackbar(View snackBar) {
- WindowManager.LayoutParams params = new WindowManager.LayoutParams(
- WindowManager.LayoutParams.FILL_PARENT,
- WindowManager.LayoutParams.WRAP_CONTENT,
- WindowManager.LayoutParams.TYPE_SYSTEM_ALERT, // TODO(b/33197203) use TYPE_AUTO_FILL
- WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
- | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN,
- PixelFormat.TRANSLUCENT);
-
- params.gravity = Gravity.BOTTOM | Gravity.LEFT;
+ private void showSnackbarUiThread(View snackBar) {
+ final LayoutParams params = new LayoutParams();
+ params.setTitle("AutoFill Save");
+ params.type = LayoutParams.TYPE_PHONE; // TODO(b/33197203) use app window token
+ params.flags =
+ LayoutParams.FLAG_NOT_FOCUSABLE // don't receive input events,
+ | LayoutParams.FLAG_ALT_FOCUSABLE_IM // resize for soft input
+ | LayoutParams.FLAG_NOT_TOUCH_MODAL; // outside touches go to windows behind us
+ params.softInputMode =
+ LayoutParams.SOFT_INPUT_ADJUST_PAN; // pan with soft input
+ params.gravity = Gravity.BOTTOM | Gravity.START;
+ params.width = LayoutParams.MATCH_PARENT;
+ params.height = LayoutParams.WRAP_CONTENT;
UiThread.getHandler().runWithScissors(() -> {
mSnackbar = snackBar;
mWm.addView(mSnackbar, params);
}, 0);
+
+ if (DEBUG) {
+ Slog.d(TAG, "showSnackbar(): auto dismissing it in " + SNACK_BAR_LIFETIME_MS + " ms");
+ }
+ mHandlerCaller.sendMessageDelayed(mHandlerCaller.obtainMessage(MSG_HIDE_SNACK_BAR),
+ SNACK_BAR_LIFETIME_MS);
}
- private void hideSnackbar() {
- UiThread.getHandler().runWithScissors(() -> {
- if (mSnackbar != null) {
- mWm.removeView(mSnackbar);
- mSnackbar = null;
- }
- }, 0);
+ private void hideSnackbarUiThread() {
+ mHandlerCaller.getHandler().removeMessages(MSG_HIDE_SNACK_BAR);
+ if (mSnackbar != null) {
+ mWm.removeView(mSnackbar);
+ mSnackbar = null;
+ }
+ }
+
+ private boolean hasCallback() {
+ synchronized (mLock) {
+ return mCallback != null;
+ }
+ }
+
+ interface AutoFillUiCallback {
+ void authenticate(IntentSender intent, Intent fillInIntent);
+ void fill(Dataset dataset);
+ void save();
}
/////////////////////////////////////////////////////////////////////////////////
@@ -277,25 +329,13 @@
private static final String NOTIFICATION_AUTO_FILL_INTENT =
"com.android.internal.autofill.action.REQUEST_AUTOFILL";
- // Extras used in the notification intents
- private static final String EXTRA_USER_ID = "user_id";
- private static final String EXTRA_NOTIFICATION_TYPE = "notification_type";
- private static final String EXTRA_SESSION_ID = "session_id";
- private static final String EXTRA_FILL_RESPONSE = "fill_response";
- private static final String EXTRA_DATASET = "dataset";
- private static final String EXTRA_AUTH_REQUIRED_EXTRAS = "auth_required_extras";
- private static final String EXTRA_FLAGS = "flags";
-
- private static final String TYPE_OPTIONS = "options";
- private static final String TYPE_AUTH_RESPONSE = "auth_response";
-
private BroadcastReceiver mNotificationReceiver;
private final Object mLock = new Object();
// Hack used to generate unique pending intents
static int sResultCode = 0;
- private void setNotificationListener() {
+ private void ensureNotificationListener() {
synchronized (mLock) {
if (mNotificationReceiver == null) {
mNotificationReceiver = new NotificationReceiver();
@@ -308,83 +348,58 @@
final class NotificationReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
- final String type = intent.getStringExtra(EXTRA_NOTIFICATION_TYPE);
- if (type == null) {
- Slog.wtf(TAG, "No extra " + EXTRA_NOTIFICATION_TYPE + " on intent " + intent);
- return;
- }
- final Dataset dataset = intent.getParcelableExtra(EXTRA_DATASET);
- final int flags = intent.getIntExtra(EXTRA_FLAGS, 0);
-
- if (DEBUG) Slog.d(TAG, "Notification received: type=" + type
- + ", sessionId=" + mSession.mId);
+ final AutoFillUiCallback callback;
synchronized (mLock) {
- switch (type) {
- case TYPE_AUTH_RESPONSE:
- mSession.notifyResponseAuthenticationResult(
- intent.getBundleExtra(EXTRA_AUTH_REQUIRED_EXTRAS), flags);
- break;
- default: {
- Slog.w(TAG, "Unknown notification type: " + type);
- }
- }
+ callback = mCallback;
+ }
+ if (callback != null) {
+ IntentSender intentSender = intent.getParcelableExtra(EXTRA_AUTH_INTENT_SENDER);
+ Intent fillInIntent = intent.getParcelableExtra(EXTRA_AUTH_FILL_IN_INTENT);
+ callback.authenticate(intentSender, fillInIntent);
}
collapseStatusBar();
}
}
- private static Intent newNotificationIntent(String type) {
- final Intent intent = new Intent(NOTIFICATION_AUTO_FILL_INTENT);
- intent.putExtra(EXTRA_NOTIFICATION_TYPE, type);
- return intent;
- }
-
- private void showAuthNotification(boolean usesFingerprint,
- Bundle extras, int flags) {
- final long token = Binder.clearCallingIdentity();
- try {
- showAuthNotificationAsSystem(usesFingerprint, extras, flags);
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- private void showAuthNotificationAsSystem(
- boolean usesFingerprint, Bundle extras, int flags) {
+ @android.annotation.UiThread
+ private void showFillResponseAuthUiUiThread(IntentSender intent, Intent fillInIntent) {
final String title = "AutoFill Authentication";
final StringBuilder subTitle = new StringBuilder("Provider require user authentication.\n");
- final Intent authIntent = newNotificationIntent(TYPE_AUTH_RESPONSE);
- if (extras != null) {
- authIntent.putExtra(EXTRA_AUTH_REQUIRED_EXTRAS, extras);
- }
- if (flags != 0) {
- authIntent.putExtra(EXTRA_FLAGS, flags);
- }
- final PendingIntent authPendingIntent = PendingIntent.getBroadcast(mContext, ++sResultCode,
- authIntent, PendingIntent.FLAG_ONE_SHOT);
+ final Intent authIntent = new Intent(NOTIFICATION_AUTO_FILL_INTENT);
+ authIntent.putExtra(EXTRA_AUTH_INTENT_SENDER, intent);
+ authIntent.putExtra(EXTRA_AUTH_FILL_IN_INTENT, fillInIntent);
- if (usesFingerprint) {
- subTitle.append("But kindly accepts your fingerprint instead"
- + "\n(tap fingerprint sensor to trigger it)");
+ final PendingIntent authPendingIntent = PendingIntent.getBroadcast(
+ mContext, ++sResultCode, authIntent, PendingIntent.FLAG_ONE_SHOT);
- } else {
- subTitle.append("Tap notification to launch its authentication UI.");
- }
+ subTitle.append("Tap notification to launch its authentication UI.");
final Notification.Builder notification = newNotificationBuilder()
.setAutoCancel(true)
.setOngoing(false)
.setContentTitle(title)
- .setStyle(new Notification.BigTextStyle().bigText(subTitle.toString()));
- if (authPendingIntent != null) {
- notification.setContentIntent(authPendingIntent);
+ .setStyle(new Notification.BigTextStyle().bigText(subTitle.toString()))
+ .setContentIntent(authPendingIntent);
+
+ ensureNotificationListener();
+
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ NotificationManager.from(mContext).notify(0, notification.build());
+ } finally {
+ Binder.restoreCallingIdentity(identity);
}
- NotificationManager.from(mContext).notify(mSession.mId, notification.build());
}
- private void dismissAuthNotification() {
- NotificationManager.from(mContext).cancel(mSession.mId);
+ @android.annotation.UiThread
+ private void hideFillResponseAuthUiUiThread() {
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ NotificationManager.from(mContext).cancel(0);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
}
private Notification.Builder newNotificationBuilder() {
diff --git a/services/autofill/java/com/android/server/autofill/DatasetPicker.java b/services/autofill/java/com/android/server/autofill/DatasetPicker.java
index 7245aaa..8212cf1 100644
--- a/services/autofill/java/com/android/server/autofill/DatasetPicker.java
+++ b/services/autofill/java/com/android/server/autofill/DatasetPicker.java
@@ -17,6 +17,7 @@
import android.content.Context;
import android.graphics.Color;
+import android.util.ArraySet;
import android.view.autofill.Dataset;
import android.view.View;
import android.view.ViewGroup;
@@ -38,15 +39,13 @@
* 3) the View is detached.
*/
final class DatasetPicker extends ListView implements OnItemClickListener {
- private static final String TAG = "DatasetPicker";
-
interface Listener {
void onDatasetPicked(Dataset dataset);
}
private final Listener mListener;
- DatasetPicker(Context context, List<Dataset> datasets, Listener listener) {
+ DatasetPicker(Context context, ArraySet<Dataset> datasets, Listener listener) {
super(context);
mListener = listener;
@@ -80,7 +79,7 @@
adapter.getFilter().filter(prefix, new FilterListener() {
@Override
public void onFilterComplete(int count) {
- DatasetPicker.this.requestLayout();
+ setVisibility(count > 0 ? View.VISIBLE : View.GONE);
}
});
}
diff --git a/services/autofill/java/com/android/server/autofill/Helper.java b/services/autofill/java/com/android/server/autofill/Helper.java
index 79095a1..7400a64 100644
--- a/services/autofill/java/com/android/server/autofill/Helper.java
+++ b/services/autofill/java/com/android/server/autofill/Helper.java
@@ -16,8 +16,15 @@
package com.android.server.autofill;
+import android.annotation.Nullable;
import android.os.Bundle;
+import android.util.ArraySet;
+import android.view.autofill.AutoFillId;
+import android.view.autofill.AutoFillValue;
+import android.view.autofill.Dataset;
+import android.view.autofill.FillResponse;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Objects;
import java.util.Set;
@@ -25,6 +32,7 @@
final class Helper {
static final boolean DEBUG = true; // TODO(b/33197203): set to false when stable
+ static final boolean VERBOSE = false;
static final String REDACTED = "[REDACTED]";
static void append(StringBuilder builder, Bundle bundle) {
@@ -51,6 +59,46 @@
return builder.toString();
}
+ /**
+ * Gets the value of a {@link Dataset} field by its id, or {@code null} if not found.
+ */
+ @Nullable
+ static AutoFillValue findValue(Dataset dataset, AutoFillId id) {
+ if (dataset != null) {
+ final ArrayList<AutoFillId> ids = dataset.getFieldIds();
+ final int size = ids.size();
+ for (int i = 0; i < size; i++) {
+ if (id.equals(ids.get(i))) {
+ return dataset.getFieldValues().get(i);
+ }
+
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Finds a data set by id in a response.
+ *
+ * @param id The dataset id.
+ * @param response The response to search.
+ * @return The dataset if found or null.
+ */
+ static Dataset findDatasetById(String id, FillResponse response) {
+ ArraySet<Dataset> datasets = response.getDatasets();
+ if (datasets == null || datasets.isEmpty()) {
+ return null;
+ }
+ final int datasetCount = datasets.size();
+ for (int i = 0; i < datasetCount; i++) {
+ Dataset dataset = datasets.valueAt(i);
+ if (dataset.getId().equals(id)) {
+ return dataset;
+ }
+ }
+ return null;
+ }
+
private Helper() {
throw new UnsupportedOperationException("contains static members only");
}
diff --git a/services/autofill/java/com/android/server/autofill/RemoteFillService.java b/services/autofill/java/com/android/server/autofill/RemoteFillService.java
new file mode 100644
index 0000000..c070f77
--- /dev/null
+++ b/services/autofill/java/com/android/server/autofill/RemoteFillService.java
@@ -0,0 +1,521 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.autofill;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.app.assist.AssistStructure;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.IBinder.DeathRecipient;
+import android.os.ICancellationSignal;
+import android.os.Message;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.service.autofill.AutoFillService;
+import android.service.autofill.IAutoFillService;
+import android.service.autofill.IFillCallback;
+import android.service.autofill.ISaveCallback;
+import android.text.format.DateUtils;
+import android.util.Slog;
+import android.view.autofill.FillResponse;
+import com.android.internal.os.HandlerCaller;
+import com.android.server.FgThread;
+
+import java.io.PrintWriter;
+import java.lang.ref.WeakReference;
+
+/**
+ * This class represents a remote fill service. It abstracts away the binding
+ * and unbinding from the remote implementation.
+ *
+ * <p>Clients can call methods of this class without worrying about when and
+ * how to bind/unbind/timeout. All state of this class is modified on a handler
+ * thread.
+ */
+final class RemoteFillService implements DeathRecipient {
+ private static final String LOG_TAG = "RemoteFillService";
+
+ private static final boolean DEBUG = Helper.DEBUG;
+
+ // How long after the last interaction with the service we would unbind
+ private static final long TIMEOUT_IDLE_BIND_MILLIS = 5 * DateUtils.MINUTE_IN_MILLIS;
+
+ private final Context mContext;
+
+ private final ComponentName mComponentName;
+
+ private final Intent mIntent;
+
+ private final FillServiceCallbacks mCallbacks;
+
+ private final int mUserId;
+
+ private final ServiceConnection mServiceConnection = new RemoteServiceConnection();
+
+ private final HandlerCaller mHandler;
+
+ private IAutoFillService mAutoFillService;
+
+ private boolean mBinding;
+
+ private boolean mDestroyed;
+
+ private boolean mServiceDied;
+
+ private boolean mCompleted;
+
+ private PendingRequest mPendingRequest;
+
+ public interface FillServiceCallbacks {
+ void onFillRequestSuccess(FillResponse response);
+ void onFillRequestFailure(CharSequence message);
+ void onSaveRequestSuccess();
+ void onSaveRequestFailure(CharSequence message);
+ void onServiceDied(RemoteFillService service);
+ }
+
+ public RemoteFillService(Context context, ComponentName componentName,
+ int userId, FillServiceCallbacks callbacks) {
+ mContext = context;
+ mCallbacks = callbacks;
+ mComponentName = componentName;
+ mIntent = new Intent(AutoFillService.SERVICE_INTERFACE)
+ .setComponent(mComponentName);
+ mUserId = userId;
+ mHandler = new MyHandler(context);
+ }
+
+ public void destroy() {
+ mHandler.obtainMessage(MyHandler.MSG_DESTROY).sendToTarget();
+ }
+
+ private void handleDestroy() {
+ if (mPendingRequest != null) {
+ mPendingRequest.cancel();
+ mPendingRequest = null;
+ }
+ ensureUnbound();
+ mDestroyed = true;
+ }
+
+ @Override
+ public void binderDied() {
+ mHandler.obtainMessage(MyHandler.MSG_BINDER_DIED).sendToTarget();
+ }
+
+ private void handleBinderDied() {
+ if (mAutoFillService != null) {
+ mAutoFillService.asBinder().unlinkToDeath(this, 0);
+ }
+ mAutoFillService = null;
+ mServiceDied = true;
+ mCallbacks.onServiceDied(this);
+ }
+
+ public void onFillRequest(@NonNull AssistStructure structure, @Nullable Bundle extras) {
+ cancelScheduledUnbind();
+ PendingFillRequest request = new PendingFillRequest(structure, extras, this);
+ mHandler.obtainMessageO(MyHandler.MSG_ON_PENDING_REQUEST, request).sendToTarget();
+ }
+
+ public void onSaveRequest(@NonNull AssistStructure structure, @Nullable Bundle extras) {
+ cancelScheduledUnbind();
+ PendingSaveRequest request = new PendingSaveRequest(structure, extras, this);
+ mHandler.obtainMessageO(MyHandler.MSG_ON_PENDING_REQUEST, request).sendToTarget();
+ }
+
+ // Note: we are dumping without a lock held so this is a bit racy but
+ // adding a lock to a class that offloads to a handler thread would
+ // mean adding a lock adding overhead to normal runtime operation.
+ public void dump(@NonNull String prefix, @NonNull PrintWriter pw) {
+ String tab = " ";
+ pw.append(prefix).append("service:").println();
+ pw.append(prefix).append(tab).append("userId=")
+ .append(String.valueOf(mUserId)).println();
+ pw.append(prefix).append(tab).append("componentName=")
+ .append(mComponentName.flattenToString()).println();
+ pw.append(prefix).append(tab).append("destroyed=")
+ .append(String.valueOf(mDestroyed)).println();
+ pw.append(prefix).append(tab).append("bound=")
+ .append(String.valueOf(isBound())).println();
+ pw.append(prefix).append(tab).append("hasPendingRequest=")
+ .append(String.valueOf(mPendingRequest != null)).println();
+ pw.println();
+ }
+
+ private void cancelScheduledUnbind() {
+ mHandler.removeMessages(MyHandler.MSG_UNBIND);
+ }
+
+ private void scheduleUnbind() {
+ cancelScheduledUnbind();
+ Message message = mHandler.obtainMessage(MyHandler.MSG_UNBIND);
+ mHandler.sendMessageDelayed(message, TIMEOUT_IDLE_BIND_MILLIS);
+ }
+
+ private void handleUnbind() {
+ ensureUnbound();
+ }
+
+ private void handlePendingRequest(PendingRequest pendingRequest) {
+ if (mDestroyed || mCompleted) {
+ return;
+ }
+ if (pendingRequest.isFinal()) {
+ mCompleted = true;
+ }
+ if (!isBound()) {
+ if (mPendingRequest != null) {
+ mPendingRequest.cancel();
+ }
+ mPendingRequest = pendingRequest;
+ ensureBound();
+ } else {
+ if (DEBUG) {
+ Slog.d(LOG_TAG, "[user: " + mUserId + "] handleOnFillRequest()");
+ }
+ pendingRequest.run();
+ }
+ }
+
+ private boolean isBound() {
+ return mAutoFillService != null;
+ }
+
+ private void ensureBound() {
+ if (isBound() || mBinding) {
+ return;
+ }
+ if (DEBUG) {
+ Slog.d(LOG_TAG, "[user: " + mUserId + "] ensureBound()");
+ }
+ mBinding = true;
+
+ boolean willBind = mContext.bindServiceAsUser(mIntent, mServiceConnection,
+ Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE,
+ new UserHandle(mUserId));
+
+ if (!willBind) {
+ if (DEBUG) {
+ Slog.d(LOG_TAG, "[user: " + mUserId + "] could not bind to " + mIntent);
+ }
+ mBinding = false;
+
+ if (!mServiceDied) {
+ handleBinderDied();
+ }
+ }
+ }
+
+ private void ensureUnbound() {
+ if (!isBound() && !mBinding) {
+ return;
+ }
+ if (DEBUG) {
+ Slog.d(LOG_TAG, "[user: " + mUserId + "] ensureUnbound()");
+ }
+ mBinding = false;
+ if (isBound()) {
+ mAutoFillService.asBinder().unlinkToDeath(this, 0);
+ mAutoFillService = null;
+ }
+ mContext.unbindService(mServiceConnection);
+ }
+
+ private void dispatchOnFillRequestSuccess(PendingRequest pendingRequest,
+ FillResponse response) {
+ mHandler.getHandler().post(() -> {
+ if (handleResponseCallbackCommon(pendingRequest)) {
+ mCallbacks.onFillRequestSuccess(response);
+ }
+ });
+ }
+
+ private void dispatchOnFillRequestFailure(PendingRequest pendingRequest,
+ CharSequence message) {
+ mHandler.getHandler().post(() -> {
+ if (handleResponseCallbackCommon(pendingRequest)) {
+ mCallbacks.onFillRequestFailure(message);
+ }
+ });
+ }
+
+ private void dispatchOnSaveRequestSuccess(PendingRequest pendingRequest) {
+ mHandler.getHandler().post(() -> {
+ if (handleResponseCallbackCommon(pendingRequest)) {
+ mCallbacks.onSaveRequestSuccess();
+ }
+ });
+ }
+
+ private void dispatchOnSaveRequestFailure(PendingRequest pendingRequest,
+ CharSequence message) {
+ mHandler.getHandler().post(() -> {
+ if (handleResponseCallbackCommon(pendingRequest)) {
+ mCallbacks.onSaveRequestFailure(message);
+ }
+ });
+ }
+
+ private boolean handleResponseCallbackCommon(PendingRequest pendingRequest) {
+ if (mDestroyed) {
+ return false;
+ }
+ if (mPendingRequest == pendingRequest) {
+ mPendingRequest = null;
+ }
+ if (mPendingRequest == null) {
+ scheduleUnbind();
+ }
+ return true;
+ }
+
+ private class RemoteServiceConnection implements ServiceConnection {
+ @Override
+ public void onServiceConnected(ComponentName name, IBinder service) {
+ if (mDestroyed || !mBinding) {
+ mContext.unbindService(mServiceConnection);
+ return;
+ }
+ mBinding = false;
+ mAutoFillService = IAutoFillService.Stub.asInterface(service);
+ try {
+ service.linkToDeath(RemoteFillService.this, 0);
+ } catch (RemoteException re) {
+ handleBinderDied();
+ return;
+ }
+
+ if (mPendingRequest != null) {
+ handlePendingRequest(mPendingRequest);
+ }
+
+ mServiceDied = false;
+ }
+
+ @Override
+ public void onServiceDisconnected(ComponentName name) {
+ mBinding = true;
+ mAutoFillService = null;
+ }
+ }
+
+ private final class MyHandler extends HandlerCaller {
+ public static final int MSG_DESTROY = 1;
+ public static final int MSG_BINDER_DIED = 2;
+ public static final int MSG_UNBIND = 3;
+ public static final int MSG_ON_PENDING_REQUEST = 4;
+
+ public MyHandler(Context context) {
+ // Cannot use lambda - doesn't compile
+ super(context, FgThread.getHandler().getLooper(), new Callback() {
+ @Override
+ public void executeMessage(Message message) {
+ if (mDestroyed) {
+ Slog.w(LOG_TAG, "Not handling " + message + " as service for "
+ + mComponentName + " is already destroyed");
+ return;
+ }
+ switch (message.what) {
+ case MSG_DESTROY: {
+ handleDestroy();
+ } break;
+
+ case MSG_BINDER_DIED: {
+ handleBinderDied();
+ } break;
+
+ case MSG_UNBIND: {
+ handleUnbind();
+ } break;
+
+ case MSG_ON_PENDING_REQUEST: {
+ handlePendingRequest((PendingRequest) message.obj);
+ } break;
+ }
+ }
+ }, false);
+ }
+ }
+
+ private static abstract class PendingRequest implements Runnable {
+ void cancel() {
+
+ }
+
+ /**
+ * @return whether this request leads to a final state where no
+ * other requests can be made.
+ */
+ boolean isFinal() {
+ return false;
+ }
+ }
+
+ private static final class PendingFillRequest extends PendingRequest {
+ private final Object mLock = new Object();
+ private final WeakReference<RemoteFillService> mWeakService;
+ private AssistStructure mStructure;
+ private Bundle mExtras;
+ private final IFillCallback mCallback;
+ private ICancellationSignal mCancellation;
+ private boolean mCancelled;
+
+ public PendingFillRequest(AssistStructure structure,
+ Bundle extras, RemoteFillService service) {
+ mStructure = structure;
+ mExtras = extras;
+ mWeakService = new WeakReference<>(service);
+ mCallback = new IFillCallback.Stub() {
+ @Override
+ public void onCancellable(ICancellationSignal cancellation) {
+ synchronized (mLock) {
+ final boolean cancelled;
+ synchronized (mLock) {
+ mCancellation = cancellation;
+ cancelled = mCancelled;
+ }
+ if (cancelled) {
+ try {
+ cancellation.cancel();
+ } catch (RemoteException e) {
+ Slog.e(LOG_TAG, "Error requesting a cancellation", e);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void onSuccess(FillResponse response) {
+ RemoteFillService remoteService = mWeakService.get();
+ if (remoteService != null) {
+ remoteService.dispatchOnFillRequestSuccess(
+ PendingFillRequest.this, response);
+ }
+ }
+
+ @Override
+ public void onFailure(CharSequence message) {
+ RemoteFillService remoteService = mWeakService.get();
+ if (remoteService != null) {
+ remoteService.dispatchOnFillRequestFailure(
+ PendingFillRequest.this, message);
+ }
+ }
+ };
+ }
+
+ @Override
+ public void run() {
+ RemoteFillService remoteService = mWeakService.get();
+ if (remoteService != null) {
+ try {
+ remoteService.mAutoFillService.onFillRequest(mStructure,
+ mExtras, mCallback);
+ synchronized (mLock) {
+ mStructure = null;
+ mExtras = null;
+ }
+ } catch (RemoteException e) {
+ Slog.e(LOG_TAG, "Error calling on fill request", e);
+ cancel();
+ }
+ }
+ }
+
+ @Override
+ public void cancel() {
+ final ICancellationSignal cancellation;
+ synchronized (mLock) {
+ if (mCancelled) {
+ return;
+ }
+ mCancelled = true;
+ cancellation = mCancellation;
+ }
+ if (cancellation == null) {
+ return;
+ }
+ try {
+ cancellation.cancel();
+ } catch (RemoteException e) {
+ Slog.e(LOG_TAG, "Error cancelling a fill request", e);
+ }
+ }
+ }
+
+ private static final class PendingSaveRequest extends PendingRequest {
+ private final Object mLock = new Object();
+ private final WeakReference<RemoteFillService> mWeakService;
+ private AssistStructure mStructure;
+ private Bundle mExtras;
+ private final ISaveCallback mCallback;
+
+ public PendingSaveRequest(@NonNull AssistStructure structure,
+ @Nullable Bundle extras, @NonNull RemoteFillService service) {
+ mStructure = structure;
+ mExtras = extras;
+ mWeakService = new WeakReference<>(service);
+ mCallback = new ISaveCallback.Stub() {
+ @Override
+ public void onSuccess() {
+ RemoteFillService service = mWeakService.get();
+ if (service != null) {
+ service.dispatchOnSaveRequestSuccess(
+ PendingSaveRequest.this);
+ }
+ }
+
+ @Override
+ public void onFailure(CharSequence message) {
+ RemoteFillService service = mWeakService.get();
+ if (service != null) {
+ service.dispatchOnSaveRequestFailure(
+ PendingSaveRequest.this, message);
+ }
+ }
+ };
+ }
+
+ @Override
+ public void run() {
+ RemoteFillService service = mWeakService.get();
+ if (service != null) {
+ try {
+ service.mAutoFillService.onSaveRequest(mStructure,
+ mExtras, mCallback);
+ synchronized (mLock) {
+ mStructure = null;
+ mExtras = null;
+ }
+ } catch (RemoteException e) {
+ Slog.e(LOG_TAG, "Error calling on save request", e);
+ }
+ }
+ }
+
+ @Override
+ public boolean isFinal() {
+ return true;
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/BatteryService.java b/services/core/java/com/android/server/BatteryService.java
index dd550f2..6248cab 100644
--- a/services/core/java/com/android/server/BatteryService.java
+++ b/services/core/java/com/android/server/BatteryService.java
@@ -49,8 +49,10 @@
import android.os.UEventObserver;
import android.os.UserHandle;
import android.provider.Settings;
+import android.service.battery.BatteryServiceDumpProto;
import android.util.EventLog;
import android.util.Slog;
+import android.util.proto.ProtoOutputStream;
import java.io.File;
import java.io.FileDescriptor;
@@ -801,6 +803,35 @@
}
}
+ private void dumpProto(FileDescriptor fd) {
+ final ProtoOutputStream proto = new ProtoOutputStream(fd);
+
+ synchronized (mLock) {
+ proto.write(BatteryServiceDumpProto.ARE_UPDATES_STOPPED, mUpdatesStopped);
+ int batteryPluggedValue = BatteryServiceDumpProto.BATTERY_PLUGGED_NONE;
+ if (mBatteryProps.chargerAcOnline) {
+ batteryPluggedValue = BatteryServiceDumpProto.BATTERY_PLUGGED_AC;
+ } else if (mBatteryProps.chargerUsbOnline) {
+ batteryPluggedValue = BatteryServiceDumpProto.BATTERY_PLUGGED_USB;
+ } else if (mBatteryProps.chargerWirelessOnline) {
+ batteryPluggedValue = BatteryServiceDumpProto.BATTERY_PLUGGED_WIRELESS;
+ }
+ proto.write(BatteryServiceDumpProto.PLUGGED, batteryPluggedValue);
+ proto.write(BatteryServiceDumpProto.MAX_CHARGING_CURRENT, mBatteryProps.maxChargingCurrent);
+ proto.write(BatteryServiceDumpProto.MAX_CHARGING_VOLTAGE, mBatteryProps.maxChargingVoltage);
+ proto.write(BatteryServiceDumpProto.CHARGE_COUNTER, mBatteryProps.batteryChargeCounter);
+ proto.write(BatteryServiceDumpProto.STATUS, mBatteryProps.batteryStatus);
+ proto.write(BatteryServiceDumpProto.HEALTH, mBatteryProps.batteryHealth);
+ proto.write(BatteryServiceDumpProto.IS_PRESENT, mBatteryProps.batteryPresent);
+ proto.write(BatteryServiceDumpProto.LEVEL, mBatteryProps.batteryLevel);
+ proto.write(BatteryServiceDumpProto.SCALE, BATTERY_SCALE);
+ proto.write(BatteryServiceDumpProto.VOLTAGE, mBatteryProps.batteryVoltage);
+ proto.write(BatteryServiceDumpProto.TEMPERATURE, mBatteryProps.batteryTemperature);
+ proto.write(BatteryServiceDumpProto.TECHNOLOGY, mBatteryProps.batteryTechnology);
+ }
+ proto.flush();
+ }
+
private final class Led {
private final Light mBatteryLight;
@@ -878,7 +909,11 @@
return;
}
- dumpInternal(fd, pw, args);
+ if (args.length > 0 && "--proto".equals(args[0])) {
+ dumpProto(fd);
+ } else {
+ dumpInternal(fd, pw, args);
+ }
}
@Override public void onShellCommand(FileDescriptor in, FileDescriptor out,
diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java
index 8020f0e..22eca77 100644
--- a/services/core/java/com/android/server/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/InputMethodManagerService.java
@@ -932,7 +932,9 @@
return;
}
final InputMethodInfo defIm = suitableImes.get(0);
- Slog.i(TAG, "Default found, using " + defIm.getId());
+ if (DEBUG) {
+ Slog.i(TAG, "Default found, using " + defIm.getId());
+ }
setSelectedInputMethodAndSubtypeLocked(defIm, NOT_A_SUBTYPE_ID, false);
}
@@ -1123,6 +1125,7 @@
}
return true;
}
+ // TODO(b/34886274): The semantics of this verification is actually not well-defined.
Slog.w(TAG, "--- IPC called from background users. Ignore. callers="
+ Debug.getCallers(10));
return false;
@@ -1134,8 +1137,18 @@
* @param token The window token given to the input method when it was started.
* @return true if and only if non-null valid token is specified.
*/
- private boolean calledWithValidToken(IBinder token) {
- if (token == null || mCurToken != token) {
+ private boolean calledWithValidToken(@Nullable IBinder token) {
+ if (token == null && Binder.getCallingPid() == Process.myPid()) {
+ if (DEBUG) {
+ // TODO(b/34851776): Basically it's the caller's fault if we reach here.
+ Slog.d(TAG, "Bug 34851776 is detected callers=" + Debug.getCallers(10));
+ }
+ return false;
+ }
+ if (token == null || token != mCurToken) {
+ // TODO(b/34886274): The semantics of this verification is actually not well-defined.
+ Slog.e(TAG, "Ignoring " + Debug.getCaller() + " due to an invalid token."
+ + " uid:" + Binder.getCallingUid() + " token:" + token);
return false;
}
return true;
@@ -1338,8 +1351,10 @@
// because if the focus changes some time before or after, the
// next client receiving focus that has any interest in input will
// be calling through here after that change happens.
- Slog.w(TAG, "Starting input on non-focused client " + cs.client
- + " (uid=" + cs.uid + " pid=" + cs.pid + ")");
+ if (DEBUG) {
+ Slog.w(TAG, "Starting input on non-focused client " + cs.client
+ + " (uid=" + cs.uid + " pid=" + cs.pid + ")");
+ }
return null;
}
} catch (RemoteException e) {
@@ -1457,7 +1472,7 @@
mCurId = info.getId();
mCurToken = new Binder();
try {
- if (true || DEBUG) Slog.v(TAG, "Adding window token: " + mCurToken);
+ if (DEBUG) Slog.v(TAG, "Adding window token: " + mCurToken);
mIWindowManager.addWindowToken(mCurToken, TYPE_INPUT_METHOD, DEFAULT_DISPLAY);
} catch (RemoteException e) {
}
@@ -1662,9 +1677,6 @@
public void updateStatusIcon(IBinder token, String packageName, int iconId) {
synchronized (mMethodMap) {
if (!calledWithValidToken(token)) {
- final int uid = Binder.getCallingUid();
- Slog.e(TAG, "Ignoring updateStatusIcon due to an invalid token. uid:" + uid
- + " token:" + token);
return;
}
final long ident = Binder.clearCallingIdentity();
@@ -1767,9 +1779,6 @@
@Override
public void setImeWindowStatus(IBinder token, int vis, int backDisposition) {
if (!calledWithValidToken(token)) {
- final int uid = Binder.getCallingUid();
- Slog.e(TAG, "Ignoring setImeWindowStatus due to an invalid token. uid:" + uid
- + " token:" + token);
return;
}
@@ -1789,9 +1798,6 @@
// Caution! This method is called in this class. Handle multi-user carefully
private void updateSystemUiLocked(IBinder token, int vis, int backDisposition) {
if (!calledWithValidToken(token)) {
- final int uid = Binder.getCallingUid();
- Slog.e(TAG, "Ignoring updateSystemUiLocked due to an invalid token. uid:" + uid
- + " token:" + token);
return;
}
@@ -2259,8 +2265,10 @@
// because if the focus changes some time before or after, the
// next client receiving focus that has any interest in input will
// be calling through here after that change happens.
- Slog.w(TAG, "Focus gain on non-focused client " + cs.client
- + " (uid=" + cs.uid + " pid=" + cs.pid + ")");
+ if (DEBUG) {
+ Slog.w(TAG, "Focus gain on non-focused client " + cs.client
+ + " (uid=" + cs.uid + " pid=" + cs.pid + ")");
+ }
return null;
}
} catch (RemoteException e) {
@@ -2275,8 +2283,10 @@
}
if (mCurFocusedWindow == windowToken) {
- Slog.w(TAG, "Window already focused, ignoring focus gain of: " + client
- + " attribute=" + attribute + ", token = " + windowToken);
+ if (DEBUG) {
+ Slog.w(TAG, "Window already focused, ignoring focus gain of: " + client
+ + " attribute=" + attribute + ", token = " + windowToken);
+ }
if (attribute != null) {
return startInputUncheckedLocked(cs, inputContext, missingMethods,
attribute, controlFlags);
@@ -2519,9 +2529,6 @@
}
synchronized (mMethodMap) {
if (!calledWithValidToken(token)) {
- final int uid = Binder.getCallingUid();
- Slog.e(TAG, "Ignoring switchToNextInputMethod due to an invalid token. uid:" + uid
- + " token:" + token);
return false;
}
final ImeSubtypeListItem nextSubtype = mSwitchingController.getNextInputMethodLocked(
@@ -2543,9 +2550,6 @@
}
synchronized (mMethodMap) {
if (!calledWithValidToken(token)) {
- final int uid = Binder.getCallingUid();
- Slog.e(TAG, "Ignoring shouldOfferSwitchingToNextInputMethod due to an invalid "
- + "token. uid:" + uid + " token:" + token);
return false;
}
final ImeSubtypeListItem nextSubtype = mSwitchingController.getNextInputMethodLocked(
@@ -2636,9 +2640,6 @@
}
synchronized (mMethodMap) {
if (!calledWithValidToken(token)) {
- final int uid = Binder.getCallingUid();
- Slog.e(TAG, "Ignoring clearLastInputMethodWindowForTransition due to an "
- + "invalid token. uid:" + uid + " token:" + token);
return;
}
}
@@ -2702,9 +2703,6 @@
}
synchronized (mMethodMap) {
if (!calledWithValidToken(token)) {
- final int uid = Binder.getCallingUid();
- Slog.e(TAG, "Ignoring hideInputMethod due to an invalid token. uid:"
- + uid + " token:" + token);
return;
}
long ident = Binder.clearCallingIdentity();
@@ -2723,9 +2721,6 @@
}
synchronized (mMethodMap) {
if (!calledWithValidToken(token)) {
- final int uid = Binder.getCallingUid();
- Slog.e(TAG, "Ignoring showMySoftInput due to an invalid token. uid:"
- + uid + " token:" + token);
return;
}
long ident = Binder.clearCallingIdentity();
@@ -3033,22 +3028,22 @@
PackageManager.GET_META_DATA | PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS,
mSettings.getCurrentUserId());
- final HashMap<String, List<InputMethodSubtype>> additionalSubtypes =
+ final HashMap<String, List<InputMethodSubtype>> additionalSubtypeMap =
mFileManager.getAllAdditionalInputMethodSubtypes();
for (int i = 0; i < services.size(); ++i) {
ResolveInfo ri = services.get(i);
ServiceInfo si = ri.serviceInfo;
- ComponentName compName = new ComponentName(si.packageName, si.name);
- if (!android.Manifest.permission.BIND_INPUT_METHOD.equals(
- si.permission)) {
- Slog.w(TAG, "Skipping input method " + compName
+ final String imeId = InputMethodInfo.computeId(ri);
+ if (!android.Manifest.permission.BIND_INPUT_METHOD.equals(si.permission)) {
+ Slog.w(TAG, "Skipping input method " + imeId
+ ": it does not require the permission "
+ android.Manifest.permission.BIND_INPUT_METHOD);
continue;
}
- if (DEBUG) Slog.d(TAG, "Checking " + compName);
+ if (DEBUG) Slog.d(TAG, "Checking " + imeId);
+ final List<InputMethodSubtype> additionalSubtypes = additionalSubtypeMap.get(imeId);
try {
InputMethodInfo p = new InputMethodInfo(mContext, ri, additionalSubtypes);
mMethodList.add(p);
@@ -3059,7 +3054,7 @@
Slog.d(TAG, "Found an input method " + p);
}
} catch (Exception e) {
- Slog.wtf(TAG, "Unable to load input method " + compName, e);
+ Slog.wtf(TAG, "Unable to load input method " + imeId, e);
}
}
@@ -3076,7 +3071,9 @@
}
}
if (!enabledImeFound) {
- Slog.i(TAG, "All the enabled IMEs are gone. Reset default enabled IMEs.");
+ if (DEBUG) {
+ Slog.i(TAG, "All the enabled IMEs are gone. Reset default enabled IMEs.");
+ }
resetDefaultEnabledIme = true;
resetSelectedInputMethodAndSubtypeLocked("");
}
diff --git a/services/core/java/com/android/server/LockSettingsStrongAuth.java b/services/core/java/com/android/server/LockSettingsStrongAuth.java
index 1314110..f5fe3db 100644
--- a/services/core/java/com/android/server/LockSettingsStrongAuth.java
+++ b/services/core/java/com/android/server/LockSettingsStrongAuth.java
@@ -51,6 +51,7 @@
private static final int MSG_REGISTER_TRACKER = 2;
private static final int MSG_UNREGISTER_TRACKER = 3;
private static final int MSG_REMOVE_USER = 4;
+ private static final int MSG_SCHEDULE_STRONG_AUTH_TIMEOUT = 5;
private static final String STRONG_AUTH_TIMEOUT_ALARM_TAG =
"LockSettingsStrongAuth.timeoutForUser";
@@ -128,6 +129,23 @@
}
}
+ private void handleScheduleStrongAuthTimeout(int userId) {
+ final DevicePolicyManager dpm =
+ (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
+ long when = SystemClock.elapsedRealtime() + dpm.getRequiredStrongAuthTimeout(null, userId);
+ // cancel current alarm listener for the user (if there was one)
+ StrongAuthTimeoutAlarmListener alarm = mStrongAuthTimeoutAlarmListenerForUser.get(userId);
+ if (alarm != null) {
+ mAlarmManager.cancel(alarm);
+ } else {
+ alarm = new StrongAuthTimeoutAlarmListener(userId);
+ mStrongAuthTimeoutAlarmListenerForUser.put(userId, alarm);
+ }
+ // schedule a new alarm listener for the user
+ mAlarmManager.set(AlarmManager.ELAPSED_REALTIME, when, STRONG_AUTH_TIMEOUT_ALARM_TAG,
+ alarm, mHandler);
+ }
+
private void notifyStrongAuthTrackers(int strongAuthReason, int userId) {
for (int i = 0; i < mStrongAuthTrackers.size(); i++) {
try {
@@ -151,7 +169,8 @@
}
public void removeUser(int userId) {
- mHandler.obtainMessage(MSG_REMOVE_USER, userId, 0).sendToTarget();
+ final int argNotUsed = 0;
+ mHandler.obtainMessage(MSG_REMOVE_USER, userId, argNotUsed).sendToTarget();
}
public void requireStrongAuth(int strongAuthReason, int userId) {
@@ -169,29 +188,8 @@
}
public void reportSuccessfulStrongAuthUnlock(int userId) {
- scheduleStrongAuthTimeout(userId);
- }
-
- private void scheduleStrongAuthTimeout(int userId) {
- final DevicePolicyManager dpm =
- (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
- long when = SystemClock.elapsedRealtime() + dpm.getRequiredStrongAuthTimeout(null, userId);
- // cancel current alarm listener for the user (if there was one)
- StrongAuthTimeoutAlarmListener alarm = mStrongAuthTimeoutAlarmListenerForUser.get(userId);
- if (alarm != null) {
- mAlarmManager.cancel(alarm);
- } else {
- alarm = new StrongAuthTimeoutAlarmListener(userId);
- mStrongAuthTimeoutAlarmListenerForUser.put(userId, alarm);
- }
- // schedule a new alarm listener for the user
- final long ident = Binder.clearCallingIdentity();
- try {
- mAlarmManager.set(AlarmManager.ELAPSED_REALTIME, when, STRONG_AUTH_TIMEOUT_ALARM_TAG,
- alarm, mHandler);
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
+ final int argNotUsed = 0;
+ mHandler.obtainMessage(MSG_SCHEDULE_STRONG_AUTH_TIMEOUT, userId, argNotUsed).sendToTarget();
}
private class StrongAuthTimeoutAlarmListener implements OnAlarmListener {
@@ -224,6 +222,9 @@
case MSG_REMOVE_USER:
handleRemoveUser(msg.arg1);
break;
+ case MSG_SCHEDULE_STRONG_AUTH_TIMEOUT:
+ handleScheduleStrongAuthTimeout(msg.arg1);
+ break;
}
}
};
diff --git a/services/core/java/com/android/server/NetworkScoreService.java b/services/core/java/com/android/server/NetworkScoreService.java
index 25016f6..5fe8b1a 100644
--- a/services/core/java/com/android/server/NetworkScoreService.java
+++ b/services/core/java/com/android/server/NetworkScoreService.java
@@ -183,11 +183,12 @@
// connection.
if (DBG) Log.d(TAG, "No active scorers available.");
unbindFromScoringServiceIfNeeded();
- } else if (activeScorer.packageName.equals(scorerPackageName)) {
+ } else if (activeScorer.getRecommendationServicePackageName().equals(scorerPackageName))
+ {
// The active scoring service changed in some way.
if (DBG) {
Log.d(TAG, "Possible change to the active scorer: "
- + activeScorer.packageName);
+ + activeScorer.getRecommendationServicePackageName());
}
if (forceUnbind) {
unbindFromScoringServiceIfNeeded();
@@ -198,7 +199,8 @@
// bound to the correct scoring app. The logic in bindToScoringServiceIfNeeded()
// will sort that out to leave us bound to the most recent active scorer.
if (DBG) {
- Log.d(TAG, "Binding to " + activeScorer.packageName + " if needed.");
+ Log.d(TAG, "Binding to " + activeScorer.getRecommendationServiceComponent()
+ + " if needed.");
}
bindToScoringServiceIfNeeded(activeScorer);
}
@@ -334,22 +336,19 @@
bindToScoringServiceIfNeeded(scorerData);
}
- private void bindToScoringServiceIfNeeded(NetworkScorerAppData scorerData) {
- if (DBG) Log.d(TAG, "bindToScoringServiceIfNeeded(" + scorerData + ")");
- if (scorerData != null && scorerData.recommendationServiceClassName != null) {
- ComponentName componentName = new ComponentName(scorerData.packageName,
- scorerData.recommendationServiceClassName);
+ private void bindToScoringServiceIfNeeded(NetworkScorerAppData appData) {
+ if (DBG) Log.d(TAG, "bindToScoringServiceIfNeeded(" + appData + ")");
+ if (appData != null) {
synchronized (mServiceConnectionLock) {
// If we're connected to a different component then drop it.
if (mServiceConnection != null
- && !mServiceConnection.mComponentName.equals(componentName)) {
+ && !mServiceConnection.mAppData.equals(appData)) {
unbindFromScoringServiceIfNeeded();
}
// If we're not connected at all then create a new connection.
if (mServiceConnection == null) {
- mServiceConnection = new ScoringServiceConnection(componentName,
- scorerData.packageUid);
+ mServiceConnection = new ScoringServiceConnection(appData);
}
// Make sure the connection is connected (idempotent)
@@ -625,7 +624,7 @@
}
}
- private boolean isCallerSystemUid() {
+ private boolean callerCanRequestScores() {
// REQUEST_NETWORK_SCORES is a signature only permission.
return mContext.checkCallingOrSelfPermission(permission.REQUEST_NETWORK_SCORES) ==
PackageManager.PERMISSION_GRANTED;
@@ -634,7 +633,7 @@
@Override
public boolean clearScores() {
// Only the active scorer or the system should be allowed to flush all scores.
- if (isCallerActiveScorer(getCallingUid()) || isCallerSystemUid()) {
+ if (isCallerActiveScorer(getCallingUid()) || callerCanRequestScores()) {
final long token = Binder.clearCallingIdentity();
try {
clearInternal();
@@ -672,7 +671,8 @@
@Override
public boolean isCallerActiveScorer(int callingUid) {
synchronized (mServiceConnectionLock) {
- return mServiceConnection != null && mServiceConnection.mScoringAppUid == callingUid;
+ return mServiceConnection != null
+ && mServiceConnection.mAppData.packageUid == callingUid;
}
}
@@ -686,7 +686,7 @@
public String getActiveScorerPackage() {
synchronized (mServiceConnectionLock) {
if (mServiceConnection != null) {
- return mServiceConnection.mComponentName.getPackageName();
+ return mServiceConnection.getPackageName();
}
}
return null;
@@ -695,7 +695,7 @@
@Override
public void disableScoring() {
// Only the active scorer or the system should be allowed to disable scoring.
- if (isCallerActiveScorer(getCallingUid()) || isCallerSystemUid()) {
+ if (isCallerActiveScorer(getCallingUid()) || callerCanRequestScores()) {
// no-op for now but we could write to the setting if needed.
} else {
throw new SecurityException(
@@ -881,7 +881,7 @@
writer.println("Scoring is disabled.");
return;
}
- writer.println("Current scorer: " + currentScorer.packageName);
+ writer.println("Current scorer: " + currentScorer);
sendCacheUpdateCallback(new BiConsumer<INetworkScoreCache, Object>() {
@Override
@@ -927,7 +927,7 @@
try {
for (int i = 0; i < count; i++) {
consumer.accept(callbackList.getBroadcastItem(i),
- callbackList.getRegisteredCallbackCookie(i));
+ callbackList.getBroadcastCookie(i));
}
} finally {
callbackList.finishBroadcast();
@@ -966,21 +966,19 @@
}
private static class ScoringServiceConnection implements ServiceConnection {
- private final ComponentName mComponentName;
- private final int mScoringAppUid;
+ private final NetworkScorerAppData mAppData;
private volatile boolean mBound = false;
private volatile boolean mConnected = false;
private volatile INetworkRecommendationProvider mRecommendationProvider;
- ScoringServiceConnection(ComponentName componentName, int scoringAppUid) {
- mComponentName = componentName;
- mScoringAppUid = scoringAppUid;
+ ScoringServiceConnection(NetworkScorerAppData appData) {
+ mAppData = appData;
}
void connect(Context context) {
if (!mBound) {
Intent service = new Intent(NetworkScoreManager.ACTION_RECOMMEND_NETWORKS);
- service.setComponent(mComponentName);
+ service.setComponent(mAppData.getRecommendationServiceComponent());
mBound = context.bindServiceAsUser(service, this,
Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE,
UserHandle.SYSTEM);
@@ -1010,6 +1008,10 @@
return mRecommendationProvider;
}
+ String getPackageName() {
+ return mAppData.getRecommendationServiceComponent().getPackageName();
+ }
+
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
if (DBG) Log.d(TAG, "ScoringServiceConnection: " + name.flattenToString());
@@ -1027,7 +1029,9 @@
}
public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
- writer.println("ScoringServiceConnection: " + mComponentName + ", bound: " + mBound
+ writer.println("ScoringServiceConnection: "
+ + mAppData.getRecommendationServiceComponent()
+ + ", bound: " + mBound
+ ", connected: " + mConnected);
}
}
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index bfa3f04..fdd7cb1 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -287,16 +287,17 @@
* and then rebuild the cache. All under the cache lock. But that change is too
* large at this point.
*/
+ final String removedPackageName = intent.getData().toString();
Runnable purgingRunnable = new Runnable() {
@Override
public void run() {
purgeOldGrantsAll();
// Notify authenticator about removed app?
+ removeVisibilityValuesForPackage(removedPackageName);
}
};
mHandler.post(purgingRunnable);
}
-
}
}, intentFilter);
@@ -429,7 +430,7 @@
@Override
public boolean addAccountExplicitlyWithVisibility(Account account, String password,
- Bundle extras, Map uidToVisibility) {
+ Bundle extras, Map packageToVisibility) {
Bundle.setDefusable(extras, true);
final int callingUid = Binder.getCallingUid();
@@ -455,7 +456,7 @@
try {
UserAccounts accounts = getUserAccounts(userId);
return addAccountInternal(accounts, account, password, extras, callingUid,
- (Map<Integer, Integer>) uidToVisibility);
+ (Map<String, Integer>) packageToVisibility);
} finally {
restoreCallingIdentity(identityToken);
}
@@ -505,7 +506,7 @@
if (accountsOfType != null) {
for (Account account : accountsOfType) {
result.put(account,
- resolveAccountVisibility(account, uid, packageName, accounts));
+ resolveAccountVisibility(account, packageName, accounts));
}
}
}
@@ -514,7 +515,7 @@
}
@Override
- public Map<Integer, Integer> getUidsAndVisibilityForAccount(Account account) {
+ public Map<String, Integer> getPackagesAndVisibilityForAccount(Account account) {
if (account == null) throw new IllegalArgumentException("account is null");
int callingUid = Binder.getCallingUid();
int userId = UserHandle.getUserId(callingUid);
@@ -525,18 +526,18 @@
String.format("uid %s cannot get secrets for account %s", callingUid, account);
throw new SecurityException(msg);
}
- return getUidsAndVisibilityForAccount(account, accounts);
+ return getPackagesAndVisibilityForAccount(account, accounts);
}
/**
- * Returns all UIDs and visibility values, which were set for given account
+ * Returns all package names and visibility values, which were set for given account.
*
- * @param account account
+ * @param account Account to get visibility values.
* @param accounts UserAccount that currently hosts the account and application
*
- * @return Map from uid to visibility.
+ * @return Map from package names to visibility.
*/
- private Map<Integer, Integer> getUidsAndVisibilityForAccount(Account account,
+ private Map<String, Integer> getPackagesAndVisibilityForAccount(Account account,
UserAccounts accounts) {
final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
try {
@@ -548,7 +549,7 @@
}
@Override
- public int getAccountVisibility(Account a, int uid) {
+ public int getAccountVisibility(Account a, String packageName) {
if (a == null) throw new IllegalArgumentException("account is null");
int callingUid = Binder.getCallingUid();
if (!isAccountManagedByCaller(a.type, callingUid, UserHandle.getUserId(callingUid))
@@ -559,23 +560,24 @@
a.type);
throw new SecurityException(msg);
}
- return getAccountVisibility(a, uid, getUserAccounts(UserHandle.getUserId(callingUid)));
+ return getAccountVisibility(a, packageName,
+ getUserAccounts(UserHandle.getUserId(callingUid)));
}
/**
- * Method gets visibility for given account and UID from the database
+ * Method returns visibility for given account and package name.
*
- * @param account The account to check visibility of
- * @param uid UID to check visibility of
+ * @param account The account to check visibility.
+ * @param packageName Package name to check visibility.
* @param accounts UserAccount that currently hosts the account and application
*
* @return Visibility value, AccountManager.VISIBILITY_UNDEFINED if no value was stored.
*
*/
- private int getAccountVisibility(Account account, int uid, UserAccounts accounts) {
+ private int getAccountVisibility(Account account, String packageName, UserAccounts accounts) {
final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
try {
- Integer visibility = accounts.accountsDb.findAccountVisibility(account, uid);
+ Integer visibility = accounts.accountsDb.findAccountVisibility(account, packageName);
return visibility != null ? visibility : AccountManager.VISIBILITY_UNDEFINED;
} finally {
StrictMode.setThreadPolicy(oldPolicy);
@@ -586,19 +588,29 @@
* Method which handles default values for Account visibility.
*
* @param account The account to check visibility.
- * @param uid UID to check visibility.
- * @param packageName Package name to check visibility - the method assumes that it has the same
- * uid as specified in the parameter.
+ * @param packageName Package name to check visibility
* @param accounts UserAccount that currently hosts the account and application
*
* @return Visibility value, the method never returns AccountManager.VISIBILITY_UNDEFINED
*
*/
- private Integer resolveAccountVisibility(Account account, int uid, String packageName,
+ private Integer resolveAccountVisibility(Account account, @NonNull String packageName,
UserAccounts accounts) {
- if (packageName == null) {
- packageName = getPackageNameForUid(uid);
+ Preconditions.checkNotNull(packageName, "packageName cannot be null");
+
+ int uid = -1;
+ try {
+ long identityToken = clearCallingIdentity();
+ try {
+ uid = mPackageManager.getPackageUidAsUser(packageName, accounts.userId);
+ } finally {
+ restoreCallingIdentity(identityToken);
+ }
+ } catch (NameNotFoundException e) {
+ Log.d(TAG, "Package not found " + e.getMessage());
+ return AccountManager.VISIBILITY_NOT_VISIBLE;
}
+
// System visibility can not be restricted.
if (UserHandle.isSameApp(uid, Process.SYSTEM_UID)) {
return AccountManager.VISIBILITY_VISIBLE;
@@ -612,8 +624,13 @@
return AccountManager.VISIBILITY_VISIBLE; // Authenticator can always see the account
}
+ if (isSpecialPackageKey(packageName)) {
+ Log.d(TAG, "Package name is forbidden: " + packageName);
+ return AccountManager.VISIBILITY_NOT_VISIBLE;
+ }
+
// Return stored value if it was set.
- int visibility = getAccountVisibility(account, uid, accounts);
+ int visibility = getAccountVisibility(account, packageName, accounts);
if (AccountManager.VISIBILITY_UNDEFINED != visibility) {
return visibility;
@@ -622,10 +639,9 @@
if (isPermittedForPackage(packageName, accounts.userId,
Manifest.permission.GET_ACCOUNTS_PRIVILEGED)) {
return AccountManager.VISIBILITY_VISIBLE;
-
}
// Profile owner gets visibility by default.
- if(isProfileOwner(uid)) {
+ if (isProfileOwner(uid)) {
return AccountManager.VISIBILITY_VISIBLE;
}
// Apps with READ_CONTACTS permission get visibility by default even post O.
@@ -638,13 +654,13 @@
// Use legacy for preO apps with GET_ACCOUNTS permission or pre/postO with signature
// match.
visibility = getAccountVisibility(account,
- AccountManager.UID_KEY_DEFAULT_LEGACY_VISIBILITY, accounts);
+ AccountManager.PACKAGE_NAME_KEY_LEGACY_VISIBLE, accounts);
if (AccountManager.VISIBILITY_UNDEFINED == visibility) {
visibility = AccountManager.VISIBILITY_USER_MANAGED_VISIBLE;
}
} else {
- visibility = getAccountVisibility(account, AccountManager.UID_KEY_DEFAULT_VISIBILITY,
- accounts);
+ visibility = getAccountVisibility(account,
+ AccountManager.PACKAGE_NAME_KEY_LEGACY_NOT_VISIBLE, accounts);
if (AccountManager.VISIBILITY_UNDEFINED == visibility) {
visibility = AccountManager.VISIBILITY_USER_MANAGED_NOT_VISIBLE;
}
@@ -655,7 +671,7 @@
/**
* Checks targetSdk for a package;
*
- * @param packageName Package Name
+ * @param packageName Package name
*
* @return True if package's target SDK is below {@link android.os.Build.VERSION_CODES#O}, or
* undefined
@@ -682,7 +698,7 @@
}
@Override
- public boolean setAccountVisibility(Account a, int uid, int newVisibility) {
+ public boolean setAccountVisibility(Account a, String packageName, int newVisibility) {
if (a == null) throw new IllegalArgumentException("account is null");
int callingUid = Binder.getCallingUid();
if (!isAccountManagedByCaller(a.type, callingUid, UserHandle.getUserId(callingUid))
@@ -693,38 +709,42 @@
a.type);
throw new SecurityException(msg);
}
- return setAccountVisibility(a, uid, newVisibility, true /* notify */,
+ return setAccountVisibility(a, packageName, newVisibility, true /* notify */,
getUserAccounts(UserHandle.getUserId(callingUid)));
}
/**
- * Gives a certain UID, represented a application, access to an account. This method
- * is called indirectly by the Authenticator.
+ * Updates visibility for given account name and package.
*
- * @param account Account to update visibility
- * @param uid to add visibility of the Account
- * @param newVisibility new visibility
+ * @param account Account to update visibility.
+ * @param packageName Package name for which visibility is updated.
+ * @param newVisibility New visibility calue
* @param notify if the flag is set applications will get notification about visibility change
* @param accounts UserAccount that currently hosts the account and application
*
* @return True if account visibility was changed.
*/
- private boolean setAccountVisibility(Account account, int uid, int newVisibility,
+ private boolean setAccountVisibility(Account account, String packageName, int newVisibility,
boolean notify, UserAccounts accounts) {
synchronized (accounts.cacheLock) {
LinkedHashSet<String> interestedPackages;
if (notify) {
- if (uid < 0) {
+ if (isSpecialPackageKey(packageName)) {
interestedPackages = getRequestingPackageNames(account.type, accounts);
} else {
- interestedPackages = new LinkedHashSet<>();
- String[] subPackages = mPackageManager.getPackagesForUid(uid);
- if (subPackages != null) {
- Collections.addAll(interestedPackages, subPackages);
+ if (!packageExistsForUser(packageName, accounts.userId)) {
+ return false; // package is not installed.
}
+ interestedPackages = new LinkedHashSet<>();
+ interestedPackages.add(packageName);
}
} else {
// Notifications will not be send.
+ if (!isSpecialPackageKey(packageName) &&
+ !packageExistsForUser(packageName, accounts.userId)) {
+ // package is not installed and not meta value.
+ return false;
+ }
interestedPackages = new LinkedHashSet<>();
}
Integer[] interestedPackagesVisibility = new Integer[interestedPackages.size()];
@@ -734,14 +754,15 @@
return false;
}
int index = 0;
- for (String packageName : interestedPackages) {
+ for (String interestedPackage : interestedPackages) {
interestedPackagesVisibility[index++] =
- resolveAccountVisibility(account, uid, packageName, accounts);
+ resolveAccountVisibility(account, interestedPackage, accounts);
}
final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
try {
- if (!accounts.accountsDb.setAccountVisibility(accountId, uid, newVisibility)) {
+ if (!accounts.accountsDb.setAccountVisibility(accountId, packageName,
+ newVisibility)) {
return false;
}
} finally {
@@ -749,10 +770,10 @@
}
index = 0;
- for (String packageName : interestedPackages) {
- int visibility = resolveAccountVisibility(account, uid, packageName, accounts);
+ for (String interestedPackage : interestedPackages) {
+ int visibility = resolveAccountVisibility(account, interestedPackage, accounts);
if (visibility != interestedPackagesVisibility[index++]) {
- sendNotification(packageName, account, accounts.userId);
+ sendNotification(interestedPackage, account, accounts.userId);
}
}
if (notify) {
@@ -777,23 +798,40 @@
LinkedHashSet<String> interestedPackages = getRequestingPackageNames(account.type,
accounts);
for (String packageName : interestedPackages) {
- try {
- final int uid = mPackageManager.getPackageUidAsUser(packageName, accounts.userId);
- int visibility = resolveAccountVisibility(account, uid, packageName, accounts);
- if (visibility != AccountManager.VISIBILITY_NOT_VISIBLE) {
- sendNotification(packageName, account, accounts.userId);
- }
- } catch (NameNotFoundException e) {
- // ignore
+ int visibility = resolveAccountVisibility(account, packageName, accounts);
+ if (visibility != AccountManager.VISIBILITY_NOT_VISIBLE) {
+ sendNotification(packageName, account, accounts.userId);
}
}
}
- LinkedHashSet<String> getRequestingPackageNames(String accountType, UserAccounts accouns) {
+ LinkedHashSet<String> getRequestingPackageNames(String accountType, UserAccounts accounts) {
// TODO return packages registered to get notifications.
return new LinkedHashSet<String>();
}
+ private boolean packageExistsForUser(String packageName, int userId) {
+ try {
+ long identityToken = clearCallingIdentity();
+ try {
+ mPackageManager.getPackageUidAsUser(packageName, userId);
+ return true; // package exist
+ } finally {
+ restoreCallingIdentity(identityToken);
+ }
+ } catch (NameNotFoundException e) {
+ return false;
+ }
+ }
+
+ /**
+ * Returns true if packageName is one of special values.
+ */
+ private boolean isSpecialPackageKey(String packageName) {
+ return (AccountManager.PACKAGE_NAME_KEY_LEGACY_VISIBLE.equals(packageName)
+ || AccountManager.PACKAGE_NAME_KEY_LEGACY_NOT_VISIBLE.equals(packageName));
+ }
+
private void sendAccountsChangedBroadcast(int userId) {
Log.i(TAG, "the accounts changed, sending broadcast of "
+ ACCOUNTS_CHANGED_INTENT.getAction());
@@ -1075,6 +1113,20 @@
}
}
+ private void removeVisibilityValuesForPackage(String packageName) {
+ synchronized (mUsers) {
+ for (int i = 0; i < mUsers.size(); i++) {
+ UserAccounts accounts = mUsers.valueAt(i);
+ try {
+ int uid = mPackageManager.getPackageUidAsUser(packageName, accounts.userId);
+ } catch (NameNotFoundException e) {
+ // package does not exist - remove visibility values
+ accounts.accountsDb.deleteAccountVisibilityForPackage(packageName);
+ }
+ }
+ }
+ }
+
private void onUserRemoved(Intent intent) {
int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
if (userId < 1) return;
@@ -1472,7 +1524,7 @@
}
private boolean addAccountInternal(UserAccounts accounts, Account account, String password,
- Bundle extras, int callingUid, Map<Integer, Integer> uidToVisibility) {
+ Bundle extras, int callingUid, Map<String, Integer> packageToVisibility) {
Bundle.setDefusable(extras, true);
if (account == null) {
return false;
@@ -1513,9 +1565,9 @@
}
}
- if (uidToVisibility != null) {
- for (Entry<Integer, Integer> entry : uidToVisibility.entrySet()) {
- setAccountVisibility(account, entry.getKey() /* uid */,
+ if (packageToVisibility != null) {
+ for (Entry<String, Integer> entry : packageToVisibility.entrySet()) {
+ setAccountVisibility(account, entry.getKey() /* package */,
entry.getValue() /* visibility */, false /* notify */, accounts);
}
}
@@ -1569,6 +1621,7 @@
public void hasFeatures(IAccountManagerResponse response,
Account account, String[] features, String opPackageName) {
int callingUid = Binder.getCallingUid();
+ mAppOpsManager.checkPackage(callingUid, opPackageName);
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "hasFeatures: " + account
+ ", response " + response
@@ -1982,14 +2035,7 @@
int[] visibilityForInterestedPackages = new int[interestedPackages.size()];
int index = 0;
for (String packageName : interestedPackages) {
- int visibility = AccountManager.VISIBILITY_NOT_VISIBLE;
- try {
- final int uid = mPackageManager.getPackageUidAsUser(packageName,
- UserHandle.getUserId(callingUid));
- visibility = resolveAccountVisibility(account, uid, packageName, accounts);
- } catch (NameNotFoundException e) {
- // ignore
- }
+ int visibility = resolveAccountVisibility(account, packageName, accounts);
visibilityForInterestedPackages[index++] = visibility;
}
accounts.accountsDb.beginTransaction();
@@ -3663,7 +3709,7 @@
// In addition to the permissions required to get an auth token we also allow
// the account to be accessed by apps for which user or authenticator granted visibility.
- int visibility = resolveAccountVisibility(account, uid, packageName,
+ int visibility = resolveAccountVisibility(account, packageName,
getUserAccounts(UserHandle.getUserId(uid)));
return (visibility == AccountManager.VISIBILITY_VISIBLE
|| visibility == AccountManager.VISIBILITY_USER_MANAGED_VISIBLE);
@@ -3870,6 +3916,7 @@
@NonNull
public Account[] getAccounts(int userId, String opPackageName) {
int callingUid = Binder.getCallingUid();
+ mAppOpsManager.checkPackage(callingUid, opPackageName);
List<String> visibleAccountTypes = getTypesVisibleToCaller(callingUid, userId,
opPackageName);
if (visibleAccountTypes.isEmpty()) {
@@ -3890,7 +3937,7 @@
}
/**
- * Returns accounts for all running users.
+ * Returns accounts for all running users, ignores visibility values.
*
* @hide
*/
@@ -3906,7 +3953,11 @@
return getAccounts(runningUserIds);
}
- /** {@hide} */
+ /**
+ * Returns accounts for all users, ignores visibility values.
+ *
+ * @hide
+ */
@NonNull
public AccountAndUser[] getAllAccounts() {
final List<UserInfo> users = getUserManager().getUsers(true);
@@ -3924,10 +3975,12 @@
UserAccounts userAccounts = getUserAccounts(userId);
if (userAccounts == null) continue;
synchronized (userAccounts.cacheLock) {
- Account[] accounts = getAccountsFromCacheLocked(userAccounts, null,
+ Account[] accounts = getAccountsFromCacheLocked(
+ userAccounts,
+ null /* type */,
Binder.getCallingUid(),
- null,
- false /* incl managed not visible*/);
+ null /* packageName */,
+ false /* include managed not visible*/);
for (int a = 0; a < accounts.length; a++) {
runningAccounts.add(new AccountAndUser(accounts[a], userId));
}
@@ -3941,9 +3994,10 @@
@Override
@NonNull
public Account[] getAccountsAsUser(String type, int userId, String opPackageName) {
- // Need calling package
- return getAccountsAsUser(type, userId, null /* callingPackage */, -1, opPackageName,
- false /* includeUserManagedNotVisible */);
+ int callingUid = Binder.getCallingUid();
+ mAppOpsManager.checkPackage(callingUid, opPackageName);
+ return getAccountsAsUser(type, userId, opPackageName /* callingPackage */, -1,
+ opPackageName, false /* includeUserManagedNotVisible */);
}
@NonNull
@@ -4112,6 +4166,7 @@
public Account[] getAccountsForPackage(String packageName, int uid, String opPackageName) {
int callingUid = Binder.getCallingUid();
if (!UserHandle.isSameApp(callingUid, Process.SYSTEM_UID)) {
+ // Don't do opPackageName check - caller is system.
throw new SecurityException("getAccountsForPackage() called from unauthorized uid "
+ callingUid + " with uid=" + uid);
}
@@ -4125,6 +4180,7 @@
String opPackageName) {
int callingUid = Binder.getCallingUid();
int userId = UserHandle.getCallingUserId();
+ mAppOpsManager.checkPackage(callingUid, opPackageName);
int packageUid = -1;
try {
packageUid = mPackageManager.getPackageUidAsUser(packageName, userId);
@@ -4148,6 +4204,7 @@
String[] features,
String opPackageName) {
int callingUid = Binder.getCallingUid();
+ mAppOpsManager.checkPackage(callingUid, opPackageName);
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "getAccounts: accountType " + type
+ ", response " + response
@@ -4738,7 +4795,7 @@
userAccounts.accountsDb.dumpDeAccountsTable(fout);
} else {
Account[] accounts = getAccountsFromCacheLocked(userAccounts, null /* type */,
- Process.SYSTEM_UID, null, false);
+ Process.SYSTEM_UID, null /* packageName */, false);
fout.println("Accounts: " + accounts.length);
for (Account account : accounts) {
fout.println(" " + account);
@@ -4954,7 +5011,7 @@
// Method checks visibility for applications targeing API level below {@link
// android.os.Build.VERSION_CODES#O},
- // returns true if the the app has GET_ACCOUNTS or GET_ACCOUNTS_PRIVELEGED permission.
+ // returns true if the the app has GET_ACCOUNTS or GET_ACCOUNTS_PRIVILEGED permission.
private boolean checkGetAccountsPermission(String packageName, int userId) {
return isPermittedForPackage(packageName, userId, Manifest.permission.GET_ACCOUNTS,
Manifest.permission.GET_ACCOUNTS_PRIVILEGED);
@@ -5307,8 +5364,7 @@
// filter based on visibility.
Map<Account, Integer> firstPass = new HashMap<>();
for (Account account : unfiltered) {
- int visibility =
- resolveAccountVisibility(account, callingUid, callingPackage, accounts);
+ int visibility = resolveAccountVisibility(account, callingPackage, accounts);
if ((visibility == AccountManager.VISIBILITY_VISIBLE
|| visibility == AccountManager.VISIBILITY_USER_MANAGED_VISIBLE)
|| (includeManagedNotVisible
@@ -5403,6 +5459,9 @@
*/
protected Account[] getAccountsFromCacheLocked(UserAccounts userAccounts, String accountType,
int callingUid, String callingPackage, boolean includeManagedNotVisible) {
+ if (callingPackage == null) {
+ callingPackage = getPackageNameForUid(callingUid);
+ }
if (accountType != null) {
final Account[] accounts = userAccounts.accountCache.get(accountType);
if (accounts == null) {
diff --git a/services/core/java/com/android/server/accounts/AccountsDb.java b/services/core/java/com/android/server/accounts/AccountsDb.java
index 85e4b5f..22543cb 100644
--- a/services/core/java/com/android/server/accounts/AccountsDb.java
+++ b/services/core/java/com/android/server/accounts/AccountsDb.java
@@ -54,7 +54,7 @@
private static final String DATABASE_NAME = "accounts.db";
private static final int PRE_N_DATABASE_VERSION = 9;
private static final int CE_DATABASE_VERSION = 10;
- private static final int DE_DATABASE_VERSION = 2; // Added visibility support in O.
+ private static final int DE_DATABASE_VERSION = 3; // Added visibility support in O
static final String TABLE_ACCOUNTS = "accounts";
@@ -75,7 +75,7 @@
private static final String TABLE_VISIBILITY = "visibility";
private static final String VISIBILITY_ACCOUNTS_ID = "accounts_id";
- private static final String VISIBILITY_UID = "_uid";
+ private static final String VISIBILITY_PACKAGE = "_package";
private static final String VISIBILITY_VALUE = "value";
private static final String TABLE_GRANTS = "grants";
@@ -252,7 +252,7 @@
createAccountsDeletionTrigger(db);
db.execSQL("DROP TABLE IF EXISTS " + TABLE_GRANTS);
db.execSQL("DROP TABLE IF EXISTS " + TABLE_DEBUG);
- oldVersion ++;
+ oldVersion++;
}
if (oldVersion != newVersion) {
@@ -559,9 +559,9 @@
private void createAccountsVisibilityTable(SQLiteDatabase db) {
db.execSQL("CREATE TABLE " + TABLE_VISIBILITY + " ( "
+ VISIBILITY_ACCOUNTS_ID + " INTEGER NOT NULL, "
- + VISIBILITY_UID + " TEXT NOT NULL, "
+ + VISIBILITY_PACKAGE + " TEXT NOT NULL, "
+ VISIBILITY_VALUE + " INTEGER, "
- + "PRIMARY KEY(" + VISIBILITY_ACCOUNTS_ID + "," + VISIBILITY_UID + "))");
+ + "PRIMARY KEY(" + VISIBILITY_ACCOUNTS_ID + "," + VISIBILITY_PACKAGE + "))");
}
static void createDebugTable(SQLiteDatabase db) {
@@ -591,9 +591,18 @@
Log.i(TAG, "upgrade from version " + oldVersion + " to version " + newVersion);
if (oldVersion == 1) {
- createAccountsVisibilityTable(db);
- createAccountsDeletionVisibilityCleanupTrigger(db);
- ++oldVersion;
+ createAccountsVisibilityTable(db);
+ createAccountsDeletionVisibilityCleanupTrigger(db);
+ oldVersion = 3; // skip version 2 which had uid based table
+ }
+
+ if (oldVersion == 2) {
+ // Remove uid based table and replace it with packageName based
+ db.execSQL("DROP TRIGGER IF EXISTS " + TABLE_ACCOUNTS + "DeleteVisibility");
+ db.execSQL("DROP TABLE IF EXISTS " + TABLE_VISIBILITY);
+ createAccountsVisibilityTable(db);
+ createAccountsDeletionVisibilityCleanupTrigger(db);
+ oldVersion++;
}
if (oldVersion != newVersion) {
@@ -890,20 +899,20 @@
new String[] {Integer.toString(uid)}) > 0;
}
- boolean setAccountVisibility(long accountId, int uid, int visibility) {
+ boolean setAccountVisibility(long accountId, String packageName, int visibility) {
SQLiteDatabase db = mDeDatabase.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(VISIBILITY_ACCOUNTS_ID, String.valueOf(accountId));
- values.put(VISIBILITY_UID, String.valueOf(uid));
+ values.put(VISIBILITY_PACKAGE, packageName);
values.put(VISIBILITY_VALUE, String.valueOf(visibility));
return (db.replace(TABLE_VISIBILITY, VISIBILITY_VALUE, values) != -1);
}
- Integer findAccountVisibility(Account account, int uid) {
+ Integer findAccountVisibility(Account account, String packageName) {
SQLiteDatabase db = mDeDatabase.getWritableDatabase();
final Cursor cursor = db.query(TABLE_VISIBILITY, new String[] {VISIBILITY_VALUE},
- SELECTION_ACCOUNTS_ID_BY_ACCOUNT + " AND " + VISIBILITY_UID + "=? ",
- new String[] {account.name, account.type, String.valueOf(uid)}, null, null, null);
+ SELECTION_ACCOUNTS_ID_BY_ACCOUNT + " AND " + VISIBILITY_PACKAGE + "=? ",
+ new String[] {account.name, account.type, packageName}, null, null, null);
try {
while (cursor.moveToNext()) {
return cursor.getInt(0);
@@ -914,11 +923,11 @@
return null;
}
- Integer findAccountVisibility(long accountId, int uid) {
+ Integer findAccountVisibility(long accountId, String packageName) {
SQLiteDatabase db = mDeDatabase.getWritableDatabase();
final Cursor cursor = db.query(TABLE_VISIBILITY, new String[] {VISIBILITY_VALUE},
- VISIBILITY_ACCOUNTS_ID + "=? AND " + VISIBILITY_UID + "=? ",
- new String[] {String.valueOf(accountId), String.valueOf(uid)}, null, null, null);
+ VISIBILITY_ACCOUNTS_ID + "=? AND " + VISIBILITY_PACKAGE + "=? ",
+ new String[] {String.valueOf(accountId), packageName}, null, null, null);
try {
while (cursor.moveToNext()) {
return cursor.getInt(0);
@@ -944,18 +953,18 @@
}
/**
- * Returns a map from uid to visibility value.
+ * Returns a map from packageNames to visibility.
*/
- Map<Integer, Integer> findAllVisibilityValuesForAccount(Account account) {
+ Map<String, Integer> findAllVisibilityValuesForAccount(Account account) {
SQLiteDatabase db = mDeDatabase.getReadableDatabase();
- Map<Integer, Integer> result = new HashMap<>();
+ Map<String, Integer> result = new HashMap<>();
final Cursor cursor =
- db.query(TABLE_VISIBILITY, new String[] {VISIBILITY_UID, VISIBILITY_VALUE},
- SELECTION_ACCOUNTS_ID_BY_ACCOUNT,
- new String[] {account.name, account.type}, null, null, null);
+ db.query(TABLE_VISIBILITY, new String[] {VISIBILITY_PACKAGE, VISIBILITY_VALUE},
+ SELECTION_ACCOUNTS_ID_BY_ACCOUNT, new String[] {account.name, account.type},
+ null, null, null);
try {
while (cursor.moveToNext()) {
- result.put(cursor.getInt(0), cursor.getInt(1));
+ result.put(cursor.getString(0), cursor.getInt(1));
}
} finally {
cursor.close();
@@ -963,10 +972,10 @@
return result;
}
- boolean deleteAccountVisibilityForUid(int uid) {
+ boolean deleteAccountVisibilityForPackage(String packageName) {
SQLiteDatabase db = mDeDatabase.getWritableDatabase();
- return db.delete(TABLE_VISIBILITY, VISIBILITY_UID + "=? ",
- new String[] {Integer.toString(uid)}) > 0;
+ return db.delete(TABLE_VISIBILITY, VISIBILITY_PACKAGE + "=? ",
+ new String[] {packageName}) > 0;
}
long insertOrReplaceMetaAuthTypeAndUid(String authenticatorType, int uid) {
diff --git a/services/core/java/com/android/server/am/ActiveInstrumentation.java b/services/core/java/com/android/server/am/ActiveInstrumentation.java
new file mode 100644
index 0000000..84e4ea9
--- /dev/null
+++ b/services/core/java/com/android/server/am/ActiveInstrumentation.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.am;
+
+import android.app.IInstrumentationWatcher;
+import android.app.IUiAutomationConnection;
+import android.content.ComponentName;
+import android.content.pm.ApplicationInfo;
+import android.os.Bundle;
+import android.util.PrintWriterPrinter;
+
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+class ActiveInstrumentation {
+ final ActivityManagerService mService;
+
+ // Class installed to instrument app
+ ComponentName mClass;
+
+ // All process names that should be instrumented
+ String[] mTargetProcesses;
+
+ // The application being instrumented
+ ApplicationInfo mTargetInfo;
+
+ // Where to save profiling
+ String mProfileFile;
+
+ // Who is waiting
+ IInstrumentationWatcher mWatcher;
+
+ // Connection to use the UI introspection APIs.
+ IUiAutomationConnection mUiAutomationConnection;
+
+ // As given to us
+ Bundle mArguments;
+
+ // Any intermediate results that have been collected.
+ Bundle mCurResults;
+
+ // Copy of instrumentationClass.
+ ComponentName mResultClass;
+
+ // Contains all running processes that have active instrumentation.
+ final ArrayList<ProcessRecord> mRunningProcesses = new ArrayList<>();
+
+ // Set to true when we have told the watcher the instrumentation is finished.
+ boolean mFinished;
+
+ ActiveInstrumentation(ActivityManagerService service) {
+ mService = service;
+ }
+
+ void removeProcess(ProcessRecord proc) {
+ mFinished = true;
+ mRunningProcesses.remove(proc);
+ if (mRunningProcesses.size() == 0) {
+ mService.mActiveInstrumentation.remove(this);
+ }
+ }
+
+ public String toString() {
+ StringBuilder sb = new StringBuilder(128);
+ sb.append("ActiveInstrumentation{");
+ sb.append(Integer.toHexString(System.identityHashCode(this)));
+ sb.append(' ');
+ sb.append(mClass.toShortString());
+ if (mFinished) {
+ sb.append(" FINISHED");
+ }
+ sb.append(" ");
+ sb.append(mRunningProcesses.size());
+ sb.append(" procs");
+ sb.append('}');
+ return sb.toString();
+ }
+
+ void dump(PrintWriter pw, String prefix) {
+ pw.print(prefix); pw.print("mClass="); pw.print(mClass);
+ pw.print(" mFinished="); pw.println(mFinished);
+ pw.print(prefix); pw.println("mRunningProcesses:");
+ for (int i=0; i<mRunningProcesses.size(); i++) {
+ pw.print(prefix); pw.print(" #"); pw.print(i); pw.print(": ");
+ pw.println(mRunningProcesses.get(i));
+ }
+ pw.print(prefix); pw.print("mTargetProcesses=");
+ pw.println(Arrays.toString(mTargetProcesses));
+ pw.print(prefix); pw.print("mTargetInfo=");
+ pw.println(mTargetInfo);
+ if (mTargetInfo != null) {
+ mTargetInfo.dump(new PrintWriterPrinter(pw), prefix + " ", 0);
+ }
+ if (mProfileFile != null) {
+ pw.print(prefix); pw.print("mProfileFile="); pw.println(mProfileFile);
+ }
+ if (mWatcher != null) {
+ pw.print(prefix); pw.print("mWatcher="); pw.println(mWatcher);
+ }
+ if (mUiAutomationConnection != null) {
+ pw.print(prefix); pw.print("mUiAutomationConnection=");
+ pw.println(mUiAutomationConnection);
+ }
+ pw.print(prefix); pw.print("mArguments=");
+ pw.println(mArguments);
+ }
+}
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 5655dc5..041fee2 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -16,6 +16,8 @@
package com.android.server.am;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
import static com.android.server.am.ActivityManagerDebugConfig.*;
import java.io.FileDescriptor;
@@ -1391,8 +1393,7 @@
}
if (r != null) {
if (mAm.checkComponentPermission(r.permission,
- callingPid, callingUid, r.appInfo.uid, r.exported)
- != PackageManager.PERMISSION_GRANTED) {
+ callingPid, callingUid, r.appInfo.uid, r.exported) != PERMISSION_GRANTED) {
if (!r.exported) {
Slog.w(TAG, "Permission Denial: Accessing service " + r.name
+ " from pid=" + callingPid
@@ -2775,16 +2776,15 @@
return info;
}
- List<ActivityManager.RunningServiceInfo> getRunningServiceInfoLocked(int maxNum, int flags) {
+ List<ActivityManager.RunningServiceInfo> getRunningServiceInfoLocked(int maxNum, int flags,
+ int callingUid, boolean allowed) {
ArrayList<ActivityManager.RunningServiceInfo> res
= new ArrayList<ActivityManager.RunningServiceInfo>();
- final int uid = Binder.getCallingUid();
final long ident = Binder.clearCallingIdentity();
try {
- if (ActivityManager.checkUidPermission(
- android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
- uid) == PackageManager.PERMISSION_GRANTED) {
+ if (ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, callingUid)
+ == PERMISSION_GRANTED) {
int[] users = mAm.mUserController.getUsers();
for (int ui=0; ui<users.length && res.size() < maxNum; ui++) {
ArrayMap<ComponentName, ServiceRecord> alls = getServicesLocked(users[ui]);
@@ -2802,16 +2802,20 @@
res.add(info);
}
} else {
- int userId = UserHandle.getUserId(uid);
+ int userId = UserHandle.getUserId(callingUid);
ArrayMap<ComponentName, ServiceRecord> alls = getServicesLocked(userId);
for (int i=0; i<alls.size() && res.size() < maxNum; i++) {
ServiceRecord sr = alls.valueAt(i);
- res.add(makeRunningServiceInfoLocked(sr));
+
+ if (allowed || (sr.app != null && sr.app.uid == callingUid)) {
+ res.add(makeRunningServiceInfoLocked(sr));
+ }
}
for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) {
ServiceRecord r = mRestartingServices.get(i);
- if (r.userId == userId) {
+ if (r.userId == userId
+ && (allowed || (r.app != null && r.app.uid == callingUid))) {
ActivityManager.RunningServiceInfo info =
makeRunningServiceInfoLocked(r);
info.restarting = r.nextRestartTime;
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 732cd10..ae76b61 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -235,6 +235,7 @@
import android.graphics.Point;
import android.graphics.Rect;
import android.location.LocationManager;
+import android.metrics.LogMaker;
import android.net.Proxy;
import android.net.ProxyInfo;
import android.net.Uri;
@@ -312,6 +313,7 @@
import com.google.android.collect.Lists;
import com.google.android.collect.Maps;
+
import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.app.AssistUtils;
@@ -322,6 +324,8 @@
import com.android.internal.app.ProcessMap;
import com.android.internal.app.SystemUserHomeActivity;
import com.android.internal.app.procstats.ProcessStats;
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.os.BackgroundThread;
import com.android.internal.os.BatteryStatsImpl;
import com.android.internal.os.IResultReceiver;
@@ -569,7 +573,9 @@
final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
- public IntentFirewall mIntentFirewall;
+ final ArrayList<ActiveInstrumentation> mActiveInstrumentation = new ArrayList<>();
+
+ public final IntentFirewall mIntentFirewall;
// Whether we should show our dialogs (ANR, crash, etc) or just perform their
// default action automatically. Important for devices without direct input
@@ -695,21 +701,16 @@
public AssistStructure structure = null;
public AssistContent content = null;
public Bundle receiverExtras;
- public int resultCode;
- public int flags;
public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
- String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _resultCode,
- int _userHandle, int _flags) {
+ String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
activity = _activity;
extras = _extras;
intent = _intent;
hint = _hint;
receiver = _receiver;
receiverExtras = _receiverExtras;
- resultCode = _resultCode;
userHandle = _userHandle;
- flags = _flags;
}
@Override
public void run() {
@@ -3924,7 +3925,7 @@
aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
ProcessRecord app = getProcessRecordLocked(aInfo.processName,
aInfo.applicationInfo.uid, true);
- if (app == null || app.instrumentationClass == null) {
+ if (app == null || app.instr == null) {
intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
}
@@ -5090,9 +5091,9 @@
app.activities.clear();
- if (app.instrumentationClass != null) {
+ if (app.instr != null) {
Slog.w(TAG, "Crash of app " + app.processName
- + " running instrumentation " + app.instrumentationClass);
+ + " running instrumentation " + app.instr.mClass);
Bundle info = new Bundle();
info.putString("shortMsg", "Process crashed.");
finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
@@ -5225,7 +5226,7 @@
// Clean up already done if the process has been re-started.
if (app.pid == pid && app.thread != null &&
app.thread.asBinder() == thread.asBinder()) {
- boolean doLowMem = app.instrumentationClass == null;
+ boolean doLowMem = app.instr == null;
boolean doOomAdj = doLowMem;
if (!app.killedByAm) {
Slog.i(TAG, "Process " + app.processName + " (pid " + pid
@@ -6381,7 +6382,7 @@
handleAppDiedLocked(app, willRestart, allowRestart);
if (willRestart) {
removeLruProcessLocked(app);
- addAppLocked(app.info, false, null /* ABI override */);
+ addAppLocked(app.info, null, false, null /* ABI override */);
}
} else {
mRemovedProcesses.add(app);
@@ -6557,7 +6558,7 @@
mWaitForDebugger = mOrigWaitForDebugger;
}
}
- String profileFile = app.instrumentationProfileFile;
+ String profileFile = app.instr != null ? app.instr.mProfileFile : null;
ParcelFileDescriptor profileFd = null;
int samplingInterval = 0;
boolean profileAutoStop = false;
@@ -6585,14 +6586,13 @@
|| (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
}
- if (app.instrumentationClass != null) {
- notifyPackageUse(app.instrumentationClass.getPackageName(),
+ if (app.instr != null) {
+ notifyPackageUse(app.instr.mClass.getPackageName(),
PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
}
if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
+ processName + " with config " + getGlobalConfiguration());
- ApplicationInfo appInfo = app.instrumentationInfo != null
- ? app.instrumentationInfo : app.info;
+ ApplicationInfo appInfo = app.instr != null ? app.instr.mTargetInfo : app.info;
app.compat = compatibilityInfoForPackageLocked(appInfo);
if (profileFd != null) {
profileFd = profileFd.dup();
@@ -6612,16 +6612,57 @@
.getSerial();
// }
+ // Check if this is a secondary process that should be incorporated into some
+ // currently active instrumentation. (Note we do this AFTER all of the profiling
+ // stuff above because profiling can currently happen only in the primary
+ // instrumentation process.)
+ if (mActiveInstrumentation.size() > 0 && app.instr == null) {
+ for (int i = mActiveInstrumentation.size() - 1; i >= 0 && app.instr == null; i--) {
+ ActiveInstrumentation aInstr = mActiveInstrumentation.get(i);
+ if (!aInstr.mFinished && aInstr.mTargetInfo.uid == app.uid) {
+ if (aInstr.mTargetProcesses.length == 0) {
+ // This is the wildcard mode, where every process brought up for
+ // the target instrumentation should be included.
+ if (aInstr.mTargetInfo.packageName.equals(app.info.packageName)) {
+ app.instr = aInstr;
+ aInstr.mRunningProcesses.add(app);
+ }
+ } else {
+ for (String proc : aInstr.mTargetProcesses) {
+ if (proc.equals(app.processName)) {
+ app.instr = aInstr;
+ aInstr.mRunningProcesses.add(app);
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+
checkTime(startTime, "attachApplicationLocked: immediately before bindApplication");
- thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
- profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
- app.instrumentationUiAutomationConnection, testMode,
- mBinderTransactionTrackingEnabled, enableTrackAllocation,
- isRestrictedBackupMode || !normalMode, app.persistent,
- new Configuration(getGlobalConfiguration()), app.compat,
- getCommonServicesLocked(app.isolated),
- mCoreSettingsObserver.getCoreSettingsLocked(),
- buildSerial);
+ if (app.instr != null) {
+ thread.bindApplication(processName, appInfo, providers,
+ app.instr.mClass,
+ profilerInfo, app.instr.mArguments,
+ app.instr.mWatcher,
+ app.instr.mUiAutomationConnection, testMode,
+ mBinderTransactionTrackingEnabled, enableTrackAllocation,
+ isRestrictedBackupMode || !normalMode, app.persistent,
+ new Configuration(getGlobalConfiguration()), app.compat,
+ getCommonServicesLocked(app.isolated),
+ mCoreSettingsObserver.getCoreSettingsLocked(),
+ buildSerial);
+ } else {
+ thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
+ null, null, null, testMode,
+ mBinderTransactionTrackingEnabled, enableTrackAllocation,
+ isRestrictedBackupMode || !normalMode, app.persistent,
+ new Configuration(getGlobalConfiguration()), app.compat,
+ getCommonServicesLocked(app.isolated),
+ mCoreSettingsObserver.getCoreSettingsLocked(),
+ buildSerial);
+ }
checkTime(startTime, "attachApplicationLocked: immediately after bindApplication");
updateLruProcessLocked(app, false, null);
@@ -6730,7 +6771,8 @@
ActivityStack stack = ActivityRecord.getStackLocked(token);
if (stack != null) {
ActivityRecord r =
- mStackSupervisor.activityIdleInternalLocked(token, false, config);
+ mStackSupervisor.activityIdleInternalLocked(token, false /* fromTimeout */,
+ false /* processPausingActivities */, config);
if (stopProfiling) {
if ((mProfileProc == r.app) && (mProfileFd != null)) {
try {
@@ -7610,7 +7652,8 @@
// Activity supports picture-in-picture, now check that we can enter PiP at this
// point, if it is
- if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode")) {
+ if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
+ false /* noThrow */)) {
return false;
}
@@ -7625,6 +7668,10 @@
mStackSupervisor.moveActivityToPinnedStackLocked(r, "enterPictureInPictureMode",
bounds, true /* moveHomeStackToFront */);
mStackSupervisor.getStack(PINNED_STACK_ID).setPictureInPictureActions(actions);
+
+ MetricsLogger.action(mContext, MetricsEvent.ACTION_PICTURE_IN_PICTURE_ENTERED,
+ r.supportsPictureInPictureWhilePausing);
+ logPictureInPictureArgs(args);
};
if (isKeyguardLocked()) {
@@ -7678,12 +7725,25 @@
stack.setPictureInPictureAspectRatio(r.pictureInPictureArgs.getAspectRatio());
stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
}
+ logPictureInPictureArgs(args);
}
} finally {
Binder.restoreCallingIdentity(origId);
}
}
+ private void logPictureInPictureArgs(PictureInPictureArgs args) {
+ if (args.hasSetActions()) {
+ MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count",
+ args.getActions().size());
+ }
+ if (args.hasSetAspectRatio()) {
+ LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED);
+ lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, args.getAspectRatio());
+ MetricsLogger.action(lm);
+ }
+ }
+
private boolean isValidPictureInPictureAspectRatio(float aspectRatio) {
return mMinPipAspectRatio <= aspectRatio && aspectRatio <= mMaxPipAspectRatio;
}
@@ -11574,7 +11634,7 @@
.getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
for (ApplicationInfo app : apps) {
if (!"android".equals(app.packageName)) {
- addAppLocked(app, false, null /* ABI override */);
+ addAppLocked(app, null, false, null /* ABI override */);
}
}
} catch (RemoteException ex) {
@@ -11762,17 +11822,18 @@
return false;
}
- final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
+ final ProcessRecord addAppLocked(ApplicationInfo info, String customProcess, boolean isolated,
String abiOverride) {
ProcessRecord app;
if (!isolated) {
- app = getProcessRecordLocked(info.processName, info.uid, true);
+ app = getProcessRecordLocked(customProcess != null ? customProcess : info.processName,
+ info.uid, true);
} else {
app = null;
}
if (app == null) {
- app = newProcessRecordLocked(info, null, isolated, 0);
+ app = newProcessRecordLocked(info, customProcess, isolated, 0);
updateLruProcessLocked(app, false, null);
updateOomAdjLocked();
}
@@ -11793,7 +11854,8 @@
}
if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
mPersistentStartingProcesses.add(app);
- startProcessLocked(app, "added application", app.processName, abiOverride,
+ startProcessLocked(app, "added application",
+ customProcess != null ? customProcess : app.processName, abiOverride,
null /* entryPoint */, null /* entryPointArgs */);
}
@@ -12248,11 +12310,11 @@
synchronized (this) {
synchronized (mPidsSelfLocked) {
final int callingPid = Binder.getCallingPid();
- ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
- if (precessRecord == null) {
+ ProcessRecord proc = mPidsSelfLocked.get(callingPid);
+ if (proc == null) {
throw new SecurityException("Unknown process: " + callingPid);
}
- if (precessRecord.instrumentationUiAutomationConnection == null) {
+ if (proc.instr == null || proc.instr.mUiAutomationConnection == null) {
throw new SecurityException("Only an instrumentation process "
+ "with a UiAutomation can call setUserIsMonkey");
}
@@ -12309,7 +12371,7 @@
}
public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
- if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
+ if (r != null && (r.instr != null || r.usingWrapper)) {
return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
}
return KEY_DISPATCHING_TIMEOUT;
@@ -12370,7 +12432,7 @@
return false;
}
- if (proc.instrumentationClass != null) {
+ if (proc.instr != null) {
Bundle info = new Bundle();
info.putString("shortMsg", "keyDispatchingTimedOut");
info.putString("longMsg", annotation);
@@ -12392,8 +12454,8 @@
@Override
public Bundle getAssistContextExtras(int requestType) {
PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
- null, 0, null, true /* focused */, true /* newSessionId */,
- UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0);
+ null, null, true /* focused */, true /* newSessionId */,
+ UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
if (pae == null) {
return null;
}
@@ -12457,44 +12519,31 @@
@Override
public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
- Bundle receiverExtras,
- IBinder activityToken, boolean focused, boolean newSessionId) {
+ Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
- 0, activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
- PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null;
+ activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
+ PENDING_ASSIST_EXTRAS_LONG_TIMEOUT) != null;
}
@Override
public boolean requestAutoFillData(IResultReceiver receiver, Bundle receiverExtras,
- int resultCode, IBinder activityToken, int flags) {
- final boolean forFill = (flags & View.AUTO_FILL_FLAG_TYPE_FILL) != 0;
- final boolean forSave = (flags & View.AUTO_FILL_FLAG_TYPE_SAVE) != 0;
- if ((forFill && forSave) || (!forFill) && !(forSave)) {
- // There can be only one!
- Slog.w(TAG, "requestAutoFillData(): invalid flags (" + flags + ")");
- return false;
- }
-
+ IBinder activityToken) {
// NOTE: we could always use ActivityManager.ASSIST_CONTEXT_FULL and let ActivityThread
// rely on the flags to decide whether the handleRequestAssistContextExtras() is for
// auto-fill, but it's safer to explicitly use new AutoFill types, in case the Assist
// requests use flags in the future as well (since their flags value might collide with the
// auto-fill flag values).
- final int type = forFill?
- ActivityManager.ASSIST_CONTEXT_AUTO_FILL :
- ActivityManager.ASSIST_CONTEXT_AUTO_FILL_SAVE;
-
- return enqueueAssistContext(type, null, null, receiver, receiverExtras, resultCode,
- activityToken, true, true, UserHandle.getCallingUserId(), null,
- PENDING_AUTO_FILL_ASSIST_STRUCTURE_TIMEOUT, flags) != null;
+ return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTO_FILL, null, null,
+ receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
+ null, PENDING_AUTO_FILL_ASSIST_STRUCTURE_TIMEOUT) != null;
}
private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
- IResultReceiver receiver, Bundle receiverExtras, int resultCode, IBinder activityToken,
- boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
- int flags) {
+ IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
+ boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout) {
enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
"enqueueAssistContext()");
+
synchronized (this) {
ActivityRecord activity = getFocusedStack().topActivity();
if (activity == null) {
@@ -12530,15 +12579,17 @@
}
extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
+
pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
- resultCode, userHandle, flags);
+ userHandle);
+
// Increment the sessionId if necessary
if (newSessionId) {
mViSessionId++;
}
try {
- activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
- requestType, mViSessionId, flags);
+ activity.app.thread.requestAssistContextExtras(activity.appToken, pae, requestType,
+ mViSessionId);
mPendingAssistExtras.add(pae);
mUiHandler.postDelayed(pae, timeout);
} catch (RemoteException e) {
@@ -12614,18 +12665,11 @@
sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
pae.receiverExtras);
- if (pae.flags > 0) {
- sendBundle.putInt(VoiceInteractionSession.KEY_FLAGS, pae.flags);
- }
- IBinder cb = extras.getBinder(AutoFillService.KEY_CALLBACK);
- if (cb != null) {
- sendBundle.putBinder(AutoFillService.KEY_CALLBACK, cb);
- }
}
}
if (sendReceiver != null) {
try {
- sendReceiver.send(pae.resultCode, sendBundle);
+ sendReceiver.send(0, sendBundle);
} catch (RemoteException e) {
}
return;
@@ -12650,9 +12694,9 @@
public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
Bundle args) {
- return enqueueAssistContext(requestType, intent, hint, null, null, 0, null,
+ return enqueueAssistContext(requestType, intent, hint, null, null, null,
true /* focused */, true /* newSessionId */, userHandle, args,
- PENDING_ASSIST_EXTRAS_TIMEOUT, 0) != null;
+ PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
}
public void registerProcessObserver(IProcessObserver observer) {
@@ -14896,8 +14940,31 @@
printed = true;
needSep = true;
}
- pw.println(String.format("%sIsolated #%2d: %s",
- " ", i, r.toString()));
+ pw.print(" Isolated #"); pw.print(i); pw.print(": ");
+ pw.println(r);
+ }
+ }
+
+ if (mActiveInstrumentation.size() > 0) {
+ boolean printed = false;
+ for (int i=0; i<mActiveInstrumentation.size(); i++) {
+ ActiveInstrumentation ai = mActiveInstrumentation.get(i);
+ if (dumpPackage != null && !ai.mClass.getPackageName().equals(dumpPackage)
+ && !ai.mTargetInfo.packageName.equals(dumpPackage)) {
+ continue;
+ }
+ if (!printed) {
+ if (needSep) {
+ pw.println();
+ }
+ pw.println(" Active instrumentation:");
+ printedAnything = true;
+ printed = true;
+ needSep = true;
+ }
+ pw.print(" Instrumentation #"); pw.print(i); pw.print(": ");
+ pw.println(ai);
+ ai.dump(pw, " ");
}
}
@@ -17395,7 +17462,11 @@
int flags) {
enforceNotIsolatedCaller("getServices");
synchronized (this) {
- return mServices.getRunningServiceInfoLocked(maxNum, flags);
+ final int callingUid = Binder.getCallingUid();
+ final boolean allowed = isGetTasksAllowed("getServices", Binder.getCallingPid(),
+ callingUid);
+
+ return mServices.getRunningServiceInfoLocked(maxNum, flags, callingUid, allowed);
}
}
@@ -19041,18 +19112,35 @@
throw new SecurityException(msg);
}
+ ActiveInstrumentation activeInstr = new ActiveInstrumentation(this);
+ activeInstr.mClass = className;
+ String defProcess = ai.processName;;
+ if (ii.targetProcess == null) {
+ activeInstr.mTargetProcesses = new String[]{ai.processName};
+ } else if (ii.targetProcess.equals("*")) {
+ activeInstr.mTargetProcesses = new String[0];
+ } else {
+ activeInstr.mTargetProcesses = ii.targetProcess.split(",");
+ defProcess = activeInstr.mTargetProcesses[0];
+ }
+ activeInstr.mTargetInfo = ai;
+ activeInstr.mProfileFile = profileFile;
+ activeInstr.mArguments = arguments;
+ activeInstr.mWatcher = watcher;
+ activeInstr.mUiAutomationConnection = uiAutomationConnection;
+ activeInstr.mResultClass = className;
+
final long origId = Binder.clearCallingIdentity();
// Instrumentation can kill and relaunch even persistent processes
forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
"start instr");
- ProcessRecord app = addAppLocked(ai, false, abiOverride);
- app.instrumentationClass = className;
- app.instrumentationInfo = ai;
- app.instrumentationProfileFile = profileFile;
- app.instrumentationArguments = arguments;
- app.instrumentationWatcher = watcher;
- app.instrumentationUiAutomationConnection = uiAutomationConnection;
- app.instrumentationResultClass = className;
+ ProcessRecord app = addAppLocked(ai, defProcess, false, abiOverride);
+ app.instr = activeInstr;
+ activeInstr.mFinished = false;
+ activeInstr.mRunningProcesses.add(app);
+ if (!mActiveInstrumentation.contains(activeInstr)) {
+ mActiveInstrumentation.add(activeInstr);
+ }
Binder.restoreCallingIdentity(origId);
}
@@ -19079,24 +19167,70 @@
}
}
+ void addInstrumentationResultsLocked(ProcessRecord app, Bundle results) {
+ if (app.instr == null) {
+ Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
+ return;
+ }
+
+ if (!app.instr.mFinished && results != null) {
+ if (app.instr.mCurResults == null) {
+ app.instr.mCurResults = new Bundle(results);
+ } else {
+ app.instr.mCurResults.putAll(results);
+ }
+ }
+ }
+
+ public void addInstrumentationResults(IApplicationThread target, Bundle results) {
+ int userId = UserHandle.getCallingUserId();
+ // Refuse possible leaked file descriptors
+ if (results != null && results.hasFileDescriptors()) {
+ throw new IllegalArgumentException("File descriptors passed in Intent");
+ }
+
+ synchronized(this) {
+ ProcessRecord app = getRecordForAppLocked(target);
+ if (app == null) {
+ Slog.w(TAG, "addInstrumentationResults: no app for " + target);
+ return;
+ }
+ final long origId = Binder.clearCallingIdentity();
+ addInstrumentationResultsLocked(app, results);
+ Binder.restoreCallingIdentity(origId);
+ }
+ }
+
void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
- if (app.instrumentationWatcher != null) {
- mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
- app.instrumentationClass, resultCode, results);
+ if (app.instr == null) {
+ Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
+ return;
}
- // Can't call out of the system process with a lock held, so post a message.
- if (app.instrumentationUiAutomationConnection != null) {
- mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
- app.instrumentationUiAutomationConnection).sendToTarget();
+ if (!app.instr.mFinished) {
+ if (app.instr.mWatcher != null) {
+ Bundle finalResults = app.instr.mCurResults;
+ if (finalResults != null) {
+ if (app.instr.mCurResults != null && results != null) {
+ finalResults.putAll(results);
+ }
+ } else {
+ finalResults = results;
+ }
+ mInstrumentationReporter.reportFinished(app.instr.mWatcher,
+ app.instr.mClass, resultCode, finalResults);
+ }
+
+ // Can't call out of the system process with a lock held, so post a message.
+ if (app.instr.mUiAutomationConnection != null) {
+ mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
+ app.instr.mUiAutomationConnection).sendToTarget();
+ }
+ app.instr.mFinished = true;
}
- app.instrumentationWatcher = null;
- app.instrumentationUiAutomationConnection = null;
- app.instrumentationClass = null;
- app.instrumentationInfo = null;
- app.instrumentationProfileFile = null;
- app.instrumentationArguments = null;
+ app.instr.removeProcess(app);
+ app.instr = null;
forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
"finished inst");
@@ -19879,7 +20013,7 @@
app.adjType = "top-activity";
foregroundActivities = true;
procState = PROCESS_STATE_CUR_TOP;
- } else if (app.instrumentationClass != null) {
+ } else if (app.instr != null) {
// Don't want to kill running instrumentation.
adj = ProcessList.FOREGROUND_APP_ADJ;
schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
@@ -21968,7 +22102,7 @@
mRemovedProcesses.remove(i);
if (app.persistent) {
- addAppLocked(app.info, false, null /* ABI override */);
+ addAppLocked(app.info, null, false, null /* ABI override */);
}
}
}
@@ -22600,13 +22734,6 @@
}
@Override
- public IBinder getTopVisibleActivity(int uid) {
- synchronized (ActivityManagerService.this) {
- return mStackSupervisor.getTopVisibleActivity(uid);
- }
- }
-
- @Override
public void notifyDockedStackMinimizedChanged(boolean minimized) {
synchronized (ActivityManagerService.this) {
mStackSupervisor.setDockedStackMinimized(minimized);
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index 8c34776..a06fa1b 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -2043,7 +2043,7 @@
mInterface.stopLockTaskMode();
} else {
int taskId = Integer.parseInt(taskIdStr);
- mInterface.startLockTaskModeById(taskId);
+ mInterface.startSystemLockTaskMode(taskId);
}
pw.println("Activity manager is " + (mInterface.isInLockTaskMode() ? "" : "not ") +
"in lockTaskMode");
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index 2b0544e5..58c17eb 100644
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -17,6 +17,7 @@
package com.android.server.am;
import static android.app.ActivityManager.ENABLE_TASK_SNAPSHOTS;
+import static android.app.ActivityManager.LOCK_TASK_MODE_NONE;
import static android.app.ActivityManager.StackId;
import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
@@ -29,6 +30,7 @@
import static android.content.pm.ActivityInfo.CONFIG_SCREEN_LAYOUT;
import static android.content.pm.ActivityInfo.CONFIG_SCREEN_SIZE;
import static android.content.pm.ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE;
+import static android.content.pm.ActivityInfo.CONFIG_UI_MODE;
import static android.content.pm.ActivityInfo.FLAG_ALWAYS_FOCUSABLE;
import static android.content.pm.ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
import static android.content.pm.ActivityInfo.FLAG_IMMERSIVE;
@@ -36,12 +38,17 @@
import static android.content.pm.ActivityInfo.FLAG_SHOW_FOR_ALL_USERS;
import static android.content.pm.ActivityInfo.FLAG_STATE_NOT_NEEDED;
import static android.content.pm.ActivityInfo.LAUNCH_MULTIPLE;
+import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_INSTANCE;
+import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TASK;
import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TOP;
import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZEABLE;
import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE;
import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION;
import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
+import static android.content.res.Configuration.UI_MODE_TYPE_MASK;
+import static android.content.res.Configuration.UI_MODE_TYPE_VR_HEADSET;
import static android.os.Build.VERSION_CODES.HONEYCOMB;
+import static android.os.Build.VERSION_CODES.O;
import static android.os.Process.SYSTEM_UID;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SAVED_STATE;
@@ -76,6 +83,7 @@
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.Rect;
+import android.os.Build;
import android.os.Bundle;
import android.os.Debug;
import android.os.IBinder;
@@ -772,7 +780,10 @@
// Remove the activity from the old task and add it to the new task
prevTask.removeActivity(this);
- setTask(newTask, null);
+ // TODO(b/34179495): This should really be set to null in removeActivity() call above,
+ // but really bad things that I can't track down right now happen when I do that.
+ // So, setting it here now and will change later when there is time for investigation.
+ task = null;
newTask.addActivityAtIndex(position, this);
}
@@ -820,19 +831,8 @@
}
}
- void setTask(TaskRecord newTask, TaskRecord taskToAffiliateWith) {
- if (task != null && task.removeActivity(this) && task != newTask
- && task.getStack() != null) {
- task.getStack().removeTask(task, "setTask");
- }
- task = newTask;
- setTaskToAffiliateWith(taskToAffiliateWith);
- }
-
void setTaskToAffiliateWith(TaskRecord taskToAffiliateWith) {
- if (taskToAffiliateWith != null &&
- launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE &&
- launchMode != ActivityInfo.LAUNCH_SINGLE_TASK) {
+ if (launchMode != LAUNCH_SINGLE_INSTANCE && launchMode != LAUNCH_SINGLE_TASK) {
task.setTaskToAffiliateWith(taskToAffiliateWith);
}
}
@@ -947,34 +947,43 @@
/**
* @return whether this activity is currently allowed to enter PIP, throwing an exception if
- * the activity is not currently visible.
+ * the activity is not currently visible and {@param noThrow} is not set.
*/
- boolean checkEnterPictureInPictureState(String caller) {
+ boolean checkEnterPictureInPictureState(String caller, boolean noThrow) {
+ boolean isCurrentAppLocked = mStackSupervisor.getLockTaskModeState() != LOCK_TASK_MODE_NONE;
boolean isKeyguardLocked = service.isKeyguardLocked();
boolean hasPinnedStack = mStackSupervisor.getStack(PINNED_STACK_ID) != null;
+ // Don't return early if !isNotLocked, since we want to throw an exception if the activity
+ // is in an incorrect state
+ boolean isNotLocked = !isKeyguardLocked && !isCurrentAppLocked;
switch (state) {
case RESUMED:
- // When visible, allow entering PiP if not on the lockscreen. If there is another
- // PiP activity, the logic to handle that comes later in enterPictureInPictureMode()
- return !isKeyguardLocked;
+ // When visible, allow entering PiP if not on the lockscreen and if the task is not
+ // locked
+ return isNotLocked;
case PAUSING:
case PAUSED:
- // When pausing, only allow enter PiP if not on the lockscreen and there is not
- // already an existing PiP activity
- return !isKeyguardLocked && !hasPinnedStack && supportsPictureInPictureWhilePausing
+ // When pausing, then only allow enter PiP as in the resume state, and in addition,
+ // require that there is not an existing PiP activity and that the current system
+ // state supports entering PiP
+ return isNotLocked && !hasPinnedStack && supportsPictureInPictureWhilePausing
&& checkEnterPictureInPictureOnHideAppOpsState();
case STOPPING:
// When stopping in a valid state, then only allow enter PiP as in the pause state.
// Otherwise, fall through to throw an exception if the caller is trying to enter
// PiP in an invalid stopping state.
if (supportsPictureInPictureWhilePausing) {
- return !isKeyguardLocked && !hasPinnedStack
+ return isNotLocked && !hasPinnedStack
&& checkEnterPictureInPictureOnHideAppOpsState();
}
default:
- throw new IllegalStateException(caller
- + ": Current activity is not visible (state=" + state.name() + ") "
- + "r=" + this);
+ if (noThrow) {
+ return false;
+ } else {
+ throw new IllegalStateException(caller
+ + ": Current activity is not visible (state=" + state.name() + ") "
+ + "r=" + this);
+ }
}
}
@@ -1672,7 +1681,8 @@
if (!idle) {
// Instead of doing the full stop routine here, let's just hide any activities
// we now can, and let them stop when the normal idle happens.
- mStackSupervisor.processStoppingActivitiesLocked(false);
+ mStackSupervisor.processStoppingActivitiesLocked(null /* idleActivity */,
+ false /* remove */, true /* processPausingActivities */);
} else {
// If this activity was already idle, then we now need to make sure we perform
// the full stop of any activities that are waiting to do so. This is because
@@ -1902,11 +1912,22 @@
task.taskId, requestedOrientation);
}
- // TODO: now used only in one place to address race-condition. Remove when that will be fixed.
- void setLastReportedConfiguration(@NonNull Configuration config) {
+ /**
+ * Set the last reported global configuration to the client. Should be called whenever a new
+ * global configuration is sent to the client for this activity.
+ */
+ void setLastReportedGlobalConfiguration(@NonNull Configuration config) {
mLastReportedConfiguration.setTo(config);
}
+ /**
+ * Set the last reported merged override configuration to the client. Should be called whenever
+ * a new merged configuration is sent to the client for this activity.
+ */
+ void setLastReportedMergedOverrideConfiguration(@NonNull Configuration config) {
+ mLastReportedOverrideConfiguration.setTo(config);
+ }
+
/** Call when override config was sent to the Window Manager to update internal records. */
void onOverrideConfigurationSent() {
mLastReportedOverrideConfiguration.setTo(task.getMergedOverrideConfiguration());
@@ -1991,7 +2012,8 @@
+ ", newGlobalConfig=" + newGlobalConfig
+ ", newTaskMergedOverrideConfig=" + newTaskMergedOverrideConfig);
- if ((changes&(~info.getRealConfigChanged())) != 0 || forceNewConfig) {
+ if (shouldRelaunchLocked(changes, newGlobalConfig, newTaskMergedOverrideConfig)
+ || forceNewConfig) {
// Aha, the activity isn't handling the change, so DIE DIE DIE.
configChangeFlags |= changes;
startFreezingScreenLocked(app, globalChanges);
@@ -2042,6 +2064,27 @@
return true;
}
+ /**
+ * When assessing a configuration change, decide if the changes flags and the new configurations
+ * should cause the Activity to relaunch.
+ */
+ private boolean shouldRelaunchLocked(int changes, Configuration newGlobalConfig,
+ Configuration newTaskMergedOverrideConfig) {
+ int configChanged = info.getRealConfigChanged();
+
+ // Override for apps targeting pre-O sdks
+ // If a device is in VR mode, and we're transitioning into VR ui mode, add ignore ui mode
+ // to the config change.
+ // For O and later, apps will be required to add configChanges="uimode" to their manifest.
+ if (appInfo.targetSdkVersion < O
+ && requestedVrComponent != null
+ && (isInVrUiMode(newGlobalConfig) || isInVrUiMode(newTaskMergedOverrideConfig))) {
+ configChanged |= CONFIG_UI_MODE;
+ }
+
+ return (changes&(~configChanged)) != 0;
+ }
+
private static int getTaskConfigurationChanges(ActivityRecord record, Configuration taskConfig,
Configuration oldTaskOverride) {
// If we went from full-screen to non-full-screen, make sure to use the correct
@@ -2142,7 +2185,7 @@
// if the app is relaunched when it's stopped, and we're not resuming,
// put it back into stopped state.
if (stopped) {
- getStack().addToStopping(this, true /* immediate */);
+ getStack().addToStopping(this, true /* scheduleIdle */, false /* idleDelayed */);
}
}
@@ -2278,6 +2321,10 @@
}
}
+ private static boolean isInVrUiMode(Configuration config) {
+ return (config.uiMode & Configuration.UI_MODE_TYPE_MASK) == UI_MODE_TYPE_VR_HEADSET;
+ }
+
@Override
public String toString() {
if (stringName != null) {
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 47109f2..ba25120 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -1139,6 +1139,18 @@
}
/**
+ * Schedule a pause timeout in case the app doesn't respond. We don't give it much time because
+ * this directly impacts the responsiveness seen by the user.
+ */
+ private void schedulePauseTimeout(ActivityRecord r) {
+ final Message msg = mHandler.obtainMessage(PAUSE_TIMEOUT_MSG);
+ msg.obj = r;
+ r.pauseTime = SystemClock.uptimeMillis();
+ mHandler.sendMessageDelayed(msg, PAUSE_TIMEOUT);
+ if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Waiting for pause to complete...");
+ }
+
+ /**
* Start pausing the currently resumed activity. It is an error to call this if there
* is already an activity being paused or there is no resumed activity.
*
@@ -1244,14 +1256,7 @@
return false;
} else {
- // Schedule a pause timeout in case the app doesn't respond.
- // We don't give it much time because this directly impacts the
- // responsiveness seen by the user.
- Message msg = mHandler.obtainMessage(PAUSE_TIMEOUT_MSG);
- msg.obj = prev;
- prev.pauseTime = SystemClock.uptimeMillis();
- mHandler.sendMessageDelayed(msg, PAUSE_TIMEOUT);
- if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Waiting for pause to complete...");
+ schedulePauseTimeout(prev);
return true;
}
@@ -1332,7 +1337,7 @@
|| mService.isSleepingOrShuttingDownLocked()) {
// If we were visible then resumeTopActivities will release resources before
// stopping.
- addToStopping(prev, true /* immediate */);
+ addToStopping(prev, true /* scheduleIdle */, false /* idleDelayed */);
}
} else {
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "App died during pause, not stopping: " + prev);
@@ -1398,7 +1403,7 @@
mStackSupervisor.ensureActivitiesVisibleLocked(resuming, 0, !PRESERVE_WINDOWS);
}
- void addToStopping(ActivityRecord r, boolean immediate) {
+ void addToStopping(ActivityRecord r, boolean scheduleIdle, boolean idleDelayed) {
if (!mStackSupervisor.mStoppingActivities.contains(r)) {
mStackSupervisor.mStoppingActivities.add(r);
}
@@ -1409,11 +1414,14 @@
// be cleared immediately.
boolean forceIdle = mStackSupervisor.mStoppingActivities.size() > MAX_STOPPING_TO_FORCE
|| (r.frontOfTask && mTaskHistory.size() <= 1);
-
- if (immediate || forceIdle) {
+ if (scheduleIdle || forceIdle) {
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Scheduling idle now: forceIdle="
- + forceIdle + "immediate=" + immediate);
- mStackSupervisor.scheduleIdleLocked();
+ + forceIdle + "immediate=" + !idleDelayed);
+ if (!idleDelayed) {
+ mStackSupervisor.scheduleIdleLocked();
+ } else {
+ mStackSupervisor.scheduleIdleTimeoutLocked(r);
+ }
} else {
mStackSupervisor.checkReadyForSleepLocked();
}
@@ -1546,38 +1554,6 @@
final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
final int focusedStackId = focusedStack.mStackId;
- final TaskRecord topFocusedTask = focusedStack.topTask();
- final boolean isOnTopLauncherFocused = topFocusedTask != null &&
- topFocusedTask.isOnTopLauncher();
- if (isOnTopLauncherFocused) {
- // When an on-top launcher is focused, we should find out whether the freeform stack or
- // the fullscreen stack appears first underneath and has activities to show, and then
- // make it visible.
- boolean behindFullscreenOrFreeForm = false;
- for (int stackBehindFocusedIndex = mStacks.indexOf(focusedStack) - 1;
- stackBehindFocusedIndex >= 0; stackBehindFocusedIndex--) {
- ActivityStack stack = mStacks.get(stackBehindFocusedIndex);
- if ((stack.mStackId == FREEFORM_WORKSPACE_STACK_ID
- || stack.mStackId == FULLSCREEN_WORKSPACE_STACK_ID)
- && stack.topRunningActivityLocked() != null) {
- if (stackIndex == stackBehindFocusedIndex) {
- return !behindFullscreenOrFreeForm ? STACK_VISIBLE : STACK_INVISIBLE;
- }
- behindFullscreenOrFreeForm = true;
- }
- }
- }
- // If an on-top launcher is on the top of the home stack but the home stack is not focused,
- // then the whole stack should be invisible.
- TaskRecord topTask = topTask();
- if (mStackId != focusedStackId && topTask != null && topTask.isOnTopLauncher()) {
- // We're here mostly because the on-top launcher didn't have a chance to move itself to
- // back. We should move it to back as soon as possible to avoid other activities
- // returning to it or other visibility issues.
- moveTaskToBackLocked(topTask.taskId);
- return STACK_INVISIBLE;
- }
-
if (mStackId == FULLSCREEN_WORKSPACE_STACK_ID
&& hasVisibleBehindActivity() && StackId.isHomeOrRecentsStack(focusedStackId)
&& !focusedStack.topActivity().fullscreen) {
@@ -1782,28 +1758,7 @@
// status of an activity in a previous task affects other.
behindFullscreenActivity = stackVisibility == STACK_INVISIBLE;
} else if (mStackId == HOME_STACK_ID) {
- if (task.isOnTopLauncher()) {
- if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "On-top launcher: at " + task
- + " stackInvisible=" + stackInvisible
- + " behindFullscreenActivity=" + behindFullscreenActivity);
- // When an on-top launcher is visible, (e.g. it's on the top of the home stack),
- // other tasks in the home stack could be visible if and only if:
- // - some app is running in the docked stack;
- // - no app is running in either the fullscreen stack or the freefrom stack.
- final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
- final ActivityStack fullscreenStack = mStackSupervisor.getStack(
- FULLSCREEN_WORKSPACE_STACK_ID);
- final ActivityStack freeformStack = mStackSupervisor.getStack(
- FREEFORM_WORKSPACE_STACK_ID);
- final boolean dockedStackEmpty = dockedStack == null ||
- dockedStack.topRunningActivityLocked() == null;
- final boolean fullscreenStackEmpty = fullscreenStack == null ||
- fullscreenStack.topRunningActivityLocked() == null;
- final boolean freeformStackEmpty = freeformStack == null ||
- freeformStack.topRunningActivityLocked() == null;
- behindFullscreenActivity = dockedStackEmpty || !fullscreenStackEmpty ||
- !freeformStackEmpty;
- } else if (task.isHomeTask()) {
+ if (task.isHomeTask()) {
if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Home task: at " + task
+ " stackInvisible=" + stackInvisible
+ " behindFullscreenActivity=" + behindFullscreenActivity);
@@ -1993,7 +1948,14 @@
if (visibleBehind == r) {
releaseBackgroundResources(r);
} else {
- addToStopping(r, true /* immediate */);
+ // If this activity is in a state where it can currently enter
+ // picture-in-picture, then don't immediately schedule the idle now in case
+ // the activity tries to enterPictureInPictureMode() later. Otherwise,
+ // we will try and stop the activity next time idle is processed.
+ final boolean canEnterPictureInPicture = r.checkEnterPictureInPictureState(
+ "makeInvisible", true /* noThrow */);
+ addToStopping(r, true /* scheduleIdle */,
+ canEnterPictureInPicture /* idleDelayed */);
}
break;
@@ -2684,14 +2646,7 @@
ActivityStack lastStack = mStackSupervisor.getLastStack();
final boolean fromHomeOrRecents = lastStack.isHomeOrRecentsStack();
final TaskRecord topTask = lastStack.topTask();
- final boolean fromOnTopLauncher = topTask != null && topTask.isOnTopLauncher();
- if (fromOnTopLauncher) {
- // Since an on-top launcher will is moved to back when tasks are launched from it,
- // those tasks should first try to return to a non-home activity.
- // This also makes sure that non-home activities are visible under a transparent
- // non-home activity.
- task.setTaskToReturnTo(APPLICATION_ACTIVITY_TYPE);
- } else if (!isHomeOrRecentsStack() && (fromHomeOrRecents || topTask() != task)) {
+ if (!isHomeOrRecentsStack() && (fromHomeOrRecents || topTask() != task)) {
// If it's a last task over home - we default to keep its return to type not to
// make underlying task focused when this one will be finished.
int returnToType = isLastTaskOverHome
@@ -2760,7 +2715,12 @@
// Slot the activity into the history stack and proceed
if (DEBUG_ADD_REMOVE) Slog.i(TAG, "Adding activity " + r + " to stack to task " + task,
new RuntimeException("here").fillInStackTrace());
- r.createWindowContainer();
+ // TODO: Need to investigate if it is okay for the controller to already be created by the
+ // time we get to this point. I think it is, but need to double check.
+ // Use test in b/34179495 to trace the call path.
+ if (r.getWindowContainerController() == null) {
+ r.createWindowContainer();
+ }
task.setFrontOfTask();
if (!isHomeOrRecentsStack() || numActivities() > 0) {
@@ -2937,8 +2897,7 @@
+ targetTask + " Callers=" + Debug.getCallers(4));
if (DEBUG_TASKS) Slog.v(TAG_TASKS,
"Pushing next activity " + p + " out to target's task " + target.task);
- p.setTask(targetTask, null);
- targetTask.addActivityAtBottom(p);
+ p.reparent(targetTask, 0 /* position - bottom */, "resetTargetTaskIfNeeded");
}
mWindowContainerController.positionChildAtBottom(
@@ -3555,7 +3514,7 @@
if (mode == FINISH_AFTER_VISIBLE && (r.visible || r.nowVisible)
&& next != null && !next.nowVisible) {
if (!mStackSupervisor.mStoppingActivities.contains(r)) {
- addToStopping(r, false /* immediate */);
+ addToStopping(r, false /* scheduleIdle */, false /* idleDelayed */);
}
if (DEBUG_STATES) Slog.v(TAG_STATES,
"Moving to STOPPING: "+ r + " (finish requested)");
@@ -3809,7 +3768,7 @@
mWindowManager.notifyAppRelaunchesCleared(r.appToken);
}
- private void removeTimeoutsForActivityLocked(ActivityRecord r) {
+ void removeTimeoutsForActivityLocked(ActivityRecord r) {
mStackSupervisor.removeTimeoutsForActivityLocked(r);
mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
mHandler.removeMessages(STOP_TIMEOUT_MSG, r);
@@ -4385,23 +4344,6 @@
if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, "Prepare to back transition: task=" + taskId);
if (mStackId == HOME_STACK_ID && topTask().isHomeTask()) {
- if (topTask().isOnTopLauncher()) {
- // An on-top launcher doesn't affect the visibility of activities on other stacks
- // behind it. So if we're moving an on-top launcher to the back, we want to move the
- // focus to the next focusable stack and resume an activity there.
- // Besides, when the docked stack is visible, we should also move the home stack to
- // the back to avoid the recents pops up on top of a fullscreen or freeform
- // activity.
-
- // Move the home stack to back.
- moveToBack(topTask());
-
- // Resume an activity in the next focusable stack.
- adjustFocusToNextFocusableStackLocked("moveTaskToBack");
- mStackSupervisor.resumeFocusedStackTopActivityLocked();
- return true;
- }
-
// For the case where we are moving the home task back and there is an activity visible
// behind it on the fullscreen stack, we want to move the focus to the visible behind
// activity to maintain order with what the user is seeing.
@@ -5074,6 +5016,7 @@
// If the activity was previously pausing, then ensure we transfer that as well
if (setPause) {
mPausingActivity = r;
+ schedulePauseTimeout(r);
}
// Move the stack in which we are placing the activity to the front. The call will also
// make sure the activity focus is set.
@@ -5115,6 +5058,7 @@
}
if (wasPaused) {
prevStack.mPausingActivity = null;
+ prevStack.removeTimeoutsForActivityLocked(r);
}
}
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 4411794..e954363 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -163,6 +163,8 @@
import android.view.Surface;
import com.android.internal.content.ReferrerIntent;
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.os.TransferPipe;
import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.util.ArrayUtils;
@@ -1333,10 +1335,18 @@
// Because we could be starting an Activity in the system process this may not go across
// a Binder interface which would create a new Configuration. Consequently we have to
// always create a new Configuration here.
+
+ final Configuration globalConfiguration =
+ new Configuration(mService.getGlobalConfiguration());
+ r.setLastReportedGlobalConfiguration(globalConfiguration);
+ final Configuration mergedOverrideConfiguration =
+ new Configuration(task.getMergedOverrideConfiguration());
+ r.setLastReportedMergedOverrideConfiguration(mergedOverrideConfiguration);
+
app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
System.identityHashCode(r), r.info,
- new Configuration(mService.getGlobalConfiguration()),
- new Configuration(task.getMergedOverrideConfiguration()), r.compat,
+ globalConfiguration,
+ mergedOverrideConfiguration, r.compat,
r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
r.persistentState, results, newIntents, !andResume,
mService.isNextTransitionForward(), profilerInfo);
@@ -1705,7 +1715,7 @@
// Checked.
final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,
- Configuration config) {
+ boolean processPausingActivities, Configuration config) {
if (DEBUG_ALL) Slog.v(TAG, "Activity idle: " + token);
ArrayList<ActivityRecord> finishes = null;
@@ -1731,7 +1741,7 @@
// We'll update with whatever configuration it now says
// it used to launch.
if (config != null) {
- r.setLastReportedConfiguration(config);
+ r.setLastReportedGlobalConfiguration(config);
}
// We are now idle. If someone is waiting for a thumbnail from
@@ -1761,7 +1771,8 @@
}
// Atomically retrieve all of the other things to do.
- final ArrayList<ActivityRecord> stops = processStoppingActivitiesLocked(true);
+ final ArrayList<ActivityRecord> stops = processStoppingActivitiesLocked(r,
+ true /* remove */, processPausingActivities);
NS = stops != null ? stops.size() : 0;
if ((NF = mFinishingActivities.size()) > 0) {
finishes = new ArrayList<>(mFinishingActivities);
@@ -2277,6 +2288,8 @@
// pinned stack is recreated. See moveActivityToPinnedStackLocked().
task.setTaskToReturnTo(isFullscreenStackVisible && onTop ?
APPLICATION_ACTIVITY_TYPE : HOME_ACTIVITY_TYPE);
+ MetricsLogger.action(mService.mContext,
+ MetricsEvent.ACTION_PICTURE_IN_PICTURE_EXPANDED_TO_FULLSCREEN);
}
moveTaskToStackLocked(tasks.get(i).taskId,
FULLSCREEN_WORKSPACE_STACK_ID, onTop, onTop /*forceFocus*/,
@@ -2689,6 +2702,7 @@
// Reset the paused activity on the previous stack
if (wasPaused) {
prevStack.mPausingActivity = null;
+ prevStack.removeTimeoutsForActivityLocked(r);
}
// If the task had focus before (or we're requested to move focus),
@@ -3367,7 +3381,8 @@
return mService.mUserController.isCurrentProfileLocked(userId);
}
- final ArrayList<ActivityRecord> processStoppingActivitiesLocked(boolean remove) {
+ final ArrayList<ActivityRecord> processStoppingActivitiesLocked(ActivityRecord idleActivity,
+ boolean remove, boolean processPausingActivities) {
ArrayList<ActivityRecord> stops = null;
final boolean nowVisible = allResumedActivitiesVisible();
@@ -3392,6 +3407,14 @@
}
}
if ((!waitingVisible || mService.isSleepingOrShuttingDownLocked()) && remove) {
+ if (!processPausingActivities && s.state == PAUSING) {
+ // Defer processing pausing activities in this iteration and reschedule
+ // a delayed idle to reprocess it again
+ removeTimeoutsForActivityLocked(idleActivity);
+ scheduleIdleTimeoutLocked(idleActivity);
+ continue;
+ }
+
if (DEBUG_STATES) Slog.v(TAG, "Ready to stop: " + s);
if (stops == null) {
stops = new ArrayList<>();
@@ -4101,9 +4124,10 @@
super(looper);
}
- void activityIdleInternal(ActivityRecord r) {
+ void activityIdleInternal(ActivityRecord r, boolean processPausingActivities) {
synchronized (mService) {
- activityIdleInternalLocked(r != null ? r.appToken : null, true, null);
+ activityIdleInternalLocked(r != null ? r.appToken : null, true /* fromTimeout */,
+ processPausingActivities, null);
}
}
@@ -4138,11 +4162,13 @@
}
// We don't at this point know if the activity is fullscreen,
// so we need to be conservative and assume it isn't.
- activityIdleInternal((ActivityRecord)msg.obj);
+ activityIdleInternal((ActivityRecord) msg.obj,
+ true /* processPausingActivities */);
} break;
case IDLE_NOW_MSG: {
if (DEBUG_IDLE) Slog.d(TAG_IDLE, "handleMessage: IDLE_NOW_MSG: r=" + msg.obj);
- activityIdleInternal((ActivityRecord)msg.obj);
+ activityIdleInternal((ActivityRecord) msg.obj,
+ false /* processPausingActivities */);
} break;
case RESUME_TOP_ACTIVITY_MSG: {
synchronized (mService) {
@@ -4887,24 +4913,4 @@
}
return topActivityTokens;
}
-
- public IBinder getTopVisibleActivity(int uid) {
- // TODO(b/33197203): get rid of DEFAULT_DISPLAY here?. Used in
- // VoiceInteractionManagerServiceImpl#showSessionLocked.
- final ActivityDisplay display = mActivityDisplays.get(DEFAULT_DISPLAY);
- if (display == null) {
- return null;
- }
- final ArrayList<ActivityStack> stacks = display.mStacks;
- for (int i = stacks.size() - 1; i >= 0; i--) {
- ActivityStack stack = stacks.get(i);
- if (stack.getStackVisibilityLocked(null) == ActivityStack.STACK_VISIBLE) {
- ActivityRecord top = stack.topActivity();
- if (top != null && stack == mFocusedStack && top.app.uid == uid) {
- return top.appToken;
- }
- }
- }
- return null;
- }
}
diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java
index 73ef88b..d1606b4 100644
--- a/services/core/java/com/android/server/am/ActivityStarter.java
+++ b/services/core/java/com/android/server/am/ActivityStarter.java
@@ -1498,15 +1498,7 @@
private void updateTaskReturnToType(
TaskRecord task, int launchFlags, ActivityStack focusedStack) {
- if (focusedStack != null && focusedStack.isHomeOrRecentsStack()
- && focusedStack.topTask() != null && focusedStack.topTask().isOnTopLauncher()) {
- // Since an on-top launcher will is moved to back when tasks are launched from it,
- // those tasks should first try to return to a non-home activity.
- // This also makes sure that non-home activities are visible under a transparent
- // non-home activity.
- task.setTaskToReturnTo(APPLICATION_ACTIVITY_TYPE);
- return;
- } else if ((launchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME))
+ if ((launchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME))
== (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) {
// Caller wants to appear on home activity.
task.setTaskToReturnTo(HOME_ACTIVITY_TYPE);
@@ -1615,7 +1607,7 @@
mNewTaskInfo != null ? mNewTaskInfo : mStartActivity.info,
mNewTaskIntent != null ? mNewTaskIntent : mIntent, mVoiceSession,
mVoiceInteractor, !mLaunchTaskBehind /* toTop */, mStartActivity.mActivityType);
- mStartActivity.setTask(task, taskToAffiliate);
+ addOrReparentStartingActivity(task, "setTaskFromReuseOrCreateNewTask - mReuseTask");
if (mLaunchBounds != null) {
final int stackId = mTargetStack.mStackId;
if (StackId.resizeStackWithLaunchBounds(stackId)) {
@@ -1625,11 +1617,14 @@
mStartActivity.task.updateOverrideConfiguration(mLaunchBounds);
}
}
- if (DEBUG_TASKS) Slog.v(TAG_TASKS,
- "Starting new activity " +
- mStartActivity + " in new task " + mStartActivity.task);
+ if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity
+ + " in new task " + mStartActivity.task);
} else {
- mStartActivity.setTask(mReuseTask, taskToAffiliate);
+ addOrReparentStartingActivity(mReuseTask, "setTaskFromReuseOrCreateNewTask");
+ }
+
+ if (taskToAffiliate != null) {
+ mStartActivity.setTaskToAffiliateWith(taskToAffiliate);
}
if (mSupervisor.isLockTaskModeViolation(mStartActivity.task)) {
@@ -1719,7 +1714,7 @@
// An existing activity is starting this new activity, so we want to keep the new one in
// the same task as the one that is starting it.
- mStartActivity.setTask(sourceTask, null);
+ addOrReparentStartingActivity(sourceTask, "setTaskFromSourceRecord");
if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity
+ " in existing task " + mStartActivity.task + " from source " + mSourceRecord);
return START_SUCCESS;
@@ -1752,7 +1747,8 @@
// Check whether we should actually launch the new activity in to the task,
// or just reuse the current activity on top.
ActivityRecord top = mInTask.getTopActivity();
- if (top != null && top.realActivity.equals(mStartActivity.realActivity) && top.userId == mStartActivity.userId) {
+ if (top != null && top.realActivity.equals(mStartActivity.realActivity)
+ && top.userId == mStartActivity.userId) {
if ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
|| mLaunchSingleTop || mLaunchSingleTask) {
ActivityStack.logStartActivity(AM_NEW_INTENT, top, top.task);
@@ -1761,7 +1757,8 @@
// anything if that is the case, so this is it!
return START_RETURN_INTENT_TO_CALLER;
}
- top.deliverNewIntentLocked(mCallingUid, mStartActivity.intent, mStartActivity.launchedFromPackage);
+ top.deliverNewIntentLocked(mCallingUid, mStartActivity.intent,
+ mStartActivity.launchedFromPackage);
return START_DELIVERED_TO_TOP;
}
}
@@ -1773,9 +1770,9 @@
return START_TASK_TO_FRONT;
}
- mStartActivity.setTask(mInTask, null);
- if (DEBUG_TASKS) Slog.v(TAG_TASKS,
- "Starting new activity " + mStartActivity + " in explicit task " + mStartActivity.task);
+ addOrReparentStartingActivity(mInTask, "setTaskFromInTask");
+ if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity
+ + " in explicit task " + mStartActivity.task);
return START_SUCCESS;
}
@@ -1790,10 +1787,18 @@
final TaskRecord task = (prev != null) ? prev.task : mTargetStack.createTaskRecord(
mSupervisor.getNextTaskIdForUserLocked(mStartActivity.userId), mStartActivity.info,
mIntent, null, null, true, mStartActivity.mActivityType);
- mStartActivity.setTask(task, null);
- mStartActivity.task.getStack().positionChildWindowContainerAtTop(mStartActivity.task);
- if (DEBUG_TASKS) Slog.v(TAG_TASKS,
- "Starting new activity " + mStartActivity + " in new guessed " + mStartActivity.task);
+ addOrReparentStartingActivity(task, "setTaskToCurrentTopOrCreateNewTask");
+ mTargetStack.positionChildWindowContainerAtTop(task);
+ if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity
+ + " in new guessed " + mStartActivity.task);
+ }
+
+ private void addOrReparentStartingActivity(TaskRecord parent, String reason) {
+ if (mStartActivity.task == null || mStartActivity.task == parent) {
+ parent.addActivityToTop(mStartActivity);
+ } else {
+ mStartActivity.reparent(parent, parent.mActivities.size() /* top */, reason);
+ }
}
private int adjustLaunchFlagsToDocumentMode(ActivityRecord r, boolean launchSingleInstance,
diff --git a/services/core/java/com/android/server/am/AppErrors.java b/services/core/java/com/android/server/am/AppErrors.java
index 384f2f8..36a913f 100644
--- a/services/core/java/com/android/server/am/AppErrors.java
+++ b/services/core/java/com/android/server/am/AppErrors.java
@@ -357,7 +357,7 @@
* If this process was running instrumentation, finish now - it will be handled in
* {@link ActivityManagerService#handleAppDiedLocked}.
*/
- if (r != null && r.instrumentationClass != null) {
+ if (r != null && r.instr != null) {
return;
}
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index f1f8bb2..3571302 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -51,8 +51,8 @@
import android.telephony.TelephonyManager;
import android.util.IntArray;
import android.util.Slog;
-
import android.util.TimeUtils;
+
import com.android.internal.annotations.GuardedBy;
import com.android.internal.app.IBatteryStats;
import com.android.internal.os.BatteryStatsHelper;
@@ -1127,6 +1127,7 @@
pw.println(" full-history: include additional detailed events in battery history:");
pw.println(" wake_lock_in, alarms and proc events");
pw.println(" no-auto-reset: don't automatically reset stats when unplugged");
+ pw.println(" pretend-screen-off: pretend the screen is off, even if screen state changes");
}
private int doEnableOrDisable(PrintWriter pw, int i, String[] args, boolean enable) {
@@ -1144,6 +1145,10 @@
synchronized (mStats) {
mStats.setNoAutoReset(enable);
}
+ } else if ("pretend-screen-off".equals(args[i])) {
+ synchronized (mStats) {
+ mStats.setPretendScreenOff(enable);
+ }
} else {
pw.println("Unknown enable/disable option: " + args[i]);
dumpHelp(pw);
diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java
index 49fe79c..356781f 100644
--- a/services/core/java/com/android/server/am/ProcessRecord.java
+++ b/services/core/java/com/android/server/am/ProcessRecord.java
@@ -135,13 +135,7 @@
int lruSeq; // Sequence id for identifying LRU update cycles
CompatibilityInfo compat; // last used compatibility mode
IBinder.DeathRecipient deathRecipient; // Who is watching for the death.
- ComponentName instrumentationClass;// class installed to instrument app
- ApplicationInfo instrumentationInfo; // the application being instrumented
- String instrumentationProfileFile; // where to save profiling
- IInstrumentationWatcher instrumentationWatcher; // who is waiting
- IUiAutomationConnection instrumentationUiAutomationConnection; // Connection to use the UI introspection APIs.
- Bundle instrumentationArguments;// as given to us
- ComponentName instrumentationResultClass;// copy of instrumentationClass
+ ActiveInstrumentation instr;// Set to currently active instrumentation running in process
boolean usingWrapper; // Set to true when process was launched with a wrapper attached
final ArraySet<BroadcastRecord> curReceivers = new ArraySet<BroadcastRecord>();// receivers currently running in the app
long lastWakeTime; // How long proc held wake lock at last check
@@ -248,19 +242,8 @@
pw.println("}");
}
pw.print(prefix); pw.print("compat="); pw.println(compat);
- if (instrumentationClass != null || instrumentationProfileFile != null
- || instrumentationArguments != null) {
- pw.print(prefix); pw.print("instrumentationClass=");
- pw.print(instrumentationClass);
- pw.print(" instrumentationProfileFile=");
- pw.println(instrumentationProfileFile);
- pw.print(prefix); pw.print("instrumentationArguments=");
- pw.println(instrumentationArguments);
- pw.print(prefix); pw.print("instrumentationInfo=");
- pw.println(instrumentationInfo);
- if (instrumentationInfo != null) {
- instrumentationInfo.dump(new PrintWriterPrinter(pw), prefix + " ");
- }
+ if (instr != null) {
+ pw.print(prefix); pw.print("instr="); pw.println(instr);
}
pw.print(prefix); pw.print("thread="); pw.println(thread);
pw.print(prefix); pw.print("pid="); pw.print(pid); pw.print(" starting=");
diff --git a/services/core/java/com/android/server/am/ProcessStatsService.java b/services/core/java/com/android/server/am/ProcessStatsService.java
index 8d2b1c2..d210ed7 100644
--- a/services/core/java/com/android/server/am/ProcessStatsService.java
+++ b/services/core/java/com/android/server/am/ProcessStatsService.java
@@ -28,6 +28,8 @@
import android.util.Slog;
import android.util.SparseArray;
import android.util.TimeUtils;
+
+import com.android.internal.annotations.GuardedBy;
import com.android.internal.app.procstats.DumpUtils;
import com.android.internal.app.procstats.IProcessStats;
import com.android.internal.app.procstats.ProcessState;
@@ -78,6 +80,10 @@
boolean mPendingWriteCommitted;
long mLastWriteTime;
+ /** For CTS to inject the screen state. */
+ @GuardedBy("mAm")
+ Boolean mInjectedScreenState;
+
public ProcessStatsService(ActivityManagerService am, File file) {
mAm = am;
mBaseDir = file;
@@ -128,6 +134,9 @@
public boolean setMemFactorLocked(int memFactor, boolean screenOn, long now) {
mMemFactorLowered = memFactor < mLastMemOnlyState;
mLastMemOnlyState = memFactor;
+ if (mInjectedScreenState != null) {
+ screenOn = mInjectedScreenState;
+ }
if (screenOn) {
memFactor += ProcessStats.ADJ_SCREEN_ON;
}
@@ -573,7 +582,9 @@
pw.println(" [--checkin|-c|--csv] [--csv-screen] [--csv-proc] [--csv-mem]");
pw.println(" [--details] [--full-details] [--current] [--hours N] [--last N]");
pw.println(" [--max N] --active] [--commit] [--reset] [--clear] [--write] [-h]");
- pw.println(" [--start-testing] [--stop-testing] [<package.name>]");
+ pw.println(" [--start-testing] [--stop-testing] ");
+ pw.println(" [--pretend-screen-on] [--pretend-screen-off] [--stop-pretend-screen]");
+ pw.println(" [<package.name>]");
pw.println(" --checkin: perform a checkin: print and delete old committed states.");
pw.println(" -c: print only state in checkin format.");
pw.println(" --csv: output data suitable for putting in a spreadsheet.");
@@ -595,6 +606,9 @@
pw.println(" --read: replace current stats with last-written stats.");
pw.println(" --start-testing: clear all stats and starting high frequency pss sampling.");
pw.println(" --stop-testing: stop high frequency pss sampling.");
+ pw.println(" --pretend-screen-on: pretend screen is on.");
+ pw.println(" --pretend-screen-off: pretend screen is off.");
+ pw.println(" --stop-pretend-screen: forget \"pretend screen\" and use the real state.");
pw.println(" -a: print everything.");
pw.println(" -h: print this help text.");
pw.println(" <package.name>: optional name of package to filter output by.");
@@ -800,6 +814,21 @@
pw.println("Stopped high frequency sampling.");
quit = true;
}
+ } else if ("--pretend-screen-on".equals(arg)) {
+ synchronized (mAm) {
+ mInjectedScreenState = true;
+ }
+ quit = true;
+ } else if ("--pretend-screen-off".equals(arg)) {
+ synchronized (mAm) {
+ mInjectedScreenState = false;
+ }
+ quit = true;
+ } else if ("--stop-pretend-screen".equals(arg)) {
+ synchronized (mAm) {
+ mInjectedScreenState = null;
+ }
+ quit = true;
} else if ("-h".equals(arg)) {
dumpHelp(pw);
return;
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index fef4073..e237e41 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -51,6 +51,7 @@
import com.android.internal.app.IVoiceInteractor;
import com.android.internal.util.XmlUtils;
+import com.android.server.wm.AppWindowContainerController;
import com.android.server.wm.TaskWindowContainerController;
import com.android.server.wm.TaskWindowContainerListener;
@@ -74,7 +75,6 @@
import static android.app.ActivityManager.StackId.RECENTS_STACK_ID;
import static android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
import static android.content.Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS;
-import static android.content.pm.ActivityInfo.FLAG_ON_TOP_LAUNCHER;
import static android.content.pm.ActivityInfo.FLAG_RELINQUISH_TASK_IDENTITY;
import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_ALWAYS;
import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_DEFAULT;
@@ -190,17 +190,15 @@
int mResizeMode; // The resize mode of this task and its activities.
// Based on the {@link ActivityInfo#resizeMode} of the root activity.
- boolean mSupportsPictureInPicture; // Whether or not this task and its activities support PiP.
- // Based on the {@link ActivityInfo#FLAG_SUPPORTS_PICTURE_IN_PICTURE} flag of the root
- // activity.
+ private boolean mSupportsPictureInPicture; // Whether or not this task and its activities
+ // support PiP. Based on the {@link ActivityInfo#FLAG_SUPPORTS_PICTURE_IN_PICTURE} flag
+ // of the root activity.
boolean mTemporarilyUnresizable; // Separate flag from mResizeMode used to suppress resize
// changes on a temporary basis.
private int mLockTaskMode; // Which tasklock mode to launch this task in. One of
// ActivityManager.LOCK_TASK_LAUNCH_MODE_*
private boolean mPrivileged; // The root activity application of this task holds
// privileged permissions.
- private boolean mIsOnTopLauncher; // Whether this task is an on-top launcher. See
- // android.R.attr#onTopLauncher.
/** Can't be put in lockTask mode. */
final static int LOCK_TASK_AUTH_DONT_LOCK = 0;
@@ -423,8 +421,8 @@
final Configuration overrideConfig = getOverrideConfiguration();
mWindowContainerController = new TaskWindowContainerController(taskId, this,
getStack().getWindowContainerController(), userId, bounds, overrideConfig,
- mResizeMode, mSupportsPictureInPicture, isHomeTask(), isOnTopLauncher(),
- onTop, showForAllUsers, lastTaskDescription);
+ mResizeMode, mSupportsPictureInPicture, isHomeTask(), onTop, showForAllUsers,
+ lastTaskDescription);
}
void removeWindowContainer() {
@@ -687,7 +685,6 @@
}
mResizeMode = info.resizeMode;
mSupportsPictureInPicture = info.supportsPictureInPicture();
- mIsOnTopLauncher = (info.flags & FLAG_ON_TOP_LAUNCHER) != 0;
mLockTaskMode = info.lockTaskLaunchMode;
mPrivileged = (info.applicationInfo.privateFlags & PRIVATE_FLAG_PRIVILEGED) != 0;
setLockTaskAuth();
@@ -1033,6 +1030,12 @@
* be in the current task or unparented to any task.
*/
void addActivityAtIndex(int index, ActivityRecord r) {
+ if (r.task != null && r.task != this) {
+ throw new IllegalArgumentException("Can not add r=" + " to task=" + this
+ + " current parent=" + r.task);
+ }
+ r.task = this;
+
// Remove r first, and if it wasn't already in the list and it's fullscreen, count it.
if (!mActivities.remove(r) && r.fullscreen) {
// Was not previously in list.
@@ -1063,6 +1066,7 @@
}
}
+ index = Math.min(size, index);
mActivities.add(index, r);
updateEffectiveIntent();
if (r.isPersistable()) {
@@ -1071,7 +1075,12 @@
// Sync. with window manager
updateOverrideConfigurationFromLaunchBounds();
- mWindowContainerController.positionChildAt(r.getWindowContainerController(), index);
+ final AppWindowContainerController appController = r.getWindowContainerController();
+ if (appController != null) {
+ // Only attempt to move in WM if the child has a controller. It is possible we haven't
+ // created controller for the activity we are starting yet.
+ mWindowContainerController.positionChildAt(appController, index);
+ }
r.onOverrideConfigurationSent();
}
@@ -1322,7 +1331,7 @@
* @param bounds The bounds to be tested.
* @return True if the requested bounds are okay for a resizing request.
*/
- boolean canResizeToBounds(Rect bounds) {
+ private boolean canResizeToBounds(Rect bounds) {
if (bounds == null || getStackId() != FREEFORM_WORKSPACE_STACK_ID) {
// Note: If not on the freeform workspace, we ignore the bounds.
return true;
@@ -1335,10 +1344,6 @@
&& (mResizeMode != RESIZE_MODE_FORCE_RESIZABLE_LANDSCAPE_ONLY || landscape);
}
- boolean isOnTopLauncher() {
- return isHomeTask() && mIsOnTopLauncher;
- }
-
/**
* Find the activity in the history stack within the given task. Returns
* the index within the history at which it's found, or < 0 if not found.
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index ef792b0..1d60946 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -5933,7 +5933,7 @@
final AccessibilityManager accessibilityManager =
(AccessibilityManager) mContext.getSystemService(Context.ACCESSIBILITY_SERVICE);
updateDefaultStreamOverrideDelay(accessibilityManager.isTouchExplorationEnabled());
- updateA11yVolumeAlias(accessibilityManager.isEnabled());
+ updateA11yVolumeAlias(accessibilityManager.isAccessibilityVolumeStreamActive());
accessibilityManager.addTouchExplorationStateChangeListener(this);
accessibilityManager.addAccessibilityServicesStateChangeListener(this);
}
@@ -6066,6 +6066,7 @@
pw.print(" mSafeMediaVolumeState=");
pw.println(safeMediaVolumeStateToString(mSafeMediaVolumeState));
pw.print(" mSafeMediaVolumeIndex="); pw.println(mSafeMediaVolumeIndex);
+ pw.print(" sIndependentA11yVolume="); pw.println(sIndependentA11yVolume);
pw.print(" mPendingVolumeCommand="); pw.println(mPendingVolumeCommand);
pw.print(" mMusicActiveMs="); pw.println(mMusicActiveMs);
pw.print(" mMcc="); pw.println(mMcc);
diff --git a/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java b/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
index 816d5fe..4930c53 100644
--- a/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
+++ b/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
@@ -46,7 +46,7 @@
implements AudioPlaybackConfiguration.PlayerDeathMonitor, PlayerFocusEnforcer {
public final static String TAG = "AudioService.PlaybackActivityMonitor";
- private final static boolean DEBUG = true;
+ private final static boolean DEBUG = false;
private ArrayList<PlayMonitorClient> mClients = new ArrayList<PlayMonitorClient>();
// a public client is one that needs an anonymized version of the playback configurations, we
diff --git a/services/core/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java b/services/core/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java
index 08a3332..017c5fb 100644
--- a/services/core/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java
+++ b/services/core/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java
@@ -66,9 +66,9 @@
public static final int EVENT_ON_LINKPROPERTIES = 3;
public static final int EVENT_ON_LOST = 4;
- private static final int LISTEN_ALL = 1;
- private static final int TRACK_DEFAULT = 2;
- private static final int MOBILE_REQUEST = 3;
+ private static final int CALLBACK_LISTEN_ALL = 1;
+ private static final int CALLBACK_TRACK_DEFAULT = 2;
+ private static final int CALLBACK_MOBILE_REQUEST = 3;
private final Context mContext;
private final StateMachine mTarget;
@@ -98,10 +98,10 @@
final NetworkRequest listenAllRequest = new NetworkRequest.Builder()
.clearCapabilities().build();
- mListenAllCallback = new UpstreamNetworkCallback(LISTEN_ALL);
+ mListenAllCallback = new UpstreamNetworkCallback(CALLBACK_LISTEN_ALL);
cm().registerNetworkCallback(listenAllRequest, mListenAllCallback);
- mDefaultNetworkCallback = new UpstreamNetworkCallback(TRACK_DEFAULT);
+ mDefaultNetworkCallback = new UpstreamNetworkCallback(CALLBACK_TRACK_DEFAULT);
cm().registerDefaultNetworkCallback(mDefaultNetworkCallback);
}
@@ -136,30 +136,25 @@
return;
}
- final NetworkRequest.Builder builder = new NetworkRequest.Builder()
- .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
- if (mDunRequired) {
- builder.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
- .addCapability(NetworkCapabilities.NET_CAPABILITY_DUN);
- } else {
- builder.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
- }
- final NetworkRequest mobileUpstreamRequest = builder.build();
+ // The following use of the legacy type system cannot be removed until
+ // after upstream selection no longer finds networks by legacy type.
+ // See also http://b/34364553 .
+ final int legacyType = mDunRequired ? TYPE_MOBILE_DUN : TYPE_MOBILE_HIPRI;
+
+ final NetworkRequest mobileUpstreamRequest = new NetworkRequest.Builder()
+ .setCapabilities(ConnectivityManager.networkCapabilitiesForType(legacyType))
+ .build();
// The existing default network and DUN callbacks will be notified.
// Therefore, to avoid duplicate notifications, we only register a no-op.
- mMobileNetworkCallback = new UpstreamNetworkCallback(MOBILE_REQUEST);
+ mMobileNetworkCallback = new UpstreamNetworkCallback(CALLBACK_MOBILE_REQUEST);
// TODO: Change the timeout from 0 (no onUnavailable callback) to some
// moderate callback timeout. This might be useful for updating some UI.
// Additionally, we log a message to aid in any subsequent debugging.
Log.d(TAG, "requesting mobile upstream network: " + mobileUpstreamRequest);
- // The following use of the legacy type system cannot be removed until
- // after upstream selection no longer finds networks by legacy type.
- // See also b/34364553.
- final int apnType = mDunRequired ? TYPE_MOBILE_DUN : TYPE_MOBILE_HIPRI;
- cm().requestNetwork(mobileUpstreamRequest, mMobileNetworkCallback, 0, apnType);
+ cm().requestNetwork(mobileUpstreamRequest, mMobileNetworkCallback, 0, legacyType);
}
public void releaseMobileNetworkRequest() {
@@ -184,17 +179,18 @@
// Always request whatever extra information we can, in case this
// was already up when start() was called, in which case we would
// not have been notified of any information that had not changed.
- final NetworkCallback cb =
- (callbackType == TRACK_DEFAULT) ? mDefaultNetworkCallback :
- (callbackType == MOBILE_REQUEST) ? mMobileNetworkCallback : null;
- if (cb != null) {
- final ConnectivityManager cm = cm();
- cm.requestNetworkCapabilities(mDefaultNetworkCallback);
- cm.requestLinkProperties(mDefaultNetworkCallback);
- }
-
- if (callbackType == TRACK_DEFAULT) {
- mCurrentDefault = network;
+ switch (callbackType) {
+ case CALLBACK_LISTEN_ALL:
+ break;
+ case CALLBACK_TRACK_DEFAULT:
+ cm().requestNetworkCapabilities(mDefaultNetworkCallback);
+ cm().requestLinkProperties(mDefaultNetworkCallback);
+ mCurrentDefault = network;
+ break;
+ case CALLBACK_MOBILE_REQUEST:
+ cm().requestNetworkCapabilities(mMobileNetworkCallback);
+ cm().requestLinkProperties(mMobileNetworkCallback);
+ break;
}
// Requesting updates for mListenAllCallback is not currently possible
@@ -262,7 +258,7 @@
}
private void handleLost(int callbackType, Network network) {
- if (callbackType == TRACK_DEFAULT) {
+ if (callbackType == CALLBACK_TRACK_DEFAULT) {
mCurrentDefault = null;
// Receiving onLost() for a default network does not necessarily
// mean the network is gone. We wait for a separate notification
diff --git a/services/core/java/com/android/server/display/AutomaticBrightnessController.java b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
index 3da49d8..168744b 100644
--- a/services/core/java/com/android/server/display/AutomaticBrightnessController.java
+++ b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
@@ -18,9 +18,6 @@
import com.android.server.EventLogTags;
import com.android.server.LocalServices;
-import com.android.server.twilight.TwilightListener;
-import com.android.server.twilight.TwilightManager;
-import com.android.server.twilight.TwilightState;
import android.annotation.Nullable;
import android.hardware.Sensor;
@@ -55,9 +52,6 @@
// non-zero, which in turn ensures that the total weight is non-zero.
private static final long AMBIENT_LIGHT_PREDICTION_TIME_MILLIS = 100;
- // Specifies the maximum magnitude of the time of day adjustment.
- private static final float TWILIGHT_ADJUSTMENT_MAX_GAMMA = 1f;
-
// Debounce for sampling user-initiated changes in display brightness to ensure
// the user is satisfied with the result before storing the sample.
private static final int BRIGHTNESS_ADJUSTMENT_SAMPLE_DEBOUNCE_MILLIS = 10000;
@@ -74,9 +68,6 @@
// The light sensor, or null if not available or needed.
private final Sensor mLightSensor;
- // The twilight service.
- private final TwilightManager mTwilight;
-
// The auto-brightness spline adjustment.
// The brightness values have been scaled to a range of 0..1.
private final Spline mScreenAutoBrightnessSpline;
@@ -186,8 +177,6 @@
private int mBrightnessAdjustmentSampleOldBrightness;
private float mBrightnessAdjustmentSampleOldGamma;
- private boolean mUseTwilight;
-
public AutomaticBrightnessController(Callbacks callbacks, Looper looper,
SensorManager sensorManager, Spline autoBrightnessSpline, int lightSensorWarmUpTime,
int brightnessMin, int brightnessMax, float dozeScaleFactor,
@@ -196,7 +185,6 @@
int ambientLightHorizon, float autoBrightnessAdjustmentMaxGamma,
HysteresisLevels dynamicHysteresis) {
mCallbacks = callbacks;
- mTwilight = LocalServices.getService(TwilightManager.class);
mSensorManager = sensorManager;
mScreenAutoBrightnessSpline = autoBrightnessSpline;
mScreenBrightnessRangeMinimum = brightnessMin;
@@ -233,7 +221,7 @@
}
public void configure(boolean enable, float adjustment, boolean dozing,
- boolean userInitiatedChange, boolean useTwilight) {
+ boolean userInitiatedChange) {
// While dozing, the application processor may be suspended which will prevent us from
// receiving new information from the light sensor. On some devices, we may be able to
// switch to a wake-up light sensor instead but for now we will simply disable the sensor
@@ -242,7 +230,6 @@
mDozing = dozing;
boolean changed = setLightSensorEnabled(enable && !dozing);
changed |= setScreenAutoBrightnessAdjustment(adjustment);
- changed |= setUseTwilight(useTwilight);
if (changed) {
updateAutoBrightness(false /*sendUpdate*/);
}
@@ -251,17 +238,6 @@
}
}
- private boolean setUseTwilight(boolean useTwilight) {
- if (mUseTwilight == useTwilight) return false;
- if (useTwilight) {
- mTwilight.registerListener(mTwilightListener, mHandler);
- } else {
- mTwilight.unregisterListener(mTwilightListener);
- }
- mUseTwilight = useTwilight;
- return true;
- }
-
public void dump(PrintWriter pw) {
pw.println();
pw.println("Automatic Brightness Controller Configuration:");
@@ -276,7 +252,6 @@
pw.println();
pw.println("Automatic Brightness Controller State:");
pw.println(" mLightSensor=" + mLightSensor);
- pw.println(" mTwilight.getLastTwilightState()=" + mTwilight.getLastTwilightState());
pw.println(" mLightSensorEnabled=" + mLightSensorEnabled);
pw.println(" mLightSensorEnableTime=" + TimeUtils.formatUptime(mLightSensorEnableTime));
pw.println(" mAmbientLux=" + mAmbientLux);
@@ -522,19 +497,6 @@
}
}
- if (mUseTwilight) {
- TwilightState state = mTwilight.getLastTwilightState();
- if (state != null && state.isNight()) {
- final long duration = state.sunriseTimeMillis() - state.sunsetTimeMillis();
- final long progress = System.currentTimeMillis() - state.sunsetTimeMillis();
- final float amount = (float) Math.pow(2.0 * progress / duration - 1.0, 2.0);
- gamma *= 1 + amount * TWILIGHT_ADJUSTMENT_MAX_GAMMA;
- if (DEBUG) {
- Slog.d(TAG, "updateAutoBrightness: twilight amount=" + amount);
- }
- }
- }
-
if (gamma != 1.0f) {
final float in = value;
value = MathUtils.pow(value, gamma);
@@ -649,13 +611,6 @@
}
};
- private final TwilightListener mTwilightListener = new TwilightListener() {
- @Override
- public void onTwilightStateChanged(@Nullable TwilightState state) {
- updateAutoBrightness(true /*sendUpdate*/);
- }
- };
-
/** Callbacks to request updates to the display's power state. */
interface Callbacks {
void updateBrightness();
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index 015345c..bed269c 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -642,7 +642,7 @@
&& mPowerRequest.brightnessSetByUser;
mAutomaticBrightnessController.configure(autoBrightnessEnabled,
mPowerRequest.screenAutoBrightnessAdjustment, state != Display.STATE_ON,
- userInitiatedChange, mPowerRequest.useTwilight);
+ userInitiatedChange);
}
// Apply brightness boost.
diff --git a/services/core/java/com/android/server/display/NightDisplayService.java b/services/core/java/com/android/server/display/NightDisplayService.java
index 0357b1b..7237fdb 100644
--- a/services/core/java/com/android/server/display/NightDisplayService.java
+++ b/services/core/java/com/android/server/display/NightDisplayService.java
@@ -111,7 +111,7 @@
getLocalService(DisplayTransformManager.class);
if (enabled) {
dtm.setColorMatrix(LEVEL_COLOR_MATRIX_NIGHT_DISPLAY, MATRIX_IDENTITY);
- } else if (mController.isActivated()) {
+ } else if (mController != null && mController.isActivated()) {
dtm.setColorMatrix(LEVEL_COLOR_MATRIX_NIGHT_DISPLAY, MATRIX_NIGHT);
}
}
diff --git a/services/core/java/com/android/server/fingerprint/FingerprintService.java b/services/core/java/com/android/server/fingerprint/FingerprintService.java
index d1f7cfd..e83b228 100644
--- a/services/core/java/com/android/server/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/fingerprint/FingerprintService.java
@@ -83,6 +83,7 @@
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
/**
@@ -113,6 +114,8 @@
new ArrayList<>();
private final CopyOnWriteArrayList<IFingerprintClientActiveCallback> mClientActiveCallbacks =
new CopyOnWriteArrayList<>();
+ private final Map<Integer, Long> mAuthenticatorIds =
+ Collections.synchronizedMap(new HashMap<>());
private final AppOpsManager mAppOps;
private static final long FAIL_LOCKOUT_TIMEOUT_MS = 30*1000;
private static final int MAX_FAILED_ATTEMPTS = 5;
@@ -130,7 +133,6 @@
private final UserManager mUserManager;
private ClientMonitor mCurrentClient;
private ClientMonitor mPendingClient;
- private long mCurrentAuthenticatorId;
private PerformanceStats mPerformanceStats;
// Normal fingerprint authentications are tracked by mPerformanceMap.
@@ -239,6 +241,7 @@
if (DEBUG) Slog.v(TAG, "Fingerprint HAL id: " + mHalDeviceId);
if (mHalDeviceId != 0) {
+ loadAuthenticatorIds();
updateActiveGroup(ActivityManager.getCurrentUser(), null);
} else {
Slog.w(TAG, "Failed to open Fingerprint HAL!");
@@ -249,6 +252,26 @@
return mDaemon;
}
+ /** Populates existing authenticator ids. To be used only during the start of the service. */
+ private void loadAuthenticatorIds() {
+ // This operation can be expensive, so keep track of the elapsed time. Might need to move to
+ // background if it takes too long.
+ long t = System.currentTimeMillis();
+
+ mAuthenticatorIds.clear();
+ for (UserInfo user : UserManager.get(mContext).getUsers(true /* excludeDying */)) {
+ int userId = getUserOrWorkProfileId(null, user.id);
+ if (!mAuthenticatorIds.containsKey(userId)) {
+ updateActiveGroup(userId, null);
+ }
+ }
+
+ t = System.currentTimeMillis() - t;
+ if (t > 1000) {
+ Slog.w(TAG, "loadAuthenticatorIds() taking too long: " + t + "ms");
+ }
+ }
+
protected void handleEnumerate(long deviceId, int fingerId, int groupId, int remaining) {
if (DEBUG) Slog.w(TAG, "Enumerate: fid=" + fingerId + ", gid="
+ groupId + "rem=" + remaining);
@@ -499,14 +522,23 @@
boolean isCurrentUserOrProfile(int userId) {
UserManager um = UserManager.get(mContext);
-
- // Allow current user or profiles of the current user...
- for (int profileId : um.getEnabledProfileIds(mCurrentUserId)) {
- if (profileId == userId) {
- return true;
- }
+ if (um == null) {
+ Slog.e(TAG, "Unable to acquire UserManager");
+ return false;
}
- return false;
+
+ final long token = Binder.clearCallingIdentity();
+ try {
+ // Allow current user or profiles of the current user...
+ for (int profileId : um.getEnabledProfileIds(mCurrentUserId)) {
+ if (profileId == userId) {
+ return true;
+ }
+ }
+ return false;
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
}
private boolean isForegroundActivity(int uid, int pid) {
@@ -1195,7 +1227,7 @@
daemon.setActiveGroup(userId, fpDir.getAbsolutePath());
mCurrentUserId = userId;
}
- mCurrentAuthenticatorId = daemon.getAuthenticatorId();
+ mAuthenticatorIds.put(userId, daemon.getAuthenticatorId());
} catch (RemoteException e) {
Slog.e(TAG, "Failed to setActiveGroup():", e);
}
@@ -1218,8 +1250,14 @@
* @return true if this is a work profile
*/
private boolean isWorkProfile(int userId) {
- UserInfo info = mUserManager.getUserInfo(userId);
- return info != null && info.isManagedProfile();
+ UserInfo userInfo = null;
+ final long token = Binder.clearCallingIdentity();
+ try {
+ userInfo = mUserManager.getUserInfo(userId);
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ return userInfo != null && userInfo.isManagedProfile();
}
private void listenForUserSwitches() {
@@ -1239,9 +1277,11 @@
/***
* @param opPackageName the name of the calling package
- * @return authenticator id for the current user
+ * @return authenticator id for the calling user
*/
public long getAuthenticatorId(String opPackageName) {
- return mCurrentAuthenticatorId;
+ final int userId = getUserOrWorkProfileId(opPackageName, UserHandle.getCallingUserId());
+ Long authenticatorId = mAuthenticatorIds.get(userId);
+ return authenticatorId != null ? authenticatorId : 0;
}
}
diff --git a/services/core/java/com/android/server/job/JobServiceContext.java b/services/core/java/com/android/server/job/JobServiceContext.java
index b089ba7..7cb223d 100644
--- a/services/core/java/com/android/server/job/JobServiceContext.java
+++ b/services/core/java/com/android/server/job/JobServiceContext.java
@@ -70,6 +70,8 @@
ActivityManager.isLowRamDeviceStatic() ? 1 : 3;
/** Amount of time a job is allowed to execute for before being considered timed-out. */
private static final long EXECUTING_TIMESLICE_MILLIS = 10 * 60 * 1000; // 10mins.
+ /** Amount of time the JobScheduler waits for the initial service launch+bind. */
+ private static final long OP_BIND_TIMEOUT_MILLIS = 18 * 1000;
/** Amount of time the JobScheduler will wait for a response from an app for a message. */
private static final long OP_TIMEOUT_MILLIS = 8 * 1000;
@@ -645,8 +647,20 @@
private void scheduleOpTimeOut() {
removeOpTimeOut();
- final long timeoutMillis = (mVerb == VERB_EXECUTING) ?
- EXECUTING_TIMESLICE_MILLIS : OP_TIMEOUT_MILLIS;
+ final long timeoutMillis;
+ switch (mVerb) {
+ case VERB_EXECUTING:
+ timeoutMillis = EXECUTING_TIMESLICE_MILLIS;
+ break;
+
+ case VERB_BINDING:
+ timeoutMillis = OP_BIND_TIMEOUT_MILLIS;
+ break;
+
+ default:
+ timeoutMillis = OP_TIMEOUT_MILLIS;
+ break;
+ }
if (DEBUG) {
Slog.d(TAG, "Scheduling time out for '" +
mRunningJob.getServiceComponent().getShortClassName() + "' jId: " +
diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java
index ede6e30..10ecb86 100644
--- a/services/core/java/com/android/server/media/MediaSessionRecord.java
+++ b/services/core/java/com/android/server/media/MediaSessionRecord.java
@@ -1123,6 +1123,38 @@
}
}
+ public void addQueueItem(MediaDescription description) {
+ try {
+ mCb.onAddQueueItem(description);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Remote failure in addQueueItem.", e);
+ }
+ }
+
+ public void addQueueItemAt(MediaDescription description, int index) {
+ try {
+ mCb.onAddQueueItemAt(description, index);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Remote failure in addQueueItemAt.", e);
+ }
+ }
+
+ public void removeQueueItem(MediaDescription description) {
+ try {
+ mCb.onRemoveQueueItem(description);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Remote failure in removeQueueItem.", e);
+ }
+ }
+
+ public void removeQueueItemAt(int index) {
+ try {
+ mCb.onRemoveQueueItemAt(index);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Remote failure in removeQueueItem.", e);
+ }
+ }
+
public void adjustVolume(int direction) {
try {
mCb.onAdjustVolume(direction);
@@ -1397,6 +1429,30 @@
}
@Override
+ public void addQueueItem(MediaDescription description) {
+ updateCallingPackage();
+ mSessionCb.addQueueItem(description);
+ }
+
+ @Override
+ public void addQueueItemAt(MediaDescription description, int index) {
+ updateCallingPackage();
+ mSessionCb.addQueueItemAt(description, index);
+ }
+
+ @Override
+ public void removeQueueItem(MediaDescription description) {
+ updateCallingPackage();
+ mSessionCb.removeQueueItem(description);
+ }
+
+ @Override
+ public void removeQueueItemAt(int index) {
+ updateCallingPackage();
+ mSessionCb.removeQueueItemAt(index);
+ }
+
+ @Override
public CharSequence getQueueTitle() {
return mQueueTitle;
}
diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java
index 3bf95ef..98177fe 100644
--- a/services/core/java/com/android/server/media/MediaSessionService.java
+++ b/services/core/java/com/android/server/media/MediaSessionService.java
@@ -155,10 +155,10 @@
}
/**
- * Tells the system UI that volume has changed on a remote session.
+ * Tells the system UI that volume has changed on an active remote session.
*/
public void notifyRemoteVolumeChanged(int flags, MediaSessionRecord session) {
- if (mRvc == null) {
+ if (mRvc == null || !session.isActive()) {
return;
}
try {
diff --git a/services/core/java/com/android/server/notification/NotificationComparator.java b/services/core/java/com/android/server/notification/NotificationComparator.java
index 6f49df4..d6c89a4 100644
--- a/services/core/java/com/android/server/notification/NotificationComparator.java
+++ b/services/core/java/com/android/server/notification/NotificationComparator.java
@@ -31,6 +31,8 @@
import android.text.TextUtils;
import android.util.ArrayMap;
+import com.android.internal.util.NotificationMessagingUtil;
+
import java.util.Comparator;
import java.util.Objects;
@@ -40,18 +42,15 @@
public class NotificationComparator
implements Comparator<NotificationRecord> {
- private final String DEFAULT_SMS_APP_SETTING = Settings.Secure.SMS_DEFAULT_APPLICATION;
-
private final Context mContext;
+ private final NotificationMessagingUtil mMessagingUtil;
private String mDefaultPhoneApp;
- private ArrayMap<Integer, String> mDefaultSmsApp = new ArrayMap<>();
public NotificationComparator(Context context) {
mContext = context;
mContext.registerReceiver(mPhoneAppBroadcastReceiver,
new IntentFilter(TelecomManager.ACTION_DEFAULT_DIALER_CHANGED));
- mContext.getContentResolver().registerContentObserver(
- Settings.Secure.getUriFor(DEFAULT_SMS_APP_SETTING), false, mSmsContentObserver);
+ mMessagingUtil = new NotificationMessagingUtil(mContext);
}
@Override
@@ -73,9 +72,15 @@
return -1 * Boolean.compare(leftImportantOngoing, rightImportantOngoing);
}
+ boolean leftMessaging = isImportantMessaging(left);
+ boolean rightMessaging = isImportantMessaging(right);
+ if (leftMessaging != rightMessaging) {
+ return -1 * Boolean.compare(leftMessaging, rightMessaging);
+ }
+
// Next: sufficiently import person to person communication
- boolean leftPeople = isImportantMessaging(left);
- boolean rightPeople = isImportantMessaging(right);
+ boolean leftPeople = isImportantPeople(left);
+ boolean rightPeople = isImportantPeople(right);
if (leftPeople && rightPeople){
// by contact proximity, close to far. if same proximity, check further fields.
@@ -128,53 +133,33 @@
if (record.getImportance() < NotificationManager.IMPORTANCE_LOW) {
return false;
}
-
// TODO: add whitelist
return isCall(record) || isMediaNotification(record);
}
- protected boolean isImportantMessaging(NotificationRecord record) {
+ protected boolean isImportantPeople(NotificationRecord record) {
if (record.getImportance() < NotificationManager.IMPORTANCE_LOW) {
return false;
}
-
- Class<? extends Notification.Style> style = getNotificationStyle(record);
- if (Notification.MessagingStyle.class.equals(style)) {
- return true;
- }
-
if (record.getContactAffinity() > ValidateNotificationPeople.NONE) {
return true;
}
-
- if (record.getNotification().category == Notification.CATEGORY_MESSAGE
- && isDefaultMessagingApp(record)) {
- return true;
- }
-
return false;
}
+ protected boolean isImportantMessaging(NotificationRecord record) {
+ return mMessagingUtil.isImportantMessaging(record.sbn, record.getImportance());
+ }
+
private boolean isOngoing(NotificationRecord record) {
final int ongoingFlags =
Notification.FLAG_FOREGROUND_SERVICE | Notification.FLAG_ONGOING_EVENT;
return (record.getNotification().flags & ongoingFlags) != 0;
}
- private Class<? extends Notification.Style> getNotificationStyle(NotificationRecord record) {
- String templateClass =
- record.getNotification().extras.getString(Notification.EXTRA_TEMPLATE);
-
- if (!TextUtils.isEmpty(templateClass)) {
- return Notification.getNotificationStyleClass(templateClass);
- }
- return null;
- }
-
private boolean isMediaNotification(NotificationRecord record) {
- return record.getNotification().extras.getParcelable(
- Notification.EXTRA_MEDIA_SESSION) != null;
+ return record.getNotification().hasMediaSession();
}
private boolean isCall(NotificationRecord record) {
@@ -191,18 +176,6 @@
return Objects.equals(pkg, mDefaultPhoneApp);
}
- @SuppressWarnings("deprecation")
- private boolean isDefaultMessagingApp(NotificationRecord record) {
- final int userId = record.getUserId();
- if (userId == UserHandle.USER_NULL || userId == UserHandle.USER_ALL) return false;
- if (mDefaultSmsApp.get(userId) == null) {
- mDefaultSmsApp.put(userId, Settings.Secure.getStringForUser(
- mContext.getContentResolver(),
- Settings.Secure.SMS_DEFAULT_APPLICATION, userId));
- }
- return Objects.equals(mDefaultSmsApp.get(userId), record.sbn.getPackageName());
- }
-
private final BroadcastReceiver mPhoneAppBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
@@ -210,17 +183,4 @@
intent.getStringExtra(TelecomManager.EXTRA_CHANGE_DEFAULT_DIALER_PACKAGE_NAME);
}
};
-
- private final ContentObserver mSmsContentObserver = new ContentObserver(
- new Handler(Looper.getMainLooper())) {
- @Override
- public void onChange(boolean selfChange, Uri uri, int userId) {
- if (Settings.Secure.getUriFor(DEFAULT_SMS_APP_SETTING).equals(uri)) {
- mDefaultSmsApp.put(userId, Settings.Secure.getStringForUser(
- mContext.getContentResolver(),
- Settings.Secure.SMS_DEFAULT_APPLICATION, userId));
-
- }
- }
- };
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 6f20f10..4207998 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -712,6 +712,7 @@
// System configuration read by SystemConfig.
final int[] mGlobalGids;
final SparseArray<ArraySet<String>> mSystemPermissions;
+ @GuardedBy("mAvailableFeatures")
final ArrayMap<String, FeatureInfo> mAvailableFeatures;
// If mac_permissions.xml was found for seinfo labeling.
@@ -832,7 +833,6 @@
private List<String> mKeepUninstalledPackages;
private UserManagerInternal mUserManagerInternal;
- private final UserDataPreparer mUserDataPreparer;
private File mCacheDir;
@@ -1936,7 +1936,7 @@
// Clean up any users or apps that were removed or recreated
// while this volume was missing
- reconcileUsers(volumeUuid);
+ sUserManager.reconcileUsers(volumeUuid);
reconcileApps(volumeUuid);
// Clean up any install sessions that expired or were
@@ -2160,19 +2160,24 @@
if (SystemProperties.getInt("ro.cp_system_other_odex", 0) == 1) {
SystemProperties.set(CP_PREOPT_PROPERTY, "requested");
// We will wait for up to 100 seconds.
- final long timeEnd = SystemClock.uptimeMillis() + 100 * 1000;
+ final long timeStart = SystemClock.uptimeMillis();
+ final long timeEnd = timeStart + 100 * 1000;
+ long timeNow = timeStart;
while (!SystemProperties.get(CP_PREOPT_PROPERTY).equals("finished")) {
try {
Thread.sleep(WAIT_TIME_MS);
} catch (InterruptedException e) {
// Do nothing
}
- if (SystemClock.uptimeMillis() > timeEnd) {
+ timeNow = SystemClock.uptimeMillis();
+ if (timeNow > timeEnd) {
SystemProperties.set(CP_PREOPT_PROPERTY, "timed-out");
Slog.wtf(TAG, "cppreopt did not finish!");
break;
}
}
+
+ Slog.i(TAG, "cppreopts took " + (timeNow - timeStart) + " ms");
}
}
@@ -2264,8 +2269,8 @@
mEphemeralInstallDir = new File(dataDir, "app-ephemeral");
mAsecInternalPath = new File(dataDir, "app-asec").getPath();
mDrmAppPrivateInstallDir = new File(dataDir, "app-private");
- mUserDataPreparer = new UserDataPreparer(mInstaller, mInstallLock, mContext, mOnlyCore);
- sUserManager = new UserManagerService(context, this, mUserDataPreparer, mPackages);
+ sUserManager = new UserManagerService(context, this,
+ new UserDataPreparer(mInstaller, mInstallLock, mContext, mOnlyCore), mPackages);
// Propagate permission configuration in to package manager.
ArrayMap<String, SystemConfig.PermissionEntry> permConfig
@@ -4215,21 +4220,22 @@
@Override
public @NonNull ParceledListSlice<FeatureInfo> getSystemAvailableFeatures() {
- synchronized (mPackages) {
- final ArrayList<FeatureInfo> res = new ArrayList<>(mAvailableFeatures.values());
-
- final FeatureInfo fi = new FeatureInfo();
- fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version",
- FeatureInfo.GL_ES_VERSION_UNDEFINED);
- res.add(fi);
-
- return new ParceledListSlice<>(res);
+ ArrayList<FeatureInfo> res;
+ synchronized (mAvailableFeatures) {
+ res = new ArrayList<>(mAvailableFeatures.size() + 1);
+ res.addAll(mAvailableFeatures.values());
}
+ final FeatureInfo fi = new FeatureInfo();
+ fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version",
+ FeatureInfo.GL_ES_VERSION_UNDEFINED);
+ res.add(fi);
+
+ return new ParceledListSlice<>(res);
}
@Override
public boolean hasSystemFeature(String name, int version) {
- synchronized (mPackages) {
+ synchronized (mAvailableFeatures) {
final FeatureInfo feat = mAvailableFeatures.get(name);
if (feat == null) {
return false;
@@ -19964,7 +19970,7 @@
});
// Now that we're mostly running, clean up stale users and apps
- reconcileUsers(StorageManager.UUID_PRIVATE_INTERNAL);
+ sUserManager.reconcileUsers(StorageManager.UUID_PRIVATE_INTERNAL);
reconcileApps(StorageManager.UUID_PRIVATE_INTERNAL);
}
@@ -20379,20 +20385,22 @@
pw.println("Features:");
}
- for (FeatureInfo feat : mAvailableFeatures.values()) {
- if (checkin) {
- pw.print("feat,");
- pw.print(feat.name);
- pw.print(",");
- pw.println(feat.version);
- } else {
- pw.print(" ");
- pw.print(feat.name);
- if (feat.version > 0) {
- pw.print(" version=");
- pw.print(feat.version);
+ synchronized (mAvailableFeatures) {
+ for (FeatureInfo feat : mAvailableFeatures.values()) {
+ if (checkin) {
+ pw.print("feat,");
+ pw.print(feat.name);
+ pw.print(",");
+ pw.println(feat.version);
+ } else {
+ pw.print(" ");
+ pw.print(feat.name);
+ if (feat.version > 0) {
+ pw.print(" version=");
+ pw.print(feat.version);
+ }
+ pw.println();
}
- pw.println();
}
}
}
@@ -21300,60 +21308,6 @@
}
}
- /**
- * Examine all users present on given mounted volume, and destroy data
- * belonging to users that are no longer valid, or whose user ID has been
- * recycled.
- */
- private void reconcileUsers(String volumeUuid) {
- final List<File> files = new ArrayList<>();
- Collections.addAll(files, FileUtils
- .listFilesOrEmpty(Environment.getDataUserDeDirectory(volumeUuid)));
- Collections.addAll(files, FileUtils
- .listFilesOrEmpty(Environment.getDataUserCeDirectory(volumeUuid)));
- Collections.addAll(files, FileUtils
- .listFilesOrEmpty(Environment.getDataSystemDeDirectory()));
- Collections.addAll(files, FileUtils
- .listFilesOrEmpty(Environment.getDataSystemCeDirectory()));
- Collections.addAll(files, FileUtils
- .listFilesOrEmpty(Environment.getDataMiscCeDirectory()));
- for (File file : files) {
- if (!file.isDirectory()) continue;
-
- final int userId;
- final UserInfo info;
- try {
- userId = Integer.parseInt(file.getName());
- info = sUserManager.getUserInfo(userId);
- } catch (NumberFormatException e) {
- Slog.w(TAG, "Invalid user directory " + file);
- continue;
- }
-
- boolean destroyUser = false;
- if (info == null) {
- logCriticalInfo(Log.WARN, "Destroying user directory " + file
- + " because no matching user was found");
- destroyUser = true;
- } else if (!mOnlyCore) {
- try {
- UserManagerService.enforceSerialNumber(file, info.serialNumber);
- } catch (IOException e) {
- logCriticalInfo(Log.WARN, "Destroying user directory " + file
- + " because we failed to enforce serial number: " + e);
- destroyUser = true;
- }
- }
-
- if (destroyUser) {
- synchronized (mInstallLock) {
- mUserDataPreparer.destroyUserDataLI(volumeUuid, userId,
- StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
- }
- }
- }
- }
-
private void assertPackageKnown(String volumeUuid, String packageName)
throws PackageManagerException {
synchronized (mPackages) {
diff --git a/services/core/java/com/android/server/pm/UserDataPreparer.java b/services/core/java/com/android/server/pm/UserDataPreparer.java
index 52599fd..fc00acc 100644
--- a/services/core/java/com/android/server/pm/UserDataPreparer.java
+++ b/services/core/java/com/android/server/pm/UserDataPreparer.java
@@ -17,13 +17,28 @@
package com.android.server.pm;
import android.content.Context;
+import android.content.pm.UserInfo;
import android.os.Environment;
import android.os.FileUtils;
import android.os.storage.StorageManager;
import android.os.storage.VolumeInfo;
+import android.system.ErrnoException;
+import android.system.Os;
+import android.system.OsConstants;
import android.util.Log;
+import android.util.Slog;
+import android.util.SparseArray;
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
import java.util.Objects;
+import java.util.Set;
import static com.android.server.pm.PackageManagerService.logCriticalInfo;
@@ -31,6 +46,9 @@
* Helper class for preparing and destroying user storage
*/
class UserDataPreparer {
+ private static final String TAG = "UserDataPreparer";
+ private static final String XATTR_SERIAL = "user.serial";
+
private final Object mInstallLock;
private final Context mContext;
private final boolean mOnlyCore;
@@ -65,19 +83,15 @@
storage.prepareUserStorage(volumeUuid, userId, userSerial, flags);
if ((flags & StorageManager.FLAG_STORAGE_DE) != 0 && !mOnlyCore) {
- UserManagerService.enforceSerialNumber(
- Environment.getDataUserDeDirectory(volumeUuid, userId), userSerial);
+ enforceSerialNumber(getDataUserDeDirectory(volumeUuid, userId), userSerial);
if (Objects.equals(volumeUuid, StorageManager.UUID_PRIVATE_INTERNAL)) {
- UserManagerService.enforceSerialNumber(
- Environment.getDataSystemDeDirectory(userId), userSerial);
+ enforceSerialNumber(getDataSystemDeDirectory(userId), userSerial);
}
}
if ((flags & StorageManager.FLAG_STORAGE_CE) != 0 && !mOnlyCore) {
- UserManagerService.enforceSerialNumber(
- Environment.getDataUserCeDirectory(volumeUuid, userId), userSerial);
+ enforceSerialNumber(getDataUserCeDirectory(volumeUuid, userId), userSerial);
if (Objects.equals(volumeUuid, StorageManager.UUID_PRIVATE_INTERNAL)) {
- UserManagerService.enforceSerialNumber(
- Environment.getDataSystemCeDirectory(userId), userSerial);
+ enforceSerialNumber(getDataSystemCeDirectory(userId), userSerial);
}
}
@@ -117,13 +131,13 @@
// Clean up system data
if (Objects.equals(volumeUuid, StorageManager.UUID_PRIVATE_INTERNAL)) {
if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) {
- FileUtils.deleteContentsAndDir(Environment.getUserSystemDirectory(userId));
- FileUtils.deleteContentsAndDir(Environment.getDataSystemDeDirectory(userId));
- FileUtils.deleteContentsAndDir(Environment.getDataMiscDeDirectory(userId));
+ FileUtils.deleteContentsAndDir(getUserSystemDirectory(userId));
+ FileUtils.deleteContentsAndDir(getDataSystemDeDirectory(userId));
+ FileUtils.deleteContentsAndDir(getDataMiscDeDirectory(userId));
}
if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
- FileUtils.deleteContentsAndDir(Environment.getDataSystemCeDirectory(userId));
- FileUtils.deleteContentsAndDir(Environment.getDataMiscCeDirectory(userId));
+ FileUtils.deleteContentsAndDir(getDataSystemCeDirectory(userId));
+ FileUtils.deleteContentsAndDir(getDataMiscCeDirectory(userId));
}
}
@@ -136,4 +150,183 @@
}
}
+ /**
+ * Examine all users present on given mounted volume, and destroy data
+ * belonging to users that are no longer valid, or whose user ID has been
+ * recycled.
+ */
+ void reconcileUsers(String volumeUuid, List<UserInfo> validUsersList) {
+ final List<File> files = new ArrayList<>();
+ Collections.addAll(files, FileUtils
+ .listFilesOrEmpty(Environment.getDataUserDeDirectory(volumeUuid)));
+ Collections.addAll(files, FileUtils
+ .listFilesOrEmpty(Environment.getDataUserCeDirectory(volumeUuid)));
+ Collections.addAll(files, FileUtils
+ .listFilesOrEmpty(Environment.getDataSystemDeDirectory()));
+ Collections.addAll(files, FileUtils
+ .listFilesOrEmpty(Environment.getDataSystemCeDirectory()));
+ Collections.addAll(files, FileUtils
+ .listFilesOrEmpty(Environment.getDataMiscCeDirectory()));
+ reconcileUsers(volumeUuid, validUsersList, files);
+ }
+
+ @VisibleForTesting
+ void reconcileUsers(String volumeUuid, List<UserInfo> validUsersList, List<File> files) {
+ final int userCount = validUsersList.size();
+ SparseArray<UserInfo> users = new SparseArray<>(userCount);
+ for (int i = 0; i < userCount; i++) {
+ UserInfo user = validUsersList.get(i);
+ users.put(user.id, user);
+ }
+ for (File file : files) {
+ if (!file.isDirectory()) {
+ continue;
+ }
+
+ final int userId;
+ final UserInfo info;
+ try {
+ userId = Integer.parseInt(file.getName());
+ info = users.get(userId);
+ } catch (NumberFormatException e) {
+ Slog.w(TAG, "Invalid user directory " + file);
+ continue;
+ }
+
+ boolean destroyUser = false;
+ if (info == null) {
+ logCriticalInfo(Log.WARN, "Destroying user directory " + file
+ + " because no matching user was found");
+ destroyUser = true;
+ } else if (!mOnlyCore) {
+ try {
+ enforceSerialNumber(file, info.serialNumber);
+ } catch (IOException e) {
+ logCriticalInfo(Log.WARN, "Destroying user directory " + file
+ + " because we failed to enforce serial number: " + e);
+ destroyUser = true;
+ }
+ }
+
+ if (destroyUser) {
+ synchronized (mInstallLock) {
+ destroyUserDataLI(volumeUuid, userId,
+ StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
+ }
+ }
+ }
+ }
+
+ @VisibleForTesting
+ protected File getDataMiscCeDirectory(int userId) {
+ return Environment.getDataMiscCeDirectory(userId);
+ }
+
+ @VisibleForTesting
+ protected File getDataSystemCeDirectory(int userId) {
+ return Environment.getDataSystemCeDirectory(userId);
+ }
+
+ @VisibleForTesting
+ protected File getDataMiscDeDirectory(int userId) {
+ return Environment.getDataMiscDeDirectory(userId);
+ }
+
+ @VisibleForTesting
+ protected File getUserSystemDirectory(int userId) {
+ return Environment.getUserSystemDirectory(userId);
+ }
+
+ @VisibleForTesting
+ protected File getDataUserCeDirectory(String volumeUuid, int userId) {
+ return Environment.getDataUserCeDirectory(volumeUuid, userId);
+ }
+
+ @VisibleForTesting
+ protected File getDataSystemDeDirectory(int userId) {
+ return Environment.getDataSystemDeDirectory(userId);
+ }
+
+ @VisibleForTesting
+ protected File getDataUserDeDirectory(String volumeUuid, int userId) {
+ return Environment.getDataUserDeDirectory(volumeUuid, userId);
+ }
+
+ @VisibleForTesting
+ protected boolean isFileEncryptedEmulatedOnly() {
+ return StorageManager.isFileEncryptedEmulatedOnly();
+ }
+
+ /**
+ * Enforce that serial number stored in user directory inode matches the
+ * given expected value. Gracefully sets the serial number if currently
+ * undefined.
+ *
+ * @throws IOException when problem extracting serial number, or serial
+ * number is mismatched.
+ */
+ void enforceSerialNumber(File file, int serialNumber) throws IOException {
+ if (isFileEncryptedEmulatedOnly()) {
+ // When we're emulating FBE, the directory may have been chmod
+ // 000'ed, meaning we can't read the serial number to enforce it;
+ // instead of destroying the user, just log a warning.
+ Slog.w(TAG, "Device is emulating FBE; assuming current serial number is valid");
+ return;
+ }
+
+ final int foundSerial = getSerialNumber(file);
+ Slog.v(TAG, "Found " + file + " with serial number " + foundSerial);
+
+ if (foundSerial == -1) {
+ Slog.d(TAG, "Serial number missing on " + file + "; assuming current is valid");
+ try {
+ setSerialNumber(file, serialNumber);
+ } catch (IOException e) {
+ Slog.w(TAG, "Failed to set serial number on " + file, e);
+ }
+
+ } else if (foundSerial != serialNumber) {
+ throw new IOException("Found serial number " + foundSerial
+ + " doesn't match expected " + serialNumber);
+ }
+ }
+
+ /**
+ * Set serial number stored in user directory inode.
+ *
+ * @throws IOException if serial number was already set
+ */
+ private static void setSerialNumber(File file, int serialNumber) throws IOException {
+ try {
+ final byte[] buf = Integer.toString(serialNumber).getBytes(StandardCharsets.UTF_8);
+ Os.setxattr(file.getAbsolutePath(), XATTR_SERIAL, buf, OsConstants.XATTR_CREATE);
+ } catch (ErrnoException e) {
+ throw e.rethrowAsIOException();
+ }
+ }
+
+ /**
+ * Return serial number stored in user directory inode.
+ *
+ * @return parsed serial number, or -1 if not set
+ */
+ @VisibleForTesting
+ static int getSerialNumber(File file) throws IOException {
+ try {
+ final byte[] buf = Os.getxattr(file.getAbsolutePath(), XATTR_SERIAL);
+ final String serial = new String(buf);
+ try {
+ return Integer.parseInt(serial);
+ } catch (NumberFormatException e) {
+ throw new IOException("Bad serial number: " + serial);
+ }
+ } catch (ErrnoException e) {
+ if (e.errno == OsConstants.ENODATA) {
+ return -1;
+ } else {
+ throw e.rethrowAsIOException();
+ }
+ }
+ }
+
}
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 455d3e4..627fa54 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -218,8 +218,6 @@
static final int WRITE_USER_MSG = 1;
static final int WRITE_USER_DELAY = 2*1000; // 2 seconds
- private static final String XATTR_SERIAL = "user.serial";
-
// Tron counters
private static final String TRON_GUEST_CREATED = "users_guest_created";
private static final String TRON_USER_CREATED = "users_user_created";
@@ -3159,6 +3157,15 @@
}
/**
+ * Examine all users present on given mounted volume, and destroy data
+ * belonging to users that are no longer valid, or whose user ID has been
+ * recycled.
+ */
+ void reconcileUsers(String volumeUuid) {
+ mUserDataPreparer.reconcileUsers(volumeUuid, getUsers(true /* excludeDying */));
+ }
+
+ /**
* Make a note of the last started time of a user and do some cleanup.
* This is called with ActivityManagerService lock held.
* @param userId the user that was just foregrounded
@@ -3219,78 +3226,6 @@
return RESTRICTIONS_FILE_PREFIX + packageName + XML_SUFFIX;
}
- /**
- * Enforce that serial number stored in user directory inode matches the
- * given expected value. Gracefully sets the serial number if currently
- * undefined.
- *
- * @throws IOException when problem extracting serial number, or serial
- * number is mismatched.
- */
- public static void enforceSerialNumber(File file, int serialNumber) throws IOException {
- if (StorageManager.isFileEncryptedEmulatedOnly()) {
- // When we're emulating FBE, the directory may have been chmod
- // 000'ed, meaning we can't read the serial number to enforce it;
- // instead of destroying the user, just log a warning.
- Slog.w(LOG_TAG, "Device is emulating FBE; assuming current serial number is valid");
- return;
- }
-
- final int foundSerial = getSerialNumber(file);
- Slog.v(LOG_TAG, "Found " + file + " with serial number " + foundSerial);
-
- if (foundSerial == -1) {
- Slog.d(LOG_TAG, "Serial number missing on " + file + "; assuming current is valid");
- try {
- setSerialNumber(file, serialNumber);
- } catch (IOException e) {
- Slog.w(LOG_TAG, "Failed to set serial number on " + file, e);
- }
-
- } else if (foundSerial != serialNumber) {
- throw new IOException("Found serial number " + foundSerial
- + " doesn't match expected " + serialNumber);
- }
- }
-
- /**
- * Set serial number stored in user directory inode.
- *
- * @throws IOException if serial number was already set
- */
- private static void setSerialNumber(File file, int serialNumber)
- throws IOException {
- try {
- final byte[] buf = Integer.toString(serialNumber).getBytes(StandardCharsets.UTF_8);
- Os.setxattr(file.getAbsolutePath(), XATTR_SERIAL, buf, OsConstants.XATTR_CREATE);
- } catch (ErrnoException e) {
- throw e.rethrowAsIOException();
- }
- }
-
- /**
- * Return serial number stored in user directory inode.
- *
- * @return parsed serial number, or -1 if not set
- */
- private static int getSerialNumber(File file) throws IOException {
- try {
- final byte[] buf = Os.getxattr(file.getAbsolutePath(), XATTR_SERIAL);
- final String serial = new String(buf);
- try {
- return Integer.parseInt(serial);
- } catch (NumberFormatException e) {
- throw new IOException("Bad serial number: " + serial);
- }
- } catch (ErrnoException e) {
- if (e.errno == OsConstants.ENODATA) {
- return -1;
- } else {
- throw e.rethrowAsIOException();
- }
- }
- }
-
@Override
public void setSeedAccountData(int userId, String accountName, String accountType,
PersistableBundle accountOptions, boolean persist) {
diff --git a/services/core/java/com/android/server/policy/BarController.java b/services/core/java/com/android/server/policy/BarController.java
index 6edb4d2..7a28081 100644
--- a/services/core/java/com/android/server/policy/BarController.java
+++ b/services/core/java/com/android/server/policy/BarController.java
@@ -18,6 +18,7 @@
import android.app.StatusBarManager;
import android.os.Handler;
+import android.os.Message;
import android.os.SystemClock;
import android.util.Slog;
import android.view.View;
@@ -43,6 +44,8 @@
private static final int TRANSLUCENT_ANIMATION_DELAY_MS = 1000;
+ private static final int MSG_NAV_BAR_VISIBILITY_CHANGED = 1;
+
protected final String mTag;
private final int mTransientFlag;
private final int mUnhideFlag;
@@ -63,6 +66,8 @@
private boolean mSetUnHideFlagWhenNextTransparent;
private boolean mNoAnimationOnNextShow;
+ private OnBarVisibilityChangedListener mVisibilityChangeListener;
+
public BarController(String tag, int transientFlag, int unhideFlag, int translucentFlag,
int statusBarManagerId, int translucentWmFlag, int transparentFlag) {
mTag = "BarController." + tag;
@@ -72,7 +77,7 @@
mStatusBarManagerId = statusBarManagerId;
mTranslucentWmFlag = translucentWmFlag;
mTransparentFlag = transparentFlag;
- mHandler = new Handler();
+ mHandler = new BarHandler();
}
public void setWindow(WindowState win) {
@@ -153,9 +158,18 @@
mNoAnimationOnNextShow = false;
final int state = computeStateLw(wasVis, wasAnim, mWin, change);
final boolean stateChanged = updateStateLw(state);
+
+ if (change && (mVisibilityChangeListener != null)) {
+ mHandler.obtainMessage(MSG_NAV_BAR_VISIBILITY_CHANGED, show ? 1 : 0, 0).sendToTarget();
+ }
+
return change || stateChanged;
}
+ void setOnBarVisibilityChangedListener(OnBarVisibilityChangedListener listener) {
+ mVisibilityChangeListener = listener;
+ }
+
protected boolean skipAnimation() {
return false;
}
@@ -300,4 +314,22 @@
pw.println(transientBarStateToString(mTransientBarState));
}
}
+
+ private class BarHandler extends Handler {
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MSG_NAV_BAR_VISIBILITY_CHANGED:
+ final boolean visible = msg.arg1 != 0;
+ if (mVisibilityChangeListener != null) {
+ mVisibilityChangeListener.onBarVisibilityChanged(visible);
+ }
+ break;
+ }
+ }
+ }
+
+ interface OnBarVisibilityChangedListener {
+ void onBarVisibilityChanged(boolean visible);
+ }
}
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 37fff68..c795676 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -16,17 +16,24 @@
package com.android.server.policy;
+import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
+import static android.Manifest.permission.SYSTEM_ALERT_WINDOW;
import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
import static android.app.ActivityManager.StackId.HOME_STACK_ID;
+import static android.app.AppOpsManager.OP_SYSTEM_ALERT_WINDOW;
+import static android.app.AppOpsManager.OP_TOAST_WINDOW;
import static android.content.Context.DISPLAY_SERVICE;
import static android.content.Context.WINDOW_SERVICE;
import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
import static android.content.pm.PackageManager.FEATURE_TELEVISION;
import static android.content.pm.PackageManager.FEATURE_WATCH;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.content.res.Configuration.EMPTY;
import static android.content.res.Configuration.UI_MODE_TYPE_CAR;
import static android.content.res.Configuration.UI_MODE_TYPE_MASK;
+import static android.os.Build.VERSION_CODES.M;
+import static android.os.Build.VERSION_CODES.O;
import static android.view.WindowManager.DOCKED_LEFT;
import static android.view.WindowManager.DOCKED_RIGHT;
import static android.view.WindowManager.DOCKED_TOP;
@@ -63,21 +70,14 @@
import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
import static android.view.WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST;
import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY;
-import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ABOVE_SUB_PANEL;
-import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
-import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA;
-import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY;
-import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_PANEL;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
-import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
import static android.view.WindowManager.LayoutParams.TYPE_BOOT_PROGRESS;
import static android.view.WindowManager.LayoutParams.TYPE_DISPLAY_OVERLAY;
import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
-import static android.view.WindowManager.LayoutParams.TYPE_DRAG;
import static android.view.WindowManager.LayoutParams.TYPE_DREAM;
import static android.view.WindowManager.LayoutParams.TYPE_INPUT_CONSUMER;
import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
-import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG;
import static android.view.WindowManager.LayoutParams.TYPE_MAGNIFICATION_OVERLAY;
import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
@@ -103,8 +103,11 @@
import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION_STARTING;
import static android.view.WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY;
import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
+import static android.view.WindowManager.LayoutParams.isSystemAlertWindowType;
import static android.view.WindowManager.TAKE_SCREENSHOT_FULLSCREEN;
import static android.view.WindowManager.TAKE_SCREENSHOT_SELECTED_REGION;
+import static android.view.WindowManagerGlobal.ADD_OKAY;
+import static android.view.WindowManagerGlobal.ADD_PERMISSION_DENIED;
import static android.view.WindowManagerPolicy.WindowManagerFuncs.CAMERA_LENS_COVERED;
import static android.view.WindowManagerPolicy.WindowManagerFuncs.CAMERA_LENS_COVER_ABSENT;
import static android.view.WindowManagerPolicy.WindowManagerFuncs.CAMERA_LENS_UNCOVERED;
@@ -156,7 +159,6 @@
import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
-import android.os.Debug;
import android.os.FactoryTest;
import android.os.Handler;
import android.os.IBinder;
@@ -314,12 +316,6 @@
// Nav bar is always translucent when the freeform stack is visible, otherwise always opaque.
static final int NAV_BAR_TRANSLUCENT_WHEN_FREEFORM_OPAQUE_OTHERWISE = 1;
- static final int APPLICATION_MEDIA_SUBLAYER = -2;
- static final int APPLICATION_MEDIA_OVERLAY_SUBLAYER = -1;
- static final int APPLICATION_PANEL_SUBLAYER = 1;
- static final int APPLICATION_SUB_PANEL_SUBLAYER = 2;
- static final int APPLICATION_ABOVE_SUB_PANEL_SUBLAYER = 3;
-
static public final String SYSTEM_DIALOG_REASON_KEY = "reason";
static public final String SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS = "globalactions";
static public final String SYSTEM_DIALOG_REASON_RECENT_APPS = "recentapps";
@@ -994,6 +990,14 @@
WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION,
View.NAVIGATION_BAR_TRANSPARENT);
+ private final BarController.OnBarVisibilityChangedListener mNavBarVisibilityListener =
+ new BarController.OnBarVisibilityChangedListener() {
+ @Override
+ public void onBarVisibilityChanged(boolean visible) {
+ mAccessibilityManager.notifyAccessibilityButtonAvailabilityChanged(visible);
+ }
+ };
+
private ImmersiveModeConfirmation mImmersiveModeConfirmation;
private SystemGesturesPointerEventListener mSystemGestures;
@@ -2315,86 +2319,82 @@
if (type < FIRST_SYSTEM_WINDOW || type > LAST_SYSTEM_WINDOW) {
// Window manager will make sure these are okay.
- return WindowManagerGlobal.ADD_OKAY;
+ return ADD_OKAY;
}
- String permission = null;
- switch (type) {
- case TYPE_TOAST:
- // XXX right now the app process has complete control over
- // this... should introduce a token to let the system
- // monitor/control what they are doing.
- outAppOp[0] = AppOpsManager.OP_TOAST_WINDOW;
- break;
- case TYPE_DREAM:
- case TYPE_INPUT_METHOD:
- case TYPE_WALLPAPER:
- case TYPE_PRESENTATION:
- case TYPE_PRIVATE_PRESENTATION:
- case TYPE_VOICE_INTERACTION:
- case TYPE_ACCESSIBILITY_OVERLAY:
- case TYPE_QS_DIALOG:
- // The window manager will check these.
- break;
- case TYPE_PHONE:
- case TYPE_PRIORITY_PHONE:
- case TYPE_SYSTEM_ALERT:
- case TYPE_SYSTEM_ERROR:
- case TYPE_SYSTEM_OVERLAY:
- permission = android.Manifest.permission.SYSTEM_ALERT_WINDOW;
- outAppOp[0] = AppOpsManager.OP_SYSTEM_ALERT_WINDOW;
- break;
+
+ if (!isSystemAlertWindowType(type)) {
+ switch (type) {
+ case TYPE_TOAST:
+ // Only apps that target older than O SDK can add window without a token, after
+ // that we require a token so apps cannot add toasts directly as the token is
+ // added by the notification system.
+ // Window manager does the checking for this.
+ outAppOp[0] = OP_TOAST_WINDOW;
+ return ADD_OKAY;
+ case TYPE_DREAM:
+ case TYPE_INPUT_METHOD:
+ case TYPE_WALLPAPER:
+ case TYPE_PRESENTATION:
+ case TYPE_PRIVATE_PRESENTATION:
+ case TYPE_VOICE_INTERACTION:
+ case TYPE_ACCESSIBILITY_OVERLAY:
+ case TYPE_QS_DIALOG:
+ // The window manager will check these.
+ return ADD_OKAY;
+ }
+ return mContext.checkCallingOrSelfPermission(INTERNAL_SYSTEM_WINDOW)
+ == PERMISSION_GRANTED ? ADD_OKAY : ADD_PERMISSION_DENIED;
+ }
+
+ // Things get a little more interesting for alert windows...
+ outAppOp[0] = OP_SYSTEM_ALERT_WINDOW;
+
+ final int callingUid = Binder.getCallingUid();
+ // system processes will be automatically granted privilege to draw
+ if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
+ return ADD_OKAY;
+ }
+
+ ApplicationInfo appInfo;
+ try {
+ appInfo = mContext.getPackageManager().getApplicationInfo(attrs.packageName,
+ UserHandle.getUserId(callingUid));
+ } catch (PackageManager.NameNotFoundException e) {
+ appInfo = null;
+ }
+
+ if (appInfo == null || (type != TYPE_APPLICATION_OVERLAY && appInfo.targetSdkVersion >= O)) {
+ /**
+ * Apps targeting >= {@link Build.VERSION_CODES#O} are required to hold
+ * {@link android.Manifest.permission#INTERNAL_SYSTEM_WINDOW} (system signature apps)
+ * permission to add alert windows that aren't
+ * {@link android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY}.
+ */
+ return (mContext.checkCallingPermission(INTERNAL_SYSTEM_WINDOW) == PERMISSION_GRANTED)
+ ? ADD_OKAY : ADD_PERMISSION_DENIED;
+ }
+
+ // check if user has enabled this operation. SecurityException will be thrown if this app
+ // has not been allowed by the user
+ final int mode = mAppOpsManager.checkOpNoThrow(outAppOp[0], callingUid, attrs.packageName);
+ switch (mode) {
+ case AppOpsManager.MODE_ALLOWED:
+ case AppOpsManager.MODE_IGNORED:
+ // although we return ADD_OKAY for MODE_IGNORED, the added window will
+ // actually be hidden in WindowManagerService
+ return ADD_OKAY;
+ case AppOpsManager.MODE_ERRORED:
+ // Don't crash legacy apps
+ if (appInfo.targetSdkVersion < M) {
+ return ADD_OKAY;
+ }
+ return ADD_PERMISSION_DENIED;
default:
- permission = android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
+ // in the default mode, we will make a decision here based on
+ // checkCallingPermission()
+ return (mContext.checkCallingPermission(SYSTEM_ALERT_WINDOW) == PERMISSION_GRANTED)
+ ? ADD_OKAY : ADD_PERMISSION_DENIED;
}
- if (permission != null) {
- if (android.Manifest.permission.SYSTEM_ALERT_WINDOW.equals(permission)) {
- final int callingUid = Binder.getCallingUid();
- // system processes will be automatically allowed privilege to draw
- if (callingUid == Process.SYSTEM_UID) {
- return WindowManagerGlobal.ADD_OKAY;
- }
-
- // check if user has enabled this operation. SecurityException will be thrown if
- // this app has not been allowed by the user
- final int mode = mAppOpsManager.checkOpNoThrow(outAppOp[0], callingUid,
- attrs.packageName);
- switch (mode) {
- case AppOpsManager.MODE_ALLOWED:
- case AppOpsManager.MODE_IGNORED:
- // although we return ADD_OKAY for MODE_IGNORED, the added window will
- // actually be hidden in WindowManagerService
- return WindowManagerGlobal.ADD_OKAY;
- case AppOpsManager.MODE_ERRORED:
- try {
- ApplicationInfo appInfo = mContext.getPackageManager()
- .getApplicationInfo(attrs.packageName,
- UserHandle.getUserId(callingUid));
- // Don't crash legacy apps
- if (appInfo.targetSdkVersion < Build.VERSION_CODES.M) {
- return WindowManagerGlobal.ADD_OKAY;
- }
- } catch (PackageManager.NameNotFoundException e) {
- /* ignore */
- }
- return WindowManagerGlobal.ADD_PERMISSION_DENIED;
- default:
- // in the default mode, we will make a decision here based on
- // checkCallingPermission()
- if (mContext.checkCallingPermission(permission) !=
- PackageManager.PERMISSION_GRANTED) {
- return WindowManagerGlobal.ADD_PERMISSION_DENIED;
- } else {
- return WindowManagerGlobal.ADD_OKAY;
- }
- }
- }
-
- if (mContext.checkCallingOrSelfPermission(permission)
- != PackageManager.PERMISSION_GRANTED) {
- return WindowManagerGlobal.ADD_PERMISSION_DENIED;
- }
- }
- return WindowManagerGlobal.ADD_OKAY;
}
@Override
@@ -2440,9 +2440,7 @@
}
// Check if third party app has set window to system window type.
- return mContext.checkCallingOrSelfPermission(
- android.Manifest.permission.INTERNAL_SYSTEM_WINDOW)
- != PackageManager.PERMISSION_GRANTED;
+ return mContext.checkCallingOrSelfPermission(INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED;
}
@Override
@@ -2591,130 +2589,9 @@
}
}
- /** {@inheritDoc} */
- @Override
- public int windowTypeToLayerLw(int type) {
- if (type >= FIRST_APPLICATION_WINDOW && type <= LAST_APPLICATION_WINDOW) {
- return 2;
- }
- switch (type) {
- case TYPE_WALLPAPER:
- // wallpaper is at the bottom, though the window manager may move it.
- return 1;
- case TYPE_PRESENTATION:
- case TYPE_PRIVATE_PRESENTATION:
- return 2;
- case TYPE_DOCK_DIVIDER:
- return 2;
- case TYPE_QS_DIALOG:
- return 2;
- case TYPE_PHONE:
- return 3;
- case TYPE_SEARCH_BAR:
- case TYPE_VOICE_INTERACTION_STARTING:
- return 4;
- case TYPE_VOICE_INTERACTION:
- // voice interaction layer is almost immediately above apps.
- return 5;
- case TYPE_INPUT_CONSUMER:
- return 6;
- case TYPE_SYSTEM_DIALOG:
- return 7;
- case TYPE_TOAST:
- // toasts and the plugged-in battery thing
- return 8;
- case TYPE_PRIORITY_PHONE:
- // SIM errors and unlock. Not sure if this really should be in a high layer.
- return 9;
- case TYPE_DREAM:
- // used for Dreams (screensavers with TYPE_DREAM windows)
- return 10;
- case TYPE_SYSTEM_ALERT:
- // like the ANR / app crashed dialogs
- return 11;
- case TYPE_INPUT_METHOD:
- // on-screen keyboards and other such input method user interfaces go here.
- return 12;
- case TYPE_INPUT_METHOD_DIALOG:
- // on-screen keyboards and other such input method user interfaces go here.
- return 13;
- case TYPE_STATUS_BAR_SUB_PANEL:
- return 15;
- case TYPE_STATUS_BAR:
- return 16;
- case TYPE_STATUS_BAR_PANEL:
- return 17;
- case TYPE_KEYGUARD_DIALOG:
- return 18;
- case TYPE_VOLUME_OVERLAY:
- // the on-screen volume indicator and controller shown when the user
- // changes the device volume
- return 19;
- case TYPE_SYSTEM_OVERLAY:
- // the on-screen volume indicator and controller shown when the user
- // changes the device volume
- return 20;
- case TYPE_NAVIGATION_BAR:
- // the navigation bar, if available, shows atop most things
- return 21;
- case TYPE_NAVIGATION_BAR_PANEL:
- // some panels (e.g. search) need to show on top of the navigation bar
- return 22;
- case TYPE_SCREENSHOT:
- // screenshot selection layer shouldn't go above system error, but it should cover
- // navigation bars at the very least.
- return 23;
- case TYPE_SYSTEM_ERROR:
- // system-level error dialogs
- return 24;
- case TYPE_MAGNIFICATION_OVERLAY:
- // used to highlight the magnified portion of a display
- return 25;
- case TYPE_DISPLAY_OVERLAY:
- // used to simulate secondary display devices
- return 26;
- case TYPE_DRAG:
- // the drag layer: input for drag-and-drop is associated with this window,
- // which sits above all other focusable windows
- return 27;
- case TYPE_ACCESSIBILITY_OVERLAY:
- // overlay put by accessibility services to intercept user interaction
- return 28;
- case TYPE_SECURE_SYSTEM_OVERLAY:
- return 29;
- case TYPE_BOOT_PROGRESS:
- return 30;
- case TYPE_POINTER:
- // the (mouse) pointer layer
- return 31;
- }
- Log.e(TAG, "Unknown window type: " + type);
- return 2;
- }
-
- /** {@inheritDoc} */
- @Override
- public int subWindowTypeToLayerLw(int type) {
- switch (type) {
- case TYPE_APPLICATION_PANEL:
- case TYPE_APPLICATION_ATTACHED_DIALOG:
- return APPLICATION_PANEL_SUBLAYER;
- case TYPE_APPLICATION_MEDIA:
- return APPLICATION_MEDIA_SUBLAYER;
- case TYPE_APPLICATION_MEDIA_OVERLAY:
- return APPLICATION_MEDIA_OVERLAY_SUBLAYER;
- case TYPE_APPLICATION_SUB_PANEL:
- return APPLICATION_SUB_PANEL_SUBLAYER;
- case TYPE_APPLICATION_ABOVE_SUB_PANEL:
- return APPLICATION_ABOVE_SUB_PANEL_SUBLAYER;
- }
- Log.e(TAG, "Unknown sub-window type: " + type);
- return 0;
- }
-
@Override
public int getMaxWallpaperLayer() {
- return windowTypeToLayerLw(TYPE_STATUS_BAR);
+ return getWindowLayerFromTypeLw(TYPE_STATUS_BAR);
}
private int getNavigationBarWidth(int rotation, int uiMode) {
@@ -2797,8 +2674,7 @@
return false;
default:
// Hide only windows below the keyguard host window.
- return windowTypeToLayerLw(win.getBaseType())
- < windowTypeToLayerLw(TYPE_STATUS_BAR);
+ return getWindowLayerLw(win) < getWindowLayerFromTypeLw(TYPE_STATUS_BAR);
}
}
@@ -3032,6 +2908,8 @@
}
mNavigationBar = win;
mNavigationBarController.setWindow(win);
+ mNavigationBarController.setOnBarVisibilityChangedListener(
+ mNavBarVisibilityListener);
if (DEBUG_LAYOUT) Slog.i(TAG, "NAVIGATION BAR: " + mNavigationBar);
break;
case TYPE_NAVIGATION_BAR_PANEL:
@@ -3043,7 +2921,7 @@
"PhoneWindowManager");
break;
}
- return WindowManagerGlobal.ADD_OKAY;
+ return ADD_OKAY;
}
/** {@inheritDoc} */
@@ -7837,8 +7715,8 @@
immersiveSticky = (vis & View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY) != 0;
final boolean navAllowedHidden = immersive || immersiveSticky;
- if (hideNavBarSysui && !navAllowedHidden && windowTypeToLayerLw(win.getBaseType())
- > windowTypeToLayerLw(TYPE_INPUT_CONSUMER)) {
+ if (hideNavBarSysui && !navAllowedHidden
+ && getWindowLayerLw(win) > getWindowLayerFromTypeLw(TYPE_INPUT_CONSUMER)) {
// We can't hide the navbar from this window otherwise the input consumer would not get
// the input events.
vis = (vis & ~View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index 238866a..91a5f4f 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -517,9 +517,6 @@
private final ArrayList<PowerManagerInternal.LowPowerModeListener> mLowPowerModeListeners
= new ArrayList<PowerManagerInternal.LowPowerModeListener>();
- // True if brightness should be affected by twilight.
- private boolean mBrightnessUseTwilight;
-
// True if we are currently in VR Mode.
private boolean mIsVrModeEnabled;
@@ -735,9 +732,6 @@
resolver.registerContentObserver(Settings.Secure.getUriFor(
Settings.Secure.DOUBLE_TAP_TO_WAKE),
false, mSettingsObserver, UserHandle.USER_ALL);
- resolver.registerContentObserver(Settings.Secure.getUriFor(
- Secure.BRIGHTNESS_USE_TWILIGHT),
- false, mSettingsObserver, UserHandle.USER_ALL);
IVrManager vrManager =
(IVrManager) getBinderService(VrManagerService.VR_MANAGER_BINDER_SERVICE);
if (vrManager != null) {
@@ -878,9 +872,6 @@
Settings.System.SCREEN_BRIGHTNESS_MODE,
Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL, UserHandle.USER_CURRENT);
- mBrightnessUseTwilight = Settings.Secure.getIntForUser(resolver,
- Secure.BRIGHTNESS_USE_TWILIGHT, 0, UserHandle.USER_CURRENT) != 0;
-
final boolean lowPowerModeEnabled = Settings.Global.getInt(resolver,
Settings.Global.LOW_POWER_MODE, 0) != 0;
final boolean autoLowPowerModeConfigured = Settings.Global.getInt(resolver,
@@ -2254,7 +2245,6 @@
mDisplayPowerRequest.useProximitySensor = shouldUseProximitySensorLocked();
mDisplayPowerRequest.lowPowerMode = mLowPowerModeEnabled;
mDisplayPowerRequest.boostScreenBrightness = shouldBoostScreenBrightness();
- mDisplayPowerRequest.useTwilight = mBrightnessUseTwilight;
if (mDisplayPowerRequest.policy == DisplayPowerRequest.POLICY_DOZE) {
mDisplayPowerRequest.dozeScreenState = mDozeScreenStateOverrideFromDreamManager;
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java b/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
index fb0dd2a..b4467af 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
@@ -23,9 +23,6 @@
public interface StatusBarManagerInternal {
void setNotificationDelegate(NotificationDelegate delegate);
- void buzzBeepBlinked();
- void notificationLightPulse(int argb, int onMillis, int offMillis);
- void notificationLightOff();
void showScreenPinningRequest(int taskId);
void showAssistDisclosure();
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index 7b7db0e..2dfe20a8 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -120,40 +120,6 @@
}
@Override
- public void buzzBeepBlinked() {
- if (mBar != null) {
- try {
- mBar.buzzBeepBlinked();
- } catch (RemoteException ex) {
- }
- }
- }
-
- @Override
- public void notificationLightPulse(int argb, int onMillis, int offMillis) {
- mNotificationLightOn = true;
- if (mBar != null) {
- try {
- mBar.notificationLightPulse(argb, onMillis, offMillis);
- } catch (RemoteException ex) {
- }
- }
- }
-
- @Override
- public void notificationLightOff() {
- if (mNotificationLightOn) {
- mNotificationLightOn = false;
- if (mBar != null) {
- try {
- mBar.notificationLightOff();
- } catch (RemoteException ex) {
- }
- }
- }
- }
-
- @Override
public void showScreenPinningRequest(int taskId) {
if (mBar != null) {
try {
diff --git a/services/core/java/com/android/server/tv/TvInputManagerService.java b/services/core/java/com/android/server/tv/TvInputManagerService.java
index 8cc53f0..e026130 100644
--- a/services/core/java/com/android/server/tv/TvInputManagerService.java
+++ b/services/core/java/com/android/server/tv/TvInputManagerService.java
@@ -23,15 +23,12 @@
import android.app.ActivityManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
-import android.content.ContentProviderOperation;
-import android.content.ContentProviderResult;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
-import android.content.OperationApplicationException;
import android.content.ServiceConnection;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
@@ -84,12 +81,9 @@
import com.android.server.IoThread;
import com.android.server.SystemService;
-import org.xmlpull.v1.XmlPullParserException;
-
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileNotFoundException;
-import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
@@ -241,44 +235,6 @@
// the update can be handled in {@link #onSomePackagesChanged}.
return true;
}
-
- @Override
- public void onPackageRemoved(String packageName, int uid) {
- synchronized (mLock) {
- UserState userState = getOrCreateUserStateLocked(getChangingUserId());
- if (!userState.packageSet.contains(packageName)) {
- // Not a TV input package.
- return;
- }
- }
-
- ArrayList<ContentProviderOperation> operations = new ArrayList<>();
-
- String selection = TvContract.BaseTvColumns.COLUMN_PACKAGE_NAME + "=?";
- String[] selectionArgs = { packageName };
-
- operations.add(ContentProviderOperation.newDelete(TvContract.Channels.CONTENT_URI)
- .withSelection(selection, selectionArgs).build());
- operations.add(ContentProviderOperation.newDelete(TvContract.Programs.CONTENT_URI)
- .withSelection(selection, selectionArgs).build());
- operations.add(ContentProviderOperation
- .newDelete(TvContract.WatchedPrograms.CONTENT_URI)
- .withSelection(selection, selectionArgs).build());
-
- ContentProviderResult[] results = null;
- try {
- ContentResolver cr = getContentResolverForUser(getChangingUserId());
- results = cr.applyBatch(TvContract.AUTHORITY, operations);
- } catch (RemoteException | OperationApplicationException e) {
- Slog.e(TAG, "error in applyBatch", e);
- }
-
- if (DEBUG) {
- Slog.d(TAG, "onPackageRemoved(packageName=" + packageName + ", uid=" + uid
- + ")");
- Slog.d(TAG, "results=" + results);
- }
- }
};
monitor.register(mContext, null, UserHandle.ALL, true);
diff --git a/services/core/java/com/android/server/vr/VrManagerInternal.java b/services/core/java/com/android/server/vr/VrManagerInternal.java
index 0fc1900..45b7baf 100644
--- a/services/core/java/com/android/server/vr/VrManagerInternal.java
+++ b/services/core/java/com/android/server/vr/VrManagerInternal.java
@@ -79,4 +79,13 @@
* given in {@link android.service.vr.VrModeException} on failure.
*/
public abstract int hasVrPackage(@NonNull ComponentName packageName, int userId);
+
+ /**
+ * Sets the persistent VR mode state of a device. When a device is in persistent VR mode it will
+ * remain in VR mode even if the foreground does not specify Vr mode being enabled. Mainly used
+ * by VR viewers to indicate that a device is placed in a VR viewer.
+ *
+ * @param enabled true if the device should be placed in persistent VR mode.
+ */
+ public abstract void setPersistentVrModeEnabled(boolean enabled);
}
diff --git a/services/core/java/com/android/server/vr/VrManagerService.java b/services/core/java/com/android/server/vr/VrManagerService.java
index e8385fc..51c4ce31 100644
--- a/services/core/java/com/android/server/vr/VrManagerService.java
+++ b/services/core/java/com/android/server/vr/VrManagerService.java
@@ -20,18 +20,12 @@
import android.app.AppOpsManager;
import android.app.NotificationManager;
import android.annotation.NonNull;
-import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
-import android.content.pm.FeatureInfo;
-import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
-import android.hardware.display.DisplayManager;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
@@ -54,7 +48,6 @@
import android.util.SparseArray;
import com.android.internal.R;
-import com.android.server.LocalServices;
import com.android.server.SystemConfig;
import com.android.server.SystemService;
import com.android.server.utils.ManagedApplicationService.PendingEvent;
@@ -70,8 +63,6 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
-import java.util.List;
-import java.util.Map;
import java.util.Objects;
/**
@@ -122,8 +113,10 @@
// State protected by mLock
private boolean mVrModeAllowed;
private boolean mVrModeEnabled;
+ private boolean mPersistentVrModeEnabled;
private EnabledComponentsObserver mComponentObserver;
private ManagedApplicationService mCurrentVrService;
+ private ComponentName mDefaultVrService;
private Context mContext;
private ComponentName mCurrentVrModeComponent;
private int mCurrentVrModeUser;
@@ -138,7 +131,6 @@
private final NotificationAccessManager mNotifAccessManager = new NotificationAccessManager();
/** Tracks the state of the screen and keyguard UI.*/
private int mSystemSleepFlags = FLAG_NONE;
- private CompatibilityDisplay mCompatibilityDisplay;
private static final int MSG_VR_STATE_CHANGE = 0;
private static final int MSG_PENDING_VR_STATE_CHANGE = 1;
@@ -159,6 +151,10 @@
if (mVrModeAllowed) {
consumeAndApplyPendingStateLocked();
} else {
+ // Disable persistent mode when VR mode isn't allowed, allows an escape hatch to
+ // exit persistent VR mode when screen is turned off.
+ mPersistentVrModeEnabled = false;
+
// Set pending state to current state.
mPendingState = (mVrModeEnabled && mCurrentVrService != null)
? new VrState(mVrModeEnabled, mCurrentVrService.getComponent(),
@@ -380,6 +376,12 @@
}
@Override
+ public void setPersistentVrModeEnabled(boolean enabled) {
+ enforceCallerPermission(Manifest.permission.ACCESS_VR_MANAGER);
+ VrManagerService.this.setPersistentVrModeEnabled(enabled);
+ }
+
+ @Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
if (getContext().checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
!= PackageManager.PERMISSION_GRANTED) {
@@ -389,6 +391,8 @@
}
pw.println("********* Dump of VrManagerService *********");
pw.println("VR mode is currently: " + ((mVrModeAllowed) ? "allowed" : "disallowed"));
+ pw.println("Persistent VR mode is currently: " +
+ ((mPersistentVrModeEnabled) ? "enabled" : "disabled"));
pw.println("Previous state transitions:\n");
String tab = " ";
dumpStateTransitions(pw);
@@ -464,6 +468,11 @@
public int hasVrPackage(ComponentName packageName, int userId) {
return VrManagerService.this.hasVrPackage(packageName, userId);
}
+
+ @Override
+ public void setPersistentVrModeEnabled(boolean enabled) {
+ VrManagerService.this.setPersistentVrModeEnabled(enabled);
+ }
}
public VrManagerService(Context context) {
@@ -497,10 +506,14 @@
mComponentObserver.rebuildAll();
}
- DisplayManager dm =
- (DisplayManager) getContext().getSystemService(Context.DISPLAY_SERVICE);
- mCompatibilityDisplay = new CompatibilityDisplay(dm, mVrManager);
- mCompatibilityDisplay.init();
+ //TODO: something more robust than picking the first one
+ ArraySet<ComponentName> defaultVrComponents =
+ SystemConfig.getInstance().getDefaultVrComponents();
+ if (defaultVrComponents.size() > 0) {
+ mDefaultVrService = defaultVrComponents.valueAt(0);
+ } else {
+ Slog.i(TAG, "No default vr listener service found.");
+ }
} else if (phase == SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) {
synchronized (mLock) {
mVrModeAllowed = true;
@@ -644,8 +657,8 @@
}
}
+ mCurrentVrModeComponent = calling;
if (calling != null && !Objects.equals(calling, mCurrentVrModeComponent)) {
- mCurrentVrModeComponent = calling;
sendUpdatedCaller = true;
}
@@ -954,7 +967,25 @@
int userId, @NonNull ComponentName callingPackage) {
synchronized (mLock) {
- VrState pending = new VrState(enabled, targetPackageName, userId, callingPackage);
+ VrState pending;
+ ComponentName targetListener;
+ ComponentName foregroundVrComponent;
+
+ // If the device is in persistent VR mode, then calls to disable VR mode are ignored,
+ // and the system default VR listener is used.
+ boolean targetEnabledState = enabled || mPersistentVrModeEnabled;
+ if (!enabled && mPersistentVrModeEnabled) {
+ targetListener = mDefaultVrService;
+
+ // Current foreground component isn't a VR one (in 2D app case)
+ foregroundVrComponent = null;
+ } else {
+ targetListener = targetPackageName;
+ foregroundVrComponent = callingPackage;
+ }
+ pending = new VrState(
+ targetEnabledState, targetListener, userId, foregroundVrComponent);
+
if (!mVrModeAllowed) {
// We're not allowed to be in VR mode. Make this state pending. This will be
// applied the next time we are allowed to enter VR mode unless it is superseded by
@@ -963,7 +994,7 @@
return;
}
- if (!enabled && mCurrentVrService != null) {
+ if (!targetEnabledState && mCurrentVrService != null) {
// If we're transitioning out of VR mode, delay briefly to avoid expensive HAL calls
// and service bind/unbind in case we are immediately switching to another VR app.
if (mPendingState == null) {
@@ -978,7 +1009,19 @@
mPendingState = null;
}
- updateCurrentVrServiceLocked(enabled, targetPackageName, userId, callingPackage);
+ updateCurrentVrServiceLocked(
+ targetEnabledState, targetListener, userId, foregroundVrComponent);
+ }
+ }
+
+ private void setPersistentVrModeEnabled(boolean enabled) {
+ synchronized (mLock) {
+ mPersistentVrModeEnabled = enabled;
+
+ // Disabling persistent mode when not showing a VR should disable the overall vr mode.
+ if (!enabled && mCurrentVrModeComponent == null) {
+ setVrMode(false, null, 0, null);
+ }
}
}
diff --git a/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java b/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java
index fedd55a9..83e77ec3 100644
--- a/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java
+++ b/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java
@@ -630,6 +630,10 @@
*/
public boolean isValidProvider(WebViewProviderInfo configInfo,
PackageInfo packageInfo) {
+ // Ensure the provider targets this framework release (or a later one).
+ if (!UserPackage.hasCorrectTargetSdkVersion(packageInfo)) {
+ return false;
+ }
if (!versionCodeGE(packageInfo.versionCode, getMinimumVersionCode())
&& !mSystemInterface.systemIsDebuggable()) {
// Webview providers may be downgraded arbitrarily low, prevent that by enforcing
diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java
index 49ffa22..f7a9e41 100644
--- a/services/core/java/com/android/server/wm/AccessibilityController.java
+++ b/services/core/java/com/android/server/wm/AccessibilityController.java
@@ -369,6 +369,7 @@
case WindowManager.LayoutParams.TYPE_SYSTEM_ALERT:
case WindowManager.LayoutParams.TYPE_TOAST:
case WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY:
+ case WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY:
case WindowManager.LayoutParams.TYPE_PRIORITY_PHONE:
case WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG:
case WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG:
@@ -687,7 +688,7 @@
mSurfaceControl = surfaceControl;
mSurfaceControl.setLayerStack(mWindowManager.getDefaultDisplay()
.getLayerStack());
- mSurfaceControl.setLayer(mWindowManagerService.mPolicy.windowTypeToLayerLw(
+ mSurfaceControl.setLayer(mWindowManagerService.mPolicy.getWindowLayerFromTypeLw(
WindowManager.LayoutParams.TYPE_MAGNIFICATION_OVERLAY)
* WindowManagerService.TYPE_LAYER_MULTIPLIER);
mSurfaceControl.setPosition(0, 0);
diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java
index 3eb529b..4eb8e02 100644
--- a/services/core/java/com/android/server/wm/AppTransition.java
+++ b/services/core/java/com/android/server/wm/AppTransition.java
@@ -951,9 +951,9 @@
float scaleW = appWidth / thumbWidth;
getNextAppTransitionStartRect(taskId, mTmpRect);
final float fromX;
- final float fromY;
+ float fromY;
final float toX;
- final float toY;
+ float toY;
final float pivotX;
final float pivotY;
if (shouldScaleDownThumbnailTransition(uiMode, orientation)) {
@@ -966,6 +966,12 @@
toY = appRect.height() / 2 * (1 - 1 / scaleW) + appRect.top;
pivotX = mTmpRect.width() / 2;
pivotY = appRect.height() / 2 / scaleW;
+ if (mGridLayoutRecentsEnabled) {
+ // In the grid layout, the header is displayed above the thumbnail instead of
+ // overlapping it.
+ fromY -= thumbHeightI;
+ toY -= thumbHeightI * scaleW;
+ }
} else {
pivotX = 0;
pivotY = 0;
@@ -1014,7 +1020,10 @@
// This AnimationSet uses the Interpolators assigned above.
AnimationSet set = new AnimationSet(false);
set.addAnimation(scale);
- set.addAnimation(alpha);
+ if (!mGridLayoutRecentsEnabled) {
+ // In the grid layout, the header should be shown for the whole animation.
+ set.addAnimation(alpha);
+ }
set.addAnimation(translate);
set.addAnimation(clipAnim);
a = set;
@@ -1033,7 +1042,10 @@
// This AnimationSet uses the Interpolators assigned above.
AnimationSet set = new AnimationSet(false);
set.addAnimation(scale);
- set.addAnimation(alpha);
+ if (!mGridLayoutRecentsEnabled) {
+ // In the grid layout, the header should be shown for the whole animation.
+ set.addAnimation(alpha);
+ }
set.addAnimation(translate);
a = set;
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index bcc720d..061aa83 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -192,7 +192,8 @@
AppWindowToken(WindowManagerService service, IApplicationToken token, boolean voiceInteraction,
DisplayContent dc) {
- super(service, token != null ? token.asBinder() : null, TYPE_APPLICATION, true, dc);
+ super(service, token != null ? token.asBinder() : null, TYPE_APPLICATION, true, dc,
+ false /* ownerCanManageAppTokens */);
appToken = token;
mVoiceInteraction = voiceInteraction;
mInputApplicationHandle = new InputApplicationHandle(this);
@@ -1151,10 +1152,11 @@
*/
@Override
int getOrientation() {
- if (hidden || hiddenRequested) {
- return SCREEN_ORIENTATION_UNSET;
+ if (fillsParent() && (isVisible() || mService.mOpeningApps.contains(this))) {
+ return mOrientation;
}
- return mOrientation;
+
+ return SCREEN_ORIENTATION_UNSET;
}
/** Returns the app's preferred orientation regardless of its currently visibility state. */
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 679f178..c45136c 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -2185,7 +2185,7 @@
&& !mService.mInputMethodTarget.isInMultiWindowMode();
}
- final int aboveAppLayer = (mService.mPolicy.windowTypeToLayerLw(TYPE_APPLICATION) + 1)
+ final int aboveAppLayer = (mService.mPolicy.getWindowLayerFromTypeLw(TYPE_APPLICATION) + 1)
* TYPE_LAYER_MULTIPLIER + TYPE_LAYER_OFFSET;
final MutableBoolean mutableIncludeFullDisplay = new MutableBoolean(includeFullDisplay);
synchronized(mService.mWindowMap) {
@@ -2728,8 +2728,10 @@
*/
private final Comparator<WindowToken> mWindowComparator = (token1, token2) ->
// Tokens with higher base layer are z-ordered on-top.
- mService.mPolicy.windowTypeToLayerLw(token1.windowType)
- < mService.mPolicy.windowTypeToLayerLw(token2.windowType) ? -1 : 1;
+ mService.mPolicy.getWindowLayerFromTypeLw(token1.windowType,
+ token1.mOwnerCanManageAppTokens)
+ < mService.mPolicy.getWindowLayerFromTypeLw(token2.windowType,
+ token2.mOwnerCanManageAppTokens) ? -1 : 1;
private final Predicate<WindowState> mGetOrientingWindow = w -> {
if (!w.isVisibleLw() || !w.mPolicyVisibilityAfterAnim) {
diff --git a/services/core/java/com/android/server/wm/DockedStackDividerController.java b/services/core/java/com/android/server/wm/DockedStackDividerController.java
index 5a2ee9a..0a92a81 100644
--- a/services/core/java/com/android/server/wm/DockedStackDividerController.java
+++ b/services/core/java/com/android/server/wm/DockedStackDividerController.java
@@ -621,11 +621,7 @@
final boolean homeVisible = homeTask.getTopVisibleAppToken() != null;
final boolean homeBehind = (fullscreenStack != null && fullscreenStack.isVisible())
|| (homeStack.hasMultipleTaskWithHomeTaskNotTop());
- // If the home task is an on-top launcher, we don't want to minimize the docked stack.
- // Instead we want everything underneath that was visible to remain visible.
- // See android.R.attr#onTopLauncher.
- final boolean isOnTopLauncher = homeStack.topTaskIsOnTopLauncher();
- setMinimizedDockedStack(homeVisible && !homeBehind && !isOnTopLauncher, animate);
+ setMinimizedDockedStack(homeVisible && !homeBehind, animate);
}
private boolean isWithinDisplay(Task task) {
diff --git a/services/core/java/com/android/server/wm/DragState.java b/services/core/java/com/android/server/wm/DragState.java
index 1ae987f..3fdafc7 100644
--- a/services/core/java/com/android/server/wm/DragState.java
+++ b/services/core/java/com/android/server/wm/DragState.java
@@ -239,7 +239,7 @@
}
int getDragLayerLw() {
- return mService.mPolicy.windowTypeToLayerLw(WindowManager.LayoutParams.TYPE_DRAG)
+ return mService.mPolicy.getWindowLayerFromTypeLw(WindowManager.LayoutParams.TYPE_DRAG)
* WindowManagerService.TYPE_LAYER_MULTIPLIER
+ WindowManagerService.TYPE_LAYER_OFFSET;
}
diff --git a/services/core/java/com/android/server/wm/InputConsumerImpl.java b/services/core/java/com/android/server/wm/InputConsumerImpl.java
index b92bfb9..36753b7 100644
--- a/services/core/java/com/android/server/wm/InputConsumerImpl.java
+++ b/services/core/java/com/android/server/wm/InputConsumerImpl.java
@@ -77,7 +77,7 @@
}
private int getLayerLw(int windowType) {
- return mService.mPolicy.windowTypeToLayerLw(windowType)
+ return mService.mPolicy.getWindowLayerFromTypeLw(windowType)
* WindowManagerService.TYPE_LAYER_MULTIPLIER
+ WindowManagerService.TYPE_LAYER_OFFSET;
}
diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java
index 5f53d84..37b8deb 100644
--- a/services/core/java/com/android/server/wm/InputMonitor.java
+++ b/services/core/java/com/android/server/wm/InputMonitor.java
@@ -24,6 +24,7 @@
import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_DISABLE_WALLPAPER_TOUCH_EVENTS;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DRAG;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS_LIGHT;
@@ -237,8 +238,8 @@
// Figure out whether this window is layered above system windows.
// We need to do this here to help the activity manager know how to
// layer its ANR dialog.
- int systemAlertLayer = mService.mPolicy.windowTypeToLayerLw(
- WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
+ int systemAlertLayer = mService.mPolicy.getWindowLayerFromTypeLw(
+ TYPE_APPLICATION_OVERLAY, windowState.mOwnerCanAddInternalSystemWindow);
aboveSystem = windowState.mBaseLayer > systemAlertLayer;
} else if (appWindowToken != null) {
Slog.i(TAG_WM, "Input event dispatching timed out "
@@ -471,7 +472,7 @@
/* Callback to get pointer layer. */
@Override
public int getPointerLayer() {
- return mService.mPolicy.windowTypeToLayerLw(WindowManager.LayoutParams.TYPE_POINTER)
+ return mService.mPolicy.getWindowLayerFromTypeLw(WindowManager.LayoutParams.TYPE_POINTER)
* WindowManagerService.TYPE_LAYER_MULTIPLIER
+ WindowManagerService.TYPE_LAYER_OFFSET;
}
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index d96e1ef..ab9a378 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -91,20 +91,16 @@
private boolean mHomeTask;
- // Whether this task is an on-top launcher task, which is determined by the root activity.
- private boolean mIsOnTopLauncher;
-
private TaskDescription mTaskDescription;
Task(int taskId, TaskStack stack, int userId, WindowManagerService service, Rect bounds,
- Configuration overrideConfig, boolean isOnTopLauncher, int resizeMode,
- boolean supportsPictureInPicture, boolean homeTask, TaskDescription taskDescription,
+ Configuration overrideConfig, int resizeMode, boolean supportsPictureInPicture,
+ boolean homeTask, TaskDescription taskDescription,
TaskWindowContainerController controller) {
mTaskId = taskId;
mStack = stack;
mUserId = userId;
mService = service;
- mIsOnTopLauncher = isOnTopLauncher;
mResizeMode = resizeMode;
mSupportsPictureInPicture = supportsPictureInPicture;
mHomeTask = homeTask;
@@ -117,7 +113,7 @@
return mStack != null ? mStack.getDisplayContent() : null;
}
- int getAdjustedAddPosition(int suggestedPosition) {
+ private int getAdjustedAddPosition(int suggestedPosition) {
final int size = mChildren.size();
if (suggestedPosition >= size) {
return Math.min(size, suggestedPosition);
@@ -347,10 +343,6 @@
|| mResizeMode == RESIZE_MODE_FORCE_RESIZABLE_PRESERVE_ORIENTATION;
}
- boolean isOnTopLauncher() {
- return mIsOnTopLauncher;
- }
-
boolean cropWindowsToStackBounds() {
return isResizeable();
}
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index 0ff1f0c..a1c9c29 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -160,10 +160,6 @@
return mChildren.size() > 1 && !mChildren.get(mChildren.size() - 1).isHomeTask();
}
- boolean topTaskIsOnTopLauncher() {
- return mChildren.get(mChildren.size() - 1).isOnTopLauncher();
- }
-
/**
* Set the bounds of the stack and its containing tasks.
* @param stackBounds New stack bounds. Passing in null sets the bounds to fullscreen.
@@ -1479,7 +1475,7 @@
return StackId.hasMovementAnimations(mStackId);
}
- public boolean getForceScaleToCrop() {
+ public boolean getForceScaleToStack() {
return mBoundsAnimating;
}
diff --git a/services/core/java/com/android/server/wm/TaskWindowContainerController.java b/services/core/java/com/android/server/wm/TaskWindowContainerController.java
index 11667c0..efc2e11 100644
--- a/services/core/java/com/android/server/wm/TaskWindowContainerController.java
+++ b/services/core/java/com/android/server/wm/TaskWindowContainerController.java
@@ -51,17 +51,17 @@
public TaskWindowContainerController(int taskId, TaskWindowContainerListener listener,
StackWindowController stackController, int userId, Rect bounds,
Configuration overrideConfig, int resizeMode, boolean supportsPictureInPicture,
- boolean homeTask, boolean isOnTopLauncher, boolean toTop, boolean showForAllUsers,
+ boolean homeTask, boolean toTop, boolean showForAllUsers,
TaskDescription taskDescription) {
this(taskId, listener, stackController, userId, bounds, overrideConfig, resizeMode,
- supportsPictureInPicture, homeTask, isOnTopLauncher, toTop, showForAllUsers,
- taskDescription, WindowManagerService.getInstance());
+ supportsPictureInPicture, homeTask, toTop, showForAllUsers, taskDescription,
+ WindowManagerService.getInstance());
}
public TaskWindowContainerController(int taskId, TaskWindowContainerListener listener,
StackWindowController stackController, int userId, Rect bounds,
Configuration overrideConfig, int resizeMode, boolean supportsPictureInPicture,
- boolean homeTask, boolean isOnTopLauncher, boolean toTop, boolean showForAllUsers,
+ boolean homeTask, boolean toTop, boolean showForAllUsers,
TaskDescription taskDescription, WindowManagerService service) {
super(listener, service);
mTaskId = taskId;
@@ -78,7 +78,7 @@
}
EventLog.writeEvent(WM_TASK_CREATED, taskId, stack.mStackId);
final Task task = createTask(taskId, stack, userId, bounds, overrideConfig, resizeMode,
- supportsPictureInPicture, homeTask, isOnTopLauncher, taskDescription);
+ supportsPictureInPicture, homeTask, taskDescription);
final int position = toTop ? POSITION_TOP : POSITION_BOTTOM;
stack.addTask(task, position, showForAllUsers, true /* moveParents */);
}
@@ -87,9 +87,9 @@
@VisibleForTesting
Task createTask(int taskId, TaskStack stack, int userId, Rect bounds,
Configuration overrideConfig, int resizeMode, boolean supportsPictureInPicture,
- boolean homeTask, boolean isOnTopLauncher, TaskDescription taskDescription) {
- return new Task(taskId, stack, userId, mService, bounds, overrideConfig, isOnTopLauncher,
- resizeMode, supportsPictureInPicture, homeTask, taskDescription, this);
+ boolean homeTask, TaskDescription taskDescription) {
+ return new Task(taskId, stack, userId, mService, bounds, overrideConfig, resizeMode,
+ supportsPictureInPicture, homeTask, taskDescription, this);
}
@Override
diff --git a/services/core/java/com/android/server/wm/WallpaperWindowToken.java b/services/core/java/com/android/server/wm/WallpaperWindowToken.java
index 8ea1b3b..28aebbb 100644
--- a/services/core/java/com/android/server/wm/WallpaperWindowToken.java
+++ b/services/core/java/com/android/server/wm/WallpaperWindowToken.java
@@ -40,8 +40,8 @@
private static final String TAG = TAG_WITH_CLASS_NAME ? "WallpaperWindowToken" : TAG_WM;
WallpaperWindowToken(WindowManagerService service, IBinder token, boolean explicit,
- DisplayContent dc) {
- super(service, token, TYPE_WALLPAPER, explicit, dc);
+ DisplayContent dc, boolean ownerCanManageAppTokens) {
+ super(service, token, TYPE_WALLPAPER, explicit, dc, ownerCanManageAppTokens);
dc.mWallpaperController.addWallpaperToken(this);
}
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index 5b96263..6973c3c 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -510,14 +510,13 @@
* specification...
*/
int getOrientation() {
-
- if (!fillsParent() || !isVisible()) {
- // Ignore invisible containers or containers that don't completely fills their parents.
+ if (!fillsParent()) {
+ // Ignore containers that don't completely fill their parents.
return SCREEN_ORIENTATION_UNSET;
}
- // The container fills its parent so we can use it orientation if it has one specified,
- // otherwise we prefer to use the orientation of its topmost child that has one
+ // The container fills its parent so we can use it orientation if it has one
+ // specified; otherwise we prefer to use the orientation of its topmost child that has one
// specified and fall back on this container's unset or unspecified value as a candidate
// if none of the children have a better candidate for the orientation.
if (mOrientation != SCREEN_ORIENTATION_UNSET
diff --git a/services/core/java/com/android/server/wm/WindowLayersController.java b/services/core/java/com/android/server/wm/WindowLayersController.java
index e0c3d60..d56110c 100644
--- a/services/core/java/com/android/server/wm/WindowLayersController.java
+++ b/services/core/java/com/android/server/wm/WindowLayersController.java
@@ -59,7 +59,6 @@
private ArrayDeque<WindowState> mPinnedWindows = new ArrayDeque<>();
private ArrayDeque<WindowState> mDockedWindows = new ArrayDeque<>();
private ArrayDeque<WindowState> mInputMethodWindows = new ArrayDeque<>();
- private ArrayDeque<WindowState> mOnTopLauncherWindows = new ArrayDeque<>();
private WindowState mDockDivider = null;
private ArrayDeque<WindowState> mReplacingWindows = new ArrayDeque<>();
private int mCurBaseLayer;
@@ -138,7 +137,6 @@
mPinnedWindows.clear();
mInputMethodWindows.clear();
mDockedWindows.clear();
- mOnTopLauncherWindows.clear();
mReplacingWindows.clear();
mDockDivider = null;
@@ -182,9 +180,6 @@
if (task == null) {
return;
}
- if (task.isOnTopLauncher()) {
- mOnTopLauncherWindows.add(w);
- }
final TaskStack stack = task.mStack;
if (stack == null) {
return;
@@ -206,10 +201,6 @@
layer = assignAndIncreaseLayerIfNeeded(mDockDivider, layer);
- while (!mOnTopLauncherWindows.isEmpty()) {
- layer = assignAndIncreaseLayerIfNeeded(mOnTopLauncherWindows.remove(), layer);
- }
-
// We know that we will be animating a relaunching window in the near future, which will
// receive a z-order increase. We want the replaced window to immediately receive the same
// treatment, e.g. to be above the dock divider.
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 9b96523..971794b 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -16,13 +16,14 @@
package com.android.server.wm;
+import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
import static android.Manifest.permission.MANAGE_APP_TOKENS;
import static android.Manifest.permission.REGISTER_WINDOW_MANAGER_LISTENERS;
import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
-import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
import static android.app.StatusBarManager.DISABLE_MASK;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.WindowManager.DOCKED_INVALID;
import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
@@ -101,7 +102,6 @@
import android.app.ActivityManagerInternal;
import android.app.AppOpsManager;
import android.app.IActivityManager;
-import android.app.RemoteAction;
import android.app.admin.DevicePolicyManager;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
@@ -236,7 +236,6 @@
import java.util.HashMap;
import java.util.List;
-import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
import static android.Manifest.permission.READ_FRAME_BUFFER;
/** {@hide} */
public class WindowManagerService extends IWindowManager.Stub
@@ -523,7 +522,7 @@
boolean mSupportsPictureInPicture = false;
int getDragLayerLocked() {
- return mPolicy.windowTypeToLayerLw(TYPE_DRAG) * TYPE_LAYER_MULTIPLIER + TYPE_LAYER_OFFSET;
+ return mPolicy.getWindowLayerFromTypeLw(TYPE_DRAG) * TYPE_LAYER_MULTIPLIER + TYPE_LAYER_OFFSET;
}
class RotationWatcher {
@@ -1099,6 +1098,8 @@
long origId;
final int callingUid = Binder.getCallingUid();
final int type = attrs.type;
+ final boolean ownerCanAddInternalSystemWindow =
+ mContext.checkCallingPermission(INTERNAL_SYSTEM_WINDOW) == PERMISSION_GRANTED;
synchronized(mWindowMap) {
if (!mDisplayReady) {
@@ -1200,7 +1201,8 @@
return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
}
}
- token = new WindowToken(this, attrs.token, type, false, displayContent);
+ token = new WindowToken(this, attrs.token, type, false, displayContent,
+ ownerCanAddInternalSystemWindow);
} else if (rootType >= FIRST_APPLICATION_WINDOW && rootType <= LAST_APPLICATION_WINDOW) {
atoken = token.asAppWindowToken();
if (atoken == null) {
@@ -1270,11 +1272,13 @@
// It is not valid to use an app token with other system types; we will
// instead make a new token for it (as if null had been passed in for the token).
attrs.token = null;
- token = new WindowToken(this, null, type, false, displayContent);
+ token = new WindowToken(this, null, type, false, displayContent,
+ ownerCanAddInternalSystemWindow);
}
- WindowState win = new WindowState(this, session, client, token, parentWindow,
- appOp[0], seq, attrs, viewVisibility, session.mUid);
+ final WindowState win = new WindowState(this, session, client, token, parentWindow,
+ appOp[0], seq, attrs, viewVisibility, session.mUid,
+ ownerCanAddInternalSystemWindow);
if (win.mDeathRecipient == null) {
// Client has apparently died, so there is no reason to
// continue.
@@ -2405,9 +2409,10 @@
return;
}
if (type == TYPE_WALLPAPER) {
- new WallpaperWindowToken(this, binder, true, dc);
+ new WallpaperWindowToken(this, binder, true, dc,
+ true /* ownerCanManageAppTokens */);
} else {
- new WindowToken(this, binder, type, true, dc);
+ new WindowToken(this, binder, type, true, dc, true /* ownerCanManageAppTokens */);
}
}
}
@@ -3606,7 +3611,7 @@
mCircularDisplayMask = new CircularDisplayMask(
getDefaultDisplayContentLocked().getDisplay(),
mFxSession,
- mPolicy.windowTypeToLayerLw(
+ mPolicy.getWindowLayerFromTypeLw(
WindowManager.LayoutParams.TYPE_POINTER)
* TYPE_LAYER_MULTIPLIER + 10, screenOffset, maskThickness);
}
@@ -3635,7 +3640,7 @@
mContext,
getDefaultDisplayContentLocked().getDisplay(),
mFxSession,
- mPolicy.windowTypeToLayerLw(
+ mPolicy.getWindowLayerFromTypeLw(
WindowManager.LayoutParams.TYPE_POINTER)
* TYPE_LAYER_MULTIPLIER + 10);
}
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 050adfe..867080e 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -18,7 +18,6 @@
import static android.app.ActivityManager.ENABLE_TASK_SNAPSHOTS;
import static android.app.ActivityManager.StackId;
-import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
import static android.app.ActivityManager.isLowRamDeviceStatic;
import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
@@ -164,6 +163,8 @@
final int mAppOp;
// UserId and appId of the owner. Don't display windows of non-current user.
final int mOwnerUid;
+ /** The owner has {@link android.Manifest.permission#INTERNAL_SYSTEM_WINDOW} */
+ final boolean mOwnerCanAddInternalSystemWindow;
final IWindowId mWindowId;
WindowToken mToken;
// The same object as mToken if this is an app window and null for non-app windows.
@@ -561,7 +562,7 @@
WindowState(WindowManagerService service, Session s, IWindow c, WindowToken token,
WindowState parentWindow, int appOp, int seq, WindowManager.LayoutParams a,
- int viewVisibility, int ownerId) {
+ int viewVisibility, int ownerId, boolean ownerCanAddInternalSystemWindow) {
mService = service;
mSession = s;
mClient = c;
@@ -569,6 +570,7 @@
mToken = token;
mAppToken = mToken.asAppWindowToken();
mOwnerUid = ownerId;
+ mOwnerCanAddInternalSystemWindow = ownerCanAddInternalSystemWindow;
mWindowId = new IWindowId.Stub() {
@Override
public void registerFocusObserver(IWindowFocusObserver observer) {
@@ -613,9 +615,9 @@
if (mAttrs.type >= FIRST_SUB_WINDOW && mAttrs.type <= LAST_SUB_WINDOW) {
// The multiplier here is to reserve space for multiple
// windows in the same type layer.
- mBaseLayer = mPolicy.windowTypeToLayerLw(parentWindow.mAttrs.type)
+ mBaseLayer = mPolicy.getWindowLayerLw(parentWindow)
* TYPE_LAYER_MULTIPLIER + TYPE_LAYER_OFFSET;
- mSubLayer = mPolicy.subWindowTypeToLayerLw(a.type);
+ mSubLayer = mPolicy.getSubWindowLayerFromTypeLw(a.type);
mIsChildWindow = true;
if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + this + " to " + parentWindow);
@@ -629,7 +631,7 @@
} else {
// The multiplier here is to reserve space for multiple
// windows in the same type layer.
- mBaseLayer = mPolicy.windowTypeToLayerLw(a.type)
+ mBaseLayer = mPolicy.getWindowLayerLw(this)
* TYPE_LAYER_MULTIPLIER + TYPE_LAYER_OFFSET;
mSubLayer = 0;
mIsChildWindow = false;
@@ -676,6 +678,11 @@
return mAttrs.packageName;
}
+ @Override
+ public boolean canAddInternalSystemWindow() {
+ return mOwnerCanAddInternalSystemWindow;
+ }
+
/**
* Subtracts the insets calculated by intersecting {@param layoutFrame} with {@param insetFrame}
* from {@param frame}. In other words, it applies the insets that would result if
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index abce222..d2ea64c8 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -915,10 +915,15 @@
if (attachedTransformation != null) {
tmpMatrix.postConcat(attachedTransformation.getMatrix());
}
- tmpMatrix.postTranslate(frame.left + mWin.mXOffset, frame.top + mWin.mYOffset);
if (appTransformation != null) {
tmpMatrix.postConcat(appTransformation.getMatrix());
}
+
+ // The translation that applies the position of the window needs to be applied at the
+ // end in case that other translations include scaling. Otherwise the scaling will
+ // affect this translation. But it needs to be set before the screen rotation animation
+ // so the pivot point is at the center of the screen for all windows.
+ tmpMatrix.postTranslate(frame.left + mWin.mXOffset, frame.top + mWin.mYOffset);
if (screenAnimation) {
tmpMatrix.postConcat(screenRotationAnimation.getEnterTransformation().getMatrix());
}
@@ -1313,18 +1318,20 @@
float surfaceWidth = mSurfaceController.getWidth();
float surfaceHeight = mSurfaceController.getHeight();
- if ((task != null && task.mStack.getForceScaleToCrop()) || mForceScaleUntilResize) {
+ if ((task != null && task.mStack.getForceScaleToStack()) || mForceScaleUntilResize) {
int hInsets = w.getAttrs().surfaceInsets.left + w.getAttrs().surfaceInsets.right;
int vInsets = w.getAttrs().surfaceInsets.top + w.getAttrs().surfaceInsets.bottom;
if (!mForceScaleUntilResize) {
mSurfaceController.forceScaleableInTransaction(true);
}
+
+ task.mStack.getDimBounds(mTmpStackBounds);
// We want to calculate the scaling based on the content area, not based on
// the entire surface, so that we scale in sync with windows that don't have insets.
- mExtraHScale = (finalClipRect.width() - hInsets) / (float)(surfaceWidth - hInsets);
- mExtraVScale = (finalClipRect.height() - vInsets) / (float)(surfaceHeight - vInsets);
+ mExtraHScale = (mTmpStackBounds.width() - hInsets) / (float)(surfaceWidth - hInsets);
+ mExtraVScale = (mTmpStackBounds.height() - vInsets) / (float)(surfaceHeight - vInsets);
- // In the case of ForceScaleToCrop we scale entire tasks together,
+ // In the case of ForceScaleToStack we scale entire tasks together,
// and so we need to scale our offsets relative to the task bounds
// or parent and child windows would fall out of alignment.
int posX = (int) (mTmpSize.left - w.mAttrs.x * (1 - mExtraHScale));
diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java
index 4b94d15..8beb87d 100644
--- a/services/core/java/com/android/server/wm/WindowToken.java
+++ b/services/core/java/com/android/server/wm/WindowToken.java
@@ -77,6 +77,9 @@
// The display this token is on.
protected DisplayContent mDisplayContent;
+ /** The owner has {@link android.Manifest.permission#MANAGE_APP_TOKENS} */
+ final boolean mOwnerCanManageAppTokens;
+
/**
* Compares two child window of this token and returns -1 if the first is lesser than the
* second in terms of z-order and 1 otherwise.
@@ -98,11 +101,12 @@
};
WindowToken(WindowManagerService service, IBinder _token, int type, boolean persistOnEmpty,
- DisplayContent dc) {
+ DisplayContent dc, boolean ownerCanManageAppTokens) {
mService = service;
token = _token;
windowType = type;
mPersistOnEmpty = persistOnEmpty;
+ mOwnerCanManageAppTokens = ownerCanManageAppTokens;
onDisplayChanged(dc);
}
diff --git a/services/core/jni/com_android_server_HardwarePropertiesManagerService.cpp b/services/core/jni/com_android_server_HardwarePropertiesManagerService.cpp
index 545b3d7..703518d 100644
--- a/services/core/jni/com_android_server_HardwarePropertiesManagerService.cpp
+++ b/services/core/jni/com_android_server_HardwarePropertiesManagerService.cpp
@@ -70,7 +70,7 @@
static void nativeInit(JNIEnv* env, jobject obj) {
// TODO(b/31632518)
if (gThermalModule == nullptr) {
- gThermalModule = IThermal::getService("thermal");
+ gThermalModule = IThermal::getService();
}
if (gThermalModule == nullptr) {
diff --git a/services/core/jni/com_android_server_SystemServer.cpp b/services/core/jni/com_android_server_SystemServer.cpp
index e46490b..3120af56 100644
--- a/services/core/jni/com_android_server_SystemServer.cpp
+++ b/services/core/jni/com_android_server_SystemServer.cpp
@@ -26,18 +26,11 @@
namespace android {
-static int start_sensor_service(void* /*unused*/) {
- SensorService::instantiate();
- return 0;
-}
-
static void android_server_SystemServer_startSensorService(JNIEnv* /* env */, jobject /* clazz */) {
char propBuf[PROPERTY_VALUE_MAX];
property_get("system_init.startsensorservice", propBuf, "1");
if (strcmp(propBuf, "1") == 0) {
- // Start the sensor service in a new thread
- createThreadEtc(start_sensor_service, nullptr,
- "StartSensorThread", PRIORITY_FOREGROUND);
+ SensorService::instantiate();
}
}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 3c1d274..003b6d0 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -60,6 +60,7 @@
import android.annotation.UserIdInt;
import android.app.Activity;
import android.app.ActivityManager;
+import android.app.ActivityManagerInternal;
import android.app.AlarmManager;
import android.app.AppGlobals;
import android.app.IActivityManager;
@@ -6151,8 +6152,12 @@
intent.setComponent(mOwners.getDeviceOwnerComponent());
intent.setDataAndType(bugreportUri, RemoteBugreportUtils.BUGREPORT_MIMETYPE);
intent.putExtra(DeviceAdminReceiver.EXTRA_BUGREPORT_HASH, bugreportHash);
- mContext.grantUriPermission(mOwners.getDeviceOwnerComponent().getPackageName(),
- bugreportUri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
+ intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+
+ LocalServices.getService(ActivityManagerInternal.class)
+ .grantUriPermissionFromIntent(Process.SHELL_UID,
+ mOwners.getDeviceOwnerComponent().getPackageName(),
+ intent, mOwners.getDeviceOwnerUserId());
mContext.sendBroadcastAsUser(intent, UserHandle.of(mOwners.getDeviceOwnerUserId()));
}
} catch (FileNotFoundException e) {
@@ -6706,6 +6711,8 @@
policy.mDelegationMap.clear();
policy.mStatusBarDisabled = false;
policy.mUserProvisioningState = DevicePolicyManager.STATE_USER_UNMANAGED;
+ policy.mAffiliationIds.clear();
+ policy.mLockTaskPackages.clear();
saveSettingsLocked(userId);
try {
@@ -8564,18 +8571,11 @@
}
}
- /**
- * Sets which packages may enter lock task mode.
- *
- * <p>This function can only be called by the device owner or alternatively by the profile owner
- * in case the user is affiliated.
- *
- * @param packages The list of packages allowed to enter lock task mode.
- */
@Override
public void setLockTaskPackages(ComponentName who, String[] packages)
throws SecurityException {
Preconditions.checkNotNull(who, "ComponentName is null");
+ Preconditions.checkNotNull(packages, "packages is null");
synchronized (this) {
getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
@@ -8598,48 +8598,48 @@
updateLockTaskPackagesLocked(packages, userHandle);
}
- /**
- * This function returns the list of components allowed to start the task lock mode.
- */
+ private void maybeClearLockTaskPackagesLocked() {
+ final long ident = mInjector.binderClearCallingIdentity();
+ try {
+ final List<UserInfo> userInfos = mUserManager.getUsers(/*excludeDying=*/ true);
+ for (int i = 0; i < userInfos.size(); i++) {
+ int userId = userInfos.get(i).id;
+ final List<String> lockTaskPackages = getUserData(userId).mLockTaskPackages;
+ if (!lockTaskPackages.isEmpty() &&
+ !isUserAffiliatedWithDeviceLocked(userId)) {
+ Slog.d(LOG_TAG,
+ "User id " + userId + " not affiliated. Clearing lock task packages");
+ setLockTaskPackagesLocked(userId, Collections.<String>emptyList());
+ }
+ }
+ } finally {
+ mInjector.binderRestoreCallingIdentity(ident);
+ }
+ }
+
@Override
public String[] getLockTaskPackages(ComponentName who) {
Preconditions.checkNotNull(who, "ComponentName is null");
+
+ final int userHandle = mInjector.binderGetCallingUserHandle().getIdentifier();
synchronized (this) {
- getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER);
- int userHandle = mInjector.binderGetCallingUserHandle().getIdentifier();
- final List<String> packages = getLockTaskPackagesLocked(userHandle);
+ getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
+ if (!isUserAffiliatedWithDeviceLocked(userHandle)) {
+ throw new SecurityException("Admin " + who +
+ " is neither the device owner or affiliated user's profile owner.");
+ }
+
+ final List<String> packages = getUserData(userHandle).mLockTaskPackages;
return packages.toArray(new String[packages.size()]);
}
}
- private List<String> getLockTaskPackagesLocked(int userHandle) {
- final DevicePolicyData policy = getUserData(userHandle);
- return policy.mLockTaskPackages;
- }
-
- /**
- * This function lets the caller know whether the given package is allowed to start the
- * lock task mode.
- * @param pkg The package to check
- */
@Override
public boolean isLockTaskPermitted(String pkg) {
- // Get current user's devicepolicy
- int uid = mInjector.binderGetCallingUid();
- int userHandle = UserHandle.getUserId(uid);
- DevicePolicyData policy = getUserData(userHandle);
+ final int userHandle = mInjector.userHandleGetCallingUserId();
synchronized (this) {
- for (int i = 0; i < policy.mLockTaskPackages.size(); i++) {
- String lockTaskPackage = policy.mLockTaskPackages.get(i);
-
- // If the given package equals one of the packages stored our list,
- // we allow this package to start lock task mode.
- if (lockTaskPackage.equals(pkg)) {
- return true;
- }
- }
+ return getUserData(userHandle).mLockTaskPackages.contains(pkg);
}
- return false;
}
@Override
@@ -9848,6 +9848,7 @@
// but as a result of that other users might become affiliated or un-affiliated.
maybePauseDeviceWideLoggingLocked();
maybeResumeDeviceWideLoggingLocked();
+ maybeClearLockTaskPackagesLocked();
}
}
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index b911d2d..83e209d 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -125,8 +125,13 @@
public final class SystemServer {
private static final String TAG = "SystemServer";
+ // Tag for timing measurement of main thread.
+ private static final String SYSTEM_SERVER_TIMING_TAG = "SystemServerTiming";
+ // Tag for timing measurement of non-main asynchronous operations.
+ private static final String SYSTEM_SERVER_TIMING_ASYNC_TAG = SYSTEM_SERVER_TIMING_TAG + "Async";
+
private static final BootTimingsTraceLog BOOT_TIMINGS_TRACE_LOG
- = new BootTimingsTraceLog("SystemServerTiming", Trace.TRACE_TAG_SYSTEM_SERVER);
+ = new BootTimingsTraceLog(SYSTEM_SERVER_TIMING_TAG, Trace.TRACE_TAG_SYSTEM_SERVER);
private static final String ENCRYPTING_STATE = "trigger_restart_min_framework";
private static final String ENCRYPTED_STATE = "1";
@@ -149,6 +154,8 @@
"com.android.server.voiceinteraction.VoiceInteractionManagerService";
private static final String PRINT_MANAGER_SERVICE_CLASS =
"com.android.server.print.PrintManagerService";
+ private static final String COMPANION_DEVICE_MANAGER_SERVICE_CLASS =
+ "com.android.server.print.CompanionDeviceManagerService";
private static final String USB_SERVICE_CLASS =
"com.android.server.usb.UsbService$Lifecycle";
private static final String MIDI_SERVICE_CLASS =
@@ -227,8 +234,11 @@
private boolean mFirstBoot;
private final boolean mRuntimeRestart;
+ private static final String START_SENSOR_SERVICE = "StartSensorService";
+ private Future<?> mSensorServiceStart;
+
/**
- * Start the sensor service.
+ * Start the sensor service. This is a blocking call and can take time.
*/
private static native void startSensorService();
@@ -382,7 +392,7 @@
MetricsLogger.histogram(null, "boot_system_server_ready", uptimeMillis);
final int MAX_UPTIME_MILLIS = 60 * 1000;
if (uptimeMillis > MAX_UPTIME_MILLIS) {
- Slog.wtf("SystemServerTiming",
+ Slog.wtf(SYSTEM_SERVER_TIMING_TAG,
"SystemServer init took too long. uptimeMillis=" + uptimeMillis);
}
}
@@ -584,9 +594,15 @@
// The sensor service needs access to package manager service, app ops
// service, and permissions service, therefore we start it after them.
- traceBeginAndSlog("StartSensorService");
- startSensorService();
- traceEnd();
+ // Start sensor service in a separate thread. Completion should be checked
+ // before using it.
+ mSensorServiceStart = SystemServerInitThreadPool.get().submit(() -> {
+ BootTimingsTraceLog traceLog = new BootTimingsTraceLog(
+ SYSTEM_SERVER_TIMING_ASYNC_TAG, Trace.TRACE_TAG_SYSTEM_SERVER);
+ traceLog.traceBegin(START_SENSOR_SERVICE);
+ startSensorService();
+ traceLog.traceEnd();
+ }, START_SENSOR_SERVICE);
}
/**
@@ -742,6 +758,9 @@
traceEnd();
traceBeginAndSlog("StartWindowManagerService");
+ // WMS needs sensor service ready
+ ConcurrentUtils.waitForFutureNoInterrupt(mSensorServiceStart, START_SENSOR_SERVICE);
+ mSensorServiceStart = null;
wm = WindowManagerService.main(context, inputManager,
mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL,
!mFirstBoot, mOnlyCore, new PhoneWindowManager());
@@ -1333,6 +1352,10 @@
traceEnd();
}
+ traceBeginAndSlog("StartCompanionDeviceManager");
+ mSystemServiceManager.startService(COMPANION_DEVICE_MANAGER_SERVICE_CLASS);
+ traceEnd();
+
traceBeginAndSlog("StartRestrictionManager");
mSystemServiceManager.startService(RestrictionsManagerService.class);
traceEnd();
@@ -1590,7 +1613,7 @@
webviewPrep = SystemServerInitThreadPool.get().submit(() -> {
Slog.i(TAG, WEBVIEW_PREPARATION);
BootTimingsTraceLog traceLog = new BootTimingsTraceLog(
- "SystemServerTiming", Trace.TRACE_TAG_SYSTEM_SERVER);
+ SYSTEM_SERVER_TIMING_ASYNC_TAG, Trace.TRACE_TAG_SYSTEM_SERVER);
traceLog.traceBegin(WEBVIEW_PREPARATION);
mWebViewUpdateService.prepareWebViewInSystemServer();
traceLog.traceEnd();
@@ -1651,13 +1674,13 @@
Watchdog.getInstance().start();
traceEnd();
- if (webviewPrep != null) {
- ConcurrentUtils.waitForFutureNoInterrupt(webviewPrep, WEBVIEW_PREPARATION);
- }
-
// It is now okay to let the various system services start their
// third party code...
traceBeginAndSlog("PhaseThirdPartyAppsCanStart");
+ // confirm webview completion before starting 3rd party
+ if (webviewPrep != null) {
+ ConcurrentUtils.waitForFutureNoInterrupt(webviewPrep, WEBVIEW_PREPARATION);
+ }
mSystemServiceManager.startBootPhase(
SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);
traceEnd();
diff --git a/services/print/java/com/android/server/print/CompanionDeviceManagerService.java b/services/print/java/com/android/server/print/CompanionDeviceManagerService.java
new file mode 100644
index 0000000..9824c1d
--- /dev/null
+++ b/services/print/java/com/android/server/print/CompanionDeviceManagerService.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package com.android.server.print;
+
+import static com.android.internal.util.Preconditions.checkNotNull;
+
+import android.app.PendingIntent;
+import android.companion.AssociationRequest;
+import android.companion.ICompanionDeviceManager;
+import android.companion.ICompanionDeviceManagerService;
+import android.companion.IOnAssociateCallback;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.util.Log;
+
+import com.android.server.SystemService;
+
+//TODO move to own package!
+/** @hide */
+public class CompanionDeviceManagerService extends SystemService {
+
+ private static final ComponentName SERVICE_TO_BIND_TO = ComponentName.createRelative(
+ "com.android.companiondevicemanager", ".DeviceDiscoveryService");
+
+ private static final boolean DEBUG = false;
+ private static final String LOG_TAG = "CompanionDeviceManagerService";
+
+ private final CompanionDeviceManagerImpl mImpl;
+
+ public CompanionDeviceManagerService(Context context) {
+ super(context);
+ mImpl = new CompanionDeviceManagerImpl();
+ }
+
+ @Override
+ public void onStart() {
+ publishBinderService(Context.COMPANION_DEVICE_SERVICE, mImpl);
+ }
+
+ class CompanionDeviceManagerImpl extends ICompanionDeviceManager.Stub {
+
+ @Override
+ public void associate(
+ AssociationRequest request,
+ IOnAssociateCallback callback,
+ String callingPackage) throws RemoteException {
+ if (DEBUG) {
+ Log.i(LOG_TAG, "associate(request = " + request + ", callback = " + callback
+ + ", callingPackage = " + callingPackage + ")");
+ }
+ checkNotNull(request);
+ checkNotNull(callback);
+ final long callingIdentity = Binder.clearCallingIdentity();
+ try {
+ //TODO bindServiceAsUser
+ getContext().bindService(
+ new Intent().setComponent(SERVICE_TO_BIND_TO),
+ getServiceConnection(request, callback, callingPackage),
+ Context.BIND_AUTO_CREATE);
+ } finally {
+ Binder.restoreCallingIdentity(callingIdentity);
+ }
+ }
+ }
+
+ private ServiceConnection getServiceConnection(
+ final AssociationRequest<?> request,
+ final IOnAssociateCallback callback,
+ final String callingPackage) {
+ return new ServiceConnection() {
+ @Override
+ public void onServiceConnected(ComponentName name, IBinder service) {
+ if (DEBUG) {
+ Log.i(LOG_TAG,
+ "onServiceConnected(name = " + name + ", service = "
+ + service + ")");
+ }
+ try {
+ ICompanionDeviceManagerService.Stub
+ .asInterface(service)
+ .startDiscovery(
+ request,
+ getCallback(callingPackage, callback),
+ callingPackage);
+ } catch (RemoteException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public void onServiceDisconnected(ComponentName name) {
+ if (DEBUG) Log.i(LOG_TAG, "onServiceDisconnected(name = " + name + ")");
+ }
+ };
+ }
+
+ private IOnAssociateCallback.Stub getCallback(
+ String callingPackage,
+ IOnAssociateCallback propagateTo) {
+ return new IOnAssociateCallback.Stub() {
+
+ @Override
+ public void onSuccess(PendingIntent launcher)
+ throws RemoteException {
+ if (DEBUG) Log.i(LOG_TAG, "onSuccess(launcher = " + launcher + ")");
+ recordSpecialPriviledgesForPackage(callingPackage);
+ propagateTo.onSuccess(launcher);
+ }
+
+ @Override
+ public void onFailure(CharSequence reason) throws RemoteException {
+ if (DEBUG) Log.i(LOG_TAG, "onFailure()");
+ propagateTo.onFailure(reason);
+ }
+ };
+ }
+
+ void recordSpecialPriviledgesForPackage(String priviledgedPackage) {
+ //TODO Show dialog before recording notification access
+// final SettingStringHelper setting =
+// new SettingStringHelper(
+// getContext().getContentResolver(),
+// Settings.Secure.ENABLED_NOTIFICATION_LISTENERS,
+// Binder.getCallingUid());
+// setting.write(ColonDelimitedSet.OfStrings.add(setting.read(), priviledgedPackage));
+ }
+}
diff --git a/services/retaildemo/java/com/android/server/retaildemo/RetailDemoModeService.java b/services/retaildemo/java/com/android/server/retaildemo/RetailDemoModeService.java
index f30c466..f943ee2c 100644
--- a/services/retaildemo/java/com/android/server/retaildemo/RetailDemoModeService.java
+++ b/services/retaildemo/java/com/android/server/retaildemo/RetailDemoModeService.java
@@ -541,6 +541,8 @@
}
private void stopDemoMode() {
+ mDeviceInDemoMode = false;
+ mIsCarrierDemoMode = false;
mPreloadAppsInstaller = null;
mCameraIdsWithFlash = null;
mInjector.destroyWakeLock();
diff --git a/services/tests/notification/src/com/android/server/notification/NotificationComparatorTest.java b/services/tests/notification/src/com/android/server/notification/NotificationComparatorTest.java
index aa08b41..064ab0a 100644
--- a/services/tests/notification/src/com/android/server/notification/NotificationComparatorTest.java
+++ b/services/tests/notification/src/com/android/server/notification/NotificationComparatorTest.java
@@ -112,6 +112,7 @@
Notification n2 = new Notification.Builder(mContext)
.setCategory(Notification.CATEGORY_CALL)
.setFlag(Notification.FLAG_FOREGROUND_SERVICE, true)
+ .setColorized(true /* colorized */)
.build();
mRecordHighCall = new NotificationRecord(mContext, new StatusBarNotification(callPkg,
callPkg, 1, "highcall", callUid, callUid, n2,
@@ -186,10 +187,10 @@
final List<NotificationRecord> expected = new ArrayList<>();
expected.add(mRecordHighCall);
expected.add(mRecordDefaultMedia);
- expected.add(mRecordStarredContact);
- expected.add(mRecordContact);
expected.add(mRecordInlineReply);
expected.add(mRecordSms);
+ expected.add(mRecordStarredContact);
+ expected.add(mRecordContact);
expected.add(mRecordEmail);
expected.add(mRecordUrgent);
expected.add(mRecordCheater);
@@ -207,14 +208,19 @@
@Test
public void testMessaging() throws Exception {
NotificationComparator comp = new NotificationComparator(mContext);
- assertTrue(comp.isImportantMessaging(mRecordStarredContact));
- assertTrue(comp.isImportantMessaging(mRecordContact));
assertTrue(comp.isImportantMessaging(mRecordInlineReply));
assertTrue(comp.isImportantMessaging(mRecordSms));
assertFalse(comp.isImportantMessaging(mRecordEmail));
assertFalse(comp.isImportantMessaging(mRecordCheater));
}
+ @Test
+ public void testPeople() throws Exception {
+ NotificationComparator comp = new NotificationComparator(mContext);
+ assertTrue(comp.isImportantPeople(mRecordStarredContact));
+ assertTrue(comp.isImportantPeople(mRecordContact));
+ }
+
private NotificationChannel getDefaultChannel() {
return new NotificationChannel(NotificationChannel.DEFAULT_CHANNEL_ID, "name",
NotificationManager.IMPORTANCE_LOW);
diff --git a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
index 9645916..3f34d4f 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
@@ -76,6 +76,7 @@
import android.net.INetworkPolicyListener;
import android.net.INetworkStatsService;
import android.net.LinkProperties;
+import android.net.NetworkCapabilities;
import android.net.NetworkInfo;
import android.net.NetworkInfo.DetailedState;
import android.net.NetworkPolicy;
@@ -975,7 +976,8 @@
info.setDetailedState(DetailedState.CONNECTED, null, null);
final LinkProperties prop = new LinkProperties();
prop.setInterfaceName(TEST_IFACE);
- return new NetworkState(info, prop, null, null, null, TEST_SSID);
+ final NetworkCapabilities networkCapabilities = new NetworkCapabilities();
+ return new NetworkState(info, prop, networkCapabilities, null, null, TEST_SSID);
}
private void expectCurrentTime() throws Exception {
diff --git a/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java
index 152b9c9..fa9e9a8 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java
@@ -117,6 +117,8 @@
private static final String SSID = "ssid";
private static final String SSID_2 = "ssid_2";
private static final String SSID_3 = "ssid_3";
+ private static final ComponentName RECOMMENDATION_SERVICE_COMP =
+ new ComponentName("newPackageName", "newScoringServiceClass");
private static final ScoredNetwork SCORED_NETWORK =
new ScoredNetwork(new NetworkKey(new WifiKey(quote(SSID), "00:00:00:00:00:00")),
null /* rssiCurve*/);
@@ -124,7 +126,7 @@
new ScoredNetwork(new NetworkKey(new WifiKey(quote(SSID_2), "00:00:00:00:00:00")),
null /* rssiCurve*/);
private static final NetworkScorerAppData NEW_SCORER =
- new NetworkScorerAppData("newPackageName", 1, "newScoringServiceClass");
+ new NetworkScorerAppData(1, RECOMMENDATION_SERVICE_COMP);
@Mock private NetworkScorerAppManager mNetworkScorerAppManager;
@Mock private Context mContext;
@@ -203,8 +205,7 @@
verify(mContext).bindServiceAsUser(MockUtils.checkIntent(
new Intent(NetworkScoreManager.ACTION_RECOMMEND_NETWORKS)
- .setComponent(new ComponentName(NEW_SCORER.packageName,
- NEW_SCORER.recommendationServiceClassName))),
+ .setComponent(RECOMMENDATION_SERVICE_COMP)),
any(ServiceConnection.class),
eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE),
eq(UserHandle.SYSTEM));
@@ -657,7 +658,8 @@
when(mNetworkScorerAppManager.getActiveScorer()).thenReturn(NEW_SCORER);
mNetworkScoreService.systemRunning();
- assertEquals(NEW_SCORER.packageName, mNetworkScoreService.getActiveScorerPackage());
+ assertEquals(NEW_SCORER.getRecommendationServicePackageName(),
+ mNetworkScoreService.getActiveScorerPackage());
}
@Test
@@ -829,8 +831,6 @@
// "injects" the mock INetworkRecommendationProvider into the NetworkScoreService.
private void injectProvider() {
- final ComponentName componentName = new ComponentName(NEW_SCORER.packageName,
- NEW_SCORER.recommendationServiceClassName);
when(mNetworkScorerAppManager.getActiveScorer()).thenReturn(NEW_SCORER);
when(mContext.bindServiceAsUser(isA(Intent.class), isA(ServiceConnection.class), anyInt(),
isA(UserHandle.class))).thenAnswer(new Answer<Boolean>() {
@@ -840,7 +840,8 @@
when(mockBinder.queryLocalInterface(anyString()))
.thenReturn(mRecommendationProvider);
invocation.getArgumentAt(1, ServiceConnection.class)
- .onServiceConnected(componentName, mockBinder);
+ .onServiceConnected(NEW_SCORER.getRecommendationServiceComponent(),
+ mockBinder);
return true;
}
});
@@ -849,8 +850,8 @@
private void bindToScorer(boolean callerIsScorer) {
final int callingUid = callerIsScorer ? Binder.getCallingUid() : 0;
- NetworkScorerAppData appData = new NetworkScorerAppData(NEW_SCORER.packageName,
- callingUid, NEW_SCORER.recommendationServiceClassName);
+ NetworkScorerAppData appData =
+ new NetworkScorerAppData(callingUid, RECOMMENDATION_SERVICE_COMP);
when(mNetworkScorerAppManager.getActiveScorer()).thenReturn(appData);
when(mContext.bindServiceAsUser(isA(Intent.class), isA(ServiceConnection.class), anyInt(),
isA(UserHandle.class))).thenReturn(true);
diff --git a/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java
index 213fb27..e433b60 100644
--- a/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java
@@ -190,6 +190,8 @@
mAms.addAccountExplicitly(a31, "p31", null);
mAms.addAccountExplicitly(a32, "p32", null);
+ String[] list = new String[]{AccountManagerServiceTestFixtures.CALLER_PACKAGE};
+ when(mMockPackageManager.getPackagesForUid(anyInt())).thenReturn(list);
Account[] accounts = mAms.getAccounts(null, mContext.getOpPackageName());
Arrays.sort(accounts, new AccountSorter());
assertEquals(6, accounts.length);
@@ -306,6 +308,8 @@
@SmallTest
public void testRemovedAccountSync() throws Exception {
+ String[] list = new String[]{AccountManagerServiceTestFixtures.CALLER_PACKAGE};
+ when(mMockPackageManager.getPackagesForUid(anyInt())).thenReturn(list);
unlockSystemUser();
Account a1 = new Account("account1", AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1);
Account a2 = new Account("account2", AccountManagerServiceTestFixtures.ACCOUNT_TYPE_2);
@@ -347,6 +351,8 @@
// Start testing
unlockSystemUser();
+ String[] list = new String[]{AccountManagerServiceTestFixtures.CALLER_PACKAGE};
+ when(mMockPackageManager.getPackagesForUid(anyInt())).thenReturn(list);
Account[] accounts = mAms.getAccounts(null, mContext.getOpPackageName());
assertEquals("1 account should be migrated", 1, accounts.length);
assertEquals(PreNTestDatabaseHelper.ACCOUNT_NAME, accounts[0].name);
@@ -1048,7 +1054,6 @@
// Assert finishSessionAsUser added calling uid and pid into the sessionBundle
assertTrue(sessionBundle.containsKey(AccountManager.KEY_CALLER_UID));
assertTrue(sessionBundle.containsKey(AccountManager.KEY_CALLER_PID));
- // Assert App bundle data overrides sessionBundle data
assertEquals(sessionBundle.getString(
AccountManager.KEY_ANDROID_PACKAGE_NAME), "APCT.package");
@@ -1387,6 +1392,9 @@
@SmallTest
public void testRemoveAccountAsUserRemovalAllowed() throws Exception {
+ String[] list = new String[]{AccountManagerServiceTestFixtures.CALLER_PACKAGE};
+ when(mMockPackageManager.getPackagesForUid(anyInt())).thenReturn(list);
+
unlockSystemUser();
mAms.addAccountExplicitly(AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS, "p1", null);
Account[] addedAccounts =
diff --git a/services/tests/servicestests/src/com/android/server/accounts/AccountsDbTest.java b/services/tests/servicestests/src/com/android/server/accounts/AccountsDbTest.java
index 2e045ff..2cb8af4 100644
--- a/services/tests/servicestests/src/com/android/server/accounts/AccountsDbTest.java
+++ b/services/tests/servicestests/src/com/android/server/accounts/AccountsDbTest.java
@@ -355,49 +355,49 @@
@Test
public void testVisibilityFindSetDelete() {
long accId = 10;
- int uid1 = 100500;
- int uid2 = 100501;
+ String packageName1 = "com.example.one";
+ String packageName2 = "com.example.two";
Account account = new Account("name", "example.com");
- assertNull(mAccountsDb.findAccountVisibility(account, uid1));
+ assertNull(mAccountsDb.findAccountVisibility(account, packageName1));
mAccountsDb.insertDeAccount(account, accId);
- assertNull(mAccountsDb.findAccountVisibility(account, uid1));
- assertNull(mAccountsDb.findAccountVisibility(accId, uid1));
+ assertNull(mAccountsDb.findAccountVisibility(account, packageName1));
+ assertNull(mAccountsDb.findAccountVisibility(accId, packageName1));
- mAccountsDb.setAccountVisibility(accId, uid1, 1);
- assertEquals(mAccountsDb.findAccountVisibility(account, uid1), Integer.valueOf(1));
- assertEquals(mAccountsDb.findAccountVisibility(accId, uid1), Integer.valueOf(1));
+ mAccountsDb.setAccountVisibility(accId, packageName1, 1);
+ assertEquals(mAccountsDb.findAccountVisibility(account, packageName1), Integer.valueOf(1));
+ assertEquals(mAccountsDb.findAccountVisibility(accId, packageName1), Integer.valueOf(1));
- mAccountsDb.setAccountVisibility(accId, uid2, 2);
- assertEquals(mAccountsDb.findAccountVisibility(accId, uid2), Integer.valueOf(2));
+ mAccountsDb.setAccountVisibility(accId, packageName2, 2);
+ assertEquals(mAccountsDb.findAccountVisibility(accId, packageName2), Integer.valueOf(2));
- mAccountsDb.setAccountVisibility(accId, uid2, 3);
- assertEquals(mAccountsDb.findAccountVisibility(accId, uid2), Integer.valueOf(3));
+ mAccountsDb.setAccountVisibility(accId, packageName2, 3);
+ assertEquals(mAccountsDb.findAccountVisibility(accId, packageName2), Integer.valueOf(3));
- Map<Integer, Integer> vis = mAccountsDb.findAllVisibilityValuesForAccount(account);
+ Map<String, Integer> vis = mAccountsDb.findAllVisibilityValuesForAccount(account);
assertEquals(vis.size(), 2);
- assertEquals(vis.get(uid1), Integer.valueOf(1));
- assertEquals(vis.get(uid2), Integer.valueOf(3));
+ assertEquals(vis.get(packageName1), Integer.valueOf(1));
+ assertEquals(vis.get(packageName2), Integer.valueOf(3));
- assertTrue(mAccountsDb.deleteAccountVisibilityForUid(uid1));
- assertNull(mAccountsDb.findAccountVisibility(accId, uid1));
- assertFalse(mAccountsDb.deleteAccountVisibilityForUid(uid1)); // Already deleted.
+ assertTrue(mAccountsDb.deleteAccountVisibilityForPackage(packageName1));
+ assertNull(mAccountsDb.findAccountVisibility(accId, packageName1));
+ assertFalse(mAccountsDb.deleteAccountVisibilityForPackage(packageName1)); // 2nd attempt.
}
@Test
public void testVisibilityCleanupTrigger() {
long accId = 10;
- int uid1 = 100500;
+ String packageName1 = "com.example.one";
Account account = new Account("name", "example.com");
- assertNull(mAccountsDb.findAccountVisibility(account, uid1));
+ assertNull(mAccountsDb.findAccountVisibility(account, packageName1));
mAccountsDb.insertDeAccount(account, accId);
- assertNull(mAccountsDb.findAccountVisibility(account, uid1));
+ assertNull(mAccountsDb.findAccountVisibility(account, packageName1));
- mAccountsDb.setAccountVisibility(accId, uid1, 1);
- assertEquals(mAccountsDb.findAccountVisibility(accId, uid1), Integer.valueOf(1));
+ mAccountsDb.setAccountVisibility(accId, packageName1, 1);
+ assertEquals(mAccountsDb.findAccountVisibility(accId, packageName1), Integer.valueOf(1));
assertTrue(mAccountsDb.deleteDeAccount(accId)); // Trigger should remove visibility.
- assertNull(mAccountsDb.findAccountVisibility(account, uid1));
+ assertNull(mAccountsDb.findAccountVisibility(account, packageName1));
}
}
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
index f4e4e08..6fb65d5 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -2089,9 +2089,19 @@
assertTrue(dpm.getAffiliationIds(admin2).isEmpty());
assertFalse(dpm.isAffiliatedUser());
+ // Set affiliation ids again, then clear PO to check that the user becomes unaffiliated
+ dpm.setAffiliationIds(admin2, userAffiliationIds);
+ assertTrue(dpm.isAffiliatedUser());
+ dpm.clearProfileOwner(admin2);
+ assertFalse(dpm.isAffiliatedUser());
+
// Check that the system user remains affiliated.
mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
assertTrue(dpm.isAffiliatedUser());
+
+ // Clear the device owner - the user becomes unaffiliated.
+ clearDeviceOwner();
+ assertFalse(dpm.isAffiliatedUser());
}
public void testGetUserProvisioningState_defaultResult() {
@@ -3332,6 +3342,75 @@
MoreAsserts.assertEmpty(targetUsers);
}
+ public void testLockTaskPackagesAllowedForAffiliatedUsers() throws Exception {
+ // Setup a device owner.
+ mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
+ setupDeviceOwner();
+ // Lock task packages are updated when loading user data.
+ verify(mContext.iactivityManager)
+ .updateLockTaskPackages(eq(UserHandle.USER_SYSTEM), eq(new String[0]));
+
+ // Set up a managed profile managed by different package (package name shouldn't matter)
+ final int MANAGED_PROFILE_USER_ID = 15;
+ final int MANAGED_PROFILE_ADMIN_UID = UserHandle.getUid(MANAGED_PROFILE_USER_ID, 20456);
+ final ComponentName adminDifferentPackage =
+ new ComponentName("another.package", "whatever.class");
+ addManagedProfile(adminDifferentPackage, MANAGED_PROFILE_ADMIN_UID, admin2);
+ verify(mContext.iactivityManager)
+ .updateLockTaskPackages(eq(MANAGED_PROFILE_USER_ID), eq(new String[0]));
+
+ // The DO can still set lock task packages
+ mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
+ final String[] doPackages = {"doPackage1", "doPackage2"};
+ dpm.setLockTaskPackages(admin1, doPackages);
+ MoreAsserts.assertEquals(doPackages, dpm.getLockTaskPackages(admin1));
+ assertTrue(dpm.isLockTaskPermitted("doPackage1"));
+ assertFalse(dpm.isLockTaskPermitted("anotherPackage"));
+ verify(mContext.iactivityManager)
+ .updateLockTaskPackages(eq(UserHandle.USER_SYSTEM), eq(doPackages));
+
+ // Managed profile is unaffiliated - shouldn't be able to setLockTaskPackages.
+ mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID;
+ final String[] poPackages = {"poPackage1", "poPackage2"};
+ try {
+ dpm.setLockTaskPackages(adminDifferentPackage, poPackages);
+ fail("Didn't throw expected security exception.");
+ } catch (SecurityException expected) {
+ }
+ try {
+ dpm.getLockTaskPackages(adminDifferentPackage);
+ fail("Didn't throw expected security exception.");
+ } catch (SecurityException expected) {
+ }
+ assertFalse(dpm.isLockTaskPermitted("doPackage1"));
+
+ // Setting same affiliation ids
+ final List<String> userAffiliationIds = Arrays.asList("some-affiliation-id");
+ mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
+ dpm.setAffiliationIds(admin1, userAffiliationIds);
+
+ mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID;
+ dpm.setAffiliationIds(adminDifferentPackage, userAffiliationIds);
+
+ // Now the managed profile can set lock task packages.
+ dpm.setLockTaskPackages(adminDifferentPackage, poPackages);
+ MoreAsserts.assertEquals(poPackages, dpm.getLockTaskPackages(adminDifferentPackage));
+ assertTrue(dpm.isLockTaskPermitted("poPackage1"));
+ assertFalse(dpm.isLockTaskPermitted("doPackage2"));
+ verify(mContext.iactivityManager)
+ .updateLockTaskPackages(eq(MANAGED_PROFILE_USER_ID), eq(poPackages));
+
+ // Unaffiliate the profile, lock task mode no longer available on the profile.
+ dpm.setAffiliationIds(adminDifferentPackage, Collections.<String>emptyList());
+ assertFalse(dpm.isLockTaskPermitted("poPackage1"));
+ // Lock task packages cleared when loading user data and when the user becomes unaffiliated.
+ verify(mContext.iactivityManager, times(2))
+ .updateLockTaskPackages(eq(MANAGED_PROFILE_USER_ID), eq(new String[0]));
+
+ mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
+ assertTrue(dpm.isLockTaskPermitted("doPackage1"));
+ }
+
public void testIsDeviceManaged() throws Exception {
mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
setupDeviceOwner();
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java b/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java
index e30bd5d..e5640c7 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java
@@ -309,6 +309,7 @@
// Sanity check for InstrumentationInfo.
assertEquals(a.info.targetPackage, b.info.targetPackage);
+ assertEquals(a.info.targetProcess, b.info.targetProcess);
assertEquals(a.info.sourceDir, b.info.sourceDir);
assertEquals(a.info.publicSourceDir, b.info.publicSourceDir);
}
diff --git a/services/tests/servicestests/src/com/android/server/pm/UserDataPreparerTest.java b/services/tests/servicestests/src/com/android/server/pm/UserDataPreparerTest.java
new file mode 100644
index 0000000..7a676e25
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/pm/UserDataPreparerTest.java
@@ -0,0 +1,273 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.pm;
+
+import android.content.Context;
+import android.content.pm.UserInfo;
+import android.os.FileUtils;
+import android.os.storage.StorageManager;
+import android.os.storage.VolumeInfo;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.util.Arrays;
+import java.util.Collections;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Matchers.isNull;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+/**
+ * <p>Run with:<pre>
+ * m FrameworksServicesTests &&
+ * adb install \
+ * -r out/target/product/hammerhead/data/app/FrameworksServicesTests/FrameworksServicesTests.apk &&
+ * adb shell am instrument -e class com.android.server.pm.UserDataPreparerTest \
+ * -w com.android.frameworks.servicestests/android.support.test.runner.AndroidJUnitRunner
+ * </pre>
+ */
+@RunWith(AndroidJUnit4.class)
+@Presubmit
+@SmallTest
+public class UserDataPreparerTest {
+
+ private static final int TEST_USER_SERIAL = 1000;
+ private static final int TEST_USER_ID = 10;
+
+ private TestUserDataPreparer mUserDataPreparer;
+
+ @Mock
+ private StorageManager mStorageManagerMock;
+
+ @Mock
+ private Context mContextMock;
+
+ @Mock
+ private Installer mInstaller;
+
+ private Object mInstallLock;
+
+ @Before
+ public void setup() {
+ Context ctx = InstrumentationRegistry.getContext();
+ FileUtils.deleteContents(ctx.getCacheDir());
+ mInstallLock = new Object();
+ MockitoAnnotations.initMocks(this);
+ mUserDataPreparer = new TestUserDataPreparer(mInstaller, mInstallLock, mContextMock, false,
+ ctx.getCacheDir());
+ when(mContextMock.getSystemServiceName(StorageManager.class))
+ .thenReturn(Context.STORAGE_SERVICE);
+ when(mContextMock.getSystemService(eq(Context.STORAGE_SERVICE)))
+ .thenReturn(mStorageManagerMock);
+ VolumeInfo testVolume = new VolumeInfo("testuuid", VolumeInfo.TYPE_PRIVATE, null, null);
+ when(mStorageManagerMock.getWritablePrivateVolumes()).thenReturn(Arrays.asList(testVolume));
+ }
+
+ @Test
+ public void testPrepareUserData_De() throws Exception {
+ File userDeDir = mUserDataPreparer.getDataUserDeDirectory(null, TEST_USER_ID);
+ userDeDir.mkdirs();
+ File systemDeDir = mUserDataPreparer.getDataSystemDeDirectory(TEST_USER_ID);
+ systemDeDir.mkdirs();
+ mUserDataPreparer
+ .prepareUserData(TEST_USER_ID, TEST_USER_SERIAL, StorageManager.FLAG_STORAGE_DE);
+ verify(mStorageManagerMock).prepareUserStorage(isNull(String.class), eq(TEST_USER_ID),
+ eq(TEST_USER_SERIAL), eq(StorageManager.FLAG_STORAGE_DE));
+ verify(mInstaller).createUserData(isNull(String.class), eq(TEST_USER_ID),
+ eq(TEST_USER_SERIAL), eq(StorageManager.FLAG_STORAGE_DE));
+ int serialNumber = UserDataPreparer.getSerialNumber(userDeDir);
+ assertEquals(TEST_USER_SERIAL, serialNumber);
+ serialNumber = UserDataPreparer.getSerialNumber(systemDeDir);
+ assertEquals(TEST_USER_SERIAL, serialNumber);
+ }
+
+ @Test
+ public void testPrepareUserData_Ce() throws Exception {
+ File userCeDir = mUserDataPreparer.getDataUserCeDirectory(null, TEST_USER_ID);
+ userCeDir.mkdirs();
+ File systemCeDir = mUserDataPreparer.getDataSystemCeDirectory(TEST_USER_ID);
+ systemCeDir.mkdirs();
+ mUserDataPreparer
+ .prepareUserData(TEST_USER_ID, TEST_USER_SERIAL, StorageManager.FLAG_STORAGE_CE);
+ verify(mStorageManagerMock).prepareUserStorage(isNull(String.class), eq(TEST_USER_ID),
+ eq(TEST_USER_SERIAL), eq(StorageManager.FLAG_STORAGE_CE));
+ verify(mInstaller).createUserData(isNull(String.class), eq(TEST_USER_ID),
+ eq(TEST_USER_SERIAL), eq(StorageManager.FLAG_STORAGE_CE));
+ int serialNumber = UserDataPreparer.getSerialNumber(userCeDir);
+ assertEquals(TEST_USER_SERIAL, serialNumber);
+ serialNumber = UserDataPreparer.getSerialNumber(systemCeDir);
+ assertEquals(TEST_USER_SERIAL, serialNumber);
+ }
+
+ @Test
+ public void testDestroyUserData() throws Exception {
+ // Add file in CE
+ File systemCeDir = mUserDataPreparer.getDataSystemCeDirectory(TEST_USER_ID);
+ systemCeDir.mkdirs();
+ File ceFile = new File(systemCeDir, "file");
+ writeFile(ceFile, "-----" );
+ testDestroyUserData_De();
+ // CE directory should be preserved
+ assertEquals(Collections.singletonList(ceFile), Arrays.asList(FileUtils.listFilesOrEmpty(
+ systemCeDir)));
+
+ testDestroyUserData_Ce();
+
+ // Verify that testDir is empty
+ assertEquals(Collections.emptyList(), Arrays.asList(FileUtils.listFilesOrEmpty(
+ mUserDataPreparer.testDir)));
+ }
+
+ @Test
+ public void testDestroyUserData_De() throws Exception {
+ File systemDir = mUserDataPreparer.getUserSystemDirectory(TEST_USER_ID);
+ systemDir.mkdirs();
+ writeFile(new File(systemDir, "file"), "-----" );
+ File systemDeDir = mUserDataPreparer.getDataSystemDeDirectory(TEST_USER_ID);
+ systemDeDir.mkdirs();
+ writeFile(new File(systemDeDir, "file"), "-----" );
+ File miscDeDir = mUserDataPreparer.getDataMiscDeDirectory(TEST_USER_ID);
+ miscDeDir.mkdirs();
+ writeFile(new File(miscDeDir, "file"), "-----" );
+
+ mUserDataPreparer.destroyUserData(TEST_USER_ID, StorageManager.FLAG_STORAGE_DE);
+
+ verify(mInstaller).destroyUserData(isNull(String.class), eq(TEST_USER_ID),
+ eq(StorageManager.FLAG_STORAGE_DE));
+ verify(mStorageManagerMock).destroyUserStorage(isNull(String.class), eq(TEST_USER_ID),
+ eq(StorageManager.FLAG_STORAGE_DE));
+
+ assertEquals(Collections.emptyList(), Arrays.asList(FileUtils.listFilesOrEmpty(systemDir)));
+ assertEquals(Collections.emptyList(), Arrays.asList(FileUtils.listFilesOrEmpty(
+ systemDeDir)));
+ assertEquals(Collections.emptyList(), Arrays.asList(FileUtils.listFilesOrEmpty(
+ miscDeDir)));
+ }
+
+ @Test
+ public void testDestroyUserData_Ce() throws Exception {
+ File systemCeDir = mUserDataPreparer.getDataSystemCeDirectory(TEST_USER_ID);
+ systemCeDir.mkdirs();
+ writeFile(new File(systemCeDir, "file"), "-----" );
+ File miscCeDir = mUserDataPreparer.getDataMiscCeDirectory(TEST_USER_ID);
+ miscCeDir.mkdirs();
+ writeFile(new File(miscCeDir, "file"), "-----" );
+
+ mUserDataPreparer.destroyUserData(TEST_USER_ID, StorageManager.FLAG_STORAGE_CE);
+
+ verify(mInstaller).destroyUserData(isNull(String.class), eq(TEST_USER_ID),
+ eq(StorageManager.FLAG_STORAGE_CE));
+ verify(mStorageManagerMock).destroyUserStorage(isNull(String.class), eq(TEST_USER_ID),
+ eq(StorageManager.FLAG_STORAGE_CE));
+
+ assertEquals(Collections.emptyList(), Arrays.asList(FileUtils.listFilesOrEmpty(
+ systemCeDir)));
+ assertEquals(Collections.emptyList(), Arrays.asList(FileUtils.listFilesOrEmpty(
+ miscCeDir)));
+ }
+
+ @Test
+ public void testReconcileUsers() throws Exception {
+ UserInfo u1 = new UserInfo(1, "u1", 0);
+ UserInfo u2 = new UserInfo(2, "u2", 0);
+ File testDir = mUserDataPreparer.testDir;
+ File dir1 = new File(testDir, "1");
+ dir1.mkdirs();
+ File dir2 = new File(testDir, "2");
+ dir2.mkdirs();
+ File dir3 = new File(testDir, "3");
+ dir3.mkdirs();
+
+ mUserDataPreparer
+ .reconcileUsers(StorageManager.UUID_PRIVATE_INTERNAL, Arrays.asList(u1, u2),
+ Arrays.asList(dir1, dir2, dir3));
+ // Verify that user 3 data is removed
+ verify(mInstaller).destroyUserData(isNull(String.class), eq(3),
+ eq(StorageManager.FLAG_STORAGE_DE|StorageManager.FLAG_STORAGE_CE));
+ }
+
+ private static void writeFile(File file, String content) throws IOException {
+ try (FileOutputStream os = new FileOutputStream(file)) {
+ os.write(content.getBytes(Charset.defaultCharset()));
+ }
+ }
+
+ private static class TestUserDataPreparer extends UserDataPreparer {
+ File testDir;
+
+ TestUserDataPreparer(Installer installer, Object installLock, Context context,
+ boolean onlyCore, File testDir) {
+ super(installer, installLock, context, onlyCore);
+ this.testDir = testDir;
+ }
+
+ @Override
+ protected File getDataMiscCeDirectory(int userId) {
+ return new File(testDir, "misc_ce_" + userId);
+ }
+
+ @Override
+ protected File getDataSystemCeDirectory(int userId) {
+ return new File(testDir, "system_ce_" + userId);
+ }
+
+ @Override
+ protected File getDataMiscDeDirectory(int userId) {
+ return new File(testDir, "misc_de_" + userId);
+ }
+
+ @Override
+ protected File getUserSystemDirectory(int userId) {
+ return new File(testDir, "user_system_" + userId);
+ }
+
+ @Override
+ protected File getDataUserCeDirectory(String volumeUuid, int userId) {
+ return new File(testDir, "user_ce_" + userId);
+ }
+
+ @Override
+ protected File getDataSystemDeDirectory(int userId) {
+ return new File(testDir, "system_de_" + userId);
+ }
+
+ @Override
+ protected File getDataUserDeDirectory(String volumeUuid, int userId) {
+ return new File(testDir, "user_de_" + userId);
+ }
+
+ @Override
+ protected boolean isFileEncryptedEmulatedOnly() {
+ return false;
+ }
+ }
+
+}
diff --git a/services/tests/servicestests/src/com/android/server/webkit/WebViewUpdateServiceTest.java b/services/tests/servicestests/src/com/android/server/webkit/WebViewUpdateServiceTest.java
index 4c0f042..e4b74eb 100644
--- a/services/tests/servicestests/src/com/android/server/webkit/WebViewUpdateServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/webkit/WebViewUpdateServiceTest.java
@@ -16,6 +16,7 @@
package com.android.server.webkit;
+import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
@@ -24,6 +25,7 @@
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.Signature;
+import android.os.Build;
import android.os.Bundle;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;
@@ -174,6 +176,8 @@
// no flag means invalid
p.applicationInfo.metaData.putString(WEBVIEW_LIBRARY_FLAG, "blah");
}
+ // Default to this package being valid in terms of targetSdkVersion.
+ p.applicationInfo.targetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT;
return p;
}
@@ -1614,4 +1618,42 @@
checkPreparationPhasesForPackage(primaryPackage, 3);
assertTrue(mWebViewUpdateServiceImpl.isMultiProcessEnabled());
}
+
+ /**
+ * Ensure that packages with a targetSdkVersion targeting the current platform are valid, and
+ * that packages targeting an older version are not valid.
+ */
+ @Test
+ public void testTargetSdkVersionValidity() {
+ PackageInfo newSdkPackage = createPackageInfo("newTargetSdkPackage",
+ true /* enabled */, true /* valid */, true /* installed */);
+ newSdkPackage.applicationInfo.targetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT;
+ PackageInfo currentSdkPackage = createPackageInfo("currentTargetSdkPackage",
+ true /* enabled */, true /* valid */, true /* installed */);
+ currentSdkPackage.applicationInfo.targetSdkVersion = Build.VERSION_CODES.N_MR1+1;
+ PackageInfo oldSdkPackage = createPackageInfo("oldTargetSdkPackage",
+ true /* enabled */, true /* valid */, true /* installed */);
+ oldSdkPackage.applicationInfo.targetSdkVersion = Build.VERSION_CODES.N_MR1;
+
+ WebViewProviderInfo newSdkProviderInfo =
+ new WebViewProviderInfo(newSdkPackage.packageName, "", true, false, null);
+ WebViewProviderInfo currentSdkProviderInfo =
+ new WebViewProviderInfo(currentSdkPackage.packageName, "", true, false, null);
+ WebViewProviderInfo[] packages = new WebViewProviderInfo[] {
+ new WebViewProviderInfo(oldSdkPackage.packageName, "", true, false, null),
+ currentSdkProviderInfo, newSdkProviderInfo};
+ setupWithPackages(packages, true);
+;
+ mTestSystemImpl.setPackageInfo(newSdkPackage);
+ mTestSystemImpl.setPackageInfo(currentSdkPackage);
+ mTestSystemImpl.setPackageInfo(oldSdkPackage);
+
+ assertArrayEquals(new WebViewProviderInfo[]{currentSdkProviderInfo, newSdkProviderInfo},
+ mWebViewUpdateServiceImpl.getValidWebViewPackages());
+
+ runWebViewBootPreparationOnMainSync();
+
+ checkPreparationPhasesForPackage(currentSdkPackage.packageName,
+ 1 /* first preparation phase */);
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java b/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
index ec429a0..1e471e3 100644
--- a/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
+++ b/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
@@ -16,49 +16,7 @@
package com.android.server.wm;
-import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
-import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
-import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY;
-import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ABOVE_SUB_PANEL;
-import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
-import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA;
-import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY;
-import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_PANEL;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
-import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL;
-import static android.view.WindowManager.LayoutParams.TYPE_BOOT_PROGRESS;
-import static android.view.WindowManager.LayoutParams.TYPE_DISPLAY_OVERLAY;
-import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
-import static android.view.WindowManager.LayoutParams.TYPE_DRAG;
-import static android.view.WindowManager.LayoutParams.TYPE_DREAM;
-import static android.view.WindowManager.LayoutParams.TYPE_INPUT_CONSUMER;
-import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
-import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
-import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG;
-import static android.view.WindowManager.LayoutParams.TYPE_MAGNIFICATION_OVERLAY;
-import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
-import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL;
-import static android.view.WindowManager.LayoutParams.TYPE_PHONE;
-import static android.view.WindowManager.LayoutParams.TYPE_POINTER;
-import static android.view.WindowManager.LayoutParams.TYPE_PRESENTATION;
-import static android.view.WindowManager.LayoutParams.TYPE_PRIORITY_PHONE;
-import static android.view.WindowManager.LayoutParams.TYPE_PRIVATE_PRESENTATION;
-import static android.view.WindowManager.LayoutParams.TYPE_QS_DIALOG;
-import static android.view.WindowManager.LayoutParams.TYPE_SCREENSHOT;
-import static android.view.WindowManager.LayoutParams.TYPE_SEARCH_BAR;
-import static android.view.WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
-import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
-import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL;
-import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL;
-import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
-import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG;
-import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
-import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;
-import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
-import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION;
-import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION_STARTING;
-import static android.view.WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY;
-import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
import static org.mockito.Mockito.mock;
import android.annotation.Nullable;
@@ -70,12 +28,10 @@
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
-import android.util.Log;
import android.view.Display;
import android.view.IWindowManager;
import android.view.KeyEvent;
import android.view.WindowManager;
-import android.view.WindowManagerGlobal;
import android.view.WindowManagerPolicy;
import android.view.animation.Animation;
import android.os.PowerManagerInternal;
@@ -163,127 +119,6 @@
}
@Override
- public int windowTypeToLayerLw(int type) {
- // TODO: figure-out a good way to keep this in-sync with PhoneWindowManager...sigh!
- if (type >= FIRST_APPLICATION_WINDOW && type <= LAST_APPLICATION_WINDOW) {
- return 2;
- }
- switch (type) {
- case TYPE_PRESENTATION:
- case TYPE_PRIVATE_PRESENTATION:
- return 2;
- case TYPE_WALLPAPER:
- // wallpaper is at the bottom, though the window manager may move it.
- return 2;
- case TYPE_DOCK_DIVIDER:
- return 2;
- case TYPE_QS_DIALOG:
- return 2;
- case TYPE_PHONE:
- return 3;
- case TYPE_SEARCH_BAR:
- case TYPE_VOICE_INTERACTION_STARTING:
- return 4;
- case TYPE_VOICE_INTERACTION:
- // voice interaction layer is almost immediately above apps.
- return 5;
- case TYPE_INPUT_CONSUMER:
- return 6;
- case TYPE_SYSTEM_DIALOG:
- return 7;
- case TYPE_TOAST:
- // toasts and the plugged-in battery thing
- return 8;
- case TYPE_PRIORITY_PHONE:
- // SIM errors and unlock. Not sure if this really should be in a high layer.
- return 9;
- case TYPE_DREAM:
- // used for Dreams (screensavers with TYPE_DREAM windows)
- return 10;
- case TYPE_SYSTEM_ALERT:
- // like the ANR / app crashed dialogs
- return 11;
- case TYPE_INPUT_METHOD:
- // on-screen keyboards and other such input method user interfaces go here.
- return 12;
- case TYPE_INPUT_METHOD_DIALOG:
- // on-screen keyboards and other such input method user interfaces go here.
- return 13;
- case TYPE_STATUS_BAR_SUB_PANEL:
- return 15;
- case TYPE_STATUS_BAR:
- return 16;
- case TYPE_STATUS_BAR_PANEL:
- return 17;
- case TYPE_KEYGUARD_DIALOG:
- return 18;
- case TYPE_VOLUME_OVERLAY:
- // the on-screen volume indicator and controller shown when the user
- // changes the device volume
- return 19;
- case TYPE_SYSTEM_OVERLAY:
- // the on-screen volume indicator and controller shown when the user
- // changes the device volume
- return 20;
- case TYPE_NAVIGATION_BAR:
- // the navigation bar, if available, shows atop most things
- return 21;
- case TYPE_NAVIGATION_BAR_PANEL:
- // some panels (e.g. search) need to show on top of the navigation bar
- return 22;
- case TYPE_SCREENSHOT:
- // screenshot selection layer shouldn't go above system error, but it should cover
- // navigation bars at the very least.
- return 23;
- case TYPE_SYSTEM_ERROR:
- // system-level error dialogs
- return 24;
- case TYPE_MAGNIFICATION_OVERLAY:
- // used to highlight the magnified portion of a display
- return 25;
- case TYPE_DISPLAY_OVERLAY:
- // used to simulate secondary display devices
- return 26;
- case TYPE_DRAG:
- // the drag layer: input for drag-and-drop is associated with this window,
- // which sits above all other focusable windows
- return 27;
- case TYPE_ACCESSIBILITY_OVERLAY:
- // overlay put by accessibility services to intercept user interaction
- return 28;
- case TYPE_SECURE_SYSTEM_OVERLAY:
- return 29;
- case TYPE_BOOT_PROGRESS:
- return 30;
- case TYPE_POINTER:
- // the (mouse) pointer layer
- return 31;
- }
- Log.e(TAG, "Unknown window type: " + type);
- return 2;
- }
-
- @Override
- public int subWindowTypeToLayerLw(int type) {
- // TODO: figure-out a good way to keep this in-sync with PhoneWindowManager...
- switch (type) {
- case TYPE_APPLICATION_PANEL:
- case TYPE_APPLICATION_ATTACHED_DIALOG:
- return 1;
- case TYPE_APPLICATION_MEDIA:
- return -2;
- case TYPE_APPLICATION_MEDIA_OVERLAY:
- return -1;
- case TYPE_APPLICATION_SUB_PANEL:
- return 2;
- case TYPE_APPLICATION_ABOVE_SUB_PANEL:
- return 3;
- }
- Log.e(TAG, "Unknown sub-window type: " + type);
- return 0;
- }
-
- @Override
public int getMaxWallpaperLayer() {
return 0;
}
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowContainerTests.java b/services/tests/servicestests/src/com/android/server/wm/WindowContainerTests.java
index 4f740ac..4f9cd95 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowContainerTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowContainerTests.java
@@ -388,6 +388,32 @@
}
@Test
+ public void testGetOrientation_childSpecified() throws Exception {
+ testGetOrientation_childSpecifiedConfig(false, SCREEN_ORIENTATION_LANDSCAPE,
+ SCREEN_ORIENTATION_LANDSCAPE);
+ testGetOrientation_childSpecifiedConfig(false, SCREEN_ORIENTATION_UNSET,
+ SCREEN_ORIENTATION_UNSET);
+ }
+
+ private void testGetOrientation_childSpecifiedConfig(boolean childVisible, int childOrientation,
+ int expectedOrientation) {
+ final TestWindowContainerBuilder builder = new TestWindowContainerBuilder();
+ final TestWindowContainer root = builder.setLayer(0).build();
+ root.setFillsParent(true);
+
+ builder.setIsVisible(childVisible);
+
+ if (childOrientation != SCREEN_ORIENTATION_UNSET) {
+ builder.setOrientation(childOrientation);
+ }
+
+ final TestWindowContainer child1 = root.addChildWindow(builder);
+ child1.setFillsParent(true);
+
+ assertTrue(root.getOrientation() == expectedOrientation);
+ }
+
+ @Test
public void testGetOrientation_Unset() throws Exception {
final TestWindowContainerBuilder builder = new TestWindowContainerBuilder();
final TestWindowContainer root = builder.setLayer(0).setIsVisible(true).build();
@@ -407,18 +433,17 @@
invisibleChild1VisibleAndSet.setOrientation(SCREEN_ORIENTATION_LANDSCAPE);
// Landscape well because the container is visible and that is what we set on it above.
assertEquals(SCREEN_ORIENTATION_LANDSCAPE, invisibleChild1VisibleAndSet.getOrientation());
- // Unset because the container isn't visible even though it has a child that thinks it is
- // visible.
- assertEquals(SCREEN_ORIENTATION_UNSET, invisible.getOrientation());
- // Unspecified because we are visible and we didn't specify an orientation and there isn't
- // a visible child.
- assertEquals(SCREEN_ORIENTATION_UNSPECIFIED, root.getOrientation());
+ // Landscape because even though the container isn't visible it has a child that is
+ // specifying it can influence the orientation by being visible.
+ assertEquals(SCREEN_ORIENTATION_LANDSCAPE, invisible.getOrientation());
+ // Landscape because the grandchild is visible and therefore can participate.
+ assertEquals(SCREEN_ORIENTATION_LANDSCAPE, root.getOrientation());
builder.setIsVisible(true).setLayer(-3);
final TestWindowContainer visibleUnset = root.addChildWindow(builder);
visibleUnset.setOrientation(SCREEN_ORIENTATION_UNSET);
assertEquals(SCREEN_ORIENTATION_UNSET, visibleUnset.getOrientation());
- assertEquals(SCREEN_ORIENTATION_UNSPECIFIED, root.getOrientation());
+ assertEquals(SCREEN_ORIENTATION_LANDSCAPE, root.getOrientation());
}
@@ -690,6 +715,7 @@
private boolean mIsAnimating;
private boolean mIsVisible;
private boolean mFillsParent;
+ private Integer mOrientation;
private boolean mOnParentSetCalled;
@@ -708,11 +734,13 @@
return 1;
};
- TestWindowContainer(int layer, boolean isAnimating, boolean isVisible) {
+ TestWindowContainer(int layer, boolean isAnimating, boolean isVisible,
+ Integer orientation) {
mLayer = layer;
mIsAnimating = isAnimating;
mIsVisible = isVisible;
mFillsParent = true;
+ mOrientation = orientation;
}
TestWindowContainer getParentWindow() {
@@ -758,6 +786,11 @@
}
@Override
+ int getOrientation() {
+ return mOrientation != null ? mOrientation : super.getOrientation();
+ }
+
+ @Override
boolean fillsParent() {
return mFillsParent;
}
@@ -771,6 +804,7 @@
private int mLayer;
private boolean mIsAnimating;
private boolean mIsVisible;
+ private Integer mOrientation;
public TestWindowContainerBuilder() {
reset();
@@ -791,15 +825,21 @@
return this;
}
+ TestWindowContainerBuilder setOrientation(int orientation) {
+ mOrientation = orientation;
+ return this;
+ }
+
TestWindowContainerBuilder reset() {
mLayer = 0;
mIsAnimating = false;
mIsVisible = false;
+ mOrientation = null;
return this;
}
TestWindowContainer build() {
- return new TestWindowContainer(mLayer, mIsAnimating, mIsVisible);
+ return new TestWindowContainer(mLayer, mIsAnimating, mIsVisible, mOrientation);
}
}
}
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowFrameTests.java b/services/tests/servicestests/src/com/android/server/wm/WindowFrameTests.java
index 186884b..98ff0e2 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowFrameTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowFrameTests.java
@@ -57,7 +57,8 @@
final Task mTask;
boolean mDockedResizingForTest = false;
WindowStateWithTask(WindowManager.LayoutParams attrs, Task t) {
- super(sWm, null, mIWindow, mWindowToken, null, 0, 0, attrs, 0, 0);
+ super(sWm, null, mIWindow, mWindowToken, null, 0, 0, attrs, 0, 0,
+ false /* ownerCanAddInternalSystemWindow */);
mTask = t;
}
@@ -77,8 +78,7 @@
final Rect mInsetBounds = new Rect();
boolean mFullscreenForTest = true;
TaskWithBounds(Rect bounds) {
- super(0, mStubStack, 0, sWm, null, null, false, 0, false, false, new TaskDescription(),
- null);
+ super(0, mStubStack, 0, sWm, null, null, 0, false, false, new TaskDescription(), null);
mBounds = bounds;
}
@Override
@@ -106,7 +106,7 @@
sWm.mSystemDecorLayer = 10000;
mWindowToken = new WindowToken(sWm, new Binder(), 0, false,
- sWm.getDefaultDisplayContentLocked());
+ sWm.getDefaultDisplayContentLocked(), false /* ownerCanManageAppTokens */);
mStubStack = new TaskStack(sWm, 0);
}
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java
index c6f88ed..bc85017 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java
@@ -181,7 +181,7 @@
attrs.setTitle(name);
final WindowState w = new WindowState(sWm, sMockSession, sIWindow, token, parent, OP_NONE,
- 0, attrs, 0, 0);
+ 0, attrs, 0, 0, false /* ownerCanAddInternalSystemWindow */);
// TODO: Probably better to make this call in the WindowState ctor to avoid errors with
// adding it to the token...
token.addWindow(w);
@@ -201,8 +201,8 @@
/** Creates a {@link Task} and adds it to the specified {@link TaskStack}. */
static Task createTaskInStack(TaskStack stack, int userId) {
- final Task newTask = new Task(sNextTaskId++, stack, userId, sWm, null, EMPTY, false, 0,
- false, false, new TaskDescription(), null);
+ final Task newTask = new Task(sNextTaskId++, stack, userId, sWm, null, EMPTY, 0, false,
+ false, new TaskDescription(), null);
stack.addTask(newTask, POSITION_TOP);
return newTask;
}
@@ -223,7 +223,8 @@
}
TestWindowToken(int type, DisplayContent dc, boolean persistOnEmpty) {
- super(sWm, mock(IBinder.class), type, persistOnEmpty, dc);
+ super(sWm, mock(IBinder.class), type, persistOnEmpty, dc,
+ false /* ownerCanManageAppTokens */);
}
int getWindowsCount() {
@@ -282,12 +283,10 @@
private boolean mIsAnimating = false;
TestTask(int taskId, TaskStack stack, int userId, WindowManagerService service, Rect bounds,
- Configuration overrideConfig, boolean isOnTopLauncher, int resizeMode,
- boolean supportsPictureInPicture, boolean homeTask,
- TaskWindowContainerController controller) {
- super(taskId, stack, userId, service, bounds, overrideConfig, isOnTopLauncher,
- resizeMode, supportsPictureInPicture, homeTask, new TaskDescription(),
- controller);
+ Configuration overrideConfig, int resizeMode, boolean supportsPictureInPicture,
+ boolean homeTask, TaskWindowContainerController controller) {
+ super(taskId, stack, userId, service, bounds, overrideConfig, resizeMode,
+ supportsPictureInPicture, homeTask, new TaskDescription(), controller);
}
boolean shouldDeferRemoval() {
@@ -338,17 +337,16 @@
}
}, stackController, 0 /* userId */, null /* bounds */,
EMPTY /* overrideConfig*/, RESIZE_MODE_UNRESIZEABLE,
- false /* supportsPictureInPicture */, false /* homeTask*/,
- false /* isOnTopLauncher */, true /* toTop*/, true /* showForAllUsers */,
- new TaskDescription(), sWm);
+ false /* supportsPictureInPicture */, false /* homeTask*/, true /* toTop*/,
+ true /* showForAllUsers */, new TaskDescription(), sWm);
}
@Override
TestTask createTask(int taskId, TaskStack stack, int userId, Rect bounds,
Configuration overrideConfig, int resizeMode, boolean supportsPictureInPicture,
- boolean homeTask, boolean isOnTopLauncher, TaskDescription taskDescription) {
- return new TestTask(taskId, stack, userId, mService, bounds, overrideConfig,
- isOnTopLauncher, resizeMode, supportsPictureInPicture, homeTask, this);
+ boolean homeTask, TaskDescription taskDescription) {
+ return new TestTask(taskId, stack, userId, mService, bounds, overrideConfig, resizeMode,
+ supportsPictureInPicture, homeTask, this);
}
}
@@ -403,7 +401,8 @@
boolean resizeReported;
TestWindowState(WindowManager.LayoutParams attrs, WindowToken token) {
- super(sWm, sMockSession, sIWindow, token, null, OP_NONE, 0, attrs, 0, 0);
+ super(sWm, sMockSession, sIWindow, token, null, OP_NONE, 0, attrs, 0, 0,
+ false /* ownerCanAddInternalSystemWindow */);
}
@Override
diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
index 4d2c3b9..07b4ca1 100644
--- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
@@ -17,6 +17,7 @@
package com.android.server.usb;
import android.app.Notification;
+import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
@@ -134,6 +135,8 @@
private static final String BOOT_MODE_PROPERTY = "ro.bootmode";
+ private static final String ADB_NOTIFICATION_CHANNEL_ID_TV = "usbdevicemanager.adb.tv";
+
private UsbHandler mHandler;
private boolean mBootCompleted;
@@ -239,6 +242,16 @@
mNotificationManager = (NotificationManager)
mContext.getSystemService(Context.NOTIFICATION_SERVICE);
+ // Ensure that the notification channels are set up
+ if (isTv()) {
+ // TV-specific notification channel
+ mNotificationManager.createNotificationChannel(
+ new NotificationChannel(ADB_NOTIFICATION_CHANNEL_ID_TV,
+ mContext.getString(
+ com.android.internal.R.string.adb_debugging_notification_channel_tv),
+ NotificationManager.IMPORTANCE_HIGH));
+ }
+
// We do not show the USB notification if the primary volume supports mass storage.
// The legacy mass storage UI will be used instead.
boolean massStorageSupported = false;
@@ -325,6 +338,10 @@
}
}
+ private boolean isTv() {
+ return mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_LEANBACK);
+ }
+
private final class UsbHandler extends Handler {
// current USB state
@@ -928,9 +945,9 @@
CharSequence message = r.getText(
com.android.internal.R.string.adb_active_notification_message);
- Intent intent = Intent.makeRestartActivityTask(
- new ComponentName("com.android.settings",
- "com.android.settings.DevelopmentSettings"));
+ Intent intent = new Intent(Settings.ACTION_APPLICATION_DEVELOPMENT_SETTINGS);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+ | Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent pi = PendingIntent.getActivityAsUser(mContext, 0,
intent, 0, null, UserHandle.CURRENT);
@@ -947,6 +964,8 @@
.setContentText(message)
.setContentIntent(pi)
.setVisibility(Notification.VISIBILITY_PUBLIC)
+ .extend(new Notification.TvExtender()
+ .setChannel(ADB_NOTIFICATION_CHANNEL_ID_TV))
.build();
mAdbNotificationShown = true;
mNotificationManager.notifyAsUser(null, id, notification,
diff --git a/telecomm/java/android/telecom/ConnectionService.java b/telecomm/java/android/telecom/ConnectionService.java
index d0ccd55..6e10029 100644
--- a/telecomm/java/android/telecom/ConnectionService.java
+++ b/telecomm/java/android/telecom/ConnectionService.java
@@ -98,6 +98,7 @@
private static final String SESSION_ADD_CS_ADAPTER = "CS.aCSA";
private static final String SESSION_REMOVE_CS_ADAPTER = "CS.rCSA";
private static final String SESSION_CREATE_CONN = "CS.crCo";
+ private static final String SESSION_CREATE_CONN_FAILED = "CS.crCoF";
private static final String SESSION_ABORT = "CS.ab";
private static final String SESSION_ANSWER = "CS.an";
private static final String SESSION_ANSWER_VIDEO = "CS.anV";
@@ -142,6 +143,7 @@
private static final int MSG_PULL_EXTERNAL_CALL = 22;
private static final int MSG_SEND_CALL_EVENT = 23;
private static final int MSG_ON_EXTRAS_CHANGED = 24;
+ private static final int MSG_CREATE_CONNECTION_FAILED = 25;
private static Connection sNullConnection;
@@ -211,6 +213,25 @@
}
@Override
+ public void createConnectionFailed(
+ String callId,
+ ConnectionRequest request,
+ boolean isIncoming,
+ Session.Info sessionInfo) {
+ Log.startSession(sessionInfo, SESSION_CREATE_CONN_FAILED);
+ try {
+ SomeArgs args = SomeArgs.obtain();
+ args.arg1 = callId;
+ args.arg2 = request;
+ args.arg3 = Log.createSubsession();
+ args.argi1 = isIncoming ? 1 : 0;
+ mHandler.obtainMessage(MSG_CREATE_CONNECTION_FAILED, args).sendToTarget();
+ } finally {
+ Log.endSession();
+ }
+ }
+
+ @Override
public void abort(String callId, Session.Info sessionInfo) {
Log.startSession(sessionInfo, SESSION_ABORT);
try {
@@ -552,6 +573,35 @@
}
break;
}
+ case MSG_CREATE_CONNECTION_FAILED: {
+ SomeArgs args = (SomeArgs) msg.obj;
+ Log.continueSession((Session) args.arg3, SESSION_HANDLER +
+ SESSION_CREATE_CONN_FAILED);
+ try {
+ final String id = (String) args.arg1;
+ final ConnectionRequest request = (ConnectionRequest) args.arg2;
+ final boolean isIncoming = args.argi1 == 1;
+ if (!mAreAccountsInitialized) {
+ Log.d(this, "Enqueueing pre-init request %s", id);
+ mPreInitializationConnectionRequests.add(
+ new android.telecom.Logging.Runnable(
+ SESSION_HANDLER + SESSION_CREATE_CONN_FAILED + ".pICR",
+ null /*lock*/) {
+ @Override
+ public void loggedRun() {
+ createConnectionFailed(id, request, isIncoming);
+ }
+ }.prepare());
+ } else {
+ Log.i(this, "createConnectionFailed %s", id);
+ createConnectionFailed(id, request, isIncoming);
+ }
+ } finally {
+ args.recycle();
+ Log.endSession();
+ }
+ break;
+ }
case MSG_ABORT: {
SomeArgs args = (SomeArgs) msg.obj;
Log.continueSession((Session) args.arg2, SESSION_HANDLER + SESSION_ABORT);
@@ -1175,6 +1225,17 @@
}
}
+ private void createConnectionFailed(final String callId, final ConnectionRequest request,
+ boolean isIncoming) {
+
+ Log.i(this, "createConnectionFailed %s", callId);
+ if (isIncoming) {
+ onCreateIncomingConnectionFailed(request);
+ } else {
+ onCreateOutgoingConnectionFailed(request);
+ }
+ }
+
private void abort(String callId) {
Log.d(this, "abort %s", callId);
findConnectionForAction(callId, "abort").onAbort();
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index ba7b6a1..96070b8 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -1517,6 +1517,10 @@
* otherwise.
*/
public boolean isIncomingCallPermitted(PhoneAccountHandle phoneAccountHandle) {
+ if (phoneAccountHandle == null) {
+ return false;
+ }
+
ITelecomService service = getTelecomService();
if (service != null) {
try {
diff --git a/telecomm/java/com/android/internal/telecom/IConnectionService.aidl b/telecomm/java/com/android/internal/telecom/IConnectionService.aidl
index 8a27675..20feba7 100644
--- a/telecomm/java/com/android/internal/telecom/IConnectionService.aidl
+++ b/telecomm/java/com/android/internal/telecom/IConnectionService.aidl
@@ -46,6 +46,9 @@
boolean isUnknown,
in Session.Info sessionInfo);
+ void createConnectionFailed(String callId, in ConnectionRequest request, boolean isIncoming,
+ in Session.Info sessionInfo);
+
void abort(String callId, in Session.Info sessionInfo);
void answerVideo(String callId, int videoState, in Session.Info sessionInfo);
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 6c45233..3b15f1c 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -1173,6 +1173,9 @@
* and {@code NEW_CODE} is the new {@code ImsReasonInfo#CODE_*} which this combination of
* original code and message shall be remapped to.
*
+ * Note: If {@code *} is specified for the original code, any ImsReasonInfo with the matching
+ * {@code MESSAGE} will be remapped to {@code NEW_CODE}.
+ *
* Example: "501|call completion elsewhere|1014"
* When the {@link ImsReasonInfo#getCode()} is {@link ImsReasonInfo#CODE_USER_TERMINATED} and
* the {@link ImsReasonInfo#getExtraMessage()} is {@code "call completion elsewhere"},
diff --git a/telephony/java/android/telephony/DisconnectCause.java b/telephony/java/android/telephony/DisconnectCause.java
index 10cb7c9..e53e246 100644
--- a/telephony/java/android/telephony/DisconnectCause.java
+++ b/telephony/java/android/telephony/DisconnectCause.java
@@ -246,23 +246,18 @@
*/
public static final int IMEI_NOT_ACCEPTED = 58;
+ /**
+ * A call over WIFI was disconnected because the WIFI signal was lost or became too degraded to
+ * continue the call.
+ */
+ public static final int WIFI_LOST = 59;
+
//*********************************************************************************************
// When adding a disconnect type:
- // 1) Please assign the new type the next id value below.
- // 2) Increment the next id value below to a new value.
- // 3) Update MAXIMUM_VALID_VALUE to the new disconnect type.
- // 4) Update toString() with the newly added disconnect type.
- // 5) Update android.telecom.DisconnectCauseUtil with any mappings to a telecom.DisconnectCause.
- //
- // NextId: 59
+ // 1) Update toString() with the newly added disconnect type.
+ // 2) Update android.telecom.DisconnectCauseUtil with any mappings to a telecom.DisconnectCause.
//*********************************************************************************************
- /** Smallest valid value for call disconnect codes. */
- public static final int MINIMUM_VALID_VALUE = NOT_DISCONNECTED;
-
- /** Largest valid value for call disconnect codes. */
- public static final int MAXIMUM_VALID_VALUE = IMEI_NOT_ACCEPTED;
-
/** Private constructor to avoid class instantiation. */
private DisconnectCause() {
// Do nothing.
@@ -387,6 +382,8 @@
return "DIALED_CALL_FORWARDING_WHILE_ROAMING";
case IMEI_NOT_ACCEPTED:
return "IMEI_NOT_ACCEPTED";
+ case WIFI_LOST:
+ return "WIFI_LOST";
default:
return "INVALID: " + cause;
}
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 913da82..1b3aa8a 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -819,37 +819,6 @@
public static final String EVENT_DOWNGRADE_DATA_DISABLED =
"android.telephony.event.EVENT_DOWNGRADE_DATA_DISABLED";
- /**
- * Response codes for sim activation. Activation completed successfully.
- * @hide
- */
- @SystemApi
- public static final int SIM_ACTIVATION_RESULT_COMPLETE = 0;
- /**
- * Response codes for sim activation. Activation not supported (device has no SIM).
- * @hide
- */
- @SystemApi
- public static final int SIM_ACTIVATION_RESULT_NOT_SUPPORTED = 1;
- /**
- * Response codes for sim activation. Activation is in progress.
- * @hide
- */
- @SystemApi
- public static final int SIM_ACTIVATION_RESULT_IN_PROGRESS = 2;
- /**
- * Response codes for sim activation. Activation failed to complete.
- * @hide
- */
- @SystemApi
- public static final int SIM_ACTIVATION_RESULT_FAILED = 3;
- /**
- * Response codes for sim activation. Activation canceled by user.
- * @hide
- */
- @SystemApi
- public static final int SIM_ACTIVATION_RESULT_CANCELED = 4;
-
/* Visual voicemail protocols */
/**
diff --git a/telephony/java/com/android/ims/ImsReasonInfo.java b/telephony/java/com/android/ims/ImsReasonInfo.java
index 56b8822..c71808c 100644
--- a/telephony/java/com/android/ims/ImsReasonInfo.java
+++ b/telephony/java/com/android/ims/ImsReasonInfo.java
@@ -308,6 +308,11 @@
public static final int CODE_DATA_DISABLED = 1406;
/**
+ * Indicates a call was disconnected due to loss of wifi signal.
+ */
+ public static final int CODE_WIFI_LOST = 1407;
+
+ /**
* Network string error messages.
* mExtraMessage may have these values.
*/
diff --git a/telephony/java/com/android/internal/telephony/RILConstants.java b/telephony/java/com/android/internal/telephony/RILConstants.java
index 891b8a1a..5ee7e23 100644
--- a/telephony/java/com/android/internal/telephony/RILConstants.java
+++ b/telephony/java/com/android/internal/telephony/RILConstants.java
@@ -417,7 +417,7 @@
int RIL_UNSOL_RESPONSE_BASE = 1000;
int RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED = 1000;
int RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED = 1001;
- int RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED = 1002;
+ int RIL_UNSOL_RESPONSE_NETWORK_STATE_CHANGED = 1002;
int RIL_UNSOL_RESPONSE_NEW_SMS = 1003;
int RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT = 1004;
int RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM = 1005;
diff --git a/tests/TransitionTests/src/com/android/transitiontests/ListViewAddRemove.java b/tests/TransitionTests/src/com/android/transitiontests/ListViewAddRemove.java
index 6629770..251bf24 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/ListViewAddRemove.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/ListViewAddRemove.java
@@ -30,8 +30,9 @@
import android.transition.AutoTransition;
import android.transition.ChangeBounds;
import android.transition.Transition;
-import android.transition.TransitionSet;
+import android.transition.TransitionListenerAdapter;
import android.transition.TransitionManager;
+import android.transition.TransitionSet;
import java.util.ArrayList;
import java.util.HashMap;
@@ -84,7 +85,7 @@
fadeIn.setDuration(50);
noFadeIn.addTransition(new Fade(Fade.OUT)).addTransition(new ChangeBounds()).addTransition(fadeIn);
- myTransition.addListener(new Transition.TransitionListenerAdapter() {
+ myTransition.addListener(new TransitionListenerAdapter() {
@Override
public void onTransitionStart(Transition transition) {
System.out.println("---------ListView Tops: Before--------");
diff --git a/tests/net/java/android/net/ConnectivityManagerTest.java b/tests/net/java/android/net/ConnectivityManagerTest.java
new file mode 100644
index 0000000..b984bbf
--- /dev/null
+++ b/tests/net/java/android/net/ConnectivityManagerTest.java
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net;
+
+import static android.net.NetworkCapabilities.NET_CAPABILITY_CBS;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_DUN;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_FOTA;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_IMS;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_MMS;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_SUPL;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_TRUSTED;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_WIFI_P2P;
+import static android.net.NetworkCapabilities.TRANSPORT_BLUETOOTH;
+import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
+import static android.net.NetworkCapabilities.TRANSPORT_ETHERNET;
+import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import android.net.ConnectivityManager;
+import android.net.NetworkCapabilities;
+
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
+
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class ConnectivityManagerTest {
+ static NetworkCapabilities verifyNetworkCapabilities(
+ int legacyType, int transportType, int... capabilities) {
+ final NetworkCapabilities nc = ConnectivityManager.networkCapabilitiesForType(legacyType);
+ assertNotNull(nc);
+ assertTrue(nc.hasTransport(transportType));
+ for (int capability : capabilities) {
+ assertTrue(nc.hasCapability(capability));
+ }
+
+ return nc;
+ }
+
+ static void verifyUnrestrictedNetworkCapabilities(int legacyType, int transportType) {
+ verifyNetworkCapabilities(
+ legacyType,
+ transportType,
+ NET_CAPABILITY_INTERNET,
+ NET_CAPABILITY_NOT_RESTRICTED,
+ NET_CAPABILITY_NOT_VPN,
+ NET_CAPABILITY_TRUSTED);
+ }
+
+ static void verifyRestrictedMobileNetworkCapabilities(int legacyType, int capability) {
+ final NetworkCapabilities nc = verifyNetworkCapabilities(
+ legacyType,
+ TRANSPORT_CELLULAR,
+ capability,
+ NET_CAPABILITY_NOT_VPN,
+ NET_CAPABILITY_TRUSTED);
+
+ assertFalse(nc.hasCapability(NET_CAPABILITY_INTERNET));
+ assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED));
+ }
+
+ @Test
+ public void testNetworkCapabilitiesForTypeMobile() {
+ verifyUnrestrictedNetworkCapabilities(
+ ConnectivityManager.TYPE_MOBILE, TRANSPORT_CELLULAR);
+ }
+
+ @Test
+ public void testNetworkCapabilitiesForTypeMobileCbs() {
+ verifyRestrictedMobileNetworkCapabilities(
+ ConnectivityManager.TYPE_MOBILE_CBS, NET_CAPABILITY_CBS);
+ }
+
+ @Test
+ public void testNetworkCapabilitiesForTypeMobileDun() {
+ verifyRestrictedMobileNetworkCapabilities(
+ ConnectivityManager.TYPE_MOBILE_DUN, NET_CAPABILITY_DUN);
+ }
+
+ @Test
+ public void testNetworkCapabilitiesForTypeMobileFota() {
+ verifyRestrictedMobileNetworkCapabilities(
+ ConnectivityManager.TYPE_MOBILE_FOTA, NET_CAPABILITY_FOTA);
+ }
+
+ @Test
+ public void testNetworkCapabilitiesForTypeMobileHipri() {
+ verifyUnrestrictedNetworkCapabilities(
+ ConnectivityManager.TYPE_MOBILE_HIPRI, TRANSPORT_CELLULAR);
+ }
+
+ @Test
+ public void testNetworkCapabilitiesForTypeMobileIms() {
+ verifyRestrictedMobileNetworkCapabilities(
+ ConnectivityManager.TYPE_MOBILE_IMS, NET_CAPABILITY_IMS);
+ }
+
+ @Test
+ public void testNetworkCapabilitiesForTypeMobileMms() {
+ final NetworkCapabilities nc = verifyNetworkCapabilities(
+ ConnectivityManager.TYPE_MOBILE_MMS,
+ TRANSPORT_CELLULAR,
+ NET_CAPABILITY_MMS,
+ NET_CAPABILITY_NOT_VPN,
+ NET_CAPABILITY_TRUSTED);
+
+ assertFalse(nc.hasCapability(NET_CAPABILITY_INTERNET));
+ }
+
+ @Test
+ public void testNetworkCapabilitiesForTypeMobileSupl() {
+ final NetworkCapabilities nc = verifyNetworkCapabilities(
+ ConnectivityManager.TYPE_MOBILE_SUPL,
+ TRANSPORT_CELLULAR,
+ NET_CAPABILITY_SUPL,
+ NET_CAPABILITY_NOT_VPN,
+ NET_CAPABILITY_TRUSTED);
+
+ assertFalse(nc.hasCapability(NET_CAPABILITY_INTERNET));
+ }
+
+ @Test
+ public void testNetworkCapabilitiesForTypeWifi() {
+ verifyUnrestrictedNetworkCapabilities(
+ ConnectivityManager.TYPE_WIFI, TRANSPORT_WIFI);
+ }
+
+ @Test
+ public void testNetworkCapabilitiesForTypeWifiP2p() {
+ final NetworkCapabilities nc = verifyNetworkCapabilities(
+ ConnectivityManager.TYPE_WIFI_P2P,
+ TRANSPORT_WIFI,
+ NET_CAPABILITY_NOT_RESTRICTED, NET_CAPABILITY_NOT_VPN,
+ NET_CAPABILITY_TRUSTED, NET_CAPABILITY_WIFI_P2P);
+
+ assertFalse(nc.hasCapability(NET_CAPABILITY_INTERNET));
+ }
+
+ @Test
+ public void testNetworkCapabilitiesForTypeBluetooth() {
+ verifyUnrestrictedNetworkCapabilities(
+ ConnectivityManager.TYPE_BLUETOOTH, TRANSPORT_BLUETOOTH);
+ }
+
+ @Test
+ public void testNetworkCapabilitiesForTypeEthernet() {
+ verifyUnrestrictedNetworkCapabilities(
+ ConnectivityManager.TYPE_ETHERNET, TRANSPORT_ETHERNET);
+ }
+}
diff --git a/tests/net/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitorTest.java b/tests/net/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitorTest.java
index b8c739b..3ed56df 100644
--- a/tests/net/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitorTest.java
+++ b/tests/net/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitorTest.java
@@ -23,7 +23,13 @@
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
import android.content.Context;
import android.net.ConnectivityManager;
@@ -40,6 +46,7 @@
import org.junit.runner.RunWith;
import org.junit.Test;
import org.mockito.Mock;
+import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import java.util.HashMap;
@@ -64,7 +71,7 @@
reset(mContext);
reset(mCS);
- mCM = new TestConnectivityManager(mContext, mCS);
+ mCM = spy(new TestConnectivityManager(mContext, mCS));
mUNM = new UpstreamNetworkMonitor(null, EVENT_UNM_UPDATE, (ConnectivityManager) mCM);
}
@@ -126,6 +133,42 @@
}
@Test
+ public void testDuplicateMobileRequestsIgnored() throws Exception {
+ assertFalse(mUNM.mobileNetworkRequested());
+ assertEquals(0, mCM.requested.size());
+
+ mUNM.start();
+ verify(mCM, Mockito.times(1)).registerNetworkCallback(
+ any(NetworkRequest.class), any(NetworkCallback.class));
+ verify(mCM, Mockito.times(1)).registerDefaultNetworkCallback(any(NetworkCallback.class));
+ assertFalse(mUNM.mobileNetworkRequested());
+ assertEquals(0, mCM.requested.size());
+
+ mUNM.updateMobileRequiresDun(true);
+ mUNM.registerMobileNetworkRequest();
+ verify(mCM, Mockito.times(1)).requestNetwork(
+ any(NetworkRequest.class), any(NetworkCallback.class), anyInt(), anyInt());
+
+ assertTrue(mUNM.mobileNetworkRequested());
+ assertUpstreamTypeRequested(TYPE_MOBILE_DUN);
+ assertTrue(mCM.isDunRequested());
+
+ // Try a few things that must not result in any state change.
+ mUNM.registerMobileNetworkRequest();
+ mUNM.updateMobileRequiresDun(true);
+ mUNM.registerMobileNetworkRequest();
+
+ assertTrue(mUNM.mobileNetworkRequested());
+ assertUpstreamTypeRequested(TYPE_MOBILE_DUN);
+ assertTrue(mCM.isDunRequested());
+
+ mUNM.stop();
+ verify(mCM, times(3)).unregisterNetworkCallback(any(NetworkCallback.class));
+
+ verifyNoMoreInteractions(mCM);
+ }
+
+ @Test
public void testRequestsDunNetwork() throws Exception {
assertFalse(mUNM.mobileNetworkRequested());
assertEquals(0, mCM.requested.size());
@@ -149,7 +192,7 @@
}
@Test
- public void testUpdateMobileRequiredDun() throws Exception {
+ public void testUpdateMobileRequiresDun() throws Exception {
mUNM.start();
// Test going from no-DUN to DUN correctly re-registers callbacks.
@@ -180,7 +223,7 @@
mCM.legacyTypeMap.values().iterator().next());
}
- private static class TestConnectivityManager extends ConnectivityManager {
+ public static class TestConnectivityManager extends ConnectivityManager {
public Set<NetworkCallback> trackingDefault = new HashSet<>();
public Map<NetworkCallback, NetworkRequest> listening = new HashMap<>();
public Map<NetworkCallback, NetworkRequest> requested = new HashMap<>();
diff --git a/tools/aapt2/LoadedApk.cpp b/tools/aapt2/LoadedApk.cpp
index 3d466ef..3d7bd94 100644
--- a/tools/aapt2/LoadedApk.cpp
+++ b/tools/aapt2/LoadedApk.cpp
@@ -16,10 +16,15 @@
#include "LoadedApk.h"
+#include "ResourceValues.h"
+#include "ValueVisitor.h"
+#include "flatten/Archive.h"
+#include "flatten/TableFlattener.h"
+
namespace aapt {
-std::unique_ptr<LoadedApk> LoadedApk::LoadApkFromPath(
- IAaptContext* context, const StringPiece& path) {
+std::unique_ptr<LoadedApk> LoadedApk::LoadApkFromPath(IAaptContext* context,
+ const android::StringPiece& path) {
Source source(path);
std::string error;
std::unique_ptr<io::ZipFileCollection> apk =
@@ -53,4 +58,67 @@
return util::make_unique<LoadedApk>(source, std::move(apk), std::move(table));
}
+bool LoadedApk::WriteToArchive(IAaptContext* context, IArchiveWriter* writer) {
+ std::set<std::string> referenced_resources;
+ // List the files being referenced in the resource table.
+ for (auto& pkg : table_->packages) {
+ for (auto& type : pkg->types) {
+ for (auto& entry : type->entries) {
+ for (auto& config_value : entry->values) {
+ FileReference* file_ref = ValueCast<FileReference>(config_value->value.get());
+ if (file_ref) {
+ referenced_resources.insert(*file_ref->path);
+ }
+ }
+ }
+ }
+ }
+
+ std::unique_ptr<io::IFileCollectionIterator> iterator = apk_->Iterator();
+ while (iterator->HasNext()) {
+ io::IFile* file = iterator->Next();
+
+ std::string path = file->GetSource().path;
+ // The name of the path has the format "<zip-file-name>@<path-to-file>".
+ path = path.substr(path.find("@") + 1);
+
+ // Skip resources that are not referenced if requested.
+ if (path.find("res/") == 0 && referenced_resources.find(path) == referenced_resources.end()) {
+ if (context->IsVerbose()) {
+ context->GetDiagnostics()->Note(DiagMessage()
+ << "Removing resource '" << path << "' from APK.");
+ }
+ continue;
+ }
+
+ // The resource table needs to be reserialized since it might have changed.
+ if (path == "resources.arsc") {
+ BigBuffer buffer = BigBuffer(1024);
+ TableFlattener flattener(&buffer);
+ if (!flattener.Consume(context, table_.get())) {
+ return false;
+ }
+
+ if (!writer->StartEntry(path, ArchiveEntry::kAlign) || !writer->WriteEntry(buffer) ||
+ !writer->FinishEntry()) {
+ context->GetDiagnostics()->Error(DiagMessage()
+ << "Error when writing file '" << path << "' in APK.");
+ return false;
+ }
+ continue;
+ }
+
+ std::unique_ptr<io::IData> data = file->OpenAsData();
+ uint32_t compression_flags = file->WasCompressed() ? ArchiveEntry::kCompress : 0u;
+ if (!writer->StartEntry(path, compression_flags) ||
+ !writer->WriteEntry(data->data(), data->size()) || !writer->FinishEntry()) {
+ context->GetDiagnostics()->Error(DiagMessage()
+ << "Error when writing file '" << path << "' in APK.");
+ return false;
+ }
+ }
+
+ return true;
+}
+
} // namespace aapt
diff --git a/tools/aapt2/LoadedApk.h b/tools/aapt2/LoadedApk.h
index 0cc2d22..f8878d1 100644
--- a/tools/aapt2/LoadedApk.h
+++ b/tools/aapt2/LoadedApk.h
@@ -19,12 +19,11 @@
#include "androidfw/StringPiece.h"
-#include "io/ZipArchive.h"
#include "ResourceTable.h"
+#include "flatten/Archive.h"
+#include "io/ZipArchive.h"
#include "unflatten/BinaryResourceParser.h"
-using android::StringPiece;
-
namespace aapt {
/** Info about an APK loaded in memory. */
@@ -42,8 +41,14 @@
const Source& GetSource() { return source_; }
- static std::unique_ptr<LoadedApk> LoadApkFromPath(
- IAaptContext* context, const StringPiece& path);
+ /**
+ * Writes the APK on disk at the given path, while also removing the resource
+ * files that are not referenced in the resource table.
+ */
+ bool WriteToArchive(IAaptContext* context, IArchiveWriter* writer);
+
+ static std::unique_ptr<LoadedApk> LoadApkFromPath(IAaptContext* context,
+ const android::StringPiece& path);
private:
Source source_;
diff --git a/tools/aapt2/Main.cpp b/tools/aapt2/Main.cpp
index 3ed698b..227ffa3 100644
--- a/tools/aapt2/Main.cpp
+++ b/tools/aapt2/Main.cpp
@@ -25,7 +25,7 @@
static const char* sMajorVersion = "2";
// Update minor version whenever a feature or flag is added.
-static const char* sMinorVersion = "5";
+static const char* sMinorVersion = "6";
int PrintVersion() {
std::cerr << "Android Asset Packaging Tool (aapt) " << sMajorVersion << "."
diff --git a/tools/aapt2/Resource.cpp b/tools/aapt2/Resource.cpp
index fdabce1..35971e7 100644
--- a/tools/aapt2/Resource.cpp
+++ b/tools/aapt2/Resource.cpp
@@ -39,6 +39,8 @@
return "bool";
case ResourceType::kColor:
return "color";
+ case ResourceType::kConfigVarying:
+ return "configVarying";
case ResourceType::kDimen:
return "dimen";
case ResourceType::kDrawable:
@@ -85,6 +87,7 @@
{"^attr-private", ResourceType::kAttrPrivate},
{"bool", ResourceType::kBool},
{"color", ResourceType::kColor},
+ {"configVarying", ResourceType::kConfigVarying},
{"dimen", ResourceType::kDimen},
{"drawable", ResourceType::kDrawable},
{"font", ResourceType::kFont},
diff --git a/tools/aapt2/Resource.h b/tools/aapt2/Resource.h
index 1950ea3..4d915d9 100644
--- a/tools/aapt2/Resource.h
+++ b/tools/aapt2/Resource.h
@@ -44,6 +44,11 @@
kAttrPrivate,
kBool,
kColor,
+
+ // Not really a type, but it shows up in some CTS tests and
+ // we need to continue respecting it.
+ kConfigVarying,
+
kDimen,
kDrawable,
kFont,
diff --git a/tools/aapt2/ResourceParser.cpp b/tools/aapt2/ResourceParser.cpp
index 79379fe..1c750c6 100644
--- a/tools/aapt2/ResourceParser.cpp
+++ b/tools/aapt2/ResourceParser.cpp
@@ -338,50 +338,52 @@
using BagParseFunc = std::function<bool(ResourceParser*, xml::XmlPullParser*,
ParsedResource*)>;
- static const auto elToItemMap =
- ImmutableMap<std::string, ItemTypeFormat>::CreatePreSorted({
- {"bool", {ResourceType::kBool, android::ResTable_map::TYPE_BOOLEAN}},
- {"color", {ResourceType::kColor, android::ResTable_map::TYPE_COLOR}},
- {"dimen",
- {ResourceType::kDimen, android::ResTable_map::TYPE_FLOAT |
- android::ResTable_map::TYPE_FRACTION |
- android::ResTable_map::TYPE_DIMENSION}},
- {"drawable",
- {ResourceType::kDrawable, android::ResTable_map::TYPE_COLOR}},
- {"fraction",
- {ResourceType::kFraction,
- android::ResTable_map::TYPE_FLOAT |
- android::ResTable_map::TYPE_FRACTION |
- android::ResTable_map::TYPE_DIMENSION}},
- {"integer",
- {ResourceType::kInteger, android::ResTable_map::TYPE_INTEGER}},
- {"string",
- {ResourceType::kString, android::ResTable_map::TYPE_STRING}},
- });
+ static const auto elToItemMap = ImmutableMap<std::string, ItemTypeFormat>::CreatePreSorted({
+ {"bool", {ResourceType::kBool, android::ResTable_map::TYPE_BOOLEAN}},
+ {"color", {ResourceType::kColor, android::ResTable_map::TYPE_COLOR}},
+ {"configVarying", {ResourceType::kConfigVarying, android::ResTable_map::TYPE_ANY}},
+ {"dimen",
+ {ResourceType::kDimen,
+ android::ResTable_map::TYPE_FLOAT | android::ResTable_map::TYPE_FRACTION |
+ android::ResTable_map::TYPE_DIMENSION}},
+ {"drawable", {ResourceType::kDrawable, android::ResTable_map::TYPE_COLOR}},
+ {"fraction",
+ {ResourceType::kFraction,
+ android::ResTable_map::TYPE_FLOAT | android::ResTable_map::TYPE_FRACTION |
+ android::ResTable_map::TYPE_DIMENSION}},
+ {"integer", {ResourceType::kInteger, android::ResTable_map::TYPE_INTEGER}},
+ {"string", {ResourceType::kString, android::ResTable_map::TYPE_STRING}},
+ });
- static const auto elToBagMap =
- ImmutableMap<std::string, BagParseFunc>::CreatePreSorted({
- {"add-resource", std::mem_fn(&ResourceParser::ParseAddResource)},
- {"array", std::mem_fn(&ResourceParser::ParseArray)},
- {"attr", std::mem_fn(&ResourceParser::ParseAttr)},
- {"declare-styleable",
- std::mem_fn(&ResourceParser::ParseDeclareStyleable)},
- {"integer-array", std::mem_fn(&ResourceParser::ParseIntegerArray)},
- {"java-symbol", std::mem_fn(&ResourceParser::ParseSymbol)},
- {"plurals", std::mem_fn(&ResourceParser::ParsePlural)},
- {"public", std::mem_fn(&ResourceParser::ParsePublic)},
- {"public-group", std::mem_fn(&ResourceParser::ParsePublicGroup)},
- {"string-array", std::mem_fn(&ResourceParser::ParseStringArray)},
- {"style", std::mem_fn(&ResourceParser::ParseStyle)},
- {"symbol", std::mem_fn(&ResourceParser::ParseSymbol)},
- });
+ static const auto elToBagMap = ImmutableMap<std::string, BagParseFunc>::CreatePreSorted({
+ {"add-resource", std::mem_fn(&ResourceParser::ParseAddResource)},
+ {"array", std::mem_fn(&ResourceParser::ParseArray)},
+ {"attr", std::mem_fn(&ResourceParser::ParseAttr)},
+ {"configVarying",
+ std::bind(&ResourceParser::ParseStyle, std::placeholders::_1, ResourceType::kConfigVarying,
+ std::placeholders::_2, std::placeholders::_3)},
+ {"declare-styleable", std::mem_fn(&ResourceParser::ParseDeclareStyleable)},
+ {"integer-array", std::mem_fn(&ResourceParser::ParseIntegerArray)},
+ {"java-symbol", std::mem_fn(&ResourceParser::ParseSymbol)},
+ {"plurals", std::mem_fn(&ResourceParser::ParsePlural)},
+ {"public", std::mem_fn(&ResourceParser::ParsePublic)},
+ {"public-group", std::mem_fn(&ResourceParser::ParsePublicGroup)},
+ {"string-array", std::mem_fn(&ResourceParser::ParseStringArray)},
+ {"style", std::bind(&ResourceParser::ParseStyle, std::placeholders::_1, ResourceType::kStyle,
+ std::placeholders::_2, std::placeholders::_3)},
+ {"symbol", std::mem_fn(&ResourceParser::ParseSymbol)},
+ });
std::string resource_type = parser->element_name();
// The value format accepted for this resource.
uint32_t resource_format = 0u;
+ bool can_be_item = true;
+ bool can_be_bag = true;
if (resource_type == "item") {
+ can_be_bag = false;
+
// Items have their type encoded in the type attribute.
if (Maybe<StringPiece> maybe_type =
xml::FindNonEmptyAttribute(parser, "type")) {
@@ -406,6 +408,17 @@
return false;
}
}
+ } else if (resource_type == "bag") {
+ can_be_item = false;
+
+ // Bags have their type encoded in the type attribute.
+ if (Maybe<StringPiece> maybe_type = xml::FindNonEmptyAttribute(parser, "type")) {
+ resource_type = maybe_type.value().to_string();
+ } else {
+ diag_->Error(DiagMessage(source_.WithLine(parser->line_number()))
+ << "<bag> must have a 'type' attribute");
+ return false;
+ }
}
// Get the name of the resource. This will be checked later, because not all
@@ -426,36 +439,61 @@
return true;
}
- const auto item_iter = elToItemMap.find(resource_type);
- if (item_iter != elToItemMap.end()) {
- // This is an item, record its type and format and start parsing.
+ if (can_be_item) {
+ const auto item_iter = elToItemMap.find(resource_type);
+ if (item_iter != elToItemMap.end()) {
+ // This is an item, record its type and format and start parsing.
- if (!maybe_name) {
- diag_->Error(DiagMessage(out_resource->source)
- << "<" << parser->element_name()
- << "> missing 'name' attribute");
- return false;
+ if (!maybe_name) {
+ diag_->Error(DiagMessage(out_resource->source)
+ << "<" << parser->element_name() << "> missing 'name' attribute");
+ return false;
+ }
+
+ out_resource->name.type = item_iter->second.type;
+ out_resource->name.entry = maybe_name.value().to_string();
+
+ // Only use the implicit format for this type if it wasn't overridden.
+ if (!resource_format) {
+ resource_format = item_iter->second.format;
+ }
+
+ if (!ParseItem(parser, out_resource, resource_format)) {
+ return false;
+ }
+ return true;
}
-
- out_resource->name.type = item_iter->second.type;
- out_resource->name.entry = maybe_name.value().to_string();
-
- // Only use the implicit format for this type if it wasn't overridden.
- if (!resource_format) {
- resource_format = item_iter->second.format;
- }
-
- if (!ParseItem(parser, out_resource, resource_format)) {
- return false;
- }
- return true;
}
// This might be a bag or something.
- const auto bag_iter = elToBagMap.find(resource_type);
- if (bag_iter != elToBagMap.end()) {
- // Ensure we have a name (unless this is a <public-group>).
- if (resource_type != "public-group") {
+ if (can_be_bag) {
+ const auto bag_iter = elToBagMap.find(resource_type);
+ if (bag_iter != elToBagMap.end()) {
+ // Ensure we have a name (unless this is a <public-group>).
+ if (resource_type != "public-group") {
+ if (!maybe_name) {
+ diag_->Error(DiagMessage(out_resource->source)
+ << "<" << parser->element_name() << "> missing 'name' attribute");
+ return false;
+ }
+
+ out_resource->name.entry = maybe_name.value().to_string();
+ }
+
+ // Call the associated parse method. The type will be filled in by the
+ // parse func.
+ if (!bag_iter->second(this, parser, out_resource)) {
+ return false;
+ }
+ return true;
+ }
+ }
+
+ if (can_be_item) {
+ // Try parsing the elementName (or type) as a resource. These shall only be
+ // resources like 'layout' or 'xml' and they can only be references.
+ const ResourceType* parsed_type = ParseResourceType(resource_type);
+ if (parsed_type) {
if (!maybe_name) {
diag_->Error(DiagMessage(out_resource->source)
<< "<" << parser->element_name()
@@ -463,39 +501,16 @@
return false;
}
+ out_resource->name.type = *parsed_type;
out_resource->name.entry = maybe_name.value().to_string();
+ out_resource->value = ParseXml(parser, android::ResTable_map::TYPE_REFERENCE, kNoRawString);
+ if (!out_resource->value) {
+ diag_->Error(DiagMessage(out_resource->source)
+ << "invalid value for type '" << *parsed_type << "'. Expected a reference");
+ return false;
+ }
+ return true;
}
-
- // Call the associated parse method. The type will be filled in by the
- // parse func.
- if (!bag_iter->second(this, parser, out_resource)) {
- return false;
- }
- return true;
- }
-
- // Try parsing the elementName (or type) as a resource. These shall only be
- // resources like 'layout' or 'xml' and they can only be references.
- const ResourceType* parsed_type = ParseResourceType(resource_type);
- if (parsed_type) {
- if (!maybe_name) {
- diag_->Error(DiagMessage(out_resource->source)
- << "<" << parser->element_name()
- << "> missing 'name' attribute");
- return false;
- }
-
- out_resource->name.type = *parsed_type;
- out_resource->name.entry = maybe_name.value().to_string();
- out_resource->value =
- ParseXml(parser, android::ResTable_map::TYPE_REFERENCE, kNoRawString);
- if (!out_resource->value) {
- diag_->Error(DiagMessage(out_resource->source)
- << "invalid value for type '" << *parsed_type
- << "'. Expected a reference");
- return false;
- }
- return true;
}
diag_->Warn(DiagMessage(out_resource->source)
@@ -1048,9 +1063,9 @@
return true;
}
-bool ResourceParser::ParseStyle(xml::XmlPullParser* parser,
+bool ResourceParser::ParseStyle(const ResourceType type, xml::XmlPullParser* parser,
ParsedResource* out_resource) {
- out_resource->name.type = ResourceType::kStyle;
+ out_resource->name.type = type;
std::unique_ptr<Style> style = util::make_unique<Style>();
diff --git a/tools/aapt2/ResourceParser.h b/tools/aapt2/ResourceParser.h
index c12dacf..cc0fa26 100644
--- a/tools/aapt2/ResourceParser.h
+++ b/tools/aapt2/ResourceParser.h
@@ -102,7 +102,8 @@
bool weak);
Maybe<Attribute::Symbol> ParseEnumOrFlagItem(xml::XmlPullParser* parser,
const android::StringPiece& tag);
- bool ParseStyle(xml::XmlPullParser* parser, ParsedResource* out_resource);
+ bool ParseStyle(const ResourceType type, xml::XmlPullParser* parser,
+ ParsedResource* out_resource);
bool ParseStyleItem(xml::XmlPullParser* parser, Style* style);
bool ParseDeclareStyleable(xml::XmlPullParser* parser,
ParsedResource* out_resource);
diff --git a/tools/aapt2/ResourceParser_test.cpp b/tools/aapt2/ResourceParser_test.cpp
index 5762fb0..cf901da 100644
--- a/tools/aapt2/ResourceParser_test.cpp
+++ b/tools/aapt2/ResourceParser_test.cpp
@@ -719,4 +719,23 @@
EXPECT_EQ(uint32_t(android::Res_value::TYPE_FLOAT), val->value.dataType);
}
+TEST_F(ResourceParserTest, ParseConfigVaryingItem) {
+ std::string input = R"EOF(<item name="foo" type="configVarying">Hey</item>)EOF";
+ ASSERT_TRUE(TestParse(input));
+ ASSERT_NE(nullptr, test::GetValue<String>(&table_, "configVarying/foo"));
+}
+
+TEST_F(ResourceParserTest, ParseBagElement) {
+ std::string input =
+ R"EOF(<bag name="bag" type="configVarying"><item name="test">Hello!</item></bag>)EOF";
+ ASSERT_TRUE(TestParse(input));
+
+ Style* val = test::GetValue<Style>(&table_, "configVarying/bag");
+ ASSERT_NE(nullptr, val);
+
+ ASSERT_EQ(1u, val->entries.size());
+ EXPECT_EQ(Reference(test::ParseNameOrDie("attr/test")), val->entries[0].key);
+ EXPECT_NE(nullptr, ValueCast<RawString>(val->entries[0].value.get()));
+}
+
} // namespace aapt
diff --git a/tools/aapt2/Resource_test.cpp b/tools/aapt2/Resource_test.cpp
index 6acb4d3..ad4e3ce 100644
--- a/tools/aapt2/Resource_test.cpp
+++ b/tools/aapt2/Resource_test.cpp
@@ -49,6 +49,10 @@
ASSERT_NE(type, nullptr);
EXPECT_EQ(*type, ResourceType::kColor);
+ type = ParseResourceType("configVarying");
+ ASSERT_NE(type, nullptr);
+ EXPECT_EQ(*type, ResourceType::kConfigVarying);
+
type = ParseResourceType("dimen");
ASSERT_NE(type, nullptr);
EXPECT_EQ(*type, ResourceType::kDimen);
diff --git a/tools/aapt2/io/File.h b/tools/aapt2/io/File.h
index 3d5b5b1..1ef9743 100644
--- a/tools/aapt2/io/File.h
+++ b/tools/aapt2/io/File.h
@@ -63,6 +63,11 @@
IFile* CreateFileSegment(size_t offset, size_t len);
+ /** Returns whether the file was compressed before it was stored in memory. */
+ virtual bool WasCompressed() {
+ return false;
+ }
+
private:
// Any segments created from this IFile need to be owned by this IFile, so
// keep them
diff --git a/tools/aapt2/io/ZipArchive.cpp b/tools/aapt2/io/ZipArchive.cpp
index 62b436f..6494d2d 100644
--- a/tools/aapt2/io/ZipArchive.cpp
+++ b/tools/aapt2/io/ZipArchive.cpp
@@ -59,6 +59,10 @@
const Source& ZipFile::GetSource() const { return source_; }
+bool ZipFile::WasCompressed() {
+ return zip_entry_.method != kCompressStored;
+}
+
ZipFileCollectionIterator::ZipFileCollectionIterator(
ZipFileCollection* collection)
: current_(collection->files_.begin()), end_(collection->files_.end()) {}
@@ -66,7 +70,7 @@
bool ZipFileCollectionIterator::HasNext() { return current_ != end_; }
IFile* ZipFileCollectionIterator::Next() {
- IFile* result = current_->second.get();
+ IFile* result = current_->get();
++current_;
return result;
}
@@ -110,8 +114,10 @@
std::string(reinterpret_cast<const char*>(zip_entry_name.name),
zip_entry_name.name_length);
std::string nested_path = path.to_string() + "@" + zip_entry_path;
- collection->files_[zip_entry_path] = util::make_unique<ZipFile>(
- collection->handle_, zip_data, Source(nested_path));
+ std::unique_ptr<IFile> file =
+ util::make_unique<ZipFile>(collection->handle_, zip_data, Source(nested_path));
+ collection->files_by_name_[zip_entry_path] = file.get();
+ collection->files_.push_back(std::move(file));
}
if (result != -1) {
@@ -122,9 +128,9 @@
}
IFile* ZipFileCollection::FindFile(const StringPiece& path) {
- auto iter = files_.find(path.to_string());
- if (iter != files_.end()) {
- return iter->second.get();
+ auto iter = files_by_name_.find(path.to_string());
+ if (iter != files_by_name_.end()) {
+ return iter->second;
}
return nullptr;
}
diff --git a/tools/aapt2/io/ZipArchive.h b/tools/aapt2/io/ZipArchive.h
index 634adad..56c74e3 100644
--- a/tools/aapt2/io/ZipArchive.h
+++ b/tools/aapt2/io/ZipArchive.h
@@ -40,6 +40,7 @@
std::unique_ptr<IData> OpenAsData() override;
const Source& GetSource() const override;
+ bool WasCompressed() override;
private:
ZipArchiveHandle zip_handle_;
@@ -57,7 +58,7 @@
io::IFile* Next() override;
private:
- std::map<std::string, std::unique_ptr<IFile>>::const_iterator current_, end_;
+ std::vector<std::unique_ptr<IFile>>::const_iterator current_, end_;
};
/**
@@ -78,7 +79,8 @@
ZipFileCollection();
ZipArchiveHandle handle_;
- std::map<std::string, std::unique_ptr<IFile>> files_;
+ std::vector<std::unique_ptr<IFile>> files_;
+ std::map<std::string, IFile*> files_by_name_;
};
} // namespace io
diff --git a/tools/aapt2/link/ManifestFixer.cpp b/tools/aapt2/link/ManifestFixer.cpp
index e5eaf2f..b4cf4f8 100644
--- a/tools/aapt2/link/ManifestFixer.cpp
+++ b/tools/aapt2/link/ManifestFixer.cpp
@@ -111,6 +111,36 @@
return true;
}
+// Checks that <uses-feature> has android:glEsVersion or android:name, not both (or neither).
+static bool VerifyUsesFeature(xml::Element* el, SourcePathDiagnostics* diag) {
+ bool has_name = false;
+ if (xml::Attribute* attr = el->FindAttribute(xml::kSchemaAndroid, "name")) {
+ if (attr->value.empty()) {
+ diag->Error(DiagMessage(el->line_number)
+ << "android:name in <uses-feature> must not be empty");
+ return false;
+ }
+ has_name = true;
+ }
+
+ bool has_gl_es_version = false;
+ if (xml::Attribute* attr = el->FindAttribute(xml::kSchemaAndroid, "glEsVersion")) {
+ if (has_name) {
+ diag->Error(DiagMessage(el->line_number)
+ << "cannot define both android:name and android:glEsVersion in <uses-feature>");
+ return false;
+ }
+ has_gl_es_version = true;
+ }
+
+ if (!has_name && !has_gl_es_version) {
+ diag->Error(DiagMessage(el->line_number)
+ << "<uses-feature> must have either android:name or android:glEsVersion attribute");
+ return false;
+ }
+ return true;
+}
+
bool ManifestFixer::BuildRules(xml::XmlActionExecutor* executor,
IDiagnostics* diag) {
// First verify some options.
@@ -134,15 +164,25 @@
}
}
- // Common intent-filter actions.
+ // Common <intent-filter> actions.
xml::XmlNodeAction intent_filter_action;
intent_filter_action["action"];
intent_filter_action["category"];
intent_filter_action["data"];
- // Common meta-data actions.
+ // Common <meta-data> actions.
xml::XmlNodeAction meta_data_action;
+ // Common <uses-feature> actions.
+ xml::XmlNodeAction uses_feature_action;
+ uses_feature_action.Action(VerifyUsesFeature);
+
+ // Common component actions.
+ xml::XmlNodeAction component_action;
+ component_action.Action(RequiredNameIsJavaClassName);
+ component_action["intent-filter"] = intent_filter_action;
+ component_action["meta-data"] = meta_data_action;
+
// Manifest actions.
xml::XmlNodeAction& manifest_action = (*executor)["manifest"];
manifest_action.Action(VerifyManifest);
@@ -190,6 +230,7 @@
});
// Instrumentation actions.
+ manifest_action["instrumentation"].Action(RequiredNameIsJavaClassName);
manifest_action["instrumentation"].Action([&](xml::Element* el) -> bool {
if (!options_.rename_instrumentation_target_package) {
return true;
@@ -201,6 +242,7 @@
}
return true;
});
+ manifest_action["instrumentation"]["meta-data"] = meta_data_action;
manifest_action["original-package"];
manifest_action["protected-broadcast"];
@@ -208,51 +250,28 @@
manifest_action["permission"];
manifest_action["permission-tree"];
manifest_action["permission-group"];
-
manifest_action["uses-configuration"];
- manifest_action["uses-feature"];
manifest_action["supports-screens"];
-
+ manifest_action["uses-feature"] = uses_feature_action;
+ manifest_action["feature-group"]["uses-feature"] = uses_feature_action;
manifest_action["compatible-screens"];
manifest_action["compatible-screens"]["screen"];
-
manifest_action["supports-gl-texture"];
-
manifest_action["meta-data"] = meta_data_action;
// Application actions.
xml::XmlNodeAction& application_action = manifest_action["application"];
application_action.Action(OptionalNameIsJavaClassName);
- // Uses library actions.
application_action["uses-library"];
-
- // Meta-data.
application_action["meta-data"] = meta_data_action;
-
- // Activity actions.
- application_action["activity"].Action(RequiredNameIsJavaClassName);
- application_action["activity"]["intent-filter"] = intent_filter_action;
- application_action["activity"]["meta-data"] = meta_data_action;
-
- // Activity alias actions.
- application_action["activity-alias"]["intent-filter"] = intent_filter_action;
- application_action["activity-alias"]["meta-data"] = meta_data_action;
-
- // Service actions.
- application_action["service"].Action(RequiredNameIsJavaClassName);
- application_action["service"]["intent-filter"] = intent_filter_action;
- application_action["service"]["meta-data"] = meta_data_action;
-
- // Receiver actions.
- application_action["receiver"].Action(RequiredNameIsJavaClassName);
- application_action["receiver"]["intent-filter"] = intent_filter_action;
- application_action["receiver"]["meta-data"] = meta_data_action;
+ application_action["activity"] = component_action;
+ application_action["activity-alias"] = component_action;
+ application_action["service"] = component_action;
+ application_action["receiver"] = component_action;
// Provider actions.
- application_action["provider"].Action(RequiredNameIsJavaClassName);
- application_action["provider"]["intent-filter"] = intent_filter_action;
- application_action["provider"]["meta-data"] = meta_data_action;
+ application_action["provider"] = component_action;
application_action["provider"]["grant-uri-permissions"];
application_action["provider"]["path-permissions"];
diff --git a/tools/aapt2/link/ManifestFixer_test.cpp b/tools/aapt2/link/ManifestFixer_test.cpp
index 12a304a..ce84993 100644
--- a/tools/aapt2/link/ManifestFixer_test.cpp
+++ b/tools/aapt2/link/ManifestFixer_test.cpp
@@ -90,7 +90,7 @@
}
TEST_F(ManifestFixerTest, AllowMetaData) {
- auto doc = Verify(R"EOF(
+ auto doc = Verify(R"EOF(
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="android">
<meta-data />
@@ -98,12 +98,13 @@
<meta-data />
<activity android:name=".Hi"><meta-data /></activity>
<activity-alias android:name=".Ho"><meta-data /></activity-alias>
- <receiver android:name=".OffToWork"><meta-data /></receiver>
- <provider android:name=".We"><meta-data /></provider>
- <service android:name=".Go"><meta-data /></service>
+ <receiver android:name=".OffTo"><meta-data /></receiver>
+ <provider android:name=".Work"><meta-data /></provider>
+ <service android:name=".We"><meta-data /></service>
</application>
+ <instrumentation android:name=".Go"><meta-data /></instrumentation>
</manifest>)EOF");
- ASSERT_NE(nullptr, doc);
+ ASSERT_NE(nullptr, doc);
}
TEST_F(ManifestFixerTest, UseDefaultSdkVersionsIfNonePresent) {
@@ -290,7 +291,7 @@
std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF(
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="android">
- <instrumentation android:targetPackage="android" />
+ <instrumentation android:name=".TestRunner" android:targetPackage="android" />
</manifest>)EOF",
options);
ASSERT_NE(nullptr, doc);
@@ -354,4 +355,51 @@
EXPECT_NE(nullptr, ValueCast<BinaryPrimitive>(attr->compiled_value.get()));
}
+TEST_F(ManifestFixerTest, UsesFeatureMustHaveNameOrGlEsVersion) {
+ std::string input = R"EOF(
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android">
+ <uses-feature android:name="feature" />
+ <uses-feature android:glEsVersion="1" />
+ <feature-group />
+ <feature-group>
+ <uses-feature android:name="feature_in_group" />
+ <uses-feature android:glEsVersion="2" />
+ </feature-group>
+ </manifest>)EOF";
+ EXPECT_NE(nullptr, Verify(input));
+
+ input = R"EOF(
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android">
+ <uses-feature android:name="feature" android:glEsVersion="1" />
+ </manifest>)EOF";
+ EXPECT_EQ(nullptr, Verify(input));
+
+ input = R"EOF(
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android">
+ <uses-feature />
+ </manifest>)EOF";
+ EXPECT_EQ(nullptr, Verify(input));
+
+ input = R"EOF(
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android">
+ <feature-group>
+ <uses-feature android:name="feature" android:glEsVersion="1" />
+ </feature-group>
+ </manifest>)EOF";
+ EXPECT_EQ(nullptr, Verify(input));
+
+ input = R"EOF(
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android">
+ <feature-group>
+ <uses-feature />
+ </feature-group>
+ </manifest>)EOF";
+ EXPECT_EQ(nullptr, Verify(input));
+}
+
} // namespace aapt
diff --git a/tools/aapt2/readme.md b/tools/aapt2/readme.md
index e2a752e..44d22c4 100644
--- a/tools/aapt2/readme.md
+++ b/tools/aapt2/readme.md
@@ -1,5 +1,12 @@
# Android Asset Packaging Tool 2.0 (AAPT2) release notes
+## Version 2.6
+### `aapt2`
+- Support legacy `configVarying` resource type.
+- Support `<bag>` tag and treat as `<style>` regardless of type.
+- Add `<feature-group>` manifest tag verification.
+- Add `<meta-data>` tag support to `<instrumentation>`.
+
## Version 2.5
### `aapt2 link ...`
- Transition XML versioning: Adds a new flag `--no-version-transitions` to disable automatic
diff --git a/tools/aapt2/strip/Strip.cpp b/tools/aapt2/strip/Strip.cpp
index b3787ec..c34cfbf3 100644
--- a/tools/aapt2/strip/Strip.cpp
+++ b/tools/aapt2/strip/Strip.cpp
@@ -22,6 +22,7 @@
#include "Diagnostics.h"
#include "Flags.h"
#include "LoadedApk.h"
+#include "split/TableSplitter.h"
using android::StringPiece;
@@ -78,7 +79,27 @@
context_->GetDiagnostics()->Note(DiagMessage() << "Stripping APK...");
}
- // TODO(lecesne): Implement stripping here.
+ // TODO(lecesne): Add support for more than one density.
+ if (options_.target_configs.size() > 1) {
+ context_->GetDiagnostics()->Error(DiagMessage()
+ << "Multiple densities not supported at the moment");
+ return 1;
+ }
+
+ // Stripping the APK using the TableSplitter with no splits and the target
+ // density as the preferred density. The resource table is modified in
+ // place in the LoadedApk.
+ TableSplitterOptions splitter_options;
+ splitter_options.preferred_density = options_.target_configs[0].density;
+ std::vector<SplitConstraints> splits;
+ TableSplitter splitter(splits, splitter_options);
+ splitter.SplitTable(apk->GetResourceTable());
+
+ std::unique_ptr<IArchiveWriter> writer =
+ CreateZipFileArchiveWriter(context_->GetDiagnostics(), options_.output_path);
+ if (!apk->WriteToArchive(context_, writer.get())) {
+ return 1;
+ }
return 0;
}
diff --git a/tools/aapt2/unflatten/BinaryResourceParser.cpp b/tools/aapt2/unflatten/BinaryResourceParser.cpp
index aeabcff..7098fe9 100644
--- a/tools/aapt2/unflatten/BinaryResourceParser.cpp
+++ b/tools/aapt2/unflatten/BinaryResourceParser.cpp
@@ -370,8 +370,7 @@
return false;
}
- if (!table_->AddResourceAllowMangled(name, config, {},
- std::move(resource_value),
+ if (!table_->AddResourceAllowMangled(name, res_id, config, {}, std::move(resource_value),
context_->GetDiagnostics())) {
return false;
}
diff --git a/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java
index 9d9d71f..8c6740c 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java
@@ -636,6 +636,20 @@
Bitmap.getDefaultDensity());
}
+ @LayoutlibDelegate
+ /*package*/ static Bitmap nativeCreateHardwareBitmap(GraphicBuffer buffer) {
+ Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED,
+ "Bitmap.nativeCreateHardwareBitmap() is not supported", null /*data*/);
+ return null;
+ }
+
+ @LayoutlibDelegate
+ /*package*/ static GraphicBuffer nativeCreateGraphicBufferHandle(long nativeBitmap) {
+ Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED,
+ "Bitmap.nativeCreateGraphicBufferHandle() is not supported", null /*data*/);
+ return null;
+ }
+
// ---- Private delegate/helper methods ----
private Bitmap_Delegate(BufferedImage image, Config config) {
diff --git a/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
index c599e9d..47216ee 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
@@ -209,20 +209,20 @@
}
@LayoutlibDelegate
- public static void nRestore(long nativeCanvas, boolean throwOnUnderflow) {
+ public static boolean nRestore(long nativeCanvas) {
// FIXME: implement throwOnUnderflow.
// get the delegate from the native int.
Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(nativeCanvas);
if (canvasDelegate == null) {
- return;
+ return false;
}
canvasDelegate.restore();
+ return true;
}
@LayoutlibDelegate
- public static void nRestoreToCount(long nativeCanvas, int saveCount,
- boolean throwOnUnderflow) {
+ public static void nRestoreToCount(long nativeCanvas, int saveCount) {
// FIXME: implement throwOnUnderflow.
// get the delegate from the native int.
Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(nativeCanvas);
@@ -427,7 +427,7 @@
}
@LayoutlibDelegate
- public static void nGetCTM(long canvas, long matrix) {
+ public static void nGetMatrix(long canvas, long matrix) {
// get the delegate from the native int.
Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(canvas);
if (canvasDelegate == null) {
diff --git a/tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java
index 147ed99..a43e545 100644
--- a/tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java
@@ -313,7 +313,8 @@
}
@LayoutlibDelegate
- /*package*/ static boolean nAddFontFromAsset(long builderPtr, AssetManager mgr, String path) {
+ /*package*/ static boolean nAddFontFromAssetManager(long builderPtr, AssetManager mgr, String path,
+ int cookie, boolean isAsset) {
FontFamily_Delegate ffd = sManager.getDelegate(builderPtr);
if (ffd == null) {
return false;
@@ -388,6 +389,10 @@
return false;
}
+ @LayoutlibDelegate
+ /*package*/ static void nAbort(long builderPtr) {
+ sManager.removeJavaReferenceFor(builderPtr);
+ }
// ---- private helper methods ----
diff --git a/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
index 9b8fa99..aa1f00d 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
@@ -1062,8 +1062,6 @@
@LayoutlibDelegate
/*package*/ static void nSetWordSpacing(long nativePaint, float wordSpacing) {
- Bridge.getLog().fidelityWarning(LayoutLog.TAG_TEXT_RENDERING,
- "Paint.setWordSpacing() not supported.", null, null);
Paint_Delegate delegate = sManager.getDelegate(nativePaint);
if (delegate == null) {
return;
diff --git a/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java
index f6c463f..11328dc 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java
@@ -16,12 +16,14 @@
package android.graphics;
-import android.text.FontConfig;
+import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.layoutlib.bridge.Bridge;
import com.android.layoutlib.bridge.impl.DelegateManager;
import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
import android.annotation.NonNull;
import android.graphics.FontFamily_Delegate.FontVariant;
+import android.text.FontConfig;
import java.awt.Font;
import java.io.File;
@@ -160,6 +162,18 @@
}
@LayoutlibDelegate
+ /*package*/ static synchronized long nativeCreateFromTypefaceWithVariation(long native_instance,
+ List<FontConfig.Axis> axes) {
+ long newInstance = nativeCreateFromTypeface(native_instance, 0);
+
+ if (newInstance != 0) {
+ Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
+ "nativeCreateFromTypefaceWithVariation is not supported", null, null);
+ }
+ return newInstance;
+ }
+
+ @LayoutlibDelegate
/*package*/ static long nativeCreateWeightAlias(long native_instance, int weight) {
Typeface_Delegate delegate = sManager.getDelegate(native_instance);
if (delegate == null) {
diff --git a/tools/layoutlib/bridge/src/android/graphics/drawable/VectorDrawable_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/drawable/VectorDrawable_Delegate.java
index 430607a..eee7473 100644
--- a/tools/layoutlib/bridge/src/android/graphics/drawable/VectorDrawable_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/drawable/VectorDrawable_Delegate.java
@@ -156,7 +156,7 @@
bounds.offsetTo(0, 0);
nativePathRenderer.draw(canvasWrapperPtr, colorFilterPtr, bounds.width(), bounds.height());
- Canvas_Delegate.nRestore(canvasWrapperPtr, true);
+ Canvas_Delegate.nRestore(canvasWrapperPtr);
return bounds.width() * bounds.height();
}
@@ -1122,7 +1122,7 @@
drawPath(currentGroup, childPath, canvasPtr, w, h, filterPtr);
}
}
- Canvas_Delegate.nRestore(canvasPtr, true);
+ Canvas_Delegate.nRestore(canvasPtr);
}
public void draw(long canvasPtr, long filterPtr, int w, int h) {
diff --git a/tools/layoutlib/bridge/src/android/text/StaticLayout_Delegate.java b/tools/layoutlib/bridge/src/android/text/StaticLayout_Delegate.java
index 65c0a07..970c7d5 100644
--- a/tools/layoutlib/bridge/src/android/text/StaticLayout_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/text/StaticLayout_Delegate.java
@@ -75,7 +75,8 @@
/*package*/ static void nSetupParagraph(long nativeBuilder, char[] text, int length,
float firstWidth, int firstWidthLineCount, float restWidth,
int[] variableTabStops, int defaultTabStop, int breakStrategy,
- int hyphenationFrequency) {
+ int hyphenationFrequency, boolean isJustified) {
+ // TODO: implement justified alignment
Builder builder = sBuilderManager.getDelegate(nativeBuilder);
if (builder == null) {
return;
diff --git a/tools/layoutlib/bridge/src/android/view/RenderNode_Delegate.java b/tools/layoutlib/bridge/src/android/view/RenderNode_Delegate.java
index a801cb0..152878b 100644
--- a/tools/layoutlib/bridge/src/android/view/RenderNode_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/view/RenderNode_Delegate.java
@@ -57,7 +57,7 @@
private String mName;
@LayoutlibDelegate
- /*package*/ static long nCreate(RenderNode thisRenderNode, String name) {
+ /*package*/ static long nCreate(String name) {
RenderNode_Delegate renderNodeDelegate = new RenderNode_Delegate();
renderNodeDelegate.mName = name;
return sManager.addNewDelegate(renderNodeDelegate);
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmGenerator.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmGenerator.java
index a2f8372..bed5806a 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmGenerator.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmGenerator.java
@@ -36,6 +36,7 @@
import java.util.TreeMap;
import java.util.jar.JarEntry;
import java.util.jar.JarOutputStream;
+import java.util.stream.Collectors;
/**
* Class that generates a new JAR from a list of classes, some of which are to be kept as-is
@@ -78,6 +79,8 @@
private final Map<String, ICreateInfo.InjectMethodRunnable> mInjectedMethodsMap;
/** A map { FQCN => set { field names } } which should be promoted to public visibility */
private final Map<String, Set<String>> mPromotedFields;
+ /** A list of classes to be promoted to public visibility */
+ private final Set<String> mPromotedClasses;
/**
* Creates a new generator that can generate the output JAR with the stubbed classes.
@@ -179,6 +182,9 @@
addToMap(createInfo.getPromotedFields(), mPromotedFields);
mInjectedMethodsMap = createInfo.getInjectedMethodsMap();
+
+ mPromotedClasses =
+ Arrays.stream(createInfo.getPromotedClasses()).collect(Collectors.toSet());
}
/**
@@ -400,7 +406,11 @@
if (promoteFields != null && !promoteFields.isEmpty()) {
cv = new PromoteFieldClassAdapter(cv, promoteFields);
}
+ if (!mPromotedClasses.isEmpty()) {
+ cv = new PromoteClassClassAdapter(cv, mPromotedClasses);
+ }
cr.accept(cv, 0);
+
return cw.toByteArray();
}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
index 741eb27..94302d3 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
@@ -113,6 +113,11 @@
}
@Override
+ public String[] getPromotedClasses() {
+ return PROMOTED_CLASSES;
+ }
+
+ @Override
public Map<String, InjectMethodRunnable> getInjectedMethodsMap() {
return INJECTED_METHODS;
}
@@ -344,6 +349,13 @@
};
/**
+ * List of classes to be promoted to public visibility. Prefer using PROMOTED_FIELDS to this
+ * if possible.
+ */
+ private final static String[] PROMOTED_CLASSES = new String[] {
+ };
+
+ /**
* List of classes for which the methods returning them should be deleted.
* The array contains a list of null terminated section starting with the name of the class
* to rename in which the methods are deleted, followed by a list of return types identifying
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/ICreateInfo.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/ICreateInfo.java
index 535a9a8..48abde4 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/ICreateInfo.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/ICreateInfo.java
@@ -78,6 +78,11 @@
String[] getPromotedFields();
/**
+ * Returns a list of classes to be promoted to public visibility.
+ */
+ String[] getPromotedClasses();
+
+ /**
* Returns a map from binary FQCN className to {@link InjectMethodRunnable} which will be
* called to inject methods into a class.
* Can be empty but must not be null.
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/PromoteClassClassAdapter.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/PromoteClassClassAdapter.java
new file mode 100644
index 0000000..99e3089
--- /dev/null
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/PromoteClassClassAdapter.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.tools.layoutlib.create;
+
+import org.objectweb.asm.ClassVisitor;
+
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static org.objectweb.asm.Opcodes.ACC_PRIVATE;
+import static org.objectweb.asm.Opcodes.ACC_PROTECTED;
+import static org.objectweb.asm.Opcodes.ACC_PUBLIC;
+
+/**
+ * Promotes given classes to public visibility.
+ */
+public class PromoteClassClassAdapter extends ClassVisitor {
+
+ private final Set<String> mClassNames;
+ private static final int CLEAR_PRIVATE_MASK = ~(ACC_PRIVATE | ACC_PROTECTED);
+
+ public PromoteClassClassAdapter(ClassVisitor cv, Set<String> classNames) {
+ super(Main.ASM_VERSION, cv);
+ mClassNames =
+ classNames.stream().map(name -> name.replace(".", "/")).collect(Collectors.toSet());
+ }
+
+ @Override
+ public void visit(int version, int access, String name, String signature, String superName,
+ String[] interfaces) {
+ if (mClassNames.contains(name)) {
+ if ((access & ACC_PUBLIC) == 0) {
+ access = (access & CLEAR_PRIVATE_MASK) | ACC_PUBLIC;
+ }
+ }
+
+ super.visit(version, access, name, signature, superName, interfaces);
+ }
+
+ @Override
+ public void visitInnerClass(String name, String outerName, String innerName, int access) {
+ if (mClassNames.contains(name)) {
+ if ((access & ACC_PUBLIC) == 0) {
+ access = (access & CLEAR_PRIVATE_MASK) | ACC_PUBLIC;
+ }
+ }
+
+ super.visitInnerClass(name, outerName, innerName, access);
+ }
+}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/PromoteFieldClassAdapter.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/PromoteFieldClassAdapter.java
index 05af033..ba77860 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/PromoteFieldClassAdapter.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/PromoteFieldClassAdapter.java
@@ -31,7 +31,7 @@
public class PromoteFieldClassAdapter extends ClassVisitor {
private final Set<String> mFieldNames;
- private static final int ACC_NOT_PUBLIC = ~(ACC_PRIVATE | ACC_PROTECTED);
+ private static final int CLEAR_PRIVATE_MASK = ~(ACC_PRIVATE | ACC_PROTECTED);
public PromoteFieldClassAdapter(ClassVisitor cv, Set<String> fieldNames) {
super(Main.ASM_VERSION, cv);
@@ -43,7 +43,7 @@
Object value) {
if (mFieldNames.contains(name)) {
if ((access & ACC_PUBLIC) == 0) {
- access = (access & ACC_NOT_PUBLIC) | ACC_PUBLIC;
+ access = (access & CLEAR_PRIVATE_MASK) | ACC_PUBLIC;
}
}
return super.visitField(access, name, desc, signature, value);
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/AsmGeneratorTest.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/AsmGeneratorTest.java
index 0560d8a..4d5d5d2 100644
--- a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/AsmGeneratorTest.java
+++ b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/AsmGeneratorTest.java
@@ -137,6 +137,11 @@
}
@Override
+ public String[] getPromotedClasses() {
+ return EMPTY_STRING_ARRAY;
+ }
+
+ @Override
public Map<String, InjectMethodRunnable> getInjectedMethodsMap() {
return Collections.emptyMap();
}
@@ -211,6 +216,11 @@
}
@Override
+ public String[] getPromotedClasses() {
+ return EMPTY_STRING_ARRAY;
+ }
+
+ @Override
public Map<String, InjectMethodRunnable> getInjectedMethodsMap() {
return Collections.emptyMap();
}
@@ -293,6 +303,11 @@
}
@Override
+ public String[] getPromotedClasses() {
+ return EMPTY_STRING_ARRAY;
+ }
+
+ @Override
public Map<String, InjectMethodRunnable> getInjectedMethodsMap() {
return Collections.emptyMap();
}
@@ -370,6 +385,11 @@
}
@Override
+ public String[] getPromotedClasses() {
+ return EMPTY_STRING_ARRAY;
+ }
+
+ @Override
public Map<String, InjectMethodRunnable> getInjectedMethodsMap() {
return Collections.singletonMap("mock_android.util.EmptyArray",
InjectMethodRunnables.CONTEXT_GET_FRAMEWORK_CLASS_LOADER);
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/PromoteClassClassAdapterTest.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/PromoteClassClassAdapterTest.java
new file mode 100644
index 0000000..eeb0b10
--- /dev/null
+++ b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/PromoteClassClassAdapterTest.java
@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.tools.layoutlib.create;
+
+import org.junit.Test;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.Opcodes;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.StringJoiner;
+
+import static org.junit.Assert.assertTrue;
+
+/**
+ * {@link ClassVisitor} that logs all the calls to the different visit methods so they can be later
+ * inspected.
+ */
+class LoggingClassVisitor extends ClassVisitor {
+ List<String> mLog = new LinkedList<String>();
+
+ public LoggingClassVisitor() {
+ super(Main.ASM_VERSION);
+ }
+
+ public LoggingClassVisitor(ClassVisitor cv) {
+ super(Main.ASM_VERSION, cv);
+ }
+
+ private static String formatAccess(int access) {
+ StringJoiner modifiers = new StringJoiner(",");
+
+ if ((access & Opcodes.ACC_PUBLIC) != 0) {
+ modifiers.add("public");
+ }
+ if ((access & Opcodes.ACC_PRIVATE) != 0) {
+ modifiers.add("private");
+ }
+ if ((access & Opcodes.ACC_PROTECTED) != 0) {
+ modifiers.add("protected");
+ }
+ if ((access & Opcodes.ACC_STATIC) != 0) {
+ modifiers.add("static");
+ }
+ if ((access & Opcodes.ACC_FINAL) != 0) {
+ modifiers.add("static");
+ }
+
+ return "[" + modifiers.toString() + "]";
+ }
+
+ private void log(String method, String format, Object...args) {
+ mLog.add(
+ String.format("[%s] - %s", method, String.format(format, (Object[]) args))
+ );
+ }
+
+ @Override
+ public void visitOuterClass(String owner, String name, String desc) {
+ log(
+ "visitOuterClass",
+ "owner=%s, name=%s, desc=%s",
+ owner, name, desc
+ );
+
+ super.visitOuterClass(owner, name, desc);
+ }
+
+ @Override
+ public void visitInnerClass(String name, String outerName, String innerName, int access) {
+ log(
+ "visitInnerClass",
+ "name=%s, outerName=%s, innerName=%s, access=%s",
+ name, outerName, innerName, formatAccess(access)
+ );
+
+ super.visitInnerClass(name, outerName, innerName, access);
+ }
+
+ @Override
+ public void visit(int version, int access, String name, String signature, String superName,
+ String[] interfaces) {
+ log(
+ "visit",
+ "version=%d, access=%s, name=%s, signature=%s, superName=%s, interfaces=%s",
+ version, formatAccess(access), name, signature, superName, Arrays.toString(interfaces)
+ );
+
+ super.visit(version, access, name, signature, superName, interfaces);
+ }
+}
+
+class PackageProtectedClass {}
+
+public class PromoteClassClassAdapterTest {
+ private static class PrivateClass {}
+ private static class ClassWithPrivateInnerClass {
+ private class InnerPrivateClass {}
+ }
+
+ @Test
+ public void testInnerClassPromotion() throws IOException {
+ ClassReader reader = new ClassReader(PrivateClass.class.getName());
+ LoggingClassVisitor log = new LoggingClassVisitor();
+
+ PromoteClassClassAdapter adapter = new PromoteClassClassAdapter(log, new HashSet<String>() {
+ {
+ add("com.android.tools.layoutlib.create.PromoteClassClassAdapterTest$PrivateClass");
+ add("com.android.tools.layoutlib.create" +
+ ".PromoteClassClassAdapterTest$ClassWithPrivateInnerClass$InnerPrivateClass");
+ }
+ });
+ reader.accept(adapter, 0);
+ assertTrue(log.mLog.contains(
+ "[visitInnerClass] - " +
+ "name=com/android/tools/layoutlib/create" +
+ "/PromoteClassClassAdapterTest$PrivateClass, " +
+ "outerName=com/android/tools/layoutlib/create" +
+ "/PromoteClassClassAdapterTest, innerName=PrivateClass, access=[public,static]"));
+
+ // Test inner of inner class
+ log.mLog.clear();
+ reader = new ClassReader(ClassWithPrivateInnerClass.class.getName());
+ reader.accept(adapter, 0);
+
+ assertTrue(log.mLog.contains("[visitInnerClass] - " +
+ "name=com/android/tools/layoutlib/create" +
+ "/PromoteClassClassAdapterTest$ClassWithPrivateInnerClass$InnerPrivateClass, " +
+ "outerName=com/android/tools/layoutlib/create" +
+ "/PromoteClassClassAdapterTest$ClassWithPrivateInnerClass, " +
+ "innerName=InnerPrivateClass, access=[public]"));
+
+ }
+
+ @Test
+ public void testProtectedClassPromotion() throws IOException {
+ ClassReader reader = new ClassReader(PackageProtectedClass.class.getName());
+ LoggingClassVisitor log = new LoggingClassVisitor();
+
+ PromoteClassClassAdapter adapter = new PromoteClassClassAdapter(log, new HashSet<String>() {
+ {
+ add("com.android.tools.layoutlib.create.PackageProtectedClass");
+ }
+ });
+
+ reader.accept(adapter, 0);
+ assertTrue(log.mLog.contains("[visit] - version=52, access=[public], " +
+ "name=com/android/tools/layoutlib/create/PackageProtectedClass, signature=null, " +
+ "superName=java/lang/Object, interfaces=[]"));
+
+ }
+}
\ No newline at end of file
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index ab725e2..3fb8ef3 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -973,7 +973,6 @@
*
* @param config The Passpoint configuration to be added
* @return true on success
- * @hide
*/
public boolean addOrUpdatePasspointConfiguration(PasspointConfiguration config) {
try {
@@ -988,7 +987,6 @@
*
* @param fqdn The FQDN of the passpoint configuration to be removed
* @return true on success
- * @hide
*/
public boolean removePasspointConfiguration(String fqdn) {
try {
@@ -1004,7 +1002,6 @@
* An empty list will be returned when no configurations are installed.
*
* @return A list of {@link PasspointConfiguration}
- * @hide
*/
public List<PasspointConfiguration> getPasspointConfigurations() {
try {
diff --git a/wifi/java/android/net/wifi/hotspot2/ConfigBuilder.java b/wifi/java/android/net/wifi/hotspot2/ConfigParser.java
similarity index 97%
rename from wifi/java/android/net/wifi/hotspot2/ConfigBuilder.java
rename to wifi/java/android/net/wifi/hotspot2/ConfigParser.java
index 78b335d..027b049a 100644
--- a/wifi/java/android/net/wifi/hotspot2/ConfigBuilder.java
+++ b/wifi/java/android/net/wifi/hotspot2/ConfigParser.java
@@ -16,7 +16,7 @@
package android.net.wifi.hotspot2;
-import android.net.wifi.hotspot2.omadm.PPSMOParser;
+import android.net.wifi.hotspot2.omadm.PpsMoParser;
import android.text.TextUtils;
import android.util.Base64;
import android.util.Log;
@@ -41,11 +41,9 @@
/**
* Utility class for building PasspointConfiguration from an installation file.
- *
- * @hide
*/
-public final class ConfigBuilder {
- private static final String TAG = "ConfigBuilder";
+public final class ConfigParser {
+ private static final String TAG = "ConfigParser";
// Header names.
private static final String CONTENT_TYPE = "Content-Type";
@@ -101,6 +99,10 @@
public String encodingType = null;
}
+ /**
+ * @hide
+ */
+ public ConfigParser() {}
/**
* Parse the Hotspot 2.0 Release 1 configuration data into a {@link PasspointConfiguration}
@@ -133,7 +135,7 @@
* certificate chain (optional).
* @return {@link PasspointConfiguration}
*/
- public static PasspointConfiguration buildPasspointConfig(String mimeType, byte[] data) {
+ public static PasspointConfiguration parsePasspointConfig(String mimeType, byte[] data) {
// Verify MIME type.
if (!TextUtils.equals(mimeType, TYPE_WIFI_CONFIG)) {
Log.e(TAG, "Unexpected MIME type: " + mimeType);
@@ -169,7 +171,7 @@
throw new IOException("Missing Passpoint Profile");
}
- PasspointConfiguration config = PPSMOParser.parseMOText(new String(profileData));
+ PasspointConfiguration config = PpsMoParser.parseMoText(new String(profileData));
if (config == null) {
throw new IOException("Failed to parse Passpoint profile");
}
@@ -470,4 +472,4 @@
}
return new Pair<PrivateKey, List<X509Certificate>>(clientKey, clientCertificateChain);
}
-}
\ No newline at end of file
+}
diff --git a/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java b/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java
index c2b307d..7b73b4b 100644
--- a/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java
+++ b/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java
@@ -17,7 +17,7 @@
package android.net.wifi.hotspot2;
import android.net.wifi.hotspot2.pps.Credential;
-import android.net.wifi.hotspot2.pps.HomeSP;
+import android.net.wifi.hotspot2.pps.HomeSp;
import android.net.wifi.hotspot2.pps.Policy;
import android.net.wifi.hotspot2.pps.UpdateParameter;
import android.os.Parcelable;
@@ -38,8 +38,6 @@
*
* For more info, refer to Hotspot 2.0 PPS MO defined in section 9.1 of the Hotspot 2.0
* Release 2 Technical Specification.
- *
- * @hide
*/
public final class PasspointConfiguration implements Parcelable {
private static final String TAG = "PasspointConfiguration";
@@ -60,11 +58,11 @@
private static final int NULL_VALUE = -1;
/**
- * Configurations under HomeSP subtree.
+ * Configurations under HomeSp subtree.
*/
- private HomeSP mHomeSp = null;
- public void setHomeSp(HomeSP homeSp) { mHomeSp = homeSp; }
- public HomeSP getHomeSp() { return mHomeSp; }
+ private HomeSp mHomeSp = null;
+ public void setHomeSp(HomeSp homeSp) { mHomeSp = homeSp; }
+ public HomeSp getHomeSp() { return mHomeSp; }
/**
* Configurations under Credential subtree.
@@ -248,7 +246,7 @@
}
if (source.mHomeSp != null) {
- mHomeSp = new HomeSP(source.mHomeSp);
+ mHomeSp = new HomeSp(source.mHomeSp);
}
if (source.mCredential != null) {
mCredential = new Credential(source.mCredential);
diff --git a/wifi/java/android/net/wifi/hotspot2/omadm/PPSMOParser.java b/wifi/java/android/net/wifi/hotspot2/omadm/PpsMoParser.java
similarity index 98%
rename from wifi/java/android/net/wifi/hotspot2/omadm/PPSMOParser.java
rename to wifi/java/android/net/wifi/hotspot2/omadm/PpsMoParser.java
index 24672d4..2ffe428 100644
--- a/wifi/java/android/net/wifi/hotspot2/omadm/PPSMOParser.java
+++ b/wifi/java/android/net/wifi/hotspot2/omadm/PpsMoParser.java
@@ -18,7 +18,7 @@
import android.net.wifi.hotspot2.PasspointConfiguration;
import android.net.wifi.hotspot2.pps.Credential;
-import android.net.wifi.hotspot2.pps.HomeSP;
+import android.net.wifi.hotspot2.pps.HomeSp;
import android.net.wifi.hotspot2.pps.Policy;
import android.net.wifi.hotspot2.pps.UpdateParameter;
import android.text.TextUtils;
@@ -109,11 +109,9 @@
* </Node>
* </Node>
* </MgmtTree>
- *
- * @hide
*/
-public final class PPSMOParser {
- private static final String TAG = "PPSMOParser";
+public final class PpsMoParser {
+ private static final String TAG = "PpsMoParser";
/**
* XML tags expected in the PPS MO (PerProviderSubscription Management Object) XML tree.
@@ -326,13 +324,18 @@
}
/**
+ * @hide
+ */
+ public PpsMoParser() {}
+
+ /**
* Convert a XML string representation of a PPS MO (PerProviderSubscription
* Management Object) tree to a {@link PasspointConfiguration} object.
*
* @param xmlString XML string representation of a PPS MO tree
* @return {@link PasspointConfiguration} or null
*/
- public static PasspointConfiguration parseMOText(String xmlString) {
+ public static PasspointConfiguration parseMoText(String xmlString) {
// Convert the XML string to a XML tree.
XMLParser xmlParser = new XMLParser();
XMLNode root = null;
@@ -640,12 +643,12 @@
* @return HomeSP
* @throws ParsingException
*/
- private static HomeSP parseHomeSP(PPSNode node) throws ParsingException {
+ private static HomeSp parseHomeSP(PPSNode node) throws ParsingException {
if (node.isLeaf()) {
throw new ParsingException("Leaf node not expected for HomeSP");
}
- HomeSP homeSp = new HomeSP();
+ HomeSp homeSp = new HomeSp();
for (PPSNode child : node.getChildren()) {
switch (child.getName()) {
case NODE_FQDN:
@@ -655,7 +658,7 @@
homeSp.setFriendlyName(getPpsNodeValue(child));
break;
case NODE_ROAMING_CONSORTIUM_OI:
- homeSp.setRoamingConsortiumOIs(
+ homeSp.setRoamingConsortiumOis(
parseRoamingConsortiumOI(getPpsNodeValue(child)));
break;
case NODE_ICON_URL:
@@ -666,8 +669,8 @@
break;
case NODE_HOME_OI_LIST:
Pair<List<Long>, List<Long>> homeOIs = parseHomeOIList(child);
- homeSp.setMatchAllOIs(convertFromLongList(homeOIs.first));
- homeSp.setMatchAnyOIs(convertFromLongList(homeOIs.second));
+ homeSp.setMatchAllOis(convertFromLongList(homeOIs.first));
+ homeSp.setMatchAnyOis(convertFromLongList(homeOIs.second));
break;
case NODE_OTHER_HOME_PARTNERS:
homeSp.setOtherHomePartners(parseOtherHomePartners(child));
@@ -909,7 +912,7 @@
credential.setRealm(getPpsNodeValue(child));
break;
case NODE_CHECK_AAA_SERVER_CERT_STATUS:
- credential.setCheckAAAServerCertStatus(
+ credential.setCheckAaaServerCertStatus(
Boolean.parseBoolean(getPpsNodeValue(child)));
break;
case NODE_SIM:
diff --git a/wifi/java/android/net/wifi/hotspot2/pps/Credential.java b/wifi/java/android/net/wifi/hotspot2/pps/Credential.java
index ff93486..025d4d3 100644
--- a/wifi/java/android/net/wifi/hotspot2/pps/Credential.java
+++ b/wifi/java/android/net/wifi/hotspot2/pps/Credential.java
@@ -42,8 +42,6 @@
*
* In addition to the fields in the Credential subtree, this will also maintain necessary
* information for the private key and certificates associated with this credential.
- *
- * @hide
*/
public final class Credential implements Parcelable {
private static final String TAG = "Credential";
@@ -98,12 +96,12 @@
* and Accounting) server's certificate during EAP (Extensible Authentication
* Protocol) authentication.
*/
- private boolean mCheckAAAServerCertStatus = false;
- public void setCheckAAAServerCertStatus(boolean checkAAAServerCertStatus) {
- mCheckAAAServerCertStatus = checkAAAServerCertStatus;
+ private boolean mCheckAaaServerCertStatus = false;
+ public void setCheckAaaServerCertStatus(boolean checkAaaServerCertStatus) {
+ mCheckAaaServerCertStatus = checkAaaServerCertStatus;
}
- public boolean getCheckAAAServerStatus() {
- return mCheckAAAServerCertStatus;
+ public boolean getCheckAaaServerStatus() {
+ return mCheckAaaServerCertStatus;
}
/**
@@ -685,7 +683,7 @@
mCreationTimeInMs = source.mCreationTimeInMs;
mExpirationTimeInMs = source.mExpirationTimeInMs;
mRealm = source.mRealm;
- mCheckAAAServerCertStatus = source.mCheckAAAServerCertStatus;
+ mCheckAaaServerCertStatus = source.mCheckAaaServerCertStatus;
if (source.mUserCredential != null) {
mUserCredential = new UserCredential(source.mUserCredential);
}
@@ -714,7 +712,7 @@
dest.writeLong(mCreationTimeInMs);
dest.writeLong(mExpirationTimeInMs);
dest.writeString(mRealm);
- dest.writeInt(mCheckAAAServerCertStatus ? 1 : 0);
+ dest.writeInt(mCheckAaaServerCertStatus ? 1 : 0);
dest.writeParcelable(mUserCredential, flags);
dest.writeParcelable(mCertCredential, flags);
dest.writeParcelable(mSimCredential, flags);
@@ -736,7 +734,7 @@
return TextUtils.equals(mRealm, that.mRealm)
&& mCreationTimeInMs == that.mCreationTimeInMs
&& mExpirationTimeInMs == that.mExpirationTimeInMs
- && mCheckAAAServerCertStatus == that.mCheckAAAServerCertStatus
+ && mCheckAaaServerCertStatus == that.mCheckAaaServerCertStatus
&& (mUserCredential == null ? that.mUserCredential == null
: mUserCredential.equals(that.mUserCredential))
&& (mCertCredential == null ? that.mCertCredential == null
@@ -751,7 +749,7 @@
@Override
public int hashCode() {
return Objects.hash(mRealm, mCreationTimeInMs, mExpirationTimeInMs,
- mCheckAAAServerCertStatus, mUserCredential, mCertCredential, mSimCredential,
+ mCheckAaaServerCertStatus, mUserCredential, mCertCredential, mSimCredential,
mCaCertificate, mClientCertificateChain, mClientPrivateKey);
}
@@ -800,7 +798,7 @@
credential.setCreationTimeInMs(in.readLong());
credential.setExpirationTimeInMs(in.readLong());
credential.setRealm(in.readString());
- credential.setCheckAAAServerCertStatus(in.readInt() != 0);
+ credential.setCheckAaaServerCertStatus(in.readInt() != 0);
credential.setUserCredential(in.readParcelable(null));
credential.setCertCredential(in.readParcelable(null));
credential.setSimCredential(in.readParcelable(null));
diff --git a/wifi/java/android/net/wifi/hotspot2/pps/HomeSP.aidl b/wifi/java/android/net/wifi/hotspot2/pps/HomeSp.aidl
similarity index 96%
rename from wifi/java/android/net/wifi/hotspot2/pps/HomeSP.aidl
rename to wifi/java/android/net/wifi/hotspot2/pps/HomeSp.aidl
index 62d5603..6d343bd 100644
--- a/wifi/java/android/net/wifi/hotspot2/pps/HomeSP.aidl
+++ b/wifi/java/android/net/wifi/hotspot2/pps/HomeSp.aidl
@@ -16,4 +16,4 @@
package android.net.wifi.hotspot2.pps;
-parcelable HomeSP;
+parcelable HomeSp;
diff --git a/wifi/java/android/net/wifi/hotspot2/pps/HomeSP.java b/wifi/java/android/net/wifi/hotspot2/pps/HomeSp.java
similarity index 79%
rename from wifi/java/android/net/wifi/hotspot2/pps/HomeSP.java
rename to wifi/java/android/net/wifi/hotspot2/pps/HomeSp.java
index 8b3b79c..7a46129 100644
--- a/wifi/java/android/net/wifi/hotspot2/pps/HomeSP.java
+++ b/wifi/java/android/net/wifi/hotspot2/pps/HomeSp.java
@@ -34,11 +34,9 @@
*
* For more info, refer to Hotspot 2.0 PPS MO defined in section 9.1 of the Hotspot 2.0
* Release 2 Technical Specification.
- *
- * @hide
*/
-public final class HomeSP implements Parcelable {
- private static final String TAG = "HomeSP";
+public final class HomeSp implements Parcelable {
+ private static final String TAG = "HomeSp";
/**
* Maximum number of bytes allowed for a SSID.
@@ -108,12 +106,12 @@
* Refer to HomeSP/HomeOIList subtree in PerProviderSubscription (PPS) Management Object
* (MO) tree for more detail.
*/
- private long[] mMatchAllOIs = null;
- public void setMatchAllOIs(long[] matchAllOIs) {
- mMatchAllOIs = matchAllOIs;
+ private long[] mMatchAllOis = null;
+ public void setMatchAllOis(long[] matchAllOis) {
+ mMatchAllOis = matchAllOis;
}
- public long[] getMatchAllOIs() {
- return mMatchAllOIs;
+ public long[] getMatchAllOis() {
+ return mMatchAllOis;
}
/**
@@ -129,12 +127,12 @@
* Refer to HomeSP/HomeOIList subtree in PerProviderSubscription (PPS) Management Object
* (MO) tree for more detail.
*/
- private long[] mMatchAnyOIs = null;
- public void setMatchAnyOIs(long[] matchAnyOIs) {
- mMatchAnyOIs = matchAnyOIs;
+ private long[] mMatchAnyOis = null;
+ public void setMatchAnyOis(long[] matchAnyOis) {
+ mMatchAnyOis = matchAnyOis;
}
- public long[] getMatchAnysOIs() {
- return mMatchAnyOIs;
+ public long[] getMatchAnysOis() {
+ return mMatchAnyOis;
}
/**
@@ -155,25 +153,25 @@
* List of Organization Identifiers (OIs) identifying a roaming consortium of
* which this provider is a member.
*/
- private long[] mRoamingConsortiumOIs = null;
- public void setRoamingConsortiumOIs(long[] roamingConsortiumOIs) {
- mRoamingConsortiumOIs = roamingConsortiumOIs;
+ private long[] mRoamingConsortiumOis = null;
+ public void setRoamingConsortiumOis(long[] roamingConsortiumOis) {
+ mRoamingConsortiumOis = roamingConsortiumOis;
}
- public long[] getRoamingConsortiumOIs() {
- return mRoamingConsortiumOIs;
+ public long[] getRoamingConsortiumOis() {
+ return mRoamingConsortiumOis;
}
/**
- * Constructor for creating HomeSP with default values.
+ * Constructor for creating HomeSp with default values.
*/
- public HomeSP() {}
+ public HomeSp() {}
/**
* Copy constructor.
*
* @param source The source to copy from
*/
- public HomeSP(HomeSP source) {
+ public HomeSp(HomeSp source) {
if (source == null) {
return;
}
@@ -183,19 +181,19 @@
if (source.mHomeNetworkIds != null) {
mHomeNetworkIds = Collections.unmodifiableMap(source.mHomeNetworkIds);
}
- if (source.mMatchAllOIs != null) {
- mMatchAllOIs = Arrays.copyOf(source.mMatchAllOIs, source.mMatchAllOIs.length);
+ if (source.mMatchAllOis != null) {
+ mMatchAllOis = Arrays.copyOf(source.mMatchAllOis, source.mMatchAllOis.length);
}
- if (source.mMatchAnyOIs != null) {
- mMatchAnyOIs = Arrays.copyOf(source.mMatchAnyOIs, source.mMatchAnyOIs.length);
+ if (source.mMatchAnyOis != null) {
+ mMatchAnyOis = Arrays.copyOf(source.mMatchAnyOis, source.mMatchAnyOis.length);
}
if (source.mOtherHomePartners != null) {
mOtherHomePartners = Arrays.copyOf(source.mOtherHomePartners,
source.mOtherHomePartners.length);
}
- if (source.mRoamingConsortiumOIs != null) {
- mRoamingConsortiumOIs = Arrays.copyOf(source.mRoamingConsortiumOIs,
- source.mRoamingConsortiumOIs.length);
+ if (source.mRoamingConsortiumOis != null) {
+ mRoamingConsortiumOis = Arrays.copyOf(source.mRoamingConsortiumOis,
+ source.mRoamingConsortiumOis.length);
}
}
@@ -210,10 +208,10 @@
dest.writeString(mFriendlyName);
dest.writeString(mIconUrl);
writeHomeNetworkIds(dest, mHomeNetworkIds);
- dest.writeLongArray(mMatchAllOIs);
- dest.writeLongArray(mMatchAnyOIs);
+ dest.writeLongArray(mMatchAllOis);
+ dest.writeLongArray(mMatchAnyOis);
dest.writeStringArray(mOtherHomePartners);
- dest.writeLongArray(mRoamingConsortiumOIs);
+ dest.writeLongArray(mRoamingConsortiumOis);
}
@Override
@@ -221,30 +219,30 @@
if (this == thatObject) {
return true;
}
- if (!(thatObject instanceof HomeSP)) {
+ if (!(thatObject instanceof HomeSp)) {
return false;
}
- HomeSP that = (HomeSP) thatObject;
+ HomeSp that = (HomeSp) thatObject;
return TextUtils.equals(mFqdn, that.mFqdn)
&& TextUtils.equals(mFriendlyName, that.mFriendlyName)
&& TextUtils.equals(mIconUrl, that.mIconUrl)
&& (mHomeNetworkIds == null ? that.mHomeNetworkIds == null
: mHomeNetworkIds.equals(that.mHomeNetworkIds))
- && Arrays.equals(mMatchAllOIs, that.mMatchAllOIs)
- && Arrays.equals(mMatchAnyOIs, that.mMatchAnyOIs)
+ && Arrays.equals(mMatchAllOis, that.mMatchAllOis)
+ && Arrays.equals(mMatchAnyOis, that.mMatchAnyOis)
&& Arrays.equals(mOtherHomePartners, that.mOtherHomePartners)
- && Arrays.equals(mRoamingConsortiumOIs, that.mRoamingConsortiumOIs);
+ && Arrays.equals(mRoamingConsortiumOis, that.mRoamingConsortiumOis);
}
@Override
public int hashCode() {
- return Objects.hash(mFqdn, mFriendlyName, mIconUrl, mHomeNetworkIds, mMatchAllOIs,
- mMatchAnyOIs, mOtherHomePartners, mRoamingConsortiumOIs);
+ return Objects.hash(mFqdn, mFriendlyName, mIconUrl, mHomeNetworkIds, mMatchAllOis,
+ mMatchAnyOis, mOtherHomePartners, mRoamingConsortiumOis);
}
/**
- * Validate HomeSP data.
+ * Validate HomeSp data.
*
* @return true on success or false on failure
*/
@@ -270,25 +268,25 @@
return true;
}
- public static final Creator<HomeSP> CREATOR =
- new Creator<HomeSP>() {
+ public static final Creator<HomeSp> CREATOR =
+ new Creator<HomeSp>() {
@Override
- public HomeSP createFromParcel(Parcel in) {
- HomeSP homeSp = new HomeSP();
+ public HomeSp createFromParcel(Parcel in) {
+ HomeSp homeSp = new HomeSp();
homeSp.setFqdn(in.readString());
homeSp.setFriendlyName(in.readString());
homeSp.setIconUrl(in.readString());
homeSp.setHomeNetworkIds(readHomeNetworkIds(in));
- homeSp.setMatchAllOIs(in.createLongArray());
- homeSp.setMatchAnyOIs(in.createLongArray());
+ homeSp.setMatchAllOis(in.createLongArray());
+ homeSp.setMatchAnyOis(in.createLongArray());
homeSp.setOtherHomePartners(in.createStringArray());
- homeSp.setRoamingConsortiumOIs(in.createLongArray());
+ homeSp.setRoamingConsortiumOis(in.createLongArray());
return homeSp;
}
@Override
- public HomeSP[] newArray(int size) {
- return new HomeSP[size];
+ public HomeSp[] newArray(int size) {
+ return new HomeSp[size];
}
/**
diff --git a/wifi/java/android/net/wifi/hotspot2/pps/Policy.java b/wifi/java/android/net/wifi/hotspot2/pps/Policy.java
index ceaada4..caca0e4 100644
--- a/wifi/java/android/net/wifi/hotspot2/pps/Policy.java
+++ b/wifi/java/android/net/wifi/hotspot2/pps/Policy.java
@@ -40,18 +40,11 @@
*
* For more info, refer to Hotspot 2.0 PPS MO defined in section 9.1 of the Hotspot 2.0
* Release 2 Technical Specification.
- *
- * @hide
*/
public final class Policy implements Parcelable {
private static final String TAG = "Policy";
/**
- * Default priority for preferred roaming partner.
- */
- public static final int PREFERRED_ROAMING_PARTNER_DEFAULT_PRIORITY = 128;
-
- /**
* Maximum number of SSIDs in the exclusion list.
*/
private static final int MAX_EXCLUSION_SSIDS = 128;
@@ -189,8 +182,9 @@
/**
* Priority associated with this roaming partner policy.
+ * Using Integer.MIN_VALUE to indicate unset value.
*/
- private int mPriority = PREFERRED_ROAMING_PARTNER_DEFAULT_PRIORITY;
+ private int mPriority = Integer.MIN_VALUE;
public void setPriority(int priority) {
mPriority = priority;
}
diff --git a/wifi/java/android/net/wifi/hotspot2/pps/UpdateParameter.java b/wifi/java/android/net/wifi/hotspot2/pps/UpdateParameter.java
index 17fbf9f..70264b0e 100644
--- a/wifi/java/android/net/wifi/hotspot2/pps/UpdateParameter.java
+++ b/wifi/java/android/net/wifi/hotspot2/pps/UpdateParameter.java
@@ -34,8 +34,6 @@
*
* For more info, refer to Hotspot 2.0 PPS MO defined in section 9.1 of the Hotspot 2.0
* Release 2 Technical Specification.
- *
- * @hide
*/
public final class UpdateParameter implements Parcelable {
private static final String TAG = "UpdateParameter";
diff --git a/wifi/tests/src/android/net/wifi/hotspot2/ConfigBuilderTest.java b/wifi/tests/src/android/net/wifi/hotspot2/ConfigParserTest.java
similarity index 91%
rename from wifi/tests/src/android/net/wifi/hotspot2/ConfigBuilderTest.java
rename to wifi/tests/src/android/net/wifi/hotspot2/ConfigParserTest.java
index f7dbf7e..56bb437 100644
--- a/wifi/tests/src/android/net/wifi/hotspot2/ConfigBuilderTest.java
+++ b/wifi/tests/src/android/net/wifi/hotspot2/ConfigParserTest.java
@@ -21,7 +21,7 @@
import android.net.wifi.FakeKeys;
import android.net.wifi.hotspot2.pps.Credential;
-import android.net.wifi.hotspot2.pps.HomeSP;
+import android.net.wifi.hotspot2.pps.HomeSp;
import android.test.suitebuilder.annotation.SmallTest;
import java.io.BufferedReader;
@@ -33,10 +33,10 @@
import org.junit.Test;
/**
- * Unit tests for {@link android.net.wifi.hotspot2.ConfigBuilder}.
+ * Unit tests for {@link android.net.wifi.hotspot2.ConfigParser}.
*/
@SmallTest
-public class ConfigBuilderTest {
+public class ConfigParserTest {
/**
* Hotspot 2.0 Release 1 installation file that contains a Passpoint profile and a
* CA (Certificate Authority) X.509 certificate {@link FakeKeys#CA_CERT0}.
@@ -83,10 +83,10 @@
PasspointConfiguration config = new PasspointConfiguration();
// HomeSP configuration.
- HomeSP homeSp = new HomeSP();
+ HomeSp homeSp = new HomeSp();
homeSp.setFriendlyName("Century House");
homeSp.setFqdn("mi6.co.uk");
- homeSp.setRoamingConsortiumOIs(new long[] {0x112233L, 0x445566L});
+ homeSp.setRoamingConsortiumOis(new long[] {0x112233L, 0x445566L});
config.setHomeSp(homeSp);
// Credential configuration.
@@ -123,7 +123,7 @@
String configStr = loadResourceFile(PASSPOINT_INSTALLATION_FILE_WITH_CA_CERT);
PasspointConfiguration expectedConfig = generateConfigurationFromProfile();
PasspointConfiguration actualConfig =
- ConfigBuilder.buildPasspointConfig(
+ ConfigParser.parsePasspointConfig(
"application/x-wifi-config", configStr.getBytes());
assertTrue(actualConfig.equals(expectedConfig));
}
@@ -136,7 +136,7 @@
@Test
public void parseConfigFileWithInvalidMimeType() throws Exception {
String configStr = loadResourceFile(PASSPOINT_INSTALLATION_FILE_WITH_CA_CERT);
- assertNull(ConfigBuilder.buildPasspointConfig(
+ assertNull(ConfigParser.parsePasspointConfig(
"application/wifi-config", configStr.getBytes()));
}
@@ -148,7 +148,7 @@
@Test
public void parseConfigFileWithUnencodedData() throws Exception {
String configStr = loadResourceFile(PASSPOINT_INSTALLATION_FILE_WITH_UNENCODED_DATA);
- assertNull(ConfigBuilder.buildPasspointConfig(
+ assertNull(ConfigParser.parsePasspointConfig(
"application/x-wifi-config", configStr.getBytes()));
}
@@ -160,7 +160,7 @@
@Test
public void parseConfigFileWithInvalidPart() throws Exception {
String configStr = loadResourceFile(PASSPOINT_INSTALLATION_FILE_WITH_INVALID_PART);
- assertNull(ConfigBuilder.buildPasspointConfig(
+ assertNull(ConfigParser.parsePasspointConfig(
"application/x-wifi-config", configStr.getBytes()));
}
@@ -172,7 +172,7 @@
@Test
public void parseConfigFileWithMissingBoundary() throws Exception {
String configStr = loadResourceFile(PASSPOINT_INSTALLATION_FILE_WITH_MISSING_BOUNDARY);
- assertNull(ConfigBuilder.buildPasspointConfig(
+ assertNull(ConfigParser.parsePasspointConfig(
"application/x-wifi-config", configStr.getBytes()));
}
@@ -185,7 +185,7 @@
@Test
public void parseConfigFileWithInvalidContentType() throws Exception {
String configStr = loadResourceFile(PASSPOINT_INSTALLATION_FILE_WITH_INVALID_CONTENT_TYPE);
- assertNull(ConfigBuilder.buildPasspointConfig(
+ assertNull(ConfigParser.parsePasspointConfig(
"application/x-wifi-config", configStr.getBytes()));
}
@@ -197,7 +197,7 @@
@Test
public void parseConfigFileWithoutPasspointProfile() throws Exception {
String configStr = loadResourceFile(PASSPOINT_INSTALLATION_FILE_WITHOUT_PROFILE);
- assertNull(ConfigBuilder.buildPasspointConfig(
+ assertNull(ConfigParser.parsePasspointConfig(
"application/x-wifi-config", configStr.getBytes()));
}
}
\ No newline at end of file
diff --git a/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java b/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java
index 3aed918..7df4fcf 100644
--- a/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java
+++ b/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java
@@ -21,7 +21,7 @@
import android.net.wifi.EAPConstants;
import android.net.wifi.hotspot2.pps.Credential;
-import android.net.wifi.hotspot2.pps.HomeSP;
+import android.net.wifi.hotspot2.pps.HomeSp;
import android.net.wifi.hotspot2.pps.Policy;
import android.net.wifi.hotspot2.pps.UpdateParameter;
import android.os.Parcel;
@@ -50,11 +50,11 @@
*
* @return {@link android.net.wifi.hotspot2.pps.HomeSP}
*/
- private static HomeSP createHomeSp() {
- HomeSP homeSp = new HomeSP();
+ private static HomeSp createHomeSp() {
+ HomeSp homeSp = new HomeSp();
homeSp.setFqdn("fqdn");
homeSp.setFriendlyName("friendly name");
- homeSp.setRoamingConsortiumOIs(new long[] {0x55, 0x66});
+ homeSp.setRoamingConsortiumOis(new long[] {0x55, 0x66});
return homeSp;
}
diff --git a/wifi/tests/src/android/net/wifi/hotspot2/omadm/PPSMOParserTest.java b/wifi/tests/src/android/net/wifi/hotspot2/omadm/PpsMoParserTest.java
similarity index 91%
rename from wifi/tests/src/android/net/wifi/hotspot2/omadm/PPSMOParserTest.java
rename to wifi/tests/src/android/net/wifi/hotspot2/omadm/PpsMoParserTest.java
index 15de5c7..7cd72f0 100644
--- a/wifi/tests/src/android/net/wifi/hotspot2/omadm/PPSMOParserTest.java
+++ b/wifi/tests/src/android/net/wifi/hotspot2/omadm/PpsMoParserTest.java
@@ -19,10 +19,10 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
-import android.net.wifi.hotspot2.omadm.PPSMOParser;
+import android.net.wifi.hotspot2.omadm.PpsMoParser;
import android.net.wifi.hotspot2.PasspointConfiguration;
import android.net.wifi.hotspot2.pps.Credential;
-import android.net.wifi.hotspot2.pps.HomeSP;
+import android.net.wifi.hotspot2.pps.HomeSp;
import android.net.wifi.hotspot2.pps.Policy;
import android.net.wifi.hotspot2.pps.UpdateParameter;
import android.test.suitebuilder.annotation.SmallTest;
@@ -43,10 +43,10 @@
import java.util.Map;
/**
- * Unit tests for {@link android.net.wifi.hotspot2.omadm.PPSMOParser}.
+ * Unit tests for {@link android.net.wifi.hotspot2.omadm.PpsMoParser}.
*/
@SmallTest
-public class PPSMOParserTest {
+public class PpsMoParserTest {
private static final String VALID_PPS_MO_XML_FILE = "assets/pps/PerProviderSubscription.xml";
private static final String PPS_MO_XML_FILE_DUPLICATE_HOMESP =
"assets/pps/PerProviderSubscription_DuplicateHomeSP.xml";
@@ -122,17 +122,17 @@
config.setUsageLimitUsageTimePeriodInMinutes(99910);
// HomeSP configuration.
- HomeSP homeSp = new HomeSP();
+ HomeSp homeSp = new HomeSp();
homeSp.setFriendlyName("Century House");
homeSp.setFqdn("mi6.co.uk");
- homeSp.setRoamingConsortiumOIs(new long[] {0x112233L, 0x445566L});
+ homeSp.setRoamingConsortiumOis(new long[] {0x112233L, 0x445566L});
homeSp.setIconUrl("icon.test.com");
Map<String, Long> homeNetworkIds = new HashMap<>();
homeNetworkIds.put("TestSSID", 0x12345678L);
homeNetworkIds.put("NullHESSID", null);
homeSp.setHomeNetworkIds(homeNetworkIds);
- homeSp.setMatchAllOIs(new long[] {0x11223344});
- homeSp.setMatchAnyOIs(new long[] {0x55667788});
+ homeSp.setMatchAllOis(new long[] {0x11223344});
+ homeSp.setMatchAnyOis(new long[] {0x55667788});
homeSp.setOtherHomePartners(new String[] {"other.fqdn.com"});
config.setHomeSp(homeSp);
@@ -141,7 +141,7 @@
credential.setCreationTimeInMs(format.parse("2016-01-01T10:00:00Z").getTime());
credential.setExpirationTimeInMs(format.parse("2016-02-01T10:00:00Z").getTime());
credential.setRealm("shaken.stirred.com");
- credential.setCheckAAAServerCertStatus(true);
+ credential.setCheckAaaServerCertStatus(true);
Credential.UserCredential userCredential = new Credential.UserCredential();
userCredential.setUsername("james");
userCredential.setPassword("Ym9uZDAwNw==");
@@ -209,53 +209,53 @@
public void parseValidPPSMOTree() throws Exception {
String ppsMoTree = loadResourceFile(VALID_PPS_MO_XML_FILE);
PasspointConfiguration expectedConfig = generateConfigurationFromPPSMOTree();
- PasspointConfiguration actualConfig = PPSMOParser.parseMOText(ppsMoTree);
+ PasspointConfiguration actualConfig = PpsMoParser.parseMoText(ppsMoTree);
assertTrue(actualConfig.equals(expectedConfig));
}
@Test
public void parseNullPPSMOTree() throws Exception {
- assertEquals(null, PPSMOParser.parseMOText(null));
+ assertEquals(null, PpsMoParser.parseMoText(null));
}
@Test
public void parseEmptyPPSMOTree() throws Exception {
- assertEquals(null, PPSMOParser.parseMOText(new String()));
+ assertEquals(null, PpsMoParser.parseMoText(new String()));
}
@Test
public void parsePPSMOTreeWithDuplicateHomeSP() throws Exception {
- assertEquals(null, PPSMOParser.parseMOText(
+ assertEquals(null, PpsMoParser.parseMoText(
loadResourceFile(PPS_MO_XML_FILE_DUPLICATE_HOMESP)));
}
@Test
public void parsePPSMOTreeWithDuplicateValue() throws Exception {
- assertEquals(null, PPSMOParser.parseMOText(
+ assertEquals(null, PpsMoParser.parseMoText(
loadResourceFile(PPS_MO_XML_FILE_DUPLICATE_VALUE)));
}
@Test
public void parsePPSMOTreeWithMissingValue() throws Exception {
- assertEquals(null, PPSMOParser.parseMOText(
+ assertEquals(null, PpsMoParser.parseMoText(
loadResourceFile(PPS_MO_XML_FILE_MISSING_VALUE)));
}
@Test
public void parsePPSMOTreeWithMissingName() throws Exception {
- assertEquals(null, PPSMOParser.parseMOText(
+ assertEquals(null, PpsMoParser.parseMoText(
loadResourceFile(PPS_MO_XML_FILE_MISSING_NAME)));
}
@Test
public void parsePPSMOTreeWithInvalidNode() throws Exception {
- assertEquals(null, PPSMOParser.parseMOText(
+ assertEquals(null, PpsMoParser.parseMoText(
loadResourceFile(PPS_MO_XML_FILE_INVALID_NODE)));
}
@Test
public void parsePPSMOTreeWithInvalidName() throws Exception {
- assertEquals(null, PPSMOParser.parseMOText(
+ assertEquals(null, PpsMoParser.parseMoText(
loadResourceFile(PPS_MO_XML_FILE_INVALID_NAME)));
}
}
diff --git a/wifi/tests/src/android/net/wifi/hotspot2/pps/CredentialTest.java b/wifi/tests/src/android/net/wifi/hotspot2/pps/CredentialTest.java
index 6f68e1c..c7ade00 100644
--- a/wifi/tests/src/android/net/wifi/hotspot2/pps/CredentialTest.java
+++ b/wifi/tests/src/android/net/wifi/hotspot2/pps/CredentialTest.java
@@ -59,7 +59,7 @@
cred.setCreationTimeInMs(123455L);
cred.setExpirationTimeInMs(2310093L);
cred.setRealm("realm");
- cred.setCheckAAAServerCertStatus(true);
+ cred.setCheckAaaServerCertStatus(true);
cred.setUserCredential(userCred);
cred.setCertCredential(certCred);
cred.setSimCredential(simCred);
diff --git a/wifi/tests/src/android/net/wifi/hotspot2/pps/HomeSPTest.java b/wifi/tests/src/android/net/wifi/hotspot2/pps/HomeSpTest.java
similarity index 68%
rename from wifi/tests/src/android/net/wifi/hotspot2/pps/HomeSPTest.java
rename to wifi/tests/src/android/net/wifi/hotspot2/pps/HomeSpTest.java
index 92e94ee5..c41c11f 100644
--- a/wifi/tests/src/android/net/wifi/hotspot2/pps/HomeSPTest.java
+++ b/wifi/tests/src/android/net/wifi/hotspot2/pps/HomeSpTest.java
@@ -30,10 +30,10 @@
import java.util.Map;
/**
- * Unit tests for {@link android.net.wifi.hotspot2.pps.HomeSP}.
+ * Unit tests for {@link android.net.wifi.hotspot2.pps.HomeSp}.
*/
@SmallTest
-public class HomeSPTest {
+public class HomeSpTest {
/**
* Helper function for creating a map of home network IDs for testing.
@@ -48,68 +48,68 @@
}
/**
- * Helper function for creating a HomeSP for testing.
+ * Helper function for creating a HomeSp for testing.
*
- * @param homeNetworkIds The map of home network IDs associated with HomeSP
- * @return {@link HomeSP}
+ * @param homeNetworkIds The map of home network IDs associated with HomeSp
+ * @return {@link HomeSp}
*/
- private static HomeSP createHomeSp(Map<String, Long> homeNetworkIds) {
- HomeSP homeSp = new HomeSP();
+ private static HomeSp createHomeSp(Map<String, Long> homeNetworkIds) {
+ HomeSp homeSp = new HomeSp();
homeSp.setFqdn("fqdn");
homeSp.setFriendlyName("friendly name");
homeSp.setIconUrl("icon.url");
homeSp.setHomeNetworkIds(homeNetworkIds);
- homeSp.setMatchAllOIs(new long[] {0x11L, 0x22L});
- homeSp.setMatchAnyOIs(new long[] {0x33L, 0x44L});
+ homeSp.setMatchAllOis(new long[] {0x11L, 0x22L});
+ homeSp.setMatchAnyOis(new long[] {0x33L, 0x44L});
homeSp.setOtherHomePartners(new String[] {"partner1", "partner2"});
- homeSp.setRoamingConsortiumOIs(new long[] {0x55, 0x66});
+ homeSp.setRoamingConsortiumOis(new long[] {0x55, 0x66});
return homeSp;
}
/**
- * Helper function for creating a HomeSP with home network IDs for testing.
+ * Helper function for creating a HomeSp with home network IDs for testing.
*
- * @return {@link HomeSP}
+ * @return {@link HomeSp}
*/
- private static HomeSP createHomeSpWithHomeNetworkIds() {
+ private static HomeSp createHomeSpWithHomeNetworkIds() {
return createHomeSp(createHomeNetworkIds());
}
/**
- * Helper function for creating a HomeSP without home network IDs for testing.
+ * Helper function for creating a HomeSp without home network IDs for testing.
*
- * @return {@link HomeSP}
+ * @return {@link HomeSp}
*/
- private static HomeSP createHomeSpWithoutHomeNetworkIds() {
+ private static HomeSp createHomeSpWithoutHomeNetworkIds() {
return createHomeSp(null);
}
/**
- * Helper function for verifying HomeSP after parcel write then read.
+ * Helper function for verifying HomeSp after parcel write then read.
* @param writeHomeSp
* @throws Exception
*/
- private static void verifyParcel(HomeSP writeHomeSp) throws Exception {
+ private static void verifyParcel(HomeSp writeHomeSp) throws Exception {
Parcel parcel = Parcel.obtain();
writeHomeSp.writeToParcel(parcel, 0);
parcel.setDataPosition(0); // Rewind data position back to the beginning for read.
- HomeSP readHomeSp = HomeSP.CREATOR.createFromParcel(parcel);
+ HomeSp readHomeSp = HomeSp.CREATOR.createFromParcel(parcel);
assertTrue(readHomeSp.equals(writeHomeSp));
}
/**
- * Verify parcel read/write for an empty HomeSP.
+ * Verify parcel read/write for an empty HomeSp.
*
* @throws Exception
*/
@Test
- public void verifyParcelWithEmptyHomeSP() throws Exception {
- verifyParcel(new HomeSP());
+ public void verifyParcelWithEmptyHomeSp() throws Exception {
+ verifyParcel(new HomeSp());
}
/**
- * Verify parcel read/write for a HomeSP containing Home Network IDs.
+ * Verify parcel read/write for a HomeSp containing Home Network IDs.
*
* @throws Exception
*/
@@ -119,7 +119,7 @@
}
/**
- * Verify parcel read/write for a HomeSP without Home Network IDs.
+ * Verify parcel read/write for a HomeSp without Home Network IDs.
*
* @throws Exception
*/
@@ -129,62 +129,62 @@
}
/**
- * Verify that a HomeSP is valid when both FQDN and Friendly Name
+ * Verify that a HomeSp is valid when both FQDN and Friendly Name
* are provided.
*
* @throws Exception
*/
@Test
- public void validateValidHomeSP() throws Exception {
- HomeSP homeSp = createHomeSpWithHomeNetworkIds();
+ public void validateValidHomeSp() throws Exception {
+ HomeSp homeSp = createHomeSpWithHomeNetworkIds();
assertTrue(homeSp.validate());
}
/**
- * Verify that a HomeSP is not valid when FQDN is not provided
+ * Verify that a HomeSp is not valid when FQDN is not provided
*
* @throws Exception
*/
@Test
public void validateHomeSpWithoutFqdn() throws Exception {
- HomeSP homeSp = createHomeSpWithHomeNetworkIds();
+ HomeSp homeSp = createHomeSpWithHomeNetworkIds();
homeSp.setFqdn(null);
assertFalse(homeSp.validate());
}
/**
- * Verify that a HomeSP is not valid when Friendly Name is not provided
+ * Verify that a HomeSp is not valid when Friendly Name is not provided
*
* @throws Exception
*/
@Test
public void validateHomeSpWithoutFriendlyName() throws Exception {
- HomeSP homeSp = createHomeSpWithHomeNetworkIds();
+ HomeSp homeSp = createHomeSpWithHomeNetworkIds();
homeSp.setFriendlyName(null);
assertFalse(homeSp.validate());
}
/**
- * Verify that a HomeSP is valid when the optional Home Network IDs are
+ * Verify that a HomeSp is valid when the optional Home Network IDs are
* not provided.
*
* @throws Exception
*/
@Test
public void validateHomeSpWithoutHomeNetworkIds() throws Exception {
- HomeSP homeSp = createHomeSpWithoutHomeNetworkIds();
+ HomeSp homeSp = createHomeSpWithoutHomeNetworkIds();
assertTrue(homeSp.validate());
}
/**
- * Verify that a HomeSP is invalid when the optional Home Network IDs
+ * Verify that a HomeSp is invalid when the optional Home Network IDs
* contained an invalid SSID (exceeding maximum number of bytes).
*
* @throws Exception
*/
@Test
public void validateHomeSpWithInvalidHomeNetworkIds() throws Exception {
- HomeSP homeSp = createHomeSpWithoutHomeNetworkIds();
+ HomeSp homeSp = createHomeSpWithoutHomeNetworkIds();
// HomeNetworkID with SSID exceeding the maximum length.
Map<String, Long> homeNetworkIds = new HashMap<>();
byte[] rawSsidBytes = new byte[33];
@@ -202,8 +202,8 @@
*/
@Test
public void validateCopyConstructorFromNullSource() throws Exception {
- HomeSP copySp = new HomeSP(null);
- HomeSP defaultSp = new HomeSP();
+ HomeSp copySp = new HomeSp(null);
+ HomeSp defaultSp = new HomeSp();
assertTrue(copySp.equals(defaultSp));
}
@@ -214,8 +214,8 @@
*/
@Test
public void validateCopyConstructorFromValidSource() throws Exception {
- HomeSP sourceSp = createHomeSpWithHomeNetworkIds();
- HomeSP copySp = new HomeSP(sourceSp);
+ HomeSp sourceSp = createHomeSpWithHomeNetworkIds();
+ HomeSp copySp = new HomeSp(sourceSp);
assertTrue(copySp.equals(sourceSp));
}
}