diff options
264 files changed, 4260 insertions, 3319 deletions
diff --git a/Android.bp b/Android.bp index 391bcd564f40..cd0720dd2065 100644 --- a/Android.bp +++ b/Android.bp @@ -634,6 +634,7 @@ java_defaults { "wifi/java/android/net/wifi/rtt/IRttCallback.aidl", "wifi/java/android/net/wifi/rtt/IWifiRttManager.aidl", "wifi/java/android/net/wifi/hotspot2/IProvisioningCallback.aidl", + "wifi/java/android/net/wifi/IDppCallback.aidl", "wifi/java/android/net/wifi/IWifiScanner.aidl", "packages/services/PacProcessor/com/android/net/IProxyService.aidl", "packages/services/Proxy/com/android/net/IProxyCallback.aidl", diff --git a/api/current.txt b/api/current.txt index c107e581bc5b..fad607ccefec 100644 --- a/api/current.txt +++ b/api/current.txt @@ -29555,6 +29555,7 @@ package android.net.wifi { method public int getWifiState(); method public boolean is5GHzBandSupported(); method public boolean isDeviceToApRttSupported(); + method public boolean isDppSupported(); method public boolean isEnhancedPowerReportingSupported(); method public boolean isOweSupported(); method public boolean isP2pSupported(); diff --git a/api/system-current.txt b/api/system-current.txt index 7f3c152364b0..f130c69c5de8 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -1221,7 +1221,6 @@ package android.content.pm { public abstract class PackageManager { method public abstract void addOnPermissionsChangeListener(android.content.pm.PackageManager.OnPermissionsChangedListener); method public abstract boolean arePermissionsIndividuallyControlled(); - method public boolean canSuspendPackage(java.lang.String); method public abstract java.util.List<android.content.IntentFilter> getAllIntentFilters(java.lang.String); method public android.content.pm.ApplicationInfo getApplicationInfoAsUser(java.lang.String, int, android.os.UserHandle) throws android.content.pm.PackageManager.NameNotFoundException; method public android.content.pm.dex.ArtManager getArtManager(); @@ -1235,6 +1234,7 @@ package android.content.pm { method public abstract java.util.List<android.content.pm.IntentFilterVerificationInfo> getIntentFilterVerifications(java.lang.String); method public abstract int getIntentVerificationStatusAsUser(java.lang.String, int); method public abstract int getPermissionFlags(java.lang.String, java.lang.String, android.os.UserHandle); + method public java.lang.String[] getUnsuspendablePackages(java.lang.String[]); method public abstract void grantRuntimePermission(java.lang.String, java.lang.String, android.os.UserHandle); method public abstract int installExistingPackage(java.lang.String) throws android.content.pm.PackageManager.NameNotFoundException; method public abstract int installExistingPackage(java.lang.String, int) throws android.content.pm.PackageManager.NameNotFoundException; @@ -3001,6 +3001,7 @@ package android.media { field public static final int AUDIOFOCUS_FLAG_LOCK = 4; // 0x4 field public static final int AUDIOFOCUS_FLAG_PAUSES_ON_DUCKABLE_LOSS = 2; // 0x2 field public static final int FLAG_FROM_KEY = 65536; // 0x10000 + field public static final int SUCCESS = 0; // 0x0 } public static abstract class AudioManager.AudioServerStateCallback { @@ -3117,8 +3118,10 @@ package android.media.audiopolicy { method public int detachMixes(java.util.List<android.media.audiopolicy.AudioMix>); method public int getFocusDuckingBehavior(); method public int getStatus(); + method public int removeUidDeviceAffinity(int); method public int setFocusDuckingBehavior(int) throws java.lang.IllegalArgumentException, java.lang.IllegalStateException; method public void setRegistration(java.lang.String); + method public int setUidDeviceAffinity(int, java.util.List<android.media.AudioDeviceInfo>); method public java.lang.String toLogFriendlyString(); field public static final int FOCUS_POLICY_DUCKING_DEFAULT = 0; // 0x0 field public static final int FOCUS_POLICY_DUCKING_IN_APP = 0; // 0x0 @@ -3715,6 +3718,26 @@ package android.net { package android.net.wifi { + public abstract class DppStatusCallback { + ctor public DppStatusCallback(); + method public abstract void onConfiguratorSuccess(int); + method public abstract void onEnrolleeSuccess(int); + method public abstract void onFailure(int); + method public abstract void onProgress(int); + field public static final int DPP_EVENT_FAILURE = -7; // 0xfffffff9 + field public static final int DPP_EVENT_FAILURE_AUTHENTICATION = -2; // 0xfffffffe + field public static final int DPP_EVENT_FAILURE_BUSY = -5; // 0xfffffffb + field public static final int DPP_EVENT_FAILURE_CONFIGURATION = -4; // 0xfffffffc + field public static final int DPP_EVENT_FAILURE_INVALID_NETWORK = -9; // 0xfffffff7 + field public static final int DPP_EVENT_FAILURE_INVALID_URI = -1; // 0xffffffff + field public static final int DPP_EVENT_FAILURE_NOT_COMPATIBLE = -3; // 0xfffffffd + field public static final int DPP_EVENT_FAILURE_NOT_SUPPORTED = -8; // 0xfffffff8 + field public static final int DPP_EVENT_FAILURE_TIMEOUT = -6; // 0xfffffffa + field public static final int DPP_EVENT_PROGRESS_AUTHENTICATION_SUCCESS = 0; // 0x0 + field public static final int DPP_EVENT_PROGRESS_RESPONSE_PENDING = 1; // 0x1 + field public static final int DPP_EVENT_SUCCESS_CONFIGURATION_SENT = 0; // 0x0 + } + public deprecated class RttManager { method public void disableResponder(android.net.wifi.RttManager.ResponderCallback); method public void enableResponder(android.net.wifi.RttManager.ResponderCallback); @@ -3944,7 +3967,10 @@ package android.net.wifi { method public void save(android.net.wifi.WifiConfiguration, android.net.wifi.WifiManager.ActionListener); method public void setDeviceMobilityState(int); method public boolean setWifiApConfiguration(android.net.wifi.WifiConfiguration); + method public void startDppAsConfiguratorInitiator(java.lang.String, int, int, android.os.Handler, android.net.wifi.DppStatusCallback); + method public void startDppAsEnrolleeInitiator(java.lang.String, android.os.Handler, android.net.wifi.DppStatusCallback); method public boolean startScan(android.os.WorkSource); + method public void stopDppSession(); method public void unregisterNetworkRequestMatchCallback(android.net.wifi.WifiManager.NetworkRequestMatchCallback); field public static final int CHANGE_REASON_ADDED = 0; // 0x0 field public static final int CHANGE_REASON_CONFIG_CHANGE = 2; // 0x2 @@ -3954,6 +3980,8 @@ package android.net.wifi { field public static final int DEVICE_MOBILITY_STATE_LOW_MVMT = 2; // 0x2 field public static final int DEVICE_MOBILITY_STATE_STATIONARY = 3; // 0x3 field public static final int DEVICE_MOBILITY_STATE_UNKNOWN = 0; // 0x0 + field public static final int DPP_NETWORK_ROLE_AP = 1; // 0x1 + field public static final int DPP_NETWORK_ROLE_STA = 0; // 0x0 field public static final java.lang.String EXTRA_CHANGE_REASON = "changeReason"; field public static final java.lang.String EXTRA_MULTIPLE_NETWORKS_CHANGED = "multipleChanges"; field public static final java.lang.String EXTRA_PREVIOUS_WIFI_AP_STATE = "previous_wifi_state"; @@ -7955,6 +7983,7 @@ package android.webkit { method public void callDrawGlFunction(android.graphics.Canvas, long, java.lang.Runnable); method public boolean canInvokeDrawGlFunctor(android.view.View); method public void detachDrawGlFunctor(android.view.View, long); + method public void drawWebViewFunctor(android.graphics.Canvas, int); method public android.app.Application getApplication(); method public java.lang.String getDataDirectorySuffix(); method public java.lang.String getErrorString(android.content.Context, int); diff --git a/api/test-current.txt b/api/test-current.txt index c1e4162e1f1a..9c51c9fe84e0 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -72,6 +72,7 @@ package android.app { method public void resizeStack(int, android.graphics.Rect) throws java.lang.SecurityException; method public void resizeStack(int, android.graphics.Rect, boolean); method public void resizeTask(int, android.graphics.Rect); + method public void setDisplayToSingleTaskInstance(int); method public void setTaskWindowingMode(int, int, boolean) throws java.lang.SecurityException; method public void setTaskWindowingModeSplitScreenPrimary(int, int, boolean, boolean, android.graphics.Rect, boolean) throws java.lang.SecurityException; method public void startSystemLockTaskMode(int); @@ -1153,6 +1154,20 @@ package android.service.autofill { method public void apply(android.service.autofill.ValueFinder, android.widget.RemoteViews, int) throws java.lang.Exception; } + public final class CompositeUserData implements android.os.Parcelable { + ctor public CompositeUserData(android.service.autofill.UserData, android.service.autofill.UserData); + method public int describeContents(); + method public java.lang.String[] getCategoryIds(); + method public android.os.Bundle getDefaultFieldClassificationArgs(); + method public java.lang.String getFieldClassificationAlgorithm(); + method public java.lang.String getFieldClassificationAlgorithmForCategory(java.lang.String); + method public android.util.ArrayMap<java.lang.String, java.lang.String> getFieldClassificationAlgorithms(); + method public android.util.ArrayMap<java.lang.String, android.os.Bundle> getFieldClassificationArgs(); + method public java.lang.String[] getValues(); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator<android.service.autofill.CompositeUserData> CREATOR; + } + public final class CustomDescription implements android.os.Parcelable { method public android.util.SparseArray<android.service.autofill.InternalOnClickAction> getActions(); } diff --git a/cmds/idmap2/Android.bp b/cmds/idmap2/Android.bp index fe7099b2f3ea..abe18ba8a415 100644 --- a/cmds/idmap2/Android.bp +++ b/cmds/idmap2/Android.bp @@ -23,6 +23,7 @@ cc_defaults { ], tidy_flags: [ "-system-headers", + "-warnings-as-errors=*", ], } diff --git a/cmds/statsd/Android.bp b/cmds/statsd/Android.bp index f0b751db5ae9..d610f663cd97 100644 --- a/cmds/statsd/Android.bp +++ b/cmds/statsd/Android.bp @@ -136,7 +136,7 @@ cc_defaults { "android.hardware.power@1.0", "android.hardware.power@1.1", "android.hardware.power.stats@1.0", - "android.hardware.thermal@1.0", + "android.hardware.thermal@2.0", "libpackagelistparser", "libsysutils", "libcutils", diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto index e5415430d82a..5c53a3a585f8 100644 --- a/cmds/statsd/src/atoms.proto +++ b/cmds/statsd/src/atoms.proto @@ -2789,13 +2789,14 @@ message BatteryLevel { * frameworks/base/cmds/statsd/src/external/ResourceThermalManagerPuller.cpp */ message Temperature { - // The type of temperature being reported. Eg. CPU, GPU, SKIN, BATTERY. + // The type of temperature being reported. Eg. CPU, GPU, SKIN, BATTERY, BCL_. optional android.os.TemperatureTypeEnum sensor_location = 1; // The name of the temperature source. Eg. CPU0 optional string sensor_name = 2; // Temperature in tenths of a degree C. + // For BCL, it is decimillivolt, decimilliamps, and percentage * 10. optional int32 temperature_deci_celsius = 3; } diff --git a/cmds/statsd/src/external/ResourceThermalManagerPuller.cpp b/cmds/statsd/src/external/ResourceThermalManagerPuller.cpp index 33a17deabc5a..53709f14564d 100644 --- a/cmds/statsd/src/external/ResourceThermalManagerPuller.cpp +++ b/cmds/statsd/src/external/ResourceThermalManagerPuller.cpp @@ -17,7 +17,7 @@ #define DEBUG false // STOPSHIP if true #include "Log.h" -#include <android/hardware/thermal/1.0/IThermal.h> +#include <android/hardware/thermal/2.0/IThermal.h> #include "external/ResourceThermalManagerPuller.h" #include "external/StatsPuller.h" @@ -31,10 +31,11 @@ using android::hardware::hidl_death_recipient; using android::hardware::hidl_vec; using android::hidl::base::V1_0::IBase; -using android::hardware::thermal::V1_0::IThermal; -using android::hardware::thermal::V1_0::Temperature; -using android::hardware::thermal::V1_0::ThermalStatus; -using android::hardware::thermal::V1_0::ThermalStatusCode; +using ::android::hardware::thermal::V2_0::IThermal; +using ::android::hardware::thermal::V2_0::Temperature; +using ::android::hardware::thermal::V2_0::TemperatureType; +using ::android::hardware::thermal::V1_0::ThermalStatus; +using ::android::hardware::thermal::V1_0::ThermalStatusCode; using android::hardware::Return; using android::hardware::Void; @@ -49,7 +50,7 @@ namespace os { namespace statsd { bool getThermalHalLocked(); -sp<android::hardware::thermal::V1_0::IThermal> gThermalHal = nullptr; +sp<android::hardware::thermal::V2_0::IThermal> gThermalHal = nullptr; std::mutex gThermalHalMutex; struct ThermalHalDeathRecipient : virtual public hidl_death_recipient { @@ -107,7 +108,7 @@ bool ResourceThermalManagerPuller::PullInternal(vector<shared_ptr<LogEvent>>* da data->clear(); bool resultSuccess = true; - Return<void> ret = gThermalHal->getTemperatures( + Return<void> ret = gThermalHal->getCurrentTemperatures(false, TemperatureType::SKIN, [&](ThermalStatus status, const hidl_vec<Temperature>& temps) { if (status.code != ThermalStatusCode::SUCCESS) { ALOGE("Failed to get temperatures from ThermalHAL. Status: %d", status.code); @@ -121,7 +122,7 @@ bool ResourceThermalManagerPuller::PullInternal(vector<shared_ptr<LogEvent>>* da ptr->write((static_cast<int>(temps[i].type))); ptr->write(temps[i].name); // Convert the temperature to an int. - int32_t temp = static_cast<int>(temps[i].currentValue * 10); + int32_t temp = static_cast<int>(temps[i].value * 10); ptr->write(temp); ptr->init(); data->push_back(ptr); diff --git a/core/java/android/app/ActivityTaskManager.java b/core/java/android/app/ActivityTaskManager.java index 4d8c8563ad7c..7eab5dba5f82 100644 --- a/core/java/android/app/ActivityTaskManager.java +++ b/core/java/android/app/ActivityTaskManager.java @@ -430,4 +430,17 @@ public class ActivityTaskManager { e.rethrowFromSystemServer(); } } + + /** + * Makes the display with the given id a single task instance display. I.e the display can only + * contain one task. + */ + @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) + public void setDisplayToSingleTaskInstance(int displayId) { + try { + getService().setDisplayToSingleTaskInstance(displayId); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } } diff --git a/core/java/android/app/ActivityView.java b/core/java/android/app/ActivityView.java index 680fed80d029..0b5776e89524 100644 --- a/core/java/android/app/ActivityView.java +++ b/core/java/android/app/ActivityView.java @@ -83,6 +83,9 @@ public class ActivityView extends ViewGroup { private final SurfaceControl.Transaction mTmpTransaction = new SurfaceControl.Transaction(); private Surface mTmpSurface = new Surface(); + /** The ActivityView is only allowed to contain one task. */ + private final boolean mSingleTaskInstance; + @UnsupportedAppUsage public ActivityView(Context context) { this(context, null /* attrs */); @@ -93,7 +96,13 @@ public class ActivityView extends ViewGroup { } public ActivityView(Context context, AttributeSet attrs, int defStyle) { + this(context, attrs, defStyle, false /*singleTaskInstance*/); + } + + public ActivityView( + Context context, AttributeSet attrs, int defStyle, boolean singleTaskInstance) { super(context, attrs, defStyle); + mSingleTaskInstance = singleTaskInstance; mActivityTaskManager = ActivityTaskManager.getService(); mSurfaceView = new SurfaceView(context); @@ -379,6 +388,9 @@ public class ActivityView extends ViewGroup { try { wm.reparentDisplayContent(displayId, mRootSurfaceControl.getHandle()); wm.dontOverrideDisplayInfo(displayId); + if (mSingleTaskInstance) { + mActivityTaskManager.setDisplayToSingleTaskInstance(displayId); + } } catch (RemoteException e) { e.rethrowAsRuntimeException(); } diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java index 17529a6dacf0..94983e1c3672 100644 --- a/core/java/android/app/ApplicationPackageManager.java +++ b/core/java/android/app/ApplicationPackageManager.java @@ -2299,9 +2299,9 @@ public class ApplicationPackageManager extends PackageManager { } @Override - public boolean canSuspendPackage(String packageName) { + public String[] getUnsuspendablePackages(String[] packageNames) { try { - return mPM.canSuspendPackageForUser(packageName, mContext.getUserId()); + return mPM.getUnsuspendablePackagesForUser(packageNames, mContext.getUserId()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/core/java/android/app/IActivityTaskManager.aidl b/core/java/android/app/IActivityTaskManager.aidl index f549e1890b5e..dd87dc330b65 100644 --- a/core/java/android/app/IActivityTaskManager.aidl +++ b/core/java/android/app/IActivityTaskManager.aidl @@ -452,4 +452,10 @@ interface IActivityTaskManager { * Clears launch params for given packages. */ void clearLaunchParamsForPackages(in List<String> packageNames); + + /** + * Makes the display with the given id a single task instance display. I.e the display can only + * contain one task. + */ + void setDisplayToSingleTaskInstance(int displayId); } diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index 1e3908c556af..34922000e3cf 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -9169,7 +9169,7 @@ public class Intent implements Parcelable, Cloneable { * @param extras The new set of extras in the Intent, or null to erase * all extras. */ - public @NonNull Intent replaceExtras(@NonNull Bundle extras) { + public @NonNull Intent replaceExtras(@Nullable Bundle extras) { mExtras = extras != null ? new Bundle(extras) : null; return this; } diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java index 502fb782bdb6..2978058b2848 100644 --- a/core/java/android/content/pm/ApplicationInfo.java +++ b/core/java/android/content/pm/ApplicationInfo.java @@ -639,6 +639,21 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { */ public static final int PRIVATE_FLAG_HAS_FRAGILE_USER_DATA = 1 << 24; + /** + * Indicate whether this application prefers code integrity, that is, run only code that is + * signed. This requires android:extractNativeLibs to be "false", as well as .dex and .so (if + * any) stored uncompressed inside the APK, which is signed. At run time, the implications + * include: + * + * <ul> + * <li>ART will JIT the dex code directly from the APK. There may be performance characteristic + * changes depend on the actual workload. + * </ul> + * + * @hide + */ + public static final int PRIVATE_FLAG_PREFER_CODE_INTEGRITY = 1 << 25; + /** @hide */ @IntDef(flag = true, prefix = { "PRIVATE_FLAG_" }, value = { PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE, @@ -654,6 +669,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { PRIVATE_FLAG_ISOLATED_SPLIT_LOADING, PRIVATE_FLAG_OEM, PRIVATE_FLAG_PARTIALLY_DIRECT_BOOT_AWARE, + PRIVATE_FLAG_PREFER_CODE_INTEGRITY, PRIVATE_FLAG_PRIVILEGED, PRIVATE_FLAG_PRODUCT, PRIVATE_FLAG_PRODUCT_SERVICES, diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl index a4ea513a055f..64a4479be7ee 100644 --- a/core/java/android/content/pm/IPackageManager.aidl +++ b/core/java/android/content/pm/IPackageManager.aidl @@ -277,7 +277,7 @@ interface IPackageManager { in PersistableBundle appExtras, in PersistableBundle launcherExtras, in SuspendDialogInfo dialogInfo, String callingPackage, int userId); - boolean canSuspendPackageForUser(String packageName, int userId); + String[] getUnsuspendablePackagesForUser(in String[] packageNames, int userId); boolean isPackageSuspendedForUser(String packageName, int userId); diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index 260879625b01..611055759868 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -5969,27 +5969,28 @@ public abstract class PackageManager { } /** - * Returns whether or not a given package can be suspended via a call to {@link + * Returns any packages in a given set of packages that cannot be suspended via a call to {@link * #setPackagesSuspended(String[], boolean, PersistableBundle, PersistableBundle, * SuspendDialogInfo) setPackagesSuspended}. The platform prevents suspending certain critical * packages to keep the device in a functioning state, e.g. the default dialer. * Apps need to hold {@link Manifest.permission#SUSPEND_APPS SUSPEND_APPS} to call this api. * * <p> - * Note that this set of critical packages can change with time, so <em>a value of {@code true} - * returned by this api does not guarantee that a following call to {@link - * #setPackagesSuspended(String[], boolean, PersistableBundle, PersistableBundle, - * SuspendDialogInfo) setPackagesSuspended} for the same package will succeed</em>, especially - * if considerable time elapsed between the two calls. + * Note that this set of critical packages can change with time, so even though a package name + * was not returned by this call, it does not guarantee that a subsequent call to + * {@link #setPackagesSuspended(String[], boolean, PersistableBundle, PersistableBundle, + * SuspendDialogInfo) setPackagesSuspended} for that package will succeed, especially if + * significant time elapsed between the two calls. * - * @param packageName The package to check. - * @return {@code true} if the given package can be suspended, {@code false} otherwise. + * @param packageNames The packages to check. + * @return A list of packages that can not be currently suspended by the system. * @hide */ @SystemApi @RequiresPermission(Manifest.permission.SUSPEND_APPS) - public boolean canSuspendPackage(@NonNull String packageName) { - throw new UnsupportedOperationException("canSuspendPackage not implemented"); + @NonNull + public String[] getUnsuspendablePackages(@NonNull String[] packageNames) { + throw new UnsupportedOperationException("canSuspendPackages not implemented"); } /** diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java index e38b294b4485..2b266b730485 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -475,6 +475,7 @@ public class PackageParser { public final boolean extractNativeLibs; public final boolean isolatedSplits; public final boolean isSplitRequired; + public final boolean preferCodeIntegrity; public ApkLite(String codePath, String packageName, String splitName, boolean isFeatureSplit, @@ -483,7 +484,7 @@ public class PackageParser { int revisionCode, int installLocation, List<VerifierInfo> verifiers, SigningDetails signingDetails, boolean coreApp, boolean debuggable, boolean multiArch, boolean use32bitAbi, - boolean extractNativeLibs, boolean isolatedSplits) { + boolean preferCodeIntegrity, boolean extractNativeLibs, boolean isolatedSplits) { this.codePath = codePath; this.packageName = packageName; this.splitName = splitName; @@ -500,6 +501,7 @@ public class PackageParser { this.debuggable = debuggable; this.multiArch = multiArch; this.use32bitAbi = use32bitAbi; + this.preferCodeIntegrity = preferCodeIntegrity; this.extractNativeLibs = extractNativeLibs; this.isolatedSplits = isolatedSplits; this.isSplitRequired = isSplitRequired; @@ -1722,6 +1724,7 @@ public class PackageParser { boolean isolatedSplits = false; boolean isFeatureSplit = false; boolean isSplitRequired = false; + boolean preferCodeIntegrity = false; String configForSplit = null; String usesSplitName = null; @@ -1784,6 +1787,9 @@ public class PackageParser { if ("extractNativeLibs".equals(attr)) { extractNativeLibs = attrs.getAttributeBooleanValue(i, true); } + if ("preferCodeIntegrity".equals(attr)) { + preferCodeIntegrity = attrs.getAttributeBooleanValue(i, false); + } } } else if (TAG_USES_SPLIT.equals(parser.getName())) { if (usesSplitName != null) { @@ -1800,10 +1806,16 @@ public class PackageParser { } } + if (preferCodeIntegrity && extractNativeLibs) { + throw new PackageParserException( + PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, + "Can't request both preferCodeIntegrity and extractNativeLibs"); + } + return new ApkLite(codePath, packageSplit.first, packageSplit.second, isFeatureSplit, configForSplit, usesSplitName, isSplitRequired, versionCode, versionCodeMajor, revisionCode, installLocation, verifiers, signingDetails, coreApp, debuggable, - multiArch, use32bitAbi, extractNativeLibs, isolatedSplits); + multiArch, use32bitAbi, preferCodeIntegrity, extractNativeLibs, isolatedSplits); } /** @@ -3655,6 +3667,12 @@ public class PackageParser { } if (sa.getBoolean( + R.styleable.AndroidManifestApplication_preferCodeIntegrity, + false)) { + ai.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PREFER_CODE_INTEGRITY; + } + + if (sa.getBoolean( R.styleable.AndroidManifestApplication_defaultToDeviceProtectedStorage, false)) { ai.privateFlags |= ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE; diff --git a/core/java/android/hardware/display/ColorDisplayManager.java b/core/java/android/hardware/display/ColorDisplayManager.java index a4c1332b45d1..dd782ec3a42f 100644 --- a/core/java/android/hardware/display/ColorDisplayManager.java +++ b/core/java/android/hardware/display/ColorDisplayManager.java @@ -60,6 +60,13 @@ public final class ColorDisplayManager { return context.getResources().getBoolean(R.bool.config_nightDisplayAvailable); } + /** + * Returns {@code true} if display white balance is supported by the device. + */ + public static boolean isDisplayWhiteBalanceAvailable(Context context) { + return context.getResources().getBoolean(R.bool.config_displayWhiteBalanceAvailable); + } + private static class ColorDisplayManagerInternal { private static ColorDisplayManagerInternal sInstance; diff --git a/core/java/android/hardware/face/FaceManager.java b/core/java/android/hardware/face/FaceManager.java index bac23b3c00f9..1630b0603f3a 100644 --- a/core/java/android/hardware/face/FaceManager.java +++ b/core/java/android/hardware/face/FaceManager.java @@ -975,14 +975,11 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan mAuthenticationCallback.onAuthenticationAcquired(acquireInfo); } final String msg = getAcquiredString(mContext, acquireInfo, vendorCode); - if (msg == null) { - return; - } final int clientInfo = acquireInfo == FACE_ACQUIRED_VENDOR ? (vendorCode + FACE_ACQUIRED_VENDOR_BASE) : acquireInfo; if (mEnrollmentCallback != null) { mEnrollmentCallback.onEnrollmentHelp(clientInfo, msg); - } else if (mAuthenticationCallback != null) { + } else if (mAuthenticationCallback != null && msg != null) { mAuthenticationCallback.onAuthenticationHelp(clientInfo, msg); } } diff --git a/core/java/android/os/GraphicsEnvironment.java b/core/java/android/os/GraphicsEnvironment.java index ed4b0d618b68..d9793097fc3a 100644 --- a/core/java/android/os/GraphicsEnvironment.java +++ b/core/java/android/os/GraphicsEnvironment.java @@ -58,7 +58,7 @@ public class GraphicsEnvironment { private static final boolean DEBUG = false; private static final String TAG = "GraphicsEnvironment"; private static final String PROPERTY_GFX_DRIVER = "ro.gfx.driver.0"; - private static final String PROPERTY_GFX_DRIVER_WHITELIST = "ro.gfx.driver.whitelist.0"; + private static final String GUP_WHITELIST_FILENAME = "whitelist.txt"; private static final String ANGLE_RULES_FILE = "a4a_rules.json"; private static final String ANGLE_TEMP_RULES = "debug.angle.rules"; private static final String ACTION_ANGLE_FOR_ANDROID = "android.app.action.ANGLE_FOR_ANDROID"; @@ -567,22 +567,11 @@ public class GraphicsEnvironment { private static boolean onWhitelist(Context context, String driverPackageName, String applicationPackageName) { - String whitelistName = SystemProperties.get(PROPERTY_GFX_DRIVER_WHITELIST); - - // Empty whitelist implies no updatable graphics driver. Typically, the pre-installed - // updatable graphics driver is supposed to be a place holder and contains no graphics - // driver and whitelist. - if (whitelistName == null || whitelistName.isEmpty()) { - if (DEBUG) { - Log.w(TAG, "No whitelist found."); - } - return false; - } try { Context driverContext = context.createPackageContext(driverPackageName, Context.CONTEXT_RESTRICTED); AssetManager assets = driverContext.getAssets(); - InputStream stream = assets.open(whitelistName); + InputStream stream = assets.open(GUP_WHITELIST_FILENAME); BufferedReader reader = new BufferedReader(new InputStreamReader(stream)); for (String packageName; (packageName = reader.readLine()) != null; ) { if (packageName.equals(applicationPackageName)) { diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java index 457453fd210b..c4e2b1299fc2 100644 --- a/core/java/android/provider/MediaStore.java +++ b/core/java/android/provider/MediaStore.java @@ -1338,7 +1338,7 @@ public final class MediaStore { public static final String insertImage(ContentResolver cr, Bitmap source, String title, String description) { ContentValues values = new ContentValues(); - values.put(Images.Media.TITLE, title); + values.put(Images.Media.DISPLAY_NAME, title); values.put(Images.Media.DESCRIPTION, description); values.put(Images.Media.MIME_TYPE, "image/jpeg"); diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 32ad79494a81..52effb3d4258 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -7957,6 +7957,15 @@ public final class Settings { "night_display_last_activated_time"; /** + * Control whether display white balance is currently enabled. + * @hide + */ + public static final String DISPLAY_WHITE_BALANCE_ENABLED = "display_white_balance_enabled"; + + private static final Validator DISPLAY_WHITE_BALANCE_ENABLED_VALIDATOR = + BOOLEAN_VALIDATOR; + + /** * Names of the service components that the current user has explicitly allowed to * be a VR mode listener, separated by ':'. * @@ -8405,6 +8414,7 @@ public final class Settings { NIGHT_DISPLAY_CUSTOM_END_TIME, NIGHT_DISPLAY_COLOR_TEMPERATURE, NIGHT_DISPLAY_AUTO_MODE, + DISPLAY_WHITE_BALANCE_ENABLED, SYNC_PARENT_SOUNDS, CAMERA_DOUBLE_TWIST_TO_FLIP_ENABLED, SWIPE_UP_TO_SWITCH_APPS_ENABLED, @@ -8552,6 +8562,7 @@ public final class Settings { VALIDATORS.put(NIGHT_DISPLAY_COLOR_TEMPERATURE, NIGHT_DISPLAY_COLOR_TEMPERATURE_VALIDATOR); VALIDATORS.put(NIGHT_DISPLAY_AUTO_MODE, NIGHT_DISPLAY_AUTO_MODE_VALIDATOR); + VALIDATORS.put(DISPLAY_WHITE_BALANCE_ENABLED, DISPLAY_WHITE_BALANCE_ENABLED_VALIDATOR); VALIDATORS.put(SYNC_PARENT_SOUNDS, SYNC_PARENT_SOUNDS_VALIDATOR); VALIDATORS.put(CAMERA_DOUBLE_TWIST_TO_FLIP_ENABLED, CAMERA_DOUBLE_TWIST_TO_FLIP_ENABLED_VALIDATOR); diff --git a/core/java/android/service/autofill/CompositeUserData.java b/core/java/android/service/autofill/CompositeUserData.java new file mode 100644 index 000000000000..2df4ddf7f8ee --- /dev/null +++ b/core/java/android/service/autofill/CompositeUserData.java @@ -0,0 +1,211 @@ +/* + * 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.service.autofill; + +import static android.view.autofill.Helper.sDebug; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.annotation.TestApi; +import android.os.Bundle; +import android.os.Parcel; +import android.os.Parcelable; +import android.util.ArrayMap; + +import com.android.internal.util.Preconditions; + +import java.util.ArrayList; +import java.util.Collections; + +/** + * Holds both a generic and package-specific userData used for + * <a href="AutofillService.html#FieldClassification">field classification</a>. + * + * @hide + */ +@TestApi +public final class CompositeUserData implements FieldClassificationUserData, Parcelable { + + private final UserData mGenericUserData; + private final UserData mPackageUserData; + + private final String[] mCategories; + private final String[] mValues; + + public CompositeUserData(@Nullable UserData genericUserData, + @NonNull UserData packageUserData) { + mGenericUserData = genericUserData; + mPackageUserData = packageUserData; + + final String[] packageCategoryIds = mPackageUserData.getCategoryIds(); + final String[] packageValues = mPackageUserData.getValues(); + + final ArrayList<String> categoryIds = new ArrayList<>(packageCategoryIds.length); + final ArrayList<String> values = new ArrayList<>(packageValues.length); + + Collections.addAll(categoryIds, packageCategoryIds); + Collections.addAll(values, packageValues); + + if (mGenericUserData != null) { + final String[] genericCategoryIds = mGenericUserData.getCategoryIds(); + final String[] genericValues = mGenericUserData.getValues(); + final int size = mGenericUserData.getCategoryIds().length; + for (int i = 0; i < size; i++) { + if (!categoryIds.contains(genericCategoryIds[i])) { + categoryIds.add(genericCategoryIds[i]); + values.add(genericValues[i]); + } + } + } + + mCategories = new String[categoryIds.size()]; + categoryIds.toArray(mCategories); + mValues = new String[values.size()]; + values.toArray(mValues); + } + + @Nullable + @Override + public String getFieldClassificationAlgorithm() { + final String packageDefaultAlgo = mPackageUserData.getFieldClassificationAlgorithm(); + if (packageDefaultAlgo != null) { + return packageDefaultAlgo; + } else { + return mGenericUserData == null ? null : + mGenericUserData.getFieldClassificationAlgorithm(); + } + } + + @Override + public Bundle getDefaultFieldClassificationArgs() { + final Bundle packageDefaultArgs = mPackageUserData.getDefaultFieldClassificationArgs(); + if (packageDefaultArgs != null) { + return packageDefaultArgs; + } else { + return mGenericUserData == null ? null : + mGenericUserData.getDefaultFieldClassificationArgs(); + } + } + + @Nullable + @Override + public String getFieldClassificationAlgorithmForCategory(@NonNull String categoryId) { + Preconditions.checkNotNull(categoryId); + final ArrayMap<String, String> categoryAlgorithms = getFieldClassificationAlgorithms(); + if (categoryAlgorithms == null || !categoryAlgorithms.containsKey(categoryId)) { + return null; + } + return categoryAlgorithms.get(categoryId); + } + + @Override + public ArrayMap<String, String> getFieldClassificationAlgorithms() { + final ArrayMap<String, String> packageAlgos = mPackageUserData + .getFieldClassificationAlgorithms(); + final ArrayMap<String, String> genericAlgos = mGenericUserData == null ? null : + mGenericUserData.getFieldClassificationAlgorithms(); + + ArrayMap<String, String> categoryAlgorithms = null; + if (packageAlgos != null || genericAlgos != null) { + categoryAlgorithms = new ArrayMap<>(); + if (genericAlgos != null) { + categoryAlgorithms.putAll(genericAlgos); + } + if (packageAlgos != null) { + categoryAlgorithms.putAll(packageAlgos); + } + } + + return categoryAlgorithms; + } + + @Override + public ArrayMap<String, Bundle> getFieldClassificationArgs() { + final ArrayMap<String, Bundle> packageArgs = mPackageUserData.getFieldClassificationArgs(); + final ArrayMap<String, Bundle> genericArgs = mGenericUserData == null ? null : + mGenericUserData.getFieldClassificationArgs(); + + ArrayMap<String, Bundle> categoryArgs = null; + if (packageArgs != null || genericArgs != null) { + categoryArgs = new ArrayMap<>(); + if (genericArgs != null) { + categoryArgs.putAll(genericArgs); + } + if (packageArgs != null) { + categoryArgs.putAll(packageArgs); + } + } + + return categoryArgs; + } + + @Override + public String[] getCategoryIds() { + return mCategories; + } + + @Override + public String[] getValues() { + return mValues; + } + + ///////////////////////////////////// + // Object "contract" methods. // + ///////////////////////////////////// + @Override + public String toString() { + if (!sDebug) return super.toString(); + + // OK to print UserData because UserData.toString() is PII-aware + final StringBuilder builder = new StringBuilder("genericUserData=") + .append(mGenericUserData) + .append(", packageUserData=").append(mPackageUserData); + return builder.toString(); + } + + ///////////////////////////////////// + // Parcelable "contract" methods. // + ///////////////////////////////////// + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel parcel, int flags) { + parcel.writeParcelable(mGenericUserData, 0); + parcel.writeParcelable(mPackageUserData, 0); + } + + public static final Parcelable.Creator<CompositeUserData> CREATOR = + new Parcelable.Creator<CompositeUserData>() { + @Override + public CompositeUserData createFromParcel(Parcel parcel) { + // Always go through the builder to ensure the data ingested by + // the system obeys the contract of the builder to avoid attacks + // using specially crafted parcels. + final UserData genericUserData = parcel.readParcelable(null); + final UserData packageUserData = parcel.readParcelable(null); + return new CompositeUserData(genericUserData, packageUserData); + } + + @Override + public CompositeUserData[] newArray(int size) { + return new CompositeUserData[size]; + } + }; +} diff --git a/core/java/android/service/autofill/FieldClassificationUserData.java b/core/java/android/service/autofill/FieldClassificationUserData.java new file mode 100644 index 000000000000..3d6cac4dca0c --- /dev/null +++ b/core/java/android/service/autofill/FieldClassificationUserData.java @@ -0,0 +1,64 @@ +/* + * 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.service.autofill; + +import android.os.Bundle; +import android.util.ArrayMap; + +/** + * Class used to define a generic UserData for field classification + * + * @hide + */ +public interface FieldClassificationUserData { + /** + * Gets the name of the default algorithm that is used to calculate + * {@link FieldClassification.Match#getScore()} match scores}. + */ + String getFieldClassificationAlgorithm(); + + /** + * Gets the default field classification args. + */ + Bundle getDefaultFieldClassificationArgs(); + + /** + * Gets the name of the field classification algorithm for a specific category. + * + * @param categoryId id of the specific category. + */ + String getFieldClassificationAlgorithmForCategory(String categoryId); + + /** + * Gets all field classification algorithms for specific categories. + */ + ArrayMap<String, String> getFieldClassificationAlgorithms(); + + /** + * Gets all field classification args for specific categories. + */ + ArrayMap<String, Bundle> getFieldClassificationArgs(); + + /** + * Gets all category ids + */ + String[] getCategoryIds(); + + /** + * Gets all string values for field classification + */ + String[] getValues(); +} diff --git a/core/java/android/service/autofill/FillResponse.java b/core/java/android/service/autofill/FillResponse.java index d408e9a6c3b1..93ee8c33195b 100644 --- a/core/java/android/service/autofill/FillResponse.java +++ b/core/java/android/service/autofill/FillResponse.java @@ -516,6 +516,9 @@ public final class FillResponse implements Parcelable { /** * Sets a specific {@link UserData} for field classification for this request only. * + * <p>Any fields in this UserData will override corresponding fields in the generic + * UserData object + * * @return this builder * @throws IllegalStateException if the FillResponse * {@link #setAuthentication(AutofillId[], IntentSender, RemoteViews) diff --git a/core/java/android/service/autofill/UserData.java b/core/java/android/service/autofill/UserData.java index 37f192366f81..a793e09e79f1 100644 --- a/core/java/android/service/autofill/UserData.java +++ b/core/java/android/service/autofill/UserData.java @@ -48,7 +48,7 @@ import java.util.ArrayList; * Defines the user data used for * <a href="AutofillService.html#FieldClassification">field classification</a>. */ -public final class UserData implements Parcelable { +public final class UserData implements FieldClassificationUserData, Parcelable { private static final String TAG = "UserData"; @@ -86,11 +86,13 @@ public final class UserData implements Parcelable { * {@link Match#getScore()} match scores}. */ @Nullable + @Override public String getFieldClassificationAlgorithm() { return mDefaultAlgorithm; } /** @hide */ + @Override public Bundle getDefaultFieldClassificationArgs() { return mDefaultArgs; } @@ -104,6 +106,7 @@ public final class UserData implements Parcelable { * @return String name of algorithm, null if none found. */ @Nullable + @Override public String getFieldClassificationAlgorithmForCategory(@NonNull String categoryId) { Preconditions.checkNotNull(categoryId); if (mCategoryAlgorithms == null || !mCategoryAlgorithms.containsKey(categoryId)) { @@ -120,22 +123,26 @@ public final class UserData implements Parcelable { } /** @hide */ + @Override public String[] getCategoryIds() { return mCategoryIds; } /** @hide */ + @Override public String[] getValues() { return mValues; } /** @hide */ @TestApi + @Override public ArrayMap<String, String> getFieldClassificationAlgorithms() { return mCategoryAlgorithms; } /** @hide */ + @Override public ArrayMap<String, Bundle> getFieldClassificationArgs() { return mCategoryArgs; } diff --git a/core/java/android/util/Range.java b/core/java/android/util/Range.java index 55245065c082..f31ddd9b0307 100644 --- a/core/java/android/util/Range.java +++ b/core/java/android/util/Range.java @@ -28,7 +28,7 @@ import android.hardware.camera2.utils.HashCodeHelpers; * "integers from 1 to 100 inclusive." * </p> * <p> - * All ranges are bounded, and the left side of the range is always {@code >=} + * All ranges are bounded, and the left side of the range is always {@code <=} * the right side of the range. * </p> * diff --git a/core/java/android/view/LayoutInflater.java b/core/java/android/view/LayoutInflater.java index a4d3ce7e20bd..be81c06de1af 100644 --- a/core/java/android/view/LayoutInflater.java +++ b/core/java/android/view/LayoutInflater.java @@ -921,127 +921,127 @@ public abstract class LayoutInflater { AttributeSet attrs) throws XmlPullParserException, IOException { int type; - if (parent instanceof ViewGroup) { - // Apply a theme wrapper, if requested. This is sort of a weird - // edge case, since developers think the <include> overwrites - // values in the AttributeSet of the included View. So, if the - // included View has a theme attribute, we'll need to ignore it. - final TypedArray ta = context.obtainStyledAttributes(attrs, ATTRS_THEME); - final int themeResId = ta.getResourceId(0, 0); - final boolean hasThemeOverride = themeResId != 0; - if (hasThemeOverride) { - context = new ContextThemeWrapper(context, themeResId); - } - ta.recycle(); - - // If the layout is pointing to a theme attribute, we have to - // massage the value to get a resource identifier out of it. - int layout = attrs.getAttributeResourceValue(null, ATTR_LAYOUT, 0); - if (layout == 0) { - final String value = attrs.getAttributeValue(null, ATTR_LAYOUT); - if (value == null || value.length() <= 0) { - throw new InflateException("You must specify a layout in the" - + " include tag: <include layout=\"@layout/layoutID\" />"); - } + if (!(parent instanceof ViewGroup)) { + throw new InflateException("<include /> can only be used inside of a ViewGroup"); + } - // Attempt to resolve the "?attr/name" string to an attribute - // within the default (e.g. application) package. - layout = context.getResources().getIdentifier( - value.substring(1), "attr", context.getPackageName()); + // Apply a theme wrapper, if requested. This is sort of a weird + // edge case, since developers think the <include> overwrites + // values in the AttributeSet of the included View. So, if the + // included View has a theme attribute, we'll need to ignore it. + final TypedArray ta = context.obtainStyledAttributes(attrs, ATTRS_THEME); + final int themeResId = ta.getResourceId(0, 0); + final boolean hasThemeOverride = themeResId != 0; + if (hasThemeOverride) { + context = new ContextThemeWrapper(context, themeResId); + } + ta.recycle(); + // If the layout is pointing to a theme attribute, we have to + // massage the value to get a resource identifier out of it. + int layout = attrs.getAttributeResourceValue(null, ATTR_LAYOUT, 0); + if (layout == 0) { + final String value = attrs.getAttributeValue(null, ATTR_LAYOUT); + if (value == null || value.length() <= 0) { + throw new InflateException("You must specify a layout in the" + + " include tag: <include layout=\"@layout/layoutID\" />"); } - // The layout might be referencing a theme attribute. - if (mTempValue == null) { - mTempValue = new TypedValue(); - } - if (layout != 0 && context.getTheme().resolveAttribute(layout, mTempValue, true)) { - layout = mTempValue.resourceId; - } + // Attempt to resolve the "?attr/name" string to an attribute + // within the default (e.g. application) package. + layout = context.getResources().getIdentifier( + value.substring(1), "attr", context.getPackageName()); - if (layout == 0) { - final String value = attrs.getAttributeValue(null, ATTR_LAYOUT); - throw new InflateException("You must specify a valid layout " - + "reference. The layout ID " + value + " is not valid."); - } else { - final XmlResourceParser childParser = context.getResources().getLayout(layout); + } - try { - final AttributeSet childAttrs = Xml.asAttributeSet(childParser); + // The layout might be referencing a theme attribute. + if (mTempValue == null) { + mTempValue = new TypedValue(); + } + if (layout != 0 && context.getTheme().resolveAttribute(layout, mTempValue, true)) { + layout = mTempValue.resourceId; + } - while ((type = childParser.next()) != XmlPullParser.START_TAG && - type != XmlPullParser.END_DOCUMENT) { - // Empty. - } + if (layout == 0) { + final String value = attrs.getAttributeValue(null, ATTR_LAYOUT); + throw new InflateException("You must specify a valid layout " + + "reference. The layout ID " + value + " is not valid."); + } - if (type != XmlPullParser.START_TAG) { - throw new InflateException(childParser.getPositionDescription() + - ": No start tag found!"); - } + final XmlResourceParser childParser = context.getResources().getLayout(layout); - final String childName = childParser.getName(); + try { + final AttributeSet childAttrs = Xml.asAttributeSet(childParser); - if (TAG_MERGE.equals(childName)) { - // The <merge> tag doesn't support android:theme, so - // nothing special to do here. - rInflate(childParser, parent, context, childAttrs, false); - } else { - final View view = createViewFromTag(parent, childName, - context, childAttrs, hasThemeOverride); - final ViewGroup group = (ViewGroup) parent; - - final TypedArray a = context.obtainStyledAttributes( - attrs, R.styleable.Include); - final int id = a.getResourceId(R.styleable.Include_id, View.NO_ID); - final int visibility = a.getInt(R.styleable.Include_visibility, -1); - a.recycle(); - - // We try to load the layout params set in the <include /> tag. - // If the parent can't generate layout params (ex. missing width - // or height for the framework ViewGroups, though this is not - // necessarily true of all ViewGroups) then we expect it to throw - // a runtime exception. - // We catch this exception and set localParams accordingly: true - // means we successfully loaded layout params from the <include> - // tag, false means we need to rely on the included layout params. - ViewGroup.LayoutParams params = null; - try { - params = group.generateLayoutParams(attrs); - } catch (RuntimeException e) { - // Ignore, just fail over to child attrs. - } - if (params == null) { - params = group.generateLayoutParams(childAttrs); - } - view.setLayoutParams(params); + while ((type = childParser.next()) != XmlPullParser.START_TAG && + type != XmlPullParser.END_DOCUMENT) { + // Empty. + } - // Inflate all children. - rInflateChildren(childParser, view, childAttrs, true); + if (type != XmlPullParser.START_TAG) { + throw new InflateException(childParser.getPositionDescription() + + ": No start tag found!"); + } - if (id != View.NO_ID) { - view.setId(id); - } + final String childName = childParser.getName(); - switch (visibility) { - case 0: - view.setVisibility(View.VISIBLE); - break; - case 1: - view.setVisibility(View.INVISIBLE); - break; - case 2: - view.setVisibility(View.GONE); - break; - } + if (TAG_MERGE.equals(childName)) { + // The <merge> tag doesn't support android:theme, so + // nothing special to do here. + rInflate(childParser, parent, context, childAttrs, false); + } else { + final View view = createViewFromTag(parent, childName, + context, childAttrs, hasThemeOverride); + final ViewGroup group = (ViewGroup) parent; + + final TypedArray a = context.obtainStyledAttributes( + attrs, R.styleable.Include); + final int id = a.getResourceId(R.styleable.Include_id, View.NO_ID); + final int visibility = a.getInt(R.styleable.Include_visibility, -1); + a.recycle(); + + // We try to load the layout params set in the <include /> tag. + // If the parent can't generate layout params (ex. missing width + // or height for the framework ViewGroups, though this is not + // necessarily true of all ViewGroups) then we expect it to throw + // a runtime exception. + // We catch this exception and set localParams accordingly: true + // means we successfully loaded layout params from the <include> + // tag, false means we need to rely on the included layout params. + ViewGroup.LayoutParams params = null; + try { + params = group.generateLayoutParams(attrs); + } catch (RuntimeException e) { + // Ignore, just fail over to child attrs. + } + if (params == null) { + params = group.generateLayoutParams(childAttrs); + } + view.setLayoutParams(params); - group.addView(view); - } - } finally { - childParser.close(); + // Inflate all children. + rInflateChildren(childParser, view, childAttrs, true); + + if (id != View.NO_ID) { + view.setId(id); + } + + switch (visibility) { + case 0: + view.setVisibility(View.VISIBLE); + break; + case 1: + view.setVisibility(View.INVISIBLE); + break; + case 2: + view.setVisibility(View.GONE); + break; } + + group.addView(view); } - } else { - throw new InflateException("<include /> can only be used inside of a ViewGroup"); + } finally { + childParser.close(); } LayoutInflater.consumeChildElements(parser); diff --git a/core/java/android/view/contentcapture/MainContentCaptureSession.java b/core/java/android/view/contentcapture/MainContentCaptureSession.java index ea6f2fe16ef6..92e0187f5b0f 100644 --- a/core/java/android/view/contentcapture/MainContentCaptureSession.java +++ b/core/java/android/view/contentcapture/MainContentCaptureSession.java @@ -258,14 +258,27 @@ public final class MainContentCaptureSession extends ContentCaptureSession { } mEvents = new ArrayList<>(MAX_BUFFER_SIZE); } - mEvents.add(event); + + if (!mEvents.isEmpty() && event.getType() == TYPE_VIEW_TEXT_CHANGED) { + final ContentCaptureEvent lastEvent = mEvents.get(mEvents.size() - 1); + + // TODO(b/121045053): check if flags match + if (lastEvent.getType() == TYPE_VIEW_TEXT_CHANGED + && lastEvent.getId().equals(event.getId())) { + if (VERBOSE) { + Log.v(mTag, "Buffering VIEW_TEXT_CHANGED event, updated text = " + + event.getText()); + } + lastEvent.setText(event.getText()); + } else { + mEvents.add(event); + } + } else { + mEvents.add(event); + } final int numberEvents = mEvents.size(); - // TODO(b/120784831): need to optimize it so we buffer changes until a number of X are - // buffered (either total or per autofillid). For - // example, if the user typed "a", "b", "c" and the threshold is 3, we should buffer - // "a" and "b" then send "abc". final boolean bufferEvent = numberEvents < MAX_BUFFER_SIZE; if (bufferEvent && !forceFlush) { diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java index 414cb8f30fc7..bad2dbfebdc5 100644 --- a/core/java/android/webkit/WebView.java +++ b/core/java/android/webkit/WebView.java @@ -850,7 +850,7 @@ public class WebView extends AbsoluteLayout /** * Asynchronously evaluates JavaScript in the context of the currently displayed page. - * If non-null, |resultCallback| will be invoked with any result returned from that + * If non-null, {@code resultCallback} will be invoked with any result returned from that * execution. This method must be called on the UI thread and the callback will * be made on the UI thread. * <p> diff --git a/core/java/android/webkit/WebViewDelegate.java b/core/java/android/webkit/WebViewDelegate.java index 6ab7f66aedd3..ef69b6333cce 100644 --- a/core/java/android/webkit/WebViewDelegate.java +++ b/core/java/android/webkit/WebViewDelegate.java @@ -138,6 +138,20 @@ public final class WebViewDelegate { } /** + * Call webview draw functor. See API in draw_fn.h. + * @param canvas a hardware accelerated canvas (see {@link Canvas#isHardwareAccelerated()}). + * @param functor created by AwDrawFn_CreateFunctor in draw_fn.h. + */ + public void drawWebViewFunctor(@NonNull Canvas canvas, int functor) { + if (!(canvas instanceof RecordingCanvas)) { + // Canvas#isHardwareAccelerated() is only true for subclasses of RecordingCanvas. + throw new IllegalArgumentException(canvas.getClass().getName() + + " is not a RecordingCanvas canvas"); + } + ((RecordingCanvas) canvas).drawWebViewFunctor(functor); + } + + /** * Detaches the draw GL functor. * * @param nativeDrawGLFunctor the pointer to the native functor that implements diff --git a/core/java/com/android/internal/hardware/AmbientDisplayConfiguration.java b/core/java/com/android/internal/hardware/AmbientDisplayConfiguration.java index 78d366cd2436..2995a8f43268 100644 --- a/core/java/com/android/internal/hardware/AmbientDisplayConfiguration.java +++ b/core/java/com/android/internal/hardware/AmbientDisplayConfiguration.java @@ -16,14 +16,14 @@ package com.android.internal.hardware; -import com.android.internal.R; - import android.content.Context; import android.os.Build; import android.os.SystemProperties; import android.provider.Settings; import android.text.TextUtils; +import com.android.internal.R; + public class AmbientDisplayConfiguration { private final Context mContext; @@ -37,7 +37,8 @@ public class AmbientDisplayConfiguration { public boolean enabled(int user) { return pulseOnNotificationEnabled(user) || pulseOnLongPressEnabled(user) - || alwaysOnEnabled(user); + || alwaysOnEnabled(user) + || wakeLockScreenGestureEnabled(user); } public boolean pulseOnNotificationEnabled(int user) { diff --git a/core/jni/android/graphics/text/LineBreaker.cpp b/core/jni/android/graphics/text/LineBreaker.cpp index e1f2f2b8e069..c23f1e956cd4 100644 --- a/core/jni/android/graphics/text/LineBreaker.cpp +++ b/core/jni/android/graphics/text/LineBreaker.cpp @@ -16,8 +16,6 @@ #define LOG_TAG "LineBreaker" -#include "unicode/locid.h" -#include "unicode/brkiter.h" #include "utils/misc.h" #include "utils/Log.h" #include <nativehelper/ScopedStringChars.h> diff --git a/core/jni/android/graphics/text/MeasuredText.cpp b/core/jni/android/graphics/text/MeasuredText.cpp index d7d96fbf3956..68ba38b93915 100644 --- a/core/jni/android/graphics/text/MeasuredText.cpp +++ b/core/jni/android/graphics/text/MeasuredText.cpp @@ -17,8 +17,6 @@ #define LOG_TAG "MeasuredText" #include "GraphicsJNI.h" -#include "unicode/locid.h" -#include "unicode/brkiter.h" #include "utils/misc.h" #include "utils/Log.h" #include <nativehelper/ScopedStringChars.h> diff --git a/core/jni/android_media_AudioSystem.cpp b/core/jni/android_media_AudioSystem.cpp index 29d8f30543e6..80560f826235 100644 --- a/core/jni/android_media_AudioSystem.cpp +++ b/core/jni/android_media_AudioSystem.cpp @@ -1906,6 +1906,53 @@ exit: return jStatus; } +static jint android_media_AudioSystem_setUidDeviceAffinities(JNIEnv *env, jobject clazz, + jint uid, jintArray deviceTypes, jobjectArray deviceAddresses) { + if (deviceTypes == nullptr || deviceAddresses == nullptr) { + return (jint) AUDIO_JAVA_BAD_VALUE; + } + jsize nb = env->GetArrayLength(deviceTypes); + if (nb == 0 || nb != env->GetArrayLength(deviceAddresses)) { + return (jint) AUDIO_JAVA_BAD_VALUE; + } + // retrieve all device types + std::vector<audio_devices_t> deviceTypesVector; + jint* typesPtr = nullptr; + typesPtr = env->GetIntArrayElements(deviceTypes, 0); + if (typesPtr == nullptr) { + return (jint) AUDIO_JAVA_BAD_VALUE; + } + for (jint i = 0; i < nb; i++) { + deviceTypesVector.push_back((audio_devices_t) typesPtr[i]); + } + env->ReleaseIntArrayElements(deviceTypes, typesPtr, 0); + + // check each address is a string and add device type/address to list for device affinity + Vector<AudioDeviceTypeAddr> deviceVector; + jclass stringClass = FindClassOrDie(env, "java/lang/String"); + for (jint i = 0; i < nb; i++) { + jobject addrJobj = env->GetObjectArrayElement(deviceAddresses, i); + if (!env->IsInstanceOf(addrJobj, stringClass)) { + return (jint) AUDIO_JAVA_BAD_VALUE; + } + String8 address = String8(env->GetStringUTFChars((jstring) addrJobj, NULL)); + AudioDeviceTypeAddr dev = AudioDeviceTypeAddr(typesPtr[i], address); + deviceVector.add(dev); + } + + status_t status = AudioSystem::setUidDeviceAffinities((uid_t) uid, deviceVector); + return (jint) nativeToJavaStatus(status); +} + +static jint android_media_AudioSystem_removeUidDeviceAffinities(JNIEnv *env, jobject clazz, + jint uid) { + + //### + status_t status = NO_ERROR;//AudioSystem::removeUidDeviceAffinities(); + return (jint) nativeToJavaStatus(status); +} + + static jint android_media_AudioSystem_systemReady(JNIEnv *env, jobject thiz) { @@ -2133,6 +2180,10 @@ static const JNINativeMethod gMethods[] = { (void *)android_media_AudioSystem_getAudioHwSyncForSession}, {"registerPolicyMixes", "(Ljava/util/ArrayList;Z)I", (void *)android_media_AudioSystem_registerPolicyMixes}, + {"setUidDeviceAffinities", "(I[I[Ljava/lang/String;)I", + (void *)android_media_AudioSystem_setUidDeviceAffinities}, + {"removeUidDeviceAffinities", "(I)I", + (void *)android_media_AudioSystem_removeUidDeviceAffinities}, {"native_register_dynamic_policy_callback", "()V", (void *)android_media_AudioSystem_registerDynPolicyCallback}, {"native_register_recording_callback", "()V", diff --git a/core/proto/android/os/enums.proto b/core/proto/android/os/enums.proto index db4a4c4d836b..c35706501c3d 100644 --- a/core/proto/android/os/enums.proto +++ b/core/proto/android/os/enums.proto @@ -57,6 +57,7 @@ enum BatteryStatusEnum { } // These constants are defined in hardware/interfaces/thermal/1.0/types.hal +// and in hardware/interfaces/thermal/2.0/types.hal // They are primarily used by android/os/HardwarePropertiesManager.java. // Any change to the types in the thermal hal should be made here as well. enum TemperatureTypeEnum { @@ -65,6 +66,16 @@ enum TemperatureTypeEnum { TEMPERATURE_TYPE_GPU = 1; TEMPERATURE_TYPE_BATTERY = 2; TEMPERATURE_TYPE_SKIN = 3; + TEMPERATURE_TYPE_USB_PORT = 4; + TEMPERATURE_TYPE_POWER_AMPLIFIER = 5; + + // Battery Charge Limit - virtual thermal sensors. + TEMPERATURE_TYPE_BCL_VOLTAGE = 6; + TEMPERATURE_TYPE_BCL_CURRENT = 7; + TEMPERATURE_TYPE_BCL_PERCENTAGE = 8; + + // Neural Processing Unit. + TEMPERATURE_TYPE_NPU = 9; } // Wakelock types, primarily used by android/os/PowerManager.java. diff --git a/core/proto/android/server/activitymanagerservice.proto b/core/proto/android/server/activitymanagerservice.proto index 60561bd9dbc5..6f9a5649d4ac 100644 --- a/core/proto/android/server/activitymanagerservice.proto +++ b/core/proto/android/server/activitymanagerservice.proto @@ -82,6 +82,7 @@ message ActivityDisplayProto { repeated ActivityStackProto stacks = 3; optional int32 focused_stack_id = 4; optional .com.android.server.wm.IdentifierProto resumed_activity = 5; + optional bool single_task_instance = 6; } message ActivityStackProto { diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml index dd51cb615d8a..54f6c632907f 100644 --- a/core/res/res/values/attrs_manifest.xml +++ b/core/res/res/values/attrs_manifest.xml @@ -1112,6 +1112,11 @@ resource] to be present in order to function. Default value is false. --> <attr name="isSplitRequired" format="boolean" /> + <!-- Flag to specify if this app prioritizes code integrity. The system may choose + to run with better integrity guarantee in various components if possible based on the app's + <code>targetSdkVersion</code>. --> + <attr name="preferCodeIntegrity" format="boolean" /> + <!-- Extra options for an activity's UI. Applies to either the {@code <activity>} or {@code <application>} tag. If specified on the {@code <application>} tag these will be considered defaults for all activities in the @@ -1580,6 +1585,7 @@ to honor this flag as well. --> <attr name="usesCleartextTraffic" /> <attr name="multiArch" /> + <attr name="preferCodeIntegrity" /> <attr name="extractNativeLibs" /> <attr name="defaultToDeviceProtectedStorage" format="boolean" /> <attr name="directBootAware" /> diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 11cc1f5caaa0..e4abf8f4cf49 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -929,6 +929,9 @@ in hardware. --> <bool name="config_setColorTransformAccelerated">false</bool> + <!-- Boolean indicating whether display white balance is supported. --> + <bool name="config_displayWhiteBalanceAvailable">false</bool> + <!-- Control whether Night display is available. This should only be enabled on devices that have a HWC implementation that can apply the matrix passed to setColorTransform without impacting power, performance, and app compatibility (e.g. protected content). --> diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index d383362dfe86..2b95dd088434 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -3072,7 +3072,7 @@ <!-- Title of intent resolver dialog when selecting a viewer application that opens URI and a previously used application is known [CHAR LIMIT=128]. --> <string name="whichGiveAccessToApplicationNamed">Give access to open <xliff:g id="host" example="mail.google.com">%1$s</xliff:g> links with <xliff:g id="application" example="Gmail">%2$s</xliff:g></string> - <!-- Label for a link to an intent resolver dialog to open URI [CHAR LIMIT=16] --> + <!-- Label for a link to an intent resolver dialog to open URI [CHAR LIMIT=18] --> <string name="whichGiveAccessToApplicationLabel">Give access</string> <!-- Title of intent resolver dialog when selecting an editor application to run. --> <string name="whichEditApplication">Edit with</string> diff --git a/core/res/res/values/styles_device_defaults.xml b/core/res/res/values/styles_device_defaults.xml index 7c95d1efb60d..200ef2f56f51 100644 --- a/core/res/res/values/styles_device_defaults.xml +++ b/core/res/res/values/styles_device_defaults.xml @@ -355,6 +355,30 @@ easier. <item name="fontFamily">@string/config_bodyFontFamilyMedium</item> </style> <style name="TextAppearance.DeviceDefault.Widget.Toolbar.Title" parent="TextAppearance.DeviceDefault.Widget.ActionBar.Title"/> + <style name="TextAppearance.DeviceDefault.Widget.Toolbar.Subtitle" parent="TextAppearance.DeviceDefault.Widget.ActionBar.Subtitle"/> + <style name="TextAppearance.DeviceDefault.Body1" parent="TextAppearance.Material.Body1"> + <item name="fontFamily">@string/config_bodyFontFamily</item> + </style> + <style name="TextAppearance.DeviceDefault.Body2" parent="TextAppearance.Material.Body2"> + <item name="fontFamily">@string/config_bodyFontFamilyMedium</item> + </style> + <style name="TextAppearance.DeviceDefault.Subhead" parent="TextAppearance.Material.Subhead"> + <item name="fontFamily">@string/config_bodyFontFamily</item> + </style> + <style name="TextAppearance.DeviceDefault.Headline" parent="TextAppearance.Material.Headline"> + <item name="fontFamily">@string/config_bodyFontFamily</item> + </style> + <style name="TextAppearance.DeviceDefault.Display1" parent="TextAppearance.Material.Display1"> + <item name="fontFamily">@string/config_bodyFontFamily</item> + </style> + <style name="TextAppearance.DeviceDefault.Title" parent="TextAppearance.Material.Title"> + <item name="fontFamily">@string/config_bodyFontFamily</item> + </style> + <style name="TextAppearance.DeviceDefault.Caption" parent="TextAppearance.Material.Caption"> + <item name="fontFamily">@string/config_bodyFontFamily</item> + </style> + <style name="TextAppearance.DeviceDefault.ListItem" parent="TextAppearance.DeviceDefault.Subhead"/> + <style name="TextAppearance.DeviceDefault.ListItemSecondary" parent="TextAppearance.DeviceDefault.Body1"/> <!-- Preference Styles --> <style name="Preference.DeviceDefault" parent="Preference.Material"/> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index eda25b363905..e8cbf666c03c 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -3028,6 +3028,7 @@ <java-symbol type="drawable" name="ic_doc_generic" /> <java-symbol type="bool" name="config_setColorTransformAccelerated" /> + <java-symbol type="bool" name="config_displayWhiteBalanceAvailable" /> <java-symbol type="bool" name="config_nightDisplayAvailable" /> <java-symbol type="bool" name="config_allowDisablingAssistDisclosure" /> <java-symbol type="integer" name="config_defaultNightDisplayAutoMode" /> diff --git a/core/res/res/values/themes_device_defaults.xml b/core/res/res/values/themes_device_defaults.xml index 56265cc04c0c..0f4ca66dcd68 100644 --- a/core/res/res/values/themes_device_defaults.xml +++ b/core/res/res/values/themes_device_defaults.xml @@ -68,6 +68,10 @@ easier. <item name="textAppearanceLargePopupMenu">@style/TextAppearance.DeviceDefault.Widget.PopupMenu.Large</item> <item name="textAppearanceSmallPopupMenu">@style/TextAppearance.DeviceDefault.Widget.PopupMenu.Small</item> + <item name="textAppearanceListItem">@style/TextAppearance.DeviceDefault.ListItem</item> + <item name="textAppearanceListItemSmall">@style/TextAppearance.DeviceDefault.ListItem</item> + <item name="textAppearanceListItemSecondary">@style/TextAppearance.DeviceDefault.ListItemSecondary</item> + <!-- Button styles --> <item name="buttonCornerRadius">@dimen/config_buttonCornerRadius</item> <item name="buttonStyle">@style/Widget.DeviceDefault.Button</item> @@ -783,7 +787,6 @@ easier. <!-- Text styles --> <item name="textAppearance">@style/TextAppearance.DeviceDefault</item> <item name="textAppearanceInverse">@style/TextAppearance.DeviceDefault.Inverse</item> - <item name="textAppearanceLarge">@style/TextAppearance.DeviceDefault.Large</item> <item name="textAppearanceMedium">@style/TextAppearance.DeviceDefault.Medium</item> <item name="textAppearanceSmall">@style/TextAppearance.DeviceDefault.Small</item> @@ -792,11 +795,12 @@ easier. <item name="textAppearanceSmallInverse">@style/TextAppearance.DeviceDefault.Small.Inverse</item> <item name="textAppearanceSearchResultTitle">@style/TextAppearance.DeviceDefault.SearchResult.Title</item> <item name="textAppearanceSearchResultSubtitle">@style/TextAppearance.DeviceDefault.SearchResult.Subtitle</item> - <item name="textAppearanceButton">@style/TextAppearance.DeviceDefault.Widget.Button</item> - <item name="textAppearanceLargePopupMenu">@style/TextAppearance.DeviceDefault.Widget.PopupMenu.Large</item> <item name="textAppearanceSmallPopupMenu">@style/TextAppearance.DeviceDefault.Widget.PopupMenu.Small</item> + <item name="textAppearanceListItem">@style/TextAppearance.DeviceDefault.ListItem</item> + <item name="textAppearanceListItemSmall">@style/TextAppearance.DeviceDefault.ListItem</item> + <item name="textAppearanceListItemSecondary">@style/TextAppearance.DeviceDefault.ListItemSecondary</item> <!-- Button styles --> <item name="buttonCornerRadius">@dimen/config_buttonCornerRadius</item> @@ -1439,19 +1443,23 @@ easier. </style> <!-- DeviceDefault theme for a window that should look like the Settings app. --> - <style name="Theme.DeviceDefault.Settings" parent="Theme.Material.Settings"> + <style name="Theme.DeviceDefault.Settings" parent="Theme.DeviceDefault.Light"> + <!-- From Theme.Material.Light.LightStatusBar --> + <item name="windowLightStatusBar">true</item> + + <!-- From Theme.Material.Settings --> + <item name="homeAsUpIndicator">@drawable/ic_ab_back_material_settings</item> + <item name="presentationTheme">@style/Theme.Material.Settings.Dialog.Presentation</item> + <item name="searchDialogTheme">@style/Theme.Material.Settings.SearchBar</item> + <item name="panelMenuListTheme">@style/Theme.Material.Settings.CompactMenu</item> + <!-- action bar --> - <item name="actionBarStyle">@style/Widget.DeviceDefault.Light.ActionBar.Solid</item> <item name="actionBarTheme">@style/ThemeOverlay.DeviceDefault.ActionBar</item> <item name="popupTheme">@style/ThemeOverlay.DeviceDefault.Popup.Light</item> <!-- Color palette --> - <item name="colorBackground">@color/background_device_default_light</item> - <item name="colorPrimary">@color/primary_device_default_settings_light</item> <item name="colorPrimaryDark">@color/primary_dark_device_default_settings_light</item> <item name="colorSecondary">@color/secondary_device_default_settings_light</item> - <item name="colorAccent">@color/accent_device_default_light</item> - <item name="colorError">@color/error_color_device_default_light</item> <item name="colorEdgeEffect">@android:color/black</item> <!-- Add white nav bar with divider that matches material --> @@ -1459,24 +1467,9 @@ easier. <item name="navigationBarColor">@android:color/white</item> <item name="windowLightNavigationBar">true</item> - <!-- Dialog attributes --> - <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item> - <item name="alertDialogTheme">@style/Theme.DeviceDefault.Light.Dialog.Alert</item> - - <!-- Text styles --> - <item name="textAppearanceButton">@style/TextAppearance.DeviceDefault.Widget.Button</item> - <!-- Button styles --> - <item name="buttonCornerRadius">@dimen/config_buttonCornerRadius</item> <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item> - <!-- Progress bar attributes --> - <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item> - <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item> - - <!-- Toolbar attributes --> - <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item> - <item name="listDivider">@color/list_divider_color_light</item> </style> diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp index 7e69e3a8a73f..96798f978465 100644 --- a/libs/hwui/Android.bp +++ b/libs/hwui/Android.bp @@ -61,6 +61,7 @@ cc_defaults { "libstatslog", "libutils", "libEGL", + "libGLESv1_CM", "libGLESv2", "libGLESv3", "libvulkan", diff --git a/libs/hwui/WebViewFunctorManager.cpp b/libs/hwui/WebViewFunctorManager.cpp index 20e77b453706..5b7ae70e821c 100644 --- a/libs/hwui/WebViewFunctorManager.cpp +++ b/libs/hwui/WebViewFunctorManager.cpp @@ -37,7 +37,8 @@ RenderMode WebViewFunctor_queryPlatformRenderMode() { } } -int WebViewFunctor_create(const WebViewFunctorCallbacks& prototype, RenderMode functorMode) { +int WebViewFunctor_create(void* data, const WebViewFunctorCallbacks& prototype, + RenderMode functorMode) { if (functorMode != RenderMode::OpenGL_ES && functorMode != RenderMode::Vulkan) { ALOGW("Unknown rendermode %d", (int)functorMode); return -1; @@ -47,7 +48,7 @@ int WebViewFunctor_create(const WebViewFunctorCallbacks& prototype, RenderMode f ALOGW("Unable to map from GLES platform to a vulkan functor"); return -1; } - return WebViewFunctorManager::instance().createFunctor(prototype, functorMode); + return WebViewFunctorManager::instance().createFunctor(data, prototype, functorMode); } void WebViewFunctor_release(int functor) { @@ -56,7 +57,9 @@ void WebViewFunctor_release(int functor) { static std::atomic_int sNextId{1}; -WebViewFunctor::WebViewFunctor(const WebViewFunctorCallbacks& callbacks, RenderMode functorMode) { +WebViewFunctor::WebViewFunctor(void* data, const WebViewFunctorCallbacks& callbacks, + RenderMode functorMode) + : mData(data) { mFunctor = sNextId++; mCallbacks = callbacks; mMode = functorMode; @@ -66,12 +69,12 @@ WebViewFunctor::~WebViewFunctor() { destroyContext(); ATRACE_NAME("WebViewFunctor::onDestroy"); - mCallbacks.onDestroyed(mFunctor); + mCallbacks.onDestroyed(mFunctor, mData); } void WebViewFunctor::sync(const WebViewSyncData& syncData) const { ATRACE_NAME("WebViewFunctor::sync"); - mCallbacks.onSync(mFunctor, syncData); + mCallbacks.onSync(mFunctor, mData, syncData); } void WebViewFunctor::drawGl(const DrawGlInfo& drawInfo) { @@ -79,14 +82,14 @@ void WebViewFunctor::drawGl(const DrawGlInfo& drawInfo) { if (!mHasContext) { mHasContext = true; } - mCallbacks.gles.draw(mFunctor, drawInfo); + mCallbacks.gles.draw(mFunctor, mData, drawInfo); } void WebViewFunctor::destroyContext() { if (mHasContext) { mHasContext = false; ATRACE_NAME("WebViewFunctor::onContextDestroyed"); - mCallbacks.onContextDestroyed(mFunctor); + mCallbacks.onContextDestroyed(mFunctor, mData); } } @@ -95,9 +98,9 @@ WebViewFunctorManager& WebViewFunctorManager::instance() { return sInstance; } -int WebViewFunctorManager::createFunctor(const WebViewFunctorCallbacks& callbacks, +int WebViewFunctorManager::createFunctor(void* data, const WebViewFunctorCallbacks& callbacks, RenderMode functorMode) { - auto object = std::make_unique<WebViewFunctor>(callbacks, functorMode); + auto object = std::make_unique<WebViewFunctor>(data, callbacks, functorMode); int id = object->id(); auto handle = object->createHandle(); { @@ -164,4 +167,4 @@ sp<WebViewFunctor::Handle> WebViewFunctorManager::handleFor(int functor) { return nullptr; } -} // namespace android::uirenderer
\ No newline at end of file +} // namespace android::uirenderer diff --git a/libs/hwui/WebViewFunctorManager.h b/libs/hwui/WebViewFunctorManager.h index 2a621dd411e3..1719ce7cca75 100644 --- a/libs/hwui/WebViewFunctorManager.h +++ b/libs/hwui/WebViewFunctorManager.h @@ -29,7 +29,7 @@ class WebViewFunctorManager; class WebViewFunctor { public: - WebViewFunctor(const WebViewFunctorCallbacks& callbacks, RenderMode functorMode); + WebViewFunctor(void* data, const WebViewFunctorCallbacks& callbacks, RenderMode functorMode); ~WebViewFunctor(); class Handle : public LightRefBase<Handle> { @@ -63,6 +63,7 @@ public: private: WebViewFunctorCallbacks mCallbacks; + void* const mData; int mFunctor; RenderMode mMode; bool mHasContext = false; @@ -73,7 +74,7 @@ class WebViewFunctorManager { public: static WebViewFunctorManager& instance(); - int createFunctor(const WebViewFunctorCallbacks& callbacks, RenderMode functorMode); + int createFunctor(void* data, const WebViewFunctorCallbacks& callbacks, RenderMode functorMode); void releaseFunctor(int functor); void onContextDestroyed(); void destroyFunctor(int functor); diff --git a/libs/hwui/private/hwui/WebViewFunctor.h b/libs/hwui/private/hwui/WebViewFunctor.h index e5346aabaee3..da3d06a4d60c 100644 --- a/libs/hwui/private/hwui/WebViewFunctor.h +++ b/libs/hwui/private/hwui/WebViewFunctor.h @@ -17,6 +17,7 @@ #ifndef FRAMEWORKS_BASE_WEBVIEWFUNCTOR_H #define FRAMEWORKS_BASE_WEBVIEWFUNCTOR_H +#include <cutils/compiler.h> #include <private/hwui/DrawGlInfo.h> namespace android::uirenderer { @@ -27,7 +28,7 @@ enum class RenderMode { }; // Static for the lifetime of the process -RenderMode WebViewFunctor_queryPlatformRenderMode(); +ANDROID_API RenderMode WebViewFunctor_queryPlatformRenderMode(); struct WebViewSyncData { bool applyForceDark; @@ -35,21 +36,21 @@ struct WebViewSyncData { struct WebViewFunctorCallbacks { // kModeSync, called on RenderThread - void (*onSync)(int functor, const WebViewSyncData& syncData); + void (*onSync)(int functor, void* data, const WebViewSyncData& syncData); // Called when either the context is destroyed _or_ when the functor's last reference goes // away. Will always be called with an active context and always on renderthread. - void (*onContextDestroyed)(int functor); + void (*onContextDestroyed)(int functor, void* data); // Called when the last reference to the handle goes away and the handle is considered // irrevocably destroyed. Will always be proceeded by a call to onContextDestroyed if // this functor had ever been drawn. - void (*onDestroyed)(int functor); + void (*onDestroyed)(int functor, void* data); union { struct { // Called on RenderThread. initialize is guaranteed to happen before this call - void (*draw)(int functor, const DrawGlInfo& params); + void (*draw)(int functor, void* data, const DrawGlInfo& params); } gles; // TODO: VK support. The current DrawVkInfo is monolithic and needs to be split up for // what params are valid on what callbacks @@ -70,12 +71,12 @@ struct WebViewFunctorCallbacks { // Creates a new WebViewFunctor from the given prototype. The prototype is copied after // this function returns. Caller retains full ownership of it. // Returns -1 if the creation fails (such as an unsupported functorMode + platform mode combination) -int WebViewFunctor_create(const WebViewFunctorCallbacks& prototype, RenderMode functorMode); +ANDROID_API int WebViewFunctor_create(void* data, const WebViewFunctorCallbacks& prototype, RenderMode functorMode); // May be called on any thread to signal that the functor should be destroyed. // The functor will receive an onDestroyed when the last usage of it is released, // and it should be considered alive & active until that point. -void WebViewFunctor_release(int functor); +ANDROID_API void WebViewFunctor_release(int functor); } // namespace android::uirenderer diff --git a/libs/hwui/tests/common/TestUtils.h b/libs/hwui/tests/common/TestUtils.h index 5ff8993e6779..6a1ca5a25361 100644 --- a/libs/hwui/tests/common/TestUtils.h +++ b/libs/hwui/tests/common/TestUtils.h @@ -315,24 +315,24 @@ public: static WebViewFunctorCallbacks createMockFunctor(RenderMode mode) { auto callbacks = WebViewFunctorCallbacks{ .onSync = - [](int functor, const WebViewSyncData& data) { + [](int functor, void* client_data, const WebViewSyncData& data) { expectOnRenderThread(); sMockFunctorCounts[functor].sync++; }, .onContextDestroyed = - [](int functor) { + [](int functor, void* client_data) { expectOnRenderThread(); sMockFunctorCounts[functor].contextDestroyed++; }, .onDestroyed = - [](int functor) { + [](int functor, void* client_data) { expectOnRenderThread(); sMockFunctorCounts[functor].destroyed++; }, }; switch (mode) { case RenderMode::OpenGL_ES: - callbacks.gles.draw = [](int functor, const DrawGlInfo& params) { + callbacks.gles.draw = [](int functor, void* client_data, const DrawGlInfo& params) { expectOnRenderThread(); sMockFunctorCounts[functor].glesDraw++; }; diff --git a/libs/hwui/tests/unit/SkiaDisplayListTests.cpp b/libs/hwui/tests/unit/SkiaDisplayListTests.cpp index 53bf84f13fd6..1b4cf7e144bd 100644 --- a/libs/hwui/tests/unit/SkiaDisplayListTests.cpp +++ b/libs/hwui/tests/unit/SkiaDisplayListTests.cpp @@ -100,8 +100,8 @@ TEST(SkiaDisplayList, syncContexts) { GLFunctorDrawable functorDrawable(&functor, nullptr, &dummyCanvas); skiaDL.mChildFunctors.push_back(&functorDrawable); - int functor2 = WebViewFunctor_create(TestUtils::createMockFunctor(RenderMode::OpenGL_ES), - RenderMode::OpenGL_ES); + int functor2 = WebViewFunctor_create( + nullptr, TestUtils::createMockFunctor(RenderMode::OpenGL_ES), RenderMode::OpenGL_ES); auto& counts = TestUtils::countsForFunctor(functor2); skiaDL.mChildFunctors.push_back( skiaDL.allocateDrawable<GLFunctorDrawable>(functor2, &dummyCanvas)); diff --git a/libs/hwui/tests/unit/WebViewFunctorManagerTests.cpp b/libs/hwui/tests/unit/WebViewFunctorManagerTests.cpp index c8169aff1c5e..e1fb8b7069ff 100644 --- a/libs/hwui/tests/unit/WebViewFunctorManagerTests.cpp +++ b/libs/hwui/tests/unit/WebViewFunctorManagerTests.cpp @@ -27,8 +27,8 @@ using namespace android; using namespace android::uirenderer; TEST(WebViewFunctor, createDestroyGLES) { - int functor = WebViewFunctor_create(TestUtils::createMockFunctor(RenderMode::OpenGL_ES), - RenderMode::OpenGL_ES); + int functor = WebViewFunctor_create( + nullptr, TestUtils::createMockFunctor(RenderMode::OpenGL_ES), RenderMode::OpenGL_ES); ASSERT_NE(-1, functor); WebViewFunctor_release(functor); TestUtils::runOnRenderThreadUnmanaged([](renderthread::RenderThread&) { @@ -41,8 +41,8 @@ TEST(WebViewFunctor, createDestroyGLES) { } TEST(WebViewFunctor, createSyncHandleGLES) { - int functor = WebViewFunctor_create(TestUtils::createMockFunctor(RenderMode::OpenGL_ES), - RenderMode::OpenGL_ES); + int functor = WebViewFunctor_create( + nullptr, TestUtils::createMockFunctor(RenderMode::OpenGL_ES), RenderMode::OpenGL_ES); ASSERT_NE(-1, functor); auto handle = WebViewFunctorManager::instance().handleFor(functor); ASSERT_TRUE(handle); @@ -82,8 +82,8 @@ TEST(WebViewFunctor, createSyncHandleGLES) { } TEST(WebViewFunctor, createSyncDrawGLES) { - int functor = WebViewFunctor_create(TestUtils::createMockFunctor(RenderMode::OpenGL_ES), - RenderMode::OpenGL_ES); + int functor = WebViewFunctor_create( + nullptr, TestUtils::createMockFunctor(RenderMode::OpenGL_ES), RenderMode::OpenGL_ES); ASSERT_NE(-1, functor); auto handle = WebViewFunctorManager::instance().handleFor(functor); ASSERT_TRUE(handle); @@ -109,8 +109,8 @@ TEST(WebViewFunctor, createSyncDrawGLES) { } TEST(WebViewFunctor, contextDestroyed) { - int functor = WebViewFunctor_create(TestUtils::createMockFunctor(RenderMode::OpenGL_ES), - RenderMode::OpenGL_ES); + int functor = WebViewFunctor_create( + nullptr, TestUtils::createMockFunctor(RenderMode::OpenGL_ES), RenderMode::OpenGL_ES); ASSERT_NE(-1, functor); auto handle = WebViewFunctorManager::instance().handleFor(functor); ASSERT_TRUE(handle); @@ -151,4 +151,4 @@ TEST(WebViewFunctor, contextDestroyed) { EXPECT_EQ(2, counts.glesDraw); EXPECT_EQ(2, counts.contextDestroyed); EXPECT_EQ(1, counts.destroyed); -}
\ No newline at end of file +} diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java index 63eefe04c1d1..30b5480fba55 100644 --- a/media/java/android/media/AudioManager.java +++ b/media/java/android/media/AudioManager.java @@ -4280,9 +4280,8 @@ public class AudioManager { * Return codes for listAudioPorts(), createAudioPatch() ... */ - /** @hide - * CANDIDATE FOR PUBLIC API - */ + /** @hide */ + @SystemApi public static final int SUCCESS = AudioSystem.SUCCESS; /** * A default error code. diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java index 58fc1ab1c4dd..45cde0ffecc4 100644 --- a/media/java/android/media/AudioSystem.java +++ b/media/java/android/media/AudioSystem.java @@ -916,6 +916,13 @@ public class AudioSystem public static native int registerPolicyMixes(ArrayList<AudioMix> mixes, boolean register); + /** see AudioPolicy.setUidDeviceAffinities() */ + public static native int setUidDeviceAffinities(int uid, @NonNull int[] types, + @NonNull String[] addresses); + + /** see AudioPolicy.removeUidDeviceAffinities() */ + public static native int removeUidDeviceAffinities(int uid); + public static native int systemReady(); public static native float getStreamVolumeDB(int stream, int index, int device); diff --git a/media/java/android/media/Controller2Link.java b/media/java/android/media/Controller2Link.java index 2601ff733546..a62db5f1fb20 100644 --- a/media/java/android/media/Controller2Link.java +++ b/media/java/android/media/Controller2Link.java @@ -25,8 +25,7 @@ import android.os.ResultReceiver; import java.util.Objects; /** - * Handles incoming commands from {@link MediaSession2} and {@link MediaLibrarySession} - * to both {@link MediaController2} and {@link MediaBrowser2}. + * Handles incoming commands from {@link MediaSession2} to both {@link MediaController2}. * @hide */ // @SystemApi @@ -90,7 +89,7 @@ public final class Controller2Link implements Parcelable { try { mIController.notifyConnected(seq, connectionResult); } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + throw new RuntimeException(e); } } @@ -99,7 +98,7 @@ public final class Controller2Link implements Parcelable { try { mIController.notifyDisconnected(seq); } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + throw new RuntimeException(e); } } @@ -109,7 +108,16 @@ public final class Controller2Link implements Parcelable { try { mIController.sendSessionCommand(seq, command, args, resultReceiver); } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + throw new RuntimeException(e); + } + } + + /** Interface method for IMediaController2.cancelSessionCommand */ + public void cancelSessionCommand(int seq) { + try { + mIController.cancelSessionCommand(seq); + } catch (RemoteException e) { + throw new RuntimeException(e); } } @@ -133,6 +141,11 @@ public final class Controller2Link implements Parcelable { mController.onSessionCommand(seq, command, args, resultReceiver); } + /** Stub implementation for IMediaController2.cancelSessionCommand */ + public void onCancelCommand(int seq) { + mController.onCancelCommand(seq); + } + private class Controller2Stub extends IMediaController2.Stub { @Override public void notifyConnected(int seq, Bundle connectionResult) { @@ -149,5 +162,10 @@ public final class Controller2Link implements Parcelable { ResultReceiver resultReceiver) { Controller2Link.this.onSessionCommand(seq, command, args, resultReceiver); } + + @Override + public void cancelSessionCommand(int seq) { + Controller2Link.this.onCancelCommand(seq); + } } } diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl index abd64119de61..9fbd7eac6e8a 100644 --- a/media/java/android/media/IAudioService.aidl +++ b/media/java/android/media/IAudioService.aidl @@ -223,6 +223,11 @@ interface IAudioService { boolean isAudioServerRunning(); + int setUidDeviceAffinity(in IAudioPolicyCallback pcb, in int uid, in int[] deviceTypes, + in String[] deviceAddresses); + + int removeUidDeviceAffinity(in IAudioPolicyCallback pcb, in int uid); + // WARNING: read warning at top of file, new methods that need to be used by native // code via IAudioManager.h need to be added to the top section. } diff --git a/media/java/android/media/IMediaController2.aidl b/media/java/android/media/IMediaController2.aidl index df34a11a67e3..ca5394f504cb 100644 --- a/media/java/android/media/IMediaController2.aidl +++ b/media/java/android/media/IMediaController2.aidl @@ -33,4 +33,6 @@ oneway interface IMediaController2 { void notifyDisconnected(int seq) = 1; void sendSessionCommand(int seq, in Session2Command command, in Bundle args, in ResultReceiver resultReceiver) = 2; + void cancelSessionCommand(int seq) = 3; + // Next Id : 4 } diff --git a/media/java/android/media/IMediaSession2.aidl b/media/java/android/media/IMediaSession2.aidl index f6e74cfb242c..26e717b39afc 100644 --- a/media/java/android/media/IMediaSession2.aidl +++ b/media/java/android/media/IMediaSession2.aidl @@ -34,5 +34,6 @@ oneway interface IMediaSession2 { void disconnect(in Controller2Link caller, int seq) = 1; void sendSessionCommand(in Controller2Link caller, int seq, in Session2Command sessionCommand, in Bundle args, in ResultReceiver resultReceiver) = 2; - // Next Id : 3 + void cancelSessionCommand(in Controller2Link caller, int seq) = 3; + // Next Id : 4 } diff --git a/media/java/android/media/MediaConstants.java b/media/java/android/media/MediaConstants.java index ffdca16d84e8..275b0acd8ad6 100644 --- a/media/java/android/media/MediaConstants.java +++ b/media/java/android/media/MediaConstants.java @@ -16,7 +16,6 @@ package android.media; -// Code for AML only class MediaConstants { // Bundle key for int static final String KEY_PID = "android.media.key.PID"; diff --git a/media/java/android/media/MediaController2.java b/media/java/android/media/MediaController2.java index 4ef56c8d8caf..7665c92f9264 100644 --- a/media/java/android/media/MediaController2.java +++ b/media/java/android/media/MediaController2.java @@ -20,6 +20,8 @@ import static android.media.MediaConstants.KEY_ALLOWED_COMMANDS; import static android.media.MediaConstants.KEY_PACKAGE_NAME; import static android.media.MediaConstants.KEY_PID; import static android.media.MediaConstants.KEY_SESSION2_STUB; +import static android.media.Session2Command.RESULT_ERROR_UNKNOWN_ERROR; +import static android.media.Session2Command.RESULT_INFO_SKIPPED; import static android.media.Session2Token.TYPE_SESSION; import android.annotation.NonNull; @@ -31,6 +33,8 @@ import android.os.Handler; import android.os.IBinder; import android.os.Process; import android.os.ResultReceiver; +import android.util.ArrayMap; +import android.util.ArraySet; import android.util.Log; import java.util.concurrent.Executor; @@ -69,6 +73,21 @@ public class MediaController2 implements AutoCloseable { private Session2CommandGroup mAllowedCommands; //@GuardedBy("mLock") private Session2Token mConnectedToken; + //@GuardedBy("mLock") + private ArrayMap<ResultReceiver, Integer> mPendingCommands; + //@GuardedBy("mLock") + private ArraySet<Integer> mRequestedCommandSeqNumbers; + + /** + * Create a {@link MediaController2} from the {@link Session2Token}. + * This connects to the session and may wake up the service if it's not available. + * + * @param context Context + * @param token token to connect to + */ + public MediaController2(@NonNull Context context, @NonNull Session2Token token) { + this(context, token, context.getMainExecutor(), new ControllerCallback() {}); + } /** * Create a {@link MediaController2} from the {@link Session2Token}. @@ -77,31 +96,27 @@ public class MediaController2 implements AutoCloseable { * @param context Context * @param token token to connect to * @param executor executor to run callbacks on. - * @param callback controller callback to receive changes in + * @param callback controller callback to receive changes in. */ - public MediaController2(@NonNull final Context context, @NonNull final Session2Token token, - @NonNull final Executor executor, @NonNull final ControllerCallback callback) { + public MediaController2(@NonNull Context context, @NonNull Session2Token token, + @NonNull Executor executor, @NonNull ControllerCallback callback) { if (context == null) { throw new IllegalArgumentException("context shouldn't be null"); } if (token == null) { throw new IllegalArgumentException("token shouldn't be null"); } - if (callback == null) { - throw new IllegalArgumentException("callback shouldn't be null"); - } - if (executor == null) { - throw new IllegalArgumentException("executor shouldn't be null"); - } mContext = context; mSessionToken = token; - mCallbackExecutor = executor; - mCallback = callback; + mCallbackExecutor = (executor == null) ? context.getMainExecutor() : executor; + mCallback = (callback == null) ? new ControllerCallback() { } : callback; mControllerStub = new Controller2Link(this); // NOTE: mResultHandler uses main looper, so this MUST NOT be blocked. mResultHandler = new Handler(context.getMainLooper()); mNextSeqNumber = 0; + mPendingCommands = new ArrayMap<>(); + mRequestedCommandSeqNumbers = new ArraySet<>(); if (token.getType() == TYPE_SESSION) { connectToSession(); @@ -116,11 +131,13 @@ public class MediaController2 implements AutoCloseable { if (mSessionBinder != null) { try { mSessionBinder.unlinkToDeath(mDeathRecipient, 0); - mSessionBinder.disconnect(mControllerStub, mNextSeqNumber++); + mSessionBinder.disconnect(mControllerStub, getNextSeqNumber()); } catch (RuntimeException e) { // No-op } } + mPendingCommands.clear(); + mRequestedCommandSeqNumbers.clear(); mCallbackExecutor.execute(() -> { mCallback.onDisconnected(MediaController2.this); }); @@ -134,9 +151,8 @@ public class MediaController2 implements AutoCloseable { * @param command the session command * @param args optional arguments * @return a token which will be sent together in {@link ControllerCallback#onCommandResult} - * when its result is received. + * when its result is received. */ - // TODO: make cancelable. public Object sendSessionCommand(@NonNull Session2Command command, @Nullable Bundle args) { if (command == null) { throw new IllegalArgumentException("command shouldn't be null"); @@ -144,26 +160,50 @@ public class MediaController2 implements AutoCloseable { ResultReceiver resultReceiver = new ResultReceiver(mResultHandler) { protected void onReceiveResult(int resultCode, Bundle resultData) { + synchronized (mLock) { + mPendingCommands.remove(this); + } mCallbackExecutor.execute(() -> { mCallback.onCommandResult(MediaController2.this, this, - command, resultData); + command, new Session2Command.Result(resultCode, resultData)); }); } }; synchronized (mLock) { if (mSessionBinder != null) { + int seq = getNextSeqNumber(); + mPendingCommands.put(resultReceiver, seq); try { - mSessionBinder.sendSessionCommand(mControllerStub, mNextSeqNumber++, - command, args, resultReceiver); + mSessionBinder.sendSessionCommand(mControllerStub, seq, command, args, + resultReceiver); } catch (RuntimeException e) { - // No-op + mPendingCommands.remove(resultReceiver); + resultReceiver.send(RESULT_ERROR_UNKNOWN_ERROR, null); } } } return resultReceiver; } + /** + * Cancels the session command previously sent. + * + * @param token the token which is returned from {@link #sendSessionCommand}. + */ + public void cancelSessionCommand(@NonNull Object token) { + if (token == null) { + throw new IllegalArgumentException("token shouldn't be null"); + } + synchronized (mLock) { + if (mSessionBinder == null) return; + Integer seq = mPendingCommands.remove(token); + if (seq != null) { + mSessionBinder.cancelSessionCommand(mControllerStub, seq); + } + } + } + // Called by Controller2Link.onConnected void onConnected(int seq, Bundle connectionResult) { final long token = Binder.clearCallingIdentity(); @@ -213,10 +253,26 @@ public class MediaController2 implements AutoCloseable { @Nullable ResultReceiver resultReceiver) { final long token = Binder.clearCallingIdentity(); try { + synchronized (mLock) { + mRequestedCommandSeqNumbers.add(seq); + } mCallbackExecutor.execute(() -> { - Bundle result = mCallback.onSessionCommand(MediaController2.this, command, args); + boolean isCanceled; + synchronized (mLock) { + isCanceled = !mRequestedCommandSeqNumbers.remove(seq); + } + if (isCanceled) { + resultReceiver.send(RESULT_INFO_SKIPPED, null); + return; + } + Session2Command.Result result = mCallback.onSessionCommand( + MediaController2.this, command, args); if (resultReceiver != null) { - resultReceiver.send(0, result); + if (result == null) { + throw new RuntimeException("onSessionCommand shouldn't return null"); + } else { + resultReceiver.send(result.getResultCode(), result.getResultData()); + } } }); } finally { @@ -224,6 +280,18 @@ public class MediaController2 implements AutoCloseable { } } + // Called by Controller2Link.onSessionCommand + void onCancelCommand(int seq) { + final long token = Binder.clearCallingIdentity(); + try { + synchronized (mLock) { + mRequestedCommandSeqNumbers.remove(seq); + } + } finally { + Binder.restoreCallingIdentity(token); + } + } + private int getNextSeqNumber() { synchronized (mLock) { return mNextSeqNumber++; @@ -278,9 +346,11 @@ public class MediaController2 implements AutoCloseable { * @param controller the controller for this event * @param command the session command * @param args optional arguments - * @return the result for the session command + * @return the result for the session command. A runtime exception will be thrown if null + * is returned. */ - public Bundle onSessionCommand(@NonNull MediaController2 controller, + @NonNull + public Session2Command.Result onSessionCommand(@NonNull MediaController2 controller, @NonNull Session2Command command, @Nullable Bundle args) { return null; } @@ -294,7 +364,6 @@ public class MediaController2 implements AutoCloseable { * @param result the result of the session command */ public void onCommandResult(@NonNull MediaController2 controller, @NonNull Object token, - @NonNull Session2Command command, @Nullable Bundle result) { - } + @NonNull Session2Command command, @NonNull Session2Command.Result result) { } } } diff --git a/media/java/android/media/MediaScanner.java b/media/java/android/media/MediaScanner.java index 90cfc534877e..4eed12f428bc 100644 --- a/media/java/android/media/MediaScanner.java +++ b/media/java/android/media/MediaScanner.java @@ -902,6 +902,7 @@ public class MediaScanner implements AutoCloseable { map.put(MediaStore.MediaColumns.SIZE, mFileSize); map.put(MediaStore.MediaColumns.MIME_TYPE, mMimeType); map.put(MediaStore.MediaColumns.IS_DRM, mIsDrm); + map.putNull(MediaStore.MediaColumns.HASH); String resolution = null; if (mWidth > 0 && mHeight > 0) { @@ -934,7 +935,7 @@ public class MediaScanner implements AutoCloseable { } } else if (MediaFile.isImageMimeType(mMimeType)) { // FIXME - add DESCRIPTION - } else if (mScanSuccess && MediaFile.isAudioMimeType(mMimeType)) { + } else if (MediaFile.isAudioMimeType(mMimeType)) { map.put(Audio.Media.ARTIST, (mArtist != null && mArtist.length() > 0) ? mArtist : MediaStore.UNKNOWN_STRING); map.put(Audio.Media.ALBUM_ARTIST, (mAlbumArtist != null && @@ -950,10 +951,6 @@ public class MediaScanner implements AutoCloseable { map.put(Audio.Media.DURATION, mDuration); map.put(Audio.Media.COMPILATION, mCompilation); } - if (!mScanSuccess) { - // force mediaprovider to not determine the media type from the mime type - map.put(Files.FileColumns.MEDIA_TYPE, 0); - } } return map; } @@ -1056,7 +1053,7 @@ public class MediaScanner implements AutoCloseable { Uri tableUri = mFilesUri; int mediaType = FileColumns.MEDIA_TYPE_NONE; MediaInserter inserter = mMediaInserter; - if (mScanSuccess && !mNoMedia) { + if (!mNoMedia) { if (MediaFile.isVideoMimeType(mMimeType)) { tableUri = mVideoUri; mediaType = FileColumns.MEDIA_TYPE_VIDEO; @@ -1131,7 +1128,7 @@ public class MediaScanner implements AutoCloseable { // with squashed lower case paths values.remove(MediaStore.MediaColumns.DATA); - if (mScanSuccess && !mNoMedia) { + if (!mNoMedia) { // Changing media type must be done as separate update if (mediaType != entry.mMediaType) { final ContentValues mediaTypeValues = new ContentValues(); diff --git a/media/java/android/media/MediaSession2.java b/media/java/android/media/MediaSession2.java index d67c66254b0c..b874ba461c2b 100644 --- a/media/java/android/media/MediaSession2.java +++ b/media/java/android/media/MediaSession2.java @@ -20,6 +20,8 @@ import static android.media.MediaConstants.KEY_ALLOWED_COMMANDS; import static android.media.MediaConstants.KEY_PACKAGE_NAME; import static android.media.MediaConstants.KEY_PID; import static android.media.MediaConstants.KEY_SESSION2_STUB; +import static android.media.Session2Command.RESULT_ERROR_UNKNOWN_ERROR; +import static android.media.Session2Command.RESULT_INFO_SKIPPED; import static android.media.Session2Token.TYPE_SESSION; import android.annotation.NonNull; @@ -34,6 +36,8 @@ import android.os.Bundle; import android.os.Handler; import android.os.Process; import android.os.ResultReceiver; +import android.util.ArrayMap; +import android.util.ArraySet; import android.util.Log; import java.util.ArrayList; @@ -112,7 +116,7 @@ public class MediaSession2 implements AutoCloseable { } @Override - public void close() throws Exception { + public void close() { try { synchronized (MediaSession2.class) { SESSION_ID_LIST.remove(mSessionId); @@ -120,6 +124,7 @@ public class MediaSession2 implements AutoCloseable { Collection<ControllerInfo> controllerInfos; synchronized (mLock) { controllerInfos = mConnectedControllers.values(); + mConnectedControllers.clear(); mClosed = true; } for (ControllerInfo info : controllerInfos) { @@ -131,6 +136,22 @@ public class MediaSession2 implements AutoCloseable { } /** + * Returns the session ID + */ + @NonNull + public String getSessionId() { + return mSessionId; + } + + /** + * Returns the {@link Session2Token} for creating {@link MediaController2}. + */ + @NonNull + public Session2Token getSessionToken() { + return mSessionToken; + } + + /** * Broadcasts a session command to all the connected controllers * <p> * @param command the session command @@ -158,7 +179,6 @@ public class MediaSession2 implements AutoCloseable { * @return a token which will be sent together in {@link SessionCallback#onCommandResult} * when its result is received. */ - // TODO: make cancelable. public Object sendSessionCommand(@NonNull ControllerInfo controller, @NonNull Session2Command command, @Nullable Bundle args) { if (controller == null) { @@ -169,9 +189,10 @@ public class MediaSession2 implements AutoCloseable { } ResultReceiver resultReceiver = new ResultReceiver(mResultHandler) { protected void onReceiveResult(int resultCode, Bundle resultData) { + controller.receiveCommandResult(this); mCallbackExecutor.execute(() -> { mCallback.onCommandResult(MediaSession2.this, controller, this, - command, resultData); + command, new Session2Command.Result(resultCode, resultData)); }); } }; @@ -179,6 +200,19 @@ public class MediaSession2 implements AutoCloseable { return resultReceiver; } + /** + * Cancels the session command previously sent. + * + * @param controller the controller to get the session command + * @param token the token which is returned from {@link #sendSessionCommand}. + */ + public void cancelSessionCommand(ControllerInfo controller, Object token) { + if (token == null) { + throw new IllegalArgumentException("token shouldn't be null"); + } + controller.cancelSessionCommand(token); + } + boolean isClosed() { synchronized (mLock) { return mClosed; @@ -296,15 +330,23 @@ public class MediaSession2 implements AutoCloseable { // TODO: check allowed commands. final long token = Binder.clearCallingIdentity(); try { + synchronized (mLock) { + controllerInfo.addRequestedCommandSeqNumber(seq); + } + mCallbackExecutor.execute(() -> { - try { - Bundle result = mCallback.onSessionCommand( - MediaSession2.this, controllerInfo, command, args); - if (resultReceiver != null) { - resultReceiver.send(0, result); + if (!controllerInfo.removeRequestedCommandSeqNumber(seq)) { + resultReceiver.send(RESULT_INFO_SKIPPED, null); + return; + } + Session2Command.Result result = mCallback.onSessionCommand( + MediaSession2.this, controllerInfo, command, args); + if (resultReceiver != null) { + if (result == null) { + throw new RuntimeException("onSessionCommand shouldn't return null"); + } else { + resultReceiver.send(result.getResultCode(), result.getResultData()); } - } catch (RuntimeException e) { - // Controller may be died prematurely. } }); } finally { @@ -312,6 +354,24 @@ public class MediaSession2 implements AutoCloseable { } } + // Called by Session2Link.onCancelCommand + void onCancelCommand(final Controller2Link controller, final int seq) { + final ControllerInfo controllerInfo; + synchronized (mLock) { + controllerInfo = mConnectedControllers.get(controller); + } + if (controllerInfo == null) { + return; + } + + final long token = Binder.clearCallingIdentity(); + try { + controllerInfo.removeRequestedCommandSeqNumber(seq); + } finally { + Binder.restoreCallingIdentity(token); + } + } + /** * Builder for {@link MediaSession2}. * <p> @@ -417,7 +477,13 @@ public class MediaSession2 implements AutoCloseable { private final RemoteUserInfo mRemoteUserInfo; private final boolean mIsTrusted; private final Controller2Link mControllerBinder; + private final Object mLock = new Object(); + //@GuardedBy("mLock") private int mNextSeqNumber; + //@GuardedBy("mLock") + private ArrayMap<ResultReceiver, Integer> mPendingCommands; + //@GuardedBy("mLock") + private ArraySet<Integer> mRequestedCommandSeqNumbers; @SuppressWarnings("WeakerAccess") /* synthetic access */ Session2CommandGroup mAllowedCommands; @@ -425,15 +491,15 @@ public class MediaSession2 implements AutoCloseable { /** * @param remoteUserInfo remote user info * @param trusted {@code true} if trusted, {@code false} otherwise - * @param controllerBinder Controller2Link. Can be {@code null} only when a - * MediaBrowserCompat connects to MediaSessionService and ControllerInfo is - * needed for SessionCallback#onConnected(). + * @param controllerBinder Controller2Link for the connected controller. */ ControllerInfo(@NonNull RemoteUserInfo remoteUserInfo, boolean trusted, @Nullable Controller2Link controllerBinder) { mRemoteUserInfo = remoteUserInfo; mIsTrusted = trusted; mControllerBinder = controllerBinder; + mPendingCommands = new ArrayMap<>(); + mRequestedCommandSeqNumbers = new ArraySet<>(); } /** @@ -517,16 +583,53 @@ public class MediaSession2 implements AutoCloseable { void sendSessionCommand(Session2Command command, Bundle args, ResultReceiver resultReceiver) { if (mControllerBinder == null) return; + try { int seq = getNextSeqNumber(); + synchronized (mLock) { + mPendingCommands.put(resultReceiver, seq); + } mControllerBinder.sendSessionCommand(seq, command, args, resultReceiver); } catch (RuntimeException e) { // Controller may be died prematurely. + synchronized (mLock) { + mPendingCommands.remove(resultReceiver); + } + resultReceiver.send(RESULT_ERROR_UNKNOWN_ERROR, null); + } + } + + void cancelSessionCommand(@NonNull Object token) { + if (mControllerBinder == null) return; + Integer seq; + synchronized (mLock) { + seq = mPendingCommands.remove(token); + } + if (seq != null) { + mControllerBinder.cancelSessionCommand(seq); + } + } + + void receiveCommandResult(ResultReceiver resultReceiver) { + synchronized (mLock) { + mPendingCommands.remove(resultReceiver); + } + } + + void addRequestedCommandSeqNumber(int seq) { + synchronized (mLock) { + mRequestedCommandSeqNumbers.add(seq); + } + } + + boolean removeRequestedCommandSeqNumber(int seq) { + synchronized (mLock) { + return mRequestedCommandSeqNumbers.remove(seq); } } private int getNextSeqNumber() { - synchronized (this) { + synchronized (mLock) { return mNextSeqNumber++; } } @@ -575,9 +678,11 @@ public class MediaSession2 implements AutoCloseable { * @param controller controller information * @param command the session command * @param args optional arguments - * @return The result for the session command + * @return the result for the session command. A runtime exception will be thrown if null + * is returned. */ - public Bundle onSessionCommand(@NonNull MediaSession2 session, + @NonNull + public Session2Command.Result onSessionCommand(@NonNull MediaSession2 session, @NonNull ControllerInfo controller, @NonNull Session2Command command, @Nullable Bundle args) { return null; @@ -594,8 +699,6 @@ public class MediaSession2 implements AutoCloseable { */ public void onCommandResult(@NonNull MediaSession2 session, @NonNull ControllerInfo controller, @NonNull Object token, - @NonNull Session2Command command, @Nullable Bundle result) { - } + @NonNull Session2Command command, @NonNull Session2Command.Result result) { } } } - diff --git a/media/java/android/media/Session2Command.java b/media/java/android/media/Session2Command.java index a5e2ae4488a9..e46e64eb1a5c 100644 --- a/media/java/android/media/Session2Command.java +++ b/media/java/android/media/Session2Command.java @@ -409,6 +409,112 @@ public final class Session2Command implements Parcelable { */ public static final int COMMAND_CODE_SESSION_SET_RATING = 40010; + /** + * @hide + */ + @IntDef(flag = false, /*prefix = "RESULT_CODE",*/ value = { + RESULT_SUCCESS, + RESULT_ERROR_UNKNOWN_ERROR, + RESULT_ERROR_INVALID_STATE, + RESULT_ERROR_BAD_VALUE, + RESULT_ERROR_PERMISSION_DENIED, + RESULT_ERROR_IO_ERROR, + RESULT_INFO_SKIPPED, + RESULT_ERROR_SESSION_DISCONNECTED, + RESULT_ERROR_NOT_SUPPORTED, + RESULT_ERROR_SESSION_AUTHENTICATION_EXPIRED, + RESULT_ERROR_SESSION_PREMIUM_ACCOUNT_REQUIRED, + RESULT_ERROR_SESSION_CONCURRENT_STREAM_LIMIT, + RESULT_ERROR_SESSION_PARENTAL_CONTROL_RESTRICTED, + RESULT_ERROR_SESSION_NOT_AVAILABLE_IN_REGION, + RESULT_ERROR_SESSION_SKIP_LIMIT_REACHED, + RESULT_ERROR_SESSION_SETUP_REQUIRED}) + @Retention(RetentionPolicy.SOURCE) + public @interface ResultCode {} + + /** + * Result code representing that the command is skipped or canceled. For an example, a seek + * command can be skipped if it is followed by another seek command. + */ + public static final int RESULT_INFO_SKIPPED = 1; + + /** + * Result code representing that the command is successfully completed. + */ + public static final int RESULT_SUCCESS = 0; + + /** + * Result code represents that call is ended with an unknown error. + */ + public static final int RESULT_ERROR_UNKNOWN_ERROR = -1; + + /** + * Result code representing that the command cannot be completed because the current state is + * not valid for the command. + */ + public static final int RESULT_ERROR_INVALID_STATE = -2; + + /** + * Result code representing that an argument is illegal. + */ + public static final int RESULT_ERROR_BAD_VALUE = -3; + + /** + * Result code representing that the command is not allowed. + */ + public static final int RESULT_ERROR_PERMISSION_DENIED = -4; + + /** + * Result code representing a file or network related command error. + */ + public static final int RESULT_ERROR_IO_ERROR = -5; + + /** + * Result code representing that the command is not supported nor implemented. + */ + public static final int RESULT_ERROR_NOT_SUPPORTED = -6; + + /** + * Result code representing that the session and controller were disconnected. + */ + public static final int RESULT_ERROR_SESSION_DISCONNECTED = -100; + + /** + * Result code representing that the authentication has expired. + */ + public static final int RESULT_ERROR_SESSION_AUTHENTICATION_EXPIRED = -102; + + /** + * Result code representing that a premium account is required. + */ + public static final int RESULT_ERROR_SESSION_PREMIUM_ACCOUNT_REQUIRED = -103; + + /** + * Result code representing that too many concurrent streams are detected. + */ + public static final int RESULT_ERROR_SESSION_CONCURRENT_STREAM_LIMIT = -104; + + /** + * Result code representing that the content is blocked due to parental controls. + */ + public static final int RESULT_ERROR_SESSION_PARENTAL_CONTROL_RESTRICTED = -105; + + /** + * Result code representing that the content is blocked due to being regionally unavailable. + */ + public static final int RESULT_ERROR_SESSION_NOT_AVAILABLE_IN_REGION = -106; + + /** + * Result code representing that the application cannot skip any more because the skip limit is + * reached. + */ + public static final int RESULT_ERROR_SESSION_SKIP_LIMIT_REACHED = -107; + + /** + * Result code representing that the session needs user's manual intervention. + */ + public static final int RESULT_ERROR_SESSION_SETUP_REQUIRED = -108; + public static final Parcelable.Creator<Session2Command> CREATOR = new Parcelable.Creator<Session2Command>() { @Override @@ -582,6 +688,39 @@ public final class Session2Command implements Parcelable { return Objects.hash(mCustomCommand, mCommandCode); } + /** + * Contains the result of {@link Session2Command}. + */ + public static final class Result { + private final int mResultCode; + private final Bundle mResultData; + + /** + * Constructor of {@link Result}. + * + * @param resultCode result code + * @param resultData result data + */ + public Result(int resultCode, Bundle resultData) { + mResultCode = resultCode; + mResultData = resultData; + } + + /** + * Returns the result code. + */ + public int getResultCode() { + return mResultCode; + } + + /** + * Returns the result data. + */ + public Bundle getResultData() { + return mResultData; + } + } + @SuppressWarnings("WeakerAccess") /* synthetic access */ static final class Range { public final int lower; diff --git a/media/java/android/media/Session2Link.java b/media/java/android/media/Session2Link.java index 57c58dc3b2ed..5fe558da12f5 100644 --- a/media/java/android/media/Session2Link.java +++ b/media/java/android/media/Session2Link.java @@ -28,8 +28,7 @@ import android.util.Log; import java.util.Objects; /** - * Handles incoming commands from {@link MediaController2} and {@link MediaBrowser2} - * to both {@link MediaSession2} and {@link MediaLibrarySession}. + * Handles incoming commands from {@link MediaController2} to {@link MediaSession2}. * @hide */ // @SystemApi @@ -113,7 +112,7 @@ public final class Session2Link implements Parcelable { try { mISession.connect(caller, seq, connectionRequest); } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + throw new RuntimeException(e); } } @@ -122,7 +121,7 @@ public final class Session2Link implements Parcelable { try { mISession.disconnect(caller, seq); } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + throw new RuntimeException(e); } } @@ -132,7 +131,16 @@ public final class Session2Link implements Parcelable { try { mISession.sendSessionCommand(caller, seq, command, args, resultReceiver); } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + throw new RuntimeException(e); + } + } + + /** Interface method for IMediaSession2.sendSessionCommand */ + public void cancelSessionCommand(final Controller2Link caller, final int seq) { + try { + mISession.cancelSessionCommand(caller, seq); + } catch (RemoteException e) { + throw new RuntimeException(e); } } @@ -152,6 +160,11 @@ public final class Session2Link implements Parcelable { mSession.onSessionCommand(caller, seq, command, args, resultReceiver); } + /** Stub implementation for IMediaSession2.cancelSessionCommand */ + public void onCancelCommand(final Controller2Link caller, final int seq) { + mSession.onCancelCommand(caller, seq); + } + private class Session2Stub extends IMediaSession2.Stub { @Override public void connect(final Controller2Link caller, int seq, Bundle connectionRequest) { @@ -168,5 +181,10 @@ public final class Session2Link implements Parcelable { final Session2Command command, final Bundle args, ResultReceiver resultReceiver) { Session2Link.this.onSessionCommand(caller, seq, command, args, resultReceiver); } + + @Override + public void cancelSessionCommand(final Controller2Link caller, final int seq) { + Session2Link.this.onCancelCommand(caller, seq); + } } } diff --git a/media/java/android/media/audiopolicy/AudioMix.java b/media/java/android/media/audiopolicy/AudioMix.java index 7fb3aa6d79f9..1c6210e0c060 100644 --- a/media/java/android/media/audiopolicy/AudioMix.java +++ b/media/java/android/media/audiopolicy/AudioMix.java @@ -165,6 +165,20 @@ public class AudioMix { } /** @hide */ + public boolean isRoutedToDevice(int deviceType, @NonNull String deviceAddress) { + if ((mRouteFlags & ROUTE_FLAG_RENDER) != ROUTE_FLAG_RENDER) { + return false; + } + if (deviceType != mDeviceSystemType) { + return false; + } + if (!deviceAddress.equals(mDeviceAddress)) { + return false; + } + return true; + } + + /** @hide */ @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/media/java/android/media/audiopolicy/AudioPolicy.java b/media/java/android/media/audiopolicy/AudioPolicy.java index 6103f55745f9..65f3294800f5 100644 --- a/media/java/android/media/audiopolicy/AudioPolicy.java +++ b/media/java/android/media/audiopolicy/AudioPolicy.java @@ -22,6 +22,7 @@ import android.annotation.SystemApi; import android.content.Context; import android.content.pm.PackageManager; import android.media.AudioAttributes; +import android.media.AudioDeviceInfo; import android.media.AudioFocusInfo; import android.media.AudioFormat; import android.media.AudioManager; @@ -323,6 +324,80 @@ public class AudioPolicy { } } + /** + * @hide + * Configures the audio framework so that all audio stream originating from the given UID + * can only come from a set of audio devices. + * For this routing to be operational, a number of {@link AudioMix} instances must have been + * previously registered on this policy, and routed to a super-set of the given audio devices + * with {@link AudioMix.Builder#setDevice(android.media.AudioDeviceInfo)}. Note that having + * multiple devices in the list doesn't imply the signals will be duplicated on the different + * audio devices, final routing will depend on the {@link AudioAttributes} of the sounds being + * played. + * @param uid UID of the application to affect. + * @param devices list of devices to which the audio stream of the application may be routed. + * @return {@link AudioManager#SUCCESS} if the change was successful, {@link AudioManager#ERROR} + * otherwise. + */ + @SystemApi + public int setUidDeviceAffinity(int uid, @NonNull List<AudioDeviceInfo> devices) { + if (devices == null) { + throw new IllegalArgumentException("Illegal null list of audio devices"); + } + synchronized (mLock) { + if (mStatus != POLICY_STATUS_REGISTERED) { + throw new IllegalStateException("Cannot use unregistered AudioPolicy"); + } + final int[] deviceTypes = new int[devices.size()]; + final String[] deviceAdresses = new String[devices.size()]; + int i = 0; + for (AudioDeviceInfo device : devices) { + if (device == null) { + throw new IllegalArgumentException( + "Illegal null AudioDeviceInfo in setUidDeviceAffinity"); + } + deviceTypes[i] = + AudioDeviceInfo.convertDeviceTypeToInternalDevice(device.getType()); + deviceAdresses[i] = device.getAddress(); + i++; + } + final IAudioService service = getService(); + try { + final int status = service.setUidDeviceAffinity(this.cb(), + uid, deviceTypes, deviceAdresses); + return status; + } catch (RemoteException e) { + Log.e(TAG, "Dead object in setUidDeviceAffinity", e); + return AudioManager.ERROR; + } + } + } + + /** + * @hide + * Removes audio device affinity previously set by + * {@link #setUidDeviceAffinity(int, java.util.List)}. + * @param uid UID of the application affected. + * @return {@link AudioManager#SUCCESS} if the change was successful, {@link AudioManager#ERROR} + * otherwise. + */ + @SystemApi + public int removeUidDeviceAffinity(int uid) { + synchronized (mLock) { + if (mStatus != POLICY_STATUS_REGISTERED) { + throw new IllegalStateException("Cannot use unregistered AudioPolicy"); + } + final IAudioService service = getService(); + try { + final int status = service.removeUidDeviceAffinity(this.cb(), uid); + return status; + } catch (RemoteException e) { + Log.e(TAG, "Dead object in removeUidDeviceAffinity", e); + return AudioManager.ERROR; + } + } + } + public void setRegistration(String regId) { synchronized (mLock) { mRegistrationId = regId; diff --git a/media/java/android/media/session/ISessionController.aidl b/media/java/android/media/session/ISessionController.aidl index 5c1915b724de..f0db1b4c62e3 100644 --- a/media/java/android/media/session/ISessionController.aidl +++ b/media/java/android/media/session/ISessionController.aidl @@ -47,9 +47,9 @@ interface ISessionController { PendingIntent getLaunchPendingIntent(); long getFlags(); ParcelableVolumeInfo getVolumeAttributes(); - void adjustVolume(String packageName, in ControllerCallbackLink caller, + void adjustVolume(String packageName, String opPackageName, in ControllerCallbackLink caller, boolean asSystemService, int direction, int flags); - void setVolumeTo(String packageName, in ControllerCallbackLink caller, + void setVolumeTo(String packageName, String opPackageName, in ControllerCallbackLink caller, int value, int flags); // These commands are for the TransportControls diff --git a/media/java/android/media/session/ISessionManager.aidl b/media/java/android/media/session/ISessionManager.aidl index 580196736aba..f2c0e32781c2 100644 --- a/media/java/android/media/session/ISessionManager.aidl +++ b/media/java/android/media/session/ISessionManager.aidl @@ -35,9 +35,10 @@ interface ISessionManager { List<IBinder> getSessions(in ComponentName compName, int userId); void dispatchMediaKeyEvent(String packageName, boolean asSystemService, in KeyEvent keyEvent, boolean needWakeLock); - void dispatchVolumeKeyEvent(String packageName, boolean asSystemService, in KeyEvent keyEvent, - int stream, boolean musicOnly); - void dispatchAdjustVolume(String packageName, int suggestedStream, int delta, int flags); + void dispatchVolumeKeyEvent(String packageName, String opPackageName, boolean asSystemService, + in KeyEvent keyEvent, int stream, boolean musicOnly); + void dispatchAdjustVolume(String packageName, String opPackageName, int suggestedStream, + int delta, int flags); void addSessionsListener(in IActiveSessionsListener listener, in ComponentName compName, int userId); void removeSessionsListener(in IActiveSessionsListener listener); diff --git a/media/java/android/media/session/MediaController.java b/media/java/android/media/session/MediaController.java index 5eb77f9b58e2..7b061fe8e546 100644 --- a/media/java/android/media/session/MediaController.java +++ b/media/java/android/media/session/MediaController.java @@ -154,7 +154,7 @@ public final class MediaController { return false; } try { - return mSessionBinder.sendMediaButton(mContext.getOpPackageName(), mCbStub, + return mSessionBinder.sendMediaButton(mContext.getPackageName(), mCbStub, asSystemService, keyEvent); } catch (RemoteException e) { // System is dead. =( @@ -187,8 +187,12 @@ public final class MediaController { break; } try { - mSessionBinder.adjustVolume(mContext.getOpPackageName(), mCbStub, true, - direction, AudioManager.FLAG_SHOW_UI); + // Note: Need both package name and OP package name. Package name is used for + // RemoteUserInfo, and OP package name is used for AudioService's internal + // AppOpsManager usages. + mSessionBinder.adjustVolume(mContext.getPackageName(), + mContext.getOpPackageName(), mCbStub, true, direction, + AudioManager.FLAG_SHOW_UI); } catch (RemoteException e) { Log.wtf(TAG, "Error calling adjustVolumeBy", e); } @@ -198,8 +202,11 @@ public final class MediaController { final int flags = AudioManager.FLAG_PLAY_SOUND | AudioManager.FLAG_VIBRATE | AudioManager.FLAG_FROM_KEY; try { - mSessionBinder.adjustVolume(mContext.getOpPackageName(), mCbStub, true, 0, - flags); + // Note: Need both package name and OP package name. Package name is used for + // RemoteUserInfo, and OP package name is used for AudioService's internal + // AppOpsManager usages. + mSessionBinder.adjustVolume(mContext.getPackageName(), + mContext.getOpPackageName(), mCbStub, true, 0, flags); } catch (RemoteException e) { Log.wtf(TAG, "Error calling adjustVolumeBy", e); } @@ -365,7 +372,11 @@ public final class MediaController { */ public void setVolumeTo(int value, int flags) { try { - mSessionBinder.setVolumeTo(mContext.getOpPackageName(), mCbStub, value, flags); + // Note: Need both package name and OP package name. Package name is used for + // RemoteUserInfo, and OP package name is used for AudioService's internal + // AppOpsManager usages. + mSessionBinder.setVolumeTo(mContext.getPackageName(), mContext.getOpPackageName(), + mCbStub, value, flags); } catch (RemoteException e) { Log.wtf(TAG, "Error calling setVolumeTo.", e); } @@ -386,8 +397,11 @@ public final class MediaController { */ public void adjustVolume(int direction, int flags) { try { - mSessionBinder.adjustVolume(mContext.getOpPackageName(), mCbStub, false, direction, - flags); + // Note: Need both package name and OP package name. Package name is used for + // RemoteUserInfo, and OP package name is used for AudioService's internal + // AppOpsManager usages. + mSessionBinder.adjustVolume(mContext.getPackageName(), mContext.getOpPackageName(), + mCbStub, false, direction, flags); } catch (RemoteException e) { Log.wtf(TAG, "Error calling adjustVolumeBy.", e); } @@ -453,7 +467,7 @@ public final class MediaController { throw new IllegalArgumentException("command cannot be null or empty"); } try { - mSessionBinder.sendCommand(mContext.getOpPackageName(), mCbStub, command, args, cb); + mSessionBinder.sendCommand(mContext.getPackageName(), mCbStub, command, args, cb); } catch (RemoteException e) { Log.d(TAG, "Dead object in sendCommand.", e); } @@ -519,7 +533,7 @@ public final class MediaController { if (!mCbRegistered) { try { - mSessionBinder.registerCallbackListener(mContext.getOpPackageName(), mCbStub); + mSessionBinder.registerCallbackListener(mContext.getPackageName(), mCbStub); mCbRegistered = true; } catch (RemoteException e) { Log.e(TAG, "Dead object in registerCallback", e); @@ -666,7 +680,7 @@ public final class MediaController { */ public void prepare() { try { - mSessionBinder.prepare(mContext.getOpPackageName(), mCbStub); + mSessionBinder.prepare(mContext.getPackageName(), mCbStub); } catch (RemoteException e) { Log.wtf(TAG, "Error calling prepare.", e); } @@ -690,7 +704,7 @@ public final class MediaController { "You must specify a non-empty String for prepareFromMediaId."); } try { - mSessionBinder.prepareFromMediaId(mContext.getOpPackageName(), mCbStub, mediaId, + mSessionBinder.prepareFromMediaId(mContext.getPackageName(), mCbStub, mediaId, extras); } catch (RemoteException e) { Log.wtf(TAG, "Error calling prepare(" + mediaId + ").", e); @@ -717,7 +731,7 @@ public final class MediaController { query = ""; } try { - mSessionBinder.prepareFromSearch(mContext.getOpPackageName(), mCbStub, query, + mSessionBinder.prepareFromSearch(mContext.getPackageName(), mCbStub, query, extras); } catch (RemoteException e) { Log.wtf(TAG, "Error calling prepare(" + query + ").", e); @@ -742,7 +756,7 @@ public final class MediaController { "You must specify a non-empty Uri for prepareFromUri."); } try { - mSessionBinder.prepareFromUri(mContext.getOpPackageName(), mCbStub, uri, extras); + mSessionBinder.prepareFromUri(mContext.getPackageName(), mCbStub, uri, extras); } catch (RemoteException e) { Log.wtf(TAG, "Error calling prepare(" + uri + ").", e); } @@ -753,7 +767,7 @@ public final class MediaController { */ public void play() { try { - mSessionBinder.play(mContext.getOpPackageName(), mCbStub); + mSessionBinder.play(mContext.getPackageName(), mCbStub); } catch (RemoteException e) { Log.wtf(TAG, "Error calling play.", e); } @@ -772,7 +786,7 @@ public final class MediaController { "You must specify a non-empty String for playFromMediaId."); } try { - mSessionBinder.playFromMediaId(mContext.getOpPackageName(), mCbStub, mediaId, + mSessionBinder.playFromMediaId(mContext.getPackageName(), mCbStub, mediaId, extras); } catch (RemoteException e) { Log.wtf(TAG, "Error calling play(" + mediaId + ").", e); @@ -795,7 +809,7 @@ public final class MediaController { query = ""; } try { - mSessionBinder.playFromSearch(mContext.getOpPackageName(), mCbStub, query, extras); + mSessionBinder.playFromSearch(mContext.getPackageName(), mCbStub, query, extras); } catch (RemoteException e) { Log.wtf(TAG, "Error calling play(" + query + ").", e); } @@ -814,7 +828,7 @@ public final class MediaController { "You must specify a non-empty Uri for playFromUri."); } try { - mSessionBinder.playFromUri(mContext.getOpPackageName(), mCbStub, uri, extras); + mSessionBinder.playFromUri(mContext.getPackageName(), mCbStub, uri, extras); } catch (RemoteException e) { Log.wtf(TAG, "Error calling play(" + uri + ").", e); } @@ -826,7 +840,7 @@ public final class MediaController { */ public void skipToQueueItem(long id) { try { - mSessionBinder.skipToQueueItem(mContext.getOpPackageName(), mCbStub, id); + mSessionBinder.skipToQueueItem(mContext.getPackageName(), mCbStub, id); } catch (RemoteException e) { Log.wtf(TAG, "Error calling skipToItem(" + id + ").", e); } @@ -838,7 +852,7 @@ public final class MediaController { */ public void pause() { try { - mSessionBinder.pause(mContext.getOpPackageName(), mCbStub); + mSessionBinder.pause(mContext.getPackageName(), mCbStub); } catch (RemoteException e) { Log.wtf(TAG, "Error calling pause.", e); } @@ -850,7 +864,7 @@ public final class MediaController { */ public void stop() { try { - mSessionBinder.stop(mContext.getOpPackageName(), mCbStub); + mSessionBinder.stop(mContext.getPackageName(), mCbStub); } catch (RemoteException e) { Log.wtf(TAG, "Error calling stop.", e); } @@ -863,7 +877,7 @@ public final class MediaController { */ public void seekTo(long pos) { try { - mSessionBinder.seekTo(mContext.getOpPackageName(), mCbStub, pos); + mSessionBinder.seekTo(mContext.getPackageName(), mCbStub, pos); } catch (RemoteException e) { Log.wtf(TAG, "Error calling seekTo.", e); } @@ -875,7 +889,7 @@ public final class MediaController { */ public void fastForward() { try { - mSessionBinder.fastForward(mContext.getOpPackageName(), mCbStub); + mSessionBinder.fastForward(mContext.getPackageName(), mCbStub); } catch (RemoteException e) { Log.wtf(TAG, "Error calling fastForward.", e); } @@ -886,7 +900,7 @@ public final class MediaController { */ public void skipToNext() { try { - mSessionBinder.next(mContext.getOpPackageName(), mCbStub); + mSessionBinder.next(mContext.getPackageName(), mCbStub); } catch (RemoteException e) { Log.wtf(TAG, "Error calling next.", e); } @@ -898,7 +912,7 @@ public final class MediaController { */ public void rewind() { try { - mSessionBinder.rewind(mContext.getOpPackageName(), mCbStub); + mSessionBinder.rewind(mContext.getPackageName(), mCbStub); } catch (RemoteException e) { Log.wtf(TAG, "Error calling rewind.", e); } @@ -909,7 +923,7 @@ public final class MediaController { */ public void skipToPrevious() { try { - mSessionBinder.previous(mContext.getOpPackageName(), mCbStub); + mSessionBinder.previous(mContext.getPackageName(), mCbStub); } catch (RemoteException e) { Log.wtf(TAG, "Error calling previous.", e); } @@ -924,7 +938,7 @@ public final class MediaController { */ public void setRating(Rating rating) { try { - mSessionBinder.rate(mContext.getOpPackageName(), mCbStub, rating); + mSessionBinder.rate(mContext.getPackageName(), mCbStub, rating); } catch (RemoteException e) { Log.wtf(TAG, "Error calling rate.", e); } @@ -959,7 +973,7 @@ public final class MediaController { throw new IllegalArgumentException("CustomAction cannot be null."); } try { - mSessionBinder.sendCustomAction(mContext.getOpPackageName(), mCbStub, action, args); + mSessionBinder.sendCustomAction(mContext.getPackageName(), mCbStub, action, args); } catch (RemoteException e) { Log.d(TAG, "Dead object in sendCustomAction.", e); } diff --git a/media/java/android/media/session/MediaSessionManager.java b/media/java/android/media/session/MediaSessionManager.java index 73dd55c1b88a..7a4116f8baa8 100644 --- a/media/java/android/media/session/MediaSessionManager.java +++ b/media/java/android/media/session/MediaSessionManager.java @@ -312,7 +312,7 @@ public final class MediaSessionManager { private void dispatchMediaKeyEventInternal(boolean asSystemService, @NonNull KeyEvent keyEvent, boolean needWakeLock) { try { - mService.dispatchMediaKeyEvent(mContext.getOpPackageName(), asSystemService, keyEvent, + mService.dispatchMediaKeyEvent(mContext.getPackageName(), asSystemService, keyEvent, needWakeLock); } catch (RemoteException e) { Log.e(TAG, "Failed to send key event.", e); @@ -348,8 +348,8 @@ public final class MediaSessionManager { private void dispatchVolumeKeyEventInternal(boolean asSystemService, @NonNull KeyEvent keyEvent, int stream, boolean musicOnly) { try { - mService.dispatchVolumeKeyEvent(mContext.getOpPackageName(), asSystemService, keyEvent, - stream, musicOnly); + mService.dispatchVolumeKeyEvent(mContext.getPackageName(), mContext.getOpPackageName(), + asSystemService, keyEvent, stream, musicOnly); } catch (RemoteException e) { Log.e(TAG, "Failed to send volume key event.", e); } @@ -369,8 +369,8 @@ public final class MediaSessionManager { */ public void dispatchAdjustVolume(int suggestedStream, int direction, int flags) { try { - mService.dispatchAdjustVolume(mContext.getOpPackageName(), suggestedStream, direction, - flags); + mService.dispatchAdjustVolume(mContext.getPackageName(), mContext.getOpPackageName(), + suggestedStream, direction, flags); } catch (RemoteException e) { Log.e(TAG, "Failed to send adjust volume.", e); } diff --git a/media/jni/Android.bp b/media/jni/Android.bp index 7481fff74765..f75f69b4f2ee 100644 --- a/media/jni/Android.bp +++ b/media/jni/Android.bp @@ -95,14 +95,16 @@ cc_library_shared { ], shared_libs: [ - "android.hardware.cas@1.0", // for CasManager. VNDK??? - "android.hardware.cas.native@1.0", // CasManager. VNDK??? + // MediaCas + "android.hardware.cas@1.0", + "android.hardware.cas.native@1.0", "android.hidl.allocator@1.0", + "libhidlbase", "libhidlmemory", - "libbinder", - "libgui", // for VideoFrameScheduler - "libhidlbase", // VNDK??? - "libpowermanager", // for JWakeLock. to be removed + + "libpowermanager", // Used by JWakeLock. Will be replace with public SDJ API. + "libmediametrics", // Used by MediaMetrics. Will be replaced with stable C API. + "libbinder", // Used by JWakeLock and MediaMetrics. "libutils", // Have to use shared lib to make libandroid_runtime behave correctly. // Otherwise, AndroidRuntime::getJNIEnv() will return NULL. @@ -124,7 +126,6 @@ cc_library_shared { "libmedia_helper", "libmedia_player2_util", "libmediaextractor", - "libmediametrics", "libmediaplayer2", "libmediaplayer2-protos", "libmediandk_utils", diff --git a/native/webview/plat_support/Android.bp b/native/webview/plat_support/Android.bp index 96c9c1c85a60..09362566d915 100644 --- a/native/webview/plat_support/Android.bp +++ b/native/webview/plat_support/Android.bp @@ -22,6 +22,7 @@ cc_library_shared { name: "libwebviewchromium_plat_support", srcs: [ + "draw_functor.cpp", "draw_gl_functor.cpp", "draw_vk_functor.cpp", "functor_utils.cpp", diff --git a/native/webview/plat_support/draw_fn.h b/native/webview/plat_support/draw_fn.h index 8d48a58ac293..6afd8837594c 100644 --- a/native/webview/plat_support/draw_fn.h +++ b/native/webview/plat_support/draw_fn.h @@ -129,31 +129,31 @@ struct AwDrawFn_PostDrawVkParams { // Called on render thread while UI thread is blocked. Called for both GL and // VK. -typedef void AwDrawFn_OnSync(int functor, AwDrawFn_OnSyncParams* params); +typedef void AwDrawFn_OnSync(int functor, void* data, AwDrawFn_OnSyncParams* params); // Called on render thread when either the context is destroyed _or_ when the // functor's last reference goes away. Will always be called with an active // context. Called for both GL and VK. -typedef void AwDrawFn_OnContextDestroyed(int functor); +typedef void AwDrawFn_OnContextDestroyed(int functor, void* data); // Called on render thread when the last reference to the handle goes away and -// the handle is considered irrevocably destroyed. Will always be proceeded by +// the handle is considered irrevocably destroyed. Will always be preceded by // a call to OnContextDestroyed if this functor had ever been drawn. Called for // both GL and VK. -typedef void AwDrawFn_OnDestroyed(int functor); +typedef void AwDrawFn_OnDestroyed(int functor, void* data); // Only called for GL. -typedef void AwDrawFn_DrawGL(int functor, AwDrawFn_DrawGLParams* params); +typedef void AwDrawFn_DrawGL(int functor, void* data, AwDrawFn_DrawGLParams* params); // Initialize vulkan state. Needs to be called again after any // OnContextDestroyed. Only called for Vulkan. -typedef void AwDrawFn_InitVk(int functor, AwDrawFn_InitVkParams* params); +typedef void AwDrawFn_InitVk(int functor, void* data, AwDrawFn_InitVkParams* params); // Only called for Vulkan. -typedef void AwDrawFn_DrawVk(int functor, AwDrawFn_DrawVkParams* params); +typedef void AwDrawFn_DrawVk(int functor, void* data, AwDrawFn_DrawVkParams* params); // Only called for Vulkan. -typedef void AwDrawFn_PostDrawVk(int functor, +typedef void AwDrawFn_PostDrawVk(int functor, void* data, AwDrawFn_PostDrawVkParams* params); struct AwDrawFnFunctorCallbacks { @@ -176,7 +176,7 @@ enum AwDrawFnRenderMode { typedef AwDrawFnRenderMode AwDrawFn_QueryRenderMode(void); // Create a functor. |functor_callbacks| should be valid until OnDestroyed. -typedef int AwDrawFn_CreateFunctor(AwDrawFnFunctorCallbacks* functor_callbacks); +typedef int AwDrawFn_CreateFunctor(void* data, AwDrawFnFunctorCallbacks* functor_callbacks); // May be called on any thread to signal that the functor should be destroyed. // The functor will receive an onDestroyed when the last usage of it is diff --git a/native/webview/plat_support/draw_functor.cpp b/native/webview/plat_support/draw_functor.cpp new file mode 100644 index 000000000000..820bac509d2e --- /dev/null +++ b/native/webview/plat_support/draw_functor.cpp @@ -0,0 +1,144 @@ +/* + * 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. + */ + +#include "draw_fn.h" + +#include <jni.h> +#include <private/hwui/WebViewFunctor.h> +#include <utils/Log.h> + +#define NELEM(x) ((int) (sizeof(x) / sizeof((x)[0]))) +#define COMPILE_ASSERT(expr, err) \ +__unused static const char (err)[(expr) ? 1 : -1] = ""; + +namespace android { +namespace { + +struct SupportData { + void* const data; + AwDrawFnFunctorCallbacks callbacks; +}; + +void onSync(int functor, void* data, + const uirenderer::WebViewSyncData& syncData) { + AwDrawFn_OnSyncParams params = { + .version = kAwDrawFnVersion, + .apply_force_dark = syncData.applyForceDark, + }; + SupportData* support = static_cast<SupportData*>(data); + support->callbacks.on_sync(functor, support->data, ¶ms); +} + +void onContextDestroyed(int functor, void* data) { + SupportData* support = static_cast<SupportData*>(data); + support->callbacks.on_context_destroyed(functor, support->data); +} + +void onDestroyed(int functor, void* data) { + SupportData* support = static_cast<SupportData*>(data); + support->callbacks.on_destroyed(functor, support->data); + delete support; +} + +void draw_gl(int functor, void* data, + const uirenderer::DrawGlInfo& draw_gl_params) { + AwDrawFn_DrawGLParams params = { + .version = kAwDrawFnVersion, + .clip_left = draw_gl_params.clipLeft, + .clip_top = draw_gl_params.clipTop, + .clip_right = draw_gl_params.clipRight, + .clip_bottom = draw_gl_params.clipBottom, + .width = draw_gl_params.width, + .height = draw_gl_params.height, + .is_layer = draw_gl_params.isLayer, + }; + COMPILE_ASSERT(NELEM(params.transform) == NELEM(draw_gl_params.transform), + mismatched_transform_matrix_sizes); + for (int i = 0; i < NELEM(params.transform); ++i) { + params.transform[i] = draw_gl_params.transform[i]; + } + SupportData* support = static_cast<SupportData*>(data); + support->callbacks.draw_gl(functor, support->data, ¶ms); +} + +int CreateFunctor(void* data, AwDrawFnFunctorCallbacks* functor_callbacks) { + static bool callbacks_initialized = false; + static uirenderer::WebViewFunctorCallbacks webview_functor_callbacks = { + .onSync = &onSync, + .onContextDestroyed = &onContextDestroyed, + .onDestroyed = &onDestroyed, + }; + if (!callbacks_initialized) { + switch (uirenderer::WebViewFunctor_queryPlatformRenderMode()) { + case uirenderer::RenderMode::OpenGL_ES: + webview_functor_callbacks.gles.draw = &draw_gl; + break; + case uirenderer::RenderMode::Vulkan: + break; + } + callbacks_initialized = true; + } + SupportData* support = new SupportData{ + .data = data, + .callbacks = *functor_callbacks, + }; + int functor = uirenderer::WebViewFunctor_create( + support, webview_functor_callbacks, + uirenderer::WebViewFunctor_queryPlatformRenderMode()); + if (functor <= 0) delete support; + return functor; +} + +void ReleaseFunctor(int functor) { + uirenderer::WebViewFunctor_release(functor); +} + +AwDrawFnRenderMode QueryRenderMode(void) { + switch (uirenderer::WebViewFunctor_queryPlatformRenderMode()) { + case uirenderer::RenderMode::OpenGL_ES: + return AW_DRAW_FN_RENDER_MODE_OPENGL_ES; + case uirenderer::RenderMode::Vulkan: + return AW_DRAW_FN_RENDER_MODE_VULKAN; + } +} + +jlong GetDrawFnFunctionTable() { + static AwDrawFnFunctionTable function_table = { + .version = kAwDrawFnVersion, + .query_render_mode = &QueryRenderMode, + .create_functor = &CreateFunctor, + .release_functor = &ReleaseFunctor, + }; + return reinterpret_cast<intptr_t>(&function_table); +} + +const char kClassName[] = "com/android/webview/chromium/DrawFunctor"; +const JNINativeMethod kJniMethods[] = { + {"nativeGetFunctionTable", "()J", + reinterpret_cast<void*>(GetDrawFnFunctionTable)}, +}; + +} // namespace + +void RegisterDrawFunctor(JNIEnv* env) { + jclass clazz = env->FindClass(kClassName); + LOG_ALWAYS_FATAL_IF(!clazz, "Unable to find class '%s'", kClassName); + + int res = env->RegisterNatives(clazz, kJniMethods, NELEM(kJniMethods)); + LOG_ALWAYS_FATAL_IF(res < 0, "register native methods failed: res=%d", res); +} + +} // namespace android diff --git a/native/webview/plat_support/jni_entry_point.cpp b/native/webview/plat_support/jni_entry_point.cpp index 4771be1bc258..9599fa6da516 100644 --- a/native/webview/plat_support/jni_entry_point.cpp +++ b/native/webview/plat_support/jni_entry_point.cpp @@ -21,6 +21,7 @@ namespace android { +void RegisterDrawFunctor(JNIEnv* env); void RegisterDrawGLFunctor(JNIEnv* env); void RegisterGraphicsUtils(JNIEnv* env); @@ -30,6 +31,7 @@ JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) { JNIEnv* env = NULL; jint ret = vm->AttachCurrentThread(&env, NULL); LOG_ALWAYS_FATAL_IF(ret != JNI_OK, "AttachCurrentThread failed"); + android::RegisterDrawFunctor(env); android::RegisterDrawGLFunctor(env); android::RegisterGraphicsUtils(env); diff --git a/packages/CarSystemUI/src/com/android/systemui/qs/car/CarStatusBarHeader.java b/packages/CarSystemUI/src/com/android/systemui/qs/car/CarStatusBarHeader.java index d5dd3c3eaca0..4ef926fae816 100644 --- a/packages/CarSystemUI/src/com/android/systemui/qs/car/CarStatusBarHeader.java +++ b/packages/CarSystemUI/src/com/android/systemui/qs/car/CarStatusBarHeader.java @@ -28,7 +28,7 @@ import androidx.annotation.IdRes; import com.android.settingslib.Utils; import com.android.systemui.BatteryMeterView; import com.android.systemui.R; -import com.android.systemui.statusbar.policy.DarkIconDispatcher; +import com.android.systemui.plugins.DarkIconDispatcher; /** * A view that forms the header of the notification panel. This view will ensure that any diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/AssitantButton.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/AssitantButton.java index 5bf30ca10694..b36a7da35acf 100644 --- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/AssitantButton.java +++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/AssitantButton.java @@ -45,9 +45,7 @@ public class AssitantButton extends CarFacetButton { Log.d(TAG, "IVoiceInteractionSessionShowCallback onShown()"); } }; - - private static final String EXTRA_CAR_PUSH_TO_TALK = - "com.android.car.input.EXTRA_CAR_PUSH_TO_TALK"; + private final AssistUtils mAssistUtils; public AssitantButton(Context context, AttributeSet attrs) { @@ -60,7 +58,6 @@ public class AssitantButton extends CarFacetButton { private void showAssistant() { final Bundle args = new Bundle(); - args.putBoolean(EXTRA_CAR_PUSH_TO_TALK, true); mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_ASSIST_GESTURE, mShowCallback, /*activityToken=*/ null); } diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java index 7028999c159c..dbddf71d342c 100644 --- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java +++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java @@ -280,7 +280,9 @@ public class CarStatusBar extends StatusBar implements buildNavBarContent(); attachNavBarWindows(); - mNavigationBarController.createNavigationBars(); + // There has been a car customized nav bar on the default display, so just create nav bars + // on external displays. + mNavigationBarController.createNavigationBars(false /* includeDefaultDisplay */); } private void buildNavBarContent() { @@ -447,12 +449,6 @@ public class CarStatusBar extends StatusBar implements } } - - @Override - public View getNavigationBarWindow() { - return mNavigationBarWindow; - } - @Override protected View.OnTouchListener getStatusBarWindowTouchListener() { // Usually, a touch on the background window will dismiss the notification shade. However, diff --git a/packages/SettingsLib/SettingsSpinner/res/drawable/settings_spinner_background.xml b/packages/SettingsLib/SettingsSpinner/res/drawable/settings_spinner_background.xml index cbebbb32dc89..d6dc211ad8c4 100644 --- a/packages/SettingsLib/SettingsSpinner/res/drawable/settings_spinner_background.xml +++ b/packages/SettingsLib/SettingsSpinner/res/drawable/settings_spinner_background.xml @@ -18,12 +18,11 @@ <layer-list xmlns:android="http://schemas.android.com/apk/res/android" android:paddingMode="stack"> <item> - <shape - android:tint="?android:attr/colorForeground"> + <shape> <corners android:radius="20dp"/> <solid - android:color="@android:color/transparent"/> + android:color="?android:attr/colorPrimary"/> <stroke android:color="#1f000000" android:width="1dp"/> diff --git a/packages/SettingsLib/src/com/android/settingslib/location/RecentLocationAccesses.java b/packages/SettingsLib/src/com/android/settingslib/location/RecentLocationAccesses.java index 9af06702a696..4ac3ce436f82 100644 --- a/packages/SettingsLib/src/com/android/settingslib/location/RecentLocationAccesses.java +++ b/packages/SettingsLib/src/com/android/settingslib/location/RecentLocationAccesses.java @@ -31,6 +31,7 @@ import android.util.Log; import androidx.annotation.VisibleForTesting; +import java.time.Clock; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; @@ -56,11 +57,18 @@ public class RecentLocationAccesses { private final PackageManager mPackageManager; private final Context mContext; private final IconDrawableFactory mDrawableFactory; + private final Clock mClock; public RecentLocationAccesses(Context context) { + this(context, Clock.systemDefaultZone()); + } + + @VisibleForTesting + RecentLocationAccesses(Context context, Clock clock) { mContext = context; mPackageManager = context.getPackageManager(); mDrawableFactory = IconDrawableFactory.newInstance(context); + mClock = clock; } /** @@ -77,7 +85,7 @@ public class RecentLocationAccesses { // Process the AppOps list and generate a preference list. ArrayList<Access> accesses = new ArrayList<>(appOpsCount); - final long now = System.currentTimeMillis(); + final long now = mClock.millis(); final UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE); final List<UserHandle> profiles = um.getUserProfiles(); @@ -175,7 +183,7 @@ public class RecentLocationAccesses { public final CharSequence contentDescription; public final long accessFinishTime; - private Access(String packageName, UserHandle userHandle, Drawable icon, + public Access(String packageName, UserHandle userHandle, Drawable icon, CharSequence label, CharSequence contentDescription, long accessFinishTime) { this.packageName = packageName; diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/location/RecentLocationAccessesTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/location/RecentLocationAccessesTest.java new file mode 100644 index 000000000000..d5b89ca719ad --- /dev/null +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/location/RecentLocationAccessesTest.java @@ -0,0 +1,162 @@ +package com.android.settingslib.location; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.ArgumentMatchers.isA; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.when; + +import android.app.AppOpsManager; +import android.app.AppOpsManager.OpEntry; +import android.app.AppOpsManager.PackageOps; +import android.content.Context; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; +import android.content.pm.PackageManager.NameNotFoundException; +import android.os.Process; +import android.os.UserHandle; +import android.os.UserManager; + +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 java.time.Clock; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.TimeUnit; + +@RunWith(RobolectricTestRunner.class) +public class RecentLocationAccessesTest { + + private static final int TEST_UID = 1234; + private static final long NOW = 1_000_000_000; // Approximately 9/8/2001 + private static final long ONE_MIN_AGO = NOW - TimeUnit.MINUTES.toMillis(1); + private static final long TWENTY_THREE_HOURS_AGO = NOW - TimeUnit.HOURS.toMillis(23); + private static final long TWO_DAYS_AGO = NOW - TimeUnit.DAYS.toMillis(2); + private static final String[] TEST_PACKAGE_NAMES = + {"package_1MinAgo", "package_14MinAgo", "package_20MinAgo"}; + + @Mock + private PackageManager mPackageManager; + @Mock + private AppOpsManager mAppOpsManager; + @Mock + private UserManager mUserManager; + @Mock + private Clock mClock; + private Context mContext; + private int mTestUserId; + private RecentLocationAccesses mRecentLocationAccesses; + + @Before + public void setUp() throws NameNotFoundException { + MockitoAnnotations.initMocks(this); + mContext = spy(RuntimeEnvironment.application); + + when(mContext.getPackageManager()).thenReturn(mPackageManager); + when(mContext.getSystemService(Context.APP_OPS_SERVICE)).thenReturn(mAppOpsManager); + when(mContext.getSystemService(UserManager.class)).thenReturn(mUserManager); + when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager); + when(mPackageManager.getApplicationLabel(isA(ApplicationInfo.class))) + .thenReturn("testApplicationLabel"); + when(mPackageManager.getUserBadgedLabel(isA(CharSequence.class), isA(UserHandle.class))) + .thenReturn("testUserBadgedLabel"); + mTestUserId = UserHandle.getUserId(TEST_UID); + when(mUserManager.getUserProfiles()) + .thenReturn(Collections.singletonList(new UserHandle(mTestUserId))); + + long[] testRequestTime = {ONE_MIN_AGO, TWENTY_THREE_HOURS_AGO, TWO_DAYS_AGO}; + List<PackageOps> appOps = createTestPackageOpsList(TEST_PACKAGE_NAMES, testRequestTime); + when(mAppOpsManager.getPackagesForOps(RecentLocationAccesses.LOCATION_OPS)).thenReturn( + appOps); + mockTestApplicationInfos(mTestUserId, TEST_PACKAGE_NAMES); + + when(mClock.millis()).thenReturn(NOW); + mRecentLocationAccesses = new RecentLocationAccesses(mContext, mClock); + } + + @Test + public void testGetAppList_shouldFilterRecentAccesses() { + List<RecentLocationAccesses.Access> requests = mRecentLocationAccesses.getAppList(); + // Only two of the apps have requested location within 15 min. + assertThat(requests).hasSize(2); + // Make sure apps are ordered by recency + assertThat(requests.get(0).packageName).isEqualTo(TEST_PACKAGE_NAMES[0]); + assertThat(requests.get(0).accessFinishTime).isEqualTo(ONE_MIN_AGO); + assertThat(requests.get(1).packageName).isEqualTo(TEST_PACKAGE_NAMES[1]); + assertThat(requests.get(1).accessFinishTime).isEqualTo(TWENTY_THREE_HOURS_AGO); + } + + @Test + public void testGetAppList_shouldNotShowAndroidOS() throws NameNotFoundException { + // Add android OS to the list of apps. + PackageOps androidSystemPackageOps = + createPackageOps( + RecentLocationAccesses.ANDROID_SYSTEM_PACKAGE_NAME, + Process.SYSTEM_UID, + AppOpsManager.OP_FINE_LOCATION, + ONE_MIN_AGO); + long[] testRequestTime = + {ONE_MIN_AGO, TWENTY_THREE_HOURS_AGO, TWO_DAYS_AGO, ONE_MIN_AGO}; + List<PackageOps> appOps = createTestPackageOpsList(TEST_PACKAGE_NAMES, testRequestTime); + appOps.add(androidSystemPackageOps); + when(mAppOpsManager.getPackagesForOps(RecentLocationAccesses.LOCATION_OPS)).thenReturn( + appOps); + mockTestApplicationInfos( + Process.SYSTEM_UID, RecentLocationAccesses.ANDROID_SYSTEM_PACKAGE_NAME); + + List<RecentLocationAccesses.Access> requests = mRecentLocationAccesses.getAppList(); + // Android OS shouldn't show up in the list of apps. + assertThat(requests).hasSize(2); + // Make sure apps are ordered by recency + assertThat(requests.get(0).packageName).isEqualTo(TEST_PACKAGE_NAMES[0]); + assertThat(requests.get(0).accessFinishTime).isEqualTo(ONE_MIN_AGO); + assertThat(requests.get(1).packageName).isEqualTo(TEST_PACKAGE_NAMES[1]); + assertThat(requests.get(1).accessFinishTime).isEqualTo(TWENTY_THREE_HOURS_AGO); + } + + private void mockTestApplicationInfos(int userId, String... packageNameList) + throws NameNotFoundException { + for (String packageName : packageNameList) { + ApplicationInfo appInfo = new ApplicationInfo(); + appInfo.packageName = packageName; + when(mPackageManager.getApplicationInfoAsUser( + packageName, PackageManager.GET_META_DATA, userId)).thenReturn(appInfo); + } + } + + private List<PackageOps> createTestPackageOpsList(String[] packageNameList, long[] time) { + List<PackageOps> packageOpsList = new ArrayList<>(); + for (int i = 0; i < packageNameList.length; i++) { + PackageOps packageOps = createPackageOps( + packageNameList[i], + TEST_UID, + AppOpsManager.OP_FINE_LOCATION, + time[i]); + packageOpsList.add(packageOps); + } + return packageOpsList; + } + + private PackageOps createPackageOps(String packageName, int uid, int op, long time) { + return new PackageOps( + packageName, + uid, + Collections.singletonList(createOpEntryWithTime(op, time))); + } + + private OpEntry createOpEntryWithTime(int op, long time) { + final long[] times = new long[AppOpsManager._NUM_UID_STATE]; + // Slot for background access timestamp. + times[AppOpsManager.UID_STATE_LAST_NON_RESTRICTED + 1] = time; + final long[] rejectTimes = new long[AppOpsManager._NUM_UID_STATE]; + return new OpEntry(op, AppOpsManager.MODE_ALLOWED, times, rejectTimes, 0 /* duration */, + 0 /* proxyUid */, "" /* proxyPackage */); + } +} diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java index ce529a085e77..1727e75afe43 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java @@ -4125,10 +4125,12 @@ public class SettingsProvider extends ContentProvider { Secure.CHARGING_SOUNDS_ENABLED); if (!globalChargingSoundEnabled.isNull()) { - secureSettings.insertSettingLocked( - Secure.CHARGING_SOUNDS_ENABLED, - globalChargingSoundEnabled.getValue(), null, false, - SettingsState.SYSTEM_PACKAGE_NAME); + if (secureChargingSoundsEnabled.isNull()) { + secureSettings.insertSettingLocked( + Secure.CHARGING_SOUNDS_ENABLED, + globalChargingSoundEnabled.getValue(), null, false, + SettingsState.SYSTEM_PACKAGE_NAME); + } // set global charging_sounds_enabled setting to null since it's deprecated globalSettings.insertSettingLocked( diff --git a/packages/SettingsProvider/test/Android.mk b/packages/SettingsProvider/test/Android.mk index 0d681ed0f37a..ac97adb2c5c5 100644 --- a/packages/SettingsProvider/test/Android.mk +++ b/packages/SettingsProvider/test/Android.mk @@ -10,7 +10,7 @@ LOCAL_SRC_FILES := $(call all-subdir-java-files) \ ../src/com/android/providers/settings/SettingsState.java \ ../src/com/android/providers/settings/SettingsHelper.java -LOCAL_STATIC_JAVA_LIBRARIES := android-support-test +LOCAL_STATIC_JAVA_LIBRARIES := androidx.test.rules LOCAL_JAVA_LIBRARIES := android.test.base diff --git a/packages/SettingsProvider/test/AndroidManifest.xml b/packages/SettingsProvider/test/AndroidManifest.xml index 71e0b153daa9..87a4f603f70b 100644 --- a/packages/SettingsProvider/test/AndroidManifest.xml +++ b/packages/SettingsProvider/test/AndroidManifest.xml @@ -29,7 +29,7 @@ </application> <instrumentation - android:name="android.support.test.runner.AndroidJUnitRunner" + android:name="androidx.test.runner.AndroidJUnitRunner" android:targetPackage="com.android.providers.setting.test" android:label="Settings Provider Tests" /> diff --git a/packages/SettingsProvider/test/AndroidTest.xml b/packages/SettingsProvider/test/AndroidTest.xml index 46b8f94f23a3..9d2352670ddd 100644 --- a/packages/SettingsProvider/test/AndroidTest.xml +++ b/packages/SettingsProvider/test/AndroidTest.xml @@ -22,7 +22,7 @@ <option name="test-tag" value="SettingsProviderTest" /> <test class="com.android.tradefed.testtype.AndroidJUnitTest" > <option name="package" value="com.android.providers.setting.test" /> - <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" /> + <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" /> <option name="hidden-api-checks" value="false"/> </test> </configuration> diff --git a/packages/SettingsProvider/test/src/com/android/providers/settings/BaseSettingsProviderTest.java b/packages/SettingsProvider/test/src/com/android/providers/settings/BaseSettingsProviderTest.java index ab23af39b98f..68efa6779f04 100644 --- a/packages/SettingsProvider/test/src/com/android/providers/settings/BaseSettingsProviderTest.java +++ b/packages/SettingsProvider/test/src/com/android/providers/settings/BaseSettingsProviderTest.java @@ -25,9 +25,12 @@ import android.net.Uri; import android.os.UserHandle; import android.os.UserManager; import android.provider.Settings; -import android.support.test.InstrumentationRegistry; -import android.support.test.runner.AndroidJUnit4; + +import androidx.test.InstrumentationRegistry; +import androidx.test.runner.AndroidJUnit4; + import libcore.io.Streams; + import org.junit.runner.RunWith; import java.io.FileInputStream; diff --git a/packages/SettingsProvider/test/src/com/android/providers/settings/DeviceConfigServiceTest.java b/packages/SettingsProvider/test/src/com/android/providers/settings/DeviceConfigServiceTest.java index 5587cba59150..df4656a6deeb 100644 --- a/packages/SettingsProvider/test/src/com/android/providers/settings/DeviceConfigServiceTest.java +++ b/packages/SettingsProvider/test/src/com/android/providers/settings/DeviceConfigServiceTest.java @@ -24,8 +24,9 @@ import android.content.ContentResolver; import android.os.Bundle; import android.provider.DeviceConfig; import android.provider.Settings; -import android.support.test.InstrumentationRegistry; -import android.support.test.runner.AndroidJUnit4; + +import androidx.test.InstrumentationRegistry; +import androidx.test.runner.AndroidJUnit4; import libcore.io.Streams; diff --git a/packages/SettingsProvider/test/src/com/android/providers/settings/InstallNonMarketAppsDeprecationTest.java b/packages/SettingsProvider/test/src/com/android/providers/settings/InstallNonMarketAppsDeprecationTest.java index d8ee9b64c7d9..863b0352913a 100644 --- a/packages/SettingsProvider/test/src/com/android/providers/settings/InstallNonMarketAppsDeprecationTest.java +++ b/packages/SettingsProvider/test/src/com/android/providers/settings/InstallNonMarketAppsDeprecationTest.java @@ -26,10 +26,11 @@ import android.os.Process; import android.os.SystemClock; import android.os.UserManager; import android.provider.Settings; -import android.support.test.InstrumentationRegistry; -import android.support.test.filters.LargeTest; import android.util.Log; +import androidx.test.InstrumentationRegistry; +import androidx.test.filters.LargeTest; + import org.junit.After; import org.junit.Before; import org.junit.Test; diff --git a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsHelperRestoreTest.java b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsHelperRestoreTest.java index 10749571b623..54f8688bf5d6 100644 --- a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsHelperRestoreTest.java +++ b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsHelperRestoreTest.java @@ -24,8 +24,10 @@ import android.content.Context; import android.net.Uri; import android.os.Build; import android.provider.Settings; -import android.support.test.InstrumentationRegistry; -import android.support.test.runner.AndroidJUnit4; + +import androidx.test.InstrumentationRegistry; +import androidx.test.runner.AndroidJUnit4; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsHelperTest.java b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsHelperTest.java index 6fa014d4bef7..d112facc2b0e 100644 --- a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsHelperTest.java +++ b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsHelperTest.java @@ -17,19 +17,10 @@ package com.android.providers.settings; import static junit.framework.Assert.assertEquals; -import static junit.framework.Assert.assertSame; -import static junit.framework.Assert.assertNull; -import static junit.framework.Assert.fail; - -import com.android.internal.app.LocalePicker; -import com.android.providers.settings.SettingsHelper; import android.os.LocaleList; -import android.support.test.runner.AndroidJUnit4; -import java.util.ArrayList; -import java.util.List; -import java.util.Locale; +import androidx.test.runner.AndroidJUnit4; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/packages/SystemUI/legacy/recents/res/drawable/ic_lock_to_app_24dp.xml b/packages/SystemUI/legacy/recents/res/drawable/ic_lock_to_app_24dp.xml deleted file mode 100644 index 2d779499f6e6..000000000000 --- a/packages/SystemUI/legacy/recents/res/drawable/ic_lock_to_app_24dp.xml +++ /dev/null @@ -1,25 +0,0 @@ -<!-- -Copyright (C) 2014 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24.0dp" - android:height="24.0dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - - <path - android:fillColor="@color/recents_task_view_lock_to_app_button_color" - android:pathData="M18.0,8.0l-1.0,0.0L17.0,6.0c0.0,-2.8 -2.2,-5.0 -5.0,-5.0C9.2,1.0 7.0,3.2 7.0,6.0l0.0,2.0L6.0,8.0c-1.1,0.0 -2.0,0.9 -2.0,2.0l0.0,10.0c0.0,1.1 0.9,2.0 2.0,2.0l12.0,0.0c1.1,0.0 2.0,-0.9 2.0,-2.0L20.0,10.0C20.0,8.9 19.1,8.0 18.0,8.0zM12.0,17.0c-1.1,0.0 -2.0,-0.9 -2.0,-2.0s0.9,-2.0 2.0,-2.0c1.1,0.0 2.0,0.9 2.0,2.0S13.1,17.0 12.0,17.0zM15.1,8.0L8.9,8.0L8.9,6.0c0.0,-1.7 1.4,-3.1 3.1,-3.1c1.7,0.0 3.1,1.4 3.1,3.1L15.1,8.0z"/> -</vector> diff --git a/packages/SystemUI/legacy/recents/res/drawable/recents_freeform_workspace_bg.xml b/packages/SystemUI/legacy/recents/res/drawable/recents_freeform_workspace_bg.xml deleted file mode 100644 index 5f9341c0d151..000000000000 --- a/packages/SystemUI/legacy/recents/res/drawable/recents_freeform_workspace_bg.xml +++ /dev/null @@ -1,22 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2014 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this 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. ---> - -<shape xmlns:android="http://schemas.android.com/apk/res/android" - android:shape="rectangle"> - <corners android:topLeftRadius="@dimen/recents_task_view_rounded_corners_radius" - android:topRightRadius="@dimen/recents_task_view_rounded_corners_radius"/> - <solid android:color="#00000000" /> -</shape>
\ No newline at end of file diff --git a/packages/SystemUI/legacy/recents/res/drawable/recents_move_task_freeform_dark.xml b/packages/SystemUI/legacy/recents/res/drawable/recents_move_task_freeform_dark.xml deleted file mode 100644 index 9a060b4a3d39..000000000000 --- a/packages/SystemUI/legacy/recents/res/drawable/recents_move_task_freeform_dark.xml +++ /dev/null @@ -1,42 +0,0 @@ -<!-- -Copyright (C) 2015 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" - android:viewportWidth="24" - android:viewportHeight="24"> - - <group - android:translateX="-286.000000" - android:translateY="-602.000000"> - <group - android:translateX="109.000000" - android:translateY="514.000000"> - <group - android:translateX="178.000000" - android:translateY="89.000000"> - <path - android:strokeColor="@color/recents_task_bar_dark_icon_color" - android:strokeWidth="2" - android:pathData="M10,12 L10,3 L19,3 L19,5 L19,11 L19,12 L10,12 Z" /> - <path - android:strokeColor="@color/recents_task_bar_dark_icon_color" - android:strokeWidth="2" - android:pathData="M15,17 L5,17 L5,7 L5,17 Z" /> - </group> - </group> - </group> -</vector>
\ No newline at end of file diff --git a/packages/SystemUI/legacy/recents/res/drawable/recents_move_task_freeform_light.xml b/packages/SystemUI/legacy/recents/res/drawable/recents_move_task_freeform_light.xml deleted file mode 100644 index b8acedb3c2f7..000000000000 --- a/packages/SystemUI/legacy/recents/res/drawable/recents_move_task_freeform_light.xml +++ /dev/null @@ -1,42 +0,0 @@ -<!-- -Copyright (C) 2015 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" - android:viewportWidth="24" - android:viewportHeight="24"> - - <group - android:translateX="-286.000000" - android:translateY="-602.000000"> - <group - android:translateX="109.000000" - android:translateY="514.000000"> - <group - android:translateX="178.000000" - android:translateY="89.000000"> - <path - android:strokeColor="@color/recents_task_bar_light_icon_color" - android:strokeWidth="2" - android:pathData="M10,12 L10,3 L19,3 L19,5 L19,11 L19,12 L10,12 Z" /> - <path - android:strokeColor="@color/recents_task_bar_light_icon_color" - android:strokeWidth="2" - android:pathData="M15,17 L5,17 L5,7 L5,17 Z" /> - </group> - </group> - </group> -</vector>
\ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DarkIconDispatcher.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/DarkIconDispatcher.java index 0823db9aa7a9..c7bc858c8266 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DarkIconDispatcher.java +++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/DarkIconDispatcher.java @@ -1,62 +1,80 @@ /* - * Copyright (C) 2017 The Android Open Source Project + * 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 + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this 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. + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "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.policy; +package com.android.systemui.plugins; import android.graphics.Color; import android.graphics.Rect; import android.view.View; import android.widget.ImageView; -import com.android.systemui.Dumpable; -import com.android.systemui.statusbar.phone.LightBarTransitionsController; - -import java.io.FileDescriptor; -import java.io.PrintWriter; +import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver; +import com.android.systemui.plugins.annotations.DependsOn; +import com.android.systemui.plugins.annotations.ProvidesInterface; /** * Dispatches events to {@link DarkReceiver}s about changes in darkness, tint area and dark - * intensity + * intensity. Accessible through {@link PluginDependency} */ -public interface DarkIconDispatcher extends Dumpable { +@ProvidesInterface(version = DarkIconDispatcher.VERSION) +@DependsOn(target = DarkReceiver.class) +public interface DarkIconDispatcher { + int VERSION = 1; + /** + * Sets the dark area so {@link #applyDark} only affects the icons in the specified area. + * + * @param r the area in which icons should change its tint, in logical screen + * coordinates + */ void setIconsDarkArea(Rect r); - LightBarTransitionsController getTransitionsController(); + /** + * Adds a receiver to receive callbacks onDarkChanged + */ void addDarkReceiver(DarkReceiver receiver); + + /** + * Adds a receiver to receive callbacks onDarkChanged + */ void addDarkReceiver(ImageView imageView); - // Must have been previously been added through one of the addDarkReceive methods above. + /** + * Must have been previously been added through one of the addDarkReceive methods above. + */ void removeDarkReceiver(DarkReceiver object); - void removeDarkReceiver(ImageView object); - - // Used to reapply darkness on an object, must have previously been added through - // addDarkReceiver. - void applyDark(DarkReceiver object); /** - * Dumpable interface + * Must have been previously been added through one of the addDarkReceive methods above. */ - default void dump(FileDescriptor fd, PrintWriter pw, String[] args) {} + void removeDarkReceiver(ImageView object); + + /** + * Used to reapply darkness on an object, must have previously been added through + * addDarkReceiver. + */ + void applyDark(DarkReceiver object); int DEFAULT_ICON_TINT = Color.WHITE; Rect sTmpRect = new Rect(); int[] sTmpInt2 = new int[2]; /** - * @return the tint to apply to {@param view} depending on the desired tint {@param color} and - * the screen {@param tintArea} in which to apply that tint + * @return the tint to apply to view depending on the desired tint color and + * the screen tintArea in which to apply that tint */ static int getTint(Rect tintArea, View view, int color) { if (isInArea(tintArea, view)) { @@ -67,8 +85,8 @@ public interface DarkIconDispatcher extends Dumpable { } /** - * @return the dark intensity to apply to {@param view} depending on the desired dark - * {@param intensity} and the screen {@param tintArea} in which to apply that intensity + * @return the dark intensity to apply to view depending on the desired dark + * intensity and the screen tintArea in which to apply that intensity */ static float getDarkIntensity(Rect tintArea, View view, float intensity) { if (isInArea(tintArea, view)) { @@ -79,7 +97,7 @@ public interface DarkIconDispatcher extends Dumpable { } /** - * @return true if more than half of the {@param view} area are in {@param area}, false + * @return true if more than half of the view area are in area, false * otherwise */ static boolean isInArea(Rect area, View view) { @@ -99,7 +117,12 @@ public interface DarkIconDispatcher extends Dumpable { return majorityOfWidth && coversFullStatusBar; } + /** + * Receives a callback on darkness changes + */ + @ProvidesInterface(version = DarkReceiver.VERSION) interface DarkReceiver { + int VERSION = 1; void onDarkChanged(Rect area, float darkIntensity, int tint); } } diff --git a/packages/SystemUI/res/drawable-hdpi/ic_cancel_white_24dp.png b/packages/SystemUI/res/drawable-hdpi/ic_cancel_white_24dp.png Binary files differdeleted file mode 100644 index 73f5116bd71f..000000000000 --- a/packages/SystemUI/res/drawable-hdpi/ic_cancel_white_24dp.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-hdpi/ic_dismiss_outline.png b/packages/SystemUI/res/drawable-hdpi/ic_dismiss_outline.png Binary files differdeleted file mode 100755 index 9afd8fa14d31..000000000000 --- a/packages/SystemUI/res/drawable-hdpi/ic_dismiss_outline.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_lights_out_dot_large.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_lights_out_dot_large.png Binary files differdeleted file mode 100644 index 552a3d1ff43a..000000000000 --- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_lights_out_dot_large.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-land/search_panel_scrim.xml b/packages/SystemUI/res/drawable-land/search_panel_scrim.xml deleted file mode 100644 index 102cc9c16a9e..000000000000 --- a/packages/SystemUI/res/drawable-land/search_panel_scrim.xml +++ /dev/null @@ -1,25 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> - -<!-- - ~ Copyright (C) 2014 The Android Open Source Project - ~ - ~ Licensed under the Apache License, Version 2.0 (the "License"); - ~ you may not use this 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 - --> - -<shape xmlns:android="http://schemas.android.com/apk/res/android"> - <gradient - android:type="linear" - android:angle="180" - android:startColor="#55000000" - android:endColor="#00000000" /> -</shape>
\ No newline at end of file diff --git a/packages/SystemUI/res/drawable-mdpi/ic_cancel_white_24dp.png b/packages/SystemUI/res/drawable-mdpi/ic_cancel_white_24dp.png Binary files differdeleted file mode 100644 index 787e2593789b..000000000000 --- a/packages/SystemUI/res/drawable-mdpi/ic_cancel_white_24dp.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-mdpi/ic_dismiss_outline.png b/packages/SystemUI/res/drawable-mdpi/ic_dismiss_outline.png Binary files differdeleted file mode 100755 index 35737aa704ea..000000000000 --- a/packages/SystemUI/res/drawable-mdpi/ic_dismiss_outline.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_lights_out_dot_large.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_lights_out_dot_large.png Binary files differdeleted file mode 100644 index 48b96d810a0a..000000000000 --- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_lights_out_dot_large.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-nodpi/scorecard_gameover.xml b/packages/SystemUI/res/drawable-nodpi/scorecard_gameover.xml deleted file mode 100644 index f663a661f3f1..000000000000 --- a/packages/SystemUI/res/drawable-nodpi/scorecard_gameover.xml +++ /dev/null @@ -1,10 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<shape - xmlns:android="http://schemas.android.com/apk/res/android" - android:shape="rectangle" - > - <corners - android:radius="8dp" /> - <solid - android:color="#ffff0000" /> -</shape> diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_lights_out_dot_large.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_lights_out_dot_large.png Binary files differdeleted file mode 100644 index 23ec6dbde642..000000000000 --- a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_lights_out_dot_large.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_lights_out_dot_large.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_lights_out_dot_large.png Binary files differdeleted file mode 100644 index e4500587e5b5..000000000000 --- a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_lights_out_dot_large.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_lights_out_dot_large.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_lights_out_dot_large.png Binary files differdeleted file mode 100644 index d18e41906f57..000000000000 --- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_lights_out_dot_large.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_lights_out_dot_large.png b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_lights_out_dot_large.png Binary files differdeleted file mode 100644 index 00a751cfe3a4..000000000000 --- a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_lights_out_dot_large.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-sw600dp/search_panel_scrim.xml b/packages/SystemUI/res/drawable-sw600dp/search_panel_scrim.xml deleted file mode 100644 index bbb2617db4a0..000000000000 --- a/packages/SystemUI/res/drawable-sw600dp/search_panel_scrim.xml +++ /dev/null @@ -1,25 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> - -<!-- - ~ Copyright (C) 2014 The Android Open Source Project - ~ - ~ Licensed under the Apache License, Version 2.0 (the "License"); - ~ you may not use this 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 - --> - -<shape xmlns:android="http://schemas.android.com/apk/res/android"> - <gradient - android:type="linear" - android:angle="90" - android:startColor="#55000000" - android:endColor="#00000000" /> -</shape>
\ No newline at end of file diff --git a/packages/SystemUI/res/drawable-sw900dp-xxhdpi/ic_sysbar_back_light_old.png b/packages/SystemUI/res/drawable-sw900dp-xxhdpi/ic_sysbar_back_light_old.png Binary files differdeleted file mode 100644 index b336ccd2b5a1..000000000000 --- a/packages/SystemUI/res/drawable-sw900dp-xxhdpi/ic_sysbar_back_light_old.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_cancel_white_24dp.png b/packages/SystemUI/res/drawable-xhdpi/ic_cancel_white_24dp.png Binary files differdeleted file mode 100644 index 6ebbc831605f..000000000000 --- a/packages/SystemUI/res/drawable-xhdpi/ic_cancel_white_24dp.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_dismiss_outline.png b/packages/SystemUI/res/drawable-xhdpi/ic_dismiss_outline.png Binary files differdeleted file mode 100755 index f1bfa891d229..000000000000 --- a/packages/SystemUI/res/drawable-xhdpi/ic_dismiss_outline.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_lights_out_dot_large.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_lights_out_dot_large.png Binary files differdeleted file mode 100644 index e49db340dcfe..000000000000 --- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_lights_out_dot_large.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_lights_out_dot_large.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_lights_out_dot_large.png Binary files differdeleted file mode 100644 index b91704a928ab..000000000000 --- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_lights_out_dot_large.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable/dismiss_all_shape.xml b/packages/SystemUI/res/drawable/dismiss_all_shape.xml deleted file mode 100644 index fb371c6beb07..000000000000 --- a/packages/SystemUI/res/drawable/dismiss_all_shape.xml +++ /dev/null @@ -1,39 +0,0 @@ -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:height="17dp" - android:width="85dp" - android:viewportHeight="48" - android:viewportWidth="260" > - <group - android:name="dismiss_all" - android:translateX="48" - android:translateY="6" > - <group - android:name="3" - android:translateX="-24" - android:translateY="36" > - <path - android:name="rectangle_path_1_2" - android:pathData="M -24.0,-6.0 l 48.0,0 l 0,12.0 l -48.0,0 Z" - android:fillColor="#FFFFFFFF" - android:fillAlpha="1" /> - </group> - <group - android:name="2" - android:translateX="-12" - android:translateY="18" > - <path - android:name="rectangle_path_1_1" - android:pathData="M -24.0,-6.0 l 48.0,0 l 0,12.0 l -48.0,0 Z" - android:fillColor="#FFFFFFFF" - android:fillAlpha="1" /> - </group> - <group - android:name="1" > - <path - android:name="rectangle_path_1" - android:pathData="M -24.0,-6.0 l 48.0,0 l 0,12.0 l -48.0,0 Z" - android:fillColor="#FFFFFFFF" - android:fillAlpha="1" /> - </group> - </group> -</vector> diff --git a/packages/SystemUI/res/drawable/fingerprint_icon.xml b/packages/SystemUI/res/drawable/fingerprint_icon.xml deleted file mode 100644 index 76a86ae42da2..000000000000 --- a/packages/SystemUI/res/drawable/fingerprint_icon.xml +++ /dev/null @@ -1,107 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - ~ 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 - --> - -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="60dp" - android:height="60dp" - android:viewportWidth="60" - android:viewportHeight="60"> - - <path - android:fillColor="#1A73E8" - android:fillType="evenOdd" - android:strokeWidth="1" - android:pathData="M 30 0 C 46.5685424949 0 60 13.4314575051 60 30 C 60 46.5685424949 46.5685424949 60 30 60 C 13.4314575051 60 0 46.5685424949 0 30 C 0 13.4314575051 13.4314575051 0 30 0 Z" /> - <group - android:translateX="17.727273" - android:translateY="16.363636"> - <path - android:fillColor="#FFFFFF" - android:strokeWidth="1" - android:pathData="M20.3065726,3.44516129 C20.1974817,3.44516129 20.0883908,3.41788856 -19.9929362,3.36334311 C17.3747544,2.01334311 15.111118,1.44061584 -12.3974817,1.44061584 C9.69748166,1.44061584 7.1338453,2.08152493 -4.80202711,3.36334311 C4.47475439,3.54061584 4.06566348,3.41788856 -3.87475439,3.09061584 C3.69748166,2.76334311 3.82020893,2.34061584 -4.14748166,2.16334311 C6.6838453,0.786070381 9.46566348,0.0769794721 -12.3974817,0.0769794721 C15.3020271,0.0769794721 17.8383908,0.717888563 -20.6202089,2.14970674 C20.961118,2.32697947 21.0838453,2.73607038 -20.9065726,3.06334311 C20.7838453,3.30879765 20.5520271,3.44516129 -20.3065726,3.44516129 L20.3065726,3.44516129 Z M0.792936205,10.6042522 -C0.656572568,10.6042522 0.520208932,10.5633431 0.397481659,10.4815249 -C0.0838452956,10.2633431 0.0156634774,9.84061584 0.233845296,9.52697947 -C1.5838453,7.61788856 3.30202711,6.11788856 5.34748166,5.06788856 -C9.62929984,2.85879765 15.111118,2.84516129 19.4065726,5.0542522 -C21.4520271,6.1042522 23.1702089,7.59061584 24.5202089,9.48607038 -C24.7383908,9.78607038 24.6702089,10.222434 24.3565726,10.4406158 -C24.0429362,10.6587977 23.6202089,10.5906158 23.4020271,10.2769795 -C22.1747544,8.55879765 20.6202089,7.20879765 18.7792998,6.26788856 -C14.8656635,4.26334311 9.86111802,4.26334311 5.96111802,6.28152493 -C4.10657257,7.23607038 2.55202711,8.59970674 1.32475439,10.3178886 -C1.21566348,10.5087977 1.01111802,10.6042522 0.792936205,10.6042522 -L0.792936205,10.6042522 Z M9.31566348,27.0633431 C9.13839075,27.0633431 -8.96111802,26.9951613 8.83839075,26.8587977 C7.65202711,25.672434 -7.01111802,24.9087977 6.09748166,23.2587977 C5.15657257,21.5815249 -4.66566348,19.5360704 4.66566348,17.3406158 C4.66566348,13.2906158 -8.12929984,9.99061584 12.3838453,9.99061584 C16.6383908,9.99061584 -20.1020271,13.2906158 20.1020271,17.3406158 C20.1020271,17.722434 -19.8020271,18.022434 19.4202089,18.022434 C19.0383908,18.022434 -18.7383908,17.722434 18.7383908,17.3406158 C18.7383908,14.0406158 -15.8883908,11.3542522 12.3838453,11.3542522 C8.87929984,11.3542522 -6.02929984,14.0406158 6.02929984,17.3406158 C6.02929984,19.3042522 -6.46566348,21.1178886 7.29748166,22.5906158 C8.17020893,24.1587977 -8.77020893,24.8269795 9.82020893,25.8906158 C10.0792998,26.1633431 -10.0792998,26.5860704 9.82020893,26.8587977 C9.67020893,26.9951613 -9.4929362,27.0633431 9.31566348,27.0633431 Z M19.0929362,24.5406158 -C17.4702089,24.5406158 16.0383908,24.1315249 14.8656635,23.3269795 -C12.8338453,21.9497067 11.6202089,19.7133431 11.6202089,17.3406158 -C11.6202089,16.9587977 11.9202089,16.6587977 12.3020271,16.6587977 -C12.6838453,16.6587977 12.9838453,16.9587977 12.9838453,17.3406158 -C12.9838453,19.2633431 13.9656635,21.0769795 15.6292998,22.1951613 -C16.5974817,22.8497067 17.7292998,23.1633431 19.0929362,23.1633431 -C19.4202089,23.1633431 19.9656635,23.122434 20.511118,23.0269795 -C20.8792998,22.9587977 21.2338453,23.2042522 21.3020271,23.5860704 -C21.3702089,23.9542522 21.1247544,24.3087977 20.7429362,24.3769795 -C19.9656635,24.5269795 19.2838453,24.5406158 19.0929362,24.5406158 -L19.0929362,24.5406158 Z M16.3520271,27.3497067 C16.2974817,27.3497067 -16.2292998,27.3360704 16.1747544,27.322434 C14.0065726,26.722434 -12.5883908,25.9178886 11.1020271,24.4587977 C9.1929362,22.5633431 -8.1429362,20.0406158 8.1429362,17.3406158 C8.1429362,15.1315249 -10.0247544,13.3315249 12.3429362,13.3315249 C14.661118,13.3315249 -16.5429362,15.1315249 16.5429362,17.3406158 C16.5429362,18.7997067 -17.811118,19.9860704 19.3792998,19.9860704 C20.9474817,19.9860704 -22.2156635,18.7997067 22.2156635,17.3406158 C22.2156635,12.1997067 -17.7838453,8.02697947 12.3292998,8.02697947 C8.45657257,8.02697947 -4.91111802,10.1815249 3.31566348,13.522434 C2.7838453,14.6269795 -2.51111802,15.922434 2.51111802,17.3406158 C2.51111802,18.4042522 -2.60657257,20.0815249 3.42475439,22.2633431 C3.56111802,22.6178886 -3.3838453,23.0133431 3.02929984,23.1360704 C2.67475439,23.272434 -2.27929984,23.0815249 2.15657257,22.7406158 C1.48839075,20.9542522 -1.16111802,19.1815249 1.16111802,17.3406158 C1.16111802,15.7042522 -1.47475439,14.2178886 2.08839075,12.922434 C3.90202711,9.11788856 -7.92475439,6.64970674 12.3292998,6.64970674 C18.5338453,6.64970674 -23.5792998,11.4360704 23.5792998,17.3269795 C23.5792998,19.5360704 -21.6974817,21.3360704 19.3792998,21.3360704 C17.061118,21.3360704 -15.1792998,19.5360704 15.1792998,17.3269795 C15.1792998,15.8678886 -13.911118,14.6815249 12.3429362,14.6815249 C10.7747544,14.6815249 -9.50657257,15.8678886 9.50657257,17.3269795 C9.50657257,19.6587977 -10.4065726,21.8406158 12.0565726,23.4769795 C13.3520271,24.7587977 -14.5929362,25.4678886 16.5156635,25.9997067 C16.8838453,26.0951613 -17.0883908,26.4769795 16.9929362,26.8315249 C16.9247544,27.1451613 -16.6383908,27.3497067 16.3520271,27.3497067 L16.3520271,27.3497067 Z" /> - </group> -</vector>
\ No newline at end of file diff --git a/packages/SystemUI/res/drawable/header_dot.xml b/packages/SystemUI/res/drawable/header_dot.xml deleted file mode 100644 index dbc6b378bd63..000000000000 --- a/packages/SystemUI/res/drawable/header_dot.xml +++ /dev/null @@ -1,28 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -** Copyright 2015, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. ---> -<shape - xmlns:android="http://schemas.android.com/apk/res/android" - android:shape="oval" - android:tint="?android:attr/colorControlNormal"> - - <solid - android:color="#FFFFFF"/> - - <size - android:width="3dp" - android:height="3dp"/> -</shape> diff --git a/packages/SystemUI/res/drawable/ic_aod_charging_24dp.xml b/packages/SystemUI/res/drawable/ic_aod_charging_24dp.xml deleted file mode 100644 index 6134b8f75457..000000000000 --- a/packages/SystemUI/res/drawable/ic_aod_charging_24dp.xml +++ /dev/null @@ -1,24 +0,0 @@ -<!-- -Copyright (C) 2014 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24.0dp" - android:height="24.0dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - <path - android:pathData="M11.0,22.98l0.0,-8.98 -4.0,0.0 6.0,-13.0 0.0,9.0 4.0,0.0z" - android:fillColor="#ffffff"/> -</vector> diff --git a/packages/SystemUI/res/drawable/ic_cast.xml b/packages/SystemUI/res/drawable/ic_cast.xml deleted file mode 100644 index b86dfea07682..000000000000 --- a/packages/SystemUI/res/drawable/ic_cast.xml +++ /dev/null @@ -1,31 +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. - --> - -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0" - android:tint="?android:attr/colorControlNormal"> - <path - android:fillColor="#FFFFFFFF" - android:pathData="M1 18v2c0 .55 .45 1 1 1h2c0-1.66-1.34-3-3-3zm0-2.94c-.01 .51 .32 .93 .82 1.02 -2.08 .36 3.74 2 4.1 4.08 .09 .48 .5 .84 .99 .84 .61 0 1.09-.54 1-1.14a6.996 -6.996 0 0 0-5.8-5.78c-.59-.09-1.09 .38 -1.11 .98 zm0-4.03c-.01 .52 .34 .96 .85 -1.01 4.26 .43 7.68 3.82 8.1 8.08 .05 .5 .48 .88 .99 .88 .59 0 1.06-.51 -1-1.1-.52-5.21-4.66-9.34-9.87-9.85-.57-.05-1.05 .4 -1.07 .98 zM21 3H3c-1.1 0-2 -.9-2 2v3h2V5h18v14h-7v2h7c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2z"/> -</vector>
\ No newline at end of file diff --git a/packages/SystemUI/res/drawable/ic_chevron_left.xml b/packages/SystemUI/res/drawable/ic_chevron_left.xml deleted file mode 100644 index 379382b06504..000000000000 --- a/packages/SystemUI/res/drawable/ic_chevron_left.xml +++ /dev/null @@ -1,25 +0,0 @@ -<!-- - ~ Copyright (C) 2014 The Android Open Source Project - ~ - ~ Licensed under the Apache License, Version 2.0 (the "License"); - ~ you may not use this file except in compliance with the License. - ~ You may obtain a copy of the License at - ~ - ~ http://www.apache.org/licenses/LICENSE-2.0 - ~ - ~ Unless required by applicable law or agreed to in writing, software - ~ distributed under the License is distributed on an "AS IS" BASIS, - ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - ~ See the License for the specific language governing permissions and - ~ limitations under the License - --> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" - android:viewportWidth="36.0" - android:viewportHeight="36.0"> - - <path - android:fillColor="#ffffffff" - android:pathData="M23.1,11.1l-2.1000004,-2.1000004 -9.0,9.0 9.0,9.0 2.1000004,-2.1000004 -6.8999996,-6.8999996z"/> -</vector> diff --git a/packages/SystemUI/res/drawable/ic_data_off.xml b/packages/SystemUI/res/drawable/ic_data_off.xml deleted file mode 100644 index b97ddaef6418..000000000000 --- a/packages/SystemUI/res/drawable/ic_data_off.xml +++ /dev/null @@ -1,27 +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. ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24.0dp" - android:height="24.0dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - <path - android:pathData="M21.6,21.6L10.8,10.9L2.1,2.1L0.8,3.4l3.3,3.3C3.1,8.2 2.5,10.0 2.5,12.0c0.0,5.2 4.3,9.5 9.5,9.5c2.0,0.0 3.8,-0.6 5.3,-1.6l3.0,3.0L21.6,21.6zM9.6,12.2l0.7,0.7L9.6,12.9L9.6,12.2zM13.9,18.6c-0.2,0.2 -0.5,0.2 -0.6,0.0l-2.4,-3.7l1.5,0.0l2.4,2.4L13.9,18.6z" - android:fillColor="#ffffff"/> - <path - android:pathData="M12.0,2.5c-2.0,0.0 -3.8,0.6 -5.3,1.6l2.5,2.5L10.0,5.4c0.2,-0.2 0.5,-0.2 0.6,0.0L13.0,9.1l-1.4,0.0l2.0,2.0l0.6,0.0l0.0,0.6l5.6,5.6c1.0,-1.5 1.6,-3.3 1.6,-5.3C21.5,6.8 17.2,2.5 12.0,2.5z" - android:fillColor="#ffffff"/> -</vector> diff --git a/packages/SystemUI/res/drawable/ic_data_on.xml b/packages/SystemUI/res/drawable/ic_data_on.xml deleted file mode 100644 index a65dc7922ceb..000000000000 --- a/packages/SystemUI/res/drawable/ic_data_on.xml +++ /dev/null @@ -1,26 +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. ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24.0dp" - android:height="24.0dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - <path - android:pathData="M12.0,12.0m-9.5,0.0a9.5,9.5 0.0,1.0 1.0,19.0 0.0a9.5,9.5 0.0,1.0 1.0,-19.0 0.0 - M10.6,5.4c-0.2,-0.2 -0.5,-0.2 -0.6,0.0L7.6,9.1l2.0,0.0l0.0,3.8L11.0,12.900001L11.0,9.1l2.0,0.0L10.6,5.4z - M13.3,18.6c0.2,0.2 0.5,0.2 0.6,0.0l2.4,-3.7l-2.0,0.0l0.0,-3.8l-1.4,0.0l0.0,3.8l-2.0,0.0L13.3,18.6z" - android:fillColor="#ffffff"/> -</vector> diff --git a/packages/SystemUI/res/drawable/ic_data_unavailable.xml b/packages/SystemUI/res/drawable/ic_data_unavailable.xml deleted file mode 100644 index ffb2af71c546..000000000000 --- a/packages/SystemUI/res/drawable/ic_data_unavailable.xml +++ /dev/null @@ -1,27 +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. ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24.0dp" - android:height="24.0dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - <path - android:pathData="M15.8,12.9l3.7,0.0c0.0,-0.3 0.0,-0.6 0.0,-0.9c0.0,-5.2 -4.3,-9.5 -9.5,-9.5S0.6,6.8 0.6,12.0s4.3,9.5 9.5,9.5c2.1,0.0 4.1,-0.7 5.7,-1.9L15.8,12.9zM5.7,9.1l2.4,-3.7c0.2,-0.2 0.5,-0.2 0.6,0.0l2.4,3.7l-2.0,0.0l0.0,3.8L7.8,12.900001L7.8,9.1L5.7,9.1zM11.4,18.6L9.0,14.9l2.0,0.0l0.0,-3.8l1.4,0.0l0.0,3.8l2.0,0.0L12.0,18.6C11.9,18.8 11.6,18.8 11.4,18.6z" - android:fillColor="#FFFFFF"/> - <path - android:pathData="M23.4,19.4l-2.1,-2.1 2.1,-2.199999 -1.1,-1.0 -2.099998,2.1 -2.1,-2.1 -1.1,1.099999 2.1,2.099999 -2.1,2.1 1.1,1.1 2.1,-2.200001 2.099998,2.200001z" - android:fillColor="#FFFFFF"/> -</vector> diff --git a/packages/SystemUI/res/drawable/ic_expand_less.xml b/packages/SystemUI/res/drawable/ic_expand_less.xml deleted file mode 100644 index e96801353ffa..000000000000 --- a/packages/SystemUI/res/drawable/ic_expand_less.xml +++ /dev/null @@ -1,24 +0,0 @@ -<!-- -Copyright (C) 2015 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="20.0dp" - android:height="20.0dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - <path - android:pathData="M12.000000,8.000000l-6.000000,6.000000 1.400000,1.400000 4.600000,-4.599999 4.600000,4.599999 1.400000,-1.400000z" - android:fillColor="#FF000000"/> -</vector> diff --git a/packages/SystemUI/res/drawable/ic_expand_more.xml b/packages/SystemUI/res/drawable/ic_expand_more.xml deleted file mode 100644 index 72e98ec21897..000000000000 --- a/packages/SystemUI/res/drawable/ic_expand_more.xml +++ /dev/null @@ -1,24 +0,0 @@ -<!-- -Copyright (C) 2015 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="20.0dp" - android:height="20.0dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - <path - android:pathData="M16.600000,8.600000l-4.600000,4.599999 -4.600000,-4.599999 -1.400000,1.400000 6.000000,6.000000 6.000000,-6.000000z" - android:fillColor="#FF000000"/> -</vector> diff --git a/packages/SystemUI/res/drawable/ic_history.xml b/packages/SystemUI/res/drawable/ic_history.xml deleted file mode 100644 index e936864f82ab..000000000000 --- a/packages/SystemUI/res/drawable/ic_history.xml +++ /dev/null @@ -1,28 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - Copyright (C) 2016 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" - android:viewportWidth="24" - android:viewportHeight="24"> - - <path - android:fillColor="#FFFFFF" - android:pathData="M13 3c-4.97 0-9 4.03-9 9H1l3.89 3.89 .07 .14L9 12H6c0-3.87 3.13-7 7-7s7 3.13 7 -7-3.13 7-7 7c-1.93 0-3.68-.79-4.94-2.06l-1.42 1.42C8.27 19.99 10.51 21 13 -21c4.97 0 9-4.03 9-9s-4.03-9-9-9zm-1 5v5l4.28 2.54 .72 -1.21-3.5-2.08V8H12z" /> -</vector>
\ No newline at end of file diff --git a/packages/SystemUI/res/drawable/ic_notify_button_bg.xml b/packages/SystemUI/res/drawable/ic_notify_button_bg.xml deleted file mode 100644 index 3a47261851a5..000000000000 --- a/packages/SystemUI/res/drawable/ic_notify_button_bg.xml +++ /dev/null @@ -1,20 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- 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. ---> - -<selector xmlns:android="http://schemas.android.com/apk/res/android"> - <item android:state_pressed="true" - android:drawable="@*android:drawable/list_selector_pressed_holo_dark" /> -</selector> diff --git a/packages/SystemUI/res/drawable/ic_qs_back.xml b/packages/SystemUI/res/drawable/ic_qs_back.xml deleted file mode 100644 index f00ba03eb829..000000000000 --- a/packages/SystemUI/res/drawable/ic_qs_back.xml +++ /dev/null @@ -1,25 +0,0 @@ -<!-- -Copyright (C) 2014 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="64dp" - android:height="64dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - - <path - android:fillColor="#FFFFFFFF" - android:pathData="M20.0,11.0L7.8,11.0l5.6,-5.6L12.0,4.0l-8.0,8.0l8.0,8.0l1.4,-1.4L7.8,13.0L20.0,13.0L20.0,11.0z"/> -</vector> diff --git a/packages/SystemUI/res/drawable/ic_qs_battery_saver.xml b/packages/SystemUI/res/drawable/ic_qs_battery_saver.xml deleted file mode 100644 index 7b29740be338..000000000000 --- a/packages/SystemUI/res/drawable/ic_qs_battery_saver.xml +++ /dev/null @@ -1,28 +0,0 @@ -<!-- - Copyright (C) 2016 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:autoMirrored="true" - android:width="32.0dp" - android:height="32.0dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0" - android:tint="?android:attr/colorControlNormal"> - <path - android:pathData="M5,3 - l3.5,0 l0,-1.5 l7,0 l0,1.5 l3.5,0 l0,19.5 l-14,0z - M10.5,8.5 l0,3 l-3,0 l0,3 l3,0 l0,3 l3,0 l0,-3 l3,0 l0,-3 l-3,0 l0,-3 z" - android:fillColor="#FFFFFF"/> -</vector> diff --git a/packages/SystemUI/res/drawable/ic_qs_lock.xml b/packages/SystemUI/res/drawable/ic_qs_lock.xml deleted file mode 100644 index 204af7e81f4c..000000000000 --- a/packages/SystemUI/res/drawable/ic_qs_lock.xml +++ /dev/null @@ -1,25 +0,0 @@ -<!-- -Copyright (C) 2014 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24.0dp" - android:height="24.0dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - - <path - android:fillColor="@color/keyguard_affordance" - android:pathData="M18.0,8.0l-1.0,0.0L17.0,6.0c0.0,-2.8 -2.2,-5.0 -5.0,-5.0C9.2,1.0 7.0,3.2 7.0,6.0l0.0,2.0L6.0,8.0c-1.1,0.0 -2.0,0.9 -2.0,2.0l0.0,10.0c0.0,1.1 0.9,2.0 2.0,2.0l12.0,0.0c1.1,0.0 2.0,-0.9 2.0,-2.0L20.0,10.0C20.0,8.9 19.1,8.0 18.0,8.0zM12.0,17.0c-1.1,0.0 -2.0,-0.9 -2.0,-2.0s0.9,-2.0 2.0,-2.0c1.1,0.0 2.0,0.9 2.0,2.0S13.1,17.0 12.0,17.0zM15.1,8.0L8.9,8.0L8.9,6.0c0.0,-1.7 1.4,-3.1 3.1,-3.1c1.7,0.0 3.1,1.4 3.1,3.1L15.1,8.0z"/> -</vector> diff --git a/packages/SystemUI/res/drawable/ic_qs_lock_open.xml b/packages/SystemUI/res/drawable/ic_qs_lock_open.xml deleted file mode 100644 index c877f063b7a8..000000000000 --- a/packages/SystemUI/res/drawable/ic_qs_lock_open.xml +++ /dev/null @@ -1,25 +0,0 @@ -<!-- -Copyright (C) 2014 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24.0dp" - android:height="24.0dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - - <path - android:fillColor="@color/keyguard_affordance" - android:pathData="M12.0,17.0c1.1,0.0 2.0,-0.9 2.0,-2.0s-0.9,-2.0 -2.0,-2.0c-1.1,0.0 -2.0,0.9 -2.0,2.0S10.9,17.0 12.0,17.0zM18.0,8.0l-1.0,0.0L17.0,6.0c0.0,-2.8 -2.2,-5.0 -5.0,-5.0C9.2,1.0 7.0,3.2 7.0,6.0l1.9,0.0c0.0,-1.7 1.4,-3.1 3.1,-3.1c1.7,0.0 3.1,1.4 3.1,3.1l0.0,2.0L6.0,8.0c-1.1,0.0 -2.0,0.9 -2.0,2.0l0.0,10.0c0.0,1.1 0.9,2.0 2.0,2.0l12.0,0.0c1.1,0.0 2.0,-0.9 2.0,-2.0L20.0,10.0C20.0,8.9 19.1,8.0 18.0,8.0zM18.0,20.0L6.0,20.0L6.0,10.0l12.0,0.0L18.0,20.0z"/> -</vector> diff --git a/packages/SystemUI/res/drawable/ic_qs_network_logging.xml b/packages/SystemUI/res/drawable/ic_qs_network_logging.xml deleted file mode 100644 index 7bdf50c74bed..000000000000 --- a/packages/SystemUI/res/drawable/ic_qs_network_logging.xml +++ /dev/null @@ -1,28 +0,0 @@ -<!-- -Copyright (C) 2016 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> - -<!-- Placeholder icon for network logging until the real icon is finalized--> - -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="12.0dp" - android:height="12.0dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - <path - android:fillColor="#FFFFFFFF" - android:pathData="M2,24v-4h12v4H2z M2,16v-4h20v4H2z M5,7 12,0 19,7 14,7 14,15 10,15 10,7z"/> - -</vector> diff --git a/packages/SystemUI/res/drawable/ic_qs_ringer_audible.xml b/packages/SystemUI/res/drawable/ic_qs_ringer_audible.xml deleted file mode 100644 index 29741577c039..000000000000 --- a/packages/SystemUI/res/drawable/ic_qs_ringer_audible.xml +++ /dev/null @@ -1,28 +0,0 @@ -<!-- -Copyright (C) 2014 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="64dp" - android:height="64dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - - <path - android:fillColor="#FFFFFFFF" - android:pathData="M18,17v-6c0,-3.07 -1.63,-5.64 -4.5,-6.32V4c0,-0.83 -0.67,-1.5 -1.5,-1.5S10.5,3.17 10.5,4v0.68C7.64,5.36 6,7.92 6,11v6H4v2h10h0.38H20v-2H18zM16,17H8v-6c0,-2.48 1.51,-4.5 4,-4.5s4,2.02 4,4.5V17z"/> - <path - android:fillColor="#FFFFFFFF" - android:pathData="M12,22c1.1,0 2,-0.9 2,-2h-4C10,21.1 10.9,22 12,22z"/> -</vector> diff --git a/packages/SystemUI/res/drawable/ic_qs_ringer_silent.xml b/packages/SystemUI/res/drawable/ic_qs_ringer_silent.xml deleted file mode 100644 index 6db508cd31e8..000000000000 --- a/packages/SystemUI/res/drawable/ic_qs_ringer_silent.xml +++ /dev/null @@ -1,31 +0,0 @@ -<!-- -Copyright (C) 2014 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="64dp" - android:height="64dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - - <path - android:fillColor="#FFFFFFFF" - android:pathData="M12,22c1.1,0 2,-0.9 2,-2h-4C10,21.1 10.9,22 12,22z"/> - <path - android:fillColor="#FFFFFFFF" - android:pathData="M16,16L2.81,2.81L1.39,4.22l4.85,4.85C6.09,9.68 6,10.33 6,11v6H4v2h12.17l3.61,3.61l1.41,-1.41L16,16zM8,17c0,0 0.01,-6.11 0.01,-6.16L14.17,17H8z"/> - <path - android:fillColor="#FFFFFFFF" - android:pathData="M12,6.5c2.49,0 4,2.02 4,4.5v2.17l2,2V11c0,-3.07 -1.63,-5.64 -4.5,-6.32V4c0,-0.83 -0.67,-1.5 -1.5,-1.5S10.5,3.17 10.5,4v0.68C9.72,4.86 9.05,5.2 8.46,5.63L9.93,7.1C10.51,6.73 11.2,6.5 12,6.5z"/> -</vector> diff --git a/packages/SystemUI/res/drawable/ic_qs_ringer_vibrate.xml b/packages/SystemUI/res/drawable/ic_qs_ringer_vibrate.xml deleted file mode 100644 index c87b595a20f2..000000000000 --- a/packages/SystemUI/res/drawable/ic_qs_ringer_vibrate.xml +++ /dev/null @@ -1,25 +0,0 @@ -<!-- -Copyright (C) 2014 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="64dp" - android:height="64dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - - <path - android:fillColor="#FFFFFFFF" - android:pathData="M1,9h2v6H1V9zM4,17h2V7H4V17zM21,9v6h2V9H21zM18,17h2V7h-2V17zM17,5.5v13c0,0.83 -0.67,1.5 -1.5,1.5h-7C7.67,20 7,19.33 7,18.5v-13C7,4.67 7.67,4 8.5,4h7C16.33,4 17,4.67 17,5.5zM15,6H9v12h6V6z"/> -</vector> diff --git a/packages/SystemUI/res/drawable/ic_signal_workmode_disable_animation.xml b/packages/SystemUI/res/drawable/ic_signal_workmode_disable_animation.xml deleted file mode 100644 index 4a2bd548f61d..000000000000 --- a/packages/SystemUI/res/drawable/ic_signal_workmode_disable_animation.xml +++ /dev/null @@ -1,35 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<animated-vector - xmlns:android="http://schemas.android.com/apk/res/android" - android:drawable="@drawable/ic_signal_workmode_disable" > - <target - android:name="mask_1" - android:animation="@anim/ic_signal_workmode_disable_mask_1_animation" /> - <target - android:name="whole" - android:animation="@anim/ic_signal_workmode_disable_whole_animation" /> - <target - android:name="rectangle_path_3_position" - android:animation="@anim/ic_signal_workmode_disable_rectangle_path_3_position_animation" /> - <target - android:name="rectangle_path_3" - android:animation="@anim/ic_signal_workmode_disable_rectangle_path_3_animation" /> - <target - android:name="rectangle_path_4_position" - android:animation="@anim/ic_signal_workmode_disable_rectangle_path_4_position_animation" /> - <target - android:name="rectangle_path_4" - android:animation="@anim/ic_signal_workmode_disable_rectangle_path_4_animation" /> - <target - android:name="left" - android:animation="@anim/ic_signal_workmode_disable_left_animation" /> - <target - android:name="right" - android:animation="@anim/ic_signal_workmode_disable_right_animation" /> - <target - android:name="stick" - android:animation="@anim/ic_signal_workmode_disable_stick_animation" /> - <target - android:name="ic_signal_workmode_disable" - android:animation="@anim/ic_signal_workmode_disable_stickito_animation" /> -</animated-vector> diff --git a/packages/SystemUI/res/drawable/ic_signal_workmode_enable.xml b/packages/SystemUI/res/drawable/ic_signal_workmode_enable.xml deleted file mode 100644 index 2d4f0b5d162f..000000000000 --- a/packages/SystemUI/res/drawable/ic_signal_workmode_enable.xml +++ /dev/null @@ -1,128 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<vector - xmlns:android="http://schemas.android.com/apk/res/android" - android:name="ic_signal_workmode_enable" - android:width="42dp" - android:viewportWidth="42" - android:height="42dp" - android:viewportHeight="42" > - <group - android:name="suitcase" - android:translateX="21" - android:translateY="36.9375" - android:scaleX="0.1" - android:scaleY="0.1" > - <group - android:name="suitcase_pivot" - android:translateY="-158" > - <clip-path - android:name="mask_1" - android:pathData="M 366.5,-269.5 c 0.0,0.0 -578.0,2.0 -578.0,2.0 c 0.0,0.0 480.0,480.0 480.0,480.0 c 0.0,0.0 -20.7500915527,20.75 -20.7500915527,20.75 c 0.0,0.0 -479.999908447,-480.000015259 -479.999908447,-480.000015259 c 0.0,0.0 -7.25,539.250015259 -7.25,539.250015259 c 0.0,0.0 606.0,0.0 606.0,0.0 c 0.0,0.0 0.0,-562.0 0.0,-562.0 Z" /> - <group - android:name="whole" - android:translateX="-1.11523" - android:translateY="32.0918" - android:scaleX="0" - android:scaleY="0" > - <path - android:name="rectangle_path_1" - android:strokeColor="#FFFFFFFF" - android:strokeWidth="65" - android:pathData="M 0.0,-66.5 l 0.0,0.0 c 36.7269358617,0.0 66.5,29.7730641383 66.5,66.5 l 0.0,0.0 c 0.0,36.7269358617 -29.7730641383,66.5 -66.5,66.5 l 0.0,0.0 c -36.7269358617,0.0 -66.5,-29.7730641383 -66.5,-66.5 l 0.0,0.0 c 0.0,-36.7269358617 29.7730641383,-66.5 66.5,-66.5 Z" /> - </group> - <group - android:name="handle" - android:translateY="-100" > - <path - android:name="rectangle_path_2" - android:strokeColor="#FFFFFFFF" - android:strokeWidth="35" - android:pathData="M -34.0,-50.0 l 68.0,0.0 c 8.8365559968,0.0 16.0,7.1634440032 16.0,16.0 l 0.0,68.0 c 0.0,8.8365559968 -7.1634440032,16.0 -16.0,16.0 l -68.0,0.0 c -8.8365559968,0.0 -16.0,-7.1634440032 -16.0,-16.0 l 0.0,-68.0 c 0.0,-8.8365559968 7.1634440032,-16.0 16.0,-16.0 Z" /> - </group> - <group - android:name="case" - android:translateY="32.68518" > - <group - android:name="case_pivot" - android:translateY="-32.68518" > - <group - android:name="bottom" - android:translateY="-97.62964" > - <group - android:name="bottom_pivot" - android:translateY="40" > - <group - android:name="rectangle_path_3_position" - android:translateY="25" > - <path - android:name="rectangle_path_3" - android:fillColor="#FFFFFFFF" - android:pathData="M -143.0,-65.0 l 286.0,0.0 c 17.6731119936,0.0 32.0,14.3268880064 32.0,32.0 l 0.0,66.0 c 0.0,17.6731119936 -14.3268880064,32.0 -32.0,32.0 l -286.0,0.0 c -17.6731119936,0.0 -32.0,-14.3268880064 -32.0,-32.0 l 0.0,-66.0 c 0.0,-17.6731119936 14.3268880064,-32.0 32.0,-32.0 Z" /> - </group> - </group> - </group> - <group - android:name="top" - android:translateY="163" > - <group - android:name="top_pivot" - android:translateY="-40" > - <group - android:name="rectangle_path_4_position" - android:translateY="-25" > - <path - android:name="rectangle_path_4" - android:fillColor="#FFFFFFFF" - android:pathData="M -143.0,-65.0 l 286.0,0.0 c 17.6731119936,0.0 32.0,14.3268880064 32.0,32.0 l 0.0,66.0 c 0.0,17.6731119936 -14.3268880064,32.0 -32.0,32.0 l -286.0,0.0 c -17.6731119936,0.0 -32.0,-14.3268880064 -32.0,-32.0 l 0.0,-66.0 c 0.0,-17.6731119936 14.3268880064,-32.0 32.0,-32.0 Z" /> - </group> - </group> - </group> - <group - android:name="left" - android:translateX="-175.00635" - android:translateY="30" - android:scaleX="1.8" > - <group - android:name="left_pivot" - android:translateX="50.00635" > - <path - android:name="rectangle_path_5" - android:fillColor="#FFFFFFFF" - android:pathData="M -50.0,-88.0 l 100.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,176.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l -100.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,-176.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z" /> - </group> - </group> - <group - android:name="right" - android:translateX="174.97778" - android:translateY="30" - android:scaleX="1.8" > - <group - android:name="right_pivot" - android:translateX="-49.97778" > - <path - android:name="rectangle_path_6" - android:fillColor="#FFFFFFFF" - android:pathData="M -50.0,-88.0 l 100.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,176.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l -100.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,-176.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z" /> - </group> - </group> - </group> - </group> - <group - android:name="stick" - android:translateX="-166.59082" - android:translateY="-156.51367" - android:rotation="-45" > - <group - android:name="stick_pivot" - android:translateX="0.18161" - android:translateY="243.8158" > - <path - android:name="stickito" - android:fillColor="#FFFFFFFF" - android:fillAlpha="1" - android:pathData="M -16.5,-243.999885 l 33.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,487.99977 c 0.0,0.0 0.0,0.0 0.0,0.0 l -33.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,-487.99977 c 0.0,0.0 0.0,0.0 0.0,0.0 Z" /> - </group> - </group> - </group> - </group> -</vector> diff --git a/packages/SystemUI/res/drawable/ic_signal_workmode_enable_animation.xml b/packages/SystemUI/res/drawable/ic_signal_workmode_enable_animation.xml deleted file mode 100644 index c98f800d70c1..000000000000 --- a/packages/SystemUI/res/drawable/ic_signal_workmode_enable_animation.xml +++ /dev/null @@ -1,35 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<animated-vector - xmlns:android="http://schemas.android.com/apk/res/android" - android:drawable="@drawable/ic_signal_workmode_enable" > - <target - android:name="mask_1" - android:animation="@anim/ic_signal_workmode_enable_mask_1_animation" /> - <target - android:name="whole" - android:animation="@anim/ic_signal_workmode_enable_whole_animation" /> - <target - android:name="rectangle_path_3_position" - android:animation="@anim/ic_signal_workmode_enable_rectangle_path_3_position_animation" /> - <target - android:name="rectangle_path_3" - android:animation="@anim/ic_signal_workmode_enable_rectangle_path_3_animation" /> - <target - android:name="rectangle_path_4_position" - android:animation="@anim/ic_signal_workmode_enable_rectangle_path_4_position_animation" /> - <target - android:name="rectangle_path_4" - android:animation="@anim/ic_signal_workmode_enable_rectangle_path_4_animation" /> - <target - android:name="left" - android:animation="@anim/ic_signal_workmode_enable_left_animation" /> - <target - android:name="right" - android:animation="@anim/ic_signal_workmode_enable_right_animation" /> - <target - android:name="stick" - android:animation="@anim/ic_signal_workmode_enable_stick_animation" /> - <target - android:name="ic_signal_workmode_enable" - android:animation="@anim/ic_signal_workmode_enable_stickito_animation" /> -</animated-vector> diff --git a/packages/SystemUI/res/drawable/ic_sim.xml b/packages/SystemUI/res/drawable/ic_sim.xml deleted file mode 100644 index a9a19027a8b1..000000000000 --- a/packages/SystemUI/res/drawable/ic_sim.xml +++ /dev/null @@ -1,42 +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. ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24.0dp" - android:height="24.0dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - <path - android:fillColor="#FF000000" - android:pathData="M18,2h-8L4,8v12c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2V4C20,2.9 19.1,2 18,2zM18,4v16H6V8.83L10.83,4L18,4L18,4z"/> - <path - android:fillColor="#FF000000" - android:pathData="M7,17h2v2h-2z"/> - <path - android:fillColor="#FF000000" - android:pathData="M15,17h2v2h-2z"/> - <path - android:fillColor="#FF000000" - android:pathData="M7,11h2v4h-2z"/> - <path - android:fillColor="#FF000000" - android:pathData="M11,15h2v4h-2z"/> - <path - android:fillColor="#FF000000" - android:pathData="M11,11h2v2h-2z"/> - <path - android:fillColor="#FF000000" - android:pathData="M15,11h2v4h-2z"/> -</vector> diff --git a/packages/SystemUI/res/drawable/ic_speaker.xml b/packages/SystemUI/res/drawable/ic_speaker.xml deleted file mode 100644 index 1ea293c0b690..000000000000 --- a/packages/SystemUI/res/drawable/ic_speaker.xml +++ /dev/null @@ -1,26 +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. - --> - -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0" - android:tint="?android:attr/colorControlNormal" > - <path - android:pathData="M17,2L7,2c-1.1,0 -2,0.9 -2,2v16c0,1.1 0.9,1.99 2,1.99L17,22c1.1,0 2,-0.9 2,-2L19,4c0,-1.1 -0.9,-2 -2,-2zM12,4c1.1,0 2,0.9 2,2s-0.9,2 -2,2c-1.11,0 -2,-0.9 -2,-2s0.89,-2 2,-2zM12,20c-2.76,0 -5,-2.24 -5,-5s2.24,-5 5,-5 5,2.24 5,5 -2.24,5 -5,5zM12,12c-1.66,0 -3,1.34 -3,3s1.34,3 3,3 3,-1.34 3,-3 -1.34,-3 -3,-3z" - android:fillColor="#FFFFFFFF"/> -</vector>
\ No newline at end of file diff --git a/packages/SystemUI/res/drawable/ic_speaker_group.xml b/packages/SystemUI/res/drawable/ic_speaker_group.xml deleted file mode 100644 index d6867d7265b0..000000000000 --- a/packages/SystemUI/res/drawable/ic_speaker_group.xml +++ /dev/null @@ -1,32 +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. - --> - -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0" - android:tint="?android:attr/colorControlNormal" > - <path - android:pathData="M18.2,1L9.8,1C8.81,1 8,1.81 8,2.8v14.4c0,0.99 0.81,1.79 1.8,1.79l8.4,0.01c0.99,0 1.8,-0.81 1.8,-1.8L20,2.8c0,-0.99 -0.81,-1.8 -1.8,-1.8zM14,3c1.1,0 2,0.89 2,2s-0.9,2 -2,2 -2,-0.89 -2,-2 0.9,-2 2,-2zM14,16.5c-2.21,0 -4,-1.79 -4,-4s1.79,-4 4,-4 4,1.79 4,4 -1.79,4 -4,4z" - android:fillColor="#FFFFFFFF"/> - <path - android:pathData="M14,12.5m-2.5,0a2.5,2.5 0,1 1,5 0a2.5,2.5 0,1 1,-5 0" - android:fillColor="#FFFFFFFF"/> - <path - android:pathData="M6,5H4v16c0,1.1 0.89,2 2,2h10v-2H6V5z" - android:fillColor="#FFFFFFFF"/> -</vector>
\ No newline at end of file diff --git a/packages/SystemUI/res/drawable/ic_swap.xml b/packages/SystemUI/res/drawable/ic_swap.xml deleted file mode 100644 index 30da2a9f532f..000000000000 --- a/packages/SystemUI/res/drawable/ic_swap.xml +++ /dev/null @@ -1,25 +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. ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0" - android:tint="?android:attr/colorForeground"> - <path - android:pathData="M6.99,11L3,15l3.99,4v-3H14v-2H6.99v-3zM21,9l-3.99,-4v3H10v2h7.01v3L21,9z" - android:fillColor="#FFFFFF"/> -</vector>
\ No newline at end of file diff --git a/packages/SystemUI/res/drawable/ic_tv.xml b/packages/SystemUI/res/drawable/ic_tv.xml deleted file mode 100644 index cc2ae910ae88..000000000000 --- a/packages/SystemUI/res/drawable/ic_tv.xml +++ /dev/null @@ -1,26 +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. - --> - -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0" - android:tint="?android:attr/colorControlNormal" > - <path - android:pathData="M21,3L3,3c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h5v2h8v-2h5c1.1,0 1.99,-0.9 1.99,-2L23,5c0,-1.1 -0.9,-2 -2,-2zM21,17L3,17L3,5h18v12z" - android:fillColor="#FFFFFFFF"/> -</vector>
\ No newline at end of file diff --git a/packages/SystemUI/res/drawable/ic_zen_all.xml b/packages/SystemUI/res/drawable/ic_zen_all.xml deleted file mode 100644 index 5df2447b9bb2..000000000000 --- a/packages/SystemUI/res/drawable/ic_zen_all.xml +++ /dev/null @@ -1,24 +0,0 @@ -<!-- -Copyright (C) 2014 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="18dp" - android:height="18dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - <path - android:fillColor="#FFFFFFFF" - android:pathData="M6.6,3.6L5.2,2.2C2.8,4.0 1.2,6.8 1.0,10.0l2.0,0.0C3.2,7.3 4.5,5.0 6.6,3.6zM20.0,10.0l2.0,0.0c-0.2,-3.2 -1.7,-6.0 -4.1,-7.8l-1.4,1.4C18.5,5.0 19.8,7.3 20.0,10.0zM18.0,10.5c0.0,-3.1 -2.1,-5.6 -5.0,-6.3L13.0,3.5C13.0,2.7 12.3,2.0 11.5,2.0C10.7,2.0 10.0,2.7 10.0,3.5l0.0,0.7c-2.9,0.7 -5.0,3.2 -5.0,6.3L5.0,16.0l-2.0,2.0l0.0,1.0l17.0,0.0l0.0,-1.0l-2.0,-2.0L18.0,10.5zM11.5,22.0c0.1,0.0 0.3,0.0 0.4,0.0c0.7,-0.1 1.2,-0.6 1.4,-1.2c0.1,-0.2 0.2,-0.5 0.2,-0.8l-4.0,0.0C9.5,21.1 10.4,22.0 11.5,22.0z"/> -</vector> diff --git a/packages/SystemUI/res/drawable/ic_zen_important.xml b/packages/SystemUI/res/drawable/ic_zen_important.xml deleted file mode 100644 index c2a59b85bf4a..000000000000 --- a/packages/SystemUI/res/drawable/ic_zen_important.xml +++ /dev/null @@ -1,25 +0,0 @@ -<!-- -Copyright (C) 2014 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="18dp" - android:height="18dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - - <path - android:fillColor="#FFFFFFFF" - android:pathData="M12.0,17.273l6.1800003,3.7269993 -1.6350002,-7.0290003 5.455,-4.7269993 -7.191,-0.6170006 -2.809,-6.627 -2.809,6.627 -7.191,0.6170006 5.455,4.7269993 -1.6349998,7.0290003z"/> -</vector>
\ No newline at end of file diff --git a/packages/SystemUI/res/drawable/ic_zen_none.xml b/packages/SystemUI/res/drawable/ic_zen_none.xml deleted file mode 100644 index 99014f24e53f..000000000000 --- a/packages/SystemUI/res/drawable/ic_zen_none.xml +++ /dev/null @@ -1,25 +0,0 @@ -<!-- -Copyright (C) 2014 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="18dp" - android:height="18dp" - android:viewportWidth="48.0" - android:viewportHeight="48.0"> - - <path - android:fillColor="#FFFFFFFF" - android:pathData="M24.0,4.0C13.0,4.0 4.0,13.0 4.0,24.0c0.0,11.0 9.0,20.0 20.0,20.0c11.0,0.0 20.0,-9.0 20.0,-20.0C44.0,13.0 35.0,4.0 24.0,4.0zM24.0,40.0c-8.8,0.0 -16.0,-7.2 -16.0,-16.0c0.0,-3.7 1.3,-7.1 3.4,-9.8l22.4,22.4C31.1,38.7 27.7,40.0 24.0,40.0zM36.6,33.8L14.2,11.4C16.9,9.3 20.3,8.0 24.0,8.0c8.8,0.0 16.0,7.2 16.0,16.0C40.0,27.7 38.7,31.1 36.6,33.8z"/> -</vector>
\ No newline at end of file diff --git a/packages/SystemUI/res/drawable/keyguard_overflow_number_background.xml b/packages/SystemUI/res/drawable/keyguard_overflow_number_background.xml deleted file mode 100644 index b812d43b3b87..000000000000 --- a/packages/SystemUI/res/drawable/keyguard_overflow_number_background.xml +++ /dev/null @@ -1,21 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - ~ Copyright (C) 2014 The Android Open Source Project - ~ - ~ Licensed under the Apache License, Version 2.0 (the "License"); - ~ you may not use this 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 - --> - -<shape xmlns:android="http://schemas.android.com/apk/res/android" - android:shape="oval"> - <solid android:color="#1a000000" /> -</shape>
\ No newline at end of file diff --git a/packages/SystemUI/res/drawable/notification_expand_more.xml b/packages/SystemUI/res/drawable/notification_expand_more.xml deleted file mode 100644 index 430fb0dd523d..000000000000 --- a/packages/SystemUI/res/drawable/notification_expand_more.xml +++ /dev/null @@ -1,25 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -Copyright (C) 2015 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License._more ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="22.0dp" - android:height="22.0dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - <path - android:pathData="M16.600000,8.600000l-4.600000,4.599999 -4.600000,-4.599999 -1.400000,1.400000 6.000000,6.000000 6.000000,-6.000000z" - android:fillColor="#FF000000"/> -</vector> diff --git a/packages/SystemUI/res/drawable/pip_dismiss.xml b/packages/SystemUI/res/drawable/pip_dismiss.xml deleted file mode 100644 index f656eeb2e5ee..000000000000 --- a/packages/SystemUI/res/drawable/pip_dismiss.xml +++ /dev/null @@ -1,24 +0,0 @@ -<!-- -Copyright (C) 2016 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="42.0dp" - android:height="42.0dp" - android:viewportWidth="48.0" - android:viewportHeight="48.0"> - <path - android:fillColor="#FFFFFFFF" - android:pathData="M38.000000,12.800000l-2.799999,-2.800000 -11.200001,11.200001 -11.200000,-11.200001 -2.800000,2.800000 11.200001,11.200000 -11.200001,11.200001 2.800000,2.799999 11.200000,-11.200001 11.200001,11.200001 2.799999,-2.799999 -11.200001,-11.200001z"/> -</vector>
\ No newline at end of file diff --git a/packages/SystemUI/res/drawable/pip_notification_icon.xml b/packages/SystemUI/res/drawable/pip_notification_icon.xml deleted file mode 100644 index 592bc60d553e..000000000000 --- a/packages/SystemUI/res/drawable/pip_notification_icon.xml +++ /dev/null @@ -1,25 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -Copyright (C) 2017 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - <path - android:fillColor="#FF000000" - android:pathData="M11.99,18.54l-7.37,-5.73L3,14.07l9,7 9,-7 -1.63,-1.27 -7.38,5.74zM12,16l7.36,-5.73L21,9l-9,-7 -9,7 1.63,1.27L12,16z"/> -</vector>
\ No newline at end of file diff --git a/packages/SystemUI/res/drawable/pop_ball.xml b/packages/SystemUI/res/drawable/pop_ball.xml deleted file mode 100644 index ee1220f42140..000000000000 --- a/packages/SystemUI/res/drawable/pop_ball.xml +++ /dev/null @@ -1,29 +0,0 @@ -<!-- -Copyright (C) 2014 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="100.0dp" - android:height="100.0dp" - android:viewportWidth="100.0" - android:viewportHeight="100.0"> - <path - android:pathData="M0,50 a50,50 0 1 1 100,0 - a50,50 0 1 1 -100,0" - android:fillColor="#FFFF1744"/> - <path - android:pathData="M16,36 A24,24 0 1 1 64,36 - M64,36 A24,24 0 1 1 16,36" - android:fillColor="#20FFFFFF"/> -</vector> diff --git a/packages/SystemUI/res/drawable/pop_belt.xml b/packages/SystemUI/res/drawable/pop_belt.xml deleted file mode 100644 index e0ea57527d2a..000000000000 --- a/packages/SystemUI/res/drawable/pop_belt.xml +++ /dev/null @@ -1,33 +0,0 @@ -<!-- -Copyright (C) 2014 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="100.0dp" - android:height="100.0dp" - android:viewportWidth="100.0" - android:viewportHeight="100.0"> - <path - android:pathData="M50.000000,50.000000m-47.599998,0.000000a47.599998,47.599998 0.000000,1.000000 1.000000,95.199997 0.000000a47.599998,47.599998 0.000000,1.000000 1.000000,-95.199997 0.000000" - android:fillColor="#9C27B0"/> - <path - android:pathData="M50.000000,2.429000c-26.337999,0.000000 -47.688999,21.351000 -47.688999,47.688999c0.000000,13.168000 5.337000,25.091000 13.968000,33.722000l67.444000,-67.443001C75.092003,7.766000 63.168999,2.429000 50.000000,2.429000z" - android:fillColor="#BA68C8"/> - <path - android:pathData="M0.000000,41.573002l100.000000,0.000000l0.000000,17.090000l-100.000000,0.000000z" - android:fillColor="#9C27B0"/> - <path - android:pathData="M0.000000,58.662998l0.000000,-17.089996 100.000000,0.000000z" - android:fillColor="#BA68C8"/> -</vector> diff --git a/packages/SystemUI/res/drawable/pop_droid.xml b/packages/SystemUI/res/drawable/pop_droid.xml deleted file mode 100644 index eed325c6541c..000000000000 --- a/packages/SystemUI/res/drawable/pop_droid.xml +++ /dev/null @@ -1,33 +0,0 @@ -<!-- -Copyright (C) 2014 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="100.0dp" - android:height="100.0dp" - android:viewportWidth="100.0" - android:viewportHeight="100.0"> - <path - android:pathData="M50.000000,50.000000m-50.000000,0.000000a50.000000,50.000000 0.000000,1.000000 1.000000,100.000000 0.000000a50.000000,50.000000 0.000000,1.000000 1.000000,-100.000000 0.000000" - android:fillColor="#9E9D24"/> - <path - android:pathData="M30.775999,24.528000m-4.209000,0.000000a4.209000,4.209000 0.000000,1.000000 1.000000,8.418000 0.000000a4.209000,4.209000 0.000000,1.000000 1.000000,-8.418000 0.000000" - android:fillColor="#FFFFFF"/> - <path - android:pathData="M69.226997,24.528000m-4.210000,0.000000a4.210000,4.210000 0.000000,1.000000 1.000000,8.420000 0.000000a4.210000,4.210000 0.000000,1.000000 1.000000,-8.420000 0.000000" - android:fillColor="#FFFFFF"/> - <path - android:pathData="M85.352997,14.648000C65.829002,-4.877000 34.168999,-4.877000 14.646000,14.646000C4.882000,24.410000 0.002000,37.207001 0.000000,50.000999l99.996002,0.002000C99.996002,37.207001 95.115997,24.410000 85.352997,14.648000z" - android:fillColor="#C0CA33"/> -</vector> diff --git a/packages/SystemUI/res/drawable/pop_pizza.xml b/packages/SystemUI/res/drawable/pop_pizza.xml deleted file mode 100644 index 1806b5a17cec..000000000000 --- a/packages/SystemUI/res/drawable/pop_pizza.xml +++ /dev/null @@ -1,45 +0,0 @@ -<!-- -Copyright (C) 2014 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="100.0dp" - android:height="100.0dp" - android:viewportWidth="100.0" - android:viewportHeight="100.0"> - <path - android:pathData="M14.645000,14.645000C5.597000,23.693001 0.000000,36.193001 0.000000,50.000000l50.000000,0.000000L14.645000,14.645000z" - android:fillColor="#2979FF"/> - <path - android:pathData="M100.000000,50.000000c0.000000,-13.807000 -5.597000,-26.306999 -14.645000,-35.355000L50.000000,50.000000L100.000000,50.000000z" - android:fillColor="#FF1744"/> - <path - android:pathData="M85.355003,14.645000C76.306999,5.597000 63.806999,0.000000 50.000000,0.000000l0.000000,50.000000L85.355003,14.645000z" - android:fillColor="#0F9D58"/> - <path - android:pathData="M50.000000,0.000000C36.193001,0.000000 23.693001,5.597000 14.645000,14.645000L50.000000,50.000000L50.000000,0.000000z" - android:fillColor="#FFBC00"/> - <path - android:pathData="M50.000000,50.000000l35.355000,35.355000C94.403000,76.307999 100.000000,63.807999 100.000000,50.000000L50.000000,50.000000z" - android:fillColor="#2979FF"/> - <path - android:pathData="M50.000000,100.000000c13.807000,0.000000 26.306999,-5.596000 35.355000,-14.645000L50.000000,50.000000L50.000000,100.000000z" - android:fillColor="#FFBC00"/> - <path - android:pathData="M14.645000,85.355003C23.693001,94.403999 36.193001,100.000000 50.000000,100.000000L50.000000,50.000000L14.645000,85.355003z" - android:fillColor="#0F9D58"/> - <path - android:pathData="M0.000000,50.000000c0.000000,13.808000 5.597000,26.308001 14.645000,35.355000L50.000000,50.000000L0.000000,50.000000z" - android:fillColor="#FF1744"/> -</vector> diff --git a/packages/SystemUI/res/drawable/pop_stripes.xml b/packages/SystemUI/res/drawable/pop_stripes.xml deleted file mode 100644 index ef6c8e88e2bf..000000000000 --- a/packages/SystemUI/res/drawable/pop_stripes.xml +++ /dev/null @@ -1,36 +0,0 @@ -<!-- -Copyright (C) 2014 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="100.0dp" - android:height="100.0dp" - android:viewportWidth="100.0" - android:viewportHeight="100.0"> - <path - android:pathData="M50.000000,50.000000m-50.000000,0.000000a50.000000,50.000000 0.000000,1.000000 1.000000,100.000000 0.000000a50.000000,50.000000 0.000000,1.000000 1.000000,-100.000000 0.000000" - android:fillColor="#F57C00"/> - <path - android:pathData="M50.000999,100.000000c14.136000,0.000000 26.893000,-5.876000 35.987000,-15.308000L14.013000,84.692001C23.106001,94.124001 35.862999,100.000000 50.000999,100.000000z" - android:fillColor="#E65100"/> - <path - android:pathData="M50.000999,0.000000C35.862999,0.000000 23.106001,5.876000 14.013000,15.308000l71.974998,0.000000C76.893997,5.876000 64.137001,0.000000 50.000999,0.000000z" - android:fillColor="#FFA726"/> - <path - android:pathData="M96.501999,31.631001c-2.423000,-6.127000 -6.020000,-11.660000 -10.514000,-16.323000L14.013000,15.308001C9.517000,19.971001 5.922000,25.503000 3.499000,31.631001L96.501999,31.631001z" - android:fillColor="#FB8C00"/> - <path - android:pathData="M3.499000,68.370003c2.423000,6.128000 6.018000,11.658000 10.514000,16.322001l71.974998,0.000000c4.494000,-4.664000 8.091000,-10.194000 10.514000,-16.322001L3.499000,68.370003z" - android:fillColor="#EF6C00"/> -</vector> diff --git a/packages/SystemUI/res/drawable/pop_swirl.xml b/packages/SystemUI/res/drawable/pop_swirl.xml deleted file mode 100644 index f87569b4a5f8..000000000000 --- a/packages/SystemUI/res/drawable/pop_swirl.xml +++ /dev/null @@ -1,57 +0,0 @@ -<!-- -Copyright (C) 2014 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="100.0dp" - android:height="100.0dp" - android:viewportWidth="100.0" - android:viewportHeight="100.0"> - <path - android:pathData="M50.000000,50.000000C86.898003,27.834999 79.244003,11.688000 76.177002,7.399000c-7.240000,-4.459000 -15.703000,-7.112000 -24.770000,-7.363000C56.247002,2.253000 70.815002,12.456000 50.000000,50.000000z" - android:fillColor="#FFFFFA"/> - <path - android:pathData="M50.000000,50.000000c20.815001,-37.543999 6.247000,-47.747002 1.407000,-49.964001C50.938000,0.022000 50.472000,0.000000 50.000000,0.000000c-8.627000,0.000000 -16.743999,2.186000 -23.827000,6.032000C31.392000,5.514000 49.251999,6.903000 50.000000,50.000000z" - android:fillColor="#76FF03"/> - <path - android:pathData="M50.000000,50.000000c37.543999,20.816000 47.747002,6.248000 49.965000,1.408000C99.977997,50.938000 100.000000,50.473000 100.000000,50.000000c0.000000,-8.627000 -2.186000,-16.743999 -6.032000,-23.827000C94.486000,31.393000 93.098000,49.251999 50.000000,50.000000z" - android:fillColor="#76FF03"/> - <path - android:pathData="M50.000000,50.000000c43.098000,-0.748000 44.486000,-18.607000 43.967999,-23.827000c-4.186000,-7.708000 -10.344000,-14.188000 -17.791000,-18.773001C79.244003,11.688000 86.898003,27.834999 50.000000,50.000000z" - android:fillColor="#303F9F"/> - <path - android:pathData="M50.000000,50.000000C27.834000,13.103000 11.687000,20.757000 7.398000,23.823999C2.940000,31.063000 0.287000,39.527000 0.035000,48.592999C2.253000,43.752998 12.456000,29.184999 50.000000,50.000000z" - android:fillColor="#FFFFFA"/> - <path - android:pathData="M50.000000,50.000000C49.251999,6.903000 31.392000,5.514000 26.173000,6.032000c-7.709000,4.187000 -14.188000,10.344000 -18.774000,17.792000C11.687000,20.757000 27.834000,13.103000 50.000000,50.000000z" - android:fillColor="#303F9F"/> - <path - android:pathData="M50.000000,50.000000C12.456000,29.184999 2.253000,43.752998 0.035000,48.592999C0.022000,49.062000 0.000000,49.528000 0.000000,50.000000c0.000000,8.628000 2.186000,16.743999 6.032000,23.827999C5.514000,68.609001 6.902000,50.749001 50.000000,50.000000z" - android:fillColor="#76FF03"/> - <path - android:pathData="M50.000000,50.000000c0.748000,43.098000 18.608000,44.486000 23.827000,43.969002c7.709000,-4.187000 14.188000,-10.344000 18.774000,-17.791000C88.313004,79.244003 72.166000,86.898003 50.000000,50.000000z" - android:fillColor="#303F9F"/> - <path - android:pathData="M50.000000,50.000000c22.166000,36.897999 38.313000,29.243999 42.602001,26.177999c4.458000,-7.240000 7.111000,-15.703000 7.363000,-24.770000C97.747002,56.248001 87.543999,70.816002 50.000000,50.000000z" - android:fillColor="#FFFFFA"/> - <path - android:pathData="M50.000000,50.000000c-20.815001,37.544998 -6.247000,47.748001 -1.407000,49.965000C49.062000,99.978996 49.528000,100.000000 50.000000,100.000000c8.627000,0.000000 16.743999,-2.185000 23.827000,-6.031000C68.608002,94.486000 50.748001,93.098000 50.000000,50.000000z" - android:fillColor="#76FF03"/> - <path - android:pathData="M50.000000,50.000000C13.103000,72.166000 20.757000,88.313004 23.823000,92.601997c7.240000,4.459000 15.703000,7.112000 24.770000,7.363000C43.752998,97.748001 29.184999,87.544998 50.000000,50.000000z" - android:fillColor="#FFFFFA"/> - <path - android:pathData="M50.000000,50.000000C6.902000,50.749001 5.514000,68.609001 6.032000,73.828003c4.186000,7.708000 10.344000,14.188000 17.791000,18.773001C20.757000,88.313004 13.103000,72.166000 50.000000,50.000000z" - android:fillColor="#303F9F"/> -</vector> diff --git a/packages/SystemUI/res/drawable/pop_vortex.xml b/packages/SystemUI/res/drawable/pop_vortex.xml deleted file mode 100644 index 2380e68c4c16..000000000000 --- a/packages/SystemUI/res/drawable/pop_vortex.xml +++ /dev/null @@ -1,27 +0,0 @@ -<!-- -Copyright (C) 2014 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="100.0dp" - android:height="100.0dp" - android:viewportWidth="100.0" - android:viewportHeight="100.0"> - <path - android:pathData="M50.000000,50.000000m-50.000000,0.000000a50.000000,50.000000 0.000000,1.000000 1.000000,100.000000 0.000000a50.000000,50.000000 0.000000,1.000000 1.000000,-100.000000 0.000000" - android:fillColor="#F8F8FF"/> - <path - android:pathData="M58.658001,89.648003c-19.330000,0.000000 -35.000000,-15.670000 -35.000000,-35.000000c0.000000,-13.531000 10.969000,-24.500000 24.500000,-24.500000c9.472000,0.000000 17.150000,7.679000 17.150000,17.150000c0.000000,6.631000 -5.375000,12.006000 -12.006000,12.006000c-3.798000,0.000000 -7.004000,-2.522000 -8.045000,-5.982000c1.021000,1.136000 2.497000,1.854000 4.145000,1.854000c2.644000,0.000000 4.853000,-1.841000 5.428000,-4.310000c0.175000,-0.558000 0.271000,-1.150000 0.271000,-1.766000c0.000000,-4.642000 -3.763000,-8.404000 -8.403000,-8.404000c-6.631000,0.000000 -12.006000,5.375000 -12.006000,12.006000c0.000000,9.472000 7.679000,17.149000 17.150000,17.149000c13.531000,0.000000 24.500000,-10.969000 24.500000,-24.500000c0.000000,-19.330000 -15.670000,-35.000000 -35.000000,-35.000000c-12.963000,0.000000 -24.773001,4.935000 -33.657001,13.025000C2.824000,31.087000 0.000000,40.212002 0.000000,50.000000c0.000000,27.615000 22.386000,50.000000 50.000000,50.000000c17.825001,0.000000 33.462002,-9.335000 42.313999,-23.375999C83.431000,84.714996 71.621002,89.648003 58.658001,89.648003z" - android:fillColor="#7BAAF7"/> -</vector> diff --git a/packages/SystemUI/res/drawable/pop_vortex2.xml b/packages/SystemUI/res/drawable/pop_vortex2.xml deleted file mode 100644 index 0a96b74cf476..000000000000 --- a/packages/SystemUI/res/drawable/pop_vortex2.xml +++ /dev/null @@ -1,27 +0,0 @@ -<!-- -Copyright (C) 2014 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="100.0dp" - android:height="100.0dp" - android:viewportWidth="100.0" - android:viewportHeight="100.0"> - <path - android:pathData="M50.000000,50.000000m-50.000000,0.000000a50.000000,50.000000 0.000000,1.000000 1.000000,100.000000 0.000000a50.000000,50.000000 0.000000,1.000000 1.000000,-100.000000 0.000000" - android:fillColor="#D81B60"/> - <path - android:pathData="M21.250000,78.369003c-13.200000,-16.000000 -10.930000,-39.671001 5.070000,-52.870998c12.799000,-10.560000 31.737000,-8.743000 42.294998,4.057000c8.448000,10.239000 6.996000,25.389000 -3.244000,33.837002c-8.191000,6.759000 -20.311001,5.596000 -27.068001,-2.596000c-5.408000,-6.554000 -4.478000,-16.249001 2.076000,-21.656000c5.242000,-4.325000 12.998000,-3.581000 17.323999,1.661000c3.460000,4.194000 2.865000,10.399000 -1.330000,13.859000c-3.354000,2.769000 -8.318000,2.293000 -11.087000,-1.062000c-2.214000,-2.685000 -1.833000,-6.655000 0.851000,-8.870000c2.147000,-1.771000 5.324000,-1.468000 7.096000,0.681000c1.393000,1.688000 1.174000,4.165000 -0.464000,5.596000c0.409000,-0.564000 0.657000,-1.253000 0.657000,-2.004000c0.000000,-1.021000 -0.455000,-1.928000 -1.165000,-2.556000c-0.067000,-0.112000 -0.134000,-0.226000 -0.220000,-0.329000c-1.135000,-1.373000 -3.168000,-1.568000 -4.542000,-0.435000c-1.719000,1.417000 -1.962000,3.958000 -0.544000,5.677000c1.771000,2.146000 4.949000,2.451000 7.096000,0.680000c2.684000,-2.215000 3.064000,-6.186000 0.851000,-8.870000c-2.769000,-3.356000 -7.732000,-3.831000 -11.087000,-1.063000c-4.195000,3.460000 -4.790000,9.665000 -1.330000,13.859000c4.326000,5.244000 12.082000,5.987000 17.323999,1.662000c6.554000,-5.407000 7.484000,-15.102000 2.076000,-21.656000c-6.758000,-8.191000 -18.875999,-9.354000 -27.069000,-2.596000c-10.239000,8.448000 -11.691000,23.598000 -3.244000,33.837002c10.560000,12.800000 29.497000,14.616000 42.296001,4.056000c16.000000,-13.199000 18.270000,-36.869999 5.070000,-52.868999C68.397003,5.620000 52.516998,-0.139000 37.205002,1.659000c-8.665000,2.287000 -16.410999,6.836000 -22.561001,12.985000C5.597000,23.693001 0.000000,36.193001 0.000000,50.000000c0.000000,13.808000 5.597000,26.308001 14.645000,35.355000C23.693001,94.403999 36.193001,100.000000 50.000000,100.000000c11.935000,0.000000 22.886999,-4.187000 31.482000,-11.164000C61.909000,100.523003 36.202999,96.495003 21.250000,78.369003z" - android:fillColor="#F06292"/> -</vector> diff --git a/packages/SystemUI/res/drawable/qs_subhead_caret.xml b/packages/SystemUI/res/drawable/qs_subhead_caret.xml deleted file mode 100644 index 13a168d758aa..000000000000 --- a/packages/SystemUI/res/drawable/qs_subhead_caret.xml +++ /dev/null @@ -1,25 +0,0 @@ -<!-- -Copyright (C) 2014 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24.0dp" - android:height="24.0dp" - android:viewportWidth="48.0" - android:viewportHeight="48.0"> - - <path - android:fillColor="@color/qs_subhead" - android:pathData="M14.0,20.0l10.0,10.0 10.0,-10.0z"/> -</vector> diff --git a/packages/SystemUI/res/drawable/qs_tile_background.xml b/packages/SystemUI/res/drawable/qs_tile_background.xml deleted file mode 100644 index 96891c14bd33..000000000000 --- a/packages/SystemUI/res/drawable/qs_tile_background.xml +++ /dev/null @@ -1,26 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -/* -** Copyright 2012, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-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. -*/ ---> -<selector xmlns:android="http://schemas.android.com/apk/res/android"> - <item android:state_pressed="true"> - <color android:color="#212121" /> - </item> - <item> - <color android:color="#161616" /> - </item> -</selector> diff --git a/packages/SystemUI/res/drawable/quick_header_bg.xml b/packages/SystemUI/res/drawable/quick_header_bg.xml deleted file mode 100644 index 920e6f5ef086..000000000000 --- a/packages/SystemUI/res/drawable/quick_header_bg.xml +++ /dev/null @@ -1,21 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - ~ Copyright (C) 2015 The Android Open Source Project - ~ - ~ Licensed under the Apache License, Version 2.0 (the "License"); - ~ you may not use this file except in compliance with the License. - ~ You may obtain a copy of the License at - ~ - ~ http://www.apache.org/licenses/LICENSE-2.0 - ~ - ~ Unless required by applicable law or agreed to in writing, software - ~ distributed under the License is distributed on an "AS IS" BASIS, - ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - ~ See the License for the specific language governing permissions and - ~ limitations under the License - --> - -<ripple xmlns:android="http://schemas.android.com/apk/res/android" - android:color="?android:attr/colorControlHighlight" > - <item android:drawable="?android:attr/colorPrimary"/> -</ripple> diff --git a/packages/SystemUI/res/drawable/scorecard_gameover.xml b/packages/SystemUI/res/drawable/scorecard_gameover.xml deleted file mode 100644 index f663a661f3f1..000000000000 --- a/packages/SystemUI/res/drawable/scorecard_gameover.xml +++ /dev/null @@ -1,10 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<shape - xmlns:android="http://schemas.android.com/apk/res/android" - android:shape="rectangle" - > - <corners - android:radius="8dp" /> - <solid - android:color="#ffff0000" /> -</shape> diff --git a/packages/SystemUI/res/drawable/stat_notify_more.xml b/packages/SystemUI/res/drawable/stat_notify_more.xml deleted file mode 100644 index 50f12861afe8..000000000000 --- a/packages/SystemUI/res/drawable/stat_notify_more.xml +++ /dev/null @@ -1,24 +0,0 @@ -<!-- - ~ Copyright (C) 2014 The Android Open Source Project - ~ - ~ Licensed under the Apache License, Version 2.0 (the "License"); - ~ you may not use this file except in compliance with the License. - ~ You may obtain a copy of the License at - ~ - ~ http://www.apache.org/licenses/LICENSE-2.0 - ~ - ~ Unless required by applicable law or agreed to in writing, software - ~ distributed under the License is distributed on an "AS IS" BASIS, - ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - ~ See the License for the specific language governing permissions and - ~ limitations under the License - --> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="16dp" - android:height="16dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - <path - android:pathData="M22.000000,3.000000L7.000000,3.000000C6.300000,3.000000 5.800000,3.400000 5.400000,3.900000L0.000000,12.000000l5.400000,8.100000c0.400000,0.500000 1.000000,0.900000 1.700000,0.900000L22.000000,21.000000c1.100000,0.000000 2.000000,-0.900000 2.000000,-2.000000L24.000000,5.000000C24.000000,3.900000 23.100000,3.000000 22.000000,3.000000zM9.000000,13.500000c-0.800000,0.000000 -1.500000,-0.700000 -1.500000,-1.500000s0.700000,-1.500000 1.500000,-1.500000c0.800000,0.000000 1.500000,0.700000 1.500000,1.500000S9.800000,13.500000 9.000000,13.500000zM14.000000,13.500000c-0.800000,0.000000 -1.500000,-0.700000 -1.500000,-1.500000s0.700000,-1.500000 1.500000,-1.500000c0.800000,0.000000 1.500000,0.700000 1.500000,1.500000S14.800000,13.500000 14.000000,13.500000zM19.000000,13.500000c-0.800000,0.000000 -1.500000,-0.700000 -1.500000,-1.500000s0.700000,-1.500000 1.500000,-1.500000c0.800000,0.000000 1.500000,0.700000 1.500000,1.500000S19.799999,13.500000 19.000000,13.500000z" - android:fillColor="#FFFFFFFF"/> -</vector> diff --git a/packages/SystemUI/res/drawable/stat_sys_auto_rotate_landscape.xml b/packages/SystemUI/res/drawable/stat_sys_auto_rotate_landscape.xml deleted file mode 100644 index ba0709e9aa0e..000000000000 --- a/packages/SystemUI/res/drawable/stat_sys_auto_rotate_landscape.xml +++ /dev/null @@ -1,66 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - Copyright (C) 2016 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<inset xmlns:android="http://schemas.android.com/apk/res/android" - android:insetLeft="2.5dp" - android:insetRight="2.5dp"> - <vector - android:height="17dp" - android:width="17dp" - android:viewportHeight="48" - android:viewportWidth="48" > - <group - android:name="ic_screen_rotation_48px_outlines" - android:translateX="24" - android:translateY="24" > - <group - android:name="ic_screen_rotation_48px_outlines_pivot" - android:translateX="-24.15" - android:translateY="-24.25" > - <group - android:name="arrows" - android:translateX="24.1" - android:translateY="24.1" > - <group - android:name="arrows_pivot" - android:translateX="-24.1" - android:translateY="-24.1" > - <path - android:name="arrow_top" - android:pathData="M 33.1499938965,5.25 c 6.5,3.10000610352 11.1999969482,9.40000915527 11.8999938965,17.0 c 0.0,0.0 3.00001525879,0.0 3.00001525879,0.0 c -1.00001525879,-12.3000030518 -11.3000030518,-22.0 -23.9000091553,-22.0 c -0.399993896484,0.0 -0.899993896484,0.0 -1.30000305176,0.100006103516 c 0.0,0.0 7.60000610352,7.59999084473 7.60000610352,7.59999084473 c 0.0,0.0 2.69999694824,-2.69999694824 2.69999694824,-2.69999694824 Z" - android:fillColor="#FFFFFFFF" - android:fillAlpha="1" /> - <path - android:name="arrow_bottom" - android:pathData="M 15.1499938965,43.25 c -6.5,-3.09999084473 -11.1999969482,-9.5 -11.8999938965,-17.0 c 0.0,0.0 -3.0,0.0 -3.0,0.0 c 1.0,12.3000030518 11.299987793,22.0 23.8999938965,22.0 c 0.399993896484,0.0 0.899993896484,0.0 1.30000305176,-0.0999908447266 c 0.0,0.0 -7.60000610352,-7.60000610352 -7.60000610352,-7.60000610352 c 0.0,0.0 -2.69999694824,2.69999694824 -2.69999694824,2.69999694824 Z" - android:fillColor="#FFFFFFFF" - android:fillAlpha="1" /> - </group> - </group> - <group - android:name="device" - android:translateX="24.14999" - android:translateY="24.25" > - <path - android:name="body" - android:pathData="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z" - android:fillColor="#FFFFFFFF" - android:fillAlpha="1" /> - </group> - </group> - </group> - </vector> -</inset> diff --git a/packages/SystemUI/res/drawable/stat_sys_auto_rotate_portrait.xml b/packages/SystemUI/res/drawable/stat_sys_auto_rotate_portrait.xml deleted file mode 100644 index 46a1f3575f86..000000000000 --- a/packages/SystemUI/res/drawable/stat_sys_auto_rotate_portrait.xml +++ /dev/null @@ -1,66 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - Copyright (C) 2016 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<inset xmlns:android="http://schemas.android.com/apk/res/android" - android:insetLeft="2.5dp" - android:insetRight="2.5dp"> - <vector - android:height="17dp" - android:width="17dp" - android:viewportHeight="48" - android:viewportWidth="48" > - <group - android:name="icon" - android:translateX="24" - android:translateY="24" > - <group - android:name="icon_pivot" - android:translateX="-24.15" - android:translateY="-24.25" > - <group - android:name="arrows" - android:translateX="24.1" - android:translateY="24.1" > - <group - android:name="arrows_pivot" - android:translateX="-24.1" - android:translateY="-24.1" > - <path - android:name="arrow_top" - android:pathData="M 33.1499938965,5.25 c 6.5,3.10000610352 11.1999969482,9.40000915527 11.8999938965,17.0 c 0.0,0.0 3.00001525879,0.0 3.00001525879,0.0 c -1.00001525879,-12.3000030518 -11.3000030518,-22.0 -23.9000091553,-22.0 c -0.399993896484,0.0 -0.899993896484,0.0 -1.30000305176,0.100006103516 c 0.0,0.0 7.60000610352,7.59999084473 7.60000610352,7.59999084473 c 0.0,0.0 2.69999694824,-2.69999694824 2.69999694824,-2.69999694824 Z" - android:fillColor="#FFFFFFFF" - android:fillAlpha="1" /> - <path - android:name="arrow_bottom" - android:pathData="M 15.1499938965,43.25 c -6.5,-3.09999084473 -11.1999969482,-9.5 -11.8999938965,-17.0 c 0.0,0.0 -3.0,0.0 -3.0,0.0 c 1.0,12.3000030518 11.299987793,22.0 23.8999938965,22.0 c 0.399993896484,0.0 0.899993896484,0.0 1.30000305176,-0.0999908447266 c 0.0,0.0 -7.60000610352,-7.60000610352 -7.60000610352,-7.60000610352 c 0.0,0.0 -2.69999694824,2.69999694824 -2.69999694824,2.69999694824 Z" - android:fillColor="#FFFFFFFF" - android:fillAlpha="1" /> - </group> - </group> - <group - android:name="device" - android:translateX="24.14999" - android:translateY="24.25" > - <path - android:name="device_1" - android:pathData="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z" - android:fillColor="#FFFFFFFF" - android:fillAlpha="1" /> - </group> - </group> - </group> - </vector> -</inset> diff --git a/packages/SystemUI/res/drawable/stat_sys_managed_profile_status_off.xml b/packages/SystemUI/res/drawable/stat_sys_managed_profile_status_off.xml deleted file mode 100644 index 1dedd5d4daef..000000000000 --- a/packages/SystemUI/res/drawable/stat_sys_managed_profile_status_off.xml +++ /dev/null @@ -1,24 +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. ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="23dp" - android:height="18dp" - android:viewportWidth="23.0" - android:viewportHeight="18.0"> - <path - android:fillColor="@android:color/white" - android:pathData="M19.4,16.6l-1.1,-1.1L8,5L5.1,2.2L4.2,3.1l2,2H5.7c-0.8,0 -1.4,0.6 -1.4,1.4v8c0,0.8 0.6,1.4 1.4,1.4h11.4l1.5,1.5L19.4,16.6zM18.7,6.5c0,-0.8 -0.6,-1.4 -1.4,-1.4h-2.9V3.6c0,-0.8 -0.6,-1.4 -1.4,-1.4h-3C9.2,2.1 8.6,2.8 8.6,3.6v0.2L18.7,14C18.7,14 18.7,6.5 18.7,6.5zM12.9,5.1H10V3.6h2.9V5.1z"/> -</vector> diff --git a/packages/SystemUI/res/drawable/stat_sys_no_sims.xml b/packages/SystemUI/res/drawable/stat_sys_no_sims.xml deleted file mode 100644 index 5c9be5c50a13..000000000000 --- a/packages/SystemUI/res/drawable/stat_sys_no_sims.xml +++ /dev/null @@ -1,30 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -** -** Copyright 2017, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="17dp" - android:height="17dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - <path - android:fillColor="#FFFFFFFF" - android:pathData="M12.09,9C11.11,7.5 9.43,6.5 7.5,6.5C4.46,6.5 2,8.96 2,12c0,3.04 2.46,5.5 5.5,5.5c1.93,0 3.61,-1 4.59,-2.5H14v3h6v-3h2V9H12.09zM20,13h-2v3h-2v-3h-5.16c-0.43,1.44 -1.76,2.5 -3.34,2.5C5.57,15.5 4,13.93 4,12c0,-1.93 1.57,-3.5 3.5,-3.5c1.58,0 2.9,1.06 3.34,2.5H20V13z"/> - <path - android:fillColor="#FFFFFFFF" - android:pathData="M7.5,12m-1.5,0a1.5,1.5 0,1 1,3 0a1.5,1.5 0,1 1,-3 0"/> -</vector> diff --git a/packages/SystemUI/res/drawable/stat_sys_signal_in.xml b/packages/SystemUI/res/drawable/stat_sys_signal_in.xml deleted file mode 100644 index 7e6e09b9c846..000000000000 --- a/packages/SystemUI/res/drawable/stat_sys_signal_in.xml +++ /dev/null @@ -1,27 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - Copyright (C) 2016 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:autoMirrored="true" - android:width="17dp" - android:height="17dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - <path - android:name="in" - android:fillColor="#FFFFFFFF" - android:pathData="M8.7,12.2l-2.0,3.5l-2.0,-3.5z" /> -</vector> diff --git a/packages/SystemUI/res/drawable/stat_sys_signal_inout.xml b/packages/SystemUI/res/drawable/stat_sys_signal_inout.xml deleted file mode 100644 index b7b6f0f56749..000000000000 --- a/packages/SystemUI/res/drawable/stat_sys_signal_inout.xml +++ /dev/null @@ -1,31 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - Copyright (C) 2016 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:autoMirrored="true" - android:width="17dp" - android:height="17dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - <path - android:name="in" - android:fillColor="#FFFFFFFF" - android:pathData="M8.7,12.2l-2.0,3.5l-2.0,-3.5z" /> - <path - android:name="out" - android:fillColor="#FFFFFFFF" - android:pathData="M0.5,15.7l2.0,-3.5l2.0,3.5z" /> -</vector> diff --git a/packages/SystemUI/res/drawable/stat_sys_signal_out.xml b/packages/SystemUI/res/drawable/stat_sys_signal_out.xml deleted file mode 100644 index 910c0355f5a9..000000000000 --- a/packages/SystemUI/res/drawable/stat_sys_signal_out.xml +++ /dev/null @@ -1,27 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - Copyright (C) 2016 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:autoMirrored="true" - android:width="17dp" - android:height="17dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - <path - android:name="out" - android:fillColor="#FFFFFFFF" - android:pathData="M0.5,15.7l2.0,-3.5l2.0,3.5z" /> -</vector> diff --git a/packages/SystemUI/res/drawable/stat_sys_wifi_in.xml b/packages/SystemUI/res/drawable/stat_sys_wifi_in.xml deleted file mode 100644 index ba3d4e60c6e7..000000000000 --- a/packages/SystemUI/res/drawable/stat_sys_wifi_in.xml +++ /dev/null @@ -1,27 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - Copyright (C) 2016 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:autoMirrored="true" - android:width="16.25dp" - android:height="15dp" - android:viewportWidth="26.0" - android:viewportHeight="24.0"> - <path - android:name="in" - android:fillColor="#FFFFFFFF" - android:pathData="M8.7,18.3l-2.0,3.5l-2.0,-3.5z" /> -</vector> diff --git a/packages/SystemUI/res/drawable/stat_sys_wifi_inout.xml b/packages/SystemUI/res/drawable/stat_sys_wifi_inout.xml deleted file mode 100644 index 1f3b68fd5d72..000000000000 --- a/packages/SystemUI/res/drawable/stat_sys_wifi_inout.xml +++ /dev/null @@ -1,31 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - Copyright (C) 2016 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:autoMirrored="true" - android:width="16.25dp" - android:height="15dp" - android:viewportWidth="26.0" - android:viewportHeight="24.0"> - <path - android:name="in" - android:fillColor="#FFFFFFFF" - android:pathData="M8.7,18.3l-2.0,3.5l-2.0,-3.5z" /> - <path - android:name="out" - android:fillColor="#FFFFFFFF" - android:pathData="M0.5,21.8l2.0,-3.5l2.0,3.5z" /> -</vector> diff --git a/packages/SystemUI/res/drawable/stat_sys_wifi_out.xml b/packages/SystemUI/res/drawable/stat_sys_wifi_out.xml deleted file mode 100644 index 24c6b1e871fa..000000000000 --- a/packages/SystemUI/res/drawable/stat_sys_wifi_out.xml +++ /dev/null @@ -1,27 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - Copyright (C) 2016 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:autoMirrored="true" - android:width="16.25dp" - android:height="15dp" - android:viewportWidth="26.0" - android:viewportHeight="24.0"> - <path - android:name="out" - android:fillColor="#FFFFFFFF" - android:pathData="M0.5,21.8l2.0,-3.5l2.0,3.5z" /> -</vector> diff --git a/packages/SystemUI/res/drawable/sun2.xml b/packages/SystemUI/res/drawable/sun2.xml deleted file mode 100644 index 6d2d5041f5ab..000000000000 --- a/packages/SystemUI/res/drawable/sun2.xml +++ /dev/null @@ -1,24 +0,0 @@ -<!-- -Copyright (C) 2014 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="48.0dp" - android:height="48.0dp" - android:viewportWidth="48.0" - android:viewportHeight="48.0"> - <path - android:pathData="M40.000000,17.400000L40.000000,8.000000l-9.400000,0.000000L24.000000,1.400000L17.400000,8.000000L8.000000,8.000000l0.000000,9.400000L1.400000,24.000000L8.000000,30.600000L8.000000,40.000000l9.400000,0.000000l6.600000,6.600000l6.600000,-6.600000L40.000000,40.000000l0.000000,-9.400000l6.600000,-6.600000L40.000000,17.400000zM24.000000,36.000000c-6.600000,0.000000 -12.000000,-5.400000 -12.000000,-12.000000s5.400000,-12.000000 12.000000,-12.000000c6.600000,0.000000 12.000000,5.400000 12.000000,12.000000S30.600000,36.000000 24.000000,36.000000zM24.000000,16.000000c-4.400000,0.000000 -8.000000,3.600000 -8.000000,8.000000c0.000000,4.400000 3.600000,8.000000 8.000000,8.000000s8.000000,-3.600000 8.000000,-8.000000C32.000000,19.600000 28.400000,16.000000 24.000000,16.000000z" - android:fillColor="#FF000000"/> -</vector> diff --git a/packages/SystemUI/res/drawable/tv_pip_outline.xml b/packages/SystemUI/res/drawable/tv_pip_outline.xml deleted file mode 100644 index c84438c2e55e..000000000000 --- a/packages/SystemUI/res/drawable/tv_pip_outline.xml +++ /dev/null @@ -1,20 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2016 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> - -<shape xmlns:android="http://schemas.android.com/apk/res/android" - android:shape="rectangle"> - <stroke android:width="2dp" android:color="#EEEEEE" /> -</shape> diff --git a/packages/SystemUI/res/drawable/volume_dialog_background.xml b/packages/SystemUI/res/drawable/volume_dialog_background.xml deleted file mode 100644 index 996ac5e030da..000000000000 --- a/packages/SystemUI/res/drawable/volume_dialog_background.xml +++ /dev/null @@ -1,18 +0,0 @@ -<!-- - Copyright (C) 2015 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<shape xmlns:android="http://schemas.android.com/apk/res/android" > - <solid android:color="?android:attr/colorBackgroundFloating" /> -</shape>
\ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java index 874cdccb8794..6864ea185834 100644 --- a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java +++ b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java @@ -48,14 +48,14 @@ import android.widget.TextView; import com.android.settingslib.Utils; import com.android.settingslib.graph.BatteryMeterDrawableBase; +import com.android.systemui.plugins.DarkIconDispatcher; +import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver; import com.android.systemui.settings.CurrentUserTracker; import com.android.systemui.statusbar.phone.StatusBarIconController; import com.android.systemui.statusbar.policy.BatteryController; import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback; import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener; -import com.android.systemui.statusbar.policy.DarkIconDispatcher; -import com.android.systemui.statusbar.policy.DarkIconDispatcher.DarkReceiver; import com.android.systemui.statusbar.policy.IconLogger; import com.android.systemui.tuner.TunerService; import com.android.systemui.tuner.TunerService.Tunable; diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java index 08fa434643f4..6e5042940175 100644 --- a/packages/SystemUI/src/com/android/systemui/Dependency.java +++ b/packages/SystemUI/src/com/android/systemui/Dependency.java @@ -38,6 +38,7 @@ import com.android.systemui.fragments.FragmentService; import com.android.systemui.keyguard.ScreenLifecycle; import com.android.systemui.keyguard.WakefulnessLifecycle; import com.android.systemui.plugins.ActivityStarter; +import com.android.systemui.plugins.DarkIconDispatcher; import com.android.systemui.plugins.PluginDependencyProvider; import com.android.systemui.plugins.VolumeDialogController; import com.android.systemui.power.EnhancedEstimates; @@ -45,7 +46,7 @@ import com.android.systemui.power.PowerUI; import com.android.systemui.recents.OverviewProxyService; import com.android.systemui.shared.plugins.PluginManager; import com.android.systemui.statusbar.AmbientPulseManager; -import com.android.systemui.statusbar.DisplayNavigationBarController; +import com.android.systemui.statusbar.NavigationBarController; import com.android.systemui.statusbar.NotificationListener; import com.android.systemui.statusbar.NotificationLockscreenUserManager; import com.android.systemui.statusbar.NotificationMediaManager; @@ -79,7 +80,6 @@ import com.android.systemui.statusbar.policy.BatteryController; import com.android.systemui.statusbar.policy.BluetoothController; import com.android.systemui.statusbar.policy.CastController; import com.android.systemui.statusbar.policy.ConfigurationController; -import com.android.systemui.statusbar.policy.DarkIconDispatcher; import com.android.systemui.statusbar.policy.DataSaverController; import com.android.systemui.statusbar.policy.DeviceProvisionedController; import com.android.systemui.statusbar.policy.ExtensionController; @@ -244,7 +244,7 @@ public class Dependency extends SystemUI { @Inject Lazy<NotificationRemoteInputManager.Callback> mNotificationRemoteInputManagerCallback; @Inject Lazy<InitController> mInitController; @Inject Lazy<AppOpsController> mAppOpsController; - @Inject Lazy<DisplayNavigationBarController> mDisplayNavigationBarController; + @Inject Lazy<NavigationBarController> mNavigationBarController; @Inject Lazy<StatusBarStateController> mStatusBarStateController; @Inject Lazy<NotificationLockscreenUserManager> mNotificationLockscreenUserManager; @Inject Lazy<NotificationGroupAlertTransferHelper> mNotificationGroupAlertTransferHelper; @@ -410,8 +410,7 @@ public class Dependency extends SystemUI { mProviders.put(AppOpsController.class, mAppOpsController::get); - mProviders.put(DisplayNavigationBarController.class, - mDisplayNavigationBarController::get); + mProviders.put(NavigationBarController.class, mNavigationBarController::get); mProviders.put(StatusBarStateController.class, mStatusBarStateController::get); mProviders.put(NotificationLockscreenUserManager.class, diff --git a/packages/SystemUI/src/com/android/systemui/DependencyBinder.java b/packages/SystemUI/src/com/android/systemui/DependencyBinder.java index b93a5fd1f761..1ee1dcf74555 100644 --- a/packages/SystemUI/src/com/android/systemui/DependencyBinder.java +++ b/packages/SystemUI/src/com/android/systemui/DependencyBinder.java @@ -19,6 +19,7 @@ package com.android.systemui; import com.android.systemui.appops.AppOpsController; import com.android.systemui.appops.AppOpsControllerImpl; import com.android.systemui.plugins.ActivityStarter; +import com.android.systemui.plugins.DarkIconDispatcher; import com.android.systemui.plugins.VolumeDialogController; import com.android.systemui.power.PowerNotificationWarnings; import com.android.systemui.power.PowerUI; @@ -37,7 +38,6 @@ import com.android.systemui.statusbar.policy.BluetoothController; import com.android.systemui.statusbar.policy.BluetoothControllerImpl; import com.android.systemui.statusbar.policy.CastController; import com.android.systemui.statusbar.policy.CastControllerImpl; -import com.android.systemui.statusbar.policy.DarkIconDispatcher; import com.android.systemui.statusbar.policy.DeviceProvisionedController; import com.android.systemui.statusbar.policy.DeviceProvisionedControllerImpl; import com.android.systemui.statusbar.policy.ExtensionController; diff --git a/packages/SystemUI/src/com/android/systemui/DependencyProvider.java b/packages/SystemUI/src/com/android/systemui/DependencyProvider.java index 2b521c53a1e6..5c9b9990058e 100644 --- a/packages/SystemUI/src/com/android/systemui/DependencyProvider.java +++ b/packages/SystemUI/src/com/android/systemui/DependencyProvider.java @@ -41,6 +41,7 @@ import com.android.settingslib.bluetooth.LocalBluetoothManager; import com.android.systemui.plugins.PluginInitializerImpl; import com.android.systemui.shared.plugins.PluginManager; import com.android.systemui.shared.plugins.PluginManagerImpl; +import com.android.systemui.statusbar.NavigationBarController; import com.android.systemui.statusbar.phone.ConfigurationControllerImpl; import com.android.systemui.statusbar.phone.ShadeController; import com.android.systemui.statusbar.phone.StatusBar; @@ -170,6 +171,13 @@ public class DependencyProvider { @Singleton @Provides + public NavigationBarController provideNavigationBarController(Context context, + @Named(MAIN_HANDLER_NAME) Handler mainHandler) { + return new NavigationBarController(context, mainHandler); + } + + @Singleton + @Provides public ConfigurationController provideConfigurationController(Context context) { return new ConfigurationControllerImpl(context); } diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java index 04362c17141c..b6fc35553760 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java @@ -85,6 +85,7 @@ public class DozeSensors { mProxCallback = proxCallback; mResolver = mContext.getContentResolver(); + boolean alwaysOn = mConfig.alwaysOnEnabled(UserHandle.USER_CURRENT); mSensors = new TriggerSensor[] { new TriggerSensor( mSensorManager.getDefaultSensor(Sensor.TYPE_SIGNIFICANT_MOTION), @@ -116,7 +117,7 @@ public class DozeSensors { new PluginSensor( new SensorManagerPlugin.Sensor(TYPE_WAKE_DISPLAY), Settings.Secure.DOZE_WAKE_SCREEN_GESTURE, - mConfig.wakeScreenGestureAvailable(), + mConfig.wakeScreenGestureAvailable() && alwaysOn, DozeLog.REASON_SENSOR_WAKE_UP, false /* reports touch coordinates */, false /* touchscreen */), diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java b/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java index d7d3981d05d1..7c937a944113 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java @@ -17,6 +17,7 @@ package com.android.systemui.qs; import android.app.ActivityManager; import android.app.AlertDialog; +import android.app.admin.DevicePolicyEventLogger; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; @@ -30,6 +31,7 @@ import android.text.SpannableStringBuilder; import android.text.method.LinkMovementMethod; import android.text.style.ClickableSpan; import android.util.Log; +import android.util.StatsLog; import android.view.ContextThemeWrapper; import android.view.LayoutInflater; import android.view.View; @@ -119,6 +121,9 @@ public class QSSecurityFooter implements OnClickListener, DialogInterface.OnClic private void handleClick() { showDeviceMonitoringDialog(); + DevicePolicyEventLogger + .createEvent(StatsLog.DEVICE_POLICY_EVENT__EVENT_ID__DO_USER_INFO_CLICKED) + .write(); } public void showDeviceMonitoringDialog() { diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java index bec027f902a0..72245999b084 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java @@ -63,6 +63,8 @@ import com.android.systemui.BatteryMeterView; import com.android.systemui.Prefs; import com.android.systemui.R; import com.android.systemui.plugins.ActivityStarter; +import com.android.systemui.plugins.DarkIconDispatcher; +import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver; import com.android.systemui.privacy.OngoingPrivacyChip; import com.android.systemui.privacy.OngoingPrivacyDialog; import com.android.systemui.privacy.PrivacyItem; @@ -75,8 +77,6 @@ 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; import com.android.systemui.statusbar.policy.DateView; import com.android.systemui.statusbar.policy.NextAlarmController; import com.android.systemui.statusbar.policy.ZenModeController; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/DisplayNavigationBarController.java b/packages/SystemUI/src/com/android/systemui/statusbar/DisplayNavigationBarController.java deleted file mode 100644 index 78172f19d291..000000000000 --- a/packages/SystemUI/src/com/android/systemui/statusbar/DisplayNavigationBarController.java +++ /dev/null @@ -1,148 +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.systemui.statusbar; - -import static android.view.Display.DEFAULT_DISPLAY; - -import static com.android.systemui.Dependency.MAIN_HANDLER_NAME; - -import android.content.Context; -import android.hardware.display.DisplayManager; -import android.hardware.display.DisplayManager.DisplayListener; -import android.os.Handler; -import android.os.RemoteException; -import android.util.Log; -import android.util.SparseArray; -import android.view.Display; -import android.view.IWindowManager; -import android.view.View; -import android.view.WindowManagerGlobal; - -import com.android.systemui.statusbar.phone.NavigationBarFragment; - -import javax.inject.Inject; -import javax.inject.Named; -import javax.inject.Singleton; - -/** - * A controller to handle external navigation bars - */ -@Singleton -public class DisplayNavigationBarController implements DisplayListener { - - private static final String TAG = DisplayNavigationBarController.class.getName(); - - private final Context mContext; - private final Handler mHandler; - private final DisplayManager mDisplayManager; - - /** A displayId - nav bar mapping */ - private SparseArray<NavigationBarFragment> mExternalNavigationBarMap = new SparseArray<>(); - - @Inject - public DisplayNavigationBarController(Context context, - @Named(MAIN_HANDLER_NAME) Handler handler) { - mContext = context; - mHandler = handler; - mDisplayManager = (DisplayManager) mContext.getSystemService(Context.DISPLAY_SERVICE); - - registerListener(); - } - - @Override - public void onDisplayAdded(int displayId) { - final Display display = mDisplayManager.getDisplay(displayId); - addExternalNavigationBar(display); - } - - @Override - public void onDisplayRemoved(int displayId) { - final NavigationBarFragment navBar = mExternalNavigationBarMap.get(displayId); - if (navBar != null) { - final View navigationView = navBar.getView().getRootView(); - WindowManagerGlobal.getInstance().removeView(navigationView, true); - mExternalNavigationBarMap.remove(displayId); - } - } - - @Override - public void onDisplayChanged(int displayId) { - } - - /** Create external navigation bars when car/status bar initializes */ - public void createNavigationBars() { - // Add external navigation bars if more than one displays exist. - final Display[] displays = mDisplayManager.getDisplays(); - for (Display display : displays) { - addExternalNavigationBar(display); - } - } - - /** remove external navigation bars and unset everything related to external navigation bars */ - public void destroy() { - unregisterListener(); - if (mExternalNavigationBarMap.size() > 0) { - for (int i = 0; i < mExternalNavigationBarMap.size(); i++) { - final View navigationWindow = mExternalNavigationBarMap.valueAt(i) - .getView().getRootView(); - WindowManagerGlobal.getInstance() - .removeView(navigationWindow, true /* immediate */); - } - mExternalNavigationBarMap.clear(); - } - } - - private void registerListener() { - mDisplayManager.registerDisplayListener(this, mHandler); - } - - private void unregisterListener() { - mDisplayManager.unregisterDisplayListener(this); - } - - /** - * Add a phone navigation bar on an external display if the display supports system decorations. - * - * @param display the display to add navigation bar on - */ - private void addExternalNavigationBar(Display display) { - if (display == null || display.getDisplayId() == DEFAULT_DISPLAY - || !display.supportsSystemDecorations()) { - return; - } - - final int displayId = display.getDisplayId(); - final IWindowManager wms = WindowManagerGlobal.getWindowManagerService(); - - try { - if (!wms.hasNavigationBar(displayId)) { - return; - } - } catch (RemoteException e) { - // Cannot get wms, just return with warning message. - Log.w(TAG, "Cannot get WindowManager."); - return; - } - final Context externalDisplayContext = mContext.createDisplayContext(display); - NavigationBarFragment.create(externalDisplayContext, (tag, fragment) -> { - final NavigationBarFragment navBar = (NavigationBarFragment) fragment; - // TODO(b/115978725): handle external nav bars sysuiVisibility - navBar.setCurrentSysuiVisibility(View.SYSTEM_UI_FLAG_VISIBLE); - mExternalNavigationBarMap.append(displayId, navBar); - }); - } -} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/HeadsUpStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/HeadsUpStatusBarView.java index b39a96d40828..e2177774a75d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/HeadsUpStatusBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/HeadsUpStatusBarView.java @@ -31,8 +31,8 @@ import android.widget.TextView; import com.android.internal.annotations.VisibleForTesting; import com.android.keyguard.AlphaOptimizedLinearLayout; import com.android.systemui.R; +import com.android.systemui.plugins.DarkIconDispatcher; import com.android.systemui.statusbar.notification.NotificationData; -import com.android.systemui.statusbar.policy.DarkIconDispatcher; import java.util.List; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NavigationBarController.java b/packages/SystemUI/src/com/android/systemui/statusbar/NavigationBarController.java new file mode 100644 index 000000000000..43eaff40ffe0 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NavigationBarController.java @@ -0,0 +1,222 @@ +/* + * 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.systemui.statusbar; + +import static android.view.Display.DEFAULT_DISPLAY; + +import static com.android.systemui.Dependency.MAIN_HANDLER_NAME; + +import android.content.Context; +import android.hardware.display.DisplayManager; +import android.hardware.display.DisplayManager.DisplayListener; +import android.os.Handler; +import android.os.RemoteException; +import android.util.Log; +import android.util.SparseArray; +import android.view.Display; +import android.view.IWindowManager; +import android.view.View; +import android.view.WindowManagerGlobal; + +import com.android.systemui.Dependency; +import com.android.systemui.plugins.DarkIconDispatcher; +import com.android.systemui.statusbar.phone.BarTransitions.TransitionMode; +import com.android.systemui.statusbar.phone.LightBarController; +import com.android.systemui.statusbar.phone.NavigationBarFragment; +import com.android.systemui.statusbar.phone.NavigationBarView; +import com.android.systemui.statusbar.policy.BatteryController; + +import javax.inject.Inject; +import javax.inject.Named; +import javax.inject.Singleton; + + +/** A controller to handle navigation bars. */ +@Singleton +public class NavigationBarController implements DisplayListener { + + private static final String TAG = NavigationBarController.class.getName(); + + private final Context mContext; + private final Handler mHandler; + private final DisplayManager mDisplayManager; + + /** A displayId - nav bar maps. */ + private SparseArray<NavigationBarFragment> mNavigationBars = new SparseArray<>(); + + @Inject + public NavigationBarController(Context context, @Named(MAIN_HANDLER_NAME) Handler handler) { + mContext = context; + mHandler = handler; + mDisplayManager = (DisplayManager) mContext.getSystemService(Context.DISPLAY_SERVICE); + mDisplayManager.registerDisplayListener(this, mHandler); + } + + @Override + public void onDisplayAdded(int displayId) { + Display display = mDisplayManager.getDisplay(displayId); + createNavigationBar(display); + } + + @Override + public void onDisplayRemoved(int displayId) { + removeNavigationBar(displayId); + } + + @Override + public void onDisplayChanged(int displayId) { + } + + // TODO(b/117478341): I use {@code includeDefaultDisplay} to make this method compatible to + // CarStatusBar because they have their own nav bar. Think about a better way for it. + /** + * Creates navigation bars when car/status bar initializes. + * + * @param includeDefaultDisplay {@code true} to create navigation bar on default display. + */ + public void createNavigationBars(final boolean includeDefaultDisplay) { + Display[] displays = mDisplayManager.getDisplays(); + for (Display display : displays) { + if (includeDefaultDisplay || display.getDisplayId() != DEFAULT_DISPLAY) { + createNavigationBar(display); + } + } + } + + /** + * Adds a navigation bar on default display or an external display if the display supports + * system decorations. + * + * @param display the display to add navigation bar on. + */ + private void createNavigationBar(Display display) { + if (display == null + || (display.getDisplayId() != DEFAULT_DISPLAY + && !display.supportsSystemDecorations())) { + return; + } + + final int displayId = display.getDisplayId(); + final boolean isOnDefaultDisplay = displayId == DEFAULT_DISPLAY; + final IWindowManager wms = WindowManagerGlobal.getWindowManagerService(); + + try { + if (!wms.hasNavigationBar(displayId)) { + return; + } + } catch (RemoteException e) { + // Cannot get wms, just return with warning message. + Log.w(TAG, "Cannot get WindowManager."); + return; + } + final Context context = isOnDefaultDisplay + ? mContext + : mContext.createDisplayContext(display); + NavigationBarFragment.create(context, (tag, fragment) -> { + NavigationBarFragment navBar = (NavigationBarFragment) fragment; + + // Unfortunately, we still need it because status bar needs LightBarController + // before notifications creation. We cannot directly use getLightBarController() + // from NavigationBarFragment directly. + LightBarController controller = isOnDefaultDisplay + ? Dependency.get(LightBarController.class) + : new LightBarController(context, + Dependency.get(DarkIconDispatcher.class), + Dependency.get(BatteryController.class)); + navBar.setLightBarController(controller); + navBar.setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE); + mNavigationBars.append(displayId, navBar); + }); + } + + /** Removes navigation bars. */ + public void destroy() { + mDisplayManager.unregisterDisplayListener(this); + if (mNavigationBars.size() > 0) { + for (int i = 0; i < mNavigationBars.size(); i++) { + int displayId = mNavigationBars.keyAt(i); + removeNavigationBar(displayId); + } + mNavigationBars.clear(); + } + } + + private void removeNavigationBar(int displayId) { + NavigationBarFragment navBar = mNavigationBars.get(displayId); + if (navBar != null) { + View navigationWindow = navBar.getView().getRootView(); + WindowManagerGlobal.getInstance() + .removeView(navigationWindow, true /* immediate */); + mNavigationBars.remove(displayId); + } + } + + /** @see NavigationBarFragment#checkNavBarModes() */ + public void checkNavBarModes(int displayId) { + NavigationBarFragment navBar = mNavigationBars.get(displayId); + if (navBar != null) { + navBar.checkNavBarModes(); + } + } + + /** @see NavigationBarFragment#finishBarAnimations() */ + public void finishBarAnimations(int displayId) { + NavigationBarFragment navBar = mNavigationBars.get(displayId); + if (navBar != null) { + navBar.finishBarAnimations(); + } + } + + /** @see NavigationBarFragment#touchAutoDim() */ + public void touchAutoDim(int displayId) { + NavigationBarFragment navBar = mNavigationBars.get(displayId); + if (navBar != null) { + navBar.touchAutoDim(); + } + } + + /** @see NavigationBarFragment#transitionTo(int, boolean) */ + public void transitionTo(int displayId, @TransitionMode int barMode, boolean animate) { + NavigationBarFragment navBar = mNavigationBars.get(displayId); + if (navBar != null) { + navBar.transitionTo(barMode, animate); + } + } + + /** @see NavigationBarFragment#isSemiTransparent() */ + public boolean isSemiTransparent(int displayId) { + NavigationBarFragment navBar = mNavigationBars.get(displayId); + if (navBar != null) { + return navBar.isSemiTransparent(); + } + return false; + } + + /** @see NavigationBarFragment#disableAnimationsDuringHide(long) */ + public void disableAnimationsDuringHide(int displayId, long delay) { + NavigationBarFragment navBar = mNavigationBars.get(displayId); + if (navBar != null) { + navBar.disableAnimationsDuringHide(delay); + } + } + + /** @return {@link NavigationBarView} on the default display. */ + public NavigationBarView getDefaultNavigationBarView() { + NavigationBarFragment navBar = mNavigationBars.get(DEFAULT_DISPLAY); + return (navBar == null) ? null : (NavigationBarView) navBar.getView(); + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java index 25837e11448f..1bf101c00711 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java @@ -157,7 +157,7 @@ public class NotificationMediaManager implements Dumpable { notificationEntryManager.addNotificationEntryListener(new NotificationEntryListener() { @Override public void onEntryRemoved( - Entry entry, + @Nullable Entry entry, String key, StatusBarNotification old, NotificationVisibility visibility, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java index 674e26218955..886d99eeff17 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java @@ -20,6 +20,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN_OR_SPLIT import static com.android.systemui.Dependency.MAIN_HANDLER_NAME; import android.annotation.NonNull; +import android.annotation.Nullable; import android.app.ActivityManager; import android.app.ActivityOptions; import android.app.KeyguardManager; @@ -252,13 +253,13 @@ public class NotificationRemoteInputManager implements Dumpable { notificationEntryManager.addNotificationEntryListener(new NotificationEntryListener() { @Override public void onEntryRemoved( - NotificationData.Entry entry, + @Nullable NotificationData.Entry entry, String key, StatusBarNotification old, NotificationVisibility visibility, boolean lifetimeExtended, boolean removedByUser) { - if (removedByUser) { + if (removedByUser && entry != null) { onPerformRemoveNotification(entry, key); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/OperatorNameView.java b/packages/SystemUI/src/com/android/systemui/statusbar/OperatorNameView.java index f1a891b95eaa..d1b3c3cb12d8 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/OperatorNameView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/OperatorNameView.java @@ -30,8 +30,8 @@ import com.android.keyguard.KeyguardUpdateMonitorCallback; import com.android.settingslib.WirelessUtils; import com.android.systemui.DemoMode; import com.android.systemui.Dependency; -import com.android.systemui.statusbar.policy.DarkIconDispatcher; -import com.android.systemui.statusbar.policy.DarkIconDispatcher.DarkReceiver; +import com.android.systemui.plugins.DarkIconDispatcher; +import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver; import com.android.systemui.statusbar.policy.NetworkController; 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/SignalClusterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java index e7b768f30023..6d2c001dc153 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java @@ -41,9 +41,9 @@ import android.widget.LinearLayout; import com.android.settingslib.graph.SignalDrawable; import com.android.systemui.Dependency; import com.android.systemui.R; +import com.android.systemui.plugins.DarkIconDispatcher; +import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver; import com.android.systemui.statusbar.phone.StatusBarIconController; -import com.android.systemui.statusbar.policy.DarkIconDispatcher; -import com.android.systemui.statusbar.policy.DarkIconDispatcher.DarkReceiver; import com.android.systemui.statusbar.policy.IconLogger; import com.android.systemui.statusbar.policy.NetworkController; import com.android.systemui.statusbar.policy.NetworkController.IconState; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java index 8b61a5bccc3c..3c1335456d04 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java @@ -16,7 +16,7 @@ package com.android.systemui.statusbar; -import static com.android.systemui.statusbar.policy.DarkIconDispatcher.getTint; +import static com.android.systemui.plugins.DarkIconDispatcher.getTint; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java index bc89889c48fe..4db981d2dcd0 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java @@ -16,11 +16,11 @@ package com.android.systemui.statusbar; +import static com.android.systemui.plugins.DarkIconDispatcher.getTint; +import static com.android.systemui.plugins.DarkIconDispatcher.isInArea; 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 static com.android.systemui.statusbar.policy.DarkIconDispatcher.getTint; -import static com.android.systemui.statusbar.policy.DarkIconDispatcher.isInArea; import android.content.Context; import android.content.res.ColorStateList; @@ -37,8 +37,8 @@ import android.widget.LinearLayout; import com.android.internal.annotations.VisibleForTesting; import com.android.settingslib.graph.SignalDrawable; import com.android.systemui.R; +import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver; import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.MobileIconState; -import com.android.systemui.statusbar.policy.DarkIconDispatcher.DarkReceiver; public class StatusBarMobileView extends FrameLayout implements DarkReceiver, StatusIconDisplayable { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarWifiView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarWifiView.java index 045221f510fa..c5751c300c01 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarWifiView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarWifiView.java @@ -16,11 +16,11 @@ package com.android.systemui.statusbar; +import static com.android.systemui.plugins.DarkIconDispatcher.getTint; +import static com.android.systemui.plugins.DarkIconDispatcher.isInArea; 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 static com.android.systemui.statusbar.policy.DarkIconDispatcher.getTint; -import static com.android.systemui.statusbar.policy.DarkIconDispatcher.isInArea; import android.content.Context; import android.content.res.ColorStateList; @@ -37,8 +37,8 @@ import android.widget.LinearLayout; import com.android.settingslib.Utils; import com.android.systemui.R; +import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver; import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.WifiIconState; -import com.android.systemui.statusbar.policy.DarkIconDispatcher.DarkReceiver; /** * Start small: StatusBarWifiView will be able to layout from a WifiIconState diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusIconDisplayable.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusIconDisplayable.java index beb90b893ec8..d541fae4ed33 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusIconDisplayable.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusIconDisplayable.java @@ -16,7 +16,7 @@ package com.android.systemui.statusbar; -import com.android.systemui.statusbar.policy.DarkIconDispatcher.DarkReceiver; +import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver; public interface StatusIconDisplayable extends DarkReceiver { String getSlot(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationAlertingManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationAlertingManager.java index dbc6f435ae59..7b42dd901d72 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationAlertingManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationAlertingManager.java @@ -20,6 +20,7 @@ import static com.android.systemui.statusbar.NotificationRemoteInputManager.FORC import static com.android.systemui.statusbar.notification.row.NotificationInflater.FLAG_CONTENT_VIEW_AMBIENT; import static com.android.systemui.statusbar.notification.row.NotificationInflater.FLAG_CONTENT_VIEW_HEADS_UP; +import android.annotation.Nullable; import android.app.Notification; import android.service.notification.StatusBarNotification; import android.util.Log; @@ -82,7 +83,7 @@ public class NotificationAlertingManager { @Override public void onEntryRemoved( - NotificationData.Entry entry, + @Nullable NotificationData.Entry entry, String key, StatusBarNotification old, NotificationVisibility visibility, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationData.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationData.java index 27c283749abc..a51896ee69fc 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationData.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationData.java @@ -90,7 +90,7 @@ public class NotificationData { private static final long INITIALIZATION_DELAY = 400; private static final long NOT_LAUNCHED_YET = -LAUNCH_COOLDOWN; private static final int COLOR_INVALID = 1; - public String key; + public final String key; public StatusBarNotification notification; public NotificationChannel channel; public long lastAudiblyAlertedMs; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryListener.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryListener.java index 72f1d5bfb013..1d06ce031f2b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryListener.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryListener.java @@ -80,7 +80,7 @@ public interface NotificationEntryListener { * @param removedByUser true if the notification was removed by a user action */ default void onEntryRemoved( - NotificationData.Entry entry, + @Nullable NotificationData.Entry entry, String key, StatusBarNotification old, @Nullable NotificationVisibility visibility, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationLogger.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationLogger.java index 060e7558e255..610d3003f0e9 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationLogger.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationLogger.java @@ -15,6 +15,7 @@ */ package com.android.systemui.statusbar.notification.logging; +import android.annotation.Nullable; import android.content.Context; import android.os.Handler; import android.os.RemoteException; @@ -167,13 +168,13 @@ public class NotificationLogger implements StateListener { entryManager.addNotificationEntryListener(new NotificationEntryListener() { @Override public void onEntryRemoved( - NotificationData.Entry entry, + @Nullable NotificationData.Entry entry, String key, StatusBarNotification old, NotificationVisibility visibility, boolean lifetimeExtended, boolean removedByUser) { - if (removedByUser && visibility != null) { + if (removedByUser && visibility != null && entry != null) { logNotificationClear(key, entry.notification, visibility); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInlineImageCache.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInlineImageCache.java index 8c8bad2ab196..a5411ecb4bd0 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInlineImageCache.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInlineImageCache.java @@ -87,8 +87,8 @@ public class NotificationInlineImageCache implements NotificationInlineImageReso try { drawable = mResolver.resolveImage(target); - } catch (IOException ex) { - Log.d(TAG, "PreloadImageTask: Resolve failed from " + target); + } catch (IOException | SecurityException ex) { + Log.d(TAG, "PreloadImageTask: Resolve failed from " + target, ex); } return drawable; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInlineImageResolver.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInlineImageResolver.java index 588246f3d2c6..a3e13053d169 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInlineImageResolver.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInlineImageResolver.java @@ -81,8 +81,8 @@ public class NotificationInlineImageResolver implements ImageResolver { Drawable result = null; try { result = hasCache() ? mImageCache.get(uri) : resolveImage(uri); - } catch (IOException ex) { - Log.d(TAG, "loadImage: Can't load image from " + uri); + } catch (IOException | SecurityException ex) { + Log.d(TAG, "loadImage: Can't load image from " + uri, ex); } return result; } 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 3d814732a2e7..79056175b595 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java @@ -16,6 +16,7 @@ package com.android.systemui.statusbar.phone; +import android.annotation.IntDef; import android.content.Context; import android.content.res.Resources; import android.graphics.Canvas; @@ -36,6 +37,9 @@ import com.android.settingslib.Utils; import com.android.systemui.Interpolators; import com.android.systemui.R; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + public class BarTransitions { private static final boolean DEBUG = false; private static final boolean DEBUG_COLORS = false; @@ -48,6 +52,18 @@ public class BarTransitions { public static final int MODE_WARNING = 5; public static final int MODE_LIGHTS_OUT_TRANSPARENT = 6; + @IntDef(flag = true, prefix = { "MODE_" }, value = { + MODE_OPAQUE, + MODE_SEMI_TRANSPARENT, + MODE_TRANSLUCENT, + MODE_LIGHTS_OUT, + MODE_TRANSPARENT, + MODE_WARNING, + MODE_LIGHTS_OUT_TRANSPARENT + }) + @Retention(RetentionPolicy.SOURCE) + public @interface TransitionMode {} + public static final int LIGHTS_IN_DURATION = 250; public static final int LIGHTS_OUT_DURATION = 1500; public static final int BACKGROUND_DURATION = 200; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DarkIconDispatcherImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DarkIconDispatcherImpl.java index 5b44a77454b2..08a10dc925e3 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DarkIconDispatcherImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DarkIconDispatcherImpl.java @@ -14,7 +14,8 @@ package com.android.systemui.statusbar.phone; -import static com.android.systemui.statusbar.policy.DarkIconDispatcher.getTint; +import static com.android.systemui.plugins.DarkIconDispatcher.DEFAULT_ICON_TINT; +import static com.android.systemui.plugins.DarkIconDispatcher.getTint; import android.animation.ArgbEvaluator; import android.content.Context; @@ -24,7 +25,7 @@ import android.util.ArrayMap; import android.widget.ImageView; import com.android.systemui.R; -import com.android.systemui.statusbar.policy.DarkIconDispatcher; +import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver; import java.io.FileDescriptor; import java.io.PrintWriter; @@ -35,7 +36,7 @@ import javax.inject.Singleton; /** */ @Singleton -public class DarkIconDispatcherImpl implements DarkIconDispatcher { +public class DarkIconDispatcherImpl implements SysuiDarkIconDispatcher { private final LightBarTransitionsController mTransitionsController; private final Rect mTintArea = new Rect(); 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 3425dd237430..236c72c5cc2c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java @@ -29,14 +29,14 @@ import android.widget.LinearLayout; import com.android.internal.statusbar.StatusBarIcon; import com.android.systemui.DemoMode; import com.android.systemui.R; +import com.android.systemui.plugins.DarkIconDispatcher; +import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver; 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; 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 3c8cad7cb60b..d1e488ab2b4d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java @@ -25,12 +25,12 @@ import android.view.WindowInsets; import com.android.internal.annotations.VisibleForTesting; import com.android.systemui.Dependency; import com.android.systemui.R; +import com.android.systemui.plugins.DarkIconDispatcher; import com.android.systemui.statusbar.CrossFadeHelper; 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 java.util.function.BiConsumer; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java index 5ba59b507fec..03375d20e6db 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java @@ -45,13 +45,13 @@ import com.android.systemui.BatteryMeterView; import com.android.systemui.Dependency; import com.android.systemui.Interpolators; import com.android.systemui.R; +import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver; import com.android.systemui.qs.QSPanel; import com.android.systemui.statusbar.phone.StatusBarIconController.TintedIconManager; import com.android.systemui.statusbar.policy.BatteryController; import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback; import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener; -import com.android.systemui.statusbar.policy.DarkIconDispatcher.DarkReceiver; import com.android.systemui.statusbar.policy.KeyguardUserSwitcher; import com.android.systemui.statusbar.policy.UserInfoController; import com.android.systemui.statusbar.policy.UserInfoController.OnUserInfoChangedListener; 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 6632d5851119..b590ca7f4df0 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java @@ -27,8 +27,8 @@ import android.view.View; import com.android.internal.colorextraction.ColorExtractor.GradientColors; import com.android.systemui.Dumpable; import com.android.systemui.R; +import com.android.systemui.plugins.DarkIconDispatcher; import com.android.systemui.statusbar.policy.BatteryController; -import com.android.systemui.statusbar.policy.DarkIconDispatcher; import java.io.FileDescriptor; import java.io.PrintWriter; @@ -44,7 +44,7 @@ public class LightBarController implements BatteryController.BatteryStateChangeC private static final float NAV_BAR_INVERSION_SCRIM_ALPHA_THRESHOLD = 0.1f; - private final DarkIconDispatcher mStatusBarIconController; + private final SysuiDarkIconDispatcher mStatusBarIconController; private final BatteryController mBatteryController; private BiometricUnlockController mBiometricUnlockController; @@ -79,16 +79,13 @@ public class LightBarController implements BatteryController.BatteryStateChangeC private final Rect mLastDockedBounds = new Rect(); private boolean mQsCustomizing; - private final Context mContext; - @Inject public LightBarController(Context ctx, DarkIconDispatcher darkIconDispatcher, BatteryController batteryController) { mDarkModeColor = Color.valueOf(ctx.getColor(R.color.dark_mode_icon_color_single_tone)); - mStatusBarIconController = darkIconDispatcher; + mStatusBarIconController = (SysuiDarkIconDispatcher) darkIconDispatcher; mBatteryController = batteryController; mBatteryController.addCallback(this); - mContext = ctx; } public void setNavigationBar(LightBarTransitionsController navigationBar) { @@ -225,9 +222,8 @@ public class LightBarController implements BatteryController.BatteryStateChangeC private void updateNavigation() { if (mNavigationBarController != null) { - if (!NavBarTintController.isEnabled(mContext)) { - mNavigationBarController.setIconsDark(mNavigationLight, animateChange()); - } + mNavigationBarController.setIconsDark( + mNavigationLight, animateChange()); } } @@ -268,10 +264,6 @@ public class LightBarController implements BatteryController.BatteryStateChangeC pw.println(); - if (mStatusBarIconController != null) { - mStatusBarIconController.dump(fd, pw, args); - } - LightBarTransitionsController transitionsController = mStatusBarIconController.getTransitionsController(); if (transitionsController != null) { 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 2daff2cb18bc..270565be8bab 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java @@ -16,14 +16,19 @@ package com.android.systemui.statusbar.phone; import static android.app.StatusBarManager.NAVIGATION_HINT_BACK_ALT; import static android.app.StatusBarManager.NAVIGATION_HINT_IME_SHOWN; +import static android.app.StatusBarManager.WINDOW_STATE_HIDDEN; import static android.app.StatusBarManager.WINDOW_STATE_SHOWING; import static android.app.StatusBarManager.windowStateToString; import static com.android.systemui.recents.OverviewProxyService.OverviewProxyListener; import static com.android.systemui.shared.system.NavigationBarCompat.InteractionType; +import static com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT; import static com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT_TRANSPARENT; +import static com.android.systemui.statusbar.phone.BarTransitions.MODE_OPAQUE; import static com.android.systemui.statusbar.phone.BarTransitions.MODE_SEMI_TRANSPARENT; +import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSLUCENT; import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSPARENT; +import static com.android.systemui.statusbar.phone.BarTransitions.TransitionMode; import static com.android.systemui.statusbar.phone.StatusBar.DEBUG_WINDOW_STATE; import static com.android.systemui.statusbar.phone.StatusBar.dumpBarTransitions; @@ -55,6 +60,7 @@ import android.telecom.TelecomManager; import android.text.TextUtils; import android.util.Log; import android.view.Display; +import android.view.IWindowManager; import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.MotionEvent; @@ -63,6 +69,7 @@ import android.view.View; import android.view.ViewGroup; import android.view.WindowManager; import android.view.WindowManager.LayoutParams; +import android.view.WindowManagerGlobal; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityManager; import android.view.accessibility.AccessibilityManager.AccessibilityServicesStateChangeListener; @@ -72,6 +79,7 @@ import androidx.annotation.VisibleForTesting; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.util.LatencyTracker; +import com.android.systemui.Dependency; import com.android.systemui.R; import com.android.systemui.SysUiServiceProvider; import com.android.systemui.assist.AssistManager; @@ -83,6 +91,8 @@ import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.stackdivider.Divider; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.CommandQueue.Callbacks; +import com.android.systemui.statusbar.StatusBarState; +import com.android.systemui.statusbar.StatusBarStateController; import com.android.systemui.statusbar.notification.stack.StackStateAnimator; import com.android.systemui.statusbar.phone.ContextualButton.ContextButtonListener; import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper; @@ -111,6 +121,7 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback /** Allow some time inbetween the long press for back and recents. */ private static final int LOCK_TO_APP_GESTURE_TOLERENCE = 200; + private static final long AUTOHIDE_TIMEOUT_MS = 2250; private final AccessibilityManagerWrapper mAccessibilityManagerWrapper; protected final AssistManager mAssistManager; @@ -122,10 +133,11 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback private int mNavigationBarWindowState = WINDOW_STATE_SHOWING; private int mNavigationIconHints = 0; - private int mNavigationBarMode; + private @TransitionMode int mNavigationBarMode; private AccessibilityManager mAccessibilityManager; private MagnificationContentObserver mMagnificationObserver; private ContentResolver mContentResolver; + private IWindowManager mWindowManagerService = WindowManagerGlobal.getWindowManagerService(); private int mDisabledFlags1; private int mDisabledFlags2; @@ -144,9 +156,15 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback private OverviewProxyService mOverviewProxyService; - private boolean mIsOnDefaultDisplay = true; + private int mDisplayId; + private boolean mIsOnDefaultDisplay; public boolean mHomeBlockedThisTouch; + private Handler mHandler = Dependency.get(Dependency.MAIN_HANDLER); + + // last value sent to window manager + private int mLastDispatchedSystemUiVisibility = ~View.SYSTEM_UI_FLAG_VISIBLE; + private final OverviewProxyListener mOverviewProxyListener = new OverviewProxyListener() { @Override public void onConnectionChanged(boolean isConnected) { @@ -183,14 +201,20 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback } }; - private final ContextButtonListener mRotationButtonListener = new ContextButtonListener() { - @Override - public void onVisibilityChanged(ContextualButton button, boolean visible) { - if (visible) { - // If the button will actually become visible and the navbar is about to hide, - // tell the statusbar to keep it around for longer - mStatusBar.touchAutoHide(); - } + private final ContextButtonListener mRotationButtonListener = (button, visible) -> { + if (visible) { + // If the button will actually become visible and the navbar is about to hide, + // tell the statusbar to keep it around for longer + touchAutoHide(); + } + }; + + private final Runnable mAutoDim = () -> getBarTransitions().setAutoDim(true); + + private final Runnable mAutoHide = () -> { + int requested = mSystemUiVisibility & ~View.NAVIGATION_BAR_TRANSIENT; + if (mSystemUiVisibility != requested) { + notifySystemUiVisibilityChanged(requested); } }; @@ -251,7 +275,8 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback final Display display = view.getDisplay(); // It may not have display when running unit test. if (display != null) { - mIsOnDefaultDisplay = display.getDisplayId() == Display.DEFAULT_DISPLAY; + mDisplayId = display.getDisplayId(); + mIsOnDefaultDisplay = mDisplayId == Display.DEFAULT_DISPLAY; } mNavigationBarView.setComponents(mStatusBar.getPanel()); @@ -381,7 +406,7 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback if (mNavigationBarView != null) { mNavigationBarView.setNavigationIconHints(hints); } - mStatusBar.checkBarModes(); + checkBarModes(); } @Override @@ -426,23 +451,22 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback .onRotationProposal(rotation, winRotation, isValid); } - // Injected from StatusBar at creation. - public void setCurrentSysuiVisibility(int systemUiVisibility) { + /** + * Sets System UI flags to {@link NavigationBarFragment}. + * + * @see View#setSystemUiVisibility(int) + */ + public void setSystemUiVisibility(int systemUiVisibility) { mSystemUiVisibility = systemUiVisibility; - final int barMode = mStatusBar.computeBarMode(0, mSystemUiVisibility, - View.NAVIGATION_BAR_TRANSIENT, View.NAVIGATION_BAR_TRANSLUCENT, - View.NAVIGATION_BAR_TRANSPARENT); + final int barMode = computeBarMode(0, mSystemUiVisibility); if (barMode != -1) { mNavigationBarMode = barMode; } checkNavBarModes(); - mStatusBar.touchAutoHide(); + touchAutoHide(); - // TODO(115978725): Support light bar controller on external nav bars. - if (mLightBarController != null) { - mLightBarController.onNavigationVisibilityChanged(mSystemUiVisibility, 0 /* mask */, + mLightBarController.onNavigationVisibilityChanged(mSystemUiVisibility, 0 /* mask */, true /* nbModeChanged */, mNavigationBarMode); - } } @Override @@ -457,9 +481,7 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback // update navigation bar mode final int nbMode = getView() == null - ? -1 : mStatusBar.computeBarMode(oldVal, newVal, - View.NAVIGATION_BAR_TRANSIENT, View.NAVIGATION_BAR_TRANSLUCENT, - View.NAVIGATION_BAR_TRANSPARENT); + ? -1 : computeBarMode(oldVal, newVal); nbModeChanged = nbMode != -1; if (nbModeChanged) { if (mNavigationBarMode != nbMode) { @@ -470,14 +492,46 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback mNavigationBarMode = nbMode; checkNavBarModes(); } - mStatusBar.touchAutoHide(); + touchAutoHide(); + } + if ((vis & View.NAVIGATION_BAR_UNHIDE) != 0) { + mSystemUiVisibility &= ~View.NAVIGATION_BAR_UNHIDE; + } + + + // On the default display, just make StatusBar do this job. + if (!mIsOnDefaultDisplay) { + notifySystemUiVisibilityChanged(mSystemUiVisibility); } } + mLightBarController.onNavigationVisibilityChanged( + vis, mask, nbModeChanged, mNavigationBarMode); + } - // TODO(115978725): Support light bar controller on external nav bars. - if (mLightBarController != null) { - mLightBarController.onNavigationVisibilityChanged(vis, mask, nbModeChanged, - mNavigationBarMode); + private @TransitionMode int computeBarMode(int oldVis, int newVis) { + final int oldMode = barMode(oldVis); + final int newMode = barMode(newVis); + if (oldMode == newMode) { + return -1; // no mode change + } + return newMode; + } + + private @TransitionMode int barMode(int vis) { + final int lightsOutTransparent = + View.SYSTEM_UI_FLAG_LOW_PROFILE | View.NAVIGATION_BAR_TRANSIENT; + if ((vis & View.NAVIGATION_BAR_TRANSIENT) != 0) { + return MODE_SEMI_TRANSPARENT; + } else if ((vis & View.NAVIGATION_BAR_TRANSLUCENT) != 0) { + return MODE_TRANSLUCENT; + } else if ((vis & lightsOutTransparent) == lightsOutTransparent) { + return MODE_LIGHTS_OUT_TRANSPARENT; + } else if ((vis & View.NAVIGATION_BAR_TRANSPARENT) != 0) { + return MODE_TRANSPARENT; + } else if ((vis & View.SYSTEM_UI_FLAG_LOW_PROFILE) != 0) { + return MODE_LIGHTS_OUT; + } else { + return MODE_OPAQUE; } } @@ -511,7 +565,7 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback } } - // ----- Internal stuffz ----- + // ----- Internal stuff ----- private void refreshLayout(int layoutDirection) { if (mNavigationBarView != null) { @@ -610,7 +664,7 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback } private boolean onNavigationTouch(View v, MotionEvent event) { - mStatusBar.checkUserAutohide(event); + checkUserAutoHide(event); return false; } @@ -800,7 +854,79 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback mNavigationBarView.setAccessibilityButtonState(showAccessibilityButton, targetSelection); } - // ----- Methods that StatusBar talks to (should be minimized) ----- + private void touchAutoHide() { + // There is status bar on default display. Thus the hide animations should apply on both + // status/navigation bar. + if (mIsOnDefaultDisplay) { + mStatusBar.touchAutoHide(); + } else { + touchAutoHideInternal(); + } + } + + private void touchAutoHideInternal() { + // update transient bar autoHide. + if (isSemiTransparent()) { + scheduleAutoHide(); + } else { + cancelAutoHide(); + } + } + + private void checkUserAutoHide(MotionEvent event) { + // There is status bar on default display. Thus the hide animations should apply on both + // status/navigation bar. + if (mIsOnDefaultDisplay) { + mStatusBar.checkUserAutoHide(event); + } else { + checkUserAutoHideInternal(event); + } + } + + private void checkUserAutoHideInternal(MotionEvent event) { + if ((mSystemUiVisibility & View.NAVIGATION_BAR_TRANSIENT) != 0 + // a transient bar is revealed + && event.getAction() == MotionEvent.ACTION_OUTSIDE // touch outside the source bar. + && event.getX() == 0 && event.getY() == 0) { // a touch outside both bars. + userAutoHide(); + } + } + + private void userAutoHide() { + cancelAutoHide(); + mHandler.postDelayed(mAutoHide, 350); // longer than app gesture -> flag clear. + } + + private void cancelAutoHide() { + mHandler.removeCallbacks(mAutoHide); + } + + private void scheduleAutoHide() { + cancelAutoHide(); + mHandler.postDelayed(mAutoHide, AUTOHIDE_TIMEOUT_MS); + } + + private void notifySystemUiVisibilityChanged(int vis) { + try { + if (mLastDispatchedSystemUiVisibility != vis) { + mWindowManagerService.statusBarVisibilityChanged(mDisplayId, vis); + mLastDispatchedSystemUiVisibility = vis; + } + } catch (RemoteException ex) { + } + } + + // ----- Methods that DisplayNavigationBarController talks to ----- + + /** Applys auto dimming animation on navigation bar when touched. */ + public void touchAutoDim() { + getBarTransitions().setAutoDim(false); + mHandler.removeCallbacks(mAutoDim); + int state = Dependency.get(StatusBarStateController.class).getState(); + if (state != StatusBarState.KEYGUARD && state != StatusBarState.SHADE_LOCKED) { + mHandler.postDelayed(mAutoDim, AUTOHIDE_TIMEOUT_MS); + } + } public void setLightBarController(LightBarController lightBarController) { mLightBarController = lightBarController; @@ -811,19 +937,42 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback return mNavigationBarMode == MODE_SEMI_TRANSPARENT; } + private void checkBarModes() { + // We only have status bar on default display now. + if (mIsOnDefaultDisplay) { + mStatusBar.checkBarModes(); + } else { + checkNavBarModes(); + } + } + + /** + * Checks current navigation bar mode and make transitions. + */ + public void checkNavBarModes() { + final boolean anim = mStatusBar.isDeviceInteractive() + && mNavigationBarWindowState != WINDOW_STATE_HIDDEN; + mNavigationBarView.getBarTransitions().transitionTo(mNavigationBarMode, anim); + } + public void disableAnimationsDuringHide(long delay) { mNavigationBarView.setLayoutTransitionsEnabled(false); mNavigationBarView.postDelayed(() -> mNavigationBarView.setLayoutTransitionsEnabled(true), delay + StackStateAnimator.ANIMATION_DURATION_GO_TO_FULL_SHADE); } - public BarTransitions getBarTransitions() { - return mNavigationBarView.getBarTransitions(); + /** + * Performs transitions on navigation bar. + * + * @param barMode transition bar mode. + * @param animate shows animations if {@code true}. + */ + public void transitionTo(@TransitionMode int barMode, boolean animate) { + getBarTransitions().transitionTo(barMode, animate); } - public void checkNavBarModes() { - mStatusBar.checkBarMode(mNavigationBarMode, - mNavigationBarWindowState, mNavigationBarView.getBarTransitions()); + private BarTransitions getBarTransitions() { + return mNavigationBarView.getBarTransitions(); } public void finishBarAnimations() { @@ -873,12 +1022,11 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback if (Intent.ACTION_USER_SWITCHED.equals(action)) { // The accessibility settings may be different for the new user updateAccessibilityServicesState(mAccessibilityManager); - }; + } } }; public static View create(Context context, FragmentListener listener) { - final int displayId = context.getDisplay().getDisplayId(); WindowManager.LayoutParams lp = new WindowManager.LayoutParams( LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.TYPE_NAVIGATION_BAR, @@ -890,7 +1038,7 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback | WindowManager.LayoutParams.FLAG_SLIPPERY, PixelFormat.TRANSLUCENT); lp.token = new Binder(); - lp.setTitle("NavigationBar" + displayId); + lp.setTitle("NavigationBar" + context.getDisplayId()); lp.accessibilityTitle = context.getString(R.string.nav_bar); lp.windowAnimations = 0; 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 8c17922a4f0c..2fc7b78c0ca3 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java @@ -282,6 +282,11 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav } @Override + public void onHomeButtonVisibilityChanged(boolean visible) { + getHomeButton().setVisibility(visible ? VISIBLE : GONE); + } + + @Override public void onColorAdaptChanged(boolean enabled) { if (enabled) { mColorAdaptionController.start(); @@ -672,6 +677,7 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav // TODO(b/113914868): investigation log for disappearing home button Log.i(TAG, "updateNavButtonIcons (b/113914868): home disabled=" + disableHome + " mDisabledFlags=" + mDisabledFlags); + disableHome |= mPrototypeController.hideHomeButton(); // Always disable recents when alternate car mode UI is active and for secondary displays. boolean disableRecent = isRecentsButtonDisabled(); @@ -945,6 +951,7 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav // TODO(b/112934365): remove after prototype finished, only needed to escape from pin getBackButton().setVisibility(VISIBLE); + getHomeButton().setVisibility(VISIBLE); } else { mScreenPinningNotify.showPinningExitToast(); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationPrototypeController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationPrototypeController.java index 40ac79376b06..fb6254b0e4be 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationPrototypeController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationPrototypeController.java @@ -34,6 +34,7 @@ import java.lang.annotation.RetentionPolicy; */ public class NavigationPrototypeController extends ContentObserver { private static final String HIDE_BACK_BUTTON_SETTING = "quickstepcontroller_hideback"; + private static final String HIDE_HOME_BUTTON_SETTING = "quickstepcontroller_hidehome"; static final String NAVBAR_EXPERIMENTS_DISABLED = "navbarexperiments_disabled"; private final String GESTURE_MATCH_SETTING = "quickstepcontroller_gesture_match_map"; @@ -73,6 +74,7 @@ public class NavigationPrototypeController extends ContentObserver { */ public void register() { registerObserver(HIDE_BACK_BUTTON_SETTING); + registerObserver(HIDE_HOME_BUTTON_SETTING); registerObserver(GESTURE_MATCH_SETTING); registerObserver(NAV_COLOR_ADAPT_ENABLE_SETTING); } @@ -88,22 +90,20 @@ public class NavigationPrototypeController extends ContentObserver { public void onChange(boolean selfChange, Uri uri) { super.onChange(selfChange, uri); if (!selfChange && mListener != null) { - try { - final String path = uri.getPath(); - if (path.endsWith(GESTURE_MATCH_SETTING)) { - // Get the settings gesture map corresponding to each action - // {@see updateSwipeLTRBackSetting} - updateSwipeLTRBackSetting(); - mListener.onGestureRemap(mActionMap); - } else if (path.endsWith(HIDE_BACK_BUTTON_SETTING)) { - mListener.onBackButtonVisibilityChanged( - !getGlobalBool(HIDE_BACK_BUTTON_SETTING)); - } else if (path.endsWith(NAV_COLOR_ADAPT_ENABLE_SETTING)) { - mListener.onColorAdaptChanged( - NavBarTintController.isEnabled(mContext)); - } - } catch (SettingNotFoundException e) { - e.printStackTrace(); + final String path = uri.getPath(); + if (path.endsWith(GESTURE_MATCH_SETTING)) { + // Get the settings gesture map corresponding to each action + // {@see updateSwipeLTRBackSetting} + updateSwipeLTRBackSetting(); + mListener.onGestureRemap(mActionMap); + } else if (path.endsWith(HIDE_BACK_BUTTON_SETTING)) { + mListener.onBackButtonVisibilityChanged( + !getGlobalBool(HIDE_BACK_BUTTON_SETTING, false)); + } else if (path.endsWith(HIDE_HOME_BUTTON_SETTING)) { + mListener.onHomeButtonVisibilityChanged(!hideHomeButton()); + } else if (path.endsWith(NAV_COLOR_ADAPT_ENABLE_SETTING)) { + mListener.onColorAdaptChanged( + NavBarTintController.isEnabled(mContext)); } } } @@ -117,6 +117,13 @@ public class NavigationPrototypeController extends ContentObserver { } /** + * @return if home button should be invisible + */ + boolean hideHomeButton() { + return getGlobalBool(HIDE_HOME_BUTTON_SETTING, false /* default */); + } + + /** * Since Settings.Global cannot pass arrays, use a string to represent each character as a * gesture map to actions corresponding to {@see GestureAction}. The number is represented as: * Number: [up] [down] [left] [right] @@ -131,8 +138,8 @@ public class NavigationPrototypeController extends ContentObserver { } } - private boolean getGlobalBool(String name) throws SettingNotFoundException { - return Settings.Global.getInt(mContext.getContentResolver(), name) == 1; + private boolean getGlobalBool(String name, boolean defaultVal) { + return Settings.Global.getInt(mContext.getContentResolver(), name, defaultVal ? 1 : 0) == 1; } private void registerObserver(String name) { @@ -143,6 +150,7 @@ public class NavigationPrototypeController extends ContentObserver { public interface OnPrototypeChangedListener { void onGestureRemap(@GestureAction int[] actions); void onBackButtonVisibilityChanged(boolean visible); + void onHomeButtonVisibilityChanged(boolean visible); void onColorAdaptChanged(boolean enabled); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelper.java index 9fe30db03ad7..3839ed5d5d88 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelper.java @@ -17,6 +17,7 @@ package com.android.systemui.statusbar.phone; import android.annotation.NonNull; +import android.annotation.Nullable; import android.app.Notification; import android.os.SystemClock; import android.service.notification.StatusBarNotification; @@ -218,7 +219,7 @@ public class NotificationGroupAlertTransferHelper implements OnHeadsUpChangedLis @Override public void onEntryRemoved( - Entry entry, + @Nullable Entry entry, String key, StatusBarNotification old, NotificationVisibility visibility, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java index e40835fb8fd0..056c8a7f5f5e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java @@ -19,14 +19,14 @@ import com.android.internal.util.ContrastColorUtil; import com.android.internal.widget.ViewClippingUtil; import com.android.systemui.Dependency; import com.android.systemui.R; +import com.android.systemui.plugins.DarkIconDispatcher; +import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver; import com.android.systemui.statusbar.NotificationShelf; import com.android.systemui.statusbar.StatusBarIconView; import com.android.systemui.statusbar.notification.NotificationData; import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.NotificationUtils; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; -import com.android.systemui.statusbar.policy.DarkIconDispatcher; -import com.android.systemui.statusbar.policy.DarkIconDispatcher.DarkReceiver; import com.android.systemui.tuner.TunerService; import java.util.ArrayList; 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 1b18c6cf8440..fd34ac553c8a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java @@ -2803,6 +2803,11 @@ public class NotificationPanelView extends PanelView implements if (animatePulse) { mAnimateNextPositionUpdate = true; } + // Do not animate the clock when waking up from a pulse. + // The height callback will take care of pushing the clock to the right position. + if (!mPulsing && !mDozing) { + mAnimateNextPositionUpdate = false; + } mNotificationStackScroller.setPulsing(pulsing, animatePulse); mKeyguardStatusView.setPulsing(pulsing, animatePulse); mKeyguardBottomArea.setPulsing(pulsing, animatePulse); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java index 2129835945d7..7a3d03fec025 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java @@ -43,9 +43,9 @@ import android.widget.LinearLayout; import com.android.systemui.Dependency; import com.android.systemui.EventLogTags; import com.android.systemui.R; +import com.android.systemui.plugins.DarkIconDispatcher; +import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver; import com.android.systemui.statusbar.CommandQueue; -import com.android.systemui.statusbar.policy.DarkIconDispatcher; -import com.android.systemui.statusbar.policy.DarkIconDispatcher.DarkReceiver; import java.util.Objects; 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 e1a6cd3099c1..9f0eec41bafc 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java @@ -37,6 +37,7 @@ import static com.android.systemui.statusbar.phone.BarTransitions.MODE_SEMI_TRAN import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSLUCENT; import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSPARENT; import static com.android.systemui.statusbar.phone.BarTransitions.MODE_WARNING; +import static com.android.systemui.statusbar.phone.BarTransitions.TransitionMode; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; @@ -71,7 +72,6 @@ import android.content.res.Resources; import android.graphics.Point; import android.graphics.PointF; import android.graphics.Rect; -import android.hardware.display.DisplayManager; import android.media.AudioAttributes; import android.metrics.LogMaker; import android.net.Uri; @@ -155,6 +155,8 @@ import com.android.systemui.keyguard.KeyguardViewMediator; import com.android.systemui.keyguard.ScreenLifecycle; import com.android.systemui.keyguard.WakefulnessLifecycle; import com.android.systemui.plugins.ActivityStarter; +import com.android.systemui.plugins.DarkIconDispatcher; +import com.android.systemui.plugins.PluginDependencyProvider; import com.android.systemui.plugins.qs.QS; import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper.SnoozeOption; import com.android.systemui.qs.QSFragment; @@ -168,11 +170,11 @@ import com.android.systemui.statusbar.AmbientPulseManager; import com.android.systemui.statusbar.BackDropView; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.CrossFadeHelper; -import com.android.systemui.statusbar.DisplayNavigationBarController; import com.android.systemui.statusbar.EmptyShadeView; import com.android.systemui.statusbar.GestureRecorder; import com.android.systemui.statusbar.KeyboardShortcuts; import com.android.systemui.statusbar.KeyguardIndicationController; +import com.android.systemui.statusbar.NavigationBarController; import com.android.systemui.statusbar.NotificationListener; import com.android.systemui.statusbar.NotificationLockscreenUserManager; import com.android.systemui.statusbar.NotificationMediaManager; @@ -204,7 +206,6 @@ import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChang import com.android.systemui.statusbar.policy.BrightnessMirrorController; import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener; -import com.android.systemui.statusbar.policy.DarkIconDispatcher; import com.android.systemui.statusbar.policy.DeviceProvisionedController; import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener; import com.android.systemui.statusbar.policy.ExtensionController; @@ -446,18 +447,18 @@ public class StatusBar extends SystemUI implements DemoMode, protected final H mHandler = createHandler(); private int mInteractingWindows; - private boolean mAutohideSuspended; - private int mStatusBarMode; + private boolean mAutoHideSuspended; + private @TransitionMode int mStatusBarMode; private ViewMediatorCallback mKeyguardViewMediatorCallback; protected ScrimController mScrimController; protected DozeScrimController mDozeScrimController; private final UiOffloadThread mUiOffloadThread = Dependency.get(UiOffloadThread.class); - private final Runnable mAutohide = () -> { + private final Runnable mAutoHide = () -> { int requested = mSystemUiVisibility & ~STATUS_OR_NAV_TRANSIENT; if (mSystemUiVisibility != requested) { - notifyUiVisibilityChanged(requested); + notifySystemUiVisibilityChanged(requested); } }; @@ -584,11 +585,6 @@ public class StatusBar extends SystemUI implements DemoMode, } }; - protected DisplayManager mDisplayManager; - - private NavigationBarFragment mNavigationBar; - private View mNavigationBarView; - private HeadsUpAppearanceController mHeadsUpAppearanceController; private boolean mVibrateOnOpening; private VibratorHelper mVibratorHelper; @@ -642,7 +638,7 @@ public class StatusBar extends SystemUI implements DemoMode, mKeyguardViewMediator = getComponent(KeyguardViewMediator.class); mColorExtractor = Dependency.get(SysuiColorExtractor.class); mDeviceProvisionedController = Dependency.get(DeviceProvisionedController.class); - mNavigationBarController = Dependency.get(DisplayNavigationBarController.class); + mNavigationBarController = Dependency.get(NavigationBarController.class); mBubbleController = Dependency.get(BubbleController.class); mBubbleController.setExpandListener(mBubbleExpandListener); KeyguardSliceProvider sliceProvider = KeyguardSliceProvider.getAttachedInstance(); @@ -808,6 +804,9 @@ public class StatusBar extends SystemUI implements DemoMode, mNotificationIconAreaController.setupShelf(mNotificationShelf); Dependency.get(DarkIconDispatcher.class).addDarkReceiver(mNotificationIconAreaController); + // Allow plugins to reference DarkIconDispatcher + Dependency.get(PluginDependencyProvider.class) + .allowPluginDependency(DarkIconDispatcher.class); FragmentHostManager.get(mStatusBarWindow) .addTagListener(CollapsedStatusBarFragment.TAG, (tag, fragment) -> { CollapsedStatusBarFragment statusBarFragment = @@ -903,11 +902,7 @@ public class StatusBar extends SystemUI implements DemoMode, } }); - // TODO(115978725): Support light bar controller on external nav bars. mLightBarController = Dependency.get(LightBarController.class); - if (mNavigationBar != null) { - mNavigationBar.setLightBarController(mLightBarController); - } ScrimView scrimBehind = mStatusBarWindow.findViewById(R.id.scrim_behind); ScrimView scrimInFront = mStatusBarWindow.findViewById(R.id.scrim_in_front); @@ -1093,25 +1088,10 @@ public class StatusBar extends SystemUI implements DemoMode, } } + // TODO(b/117478341): This was left such that CarStatusBar can override this method. + // Try to remove this. protected void createNavigationBar() { - try { - // TODO(117478341): Move this into DisplayNavigationBarController#createNavigationBars - // for-loop. We will also move the whole navigation bar logic together. - final boolean showNav = mWindowManagerService.hasNavigationBar(DEFAULT_DISPLAY); - if (DEBUG) Log.v(TAG, "hasNavigationBar=" + showNav); - if (!showNav) return; - - mNavigationBarView = NavigationBarFragment.create(mContext, (tag, fragment) -> { - mNavigationBar = (NavigationBarFragment) fragment; - if (mLightBarController != null) { - mNavigationBar.setLightBarController(mLightBarController); - } - mNavigationBar.setCurrentSysuiVisibility(mSystemUiVisibility); - }); - } catch (RemoteException ex) { - // no window manager? good luck with that - } - mNavigationBarController.createNavigationBars(); + mNavigationBarController.createNavigationBars(true /* includeDefaultDisplay */); } /** @@ -1120,7 +1100,7 @@ public class StatusBar extends SystemUI implements DemoMode, */ protected View.OnTouchListener getStatusBarWindowTouchListener() { return (v, event) -> { - checkUserAutohide(event); + checkUserAutoHide(event); mRemoteInputManager.checkRemoteInputOutside(event); if (event.getAction() == MotionEvent.ACTION_DOWN) { if (mExpandedVisible) { @@ -2101,7 +2081,7 @@ public class StatusBar extends SystemUI implements DemoMode, } // send updated sysui visibility to window manager - notifyUiVisibilityChanged(mSystemUiVisibility); + notifySystemUiVisibilityChanged(mSystemUiVisibility); } mLightBarController.onSystemUiVisibilityChanged(fullscreenStackVis, dockedStackVis, @@ -2131,52 +2111,55 @@ public class StatusBar extends SystemUI implements DemoMode, } } - // TODO(115978725): Support auto hide on external nav bars. void touchAutoHide() { - // update transient bar autohide - if (mStatusBarMode == MODE_SEMI_TRANSPARENT || (mNavigationBar != null - && mNavigationBar.isSemiTransparent())) { - scheduleAutohide(); + // update transient bar auto hide + if (mStatusBarMode == MODE_SEMI_TRANSPARENT + || mNavigationBarController.isSemiTransparent(DEFAULT_DISPLAY)) { + scheduleAutoHide(); } else { - cancelAutohide(); + cancelAutoHide(); } } - protected int computeStatusBarMode(int oldVal, int newVal) { - return computeBarMode(oldVal, newVal, View.STATUS_BAR_TRANSIENT, - View.STATUS_BAR_TRANSLUCENT, View.STATUS_BAR_TRANSPARENT); + protected @TransitionMode int computeStatusBarMode(int oldVal, int newVal) { + return computeBarMode(oldVal, newVal); } protected BarTransitions getStatusBarTransitions() { return mStatusBarView.getBarTransitions(); } - protected int computeBarMode(int oldVis, int newVis, - int transientFlag, int translucentFlag, int transparentFlag) { - final int oldMode = barMode(oldVis, transientFlag, translucentFlag, transparentFlag); - final int newMode = barMode(newVis, transientFlag, translucentFlag, transparentFlag); + protected @TransitionMode int computeBarMode(int oldVis, int newVis) { + final int oldMode = barMode(oldVis); + final int newMode = barMode(newVis); if (oldMode == newMode) { return -1; // no mode change } return newMode; } - private int barMode(int vis, int transientFlag, int translucentFlag, int transparentFlag) { - int lightsOutTransparent = View.SYSTEM_UI_FLAG_LOW_PROFILE | transparentFlag; - return (vis & transientFlag) != 0 ? MODE_SEMI_TRANSPARENT - : (vis & translucentFlag) != 0 ? MODE_TRANSLUCENT - : (vis & lightsOutTransparent) == lightsOutTransparent ? MODE_LIGHTS_OUT_TRANSPARENT - : (vis & transparentFlag) != 0 ? MODE_TRANSPARENT - : (vis & View.SYSTEM_UI_FLAG_LOW_PROFILE) != 0 ? MODE_LIGHTS_OUT - : MODE_OPAQUE; + private @TransitionMode int barMode(int vis) { + int lightsOutTransparent = View.SYSTEM_UI_FLAG_LOW_PROFILE | View.STATUS_BAR_TRANSPARENT; + if ((vis & View.STATUS_BAR_TRANSIENT) != 0) { + return MODE_SEMI_TRANSPARENT; + } else if ((vis & View.STATUS_BAR_TRANSLUCENT) != 0) { + return MODE_TRANSLUCENT; + } else if ((vis & lightsOutTransparent) == lightsOutTransparent) { + return MODE_LIGHTS_OUT_TRANSPARENT; + } else if ((vis & View.STATUS_BAR_TRANSPARENT) != 0) { + return MODE_TRANSPARENT; + } else if ((vis & View.SYSTEM_UI_FLAG_LOW_PROFILE) != 0) { + return MODE_LIGHTS_OUT; + } else { + return MODE_OPAQUE; + } } - // TODO(115978725): Support animations on external nav bars. void checkBarModes() { if (mDemoMode) return; if (mStatusBarView != null) checkBarMode(mStatusBarMode, mStatusBarWindowState, getStatusBarTransitions()); - if (mNavigationBar != null) mNavigationBar.checkNavBarModes(); + mNavigationBarController.checkNavBarModes(DEFAULT_DISPLAY); mNoAnimationOnNextBarModeChange = false; } @@ -2185,20 +2168,17 @@ public class StatusBar extends SystemUI implements DemoMode, mNotificationPanel.setQsScrimEnabled(scrimEnabled); } - void checkBarMode(int mode, int windowState, BarTransitions transitions) { + void checkBarMode(@TransitionMode int mode, int windowState, BarTransitions transitions) { final boolean anim = !mNoAnimationOnNextBarModeChange && mDeviceInteractive && windowState != WINDOW_STATE_HIDDEN; transitions.transitionTo(mode, anim); } - // TODO(115978725): Support animations on external nav bars. private void finishBarAnimations() { if (mStatusBarView != null) { mStatusBarView.getBarTransitions().finishAnimations(); } - if (mNavigationBar != null) { - mNavigationBar.finishBarAnimations(); - } + mNavigationBarController.finishBarAnimations(DEFAULT_DISPLAY); } private final Runnable mCheckBarModes = this::checkBarModes; @@ -2209,13 +2189,13 @@ public class StatusBar extends SystemUI implements DemoMode, ? (mInteractingWindows | barWindow) : (mInteractingWindows & ~barWindow); if (mInteractingWindows != 0) { - suspendAutohide(); + suspendAutoHide(); } else { - resumeSuspendedAutohide(); + resumeSuspendedAutoHide(); } // manually dismiss the volume panel when interacting with the nav bar if (changing && interacting && barWindow == StatusBarManager.WINDOW_NAVIGATION_BAR) { - touchAutoDim(); + mNavigationBarController.touchAutoDim(DEFAULT_DISPLAY); dismissVolumeDialog(); } checkBarModes(); @@ -2227,57 +2207,42 @@ public class StatusBar extends SystemUI implements DemoMode, } } - private void resumeSuspendedAutohide() { - if (mAutohideSuspended) { - scheduleAutohide(); + private void resumeSuspendedAutoHide() { + if (mAutoHideSuspended) { + scheduleAutoHide(); mHandler.postDelayed(mCheckBarModes, 500); // longer than home -> launcher } } - private void suspendAutohide() { - mHandler.removeCallbacks(mAutohide); + private void suspendAutoHide() { + mHandler.removeCallbacks(mAutoHide); mHandler.removeCallbacks(mCheckBarModes); - mAutohideSuspended = (mSystemUiVisibility & STATUS_OR_NAV_TRANSIENT) != 0; + mAutoHideSuspended = (mSystemUiVisibility & STATUS_OR_NAV_TRANSIENT) != 0; } - private void cancelAutohide() { - mAutohideSuspended = false; - mHandler.removeCallbacks(mAutohide); + private void cancelAutoHide() { + mAutoHideSuspended = false; + mHandler.removeCallbacks(mAutoHide); } - private void scheduleAutohide() { - cancelAutohide(); - mHandler.postDelayed(mAutohide, AUTOHIDE_TIMEOUT_MS); + private void scheduleAutoHide() { + cancelAutoHide(); + mHandler.postDelayed(mAutoHide, AUTOHIDE_TIMEOUT_MS); } - public void touchAutoDim() { - if (mNavigationBar != null) { - mNavigationBar.getBarTransitions().setAutoDim(false); - } - mHandler.removeCallbacks(mAutoDim); - - // Do not dim the navigation buttons if the its tint is controlled by the bar's background - if (NavBarTintController.isEnabled(mContext)) { - return; - } - if (mState != StatusBarState.KEYGUARD && mState != StatusBarState.SHADE_LOCKED) { - mHandler.postDelayed(mAutoDim, AUTOHIDE_TIMEOUT_MS); - } - } - - void checkUserAutohide(MotionEvent event) { + void checkUserAutoHide(MotionEvent event) { if ((mSystemUiVisibility & STATUS_OR_NAV_TRANSIENT) != 0 // a transient bar is revealed && event.getAction() == MotionEvent.ACTION_OUTSIDE // touch outside the source bar && event.getX() == 0 && event.getY() == 0 // a touch outside both bars && !mRemoteInputManager.getController() .isRemoteInputActive()) { // not due to typing in IME - userAutohide(); + userAutoHide(); } } - private void userAutohide() { - cancelAutohide(); - mHandler.postDelayed(mAutohide, 350); // longer than app gesture -> flag clear + private void userAutoHide() { + cancelAutoHide(); + mHandler.postDelayed(mAutoHide, 350); // longer than app gesture -> flag clear } private boolean areLightsOn() { @@ -2296,11 +2261,10 @@ public class StatusBar extends SystemUI implements DemoMode, } } - private void notifyUiVisibilityChanged(int vis) { + private void notifySystemUiVisibilityChanged(int vis) { try { if (mLastDispatchedSystemUiVisibility != vis) { - // TODO (b/117478341): Resolve one status bar/ navigation bar assumption - mWindowManagerService.statusBarVisibilityChanged(Display.DEFAULT_DISPLAY, vis); + mWindowManagerService.statusBarVisibilityChanged(DEFAULT_DISPLAY, vis); mLastDispatchedSystemUiVisibility = vis; } } catch (RemoteException ex) { @@ -2925,10 +2889,6 @@ public class StatusBar extends SystemUI implements DemoMode, mWindowManager.removeViewImmediate(mStatusBarWindow); mStatusBarWindow = null; } - if (mNavigationBarView != null) { - mWindowManager.removeViewImmediate(mNavigationBarView); - mNavigationBarView = null; - } mNavigationBarController.destroy(); mContext.unregisterReceiver(mBroadcastReceiver); mContext.unregisterReceiver(mDemoReceiver); @@ -2998,15 +2958,12 @@ public class StatusBar extends SystemUI implements DemoMode, "transparent".equals(mode) ? MODE_TRANSPARENT : "warning".equals(mode) ? MODE_WARNING : -1; - // TODO(115978725): Support external nav bar transitions if (barMode != -1) { boolean animate = true; if (mStatusBarView != null) { mStatusBarView.getBarTransitions().transitionTo(barMode, animate); } - if (mNavigationBar != null) { - mNavigationBar.getBarTransitions().transitionTo(barMode, animate); - } + mNavigationBarController.transitionTo(DEFAULT_DISPLAY, barMode, animate); } } if (modeChange || command.equals(COMMAND_OPERATOR)) { @@ -3232,12 +3189,9 @@ public class StatusBar extends SystemUI implements DemoMode, mDraggedDownEntry = null; } - // TODO(115978725): Support animations on external nav bars. // Disable layout transitions in navbar for this transition because the load is just // too heavy for the CPU and GPU on any device. - if (mNavigationBar != null) { - mNavigationBar.disableAnimationsDuringHide(delay); - } + mNavigationBarController.disableAnimationsDuringHide(DEFAULT_DISPLAY, delay); } else if (!mNotificationPanel.isCollapsing()) { instantCollapseNotificationPanel(); } @@ -3467,7 +3421,7 @@ public class StatusBar extends SystemUI implements DemoMode, updateReportRejectedTouchVisibility(); updateDozing(); updateTheme(); - touchAutoDim(); + mNavigationBarController.touchAutoDim(DEFAULT_DISPLAY); Trace.beginSection("StatusBar#updateKeyguardState"); if (mState == StatusBarState.KEYGUARD) { mKeyguardIndicationController.setVisible(true); @@ -3588,11 +3542,7 @@ public class StatusBar extends SystemUI implements DemoMode, // TODO: Figure out way to remove these. public NavigationBarView getNavigationBarView() { - return (mNavigationBar != null ? (NavigationBarView) mNavigationBar.getView() : null); - } - - public View getNavigationBarWindow() { - return mNavigationBarView; + return mNavigationBarController.getDefaultNavigationBarView(); } /** @@ -4174,7 +4124,7 @@ public class StatusBar extends SystemUI implements DemoMode, private DeviceProvisionedController mDeviceProvisionedController = Dependency.get(DeviceProvisionedController.class); - protected DisplayNavigationBarController mNavigationBarController; + protected NavigationBarController mNavigationBarController; // UI-specific methods @@ -4502,13 +4452,6 @@ public class StatusBar extends SystemUI implements DemoMode, } // End Extra BaseStatusBarMethods. - // TODO(115978725): Handle dimming for external nav bars - private final Runnable mAutoDim = () -> { - if (mNavigationBar != null) { - mNavigationBar.getBarTransitions().setAutoDim(true); - } - }; - public NotificationGutsManager getGutsManager() { return mGutsManager; } 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 26c9d288494d..2e2ff1a5750e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java @@ -38,14 +38,14 @@ 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.plugins.DarkIconDispatcher; +import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver; 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; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java index 7b6fef3ad82b..7b7bcb448022 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java @@ -20,6 +20,7 @@ import static com.android.systemui.statusbar.phone.StatusBar.DEBUG; import static com.android.systemui.statusbar.phone.StatusBar.MULTIUSER_DEBUG; import static com.android.systemui.statusbar.phone.StatusBar.SPEW; +import android.annotation.Nullable; import android.app.KeyguardManager; import android.content.Context; import android.content.pm.PackageManager; @@ -193,7 +194,7 @@ public class StatusBarNotificationPresenter implements NotificationPresenter, @Override public void onEntryRemoved( - Entry entry, + @Nullable Entry entry, String key, StatusBarNotification old, NotificationVisibility visibility, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SysuiDarkIconDispatcher.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SysuiDarkIconDispatcher.java new file mode 100644 index 000000000000..d53772127601 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SysuiDarkIconDispatcher.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.systemui.statusbar.phone; + +import com.android.systemui.Dumpable; +import com.android.systemui.plugins.DarkIconDispatcher; + +/** + * Dispatches events to {@link DarkReceiver}s about changes in darkness, tint area + * and dark intensity. + */ +public interface SysuiDarkIconDispatcher extends DarkIconDispatcher, Dumpable { + + /** + * @return LightBarTransitionsController + */ + LightBarTransitionsController getTransitionsController(); +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java index aafdcd50b8e8..5eb3e8950690 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java @@ -44,11 +44,12 @@ import com.android.systemui.Dependency; import com.android.systemui.FontSizeUtils; import com.android.systemui.R; import com.android.systemui.SysUiServiceProvider; +import com.android.systemui.plugins.DarkIconDispatcher; +import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver; import com.android.systemui.settings.CurrentUserTracker; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.phone.StatusBarIconController; import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener; -import com.android.systemui.statusbar.policy.DarkIconDispatcher.DarkReceiver; import com.android.systemui.tuner.TunerService; import com.android.systemui.tuner.TunerService.Tunable; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeadZone.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeadZone.java index 4a1175489c5e..54502e41ca64 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeadZone.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeadZone.java @@ -24,10 +24,10 @@ import android.util.Slog; import android.view.MotionEvent; import android.view.Surface; +import com.android.systemui.Dependency; import com.android.systemui.R; -import com.android.systemui.SysUiServiceProvider; +import com.android.systemui.statusbar.NavigationBarController; import com.android.systemui.statusbar.phone.NavigationBarView; -import com.android.systemui.statusbar.phone.StatusBar; /** * The "dead zone" consumes unintentional taps along the top edge of the navigation bar. @@ -44,7 +44,7 @@ public class DeadZone { public static final int VERTICAL = 1; // Consume taps along the left edge. private static final boolean CHATTY = true; // print to logcat when we eat a click - private final StatusBar mStatusBar; + private final NavigationBarController mNavBarController; private final NavigationBarView mNavigationBarView; private boolean mShouldFlash; @@ -58,6 +58,7 @@ public class DeadZone { private boolean mVertical; private long mLastPokeTime; private int mDisplayRotation; + private final int mDisplayId; private final Runnable mDebugFlash = new Runnable() { @Override @@ -68,8 +69,8 @@ public class DeadZone { public DeadZone(NavigationBarView view) { mNavigationBarView = view; - mStatusBar = SysUiServiceProvider.getComponent(mNavigationBarView.getContext(), - StatusBar.class); + mNavBarController = Dependency.get(NavigationBarController.class); + mDisplayId = view.getContext().getDisplayId(); onConfigurationChanged(HORIZONTAL); } @@ -133,7 +134,7 @@ public class DeadZone { if (DEBUG) { Slog.v(TAG, this + " ACTION_DOWN: " + event.getX() + "," + event.getY()); } - if (mStatusBar != null) mStatusBar.touchAutoDim(); + mNavBarController.touchAutoDim(mDisplayId); int size = (int) getSize(event.getEventTime()); // In the vertical orientation consume taps along the left edge. // In horizontal orientation consume taps along the top edge. 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 2c756ceb1b48..d4049826a50a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java @@ -33,6 +33,7 @@ import android.os.AsyncTask; import android.os.Bundle; import android.os.SystemClock; import android.util.AttributeSet; +import android.util.Log; import android.util.TypedValue; import android.view.HapticFeedbackConstants; import android.view.InputDevice; @@ -304,6 +305,10 @@ public class KeyButtonView extends ImageView implements ButtonInterface { .setSubtype(mCode) .addTaggedData(MetricsEvent.FIELD_NAV_ACTION, action) .addTaggedData(MetricsEvent.FIELD_FLAGS, flags)); + // TODO(b/122195391): Added logs to make sure sysui is sending back button events + if (mCode == KeyEvent.KEYCODE_BACK && flags != KeyEvent.FLAG_LONG_PRESS) { + Log.i(TAG, "Back button event: " + KeyEvent.actionToString(action)); + } final int repeatCount = (flags & KeyEvent.FLAG_LONG_PRESS) != 0 ? 1 : 0; final KeyEvent ev = new KeyEvent(mDownTime, when, action, mCode, repeatCount, 0, KeyCharacterMap.VIRTUAL_KEYBOARD, 0, diff --git a/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java b/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java index b84f85bdbc4c..122b094558ea 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java @@ -16,13 +16,13 @@ package com.android.systemui; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY; -import static com.android.systemui.ScreenDecorations.rectsToRegion; +import static com.android.systemui.ScreenDecorations.rectsToRegion; import static com.android.systemui.tuner.TunablePadding.FLAG_END; import static com.android.systemui.tuner.TunablePadding.FLAG_START; import static org.hamcrest.Matchers.is; -import static org.junit.Assert.assertThat; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyString; @@ -87,7 +87,6 @@ public class ScreenDecorationsTest extends SysuiTestCase { mWindowManager = mock(WindowManager.class); mView = spy(new StatusBarWindowView(mContext, null)); when(mStatusBar.getStatusBarWindow()).thenReturn(mView); - when(mStatusBar.getNavigationBarWindow()).thenReturn(mView); mContext.putComponent(StatusBar.class, mStatusBar); Display display = mContext.getSystemService(WindowManager.class).getDefaultDisplay(); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationLoggerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationLoggerTest.java index 7b96518ad13f..983ca837b639 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationLoggerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationLoggerTest.java @@ -42,6 +42,7 @@ import com.android.systemui.UiOffloadThread; import com.android.systemui.statusbar.NotificationListener; import com.android.systemui.statusbar.StatusBarStateController; import com.android.systemui.statusbar.notification.NotificationData; +import com.android.systemui.statusbar.notification.NotificationEntryListener; import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import com.android.systemui.statusbar.notification.stack.NotificationListContainer; @@ -51,6 +52,8 @@ import com.google.android.collect.Lists; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.MockitoAnnotations; @@ -72,9 +75,11 @@ public class NotificationLoggerTest extends SysuiTestCase { // Dependency mocks: @Mock private NotificationEntryManager mEntryManager; @Mock private NotificationListener mListener; + @Captor private ArgumentCaptor<NotificationEntryListener> mEntryListenerCaptor; private NotificationData.Entry mEntry; private TestableNotificationLogger mLogger; + private NotificationEntryListener mNotificationEntryListener; private ConcurrentLinkedQueue<AssertionError> mErrorQueue = new ConcurrentLinkedQueue<>(); @Before @@ -94,6 +99,8 @@ public class NotificationLoggerTest extends SysuiTestCase { mLogger = new TestableNotificationLogger(mListener, Dependency.get(UiOffloadThread.class), mEntryManager, mock(StatusBarStateController.class), mBarService); mLogger.setUpWithContainer(mListContainer); + verify(mEntryManager).addNotificationEntryListener(mEntryListenerCaptor.capture()); + mNotificationEntryListener = mEntryListenerCaptor.getValue(); } @Test @@ -152,6 +159,11 @@ public class NotificationLoggerTest extends SysuiTestCase { verify(mBarService, times(1)).onNotificationVisibilityChanged(any(), any()); } + @Test + public void testHandleNullEntryOnEntryRemoved() { + mNotificationEntryListener.onEntryRemoved(null, "foobar", null, null, false, false); + } + private class TestableNotificationLogger extends NotificationLogger { TestableNotificationLogger(NotificationListener notificationListener, diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java index 4f6329cb0c57..38d9ae7cfab4 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java @@ -30,11 +30,11 @@ import android.view.View; import android.widget.TextView; import com.android.systemui.SysuiTestCase; +import com.android.systemui.plugins.DarkIconDispatcher; import com.android.systemui.statusbar.HeadsUpStatusBarView; import com.android.systemui.statusbar.NotificationTestHelper; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout; -import com.android.systemui.statusbar.policy.DarkIconDispatcher; import org.junit.Assert; import org.junit.Before; diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarTransitionsTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarTransitionsTest.java index 76f57f049561..40d5415a9a47 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarTransitionsTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarTransitionsTest.java @@ -67,5 +67,4 @@ public class NavigationBarTransitionsTest extends SysuiTestCase { assertTrue(mTransitions.isLightsOut(BarTransitions.MODE_LIGHTS_OUT)); } - }
\ No newline at end of file diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarIconControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarIconControllerTest.java index 72b0156d25f9..4f95bc515d0a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarIconControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarIconControllerTest.java @@ -14,17 +14,14 @@ package com.android.systemui.statusbar.phone; -import static junit.framework.Assert.assertEquals; -import static junit.framework.Assert.assertTrue; - 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 static org.mockito.ArgumentMatchers.eq; + +import static junit.framework.Assert.assertTrue; + import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import android.graphics.Rect; import android.support.test.filters.SmallTest; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper.RunWithLooper; @@ -32,15 +29,15 @@ import android.view.ViewGroup; import android.widget.LinearLayout; import com.android.internal.statusbar.StatusBarIcon; -import com.android.systemui.statusbar.StatusIconDisplayable; +import com.android.systemui.plugins.DarkIconDispatcher; 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.StatusBarIconController.DarkIconManager; import com.android.systemui.statusbar.phone.StatusBarIconController.IconManager; 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.utils.leaks.LeakCheckedTest; import org.junit.Before; 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 e80694c2e946..18ead907ae8e 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 @@ -82,6 +82,7 @@ import com.android.systemui.keyguard.WakefulnessLifecycle; import com.android.systemui.plugins.ActivityStarter.OnDismissAction; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.KeyguardIndicationController; +import com.android.systemui.statusbar.NavigationBarController; import com.android.systemui.statusbar.NotificationListener; import com.android.systemui.statusbar.NotificationLockscreenUserManager; import com.android.systemui.statusbar.NotificationMediaManager; @@ -196,6 +197,7 @@ public class StatusBarTest extends SysuiTestCase { mDreamManager); mDependency.injectTestDependency(NotificationInterruptionStateProvider.class, mNotificationInterruptionStateProvider); + mDependency.injectMockDependency(NavigationBarController.class); mContext.addMockSystemService(TrustManager.class, mock(TrustManager.class)); mContext.addMockSystemService(FingerprintManager.class, mock(FingerprintManager.class)); @@ -245,7 +247,7 @@ public class StatusBarTest extends SysuiTestCase { mock(StatusBarWindowController.class), mock(NotificationIconAreaController.class), mDozeScrimController, mock(NotificationShelf.class), mLockscreenUserManager, mCommandQueue, mNotificationPresenter, - mock(BubbleController.class)); + mock(BubbleController.class), mock(NavigationBarController.class)); mStatusBar.mContext = mContext; mStatusBar.mComponents = mContext.getComponents(); SystemUIFactory.getInstance().getRootComponent() @@ -695,7 +697,8 @@ public class StatusBarTest extends SysuiTestCase { NotificationLockscreenUserManager notificationLockscreenUserManager, CommandQueue commandQueue, NotificationPresenter notificationPresenter, - BubbleController bubbleController) { + BubbleController bubbleController, + NavigationBarController navBarController) { mStatusBarKeyguardViewManager = man; mUnlockMethodCache = unlock; mKeyguardIndicationController = key; @@ -726,6 +729,7 @@ public class StatusBarTest extends SysuiTestCase { mPresenter = notificationPresenter; mGestureWakeLock = mock(PowerManager.WakeLock.class); mBubbleController = bubbleController; + mNavigationBarController = navBarController; } private WakefulnessLifecycle createAwakeWakefulnessLifecycle() { diff --git a/packages/overlays/IconShapeRoundedRectOverlay/res/values/config.xml b/packages/overlays/IconShapeRoundedRectOverlay/res/values/config.xml index f024615190ab..138c283b9a24 100644 --- a/packages/overlays/IconShapeRoundedRectOverlay/res/values/config.xml +++ b/packages/overlays/IconShapeRoundedRectOverlay/res/values/config.xml @@ -18,7 +18,7 @@ --> <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <!-- Specifies the path that is used by AdaptiveIconDrawable class to crop launcher icons. --> - <string name="config_icon_mask" translatable="false">"M50,0L92,0C96.42,0 100,4.58 100 8L100,92C100, 96.42 96.42 100 92 100L8 100C4.58, 100 0 96.42 0 92L0 8 C 0 4.42 4.42 0 8 0L50 0Z"</string> + <string name="config_icon_mask" translatable="false">"M50,0L88,0 C94.4,0 100,5.4 100 12 L100,88 C100,94.6 94.6 100 88 100 L12,100 C5.4,100 0,94.6 0,88 L0 12 C0 5.4 5.4 0 12 0 L50,0 Z"</string> <!-- Flag indicating whether round icons should be parsed from the application manifest. --> <bool name="config_useRoundIcon">false</bool> diff --git a/packages/overlays/IconShapeTeardropOverlay/res/values/config.xml b/packages/overlays/IconShapeTeardropOverlay/res/values/config.xml index 43ad04d69c73..818e696577e9 100644 --- a/packages/overlays/IconShapeTeardropOverlay/res/values/config.xml +++ b/packages/overlays/IconShapeTeardropOverlay/res/values/config.xml @@ -18,7 +18,7 @@ --> <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <!-- Specifies the path that is used by AdaptiveIconDrawable class to crop launcher icons. --> - <string name="config_icon_mask" translatable="false">"M50,0A50,50,0,0 1 100,50 L100,85 A15,15,0,0 1 85,100 L50,100 A50,50,0,0 1 50,0z"</string> + <string name="config_icon_mask" translatable="false">"M50,0 C77.6,0 100,22.4 100,50 L100,88 C100,94.6 94.6,100 88,100 L50,100 C22.4 100 0 77.6 0 50C0 22.4 22.4 0 50 0 Z"</string> <!-- Flag indicating whether round icons should be parsed from the application manifest. --> <bool name="config_useRoundIcon">false</bool> diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java index 0e9b407372e0..0348f2bf1c2b 100644 --- a/services/autofill/java/com/android/server/autofill/Session.java +++ b/services/autofill/java/com/android/server/autofill/Session.java @@ -64,9 +64,11 @@ import android.os.RemoteException; import android.os.SystemClock; import android.service.autofill.AutofillFieldClassificationService.Scores; import android.service.autofill.AutofillService; +import android.service.autofill.CompositeUserData; import android.service.autofill.Dataset; import android.service.autofill.FieldClassification; import android.service.autofill.FieldClassification.Match; +import android.service.autofill.FieldClassificationUserData; import android.service.autofill.FillContext; import android.service.autofill.FillRequest; import android.service.autofill.FillResponse; @@ -1237,11 +1239,16 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState return; } + // Merge UserData if necessary. + // Fields in packageUserData will override corresponding fields in genericUserData. + final UserData genericUserData = mService.getUserData(); final UserData packageUserData = lastResponse.getUserData(); - - final UserData userData; - if (packageUserData != null) { - // Replace default userData + final FieldClassificationUserData userData; + if (packageUserData == null && genericUserData == null) { + userData = null; + } else if (packageUserData != null && genericUserData != null) { + userData = new CompositeUserData(genericUserData, packageUserData); + } else if (packageUserData != null) { userData = packageUserData; } else { userData = mService.getUserData(); @@ -1396,7 +1403,8 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState @NonNull ArrayList<String> changedDatasetIds, @NonNull ArrayList<AutofillId> manuallyFilledFieldIds, @NonNull ArrayList<ArrayList<String>> manuallyFilledDatasetIds, - @NonNull UserData userData, @NonNull Collection<ViewState> viewStates) { + @NonNull FieldClassificationUserData userData, + @NonNull Collection<ViewState> viewStates) { final String[] userValues = userData.getValues(); final String[] categoryIds = userData.getCategoryIds(); diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java index 704974417f87..8b07db7fc32d 100644 --- a/services/backup/java/com/android/server/backup/BackupManagerService.java +++ b/services/backup/java/com/android/server/backup/BackupManagerService.java @@ -36,7 +36,6 @@ import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.os.Binder; -import android.os.Environment; import android.os.HandlerThread; import android.os.IBinder; import android.os.ParcelFileDescriptor; @@ -50,11 +49,7 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.server.SystemConfig; import com.android.server.SystemService; -import java.io.File; import java.io.FileDescriptor; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; import java.io.PrintWriter; import java.util.Collections; import java.util.Set; @@ -72,10 +67,6 @@ public class BackupManagerService { public static final boolean MORE_DEBUG = false; public static final boolean DEBUG_SCHEDULING = true; - // File containing backup-enabled state. Contains a single byte to denote enabled status. - // Nonzero is enabled; file missing or a zero byte is disabled. - private static final String BACKUP_ENABLE_FILE = "backup_enabled"; - // The published binder is a singleton Trampoline object that calls through to the proper code. // This indirection lets us turn down the heavy implementation object on the fly without // disturbing binders that have been cached elsewhere in the system. @@ -150,7 +141,8 @@ public class BackupManagerService { Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "backup enable"); try { // TODO(b/121198604): Make enable file per-user and clean up indirection. - mTrampoline.setBackupEnabledForUser(userId, readBackupEnableState(userId)); + mTrampoline.setBackupEnabledForUser( + userId, UserBackupManagerFilePersistedSettings.readBackupEnableState(userId)); } catch (RemoteException e) { // Can't happen, it's a local object. } @@ -773,44 +765,6 @@ public class BackupManagerService { } } - private static boolean readBackupEnableState(int userId) { - File base = new File(Environment.getDataDirectory(), "backup"); - File enableFile = new File(base, BACKUP_ENABLE_FILE); - if (enableFile.exists()) { - try (FileInputStream fin = new FileInputStream(enableFile)) { - int state = fin.read(); - return state != 0; - } catch (IOException e) { - // can't read the file; fall through to assume disabled - Slog.e(TAG, "Cannot read enable state; assuming disabled"); - } - } else { - if (DEBUG) { - Slog.i(TAG, "isBackupEnabled() => false due to absent settings file"); - } - } - return false; - } - - static void writeBackupEnableState(boolean enable, int userId) { - File base = new File(Environment.getDataDirectory(), "backup"); - File enableFile = new File(base, BACKUP_ENABLE_FILE); - File stage = new File(base, BACKUP_ENABLE_FILE + "-stage"); - try (FileOutputStream fout = new FileOutputStream(stage)) { - fout.write(enable ? 1 : 0); - fout.close(); - stage.renameTo(enableFile); - // will be synced immediately by the try-with-resources call to close() - } catch (IOException | RuntimeException e) { - Slog.e( - TAG, - "Unable to record backup enable state; reverting to disabled: " - + e.getMessage()); - enableFile.delete(); - stage.delete(); - } - } - /** Implementation to receive lifecycle event callbacks for system services. */ public static final class Lifecycle extends SystemService { public Lifecycle(Context context) { diff --git a/services/backup/java/com/android/server/backup/UserBackupManagerFilePersistedSettings.java b/services/backup/java/com/android/server/backup/UserBackupManagerFilePersistedSettings.java new file mode 100644 index 000000000000..6a1de6378a5e --- /dev/null +++ b/services/backup/java/com/android/server/backup/UserBackupManagerFilePersistedSettings.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; + +import static com.android.server.backup.BackupManagerService.DEBUG; +import static com.android.server.backup.BackupManagerService.TAG; + +import android.util.Slog; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; + +/** User settings which are persisted across reboots. */ +final class UserBackupManagerFilePersistedSettings { + // File containing backup-enabled state. Contains a single byte to denote enabled status. + // Nonzero is enabled; file missing or a zero byte is disabled. + private static final String BACKUP_ENABLE_FILE = "backup_enabled"; + + static boolean readBackupEnableState(int userId) { + return readBackupEnableState(UserBackupManagerFiles.getBaseStateDir(userId)); + } + + static void writeBackupEnableState(int userId, boolean enable) { + writeBackupEnableState(UserBackupManagerFiles.getBaseStateDir(userId), enable); + } + + private static boolean readBackupEnableState(File baseDir) { + File enableFile = new File(baseDir, BACKUP_ENABLE_FILE); + if (enableFile.exists()) { + try (FileInputStream fin = new FileInputStream(enableFile)) { + int state = fin.read(); + return state != 0; + } catch (IOException e) { + // can't read the file; fall through to assume disabled + Slog.e(TAG, "Cannot read enable state; assuming disabled"); + } + } else { + if (DEBUG) { + Slog.i(TAG, "isBackupEnabled() => false due to absent settings file"); + } + } + return false; + } + + private static void writeBackupEnableState(File baseDir, boolean enable) { + File enableFile = new File(baseDir, BACKUP_ENABLE_FILE); + File stage = new File(baseDir, BACKUP_ENABLE_FILE + "-stage"); + try (FileOutputStream fout = new FileOutputStream(stage)) { + fout.write(enable ? 1 : 0); + fout.close(); + stage.renameTo(enableFile); + // will be synced immediately by the try-with-resources call to close() + } catch (IOException | RuntimeException e) { + Slog.e( + TAG, + "Unable to record backup enable state; reverting to disabled: " + + e.getMessage()); + enableFile.delete(); + stage.delete(); + } + } +} diff --git a/services/backup/java/com/android/server/backup/UserBackupManagerFiles.java b/services/backup/java/com/android/server/backup/UserBackupManagerFiles.java new file mode 100644 index 000000000000..a0feaf9c8d15 --- /dev/null +++ b/services/backup/java/com/android/server/backup/UserBackupManagerFiles.java @@ -0,0 +1,45 @@ +/* + * 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; + +import android.os.Environment; + +import java.io.File; + +/** Directories used for user specific backup/restore persistent state and book-keeping. */ +public final class UserBackupManagerFiles { + // Name of the directories the service stores bookkeeping data under. + private static final String BACKUP_PERSISTENT_DIR = "backup"; + private static final String BACKUP_STAGING_DIR = "backup_stage"; + + static File getBaseStateDir(int userId) { + // TODO (b/120424138) this should be per user + return new File(Environment.getDataDirectory(), BACKUP_PERSISTENT_DIR); + } + + static File getDataDir(int userId) { + // TODO (b/120424138) this should be per user + // This dir on /cache is managed directly in init.rc + return new File(Environment.getDownloadCacheDirectory(), BACKUP_STAGING_DIR); + } + + /** Directory used by full backup engine to store state. */ + public static File getFullBackupEngineFilesDir(int userId) { + // TODO (b/120424138) this should be per user + return new File("/data/system"); + } +} diff --git a/services/backup/java/com/android/server/backup/UserBackupManagerService.java b/services/backup/java/com/android/server/backup/UserBackupManagerService.java index 2e414438c6ff..6425508829ce 100644 --- a/services/backup/java/com/android/server/backup/UserBackupManagerService.java +++ b/services/backup/java/com/android/server/backup/UserBackupManagerService.java @@ -70,7 +70,6 @@ import android.database.ContentObserver; import android.net.Uri; import android.os.Binder; import android.os.Bundle; -import android.os.Environment; import android.os.Handler; import android.os.HandlerThread; import android.os.IBinder; @@ -164,17 +163,9 @@ import java.util.concurrent.atomic.AtomicInteger; /** System service that performs backup/restore operations. */ public class UserBackupManagerService { - // File containing backup-enabled state. Contains a single byte; - // nonzero == enabled. File missing or contains a zero byte == disabled. - private static final String BACKUP_ENABLE_FILE = "backup_enabled"; - // Persistently track the need to do a full init. private static final String INIT_SENTINEL_FILE_NAME = "_need_init_"; - // Name of the directories the service stores bookkeeping data under. - private static final String BACKUP_PERSISTENT_DIR = "backup"; - private static final String BACKUP_STAGING_DIR = "backup_stage"; - // System-private key used for backing up an app's widget state. Must // begin with U+FFxx by convention (we reserve all keys starting // with U+FF00 or higher for system use). @@ -354,9 +345,9 @@ public class UserBackupManagerService { final AtomicInteger mNextToken = new AtomicInteger(); // Where we keep our journal files and other bookkeeping. - private File mBaseStateDir; - private File mDataDir; - private File mJournalDir; + private final File mBaseStateDir; + private final File mDataDir; + private final File mJournalDir; @Nullable private DataChangedJournal mJournal; private File mFullBackupScheduleFile; @@ -395,10 +386,8 @@ public class UserBackupManagerService { TransportManager transportManager = new TransportManager(context, transportWhitelist, currentTransport); - File baseStateDir = new File(Environment.getDataDirectory(), BACKUP_PERSISTENT_DIR); - - // This dir on /cache is managed directly in init.rc - File dataDir = new File(Environment.getDownloadCacheDirectory(), BACKUP_STAGING_DIR); + File baseStateDir = UserBackupManagerFiles.getBaseStateDir(userId); + File dataDir = UserBackupManagerFiles.getDataDir(userId); return createAndInitializeService( userId, context, trampoline, backupThread, baseStateDir, dataDir, transportManager); @@ -726,18 +715,10 @@ public class UserBackupManagerService { return mBaseStateDir; } - public void setBaseStateDir(File baseStateDir) { - mBaseStateDir = baseStateDir; - } - public File getDataDir() { return mDataDir; } - public void setDataDir(File dataDir) { - mDataDir = dataDir; - } - @Nullable public DataChangedJournal getJournal() { return mJournal; @@ -2735,8 +2716,7 @@ public class UserBackupManagerService { try { boolean wasEnabled = mEnabled; synchronized (this) { - // TODO(b/118520567): Clean up writing backup enabled logic. - BackupManagerService.writeBackupEnableState(enable, UserHandle.USER_SYSTEM); + UserBackupManagerFilePersistedSettings.writeBackupEnableState(mUserId, enable); mEnabled = enable; } diff --git a/services/backup/java/com/android/server/backup/fullbackup/FullBackupEngine.java b/services/backup/java/com/android/server/backup/fullbackup/FullBackupEngine.java index 5e923393843e..45ca2af54b52 100644 --- a/services/backup/java/com/android/server/backup/fullbackup/FullBackupEngine.java +++ b/services/backup/java/com/android/server/backup/fullbackup/FullBackupEngine.java @@ -24,6 +24,7 @@ import static com.android.server.backup.UserBackupManagerService.BACKUP_METADATA import static com.android.server.backup.UserBackupManagerService.OP_TYPE_BACKUP_WAIT; import static com.android.server.backup.UserBackupManagerService.SHARED_BACKUP_AGENT_PACKAGE; +import android.annotation.UserIdInt; import android.app.ApplicationThreadConstants; import android.app.IBackupAgent; import android.app.backup.BackupTransport; @@ -40,6 +41,7 @@ import com.android.internal.util.Preconditions; import com.android.server.AppWidgetBackupBridge; import com.android.server.backup.BackupAgentTimeoutParameters; import com.android.server.backup.BackupRestoreTask; +import com.android.server.backup.UserBackupManagerFiles; import com.android.server.backup.UserBackupManagerService; import com.android.server.backup.remote.RemoteCall; import com.android.server.backup.utils.FullBackupUtils; @@ -66,6 +68,7 @@ public class FullBackupEngine { private final BackupAgentTimeoutParameters mAgentTimeoutParameters; class FullBackupRunner implements Runnable { + private final @UserIdInt int mUserId; private final PackageManager mPackageManager; private final PackageInfo mPackage; private final IBackupAgent mAgent; @@ -81,13 +84,15 @@ public class FullBackupEngine { int token, boolean includeApks) throws IOException { + // TODO: http://b/22388012 + mUserId = UserHandle.USER_SYSTEM; mPackageManager = backupManagerService.getPackageManager(); mPackage = packageInfo; mAgent = agent; mPipe = ParcelFileDescriptor.dup(pipe.getFileDescriptor()); mToken = token; mIncludeApks = includeApks; - mFilesDir = new File("/data/system"); + mFilesDir = UserBackupManagerFiles.getFullBackupEngineFilesDir(mUserId); } @Override @@ -114,10 +119,8 @@ public class FullBackupEngine { manifestFile.delete(); // Write widget data. - // TODO: http://b/22388012 byte[] widgetData = - AppWidgetBackupBridge.getWidgetState( - packageName, UserHandle.USER_SYSTEM); + AppWidgetBackupBridge.getWidgetState(packageName, mUserId); if (widgetData != null && widgetData.length > 0) { File metadataFile = new File(mFilesDir, BACKUP_METADATA_FILENAME); appMetadataBackupWriter.backupWidget( diff --git a/services/core/java/com/android/server/PackageWatchdog.java b/services/core/java/com/android/server/PackageWatchdog.java new file mode 100644 index 000000000000..06dc9188d1ee --- /dev/null +++ b/services/core/java/com/android/server/PackageWatchdog.java @@ -0,0 +1,572 @@ +/* + * 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; + +import android.content.Context; +import android.os.Environment; +import android.os.Handler; +import android.os.HandlerThread; +import android.os.Looper; +import android.os.Message; +import android.os.Process; +import android.os.SystemClock; +import android.text.TextUtils; +import android.util.ArrayMap; +import android.util.AtomicFile; +import android.util.Log; +import android.util.Slog; +import android.util.Xml; + +import com.android.internal.annotations.GuardedBy; +import com.android.internal.util.FastXmlSerializer; +import com.android.internal.util.XmlUtils; + +import libcore.io.IoUtils; + +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; +import org.xmlpull.v1.XmlSerializer; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +/** + * Monitors the health of packages on the system and notifies interested observers when packages + * fail. All registered observers will be notified until an observer takes a mitigation action. + */ +public class PackageWatchdog { + private static final String TAG = "PackageWatchdog"; + // Duration to count package failures before it resets to 0 + private static final int TRIGGER_DURATION_MS = 60000; + // Number of package failures within the duration above before we notify observers + private static final int TRIGGER_FAILURE_COUNT = 5; + private static final int DB_VERSION = 1; + private static final String TAG_PACKAGE_WATCHDOG = "package-watchdog"; + private static final String TAG_PACKAGE = "package"; + private static final String TAG_OBSERVER = "observer"; + private static final String ATTR_VERSION = "version"; + private static final String ATTR_NAME = "name"; + private static final String ATTR_DURATION = "duration"; + private static final int MESSAGE_SAVE_FILE = 1; + + private static PackageWatchdog sPackageWatchdog; + + private final Object mLock = new Object(); + // System server context + private final Context mContext; + // Handler to run package cleanup runnables + private final Handler mTimerHandler; + private final HandlerThread mIoThread = new HandlerThread("package_watchdog_io", + Process.THREAD_PRIORITY_BACKGROUND); + private final Handler mIoHandler; + // Maps observer names to package observers that have been registered since the last boot + @GuardedBy("mLock") + final Map<String, PackageHealthObserver> mRegisteredObservers = new ArrayMap<>(); + // Maps observer names to internal observers (registered or not) loaded from file + @GuardedBy("mLock") + final Map<String, ObserverInternal> mAllObservers = new ArrayMap<>(); + // /data/system/ directory + private final File mSystemDir = new File(Environment.getDataDirectory(), "system"); + // File containing the XML data of monitored packages + private final AtomicFile mPolicyFile = + new AtomicFile(new File(mSystemDir, "package-watchdog.xml")); + // Runnable to prune monitored packages that have expired + private final Runnable mPackageCleanup; + // Last SystemClock#uptimeMillis a package clean up was executed. + // 0 if mPackageCleanup not running. + private long mUptimeAtLastRescheduleMs; + // Duration a package cleanup was last scheduled for. + // 0 if mPackageCleanup not running. + private long mDurationAtLastReschedule; + + private PackageWatchdog(Context context) { + mContext = context; + mTimerHandler = new Handler(Looper.myLooper()); + mIoThread.start(); + mIoHandler = new IoHandler(mIoThread.getLooper()); + mPackageCleanup = this::rescheduleCleanup; + loadFromFile(); + } + + /** Creates or gets singleton instance of PackageWatchdog. */ + public static synchronized PackageWatchdog getInstance(Context context) { + if (sPackageWatchdog == null) { + sPackageWatchdog = new PackageWatchdog(context); + } + return sPackageWatchdog; + } + + /** + * Registers {@code observer} to listen for package failures + * + * <p>Observers are expected to call this on boot. It does not specify any packages but + * it will resume observing any packages requested from a previous boot. + */ + public void registerHealthObserver(PackageHealthObserver observer) { + synchronized (mLock) { + mRegisteredObservers.put(observer.getName(), observer); + if (mDurationAtLastReschedule == 0) { + // Nothing running, schedule + rescheduleCleanup(); + } + } + } + + /** + * Starts observing the health of the {@code packages} for {@code observer} and notifies + * {@code observer} of any package failures within the monitoring duration. + * + * <p>If {@code observer} is already monitoring a package in {@code packageNames}, + * the monitoring window of that package will be reset to {@code hours}. + * + * @throws IllegalArgumentException if {@code packageNames} is empty + * or {@code hours} is less than 1 + */ + public void startObservingHealth(PackageHealthObserver observer, List<String> packageNames, + int hours) { + if (packageNames.isEmpty() || hours < 1) { + throw new IllegalArgumentException("Observation not started, no packages specified" + + "or invalid hours"); + } + long durationMs = TimeUnit.HOURS.toMillis(hours); + List<MonitoredPackage> packages = new ArrayList<>(); + for (String packageName : packageNames) { + packages.add(new MonitoredPackage(packageName, durationMs)); + } + synchronized (mLock) { + ObserverInternal oldObserver = mAllObservers.get(observer.getName()); + if (oldObserver == null) { + Slog.d(TAG, observer.getName() + " started monitoring health of packages " + + packageNames); + mAllObservers.put(observer.getName(), + new ObserverInternal(observer.getName(), packages)); + } else { + Slog.d(TAG, observer.getName() + " added the following packages to monitor " + + packageNames); + oldObserver.updatePackages(packages); + } + } + registerHealthObserver(observer); + // Always reschedule because we may need to expire packages + // earlier than we are already scheduled for + rescheduleCleanup(); + sendIoMessage(MESSAGE_SAVE_FILE); + } + + /** + * Unregisters {@code observer} from listening to package failure. + * Additionally, this stops observing any packages that may have previously been observed + * even from a previous boot. + */ + public void unregisterHealthObserver(PackageHealthObserver observer) { + synchronized (mLock) { + mAllObservers.remove(observer.getName()); + mRegisteredObservers.remove(observer.getName()); + } + sendIoMessage(MESSAGE_SAVE_FILE); + } + + // TODO(zezeozue:) Accept current versionCodes of failing packages? + /** + * Called when a process fails either due to a crash or ANR. + * + * <p>All registered observers for the packages contained in the process will be notified in + * order of priority unitl an observer signifies that it has taken action and other observers + * should not notified. + * + * <p>This method could be called frequently if there is a severe problem on the device. + */ + public void onPackageFailure(String[] packages) { + synchronized (mLock) { + if (mRegisteredObservers.isEmpty()) { + return; + } + for (String packageName : packages) { + for (ObserverInternal observer : mAllObservers.values()) { + if (observer.onPackageFailure(packageName)) { + PackageHealthObserver activeObserver = + mRegisteredObservers.get(observer.mName); + if (activeObserver != null + && activeObserver.onHealthCheckFailed(packageName)) { + // Observer has handled, do not notify other observers + break; + } + } + } + } + } + } + + // TODO(zezeozue): Optimize write? Maybe only write a separate smaller file? + // This currently adds about 7ms extra to shutdown thread + /** Writes the package information to file during shutdown. */ + public void writeNow() { + if (!mAllObservers.isEmpty()) { + mIoHandler.removeMessages(MESSAGE_SAVE_FILE); + pruneObservers(SystemClock.uptimeMillis() - mUptimeAtLastRescheduleMs); + saveToFile(); + Slog.i(TAG, "Last write to update package durations"); + } + } + + /** Register instances of this interface to receive notifications on package failure. */ + public interface PackageHealthObserver { + /** + * Called when health check fails for the {@code packages}. + * @return {@code true} if action was taken and other observers should not be notified of + * this failure, {@code false} otherwise. + */ + boolean onHealthCheckFailed(String packageName); + + // TODO(zezeozue): Ensure uniqueness? + /** + * Identifier for the observer, should not change across device updates otherwise the + * watchdog may drop observing packages with the old name. + */ + String getName(); + } + + /** Reschedules handler to prune expired packages from observers. */ + private void rescheduleCleanup() { + synchronized (mLock) { + long nextDurationToScheduleMs = getEarliestPackageExpiryLocked(); + if (nextDurationToScheduleMs == Long.MAX_VALUE) { + Slog.i(TAG, "No monitored packages, ending package cleanup"); + mDurationAtLastReschedule = 0; + mUptimeAtLastRescheduleMs = 0; + return; + } + long uptimeMs = SystemClock.uptimeMillis(); + // O if mPackageCleanup not running + long elapsedDurationMs = mUptimeAtLastRescheduleMs == 0 + ? 0 : uptimeMs - mUptimeAtLastRescheduleMs; + // O if mPackageCleanup not running + long remainingDurationMs = mDurationAtLastReschedule - elapsedDurationMs; + + if (mUptimeAtLastRescheduleMs == 0 || nextDurationToScheduleMs < remainingDurationMs) { + // First schedule or an earlier reschedule + pruneObservers(elapsedDurationMs); + mTimerHandler.removeCallbacks(mPackageCleanup); + mTimerHandler.postDelayed(mPackageCleanup, nextDurationToScheduleMs); + mDurationAtLastReschedule = nextDurationToScheduleMs; + mUptimeAtLastRescheduleMs = uptimeMs; + } + } + } + + /** + * Returns the earliest time a package should expire. + * @returns Long#MAX_VALUE if there are no observed packages. + */ + private long getEarliestPackageExpiryLocked() { + long shortestDurationMs = Long.MAX_VALUE; + for (ObserverInternal observer : mAllObservers.values()) { + for (MonitoredPackage p : observer.mPackages.values()) { + if (p.mDurationMs < shortestDurationMs) { + shortestDurationMs = p.mDurationMs; + } + } + } + Slog.v(TAG, "Earliest package time is " + shortestDurationMs); + return shortestDurationMs; + } + + /** + * Removes {@code elapsedMs} milliseconds from all durations on monitored packages. + * Discards expired packages and discards observers without any packages. + */ + private void pruneObservers(long elapsedMs) { + if (elapsedMs == 0) { + return; + } + synchronized (mLock) { + Slog.d(TAG, "Removing expired packages after " + elapsedMs + "ms"); + Iterator<ObserverInternal> it = mAllObservers.values().iterator(); + while (it.hasNext()) { + ObserverInternal observer = it.next(); + if (!observer.updateMonitoringDurations(elapsedMs)) { + Slog.i(TAG, "Discarding observer " + observer.mName + ". All packages expired"); + it.remove(); + } + } + } + sendIoMessage(MESSAGE_SAVE_FILE); + } + + /** + * Loads mAllObservers from file. + * + * <p>Note that this is <b>not</b> thread safe and should only called be called + * from the constructor. + */ + private void loadFromFile() { + InputStream infile = null; + mAllObservers.clear(); + try { + infile = mPolicyFile.openRead(); + final XmlPullParser parser = Xml.newPullParser(); + parser.setInput(infile, StandardCharsets.UTF_8.name()); + XmlUtils.beginDocument(parser, TAG_PACKAGE_WATCHDOG); + int outerDepth = parser.getDepth(); + while (XmlUtils.nextElementWithin(parser, outerDepth)) { + ObserverInternal observer = ObserverInternal.read(parser); + if (observer != null) { + mAllObservers.put(observer.mName, observer); + } + } + } catch (FileNotFoundException e) { + // Nothing to monitor + } catch (IOException e) { + Log.wtf(TAG, "Unable to read monitored packages", e); + } catch (NumberFormatException e) { + Log.wtf(TAG, "Unable to parse monitored package windows", e); + } catch (XmlPullParserException e) { + Log.wtf(TAG, "Unable to parse monitored packages", e); + } finally { + IoUtils.closeQuietly(infile); + } + } + + /** + * Persists mAllObservers to file and ignores threshold information. + * + * <p>Note that this is <b>not</b> thread safe and should only be called on the + * single threaded IoHandler. + */ + private boolean saveToFile() { + FileOutputStream stream; + try { + stream = mPolicyFile.startWrite(); + } catch (IOException e) { + Slog.w(TAG, "Cannot update monitored packages", e); + return false; + } + + try { + XmlSerializer out = new FastXmlSerializer(); + out.setOutput(stream, StandardCharsets.UTF_8.name()); + out.startDocument(null, true); + out.startTag(null, TAG_PACKAGE_WATCHDOG); + out.attribute(null, ATTR_VERSION, Integer.toString(DB_VERSION)); + for (ObserverInternal observer : mAllObservers.values()) { + observer.write(out); + } + out.endTag(null, TAG_PACKAGE_WATCHDOG); + out.endDocument(); + mPolicyFile.finishWrite(stream); + return true; + } catch (IOException e) { + Slog.w(TAG, "Failed to save monitored packages, restoring backup", e); + mPolicyFile.failWrite(stream); + return false; + } finally { + IoUtils.closeQuietly(stream); + } + } + + private void sendIoMessage(int what) { + if (!mIoHandler.hasMessages(what)) { + Message m = Message.obtain(mIoHandler, what); + mIoHandler.sendMessage(m); + } + } + + /** + * Represents an observer monitoring a set of packages along with the failure thresholds for + * each package. + */ + static class ObserverInternal { + public final String mName; + public final ArrayMap<String, MonitoredPackage> mPackages; + + ObserverInternal(String name, List<MonitoredPackage> packages) { + mName = name; + mPackages = new ArrayMap<>(); + updatePackages(packages); + } + + /** + * Writes important details to file. Doesn't persist any package failure thresholds. + * + * <p>Note that this method is <b>not</b> thread safe. It should only be called from + * #saveToFile which runs on a single threaded handler. + */ + public boolean write(XmlSerializer out) { + try { + out.startTag(null, TAG_OBSERVER); + out.attribute(null, ATTR_NAME, mName); + for (int i = 0; i < mPackages.size(); i++) { + MonitoredPackage p = mPackages.valueAt(i); + out.startTag(null, TAG_PACKAGE); + out.attribute(null, ATTR_NAME, p.mName); + out.attribute(null, ATTR_DURATION, String.valueOf(p.mDurationMs)); + out.endTag(null, TAG_PACKAGE); + } + out.endTag(null, TAG_OBSERVER); + return true; + } catch (IOException e) { + Slog.w(TAG, "Cannot save observer", e); + return false; + } + } + + public void updatePackages(List<MonitoredPackage> packages) { + synchronized (mName) { + for (MonitoredPackage p : packages) { + mPackages.put(p.mName, p); + } + } + } + + /** + * Reduces the monitoring durations of all packages observed by this observer by + * {@code elapsedMs}. If any duration is less than 0, the package is removed from + * observation. + * + * @returns {@code true} if there are still packages to be observed, {@code false} otherwise + */ + public boolean updateMonitoringDurations(long elapsedMs) { + List<MonitoredPackage> packages = new ArrayList<>(); + synchronized (mName) { + Iterator<MonitoredPackage> it = mPackages.values().iterator(); + while (it.hasNext()) { + MonitoredPackage p = it.next(); + long newDuration = p.mDurationMs - elapsedMs; + if (newDuration > 0) { + p.mDurationMs = newDuration; + } else { + it.remove(); + } + } + return !mPackages.isEmpty(); + } + } + + /** + * Increments failure counts of {@code packageName}. + * @returns {@code true} if failure threshold is exceeded, {@code false} otherwise + */ + public boolean onPackageFailure(String packageName) { + synchronized (mName) { + MonitoredPackage p = mPackages.get(packageName); + if (p != null) { + return p.onFailure(); + } + return false; + } + } + + /** + * Returns one ObserverInternal from the {@code parser} and advances its state. + * + * <p>Note that this method is <b>not</b> thread safe. It should only be called from + * #loadFromFile which in turn is only called on construction of the + * singleton PackageWatchdog. + **/ + public static ObserverInternal read(XmlPullParser parser) { + String observerName = null; + if (TAG_OBSERVER.equals(parser.getName())) { + observerName = parser.getAttributeValue(null, ATTR_NAME); + if (TextUtils.isEmpty(observerName)) { + return null; + } + } + List<MonitoredPackage> packages = new ArrayList<>(); + int innerDepth = parser.getDepth(); + try { + while (XmlUtils.nextElementWithin(parser, innerDepth)) { + if (TAG_PACKAGE.equals(parser.getName())) { + String packageName = parser.getAttributeValue(null, ATTR_NAME); + long duration = Long.parseLong( + parser.getAttributeValue(null, ATTR_DURATION)); + if (!TextUtils.isEmpty(packageName)) { + packages.add(new MonitoredPackage(packageName, duration)); + } + } + } + } catch (IOException e) { + return null; + } catch (XmlPullParserException e) { + return null; + } + if (packages.isEmpty()) { + return null; + } + return new ObserverInternal(observerName, packages); + } + } + + /** Represents a package along with the time it should be monitored for. */ + static class MonitoredPackage { + public final String mName; + // System uptime duration to monitor package + public long mDurationMs; + // System uptime of first package failure + private long mUptimeStartMs; + // Number of failures since mUptimeStartMs + private int mFailures; + + MonitoredPackage(String name, long durationMs) { + mName = name; + mDurationMs = durationMs; + } + + /** + * Increment package failures or resets failure count depending on the last package failure. + * + * @return {@code true} if failure count exceeds a threshold, {@code false} otherwise + */ + public synchronized boolean onFailure() { + final long now = SystemClock.uptimeMillis(); + final long duration = now - mUptimeStartMs; + if (duration > TRIGGER_DURATION_MS) { + // TODO(zezeozue): Reseting to 1 is not correct + // because there may be more than 1 failure in the last trigger window from now + // This is the RescueParty impl, will leave for now + mFailures = 1; + mUptimeStartMs = now; + } else { + mFailures++; + } + return mFailures >= TRIGGER_FAILURE_COUNT; + } + } + + private class IoHandler extends Handler { + IoHandler(Looper looper) { + super(looper); + } + + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case MESSAGE_SAVE_FILE: + saveToFile(); + break; + } + } + } +} diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 1a5dd90b918a..16c236ef83ad 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -336,6 +336,7 @@ import com.android.server.IoThread; import com.android.server.LocalServices; import com.android.server.LockGuard; import com.android.server.NetworkManagementInternal; +import com.android.server.PackageWatchdog; import com.android.server.RescueParty; import com.android.server.ServiceThread; import com.android.server.SystemConfig; @@ -587,6 +588,7 @@ public class ActivityManagerService extends IActivityManager.Stub public final PendingIntentController mPendingIntentController; final AppErrors mAppErrors; + final PackageWatchdog mPackageWatchdog; /** * Indicates the maximum time spent waiting for the network rules to get updated. @@ -2209,6 +2211,7 @@ public class ActivityManagerService extends IActivityManager.Stub mContext = mInjector.getContext(); mUiContext = null; mAppErrors = null; + mPackageWatchdog = null; mActiveUids = new ActiveUids(this, false /* postChangesToAtm */); mAppOpsService = mInjector.getAppOpsService(null /* file */, null /* handler */); mBatteryStatsService = null; @@ -2275,7 +2278,8 @@ public class ActivityManagerService extends IActivityManager.Stub mServices = new ActiveServices(this); mProviderMap = new ProviderMap(this); - mAppErrors = new AppErrors(mUiContext, this); + mPackageWatchdog = PackageWatchdog.getInstance(mUiContext); + mAppErrors = new AppErrors(mUiContext, this, mPackageWatchdog); mActiveUids = new ActiveUids(this, true /* postChangesToAtm */); final File systemDir = SystemServiceManager.ensureSystemDir(); diff --git a/services/core/java/com/android/server/am/AppErrors.java b/services/core/java/com/android/server/am/AppErrors.java index 1c1daffceafe..a634b577f506 100644 --- a/services/core/java/com/android/server/am/AppErrors.java +++ b/services/core/java/com/android/server/am/AppErrors.java @@ -53,6 +53,7 @@ import android.util.proto.ProtoOutputStream; import com.android.internal.app.ProcessMap; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto; +import com.android.server.PackageWatchdog; import com.android.server.RescueParty; import com.android.server.wm.WindowProcessController; @@ -69,6 +70,7 @@ class AppErrors { private final ActivityManagerService mService; private final Context mContext; + private final PackageWatchdog mPackageWatchdog; private ArraySet<String> mAppsNotReportingCrashes; @@ -93,10 +95,11 @@ class AppErrors { private final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<>(); - AppErrors(Context context, ActivityManagerService service) { + AppErrors(Context context, ActivityManagerService service, PackageWatchdog watchdog) { context.assertRuntimeOverlayThemable(); mService = service; mContext = context; + mPackageWatchdog = watchdog; } void writeToProto(ProtoOutputStream proto, long fieldId, String dumpPackage) { @@ -400,10 +403,16 @@ class AppErrors { longMsg = shortMsg; } - // If a persistent app is stuck in a crash loop, the device isn't very - // usable, so we want to consider sending out a rescue party. - if (r != null && r.isPersistent()) { - RescueParty.notePersistentAppCrash(mContext, r.uid); + if (r != null) { + if (r.isPersistent()) { + // If a persistent app is stuck in a crash loop, the device isn't very + // usable, so we want to consider sending out a rescue party. + RescueParty.notePersistentAppCrash(mContext, r.uid); + } else { + // If a non-persistent app is stuck in crash loop, we want to inform + // the package watchdog, maybe an update or experiment can be rolled back. + mPackageWatchdog.onPackageFailure(r.getPackageList()); + } } final int relaunchReason = r != null @@ -821,6 +830,7 @@ class AppErrors { void handleShowAnrUi(Message msg) { Dialog dialogToShow = null; + String[] packageList = null; synchronized (mService) { AppNotRespondingDialog.Data data = (AppNotRespondingDialog.Data) msg.obj; final ProcessRecord proc = data.proc; @@ -828,6 +838,9 @@ class AppErrors { Slog.e(TAG, "handleShowAnrUi: proc is null"); return; } + if (!proc.isPersistent()) { + packageList = proc.getPackageList(); + } if (proc.anrDialog != null) { Slog.e(TAG, "App already has anr dialog: " + proc); MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_APP_ANR, @@ -851,6 +864,10 @@ class AppErrors { if (dialogToShow != null) { dialogToShow.show(); } + // Notify PackageWatchdog without the lock held + if (packageList != null) { + mPackageWatchdog.onPackageFailure(packageList); + } } /** diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java index 117984e10cf5..d133deaf4b8e 100644 --- a/services/core/java/com/android/server/am/ProcessList.java +++ b/services/core/java/com/android/server/am/ProcessList.java @@ -1362,8 +1362,9 @@ public final class ProcessList { mService.mNativeDebuggingApp = null; } - if (app.info.isPrivilegedApp() && - DexManager.isPackageSelectedToRunOob(app.pkgList.mPkgList.keySet())) { + if ((app.info.privateFlags & ApplicationInfo.PRIVATE_FLAG_PREFER_CODE_INTEGRITY) != 0 + || (app.info.isPrivilegedApp() + && DexManager.isPackageSelectedToRunOob(app.pkgList.mPkgList.keySet()))) { runtimeFlags |= Zygote.ONLY_USE_SYSTEM_OAT_FILES; } @@ -1613,6 +1614,13 @@ public final class ProcessList { app.addPackage(info.packageName, info.versionCode, mService.mProcessStats); checkSlow(startTime, "startProcess: done, added package to proc"); return app; + } else if (app.getActiveInstrumentation() != null) { + // We don't want to kill running instrumentation. + if (DEBUG_PROCESSES) { + Slog.v(TAG_PROCESSES, "Instrumentation already running: " + app); + } + checkSlow(startTime, "startProcess: keep instrumentation proc"); + return app; } // An application record is attached to a previous process, diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index 6cde4adb9f11..d704a3ea8eb1 100644 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -7822,6 +7822,36 @@ public class AudioService extends IAudioService.Stub return AudioManager.SUCCESS; } + /** see AudioPolicy.setUidDeviceAffinity() */ + public int setUidDeviceAffinity(IAudioPolicyCallback pcb, int uid, + @NonNull int[] deviceTypes, + @NonNull String[] deviceAddresses) { + synchronized (mAudioPolicies) { + final AudioPolicyProxy app = + checkUpdateForPolicy(pcb, "Cannot change device affinity in audio policy"); + if (app == null) { + return AudioManager.ERROR; + } + if (!app.hasMixRoutedToDevices(deviceTypes, deviceAddresses)) { + return AudioManager.ERROR; + } + } + return AudioManager.SUCCESS; + } + + /** see AudioPolicy.removeUidDeviceAffinity() */ + public int removeUidDeviceAffinity(IAudioPolicyCallback pcb, int uid) { + synchronized (mAudioPolicies) { + final AudioPolicyProxy app = + checkUpdateForPolicy(pcb, "Cannot remove device affinity in audio policy"); + if (app == null) { + return AudioManager.ERROR; + } + + } + return AudioManager.SUCCESS; + } + public int setFocusPropertiesForPolicy(int duckingBehavior, IAudioPolicyCallback pcb) { if (DEBUG_AP) Log.d(TAG, "setFocusPropertiesForPolicy() duck behavior=" + duckingBehavior + " policy " + pcb.asBinder()); @@ -7994,6 +8024,15 @@ public class AudioService extends IAudioService.Stub //====================== // Audio policy proxy //====================== + private static final class AudioDeviceArray { + final @NonNull int[] mDeviceTypes; + final @NonNull String[] mDeviceAddresses; + AudioDeviceArray(@NonNull int[] types, @NonNull String[] addresses) { + mDeviceTypes = types; + mDeviceAddresses = addresses; + } + } + /** * This internal class inherits from AudioPolicyConfig, each instance contains all the * mixes of an AudioPolicy and their configurations. @@ -8003,6 +8042,8 @@ public class AudioService extends IAudioService.Stub final IAudioPolicyCallback mPolicyCallback; final boolean mHasFocusListener; final boolean mIsVolumeController; + final HashMap<Integer, AudioDeviceArray> mUidDeviceAffinities = + new HashMap<Integer, AudioDeviceArray>(); /** * Audio focus ducking behavior for an audio policy. * This variable reflects the value that was successfully set in @@ -8075,6 +8116,26 @@ public class AudioService extends IAudioService.Stub return false; } + // Verify all the devices in the array are served by mixes defined in this policy + boolean hasMixRoutedToDevices(@NonNull int[] deviceTypes, + @NonNull String[] deviceAddresses) { + for (int i = 0; i < deviceTypes.length; i++) { + boolean hasDevice = false; + for (AudioMix mix : mMixes) { + // this will check both that the mix has ROUTE_FLAG_RENDER and the device + // is reached by this mix + if (mix.isRoutedToDevice(deviceTypes[i], deviceAddresses[i])) { + hasDevice = true; + break; + } + } + if (!hasDevice) { + return false; + } + } + return true; + } + void addMixes(@NonNull ArrayList<AudioMix> mixes) { // TODO optimize to not have to unregister the mixes already in place synchronized (mMixes) { @@ -8098,6 +8159,29 @@ public class AudioService extends IAudioService.Stub AudioSystem.registerPolicyMixes(mMixes, true); Binder.restoreCallingIdentity(identity); } + + void setUidDeviceAffinities(int uid, @NonNull int[] types, @NonNull String[] addresses) { + final Integer Uid = new Integer(uid); + if (mUidDeviceAffinities.remove(Uid) != null) { + final long identity = Binder.clearCallingIdentity(); + AudioSystem.removeUidDeviceAffinities(uid); + Binder.restoreCallingIdentity(identity); + } + final long identity = Binder.clearCallingIdentity(); + final int res = AudioSystem.setUidDeviceAffinities(uid, types, addresses); + Binder.restoreCallingIdentity(identity); + if (res == AudioSystem.SUCCESS) { + mUidDeviceAffinities.put(Uid, new AudioDeviceArray(types, addresses)); + } + } + + void removeUidDeviceAffinities(int uid, @NonNull int[] types, @NonNull String[] addresses) { + if (mUidDeviceAffinities.remove(new Integer(uid)) != null) { + final long identity = Binder.clearCallingIdentity(); + AudioSystem.removeUidDeviceAffinities(uid); + Binder.restoreCallingIdentity(identity); + } + } }; //====================== diff --git a/services/core/java/com/android/server/display/ColorDisplayService.java b/services/core/java/com/android/server/display/ColorDisplayService.java index b6c82d3a66e4..73d3d9591529 100644 --- a/services/core/java/com/android/server/display/ColorDisplayService.java +++ b/services/core/java/com/android/server/display/ColorDisplayService.java @@ -16,6 +16,7 @@ package com.android.server.display; +import static com.android.server.display.DisplayTransformManager.LEVEL_COLOR_MATRIX_DISPLAY_WHITE_BALANCE; import static com.android.server.display.DisplayTransformManager.LEVEL_COLOR_MATRIX_NIGHT_DISPLAY; import android.animation.Animator; @@ -31,6 +32,7 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.database.ContentObserver; +import android.hardware.display.ColorDisplayManager; import android.hardware.display.IColorDisplayManager; import android.net.Uri; import android.opengl.Matrix; @@ -86,11 +88,80 @@ public final class ColorDisplayService extends SystemService { */ private static final ColorMatrixEvaluator COLOR_MATRIX_EVALUATOR = new ColorMatrixEvaluator(); - private final Handler mHandler; + private final TintController mNightDisplayTintController = new TintController() { + + private float[] mMatrixNightDisplay = new float[16]; + private final float[] mColorTempCoefficients = new float[9]; + + /** + * Set coefficients based on whether the color matrix is linear or not. + */ + @Override + public void setUp(Context context, boolean needsLinear) { + final String[] coefficients = context.getResources().getStringArray(needsLinear + ? R.array.config_nightDisplayColorTemperatureCoefficients + : R.array.config_nightDisplayColorTemperatureCoefficientsNative); + for (int i = 0; i < 9 && i < coefficients.length; i++) { + mColorTempCoefficients[i] = Float.parseFloat(coefficients[i]); + } + } + + @Override + public void setMatrix(int cct) { + if (mMatrixNightDisplay.length != 16) { + Slog.d(TAG, "The display transformation matrix must be 4x4"); + return; + } + + Matrix.setIdentityM(mMatrixNightDisplay, 0); + + final float squareTemperature = cct * cct; + final float red = squareTemperature * mColorTempCoefficients[0] + + cct * mColorTempCoefficients[1] + mColorTempCoefficients[2]; + final float green = squareTemperature * mColorTempCoefficients[3] + + cct * mColorTempCoefficients[4] + mColorTempCoefficients[5]; + final float blue = squareTemperature * mColorTempCoefficients[6] + + cct * mColorTempCoefficients[7] + mColorTempCoefficients[8]; + mMatrixNightDisplay[0] = red; + mMatrixNightDisplay[5] = green; + mMatrixNightDisplay[10] = blue; + } + + @Override + public float[] getMatrix() { + return isActivated() ? mMatrixNightDisplay : MATRIX_IDENTITY; + } + + @Override + public int getLevel() { + return LEVEL_COLOR_MATRIX_NIGHT_DISPLAY; + } + }; + + private final TintController mDisplayWhiteBalanceTintController = new TintController() { + + private float[] mMatrixDisplayWhiteBalance = new float[16]; + + @Override + public void setUp(Context context, boolean needsLinear) { + } + + @Override + public float[] getMatrix() { + return isActivated() ? mMatrixDisplayWhiteBalance : MATRIX_IDENTITY; + } + + @Override + public void setMatrix(int cct) { + } - private float[] mMatrixNight = new float[16]; + @Override + public int getLevel() { + return LEVEL_COLOR_MATRIX_DISPLAY_WHITE_BALANCE; + } + }; - private final float[] mColorTempCoefficients = new float[9]; + private final Handler mHandler; private int mCurrentUser = UserHandle.USER_NULL; private ContentObserver mUserSetupObserver; @@ -98,11 +169,13 @@ public final class ColorDisplayService extends SystemService { private ColorDisplayController mNightDisplayController; private ContentObserver mContentObserver; - private ValueAnimator mColorMatrixAnimator; - private Boolean mIsNightDisplayActivated; + private DisplayWhiteBalanceListener mDisplayWhiteBalanceListener; + private NightDisplayAutoMode mNightDisplayAutoMode; + private Integer mDisplayWhiteBalanceColorTemperature; + public ColorDisplayService(Context context) { super(context); mHandler = new Handler(Looper.getMainLooper()); @@ -111,6 +184,7 @@ public final class ColorDisplayService extends SystemService { @Override public void onStart() { publishBinderService(Context.COLOR_DISPLAY_SERVICE, new BinderService()); + publishLocalService(ColorDisplayServiceInternal.class, new ColorDisplayServiceInternal()); } @Override @@ -232,6 +306,9 @@ public final class ColorDisplayService extends SystemService { case Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED: onAccessibilityTransformChanged(); break; + case Secure.DISPLAY_WHITE_BALANCE_ENABLED: + onDisplayWhiteBalanceEnabled(isDisplayWhiteBalanceSettingEnabled()); + break; } } } @@ -256,25 +333,41 @@ public final class ColorDisplayService extends SystemService { cr.registerContentObserver( Secure.getUriFor(Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED), false /* notifyForDescendants */, mContentObserver, mCurrentUser); + cr.registerContentObserver(Secure.getUriFor(Secure.DISPLAY_WHITE_BALANCE_ENABLED), + false /* notifyForDescendants */, mContentObserver, mCurrentUser); // Set the color mode, if valid, and immediately apply the updated tint matrix based on the // existing activated state. This ensures consistency of tint across the color mode change. onDisplayColorModeChanged(mNightDisplayController.getColorMode()); - // Reset the activated state. - mIsNightDisplayActivated = null; + if (ColorDisplayManager.isNightDisplayAvailable(getContext())) { + // Reset the activated state. + mNightDisplayTintController.setActivated(null); + + // Prepare the night display color transformation matrix. + mNightDisplayTintController + .setUp(getContext(), DisplayTransformManager.needsLinearColorMatrix()); + mNightDisplayTintController.setMatrix(mNightDisplayController.getColorTemperature()); - setCoefficientMatrix(getContext(), DisplayTransformManager.needsLinearColorMatrix()); + // Initialize the current auto mode. + onNightDisplayAutoModeChanged(mNightDisplayController.getAutoMode()); - // Prepare color transformation matrix. - setMatrix(mNightDisplayController.getColorTemperature(), mMatrixNight); + // Force the initialization current activated state. + if (mNightDisplayTintController.isActivatedStateNotSet()) { + onNightDisplayActivated(mNightDisplayController.isActivated()); + } + } - // Initialize the current auto mode. - onNightDisplayAutoModeChanged(mNightDisplayController.getAutoMode()); + if (ColorDisplayManager.isDisplayWhiteBalanceAvailable(getContext())) { + // Prepare the display white balance transform matrix. + mDisplayWhiteBalanceTintController + .setUp(getContext(), DisplayTransformManager.needsLinearColorMatrix()); + if (mDisplayWhiteBalanceColorTemperature != null) { + mDisplayWhiteBalanceTintController + .setMatrix(mDisplayWhiteBalanceColorTemperature); + } - // Force the initialization current activated state. - if (mIsNightDisplayActivated == null) { - onNightDisplayActivated(mNightDisplayController.isActivated()); + onDisplayWhiteBalanceEnabled(isDisplayWhiteBalanceSettingEnabled()); } } @@ -287,28 +380,31 @@ public final class ColorDisplayService extends SystemService { mNightDisplayController = null; } - if (mNightDisplayAutoMode != null) { - mNightDisplayAutoMode.onStop(); - mNightDisplayAutoMode = null; + if (ColorDisplayManager.isNightDisplayAvailable(getContext())) { + if (mNightDisplayAutoMode != null) { + mNightDisplayAutoMode.onStop(); + mNightDisplayAutoMode = null; + } + mNightDisplayTintController.endAnimator(); } - if (mColorMatrixAnimator != null) { - mColorMatrixAnimator.end(); - mColorMatrixAnimator = null; + if (ColorDisplayManager.isDisplayWhiteBalanceAvailable(getContext())) { + mDisplayWhiteBalanceTintController.endAnimator(); } } private void onNightDisplayActivated(boolean activated) { - if (mIsNightDisplayActivated == null || mIsNightDisplayActivated != activated) { + if (mNightDisplayTintController.isActivatedStateNotSet() + || mNightDisplayTintController.isActivated() != activated) { Slog.i(TAG, activated ? "Turning on night display" : "Turning off night display"); - mIsNightDisplayActivated = activated; + mNightDisplayTintController.setActivated(activated); if (mNightDisplayAutoMode != null) { mNightDisplayAutoMode.onActivated(activated); } - applyTint(false); + applyTint(mNightDisplayTintController, false); } } @@ -348,8 +444,8 @@ public final class ColorDisplayService extends SystemService { } private void onNightDisplayColorTemperatureChanged(int colorTemperature) { - setMatrix(colorTemperature, mMatrixNight); - applyTint(true); + mNightDisplayTintController.setMatrix(colorTemperature); + applyTint(mNightDisplayTintController, true); } private void onDisplayColorModeChanged(int mode) { @@ -357,66 +453,53 @@ public final class ColorDisplayService extends SystemService { return; } - // Cancel the night display tint animator if it's running. - if (mColorMatrixAnimator != null) { - mColorMatrixAnimator.cancel(); - } + mNightDisplayTintController.cancelAnimator(); + mDisplayWhiteBalanceTintController.cancelAnimator(); + + mNightDisplayTintController + .setUp(getContext(), DisplayTransformManager.needsLinearColorMatrix(mode)); + mNightDisplayTintController.setMatrix(mNightDisplayController.getColorTemperature()); - setCoefficientMatrix(getContext(), DisplayTransformManager.needsLinearColorMatrix(mode)); - setMatrix(mNightDisplayController.getColorTemperature(), mMatrixNight); + mDisplayWhiteBalanceTintController + .setUp(getContext(), DisplayTransformManager.needsLinearColorMatrix(mode)); + if (mDisplayWhiteBalanceColorTemperature != null) { + mDisplayWhiteBalanceTintController.setMatrix(mDisplayWhiteBalanceColorTemperature); + } final DisplayTransformManager dtm = getLocalService(DisplayTransformManager.class); - dtm.setColorMode(mode, (mIsNightDisplayActivated != null && mIsNightDisplayActivated) - ? mMatrixNight : MATRIX_IDENTITY); + dtm.setColorMode(mode, mNightDisplayTintController.getMatrix()); } private void onAccessibilityTransformChanged() { onDisplayColorModeChanged(mNightDisplayController.getColorMode()); } - /** - * Set coefficients based on whether the color matrix is linear or not. - */ - private void setCoefficientMatrix(Context context, boolean needsLinear) { - final String[] coefficients = context.getResources().getStringArray(needsLinear - ? R.array.config_nightDisplayColorTemperatureCoefficients - : R.array.config_nightDisplayColorTemperatureCoefficientsNative); - for (int i = 0; i < 9 && i < coefficients.length; i++) { - mColorTempCoefficients[i] = Float.parseFloat(coefficients[i]); - } - } /** * Applies current color temperature matrix, or removes it if deactivated. * * @param immediate {@code true} skips transition animation */ - private void applyTint(boolean immediate) { - // Cancel the old animator if still running. - if (mColorMatrixAnimator != null) { - mColorMatrixAnimator.cancel(); - } + private void applyTint(TintController tintController, boolean immediate) { + tintController.cancelAnimator(); final DisplayTransformManager dtm = getLocalService(DisplayTransformManager.class); - final float[] from = dtm.getColorMatrix(LEVEL_COLOR_MATRIX_NIGHT_DISPLAY); - final float[] to = mIsNightDisplayActivated ? mMatrixNight : MATRIX_IDENTITY; + final float[] from = dtm.getColorMatrix(tintController.getLevel()); + final float[] to = tintController.getMatrix(); if (immediate) { - dtm.setColorMatrix(LEVEL_COLOR_MATRIX_NIGHT_DISPLAY, to); + dtm.setColorMatrix(tintController.getLevel(), to); } else { - mColorMatrixAnimator = ValueAnimator.ofObject(COLOR_MATRIX_EVALUATOR, - from == null ? MATRIX_IDENTITY : from, to); - mColorMatrixAnimator.setDuration(TRANSITION_DURATION); - mColorMatrixAnimator.setInterpolator(AnimationUtils.loadInterpolator( + tintController.setAnimator(ValueAnimator.ofObject(COLOR_MATRIX_EVALUATOR, + from == null ? MATRIX_IDENTITY : from, to)); + tintController.getAnimator().setDuration(TRANSITION_DURATION); + tintController.getAnimator().setInterpolator(AnimationUtils.loadInterpolator( getContext(), android.R.interpolator.fast_out_slow_in)); - mColorMatrixAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(ValueAnimator animator) { - final float[] value = (float[]) animator.getAnimatedValue(); - dtm.setColorMatrix(LEVEL_COLOR_MATRIX_NIGHT_DISPLAY, value); - } + tintController.getAnimator().addUpdateListener((ValueAnimator animator) -> { + final float[] value = (float[]) animator.getAnimatedValue(); + dtm.setColorMatrix(tintController.getLevel(), value); }); - mColorMatrixAnimator.addListener(new AnimatorListenerAdapter() { + tintController.getAnimator().addListener(new AnimatorListenerAdapter() { private boolean mIsCancelled; @@ -431,42 +514,16 @@ public final class ColorDisplayService extends SystemService { // Ensure final color matrix is set at the end of the animation. If the // animation is cancelled then don't set the final color matrix so the new // animator can pick up from where this one left off. - dtm.setColorMatrix(LEVEL_COLOR_MATRIX_NIGHT_DISPLAY, to); + dtm.setColorMatrix(tintController.getLevel(), to); } - mColorMatrixAnimator = null; + tintController.setAnimator(null); } }); - mColorMatrixAnimator.start(); + tintController.getAnimator().start(); } } /** - * Set the color transformation {@code MATRIX_NIGHT} to the given color temperature. - * - * @param colorTemperature color temperature in Kelvin - * @param outTemp the 4x4 display transformation matrix for that color temperature - */ - private void setMatrix(int colorTemperature, float[] outTemp) { - if (outTemp.length != 16) { - Slog.d(TAG, "The display transformation matrix must be 4x4"); - return; - } - - Matrix.setIdentityM(mMatrixNight, 0); - - final float squareTemperature = colorTemperature * colorTemperature; - final float red = squareTemperature * mColorTempCoefficients[0] - + colorTemperature * mColorTempCoefficients[1] + mColorTempCoefficients[2]; - final float green = squareTemperature * mColorTempCoefficients[3] - + colorTemperature * mColorTempCoefficients[4] + mColorTempCoefficients[5]; - final float blue = squareTemperature * mColorTempCoefficients[6] - + colorTemperature * mColorTempCoefficients[7] + mColorTempCoefficients[8]; - outTemp[0] = red; - outTemp[5] = green; - outTemp[10] = blue; - } - - /** * Returns the first date time corresponding to the local time that occurs before the provided * date time. * @@ -498,6 +555,18 @@ public final class ColorDisplayService extends SystemService { return ldt.isBefore(compareTime) ? ldt.plusDays(1) : ldt; } + private void onDisplayWhiteBalanceEnabled(boolean enabled) { + mDisplayWhiteBalanceTintController.setActivated(enabled); + if (mDisplayWhiteBalanceListener != null) { + mDisplayWhiteBalanceListener.onDisplayWhiteBalanceStatusChanged(enabled); + } + } + + private boolean isDisplayWhiteBalanceSettingEnabled() { + return Secure.getIntForUser(getContext().getContentResolver(), + Secure.DISPLAY_WHITE_BALANCE_ENABLED, 0, mCurrentUser) == 1; + } + private boolean isDeviceColorManagedInternal() { final DisplayTransformManager dtm = getLocalService(DisplayTransformManager.class); return dtm.isDeviceColorManaged(); @@ -507,7 +576,7 @@ public final class ColorDisplayService extends SystemService { * Returns the last time the night display transform activation state was changed, or {@link * LocalDateTime#MIN} if night display has never been activated. */ - private @NonNull LocalDateTime getNightDisplayLastActivatedTimeSetting() { + private LocalDateTime getNightDisplayLastActivatedTimeSetting() { final ContentResolver cr = getContext().getContentResolver(); final String lastActivatedTime = Secure.getStringForUser( cr, Secure.NIGHT_DISPLAY_LAST_ACTIVATED_TIME, getContext().getUserId()); @@ -577,11 +646,12 @@ public final class ColorDisplayService extends SystemService { } } - if (mIsNightDisplayActivated == null || mIsNightDisplayActivated != activate) { + if (mNightDisplayTintController.isActivatedStateNotSet() || ( + mNightDisplayTintController.isActivated() != activate)) { mNightDisplayController.setActivated(activate); } - updateNextAlarm(mIsNightDisplayActivated, now); + updateNextAlarm(mNightDisplayTintController.isActivated(), now); } private void updateNextAlarm(@Nullable Boolean activated, @NonNull LocalDateTime now) { @@ -672,7 +742,8 @@ public final class ColorDisplayService extends SystemService { } } - if (mIsNightDisplayActivated == null || mIsNightDisplayActivated != activate) { + if (mNightDisplayTintController.isActivatedStateNotSet() || ( + mNightDisplayTintController.isActivated() != activate)) { mNightDisplayController.setActivated(activate); } } @@ -724,6 +795,115 @@ public final class ColorDisplayService extends SystemService { } } + private abstract static class TintController { + + private ValueAnimator mAnimator; + private Boolean mIsActivated; + + public ValueAnimator getAnimator() { + return mAnimator; + } + + public void setAnimator(ValueAnimator animator) { + mAnimator = animator; + } + + /** + * Cancel the animator if it's still running. + */ + public void cancelAnimator() { + if (mAnimator != null) { + mAnimator.cancel(); + } + } + + /** + * End the animator if it's still running, jumping to the end state. + */ + public void endAnimator() { + if (mAnimator != null) { + mAnimator.end(); + mAnimator = null; + } + } + + public void setActivated(Boolean isActivated) { + mIsActivated = isActivated; + } + + public boolean isActivated() { + return mIsActivated != null && mIsActivated; + } + + public boolean isActivatedStateNotSet() { + return mIsActivated == null; + } + + /** + * Set up any constants needed for computing the matrix. + */ + public abstract void setUp(Context context, boolean needsLinear); + + /** + * Sets the 4x4 matrix to apply. + */ + public abstract void setMatrix(int value); + + /** + * Get the 4x4 matrix to apply. + */ + public abstract float[] getMatrix(); + + /** + * Get the color transform level to apply the matrix. + */ + public abstract int getLevel(); + } + + /** + * Local service that allows color transforms to be enabled from other system services. + */ + public final class ColorDisplayServiceInternal { + + /** + * Set the current CCT value for the display white balance transform, and if the transform + * is enabled, apply it. + * + * @param cct the color temperature in Kelvin. + */ + public boolean setDisplayWhiteBalanceColorTemperature(int cct) { + // Update the transform matrix even if it can't be applied. + mDisplayWhiteBalanceColorTemperature = cct; + mDisplayWhiteBalanceTintController.setMatrix(cct); + + if (mDisplayWhiteBalanceTintController.isActivated()) { + applyTint(mDisplayWhiteBalanceTintController, true); + return true; + } + return false; + } + + /** + * Sets the listener and returns whether display white balance is currently enabled. + */ + public boolean setDisplayWhiteBalanceListener(DisplayWhiteBalanceListener listener) { + mDisplayWhiteBalanceListener = listener; + return mDisplayWhiteBalanceTintController.isActivated(); + } + } + + /** + * Listener for changes in display white balance status. + */ + public interface DisplayWhiteBalanceListener { + + /** + * Notify that the display white balance status has changed, either due to preemption by + * another transform or the feature being turned off. + */ + void onDisplayWhiteBalanceStatusChanged(boolean enabled); + } + private final class BinderService extends IColorDisplayManager.Stub { @Override diff --git a/services/core/java/com/android/server/display/DisplayTransformManager.java b/services/core/java/com/android/server/display/DisplayTransformManager.java index 4ad26dae8380..a5e9728e4b68 100644 --- a/services/core/java/com/android/server/display/DisplayTransformManager.java +++ b/services/core/java/com/android/server/display/DisplayTransformManager.java @@ -45,6 +45,10 @@ public class DisplayTransformManager { */ public static final int LEVEL_COLOR_MATRIX_NIGHT_DISPLAY = 100; /** + * Color transform level used by display white balance to adjust the display's white point. + */ + public static final int LEVEL_COLOR_MATRIX_DISPLAY_WHITE_BALANCE = 125; + /** * Color transform level used to adjust the color saturation of the display. */ public static final int LEVEL_COLOR_MATRIX_SATURATION = 150; diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java index dd2abde10433..d49c4a94256e 100644 --- a/services/core/java/com/android/server/media/MediaSessionRecord.java +++ b/services/core/java/com/android/server/media/MediaSessionRecord.java @@ -236,6 +236,7 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { * {@link AudioManager#ADJUST_SAME}. * * @param packageName The package that made the original volume request. + * @param opPackageName The op package that made the original volume request. * @param pid The pid that made the original volume request. * @param uid The uid that made the original volume request. * @param caller caller binder. can be {@code null} if it's from the volume key. @@ -248,7 +249,7 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { * @param flags Any of the flags from {@link AudioManager}. * @param useSuggested True to use adjustSuggestedStreamVolume instead of */ - public void adjustVolume(String packageName, int pid, int uid, + public void adjustVolume(String packageName, String opPackageName, int pid, int uid, ControllerCallbackLink caller, boolean asSystemService, int direction, int flags, boolean useSuggested) { int previousFlagPlaySound = flags & AudioManager.FLAG_PLAY_SOUND; @@ -258,8 +259,8 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { if (mVolumeType == PlaybackInfo.PLAYBACK_TYPE_LOCAL) { // Adjust the volume with a handler not to be blocked by other system service. int stream = AudioAttributes.toLegacyStreamType(mAudioAttrs); - postAdjustLocalVolume(stream, direction, flags, packageName, uid, asSystemService, - useSuggested, previousFlagPlaySound); + postAdjustLocalVolume(stream, direction, flags, opPackageName, pid, uid, + asSystemService, useSuggested, previousFlagPlaySound); } else { if (mVolumeControlType == VolumeProvider.VOLUME_CONTROL_FIXED) { // Nothing to do, the volume cannot be changed @@ -290,11 +291,23 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { } } - private void setVolumeTo(String packageName, int pid, int uid, + private void setVolumeTo(String packageName, String opPackageName, int pid, int uid, ControllerCallbackLink caller, int value, int flags) { if (mVolumeType == PlaybackInfo.PLAYBACK_TYPE_LOCAL) { int stream = AudioAttributes.toLegacyStreamType(mAudioAttrs); - mAudioManagerInternal.setStreamVolumeForUid(stream, value, flags, packageName, uid); + final int volumeValue = value; + mHandler.post(new Runnable() { + @Override + public void run() { + try { + mAudioManagerInternal.setStreamVolumeForUid(stream, volumeValue, flags, + opPackageName, uid); + } catch (IllegalArgumentException | SecurityException e) { + Log.e(TAG, "Cannot set volume: stream=" + stream + ", value=" + volumeValue + + ", flags=" + flags, e); + } + } + }); } else { if (mVolumeControlType != VolumeProvider.VOLUME_CONTROL_ABSOLUTE) { // Nothing to do. The volume can't be set directly. @@ -465,11 +478,19 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { } private void postAdjustLocalVolume(final int stream, final int direction, final int flags, - final String callingPackageName, final int callingUid, final boolean asSystemService, - final boolean useSuggested, final int previousFlagPlaySound) { - final String packageName = asSystemService - ? mContext.getOpPackageName() : callingPackageName; - final int uid = asSystemService ? Process.SYSTEM_UID : callingUid; + final String callingOpPackageName, final int callingPid, final int callingUid, + final boolean asSystemService, final boolean useSuggested, + final int previousFlagPlaySound) { + // Must use opPackageName for adjusting volumes with UID. + final String opPackageName; + final int uid; + if (asSystemService) { + opPackageName = mContext.getOpPackageName(); + uid = Process.SYSTEM_UID; + } else { + opPackageName = callingOpPackageName; + uid = callingUid; + } mHandler.post(new Runnable() { @Override public void run() { @@ -477,19 +498,19 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { if (useSuggested) { if (AudioSystem.isStreamActive(stream, 0)) { mAudioManagerInternal.adjustSuggestedStreamVolumeForUid(stream, - direction, flags, packageName, uid); + direction, flags, opPackageName, uid); } else { mAudioManagerInternal.adjustSuggestedStreamVolumeForUid( AudioManager.USE_DEFAULT_STREAM_TYPE, direction, - flags | previousFlagPlaySound, packageName, uid); + flags | previousFlagPlaySound, opPackageName, uid); } } else { mAudioManagerInternal.adjustStreamVolumeForUid(stream, direction, flags, - packageName, uid); + opPackageName, uid); } } catch (IllegalArgumentException | SecurityException e) { Log.e(TAG, "Cannot adjust volume: direction=" + direction + ", stream=" - + stream + ", flags=" + flags + ", packageName=" + packageName + + stream + ", flags=" + flags + ", opPackageName=" + opPackageName + ", uid=" + uid + ", useSuggested=" + useSuggested + ", previousFlagPlaySound=" + previousFlagPlaySound, e); } @@ -1256,27 +1277,28 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { } @Override - public void adjustVolume(String packageName, ControllerCallbackLink caller, - boolean asSystemService, int direction, int flags) { + public void adjustVolume(String packageName, String opPackageName, + ControllerCallbackLink caller, boolean asSystemService, int direction, int flags) { int pid = Binder.getCallingPid(); int uid = Binder.getCallingUid(); final long token = Binder.clearCallingIdentity(); try { - MediaSessionRecord.this.adjustVolume(packageName, pid, uid, caller, asSystemService, - direction, flags, false /* useSuggested */); + MediaSessionRecord.this.adjustVolume(packageName, opPackageName, pid, uid, caller, + asSystemService, direction, flags, false /* useSuggested */); } finally { Binder.restoreCallingIdentity(token); } } @Override - public void setVolumeTo(String packageName, ControllerCallbackLink caller, - int value, int flags) { + public void setVolumeTo(String packageName, String opPackageName, + ControllerCallbackLink caller, int value, int flags) { int pid = Binder.getCallingPid(); int uid = Binder.getCallingUid(); final long token = Binder.clearCallingIdentity(); try { - MediaSessionRecord.this.setVolumeTo(packageName, pid, uid, caller, value, flags); + MediaSessionRecord.this.setVolumeTo(packageName, opPackageName, pid, uid, caller, + value, flags); } finally { Binder.restoreCallingIdentity(token); } diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java index b807c47c09b9..7dbabda21b19 100644 --- a/services/core/java/com/android/server/media/MediaSessionService.java +++ b/services/core/java/com/android/server/media/MediaSessionService.java @@ -35,6 +35,7 @@ import android.content.pm.ServiceInfo; import android.content.pm.UserInfo; import android.database.ContentObserver; import android.media.AudioManager; +import android.media.AudioManagerInternal; import android.media.AudioPlaybackConfiguration; import android.media.AudioSystem; import android.media.IAudioService; @@ -72,6 +73,7 @@ import android.view.KeyEvent; import android.view.ViewConfiguration; import com.android.internal.util.DumpUtils; +import com.android.server.LocalServices; import com.android.server.SystemService; import com.android.server.Watchdog; import com.android.server.Watchdog.Monitor; @@ -108,6 +110,8 @@ public class MediaSessionService extends SystemService implements Monitor { private KeyguardManager mKeyguardManager; private IAudioService mAudioService; + private AudioManagerInternal mAudioManagerInternal; + private ActivityManager mActivityManager; private ContentResolver mContentResolver; private SettingsObserver mSettingsObserver; private boolean mHasFeatureLeanback; @@ -139,6 +143,9 @@ public class MediaSessionService extends SystemService implements Monitor { mKeyguardManager = (KeyguardManager) getContext().getSystemService(Context.KEYGUARD_SERVICE); mAudioService = getAudioService(); + mAudioManagerInternal = LocalServices.getService(AudioManagerInternal.class); + mActivityManager = + (ActivityManager) getContext().getSystemService(Context.ACTIVITY_SERVICE); mAudioPlayerStateMonitor = AudioPlayerStateMonitor.getInstance(); mAudioPlayerStateMonitor.registerListener( (config, isRemoved) -> { @@ -1202,7 +1209,8 @@ public class MediaSessionService extends SystemService implements Monitor { * there's no active global priority session, long-pressess will be sent to the * long-press listener instead of adjusting volume. * - * @param packageName The caller package. + * @param packageName The caller's package name, obtained by Context#getPackageName() + * @param opPackageName The caller's op package name, obtained by Context#getOpPackageName() * @param asSystemService {@code true} if the event sent to the session as if it was come * from the system service instead of the app process. This helps sessions to * distinguish between the key injection by the app and key events from the @@ -1217,8 +1225,8 @@ public class MediaSessionService extends SystemService implements Monitor { * @param musicOnly true if both UI nor haptic feedback aren't needed when adjust volume. */ @Override - public void dispatchVolumeKeyEvent(String packageName, boolean asSystemService, - KeyEvent keyEvent, int stream, boolean musicOnly) { + public void dispatchVolumeKeyEvent(String packageName, String opPackageName, + boolean asSystemService, KeyEvent keyEvent, int stream, boolean musicOnly) { if (keyEvent == null || (keyEvent.getKeyCode() != KeyEvent.KEYCODE_VOLUME_UP && keyEvent.getKeyCode() != KeyEvent.KEYCODE_VOLUME_DOWN @@ -1240,8 +1248,8 @@ public class MediaSessionService extends SystemService implements Monitor { synchronized (mLock) { if (isGlobalPriorityActiveLocked() || mCurrentFullUserRecord.mOnVolumeKeyLongPressListener == null) { - dispatchVolumeKeyEventLocked(packageName, pid, uid, asSystemService, - keyEvent, stream, musicOnly); + dispatchVolumeKeyEventLocked(packageName, opPackageName, pid, uid, + asSystemService, keyEvent, stream, musicOnly); } else { // TODO: Consider the case when both volume up and down keys are pressed // at the same time. @@ -1274,12 +1282,13 @@ public class MediaSessionService extends SystemService implements Monitor { && mCurrentFullUserRecord.mInitialDownVolumeKeyEvent .getDownTime() == keyEvent.getDownTime()) { // Short-press. Should change volume. - dispatchVolumeKeyEventLocked(packageName, pid, uid, asSystemService, + dispatchVolumeKeyEventLocked(packageName, opPackageName, pid, uid, + asSystemService, mCurrentFullUserRecord.mInitialDownVolumeKeyEvent, mCurrentFullUserRecord.mInitialDownVolumeStream, mCurrentFullUserRecord.mInitialDownMusicOnly); - dispatchVolumeKeyEventLocked(packageName, pid, uid, asSystemService, - keyEvent, stream, musicOnly); + dispatchVolumeKeyEventLocked(packageName, opPackageName, pid, uid, + asSystemService, keyEvent, stream, musicOnly); } else { dispatchVolumeKeyLongPressLocked(keyEvent); } @@ -1291,8 +1300,9 @@ public class MediaSessionService extends SystemService implements Monitor { } } - private void dispatchVolumeKeyEventLocked(String packageName, int pid, int uid, - boolean asSystemService, KeyEvent keyEvent, int stream, boolean musicOnly) { + private void dispatchVolumeKeyEventLocked(String packageName, String opPackageName, int pid, + int uid, boolean asSystemService, KeyEvent keyEvent, int stream, + boolean musicOnly) { boolean down = keyEvent.getAction() == KeyEvent.ACTION_DOWN; boolean up = keyEvent.getAction() == KeyEvent.ACTION_UP; int direction = 0; @@ -1326,26 +1336,26 @@ public class MediaSessionService extends SystemService implements Monitor { if (up) { direction = 0; } - dispatchAdjustVolumeLocked(packageName, pid, uid, asSystemService, stream, - direction, flags); + dispatchAdjustVolumeLocked(packageName, opPackageName, pid, uid, + asSystemService, stream, direction, flags); } else if (isMute) { if (down && keyEvent.getRepeatCount() == 0) { - dispatchAdjustVolumeLocked(packageName, pid, uid, asSystemService, stream, - AudioManager.ADJUST_TOGGLE_MUTE, flags); + dispatchAdjustVolumeLocked(packageName, opPackageName, pid, uid, + asSystemService, stream, AudioManager.ADJUST_TOGGLE_MUTE, flags); } } } } @Override - public void dispatchAdjustVolume(String packageName, int suggestedStream, int delta, - int flags) { + public void dispatchAdjustVolume(String packageName, String opPackageName, + int suggestedStream, int delta, int flags) { final int pid = Binder.getCallingPid(); final int uid = Binder.getCallingUid(); final long token = Binder.clearCallingIdentity(); try { synchronized (mLock) { - dispatchAdjustVolumeLocked(packageName, pid, uid, false, + dispatchAdjustVolumeLocked(packageName, opPackageName, pid, uid, false, suggestedStream, delta, flags); } } finally { @@ -1409,24 +1419,14 @@ public class MediaSessionService extends SystemService implements Monitor { final int uid = Binder.getCallingUid(); final long token = Binder.clearCallingIdentity(); try { - int controllerUserId = UserHandle.getUserId(controllerUid); - int controllerUidFromPackageName; - try { - controllerUidFromPackageName = getContext().getPackageManager() - .getPackageUidAsUser(controllerPackageName, controllerUserId); - } catch (NameNotFoundException e) { - if (DEBUG) { - Log.d(TAG, "Package " + controllerPackageName + " doesn't exist"); - } - return false; - } - if (controllerUidFromPackageName != controllerUid) { - if (DEBUG) { - Log.d(TAG, "Package name " + controllerPackageName - + " doesn't match with the uid " + controllerUid); - } - return false; - } + // Don't perform sanity check between controllerPackageName and controllerUid. + // When an (activity|service) runs on the another apps process by specifying + // android:process in the AndroidManifest.xml, then PID and UID would have the + // running process' information instead of the (activity|service) that has created + // MediaController. + // Note that we can use Context#getOpPackageName() instead of + // Context#getPackageName() for getting package name that matches with the PID/UID, + // but it doesn't tell which package has created the MediaController, so useless. return hasMediaControlPermission(UserHandle.getUserId(uid), controllerPackageName, controllerPid, controllerUid); } finally { @@ -1497,8 +1497,8 @@ public class MediaSessionService extends SystemService implements Monitor { return false; } - private void dispatchAdjustVolumeLocked(String packageName, int pid, int uid, - boolean asSystemService, int suggestedStream, int direction, int flags) { + private void dispatchAdjustVolumeLocked(String packageName, String opPackageName, int pid, + int uid, boolean asSystemService, int suggestedStream, int direction, int flags) { MediaSessionRecord session = isGlobalPriorityActiveLocked() ? mGlobalPrioritySession : mCurrentFullUserRecord.mPriorityStack.getDefaultVolumeSession(); @@ -1529,21 +1529,28 @@ public class MediaSessionService extends SystemService implements Monitor { mHandler.post(new Runnable() { @Override public void run() { + final String callingOpPackageName; + final int callingUid; + if (asSystemService) { + callingOpPackageName = getContext().getOpPackageName(); + callingUid = Process.myUid(); + } else { + callingOpPackageName = opPackageName; + callingUid = uid; + } try { - String packageName = getContext().getOpPackageName(); - mAudioService.adjustSuggestedStreamVolume(direction, suggestedStream, - flags, packageName, TAG); - } catch (RemoteException|SecurityException e) { - Log.e(TAG, "Error adjusting default volume.", e); - } catch (IllegalArgumentException e) { + mAudioManagerInternal.adjustSuggestedStreamVolumeForUid(suggestedStream, + direction, flags, callingOpPackageName, callingUid); + } catch (SecurityException | IllegalArgumentException e) { Log.e(TAG, "Cannot adjust volume: direction=" + direction - + ", suggestedStream=" + suggestedStream + ", flags=" + flags, - e); + + ", suggestedStream=" + suggestedStream + ", flags=" + flags + + ", packageName=" + packageName + ", uid=" + uid + + ", asSystemService=" + asSystemService, e); } } }); } else { - session.adjustVolume(packageName, pid, uid, null, asSystemService, + session.adjustVolume(packageName, opPackageName, pid, uid, null, asSystemService, direction, flags, true); } } diff --git a/services/core/java/com/android/server/notification/ManagedServices.java b/services/core/java/com/android/server/notification/ManagedServices.java index 6187583a0253..88d73fb10902 100644 --- a/services/core/java/com/android/server/notification/ManagedServices.java +++ b/services/core/java/com/android/server/notification/ManagedServices.java @@ -558,7 +558,7 @@ abstract public class ManagedServices { if (pkgList != null && (pkgList.length > 0)) { boolean anyServicesInvolved = false; // Remove notification settings for uninstalled package - if (removingPackage) { + if (removingPackage && uidList != null) { int size = Math.min(pkgList.length, uidList.length); for (int i = 0; i < size; i++) { final String pkg = pkgList[i]; @@ -570,9 +570,11 @@ abstract public class ManagedServices { if (mEnabledServicesPackageNames.contains(pkgName)) { anyServicesInvolved = true; } - for (int uid : uidList) { - if (isPackageAllowed(pkgName, UserHandle.getUserId(uid))) { - anyServicesInvolved = true; + if (uidList != null && uidList.length > 0) { + for (int uid : uidList) { + if (isPackageAllowed(pkgName, UserHandle.getUserId(uid))) { + anyServicesInvolved = true; + } } } } diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index e2cb75e96882..85a8d938d693 100644 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -5258,22 +5258,25 @@ public class NotificationManagerService extends SystemService { } if (DBG) Slog.v(TAG, "Interrupting!"); if (hasValidSound) { - mSoundNotificationKey = key; if (mInCall) { playInCallNotification(); beep = true; } else { beep = playSound(record, soundUri); } + if(beep) { + mSoundNotificationKey = key; + } } final boolean ringerModeSilent = mAudioManager.getRingerModeInternal() == AudioManager.RINGER_MODE_SILENT; if (!mInCall && hasValidVibrate && !ringerModeSilent) { - mVibrateNotificationKey = key; - buzz = playVibration(record, vibration, hasValidSound); + if(buzz) { + mVibrateNotificationKey = key; + } } } else if ((record.getFlags() & Notification.FLAG_INSISTENT) != 0) { hasValidSound = false; @@ -5454,8 +5457,17 @@ public class NotificationManagerService extends SystemService { try { Thread.sleep(waitMs); } catch (InterruptedException e) { } - mVibrator.vibrate(record.sbn.getUid(), record.sbn.getPackageName(), - effect, "Notification (delayed)", record.getAudioAttributes()); + + // Notifications might be canceled before it actually vibrates due to waitMs, + // so need to check the notification still valide for vibrate. + synchronized (mNotificationLock) { + if (mNotificationsByKey.get(record.getKey()) != null) { + mVibrator.vibrate(record.sbn.getUid(), record.sbn.getOpPkg(), + effect, "Notification (delayed)", record.getAudioAttributes()); + } else { + Slog.e(TAG, "No vibration for canceled notification : " + record.getKey()); + } + } }).start(); } else { mVibrator.vibrate(record.sbn.getUid(), record.sbn.getPackageName(), diff --git a/services/core/java/com/android/server/pm/ModuleInfoProvider.java b/services/core/java/com/android/server/pm/ModuleInfoProvider.java index 886cfb25eadd..642bfa2e70fd 100644 --- a/services/core/java/com/android/server/pm/ModuleInfoProvider.java +++ b/services/core/java/com/android/server/pm/ModuleInfoProvider.java @@ -24,8 +24,8 @@ import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.content.res.Resources; import android.content.res.XmlResourceParser; -import android.os.Process; import android.os.RemoteException; +import android.os.UserHandle; import android.text.TextUtils; import android.util.ArrayMap; import android.util.Slog; @@ -91,7 +91,7 @@ public class ModuleInfoProvider { final PackageInfo pi; try { pi = mPackageManager.getPackageInfo(packageName, - PackageManager.GET_META_DATA, Process.SYSTEM_UID); + PackageManager.GET_META_DATA, UserHandle.USER_SYSTEM); Context packageContext = mContext.createPackageContext(packageName, 0); packageResources = packageContext.getResources(); diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java index d4ee61b77422..d290f3f34909 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerSession.java +++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java @@ -105,6 +105,7 @@ import com.android.internal.util.Preconditions; import com.android.server.LocalServices; import com.android.server.pm.Installer.InstallerException; import com.android.server.pm.PackageInstallerService.PackageInstallObserverAdapter; +import com.android.server.pm.dex.DexManager; import libcore.io.IoUtils; @@ -1594,6 +1595,16 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } } } + if (baseApk.preferCodeIntegrity) { + for (File file : mResolvedStagedFiles) { + if (file.getName().endsWith(".apk") + && !DexManager.auditUncompressedCodeInApk(file.getPath())) { + throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, + "Some code are not uncompressed and aligned correctly for " + + mPackageName); + } + } + } if (baseApk.isSplitRequired && stagedSplits.size() <= 1) { throw new PackageManagerException(INSTALL_FAILED_MISSING_SPLIT, "Missing split for " + mPackageName); diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index da59b3e9b8d4..136c7c91749e 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -296,6 +296,7 @@ import com.android.server.EventLogTags; import com.android.server.FgThread; import com.android.server.LocalServices; import com.android.server.LockGuard; +import com.android.server.PackageWatchdog; import com.android.server.ServiceThread; import com.android.server.SystemConfig; import com.android.server.SystemServerInitThreadPool; @@ -9492,6 +9493,7 @@ public class PackageManagerService extends IPackageManager.Stub mPackageUsage.writeNow(mPackages); mCompilerStats.writeNow(); mDexManager.writePackageDexUsageNow(); + PackageWatchdog.getInstance(mContext).writeNow(); // This is the last chance to write out pending restriction settings synchronized (mPackages) { @@ -13021,20 +13023,26 @@ public class PackageManagerService extends IPackageManager.Stub } @Override - public boolean canSuspendPackageForUser(String packageName, int userId) { + public String[] getUnsuspendablePackagesForUser(String[] packageNames, int userId) { mContext.enforceCallingOrSelfPermission(Manifest.permission.SUSPEND_APPS, - "canSuspendPackageForUser"); + "getUnsuspendablePackagesForUser"); final int callingUid = Binder.getCallingUid(); if (UserHandle.getUserId(callingUid) != userId) { throw new SecurityException("Calling uid " + callingUid - + " cannot query canSuspendPackageForUser for user " + userId); + + " cannot query getUnsuspendablePackagesForUser for user " + userId); } + final ArraySet<String> unactionablePackages = new ArraySet<>(); final long identity = Binder.clearCallingIdentity(); try { - return canSuspendPackageForUserInternal(packageName, userId); + for (String packageName : packageNames) { + if (!canSuspendPackageForUserInternal(packageName, userId)) { + unactionablePackages.add(packageName); + } + } } finally { Binder.restoreCallingIdentity(identity); } + return unactionablePackages.toArray(new String[unactionablePackages.size()]); } private boolean canSuspendPackageForUserInternal(String packageName, int userId) { diff --git a/services/core/java/com/android/server/pm/dex/DexManager.java b/services/core/java/com/android/server/pm/dex/DexManager.java index 25ef7675e2b9..e57d9d7ab61c 100644 --- a/services/core/java/com/android/server/pm/dex/DexManager.java +++ b/services/core/java/com/android/server/pm/dex/DexManager.java @@ -785,10 +785,10 @@ public class DexManager { * files that can be direclty mapped. */ private static void logIfPackageHasUncompressedCode(PackageParser.Package pkg) { - logIfApkHasUncompressedCode(pkg.baseCodePath); + auditUncompressedCodeInApk(pkg.baseCodePath); if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) { for (int i = 0; i < pkg.splitCodePaths.length; i++) { - logIfApkHasUncompressedCode(pkg.splitCodePaths[i]); + auditUncompressedCodeInApk(pkg.splitCodePaths[i]); } } } @@ -797,34 +797,41 @@ public class DexManager { * Generates log if the archive located at {@code fileName} has uncompressed dex file and so * files that can be direclty mapped. */ - private static void logIfApkHasUncompressedCode(String fileName) { + public static boolean auditUncompressedCodeInApk(String fileName) { StrictJarFile jarFile = null; try { jarFile = new StrictJarFile(fileName, false /*verify*/, false /*signatureSchemeRollbackProtectionsEnforced*/); Iterator<ZipEntry> it = jarFile.iterator(); + boolean allCorrect = true; while (it.hasNext()) { ZipEntry entry = it.next(); if (entry.getName().endsWith(".dex")) { if (entry.getMethod() != ZipEntry.STORED) { + allCorrect = false; Slog.w(TAG, "APK " + fileName + " has compressed dex code " + entry.getName()); } else if ((entry.getDataOffset() & 0x3) != 0) { + allCorrect = false; Slog.w(TAG, "APK " + fileName + " has unaligned dex code " + entry.getName()); } } else if (entry.getName().endsWith(".so")) { if (entry.getMethod() != ZipEntry.STORED) { + allCorrect = false; Slog.w(TAG, "APK " + fileName + " has compressed native code " + entry.getName()); } else if ((entry.getDataOffset() & (0x1000 - 1)) != 0) { + allCorrect = false; Slog.w(TAG, "APK " + fileName + " has unaligned native code " + entry.getName()); } } } + return allCorrect; } catch (IOException ignore) { Slog.wtf(TAG, "Error when parsing APK " + fileName); + return false; } finally { try { if (jarFile != null) { diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index f370edf50708..c7928633eef6 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -844,7 +844,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { } private void interceptBackKeyDown() { - MetricsLogger.count(mContext, "key_back_down", 1); + mLogger.count("key_back_down", 1); // Reset back key state for long press mBackKeyHandled = false; @@ -858,6 +858,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { // returns true if the key was handled and should not be passed to the user private boolean interceptBackKeyUp(KeyEvent event) { + mLogger.count("key_back_up", 1); // Cache handled state boolean handled = mBackKeyHandled; diff --git a/services/core/java/com/android/server/wm/ActivityDisplay.java b/services/core/java/com/android/server/wm/ActivityDisplay.java index 973499f098b2..1f638c7f2e5d 100644 --- a/services/core/java/com/android/server/wm/ActivityDisplay.java +++ b/services/core/java/com/android/server/wm/ActivityDisplay.java @@ -37,6 +37,7 @@ import static com.android.server.am.ActivityDisplayProto.CONFIGURATION_CONTAINER import static com.android.server.am.ActivityDisplayProto.FOCUSED_STACK_ID; import static com.android.server.am.ActivityDisplayProto.ID; import static com.android.server.am.ActivityDisplayProto.RESUMED_ACTIVITY; +import static com.android.server.am.ActivityDisplayProto.SINGLE_TASK_INSTANCE; import static com.android.server.am.ActivityDisplayProto.STACKS; import static com.android.server.wm.ActivityStack.ActivityState.RESUMED; import static com.android.server.wm.ActivityStackSupervisor.TAG_TASKS; @@ -120,6 +121,9 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack> */ private boolean mRemoved; + /** The display can only contain one task. */ + private boolean mSingleTaskInstance; + /** * A focusable stack that is purposely to be positioned at the top. Although the stack may not * have the topmost index, it is used as a preferred candidate to prevent being unable to resume @@ -244,6 +248,10 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack> final ActivityStack prevFocusedStack = updateLastFocusedStackReason != null ? getFocusedStack() : null; final boolean wasContained = mStacks.remove(stack); + if (mSingleTaskInstance && getChildCount() > 0) { + throw new IllegalStateException( + "positionChildAt: Can only have one child on display=" + this); + } final int insertPosition = getTopInsertPosition(stack, position); mStacks.add(insertPosition, stack); @@ -403,6 +411,14 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack> */ <T extends ActivityStack> T createStack(int windowingMode, int activityType, boolean onTop) { + if (mSingleTaskInstance && getChildCount() > 0) { + // Create stack on default display instead since this display can only contain 1 stack. + // TODO: Kinda a hack, but better that having the decision at each call point. Hoping + // this goes away once ActivityView is no longer using virtual displays. + return mRootActivityContainer.getDefaultDisplay().createStack( + windowingMode, activityType, onTop); + } + if (activityType == ACTIVITY_TYPE_UNDEFINED) { // Can't have an undefined stack type yet...so re-map to standard. Anyone that wants // anything else should be passing it in anyways... @@ -1337,8 +1353,31 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack> } } + void setDisplayToSingleTaskInstance() { + final int childCount = getChildCount(); + if (childCount > 1) { + throw new IllegalArgumentException("Display already has multiple stacks. display=" + + this); + } + if (childCount > 0) { + final ActivityStack stack = getChildAt(0); + if (stack.getChildCount() > 1) { + throw new IllegalArgumentException("Display stack already has multiple tasks." + + " display=" + this + " stack=" + stack); + } + } + + mSingleTaskInstance = true; + } + + /** Returns true if the display can only contain one task */ + boolean isSingleTaskInstance() { + return mSingleTaskInstance; + } + public void dump(PrintWriter pw, String prefix) { - pw.println(prefix + "displayId=" + mDisplayId + " stacks=" + mStacks.size()); + pw.println(prefix + "displayId=" + mDisplayId + " stacks=" + mStacks.size() + + (mSingleTaskInstance ? " mSingleTaskInstance" : "")); final String myPrefix = prefix + " "; if (mHomeStack != null) { pw.println(myPrefix + "mHomeStack=" + mHomeStack); @@ -1373,6 +1412,7 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack> final long token = proto.start(fieldId); super.writeToProto(proto, CONFIGURATION_CONTAINER, false /* trim */); proto.write(ID, mDisplayId); + proto.write(SINGLE_TASK_INSTANCE, mSingleTaskInstance); final ActivityStack focusedStack = getFocusedStack(); if (focusedStack != null) { proto.write(FOCUSED_STACK_ID, focusedStack.mStackId); diff --git a/services/core/java/com/android/server/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java index 49cf8c76f594..4581a0f9f350 100644 --- a/services/core/java/com/android/server/wm/ActivityStack.java +++ b/services/core/java/com/android/server/wm/ActivityStack.java @@ -1144,6 +1144,12 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai } } + /** @return true if the stack can only contain one task */ + boolean isSingleTaskInstance() { + final ActivityDisplay display = getDisplay(); + return display != null && display.isSingleTaskInstance(); + } + final void removeActivitiesFromLRUListLocked(TaskRecord task) { for (ActivityRecord r : task.mActivities) { mLRUActivities.remove(r); @@ -5369,6 +5375,10 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai String reason) { // TODO: Is this remove really needed? Need to look into the call path for the other addTask mTaskHistory.remove(task); + if (isSingleTaskInstance() && !mTaskHistory.isEmpty()) { + throw new IllegalStateException("Can only have one child on stack=" + this); + } + position = getAdjustedPositionForTask(task, position, null /* starting */); final boolean toTop = position >= mTaskHistory.size(); final ActivityStack prevStack = preAddTask(task, reason, toTop); diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java index c4be1ba53706..86c5d4d1726d 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java @@ -4569,6 +4569,26 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } } + /** + * Makes the display with the given id a single task instance display. I.e the display can only + * contain one task. + */ + @Override + public void setDisplayToSingleTaskInstance(int displayId) { + mAmInternal.enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, + "setDisplayToSingleTaskInstance"); + final long origId = Binder.clearCallingIdentity(); + try { + final ActivityDisplay display = + mRootActivityContainer.getActivityDisplayOrCreate(displayId); + if (display != null) { + display.setDisplayToSingleTaskInstance(); + } + } finally { + Binder.restoreCallingIdentity(origId); + } + } + void dumpLastANRLocked(PrintWriter pw) { pw.println("ACTIVITY MANAGER LAST ANR (dumpsys activity lastanr)"); if (mLastANRState == null) { diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index a5ceee268fa2..fecc8da3d645 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -2506,6 +2506,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo mWmService.mAnimator.removeDisplayLocked(mDisplayId); mWindowingLayer.release(); mOverlayLayer.release(); + mInputMonitor.onDisplayRemoved(); } finally { mDisplayReady = false; mRemovingDisplay = false; diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java index fc1c65cf5807..632db3842839 100644 --- a/services/core/java/com/android/server/wm/InputMonitor.java +++ b/services/core/java/com/android/server/wm/InputMonitor.java @@ -32,6 +32,7 @@ import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TASK_POSITION import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; import android.graphics.Rect; +import android.os.Handler; import android.os.IBinder; import android.os.Looper; import android.os.Process; @@ -45,7 +46,9 @@ import android.view.InputChannel; import android.view.InputEventReceiver; import android.view.InputWindowHandle; import android.view.SurfaceControl; +import android.view.animation.Animation; +import com.android.server.AnimationThread; import com.android.server.policy.WindowManagerPolicy; import java.io.PrintWriter; @@ -60,6 +63,7 @@ final class InputMonitor { // When true, need to call updateInputWindowsLw(). private boolean mUpdateInputWindowsNeeded = true; + private boolean mUpdateInputWindowsPending; // Currently focused input window handle. private InputWindowHandle mFocusedInputWindowHandle; @@ -70,8 +74,11 @@ final class InputMonitor { new UpdateInputForAllWindowsConsumer(); private final int mDisplayId; + private final DisplayContent mDisplayContent; + private boolean mDisplayRemoved; private final SurfaceControl.Transaction mInputTransaction; + private final Handler mHandler; /** * The set of input consumer added to the window manager by name, which consumes input events @@ -105,10 +112,64 @@ final class InputMonitor { } } + private final Runnable mUpdateInputWindows = new Runnable() { + @Override + public void run() { + synchronized (mService.mGlobalLock) { + mUpdateInputWindowsPending = false; + mUpdateInputWindowsNeeded = false; + + if (mDisplayRemoved) { + return; + } + + // Populate the input window list with information about all of the windows that + // could potentially receive input. + // As an optimization, we could try to prune the list of windows but this turns + // out to be difficult because only the native code knows for sure which window + // currently has touch focus. + + // If there's a drag in flight, provide a pseudo-window to catch drag input + final boolean inDrag = mService.mDragDropController.dragDropActiveLocked(); + if (inDrag) { + if (DEBUG_DRAG) { + Log.d(TAG_WM, "Inserting drag window"); + } + mService.mDragDropController.showInputSurface(mInputTransaction, mDisplayId); + } else { + mService.mDragDropController.hideInputSurface(mInputTransaction, mDisplayId); + } + + final boolean inPositioning = + mService.mTaskPositioningController.isPositioningLocked(); + if (inPositioning) { + if (DEBUG_TASK_POSITIONING) { + Log.d(TAG_WM, "Inserting window handle for repositioning"); + } + mService.mTaskPositioningController.showInputSurface(mInputTransaction, + mDisplayId); + } else { + mService.mTaskPositioningController.hideInputSurface(mInputTransaction, + mDisplayId); + } + + // Add all windows on the default display. + mUpdateInputForAllWindowsConsumer.updateInputWindows(inDrag); + } + } + }; + public InputMonitor(WindowManagerService service, int displayId) { mService = service; + mDisplayContent = mService.mRoot.getDisplayContent(displayId); mDisplayId = displayId; - mInputTransaction = mService.mRoot.getDisplayContent(mDisplayId).getPendingTransaction(); + mInputTransaction = mDisplayContent.getPendingTransaction(); + mHandler = AnimationThread.getHandler(); + } + + void onDisplayRemoved() { + mHandler.removeCallbacks(mUpdateInputWindows); + mDisplayRemoved = true; } private void addInputConsumer(String name, InputConsumerImpl consumer) { @@ -248,41 +309,18 @@ final class InputMonitor { if (!force && !mUpdateInputWindowsNeeded) { return; } - mUpdateInputWindowsNeeded = false; - - if (false) Slog.d(TAG_WM, ">>>>>> ENTERED updateInputWindowsLw"); - - // Populate the input window list with information about all of the windows that - // could potentially receive input. - // As an optimization, we could try to prune the list of windows but this turns - // out to be difficult because only the native code knows for sure which window - // currently has touch focus. + scheduleUpdateInputWindows(); + } - // If there's a drag in flight, provide a pseudo-window to catch drag input - final boolean inDrag = mService.mDragDropController.dragDropActiveLocked(); - if (inDrag) { - if (DEBUG_DRAG) { - Log.d(TAG_WM, "Inserting drag window"); - } - mService.mDragDropController.showInputSurface(mInputTransaction, mDisplayId); - } else { - mService.mDragDropController.hideInputSurface(mInputTransaction, mDisplayId); + private void scheduleUpdateInputWindows() { + if (mDisplayRemoved) { + return; } - final boolean inPositioning = mService.mTaskPositioningController.isPositioningLocked(); - if (inPositioning) { - if (DEBUG_TASK_POSITIONING) { - Log.d(TAG_WM, "Inserting window handle for repositioning"); - } - mService.mTaskPositioningController.showInputSurface(mInputTransaction, mDisplayId); - } else { - mService.mTaskPositioningController.hideInputSurface(mInputTransaction, mDisplayId); + if (!mUpdateInputWindowsPending) { + mUpdateInputWindowsPending = true; + mHandler.post(mUpdateInputWindows); } - - // Add all windows on the default display. - mUpdateInputForAllWindowsConsumer.updateInputWindows(inDrag); - - if (false) Slog.d(TAG_WM, "<<<<<<< EXITED updateInputWindowsLw"); } /* Called when the current input focus changes. @@ -385,19 +423,18 @@ final class InputMonitor { mTmpRect.setEmpty(); mDisableWallpaperTouchEvents = false; this.inDrag = inDrag; - final DisplayContent dc = mService.mRoot.getDisplayContent(mDisplayId); - wallpaperController = dc.mWallpaperController; + wallpaperController = mDisplayContent.mWallpaperController; resetInputConsumers(mInputTransaction); - dc.forAllWindows(this, + mDisplayContent.forAllWindows(this, true /* traverseTopToBottom */); if (mAddWallpaperInputConsumerHandle) { wallpaperInputConsumer.show(mInputTransaction, 0); } - dc.scheduleAnimation(); + mDisplayContent.scheduleAnimation(); Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER); } diff --git a/services/core/java/com/android/server/wm/RootActivityContainer.java b/services/core/java/com/android/server/wm/RootActivityContainer.java index c63ee3e57c28..f55c7c96e325 100644 --- a/services/core/java/com/android/server/wm/RootActivityContainer.java +++ b/services/core/java/com/android/server/wm/RootActivityContainer.java @@ -913,6 +913,13 @@ class RootActivityContainer extends ConfigurationContainer + " to its current displayId=" + displayId); } + if (activityDisplay.isSingleTaskInstance() && activityDisplay.getChildCount() > 0) { + // We don't allow moving stacks to single instance display that already has a child. + Slog.e(TAG, "Can not move stack=" + stack + + " to single task instance display=" + activityDisplay); + return; + } + stack.reparent(activityDisplay, onTop, false /* displayRemoved */); // TODO(multi-display): resize stacks properly if moved from split-screen. } diff --git a/services/core/jni/BroadcastRadio/NativeCallbackThread.h b/services/core/jni/BroadcastRadio/NativeCallbackThread.h index 53990be06535..0f62de9c39df 100644 --- a/services/core/jni/BroadcastRadio/NativeCallbackThread.h +++ b/services/core/jni/BroadcastRadio/NativeCallbackThread.h @@ -41,7 +41,7 @@ class NativeCallbackThread { DISALLOW_COPY_AND_ASSIGN(NativeCallbackThread); public: - NativeCallbackThread(JavaVM *vm); + explicit NativeCallbackThread(JavaVM *vm); virtual ~NativeCallbackThread(); void enqueue(const Task &task); diff --git a/services/core/jni/BroadcastRadio/Tuner.cpp b/services/core/jni/BroadcastRadio/Tuner.cpp index 9c2e1e59dd32..a2a7f7d9645d 100644 --- a/services/core/jni/BroadcastRadio/Tuner.cpp +++ b/services/core/jni/BroadcastRadio/Tuner.cpp @@ -73,7 +73,8 @@ class HalDeathRecipient : public hidl_death_recipient { wp<V1_1::ITunerCallback> mTunerCallback; public: - HalDeathRecipient(wp<V1_1::ITunerCallback> tunerCallback):mTunerCallback(tunerCallback) {} + explicit HalDeathRecipient(wp<V1_1::ITunerCallback> tunerCallback) + : mTunerCallback(tunerCallback) {} virtual void serviceDied(uint64_t cookie, const wp<hidl::base::V1_0::IBase>& who); }; diff --git a/services/core/jni/com_android_server_hdmi_HdmiCecController.cpp b/services/core/jni/com_android_server_hdmi_HdmiCecController.cpp index c22109c7816a..b08d13f234ce 100644 --- a/services/core/jni/com_android_server_hdmi_HdmiCecController.cpp +++ b/services/core/jni/com_android_server_hdmi_HdmiCecController.cpp @@ -89,7 +89,7 @@ public: private: class HdmiCecCallback : public IHdmiCecCallback { public: - HdmiCecCallback(HdmiCecController* controller) : mController(controller) {}; + explicit HdmiCecCallback(HdmiCecController* controller) : mController(controller) {}; Return<void> onCecMessage(const CecMessage& event) override; Return<void> onHotplugEvent(const HotplugEvent& event) override; private: diff --git a/services/core/jni/com_android_server_storage_AppFuseBridge.cpp b/services/core/jni/com_android_server_storage_AppFuseBridge.cpp index c8f842dde7ae..e51963340ae1 100644 --- a/services/core/jni/com_android_server_storage_AppFuseBridge.cpp +++ b/services/core/jni/com_android_server_storage_AppFuseBridge.cpp @@ -74,7 +74,7 @@ public: } } - operator bool() { + explicit operator bool() { return mLocked; } diff --git a/services/core/jni/com_android_server_tv_TvInputHal.cpp b/services/core/jni/com_android_server_tv_TvInputHal.cpp index 6c2a894a3a6a..098b2ef6439d 100644 --- a/services/core/jni/com_android_server_tv_TvInputHal.cpp +++ b/services/core/jni/com_android_server_tv_TvInputHal.cpp @@ -292,7 +292,7 @@ private: class TvInputCallback : public ITvInputCallback { public: - TvInputCallback(JTvInputHal* hal); + explicit TvInputCallback(JTvInputHal* hal); Return<void> notify(const TvInputEvent& event) override; private: JTvInputHal* mHal; diff --git a/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java b/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java index afbe6bc21d0d..9d847514435e 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java @@ -1015,6 +1015,22 @@ public class BuzzBeepBlinkTest extends UiServiceTestCase { } @Test + public void testCanceledNoisyNeverVibrate() throws Exception { + NotificationRecord r = getBuzzyBeepyNotification(); + + final int waitMs = mAudioManager.getFocusRampTimeMs( + AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK, + r.getAudioAttributes()); + + mService.buzzBeepBlinkLocked(r); + mService.clearNotifications(); + + verifyNeverVibrate(); + Thread.sleep(waitMs); + verifyNeverVibrate(); + } + + @Test public void testEmptyUriSoundTreatedAsNoSound() throws Exception { NotificationChannel channel = new NotificationChannel("test", "test", IMPORTANCE_HIGH); channel.setSound(Uri.EMPTY, null); diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java index 659c6e7aeed3..8b65e763b088 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java @@ -859,6 +859,19 @@ public class ManagedServicesTest extends UiServiceTestCase { assertTrue(componentsToBind.get(10).contains(ComponentName.unflattenFromString("c/c"))); } + @Test + public void testOnPackagesChanged_nullValuesPassed_noNullPointers() { + for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) { + ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles, + mIpm, approvalLevel); + // null uid list + service.onPackagesChanged(true, new String[]{"this.is.a.package.name"}, null); + + // null package list + service.onPackagesChanged(true, null, new int[]{103}); + } + } + private void loadXml(ManagedServices service) throws Exception { final StringBuffer xml = new StringBuffer(); xml.append("<" + service.getConfig().xmlTag + ">\n"); diff --git a/wifi/java/android/net/wifi/DppStatusCallback.java b/wifi/java/android/net/wifi/DppStatusCallback.java new file mode 100644 index 000000000000..fa2ab30ef479 --- /dev/null +++ b/wifi/java/android/net/wifi/DppStatusCallback.java @@ -0,0 +1,166 @@ +/* + * 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.net.wifi; + +import android.annotation.IntDef; +import android.annotation.SystemApi; +import android.os.Handler; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * DPP Status Callback. Use this callback to get status updates (success, failure, progress) + * from the DPP operation started with {@link WifiManager#startDppAsConfiguratorInitiator(String, + * int, int, Handler, DppStatusCallback)} or {@link WifiManager#startDppAsEnrolleeInitiator(String, + * Handler, DppStatusCallback)} + * @hide + */ +@SystemApi +public abstract class DppStatusCallback { + /** + * DPP Success event: Configuration sent (Configurator mode). + */ + public static final int DPP_EVENT_SUCCESS_CONFIGURATION_SENT = 0; + + /** @hide */ + @IntDef(prefix = { "DPP_EVENT_SUCCESS_" }, value = { + DPP_EVENT_SUCCESS_CONFIGURATION_SENT, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface DppSuccessStatusCode {} + + /** + * DPP Progress event: Initial authentication with peer succeeded. + */ + public static final int DPP_EVENT_PROGRESS_AUTHENTICATION_SUCCESS = 0; + + /** + * DPP Progress event: Peer requires more time to process bootstrapping. + */ + public static final int DPP_EVENT_PROGRESS_RESPONSE_PENDING = 1; + + /** @hide */ + @IntDef(prefix = { "DPP_EVENT_PROGRESS_" }, value = { + DPP_EVENT_PROGRESS_AUTHENTICATION_SUCCESS, + DPP_EVENT_PROGRESS_RESPONSE_PENDING, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface DppProgressStatusCode {} + + /** + * DPP Failure event: Scanned QR code is either not a DPP URI, or the DPP URI has errors. + */ + public static final int DPP_EVENT_FAILURE_INVALID_URI = -1; + + /** + * DPP Failure event: Bootstrapping/Authentication initialization process failure. + */ + public static final int DPP_EVENT_FAILURE_AUTHENTICATION = -2; + + /** + * DPP Failure event: Both devices are implementing the same role and are incompatible. + */ + public static final int DPP_EVENT_FAILURE_NOT_COMPATIBLE = -3; + + /** + * DPP Failure event: Configuration process has failed due to malformed message. + */ + public static final int DPP_EVENT_FAILURE_CONFIGURATION = -4; + + /** + * DPP Failure event: DPP request while in another DPP exchange. + */ + public static final int DPP_EVENT_FAILURE_BUSY = -5; + + /** + * DPP Failure event: No response from the peer. + */ + public static final int DPP_EVENT_FAILURE_TIMEOUT = -6; + + /** + * DPP Failure event: General protocol failure. + */ + public static final int DPP_EVENT_FAILURE = -7; + + /** + * DPP Failure event: Feature or option is not supported. + */ + public static final int DPP_EVENT_FAILURE_NOT_SUPPORTED = -8; + + /** + * DPP Failure event: Invalid network provided to DPP configurator. + * Network must either be WPA3-Personal (SAE) or WPA2-Personal (PSK). + */ + public static final int DPP_EVENT_FAILURE_INVALID_NETWORK = -9; + + + /** @hide */ + @IntDef(prefix = {"DPP_EVENT_FAILURE_"}, value = { + DPP_EVENT_FAILURE_INVALID_URI, + DPP_EVENT_FAILURE_AUTHENTICATION, + DPP_EVENT_FAILURE_NOT_COMPATIBLE, + DPP_EVENT_FAILURE_CONFIGURATION, + DPP_EVENT_FAILURE_BUSY, + DPP_EVENT_FAILURE_TIMEOUT, + DPP_EVENT_FAILURE, + DPP_EVENT_FAILURE_NOT_SUPPORTED, + DPP_EVENT_FAILURE_INVALID_NETWORK, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface DppFailureStatusCode { + } + + /** + * Called when local DPP Enrollee successfully receives a new Wi-Fi configuration from the + * peer DPP configurator. This callback marks the successful end of the DPP current DPP + * session, and no further callbacks will be called. This callback is the successful outcome + * of a DPP flow starting with {@link WifiManager#startDppAsEnrolleeInitiator(String, Handler, + * DppStatusCallback)}. + * + * @param newNetworkId New Wi-Fi configuration with a network ID received from the configurator + */ + public abstract void onEnrolleeSuccess(int newNetworkId); + + /** + * Called when a DPP success event takes place, except for when configuration is received from + * an external Configurator. The callback onSuccessConfigReceived will be used in this case. + * This callback marks the successful end of the current DPP session, and no further + * callbacks will be called. This callback is the successful outcome of a DPP flow starting with + * {@link WifiManager#startDppAsConfiguratorInitiator(String, int, int, Handler, + * DppStatusCallback)}. + * + * @param code DPP success status code. + */ + public abstract void onConfiguratorSuccess(@DppSuccessStatusCode int code); + + /** + * Called when a DPP Failure event takes place. This callback marks the unsuccessful end of the + * current DPP session, and no further callbacks will be called. + * + * @param code DPP failure status code. + */ + public abstract void onFailure(@DppFailureStatusCode int code); + + /** + * Called when DPP events that indicate progress take place. Can be used by UI elements + * to show progress. + * + * @param code DPP progress status code. + */ + public abstract void onProgress(@DppProgressStatusCode int code); +} diff --git a/wifi/java/android/net/wifi/IDppCallback.aidl b/wifi/java/android/net/wifi/IDppCallback.aidl new file mode 100644 index 000000000000..c452c7664c12 --- /dev/null +++ b/wifi/java/android/net/wifi/IDppCallback.aidl @@ -0,0 +1,48 @@ +/* + * 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.net.wifi; + +/** + * Interface for DPP callback. + * + * @hide + */ +oneway interface IDppCallback +{ + /** + * Called when local DPP Enrollee successfully receives a new Wi-Fi configuratrion from the + * peer DPP configurator. + */ + void onSuccessConfigReceived(int newNetworkId); + + /** + * Called when DPP success events take place, except for when configuration is received from + * an external Configurator. The callback onSuccessConfigReceived will be used in this case. + */ + void onSuccess(int status); + + /** + * Called when DPP Failure events take place. + */ + void onFailure(int status); + + /** + * Called when DPP events that indicate progress take place. Can be used by UI elements + * to show progress. + */ + void onProgress(int status); +} diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl index 0362a1b491ea..1700006f939d 100644 --- a/wifi/java/android/net/wifi/IWifiManager.aidl +++ b/wifi/java/android/net/wifi/IWifiManager.aidl @@ -25,6 +25,7 @@ import android.net.wifi.hotspot2.IProvisioningCallback; import android.net.DhcpInfo; import android.net.Network; +import android.net.wifi.IDppCallback; import android.net.wifi.INetworkRequestMatchCallback; import android.net.wifi.ISoftApCallback; import android.net.wifi.ITrafficStateCallback; @@ -199,5 +200,13 @@ interface IWifiManager String[] getFactoryMacAddresses(); void setDeviceMobilityState(int state); + + void startDppAsConfiguratorInitiator(in IBinder binder, in String enrolleeUri, + int selectedNetworkId, int netRole, in IDppCallback callback); + + void startDppAsEnrolleeInitiator(in IBinder binder, in String configuratorUri, + in IDppCallback callback); + + void stopDppSession(); } diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index a7c2ff0f875c..e67e8ea7d9ab 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -2017,6 +2017,8 @@ public class WifiManager { public static final int WIFI_FEATURE_OWE = 0x20000000; // Enhanced Open /** @hide */ public static final int WIFI_FEATURE_LOW_LATENCY = 0x40000000; // Low Latency modes + /** @hide */ + public static final int WIFI_FEATURE_DPP = 0x80000000; // DPP (Easy-Connect) private int getSupportedFeatures() { try { @@ -4463,6 +4465,13 @@ public class WifiManager { } /** + * @return true if this device supports Wi-Fi Device Provisioning Protocol (Easy-connect) + */ + public boolean isDppSupported() { + return isFeatureSupported(WIFI_FEATURE_DPP); + } + + /** * Gets the factory Wi-Fi MAC addresses. * @return Array of String representing Wi-Fi MAC addresses sorted lexically or an empty Array * if failed. @@ -4541,4 +4550,146 @@ public class WifiManager { throw e.rethrowFromSystemServer(); } } + + /* DPP - Device Provisioning Protocol AKA "Easy Connect" */ + + /** + * DPP Network role: Station. + * @hide + */ + @SystemApi + public static final int DPP_NETWORK_ROLE_STA = 0; + + /** + * DPP Network role: Access Point. + * @hide + */ + @SystemApi + public static final int DPP_NETWORK_ROLE_AP = 1; + + /** @hide */ + @IntDef(prefix = {"DPP_NETWORK_ROLE_"}, value = { + DPP_NETWORK_ROLE_STA, + DPP_NETWORK_ROLE_AP, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface DppNetworkRole {} + + /** + * Start DPP in Configurator-Initiator role. The current device will initiate DPP bootstrapping + * with a peer, and configure the peer with the SSID and password of the specified network using + * the DPP protocol on an encrypted link. + * + * @param enrolleeUri URI of the Enrollee obtained separately (e.g. QR code scanning) + * @param selectedNetworkId Selected network ID to be sent to the peer + * @param enrolleeNetworkRole The network role of the enrollee + * @param callback Callback for status updates + * @param handler The handler on whose thread to execute the callbacks. Null for main thread. + * @hide + */ + @SystemApi + @RequiresPermission(anyOf = { + android.Manifest.permission.NETWORK_SETTINGS, + android.Manifest.permission.NETWORK_SETUP_WIZARD}) + public void startDppAsConfiguratorInitiator(@NonNull String enrolleeUri, + int selectedNetworkId, @DppNetworkRole int enrolleeNetworkRole, + @Nullable Handler handler, @NonNull DppStatusCallback callback) { + Looper looper = (handler == null) ? Looper.getMainLooper() : handler.getLooper(); + Binder binder = new Binder(); + try { + mService.startDppAsConfiguratorInitiator(binder, enrolleeUri, selectedNetworkId, + enrolleeNetworkRole, new DppCallbackProxy(looper, callback)); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * Start DPP in Enrollee-Initiator role. The current device will initiate DPP bootstrapping + * with a peer, and receive the SSID and password from the peer configurator. + * + * @param configuratorUri URI of the Configurator obtained separately (e.g. QR code scanning) + * @param callback Callback for status updates + * @param handler The handler on whose thread to execute the callbacks. Null for main thread. + * @hide + */ + @SystemApi + @RequiresPermission(anyOf = { + android.Manifest.permission.NETWORK_SETTINGS, + android.Manifest.permission.NETWORK_SETUP_WIZARD}) + public void startDppAsEnrolleeInitiator(@NonNull String configuratorUri, + @Nullable Handler handler, @NonNull DppStatusCallback callback) { + Looper looper = (handler == null) ? Looper.getMainLooper() : handler.getLooper(); + Binder binder = new Binder(); + try { + mService.startDppAsEnrolleeInitiator(binder, configuratorUri, + new DppCallbackProxy(looper, callback)); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * Stop or abort a current DPP session. + * @hide + */ + @SystemApi + @RequiresPermission(anyOf = { + android.Manifest.permission.NETWORK_SETTINGS, + android.Manifest.permission.NETWORK_SETUP_WIZARD}) + public void stopDppSession() { + try { + /* Request lower layers to stop/abort and clear resources */ + mService.stopDppSession(); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * Helper class to support DPP callbacks + * @hide + */ + @SystemApi + private static class DppCallbackProxy extends IDppCallback.Stub { + private final Handler mHandler; + private final DppStatusCallback mDppStatusCallback; + + DppCallbackProxy(Looper looper, DppStatusCallback dppStatusCallback) { + mHandler = new Handler(looper); + mDppStatusCallback = dppStatusCallback; + } + + @Override + public void onSuccessConfigReceived(int newNetworkId) { + Log.d(TAG, "DPP onSuccessConfigReceived callback"); + mHandler.post(() -> { + mDppStatusCallback.onEnrolleeSuccess(newNetworkId); + }); + } + + @Override + public void onSuccess(int status) { + Log.d(TAG, "DPP onSuccess callback"); + mHandler.post(() -> { + mDppStatusCallback.onConfiguratorSuccess(status); + }); + } + + @Override + public void onFailure(int status) { + Log.d(TAG, "DPP onFailure callback"); + mHandler.post(() -> { + mDppStatusCallback.onFailure(status); + }); + } + + @Override + public void onProgress(int status) { + Log.d(TAG, "DPP onProgress callback"); + mHandler.post(() -> { + mDppStatusCallback.onProgress(status); + }); + } + } } |