diff options
585 files changed, 7656 insertions, 3075 deletions
diff --git a/Android.bp b/Android.bp index 092f548d8e07..abeeb4395015 100644 --- a/Android.bp +++ b/Android.bp @@ -570,7 +570,6 @@ java_defaults { "telephony/java/com/android/internal/telephony/IOnSubscriptionsChangedListener.aidl", "telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl", "telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl", - "telephony/java/com/android/internal/telephony/IRcs.aidl", "telephony/java/com/android/internal/telephony/ISms.aidl", "telephony/java/com/android/internal/telephony/ISub.aidl", "telephony/java/com/android/internal/telephony/IAns.aidl", @@ -601,6 +600,7 @@ java_defaults { "telephony/java/com/android/internal/telephony/euicc/ISetDefaultSmdpAddressCallback.aidl", "telephony/java/com/android/internal/telephony/euicc/ISetNicknameCallback.aidl", "telephony/java/com/android/internal/telephony/euicc/ISwitchToProfileCallback.aidl", + "telephony/java/com/android/internal/telephony/rcs/IRcs.aidl", "wifi/java/android/net/wifi/INetworkRequestMatchCallback.aidl", "wifi/java/android/net/wifi/INetworkRequestUserSelectionCallback.aidl", "wifi/java/android/net/wifi/ISoftApCallback.aidl", diff --git a/api/current.txt b/api/current.txt index 42e616ac3ee7..ea6f190ca44c 100755 --- a/api/current.txt +++ b/api/current.txt @@ -740,6 +740,7 @@ package android { field public static final int immersive = 16843456; // 0x10102c0 field public static final int importantForAccessibility = 16843690; // 0x10103aa field public static final int importantForAutofill = 16844120; // 0x1010558 + field public static final int importantForContentCapture = 16844182; // 0x1010596 field public static final int inAnimation = 16843127; // 0x1010177 field public static final int includeFontPadding = 16843103; // 0x101015f field public static final int includeInGlobalSearch = 16843374; // 0x101026e @@ -7580,6 +7581,8 @@ package android.app.usage { method public java.lang.String getShortcutId(); method public long getTimeStamp(); field public static final int CONFIGURATION_CHANGE = 5; // 0x5 + field public static final int FOREGROUND_SERVICE_START = 19; // 0x13 + field public static final int FOREGROUND_SERVICE_STOP = 20; // 0x14 field public static final int KEYGUARD_HIDDEN = 18; // 0x12 field public static final int KEYGUARD_SHOWN = 17; // 0x11 field public static final int MOVE_TO_BACKGROUND = 2; // 0x2 @@ -7597,9 +7600,11 @@ package android.app.usage { method public void add(android.app.usage.UsageStats); method public int describeContents(); method public long getFirstTimeStamp(); + method public long getLastTimeForegroundServiceUsed(); method public long getLastTimeStamp(); method public long getLastTimeUsed(); method public java.lang.String getPackageName(); + method public long getTotalTimeForegroundServiceUsed(); method public long getTotalTimeInForeground(); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator<android.app.usage.UsageStats> CREATOR; @@ -9470,6 +9475,7 @@ package android.content { public abstract class Context { ctor public Context(); + method public abstract boolean bindIsolatedService(android.content.Intent, android.content.ServiceConnection, int, java.lang.String); method public abstract boolean bindService(android.content.Intent, android.content.ServiceConnection, int); method public abstract int checkCallingOrSelfPermission(java.lang.String); method public abstract int checkCallingOrSelfUriPermission(android.net.Uri, int); @@ -9681,6 +9687,7 @@ package android.content { public class ContextWrapper extends android.content.Context { ctor public ContextWrapper(android.content.Context); method protected void attachBaseContext(android.content.Context); + method public boolean bindIsolatedService(android.content.Intent, android.content.ServiceConnection, int, java.lang.String); method public boolean bindService(android.content.Intent, android.content.ServiceConnection, int); method public int checkCallingOrSelfPermission(java.lang.String); method public int checkCallingOrSelfUriPermission(android.net.Uri, int); @@ -16628,6 +16635,8 @@ package android.hardware.camera2 { field public static final int SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_BGGR = 3; // 0x3 field public static final int SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_GBRG = 2; // 0x2 field public static final int SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_GRBG = 1; // 0x1 + field public static final int SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_MONO = 5; // 0x5 + field public static final int SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_NIR = 6; // 0x6 field public static final int SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_RGB = 4; // 0x4 field public static final int SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_RGGB = 0; // 0x0 field public static final int SENSOR_INFO_TIMESTAMP_SOURCE_REALTIME = 1; // 0x1 @@ -20712,6 +20721,51 @@ package android.icu.text { enum_constant public static final android.icu.text.TimeZoneNames.NameType SHORT_STANDARD; } + public abstract class Transliterator { + method public static final android.icu.text.Transliterator createFromRules(java.lang.String, java.lang.String, int); + method public void filteredTransliterate(android.icu.text.Replaceable, android.icu.text.Transliterator.Position, boolean); + method public final void finishTransliteration(android.icu.text.Replaceable, android.icu.text.Transliterator.Position); + method public static final java.util.Enumeration<java.lang.String> getAvailableIDs(); + method public static final java.util.Enumeration<java.lang.String> getAvailableSources(); + method public static final java.util.Enumeration<java.lang.String> getAvailableTargets(java.lang.String); + method public static final java.util.Enumeration<java.lang.String> getAvailableVariants(java.lang.String, java.lang.String); + method public static final java.lang.String getDisplayName(java.lang.String); + method public static java.lang.String getDisplayName(java.lang.String, java.util.Locale); + method public static java.lang.String getDisplayName(java.lang.String, android.icu.util.ULocale); + method public android.icu.text.Transliterator[] getElements(); + method public final android.icu.text.UnicodeFilter getFilter(); + method public final java.lang.String getID(); + method public static final android.icu.text.Transliterator getInstance(java.lang.String); + method public static android.icu.text.Transliterator getInstance(java.lang.String, int); + method public final android.icu.text.Transliterator getInverse(); + method public final int getMaximumContextLength(); + method public final android.icu.text.UnicodeSet getSourceSet(); + method public android.icu.text.UnicodeSet getTargetSet(); + method public void setFilter(android.icu.text.UnicodeFilter); + method public java.lang.String toRules(boolean); + method public final int transliterate(android.icu.text.Replaceable, int, int); + method public final void transliterate(android.icu.text.Replaceable); + method public final java.lang.String transliterate(java.lang.String); + method public final void transliterate(android.icu.text.Replaceable, android.icu.text.Transliterator.Position, java.lang.String); + method public final void transliterate(android.icu.text.Replaceable, android.icu.text.Transliterator.Position, int); + method public final void transliterate(android.icu.text.Replaceable, android.icu.text.Transliterator.Position); + field public static final int FORWARD = 0; // 0x0 + field public static final int REVERSE = 1; // 0x1 + } + + public static class Transliterator.Position { + ctor public Transliterator.Position(); + ctor public Transliterator.Position(int, int, int); + ctor public Transliterator.Position(int, int, int, int); + ctor public Transliterator.Position(android.icu.text.Transliterator.Position); + method public void set(android.icu.text.Transliterator.Position); + method public final void validate(int); + field public int contextLimit; + field public int contextStart; + field public int limit; + field public int start; + } + public abstract class UCharacterIterator implements java.lang.Cloneable { ctor protected UCharacterIterator(); method public java.lang.Object clone() throws java.lang.CloneNotSupportedException; @@ -42089,7 +42143,7 @@ package android.telecom { field public static final int CAPABILITY_CAN_PAUSE_VIDEO = 1048576; // 0x100000 field public static final int CAPABILITY_CAN_PULL_CALL = 16777216; // 0x1000000 field public static final int CAPABILITY_CAN_SEND_RESPONSE_VIA_CONNECTION = 4194304; // 0x400000 - field public static final int CAPABILITY_CAN_UPGRADE_TO_VIDEO = 524288; // 0x80000 + field public static final deprecated int CAPABILITY_CAN_UPGRADE_TO_VIDEO = 524288; // 0x80000 field public static final int CAPABILITY_DISCONNECT_FROM_CONFERENCE = 8192; // 0x2000 field public static final int CAPABILITY_HOLD = 1; // 0x1 field public static final int CAPABILITY_MANAGE_CONFERENCE = 128; // 0x80 @@ -42509,6 +42563,7 @@ package android.telecom { method public android.telecom.PhoneAccount getPhoneAccount(android.telecom.PhoneAccountHandle); method public java.util.List<android.telecom.PhoneAccountHandle> getSelfManagedPhoneAccounts(); method public android.telecom.PhoneAccountHandle getSimCallManager(); + method public java.lang.String getSystemDialerPackage(); method public java.lang.String getVoiceMailNumber(android.telecom.PhoneAccountHandle); method public boolean handleMmi(java.lang.String); method public boolean handleMmi(java.lang.String, android.telecom.PhoneAccountHandle); @@ -43629,6 +43684,7 @@ package android.telephony { method public int getNetworkType(); method public int getPhoneCount(); method public int getPhoneType(); + method public int getPreferredOpportunisticDataSubscription(); method public android.telephony.ServiceState getServiceState(); method public android.telephony.SignalStrength getSignalStrength(); method public int getSimCarrierId(); @@ -43678,6 +43734,7 @@ package android.telephony { method public boolean setNetworkSelectionModeManual(java.lang.String, boolean); method public boolean setOperatorBrandOverride(java.lang.String); method public boolean setPreferredNetworkTypeToGlobal(); + method public boolean setPreferredOpportunisticDataSubscription(int); method public void setVisualVoicemailSmsFilterSettings(android.telephony.VisualVoicemailSmsFilterSettings); method public boolean setVoiceMailNumber(java.lang.String, java.lang.String); method public deprecated void setVoicemailRingtoneUri(android.telecom.PhoneAccountHandle, android.net.Uri); @@ -48791,6 +48848,7 @@ package android.view { method public int getId(); method public int getImportantForAccessibility(); method public int getImportantForAutofill(); + method public int getImportantForContentCapture(); method public boolean getKeepScreenOn(); method public android.view.KeyEvent.DispatcherState getKeyDispatcherState(); method public int getLabelFor(); @@ -48924,6 +48982,7 @@ package android.view { method public boolean isHovered(); method public boolean isImportantForAccessibility(); method public final boolean isImportantForAutofill(); + method public final boolean isImportantForContentCapture(); method public boolean isInEditMode(); method public boolean isInLayout(); method public boolean isInTouchMode(); @@ -48998,6 +49057,7 @@ package android.view { method public void onPopulateAccessibilityEvent(android.view.accessibility.AccessibilityEvent); method public void onProvideAutofillStructure(android.view.ViewStructure, int); method public void onProvideAutofillVirtualStructure(android.view.ViewStructure, int); + method public boolean onProvideContentCaptureStructure(android.view.ViewStructure, int); method public void onProvideStructure(android.view.ViewStructure); method public void onProvideVirtualStructure(android.view.ViewStructure); method public android.view.PointerIcon onResolvePointerIcon(android.view.MotionEvent, int); @@ -49116,6 +49176,7 @@ package android.view { method public void setId(int); method public void setImportantForAccessibility(int); method public void setImportantForAutofill(int); + method public void setImportantForContentCapture(int); method public void setKeepScreenOn(boolean); method public void setKeyboardNavigationCluster(boolean); method public void setLabelFor(int); @@ -49286,6 +49347,11 @@ package android.view { field public static final int IMPORTANT_FOR_AUTOFILL_NO_EXCLUDE_DESCENDANTS = 8; // 0x8 field public static final int IMPORTANT_FOR_AUTOFILL_YES = 1; // 0x1 field public static final int IMPORTANT_FOR_AUTOFILL_YES_EXCLUDE_DESCENDANTS = 4; // 0x4 + field public static final int IMPORTANT_FOR_CONTENT_CAPTURE_AUTO = 0; // 0x0 + field public static final int IMPORTANT_FOR_CONTENT_CAPTURE_NO = 2; // 0x2 + field public static final int IMPORTANT_FOR_CONTENT_CAPTURE_NO_EXCLUDE_DESCENDANTS = 8; // 0x8 + field public static final int IMPORTANT_FOR_CONTENT_CAPTURE_YES = 1; // 0x1 + field public static final int IMPORTANT_FOR_CONTENT_CAPTURE_YES_EXCLUDE_DESCENDANTS = 4; // 0x4 field public static final int INVISIBLE = 4; // 0x4 field public static final int KEEP_SCREEN_ON = 67108864; // 0x4000000 field public static final int LAYER_TYPE_HARDWARE = 2; // 0x2 @@ -51740,6 +51806,10 @@ package android.view.intelligence { method public void disableContentCapture(); method public android.content.ComponentName getIntelligenceServiceComponentName(); method public boolean isContentCaptureEnabled(); + method public android.view.ViewStructure newVirtualViewStructure(android.view.autofill.AutofillId, int); + method public void notifyViewAppeared(android.view.ViewStructure); + method public void notifyViewDisappeared(android.view.autofill.AutofillId); + method public void notifyViewTextChanged(android.view.autofill.AutofillId, java.lang.CharSequence, int); field public static final int FLAG_USER_INPUT = 1; // 0x1 } @@ -54279,6 +54349,7 @@ package android.widget { method public int getSourceWidth(); method public int getWidth(); method public float getZoom(); + method public boolean isForcePositionWithinWindowSystemInsetsBounds(); method public void setZoom(float); method public void show(float, float); method public void show(float, float, float, float); @@ -54291,6 +54362,7 @@ package android.widget { method public android.widget.Magnifier.Builder setCornerRadius(float); method public android.widget.Magnifier.Builder setDefaultSourceToMagnifierOffset(int, int); method public android.widget.Magnifier.Builder setElevation(float); + method public android.widget.Magnifier.Builder setForcePositionWithinWindowSystemInsetsBounds(boolean); method public android.widget.Magnifier.Builder setSize(int, int); method public android.widget.Magnifier.Builder setZoom(float); } diff --git a/api/system-current.txt b/api/system-current.txt index e0c58b4495e8..fa49f07abf52 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -4109,8 +4109,12 @@ package android.os { } public final class PowerManager { + method public int getPowerSaveMode(); + method public boolean setDynamicPowerSavings(boolean, int); method public boolean setPowerSaveMode(boolean); method public void userActivity(long, int, int); + field public static final int POWER_SAVER_MODE_DYNAMIC = 1; // 0x1 + field public static final int POWER_SAVER_MODE_PERCENTAGE = 0; // 0x0 field public static final int USER_ACTIVITY_EVENT_ACCESSIBILITY = 3; // 0x3 field public static final int USER_ACTIVITY_EVENT_BUTTON = 1; // 0x1 field public static final int USER_ACTIVITY_EVENT_OTHER = 0; // 0x0 @@ -5427,15 +5431,21 @@ package android.telecom { method public int getAllPhoneAccountsCount(); method public int getCallState(); method public android.telecom.PhoneAccountHandle getConnectionManager(); + method public int getCurrentTtyMode(); method public deprecated android.content.ComponentName getDefaultPhoneApp(); method public java.util.List<android.telecom.PhoneAccountHandle> getPhoneAccountsForPackage(); method public java.util.List<android.telecom.PhoneAccountHandle> getPhoneAccountsSupportingScheme(java.lang.String); method public boolean isInEmergencyCall(); method public boolean isRinging(); method public boolean isTtySupported(); + method public boolean setDefaultDialer(java.lang.String); field public static final java.lang.String EXTRA_CALL_BACK_INTENT = "android.telecom.extra.CALL_BACK_INTENT"; field public static final java.lang.String EXTRA_CLEAR_MISSED_CALLS_INTENT = "android.telecom.extra.CLEAR_MISSED_CALLS_INTENT"; field public static final java.lang.String EXTRA_CONNECTION_SERVICE = "android.telecom.extra.CONNECTION_SERVICE"; + field public static final int TTY_MODE_FULL = 1; // 0x1 + field public static final int TTY_MODE_HCO = 2; // 0x2 + field public static final int TTY_MODE_OFF = 0; // 0x0 + field public static final int TTY_MODE_VCO = 3; // 0x3 } } @@ -6999,8 +7009,8 @@ package android.view.intelligence { field public static final int TYPE_ACTIVITY_RESUMED = 2; // 0x2 field public static final int TYPE_ACTIVITY_STARTED = 1; // 0x1 field public static final int TYPE_ACTIVITY_STOPPED = 4; // 0x4 - field public static final int TYPE_VIEW_ADDED = 5; // 0x5 - field public static final int TYPE_VIEW_REMOVED = 6; // 0x6 + field public static final int TYPE_VIEW_APPEARED = 5; // 0x5 + field public static final int TYPE_VIEW_DISAPPEARED = 6; // 0x6 field public static final int TYPE_VIEW_TEXT_CHANGED = 7; // 0x7 } @@ -7400,6 +7410,7 @@ package android.webkit { method public default void onMovedToDisplay(int, android.content.res.Configuration); method public abstract void onOverScrolled(int, int, boolean, boolean); method public default void onProvideAutofillVirtualStructure(android.view.ViewStructure, int); + method public default boolean onProvideContentCaptureStructure(android.view.ViewStructure, int); method public abstract void onProvideVirtualStructure(android.view.ViewStructure); method public abstract void onScrollChanged(int, int, int, int); method public abstract void onSizeChanged(int, int, int, int); diff --git a/api/test-current.txt b/api/test-current.txt index f8179b893c87..5531014cae75 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -25,6 +25,10 @@ package android.animation { package android.app { + public class Activity extends android.view.ContextThemeWrapper implements android.content.ComponentCallbacks2 android.view.KeyEvent.Callback android.view.LayoutInflater.Factory2 android.view.View.OnCreateContextMenuListener android.view.Window.Callback { + method public void onMovedToDisplay(int, android.content.res.Configuration); + } + public class ActivityManager { method public void addOnUidImportanceListener(android.app.ActivityManager.OnUidImportanceListener, int); method public void alwaysShowUnsupportedCompileSdkWarning(android.content.ComponentName); @@ -740,7 +744,11 @@ package android.os { } public final class PowerManager { + method public int getPowerSaveMode(); + method public boolean setDynamicPowerSavings(boolean, int); method public boolean setPowerSaveMode(boolean); + field public static final int POWER_SAVER_MODE_DYNAMIC = 1; // 0x1 + field public static final int POWER_SAVER_MODE_PERCENTAGE = 0; // 0x0 } public class Process { @@ -977,6 +985,9 @@ package android.provider { public static final class Settings.Global extends android.provider.Settings.NameValueTable { field public static final java.lang.String AUTOFILL_COMPAT_MODE_ALLOWED_PACKAGES = "autofill_compat_mode_allowed_packages"; + field public static final java.lang.String AUTOMATIC_POWER_SAVER_MODE = "automatic_power_saver_mode"; + field public static final java.lang.String DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD = "dynamic_power_savings_disable_threshold"; + field public static final java.lang.String DYNAMIC_POWER_SAVINGS_ENABLED = "dynamic_power_savings_enabled"; field public static final java.lang.String HIDDEN_API_BLACKLIST_EXEMPTIONS = "hidden_api_blacklist_exemptions"; field public static final java.lang.String LOCATION_GLOBAL_KILL_SWITCH = "location_global_kill_switch"; field public static final java.lang.String LOW_POWER_MODE = "low_power"; @@ -1592,6 +1603,7 @@ package android.view { public class KeyEvent extends android.view.InputEvent implements android.os.Parcelable { method public static java.lang.String actionToString(int); + method public final void setDisplayId(int); field public static final int LAST_KEYCODE = 288; // 0x120 } @@ -1638,9 +1650,9 @@ package android.view { } public abstract interface WindowManager implements android.view.ViewManager { - method public abstract void setShouldShowIme(int, boolean); - method public abstract void setShouldShowWithInsecureKeyguard(int, boolean); - method public abstract void setShouldShowSystemDecors(int, boolean); + method public default void setShouldShowIme(int, boolean); + method public default void setShouldShowSystemDecors(int, boolean); + method public default void setShouldShowWithInsecureKeyguard(int, boolean); } public static class WindowManager.LayoutParams extends android.view.ViewGroup.LayoutParams implements android.os.Parcelable { diff --git a/cmds/idmap2/idmap2/Scan.cpp b/cmds/idmap2/idmap2/Scan.cpp index 33c274e7fd35..00c49e38e8b2 100644 --- a/cmds/idmap2/idmap2/Scan.cpp +++ b/cmds/idmap2/idmap2/Scan.cpp @@ -138,7 +138,8 @@ bool Scan(const std::vector<std::string>& args, std::ostream& out_error) { std::stringstream stream; for (auto iter = interesting_apks.cbegin(); iter != interesting_apks.cend(); ++iter) { const std::string idmap_path = Idmap::CanonicalIdmapPathFor(output_directory, *iter); - if (!Verify(std::vector<std::string>({"--idmap-path", idmap_path}), out_error) && + std::stringstream dev_null; + if (!Verify(std::vector<std::string>({"--idmap-path", idmap_path}), dev_null) && !Create(std::vector<std::string>({ "--target-apk-path", target_apk_path, diff --git a/cmds/sm/src/com/android/commands/sm/Sm.java b/cmds/sm/src/com/android/commands/sm/Sm.java index c6d717a55f34..783c8c45d603 100644 --- a/cmds/sm/src/com/android/commands/sm/Sm.java +++ b/cmds/sm/src/com/android/commands/sm/Sm.java @@ -127,6 +127,8 @@ public final class Sm { filterType = VolumeInfo.TYPE_PRIVATE; } else if ("emulated".equals(filter)) { filterType = VolumeInfo.TYPE_EMULATED; + } else if ("stub".equals(filter)) { + filterType = VolumeInfo.TYPE_STUB; } else { filterType = -1; } @@ -314,7 +316,7 @@ public final class Sm { private static int showUsage() { System.err.println("usage: sm list-disks [adoptable]"); - System.err.println(" sm list-volumes [public|private|emulated|all]"); + System.err.println(" sm list-volumes [public|private|emulated|stub|all]"); System.err.println(" sm has-adoptable"); System.err.println(" sm get-primary-storage-uuid"); System.err.println(" sm set-force-adoptable [on|off|default]"); diff --git a/cmds/statsd/Android.bp b/cmds/statsd/Android.bp index a3cd8a3bb32b..0114ff488413 100644 --- a/cmds/statsd/Android.bp +++ b/cmds/statsd/Android.bp @@ -72,6 +72,7 @@ cc_defaults { "src/external/StatsPuller.cpp", "src/external/StatsCompanionServicePuller.cpp", "src/external/SubsystemSleepStatePuller.cpp", + "src/external/PowerStatsPuller.cpp", "src/external/ResourceHealthManagerPuller.cpp", "src/external/ResourceThermalManagerPuller.cpp", "src/external/StatsPullerManager.cpp", @@ -134,6 +135,7 @@ cc_defaults { "android.hardware.health@2.0", "android.hardware.power@1.0", "android.hardware.power@1.1", + "android.hardware.power.stats@1.0", "android.hardware.thermal@1.0", "libpackagelistparser", "libsysutils", diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto index 5620184d5038..53d967363765 100644 --- a/cmds/statsd/src/atoms.proto +++ b/cmds/statsd/src/atoms.proto @@ -147,6 +147,7 @@ message Atom { PhoneStateChanged phone_state_changed = 95; UserRestrictionChanged user_restriction_changed = 96; SettingsUIChanged settings_ui_changed = 97; + ConnectivityStateChanged connectivity_state_changed = 98; } // Pulled events will start at field 10000. @@ -190,6 +191,7 @@ message Atom { ProcessCpuTime process_cpu_time = 10035; NativeProcessMemoryState native_process_memory_state = 10036; CpuTimePerThreadFreq cpu_time_per_thread_freq = 10037; + OnDevicePowerMeasurement on_device_power_measurement = 10038; } // DO NOT USE field numbers above 100,000 in AOSP. @@ -2128,6 +2130,22 @@ message Notification { optional int64 visible_millis = 16; } +/* + * Logs when a connection becomes available and lost. + * Logged in StatsCompanionService.java + */ +message ConnectivityStateChanged { + // Id of the network. + optional int32 net_id = 1; + + enum State { + UNKNOWN = 0; + CONNECTED = 1; + DISCONNECTED = 2; + } + // Connected state of a network. + optional State state = 2; +} ////////////////////////////////////////////////////////////////////// // Pulled atoms below this line // @@ -2262,6 +2280,27 @@ message SubsystemSleepState { } /** + * Pulls on-device power measurement information. + * Data defined by hardware/interfaces/power/stats/1.0/types.hal. + * Pulled from: + * frameworks/base/cmds/statsd/src/external/PowerStatsPuller.cpp + */ +message OnDevicePowerMeasurement { + // Name of the subsystem (to which the rail belongs). + optional string subsystem_name = 1; + + // Rail name. The rail lies within the subsystem. + optional string rail_name = 2; + + // Time (in ms since boot) at which the rail energy value was measured. + // This may differ slightly from the time that statsd logs this information. + optional uint64 measurement_timestamp_millis = 3; + + // Accumulated energy used via the rail since device boot in uWs. + optional uint64 energy_microwatt_secs = 4; +} + +/** * Pulls Cpu time per frequency. * Pulls the time the cpu spend on the frequency index. Frequency index * starts from highest to lowest. The value should be monotonically diff --git a/cmds/statsd/src/external/PowerStatsPuller.cpp b/cmds/statsd/src/external/PowerStatsPuller.cpp new file mode 100644 index 000000000000..71e5fa0c710d --- /dev/null +++ b/cmds/statsd/src/external/PowerStatsPuller.cpp @@ -0,0 +1,146 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define DEBUG false // STOPSHIP if true +#include "Log.h" + +#include <android/hardware/power/stats/1.0/IPowerStats.h> + +#include <vector> + +#include "PowerStatsPuller.h" +#include "stats_log_util.h" + +using android::hardware::hidl_vec; +using android::hardware::power::stats::V1_0::IPowerStats; +using android::hardware::power::stats::V1_0::EnergyData; +using android::hardware::power::stats::V1_0::RailInfo; +using android::hardware::power::stats::V1_0::Status; +using android::hardware::Return; +using android::hardware::Void; + +using std::make_shared; +using std::shared_ptr; + +namespace android { +namespace os { +namespace statsd { + +sp<android::hardware::power::stats::V1_0::IPowerStats> gPowerStatsHal = nullptr; +std::mutex gPowerStatsHalMutex; +bool gPowerStatsExist = true; // Initialized to ensure making a first attempt. +std::vector<RailInfo> gRailInfo; + +bool getPowerStatsHal() { + if (gPowerStatsHal == nullptr && gPowerStatsExist) { + gPowerStatsHal = android::hardware::power::stats::V1_0::IPowerStats::getService(); + if (gPowerStatsHal == nullptr) { + ALOGW("Couldn't load power.stats HAL service"); + gPowerStatsExist = false; + } + } + return gPowerStatsHal != nullptr; +} + +PowerStatsPuller::PowerStatsPuller() : StatsPuller(android::util::ON_DEVICE_POWER_MEASUREMENT) { +} + +bool PowerStatsPuller::PullInternal(vector<shared_ptr<LogEvent>>* data) { + std::lock_guard<std::mutex> lock(gPowerStatsHalMutex); + + if (!getPowerStatsHal()) { + ALOGE("power.stats Hal not loaded"); + return false; + } + + int64_t wallClockTimestampNs = getWallClockNs(); + int64_t elapsedTimestampNs = getElapsedRealtimeNs(); + + data->clear(); + + // Pull getRailInfo if necessary + if (gRailInfo.empty()) { + bool resultSuccess = true; + Return<void> ret = gPowerStatsHal->getRailInfo( + [&resultSuccess](const hidl_vec<RailInfo> &list, Status status) { + resultSuccess = (status == Status::SUCCESS || status == Status::NOT_SUPPORTED); + if (status != Status::SUCCESS) return; + + gRailInfo.reserve(list.size()); + for (size_t i = 0; i < list.size(); ++i) { + gRailInfo.push_back(list[i]); + } + }); + if (!resultSuccess || !ret.isOk()) { + ALOGE("power.stats getRailInfo() failed. Description: %s", ret.description().c_str()); + gPowerStatsHal = nullptr; + return false; + } + // If SUCCESS but empty, or if NOT_SUPPORTED, then never try again. + if (gRailInfo.empty()) { + ALOGE("power.stats has no rail information"); + gPowerStatsExist = false; // No rail info, so never try again. + return false; + } + } + + // Pull getEnergyData and write the data out + const hidl_vec<uint32_t> desiredRailIndices; // Empty vector indicates we want all. + bool resultSuccess = true; + Return<void> ret = gPowerStatsHal->getEnergyData(desiredRailIndices, + [&data, wallClockTimestampNs, elapsedTimestampNs, &resultSuccess] + (hidl_vec<EnergyData> energyDataList, Status status) { + resultSuccess = (status == Status::SUCCESS); + if (!resultSuccess) return; + + for (size_t i = 0; i < energyDataList.size(); i++) { + const EnergyData& energyData = energyDataList[i]; + + if (energyData.index >= gRailInfo.size()) { + ALOGE("power.stats getEnergyData() returned an invalid rail index %u.", + energyData.index); + resultSuccess = false; + return; + } + const RailInfo& rail = gRailInfo[energyData.index]; + + auto ptr = make_shared<LogEvent>(android::util::ON_DEVICE_POWER_MEASUREMENT, + wallClockTimestampNs, elapsedTimestampNs); + ptr->write(rail.subsysName); + ptr->write(rail.railName); + ptr->write(energyData.timestamp); + ptr->write(energyData.energy); + ptr->init(); + data->push_back(ptr); + + VLOG("power.stat: %s.%s: %llu, %llu", + rail.subsysName.c_str(), + rail.railName.c_str(), + (unsigned long long)energyData.timestamp, + (unsigned long long)energyData.energy); + } + }); + if (!resultSuccess || !ret.isOk()) { + ALOGE("power.stats getEnergyData() failed. Description: %s", ret.description().c_str()); + gPowerStatsHal = nullptr; + return false; + } + return true; +} + +} // namespace statsd +} // namespace os +} // namespace android diff --git a/cmds/statsd/src/external/PowerStatsPuller.h b/cmds/statsd/src/external/PowerStatsPuller.h new file mode 100644 index 000000000000..dd5ff8fe08d0 --- /dev/null +++ b/cmds/statsd/src/external/PowerStatsPuller.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "StatsPuller.h" + +namespace android { +namespace os { +namespace statsd { + +/** + * Reads hal for power.stats + */ +class PowerStatsPuller : public StatsPuller { +public: + PowerStatsPuller(); + bool PullInternal(vector<std::shared_ptr<LogEvent>>* data) override; +}; + +} // namespace statsd +} // namespace os +} // namespace android diff --git a/cmds/statsd/src/external/StatsPullerManager.cpp b/cmds/statsd/src/external/StatsPullerManager.cpp index 9633980420ef..8378ae15c1ef 100644 --- a/cmds/statsd/src/external/StatsPullerManager.cpp +++ b/cmds/statsd/src/external/StatsPullerManager.cpp @@ -26,6 +26,7 @@ #include "../logd/LogEvent.h" #include "../stats_log_util.h" #include "../statscompanion_util.h" +#include "PowerStatsPuller.h" #include "ResourceHealthManagerPuller.h" #include "ResourceThermalManagerPuller.h" #include "StatsCompanionServicePuller.h" @@ -86,6 +87,9 @@ const std::map<int, PullAtomInfo> StatsPullerManager::kAllPullAtomInfo = { // subsystem_sleep_state {android::util::SUBSYSTEM_SLEEP_STATE, {{}, {}, 1 * NS_PER_SEC, new SubsystemSleepStatePuller()}}, + // on_device_power_measurement + {android::util::ON_DEVICE_POWER_MEASUREMENT, + {{}, {}, 1 * NS_PER_SEC, new PowerStatsPuller()}}, // cpu_time_per_freq {android::util::CPU_TIME_PER_FREQ, {{3}, diff --git a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp index 05103a962c33..461ad28dc77f 100644 --- a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp +++ b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp @@ -140,7 +140,7 @@ GaugeMetricProducer::GaugeMetricProducer(const ConfigKey& key, const GaugeMetric // Adjust start for partial bucket mCurrentBucketStartTimeNs = startTimeNs; - if (mIsPulled) { + if (mIsPulled && mSamplingType == GaugeMetric::RANDOM_ONE_SAMPLE) { pullAndMatchEventsLocked(startTimeNs); } diff --git a/cmds/statsd/src/metrics/GaugeMetricProducer.h b/cmds/statsd/src/metrics/GaugeMetricProducer.h index 5866139047ae..6e3530b0daf4 100644 --- a/cmds/statsd/src/metrics/GaugeMetricProducer.h +++ b/cmds/statsd/src/metrics/GaugeMetricProducer.h @@ -80,7 +80,7 @@ public: } flushCurrentBucketLocked(eventTimeNs); mCurrentBucketStartTimeNs = eventTimeNs; - if (mIsPulled) { + if (mIsPulled && mSamplingType == GaugeMetric::RANDOM_ONE_SAMPLE) { pullAndMatchEventsLocked(eventTimeNs); } }; diff --git a/cmds/statsd/src/statsd_config.proto b/cmds/statsd/src/statsd_config.proto index 5c46a296b9bf..aa789c799056 100644 --- a/cmds/statsd/src/statsd_config.proto +++ b/cmds/statsd/src/statsd_config.proto @@ -274,6 +274,7 @@ message ValueMetric { optional bool use_diff = 12; enum ValueDirection { + UNKNOWN = 0; INCREASING = 1; DECREASING = 2; ANY = 3; diff --git a/config/hiddenapi-light-greylist.txt b/config/hiddenapi-light-greylist.txt index 099756691c4e..851e35b5e9f0 100644 --- a/config/hiddenapi-light-greylist.txt +++ b/config/hiddenapi-light-greylist.txt @@ -441,6 +441,8 @@ Landroid/hardware/location/IActivityRecognitionHardwareClient$Stub;-><init>()V Landroid/hardware/location/IContextHubService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/hardware/location/IContextHubService; Landroid/hardware/usb/IUsbManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V Landroid/hardware/usb/IUsbManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/hardware/usb/IUsbManager; +Landroid/inputmethodservice/IInputMethodSessionWrapper;->mCaller:Lcom/android/internal/os/HandlerCaller; +Landroid/inputmethodservice/IInputMethodWrapper;->mCaller:Lcom/android/internal/os/HandlerCaller; Landroid/location/ICountryDetector$Stub;->asInterface(Landroid/os/IBinder;)Landroid/location/ICountryDetector; Landroid/location/ICountryListener$Stub;-><init>()V Landroid/location/IGeocodeProvider$Stub;-><init>()V @@ -4210,170 +4212,6 @@ Lcom/android/okhttp/Response;->headers:Lcom/android/okhttp/Headers; Lcom/android/okhttp/Response;->message:Ljava/lang/String; Lcom/android/okhttp/Response;->networkResponse:Lcom/android/okhttp/Response; Lcom/android/okhttp/Response;->protocol:Lcom/android/okhttp/Protocol; -Lcom/android/org/bouncycastle/asn1/ASN1EncodableVector;-><init>()V -Lcom/android/org/bouncycastle/asn1/ASN1EncodableVector;->add(Lcom/android/org/bouncycastle/asn1/ASN1Encodable;)V -Lcom/android/org/bouncycastle/asn1/ASN1InputStream;-><init>(Ljava/io/InputStream;)V -Lcom/android/org/bouncycastle/asn1/ASN1InputStream;-><init>([B)V -Lcom/android/org/bouncycastle/asn1/ASN1InputStream;->readObject()Lcom/android/org/bouncycastle/asn1/ASN1Primitive; -Lcom/android/org/bouncycastle/asn1/ASN1Integer;-><init>(Ljava/math/BigInteger;)V -Lcom/android/org/bouncycastle/asn1/DERBitString;-><init>([B)V -Lcom/android/org/bouncycastle/asn1/DEREncodableVector;-><init>()V -Lcom/android/org/bouncycastle/asn1/DERInteger;-><init>(J)V -Lcom/android/org/bouncycastle/asn1/DERInteger;-><init>(Ljava/math/BigInteger;)V -Lcom/android/org/bouncycastle/asn1/DERNull;->INSTANCE:Lcom/android/org/bouncycastle/asn1/DERNull; -Lcom/android/org/bouncycastle/asn1/DERObjectIdentifier;-><init>(Ljava/lang/String;)V -Lcom/android/org/bouncycastle/asn1/DEROctetString;-><init>([B)V -Lcom/android/org/bouncycastle/asn1/DEROutputStream;-><init>(Ljava/io/OutputStream;)V -Lcom/android/org/bouncycastle/asn1/DERSequence;-><init>()V -Lcom/android/org/bouncycastle/asn1/DERSequence;-><init>(Lcom/android/org/bouncycastle/asn1/ASN1EncodableVector;)V -Lcom/android/org/bouncycastle/asn1/DERSet;-><init>(Lcom/android/org/bouncycastle/asn1/ASN1EncodableVector;)V -Lcom/android/org/bouncycastle/asn1/pkcs/PKCSObjectIdentifiers;->sha256WithRSAEncryption:Lcom/android/org/bouncycastle/asn1/ASN1ObjectIdentifier; -Lcom/android/org/bouncycastle/asn1/x509/AlgorithmIdentifier;-><init>(Lcom/android/org/bouncycastle/asn1/ASN1ObjectIdentifier;)V -Lcom/android/org/bouncycastle/asn1/x509/AlgorithmIdentifier;-><init>(Lcom/android/org/bouncycastle/asn1/ASN1ObjectIdentifier;Lcom/android/org/bouncycastle/asn1/ASN1Encodable;)V -Lcom/android/org/bouncycastle/asn1/x509/Certificate;->getInstance(Ljava/lang/Object;)Lcom/android/org/bouncycastle/asn1/x509/Certificate; -Lcom/android/org/bouncycastle/asn1/x509/DigestInfo;-><init>(Lcom/android/org/bouncycastle/asn1/x509/AlgorithmIdentifier;[B)V -Lcom/android/org/bouncycastle/asn1/x509/SubjectPublicKeyInfo;->getInstance(Ljava/lang/Object;)Lcom/android/org/bouncycastle/asn1/x509/SubjectPublicKeyInfo; -Lcom/android/org/bouncycastle/asn1/x509/Time;-><init>(Ljava/util/Date;)V -Lcom/android/org/bouncycastle/asn1/x509/V3TBSCertificateGenerator;-><init>()V -Lcom/android/org/bouncycastle/asn1/x509/V3TBSCertificateGenerator;->generateTBSCertificate()Lcom/android/org/bouncycastle/asn1/x509/TBSCertificate; -Lcom/android/org/bouncycastle/asn1/x509/V3TBSCertificateGenerator;->setEndDate(Lcom/android/org/bouncycastle/asn1/x509/Time;)V -Lcom/android/org/bouncycastle/asn1/x509/V3TBSCertificateGenerator;->setIssuer(Lcom/android/org/bouncycastle/asn1/x509/X509Name;)V -Lcom/android/org/bouncycastle/asn1/x509/V3TBSCertificateGenerator;->setSerialNumber(Lcom/android/org/bouncycastle/asn1/ASN1Integer;)V -Lcom/android/org/bouncycastle/asn1/x509/V3TBSCertificateGenerator;->setSignature(Lcom/android/org/bouncycastle/asn1/x509/AlgorithmIdentifier;)V -Lcom/android/org/bouncycastle/asn1/x509/V3TBSCertificateGenerator;->setStartDate(Lcom/android/org/bouncycastle/asn1/x509/Time;)V -Lcom/android/org/bouncycastle/asn1/x509/V3TBSCertificateGenerator;->setSubject(Lcom/android/org/bouncycastle/asn1/x509/X509Name;)V -Lcom/android/org/bouncycastle/asn1/x509/V3TBSCertificateGenerator;->setSubjectPublicKeyInfo(Lcom/android/org/bouncycastle/asn1/x509/SubjectPublicKeyInfo;)V -Lcom/android/org/bouncycastle/asn1/x509/X509Name;-><init>(Lcom/android/org/bouncycastle/asn1/ASN1Sequence;)V -Lcom/android/org/bouncycastle/asn1/x509/X509Name;-><init>(Ljava/lang/String;)V -Lcom/android/org/bouncycastle/asn1/x509/X509Name;->CN:Lcom/android/org/bouncycastle/asn1/ASN1ObjectIdentifier; -Lcom/android/org/bouncycastle/asn1/x509/X509Name;->getOIDs()Ljava/util/Vector; -Lcom/android/org/bouncycastle/asn1/x509/X509Name;->getValues()Ljava/util/Vector; -Lcom/android/org/bouncycastle/asn1/x9/X9ObjectIdentifiers;->ecdsa_with_SHA256:Lcom/android/org/bouncycastle/asn1/ASN1ObjectIdentifier; -Lcom/android/org/bouncycastle/jce/provider/BouncyCastleProvider;-><init>()V -Lcom/android/org/bouncycastle/jce/provider/X509CertificateObject;-><init>(Lcom/android/org/bouncycastle/asn1/x509/Certificate;)V -Lcom/android/org/bouncycastle/jce/X509Principal;-><init>([B)V -Lcom/android/org/bouncycastle/x509/X509V3CertificateGenerator;-><init>()V -Lcom/android/org/bouncycastle/x509/X509V3CertificateGenerator;->generate(Ljava/security/PrivateKey;)Ljava/security/cert/X509Certificate; -Lcom/android/org/bouncycastle/x509/X509V3CertificateGenerator;->setIssuerDN(Lcom/android/org/bouncycastle/asn1/x509/X509Name;)V -Lcom/android/org/bouncycastle/x509/X509V3CertificateGenerator;->setIssuerDN(Ljavax/security/auth/x500/X500Principal;)V -Lcom/android/org/bouncycastle/x509/X509V3CertificateGenerator;->setNotAfter(Ljava/util/Date;)V -Lcom/android/org/bouncycastle/x509/X509V3CertificateGenerator;->setNotBefore(Ljava/util/Date;)V -Lcom/android/org/bouncycastle/x509/X509V3CertificateGenerator;->setPublicKey(Ljava/security/PublicKey;)V -Lcom/android/org/bouncycastle/x509/X509V3CertificateGenerator;->setSerialNumber(Ljava/math/BigInteger;)V -Lcom/android/org/bouncycastle/x509/X509V3CertificateGenerator;->setSignatureAlgorithm(Ljava/lang/String;)V -Lcom/android/org/bouncycastle/x509/X509V3CertificateGenerator;->setSubjectDN(Lcom/android/org/bouncycastle/asn1/x509/X509Name;)V -Lcom/android/org/bouncycastle/x509/X509V3CertificateGenerator;->setSubjectDN(Ljavax/security/auth/x500/X500Principal;)V -Lcom/android/org/conscrypt/AbstractConscryptSocket;->getAlpnSelectedProtocol()[B -Lcom/android/org/conscrypt/AbstractConscryptSocket;->getApplicationProtocols()[Ljava/lang/String; -Lcom/android/org/conscrypt/AbstractConscryptSocket;->getChannelId()[B -Lcom/android/org/conscrypt/AbstractConscryptSocket;->getHostname()Ljava/lang/String; -Lcom/android/org/conscrypt/AbstractConscryptSocket;->getHostnameOrIP()Ljava/lang/String; -Lcom/android/org/conscrypt/AbstractConscryptSocket;->getNpnSelectedProtocol()[B -Lcom/android/org/conscrypt/AbstractConscryptSocket;->getSoWriteTimeout()I -Lcom/android/org/conscrypt/AbstractConscryptSocket;->setAlpnProtocols([B)V -Lcom/android/org/conscrypt/AbstractConscryptSocket;->setAlpnProtocols([Ljava/lang/String;)V -Lcom/android/org/conscrypt/AbstractConscryptSocket;->setApplicationProtocols([Ljava/lang/String;)V -Lcom/android/org/conscrypt/AbstractConscryptSocket;->setChannelIdEnabled(Z)V -Lcom/android/org/conscrypt/AbstractConscryptSocket;->setChannelIdPrivateKey(Ljava/security/PrivateKey;)V -Lcom/android/org/conscrypt/AbstractConscryptSocket;->setHandshakeTimeout(I)V -Lcom/android/org/conscrypt/AbstractConscryptSocket;->setHostname(Ljava/lang/String;)V -Lcom/android/org/conscrypt/AbstractConscryptSocket;->setNpnProtocols([B)V -Lcom/android/org/conscrypt/AbstractConscryptSocket;->setSoWriteTimeout(I)V -Lcom/android/org/conscrypt/AbstractConscryptSocket;->setUseSessionTickets(Z)V -Lcom/android/org/conscrypt/ClientSessionContext;->getSession(Ljava/lang/String;I)Lcom/android/org/conscrypt/NativeSslSession; -Lcom/android/org/conscrypt/ClientSessionContext;->setPersistentCache(Lcom/android/org/conscrypt/SSLClientSessionCache;)V -Lcom/android/org/conscrypt/ConscryptFileDescriptorSocket;->setHostname(Ljava/lang/String;)V -Lcom/android/org/conscrypt/ConscryptFileDescriptorSocket;->setUseSessionTickets(Z)V -Lcom/android/org/conscrypt/FileClientSessionCache$Impl;->getSessionData(Ljava/lang/String;I)[B -Lcom/android/org/conscrypt/FileClientSessionCache;->usingDirectory(Ljava/io/File;)Lcom/android/org/conscrypt/SSLClientSessionCache; -Lcom/android/org/conscrypt/NativeCrypto;->ASN1_seq_pack_X509([J)[B -Lcom/android/org/conscrypt/NativeCrypto;->ASN1_seq_unpack_X509_bio(J)[J -Lcom/android/org/conscrypt/NativeCrypto;->ASN1_TIME_to_Calendar(JLjava/util/Calendar;)V -Lcom/android/org/conscrypt/NativeCrypto;->BIO_free_all(J)V -Lcom/android/org/conscrypt/NativeCrypto;->create_BIO_InputStream(Lcom/android/org/conscrypt/OpenSSLBIOInputStream;Z)J -Lcom/android/org/conscrypt/NativeCrypto;->create_BIO_OutputStream(Ljava/io/OutputStream;)J -Lcom/android/org/conscrypt/NativeCrypto;->d2i_PKCS7_bio(JI)[J -Lcom/android/org/conscrypt/NativeCrypto;->d2i_SSL_SESSION([B)J -Lcom/android/org/conscrypt/NativeCrypto;->d2i_X509([B)J -Lcom/android/org/conscrypt/NativeCrypto;->d2i_X509_bio(J)J -Lcom/android/org/conscrypt/NativeCrypto;->d2i_X509_CRL_bio(J)J -Lcom/android/org/conscrypt/NativeCrypto;->EC_GROUP_clear_free(J)V -Lcom/android/org/conscrypt/NativeCrypto;->EC_GROUP_new_by_curve_name(Ljava/lang/String;)J -Lcom/android/org/conscrypt/NativeCrypto;->EC_POINT_clear_free(J)V -Lcom/android/org/conscrypt/NativeCrypto;->EVP_CIPHER_CTX_new()J -Lcom/android/org/conscrypt/NativeCrypto;->EVP_CIPHER_iv_length(J)I -Lcom/android/org/conscrypt/NativeCrypto;->EVP_get_cipherbyname(Ljava/lang/String;)J -Lcom/android/org/conscrypt/NativeCrypto;->EVP_get_digestbyname(Ljava/lang/String;)J -Lcom/android/org/conscrypt/NativeCrypto;->EVP_MD_CTX_create()J -Lcom/android/org/conscrypt/NativeCrypto;->EVP_MD_CTX_destroy(J)V -Lcom/android/org/conscrypt/NativeCrypto;->EVP_MD_size(J)I -Lcom/android/org/conscrypt/NativeCrypto;->EVP_PKEY_free(J)V -Lcom/android/org/conscrypt/NativeCrypto;->EVP_PKEY_new_RSA([B[B[B[B[B[B[B[B)J -Lcom/android/org/conscrypt/NativeCrypto;->get_X509_REVOKED_ext_oids(JI)[Ljava/lang/String; -Lcom/android/org/conscrypt/NativeCrypto;->get_X509_REVOKED_revocationDate(J)J -Lcom/android/org/conscrypt/NativeCrypto;->i2d_PKCS7([J)[B -Lcom/android/org/conscrypt/NativeCrypto;->i2d_SSL_SESSION(J)[B -Lcom/android/org/conscrypt/NativeCrypto;->i2d_X509_REVOKED(J)[B -Lcom/android/org/conscrypt/NativeCrypto;->PEM_read_bio_PKCS7(JI)[J -Lcom/android/org/conscrypt/NativeCrypto;->PEM_read_bio_X509(J)J -Lcom/android/org/conscrypt/NativeCrypto;->PEM_read_bio_X509_CRL(J)J -Lcom/android/org/conscrypt/NativeCrypto;->RAND_bytes([B)V -Lcom/android/org/conscrypt/NativeCrypto;->RSA_generate_key_ex(I[B)J -Lcom/android/org/conscrypt/NativeCrypto;->SSL_CTX_new()J -Lcom/android/org/conscrypt/NativeCrypto;->SSL_SESSION_cipher(J)Ljava/lang/String; -Lcom/android/org/conscrypt/NativeCrypto;->SSL_SESSION_free(J)V -Lcom/android/org/conscrypt/NativeCrypto;->SSL_SESSION_get_time(J)J -Lcom/android/org/conscrypt/NativeCrypto;->SSL_SESSION_get_version(J)Ljava/lang/String; -Lcom/android/org/conscrypt/NativeCrypto;->SSL_SESSION_session_id(J)[B -Lcom/android/org/conscrypt/NativeCrypto;->X509_REVOKED_dup(J)J -Lcom/android/org/conscrypt/NativeCrypto;->X509_REVOKED_get_ext(JLjava/lang/String;)J -Lcom/android/org/conscrypt/NativeCrypto;->X509_REVOKED_get_ext_oid(JLjava/lang/String;)[B -Lcom/android/org/conscrypt/NativeCrypto;->X509_REVOKED_get_serialNumber(J)[B -Lcom/android/org/conscrypt/NativeCrypto;->X509_REVOKED_print(JJ)V -Lcom/android/org/conscrypt/NativeCrypto;->X509_supported_extension(J)I -Lcom/android/org/conscrypt/OpenSSLBIOInputStream;-><init>(Ljava/io/InputStream;Z)V -Lcom/android/org/conscrypt/OpenSSLBIOInputStream;->getBioContext()J -Lcom/android/org/conscrypt/OpenSSLBIOInputStream;->release()V -Lcom/android/org/conscrypt/OpenSSLContextImpl$TLSv12;-><init>()V -Lcom/android/org/conscrypt/OpenSSLContextImpl;-><init>()V -Lcom/android/org/conscrypt/OpenSSLContextImpl;->engineGetClientSessionContext()Lcom/android/org/conscrypt/ClientSessionContext; -Lcom/android/org/conscrypt/OpenSSLContextImpl;->getPreferred()Lcom/android/org/conscrypt/OpenSSLContextImpl; -Lcom/android/org/conscrypt/OpenSSLKey;-><init>(J)V -Lcom/android/org/conscrypt/OpenSSLKey;->fromPrivateKey(Ljava/security/PrivateKey;)Lcom/android/org/conscrypt/OpenSSLKey; -Lcom/android/org/conscrypt/OpenSSLKey;->getNativeRef()Lcom/android/org/conscrypt/NativeRef$EVP_PKEY; -Lcom/android/org/conscrypt/OpenSSLKey;->getPublicKey()Ljava/security/PublicKey; -Lcom/android/org/conscrypt/OpenSSLKeyHolder;->getOpenSSLKey()Lcom/android/org/conscrypt/OpenSSLKey; -Lcom/android/org/conscrypt/OpenSSLProvider;-><init>()V -Lcom/android/org/conscrypt/OpenSSLRandom;-><init>()V -Lcom/android/org/conscrypt/OpenSSLSocketFactoryImpl;-><init>()V -Lcom/android/org/conscrypt/OpenSSLSocketFactoryImpl;->sslParameters:Lcom/android/org/conscrypt/SSLParametersImpl; -Lcom/android/org/conscrypt/OpenSSLSocketImpl;->getAlpnSelectedProtocol()[B -Lcom/android/org/conscrypt/OpenSSLSocketImpl;->getChannelId()[B -Lcom/android/org/conscrypt/OpenSSLSocketImpl;->getHostname()Ljava/lang/String; -Lcom/android/org/conscrypt/OpenSSLSocketImpl;->getHostnameOrIP()Ljava/lang/String; -Lcom/android/org/conscrypt/OpenSSLSocketImpl;->getNpnSelectedProtocol()[B -Lcom/android/org/conscrypt/OpenSSLSocketImpl;->getSoWriteTimeout()I -Lcom/android/org/conscrypt/OpenSSLSocketImpl;->setAlpnProtocols([B)V -Lcom/android/org/conscrypt/OpenSSLSocketImpl;->setAlpnProtocols([Ljava/lang/String;)V -Lcom/android/org/conscrypt/OpenSSLSocketImpl;->setChannelIdEnabled(Z)V -Lcom/android/org/conscrypt/OpenSSLSocketImpl;->setChannelIdPrivateKey(Ljava/security/PrivateKey;)V -Lcom/android/org/conscrypt/OpenSSLSocketImpl;->setHandshakeTimeout(I)V -Lcom/android/org/conscrypt/OpenSSLSocketImpl;->setHostname(Ljava/lang/String;)V -Lcom/android/org/conscrypt/OpenSSLSocketImpl;->setNpnProtocols([B)V -Lcom/android/org/conscrypt/OpenSSLSocketImpl;->setSoWriteTimeout(I)V -Lcom/android/org/conscrypt/OpenSSLSocketImpl;->setUseSessionTickets(Z)V -Lcom/android/org/conscrypt/OpenSSLX509Certificate;->fromX509PemInputStream(Ljava/io/InputStream;)Lcom/android/org/conscrypt/OpenSSLX509Certificate; -Lcom/android/org/conscrypt/OpenSSLX509Certificate;->mContext:J -Lcom/android/org/conscrypt/SSLParametersImpl;->getDefault()Lcom/android/org/conscrypt/SSLParametersImpl; -Lcom/android/org/conscrypt/SSLParametersImpl;->getDefaultX509TrustManager()Ljavax/net/ssl/X509TrustManager; -Lcom/android/org/conscrypt/SSLParametersImpl;->getX509TrustManager()Ljavax/net/ssl/X509TrustManager; -Lcom/android/org/conscrypt/SSLParametersImpl;->setEnabledProtocols([Ljava/lang/String;)V -Lcom/android/org/conscrypt/SSLParametersImpl;->x509TrustManager:Ljavax/net/ssl/X509TrustManager; -Lcom/android/org/conscrypt/TrustedCertificateStore;-><init>()V -Lcom/android/org/conscrypt/TrustedCertificateStore;->getCertificateChain(Ljava/security/cert/X509Certificate;)Ljava/util/List; -Lcom/android/org/conscrypt/TrustManagerImpl;-><init>(Ljava/security/KeyStore;)V -Lcom/android/org/conscrypt/TrustManagerImpl;->checkServerTrusted([Ljava/security/cert/X509Certificate;Ljava/lang/String;Ljava/lang/String;)Ljava/util/List; -Lcom/android/org/conscrypt/X509PublicKey;-><init>(Ljava/lang/String;[B)V Lcom/android/server/net/BaseNetworkObserver;-><init>()V Lcom/android/server/net/NetlinkTracker;-><init>(Ljava/lang/String;Lcom/android/server/net/NetlinkTracker$Callback;)V Lcom/android/server/net/NetlinkTracker;->clearLinkProperties()V diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java index fade5742dc83..553acc8dcbd3 100644 --- a/core/java/android/app/Activity.java +++ b/core/java/android/app/Activity.java @@ -31,6 +31,7 @@ import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.StyleRes; import android.annotation.SystemApi; +import android.annotation.TestApi; import android.annotation.UnsupportedAppUsage; import android.app.VoiceInteractor.Request; import android.app.admin.DevicePolicyManager; @@ -2346,6 +2347,7 @@ public class Activity extends ContextThemeWrapper * @see View#onMovedToDisplay(int, Configuration) * @hide */ + @TestApi public void onMovedToDisplay(int displayId, Configuration config) { } diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java index dc707e892d9a..9837deb6143c 100644 --- a/core/java/android/app/ContextImpl.java +++ b/core/java/android/app/ContextImpl.java @@ -140,6 +140,13 @@ class ReceiverRestrictedContext extends ContextWrapper { throw new ReceiverCallNotAllowedException( "BroadcastReceiver components are not allowed to bind to services"); } + + @Override + public boolean bindIsolatedService(Intent service, ServiceConnection conn, int flags, + String instanceName) { + throw new ReceiverCallNotAllowedException( + "BroadcastReceiver components are not allowed to bind to services"); + } } /** @@ -1630,14 +1637,25 @@ class ContextImpl extends Context { public boolean bindService(Intent service, ServiceConnection conn, int flags) { warnIfCallingFromSystemProcess(); - return bindServiceCommon(service, conn, flags, mMainThread.getHandler(), getUser()); + return bindServiceCommon(service, conn, flags, null, mMainThread.getHandler(), getUser()); + } + + @Override + public boolean bindIsolatedService(Intent service, ServiceConnection conn, + int flags, String instanceName) { + warnIfCallingFromSystemProcess(); + if (instanceName == null) { + throw new NullPointerException("null instanceName"); + } + return bindServiceCommon(service, conn, flags, instanceName, mMainThread.getHandler(), + getUser()); } /** @hide */ @Override public boolean bindServiceAsUser(Intent service, ServiceConnection conn, int flags, UserHandle user) { - return bindServiceCommon(service, conn, flags, mMainThread.getHandler(), user); + return bindServiceCommon(service, conn, flags, null, mMainThread.getHandler(), user); } /** @hide */ @@ -1647,7 +1665,7 @@ class ContextImpl extends Context { if (handler == null) { throw new IllegalArgumentException("handler must not be null."); } - return bindServiceCommon(service, conn, flags, handler, user); + return bindServiceCommon(service, conn, flags, null, handler, user); } /** @hide */ @@ -1669,7 +1687,8 @@ class ContextImpl extends Context { return mMainThread.getHandler(); } - private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags, Handler + private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags, + String instanceName, Handler handler, UserHandle user) { // Keep this in sync with DevicePolicyManager.bindDeviceAdminServiceAsUser. IServiceConnection sd; @@ -1690,10 +1709,10 @@ class ContextImpl extends Context { flags |= BIND_WAIVE_PRIORITY; } service.prepareToLeaveProcess(this); - int res = ActivityManager.getService().bindService( + int res = ActivityManager.getService().bindIsolatedService( mMainThread.getApplicationThread(), getActivityToken(), service, service.resolveTypeIfNeeded(getContentResolver()), - sd, flags, getOpPackageName(), user.getIdentifier()); + sd, flags, instanceName, getOpPackageName(), user.getIdentifier()); if (res < 0) { throw new SecurityException( "Not allowed to bind to service " + service); diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl index e2312a539ae4..f27c6677ed22 100644 --- a/core/java/android/app/IActivityManager.aidl +++ b/core/java/android/app/IActivityManager.aidl @@ -133,9 +133,13 @@ interface IActivityManager { in String resolvedType, boolean requireForeground, in String callingPackage, int userId); int stopService(in IApplicationThread caller, in Intent service, in String resolvedType, int userId); + // Currently keeping old bindService because it is on the greylist int bindService(in IApplicationThread caller, in IBinder token, in Intent service, in String resolvedType, in IServiceConnection connection, int flags, in String callingPackage, int userId); + int bindIsolatedService(in IApplicationThread caller, in IBinder token, in Intent service, + in String resolvedType, in IServiceConnection connection, int flags, + in String instanceName, in String callingPackage, int userId); boolean unbindService(in IServiceConnection connection); void publishService(in IBinder token, in Intent intent, in IBinder service); void setDebugApp(in String packageName, boolean waitForDebugger, boolean persistent); diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java index ac164428abf8..015bc6c4bb07 100644 --- a/core/java/android/app/Instrumentation.java +++ b/core/java/android/app/Instrumentation.java @@ -1009,7 +1009,7 @@ public class Instrumentation { * from its event processing, though it may <em>not</em> have completely * finished reacting from the event -- for example, if it needs to update * its display as a result, it may still be in the process of doing that. - * + * * @param event The event to send to the current focus. */ public void sendKeySync(KeyEvent event) { @@ -1017,14 +1017,7 @@ public class Instrumentation { long downTime = event.getDownTime(); long eventTime = event.getEventTime(); - int action = event.getAction(); - int code = event.getKeyCode(); - int repeatCount = event.getRepeatCount(); - int metaState = event.getMetaState(); - int deviceId = event.getDeviceId(); - int scancode = event.getScanCode(); int source = event.getSource(); - int flags = event.getFlags(); if (source == InputDevice.SOURCE_UNKNOWN) { source = InputDevice.SOURCE_KEYBOARD; } @@ -1034,12 +1027,14 @@ public class Instrumentation { if (downTime == 0) { downTime = eventTime; } - KeyEvent newEvent = new KeyEvent(downTime, eventTime, action, code, repeatCount, metaState, - deviceId, scancode, flags | KeyEvent.FLAG_FROM_SYSTEM, source); + KeyEvent newEvent = new KeyEvent(event); + newEvent.setTime(downTime, eventTime); + newEvent.setSource(source); + newEvent.setFlags(event.getFlags() | KeyEvent.FLAG_FROM_SYSTEM); InputManager.getInstance().injectInputEvent(newEvent, InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH); } - + /** * Sends an up and down key event sync to the currently focused window. * diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java index 5850540dfba0..0123551230b0 100644 --- a/core/java/android/app/SystemServiceRegistry.java +++ b/core/java/android/app/SystemServiceRegistry.java @@ -153,6 +153,7 @@ import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; import android.telephony.euicc.EuiccCardManager; import android.telephony.euicc.EuiccManager; +import android.telephony.rcs.RcsManager; import android.util.ArrayMap; import android.util.Log; import android.view.ContextThemeWrapper; @@ -547,6 +548,14 @@ final class SystemServiceRegistry { return new SubscriptionManager(ctx.getOuterContext()); }}); + registerService(Context.TELEPHONY_RCS_SERVICE, RcsManager.class, + new CachedServiceFetcher<RcsManager>() { + @Override + public RcsManager createService(ContextImpl ctx) { + return new RcsManager(); + } + }); + registerService(Context.CARRIER_CONFIG_SERVICE, CarrierConfigManager.class, new CachedServiceFetcher<CarrierConfigManager>() { @Override diff --git a/core/java/android/app/usage/UsageEvents.java b/core/java/android/app/usage/UsageEvents.java index 308b39efc3b1..3a5975aea628 100644 --- a/core/java/android/app/usage/UsageEvents.java +++ b/core/java/android/app/usage/UsageEvents.java @@ -50,12 +50,20 @@ public final class UsageEvents implements Parcelable { public static final int NONE = 0; /** - * An event type denoting that a component moved to the foreground. + * An event type denoting that an {@link android.app.Activity} moved to the foreground. + * This event has a package name and class name associated with it and can be retrieved + * using {@link #getPackageName()} and {@link #getClassName()}. + * If a package has multiple activities, this event is reported for each activity that moves + * to foreground. */ public static final int MOVE_TO_FOREGROUND = 1; /** - * An event type denoting that a component moved to the background. + * An event type denoting that an {@link android.app.Activity} moved to the background. + * This event has a package name and class name associated with it and can be retrieved + * using {@link #getPackageName()} and {@link #getClassName()}. + * If a package has multiple activities, this event is reported for each activity that moves + * to background. */ public static final int MOVE_TO_BACKGROUND = 2; @@ -166,10 +174,43 @@ public final class UsageEvents implements Parcelable { public static final int KEYGUARD_HIDDEN = 18; /** + * An event type denoting start of a foreground service. + * This event has a package name and class name associated with it and can be retrieved + * using {@link #getPackageName()} and {@link #getClassName()}. + * If a package has multiple foreground services, this event is reported for each service + * that is started. + */ + public static final int FOREGROUND_SERVICE_START = 19; + + /** + * An event type denoting stop of a foreground service. + * This event has a package name and class name associated with it and can be retrieved + * using {@link #getPackageName()} and {@link #getClassName()}. + * If a package has multiple foreground services, this event is reported for each service + * that is stopped. + */ + public static final int FOREGROUND_SERVICE_STOP = 20; + + /** + * An event type denoting that a foreground service is at started state at beginning of a + * time interval. + * This is effectively treated as a {@link #FOREGROUND_SERVICE_START}. + * {@hide} + */ + public static final int CONTINUING_FOREGROUND_SERVICE = 21; + + /** + * An event type denoting that a foreground service is at started state when the stats + * rolled-over at the end of a time interval. + * {@hide} + */ + public static final int ROLLOVER_FOREGROUND_SERVICE = 22; + + /** * Keep in sync with the greatest event type value. * @hide */ - public static final int MAX_EVENT_TYPE = 18; + public static final int MAX_EVENT_TYPE = 22; /** @hide */ public static final int FLAG_IS_PACKAGE_INSTANT_APP = 1 << 0; diff --git a/core/java/android/app/usage/UsageStats.java b/core/java/android/app/usage/UsageStats.java index 0659a237d522..73426e495037 100644 --- a/core/java/android/app/usage/UsageStats.java +++ b/core/java/android/app/usage/UsageStats.java @@ -16,6 +16,15 @@ package android.app.usage; +import static android.app.usage.UsageEvents.Event.CONTINUE_PREVIOUS_DAY; +import static android.app.usage.UsageEvents.Event.CONTINUING_FOREGROUND_SERVICE; +import static android.app.usage.UsageEvents.Event.END_OF_DAY; +import static android.app.usage.UsageEvents.Event.FOREGROUND_SERVICE_START; +import static android.app.usage.UsageEvents.Event.FOREGROUND_SERVICE_STOP; +import static android.app.usage.UsageEvents.Event.MOVE_TO_BACKGROUND; +import static android.app.usage.UsageEvents.Event.MOVE_TO_FOREGROUND; +import static android.app.usage.UsageEvents.Event.ROLLOVER_FOREGROUND_SERVICE; + import android.annotation.SystemApi; import android.annotation.UnsupportedAppUsage; import android.os.Bundle; @@ -48,19 +57,32 @@ public final class UsageStats implements Parcelable { public long mEndTimeStamp; /** - * Last time used by the user with an explicit action (notification, activity launch). + * Last time used by the user with an explicit action (notification, activity launch) * {@hide} */ @UnsupportedAppUsage public long mLastTimeUsed; /** + * Total time this package's activity is in foreground. * {@hide} */ @UnsupportedAppUsage public long mTotalTimeInForeground; /** + * Last time foreground service is started. + * {@hide} + */ + public long mLastTimeForegroundServiceUsed; + + /** + * Total time this package's foreground service is started. + * {@hide} + */ + public long mTotalTimeForegroundServiceUsed; + + /** * {@hide} */ @UnsupportedAppUsage @@ -71,16 +93,36 @@ public final class UsageStats implements Parcelable { */ public int mAppLaunchCount; - /** + /** Last activity MOVE_TO_FOREGROUND or MOVE_TO_BACKGROUND event. * {@hide} + * @deprecated use {@link #mLastForegroundActivityEventMap} instead. */ @UnsupportedAppUsage + @Deprecated public int mLastEvent; /** + * If an activity is in foreground, it has one entry in this map. + * When activity moves to background, it is removed from this map. + * Key is activity class name. + * Value is last time this activity MOVE_TO_FOREGROUND or MOVE_TO_BACKGROUND event. + * {@hide} + */ + public ArrayMap<String, Integer> mLastForegroundActivityEventMap = new ArrayMap<>(); + + /** + * If a foreground service is started, it has one entry in this map. + * When a foreground service is stopped, it is removed from this map. + * Key is foreground service class name. + * Value is last foreground service FOREGROUND_SERVICE_START ot FOREGROUND_SERVICE_STOP event. * {@hide} */ - public ArrayMap<String, ArrayMap<String, Integer>> mChooserCounts; + public ArrayMap<String, Integer> mLastForegroundServiceEventMap = new ArrayMap<>(); + + /** + * {@hide} + */ + public ArrayMap<String, ArrayMap<String, Integer>> mChooserCounts = new ArrayMap<>(); /** * {@hide} @@ -93,10 +135,14 @@ public final class UsageStats implements Parcelable { mBeginTimeStamp = stats.mBeginTimeStamp; mEndTimeStamp = stats.mEndTimeStamp; mLastTimeUsed = stats.mLastTimeUsed; + mLastTimeForegroundServiceUsed = stats.mLastTimeForegroundServiceUsed; mTotalTimeInForeground = stats.mTotalTimeInForeground; + mTotalTimeForegroundServiceUsed = stats.mTotalTimeForegroundServiceUsed; mLaunchCount = stats.mLaunchCount; mAppLaunchCount = stats.mAppLaunchCount; mLastEvent = stats.mLastEvent; + mLastForegroundActivityEventMap = stats.mLastForegroundActivityEventMap; + mLastForegroundServiceEventMap = stats.mLastForegroundServiceEventMap; mChooserCounts = stats.mChooserCounts; } @@ -136,7 +182,7 @@ public final class UsageStats implements Parcelable { } /** - * Get the last time this package was used, measured in milliseconds since the epoch. + * Get the last time this package's activity was used, measured in milliseconds since the epoch. * <p/> * See {@link System#currentTimeMillis()}. */ @@ -152,6 +198,23 @@ public final class UsageStats implements Parcelable { } /** + * Get the last time this package's foreground service was used, measured in milliseconds since + * the epoch. + * <p/> + * See {@link System#currentTimeMillis()}. + */ + public long getLastTimeForegroundServiceUsed() { + return mLastTimeForegroundServiceUsed; + } + + /** + * Get the total time this package's foreground services are started, measured in milliseconds. + */ + public long getTotalTimeForegroundServiceUsed() { + return mTotalTimeForegroundServiceUsed; + } + + /** * Returns the number of times the app was launched as an activity from outside of the app. * Excludes intra-app activity transitions. * @hide @@ -161,6 +224,19 @@ public final class UsageStats implements Parcelable { return mAppLaunchCount; } + private void mergeEventMap(ArrayMap<String, Integer> left, ArrayMap<String, Integer> right) { + final int size = right.size(); + for (int i = 0; i < size; i++) { + final String className = right.keyAt(i); + final Integer event = right.valueAt(i); + if (left.containsKey(className)) { + left.put(className, Math.max(left.get(className), event)); + } else { + left.put(className, event); + } + } + } + /** * Add the statistics from the right {@link UsageStats} to the left. The package name for * both {@link UsageStats} objects must be the same. @@ -179,12 +255,16 @@ public final class UsageStats implements Parcelable { if (right.mBeginTimeStamp > mBeginTimeStamp) { // Even though incoming UsageStat begins after this one, its last time used fields // may somehow be empty or chronologically preceding the older UsageStat. - mLastEvent = Math.max(mLastEvent, right.mLastEvent); + mergeEventMap(mLastForegroundActivityEventMap, right.mLastForegroundActivityEventMap); + mergeEventMap(mLastForegroundServiceEventMap, right.mLastForegroundServiceEventMap); mLastTimeUsed = Math.max(mLastTimeUsed, right.mLastTimeUsed); + mLastTimeForegroundServiceUsed = Math.max(mLastTimeForegroundServiceUsed, + right.mLastTimeForegroundServiceUsed); } mBeginTimeStamp = Math.min(mBeginTimeStamp, right.mBeginTimeStamp); mEndTimeStamp = Math.max(mEndTimeStamp, right.mEndTimeStamp); mTotalTimeInForeground += right.mTotalTimeInForeground; + mTotalTimeForegroundServiceUsed += right.mTotalTimeForegroundServiceUsed; mLaunchCount += right.mLaunchCount; mAppLaunchCount += right.mAppLaunchCount; if (mChooserCounts == null) { @@ -209,6 +289,161 @@ public final class UsageStats implements Parcelable { } } + /** + * Tell if an event indicate activity is in foreground or not. + * @param event the activity event. + * @return true if activity is in foreground, false otherwise. + * @hide + */ + private boolean isActivityInForeground(int event) { + return event == MOVE_TO_FOREGROUND + || event == CONTINUE_PREVIOUS_DAY; + } + + /** + * Tell if an event indicate foreground sevice is started or not. + * @param event the foreground service event. + * @return true if foreground service is started, false if stopped. + * @hide + */ + private boolean isForegroundServiceStarted(int event) { + return event == FOREGROUND_SERVICE_START + || event == CONTINUING_FOREGROUND_SERVICE; + } + + /** + * If any activity in foreground or any foreground service is started, the app is considered in + * use. + * @return true if in use, false otherwise. + * @hide + */ + private boolean isAppInUse() { + return !mLastForegroundActivityEventMap.isEmpty() + || !mLastForegroundServiceEventMap.isEmpty(); + } + + /** + * Update by an event of an activity. + * @param className className of the activity. + * @param timeStamp timeStamp of the event. + * @param eventType type of the event. + * @hide + */ + private void updateForegroundActivity(String className, long timeStamp, int eventType) { + if (eventType != MOVE_TO_BACKGROUND + && eventType != MOVE_TO_FOREGROUND + && eventType != END_OF_DAY) { + return; + } + + final Integer lastEvent = mLastForegroundActivityEventMap.get(className); + if (lastEvent != null) { + if (isActivityInForeground(lastEvent)) { + if (timeStamp > mLastTimeUsed) { + mTotalTimeInForeground += timeStamp - mLastTimeUsed; + mLastTimeUsed = timeStamp; + } + } + if (eventType == MOVE_TO_BACKGROUND) { + mLastForegroundActivityEventMap.remove(className); + } else { + mLastForegroundActivityEventMap.put(className, eventType); + } + } else if (eventType == MOVE_TO_FOREGROUND) { + if (!isAppInUse()) { + mLastTimeUsed = timeStamp; + } + mLastForegroundActivityEventMap.put(className, eventType); + } + } + + /** + * Update by an event of an foreground service. + * @param className className of the foreground service. + * @param timeStamp timeStamp of the event. + * @param eventType type of the event. + * @hide + */ + private void updateForegroundService(String className, long timeStamp, int eventType) { + if (eventType != FOREGROUND_SERVICE_STOP + && eventType != FOREGROUND_SERVICE_START + && eventType != ROLLOVER_FOREGROUND_SERVICE) { + return; + } + final Integer lastEvent = mLastForegroundServiceEventMap.get(className); + if (lastEvent != null) { + if (isForegroundServiceStarted(lastEvent)) { + if (timeStamp > mLastTimeForegroundServiceUsed) { + mTotalTimeForegroundServiceUsed += + timeStamp - mLastTimeForegroundServiceUsed; + mLastTimeForegroundServiceUsed = timeStamp; + } + } + if (eventType == FOREGROUND_SERVICE_STOP) { + mLastForegroundServiceEventMap.remove(className); + } else { + mLastForegroundServiceEventMap.put(className, eventType); + } + } else if (eventType == FOREGROUND_SERVICE_START) { + if (!isAppInUse()) { + mLastTimeForegroundServiceUsed = timeStamp; + } + mLastForegroundServiceEventMap.put(className, eventType); + } + } + + /** + * Update the UsageStats by a activity or foreground service event. + * @param className class name of a activity or foreground service, could be null to mark + * END_OF_DAY or rollover. + * @param timeStamp Epoch timestamp in milliseconds. + * @param eventType event type as in {@link UsageEvents.Event} + * @hide + */ + public void update(String className, long timeStamp, int eventType) { + switch(eventType) { + case MOVE_TO_BACKGROUND: + case MOVE_TO_FOREGROUND: + updateForegroundActivity(className, timeStamp, eventType); + break; + case END_OF_DAY: + // END_OF_DAY means updating all activities. + final int size = mLastForegroundActivityEventMap.size(); + for (int i = 0; i < size; i++) { + final String name = mLastForegroundActivityEventMap.keyAt(i); + updateForegroundActivity(name, timeStamp, eventType); + } + break; + case CONTINUE_PREVIOUS_DAY: + mLastTimeUsed = timeStamp; + mLastForegroundActivityEventMap.put(className, eventType); + break; + case FOREGROUND_SERVICE_STOP: + case FOREGROUND_SERVICE_START: + updateForegroundService(className, timeStamp, eventType); + break; + case ROLLOVER_FOREGROUND_SERVICE: + // ROLLOVER_FOREGROUND_SERVICE means updating all foreground services. + final int size2 = mLastForegroundServiceEventMap.size(); + for (int i = 0; i < size2; i++) { + final String name = mLastForegroundServiceEventMap.keyAt(i); + updateForegroundService(name, timeStamp, eventType); + } + break; + case CONTINUING_FOREGROUND_SERVICE: + mLastTimeForegroundServiceUsed = timeStamp; + mLastForegroundServiceEventMap.put(className, eventType); + break; + default: + break; + } + mEndTimeStamp = timeStamp; + + if (eventType == MOVE_TO_FOREGROUND) { + mLaunchCount += 1; + } + } + @Override public int describeContents() { return 0; @@ -220,7 +455,9 @@ public final class UsageStats implements Parcelable { dest.writeLong(mBeginTimeStamp); dest.writeLong(mEndTimeStamp); dest.writeLong(mLastTimeUsed); + dest.writeLong(mLastTimeForegroundServiceUsed); dest.writeLong(mTotalTimeInForeground); + dest.writeLong(mTotalTimeForegroundServiceUsed); dest.writeInt(mLaunchCount); dest.writeInt(mAppLaunchCount); dest.writeInt(mLastEvent); @@ -239,6 +476,22 @@ public final class UsageStats implements Parcelable { } } dest.writeBundle(allCounts); + + final Bundle foregroundActivityEventBundle = new Bundle(); + final int foregroundEventSize = mLastForegroundActivityEventMap.size(); + for (int i = 0; i < foregroundEventSize; i++) { + foregroundActivityEventBundle.putInt(mLastForegroundActivityEventMap.keyAt(i), + mLastForegroundActivityEventMap.valueAt(i)); + } + dest.writeBundle(foregroundActivityEventBundle); + + final Bundle foregroundServiceEventBundle = new Bundle(); + final int foregroundServiceEventSize = mLastForegroundServiceEventMap.size(); + for (int i = 0; i < foregroundServiceEventSize; i++) { + foregroundServiceEventBundle.putInt(mLastForegroundServiceEventMap.keyAt(i), + mLastForegroundServiceEventMap.valueAt(i)); + } + dest.writeBundle(foregroundServiceEventBundle); } public static final Creator<UsageStats> CREATOR = new Creator<UsageStats>() { @@ -249,7 +502,9 @@ public final class UsageStats implements Parcelable { stats.mBeginTimeStamp = in.readLong(); stats.mEndTimeStamp = in.readLong(); stats.mLastTimeUsed = in.readLong(); + stats.mLastTimeForegroundServiceUsed = in.readLong(); stats.mTotalTimeInForeground = in.readLong(); + stats.mTotalTimeForegroundServiceUsed = in.readLong(); stats.mLaunchCount = in.readInt(); stats.mAppLaunchCount = in.readInt(); stats.mLastEvent = in.readInt(); @@ -272,9 +527,20 @@ public final class UsageStats implements Parcelable { } } } + readBundleToEventMap(stats.mLastForegroundActivityEventMap, in.readBundle()); + readBundleToEventMap(stats.mLastForegroundServiceEventMap, in.readBundle()); return stats; } + private void readBundleToEventMap(ArrayMap<String, Integer> eventMap, Bundle bundle) { + if (bundle != null) { + for (String className : bundle.keySet()) { + final int event = bundle.getInt(className); + eventMap.put(className, event); + } + } + } + @Override public UsageStats[] newArray(int size) { return new UsageStats[size]; diff --git a/core/java/android/app/usage/UsageStatsManager.java b/core/java/android/app/usage/UsageStatsManager.java index 6d7400e0ef73..55148511ed10 100644 --- a/core/java/android/app/usage/UsageStatsManager.java +++ b/core/java/android/app/usage/UsageStatsManager.java @@ -192,7 +192,10 @@ public final class UsageStatsManager { public static final int REASON_SUB_USAGE_EXEMPTED_SYNC_SCHEDULED_DOZE = 0x000C; /** @hide */ public static final int REASON_SUB_USAGE_EXEMPTED_SYNC_START = 0x000D; - + /** @hide */ + public static final int REASON_SUB_USAGE_FOREGROUND_SERVICE_START = 0x000E; + /** @hide */ + public static final int REASON_SUB_USAGE_FOREGROUND_SERVICE_STOP = 0x000F; /** @hide */ public static final int REASON_SUB_PREDICTED_RESTORED = 0x0001; diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index 2aa32c4b9cff..03eba7efea91 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -2906,8 +2906,9 @@ public abstract class Context { * @param flags Operation options for the binding. May be 0, * {@link #BIND_AUTO_CREATE}, {@link #BIND_DEBUG_UNBIND}, * {@link #BIND_NOT_FOREGROUND}, {@link #BIND_ABOVE_CLIENT}, - * {@link #BIND_ALLOW_OOM_MANAGEMENT}, or - * {@link #BIND_WAIVE_PRIORITY}. + * {@link #BIND_ALLOW_OOM_MANAGEMENT}, {@link #BIND_WAIVE_PRIORITY}. + * {@link #BIND_IMPORTANT}, or + * {@link #BIND_ADJUST_WITH_ACTIVITY}. * @return {@code true} if the system is in the process of bringing up a * service that your client has permission to bind to; {@code false} * if the system couldn't find the service or if your client doesn't @@ -2923,11 +2924,38 @@ public abstract class Context { * @see #BIND_AUTO_CREATE * @see #BIND_DEBUG_UNBIND * @see #BIND_NOT_FOREGROUND + * @see #BIND_ABOVE_CLIENT + * @see #BIND_ALLOW_OOM_MANAGEMENT + * @see #BIND_WAIVE_PRIORITY + * @see #BIND_IMPORTANT + * @see #BIND_ADJUST_WITH_ACTIVITY */ public abstract boolean bindService(@RequiresPermission Intent service, @NonNull ServiceConnection conn, @BindServiceFlags int flags); /** + * Variation of {@link #bindService} that, in the specific case of isolated + * services, allows the caller to generate multiple instances of a service + * from a single component declaration. + * + * @param service Identifies the service to connect to. The Intent must + * specify an explicit component name. + * @param conn Receives information as the service is started and stopped. + * This must be a valid ServiceConnection object; it must not be null. + * @param flags Operation options for the binding as per {@link #bindService}. + * @param instanceName Unique identifier for the service instance. Each unique + * name here will result in a different service instance being created. + * @return Returns success of binding as per {@link #bindService}. + * + * @throws SecurityException If the caller does not have permission to access the service + * + * @see #bindService + */ + public abstract boolean bindIsolatedService(@RequiresPermission Intent service, + @NonNull ServiceConnection conn, @BindServiceFlags int flags, + @NonNull String instanceName); + + /** * Same as {@link #bindService(Intent, ServiceConnection, int)}, but with an explicit userHandle * argument for use by system server and other multi-user aware code. * @hide @@ -2941,7 +2969,7 @@ public abstract class Context { } /** - * Same as {@link #bindService(Intent, ServiceConnection, int, UserHandle)}, but with an + * Same as {@link #bindServiceAsUser(Intent, ServiceConnection, int, UserHandle)}, but with an * explicit non-null Handler to run the ServiceConnection callbacks on. * * @hide @@ -4367,6 +4395,13 @@ public abstract class Context { public static final String APP_BINDING_SERVICE = "app_binding"; /** + * Use with {@link #getSystemService(String)} to retrieve an + * {@link android.telephony.rcs.RcsManager}. + * @hide + */ + public static final String TELEPHONY_RCS_SERVICE = "ircs"; + + /** * 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/ContextWrapper.java b/core/java/android/content/ContextWrapper.java index bfad2b42bc94..88696b0e1e4d 100644 --- a/core/java/android/content/ContextWrapper.java +++ b/core/java/android/content/ContextWrapper.java @@ -705,6 +705,12 @@ public class ContextWrapper extends Context { return mBase.bindService(service, conn, flags); } + @Override + public boolean bindIsolatedService(Intent service, ServiceConnection conn, + int flags, String instanceName) { + return mBase.bindIsolatedService(service, conn, flags, instanceName); + } + /** @hide */ @Override public boolean bindServiceAsUser(Intent service, ServiceConnection conn, int flags, diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java index 6b5c6597f31d..48240db50531 100644 --- a/core/java/android/content/pm/ApplicationInfo.java +++ b/core/java/android/content/pm/ApplicationInfo.java @@ -27,7 +27,6 @@ import android.content.Context; import android.content.pm.PackageManager.NameNotFoundException; import android.content.res.Resources; import android.graphics.drawable.Drawable; -import android.os.Build; import android.os.Environment; import android.os.Parcel; import android.os.Parcelable; @@ -1171,11 +1170,11 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { * system apps. * @hide */ - public static final int HIDDEN_API_ENFORCEMENT_NONE = 0; + public static final int HIDDEN_API_ENFORCEMENT_DISABLED = 0; /** * No API enforcement, but enable the detection logic and warnings. Observed behaviour is the - * same as {@link #HIDDEN_API_ENFORCEMENT_NONE} but you may see warnings in the log when APIs - * are accessed. + * same as {@link #HIDDEN_API_ENFORCEMENT_DISABLED} but you may see warnings in the log when + * APIs are accessed. * @hide * */ public static final int HIDDEN_API_ENFORCEMENT_JUST_WARN = 1; @@ -1183,14 +1182,10 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { * Dark grey list enforcement. Enforces the dark grey and black lists * @hide */ - public static final int HIDDEN_API_ENFORCEMENT_DARK_GREY_AND_BLACK = 2; - /** - * Blacklist enforcement only. - * @hide - */ - public static final int HIDDEN_API_ENFORCEMENT_BLACK = 3; + public static final int HIDDEN_API_ENFORCEMENT_ENABLED = 2; - private static final int HIDDEN_API_ENFORCEMENT_MAX = HIDDEN_API_ENFORCEMENT_BLACK; + private static final int HIDDEN_API_ENFORCEMENT_MIN = HIDDEN_API_ENFORCEMENT_DEFAULT; + private static final int HIDDEN_API_ENFORCEMENT_MAX = HIDDEN_API_ENFORCEMENT_ENABLED; /** * Values in this IntDef MUST be kept in sync with enum hiddenapi::EnforcementPolicy in @@ -1199,17 +1194,16 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { */ @IntDef(prefix = { "HIDDEN_API_ENFORCEMENT_" }, value = { HIDDEN_API_ENFORCEMENT_DEFAULT, - HIDDEN_API_ENFORCEMENT_NONE, + HIDDEN_API_ENFORCEMENT_DISABLED, HIDDEN_API_ENFORCEMENT_JUST_WARN, - HIDDEN_API_ENFORCEMENT_DARK_GREY_AND_BLACK, - HIDDEN_API_ENFORCEMENT_BLACK, + HIDDEN_API_ENFORCEMENT_ENABLED, }) @Retention(RetentionPolicy.SOURCE) public @interface HiddenApiEnforcementPolicy {} /** @hide */ public static boolean isValidHiddenApiEnforcementPolicy(int policy) { - return policy >= HIDDEN_API_ENFORCEMENT_DEFAULT && policy <= HIDDEN_API_ENFORCEMENT_MAX; + return policy >= HIDDEN_API_ENFORCEMENT_MIN && policy <= HIDDEN_API_ENFORCEMENT_MAX; } private int mHiddenApiPolicy = HIDDEN_API_ENFORCEMENT_DEFAULT; @@ -1749,16 +1743,12 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { */ public @HiddenApiEnforcementPolicy int getHiddenApiEnforcementPolicy() { if (isAllowedToUseHiddenApis()) { - return HIDDEN_API_ENFORCEMENT_NONE; + return HIDDEN_API_ENFORCEMENT_DISABLED; } if (mHiddenApiPolicy != HIDDEN_API_ENFORCEMENT_DEFAULT) { return mHiddenApiPolicy; } - if (targetSdkVersion < Build.VERSION_CODES.P) { - return HIDDEN_API_ENFORCEMENT_BLACK; - } else { - return HIDDEN_API_ENFORCEMENT_DARK_GREY_AND_BLACK; - } + return HIDDEN_API_ENFORCEMENT_ENABLED; } /** @@ -1777,23 +1767,15 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { * This will have no effect if this app is not subject to hidden API enforcement, i.e. if it * is on the package whitelist. * - * @param policyPreP configured policy for pre-P apps, or {@link - * #HIDDEN_API_ENFORCEMENT_DEFAULT} if nothing configured. - * @param policyP configured policy for apps targeting P or later, or {@link - * #HIDDEN_API_ENFORCEMENT_DEFAULT} if nothing configured. + * @param policy configured policy for this app, or {@link #HIDDEN_API_ENFORCEMENT_DEFAULT} + * if nothing configured. * @hide */ - public void maybeUpdateHiddenApiEnforcementPolicy( - @HiddenApiEnforcementPolicy int policyPreP, @HiddenApiEnforcementPolicy int policyP) { + public void maybeUpdateHiddenApiEnforcementPolicy(@HiddenApiEnforcementPolicy int policy) { if (isPackageWhitelistedForHiddenApis()) { return; } - if (targetSdkVersion < Build.VERSION_CODES.P) { - setHiddenApiEnforcementPolicy(policyPreP); - } else if (targetSdkVersion >= Build.VERSION_CODES.P) { - setHiddenApiEnforcementPolicy(policyP); - } - + setHiddenApiEnforcementPolicy(policy); } /** diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java index 444ca87a68ef..7148b124253e 100644 --- a/core/java/android/hardware/camera2/CameraCharacteristics.java +++ b/core/java/android/hardware/camera2/CameraCharacteristics.java @@ -28,8 +28,8 @@ import android.hardware.camera2.utils.ArrayUtils; import android.hardware.camera2.utils.TypeReference; import android.util.Rational; -import java.util.Arrays; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.HashSet; import java.util.List; @@ -2668,7 +2668,8 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri /** * <p>The arrangement of color filters on sensor; * represents the colors in the top-left 2x2 section of - * the sensor, in reading order.</p> + * the sensor, in reading order, for a Bayer camera, or the + * light spectrum it captures for MONOCHROME camera.</p> * <p><b>Possible values:</b> * <ul> * <li>{@link #SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_RGGB RGGB}</li> @@ -2676,6 +2677,8 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * <li>{@link #SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_GBRG GBRG}</li> * <li>{@link #SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_BGGR BGGR}</li> * <li>{@link #SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_RGB RGB}</li> + * <li>{@link #SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_MONO MONO}</li> + * <li>{@link #SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_NIR NIR}</li> * </ul></p> * <p><b>Optional</b> - This value may be {@code null} on some devices.</p> * <p><b>Full capability</b> - @@ -2688,6 +2691,8 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * @see #SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_GBRG * @see #SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_BGGR * @see #SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_RGB + * @see #SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_MONO + * @see #SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_NIR */ @PublicKey public static final Key<Integer> SENSOR_INFO_COLOR_FILTER_ARRANGEMENT = @@ -2919,6 +2924,8 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * <p>Some devices may choose to provide a second set of calibration * information for improved quality, including * {@link CameraCharacteristics#SENSOR_REFERENCE_ILLUMINANT2 android.sensor.referenceIlluminant2} and its corresponding matrices.</p> + * <p>Starting from Android Q, this key will not be present for a MONOCHROME camera, even if + * the camera device has RAW capability.</p> * <p><b>Possible values:</b> * <ul> * <li>{@link #SENSOR_REFERENCE_ILLUMINANT1_DAYLIGHT DAYLIGHT}</li> @@ -2981,6 +2988,8 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * <p>If this key is present, then {@link CameraCharacteristics#SENSOR_COLOR_TRANSFORM2 android.sensor.colorTransform2}, * {@link CameraCharacteristics#SENSOR_CALIBRATION_TRANSFORM2 android.sensor.calibrationTransform2}, and * {@link CameraCharacteristics#SENSOR_FORWARD_MATRIX2 android.sensor.forwardMatrix2} will also be present.</p> + * <p>Starting from Android Q, this key will not be present for a MONOCHROME camera, even if + * the camera device has RAW capability.</p> * <p><b>Range of valid values:</b><br> * Any value listed in {@link CameraCharacteristics#SENSOR_REFERENCE_ILLUMINANT1 android.sensor.referenceIlluminant1}</p> * <p><b>Optional</b> - This value may be {@code null} on some devices.</p> @@ -3006,6 +3015,8 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * colorspace) into this camera device's native sensor color * space under the first reference illuminant * ({@link CameraCharacteristics#SENSOR_REFERENCE_ILLUMINANT1 android.sensor.referenceIlluminant1}).</p> + * <p>Starting from Android Q, this key will not be present for a MONOCHROME camera, even if + * the camera device has RAW capability.</p> * <p><b>Optional</b> - This value may be {@code null} on some devices.</p> * <p><b>Permission {@link android.Manifest.permission#CAMERA } is needed to access this property</b></p> * @@ -3029,6 +3040,8 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * ({@link CameraCharacteristics#SENSOR_REFERENCE_ILLUMINANT2 android.sensor.referenceIlluminant2}).</p> * <p>This matrix will only be present if the second reference * illuminant is present.</p> + * <p>Starting from Android Q, this key will not be present for a MONOCHROME camera, even if + * the camera device has RAW capability.</p> * <p><b>Optional</b> - This value may be {@code null} on some devices.</p> * <p><b>Permission {@link android.Manifest.permission#CAMERA } is needed to access this property</b></p> * @@ -3053,6 +3066,8 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * and the CIE XYZ colorspace when calculating this transform will * match the standard white point for the first reference illuminant * (i.e. no chromatic adaptation will be applied by this transform).</p> + * <p>Starting from Android Q, this key will not be present for a MONOCHROME camera, even if + * the camera device has RAW capability.</p> * <p><b>Optional</b> - This value may be {@code null} on some devices.</p> * <p><b>Permission {@link android.Manifest.permission#CAMERA } is needed to access this property</b></p> * @@ -3079,6 +3094,8 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * (i.e. no chromatic adaptation will be applied by this transform).</p> * <p>This matrix will only be present if the second reference * illuminant is present.</p> + * <p>Starting from Android Q, this key will not be present for a MONOCHROME camera, even if + * the camera device has RAW capability.</p> * <p><b>Optional</b> - This value may be {@code null} on some devices.</p> * <p><b>Permission {@link android.Manifest.permission#CAMERA } is needed to access this property</b></p> * @@ -3101,6 +3118,8 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * this matrix is chosen so that the standard white point for this reference * illuminant in the reference sensor colorspace is mapped to D50 in the * CIE XYZ colorspace.</p> + * <p>Starting from Android Q, this key will not be present for a MONOCHROME camera, even if + * the camera device has RAW capability.</p> * <p><b>Optional</b> - This value may be {@code null} on some devices.</p> * <p><b>Permission {@link android.Manifest.permission#CAMERA } is needed to access this property</b></p> * @@ -3125,6 +3144,8 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * CIE XYZ colorspace.</p> * <p>This matrix will only be present if the second reference * illuminant is present.</p> + * <p>Starting from Android Q, this key will not be present for a MONOCHROME camera, even if + * the camera device has RAW capability.</p> * <p><b>Optional</b> - This value may be {@code null} on some devices.</p> * <p><b>Permission {@link android.Manifest.permission#CAMERA } is needed to access this property</b></p> * @@ -3153,6 +3174,7 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * level values. For raw capture in particular, it is recommended to use * pixels from {@link CameraCharacteristics#SENSOR_OPTICAL_BLACK_REGIONS android.sensor.opticalBlackRegions} to calculate black * level values for each frame.</p> + * <p>For a MONOCHROME camera device, all of the 2x2 channels must have the same values.</p> * <p><b>Range of valid values:</b><br> * >= 0 for each.</p> * <p><b>Optional</b> - This value may be {@code null} on some devices.</p> diff --git a/core/java/android/hardware/camera2/CameraDevice.java b/core/java/android/hardware/camera2/CameraDevice.java index ac00f1488b14..dc6cffc4ebee 100644 --- a/core/java/android/hardware/camera2/CameraDevice.java +++ b/core/java/android/hardware/camera2/CameraDevice.java @@ -357,7 +357,7 @@ public abstract class CameraDevice implements AutoCloseable { * </p> * * <p>MONOCHROME-capability ({@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES} - * includes {@link CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_MONOCHROME MONOCHROME}) + * includes {@link CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_MONOCHROME MONOCHROME}) devices * supporting {@link android.graphics.ImageFormat#Y8 Y8} support substituting {@code YUV} * streams with {@code Y8} in all guaranteed stream combinations for the device's hardware level * and capabilities.</p> diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java index ffc22641f025..402472af65a3 100644 --- a/core/java/android/hardware/camera2/CameraMetadata.java +++ b/core/java/android/hardware/camera2/CameraMetadata.java @@ -880,11 +880,15 @@ public abstract class CameraMetadata<TKey> { /** * <p>The camera device is a monochrome camera that doesn't contain a color filter array, - * and the pixel values on U and V planes are all 128.</p> + * and for YUV_420_888 stream, the pixel values on U and V planes are all 128.</p> * <p>A MONOCHROME camera must support the guaranteed stream combinations required for * its device level and capabilities. Additionally, if the monochrome camera device * supports Y8 format, all mandatory stream combination requirements related to {@link android.graphics.ImageFormat#YUV_420_888 YUV_420_888} apply - * to {@link android.graphics.ImageFormat#Y8 Y8} as well.</p> + * to {@link android.graphics.ImageFormat#Y8 Y8} as well. There are no + * mandatory stream combination requirements with regard to + * {@link android.graphics.ImageFormat#Y8 Y8} for Bayer camera devices.</p> + * <p>Starting from Android Q, the SENSOR_INFO_COLOR_FILTER_ARRANGEMENT of a MONOCHROME + * camera will be either MONO or NIR.</p> * @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES */ public static final int REQUEST_AVAILABLE_CAPABILITIES_MONOCHROME = 12; @@ -937,6 +941,23 @@ public abstract class CameraMetadata<TKey> { */ public static final int SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_RGB = 4; + /** + * <p>Sensor doesn't have any Bayer color filter. + * Such sensor captures visible light in monochrome. The exact weighting and + * wavelengths captured is not specified, but generally only includes the visible + * frequencies. This value implies a MONOCHROME camera.</p> + * @see CameraCharacteristics#SENSOR_INFO_COLOR_FILTER_ARRANGEMENT + */ + public static final int SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_MONO = 5; + + /** + * <p>Sensor has a near infrared filter capturing light with wavelength between + * roughly 750nm and 1400nm, and the same filter covers the whole sensor array. This + * value implies a MONOCHROME camera.</p> + * @see CameraCharacteristics#SENSOR_INFO_COLOR_FILTER_ARRANGEMENT + */ + public static final int SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_NIR = 6; + // // Enumeration values for CameraCharacteristics#SENSOR_INFO_TIMESTAMP_SOURCE // diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java index 2744e9111509..8ebaf2f7db44 100644 --- a/core/java/android/hardware/camera2/CaptureRequest.java +++ b/core/java/android/hardware/camera2/CaptureRequest.java @@ -24,8 +24,8 @@ import android.hardware.camera2.impl.PublicKey; import android.hardware.camera2.impl.SyntheticKey; import android.hardware.camera2.params.OutputConfiguration; import android.hardware.camera2.utils.HashCodeHelpers; -import android.hardware.camera2.utils.TypeReference; import android.hardware.camera2.utils.SurfaceUtils; +import android.hardware.camera2.utils.TypeReference; import android.os.Parcel; import android.os.Parcelable; import android.util.ArraySet; @@ -2947,8 +2947,8 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>> * of points can be less than max (that is, the request doesn't have to * always provide a curve with number of points equivalent to * {@link CameraCharacteristics#TONEMAP_MAX_CURVE_POINTS android.tonemap.maxCurvePoints}).</p> - * <p>For devices with MONOCHROME capability, only red channel is used. Green and blue channels - * are ignored.</p> + * <p>For devices with MONOCHROME capability, all three channels must have the same set of + * control points.</p> * <p>A few examples, and their corresponding graphical mappings; these * only specify the red channel and the precision is limited to 4 * digits, for conciseness.</p> @@ -3011,8 +3011,8 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>> * of points can be less than max (that is, the request doesn't have to * always provide a curve with number of points equivalent to * {@link CameraCharacteristics#TONEMAP_MAX_CURVE_POINTS android.tonemap.maxCurvePoints}).</p> - * <p>For devices with MONOCHROME capability, only red channel is used. Green and blue channels - * are ignored.</p> + * <p>For devices with MONOCHROME capability, all three channels must have the same set of + * control points.</p> * <p>A few examples, and their corresponding graphical mappings; these * only specify the red channel and the precision is limited to 4 * digits, for conciseness.</p> diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java index 2b67f3e6adcb..3d70c516b577 100644 --- a/core/java/android/hardware/camera2/CaptureResult.java +++ b/core/java/android/hardware/camera2/CaptureResult.java @@ -3417,6 +3417,8 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> { * used to interpolate between the provided color transforms when * processing raw sensor data.</p> * <p>The order of the values is R, G, B; where R is in the lowest index.</p> + * <p>Starting from Android Q, this key will not be present for a MONOCHROME camera, even if + * the camera device has RAW capability.</p> * <p><b>Optional</b> - This value may be {@code null} on some devices.</p> */ @PublicKey @@ -3442,6 +3444,8 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> { * that channel.</p> * <p>A more detailed description of the noise model can be found in the * Adobe DNG specification for the NoiseProfile tag.</p> + * <p>For a MONOCHROME camera, there is only one color channel. So the noise model coefficients + * will only contain one S and one O.</p> * <p><b>Optional</b> - This value may be {@code null} on some devices.</p> * * @see CameraCharacteristics#SENSOR_INFO_COLOR_FILTER_ARRANGEMENT @@ -3482,6 +3486,8 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> { * <li>R > 1.20 will require strong software correction to produce * a usuable image (>20% divergence).</li> * </ul> + * <p>Starting from Android Q, this key will not be present for a MONOCHROME camera, even if + * the camera device has RAW capability.</p> * <p><b>Range of valid values:</b><br></p> * <p>>= 0</p> * <p><b>Optional</b> - This value may be {@code null} on some devices.</p> @@ -3592,6 +3598,7 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> { * layout key (see {@link CameraCharacteristics#SENSOR_INFO_COLOR_FILTER_ARRANGEMENT android.sensor.info.colorFilterArrangement}), i.e. the * nth value given corresponds to the black level offset for the nth * color channel listed in the CFA.</p> + * <p>For a MONOCHROME camera, all of the 2x2 channels must have the same values.</p> * <p>This key will be available if {@link CameraCharacteristics#SENSOR_OPTICAL_BLACK_REGIONS android.sensor.opticalBlackRegions} is available or the * camera device advertises this key via {@link android.hardware.camera2.CameraCharacteristics#getAvailableCaptureResultKeys }.</p> * <p><b>Range of valid values:</b><br> @@ -3852,6 +3859,17 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> { * <p>As a visualization only, inverting the full-color map to recover an * image of a gray wall (using bicubic interpolation for visual quality) as captured by the sensor gives:</p> * <p><img alt="Image of a uniform white wall (inverse shading map)" src="/reference/images/camera2/metadata/android.statistics.lensShadingMap/inv_shading.png" /></p> + * <p>For a MONOCHROME camera, all of the 2x2 channels must have the same values. An example + * shading map for such a camera is defined as:</p> + * <pre><code>android.lens.info.shadingMapSize = [ 4, 3 ] + * android.statistics.lensShadingMap = + * [ 1.3, 1.3, 1.3, 1.3, 1.2, 1.2, 1.2, 1.2, + * 1.1, 1.1, 1.1, 1.1, 1.3, 1.3, 1.3, 1.3, + * 1.2, 1.2, 1.2, 1.2, 1.1, 1.1, 1.1, 1.1, + * 1.0, 1.0, 1.0, 1.0, 1.2, 1.2, 1.2, 1.2, + * 1.3, 1.3, 1.3, 1.3, 1.2, 1.2, 1.2, 1.2, + * 1.2, 1.2, 1.2, 1.2, 1.3, 1.3, 1.3, 1.3 ] + * </code></pre> * <p><b>Range of valid values:</b><br> * Each gain factor is >= 1</p> * <p><b>Optional</b> - This value may be {@code null} on some devices.</p> @@ -3894,13 +3912,13 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> { * (x,y) ϵ (0 ... N-1, 0 ... M-1) is the value of the shading map at * pixel ( ((W-1)/(N-1)) * x, ((H-1)/(M-1)) * y) for the four color channels. * The map is assumed to be bilinearly interpolated between the sample points.</p> - * <p>The channel order is [R, Geven, Godd, B], where Geven is the green - * channel for the even rows of a Bayer pattern, and Godd is the odd rows. + * <p>For a Bayer camera, the channel order is [R, Geven, Godd, B], where Geven is + * the green channel for the even rows of a Bayer pattern, and Godd is the odd rows. * The shading map is stored in a fully interleaved format, and its size * is provided in the camera static metadata by android.lens.info.shadingMapSize.</p> * <p>The shading map will generally have on the order of 30-40 rows and columns, * and will be smaller than 64x64.</p> - * <p>As an example, given a very small map defined as:</p> + * <p>As an example, given a very small map for a Bayer camera defined as:</p> * <pre><code>android.lens.info.shadingMapSize = [ 4, 3 ] * android.statistics.lensShadingMap = * [ 1.3, 1.2, 1.15, 1.2, 1.2, 1.2, 1.15, 1.2, @@ -3920,6 +3938,17 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> { * image of a gray wall (using bicubic interpolation for visual quality) * as captured by the sensor gives:</p> * <p><img alt="Image of a uniform white wall (inverse shading map)" src="/reference/images/camera2/metadata/android.statistics.lensShadingMap/inv_shading.png" /></p> + * <p>For a MONOCHROME camera, all of the 2x2 channels must have the same values. An example + * shading map for such a camera is defined as:</p> + * <pre><code>android.lens.info.shadingMapSize = [ 4, 3 ] + * android.statistics.lensShadingMap = + * [ 1.3, 1.3, 1.3, 1.3, 1.2, 1.2, 1.2, 1.2, + * 1.1, 1.1, 1.1, 1.1, 1.3, 1.3, 1.3, 1.3, + * 1.2, 1.2, 1.2, 1.2, 1.1, 1.1, 1.1, 1.1, + * 1.0, 1.0, 1.0, 1.0, 1.2, 1.2, 1.2, 1.2, + * 1.3, 1.3, 1.3, 1.3, 1.2, 1.2, 1.2, 1.2, + * 1.2, 1.2, 1.2, 1.2, 1.3, 1.3, 1.3, 1.3 ] + * </code></pre> * <p>Note that the RAW image data might be subject to lens shading * correction not reported on this map. Query * {@link CameraCharacteristics#SENSOR_INFO_LENS_SHADING_APPLIED android.sensor.info.lensShadingApplied} to see if RAW image data has subject @@ -4250,8 +4279,8 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> { * of points can be less than max (that is, the request doesn't have to * always provide a curve with number of points equivalent to * {@link CameraCharacteristics#TONEMAP_MAX_CURVE_POINTS android.tonemap.maxCurvePoints}).</p> - * <p>For devices with MONOCHROME capability, only red channel is used. Green and blue channels - * are ignored.</p> + * <p>For devices with MONOCHROME capability, all three channels must have the same set of + * control points.</p> * <p>A few examples, and their corresponding graphical mappings; these * only specify the red channel and the precision is limited to 4 * digits, for conciseness.</p> @@ -4314,8 +4343,8 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> { * of points can be less than max (that is, the request doesn't have to * always provide a curve with number of points equivalent to * {@link CameraCharacteristics#TONEMAP_MAX_CURVE_POINTS android.tonemap.maxCurvePoints}).</p> - * <p>For devices with MONOCHROME capability, only red channel is used. Green and blue channels - * are ignored.</p> + * <p>For devices with MONOCHROME capability, all three channels must have the same set of + * control points.</p> * <p>A few examples, and their corresponding graphical mappings; these * only specify the red channel and the precision is limited to 4 * digits, for conciseness.</p> diff --git a/core/java/android/hardware/camera2/params/BlackLevelPattern.java b/core/java/android/hardware/camera2/params/BlackLevelPattern.java index 6d6c094ebf04..283977fecbd5 100644 --- a/core/java/android/hardware/camera2/params/BlackLevelPattern.java +++ b/core/java/android/hardware/camera2/params/BlackLevelPattern.java @@ -16,13 +16,17 @@ package android.hardware.camera2.params; -import java.util.Arrays; - import static com.android.internal.util.Preconditions.checkNotNull; +import java.util.Arrays; + /** * Immutable class to store a 4-element vector of integers corresponding to a 2x2 pattern * of color channel offsets used for the black level offsets of each color channel. + * + * For a camera device with + * {@link android.hardware.camera2.CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES_MONOCHROME + * MONOCHROME} capability, all 4 elements of the pattern will have the same value. */ public final class BlackLevelPattern { @@ -133,6 +137,12 @@ public final class BlackLevelPattern { * {@link android.hardware.camera2.CameraCharacteristics#SENSOR_INFO_COLOR_FILTER_ARRANGEMENT}). * </p> * + * <p>A {@link + * android.hardware.camera2.CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES_MONOCHROME + * MONOCHROME} camera only has one channel. As a result, the returned string will contain 4 + * identical values. + * </p> + * * @return string representation of {@link BlackLevelPattern} * * @see android.hardware.camera2.CameraCharacteristics#SENSOR_INFO_COLOR_FILTER_ARRANGEMENT diff --git a/core/java/android/hardware/camera2/params/TonemapCurve.java b/core/java/android/hardware/camera2/params/TonemapCurve.java index 71e68a5271c2..90e63556f018 100644 --- a/core/java/android/hardware/camera2/params/TonemapCurve.java +++ b/core/java/android/hardware/camera2/params/TonemapCurve.java @@ -34,6 +34,10 @@ import java.util.Arrays; * use as the tonemapping/contrast/gamma curve when {@link CaptureRequest#TONEMAP_MODE} is * set to {@link CameraMetadata#TONEMAP_MODE_CONTRAST_CURVE}.</p> * + * <p>For a camera device with + * {@link android.hardware.camera2.CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES_MONOCHROME + * MONOCHROME} capability, all 3 channels will contain the same set of control points. + * * <p>The total number of points {@code (Pin, Pout)} for each color channel can be no more than * {@link CameraCharacteristics#TONEMAP_MAX_CURVE_POINTS}.</p> * diff --git a/core/java/android/os/IPowerManager.aidl b/core/java/android/os/IPowerManager.aidl index 7ceeb526ffcf..ca5b2333b14d 100644 --- a/core/java/android/os/IPowerManager.aidl +++ b/core/java/android/os/IPowerManager.aidl @@ -48,6 +48,8 @@ interface IPowerManager boolean isPowerSaveMode(); PowerSaveState getPowerSaveState(int serviceType); boolean setPowerSaveMode(boolean mode); + boolean setDynamicPowerSavings(boolean dynamicPowerSavingsEnabled, int disableThreshold); + int getPowerSaveMode(); boolean isDeviceIdleMode(); boolean isLightDeviceIdleMode(); diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java index 27c281d56f4d..a307cd80e724 100644 --- a/core/java/android/os/PowerManager.java +++ b/core/java/android/os/PowerManager.java @@ -16,6 +16,7 @@ package android.os; +import android.Manifest.permission; import android.annotation.IntDef; import android.annotation.RequiresPermission; import android.annotation.SdkConstant; @@ -1185,6 +1186,105 @@ public final class PowerManager { } /** + * Updates the current state of dynamic power savings and disable threshold. This is + * a signal to the system which an app can update to serve as an indicator that + * the user will be in a battery critical situation before being able to plug in. + * Only apps with the {@link android.Manifest.permission#POWER_SAVER} permission may do this. + * This is a device global state, not a per user setting. + * + * <p>When enabled, the system may enact various measures for reducing power consumption in + * order to help ensure that the user will make it to their next charging point. The most + * visible of these will be the automatic enabling of battery saver if the user has set + * their battery saver mode to "automatic". Note + * that this is NOT simply an on/off switch for features, but rather a hint for the + * system to consider enacting these power saving features, some of which have additional + * logic around when to activate based on this signal. + * + * <p>The provided threshold is the percentage the system should consider itself safe at given + * the current state of the device. The value is an integer representing a battery level. + * + * <p>The threshold is meant to set an explicit stopping point for dynamic power savings + * functionality so that the dynamic power savings itself remains a signal rather than becoming + * an on/off switch for a subset of features. + * @hide + * + * @param dynamicPowerSavingsEnabled A signal indicating to the system if it believes the + * dynamic power savings behaviors should be activated. + * @param disableThreshold When the suggesting app believes it would be safe to disable dynamic + * power savings behaviors. + * @return True if the update was allowed and succeeded. + * + * @hide + */ + @SystemApi + @TestApi + @RequiresPermission(permission.POWER_SAVER) + public boolean setDynamicPowerSavings(boolean dynamicPowerSavingsEnabled, + int disableThreshold) { + try { + return mService.setDynamicPowerSavings(dynamicPowerSavingsEnabled, disableThreshold); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * Indicates automatic battery saver toggling by the system will be based on percentage. + * + * @see PowerManager#getPowerSaveMode() + * + * @hide + */ + @SystemApi + @TestApi + public static final int POWER_SAVER_MODE_PERCENTAGE = 0; + + /** + * Indicates automatic battery saver toggling by the system will be based on the state + * of the dynamic power savings signal. + * + * @see PowerManager#setDynamicPowerSavings(boolean, int) + * @see PowerManager#getPowerSaveMode() + * + * @hide + */ + @SystemApi + @TestApi + public static final int POWER_SAVER_MODE_DYNAMIC = 1; + + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(value = { + POWER_SAVER_MODE_PERCENTAGE, + POWER_SAVER_MODE_DYNAMIC + + }) + public @interface AutoPowerSaverMode{} + + + /** + * Returns the current battery saver control mode. Values it may return are defined in + * AutoPowerSaverMode. Note that this is a global device state, not a per user setting. + * + * @return The current value power saver mode for the system. + * + * @see AutoPowerSaverMode + * @see PowerManager#getPowerSaveMode() + * @hide + */ + @AutoPowerSaverMode + @SystemApi + @TestApi + @RequiresPermission(android.Manifest.permission.POWER_SAVER) + public int getPowerSaveMode() { + try { + return mService.getPowerSaveMode(); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** * Get data about the battery saver mode for a specific service * @param serviceType unique key for the service, one of {@link ServiceType} * @return Battery saver state data. diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java index 8a36a782750b..423ce771969f 100644 --- a/core/java/android/os/storage/StorageManager.java +++ b/core/java/android/os/storage/StorageManager.java @@ -268,6 +268,9 @@ public class StorageManager { public static final int ENCRYPTION_STATE_ERROR_CORRUPT = IVold.ENCRYPTION_STATE_ERROR_CORRUPT; + /** @hide Prefix used in sandboxIds for apps with sharedUserIds */ + public static final String SHARED_SANDBOX_PREFIX = "shared-"; + private static volatile IStorageManager sStorageManager = null; private final Context mContext; @@ -801,7 +804,7 @@ public class StorageManager { try { for (VolumeInfo vol : mStorageManager.getVolumes(0)) { if (vol.path != null && FileUtils.contains(vol.path, pathString) - && vol.type != VolumeInfo.TYPE_PUBLIC) { + && vol.type != VolumeInfo.TYPE_PUBLIC && vol.type != VolumeInfo.TYPE_STUB) { // TODO: verify that emulated adopted devices have UUID of // underlying volume try { diff --git a/core/java/android/os/storage/VolumeInfo.java b/core/java/android/os/storage/VolumeInfo.java index e55afb69bab9..8c3aa1750acf 100644 --- a/core/java/android/os/storage/VolumeInfo.java +++ b/core/java/android/os/storage/VolumeInfo.java @@ -84,6 +84,7 @@ public class VolumeInfo implements Parcelable { public static final int TYPE_EMULATED = IVold.VOLUME_TYPE_EMULATED; public static final int TYPE_ASEC = IVold.VOLUME_TYPE_ASEC; public static final int TYPE_OBB = IVold.VOLUME_TYPE_OBB; + public static final int TYPE_STUB = IVold.VOLUME_TYPE_STUB; public static final int STATE_UNMOUNTED = IVold.VOLUME_STATE_UNMOUNTED; public static final int STATE_CHECKING = IVold.VOLUME_STATE_CHECKING; @@ -295,7 +296,7 @@ public class VolumeInfo implements Parcelable { } public boolean isVisibleForUser(int userId) { - if (type == TYPE_PUBLIC && mountUserId == userId) { + if ((type == TYPE_PUBLIC || type == TYPE_STUB) && mountUserId == userId) { return isVisible(); } else if (type == TYPE_EMULATED) { return isVisible(); @@ -327,7 +328,7 @@ public class VolumeInfo implements Parcelable { public File getPathForUser(int userId) { if (path == null) { return null; - } else if (type == TYPE_PUBLIC) { + } else if (type == TYPE_PUBLIC || type == TYPE_STUB) { return new File(path); } else if (type == TYPE_EMULATED) { return new File(path, Integer.toString(userId)); @@ -344,7 +345,7 @@ public class VolumeInfo implements Parcelable { public File getInternalPathForUser(int userId) { if (path == null) { return null; - } else if (type == TYPE_PUBLIC) { + } else if (type == TYPE_PUBLIC || type == TYPE_STUB) { // TODO: plumb through cleaner path from vold return new File(path.replace("/storage/", "/mnt/media_rw/")); } else { @@ -390,7 +391,7 @@ public class VolumeInfo implements Parcelable { removable = true; } - } else if (type == TYPE_PUBLIC) { + } else if (type == TYPE_PUBLIC || type == TYPE_STUB) { emulated = false; removable = true; @@ -447,7 +448,8 @@ public class VolumeInfo implements Parcelable { public @Nullable Intent buildBrowseIntentForUser(int userId) { final Uri uri; - if (type == VolumeInfo.TYPE_PUBLIC && mountUserId == userId) { + if ((type == VolumeInfo.TYPE_PUBLIC || type == VolumeInfo.TYPE_STUB) + && mountUserId == userId) { uri = DocumentsContract.buildRootUri(DOCUMENT_AUTHORITY, fsUuid); } else if (type == VolumeInfo.TYPE_EMULATED && isPrimary()) { uri = DocumentsContract.buildRootUri(DOCUMENT_AUTHORITY, diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 0aa3a7b28829..040222217db4 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -11811,14 +11811,54 @@ public final class Settings { /** * Battery level [1-100] at which low power mode automatically turns on. - * If 0, it will not automatically turn on. + * Pre-Q If 0, it will not automatically turn on. Q and newer it will only automatically + * turn on if the {@link #AUTOMATIC_POWER_SAVER_MODE} setting is also set to + * {@link android.os.PowerManager.AutoPowerSaverMode#POWER_SAVER_MODE_PERCENTAGE}. + * + * @see #AUTOMATIC_POWER_SAVER_MODE + * @see android.os.PowerManager#getPowerSaveMode() * @hide */ public static final String LOW_POWER_MODE_TRIGGER_LEVEL = "low_power_trigger_level"; + private static final Validator LOW_POWER_MODE_TRIGGER_LEVEL_VALIDATOR = new SettingsValidators.InclusiveIntegerRangeValidator(0, 100); + /** + * Whether battery saver is currently set to trigger based on percentage, dynamic power + * savings trigger, or none. See {@link android.os.PowerManager.AutoPowerSaverMode} for + * accepted values. + * + * @hide + */ + @TestApi + public static final String AUTOMATIC_POWER_SAVER_MODE = "automatic_power_saver_mode"; + + private static final Validator AUTOMATIC_POWER_SAVER_MODE_VALIDATOR = + new SettingsValidators.DiscreteValueValidator(new String[] {"0", "1"}); + + /** + * The setting that backs the disable threshold for the setPowerSavingsWarning api in + * PowerManager + * + * @see android.os.PowerManager#setDynamicPowerSavings(boolean, int) + * @hide + */ + @TestApi + public static final String DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD = + "dynamic_power_savings_disable_threshold"; + private static final Validator DYNAMIC_POWER_SAVINGS_VALIDATOR = + new SettingsValidators.InclusiveIntegerRangeValidator(0, 100); + + /** + * The setting which backs the setDynamicPowerSavings api in PowerManager. + * + * @see android.os.PowerManager#setDynamicPowerSavings(boolean, int) + * @hide + */ + @TestApi + public static final String DYNAMIC_POWER_SAVINGS_ENABLED = "dynamic_power_savings_enabled"; /** * The max value for {@link #LOW_POWER_MODE_TRIGGER_LEVEL}. If this setting is not set @@ -12636,27 +12676,14 @@ public final class Settings { "hidden_api_access_log_sampling_rate"; /** - * Hidden API enforcement policy for apps targeting SDK versions prior to the latest - * version. - * - * Values correspond to @{@link - * android.content.pm.ApplicationInfo.HiddenApiEnforcementPolicy} - * - * @hide - */ - public static final String HIDDEN_API_POLICY_PRE_P_APPS = - "hidden_api_policy_pre_p_apps"; - - /** - * Hidden API enforcement policy for apps targeting the current SDK version. + * Hidden API enforcement policy for apps. * * Values correspond to @{@link * android.content.pm.ApplicationInfo.HiddenApiEnforcementPolicy} * * @hide */ - public static final String HIDDEN_API_POLICY_P_APPS = - "hidden_api_policy_p_apps"; + public static final String HIDDEN_API_POLICY = "hidden_api_policy"; /** * Timeout for a single {@link android.media.soundtrigger.SoundTriggerDetectionService} @@ -12755,6 +12782,9 @@ public final class Settings { VALIDATORS.put(LOW_POWER_MODE_TRIGGER_LEVEL, LOW_POWER_MODE_TRIGGER_LEVEL_VALIDATOR); VALIDATORS.put(LOW_POWER_MODE_TRIGGER_LEVEL_MAX, LOW_POWER_MODE_TRIGGER_LEVEL_VALIDATOR); + VALIDATORS.put(AUTOMATIC_POWER_SAVER_MODE, AUTOMATIC_POWER_SAVER_MODE_VALIDATOR); + VALIDATORS.put(DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD, + DYNAMIC_POWER_SAVINGS_VALIDATOR); VALIDATORS.put(BLUETOOTH_ON, BLUETOOTH_ON_VALIDATOR); VALIDATORS.put(PRIVATE_DNS_MODE, PRIVATE_DNS_MODE_VALIDATOR); VALIDATORS.put(PRIVATE_DNS_SPECIFIER, PRIVATE_DNS_SPECIFIER_VALIDATOR); diff --git a/core/java/android/view/KeyEvent.java b/core/java/android/view/KeyEvent.java index 907f38535842..0739516e4e96 100644 --- a/core/java/android/view/KeyEvent.java +++ b/core/java/android/view/KeyEvent.java @@ -1978,6 +1978,7 @@ public class KeyEvent extends InputEvent implements Parcelable { } /** @hide */ + @TestApi @Override public final void setDisplayId(int displayId) { mDisplayId = displayId; @@ -2042,6 +2043,16 @@ public class KeyEvent extends InputEvent implements Parcelable { } /** + * Modifies the flags of the event. + * + * @param newFlags New flags for the event, replacing the entire value. + * @hide + */ + public final void setFlags(int newFlags) { + mFlags = newFlags; + } + + /** * Returns the flags for this key event. * * @see #FLAG_WOKE_HERE @@ -2542,6 +2553,20 @@ public class KeyEvent extends InputEvent implements Parcelable { } /** + * Modifies the down time and the event time of the event. + * + * @param downTime The new down time (in {@link android.os.SystemClock#uptimeMillis}) of the + * event. + * @param eventTime The new event time (in {@link android.os.SystemClock#uptimeMillis}) of the + * event. + * @hide + */ + public final void setTime(long downTime, long eventTime) { + mDownTime = downTime; + mEventTime = eventTime; + } + + /** * Retrieve the time of the most recent key down event, * in the {@link android.os.SystemClock#uptimeMillis} time base. If this * is a down event, this will be the same as {@link #getEventTime()}. diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java index 0d33bbd1fc76..3d16eb89c41d 100644 --- a/core/java/android/view/SurfaceControl.java +++ b/core/java/android/view/SurfaceControl.java @@ -572,6 +572,10 @@ public class SurfaceControl implements Parcelable { * Good practice is to first create the surface with the {@link #HIDDEN} flag * specified, open a transaction, set the surface layer, layer stack, alpha, * and position, call {@link #show} if appropriate, and close the transaction. + * <p> + * Bounds of the surface is determined by its crop and its buffer size. If the + * surface has no buffer or crop, the surface is boundless and only constrained + * by the size of its parent bounds. * * @param session The surface session, must not be null. * @param name The surface name, must not be null. @@ -959,6 +963,14 @@ public class SurfaceControl implements Parcelable { } } + /** + * Bounds the surface and its children to the bounds specified. Size of the surface will be + * ignored and only the crop and buffer size will be used to determine the bounds of the + * surface. If no crop is specified and the surface has no buffer, the surface bounds is only + * constrained by the size of its parent bounds. + * + * @param crop Bounds of the crop to apply. + */ public void setWindowCrop(Rect crop) { checkNotReleased(); synchronized (SurfaceControl.class) { @@ -966,6 +978,19 @@ public class SurfaceControl implements Parcelable { } } + /** + * Same as {@link SurfaceControl#setWindowCrop(Rect)} but sets the crop rect top left at 0, 0. + * + * @param width width of crop rect + * @param height height of crop rect + */ + public void setWindowCrop(int width, int height) { + checkNotReleased(); + synchronized (SurfaceControl.class) { + sGlobalTransaction.setWindowCrop(this, width, height); + } + } + public void setLayerStack(int layerStack) { checkNotReleased(); synchronized(SurfaceControl.class) { @@ -1477,6 +1502,12 @@ public class SurfaceControl implements Parcelable { return this; } + public Transaction setWindowCrop(SurfaceControl sc, int width, int height) { + sc.checkNotReleased(); + nativeSetWindowCrop(mNativeObject, sc.mNativeObject, 0, 0, width, height); + return this; + } + @UnsupportedAppUsage public Transaction setLayerStack(SurfaceControl sc, int layerStack) { sc.checkNotReleased(); diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java index 67f9399e678a..2b68ec0edcbe 100644 --- a/core/java/android/view/SurfaceView.java +++ b/core/java/android/view/SurfaceView.java @@ -598,6 +598,7 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb } if (sizeChanged && !creating) { mSurfaceControl.setSize(mSurfaceWidth, mSurfaceHeight); + mSurfaceControl.setWindowCrop(mSurfaceWidth, mSurfaceHeight); } } finally { SurfaceControl.closeTransaction(); @@ -1169,6 +1170,12 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb } @Override + public void setWindowCrop(int width, int height) { + super.setWindowCrop(width, height); + mBackgroundControl.setWindowCrop(width, height); + } + + @Override public void setLayerStack(int layerStack) { super.setLayerStack(layerStack); mBackgroundControl.setLayerStack(layerStack); diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java index bac0154cc392..bf1a005bad18 100644 --- a/core/java/android/view/ThreadedRenderer.java +++ b/core/java/android/view/ThreadedRenderer.java @@ -172,6 +172,12 @@ public final class ThreadedRenderer extends HardwareRenderer { */ public static final String DEBUG_FPS_DIVISOR = "debug.hwui.fps_divisor"; + /** + * Forces smart-dark to be always on. + * @hide + */ + public static final String DEBUG_FORCE_DARK = "debug.hwui.force_dark"; + public static int EGL_CONTEXT_PRIORITY_HIGH_IMG = 0x3101; public static int EGL_CONTEXT_PRIORITY_MEDIUM_IMG = 0x3102; public static int EGL_CONTEXT_PRIORITY_LOW_IMG = 0x3103; @@ -675,10 +681,8 @@ public final class ThreadedRenderer extends HardwareRenderer { mLightY = a.getDimension(R.styleable.Lighting_lightY, 0); mLightZ = a.getDimension(R.styleable.Lighting_lightZ, 0); mLightRadius = a.getDimension(R.styleable.Lighting_lightRadius, 0); - final int ambientShadowAlpha = - (int) (255 * a.getFloat(R.styleable.Lighting_ambientShadowAlpha, 0) + 0.5f); - final int spotShadowAlpha = - (int) (255 * a.getFloat(R.styleable.Lighting_spotShadowAlpha, 0) + 0.5f); + final float ambientShadowAlpha = a.getFloat(R.styleable.Lighting_ambientShadowAlpha, 0); + final float spotShadowAlpha = a.getFloat(R.styleable.Lighting_spotShadowAlpha, 0); a.recycle(); setLightSourceAlpha(ambientShadowAlpha, spotShadowAlpha); } diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 7ba027f139ad..ec16828265fc 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -112,6 +112,7 @@ import android.view.autofill.AutofillValue; import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputConnection; import android.view.inputmethod.InputMethodManager; +import android.view.intelligence.IntelligenceManager; import android.widget.Checkable; import android.widget.FrameLayout; import android.widget.ScrollBarDrawable; @@ -799,6 +800,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback, private static final String AUTOFILL_LOG_TAG = "View.Autofill"; /** + * The logging tag used by this class when logging content capture-related messages. + */ + private static final String CONTENT_CAPTURE_LOG_TAG = "View.ContentCapture"; + + /** * When set to true, apps will draw debugging information about their layouts. * * @hide @@ -1337,6 +1343,59 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ public static final int AUTOFILL_FLAG_INCLUDE_NOT_IMPORTANT_VIEWS = 0x1; + /** @hide */ + @IntDef(prefix = { "IMPORTANT_FOR_CONTENT_CAPTURE_" }, value = { + IMPORTANT_FOR_CONTENT_CAPTURE_AUTO, + IMPORTANT_FOR_CONTENT_CAPTURE_YES, + IMPORTANT_FOR_CONTENT_CAPTURE_NO, + IMPORTANT_FOR_CONTENT_CAPTURE_YES_EXCLUDE_DESCENDANTS, + IMPORTANT_FOR_CONTENT_CAPTURE_NO_EXCLUDE_DESCENDANTS + }) + @Retention(RetentionPolicy.SOURCE) + public @interface ContentCaptureImportance {} + + /** + * Automatically determine whether a view is important for content capture. + * + * @see #isImportantForContentCapture() + * @see #setImportantForContentCapture(int) + */ + public static final int IMPORTANT_FOR_CONTENT_CAPTURE_AUTO = 0x0; + + /** + * The view is important for content capture, and its children (if any) will be traversed. + * + * @see #isImportantForContentCapture() + * @see #setImportantForContentCapture(int) + */ + public static final int IMPORTANT_FOR_CONTENT_CAPTURE_YES = 0x1; + + /** + * The view is not important for content capture, but its children (if any) will be traversed. + * + * @see #isImportantForContentCapture() + * @see #setImportantForContentCapture(int) + */ + public static final int IMPORTANT_FOR_CONTENT_CAPTURE_NO = 0x2; + + /** + * The view is important for content capture, but its children (if any) will not be traversed. + * + * @see #isImportantForContentCapture() + * @see #setImportantForContentCapture(int) + */ + public static final int IMPORTANT_FOR_CONTENT_CAPTURE_YES_EXCLUDE_DESCENDANTS = 0x4; + + /** + * The view is not important for content capture, and its children (if any) will not be + * traversed. + * + * @see #isImportantForContentCapture() + * @see #setImportantForContentCapture(int) + */ + public static final int IMPORTANT_FOR_CONTENT_CAPTURE_NO_EXCLUDE_DESCENDANTS = 0x8; + + /** * This view is enabled. Interpretation varies by subclass. * Use with ENABLED_MASK when calling setFlags. @@ -2243,7 +2302,44 @@ public class View implements Drawable.Callback, KeyEvent.Callback, @UnsupportedAppUsage protected Object mTag = null; - // for mPrivateFlags: + /* + * Masks for mPrivateFlags, as generated by dumpFlags(): + * + * |-------|-------|-------|-------| + * 1 PFLAG_WANTS_FOCUS + * 1 PFLAG_FOCUSED + * 1 PFLAG_SELECTED + * 1 PFLAG_IS_ROOT_NAMESPACE + * 1 PFLAG_HAS_BOUNDS + * 1 PFLAG_DRAWN + * 1 PFLAG_DRAW_ANIMATION + * 1 PFLAG_SKIP_DRAW + * 1 PFLAG_REQUEST_TRANSPARENT_REGIONS + * 1 PFLAG_DRAWABLE_STATE_DIRTY + * 1 PFLAG_MEASURED_DIMENSION_SET + * 1 PFLAG_FORCE_LAYOUT + * 1 PFLAG_LAYOUT_REQUIRED + * 1 PFLAG_PRESSED + * 1 PFLAG_DRAWING_CACHE_VALID + * 1 PFLAG_ANIMATION_STARTED + * 1 PFLAG_SAVE_STATE_CALLED + * 1 PFLAG_ALPHA_SET + * 1 PFLAG_SCROLL_CONTAINER + * 1 PFLAG_SCROLL_CONTAINER_ADDED + * 1 PFLAG_DIRTY + * 1 PFLAG_DIRTY_MASK + * 1 PFLAG_OPAQUE_BACKGROUND + * 1 PFLAG_OPAQUE_SCROLLBARS + * 11 PFLAG_OPAQUE_MASK + * 1 PFLAG_PREPRESSED + * 1 PFLAG_CANCEL_NEXT_UP_EVENT + * 1 PFLAG_AWAKEN_SCROLL_BARS_ON_ATTACH + * 1 PFLAG_HOVERED + * 1 PFLAG_NOTIFY_AUTOFILL_MANAGER_ON_CLICK + * 1 PFLAG_ACTIVATED + * 1 PFLAG_INVALIDATED + * |-------|-------|-------|-------| + */ /** {@hide} */ static final int PFLAG_WANTS_FOCUS = 0x00000001; /** {@hide} */ @@ -2393,7 +2489,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ static final int PFLAG_INVALIDATED = 0x80000000; - /** + /* End of masks for mPrivateFlags */ + + /* * Masks for mPrivateFlags2, as generated by dumpFlags(): * * |-------|-------|-------|-------| @@ -2934,7 +3032,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, /* End of masks for mPrivateFlags2 */ - /** + /* * Masks for mPrivateFlags3, as generated by dumpFlags(): * * |-------|-------|-------|-------| @@ -3270,6 +3368,57 @@ public class View implements Drawable.Callback, KeyEvent.Callback, /* End of masks for mPrivateFlags3 */ + /* + * Masks for mPrivateFlags4, as generated by dumpFlags(): + * + * |-------|-------|-------|-------| + * 1111 PFLAG4_IMPORTANT_FOR_CONTENT_CAPTURE_MASK + * 1 PFLAG4_NOTIFIED_CONTENT_CAPTURE_ON_LAYOUT + * 1 PFLAG4_NOTIFIED_CONTENT_CAPTURE_ADDED + * 1 PFLAG4_LAST_CONTENT_CAPTURE_NOTIFICATION_TYPE + * |-------|-------|-------|-------| + */ + + /** + * Mask for obtaining the bits which specify how to determine + * whether a view is important for autofill. + * + * <p>NOTE: the important for content capture values were the first flags added and are set in + * the rightmost position, so we don't need to shift them + */ + private static final int PFLAG4_IMPORTANT_FOR_CONTENT_CAPTURE_MASK = + IMPORTANT_FOR_CONTENT_CAPTURE_AUTO | IMPORTANT_FOR_CONTENT_CAPTURE_YES + | IMPORTANT_FOR_CONTENT_CAPTURE_NO + | IMPORTANT_FOR_CONTENT_CAPTURE_YES_EXCLUDE_DESCENDANTS + | IMPORTANT_FOR_CONTENT_CAPTURE_NO_EXCLUDE_DESCENDANTS; + + /* + * Variables used to control when the IntelligenceManager.notifyNodeAdded()/removed() methods + * should be called. + * + * The idea is to call notifyNodeAdded() after the view is layout and visible, then call + * notifyNodeRemoved() when it's gone (without known when it was removed from the parent). + * + * TODO(b/111276913): the current algortighm could probably be optimized and some of them + * removed + */ + private static final int PFLAG4_NOTIFIED_CONTENT_CAPTURE_ON_LAYOUT = 0x10; + private static final int PFLAG4_NOTIFIED_CONTENT_CAPTURE_ADDED = 0x20; + private static final int PFLAG4_LAST_CONTENT_CAPTURE_NOTIFICATION_TYPE = 0x40; + + private static final int CONTENT_CAPTURE_NOTIFICATION_TYPE_APPEARED = 1; + private static final int CONTENT_CAPTURE_NOTIFICATION_TYPE_DISAPPEARED = 0; + + /** @hide */ + @IntDef(flag = true, prefix = { "CONTENT_CAPTURE_NOTIFICATION_TYPE_" }, value = { + CONTENT_CAPTURE_NOTIFICATION_TYPE_APPEARED, + CONTENT_CAPTURE_NOTIFICATION_TYPE_DISAPPEARED + }) + @Retention(RetentionPolicy.SOURCE) + public @interface ContentCaptureNotificationType {} + + /* End of masks for mPrivateFlags4 */ + /** * Always allow a user to over-scroll this view, provided it is a * view that can scroll. @@ -3861,6 +4010,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, @UnsupportedAppUsage int mPrivateFlags3; + private int mPrivateFlags4; + /** * This view's request for the visibility of the status bar. * @hide @@ -5803,6 +5954,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, mAttributes = trimmed; } + @Override public String toString() { StringBuilder out = new StringBuilder(128); out.append(getClass().getName()); @@ -5875,6 +6027,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } } } + if (mAutofillId != null) { + out.append(" aid="); out.append(mAutofillId); + } out.append("}"); return out.toString(); } @@ -7888,7 +8043,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * fills in all data that can be inferred from the view itself. */ public void onProvideStructure(ViewStructure structure) { - onProvideStructureForAssistOrAutofill(structure, false, 0); + onProvideStructureForAssistOrAutofillOrViewCapture(structure, /* forAutofill = */ false, + /* forViewCapture= */ false, /* flags= */ 0); } /** @@ -7961,11 +8117,46 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @see #AUTOFILL_FLAG_INCLUDE_NOT_IMPORTANT_VIEWS */ public void onProvideAutofillStructure(ViewStructure structure, @AutofillFlags int flags) { - onProvideStructureForAssistOrAutofill(structure, true, flags); + onProvideStructureForAssistOrAutofillOrViewCapture(structure, /* forAutofill = */ true, + /* forViewCapture= */ false, flags); } - private void onProvideStructureForAssistOrAutofill(ViewStructure structure, - boolean forAutofill, @AutofillFlags int flags) { + /** + * Populates a {@link ViewStructure} for Content Capture. + * + * <p>This method is called after a view is that is eligible for Content Capture + * (for example, if it {@link #isImportantForAutofill()}, an intelligence service is enabled for + * the user, and the activity rendering the view is enabled for Content Capture) is laid out and + * is visible. + * + * <p><b>Note: </b>the following methods of the {@code structure} will be ignored: + * <ul> + * <li>{@link ViewStructure#setChildCount(int)} + * <li>{@link ViewStructure#addChildCount(int)} + * <li>{@link ViewStructure#getChildCount()} + * <li>{@link ViewStructure#newChild(int)} + * <li>{@link ViewStructure#asyncNewChild(int)} + * <li>{@link ViewStructure#asyncCommit()} + * <li>{@link ViewStructure#setWebDomain(String)} + * <li>{@link ViewStructure#newHtmlInfoBuilder(String)} + * <li>{@link ViewStructure#setHtmlInfo(android.view.ViewStructure.HtmlInfo)} + * <li>{@link ViewStructure#setDataIsSensitive(boolean)} + * </ul> + * + * @return whether the IntelligenceService should be notified that the view was added (through + * the {@link IntelligenceManager#notifyViewAppeared(ViewStructure)} method) to the view + * hierarchy. Most views should return {@code true} here, but views that contains virtual + * hierarchy might opt to return {@code false} and notify the manager independently, as the + * virtual views are rendered. + */ + public boolean onProvideContentCaptureStructure(@NonNull ViewStructure structure, int flags) { + onProvideStructureForAssistOrAutofillOrViewCapture(structure, /* forAutofill = */ false, + /* forViewCapture= */ true, flags); + return true; + } + + private void onProvideStructureForAssistOrAutofillOrViewCapture(ViewStructure structure, + boolean forAutofill, boolean forViewCapture, @AutofillFlags int flags) { final int id = mID; if (id != NO_ID && !isViewIdGenerated(id)) { String pkg, type, entry; @@ -7981,8 +8172,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } else { structure.setId(id, null, null, null); } + if (forViewCapture) { + structure.setDataIsSensitive(false); + } - if (forAutofill) { + if (forAutofill || forViewCapture) { final @AutofillType int autofillType = getAutofillType(); // Don't need to fill autofill info if view does not support it. // For example, only TextViews that are editable support autofill @@ -8530,9 +8724,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, if (parentImportance == IMPORTANT_FOR_AUTOFILL_NO_EXCLUDE_DESCENDANTS || parentImportance == IMPORTANT_FOR_AUTOFILL_YES_EXCLUDE_DESCENDANTS) { if (Log.isLoggable(AUTOFILL_LOG_TAG, Log.VERBOSE)) { - Log.v(AUTOFILL_LOG_TAG, "View (autofillId=" + getAutofillViewId() + ", " - + getClass() + ") is not important for autofill because parent " - + parent + "'s importance is " + parentImportance); + Log.v(AUTOFILL_LOG_TAG, "View (" + this + ") is not important for autofill " + + "because parent " + parent + "'s importance is " + parentImportance); } return false; } @@ -8549,14 +8742,18 @@ public class View implements Drawable.Callback, KeyEvent.Callback, if (importance == IMPORTANT_FOR_AUTOFILL_NO_EXCLUDE_DESCENDANTS || importance == IMPORTANT_FOR_AUTOFILL_NO) { if (Log.isLoggable(AUTOFILL_LOG_TAG, Log.VERBOSE)) { - Log.v(AUTOFILL_LOG_TAG, "View (autofillId=" + getAutofillViewId() + ", " - + getClass() + ") is not important for autofill because its " - + "importance is " + importance); + Log.v(AUTOFILL_LOG_TAG, "View (" + this + ") is not important for autofill " + + "because its importance is " + importance); } return false; } // Then use some heuristics to handle AUTO. + if (importance != IMPORTANT_FOR_AUTOFILL_AUTO) { + Log.w(AUTOFILL_LOG_TAG, "invalid autofill importance (" + importance + " on view " + + this); + return false; + } // Always include views that have an explicit resource id. final int id = mID; @@ -8584,6 +8781,198 @@ public class View implements Drawable.Callback, KeyEvent.Callback, return false; } + /** + * Gets the mode for determining whether this view is important for content capture. + * + * <p>See {@link #setImportantForContentCapture(int)} and + * {@link #isImportantForContentCapture()} for more info about this mode. + * + * @return {@link #IMPORTANT_FOR_CONTENT_CAPTURE_AUTO} by default, or value passed to + * {@link #setImportantForContentCapture(int)}. + * + * @attr ref android.R.styleable#View_importantForContentCapture + */ + @ViewDebug.ExportedProperty(mapping = { + @ViewDebug.IntToString(from = IMPORTANT_FOR_CONTENT_CAPTURE_AUTO, to = "auto"), + @ViewDebug.IntToString(from = IMPORTANT_FOR_CONTENT_CAPTURE_YES, to = "yes"), + @ViewDebug.IntToString(from = IMPORTANT_FOR_CONTENT_CAPTURE_NO, to = "no"), + @ViewDebug.IntToString(from = IMPORTANT_FOR_CONTENT_CAPTURE_YES_EXCLUDE_DESCENDANTS, + to = "yesExcludeDescendants"), + @ViewDebug.IntToString(from = IMPORTANT_FOR_CONTENT_CAPTURE_NO_EXCLUDE_DESCENDANTS, + to = "noExcludeDescendants")}) + public @ContentCaptureImportance int getImportantForContentCapture() { + // NOTE: the important for content capture values were the first flags added and are set in + // the rightmost position, so we don't need to shift them + return mPrivateFlags4 & PFLAG4_IMPORTANT_FOR_CONTENT_CAPTURE_MASK; + } + + /** + * Sets the mode for determining whether this view is considered important for content capture. + * + * <p>The platform determines the importance for autofill automatically but you + * can use this method to customize the behavior. Typically, a view that provides text should + * be marked as {@link #IMPORTANT_FOR_CONTENT_CAPTURE_YES}. + * + * @param mode {@link #IMPORTANT_FOR_CONTENT_CAPTURE_AUTO}, + * {@link #IMPORTANT_FOR_CONTENT_CAPTURE_YES}, {@link #IMPORTANT_FOR_CONTENT_CAPTURE_NO}, + * {@link #IMPORTANT_FOR_CONTENT_CAPTURE_YES_EXCLUDE_DESCENDANTS}, + * or {@link #IMPORTANT_FOR_CONTENT_CAPTURE_NO_EXCLUDE_DESCENDANTS}. + * + * @attr ref android.R.styleable#View_importantForContentCapture + */ + public void setImportantForContentCapture(@ContentCaptureImportance int mode) { + // Reset first + mPrivateFlags4 &= ~PFLAG4_IMPORTANT_FOR_CONTENT_CAPTURE_MASK; + // Then set again + // NOTE: the important for content capture values were the first flags added and are set in + // the rightmost position, so we don't need to shift them + mPrivateFlags4 |= (mode & PFLAG4_IMPORTANT_FOR_CONTENT_CAPTURE_MASK); + } + + /** + * Hints the Android System whether this view is considered important for Content Capture, based + * on the value explicitly set by {@link #setImportantForContentCapture(int)} and heuristics + * when it's {@link #IMPORTANT_FOR_CONTENT_CAPTURE_AUTO}. + * + * @return whether the view is considered important for autofill. + * + * @see #setImportantForContentCapture(int) + * @see #IMPORTANT_FOR_CONTENT_CAPTURE_AUTO + * @see #IMPORTANT_FOR_CONTENT_CAPTURE_YES + * @see #IMPORTANT_FOR_CONTENT_CAPTURE_NO + * @see #IMPORTANT_FOR_CONTENT_CAPTURE_YES_EXCLUDE_DESCENDANTS + * @see #IMPORTANT_FOR_CONTENT_CAPTURE_NO_EXCLUDE_DESCENDANTS + */ + public final boolean isImportantForContentCapture() { + // Check parent mode to ensure we're important + ViewParent parent = mParent; + while (parent instanceof View) { + final int parentImportance = ((View) parent).getImportantForContentCapture(); + if (parentImportance == IMPORTANT_FOR_CONTENT_CAPTURE_NO_EXCLUDE_DESCENDANTS + || parentImportance == IMPORTANT_FOR_CONTENT_CAPTURE_YES_EXCLUDE_DESCENDANTS) { + if (Log.isLoggable(CONTENT_CAPTURE_LOG_TAG, Log.VERBOSE)) { + Log.v(CONTENT_CAPTURE_LOG_TAG, "View (" + this + ") is not important for " + + "content capture because parent " + parent + "'s importance is " + + parentImportance); + } + return false; + } + parent = parent.getParent(); + } + + final int importance = getImportantForContentCapture(); + + // First, check the explicit states. + if (importance == IMPORTANT_FOR_CONTENT_CAPTURE_YES_EXCLUDE_DESCENDANTS + || importance == IMPORTANT_FOR_CONTENT_CAPTURE_YES) { + return true; + } + if (importance == IMPORTANT_FOR_CONTENT_CAPTURE_NO_EXCLUDE_DESCENDANTS + || importance == IMPORTANT_FOR_CONTENT_CAPTURE_NO) { + if (Log.isLoggable(CONTENT_CAPTURE_LOG_TAG, Log.VERBOSE)) { + Log.v(CONTENT_CAPTURE_LOG_TAG, "View (" + this + ") is not important for content " + + "capture because its importance is " + importance); + } + return false; + } + + // Then use some heuristics to handle AUTO. + if (importance != IMPORTANT_FOR_CONTENT_CAPTURE_AUTO) { + Log.w(CONTENT_CAPTURE_LOG_TAG, "invalid content capture importance (" + importance + + " on view " + this); + return false; + } + + // View group is important if at least one children also is + //TODO(b/111276913): decide if we really need to send the relevant parents or just the + // leaves (with absolute coordinates). If it's the latter, then we need to update this + // javadoc and ViewGroup's implementation. + if (this instanceof ViewGroup) { + final ViewGroup group = (ViewGroup) this; + for (int i = 0; i < group.getChildCount(); i++) { + final View child = group.getChildAt(i); + if (child.isImportantForContentCapture()) { + return true; + } + } + } + + // If the app developer explicitly set hints or autofill hintsfor it, it's important. + if (getAutofillHints() != null) { + return true; + } + + // Otherwise, assume it's not important... + return false; + } + + /** + * Helper used to notify the {@link IntelligenceManager}anager when the view is removed or + * added, based on whether it's laid out and visible, and without knowing if the parent removed + * it from the view + * hierarchy. + */ + // TODO(b/111276913): make sure the current algorithm covers all cases. For example, it should + // probably be called every time notifyEnterOrExitForAutoFillIfNeeded() is called as well. + private void notifyNodeAddedOrRemovedForContentCaptureIfNeeded( + @ContentCaptureNotificationType int type) { + if (type != CONTENT_CAPTURE_NOTIFICATION_TYPE_APPEARED + && type != CONTENT_CAPTURE_NOTIFICATION_TYPE_DISAPPEARED) { + // Sanity check so it does not screw up the flags + Log.wtf(CONTENT_CAPTURE_LOG_TAG, "notifyNodeAddedOrRemovedForContentCaptureIfNeeded(): " + + "invalid type " + type + " for " + this); + return; + } + + if (!isImportantForContentCapture()) return; + + final IntelligenceManager im = mContext.getSystemService(IntelligenceManager.class); + if (im == null || !im.isContentCaptureEnabled()) return; + + // Make sure event is notified just once, and reset the + // PFLAG4_LAST_CONTENT_CAPTURE_NOTIFICATION_TYPE flag + boolean ignoreNotification = false; + if (type == CONTENT_CAPTURE_NOTIFICATION_TYPE_APPEARED) { + if ((mPrivateFlags4 & PFLAG4_LAST_CONTENT_CAPTURE_NOTIFICATION_TYPE) + == CONTENT_CAPTURE_NOTIFICATION_TYPE_APPEARED) { + ignoreNotification = true; + } else { + mPrivateFlags4 |= PFLAG4_LAST_CONTENT_CAPTURE_NOTIFICATION_TYPE; + } + } else { + if ((mPrivateFlags4 & PFLAG4_LAST_CONTENT_CAPTURE_NOTIFICATION_TYPE) + == CONTENT_CAPTURE_NOTIFICATION_TYPE_DISAPPEARED) { + ignoreNotification = true; + } else { + mPrivateFlags4 &= ~PFLAG4_LAST_CONTENT_CAPTURE_NOTIFICATION_TYPE; + } + } + if (ignoreNotification) { + if (Log.isLoggable(CONTENT_CAPTURE_LOG_TAG, Log.VERBOSE)) { + // TODO(b/111276913): remove this log statement if the algorithm is not improved + // (right now it's called too many times when the activity is stopped and/or views + // disappear + Log.v(CONTENT_CAPTURE_LOG_TAG, "notifyNodeAddedOrRemovedForContentCaptureIfNeeded(" + + type + "): ignoring repeated notification on " + this); + } + return; + } + + if (type == CONTENT_CAPTURE_NOTIFICATION_TYPE_APPEARED) { + final ViewStructure structure = im.newViewStructure(this); + boolean notifyMgr = onProvideContentCaptureStructure(structure, /* flags= */ 0); + if (notifyMgr) { + im.notifyViewAppeared(structure); + } + mPrivateFlags4 |= PFLAG4_NOTIFIED_CONTENT_CAPTURE_ADDED; + } else { + if ((mPrivateFlags4 & PFLAG4_NOTIFIED_CONTENT_CAPTURE_ADDED) == 0) { + return; // skip initial notification + } + im.notifyViewDisappeared(getAutofillId()); + } + } + @Nullable private AutofillManager getAutofillManager() { return mContext.getSystemService(AutofillManager.class); @@ -13094,6 +13483,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback, : AccessibilityEvent.CONTENT_CHANGE_TYPE_PANE_DISAPPEARED); } } + notifyNodeAddedOrRemovedForContentCaptureIfNeeded(isVisible + ? CONTENT_CAPTURE_NOTIFICATION_TYPE_APPEARED + : CONTENT_CAPTURE_NOTIFICATION_TYPE_DISAPPEARED); } /** @@ -18630,6 +19022,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } notifyEnterOrExitForAutoFillIfNeeded(false); + notifyNodeAddedOrRemovedForContentCaptureIfNeeded( + CONTENT_CAPTURE_NOTIFICATION_TYPE_DISAPPEARED); } /** @@ -20934,6 +21328,13 @@ public class View implements Drawable.Callback, KeyEvent.Callback, mPrivateFlags3 &= ~PFLAG3_NOTIFY_AUTOFILL_ENTER_ON_LAYOUT; notifyEnterOrExitForAutoFillIfNeeded(true); } + + if ((mViewFlags & VISIBILITY_MASK) == VISIBLE + && (mPrivateFlags4 & PFLAG4_NOTIFIED_CONTENT_CAPTURE_ON_LAYOUT) == 0) { + notifyNodeAddedOrRemovedForContentCaptureIfNeeded( + CONTENT_CAPTURE_NOTIFICATION_TYPE_APPEARED); + mPrivateFlags4 |= PFLAG4_NOTIFIED_CONTENT_CAPTURE_ON_LAYOUT; + } } private boolean hasParentWantsFocus() { diff --git a/core/java/android/view/ViewStructure.java b/core/java/android/view/ViewStructure.java index 38dcdd30d843..6efb6f38d118 100644 --- a/core/java/android/view/ViewStructure.java +++ b/core/java/android/view/ViewStructure.java @@ -24,7 +24,6 @@ import android.os.Bundle; import android.os.LocaleList; import android.util.Pair; import android.view.View.AutofillImportance; -import android.view.ViewStructure.HtmlInfo; import android.view.autofill.AutofillId; import android.view.autofill.AutofillValue; diff --git a/core/java/android/view/WindowInsets.java b/core/java/android/view/WindowInsets.java index 4a7e783ffbdb..a8debbd623f5 100644 --- a/core/java/android/view/WindowInsets.java +++ b/core/java/android/view/WindowInsets.java @@ -77,11 +77,17 @@ public final class WindowInsets { CONSUMED = new WindowInsets((Insets) null, null, null, false, false, null); } - /** @hide */ + /** + * Construct a new WindowInsets from individual insets. + * + * A {@code null} inset indicates that the respective inset is consumed. + * + * @hide + */ public WindowInsets(Rect systemWindowInsets, Rect windowDecorInsets, Rect stableInsets, boolean isRound, boolean alwaysConsumeNavBar, DisplayCutout displayCutout) { - this(Insets.of(systemWindowInsets), Insets.of(windowDecorInsets), Insets.of(stableInsets), - isRound, alwaysConsumeNavBar, displayCutout); + this(insetsOrNull(systemWindowInsets), insetsOrNull(windowDecorInsets), + insetsOrNull(stableInsets), isRound, alwaysConsumeNavBar, displayCutout); } private WindowInsets(Insets systemWindowInsets, Insets windowDecorInsets, @@ -673,6 +679,10 @@ public final class WindowInsets { return Insets.of(newLeft, newTop, newRight, newBottom); } + private static Insets insetsOrNull(Rect insets) { + return insets != null ? Insets.of(insets) : null; + } + /** * @return whether system window insets have been consumed. */ diff --git a/core/java/android/view/intelligence/ContentCaptureEvent.java b/core/java/android/view/intelligence/ContentCaptureEvent.java index 2530ae3b3124..befcb55b1f73 100644 --- a/core/java/android/view/intelligence/ContentCaptureEvent.java +++ b/core/java/android/view/intelligence/ContentCaptureEvent.java @@ -16,12 +16,17 @@ package android.view.intelligence; import android.annotation.IntDef; +import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; import android.os.Parcel; import android.os.Parcelable; +import android.os.SystemClock; import android.view.autofill.AutofillId; +import com.android.internal.util.Preconditions; + +import java.io.PrintWriter; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -60,14 +65,14 @@ public final class ContentCaptureEvent implements Parcelable { * * <p>The metadata of the node is available through {@link #getViewNode()}. */ - public static final int TYPE_VIEW_ADDED = 5; + public static final int TYPE_VIEW_APPEARED = 5; /** * Called when a node has been removed from the screen and is not visible to the user anymore. * * <p>The id of the node is available through {@link #getId()}. */ - public static final int TYPE_VIEW_REMOVED = 6; + public static final int TYPE_VIEW_DISAPPEARED = 6; /** * Called when the text of a node has been changed. @@ -85,8 +90,8 @@ public final class ContentCaptureEvent implements Parcelable { TYPE_ACTIVITY_PAUSED, TYPE_ACTIVITY_RESUMED, TYPE_ACTIVITY_STOPPED, - TYPE_VIEW_ADDED, - TYPE_VIEW_REMOVED, + TYPE_VIEW_APPEARED, + TYPE_VIEW_DISAPPEARED, TYPE_VIEW_TEXT_CHANGED }) @Retention(RetentionPolicy.SOURCE) @@ -95,7 +100,9 @@ public final class ContentCaptureEvent implements Parcelable { private final int mType; private final long mEventTime; private final int mFlags; - + private @Nullable AutofillId mId; + private @Nullable ViewNode mNode; + private @Nullable CharSequence mText; /** @hide */ public ContentCaptureEvent(int type, long eventTime, int flags) { @@ -104,12 +111,42 @@ public final class ContentCaptureEvent implements Parcelable { mFlags = flags; } + + /** @hide */ + public ContentCaptureEvent(int type, int flags) { + this(type, SystemClock.uptimeMillis(), flags); + } + + /** @hide */ + public ContentCaptureEvent(int type) { + this(type, /* flags= */ 0); + } + + /** @hide */ + public ContentCaptureEvent setAutofillId(@NonNull AutofillId id) { + mId = Preconditions.checkNotNull(id); + return this; + } + + /** @hide */ + public ContentCaptureEvent setViewNode(@NonNull ViewNode node) { + mNode = Preconditions.checkNotNull(node); + return this; + } + + /** @hide */ + public ContentCaptureEvent setText(@Nullable CharSequence text) { + mText = text; + return this; + } + /** * Gets the type of the event. * * @return one of {@link #TYPE_ACTIVITY_STARTED}, {@link #TYPE_ACTIVITY_RESUMED}, * {@link #TYPE_ACTIVITY_PAUSED}, {@link #TYPE_ACTIVITY_STOPPED}, - * {@link #TYPE_VIEW_ADDED}, {@link #TYPE_VIEW_REMOVED}, or {@link #TYPE_VIEW_TEXT_CHANGED}. + * {@link #TYPE_VIEW_APPEARED}, {@link #TYPE_VIEW_DISAPPEARED}, + * or {@link #TYPE_VIEW_TEXT_CHANGED}. */ public @EventType int getType() { return mType; @@ -135,21 +172,21 @@ public final class ContentCaptureEvent implements Parcelable { /** * Gets the whole metadata of the node associated with the event. * - * <p>Only set on {@link #TYPE_VIEW_ADDED} events. + * <p>Only set on {@link #TYPE_VIEW_APPEARED} events. */ @Nullable public ViewNode getViewNode() { - return null; + return mNode; } /** * Gets the {@link AutofillId} of the node associated with the event. * - * <p>Only set on {@link #TYPE_VIEW_REMOVED} and {@link #TYPE_VIEW_TEXT_CHANGED} events. + * <p>Only set on {@link #TYPE_VIEW_DISAPPEARED} and {@link #TYPE_VIEW_TEXT_CHANGED} events. */ @Nullable public AutofillId getId() { - return null; + return mId; } /** @@ -159,16 +196,41 @@ public final class ContentCaptureEvent implements Parcelable { */ @Nullable public CharSequence getText() { - return null; + return mText; + } + + /** @hide */ + public void dump(@NonNull PrintWriter pw) { + pw.print("type="); pw.print(getTypeAsString(mType)); + pw.print(", time="); pw.print(mEventTime); + if (mFlags > 0) { + pw.print(", flags="); pw.print(mFlags); + } + if (mId != null) { + pw.print(", id="); pw.print(mId); + } + if (mNode != null) { + pw.print(", id="); pw.print(mNode.getAutofillId()); + } } @Override public String toString() { final StringBuilder string = new StringBuilder("ContentCaptureEvent[type=") - .append(getTypeAsString(mType)).append(", time=").append(mEventTime); + .append(getTypeAsString(mType)); if (mFlags > 0) { string.append(", flags=").append(mFlags); } + if (mId != null) { + string.append(", id=").append(mId); + } + if (mNode != null) { + final String className = mNode.getClassName(); + if (mNode != null) { + string.append(", class=").append(className); + } + string.append(", id=").append(mNode.getAutofillId()); + } return string.append(']').toString(); } @@ -182,6 +244,9 @@ public final class ContentCaptureEvent implements Parcelable { parcel.writeInt(mType); parcel.writeLong(mEventTime); parcel.writeInt(mFlags); + parcel.writeParcelable(mId, flags); + ViewNode.writeToParcel(parcel, mNode, flags); + parcel.writeCharSequence(mText); } public static final Parcelable.Creator<ContentCaptureEvent> CREATOR = @@ -192,7 +257,17 @@ public final class ContentCaptureEvent implements Parcelable { final int type = parcel.readInt(); final long eventTime = parcel.readLong(); final int flags = parcel.readInt(); - return new ContentCaptureEvent(type, eventTime, flags); + final ContentCaptureEvent event = new ContentCaptureEvent(type, eventTime, flags); + final AutofillId id = parcel.readParcelable(null); + if (id != null) { + event.setAutofillId(id); + } + final ViewNode node = ViewNode.readFromParcel(parcel); + if (node != null) { + event.setViewNode(node); + } + event.setText(parcel.readCharSequence()); + return event; } @Override @@ -201,7 +276,6 @@ public final class ContentCaptureEvent implements Parcelable { } }; - /** @hide */ public static String getTypeAsString(@EventType int type) { switch (type) { @@ -213,10 +287,10 @@ public final class ContentCaptureEvent implements Parcelable { return "ACTIVITY_PAUSED"; case TYPE_ACTIVITY_STOPPED: return "ACTIVITY_STOPPED"; - case TYPE_VIEW_ADDED: - return "VIEW_ADDED"; - case TYPE_VIEW_REMOVED: - return "VIEW_REMOVED"; + case TYPE_VIEW_APPEARED: + return "VIEW_APPEARED"; + case TYPE_VIEW_DISAPPEARED: + return "VIEW_DISAPPEARED"; case TYPE_VIEW_TEXT_CHANGED: return "VIEW_TEXT_CHANGED"; default: diff --git a/core/java/android/view/intelligence/IntelligenceManager.java b/core/java/android/view/intelligence/IntelligenceManager.java index 9bf6c2ce6184..c02fb3218a2e 100644 --- a/core/java/android/view/intelligence/IntelligenceManager.java +++ b/core/java/android/view/intelligence/IntelligenceManager.java @@ -15,6 +15,12 @@ */ package android.view.intelligence; +import static android.view.intelligence.ContentCaptureEvent.TYPE_VIEW_APPEARED; +import static android.view.intelligence.ContentCaptureEvent.TYPE_VIEW_DISAPPEARED; +import static android.view.intelligence.ContentCaptureEvent.TYPE_VIEW_TEXT_CHANGED; + +import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage; + import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; @@ -22,11 +28,15 @@ import android.annotation.SystemService; import android.content.ComponentName; import android.content.Context; import android.os.Bundle; +import android.os.Handler; +import android.os.HandlerThread; import android.os.IBinder; import android.os.RemoteException; -import android.os.SystemClock; import android.service.intelligence.InteractionSessionId; import android.util.Log; +import android.view.View; +import android.view.ViewStructure; +import android.view.autofill.AutofillId; import android.view.intelligence.ContentCaptureEvent.EventType; import com.android.internal.annotations.GuardedBy; @@ -34,8 +44,7 @@ import com.android.internal.os.IResultReceiver; import com.android.internal.util.Preconditions; import java.io.PrintWriter; -import java.util.Arrays; -import java.util.List; +import java.util.ArrayList; import java.util.Set; /** @@ -46,8 +55,9 @@ public final class IntelligenceManager { private static final String TAG = "IntelligenceManager"; - // TODO(b/111276913): define a way to dynamically set it (for example, using settings?) + // TODO(b/111276913): define a way to dynamically set them(for example, using settings?) private static final boolean VERBOSE = false; + private static final boolean DEBUG = true; // STOPSHIP if not set to false /** * Used to indicate that a text change was caused by user input (for example, through IME). @@ -55,7 +65,6 @@ public final class IntelligenceManager { //TODO(b/111276913): link to notifyTextChanged() method once available public static final int FLAG_USER_INPUT = 0x1; - /** * Initial state, when there is no session. * @@ -77,6 +86,15 @@ public final class IntelligenceManager { */ public static final int STATE_ACTIVE = 2; + private static final String BG_THREAD_NAME = "intel_svc_streamer_thread"; + + /** + * Maximum number of events that are delayed for an app. + * + * <p>If the session is not started after the limit is reached, it's discarded. + */ + private static final int MAX_DELAYED_SIZE = 20; + private final Context mContext; @Nullable @@ -99,10 +117,24 @@ public final class IntelligenceManager { @GuardedBy("mLock") private ComponentName mComponentName; + // TODO(b/111276913): create using maximum batch size as capacity + /** + * List of events held to be sent as a batch. + */ + @GuardedBy("mLock") + private final ArrayList<ContentCaptureEvent> mEvents = new ArrayList<>(); + + private final Handler mHandler; + /** @hide */ public IntelligenceManager(@NonNull Context context, @Nullable IIntelligenceManager service) { mContext = Preconditions.checkNotNull(context, "context cannot be null"); mService = service; + + // TODO(b/111276913): use an existing bg thread instead... + final HandlerThread bgThread = new HandlerThread(BG_THREAD_NAME); + bgThread.start(); + mHandler = Handler.createAsync(bgThread.getLooper()); } /** @hide */ @@ -111,8 +143,9 @@ public final class IntelligenceManager { synchronized (mLock) { if (mState != STATE_UNKNOWN) { + // TODO(b/111276913): revisit this scenario Log.w(TAG, "ignoring onActivityStarted(" + token + ") while on state " - + getStateAsStringLocked()); + + getStateAsString(mState)); return; } mState = STATE_WAITING_FOR_SERVER; @@ -121,8 +154,8 @@ public final class IntelligenceManager { mComponentName = componentName; if (VERBOSE) { - Log.v(TAG, "onActivityStarted(): token=" + token + ", act=" + componentName - + ", id=" + mId); + Log.v(TAG, "onActivityCreated(): token=" + token + ", act=" + + getActivityDebugNameLocked() + ", id=" + mId); } final int flags = 0; // TODO(b/111276913): get proper flags @@ -138,12 +171,12 @@ public final class IntelligenceManager { } else { // TODO(b/111276913): handle other cases like disabled by // service - mState = STATE_UNKNOWN; + resetStateLocked(); } if (VERBOSE) { Log.v(TAG, "onActivityStarted() result: code=" + resultCode + ", id=" + mId - + ", state=" + getStateAsStringLocked()); + + ", state=" + getStateAsString(mState)); } } } @@ -154,37 +187,74 @@ public final class IntelligenceManager { } } - /** - * Used for intermediate events (i.e, other than created and destroyed). - * - * @hide - */ - public void onActivityLifecycleEvent(@EventType int type) { - if (!isContentCaptureEnabled()) return; + //TODO(b/111276913): should buffer event (and call service on handler thread), instead of + // calling right away + private void sendEvent(@NonNull ContentCaptureEvent event) { + mHandler.sendMessage(obtainMessage(IntelligenceManager::handleSendEvent, this, event)); + } - //TODO(b/111276913): should buffer event (and call service on handler thread), instead of - // calling right away - final ContentCaptureEvent event = new ContentCaptureEvent(type, SystemClock.uptimeMillis(), - 0); - final List<ContentCaptureEvent> events = Arrays.asList(event); + private void handleSendEvent(@NonNull ContentCaptureEvent event) { synchronized (mLock) { - //TODO(b/111276913): check session state; for example, how to handle if it's waiting for - // remote id + mEvents.add(event); + final int numberEvents = mEvents.size(); + if (mState != STATE_ACTIVE) { + if (numberEvents >= MAX_DELAYED_SIZE) { + // Typically happens on system apps that are started before the system service + // is ready (like com.android.settings/.FallbackHome) + //TODO(b/111276913): try to ignore session while system is not ready / boot + // not complete instead. + Log.w(TAG, "Closing session for " + getActivityDebugNameLocked() + + " after " + numberEvents + " delayed events"); + // TODO(b/111276913): blacklist activity / use special flag to indicate that + // when it's launched again + resetStateLocked(); + return; + } + + if (VERBOSE) { + Log.v(TAG, "Delaying " + numberEvents + " events for " + + getActivityDebugNameLocked() + " while on state " + + getStateAsString(mState)); + } + return; + } - if (VERBOSE) { - Log.v(TAG, "onActivityLifecycleEvent() for " + mComponentName.flattenToShortString() - + ": " + ContentCaptureEvent.getTypeAsString(type)); + if (mId == null) { + // Sanity check - should not happen + Log.wtf(TAG, "null session id for " + mComponentName); + return; } + //TODO(b/111276913): right now we're sending sending right away (unless not ready), but + // we should hold the events and flush later. try { - mService.sendEvents(mContext.getUserId(), mId, events); + if (DEBUG) { + Log.d(TAG, "Sending " + numberEvents + " event(s) for " + + getActivityDebugNameLocked()); + } + mService.sendEvents(mContext.getUserId(), mId, mEvents); + mEvents.clear(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } } + /** + * Used for intermediate events (i.e, other than created and destroyed). + * + * @hide + */ + public void onActivityLifecycleEvent(@EventType int type) { + if (!isContentCaptureEnabled()) return; + if (VERBOSE) { + Log.v(TAG, "onActivityLifecycleEvent() for " + getActivityDebugNameLocked() + + ": " + ContentCaptureEvent.getTypeAsString(type)); + } + sendEvent(new ContentCaptureEvent(type)); + } + /** @hide */ public void onActivityDestroyed() { if (!isContentCaptureEnabled()) return; @@ -194,22 +264,105 @@ public final class IntelligenceManager { // id) and send it to the cache of batched commands if (VERBOSE) { - Log.v(TAG, "onActivityDestroyed(): state=" + getStateAsStringLocked() + Log.v(TAG, "onActivityDestroyed(): state=" + getStateAsString(mState) + ", mId=" + mId); } try { mService.finishSession(mContext.getUserId(), mId); - mState = STATE_UNKNOWN; - mId = null; - mApplicationToken = null; - mComponentName = null; + resetStateLocked(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } } + @GuardedBy("mLock") + private void resetStateLocked() { + mState = STATE_UNKNOWN; + mId = null; + mApplicationToken = null; + mComponentName = null; + mEvents.clear(); + } + + /** + * Notifies the Intelligence Service that a node has been added to the view structure. + * + * <p>Typically called "manually" by views that handle their own virtual view hierarchy, or + * automatically by the Android System for views that return {@code true} on + * {@link View#onProvideContentCaptureStructure(ViewStructure, int)}. + * + * @param node node that has been added. + */ + public void notifyViewAppeared(@NonNull ViewStructure node) { + Preconditions.checkNotNull(node); + if (!isContentCaptureEnabled()) return; + + if (!(node instanceof ViewNode.ViewStructureImpl)) { + throw new IllegalArgumentException("Invalid node class: " + node.getClass()); + } + sendEvent(new ContentCaptureEvent(TYPE_VIEW_APPEARED) + .setViewNode(((ViewNode.ViewStructureImpl) node).mNode)); + } + + /** + * Notifies the Intelligence Service that a node has been removed from the view structure. + * + * <p>Typically called "manually" by views that handle their own virtual view hierarchy, or + * automatically by the Android System for standard views. + * + * @param id id of the node that has been removed. + */ + public void notifyViewDisappeared(@NonNull AutofillId id) { + Preconditions.checkNotNull(id); + if (!isContentCaptureEnabled()) return; + + sendEvent(new ContentCaptureEvent(TYPE_VIEW_DISAPPEARED).setAutofillId(id)); + } + + /** + * Notifies the Intelligence Service that the value of a text node has been changed. + * + * @param id of the node. + * @param text new text. + * @param flags either {@code 0} or {@link #FLAG_USER_INPUT} when the value was explicitly + * changed by the user (for example, through the keyboard). + */ + public void notifyViewTextChanged(@NonNull AutofillId id, @Nullable CharSequence text, + int flags) { + Preconditions.checkNotNull(id); + if (!isContentCaptureEnabled()) return; + + sendEvent(new ContentCaptureEvent(TYPE_VIEW_TEXT_CHANGED, flags).setAutofillId(id) + .setText(text)); + } + + /** + * Creates a {@link ViewStructure} for a "standard" view. + * + * @hide + */ + @NonNull + public ViewStructure newViewStructure(@NonNull View view) { + return new ViewNode.ViewStructureImpl(view); + } + + /** + * Creates a {@link ViewStructure} for a "virtual" view, so it can be passed to + * {@link #notifyViewAppeared(ViewStructure)} by the view managing the virtual view hierarchy. + * + * @param parentId id of the virtual view parent (it can be obtained by calling + * {@link ViewStructure#getAutofillId()} on the parent). + * @param virtualId id of the virtual child, relative to the parent. + * + * @return a new {@link ViewStructure} that can be used for Content Capture purposes. + */ + @NonNull + public ViewStructure newVirtualViewStructure(@NonNull AutofillId parentId, int virtualId) { + return new ViewNode.ViewStructureImpl(parentId, virtualId); + } + /** * Returns the component name of the {@code android.service.intelligence.IntelligenceService} * that is enabled for the current user. @@ -322,15 +475,29 @@ public final class IntelligenceManager { pw.print(prefix2); pw.print("enabled: "); pw.println(isContentCaptureEnabled()); pw.print(prefix2); pw.print("id: "); pw.println(mId); pw.print(prefix2); pw.print("state: "); pw.print(mState); pw.print(" ("); - pw.print(getStateAsStringLocked()); pw.println(")"); - pw.print(prefix2); pw.print("appToken: "); pw.println(mApplicationToken); - pw.print(prefix2); pw.print("componentName: "); pw.println(mComponentName); + pw.print(getStateAsString(mState)); pw.println(")"); + pw.print(prefix2); pw.print("app token: "); pw.println(mApplicationToken); + pw.print(prefix2); pw.print("component name: "); + pw.println(mComponentName == null ? "null" : mComponentName.flattenToShortString()); + final int numberEvents = mEvents.size(); + pw.print(prefix2); pw.print("batched events: "); pw.println(numberEvents); + if (numberEvents > 0) { + for (int i = 0; i < numberEvents; i++) { + final ContentCaptureEvent event = mEvents.get(i); + pw.println(i); pw.print(": "); event.dump(pw); pw.println(); + } + + } } } + /** + * Gets a string that can be used to identify the activity on logging statements. + */ @GuardedBy("mLock") - private String getStateAsStringLocked() { - return getStateAsString(mState); + private String getActivityDebugNameLocked() { + return mComponentName == null ? mContext.getPackageName() + : mComponentName.flattenToShortString(); } @NonNull diff --git a/core/java/android/view/intelligence/ViewNode.java b/core/java/android/view/intelligence/ViewNode.java index 357ecf599f7a..cc78e6b4aa6d 100644 --- a/core/java/android/view/intelligence/ViewNode.java +++ b/core/java/android/view/intelligence/ViewNode.java @@ -15,10 +15,24 @@ */ package android.view.intelligence; +import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; import android.app.assist.AssistStructure; +import android.graphics.Matrix; +import android.graphics.Rect; +import android.os.Bundle; +import android.os.LocaleList; +import android.os.Parcel; +import android.util.Log; +import android.view.View; +import android.view.ViewParent; +import android.view.ViewStructure; +import android.view.ViewStructure.HtmlInfo.Builder; import android.view.autofill.AutofillId; +import android.view.autofill.AutofillValue; + +import com.android.internal.util.Preconditions; //TODO(b/111276913): add javadocs / implement Parcelable / implement //TODO(b/111276913): for now it's extending ViewNode directly as it needs most of its properties, @@ -28,6 +42,16 @@ import android.view.autofill.AutofillId; @SystemApi public final class ViewNode extends AssistStructure.ViewNode { + private static final String TAG = "ViewNode"; + + private AutofillId mParentAutofillId; + + // TODO(b/111276913): temporarily setting some fields here while they're not accessible from the + // superclass + private AutofillId mAutofillId; + private CharSequence mText; + private String mClassName; + /** @hide */ public ViewNode() { } @@ -38,7 +62,343 @@ public final class ViewNode extends AssistStructure.ViewNode { */ @Nullable public AutofillId getParentAutofillId() { - //TODO(b/111276913): implement - return null; + return mParentAutofillId; + } + + // TODO(b/111276913): temporarily overwriting some methods + @Override + public AutofillId getAutofillId() { + return mAutofillId; + } + @Override + public CharSequence getText() { + return mText; + } + @Override + public String getClassName() { + return mClassName; + } + + /** @hide */ + public static void writeToParcel(@NonNull Parcel parcel, @Nullable ViewNode node, int flags) { + if (node == null) { + parcel.writeParcelable(null, flags); + return; + } + parcel.writeParcelable(node.mAutofillId, flags); + parcel.writeParcelable(node.mParentAutofillId, flags); + parcel.writeCharSequence(node.mText); + parcel.writeString(node.mClassName); + } + + /** @hide */ + public static @Nullable ViewNode readFromParcel(@NonNull Parcel parcel) { + final AutofillId id = parcel.readParcelable(null); + if (id == null) return null; + + final ViewNode node = new ViewNode(); + + node.mAutofillId = id; + node.mParentAutofillId = parcel.readParcelable(null); + node.mText = parcel.readCharSequence(); + node.mClassName = parcel.readString(); + + return node; + } + + /** @hide */ + static final class ViewStructureImpl extends ViewStructure { + + final ViewNode mNode = new ViewNode(); + + ViewStructureImpl(@NonNull View view) { + mNode.mAutofillId = Preconditions.checkNotNull(view).getAutofillId(); + final ViewParent parent = view.getParent(); + if (parent instanceof View) { + mNode.mParentAutofillId = ((View) parent).getAutofillId(); + } + } + + ViewStructureImpl(@NonNull AutofillId parentId, int virtualId) { + mNode.mParentAutofillId = Preconditions.checkNotNull(parentId); + mNode.mAutofillId = new AutofillId(parentId, virtualId); + } + + @Override + public void setId(int id, String packageName, String typeName, String entryName) { + // TODO(b/111276913): implement or move to superclass + } + + @Override + public void setDimens(int left, int top, int scrollX, int scrollY, int width, int height) { + // TODO(b/111276913): implement or move to superclass + } + + @Override + public void setTransformation(Matrix matrix) { + // TODO(b/111276913): implement or move to superclass + } + + @Override + public void setElevation(float elevation) { + // TODO(b/111276913): implement or move to superclass + } + + @Override + public void setAlpha(float alpha) { + // TODO(b/111276913): implement or move to superclass + } + + @Override + public void setVisibility(int visibility) { + // TODO(b/111276913): implement or move to superclass + } + + @Override + public void setAssistBlocked(boolean state) { + // TODO(b/111276913): implement or move to superclass + } + + @Override + public void setEnabled(boolean state) { + // TODO(b/111276913): implement or move to superclass + } + + @Override + public void setClickable(boolean state) { + // TODO(b/111276913): implement or move to superclass + } + + @Override + public void setLongClickable(boolean state) { + // TODO(b/111276913): implement or move to superclass + } + + @Override + public void setContextClickable(boolean state) { + // TODO(b/111276913): implement or move to superclass + } + + @Override + public void setFocusable(boolean state) { + // TODO(b/111276913): implement or move to superclass + } + + @Override + public void setFocused(boolean state) { + // TODO(b/111276913): implement or move to superclass + } + + @Override + public void setAccessibilityFocused(boolean state) { + // TODO(b/111276913): implement or move to superclass + } + + @Override + public void setCheckable(boolean state) { + // TODO(b/111276913): implement or move to superclass + } + + @Override + public void setChecked(boolean state) { + // TODO(b/111276913): implement or move to superclass + } + + @Override + public void setSelected(boolean state) { + // TODO(b/111276913): implement or move to superclass + } + + @Override + public void setActivated(boolean state) { + // TODO(b/111276913): implement or move to superclass + } + + @Override + public void setOpaque(boolean opaque) { + // TODO(b/111276913): implement or move to superclass + } + + @Override + public void setClassName(String className) { + // TODO(b/111276913): temporarily setting directly; should be done on superclass instead + mNode.mClassName = className; + } + + @Override + public void setContentDescription(CharSequence contentDescription) { + // TODO(b/111276913): implement or move to superclass + } + + @Override + public void setText(CharSequence text) { + // TODO(b/111276913): temporarily setting directly; should be done on superclass instead + mNode.mText = text; + } + + @Override + public void setText(CharSequence text, int selectionStart, int selectionEnd) { + // TODO(b/111276913): implement or move to superclass + } + + @Override + public void setTextStyle(float size, int fgColor, int bgColor, int style) { + // TODO(b/111276913): implement or move to superclass + } + + @Override + public void setTextLines(int[] charOffsets, int[] baselines) { + // TODO(b/111276913): implement or move to superclass + } + + @Override + public void setHint(CharSequence hint) { + // TODO(b/111276913): implement or move to superclass + } + + @Override + public CharSequence getText() { + // TODO(b/111276913): temporarily getting directly; should be done on superclass instead + return mNode.mText; + } + + @Override + public int getTextSelectionStart() { + // TODO(b/111276913): implement or move to superclass + return 0; + } + + @Override + public int getTextSelectionEnd() { + // TODO(b/111276913): implement or move to superclass + return 0; + } + + @Override + public CharSequence getHint() { + // TODO(b/111276913): implement or move to superclass + return null; + } + + @Override + public Bundle getExtras() { + // TODO(b/111276913): implement or move to superclass + return null; + } + + @Override + public boolean hasExtras() { + // TODO(b/111276913): implement or move to superclass + return false; + } + + @Override + public void setChildCount(int num) { + Log.w(TAG, "setChildCount() is not supported"); + } + + @Override + public int addChildCount(int num) { + Log.w(TAG, "addChildCount() is not supported"); + return 0; + } + + @Override + public int getChildCount() { + Log.w(TAG, "getChildCount() is not supported"); + return 0; + } + + @Override + public ViewStructure newChild(int index) { + Log.w(TAG, "newChild() is not supported"); + return null; + } + + @Override + public ViewStructure asyncNewChild(int index) { + Log.w(TAG, "asyncNewChild() is not supported"); + return null; + } + + @Override + public AutofillId getAutofillId() { + // TODO(b/111276913): temporarily getting directly; should be done on superclass instead + return mNode.mAutofillId; + } + + @Override + public void setAutofillId(AutofillId id) { + // TODO(b/111276913): temporarily setting directly; should be done on superclass instead + mNode.mAutofillId = id; + } + + @Override + public void setAutofillId(AutofillId parentId, int virtualId) { + // TODO(b/111276913): temporarily setting directly; should be done on superclass instead + mNode.mAutofillId = new AutofillId(parentId, virtualId); + } + + @Override + public void setAutofillType(int type) { + // TODO(b/111276913): implement or move to superclass + } + + @Override + public void setAutofillHints(String[] hint) { + // TODO(b/111276913): implement or move to superclass + } + + @Override + public void setAutofillValue(AutofillValue value) { + // TODO(b/111276913): implement or move to superclass + } + + @Override + public void setAutofillOptions(CharSequence[] options) { + // TODO(b/111276913): implement or move to superclass + } + + @Override + public void setInputType(int inputType) { + // TODO(b/111276913): implement or move to superclass + } + + @Override + public void setDataIsSensitive(boolean sensitive) { + // TODO(b/111276913): implement or move to superclass + } + + @Override + public void asyncCommit() { + Log.w(TAG, "asyncCommit() is not supported"); + } + + @Override + public Rect getTempRect() { + // TODO(b/111276913): implement or move to superclass + return null; + } + + @Override + public void setWebDomain(String domain) { + Log.w(TAG, "setWebDomain() is not supported"); + } + + @Override + public void setLocaleList(LocaleList localeList) { + // TODO(b/111276913): implement or move to superclass + } + + @Override + public Builder newHtmlInfoBuilder(String tagName) { + Log.w(TAG, "newHtmlInfoBuilder() is not supported"); + return null; + } + + @Override + public void setHtmlInfo(HtmlInfo htmlInfo) { + Log.w(TAG, "setHtmlInfo() is not supported"); + } } } diff --git a/core/java/android/view/textclassifier/TextClassifier.java b/core/java/android/view/textclassifier/TextClassifier.java index e6757448b5bb..524f70939398 100644 --- a/core/java/android/view/textclassifier/TextClassifier.java +++ b/core/java/android/view/textclassifier/TextClassifier.java @@ -48,6 +48,9 @@ import java.util.Set; /** * Interface for providing text classification related features. + * <p> + * The TextClassifier may be used to understand the meaning of text, as well as generating predicted + * next actions based on the text. * * <p><strong>NOTE: </strong>Unless otherwise stated, methods of this interface are blocking * operations. Call on a worker thread. diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java index f343a52b365c..10937196a74f 100644 --- a/core/java/android/webkit/WebView.java +++ b/core/java/android/webkit/WebView.java @@ -2695,6 +2695,11 @@ public class WebView extends AbsoluteLayout } @Override + public boolean onProvideContentCaptureStructure(ViewStructure structure, int flags) { + return mProvider.getViewDelegate().onProvideContentCaptureStructure(structure, flags); + } + + @Override public void autofill(SparseArray<AutofillValue>values) { mProvider.getViewDelegate().autofill(values); } diff --git a/core/java/android/webkit/WebViewProvider.java b/core/java/android/webkit/WebViewProvider.java index 00e782bd5046..ceada07c715b 100644 --- a/core/java/android/webkit/WebViewProvider.java +++ b/core/java/android/webkit/WebViewProvider.java @@ -341,6 +341,12 @@ public interface WebViewProvider { return true; // true is the default value returned by View.isVisibleToUserForAutofill() } + default boolean onProvideContentCaptureStructure( + @SuppressWarnings("unused") android.view.ViewStructure structure, + @SuppressWarnings("unused") int flags) { + return false; // WebView provides virtual views and is responsible to notify manager + } + public AccessibilityNodeProvider getAccessibilityNodeProvider(); public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info); diff --git a/core/java/android/widget/Magnifier.java b/core/java/android/widget/Magnifier.java index 9da2a4307a93..9f509b1f3d0b 100644 --- a/core/java/android/widget/Magnifier.java +++ b/core/java/android/widget/Magnifier.java @@ -93,6 +93,8 @@ public final class Magnifier { private final int mDefaultHorizontalSourceToMagnifierOffset; // The vertical offset between the source and window coords when #show(float, float) is used. private final int mDefaultVerticalSourceToMagnifierOffset; + // Whether the magnifier will be clamped inside the main surface and not overlap system insets. + private final boolean mForcePositionWithinWindowSystemInsetsBounds; // The parent surface for the magnifier surface. private SurfaceInfo mParentSurface; // The surface where the content will be copied from. @@ -141,6 +143,8 @@ public final class Magnifier { params.mHorizontalDefaultSourceToMagnifierOffset; mDefaultVerticalSourceToMagnifierOffset = params.mVerticalDefaultSourceToMagnifierOffset; + mForcePositionWithinWindowSystemInsetsBounds = + params.mForcePositionWithinWindowSystemInsetsBounds; // The view's surface coordinates will not be updated until the magnifier is first shown. mViewCoordinatesInSurface = new int[2]; } @@ -379,6 +383,17 @@ public final class Magnifier { } /** + * Returns whether the magnifier position will be adjusted such that the magnifier will be + * fully within the bounds of the main application window, by also avoiding any overlap with + * system insets (such as the one corresponding to the status bar). + * @return whether the magnifier position will be adjusted + * @see Magnifier.Builder#setForcePositionWithinWindowSystemInsetsBounds(boolean) + */ + public boolean isForcePositionWithinWindowSystemInsetsBounds() { + return mForcePositionWithinWindowSystemInsetsBounds; + } + + /** * Returns the top left coordinates of the magnifier, relative to the surface of the * main application window. They will be determined by the coordinates of the last * {@link #show(float, float)} or {@link #show(float, float, float, float)} call, adjusted @@ -567,6 +582,11 @@ public final class Magnifier { * @return the current window coordinates, after they are clamped inside the parent surface */ private Point getCurrentClampedWindowCoordinates() { + if (!mForcePositionWithinWindowSystemInsetsBounds) { + // No position adjustment should be done, so return the raw coordinates. + return new Point(mWindowCoords); + } + final Rect windowBounds; if (mParentSurface.mIsMainWindowSurface) { final Insets systemInsets = mView.getRootWindowInsets().getSystemWindowInsets(); @@ -891,6 +911,7 @@ public final class Magnifier { private @FloatRange(from = 0f) float mCornerRadius; private int mHorizontalDefaultSourceToMagnifierOffset; private int mVerticalDefaultSourceToMagnifierOffset; + private boolean mForcePositionWithinWindowSystemInsetsBounds; /** * Construct a new builder for {@link Magnifier} objects. @@ -915,6 +936,7 @@ public final class Magnifier { mVerticalDefaultSourceToMagnifierOffset = a.getDimensionPixelSize(R.styleable.Magnifier_magnifierVerticalOffset, 0); a.recycle(); + mForcePositionWithinWindowSystemInsetsBounds = true; } /** @@ -1000,6 +1022,28 @@ public final class Magnifier { } /** + * Defines the behavior of the magnifier when it is requested to position outside the + * surface of the main application window. The default value is {@code true}, which means + * that the position will be adjusted such that the magnifier will be fully within the + * bounds of the main application window, by also avoiding any overlap with system insets + * (such as the one corresponding to the status bar). If you require a custom behavior, this + * flag should be set to {@code false}, meaning that the magnifier will be able to cross the + * main application surface boundaries (and also overlap the system insets). This should be + * handled with care, when passing coordinates to {@link #show(float, float)}; note that: + * <ul> + * <li>in a multiwindow context, if the magnifier crosses the boundary between the two + * windows, it will not be able to show over the window of the other application</li> + * <li>if the magnifier overlaps the status bar, there is no guarantee about which one + * will be displayed on top. This should be handled with care.</li> + * </ul> + * @param force whether the magnifier position will be adjusted + */ + public Builder setForcePositionWithinWindowSystemInsetsBounds(boolean force) { + mForcePositionWithinWindowSystemInsetsBounds = force; + return this; + } + + /** * Builds a {@link Magnifier} instance based on the configuration of this {@link Builder}. */ public @NonNull Magnifier build() { diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java index a93604f95c79..c0979fe13de4 100644 --- a/core/java/android/widget/RemoteViews.java +++ b/core/java/android/widget/RemoteViews.java @@ -196,12 +196,6 @@ public class RemoteViews implements Parcelable, Filter { private boolean mIsRoot = true; /** - * Optional theme resource id applied in inflateView(). When 0, Theme.DeviceDefault will be - * used. - */ - private int mApplyThemeResId; - - /** * Whether reapply is disallowed on this remoteview. This maybe be true if some actions modify * the layout in a way that isn't recoverable, since views are being removed. */ @@ -3262,14 +3256,6 @@ public class RemoteViews implements Parcelable, Filter { } /** - * Set the theme used in apply() and applyASync(). - * @hide - */ - public void setApplyTheme(@StyleRes int themeResId) { - mApplyThemeResId = themeResId; - } - - /** * Inflates the view hierarchy represented by this object and applies * all of the actions. * @@ -3290,11 +3276,25 @@ public class RemoteViews implements Parcelable, Filter { View result = inflateView(context, rvToApply, parent); rvToApply.performApply(result, parent, handler); + return result; + } + + /** @hide */ + public View applyWithTheme(Context context, ViewGroup parent, OnClickHandler handler, + @StyleRes int applyThemeResId) { + RemoteViews rvToApply = getRemoteViewsToApply(context); + View result = inflateView(context, rvToApply, parent, applyThemeResId); + rvToApply.performApply(result, parent, handler); return result; } private View inflateView(Context context, RemoteViews rv, ViewGroup parent) { + return inflateView(context, rv, parent, 0); + } + + private View inflateView(Context context, RemoteViews rv, ViewGroup parent, + @StyleRes int applyThemeResId) { // RemoteViews may be built by an application installed in another // user. So build a context that loads resources from that user but // still returns the current users userId so settings like data / time formats @@ -3303,8 +3303,8 @@ public class RemoteViews implements Parcelable, Filter { Context inflationContext = new RemoteViewsContextWrapper(context, contextForResources); // If mApplyThemeResId is not given, Theme.DeviceDefault will be used. - if (mApplyThemeResId != 0) { - inflationContext = new ContextThemeWrapper(inflationContext, mApplyThemeResId); + if (applyThemeResId != 0) { + inflationContext = new ContextThemeWrapper(inflationContext, applyThemeResId); } LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); diff --git a/core/java/android/widget/Switch.java b/core/java/android/widget/Switch.java index 8bfc151b1a83..d55c09f7fcb6 100644 --- a/core/java/android/widget/Switch.java +++ b/core/java/android/widget/Switch.java @@ -1422,17 +1422,24 @@ public class Switch extends CompoundButton { @Override public void onProvideStructure(ViewStructure structure) { super.onProvideStructure(structure); - onProvideAutoFillStructureForAssistOrAutofill(structure); + onProvideStructureForAssistOrAutofillOrViewCapture(structure); } @Override public void onProvideAutofillStructure(ViewStructure structure, int flags) { super.onProvideAutofillStructure(structure, flags); - onProvideAutoFillStructureForAssistOrAutofill(structure); + onProvideStructureForAssistOrAutofillOrViewCapture(structure); } - // NOTE: currently there is no difference for Assist or AutoFill, so it doesn't take flags - private void onProvideAutoFillStructureForAssistOrAutofill(ViewStructure structure) { + @Override + public boolean onProvideContentCaptureStructure(ViewStructure structure, int flags) { + final boolean notifyManager = super.onProvideContentCaptureStructure(structure, flags); + onProvideStructureForAssistOrAutofillOrViewCapture(structure); + return notifyManager; + } + + // NOTE: currently there is no difference for any type, so it doesn't take flags + private void onProvideStructureForAssistOrAutofillOrViewCapture(ViewStructure structure) { CharSequence switchText = isChecked() ? mTextOn : mTextOff; if (!TextUtils.isEmpty(switchText)) { CharSequence oldText = structure.getText(); diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index 572670fc662b..3bdd7b8e91be 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -166,6 +166,7 @@ import android.view.inputmethod.ExtractedText; import android.view.inputmethod.ExtractedTextRequest; import android.view.inputmethod.InputConnection; import android.view.inputmethod.InputMethodManager; +import android.view.intelligence.IntelligenceManager; import android.view.textclassifier.TextClassification; import android.view.textclassifier.TextClassificationContext; import android.view.textclassifier.TextClassificationManager; @@ -948,6 +949,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener if (getImportantForAutofill() == IMPORTANT_FOR_AUTOFILL_AUTO) { setImportantForAutofill(IMPORTANT_FOR_AUTOFILL_YES); } + if (getImportantForContentCapture() == IMPORTANT_FOR_CONTENT_CAPTURE_AUTO) { + setImportantForContentCapture(IMPORTANT_FOR_CONTENT_CAPTURE_YES); + } setTextInternal(""); @@ -6072,7 +6076,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener if (needEditableForNotification) { sendAfterTextChanged((Editable) text); } else { - notifyAutoFillManagerAfterTextChanged(); + notifyManagersAfterTextChanged(); } // SelectionModifierCursorController depends on textCanBeSelected, which depends on text @@ -10121,23 +10125,33 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } // Always notify AutoFillManager - it will return right away if autofill is disabled. - notifyAutoFillManagerAfterTextChanged(); + notifyManagersAfterTextChanged(); hideErrorIfUnchanged(); } - private void notifyAutoFillManagerAfterTextChanged() { - // It is important to not check whether the view is important for autofill - // since the user can trigger autofill manually on not important views. - if (!isAutofillable()) { - return; + private void notifyManagersAfterTextChanged() { + + // Autofill + if (isAutofillable()) { + // It is important to not check whether the view is important for autofill + // since the user can trigger autofill manually on not important views. + final AutofillManager afm = mContext.getSystemService(AutofillManager.class); + if (afm != null) { + if (android.view.autofill.Helper.sVerbose) { + Log.v(LOG_TAG, "notifyAutoFillManagerAfterTextChanged"); + } + afm.notifyValueChanged(TextView.this); + } } - final AutofillManager afm = mContext.getSystemService(AutofillManager.class); - if (afm != null) { - if (android.view.autofill.Helper.sVerbose) { - Log.v(LOG_TAG, "notifyAutoFillManagerAfterTextChanged"); + + // ContentCapture + if (isImportantForContentCapture() && isTextEditable()) { + final IntelligenceManager im = mContext.getSystemService(IntelligenceManager.class); + if (im != null && im.isContentCaptureEnabled()) { + // TODO(b/111276913): pass flags when edited by user / add CTS test + im.notifyViewTextChanged(getAutofillId(), getText(), /* flags= */ 0); } - afm.notifyValueChanged(TextView.this); } } @@ -10900,21 +10914,33 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener @Override public void onProvideStructure(ViewStructure structure) { super.onProvideStructure(structure); - onProvideAutoStructureForAssistOrAutofill(structure, false); + onProvideStructureForAssistOrAutofillOrViewCapture(structure, /* forAutofill = */ false, + /* forViewCapture= */ false); } @Override public void onProvideAutofillStructure(ViewStructure structure, int flags) { super.onProvideAutofillStructure(structure, flags); - onProvideAutoStructureForAssistOrAutofill(structure, true); + onProvideStructureForAssistOrAutofillOrViewCapture(structure, /* forAutofill = */ true, + /* forViewCapture= */ false); + } + + @Override + public boolean onProvideContentCaptureStructure(ViewStructure structure, int flags) { + final boolean notifyManager = super.onProvideContentCaptureStructure(structure, flags); + onProvideStructureForAssistOrAutofillOrViewCapture(structure, /* forAutofill = */ false, + /* forViewCapture= */ true); + return notifyManager; } - private void onProvideAutoStructureForAssistOrAutofill(ViewStructure structure, - boolean forAutofill) { + private void onProvideStructureForAssistOrAutofillOrViewCapture(ViewStructure structure, + boolean forAutofill, boolean forViewCapture) { final boolean isPassword = hasPasswordTransformationMethod() || isPasswordInputType(getInputType()); - if (forAutofill) { - structure.setDataIsSensitive(!mTextSetFromXmlOrResourceId); + if (forAutofill || forViewCapture) { + if (forAutofill) { + structure.setDataIsSensitive(!mTextSetFromXmlOrResourceId); + } if (mTextId != ResourceId.ID_NULL) { try { structure.setTextIdEntry(getResources().getResourceEntryName(mTextId)); @@ -10927,7 +10953,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } } - if (!isPassword || forAutofill) { + if (!isPassword || forAutofill || forViewCapture) { if (mLayout == null) { assumeLayout(); } @@ -11043,7 +11069,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener // of the View (and can be any drawable) or a BackgroundColorSpan inside the text. structure.setTextStyle(getTextSize(), getCurrentTextColor(), AssistStructure.ViewNode.TEXT_COLOR_UNDEFINED /* bgColor */, style); - } else { + } + if (forAutofill || forViewCapture) { structure.setMinTextEms(getMinEms()); structure.setMaxTextEms(getMaxEms()); int maxLength = -1; diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java index 0f8872267042..46c6fa42babf 100644 --- a/core/java/com/android/internal/app/ResolverActivity.java +++ b/core/java/com/android/internal/app/ResolverActivity.java @@ -93,6 +93,9 @@ import java.util.Set; @UiThread public class ResolverActivity extends Activity { + // Temporary flag for new chooser delegate behavior. + boolean mEnableChooserDelegate = false; + protected ResolveListAdapter mAdapter; private boolean mSafeForwardingMode; private AbsListView mAdapterView; @@ -1216,7 +1219,13 @@ public class ResolverActivity extends Activity { @Override public boolean startAsCaller(ResolverActivity activity, Bundle options, int userId) { - return activity.startAsCallerImpl(mResolvedIntent, options, false, userId); + + if (mEnableChooserDelegate) { + return activity.startAsCallerImpl(mResolvedIntent, options, false, userId); + } else { + activity.startActivityAsCaller(mResolvedIntent, options, null, false, userId); + return true; + } } @Override diff --git a/core/java/com/android/internal/statusbar/IStatusBar.aidl b/core/java/com/android/internal/statusbar/IStatusBar.aidl index 9b8f120ec08d..604537ffee03 100644 --- a/core/java/com/android/internal/statusbar/IStatusBar.aidl +++ b/core/java/com/android/internal/statusbar/IStatusBar.aidl @@ -142,7 +142,7 @@ oneway interface IStatusBar // Used to show the dialog when BiometricService starts authentication void showBiometricDialog(in Bundle bundle, IBiometricPromptReceiver receiver, int type, - boolean requireConfirmation); + boolean requireConfirmation, int userId); // Used to hide the dialog when a biometric is authenticated void onBiometricAuthenticated(); // Used to set a temporary message, e.g. fingerprint not recognized, finger moved too fast, etc diff --git a/core/java/com/android/internal/statusbar/IStatusBarService.aidl b/core/java/com/android/internal/statusbar/IStatusBarService.aidl index 90f2002d7363..9a7094accfae 100644 --- a/core/java/com/android/internal/statusbar/IStatusBarService.aidl +++ b/core/java/com/android/internal/statusbar/IStatusBarService.aidl @@ -92,7 +92,7 @@ interface IStatusBarService // Used to show the dialog when BiometricService starts authentication void showBiometricDialog(in Bundle bundle, IBiometricPromptReceiver receiver, int type, - boolean requireConfirmation); + boolean requireConfirmation, int userId); // Used to hide the dialog when a biometric is authenticated void onBiometricAuthenticated(); // Used to set a temporary message, e.g. fingerprint not recognized, finger moved too fast, etc diff --git a/core/jni/android_hardware_camera2_DngCreator.cpp b/core/jni/android_hardware_camera2_DngCreator.cpp index c977437f7df2..29051f14c72f 100644 --- a/core/jni/android_hardware_camera2_DngCreator.cpp +++ b/core/jni/android_hardware_camera2_DngCreator.cpp @@ -892,6 +892,13 @@ static status_t convertCFA(uint8_t cfaEnum, /*out*/uint8_t* cfaOut) { cfaOut[3] = 0; break; } + // MONO and NIR are degenerate case of RGGB pattern: only Red channel + // will be used. + case ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_MONO: + case ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_NIR: { + cfaOut[0] = 0; + break; + } default: { return BAD_VALUE; } @@ -1063,6 +1070,8 @@ static sp<TiffWriter> DngCreator_setup(JNIEnv* env, jobject thiz, uint32_t image uint32_t preWidth = 0; uint32_t preHeight = 0; + uint8_t colorFilter = 0; + bool isBayer = true; { // Check dimensions camera_metadata_entry entry = @@ -1083,9 +1092,24 @@ static sp<TiffWriter> DngCreator_setup(JNIEnv* env, jobject thiz, uint32_t image "either the preCorrectionActiveArraySize or the pixelArraySize."); return nullptr; } - } - + camera_metadata_entry colorFilterEntry = + characteristics.find(ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT); + colorFilter = colorFilterEntry.data.u8[0]; + camera_metadata_entry capabilitiesEntry = + characteristics.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES); + size_t capsCount = capabilitiesEntry.count; + uint8_t* caps = capabilitiesEntry.data.u8; + if (std::find(caps, caps+capsCount, ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MONOCHROME) + != caps+capsCount) { + isBayer = false; + } else if (colorFilter == ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_MONO || + colorFilter == ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_NIR) { + jniThrowException(env, "java/lang/AssertionError", + "A camera device with MONO/NIR color filter must have MONOCHROME capability."); + return nullptr; + } + } writer->addIfd(TIFF_IFD_0); @@ -1094,9 +1118,12 @@ static sp<TiffWriter> DngCreator_setup(JNIEnv* env, jobject thiz, uint32_t image const uint32_t samplesPerPixel = 1; const uint32_t bitsPerSample = BITS_PER_SAMPLE; - OpcodeListBuilder::CfaLayout opcodeCfaLayout = OpcodeListBuilder::CFA_RGGB; + OpcodeListBuilder::CfaLayout opcodeCfaLayout = OpcodeListBuilder::CFA_NONE; uint8_t cfaPlaneColor[3] = {0, 1, 2}; - uint8_t cfaEnum = -1; + camera_metadata_entry cfaEntry = + characteristics.find(ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT); + BAIL_IF_EMPTY_RET_NULL_SP(cfaEntry, env, TAG_CFAPATTERN, writer); + uint8_t cfaEnum = cfaEntry.data.u8[0]; // TODO: Greensplit. // TODO: Add remaining non-essential tags @@ -1141,12 +1168,20 @@ static sp<TiffWriter> DngCreator_setup(JNIEnv* env, jobject thiz, uint32_t image { // Set photometric interpretation - uint16_t interpretation = 32803; // CFA + uint16_t interpretation = isBayer ? 32803 /* CFA */ : + 34892; /* Linear Raw */; BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_PHOTOMETRICINTERPRETATION, 1, &interpretation, TIFF_IFD_0), env, TAG_PHOTOMETRICINTERPRETATION, writer); } { + uint16_t repeatDim[2] = {2, 2}; + if (!isBayer) { + repeatDim[0] = repeatDim[1] = 1; + } + BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_BLACKLEVELREPEATDIM, 2, repeatDim, + TIFF_IFD_0), env, TAG_BLACKLEVELREPEATDIM, writer); + // Set blacklevel tags, using dynamic black level if available camera_metadata_entry entry = results.find(ANDROID_SENSOR_DYNAMIC_BLACK_LEVEL); @@ -1165,14 +1200,9 @@ static sp<TiffWriter> DngCreator_setup(JNIEnv* env, jobject thiz, uint32_t image blackLevelRational[i * 2] = static_cast<uint32_t>(entry.data.i32[i]); blackLevelRational[i * 2 + 1] = 1; } - } - BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_BLACKLEVEL, 4, blackLevelRational, - TIFF_IFD_0), env, TAG_BLACKLEVEL, writer); - - uint16_t repeatDim[2] = {2, 2}; - BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_BLACKLEVELREPEATDIM, 2, repeatDim, - TIFF_IFD_0), env, TAG_BLACKLEVELREPEATDIM, writer); + BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_BLACKLEVEL, repeatDim[0]*repeatDim[1], + blackLevelRational, TIFF_IFD_0), env, TAG_BLACKLEVEL, writer); } { @@ -1189,21 +1219,15 @@ static sp<TiffWriter> DngCreator_setup(JNIEnv* env, jobject thiz, uint32_t image TIFF_IFD_0), env, TAG_PLANARCONFIGURATION, writer); } - { + // All CFA pattern tags are not necessary for monochrome cameras. + if (isBayer) { // Set CFA pattern dimensions uint16_t repeatDim[2] = {2, 2}; BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_CFAREPEATPATTERNDIM, 2, repeatDim, TIFF_IFD_0), env, TAG_CFAREPEATPATTERNDIM, writer); - } - { // Set CFA pattern - camera_metadata_entry entry = - characteristics.find(ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT); - BAIL_IF_EMPTY_RET_NULL_SP(entry, env, TAG_CFAPATTERN, writer); - const int cfaLength = 4; - cfaEnum = entry.data.u8[0]; uint8_t cfa[cfaLength]; if ((err = convertCFA(cfaEnum, /*out*/cfa)) != OK) { jniThrowExceptionFmt(env, "java/lang/IllegalStateException", @@ -1214,15 +1238,11 @@ static sp<TiffWriter> DngCreator_setup(JNIEnv* env, jobject thiz, uint32_t image env, TAG_CFAPATTERN, writer); opcodeCfaLayout = convertCFAEnumToOpcodeLayout(cfaEnum); - } - { // Set CFA plane color BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_CFAPLANECOLOR, 3, cfaPlaneColor, TIFF_IFD_0), env, TAG_CFAPLANECOLOR, writer); - } - { // Set CFA layout uint16_t cfaLayout = 1; BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_CFALAYOUT, 1, &cfaLayout, TIFF_IFD_0), @@ -1442,7 +1462,7 @@ static sp<TiffWriter> DngCreator_setup(JNIEnv* env, jobject thiz, uint32_t image } bool singleIlluminant = false; - { + if (isBayer) { // Set calibration illuminants camera_metadata_entry entry1 = characteristics.find(ANDROID_SENSOR_REFERENCE_ILLUMINANT1); @@ -1464,7 +1484,7 @@ static sp<TiffWriter> DngCreator_setup(JNIEnv* env, jobject thiz, uint32_t image } } - { + if (isBayer) { // Set color transforms camera_metadata_entry entry1 = characteristics.find(ANDROID_SENSOR_COLOR_TRANSFORM1); @@ -1497,7 +1517,7 @@ static sp<TiffWriter> DngCreator_setup(JNIEnv* env, jobject thiz, uint32_t image } } - { + if (isBayer) { // Set calibration transforms camera_metadata_entry entry1 = characteristics.find(ANDROID_SENSOR_CALIBRATION_TRANSFORM1); @@ -1531,7 +1551,7 @@ static sp<TiffWriter> DngCreator_setup(JNIEnv* env, jobject thiz, uint32_t image } } - { + if (isBayer) { // Set forward transforms camera_metadata_entry entry1 = characteristics.find(ANDROID_SENSOR_FORWARD_MATRIX1); @@ -1565,7 +1585,7 @@ static sp<TiffWriter> DngCreator_setup(JNIEnv* env, jobject thiz, uint32_t image } } - { + if (isBayer) { // Set camera neutral camera_metadata_entry entry = results.find(ANDROID_SENSOR_NEUTRAL_COLOR_POINT); @@ -1632,8 +1652,8 @@ static sp<TiffWriter> DngCreator_setup(JNIEnv* env, jobject thiz, uint32_t image camera_metadata_entry entry = results.find(ANDROID_SENSOR_NOISE_PROFILE); - const status_t numPlaneColors = 3; - const status_t numCfaChannels = 4; + const status_t numPlaneColors = isBayer ? 3 : 1; + const status_t numCfaChannels = isBayer ? 4 : 1; uint8_t cfaOut[numCfaChannels]; if ((err = convertCFA(cfaEnum, /*out*/cfaOut)) != OK) { @@ -1710,41 +1730,43 @@ static sp<TiffWriter> DngCreator_setup(JNIEnv* env, jobject thiz, uint32_t image } } + // Hot pixel map is specific to bayer camera per DNG spec. + if (isBayer) { + // Set up bad pixel correction list + camera_metadata_entry entry3 = characteristics.find(ANDROID_STATISTICS_HOT_PIXEL_MAP); - // Set up bad pixel correction list - camera_metadata_entry entry3 = characteristics.find(ANDROID_STATISTICS_HOT_PIXEL_MAP); - - if ((entry3.count % 2) != 0) { - ALOGE("%s: Hot pixel map contains odd number of values, cannot map to pairs!", - __FUNCTION__); - jniThrowRuntimeException(env, "failed to add hotpixel map."); - return nullptr; - } + if ((entry3.count % 2) != 0) { + ALOGE("%s: Hot pixel map contains odd number of values, cannot map to pairs!", + __FUNCTION__); + jniThrowRuntimeException(env, "failed to add hotpixel map."); + return nullptr; + } - // Adjust the bad pixel coordinates to be relative to the origin of the active area DNG tag - std::vector<uint32_t> v; - for (size_t i = 0; i < entry3.count; i += 2) { - int32_t x = entry3.data.i32[i]; - int32_t y = entry3.data.i32[i + 1]; - x -= static_cast<int32_t>(xmin); - y -= static_cast<int32_t>(ymin); - if (x < 0 || y < 0 || static_cast<uint32_t>(x) >= width || - static_cast<uint32_t>(y) >= height) { - continue; + // Adjust the bad pixel coordinates to be relative to the origin of the active area DNG tag + std::vector<uint32_t> v; + for (size_t i = 0; i < entry3.count; i += 2) { + int32_t x = entry3.data.i32[i]; + int32_t y = entry3.data.i32[i + 1]; + x -= static_cast<int32_t>(xmin); + y -= static_cast<int32_t>(ymin); + if (x < 0 || y < 0 || static_cast<uint32_t>(x) >= width || + static_cast<uint32_t>(y) >= height) { + continue; + } + v.push_back(x); + v.push_back(y); } - v.push_back(x); - v.push_back(y); - } - const uint32_t* badPixels = &v[0]; - uint32_t badPixelCount = v.size(); + const uint32_t* badPixels = &v[0]; + uint32_t badPixelCount = v.size(); - if (badPixelCount > 0) { - err = builder.addBadPixelListForMetadata(badPixels, badPixelCount, opcodeCfaLayout); + if (badPixelCount > 0) { + err = builder.addBadPixelListForMetadata(badPixels, badPixelCount, opcodeCfaLayout); - if (err != OK) { - ALOGE("%s: Could not add hotpixel map.", __FUNCTION__); - jniThrowRuntimeException(env, "failed to add hotpixel map."); - return nullptr; + if (err != OK) { + ALOGE("%s: Could not add hotpixel map.", __FUNCTION__); + jniThrowRuntimeException(env, "failed to add hotpixel map."); + return nullptr; + } } } @@ -1960,10 +1982,12 @@ static sp<TiffWriter> DngCreator_setup(JNIEnv* env, jobject thiz, uint32_t image tagsToMove.add(TAG_BLACKLEVELREPEATDIM); tagsToMove.add(TAG_SAMPLESPERPIXEL); tagsToMove.add(TAG_PLANARCONFIGURATION); - tagsToMove.add(TAG_CFAREPEATPATTERNDIM); - tagsToMove.add(TAG_CFAPATTERN); - tagsToMove.add(TAG_CFAPLANECOLOR); - tagsToMove.add(TAG_CFALAYOUT); + if (isBayer) { + tagsToMove.add(TAG_CFAREPEATPATTERNDIM); + tagsToMove.add(TAG_CFAPATTERN); + tagsToMove.add(TAG_CFAPLANECOLOR); + tagsToMove.add(TAG_CFALAYOUT); + } tagsToMove.add(TAG_XRESOLUTION); tagsToMove.add(TAG_YRESOLUTION); tagsToMove.add(TAG_RESOLUTIONUNIT); diff --git a/core/proto/android/providers/settings/global.proto b/core/proto/android/providers/settings/global.proto index 72892fa07381..7de8020c4d32 100644 --- a/core/proto/android/providers/settings/global.proto +++ b/core/proto/android/providers/settings/global.proto @@ -332,6 +332,18 @@ message GlobalSettingsProto { } optional Dropbox dropbox = 46; + message DynamicPowerSavings { + option (android.msg_privacy).dest = DEST_EXPLICIT; + + // When to auto disable interventions that were triggered due to + // {@link #DYNAMIC_POWER_SAVINGS_ENABLED}. Value is a percentage indicating + // a battery level. + optional SettingProto disable_threshold = 1 [ (android.privacy).dest = DEST_AUTOMATIC]; + // Whether dynamic power savings based behaviors should be running or not. + optional SettingProto enabled = 2 [ (android.privacy).dest = DEST_AUTOMATIC]; + } + optional DynamicPowerSavings dynamic_power_savings = 143; + message Emergency { option (android.msg_privacy).dest = DEST_EXPLICIT; @@ -491,6 +503,9 @@ message GlobalSettingsProto { // The max value for {@link #LOW_POWER_MODE_TRIGGER_LEVEL}. If this setting // is not set or the value is 0, the default max will be used. optional SettingProto trigger_level_max = 3 [ (android.privacy).dest = DEST_AUTOMATIC ]; + // Whether automatic battery saver mode is controlled via percentage, + // {@link #DYNAMIC_POWER_SAVINGS_ENABLED} or disabled. + optional SettingProto automatic_power_saver_mode = 4 [ (android.privacy).dest = DEST_AUTOMATIC]; } optional LowPowerMode low_power_mode = 70; @@ -972,5 +987,5 @@ message GlobalSettingsProto { // Please insert fields in alphabetical order and group them into messages // if possible (to avoid reaching the method limit). - // Next tag = 143; + // Next tag = 144; } diff --git a/core/proto/android/server/usagestatsservice.proto b/core/proto/android/server/usagestatsservice.proto index 941c81fbb8df..3d60a86d86c9 100644 --- a/core/proto/android/server/usagestatsservice.proto +++ b/core/proto/android/server/usagestatsservice.proto @@ -45,11 +45,15 @@ message IntervalStatsProto { optional string package = 1; // package_index contains the index + 1 of the package name in the string pool optional int32 package_index = 2; + // Time attributes stored as an offset of the IntervalStats's beginTime. optional int64 last_time_active_ms = 3; optional int64 total_time_active_ms = 4; optional int32 last_event = 5; optional int32 app_launch_count = 6; repeated ChooserAction chooser_actions = 7; + // Time attributes stored as an offset of the IntervalStats's beginTime. + optional int64 last_time_service_used_ms = 8; + optional int64 total_time_service_used_ms = 9; } // Stores the relevant information an IntervalStats will have about a Configuration @@ -86,6 +90,8 @@ message IntervalStatsProto { // stringpool contains all the package and class names used by UsageStats and Event // They will hold a number that is equal to the index + 1 of their string in the pool optional StringPool stringpool = 2; + optional int32 major_version = 3; + optional int32 minor_version = 4; // The following fields contain aggregated usage stats data optional CountAndTime interactive = 10; diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml index 68ec34229d48..a99b9421e3b3 100644 --- a/core/res/res/values/attrs.xml +++ b/core/res/res/values/attrs.xml @@ -2448,6 +2448,25 @@ <flag name="noExcludeDescendants" value="0x8" /> </attr> + <!-- Hints the Android System whether the view node associated with this View should be + use for content capture purposes. --> + <attr name="importantForContentCapture"> + <!-- Let the Android System use its heuristics to determine if the view is important for content capture. --> + <flag name="auto" value="0" /> + <!-- Hint the Android System that this view is important for content capture, + and its children (if any) will be traversed.. --> + <flag name="yes" value="0x1" /> + <!-- Hint the Android System that this view is *not* important for content capture, + but its children (if any) will be traversed.. --> + <flag name="no" value="0x2" /> + <!-- Hint the Android System that this view is important for content capture, + but its children (if any) will not be traversed. --> + <flag name="yesExcludeDescendants" value="0x4" /> + <!-- Hint the Android System that this view is *not* important for content capture, + and its children (if any) will not be traversed. --> + <flag name="noExcludeDescendants" value="0x8" /> + </attr> + <!-- Boolean that controls whether a view can take focus while in touch mode. If this is true for a view, that view can gain focus when clicked on, and can keep focus if another view is clicked on that doesn't have this attribute set to true. --> diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 6ae183b99942..26f3370f0dc5 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -3531,6 +3531,9 @@ <!-- Whether or not battery saver should be "sticky" when manually enabled. --> <bool name="config_batterySaverStickyBehaviourDisabled">false</bool> + <!-- Config flag to track default disable threshold for Dynamic power savings enabled battery saver. --> + <integer name="config_dynamicPowerSavingsDefaultDisableThreshold">80</integer> + <!-- Model of potentially misprovisioned devices. If none is specified in an overlay, an empty string is passed in. --> <string name="config_misprovisionedDeviceModel" translatable="false"></string> diff --git a/core/res/res/values/locale_config.xml b/core/res/res/values/locale_config.xml index 35eee6a3b175..d6c0a108cffa 100644 --- a/core/res/res/values/locale_config.xml +++ b/core/res/res/values/locale_config.xml @@ -23,80 +23,81 @@ <item>ak-GH</item> <!-- Akan (Ghana) --> <item>am-ET</item> <!-- Amharic (Ethiopia) --> <item>ar-AE</item> <!-- Arabic (United Arab Emirates) --> - <item>ar-AE-u-nu-latn</item> <!-- Arabic (United Arab Emirates,Western Digits) --> + <item>ar-AE-u-nu-latn</item> <!-- Arabic (United Arab Emirates, Western Digits) --> <item>ar-BH</item> <!-- Arabic (Bahrain) --> - <item>ar-BH-u-nu-latn</item> <!-- Arabic (Bahrain,Western Digits) --> + <item>ar-BH-u-nu-latn</item> <!-- Arabic (Bahrain, Western Digits) --> <item>ar-DJ</item> <!-- Arabic (Djibouti) --> - <item>ar-DJ-u-nu-latn</item> <!-- Arabic (Djibouti,Western Digits) --> + <item>ar-DJ-u-nu-latn</item> <!-- Arabic (Djibouti, Western Digits) --> <item>ar-DZ</item> <!-- Arabic (Algeria) --> - <item>ar-DZ-u-nu-arab</item> <!-- Arabic (Algeria,Arabic-Indic Digits) --> + <item>ar-DZ-u-nu-arab</item> <!-- Arabic (Algeria, Arabic-Indic Digits) --> <item>ar-EG</item> <!-- Arabic (Egypt) --> - <item>ar-EG-u-nu-latn</item> <!-- Arabic (Egypt,Western Digits) --> + <item>ar-EG-u-nu-latn</item> <!-- Arabic (Egypt, Western Digits) --> <item>ar-EH</item> <!-- Arabic (Western Sahara) --> - <item>ar-EH-u-nu-arab</item> <!-- Arabic (Western Sahara,Arabic-Indic Digits) --> + <item>ar-EH-u-nu-arab</item> <!-- Arabic (Western Sahara, Arabic-Indic Digits) --> <item>ar-ER</item> <!-- Arabic (Eritrea) --> - <item>ar-ER-u-nu-latn</item> <!-- Arabic (Eritrea,Western Digits) --> + <item>ar-ER-u-nu-latn</item> <!-- Arabic (Eritrea, Western Digits) --> <item>ar-IL</item> <!-- Arabic (Israel) --> - <item>ar-IL-u-nu-latn</item> <!-- Arabic (Israel,Western Digits) --> + <item>ar-IL-u-nu-latn</item> <!-- Arabic (Israel, Western Digits) --> <item>ar-IQ</item> <!-- Arabic (Iraq) --> - <item>ar-IQ-u-nu-latn</item> <!-- Arabic (Iraq,Western Digits) --> + <item>ar-IQ-u-nu-latn</item> <!-- Arabic (Iraq, Western Digits) --> <item>ar-JO</item> <!-- Arabic (Jordan) --> - <item>ar-JO-u-nu-latn</item> <!-- Arabic (Jordan,Western Digits) --> + <item>ar-JO-u-nu-latn</item> <!-- Arabic (Jordan, Western Digits) --> <item>ar-KM</item> <!-- Arabic (Comoros) --> - <item>ar-KM-u-nu-latn</item> <!-- Arabic (Comoros,Western Digits) --> + <item>ar-KM-u-nu-latn</item> <!-- Arabic (Comoros, Western Digits) --> <item>ar-KW</item> <!-- Arabic (Kuwait) --> - <item>ar-KW-u-nu-latn</item> <!-- Arabic (Kuwait,Western Digits) --> + <item>ar-KW-u-nu-latn</item> <!-- Arabic (Kuwait, Western Digits) --> <item>ar-LB</item> <!-- Arabic (Lebanon) --> - <item>ar-LB-u-nu-latn</item> <!-- Arabic (Lebanon,Western Digits) --> + <item>ar-LB-u-nu-latn</item> <!-- Arabic (Lebanon, Western Digits) --> <item>ar-LY</item> <!-- Arabic (Libya) --> - <item>ar-LY-u-nu-arab</item> <!-- Arabic (Libya,Arabic-Indic Digits) --> + <item>ar-LY-u-nu-arab</item> <!-- Arabic (Libya, Arabic-Indic Digits) --> <item>ar-MA</item> <!-- Arabic (Morocco) --> - <item>ar-MA-u-nu-arab</item> <!-- Arabic (Morocco,Arabic-Indic Digits) --> + <item>ar-MA-u-nu-arab</item> <!-- Arabic (Morocco, Arabic-Indic Digits) --> <item>ar-MR</item> <!-- Arabic (Mauritania) --> - <item>ar-MR-u-nu-latn</item> <!-- Arabic (Mauritania,Western Digits) --> + <item>ar-MR-u-nu-latn</item> <!-- Arabic (Mauritania, Western Digits) --> <item>ar-OM</item> <!-- Arabic (Oman) --> - <item>ar-OM-u-nu-latn</item> <!-- Arabic (Oman,Western Digits) --> + <item>ar-OM-u-nu-latn</item> <!-- Arabic (Oman, Western Digits) --> <item>ar-PS</item> <!-- Arabic (Palestine) --> - <item>ar-PS-u-nu-latn</item> <!-- Arabic (Palestine,Western Digits) --> + <item>ar-PS-u-nu-latn</item> <!-- Arabic (Palestine, Western Digits) --> <item>ar-QA</item> <!-- Arabic (Qatar) --> - <item>ar-QA-u-nu-latn</item> <!-- Arabic (Qatar,Western Digits) --> + <item>ar-QA-u-nu-latn</item> <!-- Arabic (Qatar, Western Digits) --> <item>ar-SA</item> <!-- Arabic (Saudi Arabia) --> - <item>ar-SA-u-nu-latn</item> <!-- Arabic (Saudi Arabia,Western Digits) --> + <item>ar-SA-u-nu-latn</item> <!-- Arabic (Saudi Arabia, Western Digits) --> <item>ar-SD</item> <!-- Arabic (Sudan) --> - <item>ar-SD-u-nu-latn</item> <!-- Arabic (Sudan,Western Digits) --> + <item>ar-SD-u-nu-latn</item> <!-- Arabic (Sudan, Western Digits) --> <item>ar-SO</item> <!-- Arabic (Somalia) --> - <item>ar-SO-u-nu-latn</item> <!-- Arabic (Somalia,Western Digits) --> + <item>ar-SO-u-nu-latn</item> <!-- Arabic (Somalia, Western Digits) --> <item>ar-SS</item> <!-- Arabic (South Sudan) --> - <item>ar-SS-u-nu-latn</item> <!-- Arabic (South Sudan,Western Digits) --> + <item>ar-SS-u-nu-latn</item> <!-- Arabic (South Sudan, Western Digits) --> <item>ar-SY</item> <!-- Arabic (Syria) --> - <item>ar-SY-u-nu-latn</item> <!-- Arabic (Syria,Western Digits) --> + <item>ar-SY-u-nu-latn</item> <!-- Arabic (Syria, Western Digits) --> <item>ar-TD</item> <!-- Arabic (Chad) --> - <item>ar-TD-u-nu-latn</item> <!-- Arabic (Chad,Western Digits) --> + <item>ar-TD-u-nu-latn</item> <!-- Arabic (Chad, Western Digits) --> <item>ar-TN</item> <!-- Arabic (Tunisia) --> - <item>ar-TN-u-nu-arab</item> <!-- Arabic (Tunisia,Arabic-Indic Digits) --> + <item>ar-TN-u-nu-arab</item> <!-- Arabic (Tunisia, Arabic-Indic Digits) --> <item>ar-XB</item> <!-- Right-to-left pseudolocale --> <item>ar-YE</item> <!-- Arabic (Yemen) --> - <item>ar-YE-u-nu-latn</item> <!-- Arabic (Yemen,Western Digits) --> + <item>ar-YE-u-nu-latn</item> <!-- Arabic (Yemen, Western Digits) --> <item>as-IN</item> <!-- Assamese (India) --> <item>asa-TZ</item> <!-- Asu (Tanzania) --> - <item>az-Cyrl-AZ</item> <!-- Azerbaijani (Cyrillic,Azerbaijan) --> - <item>az-Latn-AZ</item> <!-- Azerbaijani (Latin,Azerbaijan) --> + <item>ast-ES</item> <!-- Asturian (Spain) --> + <item>az-Cyrl-AZ</item> <!-- Azerbaijani (Cyrillic, Azerbaijan) --> + <item>az-Latn-AZ</item> <!-- Azerbaijani (Latin, Azerbaijan) --> <item>bas-CM</item> <!-- Basaa (Cameroon) --> <item>be-BY</item> <!-- Belarusian (Belarus) --> <item>bem-ZM</item> <!-- Bemba (Zambia) --> <item>bez-TZ</item> <!-- Bena (Tanzania) --> <item>bg-BG</item> <!-- Bulgarian (Bulgaria) --> <item>bm-ML</item> <!-- Bambara (Mali) --> - <item>bn-BD</item> <!-- Bengali (Bangladesh) --> - <item>bn-BD-u-nu-latn</item> <!-- Bengali (Bangladesh,Western Digits) --> - <item>bn-IN</item> <!-- Bengali (India) --> - <item>bn-IN-u-nu-latn</item> <!-- Bengali (India,Western Digits) --> + <item>bn-BD</item> <!-- Bangla (Bangladesh) --> + <item>bn-BD-u-nu-latn</item> <!-- Bangla (Bangladesh, Western Digits) --> + <item>bn-IN</item> <!-- Bangla (India) --> + <item>bn-IN-u-nu-latn</item> <!-- Bangla (India, Western Digits) --> <item>bo-CN</item> <!-- Tibetan (China) --> <item>bo-IN</item> <!-- Tibetan (India) --> <item>br-FR</item> <!-- Breton (France) --> <item>brx-IN</item> <!-- Bodo (India) --> - <item>bs-Cyrl-BA</item> <!-- Bosnian (Cyrillic,Bosnia & Herzegovina) --> - <item>bs-Latn-BA</item> <!-- Bosnian (Latin,Bosnia & Herzegovina) --> + <item>bs-Cyrl-BA</item> <!-- Bosnian (Cyrillic, Bosnia & Herzegovina) --> + <item>bs-Latn-BA</item> <!-- Bosnian (Latin, Bosnia & Herzegovina) --> <item>ca-AD</item> <!-- Catalan (Andorra) --> <item>ca-ES</item> <!-- Catalan (Spain) --> <item>ca-FR</item> <!-- Catalan (France) --> @@ -113,6 +114,7 @@ <item>de-BE</item> <!-- German (Belgium) --> <item>de-CH</item> <!-- German (Switzerland) --> <item>de-DE</item> <!-- German (Germany) --> + <item>de-IT</item> <!-- German (Italy) --> <item>de-LI</item> <!-- German (Liechtenstein) --> <item>de-LU</item> <!-- German (Luxembourg) --> <item>dje-NE</item> <!-- Zarma (Niger) --> @@ -230,6 +232,8 @@ <item>en-ZW</item> <!-- English (Zimbabwe) --> <item>es-AR</item> <!-- Spanish (Argentina) --> <item>es-BO</item> <!-- Spanish (Bolivia) --> + <item>es-BR</item> <!-- Spanish (Brazil) --> + <item>es-BZ</item> <!-- Spanish (Belize) --> <item>es-CL</item> <!-- Spanish (Chile) --> <item>es-CO</item> <!-- Spanish (Colombia) --> <item>es-CR</item> <!-- Spanish (Costa Rica) --> @@ -257,9 +261,9 @@ <item>eu-ES</item> <!-- Basque (Spain) --> <item>ewo-CM</item> <!-- Ewondo (Cameroon) --> <item>fa-AF</item> <!-- Persian (Afghanistan) --> - <item>fa-AF-u-nu-latn</item> <!-- Persian (Afghanistan,Western Digits) --> + <item>fa-AF-u-nu-latn</item> <!-- Persian (Afghanistan, Western Digits) --> <item>fa-IR</item> <!-- Persian (Iran) --> - <item>fa-IR-u-nu-latn</item> <!-- Persian (Iran,Western Digits) --> + <item>fa-IR-u-nu-latn</item> <!-- Persian (Iran, Western Digits) --> <item>ff-CM</item> <!-- Fulah (Cameroon) --> <item>ff-GN</item> <!-- Fulah (Guinea) --> <item>ff-MR</item> <!-- Fulah (Mauritania) --> @@ -274,9 +278,9 @@ <item>fr-BJ</item> <!-- French (Benin) --> <item>fr-BL</item> <!-- French (St. Barthélemy) --> <item>fr-CA</item> <!-- French (Canada) --> - <item>fr-CD</item> <!-- French (Congo (DRC)) --> + <item>fr-CD</item> <!-- French (Congo - Kinshasa) --> <item>fr-CF</item> <!-- French (Central African Republic) --> - <item>fr-CG</item> <!-- French (Congo (Republic)) --> + <item>fr-CG</item> <!-- French (Congo - Brazzaville) --> <item>fr-CH</item> <!-- French (Switzerland) --> <item>fr-CI</item> <!-- French (Côte d’Ivoire) --> <item>fr-CM</item> <!-- French (Cameroon) --> @@ -329,20 +333,20 @@ <item>ha-NE</item> <!-- Hausa (Niger) --> <item>ha-NG</item> <!-- Hausa (Nigeria) --> <item>haw-US</item> <!-- Hawaiian (United States) --> - <item>iw-IL</item> <!-- Hebrew (Israel) --> <item>hi-IN</item> <!-- Hindi (India) --> <item>hr-BA</item> <!-- Croatian (Bosnia & Herzegovina) --> <item>hr-HR</item> <!-- Croatian (Croatia) --> <item>hsb-DE</item> <!-- Upper Sorbian (Germany) --> <item>hu-HU</item> <!-- Hungarian (Hungary) --> <item>hy-AM</item> <!-- Armenian (Armenia) --> - <item>in-ID</item> <!-- Indonesian (Indonesia) --> <item>ig-NG</item> <!-- Igbo (Nigeria) --> <item>ii-CN</item> <!-- Sichuan Yi (China) --> + <item>in-ID</item> <!-- Indonesian (Indonesia) --> <item>is-IS</item> <!-- Icelandic (Iceland) --> <item>it-CH</item> <!-- Italian (Switzerland) --> <item>it-IT</item> <!-- Italian (Italy) --> <item>it-SM</item> <!-- Italian (San Marino) --> + <item>iw-IL</item> <!-- Hebrew (Israel) --> <item>ja-JP</item> <!-- Japanese (Japan) --> <item>jgo-CM</item> <!-- Ngomba (Cameroon) --> <item>jmc-TZ</item> <!-- Machame (Tanzania) --> @@ -372,12 +376,12 @@ <item>lg-UG</item> <!-- Ganda (Uganda) --> <item>lkt-US</item> <!-- Lakota (United States) --> <item>ln-AO</item> <!-- Lingala (Angola) --> - <item>ln-CD</item> <!-- Lingala (Congo (DRC)) --> + <item>ln-CD</item> <!-- Lingala (Congo - Kinshasa) --> <item>ln-CF</item> <!-- Lingala (Central African Republic) --> - <item>ln-CG</item> <!-- Lingala (Congo (Republic)) --> + <item>ln-CG</item> <!-- Lingala (Congo - Brazzaville) --> <item>lo-LA</item> <!-- Lao (Laos) --> <item>lt-LT</item> <!-- Lithuanian (Lithuania) --> - <item>lu-CD</item> <!-- Luba-Katanga (Congo (DRC)) --> + <item>lu-CD</item> <!-- Luba-Katanga (Congo - Kinshasa) --> <item>luo-KE</item> <!-- Luo (Kenya) --> <item>luy-KE</item> <!-- Luyia (Kenya) --> <item>lv-LV</item> <!-- Latvian (Latvia) --> @@ -418,11 +422,11 @@ <item>nyn-UG</item> <!-- Nyankole (Uganda) --> <item>om-ET</item> <!-- Oromo (Ethiopia) --> <item>om-KE</item> <!-- Oromo (Kenya) --> - <item>or-IN</item> <!-- Oriya (India) --> + <item>or-IN</item> <!-- Odia (India) --> <item>os-GE</item> <!-- Ossetic (Georgia) --> <item>os-RU</item> <!-- Ossetic (Russia) --> - <item>pa-Arab-PK</item> <!-- Punjabi (Arabic,Pakistan) --> - <item>pa-Guru-IN</item> <!-- Punjabi (Gurmukhi,India) --> + <item>pa-Arab-PK</item> <!-- Punjabi (Arabic, Pakistan) --> + <item>pa-Guru-IN</item> <!-- Punjabi (Gurmukhi, India) --> <item>pl-PL</item> <!-- Polish (Poland) --> <item>ps-AF</item> <!-- Pashto (Afghanistan) --> <item>pt-AO</item> <!-- Portuguese (Angola) --> @@ -471,18 +475,18 @@ <item>sq-AL</item> <!-- Albanian (Albania) --> <item>sq-MK</item> <!-- Albanian (Macedonia (FYROM)) --> <item>sq-XK</item> <!-- Albanian (Kosovo) --> - <item>sr-Cyrl-BA</item> <!-- Serbian (Cyrillic,Bosnia & Herzegovina) --> - <item>sr-Cyrl-ME</item> <!-- Serbian (Cyrillic,Montenegro) --> - <item>sr-Cyrl-RS</item> <!-- Serbian (Cyrillic,Serbia) --> - <item>sr-Cyrl-XK</item> <!-- Serbian (Cyrillic,Kosovo) --> - <item>sr-Latn-BA</item> <!-- Serbian (Latin,Bosnia & Herzegovina) --> - <item>sr-Latn-ME</item> <!-- Serbian (Latin,Montenegro) --> - <item>sr-Latn-RS</item> <!-- Serbian (Latin,Serbia) --> - <item>sr-Latn-XK</item> <!-- Serbian (Latin,Kosovo) --> + <item>sr-Cyrl-BA</item> <!-- Serbian (Cyrillic, Bosnia & Herzegovina) --> + <item>sr-Cyrl-ME</item> <!-- Serbian (Cyrillic, Montenegro) --> + <item>sr-Cyrl-RS</item> <!-- Serbian (Cyrillic, Serbia) --> + <item>sr-Cyrl-XK</item> <!-- Serbian (Cyrillic, Kosovo) --> + <item>sr-Latn-BA</item> <!-- Serbian (Latin, Bosnia & Herzegovina) --> + <item>sr-Latn-ME</item> <!-- Serbian (Latin, Montenegro) --> + <item>sr-Latn-RS</item> <!-- Serbian (Latin, Serbia) --> + <item>sr-Latn-XK</item> <!-- Serbian (Latin, Kosovo) --> <item>sv-AX</item> <!-- Swedish (Åland Islands) --> <item>sv-FI</item> <!-- Swedish (Finland) --> <item>sv-SE</item> <!-- Swedish (Sweden) --> - <item>sw-CD</item> <!-- Swahili (Congo (DRC)) --> + <item>sw-CD</item> <!-- Swahili (Congo - Kinshasa) --> <item>sw-KE</item> <!-- Swahili (Kenya) --> <item>sw-TZ</item> <!-- Swahili (Tanzania) --> <item>sw-UG</item> <!-- Swahili (Uganda) --> @@ -502,12 +506,12 @@ <item>ug-CN</item> <!-- Uyghur (China) --> <item>uk-UA</item> <!-- Ukrainian (Ukraine) --> <item>ur-IN</item> <!-- Urdu (India) --> - <item>ur-IN-u-nu-latn</item> <!-- Urdu (India,Western Digits) --> + <item>ur-IN-u-nu-latn</item> <!-- Urdu (India, Western Digits) --> <item>ur-PK</item> <!-- Urdu (Pakistan) --> - <item>ur-PK-u-nu-arabext</item> <!-- Urdu (Pakistan,Extended Arabic-Indic Digits) --> - <item>uz-Arab-AF</item> <!-- Uzbek (Arabic,Afghanistan) --> - <item>uz-Cyrl-UZ</item> <!-- Uzbek (Cyrillic,Uzbekistan) --> - <item>uz-Latn-UZ</item> <!-- Uzbek (Latin,Uzbekistan) --> + <item>ur-PK-u-nu-arabext</item> <!-- Urdu (Pakistan, Extended Arabic-Indic Digits) --> + <item>uz-Arab-AF</item> <!-- Uzbek (Arabic, Afghanistan) --> + <item>uz-Cyrl-UZ</item> <!-- Uzbek (Cyrillic, Uzbekistan) --> + <item>uz-Latn-UZ</item> <!-- Uzbek (Latin, Uzbekistan) --> <item>vi-VN</item> <!-- Vietnamese (Vietnam) --> <item>vun-TZ</item> <!-- Vunjo (Tanzania) --> <item>wae-CH</item> <!-- Walser (Switzerland) --> @@ -515,15 +519,16 @@ <item>yav-CM</item> <!-- Yangben (Cameroon) --> <item>yo-BJ</item> <!-- Yoruba (Benin) --> <item>yo-NG</item> <!-- Yoruba (Nigeria) --> - <item>yue-HK</item> <!-- Cantonese (Hong Kong) --> + <item>yue-Hans-CN</item> <!-- Cantonese (Simplified, China) --> + <item>yue-Hant-HK</item> <!-- Cantonese (Traditional, Hong Kong) --> <item>zgh-MA</item> <!-- Standard Moroccan Tamazight (Morocco) --> - <item>zh-Hans-CN</item> <!-- Chinese (Simplified Han,China) --> - <item>zh-Hans-HK</item> <!-- Chinese (Simplified Han,Hong Kong) --> - <item>zh-Hans-MO</item> <!-- Chinese (Simplified Han,Macau) --> - <item>zh-Hans-SG</item> <!-- Chinese (Simplified Han,Singapore) --> - <item>zh-Hant-HK</item> <!-- Chinese (Traditional Han,Hong Kong) --> - <item>zh-Hant-MO</item> <!-- Chinese (Traditional Han,Macau) --> - <item>zh-Hant-TW</item> <!-- Chinese (Traditional Han,Taiwan) --> + <item>zh-Hans-CN</item> <!-- Chinese (Simplified, China) --> + <item>zh-Hans-HK</item> <!-- Chinese (Simplified, Hong Kong) --> + <item>zh-Hans-MO</item> <!-- Chinese (Simplified, Macau) --> + <item>zh-Hans-SG</item> <!-- Chinese (Simplified, Singapore) --> + <item>zh-Hant-HK</item> <!-- Chinese (Traditional, Hong Kong) --> + <item>zh-Hant-MO</item> <!-- Chinese (Traditional, Macau) --> + <item>zh-Hant-TW</item> <!-- Chinese (Traditional, Taiwan) --> <item>zu-ZA</item> <!-- Zulu (South Africa) --> </string-array> diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index 86879c30553f..73dae0801b8e 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -2919,6 +2919,7 @@ <public name="settingsSliceUri" /> <public name="shell" /> <public name="interactiveUiTimeout" /> + <public name="importantForContentCapture" /> </public-group> <public-group type="drawable" first-id="0x010800b4"> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 6276884801a4..4eb723eb973d 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -3436,6 +3436,7 @@ <java-symbol type="integer" name="config_lowBatteryAutoTriggerDefaultLevel" /> <java-symbol type="bool" name="config_batterySaverStickyBehaviourDisabled" /> + <java-symbol type="integer" name="config_dynamicPowerSavingsDefaultDisableThreshold" /> <!-- For car devices --> <java-symbol type="string" name="car_loading_profile" /> diff --git a/core/tests/coretests/src/android/app/usage/UsageStatsTest.java b/core/tests/coretests/src/android/app/usage/UsageStatsTest.java index c6d077dee18f..1f047f9e6d10 100644 --- a/core/tests/coretests/src/android/app/usage/UsageStatsTest.java +++ b/core/tests/coretests/src/android/app/usage/UsageStatsTest.java @@ -16,8 +16,19 @@ package android.app.usage; -import static com.google.common.truth.Truth.assertThat; +import static android.app.usage.UsageEvents.Event.CONTINUE_PREVIOUS_DAY; +import static android.app.usage.UsageEvents.Event.CONTINUING_FOREGROUND_SERVICE; +import static android.app.usage.UsageEvents.Event.END_OF_DAY; +import static android.app.usage.UsageEvents.Event.FOREGROUND_SERVICE_START; +import static android.app.usage.UsageEvents.Event.FOREGROUND_SERVICE_STOP; +import static android.app.usage.UsageEvents.Event.MOVE_TO_BACKGROUND; +import static android.app.usage.UsageEvents.Event.MOVE_TO_FOREGROUND; +import static android.app.usage.UsageEvents.Event.ROLLOVER_FOREGROUND_SERVICE; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; + +import android.os.Parcel; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; @@ -46,7 +57,7 @@ public class UsageStatsTest { left.add(right); - assertThat(left.getFirstTimeStamp()).isEqualTo(99999); + assertEquals(left.getFirstTimeStamp(), 99999); } @Test @@ -58,7 +69,7 @@ public class UsageStatsTest { left.add(right); - assertThat(left.getLastTimeStamp()).isEqualTo(100001); + assertEquals(left.getLastTimeStamp(), 100001); } @Test @@ -72,7 +83,7 @@ public class UsageStatsTest { left.add(right); - assertThat(left.getLastTimeUsed()).isEqualTo(200001); + assertEquals(left.getLastTimeUsed(), 200001); } @Test @@ -86,7 +97,7 @@ public class UsageStatsTest { left.add(right); - assertThat(left.getLastTimeUsed()).isEqualTo(200000); + assertEquals(left.getLastTimeUsed(), 200000); } @Test @@ -100,6 +111,373 @@ public class UsageStatsTest { left.add(right); - assertThat(left.getTotalTimeInForeground()).isEqualTo(11); + assertEquals(left.getTotalTimeInForeground(), 11); + } + + @Test + public void testParcelable() { + left.mPackageName = "com.test"; + left.mBeginTimeStamp = 100000; + left.mTotalTimeInForeground = 10; + + left.mLastForegroundActivityEventMap.put("com.test.activity1", MOVE_TO_FOREGROUND); + left.mLastForegroundActivityEventMap.put("com.test.activity2", MOVE_TO_FOREGROUND); + left.mLastForegroundServiceEventMap.put("com.test.service1", FOREGROUND_SERVICE_START); + left.mLastForegroundServiceEventMap.put("com.test.service2", FOREGROUND_SERVICE_START); + + Parcel p = Parcel.obtain(); + left.writeToParcel(p, 0); + p.setDataPosition(0); + right = UsageStats.CREATOR.createFromParcel(p); + compareUsageStats(left, right); + } + + @Test + public void testForegroundActivity() { + left.mPackageName = "com.test"; + left.mBeginTimeStamp = 100000; + + left.update("com.test.activity1", 200000, MOVE_TO_FOREGROUND); + assertEquals(left.mLastTimeUsed, 200000); + assertEquals(left.mLastForegroundActivityEventMap.get("com.test.activity1"), + new Integer(MOVE_TO_FOREGROUND)); + assertEquals(left.mLaunchCount, 1); + + left.update("com.test.activity1", 350000, MOVE_TO_BACKGROUND); + assertEquals(left.mLastTimeUsed, 350000); + assertFalse(left.mLastForegroundActivityEventMap.containsKey("com.test.activity1")); + assertEquals(left.mTotalTimeInForeground, 350000 - 200000); + } + + @Test + public void testEvent_CONTINUE_PREVIOUS_DAY() { + left.mPackageName = "com.test"; + left.mBeginTimeStamp = 100000; + + left.update("com.test.activity1", 100000, CONTINUE_PREVIOUS_DAY); + assertEquals(left.mLastTimeUsed, 100000); + assertEquals(left.mLastForegroundActivityEventMap.get("com.test.activity1"), + new Integer(CONTINUE_PREVIOUS_DAY)); + assertEquals(left.mLaunchCount, 0); + + left.update("com.test.activity1", 350000, MOVE_TO_BACKGROUND); + assertEquals(left.mLastTimeUsed, 350000); + assertEquals(left.mLastForegroundActivityEventMap.get("com.test.activity1"), null); + assertEquals(left.mTotalTimeInForeground, 350000 - 100000); + } + + @Test + public void testEvent_END_OF_DAY() { + left.mPackageName = "com.test"; + left.mBeginTimeStamp = 100000; + + left.update("com.test.activity1", 100000, CONTINUE_PREVIOUS_DAY); + assertEquals(left.mLastTimeUsed, 100000); + assertEquals(left.mLastForegroundActivityEventMap.get("com.test.activity1"), + new Integer(CONTINUE_PREVIOUS_DAY)); + assertEquals(left.mLaunchCount, 0); + + left.update(null, 350000, END_OF_DAY); + assertEquals(left.mLastTimeUsed, 350000); + assertEquals(left.mLastForegroundActivityEventMap.get("com.test.activity1"), + new Integer(END_OF_DAY)); + assertEquals(left.mTotalTimeInForeground, 350000 - 100000); + } + + @Test + public void testForegroundActivityEventSequence() { + left.mPackageName = "com.test"; + left.mBeginTimeStamp = 100000; + + left.update("com.test.activity1", 100000, CONTINUE_PREVIOUS_DAY); + assertEquals(left.mLastTimeUsed, 100000); + assertEquals(left.mLastForegroundActivityEventMap.get("com.test.activity1"), + new Integer(CONTINUE_PREVIOUS_DAY)); + assertEquals(left.mLaunchCount, 0); + + left.update("com.test.activity1", 350000, MOVE_TO_BACKGROUND); + assertEquals(left.mLastTimeUsed, 350000); + assertEquals(left.mLastForegroundActivityEventMap.get("com.test.activity1"), null); + assertEquals(left.mTotalTimeInForeground, 250000 /*350000 - 100000*/); + + left.update("com.test.activity1", 450000, MOVE_TO_FOREGROUND); + assertEquals(left.mLastTimeUsed, 450000); + assertEquals(left.mLastForegroundActivityEventMap.get("com.test.activity1"), + new Integer(MOVE_TO_FOREGROUND)); + assertEquals(left.mTotalTimeInForeground, 250000); + + left.update("com.test.activity1", 500000, MOVE_TO_BACKGROUND); + assertEquals(left.mLastTimeUsed, 500000); + assertEquals(left.mLastForegroundActivityEventMap.get("com.test.activity1"), null); + assertEquals(left.mTotalTimeInForeground, 250000 + 50000 /*500000 - 450000*/); + } + + @Test + public void testForegroundActivityEventOutOfSequence() { + left.mPackageName = "com.test"; + left.mBeginTimeStamp = 100000; + + left.update("com.test.activity1", 100000, CONTINUE_PREVIOUS_DAY); + assertEquals(left.mLastTimeUsed, 100000); + assertEquals(left.mLastForegroundActivityEventMap.get("com.test.activity1"), + new Integer(CONTINUE_PREVIOUS_DAY)); + assertEquals(left.mLaunchCount, 0); + + left.update("com.test.activity1", 150000, MOVE_TO_FOREGROUND); + assertEquals(left.mLastTimeUsed, 150000); + assertEquals(left.mLastForegroundActivityEventMap.get("com.test.activity1"), + new Integer(MOVE_TO_FOREGROUND)); + assertEquals(left.mLaunchCount, 1); + assertEquals(left.mTotalTimeInForeground, 50000 /*150000 - 100000*/); + + left.update("com.test.activity1", 200000, MOVE_TO_FOREGROUND); + assertEquals(left.mLastTimeUsed, 200000); + assertEquals(left.mLastForegroundActivityEventMap.get("com.test.activity1"), + new Integer(MOVE_TO_FOREGROUND)); + assertEquals(left.mLaunchCount, 2); + assertEquals(left.mTotalTimeInForeground, 100000); + + left.update("com.test.activity1", 250000, MOVE_TO_BACKGROUND); + assertEquals(left.mLastTimeUsed, 250000); + assertEquals(left.mLastForegroundActivityEventMap.get("com.test.activity1"), null); + assertEquals(left.mTotalTimeInForeground, 150000); + + left.update("com.test.activity1", 300000, MOVE_TO_BACKGROUND); + assertEquals(left.mLastTimeUsed, 250000); + assertEquals(left.mLastForegroundActivityEventMap.get("com.test.activity1"), null); + assertEquals(left.mTotalTimeInForeground, 150000); + + left.update("com.test.activity1", 350000, MOVE_TO_FOREGROUND); + assertEquals(left.mLastTimeUsed, 350000); + assertEquals(left.mLastForegroundActivityEventMap.get("com.test.activity1"), + new Integer(MOVE_TO_FOREGROUND)); + assertEquals(left.mTotalTimeInForeground, 150000); + + left.update("com.test.activity1", 400000, END_OF_DAY); + assertEquals(left.mLastTimeUsed, 400000); + assertEquals(left.mLastForegroundActivityEventMap.get("com.test.activity1"), + new Integer(END_OF_DAY)); + assertEquals(left.mTotalTimeInForeground, 200000); + } + + @Test + public void testTwoActivityEventSequence() { + left.mPackageName = "com.test"; + left.mBeginTimeStamp = 100000; + + left.update("com.test.activity1", 100000, CONTINUE_PREVIOUS_DAY); + left.update("com.test.activity2", 100000, CONTINUE_PREVIOUS_DAY); + assertEquals(left.mLastTimeUsed, 100000); + assertEquals(left.mLastForegroundActivityEventMap.get("com.test.activity1"), + new Integer(CONTINUE_PREVIOUS_DAY)); + assertEquals(left.mLastForegroundActivityEventMap.get("com.test.activity2"), + new Integer(CONTINUE_PREVIOUS_DAY)); + assertEquals(left.mLaunchCount, 0); + + left.update("com.test.activity1", 350000, MOVE_TO_BACKGROUND); + assertEquals(left.mLastTimeUsed, 350000); + assertEquals(left.mLastForegroundActivityEventMap.get("com.test.activity1"), null); + assertEquals(left.mTotalTimeInForeground, 250000 /*350000 - 100000*/); + + left.update("com.test.activity2", 450000, MOVE_TO_BACKGROUND); + assertEquals(left.mLastTimeUsed, 450000); + assertEquals(left.mLastForegroundActivityEventMap.get("com.test.activity2"), null); + assertEquals(left.mTotalTimeInForeground, 250000 + 100000 /*450000 - 350000*/); + + left.update(null, 500000, END_OF_DAY); + assertEquals(left.mLastTimeUsed, 450000); + assertEquals(left.mTotalTimeInForeground, 350000); + } + + @Test + public void testForegroundService() { + left.mPackageName = "com.test"; + left.mBeginTimeStamp = 100000; + + left.update("com.test.service1", 200000, FOREGROUND_SERVICE_START); + assertEquals(left.mLastTimeForegroundServiceUsed, 200000); + assertEquals(left.mLastForegroundServiceEventMap.get("com.test.service1"), + new Integer(FOREGROUND_SERVICE_START)); + assertEquals(left.mLaunchCount, 0); + + left.update("com.test.service1", 350000, FOREGROUND_SERVICE_STOP); + assertEquals(left.mLastTimeForegroundServiceUsed, 350000); + assertEquals(left.mLastForegroundServiceEventMap.get("com.test.service1"), null); + assertEquals(left.mTotalTimeForegroundServiceUsed, 350000 - 200000); + } + + @Test + public void testEvent_CONTINUING_FOREGROUND_SERVICE() { + left.mPackageName = "com.test"; + left.mBeginTimeStamp = 100000; + + left.update("com.test.service1", 100000, CONTINUING_FOREGROUND_SERVICE); + assertEquals(left.mLastTimeForegroundServiceUsed, 100000); + assertEquals(left.mLastForegroundServiceEventMap.get("com.test.service1"), + new Integer(CONTINUING_FOREGROUND_SERVICE)); + assertEquals(left.mLaunchCount, 0); + + left.update("com.test.service1", 350000, FOREGROUND_SERVICE_STOP); + assertEquals(left.mLastTimeForegroundServiceUsed, 350000); + assertEquals(left.mLastForegroundServiceEventMap.get("com.test.service1"), null); + assertEquals(left.mTotalTimeForegroundServiceUsed, 350000 - 100000); + } + + @Test + public void testEvent_ROLLOVER_FOREGROUND_SERVICE() { + left.mPackageName = "com.test"; + left.mBeginTimeStamp = 100000; + + left.update("com.test.service1", 100000, + CONTINUING_FOREGROUND_SERVICE); + assertEquals(left.mLastTimeForegroundServiceUsed, 100000); + assertEquals(left.mLastForegroundServiceEventMap.get("com.test.service1"), + new Integer(CONTINUING_FOREGROUND_SERVICE)); + assertEquals(left.mLaunchCount, 0); + + left.update(null, 350000, ROLLOVER_FOREGROUND_SERVICE); + assertEquals(left.mLastTimeForegroundServiceUsed, 350000); + assertEquals(left.mLastForegroundServiceEventMap.get("com.test.service1"), + new Integer(ROLLOVER_FOREGROUND_SERVICE)); + assertEquals(left.mTotalTimeForegroundServiceUsed, 350000 - 100000); + } + + @Test + public void testForegroundServiceEventSequence() { + left.mPackageName = "com.test"; + left.mBeginTimeStamp = 100000; + + left.update("com.test.service1", 100000, + CONTINUING_FOREGROUND_SERVICE); + assertEquals(left.mLastTimeForegroundServiceUsed, 100000); + assertEquals(left.mLastForegroundServiceEventMap.get("com.test.service1"), + new Integer(CONTINUING_FOREGROUND_SERVICE)); + assertEquals(left.mLaunchCount, 0); + + left.update("com.test.service1", 350000, FOREGROUND_SERVICE_STOP); + assertEquals(left.mLastTimeForegroundServiceUsed, 350000); + assertEquals(left.mLastForegroundServiceEventMap.get("com.test.service1"), null); + assertEquals(left.mTotalTimeForegroundServiceUsed, 250000 /*350000 - 100000*/); + + left.update("com.test.service1", 450000, FOREGROUND_SERVICE_START); + assertEquals(left.mLastTimeForegroundServiceUsed, 450000); + assertEquals(left.mLastForegroundServiceEventMap.get("com.test.service1"), + new Integer(FOREGROUND_SERVICE_START)); + assertEquals(left.mTotalTimeForegroundServiceUsed, 250000); + + left.update("com.test.service1", 500000, FOREGROUND_SERVICE_STOP); + assertEquals(left.mLastTimeForegroundServiceUsed, 500000); + assertEquals(left.mLastForegroundServiceEventMap.get("com.test.service1"), null); + assertEquals(left.mTotalTimeForegroundServiceUsed, 250000 + 50000 /*500000 - 450000*/); + } + + @Test + public void testTwoServiceEventSequence() { + left.mPackageName = "com.test"; + left.mBeginTimeStamp = 100000; + + left.update("com.test.service1", 100000, + CONTINUING_FOREGROUND_SERVICE); + left.update("com.test.service2", 100000, + CONTINUING_FOREGROUND_SERVICE); + assertEquals(left.mLastTimeForegroundServiceUsed, 100000); + assertEquals(left.mLastForegroundServiceEventMap.get("com.test.service1"), + new Integer(CONTINUING_FOREGROUND_SERVICE)); + assertEquals(left.mLastForegroundServiceEventMap.get("com.test.service2"), + new Integer(CONTINUING_FOREGROUND_SERVICE)); + assertEquals(left.mLaunchCount, 0); + + left.update("com.test.service1", 350000, FOREGROUND_SERVICE_STOP); + assertEquals(left.mLastTimeForegroundServiceUsed, 350000); + assertEquals(left.mLastForegroundServiceEventMap.get("com.test.service1"), null); + assertEquals(left.mTotalTimeForegroundServiceUsed, 250000 /*350000 - 100000*/); + + left.update("com.test.service2", 450000, FOREGROUND_SERVICE_STOP); + assertEquals(left.mLastTimeForegroundServiceUsed, 450000); + assertEquals(left.mLastForegroundServiceEventMap.get("com.test.service2"), null); + assertEquals(left.mTotalTimeForegroundServiceUsed, 250000 + 100000 /*450000 - 350000*/); + + left.update(null, 500000, ROLLOVER_FOREGROUND_SERVICE); + assertEquals(left.mLastTimeForegroundServiceUsed, 450000); + assertEquals(left.mTotalTimeForegroundServiceUsed, 350000); + } + + @Test + public void testTwoActivityAndTwoServiceEventSequence() { + left.mPackageName = "com.test"; + left.mBeginTimeStamp = 100000; + + left.update("com.test.activity1", 100000, CONTINUE_PREVIOUS_DAY); + left.update("com.test.activity2", 100000, CONTINUE_PREVIOUS_DAY); + left.update("com.test.service1", 100000, + CONTINUING_FOREGROUND_SERVICE); + left.update("com.test.service2", 100000, + CONTINUING_FOREGROUND_SERVICE); + assertEquals(left.mLastTimeUsed, 100000); + assertEquals(left.mLastTimeForegroundServiceUsed, 100000); + assertEquals(left.mLastForegroundActivityEventMap.get("com.test.activity1"), + new Integer(CONTINUE_PREVIOUS_DAY)); + assertEquals(left.mLastForegroundActivityEventMap.get("com.test.activity2"), + new Integer(CONTINUE_PREVIOUS_DAY)); + assertEquals(left.mLastForegroundServiceEventMap.get("com.test.service1"), + new Integer(CONTINUING_FOREGROUND_SERVICE)); + assertEquals(left.mLastForegroundServiceEventMap.get("com.test.service2"), + new Integer(CONTINUING_FOREGROUND_SERVICE)); + assertEquals(left.mLaunchCount, 0); + + left.update("com.test.activity1", 350000, MOVE_TO_BACKGROUND); + assertEquals(left.mLastTimeUsed, 350000); + assertEquals(left.mLastForegroundActivityEventMap.get("com.test.activity1"), null); + assertEquals(left.mTotalTimeInForeground, 250000 /*350000 - 100000*/); + + left.update("com.test.service1", 400000, FOREGROUND_SERVICE_STOP); + assertEquals(left.mLastTimeForegroundServiceUsed, 400000); + assertEquals(left.mLastForegroundServiceEventMap.get("com.test.service1"), null); + assertEquals(left.mTotalTimeForegroundServiceUsed, 300000 /*400000 - 100000*/); + + left.update("com.test.activity2", 450000, MOVE_TO_BACKGROUND); + assertEquals(left.mLastTimeUsed, 450000); + assertEquals(left.mLastForegroundActivityEventMap.get("com.test.activity2"), null); + assertEquals(left.mTotalTimeInForeground, 250000 + 100000 /*450000 - 350000*/); + + left.update("com.test.service2", 500000, FOREGROUND_SERVICE_STOP); + assertEquals(left.mLastTimeForegroundServiceUsed, 500000); + assertEquals(left.mLastForegroundServiceEventMap.get("com.test.service2"), null); + assertEquals(left.mTotalTimeForegroundServiceUsed, 300000 + 100000 /*500000 - 400000*/); + + + left.update(null, 550000, END_OF_DAY); + assertEquals(left.mLastTimeUsed, 450000); + assertEquals(left.mTotalTimeInForeground, 350000); + left.update(null, 550000, ROLLOVER_FOREGROUND_SERVICE); + assertEquals(left.mLastTimeForegroundServiceUsed, 500000); + assertEquals(left.mTotalTimeForegroundServiceUsed, 400000); + } + + void compareUsageStats(UsageStats us1, UsageStats us2) { + assertEquals(us1.mPackageName, us2.mPackageName); + assertEquals(us1.mBeginTimeStamp, us2.mBeginTimeStamp); + assertEquals(us1.mLastTimeUsed, us2.mLastTimeUsed); + assertEquals(us1.mLastTimeForegroundServiceUsed, us2.mLastTimeForegroundServiceUsed); + assertEquals(us1.mTotalTimeInForeground, us2.mTotalTimeInForeground); + assertEquals(us1.mTotalTimeForegroundServiceUsed, us2.mTotalTimeForegroundServiceUsed); + assertEquals(us1.mAppLaunchCount, us2.mAppLaunchCount); + assertEquals(us1.mLastForegroundActivityEventMap.size(), + us2.mLastForegroundActivityEventMap.size()); + for (int i = 0; i < us1.mLastForegroundActivityEventMap.size(); i++) { + assertEquals(us1.mLastForegroundActivityEventMap.keyAt(i), + us2.mLastForegroundActivityEventMap.keyAt(i)); + assertEquals(us1.mLastForegroundActivityEventMap.valueAt(i), + us2.mLastForegroundActivityEventMap.valueAt(i)); + } + assertEquals(us1.mLastForegroundServiceEventMap.size(), + us2.mLastForegroundServiceEventMap.size()); + for (int i = 0; i < us1.mLastForegroundServiceEventMap.size(); i++) { + assertEquals(us1.mLastForegroundServiceEventMap.keyAt(i), + us2.mLastForegroundServiceEventMap.keyAt(i)); + assertEquals(us1.mLastForegroundServiceEventMap.valueAt(i), + us2.mLastForegroundServiceEventMap.valueAt(i)); + } + assertEquals(us1.mChooserCounts, us2.mChooserCounts); } } diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java index 78d45d05af93..8c91c370fcf6 100644 --- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java +++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java @@ -124,6 +124,7 @@ public class SettingsBackupTest { Settings.Global.AUTOFILL_LOGGING_LEVEL, Settings.Global.AUTOFILL_MAX_PARTITIONS_SIZE, Settings.Global.AUTOFILL_MAX_VISIBLE_DATASETS, + Settings.Global.AUTOMATIC_POWER_SAVER_MODE, Settings.Global.BATTERY_DISCHARGE_DURATION_THRESHOLD, Settings.Global.BATTERY_DISCHARGE_THRESHOLD, Settings.Global.BATTERY_SAVER_DEVICE_SPECIFIC_CONSTANTS, @@ -235,6 +236,8 @@ public class SettingsBackupTest { Settings.Global.ENABLE_DELETION_HELPER_NO_THRESHOLD_TOGGLE, Settings.Global.ENABLE_DISKSTATS_LOGGING, Settings.Global.ENABLE_EPHEMERAL_FEATURE, + Settings.Global.DYNAMIC_POWER_SAVINGS_ENABLED, + Settings.Global.DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD, Settings.Global.SMART_REPLIES_IN_NOTIFICATIONS_FLAGS, Settings.Global.ENHANCED_4G_MODE_ENABLED, Settings.Global.EPHEMERAL_COOKIE_MAX_SIZE_BYTES, @@ -261,8 +264,7 @@ public class SettingsBackupTest { Settings.Global.HDMI_SYSTEM_AUDIO_CONTROL_ENABLED, Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED, Settings.Global.HIDDEN_API_ACCESS_LOG_SAMPLING_RATE, - Settings.Global.HIDDEN_API_POLICY_P_APPS, - Settings.Global.HIDDEN_API_POLICY_PRE_P_APPS, + Settings.Global.HIDDEN_API_POLICY, Settings.Global.HIDE_ERROR_DIALOGS, Settings.Global.HTTP_PROXY, HYBRID_SYSUI_BATTERY_WARNING_FLAGS, diff --git a/core/tests/coretests/src/android/view/WindowInsetsTest.java b/core/tests/coretests/src/android/view/WindowInsetsTest.java new file mode 100644 index 000000000000..1c2df2cfedb1 --- /dev/null +++ b/core/tests/coretests/src/android/view/WindowInsetsTest.java @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.view; + +import static org.junit.Assert.assertTrue; + +import android.graphics.Rect; +import android.platform.test.annotations.Presubmit; +import android.support.test.filters.SmallTest; +import android.support.test.runner.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(AndroidJUnit4.class) +@SmallTest +@Presubmit +public class WindowInsetsTest { + + @Test + public void systemWindowInsets_afterConsuming_isConsumed() { + assertTrue(new WindowInsets(new Rect(1, 2, 3, 4), null, null, false, false, null) + .consumeSystemWindowInsets().isConsumed()); + } + + @Test + public void multiNullConstructor_isConsumed() { + assertTrue(new WindowInsets(null, null, null, false, false, null).isConsumed()); + } + + @Test + public void singleNullConstructor_isConsumed() { + assertTrue(new WindowInsets((Rect) null).isConsumed()); + } + +} diff --git a/core/tests/packagemanagertests/src/android/content/pm/KernelPackageMappingTests.java b/core/tests/packagemanagertests/src/android/content/pm/KernelPackageMappingTests.java index 01382aae923e..4e0f2a8fe060 100644 --- a/core/tests/packagemanagertests/src/android/content/pm/KernelPackageMappingTests.java +++ b/core/tests/packagemanagertests/src/android/content/pm/KernelPackageMappingTests.java @@ -81,7 +81,7 @@ public class KernelPackageMappingTests { @Test public void testSharedInstalledPrimary() throws Exception { - assertEquals("1001", getContent(getKernelPackageFile("shared:android.uid.phone", "appid"))); + assertEquals("1001", getContent(getKernelPackageFile("shared-android.uid.phone", "appid"))); } @Test @@ -92,7 +92,7 @@ public class KernelPackageMappingTests { @Test public void testSharedInstalledAll() throws Exception { - assertEquals("", getContent(getKernelPackageFile("shared:android.uid.phone", + assertEquals("", getContent(getKernelPackageFile("shared-android.uid.phone", "excluded_userids"))); } diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml index a1fbe0a8eaa1..84cb5f80ece3 100644 --- a/data/etc/privapp-permissions-platform.xml +++ b/data/etc/privapp-permissions-platform.xml @@ -194,6 +194,8 @@ applications that come with the platform <privapp-permissions package="com.android.providers.calendar"> <permission name="android.permission.GET_ACCOUNTS_PRIVILEGED"/> + <permission name="android.permission.INTERACT_ACROSS_USERS" /> + <permission name="android.permission.MANAGE_USERS" /> <permission name="android.permission.UPDATE_APP_OPS_STATS"/> <permission name="android.permission.USE_RESERVED_DISK"/> </privapp-permissions> @@ -324,6 +326,7 @@ applications that come with the platform <permission name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/> <permission name="android.permission.MOVE_PACKAGE"/> <permission name="android.permission.PACKAGE_USAGE_STATS" /> + <permission name="android.permission.POWER_SAVER" /> <permission name="android.permission.READ_FRAME_BUFFER"/> <permission name="android.permission.READ_LOWPAN_CREDENTIAL"/> <permission name="android.permission.READ_PRIVILEGED_PHONE_STATE"/> diff --git a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp index 7fc41acefe8a..a494e490aea1 100644 --- a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp +++ b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp @@ -51,7 +51,7 @@ Frame SkiaVulkanPipeline::getFrame() { LOG_ALWAYS_FATAL_IF(mVkSurface == nullptr, "drawRenderNode called on a context with no surface!"); - SkSurface* backBuffer = mVkManager.getBackbufferSurface(mVkSurface); + SkSurface* backBuffer = mVkManager.getBackbufferSurface(&mVkSurface); if (backBuffer == nullptr) { SkDebugf("failed to get backbuffer"); return Frame(-1, -1, 0); diff --git a/libs/hwui/renderthread/VulkanManager.cpp b/libs/hwui/renderthread/VulkanManager.cpp index f96b1f897921..d84ec8508ee4 100644 --- a/libs/hwui/renderthread/VulkanManager.cpp +++ b/libs/hwui/renderthread/VulkanManager.cpp @@ -16,6 +16,8 @@ #include "VulkanManager.h" +#include <gui/Surface.h> + #include "Properties.h" #include "RenderThread.h" #include "renderstate/RenderState.h" @@ -452,7 +454,20 @@ VulkanSurface::BackbufferInfo* VulkanManager::getAvailableBackbuffer(VulkanSurfa return backbuffer; } -SkSurface* VulkanManager::getBackbufferSurface(VulkanSurface* surface) { +SkSurface* VulkanManager::getBackbufferSurface(VulkanSurface** surfaceOut) { + // Recreate VulkanSurface, if ANativeWindow has been resized. + VulkanSurface* surface = *surfaceOut; + int windowWidth = 0, windowHeight = 0; + ANativeWindow* window = surface->mNativeWindow; + window->query(window, NATIVE_WINDOW_WIDTH, &windowWidth); + window->query(window, NATIVE_WINDOW_HEIGHT, &windowHeight); + if (windowWidth != surface->mWindowWidth || windowHeight != surface->mWindowHeight) { + ColorMode colorMode = surface->mColorMode; + destroySurface(surface); + *surfaceOut = createSurface(window, colorMode); + surface = *surfaceOut; + } + VulkanSurface::BackbufferInfo* backbuffer = getAvailableBackbuffer(surface); SkASSERT(backbuffer); @@ -717,6 +732,8 @@ bool VulkanManager::createSwapchain(VulkanSurface* surface) { extent.height = caps.minImageExtent.height; } SkASSERT(extent.height <= caps.maxImageExtent.height); + surface->mWindowWidth = extent.width; + surface->mWindowHeight = extent.height; uint32_t imageCount = caps.minImageCount + 2; if (caps.maxImageCount > 0 && imageCount > caps.maxImageCount) { @@ -814,7 +831,7 @@ VulkanSurface* VulkanManager::createSurface(ANativeWindow* window, ColorMode col return nullptr; } - VulkanSurface* surface = new VulkanSurface(colorMode); + VulkanSurface* surface = new VulkanSurface(colorMode, window); VkAndroidSurfaceCreateInfoKHR surfaceCreateInfo; memset(&surfaceCreateInfo, 0, sizeof(VkAndroidSurfaceCreateInfoKHR)); diff --git a/libs/hwui/renderthread/VulkanManager.h b/libs/hwui/renderthread/VulkanManager.h index 6702649402e6..8594a1bd4339 100644 --- a/libs/hwui/renderthread/VulkanManager.h +++ b/libs/hwui/renderthread/VulkanManager.h @@ -38,7 +38,8 @@ class RenderThread; class VulkanSurface { public: - VulkanSurface(ColorMode colorMode) : mColorMode(colorMode) {} + VulkanSurface(ColorMode colorMode, ANativeWindow* window) + : mColorMode(colorMode), mNativeWindow(window) {} sk_sp<SkSurface> getBackBufferSurface() { return mBackbuffer; } @@ -75,6 +76,9 @@ private: ImageInfo* mImageInfos; uint16_t mCurrentTime = 0; ColorMode mColorMode; + ANativeWindow* mNativeWindow; + int mWindowWidth = 0; + int mWindowHeight = 0; }; // This class contains the shared global Vulkan objects, such as VkInstance, VkDevice and VkQueue, @@ -109,7 +113,7 @@ public: // Returns an SkSurface which wraps the next image returned from vkAcquireNextImageKHR. It also // will transition the VkImage from a present layout to color attachment so that it can be used // by the client for drawing. - SkSurface* getBackbufferSurface(VulkanSurface* surface); + SkSurface* getBackbufferSurface(VulkanSurface** surface); // Presents the current VkImage. void swapBuffers(VulkanSurface* surface); diff --git a/media/java/android/media/MediaPlayer2Impl.java b/media/java/android/media/MediaPlayer2Impl.java index 0431820777bf..9b97b1060c8a 100644 --- a/media/java/android/media/MediaPlayer2Impl.java +++ b/media/java/android/media/MediaPlayer2Impl.java @@ -56,15 +56,20 @@ import java.net.URL; import java.nio.ByteOrder; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; +import java.util.Queue; import java.util.UUID; +import java.util.WeakHashMap; +import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.Executor; import java.util.concurrent.RejectedExecutionException; import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicLong; /** * @hide @@ -94,17 +99,11 @@ public final class MediaPlayer2Impl extends MediaPlayer2 { private final Object mSrcLock = new Object(); //--- guarded by |mSrcLock| start - private long mSrcIdGenerator = 0; - private DataSourceDesc mCurrentDSD; - private long mCurrentSrcId = mSrcIdGenerator++; - private List<DataSourceDesc> mNextDSDs; - private long mNextSrcId = mSrcIdGenerator++; - private int mNextSourceState = NEXT_SOURCE_STATE_INIT; - private boolean mNextSourcePlayPending = false; + private SourceInfo mCurrentSourceInfo; + private final Queue<SourceInfo> mNextSourceInfos = new ConcurrentLinkedQueue<>(); //--- guarded by |mSrcLock| end + private final AtomicLong mSrcIdGenerator = new AtomicLong(0); - private AtomicInteger mBufferedPercentageCurrent = new AtomicInteger(0); - private AtomicInteger mBufferedPercentageNext = new AtomicInteger(0); private volatile float mVolume = 1.0f; private VideoSize mVideoSize = new VideoSize(0, 0); @@ -227,7 +226,15 @@ public final class MediaPlayer2Impl extends MediaPlayer2 { @Override public long getBufferedPosition() { // Use cached buffered percent for now. - return getDuration() * mBufferedPercentageCurrent.get() / 100; + int bufferedPercentage; + synchronized (mSrcLock) { + if (mCurrentSourceInfo == null) { + bufferedPercentage = 0; + } else { + bufferedPercentage = mCurrentSourceInfo.mBufferedPercentage.get(); + } + } + return getDuration() * bufferedPercentage / 100; } @Override @@ -246,15 +253,14 @@ public final class MediaPlayer2Impl extends MediaPlayer2 { final String msg = "Cannot set AudioAttributes to null"; throw new IllegalArgumentException(msg); } - setParameter(KEY_PARAMETER_AUDIO_ATTRIBUTES, attributes); + native_setAudioAttributes(attributes); } }); } @Override public @NonNull AudioAttributes getAudioAttributes() { - AudioAttributes attributes = (AudioAttributes) getParameter(KEY_PARAMETER_AUDIO_ATTRIBUTES); - return attributes; + return native_getAudioAttributes(); } @Override @@ -269,9 +275,8 @@ public final class MediaPlayer2Impl extends MediaPlayer2 { } synchronized (mSrcLock) { - mCurrentDSD = dsd; - mCurrentSrcId = mSrcIdGenerator++; - handleDataSource(true /* isCurrent */, dsd, mCurrentSrcId); + mCurrentSourceInfo = new SourceInfo(dsd); + handleDataSource(true /* isCurrent */, dsd, mCurrentSourceInfo.mId); } } }); @@ -284,10 +289,8 @@ public final class MediaPlayer2Impl extends MediaPlayer2 { void process() { checkArgument(dsd != null, "the DataSourceDesc cannot be null"); synchronized (mSrcLock) { - mNextDSDs = new ArrayList<DataSourceDesc>(1); - mNextDSDs.add(dsd); - mNextSrcId = mSrcIdGenerator++; - mNextSourceState = NEXT_SOURCE_STATE_INIT; + mNextSourceInfos.clear(); + mNextSourceInfos.add(new SourceInfo(dsd)); } prepareNextDataSource(); } @@ -310,9 +313,10 @@ public final class MediaPlayer2Impl extends MediaPlayer2 { } synchronized (mSrcLock) { - mNextDSDs = new ArrayList(dsds); - mNextSrcId = mSrcIdGenerator++; - mNextSourceState = NEXT_SOURCE_STATE_INIT; + mNextSourceInfos.clear(); + for (DataSourceDesc dsd : dsds) { + mNextSourceInfos.add(new SourceInfo(dsd)); + } } prepareNextDataSource(); } @@ -324,22 +328,15 @@ public final class MediaPlayer2Impl extends MediaPlayer2 { return addTask(new Task(CALL_COMPLETED_CLEAR_NEXT_DATA_SOURCES, false) { @Override void process() { - synchronized (mSrcLock) { - if (mNextDSDs != null) { - mNextDSDs.clear(); - mNextDSDs = null; - } - mNextSrcId = mSrcIdGenerator++; - mNextSourceState = NEXT_SOURCE_STATE_INIT; - } + mNextSourceInfos.clear(); } }); } @Override - public @NonNull DataSourceDesc getCurrentDataSource() { + public DataSourceDesc getCurrentDataSource() { synchronized (mSrcLock) { - return mCurrentDSD; + return mCurrentSourceInfo == null ? null : mCurrentSourceInfo.mDSD; } } @@ -703,39 +700,35 @@ public final class MediaPlayer2Impl extends MediaPlayer2 { // return true if there is a next data source, false otherwise. // This function should be always called on |mHandlerThread|. private boolean prepareNextDataSource() { - if (Looper.myLooper() != mHandlerThread.getLooper()) { + HandlerThread handlerThread = mHandlerThread; + if (handlerThread != null && Looper.myLooper() != handlerThread.getLooper()) { Log.e(TAG, "prepareNextDataSource: called on wrong looper"); } boolean hasNextDSD; - synchronized (mSrcLock) { - hasNextDSD = (mNextDSDs != null && !mNextDSDs.isEmpty()); - } - int state = getState(); - if (state == PLAYER_STATE_ERROR || state == PLAYER_STATE_IDLE) { - // Current source has not been prepared yet. - return hasNextDSD; - } - synchronized (mSrcLock) { - if (!hasNextDSD || mNextSourceState != NEXT_SOURCE_STATE_INIT) { + hasNextDSD = !mNextSourceInfos.isEmpty(); + if (state == PLAYER_STATE_ERROR || state == PLAYER_STATE_IDLE) { + // Current source has not been prepared yet. + return hasNextDSD; + } + + SourceInfo nextSource = mNextSourceInfos.peek(); + if (!hasNextDSD || nextSource.mStateAsNextSource != NEXT_SOURCE_STATE_INIT) { // There is no next source or it's in preparing or prepared state. return hasNextDSD; } try { - mNextSourceState = NEXT_SOURCE_STATE_PREPARING; - handleDataSource(false /* isCurrent */, mNextDSDs.get(0), mNextSrcId); + nextSource.mStateAsNextSource = NEXT_SOURCE_STATE_PREPARING; + handleDataSource(false /* isCurrent */, nextSource.mDSD, nextSource.mId); } catch (Exception e) { Message msg = mTaskHandler.obtainMessage( MEDIA_ERROR, MEDIA_ERROR_IO, MEDIA_ERROR_UNKNOWN, null); - mTaskHandler.handleMessage(msg, mNextSrcId); + mTaskHandler.handleMessage(msg, nextSource.mId); - mNextDSDs.remove(0); - // make a new SrcId to obsolete notification for previous one. - mNextSrcId = mSrcIdGenerator++; - mNextSourceState = NEXT_SOURCE_STATE_INIT; + mNextSourceInfos.poll(); return prepareNextDataSource(); } } @@ -744,25 +737,21 @@ public final class MediaPlayer2Impl extends MediaPlayer2 { // This function should be always called on |mHandlerThread|. private void playNextDataSource() { - if (Looper.myLooper() != mHandlerThread.getLooper()) { + HandlerThread handlerThread = mHandlerThread; + if (handlerThread != null && Looper.myLooper() != handlerThread.getLooper()) { Log.e(TAG, "playNextDataSource: called on wrong looper"); } boolean hasNextDSD = false; synchronized (mSrcLock) { - if (mNextDSDs != null && !mNextDSDs.isEmpty()) { + if (!mNextSourceInfos.isEmpty()) { hasNextDSD = true; - if (mNextSourceState == NEXT_SOURCE_STATE_PREPARED) { + SourceInfo nextSourceInfo = mNextSourceInfos.peek(); + if (nextSourceInfo.mStateAsNextSource == NEXT_SOURCE_STATE_PREPARED) { // Switch to next source only when it has been prepared. - mCurrentDSD = mNextDSDs.get(0); - mCurrentSrcId = mNextSrcId; - mBufferedPercentageCurrent.set(mBufferedPercentageNext.get()); - mNextDSDs.remove(0); - mNextSrcId = mSrcIdGenerator++; // make it different from |mCurrentSrcId| - mBufferedPercentageNext.set(0); - mNextSourceState = NEXT_SOURCE_STATE_INIT; - - long srcId = mCurrentSrcId; + mCurrentSourceInfo = mNextSourceInfos.poll(); + + long srcId = mCurrentSourceInfo.mId; try { nativePlayNextDataSource(srcId); } catch (Exception e) { @@ -777,9 +766,8 @@ public final class MediaPlayer2Impl extends MediaPlayer2 { // Now a new current src is playing. // Wait for MEDIA_INFO_DATA_SOURCE_START to prepare next source. - mNextSourcePlayPending = false; } - } else if (mNextSourceState == NEXT_SOURCE_STATE_INIT) { + } else if (nextSourceInfo.mStateAsNextSource == NEXT_SOURCE_STATE_INIT) { hasNextDSD = prepareNextDataSource(); } } @@ -1074,12 +1062,8 @@ public final class MediaPlayer2Impl extends MediaPlayer2 { mDrmEventCallbackRecords.clear(); } synchronized (mSrcLock) { - if (mNextDSDs != null) { - mNextDSDs.clear(); - mNextDSDs = null; - } - mNextSrcId = mSrcIdGenerator++; - mNextSourceState = NEXT_SOURCE_STATE_INIT; + mCurrentSourceInfo = null; + mNextSourceInfos.clear(); } synchronized (mTaskLock) { @@ -1102,14 +1086,12 @@ public final class MediaPlayer2Impl extends MediaPlayer2 { // Keep KEY_PARAMETER_* in sync with include/media/mediaplayer2.h private final static int KEY_PARAMETER_AUDIO_ATTRIBUTES = 1400; /** - * Sets the parameter indicated by key. - * @param key key indicates the parameter to be set. + * Sets the audio attributes. * @param value value of the parameter to be set. * @return true if the parameter is set successfully, false otherwise */ - private native boolean setParameter(int key, Object value); - - private native Object getParameter(int key); + private native boolean native_setAudioAttributes(AudioAttributes audioAttributes); + private native AudioAttributes native_getAudioAttributes(); /** @@ -1535,20 +1517,11 @@ public final class MediaPlayer2Impl extends MediaPlayer2 { final int what = msg.arg1; final int extra = msg.arg2; - final DataSourceDesc dsd; - boolean isCurrentSrcId = false; - boolean isNextSrcId = false; - synchronized (mSrcLock) { - if (srcId == mCurrentSrcId) { - dsd = mCurrentDSD; - isCurrentSrcId = true; - } else if (mNextDSDs != null && !mNextDSDs.isEmpty() && srcId == mNextSrcId) { - dsd = mNextDSDs.get(0); - isNextSrcId = true; - } else { - return; - } + final SourceInfo sourceInfo = getSourceInfoById(srcId); + if (sourceInfo == null) { + return; } + final DataSourceDesc dsd = sourceInfo.mDSD; switch(msg.what) { case MEDIA_PREPARED: @@ -1564,14 +1537,16 @@ public final class MediaPlayer2Impl extends MediaPlayer2 { } synchronized (mSrcLock) { + SourceInfo nextSourceInfo = mNextSourceInfos.peek(); Log.i(TAG, "MEDIA_PREPARED: srcId=" + srcId - + ", currentSrcId=" + mCurrentSrcId + ", nextSrcId=" + mNextSrcId); + + ", curSrc=" + mCurrentSourceInfo + + ", nextSrc=" + nextSourceInfo); - if (isCurrentSrcId) { + if (isCurrentSource(srcId)) { prepareNextDataSource(); - } else if (isNextSrcId) { - mNextSourceState = NEXT_SOURCE_STATE_PREPARED; - if (mNextSourcePlayPending) { + } else if (isNextSource(srcId)) { + nextSourceInfo.mStateAsNextSource = NEXT_SOURCE_STATE_PREPARED; + if (nextSourceInfo.mPlayPendingAsNextSource) { playNextDataSource(); } } @@ -1624,7 +1599,7 @@ public final class MediaPlayer2Impl extends MediaPlayer2 { case MEDIA_PLAYBACK_COMPLETE: { - if (isCurrentSrcId) { + if (isCurrentSource(srcId)) { sendEvent(new EventNotifier() { @Override public void notify(EventCallback callback) { @@ -1635,11 +1610,13 @@ public final class MediaPlayer2Impl extends MediaPlayer2 { stayAwake(false); synchronized (mSrcLock) { - mNextSourcePlayPending = true; - + SourceInfo nextSourceInfo = mNextSourceInfos.peek(); + if (nextSourceInfo != null) { + nextSourceInfo.mPlayPendingAsNextSource = true; + } Log.i(TAG, "MEDIA_PLAYBACK_COMPLETE: srcId=" + srcId - + ", currentSrcId=" + mCurrentSrcId - + ", nextSrcId=" + mNextSrcId); + + ", curSrc=" + mCurrentSourceInfo + + ", nextSrc=" + nextSourceInfo); } playNextDataSource(); @@ -1670,13 +1647,11 @@ public final class MediaPlayer2Impl extends MediaPlayer2 { } }); - synchronized (mSrcLock) { - if (isCurrentSrcId) { - mBufferedPercentageCurrent.set(percent); - } else if (isNextSrcId) { - mBufferedPercentageNext.set(percent); - } + SourceInfo src = getSourceInfoById(srcId); + if (src != null) { + src.mBufferedPercentage.set(percent); } + return; } @@ -1754,7 +1729,7 @@ public final class MediaPlayer2Impl extends MediaPlayer2 { }); if (msg.arg1 == MEDIA_INFO_DATA_SOURCE_START) { - if (isCurrentSrcId) { + if (isCurrentSource(srcId)) { prepareNextDataSource(); } } @@ -1857,6 +1832,7 @@ public final class MediaPlayer2Impl extends MediaPlayer2 { } } } + } /* @@ -2133,7 +2109,7 @@ public final class MediaPlayer2Impl extends MediaPlayer2 { @Override public void notify(DrmEventCallback callback) { callback.onDrmPrepared( - MediaPlayer2Impl.this, mCurrentDSD, prepareDrmStatus); + MediaPlayer2Impl.this, getCurrentDataSource(), prepareDrmStatus); } }); @@ -2199,7 +2175,7 @@ public final class MediaPlayer2Impl extends MediaPlayer2 { // call the callback outside the lock if (mOnDrmConfigHelper != null) { - mOnDrmConfigHelper.onDrmConfig(this, mCurrentDSD); + mOnDrmConfigHelper.onDrmConfig(this, getCurrentDataSource()); } synchronized (mDrmLock) { @@ -2820,7 +2796,7 @@ public final class MediaPlayer2Impl extends MediaPlayer2 { @Override public void notify(DrmEventCallback callback) { callback.onDrmPrepared( - mediaPlayer, mCurrentDSD, status); + mediaPlayer, getCurrentDataSource(), status); } }); @@ -3087,9 +3063,7 @@ public final class MediaPlayer2Impl extends MediaPlayer2 { } catch (Exception e) { status = CALL_STATUS_ERROR_UNKNOWN; } - synchronized (mSrcLock) { - mDSD = mCurrentDSD; - } + mDSD = getCurrentDataSource(); if (mMediaCallType != CALL_COMPLETED_SEEK_TO) { synchronized (mTaskLock) { @@ -3132,4 +3106,50 @@ public final class MediaPlayer2Impl extends MediaPlayer2 { super(detailMessage); } }; + + private final class SourceInfo { + final DataSourceDesc mDSD; + final long mId = mSrcIdGenerator.getAndIncrement(); + AtomicInteger mBufferedPercentage = new AtomicInteger(0); + + // m*AsNextSource (below) only applies to pending data sources in the playlist; + // the meanings of mCurrentSourceInfo.{mStateAsNextSource,mPlayPendingAsNextSource} + // are undefined. + int mStateAsNextSource = NEXT_SOURCE_STATE_INIT; + boolean mPlayPendingAsNextSource = false; + + SourceInfo(DataSourceDesc dsd) { + this.mDSD = dsd; + } + + @Override + public String toString() { + return String.format("%s(%d)", SourceInfo.class.getName(), mId); + } + + } + + private SourceInfo getSourceInfoById(long srcId) { + synchronized (mSrcLock) { + if (isCurrentSource(srcId)) { + return mCurrentSourceInfo; + } + if (isNextSource(srcId)) { + return mNextSourceInfos.peek(); + } + } + return null; + } + + private boolean isCurrentSource(long srcId) { + synchronized (mSrcLock) { + return mCurrentSourceInfo != null && mCurrentSourceInfo.mId == srcId; + } + } + + private boolean isNextSource(long srcId) { + SourceInfo nextSourceInfo = mNextSourceInfos.peek(); + return nextSourceInfo != null && nextSourceInfo.mId == srcId; + } + } diff --git a/media/jni/android_media_MediaPlayer2.cpp b/media/jni/android_media_MediaPlayer2.cpp index 8e30455c31f0..0769e5c84674 100644 --- a/media/jni/android_media_MediaPlayer2.cpp +++ b/media/jni/android_media_MediaPlayer2.cpp @@ -846,56 +846,29 @@ android_media_MediaPlayer2_reset(JNIEnv *env, jobject thiz) } static jboolean -android_media_MediaPlayer2_setParameter(JNIEnv *env, jobject thiz, jint key, jobject) +android_media_MediaPlayer2_setAudioAttributes(JNIEnv *env, jobject thiz, jobject attributes) { - ALOGV("setParameter: key %d", key); + ALOGV("setAudioAttributes"); sp<MediaPlayer2> mp = getMediaPlayer(env, thiz); if (mp == NULL ) { jniThrowException(env, "java/lang/IllegalStateException", NULL); return false; } - - return false; - // TODO: set/getParameter is temporarily disabled to remove android_runtime.so dependency. - // Once JAudioTrack migration is done, the AudioAttribute jobject - // should be directly passed to AudioTrack without native parcel conversion. - /* - Parcel *request = parcelForJavaObject(env, java_request); - status_t err = mp->setParameter(key, *request); - if (err == OK) { - return true; - } else { - return false; - } - */ + status_t err = mp->setAudioAttributes(attributes); + return err == OK; } static jobject -android_media_MediaPlayer2_getParameter(JNIEnv *env, jobject thiz, jint key) +android_media_MediaPlayer2_getAudioAttributes(JNIEnv *env, jobject thiz) { - ALOGV("getParameter: key %d", key); + ALOGV("getAudioAttributes"); sp<MediaPlayer2> mp = getMediaPlayer(env, thiz); if (mp == NULL) { jniThrowException(env, "java/lang/IllegalStateException", NULL); return NULL; } - return NULL; - // TODO: set/getParameter is temporarily disabled to remove android_runtime.so dependency. - // Once JAudioTrack migration is done, the AudioAttribute jobject - // should be directly passed to AudioTrack without native parcel conversion. - /* - jobject jParcel = createJavaParcelObject(env); - if (jParcel != NULL) { - Parcel* nativeParcel = parcelForJavaObject(env, jParcel); - status_t err = mp->getParameter(key, nativeParcel); - if (err != OK) { - env->DeleteLocalRef(jParcel); - return NULL; - } - } - return jParcel; - */ + return mp->getAudioAttributes(); } static void @@ -1428,17 +1401,17 @@ static const JNINativeMethod gMethods[] = { {"native_getState", "()I", (void *)android_media_MediaPlayer2_getState}, {"native_getMetrics", "()Landroid/os/PersistableBundle;", (void *)android_media_MediaPlayer2_native_getMetrics}, {"_setPlaybackParams", "(Landroid/media/PlaybackParams;)V", (void *)android_media_MediaPlayer2_setPlaybackParams}, - {"getPlaybackParams", "()Landroid/media/PlaybackParams;", (void *)android_media_MediaPlayer2_getPlaybackParams}, - {"_setSyncParams", "(Landroid/media/SyncParams;)V", (void *)android_media_MediaPlayer2_setSyncParams}, - {"getSyncParams", "()Landroid/media/SyncParams;", (void *)android_media_MediaPlayer2_getSyncParams}, + {"getPlaybackParams", "()Landroid/media/PlaybackParams;", (void *)android_media_MediaPlayer2_getPlaybackParams}, + {"_setSyncParams", "(Landroid/media/SyncParams;)V", (void *)android_media_MediaPlayer2_setSyncParams}, + {"getSyncParams", "()Landroid/media/SyncParams;", (void *)android_media_MediaPlayer2_getSyncParams}, {"_seekTo", "(JI)V", (void *)android_media_MediaPlayer2_seekTo}, {"_pause", "()V", (void *)android_media_MediaPlayer2_pause}, {"getCurrentPosition", "()J", (void *)android_media_MediaPlayer2_getCurrentPosition}, {"getDuration", "()J", (void *)android_media_MediaPlayer2_getDuration}, {"_release", "()V", (void *)android_media_MediaPlayer2_release}, {"_reset", "()V", (void *)android_media_MediaPlayer2_reset}, - {"setParameter", "(ILjava/lang/Object;)Z", (void *)android_media_MediaPlayer2_setParameter}, - {"getParameter", "(I)Ljava/lang/Object;", (void *)android_media_MediaPlayer2_getParameter}, + {"native_setAudioAttributes", "(Landroid/media/AudioAttributes;)Z", (void *)android_media_MediaPlayer2_setAudioAttributes}, + {"native_getAudioAttributes", "()Landroid/media/AudioAttributes;", (void *)android_media_MediaPlayer2_getAudioAttributes}, {"setLooping", "(Z)V", (void *)android_media_MediaPlayer2_setLooping}, {"isLooping", "()Z", (void *)android_media_MediaPlayer2_isLooping}, {"native_setVolume", "(F)V", (void *)android_media_MediaPlayer2_setVolume}, diff --git a/packages/ExtServices/src/android/ext/services/notification/Assistant.java b/packages/ExtServices/src/android/ext/services/notification/Assistant.java index 11366848874a..60153fcbc26b 100644 --- a/packages/ExtServices/src/android/ext/services/notification/Assistant.java +++ b/packages/ExtServices/src/android/ext/services/notification/Assistant.java @@ -78,8 +78,6 @@ import java.util.Map; public class Assistant extends NotificationAssistantService { private static final String TAG = "ExtAssistant"; private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); - public static final boolean AUTO_DEMOTE_NOTIFICATIONS = SystemProperties.getBoolean( - "debug.demote_notifs", false); public static final boolean AGE_NOTIFICATIONS = SystemProperties.getBoolean( "debug.age_notifs", false); @@ -242,7 +240,8 @@ public class Assistant extends NotificationAssistantService { if (!smartReplies.isEmpty()) { signals.putCharSequenceArrayList(Adjustment.KEY_SMART_REPLIES, smartReplies); } - if (AUTO_DEMOTE_NOTIFICATIONS) { + if (Settings.Secure.getInt(getContentResolver(), + Settings.Secure.NOTIFICATION_NEW_INTERRUPTION_MODEL, 0) == 1) { if (mNotificationCategorizer.shouldSilence(entry)) { final int importance = entry.getImportance() < IMPORTANCE_LOW ? entry.getImportance() : IMPORTANCE_LOW; diff --git a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java index 4e52ff6d016c..4abcf73af109 100644 --- a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java +++ b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java @@ -186,7 +186,8 @@ public class ExternalStorageProvider extends FileSystemProvider { title = mStorageManager.getBestVolumeDescription(privateVol); storageUuid = StorageManager.convert(privateVol.fsUuid); } - } else if (volume.getType() == VolumeInfo.TYPE_PUBLIC + } else if ((volume.getType() == VolumeInfo.TYPE_PUBLIC + || volume.getType() == VolumeInfo.TYPE_STUB) && volume.getMountUserId() == userId) { rootId = volume.getFsUuid(); title = mStorageManager.getBestVolumeDescription(volume); diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml index b77d4e556da5..d34820cd3a11 100644 --- a/packages/SettingsLib/res/values-af/strings.xml +++ b/packages/SettingsLib/res/values-af/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"Kan nie skandeer vir netwerke nie"</string> - <string name="wifi_security_none" msgid="7985461072596594400">"Geen"</string> <string name="wifi_remembered" msgid="4955746899347821096">"Gestoor"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"Gedeaktiveer"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP-opstelling het misluk"</string> diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml index 836ec808d207..b595e2b05154 100644 --- a/packages/SettingsLib/res/values-am/strings.xml +++ b/packages/SettingsLib/res/values-am/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"ለአውታረመረቦች መቃኘት አይቻልም"</string> - <string name="wifi_security_none" msgid="7985461072596594400">"የለም"</string> <string name="wifi_remembered" msgid="4955746899347821096">"ተቀምጧል"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"ተሰናክሏል"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"የአይ.ፒ. ውቅረት መሰናከል"</string> diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml index 83c4b8ee3b86..f8c2ba2bd20d 100644 --- a/packages/SettingsLib/res/values-ar/strings.xml +++ b/packages/SettingsLib/res/values-ar/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"لا يمكن فحص الشبكات"</string> - <string name="wifi_security_none" msgid="7985461072596594400">"بدون"</string> <string name="wifi_remembered" msgid="4955746899347821096">"تم الحفظ"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"غير مفعّلة"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"تعذّرت تهيئة عنوان IP"</string> @@ -227,11 +226,11 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="6893955536658137179">"اختيار برنامج ترميز LDAC\nلصوت مشغّل البلوتوث: جودة التشغيل"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"البث: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> <string name="select_private_dns_configuration_title" msgid="3700456559305263922">"نظام أسماء النطاقات الخاص"</string> - <string name="select_private_dns_configuration_dialog_title" msgid="9221994415765826811">"اختر وضع نظام أسماء النطاقات الخاص"</string> + <string name="select_private_dns_configuration_dialog_title" msgid="9221994415765826811">"تحديد وضع \"نظام أسماء النطاقات الخاص\""</string> <string name="private_dns_mode_off" msgid="8236575187318721684">"غير مفعّل"</string> <string name="private_dns_mode_opportunistic" msgid="8314986739896927399">"تلقائي"</string> - <string name="private_dns_mode_provider" msgid="8354935160639360804">"اسم مضيف مزوّد نظام أسماء النطاقات الخاص"</string> - <string name="private_dns_mode_provider_hostname_hint" msgid="2487492386970928143">"أدخل اسم مضيف مزوّد نظام أسماء النطاقات"</string> + <string name="private_dns_mode_provider" msgid="8354935160639360804">"اسم مضيف مزوّد \"نظام أسماء النطاقات الخاص\""</string> + <string name="private_dns_mode_provider_hostname_hint" msgid="2487492386970928143">"يُرجى إدخال اسم مضيف \"مزوّد نظام أسماء النطاقات\""</string> <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"تعذّر الاتصال"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"عرض خيارات شهادة عرض شاشة لاسلكي"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"زيادة مستوى تسجيل Wi-Fi، وعرض لكل SSID RSSI في منتقي Wi-Fi"</string> @@ -371,10 +370,10 @@ <string name="power_remaining_duration_only_enhanced" msgid="4189311599812296592">"يتبقى <xliff:g id="TIME_REMAINING">%1$s</xliff:g> تقريبًا، بناءً على استخدامك"</string> <string name="power_discharging_duration_enhanced" msgid="1992003260664804080">"يتبقى <xliff:g id="TIME_REMAINING">%1$s</xliff:g> تقريبًا، بناءً على استخدامك (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_duration_only_short" msgid="3463575350656389957">"الوقت المتبقي: <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> - <string name="power_discharge_by_enhanced" msgid="2095821536747992464">"من المفترض أن يستمر شحن البطارية حتى حوالي الساعة <xliff:g id="TIME">%1$s</xliff:g> حسب استخدامك (<xliff:g id="LEVEL">%2$s</xliff:g>)."</string> - <string name="power_discharge_by_only_enhanced" msgid="2175151772952365149">"من المفترض أن يستمر شحن البطارية حتى حوالي الساعة <xliff:g id="TIME">%1$s</xliff:g> حسب استخدامك."</string> - <string name="power_discharge_by" msgid="6453537733650125582">"من المفترض أن يستمر شحن البطارية حتى حوالي الساعة <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)."</string> - <string name="power_discharge_by_only" msgid="107616694963545745">"من المفترض أن يستمر شحن البطارية حتى حوالي الساعة <xliff:g id="TIME">%1$s</xliff:g>."</string> + <string name="power_discharge_by_enhanced" msgid="2095821536747992464">"قد تكفي طاقة البطارية حتى حوالي الساعة <xliff:g id="TIME">%1$s</xliff:g> حسب استخدامك (<xliff:g id="LEVEL">%2$s</xliff:g>)."</string> + <string name="power_discharge_by_only_enhanced" msgid="2175151772952365149">"قد تكفي طاقة البطارية حتى حوالي الساعة <xliff:g id="TIME">%1$s</xliff:g> حسب استخدامك."</string> + <string name="power_discharge_by" msgid="6453537733650125582">"قد تكفي طاقة البطارية حتى حوالي الساعة <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)."</string> + <string name="power_discharge_by_only" msgid="107616694963545745">"قد تكفي طاقة البطارية حتى حوالي الساعة <xliff:g id="TIME">%1$s</xliff:g>."</string> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"يتبقى أقل من <xliff:g id="THRESHOLD">%1$s</xliff:g>."</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"يتبقى أقل من <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)."</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"يتبقى أكثر من <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)."</string> diff --git a/packages/SettingsLib/res/values-as/strings.xml b/packages/SettingsLib/res/values-as/strings.xml index ddd17daf5e80..72122c2648ae 100644 --- a/packages/SettingsLib/res/values-as/strings.xml +++ b/packages/SettingsLib/res/values-as/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"নেটৱৰ্ক বিচাৰি স্কেন কৰিব পৰা নাই"</string> - <string name="wifi_security_none" msgid="7985461072596594400">"নাই"</string> <string name="wifi_remembered" msgid="4955746899347821096">"ছেভ কৰি থোৱা নেটৱৰ্কসমূহ"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"নিষ্ক্ৰিয় হৈ আছে"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP কনফিগাৰেশ্বন বিফল হৈছে"</string> diff --git a/packages/SettingsLib/res/values-az/strings.xml b/packages/SettingsLib/res/values-az/strings.xml index a6e484f64726..23008e2f3a35 100644 --- a/packages/SettingsLib/res/values-az/strings.xml +++ b/packages/SettingsLib/res/values-az/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"Şəbəkə axtarmaq olmur"</string> - <string name="wifi_security_none" msgid="7985461072596594400">"Heç biri"</string> <string name="wifi_remembered" msgid="4955746899347821096">"Yadda saxlanılan"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"Deaktiv"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP Konfiqurasiya Uğursuzluğu"</string> diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml index a446845b0fba..3ee8589268cd 100644 --- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml +++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml @@ -21,13 +21,12 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"Nije moguće skenirati mreže"</string> - <string name="wifi_security_none" msgid="7985461072596594400">"Nema"</string> <string name="wifi_remembered" msgid="4955746899347821096">"Sačuvano"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"Onemogućeno"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP konfiguracija je otkazala"</string> <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"Nije povezano zbog lošeg kvaliteta mreže"</string> <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"Wi-Fi veza je otkazala"</string> - <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"Problem sa potvrdom autentičnosti"</string> + <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"Problem sa potvrdom identiteta"</string> <string name="wifi_cant_connect" msgid="5410016875644565884">"Povezivanje nije uspelo"</string> <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"Povezivanje sa „<xliff:g id="AP_NAME">%1$s</xliff:g>“ nije uspelo"</string> <string name="wifi_check_password_try_again" msgid="516958988102584767">"Proverite lozinku i probajte ponovo"</string> @@ -448,5 +447,5 @@ <string name="zen_mode_duration_settings_title" msgid="229547412251222757">"Trajanje"</string> <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"Uvek pitaj"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"Dok ne isključite"</string> - <string name="time_unit_just_now" msgid="6363336622778342422">"Upravo sada"</string> + <string name="time_unit_just_now" msgid="6363336622778342422">"Upravo"</string> </resources> diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml index d56db13e298e..64253bff6a25 100644 --- a/packages/SettingsLib/res/values-be/strings.xml +++ b/packages/SettingsLib/res/values-be/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"Не атрымлiваецца выканаць сканаванне для сетак"</string> - <string name="wifi_security_none" msgid="7985461072596594400">"Няма"</string> <string name="wifi_remembered" msgid="4955746899347821096">"Захавана"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"Адключана"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"Збой канфігурацыі IP"</string> diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml index c1bc31c697cd..668aa2d82d07 100644 --- a/packages/SettingsLib/res/values-bg/strings.xml +++ b/packages/SettingsLib/res/values-bg/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"Не може да се сканира за мрежи"</string> - <string name="wifi_security_none" msgid="7985461072596594400">"Няма"</string> <string name="wifi_remembered" msgid="4955746899347821096">"Запазено"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"Деактивирани"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"Неуспешно конфигуриране на IP адреса"</string> @@ -374,7 +373,7 @@ <string name="power_discharge_by_enhanced" msgid="2095821536747992464">"Следва да издържи приблизително до <xliff:g id="TIME">%1$s</xliff:g> въз основа на използването (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only_enhanced" msgid="2175151772952365149">"Следва да издържи приблизително до <xliff:g id="TIME">%1$s</xliff:g> въз основа на използването"</string> <string name="power_discharge_by" msgid="6453537733650125582">"Следва да издържи приблизително до <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_discharge_by_only" msgid="107616694963545745">"Следва да издържи приблизително до <xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="power_discharge_by_only" msgid="107616694963545745">"Следва да издържи до около <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"Остава/т по-малко от <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"Остава/т по-малко от <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"Остава/т повече от <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml index 1550c00cc2fa..c6eed2cbf7dc 100644 --- a/packages/SettingsLib/res/values-bn/strings.xml +++ b/packages/SettingsLib/res/values-bn/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"নেটওয়ার্কগুলির জন্য স্ক্যান করা যাবে না"</string> - <string name="wifi_security_none" msgid="7985461072596594400">"কোনো কিছুই নয়"</string> <string name="wifi_remembered" msgid="4955746899347821096">"সংরক্ষিত"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"অক্ষম হয়েছে"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP কনফিগারেশনের ব্যর্থতা"</string> diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml index 460e7cfe4671..16179fb7157c 100644 --- a/packages/SettingsLib/res/values-bs/strings.xml +++ b/packages/SettingsLib/res/values-bs/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"Ne može skenirati mreže"</string> - <string name="wifi_security_none" msgid="7985461072596594400">"Nema"</string> <string name="wifi_remembered" msgid="4955746899347821096">"Sačuvano"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"Onemogućeno"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"Greška u konfiguraciji IP-a"</string> diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml index 5638947f64b1..f906ea4eeef1 100644 --- a/packages/SettingsLib/res/values-ca/strings.xml +++ b/packages/SettingsLib/res/values-ca/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"No es poden cercar xarxes"</string> - <string name="wifi_security_none" msgid="7985461072596594400">"Cap"</string> <string name="wifi_remembered" msgid="4955746899347821096">"Desat"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"Desactivat"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"Error de configuració d\'IP"</string> @@ -70,7 +69,7 @@ <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"Actiu"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Àudio multimèdia"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Trucades telefòniques"</string> - <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Transferència del fitxer"</string> + <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Transferència de fitxers"</string> <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Dispositiu d\'entrada"</string> <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Accés a Internet"</string> <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Compartir contactes"</string> @@ -393,7 +392,7 @@ <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"s\'està carregant"</string> <string name="battery_info_status_discharging" msgid="310932812698268588">"No s\'està carregant"</string> <string name="battery_info_status_not_charging" msgid="8523453668342598579">"El dispositiu està endollat però en aquests moments no es pot carregar"</string> - <string name="battery_info_status_full" msgid="2824614753861462808">"Plena"</string> + <string name="battery_info_status_full" msgid="2824614753861462808">"Completa"</string> <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Controlat per l\'administrador"</string> <string name="disabled" msgid="9206776641295849915">"Desactivat"</string> <string name="external_source_trusted" msgid="2707996266575928037">"Amb permís"</string> diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml index de02245b0e94..f9c866992628 100644 --- a/packages/SettingsLib/res/values-cs/strings.xml +++ b/packages/SettingsLib/res/values-cs/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"Nelze hledat sítě"</string> - <string name="wifi_security_none" msgid="7985461072596594400">"Žádné"</string> <string name="wifi_remembered" msgid="4955746899347821096">"Uloženo"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"Vypnuto"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"Selhání konfigurace protokolu IP"</string> diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml index 34608d370bd7..6b2bd98e4f09 100644 --- a/packages/SettingsLib/res/values-da/strings.xml +++ b/packages/SettingsLib/res/values-da/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"Der kan ikke søges efter netværk"</string> - <string name="wifi_security_none" msgid="7985461072596594400">"Ingen"</string> <string name="wifi_remembered" msgid="4955746899347821096">"Gemt"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"Deaktiveret"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP-konfigurationsfejl"</string> diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml index 79965d22f4f9..ad6f5f2112cc 100644 --- a/packages/SettingsLib/res/values-de/strings.xml +++ b/packages/SettingsLib/res/values-de/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"Netzwerkscan nicht möglich"</string> - <string name="wifi_security_none" msgid="7985461072596594400">"Keine"</string> <string name="wifi_remembered" msgid="4955746899347821096">"Gespeichert"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"Deaktiviert"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP-Konfigurationsfehler"</string> @@ -231,7 +230,7 @@ <string name="private_dns_mode_off" msgid="8236575187318721684">"Aus"</string> <string name="private_dns_mode_opportunistic" msgid="8314986739896927399">"Automatisch"</string> <string name="private_dns_mode_provider" msgid="8354935160639360804">"Hostname des privaten DNS-Anbieters"</string> - <string name="private_dns_mode_provider_hostname_hint" msgid="2487492386970928143">"Hostnamen des DNS-Anbieters eingeben"</string> + <string name="private_dns_mode_provider_hostname_hint" msgid="2487492386970928143">"Hostname des DNS-Anbieters eingeben"</string> <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Verbindung nicht möglich"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Optionen zur Zertifizierung für kabellose Übertragung anzeigen"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Level für WLAN-Protokollierung erhöhen, in WiFi Picker pro SSID-RSSI anzeigen"</string> diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml index b9ea8435200f..5bfbf2c0c1cb 100644 --- a/packages/SettingsLib/res/values-el/strings.xml +++ b/packages/SettingsLib/res/values-el/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"Δεν είναι δυνατή η σάρωση για δίκτυα"</string> - <string name="wifi_security_none" msgid="7985461072596594400">"Καμία"</string> <string name="wifi_remembered" msgid="4955746899347821096">"Αποθηκευμένο"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"Απενεργοποιημένο"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"Αποτυχία διαμόρφωσης διεύθυνσης IP"</string> @@ -231,7 +230,7 @@ <string name="private_dns_mode_off" msgid="8236575187318721684">"Ανενεργή"</string> <string name="private_dns_mode_opportunistic" msgid="8314986739896927399">"Αυτόματα"</string> <string name="private_dns_mode_provider" msgid="8354935160639360804">"Όνομα κεντρικού υπολογιστή παρόχου DNS"</string> - <string name="private_dns_mode_provider_hostname_hint" msgid="2487492386970928143">"Εισαγάγετε το όνομα κεντρικού υπολογιστή του παρόχου DNS"</string> + <string name="private_dns_mode_provider_hostname_hint" msgid="2487492386970928143">"Όνομα κεντρικού υπολογιστή του παρόχου DNS"</string> <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Δεν ήταν δυνατή η σύνδεση"</string> <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Εμφάνιση επιλογών για πιστοποίηση ασύρματης οθόνης"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Αύξηση επιπέδου καταγ. Wi-Fi, εμφάνιση ανά SSID RSSI στο εργαλείο επιλογής Wi-Fi"</string> diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml index 1a7d7c52c63c..f0eaeed5f885 100644 --- a/packages/SettingsLib/res/values-en-rAU/strings.xml +++ b/packages/SettingsLib/res/values-en-rAU/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"Can\'t scan for networks"</string> - <string name="wifi_security_none" msgid="7985461072596594400">"None"</string> <string name="wifi_remembered" msgid="4955746899347821096">"Saved"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"Disabled"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP Configuration Failure"</string> diff --git a/packages/SettingsLib/res/values-en-rCA/strings.xml b/packages/SettingsLib/res/values-en-rCA/strings.xml index 1a7d7c52c63c..f0eaeed5f885 100644 --- a/packages/SettingsLib/res/values-en-rCA/strings.xml +++ b/packages/SettingsLib/res/values-en-rCA/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"Can\'t scan for networks"</string> - <string name="wifi_security_none" msgid="7985461072596594400">"None"</string> <string name="wifi_remembered" msgid="4955746899347821096">"Saved"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"Disabled"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP Configuration Failure"</string> diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml index 1a7d7c52c63c..f0eaeed5f885 100644 --- a/packages/SettingsLib/res/values-en-rGB/strings.xml +++ b/packages/SettingsLib/res/values-en-rGB/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"Can\'t scan for networks"</string> - <string name="wifi_security_none" msgid="7985461072596594400">"None"</string> <string name="wifi_remembered" msgid="4955746899347821096">"Saved"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"Disabled"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP Configuration Failure"</string> diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml index 1a7d7c52c63c..f0eaeed5f885 100644 --- a/packages/SettingsLib/res/values-en-rIN/strings.xml +++ b/packages/SettingsLib/res/values-en-rIN/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"Can\'t scan for networks"</string> - <string name="wifi_security_none" msgid="7985461072596594400">"None"</string> <string name="wifi_remembered" msgid="4955746899347821096">"Saved"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"Disabled"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP Configuration Failure"</string> diff --git a/packages/SettingsLib/res/values-en-rXC/strings.xml b/packages/SettingsLib/res/values-en-rXC/strings.xml index 2bfd5b18004e..6927fda440e7 100644 --- a/packages/SettingsLib/res/values-en-rXC/strings.xml +++ b/packages/SettingsLib/res/values-en-rXC/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"Can\'t scan for networks"</string> - <string name="wifi_security_none" msgid="7985461072596594400">"None"</string> <string name="wifi_remembered" msgid="4955746899347821096">"Saved"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"Disabled"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP Configuration Failure"</string> diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml index 790c0d3e5aa0..675084fbed8d 100644 --- a/packages/SettingsLib/res/values-es-rUS/strings.xml +++ b/packages/SettingsLib/res/values-es-rUS/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"No se pueden buscar las redes."</string> - <string name="wifi_security_none" msgid="7985461072596594400">"Ninguna"</string> <string name="wifi_remembered" msgid="4955746899347821096">"Guardada"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"Inhabilitada"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"Error de configuración IP"</string> diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml index 1dec85d8f1e0..b51b84751def 100644 --- a/packages/SettingsLib/res/values-es/strings.xml +++ b/packages/SettingsLib/res/values-es/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"No se puede buscar redes."</string> - <string name="wifi_security_none" msgid="7985461072596594400">"Ninguna"</string> <string name="wifi_remembered" msgid="4955746899347821096">"Guardado"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"Inhabilitado"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"Error de configuración de IP"</string> diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml index 406e15d99c6e..fb077be51f4f 100644 --- a/packages/SettingsLib/res/values-et/strings.xml +++ b/packages/SettingsLib/res/values-et/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"Võrke ei saa kontrollida"</string> - <string name="wifi_security_none" msgid="7985461072596594400">"Puudub"</string> <string name="wifi_remembered" msgid="4955746899347821096">"Salvestatud"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"Keelatud"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP seadistamise ebaõnnestumine"</string> diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml index bd4724e4e002..3d3b8c324f77 100644 --- a/packages/SettingsLib/res/values-eu/strings.xml +++ b/packages/SettingsLib/res/values-eu/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"Ezin dira sareak bilatu"</string> - <string name="wifi_security_none" msgid="7985461072596594400">"Bat ere ez"</string> <string name="wifi_remembered" msgid="4955746899347821096">"Gordeta"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"Desgaituta"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"Ezin izan da konfiguratu IP helbidea"</string> diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml index 45b8ac7f52c4..0af118ec0ad8 100644 --- a/packages/SettingsLib/res/values-fa/strings.xml +++ b/packages/SettingsLib/res/values-fa/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"اسکن شبکهها امکانپذیر نیست"</string> - <string name="wifi_security_none" msgid="7985461072596594400">"هیچکدام"</string> <string name="wifi_remembered" msgid="4955746899347821096">"ذخیرهشده"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"غیرفعال شد"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"پیکربندی IP انجام نشد"</string> diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml index 23c63b133321..dde10d0d7fcb 100644 --- a/packages/SettingsLib/res/values-fi/strings.xml +++ b/packages/SettingsLib/res/values-fi/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"Verkkoja ei voi etsiä."</string> - <string name="wifi_security_none" msgid="7985461072596594400">"Ei mitään"</string> <string name="wifi_remembered" msgid="4955746899347821096">"Tallennettu"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"Pois käytöstä"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP-kokoonpanovirhe"</string> diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml index ad990000936d..1257ea53c0c0 100644 --- a/packages/SettingsLib/res/values-fr-rCA/strings.xml +++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"Impossible de rechercher des réseaux."</string> - <string name="wifi_security_none" msgid="7985461072596594400">"Aucune"</string> <string name="wifi_remembered" msgid="4955746899347821096">"Enregistré"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"Désactivés"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"Échec de configuration de l\'adresse IP"</string> @@ -227,7 +226,7 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="6893955536658137179">"Déclencher le codec audio Bluetooth LDAC\nSélection : qualité de lecture"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Diffusion : <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> <string name="select_private_dns_configuration_title" msgid="3700456559305263922">"DNS privé"</string> - <string name="select_private_dns_configuration_dialog_title" msgid="9221994415765826811">"Sélectionnez le mode DNS privé"</string> + <string name="select_private_dns_configuration_dialog_title" msgid="9221994415765826811">"Sélectionner le mode DNS privé"</string> <string name="private_dns_mode_off" msgid="8236575187318721684">"Désactivé"</string> <string name="private_dns_mode_opportunistic" msgid="8314986739896927399">"Automatique"</string> <string name="private_dns_mode_provider" msgid="8354935160639360804">"Nom d\'hôte du fournisseur DNS privé"</string> diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml index c23db251d9c0..444a52ea94b2 100644 --- a/packages/SettingsLib/res/values-fr/strings.xml +++ b/packages/SettingsLib/res/values-fr/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"Impossible de rechercher des réseaux."</string> - <string name="wifi_security_none" msgid="7985461072596594400">"Aucune"</string> <string name="wifi_remembered" msgid="4955746899347821096">"Enregistré"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"Désactivé"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"Échec de configuration de l\'adresse IP"</string> @@ -70,7 +69,7 @@ <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"Actif"</string> <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Multimédia"</string> <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Appels téléphoniques"</string> - <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Transfert de fichier"</string> + <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Transfert de fichiers"</string> <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Périphérique d\'entrée"</string> <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Accès Internet"</string> <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Partage de contacts"</string> diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml index 46532e9d4233..8df269719ef6 100644 --- a/packages/SettingsLib/res/values-gl/strings.xml +++ b/packages/SettingsLib/res/values-gl/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"Non se poden explorar redes"</string> - <string name="wifi_security_none" msgid="7985461072596594400">"Ningunha"</string> <string name="wifi_remembered" msgid="4955746899347821096">"Gardada"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"Desactivadas"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"Erro na configuración de IP"</string> diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml index 6a7449047c08..4a92f2a4a8e8 100644 --- a/packages/SettingsLib/res/values-gu/strings.xml +++ b/packages/SettingsLib/res/values-gu/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"નેટવર્ક્સ માટે સ્કૅન કરી શકતા નથી"</string> - <string name="wifi_security_none" msgid="7985461072596594400">"કોઈ નહીં"</string> <string name="wifi_remembered" msgid="4955746899347821096">"સાચવેલા"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"અક્ષમ કર્યો"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP કન્ફિગરેશન નિષ્ફળ"</string> diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml index bd9a6ec335b7..6d88c3587597 100644 --- a/packages/SettingsLib/res/values-hi/strings.xml +++ b/packages/SettingsLib/res/values-hi/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"नेटवर्क के लिए स्कैन नहीं कर सकता"</string> - <string name="wifi_security_none" msgid="7985461072596594400">"कोई नहीं"</string> <string name="wifi_remembered" msgid="4955746899347821096">"सेव किया गया"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"अक्षम"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP कॉन्फ़िगरेशन की विफलता"</string> diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml index 52705313d0f0..32c9a620b3fb 100644 --- a/packages/SettingsLib/res/values-hr/strings.xml +++ b/packages/SettingsLib/res/values-hr/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"Skeniranje mreža nije moguće"</string> - <string name="wifi_security_none" msgid="7985461072596594400">"Nema"</string> <string name="wifi_remembered" msgid="4955746899347821096">"Spremljeno"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"Onemogućeno"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"Konfiguracija IP-a nije uspjela"</string> diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml index ad897f82b93f..ed19267f342b 100644 --- a/packages/SettingsLib/res/values-hu/strings.xml +++ b/packages/SettingsLib/res/values-hu/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"Nem lehet beolvasni a hálózatokat"</string> - <string name="wifi_security_none" msgid="7985461072596594400">"Nincs"</string> <string name="wifi_remembered" msgid="4955746899347821096">"Mentve"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"Letiltva"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP-konfigurációs hiba"</string> diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml index 82755f990432..6d516ea3d760 100644 --- a/packages/SettingsLib/res/values-hy/strings.xml +++ b/packages/SettingsLib/res/values-hy/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"Հնարավոր չէ սկանավորել ցանցերը"</string> - <string name="wifi_security_none" msgid="7985461072596594400">"Ոչ մեկը"</string> <string name="wifi_remembered" msgid="4955746899347821096">"Պահված է"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"Անջատված"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP կարգավորման ձախողում"</string> diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml index 961f892df571..a5f2317bba7c 100644 --- a/packages/SettingsLib/res/values-in/strings.xml +++ b/packages/SettingsLib/res/values-in/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"Tidak dapat memindai jaringan"</string> - <string name="wifi_security_none" msgid="7985461072596594400">"Tidak ada"</string> <string name="wifi_remembered" msgid="4955746899347821096">"Disimpan"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"Nonaktif"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"Kegagalan Konfigurasi IP"</string> diff --git a/packages/SettingsLib/res/values-is/strings.xml b/packages/SettingsLib/res/values-is/strings.xml index 759b7ba89562..6cf09a615eb7 100644 --- a/packages/SettingsLib/res/values-is/strings.xml +++ b/packages/SettingsLib/res/values-is/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"Ekki er hægt að leita að netum"</string> - <string name="wifi_security_none" msgid="7985461072596594400">"Ekkert"</string> <string name="wifi_remembered" msgid="4955746899347821096">"Vistað"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"Óvirkt"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP-stillingarvilla"</string> diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml index bd41e28210b4..a1b9b82eddf4 100644 --- a/packages/SettingsLib/res/values-it/strings.xml +++ b/packages/SettingsLib/res/values-it/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"Impossibile cercare reti"</string> - <string name="wifi_security_none" msgid="7985461072596594400">"Nessuna"</string> <string name="wifi_remembered" msgid="4955746899347821096">"Salvata"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"Disattivata"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"Errore configurazione IP"</string> diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml index 5da253c2d4bb..1a5062200d77 100644 --- a/packages/SettingsLib/res/values-iw/strings.xml +++ b/packages/SettingsLib/res/values-iw/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"לא ניתן לסרוק לאיתור רשתות"</string> - <string name="wifi_security_none" msgid="7985461072596594400">"ללא"</string> <string name="wifi_remembered" msgid="4955746899347821096">"נשמר"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"מושבת"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"כשל בתצורת IP"</string> @@ -316,7 +315,7 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"מגבלה של תהליכים ברקע"</string> <string name="show_all_anrs" msgid="4924885492787069007">"הצגת מקרי ANR ברקע"</string> <string name="show_all_anrs_summary" msgid="6636514318275139826">"הצגת תיבת דו-שיח של \'אפליקציה לא מגיבה\' עבור אפליקציות שפועלות ברקע"</string> - <string name="show_notification_channel_warnings" msgid="1399948193466922683">"אזהרות לגבי ערוץ הודעות"</string> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"אזהרות לגבי ערוץ התראות"</string> <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"הצגת אזהרה כשאפליקציה שולחת התראה ללא ערוץ חוקי"</string> <string name="force_allow_on_external" msgid="3215759785081916381">"אילוץ הרשאת אפליקציות באחסון חיצוני"</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"מאפשר כתיבה של כל אפליקציה באחסון חיצוני, ללא התחשבות בערכי המניפסט"</string> diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml index f6b81ed32793..4c544af39fd0 100644 --- a/packages/SettingsLib/res/values-ja/strings.xml +++ b/packages/SettingsLib/res/values-ja/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"ネットワークをスキャンできません"</string> - <string name="wifi_security_none" msgid="7985461072596594400">"なし"</string> <string name="wifi_remembered" msgid="4955746899347821096">"保存済み"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"無効"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP設定エラー"</string> @@ -436,7 +435,7 @@ <string name="cancel" msgid="6859253417269739139">"キャンセル"</string> <string name="okay" msgid="1997666393121016642">"OK"</string> <string name="zen_mode_enable_dialog_turn_on" msgid="8287824809739581837">"ON にする"</string> - <string name="zen_mode_settings_turn_on_dialog_title" msgid="2297134204747331078">"マナーモードを ON にする"</string> + <string name="zen_mode_settings_turn_on_dialog_title" msgid="2297134204747331078">"サイレント モードを ON にする"</string> <string name="zen_mode_settings_summary_off" msgid="6119891445378113334">"なし"</string> <string name="zen_interruption_level_priority" msgid="2078370238113347720">"優先的な通知のみ"</string> <string name="zen_mode_and_condition" msgid="4927230238450354412">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>。<xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string> diff --git a/packages/SettingsLib/res/values-ka/strings.xml b/packages/SettingsLib/res/values-ka/strings.xml index d5f54088cb48..92f304960f59 100644 --- a/packages/SettingsLib/res/values-ka/strings.xml +++ b/packages/SettingsLib/res/values-ka/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"ქსელების სკანირება არა არის შესაძლებელი"</string> - <string name="wifi_security_none" msgid="7985461072596594400">"არცერთი"</string> <string name="wifi_remembered" msgid="4955746899347821096">"დამახსოვრებულია"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"გამორთულია"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP კონფიგურაციის შეფერხება"</string> diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml index c3fbfcd79d7c..b56c6fd1c39d 100644 --- a/packages/SettingsLib/res/values-kk/strings.xml +++ b/packages/SettingsLib/res/values-kk/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"Желілерді шолу мүмкін емес"</string> - <string name="wifi_security_none" msgid="7985461072596594400">"Ешқандай"</string> <string name="wifi_remembered" msgid="4955746899347821096">"Сақталды"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"Өшірілген"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP конфигурациясының қатесі"</string> diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml index 8e73f81b5d3a..58604731a258 100644 --- a/packages/SettingsLib/res/values-km/strings.xml +++ b/packages/SettingsLib/res/values-km/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"មិនអាចវិភាគរកបណ្ដាញ"</string> - <string name="wifi_security_none" msgid="7985461072596594400">"គ្មាន"</string> <string name="wifi_remembered" msgid="4955746899347821096">"បានរក្សាទុក"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"បានបិទ"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"ការកំណត់រចនាសម្ព័ន្ធ IP បរាជ័យ"</string> diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml index ce225eaeeb85..87e18e68750c 100644 --- a/packages/SettingsLib/res/values-kn/strings.xml +++ b/packages/SettingsLib/res/values-kn/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"ನೆಟ್ವರ್ಕ್ಗಳಿಗಾಗಿ ಸ್ಕ್ಯಾನ್ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ"</string> - <string name="wifi_security_none" msgid="7985461072596594400">"ಯಾವುದೂ ಇಲ್ಲ"</string> <string name="wifi_remembered" msgid="4955746899347821096">"ಉಳಿಸಲಾಗಿದೆ"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP ಕಾನ್ಫಿಗರೇಶನ್ ವಿಫಲತೆ"</string> diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml index b47471b18df7..3333c0dd05d2 100644 --- a/packages/SettingsLib/res/values-ko/strings.xml +++ b/packages/SettingsLib/res/values-ko/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"네트워크를 검색할 수 없습니다."</string> - <string name="wifi_security_none" msgid="7985461072596594400">"없음"</string> <string name="wifi_remembered" msgid="4955746899347821096">"저장됨"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"사용 중지됨"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP 설정 실패"</string> diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml index 9853dac4e4e8..cbbc47c1b3cf 100644 --- a/packages/SettingsLib/res/values-ky/strings.xml +++ b/packages/SettingsLib/res/values-ky/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"Түйүндөрдү издөө мүмкүн эмес"</string> - <string name="wifi_security_none" msgid="7985461072596594400">"Жок"</string> <string name="wifi_remembered" msgid="4955746899347821096">"Сакталды"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"Өчүрүлгөн"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP конфигурациясы бузулду"</string> diff --git a/packages/SettingsLib/res/values-lo/strings.xml b/packages/SettingsLib/res/values-lo/strings.xml index 1816515e6bd2..21e4679b9019 100644 --- a/packages/SettingsLib/res/values-lo/strings.xml +++ b/packages/SettingsLib/res/values-lo/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"ບໍ່ສາມາດກວດຫາເຄືອຂ່າຍໄດ້"</string> - <string name="wifi_security_none" msgid="7985461072596594400">"ບໍ່ໃຊ້"</string> <string name="wifi_remembered" msgid="4955746899347821096">"ບັນທຶກແລ້ວ"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"ປິດການນຳໃຊ້"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"ການຕັ້ງຄ່າ IP ລົ້ມເຫຼວ"</string> diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml index e6a8e1c71d7e..cbff9e745965 100644 --- a/packages/SettingsLib/res/values-lt/strings.xml +++ b/packages/SettingsLib/res/values-lt/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"Nepavyksta nuskaityti tinklų"</string> - <string name="wifi_security_none" msgid="7985461072596594400">"Nėra"</string> <string name="wifi_remembered" msgid="4955746899347821096">"Išsaugotas"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"Neleidžiama"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP konfigūracijos triktis"</string> diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml index b55afc0f36ca..d200828f6933 100644 --- a/packages/SettingsLib/res/values-lv/strings.xml +++ b/packages/SettingsLib/res/values-lv/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"Nevar skenēt tīklus"</string> - <string name="wifi_security_none" msgid="7985461072596594400">"Nav"</string> <string name="wifi_remembered" msgid="4955746899347821096">"Saglabāts"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"Atspējots"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP konfigurācijas kļūme"</string> diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml index e28c8ee0c596..db16847bd07c 100644 --- a/packages/SettingsLib/res/values-mk/strings.xml +++ b/packages/SettingsLib/res/values-mk/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"Не може да скенира за мрежи"</string> - <string name="wifi_security_none" msgid="7985461072596594400">"Ниедна"</string> <string name="wifi_remembered" msgid="4955746899347821096">"Зачувано"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"Оневозможено"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"Конфигурирањето ИП не успеа"</string> diff --git a/packages/SettingsLib/res/values-ml/strings.xml b/packages/SettingsLib/res/values-ml/strings.xml index 686039811e2f..c3af9684db4c 100644 --- a/packages/SettingsLib/res/values-ml/strings.xml +++ b/packages/SettingsLib/res/values-ml/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"നെറ്റ്വർക്കുകൾക്കായി സ്കാൻ ചെയ്യാനായില്ല"</string> - <string name="wifi_security_none" msgid="7985461072596594400">"ഒന്നുമില്ല"</string> <string name="wifi_remembered" msgid="4955746899347821096">"സംരക്ഷിച്ചു"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"പ്രവർത്തനരഹിതമാക്കി"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP കോൺഫിഗറേഷൻ പരാജയം"</string> diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml index ba6d60199224..8627e1b3b2b5 100644 --- a/packages/SettingsLib/res/values-mn/strings.xml +++ b/packages/SettingsLib/res/values-mn/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"Сүлжээнүүдийг скан хийх боломжгүй"</string> - <string name="wifi_security_none" msgid="7985461072596594400">"Байхгүй"</string> <string name="wifi_remembered" msgid="4955746899347821096">"Хадгалагдсан"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"Идэвхгүйжүүлсэн"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP тохируулга амжилтгүй"</string> diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml index a5d230adcc20..cd7f175eabc0 100644 --- a/packages/SettingsLib/res/values-mr/strings.xml +++ b/packages/SettingsLib/res/values-mr/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"नेटवर्कसाठी स्कॅन करू शकत नाही"</string> - <string name="wifi_security_none" msgid="7985461072596594400">"काहीही नाही"</string> <string name="wifi_remembered" msgid="4955746899347821096">"सेव्ह केले"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"अक्षम"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP कॉन्फिगरेशन अयशस्वी"</string> diff --git a/packages/SettingsLib/res/values-ms/strings.xml b/packages/SettingsLib/res/values-ms/strings.xml index a7ac3ef09c2e..d0b2e12b16b1 100644 --- a/packages/SettingsLib/res/values-ms/strings.xml +++ b/packages/SettingsLib/res/values-ms/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"Tidak boleh mengimbas untuk rangkaian"</string> - <string name="wifi_security_none" msgid="7985461072596594400">"Tiada"</string> <string name="wifi_remembered" msgid="4955746899347821096">"Disimpan"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"Dinyahdayakan"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"Kegagalan Konfigurasi IP"</string> diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml index 6cdab67ab819..5f5957c46471 100644 --- a/packages/SettingsLib/res/values-my/strings.xml +++ b/packages/SettingsLib/res/values-my/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"ကွန်ယက်များကို စကင်မလုပ်နိုင်ပါ"</string> - <string name="wifi_security_none" msgid="7985461072596594400">"တစ်ခုမျှ မဟုတ်ပါ"</string> <string name="wifi_remembered" msgid="4955746899347821096">"သိမ်းဆည်းပြီး"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"ပိတ်ထားသည်"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP ပြုပြင်ခြင်း မအောင်မြင်ပါ"</string> diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml index cf18477fb01e..3c240f8ecd6e 100644 --- a/packages/SettingsLib/res/values-nb/strings.xml +++ b/packages/SettingsLib/res/values-nb/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"Kan ikke søke etter nettverk"</string> - <string name="wifi_security_none" msgid="7985461072596594400">"Ingen"</string> <string name="wifi_remembered" msgid="4955746899347821096">"Lagret"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"Slått av"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP-konfigurasjonsfeil"</string> diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml index 8aba0f8ee151..1699870e1ecf 100644 --- a/packages/SettingsLib/res/values-ne/strings.xml +++ b/packages/SettingsLib/res/values-ne/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"सञ्जालका लागि स्क्यान गर्न सक्दैन"</string> - <string name="wifi_security_none" msgid="7985461072596594400">"कुनै पनि होइन"</string> <string name="wifi_remembered" msgid="4955746899347821096">"सुरक्षित गरियो"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"असक्षम पारियो"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP विन्यास असफल"</string> diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml index e3f1aead7d84..738df94f47fd 100644 --- a/packages/SettingsLib/res/values-nl/strings.xml +++ b/packages/SettingsLib/res/values-nl/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"Kan niet zoeken naar netwerken"</string> - <string name="wifi_security_none" msgid="7985461072596594400">"Geen"</string> <string name="wifi_remembered" msgid="4955746899347821096">"Opgeslagen"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"Uitgeschakeld"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP-configuratie mislukt"</string> diff --git a/packages/SettingsLib/res/values-or/strings.xml b/packages/SettingsLib/res/values-or/strings.xml index 8ecac4d59727..2d39cc6df105 100644 --- a/packages/SettingsLib/res/values-or/strings.xml +++ b/packages/SettingsLib/res/values-or/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"ନେଟ୍ୱର୍କଗୁଡ଼ିକୁ ଖୋଜିପାରୁନାହିଁ"</string> - <string name="wifi_security_none" msgid="7985461072596594400">"କିଛି ନାହିଁ"</string> <string name="wifi_remembered" msgid="4955746899347821096">"ସେଭ୍ ହୋଇଗଲା"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"ଅକ୍ଷମ ହୋଇଛି"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP କନଫିଗରେଶନ ବିଫଳ ହୋଇଛି"</string> diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml index 6f17e134bda5..61f04470a03e 100644 --- a/packages/SettingsLib/res/values-pa/strings.xml +++ b/packages/SettingsLib/res/values-pa/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"ਨੈਟਵਰਕਾਂ ਲਈ ਸਕੈਨ ਨਹੀਂ ਕਰ ਸਕਦਾ"</string> - <string name="wifi_security_none" msgid="7985461072596594400">"ਕੋਈ ਨਹੀਂ"</string> <string name="wifi_remembered" msgid="4955746899347821096">"ਰੱਖਿਅਤ ਕੀਤਾ"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"ਅਯੋਗ ਬਣਾਇਆ"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP ਕੌਂਫਿਗਰੇਸ਼ਨ ਅਸਫਲਤਾ"</string> diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml index 3c208e3bbe2b..519f82cf5275 100644 --- a/packages/SettingsLib/res/values-pl/strings.xml +++ b/packages/SettingsLib/res/values-pl/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"Nie można wyszukać sieci."</string> - <string name="wifi_security_none" msgid="7985461072596594400">"Brak"</string> <string name="wifi_remembered" msgid="4955746899347821096">"Zapisana"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"Wyłączona"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"Błąd konfiguracji IP"</string> diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml index 5c363a415f79..16844a2ec063 100644 --- a/packages/SettingsLib/res/values-pt-rBR/strings.xml +++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"Não é possível verificar a existência de redes"</string> - <string name="wifi_security_none" msgid="7985461072596594400">"Nenhuma"</string> <string name="wifi_remembered" msgid="4955746899347821096">"Salva"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"Desativado"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"Falha de configuração de IP"</string> @@ -227,7 +226,7 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="6893955536658137179">"Acionar seleção de codec de áudio\nBluetooth LDAC: qualidade de reprodução"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Streaming: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> <string name="select_private_dns_configuration_title" msgid="3700456559305263922">"DNS particular"</string> - <string name="select_private_dns_configuration_dialog_title" msgid="9221994415765826811">"Selecione o modo DNS particular"</string> + <string name="select_private_dns_configuration_dialog_title" msgid="9221994415765826811">"Selecione o modo de DNS particular"</string> <string name="private_dns_mode_off" msgid="8236575187318721684">"Desativado"</string> <string name="private_dns_mode_opportunistic" msgid="8314986739896927399">"Automático"</string> <string name="private_dns_mode_provider" msgid="8354935160639360804">"Nome do host do provedor de DNS particular"</string> diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml index 66c59ac0b9bf..f01ddfa54d80 100644 --- a/packages/SettingsLib/res/values-pt-rPT/strings.xml +++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"Não é possível verificar redes"</string> - <string name="wifi_security_none" msgid="7985461072596594400">"Nenhuma"</string> <string name="wifi_remembered" msgid="4955746899347821096">"Guardada"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"Desativado"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"Falha de configuração de IP"</string> @@ -278,7 +277,7 @@ <string name="media_category" msgid="4388305075496848353">"Multimédia"</string> <string name="debug_monitoring_category" msgid="7640508148375798343">"Monitorização"</string> <string name="strict_mode" msgid="1938795874357830695">"Modo rigoroso ativado"</string> - <string name="strict_mode_summary" msgid="142834318897332338">"Piscar ecrã se aplic. fazem oper. prolong. no tópico princ."</string> + <string name="strict_mode_summary" msgid="142834318897332338">"Piscar ecrã se app fazem oper. prolong. no tópico princ."</string> <string name="pointer_location" msgid="6084434787496938001">"Localização do ponteiro"</string> <string name="pointer_location_summary" msgid="840819275172753713">"Apresentar dados atuais de toque"</string> <string name="show_touches" msgid="2642976305235070316">"Mostrar toques"</string> @@ -305,7 +304,7 @@ <string name="show_non_rect_clip" msgid="505954950474595172">"Depurar operações de clipe não retangulares"</string> <string name="track_frame_time" msgid="6094365083096851167">"Renderiz. HWUI do perfil"</string> <string name="enable_gpu_debug_layers" msgid="3848838293793255097">"Ativar cam. depuração GPU"</string> - <string name="enable_gpu_debug_layers_summary" msgid="8009136940671194940">"Permitir carreg. cam. depuração GPU p/ dep. aplic."</string> + <string name="enable_gpu_debug_layers_summary" msgid="8009136940671194940">"Permitir carreg. cam. depuração GPU p/ dep. app"</string> <string name="window_animation_scale_title" msgid="6162587588166114700">"Escala de anim. da janela"</string> <string name="transition_animation_scale_title" msgid="387527540523595875">"Escala de anim. de trans."</string> <string name="animator_duration_scale_title" msgid="3406722410819934083">"Esc. de duração do anim."</string> diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml index 5c363a415f79..16844a2ec063 100644 --- a/packages/SettingsLib/res/values-pt/strings.xml +++ b/packages/SettingsLib/res/values-pt/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"Não é possível verificar a existência de redes"</string> - <string name="wifi_security_none" msgid="7985461072596594400">"Nenhuma"</string> <string name="wifi_remembered" msgid="4955746899347821096">"Salva"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"Desativado"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"Falha de configuração de IP"</string> @@ -227,7 +226,7 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="6893955536658137179">"Acionar seleção de codec de áudio\nBluetooth LDAC: qualidade de reprodução"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"Streaming: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> <string name="select_private_dns_configuration_title" msgid="3700456559305263922">"DNS particular"</string> - <string name="select_private_dns_configuration_dialog_title" msgid="9221994415765826811">"Selecione o modo DNS particular"</string> + <string name="select_private_dns_configuration_dialog_title" msgid="9221994415765826811">"Selecione o modo de DNS particular"</string> <string name="private_dns_mode_off" msgid="8236575187318721684">"Desativado"</string> <string name="private_dns_mode_opportunistic" msgid="8314986739896927399">"Automático"</string> <string name="private_dns_mode_provider" msgid="8354935160639360804">"Nome do host do provedor de DNS particular"</string> diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml index 703add617db1..8a7b4401217c 100644 --- a/packages/SettingsLib/res/values-ro/strings.xml +++ b/packages/SettingsLib/res/values-ro/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"Nu se poate scana pentru rețele"</string> - <string name="wifi_security_none" msgid="7985461072596594400">"Niciuna"</string> <string name="wifi_remembered" msgid="4955746899347821096">"Salvată"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"Dezactivată"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"Eroare de configurație IP"</string> diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml index 4eb3ca480743..31274d1c378a 100644 --- a/packages/SettingsLib/res/values-ru/strings.xml +++ b/packages/SettingsLib/res/values-ru/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"Не удалось начать поиск сетей."</string> - <string name="wifi_security_none" msgid="7985461072596594400">"Нет"</string> <string name="wifi_remembered" msgid="4955746899347821096">"Сохранено"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"Отключено"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"Ошибка IP-конфигурации"</string> diff --git a/packages/SettingsLib/res/values-si/strings.xml b/packages/SettingsLib/res/values-si/strings.xml index 1ab5b794951e..b22e0689ef3a 100644 --- a/packages/SettingsLib/res/values-si/strings.xml +++ b/packages/SettingsLib/res/values-si/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"ජාල සඳහා පරිලෝකනය කළ නොහැක"</string> - <string name="wifi_security_none" msgid="7985461072596594400">"කිසිවක් නැත"</string> <string name="wifi_remembered" msgid="4955746899347821096">"සුරකින ලදි"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"අබලයි"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP වින්යාස කිරීම අසාර්ථකයි"</string> diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml index 5c3920fdb74b..43923b87d6a7 100644 --- a/packages/SettingsLib/res/values-sk/strings.xml +++ b/packages/SettingsLib/res/values-sk/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"Siete sa nedajú vyhľadávať"</string> - <string name="wifi_security_none" msgid="7985461072596594400">"Žiadne"</string> <string name="wifi_remembered" msgid="4955746899347821096">"Uložené"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"Vypnuté"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"Zlyhanie konfigurácie adresy IP"</string> @@ -438,7 +437,7 @@ <string name="cancel" msgid="6859253417269739139">"Zrušiť"</string> <string name="okay" msgid="1997666393121016642">"OK"</string> <string name="zen_mode_enable_dialog_turn_on" msgid="8287824809739581837">"Zapnúť"</string> - <string name="zen_mode_settings_turn_on_dialog_title" msgid="2297134204747331078">"Zapnite režim Nerušiť"</string> + <string name="zen_mode_settings_turn_on_dialog_title" msgid="2297134204747331078">"Zapnite režim bez vyrušení"</string> <string name="zen_mode_settings_summary_off" msgid="6119891445378113334">"Nikdy"</string> <string name="zen_interruption_level_priority" msgid="2078370238113347720">"Iba prioritné"</string> <string name="zen_mode_and_condition" msgid="4927230238450354412">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string> diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml index f4794051f635..6d392fe2e57e 100644 --- a/packages/SettingsLib/res/values-sl/strings.xml +++ b/packages/SettingsLib/res/values-sl/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"Ni mogoče iskati omrežij"</string> - <string name="wifi_security_none" msgid="7985461072596594400">"Brez"</string> <string name="wifi_remembered" msgid="4955746899347821096">"Shranjeno"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"Onemogočeno"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"Konfiguracija IP-ja ni uspela"</string> diff --git a/packages/SettingsLib/res/values-sq/strings.xml b/packages/SettingsLib/res/values-sq/strings.xml index 274198584bf6..e05a01953904 100644 --- a/packages/SettingsLib/res/values-sq/strings.xml +++ b/packages/SettingsLib/res/values-sq/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"Nuk mund të skanojë për rrjete"</string> - <string name="wifi_security_none" msgid="7985461072596594400">"Asnjë"</string> <string name="wifi_remembered" msgid="4955746899347821096">"U ruajt"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"Të çaktivizuara"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"Dështim në konfigurimin e IP-së"</string> diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml index 241d9cb0d7f0..371b909d987b 100644 --- a/packages/SettingsLib/res/values-sr/strings.xml +++ b/packages/SettingsLib/res/values-sr/strings.xml @@ -21,13 +21,12 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"Није могуће скенирати мреже"</string> - <string name="wifi_security_none" msgid="7985461072596594400">"Нема"</string> <string name="wifi_remembered" msgid="4955746899347821096">"Сачувано"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"Онемогућено"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP конфигурација је отказала"</string> <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"Није повезано због лошег квалитета мреже"</string> <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"Wi-Fi веза је отказала"</string> - <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"Проблем са потврдом аутентичности"</string> + <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"Проблем са потврдом идентитета"</string> <string name="wifi_cant_connect" msgid="5410016875644565884">"Повезивање није успело"</string> <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"Повезивање са „<xliff:g id="AP_NAME">%1$s</xliff:g>“ није успело"</string> <string name="wifi_check_password_try_again" msgid="516958988102584767">"Проверите лозинку и пробајте поново"</string> @@ -448,5 +447,5 @@ <string name="zen_mode_duration_settings_title" msgid="229547412251222757">"Трајање"</string> <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"Увек питај"</string> <string name="zen_mode_forever" msgid="2704305038191592967">"Док не искључите"</string> - <string name="time_unit_just_now" msgid="6363336622778342422">"Управо сада"</string> + <string name="time_unit_just_now" msgid="6363336622778342422">"Управо"</string> </resources> diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml index d338e9615a08..e6872bb35d8a 100644 --- a/packages/SettingsLib/res/values-sv/strings.xml +++ b/packages/SettingsLib/res/values-sv/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"Det går inte att söka efter nätverk"</string> - <string name="wifi_security_none" msgid="7985461072596594400">"Ingen"</string> <string name="wifi_remembered" msgid="4955746899347821096">"Sparat"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"Inaktiverad"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP-konfigurationsfel"</string> diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml index d693077737e2..23efb916c4ca 100644 --- a/packages/SettingsLib/res/values-sw/strings.xml +++ b/packages/SettingsLib/res/values-sw/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"Haiwezi kutambaza mitandao"</string> - <string name="wifi_security_none" msgid="7985461072596594400">"Hamna"</string> <string name="wifi_remembered" msgid="4955746899347821096">"Imehifadhiwa"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"Imezimwa"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"Haikuweza Kusanidi IP"</string> diff --git a/packages/SettingsLib/res/values-ta/strings.xml b/packages/SettingsLib/res/values-ta/strings.xml index 8f5c7d8bf273..53ba7386c9ae 100644 --- a/packages/SettingsLib/res/values-ta/strings.xml +++ b/packages/SettingsLib/res/values-ta/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"நெட்வொர்க்குகளுக்கு ஸ்கேன் செய்யப்படவில்லை"</string> - <string name="wifi_security_none" msgid="7985461072596594400">"ஏதுமில்லை"</string> <string name="wifi_remembered" msgid="4955746899347821096">"சேமிக்கப்பட்டது"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"முடக்கப்பட்டது"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP உள்ளமைவில் தோல்வி"</string> diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml index 5f7ab99678c4..c8c6b4ce69f6 100644 --- a/packages/SettingsLib/res/values-te/strings.xml +++ b/packages/SettingsLib/res/values-te/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"నెట్వర్క్ల కోసం స్కాన్ చేయడం సాధ్యపడదు"</string> - <string name="wifi_security_none" msgid="7985461072596594400">"ఏదీ లేదు"</string> <string name="wifi_remembered" msgid="4955746899347821096">"సేవ్ చేయబడింది"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"నిలిపివేయబడింది"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP కాన్ఫిగరేషన్ వైఫల్యం"</string> diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml index 020baf024435..d293d590f1a2 100644 --- a/packages/SettingsLib/res/values-th/strings.xml +++ b/packages/SettingsLib/res/values-th/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"ไม่สามารถสแกนหาเครือข่าย"</string> - <string name="wifi_security_none" msgid="7985461072596594400">"ไม่มี"</string> <string name="wifi_remembered" msgid="4955746899347821096">"บันทึกแล้ว"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"ปิดอยู่"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"การกำหนดค่า IP ล้มเหลว"</string> diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml index 2164ade839d9..9da4561c65b6 100644 --- a/packages/SettingsLib/res/values-tl/strings.xml +++ b/packages/SettingsLib/res/values-tl/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"Hindi makapag-scan ng mga network"</string> - <string name="wifi_security_none" msgid="7985461072596594400">"Wala"</string> <string name="wifi_remembered" msgid="4955746899347821096">"Na-save"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"Naka-disable"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"Pagkabigo ng Configuration ng IP"</string> @@ -374,7 +373,7 @@ <string name="power_discharge_by_enhanced" msgid="2095821536747992464">"Tatagal dapat nang hanggang humigit-kumulang <xliff:g id="TIME">%1$s</xliff:g> batay sa iyong paggamit (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only_enhanced" msgid="2175151772952365149">"Tatagal dapat nang hanggang humigit-kumulang <xliff:g id="TIME">%1$s</xliff:g> batay sa iyong paggamit"</string> <string name="power_discharge_by" msgid="6453537733650125582">"Tatagal dapat nang hanggang humigit-kumulang <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_discharge_by_only" msgid="107616694963545745">"Tatagal dapat nang hanggang humigit-kumulang <xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="power_discharge_by_only" msgid="107616694963545745">"Tatagal hanggang mga <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"Wala nang <xliff:g id="THRESHOLD">%1$s</xliff:g> ang natitira"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"Wala nang <xliff:g id="THRESHOLD">%1$s</xliff:g> ang natitira (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"Mahigit <xliff:g id="TIME_REMAINING">%1$s</xliff:g> pa ang natitira (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml index 532927cb0327..2d5cd7f36f55 100644 --- a/packages/SettingsLib/res/values-tr/strings.xml +++ b/packages/SettingsLib/res/values-tr/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"Ağlar taranamıyor"</string> - <string name="wifi_security_none" msgid="7985461072596594400">"Yok"</string> <string name="wifi_remembered" msgid="4955746899347821096">"Kaydedildi"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"Devre dışı"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP Yapılandırması Hatası"</string> diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml index cf26d20df357..512ea86da467 100644 --- a/packages/SettingsLib/res/values-uk/strings.xml +++ b/packages/SettingsLib/res/values-uk/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"Неможливо здійснити сканування мереж"</string> - <string name="wifi_security_none" msgid="7985461072596594400">"Немає"</string> <string name="wifi_remembered" msgid="4955746899347821096">"Збережено"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"Вимкнено"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"Помилка конфігурації IP-адреси"</string> diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml index c158179ccaa5..84ad3ed16410 100644 --- a/packages/SettingsLib/res/values-ur/strings.xml +++ b/packages/SettingsLib/res/values-ur/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"نیٹ ورکس کیلئے اسکین نہيں کر سکتے ہیں"</string> - <string name="wifi_security_none" msgid="7985461072596594400">"کوئی نہیں"</string> <string name="wifi_remembered" msgid="4955746899347821096">"محفوظ کردیا گیا"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"غیر فعال"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP کنفیگریشن کی ناکامی"</string> diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml index ac8bffed12ac..af2ada59c770 100644 --- a/packages/SettingsLib/res/values-uz/strings.xml +++ b/packages/SettingsLib/res/values-uz/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"Tarmoqlarni tekshirib chiqishni iloji bo‘lmadi"</string> - <string name="wifi_security_none" msgid="7985461072596594400">"Hech qanday"</string> <string name="wifi_remembered" msgid="4955746899347821096">"Saqlandi"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"O‘chiq"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP manzilini sozlab bo‘lmadi"</string> diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml index 78306dab1c00..f454127547ea 100644 --- a/packages/SettingsLib/res/values-vi/strings.xml +++ b/packages/SettingsLib/res/values-vi/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"Không thể dò tìm mạng"</string> - <string name="wifi_security_none" msgid="7985461072596594400">"Không"</string> <string name="wifi_remembered" msgid="4955746899347821096">"Đã lưu"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"Đã tắt"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"Lỗi cấu hình IP"</string> diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml index 4fb261004b27..10a20bef083f 100644 --- a/packages/SettingsLib/res/values-zh-rCN/strings.xml +++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"无法扫描网络"</string> - <string name="wifi_security_none" msgid="7985461072596594400">"无"</string> <string name="wifi_remembered" msgid="4955746899347821096">"已保存"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"已停用"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP 配置失败"</string> diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml index c5a8f92074af..15105453c5b6 100644 --- a/packages/SettingsLib/res/values-zh-rHK/strings.xml +++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"無法掃瞄網絡"</string> - <string name="wifi_security_none" msgid="7985461072596594400">"無"</string> <string name="wifi_remembered" msgid="4955746899347821096">"已儲存"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"已停用"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP 設定失敗"</string> diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml index 0947ccec38ed..90c0d808cd08 100644 --- a/packages/SettingsLib/res/values-zh-rTW/strings.xml +++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"無法掃描網路"</string> - <string name="wifi_security_none" msgid="7985461072596594400">"無"</string> <string name="wifi_remembered" msgid="4955746899347821096">"已儲存"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"已停用"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP 設定失敗"</string> diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml index cd90d745123b..e4f9f4d77733 100644 --- a/packages/SettingsLib/res/values-zu/strings.xml +++ b/packages/SettingsLib/res/values-zu/strings.xml @@ -21,7 +21,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="wifi_fail_to_scan" msgid="1265540342578081461">"Ayikwazi ukuhlola amanethiwekhi"</string> - <string name="wifi_security_none" msgid="7985461072596594400">"Lutho"</string> <string name="wifi_remembered" msgid="4955746899347821096">"Kulondoloziwe"</string> <string name="wifi_disabled_generic" msgid="4259794910584943386">"Akusebenzi"</string> <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"Ukwehluleka kokulungiswa kwe-IP"</string> diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml index c9bcd65f8d0d..2823149a1585 100644 --- a/packages/SettingsLib/res/values/strings.xml +++ b/packages/SettingsLib/res/values/strings.xml @@ -39,8 +39,8 @@ <!-- Do not translate. Concise terminology for wifi with 802.1x EAP Suite-B security --> <string name="wifi_security_short_eap_suiteb" translatable="false">Suite-B</string> - <!-- Used in Wi-Fi settings dialogs when Wi-Fi does not have any security. --> - <string name="wifi_security_none" translatable="false">None</string> + <!-- Used in Wi-Fi settings dialogs when Wi-Fi does not have any security. [CHAR LIMIT=40] --> + <string name="wifi_security_none">None</string> <!-- Do not translate. Terminology for wifi with WEP security --> <string name="wifi_security_wep" translatable="false">WEP</string> @@ -930,6 +930,8 @@ <string name="power_discharge_by">Should last until about <xliff:g id="time">%1$s</xliff:g> (<xliff:g id="level">%2$s</xliff:g>)</string> <!-- [CHAR_LIMIT=100] Label for estimated time that phone will run out of battery --> <string name="power_discharge_by_only">Should last until about <xliff:g id="time">%1$s</xliff:g></string> + <!-- [CHAR_LIMIT=100] Label for estimated time that phone will run out of battery --> + <string name="power_discharge_by_only_short">Until <xliff:g id="time" example="12 PM">%1$s</xliff:g></string> <!-- [CHAR_LIMIT=60] label for estimated remaining duration of battery when under a certain amount --> <string name="power_remaining_less_than_duration_only">Less than <xliff:g id="threshold">%1$s</xliff:g> remaining</string> diff --git a/packages/SettingsLib/src/com/android/settingslib/core/instrumentation/EventLogWriter.java b/packages/SettingsLib/src/com/android/settingslib/core/instrumentation/EventLogWriter.java index 1aeb075abf30..e8245082f8ef 100644 --- a/packages/SettingsLib/src/com/android/settingslib/core/instrumentation/EventLogWriter.java +++ b/packages/SettingsLib/src/com/android/settingslib/core/instrumentation/EventLogWriter.java @@ -44,7 +44,14 @@ public class EventLogWriter implements LogWriter { @Override public void action(Context context, int category, Pair<Integer, Object>... taggedData) { - action(context, category, "", taggedData); + final LogMaker logMaker = new LogMaker(category) + .setType(MetricsProto.MetricsEvent.TYPE_ACTION); + if (taggedData != null) { + for (Pair<Integer, Object> pair : taggedData) { + logMaker.addTaggedData(pair.first, pair.second); + } + } + MetricsLogger.action(logMaker); } @Override @@ -58,19 +65,12 @@ public class EventLogWriter implements LogWriter { } @Override - public void action(Context context, int category, String pkg, - Pair<Integer, Object>... taggedData) { - if (taggedData == null || taggedData.length == 0) { - MetricsLogger.action(context, category, pkg); - } else { - final LogMaker logMaker = new LogMaker(category) - .setType(MetricsProto.MetricsEvent.TYPE_ACTION) - .setPackageName(pkg); - for (Pair<Integer, Object> pair : taggedData) { - logMaker.addTaggedData(pair.first, pair.second); - } - MetricsLogger.action(logMaker); - } + public void action(Context context, int category, String pkg) { + final LogMaker logMaker = new LogMaker(category) + .setType(MetricsProto.MetricsEvent.TYPE_ACTION) + .setPackageName(pkg); + + MetricsLogger.action(logMaker); } @Override diff --git a/packages/SettingsLib/src/com/android/settingslib/core/instrumentation/LogWriter.java b/packages/SettingsLib/src/com/android/settingslib/core/instrumentation/LogWriter.java index b60364ea7271..f1876883a336 100644 --- a/packages/SettingsLib/src/com/android/settingslib/core/instrumentation/LogWriter.java +++ b/packages/SettingsLib/src/com/android/settingslib/core/instrumentation/LogWriter.java @@ -51,7 +51,7 @@ public interface LogWriter { /** * Logs an user action. */ - void action(Context context, int category, String pkg, Pair<Integer, Object>... taggedData); + void action(Context context, int category, String pkg); /** * Generically log action. diff --git a/packages/SettingsLib/src/com/android/settingslib/core/instrumentation/MetricsFeatureProvider.java b/packages/SettingsLib/src/com/android/settingslib/core/instrumentation/MetricsFeatureProvider.java index 188204e82e70..8cc3b5a3f37a 100644 --- a/packages/SettingsLib/src/com/android/settingslib/core/instrumentation/MetricsFeatureProvider.java +++ b/packages/SettingsLib/src/com/android/settingslib/core/instrumentation/MetricsFeatureProvider.java @@ -79,7 +79,10 @@ public class MetricsFeatureProvider { } } - public void action(Context context, int category, Pair<Integer, Object>... taggedData) { + /** + * Logs a simple action without page id or attribution + */ + public void action(Context context, int category, Pair<Integer, Object>... taggedData) { for (LogWriter writer : mLoggerWriters) { writer.action(context, category, taggedData); } @@ -88,10 +91,9 @@ public class MetricsFeatureProvider { /** * Logs a generic Settings event. */ - public void action(Context context, int category, String pkg, - Pair<Integer, Object>... taggedData) { + public void action(Context context, int category, String pkg) { for (LogWriter writer : mLoggerWriters) { - writer.action(context, category, pkg, taggedData); + writer.action(context, category, pkg); } } @@ -135,16 +137,22 @@ public class MetricsFeatureProvider { // Not loggable return; } - action(context, MetricsEvent.ACTION_SETTINGS_TILE_CLICK, action, - Pair.create(MetricsEvent.FIELD_CONTEXT, sourceMetricsCategory)); + action(sourceMetricsCategory, + MetricsEvent.ACTION_SETTINGS_TILE_CLICK, + SettingsEnums.PAGE_UNKNOWN, + action, + 0); return; } else if (TextUtils.equals(cn.getPackageName(), context.getPackageName())) { // Going to a Setting internal page, skip click logging in favor of page's own // visibility logging. return; } - action(context, MetricsEvent.ACTION_SETTINGS_TILE_CLICK, cn.flattenToString(), - Pair.create(MetricsEvent.FIELD_CONTEXT, sourceMetricsCategory)); + action(sourceMetricsCategory, + MetricsEvent.ACTION_SETTINGS_TILE_CLICK, + SettingsEnums.PAGE_UNKNOWN, + cn.flattenToString(), + 0); } } diff --git a/packages/SettingsLib/src/com/android/settingslib/core/instrumentation/SharedPreferencesLogger.java b/packages/SettingsLib/src/com/android/settingslib/core/instrumentation/SharedPreferencesLogger.java index 71f3789405c8..320380fc0ed9 100644 --- a/packages/SettingsLib/src/com/android/settingslib/core/instrumentation/SharedPreferencesLogger.java +++ b/packages/SettingsLib/src/com/android/settingslib/core/instrumentation/SharedPreferencesLogger.java @@ -15,6 +15,7 @@ package com.android.settingslib.core.instrumentation; import android.annotation.Nullable; +import android.app.settings.SettingsEnums; import android.content.ComponentName; import android.content.Context; import android.content.SharedPreferences; @@ -22,12 +23,9 @@ import android.content.pm.PackageManager; import android.os.AsyncTask; import android.text.TextUtils; import android.util.Log; -import android.util.Pair; import androidx.annotation.VisibleForTesting; -import com.android.internal.logging.nano.MetricsProto.MetricsEvent; - import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentSkipListSet; @@ -117,10 +115,9 @@ public class SharedPreferencesLogger implements SharedPreferences { return; } - final Pair<Integer, Object> valueData; + final int intVal; if (value instanceof Long) { final Long longVal = (Long) value; - final int intVal; if (longVal > Integer.MAX_VALUE) { intVal = Integer.MAX_VALUE; } else if (longVal < Integer.MIN_VALUE) { @@ -128,47 +125,45 @@ public class SharedPreferencesLogger implements SharedPreferences { } else { intVal = longVal.intValue(); } - valueData = Pair.create(MetricsEvent.FIELD_SETTINGS_PREFERENCE_CHANGE_INT_VALUE, - intVal); } else if (value instanceof Integer) { - valueData = Pair.create(MetricsEvent.FIELD_SETTINGS_PREFERENCE_CHANGE_INT_VALUE, - value); + intVal = (int) value; } else if (value instanceof Boolean) { - valueData = Pair.create(MetricsEvent.FIELD_SETTINGS_PREFERENCE_CHANGE_INT_VALUE, - (Boolean) value ? 1 : 0); + intVal = (Boolean) value ? 1 : 0; } else if (value instanceof Float) { - valueData = Pair.create(MetricsEvent.FIELD_SETTINGS_PREFERENCE_CHANGE_FLOAT_VALUE, - value); - } else if (value instanceof String) { - Log.d(LOG_TAG, "Tried to log string preference " + prefKey + " = " + value); - valueData = null; + final float floatValue = (float) value; + if (floatValue > Integer.MAX_VALUE) { + intVal = Integer.MAX_VALUE; + } else if (floatValue < Integer.MIN_VALUE) { + intVal = Integer.MIN_VALUE; + } else { + intVal = (int) floatValue; + } } else { Log.w(LOG_TAG, "Tried to log unloggable object" + value); - valueData = null; - } - if (valueData != null) { - // Pref key exists in set, log it's change in metrics. - mMetricsFeature.action(mContext, MetricsEvent.ACTION_SETTINGS_PREFERENCE_CHANGE, - Pair.create(MetricsEvent.FIELD_SETTINGS_PREFERENCE_CHANGE_NAME, prefKey), - valueData); + return; } + // Pref key exists in set, log it's change in metrics. + mMetricsFeature.action(SettingsEnums.PAGE_UNKNOWN, + SettingsEnums.ACTION_SETTINGS_PREFERENCE_CHANGE, + SettingsEnums.PAGE_UNKNOWN, + prefKey, + intVal); } @VisibleForTesting void logPackageName(String key, String value) { final String prefKey = mTag + "/" + key; - mMetricsFeature.action(mContext, MetricsEvent.ACTION_SETTINGS_PREFERENCE_CHANGE, value, - Pair.create(MetricsEvent.FIELD_SETTINGS_PREFERENCE_CHANGE_NAME, prefKey)); + mMetricsFeature.action(SettingsEnums.PAGE_UNKNOWN, + SettingsEnums.ACTION_SETTINGS_PREFERENCE_CHANGE, + SettingsEnums.PAGE_UNKNOWN, + prefKey + ":" + value, + 0); } private void safeLogValue(String key, String value) { new AsyncPackageCheck().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, key, value); } - public static String buildCountName(String prefKey, Object value) { - return prefKey + "|" + value; - } - public static String buildPrefKey(String tag, String key) { return tag + "/" + key; } diff --git a/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageMeasurement.java b/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageMeasurement.java index 5a57e69ae131..8f9394fd3c5a 100644 --- a/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageMeasurement.java +++ b/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageMeasurement.java @@ -152,7 +152,8 @@ public class StorageMeasurement { final MeasurementDetails details = new MeasurementDetails(); if (mVolume == null) return details; - if (mVolume.getType() == VolumeInfo.TYPE_PUBLIC) { + if (mVolume.getType() == VolumeInfo.TYPE_PUBLIC + || mVolume.getType() == VolumeInfo.TYPE_STUB) { details.totalSize = mVolume.getPath().getTotalSpace(); details.availSize = mVolume.getPath().getUsableSpace(); return details; diff --git a/packages/SettingsLib/src/com/android/settingslib/utils/PowerUtil.java b/packages/SettingsLib/src/com/android/settingslib/utils/PowerUtil.java index fa59688d1523..43c97df24a58 100644 --- a/packages/SettingsLib/src/com/android/settingslib/utils/PowerUtil.java +++ b/packages/SettingsLib/src/com/android/settingslib/utils/PowerUtil.java @@ -81,6 +81,30 @@ public class PowerUtil { return null; } + /** + * Method to produce a shortened string describing the remaining battery. Suitable for Quick + * Settings and other areas where space is constrained. + * + * @param context context to fetch descriptions from + * @param drainTimeMs The estimated time remaining before the phone dies in milliseconds. + * + * @return a properly formatted and localized short string describing how much time remains + * before the battery runs out. + */ + @Nullable + public static String getBatteryRemainingShortStringFormatted( + Context context, long drainTimeMs) { + if (drainTimeMs <= 0) { + return null; + } + + if (drainTimeMs <= ONE_DAY_MILLIS) { + return getRegularTimeRemainingShortString(context, drainTimeMs); + } else { + return getMoreThanOneDayShortString(context, drainTimeMs); + } + } + private static String getShutdownImminentString(Context context, String percentageString) { return TextUtils.isEmpty(percentageString) ? context.getString(R.string.power_remaining_duration_only_shutdown_imminent) @@ -120,6 +144,14 @@ public class PowerUtil { } } + private static String getMoreThanOneDayShortString(Context context, long drainTimeMs) { + final long roundedTimeMs = roundTimeToNearestThreshold(drainTimeMs, ONE_HOUR_MILLIS); + CharSequence timeString = StringUtil.formatElapsedTime(context, roundedTimeMs, + false /* withSeconds */); + + return context.getString(R.string.power_remaining_duration_only_short, timeString); + } + private static String getMoreThanTwoDaysString(Context context, String percentageString) { final Locale currentLocale = context.getResources().getConfiguration().getLocales().get(0); final MeasureFormat frmt = MeasureFormat.getInstance(currentLocale, FormatWidth.SHORT); @@ -162,6 +194,22 @@ public class PowerUtil { } } + private static String getRegularTimeRemainingShortString(Context context, long drainTimeMs) { + // Get the time of day we think device will die rounded to the nearest 15 min. + final long roundedTimeOfDayMs = + roundTimeToNearestThreshold( + System.currentTimeMillis() + drainTimeMs, + FIFTEEN_MINUTES_MILLIS); + + // convert the time to a properly formatted string. + String skeleton = android.text.format.DateFormat.getTimeFormatString(context); + DateFormat fmt = DateFormat.getInstanceForSkeleton(skeleton); + Date date = Date.from(Instant.ofEpochMilli(roundedTimeOfDayMs)); + CharSequence timeString = fmt.format(date); + + return context.getString(R.string.power_discharge_by_only_short, timeString); + } + public static long convertUsToMs(long timeUs) { return timeUs / 1000; } diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/instrumentation/MetricsFeatureProviderTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/instrumentation/MetricsFeatureProviderTest.java index 603f838364eb..4ec6fb2efab1 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/instrumentation/MetricsFeatureProviderTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/instrumentation/MetricsFeatureProviderTest.java @@ -17,8 +17,6 @@ package com.android.settingslib.core.instrumentation; import static com.google.common.truth.Truth.assertThat; -import static org.mockito.Matchers.anyString; -import static org.mockito.Matchers.eq; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; @@ -27,7 +25,6 @@ import android.app.settings.SettingsEnums; import android.content.ComponentName; import android.content.Context; import android.content.Intent; -import android.util.Pair; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settingslib.SettingsLibRobolectricTestRunner; @@ -77,10 +74,11 @@ public class MetricsFeatureProviderTest { mProvider.logDashboardStartIntent(mContext, intent, MetricsEvent.SETTINGS_GESTURES); verify(mLogWriter).action( - eq(mContext), - eq(MetricsEvent.ACTION_SETTINGS_TILE_CLICK), - anyString(), - eq(Pair.create(MetricsEvent.FIELD_CONTEXT, MetricsEvent.SETTINGS_GESTURES))); + MetricsEvent.SETTINGS_GESTURES, + MetricsEvent.ACTION_SETTINGS_TILE_CLICK, + SettingsEnums.PAGE_UNKNOWN, + Intent.ACTION_ASSIST, + 0); } @Test @@ -90,10 +88,11 @@ public class MetricsFeatureProviderTest { mProvider.logDashboardStartIntent(mContext, intent, MetricsEvent.SETTINGS_GESTURES); verify(mLogWriter).action( - eq(mContext), - eq(MetricsEvent.ACTION_SETTINGS_TILE_CLICK), - anyString(), - eq(Pair.create(MetricsEvent.FIELD_CONTEXT, MetricsEvent.SETTINGS_GESTURES))); + MetricsEvent.SETTINGS_GESTURES, + MetricsEvent.ACTION_SETTINGS_TILE_CLICK, + SettingsEnums.PAGE_UNKNOWN, + "pkg/cls", + 0); } @Test diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/instrumentation/SharedPreferenceLoggerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/instrumentation/SharedPreferenceLoggerTest.java index be671e6d4e22..6285fcdb10b3 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/instrumentation/SharedPreferenceLoggerTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/instrumentation/SharedPreferenceLoggerTest.java @@ -15,25 +15,16 @@ */ package com.android.settingslib.core.instrumentation; -import static com.android.internal.logging.nano.MetricsProto.MetricsEvent - .ACTION_SETTINGS_PREFERENCE_CHANGE; -import static com.android.internal.logging.nano.MetricsProto.MetricsEvent - .FIELD_SETTINGS_PREFERENCE_CHANGE_FLOAT_VALUE; -import static com.android.internal.logging.nano.MetricsProto.MetricsEvent - .FIELD_SETTINGS_PREFERENCE_CHANGE_INT_VALUE; -import static com.android.internal.logging.nano.MetricsProto.MetricsEvent - .FIELD_SETTINGS_PREFERENCE_CHANGE_NAME; - -import static org.mockito.Matchers.any; +import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_SETTINGS_PREFERENCE_CHANGE; + +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Matchers.anyInt; -import static org.mockito.Matchers.argThat; -import static org.mockito.Matchers.eq; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; +import android.app.settings.SettingsEnums; import android.content.Context; import android.content.SharedPreferences; -import android.util.Pair; import com.android.settingslib.SettingsLibRobolectricTestRunner; @@ -41,7 +32,6 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Answers; -import org.mockito.ArgumentMatcher; import org.mockito.Mock; import org.mockito.MockitoAnnotations; @@ -50,11 +40,11 @@ public class SharedPreferenceLoggerTest { private static final String TEST_TAG = "tag"; private static final String TEST_KEY = "key"; + private static final String TEST_TAGGED_KEY = TEST_TAG + "/" + TEST_KEY; @Mock(answer = Answers.RETURNS_DEEP_STUBS) private Context mContext; - private ArgumentMatcher<Pair<Integer, Object>> mNamePairMatcher; @Mock private MetricsFeatureProvider mMetricsFeature; private SharedPreferencesLogger mSharedPrefLogger; @@ -63,7 +53,6 @@ public class SharedPreferenceLoggerTest { public void init() { MockitoAnnotations.initMocks(this); mSharedPrefLogger = new SharedPreferencesLogger(mContext, TEST_TAG, mMetricsFeature); - mNamePairMatcher = pairMatches(FIELD_SETTINGS_PREFERENCE_CHANGE_NAME, String.class); } @Test @@ -77,9 +66,11 @@ public class SharedPreferenceLoggerTest { editor.putInt(TEST_KEY, 2); editor.putInt(TEST_KEY, 2); - verify(mMetricsFeature, times(6)).action(any(Context.class), anyInt(), - argThat(mNamePairMatcher), - argThat(pairMatches(FIELD_SETTINGS_PREFERENCE_CHANGE_INT_VALUE, Integer.class))); + verify(mMetricsFeature, times(6)).action(eq(SettingsEnums.PAGE_UNKNOWN), + eq(SettingsEnums.ACTION_SETTINGS_PREFERENCE_CHANGE), + eq(SettingsEnums.PAGE_UNKNOWN), + eq(TEST_TAGGED_KEY), + anyInt()); } @Test @@ -92,12 +83,16 @@ public class SharedPreferenceLoggerTest { editor.putBoolean(TEST_KEY, false); - verify(mMetricsFeature).action(any(Context.class), anyInt(), - argThat(mNamePairMatcher), - argThat(pairMatches(FIELD_SETTINGS_PREFERENCE_CHANGE_INT_VALUE, true))); - verify(mMetricsFeature, times(3)).action(any(Context.class), anyInt(), - argThat(mNamePairMatcher), - argThat(pairMatches(FIELD_SETTINGS_PREFERENCE_CHANGE_INT_VALUE, false))); + verify(mMetricsFeature).action(SettingsEnums.PAGE_UNKNOWN, + SettingsEnums.ACTION_SETTINGS_PREFERENCE_CHANGE, + SettingsEnums.PAGE_UNKNOWN, + TEST_TAGGED_KEY, + 1); + verify(mMetricsFeature, times(3)).action(SettingsEnums.PAGE_UNKNOWN, + SettingsEnums.ACTION_SETTINGS_PREFERENCE_CHANGE, + SettingsEnums.PAGE_UNKNOWN, + TEST_TAGGED_KEY, + 0); } @Test @@ -109,9 +104,11 @@ public class SharedPreferenceLoggerTest { editor.putLong(TEST_KEY, 1); editor.putLong(TEST_KEY, 2); - verify(mMetricsFeature, times(4)).action(any(Context.class), anyInt(), - argThat(mNamePairMatcher), - argThat(pairMatches(FIELD_SETTINGS_PREFERENCE_CHANGE_INT_VALUE, Integer.class))); + verify(mMetricsFeature, times(4)).action(eq(SettingsEnums.PAGE_UNKNOWN), + eq(SettingsEnums.ACTION_SETTINGS_PREFERENCE_CHANGE), + eq(SettingsEnums.PAGE_UNKNOWN), + eq(TEST_TAGGED_KEY), + anyInt()); } @Test @@ -121,10 +118,11 @@ public class SharedPreferenceLoggerTest { editor.putLong(TEST_KEY, 1); editor.putLong(TEST_KEY, veryBigNumber); - verify(mMetricsFeature).action(any(Context.class), anyInt(), - argThat(mNamePairMatcher), - argThat(pairMatches( - FIELD_SETTINGS_PREFERENCE_CHANGE_INT_VALUE, Integer.MAX_VALUE))); + verify(mMetricsFeature).action(SettingsEnums.PAGE_UNKNOWN, + SettingsEnums.ACTION_SETTINGS_PREFERENCE_CHANGE, + SettingsEnums.PAGE_UNKNOWN, + TEST_TAGGED_KEY, + Integer.MAX_VALUE); } @Test @@ -134,10 +132,10 @@ public class SharedPreferenceLoggerTest { editor.putLong(TEST_KEY, 1); editor.putLong(TEST_KEY, veryNegativeNumber); - verify(mMetricsFeature).action(any(Context.class), anyInt(), - argThat(mNamePairMatcher), - argThat(pairMatches( - FIELD_SETTINGS_PREFERENCE_CHANGE_INT_VALUE, Integer.MIN_VALUE))); + verify(mMetricsFeature).action(SettingsEnums.PAGE_UNKNOWN, + SettingsEnums.ACTION_SETTINGS_PREFERENCE_CHANGE, + SettingsEnums.PAGE_UNKNOWN, + TEST_TAGGED_KEY, Integer.MIN_VALUE); } @Test @@ -149,38 +147,20 @@ public class SharedPreferenceLoggerTest { editor.putFloat(TEST_KEY, 1); editor.putFloat(TEST_KEY, 2); - verify(mMetricsFeature, times(4)).action(any(Context.class), anyInt(), - argThat(mNamePairMatcher), - argThat(pairMatches(FIELD_SETTINGS_PREFERENCE_CHANGE_FLOAT_VALUE, Float.class))); + verify(mMetricsFeature, times(4)).action(eq(SettingsEnums.PAGE_UNKNOWN), + eq(SettingsEnums.ACTION_SETTINGS_PREFERENCE_CHANGE), + eq(SettingsEnums.PAGE_UNKNOWN), + eq(TEST_TAGGED_KEY), + anyInt()); } @Test public void logPackage_shouldUseLogPackageApi() { mSharedPrefLogger.logPackageName("key", "com.android.settings"); - verify(mMetricsFeature).action(any(Context.class), - eq(ACTION_SETTINGS_PREFERENCE_CHANGE), - eq("com.android.settings"), - any(Pair.class)); - } - - private ArgumentMatcher<Pair<Integer, Object>> pairMatches(int tag, Class clazz) { - return pair -> pair.first == tag && isInstanceOfType(pair.second, clazz); - } - - private ArgumentMatcher<Pair<Integer, Object>> pairMatches(int tag, boolean bool) { - return pair -> pair.first == tag - && isInstanceOfType(pair.second, Integer.class) - && pair.second.equals((bool ? 1 : 0)); - } - - private ArgumentMatcher<Pair<Integer, Object>> pairMatches(int tag, int val) { - return pair -> pair.first == tag - && isInstanceOfType(pair.second, Integer.class) - && pair.second.equals(val); - } - - /** Returns true if the instance is assignable to the type Clazz. */ - private static boolean isInstanceOfType(Object instance, Class<?> clazz) { - return clazz.isInstance(instance); + verify(mMetricsFeature).action(SettingsEnums.PAGE_UNKNOWN, + ACTION_SETTINGS_PREFERENCE_CHANGE, + SettingsEnums.PAGE_UNKNOWN, + "tag/key:com.android.settings", + 0); } } diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java index 448a96301990..cbb6e82c8f86 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java @@ -572,6 +572,15 @@ class SettingsProtoDumpUtil { GlobalSettingsProto.Dropbox.SETTINGS); p.end(dropboxToken); + final long dynamicPowerSavingsToken = p.start(GlobalSettingsProto.DYNAMIC_POWER_SAVINGS); + dumpSetting(s, p, + Settings.Global.DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD, + GlobalSettingsProto.DynamicPowerSavings.DISABLE_THRESHOLD); + dumpSetting(s, p, + Settings.Global.DYNAMIC_POWER_SAVINGS_ENABLED, + GlobalSettingsProto.DynamicPowerSavings.ENABLED); + p.end(dynamicPowerSavingsToken); + final long emergencyToken = p.start(GlobalSettingsProto.EMERGENCY); dumpSetting(s, p, Settings.Global.EMERGENCY_TONE, @@ -794,6 +803,9 @@ class SettingsProtoDumpUtil { dumpSetting(s, p, Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL_MAX, GlobalSettingsProto.LowPowerMode.TRIGGER_LEVEL_MAX); + dumpSetting(s, p, + Settings.Global.AUTOMATIC_POWER_SAVER_MODE, + GlobalSettingsProto.LowPowerMode.AUTOMATIC_POWER_SAVER_MODE); p.end(lpmToken); dumpSetting(s, p, diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml index 822c39b6a71d..89690fb8dc5b 100644 --- a/packages/Shell/AndroidManifest.xml +++ b/packages/Shell/AndroidManifest.xml @@ -83,6 +83,7 @@ <uses-permission android:name="android.permission.ACCESS_SURFACE_FLINGER" /> <uses-permission android:name="android.permission.READ_FRAME_BUFFER" /> <uses-permission android:name="android.permission.DEVICE_POWER" /> + <uses-permission android:name="android.permission.POWER_SAVER" /> <uses-permission android:name="android.permission.INSTALL_LOCATION_PROVIDER" /> <uses-permission android:name="android.permission.BACKUP" /> <uses-permission android:name="android.permission.FORCE_STOP_PACKAGES" /> diff --git a/packages/SystemUI/res/drawable-nodpi/work_challenge_background.png b/packages/SystemUI/res/drawable-nodpi/work_challenge_background.png Binary files differnew file mode 100644 index 000000000000..311f30bc1e6b --- /dev/null +++ b/packages/SystemUI/res/drawable-nodpi/work_challenge_background.png diff --git a/packages/SystemUI/res/layout/biometric_dialog.xml b/packages/SystemUI/res/layout/biometric_dialog.xml index 67c0adfa87a4..5ca34b033f0d 100644 --- a/packages/SystemUI/res/layout/biometric_dialog.xml +++ b/packages/SystemUI/res/layout/biometric_dialog.xml @@ -14,157 +14,169 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License --> -<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" +<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/layout" android:layout_width="match_parent" - android:layout_height="match_parent" - android:gravity="bottom" - android:background="@color/biometric_dialog_dim_color" - android:orientation="vertical"> - - <!-- This is not a Space since Spaces cannot be clicked --> - <View - android:id="@+id/space" + android:layout_height="match_parent"> + + <ImageView + android:id="@+id/background" android:layout_width="match_parent" - android:layout_height="0dp" - android:layout_weight="1" /> + android:layout_height="match_parent" + android:scaleType="center" /> <LinearLayout android:layout_width="match_parent" - android:layout_height="wrap_content" - android:orientation="horizontal"> + android:layout_height="match_parent" + android:gravity="bottom" + android:background="@color/biometric_dialog_dim_color" + android:orientation="vertical"> - <!-- This is not a Space since Spaces cannot be clicked. The width of this changes depending - on horizontal/portrait orientation --> + <!-- This is not a Space since Spaces cannot be clicked --> <View - android:id="@+id/left_space" - android:layout_weight="1" - android:layout_width="0dp" - android:layout_height="match_parent"/> + android:id="@+id/space" + android:layout_width="match_parent" + android:layout_height="0dp" + android:layout_weight="1" /> <LinearLayout - android:id="@+id/dialog" android:layout_width="match_parent" android:layout_height="wrap_content" - android:orientation="vertical" - android:background="@drawable/biometric_dialog_bg" - android:layout_marginBottom="@dimen/biometric_dialog_border_padding" - android:layout_marginLeft="@dimen/biometric_dialog_border_padding" - android:layout_marginRight="@dimen/biometric_dialog_border_padding"> - - <TextView - android:id="@+id/title" - android:fontFamily="@*android:string/config_headlineFontFamilyMedium" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_marginEnd="24dp" - android:layout_marginStart="24dp" - android:layout_marginTop="24dp" - android:gravity="@integer/biometric_dialog_text_gravity" - android:textSize="20sp" - android:maxLines="1" - android:singleLine="true" - android:ellipsize="marquee" - android:marqueeRepeatLimit="marquee_forever" - android:textColor="?android:attr/textColorPrimary"/> - - <TextView - android:id="@+id/subtitle" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_marginTop="8dp" - android:layout_marginStart="24dp" - android:layout_marginEnd="24dp" - android:gravity="@integer/biometric_dialog_text_gravity" - android:textSize="16sp" - android:maxLines="1" - android:singleLine="true" - android:ellipsize="marquee" - android:marqueeRepeatLimit="marquee_forever" - android:textColor="?android:attr/textColorPrimary"/> - - <TextView - android:id="@+id/description" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_marginEnd="24dp" - android:layout_marginStart="24dp" - android:gravity="@integer/biometric_dialog_text_gravity" - android:paddingTop="8dp" - android:textSize="16sp" - android:maxLines="4" - android:textColor="?android:attr/textColorPrimary"/> - - <ImageView - android:id="@+id/biometric_icon" - android:layout_width="@dimen/biometric_dialog_biometric_icon_size" - android:layout_height="@dimen/biometric_dialog_biometric_icon_size" - android:layout_gravity="center_horizontal" - android:layout_marginTop="48dp" - android:scaleType="fitXY" /> - - <TextView - android:id="@+id/error" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_marginEnd="24dp" - android:layout_marginStart="24dp" - android:paddingTop="16dp" - android:paddingBottom="24dp" - android:textSize="12sp" - android:gravity="center_horizontal" - android:accessibilityLiveRegion="polite" - android:contentDescription="@string/accessibility_biometric_dialog_help_area" - android:textColor="?android:attr/textColorSecondary"/> + android:orientation="horizontal"> + + <!-- This is not a Space since Spaces cannot be clicked. The width of this changes depending + on horizontal/portrait orientation --> + <View + android:id="@+id/left_space" + android:layout_weight="1" + android:layout_width="0dp" + android:layout_height="match_parent"/> <LinearLayout + android:id="@+id/dialog" android:layout_width="match_parent" - android:layout_height="72dip" - android:paddingTop="24dp" - android:layout_gravity="center_vertical" - style="?android:attr/buttonBarStyle" - android:orientation="horizontal" - android:measureWithLargestChild="true"> - <Space android:id="@+id/leftSpacer" - android:layout_width="12dp" - android:layout_height="match_parent" - android:visibility="visible" /> - <!-- Negative Button --> - <Button android:id="@+id/button2" - android:layout_width="wrap_content" - android:layout_height="match_parent" - style="@*android:style/Widget.DeviceDefault.Button.Borderless.Colored" - android:gravity="center" - android:maxLines="2" /> - <Space android:id="@+id/middleSpacer" - android:layout_width="0dp" - android:layout_height="match_parent" - android:layout_weight="1" - android:visibility="visible" /> - <!-- Positive Button --> - <Button android:id="@+id/button1" - android:layout_width="wrap_content" - android:layout_height="match_parent" - style="@*android:style/Widget.DeviceDefault.Button.Colored" - android:gravity="center" - android:maxLines="2" - android:text="@string/biometric_dialog_confirm" - android:visibility="gone"/> - <Space android:id="@+id/rightSpacer" - android:layout_width="12dip" - android:layout_height="match_parent" - android:visibility="visible" /> + android:layout_height="wrap_content" + android:orientation="vertical" + android:background="@drawable/biometric_dialog_bg" + android:layout_marginBottom="@dimen/biometric_dialog_border_padding" + android:layout_marginLeft="@dimen/biometric_dialog_border_padding" + android:layout_marginRight="@dimen/biometric_dialog_border_padding"> + + <TextView + android:id="@+id/title" + android:fontFamily="@*android:string/config_headlineFontFamilyMedium" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginEnd="24dp" + android:layout_marginStart="24dp" + android:layout_marginTop="24dp" + android:gravity="@integer/biometric_dialog_text_gravity" + android:textSize="20sp" + android:maxLines="1" + android:singleLine="true" + android:ellipsize="marquee" + android:marqueeRepeatLimit="marquee_forever" + android:textColor="?android:attr/textColorPrimary"/> + + <TextView + android:id="@+id/subtitle" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="8dp" + android:layout_marginStart="24dp" + android:layout_marginEnd="24dp" + android:gravity="@integer/biometric_dialog_text_gravity" + android:textSize="16sp" + android:maxLines="1" + android:singleLine="true" + android:ellipsize="marquee" + android:marqueeRepeatLimit="marquee_forever" + android:textColor="?android:attr/textColorPrimary"/> + + <TextView + android:id="@+id/description" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginEnd="24dp" + android:layout_marginStart="24dp" + android:gravity="@integer/biometric_dialog_text_gravity" + android:paddingTop="8dp" + android:textSize="16sp" + android:maxLines="4" + android:textColor="?android:attr/textColorPrimary"/> + + <ImageView + android:id="@+id/biometric_icon" + android:layout_width="@dimen/biometric_dialog_biometric_icon_size" + android:layout_height="@dimen/biometric_dialog_biometric_icon_size" + android:layout_gravity="center_horizontal" + android:layout_marginTop="48dp" + android:scaleType="fitXY" /> + + <TextView + android:id="@+id/error" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginEnd="24dp" + android:layout_marginStart="24dp" + android:paddingTop="16dp" + android:paddingBottom="24dp" + android:textSize="12sp" + android:gravity="center_horizontal" + android:accessibilityLiveRegion="polite" + android:contentDescription="@string/accessibility_biometric_dialog_help_area" + android:textColor="?android:attr/textColorSecondary"/> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="72dip" + android:paddingTop="24dp" + android:layout_gravity="center_vertical" + style="?android:attr/buttonBarStyle" + android:orientation="horizontal" + android:measureWithLargestChild="true"> + <Space android:id="@+id/leftSpacer" + android:layout_width="12dp" + android:layout_height="match_parent" + android:visibility="visible" /> + <!-- Negative Button --> + <Button android:id="@+id/button2" + android:layout_width="wrap_content" + android:layout_height="match_parent" + style="@*android:style/Widget.DeviceDefault.Button.Borderless.Colored" + android:gravity="center" + android:maxLines="2" /> + <Space android:id="@+id/middleSpacer" + android:layout_width="0dp" + android:layout_height="match_parent" + android:layout_weight="1" + android:visibility="visible" /> + <!-- Positive Button --> + <Button android:id="@+id/button1" + android:layout_width="wrap_content" + android:layout_height="match_parent" + style="@*android:style/Widget.DeviceDefault.Button.Colored" + android:gravity="center" + android:maxLines="2" + android:text="@string/biometric_dialog_confirm" + android:visibility="gone"/> + <Space android:id="@+id/rightSpacer" + android:layout_width="12dip" + android:layout_height="match_parent" + android:visibility="visible" /> + </LinearLayout> </LinearLayout> - </LinearLayout> - <!-- This is not a Space since Spaces cannot be clicked. The width of this changes depending - on horizontal/portrait orientation --> - <View - android:id="@+id/right_space" - android:layout_weight="1" - android:layout_width="0dp" - android:layout_height="match_parent" /> + <!-- This is not a Space since Spaces cannot be clicked. The width of this changes depending + on horizontal/portrait orientation --> + <View + android:id="@+id/right_space" + android:layout_weight="1" + android:layout_width="0dp" + android:layout_height="match_parent" /> + + </LinearLayout> </LinearLayout> -</LinearLayout> +</FrameLayout> diff --git a/packages/SystemUI/res/layout/navigation_bar_window.xml b/packages/SystemUI/res/layout/navigation_bar_window.xml index 6fa46d4ba3f8..f98cbd8d10fa 100644 --- a/packages/SystemUI/res/layout/navigation_bar_window.xml +++ b/packages/SystemUI/res/layout/navigation_bar_window.xml @@ -20,6 +20,7 @@ xmlns:android="http://schemas.android.com/apk/res/android" xmlns:systemui="http://schemas.android.com/apk/res-auto" android:id="@+id/navigation_bar_frame" + android:theme="@style/Theme.SystemUI" android:layout_height="match_parent" android:layout_width="match_parent"> diff --git a/packages/SystemUI/res/layout/quick_qs_status_icons.xml b/packages/SystemUI/res/layout/quick_qs_status_icons.xml index 94189bb9594b..2000104ad0cd 100644 --- a/packages/SystemUI/res/layout/quick_qs_status_icons.xml +++ b/packages/SystemUI/res/layout/quick_qs_status_icons.xml @@ -42,6 +42,20 @@ android:id="@+id/statusIcons" android:layout_width="0dp" android:layout_height="match_parent" - android:layout_weight="1" /> + android:layout_weight="1" + android:paddingEnd="@dimen/signal_cluster_battery_padding" /> + + <com.android.systemui.BatteryMeterView + android:id="@+id/batteryRemainingIcon" + android:layout_height="match_parent" + android:layout_width="wrap_content" + android:paddingEnd="2dp" /> + + <TextView + android:id="@+id/batteryRemainingText" + android:textAppearance="@style/TextAppearance.QS.TileLabel" + android:layout_height="match_parent" + android:layout_width="wrap_content" + android:gravity="center_vertical" /> </LinearLayout> diff --git a/packages/SystemUI/src/com/android/keyguard/CarrierText.java b/packages/SystemUI/src/com/android/keyguard/CarrierText.java index a0a36878634a..b7d51978fab2 100644 --- a/packages/SystemUI/src/com/android/keyguard/CarrierText.java +++ b/packages/SystemUI/src/com/android/keyguard/CarrierText.java @@ -16,10 +16,6 @@ package com.android.keyguard; -import java.util.List; -import java.util.Locale; -import java.util.Objects; - import android.content.Context; import android.content.Intent; import android.content.IntentFilter; @@ -28,6 +24,7 @@ import android.net.ConnectivityManager; import android.net.wifi.WifiManager; import android.telephony.ServiceState; import android.telephony.SubscriptionInfo; +import android.telephony.TelephonyManager; import android.text.TextUtils; import android.text.method.SingleLineTransformationMethod; import android.util.AttributeSet; @@ -40,7 +37,9 @@ import com.android.internal.telephony.IccCardConstants.State; import com.android.internal.telephony.TelephonyIntents; import com.android.settingslib.WirelessUtils; -import android.telephony.TelephonyManager; +import java.util.List; +import java.util.Locale; +import java.util.Objects; public class CarrierText extends TextView { private static final boolean DEBUG = KeyguardConstants.DEBUG; diff --git a/packages/SystemUI/src/com/android/keyguard/EmergencyButton.java b/packages/SystemUI/src/com/android/keyguard/EmergencyButton.java index ac8f0246a608..210b82d1d69c 100644 --- a/packages/SystemUI/src/com/android/keyguard/EmergencyButton.java +++ b/packages/SystemUI/src/com/android/keyguard/EmergencyButton.java @@ -16,7 +16,6 @@ package com.android.keyguard; -import android.app.ActivityManager; import android.app.ActivityOptions; import android.app.ActivityTaskManager; import android.content.Context; @@ -37,8 +36,8 @@ import android.widget.Button; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.telephony.IccCardConstants.State; -import com.android.internal.widget.LockPatternUtils; import com.android.internal.util.EmergencyAffordanceManager; +import com.android.internal.widget.LockPatternUtils; import com.android.systemui.util.EmergencyDialerConstants; /** diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardEsimArea.java b/packages/SystemUI/src/com/android/keyguard/KeyguardEsimArea.java index 63b7ae2d856a..c2bbfbf73bb6 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardEsimArea.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardEsimArea.java @@ -22,19 +22,15 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; -import android.os.Handler; -import android.os.HandlerThread; import android.os.UserHandle; +import android.telephony.SubscriptionInfo; +import android.telephony.SubscriptionManager; +import android.telephony.euicc.EuiccManager; import android.util.AttributeSet; +import android.util.Log; import android.view.View; import android.view.WindowManager; import android.widget.Button; -import android.telephony.SubscriptionManager; -import android.telephony.SubscriptionInfo; -import android.telephony.euicc.EuiccManager; -import android.util.Log; - -import java.lang.ref.WeakReference; /*** * This button is used by the device with embedded SIM card to disable current carrier to unlock diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardHostView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardHostView.java index 34df15f17869..cf22286c1614 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardHostView.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardHostView.java @@ -19,8 +19,8 @@ package com.android.keyguard; import android.app.Activity; import android.app.ActivityManager; import android.content.Context; -import android.content.res.Resources; import android.content.res.ColorStateList; +import android.content.res.Resources; import android.graphics.Canvas; import android.media.AudioManager; import android.os.SystemClock; diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java index f400f6039882..3cc18ddf3b2a 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java @@ -23,8 +23,6 @@ import android.view.KeyEvent; import android.view.MotionEvent; import android.view.View; -import com.android.internal.annotations.VisibleForTesting; - /** * A Pin based Keyguard input view */ diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java index b8df3c067969..7af27f2ed49a 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java @@ -21,7 +21,6 @@ import android.app.admin.DevicePolicyManager; import android.content.Context; import android.content.res.ColorStateList; import android.os.UserHandle; -import androidx.annotation.VisibleForTesting; import android.util.AttributeSet; import android.util.Log; import android.util.Slog; @@ -31,6 +30,8 @@ import android.view.View; import android.view.WindowManager; import android.widget.FrameLayout; +import androidx.annotation.VisibleForTesting; + import com.android.internal.widget.LockPatternUtils; import com.android.keyguard.KeyguardSecurityModel.SecurityMode; diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityView.java index 1a09364f564c..272b3bdf56a4 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityView.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityView.java @@ -15,9 +15,10 @@ */ package com.android.keyguard; -import com.android.internal.widget.LockPatternUtils; import android.content.res.ColorStateList; +import com.android.internal.widget.LockPatternUtils; + public interface KeyguardSecurityView { static public final int SCREEN_ON = 1; static public final int VIEW_REVEALED = 2; diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityViewFlipper.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityViewFlipper.java index 74e2a6835b41..e6a02506b4a3 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityViewFlipper.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityViewFlipper.java @@ -18,8 +18,8 @@ package com.android.keyguard; import android.annotation.NonNull; import android.content.Context; -import android.content.res.TypedArray; import android.content.res.ColorStateList; +import android.content.res.TypedArray; import android.graphics.Rect; import android.util.AttributeSet; import android.util.Log; @@ -28,18 +28,15 @@ import android.view.View; import android.view.ViewDebug; import android.view.ViewGroup; import android.view.ViewHierarchyEncoder; -import android.view.WindowManager; import android.widget.FrameLayout; import android.widget.ViewFlipper; import com.android.internal.widget.LockPatternUtils; -import java.lang.Override; - /** * Subclass of the current view flipper that allows us to overload dispatchTouchEvent() so - * we can emulate {@link WindowManager.LayoutParams#FLAG_SLIPPERY} within a view hierarchy. - * + * we can emulate {@link android.view.WindowManager.LayoutParams#FLAG_SLIPPERY} within a view + * hierarchy. */ public class KeyguardSecurityViewFlipper extends ViewFlipper implements KeyguardSecurityView { private static final String TAG = "KeyguardSecurityViewFlipper"; diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java index 42c7a5680d11..6528d8c07a6c 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java @@ -16,32 +16,31 @@ package com.android.keyguard; -import com.android.internal.telephony.ITelephony; -import com.android.internal.telephony.IccCardConstants; -import com.android.internal.telephony.IccCardConstants.State; -import com.android.internal.telephony.PhoneConstants; - -import android.content.Context; -import android.content.res.ColorStateList; -import android.content.res.Configuration; -import android.content.res.Resources; import android.app.AlertDialog; import android.app.AlertDialog.Builder; import android.app.Dialog; import android.app.ProgressDialog; +import android.content.Context; +import android.content.res.ColorStateList; +import android.content.res.Configuration; +import android.content.res.Resources; import android.graphics.Color; import android.os.RemoteException; import android.os.ServiceManager; import android.telephony.SubscriptionInfo; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; -import android.telephony.euicc.EuiccManager; import android.util.AttributeSet; import android.util.Log; import android.view.View; import android.view.WindowManager; import android.widget.ImageView; +import com.android.internal.telephony.ITelephony; +import com.android.internal.telephony.IccCardConstants; +import com.android.internal.telephony.IccCardConstants.State; +import com.android.internal.telephony.PhoneConstants; + /** * Displays a PIN pad for unlocking. */ diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java index 1b61568276ce..1157f86872ec 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java @@ -16,20 +16,19 @@ package com.android.keyguard; -import android.content.Context; -import android.content.res.ColorStateList; -import android.content.res.Resources; import android.app.Activity; import android.app.AlertDialog; import android.app.Dialog; import android.app.ProgressDialog; +import android.content.Context; +import android.content.res.ColorStateList; +import android.content.res.Resources; import android.graphics.Color; import android.os.RemoteException; import android.os.ServiceManager; import android.telephony.SubscriptionInfo; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; -import android.telephony.euicc.EuiccManager; import android.util.AttributeSet; import android.util.Log; import android.view.View; @@ -38,8 +37,8 @@ import android.widget.ImageView; import com.android.internal.telephony.ITelephony; import com.android.internal.telephony.IccCardConstants; -import com.android.internal.telephony.PhoneConstants; import com.android.internal.telephony.IccCardConstants.State; +import com.android.internal.telephony.PhoneConstants; /** diff --git a/packages/SystemUI/src/com/android/systemui/AutoReinflateContainer.java b/packages/SystemUI/src/com/android/systemui/AutoReinflateContainer.java index bbc8ecdcc066..5ed9eaad0a00 100644 --- a/packages/SystemUI/src/com/android/systemui/AutoReinflateContainer.java +++ b/packages/SystemUI/src/com/android/systemui/AutoReinflateContainer.java @@ -18,7 +18,6 @@ import android.annotation.Nullable; import android.content.Context; import android.content.res.Configuration; import android.content.res.TypedArray; -import android.os.LocaleList; import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.View; diff --git a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java index f6fec5456ed8..053ea67b92c8 100644 --- a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java +++ b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java @@ -19,7 +19,10 @@ import static android.app.StatusBarManager.DISABLE2_SYSTEM_ICONS; import static android.app.StatusBarManager.DISABLE_NONE; import static android.provider.Settings.System.SHOW_BATTERY_PERCENT; +import static java.lang.annotation.RetentionPolicy.SOURCE; + import android.animation.ArgbEvaluator; +import android.annotation.IntDef; import android.app.ActivityManager; import android.content.Context; import android.content.res.Resources; @@ -55,15 +58,23 @@ import com.android.systemui.statusbar.policy.IconLogger; import com.android.systemui.tuner.TunerService; import com.android.systemui.tuner.TunerService.Tunable; import com.android.systemui.util.Utils.DisableStateTracker; -import com.android.systemui.R; import java.io.FileDescriptor; import java.io.PrintWriter; +import java.lang.annotation.Retention; import java.text.NumberFormat; public class BatteryMeterView extends LinearLayout implements BatteryStateChangeCallback, Tunable, DarkReceiver, ConfigurationListener { + + @Retention(SOURCE) + @IntDef({MODE_DEFAULT, MODE_ON, MODE_OFF}) + public @interface BatteryPercentMode {} + public static final int MODE_DEFAULT = 0; + public static final int MODE_ON = 1; + public static final int MODE_OFF = 2; + private final BatteryMeterDrawableBase mDrawable; private final String mSlotBattery; private final ImageView mBatteryIconView; @@ -74,6 +85,7 @@ public class BatteryMeterView extends LinearLayout implements private SettingObserver mSettingObserver; private int mTextColor; private int mLevel; + private int mShowPercentMode = MODE_DEFAULT; private boolean mForceShowPercent; private boolean mShowPercentAvailable; @@ -154,7 +166,19 @@ public class BatteryMeterView extends LinearLayout implements } public void setForceShowPercent(boolean show) { - mForceShowPercent = show; + setPercentShowMode(show ? MODE_ON : MODE_DEFAULT); + } + + /** + * Force a particular mode of showing percent + * + * 0 - No preference + * 1 - Force on + * 2 - Force off + * @param mode desired mode (none, on, off) + */ + public void setPercentShowMode(@BatteryPercentMode int mode) { + mShowPercentMode = mode; updateShowPercent(); } @@ -273,7 +297,8 @@ public class BatteryMeterView extends LinearLayout implements .getIntForUser(getContext().getContentResolver(), SHOW_BATTERY_PERCENT, 0, mUser); - if ((mShowPercentAvailable && systemSetting) || mForceShowPercent) { + if ((mShowPercentAvailable && systemSetting && mShowPercentMode != MODE_OFF) + || mShowPercentMode == MODE_ON) { if (!showing) { mBatteryPercentView = loadPercentView(); if (mTextColor != 0) mBatteryPercentView.setTextColor(mTextColor); diff --git a/packages/SystemUI/src/com/android/systemui/DejankUtils.java b/packages/SystemUI/src/com/android/systemui/DejankUtils.java index 4ee3bd37ce3c..bec8820a3053 100644 --- a/packages/SystemUI/src/com/android/systemui/DejankUtils.java +++ b/packages/SystemUI/src/com/android/systemui/DejankUtils.java @@ -16,12 +16,12 @@ package com.android.systemui; -import com.android.internal.annotations.VisibleForTesting; -import com.android.systemui.util.Assert; - import android.os.Handler; import android.view.Choreographer; +import com.android.internal.annotations.VisibleForTesting; +import com.android.systemui.util.Assert; + import java.util.ArrayList; /** diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java index fbcf0680f185..5e6d272bd427 100644 --- a/packages/SystemUI/src/com/android/systemui/Dependency.java +++ b/packages/SystemUI/src/com/android/systemui/Dependency.java @@ -296,7 +296,7 @@ public class Dependency extends SystemUI { new WakefulnessLifecycle()); mProviders.put(FragmentService.class, () -> - new FragmentService(mContext)); + new FragmentService()); mProviders.put(ExtensionController.class, () -> new ExtensionControllerImpl(mContext)); diff --git a/packages/SystemUI/src/com/android/systemui/DockedStackExistsListener.java b/packages/SystemUI/src/com/android/systemui/DockedStackExistsListener.java index 81e4db3b2561..5c0df179dd27 100644 --- a/packages/SystemUI/src/com/android/systemui/DockedStackExistsListener.java +++ b/packages/SystemUI/src/com/android/systemui/DockedStackExistsListener.java @@ -14,7 +14,6 @@ package com.android.systemui; -import android.os.IBinder; import android.os.RemoteException; import android.util.Log; import android.view.IDockedStackListener; diff --git a/packages/SystemUI/src/com/android/systemui/ExpandHelper.java b/packages/SystemUI/src/com/android/systemui/ExpandHelper.java index f5ad7476a156..ecf4c0a86bfc 100644 --- a/packages/SystemUI/src/com/android/systemui/ExpandHelper.java +++ b/packages/SystemUI/src/com/android/systemui/ExpandHelper.java @@ -32,9 +32,9 @@ import android.view.View; import android.view.ViewConfiguration; import com.android.internal.annotations.VisibleForTesting; +import com.android.systemui.statusbar.FlingAnimationUtils; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import com.android.systemui.statusbar.notification.row.ExpandableView; -import com.android.systemui.statusbar.FlingAnimationUtils; import com.android.systemui.statusbar.policy.ScrollAdapter; public class ExpandHelper implements Gefingerpoken { diff --git a/packages/SystemUI/src/com/android/systemui/ForegroundServiceControllerImpl.java b/packages/SystemUI/src/com/android/systemui/ForegroundServiceControllerImpl.java index 1fa925e5ad1f..bab472c2e687 100644 --- a/packages/SystemUI/src/com/android/systemui/ForegroundServiceControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/ForegroundServiceControllerImpl.java @@ -23,7 +23,6 @@ import android.service.notification.StatusBarNotification; import android.util.ArrayMap; import android.util.ArraySet; import android.util.Log; -import android.util.Slog; import android.util.SparseArray; import com.android.internal.messages.nano.SystemMessageProto; diff --git a/packages/SystemUI/src/com/android/systemui/ForegroundServicesDialog.java b/packages/SystemUI/src/com/android/systemui/ForegroundServicesDialog.java index 9d286cf7e6d5..cb9523fcaed1 100644 --- a/packages/SystemUI/src/com/android/systemui/ForegroundServicesDialog.java +++ b/packages/SystemUI/src/com/android/systemui/ForegroundServicesDialog.java @@ -42,8 +42,6 @@ import com.android.internal.app.AlertController; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto; -import com.android.systemui.R; - import java.util.ArrayList; /** diff --git a/packages/SystemUI/src/com/android/systemui/HardwareUiLayout.java b/packages/SystemUI/src/com/android/systemui/HardwareUiLayout.java index b1463a3c53ea..16e869e9d317 100644 --- a/packages/SystemUI/src/com/android/systemui/HardwareUiLayout.java +++ b/packages/SystemUI/src/com/android/systemui/HardwareUiLayout.java @@ -14,6 +14,10 @@ package com.android.systemui; +import static com.android.systemui.util.leak.RotationUtils.ROTATION_LANDSCAPE; +import static com.android.systemui.util.leak.RotationUtils.ROTATION_NONE; +import static com.android.systemui.util.leak.RotationUtils.ROTATION_SEASCAPE; + import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorSet; @@ -33,10 +37,6 @@ import com.android.systemui.tuner.TunerService; import com.android.systemui.tuner.TunerService.Tunable; import com.android.systemui.util.leak.RotationUtils; -import static com.android.systemui.util.leak.RotationUtils.ROTATION_LANDSCAPE; -import static com.android.systemui.util.leak.RotationUtils.ROTATION_NONE; -import static com.android.systemui.util.leak.RotationUtils.ROTATION_SEASCAPE; - public class HardwareUiLayout extends LinearLayout implements Tunable { private static final String EDGE_BLEED = "sysui_hwui_edge_bleed"; diff --git a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java index d8eb96504e79..1d2d7fafe800 100644 --- a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java +++ b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java @@ -20,6 +20,7 @@ import android.app.WallpaperManager; import android.content.ComponentCallbacks2; import android.graphics.Bitmap; import android.graphics.Canvas; +import android.graphics.RecordingCanvas; import android.graphics.Rect; import android.graphics.RectF; import android.graphics.Region.Op; @@ -30,7 +31,6 @@ import android.service.wallpaper.WallpaperService; import android.util.Log; import android.view.Display; import android.view.DisplayInfo; -import android.graphics.RecordingCanvas; import android.view.Surface; import android.view.SurfaceHolder; import android.view.WindowManager; diff --git a/packages/SystemUI/src/com/android/systemui/LatencyTester.java b/packages/SystemUI/src/com/android/systemui/LatencyTester.java index 1e458fa5c112..50f1b44b05b1 100644 --- a/packages/SystemUI/src/com/android/systemui/LatencyTester.java +++ b/packages/SystemUI/src/com/android/systemui/LatencyTester.java @@ -16,17 +16,17 @@ package com.android.systemui; -import android.hardware.biometrics.BiometricSourceType; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.hardware.biometrics.BiometricSourceType; import android.os.Build; import android.os.PowerManager; import android.os.SystemClock; -import com.android.keyguard.KeyguardUpdateMonitor; import com.android.internal.util.LatencyTracker; +import com.android.keyguard.KeyguardUpdateMonitor; import com.android.systemui.statusbar.phone.BiometricUnlockController; import com.android.systemui.statusbar.phone.StatusBar; diff --git a/packages/SystemUI/src/com/android/systemui/PluginInflateContainer.java b/packages/SystemUI/src/com/android/systemui/PluginInflateContainer.java index f6ad62616a96..f9617cad848e 100644 --- a/packages/SystemUI/src/com/android/systemui/PluginInflateContainer.java +++ b/packages/SystemUI/src/com/android/systemui/PluginInflateContainer.java @@ -21,8 +21,8 @@ import android.util.Log; import android.view.View; import com.android.systemui.plugins.PluginListener; -import com.android.systemui.shared.plugins.PluginManager; import com.android.systemui.plugins.ViewProvider; +import com.android.systemui.shared.plugins.PluginManager; /** * Define an interface or abstract class as follows that includes the diff --git a/packages/SystemUI/src/com/android/systemui/RegionInterceptingFrameLayout.java b/packages/SystemUI/src/com/android/systemui/RegionInterceptingFrameLayout.java index 6dc2d67a1c78..8351bbfaa430 100644 --- a/packages/SystemUI/src/com/android/systemui/RegionInterceptingFrameLayout.java +++ b/packages/SystemUI/src/com/android/systemui/RegionInterceptingFrameLayout.java @@ -21,7 +21,6 @@ import android.graphics.Region; import android.graphics.Region.Op; import android.util.AttributeSet; import android.view.View; -import android.view.ViewTreeObserver; import android.view.ViewTreeObserver.InternalInsetsInfo; import android.view.ViewTreeObserver.OnComputeInternalInsetsListener; import android.widget.FrameLayout; diff --git a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java index c84449683c1c..1dd231ca7642 100644 --- a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java +++ b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java @@ -63,6 +63,8 @@ import android.view.WindowManager; import android.widget.FrameLayout; import android.widget.ImageView; +import androidx.annotation.VisibleForTesting; + import com.android.internal.util.Preconditions; import com.android.systemui.RegionInterceptingFrameLayout.RegionInterceptableView; import com.android.systemui.fragments.FragmentHostManager; @@ -79,8 +81,6 @@ import com.android.systemui.util.leak.RotationUtils; import java.util.ArrayList; import java.util.List; -import androidx.annotation.VisibleForTesting; - /** * An overlay that draws screen decorations in software (e.g for rounded corners or display cutout) * for antialiasing and emulation purposes. diff --git a/packages/SystemUI/src/com/android/systemui/SysUIToast.java b/packages/SystemUI/src/com/android/systemui/SysUIToast.java index 43b918dbea73..8bcf0571b2d0 100644 --- a/packages/SystemUI/src/com/android/systemui/SysUIToast.java +++ b/packages/SystemUI/src/com/android/systemui/SysUIToast.java @@ -15,11 +15,12 @@ */ package com.android.systemui; +import static android.widget.Toast.Duration; + import android.annotation.StringRes; import android.content.Context; import android.view.WindowManager; import android.widget.Toast; -import static android.widget.Toast.Duration; public class SysUIToast { diff --git a/packages/SystemUI/src/com/android/systemui/SystemBars.java b/packages/SystemUI/src/com/android/systemui/SystemBars.java index b5093b3ce52a..6edc23be8e23 100644 --- a/packages/SystemUI/src/com/android/systemui/SystemBars.java +++ b/packages/SystemUI/src/com/android/systemui/SystemBars.java @@ -14,13 +14,8 @@ package com.android.systemui; -import android.content.res.Configuration; -import android.provider.Settings; import android.util.Log; -import com.android.systemui.R; -import com.android.systemui.SystemUI; - import java.io.FileDescriptor; import java.io.PrintWriter; diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java index c4bf27b5104a..2dd362e97ccc 100644 --- a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java +++ b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java @@ -22,9 +22,9 @@ import android.util.ArrayMap; import android.util.Log; import android.view.ViewGroup; +import com.android.internal.colorextraction.ColorExtractor.GradientColors; import com.android.internal.util.function.TriConsumer; import com.android.internal.widget.LockPatternUtils; -import com.android.internal.colorextraction.ColorExtractor.GradientColors; import com.android.keyguard.ViewMediatorCallback; import com.android.systemui.Dependency.DependencyProvider; import com.android.systemui.classifier.FalsingManager; @@ -32,20 +32,20 @@ import com.android.systemui.keyguard.DismissCallbackRegistry; import com.android.systemui.qs.QSTileHost; import com.android.systemui.statusbar.AmbientPulseManager; import com.android.systemui.statusbar.KeyguardIndicationController; -import com.android.systemui.statusbar.NotificationLockscreenUserManagerImpl; -import com.android.systemui.statusbar.StatusBarStateController; -import com.android.systemui.statusbar.notification.row.NotificationBlockingHelperManager; -import com.android.systemui.statusbar.notification.NotificationEntryManager; -import com.android.systemui.statusbar.notification.row.NotificationGutsManager; import com.android.systemui.statusbar.NotificationListener; import com.android.systemui.statusbar.NotificationLockscreenUserManager; -import com.android.systemui.statusbar.notification.logging.NotificationLogger; +import com.android.systemui.statusbar.NotificationLockscreenUserManagerImpl; import com.android.systemui.statusbar.NotificationMediaManager; import com.android.systemui.statusbar.NotificationRemoteInputManager; import com.android.systemui.statusbar.NotificationViewHierarchyManager; import com.android.systemui.statusbar.ScrimView; import com.android.systemui.statusbar.SmartReplyController; +import com.android.systemui.statusbar.StatusBarStateController; +import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.VisualStabilityManager; +import com.android.systemui.statusbar.notification.logging.NotificationLogger; +import com.android.systemui.statusbar.notification.row.NotificationBlockingHelperManager; +import com.android.systemui.statusbar.notification.row.NotificationGutsManager; import com.android.systemui.statusbar.phone.DozeParameters; import com.android.systemui.statusbar.phone.KeyguardBouncer; import com.android.systemui.statusbar.phone.KeyguardDismissUtil; diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIService.java b/packages/SystemUI/src/com/android/systemui/SystemUIService.java index 8e29841e887d..ac108becfeb2 100644 --- a/packages/SystemUI/src/com/android/systemui/SystemUIService.java +++ b/packages/SystemUI/src/com/android/systemui/SystemUIService.java @@ -24,13 +24,13 @@ import android.os.Process; import android.os.SystemProperties; import android.util.Slog; -import java.io.FileDescriptor; -import java.io.PrintWriter; - import com.android.internal.os.BinderInternal; import com.android.systemui.shared.plugins.PluginManager; import com.android.systemui.shared.plugins.PluginManagerImpl; +import java.io.FileDescriptor; +import java.io.PrintWriter; + public class SystemUIService extends Service { @Override diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistDisclosure.java b/packages/SystemUI/src/com/android/systemui/assist/AssistDisclosure.java index 4bd095de3777..79d4f8d634ce 100644 --- a/packages/SystemUI/src/com/android/systemui/assist/AssistDisclosure.java +++ b/packages/SystemUI/src/com/android/systemui/assist/AssistDisclosure.java @@ -31,7 +31,6 @@ import android.os.Handler; import android.view.View; import android.view.WindowManager; import android.view.accessibility.AccessibilityEvent; -import android.view.animation.AnimationUtils; import com.android.systemui.Interpolators; import com.android.systemui.R; diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogImpl.java b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogImpl.java index 67bc8b626689..c0047c015813 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogImpl.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogImpl.java @@ -140,7 +140,7 @@ public class BiometricDialogImpl extends SystemUI implements CommandQueue.Callba @Override public void showBiometricDialog(Bundle bundle, IBiometricPromptReceiver receiver, int type, - boolean requireConfirmation) { + boolean requireConfirmation, int userId) { if (DEBUG) Log.d(TAG, "showBiometricDialog, type: " + type); // Remove these messages as they are part of the previous client mHandler.removeMessages(MSG_BIOMETRIC_ERROR); @@ -151,6 +151,7 @@ public class BiometricDialogImpl extends SystemUI implements CommandQueue.Callba args.arg2 = receiver; args.argi1 = type; args.arg3 = requireConfirmation; + args.argi2 = userId; mHandler.obtainMessage(MSG_SHOW_DIALOG, args).sendToTarget(); } @@ -194,7 +195,8 @@ public class BiometricDialogImpl extends SystemUI implements CommandQueue.Callba } mReceiver = (IBiometricPromptReceiver) args.arg2; mCurrentDialog.setBundle((Bundle)args.arg1); - mCurrentDialog.setRequireConfirmation((boolean)args.arg3); + mCurrentDialog.setRequireConfirmation((boolean) args.arg3); + mCurrentDialog.setUserId(args.argi2); mCurrentDialog.setSkipIntro(skipAnimation); mWindowManager.addView(mCurrentDialog, mCurrentDialog.getLayoutParams()); mDialogShowing = true; diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogView.java b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogView.java index 1faae9d83fe6..38427adfd42a 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogView.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogView.java @@ -16,15 +16,19 @@ package com.android.systemui.biometrics; +import android.app.admin.DevicePolicyManager; import android.content.Context; import android.content.res.TypedArray; import android.graphics.PixelFormat; +import android.graphics.PorterDuff; +import android.graphics.drawable.Drawable; import android.hardware.biometrics.BiometricPrompt; import android.os.Binder; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; import android.os.Message; +import android.os.UserManager; import android.text.TextUtils; import android.util.DisplayMetrics; import android.util.Log; @@ -64,6 +68,8 @@ public abstract class BiometricDialogView extends LinearLayout { private final IBinder mWindowToken = new Binder(); private final Interpolator mLinearOutSlowIn; private final WindowManager mWindowManager; + private final UserManager mUserManager; + private final DevicePolicyManager mDevicePolicyManager; private final float mAnimationTranslationOffset; private final int mErrorColor; private final int mTextColor; @@ -79,6 +85,7 @@ public abstract class BiometricDialogView extends LinearLayout { private boolean mWasForceRemoved; private boolean mSkipIntro; protected boolean mRequireConfirmation; + private int mUserId; // used to determine if we should show work background protected abstract void updateIcon(int lastState, int newState); protected abstract int getHintStringResourceId(); @@ -121,7 +128,9 @@ public abstract class BiometricDialogView extends LinearLayout { super(context); mCallback = callback; mLinearOutSlowIn = Interpolators.LINEAR_OUT_SLOW_IN; - mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE); + mWindowManager = mContext.getSystemService(WindowManager.class); + mUserManager = mContext.getSystemService(UserManager.class); + mDevicePolicyManager = mContext.getSystemService(DevicePolicyManager.class); mAnimationTranslationOffset = getResources() .getDimension(R.dimen.biometric_dialog_animation_translation_offset); @@ -199,6 +208,18 @@ public abstract class BiometricDialogView extends LinearLayout { final TextView description = mLayout.findViewById(R.id.description); final Button negative = mLayout.findViewById(R.id.button2); final Button positive = mLayout.findViewById(R.id.button1); + final ImageView backgroundView = mLayout.findViewById(R.id.background); + + if (mUserManager.isManagedProfile(mUserId)) { + final Drawable image = getResources().getDrawable(R.drawable.work_challenge_background, + mContext.getTheme()); + image.setColorFilter(mDevicePolicyManager.getOrganizationColorForUser(mUserId), + PorterDuff.Mode.DARKEN); + backgroundView.setImageDrawable(image); + } else { + backgroundView.setImageDrawable(null); + backgroundView.setBackgroundColor(R.color.biometric_dialog_dim_color); + } if (RotationUtils.getRotation(mContext) != RotationUtils.ROTATION_NONE) { mDialog.getLayoutParams().width = (int) mDialogWidth; @@ -329,6 +350,10 @@ public abstract class BiometricDialogView extends LinearLayout { positive.setVisibility(View.VISIBLE); } + public void setUserId(int userId) { + mUserId = userId; + } + public ViewGroup getLayout() { return mLayout; } diff --git a/packages/SystemUI/src/com/android/systemui/car/CarNotificationEntryManager.java b/packages/SystemUI/src/com/android/systemui/car/CarNotificationEntryManager.java index 96af08b6bf6b..50fefe948aa8 100644 --- a/packages/SystemUI/src/com/android/systemui/car/CarNotificationEntryManager.java +++ b/packages/SystemUI/src/com/android/systemui/car/CarNotificationEntryManager.java @@ -17,9 +17,9 @@ package com.android.systemui.car; import android.content.Context; -import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import com.android.systemui.statusbar.notification.NotificationData; import com.android.systemui.statusbar.notification.NotificationEntryManager; +import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; public class CarNotificationEntryManager extends NotificationEntryManager { public CarNotificationEntryManager(Context context) { diff --git a/packages/SystemUI/src/com/android/systemui/car/CarSystemUIFactory.java b/packages/SystemUI/src/com/android/systemui/car/CarSystemUIFactory.java index e4b2e07dc81e..09c000b469a7 100644 --- a/packages/SystemUI/src/com/android/systemui/car/CarSystemUIFactory.java +++ b/packages/SystemUI/src/com/android/systemui/car/CarSystemUIFactory.java @@ -23,10 +23,10 @@ import com.android.keyguard.ViewMediatorCallback; import com.android.systemui.Dependency.DependencyProvider; import com.android.systemui.SystemUIFactory; import com.android.systemui.statusbar.NotificationMediaManager; -import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.car.CarFacetButtonController; import com.android.systemui.statusbar.car.CarStatusBarKeyguardViewManager; import com.android.systemui.statusbar.car.hvac.HvacController; +import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager; /** diff --git a/packages/SystemUI/src/com/android/systemui/chooser/ChooserActivity.java b/packages/SystemUI/src/com/android/systemui/chooser/ChooserActivity.java index 158deb46f8d2..28a38083218e 100644 --- a/packages/SystemUI/src/com/android/systemui/chooser/ChooserActivity.java +++ b/packages/SystemUI/src/com/android/systemui/chooser/ChooserActivity.java @@ -17,16 +17,7 @@ package com.android.systemui.chooser; import android.app.Activity; -import android.app.ActivityManager; -import android.content.Intent; import android.os.Bundle; -import android.os.IBinder; -import android.util.Log; - -import com.android.systemui.R; - -import java.lang.Thread; -import java.util.ArrayList; /** * Activity for selecting which application ought to handle an ACTION_SEND intent. diff --git a/packages/SystemUI/src/com/android/systemui/classifier/AnglesClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/AnglesClassifier.java index cdf4ba7d99d7..6d13973d23b5 100644 --- a/packages/SystemUI/src/com/android/systemui/classifier/AnglesClassifier.java +++ b/packages/SystemUI/src/com/android/systemui/classifier/AnglesClassifier.java @@ -18,7 +18,6 @@ package com.android.systemui.classifier; import android.os.Build; import android.os.SystemProperties; -import android.util.Log; import android.view.MotionEvent; import java.util.ArrayList; diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingLog.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingLog.java index 71ddba5ffdcc..cb7c998fad8e 100644 --- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingLog.java +++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingLog.java @@ -23,8 +23,6 @@ import android.os.SystemProperties; import android.util.Log; import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; import java.io.IOException; import java.io.PrintWriter; import java.text.SimpleDateFormat; diff --git a/packages/SystemUI/src/com/android/systemui/classifier/HumanInteractionClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/HumanInteractionClassifier.java index 592a275edaa0..577d57a9990e 100644 --- a/packages/SystemUI/src/com/android/systemui/classifier/HumanInteractionClassifier.java +++ b/packages/SystemUI/src/com/android/systemui/classifier/HumanInteractionClassifier.java @@ -24,13 +24,11 @@ import android.os.Looper; import android.os.UserHandle; import android.provider.Settings; import android.util.DisplayMetrics; -import android.util.Log; import android.view.MotionEvent; import com.android.systemui.R; import java.util.ArrayDeque; -import java.util.ArrayList; /** * An classifier trying to determine whether it is a human interacting with the phone or not. diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java b/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java index e2047bf89833..d93ed1785a0a 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java @@ -22,7 +22,6 @@ import android.content.Context; import android.hardware.Sensor; import android.hardware.SensorManager; import android.os.Handler; -import android.os.PowerManager; import com.android.internal.hardware.AmbientDisplayConfiguration; import com.android.keyguard.KeyguardUpdateMonitor; diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeReceiver.java b/packages/SystemUI/src/com/android/systemui/doze/DozeReceiver.java index 30dfd3622198..4a2e06c058cb 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeReceiver.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeReceiver.java @@ -22,11 +22,6 @@ package com.android.systemui.doze; public interface DozeReceiver { /** - * If device enters or leaves doze mode - */ - void setDozing(boolean dozing); - - /** * Invoked every time a minute is elapsed in doze mode */ void dozeTimeTick(); diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeScreenStatePreventingAdapter.java b/packages/SystemUI/src/com/android/systemui/doze/DozeScreenStatePreventingAdapter.java index 4fc2d9bd344b..25c2c39f3e25 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeScreenStatePreventingAdapter.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeScreenStatePreventingAdapter.java @@ -16,9 +16,10 @@ package com.android.systemui.doze; -import androidx.annotation.VisibleForTesting; import android.view.Display; +import androidx.annotation.VisibleForTesting; + import com.android.systemui.statusbar.phone.DozeParameters; /** diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeSuspendScreenStatePreventingAdapter.java b/packages/SystemUI/src/com/android/systemui/doze/DozeSuspendScreenStatePreventingAdapter.java index 3013b969c74b..a0c490951199 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeSuspendScreenStatePreventingAdapter.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeSuspendScreenStatePreventingAdapter.java @@ -16,9 +16,10 @@ package com.android.systemui.doze; -import androidx.annotation.VisibleForTesting; import android.view.Display; +import androidx.annotation.VisibleForTesting; + import com.android.systemui.statusbar.phone.DozeParameters; /** diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeWallpaperState.java b/packages/SystemUI/src/com/android/systemui/doze/DozeWallpaperState.java index 47f86fed7e69..9a5a5b855999 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeWallpaperState.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeWallpaperState.java @@ -23,8 +23,6 @@ import android.os.ServiceManager; import android.util.Log; import com.android.internal.annotations.VisibleForTesting; -import com.android.keyguard.KeyguardUpdateMonitor; -import com.android.keyguard.KeyguardUpdateMonitorCallback; import com.android.systemui.statusbar.phone.DozeParameters; import java.io.PrintWriter; diff --git a/packages/SystemUI/src/com/android/systemui/egg/MLandActivity.java b/packages/SystemUI/src/com/android/systemui/egg/MLandActivity.java index f06ea451d4d0..84b91bc8e3a1 100644 --- a/packages/SystemUI/src/com/android/systemui/egg/MLandActivity.java +++ b/packages/SystemUI/src/com/android/systemui/egg/MLandActivity.java @@ -19,7 +19,6 @@ package com.android.systemui.egg; import android.app.Activity; import android.os.Bundle; import android.view.View; -import android.view.ViewGroup; import com.android.systemui.R; diff --git a/packages/SystemUI/src/com/android/systemui/fragments/FragmentHostManager.java b/packages/SystemUI/src/com/android/systemui/fragments/FragmentHostManager.java index 0ed1cd128caa..60e39b21680b 100644 --- a/packages/SystemUI/src/com/android/systemui/fragments/FragmentHostManager.java +++ b/packages/SystemUI/src/com/android/systemui/fragments/FragmentHostManager.java @@ -28,11 +28,12 @@ import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.os.Parcelable; -import androidx.annotation.NonNull; import android.util.ArrayMap; import android.view.LayoutInflater; import android.view.View; +import androidx.annotation.NonNull; + import com.android.settingslib.applications.InterestingConfigChanges; import com.android.systemui.Dependency; import com.android.systemui.plugins.Plugin; @@ -59,11 +60,11 @@ public class FragmentHostManager { private FragmentController mFragments; private FragmentLifecycleCallbacks mLifecycleCallbacks; - FragmentHostManager(Context context, FragmentService manager, View rootView) { - mContext = context; + FragmentHostManager(FragmentService manager, View rootView) { + mContext = rootView.getContext(); mManager = manager; mRootView = rootView; - mConfigChanges.applyNewConfig(context.getResources()); + mConfigChanges.applyNewConfig(mContext.getResources()); createFragmentHost(null); } @@ -203,6 +204,10 @@ public class FragmentHostManager { } } + public static void removeAndDestroy(View view) { + Dependency.get(FragmentService.class).removeAndDestroy(view); + } + class HostCallbacks extends FragmentHostCallback<FragmentHostManager> { public HostCallbacks() { super(mContext, FragmentHostManager.this.mHandler, 0); diff --git a/packages/SystemUI/src/com/android/systemui/fragments/FragmentService.java b/packages/SystemUI/src/com/android/systemui/fragments/FragmentService.java index f9bf4f59a32a..bf7d629c5d7a 100644 --- a/packages/SystemUI/src/com/android/systemui/fragments/FragmentService.java +++ b/packages/SystemUI/src/com/android/systemui/fragments/FragmentService.java @@ -14,18 +14,13 @@ package com.android.systemui.fragments; -import android.content.Context; import android.content.res.Configuration; -import android.os.Bundle; import android.os.Handler; import android.util.ArrayMap; -import android.util.Log; import android.view.View; import com.android.systemui.ConfigurationChangedReceiver; import com.android.systemui.Dumpable; -import com.android.systemui.SystemUI; -import com.android.systemui.SystemUIApplication; import java.io.FileDescriptor; import java.io.PrintWriter; @@ -40,11 +35,6 @@ public class FragmentService implements ConfigurationChangedReceiver, Dumpable { private final ArrayMap<View, FragmentHostState> mHosts = new ArrayMap<>(); private final Handler mHandler = new Handler(); - private final Context mContext; - - public FragmentService(Context context) { - mContext = context; - } public FragmentHostManager getFragmentHostManager(View view) { View root = view.getRootView(); @@ -56,6 +46,13 @@ public class FragmentService implements ConfigurationChangedReceiver, Dumpable { return state.getFragmentHostManager(); } + public void removeAndDestroy(View view) { + final FragmentHostState state = mHosts.remove(view.getRootView()); + if (state != null) { + state.mFragmentHostManager.destroy(); + } + } + public void destroyAll() { for (FragmentHostState state : mHosts.values()) { state.mFragmentHostManager.destroy(); @@ -84,7 +81,7 @@ public class FragmentService implements ConfigurationChangedReceiver, Dumpable { public FragmentHostState(View view) { mView = view; - mFragmentHostManager = new FragmentHostManager(mContext, FragmentService.this, mView); + mFragmentHostManager = new FragmentHostManager(FragmentService.this, mView); } public void sendConfigurationChange(Configuration newConfig) { diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/KeyboardUI.java b/packages/SystemUI/src/com/android/systemui/keyboard/KeyboardUI.java index e0657c90238f..7d52a9a08c2a 100644 --- a/packages/SystemUI/src/com/android/systemui/keyboard/KeyboardUI.java +++ b/packages/SystemUI/src/com/android/systemui/keyboard/KeyboardUI.java @@ -43,12 +43,12 @@ import android.util.Slog; import android.widget.Toast; import com.android.settingslib.bluetooth.BluetoothCallback; +import com.android.settingslib.bluetooth.BluetoothUtils; import com.android.settingslib.bluetooth.CachedBluetoothDevice; import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager; import com.android.settingslib.bluetooth.LocalBluetoothAdapter; import com.android.settingslib.bluetooth.LocalBluetoothManager; import com.android.settingslib.bluetooth.LocalBluetoothProfileManager; -import com.android.settingslib.bluetooth.BluetoothUtils; import com.android.systemui.Dependency; import com.android.systemui.R; import com.android.systemui.SystemUI; diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/DismissCallbackRegistry.java b/packages/SystemUI/src/com/android/systemui/keyguard/DismissCallbackRegistry.java index d833c16c04b3..7bec5c0349f9 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/DismissCallbackRegistry.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/DismissCallbackRegistry.java @@ -19,6 +19,7 @@ package com.android.systemui.keyguard; import com.android.internal.policy.IKeyguardDismissCallback; import com.android.systemui.Dependency; import com.android.systemui.UiOffloadThread; + import java.util.ArrayList; /** diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardLifecyclesDispatcher.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardLifecyclesDispatcher.java index 4c98c08222e3..b3481c52d7f2 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardLifecyclesDispatcher.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardLifecyclesDispatcher.java @@ -19,8 +19,6 @@ package com.android.systemui.keyguard; import android.os.Handler; import android.os.Message; -import com.android.internal.policy.IKeyguardDrawnCallback; - /** * Dispatches the lifecycles keyguard gets from WindowManager on the main thread. */ diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java index 22b41a4f9cfa..81247cd2f727 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java @@ -16,6 +16,8 @@ package com.android.systemui.keyguard; +import static android.content.pm.PackageManager.PERMISSION_GRANTED; + import android.app.Service; import android.content.Intent; import android.os.Binder; @@ -34,8 +36,6 @@ import com.android.internal.policy.IKeyguardStateCallback; import com.android.systemui.Dependency; import com.android.systemui.SystemUIApplication; -import static android.content.pm.PackageManager.PERMISSION_GRANTED; - public class KeyguardService extends Service { static final String TAG = "KeyguardService"; static final String PERMISSION = android.Manifest.permission.CONTROL_KEYGUARD; diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java index fe1b35609ae5..3b9110d31c6f 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java @@ -1940,11 +1940,6 @@ public class KeyguardViewMediator extends SystemUI { mContext.getSystemService(Context.STATUS_BAR_SERVICE); } - // TODO(b/113914868): investigation log for disappearing home button - Log.d(TAG, "adjustStatusBarLocked (b/113914868): mShowing=" + mShowing - + " mStatusBarManager=" + mStatusBarManager + " mOccluded=" - + mOccluded + " isSecure=" + isSecure() + " force=" + forceHideHomeRecentsButtons); - if (mStatusBarManager == null) { Log.w(TAG, "Could not get status bar manager"); } else { @@ -1961,6 +1956,12 @@ public class KeyguardViewMediator extends SystemUI { + " --> flags=0x" + Integer.toHexString(flags)); } + // TODO(b/113914868): investigation log for disappearing home button + Log.d(TAG, "adjustStatusBarLocked (b/113914868): flags=" + flags + + "mShowing=" + mShowing + " mStatusBarManager=" + mStatusBarManager + + " mOccluded=" + mOccluded + " isSecure=" + isSecure() + + " force=" + forceHideHomeRecentsButtons); + mStatusBarManager.disable(flags); } } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/WorkLockActivityController.java b/packages/SystemUI/src/com/android/systemui/keyguard/WorkLockActivityController.java index 74f770679cc9..6498b9161be7 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/WorkLockActivityController.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/WorkLockActivityController.java @@ -28,6 +28,7 @@ import android.os.Bundle; import android.os.RemoteException; import android.os.UserHandle; import android.util.Log; + import com.android.internal.annotations.VisibleForTesting; import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.shared.system.TaskStackChangeListener; diff --git a/packages/SystemUI/src/com/android/systemui/media/RingtonePlayer.java b/packages/SystemUI/src/com/android/systemui/media/RingtonePlayer.java index ab612dd93dd1..ddd9cbf209d6 100644 --- a/packages/SystemUI/src/com/android/systemui/media/RingtonePlayer.java +++ b/packages/SystemUI/src/com/android/systemui/media/RingtonePlayer.java @@ -33,10 +33,8 @@ import android.os.RemoteException; import android.os.ServiceManager; import android.os.UserHandle; import android.provider.MediaStore; -import android.provider.MediaStore.Audio.AudioColumns; import android.util.Log; -import com.android.internal.util.Preconditions; import com.android.systemui.SystemUI; import java.io.FileDescriptor; diff --git a/packages/SystemUI/src/com/android/systemui/pip/PipUI.java b/packages/SystemUI/src/com/android/systemui/pip/PipUI.java index 70b581a78ce4..7792e177b601 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/PipUI.java +++ b/packages/SystemUI/src/com/android/systemui/pip/PipUI.java @@ -23,8 +23,10 @@ import android.content.pm.PackageManager; import android.content.res.Configuration; import android.os.UserHandle; import android.os.UserManager; + import com.android.systemui.SystemUI; import com.android.systemui.statusbar.CommandQueue; + import java.io.FileDescriptor; import java.io.PrintWriter; 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 9ce2606a2a15..8615e43b73fe 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipDismissViewController.java +++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipDismissViewController.java @@ -27,6 +27,7 @@ import android.view.View; import android.view.WindowManager; import android.view.WindowManager.LayoutParams; import android.widget.FrameLayout; + import com.android.systemui.Interpolators; import com.android.systemui.R; import com.android.systemui.shared.system.WindowManagerWrapper; diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java index 08208e506f24..8c3f43635f72 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java +++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java @@ -35,6 +35,7 @@ import android.view.IPinnedStackController; import android.view.IPinnedStackListener; import android.view.IWindowManager; import android.view.WindowManagerGlobal; + import com.android.systemui.Dependency; import com.android.systemui.UiOffloadThread; import com.android.systemui.pip.BasePipManager; @@ -42,6 +43,7 @@ import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.shared.system.InputConsumerController; import com.android.systemui.shared.system.TaskStackChangeListener; import com.android.systemui.shared.system.WindowManagerWrapper; + import java.io.PrintWriter; /** diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java index b746c192cece..e447defadd08 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java +++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java @@ -23,15 +23,14 @@ import static android.provider.Settings.ACTION_PICTURE_IN_PICTURE_SETTINGS; import static com.android.systemui.pip.phone.PipMenuActivityController.EXTRA_ACTIONS; import static com.android.systemui.pip.phone.PipMenuActivityController.EXTRA_ALLOW_TIMEOUT; import static com.android.systemui.pip.phone.PipMenuActivityController.EXTRA_CONTROLLER_MESSENGER; -import static com.android.systemui.pip.phone.PipMenuActivityController.EXTRA_WILL_RESIZE_MENU; import static com.android.systemui.pip.phone.PipMenuActivityController.EXTRA_DISMISS_FRACTION; -import static com.android.systemui.pip.phone.PipMenuActivityController.EXTRA_MOVEMENT_BOUNDS; import static com.android.systemui.pip.phone.PipMenuActivityController.EXTRA_MENU_STATE; +import static com.android.systemui.pip.phone.PipMenuActivityController.EXTRA_MOVEMENT_BOUNDS; import static com.android.systemui.pip.phone.PipMenuActivityController.EXTRA_STACK_BOUNDS; - -import static com.android.systemui.pip.phone.PipMenuActivityController.MENU_STATE_NONE; +import static com.android.systemui.pip.phone.PipMenuActivityController.EXTRA_WILL_RESIZE_MENU; import static com.android.systemui.pip.phone.PipMenuActivityController.MENU_STATE_CLOSE; import static com.android.systemui.pip.phone.PipMenuActivityController.MENU_STATE_FULL; +import static com.android.systemui.pip.phone.PipMenuActivityController.MENU_STATE_NONE; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; 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 56b83247a15e..46d53e410725 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java +++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java @@ -37,8 +37,10 @@ import android.os.RemoteException; import android.os.SystemClock; import android.os.UserHandle; import android.util.Log; + import com.android.systemui.pip.phone.PipMediaController.ActionListener; import com.android.systemui.shared.system.InputConsumerController; + import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java index ce7da79de794..38583564f5b0 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java +++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java @@ -18,6 +18,7 @@ package com.android.systemui.pip.phone; import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; + import static com.android.systemui.Interpolators.FAST_OUT_LINEAR_IN; import static com.android.systemui.Interpolators.FAST_OUT_SLOW_IN; import static com.android.systemui.Interpolators.LINEAR_OUT_SLOW_IN; @@ -42,11 +43,13 @@ import android.os.Message; import android.os.RemoteException; import android.util.Log; import android.view.animation.Interpolator; + import com.android.internal.graphics.SfVsyncFrameCallbackProvider; import com.android.internal.os.SomeArgs; import com.android.internal.policy.PipSnapAlgorithm; import com.android.systemui.shared.system.WindowManagerWrapper; import com.android.systemui.statusbar.FlingAnimationUtils; + import java.io.PrintWriter; /** diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchState.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchState.java index b9369d39dd51..9aa21f8270b3 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchState.java +++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchState.java @@ -18,7 +18,6 @@ package com.android.systemui.pip.phone; import android.graphics.PointF; import android.os.Handler; -import android.os.SystemClock; import android.util.Log; import android.view.MotionEvent; import android.view.VelocityTracker; diff --git a/packages/SystemUI/src/com/android/systemui/pip/tv/PipControlsView.java b/packages/SystemUI/src/com/android/systemui/pip/tv/PipControlsView.java index 10206d492e3a..a40b72b30f22 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/tv/PipControlsView.java +++ b/packages/SystemUI/src/com/android/systemui/pip/tv/PipControlsView.java @@ -16,7 +16,6 @@ package com.android.systemui.pip.tv; -import android.app.ActivityManager; import android.app.PendingIntent.CanceledException; import android.app.RemoteAction; import android.content.Context; @@ -24,20 +23,15 @@ import android.graphics.Color; import android.media.session.MediaController; import android.media.session.PlaybackState; import android.os.Handler; -import android.os.RemoteException; +import android.util.AttributeSet; import android.util.Log; -import android.view.View; import android.view.Gravity; import android.view.LayoutInflater; -import android.widget.ImageView; +import android.view.View; import android.widget.LinearLayout; -import android.util.AttributeSet; import com.android.systemui.R; -import static android.media.session.PlaybackState.ACTION_PAUSE; -import static android.media.session.PlaybackState.ACTION_PLAY; - import java.util.ArrayList; import java.util.List; diff --git a/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java index e17e0bca56dc..ca3cdf4bee80 100755 --- a/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java +++ b/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java @@ -49,6 +49,7 @@ import android.view.IPinnedStackController; import android.view.IPinnedStackListener; import android.view.IWindowManager; import android.view.WindowManagerGlobal; + import com.android.systemui.Dependency; import com.android.systemui.R; import com.android.systemui.UiOffloadThread; @@ -56,7 +57,7 @@ import com.android.systemui.pip.BasePipManager; import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.shared.system.TaskStackChangeListener; import com.android.systemui.shared.system.WindowManagerWrapper; -import java.io.PrintWriter; + import java.util.ArrayList; import java.util.List; diff --git a/packages/SystemUI/src/com/android/systemui/pip/tv/PipMenuActivity.java b/packages/SystemUI/src/com/android/systemui/pip/tv/PipMenuActivity.java index e437eff28a08..3a5fa2253057 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/tv/PipMenuActivity.java +++ b/packages/SystemUI/src/com/android/systemui/pip/tv/PipMenuActivity.java @@ -22,7 +22,6 @@ import android.app.Activity; import android.content.Intent; import android.content.pm.ParceledListSlice; import android.os.Bundle; -import android.view.View; import com.android.systemui.R; diff --git a/packages/SystemUI/src/com/android/systemui/pip/tv/PipNotification.java b/packages/SystemUI/src/com/android/systemui/pip/tv/PipNotification.java index ac41b752020b..89ecc6abd623 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/tv/PipNotification.java +++ b/packages/SystemUI/src/com/android/systemui/pip/tv/PipNotification.java @@ -26,17 +26,15 @@ import android.content.IntentFilter; import android.content.pm.ParceledListSlice; import android.content.res.Resources; import android.graphics.Bitmap; -import android.graphics.drawable.Icon; import android.media.MediaMetadata; import android.media.session.MediaController; import android.media.session.PlaybackState; import android.text.TextUtils; import android.util.Log; -import android.view.View; -import com.android.systemui.util.NotificationChannels; -import com.android.systemui.R; import com.android.internal.messages.nano.SystemMessageProto.SystemMessage; +import com.android.systemui.R; +import com.android.systemui.util.NotificationChannels; /** * A notification that informs users that PIP is running and also provides PIP controls. diff --git a/packages/SystemUI/src/com/android/systemui/power/EnhancedEstimatesImpl.java b/packages/SystemUI/src/com/android/systemui/power/EnhancedEstimatesImpl.java index 5686d801bca2..3f2417638f1a 100644 --- a/packages/SystemUI/src/com/android/systemui/power/EnhancedEstimatesImpl.java +++ b/packages/SystemUI/src/com/android/systemui/power/EnhancedEstimatesImpl.java @@ -1,7 +1,5 @@ package com.android.systemui.power; -import android.util.Log; - public class EnhancedEstimatesImpl implements EnhancedEstimates { @Override diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java index 21eab592098d..b722f9f1d1c1 100644 --- a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java +++ b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java @@ -41,6 +41,7 @@ import android.text.style.URLSpan; import android.util.Log; import android.util.Slog; import android.view.View; + import androidx.annotation.VisibleForTesting; import com.android.internal.messages.nano.SystemMessageProto.SystemMessage; diff --git a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialogBuilder.kt b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialogBuilder.kt index 2f86f78d7669..5ce4ee738373 100644 --- a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialogBuilder.kt +++ b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialogBuilder.kt @@ -16,7 +16,6 @@ package com.android.systemui.privacy import android.content.Context import com.android.systemui.R -import java.lang.IllegalStateException import java.lang.Math.max class PrivacyDialogBuilder(val context: Context, itemsList: List<PrivacyItem>) { @@ -71,4 +70,4 @@ class PrivacyDialogBuilder(val context: Context, itemsList: List<PrivacyItem>) { fun generateTypesText() = itemsByType.keys.map { it.getName(context) }.sorted().joinToString() fun generateIcons() = itemsByType.keys.map { it.getIcon(context) } -}
\ No newline at end of file +} diff --git a/packages/SystemUI/src/com/android/systemui/qs/AlphaControlledSignalTileView.java b/packages/SystemUI/src/com/android/systemui/qs/AlphaControlledSignalTileView.java index 2c7ec70a5fff..6a6f5728fc5b 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/AlphaControlledSignalTileView.java +++ b/packages/SystemUI/src/com/android/systemui/qs/AlphaControlledSignalTileView.java @@ -19,6 +19,7 @@ package com.android.systemui.qs; import android.content.Context; import android.content.res.ColorStateList; import android.graphics.drawable.Drawable; + import com.android.systemui.qs.tileimpl.SlashImageView; diff --git a/packages/SystemUI/src/com/android/systemui/qs/AutoSizingList.java b/packages/SystemUI/src/com/android/systemui/qs/AutoSizingList.java index 767fd9efd4f0..1195184050e3 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/AutoSizingList.java +++ b/packages/SystemUI/src/com/android/systemui/qs/AutoSizingList.java @@ -23,6 +23,7 @@ import android.util.AttributeSet; import android.view.View; import android.widget.LinearLayout; import android.widget.ListAdapter; + import com.android.systemui.R; /** diff --git a/packages/SystemUI/src/com/android/systemui/qs/CellTileView.java b/packages/SystemUI/src/com/android/systemui/qs/CellTileView.java index 376e6ae16cc8..c1aa7069d6ba 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/CellTileView.java +++ b/packages/SystemUI/src/com/android/systemui/qs/CellTileView.java @@ -20,7 +20,6 @@ import android.service.quicksettings.Tile; import android.widget.ImageView; import com.android.settingslib.graph.SignalDrawable; -import com.android.settingslib.Utils; import com.android.systemui.R; import com.android.systemui.plugins.qs.QSTile.Icon; import com.android.systemui.plugins.qs.QSTile.State; diff --git a/packages/SystemUI/src/com/android/systemui/qs/DataUsageGraph.java b/packages/SystemUI/src/com/android/systemui/qs/DataUsageGraph.java index 6aad47927a15..afce69e7f2d0 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/DataUsageGraph.java +++ b/packages/SystemUI/src/com/android/systemui/qs/DataUsageGraph.java @@ -18,7 +18,6 @@ package com.android.systemui.qs; import android.content.Context; import android.content.res.Resources; -import android.content.res.ColorStateList; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.RectF; diff --git a/packages/SystemUI/src/com/android/systemui/qs/PageIndicator.java b/packages/SystemUI/src/com/android/systemui/qs/PageIndicator.java index aa2f8d171143..d5c5ba401e99 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/PageIndicator.java +++ b/packages/SystemUI/src/com/android/systemui/qs/PageIndicator.java @@ -6,10 +6,10 @@ import android.content.res.TypedArray; import android.graphics.drawable.AnimatedVectorDrawable; import android.util.AttributeSet; import android.util.Log; -import android.util.TypedValue; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; + import com.android.systemui.R; import java.util.ArrayList; diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java index 1451e71e2df5..dbd304233601 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java @@ -23,14 +23,11 @@ import android.content.Context; import android.content.res.Configuration; import android.graphics.Point; import android.util.AttributeSet; -import android.util.Log; import android.view.View; import android.widget.FrameLayout; import com.android.systemui.R; -import com.android.systemui.SysUiServiceProvider; import com.android.systemui.qs.customize.QSCustomizer; -import com.android.systemui.statusbar.CommandQueue; /** * Wrapper view with background which contains {@link QSPanel} and {@link BaseStatusBarHeader} diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSDetailItems.java b/packages/SystemUI/src/com/android/systemui/qs/QSDetailItems.java index ddd991023273..dab0efe10b5d 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSDetailItems.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSDetailItems.java @@ -32,6 +32,7 @@ import android.widget.BaseAdapter; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.TextView; + import com.android.systemui.FontSizeUtils; import com.android.systemui.R; import com.android.systemui.plugins.qs.QSTile; diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java b/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java index 84eb3da51bcf..b597a72ba899 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java @@ -15,9 +15,10 @@ */ package com.android.systemui.qs; -import androidx.annotation.Nullable; import android.view.View; +import androidx.annotation.Nullable; + /** * The bottom footer of the quick settings panel. */ diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java b/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java index f147fb3054b7..8903a38dc600 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java @@ -28,8 +28,6 @@ import android.graphics.drawable.Drawable; import android.graphics.drawable.RippleDrawable; import android.os.Bundle; import android.os.UserManager; -import androidx.annotation.Nullable; -import androidx.annotation.VisibleForTesting; import android.text.TextUtils; import android.util.AttributeSet; import android.view.View; @@ -40,6 +38,9 @@ import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.Toast; +import androidx.annotation.Nullable; +import androidx.annotation.VisibleForTesting; + import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto; import com.android.keyguard.CarrierText; diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java index f9971d83addc..953eb70cac5d 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java @@ -22,8 +22,6 @@ import android.app.Fragment; import android.content.res.Configuration; import android.graphics.Rect; import android.os.Bundle; -import androidx.annotation.Nullable; -import androidx.annotation.VisibleForTesting; import android.util.Log; import android.view.ContextThemeWrapper; import android.view.LayoutInflater; @@ -34,6 +32,9 @@ import android.view.ViewGroup; import android.view.ViewTreeObserver; import android.widget.FrameLayout.LayoutParams; +import androidx.annotation.Nullable; +import androidx.annotation.VisibleForTesting; + import com.android.systemui.Dependency; import com.android.systemui.Interpolators; import com.android.systemui.R; @@ -42,9 +43,9 @@ import com.android.systemui.SysUiServiceProvider; import com.android.systemui.plugins.qs.QS; import com.android.systemui.qs.customize.QSCustomizer; import com.android.systemui.statusbar.CommandQueue; +import com.android.systemui.statusbar.notification.stack.StackStateAnimator; import com.android.systemui.statusbar.phone.NotificationsQuickSettingsContainer; import com.android.systemui.statusbar.policy.RemoteInputQuickSettingsDisabler; -import com.android.systemui.statusbar.notification.stack.StackStateAnimator; public class QSFragment extends Fragment implements QS, CommandQueue.Callbacks { private static final String TAG = "QS"; diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java index cf63e478312c..f1f0f698ab72 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java @@ -17,6 +17,7 @@ package com.android.systemui.qs; import static android.content.res.Configuration.ORIENTATION_LANDSCAPE; + import static com.android.systemui.qs.tileimpl.QSTileImpl.getColorForState; import android.annotation.Nullable; @@ -30,7 +31,6 @@ import android.os.Handler; import android.os.Message; import android.service.quicksettings.Tile; import android.util.AttributeSet; -import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.widget.LinearLayout; diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSScrollLayout.java b/packages/SystemUI/src/com/android/systemui/qs/QSScrollLayout.java index 7ebab0bfce24..001cbbac5606 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSScrollLayout.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSScrollLayout.java @@ -17,7 +17,6 @@ package com.android.systemui.qs; import android.animation.ObjectAnimator; import android.content.Context; import android.graphics.Canvas; -import androidx.core.widget.NestedScrollView; import android.util.Property; import android.view.MotionEvent; import android.view.View; @@ -25,6 +24,8 @@ import android.view.ViewConfiguration; import android.view.ViewParent; import android.widget.LinearLayout; +import androidx.core.widget.NestedScrollView; + import com.android.systemui.R; import com.android.systemui.qs.touch.OverScroll; import com.android.systemui.qs.touch.SwipeDetector; diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java b/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java index 8f3a7b3c04e9..e2e943a369c2 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java @@ -33,8 +33,8 @@ import android.util.Log; import android.view.ContextThemeWrapper; import android.view.LayoutInflater; import android.view.View; -import android.view.ViewGroup; import android.view.View.OnClickListener; +import android.view.ViewGroup; import android.view.Window; import android.widget.ImageView; import android.widget.TextView; @@ -46,8 +46,6 @@ import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.statusbar.phone.SystemUIDialog; import com.android.systemui.statusbar.policy.SecurityController; -import static android.provider.Settings.ACTION_VPN_SETTINGS; - public class QSSecurityFooter implements OnClickListener, DialogInterface.OnClickListener { protected static final String TAG = "QSSecurityFooter"; protected static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java b/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java index cefeeb526968..d1c2df53b5a5 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java @@ -31,14 +31,14 @@ import android.util.Log; import com.android.systemui.Dependency; import com.android.systemui.R; import com.android.systemui.plugins.PluginListener; -import com.android.systemui.shared.plugins.PluginManager; import com.android.systemui.plugins.qs.QSFactory; -import com.android.systemui.plugins.qs.QSTileView; import com.android.systemui.plugins.qs.QSTile; +import com.android.systemui.plugins.qs.QSTileView; import com.android.systemui.qs.external.CustomTile; import com.android.systemui.qs.external.TileLifecycleManager; import com.android.systemui.qs.external.TileServices; import com.android.systemui.qs.tileimpl.QSFactoryImpl; +import com.android.systemui.shared.plugins.PluginManager; import com.android.systemui.statusbar.phone.AutoTileManager; import com.android.systemui.statusbar.phone.StatusBar; import com.android.systemui.statusbar.phone.StatusBarIconController; diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java index 792909928258..e3f85d93b8da 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java @@ -15,6 +15,7 @@ package com.android.systemui.qs; import static android.app.StatusBarManager.DISABLE2_QUICK_SETTINGS; +import static android.provider.Settings.System.SHOW_BATTERY_PERCENT; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; @@ -28,12 +29,15 @@ import android.content.Intent; import android.content.IntentFilter; import android.content.res.Configuration; import android.content.res.Resources; +import android.database.ContentObserver; import android.graphics.Color; import android.graphics.Rect; import android.media.AudioManager; +import android.net.Uri; import android.os.Handler; import android.os.Looper; import android.provider.AlarmClock; +import android.provider.Settings; import android.service.notification.ZenModeConfig; import android.text.format.DateUtils; import android.util.AttributeSet; @@ -68,6 +72,7 @@ import com.android.systemui.statusbar.phone.StatusBarIconController; import com.android.systemui.statusbar.phone.StatusBarIconController.TintedIconManager; import com.android.systemui.statusbar.phone.StatusIconContainer; import com.android.systemui.statusbar.phone.SystemUIDialog; +import com.android.systemui.statusbar.policy.BatteryController; import com.android.systemui.statusbar.policy.Clock; import com.android.systemui.statusbar.policy.DarkIconDispatcher; import com.android.systemui.statusbar.policy.DarkIconDispatcher.DarkReceiver; @@ -132,6 +137,9 @@ public class QuickStatusBarHeader extends RelativeLayout implements private DateView mDateView; private OngoingPrivacyChip mPrivacyChip; private Space mSpace; + private BatteryMeterView mBatteryRemainingIcon; + private TextView mBatteryRemainingText; + private boolean mShowBatteryPercentAndEstimate; private NextAlarmController mAlarmController; private ZenModeController mZenController; @@ -148,6 +156,9 @@ public class QuickStatusBarHeader extends RelativeLayout implements }; private boolean mHasTopCutout = false; + private final PercentSettingObserver mPercentSettingObserver = + new PercentSettingObserver(new Handler(mContext.getMainLooper())); + /** * Runnable for automatically fading out the long press tooltip (as if it were animating away). */ @@ -204,8 +215,12 @@ public class QuickStatusBarHeader extends RelativeLayout implements // Set the correct tint for the status icons so they contrast mIconManager.setTint(fillColor); + mShowBatteryPercentAndEstimate = mContext.getResources().getBoolean( + com.android.internal.R.bool.config_battery_percentage_setting_available); + mBatteryMeterView = findViewById(R.id.battery); - mBatteryMeterView.setForceShowPercent(true); + mBatteryMeterView.setPercentShowMode(mShowBatteryPercentAndEstimate + ? BatteryMeterView.MODE_ON : BatteryMeterView.MODE_OFF); mBatteryMeterView.setOnClickListener(this); mClockView = findViewById(R.id.clock); mClockView.setOnClickListener(this); @@ -213,6 +228,15 @@ public class QuickStatusBarHeader extends RelativeLayout implements mPrivacyChip = findViewById(R.id.privacy_chip); mPrivacyChip.setOnClickListener(this); mSpace = findViewById(R.id.space); + + // Tint for the battery icons are handled in setupHost() + mBatteryRemainingIcon = findViewById(R.id.batteryRemainingIcon); + mBatteryRemainingIcon.setPercentShowMode(BatteryMeterView.MODE_OFF); + + mBatteryRemainingText = findViewById(R.id.batteryRemainingText); + mBatteryRemainingText.setTextColor(fillColor); + + updateShowPercent(); } private void updateStatusText() { @@ -371,6 +395,14 @@ public class QuickStatusBarHeader extends RelativeLayout implements .build(); } + private void updateBatteryRemainingText() { + if (!mShowBatteryPercentAndEstimate) { + return; + } + mBatteryRemainingText.setText( + Dependency.get(BatteryController.class).getEstimatedTimeRemainingString()); + } + public void setExpanded(boolean expanded) { if (mExpanded == expanded) return; mExpanded = expanded; @@ -436,6 +468,9 @@ public class QuickStatusBarHeader extends RelativeLayout implements super.onAttachedToWindow(); Dependency.get(StatusBarIconController.class).addIconGroup(mIconManager); requestApplyInsets(); + mContext.getContentResolver().registerContentObserver( + Settings.System.getUriFor(SHOW_BATTERY_PERCENT), false, mPercentSettingObserver, + ActivityManager.getCurrentUser()); } @Override @@ -475,6 +510,7 @@ public class QuickStatusBarHeader extends RelativeLayout implements public void onDetachedFromWindow() { setListening(false); Dependency.get(StatusBarIconController.class).removeIconGroup(mIconManager); + mContext.getContentResolver().unregisterContentObserver(mPercentSettingObserver); super.onDetachedFromWindow(); } @@ -491,6 +527,7 @@ public class QuickStatusBarHeader extends RelativeLayout implements mAlarmController.addCallback(this); mContext.registerReceiver(mRingerReceiver, new IntentFilter(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION)); + updateBatteryRemainingText(); } else { mZenController.removeCallback(this); mAlarmController.removeCallback(this); @@ -660,6 +697,14 @@ public class QuickStatusBarHeader extends RelativeLayout implements // Use SystemUI context to get battery meter colors, and let it use the default tint (white) mBatteryMeterView.setColorsFromContext(mHost.getContext()); mBatteryMeterView.onDarkChanged(new Rect(), 0, DarkIconDispatcher.DEFAULT_ICON_TINT); + + Rect tintArea = new Rect(0, 0, 0, 0); + int colorForeground = Utils.getColorAttrDefaultColor(getContext(), + android.R.attr.colorForeground); + float intensity = getColorIntensity(colorForeground); + int fillColor = fillColorForIntensity(intensity, getContext()); + mBatteryRemainingIcon.setColorsFromContext(mHost.getContext()); + mBatteryRemainingIcon.onDarkChanged(tintArea, intensity, fillColor); } public void setCallback(Callback qsPanelCallback) { @@ -692,4 +737,39 @@ public class QuickStatusBarHeader extends RelativeLayout implements lp.rightMargin = sideMargins; } } + + private void updateShowPercent() { + final boolean systemSetting = 0 != Settings.System + .getIntForUser(getContext().getContentResolver(), + SHOW_BATTERY_PERCENT, 0, ActivityManager.getCurrentUser()); + + mShowBatteryPercentAndEstimate = systemSetting; + + updateBatteryViews(); + } + + private void updateBatteryViews() { + if (mShowBatteryPercentAndEstimate) { + mBatteryMeterView.setPercentShowMode(BatteryMeterView.MODE_ON); + mBatteryRemainingIcon.setVisibility(View.VISIBLE); + mBatteryRemainingText.setVisibility(View.VISIBLE); + updateBatteryRemainingText(); + } else { + mBatteryMeterView.setPercentShowMode(BatteryMeterView.MODE_OFF); + mBatteryRemainingIcon.setVisibility(View.GONE); + mBatteryRemainingText.setVisibility(View.GONE); + } + } + + private final class PercentSettingObserver extends ContentObserver { + PercentSettingObserver(Handler handler) { + super(handler); + } + + @Override + public void onChange(boolean selfChange, Uri uri) { + super.onChange(selfChange, uri); + updateShowPercent(); + } + } } diff --git a/packages/SystemUI/src/com/android/systemui/qs/car/CarQSFooter.java b/packages/SystemUI/src/com/android/systemui/qs/car/CarQSFooter.java index f6b08b05bf38..0389030a17b2 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/car/CarQSFooter.java +++ b/packages/SystemUI/src/com/android/systemui/qs/car/CarQSFooter.java @@ -16,14 +16,14 @@ package com.android.systemui.qs.car; import android.content.Context; import android.content.Intent; import android.graphics.drawable.Drawable; -import androidx.annotation.Nullable; import android.util.AttributeSet; import android.util.Log; -import android.view.View; import android.widget.ImageView; import android.widget.RelativeLayout; import android.widget.TextView; +import androidx.annotation.Nullable; + import com.android.systemui.Dependency; import com.android.systemui.R; import com.android.systemui.plugins.ActivityStarter; diff --git a/packages/SystemUI/src/com/android/systemui/qs/car/CarQSFragment.java b/packages/SystemUI/src/com/android/systemui/qs/car/CarQSFragment.java index 2d9e4d7fc22b..3e82c54dc811 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/car/CarQSFragment.java +++ b/packages/SystemUI/src/com/android/systemui/qs/car/CarQSFragment.java @@ -22,14 +22,15 @@ import android.animation.ValueAnimator; import android.app.Fragment; import android.content.Context; import android.os.Bundle; -import androidx.annotation.Nullable; -import androidx.annotation.VisibleForTesting; -import androidx.recyclerview.widget.GridLayoutManager; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; +import androidx.annotation.Nullable; +import androidx.annotation.VisibleForTesting; +import androidx.recyclerview.widget.GridLayoutManager; + import com.android.systemui.R; import com.android.systemui.plugins.qs.QS; import com.android.systemui.qs.QSFooter; diff --git a/packages/SystemUI/src/com/android/systemui/qs/car/CarStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/qs/car/CarStatusBarHeader.java index 9b225bb9f18b..083a7471c3c1 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/car/CarStatusBarHeader.java +++ b/packages/SystemUI/src/com/android/systemui/qs/car/CarStatusBarHeader.java @@ -16,11 +16,12 @@ package com.android.systemui.qs.car; import android.content.Context; import android.graphics.Color; import android.graphics.Rect; -import androidx.annotation.IdRes; import android.util.AttributeSet; import android.view.View; import android.widget.LinearLayout; +import androidx.annotation.IdRes; + import com.android.settingslib.Utils; import com.android.systemui.BatteryMeterView; import com.android.systemui.R; diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java index dc17dd8fee63..64ad95c6eaea 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java +++ b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java @@ -20,13 +20,8 @@ import android.animation.Animator.AnimatorListener; import android.animation.AnimatorListenerAdapter; import android.content.Context; import android.content.res.Configuration; -import android.graphics.Point; import android.os.Bundle; -import androidx.recyclerview.widget.DefaultItemAnimator; -import androidx.recyclerview.widget.GridLayoutManager; -import androidx.recyclerview.widget.RecyclerView; import android.util.AttributeSet; -import android.util.Log; import android.util.TypedValue; import android.view.ContextThemeWrapper; import android.view.LayoutInflater; @@ -37,6 +32,10 @@ import android.widget.LinearLayout; import android.widget.Toolbar; import android.widget.Toolbar.OnMenuItemClickListener; +import androidx.recyclerview.widget.DefaultItemAnimator; +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto; import com.android.settingslib.Utils; diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java index 15d2e66a82ce..a29e93a57c69 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java +++ b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java @@ -23,13 +23,6 @@ import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.drawable.ColorDrawable; import android.os.Handler; -import androidx.core.view.ViewCompat; -import androidx.recyclerview.widget.GridLayoutManager.SpanSizeLookup; -import androidx.recyclerview.widget.RecyclerView; -import androidx.recyclerview.widget.RecyclerView.ItemDecoration; -import androidx.recyclerview.widget.RecyclerView.State; -import androidx.recyclerview.widget.RecyclerView.ViewHolder; -import androidx.recyclerview.widget.ItemTouchHelper; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; @@ -39,6 +32,14 @@ import android.view.accessibility.AccessibilityManager; import android.widget.FrameLayout; import android.widget.TextView; +import androidx.core.view.ViewCompat; +import androidx.recyclerview.widget.GridLayoutManager.SpanSizeLookup; +import androidx.recyclerview.widget.ItemTouchHelper; +import androidx.recyclerview.widget.RecyclerView; +import androidx.recyclerview.widget.RecyclerView.ItemDecoration; +import androidx.recyclerview.widget.RecyclerView.State; +import androidx.recyclerview.widget.RecyclerView.ViewHolder; + import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto; import com.android.systemui.R; 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 bb65bedd8aeb..89066651084d 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java @@ -15,6 +15,9 @@ */ package com.android.systemui.qs.external; +import static android.view.Display.DEFAULT_DISPLAY; +import static android.view.WindowManager.LayoutParams.TYPE_QS_DIALOG; + import android.app.ActivityManager; import android.content.ComponentName; import android.content.Intent; @@ -41,13 +44,11 @@ import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.systemui.Dependency; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.qs.QSTile.State; -import com.android.systemui.qs.tileimpl.QSTileImpl; -import com.android.systemui.qs.external.TileLifecycleManager.TileChangeListener; import com.android.systemui.qs.QSTileHost; -import java.util.Objects; +import com.android.systemui.qs.external.TileLifecycleManager.TileChangeListener; +import com.android.systemui.qs.tileimpl.QSTileImpl; -import static android.view.Display.DEFAULT_DISPLAY; -import static android.view.WindowManager.LayoutParams.TYPE_QS_DIALOG; +import java.util.Objects; public class CustomTile extends QSTileImpl<State> implements TileChangeListener { public static final String PREFIX = "custom("; diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/QSTileServiceWrapper.java b/packages/SystemUI/src/com/android/systemui/qs/external/QSTileServiceWrapper.java index 451e1f6ca827..2345667f0409 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/external/QSTileServiceWrapper.java +++ b/packages/SystemUI/src/com/android/systemui/qs/external/QSTileServiceWrapper.java @@ -16,9 +16,7 @@ package com.android.systemui.qs.external; import android.os.IBinder; -import android.service.quicksettings.IQSService; import android.service.quicksettings.IQSTileService; -import android.service.quicksettings.Tile; import android.util.Log; diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/TileColorPicker.java b/packages/SystemUI/src/com/android/systemui/qs/external/TileColorPicker.java index 75dd0d9e565d..1caab5aa77ef 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/external/TileColorPicker.java +++ b/packages/SystemUI/src/com/android/systemui/qs/external/TileColorPicker.java @@ -18,7 +18,9 @@ package com.android.systemui.qs.external; import android.content.Context; import android.content.res.ColorStateList; import android.service.quicksettings.Tile; + import androidx.annotation.VisibleForTesting; + import com.android.systemui.R; public class TileColorPicker { diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java b/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java index 4e0f38fc4662..305fbf2e3e98 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java +++ b/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java @@ -15,15 +15,14 @@ */ package com.android.systemui.qs.external; -import android.app.AppGlobals; 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.pm.PackageManager; import android.content.pm.ServiceInfo; -import android.content.ServiceConnection; import android.net.Uri; import android.os.Binder; import android.os.Handler; @@ -34,10 +33,10 @@ import android.service.quicksettings.IQSService; import android.service.quicksettings.IQSTileService; import android.service.quicksettings.Tile; import android.service.quicksettings.TileService; -import androidx.annotation.VisibleForTesting; import android.util.ArraySet; import android.util.Log; -import com.android.systemui.qs.external.PackageManagerAdapter; + +import androidx.annotation.VisibleForTesting; import java.util.Objects; import java.util.Set; diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/TileServiceManager.java b/packages/SystemUI/src/com/android/systemui/qs/external/TileServiceManager.java index 9f9fe39bab6c..416c2da53606 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/external/TileServiceManager.java +++ b/packages/SystemUI/src/com/android/systemui/qs/external/TileServiceManager.java @@ -30,9 +30,10 @@ import android.os.UserHandle; import android.service.quicksettings.IQSTileService; import android.service.quicksettings.Tile; import android.service.quicksettings.TileService; -import androidx.annotation.VisibleForTesting; import android.util.Log; +import androidx.annotation.VisibleForTesting; + import com.android.systemui.qs.external.TileLifecycleManager.TileChangeListener; import java.util.List; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java index ac7ef5dc308e..b2f60436fecd 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java @@ -20,8 +20,11 @@ import android.util.Log; import android.view.ContextThemeWrapper; import com.android.systemui.R; -import com.android.systemui.plugins.qs.*; +import com.android.systemui.plugins.qs.QSFactory; +import com.android.systemui.plugins.qs.QSIconView; +import com.android.systemui.plugins.qs.QSTile; import com.android.systemui.plugins.qs.QSTileView; +import com.android.systemui.qs.QSTileHost; import com.android.systemui.qs.external.CustomTile; import com.android.systemui.qs.tiles.AirplaneModeTile; import com.android.systemui.qs.tiles.BatterySaverTile; @@ -41,7 +44,6 @@ import com.android.systemui.qs.tiles.RotationLockTile; import com.android.systemui.qs.tiles.UserTile; import com.android.systemui.qs.tiles.WifiTile; import com.android.systemui.qs.tiles.WorkModeTile; -import com.android.systemui.qs.QSTileHost; import com.android.systemui.util.leak.GarbageMonitor; public class QSFactoryImpl implements QSFactory { diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSIconViewImpl.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSIconViewImpl.java index 9dd5d8fbc776..e2453128d4b0 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSIconViewImpl.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSIconViewImpl.java @@ -34,8 +34,8 @@ import com.android.systemui.R; import com.android.systemui.plugins.qs.QSIconView; import com.android.systemui.plugins.qs.QSTile; import com.android.systemui.plugins.qs.QSTile.State; - import com.android.systemui.qs.AlphaControlledSignalTileView.AlphaControlledSlashImageView; + import java.util.Objects; public class QSIconViewImpl extends QSIconView { diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/SlashImageView.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/SlashImageView.java index a3e9afd366fd..72c68ce12ca4 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/SlashImageView.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/SlashImageView.java @@ -17,9 +17,10 @@ package com.android.systemui.qs.tileimpl; import android.annotation.Nullable; import android.content.Context; import android.graphics.drawable.Drawable; -import androidx.annotation.NonNull; import android.widget.ImageView; +import androidx.annotation.NonNull; + import com.android.internal.annotations.VisibleForTesting; import com.android.systemui.plugins.qs.QSTile.SlashState; import com.android.systemui.qs.SlashDrawable; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java index 7f3537c2d41d..da2828eae7da 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java @@ -20,6 +20,7 @@ import android.content.Intent; import android.graphics.drawable.Drawable; import android.service.quicksettings.Tile; import android.widget.Switch; + import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settingslib.graph.BatteryMeterDrawableBase; import com.android.systemui.Dependency; 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 cd0031173f8b..c62a592be8e2 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java @@ -16,8 +16,6 @@ package com.android.systemui.qs.tiles; -import static com.android.settingslib.graph.BluetoothDeviceLayerDrawable.createLayerDrawable; - import android.annotation.Nullable; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothClass; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java index b93f1c208c11..c13a07fdd15e 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java @@ -22,14 +22,13 @@ import android.provider.Settings.Secure; import android.service.quicksettings.Tile; import android.widget.Switch; -import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.systemui.R; import com.android.systemui.R.drawable; -import com.android.systemui.qs.QSHost; import com.android.systemui.plugins.qs.QSTile.BooleanState; -import com.android.systemui.qs.tileimpl.QSTileImpl; +import com.android.systemui.qs.QSHost; import com.android.systemui.qs.SecureSetting; +import com.android.systemui.qs.tileimpl.QSTileImpl; /** Quick settings tile: Invert colors **/ public class ColorInversionTile extends QSTileImpl<BooleanState> { diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java index ace361bdb4e6..fd8b9c9534dc 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java @@ -18,6 +18,7 @@ import android.content.DialogInterface.OnClickListener; import android.content.Intent; import android.service.quicksettings.Tile; import android.widget.Switch; + import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.systemui.Dependency; import com.android.systemui.Prefs; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DataUsageDetailView.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DataUsageDetailView.java index 7bcc6d7b93a9..55785586464f 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DataUsageDetailView.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DataUsageDetailView.java @@ -16,11 +16,10 @@ package com.android.systemui.qs.tiles; -import android.annotation.ColorInt; import android.content.Context; +import android.content.res.ColorStateList; import android.content.res.Configuration; import android.content.res.Resources; -import android.content.res.ColorStateList; import android.util.AttributeSet; import android.view.View; import android.widget.LinearLayout; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/IntentTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/IntentTile.java index 3c565ef9d07f..a639a9525dd4 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/IntentTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/IntentTile.java @@ -29,13 +29,11 @@ import android.os.UserHandle; import android.text.TextUtils; import android.util.Log; -import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.systemui.Dependency; import com.android.systemui.plugins.ActivityStarter; -import com.android.systemui.qs.QSHost; -import com.android.systemui.plugins.qs.QSTile; import com.android.systemui.plugins.qs.QSTile.State; +import com.android.systemui.qs.QSHost; import com.android.systemui.qs.tileimpl.QSTileImpl; import java.util.Arrays; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java index d7f2a2642180..b5f2d005e8e4 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java @@ -27,8 +27,8 @@ import com.android.systemui.Dependency; import com.android.systemui.R; import com.android.systemui.R.drawable; import com.android.systemui.plugins.ActivityStarter; -import com.android.systemui.qs.QSHost; import com.android.systemui.plugins.qs.QSTile.BooleanState; +import com.android.systemui.qs.QSHost; import com.android.systemui.qs.tileimpl.QSTileImpl; import com.android.systemui.statusbar.policy.KeyguardMonitor; import com.android.systemui.statusbar.policy.LocationController; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/NfcTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/NfcTile.java index 9edd65e14bf2..a365e4c53b0d 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/NfcTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/NfcTile.java @@ -22,17 +22,15 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageManager; -import android.graphics.drawable.Drawable; import android.nfc.NfcAdapter; import android.provider.Settings; import android.service.quicksettings.Tile; import android.widget.Switch; -import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.systemui.R; -import com.android.systemui.qs.QSHost; import com.android.systemui.plugins.qs.QSTile.BooleanState; +import com.android.systemui.qs.QSHost; import com.android.systemui.qs.tileimpl.QSTileImpl; /** Quick settings tile: Enable/Disable NFC **/ diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java index c41f087aa76b..938dc0be2d85 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java @@ -24,16 +24,17 @@ import android.content.Intent; import android.metrics.LogMaker; import android.provider.Settings; import android.service.quicksettings.Tile; -import androidx.annotation.StringRes; import android.text.TextUtils; import android.util.Log; import android.widget.Switch; +import androidx.annotation.StringRes; + import com.android.internal.app.ColorDisplayController; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.systemui.R; -import com.android.systemui.qs.QSHost; import com.android.systemui.plugins.qs.QSTile.BooleanState; +import com.android.systemui.qs.QSHost; import com.android.systemui.qs.tileimpl.QSTileImpl; import java.text.DateFormat; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java index 28b047bad71d..634581638c32 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java @@ -19,17 +19,15 @@ package com.android.systemui.qs.tiles; import android.content.Context; import android.content.Intent; import android.content.res.Configuration; - import android.provider.Settings; import android.service.quicksettings.Tile; import android.widget.Switch; -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.qs.QSHost; import com.android.systemui.plugins.qs.QSTile.BooleanState; +import com.android.systemui.qs.QSHost; import com.android.systemui.qs.tileimpl.QSTileImpl; import com.android.systemui.statusbar.policy.RotationLockController; import com.android.systemui.statusbar.policy.RotationLockController.RotationLockControllerCallback; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailItemView.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailItemView.java index ad7d1b6b4689..64fe54aa656d 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailItemView.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailItemView.java @@ -30,7 +30,6 @@ import android.widget.LinearLayout; import android.widget.TextView; import com.android.internal.util.ArrayUtils; -import com.android.settingslib.drawable.UserIconDrawable; import com.android.systemui.FontSizeUtils; import com.android.systemui.R; import com.android.systemui.statusbar.phone.UserAvatarView; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserTile.java index bde1c98d023c..e5c51a66fafa 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserTile.java @@ -24,9 +24,9 @@ import android.util.Pair; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.systemui.Dependency; import com.android.systemui.plugins.qs.DetailAdapter; -import com.android.systemui.qs.QSHost; import com.android.systemui.plugins.qs.QSTile; import com.android.systemui.plugins.qs.QSTile.State; +import com.android.systemui.qs.QSHost; import com.android.systemui.qs.tileimpl.QSTileImpl; import com.android.systemui.statusbar.policy.UserInfoController; import com.android.systemui.statusbar.policy.UserSwitcherController; diff --git a/packages/SystemUI/src/com/android/systemui/qs/touch/SwipeDetector.java b/packages/SystemUI/src/com/android/systemui/qs/touch/SwipeDetector.java index 911bea67b8b4..e7161e1deace 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/touch/SwipeDetector.java +++ b/packages/SystemUI/src/com/android/systemui/qs/touch/SwipeDetector.java @@ -19,12 +19,13 @@ import static android.view.MotionEvent.INVALID_POINTER_ID; import android.content.Context; import android.graphics.PointF; -import androidx.annotation.NonNull; -import androidx.annotation.VisibleForTesting; import android.util.Log; import android.view.MotionEvent; import android.view.ViewConfiguration; +import androidx.annotation.NonNull; +import androidx.annotation.VisibleForTesting; + /** * One dimensional scroll/drag/swipe gesture detector. * diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyRecentsImpl.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyRecentsImpl.java index 661b958d4865..958695d3b2ee 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyRecentsImpl.java +++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyRecentsImpl.java @@ -31,6 +31,7 @@ import android.os.RemoteException; import android.util.Log; import android.view.Display; import android.widget.Toast; + import com.android.systemui.Dependency; import com.android.systemui.R; import com.android.systemui.SysUiServiceProvider; diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java index 19f76759ead7..1b89324209de 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java +++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java @@ -17,9 +17,9 @@ package com.android.systemui.recents; import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE; +import static android.view.MotionEvent.ACTION_CANCEL; import static android.view.MotionEvent.ACTION_DOWN; import static android.view.MotionEvent.ACTION_UP; -import static android.view.MotionEvent.ACTION_CANCEL; import static com.android.systemui.shared.system.NavigationBarCompat.FLAG_DISABLE_SWIPE_UP; import static com.android.systemui.shared.system.NavigationBarCompat.FLAG_SHOW_OVERVIEW_BUTTON; @@ -42,6 +42,7 @@ import android.os.UserHandle; import android.provider.Settings; import android.util.Log; import android.view.MotionEvent; + import com.android.systemui.Dependency; import com.android.systemui.Dumpable; import com.android.systemui.Prefs; @@ -55,6 +56,7 @@ import com.android.systemui.statusbar.phone.StatusBar; import com.android.systemui.statusbar.policy.CallbackController; import com.android.systemui.statusbar.policy.DeviceProvisionedController; import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener; + import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; diff --git a/packages/SystemUI/src/com/android/systemui/recents/Recents.java b/packages/SystemUI/src/com/android/systemui/recents/Recents.java index de22d219d4aa..0702d74506fd 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/Recents.java +++ b/packages/SystemUI/src/com/android/systemui/recents/Recents.java @@ -20,9 +20,11 @@ import android.content.ContentResolver; import android.content.res.Configuration; import android.graphics.Rect; import android.provider.Settings; + import com.android.systemui.R; import com.android.systemui.SystemUI; import com.android.systemui.statusbar.CommandQueue; + import java.io.FileDescriptor; import java.io.PrintWriter; diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsImplementation.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsImplementation.java index 8a04c11f551a..3efed3fe2c4d 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/RecentsImplementation.java +++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsImplementation.java @@ -18,7 +18,9 @@ package com.android.systemui.recents; import android.content.Context; import android.content.res.Configuration; import android.graphics.Rect; + import com.android.systemui.SysUiServiceProvider; + import java.io.PrintWriter; interface RecentsImplementation { diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsOnboarding.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsOnboarding.java index af0ebdc1306a..34f3c606be62 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/RecentsOnboarding.java +++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsOnboarding.java @@ -19,16 +19,17 @@ package com.android.systemui.recents; import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; -import static com.android.systemui.Prefs.Key.HAS_DISMISSED_RECENTS_QUICK_SCRUB_ONBOARDING_ONCE; import static com.android.systemui.Prefs.Key.DISMISSED_RECENTS_SWIPE_UP_ONBOARDING_COUNT; +import static com.android.systemui.Prefs.Key.HAS_DISMISSED_RECENTS_QUICK_SCRUB_ONBOARDING_ONCE; import static com.android.systemui.Prefs.Key.HAS_SEEN_RECENTS_QUICK_SCRUB_ONBOARDING; import static com.android.systemui.Prefs.Key.HAS_SEEN_RECENTS_SWIPE_UP_ONBOARDING; import static com.android.systemui.Prefs.Key.OVERVIEW_OPENED_COUNT; import static com.android.systemui.Prefs.Key.OVERVIEW_OPENED_FROM_HOME_COUNT; -import static com.android.systemui.shared.system.LauncherEventUtil.VISIBLE; import static com.android.systemui.shared.system.LauncherEventUtil.DISMISS; -import static com.android.systemui.shared.system.LauncherEventUtil.RECENTS_QUICK_SCRUB_ONBOARDING_TIP; +import static com.android.systemui.shared.system.LauncherEventUtil + .RECENTS_QUICK_SCRUB_ONBOARDING_TIP; import static com.android.systemui.shared.system.LauncherEventUtil.RECENTS_SWIPE_UP_ONBOARDING_TIP; +import static com.android.systemui.shared.system.LauncherEventUtil.VISIBLE; import android.annotation.StringRes; import android.annotation.TargetApi; @@ -45,9 +46,9 @@ import android.graphics.Paint; import android.graphics.PixelFormat; import android.graphics.drawable.ShapeDrawable; import android.os.Build; +import android.os.RemoteException; import android.os.SystemProperties; import android.os.UserManager; -import android.os.RemoteException; import android.util.TypedValue; import android.view.Gravity; import android.view.LayoutInflater; @@ -64,6 +65,7 @@ import com.android.systemui.R; import com.android.systemui.shared.recents.IOverviewProxy; import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.shared.system.TaskStackChangeListener; + import java.io.PrintWriter; import java.util.Collections; import java.util.HashSet; diff --git a/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java b/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java index f92c50a93f69..216b9409521f 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java +++ b/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java @@ -16,6 +16,9 @@ package com.android.systemui.recents; +import static com.android.systemui.util.leak.RotationUtils.ROTATION_LANDSCAPE; +import static com.android.systemui.util.leak.RotationUtils.ROTATION_SEASCAPE; + import android.animation.ArgbEvaluator; import android.animation.ValueAnimator; import android.app.ActivityManager; @@ -50,9 +53,6 @@ import com.android.systemui.util.leak.RotationUtils; import java.util.ArrayList; -import static com.android.systemui.util.leak.RotationUtils.ROTATION_LANDSCAPE; -import static com.android.systemui.util.leak.RotationUtils.ROTATION_SEASCAPE; - public class ScreenPinningRequest implements View.OnClickListener { private final Context mContext; diff --git a/packages/SystemUI/src/com/android/systemui/recents/TriangleShape.java b/packages/SystemUI/src/com/android/systemui/recents/TriangleShape.java index af8c2d08f4b4..ef4e19559f1f 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/TriangleShape.java +++ b/packages/SystemUI/src/com/android/systemui/recents/TriangleShape.java @@ -19,6 +19,7 @@ package com.android.systemui.recents; import android.graphics.Outline; import android.graphics.Path; import android.graphics.drawable.shapes.PathShape; + import androidx.annotation.NonNull; /** diff --git a/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java b/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java index 3ed5f70b8915..79228b9c369e 100644 --- a/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java +++ b/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java @@ -43,7 +43,6 @@ import android.widget.ImageView; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; -import com.android.settingslib.RestrictedLockUtils; import com.android.settingslib.RestrictedLockUtilsInternal; import com.android.systemui.Dependency; diff --git a/packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java b/packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java index 2ae53b5d81fe..0374a013a90c 100644 --- a/packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java +++ b/packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java @@ -18,7 +18,6 @@ package com.android.systemui.settings; import android.app.Activity; import android.os.Bundle; -import android.view.ContextThemeWrapper; import android.view.Gravity; import android.view.KeyEvent; import android.view.LayoutInflater; diff --git a/packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyDispatcher.java b/packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyDispatcher.java index 64fa8f86c5f6..07675e248906 100644 --- a/packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyDispatcher.java +++ b/packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyDispatcher.java @@ -26,6 +26,7 @@ import android.view.IWindowManager; import android.view.KeyEvent; import android.view.WindowManager; import android.view.WindowManagerGlobal; + import com.android.internal.policy.DividerSnapAlgorithm; import com.android.systemui.SystemUI; import com.android.systemui.recents.Recents; diff --git a/packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyServiceProxy.java b/packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyServiceProxy.java index 8ec862e1fdec..156964ac326d 100644 --- a/packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyServiceProxy.java +++ b/packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyServiceProxy.java @@ -19,6 +19,7 @@ package com.android.systemui.shortcut; import android.os.Handler; import android.os.Message; import android.os.RemoteException; + import com.android.internal.policy.IShortcutService; /** diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java b/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java index ea194a70adf2..cd2074fd64b8 100644 --- a/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java +++ b/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java @@ -26,9 +26,11 @@ import android.view.IDockedStackListener; import android.view.LayoutInflater; import android.view.View; import android.view.WindowManagerGlobal; + import com.android.systemui.R; import com.android.systemui.SystemUI; import com.android.systemui.recents.Recents; + import java.io.FileDescriptor; import java.io.PrintWriter; diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java index fa01af68364e..7a7d1f6b1f04 100644 --- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java +++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java @@ -55,6 +55,7 @@ import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction; import android.view.animation.Interpolator; import android.view.animation.PathInterpolator; import android.widget.FrameLayout; + import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.policy.DividerSnapAlgorithm; diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerWindowManager.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerWindowManager.java index b7a5d31a324b..2486d6534e8d 100644 --- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerWindowManager.java +++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerWindowManager.java @@ -16,12 +16,6 @@ package com.android.systemui.stackdivider; -import android.content.Context; -import android.graphics.PixelFormat; -import android.os.Binder; -import android.view.View; -import android.view.WindowManager; - import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL; @@ -32,6 +26,12 @@ import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_M import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION; import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER; +import android.content.Context; +import android.graphics.PixelFormat; +import android.os.Binder; +import android.view.View; +import android.view.WindowManager; + /** * Manages the window parameters of the docked stack divider. */ diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivityController.java b/packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivityController.java index f66db48f441c..c6ac309a0f4e 100644 --- a/packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivityController.java +++ b/packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivityController.java @@ -16,7 +16,8 @@ package com.android.systemui.stackdivider; -import static com.android.systemui.stackdivider.ForcedResizableInfoActivity.EXTRA_FORCED_RESIZEABLE_REASON; +import static com.android.systemui.stackdivider.ForcedResizableInfoActivity + .EXTRA_FORCED_RESIZEABLE_REASON; import android.app.ActivityOptions; import android.content.Context; @@ -25,6 +26,7 @@ import android.os.Handler; import android.os.UserHandle; import android.util.ArraySet; import android.widget.Toast; + import com.android.systemui.R; import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.shared.system.TaskStackChangeListener; diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java b/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java index 600964e98b84..228aab5e3eec 100644 --- a/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java +++ b/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java @@ -18,7 +18,6 @@ package com.android.systemui.stackdivider; import static android.view.WindowManager.DOCKED_INVALID; -import android.app.ActivityManager; import android.app.ActivityTaskManager; import android.graphics.Rect; import android.os.RemoteException; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java index daaefb9b2559..0c8f48752455 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java @@ -27,9 +27,9 @@ import android.os.Handler; import android.os.IBinder; import android.os.Looper; import android.os.Message; +import android.util.Pair; import androidx.annotation.VisibleForTesting; -import android.util.Pair; import com.android.internal.os.SomeArgs; import com.android.internal.statusbar.IStatusBar; @@ -164,7 +164,7 @@ public class CommandQueue extends IStatusBar.Stub { default void onRotationProposal(int rotation, boolean isValid) { } default void showBiometricDialog(Bundle bundle, IBiometricPromptReceiver receiver, - int type, boolean requireConfirmation) { } + int type, boolean requireConfirmation, int userId) { } default void onBiometricAuthenticated() { } default void onBiometricHelp(String message) { } default void onBiometricError(String error) { } @@ -524,13 +524,14 @@ public class CommandQueue extends IStatusBar.Stub { @Override public void showBiometricDialog(Bundle bundle, IBiometricPromptReceiver receiver, int type, - boolean requireConfirmation) { + boolean requireConfirmation, int userId) { synchronized (mLock) { SomeArgs args = SomeArgs.obtain(); args.arg1 = bundle; args.arg2 = receiver; args.argi1 = type; args.arg3 = requireConfirmation; + args.argi2 = userId; mHandler.obtainMessage(MSG_BIOMETRIC_SHOW, args) .sendToTarget(); } @@ -774,8 +775,9 @@ public class CommandQueue extends IStatusBar.Stub { mCallbacks.get(i).showBiometricDialog( (Bundle) someArgs.arg1, (IBiometricPromptReceiver) someArgs.arg2, - someArgs.argi1, - (boolean) someArgs.arg3); + someArgs.argi1 /* type */, + (boolean) someArgs.arg3 /* requireConfirmation */, + someArgs.argi2 /* userId */); } someArgs.recycle(); break; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcuts.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcuts.java index 00e0b954d7be..7f39e474f6c6 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcuts.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcuts.java @@ -62,11 +62,13 @@ import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.RelativeLayout; import android.widget.TextView; + import com.android.internal.app.AssistUtils; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto; import com.android.settingslib.Utils; import com.android.systemui.R; + import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java index 1f576342d5cd..a188c5ae7538 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java @@ -40,7 +40,6 @@ import android.widget.ImageView; import com.android.systemui.Interpolators; import com.android.systemui.R; -import com.android.systemui.statusbar.phone.KeyguardAffordanceHelper; /** * An ImageView which does not have overlapping renderings commands and therefore does not need a diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NeutralGoodDrawable.java b/packages/SystemUI/src/com/android/systemui/statusbar/NeutralGoodDrawable.java index cdb0514a2686..8642ca4c7d33 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NeutralGoodDrawable.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NeutralGoodDrawable.java @@ -17,14 +17,11 @@ package com.android.systemui.statusbar; import android.content.Context; -import android.content.res.Resources.Theme; -import android.graphics.Canvas; -import android.graphics.ColorFilter; -import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.graphics.drawable.LayerDrawable; import android.view.ContextThemeWrapper; import android.view.Gravity; + import com.android.settingslib.Utils; import com.android.systemui.R; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLifetimeExtender.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLifetimeExtender.java index 62c21dc17386..ecd9814c3073 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLifetimeExtender.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLifetimeExtender.java @@ -1,9 +1,9 @@ package com.android.systemui.statusbar; -import com.android.systemui.statusbar.notification.NotificationData; - import androidx.annotation.NonNull; +import com.android.systemui.statusbar.notification.NotificationData; + /** * Interface for anything that may need to keep notifications managed even after * {@link NotificationListener} removes it. The lifetime extender is in charge of performing the diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationPresenter.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationPresenter.java index 5c8f4cbf6078..0e9f950f54ed 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationPresenter.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationPresenter.java @@ -16,11 +16,8 @@ package com.android.systemui.statusbar; import android.content.Intent; -import android.os.Handler; -import android.view.View; import com.android.systemui.statusbar.notification.ActivityLaunchAnimator; -import com.android.systemui.statusbar.notification.NotificationData; import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.row.ActivatableNotificationView; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationUiAdjustment.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationUiAdjustment.java index 47b7fe9d7277..f42c6ef7356d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationUiAdjustment.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationUiAdjustment.java @@ -22,10 +22,10 @@ import android.app.RemoteInput; import android.graphics.drawable.Icon; import android.text.TextUtils; -import com.android.systemui.statusbar.notification.NotificationData; - import androidx.annotation.VisibleForTesting; +import com.android.systemui.statusbar.notification.NotificationData; + import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/OperatorNameView.java b/packages/SystemUI/src/com/android/systemui/statusbar/OperatorNameView.java index 5090f74d4019..f1a891b95eaa 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/OperatorNameView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/OperatorNameView.java @@ -15,10 +15,9 @@ package com.android.systemui.statusbar; import android.content.Context; -import android.net.ConnectivityManager; import android.graphics.Rect; +import android.net.ConnectivityManager; import android.os.Bundle; -import android.provider.Settings; import android.telephony.ServiceState; import android.telephony.SubscriptionInfo; import android.text.TextUtils; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/RemoteInputController.java b/packages/SystemUI/src/com/android/systemui/statusbar/RemoteInputController.java index 7f63191c9131..929f43e01c0f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/RemoteInputController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/RemoteInputController.java @@ -16,10 +16,6 @@ package com.android.systemui.statusbar; -import com.android.internal.util.Preconditions; -import com.android.systemui.statusbar.notification.NotificationData; -import com.android.systemui.statusbar.policy.RemoteInputView; - import android.app.Notification; import android.app.RemoteInput; import android.content.Context; @@ -27,6 +23,10 @@ import android.os.SystemProperties; import android.util.ArrayMap; import android.util.Pair; +import com.android.internal.util.Preconditions; +import com.android.systemui.statusbar.notification.NotificationData; +import com.android.systemui.statusbar.policy.RemoteInputView; + import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.List; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ScrimView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ScrimView.java index 3bc434280c51..cb9060bc9574 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/ScrimView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/ScrimView.java @@ -28,16 +28,14 @@ import android.graphics.Point; import android.graphics.PorterDuff; import android.graphics.PorterDuff.Mode; import android.graphics.PorterDuffColorFilter; -import android.graphics.PorterDuffXfermode; -import android.graphics.Rect; import android.graphics.drawable.Drawable; -import androidx.core.graphics.ColorUtils; import android.util.AttributeSet; import android.util.Log; import android.view.Display; import android.view.View; import android.view.WindowManager; -import android.view.animation.Interpolator; + +import androidx.core.graphics.ColorUtils; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.colorextraction.ColorExtractor; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SmartReplyController.java b/packages/SystemUI/src/com/android/systemui/statusbar/SmartReplyController.java index fb888ddc5f13..758c33a5aabe 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/SmartReplyController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/SmartReplyController.java @@ -16,13 +16,11 @@ package com.android.systemui.statusbar; import android.os.RemoteException; -import android.service.notification.StatusBarNotification; import android.util.ArraySet; import com.android.internal.statusbar.IStatusBarService; import com.android.systemui.Dependency; import com.android.systemui.statusbar.notification.NotificationData; -import com.android.systemui.statusbar.notification.NotificationEntryManager; import java.util.Set; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconContainer.java index 56f78f419275..065222762b33 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconContainer.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconContainer.java @@ -17,6 +17,7 @@ package com.android.systemui.statusbar; import com.android.internal.statusbar.StatusBarIcon; + import java.util.ArrayList; import java.util.List; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java index 3c52e8cab422..bc89889c48fe 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java @@ -27,16 +27,14 @@ import android.content.res.ColorStateList; import android.graphics.Color; import android.graphics.Rect; import android.util.AttributeSet; -import android.util.Log; import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; import android.widget.FrameLayout; import android.widget.ImageView; - import android.widget.LinearLayout; + import com.android.internal.annotations.VisibleForTesting; -import com.android.keyguard.AlphaOptimizedLinearLayout; import com.android.settingslib.graph.SignalDrawable; import com.android.systemui.R; import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.MobileIconState; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateController.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateController.java index 12c0fcbed204..eaf52cb357fe 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateController.java @@ -18,11 +18,17 @@ package com.android.systemui.statusbar; import static java.lang.annotation.RetentionPolicy.SOURCE; +import android.animation.ObjectAnimator; +import android.animation.ValueAnimator; import android.annotation.IntDef; -import android.util.ArraySet; -import android.util.Log; +import android.util.FloatProperty; +import android.view.animation.Interpolator; + import com.android.internal.annotations.GuardedBy; +import com.android.systemui.Interpolators; +import com.android.systemui.statusbar.notification.stack.StackStateAnimator; import com.android.systemui.statusbar.phone.StatusBar; + import java.lang.annotation.Retention; import java.util.ArrayList; import java.util.Comparator; @@ -38,14 +44,51 @@ public class StatusBarStateController { private static final Comparator <RankedListener> mComparator = (o1, o2) -> Integer.compare(o1.rank, o2.rank); + private static final FloatProperty<StatusBarStateController> SET_DARK_AMOUNT_PROPERTY = + new FloatProperty<StatusBarStateController>("mDozeAmount") { + + @Override + public void setValue(StatusBarStateController object, float value) { + object.setDozeAmountInternal(value); + } + + @Override + public Float get(StatusBarStateController object) { + return object.mDozeAmount; + } + }; private final ArrayList<RankedListener> mListeners = new ArrayList<>(); - private boolean mIsDozing; private int mState; private int mLastState; private boolean mLeaveOpenOnKeyguardHide; private boolean mKeyguardRequested; + /** + * If the device is currently dozing or not. + */ + private boolean mIsDozing; + + /** + * Current {@link #mDozeAmount} animator. + */ + private ValueAnimator mDarkAnimator; + + /** + * Current doze amount in this frame. + */ + private float mDozeAmount; + + /** + * Where the animator will stop. + */ + private float mDozeAmountTarget; + + /** + * The type of interpolator that should be used to the doze animation. + */ + private Interpolator mDozeInterpolator = Interpolators.FAST_OUT_SLOW_IN; + // TODO: b/115739177 (remove this explicit ordering if we can) @Retention(SOURCE) @IntDef({RANK_STATUS_BAR, RANK_STATUS_BAR_WINDOW_CONTROLLER, RANK_STACK_SCROLLER, RANK_SHELF}) @@ -94,6 +137,14 @@ public class StatusBarStateController { return mIsDozing; } + public float getDozeAmount() { + return mDozeAmount; + } + + public float getInterpolatedDozeAmount() { + return mDozeInterpolator.getInterpolation(mDozeAmount); + } + /** * Update the dozing state from {@link StatusBar}'s perspective * @param isDozing well, are we dozing? @@ -116,6 +167,51 @@ public class StatusBarStateController { return true; } + /** + * Changes the current doze amount. + * + * @param dozeAmount New doze/dark amount. + * @param animated If change should be animated or not. This will cancel current animations. + */ + public void setDozeAmount(float dozeAmount, boolean animated) { + if (mDarkAnimator != null && mDarkAnimator.isRunning()) { + if (animated && mDozeAmountTarget == dozeAmount) { + return; + } else { + mDarkAnimator.cancel(); + } + } + + mDozeAmountTarget = dozeAmount; + if (animated) { + startDozeAnimation(); + } else { + setDozeAmountInternal(dozeAmount); + } + } + + private void startDozeAnimation() { + if (mDozeAmount == 0f || mDozeAmount == 1f) { + mDozeInterpolator = mIsDozing + ? Interpolators.FAST_OUT_SLOW_IN + : Interpolators.TOUCH_RESPONSE_REVERSE; + } + mDarkAnimator = ObjectAnimator.ofFloat(this, SET_DARK_AMOUNT_PROPERTY, mDozeAmountTarget); + mDarkAnimator.setInterpolator(Interpolators.LINEAR); + mDarkAnimator.setDuration(StackStateAnimator.ANIMATION_DURATION_WAKEUP); + mDarkAnimator.start(); + } + + private void setDozeAmountInternal(float dozeAmount) { + mDozeAmount = dozeAmount; + float interpolatedAmount = mDozeInterpolator.getInterpolation(dozeAmount); + synchronized (mListeners) { + for (RankedListener rl : new ArrayList<>(mListeners)) { + rl.listener.onDozeAmountChanged(mDozeAmount, interpolatedAmount); + } + } + } + public boolean goingToFullShade() { return mState == StatusBarState.SHADE && mLeaveOpenOnKeyguardHide; } @@ -202,7 +298,8 @@ public class StatusBarStateController { public interface StateListener { /** - * Callback before the new state is applied, for those who need to preempt the change + * Callback before the new state is applied, for those who need to preempt the change. + * * @param oldState state before the change * @param newState new state to be applied in {@link #onStateChanged} */ @@ -218,17 +315,29 @@ public class StatusBarStateController { /** * Required callback. Get the new state and do what you will with it. Keep in mind that * other listeners are typically unordered and don't rely on your work being done before - * other peers + * other peers. + * + * Only called if the state is actually different. * - * Only called if the state is actually different * @param newState the new {@link StatusBarState} */ public void onStateChanged(int newState); /** * Callback to be notified when Dozing changes. Dozing is stored separately from state. + * * @param isDozing {@code true} if dozing according to {@link StatusBar} */ public default void onDozingChanged(boolean isDozing) {} + + /** + * Callback to be notified when the doze amount changes. Useful for animations. + * Note: this will be called for each animation frame. Please be careful to avoid + * performance regressions. + * + * @param linear A number from 0 to 1, where 1 means that the device is dozing. + * @param eased Same as {@code linear} but transformed by an interpolator. + */ + default void onDozeAmountChanged(float linear, float eased) {} } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarWifiView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarWifiView.java index f3fc99e36426..045221f510fa 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarWifiView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarWifiView.java @@ -27,18 +27,14 @@ import android.content.res.ColorStateList; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.util.AttributeSet; -import android.util.Log; import android.view.ContextThemeWrapper; import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; -import android.view.ViewGroup; -import android.view.ViewGroup.LayoutParams; import android.widget.FrameLayout; import android.widget.ImageView; - import android.widget.LinearLayout; -import com.android.keyguard.AlphaOptimizedLinearLayout; + import com.android.settingslib.Utils; import com.android.systemui.R; import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.WifiIconState; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/UserUtil.java b/packages/SystemUI/src/com/android/systemui/statusbar/UserUtil.java index f9afc7c34668..c4fadff16c09 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/UserUtil.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/UserUtil.java @@ -16,12 +16,12 @@ package com.android.systemui.statusbar; -import com.android.systemui.statusbar.phone.SystemUIDialog; -import com.android.systemui.statusbar.policy.UserSwitcherController; import android.content.Context; import android.content.DialogInterface; import com.android.systemui.R; +import com.android.systemui.statusbar.phone.SystemUIDialog; +import com.android.systemui.statusbar.policy.UserSwitcherController; public class UserUtil { public static void deleteUserWithPrompt(Context context, int userId, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarFacetButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarFacetButton.java index 46f88635be79..bd328567fb46 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarFacetButton.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarFacetButton.java @@ -3,10 +3,8 @@ package com.android.systemui.statusbar.car; import android.content.Context; import android.content.Intent; import android.content.res.TypedArray; -import android.graphics.drawable.Drawable; import android.os.UserHandle; import android.util.AttributeSet; -import android.util.Log; import android.view.View; import android.widget.ImageView; import android.widget.LinearLayout; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationBarView.java index 9ed092974963..81f7846b357d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationBarView.java @@ -16,13 +16,10 @@ package com.android.systemui.statusbar.car; -import android.app.UiModeManager; import android.content.Context; import android.util.AttributeSet; -import android.util.Log; import android.view.View; import android.widget.LinearLayout; -import android.widget.TextView; import com.android.keyguard.AlphaOptimizedImageButton; import com.android.systemui.Dependency; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/ConnectedDeviceSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/ConnectedDeviceSignalController.java index 0304086dbfda..f2923f7df248 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/car/ConnectedDeviceSignalController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/ConnectedDeviceSignalController.java @@ -1,5 +1,7 @@ package com.android.systemui.statusbar.car; +import static com.android.systemui.statusbar.phone.StatusBar.DEBUG; + import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothHeadsetClient; @@ -9,21 +11,19 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; -import android.graphics.drawable.Drawable; import android.os.Bundle; import android.telephony.SignalStrength; import android.util.Log; import android.util.TypedValue; import android.view.View; import android.widget.ImageView; + import com.android.settingslib.graph.SignalDrawable; import com.android.systemui.Dependency; import com.android.systemui.R; import com.android.systemui.statusbar.ScalingDrawableWrapper; import com.android.systemui.statusbar.policy.BluetoothController; -import static com.android.systemui.statusbar.phone.StatusBar.DEBUG; - /** * Controller that monitors signal strength for a device that is connected via bluetooth. */ diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/SwitchToGuestTimer.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/SwitchToGuestTimer.java index f9fa44b17489..0c91cba43390 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/car/SwitchToGuestTimer.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/SwitchToGuestTimer.java @@ -21,10 +21,10 @@ import android.content.Context; import android.os.CountDownTimer; import android.util.Log; -import com.android.systemui.R; - import androidx.annotation.GuardedBy; +import com.android.systemui.R; + /** * Wrapper for a countdown timer that switches to Guest if the user has been driving with * the keyguard up for configurable number of seconds. diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/UserGridRecyclerView.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/UserGridRecyclerView.java index 53a7afe76d0d..d802ed8d6e3a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/car/UserGridRecyclerView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/UserGridRecyclerView.java @@ -29,7 +29,6 @@ import android.content.pm.UserInfo; import android.content.res.Resources; import android.graphics.Bitmap; import android.os.AsyncTask; -import android.os.UserHandle; import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.View; @@ -44,8 +43,8 @@ import androidx.recyclerview.widget.RecyclerView; import com.android.internal.util.UserIcons; import com.android.systemui.R; - import com.android.systemui.statusbar.phone.SystemUIDialog; + import java.util.ArrayList; import java.util.List; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActionListTransformState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActionListTransformState.java index 8c725446a3cb..6044a7e16b61 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActionListTransformState.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActionListTransformState.java @@ -16,11 +16,7 @@ package com.android.systemui.statusbar.notification; -import android.text.Layout; -import android.text.TextUtils; import android.util.Pools; -import android.view.View; -import android.widget.TextView; /** * A transform state of the action list diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/CustomInterpolatorTransformation.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/CustomInterpolatorTransformation.java index de4c3128e99f..dea1a07c0268 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/CustomInterpolatorTransformation.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/CustomInterpolatorTransformation.java @@ -17,16 +17,11 @@ package com.android.systemui.statusbar.notification; import android.view.View; -import android.view.animation.Interpolator; -import com.android.systemui.Interpolators; import com.android.systemui.statusbar.CrossFadeHelper; import com.android.systemui.statusbar.TransformableView; import com.android.systemui.statusbar.ViewTransformationHelper; -import static com.android.systemui.statusbar.TransformableView.TRANSFORMING_VIEW_TITLE; -import static com.android.systemui.statusbar.notification.TransformState.TRANSFORM_Y; - /** * A custom transformation that modifies the interpolator */ diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ImageGradientColorizer.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ImageGradientColorizer.java index 454edbb1a037..f5a76f0499e2 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ImageGradientColorizer.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ImageGradientColorizer.java @@ -17,7 +17,6 @@ package com.android.systemui.statusbar.notification; import android.graphics.Bitmap; -import android.graphics.BitmapShader; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.ColorMatrix; @@ -27,7 +26,6 @@ import android.graphics.Paint; import android.graphics.PorterDuff; import android.graphics.PorterDuffXfermode; import android.graphics.Shader; -import android.graphics.Xfermode; import android.graphics.drawable.Drawable; /** diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/MediaNotificationProcessor.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/MediaNotificationProcessor.java index 8c0d70062eb1..ab94008d656a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/MediaNotificationProcessor.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/MediaNotificationProcessor.java @@ -23,9 +23,10 @@ import android.graphics.Canvas; import android.graphics.Color; import android.graphics.drawable.Drawable; import android.graphics.drawable.Icon; +import android.util.LayoutDirection; + import androidx.annotation.VisibleForTesting; import androidx.palette.graphics.Palette; -import android.util.LayoutDirection; import com.android.internal.util.ContrastColorUtil; import com.android.systemui.R; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/MessagingImageTransformState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/MessagingImageTransformState.java index b97995dd5f93..a3fb2251f5aa 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/MessagingImageTransformState.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/MessagingImageTransformState.java @@ -20,7 +20,6 @@ import android.util.Pools; import android.view.View; import com.android.internal.widget.MessagingImageMessage; -import com.android.systemui.Interpolators; import com.android.systemui.R; import com.android.systemui.statusbar.ViewTransformationHelper; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationDozeHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationDozeHelper.java index fb362c5e506f..ef042bab7625 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationDozeHelper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationDozeHelper.java @@ -26,7 +26,7 @@ import android.widget.ImageView; import com.android.systemui.Interpolators; import com.android.systemui.R; -import com.android.systemui.statusbar.phone.NotificationPanelView; +import com.android.systemui.statusbar.notification.stack.StackStateAnimator; import java.util.function.Consumer; @@ -63,13 +63,14 @@ public class NotificationDozeHelper { } } + // TODO: this should be using StatusBarStateController#getDozeAmount public void startIntensityAnimation(ValueAnimator.AnimatorUpdateListener updateListener, boolean dark, long delay, Animator.AnimatorListener listener) { float startIntensity = dark ? 0f : 1f; float endIntensity = dark ? 1f : 0f; ValueAnimator animator = ValueAnimator.ofFloat(startIntensity, endIntensity); animator.addUpdateListener(updateListener); - animator.setDuration(NotificationPanelView.DOZE_ANIMATION_DURATION); + animator.setDuration(StackStateAnimator.ANIMATION_DURATION_WAKEUP); animator.setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN); animator.setStartDelay(delay); if (listener != null) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/TransformState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/TransformState.java index 07b8c3558304..337f31295308 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/TransformState.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/TransformState.java @@ -29,9 +29,9 @@ import com.android.internal.widget.ViewClippingUtil; import com.android.systemui.Interpolators; import com.android.systemui.R; import com.android.systemui.statusbar.CrossFadeHelper; -import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import com.android.systemui.statusbar.TransformableView; import com.android.systemui.statusbar.ViewTransformationHelper; +import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; /** * A transform state of a view. diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/VisualStabilityManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/VisualStabilityManager.java index da8954ae4c03..75613a42eb5e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/VisualStabilityManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/VisualStabilityManager.java @@ -16,9 +16,10 @@ package com.android.systemui.statusbar.notification; -import androidx.collection.ArraySet; import android.view.View; +import androidx.collection.ArraySet; + import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBlockingHelperManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBlockingHelperManager.java index 1a4ef0914664..16796dd86e18 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBlockingHelperManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBlockingHelperManager.java @@ -16,10 +16,13 @@ package com.android.systemui.statusbar.notification.row; +import static android.service.notification.NotificationListenerService.Ranking + .USER_SENTIMENT_NEGATIVE; + import android.content.Context; +import android.util.Log; import androidx.annotation.VisibleForTesting; -import android.util.Log; import com.android.internal.logging.MetricsLogger; import com.android.systemui.Dependency; @@ -31,8 +34,6 @@ import java.util.Collections; import java.util.HashSet; import java.util.Set; -import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE; - /** * Manager for the notification blocking helper - tracks and helps create the blocking helper * affordance. diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationSnooze.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationSnooze.java index 75b05c26886d..d65f2c53598c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationSnooze.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationSnooze.java @@ -16,16 +16,6 @@ package com.android.systemui.statusbar.notification.row; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.TimeUnit; - -import com.android.internal.annotations.VisibleForTesting; -import com.android.internal.logging.MetricsLogger; -import com.android.internal.logging.nano.MetricsProto.MetricsEvent; -import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper; -import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper.SnoozeOption; - import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorSet; @@ -53,8 +43,17 @@ import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; +import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.logging.MetricsLogger; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.systemui.Interpolators; import com.android.systemui.R; +import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper; +import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper.SnoozeOption; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.TimeUnit; public class NotificationSnooze extends LinearLayout implements NotificationGuts.GutsContent, View.OnClickListener { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowInflaterTask.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowInflaterTask.java index a21794bc4835..1741a0b6b37c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowInflaterTask.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowInflaterTask.java @@ -17,11 +17,12 @@ package com.android.systemui.statusbar.notification.row; import android.content.Context; -import androidx.asynclayoutinflater.view.AsyncLayoutInflater; import android.util.Log; import android.view.View; import android.view.ViewGroup; +import androidx.asynclayoutinflater.view.AsyncLayoutInflater; + import com.android.systemui.R; import com.android.systemui.statusbar.InflationTask; import com.android.systemui.statusbar.notification.NotificationData; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/StackScrollerDecorView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/StackScrollerDecorView.java index 8a061a606099..1b40c06a5867 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/StackScrollerDecorView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/StackScrollerDecorView.java @@ -24,7 +24,6 @@ import android.view.animation.Interpolator; import com.android.internal.annotations.VisibleForTesting; import com.android.systemui.Interpolators; -import com.android.systemui.statusbar.notification.row.ExpandableView; /** * A common base class for all views in the notification stack scroller which don't have a diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationBigTextTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationBigTextTemplateViewWrapper.java index 133df3c154de..4261df3dab27 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationBigTextTemplateViewWrapper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationBigTextTemplateViewWrapper.java @@ -21,8 +21,8 @@ import android.service.notification.StatusBarNotification; import android.view.View; import com.android.internal.widget.ImageFloatingTextView; -import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import com.android.systemui.statusbar.TransformableView; +import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; /** * Wraps a notification containing a big text template diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java index 6ca07ed8b161..a8ced7a01d84 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java @@ -16,9 +16,9 @@ package com.android.systemui.statusbar.notification.row.wrapper; +import static com.android.systemui.statusbar.notification.TransformState.TRANSFORM_Y; import static com.android.systemui.statusbar.notification.row.ExpandableNotificationRow .DEFAULT_HEADER_VISIBLE_AMOUNT; -import static com.android.systemui.statusbar.notification.TransformState.TRANSFORM_Y; import android.app.Notification; import android.content.Context; @@ -34,12 +34,12 @@ import android.widget.TextView; import com.android.internal.widget.NotificationExpandButton; import com.android.systemui.Interpolators; import com.android.systemui.R; +import com.android.systemui.statusbar.TransformableView; +import com.android.systemui.statusbar.ViewTransformationHelper; import com.android.systemui.statusbar.notification.CustomInterpolatorTransformation; import com.android.systemui.statusbar.notification.ImageTransformState; import com.android.systemui.statusbar.notification.TransformState; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; -import com.android.systemui.statusbar.TransformableView; -import com.android.systemui.statusbar.ViewTransformationHelper; import java.util.Stack; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMediaTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMediaTemplateViewWrapper.java index 37d2f6bba7ff..5a9a56865a5c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMediaTemplateViewWrapper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMediaTemplateViewWrapper.java @@ -19,8 +19,8 @@ package com.android.systemui.statusbar.notification.row.wrapper; import android.content.Context; import android.view.View; -import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import com.android.systemui.statusbar.TransformableView; +import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; /** * Wraps a notification containing a media template diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMessagingTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMessagingTemplateViewWrapper.java index 13c596023f95..c9a274294d16 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMessagingTemplateViewWrapper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMessagingTemplateViewWrapper.java @@ -16,15 +16,15 @@ package com.android.systemui.statusbar.notification.row.wrapper; +import android.content.Context; +import android.view.View; + import com.android.internal.widget.MessagingLayout; import com.android.internal.widget.MessagingLinearLayout; import com.android.systemui.R; import com.android.systemui.statusbar.notification.NotificationUtils; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; -import android.content.Context; -import android.view.View; - /** * Wraps a notification containing a messaging template */ diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationTemplateViewWrapper.java index d934902b96e8..ff5e15bfe751 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationTemplateViewWrapper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationTemplateViewWrapper.java @@ -37,11 +37,11 @@ import com.android.systemui.Dependency; import com.android.systemui.R; import com.android.systemui.UiOffloadThread; import com.android.systemui.statusbar.CrossFadeHelper; +import com.android.systemui.statusbar.TransformableView; +import com.android.systemui.statusbar.ViewTransformationHelper; import com.android.systemui.statusbar.notification.ImageTransformState; import com.android.systemui.statusbar.notification.TransformState; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; -import com.android.systemui.statusbar.TransformableView; -import com.android.systemui.statusbar.ViewTransformationHelper; import com.android.systemui.statusbar.notification.row.HybridNotificationView; /** diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapper.java index f76284dd1ffc..1efdc56874f3 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapper.java @@ -24,9 +24,9 @@ import android.view.NotificationHeaderView; import android.view.View; import com.android.systemui.statusbar.CrossFadeHelper; +import com.android.systemui.statusbar.TransformableView; import com.android.systemui.statusbar.notification.TransformState; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; -import com.android.systemui.statusbar.TransformableView; /** * Wraps the actual notification content view; used to implement behaviors which are different for diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AnimationFilter.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AnimationFilter.java index c6f953c8a6ae..ba56a943f559 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AnimationFilter.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AnimationFilter.java @@ -16,10 +16,11 @@ package com.android.systemui.statusbar.notification.stack; -import androidx.collection.ArraySet; import android.util.Property; import android.view.View; +import androidx.collection.ArraySet; + import java.util.ArrayList; /** diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java index da089b307850..74b4aa2a7057 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java @@ -33,13 +33,13 @@ import android.widget.TextView; import com.android.internal.annotations.VisibleForTesting; import com.android.systemui.R; import com.android.systemui.statusbar.CrossFadeHelper; -import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import com.android.systemui.statusbar.NotificationHeaderUtil; +import com.android.systemui.statusbar.notification.NotificationUtils; +import com.android.systemui.statusbar.notification.VisualStabilityManager; +import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import com.android.systemui.statusbar.notification.row.HybridGroupManager; import com.android.systemui.statusbar.notification.row.HybridNotificationView; -import com.android.systemui.statusbar.notification.NotificationUtils; import com.android.systemui.statusbar.notification.row.wrapper.NotificationViewWrapper; -import com.android.systemui.statusbar.notification.VisualStabilityManager; import java.util.ArrayList; import java.util.List; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationListContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationListContainer.java index cfb6d990a9a7..4d100a46c48a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationListContainer.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationListContainer.java @@ -16,17 +16,18 @@ package com.android.systemui.statusbar.notification.stack; -import static com.android.systemui.statusbar.notification.ActivityLaunchAnimator.ExpandAnimationParameters; +import static com.android.systemui.statusbar.notification.ActivityLaunchAnimator + .ExpandAnimationParameters; import android.view.View; import android.view.ViewGroup; import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper; +import com.android.systemui.statusbar.notification.NotificationData; import com.android.systemui.statusbar.notification.VisibilityLocationProvider; +import com.android.systemui.statusbar.notification.logging.NotificationLogger; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import com.android.systemui.statusbar.notification.row.ExpandableView; -import com.android.systemui.statusbar.notification.NotificationData; -import com.android.systemui.statusbar.notification.logging.NotificationLogger; /** * Interface representing the entity that contains notifications. It can have diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java index bcf949f4ff69..a7329b0f181a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java @@ -2312,7 +2312,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd View child = getChildAt(i); if (child.getVisibility() != View.GONE && child instanceof ExpandableNotificationRow) { ExpandableNotificationRow row = (ExpandableNotificationRow) child; - if (mEntryManager.getNotificationData().isHighPriority( + if (!mEntryManager.getNotificationData().isHighPriority( row.getStatusBarNotification())) { break; } else { @@ -4399,16 +4399,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd } @ShadeViewRefactor(RefactorComponent.STATE_RESOLVER) - public long getDarkAnimationDuration(boolean dark) { - long duration = StackStateAnimator.ANIMATION_DURATION_WAKEUP; - // Longer animation when sleeping with more than 1 notification - if (dark && getNotGoneChildCount() > 2) { - duration *= 1.2f; - } - return duration; - } - - @ShadeViewRefactor(RefactorComponent.STATE_RESOLVER) private int findDarkAnimationOriginIndex(@Nullable PointF screenLocation) { if (screenLocation == null || screenLocation.y < mTopPadding) { return AnimationEvent.DARK_ANIMATION_ORIGIN_INDEX_ABOVE; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java index da3fb66ec1db..a94401b6319c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java @@ -26,10 +26,10 @@ import android.view.animation.Interpolator; import com.android.keyguard.KeyguardSliceView; import com.android.systemui.Interpolators; import com.android.systemui.R; -import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; -import com.android.systemui.statusbar.notification.row.ExpandableView; import com.android.systemui.statusbar.NotificationShelf; import com.android.systemui.statusbar.StatusBarIconView; +import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; +import com.android.systemui.statusbar.notification.row.ExpandableView; import java.util.ArrayList; import java.util.HashSet; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ViewState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ViewState.java index a15fd7083017..b00068cd2445 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ViewState.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ViewState.java @@ -28,9 +28,9 @@ import android.view.animation.Interpolator; import com.android.systemui.Dumpable; import com.android.systemui.Interpolators; import com.android.systemui.R; -import com.android.systemui.statusbar.notification.row.ExpandableView; import com.android.systemui.statusbar.notification.AnimatableProperty; import com.android.systemui.statusbar.notification.PropertyAnimator; +import com.android.systemui.statusbar.notification.row.ExpandableView; import com.android.systemui.statusbar.policy.HeadsUpUtil; import java.io.FileDescriptor; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java index ab58660f6ed6..d5056b75a383 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java @@ -17,6 +17,7 @@ package com.android.systemui.statusbar.phone; import android.content.Context; import android.os.Handler; import android.provider.Settings.Secure; + import com.android.internal.annotations.VisibleForTesting; import com.android.internal.app.ColorDisplayController; import com.android.systemui.Dependency; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java index c32dcea1f646..3d814732a2e7 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java @@ -16,7 +16,6 @@ package com.android.systemui.statusbar.phone; -import android.app.ActivityManager; import android.content.Context; import android.content.res.Resources; import android.graphics.Canvas; @@ -25,9 +24,9 @@ import android.graphics.ColorFilter; import android.graphics.Paint; import android.graphics.PixelFormat; import android.graphics.PorterDuff; +import android.graphics.PorterDuff.Mode; import android.graphics.PorterDuffColorFilter; import android.graphics.Rect; -import android.graphics.PorterDuff.Mode; import android.graphics.drawable.Drawable; import android.os.SystemClock; import android.util.Log; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java index 8325bf8085bd..302d630eeb2b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java @@ -16,18 +16,18 @@ package com.android.systemui.statusbar.phone; -import android.hardware.biometrics.BiometricSourceType; import android.content.Context; +import android.hardware.biometrics.BiometricSourceType; import android.os.Handler; import android.os.PowerManager; import android.os.SystemClock; import android.os.Trace; import android.util.Log; +import com.android.internal.util.LatencyTracker; import com.android.keyguard.KeyguardConstants; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.keyguard.KeyguardUpdateMonitorCallback; -import com.android.internal.util.LatencyTracker; import com.android.systemui.Dependency; import com.android.systemui.keyguard.KeyguardViewMediator; import com.android.systemui.keyguard.ScreenLifecycle; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ButtonDispatcher.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ButtonDispatcher.java index 119f01adddf8..4ced702f479e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ButtonDispatcher.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ButtonDispatcher.java @@ -21,8 +21,8 @@ import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.ValueAnimator; import android.view.View; - import android.view.View.AccessibilityDelegate; + import com.android.systemui.plugins.statusbar.phone.NavBarButtonProvider.ButtonInterface; import com.android.systemui.statusbar.policy.KeyButtonDrawable; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ContextualButtonGroup.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ContextualButtonGroup.java index 970304399b67..cc8adde2ed04 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ContextualButtonGroup.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ContextualButtonGroup.java @@ -19,6 +19,7 @@ package com.android.systemui.statusbar.phone; import android.annotation.IdRes; import android.annotation.NonNull; import android.view.View; + import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java index e052e531ddd2..3425dd237430 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java @@ -24,20 +24,20 @@ import android.util.Log; import android.view.Gravity; import android.view.View; import android.view.ViewGroup; -import android.view.ViewGroup.LayoutParams; import android.widget.LinearLayout; import com.android.internal.statusbar.StatusBarIcon; import com.android.systemui.DemoMode; import com.android.systemui.R; -import com.android.systemui.statusbar.StatusIconDisplayable; import com.android.systemui.statusbar.StatusBarIconView; import com.android.systemui.statusbar.StatusBarMobileView; import com.android.systemui.statusbar.StatusBarWifiView; +import com.android.systemui.statusbar.StatusIconDisplayable; import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.MobileIconState; import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.WifiIconState; import com.android.systemui.statusbar.policy.DarkIconDispatcher; import com.android.systemui.statusbar.policy.DarkIconDispatcher.DarkReceiver; + import java.util.ArrayList; public class DemoStatusIcons extends StatusIconContainer implements DemoMode, DarkReceiver { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ExpandableIndicator.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ExpandableIndicator.java index 8f49c85b0938..efc289185cfa 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ExpandableIndicator.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ExpandableIndicator.java @@ -18,6 +18,7 @@ import android.content.Context; import android.graphics.drawable.AnimatedVectorDrawable; import android.util.AttributeSet; import android.widget.ImageView; + import com.android.systemui.R; public class ExpandableIndicator extends ImageView { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java index c66bbb1696ac..40f9f45bf8bb 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java @@ -26,12 +26,12 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.systemui.Dependency; import com.android.systemui.R; import com.android.systemui.statusbar.CrossFadeHelper; -import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import com.android.systemui.statusbar.HeadsUpStatusBarView; import com.android.systemui.statusbar.notification.NotificationData; +import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; +import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout; import com.android.systemui.statusbar.policy.DarkIconDispatcher; import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener; -import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout; import java.util.function.BiConsumer; import java.util.function.Consumer; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java index 976327a49f58..d05893d55508 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java @@ -21,8 +21,6 @@ import android.annotation.Nullable; import android.content.Context; import android.content.res.Configuration; import android.content.res.Resources; -import androidx.collection.ArraySet; - import android.graphics.Rect; import android.graphics.Region; import android.graphics.Region.Op; @@ -33,16 +31,18 @@ import android.view.Gravity; import android.view.View; import android.view.ViewTreeObserver; +import androidx.collection.ArraySet; + import com.android.systemui.Dependency; import com.android.systemui.Dumpable; import com.android.systemui.R; import com.android.systemui.ScreenDecorations; import com.android.systemui.statusbar.StatusBarState; +import com.android.systemui.statusbar.StatusBarStateController; import com.android.systemui.statusbar.StatusBarStateController.StateListener; -import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import com.android.systemui.statusbar.notification.NotificationData; -import com.android.systemui.statusbar.StatusBarStateController; import com.android.systemui.statusbar.notification.VisualStabilityManager; +import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.statusbar.policy.HeadsUpManager; import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java index e4a5caaf7d71..be4df458ecb9 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java @@ -21,10 +21,9 @@ import android.view.MotionEvent; import android.view.ViewConfiguration; import com.android.systemui.Gefingerpoken; +import com.android.systemui.statusbar.notification.NotificationData; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import com.android.systemui.statusbar.notification.row.ExpandableView; -import com.android.systemui.statusbar.notification.NotificationData; -import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout; /** * A helper class to handle touches on the heads-up views. diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java index 235629bbb509..c0d1818d8da9 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java @@ -16,8 +16,8 @@ package com.android.systemui.statusbar.phone; -import static com.android.systemui.plugins.ActivityStarter.OnDismissAction; import static com.android.keyguard.KeyguardSecurityModel.SecurityMode; +import static com.android.systemui.plugins.ActivityStarter.OnDismissAction; import android.content.Context; import android.content.res.ColorStateList; @@ -268,6 +268,8 @@ public class KeyguardBouncer { } public void hide(boolean destroyView) { + // TODO(b/113914868): investigation log for disappearing home button + Log.i(TAG, "KeyguardBouncer.hide (b/113914868): destroyView=" + destroyView); if (isShowing()) { StatsLog.write(StatsLog.KEYGUARD_BOUNCER_STATE_CHANGED, StatsLog.KEYGUARD_BOUNCER_STATE_CHANGED__STATE__HIDDEN); 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 8cace7206a1f..e0c5516417ba 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java @@ -16,7 +16,9 @@ package com.android.systemui.statusbar.phone; -import android.app.WallpaperColors; +import static com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT_TRANSPARENT; +import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSPARENT; + import android.content.Context; import android.graphics.Color; import android.graphics.Rect; @@ -32,9 +34,6 @@ import com.android.systemui.statusbar.policy.DarkIconDispatcher; 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. */ 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 b0ac6ecae5bb..b29889dac6f8 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarTransitionsController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarTransitionsController.java @@ -21,6 +21,7 @@ import android.content.Context; import android.os.Bundle; import android.os.Handler; import android.os.SystemClock; +import android.util.MathUtils; import android.util.TimeUtils; import com.android.systemui.Dependency; @@ -29,6 +30,7 @@ import com.android.systemui.Interpolators; import com.android.systemui.SysUiServiceProvider; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.CommandQueue.Callbacks; +import com.android.systemui.statusbar.StatusBarStateController; import com.android.systemui.statusbar.policy.KeyguardMonitor; import java.io.FileDescriptor; @@ -37,7 +39,8 @@ import java.io.PrintWriter; /** * Class to control all aspects about light bar changes. */ -public class LightBarTransitionsController implements Dumpable, Callbacks { +public class LightBarTransitionsController implements Dumpable, Callbacks, + StatusBarStateController.StateListener { public static final long DEFAULT_TINT_ANIMATION_DURATION = 120; private static final String EXTRA_DARK_INTENSITY = "dark_intensity"; @@ -45,6 +48,7 @@ public class LightBarTransitionsController implements Dumpable, Callbacks { private final Handler mHandler; private final DarkIntensityApplier mApplier; private final KeyguardMonitor mKeyguardMonitor; + private final StatusBarStateController mStatusBarStateController; private boolean mTransitionDeferring; private long mTransitionDeferringStartTime; @@ -55,6 +59,7 @@ public class LightBarTransitionsController implements Dumpable, Callbacks { private ValueAnimator mTintAnimator; private float mDarkIntensity; private float mNextDarkIntensity; + private float mDozeAmount; private final Runnable mTransitionDeferringDoneRunnable = new Runnable() { @Override public void run() { @@ -66,13 +71,17 @@ public class LightBarTransitionsController implements Dumpable, Callbacks { mApplier = applier; mHandler = new Handler(); mKeyguardMonitor = Dependency.get(KeyguardMonitor.class); + mStatusBarStateController = Dependency.get(StatusBarStateController.class); SysUiServiceProvider.getComponent(context, CommandQueue.class) .addCallbacks(this); + mStatusBarStateController.addListener(this); + mDozeAmount = mStatusBarStateController.getDozeAmount(); } public void destroy(Context context) { SysUiServiceProvider.getComponent(context, CommandQueue.class) .removeCallbacks(this); + mStatusBarStateController.removeListener(this); } public void saveState(Bundle outState) { @@ -173,7 +182,11 @@ public class LightBarTransitionsController implements Dumpable, Callbacks { private void setIconTintInternal(float darkIntensity) { mDarkIntensity = darkIntensity; - mApplier.applyDarkIntensity(darkIntensity); + dispatchDark(); + } + + private void dispatchDark() { + mApplier.applyDarkIntensity(MathUtils.lerp(mDarkIntensity, 0f, mDozeAmount)); } @Override @@ -196,6 +209,15 @@ public class LightBarTransitionsController implements Dumpable, Callbacks { pw.print(" mNextDarkIntensity="); pw.println(mNextDarkIntensity); } + @Override + public void onStateChanged(int newState) { } + + @Override + public void onDozeAmountChanged(float linear, float eased) { + mDozeAmount = eased; + dispatchDark(); + } + /** * 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 index 27798203e4fe..7621887b4170 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenGestureLogger.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenGestureLogger.java @@ -19,7 +19,6 @@ package com.android.systemui.statusbar.phone; import android.metrics.LogMaker; import android.util.ArrayMap; -import com.android.internal.annotations.VisibleForTesting; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.systemui.Dependency; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java index 673cdb7c78ac..d2023ec49ebc 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java @@ -20,6 +20,7 @@ import android.annotation.Nullable; import android.app.ActivityManager; import android.app.IWallpaperManager; import android.app.IWallpaperManagerCallback; +import android.app.WallpaperColors; import android.app.WallpaperManager; import android.content.Context; import android.content.res.Resources; @@ -36,7 +37,6 @@ import android.os.ParcelFileDescriptor; import android.os.RemoteException; import android.os.ServiceManager; import android.os.UserHandle; -import android.app.WallpaperColors; import android.util.Log; import com.android.keyguard.KeyguardUpdateMonitor; 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 4406b1495b2c..0cf1b3ddc213 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java @@ -144,6 +144,7 @@ public class NavigationBarFragment extends Fragment implements Callbacks { private OverviewProxyService mOverviewProxyService; + private boolean mIsOnDefaultDisplay = true; public boolean mHomeBlockedThisTouch; private final OverviewProxyListener mOverviewProxyListener = new OverviewProxyListener() { @@ -241,6 +242,11 @@ public class NavigationBarFragment extends Fragment implements Callbacks { public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); mNavigationBarView = (NavigationBarView) view; + final Display display = view.getDisplay(); + // It may not have display when running unit test. + if (display != null) { + mIsOnDefaultDisplay = display.getDisplayId() == Display.DEFAULT_DISPLAY; + } mNavigationBarView.setComponents(mStatusBar.getPanel()); mNavigationBarView.setDisabledFlags(mDisabledFlags1); @@ -253,8 +259,6 @@ public class NavigationBarFragment extends Fragment implements Callbacks { prepareNavigationBarView(); checkNavBarModes(); - setDisabled2Flags(mDisabledFlags2); - IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_OFF); filter.addAction(Intent.ACTION_SCREEN_ON); filter.addAction(Intent.ACTION_USER_SWITCHED); @@ -262,16 +266,23 @@ public class NavigationBarFragment extends Fragment implements Callbacks { notifyNavigationBarScreenOn(); mOverviewProxyService.addCallback(mOverviewProxyListener); - RotationContextButton rotationButton = mNavigationBarView.getRotateSuggestionButton(); - rotationButton.setListener(mRotationButtonListener); - rotationButton.addRotationCallback(mRotationWatcher); - - // Reset user rotation pref to match that of the WindowManager if starting in locked mode - // This will automatically happen when switching from auto-rotate to locked mode - if (rotationButton.isRotationLocked()) { - final int winRotation = mWindowManager.getDefaultDisplay().getRotation(); - rotationButton.setRotationLockedAtAngle(winRotation); + // Currently there is no accelerometer sensor on non-default display. + if (mIsOnDefaultDisplay) { + final RotationContextButton rotationButton = + mNavigationBarView.getRotateSuggestionButton(); + rotationButton.setListener(mRotationButtonListener); + rotationButton.addRotationCallback(mRotationWatcher); + + // Reset user rotation pref to match that of the WindowManager if starting in locked + // mode. This will automatically happen when switching from auto-rotate to locked mode. + if (display != null && rotationButton.isRotationLocked()) { + final int winRotation = display.getRotation(); + rotationButton.setRotationLockedAtAngle(winRotation); + } + } else { + mDisabledFlags2 |= StatusBarManager.DISABLE2_ROTATE_SUGGESTIONS; } + setDisabled2Flags(mDisabledFlags2); } @Override @@ -389,7 +400,7 @@ public class NavigationBarFragment extends Fragment implements Callbacks { @Override public void onRotationProposal(final int rotation, boolean isValid) { - final int winRotation = mWindowManager.getDefaultDisplay().getRotation(); + final int winRotation = mNavigationBarView.getDisplay().getRotation(); final boolean rotateSuggestionsDisabled = RotationContextButton .hasDisable2RotateSuggestionFlag(mDisabledFlags2); if (RotationContextButton.DEBUG_ROTATION) { @@ -477,10 +488,13 @@ public class NavigationBarFragment extends Fragment implements Callbacks { updateScreenPinningGestures(); } - final int masked2 = state2 & (StatusBarManager.DISABLE2_ROTATE_SUGGESTIONS); - if (masked2 != mDisabledFlags2) { - mDisabledFlags2 = masked2; - setDisabled2Flags(masked2); + // Only default display supports rotation suggestions. + if (mIsOnDefaultDisplay) { + final int masked2 = state2 & (StatusBarManager.DISABLE2_ROTATE_SUGGESTIONS); + if (masked2 != mDisabledFlags2) { + mDisabledFlags2 = masked2; + setDisabled2Flags(masked2); + } } } @@ -881,13 +895,23 @@ public class NavigationBarFragment extends Fragment implements Callbacks { if (DEBUG) Log.v(TAG, "addNavigationBar: about to add " + navigationBarView); if (navigationBarView == null) return null; + final NavigationBarFragment fragment = new NavigationBarFragment(); + navigationBarView.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() { + @Override + public void onViewAttachedToWindow(View v) { + final FragmentHostManager fragmentHost = FragmentHostManager.get(v); + fragmentHost.getFragmentManager().beginTransaction() + .replace(R.id.navigation_bar_frame, fragment, TAG) + .commit(); + fragmentHost.addTagListener(TAG, listener); + } + + @Override + public void onViewDetachedFromWindow(View v) { + FragmentHostManager.removeAndDestroy(v); + } + }); context.getSystemService(WindowManager.class).addView(navigationBarView, lp); - FragmentHostManager fragmentHost = FragmentHostManager.get(navigationBarView); - NavigationBarFragment fragment = new NavigationBarFragment(); - fragmentHost.getFragmentManager().beginTransaction() - .replace(R.id.navigation_bar_frame, fragment, TAG) - .commit(); - fragmentHost.addTagListener(TAG, listener); return navigationBarView; } } 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 22b6ba6fbb25..7c31dae2a746 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java @@ -14,6 +14,8 @@ package com.android.systemui.statusbar.phone; +import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; + import android.annotation.Nullable; import android.content.Context; import android.content.res.Configuration; @@ -34,11 +36,11 @@ import android.widget.LinearLayout; import android.widget.Space; import com.android.systemui.Dependency; -import com.android.systemui.recents.OverviewProxyService; import com.android.systemui.R; import com.android.systemui.plugins.PluginListener; -import com.android.systemui.shared.plugins.PluginManager; import com.android.systemui.plugins.statusbar.phone.NavBarButtonProvider; +import com.android.systemui.recents.OverviewProxyService; +import com.android.systemui.shared.plugins.PluginManager; import com.android.systemui.statusbar.phone.ReverseLinearLayout.ReverseRelativeLayout; import com.android.systemui.statusbar.policy.KeyButtonView; import com.android.systemui.tuner.TunerService; @@ -48,8 +50,6 @@ import java.util.ArrayList; import java.util.List; import java.util.Objects; -import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; - public class NavigationBarInflaterView extends FrameLayout implements Tunable, PluginListener<NavBarButtonProvider> { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarTransitions.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarTransitions.java index d58b5543221e..12a0cc882a81 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarTransitions.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarTransitions.java @@ -26,7 +26,6 @@ import android.view.IWallpaperVisibilityListener; import android.view.IWindowManager; import android.view.MotionEvent; import android.view.View; -import android.view.View.OnLayoutChangeListener; import com.android.internal.statusbar.IStatusBarService; import com.android.systemui.Dependency; 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 2c3c27fe5039..2f58ca1c984b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java @@ -17,10 +17,15 @@ package com.android.systemui.statusbar.phone; import static android.view.MotionEvent.ACTION_DOWN; + +import static com.android.systemui.shared.system.NavigationBarCompat.FLAG_DISABLE_QUICK_SCRUB; +import static com.android.systemui.shared.system.NavigationBarCompat.FLAG_SHOW_OVERVIEW_BUTTON; import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_BACK; import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_DEAD_ZONE; import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_HOME; import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_NONE; +import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_OVERVIEW; +import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_ROTATION; import android.animation.LayoutTransition; import android.animation.LayoutTransition.TransitionListener; @@ -60,15 +65,15 @@ import android.widget.FrameLayout; import com.android.systemui.Dependency; import com.android.systemui.DockedStackExistsListener; import com.android.systemui.Interpolators; -import com.android.systemui.recents.OverviewProxyService; import com.android.systemui.R; import com.android.systemui.SysUiServiceProvider; import com.android.systemui.plugins.PluginListener; -import com.android.systemui.shared.plugins.PluginManager; import com.android.systemui.plugins.statusbar.phone.NavGesture; import com.android.systemui.plugins.statusbar.phone.NavGesture.GestureHelper; +import com.android.systemui.recents.OverviewProxyService; import com.android.systemui.recents.Recents; import com.android.systemui.recents.RecentsOnboarding; +import com.android.systemui.shared.plugins.PluginManager; import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.shared.system.NavigationBarCompat; import com.android.systemui.shared.system.WindowManagerWrapper; @@ -79,11 +84,6 @@ import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.function.Consumer; -import static com.android.systemui.shared.system.NavigationBarCompat.FLAG_DISABLE_QUICK_SCRUB; -import static com.android.systemui.shared.system.NavigationBarCompat.FLAG_SHOW_OVERVIEW_BUTTON; -import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_OVERVIEW; -import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_ROTATION; - public class NavigationBarView extends FrameLayout implements PluginListener<NavGesture> { final static boolean DEBUG = false; final static String TAG = "StatusBar/NavBarView"; @@ -264,8 +264,7 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav public NavigationBarView(Context context, AttributeSet attrs) { super(context, attrs); - mDisplay = ((WindowManager) context.getSystemService( - Context.WINDOW_SERVICE)).getDefaultDisplay(); + mDisplay = context.getDisplay(); mVertical = false; mLongClickableAccessibilityButton = false; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationGestureAction.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationGestureAction.java index 593bfae2aa4c..83067f6cff87 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationGestureAction.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationGestureAction.java @@ -26,7 +26,6 @@ import android.content.Context; import android.graphics.Canvas; import android.view.MotionEvent; -import android.view.WindowManagerPolicyConstants; import com.android.systemui.recents.OverviewProxyService; /** diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NearestTouchFrame.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NearestTouchFrame.java index 1524f806f871..2a11c2676b0c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NearestTouchFrame.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NearestTouchFrame.java @@ -16,17 +16,14 @@ package com.android.systemui.statusbar.phone; import android.content.Context; import android.content.res.Configuration; -import android.graphics.Rect; -import androidx.annotation.VisibleForTesting; import android.util.AttributeSet; -import android.util.Log; import android.util.Pair; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.widget.FrameLayout; -import com.android.systemui.R; +import androidx.annotation.VisibleForTesting; import java.util.ArrayList; import java.util.Comparator; 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 ecf6b6a875b8..fa71df25c482 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java @@ -22,7 +22,6 @@ import static com.android.systemui.statusbar.notification.ActivityLaunchAnimator import android.animation.Animator; import android.animation.AnimatorListenerAdapter; -import android.animation.ObjectAnimator; import android.animation.ValueAnimator; import android.app.ActivityManager; import android.app.Fragment; @@ -41,7 +40,6 @@ import android.graphics.Rect; import android.os.PowerManager; import android.os.SystemProperties; import android.util.AttributeSet; -import android.util.FloatProperty; import android.util.Log; import android.util.MathUtils; import android.view.LayoutInflater; @@ -51,7 +49,6 @@ import android.view.View; import android.view.ViewGroup; import android.view.WindowInsets; import android.view.accessibility.AccessibilityManager; -import android.view.animation.Interpolator; import android.widget.FrameLayout; import com.android.internal.logging.MetricsLogger; @@ -104,7 +101,7 @@ public class NotificationPanelView extends PanelView implements View.OnClickListener, NotificationStackScrollLayout.OnOverscrollTopChangedListener, KeyguardAffordanceHelper.Callback, NotificationStackScrollLayout.OnEmptySpaceClickListener, OnHeadsUpChangedListener, QS.HeightListener, ZenModeController.Callback, - ConfigurationController.ConfigurationListener { + ConfigurationController.ConfigurationListener, StateListener { private static final boolean DEBUG = false; @@ -139,25 +136,9 @@ public class NotificationPanelView extends PanelView implements private static final Rect mDummyDirtyRect = new Rect(0, 0, 1, 1); - public static final long DOZE_ANIMATION_DURATION = 700; - private static final AnimationProperties CLOCK_ANIMATION_PROPERTIES = new AnimationProperties() .setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD); - private static final FloatProperty<NotificationPanelView> SET_DARK_AMOUNT_PROPERTY = - new FloatProperty<NotificationPanelView>("mInterpolatedDarkAmount") { - - @Override - public void setValue(NotificationPanelView object, float value) { - object.setDarkAmount(value, object.mDarkInterpolator.getInterpolation(value)); - } - @Override - public Float get(NotificationPanelView object) { - return object.mLinearDarkAmount; - } - }; - - private Interpolator mDarkInterpolator; private final PowerManager mPowerManager; private final AccessibilityManager mAccessibilityManager; @@ -295,11 +276,9 @@ public class NotificationPanelView extends PanelView implements */ private boolean mSemiAwake; - private float mDarkAmountTarget; private boolean mPulsing; private LockscreenGestureLogger mLockscreenGestureLogger = new LockscreenGestureLogger(); private boolean mNoVisibleNotifications = true; - private ValueAnimator mDarkAnimator; private boolean mUserSetupComplete; private int mQsNotificationTopPadding; private float mExpandOffset; @@ -339,7 +318,6 @@ public class NotificationPanelView extends PanelView implements private final NotificationEntryManager mEntryManager = Dependency.get(NotificationEntryManager.class); - private final StateListener mListener = this::setBarState; private final CommandQueue mCommandQueue; private final NotificationLockscreenUserManager mLockscreenUserManager = Dependency.get(NotificationLockscreenUserManager.class); @@ -388,7 +366,7 @@ public class NotificationPanelView extends PanelView implements protected void onAttachedToWindow() { super.onAttachedToWindow(); FragmentHostManager.get(this).addTagListener(QS.TAG, mFragmentListener); - Dependency.get(StatusBarStateController.class).addListener(mListener); + Dependency.get(StatusBarStateController.class).addListener(this); Dependency.get(ZenModeController.class).addCallback(this); Dependency.get(ConfigurationController.class).addCallback(this); } @@ -397,7 +375,7 @@ public class NotificationPanelView extends PanelView implements protected void onDetachedFromWindow() { super.onDetachedFromWindow(); FragmentHostManager.get(this).removeTagListener(QS.TAG, mFragmentListener); - Dependency.get(StatusBarStateController.class).removeListener(mListener); + Dependency.get(StatusBarStateController.class).removeListener(this); Dependency.get(ZenModeController.class).removeCallback(this); Dependency.get(ConfigurationController.class).removeCallback(this); } @@ -475,7 +453,8 @@ public class NotificationPanelView extends PanelView implements mKeyguardBottomArea.initFrom(oldBottomArea); addView(mKeyguardBottomArea, index); initBottomArea(); - setDarkAmount(mLinearDarkAmount, mInterpolatedDarkAmount); + onDozeAmountChanged(mStatusBarStateController.getDozeAmount(), + mStatusBarStateController.getInterpolatedDozeAmount()); if (mKeyguardStatusBar != null) { mKeyguardStatusBar.onThemeChanged(); @@ -1221,7 +1200,8 @@ public class NotificationPanelView extends PanelView implements } } - private void setBarState(int statusBarState) { + @Override + public void onStateChanged(int statusBarState) { boolean goingToFullShade = mStatusBarStateController.goingToFullShade(); boolean keyguardFadingAway = mKeyguardMonitor.isKeyguardFadingAway(); int oldState = mBarState; @@ -2806,24 +2786,10 @@ public class NotificationPanelView extends PanelView implements updateDozingVisibilities(animate); } - final float darkAmount = dozing ? 1 : 0; - if (mDarkAnimator != null && mDarkAnimator.isRunning()) { - if (animate && mDarkAmountTarget == darkAmount) { - return; - } else { - mDarkAnimator.cancel(); - } - if (mSemiAwake) { - setDarkAmount(0, 0); - } - } - mDarkAmountTarget = darkAmount; - if (!mSemiAwake) { - if (animate) { - startDarkAnimation(); - } else { - setDarkAmount(darkAmount, darkAmount); - } + final float darkAmount = dozing && !mSemiAwake ? 1 : 0; + mStatusBarStateController.setDozeAmount(darkAmount, animate); + if (animate) { + mNotificationStackScroller.notifyDarkAnimationStart(mDozing); } } @@ -2831,21 +2797,8 @@ public class NotificationPanelView extends PanelView implements return mSemiAwake; } - private void startDarkAnimation() { - if (mInterpolatedDarkAmount == 0f || mInterpolatedDarkAmount == 1f) { - mDarkInterpolator = mDozing - ? Interpolators.FAST_OUT_SLOW_IN - : Interpolators.TOUCH_RESPONSE_REVERSE; - } - mNotificationStackScroller.notifyDarkAnimationStart(mDozing); - mDarkAnimator = ObjectAnimator.ofFloat(this, SET_DARK_AMOUNT_PROPERTY, mDozing ? 1 : 0); - mDarkAnimator.setInterpolator(Interpolators.LINEAR); - mDarkAnimator.setDuration( - mNotificationStackScroller.getDarkAnimationDuration(mDozing)); - mDarkAnimator.start(); - } - - private void setDarkAmount(float linearAmount, float amount) { + @Override + public void onDozeAmountChanged(float linearAmount, float amount) { mInterpolatedDarkAmount = amount; mLinearDarkAmount = linearAmount; mKeyguardStatusBar.setDarkAmount(mInterpolatedDarkAmount); @@ -3047,7 +3000,8 @@ public class NotificationPanelView extends PanelView implements mSemiAwake = false; mNotificationStackScroller.setDark(false /* dark */, true /* animate */, null /* touchLocation */); - startDarkAnimation(); + mStatusBarStateController.setDozeAmount(0f, true /* animated */); + mNotificationStackScroller.notifyDarkAnimationStart(mDozing); mStatusBar.updateScrimController(); return WAKE_UP_TO_SHADE; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java index e7ede6f626ba..ca762cdf07f3 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java @@ -20,7 +20,6 @@ import android.app.Fragment; import android.content.Context; import android.content.res.Configuration; import android.graphics.Canvas; -import androidx.annotation.DimenRes; import android.util.AttributeSet; import android.view.View; import android.view.ViewStub; @@ -28,6 +27,8 @@ import android.view.ViewStub.OnInflateListener; import android.view.WindowInsets; import android.widget.FrameLayout; +import androidx.annotation.DimenRes; + import com.android.systemui.R; import com.android.systemui.fragments.FragmentHostManager; import com.android.systemui.fragments.FragmentHostManager.FragmentListener; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java index deac669e31d8..65b0ecc00953 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java @@ -22,7 +22,6 @@ import android.os.Parcelable; import android.util.AttributeSet; import android.util.Log; import android.view.MotionEvent; -import android.view.View; import android.widget.FrameLayout; public abstract class PanelBar extends FrameLayout { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickScrubAction.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickScrubAction.java index c64e12478098..74744f1408fb 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickScrubAction.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickScrubAction.java @@ -34,7 +34,6 @@ import android.graphics.RadialGradient; import android.graphics.Rect; import android.graphics.Shader; import android.os.RemoteException; - import android.util.FloatProperty; import android.util.Log; import android.view.MotionEvent; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java index 37c4c58a3bd9..0eff4d4adff5 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java @@ -42,10 +42,10 @@ import android.view.ViewPropertyAnimator; import com.android.systemui.Dependency; import com.android.systemui.Interpolators; -import com.android.systemui.plugins.statusbar.phone.NavGesture.GestureHelper; import com.android.systemui.R; -import com.android.systemui.recents.OverviewProxyService; import com.android.systemui.SysUiServiceProvider; +import com.android.systemui.plugins.statusbar.phone.NavGesture.GestureHelper; +import com.android.systemui.recents.OverviewProxyService; import com.android.systemui.shared.recents.IOverviewProxy; import com.android.systemui.shared.recents.utilities.Utilities; import com.android.systemui.shared.system.NavigationBarCompat; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/RotationContextButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/RotationContextButton.java index c6e98e0cfeb3..a7b8eff959c2 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/RotationContextButton.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/RotationContextButton.java @@ -39,10 +39,10 @@ import android.view.Surface; import android.view.View; import android.view.WindowManagerGlobal; -import com.android.systemui.Dependency; -import com.android.systemui.Interpolators; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; +import com.android.systemui.Dependency; +import com.android.systemui.Interpolators; import com.android.systemui.R; import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.shared.system.TaskStackChangeListener; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScreenPinningNotify.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScreenPinningNotify.java index 2a5028bbe181..f8731b4980d9 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScreenPinningNotify.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScreenPinningNotify.java @@ -19,7 +19,6 @@ package com.android.systemui.statusbar.phone; import android.content.Context; import android.os.SystemClock; import android.util.Slog; -import android.view.WindowManager; import android.widget.Toast; import com.android.systemui.R; 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 1bed26dd3474..9f34cbb23131 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java @@ -23,7 +23,6 @@ import android.app.AlarmManager; import android.app.WallpaperManager; import android.content.Context; import android.graphics.Color; -import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.os.Handler; import android.os.Trace; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ShadeController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ShadeController.java index e546119968aa..f9262186968f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ShadeController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ShadeController.java @@ -15,6 +15,7 @@ package com.android.systemui.statusbar.phone; import android.view.View; + import com.android.systemui.statusbar.StatusBarState; import com.android.systemui.statusbar.notification.row.ActivatableNotificationView; 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 12fbf2d979f4..a6a9d74a894c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java @@ -342,7 +342,8 @@ public class StatusBar extends SystemUI implements DemoMode, private int mStatusBarWindowState = WINDOW_STATE_SHOWING; protected StatusBarWindowController mStatusBarWindowController; protected UnlockMethodCache mUnlockMethodCache; - private DozeServiceHost mDozeServiceHost = new DozeServiceHost(); + @VisibleForTesting + DozeServiceHost mDozeServiceHost = new DozeServiceHost(); private boolean mWakeUpComingFromTouch; private PointF mWakeUpTouchLocation; @@ -479,7 +480,7 @@ public class StatusBar extends SystemUI implements DemoMode, private boolean mLaunchCameraOnScreenTurningOn; private boolean mLaunchCameraOnFinishedGoingToSleep; private int mLastCameraLaunchSource; - private PowerManager.WakeLock mGestureWakeLock; + protected PowerManager.WakeLock mGestureWakeLock; private Vibrator mVibrator; private long[] mCameraLaunchGestureVibePattern; @@ -3609,6 +3610,7 @@ public class StatusBar extends SystemUI implements DemoMode, } } + @VisibleForTesting final WakefulnessLifecycle.Observer mWakefulnessObserver = new WakefulnessLifecycle.Observer() { @Override public void onFinishedGoingToSleep() { @@ -3650,6 +3652,7 @@ public class StatusBar extends SystemUI implements DemoMode, mNotificationPanel.setTouchAndAnimationDisabled(false); updateVisibleToUser(); updateIsKeyguard(); + mDozeServiceHost.stopDozing(); } }; @@ -3856,7 +3859,8 @@ public class StatusBar extends SystemUI implements DemoMode, return mStatusBarKeyguardViewManager.isShowing(); } - private final class DozeServiceHost implements DozeHost { + @VisibleForTesting + final class DozeServiceHost implements DozeHost { private final ArrayList<Callback> mCallbacks = new ArrayList<>(); private boolean mAnimateWakeup; private boolean mAnimateScreenOff; @@ -3944,7 +3948,6 @@ public class StatusBar extends SystemUI implements DemoMode, mDozingRequested = false; DozeLog.traceDozing(mContext, mDozing); updateDozing(); - mWakefulnessLifecycle.dispatchStartedWakingUp(); } } 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 0d6cb5c50077..26c9d288494d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java @@ -16,16 +16,15 @@ package com.android.systemui.statusbar.phone; import static android.app.StatusBarManager.DISABLE2_SYSTEM_ICONS; import static android.app.StatusBarManager.DISABLE_NONE; + import static com.android.systemui.statusbar.phone.StatusBarIconHolder.TYPE_ICON; import static com.android.systemui.statusbar.phone.StatusBarIconHolder.TYPE_MOBILE; import static com.android.systemui.statusbar.phone.StatusBarIconHolder.TYPE_WIFI; import android.content.Context; import android.os.Bundle; -import androidx.annotation.VisibleForTesting; import android.text.TextUtils; import android.util.ArraySet; -import android.util.Log; import android.view.Gravity; import android.view.View; import android.view.ViewGroup; @@ -33,19 +32,22 @@ import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.LinearLayout.LayoutParams; +import androidx.annotation.VisibleForTesting; + import com.android.internal.statusbar.StatusBarIcon; import com.android.systemui.DemoMode; import com.android.systemui.Dependency; import com.android.systemui.R; -import com.android.systemui.statusbar.StatusIconDisplayable; import com.android.systemui.statusbar.StatusBarIconView; import com.android.systemui.statusbar.StatusBarMobileView; import com.android.systemui.statusbar.StatusBarWifiView; +import com.android.systemui.statusbar.StatusIconDisplayable; import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.MobileIconState; import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.WifiIconState; import com.android.systemui.statusbar.policy.DarkIconDispatcher; import com.android.systemui.statusbar.policy.DarkIconDispatcher.DarkReceiver; import com.android.systemui.util.Utils.DisableStateTracker; + import java.util.List; public interface StatusBarIconController { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java index 24a589665600..7c17c018443e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java @@ -45,8 +45,6 @@ import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; -import static com.android.systemui.statusbar.phone.StatusBarIconController.TAG_PRIMARY; - /** * Receives the callbacks from CommandQueue related to icons and tracks the state of * all the icons. Dispatches this state to any IconManagers that are currently diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconHolder.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconHolder.java index c4ff85fb7984..88d0035b333d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconHolder.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconHolder.java @@ -20,6 +20,7 @@ import android.annotation.Nullable; import android.content.Context; import android.graphics.drawable.Icon; import android.os.UserHandle; + import com.android.internal.statusbar.StatusBarIcon; import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.MobileIconState; import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.WifiIconState; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconList.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconList.java index b7e1cfb0097b..2e4161787267 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconList.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconList.java @@ -16,16 +16,17 @@ package com.android.systemui.statusbar.phone; +import static com.android.systemui.statusbar.phone.StatusBarIconController.TAG_PRIMARY; + import android.annotation.NonNull; import android.annotation.Nullable; + import com.android.internal.annotations.VisibleForTesting; -import com.android.internal.statusbar.StatusBarIcon; + import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; -import static com.android.systemui.statusbar.phone.StatusBarIconController.TAG_PRIMARY; - public class StatusBarIconList { private ArrayList<Slot> mSlots = new ArrayList<>(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java index f81ffe9ecb76..8286d26e9999 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java @@ -17,29 +17,20 @@ package com.android.systemui.statusbar.phone; import android.content.Context; -import android.content.res.ColorStateList; -import android.graphics.Rect; import android.os.Handler; -import android.os.Looper; import android.telephony.SubscriptionInfo; import android.util.ArraySet; import android.util.Log; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.view.accessibility.AccessibilityEvent; -import android.widget.ImageView; -import com.android.settingslib.graph.SignalDrawable; + import com.android.systemui.Dependency; import com.android.systemui.R; -import com.android.systemui.statusbar.phone.StatusBarIconController; -import com.android.systemui.statusbar.policy.DarkIconDispatcher; import com.android.systemui.statusbar.policy.NetworkController; import com.android.systemui.statusbar.policy.NetworkController.IconState; import com.android.systemui.statusbar.policy.NetworkControllerImpl; import com.android.systemui.statusbar.policy.SecurityController; import com.android.systemui.tuner.TunerService; import com.android.systemui.tuner.TunerService.Tunable; + import java.util.ArrayList; import java.util.List; import java.util.Objects; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java index ad9b9b30fafc..978a72dcb4b7 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java @@ -33,7 +33,6 @@ import android.media.AudioManager; import android.media.session.MediaSessionLegacyHelper; import android.net.Uri; import android.os.Bundle; -import android.os.IBinder; import android.os.SystemClock; import android.util.AttributeSet; import android.view.ActionMode; @@ -50,8 +49,6 @@ import android.view.View; import android.view.ViewGroup; import android.view.ViewTreeObserver; import android.view.Window; -import android.view.WindowManager; -import android.view.WindowManagerGlobal; import android.widget.FrameLayout; import com.android.internal.annotations.VisibleForTesting; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusIconContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusIconContainer.java index 56a177eb15fe..6495910359bb 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusIconContainer.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusIconContainer.java @@ -16,9 +16,9 @@ package com.android.systemui.statusbar.phone; -import static com.android.systemui.statusbar.StatusBarIconView.STATE_ICON; import static com.android.systemui.statusbar.StatusBarIconView.STATE_DOT; import static com.android.systemui.statusbar.StatusBarIconView.STATE_HIDDEN; +import static com.android.systemui.statusbar.StatusBarIconView.STATE_ICON; import android.annotation.Nullable; import android.content.Context; @@ -28,14 +28,15 @@ import android.graphics.Paint; import android.graphics.Paint.Style; import android.util.AttributeSet; import android.util.Log; - import android.view.View; + import com.android.keyguard.AlphaOptimizedLinearLayout; import com.android.systemui.R; import com.android.systemui.statusbar.StatusIconDisplayable; import com.android.systemui.statusbar.notification.stack.AnimationFilter; import com.android.systemui.statusbar.notification.stack.AnimationProperties; import com.android.systemui.statusbar.notification.stack.ViewState; + import java.util.ArrayList; /** diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java index e5925f07017f..bdd76c8ea05a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java @@ -16,8 +16,8 @@ package com.android.systemui.statusbar.phone; -import android.hardware.biometrics.BiometricSourceType; import android.content.Context; +import android.hardware.biometrics.BiometricSourceType; import android.os.Trace; import com.android.internal.widget.LockPatternUtils; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UserAvatarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UserAvatarView.java index 2ed2edb969bd..ba55f2ddcf13 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UserAvatarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UserAvatarView.java @@ -20,7 +20,6 @@ import android.content.Context; import android.content.res.ColorStateList; import android.content.res.TypedArray; import android.graphics.Bitmap; -import android.graphics.PorterDuff; import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.view.View; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java index 6f4026db5633..f65f8261dcfb 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java @@ -55,4 +55,11 @@ public interface BatteryController extends DemoMode, Dumpable, default void onBatteryLevelChanged(int level, boolean pluggedIn, boolean charging) {} default void onPowerSaveChanged(boolean isPowerSave) {} } + + /** + * If available, get the estimated battery time remaining as a string + */ + default String getEstimatedTimeRemainingString() { + return null; + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java index 7221efab0bb2..ddcfbf6f3c31 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java @@ -29,9 +29,14 @@ import android.util.Log; import com.android.internal.annotations.VisibleForTesting; import com.android.settingslib.fuelgauge.BatterySaverUtils; +import com.android.settingslib.utils.PowerUtil; +import com.android.systemui.Dependency; +import com.android.systemui.power.EnhancedEstimates; +import com.android.systemui.power.Estimate; import java.io.FileDescriptor; import java.io.PrintWriter; +import java.text.NumberFormat; import java.util.ArrayList; /** @@ -44,7 +49,9 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC public static final String ACTION_LEVEL_TEST = "com.android.systemui.BATTERY_LEVEL_TEST"; private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); + private static final int UPDATE_GRANULARITY_MSEC = 1000 * 60; + private final EnhancedEstimates mEstimates = Dependency.get(EnhancedEstimates.class); private final ArrayList<BatteryController.BatteryStateChangeCallback> mChangeCallbacks = new ArrayList<>(); private final PowerManager mPowerManager; private final Handler mHandler; @@ -58,6 +65,8 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC protected boolean mAodPowerSave; private boolean mTestmode = false; private boolean mHasReceivedBattery = false; + private Estimate mEstimate; + private long mLastEstimateTimestamp = -1; public BatteryControllerImpl(Context context) { this(context, context.getSystemService(PowerManager.class)); @@ -71,6 +80,7 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC registerReceiver(); updatePowerSave(); + updateEstimate(); } private void registerReceiver() { @@ -180,6 +190,26 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC return mAodPowerSave; } + @Override + public String getEstimatedTimeRemainingString() { + if (mEstimate == null + || System.currentTimeMillis() > mLastEstimateTimestamp + UPDATE_GRANULARITY_MSEC) { + updateEstimate(); + } + // Estimates may not exist yet even if we've checked + if (mEstimate == null) { + return null; + } + final String percentage = NumberFormat.getPercentInstance().format((double) mLevel / 100.0); + return PowerUtil.getBatteryRemainingShortStringFormatted( + mContext, mEstimate.estimateMillis); + } + + private void updateEstimate() { + mEstimate = mEstimates.getEstimate(); + mLastEstimateTimestamp = System.currentTimeMillis(); + } + private void updatePowerSave() { setPowerSave(mPowerManager.isPowerSaveMode()); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CallbackHandler.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CallbackHandler.java index b76d536150eb..e1bb19a6f69f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CallbackHandler.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CallbackHandler.java @@ -19,6 +19,7 @@ import android.os.Handler; import android.os.Looper; import android.os.Message; import android.telephony.SubscriptionInfo; + import com.android.internal.annotations.VisibleForTesting; import com.android.systemui.statusbar.policy.NetworkController.EmergencyListener; import com.android.systemui.statusbar.policy.NetworkController.IconState; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerImpl.java index 533bd86dbf5e..ccfe073d5cb8 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerImpl.java @@ -16,6 +16,8 @@ package com.android.systemui.statusbar.policy; +import static android.media.MediaRouter.ROUTE_TYPE_REMOTE_DISPLAY; + import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; @@ -30,6 +32,8 @@ import android.util.ArrayMap; import android.util.ArraySet; import android.util.Log; +import androidx.annotation.VisibleForTesting; + import com.android.internal.annotations.GuardedBy; import com.android.systemui.R; @@ -40,10 +44,6 @@ import java.util.Objects; import java.util.Set; import java.util.UUID; -import static android.media.MediaRouter.ROUTE_TYPE_REMOTE_DISPLAY; - -import androidx.annotation.VisibleForTesting; - /** Platform implementation of the cast controller. **/ public class CastControllerImpl implements CastController { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DataSaverControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DataSaverControllerImpl.java index 2ede327ab698..911715fdba63 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DataSaverControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DataSaverControllerImpl.java @@ -21,8 +21,6 @@ import android.os.Handler; import android.os.Looper; import android.os.RemoteException; -import com.android.systemui.statusbar.policy.DataSaverController.Listener; - import java.util.ArrayList; public class DataSaverControllerImpl implements DataSaverController { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DateView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DateView.java index dcce77c7c355..74a30fa8094f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DateView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DateView.java @@ -27,7 +27,6 @@ import android.text.TextUtils; import android.util.AttributeSet; import android.widget.TextView; -import com.android.settingslib.Utils; import com.android.systemui.Dependency; import com.android.systemui.R; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceProvisionedController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceProvisionedController.java index cae76b492527..7b4c35a8d25a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceProvisionedController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceProvisionedController.java @@ -14,8 +14,6 @@ package com.android.systemui.statusbar.policy; -import android.content.Context; - import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener; public interface DeviceProvisionedController extends CallbackController<DeviceProvisionedListener> { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/EmergencyCryptkeeperText.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/EmergencyCryptkeeperText.java index c7261899a786..0d6178b1176b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/EmergencyCryptkeeperText.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/EmergencyCryptkeeperText.java @@ -23,13 +23,9 @@ import android.content.Intent; import android.content.IntentFilter; import android.net.ConnectivityManager; import android.provider.Settings; -import android.telephony.ServiceState; import android.telephony.SubscriptionInfo; import android.text.TextUtils; import android.util.AttributeSet; -import android.util.Log; -import android.view.ViewGroup; -import android.view.ViewParent; import android.widget.TextView; import com.android.internal.telephony.IccCardConstants; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/FlashlightControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/FlashlightControllerImpl.java index 11fc40804f71..e23ce2d022b3 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/FlashlightControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/FlashlightControllerImpl.java @@ -30,8 +30,6 @@ import android.provider.Settings.Secure; import android.text.TextUtils; import android.util.Log; -import com.android.systemui.statusbar.policy.FlashlightController.FlashlightListener; - import java.io.FileDescriptor; import java.io.PrintWriter; import java.lang.ref.WeakReference; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java index b4d24d16113e..6b83b70b0ca5 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java @@ -16,22 +16,23 @@ package com.android.systemui.statusbar.policy; -import static com.android.systemui.statusbar.notification.row.NotificationInflater.FLAG_CONTENT_VIEW_HEADS_UP; +import static com.android.systemui.statusbar.notification.row.NotificationInflater + .FLAG_CONTENT_VIEW_HEADS_UP; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; import android.content.res.Resources; import android.database.ContentObserver; -import android.util.ArrayMap; import android.provider.Settings; +import android.util.ArrayMap; import android.util.Log; import com.android.internal.logging.MetricsLogger; import com.android.systemui.R; import com.android.systemui.statusbar.AlertingNotificationManager; -import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import com.android.systemui.statusbar.notification.NotificationData; +import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import java.io.FileDescriptor; import java.io.PrintWriter; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/IconLoggerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/IconLoggerImpl.java index 5fd79a4bb342..aee021ce4688 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/IconLoggerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/IconLoggerImpl.java @@ -23,9 +23,10 @@ import android.content.Context; import android.metrics.LogMaker; import android.os.Handler; import android.os.Looper; -import androidx.annotation.VisibleForTesting; import android.util.ArraySet; +import androidx.annotation.VisibleForTesting; + import com.android.internal.logging.MetricsLogger; import java.util.Arrays; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonDrawable.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonDrawable.java index 2340786d81fb..03c89c60360f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonDrawable.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonDrawable.java @@ -37,6 +37,7 @@ import android.graphics.drawable.AnimatedVectorDrawable; import android.graphics.drawable.Drawable; import android.util.FloatProperty; import android.view.ContextThemeWrapper; + import com.android.settingslib.Utils; import com.android.systemui.R; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonRipple.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonRipple.java index 59bd85eaabd4..8b869969e215 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonRipple.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonRipple.java @@ -25,9 +25,9 @@ import android.graphics.CanvasProperty; import android.graphics.ColorFilter; import android.graphics.Paint; import android.graphics.PixelFormat; +import android.graphics.RecordingCanvas; import android.graphics.drawable.Drawable; import android.os.Handler; -import android.graphics.RecordingCanvas; import android.view.RenderNodeAnimator; import android.view.View; import android.view.ViewConfiguration; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java index 6fa73ef62447..2c756ceb1b48 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java @@ -45,12 +45,13 @@ import android.view.ViewConfiguration; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityNodeInfo; import android.widget.ImageView; + import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.systemui.Dependency; -import com.android.systemui.recents.OverviewProxyService; import com.android.systemui.R; import com.android.systemui.plugins.statusbar.phone.NavBarButtonProvider.ButtonInterface; +import com.android.systemui.recents.OverviewProxyService; import com.android.systemui.shared.system.NavigationBarCompat; public class KeyButtonView extends ImageView implements ButtonInterface { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java index fcd7e0953825..840e77ea85a2 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java @@ -29,12 +29,14 @@ import android.location.LocationManager; import android.os.Handler; import android.os.Looper; import android.os.Message; -import android.os.Process; import android.os.UserHandle; import android.os.UserManager; import android.provider.Settings; + import androidx.annotation.VisibleForTesting; + import com.android.systemui.util.Utils; + import java.util.ArrayList; import java.util.List; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java index 8ca14152f080..e943261bda7b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java @@ -35,8 +35,8 @@ import android.util.SparseArray; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.telephony.TelephonyIntents; import com.android.internal.telephony.cdma.EriInfo; -import com.android.settingslib.graph.SignalDrawable; import com.android.settingslib.Utils; +import com.android.settingslib.graph.SignalDrawable; import com.android.systemui.R; import com.android.systemui.statusbar.policy.NetworkController.IconState; import com.android.systemui.statusbar.policy.NetworkController.SignalCallback; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NextAlarmControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NextAlarmControllerImpl.java index dfdeae1fc497..dac878c69313 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NextAlarmControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NextAlarmControllerImpl.java @@ -23,8 +23,6 @@ import android.content.Intent; import android.content.IntentFilter; import android.os.UserHandle; -import com.android.systemui.statusbar.policy.NextAlarmController.NextAlarmChangeCallback; - import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/OnHeadsUpChangedListener.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/OnHeadsUpChangedListener.java index 5028fd1cec9e..d43476885979 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/OnHeadsUpChangedListener.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/OnHeadsUpChangedListener.java @@ -16,8 +16,8 @@ package com.android.systemui.statusbar.policy; -import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import com.android.systemui.statusbar.notification.NotificationData; +import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; /** * A listener to heads up changes diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java index 7dd0d0fbef47..a485fa89ebe8 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java @@ -55,8 +55,8 @@ import com.android.internal.logging.nano.MetricsProto; import com.android.systemui.Dependency; import com.android.systemui.Interpolators; import com.android.systemui.R; -import com.android.systemui.statusbar.notification.NotificationData; import com.android.systemui.statusbar.RemoteInputController; +import com.android.systemui.statusbar.notification.NotificationData; import com.android.systemui.statusbar.notification.row.wrapper.NotificationViewWrapper; import com.android.systemui.statusbar.notification.stack.StackStateAnimator; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SignalController.java index 91c208d571f5..9ec30d43ac75 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SignalController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SignalController.java @@ -15,16 +15,17 @@ */ package com.android.systemui.statusbar.policy; +import static com.android.systemui.statusbar.policy.NetworkControllerImpl.TAG; + import android.content.Context; import android.text.format.DateFormat; import android.util.Log; + import com.android.systemui.statusbar.policy.NetworkController.SignalCallback; import java.io.PrintWriter; import java.util.BitSet; -import static com.android.systemui.statusbar.policy.NetworkControllerImpl.TAG; - /** * Common base class for handling signal for both wifi and mobile data. diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyConstants.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyConstants.java index 7b0b80049966..71d6e5421b75 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyConstants.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyConstants.java @@ -16,7 +16,6 @@ package com.android.systemui.statusbar.policy; -import android.content.ContentResolver; import android.content.Context; import android.content.res.Resources; import android.database.ContentObserver; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java index aa4782fd864a..42f1378a15dc 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java @@ -28,11 +28,11 @@ import android.widget.Button; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.ContrastColorUtil; -import com.android.systemui.plugins.ActivityStarter.OnDismissAction; import com.android.systemui.Dependency; import com.android.systemui.R; -import com.android.systemui.statusbar.notification.NotificationData; +import com.android.systemui.plugins.ActivityStarter.OnDismissAction; import com.android.systemui.statusbar.SmartReplyController; +import com.android.systemui.statusbar.notification.NotificationData; import com.android.systemui.statusbar.notification.NotificationUtils; import com.android.systemui.statusbar.phone.KeyguardDismissUtil; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserInfoControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserInfoControllerImpl.java index f5ae88b1788d..fed803217568 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserInfoControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserInfoControllerImpl.java @@ -37,7 +37,6 @@ import android.util.Log; import com.android.internal.util.UserIcons; import com.android.settingslib.drawable.UserIconDrawable; import com.android.systemui.R; -import com.android.systemui.statusbar.policy.UserInfoController.OnUserInfoChangedListener; import java.util.ArrayList; 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 b5d92a5840e0..cd379c5f551f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java @@ -25,7 +25,6 @@ import android.os.ServiceManager; import com.android.internal.statusbar.IStatusBarService; import com.android.internal.statusbar.StatusBarIcon; import com.android.systemui.SystemUI; -import com.android.systemui.pip.tv.PipManager; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.CommandQueue.Callbacks; diff --git a/packages/SystemUI/src/com/android/systemui/tuner/BatteryPreference.java b/packages/SystemUI/src/com/android/systemui/tuner/BatteryPreference.java index 499be42b0b8c..905b9a398b68 100644 --- a/packages/SystemUI/src/com/android/systemui/tuner/BatteryPreference.java +++ b/packages/SystemUI/src/com/android/systemui/tuner/BatteryPreference.java @@ -14,19 +14,21 @@ package com.android.systemui.tuner; +import static android.provider.Settings.System.SHOW_BATTERY_PERCENT; + import android.content.Context; import android.provider.Settings; -import androidx.preference.DropDownPreference; import android.text.TextUtils; import android.util.ArraySet; import android.util.AttributeSet; + +import androidx.preference.DropDownPreference; + 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 android.provider.Settings.System.SHOW_BATTERY_PERCENT; - public class BatteryPreference extends DropDownPreference implements TunerService.Tunable { private static final String PERCENT = "percent"; diff --git a/packages/SystemUI/src/com/android/systemui/tuner/BetterListPreference.java b/packages/SystemUI/src/com/android/systemui/tuner/BetterListPreference.java index 702abeabc136..265823ab0b21 100644 --- a/packages/SystemUI/src/com/android/systemui/tuner/BetterListPreference.java +++ b/packages/SystemUI/src/com/android/systemui/tuner/BetterListPreference.java @@ -15,9 +15,10 @@ package com.android.systemui.tuner; import android.content.Context; -import androidx.preference.ListPreference; import android.util.AttributeSet; +import androidx.preference.ListPreference; + public class BetterListPreference extends ListPreference { private CharSequence mSummary; diff --git a/packages/SystemUI/src/com/android/systemui/tuner/ClockPreference.java b/packages/SystemUI/src/com/android/systemui/tuner/ClockPreference.java index 16ab65c341ca..a526603372bd 100644 --- a/packages/SystemUI/src/com/android/systemui/tuner/ClockPreference.java +++ b/packages/SystemUI/src/com/android/systemui/tuner/ClockPreference.java @@ -14,11 +14,12 @@ package com.android.systemui.tuner; import android.content.Context; -import androidx.preference.DropDownPreference; import android.text.TextUtils; import android.util.ArraySet; import android.util.AttributeSet; +import androidx.preference.DropDownPreference; + import com.android.systemui.Dependency; import com.android.systemui.statusbar.phone.StatusBarIconController; import com.android.systemui.statusbar.policy.Clock; diff --git a/packages/SystemUI/src/com/android/systemui/tuner/CustomListPreference.java b/packages/SystemUI/src/com/android/systemui/tuner/CustomListPreference.java index 8da0043bf439..ade1f8258335 100644 --- a/packages/SystemUI/src/com/android/systemui/tuner/CustomListPreference.java +++ b/packages/SystemUI/src/com/android/systemui/tuner/CustomListPreference.java @@ -14,7 +14,6 @@ package com.android.systemui.tuner; -import android.annotation.Nullable; import android.app.AlertDialog; import android.app.Dialog; import android.app.DialogFragment; @@ -22,12 +21,10 @@ import android.content.Context; import android.content.DialogInterface; import android.content.DialogInterface.OnClickListener; import android.os.Bundle; -import androidx.preference.ListPreferenceDialogFragment; -import androidx.preference.ListPreference; import android.util.AttributeSet; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; + +import androidx.preference.ListPreference; +import androidx.preference.ListPreferenceDialogFragment; public class CustomListPreference extends ListPreference { diff --git a/packages/SystemUI/src/com/android/systemui/tuner/DemoModeFragment.java b/packages/SystemUI/src/com/android/systemui/tuner/DemoModeFragment.java index a0f278bfbb8a..a60ca6201419 100644 --- a/packages/SystemUI/src/com/android/systemui/tuner/DemoModeFragment.java +++ b/packages/SystemUI/src/com/android/systemui/tuner/DemoModeFragment.java @@ -23,12 +23,13 @@ import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.provider.Settings; -import androidx.preference.PreferenceFragment; -import androidx.preference.SwitchPreference; +import android.view.MenuItem; + import androidx.preference.Preference; import androidx.preference.Preference.OnPreferenceChangeListener; +import androidx.preference.PreferenceFragment; import androidx.preference.PreferenceScreen; -import android.view.MenuItem; +import androidx.preference.SwitchPreference; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; diff --git a/packages/SystemUI/src/com/android/systemui/tuner/LockscreenFragment.java b/packages/SystemUI/src/com/android/systemui/tuner/LockscreenFragment.java index d63235ca8d26..4dbceac9b3a7 100644 --- a/packages/SystemUI/src/com/android/systemui/tuner/LockscreenFragment.java +++ b/packages/SystemUI/src/com/android/systemui/tuner/LockscreenFragment.java @@ -21,32 +21,25 @@ import android.content.Context; import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.pm.LauncherActivityInfo; -import android.content.pm.LauncherApps; -import android.content.pm.LauncherApps.ShortcutQuery; import android.content.pm.PackageManager.NameNotFoundException; -import android.content.pm.ShortcutInfo; import android.graphics.drawable.Drawable; -import android.graphics.drawable.ScaleDrawable; import android.os.Bundle; import android.os.Handler; -import android.os.Process; -import androidx.preference.PreferenceFragment; -import androidx.preference.SwitchPreference; -import androidx.preference.Preference; -import androidx.preference.PreferenceGroup; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.RecyclerView; -import androidx.recyclerview.widget.RecyclerView.ViewHolder; import android.text.TextUtils; -import android.util.Log; import android.util.TypedValue; -import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; +import androidx.preference.Preference; +import androidx.preference.PreferenceFragment; +import androidx.preference.SwitchPreference; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; +import androidx.recyclerview.widget.RecyclerView.ViewHolder; + import com.android.systemui.Dependency; import com.android.systemui.R; import com.android.systemui.plugins.IntentButtonProvider.IntentButton; @@ -57,7 +50,6 @@ import com.android.systemui.tuner.ShortcutParser.Shortcut; import com.android.systemui.tuner.TunerService.Tunable; import java.util.ArrayList; -import java.util.List; import java.util.Map; import java.util.function.Consumer; diff --git a/packages/SystemUI/src/com/android/systemui/tuner/NavBarTuner.java b/packages/SystemUI/src/com/android/systemui/tuner/NavBarTuner.java index e3a452a0786a..fa531b5243b4 100644 --- a/packages/SystemUI/src/com/android/systemui/tuner/NavBarTuner.java +++ b/packages/SystemUI/src/com/android/systemui/tuner/NavBarTuner.java @@ -34,9 +34,6 @@ import android.graphics.drawable.Drawable; import android.graphics.drawable.Icon; import android.os.Bundle; import android.os.Handler; -import androidx.preference.ListPreference; -import androidx.preference.Preference; -import androidx.preference.Preference.OnPreferenceChangeListener; import android.text.SpannableStringBuilder; import android.text.style.ImageSpan; import android.util.Log; @@ -44,6 +41,10 @@ import android.util.TypedValue; import android.view.KeyEvent; import android.widget.EditText; +import androidx.preference.ListPreference; +import androidx.preference.Preference; +import androidx.preference.Preference.OnPreferenceChangeListener; + import com.android.systemui.Dependency; import com.android.systemui.R; import com.android.systemui.tuner.TunerService.Tunable; diff --git a/packages/SystemUI/src/com/android/systemui/tuner/OtherPrefs.java b/packages/SystemUI/src/com/android/systemui/tuner/OtherPrefs.java index d766145f27db..7239c8a22a31 100644 --- a/packages/SystemUI/src/com/android/systemui/tuner/OtherPrefs.java +++ b/packages/SystemUI/src/com/android/systemui/tuner/OtherPrefs.java @@ -15,7 +15,9 @@ package com.android.systemui.tuner; import android.os.Bundle; + import androidx.preference.PreferenceFragment; + import com.android.systemui.R; public class OtherPrefs extends PreferenceFragment { @@ -23,4 +25,4 @@ public class OtherPrefs extends PreferenceFragment { public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { addPreferencesFromResource(R.xml.other_settings); } -}
\ No newline at end of file +} diff --git a/packages/SystemUI/src/com/android/systemui/tuner/PluginFragment.java b/packages/SystemUI/src/com/android/systemui/tuner/PluginFragment.java index ecb830c48ccc..dae1472c42af 100644 --- a/packages/SystemUI/src/com/android/systemui/tuner/PluginFragment.java +++ b/packages/SystemUI/src/com/android/systemui/tuner/PluginFragment.java @@ -29,6 +29,11 @@ import android.util.ArrayMap; import android.util.ArraySet; import android.view.View; +import androidx.preference.PreferenceFragment; +import androidx.preference.PreferenceScreen; +import androidx.preference.PreferenceViewHolder; +import androidx.preference.SwitchPreference; + import com.android.internal.util.ArrayUtils; import com.android.systemui.Dependency; import com.android.systemui.R; @@ -41,11 +46,6 @@ import com.android.systemui.shared.plugins.PluginPrefs; import java.util.List; import java.util.Set; -import androidx.preference.PreferenceFragment; -import androidx.preference.PreferenceScreen; -import androidx.preference.PreferenceViewHolder; -import androidx.preference.SwitchPreference; - public class PluginFragment extends PreferenceFragment { public static final String ACTION_PLUGIN_SETTINGS diff --git a/packages/SystemUI/src/com/android/systemui/tuner/PowerNotificationControlsFragment.java b/packages/SystemUI/src/com/android/systemui/tuner/PowerNotificationControlsFragment.java index 8740a3c2f45a..80f9de6b4ba5 100644 --- a/packages/SystemUI/src/com/android/systemui/tuner/PowerNotificationControlsFragment.java +++ b/packages/SystemUI/src/com/android/systemui/tuner/PowerNotificationControlsFragment.java @@ -15,10 +15,6 @@ */ package com.android.systemui.tuner; -import com.android.internal.logging.MetricsLogger; -import com.android.internal.logging.nano.MetricsProto.MetricsEvent; -import com.android.systemui.R; - import android.annotation.Nullable; import android.app.Fragment; import android.os.Bundle; @@ -29,6 +25,10 @@ import android.view.ViewGroup; import android.widget.Switch; import android.widget.TextView; +import com.android.internal.logging.MetricsLogger; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; +import com.android.systemui.R; + public class PowerNotificationControlsFragment extends Fragment { private static final String KEY_SHOW_PNC = "show_importance_slider"; diff --git a/packages/SystemUI/src/com/android/systemui/tuner/RadioListPreference.java b/packages/SystemUI/src/com/android/systemui/tuner/RadioListPreference.java index d80c649be1ba..79811c5de42d 100644 --- a/packages/SystemUI/src/com/android/systemui/tuner/RadioListPreference.java +++ b/packages/SystemUI/src/com/android/systemui/tuner/RadioListPreference.java @@ -17,21 +17,19 @@ package com.android.systemui.tuner; import android.app.AlertDialog.Builder; import android.app.Dialog; import android.app.DialogFragment; -import android.app.Fragment; import android.content.Context; import android.content.DialogInterface.OnClickListener; import android.os.Bundle; -import androidx.preference.PreferenceFragment; -import androidx.preference.Preference; -import androidx.preference.PreferenceScreen; import android.util.AttributeSet; -import android.util.Log; import android.view.View; import android.widget.Toolbar; +import androidx.preference.Preference; +import androidx.preference.PreferenceScreen; + import com.android.settingslib.Utils; -import com.android.systemui.fragments.FragmentHostManager; import com.android.systemui.R; +import com.android.systemui.fragments.FragmentHostManager; import java.util.Objects; diff --git a/packages/SystemUI/src/com/android/systemui/tuner/SelectablePreference.java b/packages/SystemUI/src/com/android/systemui/tuner/SelectablePreference.java index dded464901ac..0be793eefa18 100644 --- a/packages/SystemUI/src/com/android/systemui/tuner/SelectablePreference.java +++ b/packages/SystemUI/src/com/android/systemui/tuner/SelectablePreference.java @@ -16,9 +16,10 @@ package com.android.systemui.tuner; import android.content.Context; import android.graphics.drawable.Drawable; -import androidx.preference.CheckBoxPreference; import android.util.TypedValue; +import androidx.preference.CheckBoxPreference; + import com.android.systemui.statusbar.ScalingDrawableWrapper; public class SelectablePreference extends CheckBoxPreference { diff --git a/packages/SystemUI/src/com/android/systemui/tuner/ShortcutPicker.java b/packages/SystemUI/src/com/android/systemui/tuner/ShortcutPicker.java index 3c9d25d13350..11e1f278a271 100644 --- a/packages/SystemUI/src/com/android/systemui/tuner/ShortcutPicker.java +++ b/packages/SystemUI/src/com/android/systemui/tuner/ShortcutPicker.java @@ -20,12 +20,12 @@ import android.content.Context; import android.content.pm.LauncherActivityInfo; import android.content.pm.LauncherApps; import android.content.pm.PackageManager.NameNotFoundException; -import android.graphics.drawable.ColorDrawable; import android.os.Bundle; import android.os.Process; -import androidx.preference.PreferenceFragment; + import androidx.preference.Preference; import androidx.preference.PreferenceCategory; +import androidx.preference.PreferenceFragment; import androidx.preference.PreferenceScreen; import androidx.preference.PreferenceViewHolder; diff --git a/packages/SystemUI/src/com/android/systemui/tuner/StatusBarSwitch.java b/packages/SystemUI/src/com/android/systemui/tuner/StatusBarSwitch.java index 670fcc2a4d15..6f23e207c048 100644 --- a/packages/SystemUI/src/com/android/systemui/tuner/StatusBarSwitch.java +++ b/packages/SystemUI/src/com/android/systemui/tuner/StatusBarSwitch.java @@ -19,10 +19,11 @@ import android.app.ActivityManager; import android.content.ContentResolver; import android.content.Context; import android.provider.Settings; -import androidx.preference.SwitchPreference; import android.text.TextUtils; import android.util.AttributeSet; +import androidx.preference.SwitchPreference; + import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.systemui.Dependency; diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java index 5aa303530ae5..ecf1784e66c4 100644 --- a/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java +++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java @@ -22,12 +22,13 @@ import android.content.DialogInterface; import android.os.Build; import android.os.Bundle; import android.provider.Settings; -import androidx.preference.PreferenceFragment; -import androidx.preference.Preference; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; +import androidx.preference.Preference; +import androidx.preference.PreferenceFragment; + import com.android.internal.hardware.AmbientDisplayConfiguration; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerPreferenceFragment.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerPreferenceFragment.java index a22277eea05b..9cc8943aa6de 100644 --- a/packages/SystemUI/src/com/android/systemui/tuner/TunerPreferenceFragment.java +++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerPreferenceFragment.java @@ -15,9 +15,9 @@ package com.android.systemui.tuner; import android.app.DialogFragment; -import android.os.Bundle; -import androidx.preference.PreferenceFragment; + import androidx.preference.Preference; +import androidx.preference.PreferenceFragment; public abstract class TunerPreferenceFragment extends PreferenceFragment { diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerService.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerService.java index 3a9d1c7caeb8..3bccdab8c1ba 100644 --- a/packages/SystemUI/src/com/android/systemui/tuner/TunerService.java +++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerService.java @@ -26,8 +26,6 @@ import android.content.pm.PackageManager.NameNotFoundException; import android.os.UserHandle; import android.provider.Settings; -import static android.provider.Settings.System.SHOW_BATTERY_PERCENT; -import com.android.systemui.DemoMode; import com.android.systemui.Dependency; import com.android.systemui.R; import com.android.systemui.statusbar.phone.SystemUIDialog; diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerSwitch.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerSwitch.java index f53d51690712..2df9000ed665 100644 --- a/packages/SystemUI/src/com/android/systemui/tuner/TunerSwitch.java +++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerSwitch.java @@ -3,9 +3,10 @@ package com.android.systemui.tuner; import android.content.Context; import android.content.res.TypedArray; import android.provider.Settings; -import androidx.preference.SwitchPreference; import android.util.AttributeSet; +import androidx.preference.SwitchPreference; + import com.android.internal.logging.MetricsLogger; import com.android.systemui.Dependency; import com.android.systemui.R; diff --git a/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java b/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java index 2f8dfdc2991a..329d02959435 100644 --- a/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java +++ b/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java @@ -19,7 +19,6 @@ package com.android.systemui.usb; import android.annotation.NonNull; import android.app.Notification; import android.app.Notification.Action; -import android.app.NotificationChannel; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.BroadcastReceiver; diff --git a/packages/SystemUI/src/com/android/systemui/usb/UsbResolverActivity.java b/packages/SystemUI/src/com/android/systemui/usb/UsbResolverActivity.java index ec5030b8b028..fa3ff64e5e18 100644 --- a/packages/SystemUI/src/com/android/systemui/usb/UsbResolverActivity.java +++ b/packages/SystemUI/src/com/android/systemui/usb/UsbResolverActivity.java @@ -16,6 +16,8 @@ package com.android.systemui.usb; +import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE; + import android.content.ActivityNotFoundException; import android.content.Intent; import android.content.pm.ResolveInfo; @@ -38,8 +40,6 @@ import com.android.systemui.R; import java.util.ArrayList; import java.util.Iterator; -import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE; - /* Activity for choosing an application for a USB device or accessory */ public class UsbResolverActivity extends ResolverActivity { public static final String TAG = "UsbResolverActivity"; diff --git a/packages/SystemUI/src/com/android/systemui/util/NotificationChannels.java b/packages/SystemUI/src/com/android/systemui/util/NotificationChannels.java index c468fef293de..f35af90edc3c 100644 --- a/packages/SystemUI/src/com/android/systemui/util/NotificationChannels.java +++ b/packages/SystemUI/src/com/android/systemui/util/NotificationChannels.java @@ -16,7 +16,6 @@ package com.android.systemui.util; import android.app.NotificationChannel; import android.app.NotificationManager; - import android.content.Context; import android.content.pm.PackageManager; import android.media.AudioAttributes; diff --git a/packages/SystemUI/src/com/android/systemui/util/leak/DumpTruck.java b/packages/SystemUI/src/com/android/systemui/util/leak/DumpTruck.java index 9b15b00b9242..efd6e03b0d20 100644 --- a/packages/SystemUI/src/com/android/systemui/util/leak/DumpTruck.java +++ b/packages/SystemUI/src/com/android/systemui/util/leak/DumpTruck.java @@ -20,9 +20,10 @@ import android.content.Context; import android.content.Intent; import android.net.Uri; import android.os.Build; -import androidx.core.content.FileProvider; import android.util.Log; +import androidx.core.content.FileProvider; + import com.android.systemui.Dependency; import java.io.BufferedInputStream; diff --git a/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java b/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java index 3c88d29f1711..b2cc2694916e 100644 --- a/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java +++ b/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java @@ -37,7 +37,6 @@ import android.os.Message; import android.os.Process; import android.os.SystemProperties; import android.provider.Settings; -import androidx.annotation.VisibleForTesting; import android.service.quicksettings.Tile; import android.text.format.DateUtils; import android.util.Log; diff --git a/packages/SystemUI/src/com/android/systemui/util/leak/LeakDetector.java b/packages/SystemUI/src/com/android/systemui/util/leak/LeakDetector.java index 574fdb98caa7..c50e8f8a3596 100644 --- a/packages/SystemUI/src/com/android/systemui/util/leak/LeakDetector.java +++ b/packages/SystemUI/src/com/android/systemui/util/leak/LeakDetector.java @@ -24,7 +24,6 @@ import com.android.systemui.Dumpable; import java.io.FileDescriptor; import java.io.PrintWriter; -import java.io.Writer; import java.util.Collection; /** diff --git a/packages/SystemUI/src/com/android/systemui/util/leak/LeakReporter.java b/packages/SystemUI/src/com/android/systemui/util/leak/LeakReporter.java index 8ea5fd4ee93c..a47e99d1e84d 100644 --- a/packages/SystemUI/src/com/android/systemui/util/leak/LeakReporter.java +++ b/packages/SystemUI/src/com/android/systemui/util/leak/LeakReporter.java @@ -27,9 +27,10 @@ import android.net.Uri; import android.os.Debug; import android.os.SystemProperties; import android.os.UserHandle; -import androidx.core.content.FileProvider; import android.util.Log; +import androidx.core.content.FileProvider; + import com.google.android.collect.Lists; import java.io.File; diff --git a/packages/SystemUI/src/com/android/systemui/util/wakelock/SettableWakeLock.java b/packages/SystemUI/src/com/android/systemui/util/wakelock/SettableWakeLock.java index f2ed55f3dd32..13729dfbccda 100644 --- a/packages/SystemUI/src/com/android/systemui/util/wakelock/SettableWakeLock.java +++ b/packages/SystemUI/src/com/android/systemui/util/wakelock/SettableWakeLock.java @@ -16,9 +16,6 @@ package com.android.systemui.util.wakelock; -import android.os.Handler; -import android.os.PowerManager; - import com.android.internal.util.Preconditions; public class SettableWakeLock { diff --git a/packages/SystemUI/src/com/android/systemui/util/wakelock/WakeLock.java b/packages/SystemUI/src/com/android/systemui/util/wakelock/WakeLock.java index 16ce35c50ea2..b0f1b54b262e 100644 --- a/packages/SystemUI/src/com/android/systemui/util/wakelock/WakeLock.java +++ b/packages/SystemUI/src/com/android/systemui/util/wakelock/WakeLock.java @@ -18,6 +18,7 @@ package com.android.systemui.util.wakelock; import android.content.Context; import android.os.PowerManager; + import androidx.annotation.VisibleForTesting; /** WakeLock wrapper for testability */ @@ -71,4 +72,4 @@ public interface WakeLock { } }; } -}
\ No newline at end of file +} diff --git a/packages/SystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java index 9077b6b10ac7..9b616e00a72f 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java +++ b/packages/SystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java @@ -34,8 +34,8 @@ import android.content.ServiceConnection; import android.content.res.TypedArray; import android.content.res.XmlResourceParser; import android.graphics.Color; -import android.graphics.drawable.ColorDrawable; import android.graphics.PixelFormat; +import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.media.AudioAttributes; import android.media.AudioManager; @@ -65,17 +65,17 @@ import androidx.car.widget.ListItemProvider.ListProvider; import androidx.car.widget.PagedListView; import androidx.car.widget.SeekbarListItem; -import java.util.Iterator; +import com.android.systemui.R; +import com.android.systemui.plugins.VolumeDialog; + import org.xmlpull.v1.XmlPullParserException; import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; +import java.util.Iterator; import java.util.List; -import com.android.systemui.R; -import com.android.systemui.plugins.VolumeDialog; - /** * Car version of the volume dialog. * diff --git a/packages/SystemUI/src/com/android/systemui/volume/SafetyWarningDialog.java b/packages/SystemUI/src/com/android/systemui/volume/SafetyWarningDialog.java index c97095e1860b..361604c461b4 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/SafetyWarningDialog.java +++ b/packages/SystemUI/src/com/android/systemui/volume/SafetyWarningDialog.java @@ -27,7 +27,6 @@ import android.util.Log; import android.view.KeyEvent; import android.view.WindowManager; - import com.android.systemui.statusbar.phone.SystemUIDialog; abstract public class SafetyWarningDialog extends SystemUIDialog @@ -116,4 +115,4 @@ abstract public class SafetyWarningDialog extends SystemUIDialog } } }; -}
\ No newline at end of file +} diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeComponent.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeComponent.java index 36c673c7106b..42393375b45e 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/VolumeComponent.java +++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeComponent.java @@ -19,7 +19,6 @@ package com.android.systemui.volume; import android.content.res.Configuration; import com.android.systemui.DemoMode; -import com.android.systemui.statusbar.policy.ZenModeController; import java.io.FileDescriptor; import java.io.PrintWriter; diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java index 6f65b081afc4..e4f37decdf35 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java +++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java @@ -23,8 +23,6 @@ import android.util.Log; import com.android.systemui.R; import com.android.systemui.SystemUI; import com.android.systemui.qs.tiles.DndTile; -import com.android.systemui.statusbar.policy.ZenModeController; -import com.android.systemui.statusbar.policy.ZenModeControllerImpl; import java.io.FileDescriptor; import java.io.PrintWriter; diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java index 098fa62f4044..dcd59462a7f7 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java @@ -44,6 +44,7 @@ import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper.Snoo import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import org.junit.Before; +import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @@ -55,6 +56,7 @@ import org.mockito.stubbing.Answer; * Tests for {@link NotificationSwipeHelper}. */ @SmallTest +@Ignore @RunWith(AndroidJUnit4.class) @UiThreadTest public class NotificationSwipeHelperTest extends SysuiTestCase { diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LightBarTransitionsControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LightBarTransitionsControllerTest.java new file mode 100644 index 000000000000..0031c32a9846 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LightBarTransitionsControllerTest.java @@ -0,0 +1,75 @@ +/* + * Copyright (C) 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 + * + * 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 static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.reset; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +import android.support.test.filters.SmallTest; +import android.testing.AndroidTestingRunner; +import android.testing.TestableLooper; + +import com.android.systemui.SysuiTestCase; +import com.android.systemui.statusbar.CommandQueue; +import com.android.systemui.statusbar.phone.LightBarTransitionsController.DarkIntensityApplier; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +@SmallTest +@RunWith(AndroidTestingRunner.class) +@TestableLooper.RunWithLooper +public class LightBarTransitionsControllerTest extends SysuiTestCase { + + @Mock + private DarkIntensityApplier mApplier; + private LightBarTransitionsController mLightBarTransitionsController; + + @Before + public void setup() { + MockitoAnnotations.initMocks(this); + mContext.putComponent(CommandQueue.class, mock(CommandQueue.class)); + mLightBarTransitionsController = new LightBarTransitionsController(mContext, mApplier); + } + + @Test + public void setIconsDark_lightAndDark() { + mLightBarTransitionsController.setIconsDark(true /* dark */, false /* animate */); + verify(mApplier).applyDarkIntensity(eq(1f)); + + mLightBarTransitionsController.setIconsDark(false /* dark */, false /* animate */); + verify(mApplier).applyDarkIntensity(eq(0f)); + } + + @Test + public void onDozeAmountChanged_lightWhenDozing() { + mLightBarTransitionsController.onDozeAmountChanged(1f /* linear */, 1f /* eased */); + mLightBarTransitionsController.setIconsDark(true /* dark */, false /* animate */); + verify(mApplier, times(2)).applyDarkIntensity(eq(0f)); + + reset(mApplier); + mLightBarTransitionsController.setIconsDark(false /* dark */, false /* animate */); + verify(mApplier).applyDarkIntensity(eq(0f)); + } + +} 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 882f2615f443..d442de20db1e 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 @@ -593,6 +593,30 @@ public class StatusBarTest extends SysuiTestCase { verify(mStatusBarStateController).setState(eq(StatusBarState.FULLSCREEN_USER_SWITCHER)); } + @Test + public void testStartStopDozing() { + mStatusBar.setBarStateForTest(StatusBarState.KEYGUARD); + when(mStatusBarStateController.isKeyguardRequested()).thenReturn(true); + + mStatusBar.mDozeServiceHost.startDozing(); + verify(mStatusBarStateController).setIsDozing(eq(true)); + + mStatusBar.mDozeServiceHost.stopDozing(); + verify(mStatusBarStateController).setIsDozing(eq(false)); + } + + @Test + public void testOnStartedWakingUp_isNotDozing() { + mStatusBar.setBarStateForTest(StatusBarState.KEYGUARD); + when(mStatusBarStateController.isKeyguardRequested()).thenReturn(true); + + mStatusBar.mDozeServiceHost.startDozing(); + verify(mStatusBarStateController).setIsDozing(eq(true)); + + mStatusBar.mWakefulnessObserver.onStartedWakingUp(); + verify(mStatusBarStateController).setIsDozing(eq(false)); + } + static class TestableStatusBar extends StatusBar { public TestableStatusBar(StatusBarKeyguardViewManager man, UnlockMethodCache unlock, KeyguardIndicationController key, @@ -642,6 +666,7 @@ public class StatusBarTest extends SysuiTestCase { mLockscreenUserManager = notificationLockscreenUserManager; mCommandQueue = commandQueue; mPresenter = notificationPresenter; + mGestureWakeLock = mock(PowerManager.WakeLock.class); } private WakefulnessLifecycle createAwakeWakefulnessLifecycle() { diff --git a/proto/src/metrics_constants/metrics_constants.proto b/proto/src/metrics_constants/metrics_constants.proto index a947ea1e6b0f..8ae587296d45 100644 --- a/proto/src/metrics_constants/metrics_constants.proto +++ b/proto/src/metrics_constants/metrics_constants.proto @@ -6584,6 +6584,18 @@ message MetricsEvent { // OS: Q TOP_LEVEL_PRIVACY = 1587; + // OPEN: Settings > Sound & notification > Do Not Disturb > See all exceptions > + // Allow apps to override + // CATEGORY: SETTINGS + // OS: Q + NOTIFICATION_ZEN_MODE_OVERRIDING_APPS = 1588; + + // OPEN: Settings > Sound & notification > Do Not Disturb > See all exceptions > + // Allow apps to override > Choose app + // CATEGORY: SETTINGS + // OS: Q + NOTIFICATION_ZEN_MODE_OVERRIDING_APP = 1589; + // ---- End Q Constants, all Q constants go above this line ---- // Add new aosp constants above this line. diff --git a/proto/src/wifi.proto b/proto/src/wifi.proto index 033e99605d3f..11963d2a2c89 100644 --- a/proto/src/wifi.proto +++ b/proto/src/wifi.proto @@ -1674,4 +1674,20 @@ message WifiLinkLayerUsageStats { // Total time the wifi radio is scanning in ms over the logging duration. optional int64 radio_scan_time_ms = 5; + + // Total time the wifi radio spent doing nan scans in ms over the logging duration. + optional int64 radio_nan_scan_time_ms = 6; + + // Total time the wifi radio spent doing background scans in ms over the logging duration. + optional int64 radio_background_scan_time_ms = 7; + + // Total time the wifi radio spent doing roam scans in ms over the logging duration. + optional int64 radio_roam_scan_time_ms = 8; + + // Total time the wifi radio spent doing pno scans in ms over the logging duration. + optional int64 radio_pno_scan_time_ms = 9; + + // Total time the wifi radio spent doing hotspot 2.0 scans and GAS exchange + // in ms over the logging duration. + optional int64 radio_hs20_scan_time_ms = 10; }
\ No newline at end of file diff --git a/services/Android.bp b/services/Android.bp index bea51be321c9..33904383f84a 100644 --- a/services/Android.bp +++ b/services/Android.bp @@ -23,6 +23,7 @@ java_library { "services.companion", "services.coverage", "services.devicepolicy", + "services.intelligence", "services.midi", "services.net", "services.print", diff --git a/services/autofill/java/com/android/server/autofill/ui/FillUi.java b/services/autofill/java/com/android/server/autofill/ui/FillUi.java index d1fe970c0783..7a65a536335f 100644 --- a/services/autofill/java/com/android/server/autofill/ui/FillUi.java +++ b/services/autofill/java/com/android/server/autofill/ui/FillUi.java @@ -218,8 +218,8 @@ final class FillUi { ViewGroup container = decor.findViewById(R.id.autofill_dataset_picker); final View content; try { - response.getPresentation().setApplyTheme(mThemeId); - content = response.getPresentation().apply(mContext, decor, interceptionHandler); + content = response.getPresentation().applyWithTheme( + mContext, decor, interceptionHandler, mThemeId); container.addView(content); } catch (RuntimeException e) { callback.onCanceled(); @@ -259,8 +259,7 @@ final class FillUi { RemoteViews.OnClickHandler clickBlocker = null; if (headerPresentation != null) { clickBlocker = newClickBlocker(); - headerPresentation.setApplyTheme(mThemeId); - mHeader = headerPresentation.apply(mContext, null, clickBlocker); + mHeader = headerPresentation.applyWithTheme(mContext, null, clickBlocker, mThemeId); final LinearLayout headerContainer = decor.findViewById(R.id.autofill_dataset_header); if (sVerbose) Slog.v(TAG, "adding header"); @@ -277,8 +276,8 @@ final class FillUi { if (clickBlocker == null) { // already set for header clickBlocker = newClickBlocker(); } - footerPresentation.setApplyTheme(mThemeId); - mFooter = footerPresentation.apply(mContext, null, clickBlocker); + mFooter = footerPresentation.applyWithTheme( + mContext, null, clickBlocker, mThemeId); // Footer not supported on some platform e.g. TV if (sVerbose) Slog.v(TAG, "adding footer"); footerContainer.addView(mFooter); @@ -304,8 +303,8 @@ final class FillUi { final View view; try { if (sVerbose) Slog.v(TAG, "setting remote view for " + focusedViewId); - presentation.setApplyTheme(mThemeId); - view = presentation.apply(mContext, null, interceptionHandler); + view = presentation.applyWithTheme( + mContext, null, interceptionHandler, mThemeId); } catch (RuntimeException e) { Slog.e(TAG, "Error inflating remote views", e); continue; diff --git a/services/autofill/java/com/android/server/autofill/ui/SaveUi.java b/services/autofill/java/com/android/server/autofill/ui/SaveUi.java index 1e30c8afffa3..843aa741f2c3 100644 --- a/services/autofill/java/com/android/server/autofill/ui/SaveUi.java +++ b/services/autofill/java/com/android/server/autofill/ui/SaveUi.java @@ -339,8 +339,8 @@ final class SaveUi { try { // Create the remote view peer. - template.setApplyTheme(mThemeId); - final View customSubtitleView = template.apply(context, null, handler); + final View customSubtitleView = template.applyWithTheme( + context, null, handler, mThemeId); // Apply batch updates (if any). final ArrayList<Pair<InternalValidator, BatchUpdates>> updates = diff --git a/services/backup/java/com/android/server/backup/encryption/chunking/cdc/ContentDefinedChunker.java b/services/backup/java/com/android/server/backup/encryption/chunking/cdc/ContentDefinedChunker.java new file mode 100644 index 000000000000..18011f620b24 --- /dev/null +++ b/services/backup/java/com/android/server/backup/encryption/chunking/cdc/ContentDefinedChunker.java @@ -0,0 +1,136 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.backup.encryption.chunking.cdc; + +import static com.android.internal.util.Preconditions.checkArgument; + +import com.android.server.backup.encryption.chunking.Chunker; + +import java.io.IOException; +import java.io.InputStream; +import java.security.GeneralSecurityException; +import java.util.Arrays; + +/** Splits a stream of bytes into variable-sized chunks, using content-defined chunking. */ +public class ContentDefinedChunker implements Chunker { + private static final int WINDOW_SIZE = 31; + private static final byte DEFAULT_OUT_BYTE = (byte) 0; + + private final byte[] mChunkBuffer; + private final RabinFingerprint64 mRabinFingerprint64; + private final FingerprintMixer mFingerprintMixer; + private final BreakpointPredicate mBreakpointPredicate; + private final int mMinChunkSize; + private final int mMaxChunkSize; + + /** + * Constructor. + * + * @param minChunkSize The minimum size of a chunk. No chunk will be produced of a size smaller + * than this except possibly at the very end of the stream. + * @param maxChunkSize The maximum size of a chunk. No chunk will be produced of a larger size. + * @param rabinFingerprint64 Calculates fingerprints, with which to determine breakpoints. + * @param breakpointPredicate Given a Rabin fingerprint, returns whether this ought to be a + * breakpoint. + */ + public ContentDefinedChunker( + int minChunkSize, + int maxChunkSize, + RabinFingerprint64 rabinFingerprint64, + FingerprintMixer fingerprintMixer, + BreakpointPredicate breakpointPredicate) { + checkArgument( + minChunkSize >= WINDOW_SIZE, + "Minimum chunk size must be greater than window size."); + checkArgument( + maxChunkSize >= minChunkSize, + "Maximum chunk size cannot be smaller than minimum chunk size."); + mChunkBuffer = new byte[maxChunkSize]; + mRabinFingerprint64 = rabinFingerprint64; + mBreakpointPredicate = breakpointPredicate; + mFingerprintMixer = fingerprintMixer; + mMinChunkSize = minChunkSize; + mMaxChunkSize = maxChunkSize; + } + + /** + * Breaks the input stream into variable-sized chunks. + * + * @param inputStream The input bytes to break into chunks. + * @param chunkConsumer A function to process each chunk as it's generated. + * @throws IOException Thrown if there is an issue reading from the input stream. + * @throws GeneralSecurityException Thrown if the {@link ChunkConsumer} throws it. + */ + @Override + public void chunkify(InputStream inputStream, ChunkConsumer chunkConsumer) + throws IOException, GeneralSecurityException { + int chunkLength; + int initialReadLength = mMinChunkSize - WINDOW_SIZE; + + // Performance optimization - there is no reason to calculate fingerprints for windows + // ending before the minimum chunk size. + while ((chunkLength = + inputStream.read(mChunkBuffer, /*off=*/ 0, /*len=*/ initialReadLength)) + != -1) { + int b; + long fingerprint = 0L; + + while ((b = inputStream.read()) != -1) { + byte inByte = (byte) b; + byte outByte = getCurrentWindowStartByte(chunkLength); + mChunkBuffer[chunkLength++] = inByte; + + fingerprint = + mRabinFingerprint64.computeFingerprint64(inByte, outByte, fingerprint); + + if (chunkLength >= mMaxChunkSize + || (chunkLength >= mMinChunkSize + && mBreakpointPredicate.isBreakpoint( + mFingerprintMixer.mix(fingerprint)))) { + chunkConsumer.accept(Arrays.copyOf(mChunkBuffer, chunkLength)); + chunkLength = 0; + break; + } + } + + if (chunkLength > 0) { + chunkConsumer.accept(Arrays.copyOf(mChunkBuffer, chunkLength)); + } + } + } + + private byte getCurrentWindowStartByte(int chunkLength) { + if (chunkLength < mMinChunkSize) { + return DEFAULT_OUT_BYTE; + } else { + return mChunkBuffer[chunkLength - WINDOW_SIZE]; + } + } + + /** Whether the current fingerprint indicates the end of a chunk. */ + public interface BreakpointPredicate { + + /** + * Returns {@code true} if the fingerprint of the last {@code WINDOW_SIZE} bytes indicates + * the chunk ought to end at this position. + * + * @param fingerprint Fingerprint of the last {@code WINDOW_SIZE} bytes. + * @return Whether this ought to be a chunk breakpoint. + */ + boolean isBreakpoint(long fingerprint); + } +} diff --git a/services/backup/java/com/android/server/backup/encryption/chunking/cdc/FingerprintMixer.java b/services/backup/java/com/android/server/backup/encryption/chunking/cdc/FingerprintMixer.java new file mode 100644 index 000000000000..e9f30505c112 --- /dev/null +++ b/services/backup/java/com/android/server/backup/encryption/chunking/cdc/FingerprintMixer.java @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.backup.encryption.chunking.cdc; + +import static com.android.internal.util.Preconditions.checkArgument; + +import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; +import java.security.InvalidKeyException; + +import javax.crypto.SecretKey; + +/** + * Helper for mixing fingerprint with key material. + * + * <p>We do this as otherwise the Rabin fingerprint leaks information about the plaintext. i.e., if + * two users have the same file, it will be partitioned by Rabin in the same way, allowing us to + * infer that it is the same as another user's file. + * + * <p>By mixing the fingerprint with the user's secret key, the chunking method is different on a + * per key basis. Each application has its own {@link SecretKey}, so we cannot infer that a file is + * the same even across multiple applications owned by the same user, never mind across multiple + * users. + * + * <p>Instead of directly mixing the fingerprint with the user's secret, we first securely and + * deterministically derive a secondary chunking key. As Rabin is not a cryptographically secure + * hash, it might otherwise leak information about the user's secret. This prevents that from + * happening. + */ +public class FingerprintMixer { + public static final int SALT_LENGTH_BYTES = 256 / Byte.SIZE; + private static final String DERIVED_KEY_NAME = "RabinFingerprint64Mixer"; + + private final long mAddend; + private final long mMultiplicand; + + /** + * A new instance from a given secret key and salt. Salt must be the same across incremental + * backups, or a different chunking strategy will be used each time, defeating the dedup. + * + * @param secretKey The application-specific secret. + * @param salt The salt. + * @throws InvalidKeyException If the encoded form of {@code secretKey} is inaccessible. + */ + public FingerprintMixer(SecretKey secretKey, byte[] salt) throws InvalidKeyException { + checkArgument(salt.length == SALT_LENGTH_BYTES, "Requires a 256-bit salt."); + byte[] keyBytes = secretKey.getEncoded(); + if (keyBytes == null) { + throw new InvalidKeyException("SecretKey must support encoding for FingerprintMixer."); + } + byte[] derivedKey = + Hkdf.hkdf(keyBytes, salt, DERIVED_KEY_NAME.getBytes(StandardCharsets.UTF_8)); + ByteBuffer buffer = ByteBuffer.wrap(derivedKey); + mAddend = buffer.getLong(); + // Multiplicand must be odd - otherwise we lose some bits of the Rabin fingerprint when + // mixing + mMultiplicand = buffer.getLong() | 1; + } + + /** + * Mixes the fingerprint with the derived key material. This is performed by adding part of the + * derived key and multiplying by another part of the derived key (which is forced to be odd, so + * that the operation is reversible). + * + * @param fingerprint A 64-bit Rabin fingerprint. + * @return The mixed fingerprint. + */ + long mix(long fingerprint) { + return ((fingerprint + mAddend) * mMultiplicand); + } + + /** The addend part of the derived key. */ + long getAddend() { + return mAddend; + } + + /** The multiplicand part of the derived key. */ + long getMultiplicand() { + return mMultiplicand; + } +} diff --git a/services/backup/java/com/android/server/backup/encryption/chunking/cdc/Hkdf.java b/services/backup/java/com/android/server/backup/encryption/chunking/cdc/Hkdf.java new file mode 100644 index 000000000000..6f4f549ab2d7 --- /dev/null +++ b/services/backup/java/com/android/server/backup/encryption/chunking/cdc/Hkdf.java @@ -0,0 +1,115 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.backup.encryption.chunking.cdc; + +import static com.android.internal.util.Preconditions.checkNotNull; + +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; + +import javax.crypto.Mac; +import javax.crypto.spec.SecretKeySpec; + +/** + * Secure HKDF utils. Allows client to deterministically derive additional key material from a base + * secret. If the derived key material is compromised, this does not in of itself compromise the + * root secret. + * + * <p>TODO(b/116575321): After all code is ported, rename this class to HkdfUtils. + */ +public final class Hkdf { + private static final byte[] CONSTANT_01 = {0x01}; + private static final String HmacSHA256 = "HmacSHA256"; + private static final String AES = "AES"; + + /** + * Implements HKDF (RFC 5869) with the SHA-256 hash and a 256-bit output key length. + * + * <p>IMPORTANT: The use or edit of this method requires a security review. + * + * @param masterKey Master key from which to derive sub-keys. + * @param salt A randomly generated 256-bit byte string. + * @param data Arbitrary information that is bound to the derived key (i.e., used in its + * creation). + * @return Raw derived key bytes = HKDF-SHA256(masterKey, salt, data). + * @throws InvalidKeyException If the salt can not be used as a valid key. + */ + static byte[] hkdf(byte[] masterKey, byte[] salt, byte[] data) throws InvalidKeyException { + checkNotNull(masterKey, "HKDF requires master key to be set."); + checkNotNull(salt, "HKDF requires a salt."); + checkNotNull(data, "No data provided to HKDF."); + return hkdfSha256Expand(hkdfSha256Extract(masterKey, salt), data); + } + + private Hkdf() {} + + /** + * The HKDF (RFC 5869) extraction function, using the SHA-256 hash function. This function is + * used to pre-process the {@code inputKeyMaterial} and mix it with the {@code salt}, producing + * output suitable for use with HKDF expansion function (which produces the actual derived key). + * + * <p>IMPORTANT: The use or edit of this method requires a security review. + * + * @see #hkdfSha256Expand(byte[], byte[]) + * @return HMAC-SHA256(salt, inputKeyMaterial) (salt is the "key" for the HMAC) + * @throws InvalidKeyException If the salt can not be used as a valid key. + */ + private static byte[] hkdfSha256Extract(byte[] inputKeyMaterial, byte[] salt) + throws InvalidKeyException { + // Note that the SecretKey encoding format is defined to be RAW, so the encoded form should + // be consistent across implementations. + Mac sha256; + try { + sha256 = Mac.getInstance(HmacSHA256); + } catch (NoSuchAlgorithmException e) { + // This can not happen - HmacSHA256 is supported by the platform. + throw new AssertionError(e); + } + sha256.init(new SecretKeySpec(salt, AES)); + + return sha256.doFinal(inputKeyMaterial); + } + + /** + * Special case of HKDF (RFC 5869) expansion function, using the SHA-256 hash function and + * allowing for a maximum output length of 256 bits. + * + * <p>IMPORTANT: The use or edit of this method requires a security review. + * + * @param pseudoRandomKey Generated by {@link #hkdfSha256Extract(byte[], byte[])}. + * @param info Arbitrary information the derived key should be bound to. + * @return Raw derived key bytes = HMAC-SHA256(pseudoRandomKey, info | 0x01). + * @throws InvalidKeyException If the salt can not be used as a valid key. + */ + private static byte[] hkdfSha256Expand(byte[] pseudoRandomKey, byte[] info) + throws InvalidKeyException { + // Note that RFC 5869 computes number of blocks N = ceil(hash length / output length), but + // here we only deal with a 256 bit hash up to a 256 bit output, yielding N=1. + Mac sha256; + try { + sha256 = Mac.getInstance(HmacSHA256); + } catch (NoSuchAlgorithmException e) { + // This can not happen - HmacSHA256 is supported by the platform. + throw new AssertionError(e); + } + sha256.init(new SecretKeySpec(pseudoRandomKey, AES)); + + sha256.update(info); + sha256.update(CONSTANT_01); + return sha256.doFinal(); + } +} diff --git a/services/backup/java/com/android/server/backup/encryption/chunking/cdc/IsChunkBreakpoint.java b/services/backup/java/com/android/server/backup/encryption/chunking/cdc/IsChunkBreakpoint.java new file mode 100644 index 000000000000..e867e7c1b801 --- /dev/null +++ b/services/backup/java/com/android/server/backup/encryption/chunking/cdc/IsChunkBreakpoint.java @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.backup.encryption.chunking.cdc; + +import static com.android.internal.util.Preconditions.checkArgument; + +import com.android.server.backup.encryption.chunking.cdc.ContentDefinedChunker.BreakpointPredicate; + +/** + * Function to determine whether a 64-bit fingerprint ought to be a chunk breakpoint. + * + * <p>This works by checking whether there are at least n leading zeros in the fingerprint. n is + * calculated to on average cause a breakpoint after a given number of trials (provided in the + * constructor). This allows us to choose a number of trials that gives a desired average chunk + * size. This works because the fingerprint is pseudo-randomly distributed. + */ +public class IsChunkBreakpoint implements BreakpointPredicate { + private final int mLeadingZeros; + private final long mBitmask; + + /** + * A new instance that causes a breakpoint after a given number of trials on average. + * + * @param averageNumberOfTrialsUntilBreakpoint The number of trials after which on average to + * create a new chunk. If this is not a power of 2, some precision is sacrificed (i.e., on + * average, breaks will actually happen after the nearest power of 2 to the average number + * of trials passed in). + */ + public IsChunkBreakpoint(long averageNumberOfTrialsUntilBreakpoint) { + checkArgument( + averageNumberOfTrialsUntilBreakpoint >= 0, + "Average number of trials must be non-negative"); + + // Want n leading zeros after t trials. + // P(leading zeros = n) = 1/2^n + // Expected num trials to get n leading zeros = 1/2^-n + // t = 1/2^-n + // n = log2(t) + mLeadingZeros = (int) Math.round(log2(averageNumberOfTrialsUntilBreakpoint)); + mBitmask = ~(~0L >>> mLeadingZeros); + } + + /** + * Returns {@code true} if {@code fingerprint} indicates that there should be a chunk + * breakpoint. + */ + @Override + public boolean isBreakpoint(long fingerprint) { + return (fingerprint & mBitmask) == 0; + } + + /** Returns the number of leading zeros in the fingerprint that causes a breakpoint. */ + public int getLeadingZeros() { + return mLeadingZeros; + } + + /** + * Calculates log base 2 of x. Not the most efficient possible implementation, but it's simple, + * obviously correct, and is only invoked on object construction. + */ + private static double log2(double x) { + return Math.log(x) / Math.log(2); + } +} diff --git a/services/backup/java/com/android/server/backup/encryption/chunking/cdc/RabinFingerprint64.java b/services/backup/java/com/android/server/backup/encryption/chunking/cdc/RabinFingerprint64.java new file mode 100644 index 000000000000..1e14ffa5ad77 --- /dev/null +++ b/services/backup/java/com/android/server/backup/encryption/chunking/cdc/RabinFingerprint64.java @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.backup.encryption.chunking.cdc; + +/** Helper to calculate a 64-bit Rabin fingerprint over a 31-byte window. */ +public class RabinFingerprint64 { + private static final long DEFAULT_IRREDUCIBLE_POLYNOMIAL_64 = 0x000000000000001BL; + private static final int POLYNOMIAL_DEGREE = 64; + private static final int SLIDING_WINDOW_SIZE_BYTES = 31; + + private final long mPoly64; + // Auxiliary tables to speed up the computation of Rabin fingerprints. + private final long[] mTableFP64 = new long[256]; + private final long[] mTableOutByte = new long[256]; + + /** + * Constructs a new instance over the given irreducible 64-degree polynomial. It is up to the + * caller to determine that the polynomial is irreducible. If it is not the fingerprinting will + * not behave as expected. + * + * @param poly64 The polynomial. + */ + public RabinFingerprint64(long poly64) { + mPoly64 = poly64; + } + + /** Constructs a new instance using {@code x^64 + x^4 + x + 1} as the irreducible polynomial. */ + public RabinFingerprint64() { + this(DEFAULT_IRREDUCIBLE_POLYNOMIAL_64); + computeFingerprintTables64(); + computeFingerprintTables64Windowed(); + } + + /** + * Computes the fingerprint for the new sliding window given the fingerprint of the previous + * sliding window, the byte sliding in, and the byte sliding out. + * + * @param inChar The new char coming into the sliding window. + * @param outChar The left most char sliding out of the window. + * @param fingerPrint Fingerprint for previous window. + * @return New fingerprint for the new sliding window. + */ + public long computeFingerprint64(byte inChar, byte outChar, long fingerPrint) { + return (fingerPrint << 8) + ^ (inChar & 0xFF) + ^ mTableFP64[(int) (fingerPrint >>> 56)] + ^ mTableOutByte[outChar & 0xFF]; + } + + /** Compute auxiliary tables to speed up the fingerprint computation. */ + private void computeFingerprintTables64() { + long[] degreesRes64 = new long[POLYNOMIAL_DEGREE]; + degreesRes64[0] = mPoly64; + for (int i = 1; i < POLYNOMIAL_DEGREE; i++) { + if ((degreesRes64[i - 1] & (1L << 63)) == 0) { + degreesRes64[i] = degreesRes64[i - 1] << 1; + } else { + degreesRes64[i] = (degreesRes64[i - 1] << 1) ^ mPoly64; + } + } + for (int i = 0; i < 256; i++) { + int currIndex = i; + for (int j = 0; (currIndex > 0) && (j < 8); j++) { + if ((currIndex & 0x1) == 1) { + mTableFP64[i] ^= degreesRes64[j]; + } + currIndex >>>= 1; + } + } + } + + /** + * Compute auxiliary table {@code mTableOutByte} to facilitate the computing of fingerprints for + * sliding windows. This table is to take care of the effect on the fingerprint when the + * leftmost byte in the window slides out. + */ + private void computeFingerprintTables64Windowed() { + // Auxiliary array degsRes64[8] defined by: <code>degsRes64[i] = x^(8 * + // SLIDING_WINDOW_SIZE_BYTES + i) mod this.mPoly64.</code> + long[] degsRes64 = new long[8]; + degsRes64[0] = mPoly64; + for (int i = 65; i < 8 * (SLIDING_WINDOW_SIZE_BYTES + 1); i++) { + if ((degsRes64[(i - 1) % 8] & (1L << 63)) == 0) { + degsRes64[i % 8] = degsRes64[(i - 1) % 8] << 1; + } else { + degsRes64[i % 8] = (degsRes64[(i - 1) % 8] << 1) ^ mPoly64; + } + } + for (int i = 0; i < 256; i++) { + int currIndex = i; + for (int j = 0; (currIndex > 0) && (j < 8); j++) { + if ((currIndex & 0x1) == 1) { + mTableOutByte[i] ^= degsRes64[j]; + } + currIndex >>>= 1; + } + } + } +} diff --git a/services/backup/java/com/android/server/backup/keyvalue/KeyValueBackupTask.java b/services/backup/java/com/android/server/backup/keyvalue/KeyValueBackupTask.java index 3a5232a6b97a..d6f2a8775518 100644 --- a/services/backup/java/com/android/server/backup/keyvalue/KeyValueBackupTask.java +++ b/services/backup/java/com/android/server/backup/keyvalue/KeyValueBackupTask.java @@ -260,6 +260,10 @@ public class KeyValueBackupTask implements BackupRestoreTask, Runnable { @Nullable private ParcelFileDescriptor mSavedState; @Nullable private ParcelFileDescriptor mBackupData; @Nullable private ParcelFileDescriptor mNewState; + // Indicates whether there was any data to be backed up, i.e. the queue was not empty + // and at least one of the packages had data. Used to avoid updating current token for + // empty backups. + private boolean mHasDataToBackup; /** * This {@link ConditionVariable} is used to signal that the cancel operation has been @@ -332,6 +336,8 @@ public class KeyValueBackupTask implements BackupRestoreTask, Runnable { public void run() { Process.setThreadPriority(THREAD_PRIORITY); + mHasDataToBackup = false; + int status = BackupTransport.TRANSPORT_OK; try { startTask(); @@ -529,10 +535,10 @@ public class KeyValueBackupTask implements BackupRestoreTask, Runnable { String callerLogString = "KVBT.finishTask()"; - // If we succeeded and this is the first time we've done a backup, we can record the current - // backup dataset token. + // If the backup data was not empty, we succeeded and this is the first time + // we've done a backup, we can record the current backup dataset token. long currentToken = mBackupManagerService.getCurrentToken(); - if ((status == BackupTransport.TRANSPORT_OK) && (currentToken == 0)) { + if (mHasDataToBackup && (status == BackupTransport.TRANSPORT_OK) && (currentToken == 0)) { try { IBackupTransport transport = mTransportClient.connectOrThrow(callerLogString); mBackupManagerService.setCurrentToken(transport.getCurrentRestoreSet()); @@ -838,6 +844,8 @@ public class KeyValueBackupTask implements BackupRestoreTask, Runnable { return BackupTransport.TRANSPORT_OK; } + mHasDataToBackup = true; + int status; try (ParcelFileDescriptor backupData = ParcelFileDescriptor.open(backupDataFile, MODE_READ_ONLY)) { diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java index 5b3ab85e6107..923ac0063baf 100644 --- a/services/core/java/com/android/server/StorageManagerService.java +++ b/services/core/java/com/android/server/StorageManagerService.java @@ -186,8 +186,6 @@ class StorageManagerService extends IStorageManager.Stub private static final boolean ENABLE_ISOLATED_STORAGE = SystemProperties .getBoolean(StorageManager.PROP_ISOLATED_STORAGE, false); - private static final String SHARED_SANDBOX_ID_PREFIX = "shared:"; - public static class Lifecycle extends SystemService { private StorageManagerService mStorageManagerService; @@ -1235,6 +1233,9 @@ class StorageManagerService extends IStorageManager.Stub } else if (vol.type == VolumeInfo.TYPE_PRIVATE) { mHandler.obtainMessage(H_VOLUME_MOUNT, vol).sendToTarget(); + } else if (vol.type == VolumeInfo.TYPE_STUB) { + vol.mountUserId = mCurrentUserId; + mHandler.obtainMessage(H_VOLUME_MOUNT, vol).sendToTarget(); } else { Slog.d(TAG, "Skipping automatic mounting of " + vol); } @@ -1245,6 +1246,7 @@ class StorageManagerService extends IStorageManager.Stub case VolumeInfo.TYPE_PRIVATE: case VolumeInfo.TYPE_PUBLIC: case VolumeInfo.TYPE_EMULATED: + case VolumeInfo.TYPE_STUB: break; default: return false; @@ -1321,7 +1323,8 @@ class StorageManagerService extends IStorageManager.Stub } } - if (vol.type == VolumeInfo.TYPE_PUBLIC && vol.state == VolumeInfo.STATE_EJECTING) { + if ((vol.type == VolumeInfo.TYPE_PUBLIC || vol.type == VolumeInfo.TYPE_STUB) + && vol.state == VolumeInfo.STATE_EJECTING) { // TODO: this should eventually be handled by new ObbVolume state changes /* * Some OBBs might have been unmounted when this volume was @@ -1403,7 +1406,8 @@ class StorageManagerService extends IStorageManager.Stub } boolean isTypeRestricted = false; - if (vol.type == VolumeInfo.TYPE_PUBLIC || vol.type == VolumeInfo.TYPE_PRIVATE) { + if (vol.type == VolumeInfo.TYPE_PUBLIC || vol.type == VolumeInfo.TYPE_PRIVATE + || vol.type == VolumeInfo.TYPE_STUB) { isTypeRestricted = userManager .hasUserRestriction(UserManager.DISALLOW_MOUNT_PHYSICAL_MEDIA, Binder.getCallingUserHandle()); @@ -1495,7 +1499,8 @@ class StorageManagerService extends IStorageManager.Stub } private static String getSandboxId(String packageName, String sharedUserId) { - return sharedUserId == null ? packageName : SHARED_SANDBOX_ID_PREFIX + sharedUserId; + return sharedUserId == null + ? packageName : StorageManager.SHARED_SANDBOX_PREFIX + sharedUserId; } private void connect() { @@ -2834,6 +2839,7 @@ class StorageManagerService extends IStorageManager.Stub final VolumeInfo vol = mVolumes.valueAt(i); switch (vol.getType()) { case VolumeInfo.TYPE_PUBLIC: + case VolumeInfo.TYPE_STUB: case VolumeInfo.TYPE_EMULATED: break; default: diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java index 2d3912bda9cc..b5217ad7af19 100644 --- a/services/core/java/com/android/server/am/ActiveServices.java +++ b/services/core/java/com/android/server/am/ActiveServices.java @@ -17,40 +17,69 @@ package com.android.server.am; import static android.content.pm.PackageManager.PERMISSION_GRANTED; -import static com.android.server.am.ActivityManagerDebugConfig.*; -import java.io.FileDescriptor; -import java.io.IOException; -import java.io.PrintWriter; -import java.io.StringWriter; -import java.util.ArrayList; -import java.util.Comparator; -import java.util.Iterator; -import java.util.List; -import java.util.Set; -import java.util.function.Predicate; +import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKGROUND_CHECK; +import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOREGROUND_SERVICE; +import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU; +import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW; +import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE; +import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE_EXECUTING; +import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU; +import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE; +import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE_EXECUTING; +import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM; +import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME; +import android.app.ActivityManager; import android.app.ActivityManagerInternal; import android.app.ActivityThread; +import android.app.AppGlobals; import android.app.AppOpsManager; +import android.app.IApplicationThread; +import android.app.IServiceConnection; +import android.app.Notification; import android.app.NotificationManager; +import android.app.PendingIntent; +import android.app.Service; import android.app.ServiceStartArgs; +import android.content.ComponentName; import android.content.ComponentName.WithComponentName; +import android.content.Context; import android.content.IIntentSender; +import android.content.Intent; import android.content.IntentSender; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; import android.content.pm.ParceledListSlice; +import android.content.pm.ResolveInfo; +import android.content.pm.ServiceInfo; import android.net.Uri; +import android.os.Binder; import android.os.Build; import android.os.Bundle; import android.os.DeadObjectException; import android.os.Handler; +import android.os.IBinder; import android.os.Looper; +import android.os.Message; +import android.os.Process; import android.os.RemoteCallback; +import android.os.RemoteException; +import android.os.SystemClock; import android.os.SystemProperties; import android.os.TransactionTooLargeException; +import android.os.UserHandle; import android.provider.Settings; import android.util.ArrayMap; import android.util.ArraySet; +import android.util.EventLog; +import android.util.PrintWriterPrinter; +import android.util.Slog; +import android.util.SparseArray; +import android.util.StatsLog; +import android.util.TimeUtils; +import android.util.proto.ProtoOutputStream; +import android.webkit.WebViewZygote; import com.android.internal.R; import com.android.internal.app.procstats.ServiceState; @@ -64,39 +93,20 @@ import com.android.server.AppStateTracker; import com.android.server.LocalServices; import com.android.server.SystemService; import com.android.server.am.ActivityManagerService.ItemMatcher; - -import android.app.ActivityManager; -import android.app.AppGlobals; -import android.app.IApplicationThread; -import android.app.IServiceConnection; -import android.app.Notification; -import android.app.PendingIntent; -import android.app.Service; -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; -import android.content.pm.ServiceInfo; -import android.os.Binder; -import android.os.IBinder; -import android.os.Message; -import android.os.Process; -import android.os.RemoteException; -import android.os.SystemClock; -import android.os.UserHandle; -import android.util.EventLog; -import android.util.PrintWriterPrinter; -import android.util.Slog; -import android.util.StatsLog; -import android.util.SparseArray; -import android.util.TimeUtils; -import android.util.proto.ProtoOutputStream; -import android.webkit.WebViewZygote; import com.android.server.uri.NeededUriGrants; import com.android.server.wm.ActivityServiceConnectionsHolder; +import java.io.FileDescriptor; +import java.io.IOException; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.Iterator; +import java.util.List; +import java.util.Set; +import java.util.function.Predicate; + public final class ActiveServices { private static final String TAG = TAG_WITH_CLASS_NAME ? "ActiveServices" : TAG_AM; private static final String TAG_MU = TAG + POSTFIX_MU; @@ -182,10 +192,10 @@ public final class ActiveServices { public void stopForegroundServicesForUidPackage(final int uid, final String packageName) { synchronized (mAm) { final ServiceMap smap = getServiceMapLocked(UserHandle.getUserId(uid)); - final int N = smap.mServicesByName.size(); + final int N = smap.mServicesByInstanceName.size(); final ArrayList<ServiceRecord> toStop = new ArrayList<>(N); for (int i = 0; i < N; i++) { - final ServiceRecord r = smap.mServicesByName.valueAt(i); + final ServiceRecord r = smap.mServicesByInstanceName.valueAt(i); if (uid == r.serviceInfo.applicationInfo.uid || packageName.equals(r.serviceInfo.packageName)) { if (r.isForeground) { @@ -236,7 +246,7 @@ public final class ActiveServices { */ final class ServiceMap extends Handler { final int mUserId; - final ArrayMap<ComponentName, ServiceRecord> mServicesByName = new ArrayMap<>(); + final ArrayMap<ComponentName, ServiceRecord> mServicesByInstanceName = new ArrayMap<>(); final ArrayMap<Intent.FilterComparison, ServiceRecord> mServicesByIntent = new ArrayMap<>(); final ArrayList<ServiceRecord> mDelayedStartList = new ArrayList<>(); @@ -358,7 +368,7 @@ public final class ActiveServices { // TODO: Deal with global services if (DEBUG_MU) Slog.v(TAG_MU, "getServiceByNameLocked(" + name + "), callingUser = " + callingUser); - return getServiceMapLocked(callingUser).mServicesByName.get(name); + return getServiceMapLocked(callingUser).mServicesByInstanceName.get(name); } boolean hasBackgroundServicesLocked(int callingUser) { @@ -376,7 +386,7 @@ public final class ActiveServices { } ArrayMap<ComponentName, ServiceRecord> getServicesLocked(int callingUser) { - return getServiceMapLocked(callingUser).mServicesByName; + return getServiceMapLocked(callingUser).mServicesByInstanceName; } private boolean appRestrictedAnyInBackground(final int uid, final String packageName) { @@ -406,7 +416,7 @@ public final class ActiveServices { } ServiceLookupResult res = - retrieveServiceLocked(service, resolvedType, callingPackage, + retrieveServiceLocked(service, null, resolvedType, callingPackage, callingPid, callingUid, userId, true, callerFg, false, false); if (res == null) { return null; @@ -434,7 +444,7 @@ public final class ActiveServices { boolean forcedStandby = false; if (bgLaunch && appRestrictedAnyInBackground(r.appInfo.uid, r.packageName)) { if (DEBUG_FOREGROUND_SERVICE) { - Slog.d(TAG, "Forcing bg-only service start only for " + r.shortName + Slog.d(TAG, "Forcing bg-only service start only for " + r.shortInstanceName + " : bgLaunch=" + bgLaunch + " callerFg=" + callerFg); } forcedStandby = true; @@ -454,7 +464,7 @@ public final class ActiveServices { // Not allowed, fall back to normal start service, failing siliently // if background check restricts that. Slog.w(TAG, "startForegroundService not allowed due to app op: service " - + service + " to " + r.name.flattenToShortString() + + service + " to " + r.shortInstanceName + " from pid=" + callingPid + " uid=" + callingUid + " pkg=" + callingPackage); fgRequired = false; @@ -474,7 +484,7 @@ public final class ActiveServices { r.appInfo.targetSdkVersion, callingPid, false, false, forcedStandby); if (allowed != ActivityManager.APP_START_MODE_NORMAL) { Slog.w(TAG, "Background start not allowed: service " - + service + " to " + r.name.flattenToShortString() + + service + " to " + r.shortInstanceName + " from pid=" + callingPid + " uid=" + callingUid + " pkg=" + callingPackage + " startFg?=" + fgRequired); if (allowed == ActivityManager.APP_START_MODE_DELAYED || forceSilentAbort) { @@ -731,7 +741,7 @@ public final class ActiveServices { } // If this service is active, make sure it is stopped. - ServiceLookupResult r = retrieveServiceLocked(service, resolvedType, null, + ServiceLookupResult r = retrieveServiceLocked(service, null, resolvedType, null, Binder.getCallingPid(), Binder.getCallingUid(), userId, false, false, false, false); if (r != null) { if (r.record != null) { @@ -755,8 +765,8 @@ public final class ActiveServices { ServiceMap services = mServiceMap.get(UserHandle.getUserId(uid)); ArrayList<ServiceRecord> stopping = null; if (services != null) { - for (int i=services.mServicesByName.size()-1; i>=0; i--) { - ServiceRecord service = services.mServicesByName.valueAt(i); + for (int i = services.mServicesByInstanceName.size() - 1; i >= 0; i--) { + ServiceRecord service = services.mServicesByInstanceName.valueAt(i); if (service.appInfo.uid == uid && service.startRequested) { if (mAm.getAppStartModeLocked(service.appInfo.uid, service.packageName, service.appInfo.targetSdkVersion, -1, false, false, false) @@ -764,7 +774,7 @@ public final class ActiveServices { if (stopping == null) { stopping = new ArrayList<>(); } - String compName = service.name.flattenToShortString(); + String compName = service.shortInstanceName; EventLogTags.writeAmStopIdleService(service.appInfo.uid, compName); StringBuilder sb = new StringBuilder(64); sb.append("Stopping service due to app idle: "); @@ -791,7 +801,7 @@ public final class ActiveServices { } IBinder peekServiceLocked(Intent service, String resolvedType, String callingPackage) { - ServiceLookupResult r = retrieveServiceLocked(service, resolvedType, callingPackage, + ServiceLookupResult r = retrieveServiceLocked(service, null, resolvedType, callingPackage, Binder.getCallingPid(), Binder.getCallingUid(), UserHandle.getCallingUserId(), false, false, false, false); @@ -1218,7 +1228,7 @@ public final class ActiveServices { case AppOpsManager.MODE_IGNORED: // Whoops, silently ignore this. Slog.w(TAG, "Service.startForeground() not allowed due to app op: service " - + r.shortName); + + r.shortInstanceName); ignoreForeground = true; break; default: @@ -1229,7 +1239,7 @@ public final class ActiveServices { appRestrictedAnyInBackground(r.appInfo.uid, r.packageName)) { Slog.w(TAG, "Service.startForeground() not allowed due to bg restriction: service " - + r.shortName); + + r.shortInstanceName); // Back off of any foreground expectations around this service, since we've // just turned down its fg request. updateServiceForegroundLocked(r.app, false); @@ -1283,8 +1293,9 @@ public final class ActiveServices { AppOpsManager.OP_START_FOREGROUND, r.appInfo.uid, r.packageName, true); StatsLog.write(StatsLog.FOREGROUND_SERVICE_STATE_CHANGED, - r.appInfo.uid, r.shortName, + r.appInfo.uid, r.shortInstanceName, StatsLog.FOREGROUND_SERVICE_STATE_CHANGED__STATE__ENTER); + mAm.updateForegroundServiceUsageStats(r.name, r.userId, true); } r.postNotification(); if (r.app != null) { @@ -1332,8 +1343,9 @@ public final class ActiveServices { AppOpsManager.getToken(mAm.mAppOpsService), AppOpsManager.OP_START_FOREGROUND, r.appInfo.uid, r.packageName); StatsLog.write(StatsLog.FOREGROUND_SERVICE_STATE_CHANGED, - r.appInfo.uid, r.shortName, + r.appInfo.uid, r.shortInstanceName, StatsLog.FOREGROUND_SERVICE_STATE_CHANGED__STATE__EXIT); + mAm.updateForegroundServiceUsageStats(r.name, r.userId, false); if (r.app != null) { mAm.updateLruProcessLocked(r.app, false, null); updateServiceForegroundLocked(r.app, true); @@ -1361,8 +1373,8 @@ public final class ActiveServices { // due the other service. ServiceMap sm = getServiceMapLocked(r.userId); if (sm != null) { - for (int i = sm.mServicesByName.size()-1; i >= 0; i--) { - ServiceRecord other = sm.mServicesByName.valueAt(i); + for (int i = sm.mServicesByInstanceName.size() - 1; i >= 0; i--) { + ServiceRecord other = sm.mServicesByInstanceName.valueAt(i); if (other != r && other.foregroundId == r.foregroundId && other.packageName.equals(r.packageName)) { // Found one! Abort the cancel. @@ -1454,7 +1466,8 @@ public final class ActiveServices { int bindServiceLocked(IApplicationThread caller, IBinder token, Intent service, String resolvedType, final IServiceConnection connection, int flags, - String callingPackage, final int userId) throws TransactionTooLargeException { + String instanceName, String callingPackage, final int userId) + throws TransactionTooLargeException { if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "bindService: " + service + " type=" + resolvedType + " conn=" + connection.asBinder() + " flags=0x" + Integer.toHexString(flags)); @@ -1518,8 +1531,9 @@ public final class ActiveServices { final boolean allowInstant = (flags & Context.BIND_ALLOW_INSTANT) != 0; ServiceLookupResult res = - retrieveServiceLocked(service, resolvedType, callingPackage, Binder.getCallingPid(), - Binder.getCallingUid(), userId, true, callerFg, isBindExternal, allowInstant); + retrieveServiceLocked(service, instanceName, resolvedType, callingPackage, + Binder.getCallingPid(), Binder.getCallingUid(), userId, true, + callerFg, isBindExternal, allowInstant); if (res == null) { return 0; } @@ -1625,7 +1639,7 @@ public final class ActiveServices { mAm.startAssociationLocked(callerApp.uid, callerApp.processName, callerApp.getCurProcState(), s.appInfo.uid, s.appInfo.longVersionCode, - s.name, s.processName); + s.instanceName, s.processName); // Once the apps have become associated, if one of them is caller is ephemeral // the target app should now be able to see the calling app mAm.grantEphemeralAccessLocked(callerApp.userId, service, @@ -1697,7 +1711,7 @@ public final class ActiveServices { try { c.conn.connected(s.name, b.intent.binder, false); } catch (Exception e) { - Slog.w(TAG, "Failure sending service " + s.shortName + Slog.w(TAG, "Failure sending service " + s.shortInstanceName + " to connection " + c.conn.asBinder() + " (in " + c.binding.client.processName + ")", e); } @@ -1751,9 +1765,9 @@ public final class ActiveServices { try { c.conn.connected(r.name, service, false); } catch (Exception e) { - Slog.w(TAG, "Failure sending service " + r.name + - " to connection " + c.conn.asBinder() + - " (in " + c.binding.client.processName + ")", e); + Slog.w(TAG, "Failure sending service " + r.shortInstanceName + + " to connection " + c.conn.asBinder() + + " (in " + c.binding.client.processName + ")", e); } } } @@ -1886,7 +1900,8 @@ public final class ActiveServices { } private ServiceLookupResult retrieveServiceLocked(Intent service, - String resolvedType, String callingPackage, int callingPid, int callingUid, int userId, + String instanceName, String resolvedType, String callingPackage, + int callingPid, int callingUid, int userId, boolean createIfNeeded, boolean callingFromFg, boolean isBindExternal, boolean allowInstant) { ServiceRecord r = null; @@ -1897,12 +1912,23 @@ public final class ActiveServices { ActivityManagerInternal.ALLOW_NON_FULL_IN_PROFILE, "service", null); ServiceMap smap = getServiceMapLocked(userId); - final ComponentName comp = service.getComponent(); + final ComponentName comp; + if (instanceName == null) { + comp = service.getComponent(); + } else { + final ComponentName realComp = service.getComponent(); + if (realComp == null) { + throw new IllegalArgumentException("Can't use custom instance name '" + instanceName + + "' without expicit component in Intent"); + } + comp = new ComponentName(realComp.getPackageName(), + realComp.getClassName() + ":" + instanceName); + } if (comp != null) { - r = smap.mServicesByName.get(comp); + r = smap.mServicesByInstanceName.get(comp); if (DEBUG_SERVICE && r != null) Slog.v(TAG_SERVICE, "Retrieved by component: " + r); } - if (r == null && !isBindExternal) { + if (r == null && !isBindExternal && instanceName == null) { Intent.FilterComparison filter = new Intent.FilterComparison(service); r = smap.mServicesByIntent.get(filter); if (DEBUG_SERVICE && r != null) Slog.v(TAG_SERVICE, "Retrieved by intent: " + r); @@ -1924,24 +1950,29 @@ public final class ActiveServices { // TODO: come back and remove this assumption to triage all services ResolveInfo rInfo = mAm.getPackageManagerInternalLocked().resolveService(service, resolvedType, flags, userId, callingUid); - ServiceInfo sInfo = - rInfo != null ? rInfo.serviceInfo : null; + ServiceInfo sInfo = rInfo != null ? rInfo.serviceInfo : null; if (sInfo == null) { Slog.w(TAG_SERVICE, "Unable to start service " + service + " U=" + userId + ": not found"); return null; } - ComponentName name = new ComponentName( + if (instanceName != null + && (sInfo.flags & ServiceInfo.FLAG_ISOLATED_PROCESS) == 0) { + throw new IllegalArgumentException("Can't use instance name '" + instanceName + + "' with non-isolated service '" + sInfo.name + "'"); + } + ComponentName className = new ComponentName( sInfo.applicationInfo.packageName, sInfo.name); + ComponentName name = comp != null ? comp : className; if ((sInfo.flags & ServiceInfo.FLAG_EXTERNAL_SERVICE) != 0) { if (isBindExternal) { if (!sInfo.exported) { - throw new SecurityException("BIND_EXTERNAL_SERVICE failed, " + name + - " is not exported"); + throw new SecurityException("BIND_EXTERNAL_SERVICE failed, " + + className + " is not exported"); } if ((sInfo.flags & ServiceInfo.FLAG_ISOLATED_PROCESS) == 0) { - throw new SecurityException("BIND_EXTERNAL_SERVICE failed, " + name + - " is not an isolatedProcess"); + throw new SecurityException("BIND_EXTERNAL_SERVICE failed, " + + className + " is not an isolatedProcess"); } // Run the service under the calling package's application. ApplicationInfo aInfo = AppGlobals.getPackageManager().getApplicationInfo( @@ -1955,6 +1986,9 @@ public final class ActiveServices { sInfo.applicationInfo.packageName = aInfo.packageName; sInfo.applicationInfo.uid = aInfo.uid; name = new ComponentName(aInfo.packageName, name.getClassName()); + className = new ComponentName(aInfo.packageName, + instanceName == null ? className.getClassName() + : (className.getClassName() + ":" + instanceName)); service.setComponent(name); } else { throw new SecurityException("BIND_EXTERNAL_SERVICE required for " + @@ -1974,7 +2008,7 @@ public final class ActiveServices { sInfo = new ServiceInfo(sInfo); sInfo.applicationInfo = mAm.getAppInfoForUser(sInfo.applicationInfo, userId); } - r = smap.mServicesByName.get(name); + r = smap.mServicesByInstanceName.get(name); if (DEBUG_SERVICE && r != null) Slog.v(TAG_SERVICE, "Retrieved via pm by intent: " + r); if (r == null && createIfNeeded) { @@ -1985,19 +2019,20 @@ public final class ActiveServices { final BatteryStatsImpl stats = mAm.mBatteryStatsService.getActiveStatistics(); synchronized (stats) { ss = stats.getServiceStatsLocked( - sInfo.applicationInfo.uid, sInfo.packageName, - sInfo.name); + sInfo.applicationInfo.uid, name.getPackageName(), + name.getClassName()); } - r = new ServiceRecord(mAm, ss, name, filter, sInfo, callingFromFg, res); + r = new ServiceRecord(mAm, ss, className, name, filter, sInfo, callingFromFg, + res); res.setService(r); - smap.mServicesByName.put(name, r); + smap.mServicesByInstanceName.put(name, r); smap.mServicesByIntent.put(filter, r); // Make sure this component isn't in the pending list. for (int i=mPendingServices.size()-1; i>=0; i--) { final ServiceRecord pr = mPendingServices.get(i); if (pr.serviceInfo.applicationInfo.uid == sInfo.applicationInfo.uid - && pr.name.equals(name)) { + && pr.instanceName.equals(name)) { if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Remove pending: " + pr); mPendingServices.remove(i); } @@ -2012,14 +2047,14 @@ public final class ActiveServices { if (mAm.checkComponentPermission(r.permission, callingPid, callingUid, r.appInfo.uid, r.exported) != PERMISSION_GRANTED) { if (!r.exported) { - Slog.w(TAG, "Permission Denial: Accessing service " + r.name + Slog.w(TAG, "Permission Denial: Accessing service " + r.shortInstanceName + " from pid=" + callingPid + ", uid=" + callingUid + " that is not exported from uid " + r.appInfo.uid); return new ServiceLookupResult(null, "not exported from uid " + r.appInfo.uid); } - Slog.w(TAG, "Permission Denial: Accessing service " + r.name + Slog.w(TAG, "Permission Denial: Accessing service " + r.shortInstanceName + " from pid=" + callingPid + ", uid=" + callingUid + " requires " + r.permission); @@ -2028,7 +2063,7 @@ public final class ActiveServices { final int opCode = AppOpsManager.permissionToOpCode(r.permission); if (opCode != AppOpsManager.OP_NONE && mAm.mAppOpsService.noteOperation( opCode, callingUid, callingPackage) != AppOpsManager.MODE_ALLOWED) { - Slog.w(TAG, "Appop Denial: Accessing service " + r.name + Slog.w(TAG, "Appop Denial: Accessing service " + r.shortInstanceName + " from pid=" + callingPid + ", uid=" + callingUid + " requires appop " + AppOpsManager.opToName(opCode)); @@ -2049,7 +2084,7 @@ public final class ActiveServices { if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, ">>> EXECUTING " + why + " of " + r + " in app " + r.app); else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG_SERVICE_EXECUTING, ">>> EXECUTING " - + why + " of " + r.shortName); + + why + " of " + r.shortInstanceName); // For b/34123235: Services within the system server won't start until SystemServer // does Looper.loop(), so we shouldn't try to start/bind to them too early in the boot @@ -2134,14 +2169,14 @@ public final class ActiveServices { boolean canceled = false; if (mAm.mAtmInternal.isShuttingDown()) { - Slog.w(TAG, "Not scheduling restart of crashed service " + r.shortName + Slog.w(TAG, "Not scheduling restart of crashed service " + r.shortInstanceName + " - system is shutting down"); return false; } ServiceMap smap = getServiceMapLocked(r.userId); - if (smap.mServicesByName.get(r.name) != r) { - ServiceRecord cur = smap.mServicesByName.get(r.name); + if (smap.mServicesByInstanceName.get(r.instanceName) != r) { + ServiceRecord cur = smap.mServicesByInstanceName.get(r.instanceName); Slog.wtf(TAG, "Attempting to schedule restart of " + r + " when found in map: " + cur); return false; @@ -2172,7 +2207,7 @@ public final class ActiveServices { if (resetTime < dur) resetTime = dur; } else { Slog.w(TAG, "Canceling start item " + si.intent + " in service " - + r.name); + + r.shortInstanceName); canceled = true; } } @@ -2244,9 +2279,9 @@ public final class ActiveServices { mAm.mHandler.postAtTime(r.restarter, r.nextRestartTime); r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay; Slog.w(TAG, "Scheduling restart of crashed service " - + r.shortName + " in " + r.restartDelay + "ms"); + + r.shortInstanceName + " in " + r.restartDelay + "ms"); EventLog.writeEvent(EventLogTags.AM_SCHEDULE_SERVICE_RESTART, - r.userId, r.shortName, r.restartDelay); + r.userId, r.shortInstanceName, r.restartDelay); return canceled; } @@ -2381,7 +2416,7 @@ public final class ActiveServices { } catch (TransactionTooLargeException e) { throw e; } catch (RemoteException e) { - Slog.w(TAG, "Exception when starting service " + r.shortName, e); + Slog.w(TAG, "Exception when starting service " + r.shortInstanceName, e); } // If a dead object exception was thrown -- fall through to @@ -2405,7 +2440,7 @@ public final class ActiveServices { // to be executed when the app comes up. if (app == null && !permissionsReviewRequired) { if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags, - hostingType, r.name, false, isolated, false)) == null) { + hostingType, r.instanceName, false, isolated, false)) == null) { String msg = "Unable to launch app " + r.appInfo.packageName + "/" + r.appInfo.uid + " for service " @@ -2476,8 +2511,9 @@ public final class ActiveServices { try { if (LOG_SERVICE_START_STOP) { String nameTerm; - int lastPeriod = r.shortName.lastIndexOf('.'); - nameTerm = lastPeriod >= 0 ? r.shortName.substring(lastPeriod) : r.shortName; + int lastPeriod = r.shortInstanceName.lastIndexOf('.'); + nameTerm = lastPeriod >= 0 ? r.shortInstanceName.substring(lastPeriod) + : r.shortInstanceName; EventLogTags.writeAmCreateService( r.userId, System.identityHashCode(r), nameTerm, r.app.uid, r.app.pid); } @@ -2693,9 +2729,9 @@ public final class ActiveServices { try { cr.conn.connected(r.name, null, true); } catch (Exception e) { - Slog.w(TAG, "Failure disconnecting service " + r.name + - " to connection " + c.get(i).conn.asBinder() + - " (in " + c.get(i).binding.client.processName + ")", e); + Slog.w(TAG, "Failure disconnecting service " + r.shortInstanceName + + " to connection " + c.get(i).conn.asBinder() + + " (in " + c.get(i).binding.client.processName + ")", e); } } } @@ -2716,7 +2752,7 @@ public final class ActiveServices { ibr.intent.getIntent()); } catch (Exception e) { Slog.w(TAG, "Exception when unbinding service " - + r.shortName, e); + + r.shortInstanceName, e); serviceProcessGoneLocked(r); } } @@ -2761,14 +2797,14 @@ public final class ActiveServices { } final ServiceMap smap = getServiceMapLocked(r.userId); - ServiceRecord found = smap.mServicesByName.remove(r.name); + ServiceRecord found = smap.mServicesByInstanceName.remove(r.instanceName); // Note when this method is called by bringUpServiceLocked(), the service is not found - // in mServicesByName and found will be null. + // in mServicesByInstanceName and found will be null. if (found != null && found != r) { // This is not actually the service we think is running... this should not happen, // but if it does, fail hard. - smap.mServicesByName.put(r.name, found); + smap.mServicesByInstanceName.put(r.instanceName, found); throw new IllegalStateException("Bringing down " + r + " but actually running " + found); } @@ -2795,8 +2831,9 @@ public final class ActiveServices { mAm.mAppOpsService.finishOperation( AppOpsManager.getToken(mAm.mAppOpsService), AppOpsManager.OP_START_FOREGROUND, r.appInfo.uid, r.packageName); - StatsLog.write(StatsLog.FOREGROUND_SERVICE_STATE_CHANGED, r.appInfo.uid, r.shortName, - StatsLog.FOREGROUND_SERVICE_STATE_CHANGED__STATE__EXIT); + StatsLog.write(StatsLog.FOREGROUND_SERVICE_STATE_CHANGED, r.appInfo.uid, + r.shortInstanceName, StatsLog.FOREGROUND_SERVICE_STATE_CHANGED__STATE__EXIT); + mAm.updateForegroundServiceUsageStats(r.name, r.userId, false); } r.isForeground = false; @@ -2825,7 +2862,7 @@ public final class ActiveServices { r.app.thread.scheduleStopService(r); } catch (Exception e) { Slog.w(TAG, "Exception when destroying service " - + r.shortName, e); + + r.shortInstanceName, e); serviceProcessGoneLocked(r); } } else { @@ -2902,7 +2939,7 @@ public final class ActiveServices { } mAm.stopAssociationLocked(b.client.uid, b.client.processName, s.appInfo.uid, - s.appInfo.longVersionCode, s.name, s.processName); + s.appInfo.longVersionCode, s.instanceName, s.processName); if (b.connections.size() == 0) { b.intent.apps.remove(b.client); @@ -2929,7 +2966,7 @@ public final class ActiveServices { b.intent.doRebind = false; s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent()); } catch (Exception e) { - Slog.w(TAG, "Exception when unbinding service " + s.shortName, e); + Slog.w(TAG, "Exception when unbinding service " + s.shortInstanceName, e); serviceProcessGoneLocked(s); } } @@ -3048,17 +3085,17 @@ public final class ActiveServices { + ": nesting=" + r.executeNesting + ", inDestroying=" + inDestroying + ", app=" + r.app); else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG_SERVICE_EXECUTING, - "<<< DONE EXECUTING " + r.shortName); + "<<< DONE EXECUTING " + r.shortInstanceName); r.executeNesting--; if (r.executeNesting <= 0) { if (r.app != null) { if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, - "Nesting at 0 of " + r.shortName); + "Nesting at 0 of " + r.shortInstanceName); r.app.execServicesFg = false; r.app.executingServices.remove(r); if (r.app.executingServices.size() == 0) { if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG_SERVICE_EXECUTING, - "No more executingServices of " + r.shortName); + "No more executingServices of " + r.shortInstanceName); mAm.mHandler.removeMessages(ActivityManagerService.SERVICE_TIMEOUT_MSG, r.app); } else if (r.executeFg) { // Need to re-evaluate whether the app still needs to be in the foreground. @@ -3128,7 +3165,7 @@ public final class ActiveServices { } } catch (RemoteException e) { Slog.w(TAG, "Exception in new application when starting service " - + sr.shortName, e); + + sr.shortInstanceName, e); throw e; } } @@ -3214,7 +3251,8 @@ public final class ActiveServices { if (userId == UserHandle.USER_ALL) { for (int i = mServiceMap.size() - 1; i >= 0; i--) { didSomething |= collectPackageServicesLocked(packageName, filterByClasses, - evenPersistent, doit, killProcess, mServiceMap.valueAt(i).mServicesByName); + evenPersistent, doit, killProcess, + mServiceMap.valueAt(i).mServicesByInstanceName); if (!doit && didSomething) { return true; } @@ -3225,7 +3263,7 @@ public final class ActiveServices { } else { ServiceMap smap = mServiceMap.get(userId); if (smap != null) { - ArrayMap<ComponentName, ServiceRecord> items = smap.mServicesByName; + ArrayMap<ComponentName, ServiceRecord> items = smap.mServicesByInstanceName; didSomething = collectPackageServicesLocked(packageName, filterByClasses, evenPersistent, doit, killProcess, items); } @@ -3275,7 +3313,7 @@ public final class ActiveServices { ServiceRecord sr = services.get(i); if (sr.startRequested) { if ((sr.serviceInfo.flags&ServiceInfo.FLAG_STOP_WITH_TASK) != 0) { - Slog.i(TAG, "Stopping service " + sr.shortName + ": remove task"); + Slog.i(TAG, "Stopping service " + sr.shortInstanceName + ": remove task"); stopServiceLocked(sr); } else { sr.pendingStarts.add(new ServiceRecord.StartItem(sr, true, @@ -3313,7 +3351,7 @@ public final class ActiveServices { } catch (Exception e) { // todo: this should be asynchronous! Slog.w(TAG, "Exception thrown disconnected servce " - + r.shortName + + r.shortInstanceName + " from app " + app.processName, e); } } @@ -3387,7 +3425,7 @@ public final class ActiveServices { if (false && proc != null && !proc.isPersistent() && proc.thread != null && proc.pid != 0 && proc.pid != ActivityManagerService.MY_PID && proc.setProcState >= ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { - proc.kill("bound to service " + sr.name.flattenToShortString() + proc.kill("bound to service " + sr.shortInstanceName + " in dying proc " + (app != null ? app.processName : "??"), true); } } @@ -3408,7 +3446,7 @@ public final class ActiveServices { // Sanity check: if the service listed for the app is not one // we actually are maintaining, just let it drop. - final ServiceRecord curRec = smap.mServicesByName.get(sr.name); + final ServiceRecord curRec = smap.mServicesByInstanceName.get(sr.instanceName); if (curRec != sr) { if (curRec != null) { Slog.wtf(TAG, "Service " + sr + " in process " + app @@ -3425,7 +3463,7 @@ public final class ActiveServices { Slog.w(TAG, "Service crashed " + sr.crashCount + " times, stopping: " + sr); EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH, - sr.userId, sr.crashCount, sr.shortName, app.pid); + sr.userId, sr.crashCount, sr.shortInstanceName, app.pid); bringDownServiceLocked(sr); } else if (!allowRestart || !mAm.mUserController.isUserRunning(sr.userId, 0)) { @@ -3631,7 +3669,7 @@ public final class ActiveServices { mLastAnrDump = sw.toString(); mAm.mHandler.removeCallbacks(mLastAnrDumpClearer); mAm.mHandler.postDelayed(mLastAnrDumpClearer, LAST_ANR_LIFETIME_DURATION_MSECS); - anrMessage = "executing service " + timeout.shortName; + anrMessage = "executing service " + timeout.shortInstanceName; } else { Message msg = mAm.mHandler.obtainMessage( ActivityManagerService.SERVICE_TIMEOUT_MSG); @@ -3677,7 +3715,8 @@ public final class ActiveServices { final int userId = UserHandle.getUserId(applicationInfo.uid); ServiceMap serviceMap = mServiceMap.get(userId); if (serviceMap != null) { - ArrayMap<ComponentName, ServiceRecord> servicesByName = serviceMap.mServicesByName; + ArrayMap<ComponentName, ServiceRecord> servicesByName + = serviceMap.mServicesByInstanceName; for (int j = servicesByName.size() - 1; j >= 0; j--) { ServiceRecord serviceRecord = servicesByName.valueAt(j); if (applicationInfo.packageName.equals(serviceRecord.appInfo.packageName)) { @@ -3748,9 +3787,9 @@ public final class ActiveServices { final int[] users = mAm.mUserController.getUsers(); for (int user : users) { ServiceMap smap = getServiceMapLocked(user); - if (smap.mServicesByName.size() > 0) { - for (int si=0; si<smap.mServicesByName.size(); si++) { - ServiceRecord r = smap.mServicesByName.valueAt(si); + if (smap.mServicesByInstanceName.size() > 0) { + for (int si=0; si<smap.mServicesByInstanceName.size(); si++) { + ServiceRecord r = smap.mServicesByInstanceName.valueAt(si); if (!matcher.match(r, r.name)) { continue; } @@ -4151,7 +4190,7 @@ public final class ActiveServices { } long token = proto.start(ActiveServicesProto.SERVICES_BY_USERS); proto.write(ActiveServicesProto.ServicesByUser.USER_ID, user); - ArrayMap<ComponentName, ServiceRecord> alls = smap.mServicesByName; + ArrayMap<ComponentName, ServiceRecord> alls = smap.mServicesByInstanceName; for (int i=0; i<alls.size(); i++) { alls.valueAt(i).writeToProto(proto, ActiveServicesProto.ServicesByUser.SERVICE_RECORDS); @@ -4184,7 +4223,7 @@ public final class ActiveServices { if (smap == null) { continue; } - ArrayMap<ComponentName, ServiceRecord> alls = smap.mServicesByName; + ArrayMap<ComponentName, ServiceRecord> alls = smap.mServicesByInstanceName; for (int i=0; i<alls.size(); i++) { ServiceRecord r1 = alls.valueAt(i); @@ -4222,7 +4261,7 @@ public final class ActiveServices { String innerPrefix = prefix + " "; synchronized (mAm) { pw.print(prefix); pw.print("SERVICE "); - pw.print(r.shortName); pw.print(" "); + pw.print(r.shortInstanceName); pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); pw.print(" pid="); if (r.app != null) pw.println(r.app.pid); diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 3406aa3a15f5..771d3765d902 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -2055,8 +2055,7 @@ public class ActivityManagerService extends IActivityManager.Stub private String mExemptionsStr; private List<String> mExemptions = Collections.emptyList(); private int mLogSampleRate = -1; - @HiddenApiEnforcementPolicy private int mPolicyPreP = HIDDEN_API_ENFORCEMENT_DEFAULT; - @HiddenApiEnforcementPolicy private int mPolicyP = HIDDEN_API_ENFORCEMENT_DEFAULT; + @HiddenApiEnforcementPolicy private int mPolicy = HIDDEN_API_ENFORCEMENT_DEFAULT; public HiddenApiSettings(Handler handler, Context context) { super(handler); @@ -2073,11 +2072,7 @@ public class ActivityManagerService extends IActivityManager.Stub false, this); mContext.getContentResolver().registerContentObserver( - Settings.Global.getUriFor(Settings.Global.HIDDEN_API_POLICY_PRE_P_APPS), - false, - this); - mContext.getContentResolver().registerContentObserver( - Settings.Global.getUriFor(Settings.Global.HIDDEN_API_POLICY_P_APPS), + Settings.Global.getUriFor(Settings.Global.HIDDEN_API_POLICY), false, this); update(); @@ -2112,8 +2107,7 @@ public class ActivityManagerService extends IActivityManager.Stub mLogSampleRate = logSampleRate; zygoteProcess.setHiddenApiAccessLogSampleRate(mLogSampleRate); } - mPolicyPreP = getValidEnforcementPolicy(Settings.Global.HIDDEN_API_POLICY_PRE_P_APPS); - mPolicyP = getValidEnforcementPolicy(Settings.Global.HIDDEN_API_POLICY_P_APPS); + mPolicy = getValidEnforcementPolicy(Settings.Global.HIDDEN_API_POLICY); } private @HiddenApiEnforcementPolicy int getValidEnforcementPolicy(String settingsKey) { @@ -2130,12 +2124,8 @@ public class ActivityManagerService extends IActivityManager.Stub return mBlacklistDisabled; } - @HiddenApiEnforcementPolicy int getPolicyForPrePApps() { - return mPolicyPreP; - } - - @HiddenApiEnforcementPolicy int getPolicyForPApps() { - return mPolicyP; + @HiddenApiEnforcementPolicy int getPolicy() { + return mPolicy; } public void onChange(boolean selfChange) { @@ -2686,8 +2676,10 @@ public class ActivityManagerService extends IActivityManager.Stub } void updateUsageStats(ComponentName activity, int uid, int userId, boolean resumed) { - if (DEBUG_SWITCH) Slog.d(TAG_SWITCH, - "updateUsageStats: comp=" + activity + "res=" + resumed); + if (DEBUG_SWITCH) { + Slog.d(TAG_SWITCH, + "updateUsageStats: comp=" + activity + "res=" + resumed); + } final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); StatsLog.write(StatsLog.ACTIVITY_FOREGROUND_STATE_CHANGED, uid, activity.getPackageName(), @@ -2714,6 +2706,20 @@ public class ActivityManagerService extends IActivityManager.Stub } } + void updateForegroundServiceUsageStats(ComponentName service, int userId, boolean started) { + if (DEBUG_SWITCH) { + Slog.d(TAG_SWITCH, "updateForegroundServiceUsageStats: comp=" + + service + "started=" + started); + } + synchronized (this) { + if (mUsageStatsService != null) { + mUsageStatsService.reportEvent(service, userId, + started ? UsageEvents.Event.FOREGROUND_SERVICE_START + : UsageEvents.Event.FOREGROUND_SERVICE_STOP); + } + } + } + CompatibilityInfo compatibilityInfoForPackage(ApplicationInfo ai) { return mAtmInternal.compatibilityInfoForPackage(ai); } @@ -13177,8 +13183,15 @@ public class ActivityManagerService extends IActivityManager.Stub } public int bindService(IApplicationThread caller, IBinder token, Intent service, - String resolvedType, IServiceConnection connection, int flags, String callingPackage, - int userId) throws TransactionTooLargeException { + String resolvedType, IServiceConnection connection, int flags, + String callingPackage, int userId) throws TransactionTooLargeException { + return bindIsolatedService(caller, token, service, resolvedType, connection, flags, + null, callingPackage, userId); + } + + public int bindIsolatedService(IApplicationThread caller, IBinder token, Intent service, + String resolvedType, IServiceConnection connection, int flags, String instanceName, + String callingPackage, int userId) throws TransactionTooLargeException { enforceNotIsolatedCaller("bindService"); // Refuse possible leaked file descriptors @@ -13192,7 +13205,7 @@ public class ActivityManagerService extends IActivityManager.Stub synchronized(this) { return mServices.bindServiceLocked(caller, token, service, - resolvedType, connection, flags, callingPackage, userId); + resolvedType, connection, flags, instanceName, callingPackage, userId); } } @@ -15825,7 +15838,7 @@ public class ActivityManagerService extends IActivityManager.Stub mayBeTop = true; mayBeTopType = "service"; mayBeTopSource = cr.binding.client; - mayBeTopTarget = s.name; + mayBeTopTarget = s.instanceName; clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; } else { // Special handling for above-top states (persistent @@ -15879,7 +15892,7 @@ public class ActivityManagerService extends IActivityManager.Stub .REASON_SERVICE_IN_USE; app.adjSource = cr.binding.client; app.adjSourceProcState = clientProcState; - app.adjTarget = s.name; + app.adjTarget = s.instanceName; if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to " + adjType + ": " + app + ", due to " + cr.binding.client @@ -15909,7 +15922,7 @@ public class ActivityManagerService extends IActivityManager.Stub .REASON_SERVICE_IN_USE; app.adjSource = a; app.adjSourceProcState = procState; - app.adjTarget = s.name; + app.adjTarget = s.instanceName; if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to service w/activity: " + app); @@ -19164,6 +19177,9 @@ public class ActivityManagerService extends IActivityManager.Stub if (!SystemProperties.getBoolean(StorageManager.PROP_ISOLATED_STORAGE, false)) { return false; } + if (uid == SHELL_UID || uid == ROOT_UID) { + return false; + } synchronized (mPidsSelfLocked) { final ProcessRecord pr = mPidsSelfLocked.get(pid); return pr == null || pr.mountMode != Zygote.MOUNT_EXTERNAL_FULL; diff --git a/services/core/java/com/android/server/am/AppBindRecord.java b/services/core/java/com/android/server/am/AppBindRecord.java index 4eaebd04a8ad..9870420cae13 100644 --- a/services/core/java/com/android/server/am/AppBindRecord.java +++ b/services/core/java/com/android/server/am/AppBindRecord.java @@ -59,12 +59,12 @@ final class AppBindRecord { public String toString() { return "AppBindRecord{" + Integer.toHexString(System.identityHashCode(this)) - + " " + service.shortName + ":" + client.processName + "}"; + + " " + service.shortInstanceName + ":" + client.processName + "}"; } void writeToProto(ProtoOutputStream proto, long fieldId) { long token = proto.start(fieldId); - proto.write(AppBindRecordProto.SERVICE_NAME, service.shortName); + proto.write(AppBindRecordProto.SERVICE_NAME, service.shortInstanceName); proto.write(AppBindRecordProto.CLIENT_PROC_NAME, client.processName); final int N = connections.size(); for (int i=0; i<N; i++) { diff --git a/services/core/java/com/android/server/am/ConnectionRecord.java b/services/core/java/com/android/server/am/ConnectionRecord.java index 37d07bbda760..bfa3f66ce726 100644 --- a/services/core/java/com/android/server/am/ConnectionRecord.java +++ b/services/core/java/com/android/server/am/ConnectionRecord.java @@ -115,16 +115,16 @@ final class ConnectionRecord { && (binding.service.appInfo.uid != clientUid || !binding.service.processName.equals(clientProcessName))) { ProcessStats.ProcessStateHolder holder = binding.service.app.pkgList.get( - binding.service.name.getPackageName()); + binding.service.instanceName.getPackageName()); if (holder == null) { Slog.wtf(TAG_AM, "No package in referenced service " - + binding.service.name.toShortString() + ": proc=" + binding.service.app); + + binding.service.shortInstanceName + ": proc=" + binding.service.app); } else if (holder.pkg == null) { Slog.wtf(TAG_AM, "Inactive holder in referenced service " - + binding.service.name.toShortString() + ": proc=" + binding.service.app); + + binding.service.shortInstanceName + ": proc=" + binding.service.app); } else { association = holder.pkg.getAssociationStateLocked(holder.state, - binding.service.name.getClassName()).startSource(clientUid, + binding.service.instanceName.getClassName()).startSource(clientUid, clientProcessName); } @@ -202,7 +202,7 @@ final class ConnectionRecord { if (serviceDead) { sb.append("DEAD "); } - sb.append(binding.service.shortName); + sb.append(binding.service.shortInstanceName); sb.append(":@"); sb.append(Integer.toHexString(System.identityHashCode(conn.asBinder()))); sb.append('}'); @@ -223,7 +223,7 @@ final class ConnectionRecord { proto.write(ConnectionRecordProto.FLAGS, ConnectionRecordProto.DEAD); } if (binding.service != null) { - proto.write(ConnectionRecordProto.SERVICE_NAME, binding.service.shortName); + proto.write(ConnectionRecordProto.SERVICE_NAME, binding.service.shortInstanceName); } proto.end(token); } diff --git a/services/core/java/com/android/server/am/IntentBindRecord.java b/services/core/java/com/android/server/am/IntentBindRecord.java index 839b6e1bd634..90aef3efea46 100644 --- a/services/core/java/com/android/server/am/IntentBindRecord.java +++ b/services/core/java/com/android/server/am/IntentBindRecord.java @@ -99,7 +99,7 @@ final class IntentBindRecord { if ((collectFlags()&Context.BIND_AUTO_CREATE) != 0) { sb.append("CR "); } - sb.append(service.shortName); + sb.append(service.shortInstanceName); sb.append(':'); if (intent != null) { intent.getIntent().toShortString(sb, false, false, false, false); diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java index c1b720e3f847..84b364bd20a8 100644 --- a/services/core/java/com/android/server/am/ProcessList.java +++ b/services/core/java/com/android/server/am/ProcessList.java @@ -1363,8 +1363,7 @@ public final class ProcessList { if (!disableHiddenApiChecks && !mService.mHiddenApiBlacklist.isDisabled()) { app.info.maybeUpdateHiddenApiEnforcementPolicy( - mService.mHiddenApiBlacklist.getPolicyForPrePApps(), - mService.mHiddenApiBlacklist.getPolicyForPApps()); + mService.mHiddenApiBlacklist.getPolicy()); @ApplicationInfo.HiddenApiEnforcementPolicy int policy = app.info.getHiddenApiEnforcementPolicy(); int policyBits = (policy << Zygote.API_ENFORCEMENT_POLICY_SHIFT); diff --git a/services/core/java/com/android/server/am/ServiceRecord.java b/services/core/java/com/android/server/am/ServiceRecord.java index d8f94c933ac8..09f8c3eee3b6 100644 --- a/services/core/java/com/android/server/am/ServiceRecord.java +++ b/services/core/java/com/android/server/am/ServiceRecord.java @@ -70,7 +70,8 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN final ActivityManagerService ams; final BatteryStatsImpl.Uid.Pkg.Serv stats; final ComponentName name; // service component. - final String shortName; // name.flattenToShortString(). + final ComponentName instanceName; // service component's per-instance name. + final String shortInstanceName; // instanceName.flattenToShortString(). final Intent.FilterComparison intent; // original intent used to find service. final ServiceInfo serviceInfo; @@ -190,7 +191,7 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN StringBuilder sb = new StringBuilder(128); sb.append("ServiceRecord{") .append(Integer.toHexString(System.identityHashCode(sr))) - .append(' ').append(sr.shortName) + .append(' ').append(sr.shortInstanceName) .append(" StartItem ") .append(Integer.toHexString(System.identityHashCode(this))) .append(" id=").append(id).append('}'); @@ -235,7 +236,7 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN void writeToProto(ProtoOutputStream proto, long fieldId) { long token = proto.start(fieldId); - proto.write(ServiceRecordProto.SHORT_NAME, this.shortName); + proto.write(ServiceRecordProto.SHORT_NAME, this.shortInstanceName); proto.write(ServiceRecordProto.IS_RUNNING, app != null); if (app != null) { proto.write(ServiceRecordProto.PID, app.pid); @@ -448,12 +449,14 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN ServiceRecord(ActivityManagerService ams, BatteryStatsImpl.Uid.Pkg.Serv servStats, ComponentName name, + ComponentName instanceName, Intent.FilterComparison intent, ServiceInfo sInfo, boolean callerIsFg, Runnable restarter) { this.ams = ams; this.stats = servStats; this.name = name; - shortName = name.flattenToShortString(); + this.instanceName = instanceName; + shortInstanceName = instanceName.flattenToShortString(); this.intent = intent; serviceInfo = sInfo; appInfo = sInfo.applicationInfo; @@ -618,7 +621,7 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN // those dirty apps we will create a notification clearly // blaming the app. Slog.v(TAG, "Attempted to start a foreground service (" - + name + + shortInstanceName + ") with a broken notification (no icon: " + localForegroundNoti + ")"); @@ -701,7 +704,7 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN Slog.w(TAG, "Error showing notification for service", e); // If it gave us a garbage notification, it doesn't // get to be foreground. - ams.setServiceForeground(name, ServiceRecord.this, + ams.setServiceForeground(instanceName, ServiceRecord.this, 0, null, 0); ams.crashApplication(appUid, appPid, localPackageName, -1, "Bad notification for startForeground: " + e); @@ -773,7 +776,7 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN sb.append("ServiceRecord{") .append(Integer.toHexString(System.identityHashCode(this))) .append(" u").append(userId) - .append(' ').append(shortName).append('}'); + .append(' ').append(shortInstanceName).append('}'); return stringName = sb.toString(); } diff --git a/services/core/java/com/android/server/biometrics/AuthenticationClient.java b/services/core/java/com/android/server/biometrics/AuthenticationClient.java index 61836fdd7316..2c2d4045b205 100644 --- a/services/core/java/com/android/server/biometrics/AuthenticationClient.java +++ b/services/core/java/com/android/server/biometrics/AuthenticationClient.java @@ -358,7 +358,7 @@ public abstract class AuthenticationClient extends ClientMonitor { if (mBundle != null) { try { mStatusBarService.showBiometricDialog(mBundle, mDialogReceiver, - getBiometricType(), mRequireConfirmation); + getBiometricType(), mRequireConfirmation, getTargetUserId()); } catch (RemoteException e) { Slog.e(getLogTag(), "Unable to show biometric dialog", e); } diff --git a/services/core/java/com/android/server/biometrics/face/FaceService.java b/services/core/java/com/android/server/biometrics/face/FaceService.java index bc3cc3bd383c..7aa2e47300dd 100644 --- a/services/core/java/com/android/server/biometrics/face/FaceService.java +++ b/services/core/java/com/android/server/biometrics/face/FaceService.java @@ -485,7 +485,7 @@ public class FaceService extends BiometricServiceBase { BiometricAuthenticator.Identifier biometric, int userId) throws RemoteException { if (mFaceServiceReceiver != null) { - if (biometric instanceof Face) { + if (biometric == null || biometric instanceof Face) { mFaceServiceReceiver.onAuthenticationSucceeded(deviceId, (Face)biometric); } else { Slog.e(TAG, "onAuthenticationSucceeded received non-face biometric"); diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java index f0745731ffeb..9e6e3812df6b 100644 --- a/services/core/java/com/android/server/location/GnssLocationProvider.java +++ b/services/core/java/com/android/server/location/GnssLocationProvider.java @@ -2075,8 +2075,8 @@ public class GnssLocationProvider implements LocationProviderInterface, InjectNt // note that this assumes the message will not be removed from the queue before // it is handled (otherwise the wake lock would be leaked). mWakeLock.acquire(); - if (Log.isLoggable(TAG, Log.INFO)) { - Log.i(TAG, "WakeLock acquired by sendMessage(" + messageIdAsString(message) + ", " + arg + if (DEBUG) { + Log.d(TAG, "WakeLock acquired by sendMessage(" + messageIdAsString(message) + ", " + arg + ", " + obj + ")"); } mHandler.obtainMessage(message, arg, 1, obj).sendToTarget(); @@ -2133,8 +2133,8 @@ public class GnssLocationProvider implements LocationProviderInterface, InjectNt if (msg.arg2 == 1) { // wakelock was taken for this message, release it mWakeLock.release(); - if (Log.isLoggable(TAG, Log.INFO)) { - Log.i(TAG, "WakeLock released by handleMessage(" + messageIdAsString(message) + if (DEBUG) { + Log.d(TAG, "WakeLock released by handleMessage(" + messageIdAsString(message) + ", " + msg.arg1 + ", " + msg.obj + ")"); } } diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index b404c41c211d..1c7572ee4e2c 100644 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -3610,7 +3610,7 @@ public class NotificationManagerService extends SystemService { NotificationRecord r = mNotificationsByKey.get(adjustment.getKey()); if (r != null && mAssistants.isSameUser(token, r.getUserId())) { applyAdjustment(r, adjustment); - r.applyAdjustments(); + r.applyImportanceFromAdjustments(); if (r.getImportance() == IMPORTANCE_NONE) { cancelNotificationsFromListener(token, new String[]{r.getKey()}); } else { diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java index 84d0c018a3dc..a11b03f68667 100644 --- a/services/core/java/com/android/server/notification/NotificationRecord.java +++ b/services/core/java/com/android/server/notification/NotificationRecord.java @@ -664,6 +664,18 @@ public final class NotificationRecord { .addTaggedData(MetricsEvent.ADJUSTMENT_KEY_SMART_REPLIES, getSmartReplies().size())); } + } + applyImportanceFromAdjustments(); + } + } + + /** + * Update importance from the adjustment. + */ + public void applyImportanceFromAdjustments() { + synchronized (mAdjustments) { + for (Adjustment adjustment : mAdjustments) { + Bundle signals = adjustment.getSignals(); if (signals.containsKey(Adjustment.KEY_IMPORTANCE)) { int importance = signals.getInt(Adjustment.KEY_IMPORTANCE); importance = Math.max(IMPORTANCE_UNSPECIFIED, importance); diff --git a/services/core/java/com/android/server/pm/PackageDexOptimizer.java b/services/core/java/com/android/server/pm/PackageDexOptimizer.java index 95c70d590b69..95d2154dcdb9 100644 --- a/services/core/java/com/android/server/pm/PackageDexOptimizer.java +++ b/services/core/java/com/android/server/pm/PackageDexOptimizer.java @@ -49,7 +49,7 @@ import java.util.Map; import dalvik.system.DexFile; -import static android.content.pm.ApplicationInfo.HIDDEN_API_ENFORCEMENT_NONE; +import static android.content.pm.ApplicationInfo.HIDDEN_API_ENFORCEMENT_DISABLED; import static com.android.server.pm.Installer.DEXOPT_BOOTCOMPLETE; import static com.android.server.pm.Installer.DEXOPT_DEBUGGABLE; @@ -548,7 +548,7 @@ public class PackageDexOptimizer { // Some apps are executed with restrictions on hidden API usage. If this app is one // of them, pass a flag to dexopt to enable the same restrictions during compilation. // TODO we should pass the actual flag value to dexopt, rather than assuming blacklist - int hiddenApiFlag = info.getHiddenApiEnforcementPolicy() == HIDDEN_API_ENFORCEMENT_NONE + int hiddenApiFlag = info.getHiddenApiEnforcementPolicy() == HIDDEN_API_ENFORCEMENT_DISABLED ? 0 : DEXOPT_ENABLE_HIDDEN_API_CHECKS; // Avoid generating CompactDex for modes that are latency critical. diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java index 26f6e96ce957..ea190a7301fc 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerSession.java +++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java @@ -1126,101 +1126,108 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR, "Session not sealed"); } - if (!params.isMultiPackage) { - Preconditions.checkNotNull(mPackageName); - Preconditions.checkNotNull(mSigningDetails); - Preconditions.checkNotNull(mResolvedBaseFile); - - if (needToAskForPermissionsLocked()) { - // User needs to confirm installation; - // give installer an intent they can use to involve - // user. - final Intent intent = new Intent(PackageInstaller.ACTION_CONFIRM_INSTALL); - intent.setPackage(mPm.getPackageInstallerPackageName()); - intent.putExtra(PackageInstaller.EXTRA_SESSION_ID, sessionId); - try { - mRemoteObserver.onUserActionRequired(intent); - } catch (RemoteException ignored) { - } - - // Commit was keeping session marked as active until now; release - // that extra refcount so session appears idle. - closeInternal(false); - return null; - } + final IPackageInstallObserver2 localObserver; + if ((params.installFlags & PackageManager.INSTALL_APEX) != 0) { + localObserver = null; + } else { + if (!params.isMultiPackage) { + Preconditions.checkNotNull(mPackageName); + Preconditions.checkNotNull(mSigningDetails); + Preconditions.checkNotNull(mResolvedBaseFile); + + if (needToAskForPermissionsLocked()) { + // User needs to confirm installation; + // give installer an intent they can use to involve + // user. + final Intent intent = new Intent(PackageInstaller.ACTION_CONFIRM_INSTALL); + intent.setPackage(mPm.getPackageInstallerPackageName()); + intent.putExtra(PackageInstaller.EXTRA_SESSION_ID, sessionId); + try { + mRemoteObserver.onUserActionRequired(intent); + } catch (RemoteException ignored) { + } - // Inherit any packages and native libraries from existing install that - // haven't been overridden. - if (params.mode == SessionParams.MODE_INHERIT_EXISTING) { - try { - final List<File> fromFiles = mResolvedInheritedFiles; - final File toDir = resolveStageDirLocked(); + // Commit was keeping session marked as active until now; release + // that extra refcount so session appears idle. + closeInternal(false); + return null; + } - if (LOGD) Slog.d(TAG, "Inherited files: " + mResolvedInheritedFiles); - if (!mResolvedInheritedFiles.isEmpty() && mInheritedFilesBase == null) { - throw new IllegalStateException("mInheritedFilesBase == null"); - } + // Inherit any packages and native libraries from existing install that + // haven't been overridden. + if (params.mode == SessionParams.MODE_INHERIT_EXISTING) { + try { + final List<File> fromFiles = mResolvedInheritedFiles; + final File toDir = resolveStageDirLocked(); - if (isLinkPossible(fromFiles, toDir)) { - if (!mResolvedInstructionSets.isEmpty()) { - final File oatDir = new File(toDir, "oat"); - createOatDirs(mResolvedInstructionSets, oatDir); + if (LOGD) Slog.d(TAG, "Inherited files: " + mResolvedInheritedFiles); + if (!mResolvedInheritedFiles.isEmpty() && mInheritedFilesBase == null) { + throw new IllegalStateException("mInheritedFilesBase == null"); } - // pre-create lib dirs for linking if necessary - if (!mResolvedNativeLibPaths.isEmpty()) { - for (String libPath : mResolvedNativeLibPaths) { - // "/lib/arm64" -> ["lib", "arm64"] - final int splitIndex = libPath.lastIndexOf('/'); - if (splitIndex < 0 || splitIndex >= libPath.length() - 1) { - Slog.e(TAG, - "Skipping native library creation for linking due to " - + "invalid path: " + libPath); - continue; - } - final String libDirPath = libPath.substring(1, splitIndex); - final File libDir = new File(toDir, libDirPath); - if (!libDir.exists()) { - NativeLibraryHelper.createNativeLibrarySubdir(libDir); + + if (isLinkPossible(fromFiles, toDir)) { + if (!mResolvedInstructionSets.isEmpty()) { + final File oatDir = new File(toDir, "oat"); + createOatDirs(mResolvedInstructionSets, oatDir); + } + // pre-create lib dirs for linking if necessary + if (!mResolvedNativeLibPaths.isEmpty()) { + for (String libPath : mResolvedNativeLibPaths) { + // "/lib/arm64" -> ["lib", "arm64"] + final int splitIndex = libPath.lastIndexOf('/'); + if (splitIndex < 0 || splitIndex >= libPath.length() - 1) { + Slog.e(TAG, + "Skipping native library creation for linking due" + + " to invalid path: " + libPath); + continue; + } + final String libDirPath = libPath.substring(1, splitIndex); + final File libDir = new File(toDir, libDirPath); + if (!libDir.exists()) { + NativeLibraryHelper.createNativeLibrarySubdir(libDir); + } + final String archDirPath = libPath.substring(splitIndex + 1); + NativeLibraryHelper.createNativeLibrarySubdir( + new File(libDir, archDirPath)); } - final String archDirPath = libPath.substring(splitIndex + 1); - NativeLibraryHelper.createNativeLibrarySubdir( - new File(libDir, archDirPath)); } + linkFiles(fromFiles, toDir, mInheritedFilesBase); + } else { + // TODO: this should delegate to DCS so the system process + // avoids holding open FDs into containers. + copyFiles(fromFiles, toDir); } - linkFiles(fromFiles, toDir, mInheritedFilesBase); - } else { - // TODO: this should delegate to DCS so the system process - // avoids holding open FDs into containers. - copyFiles(fromFiles, toDir); + } catch (IOException e) { + throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE, + "Failed to inherit existing install", e); } - } catch (IOException e) { - throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE, - "Failed to inherit existing install", e); } - } - // TODO: surface more granular state from dexopt - mInternalProgress = 0.5f; - computeProgressLocked(true); + // TODO: surface more granular state from dexopt + mInternalProgress = 0.5f; + computeProgressLocked(true); - // Unpack native libraries - extractNativeLibraries(mResolvedStageDir, params.abiOverride, mayInheritNativeLibs()); - } - // We've reached point of no return; call into PMS to install the stage. - // Regardless of success or failure we always destroy session. - final IPackageInstallObserver2 localObserver = new IPackageInstallObserver2.Stub() { - @Override - public void onUserActionRequired(Intent intent) { - throw new IllegalStateException(); + // Unpack native libraries + extractNativeLibraries(mResolvedStageDir, params.abiOverride, + mayInheritNativeLibs()); } - @Override - public void onPackageInstalled(String basePackageName, int returnCode, String msg, - Bundle extras) { - destroyInternal(); - dispatchSessionFinished(returnCode, msg, extras); - } - }; + // We've reached point of no return; call into PMS to install the stage. + // Regardless of success or failure we always destroy session. + localObserver = new IPackageInstallObserver2.Stub() { + @Override + public void onUserActionRequired(Intent intent) { + throw new IllegalStateException(); + } + + @Override + public void onPackageInstalled(String basePackageName, int returnCode, String msg, + Bundle extras) { + destroyInternal(); + dispatchSessionFinished(returnCode, msg, extras); + } + }; + } final UserHandle user; if ((params.installFlags & PackageManager.INSTALL_ALL_USERS) != 0) { @@ -1230,11 +1237,9 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } mRelinquished = true; - final PackageManagerService.ActiveInstallSession activeInstallSession = - new PackageManagerService.ActiveInstallSession(mPackageName, stageDir, - localObserver, params, mInstallerPackageName, mInstallerUid, user, - mSigningDetails); - return activeInstallSession; + return new PackageManagerService.ActiveInstallSession(mPackageName, stageDir, + localObserver, params, mInstallerPackageName, mInstallerUid, user, + mSigningDetails); } private static void maybeRenameFile(File from, File to) throws PackageManagerException { diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 77045fb11b1f..8a0c416ece04 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -9308,7 +9308,7 @@ public class PackageManagerService extends IPackageManager.Stub } } - private SharedLibraryInfo getSharedLibraryInfoLPr(String name, long version) { + private @Nullable SharedLibraryInfo getSharedLibraryInfoLPr(String name, long version) { LongSparseArray<SharedLibraryInfo> versionedLib = mSharedLibraries.get(name); if (versionedLib == null) { return null; @@ -9580,16 +9580,26 @@ public class PackageManagerService extends IPackageManager.Stub private void applyDefiningSharedLibraryUpdateLocked( PackageParser.Package pkg, SharedLibraryInfo libInfo, BiConsumer<SharedLibraryInfo, SharedLibraryInfo> action) { + // Note that libraries defined by this package may be null if: + // - Package manager was unable to create the shared library. The package still + // gets installed, but the shared library does not get created. + // Or: + // - Package manager is in a state where package isn't scanned yet. This will + // get called again after scanning to fix the dependencies. if (pkg.isLibrary()) { if (pkg.staticSharedLibName != null) { SharedLibraryInfo definedLibrary = getSharedLibraryInfoLPr( pkg.staticSharedLibName, pkg.staticSharedLibVersion); - action.accept(definedLibrary, libInfo); + if (definedLibrary != null) { + action.accept(definedLibrary, libInfo); + } } else { for (String libraryName : pkg.libraryNames) { SharedLibraryInfo definedLibrary = getSharedLibraryInfoLPr( libraryName, SharedLibraryInfo.VERSION_UNDEFINED); - action.accept(definedLibrary, libInfo); + if (definedLibrary != null) { + action.accept(definedLibrary, libInfo); + } } } } @@ -16337,17 +16347,6 @@ public class PackageManagerService extends IPackageManager.Stub + oldPackage.mSharedUserId); } - // check if the new package supports all of the abis which the old package - // supports - boolean oldPkgSupportMultiArch = - oldPackage.applicationInfo.secondaryCpuAbi != null; - boolean newPkgSupportMultiArch = pkg.applicationInfo.secondaryCpuAbi != null; - if (isSystemApp(oldPackage) && oldPkgSupportMultiArch - && !newPkgSupportMultiArch) { - throw new PrepareFailure(INSTALL_FAILED_UPDATE_INCOMPATIBLE, - "Update to package " + pkgName11 + " doesn't support multi arch"); - } - // In case of rollback, remember per-user/profile install state allUsers = sUserManager.getUserIds(); installedUsers = ps.queryInstalledUsers(allUsers, true); @@ -17774,30 +17773,58 @@ public class PackageManagerService extends IPackageManager.Stub return true; } + private static class DeletePackageAction { + public final PackageSetting deletingPs; + + private DeletePackageAction(PackageSetting deletingPs) { + this.deletingPs = deletingPs; + } + } + + /** + * @return a {@link DeletePackageAction} if the provided package may be deleted, {@code null} + * otherwise. + */ + @Nullable + private DeletePackageAction mayDeletePackageLIF(@NonNull String packageName) { + synchronized (mPackages) { + final PackageSetting ps; + ps = mSettings.mPackages.get(packageName); + if (ps == null) { + return null; + } + return new DeletePackageAction(ps); + } + } + /* * This method handles package deletion in general */ - private boolean deletePackageLIF(String packageName, UserHandle user, + private boolean deletePackageLIF(@NonNull String packageName, UserHandle user, boolean deleteCodeAndResources, int[] allUserHandles, int flags, PackageRemovedInfo outInfo, boolean writeSettings, PackageParser.Package replacingPackage) { - if (packageName == null) { - Slog.w(TAG, "Attempt to delete null packageName."); + final DeletePackageAction action = mayDeletePackageLIF(packageName); + if (null == action) { return false; } if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user); - PackageSetting ps; + return executeDeletePackageLIF(action, packageName, user, deleteCodeAndResources, + allUserHandles, flags, outInfo, writeSettings, replacingPackage); + } + + private boolean executeDeletePackageLIF(DeletePackageAction action, + String packageName, UserHandle user, boolean deleteCodeAndResources, + int[] allUserHandles, int flags, PackageRemovedInfo outInfo, + boolean writeSettings, PackageParser.Package replacingPackage) { + final PackageSetting ps = action.deletingPs; + final boolean systemApp = isSystemApp(ps); synchronized (mPackages) { - ps = mSettings.mPackages.get(packageName); - if (ps == null) { - Slog.w(TAG, "Package named '" + packageName + "' doesn't exist."); - return false; - } - if (ps.parentPackageName != null && (!isSystemApp(ps) - || (flags & PackageManager.DELETE_SYSTEM_APP) != 0)) { + if (ps.parentPackageName != null + && (!systemApp || (flags & PackageManager.DELETE_SYSTEM_APP) != 0)) { if (DEBUG_REMOVE) { Slog.d(TAG, "Uninstalled child package:" + packageName + " for user:" + ((user == null) ? UserHandle.USER_ALL : user)); @@ -17805,9 +17832,7 @@ public class PackageManagerService extends IPackageManager.Stub final int removedUserId = (user != null) ? user.getIdentifier() : UserHandle.USER_ALL; - if (!clearPackageStateForUserLIF(ps, removedUserId, outInfo)) { - return false; - } + clearPackageStateForUserLIF(ps, removedUserId, outInfo); markPackageUninstalledForUserLPw(ps, user); scheduleWritePackageRestrictionsLocked(user); return true; @@ -17820,7 +17845,7 @@ public class PackageManagerService extends IPackageManager.Stub } - if (((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null + if (((!systemApp || (flags & PackageManager.DELETE_SYSTEM_APP) != 0) && user != null && user.getIdentifier() != UserHandle.USER_ALL)) { // The caller is asking that the package only be deleted for a single // user. To do this, we just mark its uninstalled state and delete @@ -17829,7 +17854,7 @@ public class PackageManagerService extends IPackageManager.Stub // semantics than normal for uninstalling system apps. markPackageUninstalledForUserLPw(ps, user); - if (!isSystemApp(ps)) { + if (!systemApp) { // Do not uninstall the APK if an app should be cached boolean keepUninstalledPackage = shouldKeepUninstalledPackageLPr(packageName); if (ps.isAnyInstalled(sUserManager.getUserIds()) || keepUninstalledPackage) { @@ -17837,9 +17862,7 @@ public class PackageManagerService extends IPackageManager.Stub // we need to do is clear this user's data and save that // it is uninstalled. if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users"); - if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) { - return false; - } + clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo); scheduleWritePackageRestrictionsLocked(user); return true; } else { @@ -17855,9 +17878,7 @@ public class PackageManagerService extends IPackageManager.Stub // we need to do is clear this user's data and save that // it is uninstalled. if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app"); - if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) { - return false; - } + clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo); scheduleWritePackageRestrictionsLocked(user); return true; } @@ -17883,8 +17904,9 @@ public class PackageManagerService extends IPackageManager.Stub } } - boolean ret = false; - if (isSystemApp(ps)) { + // TODO(b/109941548): break reasons for ret = false out into mayDelete method + final boolean ret; + if (systemApp) { if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package: " + ps.name); // When an updated system application is deleted we delete the existing resources // as well and fall back to existing code in system partition @@ -17913,7 +17935,7 @@ public class PackageManagerService extends IPackageManager.Stub // If we uninstalled an update to a system app there may be some // child packages that appeared as they are declared in the system // app but were not declared in the update. - if (isSystemApp(ps)) { + if (systemApp) { synchronized (mPackages) { PackageSetting updatedPs = mSettings.getPackageLPr(ps.name); final int childCount = (updatedPs.childPackageNames != null) @@ -17974,7 +17996,7 @@ public class PackageManagerService extends IPackageManager.Stub mSettings.writeKernelMappingLPr(ps); } - private boolean clearPackageStateForUserLIF(PackageSetting ps, int userId, + private void clearPackageStateForUserLIF(PackageSetting ps, int userId, PackageRemovedInfo outInfo) { final PackageParser.Package pkg; synchronized (mPackages) { @@ -18010,8 +18032,6 @@ public class PackageManagerService extends IPackageManager.Stub outInfo.removedUsers = userIds; outInfo.broadcastUsers = userIds; } - - return true; } @Override diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java index 4c93441b5c7b..6009bd3e2c82 100644 --- a/services/core/java/com/android/server/pm/Settings.java +++ b/services/core/java/com/android/server/pm/Settings.java @@ -2637,7 +2637,7 @@ public final class Settings { } for (final SharedUserSetting sus : mSharedUsers.values()) { - knownSet.remove(sus.getSandboxName()); + knownSet.remove(sus.getStorageSandboxName()); } // Remove any unclaimed mappings @@ -2653,7 +2653,8 @@ public final class Settings { void writeKernelMappingLPr(SharedUserSetting sus) { if (mKernelMappingFilename == null || sus == null || sus.name == null) return; - writeKernelMappingLPr(sus.getSandboxName(), sus.userId, sus.getNotInstalledUserIds()); + writeKernelMappingLPr(sus.getStorageSandboxName(), + sus.userId, sus.getNotInstalledUserIds()); } void writeKernelMappingLPr(PackageSetting ps) { diff --git a/services/core/java/com/android/server/pm/SharedUserSetting.java b/services/core/java/com/android/server/pm/SharedUserSetting.java index 32826e51f0a4..d67144e8ce39 100644 --- a/services/core/java/com/android/server/pm/SharedUserSetting.java +++ b/services/core/java/com/android/server/pm/SharedUserSetting.java @@ -19,6 +19,7 @@ package com.android.server.pm; import android.annotation.Nullable; import android.content.pm.ApplicationInfo; import android.content.pm.PackageParser; +import android.os.storage.StorageManager; import android.service.pm.PackageServiceDumpProto; import android.util.ArraySet; import android.util.proto.ProtoOutputStream; @@ -166,8 +167,8 @@ public final class SharedUserSetting extends SettingBase { return excludedUserIds == null ? EmptyArray.INT : excludedUserIds; } - public String getSandboxName() { - return "shared:" + name; + public String getStorageSandboxName() { + return StorageManager.SHARED_SANDBOX_PREFIX + name; } /** Updates all fields in this shared user setting from another. */ diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java index 43a9c782b8d6..29d62372e154 100644 --- a/services/core/java/com/android/server/power/PowerManagerService.java +++ b/services/core/java/com/android/server/power/PowerManagerService.java @@ -4439,6 +4439,42 @@ public final class PowerManagerService extends SystemService } @Override // Binder call + public boolean setDynamicPowerSavings(boolean dynamicPowerSavingsEnabled, + int disableThreshold) { + mContext.enforceCallingOrSelfPermission(android.Manifest.permission.POWER_SAVER, + "updateDynamicPowerSavings"); + final long ident = Binder.clearCallingIdentity(); + try { + final ContentResolver resolver = mContext.getContentResolver(); + boolean success = Settings.Global.putInt(resolver, + Settings.Global.DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD, + disableThreshold); + if (success) { + // abort updating if we weren't able to succeed on the threshold + success &= Settings.Global.putInt(resolver, + Settings.Global.DYNAMIC_POWER_SAVINGS_ENABLED, + dynamicPowerSavingsEnabled ? 1 : 0); + } + return success; + } finally { + Binder.restoreCallingIdentity(ident); + } + } + + @Override // Binder call + public int getPowerSaveMode() { + mContext.enforceCallingOrSelfPermission(android.Manifest.permission.POWER_SAVER, null); + final long ident = Binder.clearCallingIdentity(); + try { + return Settings.Global.getInt(mContext.getContentResolver(), + Settings.Global.AUTOMATIC_POWER_SAVER_MODE, + PowerManager.POWER_SAVER_MODE_PERCENTAGE); + } finally { + Binder.restoreCallingIdentity(ident); + } + } + + @Override // Binder call public boolean isDeviceIdleMode() { final long ident = Binder.clearCallingIdentity(); try { diff --git a/services/core/java/com/android/server/power/batterysaver/BatterySaverController.java b/services/core/java/com/android/server/power/batterysaver/BatterySaverController.java index 5569822300b9..6400c88b320f 100644 --- a/services/core/java/com/android/server/power/batterysaver/BatterySaverController.java +++ b/services/core/java/com/android/server/power/batterysaver/BatterySaverController.java @@ -93,8 +93,8 @@ public class BatterySaverController implements BatterySaverPolicyListener { */ private final Plugin[] mPlugins; - public static final int REASON_AUTOMATIC_ON = 0; - public static final int REASON_AUTOMATIC_OFF = 1; + public static final int REASON_PERCENTAGE_AUTOMATIC_ON = 0; + public static final int REASON_PERCENTAGE_AUTOMATIC_OFF = 1; public static final int REASON_MANUAL_ON = 2; public static final int REASON_MANUAL_OFF = 3; public static final int REASON_STICKY_RESTORE = 4; @@ -102,6 +102,8 @@ public class BatterySaverController implements BatterySaverPolicyListener { public static final int REASON_POLICY_CHANGED = 6; public static final int REASON_PLUGGED_IN = 7; public static final int REASON_SETTING_CHANGED = 8; + public static final int REASON_DYNAMIC_POWER_SAVINGS_AUTOMATIC_ON = 9; + public static final int REASON_DYNAMIC_POWER_SAVINGS_AUTOMATIC_OFF = 10; /** * Plugin interface. All methods are guaranteed to be called on the same (handler) thread. diff --git a/services/core/java/com/android/server/power/batterysaver/BatterySaverStateMachine.java b/services/core/java/com/android/server/power/batterysaver/BatterySaverStateMachine.java index 20ceed43d27d..f262f6dabbe0 100644 --- a/services/core/java/com/android/server/power/batterysaver/BatterySaverStateMachine.java +++ b/services/core/java/com/android/server/power/batterysaver/BatterySaverStateMachine.java @@ -19,6 +19,7 @@ import android.content.ContentResolver; import android.content.Context; import android.database.ContentObserver; import android.os.Handler; +import android.os.PowerManager; import android.os.UserHandle; import android.provider.Settings; import android.provider.Settings.Global; @@ -87,6 +88,11 @@ public class BatterySaverStateMachine { /** Config flag to track if battery saver's sticky behaviour is disabled. */ private final boolean mBatterySaverStickyBehaviourDisabled; + /** Config flag to track default disable threshold for Dynamic Power Savings enabled battery + * saver. */ + @GuardedBy("mLock") + private final int mDynamicPowerSavingsDefaultDisableThreshold; + /** * Previously known value of Global.LOW_POWER_MODE_TRIGGER_LEVEL. * (Currently only used in dumpsys.) @@ -94,6 +100,23 @@ public class BatterySaverStateMachine { @GuardedBy("mLock") private int mSettingBatterySaverTriggerThreshold; + /** Previously known value of Global.AUTOMATIC_POWER_SAVER_MODE. */ + @GuardedBy("mLock") + private int mSettingAutomaticBatterySaver; + + /** When to disable battery saver again if it was enabled due to an external suggestion. + * Corresponds to Global.DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD. + */ + @GuardedBy("mLock") + private int mDynamicPowerSavingsDisableThreshold; + + /** + * Whether we've received a suggestion that battery saver should be on from an external app. + * Updates when Global.DYNAMIC_POWER_SAVINGS_ENABLED changes. + */ + @GuardedBy("mLock") + private boolean mDynamicPowerSavingsBatterySaver; + /** * Whether BS has been manually disabled while the battery level is low, in which case we * shouldn't auto re-enable it until the battery level is not low. @@ -130,13 +153,15 @@ public class BatterySaverStateMachine { mBatterySaverStickyBehaviourDisabled = mContext.getResources().getBoolean( com.android.internal.R.bool.config_batterySaverStickyBehaviourDisabled); + mDynamicPowerSavingsDefaultDisableThreshold = mContext.getResources().getInteger( + com.android.internal.R.integer.config_dynamicPowerSavingsDefaultDisableThreshold); } private boolean isBatterySaverEnabled() { return mBatterySaverController.isEnabled(); } - private boolean isAutoBatterySaverConfigured() { + private boolean isAutoBatterySaverConfiguredLocked() { return mSettingBatterySaverTriggerThreshold > 0; } @@ -165,6 +190,15 @@ public class BatterySaverStateMachine { cr.registerContentObserver(Settings.Global.getUriFor( Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL), false, mSettingsObserver, UserHandle.USER_SYSTEM); + cr.registerContentObserver(Settings.Global.getUriFor( + Global.AUTOMATIC_POWER_SAVER_MODE), + false, mSettingsObserver, UserHandle.USER_SYSTEM); + cr.registerContentObserver(Settings.Global.getUriFor( + Global.DYNAMIC_POWER_SAVINGS_ENABLED), + false, mSettingsObserver, UserHandle.USER_SYSTEM); + cr.registerContentObserver(Settings.Global.getUriFor( + Global.DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD), + false, mSettingsObserver, UserHandle.USER_SYSTEM); synchronized (mLock) { @@ -202,11 +236,20 @@ public class BatterySaverStateMachine { Settings.Global.LOW_POWER_MODE, 0) != 0; final boolean lowPowerModeEnabledSticky = getGlobalSetting( Settings.Global.LOW_POWER_MODE_STICKY, 0) != 0; + final boolean dynamicPowerSavingsBatterySaver = getGlobalSetting( + Global.DYNAMIC_POWER_SAVINGS_ENABLED, 0) != 0; final int lowPowerModeTriggerLevel = getGlobalSetting( Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL, 0); + final int automaticBatterySaver = getGlobalSetting( + Global.AUTOMATIC_POWER_SAVER_MODE, + PowerManager.POWER_SAVER_MODE_PERCENTAGE); + final int dynamicPowerSavingsDisableThreshold = getGlobalSetting( + Global.DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD, + mDynamicPowerSavingsDefaultDisableThreshold); setSettingsLocked(lowPowerModeEnabled, lowPowerModeEnabledSticky, - lowPowerModeTriggerLevel); + lowPowerModeTriggerLevel, automaticBatterySaver, dynamicPowerSavingsBatterySaver, + dynamicPowerSavingsDisableThreshold); } /** @@ -218,11 +261,16 @@ public class BatterySaverStateMachine { @GuardedBy("mLock") @VisibleForTesting void setSettingsLocked(boolean batterySaverEnabled, boolean batterySaverEnabledSticky, - int batterySaverTriggerThreshold) { + int batterySaverTriggerThreshold, int automaticBatterySaver, + boolean dynamicPowerSavingsBatterySaver, int dynamicPowerSavingsDisableThreshold) { if (DEBUG) { Slog.d(TAG, "setSettings: enabled=" + batterySaverEnabled + " sticky=" + batterySaverEnabledSticky - + " threshold=" + batterySaverTriggerThreshold); + + " threshold=" + batterySaverTriggerThreshold + + " automaticBatterySaver=" + automaticBatterySaver + + " dynamicPowerSavingsBatterySaver=" + dynamicPowerSavingsBatterySaver + + " dynamicPowerSavingsDisableThreshold=" + + dynamicPowerSavingsDisableThreshold); } mSettingsLoaded = true; @@ -232,14 +280,23 @@ public class BatterySaverStateMachine { mSettingBatterySaverEnabledSticky != batterySaverEnabledSticky; final boolean thresholdChanged = mSettingBatterySaverTriggerThreshold != batterySaverTriggerThreshold; - - if (!(enabledChanged || stickyChanged || thresholdChanged)) { + final boolean automaticModeChanged = mSettingAutomaticBatterySaver != automaticBatterySaver; + final boolean dynamicPowerSavingsThresholdChanged = + mDynamicPowerSavingsDisableThreshold != dynamicPowerSavingsDisableThreshold; + final boolean dynamicPowerSavingsBatterySaverChanged = + mDynamicPowerSavingsBatterySaver != dynamicPowerSavingsBatterySaver; + + if (!(enabledChanged || stickyChanged || thresholdChanged || automaticModeChanged + || dynamicPowerSavingsThresholdChanged || dynamicPowerSavingsBatterySaverChanged)) { return; } mSettingBatterySaverEnabled = batterySaverEnabled; mSettingBatterySaverEnabledSticky = batterySaverEnabledSticky; mSettingBatterySaverTriggerThreshold = batterySaverTriggerThreshold; + mSettingAutomaticBatterySaver = automaticBatterySaver; + mDynamicPowerSavingsDisableThreshold = dynamicPowerSavingsDisableThreshold; + mDynamicPowerSavingsBatterySaver = dynamicPowerSavingsBatterySaver; if (thresholdChanged) { // To avoid spamming the event log, we throttle logging here. @@ -287,6 +344,17 @@ public class BatterySaverStateMachine { } } + @GuardedBy("mLock") + private boolean isBatteryLowLocked() { + final boolean percentageLow = + mSettingAutomaticBatterySaver == PowerManager.POWER_SAVER_MODE_PERCENTAGE + && mIsBatteryLevelLow; + final boolean dynamicPowerSavingsLow = + mSettingAutomaticBatterySaver == PowerManager.POWER_SAVER_MODE_DYNAMIC + && mBatteryLevel <= mDynamicPowerSavingsDisableThreshold; + return percentageLow || dynamicPowerSavingsLow; + } + /** * Decide whether to auto-start / stop battery saver. */ @@ -299,12 +367,14 @@ public class BatterySaverStateMachine { + " mIsBatteryLevelLow=" + mIsBatteryLevelLow + " mBatterySaverSnoozing=" + mBatterySaverSnoozing + " mIsPowered=" + mIsPowered + + " mSettingAutomaticBatterySaver=" + mSettingAutomaticBatterySaver + " mSettingBatterySaverEnabledSticky=" + mSettingBatterySaverEnabledSticky); } if (!(mBootCompleted && mSettingsLoaded && mBatteryStatusSet)) { return; // Not fully initialized yet. } - if (!mIsBatteryLevelLow) { + + if (!isBatteryLowLocked()) { updateSnoozingLocked(false, "Battery not low"); } if (mIsPowered) { @@ -319,20 +389,35 @@ public class BatterySaverStateMachine { BatterySaverController.REASON_STICKY_RESTORE, "Sticky restore"); - } else if (mIsBatteryLevelLow) { - if (!mBatterySaverSnoozing && isAutoBatterySaverConfigured()) { + } else if (mSettingAutomaticBatterySaver + == PowerManager.POWER_SAVER_MODE_PERCENTAGE + && isAutoBatterySaverConfiguredLocked()) { + if (mIsBatteryLevelLow && !mBatterySaverSnoozing) { enableBatterySaverLocked(/*enable=*/ true, /*manual=*/ false, - BatterySaverController.REASON_AUTOMATIC_ON, - "Auto ON"); + BatterySaverController.REASON_PERCENTAGE_AUTOMATIC_ON, + "Percentage Auto ON"); + } else { + // Battery not low + enableBatterySaverLocked(/*enable=*/ false, /*manual=*/ false, + BatterySaverController.REASON_PERCENTAGE_AUTOMATIC_OFF, + "Percentage Auto OFF"); + } + } else if (mSettingAutomaticBatterySaver + == PowerManager.POWER_SAVER_MODE_DYNAMIC) { + if (mBatteryLevel >= mDynamicPowerSavingsDisableThreshold) { + enableBatterySaverLocked(/*enable=*/ false, /*manual=*/ false, + BatterySaverController.REASON_DYNAMIC_POWER_SAVINGS_AUTOMATIC_OFF, + "Dynamic Warning Auto OFF"); + } else if (mDynamicPowerSavingsBatterySaver && !mBatterySaverSnoozing) { + enableBatterySaverLocked(/*enable=*/ true, /*manual=*/ false, + BatterySaverController.REASON_DYNAMIC_POWER_SAVINGS_AUTOMATIC_ON, + "Dynamic Warning Auto ON"); } - } else { // Battery not low - enableBatterySaverLocked(/*enable=*/ false, /*manual=*/ false, - BatterySaverController.REASON_AUTOMATIC_OFF, - "Auto OFF"); } + // do nothing if automatic battery saver mode = PERCENTAGE and low warning threshold = 0% } - /** + /** * {@link com.android.server.power.PowerManagerService} calls it when * {@link android.os.PowerManager#setPowerSaveMode} is called. * @@ -383,7 +468,7 @@ public class BatterySaverStateMachine { // When battery saver is disabled manually (while battery saver is enabled) // when the battery level is low, we "snooze" BS -- i.e. disable auto battery saver. // We resume auto-BS once the battery level is not low, or the device is plugged in. - if (isBatterySaverEnabled() && mIsBatteryLevelLow) { + if (isBatterySaverEnabled() && isBatteryLowLocked()) { updateSnoozingLocked(true, "Manual snooze"); } } diff --git a/services/core/java/com/android/server/role/RoleManagerService.java b/services/core/java/com/android/server/role/RoleManagerService.java index b7d2ce29563e..ded075d5742c 100644 --- a/services/core/java/com/android/server/role/RoleManagerService.java +++ b/services/core/java/com/android/server/role/RoleManagerService.java @@ -104,12 +104,18 @@ public class RoleManagerService extends SystemService { @Override public void onStart() { publishBinderService(Context.ROLE_SERVICE, new Stub()); + //TODO add watch for new user creation and run default grants for them } @Override public void onStartUser(@UserIdInt int userId) { synchronized (mLock) { + //TODO only call into PermissionController if it or system upgreaded (for boot time) + // (add package changes watch; + // we can detect upgrade using build fingerprint and app version) getUserStateLocked(userId); + //TODO call permission grant policy here + Slog.i(LOG_TAG, "Granting default permissions..."); } } diff --git a/services/core/java/com/android/server/role/RoleUserState.java b/services/core/java/com/android/server/role/RoleUserState.java index caa7c2845ccb..becc9622dffb 100644 --- a/services/core/java/com/android/server/role/RoleUserState.java +++ b/services/core/java/com/android/server/role/RoleUserState.java @@ -73,7 +73,7 @@ public class RoleUserState { * Maps role names to its holders' package names. The values should never be null. */ @GuardedBy("RoleManagerService.mLock") - private ArrayMap<String, ArraySet<String>> mRoles = new ArrayMap<>(); + private ArrayMap<String, ArraySet<String>> mRoles = null; @GuardedBy("RoleManagerService.mLock") private boolean mDestroyed; @@ -188,7 +188,8 @@ public class RoleUserState { roles.put(roleName, roleHolders); } mWriteHandler.removeCallbacksAndMessages(null); - mWriteHandler.sendMessage(PooledLambda.obtainMessage(this::writeSync, version, roles)); + mWriteHandler.sendMessage(PooledLambda.obtainMessage( + RoleUserState::writeSync, this, version, roles)); } @WorkerThread diff --git a/services/core/java/com/android/server/stats/StatsCompanionService.java b/services/core/java/com/android/server/stats/StatsCompanionService.java index cef484f07972..01d02d61cc83 100644 --- a/services/core/java/com/android/server/stats/StatsCompanionService.java +++ b/services/core/java/com/android/server/stats/StatsCompanionService.java @@ -41,6 +41,9 @@ import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.UserInfo; import android.hardware.fingerprint.FingerprintManager; +import android.net.ConnectivityManager; +import android.net.Network; +import android.net.NetworkRequest; import android.net.NetworkStats; import android.net.wifi.IWifiManager; import android.net.wifi.WifiActivityEnergyInfo; @@ -271,6 +274,12 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { Slog.e(TAG, "cannot find thermalservice, no throttling push notifications"); } + // Default NetworkRequest should cover all transport types. + final NetworkRequest request = new NetworkRequest.Builder().build(); + final ConnectivityManager connectivityManager = + (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE); + connectivityManager.registerNetworkCallback(request, new ConnectivityStatsCallback()); + HandlerThread handlerThread = new HandlerThread(TAG); handlerThread.start(); mHandler = new CompanionHandler(handlerThread.getLooper()); @@ -1875,4 +1884,19 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { temp.getValue()); } } + + private static final class ConnectivityStatsCallback extends + ConnectivityManager.NetworkCallback { + @Override + public void onAvailable(Network network) { + StatsLog.write(StatsLog.CONNECTIVITY_STATE_CHANGED, network.netId, + StatsLog.CONNECTIVITY_STATE_CHANGED__STATE__CONNECTED); + } + + @Override + public void onLost(Network network) { + StatsLog.write(StatsLog.CONNECTIVITY_STATE_CHANGED, network.netId, + StatsLog.CONNECTIVITY_STATE_CHANGED__STATE__DISCONNECTED); + } + } } diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java index ec78560c9962..3e07ebea6a17 100644 --- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java +++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java @@ -37,6 +37,7 @@ import android.os.UserHandle; import android.service.notification.NotificationStats; import android.text.TextUtils; import android.util.ArrayMap; +import android.util.Log; import android.util.Slog; import com.android.internal.R; @@ -567,11 +568,11 @@ public class StatusBarManagerService extends IStatusBarService.Stub { @Override public void showBiometricDialog(Bundle bundle, IBiometricPromptReceiver receiver, int type, - boolean requireConfirmation) { + boolean requireConfirmation, int userId) { enforceBiometricDialog(); if (mBar != null) { try { - mBar.showBiometricDialog(bundle, receiver, type, requireConfirmation); + mBar.showBiometricDialog(bundle, receiver, type, requireConfirmation, userId); } catch (RemoteException ex) { } } @@ -671,6 +672,20 @@ public class StatusBarManagerService extends IStatusBarService.Stub { // Ensure state for the current user is applied, even if passed a non-current user. final int net1 = gatherDisableActionsLocked(mCurrentUserId, 1); final int net2 = gatherDisableActionsLocked(mCurrentUserId, 2); + + // TODO(b/113914868): investigation log for disappearing home button + if (whichFlag == 1 && pkg.contains("systemui")) { + String disabledData = "{ "; + for (int i = 0; i < mDisableRecords.size(); i++) { + DisableRecord tok = mDisableRecords.get(i); + disabledData += " ([" + i + "] " + tok + "), "; + } + disabledData += " }"; + Log.d(TAG, "disabledlocked (b/113914868): net1=" + net1 + ", mDisabled1=" + mDisabled1 + + ", token=" + token + ", mDisableRecords=" + mDisableRecords.size() + " => " + + disabledData); + } + if (net1 != mDisabled1 || net2 != mDisabled2) { mDisabled1 = net1; mDisabled2 = net2; diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java index d30cd1905115..3cece11c0f38 100644 --- a/services/core/java/com/android/server/wm/AppWindowToken.java +++ b/services/core/java/com/android/server/wm/AppWindowToken.java @@ -1749,6 +1749,7 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree .setName(getSurfaceControl() + " - animation-bounds") .setSize(getSurfaceWidth(), getSurfaceHeight()); final SurfaceControl boundsLayer = builder.build(); + t.setWindowCrop(boundsLayer, getSurfaceWidth(), getSurfaceHeight()); t.show(boundsLayer); return boundsLayer; } diff --git a/services/core/java/com/android/server/wm/BlackFrame.java b/services/core/java/com/android/server/wm/BlackFrame.java index e358ad5ed756..9633864ed77e 100644 --- a/services/core/java/com/android/server/wm/BlackFrame.java +++ b/services/core/java/com/android/server/wm/BlackFrame.java @@ -52,7 +52,7 @@ public class BlackFrame { .setColorLayer(true) .setParent(null) // TODO: Work-around for b/69259549 .build(); - + transaction.setWindowCrop(surface, w, h); transaction.setLayerStack(surface, dc.getDisplayId()); transaction.setAlpha(surface, 1); transaction.setLayer(surface, layer); diff --git a/services/core/java/com/android/server/wm/Dimmer.java b/services/core/java/com/android/server/wm/Dimmer.java index 65c8e96a0774..cc14afce7ff6 100644 --- a/services/core/java/com/android/server/wm/Dimmer.java +++ b/services/core/java/com/android/server/wm/Dimmer.java @@ -126,9 +126,10 @@ class Dimmer { DimState(SurfaceControl dimLayer) { mDimLayer = dimLayer; mDimming = true; - mSurfaceAnimator = new SurfaceAnimator(new DimAnimatable(dimLayer), () -> { + final DimAnimatable dimAnimatable = new DimAnimatable(dimLayer); + mSurfaceAnimator = new SurfaceAnimator(dimAnimatable, () -> { if (!mDimming) { - mDimLayer.destroy(); + dimAnimatable.getPendingTransaction().destroy(mDimLayer); } }, mHost.mService); } @@ -309,6 +310,7 @@ class Dimmer { // TODO: Once we use geometry from hierarchy this falls away. t.setSize(mDimState.mDimLayer, bounds.width(), bounds.height()); t.setPosition(mDimState.mDimLayer, bounds.left, bounds.top); + t.setWindowCrop(mDimState.mDimLayer, bounds.width(), bounds.height()); if (!mDimState.isVisible) { mDimState.isVisible = true; t.show(mDimState.mDimLayer); diff --git a/services/core/java/com/android/server/wm/Letterbox.java b/services/core/java/com/android/server/wm/Letterbox.java index 4eb021cd55dc..b49d304cf9a8 100644 --- a/services/core/java/com/android/server/wm/Letterbox.java +++ b/services/core/java/com/android/server/wm/Letterbox.java @@ -187,6 +187,7 @@ public class Letterbox { } t.setPosition(mSurface, mSurfaceFrame.left, mSurfaceFrame.top); t.setSize(mSurface, mSurfaceFrame.width(), mSurfaceFrame.height()); + t.setWindowCrop(mSurface, mSurfaceFrame.width(), mSurfaceFrame.height()); t.show(mSurface); } else if (mSurface != null) { t.hide(mSurface); diff --git a/services/core/java/com/android/server/wm/SurfaceAnimator.java b/services/core/java/com/android/server/wm/SurfaceAnimator.java index 3ea615a3b58a..66063c405943 100644 --- a/services/core/java/com/android/server/wm/SurfaceAnimator.java +++ b/services/core/java/com/android/server/wm/SurfaceAnimator.java @@ -16,12 +16,12 @@ package com.android.server.wm; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM; -import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; -import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; import static com.android.server.wm.SurfaceAnimatorProto.ANIMATION_ADAPTER; import static com.android.server.wm.SurfaceAnimatorProto.ANIMATION_START_DELAYED; import static com.android.server.wm.SurfaceAnimatorProto.LEASH; +import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM; +import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; +import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; import android.annotation.NonNull; import android.annotation.Nullable; @@ -305,6 +305,7 @@ class SurfaceAnimator { .setName(surface + " - animation-leash") .setSize(width, height); final SurfaceControl leash = builder.build(); + t.setWindowCrop(surface, width, height); if (!hidden) { t.show(leash); } diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java index 3493111a15e1..073601ddefc6 100644 --- a/services/core/java/com/android/server/wm/TaskStack.java +++ b/services/core/java/com/android/server/wm/TaskStack.java @@ -259,6 +259,7 @@ public class TaskStack extends WindowContainer<Task> implements final Rect stackBounds = getBounds(); getPendingTransaction() .setSize(mAnimationBackgroundSurface, mTmpRect.width(), mTmpRect.height()) + .setWindowCrop(mAnimationBackgroundSurface, mTmpRect.width(), mTmpRect.height()) .setPosition(mAnimationBackgroundSurface, mTmpRect.left - stackBounds.left, mTmpRect.top - stackBounds.top); scheduleAnimation(); @@ -789,6 +790,7 @@ public class TaskStack extends WindowContainer<Task> implements return; } transaction.setSize(mSurfaceControl, width, height); + transaction.setWindowCrop(mSurfaceControl, width, height); mLastSurfaceSize.set(width, height); } diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index b88165ef0f24..a7542d70c0e0 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -491,6 +491,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { */ final boolean mIsWatch; + /** + * Whether this device has the telephony feature. + */ + final boolean mHasTelephonyFeature; + private final CertificateMonitor mCertificateMonitor; private final SecurityLogMonitor mSecurityLogMonitor; @@ -2133,6 +2138,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { mHasFeature = mInjector.hasFeature(); mIsWatch = mInjector.getPackageManager() .hasSystemFeature(PackageManager.FEATURE_WATCH); + mHasTelephonyFeature = mInjector.getPackageManager() + .hasSystemFeature(PackageManager.FEATURE_TELEPHONY); mBackgroundHandler = BackgroundThread.getHandler(); // Needed when mHasFeature == false, because it controls the certificate warning text. @@ -12927,7 +12934,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override public int addOverrideApn(@NonNull ComponentName who, @NonNull ApnSetting apnSetting) { - if (!mHasFeature) { + if (!mHasFeature || !mHasTelephonyFeature) { return -1; } Preconditions.checkNotNull(who, "ComponentName is null in addOverrideApn"); @@ -12956,7 +12963,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override public boolean updateOverrideApn(@NonNull ComponentName who, int apnId, @NonNull ApnSetting apnSetting) { - if (!mHasFeature) { + if (!mHasFeature || !mHasTelephonyFeature) { return false; } Preconditions.checkNotNull(who, "ComponentName is null in updateOverrideApn"); @@ -12978,7 +12985,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override public boolean removeOverrideApn(@NonNull ComponentName who, int apnId) { - if (!mHasFeature) { + if (!mHasFeature || !mHasTelephonyFeature) { return false; } Preconditions.checkNotNull(who, "ComponentName is null in removeOverrideApn"); @@ -13004,7 +13011,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override public List<ApnSetting> getOverrideApns(@NonNull ComponentName who) { - if (!mHasFeature) { + if (!mHasFeature || !mHasTelephonyFeature) { return Collections.emptyList(); } Preconditions.checkNotNull(who, "ComponentName is null in getOverrideApns"); @@ -13040,7 +13047,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override public void setOverrideApnsEnabled(@NonNull ComponentName who, boolean enabled) { - if (!mHasFeature) { + if (!mHasFeature || !mHasTelephonyFeature) { return; } Preconditions.checkNotNull(who, "ComponentName is null in setOverrideApnEnabled"); @@ -13063,7 +13070,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override public boolean isOverrideApnEnabled(@NonNull ComponentName who) { - if (!mHasFeature) { + if (!mHasFeature || !mHasTelephonyFeature) { return false; } Preconditions.checkNotNull(who, "ComponentName is null in isOverrideApnEnabled"); diff --git a/services/intelligence/Android.bp b/services/intelligence/Android.bp new file mode 100644 index 000000000000..2df123500a54 --- /dev/null +++ b/services/intelligence/Android.bp @@ -0,0 +1,5 @@ +java_library_static { + name: "services.intelligence", + srcs: ["java/**/*.java"], + libs: ["services.core"], +} diff --git a/services/autofill/java/com/android/server/intelligence/ContentCaptureSession.java b/services/intelligence/java/com/android/server/intelligence/ContentCaptureSession.java index 9cab1ed15b9e..9cab1ed15b9e 100644 --- a/services/autofill/java/com/android/server/intelligence/ContentCaptureSession.java +++ b/services/intelligence/java/com/android/server/intelligence/ContentCaptureSession.java diff --git a/services/autofill/java/com/android/server/intelligence/IntelligenceManagerService.java b/services/intelligence/java/com/android/server/intelligence/IntelligenceManagerService.java index 43d4a4476c11..43d4a4476c11 100644 --- a/services/autofill/java/com/android/server/intelligence/IntelligenceManagerService.java +++ b/services/intelligence/java/com/android/server/intelligence/IntelligenceManagerService.java diff --git a/services/autofill/java/com/android/server/intelligence/IntelligencePerUserService.java b/services/intelligence/java/com/android/server/intelligence/IntelligencePerUserService.java index 584b872c64d0..584b872c64d0 100644 --- a/services/autofill/java/com/android/server/intelligence/IntelligencePerUserService.java +++ b/services/intelligence/java/com/android/server/intelligence/IntelligencePerUserService.java diff --git a/services/autofill/java/com/android/server/intelligence/RemoteIntelligenceService.java b/services/intelligence/java/com/android/server/intelligence/RemoteIntelligenceService.java index 9d241fbf820d..9d241fbf820d 100644 --- a/services/autofill/java/com/android/server/intelligence/RemoteIntelligenceService.java +++ b/services/intelligence/java/com/android/server/intelligence/RemoteIntelligenceService.java diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index 86eb6f3e4c42..73990f800ac1 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -118,6 +118,7 @@ import com.android.server.power.PowerManagerService; import com.android.server.power.ShutdownThread; import com.android.server.power.ThermalManagerService; import com.android.server.restrictions.RestrictionsManagerService; +import com.android.server.role.RoleManagerService; import com.android.server.security.KeyAttestationApplicationIdProviderService; import com.android.server.security.KeyChainSystemService; import com.android.server.soundtrigger.SoundTriggerService; @@ -1911,6 +1912,11 @@ public final class SystemServer { } traceEnd(); + // Grants default permissions and defines roles + traceBeginAndSlog("StartRoleManagerService"); + mSystemServiceManager.startService(RoleManagerService.class); + traceEnd(); + // No dependency on Webview preparation in system server. But this should // be completed before allowing 3rd party final String WEBVIEW_PREPARATION = "WebViewFactoryPreparation"; diff --git a/services/robotests/Android.mk b/services/robotests/Android.mk index e67f8d32fb6d..9ab06a129d88 100644 --- a/services/robotests/Android.mk +++ b/services/robotests/Android.mk @@ -12,10 +12,9 @@ # See the License for the specific language governing permissions and # limitations under the License. - -############################################################## -# FrameworksServicesLib app just for Robolectric test target # -############################################################## +################################################################### +# FrameworksServicesLib app just for Robolectric test target # +################################################################### LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) @@ -32,81 +31,51 @@ LOCAL_STATIC_JAVA_LIBRARIES := \ include $(BUILD_PACKAGE) -############################################## -# FrameworksServices Robolectric test target # -############################################## +################################################################### +# FrameworksServicesLib Robolectric test target. # +################################################################### include $(CLEAR_VARS) -# Dependency platform-robolectric-android-all-stubs below contains a bunch of Android classes as -# stubs that throw RuntimeExceptions when we use them. The goal is to include hidden APIs that -# weren't included in Robolectric's Android jar files. However, we are testing the framework itself -# here, so if we write stuff that is being used in the tests and exist in -# platform-robolectric-android-all-stubs, the class loader is going to pick up the latter, and thus -# we are going to test what we don't want. To solve this: -# -# 1. If the class being used should be visible to bundled apps: -# => Bypass the stubs target by including them in LOCAL_SRC_FILES and LOCAL_AIDL_INCLUDES -# (if aidl). -# -# 2. If it's not visible: -# => Remove the class from the stubs jar (common/robolectric/android-all/android-all-stubs.jar) -# and add the class path to -# common/robolectric/android-all/android-all-stubs_removed_classes.txt. -# +LOCAL_MODULE := FrameworksServicesRoboTests -INTERNAL_BACKUP := ../../core/java/com/android/internal/backup - -LOCAL_SRC_FILES := \ - $(call all-java-files-under, src) \ - $(call all-Iaidl-files-under, $(INTERNAL_BACKUP)) \ - $(call all-java-files-under, ../../core/java/android/app/backup) \ - $(call all-Iaidl-files-under, ../../core/java/android/app/backup) \ - $(call all-java-files-under, ../../core/java/android/util/proto) \ - ../../core/java/android/content/pm/PackageInfo.java \ - ../../core/java/android/app/IBackupAgent.aidl \ - ../../core/java/android/util/KeyValueSettingObserver.java \ - ../../core/java/android/content/pm/PackageParser.java \ - ../../core/java/android/content/pm/SigningInfo.java - -LOCAL_AIDL_INCLUDES := \ - $(call all-Iaidl-files-under, $(INTERNAL_BACKUP)) \ - $(call all-Iaidl-files-under, ../../core/java/android/app/backup) \ - ../../core/java/android/app/IBackupAgent.aidl +LOCAL_SRC_FILES := $(call all-java-files-under, src) -LOCAL_STATIC_JAVA_LIBRARIES := \ - platform-robolectric-android-all-stubs \ - android-support-test \ - guava \ - mockito-robolectric-prebuilt \ +LOCAL_RESOURCE_DIR := \ + $(LOCAL_PATH)/res + +LOCAL_JAVA_RESOURCE_DIRS := config + +# Include the testing libraries +LOCAL_JAVA_LIBRARIES := \ platform-test-annotations \ + robolectric_android-all-stub \ + Robolectric_all-target \ + mockito-robolectric-prebuilt \ truth-prebuilt \ testng -LOCAL_JAVA_LIBRARIES := \ - junit \ - platform-robolectric-3.6.2-prebuilt - LOCAL_INSTRUMENTATION_FOR := FrameworksServicesLib -LOCAL_MODULE := FrameworksServicesRoboTests LOCAL_MODULE_TAGS := optional include $(BUILD_STATIC_JAVA_LIBRARY) -############################################################### -# FrameworksServices runner target to run the previous target # -############################################################### +################################################################### +# FrameworksServicesLib runner target to run the previous target. # +################################################################### include $(CLEAR_VARS) LOCAL_MODULE := RunFrameworksServicesRoboTests -LOCAL_SDK_VERSION := current - -LOCAL_STATIC_JAVA_LIBRARIES := \ - FrameworksServicesRoboTests +LOCAL_JAVA_LIBRARIES := \ + FrameworksServicesRoboTests \ + platform-test-annotations \ + robolectric_android-all-stub \ + Robolectric_all-target \ + mockito-robolectric-prebuilt \ + truth-prebuilt \ + testng LOCAL_TEST_PACKAGE := FrameworksServicesLib -LOCAL_INSTRUMENT_SOURCE_DIRS := $(dir $(LOCAL_PATH))backup/java - -include prebuilts/misc/common/robolectric/3.6.2/run_robotests.mk +include external/robolectric-shadows/run_robotests.mk
\ No newline at end of file diff --git a/services/robotests/config/robolectric.properties b/services/robotests/config/robolectric.properties new file mode 100644 index 000000000000..850557a9b693 --- /dev/null +++ b/services/robotests/config/robolectric.properties @@ -0,0 +1 @@ +sdk=NEWEST_SDK
\ No newline at end of file diff --git a/services/robotests/src/android/app/backup/BackupUtilsTest.java b/services/robotests/src/android/app/backup/BackupUtilsTest.java index 04a2a14b50e9..099cde04bd5e 100644 --- a/services/robotests/src/android/app/backup/BackupUtilsTest.java +++ b/services/robotests/src/android/app/backup/BackupUtilsTest.java @@ -22,14 +22,11 @@ import android.app.backup.FullBackup.BackupScheme.PathWithRequiredFlags; import android.content.Context; import android.platform.test.annotations.Presubmit; -import com.android.server.testing.FrameworkRobolectricTestRunner; -import com.android.server.testing.SystemLoaderPackages; - import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; -import org.robolectric.annotation.Config; import org.robolectric.annotation.internal.DoNotInstrument; import java.io.File; @@ -38,9 +35,7 @@ import java.util.Collection; import java.util.stream.Collectors; import java.util.stream.Stream; -@RunWith(FrameworkRobolectricTestRunner.class) -@Config(manifest = Config.NONE, sdk = 26) -@SystemLoaderPackages({"android.app.backup"}) +@RunWith(RobolectricTestRunner.class) @Presubmit @DoNotInstrument public class BackupUtilsTest { diff --git a/services/robotests/src/com/android/server/backup/BackupAgentTimeoutParametersTest.java b/services/robotests/src/com/android/server/backup/BackupAgentTimeoutParametersTest.java index 0d2c2218eedf..5b226f36d565 100644 --- a/services/robotests/src/com/android/server/backup/BackupAgentTimeoutParametersTest.java +++ b/services/robotests/src/com/android/server/backup/BackupAgentTimeoutParametersTest.java @@ -25,22 +25,16 @@ import android.content.Context; import android.os.Handler; import android.platform.test.annotations.Presubmit; import android.provider.Settings; -import android.util.KeyValueSettingObserver; -import com.android.server.testing.FrameworkRobolectricTestRunner; -import com.android.server.testing.SystemLoaderClasses; -import com.android.server.testing.SystemLoaderPackages; + import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; -import org.robolectric.annotation.Config; /** Tests for {@link BackupAgentTimeoutParameters}. */ -@RunWith(FrameworkRobolectricTestRunner.class) -@Config(manifest = Config.NONE, sdk = 26) -@SystemLoaderPackages({"com.android.server.backup"}) -@SystemLoaderClasses({KeyValueSettingObserver.class}) +@RunWith(RobolectricTestRunner.class) @Presubmit public class BackupAgentTimeoutParametersTest { private ContentResolver mContentResolver; diff --git a/services/robotests/src/com/android/server/backup/BackupManagerConstantsTest.java b/services/robotests/src/com/android/server/backup/BackupManagerConstantsTest.java index 2a32c2eef6ca..affa1f3f97f3 100644 --- a/services/robotests/src/com/android/server/backup/BackupManagerConstantsTest.java +++ b/services/robotests/src/com/android/server/backup/BackupManagerConstantsTest.java @@ -23,21 +23,15 @@ import android.content.Context; import android.os.Handler; import android.platform.test.annotations.Presubmit; import android.provider.Settings; -import android.util.KeyValueSettingObserver; -import com.android.server.testing.FrameworkRobolectricTestRunner; -import com.android.server.testing.SystemLoaderClasses; -import com.android.server.testing.SystemLoaderPackages; + import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; -import org.robolectric.annotation.Config; -@RunWith(FrameworkRobolectricTestRunner.class) -@Config(manifest = Config.NONE, sdk = 26) -@SystemLoaderPackages({"com.android.server.backup"}) -@SystemLoaderClasses({KeyValueSettingObserver.class}) +@RunWith(RobolectricTestRunner.class) @Presubmit public class BackupManagerConstantsTest { private static final String PACKAGE_NAME = "some.package.name"; diff --git a/services/robotests/src/com/android/server/backup/BackupManagerServiceTest.java b/services/robotests/src/com/android/server/backup/BackupManagerServiceTest.java index de915ab0829c..c4cb59339aee 100644 --- a/services/robotests/src/com/android/server/backup/BackupManagerServiceTest.java +++ b/services/robotests/src/com/android/server/backup/BackupManagerServiceTest.java @@ -22,7 +22,9 @@ import static com.android.server.backup.testing.TransportData.d2dTransport; import static com.android.server.backup.testing.TransportData.localTransport; import static com.android.server.backup.testing.TransportTestUtils.setUpCurrentTransport; import static com.android.server.backup.testing.TransportTestUtils.setUpTransports; + import static com.google.common.truth.Truth.assertThat; + import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; @@ -45,24 +47,23 @@ import android.os.PowerManager; import android.os.PowerSaveState; import android.platform.test.annotations.Presubmit; import android.provider.Settings; + import com.android.server.backup.testing.BackupManagerServiceTestUtils; import com.android.server.backup.testing.TransportData; import com.android.server.backup.testing.TransportTestUtils.TransportMock; import com.android.server.backup.transport.TransportNotRegisteredException; -import com.android.server.testing.FrameworkRobolectricTestRunner; -import com.android.server.testing.SystemLoaderPackages; import com.android.server.testing.shadows.ShadowAppBackupUtils; import com.android.server.testing.shadows.ShadowBinder; import com.android.server.testing.shadows.ShadowKeyValueBackupJob; import com.android.server.testing.shadows.ShadowKeyValueBackupTask; -import java.io.File; -import java.util.List; + import org.junit.After; 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.RuntimeEnvironment; import org.robolectric.annotation.Config; import org.robolectric.annotation.Implements; @@ -71,9 +72,11 @@ import org.robolectric.shadows.ShadowLooper; import org.robolectric.shadows.ShadowPackageManager; import org.robolectric.shadows.ShadowSettings; -@RunWith(FrameworkRobolectricTestRunner.class) -@Config(manifest = Config.NONE, sdk = 26, shadows = {ShadowAppBackupUtils.class}) -@SystemLoaderPackages({"com.android.server.backup"}) +import java.io.File; +import java.util.List; + +@RunWith(RobolectricTestRunner.class) +@Config(shadows = {ShadowAppBackupUtils.class}) @Presubmit public class BackupManagerServiceTest { private static final String TAG = "BMSTest"; diff --git a/services/robotests/src/com/android/server/backup/KeyValueBackupJobTest.java b/services/robotests/src/com/android/server/backup/KeyValueBackupJobTest.java index dd0a58d5e98e..8e17209e1f50 100644 --- a/services/robotests/src/com/android/server/backup/KeyValueBackupJobTest.java +++ b/services/robotests/src/com/android/server/backup/KeyValueBackupJobTest.java @@ -22,19 +22,14 @@ import android.content.Context; import android.os.Handler; import android.platform.test.annotations.Presubmit; -import com.android.server.testing.FrameworkRobolectricTestRunner; -import com.android.server.testing.SystemLoaderPackages; - import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; -import org.robolectric.annotation.Config; -@RunWith(FrameworkRobolectricTestRunner.class) -@Config(manifest = Config.NONE, sdk = 26) -@SystemLoaderPackages({"com.android.server.backup"}) +@RunWith(RobolectricTestRunner.class) @Presubmit public class KeyValueBackupJobTest { private Context mContext; diff --git a/services/robotests/src/com/android/server/backup/TransportManagerTest.java b/services/robotests/src/com/android/server/backup/TransportManagerTest.java index 051a4a037816..693092da0334 100644 --- a/services/robotests/src/com/android/server/backup/TransportManagerTest.java +++ b/services/robotests/src/com/android/server/backup/TransportManagerTest.java @@ -56,17 +56,14 @@ import com.android.server.backup.transport.OnTransportRegisteredListener; import com.android.server.backup.transport.TransportClient; import com.android.server.backup.transport.TransportClientManager; import com.android.server.backup.transport.TransportNotRegisteredException; -import com.android.server.testing.FrameworkRobolectricTestRunner; -import com.android.server.testing.SystemLoaderPackages; -import com.android.server.testing.shadows.FrameworkShadowContextImpl; 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.RuntimeEnvironment; -import org.robolectric.annotation.Config; import org.robolectric.shadows.ShadowPackageManager; import java.util.ArrayList; @@ -75,12 +72,7 @@ import java.util.Objects; import java.util.Set; import java.util.stream.Stream; -@RunWith(FrameworkRobolectricTestRunner.class) -@Config( - manifest = Config.NONE, - sdk = 26, - shadows = {FrameworkShadowContextImpl.class}) -@SystemLoaderPackages({"com.android.server.backup"}) +@RunWith(RobolectricTestRunner.class) @Presubmit public class TransportManagerTest { private static final String PACKAGE_A = "some.package.a"; @@ -682,7 +674,7 @@ public class TransportManagerTest { transport.getTransportComponent().getPackageName(), ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); } - setUpTransports(transportSet.toArray(new TransportData[transportSet.size()])); + setUpTransports(transportSet.toArray(new TransportData[0])); TransportManager transportManager = createTransportManager(selectedTransport, transports); transportManager.registerTransports(); return transportManager; diff --git a/services/robotests/src/com/android/server/backup/encryption/chunk/ChunkHashTest.java b/services/robotests/src/com/android/server/backup/encryption/chunk/ChunkHashTest.java index 3b6e038ec8cb..3f57240bc0e9 100644 --- a/services/robotests/src/com/android/server/backup/encryption/chunk/ChunkHashTest.java +++ b/services/robotests/src/com/android/server/backup/encryption/chunk/ChunkHashTest.java @@ -19,17 +19,16 @@ package com.android.server.backup.encryption.chunk; import static com.google.common.truth.Truth.assertThat; import android.platform.test.annotations.Presubmit; -import com.android.server.testing.FrameworkRobolectricTestRunner; -import com.android.server.testing.SystemLoaderPackages; + import com.google.common.primitives.Bytes; -import java.util.Arrays; + import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.annotation.Config; +import org.robolectric.RobolectricTestRunner; + +import java.util.Arrays; -@RunWith(FrameworkRobolectricTestRunner.class) -@Config(manifest = Config.NONE, sdk = 26) -@SystemLoaderPackages({"com.android.server.backup"}) +@RunWith(RobolectricTestRunner.class) @Presubmit public class ChunkHashTest { private static final int HASH_LENGTH_BYTES = 256 / 8; diff --git a/services/robotests/src/com/android/server/backup/encryption/chunk/ChunkListingTest.java b/services/robotests/src/com/android/server/backup/encryption/chunk/ChunkListingTest.java index 383bf1d73416..4354db72554a 100644 --- a/services/robotests/src/com/android/server/backup/encryption/chunk/ChunkListingTest.java +++ b/services/robotests/src/com/android/server/backup/encryption/chunk/ChunkListingTest.java @@ -21,22 +21,20 @@ import static com.google.common.truth.Truth.assertThat; import android.platform.test.annotations.Presubmit; import android.util.proto.ProtoInputStream; import android.util.proto.ProtoOutputStream; + import com.android.internal.util.Preconditions; -import com.android.server.testing.FrameworkRobolectricTestRunner; -import com.android.server.testing.SystemLoaderPackages; + import com.google.common.base.Charsets; -import java.io.ByteArrayInputStream; -import java.util.Arrays; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.annotation.Config; +import org.robolectric.RobolectricTestRunner; + +import java.io.ByteArrayInputStream; +import java.util.Arrays; -@RunWith(FrameworkRobolectricTestRunner.class) -@Config(manifest = Config.NONE, sdk = 26) -// Include android.util.proto in addition to classes under test because the latest versions of -// android.util.proto.Proto{Input|Output}Stream are not part of Robolectric. -@SystemLoaderPackages({"com.android.server.backup", "android.util.proto"}) +@RunWith(RobolectricTestRunner.class) @Presubmit public class ChunkListingTest { private static final String CHUNK_A = "CHUNK_A"; diff --git a/services/robotests/src/com/android/server/backup/encryption/chunk/ChunkTest.java b/services/robotests/src/com/android/server/backup/encryption/chunk/ChunkTest.java index 1dd7dc834f9e..17c9a86169be 100644 --- a/services/robotests/src/com/android/server/backup/encryption/chunk/ChunkTest.java +++ b/services/robotests/src/com/android/server/backup/encryption/chunk/ChunkTest.java @@ -21,21 +21,18 @@ import static com.google.common.truth.Truth.assertThat; import android.platform.test.annotations.Presubmit; import android.util.proto.ProtoInputStream; import android.util.proto.ProtoOutputStream; -import com.android.server.testing.FrameworkRobolectricTestRunner; -import com.android.server.testing.SystemLoaderPackages; + import com.google.common.base.Charsets; -import java.io.ByteArrayInputStream; -import java.util.Arrays; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.annotation.Config; +import org.robolectric.RobolectricTestRunner; + +import java.io.ByteArrayInputStream; +import java.util.Arrays; -@RunWith(FrameworkRobolectricTestRunner.class) -@Config(manifest = Config.NONE, sdk = 26) -// Include android.util.proto in addition to classes under test because the latest versions of -// android.util.proto.Proto{Input|Output}Stream are not part of Robolectric. -@SystemLoaderPackages({"com.android.server.backup", "android.util.proto"}) +@RunWith(RobolectricTestRunner.class) @Presubmit public class ChunkTest { private static final String CHUNK_A = "CHUNK_A"; diff --git a/services/robotests/src/com/android/server/backup/encryption/chunk/EncryptedChunkOrderingTest.java b/services/robotests/src/com/android/server/backup/encryption/chunk/EncryptedChunkOrderingTest.java index 1cd1528b930c..0bf14174e5c3 100644 --- a/services/robotests/src/com/android/server/backup/encryption/chunk/EncryptedChunkOrderingTest.java +++ b/services/robotests/src/com/android/server/backup/encryption/chunk/EncryptedChunkOrderingTest.java @@ -19,16 +19,14 @@ package com.android.server.backup.encryption.chunk; import static com.google.common.truth.Truth.assertThat; import android.platform.test.annotations.Presubmit; -import com.android.server.testing.FrameworkRobolectricTestRunner; -import com.android.server.testing.SystemLoaderPackages; + import com.google.common.primitives.Bytes; + import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.annotation.Config; +import org.robolectric.RobolectricTestRunner; -@RunWith(FrameworkRobolectricTestRunner.class) -@Config(manifest = Config.NONE, sdk = 26) -@SystemLoaderPackages({"com.android.server.backup"}) +@RunWith(RobolectricTestRunner.class) @Presubmit public class EncryptedChunkOrderingTest { private static final byte[] TEST_BYTE_ARRAY_1 = new byte[] {1, 2, 3, 4, 5}; diff --git a/services/robotests/src/com/android/server/backup/encryption/chunking/ChunkEncryptorTest.java b/services/robotests/src/com/android/server/backup/encryption/chunking/ChunkEncryptorTest.java index 2cc3ef85d1ef..d0e5fb335da9 100644 --- a/services/robotests/src/com/android/server/backup/encryption/chunking/ChunkEncryptorTest.java +++ b/services/robotests/src/com/android/server/backup/encryption/chunking/ChunkEncryptorTest.java @@ -17,32 +17,35 @@ package com.android.server.backup.encryption.chunking; import static com.android.server.backup.testing.CryptoTestUtils.generateAesKey; + import static com.google.common.truth.Truth.assertThat; -import static java.nio.charset.StandardCharsets.UTF_8; + import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.mock; +import static java.nio.charset.StandardCharsets.UTF_8; + import android.platform.test.annotations.Presubmit; + import com.android.server.backup.encryption.chunk.ChunkHash; -import com.android.server.testing.FrameworkRobolectricTestRunner; -import com.android.server.testing.SystemLoaderPackages; -import java.security.SecureRandom; -import javax.crypto.Cipher; -import javax.crypto.Mac; -import javax.crypto.SecretKey; -import javax.crypto.spec.GCMParameterSpec; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; -import org.robolectric.annotation.Config; +import org.robolectric.RobolectricTestRunner; + +import java.security.SecureRandom; + +import javax.crypto.Cipher; +import javax.crypto.Mac; +import javax.crypto.SecretKey; +import javax.crypto.spec.GCMParameterSpec; -@RunWith(FrameworkRobolectricTestRunner.class) -@Config(manifest = Config.NONE, sdk = 26) -@SystemLoaderPackages({"com.android.server.backup"}) +@RunWith(RobolectricTestRunner.class) @Presubmit public class ChunkEncryptorTest { private static final String MAC_ALGORITHM = "HmacSHA256"; diff --git a/services/robotests/src/com/android/server/backup/encryption/chunking/ChunkHasherTest.java b/services/robotests/src/com/android/server/backup/encryption/chunking/ChunkHasherTest.java index 11796c01f37c..2bbbf2857146 100644 --- a/services/robotests/src/com/android/server/backup/encryption/chunking/ChunkHasherTest.java +++ b/services/robotests/src/com/android/server/backup/encryption/chunking/ChunkHasherTest.java @@ -19,20 +19,19 @@ package com.android.server.backup.encryption.chunking; import static com.google.common.truth.Truth.assertThat; import android.platform.test.annotations.Presubmit; + import com.android.server.backup.encryption.chunk.ChunkHash; -import com.android.server.testing.FrameworkRobolectricTestRunner; -import com.android.server.testing.SystemLoaderPackages; -import javax.crypto.Mac; -import javax.crypto.SecretKey; -import javax.crypto.spec.SecretKeySpec; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.annotation.Config; +import org.robolectric.RobolectricTestRunner; + +import javax.crypto.Mac; +import javax.crypto.SecretKey; +import javax.crypto.spec.SecretKeySpec; -@RunWith(FrameworkRobolectricTestRunner.class) -@Config(manifest = Config.NONE, sdk = 26) -@SystemLoaderPackages({"com.android.server.backup"}) +@RunWith(RobolectricTestRunner.class) @Presubmit public class ChunkHasherTest { private static final String KEY_ALGORITHM = "AES"; diff --git a/services/robotests/src/com/android/server/backup/encryption/chunking/EncryptedChunkTest.java b/services/robotests/src/com/android/server/backup/encryption/chunking/EncryptedChunkTest.java index c5f9b10c1aaf..8e801a133909 100644 --- a/services/robotests/src/com/android/server/backup/encryption/chunking/EncryptedChunkTest.java +++ b/services/robotests/src/com/android/server/backup/encryption/chunking/EncryptedChunkTest.java @@ -17,21 +17,22 @@ package com.android.server.backup.encryption.chunking; import static com.google.common.truth.Truth.assertThat; + import static org.testng.Assert.assertThrows; import android.platform.test.annotations.Presubmit; + import com.android.server.backup.encryption.chunk.ChunkHash; -import com.android.server.testing.FrameworkRobolectricTestRunner; -import com.android.server.testing.SystemLoaderPackages; + import com.google.common.primitives.Bytes; -import java.util.Arrays; + import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.annotation.Config; +import org.robolectric.RobolectricTestRunner; + +import java.util.Arrays; -@RunWith(FrameworkRobolectricTestRunner.class) -@Config(manifest = Config.NONE, sdk = 26) -@SystemLoaderPackages({"com.android.server.backup"}) +@RunWith(RobolectricTestRunner.class) @Presubmit public class EncryptedChunkTest { private static final byte[] CHUNK_HASH_1_BYTES = diff --git a/services/robotests/src/com/android/server/backup/encryption/chunking/InlineLengthsEncryptedChunkEncoderTest.java b/services/robotests/src/com/android/server/backup/encryption/chunking/InlineLengthsEncryptedChunkEncoderTest.java index b162557ed623..2f872beacd17 100644 --- a/services/robotests/src/com/android/server/backup/encryption/chunking/InlineLengthsEncryptedChunkEncoderTest.java +++ b/services/robotests/src/com/android/server/backup/encryption/chunking/InlineLengthsEncryptedChunkEncoderTest.java @@ -17,25 +17,25 @@ package com.android.server.backup.encryption.chunking; import static com.google.common.truth.Truth.assertThat; + import static org.mockito.Mockito.inOrder; import static org.mockito.Mockito.mock; import android.platform.test.annotations.Presubmit; + import com.android.server.backup.encryption.chunk.ChunkHash; import com.android.server.backup.encryption.chunk.ChunksMetadataProto; -import com.android.server.testing.FrameworkRobolectricTestRunner; -import com.android.server.testing.SystemLoaderPackages; -import java.util.Arrays; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InOrder; import org.mockito.Mock; -import org.robolectric.annotation.Config; +import org.robolectric.RobolectricTestRunner; + +import java.util.Arrays; -@RunWith(FrameworkRobolectricTestRunner.class) -@Config(manifest = Config.NONE, sdk = 26) -@SystemLoaderPackages({"com.android.server.backup"}) +@RunWith(RobolectricTestRunner.class) @Presubmit public class InlineLengthsEncryptedChunkEncoderTest { diff --git a/services/robotests/src/com/android/server/backup/encryption/chunking/LengthlessEncryptedChunkEncoderTest.java b/services/robotests/src/com/android/server/backup/encryption/chunking/LengthlessEncryptedChunkEncoderTest.java index b61dbe9008ce..978bddb7301a 100644 --- a/services/robotests/src/com/android/server/backup/encryption/chunking/LengthlessEncryptedChunkEncoderTest.java +++ b/services/robotests/src/com/android/server/backup/encryption/chunking/LengthlessEncryptedChunkEncoderTest.java @@ -17,25 +17,25 @@ package com.android.server.backup.encryption.chunking; import static com.google.common.truth.Truth.assertThat; + import static org.mockito.Mockito.inOrder; import static org.mockito.Mockito.mock; import android.platform.test.annotations.Presubmit; + import com.android.server.backup.encryption.chunk.ChunkHash; import com.android.server.backup.encryption.chunk.ChunksMetadataProto; -import com.android.server.testing.FrameworkRobolectricTestRunner; -import com.android.server.testing.SystemLoaderPackages; -import java.util.Arrays; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InOrder; import org.mockito.Mock; -import org.robolectric.annotation.Config; +import org.robolectric.RobolectricTestRunner; + +import java.util.Arrays; -@RunWith(FrameworkRobolectricTestRunner.class) -@Config(manifest = Config.NONE, sdk = 26) -@SystemLoaderPackages({"com.android.server.backup"}) +@RunWith(RobolectricTestRunner.class) @Presubmit public class LengthlessEncryptedChunkEncoderTest { private static final byte[] TEST_NONCE = @@ -74,7 +74,7 @@ public class LengthlessEncryptedChunkEncoderTest { } @Test - public void getChunkOrderingType_returnsExplicitStartsType() throws Exception { + public void getChunkOrderingType_returnsExplicitStartsType() { assertThat(mEncoder.getChunkOrderingType()).isEqualTo(ChunksMetadataProto.EXPLICIT_STARTS); } } diff --git a/services/robotests/src/com/android/server/backup/encryption/chunking/RawBackupWriterTest.java b/services/robotests/src/com/android/server/backup/encryption/chunking/RawBackupWriterTest.java index 8b54e1e78246..19ef8fb339ba 100644 --- a/services/robotests/src/com/android/server/backup/encryption/chunking/RawBackupWriterTest.java +++ b/services/robotests/src/com/android/server/backup/encryption/chunking/RawBackupWriterTest.java @@ -17,23 +17,23 @@ package com.android.server.backup.encryption.chunking; import static com.google.common.truth.Truth.assertThat; + import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.testng.Assert.assertThrows; import android.platform.test.annotations.Presubmit; -import com.android.server.testing.FrameworkRobolectricTestRunner; -import com.android.server.testing.SystemLoaderPackages; + import com.google.common.primitives.Bytes; -import java.io.ByteArrayOutputStream; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.annotation.Config; +import org.robolectric.RobolectricTestRunner; + +import java.io.ByteArrayOutputStream; -@RunWith(FrameworkRobolectricTestRunner.class) -@Config(manifest = Config.NONE, sdk = 26) -@SystemLoaderPackages({"com.android.server.backup"}) +@RunWith(RobolectricTestRunner.class) @Presubmit public class RawBackupWriterTest { private static final byte[] TEST_BYTES = {1, 2, 3, 4, 5, 6}; diff --git a/services/robotests/src/com/android/server/backup/encryption/chunking/cdc/ContentDefinedChunkerTest.java b/services/robotests/src/com/android/server/backup/encryption/chunking/cdc/ContentDefinedChunkerTest.java new file mode 100644 index 000000000000..77b734785424 --- /dev/null +++ b/services/robotests/src/com/android/server/backup/encryption/chunking/cdc/ContentDefinedChunkerTest.java @@ -0,0 +1,232 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.backup.encryption.chunking.cdc; + +import static com.android.server.backup.testing.CryptoTestUtils.generateAesKey; + +import static com.google.common.truth.Truth.assertThat; + +import static org.testng.Assert.assertThrows; + +import static java.nio.charset.StandardCharsets.UTF_8; + +import android.platform.test.annotations.Presubmit; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.security.GeneralSecurityException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Random; + +import javax.crypto.SecretKey; + +/** Tests for {@link ContentDefinedChunker}. */ +@RunWith(RobolectricTestRunner.class) +@Presubmit +public class ContentDefinedChunkerTest { + private static final int WINDOW_SIZE_BYTES = 31; + private static final int MIN_SIZE_BYTES = 40; + private static final int MAX_SIZE_BYTES = 300; + private static final String CHUNK_BOUNDARY = "<----------BOUNDARY----------->"; + private static final byte[] CHUNK_BOUNDARY_BYTES = CHUNK_BOUNDARY.getBytes(UTF_8); + private static final String CHUNK_1 = "This is the first chunk"; + private static final String CHUNK_2 = "And this is the second chunk"; + private static final String CHUNK_3 = "And finally here is the third chunk"; + private static final String SMALL_CHUNK = "12345678"; + + private FingerprintMixer mFingerprintMixer; + private RabinFingerprint64 mRabinFingerprint64; + private ContentDefinedChunker mChunker; + + /** Set up a {@link ContentDefinedChunker} and dependencies for use in the tests. */ + @Before + public void setUp() throws Exception { + SecretKey secretKey = generateAesKey(); + byte[] salt = new byte[FingerprintMixer.SALT_LENGTH_BYTES]; + Random random = new Random(); + random.nextBytes(salt); + mFingerprintMixer = new FingerprintMixer(secretKey, salt); + + mRabinFingerprint64 = new RabinFingerprint64(); + long chunkBoundaryFingerprint = calculateFingerprint(CHUNK_BOUNDARY_BYTES); + mChunker = + new ContentDefinedChunker( + MIN_SIZE_BYTES, + MAX_SIZE_BYTES, + mRabinFingerprint64, + mFingerprintMixer, + (fingerprint) -> fingerprint == chunkBoundaryFingerprint); + } + + /** + * Creating a {@link ContentDefinedChunker} with a minimum chunk size that is smaller than the + * window size should throw an {@link IllegalArgumentException}. + */ + @Test + public void create_withMinChunkSizeSmallerThanWindowSize_throwsIllegalArgumentException() { + assertThrows( + IllegalArgumentException.class, + () -> + new ContentDefinedChunker( + WINDOW_SIZE_BYTES - 1, + MAX_SIZE_BYTES, + mRabinFingerprint64, + mFingerprintMixer, + null)); + } + + /** + * Creating a {@link ContentDefinedChunker} with a maximum chunk size that is smaller than the + * minimum chunk size should throw an {@link IllegalArgumentException}. + */ + @Test + public void create_withMaxChunkSizeSmallerThanMinChunkSize_throwsIllegalArgumentException() { + assertThrows( + IllegalArgumentException.class, + () -> + new ContentDefinedChunker( + MIN_SIZE_BYTES, + MIN_SIZE_BYTES - 1, + mRabinFingerprint64, + mFingerprintMixer, + null)); + } + + /** + * {@link ContentDefinedChunker#chunkify(InputStream, Chunker.ChunkConsumer)} should split the + * input stream across chunk boundaries by default. + */ + @Test + public void chunkify_withLargeChunks_splitsIntoChunksAcrossBoundaries() throws Exception { + byte[] input = + (CHUNK_1 + CHUNK_BOUNDARY + CHUNK_2 + CHUNK_BOUNDARY + CHUNK_3).getBytes(UTF_8); + ByteArrayInputStream inputStream = new ByteArrayInputStream(input); + ArrayList<String> result = new ArrayList<>(); + + mChunker.chunkify(inputStream, (chunk) -> result.add(new String(chunk, UTF_8))); + + assertThat(result) + .containsExactly(CHUNK_1 + CHUNK_BOUNDARY, CHUNK_2 + CHUNK_BOUNDARY, CHUNK_3) + .inOrder(); + } + + /** Chunks should be combined across boundaries until they reach the minimum chunk size. */ + @Test + public void chunkify_withSmallChunks_combinesChunksUntilMinSize() throws Exception { + byte[] input = + (SMALL_CHUNK + CHUNK_BOUNDARY + CHUNK_2 + CHUNK_BOUNDARY + CHUNK_3).getBytes(UTF_8); + ByteArrayInputStream inputStream = new ByteArrayInputStream(input); + ArrayList<String> result = new ArrayList<>(); + + mChunker.chunkify(inputStream, (chunk) -> result.add(new String(chunk, UTF_8))); + + assertThat(result) + .containsExactly(SMALL_CHUNK + CHUNK_BOUNDARY + CHUNK_2 + CHUNK_BOUNDARY, CHUNK_3) + .inOrder(); + assertThat(result.get(0).length()).isAtLeast(MIN_SIZE_BYTES); + } + + /** Chunks can not be larger than the maximum chunk size. */ + @Test + public void chunkify_doesNotProduceChunksLargerThanMaxSize() throws Exception { + byte[] largeInput = new byte[MAX_SIZE_BYTES * 10]; + Arrays.fill(largeInput, "a".getBytes(UTF_8)[0]); + ByteArrayInputStream inputStream = new ByteArrayInputStream(largeInput); + ArrayList<String> result = new ArrayList<>(); + + mChunker.chunkify(inputStream, (chunk) -> result.add(new String(chunk, UTF_8))); + + byte[] expectedChunkBytes = new byte[MAX_SIZE_BYTES]; + Arrays.fill(expectedChunkBytes, "a".getBytes(UTF_8)[0]); + String expectedChunk = new String(expectedChunkBytes, UTF_8); + assertThat(result) + .containsExactly( + expectedChunk, + expectedChunk, + expectedChunk, + expectedChunk, + expectedChunk, + expectedChunk, + expectedChunk, + expectedChunk, + expectedChunk, + expectedChunk) + .inOrder(); + } + + /** + * If the input stream signals zero availablility, {@link + * ContentDefinedChunker#chunkify(InputStream, Chunker.ChunkConsumer)} should still work. + */ + @Test + public void chunkify_withInputStreamReturningZeroAvailability_returnsChunks() throws Exception { + byte[] input = (SMALL_CHUNK + CHUNK_BOUNDARY + CHUNK_2).getBytes(UTF_8); + ZeroAvailabilityInputStream zeroAvailabilityInputStream = + new ZeroAvailabilityInputStream(input); + ArrayList<String> result = new ArrayList<>(); + + mChunker.chunkify( + zeroAvailabilityInputStream, (chunk) -> result.add(new String(chunk, UTF_8))); + + assertThat(result).containsExactly(SMALL_CHUNK + CHUNK_BOUNDARY + CHUNK_2).inOrder(); + } + + /** + * {@link ContentDefinedChunker#chunkify(InputStream, Chunker.ChunkConsumer)} should rethrow any + * exception thrown by its consumer. + */ + @Test + public void chunkify_whenConsumerThrowsException_rethrowsException() throws Exception { + ByteArrayInputStream inputStream = new ByteArrayInputStream(new byte[] {1}); + + assertThrows( + GeneralSecurityException.class, + () -> + mChunker.chunkify( + inputStream, + (chunk) -> { + throw new GeneralSecurityException(); + })); + } + + private long calculateFingerprint(byte[] bytes) { + long fingerprint = 0; + for (byte inByte : bytes) { + fingerprint = + mRabinFingerprint64.computeFingerprint64( + /*inChar=*/ inByte, /*outChar=*/ (byte) 0, fingerprint); + } + return mFingerprintMixer.mix(fingerprint); + } + + private static class ZeroAvailabilityInputStream extends ByteArrayInputStream { + ZeroAvailabilityInputStream(byte[] wrapped) { + super(wrapped); + } + + @Override + public synchronized int available() { + return 0; + } + } +} diff --git a/services/robotests/src/com/android/server/backup/encryption/chunking/cdc/FingerprintMixerTest.java b/services/robotests/src/com/android/server/backup/encryption/chunking/cdc/FingerprintMixerTest.java new file mode 100644 index 000000000000..936b5dca033d --- /dev/null +++ b/services/robotests/src/com/android/server/backup/encryption/chunking/cdc/FingerprintMixerTest.java @@ -0,0 +1,205 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.backup.encryption.chunking.cdc; + +import static com.google.common.truth.Truth.assertThat; + +import static org.testng.Assert.assertThrows; + +import android.platform.test.annotations.Presubmit; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; + +import java.security.InvalidKeyException; +import java.security.Key; +import java.util.HashSet; +import java.util.Random; + +import javax.crypto.SecretKey; +import javax.crypto.spec.SecretKeySpec; + +/** Tests for {@link FingerprintMixer}. */ +@RunWith(RobolectricTestRunner.class) +@Presubmit +public class FingerprintMixerTest { + private static final String KEY_ALGORITHM = "AES"; + private static final int SEED = 42; + private static final int SALT_LENGTH_BYTES = 256 / 8; + private static final int KEY_SIZE_BITS = 256; + + private Random mSeededRandom; + private FingerprintMixer mFingerprintMixer; + + /** Set up a {@link FingerprintMixer} with deterministic key and salt generation. */ + @Before + public void setUp() throws Exception { + // Seed so that the tests are deterministic. + mSeededRandom = new Random(SEED); + mFingerprintMixer = new FingerprintMixer(randomKey(), randomSalt()); + } + + /** + * Construcing a {@link FingerprintMixer} with a salt that is too small should throw an {@link + * IllegalArgumentException}. + */ + @Test + public void create_withIncorrectSaltSize_throwsIllegalArgumentException() { + byte[] tooSmallSalt = new byte[SALT_LENGTH_BYTES - 1]; + + assertThrows( + IllegalArgumentException.class, + () -> new FingerprintMixer(randomKey(), tooSmallSalt)); + } + + /** + * Constructing a {@link FingerprintMixer} with a secret key that can't be encoded should throw + * an {@link InvalidKeyException}. + */ + @Test + public void create_withUnencodableSecretKey_throwsInvalidKeyException() { + byte[] keyBytes = new byte[KEY_SIZE_BITS / 8]; + UnencodableSecretKeySpec keySpec = + new UnencodableSecretKeySpec(keyBytes, 0, keyBytes.length, KEY_ALGORITHM); + + assertThrows(InvalidKeyException.class, () -> new FingerprintMixer(keySpec, randomSalt())); + } + + /** + * {@link FingerprintMixer#getAddend()} should not return the same addend for two different + * keys. + */ + @Test + public void getAddend_withDifferentKey_returnsDifferentResult() throws Exception { + int iterations = 100_000; + HashSet<Long> returnedAddends = new HashSet<>(); + byte[] salt = randomSalt(); + + for (int i = 0; i < iterations; i++) { + FingerprintMixer fingerprintMixer = new FingerprintMixer(randomKey(), salt); + long addend = fingerprintMixer.getAddend(); + returnedAddends.add(addend); + } + + assertThat(returnedAddends).containsNoDuplicates(); + } + + /** + * {@link FingerprintMixer#getMultiplicand()} should not return the same multiplicand for two + * different keys. + */ + @Test + public void getMultiplicand_withDifferentKey_returnsDifferentResult() throws Exception { + int iterations = 100_000; + HashSet<Long> returnedMultiplicands = new HashSet<>(); + byte[] salt = randomSalt(); + + for (int i = 0; i < iterations; i++) { + FingerprintMixer fingerprintMixer = new FingerprintMixer(randomKey(), salt); + long multiplicand = fingerprintMixer.getMultiplicand(); + returnedMultiplicands.add(multiplicand); + } + + assertThat(returnedMultiplicands).containsNoDuplicates(); + } + + /** The multiplicant returned by {@link FingerprintMixer} should always be odd. */ + @Test + public void getMultiplicand_isOdd() throws Exception { + int iterations = 100_000; + + for (int i = 0; i < iterations; i++) { + FingerprintMixer fingerprintMixer = new FingerprintMixer(randomKey(), randomSalt()); + + long multiplicand = fingerprintMixer.getMultiplicand(); + + assertThat(isOdd(multiplicand)).isTrue(); + } + } + + /** {@link FingerprintMixer#mix(long)} should have a random distribution. */ + @Test + public void mix_randomlyDistributesBits() throws Exception { + int iterations = 100_000; + float tolerance = 0.1f; + int[] totals = new int[64]; + + for (int i = 0; i < iterations; i++) { + long n = mFingerprintMixer.mix(mSeededRandom.nextLong()); + for (int j = 0; j < 64; j++) { + int bit = (int) (n >> j & 1); + totals[j] += bit; + } + } + + for (int i = 0; i < 64; i++) { + float mean = ((float) totals[i]) / iterations; + float diff = Math.abs(mean - 0.5f); + assertThat(diff).isLessThan(tolerance); + } + } + + /** + * {@link FingerprintMixer#mix(long)} should always produce a number that's different from the + * input. + */ + @Test + public void mix_doesNotProduceSameNumberAsInput() { + int iterations = 100_000; + + for (int i = 0; i < iterations; i++) { + assertThat(mFingerprintMixer.mix(i)).isNotEqualTo(i); + } + } + + private byte[] randomSalt() { + byte[] salt = new byte[SALT_LENGTH_BYTES]; + mSeededRandom.nextBytes(salt); + return salt; + } + + /** + * Not a secure way of generating keys. We want to deterministically generate the same keys for + * each test run, though, to ensure the test is deterministic. + */ + private SecretKey randomKey() { + byte[] keyBytes = new byte[KEY_SIZE_BITS / 8]; + mSeededRandom.nextBytes(keyBytes); + return new SecretKeySpec(keyBytes, 0, keyBytes.length, KEY_ALGORITHM); + } + + private static boolean isOdd(long n) { + return Math.abs(n % 2) == 1; + } + + /** + * Subclass of {@link SecretKeySpec} that does not provide an encoded version. As per its + * contract in {@link Key}, that means {@code getEncoded()} always returns null. + */ + private class UnencodableSecretKeySpec extends SecretKeySpec { + UnencodableSecretKeySpec(byte[] key, int offset, int len, String algorithm) { + super(key, offset, len, algorithm); + } + + @Override + public byte[] getEncoded() { + return null; + } + } +} diff --git a/services/robotests/src/com/android/server/backup/encryption/chunking/cdc/HkdfTest.java b/services/robotests/src/com/android/server/backup/encryption/chunking/cdc/HkdfTest.java new file mode 100644 index 000000000000..549437454e9c --- /dev/null +++ b/services/robotests/src/com/android/server/backup/encryption/chunking/cdc/HkdfTest.java @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.backup.encryption.chunking.cdc; + +import static com.google.common.truth.Truth.assertThat; + +import static org.testng.Assert.assertThrows; + +import android.platform.test.annotations.Presubmit; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; + +/** Tests for {@link Hkdf}. */ +@RunWith(RobolectricTestRunner.class) +@Presubmit +public class HkdfTest { + /** HKDF Test Case 1 IKM from RFC 5869 */ + private static final byte[] HKDF_CASE1_IKM = { + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, + 0x0b, 0x0b + }; + + /** HKDF Test Case 1 salt from RFC 5869 */ + private static final byte[] HKDF_CASE1_SALT = { + 0x00, 0x01, 0x02, 0x03, 0x04, + 0x05, 0x06, 0x07, 0x08, 0x09, + 0x0a, 0x0b, 0x0c + }; + + /** HKDF Test Case 1 info from RFC 5869 */ + private static final byte[] HKDF_CASE1_INFO = { + (byte) 0xf0, (byte) 0xf1, (byte) 0xf2, (byte) 0xf3, (byte) 0xf4, + (byte) 0xf5, (byte) 0xf6, (byte) 0xf7, (byte) 0xf8, (byte) 0xf9 + }; + + /** First 32 bytes of HKDF Test Case 1 OKM (output) from RFC 5869 */ + private static final byte[] HKDF_CASE1_OKM = { + (byte) 0x3c, (byte) 0xb2, (byte) 0x5f, (byte) 0x25, (byte) 0xfa, + (byte) 0xac, (byte) 0xd5, (byte) 0x7a, (byte) 0x90, (byte) 0x43, + (byte) 0x4f, (byte) 0x64, (byte) 0xd0, (byte) 0x36, (byte) 0x2f, + (byte) 0x2a, (byte) 0x2d, (byte) 0x2d, (byte) 0x0a, (byte) 0x90, + (byte) 0xcf, (byte) 0x1a, (byte) 0x5a, (byte) 0x4c, (byte) 0x5d, + (byte) 0xb0, (byte) 0x2d, (byte) 0x56, (byte) 0xec, (byte) 0xc4, + (byte) 0xc5, (byte) 0xbf + }; + + /** Test the example from RFC 5869. */ + @Test + public void hkdf_derivesKeyMaterial() throws Exception { + byte[] result = Hkdf.hkdf(HKDF_CASE1_IKM, HKDF_CASE1_SALT, HKDF_CASE1_INFO); + + assertThat(result).isEqualTo(HKDF_CASE1_OKM); + } + + /** Providing a key that is null should throw a {@link java.lang.NullPointerException}. */ + @Test + public void hkdf_withNullKey_throwsNullPointerException() throws Exception { + assertThrows( + NullPointerException.class, + () -> Hkdf.hkdf(null, HKDF_CASE1_SALT, HKDF_CASE1_INFO)); + } + + /** Providing a salt that is null should throw a {@link java.lang.NullPointerException}. */ + @Test + public void hkdf_withNullSalt_throwsNullPointerException() throws Exception { + assertThrows( + NullPointerException.class, () -> Hkdf.hkdf(HKDF_CASE1_IKM, null, HKDF_CASE1_INFO)); + } + + /** Providing data that is null should throw a {@link java.lang.NullPointerException}. */ + @Test + public void hkdf_withNullData_throwsNullPointerException() throws Exception { + assertThrows( + NullPointerException.class, () -> Hkdf.hkdf(HKDF_CASE1_IKM, HKDF_CASE1_SALT, null)); + } +} diff --git a/services/robotests/src/com/android/server/backup/encryption/chunking/cdc/IsChunkBreakpointTest.java b/services/robotests/src/com/android/server/backup/encryption/chunking/cdc/IsChunkBreakpointTest.java new file mode 100644 index 000000000000..277dc372e73c --- /dev/null +++ b/services/robotests/src/com/android/server/backup/encryption/chunking/cdc/IsChunkBreakpointTest.java @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.backup.encryption.chunking.cdc; + +import static com.google.common.truth.Truth.assertThat; + +import static org.testng.Assert.assertThrows; + +import android.platform.test.annotations.Presubmit; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; + +import java.util.Random; + +/** Tests for {@link IsChunkBreakpoint}. */ +@RunWith(RobolectricTestRunner.class) +@Presubmit +public class IsChunkBreakpointTest { + private static final int RANDOM_SEED = 42; + private static final double TOLERANCE = 0.01; + private static final int NUMBER_OF_TESTS = 10000; + private static final int BITS_PER_LONG = 64; + + private Random mRandom; + + /** Make sure that tests are deterministic. */ + @Before + public void setUp() { + mRandom = new Random(RANDOM_SEED); + } + + /** + * Providing a negative average number of trials should throw an {@link + * IllegalArgumentException}. + */ + @Test + public void create_withNegativeAverageNumberOfTrials_throwsIllegalArgumentException() { + assertThrows(IllegalArgumentException.class, () -> new IsChunkBreakpoint(-1)); + } + + // Note: the following three tests are compute-intensive, so be cautious adding more. + + /** + * If the provided average number of trials is zero, a breakpoint should be expected after one + * trial on average. + */ + @Test + public void + isBreakpoint_withZeroAverageNumberOfTrials_isTrueOnAverageAfterOneTrial() { + assertExpectedTrials(new IsChunkBreakpoint(0), /*expectedTrials=*/ 1); + } + + /** + * If the provided average number of trials is 512, a breakpoint should be expected after 512 + * trials on average. + */ + @Test + public void + isBreakpoint_with512AverageNumberOfTrials_isTrueOnAverageAfter512Trials() { + assertExpectedTrials(new IsChunkBreakpoint(512), /*expectedTrials=*/ 512); + } + + /** + * If the provided average number of trials is 1024, a breakpoint should be expected after 1024 + * trials on average. + */ + @Test + public void + isBreakpoint_with1024AverageNumberOfTrials_isTrueOnAverageAfter1024Trials() { + assertExpectedTrials(new IsChunkBreakpoint(1024), /*expectedTrials=*/ 1024); + } + + /** The number of leading zeros should be the logarithm of the average number of trials. */ + @Test + public void getLeadingZeros_squaredIsAverageNumberOfTrials() { + for (int i = 0; i < BITS_PER_LONG; i++) { + long averageNumberOfTrials = (long) Math.pow(2, i); + + int leadingZeros = new IsChunkBreakpoint(averageNumberOfTrials).getLeadingZeros(); + + assertThat(leadingZeros).isEqualTo(i); + } + } + + private void assertExpectedTrials(IsChunkBreakpoint isChunkBreakpoint, long expectedTrials) { + long sum = 0; + for (int i = 0; i < NUMBER_OF_TESTS; i++) { + sum += numberOfTrialsTillBreakpoint(isChunkBreakpoint); + } + long averageTrials = sum / NUMBER_OF_TESTS; + assertThat((double) Math.abs(averageTrials - expectedTrials)) + .isLessThan(TOLERANCE * expectedTrials); + } + + private int numberOfTrialsTillBreakpoint(IsChunkBreakpoint isChunkBreakpoint) { + int trials = 0; + + while (true) { + trials++; + if (isChunkBreakpoint.isBreakpoint(mRandom.nextLong())) { + return trials; + } + } + } +} diff --git a/services/robotests/src/com/android/server/backup/encryption/chunking/cdc/RabinFingerprint64Test.java b/services/robotests/src/com/android/server/backup/encryption/chunking/cdc/RabinFingerprint64Test.java new file mode 100644 index 000000000000..729580cf5101 --- /dev/null +++ b/services/robotests/src/com/android/server/backup/encryption/chunking/cdc/RabinFingerprint64Test.java @@ -0,0 +1,132 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.backup.encryption.chunking.cdc; + +import static com.google.common.truth.Truth.assertThat; + +import static java.nio.charset.StandardCharsets.UTF_8; + +import android.platform.test.annotations.Presubmit; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; + +/** Tests for {@link RabinFingerprint64}. */ +@RunWith(RobolectricTestRunner.class) +@Presubmit +public class RabinFingerprint64Test { + private static final int WINDOW_SIZE = 31; + private static final ImmutableList<String> TEST_STRINGS = + ImmutableList.of( + "ervHTtChYXO6eXivYqThlyyzqkbRaOR", + "IxaVunH9ZC3qneWfhj1GkBH4ys9CYqz", + "wZRVjlE1p976icCFPX9pibk4PEBvjSH", + "pHIVaT8x8If9D6s9croksgNmJpmGYWI"); + + private final RabinFingerprint64 mRabinFingerprint64 = new RabinFingerprint64(); + + /** + * No matter where in the input buffer a string occurs, {@link + * RabinFingerprint64#computeFingerprint64(byte, byte, long)} should return the same + * fingerprint. + */ + @Test + public void computeFingerprint64_forSameWindow_returnsSameFingerprint() { + long fingerprint1 = + computeFingerprintAtPosition(getBytes(TEST_STRINGS.get(0)), WINDOW_SIZE - 1); + long fingerprint2 = + computeFingerprintAtPosition( + getBytes(TEST_STRINGS.get(1), TEST_STRINGS.get(0)), WINDOW_SIZE * 2 - 1); + long fingerprint3 = + computeFingerprintAtPosition( + getBytes(TEST_STRINGS.get(2), TEST_STRINGS.get(3), TEST_STRINGS.get(0)), + WINDOW_SIZE * 3 - 1); + String stub = "abc"; + long fingerprint4 = + computeFingerprintAtPosition( + getBytes(stub, TEST_STRINGS.get(0)), WINDOW_SIZE + stub.length() - 1); + + // Assert that all fingerprints are exactly the same + assertThat(ImmutableSet.of(fingerprint1, fingerprint2, fingerprint3, fingerprint4)) + .hasSize(1); + } + + /** The computed fingerprint should be different for different inputs. */ + @Test + public void computeFingerprint64_withDifferentInput_returnsDifferentFingerprint() { + long fingerprint1 = computeFingerprintOf(TEST_STRINGS.get(0)); + long fingerprint2 = computeFingerprintOf(TEST_STRINGS.get(1)); + long fingerprint3 = computeFingerprintOf(TEST_STRINGS.get(2)); + long fingerprint4 = computeFingerprintOf(TEST_STRINGS.get(3)); + + assertThat(ImmutableList.of(fingerprint1, fingerprint2, fingerprint3, fingerprint4)) + .containsNoDuplicates(); + } + + /** + * An input with the same characters in a different order should return a different fingerprint. + */ + @Test + public void computeFingerprint64_withSameInputInDifferentOrder_returnsDifferentFingerprint() { + long fingerprint1 = computeFingerprintOf("abcdefghijklmnopqrstuvwxyz12345"); + long fingerprint2 = computeFingerprintOf("54321zyxwvutsrqponmlkjihgfedcba"); + long fingerprint3 = computeFingerprintOf("4bcdefghijklmnopqrstuvwxyz123a5"); + long fingerprint4 = computeFingerprintOf("bacdefghijklmnopqrstuvwxyz12345"); + + assertThat(ImmutableList.of(fingerprint1, fingerprint2, fingerprint3, fingerprint4)) + .containsNoDuplicates(); + } + + /** UTF-8 bytes of all the given strings in order. */ + private byte[] getBytes(String... strings) { + StringBuilder sb = new StringBuilder(); + for (String s : strings) { + sb.append(s); + } + return sb.toString().getBytes(UTF_8); + } + + /** + * The Rabin fingerprint of a window of bytes ending at {@code position} in the {@code bytes} + * array. + */ + private long computeFingerprintAtPosition(byte[] bytes, int position) { + assertThat(position).isAtMost(bytes.length - 1); + long fingerprint = 0; + for (int i = 0; i <= position; i++) { + byte outChar; + if (i >= WINDOW_SIZE) { + outChar = bytes[i - WINDOW_SIZE]; + } else { + outChar = (byte) 0; + } + fingerprint = + mRabinFingerprint64.computeFingerprint64( + /*inChar=*/ bytes[i], outChar, fingerprint); + } + return fingerprint; + } + + private long computeFingerprintOf(String s) { + assertThat(s.length()).isEqualTo(WINDOW_SIZE); + return computeFingerprintAtPosition(s.getBytes(UTF_8), WINDOW_SIZE - 1); + } +} diff --git a/services/robotests/src/com/android/server/backup/fullbackup/AppMetadataBackupWriterTest.java b/services/robotests/src/com/android/server/backup/fullbackup/AppMetadataBackupWriterTest.java index b771039b2936..fd7ced2d58b6 100644 --- a/services/robotests/src/com/android/server/backup/fullbackup/AppMetadataBackupWriterTest.java +++ b/services/robotests/src/com/android/server/backup/fullbackup/AppMetadataBackupWriterTest.java @@ -7,6 +7,7 @@ import static com.android.server.backup.BackupManagerService.BACKUP_METADATA_VER import static com.android.server.backup.BackupManagerService.BACKUP_WIDGET_METADATA_TOKEN; import static com.google.common.truth.Truth.assertThat; + import static org.robolectric.Shadows.shadowOf; import static org.testng.Assert.expectThrows; @@ -21,52 +22,47 @@ import android.content.pm.PackageParser.SigningDetails; import android.content.pm.Signature; import android.content.pm.SigningInfo; import android.os.Build; -import android.os.Build.VERSION_CODES; import android.os.Environment; import android.os.ParcelFileDescriptor; import android.os.UserHandle; -import com.android.server.testing.FrameworkRobolectricTestRunner; -import com.android.server.testing.SystemLoaderClasses; -import com.android.server.testing.SystemLoaderPackages; import com.android.server.testing.shadows.ShadowBackupDataInput; import com.android.server.testing.shadows.ShadowBackupDataOutput; import com.android.server.testing.shadows.ShadowFullBackup; -import java.io.ByteArrayOutputStream; -import java.io.DataOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.attribute.FileTime; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; import org.robolectric.shadows.ShadowApplicationPackageManager; import org.robolectric.shadows.ShadowEnvironment; -@RunWith(FrameworkRobolectricTestRunner.class) +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.attribute.FileTime; + +@RunWith(RobolectricTestRunner.class) @Config( - manifest = Config.NONE, - sdk = 26, shadows = { ShadowBackupDataInput.class, ShadowBackupDataOutput.class, ShadowEnvironment.class, ShadowFullBackup.class, }) -@SystemLoaderPackages({"com.android.server.backup", "android.app.backup"}) -@SystemLoaderClasses({PackageInfo.class, SigningInfo.class}) public class AppMetadataBackupWriterTest { private static final String TEST_PACKAGE = "com.test.package"; private static final String TEST_PACKAGE_INSTALLER = "com.test.package.installer"; private static final Long TEST_PACKAGE_VERSION_CODE = 100L; + private PackageManager mPackageManager; private ShadowApplicationPackageManager mShadowPackageManager; private File mFilesDir; private File mBackupDataOutputFile; @@ -76,8 +72,8 @@ public class AppMetadataBackupWriterTest { public void setUp() throws Exception { Application application = RuntimeEnvironment.application; - PackageManager packageManager = application.getPackageManager(); - mShadowPackageManager = (ShadowApplicationPackageManager) shadowOf(packageManager); + mPackageManager = application.getPackageManager(); + mShadowPackageManager = (ShadowApplicationPackageManager) shadowOf(mPackageManager); mFilesDir = RuntimeEnvironment.application.getFilesDir(); mBackupDataOutputFile = new File(mFilesDir, "output"); @@ -87,7 +83,7 @@ public class AppMetadataBackupWriterTest { mBackupDataOutputFile, ParcelFileDescriptor.MODE_READ_WRITE); FullBackupDataOutput output = new FullBackupDataOutput(pfd, /* quota */ -1, /* transportFlags */ 0); - mBackupWriter = new AppMetadataBackupWriter(output, packageManager); + mBackupWriter = new AppMetadataBackupWriter(output, mPackageManager); } @After @@ -211,36 +207,6 @@ public class AppMetadataBackupWriterTest { * N* (signature byte array in ascii format per Signature.toCharsString()) * </pre> */ - @Config(sdk = VERSION_CODES.O) - @Test - public void testBackupManifest_whenApiO_writesCorrectApi() throws Exception { - PackageInfo packageInfo = - createPackageInfo(TEST_PACKAGE, TEST_PACKAGE_INSTALLER, TEST_PACKAGE_VERSION_CODE); - File manifestFile = createFile(BACKUP_MANIFEST_FILENAME); - - mBackupWriter.backupManifest(packageInfo, manifestFile, mFilesDir, /* withApk */ false); - - byte[] manifestBytes = getWrittenBytes(mBackupDataOutputFile, /* includeTarHeader */ false); - String[] manifest = new String(manifestBytes, StandardCharsets.UTF_8).split("\n"); - assertThat(manifest.length).isEqualTo(7); - assertThat(manifest[3]).isEqualTo(Integer.toString(VERSION_CODES.O)); // platform version - manifestFile.delete(); - } - - /** - * The manifest format is: - * - * <pre> - * BACKUP_MANIFEST_VERSION - * package name - * package version code - * platform version code - * installer package name (can be empty) - * boolean (1 if archive includes .apk, otherwise 0) - * # of signatures N - * N* (signature byte array in ascii format per Signature.toCharsString()) - * </pre> - */ @Test public void testBackupManifest_withoutInstallerPackage_writesEmptyInstaller() throws Exception { PackageInfo packageInfo = createPackageInfo(TEST_PACKAGE, null, TEST_PACKAGE_VERSION_CODE); @@ -394,7 +360,7 @@ public class AppMetadataBackupWriterTest { } @Test - public void testBackupObb_withNoObbData_doesNotWriteBytesToOutput() throws Exception { + public void testBackupObb_withNoObbData_doesNotWriteBytesToOutput() { PackageInfo packageInfo = createPackageInfo(TEST_PACKAGE, TEST_PACKAGE_INSTALLER, TEST_PACKAGE_VERSION_CODE); File obbDir = createObbDirForPackage(packageInfo.packageName); @@ -416,7 +382,7 @@ public class AppMetadataBackupWriterTest { packageInfo.setLongVersionCode(versionCode); mShadowPackageManager.addPackage(packageInfo); if (installerPackageName != null) { - mShadowPackageManager.setInstallerPackageName(packageName, installerPackageName); + mPackageManager.setInstallerPackageName(packageName, installerPackageName); } return packageInfo; } diff --git a/services/robotests/src/com/android/server/backup/internal/PerformInitializeTaskTest.java b/services/robotests/src/com/android/server/backup/internal/PerformInitializeTaskTest.java index 646367e5a8ba..6ee6eb67dd57 100644 --- a/services/robotests/src/com/android/server/backup/internal/PerformInitializeTaskTest.java +++ b/services/robotests/src/com/android/server/backup/internal/PerformInitializeTaskTest.java @@ -46,20 +46,18 @@ import android.util.Log; import com.android.internal.backup.IBackupTransport; import com.android.server.backup.BackupManagerService; import com.android.server.backup.TransportManager; -import com.android.server.backup.testing.TransportTestUtils; import com.android.server.backup.testing.TransportData; +import com.android.server.backup.testing.TransportTestUtils; import com.android.server.backup.testing.TransportTestUtils.TransportMock; import com.android.server.backup.transport.TransportClient; -import com.android.server.testing.FrameworkRobolectricTestRunner; -import com.android.server.testing.SystemLoaderPackages; import com.android.server.testing.shadows.ShadowSlog; - 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.RuntimeEnvironment; import org.robolectric.annotation.Config; @@ -69,9 +67,8 @@ import java.util.Iterator; import java.util.List; import java.util.stream.Stream; -@RunWith(FrameworkRobolectricTestRunner.class) -@Config(manifest = Config.NONE, sdk = 26, shadows = ShadowSlog.class) -@SystemLoaderPackages({"com.android.server.backup"}) +@RunWith(RobolectricTestRunner.class) +@Config(shadows = ShadowSlog.class) @Presubmit public class PerformInitializeTaskTest { @Mock private BackupManagerService mBackupManagerService; diff --git a/services/robotests/src/com/android/server/backup/keyvalue/AgentExceptionTest.java b/services/robotests/src/com/android/server/backup/keyvalue/AgentExceptionTest.java index 373033500cde..b00b922ed3d0 100644 --- a/services/robotests/src/com/android/server/backup/keyvalue/AgentExceptionTest.java +++ b/services/robotests/src/com/android/server/backup/keyvalue/AgentExceptionTest.java @@ -20,29 +20,24 @@ import static com.google.common.truth.Truth.assertThat; import android.platform.test.annotations.Presubmit; -import com.android.server.testing.FrameworkRobolectricTestRunner; -import com.android.server.testing.SystemLoaderPackages; - import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.annotation.Config; +import org.robolectric.RobolectricTestRunner; import java.io.IOException; -@RunWith(FrameworkRobolectricTestRunner.class) -@Config(manifest = Config.NONE, sdk = 26) -@SystemLoaderPackages({"com.android.server.backup"}) +@RunWith(RobolectricTestRunner.class) @Presubmit public class AgentExceptionTest { @Test - public void testTransitory_isTransitory() throws Exception { + public void testTransitory_isTransitory() { AgentException exception = AgentException.transitory(); assertThat(exception.isTransitory()).isTrue(); } @Test - public void testTransitory_withCause() throws Exception { + public void testTransitory_withCause() { Exception cause = new IOException(); AgentException exception = AgentException.transitory(cause); @@ -52,14 +47,14 @@ public class AgentExceptionTest { } @Test - public void testPermanent_isNotTransitory() throws Exception { + public void testPermanent_isNotTransitory() { AgentException exception = AgentException.permanent(); assertThat(exception.isTransitory()).isFalse(); } @Test - public void testPermanent_withCause() throws Exception { + public void testPermanent_withCause() { Exception cause = new IOException(); AgentException exception = AgentException.permanent(cause); diff --git a/services/robotests/src/com/android/server/backup/keyvalue/BackupExceptionTest.java b/services/robotests/src/com/android/server/backup/keyvalue/BackupExceptionTest.java index 5ea74f163bd6..d5603d64687a 100644 --- a/services/robotests/src/com/android/server/backup/keyvalue/BackupExceptionTest.java +++ b/services/robotests/src/com/android/server/backup/keyvalue/BackupExceptionTest.java @@ -20,18 +20,13 @@ import static com.google.common.truth.Truth.assertThat; import android.platform.test.annotations.Presubmit; -import com.android.server.testing.FrameworkRobolectricTestRunner; -import com.android.server.testing.SystemLoaderPackages; - import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.annotation.Config; +import org.robolectric.RobolectricTestRunner; import java.io.IOException; -@RunWith(FrameworkRobolectricTestRunner.class) -@Config(manifest = Config.NONE, sdk = 26) -@SystemLoaderPackages({"com.android.server.backup"}) +@RunWith(RobolectricTestRunner.class) @Presubmit public class BackupExceptionTest { @Test diff --git a/services/robotests/src/com/android/server/backup/keyvalue/KeyValueBackupReporterTest.java b/services/robotests/src/com/android/server/backup/keyvalue/KeyValueBackupReporterTest.java index 31e8333fea89..a0afb5e0d84e 100644 --- a/services/robotests/src/com/android/server/backup/keyvalue/KeyValueBackupReporterTest.java +++ b/services/robotests/src/com/android/server/backup/keyvalue/KeyValueBackupReporterTest.java @@ -27,9 +27,6 @@ import android.platform.test.annotations.Presubmit; import android.util.Log; import com.android.server.backup.BackupManagerService; -import com.android.server.backup.remote.RemoteResult; -import com.android.server.testing.FrameworkRobolectricTestRunner; -import com.android.server.testing.SystemLoaderPackages; import com.android.server.testing.shadows.ShadowEventLog; import com.android.server.testing.shadows.ShadowSlog; @@ -37,17 +34,11 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; +import org.robolectric.RobolectricTestRunner; import org.robolectric.annotation.Config; -import org.robolectric.shadows.ShadowLog; -import java.lang.reflect.Field; - -@RunWith(FrameworkRobolectricTestRunner.class) -@Config( - manifest = Config.NONE, - sdk = 26, - shadows = {ShadowEventLog.class, ShadowSlog.class}) -@SystemLoaderPackages({"com.android.server.backup"}) +@RunWith(RobolectricTestRunner.class) +@Config(shadows = {ShadowEventLog.class, ShadowSlog.class}) @Presubmit public class KeyValueBackupReporterTest { @Mock private BackupManagerService mBackupManagerService; @@ -57,33 +48,31 @@ public class KeyValueBackupReporterTest { private KeyValueBackupReporter mReporter; @Before - public void setUp() throws Exception { + public void setUp() { mReporter = new KeyValueBackupReporter(mBackupManagerService, mObserver, mMonitor); } @Test - public void testMoreDebug_isFalse() throws Exception { - boolean moreDebug = KeyValueBackupReporter.MORE_DEBUG; - - assertThat(moreDebug).isFalse(); + public void testMoreDebug_isFalse() { + assertThat(KeyValueBackupReporter.MORE_DEBUG).isFalse(); } @Test - public void testOnNewThread_logsCorrectly() throws Exception { + public void testOnNewThread_logsCorrectly() { KeyValueBackupReporter.onNewThread("foo"); assertLogcat(TAG, Log.DEBUG); } @Test - public void testGetMonitor_returnsMonitor() throws Exception { + public void testGetMonitor_returnsMonitor() { IBackupManagerMonitor monitor = mReporter.getMonitor(); assertThat(monitor).isEqualTo(mMonitor); } @Test - public void testGetObserver_returnsObserver() throws Exception { + public void testGetObserver_returnsObserver() { IBackupObserver observer = mReporter.getObserver(); assertThat(observer).isEqualTo(mObserver); diff --git a/services/robotests/src/com/android/server/backup/keyvalue/KeyValueBackupTaskTest.java b/services/robotests/src/com/android/server/backup/keyvalue/KeyValueBackupTaskTest.java index ba1d83ee2a53..a69f007dfe08 100644 --- a/services/robotests/src/com/android/server/backup/keyvalue/KeyValueBackupTaskTest.java +++ b/services/robotests/src/com/android/server/backup/keyvalue/KeyValueBackupTaskTest.java @@ -25,9 +25,12 @@ import static android.app.backup.BackupManager.SUCCESS; import static android.app.backup.ForwardingBackupAgent.forward; import static com.android.server.backup.testing.BackupManagerServiceTestUtils.createBackupWakeLock; -import static com.android.server.backup.testing.BackupManagerServiceTestUtils.createInitializedBackupManagerService; -import static com.android.server.backup.testing.BackupManagerServiceTestUtils.setUpBackupManagerServiceBasics; -import static com.android.server.backup.testing.BackupManagerServiceTestUtils.setUpBinderCallerAndApplicationAsSystem; +import static com.android.server.backup.testing.BackupManagerServiceTestUtils + .createInitializedBackupManagerService; +import static com.android.server.backup.testing.BackupManagerServiceTestUtils + .setUpBackupManagerServiceBasics; +import static com.android.server.backup.testing.BackupManagerServiceTestUtils + .setUpBinderCallerAndApplicationAsSystem; import static com.android.server.backup.testing.PackageData.PM_PACKAGE; import static com.android.server.backup.testing.PackageData.fullBackupPackage; import static com.android.server.backup.testing.PackageData.keyValuePackage; @@ -62,8 +65,8 @@ import static org.mockito.Mockito.verifyZeroInteractions; import static org.mockito.Mockito.when; import static org.robolectric.Shadows.shadowOf; import static org.robolectric.shadow.api.Shadow.extract; -import static org.testng.Assert.fail; import static org.testng.Assert.expectThrows; +import static org.testng.Assert.fail; import static java.nio.file.StandardCopyOption.REPLACE_EXISTING; import static java.util.Collections.emptyList; @@ -114,9 +117,6 @@ import com.android.server.backup.testing.TestUtils.ThrowingRunnable; import com.android.server.backup.testing.TransportData; import com.android.server.backup.testing.TransportTestUtils; import com.android.server.backup.testing.TransportTestUtils.TransportMock; -import com.android.server.testing.FrameworkRobolectricTestRunner; -import com.android.server.testing.SystemLoaderClasses; -import com.android.server.testing.SystemLoaderPackages; import com.android.server.testing.shadows.FrameworkShadowLooper; import com.android.server.testing.shadows.ShadowBackupDataInput; import com.android.server.testing.shadows.ShadowBackupDataOutput; @@ -134,6 +134,7 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; +import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; import org.robolectric.shadows.ShadowApplication; @@ -156,10 +157,8 @@ import java.util.concurrent.TimeoutException; import java.util.stream.Stream; // TODO: Test agents timing out -@RunWith(FrameworkRobolectricTestRunner.class) +@RunWith(RobolectricTestRunner.class) @Config( - manifest = Config.NONE, - sdk = 26, shadows = { FrameworkShadowLooper.class, ShadowBackupDataInput.class, @@ -167,8 +166,6 @@ import java.util.stream.Stream; ShadowEventLog.class, ShadowQueuedWork.class, }) -@SystemLoaderPackages({"com.android.server.backup", "android.app.backup"}) -@SystemLoaderClasses({IBackupTransport.class, IBackupAgent.class, PackageInfo.class}) @Presubmit public class KeyValueBackupTaskTest { private static final PackageData PACKAGE_1 = keyValuePackage(1); @@ -187,6 +184,7 @@ public class KeyValueBackupTaskTest { private Handler mBackupHandler; private PowerManager.WakeLock mWakeLock; private KeyValueBackupReporter mReporter; + private PackageManager mPackageManager; private ShadowPackageManager mShadowPackageManager; private FakeIBackupManager mBackupManager; private File mBaseStateDir; @@ -219,8 +217,8 @@ public class KeyValueBackupTaskTest { mDataDir.mkdirs(); assertThat(mDataDir.isDirectory()).isTrue(); - PackageManager packageManager = mApplication.getPackageManager(); - mShadowPackageManager = shadowOf(packageManager); + mPackageManager = mApplication.getPackageManager(); + mShadowPackageManager = shadowOf(mPackageManager); mWakeLock = createBackupWakeLock(mApplication); mBackupManager = spy(FakeIBackupManager.class); @@ -235,7 +233,7 @@ public class KeyValueBackupTaskTest { mBackupManagerService, mApplication, mTransportManager, - packageManager, + mPackageManager, mBackupManagerService.getBackupHandler(), mWakeLock, mBackupManagerService.getAgentTimeoutParameters()); @@ -332,6 +330,22 @@ public class KeyValueBackupTaskTest { .isEqualTo("packageState".getBytes()); } + /** + * Do not update backup token if the backup queue was empty + */ + @Test + public void testRunTask_whenQueueEmptyOnFirstBackup_doesNotUpdateCurrentToken() + throws Exception { + TransportMock transportMock = setUpInitializedTransport(mTransport); + KeyValueBackupTask task = createKeyValueBackupTask(transportMock, true); + mBackupManagerService.setCurrentToken(0L); + when(transportMock.transport.getCurrentRestoreSet()).thenReturn(1234L); + + runTask(task); + + assertThat(mBackupManagerService.getCurrentToken()).isEqualTo(0L); + } + @Test public void testRunTask_whenOnePackageAndTransportUnavailable() throws Exception { TransportMock transportMock = setUpInitializedTransport(mTransport.unavailable()); @@ -2302,6 +2316,24 @@ public class KeyValueBackupTaskTest { expectThrows(IllegalArgumentException.class, () -> task.handleCancel(false)); } + /** + * Do not update backup token if no data was moved. + */ + @Test + public void testRunTask_whenNoDataToBackupOnFirstBackup_doesNotUpdateCurrentToken() + throws Exception { + TransportMock transportMock = setUpInitializedTransport(mTransport); + mBackupManagerService.setCurrentToken(0L); + when(transportMock.transport.getCurrentRestoreSet()).thenReturn(1234L); + // Set up agent with no data. + setUpAgent(PACKAGE_1); + KeyValueBackupTask task = createKeyValueBackupTask(transportMock, true, PACKAGE_1); + + runTask(task); + + assertThat(mBackupManagerService.getCurrentToken()).isEqualTo(0L); + } + private void runTask(KeyValueBackupTask task) { // Pretend we are not on the main-thread to prevent RemoteCall from complaining mShadowMainLooper.setCurrentThread(false); @@ -2406,7 +2438,7 @@ public class KeyValueBackupTaskTest { private AgentMock setUpAgent(PackageData packageData) { try { - mShadowPackageManager.setApplicationEnabledSetting( + mPackageManager.setApplicationEnabledSetting( packageData.packageName, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0); PackageInfo packageInfo = getPackageInfo(packageData); mShadowPackageManager.addPackage(packageInfo); diff --git a/services/robotests/src/com/android/server/backup/keyvalue/TaskExceptionTest.java b/services/robotests/src/com/android/server/backup/keyvalue/TaskExceptionTest.java index 4b79657b1dae..3698b79872b1 100644 --- a/services/robotests/src/com/android/server/backup/keyvalue/TaskExceptionTest.java +++ b/services/robotests/src/com/android/server/backup/keyvalue/TaskExceptionTest.java @@ -23,18 +23,13 @@ import static org.testng.Assert.expectThrows; import android.app.backup.BackupTransport; import android.platform.test.annotations.Presubmit; -import com.android.server.testing.FrameworkRobolectricTestRunner; -import com.android.server.testing.SystemLoaderPackages; - import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.annotation.Config; +import org.robolectric.RobolectricTestRunner; import java.io.IOException; -@RunWith(FrameworkRobolectricTestRunner.class) -@Config(manifest = Config.NONE, sdk = 26) -@SystemLoaderPackages({"com.android.server.backup"}) +@RunWith(RobolectricTestRunner.class) @Presubmit public class TaskExceptionTest { @Test diff --git a/services/robotests/src/com/android/server/backup/remote/FutureBackupCallbackTest.java b/services/robotests/src/com/android/server/backup/remote/FutureBackupCallbackTest.java index f3621e282179..5ac26f49abdc 100644 --- a/services/robotests/src/com/android/server/backup/remote/FutureBackupCallbackTest.java +++ b/services/robotests/src/com/android/server/backup/remote/FutureBackupCallbackTest.java @@ -20,18 +20,13 @@ import static com.google.common.truth.Truth.assertThat; import android.platform.test.annotations.Presubmit; -import com.android.server.testing.FrameworkRobolectricTestRunner; -import com.android.server.testing.SystemLoaderPackages; - import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.annotation.Config; +import org.robolectric.RobolectricTestRunner; import java.util.concurrent.CompletableFuture; -@RunWith(FrameworkRobolectricTestRunner.class) -@Config(manifest = Config.NONE, sdk = 26) -@SystemLoaderPackages({"com.android.server.backup"}) +@RunWith(RobolectricTestRunner.class) @Presubmit public class FutureBackupCallbackTest { @Test diff --git a/services/robotests/src/com/android/server/backup/remote/RemoteCallTest.java b/services/robotests/src/com/android/server/backup/remote/RemoteCallTest.java index 1d92bed2fde1..7ec2a4e66903 100644 --- a/services/robotests/src/com/android/server/backup/remote/RemoteCallTest.java +++ b/services/robotests/src/com/android/server/backup/remote/RemoteCallTest.java @@ -32,23 +32,19 @@ import android.os.Looper; import android.platform.test.annotations.Presubmit; import com.android.server.backup.testing.TestUtils.ThrowingRunnable; -import com.android.server.testing.FrameworkRobolectricTestRunner; -import com.android.server.testing.SystemLoaderPackages; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; -import org.robolectric.annotation.Config; +import org.robolectric.RobolectricTestRunner; import java.util.concurrent.Callable; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Future; -@RunWith(FrameworkRobolectricTestRunner.class) -@Config(manifest = Config.NONE, sdk = 26) -@SystemLoaderPackages({"com.android.server.backup"}) +@RunWith(RobolectricTestRunner.class) @Presubmit public class RemoteCallTest { /** A {@link RemoteCallable} that calls the callback immediately. */ @@ -267,9 +263,4 @@ public class RemoteCallTest { private static void postDelayed(Handler handler, ThrowingRunnable runnable, long delayMillis) { handler.postDelayed(() -> uncheck(runnable), delayMillis); } - - /** Unchecked version of {@link Handler#post(Runnable)}. */ - private static void post(Handler handler, ThrowingRunnable runnable) { - handler.post(() -> uncheck(runnable)); - } } diff --git a/services/robotests/src/com/android/server/backup/remote/RemoteResultTest.java b/services/robotests/src/com/android/server/backup/remote/RemoteResultTest.java index 7f6fd5785b65..b9a77fbafe61 100644 --- a/services/robotests/src/com/android/server/backup/remote/RemoteResultTest.java +++ b/services/robotests/src/com/android/server/backup/remote/RemoteResultTest.java @@ -22,16 +22,11 @@ import static org.testng.Assert.expectThrows; import android.platform.test.annotations.Presubmit; -import com.android.server.testing.FrameworkRobolectricTestRunner; -import com.android.server.testing.SystemLoaderPackages; - import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.annotation.Config; +import org.robolectric.RobolectricTestRunner; -@RunWith(FrameworkRobolectricTestRunner.class) -@Config(manifest = Config.NONE, sdk = 26) -@SystemLoaderPackages({"com.android.server.backup"}) +@RunWith(RobolectricTestRunner.class) @Presubmit public class RemoteResultTest { @Test diff --git a/services/robotests/src/com/android/server/backup/remote/ServiceBackupCallbackTest.java b/services/robotests/src/com/android/server/backup/remote/ServiceBackupCallbackTest.java index e0d3c0c09eb8..38a54dab3fb8 100644 --- a/services/robotests/src/com/android/server/backup/remote/ServiceBackupCallbackTest.java +++ b/services/robotests/src/com/android/server/backup/remote/ServiceBackupCallbackTest.java @@ -22,16 +22,11 @@ import static org.mockito.Mockito.verify; import android.app.backup.IBackupManager; import android.platform.test.annotations.Presubmit; -import com.android.server.testing.FrameworkRobolectricTestRunner; -import com.android.server.testing.SystemLoaderPackages; - import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.annotation.Config; +import org.robolectric.RobolectricTestRunner; -@RunWith(FrameworkRobolectricTestRunner.class) -@Config(manifest = Config.NONE, sdk = 26) -@SystemLoaderPackages({"com.android.server.backup"}) +@RunWith(RobolectricTestRunner.class) @Presubmit public class ServiceBackupCallbackTest { @Test diff --git a/services/robotests/src/com/android/server/backup/restore/ActiveRestoreSessionTest.java b/services/robotests/src/com/android/server/backup/restore/ActiveRestoreSessionTest.java index 27171207e9c5..0e2b95b3167d 100644 --- a/services/robotests/src/com/android/server/backup/restore/ActiveRestoreSessionTest.java +++ b/services/robotests/src/com/android/server/backup/restore/ActiveRestoreSessionTest.java @@ -19,7 +19,6 @@ package com.android.server.backup.restore; import static com.android.server.backup.testing.BackupManagerServiceTestUtils.createBackupWakeLock; import static com.android.server.backup.testing.BackupManagerServiceTestUtils.setUpBackupManagerServiceBasics; import static com.android.server.backup.testing.BackupManagerServiceTestUtils.startBackupThreadAndGetLooper; - import static com.android.server.backup.testing.TestUtils.assertEventLogged; import static com.android.server.backup.testing.TestUtils.assertEventNotLogged; import static com.android.server.backup.testing.TransportData.backupTransport; @@ -58,8 +57,6 @@ import com.android.server.backup.internal.BackupHandler; import com.android.server.backup.testing.TransportData; import com.android.server.backup.testing.TransportTestUtils; import com.android.server.backup.testing.TransportTestUtils.TransportMock; -import com.android.server.testing.FrameworkRobolectricTestRunner; -import com.android.server.testing.SystemLoaderPackages; import com.android.server.testing.shadows.ShadowEventLog; import com.android.server.testing.shadows.ShadowPerformUnifiedRestoreTask; @@ -69,6 +66,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; import org.robolectric.shadows.ShadowApplication; @@ -78,18 +76,14 @@ import org.robolectric.shadows.ShadowPackageManager; import java.util.ArrayDeque; -@RunWith(FrameworkRobolectricTestRunner.class) -@Config( - manifest = Config.NONE, - sdk = 26, - shadows = {ShadowEventLog.class, ShadowPerformUnifiedRestoreTask.class, ShadowBinder.class}) -@SystemLoaderPackages({"com.android.server.backup"}) +@RunWith(RobolectricTestRunner.class) +@Config(shadows = {ShadowEventLog.class, ShadowPerformUnifiedRestoreTask.class, ShadowBinder.class}) @Presubmit public class ActiveRestoreSessionTest { private static final String PACKAGE_1 = "com.example.package1"; private static final String PACKAGE_2 = "com.example.package2"; - public static final long TOKEN_1 = 1L; - public static final long TOKEN_2 = 2L; + private static final long TOKEN_1 = 1L; + private static final long TOKEN_2 = 2L; @Mock private BackupManagerService mBackupManagerService; @Mock private TransportManager mTransportManager; diff --git a/services/robotests/src/com/android/server/backup/transport/TransportClientManagerTest.java b/services/robotests/src/com/android/server/backup/transport/TransportClientManagerTest.java index bbec7af34d71..7dd0d927edd0 100644 --- a/services/robotests/src/com/android/server/backup/transport/TransportClientManagerTest.java +++ b/services/robotests/src/com/android/server/backup/transport/TransportClientManagerTest.java @@ -17,6 +17,7 @@ package com.android.server.backup.transport; import static com.android.server.backup.TransportManager.SERVICE_ACTION_TRANSPORT_HOST; + import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.argThat; @@ -32,19 +33,15 @@ import android.os.Bundle; import android.os.UserHandle; import android.platform.test.annotations.Presubmit; -import com.android.server.testing.FrameworkRobolectricTestRunner; -import com.android.server.testing.SystemLoaderPackages; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentMatcher; import org.mockito.Mock; import org.mockito.MockitoAnnotations; -import org.robolectric.annotation.Config; +import org.robolectric.RobolectricTestRunner; -@RunWith(FrameworkRobolectricTestRunner.class) -@Config(manifest = Config.NONE, sdk = 26) -@SystemLoaderPackages({"com.android.server.backup"}) +@RunWith(RobolectricTestRunner.class) @Presubmit public class TransportClientManagerTest { private static final String PACKAGE_NAME = "random.package.name"; diff --git a/services/robotests/src/com/android/server/backup/transport/TransportClientTest.java b/services/robotests/src/com/android/server/backup/transport/TransportClientTest.java index f843b50bcd15..7281a3c87a29 100644 --- a/services/robotests/src/com/android/server/backup/transport/TransportClientTest.java +++ b/services/robotests/src/com/android/server/backup/transport/TransportClientTest.java @@ -49,8 +49,6 @@ import android.util.Log; import com.android.internal.backup.IBackupTransport; import com.android.server.EventLogTags; -import com.android.server.testing.FrameworkRobolectricTestRunner; -import com.android.server.testing.SystemLoaderPackages; import com.android.server.testing.shadows.FrameworkShadowLooper; import com.android.server.testing.shadows.ShadowCloseGuard; import com.android.server.testing.shadows.ShadowEventLog; @@ -62,6 +60,7 @@ import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import org.robolectric.RobolectricTestRunner; import org.robolectric.annotation.Config; import org.robolectric.shadows.ShadowLog; import org.robolectric.shadows.ShadowLooper; @@ -69,17 +68,13 @@ import org.robolectric.shadows.ShadowLooper; import java.util.concurrent.CompletableFuture; import java.util.function.Supplier; -@RunWith(FrameworkRobolectricTestRunner.class) -@Config( - manifest = Config.NONE, - sdk = 26, - shadows = { +@RunWith(RobolectricTestRunner.class) +@Config(shadows = { ShadowEventLog.class, ShadowCloseGuard.class, ShadowSlog.class, FrameworkShadowLooper.class }) -@SystemLoaderPackages({"com.android.server.backup"}) @Presubmit public class TransportClientTest { private static final String PACKAGE_NAME = "some.package.name"; @@ -137,7 +132,7 @@ public class TransportClientTest { } @Test - public void testConnectAsync_callsBindService() throws Exception { + public void testConnectAsync_callsBindService() { mTransportClient.connectAsync(mTransportConnectionListener, "caller"); verify(mContext) @@ -149,7 +144,7 @@ public class TransportClientTest { } @Test - public void testConnectAsync_callsListenerWhenConnected() throws Exception { + public void testConnectAsync_callsListenerWhenConnected() { mTransportClient.connectAsync(mTransportConnectionListener, "caller"); ServiceConnection connection = verifyBindServiceAsUserAndCaptureServiceConnection(mContext); @@ -161,8 +156,7 @@ public class TransportClientTest { } @Test - public void testConnectAsync_whenPendingConnection_callsAllListenersWhenConnected() - throws Exception { + public void testConnectAsync_whenPendingConnection_callsAllListenersWhenConnected() { mTransportClient.connectAsync(mTransportConnectionListener, "caller1"); ServiceConnection connection = verifyBindServiceAsUserAndCaptureServiceConnection(mContext); @@ -177,7 +171,7 @@ public class TransportClientTest { } @Test - public void testConnectAsync_whenAlreadyConnected_callsListener() throws Exception { + public void testConnectAsync_whenAlreadyConnected_callsListener() { mTransportClient.connectAsync(mTransportConnectionListener, "caller1"); ServiceConnection connection = verifyBindServiceAsUserAndCaptureServiceConnection(mContext); connection.onServiceConnected(mTransportComponent, mTransportBinder); @@ -190,7 +184,7 @@ public class TransportClientTest { } @Test - public void testConnectAsync_whenFrameworkDoesntBind_callsListener() throws Exception { + public void testConnectAsync_whenFrameworkDoesntBind_callsListener() { when(mContext.bindServiceAsUser( eq(mBindIntent), any(ServiceConnection.class), @@ -206,7 +200,7 @@ public class TransportClientTest { } @Test - public void testConnectAsync_whenFrameworkDoesNotBind_releasesConnection() throws Exception { + public void testConnectAsync_whenFrameworkDoesNotBind_releasesConnection() { when(mContext.bindServiceAsUser( eq(mBindIntent), any(ServiceConnection.class), @@ -221,8 +215,7 @@ public class TransportClientTest { } @Test - public void testConnectAsync_afterOnServiceDisconnectedBeforeNewConnection_callsListener() - throws Exception { + public void testConnectAsync_afterOnServiceDisconnectedBeforeNewConnection_callsListener() { mTransportClient.connectAsync(mTransportConnectionListener, "caller1"); ServiceConnection connection = verifyBindServiceAsUserAndCaptureServiceConnection(mContext); connection.onServiceConnected(mTransportComponent, mTransportBinder); @@ -235,8 +228,7 @@ public class TransportClientTest { } @Test - public void testConnectAsync_afterOnServiceDisconnectedAfterNewConnection_callsListener() - throws Exception { + public void testConnectAsync_afterOnServiceDisconnectedAfterNewConnection_callsListener() { mTransportClient.connectAsync(mTransportConnectionListener, "caller1"); ServiceConnection connection = verifyBindServiceAsUserAndCaptureServiceConnection(mContext); connection.onServiceConnected(mTransportComponent, mTransportBinder); @@ -251,7 +243,7 @@ public class TransportClientTest { } @Test - public void testConnectAsync_callsListenerIfBindingDies() throws Exception { + public void testConnectAsync_callsListenerIfBindingDies() { mTransportClient.connectAsync(mTransportConnectionListener, "caller"); ServiceConnection connection = verifyBindServiceAsUserAndCaptureServiceConnection(mContext); @@ -263,8 +255,7 @@ public class TransportClientTest { } @Test - public void testConnectAsync_whenPendingConnection_callsListenersIfBindingDies() - throws Exception { + public void testConnectAsync_whenPendingConnection_callsListenersIfBindingDies() { mTransportClient.connectAsync(mTransportConnectionListener, "caller1"); ServiceConnection connection = verifyBindServiceAsUserAndCaptureServiceConnection(mContext); @@ -412,14 +403,14 @@ public class TransportClientTest { } @Test - public void testMarkAsDisposed_whenCreated() throws Throwable { + public void testMarkAsDisposed_whenCreated() { mTransportClient.markAsDisposed(); // No exception thrown } @Test - public void testMarkAsDisposed_afterOnBindingDied() throws Throwable { + public void testMarkAsDisposed_afterOnBindingDied() { mTransportClient.connectAsync(mTransportConnectionListener, "caller1"); ServiceConnection connection = verifyBindServiceAsUserAndCaptureServiceConnection(mContext); connection.onBindingDied(mTransportComponent); @@ -430,7 +421,7 @@ public class TransportClientTest { } @Test - public void testMarkAsDisposed_whenConnectedAndUnbound() throws Throwable { + public void testMarkAsDisposed_whenConnectedAndUnbound() { mTransportClient.connectAsync(mTransportConnectionListener, "caller1"); ServiceConnection connection = verifyBindServiceAsUserAndCaptureServiceConnection(mContext); connection.onServiceConnected(mTransportComponent, mTransportBinder); @@ -442,7 +433,7 @@ public class TransportClientTest { } @Test - public void testMarkAsDisposed_afterOnServiceDisconnected() throws Throwable { + public void testMarkAsDisposed_afterOnServiceDisconnected() { mTransportClient.connectAsync(mTransportConnectionListener, "caller1"); ServiceConnection connection = verifyBindServiceAsUserAndCaptureServiceConnection(mContext); connection.onServiceConnected(mTransportComponent, mTransportBinder); @@ -454,14 +445,14 @@ public class TransportClientTest { } @Test - public void testMarkAsDisposed_whenBound() throws Throwable { + public void testMarkAsDisposed_whenBound() { mTransportClient.connectAsync(mTransportConnectionListener, "caller1"); expectThrows(RuntimeException.class, mTransportClient::markAsDisposed); } @Test - public void testMarkAsDisposed_whenConnected() throws Throwable { + public void testMarkAsDisposed_whenConnected() { mTransportClient.connectAsync(mTransportConnectionListener, "caller1"); ServiceConnection connection = verifyBindServiceAsUserAndCaptureServiceConnection(mContext); connection.onServiceConnected(mTransportComponent, mTransportBinder); diff --git a/services/robotests/src/com/android/server/backup/transport/TransportStatsTest.java b/services/robotests/src/com/android/server/backup/transport/TransportStatsTest.java index 322db85c4f42..f01a6b067c8a 100644 --- a/services/robotests/src/com/android/server/backup/transport/TransportStatsTest.java +++ b/services/robotests/src/com/android/server/backup/transport/TransportStatsTest.java @@ -25,17 +25,13 @@ import android.content.ComponentName; import android.platform.test.annotations.Presubmit; import com.android.server.backup.transport.TransportStats.Stats; -import com.android.server.testing.FrameworkRobolectricTestRunner; -import com.android.server.testing.SystemLoaderPackages; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.annotation.Config; +import org.robolectric.RobolectricTestRunner; -@RunWith(FrameworkRobolectricTestRunner.class) -@Config(manifest = Config.NONE, sdk = 26) -@SystemLoaderPackages({"com.android.server.backup"}) +@RunWith(RobolectricTestRunner.class) @Presubmit public class TransportStatsTest { private static final double TOLERANCE = 0.0001; diff --git a/services/robotests/src/com/android/server/location/GnssBatchingProviderTest.java b/services/robotests/src/com/android/server/location/GnssBatchingProviderTest.java index 504609472fa6..d58c3f73b8e8 100644 --- a/services/robotests/src/com/android/server/location/GnssBatchingProviderTest.java +++ b/services/robotests/src/com/android/server/location/GnssBatchingProviderTest.java @@ -1,9 +1,10 @@ package com.android.server.location; import static com.google.common.truth.Truth.assertThat; -import static org.mockito.Matchers.anyBoolean; -import static org.mockito.Matchers.anyLong; -import static org.mockito.Matchers.eq; + +import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -11,27 +12,18 @@ import static org.mockito.Mockito.when; import android.platform.test.annotations.Presubmit; import com.android.server.location.GnssBatchingProvider.GnssBatchingProviderNative; -import com.android.server.testing.FrameworkRobolectricTestRunner; -import com.android.server.testing.SystemLoaderPackages; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; -import org.robolectric.annotation.Config; +import org.robolectric.RobolectricTestRunner; /** * Unit tests for {@link GnssBatchingProvider}. */ -@RunWith(FrameworkRobolectricTestRunner.class) -@Config( - manifest = Config.NONE, - shadows = { - }, - sdk = 27 -) -@SystemLoaderPackages({"com.android.server.location"}) +@RunWith(RobolectricTestRunner.class) @Presubmit public class GnssBatchingProviderTest { diff --git a/services/robotests/src/com/android/server/location/GnssGeofenceProviderTest.java b/services/robotests/src/com/android/server/location/GnssGeofenceProviderTest.java index 187303cc93d6..beb59414546a 100644 --- a/services/robotests/src/com/android/server/location/GnssGeofenceProviderTest.java +++ b/services/robotests/src/com/android/server/location/GnssGeofenceProviderTest.java @@ -1,8 +1,8 @@ package com.android.server.location; -import static org.mockito.Matchers.anyDouble; -import static org.mockito.Matchers.anyInt; -import static org.mockito.Matchers.eq; +import static org.mockito.ArgumentMatchers.anyDouble; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -11,25 +11,17 @@ import android.os.Looper; import android.os.RemoteException; import android.platform.test.annotations.Presubmit; -import com.android.server.testing.FrameworkRobolectricTestRunner; -import com.android.server.testing.SystemLoaderPackages; - import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; -import org.robolectric.annotation.Config; +import org.robolectric.RobolectricTestRunner; /** * Unit tests for {@link GnssGeofenceProvider}. */ -@RunWith(FrameworkRobolectricTestRunner.class) -@Config( - manifest = Config.NONE, - sdk = 27 -) -@SystemLoaderPackages({"com.android.server.location"}) +@RunWith(RobolectricTestRunner.class) @Presubmit public class GnssGeofenceProviderTest { private static final int GEOFENCE_ID = 12345; diff --git a/services/robotests/src/com/android/server/location/GnssMeasurementsProviderTest.java b/services/robotests/src/com/android/server/location/GnssMeasurementsProviderTest.java index 23d6cf69edc6..b349b67dab0c 100644 --- a/services/robotests/src/com/android/server/location/GnssMeasurementsProviderTest.java +++ b/services/robotests/src/com/android/server/location/GnssMeasurementsProviderTest.java @@ -1,6 +1,7 @@ package com.android.server.location; import static com.google.common.truth.Truth.assertThat; + import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -10,26 +11,18 @@ import android.os.Handler; import android.os.Looper; import android.platform.test.annotations.Presubmit; -import com.android.server.testing.FrameworkRobolectricTestRunner; -import com.android.server.testing.SystemLoaderPackages; - 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.RuntimeEnvironment; -import org.robolectric.annotation.Config; /** * Unit tests for {@link GnssMeasurementsProvider}. */ -@RunWith(FrameworkRobolectricTestRunner.class) -@Config( - manifest = Config.NONE, - sdk = 27 -) -@SystemLoaderPackages({"com.android.server.location"}) +@RunWith(RobolectricTestRunner.class) @Presubmit public class GnssMeasurementsProviderTest { @Mock diff --git a/services/robotests/src/com/android/server/location/GnssNavigationMessageProviderTest.java b/services/robotests/src/com/android/server/location/GnssNavigationMessageProviderTest.java index 8d3de3c9dbc1..59e9a15efb53 100644 --- a/services/robotests/src/com/android/server/location/GnssNavigationMessageProviderTest.java +++ b/services/robotests/src/com/android/server/location/GnssNavigationMessageProviderTest.java @@ -10,25 +10,17 @@ import android.os.Handler; import android.os.Looper; import android.platform.test.annotations.Presubmit; -import com.android.server.testing.FrameworkRobolectricTestRunner; -import com.android.server.testing.SystemLoaderPackages; - import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; -import org.robolectric.annotation.Config; +import org.robolectric.RobolectricTestRunner; /** * Unit tests for {@link GnssNavigationMessageProvider}. */ -@RunWith(FrameworkRobolectricTestRunner.class) -@Config( - manifest = Config.NONE, - sdk = 27 -) -@SystemLoaderPackages({"com.android.server.location"}) +@RunWith(RobolectricTestRunner.class) @Presubmit public class GnssNavigationMessageProviderTest { @Mock diff --git a/services/robotests/src/com/android/server/location/GnssPositionModeTest.java b/services/robotests/src/com/android/server/location/GnssPositionModeTest.java index e6d5355127b0..f37f50e76ae5 100644 --- a/services/robotests/src/com/android/server/location/GnssPositionModeTest.java +++ b/services/robotests/src/com/android/server/location/GnssPositionModeTest.java @@ -4,24 +4,16 @@ import static com.google.common.truth.Truth.assertThat; import android.platform.test.annotations.Presubmit; -import com.android.server.testing.FrameworkRobolectricTestRunner; -import com.android.server.testing.SystemLoaderPackages; - import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.annotation.Config; +import org.robolectric.RobolectricTestRunner; import java.util.HashSet; /** * Unit tests for {@link GnssPositionMode}. */ -@RunWith(FrameworkRobolectricTestRunner.class) -@Config( - manifest = Config.NONE, - sdk = 27 -) -@SystemLoaderPackages({"com.android.server.location"}) +@RunWith(RobolectricTestRunner.class) @Presubmit public class GnssPositionModeTest { diff --git a/services/robotests/src/com/android/server/location/GnssSatelliteBlacklistHelperTest.java b/services/robotests/src/com/android/server/location/GnssSatelliteBlacklistHelperTest.java index d6f54460afbe..ba4a753e4813 100644 --- a/services/robotests/src/com/android/server/location/GnssSatelliteBlacklistHelperTest.java +++ b/services/robotests/src/com/android/server/location/GnssSatelliteBlacklistHelperTest.java @@ -2,7 +2,7 @@ package com.android.server.location; import static com.google.common.truth.Truth.assertThat; -import static org.mockito.Matchers.any; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; @@ -13,18 +13,15 @@ import android.os.Looper; import android.platform.test.annotations.Presubmit; import android.provider.Settings; -import com.android.server.testing.FrameworkRobolectricTestRunner; -import com.android.server.testing.SystemLoaderPackages; - import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; import org.robolectric.Shadows; -import org.robolectric.annotation.Config; import java.util.Collection; import java.util.List; @@ -32,18 +29,10 @@ import java.util.List; /** * Unit tests for {@link GnssSatelliteBlacklistHelper}. */ -@RunWith(FrameworkRobolectricTestRunner.class) -@Config( - manifest = Config.NONE, - shadows = { - }, - sdk = 27 -) -@SystemLoaderPackages({"com.android.server.location"}) +@RunWith(RobolectricTestRunner.class) @Presubmit public class GnssSatelliteBlacklistHelperTest { - private Context mContext; private ContentResolver mContentResolver; @Mock private GnssSatelliteBlacklistHelper.GnssSatelliteBlacklistCallback mCallback; @@ -51,9 +40,9 @@ public class GnssSatelliteBlacklistHelperTest { @Before public void setUp() { MockitoAnnotations.initMocks(this); - mContext = RuntimeEnvironment.application; - mContentResolver = mContext.getContentResolver(); - new GnssSatelliteBlacklistHelper(mContext, Looper.myLooper(), mCallback); + Context context = RuntimeEnvironment.application; + mContentResolver = context.getContentResolver(); + new GnssSatelliteBlacklistHelper(context, Looper.myLooper(), mCallback); } @Test diff --git a/services/robotests/src/com/android/server/location/NtpTimeHelperTest.java b/services/robotests/src/com/android/server/location/NtpTimeHelperTest.java index a68b5795235b..aac0a340b30c 100644 --- a/services/robotests/src/com/android/server/location/NtpTimeHelperTest.java +++ b/services/robotests/src/com/android/server/location/NtpTimeHelperTest.java @@ -9,16 +9,14 @@ import android.platform.test.annotations.Presubmit; import android.util.NtpTrustedTime; import com.android.server.location.NtpTimeHelper.InjectNtpTimeCallback; -import com.android.server.testing.FrameworkRobolectricTestRunner; -import com.android.server.testing.SystemLoaderPackages; 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.RuntimeEnvironment; -import org.robolectric.annotation.Config; import org.robolectric.shadows.ShadowLooper; import org.robolectric.shadows.ShadowSystemClock; @@ -28,12 +26,7 @@ import java.util.concurrent.TimeUnit; /** * Unit tests for {@link NtpTimeHelper}. */ -@RunWith(FrameworkRobolectricTestRunner.class) -@Config( - manifest = Config.NONE, - sdk = 27 -) -@SystemLoaderPackages({"com.android.server.location"}) +@RunWith(RobolectricTestRunner.class) @Presubmit public class NtpTimeHelperTest { diff --git a/services/robotests/src/com/android/server/testing/FrameworkRobolectricTestRunner.java b/services/robotests/src/com/android/server/testing/FrameworkRobolectricTestRunner.java deleted file mode 100644 index d2a4d06dfbd0..000000000000 --- a/services/robotests/src/com/android/server/testing/FrameworkRobolectricTestRunner.java +++ /dev/null @@ -1,186 +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.server.testing; - -import static java.util.Arrays.asList; - -import com.google.common.collect.ImmutableSet; - -import org.junit.runners.model.FrameworkMethod; -import org.junit.runners.model.InitializationError; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.internal.SandboxFactory; -import org.robolectric.internal.SdkEnvironment; -import org.robolectric.internal.bytecode.InstrumentationConfiguration; -import org.robolectric.internal.bytecode.SandboxClassLoader; -import org.robolectric.util.Util; - -import java.io.IOException; -import java.io.InputStream; -import java.net.URL; -import java.util.Arrays; -import java.util.Enumeration; -import java.util.HashSet; -import java.util.Set; -import java.util.stream.Stream; - -import javax.annotation.Nonnull; - -/** - * HACK - * Robolectric loads up Android environment from prebuilt android jars before running a method. - * These jars are versioned according to the SDK level configured for the method (or class). The - * jars represent a snapshot of the Android APIs in that SDK level. For Robolectric tests that are - * testing Android components themselves we don't want certain classes (usually the - * class-under-test) to be loaded from the prebuilt jar, we want it instead to be loaded from the - * dependencies of our test target, i.e. the system class loader. That way we can write tests - * against the actual classes that are in the tree, not a past version of them. Ideally we would - * have a locally built jar referenced by Robolectric, but until that happens one can use this - * class. - * This class reads the {@link SystemLoaderClasses} or {@link SystemLoaderPackages} annotations on - * test classes, for classes that match the annotations it will bypass the android jar and load it - * from the system class loader. Allowing the test to test the actual class in the tree. - * - * Implementation note: One could think about overriding - * {@link RobolectricTestRunner#createClassLoaderConfig(FrameworkMethod)} method and putting the - * classes in the annotation in the {@link InstrumentationConfiguration} list of classes not to - * acquire. Unfortunately, this will not work because we will not be instrumenting the class. - * Instead, we have to load the class bytes from the system class loader but still instrument it, we - * do this by overriding {@link SandboxClassLoader#getByteCode(String)} and loading the class bytes - * from the system class loader if it in the {@link SystemLoaderClasses} annotation. This way the - * {@link SandboxClassLoader} still instruments the class, but it's not loaded from the android jar. - * Finally, we inject the custom class loader in place of the default one. - * - * TODO: Remove this when we are using locally built android jars in the method's environment. - */ -public class FrameworkRobolectricTestRunner extends RobolectricTestRunner { - private final SandboxFactory mSandboxFactory; - - public FrameworkRobolectricTestRunner(Class<?> testClass) throws InitializationError { - super(testClass); - Set<String> classPrefixes = getSystemLoaderClassPrefixes(testClass); - mSandboxFactory = new FrameworkSandboxFactory(classPrefixes); - } - - private Set<String> getSystemLoaderClassPrefixes(Class<?> testClass) { - Set<String> classPrefixes = new HashSet<>(); - SystemLoaderClasses byClass = testClass.getAnnotation(SystemLoaderClasses.class); - if (byClass != null) { - Stream.of(byClass.value()).map(Class::getName).forEach(classPrefixes::add); - } - SystemLoaderPackages byPackage = testClass.getAnnotation(SystemLoaderPackages.class); - if (byPackage != null) { - classPrefixes.addAll(asList(byPackage.value())); - } - return classPrefixes; - } - - @Nonnull - @Override - protected SdkEnvironment getSandbox(FrameworkMethod method) { - // HACK: Calling super just to get SdkConfig via sandbox.getSdkConfig(), because - // RobolectricFrameworkMethod, the runtime class of method, is package-protected - SdkEnvironment sandbox = super.getSandbox(method); - return mSandboxFactory.getSdkEnvironment( - createClassLoaderConfig(method), - getJarResolver(), - sandbox.getSdkConfig()); - } - - private static class FrameworkClassLoader extends SandboxClassLoader { - private final Set<String> mSystemLoaderClassPrefixes; - - private FrameworkClassLoader( - Set<String> systemLoaderClassPrefixes, - ClassLoader systemClassLoader, - InstrumentationConfiguration instrumentationConfig, - URL... urls) { - super(systemClassLoader, instrumentationConfig, urls); - mSystemLoaderClassPrefixes = systemLoaderClassPrefixes; - } - - @Override - protected byte[] getByteCode(String className) throws ClassNotFoundException { - String classFileName = className.replace('.', '/') + ".class"; - if (shouldLoadFromSystemLoader(className)) { - try (InputStream classByteStream = getResourceAsStream(classFileName)) { - if (classByteStream == null) { - throw new ClassNotFoundException(className); - } - return Util.readBytes(classByteStream); - } catch (IOException e) { - throw new ClassNotFoundException( - "Couldn't load " + className + " from system class loader", e); - } - } - return super.getByteCode(className); - } - - /** - * HACK^2 - * The framework Robolectric run configuration puts a prebuilt in front of us, so we try not - * to load the class from there, if possible. - */ - @Override - public InputStream getResourceAsStream(String resource) { - try { - Enumeration<URL> urls = getResources(resource); - while (urls.hasMoreElements()) { - URL url = urls.nextElement(); - if (!url.toString().toLowerCase().contains("prebuilt")) { - return url.openStream(); - } - } - } catch (IOException e) { - // Fall through - } - return super.getResourceAsStream(resource); - } - - /** - * Classes like com.package.ClassName$InnerClass should also be loaded from the system class - * loader, so we test if the classes in the annotation are prefixes of the class to load. - */ - private boolean shouldLoadFromSystemLoader(String className) { - for (String classPrefix : mSystemLoaderClassPrefixes) { - if (className.startsWith(classPrefix)) { - return true; - } - } - return false; - } - } - - private static class FrameworkSandboxFactory extends SandboxFactory { - private final Set<String> mSystemLoaderClassPrefixes; - - private FrameworkSandboxFactory(Set<String> systemLoaderClassPrefixes) { - mSystemLoaderClassPrefixes = systemLoaderClassPrefixes; - } - - @Nonnull - @Override - public ClassLoader createClassLoader( - InstrumentationConfiguration instrumentationConfig, URL... urls) { - return new FrameworkClassLoader( - mSystemLoaderClassPrefixes, - ClassLoader.getSystemClassLoader(), - instrumentationConfig, - urls); - } - } -} diff --git a/services/robotests/src/com/android/server/testing/SystemLoaderClasses.java b/services/robotests/src/com/android/server/testing/SystemLoaderClasses.java deleted file mode 100644 index 646a413c2667..000000000000 --- a/services/robotests/src/com/android/server/testing/SystemLoaderClasses.java +++ /dev/null @@ -1,35 +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.server.testing; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Annotation to be used in test classes that run with {@link FrameworkRobolectricTestRunner}. - * This will make the classes specified be loaded from the system class loader, NOT from the - * Robolectric android jar. - * - * @see FrameworkRobolectricTestRunner - */ -@Target(ElementType.TYPE) -@Retention(RetentionPolicy.RUNTIME) -public @interface SystemLoaderClasses { - Class<?>[] value() default {}; -} diff --git a/services/robotests/src/com/android/server/testing/SystemLoaderPackages.java b/services/robotests/src/com/android/server/testing/SystemLoaderPackages.java deleted file mode 100644 index e01c0a4cffa5..000000000000 --- a/services/robotests/src/com/android/server/testing/SystemLoaderPackages.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package com.android.server.testing; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Annotation to be used in test classes that run with {@link FrameworkRobolectricTestRunner}. - * This will make the classes under the specified packages be loaded from the system class loader, - * NOT from the Robolectric android jar. - * - * @see FrameworkRobolectricTestRunner - */ -@Target(ElementType.TYPE) -@Retention(RetentionPolicy.RUNTIME) -public @interface SystemLoaderPackages { - String[] value() default {}; -} diff --git a/services/robotests/src/com/android/server/testing/shadows/FrameworkShadowContextImpl.java b/services/robotests/src/com/android/server/testing/shadows/FrameworkShadowContextImpl.java deleted file mode 100644 index 6d220737f2fb..000000000000 --- a/services/robotests/src/com/android/server/testing/shadows/FrameworkShadowContextImpl.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package com.android.server.testing.shadows; - -import android.content.Intent; -import android.content.ServiceConnection; -import android.os.UserHandle; - -import org.robolectric.annotation.Implementation; -import org.robolectric.annotation.Implements; -import org.robolectric.shadows.ShadowContextImpl; - -@Implements(className = ShadowContextImpl.CLASS_NAME, inheritImplementationMethods = true) -public class FrameworkShadowContextImpl extends ShadowContextImpl { - @Implementation - public boolean bindServiceAsUser( - Intent service, - ServiceConnection connection, - int flags, - UserHandle user) { - return bindService(service, connection, flags); - } -} diff --git a/services/robotests/src/com/android/server/testing/shadows/FrameworkShadowLooper.java b/services/robotests/src/com/android/server/testing/shadows/FrameworkShadowLooper.java index c0eeb3890a86..16d16cda42ed 100644 --- a/services/robotests/src/com/android/server/testing/shadows/FrameworkShadowLooper.java +++ b/services/robotests/src/com/android/server/testing/shadows/FrameworkShadowLooper.java @@ -25,7 +25,7 @@ import org.robolectric.shadows.ShadowLooper; import java.util.Optional; -@Implements(value = Looper.class, inheritImplementationMethods = true) +@Implements(value = Looper.class) public class FrameworkShadowLooper extends ShadowLooper { @RealObject private Looper mLooper; private Optional<Boolean> mIsCurrentThread = Optional.empty(); @@ -39,7 +39,7 @@ public class FrameworkShadowLooper extends ShadowLooper { } @Implementation - public boolean isCurrentThread() { + protected boolean isCurrentThread() { if (mIsCurrentThread.isPresent()) { return mIsCurrentThread.get(); } diff --git a/services/robotests/src/com/android/server/testing/shadows/ShadowAppBackupUtils.java b/services/robotests/src/com/android/server/testing/shadows/ShadowAppBackupUtils.java index 21faa090f003..5fffb149fd96 100644 --- a/services/robotests/src/com/android/server/testing/shadows/ShadowAppBackupUtils.java +++ b/services/robotests/src/com/android/server/testing/shadows/ShadowAppBackupUtils.java @@ -26,6 +26,7 @@ import com.android.server.backup.utils.AppBackupUtils; import org.robolectric.annotation.Implementation; import org.robolectric.annotation.Implements; +import org.robolectric.annotation.Resetter; import java.util.HashSet; import java.util.Set; @@ -52,21 +53,22 @@ public class ShadowAppBackupUtils { } @Implementation - public static boolean appIsRunningAndEligibleForBackupWithTransport( + protected static boolean appIsRunningAndEligibleForBackupWithTransport( @Nullable TransportClient transportClient, String packageName, PackageManager pm) { return sAppsRunningAndEligibleForBackupWithTransport.contains(packageName); } @Implementation - public static boolean appIsEligibleForBackup(ApplicationInfo app, PackageManager pm) { + protected static boolean appIsEligibleForBackup(ApplicationInfo app, PackageManager pm) { return sAppsEligibleForBackup.contains(app.packageName); } @Implementation - public static boolean appGetsFullBackup(PackageInfo packageInfo) { + protected static boolean appGetsFullBackup(PackageInfo packageInfo) { return sAppsGetFullBackup.contains(packageInfo.packageName); } + @Resetter public static void reset() { sAppsRunningAndEligibleForBackupWithTransport.clear(); sAppsEligibleForBackup.clear(); diff --git a/services/robotests/src/com/android/server/testing/shadows/ShadowBackupDataInput.java b/services/robotests/src/com/android/server/testing/shadows/ShadowBackupDataInput.java index 4901828133c9..e7d2a68c4221 100644 --- a/services/robotests/src/com/android/server/testing/shadows/ShadowBackupDataInput.java +++ b/services/robotests/src/com/android/server/testing/shadows/ShadowBackupDataInput.java @@ -52,12 +52,12 @@ public class ShadowBackupDataInput { private boolean mHeaderReady; @Implementation - public void __constructor__(FileDescriptor fd) { + protected void __constructor__(FileDescriptor fd) { mFileDescriptor = fd; } @Implementation - public boolean readNextHeader() throws IOException { + protected boolean readNextHeader() throws IOException { if (sReadNextHeaderThrow) { sReadNextHeaderThrow = false; throw new IOException("Fake exception"); @@ -75,19 +75,19 @@ public class ShadowBackupDataInput { } @Implementation - public String getKey() { + protected String getKey() { checkHeaderReady(); return mKey; } @Implementation - public int getDataSize() { + protected int getDataSize() { checkHeaderReady(); return mSize; } @Implementation - public int readEntityData(byte[] data, int offset, int size) throws IOException { + protected int readEntityData(byte[] data, int offset, int size) throws IOException { checkHeaderReady(); int result = mInput.read(data, offset, size); if (result < 0) { @@ -97,7 +97,7 @@ public class ShadowBackupDataInput { } @Implementation - public void skipEntityData() throws IOException { + protected void skipEntityData() throws IOException { checkHeaderReady(); mInput.read(new byte[mSize], 0, mSize); } diff --git a/services/robotests/src/com/android/server/testing/shadows/ShadowBackupDataOutput.java b/services/robotests/src/com/android/server/testing/shadows/ShadowBackupDataOutput.java index 5812c3c85a58..4aef28c5d620 100644 --- a/services/robotests/src/com/android/server/testing/shadows/ShadowBackupDataOutput.java +++ b/services/robotests/src/com/android/server/testing/shadows/ShadowBackupDataOutput.java @@ -39,19 +39,19 @@ public class ShadowBackupDataOutput { private int mTransportFlags; @Implementation - public void __constructor__(FileDescriptor fd, long quota, int transportFlags) { + protected void __constructor__(FileDescriptor fd, long quota, int transportFlags) { mFileDescriptor = fd; mQuota = quota; mTransportFlags = transportFlags; } @Implementation - public long getQuota() { + protected long getQuota() { return mQuota; } @Implementation - public int getTransportFlags() { + protected int getTransportFlags() { return mTransportFlags; } @@ -61,7 +61,7 @@ public class ShadowBackupDataOutput { } @Implementation - public int writeEntityHeader(String key, int dataSize) throws IOException { + protected int writeEntityHeader(String key, int dataSize) throws IOException { ensureOutput(); final int size; try (ByteArrayOutputStream byteStream = new ByteArrayOutputStream()) { @@ -81,7 +81,7 @@ public class ShadowBackupDataOutput { } @Implementation - public int writeEntityData(byte[] data, int size) throws IOException { + protected int writeEntityData(byte[] data, int size) throws IOException { ensureOutput(); mOutput.write(data, 0, size); mOutput.flush(); diff --git a/services/robotests/src/com/android/server/testing/shadows/ShadowBinder.java b/services/robotests/src/com/android/server/testing/shadows/ShadowBinder.java index 043d44bdeaea..1ece49ea2060 100644 --- a/services/robotests/src/com/android/server/testing/shadows/ShadowBinder.java +++ b/services/robotests/src/com/android/server/testing/shadows/ShadowBinder.java @@ -17,6 +17,7 @@ package com.android.server.testing.shadows; import android.os.Binder; + import org.robolectric.annotation.Implementation; import org.robolectric.annotation.Implements; @@ -31,14 +32,14 @@ public class ShadowBinder extends org.robolectric.shadows.ShadowBinder { private static Integer originalCallingUid; @Implementation - public static long clearCallingIdentity() { + protected static long clearCallingIdentity() { originalCallingUid = getCallingUid(); setCallingUid(LOCAL_UID); return 1L; } @Implementation - public static void restoreCallingIdentity(long token) { + protected static void restoreCallingIdentity(long token) { setCallingUid(originalCallingUid); } } diff --git a/services/robotests/src/com/android/server/testing/shadows/ShadowEventLog.java b/services/robotests/src/com/android/server/testing/shadows/ShadowEventLog.java index 3df172378f19..5d9c88bd466b 100644 --- a/services/robotests/src/com/android/server/testing/shadows/ShadowEventLog.java +++ b/services/robotests/src/com/android/server/testing/shadows/ShadowEventLog.java @@ -32,14 +32,14 @@ public class ShadowEventLog { private static final LinkedHashSet<Entry> ENTRIES = new LinkedHashSet<>(); @Implementation - public static int writeEvent(int tag, Object... values) { + protected static int writeEvent(int tag, Object... values) { ENTRIES.add(new Entry(tag, Arrays.asList(values))); // Currently we don't care about the return value, if we do, estimate it correctly return 0; } @Implementation - public static int writeEvent(int tag, String string) { + protected static int writeEvent(int tag, String string) { return writeEvent(tag, (Object) string); } diff --git a/services/robotests/src/com/android/server/testing/shadows/ShadowFullBackup.java b/services/robotests/src/com/android/server/testing/shadows/ShadowFullBackup.java index 3c913e317375..47564763bac9 100644 --- a/services/robotests/src/com/android/server/testing/shadows/ShadowFullBackup.java +++ b/services/robotests/src/com/android/server/testing/shadows/ShadowFullBackup.java @@ -31,7 +31,7 @@ public class ShadowFullBackup { * implementation. */ @Implementation - public static int backupToTar( + protected static int backupToTar( String packageName, String domain, String linkdomain, diff --git a/services/robotests/src/com/android/server/testing/shadows/ShadowKeyValueBackupJob.java b/services/robotests/src/com/android/server/testing/shadows/ShadowKeyValueBackupJob.java index 3941f1754054..23c44b0e8c83 100644 --- a/services/robotests/src/com/android/server/testing/shadows/ShadowKeyValueBackupJob.java +++ b/services/robotests/src/com/android/server/testing/shadows/ShadowKeyValueBackupJob.java @@ -18,8 +18,10 @@ package com.android.server.testing.shadows; import android.content.Context; import android.os.Binder; + import com.android.server.backup.BackupManagerConstants; import com.android.server.backup.KeyValueBackupJob; + import org.robolectric.annotation.Implementation; import org.robolectric.annotation.Implements; @@ -32,7 +34,7 @@ public class ShadowKeyValueBackupJob { } @Implementation - public static void schedule(Context ctx, long delay, BackupManagerConstants constants) { + protected static void schedule(Context ctx, long delay, BackupManagerConstants constants) { callingUid = Binder.getCallingUid(); } } diff --git a/services/robotests/src/com/android/server/testing/shadows/ShadowKeyValueBackupTask.java b/services/robotests/src/com/android/server/testing/shadows/ShadowKeyValueBackupTask.java index b7db56b8915b..ca8066403eca 100644 --- a/services/robotests/src/com/android/server/testing/shadows/ShadowKeyValueBackupTask.java +++ b/services/robotests/src/com/android/server/testing/shadows/ShadowKeyValueBackupTask.java @@ -53,7 +53,7 @@ public class ShadowKeyValueBackupTask { private List<String> mPendingFullBackups; @Implementation - public void __constructor__( + protected void __constructor__( BackupManagerService backupManagerService, TransportClient transportClient, String transportDirName, @@ -71,7 +71,7 @@ public class ShadowKeyValueBackupTask { } @Implementation - public void execute() { + protected void execute() { mListener.onFinished("ShadowKeyValueBackupTask.execute()"); } diff --git a/services/robotests/src/com/android/server/testing/shadows/ShadowPerformUnifiedRestoreTask.java b/services/robotests/src/com/android/server/testing/shadows/ShadowPerformUnifiedRestoreTask.java index 0f93c7a1d0b3..228d4eb818a4 100644 --- a/services/robotests/src/com/android/server/testing/shadows/ShadowPerformUnifiedRestoreTask.java +++ b/services/robotests/src/com/android/server/testing/shadows/ShadowPerformUnifiedRestoreTask.java @@ -54,7 +54,7 @@ public class ShadowPerformUnifiedRestoreTask { private OnTaskFinishedListener mListener; @Implementation - public void __constructor__( + protected void __constructor__( BackupManagerService backupManagerService, TransportClient transportClient, IRestoreObserver observer, @@ -74,7 +74,7 @@ public class ShadowPerformUnifiedRestoreTask { } @Implementation - public void execute() { + protected void execute() { mBackupManagerService.setRestoreInProgress(false); mListener.onFinished("ShadowPerformUnifiedRestoreTask.execute()"); } diff --git a/services/robotests/src/com/android/server/testing/shadows/ShadowSlog.java b/services/robotests/src/com/android/server/testing/shadows/ShadowSlog.java index 737b0c85d861..32ef1bc502ae 100644 --- a/services/robotests/src/com/android/server/testing/shadows/ShadowSlog.java +++ b/services/robotests/src/com/android/server/testing/shadows/ShadowSlog.java @@ -21,92 +21,91 @@ import android.util.Slog; import org.robolectric.annotation.Implementation; import org.robolectric.annotation.Implements; -import org.robolectric.shadows.ShadowLog; @Implements(Slog.class) public class ShadowSlog { @Implementation - public static int v(String tag, String msg) { + protected static int v(String tag, String msg) { return Log.v(tag, msg); } @Implementation - public static int v(String tag, String msg, Throwable tr) { + protected static int v(String tag, String msg, Throwable tr) { return Log.v(tag, msg, tr); } @Implementation - public static int d(String tag, String msg) { + protected static int d(String tag, String msg) { return Log.d(tag, msg); } @Implementation - public static int d(String tag, String msg, Throwable tr) { + protected static int d(String tag, String msg, Throwable tr) { return Log.d(tag, msg, tr); } @Implementation - public static int i(String tag, String msg) { + protected static int i(String tag, String msg) { return Log.i(tag, msg); } @Implementation - public static int i(String tag, String msg, Throwable tr) { + protected static int i(String tag, String msg, Throwable tr) { return Log.i(tag, msg, tr); } @Implementation - public static int w(String tag, String msg) { + protected static int w(String tag, String msg) { return Log.w(tag, msg); } @Implementation - public static int w(String tag, String msg, Throwable tr) { + protected static int w(String tag, String msg, Throwable tr) { return Log.w(tag, msg, tr); } @Implementation - public static int w(String tag, Throwable tr) { + protected static int w(String tag, Throwable tr) { return Log.w(tag, tr); } @Implementation - public static int e(String tag, String msg) { + protected static int e(String tag, String msg) { return Log.e(tag, msg); } @Implementation - public static int e(String tag, String msg, Throwable tr) { + protected static int e(String tag, String msg, Throwable tr) { return Log.e(tag, msg, tr); } @Implementation - public static int wtf(String tag, String msg) { + protected static int wtf(String tag, String msg) { return Log.wtf(tag, msg); } @Implementation - public static void wtfQuiet(String tag, String msg) { + protected static void wtfQuiet(String tag, String msg) { Log.wtf(tag, msg); } @Implementation - public static int wtfStack(String tag, String msg) { + protected static int wtfStack(String tag, String msg) { return Log.wtf(tag, msg); } @Implementation - public static int wtf(String tag, Throwable tr) { + protected static int wtf(String tag, Throwable tr) { return Log.wtf(tag, tr); } @Implementation - public static int wtf(String tag, String msg, Throwable tr) { + protected static int wtf(String tag, String msg, Throwable tr) { return Log.wtf(tag, msg, tr); } @Implementation - public static int println(int priority, String tag, String msg) { + protected static int println(int priority, String tag, String msg) { return Log.println(priority, tag, msg); } } diff --git a/services/tests/servicestests/src/com/android/server/StorageManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/StorageManagerServiceTest.java index ee42ce8b591a..e6b328a128b7 100644 --- a/services/tests/servicestests/src/com/android/server/StorageManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/StorageManagerServiceTest.java @@ -125,7 +125,7 @@ public class StorageManagerServiceTest { "/storage/emulated/0/foo.jpg", PID_GREY, UID_GREY); assertTranslation( - "/storage/emulated/0/Android/sandbox/shared:colors/foo.jpg", + "/storage/emulated/0/Android/sandbox/shared-colors/foo.jpg", "/storage/emulated/0/foo.jpg", PID_RED, UID_COLORS); } @@ -137,7 +137,7 @@ public class StorageManagerServiceTest { "/storage/0000-0000/foo/bar.jpg", PID_GREY, UID_GREY); assertTranslation( - "/storage/0000-0000/Android/sandbox/shared:colors/foo/bar.jpg", + "/storage/0000-0000/Android/sandbox/shared-colors/foo/bar.jpg", "/storage/0000-0000/foo/bar.jpg", PID_RED, UID_COLORS); } @@ -152,7 +152,7 @@ public class StorageManagerServiceTest { // Accessing other package paths goes into sandbox assertTranslation( - "/storage/emulated/0/Android/sandbox/shared:colors/" + "/storage/emulated/0/Android/sandbox/shared-colors/" + "Android/data/com.grey/foo.jpg", "/storage/emulated/0/Android/data/com.grey/foo.jpg", PID_RED, UID_COLORS); @@ -201,7 +201,7 @@ public class StorageManagerServiceTest { // Sandboxes can't see paths in other sandboxes try { mService.translateSystemToApp( - "/storage/emulated/0/Android/sandbox/shared:colors/foo.jpg", + "/storage/emulated/0/Android/sandbox/shared-colors/foo.jpg", PID_GREY, UID_GREY); fail(); } catch (SecurityException expected) { diff --git a/services/tests/servicestests/src/com/android/server/power/batterysaver/BatterySaverStateMachineTest.java b/services/tests/servicestests/src/com/android/server/power/batterysaver/BatterySaverStateMachineTest.java index fd04970d50fe..f31ca55d422e 100644 --- a/services/tests/servicestests/src/com/android/server/power/batterysaver/BatterySaverStateMachineTest.java +++ b/services/tests/servicestests/src/com/android/server/power/batterysaver/BatterySaverStateMachineTest.java @@ -115,7 +115,12 @@ public class BatterySaverStateMachineTest { mTarget.setSettingsLocked( mPersistedState.global.getOrDefault(Global.LOW_POWER_MODE, 0) != 0, mPersistedState.global.getOrDefault(Global.LOW_POWER_MODE_STICKY, 0) != 0, - mDevice.getLowPowerModeTriggerLevel()); + mDevice.getLowPowerModeTriggerLevel(), + mPersistedState.global.getOrDefault(Global.AUTOMATIC_POWER_SAVER_MODE, 0), + mPersistedState.global.getOrDefault( + Global.DYNAMIC_POWER_SAVINGS_ENABLED, 0) != 0, + mPersistedState.global.getOrDefault( + Global.DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD, 100)); } public void putGlobalSetting(String key, int value) { @@ -174,6 +179,9 @@ public class BatterySaverStateMachineTest { when(mMockResources.getBoolean( com.android.internal.R.bool.config_batterySaverStickyBehaviourDisabled)) .thenReturn(false); + when(mMockResources.getInteger( + com.android.internal.R.integer.config_dynamicPowerSavingsDefaultDisableThreshold)) + .thenReturn(80); mPersistedState = new DevicePersistedState(); initDevice(); @@ -303,6 +311,7 @@ public class BatterySaverStateMachineTest { @Test public void testAutoBatterySaver() { mDevice.putGlobalSetting(Global.LOW_POWER_MODE_TRIGGER_LEVEL, 50); + mDevice.putGlobalSetting(Global.AUTOMATIC_POWER_SAVER_MODE, 0); assertEquals(false, mDevice.batterySaverEnabled); assertEquals(100, mPersistedState.batteryLevel); @@ -515,6 +524,7 @@ public class BatterySaverStateMachineTest { .thenReturn(true); initDevice(); mDevice.putGlobalSetting(Global.LOW_POWER_MODE_TRIGGER_LEVEL, 50); + mDevice.putGlobalSetting(Global.AUTOMATIC_POWER_SAVER_MODE, 0); mTarget.setBatterySaverEnabledManually(true); @@ -626,4 +636,123 @@ public class BatterySaverStateMachineTest { assertEquals(90, mPersistedState.batteryLevel); assertEquals(false, mPersistedState.batteryLow); } + + @Test + public void testAutoBatterySaver_smartBatterySaverEnabled() { + mDevice.putGlobalSetting(Global.DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD, 50); + mDevice.putGlobalSetting(Global.AUTOMATIC_POWER_SAVER_MODE, 1); + mDevice.putGlobalSetting(Global.DYNAMIC_POWER_SAVINGS_ENABLED, 0); + + assertEquals(false, mDevice.batterySaverEnabled); + assertEquals(100, mPersistedState.batteryLevel); + + mDevice.setBatteryLevel(90); + + assertEquals(false, mDevice.batterySaverEnabled); + assertEquals(90, mPersistedState.batteryLevel); + + mDevice.setBatteryLevel(51); + + assertEquals(false, mDevice.batterySaverEnabled); + assertEquals(51, mPersistedState.batteryLevel); + + // Hit the threshold. BS should be disabled since dynamic power savings still off + mDevice.setBatteryLevel(50); + + assertEquals(false, mDevice.batterySaverEnabled); + assertEquals(50, mPersistedState.batteryLevel); + + // dynamic power savings comes on, battery saver should turn on + mDevice.putGlobalSetting(Global.DYNAMIC_POWER_SAVINGS_ENABLED, 1); + mDevice.setBatteryLevel(40); + + assertEquals(true, mDevice.batterySaverEnabled); + assertEquals(40, mPersistedState.batteryLevel); + + mDevice.setPowered(true); + + assertEquals(false, mDevice.batterySaverEnabled); + assertEquals(40, mPersistedState.batteryLevel); + + mDevice.setPowered(false); + + assertEquals(true, mDevice.batterySaverEnabled); + assertEquals(40, mPersistedState.batteryLevel); + + mTarget.setBatterySaverEnabledManually(false); // Manually disable -> snooze. + + assertEquals(false, mDevice.batterySaverEnabled); + assertEquals(40, mPersistedState.batteryLevel); + + mDevice.setBatteryLevel(30); + + assertEquals(false, mDevice.batterySaverEnabled); + assertEquals(30, mPersistedState.batteryLevel); + + // Plug in and out, snooze will reset. + mDevice.setPowered(true); + mDevice.setPowered(false); + + assertEquals(true, mDevice.batterySaverEnabled); + assertEquals(30, mPersistedState.batteryLevel); + + mDevice.setPowered(true); + mDevice.setBatteryLevel(60); + + assertEquals(false, mDevice.batterySaverEnabled); + assertEquals(60, mPersistedState.batteryLevel); + + mDevice.setPowered(false); + + assertEquals(false, mDevice.batterySaverEnabled); + assertEquals(60, mPersistedState.batteryLevel); + + mDevice.setBatteryLevel(40); + + assertEquals(true, mDevice.batterySaverEnabled); + assertEquals(40, mPersistedState.batteryLevel); + + mDevice.setBatteryLevel(70); + + assertEquals(false, mDevice.batterySaverEnabled); + assertEquals(70, mPersistedState.batteryLevel); + + // Bump up the threshold. + mDevice.putGlobalSetting(Global.DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD, 71); + mDevice.setBatteryLevel(mPersistedState.batteryLevel); + + // changes are only registered if some battery level changed + assertEquals(false, mDevice.batterySaverEnabled); + assertEquals(70, mPersistedState.batteryLevel); + + mDevice.setBatteryLevel(69); + + assertEquals(true, mDevice.batterySaverEnabled); + assertEquals(69, mPersistedState.batteryLevel); + + // Then down. + mDevice.putGlobalSetting(Global.DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD, 60); + mDevice.setBatteryLevel(mPersistedState.batteryLevel); + + // changes are only registered if battery level changed + assertEquals(true, mDevice.batterySaverEnabled); + assertEquals(69, mPersistedState.batteryLevel); + + mDevice.setBatteryLevel(68); + assertEquals(false, mDevice.batterySaverEnabled); + assertEquals(68, mPersistedState.batteryLevel); + + // Reboot in low state -> automatically enable BS. + mDevice.setPowered(false); + mDevice.setBatteryLevel(30); + mTarget.setBatterySaverEnabledManually(false); + + assertEquals(false, mDevice.batterySaverEnabled); + assertEquals(30, mPersistedState.batteryLevel); + + initDevice(); + + assertEquals(true, mDevice.batterySaverEnabled); + assertEquals(30, mPersistedState.batteryLevel); + } } diff --git a/services/tests/servicestests/src/com/android/server/usage/UsageStatsDatabaseTest.java b/services/tests/servicestests/src/com/android/server/usage/UsageStatsDatabaseTest.java index 473682d4d906..bf7f53dd7d8f 100644 --- a/services/tests/servicestests/src/com/android/server/usage/UsageStatsDatabaseTest.java +++ b/services/tests/servicestests/src/com/android/server/usage/UsageStatsDatabaseTest.java @@ -16,13 +16,12 @@ package com.android.server.usage; -import static junit.framework.TestCase.assertNull; import static junit.framework.TestCase.fail; import static org.testng.Assert.assertEquals; import android.app.usage.EventList; -import android.app.usage.UsageEvents; +import android.app.usage.UsageEvents.Event; import android.app.usage.UsageStats; import android.app.usage.UsageStatsManager; import android.content.Context; @@ -112,6 +111,8 @@ public class UsageStatsDatabaseTest { long time = System.currentTimeMillis() - (numberOfEvents*timeProgression); mIntervalStats = new IntervalStats(); + mIntervalStats.majorVersion = 7; + mIntervalStats.minorVersion = 8; mIntervalStats.beginTime = time; mIntervalStats.interactiveTracker.count = 2; mIntervalStats.interactiveTracker.duration = 111111; @@ -127,41 +128,39 @@ public class UsageStatsDatabaseTest { } for (int i = 0; i < numberOfEvents; i++) { - UsageEvents.Event event = new UsageEvents.Event(); + Event event = new Event(); final int packageInt = ((i / 3) % 7); event.mPackage = "fake.package.name" + packageInt; //clusters of 3 events from 7 "apps" if (packageInt == 3) { // Third app is an instant app - event.mFlags |= UsageEvents.Event.FLAG_IS_PACKAGE_INSTANT_APP; - } else if (packageInt == 2 || packageInt == 4) { - event.mClass = ".fake.class.name" + i % 11; + event.mFlags |= Event.FLAG_IS_PACKAGE_INSTANT_APP; } - + event.mClass = ".fake.class.name" + i % 11; event.mTimeStamp = time; event.mEventType = i % 19; //"random" event type switch (event.mEventType) { - case UsageEvents.Event.CONFIGURATION_CHANGE: + case Event.CONFIGURATION_CHANGE: //empty config, event.mConfiguration = new Configuration(); break; - case UsageEvents.Event.SHORTCUT_INVOCATION: + case Event.SHORTCUT_INVOCATION: //"random" shortcut event.mShortcutId = "shortcut" + (i % 8); break; - case UsageEvents.Event.STANDBY_BUCKET_CHANGED: + case Event.STANDBY_BUCKET_CHANGED: //"random" bucket and reason event.mBucketAndReason = (((i % 5 + 1) * 10) << 16) & (i % 5 + 1) << 8; break; - case UsageEvents.Event.NOTIFICATION_INTERRUPTION: + case Event.NOTIFICATION_INTERRUPTION: //"random" channel event.mNotificationChannelId = "channel" + (i % 5); break; } mIntervalStats.events.insert(event); - mIntervalStats.update(event.mPackage, event.mTimeStamp, event.mEventType); + mIntervalStats.update(event.mPackage, event.mClass, event.mTimeStamp, event.mEventType); time += timeProgression; // Arbitrary progression of time } @@ -221,29 +220,30 @@ public class UsageStatsDatabaseTest { // mEndTimeStamp is based on the enclosing IntervalStats, don't bother checking assertEquals(us1.mLastTimeUsed, us2.mLastTimeUsed); assertEquals(us1.mTotalTimeInForeground, us2.mTotalTimeInForeground); + assertEquals(us1.mLastTimeForegroundServiceUsed, us2.mLastTimeForegroundServiceUsed); + assertEquals(us1.mTotalTimeForegroundServiceUsed, us2.mTotalTimeForegroundServiceUsed); // mLaunchCount not persisted, so skipped assertEquals(us1.mAppLaunchCount, us2.mAppLaunchCount); - assertEquals(us1.mLastEvent, us2.mLastEvent); assertEquals(us1.mChooserCounts, us2.mChooserCounts); } - void compareUsageEvent(UsageEvents.Event e1, UsageEvents.Event e2, int debugId) { + void compareUsageEvent(Event e1, Event e2, int debugId) { assertEquals(e1.mPackage, e2.mPackage, "Usage event " + debugId); assertEquals(e1.mClass, e2.mClass, "Usage event " + debugId); assertEquals(e1.mTimeStamp, e2.mTimeStamp, "Usage event " + debugId); assertEquals(e1.mEventType, e2.mEventType, "Usage event " + debugId); switch (e1.mEventType) { - case UsageEvents.Event.CONFIGURATION_CHANGE: + case Event.CONFIGURATION_CHANGE: assertEquals(e1.mConfiguration, e2.mConfiguration, "Usage event " + debugId + e2.mConfiguration.toString()); break; - case UsageEvents.Event.SHORTCUT_INVOCATION: + case Event.SHORTCUT_INVOCATION: assertEquals(e1.mShortcutId, e2.mShortcutId, "Usage event " + debugId); break; - case UsageEvents.Event.STANDBY_BUCKET_CHANGED: + case Event.STANDBY_BUCKET_CHANGED: assertEquals(e1.mBucketAndReason, e2.mBucketAndReason, "Usage event " + debugId); break; - case UsageEvents.Event.NOTIFICATION_INTERRUPTION: + case Event.NOTIFICATION_INTERRUPTION: assertEquals(e1.mNotificationChannelId, e2.mNotificationChannelId, "Usage event " + debugId); break; @@ -252,6 +252,8 @@ public class UsageStatsDatabaseTest { } void compareIntervalStats(IntervalStats stats1, IntervalStats stats2) { + assertEquals(stats1.majorVersion, stats2.majorVersion); + assertEquals(stats1.minorVersion, stats2.minorVersion); assertEquals(stats1.beginTime, stats2.beginTime); assertEquals(stats1.endTime, stats2.endTime); assertEquals(stats1.interactiveTracker.count, stats2.interactiveTracker.count); diff --git a/services/tests/servicestests/src/com/android/server/wm/DimmerTests.java b/services/tests/servicestests/src/com/android/server/wm/DimmerTests.java index b6a7cfba7dc4..991981f62d30 100644 --- a/services/tests/servicestests/src/com/android/server/wm/DimmerTests.java +++ b/services/tests/servicestests/src/com/android/server/wm/DimmerTests.java @@ -37,7 +37,7 @@ import org.junit.Test; /** * Build/Install/Run: - * atest FrameworksServicesTests:DimmerTests; + * atest FrameworksServicesTests:DimmerTests */ @Presubmit public class DimmerTests extends WindowTestsBase { @@ -211,7 +211,7 @@ public class DimmerTests extends WindowTestsBase { mDimmer.updateDims(mTransaction, new Rect()); verify(mSurfaceAnimatorStarter).startAnimation(any(SurfaceAnimator.class), any( SurfaceControl.Transaction.class), any(AnimationAdapter.class), anyBoolean()); - verify(dimLayer).destroy(); + verify(mHost.getPendingTransaction()).destroy(dimLayer); } @Test diff --git a/services/usage/java/com/android/server/usage/AppStandbyController.java b/services/usage/java/com/android/server/usage/AppStandbyController.java index 4f573a475ae7..152831f50770 100644 --- a/services/usage/java/com/android/server/usage/AppStandbyController.java +++ b/services/usage/java/com/android/server/usage/AppStandbyController.java @@ -27,6 +27,8 @@ import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_ACTIVE_TIMEOU import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_EXEMPTED_SYNC_SCHEDULED_DOZE; import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_EXEMPTED_SYNC_SCHEDULED_NON_DOZE; import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_EXEMPTED_SYNC_START; +import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_FOREGROUND_SERVICE_START; +import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_FOREGROUND_SERVICE_STOP; import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_MOVE_TO_BACKGROUND; import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_MOVE_TO_FOREGROUND; import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_NOTIFICATION_SEEN; @@ -844,6 +846,8 @@ public class AppStandbyController { // Inform listeners if necessary if ((event.mEventType == UsageEvents.Event.MOVE_TO_FOREGROUND || event.mEventType == UsageEvents.Event.MOVE_TO_BACKGROUND + || event.mEventType == UsageEvents.Event.FOREGROUND_SERVICE_START + || event.mEventType == UsageEvents.Event.FOREGROUND_SERVICE_STOP || event.mEventType == UsageEvents.Event.SYSTEM_INTERACTION || event.mEventType == UsageEvents.Event.USER_INTERACTION || event.mEventType == UsageEvents.Event.NOTIFICATION_SEEN @@ -896,6 +900,10 @@ public class AppStandbyController { switch (eventType) { case UsageEvents.Event.MOVE_TO_FOREGROUND: return REASON_SUB_USAGE_MOVE_TO_FOREGROUND; case UsageEvents.Event.MOVE_TO_BACKGROUND: return REASON_SUB_USAGE_MOVE_TO_BACKGROUND; + case UsageEvents.Event.FOREGROUND_SERVICE_START: + return REASON_SUB_USAGE_FOREGROUND_SERVICE_START; + case UsageEvents.Event.FOREGROUND_SERVICE_STOP: + return REASON_SUB_USAGE_FOREGROUND_SERVICE_STOP; case UsageEvents.Event.SYSTEM_INTERACTION: return REASON_SUB_USAGE_SYSTEM_INTERACTION; case UsageEvents.Event.USER_INTERACTION: return REASON_SUB_USAGE_USER_INTERACTION; case UsageEvents.Event.NOTIFICATION_SEEN: return REASON_SUB_USAGE_NOTIFICATION_SEEN; diff --git a/services/usage/java/com/android/server/usage/IntervalStats.java b/services/usage/java/com/android/server/usage/IntervalStats.java index db9972f96b21..84052672f6d3 100644 --- a/services/usage/java/com/android/server/usage/IntervalStats.java +++ b/services/usage/java/com/android/server/usage/IntervalStats.java @@ -18,7 +18,6 @@ package com.android.server.usage; import android.app.usage.ConfigurationStats; import android.app.usage.EventList; import android.app.usage.EventStats; -import android.app.usage.TimeSparseArray; import android.app.usage.UsageEvents; import android.app.usage.UsageStats; import android.content.res.Configuration; @@ -26,12 +25,16 @@ import android.util.ArrayMap; import android.util.ArraySet; import android.util.proto.ProtoInputStream; +import com.android.internal.annotations.VisibleForTesting; + import java.io.IOException; import java.util.List; -import com.android.internal.annotations.VisibleForTesting; - public class IntervalStats { + public static final int CURRENT_MAJOR_VERSION = 1; + public static final int CURRENT_MINOR_VERSION = 1; + public int majorVersion = CURRENT_MAJOR_VERSION; + public int minorVersion = CURRENT_MINOR_VERSION; public long beginTime; public long endTime; public long lastTimeSaved; @@ -219,8 +222,12 @@ public class IntervalStats { switch (eventType) { case UsageEvents.Event.MOVE_TO_FOREGROUND: case UsageEvents.Event.MOVE_TO_BACKGROUND: + case UsageEvents.Event.FOREGROUND_SERVICE_START: + case UsageEvents.Event.FOREGROUND_SERVICE_STOP: case UsageEvents.Event.END_OF_DAY: + case UsageEvents.Event.ROLLOVER_FOREGROUND_SERVICE: case UsageEvents.Event.CONTINUE_PREVIOUS_DAY: + case UsageEvents.Event.CONTINUING_FOREGROUND_SERVICE: return true; } return false; @@ -239,32 +246,9 @@ public class IntervalStats { * @hide */ @VisibleForTesting - public void update(String packageName, long timeStamp, int eventType) { + public void update(String packageName, String className, long timeStamp, int eventType) { UsageStats usageStats = getOrCreateUsageStats(packageName); - - // TODO(adamlesinski): Ensure that we recover from incorrect event sequences - // like double MOVE_TO_BACKGROUND, etc. - if (eventType == UsageEvents.Event.MOVE_TO_BACKGROUND || - eventType == UsageEvents.Event.END_OF_DAY) { - if (usageStats.mLastEvent == UsageEvents.Event.MOVE_TO_FOREGROUND || - usageStats.mLastEvent == UsageEvents.Event.CONTINUE_PREVIOUS_DAY) { - usageStats.mTotalTimeInForeground += timeStamp - usageStats.mLastTimeUsed; - } - } - - if (isStatefulEvent(eventType)) { - usageStats.mLastEvent = eventType; - } - - if (isUserVisibleEvent(eventType)) { - usageStats.mLastTimeUsed = timeStamp; - } - usageStats.mEndTimeStamp = timeStamp; - - if (eventType == UsageEvents.Event.MOVE_TO_FOREGROUND) { - usageStats.mLaunchCount += 1; - } - + usageStats.update(className, timeStamp, eventType); endTime = timeStamp; } @@ -372,4 +356,19 @@ public class IntervalStats { } return mStringCache.valueAt(index); } + + /** + * When an IntervalStats object is deserialized, if the object's version number + * is lower than current version number, optionally perform a upgrade. + */ + void upgradeIfNeeded() { + // We only uprade on majorVersion change, no need to upgrade on minorVersion change. + if (!(majorVersion < CURRENT_MAJOR_VERSION)) { + return; + } + /* + Optional upgrade code here. + */ + majorVersion = CURRENT_MAJOR_VERSION; + } } diff --git a/services/usage/java/com/android/server/usage/UsageStatsProto.java b/services/usage/java/com/android/server/usage/UsageStatsProto.java index 30d303f426bf..8e1c06091605 100644 --- a/services/usage/java/com/android/server/usage/UsageStatsProto.java +++ b/services/usage/java/com/android/server/usage/UsageStatsProto.java @@ -21,13 +21,12 @@ import android.app.usage.UsageEvents; import android.app.usage.UsageStats; import android.content.res.Configuration; import android.util.ArrayMap; - import android.util.Slog; import android.util.proto.ProtoInputStream; import android.util.proto.ProtoOutputStream; -import java.io.InputStream; import java.io.IOException; +import java.io.InputStream; import java.io.OutputStream; import java.net.ProtocolException; import java.util.ArrayList; @@ -105,6 +104,7 @@ final class UsageStatsProto { stats = tempPackageIndex; break; case (int) IntervalStatsProto.UsageStats.LAST_TIME_ACTIVE_MS: + // Time attributes stored is an offset of the beginTime. stats.mLastTimeUsed = statsOut.beginTime + proto.readLong( IntervalStatsProto.UsageStats.LAST_TIME_ACTIVE_MS); break; @@ -113,7 +113,8 @@ final class UsageStatsProto { IntervalStatsProto.UsageStats.TOTAL_TIME_ACTIVE_MS); break; case (int) IntervalStatsProto.UsageStats.LAST_EVENT: - stats.mLastEvent = proto.readInt(IntervalStatsProto.UsageStats.LAST_EVENT); + stats.mLastEvent = + proto.readInt(IntervalStatsProto.UsageStats.LAST_EVENT); break; case (int) IntervalStatsProto.UsageStats.APP_LAUNCH_COUNT: stats.mAppLaunchCount = proto.readInt( @@ -125,6 +126,15 @@ final class UsageStatsProto { loadChooserCounts(proto, stats); proto.end(chooserToken); break; + case (int) IntervalStatsProto.UsageStats.LAST_TIME_SERVICE_USED_MS: + // Time attributes stored is an offset of the beginTime. + stats.mLastTimeForegroundServiceUsed = statsOut.beginTime + proto.readLong( + IntervalStatsProto.UsageStats.LAST_TIME_SERVICE_USED_MS); + break; + case (int) IntervalStatsProto.UsageStats.TOTAL_TIME_SERVICE_USED_MS: + stats.mTotalTimeForegroundServiceUsed = proto.readLong( + IntervalStatsProto.UsageStats.TOTAL_TIME_SERVICE_USED_MS); + break; } } if (stats.mLastTimeUsed == 0) { @@ -315,11 +325,18 @@ final class UsageStatsProto { + ") not found in IntervalStats string cache"); proto.write(IntervalStatsProto.UsageStats.PACKAGE, usageStats.mPackageName); } + // Time attributes stored as an offset of the beginTime. proto.write(IntervalStatsProto.UsageStats.LAST_TIME_ACTIVE_MS, usageStats.mLastTimeUsed - stats.beginTime); proto.write(IntervalStatsProto.UsageStats.TOTAL_TIME_ACTIVE_MS, usageStats.mTotalTimeInForeground); - proto.write(IntervalStatsProto.UsageStats.LAST_EVENT, usageStats.mLastEvent); + proto.write(IntervalStatsProto.UsageStats.LAST_EVENT, + usageStats.mLastEvent); + // Time attributes stored as an offset of the beginTime. + proto.write(IntervalStatsProto.UsageStats.LAST_TIME_SERVICE_USED_MS, + usageStats.mLastTimeForegroundServiceUsed - stats.beginTime); + proto.write(IntervalStatsProto.UsageStats.TOTAL_TIME_SERVICE_USED_MS, + usageStats.mTotalTimeForegroundServiceUsed); proto.write(IntervalStatsProto.UsageStats.APP_LAUNCH_COUNT, usageStats.mAppLaunchCount); writeChooserCounts(proto, usageStats); proto.end(token); @@ -471,6 +488,14 @@ final class UsageStatsProto { statsOut.endTime = statsOut.beginTime + proto.readLong( IntervalStatsProto.END_TIME_MS); break; + case (int) IntervalStatsProto.MAJOR_VERSION: + statsOut.majorVersion = proto.readInt( + IntervalStatsProto.MAJOR_VERSION); + break; + case (int) IntervalStatsProto.MINOR_VERSION: + statsOut.minorVersion = proto.readInt( + IntervalStatsProto.MINOR_VERSION); + break; case (int) IntervalStatsProto.INTERACTIVE: loadCountAndTime(proto, IntervalStatsProto.INTERACTIVE, statsOut.interactiveTracker); @@ -505,6 +530,7 @@ final class UsageStatsProto { // endTime not assigned, assume default value of 0 plus beginTime statsOut.endTime = statsOut.beginTime; } + statsOut.upgradeIfNeeded(); return; } } @@ -519,6 +545,8 @@ final class UsageStatsProto { public static void write(OutputStream out, IntervalStats stats) throws IOException { final ProtoOutputStream proto = new ProtoOutputStream(out); proto.write(IntervalStatsProto.END_TIME_MS, stats.endTime - stats.beginTime); + proto.write(IntervalStatsProto.MAJOR_VERSION, stats.majorVersion); + proto.write(IntervalStatsProto.MINOR_VERSION, stats.minorVersion); // String pool should be written before the rest of the usage stats writeStringPool(proto, stats); diff --git a/services/usage/java/com/android/server/usage/UsageStatsXmlV1.java b/services/usage/java/com/android/server/usage/UsageStatsXmlV1.java index a68f9d385ca5..d94062002dcd 100644 --- a/services/usage/java/com/android/server/usage/UsageStatsXmlV1.java +++ b/services/usage/java/com/android/server/usage/UsageStatsXmlV1.java @@ -15,19 +15,18 @@ */ package com.android.server.usage; -import com.android.internal.util.XmlUtils; - -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; -import org.xmlpull.v1.XmlSerializer; - import android.app.usage.ConfigurationStats; -import android.app.usage.EventList; import android.app.usage.UsageEvents; import android.app.usage.UsageStats; import android.content.res.Configuration; import android.util.ArrayMap; +import com.android.internal.util.XmlUtils; + +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; +import org.xmlpull.v1.XmlSerializer; + import java.io.IOException; import java.net.ProtocolException; @@ -61,6 +60,7 @@ final class UsageStatsXmlV1 { private static final String FLAGS_ATTR = "flags"; private static final String CLASS_ATTR = "class"; private static final String TOTAL_TIME_ACTIVE_ATTR = "timeActive"; + private static final String TOTAL_TIME_SERVICE_USED_ATTR = "timeServiceUsed"; private static final String COUNT_ATTR = "count"; private static final String ACTIVE_ATTR = "active"; private static final String LAST_EVENT_ATTR = "lastEvent"; @@ -69,9 +69,12 @@ final class UsageStatsXmlV1 { private static final String STANDBY_BUCKET_ATTR = "standbyBucket"; private static final String APP_LAUNCH_COUNT_ATTR = "appLaunchCount"; private static final String NOTIFICATION_CHANNEL_ATTR = "notificationChannel"; + private static final String MAJOR_VERSION_ATTR = "majorVersion"; + private static final String MINOR_VERSION_ATTR = "minorVersion"; // Time attributes stored as an offset of the beginTime. private static final String LAST_TIME_ACTIVE_ATTR = "lastTimeActive"; + private static final String LAST_TIME_SERVICE_USED_ATTR = "lastTimeServiceUsed"; private static final String END_TIME_ATTR = "endTime"; private static final String TIME_ATTR = "time"; @@ -86,9 +89,14 @@ final class UsageStatsXmlV1 { // Apply the offset to the beginTime to find the absolute time. stats.mLastTimeUsed = statsOut.beginTime + XmlUtils.readLongAttribute( parser, LAST_TIME_ACTIVE_ATTR); + stats.mLastTimeForegroundServiceUsed = statsOut.beginTime + XmlUtils.readLongAttribute( + parser, LAST_TIME_SERVICE_USED_ATTR); stats.mTotalTimeInForeground = XmlUtils.readLongAttribute(parser, TOTAL_TIME_ACTIVE_ATTR); + stats.mTotalTimeForegroundServiceUsed = XmlUtils.readLongAttribute(parser, + TOTAL_TIME_SERVICE_USED_ATTR); stats.mLastEvent = XmlUtils.readIntAttribute(parser, LAST_EVENT_ATTR); - stats.mAppLaunchCount = XmlUtils.readIntAttribute(parser, APP_LAUNCH_COUNT_ATTR, 0); + stats.mAppLaunchCount = XmlUtils.readIntAttribute(parser, APP_LAUNCH_COUNT_ATTR, + 0); int eventCode; while ((eventCode = parser.next()) != XmlPullParser.END_DOCUMENT) { final String tag = parser.getName(); @@ -206,9 +214,12 @@ final class UsageStatsXmlV1 { // Write the time offset. XmlUtils.writeLongAttribute(xml, LAST_TIME_ACTIVE_ATTR, usageStats.mLastTimeUsed - stats.beginTime); - + XmlUtils.writeLongAttribute(xml, LAST_TIME_SERVICE_USED_ATTR, + usageStats.mLastTimeForegroundServiceUsed - stats.beginTime); XmlUtils.writeStringAttribute(xml, PACKAGE_ATTR, usageStats.mPackageName); XmlUtils.writeLongAttribute(xml, TOTAL_TIME_ACTIVE_ATTR, usageStats.mTotalTimeInForeground); + XmlUtils.writeLongAttribute(xml, TOTAL_TIME_SERVICE_USED_ATTR, + usageStats.mTotalTimeForegroundServiceUsed); XmlUtils.writeIntAttribute(xml, LAST_EVENT_ATTR, usageStats.mLastEvent); if (usageStats.mAppLaunchCount > 0) { XmlUtils.writeIntAttribute(xml, APP_LAUNCH_COUNT_ATTR, usageStats.mAppLaunchCount); @@ -339,6 +350,8 @@ final class UsageStatsXmlV1 { } statsOut.endTime = statsOut.beginTime + XmlUtils.readLongAttribute(parser, END_TIME_ATTR); + statsOut.majorVersion = XmlUtils.readIntAttribute(parser, MAJOR_VERSION_ATTR); + statsOut.minorVersion = XmlUtils.readIntAttribute(parser, MINOR_VERSION_ATTR); int eventCode; int outerDepth = parser.getDepth(); @@ -391,6 +404,8 @@ final class UsageStatsXmlV1 { */ public static void write(XmlSerializer xml, IntervalStats stats) throws IOException { XmlUtils.writeLongAttribute(xml, END_TIME_ATTR, stats.endTime - stats.beginTime); + XmlUtils.writeIntAttribute(xml, MAJOR_VERSION_ATTR, stats.majorVersion); + XmlUtils.writeIntAttribute(xml, MINOR_VERSION_ATTR, stats.minorVersion); writeCountAndTime(xml, INTERACTIVE_TAG, stats.interactiveTracker.count, stats.interactiveTracker.duration); diff --git a/services/usage/java/com/android/server/usage/UserUsageStatsService.java b/services/usage/java/com/android/server/usage/UserUsageStatsService.java index 1a8aba085d24..32875dab465f 100644 --- a/services/usage/java/com/android/server/usage/UserUsageStatsService.java +++ b/services/usage/java/com/android/server/usage/UserUsageStatsService.java @@ -22,9 +22,9 @@ import android.app.usage.EventStats; import android.app.usage.UsageEvents; import android.app.usage.UsageStats; import android.app.usage.UsageStatsManager; +import android.content.Context; import android.content.res.Configuration; import android.os.SystemClock; -import android.content.Context; import android.text.format.DateUtils; import android.util.ArrayMap; import android.util.ArraySet; @@ -129,11 +129,17 @@ class UserUsageStatsService { for (IntervalStats stat : mCurrentStats) { final int pkgCount = stat.packageStats.size(); for (int i = 0; i < pkgCount; i++) { - UsageStats pkgStats = stat.packageStats.valueAt(i); - if (pkgStats.mLastEvent == UsageEvents.Event.MOVE_TO_FOREGROUND || - pkgStats.mLastEvent == UsageEvents.Event.CONTINUE_PREVIOUS_DAY) { - stat.update(pkgStats.mPackageName, stat.lastTimeSaved, - UsageEvents.Event.END_OF_DAY); + final UsageStats pkgStats = stat.packageStats.valueAt(i); + if (!pkgStats.mLastForegroundActivityEventMap.isEmpty() + || !pkgStats.mLastForegroundServiceEventMap.isEmpty()) { + if (!pkgStats.mLastForegroundActivityEventMap.isEmpty()) { + stat.update(pkgStats.mPackageName, null, stat.lastTimeSaved, + UsageEvents.Event.END_OF_DAY); + } + if (!pkgStats.mLastForegroundServiceEventMap.isEmpty()) { + stat.update(pkgStats.mPackageName, null , stat.lastTimeSaved, + UsageEvents.Event.ROLLOVER_FOREGROUND_SERVICE); + } notifyStatsChanged(); } } @@ -218,7 +224,8 @@ class UserUsageStatsService { stats.updateKeyguardHidden(event.mTimeStamp); } break; default: { - stats.update(event.mPackage, event.mTimeStamp, event.mEventType); + stats.update(event.mPackage, event.getClassName(), + event.mTimeStamp, event.mEventType); if (incrementAppLaunch) { stats.incrementAppLaunchCount(event.mPackage); } @@ -481,25 +488,43 @@ class UserUsageStatsService { final long startTime = SystemClock.elapsedRealtime(); Slog.i(TAG, mLogPrefix + "Rolling over usage stats"); - // Finish any ongoing events with an END_OF_DAY event. Make a note of which components - // need a new CONTINUE_PREVIOUS_DAY entry. + // Finish any ongoing events with an END_OF_DAY or ROLLOVER_FOREGROUND_SERVICE event. + // Make a note of which components need a new CONTINUE_PREVIOUS_DAY or + // CONTINUING_FOREGROUND_SERVICE entry. final Configuration previousConfig = mCurrentStats[UsageStatsManager.INTERVAL_DAILY].activeConfiguration; ArraySet<String> continuePreviousDay = new ArraySet<>(); + ArrayMap<String, ArrayMap<String, Integer>> continuePreviousDayForegroundActivity = + new ArrayMap<>(); + ArrayMap<String, ArrayMap<String, Integer>> continuePreviousDayForegroundService = + new ArrayMap<>(); for (IntervalStats stat : mCurrentStats) { final int pkgCount = stat.packageStats.size(); for (int i = 0; i < pkgCount; i++) { - UsageStats pkgStats = stat.packageStats.valueAt(i); - if (pkgStats.mLastEvent == UsageEvents.Event.MOVE_TO_FOREGROUND || - pkgStats.mLastEvent == UsageEvents.Event.CONTINUE_PREVIOUS_DAY) { + final UsageStats pkgStats = stat.packageStats.valueAt(i); + if (!pkgStats.mLastForegroundActivityEventMap.isEmpty() + || !pkgStats.mLastForegroundServiceEventMap.isEmpty()) { + if (!pkgStats.mLastForegroundActivityEventMap.isEmpty()) { + continuePreviousDayForegroundActivity.put(pkgStats.mPackageName, + pkgStats.mLastForegroundActivityEventMap); + stat.update(pkgStats.mPackageName, null, + mDailyExpiryDate.getTimeInMillis() - 1, + UsageEvents.Event.END_OF_DAY); + } + if (!pkgStats.mLastForegroundServiceEventMap.isEmpty()) { + continuePreviousDayForegroundService.put(pkgStats.mPackageName, + pkgStats.mLastForegroundServiceEventMap); + stat.update(pkgStats.mPackageName, null, + mDailyExpiryDate.getTimeInMillis() - 1, + UsageEvents.Event.ROLLOVER_FOREGROUND_SERVICE); + } continuePreviousDay.add(pkgStats.mPackageName); - stat.update(pkgStats.mPackageName, mDailyExpiryDate.getTimeInMillis() - 1, - UsageEvents.Event.END_OF_DAY); notifyStatsChanged(); } } - stat.updateConfigurationStats(null, mDailyExpiryDate.getTimeInMillis() - 1); + stat.updateConfigurationStats(null, + mDailyExpiryDate.getTimeInMillis() - 1); stat.commitTime(mDailyExpiryDate.getTimeInMillis() - 1); } @@ -509,10 +534,27 @@ class UserUsageStatsService { final int continueCount = continuePreviousDay.size(); for (int i = 0; i < continueCount; i++) { - String name = continuePreviousDay.valueAt(i); + String pkgName = continuePreviousDay.valueAt(i); final long beginTime = mCurrentStats[UsageStatsManager.INTERVAL_DAILY].beginTime; for (IntervalStats stat : mCurrentStats) { - stat.update(name, beginTime, UsageEvents.Event.CONTINUE_PREVIOUS_DAY); + if (continuePreviousDayForegroundActivity.containsKey(pkgName)) { + final ArrayMap<String, Integer> foregroundActivityEventMap = + continuePreviousDayForegroundActivity.get(pkgName); + final int size = foregroundActivityEventMap.size(); + for (int j = 0; j < size; j++) { + stat.update(pkgName, foregroundActivityEventMap.keyAt(j), beginTime, + UsageEvents.Event.CONTINUE_PREVIOUS_DAY); + } + } + if (continuePreviousDayForegroundService.containsKey(pkgName)) { + final ArrayMap<String, Integer> foregroundServiceEventMap = + continuePreviousDayForegroundService.get(pkgName); + final int size = foregroundServiceEventMap.size(); + for (int j = 0; j < size; j++) { + stat.update(pkgName, foregroundServiceEventMap.keyAt(j), beginTime, + UsageEvents.Event.CONTINUING_FOREGROUND_SERVICE); + } + } stat.updateConfigurationStats(previousConfig, beginTime); notifyStatsChanged(); } @@ -837,10 +879,18 @@ class UserUsageStatsService { return "MOVE_TO_BACKGROUND"; case UsageEvents.Event.MOVE_TO_FOREGROUND: return "MOVE_TO_FOREGROUND"; + case UsageEvents.Event.FOREGROUND_SERVICE_START: + return "FOREGROUND_SERVICE_START"; + case UsageEvents.Event.FOREGROUND_SERVICE_STOP: + return "FOREGROUND_SERVICE_STOP"; case UsageEvents.Event.END_OF_DAY: return "END_OF_DAY"; + case UsageEvents.Event.ROLLOVER_FOREGROUND_SERVICE: + return "ROLLOVER_FOREGROUND_SERVICE"; case UsageEvents.Event.CONTINUE_PREVIOUS_DAY: return "CONTINUE_PREVIOUS_DAY"; + case UsageEvents.Event.CONTINUING_FOREGROUND_SERVICE: + return "CONTINUING_FOREGROUND_SERVICE"; case UsageEvents.Event.CONFIGURATION_CHANGE: return "CONFIGURATION_CHANGE"; case UsageEvents.Event.SYSTEM_INTERACTION: diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java index b6ac91d45e78..cef998651cfe 100644 --- a/telecomm/java/android/telecom/Call.java +++ b/telecomm/java/android/telecom/Call.java @@ -21,6 +21,7 @@ import android.annotation.Nullable; import android.annotation.SystemApi; import android.annotation.UnsupportedAppUsage; import android.net.Uri; +import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.ParcelFileDescriptor; @@ -322,8 +323,11 @@ public final class Call { /** * Call can be upgraded to a video call. * @hide + * @deprecated Use {@link #CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL} and + * {@link #CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL} to indicate for a call + * whether or not video calling is supported. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 119305590) public static final int CAPABILITY_CAN_UPGRADE_TO_VIDEO = 0x00080000; /** diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java index 34603a3f056a..0589cd4a538e 100644 --- a/telecomm/java/android/telecom/Connection.java +++ b/telecomm/java/android/telecom/Connection.java @@ -272,6 +272,9 @@ public abstract class Connection extends Conferenceable { /** * Call can be upgraded to a video call. + * @deprecated Use {@link #CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL} and + * {@link #CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL} to indicate for a call whether or not + * video calling is supported. */ public static final int CAPABILITY_CAN_UPGRADE_TO_VIDEO = 0x00080000; diff --git a/telecomm/java/android/telecom/PhoneAccount.java b/telecomm/java/android/telecom/PhoneAccount.java index 9a4ea9e7f4bd..2ffad0345c64 100644 --- a/telecomm/java/android/telecom/PhoneAccount.java +++ b/telecomm/java/android/telecom/PhoneAccount.java @@ -985,10 +985,10 @@ public final class PhoneAccount implements Parcelable { /** * Generates a string representation of a capabilities bitmask. * - * @param capabilities The capabilities bitmask. * @return String representation of the capabilities bitmask. + * @hide */ - private String capabilitiesToString() { + public String capabilitiesToString() { StringBuilder sb = new StringBuilder(); if (hasCapabilities(CAPABILITY_SELF_MANAGED)) { sb.append("SelfManaged "); diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java index fa16bfe8e795..9f0bdd715359 100644 --- a/telecomm/java/android/telecom/TelecomManager.java +++ b/telecomm/java/android/telecom/TelecomManager.java @@ -15,6 +15,7 @@ package android.telecom; import android.Manifest; +import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.RequiresPermission; import android.annotation.SuppressAutoDoc; @@ -36,6 +37,8 @@ import android.util.Log; import com.android.internal.telecom.ITelecomService; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -413,8 +416,10 @@ public class TelecomManager { * <p> * The phone number of the call used by Telecom to determine which call should be handed over. * @hide + * @deprecated Use the public handover APIs. See + * {@link Call#handoverTo(PhoneAccountHandle, int, Bundle)} for more information. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 119305590) public static final String EXTRA_IS_HANDOVER = "android.telecom.extra.IS_HANDOVER"; /** @@ -528,11 +533,19 @@ public class TelecomManager { public static final char DTMF_CHARACTER_WAIT = ';'; /** + * @hide + */ + @IntDef(prefix = { "TTY_MODE_" }, + value = {TTY_MODE_OFF, TTY_MODE_FULL, TTY_MODE_HCO, TTY_MODE_VCO}) + @Retention(RetentionPolicy.SOURCE) + public @interface TtyMode {} + + /** * TTY (teletypewriter) mode is off. * * @hide */ - @UnsupportedAppUsage + @SystemApi public static final int TTY_MODE_OFF = 0; /** @@ -541,6 +554,7 @@ public class TelecomManager { * * @hide */ + @SystemApi public static final int TTY_MODE_FULL = 1; /** @@ -550,6 +564,7 @@ public class TelecomManager { * * @hide */ + @SystemApi public static final int TTY_MODE_HCO = 2; /** @@ -559,6 +574,7 @@ public class TelecomManager { * * @hide */ + @SystemApi public static final int TTY_MODE_VCO = 3; /** @@ -827,8 +843,9 @@ public class TelecomManager { * @return The phone account handle of the current sim call manager. * * @hide + * @deprecated Use {@link #getSimCallManager()}. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 119305590) public PhoneAccountHandle getSimCallManager(int userId) { try { if (isServiceConnected()) { @@ -929,10 +946,12 @@ public class TelecomManager { * Returns a list of {@link PhoneAccountHandle}s including those which have not been enabled * by the user. * + * @param includeDisabledAccounts When {@code true}, disabled phone accounts will be included, + * when {@code false}, only * @return A list of {@code PhoneAccountHandle} objects. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 119305590) public List<PhoneAccountHandle> getCallCapablePhoneAccounts(boolean includeDisabledAccounts) { try { if (isServiceConnected()) { @@ -1155,7 +1174,7 @@ public class TelecomManager { /** * Used to set the default dialer package. * - * @param packageName to set the default dialer to.. + * @param packageName to set the default dialer to. * * @result {@code true} if the default dialer was successfully changed, {@code false} if * the specified package does not correspond to an installed dialer, or is already @@ -1166,7 +1185,10 @@ public class TelecomManager { * * @hide */ - @UnsupportedAppUsage + @SystemApi + @RequiresPermission(allOf = { + android.Manifest.permission.MODIFY_PHONE_STATE, + android.Manifest.permission.WRITE_SECURE_SETTINGS}) public boolean setDefaultDialer(String packageName) { try { if (isServiceConnected()) { @@ -1179,12 +1201,10 @@ public class TelecomManager { } /** - * Used to determine the dialer package that is preloaded on the system partition. + * Determines the package name of the system-provided default phone app. * * @return package name for the system dialer package or null if no system dialer is preloaded. - * @hide */ - @UnsupportedAppUsage public String getSystemDialerPackage() { try { if (isServiceConnected()) { @@ -1545,8 +1565,9 @@ public class TelecomManager { * - {@link TelecomManager#TTY_MODE_VCO} * @hide */ - @UnsupportedAppUsage - public int getCurrentTtyMode() { + @SystemApi + @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) + public @TtyMode int getCurrentTtyMode() { try { if (isServiceConnected()) { return getTelecomService().getCurrentTtyMode(mContext.getOpPackageName()); diff --git a/telephony/java/android/telephony/CellConfigLte.java b/telephony/java/android/telephony/CellConfigLte.java new file mode 100644 index 000000000000..35769f04c5ae --- /dev/null +++ b/telephony/java/android/telephony/CellConfigLte.java @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.telephony; + +import android.os.Parcel; +import android.os.Parcelable; + +import java.util.Objects; + +/** + * The container of LTE cell related configs. + * @hide + */ +public class CellConfigLte implements Parcelable { + private final boolean mIsEndcAvailable; + + /** @hide */ + public CellConfigLte() { + mIsEndcAvailable = false; + } + + /** @hide */ + public CellConfigLte(boolean isEndcAvailable) { + mIsEndcAvailable = isEndcAvailable; + } + + /** @hide */ + public CellConfigLte(CellConfigLte config) { + mIsEndcAvailable = config.mIsEndcAvailable; + } + + /** + * Indicates that if E-UTRA-NR Dual Connectivity (EN-DC) is supported by the LTE cell. + * + * Reference: 3GPP TS 36.331 v15.2.2 6.3.1 System information blocks. + * + * @return {@code true} if E-UTRA-NR Dual Connectivity (EN-DC) is supported by the LTE cell. + * + */ + boolean isEndcAvailable() { + return mIsEndcAvailable; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public int hashCode() { + return Objects.hash(mIsEndcAvailable); + } + + @Override + public boolean equals(Object other) { + if (!(other instanceof CellConfigLte)) return false; + + CellConfigLte o = (CellConfigLte) other; + return mIsEndcAvailable == o.mIsEndcAvailable; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeBoolean(mIsEndcAvailable); + } + + @Override + public String toString() { + return new StringBuilder().append(this.getClass().getName()) + .append(" :{") + .append(" isEndcAvailable = " + mIsEndcAvailable) + .append(" }") + .toString(); + } + + private CellConfigLte(Parcel in) { + mIsEndcAvailable = in.readBoolean(); + } + + public static final Creator<CellConfigLte> CREATOR = new Creator<CellConfigLte>() { + @Override + public CellConfigLte createFromParcel(Parcel in) { + return new CellConfigLte(in); + } + + @Override + public CellConfigLte[] newArray(int size) { + return new CellConfigLte[0]; + } + }; +} diff --git a/telephony/java/android/telephony/CellInfoLte.java b/telephony/java/android/telephony/CellInfoLte.java index 389f643e05a4..7d5388b7b7f4 100644 --- a/telephony/java/android/telephony/CellInfoLte.java +++ b/telephony/java/android/telephony/CellInfoLte.java @@ -19,7 +19,8 @@ package android.telephony; import android.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; -import android.telephony.Rlog; + +import java.util.Objects; /** * A {@link CellInfo} representing an LTE cell that provides identity and measurement info. @@ -31,6 +32,7 @@ public final class CellInfoLte extends CellInfo implements Parcelable { private CellIdentityLte mCellIdentityLte; private CellSignalStrengthLte mCellSignalStrengthLte; + private CellConfigLte mCellConfig; /** @hide */ @UnsupportedAppUsage @@ -38,6 +40,7 @@ public final class CellInfoLte extends CellInfo implements Parcelable { super(); mCellIdentityLte = new CellIdentityLte(); mCellSignalStrengthLte = new CellSignalStrengthLte(); + mCellConfig = new CellConfigLte(); } /** @hide */ @@ -45,6 +48,7 @@ public final class CellInfoLte extends CellInfo implements Parcelable { super(ci); this.mCellIdentityLte = ci.mCellIdentityLte.copy(); this.mCellSignalStrengthLte = ci.mCellSignalStrengthLte.copy(); + this.mCellConfig = new CellConfigLte(ci.mCellConfig); } @Override @@ -71,26 +75,37 @@ public final class CellInfoLte extends CellInfo implements Parcelable { mCellSignalStrengthLte = css; } + /** @hide */ + public void setCellConfig(CellConfigLte cellConfig) { + if (DBG) log("setCellConfig: " + cellConfig); + mCellConfig = cellConfig; + } + + /** @hide */ + public CellConfigLte getCellConfig() { + if (DBG) log("getCellConfig: " + mCellConfig); + return mCellConfig; + } + /** * @return hash code */ @Override public int hashCode() { - return super.hashCode() + mCellIdentityLte.hashCode() + mCellSignalStrengthLte.hashCode(); + return Objects.hash( + super.hashCode(), + mCellIdentityLte.hashCode(), + mCellSignalStrengthLte.hashCode(), + mCellConfig.hashCode()); } @Override public boolean equals(Object other) { - if (!super.equals(other)) { - return false; - } - try { - CellInfoLte o = (CellInfoLte) other; - return mCellIdentityLte.equals(o.mCellIdentityLte) - && mCellSignalStrengthLte.equals(o.mCellSignalStrengthLte); - } catch (ClassCastException e) { - return false; - } + if (!(other instanceof CellInfoLte)) return false; + CellInfoLte o = (CellInfoLte) other; + return super.equals(o) && mCellIdentityLte.equals(o.mCellIdentityLte) + && mCellSignalStrengthLte.equals(o.mCellSignalStrengthLte) + && mCellConfig.equals(o.mCellConfig); } @Override @@ -101,6 +116,7 @@ public final class CellInfoLte extends CellInfo implements Parcelable { sb.append(super.toString()); sb.append(" ").append(mCellIdentityLte); sb.append(" ").append(mCellSignalStrengthLte); + sb.append(" ").append(mCellConfig); sb.append("}"); return sb.toString(); @@ -119,6 +135,7 @@ public final class CellInfoLte extends CellInfo implements Parcelable { super.writeToParcel(dest, flags, TYPE_LTE); mCellIdentityLte.writeToParcel(dest, flags); mCellSignalStrengthLte.writeToParcel(dest, flags); + mCellConfig.writeToParcel(dest, flags); } /** @@ -129,6 +146,7 @@ public final class CellInfoLte extends CellInfo implements Parcelable { super(in); mCellIdentityLte = CellIdentityLte.CREATOR.createFromParcel(in); mCellSignalStrengthLte = CellSignalStrengthLte.CREATOR.createFromParcel(in); + mCellConfig = CellConfigLte.CREATOR.createFromParcel(in); if (DBG) log("CellInfoLte(Parcel): " + toString()); } diff --git a/telephony/java/android/telephony/DataSpecificRegistrationStates.java b/telephony/java/android/telephony/DataSpecificRegistrationStates.java index 97e3037b3c90..b6e6cbae8c26 100644 --- a/telephony/java/android/telephony/DataSpecificRegistrationStates.java +++ b/telephony/java/android/telephony/DataSpecificRegistrationStates.java @@ -17,17 +17,40 @@ public class DataSpecificRegistrationStates implements Parcelable{ */ public final int maxDataCalls; - DataSpecificRegistrationStates(int maxDataCalls) { + /** + * Indicates if the use of dual connectivity with NR is restricted. + * Reference: 3GPP TS 24.301 v15.03 section 9.3.3.12A. + */ + public final boolean isDcNrRestricted; + + /** + * Indicates if NR is supported by the selected PLMN. + * + * {@code true} if the bit N is in the PLMN-InfoList-r15 is true and the selected PLMN is + * present in plmn-IdentityList at position N. + * Reference: 3GPP TS 36.331 v15.2.2 section 6.3.1 PLMN-InfoList-r15. + * 3GPP TS 36.331 v15.2.2 section 6.2.2 SystemInformationBlockType1 message. + */ + public final boolean isNrAvailable; + + DataSpecificRegistrationStates( + int maxDataCalls, boolean isDcNrRestricted, boolean isNrAvailable) { this.maxDataCalls = maxDataCalls; + this.isDcNrRestricted = isDcNrRestricted; + this.isNrAvailable = isNrAvailable; } private DataSpecificRegistrationStates(Parcel source) { maxDataCalls = source.readInt(); + isDcNrRestricted = source.readBoolean(); + isNrAvailable = source.readBoolean(); } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeInt(maxDataCalls); + dest.writeBoolean(isDcNrRestricted); + dest.writeBoolean(isNrAvailable); } @Override @@ -37,24 +60,30 @@ public class DataSpecificRegistrationStates implements Parcelable{ @Override public String toString() { - return "DataSpecificRegistrationStates {" + " mMaxDataCalls=" + maxDataCalls + "}"; + return new StringBuilder().append(this.getClass().getName()) + .append(" :{") + .append(" maxDataCalls = " + maxDataCalls) + .append(" isDcNrRestricted = " + isDcNrRestricted) + .append(" isNrAvailable = " + isNrAvailable) + .append(" }") + .toString(); } @Override public int hashCode() { - return Objects.hash(maxDataCalls); + return Objects.hash(maxDataCalls, isDcNrRestricted, isNrAvailable); } @Override public boolean equals(Object o) { if (this == o) return true; - if (o == null || !(o instanceof DataSpecificRegistrationStates)) { - return false; - } + if (!(o instanceof DataSpecificRegistrationStates)) return false; DataSpecificRegistrationStates other = (DataSpecificRegistrationStates) o; - return this.maxDataCalls == other.maxDataCalls; + return this.maxDataCalls == other.maxDataCalls + && this.isDcNrRestricted == other.isDcNrRestricted + && this.isNrAvailable == other.isNrAvailable; } public static final Parcelable.Creator<DataSpecificRegistrationStates> CREATOR = diff --git a/telephony/java/android/telephony/NetworkRegistrationState.java b/telephony/java/android/telephony/NetworkRegistrationState.java index 68e512eaff37..75e8eda33cdc 100644 --- a/telephony/java/android/telephony/NetworkRegistrationState.java +++ b/telephony/java/android/telephony/NetworkRegistrationState.java @@ -161,11 +161,9 @@ public class NetworkRegistrationState implements Parcelable { * @hide */ public NetworkRegistrationState(int domain, int transportType, int regState, - int accessNetworkTechnology, int rejectCause, - boolean emergencyOnly, int[] availableServices, - @Nullable CellIdentity cellIdentity, boolean cssSupported, - int roamingIndicator, int systemIsInPrl, - int defaultRoamingIndicator) { + int accessNetworkTechnology, int rejectCause, boolean emergencyOnly, + int[] availableServices, @Nullable CellIdentity cellIdentity, boolean cssSupported, + int roamingIndicator, int systemIsInPrl, int defaultRoamingIndicator) { this(domain, transportType, regState, accessNetworkTechnology, rejectCause, emergencyOnly, availableServices, cellIdentity); @@ -178,13 +176,14 @@ public class NetworkRegistrationState implements Parcelable { * @hide */ public NetworkRegistrationState(int domain, int transportType, int regState, - int accessNetworkTechnology, int rejectCause, - boolean emergencyOnly, int[] availableServices, - @Nullable CellIdentity cellIdentity, int maxDataCalls) { + int accessNetworkTechnology, int rejectCause, boolean emergencyOnly, + int[] availableServices, @Nullable CellIdentity cellIdentity, int maxDataCalls, + boolean isDcNrRestricted, boolean isNrAvailable) { this(domain, transportType, regState, accessNetworkTechnology, rejectCause, emergencyOnly, availableServices, cellIdentity); - mDataSpecificStates = new DataSpecificRegistrationStates(maxDataCalls); + mDataSpecificStates = new DataSpecificRegistrationStates( + maxDataCalls, isDcNrRestricted, isNrAvailable); } protected NetworkRegistrationState(Parcel source) { @@ -345,7 +344,7 @@ public class NetworkRegistrationState implements Parcelable { public boolean equals(Object o) { if (this == o) return true; - if (o == null || !(o instanceof NetworkRegistrationState)) { + if (!(o instanceof NetworkRegistrationState)) { return false; } @@ -357,11 +356,10 @@ public class NetworkRegistrationState implements Parcelable { && mAccessNetworkTechnology == other.mAccessNetworkTechnology && mRejectCause == other.mRejectCause && mEmergencyOnly == other.mEmergencyOnly - && (mAvailableServices == other.mAvailableServices - || Arrays.equals(mAvailableServices, other.mAvailableServices)) - && equals(mCellIdentity, other.mCellIdentity) - && equals(mVoiceSpecificStates, other.mVoiceSpecificStates) - && equals(mDataSpecificStates, other.mDataSpecificStates); + && Arrays.equals(mAvailableServices, other.mAvailableServices) + && Objects.equals(mCellIdentity, other.mCellIdentity) + && Objects.equals(mVoiceSpecificStates, other.mVoiceSpecificStates) + && Objects.equals(mDataSpecificStates, other.mDataSpecificStates); } @Override @@ -391,14 +389,4 @@ public class NetworkRegistrationState implements Parcelable { return new NetworkRegistrationState[size]; } }; - - private static boolean equals(Object o1, Object o2) { - if (o1 == o2) { - return true; - } else if (o1 == null) { - return false; - } else { - return o1.equals(o2); - } - } } diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index a188ef63e3ed..bd1a0fbdcb47 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -9361,4 +9361,55 @@ public class TelephonyManager { } return false; } + + /** + * Set preferred opportunistic data subscription id. + * + * <p>Requires that the calling app has carrier privileges on both primary and + * secondary subscriptions (see + * {@link #hasCarrierPrivileges}), or has permission + * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}. + * + * @param subId which opportunistic subscription + * {@link SubscriptionManager#getOpportunisticSubscriptions} is preferred for cellular data. + * Pass {@link SubscriptionManager#DEFAULT_SUBSCRIPTION_ID} to unset the preference + * @return true if request is accepted, else false. + * + */ + public boolean setPreferredOpportunisticDataSubscription(int subId) { + String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>"; + try { + IAns iAlternativeNetworkService = getIAns(); + if (iAlternativeNetworkService != null) { + return iAlternativeNetworkService.setPreferredData(subId, pkgForDebug); + } + } catch (RemoteException ex) { + Rlog.e(TAG, "setPreferredData RemoteException", ex); + } + return false; + } + + /** + * Get preferred opportunistic data subscription Id + * + * <p>Requires that the calling app has carrier privileges (see {@link #hasCarrierPrivileges}), + * or has permission {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}. + * @return subId preferred opportunistic subscription id or + * {@link SubscriptionManager#DEFAULT_SUBSCRIPTION_ID} if there are no preferred + * subscription id + * + */ + public int getPreferredOpportunisticDataSubscription() { + String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>"; + int subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; + try { + IAns iAlternativeNetworkService = getIAns(); + if (iAlternativeNetworkService != null) { + subId = iAlternativeNetworkService.getPreferredData(pkgForDebug); + } + } catch (RemoteException ex) { + Rlog.e(TAG, "getPreferredData RemoteException", ex); + } + return subId; + } } diff --git a/telephony/java/android/telephony/RcsManager.java b/telephony/java/android/telephony/rcs/RcsManager.java index 00ce03a1f668..0ef4e1552085 100644 --- a/telephony/java/android/telephony/RcsManager.java +++ b/telephony/java/android/telephony/rcs/RcsManager.java @@ -14,18 +14,22 @@ * limitations under the License. */ -package android.telephony; +package android.telephony.rcs; +import android.annotation.SystemService; +import android.content.Context; import android.os.RemoteException; import android.os.ServiceManager; +import android.telephony.Rlog; -import com.android.internal.telephony.IRcs; +import com.android.internal.telephony.rcs.IRcs; /** * RcsManager is the application interface to RcsProvider and provides access methods to * RCS related database tables. * @hide - TODO make this public */ +@SystemService(Context.TELEPHONY_RCS_SERVICE) public class RcsManager { private static final String TAG = "RcsManager"; private static final boolean VDBG = false; diff --git a/telephony/java/android/telephony/rcs/RcsThread.aidl b/telephony/java/android/telephony/rcs/RcsThread.aidl new file mode 100644 index 000000000000..e2e0da5da347 --- /dev/null +++ b/telephony/java/android/telephony/rcs/RcsThread.aidl @@ -0,0 +1,20 @@ +/* +** +** Copyright 2018, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +package android.telephony; + +parcelable RcsThread;
\ No newline at end of file diff --git a/telephony/java/android/telephony/rcs/RcsThread.java b/telephony/java/android/telephony/rcs/RcsThread.java new file mode 100644 index 000000000000..83eb973ec12b --- /dev/null +++ b/telephony/java/android/telephony/rcs/RcsThread.java @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.telephony.rcs; + +import android.os.Parcel; +import android.os.Parcelable; +import android.os.RemoteException; +import android.os.ServiceManager; + +import com.android.internal.telephony.rcs.IRcs; + +/** + * RcsThread represents a single RCS conversation thread. It holds messages that were sent and + * received and events that occured on that thread. + * @hide - TODO(sahinc) make this public + */ +public class RcsThread implements Parcelable { + public static final Creator<RcsThread> CREATOR = new Creator<RcsThread>() { + @Override + public RcsThread createFromParcel(Parcel in) { + return new RcsThread(in); + } + + @Override + public RcsThread[] newArray(int size) { + return new RcsThread[size]; + } + }; + + protected RcsThread(Parcel in) { + } + + /** + * Returns the number of messages in this RCS thread. + * + * @hide + */ + public int getMessageCount() { + try { + IRcs iRcs = IRcs.Stub.asInterface(ServiceManager.getService("ircs")); + if (iRcs != null) { + // TODO(sahinc): substitute to the regular thread id once we have database + // TODO(sahinc): connection in place + return iRcs.getMessageCount(/* rcsThreadId= */ 123); + } + } catch (RemoteException re) { + // TODO(sahinc): Log something meaningful + } + return 0; + } + + /** Implement the Parcelable interface */ + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + } +} diff --git a/telephony/java/com/android/internal/telephony/IAns.aidl b/telephony/java/com/android/internal/telephony/IAns.aidl index 6eb8d666cb1e..e9a46491522e 100755 --- a/telephony/java/com/android/internal/telephony/IAns.aidl +++ b/telephony/java/com/android/internal/telephony/IAns.aidl @@ -49,4 +49,33 @@ interface IAns { * @param callingPackage caller's package name */ boolean isEnabled(String callingPackage); + + /** + * Set preferred opportunistic data subscription id. + * + * <p>Requires that the calling app has carrier privileges on both primary and + * secondary subscriptions (see + * {@link #hasCarrierPrivileges}), or has permission + * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}. + * + * @param subId which opportunistic subscription + * {@link SubscriptionManager#getOpportunisticSubscriptions} is preferred for cellular data. + * Pass {@link SubscriptionManager#DEFAULT_SUBSCRIPTION_ID} to unset the preference + * @param callingPackage caller's package name + * @return true if request is accepted, else false. + * + */ + boolean setPreferredData(int subId, String callingPackage); + + /** + * Get preferred opportunistic data subscription Id + * + * <p>Requires that the calling app has carrier privileges (see {@link #hasCarrierPrivileges}), + * or has permission {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}. + * @return subId preferred opportunistic subscription id or + * {@link SubscriptionManager#DEFAULT_SUBSCRIPTION_ID} if there are no preferred + * subscription id + * + */ + int getPreferredData(String callingPackage); } diff --git a/telephony/java/com/android/internal/telephony/IRcs.aidl b/telephony/java/com/android/internal/telephony/rcs/IRcs.aidl index ede8695ef08e..4c289acd15ef 100644 --- a/telephony/java/com/android/internal/telephony/IRcs.aidl +++ b/telephony/java/com/android/internal/telephony/rcs/IRcs.aidl @@ -14,8 +14,12 @@ * limitations under the License. */ -package com.android.internal.telephony; +package com.android.internal.telephony.rcs; interface IRcs { + // RcsManager APIs void deleteThread(int threadId); + + // RcsThread APIs + int getMessageCount(int rcsThreadId); }
\ No newline at end of file diff --git a/test-mock/api/current.txt b/test-mock/api/current.txt index fc9b4c6831e8..f91d74a30693 100644 --- a/test-mock/api/current.txt +++ b/test-mock/api/current.txt @@ -31,6 +31,7 @@ package android.test.mock { public class MockContext extends android.content.Context { ctor public MockContext(); + method public boolean bindIsolatedService(android.content.Intent, android.content.ServiceConnection, int, java.lang.String); method public boolean bindService(android.content.Intent, android.content.ServiceConnection, int); method public int checkCallingOrSelfPermission(java.lang.String); method public int checkCallingOrSelfUriPermission(android.net.Uri, int); diff --git a/test-mock/src/android/test/mock/MockContext.java b/test-mock/src/android/test/mock/MockContext.java index fa5b896ea126..66be6d9d9840 100644 --- a/test-mock/src/android/test/mock/MockContext.java +++ b/test-mock/src/android/test/mock/MockContext.java @@ -576,6 +576,13 @@ public class MockContext extends Context { throw new UnsupportedOperationException(); } + @Override + public boolean bindIsolatedService(Intent service, + ServiceConnection conn, int flags, + String instanceName) { + throw new UnsupportedOperationException(); + } + /** @hide */ @Override public boolean bindServiceAsUser(Intent service, ServiceConnection conn, int flags, diff --git a/test-runner/src/android/test/IsolatedContext.java b/test-runner/src/android/test/IsolatedContext.java index 6e4c41eef81c..73db4517e130 100644 --- a/test-runner/src/android/test/IsolatedContext.java +++ b/test-runner/src/android/test/IsolatedContext.java @@ -75,6 +75,12 @@ public class IsolatedContext extends ContextWrapper { } @Override + public boolean bindIsolatedService(Intent service, ServiceConnection conn, int flags, + String instanceName) { + return false; + } + + @Override public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) { return null; } diff --git a/tests/RcsTests/Android.mk b/tests/RcsTests/Android.mk new file mode 100644 index 000000000000..adc7cab91389 --- /dev/null +++ b/tests/RcsTests/Android.mk @@ -0,0 +1,19 @@ +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := tests + +# Only compile source java files in this apk. +LOCAL_SRC_FILES := $(call all-java-files-under, src) + +LOCAL_PACKAGE_NAME := RcsTests +LOCAL_PRIVATE_PLATFORM_APIS := true + +LOCAL_CERTIFICATE := platform +LOCAL_JAVA_LIBRARIES := android.test.runner android.test.base +LOCAL_STATIC_JAVA_LIBRARIES := junit android-support-test mockito-target-minus-junit4 + +include $(BUILD_PACKAGE) + +# Use the following include to make our test apk. +include $(call all-makefiles-under,$(LOCAL_PATH)) diff --git a/tests/RcsTests/AndroidManifest.xml b/tests/RcsTests/AndroidManifest.xml new file mode 100644 index 000000000000..a7e7d479a4d9 --- /dev/null +++ b/tests/RcsTests/AndroidManifest.xml @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="utf-8"?> + +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.tests.rcs"> + <application android:label="RCS Test"> + <uses-library android:name="android.test.runner" /> + </application> + + <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner" + android:targetPackage="com.android.tests.rcs"/> +</manifest> diff --git a/tests/RcsTests/src/com/android/tests/rcs/RcsManagerTest.java b/tests/RcsTests/src/com/android/tests/rcs/RcsManagerTest.java new file mode 100644 index 000000000000..7f5f03e0d5a4 --- /dev/null +++ b/tests/RcsTests/src/com/android/tests/rcs/RcsManagerTest.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.tests.rcs; + +import android.support.test.runner.AndroidJUnit4; +import android.telephony.rcs.RcsManager; + +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(AndroidJUnit4.class) +public class RcsManagerTest { + //TODO(sahinc): Add meaningful tests once we have more of the implementation in place + @Test + public void testDeleteThreadDoesntCrash() { + RcsManager mRcsManager = new RcsManager(); + mRcsManager.deleteThread(0); + } +} diff --git a/tests/UsageStatsPerfTests/src/com/android/frameworks/perftests/usage/tests/UsageStatsDatabasePerfTest.java b/tests/UsageStatsPerfTests/src/com/android/frameworks/perftests/usage/tests/UsageStatsDatabasePerfTest.java index 8467bee819cb..be74a6d162ae 100644 --- a/tests/UsageStatsPerfTests/src/com/android/frameworks/perftests/usage/tests/UsageStatsDatabasePerfTest.java +++ b/tests/UsageStatsPerfTests/src/com/android/frameworks/perftests/usage/tests/UsageStatsDatabasePerfTest.java @@ -18,10 +18,6 @@ package com.android.frameworks.perftests.usage.tests; import static junit.framework.Assert.assertEquals; -import com.android.server.usage.UsageStatsDatabase; -import com.android.server.usage.UsageStatsDatabase.StatCombiner; -import com.android.server.usage.IntervalStats; - import android.app.usage.EventList; import android.app.usage.UsageEvents; import android.app.usage.UsageStatsManager; @@ -29,10 +25,14 @@ import android.content.Context; import android.os.SystemClock; import android.perftests.utils.ManualBenchmarkState; import android.perftests.utils.PerfManualStatusReporter; -import android.support.test.filters.LargeTest; import android.support.test.InstrumentationRegistry; +import android.support.test.filters.LargeTest; import android.support.test.runner.AndroidJUnit4; +import com.android.server.usage.IntervalStats; +import com.android.server.usage.UsageStatsDatabase; +import com.android.server.usage.UsageStatsDatabase.StatCombiner; + import org.junit.BeforeClass; import org.junit.Rule; import org.junit.Test; @@ -90,11 +90,13 @@ public class UsageStatsDatabasePerfTest { for (int pkg = 0; pkg < packageCount; pkg++) { UsageEvents.Event event = new UsageEvents.Event(); event.mPackage = "fake.package.name" + pkg; + event.mClass = event.mPackage + ".class1"; event.mTimeStamp = 1; event.mEventType = UsageEvents.Event.MOVE_TO_FOREGROUND; for (int evt = 0; evt < eventsPerPackage; evt++) { intervalStats.events.insert(event); - intervalStats.update(event.mPackage, event.mTimeStamp, event.mEventType); + intervalStats.update(event.mPackage, event.mClass, event.mTimeStamp, + event.mEventType); } } } diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java index 8fc9b9759469..b34ac264ade4 100644 --- a/wifi/java/android/net/wifi/WifiConfiguration.java +++ b/wifi/java/android/net/wifi/WifiConfiguration.java @@ -58,7 +58,7 @@ public class WifiConfiguration implements Parcelable { /** * Current Version of the Backup Serializer. */ - private static final int BACKUP_VERSION = 2; + private static final int BACKUP_VERSION = 3; /** {@hide} */ public static final String ssidVarName = "ssid"; /** {@hide} */ @@ -2420,6 +2420,7 @@ public class WifiConfiguration implements Parcelable { out.writeInt(apChannel); BackupUtils.writeString(out, preSharedKey); out.writeInt(getAuthType()); + out.writeBoolean(hiddenSSID); return baos.toByteArray(); } @@ -2442,6 +2443,9 @@ public class WifiConfiguration implements Parcelable { config.apChannel = in.readInt(); config.preSharedKey = BackupUtils.readString(in); config.allowedKeyManagement.set(in.readInt()); + if (version >= 3) { + config.hiddenSSID = in.readBoolean(); + } return config; } } diff --git a/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java b/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java index 5f3e1b27672e..bf6feac1aba7 100644 --- a/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java +++ b/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java @@ -23,6 +23,7 @@ import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertTrue; import android.net.MacAddress; +import android.net.wifi.WifiConfiguration.KeyMgmt; import android.net.wifi.WifiConfiguration.NetworkSelectionStatus; import android.os.Parcel; import android.support.test.filters.SmallTest; @@ -30,6 +31,9 @@ import android.support.test.filters.SmallTest; import org.junit.Before; import org.junit.Test; +import java.io.ByteArrayInputStream; +import java.io.DataInputStream; + /** * Unit tests for {@link android.net.wifi.WifiConfiguration}. */ @@ -242,4 +246,30 @@ public class WifiConfigurationTest { config.setRandomizedMacAddress(null); assertEquals(defaultMac, config.getRandomizedMacAddress()); } + + /** + * Verifies that the serialization/de-serialization for softap config works. + */ + @Test + public void testSoftApConfigBackupAndRestore() throws Exception { + WifiConfiguration config = new WifiConfiguration(); + config.SSID = "TestAP"; + config.apBand = WifiConfiguration.AP_BAND_5GHZ; + config.apChannel = 40; + config.allowedKeyManagement.set(KeyMgmt.WPA2_PSK); + config.preSharedKey = "TestPsk"; + config.hiddenSSID = true; + + byte[] data = config.getBytesForBackup(); + ByteArrayInputStream bais = new ByteArrayInputStream(data); + DataInputStream in = new DataInputStream(bais); + WifiConfiguration restoredConfig = WifiConfiguration.getWifiConfigFromBackup(in); + + assertEquals(config.SSID, restoredConfig.SSID); + assertEquals(config.preSharedKey, restoredConfig.preSharedKey); + assertEquals(config.getAuthType(), restoredConfig.getAuthType()); + assertEquals(config.apBand, restoredConfig.apBand); + assertEquals(config.apChannel, restoredConfig.apChannel); + assertEquals(config.hiddenSSID, restoredConfig.hiddenSSID); + } } |