diff options
186 files changed, 3213 insertions, 2063 deletions
diff --git a/api/current.txt b/api/current.txt index 87947809ee2b..db175427139c 100644 --- a/api/current.txt +++ b/api/current.txt @@ -291,6 +291,7 @@ package android { field public static final int allowBackup = 16843392; // 0x1010280 field public static final int allowClearUserData = 16842757; // 0x1010005 field public static final int allowEmbedded = 16843765; // 0x10103f5 + field public static final int allowExternalStorageSandbox = 16844201; // 0x10105a9 field public static final int allowParallelSyncs = 16843570; // 0x1010332 field public static final int allowSingleTap = 16843353; // 0x1010259 field public static final int allowTaskReparenting = 16843268; // 0x1010204 @@ -11534,107 +11535,107 @@ package android.content.pm { public abstract class PackageManager { ctor public PackageManager(); - method @Deprecated public abstract void addPackageToPreferred(String); - method public abstract boolean addPermission(android.content.pm.PermissionInfo); - method public abstract boolean addPermissionAsync(android.content.pm.PermissionInfo); - method @Deprecated public abstract void addPreferredActivity(android.content.IntentFilter, int, android.content.ComponentName[], android.content.ComponentName); + method @Deprecated public abstract void addPackageToPreferred(@NonNull String); + method public abstract boolean addPermission(@NonNull android.content.pm.PermissionInfo); + method public abstract boolean addPermissionAsync(@NonNull android.content.pm.PermissionInfo); + method @Deprecated public abstract void addPreferredActivity(@NonNull android.content.IntentFilter, int, @Nullable android.content.ComponentName[], @NonNull android.content.ComponentName); method public abstract boolean canRequestPackageInstalls(); - method public abstract String[] canonicalToCurrentPackageNames(String[]); - method @CheckResult public abstract int checkPermission(String, String); - method @CheckResult public abstract int checkSignatures(String, String); + method public abstract String[] canonicalToCurrentPackageNames(@NonNull String[]); + method @CheckResult public abstract int checkPermission(@NonNull String, @NonNull String); + method @CheckResult public abstract int checkSignatures(@NonNull String, @NonNull String); method @CheckResult public abstract int checkSignatures(int, int); method public abstract void clearInstantAppCookie(); - method @Deprecated public abstract void clearPackagePreferredActivities(String); - method public abstract String[] currentToCanonicalPackageNames(String[]); + method @Deprecated public abstract void clearPackagePreferredActivities(@NonNull String); + method public abstract String[] currentToCanonicalPackageNames(@NonNull String[]); method public abstract void extendVerificationTimeout(int, int, long); - method public abstract android.graphics.drawable.Drawable getActivityBanner(android.content.ComponentName) throws android.content.pm.PackageManager.NameNotFoundException; - method public abstract android.graphics.drawable.Drawable getActivityBanner(android.content.Intent) throws android.content.pm.PackageManager.NameNotFoundException; - method public abstract android.graphics.drawable.Drawable getActivityIcon(android.content.ComponentName) throws android.content.pm.PackageManager.NameNotFoundException; - method public abstract android.graphics.drawable.Drawable getActivityIcon(android.content.Intent) throws android.content.pm.PackageManager.NameNotFoundException; - method public abstract android.content.pm.ActivityInfo getActivityInfo(android.content.ComponentName, int) throws android.content.pm.PackageManager.NameNotFoundException; - method public abstract android.graphics.drawable.Drawable getActivityLogo(android.content.ComponentName) throws android.content.pm.PackageManager.NameNotFoundException; - method public abstract android.graphics.drawable.Drawable getActivityLogo(android.content.Intent) throws android.content.pm.PackageManager.NameNotFoundException; - method public abstract java.util.List<android.content.pm.PermissionGroupInfo> getAllPermissionGroups(int); - method public abstract android.graphics.drawable.Drawable getApplicationBanner(android.content.pm.ApplicationInfo); - method public abstract android.graphics.drawable.Drawable getApplicationBanner(String) throws android.content.pm.PackageManager.NameNotFoundException; + method @Nullable public abstract android.graphics.drawable.Drawable getActivityBanner(@NonNull android.content.ComponentName) throws android.content.pm.PackageManager.NameNotFoundException; + method @Nullable public abstract android.graphics.drawable.Drawable getActivityBanner(@NonNull android.content.Intent) throws android.content.pm.PackageManager.NameNotFoundException; + method @NonNull public abstract android.graphics.drawable.Drawable getActivityIcon(@NonNull android.content.ComponentName) throws android.content.pm.PackageManager.NameNotFoundException; + method @NonNull public abstract android.graphics.drawable.Drawable getActivityIcon(@NonNull android.content.Intent) throws android.content.pm.PackageManager.NameNotFoundException; + method @NonNull public abstract android.content.pm.ActivityInfo getActivityInfo(@NonNull android.content.ComponentName, int) throws android.content.pm.PackageManager.NameNotFoundException; + method @Nullable public abstract android.graphics.drawable.Drawable getActivityLogo(@NonNull android.content.ComponentName) throws android.content.pm.PackageManager.NameNotFoundException; + method @Nullable public abstract android.graphics.drawable.Drawable getActivityLogo(@NonNull android.content.Intent) throws android.content.pm.PackageManager.NameNotFoundException; + method @NonNull public abstract java.util.List<android.content.pm.PermissionGroupInfo> getAllPermissionGroups(int); + method @Nullable public abstract android.graphics.drawable.Drawable getApplicationBanner(@NonNull android.content.pm.ApplicationInfo); + method @Nullable public abstract android.graphics.drawable.Drawable getApplicationBanner(@NonNull String) throws android.content.pm.PackageManager.NameNotFoundException; method public abstract int getApplicationEnabledSetting(@NonNull String); - method public abstract android.graphics.drawable.Drawable getApplicationIcon(android.content.pm.ApplicationInfo); - method public abstract android.graphics.drawable.Drawable getApplicationIcon(String) throws android.content.pm.PackageManager.NameNotFoundException; - method public abstract android.content.pm.ApplicationInfo getApplicationInfo(String, int) throws android.content.pm.PackageManager.NameNotFoundException; - method public abstract CharSequence getApplicationLabel(android.content.pm.ApplicationInfo); - method public abstract android.graphics.drawable.Drawable getApplicationLogo(android.content.pm.ApplicationInfo); - method public abstract android.graphics.drawable.Drawable getApplicationLogo(String) throws android.content.pm.PackageManager.NameNotFoundException; + method @NonNull public abstract android.graphics.drawable.Drawable getApplicationIcon(@NonNull android.content.pm.ApplicationInfo); + method @NonNull public abstract android.graphics.drawable.Drawable getApplicationIcon(@NonNull String) throws android.content.pm.PackageManager.NameNotFoundException; + method @NonNull public abstract android.content.pm.ApplicationInfo getApplicationInfo(@NonNull String, int) throws android.content.pm.PackageManager.NameNotFoundException; + method @NonNull public abstract CharSequence getApplicationLabel(@NonNull android.content.pm.ApplicationInfo); + method @Nullable public abstract android.graphics.drawable.Drawable getApplicationLogo(@NonNull android.content.pm.ApplicationInfo); + method @Nullable public abstract android.graphics.drawable.Drawable getApplicationLogo(@NonNull String) throws android.content.pm.PackageManager.NameNotFoundException; method @Nullable public abstract android.content.pm.ChangedPackages getChangedPackages(@IntRange(from=0) int); method public abstract int getComponentEnabledSetting(@NonNull android.content.ComponentName); - method public abstract android.graphics.drawable.Drawable getDefaultActivityIcon(); - method public abstract android.graphics.drawable.Drawable getDrawable(String, @DrawableRes int, android.content.pm.ApplicationInfo); - method public abstract java.util.List<android.content.pm.ApplicationInfo> getInstalledApplications(int); + method @NonNull public abstract android.graphics.drawable.Drawable getDefaultActivityIcon(); + method @Nullable public abstract android.graphics.drawable.Drawable getDrawable(@NonNull String, @DrawableRes int, @Nullable android.content.pm.ApplicationInfo); + method @NonNull public abstract java.util.List<android.content.pm.ApplicationInfo> getInstalledApplications(int); method @NonNull public java.util.List<android.content.pm.ModuleInfo> getInstalledModules(int); - method public abstract java.util.List<android.content.pm.PackageInfo> getInstalledPackages(int); - method @Nullable public abstract String getInstallerPackageName(String); + method @NonNull public abstract java.util.List<android.content.pm.PackageInfo> getInstalledPackages(int); + method @Nullable public abstract String getInstallerPackageName(@NonNull String); method @NonNull public abstract byte[] getInstantAppCookie(); method public abstract int getInstantAppCookieMaxBytes(); - method public abstract android.content.pm.InstrumentationInfo getInstrumentationInfo(android.content.ComponentName, int) throws android.content.pm.PackageManager.NameNotFoundException; + method @NonNull public abstract android.content.pm.InstrumentationInfo getInstrumentationInfo(@NonNull android.content.ComponentName, int) throws android.content.pm.PackageManager.NameNotFoundException; method @Nullable public abstract android.content.Intent getLaunchIntentForPackage(@NonNull String); method @Nullable public abstract android.content.Intent getLeanbackLaunchIntentForPackage(@NonNull String); - method public android.content.pm.ModuleInfo getModuleInfo(String, int) throws android.content.pm.PackageManager.NameNotFoundException; + method @NonNull public android.content.pm.ModuleInfo getModuleInfo(@NonNull String, int) throws android.content.pm.PackageManager.NameNotFoundException; method @Nullable public abstract String getNameForUid(int); - method public android.content.pm.PackageInfo getPackageArchiveInfo(String, int); + method @Nullable public android.content.pm.PackageInfo getPackageArchiveInfo(@NonNull String, int); method public abstract int[] getPackageGids(@NonNull String) throws android.content.pm.PackageManager.NameNotFoundException; - method public abstract int[] getPackageGids(String, int) throws android.content.pm.PackageManager.NameNotFoundException; - method public abstract android.content.pm.PackageInfo getPackageInfo(String, int) throws android.content.pm.PackageManager.NameNotFoundException; - method public abstract android.content.pm.PackageInfo getPackageInfo(android.content.pm.VersionedPackage, int) throws android.content.pm.PackageManager.NameNotFoundException; + method public abstract int[] getPackageGids(@NonNull String, int) throws android.content.pm.PackageManager.NameNotFoundException; + method public abstract android.content.pm.PackageInfo getPackageInfo(@NonNull String, int) throws android.content.pm.PackageManager.NameNotFoundException; + method public abstract android.content.pm.PackageInfo getPackageInfo(@NonNull android.content.pm.VersionedPackage, int) throws android.content.pm.PackageManager.NameNotFoundException; method @NonNull public abstract android.content.pm.PackageInstaller getPackageInstaller(); - method public abstract int getPackageUid(String, int) throws android.content.pm.PackageManager.NameNotFoundException; + method public abstract int getPackageUid(@NonNull String, int) throws android.content.pm.PackageManager.NameNotFoundException; method @Nullable public abstract String[] getPackagesForUid(int); - method public abstract java.util.List<android.content.pm.PackageInfo> getPackagesHoldingPermissions(String[], int); - method public abstract android.content.pm.PermissionGroupInfo getPermissionGroupInfo(String, int) throws android.content.pm.PackageManager.NameNotFoundException; - method public abstract android.content.pm.PermissionInfo getPermissionInfo(String, int) throws android.content.pm.PackageManager.NameNotFoundException; - method @Deprecated public abstract int getPreferredActivities(@NonNull java.util.List<android.content.IntentFilter>, @NonNull java.util.List<android.content.ComponentName>, String); - method @Deprecated public abstract java.util.List<android.content.pm.PackageInfo> getPreferredPackages(int); - method public abstract android.content.pm.ProviderInfo getProviderInfo(android.content.ComponentName, int) throws android.content.pm.PackageManager.NameNotFoundException; - method public abstract android.content.pm.ActivityInfo getReceiverInfo(android.content.ComponentName, int) throws android.content.pm.PackageManager.NameNotFoundException; - method public abstract android.content.res.Resources getResourcesForActivity(android.content.ComponentName) throws android.content.pm.PackageManager.NameNotFoundException; - method public abstract android.content.res.Resources getResourcesForApplication(android.content.pm.ApplicationInfo) throws android.content.pm.PackageManager.NameNotFoundException; - method public abstract android.content.res.Resources getResourcesForApplication(String) throws android.content.pm.PackageManager.NameNotFoundException; - method public abstract android.content.pm.ServiceInfo getServiceInfo(android.content.ComponentName, int) throws android.content.pm.PackageManager.NameNotFoundException; + method @NonNull public abstract java.util.List<android.content.pm.PackageInfo> getPackagesHoldingPermissions(@NonNull String[], int); + method @NonNull public abstract android.content.pm.PermissionGroupInfo getPermissionGroupInfo(@NonNull String, int) throws android.content.pm.PackageManager.NameNotFoundException; + method public abstract android.content.pm.PermissionInfo getPermissionInfo(@NonNull String, int) throws android.content.pm.PackageManager.NameNotFoundException; + method @Deprecated public abstract int getPreferredActivities(@NonNull java.util.List<android.content.IntentFilter>, @NonNull java.util.List<android.content.ComponentName>, @Nullable String); + method @Deprecated @NonNull public abstract java.util.List<android.content.pm.PackageInfo> getPreferredPackages(int); + method @NonNull public abstract android.content.pm.ProviderInfo getProviderInfo(@NonNull android.content.ComponentName, int) throws android.content.pm.PackageManager.NameNotFoundException; + method @NonNull public abstract android.content.pm.ActivityInfo getReceiverInfo(@NonNull android.content.ComponentName, int) throws android.content.pm.PackageManager.NameNotFoundException; + method @NonNull public abstract android.content.res.Resources getResourcesForActivity(@NonNull android.content.ComponentName) throws android.content.pm.PackageManager.NameNotFoundException; + method @NonNull public abstract android.content.res.Resources getResourcesForApplication(@NonNull android.content.pm.ApplicationInfo) throws android.content.pm.PackageManager.NameNotFoundException; + method @NonNull public abstract android.content.res.Resources getResourcesForApplication(@NonNull String) throws android.content.pm.PackageManager.NameNotFoundException; + method @NonNull public abstract android.content.pm.ServiceInfo getServiceInfo(@NonNull android.content.ComponentName, int) throws android.content.pm.PackageManager.NameNotFoundException; method @NonNull public abstract java.util.List<android.content.pm.SharedLibraryInfo> getSharedLibraries(int); method @Nullable public android.os.Bundle getSuspendedPackageAppExtras(); method public boolean getSyntheticAppDetailsActivityEnabled(@NonNull String); - method public abstract android.content.pm.FeatureInfo[] getSystemAvailableFeatures(); - method public abstract String[] getSystemSharedLibraryNames(); - method public abstract CharSequence getText(String, @StringRes int, android.content.pm.ApplicationInfo); - method public abstract android.graphics.drawable.Drawable getUserBadgedDrawableForDensity(android.graphics.drawable.Drawable, android.os.UserHandle, android.graphics.Rect, int); - method public abstract android.graphics.drawable.Drawable getUserBadgedIcon(android.graphics.drawable.Drawable, android.os.UserHandle); - method public abstract CharSequence getUserBadgedLabel(CharSequence, android.os.UserHandle); - method public abstract android.content.res.XmlResourceParser getXml(String, @XmlRes int, android.content.pm.ApplicationInfo); - method public boolean hasSigningCertificate(String, byte[], int); - method public boolean hasSigningCertificate(int, byte[], int); - method public abstract boolean hasSystemFeature(String); - method public abstract boolean hasSystemFeature(String, int); + method @NonNull public abstract android.content.pm.FeatureInfo[] getSystemAvailableFeatures(); + method @Nullable public abstract String[] getSystemSharedLibraryNames(); + method @Nullable public abstract CharSequence getText(@NonNull String, @StringRes int, @Nullable android.content.pm.ApplicationInfo); + method @NonNull public abstract android.graphics.drawable.Drawable getUserBadgedDrawableForDensity(@NonNull android.graphics.drawable.Drawable, @NonNull android.os.UserHandle, @Nullable android.graphics.Rect, int); + method @NonNull public abstract android.graphics.drawable.Drawable getUserBadgedIcon(@NonNull android.graphics.drawable.Drawable, @NonNull android.os.UserHandle); + method @NonNull public abstract CharSequence getUserBadgedLabel(@NonNull CharSequence, @NonNull android.os.UserHandle); + method @Nullable public abstract android.content.res.XmlResourceParser getXml(@NonNull String, @XmlRes int, @Nullable android.content.pm.ApplicationInfo); + method public boolean hasSigningCertificate(@NonNull String, @NonNull byte[], int); + method public boolean hasSigningCertificate(int, @NonNull byte[], int); + method public abstract boolean hasSystemFeature(@NonNull String); + method public abstract boolean hasSystemFeature(@NonNull String, int); method public abstract boolean isInstantApp(); - method public abstract boolean isInstantApp(String); - method public boolean isPackageSuspended(String) throws android.content.pm.PackageManager.NameNotFoundException; + method public abstract boolean isInstantApp(@NonNull String); + method public boolean isPackageSuspended(@NonNull String) throws android.content.pm.PackageManager.NameNotFoundException; method public boolean isPackageSuspended(); method @CheckResult public abstract boolean isPermissionRevokedByPolicy(@NonNull String, @NonNull String); method public abstract boolean isSafeMode(); - method public abstract java.util.List<android.content.pm.ResolveInfo> queryBroadcastReceivers(android.content.Intent, int); - method public abstract java.util.List<android.content.pm.ProviderInfo> queryContentProviders(String, int, int); - method public abstract java.util.List<android.content.pm.InstrumentationInfo> queryInstrumentation(String, int); - method public abstract java.util.List<android.content.pm.ResolveInfo> queryIntentActivities(android.content.Intent, int); - method public abstract java.util.List<android.content.pm.ResolveInfo> queryIntentActivityOptions(@Nullable android.content.ComponentName, @Nullable android.content.Intent[], android.content.Intent, int); - method public abstract java.util.List<android.content.pm.ResolveInfo> queryIntentContentProviders(android.content.Intent, int); - method public abstract java.util.List<android.content.pm.ResolveInfo> queryIntentServices(android.content.Intent, int); - method public abstract java.util.List<android.content.pm.PermissionInfo> queryPermissionsByGroup(String, int) throws android.content.pm.PackageManager.NameNotFoundException; - method @Deprecated public abstract void removePackageFromPreferred(String); - method public abstract void removePermission(String); - method public abstract android.content.pm.ResolveInfo resolveActivity(android.content.Intent, int); - method public abstract android.content.pm.ProviderInfo resolveContentProvider(String, int); - method public abstract android.content.pm.ResolveInfo resolveService(android.content.Intent, int); + method @NonNull public abstract java.util.List<android.content.pm.ResolveInfo> queryBroadcastReceivers(@NonNull android.content.Intent, int); + method @NonNull public abstract java.util.List<android.content.pm.ProviderInfo> queryContentProviders(@Nullable String, int, int); + method @NonNull public abstract java.util.List<android.content.pm.InstrumentationInfo> queryInstrumentation(@NonNull String, int); + method @Nullable public abstract java.util.List<android.content.pm.ResolveInfo> queryIntentActivities(@NonNull android.content.Intent, int); + method @NonNull public abstract java.util.List<android.content.pm.ResolveInfo> queryIntentActivityOptions(@Nullable android.content.ComponentName, @Nullable android.content.Intent[], @NonNull android.content.Intent, int); + method @NonNull public abstract java.util.List<android.content.pm.ResolveInfo> queryIntentContentProviders(@NonNull android.content.Intent, int); + method @NonNull public abstract java.util.List<android.content.pm.ResolveInfo> queryIntentServices(@NonNull android.content.Intent, int); + method @NonNull public abstract java.util.List<android.content.pm.PermissionInfo> queryPermissionsByGroup(@NonNull String, int) throws android.content.pm.PackageManager.NameNotFoundException; + method @Deprecated public abstract void removePackageFromPreferred(@NonNull String); + method public abstract void removePermission(@NonNull String); + method @Nullable public abstract android.content.pm.ResolveInfo resolveActivity(@NonNull android.content.Intent, int); + method @Nullable public abstract android.content.pm.ProviderInfo resolveContentProvider(@NonNull String, int); + method @Nullable public abstract android.content.pm.ResolveInfo resolveService(@NonNull android.content.Intent, int); method public abstract void setApplicationCategoryHint(@NonNull String, int); method @RequiresPermission(value=android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE, conditional=true) public abstract void setApplicationEnabledSetting(@NonNull String, int, int); method @RequiresPermission(value=android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE, conditional=true) public abstract void setComponentEnabledSetting(@NonNull android.content.ComponentName, int, int); - method public abstract void setInstallerPackageName(String, String); + method public abstract void setInstallerPackageName(@NonNull String, @Nullable String); method public abstract void updateInstantAppCookie(@Nullable byte[]); method public abstract void verifyPendingInstall(int, int); field public static final int CERT_INPUT_RAW_X509 = 0; // 0x0 @@ -28756,6 +28757,7 @@ package android.net { method @NonNull public static android.net.DnsResolver getInstance(); method public <T> void query(@Nullable android.net.Network, @NonNull byte[], int, @NonNull java.util.concurrent.Executor, @Nullable android.os.CancellationSignal, @NonNull android.net.DnsResolver.AnswerCallback<T>); method public <T> void query(@Nullable android.net.Network, @NonNull String, int, int, int, @NonNull java.util.concurrent.Executor, @Nullable android.os.CancellationSignal, @NonNull android.net.DnsResolver.AnswerCallback<T>); + method public void query(@Nullable android.net.Network, @NonNull String, int, @NonNull java.util.concurrent.Executor, @Nullable android.os.CancellationSignal, @NonNull android.net.DnsResolver.InetAddressAnswerCallback); field public static final int CLASS_IN = 1; // 0x1 field public static final int FLAG_EMPTY = 0; // 0x0 field public static final int FLAG_NO_CACHE_LOOKUP = 4; // 0x4 @@ -34658,9 +34660,11 @@ package android.os { method @NonNull public static java.io.File getRootDirectory(); method @Deprecated public static String getStorageState(java.io.File); method public static boolean isExternalStorageEmulated(); - method public static boolean isExternalStorageEmulated(java.io.File); + method public static boolean isExternalStorageEmulated(@NonNull java.io.File); method public static boolean isExternalStorageRemovable(); - method public static boolean isExternalStorageRemovable(java.io.File); + method public static boolean isExternalStorageRemovable(@NonNull java.io.File); + method public static boolean isExternalStorageSandboxed(); + method public static boolean isExternalStorageSandboxed(@NonNull java.io.File); field public static String DIRECTORY_ALARMS; field public static String DIRECTORY_AUDIOBOOKS; field public static String DIRECTORY_DCIM; diff --git a/api/system-current.txt b/api/system-current.txt index 48b1385a872f..8ee1e0ab5867 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -1593,46 +1593,46 @@ package android.content.pm { } public abstract class PackageManager { - method @RequiresPermission("android.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS") public abstract void addOnPermissionsChangeListener(android.content.pm.PackageManager.OnPermissionsChangedListener); + method @RequiresPermission("android.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS") public abstract void addOnPermissionsChangeListener(@NonNull android.content.pm.PackageManager.OnPermissionsChangedListener); method public abstract boolean arePermissionsIndividuallyControlled(); - method public abstract java.util.List<android.content.IntentFilter> getAllIntentFilters(String); + method @NonNull public abstract java.util.List<android.content.IntentFilter> getAllIntentFilters(@NonNull String); method @NonNull @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) public android.content.pm.ApplicationInfo getApplicationInfoAsUser(@NonNull String, int, @NonNull android.os.UserHandle) throws android.content.pm.PackageManager.NameNotFoundException; method @NonNull public android.content.pm.dex.ArtManager getArtManager(); method @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_SHARED_LIBRARIES) public java.util.List<android.content.pm.SharedLibraryInfo> getDeclaredSharedLibraries(@NonNull String, int); - method @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) public abstract String getDefaultBrowserPackageNameAsUser(int); + method @Nullable @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) public abstract String getDefaultBrowserPackageNameAsUser(int); method @Nullable @RequiresPermission(android.Manifest.permission.SET_HARMFUL_APP_WARNINGS) public CharSequence getHarmfulAppWarning(@NonNull String); method @Nullable public String getIncidentReportApproverPackageName(); - method @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) public abstract java.util.List<android.content.pm.PackageInfo> getInstalledPackagesAsUser(int, int); + method @NonNull @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) public abstract java.util.List<android.content.pm.PackageInfo> getInstalledPackagesAsUser(int, int); method @Nullable @RequiresPermission(android.Manifest.permission.ACCESS_INSTANT_APPS) public abstract android.graphics.drawable.Drawable getInstantAppIcon(String); - method public abstract android.content.ComponentName getInstantAppInstallerComponent(); - method public abstract android.content.ComponentName getInstantAppResolverSettingsComponent(); + method @Nullable public abstract android.content.ComponentName getInstantAppInstallerComponent(); + method @Nullable public abstract android.content.ComponentName getInstantAppResolverSettingsComponent(); method @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_INSTANT_APPS) public abstract java.util.List<android.content.pm.InstantAppInfo> getInstantApps(); - method public abstract java.util.List<android.content.pm.IntentFilterVerificationInfo> getIntentFilterVerifications(String); - method @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) public abstract int getIntentVerificationStatusAsUser(String, int); - method @android.content.pm.PackageManager.PermissionFlags @RequiresPermission(anyOf={android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS, android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS, android.Manifest.permission.GET_RUNTIME_PERMISSIONS}) public abstract int getPermissionFlags(String, String, @NonNull android.os.UserHandle); + method @NonNull public abstract java.util.List<android.content.pm.IntentFilterVerificationInfo> getIntentFilterVerifications(@NonNull String); + method @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) public abstract int getIntentVerificationStatusAsUser(@NonNull String, int); + method @android.content.pm.PackageManager.PermissionFlags @RequiresPermission(anyOf={android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS, android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS, android.Manifest.permission.GET_RUNTIME_PERMISSIONS}) public abstract int getPermissionFlags(@NonNull String, @NonNull String, @NonNull android.os.UserHandle); method @NonNull @RequiresPermission(android.Manifest.permission.SUSPEND_APPS) public String[] getUnsuspendablePackages(@NonNull String[]); method @RequiresPermission(android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS) public abstract void grantRuntimePermission(@NonNull String, @NonNull String, @NonNull android.os.UserHandle); - method @Deprecated public abstract int installExistingPackage(String) throws android.content.pm.PackageManager.NameNotFoundException; - method @Deprecated public abstract int installExistingPackage(String, int) throws android.content.pm.PackageManager.NameNotFoundException; - method @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) public java.util.List<android.content.pm.ResolveInfo> queryBroadcastReceiversAsUser(android.content.Intent, int, android.os.UserHandle); + method @Deprecated public abstract int installExistingPackage(@NonNull String) throws android.content.pm.PackageManager.NameNotFoundException; + method @Deprecated public abstract int installExistingPackage(@NonNull String, int) throws android.content.pm.PackageManager.NameNotFoundException; + method @NonNull @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) public java.util.List<android.content.pm.ResolveInfo> queryBroadcastReceiversAsUser(@NonNull android.content.Intent, int, android.os.UserHandle); method @NonNull @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) public java.util.List<android.content.pm.ResolveInfo> queryIntentActivitiesAsUser(@NonNull android.content.Intent, int, @NonNull android.os.UserHandle); method @NonNull @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) public java.util.List<android.content.pm.ResolveInfo> queryIntentContentProvidersAsUser(@NonNull android.content.Intent, int, @NonNull android.os.UserHandle); method @NonNull @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) public java.util.List<android.content.pm.ResolveInfo> queryIntentServicesAsUser(@NonNull android.content.Intent, int, @NonNull android.os.UserHandle); - method public abstract void registerDexModule(String, @Nullable android.content.pm.PackageManager.DexModuleRegisterCallback); - method @RequiresPermission("android.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS") public abstract void removeOnPermissionsChangeListener(android.content.pm.PackageManager.OnPermissionsChangedListener); + method public abstract void registerDexModule(@NonNull String, @Nullable android.content.pm.PackageManager.DexModuleRegisterCallback); + method @RequiresPermission("android.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS") public abstract void removeOnPermissionsChangeListener(@NonNull android.content.pm.PackageManager.OnPermissionsChangedListener); method @Deprecated public void replacePreferredActivity(@NonNull android.content.IntentFilter, int, @NonNull java.util.List<android.content.ComponentName>, @NonNull android.content.ComponentName); method @RequiresPermission(android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS) public abstract void revokeRuntimePermission(@NonNull String, @NonNull String, @NonNull android.os.UserHandle); method public void sendDeviceCustomizationReadyBroadcast(); - method @RequiresPermission(allOf={android.Manifest.permission.SET_PREFERRED_APPLICATIONS, android.Manifest.permission.INTERACT_ACROSS_USERS_FULL}) public abstract boolean setDefaultBrowserPackageNameAsUser(String, int); + method @RequiresPermission(allOf={android.Manifest.permission.SET_PREFERRED_APPLICATIONS, android.Manifest.permission.INTERACT_ACROSS_USERS_FULL}) public abstract boolean setDefaultBrowserPackageNameAsUser(@Nullable String, int); method @NonNull @RequiresPermission(android.Manifest.permission.SUSPEND_APPS) public String[] setDistractingPackageRestrictions(@NonNull String[], int); method @RequiresPermission(android.Manifest.permission.SET_HARMFUL_APP_WARNINGS) public void setHarmfulAppWarning(@NonNull String, @Nullable CharSequence); method @Deprecated @Nullable @RequiresPermission(android.Manifest.permission.SUSPEND_APPS) public String[] setPackagesSuspended(@Nullable String[], boolean, @Nullable android.os.PersistableBundle, @Nullable android.os.PersistableBundle, @Nullable String); method @Nullable @RequiresPermission(android.Manifest.permission.SUSPEND_APPS) public String[] setPackagesSuspended(@Nullable String[], boolean, @Nullable android.os.PersistableBundle, @Nullable android.os.PersistableBundle, @Nullable android.content.pm.SuspendDialogInfo); method @RequiresPermission(value=android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE, conditional=true) public void setSyntheticAppDetailsActivityEnabled(@NonNull String, boolean); - method @RequiresPermission(android.Manifest.permission.INSTALL_PACKAGES) public abstract void setUpdateAvailable(String, boolean); - method @RequiresPermission(android.Manifest.permission.SET_PREFERRED_APPLICATIONS) public abstract boolean updateIntentVerificationStatusAsUser(String, int, int); - method @RequiresPermission(anyOf={android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS, android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS}) public abstract void updatePermissionFlags(String, String, @android.content.pm.PackageManager.PermissionFlags int, @android.content.pm.PackageManager.PermissionFlags int, @NonNull android.os.UserHandle); - method @RequiresPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT) public abstract void verifyIntentFilter(int, int, java.util.List<java.lang.String>); + method @RequiresPermission(android.Manifest.permission.INSTALL_PACKAGES) public abstract void setUpdateAvailable(@NonNull String, boolean); + method @RequiresPermission(android.Manifest.permission.SET_PREFERRED_APPLICATIONS) public abstract boolean updateIntentVerificationStatusAsUser(@NonNull String, int, int); + method @RequiresPermission(anyOf={android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS, android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS}) public abstract void updatePermissionFlags(@NonNull String, @NonNull String, @android.content.pm.PackageManager.PermissionFlags int, @android.content.pm.PackageManager.PermissionFlags int, @NonNull android.os.UserHandle); + method @RequiresPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT) public abstract void verifyIntentFilter(int, int, @NonNull java.util.List<java.lang.String>); field public static final String ACTION_REQUEST_PERMISSIONS = "android.content.pm.action.REQUEST_PERMISSIONS"; field public static final String EXTRA_REQUEST_PERMISSIONS_NAMES = "android.content.pm.extra.REQUEST_PERMISSIONS_NAMES"; field public static final String EXTRA_REQUEST_PERMISSIONS_RESULTS = "android.content.pm.extra.REQUEST_PERMISSIONS_RESULTS"; diff --git a/api/test-current.txt b/api/test-current.txt index 8dff8f405ba6..7762baabc272 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -663,20 +663,20 @@ package android.content.pm { public abstract class PackageManager { method public abstract boolean arePermissionsIndividuallyControlled(); - method @RequiresPermission("android.permission.INTERACT_ACROSS_USERS_FULL") public abstract String getDefaultBrowserPackageNameAsUser(int); + method @Nullable @RequiresPermission("android.permission.INTERACT_ACROSS_USERS_FULL") public abstract String getDefaultBrowserPackageNameAsUser(int); method @Nullable public String getIncidentReportApproverPackageName(); - method public abstract int getInstallReason(String, @NonNull android.os.UserHandle); - method public abstract java.util.List<android.content.pm.ApplicationInfo> getInstalledApplicationsAsUser(int, int); - method @RequiresPermission("android.permission.INTERACT_ACROSS_USERS_FULL") public abstract java.util.List<android.content.pm.PackageInfo> getInstalledPackagesAsUser(int, int); + method public abstract int getInstallReason(@NonNull String, @NonNull android.os.UserHandle); + method @NonNull public abstract java.util.List<android.content.pm.ApplicationInfo> getInstalledApplicationsAsUser(int, int); + method @NonNull @RequiresPermission("android.permission.INTERACT_ACROSS_USERS_FULL") public abstract java.util.List<android.content.pm.PackageInfo> getInstalledPackagesAsUser(int, int); method @Nullable public abstract String[] getNamesForUids(int[]); - method public abstract String getPermissionControllerPackageName(); - method @RequiresPermission(anyOf={"android.permission.GRANT_RUNTIME_PERMISSIONS", "android.permission.REVOKE_RUNTIME_PERMISSIONS", "android.permission.GET_RUNTIME_PERMISSIONS"}) public abstract int getPermissionFlags(String, String, @NonNull android.os.UserHandle); + method @NonNull public abstract String getPermissionControllerPackageName(); + method @RequiresPermission(anyOf={"android.permission.GRANT_RUNTIME_PERMISSIONS", "android.permission.REVOKE_RUNTIME_PERMISSIONS", "android.permission.GET_RUNTIME_PERMISSIONS"}) public abstract int getPermissionFlags(@NonNull String, @NonNull String, @NonNull android.os.UserHandle); method @NonNull public abstract String getServicesSystemSharedLibraryPackageName(); method @NonNull public abstract String getSharedSystemSharedLibraryPackageName(); - method public String getWellbeingPackageName(); + method @Nullable public String getWellbeingPackageName(); method @RequiresPermission("android.permission.GRANT_RUNTIME_PERMISSIONS") public abstract void grantRuntimePermission(@NonNull String, @NonNull String, @NonNull android.os.UserHandle); method @RequiresPermission("android.permission.REVOKE_RUNTIME_PERMISSIONS") public abstract void revokeRuntimePermission(@NonNull String, @NonNull String, @NonNull android.os.UserHandle); - method @RequiresPermission(anyOf={"android.permission.GRANT_RUNTIME_PERMISSIONS", "android.permission.REVOKE_RUNTIME_PERMISSIONS"}) public abstract void updatePermissionFlags(String, String, int, int, @NonNull android.os.UserHandle); + method @RequiresPermission(anyOf={"android.permission.GRANT_RUNTIME_PERMISSIONS", "android.permission.REVOKE_RUNTIME_PERMISSIONS"}) public abstract void updatePermissionFlags(@NonNull String, @NonNull String, int, int, @NonNull android.os.UserHandle); field public static final String FEATURE_ADOPTABLE_STORAGE = "android.software.adoptable_storage"; field public static final String FEATURE_FILE_BASED_ENCRYPTION = "android.software.file_based_encryption"; field public static final int FLAG_PERMISSION_HIDDEN = 1024; // 0x400 diff --git a/cmds/bmgr/Android.bp b/cmds/bmgr/Android.bp new file mode 100644 index 000000000000..b64923bcbe1b --- /dev/null +++ b/cmds/bmgr/Android.bp @@ -0,0 +1,8 @@ +// Copyright 2007 The Android Open Source Project +// + +java_binary { + name: "bmgr", + wrapper: "bmgr", + srcs: ["**/*.java"], +} diff --git a/cmds/bmgr/Android.mk b/cmds/bmgr/Android.mk deleted file mode 100644 index d520cf2143ee..000000000000 --- a/cmds/bmgr/Android.mk +++ /dev/null @@ -1,16 +0,0 @@ -# Copyright 2007 The Android Open Source Project -# -LOCAL_PATH:= $(call my-dir) - -include $(CLEAR_VARS) -LOCAL_SRC_FILES := $(call all-subdir-java-files) -LOCAL_MODULE := bmgrlib -LOCAL_MODULE_STEM := bmgr -include $(BUILD_JAVA_LIBRARY) - -include $(CLEAR_VARS) -LOCAL_MODULE := bmgr -LOCAL_MODULE_CLASS := EXECUTABLES -LOCAL_SRC_FILES := bmgr -LOCAL_REQUIRED_MODULES := bmgrlib -include $(BUILD_PREBUILT) diff --git a/cmds/media/Android.bp b/cmds/media/Android.bp new file mode 100644 index 000000000000..7879c53684a7 --- /dev/null +++ b/cmds/media/Android.bp @@ -0,0 +1,8 @@ +// Copyright 2013 The Android Open Source Project +// + +java_binary { + name: "media", + wrapper: "media", + srcs: ["**/*.java"], +} diff --git a/cmds/media/Android.mk b/cmds/media/Android.mk deleted file mode 100644 index b9451c596da0..000000000000 --- a/cmds/media/Android.mk +++ /dev/null @@ -1,15 +0,0 @@ -# Copyright 2013 The Android Open Source Project -# -LOCAL_PATH:= $(call my-dir) - -include $(CLEAR_VARS) -LOCAL_SRC_FILES := $(call all-subdir-java-files) -LOCAL_MODULE := media_cmd -include $(BUILD_JAVA_LIBRARY) - -include $(CLEAR_VARS) -LOCAL_MODULE := media -LOCAL_SRC_FILES := media -LOCAL_MODULE_CLASS := EXECUTABLES -LOCAL_MODULE_TAGS := optional -include $(BUILD_PREBUILT) diff --git a/cmds/media/media b/cmds/media/media index 5c0eb2f39c2d..8ada9145a4f7 100755 --- a/cmds/media/media +++ b/cmds/media/media @@ -3,5 +3,5 @@ # shell. # base=/system -export CLASSPATH=$base/framework/media_cmd.jar +export CLASSPATH=$base/framework/media.jar exec app_process $base/bin com.android.commands.media.Media "$@" diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 08239a1e7ed9..2441672fb048 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -2100,6 +2100,16 @@ public final class ActivityThread extends ClientTransactionHandler { public final LoadedApk getPackageInfo(String packageName, CompatibilityInfo compatInfo, int flags, int userId) { final boolean differentUser = (UserHandle.myUserId() != userId); + ApplicationInfo ai; + try { + ai = getPackageManager().getApplicationInfo(packageName, + PackageManager.GET_SHARED_LIBRARY_FILES + | PackageManager.MATCH_DEBUG_TRIAGED_MISSING, + (userId < 0) ? UserHandle.myUserId() : userId); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + synchronized (mResourcesManager) { WeakReference<LoadedApk> ref; if (differentUser) { @@ -2112,11 +2122,7 @@ public final class ActivityThread extends ClientTransactionHandler { } LoadedApk packageInfo = ref != null ? ref.get() : null; - //Slog.i(TAG, "getPackageInfo " + packageName + ": " + packageInfo); - //if (packageInfo != null) Slog.i(TAG, "isUptoDate " + packageInfo.mResDir - // + ": " + packageInfo.mResources.getAssets().isUpToDate()); - if (packageInfo != null && (packageInfo.mResources == null - || packageInfo.mResources.getAssets().isUpToDate())) { + if (ai != null && packageInfo != null && isLoadedApkUpToDate(packageInfo, ai)) { if (packageInfo.isSecurityViolation() && (flags&Context.CONTEXT_IGNORE_SECURITY) == 0) { throw new SecurityException( @@ -2129,16 +2135,6 @@ public final class ActivityThread extends ClientTransactionHandler { } } - ApplicationInfo ai = null; - try { - ai = getPackageManager().getApplicationInfo(packageName, - PackageManager.GET_SHARED_LIBRARY_FILES - | PackageManager.MATCH_DEBUG_TRIAGED_MISSING, - (userId < 0) ? UserHandle.myUserId() : userId); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - if (ai != null) { return getPackageInfo(ai, compatInfo, flags); } @@ -2209,37 +2205,59 @@ public final class ActivityThread extends ClientTransactionHandler { } LoadedApk packageInfo = ref != null ? ref.get() : null; - if (packageInfo == null || (packageInfo.mResources != null - && !packageInfo.mResources.getAssets().isUpToDate())) { - if (localLOGV) Slog.v(TAG, (includeCode ? "Loading code package " + + boolean isUpToDate = packageInfo != null && isLoadedApkUpToDate(packageInfo, aInfo); + + if (isUpToDate) { + return packageInfo; + } + + if (localLOGV) { + Slog.v(TAG, (includeCode ? "Loading code package " : "Loading resource-only package ") + aInfo.packageName + " (in " + (mBoundApplication != null - ? mBoundApplication.processName : null) + ? mBoundApplication.processName : null) + ")"); - packageInfo = + } + + packageInfo = new LoadedApk(this, aInfo, compatInfo, baseLoader, - securityViolation, includeCode && - (aInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0, registerPackage); + securityViolation, includeCode + && (aInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0, registerPackage); - if (mSystemThread && "android".equals(aInfo.packageName)) { - packageInfo.installSystemApplicationInfo(aInfo, - getSystemContext().mPackageInfo.getClassLoader()); - } + if (mSystemThread && "android".equals(aInfo.packageName)) { + packageInfo.installSystemApplicationInfo(aInfo, + getSystemContext().mPackageInfo.getClassLoader()); + } - if (differentUser) { - // Caching not supported across users - } else if (includeCode) { - mPackages.put(aInfo.packageName, - new WeakReference<LoadedApk>(packageInfo)); - } else { - mResourcePackages.put(aInfo.packageName, - new WeakReference<LoadedApk>(packageInfo)); - } + if (differentUser) { + // Caching not supported across users + } else if (includeCode) { + mPackages.put(aInfo.packageName, + new WeakReference<LoadedApk>(packageInfo)); + } else { + mResourcePackages.put(aInfo.packageName, + new WeakReference<LoadedApk>(packageInfo)); } + return packageInfo; } } + /** + * Compares overlay/resource directories for a LoadedApk to determine if it's up to date + * with the given ApplicationInfo. + */ + private boolean isLoadedApkUpToDate(LoadedApk loadedApk, ApplicationInfo appInfo) { + Resources packageResources = loadedApk.mResources; + String[] overlayDirs = ArrayUtils.defeatNullable(loadedApk.getOverlayDirs()); + String[] resourceDirs = ArrayUtils.defeatNullable(appInfo.resourceDirs); + + return (packageResources == null || packageResources.getAssets().isUpToDate()) + && overlayDirs.length == resourceDirs.length + && ArrayUtils.containsAll(overlayDirs, resourceDirs); + } + @UnsupportedAppUsage ActivityThread() { mResourcesManager = ResourcesManager.getInstance(); @@ -5434,19 +5452,25 @@ public final class ActivityThread extends ClientTransactionHandler { ref = mResourcePackages.get(ai.packageName); resApk = ref != null ? ref.get() : null; } + + final String[] oldResDirs = new String[2]; + if (apk != null) { + oldResDirs[0] = apk.getResDir(); final ArrayList<String> oldPaths = new ArrayList<>(); LoadedApk.makePaths(this, apk.getApplicationInfo(), oldPaths); apk.updateApplicationInfo(ai, oldPaths); } if (resApk != null) { + oldResDirs[1] = resApk.getResDir(); final ArrayList<String> oldPaths = new ArrayList<>(); LoadedApk.makePaths(this, resApk.getApplicationInfo(), oldPaths); resApk.updateApplicationInfo(ai, oldPaths); } + synchronized (mResourcesManager) { // Update all affected Resources objects to use new ResourcesImpl - mResourcesManager.applyNewResourceDirsLocked(ai.sourceDir, ai.resourceDirs); + mResourcesManager.applyNewResourceDirsLocked(ai, oldResDirs); } ApplicationPackageManager.configurationChanged(); @@ -5699,9 +5723,17 @@ public final class ActivityThread extends ClientTransactionHandler { } } } + + final String[] oldResDirs = { pkgInfo.getResDir() }; + final ArrayList<String> oldPaths = new ArrayList<>(); LoadedApk.makePaths(this, pkgInfo.getApplicationInfo(), oldPaths); pkgInfo.updateApplicationInfo(aInfo, oldPaths); + + synchronized (mResourcesManager) { + // Update affected Resources objects to use new ResourcesImpl + mResourcesManager.applyNewResourceDirsLocked(aInfo, oldResDirs); + } } catch (RemoteException e) { } } diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java index 404e52011c39..a906790c45ab 100644 --- a/core/java/android/app/ApplicationPackageManager.java +++ b/core/java/android/app/ApplicationPackageManager.java @@ -3049,6 +3049,15 @@ public class ApplicationPackageManager extends PackageManager { } @Override + public String getAttentionServicePackageName() { + try { + return mPM.getAttentionServicePackageName(); + } catch (RemoteException e) { + throw e.rethrowAsRuntimeException(); + } + } + + @Override public String getWellbeingPackageName() { try { return mPM.getWellbeingPackageName(); diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java index 11000df5b993..41a4fba0434c 100644 --- a/core/java/android/app/ContextImpl.java +++ b/core/java/android/app/ContextImpl.java @@ -2122,8 +2122,7 @@ class ContextImpl extends Context { } private static Resources createResources(IBinder activityToken, LoadedApk pi, String splitName, - int displayId, Configuration overrideConfig, CompatibilityInfo compatInfo, - String[] overlayDirs) { + int displayId, Configuration overrideConfig, CompatibilityInfo compatInfo) { final String[] splitResDirs; final ClassLoader classLoader; try { @@ -2135,7 +2134,7 @@ class ContextImpl extends Context { return ResourcesManager.getInstance().getResources(activityToken, pi.getResDir(), splitResDirs, - overlayDirs, + pi.getOverlayDirs(), pi.getApplicationInfo().sharedLibraryFiles, displayId, overrideConfig, @@ -2153,11 +2152,9 @@ class ContextImpl extends Context { new UserHandle(UserHandle.getUserId(application.uid)), flags, null, null); final int displayId = getDisplayId(); - // overlayDirs is retrieved directly from ApplicationInfo since ActivityThread may have - // a LoadedApk containing Resources with stale overlays for a remote application. - final String[] overlayDirs = application.resourceDirs; + c.setResources(createResources(mActivityToken, pi, null, displayId, null, - getDisplayAdjustments(displayId).getCompatibilityInfo(), overlayDirs)); + getDisplayAdjustments(displayId).getCompatibilityInfo())); if (c.mResources != null) { return c; } @@ -2192,7 +2189,7 @@ class ContextImpl extends Context { final int displayId = getDisplayId(); c.setResources(createResources(mActivityToken, pi, null, displayId, null, - getDisplayAdjustments(displayId).getCompatibilityInfo(), pi.getOverlayDirs())); + getDisplayAdjustments(displayId).getCompatibilityInfo())); if (c.mResources != null) { return c; } @@ -2242,8 +2239,7 @@ class ContextImpl extends Context { final int displayId = getDisplayId(); context.setResources(createResources(mActivityToken, mPackageInfo, mSplitName, displayId, - overrideConfiguration, getDisplayAdjustments(displayId).getCompatibilityInfo(), - mPackageInfo.getOverlayDirs())); + overrideConfiguration, getDisplayAdjustments(displayId).getCompatibilityInfo())); return context; } @@ -2258,8 +2254,7 @@ class ContextImpl extends Context { final int displayId = display.getDisplayId(); context.setResources(createResources(mActivityToken, mPackageInfo, mSplitName, displayId, - null, getDisplayAdjustments(displayId).getCompatibilityInfo(), - mPackageInfo.getOverlayDirs())); + null, getDisplayAdjustments(displayId).getCompatibilityInfo())); context.mDisplay = display; return context; } @@ -2441,7 +2436,7 @@ class ContextImpl extends Context { ContextImpl context = new ContextImpl(null, systemContext.mMainThread, packageInfo, null, null, null, 0, null, null); context.setResources(createResources(null, packageInfo, null, displayId, null, - packageInfo.getCompatibilityInfo(), packageInfo.getOverlayDirs())); + packageInfo.getCompatibilityInfo())); context.updateDisplay(displayId); return context; } diff --git a/core/java/android/app/ResourcesManager.java b/core/java/android/app/ResourcesManager.java index 35658fbcb989..b93aaa2aca68 100644 --- a/core/java/android/app/ResourcesManager.java +++ b/core/java/android/app/ResourcesManager.java @@ -22,6 +22,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UnsupportedAppUsage; import android.content.pm.ActivityInfo; +import android.content.pm.ApplicationInfo; import android.content.res.ApkAssets; import android.content.res.AssetManager; import android.content.res.CompatResources; @@ -32,6 +33,7 @@ import android.content.res.ResourcesImpl; import android.content.res.ResourcesKey; import android.hardware.display.DisplayManagerGlobal; import android.os.IBinder; +import android.os.Process; import android.os.Trace; import android.util.ArrayMap; import android.util.DisplayMetrics; @@ -1136,27 +1138,46 @@ public class ResourcesManager { } // TODO(adamlesinski): Make this accept more than just overlay directories. - final void applyNewResourceDirsLocked(@NonNull final String baseCodePath, - @Nullable final String[] newResourceDirs) { + final void applyNewResourceDirsLocked(@NonNull final ApplicationInfo appInfo, + @Nullable final String[] oldPaths) { try { Trace.traceBegin(Trace.TRACE_TAG_RESOURCES, "ResourcesManager#applyNewResourceDirsLocked"); + String baseCodePath = appInfo.getBaseCodePath(); + + final int myUid = Process.myUid(); + String[] newSplitDirs = appInfo.uid == myUid + ? appInfo.splitSourceDirs + : appInfo.splitPublicSourceDirs; + + // ApplicationInfo is mutable, so clone the arrays to prevent outside modification + String[] copiedSplitDirs = ArrayUtils.cloneOrNull(newSplitDirs); + String[] copiedResourceDirs = ArrayUtils.cloneOrNull(appInfo.resourceDirs); + final ArrayMap<ResourcesImpl, ResourcesKey> updatedResourceKeys = new ArrayMap<>(); final int implCount = mResourceImpls.size(); for (int i = 0; i < implCount; i++) { final ResourcesKey key = mResourceImpls.keyAt(i); final WeakReference<ResourcesImpl> weakImplRef = mResourceImpls.valueAt(i); final ResourcesImpl impl = weakImplRef != null ? weakImplRef.get() : null; - if (impl != null && (key.mResDir == null || key.mResDir.equals(baseCodePath))) { + + if (impl == null) { + continue; + } + + if (key.mResDir == null + || key.mResDir.equals(baseCodePath) + || ArrayUtils.contains(oldPaths, key.mResDir)) { updatedResourceKeys.put(impl, new ResourcesKey( - key.mResDir, - key.mSplitResDirs, - newResourceDirs, + baseCodePath, + copiedSplitDirs, + copiedResourceDirs, key.mLibDirs, key.mDisplayId, key.mOverrideConfiguration, - key.mCompatInfo)); + key.mCompatInfo + )); } } diff --git a/core/java/android/content/om/OverlayInfo.java b/core/java/android/content/om/OverlayInfo.java index aabe59d18383..b8c6d87acd5c 100644 --- a/core/java/android/content/om/OverlayInfo.java +++ b/core/java/android/content/om/OverlayInfo.java @@ -44,7 +44,7 @@ public final class OverlayInfo implements Parcelable { STATE_DISABLED, STATE_ENABLED, STATE_ENABLED_STATIC, - STATE_TARGET_UPGRADING, + // @Deprecated STATE_TARGET_UPGRADING, STATE_OVERLAY_UPGRADING, }) /** @hide */ @@ -96,7 +96,14 @@ public final class OverlayInfo implements Parcelable { * The target package is currently being upgraded; the state will change * once the package installation has finished. * @hide + * + * @deprecated No longer used. Caused invalid transitions from enabled -> upgrading -> enabled, + * where an update is propagated when nothing has changed. Can occur during --dont-kill + * installs when code and resources are hot swapped and the Activity should not be relaunched. + * In all other cases, the process and therefore Activity is killed, so the state loop is + * irrelevant. */ + @Deprecated public static final int STATE_TARGET_UPGRADING = 4; /** diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java index 068a93a253ff..5328dda03893 100644 --- a/core/java/android/content/pm/ApplicationInfo.java +++ b/core/java/android/content/pm/ApplicationInfo.java @@ -678,6 +678,14 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { */ public static final int PRIVATE_FLAG_IS_RESOURCE_OVERLAY = 1 << 28; + /** + * Value for {@link #privateFlags}: If {@code true} this app allows + * shared/external storage media to be a sandboxed view that only contains + * files owned by the app. + * + * @hide + */ + public static final int PRIVATE_FLAG_ALLOW_EXTERNAL_STORAGE_SANDBOX = 1 << 29; /** @hide */ @IntDef(flag = true, prefix = { "PRIVATE_FLAG_" }, value = { @@ -707,7 +715,8 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { PRIVATE_FLAG_VIRTUAL_PRELOAD, PRIVATE_FLAG_HAS_FRAGILE_USER_DATA, PRIVATE_FLAG_ALLOW_CLEAR_USER_DATA_ON_FAILED_RESTORE, - PRIVATE_FLAG_ALLOW_AUDIO_PLAYBACK_CAPTURE + PRIVATE_FLAG_ALLOW_AUDIO_PLAYBACK_CAPTURE, + PRIVATE_FLAG_ALLOW_EXTERNAL_STORAGE_SANDBOX, }) @Retention(RetentionPolicy.SOURCE) public @interface ApplicationInfoPrivateFlags {} @@ -1822,6 +1831,16 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { return (privateFlags & PRIVATE_FLAG_ALLOW_AUDIO_PLAYBACK_CAPTURE) != 0; } + /** + * If {@code true} this app allows shared/external storage media to be a + * sandboxed view that only contains files owned by the app. + * + * @hide + */ + public boolean isExternalStorageSandboxAllowed() { + return (privateFlags & PRIVATE_FLAG_ALLOW_EXTERNAL_STORAGE_SANDBOX) != 0; + } + private boolean isAllowedToUseHiddenApis() { if (isSignedWithPlatformKey()) { return true; diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl index c798270d1fdc..fb2218778c9b 100644 --- a/core/java/android/content/pm/IPackageManager.aidl +++ b/core/java/android/content/pm/IPackageManager.aidl @@ -740,6 +740,8 @@ interface IPackageManager { String getSystemTextClassifierPackageName(); + String getAttentionServicePackageName(); + String getWellbeingPackageName(); String getAppPredictionServicePackageName(); diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java index 1e6cea39b44d..5d6867e14393 100644 --- a/core/java/android/content/pm/PackageInstaller.java +++ b/core/java/android/content/pm/PackageInstaller.java @@ -1211,6 +1211,9 @@ public class PackageInstaller { * Adds a session ID to the set of sessions that will be committed atomically * when this session is committed. * + * <p>If the parent is staged or has rollback enabled, all children must have + * the same properties. + * * @param sessionId the session ID to add to this multi-package session. */ public void addChildSessionId(int sessionId) { @@ -1480,6 +1483,9 @@ public class PackageInstaller { /** * Request that rollbacks be enabled or disabled for the given upgrade. * + * <p>If the parent session is staged or has rollback enabled, all children sessions + * must have the same properties. + * * @param enable set to {@code true} to enable, {@code false} to disable * @hide */ @@ -1607,6 +1613,9 @@ public class PackageInstaller { * multi-package. In that case, if any of the children sessions fail to install at reboot, * all the other children sessions are aborted as well. * + * <p>If the parent session is staged or has rollback enabled, all children sessions + * must have the same properties. + * * {@hide} */ @SystemApi @TestApi @@ -1626,6 +1635,11 @@ public class PackageInstaller { installFlags |= PackageManager.INSTALL_APEX; } + /** @hide */ + public boolean getEnableRollback() { + return (installFlags & PackageManager.INSTALL_ENABLE_ROLLBACK) != 0; + } + /** {@hide} */ public void dump(IndentingPrintWriter pw) { pw.printPair("mode", mode); diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index b190b34aa03f..8f7df2517580 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -1397,6 +1397,14 @@ public abstract class PackageManager { */ public static final int INSTALL_FAILED_OTHER_STAGED_SESSION_IN_PROGRESS = -119; + /** + * Installation failed return code: one of the child sessions does not match the parent session + * in respect to staged or rollback enabled parameters. + * + * @hide + */ + public static final int INSTALL_FAILED_MULTIPACKAGE_INCONSISTENCY = -120; + /** @hide */ @IntDef(flag = true, prefix = { "DELETE_" }, value = { DELETE_KEEP_DATA, @@ -3214,7 +3222,8 @@ public abstract class PackageManager { * @throws NameNotFoundException if a package with the given name cannot be * found on the system. */ - public abstract PackageInfo getPackageInfo(String packageName, @PackageInfoFlags int flags) + public abstract PackageInfo getPackageInfo(@NonNull String packageName, + @PackageInfoFlags int flags) throws NameNotFoundException; /** @@ -3239,7 +3248,7 @@ public abstract class PackageManager { * @throws NameNotFoundException if a package with the given name cannot be * found on the system. */ - public abstract PackageInfo getPackageInfo(VersionedPackage versionedPackage, + public abstract PackageInfo getPackageInfo(@NonNull VersionedPackage versionedPackage, @PackageInfoFlags int flags) throws NameNotFoundException; /** @@ -3263,25 +3272,25 @@ public abstract class PackageManager { */ @RequiresPermission(Manifest.permission.INTERACT_ACROSS_USERS) @UnsupportedAppUsage - public abstract PackageInfo getPackageInfoAsUser(String packageName, + public abstract PackageInfo getPackageInfoAsUser(@NonNull String packageName, @PackageInfoFlags int flags, @UserIdInt int userId) throws NameNotFoundException; /** * Map from the current package names in use on the device to whatever * the current canonical name of that package is. - * @param names Array of current names to be mapped. + * @param packageNames Array of current names to be mapped. * @return Returns an array of the same size as the original, containing * the canonical name for each package. */ - public abstract String[] currentToCanonicalPackageNames(String[] names); + public abstract String[] currentToCanonicalPackageNames(@NonNull String[] packageNames); /** * Map from a packages canonical name to the current name in use on the device. - * @param names Array of new names to be mapped. + * @param packageNames Array of new names to be mapped. * @return Returns an array of the same size as the original, containing * the current name for each package. */ - public abstract String[] canonicalToCurrentPackageNames(String[] names); + public abstract String[] canonicalToCurrentPackageNames(@NonNull String[] packageNames); /** * Returns a "good" intent to launch a front-door activity in a package. @@ -3360,7 +3369,7 @@ public abstract class PackageManager { * @throws NameNotFoundException if a package with the given name cannot be * found on the system. */ - public abstract int[] getPackageGids(String packageName, @PackageInfoFlags int flags) + public abstract int[] getPackageGids(@NonNull String packageName, @PackageInfoFlags int flags) throws NameNotFoundException; /** @@ -3375,7 +3384,7 @@ public abstract class PackageManager { * @throws NameNotFoundException if a package with the given name can not be * found on the system. */ - public abstract int getPackageUid(String packageName, @PackageInfoFlags int flags) + public abstract int getPackageUid(@NonNull String packageName, @PackageInfoFlags int flags) throws NameNotFoundException; /** @@ -3393,7 +3402,7 @@ public abstract class PackageManager { * @hide */ @UnsupportedAppUsage - public abstract int getPackageUidAsUser(String packageName, @UserIdInt int userId) + public abstract int getPackageUidAsUser(@NonNull String packageName, @UserIdInt int userId) throws NameNotFoundException; /** @@ -3411,13 +3420,13 @@ public abstract class PackageManager { * @hide */ @UnsupportedAppUsage - public abstract int getPackageUidAsUser(String packageName, @PackageInfoFlags int flags, - @UserIdInt int userId) throws NameNotFoundException; + public abstract int getPackageUidAsUser(@NonNull String packageName, + @PackageInfoFlags int flags, @UserIdInt int userId) throws NameNotFoundException; /** * Retrieve all of the information we know about a particular permission. * - * @param name The fully qualified name (i.e. com.google.permission.LOGIN) + * @param permissionName The fully qualified name (i.e. com.google.permission.LOGIN) * of the permission you are interested in. * @param flags Additional option flags to modify the data returned. * @return Returns a {@link PermissionInfo} containing information about the @@ -3425,13 +3434,13 @@ public abstract class PackageManager { * @throws NameNotFoundException if a package with the given name cannot be * found on the system. */ - public abstract PermissionInfo getPermissionInfo(String name, @PermissionInfoFlags int flags) - throws NameNotFoundException; + public abstract PermissionInfo getPermissionInfo(@NonNull String permissionName, + @PermissionInfoFlags int flags) throws NameNotFoundException; /** * Query for all of the permissions associated with a particular group. * - * @param group The fully qualified name (i.e. com.google.permission.LOGIN) + * @param permissionGroup The fully qualified name (i.e. com.google.permission.LOGIN) * of the permission group you are interested in. Use null to * find all of the permissions not associated with a group. * @param flags Additional option flags to modify the data returned. @@ -3440,7 +3449,8 @@ public abstract class PackageManager { * @throws NameNotFoundException if a package with the given name cannot be * found on the system. */ - public abstract List<PermissionInfo> queryPermissionsByGroup(String group, + @NonNull + public abstract List<PermissionInfo> queryPermissionsByGroup(@NonNull String permissionGroup, @PermissionInfoFlags int flags) throws NameNotFoundException; /** @@ -3465,7 +3475,7 @@ public abstract class PackageManager { * Retrieve all of the information we know about a particular group of * permissions. * - * @param name The fully qualified name (i.e. + * @param permissionName The fully qualified name (i.e. * com.google.permission_group.APPS) of the permission you are * interested in. * @param flags Additional option flags to modify the data returned. @@ -3474,7 +3484,8 @@ public abstract class PackageManager { * @throws NameNotFoundException if a package with the given name cannot be * found on the system. */ - public abstract PermissionGroupInfo getPermissionGroupInfo(String name, + @NonNull + public abstract PermissionGroupInfo getPermissionGroupInfo(@NonNull String permissionName, @PermissionGroupInfoFlags int flags) throws NameNotFoundException; /** @@ -3484,6 +3495,7 @@ public abstract class PackageManager { * @return Returns a list of {@link PermissionGroupInfo} containing * information about all of the known permission groups. */ + @NonNull public abstract List<PermissionGroupInfo> getAllPermissionGroups( @PermissionGroupInfoFlags int flags); @@ -3504,12 +3516,14 @@ public abstract class PackageManager { * @throws NameNotFoundException if a package with the given name cannot be * found on the system. */ - public abstract ApplicationInfo getApplicationInfo(String packageName, + @NonNull + public abstract ApplicationInfo getApplicationInfo(@NonNull String packageName, @ApplicationInfoFlags int flags) throws NameNotFoundException; /** {@hide} */ + @NonNull @UnsupportedAppUsage - public abstract ApplicationInfo getApplicationInfoAsUser(String packageName, + public abstract ApplicationInfo getApplicationInfoAsUser(@NonNull String packageName, @ApplicationInfoFlags int flags, @UserIdInt int userId) throws NameNotFoundException; /** @@ -3552,7 +3566,8 @@ public abstract class PackageManager { * @throws NameNotFoundException if a package with the given name cannot be * found on the system. */ - public abstract ActivityInfo getActivityInfo(ComponentName component, + @NonNull + public abstract ActivityInfo getActivityInfo(@NonNull ComponentName component, @ComponentInfoFlags int flags) throws NameNotFoundException; /** @@ -3568,7 +3583,8 @@ public abstract class PackageManager { * @throws NameNotFoundException if a package with the given name cannot be * found on the system. */ - public abstract ActivityInfo getReceiverInfo(ComponentName component, + @NonNull + public abstract ActivityInfo getReceiverInfo(@NonNull ComponentName component, @ComponentInfoFlags int flags) throws NameNotFoundException; /** @@ -3583,7 +3599,8 @@ public abstract class PackageManager { * @throws NameNotFoundException if a package with the given name cannot be * found on the system. */ - public abstract ServiceInfo getServiceInfo(ComponentName component, + @NonNull + public abstract ServiceInfo getServiceInfo(@NonNull ComponentName component, @ComponentInfoFlags int flags) throws NameNotFoundException; /** @@ -3599,7 +3616,8 @@ public abstract class PackageManager { * @throws NameNotFoundException if a package with the given name cannot be * found on the system. */ - public abstract ProviderInfo getProviderInfo(ComponentName component, + @NonNull + public abstract ProviderInfo getProviderInfo(@NonNull ComponentName component, @ComponentInfoFlags int flags) throws NameNotFoundException; /** @@ -3612,7 +3630,8 @@ public abstract class PackageManager { * @throws NameNotFoundException if a module with the given name cannot be * found on the system. */ - public ModuleInfo getModuleInfo(String packageName, @ModuleInfoFlags int flags) + @NonNull + public ModuleInfo getModuleInfo(@NonNull String packageName, @ModuleInfoFlags int flags) throws NameNotFoundException { throw new UnsupportedOperationException( "getModuleInfo not implemented in subclass"); @@ -3626,7 +3645,8 @@ public abstract class PackageManager { * module, containing information about the module. In the unlikely case * there are no installed modules, an empty list is returned. */ - public @NonNull List<ModuleInfo> getInstalledModules(@ModuleInfoFlags int flags) { + @NonNull + public List<ModuleInfo> getInstalledModules(@ModuleInfoFlags int flags) { throw new UnsupportedOperationException( "getInstalledModules not implemented in subclass"); } @@ -3644,6 +3664,7 @@ public abstract class PackageManager { * applications with data directory i.e. applications which had been * deleted with {@code DONT_DELETE_DATA} flag set). */ + @NonNull public abstract List<PackageInfo> getInstalledPackages(@PackageInfoFlags int flags); /** @@ -3661,8 +3682,9 @@ public abstract class PackageManager { * applications with data directory i.e. applications which had been * deleted with {@code DONT_DELETE_DATA} flag set). */ + @NonNull public abstract List<PackageInfo> getPackagesHoldingPermissions( - String[] permissions, @PackageInfoFlags int flags); + @NonNull String[] permissions, @PackageInfoFlags int flags); /** * Return a List of all packages that are installed on the device, for a @@ -3680,6 +3702,7 @@ public abstract class PackageManager { * deleted with {@code DONT_DELETE_DATA} flag set). * @hide */ + @NonNull @TestApi @SystemApi @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) @@ -3690,8 +3713,8 @@ public abstract class PackageManager { * Check whether a particular package has been granted a particular * permission. * - * @param permName The name of the permission you are checking for. - * @param pkgName The name of the package you are checking against. + * @param permissionName The name of the permission you are checking for. + * @param packageName The name of the package you are checking against. * * @return If the package has the permission, PERMISSION_GRANTED is * returned. If it does not have the permission, PERMISSION_DENIED @@ -3701,7 +3724,9 @@ public abstract class PackageManager { * @see #PERMISSION_DENIED */ @CheckResult - public abstract @PermissionResult int checkPermission(String permName, String pkgName); + @PermissionResult + public abstract int checkPermission(@NonNull String permissionName, + @NonNull String packageName); /** * Checks whether a particular permissions has been revoked for a @@ -3710,14 +3735,14 @@ public abstract class PackageManager { * permissions, hence the only way for an app to get such a permission * is by a policy change. * - * @param permName The name of the permission you are checking for. - * @param pkgName The name of the package you are checking against. + * @param permissionName The name of the permission you are checking for. + * @param packageName The name of the package you are checking against. * * @return Whether the permission is restricted by policy. */ @CheckResult - public abstract boolean isPermissionRevokedByPolicy(@NonNull String permName, - @NonNull String pkgName); + public abstract boolean isPermissionRevokedByPolicy(@NonNull String permissionName, + @NonNull String packageName); /** * Gets the package name of the component controlling runtime permissions. @@ -3726,6 +3751,7 @@ public abstract class PackageManager { * * @hide */ + @NonNull @TestApi public abstract String getPermissionControllerPackageName(); @@ -3761,7 +3787,7 @@ public abstract class PackageManager { * * @see #removePermission(String) */ - public abstract boolean addPermission(PermissionInfo info); + public abstract boolean addPermission(@NonNull PermissionInfo info); /** * Like {@link #addPermission(PermissionInfo)} but asynchronously @@ -3770,7 +3796,7 @@ public abstract class PackageManager { * expense of no guarantee the added permission will be retained if * the device is rebooted before it is written. */ - public abstract boolean addPermissionAsync(PermissionInfo info); + public abstract boolean addPermissionAsync(@NonNull PermissionInfo info); /** * Removes a permission that was previously added with @@ -3778,14 +3804,14 @@ public abstract class PackageManager { * -- you are only allowed to remove permissions that you are allowed * to add. * - * @param name The name of the permission to remove. + * @param permissionName The name of the permission to remove. * * @throws SecurityException if you are not allowed to remove the * given permission name. * * @see #addPermission(PermissionInfo) */ - public abstract void removePermission(String name); + public abstract void removePermission(@NonNull String permissionName); /** * Permission flags set when granting or revoking a permission. @@ -3880,8 +3906,9 @@ public abstract class PackageManager { android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS, android.Manifest.permission.GET_RUNTIME_PERMISSIONS }) - public abstract @PermissionFlags int getPermissionFlags(String permissionName, - String packageName, @NonNull UserHandle user); + @PermissionFlags + public abstract int getPermissionFlags(@NonNull String permissionName, + @NonNull String packageName, @NonNull UserHandle user); /** * Updates the flags associated with a permission by replacing the flags in @@ -3901,9 +3928,9 @@ public abstract class PackageManager { android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS, android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS }) - public abstract void updatePermissionFlags(String permissionName, - String packageName, @PermissionFlags int flagMask, @PermissionFlags int flagValues, - @NonNull UserHandle user); + public abstract void updatePermissionFlags(@NonNull String permissionName, + @NonNull String packageName, @PermissionFlags int flagMask, + @PermissionFlags int flagValues, @NonNull UserHandle user); /** * Gets whether you should show UI with rationale for requesting a permission. @@ -3911,13 +3938,13 @@ public abstract class PackageManager { * which the permission is requested does not clearly communicate to the user * what would be the benefit from grating this permission. * - * @param permission A permission your app wants to request. + * @param permissionName A permission your app wants to request. * @return Whether you can show permission rationale UI. * * @hide */ @UnsupportedAppUsage - public abstract boolean shouldShowRequestPermissionRationale(String permission); + public abstract boolean shouldShowRequestPermissionRationale(@NonNull String permissionName); /** * Returns an {@link android.content.Intent} suitable for passing to @@ -3928,6 +3955,7 @@ public abstract class PackageManager { * * @hide */ + @NonNull @UnsupportedAppUsage public Intent buildRequestPermissionsIntent(@NonNull String[] permissions) { if (ArrayUtils.isEmpty(permissions)) { @@ -3946,8 +3974,8 @@ public abstract class PackageManager { * with each other: they can share the same user-id, run instrumentation * against each other, etc. * - * @param pkg1 First package name whose signature will be compared. - * @param pkg2 Second package name whose signature will be compared. + * @param packageName1 First package name whose signature will be compared. + * @param packageName2 Second package name whose signature will be compared. * * @return Returns an integer indicating whether all signatures on the * two packages match. The value is >= 0 ({@link #SIGNATURE_MATCH}) if @@ -3957,7 +3985,9 @@ public abstract class PackageManager { * @see #checkSignatures(int, int) */ @CheckResult - public abstract @SignatureResult int checkSignatures(String pkg1, String pkg2); + @SignatureResult + public abstract int checkSignatures(@NonNull String packageName1, + @NonNull String packageName2); /** * Like {@link #checkSignatures(String, String)}, but takes UIDs of @@ -4030,7 +4060,7 @@ public abstract class PackageManager { * @hide */ @UnsupportedAppUsage - public abstract int getUidForSharedUser(String sharedUserName) + public abstract int getUidForSharedUser(@NonNull String sharedUserName) throws NameNotFoundException; /** @@ -4049,6 +4079,7 @@ public abstract class PackageManager { * applications with data directory i.e. applications which had been * deleted with {@code DONT_DELETE_DATA} flag set). */ + @NonNull public abstract List<ApplicationInfo> getInstalledApplications(@ApplicationInfoFlags int flags); /** @@ -4071,6 +4102,7 @@ public abstract class PackageManager { * deleted with {@code DONT_DELETE_DATA} flag set). * @hide */ + @NonNull @TestApi public abstract List<ApplicationInfo> getInstalledApplicationsAsUser( @ApplicationInfoFlags int flags, @UserIdInt int userId); @@ -4121,7 +4153,7 @@ public abstract class PackageManager { * @see #getInstantAppCookieMaxBytes() * @see #clearInstantAppCookie() */ - public abstract boolean isInstantApp(String packageName); + public abstract boolean isInstantApp(@NonNull String packageName); /** * Gets the maximum size in bytes of the cookie data an instant app @@ -4208,6 +4240,7 @@ public abstract class PackageManager { * available on the system, or null if none are installed. * */ + @Nullable public abstract String[] getSystemSharedLibraryNames(); /** @@ -4296,6 +4329,7 @@ public abstract class PackageManager { * @return An array of FeatureInfo classes describing the features * that are available on the system, or null if there are none(!!). */ + @NonNull public abstract FeatureInfo[] getSystemAvailableFeatures(); /** @@ -4306,7 +4340,7 @@ public abstract class PackageManager { * * @return Returns true if the devices supports the feature, else false. */ - public abstract boolean hasSystemFeature(String name); + public abstract boolean hasSystemFeature(@NonNull String featureName); /** * Check whether the given feature name and version is one of the available @@ -4317,7 +4351,7 @@ public abstract class PackageManager { * * @return Returns true if the devices supports the feature, else false. */ - public abstract boolean hasSystemFeature(String name, int version); + public abstract boolean hasSystemFeature(@NonNull String featureName, int version); /** * Determine the best action to perform for a given Intent. This is how @@ -4345,7 +4379,9 @@ public abstract class PackageManager { * found and there is no default set, returns a ResolveInfo object * containing something else, such as the activity resolver. */ - public abstract ResolveInfo resolveActivity(Intent intent, @ResolveInfoFlags int flags); + @Nullable + public abstract ResolveInfo resolveActivity(@NonNull Intent intent, + @ResolveInfoFlags int flags); /** * Determine the best action to perform for a given Intent for a given user. @@ -4375,9 +4411,10 @@ public abstract class PackageManager { * containing something else, such as the activity resolver. * @hide */ + @Nullable @UnsupportedAppUsage - public abstract ResolveInfo resolveActivityAsUser(Intent intent, @ResolveInfoFlags int flags, - @UserIdInt int userId); + public abstract ResolveInfo resolveActivityAsUser(@NonNull Intent intent, + @ResolveInfoFlags int flags, @UserIdInt int userId); /** * Retrieve all activities that can be performed for the given intent. @@ -4394,7 +4431,8 @@ public abstract class PackageManager { * {@link #resolveActivity}. If there are no matching activities, an * empty list is returned. */ - public abstract List<ResolveInfo> queryIntentActivities(Intent intent, + @Nullable + public abstract List<ResolveInfo> queryIntentActivities(@NonNull Intent intent, @ResolveInfoFlags int flags); /** @@ -4414,8 +4452,9 @@ public abstract class PackageManager { * empty list is returned. * @hide */ + @Nullable @UnsupportedAppUsage - public abstract List<ResolveInfo> queryIntentActivitiesAsUser(Intent intent, + public abstract List<ResolveInfo> queryIntentActivitiesAsUser(@NonNull Intent intent, @ResolveInfoFlags int flags, @UserIdInt int userId); /** @@ -4469,8 +4508,9 @@ public abstract class PackageManager { * included by one of the <var>specifics</var> intents. If there are * no matching activities, an empty list is returned. */ + @NonNull public abstract List<ResolveInfo> queryIntentActivityOptions(@Nullable ComponentName caller, - @Nullable Intent[] specifics, Intent intent, @ResolveInfoFlags int flags); + @Nullable Intent[] specifics, @NonNull Intent intent, @ResolveInfoFlags int flags); /** * Retrieve all receivers that can handle a broadcast of the given intent. @@ -4481,7 +4521,8 @@ public abstract class PackageManager { * each matching receiver, ordered from best to worst. If there are * no matching receivers, an empty list or null is returned. */ - public abstract List<ResolveInfo> queryBroadcastReceivers(Intent intent, + @NonNull + public abstract List<ResolveInfo> queryBroadcastReceivers(@NonNull Intent intent, @ResolveInfoFlags int flags); /** @@ -4496,9 +4537,10 @@ public abstract class PackageManager { * no matching receivers, an empty list or null is returned. * @hide */ + @NonNull @SystemApi @RequiresPermission(Manifest.permission.INTERACT_ACROSS_USERS) - public List<ResolveInfo> queryBroadcastReceiversAsUser(Intent intent, + public List<ResolveInfo> queryBroadcastReceiversAsUser(@NonNull Intent intent, @ResolveInfoFlags int flags, UserHandle userHandle) { return queryBroadcastReceiversAsUser(intent, flags, userHandle.getIdentifier()); } @@ -4506,15 +4548,17 @@ public abstract class PackageManager { /** * @hide */ + @NonNull @UnsupportedAppUsage - public abstract List<ResolveInfo> queryBroadcastReceiversAsUser(Intent intent, + public abstract List<ResolveInfo> queryBroadcastReceiversAsUser(@NonNull Intent intent, @ResolveInfoFlags int flags, @UserIdInt int userId); - /** {@hide} */ + /** @deprecated @hide */ + @NonNull @Deprecated @UnsupportedAppUsage - public List<ResolveInfo> queryBroadcastReceivers(Intent intent, + public List<ResolveInfo> queryBroadcastReceivers(@NonNull Intent intent, @ResolveInfoFlags int flags, @UserIdInt int userId) { final String msg = "Shame on you for calling the hidden API " + "queryBroadcastReceivers(). Shame!"; @@ -4536,13 +4580,15 @@ public abstract class PackageManager { * that was determined to be the best action. Returns null if no * matching service was found. */ - public abstract ResolveInfo resolveService(Intent intent, @ResolveInfoFlags int flags); + @Nullable + public abstract ResolveInfo resolveService(@NonNull Intent intent, @ResolveInfoFlags int flags); /** * @hide */ - public abstract ResolveInfo resolveServiceAsUser(Intent intent, @ResolveInfoFlags int flags, - @UserIdInt int userId); + @Nullable + public abstract ResolveInfo resolveServiceAsUser(@NonNull Intent intent, + @ResolveInfoFlags int flags, @UserIdInt int userId); /** * Retrieve all services that can match the given intent. @@ -4555,7 +4601,8 @@ public abstract class PackageManager { * {@link #resolveService}. If there are no matching services, an * empty list or null is returned. */ - public abstract List<ResolveInfo> queryIntentServices(Intent intent, + @NonNull + public abstract List<ResolveInfo> queryIntentServices(@NonNull Intent intent, @ResolveInfoFlags int flags); /** @@ -4571,8 +4618,9 @@ public abstract class PackageManager { * empty list or null is returned. * @hide */ + @NonNull @UnsupportedAppUsage - public abstract List<ResolveInfo> queryIntentServicesAsUser(Intent intent, + public abstract List<ResolveInfo> queryIntentServicesAsUser(@NonNull Intent intent, @ResolveInfoFlags int flags, @UserIdInt int userId); /** @@ -4608,9 +4656,10 @@ public abstract class PackageManager { * no matching services, an empty list or null is returned. * @hide */ + @NonNull @UnsupportedAppUsage public abstract List<ResolveInfo> queryIntentContentProvidersAsUser( - Intent intent, @ResolveInfoFlags int flags, @UserIdInt int userId); + @NonNull Intent intent, @ResolveInfoFlags int flags, @UserIdInt int userId); /** * Retrieve all providers that can match the given intent. @@ -4642,7 +4691,8 @@ public abstract class PackageManager { * each matching provider, ordered from best to worst. If there are * no matching services, an empty list or null is returned. */ - public abstract List<ResolveInfo> queryIntentContentProviders(Intent intent, + @NonNull + public abstract List<ResolveInfo> queryIntentContentProviders(@NonNull Intent intent, @ResolveInfoFlags int flags); /** @@ -4659,21 +4709,23 @@ public abstract class PackageManager { * @return A {@link ProviderInfo} object containing information about the * provider. If a provider was not found, returns null. */ - public abstract ProviderInfo resolveContentProvider(String authority, + @Nullable + public abstract ProviderInfo resolveContentProvider(@NonNull String authority, @ComponentInfoFlags int flags); /** * Find a single content provider by its base path name. * - * @param name The name of the provider to find. + * @param providerName The name of the provider to find. * @param flags Additional option flags to modify the data returned. * @param userId The user id. * @return A {@link ProviderInfo} object containing information about the * provider. If a provider was not found, returns null. * @hide */ + @Nullable @UnsupportedAppUsage - public abstract ProviderInfo resolveContentProviderAsUser(String name, + public abstract ProviderInfo resolveContentProviderAsUser(@NonNull String providerName, @ComponentInfoFlags int flags, @UserIdInt int userId); /** @@ -4693,8 +4745,9 @@ public abstract class PackageManager { * <var>processName</var> is null, all known content providers. * <em>If there are no matching providers, null is returned.</em> */ + @NonNull public abstract List<ProviderInfo> queryContentProviders( - String processName, int uid, @ComponentInfoFlags int flags); + @Nullable String processName, int uid, @ComponentInfoFlags int flags); /** * Same as {@link #queryContentProviders}, except when {@code metaDataKey} is not null, @@ -4711,8 +4764,9 @@ public abstract class PackageManager { * * @hide */ - public List<ProviderInfo> queryContentProviders( - String processName, int uid, @ComponentInfoFlags int flags, String metaDataKey) { + @NonNull + public List<ProviderInfo> queryContentProviders(@Nullable String processName, + int uid, @ComponentInfoFlags int flags, String metaDataKey) { // Provide the default implementation for mocks. return queryContentProviders(processName, uid, flags); } @@ -4730,7 +4784,8 @@ public abstract class PackageManager { * @throws NameNotFoundException if a package with the given name cannot be * found on the system. */ - public abstract InstrumentationInfo getInstrumentationInfo(ComponentName className, + @NonNull + public abstract InstrumentationInfo getInstrumentationInfo(@NonNull ComponentName className, @InstrumentationInfoFlags int flags) throws NameNotFoundException; /** @@ -4745,7 +4800,8 @@ public abstract class PackageManager { * entry for each matching instrumentation. If there are no * instrumentation available, returns an empty list. */ - public abstract List<InstrumentationInfo> queryInstrumentation(String targetPackage, + @NonNull + public abstract List<InstrumentationInfo> queryInstrumentation(@NonNull String targetPackage, @InstrumentationInfoFlags int flags); /** @@ -4765,8 +4821,9 @@ public abstract class PackageManager { * @return Returns a Drawable holding the requested image. Returns null if * an image could not be found for any reason. */ - public abstract Drawable getDrawable(String packageName, @DrawableRes int resid, - ApplicationInfo appInfo); + @Nullable + public abstract Drawable getDrawable(@NonNull String packageName, @DrawableRes int resid, + @Nullable ApplicationInfo appInfo); /** * Retrieve the icon associated with an activity. Given the full name of @@ -4783,7 +4840,8 @@ public abstract class PackageManager { * * @see #getActivityIcon(Intent) */ - public abstract Drawable getActivityIcon(ComponentName activityName) + @NonNull + public abstract Drawable getActivityIcon(@NonNull ComponentName activityName) throws NameNotFoundException; /** @@ -4803,7 +4861,8 @@ public abstract class PackageManager { * * @see #getActivityIcon(ComponentName) */ - public abstract Drawable getActivityIcon(Intent intent) + @NonNull + public abstract Drawable getActivityIcon(@NonNull Intent intent) throws NameNotFoundException; /** @@ -4819,7 +4878,8 @@ public abstract class PackageManager { * activity could not be loaded. * @see #getActivityBanner(Intent) */ - public abstract Drawable getActivityBanner(ComponentName activityName) + @Nullable + public abstract Drawable getActivityBanner(@NonNull ComponentName activityName) throws NameNotFoundException; /** @@ -4837,7 +4897,8 @@ public abstract class PackageManager { * matching the given intent could not be loaded. * @see #getActivityBanner(ComponentName) */ - public abstract Drawable getActivityBanner(Intent intent) + @Nullable + public abstract Drawable getActivityBanner(@NonNull Intent intent) throws NameNotFoundException; /** @@ -4846,6 +4907,7 @@ public abstract class PackageManager { * * @return Drawable Image of the icon. */ + @NonNull public abstract Drawable getDefaultActivityIcon(); /** @@ -4859,7 +4921,8 @@ public abstract class PackageManager { * * @see #getApplicationIcon(String) */ - public abstract Drawable getApplicationIcon(ApplicationInfo info); + @NonNull + public abstract Drawable getApplicationIcon(@NonNull ApplicationInfo info); /** * Retrieve the icon associated with an application. Given the name of the @@ -4877,7 +4940,8 @@ public abstract class PackageManager { * * @see #getApplicationIcon(ApplicationInfo) */ - public abstract Drawable getApplicationIcon(String packageName) + @NonNull + public abstract Drawable getApplicationIcon(@NonNull String packageName) throws NameNotFoundException; /** @@ -4888,7 +4952,8 @@ public abstract class PackageManager { * banner specified. * @see #getApplicationBanner(String) */ - public abstract Drawable getApplicationBanner(ApplicationInfo info); + @Nullable + public abstract Drawable getApplicationBanner(@NonNull ApplicationInfo info); /** * Retrieve the banner associated with an application. Given the name of the @@ -4904,7 +4969,8 @@ public abstract class PackageManager { * application could not be loaded. * @see #getApplicationBanner(ApplicationInfo) */ - public abstract Drawable getApplicationBanner(String packageName) + @Nullable + public abstract Drawable getApplicationBanner(@NonNull String packageName) throws NameNotFoundException; /** @@ -4920,7 +4986,8 @@ public abstract class PackageManager { * activity could not be loaded. * @see #getActivityLogo(Intent) */ - public abstract Drawable getActivityLogo(ComponentName activityName) + @Nullable + public abstract Drawable getActivityLogo(@NonNull ComponentName activityName) throws NameNotFoundException; /** @@ -4941,7 +5008,8 @@ public abstract class PackageManager { * * @see #getActivityLogo(ComponentName) */ - public abstract Drawable getActivityLogo(Intent intent) + @Nullable + public abstract Drawable getActivityLogo(@NonNull Intent intent) throws NameNotFoundException; /** @@ -4955,7 +5023,8 @@ public abstract class PackageManager { * * @see #getApplicationLogo(String) */ - public abstract Drawable getApplicationLogo(ApplicationInfo info); + @Nullable + public abstract Drawable getApplicationLogo(@NonNull ApplicationInfo info); /** * Retrieve the logo associated with an application. Given the name of the @@ -4974,7 +5043,8 @@ public abstract class PackageManager { * * @see #getApplicationLogo(ApplicationInfo) */ - public abstract Drawable getApplicationLogo(String packageName) + @Nullable + public abstract Drawable getApplicationLogo(@NonNull String packageName) throws NameNotFoundException; /** @@ -4988,12 +5058,14 @@ public abstract class PackageManager { * is performed in place and the original drawable is returned. * </p> * - * @param icon The icon to badge. + * @param drawable The drawable to badge. * @param user The target user. * @return A drawable that combines the original icon and a badge as * determined by the system. */ - public abstract Drawable getUserBadgedIcon(Drawable icon, UserHandle user); + @NonNull + public abstract Drawable getUserBadgedIcon(@NonNull Drawable drawable, + @NonNull UserHandle user); /** * If the target user is a managed profile of the calling user or the caller @@ -5019,8 +5091,9 @@ public abstract class PackageManager { * @return A drawable that combines the original drawable and a badge as * determined by the system. */ - public abstract Drawable getUserBadgedDrawableForDensity(Drawable drawable, - UserHandle user, Rect badgeLocation, int badgeDensity); + @NonNull + public abstract Drawable getUserBadgedDrawableForDensity(@NonNull Drawable drawable, + @NonNull UserHandle user, @Nullable Rect badgeLocation, int badgeDensity); /** * If the target user is a managed profile of the calling user or the caller @@ -5034,8 +5107,9 @@ public abstract class PackageManager { * @return the drawable or null if no drawable is required. * @hide */ + @Nullable @UnsupportedAppUsage - public abstract Drawable getUserBadgeForDensity(UserHandle user, int density); + public abstract Drawable getUserBadgeForDensity(@NonNull UserHandle user, int density); /** * If the target user is a managed profile of the calling user or the caller @@ -5051,8 +5125,10 @@ public abstract class PackageManager { * @return the drawable or null if no drawable is required. * @hide */ + @Nullable @UnsupportedAppUsage - public abstract Drawable getUserBadgeForDensityNoBackground(UserHandle user, int density); + public abstract Drawable getUserBadgeForDensityNoBackground(@NonNull UserHandle user, + int density); /** * If the target user is a managed profile of the calling user or the caller @@ -5065,7 +5141,9 @@ public abstract class PackageManager { * @return A label that combines the original label and a badge as * determined by the system. */ - public abstract CharSequence getUserBadgedLabel(CharSequence label, UserHandle user); + @NonNull + public abstract CharSequence getUserBadgedLabel(@NonNull CharSequence label, + @NonNull UserHandle user); /** * Retrieve text from a package. This is a low-level API used by @@ -5084,8 +5162,9 @@ public abstract class PackageManager { * @return Returns a CharSequence holding the requested text. Returns null * if the text could not be found for any reason. */ - public abstract CharSequence getText(String packageName, @StringRes int resid, - ApplicationInfo appInfo); + @Nullable + public abstract CharSequence getText(@NonNull String packageName, @StringRes int resid, + @Nullable ApplicationInfo appInfo); /** * Retrieve an XML file from a package. This is a low-level API used to @@ -5103,8 +5182,9 @@ public abstract class PackageManager { * data. Returns null if the xml resource could not be found for any * reason. */ - public abstract XmlResourceParser getXml(String packageName, @XmlRes int resid, - ApplicationInfo appInfo); + @Nullable + public abstract XmlResourceParser getXml(@NonNull String packageName, @XmlRes int resid, + @Nullable ApplicationInfo appInfo); /** * Return the label to use for this application. @@ -5113,7 +5193,8 @@ public abstract class PackageManager { * it could not be found for any reason. * @param info The application to get the label of. */ - public abstract CharSequence getApplicationLabel(ApplicationInfo info); + @NonNull + public abstract CharSequence getApplicationLabel(@NonNull ApplicationInfo info); /** * Retrieve the resources associated with an activity. Given the full @@ -5130,7 +5211,8 @@ public abstract class PackageManager { * * @see #getResourcesForApplication(ApplicationInfo) */ - public abstract Resources getResourcesForActivity(ComponentName activityName) + @NonNull + public abstract Resources getResourcesForActivity(@NonNull ComponentName activityName) throws NameNotFoundException; /** @@ -5143,7 +5225,8 @@ public abstract class PackageManager { * @throws NameNotFoundException Thrown if the resources for the given * application could not be loaded (most likely because it was uninstalled). */ - public abstract Resources getResourcesForApplication(ApplicationInfo app) + @NonNull + public abstract Resources getResourcesForApplication(@NonNull ApplicationInfo app) throws NameNotFoundException; /** @@ -5152,7 +5235,7 @@ public abstract class PackageManager { * calls getResources() to return its application's resources. If the * appPackageName cannot be found, NameNotFoundException is thrown. * - * @param appPackageName Package name of the application whose resources + * @param packageName Package name of the application whose resources * are to be retrieved. * * @return Returns the application's Resources. @@ -5161,12 +5244,14 @@ public abstract class PackageManager { * * @see #getResourcesForApplication(ApplicationInfo) */ - public abstract Resources getResourcesForApplication(String appPackageName) + @NonNull + public abstract Resources getResourcesForApplication(@NonNull String packageName) throws NameNotFoundException; /** @hide */ + @NonNull @UnsupportedAppUsage - public abstract Resources getResourcesForApplicationAsUser(String appPackageName, + public abstract Resources getResourcesForApplicationAsUser(@NonNull String packageName, @UserIdInt int userId) throws NameNotFoundException; /** @@ -5178,7 +5263,9 @@ public abstract class PackageManager { * @return A PackageInfo object containing information about the package * archive. If the package could not be parsed, returns null. */ - public PackageInfo getPackageArchiveInfo(String archiveFilePath, @PackageInfoFlags int flags) { + @Nullable + public PackageInfo getPackageArchiveInfo(@NonNull String archiveFilePath, + @PackageInfoFlags int flags) { final PackageParser parser = new PackageParser(); parser.setCallback(new PackageParser.CallbackImpl(this)); final File apkFile = new File(archiveFilePath); @@ -5212,7 +5299,8 @@ public abstract class PackageManager { */ @Deprecated @SystemApi - public abstract int installExistingPackage(String packageName) throws NameNotFoundException; + public abstract int installExistingPackage(@NonNull String packageName) + throws NameNotFoundException; /** * If there is already an application with the given package name installed @@ -5223,8 +5311,8 @@ public abstract class PackageManager { */ @Deprecated @SystemApi - public abstract int installExistingPackage(String packageName, @InstallReason int installReason) - throws NameNotFoundException; + public abstract int installExistingPackage(@NonNull String packageName, + @InstallReason int installReason) throws NameNotFoundException; /** * If there is already an application with the given package name installed @@ -5239,8 +5327,8 @@ public abstract class PackageManager { Manifest.permission.INSTALL_PACKAGES, Manifest.permission.INTERACT_ACROSS_USERS_FULL}) @UnsupportedAppUsage - public abstract int installExistingPackageAsUser(String packageName, @UserIdInt int userId) - throws NameNotFoundException; + public abstract int installExistingPackageAsUser(@NonNull String packageName, + @UserIdInt int userId) throws NameNotFoundException; /** * Allows a package listening to the @@ -5316,7 +5404,7 @@ public abstract class PackageManager { @SystemApi @RequiresPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT) public abstract void verifyIntentFilter(int verificationId, int verificationCode, - List<String> failedDomains); + @NonNull List<String> failedDomains); /** * Get the status of a Domain Verification Result for an IntentFilter. This is @@ -5340,7 +5428,8 @@ public abstract class PackageManager { */ @SystemApi @RequiresPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL) - public abstract int getIntentVerificationStatusAsUser(String packageName, @UserIdInt int userId); + public abstract int getIntentVerificationStatusAsUser(@NonNull String packageName, + @UserIdInt int userId); /** * Allow to change the status of a Intent Verification status for all IntentFilter of an App. @@ -5364,8 +5453,8 @@ public abstract class PackageManager { */ @SystemApi @RequiresPermission(android.Manifest.permission.SET_PREFERRED_APPLICATIONS) - public abstract boolean updateIntentVerificationStatusAsUser(String packageName, int status, - @UserIdInt int userId); + public abstract boolean updateIntentVerificationStatusAsUser(@NonNull String packageName, + int status, @UserIdInt int userId); /** * Get the list of IntentFilterVerificationInfo for a specific package and User. @@ -5379,9 +5468,10 @@ public abstract class PackageManager { * * @hide */ + @NonNull @SystemApi public abstract List<IntentFilterVerificationInfo> getIntentFilterVerifications( - String packageName); + @NonNull String packageName); /** * Get the list of IntentFilter for a specific package. @@ -5394,8 +5484,9 @@ public abstract class PackageManager { * * @hide */ + @NonNull @SystemApi - public abstract List<IntentFilter> getAllIntentFilters(String packageName); + public abstract List<IntentFilter> getAllIntentFilters(@NonNull String packageName); /** * Get the default Browser package name for a specific user. @@ -5407,6 +5498,7 @@ public abstract class PackageManager { * * @hide */ + @Nullable @TestApi @SystemApi @RequiresPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL) @@ -5428,7 +5520,7 @@ public abstract class PackageManager { @RequiresPermission(allOf = { Manifest.permission.SET_PREFERRED_APPLICATIONS, Manifest.permission.INTERACT_ACROSS_USERS_FULL}) - public abstract boolean setDefaultBrowserPackageNameAsUser(String packageName, + public abstract boolean setDefaultBrowserPackageNameAsUser(@Nullable String packageName, @UserIdInt int userId); /** @@ -5446,13 +5538,13 @@ public abstract class PackageManager { * @param installerPackageName The package name of the new installer. May be * null to clear the association. */ - public abstract void setInstallerPackageName(String targetPackage, - String installerPackageName); + public abstract void setInstallerPackageName(@NonNull String targetPackage, + @Nullable String installerPackageName); /** @hide */ @SystemApi @RequiresPermission(Manifest.permission.INSTALL_PACKAGES) - public abstract void setUpdateAvailable(String packageName, boolean updateAvaialble); + public abstract void setUpdateAvailable(@NonNull String packageName, boolean updateAvaialble); /** * Attempts to delete a package. Since this may take a little while, the @@ -5472,8 +5564,8 @@ public abstract class PackageManager { */ @RequiresPermission(Manifest.permission.DELETE_PACKAGES) @UnsupportedAppUsage - public abstract void deletePackage(String packageName, IPackageDeleteObserver observer, - @DeleteFlags int flags); + public abstract void deletePackage(@NonNull String packageName, + @Nullable IPackageDeleteObserver observer, @DeleteFlags int flags); /** * Attempts to delete a package. Since this may take a little while, the @@ -5495,7 +5587,8 @@ public abstract class PackageManager { Manifest.permission.INTERACT_ACROSS_USERS_FULL}) @UnsupportedAppUsage public abstract void deletePackageAsUser(@NonNull String packageName, - IPackageDeleteObserver observer, @DeleteFlags int flags, @UserIdInt int userId); + @Nullable IPackageDeleteObserver observer, @DeleteFlags int flags, + @UserIdInt int userId); /** * Retrieve the package name of the application that installed a package. This identifies @@ -5505,7 +5598,7 @@ public abstract class PackageManager { * @throws IllegalArgumentException if the given package name is not installed */ @Nullable - public abstract String getInstallerPackageName(String packageName); + public abstract String getInstallerPackageName(@NonNull String packageName); /** * Attempts to clear the user data directory of an application. @@ -5522,8 +5615,8 @@ public abstract class PackageManager { * @hide */ @UnsupportedAppUsage - public abstract void clearApplicationUserData(String packageName, - IPackageDataObserver observer); + public abstract void clearApplicationUserData(@NonNull String packageName, + @Nullable IPackageDataObserver observer); /** * Attempts to delete the cache files associated with an application. * Since this may take a little while, the result will @@ -5541,8 +5634,8 @@ public abstract class PackageManager { * @hide */ @UnsupportedAppUsage - public abstract void deleteApplicationCacheFiles(String packageName, - IPackageDataObserver observer); + public abstract void deleteApplicationCacheFiles(@NonNull String packageName, + @Nullable IPackageDataObserver observer); /** * Attempts to delete the cache files associated with an application for a given user. Since @@ -5563,8 +5656,8 @@ public abstract class PackageManager { * @hide */ @UnsupportedAppUsage - public abstract void deleteApplicationCacheFilesAsUser(String packageName, int userId, - IPackageDataObserver observer); + public abstract void deleteApplicationCacheFilesAsUser(@NonNull String packageName, + @UserIdInt int userId, @Nullable IPackageDataObserver observer); /** * Free storage by deleting LRU sorted list of cache files across @@ -5589,14 +5682,15 @@ public abstract class PackageManager { * @hide */ @UnsupportedAppUsage - public void freeStorageAndNotify(long freeStorageSize, IPackageDataObserver observer) { + public void freeStorageAndNotify(long freeStorageSize, + @Nullable IPackageDataObserver observer) { freeStorageAndNotify(null, freeStorageSize, observer); } /** {@hide} */ @UnsupportedAppUsage - public abstract void freeStorageAndNotify(String volumeUuid, long freeStorageSize, - IPackageDataObserver observer); + public abstract void freeStorageAndNotify(@Nullable String volumeUuid, long freeStorageSize, + @Nullable IPackageDataObserver observer); /** * Free storage by deleting LRU sorted list of cache files across @@ -5622,13 +5716,14 @@ public abstract class PackageManager { * @hide */ @UnsupportedAppUsage - public void freeStorage(long freeStorageSize, IntentSender pi) { + public void freeStorage(long freeStorageSize, @Nullable IntentSender pi) { freeStorage(null, freeStorageSize, pi); } /** {@hide} */ @UnsupportedAppUsage - public abstract void freeStorage(String volumeUuid, long freeStorageSize, IntentSender pi); + public abstract void freeStorage(@Nullable String volumeUuid, long freeStorageSize, + @Nullable IntentSender pi); /** * Retrieve the size information for a package. @@ -5651,8 +5746,8 @@ public abstract class PackageManager { */ @Deprecated @UnsupportedAppUsage - public abstract void getPackageSizeInfoAsUser(String packageName, @UserIdInt int userId, - IPackageStatsObserver observer); + public abstract void getPackageSizeInfoAsUser(@NonNull String packageName, + @UserIdInt int userId, @Nullable IPackageStatsObserver observer); /** * Like {@link #getPackageSizeInfoAsUser(String, int, IPackageStatsObserver)}, but @@ -5663,7 +5758,7 @@ public abstract class PackageManager { */ @Deprecated @UnsupportedAppUsage - public void getPackageSizeInfo(String packageName, IPackageStatsObserver observer) { + public void getPackageSizeInfo(@NonNull String packageName, IPackageStatsObserver observer) { getPackageSizeInfoAsUser(packageName, getUserId(), observer); } @@ -5676,7 +5771,7 @@ public abstract class PackageManager { * holders, see {@link android.app.role.RoleManager}. */ @Deprecated - public abstract void addPackageToPreferred(String packageName); + public abstract void addPackageToPreferred(@NonNull String packageName); /** * @deprecated This function no longer does anything. It is the platform's @@ -5687,7 +5782,7 @@ public abstract class PackageManager { * holders, see {@link android.app.role.RoleManager}. */ @Deprecated - public abstract void removePackageFromPreferred(String packageName); + public abstract void removePackageFromPreferred(@NonNull String packageName); /** * Retrieve the list of all currently configured preferred packages. The @@ -5705,6 +5800,7 @@ public abstract class PackageManager { * an app to be responsible for a particular role and to check current role * holders, see {@link android.app.role.RoleManager}. */ + @NonNull @Deprecated public abstract List<PackageInfo> getPreferredPackages(@PackageInfoFlags int flags); @@ -5731,8 +5827,8 @@ public abstract class PackageManager { * holders, see {@link android.app.role.RoleManager}. */ @Deprecated - public abstract void addPreferredActivity(IntentFilter filter, int match, - ComponentName[] set, ComponentName activity); + public abstract void addPreferredActivity(@NonNull IntentFilter filter, int match, + @Nullable ComponentName[] set, @NonNull ComponentName activity); /** * Same as {@link #addPreferredActivity(IntentFilter, int, @@ -5749,8 +5845,8 @@ public abstract class PackageManager { */ @Deprecated @UnsupportedAppUsage - public void addPreferredActivityAsUser(IntentFilter filter, int match, - ComponentName[] set, ComponentName activity, @UserIdInt int userId) { + public void addPreferredActivityAsUser(@NonNull IntentFilter filter, int match, + @Nullable ComponentName[] set, @NonNull ComponentName activity, @UserIdInt int userId) { throw new RuntimeException("Not implemented. Must override in a subclass."); } @@ -5781,8 +5877,8 @@ public abstract class PackageManager { */ @Deprecated @UnsupportedAppUsage - public abstract void replacePreferredActivity(IntentFilter filter, int match, - ComponentName[] set, ComponentName activity); + public abstract void replacePreferredActivity(@NonNull IntentFilter filter, int match, + @Nullable ComponentName[] set, @NonNull ComponentName activity); /** * Replaces an existing preferred activity mapping to the system, and if that were not present @@ -5826,8 +5922,8 @@ public abstract class PackageManager { */ @Deprecated @UnsupportedAppUsage - public void replacePreferredActivityAsUser(IntentFilter filter, int match, - ComponentName[] set, ComponentName activity, @UserIdInt int userId) { + public void replacePreferredActivityAsUser(@NonNull IntentFilter filter, int match, + @Nullable ComponentName[] set, @NonNull ComponentName activity, @UserIdInt int userId) { throw new RuntimeException("Not implemented. Must override in a subclass."); } @@ -5848,7 +5944,7 @@ public abstract class PackageManager { * holders, see {@link android.app.role.RoleManager}. */ @Deprecated - public abstract void clearPackagePreferredActivities(String packageName); + public abstract void clearPackagePreferredActivities(@NonNull String packageName); /** * Retrieve all preferred activities, previously added with @@ -5876,15 +5972,16 @@ public abstract class PackageManager { */ @Deprecated public abstract int getPreferredActivities(@NonNull List<IntentFilter> outFilters, - @NonNull List<ComponentName> outActivities, String packageName); + @NonNull List<ComponentName> outActivities, @Nullable String packageName); /** * Ask for the set of available 'home' activities and the current explicit * default, if any. * @hide */ + @Nullable @UnsupportedAppUsage - public abstract ComponentName getHomeActivities(List<ResolveInfo> outActivities); + public abstract ComponentName getHomeActivities(@NonNull List<ResolveInfo> outActivities); /** * Set the enabled setting for a package component (activity, receiver, service, provider). @@ -5984,7 +6081,7 @@ public abstract class PackageManager { * @hide */ @UnsupportedAppUsage - public abstract void flushPackageRestrictionsAsUser(int userId); + public abstract void flushPackageRestrictionsAsUser(@UserIdInt int userId); /** * Puts the package in a hidden state, which is almost like an uninstalled state, @@ -5994,8 +6091,8 @@ public abstract class PackageManager { * @hide */ @UnsupportedAppUsage - public abstract boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden, - UserHandle userHandle); + public abstract boolean setApplicationHiddenSettingAsUser(@NonNull String packageName, + boolean hidden, @NonNull UserHandle userHandle); /** * Returns the hidden state of a package. @@ -6003,8 +6100,8 @@ public abstract class PackageManager { * @hide */ @UnsupportedAppUsage - public abstract boolean getApplicationHiddenSettingAsUser(String packageName, - UserHandle userHandle); + public abstract boolean getApplicationHiddenSettingAsUser(@NonNull String packageName, + @NonNull UserHandle userHandle); /** * Return whether the device has been booted into safe mode. @@ -6020,7 +6117,8 @@ public abstract class PackageManager { */ @SystemApi @RequiresPermission(Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS) - public abstract void addOnPermissionsChangeListener(OnPermissionsChangedListener listener); + public abstract void addOnPermissionsChangeListener( + @NonNull OnPermissionsChangedListener listener); /** * Remvoes a listener for permission changes for installed packages. @@ -6031,7 +6129,8 @@ public abstract class PackageManager { */ @SystemApi @RequiresPermission(Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS) - public abstract void removeOnPermissionsChangeListener(OnPermissionsChangedListener listener); + public abstract void removeOnPermissionsChangeListener( + @NonNull OnPermissionsChangedListener listener); /** * Return the {@link KeySet} associated with the String alias for this @@ -6041,14 +6140,16 @@ public abstract class PackageManager { * application's AndroidManifest.xml. * @hide */ + @NonNull @UnsupportedAppUsage - public abstract KeySet getKeySetByAlias(String packageName, String alias); + public abstract KeySet getKeySetByAlias(@NonNull String packageName, @NonNull String alias); /** Return the signing {@link KeySet} for this application. * @hide */ + @NonNull @UnsupportedAppUsage - public abstract KeySet getSigningKeySet(String packageName); + public abstract KeySet getSigningKeySet(@NonNull String packageName); /** * Return whether the package denoted by packageName has been signed by all @@ -6058,7 +6159,7 @@ public abstract class PackageManager { * @hide */ @UnsupportedAppUsage - public abstract boolean isSignedBy(String packageName, KeySet ks); + public abstract boolean isSignedBy(@NonNull String packageName, @NonNull KeySet ks); /** * Return whether the package denoted by packageName has been signed by all @@ -6067,7 +6168,7 @@ public abstract class PackageManager { * @hide */ @UnsupportedAppUsage - public abstract boolean isSignedByExactly(String packageName, KeySet ks); + public abstract boolean isSignedByExactly(@NonNull String packageName, @NonNull KeySet ks); /** * Flag to denote no restrictions. This should be used to clear any restrictions that may have @@ -6284,7 +6385,7 @@ public abstract class PackageManager { * @hide */ @UnsupportedAppUsage - public abstract boolean isPackageSuspendedForUser(String packageName, int userId); + public abstract boolean isPackageSuspendedForUser(@NonNull String packageName, int userId); /** * Query if an app is currently suspended. @@ -6294,7 +6395,7 @@ public abstract class PackageManager { * * @see #isPackageSuspended() */ - public boolean isPackageSuspended(String packageName) throws NameNotFoundException { + public boolean isPackageSuspended(@NonNull String packageName) throws NameNotFoundException { throw new UnsupportedOperationException("isPackageSuspended not implemented"); } @@ -6378,23 +6479,26 @@ public abstract class PackageManager { /** {@hide} */ @UnsupportedAppUsage - public abstract void registerMoveCallback(MoveCallback callback, Handler handler); + public abstract void registerMoveCallback(@NonNull MoveCallback callback, + @NonNull Handler handler); /** {@hide} */ @UnsupportedAppUsage - public abstract void unregisterMoveCallback(MoveCallback callback); + public abstract void unregisterMoveCallback(@NonNull MoveCallback callback); /** {@hide} */ @UnsupportedAppUsage - public abstract int movePackage(String packageName, VolumeInfo vol); + public abstract int movePackage(@NonNull String packageName, @NonNull VolumeInfo vol); /** {@hide} */ @UnsupportedAppUsage - public abstract @Nullable VolumeInfo getPackageCurrentVolume(ApplicationInfo app); + public abstract @Nullable VolumeInfo getPackageCurrentVolume(@NonNull ApplicationInfo app); /** {@hide} */ + @NonNull @UnsupportedAppUsage - public abstract @NonNull List<VolumeInfo> getPackageCandidateVolumes(ApplicationInfo app); + public abstract List<VolumeInfo> getPackageCandidateVolumes( + @NonNull ApplicationInfo app); /** {@hide} */ - public abstract int movePrimaryStorage(VolumeInfo vol); + public abstract int movePrimaryStorage(@NonNull VolumeInfo vol); /** {@hide} */ public abstract @Nullable VolumeInfo getPrimaryStorageCurrentVolume(); /** {@hide} */ @@ -6407,6 +6511,7 @@ public abstract class PackageManager { * @return identity that uniquely identifies current device * @hide */ + @NonNull public abstract VerifierDeviceIdentity getVerifierDeviceIdentity(); /** @@ -6437,8 +6542,8 @@ public abstract class PackageManager { * @hide */ @UnsupportedAppUsage - public abstract void addCrossProfileIntentFilter(IntentFilter filter, int sourceUserId, - int targetUserId, int flags); + public abstract void addCrossProfileIntentFilter(@NonNull IntentFilter filter, + @UserIdInt int sourceUserId, @UserIdInt int targetUserId, int flags); /** * Clearing {@code CrossProfileIntentFilter}s which have the specified user @@ -6448,27 +6553,32 @@ public abstract class PackageManager { * @hide */ @UnsupportedAppUsage - public abstract void clearCrossProfileIntentFilters(int sourceUserId); + public abstract void clearCrossProfileIntentFilters(@UserIdInt int sourceUserId); /** * @hide */ + @NonNull @UnsupportedAppUsage - public abstract Drawable loadItemIcon(PackageItemInfo itemInfo, ApplicationInfo appInfo); + public abstract Drawable loadItemIcon(@NonNull PackageItemInfo itemInfo, + @Nullable ApplicationInfo appInfo); /** * @hide */ + @NonNull @UnsupportedAppUsage - public abstract Drawable loadUnbadgedItemIcon(PackageItemInfo itemInfo, ApplicationInfo appInfo); + public abstract Drawable loadUnbadgedItemIcon(@NonNull PackageItemInfo itemInfo, + @Nullable ApplicationInfo appInfo); /** {@hide} */ @UnsupportedAppUsage - public abstract boolean isPackageAvailable(String packageName); + public abstract boolean isPackageAvailable(@NonNull String packageName); /** {@hide} */ + @NonNull @UnsupportedAppUsage - public static String installStatusToString(int status, String msg) { + public static String installStatusToString(int status, @Nullable String msg) { final String str = installStatusToString(status); if (msg != null) { return str + ": " + msg; @@ -6478,6 +6588,7 @@ public abstract class PackageManager { } /** {@hide} */ + @NonNull @UnsupportedAppUsage public static String installStatusToString(int status) { switch (status) { @@ -6582,7 +6693,8 @@ public abstract class PackageManager { } /** {@hide} */ - public static String deleteStatusToString(int status, String msg) { + @NonNull + public static String deleteStatusToString(int status, @Nullable String msg) { final String str = deleteStatusToString(status); if (msg != null) { return str + ": " + msg; @@ -6592,6 +6704,7 @@ public abstract class PackageManager { } /** {@hide} */ + @NonNull @UnsupportedAppUsage public static String deleteStatusToString(int status) { switch (status) { @@ -6621,6 +6734,7 @@ public abstract class PackageManager { } /** {@hide} */ + @NonNull public static String permissionFlagToString(int flag) { switch (flag) { case FLAG_PERMISSION_GRANTED_BY_DEFAULT: return "GRANTED_BY_DEFAULT"; @@ -6668,8 +6782,8 @@ public abstract class PackageManager { * @hide */ @TestApi - public abstract @InstallReason int getInstallReason(String packageName, - @NonNull UserHandle user); + @InstallReason + public abstract int getInstallReason(@NonNull String packageName, @NonNull UserHandle user); /** * Checks whether the calling package is allowed to request package installs through package @@ -6695,6 +6809,7 @@ public abstract class PackageManager { * @see {@link android.content.Intent#ACTION_INSTANT_APP_RESOLVER_SETTINGS} * @hide */ + @Nullable @SystemApi public abstract ComponentName getInstantAppResolverSettingsComponent(); @@ -6705,6 +6820,7 @@ public abstract class PackageManager { * @see {@link android.content.Intent#ACTION_INSTALL_INSTANT_APP_PACKAGE} * @hide */ + @Nullable @SystemApi public abstract ComponentName getInstantAppInstallerComponent(); @@ -6714,7 +6830,9 @@ public abstract class PackageManager { * @see {@link android.provider.Settings.Secure#ANDROID_ID} * @hide */ - public abstract String getInstantAppAndroidId(String packageName, @NonNull UserHandle user); + @Nullable + public abstract String getInstantAppAndroidId(@NonNull String packageName, + @NonNull UserHandle user); /** * Callback use to notify the callers of module registration that the operation @@ -6757,7 +6875,7 @@ public abstract class PackageManager { * @hide */ @SystemApi - public abstract void registerDexModule(String dexModulePath, + public abstract void registerDexModule(@NonNull String dexModulePath, @Nullable DexModuleRegisterCallback callback); /** @@ -6837,8 +6955,8 @@ public abstract class PackageManager { * @param type representation of the {@code certificate} * @return true if this package was or is signed by exactly the certificate {@code certificate} */ - public boolean hasSigningCertificate( - String packageName, byte[] certificate, @CertificateInputType int type) { + public boolean hasSigningCertificate(@NonNull String packageName, @NonNull byte[] certificate, + @CertificateInputType int type) { throw new UnsupportedOperationException( "hasSigningCertificate not implemented in subclass"); } @@ -6862,7 +6980,7 @@ public abstract class PackageManager { * @return true if this package was or is signed by exactly the certificate {@code certificate} */ public boolean hasSigningCertificate( - int uid, byte[] certificate, @CertificateInputType int type) { + int uid, @NonNull byte[] certificate, @CertificateInputType int type) { throw new UnsupportedOperationException( "hasSigningCertificate not implemented in subclass"); } @@ -6872,16 +6990,28 @@ public abstract class PackageManager { * * @hide */ + @Nullable public String getSystemTextClassifierPackageName() { throw new UnsupportedOperationException( "getSystemTextClassifierPackageName not implemented in subclass"); } /** + * @return attention service package name, or null if there's none. + * + * @hide + */ + public String getAttentionServicePackageName() { + throw new UnsupportedOperationException( + "getAttentionServicePackageName not implemented in subclass"); + } + + /** * @return the wellbeing app package name, or null if it's not defined by the OEM. * * @hide */ + @Nullable @TestApi public String getWellbeingPackageName() { throw new UnsupportedOperationException( @@ -6893,6 +7023,7 @@ public abstract class PackageManager { * * @hide */ + @Nullable public String getAppPredictionServicePackageName() { throw new UnsupportedOperationException( "getAppPredictionServicePackageName not implemented in subclass"); @@ -6903,6 +7034,7 @@ public abstract class PackageManager { * * @hide */ + @Nullable public String getSystemCaptionsServicePackageName() { throw new UnsupportedOperationException( "getSystemCaptionsServicePackageName not implemented in subclass"); @@ -6928,7 +7060,7 @@ public abstract class PackageManager { * * @hide */ - public boolean isPackageStateProtected(String packageName, int userId) { + public boolean isPackageStateProtected(@NonNull String packageName, @UserIdInt int userId) { throw new UnsupportedOperationException( "isPackageStateProtected not implemented in subclass"); } diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java index 35d1eac5c0ad..0a01dcda8bbb 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -3689,6 +3689,12 @@ public class PackageParser { ai.privateFlags |= ApplicationInfo.PRIVATE_FLAG_ALLOW_AUDIO_PLAYBACK_CAPTURE; } + if (sa.getBoolean( + R.styleable.AndroidManifestApplication_allowExternalStorageSandbox, + owner.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.Q)) { + ai.privateFlags |= ApplicationInfo.PRIVATE_FLAG_ALLOW_EXTERNAL_STORAGE_SANDBOX; + } + ai.maxAspectRatio = sa.getFloat(R.styleable.AndroidManifestApplication_maxAspectRatio, 0); ai.minAspectRatio = sa.getFloat(R.styleable.AndroidManifestApplication_minAspectRatio, 0); diff --git a/core/java/android/content/res/AssetManager.java b/core/java/android/content/res/AssetManager.java index 49b4cb01c6a6..514015fe0c86 100644 --- a/core/java/android/content/res/AssetManager.java +++ b/core/java/android/content/res/AssetManager.java @@ -1263,12 +1263,19 @@ public final class AssetManager implements AutoCloseable { */ @UnsupportedAppUsage public boolean isUpToDate() { - for (ApkAssets apkAssets : getApkAssets()) { - if (!apkAssets.isUpToDate()) { + synchronized (this) { + if (!mOpen) { return false; } + + for (ApkAssets apkAssets : mApkAssets) { + if (!apkAssets.isUpToDate()) { + return false; + } + } + + return true; } - return true; } /** diff --git a/core/java/android/database/sqlite/SQLiteQueryBuilder.java b/core/java/android/database/sqlite/SQLiteQueryBuilder.java index bad80b89a6b0..014bc242e17a 100644 --- a/core/java/android/database/sqlite/SQLiteQueryBuilder.java +++ b/core/java/android/database/sqlite/SQLiteQueryBuilder.java @@ -39,6 +39,7 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Objects; import java.util.Set; +import java.util.regex.Matcher; import java.util.regex.Pattern; /** @@ -47,11 +48,15 @@ import java.util.regex.Pattern; */ public class SQLiteQueryBuilder { private static final String TAG = "SQLiteQueryBuilder"; + private static final Pattern sLimitPattern = Pattern.compile("\\s*\\d+\\s*(,\\s*\\d+\\s*)?"); + private static final Pattern sAggregationPattern = Pattern.compile( + "(?i)(AVG|COUNT|MAX|MIN|SUM|TOTAL)\\((.+)\\)"); private Map<String, String> mProjectionMap = null; private List<Pattern> mProjectionGreylist = null; + private boolean mProjectionAggregationAllowed = false; @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private String mTables = ""; @@ -203,6 +208,16 @@ public class SQLiteQueryBuilder { return mProjectionGreylist; } + /** {@hide} */ + public void setProjectionAggregationAllowed(boolean projectionAggregationAllowed) { + mProjectionAggregationAllowed = projectionAggregationAllowed; + } + + /** {@hide} */ + public boolean isProjectionAggregationAllowed() { + return mProjectionAggregationAllowed; + } + /** * Sets the cursor factory to be used for the query. You can use * one factory for all queries on a database but it is normally @@ -842,26 +857,48 @@ public class SQLiteQueryBuilder { return query.toString(); } + private static @NonNull String maybeWithOperator(@Nullable String operator, + @NonNull String column) { + if (operator != null) { + return operator + "(" + column + ")"; + } else { + return column; + } + } + + /** {@hide} */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) - private String[] computeProjection(String[] projectionIn) { + public String[] computeProjection(String[] projectionIn) { if (projectionIn != null && projectionIn.length > 0) { if (mProjectionMap != null) { String[] projection = new String[projectionIn.length]; int length = projectionIn.length; for (int i = 0; i < length; i++) { + String operator = null; String userColumn = projectionIn[i]; String column = mProjectionMap.get(userColumn); + // If aggregation is allowed, extract the underlying column + // that may be aggregated + if (mProjectionAggregationAllowed) { + final Matcher matcher = sAggregationPattern.matcher(userColumn); + if (matcher.matches()) { + operator = matcher.group(1); + userColumn = matcher.group(2); + column = mProjectionMap.get(userColumn); + } + } + if (column != null) { - projection[i] = column; + projection[i] = maybeWithOperator(operator, column); continue; } if (!mStrict && ( userColumn.contains(" AS ") || userColumn.contains(" as "))) { /* A column alias already exist */ - projection[i] = userColumn; + projection[i] = maybeWithOperator(operator, userColumn); continue; } @@ -878,7 +915,7 @@ public class SQLiteQueryBuilder { if (match) { Log.w(TAG, "Allowing abusive custom column: " + userColumn); - projection[i] = userColumn; + projection[i] = maybeWithOperator(operator, userColumn); continue; } } @@ -911,7 +948,8 @@ public class SQLiteQueryBuilder { return null; } - private @Nullable String computeWhere(@Nullable String selection) { + /** {@hide} */ + public @Nullable String computeWhere(@Nullable String selection) { final boolean hasInternal = !TextUtils.isEmpty(mWhereClause); final boolean hasExternal = !TextUtils.isEmpty(selection); diff --git a/core/java/android/net/DnsResolver.java b/core/java/android/net/DnsResolver.java index f9e0af227ac3..06c32c675a31 100644 --- a/core/java/android/net/DnsResolver.java +++ b/core/java/android/net/DnsResolver.java @@ -22,6 +22,10 @@ import static android.net.NetworkUtils.resNetworkResult; import static android.net.NetworkUtils.resNetworkSend; import static android.os.MessageQueue.OnFileDescriptorEventListener.EVENT_ERROR; import static android.os.MessageQueue.OnFileDescriptorEventListener.EVENT_INPUT; +import static android.system.OsConstants.AF_INET; +import static android.system.OsConstants.AF_INET6; +import static android.system.OsConstants.IPPROTO_UDP; +import static android.system.OsConstants.SOCK_DGRAM; import android.annotation.CallbackExecutor; import android.annotation.IntDef; @@ -30,12 +34,18 @@ import android.annotation.Nullable; import android.os.CancellationSignal; import android.os.Looper; import android.system.ErrnoException; +import android.system.Os; import android.util.Log; +import libcore.io.IoUtils; + import java.io.FileDescriptor; +import java.io.IOException; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.SocketAddress; import java.net.UnknownHostException; import java.util.ArrayList; import java.util.List; @@ -52,6 +62,7 @@ public final class DnsResolver { private static final String TAG = "DnsResolver"; private static final int FD_EVENTS = EVENT_INPUT | EVENT_ERROR; private static final int MAXPACKET = 8 * 1024; + private static final int SLEEP_TIME_MS = 2; @IntDef(prefix = { "CLASS_" }, value = { CLASS_IN @@ -188,9 +199,9 @@ public final class DnsResolver { * Send a raw DNS query. * The answer will be provided asynchronously through the provided {@link AnswerCallback}. * - * @param network {@link Network} specifying which network for querying. + * @param network {@link Network} specifying which network to query on. * {@code null} for query on default network. - * @param query blob message + * @param query blob message to query * @param flags flags as a combination of the FLAGS_* constants * @param executor The {@link Executor} that the callback should be executed on. * @param cancellationSignal used by the caller to signal if the query should be @@ -211,21 +222,26 @@ public final class DnsResolver { queryfd = resNetworkSend((network != null ? network.netId : NETID_UNSET), query, query.length, flags); } catch (ErrnoException e) { - callback.onQueryException(e); + executor.execute(() -> { + callback.onQueryException(e); + }); return; } - maybeAddCancellationSignal(cancellationSignal, queryfd, lock); - registerFDListener(executor, queryfd, callback, cancellationSignal, lock); + synchronized (lock) { + registerFDListener(executor, queryfd, callback, cancellationSignal, lock); + if (cancellationSignal == null) return; + addCancellationSignal(cancellationSignal, queryfd, lock); + } } /** * Send a DNS query with the specified name, class and query type. * The answer will be provided asynchronously through the provided {@link AnswerCallback}. * - * @param network {@link Network} specifying which network for querying. + * @param network {@link Network} specifying which network to query on. * {@code null} for query on default network. - * @param domain domain name for querying + * @param domain domain name to query * @param nsClass dns class as one of the CLASS_* constants * @param nsType dns resource record (RR) type as one of the TYPE_* constants * @param flags flags as a combination of the FLAGS_* constants @@ -249,12 +265,152 @@ public final class DnsResolver { queryfd = resNetworkQuery((network != null ? network.netId : NETID_UNSET), domain, nsClass, nsType, flags); } catch (ErrnoException e) { - callback.onQueryException(e); + executor.execute(() -> { + callback.onQueryException(e); + }); return; } + synchronized (lock) { + registerFDListener(executor, queryfd, callback, cancellationSignal, lock); + if (cancellationSignal == null) return; + addCancellationSignal(cancellationSignal, queryfd, lock); + } + } + + private class InetAddressAnswerAccumulator extends InetAddressAnswerCallback { + private final List<InetAddress> mAllAnswers; + private ParseException mParseException; + private ErrnoException mErrnoException; + private final InetAddressAnswerCallback mUserCallback; + private final int mTargetAnswerCount; + private int mReceivedAnswerCount = 0; + + InetAddressAnswerAccumulator(int size, @NonNull InetAddressAnswerCallback callback) { + mTargetAnswerCount = size; + mAllAnswers = new ArrayList<>(); + mUserCallback = callback; + } + + private boolean maybeReportException() { + if (mErrnoException != null) { + mUserCallback.onQueryException(mErrnoException); + return true; + } + if (mParseException != null) { + mUserCallback.onParseException(mParseException); + return true; + } + return false; + } + + private void maybeReportAnswer() { + if (++mReceivedAnswerCount != mTargetAnswerCount) return; + if (mAllAnswers.isEmpty() && maybeReportException()) return; + // TODO: Do RFC6724 sort. + mUserCallback.onAnswer(mAllAnswers); + } + + @Override + public void onAnswer(@NonNull List<InetAddress> answer) { + mAllAnswers.addAll(answer); + maybeReportAnswer(); + } + + @Override + public void onParseException(@NonNull ParseException e) { + mParseException = e; + maybeReportAnswer(); + } - maybeAddCancellationSignal(cancellationSignal, queryfd, lock); - registerFDListener(executor, queryfd, callback, cancellationSignal, lock); + @Override + public void onQueryException(@NonNull ErrnoException e) { + mErrnoException = e; + maybeReportAnswer(); + } + } + + /** + * Send a DNS query with the specified name, get back a set of InetAddresses asynchronously. + * The answer will be provided asynchronously through the provided + * {@link InetAddressAnswerCallback}. + * + * @param network {@link Network} specifying which network to query on. + * {@code null} for query on default network. + * @param domain domain name to query + * @param flags flags as a combination of the FLAGS_* constants + * @param executor The {@link Executor} that the callback should be executed on. + * @param cancellationSignal used by the caller to signal if the query should be + * cancelled. May be {@code null}. + * @param callback an {@link InetAddressAnswerCallback} which will be called to notify the + * caller of the result of dns query. + */ + public void query(@Nullable Network network, @NonNull String domain, @QueryFlag int flags, + @NonNull @CallbackExecutor Executor executor, + @Nullable CancellationSignal cancellationSignal, + @NonNull InetAddressAnswerCallback callback) { + if (cancellationSignal != null && cancellationSignal.isCanceled()) { + return; + } + final Object lock = new Object(); + final boolean queryIpv6 = haveIpv6(network); + final boolean queryIpv4 = haveIpv4(network); + + final FileDescriptor v4fd; + final FileDescriptor v6fd; + + int queryCount = 0; + + if (queryIpv6) { + try { + v6fd = resNetworkQuery((network != null + ? network.netId : NETID_UNSET), domain, CLASS_IN, TYPE_AAAA, flags); + } catch (ErrnoException e) { + executor.execute(() -> { + callback.onQueryException(e); + }); + return; + } + queryCount++; + } else v6fd = null; + + // TODO: Use device flag to control the sleep time. + // Avoiding gateways drop packets if queries are sent too close together + try { + Thread.sleep(SLEEP_TIME_MS); + } catch (InterruptedException ex) { } + + if (queryIpv4) { + try { + v4fd = resNetworkQuery((network != null + ? network.netId : NETID_UNSET), domain, CLASS_IN, TYPE_A, flags); + } catch (ErrnoException e) { + if (queryIpv6) resNetworkCancel(v6fd); // Closes fd, marks it invalid. + executor.execute(() -> { + callback.onQueryException(e); + }); + return; + } + queryCount++; + } else v4fd = null; + + final InetAddressAnswerAccumulator accumulator = + new InetAddressAnswerAccumulator(queryCount, callback); + + synchronized (lock) { + if (queryIpv6) { + registerFDListener(executor, v6fd, accumulator, cancellationSignal, lock); + } + if (queryIpv4) { + registerFDListener(executor, v4fd, accumulator, cancellationSignal, lock); + } + if (cancellationSignal == null) return; + cancellationSignal.setOnCancelListener(() -> { + synchronized (lock) { + if (queryIpv4) cancelQuery(v4fd); + if (queryIpv6) cancelQuery(v6fd); + } + }); + } } private <T> void registerFDListener(@NonNull Executor executor, @@ -271,7 +427,7 @@ public final class DnsResolver { } byte[] answerbuf = null; try { - answerbuf = resNetworkResult(fd); + answerbuf = resNetworkResult(fd); // Closes fd, marks it invalid. } catch (ErrnoException e) { Log.e(TAG, "resNetworkResult:" + e.toString()); answerCallback.onQueryException(e); @@ -291,19 +447,53 @@ public final class DnsResolver { }); } - private void maybeAddCancellationSignal(@Nullable CancellationSignal cancellationSignal, + private void cancelQuery(@NonNull FileDescriptor queryfd) { + if (!queryfd.valid()) return; + Looper.getMainLooper().getQueue().removeOnFileDescriptorEventListener(queryfd); + resNetworkCancel(queryfd); // Closes fd, marks it invalid. + } + + private void addCancellationSignal(@NonNull CancellationSignal cancellationSignal, @NonNull FileDescriptor queryfd, @NonNull Object lock) { - if (cancellationSignal == null) return; cancellationSignal.setOnCancelListener(() -> { synchronized (lock) { - if (!queryfd.valid()) return; - Looper.getMainLooper().getQueue() - .removeOnFileDescriptorEventListener(queryfd); - resNetworkCancel(queryfd); + cancelQuery(queryfd); } }); } + // These two functions match the behaviour of have_ipv4 and have_ipv6 in the native resolver. + private boolean haveIpv4(@Nullable Network network) { + final SocketAddress addrIpv4 = + new InetSocketAddress(InetAddresses.parseNumericAddress("8.8.8.8"), 0); + return checkConnectivity(network, AF_INET, addrIpv4); + } + + private boolean haveIpv6(@Nullable Network network) { + final SocketAddress addrIpv6 = + new InetSocketAddress(InetAddresses.parseNumericAddress("2000::"), 0); + return checkConnectivity(network, AF_INET6, addrIpv6); + } + + private boolean checkConnectivity(@Nullable Network network, + int domain, @NonNull SocketAddress addr) { + final FileDescriptor socket; + try { + socket = Os.socket(domain, SOCK_DGRAM, IPPROTO_UDP); + } catch (ErrnoException e) { + return false; + } + try { + if (network != null) network.bindSocket(socket); + Os.connect(socket, addr); + } catch (IOException | ErrnoException e) { + return false; + } finally { + IoUtils.closeQuietly(socket); + } + return true; + } + private static class DnsAddressAnswer extends DnsPacket { private static final String TAG = "DnsResolver.DnsAddressAnswer"; private static final boolean DBG = false; diff --git a/core/java/android/os/BatterySaverPolicyConfig.java b/core/java/android/os/BatterySaverPolicyConfig.java index bda4e27bf542..879ab1ecb101 100644 --- a/core/java/android/os/BatterySaverPolicyConfig.java +++ b/core/java/android/os/BatterySaverPolicyConfig.java @@ -58,7 +58,8 @@ public final class BatterySaverPolicyConfig implements Parcelable { mAdvertiseIsEnabled = in.mAdvertiseIsEnabled; mDeferFullBackup = in.mDeferFullBackup; mDeferKeyValueBackup = in.mDeferKeyValueBackup; - mDeviceSpecificSettings = Collections.unmodifiableMap(in.mDeviceSpecificSettings); + mDeviceSpecificSettings = Collections.unmodifiableMap( + new ArrayMap<>(in.mDeviceSpecificSettings)); mDisableAnimation = in.mDisableAnimation; mDisableAod = in.mDisableAod; mDisableLaunchBoost = in.mDisableLaunchBoost; diff --git a/core/java/android/os/Environment.java b/core/java/android/os/Environment.java index cceb6edc4c0a..f7e927e48863 100644 --- a/core/java/android/os/Environment.java +++ b/core/java/android/os/Environment.java @@ -20,6 +20,8 @@ import android.annotation.NonNull; import android.annotation.SystemApi; import android.annotation.TestApi; import android.annotation.UnsupportedAppUsage; +import android.app.AppGlobals; +import android.app.AppOpsManager; import android.app.admin.DevicePolicyManager; import android.content.Context; import android.os.storage.StorageManager; @@ -1060,7 +1062,7 @@ public class Environment { * @throws IllegalArgumentException if the path is not a valid storage * device. */ - public static boolean isExternalStorageRemovable(File path) { + public static boolean isExternalStorageRemovable(@NonNull File path) { final StorageVolume volume = StorageManager.getStorageVolume(path, UserHandle.myUserId()); if (volume != null) { return volume.isRemovable(); @@ -1103,7 +1105,7 @@ public class Environment { * @throws IllegalArgumentException if the path is not a valid storage * device. */ - public static boolean isExternalStorageEmulated(File path) { + public static boolean isExternalStorageEmulated(@NonNull File path) { final StorageVolume volume = StorageManager.getStorageVolume(path, UserHandle.myUserId()); if (volume != null) { return volume.isEmulated(); @@ -1112,6 +1114,44 @@ public class Environment { } } + /** + * Returns whether the shared/external storage media at the given path is a + * sandboxed view that only contains files owned by the app. + * <p> + * This value may be different from the value requested by + * {@code allowExternalStorageSandbox} in the app's manifest, since an app + * may inherit its sandboxed state based on when it was first installed. + * <p> + * Sandboxed apps can continue to discover and read media belonging to other + * apps via {@link android.provider.MediaStore}. + */ + public static boolean isExternalStorageSandboxed() { + final File externalDir = sCurrentUser.getExternalDirs()[0]; + return isExternalStorageSandboxed(externalDir); + } + + /** + * Returns whether the shared/external storage media at the given path is a + * sandboxed view that only contains files owned by the app. + * <p> + * This value may be different from the value requested by + * {@code allowExternalStorageSandbox} in the app's manifest, since an app + * may inherit its sandboxed state based on when it was first installed. + * <p> + * Sandboxed apps can continue to discover and read media belonging to other + * apps via {@link android.provider.MediaStore}. + * + * @throws IllegalArgumentException if the path is not a valid storage + * device. + */ + public static boolean isExternalStorageSandboxed(@NonNull File path) { + final Context context = AppGlobals.getInitialApplication(); + final AppOpsManager appOps = context.getSystemService(AppOpsManager.class); + return appOps.noteOpNoThrow(AppOpsManager.OP_LEGACY_STORAGE, + context.getApplicationInfo().uid, + context.getPackageName()) != AppOpsManager.MODE_ALLOWED; + } + static File getDirectory(String variableName, String defaultPath) { String path = System.getenv(variableName); return path == null ? new File(defaultPath) : new File(path); diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java index 64e2f890ee47..7d61bf6f3986 100644 --- a/core/java/android/os/PowerManager.java +++ b/core/java/android/os/PowerManager.java @@ -773,8 +773,10 @@ public final class PowerManager { */ public static final int LOCATION_MODE_THROTTLE_REQUESTS_WHEN_SCREEN_OFF = 4; - static final int MIN_LOCATION_MODE = LOCATION_MODE_NO_CHANGE; - static final int MAX_LOCATION_MODE = LOCATION_MODE_THROTTLE_REQUESTS_WHEN_SCREEN_OFF; + /** @hide */ + public static final int MIN_LOCATION_MODE = LOCATION_MODE_NO_CHANGE; + /** @hide */ + public static final int MAX_LOCATION_MODE = LOCATION_MODE_THROTTLE_REQUESTS_WHEN_SCREEN_OFF; /** * @hide diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 1cab250b7d91..5c2eacc18603 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -14726,7 +14726,6 @@ public final class Settings { * * @hide */ - // TODO(b/117663715): require a new write permission restricted to a single source @RequiresPermission(Manifest.permission.WRITE_DEVICE_CONFIG) static void resetToDefaults(@NonNull ContentResolver resolver, @ResetMode int resetMode, @Nullable String prefix) { diff --git a/core/java/android/view/DisplayCutout.java b/core/java/android/view/DisplayCutout.java index 610f7edef451..715181f28076 100644 --- a/core/java/android/view/DisplayCutout.java +++ b/core/java/android/view/DisplayCutout.java @@ -512,8 +512,8 @@ public final class DisplayCutout { * @hide */ public DisplayCutout inset(int insetLeft, int insetTop, int insetRight, int insetBottom) { - if (isBoundsEmpty() - || insetLeft == 0 && insetTop == 0 && insetRight == 0 && insetBottom == 0) { + if (insetLeft == 0 && insetTop == 0 && insetRight == 0 && insetBottom == 0 + || isBoundsEmpty()) { return this; } @@ -534,6 +534,12 @@ public final class DisplayCutout { safeInsets.right = atLeastZero(safeInsets.right - insetRight); } + // If we are not cutting off part of the cutout by insetting it on bottom/right, and we also + // don't move it around, we can avoid the allocation and copy of the instance. + if (insetLeft == 0 && insetTop == 0 && mSafeInsets.equals(safeInsets)) { + return this; + } + Rect[] bounds = mBounds.getRects(); for (int i = 0; i < bounds.length; ++i) { if (!bounds[i].equals(ZERO_RECT)) { diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 5df990c142c4..24f4c1431214 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -7955,6 +7955,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * View is not a pane. * * {@see AccessibilityNodeInfo#setPaneTitle(CharSequence)} + * + * @attr ref android.R.styleable#View_accessibilityPaneTitle */ public void setAccessibilityPaneTitle(@Nullable CharSequence accessibilityPaneTitle) { if (!TextUtils.equals(accessibilityPaneTitle, mAccessibilityPaneTitle)) { @@ -7970,6 +7972,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @return The current pane title. * * {@see #setAccessibilityPaneTitle}. + * + * @attr ref android.R.styleable#View_accessibilityPaneTitle */ @InspectableProperty @Nullable @@ -12112,6 +12116,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @see #setScreenReaderFocusable(boolean) * * @return Whether the view should be treated as a focusable unit by screen reader. + * + * @attr ref android.R.styleable#View_screenReaderFocusable */ @InspectableProperty public boolean isScreenReaderFocusable() { @@ -12130,6 +12136,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * * @param screenReaderFocusable Whether the view should be treated as a unit by screen reader * accessibility tools. + * + * @attr ref android.R.styleable#View_screenReaderFocusable */ public void setScreenReaderFocusable(boolean screenReaderFocusable) { updatePflags3AndNotifyA11yIfChanged(PFLAG3_SCREEN_READER_FOCUSABLE, screenReaderFocusable); @@ -17960,7 +17968,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, final int scrollX = mScrollX; final int scrollY = mScrollY; invalidateInternal(dirty.left - scrollX, dirty.top - scrollY, - dirty.right - scrollX, dirty.bottom - scrollY, true, false); + dirty.right - scrollX, dirty.bottom - scrollY, true); } /** @@ -17986,7 +17994,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, public void invalidate(int l, int t, int r, int b) { final int scrollX = mScrollX; final int scrollY = mScrollY; - invalidateInternal(l - scrollX, t - scrollY, r - scrollX, b - scrollY, true, false); + invalidateInternal(l - scrollX, t - scrollY, r - scrollX, b - scrollY, true); } /** @@ -18016,11 +18024,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ @UnsupportedAppUsage public void invalidate(boolean invalidateCache) { - invalidateInternal(0, 0, mRight - mLeft, mBottom - mTop, invalidateCache, true); + invalidateInternal(0, 0, mRight - mLeft, mBottom - mTop, invalidateCache); } - void invalidateInternal(int l, int t, int r, int b, boolean invalidateCache, - boolean fullInvalidate) { + void invalidateInternal(int l, int t, int r, int b, boolean invalidateCache) { if (mGhostView != null) { mGhostView.invalidate(true); return; @@ -18037,11 +18044,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback, if ((mPrivateFlags & (PFLAG_DRAWN | PFLAG_HAS_BOUNDS)) == (PFLAG_DRAWN | PFLAG_HAS_BOUNDS) || (invalidateCache && (mPrivateFlags & PFLAG_DRAWING_CACHE_VALID) == PFLAG_DRAWING_CACHE_VALID) || (mPrivateFlags & PFLAG_INVALIDATED) != PFLAG_INVALIDATED - || (fullInvalidate && isOpaque() != mLastIsOpaque)) { - if (fullInvalidate) { - mLastIsOpaque = isOpaque(); - mPrivateFlags &= ~PFLAG_DRAWN; - } + || isOpaque() != mLastIsOpaque) { + mLastIsOpaque = isOpaque(); + mPrivateFlags &= ~PFLAG_DRAWN; mPrivateFlags |= PFLAG_DIRTY; @@ -22586,12 +22591,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, @Override public void invalidateDrawable(@NonNull Drawable drawable) { if (verifyDrawable(drawable)) { - final Rect dirty = drawable.getDirtyBounds(); - final int scrollX = mScrollX; - final int scrollY = mScrollY; - - invalidate(dirty.left + scrollX, dirty.top + scrollY, - dirty.right + scrollX, dirty.bottom + scrollY); + invalidate(); rebuildOutline(); } } diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 5f6033358cc3..49166ade34ce 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -1455,6 +1455,7 @@ public final class ViewRootImpl implements ViewParent, @Override public void onDescendantInvalidated(@NonNull View child, @NonNull View descendant) { + checkThread(); if ((descendant.mPrivateFlags & PFLAG_DRAW_ANIMATION) != 0) { mIsAnimating = true; } diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java index f29174b54383..f14b50dcd04d 100644 --- a/core/java/com/android/internal/app/ChooserActivity.java +++ b/core/java/com/android/internal/app/ChooserActivity.java @@ -1594,7 +1594,7 @@ public class ChooserActivity extends ResolverActivity { if (info == null) return null; // Now fetch app icon and raster with no badging even in work profile - Bitmap appIcon = (new ActivityInfoPresentationGetter(info)).getIconBitmap(); + Bitmap appIcon = makePresentationGetter(info).getIconBitmap(); // Raster target drawable with appIcon as a badge SimpleIconFactory sif = SimpleIconFactory.obtain(ChooserActivity.this); @@ -1865,8 +1865,9 @@ public class ChooserActivity extends ResolverActivity { ri.noResourceId = true; ri.icon = 0; } + ResolveInfoPresentationGetter getter = makePresentationGetter(ri); mCallerTargets.add(new DisplayResolveInfo(ii, ri, - ri.loadLabel(pm), null, ii)); + getter.getLabel(), getter.getSubLabel(), ii)); } } } @@ -1879,12 +1880,6 @@ public class ChooserActivity extends ResolverActivity { } @Override - public boolean showsExtendedInfo(TargetInfo info) { - // We have badges so we don't need this text shown. - return false; - } - - @Override public View onCreateView(ViewGroup parent) { return mInflater.inflate( com.android.internal.R.layout.resolve_grid_item, parent, false); @@ -2301,8 +2296,10 @@ public class ChooserActivity extends ResolverActivity { final int spec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); int columnCount = holder.getColumnCount(); + final boolean isDirectShare = holder instanceof DirectShareViewHolder; + for (int i = 0; i < columnCount; i++) { - final View v = mChooserListAdapter.createView(holder.getRow(i)); + final View v = mChooserListAdapter.createView(holder.getRowByIndex(i)); final int column = i; v.setOnClickListener(new OnClickListener() { @Override @@ -2321,27 +2318,31 @@ public class ChooserActivity extends ResolverActivity { }); ViewGroup row = holder.addView(i, v); + // Force Direct Share to be 2 lines and auto-wrap to second line via hoz scroll = + // false. TextView#setHorizontallyScrolling must be reset after #setLines. Must be + // done before measuring. + if (isDirectShare) { + final ViewHolder vh = (ViewHolder) v.getTag(); + vh.text.setLines(2); + vh.text.setHorizontallyScrolling(false); + vh.text2.setVisibility(View.GONE); + } + // Force height to be a given so we don't have visual disruption during scaling. - LayoutParams lp = v.getLayoutParams(); v.measure(spec, spec); - if (lp == null) { - lp = new LayoutParams(LayoutParams.MATCH_PARENT, v.getMeasuredHeight()); - row.setLayoutParams(lp); - } else { - lp.height = v.getMeasuredHeight(); - } + setViewHeight(v, v.getMeasuredHeight()); } final ViewGroup viewGroup = holder.getViewGroup(); - // Pre-measure so we can scale later. + // Pre-measure and fix height so we can scale later. holder.measure(); - LayoutParams lp = viewGroup.getLayoutParams(); - if (lp == null) { - lp = new LayoutParams(LayoutParams.MATCH_PARENT, holder.getMeasuredRowHeight()); - viewGroup.setLayoutParams(lp); - } else { - lp.height = holder.getMeasuredRowHeight(); + setViewHeight(viewGroup, holder.getMeasuredRowHeight()); + + if (isDirectShare) { + DirectShareViewHolder dsvh = (DirectShareViewHolder) holder; + setViewHeight(dsvh.getRow(0), holder.getMeasuredRowHeight()); + setViewHeight(dsvh.getRow(1), holder.getMeasuredRowHeight()); } viewGroup.setTag(holder); @@ -2349,6 +2350,16 @@ public class ChooserActivity extends ResolverActivity { return holder; } + private void setViewHeight(View view, int heightPx) { + LayoutParams lp = view.getLayoutParams(); + if (lp == null) { + lp = new LayoutParams(LayoutParams.MATCH_PARENT, heightPx); + view.setLayoutParams(lp); + } else { + lp.height = heightPx; + } + } + RowViewHolder createViewHolder(int viewType, ViewGroup parent) { if (viewType == VIEW_TYPE_DIRECT_SHARE) { ViewGroup parentGroup = (ViewGroup) mLayoutInflater.inflate( @@ -2386,7 +2397,7 @@ public class ChooserActivity extends ResolverActivity { if (startType != lastStartType || rowPosition == getContentPreviewRowCount()) { row.setBackground(mChooserRowLayer); - setVertPadding(row, mChooserRowServiceSpacing, 0); + setVertPadding(row, 0, 0); } else { row.setBackground(null); setVertPadding(row, 0, 0); @@ -2483,7 +2494,9 @@ public class ChooserActivity extends ResolverActivity { abstract ViewGroup getViewGroup(); - abstract ViewGroup getRow(int index); + abstract ViewGroup getRowByIndex(int index); + + abstract ViewGroup getRow(int rowNumber); abstract void setViewVisibility(int i, int visibility); @@ -2532,10 +2545,15 @@ public class ChooserActivity extends ResolverActivity { return mRow; } - public ViewGroup getRow(int index) { + public ViewGroup getRowByIndex(int index) { return mRow; } + public ViewGroup getRow(int rowNumber) { + if (rowNumber == 0) return mRow; + return null; + } + public ViewGroup addView(int index, View v) { mRow.addView(v); mCells[index] = v; @@ -2574,7 +2592,7 @@ public class ChooserActivity extends ResolverActivity { } public ViewGroup addView(int index, View v) { - ViewGroup row = getRow(index); + ViewGroup row = getRowByIndex(index); row.addView(v); mCells[index] = v; @@ -2589,10 +2607,14 @@ public class ChooserActivity extends ResolverActivity { return mParent; } - public ViewGroup getRow(int index) { + public ViewGroup getRowByIndex(int index) { return mRows.get(index / mCellCountPerRow); } + public ViewGroup getRow(int rowNumber) { + return mRows.get(rowNumber); + } + public void measure() { final int spec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); getRow(0).measure(spec, spec); diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java index 84a1bed36e55..9f9e083f1fb1 100644 --- a/core/java/com/android/internal/app/ResolverActivity.java +++ b/core/java/com/android/internal/app/ResolverActivity.java @@ -83,7 +83,6 @@ import com.android.internal.widget.ResolverDrawerLayout; import java.util.ArrayList; import java.util.Arrays; -import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Objects; @@ -499,33 +498,40 @@ public class ResolverActivity extends Activity { /** - * Loads the icon for the provided ApplicationInfo. Defaults to using the application icon over - * any IntentFilter or Activity icon to increase user understanding, with an exception for - * applications that hold the right permission. Always attempts to use icon resources over - * PackageManager loading mechanisms so badging can be done by iconloader. + * Loads the icon and label for the provided ApplicationInfo. Defaults to using the application + * icon and label over any IntentFilter or Activity icon to increase user understanding, with an + * exception for applications that hold the right permission. Always attempts to use available + * resources over PackageManager loading mechanisms so badging can be done by iconloader. Uses + * Strings to strip creative formatting. */ - private abstract class TargetPresentationGetter { - @Nullable abstract Drawable getIconSubstitute(); - @Nullable abstract String getAppSubLabel(); + private abstract static class TargetPresentationGetter { + @Nullable abstract Drawable getIconSubstituteInternal(); + @Nullable abstract String getAppSubLabelInternal(); + private Context mCtx; + protected PackageManager mPm; private final ApplicationInfo mAi; + private final int mIconDpi; private final boolean mHasSubstitutePermission; - TargetPresentationGetter(ApplicationInfo ai) { + TargetPresentationGetter(Context ctx, int iconDpi, ApplicationInfo ai) { + mCtx = ctx; + mPm = ctx.getPackageManager(); mAi = ai; + mIconDpi = iconDpi; mHasSubstitutePermission = PackageManager.PERMISSION_GRANTED == mPm.checkPermission( android.Manifest.permission.SUBSTITUTE_SHARE_TARGET_APP_NAME_AND_ICON, mAi.packageName); } - Drawable getIcon() { - return new BitmapDrawable(getResources(), getIconBitmap()); + public Drawable getIcon() { + return new BitmapDrawable(mCtx.getResources(), getIconBitmap()); } - Bitmap getIconBitmap() { + public Bitmap getIconBitmap() { Drawable dr = null; if (mHasSubstitutePermission) { - dr = getIconSubstitute(); + dr = getIconSubstituteInternal(); } if (dr == null) { @@ -542,18 +548,18 @@ public class ResolverActivity extends Activity { dr = mAi.loadIcon(mPm); } - SimpleIconFactory sif = SimpleIconFactory.obtain(ResolverActivity.this); + SimpleIconFactory sif = SimpleIconFactory.obtain(mCtx); Bitmap icon = sif.createUserBadgedIconBitmap(dr, Process.myUserHandle()); sif.recycle(); return icon; } - String getLabel() { + public String getLabel() { String label = null; // Apps with the substitute permission will always show the sublabel as their label if (mHasSubstitutePermission) { - label = getAppSubLabel(); + label = getAppSubLabelInternal(); } if (label == null) { @@ -563,10 +569,14 @@ public class ResolverActivity extends Activity { return label; } - String getSubLabel() { + public String getSubLabel() { // Apps with the substitute permission will never have a sublabel if (mHasSubstitutePermission) return null; - return getAppSubLabel(); + return getAppSubLabelInternal(); + } + + protected String loadLabelFromResource(Resources res, int resId) { + return res.getString(resId); } @Nullable @@ -576,17 +586,19 @@ public class ResolverActivity extends Activity { } - protected class ResolveInfoPresentationGetter extends TargetPresentationGetter { - + /** + * Loads the icon and label for the provided ResolveInfo. + */ + @VisibleForTesting + public static class ResolveInfoPresentationGetter extends TargetPresentationGetter { private final ResolveInfo mRi; - - ResolveInfoPresentationGetter(ResolveInfo ri) { - super(ri.activityInfo.applicationInfo); + public ResolveInfoPresentationGetter(Context ctx, int iconDpi, ResolveInfo ri) { + super(ctx, iconDpi, ri.activityInfo.applicationInfo); mRi = ri; } @Override - Drawable getIconSubstitute() { + Drawable getIconSubstituteInternal() { Drawable dr = null; try { // Do not use ResolveInfo#getIconResource() as it defaults to the app @@ -603,20 +615,31 @@ public class ResolverActivity extends Activity { } @Override - String getAppSubLabel() { + String getAppSubLabelInternal() { + // Will default to app name if no intent filter or activity label set, make sure to + // check if subLabel matches label before final display return (String) mRi.loadLabel(mPm); } } - protected class ActivityInfoPresentationGetter extends TargetPresentationGetter { + ResolveInfoPresentationGetter makePresentationGetter(ResolveInfo ri) { + return new ResolveInfoPresentationGetter(this, mIconDpi, ri); + } + + /** + * Loads the icon and label for the provided ActivityInfo. + */ + @VisibleForTesting + public static class ActivityInfoPresentationGetter extends TargetPresentationGetter { private final ActivityInfo mActivityInfo; - protected ActivityInfoPresentationGetter(ActivityInfo activityInfo) { - super(activityInfo.applicationInfo); + public ActivityInfoPresentationGetter(Context ctx, int iconDpi, + ActivityInfo activityInfo) { + super(ctx, iconDpi, activityInfo.applicationInfo); mActivityInfo = activityInfo; } @Override - Drawable getIconSubstitute() { + Drawable getIconSubstituteInternal() { Drawable dr = null; try { // Do not use ActivityInfo#getIconResource() as it defaults to the app @@ -634,13 +657,19 @@ public class ResolverActivity extends Activity { } @Override - String getAppSubLabel() { + String getAppSubLabelInternal() { + // Will default to app name if no activity label set, make sure to check if subLabel + // matches label before final display return (String) mActivityInfo.loadLabel(mPm); } } + protected ActivityInfoPresentationGetter makePresentationGetter(ActivityInfo ai) { + return new ActivityInfoPresentationGetter(this, mIconDpi, ai); + } + Drawable loadIconForResolveInfo(ResolveInfo ri) { - return (new ResolveInfoPresentationGetter(ri)).getIcon(); + return makePresentationGetter(ri).getIcon(); } @Override @@ -1713,34 +1742,13 @@ public class ResolverActivity extends Activity { } } - // Check for applications with same name and use application name or - // package name if necessary - ResolvedComponentInfo rci0 = sortedComponents.get(0); - ResolveInfo r0 = rci0.getResolveInfoAt(0); - int start = 0; - CharSequence r0Label = r0.loadLabel(mPm); - mHasExtendedInfo = false; - for (int i = 1; i < N; i++) { - if (r0Label == null) { - r0Label = r0.activityInfo.packageName; - } - ResolvedComponentInfo rci = sortedComponents.get(i); - ResolveInfo ri = rci.getResolveInfoAt(0); - CharSequence riLabel = ri.loadLabel(mPm); - if (riLabel == null) { - riLabel = ri.activityInfo.packageName; + for (ResolvedComponentInfo rci : sortedComponents) { + final ResolveInfo ri = rci.getResolveInfoAt(0); + if (ri != null) { + ResolveInfoPresentationGetter pg = makePresentationGetter(ri); + addResolveInfoWithAlternates(rci, pg.getSubLabel(), pg.getLabel()); } - if (riLabel.equals(r0Label)) { - continue; - } - processGroup(sortedComponents, start, (i - 1), rci0, r0Label); - rci0 = rci; - r0 = ri; - r0Label = riLabel; - start = i; } - // Process last group - processGroup(sortedComponents, start, (N - 1), rci0, r0Label); } postListReadyRunnable(); @@ -1782,55 +1790,6 @@ public class ResolverActivity extends Activity { return mFilterLastUsed; } - private void processGroup(List<ResolvedComponentInfo> rList, int start, int end, - ResolvedComponentInfo ro, CharSequence roLabel) { - // Process labels from start to i - int num = end - start+1; - if (num == 1) { - // No duplicate labels. Use label for entry at start - addResolveInfoWithAlternates(ro, null, roLabel); - } else { - mHasExtendedInfo = true; - boolean usePkg = false; - final ApplicationInfo ai = ro.getResolveInfoAt(0).activityInfo.applicationInfo; - final CharSequence startApp = ai.loadLabel(mPm); - if (startApp == null) { - usePkg = true; - } - if (!usePkg) { - // Use HashSet to track duplicates - HashSet<CharSequence> duplicates = - new HashSet<CharSequence>(); - duplicates.add(startApp); - for (int j = start+1; j <= end ; j++) { - ResolveInfo jRi = rList.get(j).getResolveInfoAt(0); - CharSequence jApp = jRi.activityInfo.applicationInfo.loadLabel(mPm); - if ( (jApp == null) || (duplicates.contains(jApp))) { - usePkg = true; - break; - } else { - duplicates.add(jApp); - } - } - // Clear HashSet for later use - duplicates.clear(); - } - for (int k = start; k <= end; k++) { - final ResolvedComponentInfo rci = rList.get(k); - final ResolveInfo add = rci.getResolveInfoAt(0); - final CharSequence extraInfo; - if (usePkg) { - // Use package name for all entries from start to end-1 - extraInfo = add.activityInfo.packageName; - } else { - // Use application name for all entries from start to end-1 - extraInfo = add.activityInfo.applicationInfo.loadLabel(mPm); - } - addResolveInfoWithAlternates(rci, extraInfo, roLabel); - } - } - } - private void addResolveInfoWithAlternates(ResolvedComponentInfo rci, CharSequence extraInfo, CharSequence roLabel) { final int count = rci.getCount(); @@ -1979,31 +1938,32 @@ public class ResolverActivity extends Activity { com.android.internal.R.layout.resolve_list_item, parent, false); } - public boolean showsExtendedInfo(TargetInfo info) { - return !TextUtils.isEmpty(info.getExtendedInfo()); - } - public final void bindView(int position, View view) { onBindView(view, getItem(position)); } - private void onBindView(View view, TargetInfo info) { + protected void onBindView(View view, TargetInfo info) { final ViewHolder holder = (ViewHolder) view.getTag(); if (info == null) { holder.icon.setImageDrawable( getDrawable(R.drawable.resolver_icon_placeholder)); return; } + final CharSequence label = info.getDisplayLabel(); if (!TextUtils.equals(holder.text.getText(), label)) { holder.text.setText(info.getDisplayLabel()); } - if (showsExtendedInfo(info)) { - holder.text2.setVisibility(View.VISIBLE); - holder.text2.setText(info.getExtendedInfo()); - } else { - holder.text2.setVisibility(View.GONE); + + // Always show a subLabel for visual consistency across list items. Show an empty + // subLabel if the subLabel is the same as the label + CharSequence subLabel = info.getExtendedInfo(); + if (TextUtils.equals(label, subLabel)) subLabel = null; + + if (!TextUtils.equals(holder.text2.getText(), subLabel)) { + holder.text2.setText(subLabel); } + if (info instanceof DisplayResolveInfo && !((DisplayResolveInfo) info).hasDisplayIcon()) { new LoadAdapterIconTask((DisplayResolveInfo) info).execute(); diff --git a/core/java/com/android/internal/util/ArrayUtils.java b/core/java/com/android/internal/util/ArrayUtils.java index 3303374fd6c4..e8691fa5e23e 100644 --- a/core/java/com/android/internal/util/ArrayUtils.java +++ b/core/java/com/android/internal/util/ArrayUtils.java @@ -527,6 +527,13 @@ public class ArrayUtils { return (array != null) ? array.clone() : null; } + /** + * Clones an array or returns null if the array is null. + */ + public static @Nullable <T> T[] cloneOrNull(@Nullable T[] array) { + return (array != null) ? array.clone() : null; + } + public static @Nullable <T> ArraySet<T> cloneOrNull(@Nullable ArraySet<T> array) { return (array != null) ? new ArraySet<T>(array) : null; } diff --git a/core/jni/android_content_res_ApkAssets.cpp b/core/jni/android_content_res_ApkAssets.cpp index f40b461a6dfd..bd4862dfb08d 100644 --- a/core/jni/android_content_res_ApkAssets.cpp +++ b/core/jni/android_content_res_ApkAssets.cpp @@ -106,8 +106,7 @@ static jlong NativeGetStringBlock(JNIEnv* /*env*/, jclass /*clazz*/, jlong ptr) static jboolean NativeIsUpToDate(JNIEnv* /*env*/, jclass /*clazz*/, jlong ptr) { const ApkAssets* apk_assets = reinterpret_cast<const ApkAssets*>(ptr); - (void)apk_assets; - return JNI_TRUE; + return apk_assets->IsUpToDate() ? JNI_TRUE : JNI_FALSE; } static jlong NativeOpenXml(JNIEnv* env, jclass /*clazz*/, jlong ptr, jstring file_name) { diff --git a/packages/SystemUI/res/drawable/ic_airplane.xml b/core/res/res/drawable/ic_qs_airplane.xml index 166d415a6dcc..166d415a6dcc 100644 --- a/packages/SystemUI/res/drawable/ic_airplane.xml +++ b/core/res/res/drawable/ic_qs_airplane.xml diff --git a/packages/SystemUI/res/drawable/ic_qs_auto_rotate.xml b/core/res/res/drawable/ic_qs_auto_rotate.xml index 47e1059fab44..47e1059fab44 100644 --- a/packages/SystemUI/res/drawable/ic_qs_auto_rotate.xml +++ b/core/res/res/drawable/ic_qs_auto_rotate.xml diff --git a/core/res/res/drawable/ic_qs_bluetooth.xml b/core/res/res/drawable/ic_qs_bluetooth.xml new file mode 100644 index 000000000000..91fcff0dfab6 --- /dev/null +++ b/core/res/res/drawable/ic_qs_bluetooth.xml @@ -0,0 +1,25 @@ +<!-- + 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.0" + android:viewportHeight="24.0" + android:tint="?android:attr/colorControlNormal"> + <path + android:fillColor="@android:color/white" + android:pathData="M17.71,7.71L12,2h-1v7.59L6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 11,14.41L11,22h1l5.71,-5.71 -4.3,-4.29 4.3,-4.29zM13,5.83l1.88,1.88L13,9.59L13,5.83zM14.88,16.29L13,18.17v-3.76l1.88,1.88z"/> +</vector>
\ No newline at end of file diff --git a/packages/SystemUI/res/drawable/ic_dnd.xml b/core/res/res/drawable/ic_qs_dnd.xml index b361169ce1af..b361169ce1af 100644 --- a/packages/SystemUI/res/drawable/ic_dnd.xml +++ b/core/res/res/drawable/ic_qs_dnd.xml diff --git a/packages/SystemUI/res/drawable/ic_signal_flashlight.xml b/core/res/res/drawable/ic_qs_flashlight.xml index e63595300d5f..e63595300d5f 100644 --- a/packages/SystemUI/res/drawable/ic_signal_flashlight.xml +++ b/core/res/res/drawable/ic_qs_flashlight.xml diff --git a/core/res/res/drawable/ic_settings_bluetooth.xml b/core/res/res/drawable/ic_settings_bluetooth.xml index 6e32e1a7f631..91fcff0dfab6 100644 --- a/core/res/res/drawable/ic_settings_bluetooth.xml +++ b/core/res/res/drawable/ic_settings_bluetooth.xml @@ -14,12 +14,12 @@ limitations under the License. --> <vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24.0dp" - android:height="24.0dp" + 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="M13.5,12l3.8,-3.7c0.4,-0.4 0.4,-1.1 0,-1.5l-4.5,-4.5c-0.4,-0.4 -1.1,-0.4 -1.5,0.1C11.1,2.5 11,2.8 11,3v6.4L6.9,5.4C6.5,5 5.9,5 5.5,5.4s-0.4,1.1 0,1.5l5.1,5.1l-5.1,5.1c-0.4,0.4 -0.4,1.1 0,1.5s1.1,0.4 1.5,0l4.1,-4V21c0,0.6 0.5,1 1,1c0.3,0 0.5,-0.1 0.7,-0.3l0.1,0l4.5,-4.5c0.4,-0.4 0.4,-1.1 0,-1.5L13.5,12zM13,9.7V5.4l2.1,2.2L13,9.7zM13,18.6v-4.3l2.1,2.2L13,18.6z"/> -</vector> + android:fillColor="@android:color/white" + android:pathData="M17.71,7.71L12,2h-1v7.59L6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 11,14.41L11,22h1l5.71,-5.71 -4.3,-4.29 4.3,-4.29zM13,5.83l1.88,1.88L13,9.59L13,5.83zM14.88,16.29L13,18.17v-3.76l1.88,1.88z"/> +</vector>
\ No newline at end of file diff --git a/core/res/res/layout/resolve_grid_item.xml b/core/res/res/layout/resolve_grid_item.xml index 4a3dfba63c6d..7065149e268e 100644 --- a/core/res/res/layout/resolve_grid_item.xml +++ b/core/res/res/layout/resolve_grid_item.xml @@ -22,46 +22,43 @@ android:layout_height="wrap_content" android:minHeight="100dp" android:gravity="center" - android:paddingTop="8dp" + android:paddingTop="24dp" android:paddingBottom="8dp" + android:paddingLeft="2dp" + android:paddingRight="2dp" android:focusable="true" android:background="?attr/selectableItemBackgroundBorderless"> <ImageView android:id="@+id/icon" android:layout_width="@dimen/resolver_icon_size" android:layout_height="@dimen/resolver_icon_size" - android:layout_marginLeft="3dp" - android:layout_marginRight="3dp" - android:layout_marginBottom="3dp" android:scaleType="fitCenter" /> - <!-- Activity name --> + <!-- Size manually tuned to match specs --> + <Space android:layout_width="1dp" + android:layout_height="7dp"/> + + <!-- App name or Direct Share target name, DS set to 2 lines --> <TextView android:id="@android:id/text1" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginTop="4dp" - android:layout_marginLeft="4dp" - android:layout_marginRight="4dp" android:textAppearance="?attr/textAppearanceSmall" android:textColor="?attr/textColorPrimary" - android:textSize="12sp" + android:textSize="14sp" android:fontFamily="sans-serif-condensed" android:gravity="top|center_horizontal" - android:minLines="2" - android:maxLines="2" - android:ellipsize="marquee" /> - <!-- Extended activity info to distinguish between duplicate activity names --> + android:lines="1" + android:ellipsize="end" /> + + <!-- Activity name if set, gone for Direct Share targets --> <TextView android:id="@android:id/text2" android:textAppearance="?android:attr/textAppearanceSmall" android:textSize="12sp" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginLeft="4dp" - android:layout_marginRight="4dp" - android:minLines="2" - android:maxLines="2" + android:lines="1" android:gravity="top|center_horizontal" - android:ellipsize="marquee" - android:visibility="gone" /> + android:ellipsize="end"/> + </LinearLayout> diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml index 362d01c30487..8f3f25aad182 100644 --- a/core/res/res/values/attrs_manifest.xml +++ b/core/res/res/values/attrs_manifest.xml @@ -1687,6 +1687,17 @@ - {@code false} for apps with targetSdkVersion < 29. --> <attr name="allowAudioPlaybackCapture" format="boolean" /> + <!-- If {@code true} this app allows shared/external storage media to be + a sandboxed view that only contains files owned by the app. + <p> + Sandboxed apps can continue to discover and read media belonging to other + apps via {@code MediaStore}. + <p> + The default value is: + - {@code true} for apps with targetSdkVersion >= 29 (Q). + - {@code false} for apps with targetSdkVersion < 29. + --> + <attr name="allowExternalStorageSandbox" format="boolean" /> </declare-styleable> <!-- The <code>permission</code> tag declares a security permission that can be used to control access from other packages to specific components or diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index 3505994060d8..3bbc03f17efc 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -2942,6 +2942,7 @@ <public name="allowClearUserDataOnFailedRestore"/> <public name="allowAudioPlaybackCapture"/> <public name="secureElementName" /> + <public name="allowExternalStorageSandbox"/> </public-group> <public-group type="drawable" first-id="0x010800b4"> diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index 45494a08f7d3..03259ed2c0c6 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -1582,25 +1582,25 @@ </string-array> <!-- Error message shown when the face hardware can't be accessed. [CHAR LIMIT=50] --> - <string name="face_error_hw_not_available">Face hardware not available.</string> + <string name="face_error_hw_not_available">Can\u2019t verify face. Hardware not available.</string> <!-- Error message shown when the face hardware timer has expired and the user needs to restart the operation. [CHAR LIMIT=50] --> <string name="face_error_timeout">Face timeout reached. Try again.</string> - <!-- Error message shown when the face hardware has run out of room for storing faces. [CHAR LIMIT=50] --> - <string name="face_error_no_space">Face can\u2019t be stored.</string> + <!-- Error message shown when the face hardware has run out of room for storing faces. [CHAR LIMIT=60] --> + <string name="face_error_no_space">Can\u2019t store new face data. Delete an old one first.</string> <!-- Generic error message shown when the face operation (e.g. enrollment or authentication) is canceled. Generally not shown to the user. [CHAR LIMIT=50] --> - <string name="face_error_canceled">Face operation canceled.</string> + <string name="face_error_canceled">Face operation canceled</string> <!-- Generic error message shown when the face authentication operation is canceled due to user input. Generally not shown to the user [CHAR LIMIT=50] --> - <string name="face_error_user_canceled">Face authentication canceled by user.</string> + <string name="face_error_user_canceled">Face authentication canceled by user</string> <!-- Generic error message shown when the face operation fails because too many attempts have been made. [CHAR LIMIT=50] --> <string name="face_error_lockout">Too many attempts. Try again later.</string> - <!-- Generic error message shown when the face operation fails because strong authentication is required. [CHAR LIMIT=50] --> - <string name="face_error_lockout_permanent">Too many attempts. Facial authentication disabled.</string> + <!-- Generic error message shown when the face operation fails because strong authentication is required. [CHAR LIMIT=60] --> + <string name="face_error_lockout_permanent">Too many attempts. Face authentication disabled.</string> <!-- Generic error message shown when the face hardware can't recognize the face. [CHAR LIMIT=50] --> <string name="face_error_unable_to_process">Can\u2019t verify face. Try again.</string> <!-- Generic error message shown when the user has no enrolled face. [CHAR LIMIT=50] --> - <string name="face_error_not_enrolled">You haven\u2019t set up face authentication.</string> + <string name="face_error_not_enrolled">You haven\u2019t set up face authentication</string> <!-- Generic error message shown when the app requests face authentication on a device without a sensor. [CHAR LIMIT=60] --> - <string name="face_error_hw_not_present">Face authentication is not supported on this device.</string> + <string name="face_error_hw_not_present">Face authentication is not supported on this device</string> <!-- Template to be used to name enrolled faces by default. [CHAR LIMIT=10] --> <string name="face_name_template">Face <xliff:g id="faceId" example="1">%d</xliff:g></string> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 7a473d244492..35fd88e64d5b 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -1443,6 +1443,11 @@ <java-symbol type="drawable" name="ic_instant_icon_badge_bolt" /> <java-symbol type="drawable" name="emulator_circular_window_overlay" /> <java-symbol type="drawable" name="ic_qs_battery_saver" /> + <java-symbol type="drawable" name="ic_qs_bluetooth" /> + <java-symbol type="drawable" name="ic_qs_airplane" /> + <java-symbol type="drawable" name="ic_qs_flashlight" /> + <java-symbol type="drawable" name="ic_qs_auto_rotate" /> + <java-symbol type="drawable" name="ic_qs_dnd" /> <java-symbol type="drawable" name="sim_light_blue" /> <java-symbol type="drawable" name="sim_light_green" /> diff --git a/core/tests/coretests/src/com/android/internal/app/ResolverActivityTest.java b/core/tests/coretests/src/com/android/internal/app/ResolverActivityTest.java index 7430c7ab23fc..453bddd9e962 100644 --- a/core/tests/coretests/src/com/android/internal/app/ResolverActivityTest.java +++ b/core/tests/coretests/src/com/android/internal/app/ResolverActivityTest.java @@ -23,6 +23,7 @@ import static androidx.test.espresso.matcher.ViewMatchers.isEnabled; import static androidx.test.espresso.matcher.ViewMatchers.withId; import static androidx.test.espresso.matcher.ViewMatchers.withText; +import static com.android.internal.app.ResolverDataProvider.createPackageManagerMockedInfo; import static com.android.internal.app.ResolverWrapperActivity.sOverrides; import static org.hamcrest.CoreMatchers.is; @@ -32,6 +33,7 @@ import static org.mockito.Mockito.when; import android.content.Intent; import android.content.pm.ResolveInfo; +import android.text.TextUtils; import android.view.View; import android.widget.RelativeLayout; @@ -40,7 +42,10 @@ import androidx.test.rule.ActivityTestRule; import androidx.test.runner.AndroidJUnit4; import com.android.internal.R; +import com.android.internal.app.ResolverActivity.ActivityInfoPresentationGetter; +import com.android.internal.app.ResolverActivity.ResolveInfoPresentationGetter; import com.android.internal.app.ResolverActivity.ResolvedComponentInfo; +import com.android.internal.app.ResolverDataProvider.PackageManagerMockedInfo; import com.android.internal.widget.ResolverDrawerLayout; import org.junit.Before; @@ -319,6 +324,50 @@ public class ResolverActivityTest { assertThat(chosen[0], is(toChoose)); } + @Test + public void getActivityLabelAndSubLabel() throws Exception { + ActivityInfoPresentationGetter pg; + PackageManagerMockedInfo info; + + info = createPackageManagerMockedInfo(false); + pg = new ActivityInfoPresentationGetter( + info.ctx, 0, info.activityInfo); + assertThat("Label should match app label", pg.getLabel().equals( + info.setAppLabel)); + assertThat("Sublabel should match activity label if set", + pg.getSubLabel().equals(info.setActivityLabel)); + + info = createPackageManagerMockedInfo(true); + pg = new ActivityInfoPresentationGetter( + info.ctx, 0, info.activityInfo); + assertThat("With override permission label should match activity label if set", + pg.getLabel().equals(info.setActivityLabel)); + assertThat("With override permission sublabel should be empty", + TextUtils.isEmpty(pg.getSubLabel())); + } + + @Test + public void getResolveInfoLabelAndSubLabel() throws Exception { + ResolveInfoPresentationGetter pg; + PackageManagerMockedInfo info; + + info = createPackageManagerMockedInfo(false); + pg = new ResolveInfoPresentationGetter( + info.ctx, 0, info.resolveInfo); + assertThat("Label should match app label", pg.getLabel().equals( + info.setAppLabel)); + assertThat("Sublabel should match resolve info label if set", + pg.getSubLabel().equals(info.setResolveInfoLabel)); + + info = createPackageManagerMockedInfo(true); + pg = new ResolveInfoPresentationGetter( + info.ctx, 0, info.resolveInfo); + assertThat("With override permission label should match resolve info label if set", + pg.getLabel().equals(info.setResolveInfoLabel)); + assertThat("With override permission sublabel should be empty", + TextUtils.isEmpty(pg.getSubLabel())); + } + private Intent createSendImageIntent() { Intent sendIntent = new Intent(); sendIntent.setAction(Intent.ACTION_SEND); diff --git a/core/tests/coretests/src/com/android/internal/app/ResolverDataProvider.java b/core/tests/coretests/src/com/android/internal/app/ResolverDataProvider.java index 850b466ec755..59634f6d261c 100644 --- a/core/tests/coretests/src/com/android/internal/app/ResolverDataProvider.java +++ b/core/tests/coretests/src/com/android/internal/app/ResolverDataProvider.java @@ -17,11 +17,17 @@ package com.android.internal.app; import android.content.ComponentName; +import android.content.Context; import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; +import android.content.res.Resources; import android.os.UserHandle; +import android.test.mock.MockContext; +import android.test.mock.MockPackageManager; +import android.test.mock.MockResources; /** * Utility class used by resolver tests to create mock data @@ -71,6 +77,86 @@ class ResolverDataProvider { return ai; } + static class PackageManagerMockedInfo { + public Context ctx; + public ApplicationInfo appInfo; + public ActivityInfo activityInfo; + public ResolveInfo resolveInfo; + public String setAppLabel; + public String setActivityLabel; + public String setResolveInfoLabel; + } + + static PackageManagerMockedInfo createPackageManagerMockedInfo(boolean hasOverridePermission) { + final String appLabel = "app_label"; + final String activityLabel = "activity_label"; + final String resolveInfoLabel = "resolve_info_label"; + + MockContext ctx = new MockContext() { + @Override + public PackageManager getPackageManager() { + return new MockPackageManager() { + @Override + public int checkPermission(String permName, String pkgName) { + if (hasOverridePermission) return PERMISSION_GRANTED; + return PERMISSION_DENIED; + } + }; + } + + @Override + public Resources getResources() { + return new MockResources() { + @Override + public String getString(int id) throws NotFoundException { + if (id == 1) return appLabel; + if (id == 2) return activityLabel; + if (id == 3) return resolveInfoLabel; + return null; + } + }; + } + }; + + ApplicationInfo appInfo = new ApplicationInfo() { + @Override + public CharSequence loadLabel(PackageManager pm) { + return appLabel; + } + }; + appInfo.labelRes = 1; + + ActivityInfo activityInfo = new ActivityInfo() { + @Override + public CharSequence loadLabel(PackageManager pm) { + return activityLabel; + } + }; + activityInfo.labelRes = 2; + activityInfo.applicationInfo = appInfo; + + ResolveInfo resolveInfo = new ResolveInfo() { + @Override + public CharSequence loadLabel(PackageManager pm) { + return resolveInfoLabel; + } + }; + resolveInfo.activityInfo = activityInfo; + resolveInfo.resolvePackageName = "super.fake.packagename"; + resolveInfo.labelRes = 3; + + PackageManagerMockedInfo mockedInfo = new PackageManagerMockedInfo(); + mockedInfo.activityInfo = activityInfo; + mockedInfo.appInfo = appInfo; + mockedInfo.ctx = ctx; + mockedInfo.resolveInfo = resolveInfo; + mockedInfo.setAppLabel = appLabel; + mockedInfo.setActivityLabel = activityLabel; + mockedInfo.setResolveInfoLabel = resolveInfoLabel; + + return mockedInfo; + } + static Intent createResolverIntent(int i) { return new Intent("intentAction" + i); } diff --git a/libs/androidfw/ApkAssets.cpp b/libs/androidfw/ApkAssets.cpp index 66a547723b2f..7b7599ff74ec 100644 --- a/libs/androidfw/ApkAssets.cpp +++ b/libs/androidfw/ApkAssets.cpp @@ -29,6 +29,7 @@ #include "androidfw/Asset.h" #include "androidfw/Idmap.h" +#include "androidfw/misc.h" #include "androidfw/ResourceTypes.h" #include "androidfw/Util.h" @@ -39,8 +40,10 @@ using base::unique_fd; static const std::string kResourcesArsc("resources.arsc"); -ApkAssets::ApkAssets(ZipArchiveHandle unmanaged_handle, const std::string& path) - : zip_handle_(unmanaged_handle, ::CloseArchive), path_(path) { +ApkAssets::ApkAssets(ZipArchiveHandle unmanaged_handle, + const std::string& path, + time_t last_mod_time) + : zip_handle_(unmanaged_handle, ::CloseArchive), path_(path), last_mod_time_(last_mod_time) { } std::unique_ptr<const ApkAssets> ApkAssets::Load(const std::string& path, bool system) { @@ -116,8 +119,10 @@ std::unique_ptr<const ApkAssets> ApkAssets::LoadImpl( return {}; } + time_t last_mod_time = getFileModDate(path.c_str()); + // Wrap the handle in a unique_ptr so it gets automatically closed. - std::unique_ptr<ApkAssets> loaded_apk(new ApkAssets(unmanaged_handle, path)); + std::unique_ptr<ApkAssets> loaded_apk(new ApkAssets(unmanaged_handle, path, last_mod_time)); // Find the resource table. ::ZipString entry_name(kResourcesArsc.c_str()); @@ -248,4 +253,8 @@ bool ApkAssets::ForEachFile(const std::string& root_path, return result == -1; } +bool ApkAssets::IsUpToDate() const { + return last_mod_time_ == getFileModDate(path_.c_str()); +} + } // namespace android diff --git a/libs/androidfw/include/androidfw/ApkAssets.h b/libs/androidfw/include/androidfw/ApkAssets.h index 35bbb5804df4..49fc82bff11e 100644 --- a/libs/androidfw/include/androidfw/ApkAssets.h +++ b/libs/androidfw/include/androidfw/ApkAssets.h @@ -84,6 +84,8 @@ class ApkAssets { return idmap_asset_.get() != nullptr; } + bool IsUpToDate() const; + private: DISALLOW_COPY_AND_ASSIGN(ApkAssets); @@ -95,12 +97,13 @@ class ApkAssets { // Creates an Asset from any file on the file system. static std::unique_ptr<Asset> CreateAssetFromFile(const std::string& path); - ApkAssets(ZipArchiveHandle unmanaged_handle, const std::string& path); + ApkAssets(ZipArchiveHandle unmanaged_handle, const std::string& path, time_t last_mod_time); using ZipArchivePtr = std::unique_ptr<ZipArchive, void(*)(ZipArchiveHandle)>; ZipArchivePtr zip_handle_; const std::string path_; + time_t last_mod_time_; std::unique_ptr<Asset> resources_asset_; std::unique_ptr<Asset> idmap_asset_; std::unique_ptr<const LoadedArsc> loaded_arsc_; diff --git a/libs/hwui/Readback.cpp b/libs/hwui/Readback.cpp index fb60a966c48f..89a9b997af97 100644 --- a/libs/hwui/Readback.cpp +++ b/libs/hwui/Readback.cpp @@ -84,6 +84,7 @@ CopyResult Readback::copyHWBitmapInto(Bitmap* hwBitmap, SkBitmap* bitmap) { } CopyResult Readback::copyLayerInto(DeferredLayerUpdater* deferredLayer, SkBitmap* bitmap) { + ATRACE_CALL(); if (!mRenderThread.getGrContext()) { return CopyResult::UnknownError; } @@ -104,6 +105,7 @@ CopyResult Readback::copyLayerInto(DeferredLayerUpdater* deferredLayer, SkBitmap CopyResult Readback::copyImageInto(const sk_sp<SkImage>& image, Matrix4& texTransform, const Rect& srcRect, SkBitmap* bitmap) { + ATRACE_CALL(); if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaGL) { mRenderThread.requireGlContext(); } else { diff --git a/libs/hwui/pipeline/skia/VkFunctorDrawable.cpp b/libs/hwui/pipeline/skia/VkFunctorDrawable.cpp index ceab407cb939..1b9e53b21adb 100644 --- a/libs/hwui/pipeline/skia/VkFunctorDrawable.cpp +++ b/libs/hwui/pipeline/skia/VkFunctorDrawable.cpp @@ -19,6 +19,7 @@ #include "renderthread/VulkanManager.h" #include "renderthread/RenderThread.h" +#include <SkAndroidFrameworkUtils.h> #include <GrBackendDrawableInfo.h> #include <SkImage.h> #include <utils/Color.h> @@ -89,9 +90,29 @@ void VkFunctorDrawHandler::draw(const GrBackendDrawableInfo& info) { VkFunctorDrawable::~VkFunctorDrawable() { } -void VkFunctorDrawable::onDraw(SkCanvas* /*canvas*/) { - LOG_ALWAYS_FATAL("VkFunctorDrawable::onDraw() should never be called."); - // Instead of calling onDraw(), the call should come from onSnapGpuDrawHandler. +void VkFunctorDrawable::onDraw(SkCanvas* canvas) { + // "canvas" is either SkNWayCanvas created by SkiaPipeline::tryCapture (SKP capture use case) or + // AlphaFilterCanvas (used by RenderNodeDrawable to apply alpha in certain cases). + // "VkFunctorDrawable::onDraw" is not invoked for the most common case, when drawing in a GPU + // canvas. + + if (canvas->getGrContext() == nullptr) { + // We're dumping a picture, render a light-blue rectangle instead + SkPaint paint; + paint.setColor(0xFF81D4FA); + canvas->drawRect(mBounds, paint); + } else { + // Handle the case when "canvas" is AlphaFilterCanvas. Find the wrapped GPU canvas. + SkCanvas* gpuCanvas = SkAndroidFrameworkUtils::getBaseWrappedCanvas(canvas); + // Enforce "canvas" must be an AlphaFilterCanvas. For GPU canvas, the call should come from + // onSnapGpuDrawHandler. + LOG_ALWAYS_FATAL_IF( + gpuCanvas == canvas, + "VkFunctorDrawable::onDraw() should not be called with a GPU canvas!"); + + // This will invoke onSnapGpuDrawHandler and regular draw flow. + gpuCanvas->drawDrawable(this); + } } std::unique_ptr<FunctorDrawable::GpuDrawHandler> VkFunctorDrawable::onSnapGpuDrawHandler( diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp index 1bcb819509af..16240b4e177b 100644 --- a/libs/hwui/renderthread/RenderProxy.cpp +++ b/libs/hwui/renderthread/RenderProxy.cpp @@ -162,6 +162,7 @@ void RenderProxy::buildLayer(RenderNode* node) { } bool RenderProxy::copyLayerInto(DeferredLayerUpdater* layer, SkBitmap& bitmap) { + ATRACE_NAME("TextureView#getBitmap"); auto& thread = RenderThread::getInstance(); return thread.queue().runSync([&]() -> bool { return thread.readback().copyLayerInto(layer, &bitmap) == CopyResult::Success; @@ -347,6 +348,7 @@ void RenderProxy::prepareToDraw(Bitmap& bitmap) { } int RenderProxy::copyHWBitmapInto(Bitmap* hwBitmap, SkBitmap* bitmap) { + ATRACE_NAME("HardwareBitmap readback"); RenderThread& thread = RenderThread::getInstance(); if (gettid() == thread.getTid()) { // TODO: fix everything that hits this. We should never be triggering a readback ourselves. diff --git a/libs/hwui/renderthread/VulkanSurface.cpp b/libs/hwui/renderthread/VulkanSurface.cpp index 1708d3c0e093..3fed6b09ede2 100644 --- a/libs/hwui/renderthread/VulkanSurface.cpp +++ b/libs/hwui/renderthread/VulkanSurface.cpp @@ -222,7 +222,17 @@ VulkanSurface* VulkanSurface::Create(ANativeWindow* window, ColorMode colorMode, const SkISize maxSize = SkISize::Make(caps.maxImageExtent.width, caps.maxImageExtent.height); ComputeWindowSizeAndTransform(&windowInfo, minSize, maxSize); - windowInfo.bufferCount = std::max<uint32_t>(VulkanSurface::sMaxBufferCount, caps.minImageCount); + int query_value; + int err = window->query(window, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &query_value); + if (err != 0 || query_value < 0) { + ALOGE("window->query failed: %s (%d) value=%d", strerror(-err), err, + query_value); + return nullptr; + } + auto min_undequeued_buffers = static_cast<uint32_t>(query_value); + + windowInfo.bufferCount = min_undequeued_buffers + + std::max(VulkanSurface::sTargetBufferCount, caps.minImageCount); if (caps.maxImageCount > 0 && windowInfo.bufferCount > caps.maxImageCount) { // Application must settle for fewer images than desired: windowInfo.bufferCount = caps.maxImageCount; @@ -357,10 +367,9 @@ bool VulkanSurface::UpdateWindow(ANativeWindow* window, const WindowInfo& window return false; } - // Lower layer insists that we have at least two buffers. - err = native_window_set_buffer_count(window, std::max(2, windowInfo.bufferCount)); + err = native_window_set_buffer_count(window, windowInfo.bufferCount); if (err != 0) { - ALOGE("VulkanSurface::UpdateWindow() native_window_set_buffer_count(%d) failed: %s (%d)", + ALOGE("VulkanSurface::UpdateWindow() native_window_set_buffer_count(%zu) failed: %s (%d)", windowInfo.bufferCount, strerror(-err), err); return false; } @@ -392,7 +401,7 @@ VulkanSurface::~VulkanSurface() { } void VulkanSurface::releaseBuffers() { - for (uint32_t i = 0; i < VulkanSurface::sMaxBufferCount; i++) { + for (uint32_t i = 0; i < mWindowInfo.bufferCount; i++) { VulkanSurface::NativeBufferInfo& bufferInfo = mNativeBuffers[i]; if (bufferInfo.buffer.get() != nullptr && bufferInfo.dequeued) { diff --git a/libs/hwui/renderthread/VulkanSurface.h b/libs/hwui/renderthread/VulkanSurface.h index 418d40f8c056..305483fce2d5 100644 --- a/libs/hwui/renderthread/VulkanSurface.h +++ b/libs/hwui/renderthread/VulkanSurface.h @@ -83,14 +83,19 @@ private: * as private to this class. * */ - static constexpr int sMaxBufferCount = 3; + + // How many buffers we want to be able to use ourselves. We want 1 in active rendering with + // 1 more queued, so 2. This will be added to NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, which is + // how many buffers the consumer needs (eg, 1 for SurfaceFlinger), getting to a typically + // triple-buffered queue as a result. + static constexpr uint32_t sTargetBufferCount = 2; struct WindowInfo { SkISize size; PixelFormat pixelFormat; android_dataspace dataspace; int transform; - int bufferCount; + size_t bufferCount; uint64_t windowUsageFlags; // size of the ANativeWindow if the inverse of transform requires us to swap width/height @@ -111,7 +116,8 @@ private: const SkISize& maxSize); void releaseBuffers(); - NativeBufferInfo mNativeBuffers[VulkanSurface::sMaxBufferCount]; + // TODO: Just use a vector? + NativeBufferInfo mNativeBuffers[android::BufferQueueDefs::NUM_BUFFER_SLOTS]; sp<ANativeWindow> mNativeWindow; WindowInfo mWindowInfo; diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockPlugin.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockPlugin.java index 7b7657a3d646..105be46c05d7 100644 --- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockPlugin.java +++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockPlugin.java @@ -28,7 +28,7 @@ import java.util.TimeZone; public interface ClockPlugin extends Plugin { String ACTION = "com.android.systemui.action.PLUGIN_CLOCK"; - int VERSION = 2; + int VERSION = 3; /** * Get the name of the clock face. @@ -48,6 +48,17 @@ public interface ClockPlugin extends Plugin { Bitmap getThumbnail(); /** + * Get preview images of clock face to be shown in the picker app. + * + * Preview image should be realistic and show what the clock face will look like on AOD and lock + * screen. + * + * @param width width of the preview image, should be the same as device width in pixels. + * @param height height of the preview image, should be the same as device height in pixels. + */ + Bitmap getPreview(int width, int height); + + /** * Get clock view. * @return clock view from plugin. */ diff --git a/packages/SystemUI/res/drawable/ic_qs_branded_vpn.xml b/packages/SystemUI/res/drawable/ic_qs_branded_vpn.xml deleted file mode 100644 index b20e1582698c..000000000000 --- a/packages/SystemUI/res/drawable/ic_qs_branded_vpn.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:width="12.0dp" - android:height="12.0dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - <path - android:fillColor="#4DFFFFFF" - 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="#4DFFFFFF" - 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/ic_qs_vpn.xml b/packages/SystemUI/res/drawable/ic_qs_vpn.xml deleted file mode 100644 index 6567d123f5d5..000000000000 --- a/packages/SystemUI/res/drawable/ic_qs_vpn.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="12.0dp" - android:height="12.0dp" - 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_airplane_mode.xml b/packages/SystemUI/res/drawable/stat_sys_airplane_mode.xml index 9577b0b2ef89..0f8c57183950 100644 --- a/packages/SystemUI/res/drawable/stat_sys_airplane_mode.xml +++ b/packages/SystemUI/res/drawable/stat_sys_airplane_mode.xml @@ -17,4 +17,4 @@ */ --> <inset xmlns:android="http://schemas.android.com/apk/res/android" - android:drawable="@drawable/ic_airplane" /> + android:drawable="@*android:drawable/ic_qs_airplane" /> diff --git a/packages/SystemUI/res/drawable/stat_sys_branded_vpn.xml b/packages/SystemUI/res/drawable/stat_sys_branded_vpn.xml index bfae8575cd14..5913cdf4a073 100644 --- a/packages/SystemUI/res/drawable/stat_sys_branded_vpn.xml +++ b/packages/SystemUI/res/drawable/stat_sys_branded_vpn.xml @@ -13,6 +13,7 @@ See the License for the specific language governing permissions and limitations under the License. --> +<!-- This icon is statically overlayed - do not remove.--> <vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="17.0dp" android:height="17.0dp" diff --git a/packages/SystemUI/res/drawable/stat_sys_dnd.xml b/packages/SystemUI/res/drawable/stat_sys_dnd.xml index a22d2360b3e5..aa352b42cf04 100644 --- a/packages/SystemUI/res/drawable/stat_sys_dnd.xml +++ b/packages/SystemUI/res/drawable/stat_sys_dnd.xml @@ -19,4 +19,4 @@ <inset xmlns:android="http://schemas.android.com/apk/res/android" android:insetLeft="2.5dp" android:insetRight="2.5dp" - android:drawable="@drawable/ic_dnd" />
\ No newline at end of file + android:drawable="@*android:drawable/ic_qs_dnd" />
\ No newline at end of file diff --git a/packages/SystemUI/res/layout-land/volume_dialog.xml b/packages/SystemUI/res/layout-land/volume_dialog.xml index 9acfbafa3c0b..c420117073c5 100644 --- a/packages/SystemUI/res/layout-land/volume_dialog.xml +++ b/packages/SystemUI/res/layout-land/volume_dialog.xml @@ -54,6 +54,8 @@ android:background="@drawable/rounded_ripple" android:layout_width="match_parent" android:layout_height="match_parent" + android:scaleType="fitCenter" + android:padding="@dimen/volume_dialog_ringer_icon_padding" android:tint="@color/accent_tint_color_selector" android:layout_gravity="center" android:soundEffectsEnabled="false" /> diff --git a/packages/SystemUI/res/layout/ongoing_privacy_dialog_content.xml b/packages/SystemUI/res/layout/ongoing_privacy_dialog_content.xml deleted file mode 100644 index 665fc3fbf3da..000000000000 --- a/packages/SystemUI/res/layout/ongoing_privacy_dialog_content.xml +++ /dev/null @@ -1,61 +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. ---> - -<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" - android:id="@+id/container" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:fillViewport ="true" - android:orientation="vertical"> - - <LinearLayout - android:id="@+id/dialog_container" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:orientation="vertical" > - <TextView - android:id="@+id/title" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:gravity="center" - android:textDirection="locale" - android:textAppearance="@style/TextAppearance.AppOpsDialog.Title" - android:textColor="@*android:color/text_color_primary" - android:layout_marginStart="@dimen/ongoing_appops_dialog_title_margin_sides" - android:layout_marginEnd="@dimen/ongoing_appops_dialog_title_margin_sides" - android:layout_marginBottom="@dimen/ongoing_appops_dialog_title_margin_top_bottom" - android:layout_marginTop="@dimen/ongoing_appops_dialog_title_margin_top_bottom" - /> - - <LinearLayout - android:orientation="vertical" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_marginBottom="@dimen/ongoing_appops_dialog_items_bottom_margin" > - - <LinearLayout - android:id="@+id/items_container" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:orientation="vertical" - android:gravity="start" - /> - </LinearLayout> - - </LinearLayout> - -</ScrollView>
\ No newline at end of file diff --git a/packages/SystemUI/res/layout/ongoing_privacy_dialog_item.xml b/packages/SystemUI/res/layout/ongoing_privacy_dialog_item.xml deleted file mode 100644 index c8e0845a9144..000000000000 --- a/packages/SystemUI/res/layout/ongoing_privacy_dialog_item.xml +++ /dev/null @@ -1,61 +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. ---> - -<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="match_parent" - android:layout_height="@dimen/ongoing_appops_dialog_line_height" - android:layout_marginStart="@dimen/ongoing_appops_dialog_text_padding" - android:layout_marginEnd="@dimen/ongoing_appops_dialog_text_padding" - android:fillViewport="true" - android:orientation="horizontal" - android:focusable="true" - android:layout_gravity="center_vertical"> - - <FrameLayout - android:layout_height="@dimen/ongoing_appops_dialog_app_icon_size" - android:layout_width="@dimen/ongoing_appops_dialog_app_icon_size" - android:layout_gravity="start|center_vertical"> - - <ImageView - android:id="@+id/app_icon" - android:layout_height="@dimen/ongoing_appops_dialog_app_icon_size" - android:layout_width="@dimen/ongoing_appops_dialog_app_icon_size" - android:layout_gravity="center" - /> - </FrameLayout> - - <TextView - android:id="@+id/app_name" - android:layout_height="match_parent" - android:layout_width="0dp" - android:layout_weight="1" - android:gravity="start|center_vertical" - android:textDirection="locale" - android:textAppearance="@style/TextAppearance.AppOpsDialog.Item" - android:textColor="@*android:color/text_color_primary" - android:layout_marginStart="@dimen/ongoing_appops_dialog_text_padding" - /> - - <LinearLayout - android:id="@+id/icons" - android:layout_height="match_parent" - android:layout_width="wrap_content" - android:gravity="end" - android:layout_gravity="end|center_vertical" - android:visibility="gone" - /> -</LinearLayout>
\ No newline at end of file diff --git a/packages/SystemUI/res/layout/volume_dialog.xml b/packages/SystemUI/res/layout/volume_dialog.xml index d1c80c43b3e9..a90b1eb471ff 100644 --- a/packages/SystemUI/res/layout/volume_dialog.xml +++ b/packages/SystemUI/res/layout/volume_dialog.xml @@ -56,6 +56,8 @@ android:background="@drawable/rounded_ripple" android:layout_width="match_parent" android:layout_height="match_parent" + android:scaleType="fitCenter" + android:padding="@dimen/volume_dialog_ringer_icon_padding" android:tint="@color/accent_tint_color_selector" android:layout_gravity="center" android:soundEffectsEnabled="false" /> diff --git a/packages/SystemUI/res/layout/volume_dnd_icon.xml b/packages/SystemUI/res/layout/volume_dnd_icon.xml index 037d143fa69e..10c1472ae993 100644 --- a/packages/SystemUI/res/layout/volume_dnd_icon.xml +++ b/packages/SystemUI/res/layout/volume_dnd_icon.xml @@ -24,6 +24,6 @@ android:layout_width="14dp" android:layout_height="14dp" android:layout_gravity="right|top" - android:src="@drawable/ic_dnd" + android:src="@*android:drawable/ic_qs_dnd" android:tint="?android:attr/textColorTertiary"/> </FrameLayout>
\ No newline at end of file diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index 039eca694e24..1a865eef8d24 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -341,6 +341,8 @@ <dimen name="volume_dialog_ringer_size">64dp</dimen> + <dimen name="volume_dialog_ringer_icon_padding">20dp</dimen> + <dimen name="volume_dialog_caption_size">64dp</dimen> <dimen name="volume_dialog_tap_target_size">48dp</dimen> diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index 03b6a5208f0c..0411d015fd63 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -2345,18 +2345,6 @@ <!-- Content description for ongoing privacy chip. Use with multiple apps [CHAR LIMIT=NONE]--> <string name="ongoing_privacy_chip_content_multiple_apps">Applications are using your <xliff:g id="types_list" example="camera, location">%s</xliff:g>.</string> - <!-- Action for accepting the Ongoing privacy dialog [CHAR LIMIT=10]--> - <string name="ongoing_privacy_dialog_ok">Got it</string> - - <!-- Action on Ongoing Privacy Dialog to open privacy hub [CHAR LIMIT=23]--> - <string name="ongoing_privacy_dialog_open_settings">Privacy settings</string> - - <!-- Text for item in Ongoing Privacy Dialog title when only one app is using app ops [CHAR LIMIT=NONE] --> - <string name="ongoing_privacy_dialog_single_app_title">App using your <xliff:g id="types_list" example="camera( and location)">%s</xliff:g></string> - - <!-- Text for item in Ongoing Privacy Dialog title when multiple apps is using app ops [CHAR LIMIT=NONE] --> - <string name="ongoing_privacy_dialog_multiple_apps_title">Apps using your <xliff:g id="types_list" example="camera( and location)">%s</xliff:g></string> - <!-- Separator for types. Include spaces before and after if needed [CHAR LIMIT=10] --> <string name="ongoing_privacy_dialog_separator">,\u0020</string> diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java index c0ec405e7dc1..fb4fe814601f 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java @@ -99,13 +99,7 @@ public class KeyguardSimPinView extends KeyguardPinBasedInputView { esimButton.setVisibility(isEsimLocked ? View.VISIBLE : View.GONE); } - private void showDefaultMessage() { - if (mRemainingAttempts >= 0) { - mSecurityMessageDisplay.setMessage(getPinPasswordErrorMessage( - mRemainingAttempts, true)); - return; - } - + private void setLockedSimMessage() { boolean isEsimLocked = KeyguardEsimArea.isEsimLocked(mContext, mSubId); int count = TelephonyManager.getDefault().getSimCount(); Resources rez = getResources(); @@ -122,13 +116,20 @@ public class KeyguardSimPinView extends KeyguardPinBasedInputView { color = info.getIconTint(); } } - if (isEsimLocked) { msg = rez.getString(R.string.kg_sim_lock_esim_instructions, msg); } mSecurityMessageDisplay.setMessage(msg); mSimImageView.setImageTintList(ColorStateList.valueOf(color)); + } + + private void showDefaultMessage() { + setLockedSimMessage(); + if (mRemainingAttempts >= 0) { + return; + } + // Sending empty PIN here to query the number of remaining PIN attempts new CheckSimPin("", mSubId) { @@ -137,8 +138,7 @@ public class KeyguardSimPinView extends KeyguardPinBasedInputView { " attemptsRemaining=" + attemptsRemaining); if (attemptsRemaining >= 0) { mRemainingAttempts = attemptsRemaining; - mSecurityMessageDisplay.setMessage( - getPinPasswordErrorMessage(attemptsRemaining, true)); + setLockedSimMessage(); } } }.start(); diff --git a/packages/SystemUI/src/com/android/keyguard/clock/BubbleClockController.java b/packages/SystemUI/src/com/android/keyguard/clock/BubbleClockController.java index 32c1242b695d..147def392594 100644 --- a/packages/SystemUI/src/com/android/keyguard/clock/BubbleClockController.java +++ b/packages/SystemUI/src/com/android/keyguard/clock/BubbleClockController.java @@ -15,15 +15,19 @@ */ package com.android.keyguard.clock; +import android.app.WallpaperManager; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.BitmapFactory; +import android.graphics.Color; import android.graphics.Paint.Style; import android.view.LayoutInflater; import android.view.View; import android.widget.TextClock; +import com.android.internal.colorextraction.ColorExtractor; import com.android.keyguard.R; +import com.android.systemui.colorextraction.SysuiColorExtractor; import com.android.systemui.plugins.ClockPlugin; import java.util.TimeZone; @@ -44,6 +48,16 @@ public class BubbleClockController implements ClockPlugin { private final LayoutInflater mLayoutInflater; /** + * Extracts accent color from wallpaper. + */ + private final SysuiColorExtractor mColorExtractor; + + /** + * Renders preview from clock view. + */ + private final ViewPreviewer mRenderer = new ViewPreviewer(); + + /** * Custom clock shown on AOD screen and behind stack scroller on lock. */ private View mView; @@ -64,11 +78,15 @@ public class BubbleClockController implements ClockPlugin { /** * Create a BubbleClockController instance. * - * @param layoutInflater Inflater used to inflate custom clock views. + * @param res Resources contains title and thumbnail. + * @param inflater Inflater used to inflate custom clock views. + * @param colorExtractor Extracts accent color from wallpaper. */ - public BubbleClockController(Resources res, LayoutInflater inflater) { + public BubbleClockController(Resources res, LayoutInflater inflater, + SysuiColorExtractor colorExtractor) { mResources = res; mLayoutInflater = inflater; + mColorExtractor = colorExtractor; } private void createViews() { @@ -99,6 +117,23 @@ public class BubbleClockController implements ClockPlugin { } @Override + public Bitmap getPreview(int width, int height) { + + // Use the big clock view for the preview + View view = getBigClockView(); + + // Initialize state of plugin before generating preview. + setDarkAmount(1f); + setTextColor(Color.WHITE); + ColorExtractor.GradientColors colors = mColorExtractor.getColors( + WallpaperManager.FLAG_LOCK, true); + setColorPalette(colors.supportsDarkText(), colors.getColorPalette()); + onTimeTick(); + + return mRenderer.createPreview(view, width, height); + } + + @Override public View getView() { if (mLockClockContainer == null) { createViews(); diff --git a/packages/SystemUI/src/com/android/keyguard/clock/ClockManager.java b/packages/SystemUI/src/com/android/keyguard/clock/ClockManager.java index 8ad5c7b90882..d0fff749972d 100644 --- a/packages/SystemUI/src/com/android/keyguard/clock/ClockManager.java +++ b/packages/SystemUI/src/com/android/keyguard/clock/ClockManager.java @@ -16,29 +16,19 @@ package com.android.keyguard.clock; import android.annotation.Nullable; -import android.app.WallpaperManager; import android.content.ContentResolver; import android.content.Context; import android.content.res.Resources; import android.database.ContentObserver; -import android.graphics.Bitmap; -import android.graphics.Bitmap.Config; -import android.graphics.Canvas; -import android.graphics.Color; import android.os.Handler; import android.os.Looper; import android.provider.Settings; import android.util.ArrayMap; import android.util.DisplayMetrics; -import android.util.Log; import android.view.LayoutInflater; -import android.view.View; -import android.view.View.MeasureSpec; -import android.view.ViewGroup; import androidx.annotation.VisibleForTesting; -import com.android.internal.colorextraction.ColorExtractor; import com.android.systemui.SysUiServiceProvider; import com.android.systemui.colorextraction.SysuiColorExtractor; import com.android.systemui.dock.DockManager; @@ -51,8 +41,6 @@ import com.android.systemui.util.InjectionInflationController; import java.util.ArrayList; import java.util.List; import java.util.Map; -import java.util.concurrent.Callable; -import java.util.concurrent.FutureTask; import javax.inject.Inject; import javax.inject.Singleton; @@ -128,7 +116,6 @@ public final class ClockManager { private final List<ClockChangedListener> mListeners = new ArrayList<>(); - private final SysuiColorExtractor mColorExtractor; private final int mWidth; private final int mHeight; @@ -144,17 +131,16 @@ public final class ClockManager { ContentResolver contentResolver, SettingsWrapper settingsWrapper) { mContext = context; mPluginManager = pluginManager; - mColorExtractor = colorExtractor; mContentResolver = contentResolver; mSettingsWrapper = settingsWrapper; Resources res = context.getResources(); LayoutInflater layoutInflater = injectionInflater.injectable(LayoutInflater.from(context)); - addClockPlugin(new DefaultClockController(res, layoutInflater)); - addClockPlugin(new BubbleClockController(res, layoutInflater)); - addClockPlugin(new StretchAnalogClockController(res, layoutInflater)); - addClockPlugin(new TypeClockController(res, layoutInflater)); + addClockPlugin(new DefaultClockController(res, layoutInflater, colorExtractor)); + addClockPlugin(new BubbleClockController(res, layoutInflater, colorExtractor)); + addClockPlugin(new StretchAnalogClockController(res, layoutInflater, colorExtractor)); + addClockPlugin(new TypeClockController(res, layoutInflater, colorExtractor)); // Store the size of the display for generation of clock preview. DisplayMetrics dm = res.getDisplayMetrics(); @@ -217,7 +203,7 @@ public final class ClockManager { .setTitle(plugin.getTitle()) .setId(id) .setThumbnail(() -> plugin.getThumbnail()) - .setPreview(() -> getClockPreview(id)) + .setPreview(() -> plugin.getPreview(mWidth, mHeight)) .build()); } @@ -232,81 +218,6 @@ public final class ClockManager { } } - /** - * Generate a realistic preview of a clock face. - * @param clockId ID of clock to use for preview, should be obtained from {@link getClockInfos}. - * Returns null if clockId is not found. - */ - @Nullable - private Bitmap getClockPreview(String clockId) { - FutureTask<Bitmap> task = new FutureTask<>(new Callable<Bitmap>() { - @Override - public Bitmap call() { - Bitmap bitmap = Bitmap.createBitmap(mWidth, mHeight, Config.ARGB_8888); - ClockPlugin plugin = mClocks.get(clockId); - if (plugin == null) { - return null; - } - - // Use the big clock view for the preview - View clockView = plugin.getBigClockView(); - if (clockView == null) { - return null; - } - - // Initialize state of plugin before generating preview. - plugin.setDarkAmount(1f); - plugin.setTextColor(Color.WHITE); - - ColorExtractor.GradientColors colors = mColorExtractor.getColors( - WallpaperManager.FLAG_LOCK, true); - plugin.setColorPalette(colors.supportsDarkText(), colors.getColorPalette()); - plugin.onTimeTick(); - - // Draw clock view hierarchy to canvas. - Canvas canvas = new Canvas(bitmap); - canvas.drawColor(Color.BLACK); - dispatchVisibilityAggregated(clockView, true); - clockView.measure(MeasureSpec.makeMeasureSpec(mWidth, MeasureSpec.EXACTLY), - MeasureSpec.makeMeasureSpec(mHeight, MeasureSpec.EXACTLY)); - clockView.layout(0, 0, mWidth, mHeight); - clockView.draw(canvas); - return bitmap; - } - }); - - if (Looper.myLooper() == Looper.getMainLooper()) { - task.run(); - } else { - mMainHandler.post(task); - } - - try { - return task.get(); - } catch (Exception e) { - Log.e(TAG, "Error completing task", e); - return null; - } - } - - private void dispatchVisibilityAggregated(View view, boolean isVisible) { - // Similar to View.dispatchVisibilityAggregated implementation. - final boolean thisVisible = view.getVisibility() == View.VISIBLE; - if (thisVisible || !isVisible) { - view.onVisibilityAggregated(isVisible); - } - - if (view instanceof ViewGroup) { - isVisible = thisVisible && isVisible; - ViewGroup vg = (ViewGroup) view; - int count = vg.getChildCount(); - - for (int i = 0; i < count; i++) { - dispatchVisibilityAggregated(vg.getChildAt(i), isVisible); - } - } - } - private void notifyClockChanged(ClockPlugin plugin) { for (int i = 0; i < mListeners.size(); i++) { // It probably doesn't make sense to supply the same plugin instances to multiple diff --git a/packages/SystemUI/src/com/android/keyguard/clock/DefaultClockController.java b/packages/SystemUI/src/com/android/keyguard/clock/DefaultClockController.java index 8a6a4cd95991..73414b30432f 100644 --- a/packages/SystemUI/src/com/android/keyguard/clock/DefaultClockController.java +++ b/packages/SystemUI/src/com/android/keyguard/clock/DefaultClockController.java @@ -15,15 +15,19 @@ */ package com.android.keyguard.clock; +import android.app.WallpaperManager; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.BitmapFactory; +import android.graphics.Color; import android.graphics.Paint.Style; import android.view.LayoutInflater; import android.view.View; import android.widget.TextView; +import com.android.internal.colorextraction.ColorExtractor; import com.android.keyguard.R; +import com.android.systemui.colorextraction.SysuiColorExtractor; import com.android.systemui.plugins.ClockPlugin; import java.util.TimeZone; @@ -44,6 +48,16 @@ public class DefaultClockController implements ClockPlugin { private final LayoutInflater mLayoutInflater; /** + * Extracts accent color from wallpaper. + */ + private final SysuiColorExtractor mColorExtractor; + + /** + * Renders preview from clock view. + */ + private final ViewPreviewer mRenderer = new ViewPreviewer(); + + /** * Root view of preview. */ private View mView; @@ -61,11 +75,15 @@ public class DefaultClockController implements ClockPlugin { /** * Create a DefaultClockController instance. * + * @param res Resources contains title and thumbnail. * @param inflater Inflater used to inflate custom clock views. + * @param colorExtractor Extracts accent color from wallpaper. */ - public DefaultClockController(Resources res, LayoutInflater inflater) { + public DefaultClockController(Resources res, LayoutInflater inflater, + SysuiColorExtractor colorExtractor) { mResources = res; mLayoutInflater = inflater; + mColorExtractor = colorExtractor; } private void createViews() { @@ -90,6 +108,23 @@ public class DefaultClockController implements ClockPlugin { } @Override + public Bitmap getPreview(int width, int height) { + + // Use the big clock view for the preview + View view = getBigClockView(); + + // Initialize state of plugin before generating preview. + setDarkAmount(1f); + setTextColor(Color.WHITE); + ColorExtractor.GradientColors colors = mColorExtractor.getColors( + WallpaperManager.FLAG_LOCK, true); + setColorPalette(colors.supportsDarkText(), colors.getColorPalette()); + onTimeTick(); + + return mRenderer.createPreview(view, width, height); + } + + @Override public View getView() { return null; } diff --git a/packages/SystemUI/src/com/android/keyguard/clock/StretchAnalogClockController.java b/packages/SystemUI/src/com/android/keyguard/clock/StretchAnalogClockController.java index 34b2fd86f648..ea9f0cd3c17d 100644 --- a/packages/SystemUI/src/com/android/keyguard/clock/StretchAnalogClockController.java +++ b/packages/SystemUI/src/com/android/keyguard/clock/StretchAnalogClockController.java @@ -15,15 +15,19 @@ */ package com.android.keyguard.clock; +import android.app.WallpaperManager; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.BitmapFactory; +import android.graphics.Color; import android.graphics.Paint.Style; import android.view.LayoutInflater; import android.view.View; import android.widget.TextClock; +import com.android.internal.colorextraction.ColorExtractor; import com.android.keyguard.R; +import com.android.systemui.colorextraction.SysuiColorExtractor; import com.android.systemui.plugins.ClockPlugin; import java.util.TimeZone; @@ -44,6 +48,16 @@ public class StretchAnalogClockController implements ClockPlugin { private final LayoutInflater mLayoutInflater; /** + * Extracts accent color from wallpaper. + */ + private final SysuiColorExtractor mColorExtractor; + + /** + * Renders preview from clock view. + */ + private final ViewPreviewer mRenderer = new ViewPreviewer(); + + /** * Custom clock shown on AOD screen and behind stack scroller on lock. */ private View mBigClockView; @@ -64,11 +78,15 @@ public class StretchAnalogClockController implements ClockPlugin { /** * Create a BubbleClockController instance. * - * @param layoutInflater Inflater used to inflate custom clock views. + * @param res Resources contains title and thumbnail. + * @param inflater Inflater used to inflate custom clock views. + * @param colorExtractor Extracts accent color from wallpaper. */ - public StretchAnalogClockController(Resources res, LayoutInflater inflater) { + public StretchAnalogClockController(Resources res, LayoutInflater inflater, + SysuiColorExtractor colorExtractor) { mResources = res; mLayoutInflater = inflater; + mColorExtractor = colorExtractor; } private void createViews() { @@ -99,6 +117,23 @@ public class StretchAnalogClockController implements ClockPlugin { } @Override + public Bitmap getPreview(int width, int height) { + + // Use the big clock view for the preview + View view = getBigClockView(); + + // Initialize state of plugin before generating preview. + setDarkAmount(1f); + setTextColor(Color.WHITE); + ColorExtractor.GradientColors colors = mColorExtractor.getColors( + WallpaperManager.FLAG_LOCK, true); + setColorPalette(colors.supportsDarkText(), colors.getColorPalette()); + onTimeTick(); + + return mRenderer.createPreview(view, width, height); + } + + @Override public View getView() { if (mView == null) { createViews(); diff --git a/packages/SystemUI/src/com/android/keyguard/clock/TypeClockController.java b/packages/SystemUI/src/com/android/keyguard/clock/TypeClockController.java index 387f2656c6f8..67c0989b49c4 100644 --- a/packages/SystemUI/src/com/android/keyguard/clock/TypeClockController.java +++ b/packages/SystemUI/src/com/android/keyguard/clock/TypeClockController.java @@ -15,14 +15,18 @@ */ package com.android.keyguard.clock; +import android.app.WallpaperManager; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.BitmapFactory; +import android.graphics.Color; import android.graphics.Paint.Style; import android.view.LayoutInflater; import android.view.View; +import com.android.internal.colorextraction.ColorExtractor; import com.android.keyguard.R; +import com.android.systemui.colorextraction.SysuiColorExtractor; import com.android.systemui.plugins.ClockPlugin; import java.util.TimeZone; @@ -43,6 +47,16 @@ public class TypeClockController implements ClockPlugin { private final LayoutInflater mLayoutInflater; /** + * Extracts accent color from wallpaper. + */ + private final SysuiColorExtractor mColorExtractor; + + /** + * Renders preview from clock view. + */ + private final ViewPreviewer mRenderer = new ViewPreviewer(); + + /** * Custom clock shown on AOD screen and behind stack scroller on lock. */ private View mView; @@ -61,11 +75,15 @@ public class TypeClockController implements ClockPlugin { /** * Create a TypeClockController instance. * + * @param res Resources contains title and thumbnail. * @param inflater Inflater used to inflate custom clock views. + * @param colorExtractor Extracts accent color from wallpaper. */ - TypeClockController(Resources res, LayoutInflater inflater) { + TypeClockController(Resources res, LayoutInflater inflater, + SysuiColorExtractor colorExtractor) { mResources = res; mLayoutInflater = inflater; + mColorExtractor = colorExtractor; } private void createViews() { @@ -96,6 +114,23 @@ public class TypeClockController implements ClockPlugin { } @Override + public Bitmap getPreview(int width, int height) { + + // Use the big clock view for the preview + View view = getBigClockView(); + + // Initialize state of plugin before generating preview. + setDarkAmount(1f); + setTextColor(Color.WHITE); + ColorExtractor.GradientColors colors = mColorExtractor.getColors( + WallpaperManager.FLAG_LOCK, true); + setColorPalette(colors.supportsDarkText(), colors.getColorPalette()); + onTimeTick(); + + return mRenderer.createPreview(view, width, height); + } + + @Override public View getView() { if (mLockClock == null) { createViews(); diff --git a/packages/SystemUI/src/com/android/keyguard/clock/ViewPreviewer.java b/packages/SystemUI/src/com/android/keyguard/clock/ViewPreviewer.java new file mode 100644 index 000000000000..abd0dd28dabc --- /dev/null +++ b/packages/SystemUI/src/com/android/keyguard/clock/ViewPreviewer.java @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.keyguard.clock; + +import android.annotation.Nullable; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Color; +import android.os.Handler; +import android.os.Looper; +import android.util.Log; +import android.view.View; +import android.view.ViewGroup; + +import java.util.concurrent.Callable; +import java.util.concurrent.FutureTask; + +/** + * Creates a preview image ({@link Bitmap}) of a {@link View} for a custom clock face. + */ +final class ViewPreviewer { + + private static final String TAG = "ViewPreviewer"; + + /** + * Handler used to run {@link View#draw(Canvas)} on the main thread. + */ + private final Handler mMainHandler = new Handler(Looper.getMainLooper()); + + /** + * Generate a realistic preview of a clock face. + * + * @param view view is used to generate preview image. + * @param width width of the preview image, should be the same as device width in pixels. + * @param height height of the preview image, should be the same as device height in pixels. + * @return bitmap of view. + */ + @Nullable + Bitmap createPreview(View view, int width, int height) { + if (view == null) { + return null; + } + FutureTask<Bitmap> task = new FutureTask<>(new Callable<Bitmap>() { + @Override + public Bitmap call() { + Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); + + // Draw clock view hierarchy to canvas. + Canvas canvas = new Canvas(bitmap); + canvas.drawColor(Color.BLACK); + dispatchVisibilityAggregated(view, true); + view.measure(View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.EXACTLY), + View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.EXACTLY)); + view.layout(0, 0, width, height); + view.draw(canvas); + + return bitmap; + } + }); + + if (Looper.myLooper() == Looper.getMainLooper()) { + task.run(); + } else { + mMainHandler.post(task); + } + + try { + return task.get(); + } catch (Exception e) { + Log.e(TAG, "Error completing task", e); + return null; + } + } + + private void dispatchVisibilityAggregated(View view, boolean isVisible) { + // Similar to View.dispatchVisibilityAggregated implementation. + final boolean thisVisible = view.getVisibility() == View.VISIBLE; + if (thisVisible || !isVisible) { + view.onVisibilityAggregated(isVisible); + } + + if (view instanceof ViewGroup) { + isVisible = thisVisible && isVisible; + ViewGroup vg = (ViewGroup) view; + int count = vg.getChildCount(); + + for (int i = 0; i < count; i++) { + dispatchVisibilityAggregated(vg.getChildAt(i), isVisible); + } + } + } +} diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java index 559c9f6dd04b..de887ff6ff86 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java @@ -381,10 +381,18 @@ public class BubbleExpandedView extends LinearLayout implements View.OnClickList } /** - * Update bubble expanded view header when user toggles dark mode. + * Update header color when user toggles dark mode. */ void updateHeaderColor() { - mHeaderView.setBackgroundColor(mContext.getColor(R.attr.colorAccent)); + TypedArray ta = mContext.obtainStyledAttributes( + new int[] {android.R.attr.colorBackgroundFloating, android.R.attr.colorForeground}); + int bgColor = ta.getColor(0, Color.WHITE /* default */); + int btnColor = ta.getColor(1, Color.BLACK /* default */); + ta.recycle(); + + mHeaderView.setBackgroundColor(bgColor); + mSettingsIcon.setColorFilter(btnColor); + mDeepLinkIcon.setColorFilter(btnColor); } private void updateHeaderView() { diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java index 617090ac89e1..be55829869eb 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java @@ -52,6 +52,7 @@ import androidx.dynamicanimation.animation.SpringForce; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.widget.ViewClippingUtil; +import com.android.systemui.Dependency; import com.android.systemui.R; import com.android.systemui.bubbles.BubbleController.DismissReason; import com.android.systemui.bubbles.animation.ExpandedAnimationController; @@ -270,8 +271,8 @@ public class BubbleStackView extends FrameLayout { * Handle config changes. */ public void onConfigChanged() { - if (mExpandedBubble != null) { - mExpandedBubble.expandedView.updateHeaderColor(); + for (Bubble b: mBubbleData.getBubbles()) { + b.expandedView.updateHeaderColor(); } } @@ -316,7 +317,8 @@ public class BubbleStackView extends FrameLayout { } switch (action) { case AccessibilityNodeInfo.ACTION_DISMISS: - stackDismissed(BubbleController.DISMISS_ACCESSIBILITY_ACTION); + Dependency.get(BubbleController.class).dismissStack( + BubbleController.DISMISS_ACCESSIBILITY_ACTION); return true; case AccessibilityNodeInfo.ACTION_COLLAPSE: collapseStack(); @@ -422,7 +424,7 @@ public class BubbleStackView extends FrameLayout { * Sets the entry that should be expanded and expands if needed. */ @VisibleForTesting - public void setExpandedBubble(NotificationEntry entry) { + void setExpandedBubble(NotificationEntry entry) { for (int i = 0; i < mBubbleContainer.getChildCount(); i++) { BubbleView bv = (BubbleView) mBubbleContainer.getChildAt(i); if (entry.equals(bv.getEntry())) { @@ -436,7 +438,7 @@ public class BubbleStackView extends FrameLayout { * * @param entry the notification to add to the stack of bubbles. */ - public void addBubble(NotificationEntry entry) { + void addBubble(NotificationEntry entry) { Bubble b = new Bubble(entry, mInflater, this /* stackView */, mBlockedListener); mBubbleData.addBubble(b); @@ -451,12 +453,17 @@ public class BubbleStackView extends FrameLayout { /** * Remove a bubble from the stack. */ - public void removeBubble(String key, int reason) { + void removeBubble(String key, int reason) { Bubble b = mBubbleData.removeBubble(key); if (b == null) { return; } - int removedIndex = dismissBubble(b, reason); + setBubbleDismissed(b, reason); + + // Remove it from the views + int removedIndex = mBubbleContainer.indexOfChild(b.iconView); + mBubbleContainer.removeViewAt(removedIndex); + int bubbleCount = mBubbleContainer.getChildCount(); if (bubbleCount == 0) { // If no bubbles remain, collapse the entire stack. @@ -481,9 +488,9 @@ public class BubbleStackView extends FrameLayout { /** * Dismiss the stack of bubbles. */ - public void stackDismissed(int reason) { + void stackDismissed(int reason) { for (Bubble bubble : mBubbleData.getBubbles()) { - dismissBubble(bubble, reason); + setBubbleDismissed(bubble, reason); } mBubbleData.clear(); collapseStack(); @@ -495,8 +502,7 @@ public class BubbleStackView extends FrameLayout { } /** - * Marks the notification entry as dismissed, cleans up Bubble icon and expanded view UI - * elements and calls deleteIntent if necessary. + * Marks the notification entry as dismissed & calls any delete intents for the bubble. * * <p>Note: This does not remove the Bubble from BubbleData. * @@ -504,17 +510,13 @@ public class BubbleStackView extends FrameLayout { * @param reason code for the reason the dismiss was triggered * @see BubbleController.DismissReason */ - private int dismissBubble(Bubble bubble, @DismissReason int reason) { + private void setBubbleDismissed(Bubble bubble, @DismissReason int reason) { if (DEBUG) { Log.d(TAG, "dismissBubble: " + bubble + " reason=" + reason); } bubble.entry.setBubbleDismissed(true); bubble.expandedView.cleanUpExpandedState(); - // Remove it from the views - int removedIndex = mBubbleContainer.indexOfChild(bubble.iconView); - mBubbleContainer.removeViewAt(removedIndex); - if (reason == BubbleController.DISMISS_USER_GESTURE) { Notification.BubbleMetadata bubbleMetadata = bubble.entry.getBubbleMetadata(); PendingIntent deleteIntent = bubbleMetadata != null @@ -529,7 +531,6 @@ public class BubbleStackView extends FrameLayout { } } } - return removedIndex; } /** @@ -856,7 +857,6 @@ public class BubbleStackView extends FrameLayout { private void applyCurrentState() { Log.d(TAG, "applyCurrentState: mIsExpanded=" + mIsExpanded); - mExpandedViewContainer.setVisibility(mIsExpanded ? VISIBLE : GONE); if (mIsExpanded) { // First update the view so that it calculates a new height (ensuring the y position diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java b/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java index f65112c5c2f5..8bf2256a4f80 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java @@ -192,7 +192,10 @@ public class DozeMachine { @MainThread public State getState() { Assert.isMainThread(); - Preconditions.checkState(!isExecutingTransition()); + if (isExecutingTransition()) { + throw new IllegalStateException("Cannot get state because there were pending " + + "transitions: " + mQueuedRequests.toString()); + } return mState; } diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java b/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java index 1dd3101075b0..bd6882c01bbd 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java @@ -56,6 +56,7 @@ public class DozeScreenBrightness extends BroadcastReceiver implements DozeMachi private boolean mRegistered; private int mDefaultDozeBrightness; private boolean mPaused = false; + private boolean mScreenOff = false; private int mLastSensorValue = -1; /** @@ -118,6 +119,7 @@ public class DozeScreenBrightness extends BroadcastReceiver implements DozeMachi break; } if (newState != DozeMachine.State.FINISH) { + setScreenOff(newState == DozeMachine.State.DOZE); setPaused(newState == DozeMachine.State.DOZE_AOD_PAUSED); } } @@ -135,15 +137,15 @@ public class DozeScreenBrightness extends BroadcastReceiver implements DozeMachi try { if (mRegistered) { mLastSensorValue = (int) event.values[0]; - updateBrightnessAndReady(); + updateBrightnessAndReady(false /* force */); } } finally { Trace.endSection(); } } - private void updateBrightnessAndReady() { - if (mRegistered || mDebugBrightnessBucket != -1) { + private void updateBrightnessAndReady(boolean force) { + if (force || mRegistered || mDebugBrightnessBucket != -1) { int sensorValue = mDebugBrightnessBucket == -1 ? mLastSensorValue : mDebugBrightnessBucket; int brightness = computeBrightness(sensorValue); @@ -153,7 +155,7 @@ public class DozeScreenBrightness extends BroadcastReceiver implements DozeMachi } int scrimOpacity = -1; - if (mPaused) { + if (mPaused || mScreenOff) { // If AOD is paused, force the screen black until the // sensor reports a new brightness. This ensures that when the screen comes on // again, it will only show after the brightness sensor has stabilized, @@ -216,13 +218,20 @@ public class DozeScreenBrightness extends BroadcastReceiver implements DozeMachi private void setPaused(boolean paused) { if (mPaused != paused) { mPaused = paused; - updateBrightnessAndReady(); + updateBrightnessAndReady(false /* force */); + } + } + + private void setScreenOff(boolean screenOff) { + if (mScreenOff != screenOff) { + mScreenOff = screenOff; + updateBrightnessAndReady(true /* force */); } } @Override public void onReceive(Context context, Intent intent) { mDebugBrightnessBucket = intent.getIntExtra(BRIGHTNESS_BUCKET, -1); - updateBrightnessAndReady(); + updateBrightnessAndReady(false /* force */); } } diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java index c9eb60387969..0fe6611b4274 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java @@ -16,6 +16,7 @@ package com.android.systemui.doze; +import android.annotation.Nullable; import android.app.AlarmManager; import android.app.UiModeManager; import android.content.BroadcastReceiver; @@ -147,7 +148,7 @@ public class DozeTriggers implements DozeMachine.Part { boolean wakeEvent = rawValues != null && rawValues.length > 0 && rawValues[0] != 0; if (isWakeDisplay) { - onWakeScreen(wakeEvent, mMachine.getState()); + onWakeScreen(wakeEvent, mMachine.isExecutingTransition() ? null : mMachine.getState()); } else if (isLongPress) { requestPulse(pulseReason, sensorPerformedProxCheck); } else if (isWakeLockScreen) { @@ -228,10 +229,14 @@ public class DozeTriggers implements DozeMachine.Part { } } - private void onWakeScreen(boolean wake, DozeMachine.State state) { + /** + * When a wake screen event is received from a sensor + * @param wake {@code true} when it's time to wake up, {@code false} when we should sleep. + * @param state The current state, or null if the state could not be determined due to enqueued + * transitions. + */ + private void onWakeScreen(boolean wake, @Nullable DozeMachine.State state) { DozeLog.traceWakeDisplay(wake); - boolean paused = (state == DozeMachine.State.DOZE_AOD_PAUSED); - boolean pausing = (state == DozeMachine.State.DOZE_AOD_PAUSING); sWakeDisplaySensorState = wake; if (wake) { @@ -245,6 +250,8 @@ public class DozeTriggers implements DozeMachine.Part { } }, false /* alreadyPerformedProxCheck */, DozeLog.REASON_SENSOR_WAKE_UP); } else { + boolean paused = (state == DozeMachine.State.DOZE_AOD_PAUSED); + boolean pausing = (state == DozeMachine.State.DOZE_AOD_PAUSING); if (!pausing && !paused) { mMachine.requestState(DozeMachine.State.DOZE); } diff --git a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialogBuilder.kt b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialogBuilder.kt index 59b3c3464a69..d08a3733703b 100644 --- a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialogBuilder.kt +++ b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialogBuilder.kt @@ -53,9 +53,4 @@ class PrivacyDialogBuilder(private val context: Context, itemsList: List<Privacy else -> types.map { it.getName(context) }.joinWithAnd().toString() } } - - fun getDialogTitle(): String { - return context.getString(R.string.ongoing_privacy_dialog_multiple_apps_title, - joinTypes()) - } } diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java b/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java index 7c937a944113..b682cb09b598 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java @@ -160,9 +160,9 @@ public class QSSecurityFooter implements OnClickListener, DialogInterface.OnClic int footerIconId = R.drawable.ic_info_outline; if (vpnName != null || vpnNameWorkProfile != null) { if (mSecurityController.isVpnBranded()) { - footerIconId = R.drawable.ic_qs_branded_vpn; + footerIconId = R.drawable.stat_sys_branded_vpn; } else { - footerIconId = R.drawable.ic_qs_vpn; + footerIconId = R.drawable.stat_sys_vpn_ic; } } if (mFooterIconId != footerIconId) { diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java index cf04ea6b5448..19e20a93ce66 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java @@ -43,7 +43,7 @@ import javax.inject.Inject; /** Quick settings tile: Airplane mode **/ public class AirplaneModeTile extends QSTileImpl<BooleanState> { - private final Icon mIcon = ResourceIcon.get(R.drawable.ic_airplane); + private final Icon mIcon = ResourceIcon.get(com.android.internal.R.drawable.ic_qs_airplane); private final GlobalSetting mSetting; private final ActivityStarter mActivityStarter; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java index f1a8d3730606..ca040762047c 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java @@ -147,14 +147,15 @@ public class BluetoothTile extends QSTileImpl<BooleanState> { state.icon = ResourceIcon.get(R.drawable.ic_bluetooth_transient_animation); state.contentDescription = state.secondaryLabel; } else { - state.icon = ResourceIcon.get(R.drawable.ic_qs_bluetooth_on); + state.icon = + ResourceIcon.get(com.android.internal.R.drawable.ic_qs_bluetooth); state.contentDescription = mContext.getString( R.string.accessibility_quick_settings_bluetooth) + "," + mContext.getString(R.string.accessibility_not_connected); } state.state = Tile.STATE_ACTIVE; } else { - state.icon = ResourceIcon.get(R.drawable.ic_qs_bluetooth_on); + state.icon = ResourceIcon.get(com.android.internal.R.drawable.ic_qs_bluetooth); state.contentDescription = mContext.getString( R.string.accessibility_quick_settings_bluetooth); state.state = Tile.STATE_INACTIVE; @@ -383,7 +384,7 @@ public class BluetoothTile extends QSTileImpl<BooleanState> { for (CachedBluetoothDevice device : devices) { if (mController.getBondState(device) == BluetoothDevice.BOND_NONE) continue; final Item item = new Item(); - item.iconResId = R.drawable.ic_qs_bluetooth_on; + item.iconResId = com.android.internal.R.drawable.ic_qs_bluetooth; item.line1 = device.getName(); item.tag = device; int state = device.getMaxConnectionState(); diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java index 7fcd59f7c931..869fa6b18245 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java @@ -235,7 +235,7 @@ public class DndTile extends QSTileImpl<BooleanState> { state.label = getTileLabel(); state.secondaryLabel = TextUtils.emptyIfNull(ZenModeConfig.getDescription(mContext, zen != Global.ZEN_MODE_OFF, mController.getConfig(), false)); - state.icon = ResourceIcon.get(R.drawable.ic_dnd); + state.icon = ResourceIcon.get(com.android.internal.R.drawable.ic_qs_dnd); checkIfRestrictionEnforcedByAdminOnly(state, UserManager.DISALLOW_ADJUST_VOLUME); switch (zen) { case Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS: diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java index dfa3fb9dafc9..2755e9880b58 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java @@ -35,7 +35,7 @@ import javax.inject.Inject; public class FlashlightTile extends QSTileImpl<BooleanState> implements FlashlightController.FlashlightListener { - private final Icon mIcon = ResourceIcon.get(R.drawable.ic_signal_flashlight); + private final Icon mIcon = ResourceIcon.get(com.android.internal.R.drawable.ic_qs_flashlight); private final FlashlightController mFlashlightController; @Inject diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java index 21f3d6e77f7b..7ca1e44c93cd 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java @@ -36,7 +36,7 @@ import javax.inject.Inject; /** Quick settings tile: Rotation **/ public class RotationLockTile extends QSTileImpl<BooleanState> { - private final Icon mIcon = ResourceIcon.get(R.drawable.ic_qs_auto_rotate); + private final Icon mIcon = ResourceIcon.get(com.android.internal.R.drawable.ic_qs_auto_rotate); private final RotationLockController mController; @Inject 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 79056175b595..211a40a91101 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java @@ -70,7 +70,7 @@ public class BarTransitions { private final String mTag; private final View mView; - private final BarBackgroundDrawable mBarBackground; + protected final BarBackgroundDrawable mBarBackground; private int mMode; private boolean mAlwaysOpaque = false; @@ -152,7 +152,7 @@ public class BarTransitions { return mode == MODE_LIGHTS_OUT || mode == MODE_LIGHTS_OUT_TRANSPARENT; } - private static class BarBackgroundDrawable extends Drawable { + protected static class BarBackgroundDrawable extends Drawable { private final int mOpaque; private final int mSemiTransparent; private final int mTransparent; @@ -171,6 +171,7 @@ public class BarTransitions { private int mGradientAlphaStart; private int mColorStart; + private Rect mFrame; public BarBackgroundDrawable(Context context, int gradientResourceId) { @@ -190,6 +191,10 @@ public class BarTransitions { mGradient = context.getDrawable(gradientResourceId); } + public void setFrame(Rect frame) { + mFrame = frame; + } + @Override public void setAlpha(int alpha) { // noop @@ -296,7 +301,11 @@ public class BarTransitions { if (mTintFilter != null) { mPaint.setColorFilter(mTintFilter); } - canvas.drawPaint(mPaint); + if (mFrame != null) { + canvas.drawRect(mFrame, mPaint); + } else { + canvas.drawPaint(mPaint); + } } if (mAnimating) { invalidateSelf(); // keep going 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 cbb5d5430e8d..94856234503c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java @@ -988,11 +988,11 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback if (Intent.ACTION_SCREEN_ON.equals(action)) { // Enabled and screen is on, start it again if enabled if (NavBarTintController.isEnabled(getContext())) { - mNavigationBarView.getColorAdaptionController().start(); + mNavigationBarView.getTintController().start(); } } else { // Screen off disable it - mNavigationBarView.getColorAdaptionController().stop(); + mNavigationBarView.getTintController().stop(); } } if (Intent.ACTION_USER_SWITCHED.equals(action)) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarTransitions.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarTransitions.java index 3984405f8e09..d4cec429dc90 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarTransitions.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarTransitions.java @@ -17,6 +17,7 @@ package com.android.systemui.statusbar.phone; import android.content.Context; +import android.graphics.Rect; import android.os.Handler; import android.os.RemoteException; import android.os.ServiceManager; @@ -105,6 +106,10 @@ public final class NavigationBarTransitions extends BarTransitions { applyLightsOut(true, false); } + void setBackgroundFrame(Rect frame) { + mBarBackground.setFrame(frame); + } + @Override protected boolean isLightsOut(int mode) { return super.isLightsOut(mode) || (mAllowAutoDimWallpaperNotVisible && mAutoDim @@ -119,6 +124,7 @@ public final class NavigationBarTransitions extends BarTransitions { protected void onTransition(int oldMode, int newMode, boolean animate) { super.onTransition(oldMode, newMode, animate); applyLightsOut(animate, false /*force*/); + mView.onBarTransition(newMode); } private void applyLightsOut(boolean animate, boolean force) { 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 f2d62414d51e..f22ecf6792bc 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java @@ -30,6 +30,7 @@ import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_ import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_NONE; import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_OVERVIEW; import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_ROTATION; +import static com.android.systemui.statusbar.phone.BarTransitions.MODE_OPAQUE; import static com.android.systemui.statusbar.phone.NavigationBarInflaterView.NAV_BAR_VIEWS; import android.animation.LayoutTransition; @@ -172,7 +173,7 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav private RecentsOnboarding mRecentsOnboarding; private NotificationPanelView mPanelView; - private NavBarTintController mColorAdaptionController; + private NavBarTintController mTintController; private boolean mAssistantAvailable; private NavigationPrototypeController mPrototypeController; private NavigationGestureAction[] mDefaultGestureMap; @@ -309,9 +310,9 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav @Override public void onColorAdaptChanged(boolean enabled) { if (enabled) { - mColorAdaptionController.start(); + mTintController.start(); } else { - mColorAdaptionController.stop(); + mTintController.stop(); } } @@ -442,15 +443,15 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav mPrototypeController = new NavigationPrototypeController(context); mPrototypeController.register(); mPrototypeController.setOnPrototypeChangedListener(mPrototypeListener); - mColorAdaptionController = new NavBarTintController(this, getLightTransitionsController()); + mTintController = new NavBarTintController(this, getLightTransitionsController()); IntentFilter filter = new IntentFilter(ACTION_OVERLAY_CHANGED); filter.addDataScheme("package"); context.registerReceiver(mOverlaysChangedReceiver, filter); } - public NavBarTintController getColorAdaptionController() { - return mColorAdaptionController; + public NavBarTintController getTintController() { + return mTintController; } public BarTransitions getBarTransitions() { @@ -476,7 +477,7 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav @Override protected void dispatchDraw(Canvas canvas) { super.dispatchDraw(canvas); - mColorAdaptionController.onDraw(); + mTintController.onDraw(); } private void updateNavigationGestures() { @@ -557,6 +558,17 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav return super.onTouchEvent(event); } + void onBarTransition(int newMode) { + if (newMode == MODE_OPAQUE) { + // If the nav bar background is opaque, stop auto tinting since we know the icons are + // showing over a dark background + mTintController.stop(); + getLightTransitionsController().setIconsDark(false /* dark */, true /* animate */); + } else { + mTintController.start(); + } + } + private boolean shouldDeadZoneConsumeTouchEvents(MotionEvent event) { if (mDeadZone.onTouchEvent(event) || mDeadZoneConsuming) { switch (event.getActionMasked()) { @@ -978,9 +990,9 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav // Color adaption is tied with showing home handle, only avaliable if visible if (visible) { - mColorAdaptionController.start(); + mTintController.start(); } else { - mColorAdaptionController.stop(); + mTintController.stop(); } } @@ -1206,6 +1218,19 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav reorient(); notifyVerticalChangedListener(newVertical); } + + if (QuickStepContract.isGesturalMode(getContext())) { + // Update the nav bar background to match the height of the visible nav bar + int height = mIsVertical + ? getResources().getDimensionPixelSize( + com.android.internal.R.dimen.navigation_bar_height_landscape) + : getResources().getDimensionPixelSize( + com.android.internal.R.dimen.navigation_bar_height); + int frameHeight = getResources().getDimensionPixelSize( + com.android.internal.R.dimen.navigation_bar_frame_height); + mBarTransitions.setBackgroundFrame(new Rect(0, frameHeight - height, w, h)); + } + super.onMeasure(widthMeasureSpec, heightMeasureSpec); } @@ -1232,9 +1257,9 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav } if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) { - mColorAdaptionController.start(); + mTintController.start(); } else { - mColorAdaptionController.stop(); + mTintController.stop(); } } @@ -1417,7 +1442,7 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav mGestureHelper.dump(pw); } mRecentsOnboarding.dump(pw); - mColorAdaptionController.dump(pw); + mTintController.dump(pw); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationHandle.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationHandle.java index 81a425cd5eba..7dc71f590ecd 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationHandle.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationHandle.java @@ -57,6 +57,7 @@ public class NavigationHandle extends View implements ButtonInterface { mLightColor = Utils.getColorAttrDefaultColor(lightContext, R.attr.singleToneColor); mDarkColor = Utils.getColorAttrDefaultColor(darkContext, R.attr.singleToneColor); mPaint.setAntiAlias(true); + setFocusable(false); } @Override diff --git a/packages/SystemUI/tests/src/com/android/keyguard/clock/BubbleClockControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/clock/BubbleClockControllerTest.java index 267468ffa4d6..f03c234ac3bb 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/clock/BubbleClockControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/clock/BubbleClockControllerTest.java @@ -27,10 +27,13 @@ import android.view.ViewGroup; import android.widget.TextView; import com.android.systemui.SysuiTestCase; +import com.android.systemui.colorextraction.SysuiColorExtractor; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; @SmallTest @RunWith(AndroidTestingRunner.class) @@ -38,12 +41,15 @@ import org.junit.runner.RunWith; public final class BubbleClockControllerTest extends SysuiTestCase { private BubbleClockController mClockController; + @Mock SysuiColorExtractor mMockColorExtractor; @Before public void setUp() { + MockitoAnnotations.initMocks(this); + Resources res = getContext().getResources(); LayoutInflater layoutInflater = LayoutInflater.from(getContext()); - mClockController = new BubbleClockController(res, layoutInflater); + mClockController = new BubbleClockController(res, layoutInflater, mMockColorExtractor); } @Test diff --git a/packages/SystemUI/tests/src/com/android/keyguard/clock/StretchAnalogClockControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/clock/StretchAnalogClockControllerTest.java index 0659b4fe71cd..26fa62b77d9a 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/clock/StretchAnalogClockControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/clock/StretchAnalogClockControllerTest.java @@ -27,10 +27,13 @@ import android.view.ViewGroup; import android.widget.TextView; import com.android.systemui.SysuiTestCase; +import com.android.systemui.colorextraction.SysuiColorExtractor; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; @SmallTest @RunWith(AndroidTestingRunner.class) @@ -38,12 +41,16 @@ import org.junit.runner.RunWith; public final class StretchAnalogClockControllerTest extends SysuiTestCase { private StretchAnalogClockController mClockController; + @Mock SysuiColorExtractor mMockColorExtractor; @Before public void setUp() { + MockitoAnnotations.initMocks(this); + Resources res = getContext().getResources(); LayoutInflater layoutInflater = LayoutInflater.from(getContext()); - mClockController = new StretchAnalogClockController(res, layoutInflater); + mClockController = new StretchAnalogClockController(res, layoutInflater, + mMockColorExtractor); } @Test diff --git a/packages/SystemUI/tests/src/com/android/keyguard/clock/ViewPreviewerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/clock/ViewPreviewerTest.kt new file mode 100644 index 000000000000..d9ef7fa34883 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/keyguard/clock/ViewPreviewerTest.kt @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.keyguard.clock + +import android.content.Context +import com.google.common.truth.Truth.assertThat + +import android.graphics.Canvas +import android.graphics.Color +import android.testing.AndroidTestingRunner +import android.view.View +import androidx.test.filters.SmallTest +import com.android.systemui.SysuiTestCase +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith + +@RunWith(AndroidTestingRunner::class) +@SmallTest +class ViewPreviewerTest : SysuiTestCase() { + + private lateinit var previewer: ViewPreviewer + private lateinit var view: View + + @Before + fun setUp() { + previewer = ViewPreviewer() + view = TestView(context) + } + + @Test + fun testCreatePreview() { + val width = 100 + val height = 100 + // WHEN a preview image is created + val bitmap = previewer.createPreview(view, width, height) + // THEN the bitmap has the expected width and height + assertThat(bitmap.height).isEqualTo(height) + assertThat(bitmap.width).isEqualTo(width) + assertThat(bitmap.getPixel(0, 0)).isEqualTo(Color.RED) + } + + class TestView(context: Context) : View(context) { + override fun onDraw(canvas: Canvas?) { + super.onDraw(canvas) + canvas?.drawColor(Color.RED) + } + } +}
\ No newline at end of file diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenBrightnessTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenBrightnessTest.java index cde3398f91a6..392c677b9827 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenBrightnessTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenBrightnessTest.java @@ -237,6 +237,18 @@ public class DozeScreenBrightnessTest extends SysuiTestCase { } @Test + public void screenOff_softBlanks() throws Exception { + mScreen.transitionTo(UNINITIALIZED, INITIALIZED); + mScreen.transitionTo(INITIALIZED, DOZE_AOD); + mScreen.transitionTo(DOZE_AOD, DOZE); + assertEquals(1f, mHostFake.aodDimmingScrimOpacity, 0.001f /* delta */); + + mScreen.transitionTo(DOZE, DOZE_AOD); + mSensor.sendSensorEvent(2); + assertEquals(0f, mHostFake.aodDimmingScrimOpacity, 0.001f /* delta */); + } + + @Test public void pausingAod_unblanksAfterSensor() throws Exception { mScreen.transitionTo(UNINITIALIZED, INITIALIZED); mScreen.transitionTo(INITIALIZED, DOZE_AOD); diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java index fd31013db429..47933ba9fdaa 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java @@ -194,7 +194,7 @@ public class QSSecurityFooterTest extends SysuiTestCase { VPN_PACKAGE), mFooterText.getText()); assertEquals(View.VISIBLE, mFooterIcon.getVisibility()); - assertEquals(R.drawable.ic_qs_vpn, mFooterIcon.getLastImageResource()); + assertEquals(R.drawable.stat_sys_vpn_ic, mFooterIcon.getLastImageResource()); // Same situation, but with organization name set when(mSecurityController.getDeviceOwnerOrganizationName()) @@ -220,7 +220,7 @@ public class QSSecurityFooterTest extends SysuiTestCase { assertEquals(mContext.getString(R.string.quick_settings_disclosure_management_vpns), mFooterText.getText()); assertEquals(View.VISIBLE, mFooterIcon.getVisibility()); - assertEquals(R.drawable.ic_qs_vpn, mFooterIcon.getLastImageResource()); + assertEquals(R.drawable.stat_sys_vpn_ic, mFooterIcon.getLastImageResource()); // Same situation, but with organization name set when(mSecurityController.getDeviceOwnerOrganizationName()) @@ -243,7 +243,7 @@ public class QSSecurityFooterTest extends SysuiTestCase { TestableLooper.get(this).processAllMessages(); assertEquals(View.VISIBLE, mFooterIcon.getVisibility()); - assertEquals(R.drawable.ic_qs_vpn, mFooterIcon.getLastImageResource()); + assertEquals(R.drawable.stat_sys_vpn_ic, mFooterIcon.getLastImageResource()); assertEquals(mContext.getString(R.string.quick_settings_disclosure_management_monitoring), mFooterText.getText()); } @@ -294,7 +294,7 @@ public class QSSecurityFooterTest extends SysuiTestCase { mFooter.refreshState(); TestableLooper.get(this).processAllMessages(); - assertEquals(R.drawable.ic_qs_vpn, mFooterIcon.getLastImageResource()); + assertEquals(R.drawable.stat_sys_vpn_ic, mFooterIcon.getLastImageResource()); assertEquals(mContext.getString(R.string.quick_settings_disclosure_vpns), mFooterText.getText()); } @@ -306,7 +306,7 @@ public class QSSecurityFooterTest extends SysuiTestCase { mFooter.refreshState(); TestableLooper.get(this).processAllMessages(); - assertEquals(R.drawable.ic_qs_vpn, mFooterIcon.getLastImageResource()); + assertEquals(R.drawable.stat_sys_vpn_ic, mFooterIcon.getLastImageResource()); assertEquals(mContext.getString( R.string.quick_settings_disclosure_managed_profile_named_vpn, VPN_PACKAGE_2), @@ -320,7 +320,7 @@ public class QSSecurityFooterTest extends SysuiTestCase { mFooter.refreshState(); TestableLooper.get(this).processAllMessages(); - assertEquals(R.drawable.ic_qs_vpn, mFooterIcon.getLastImageResource()); + assertEquals(R.drawable.stat_sys_vpn_ic, mFooterIcon.getLastImageResource()); assertEquals(mContext.getString(R.string.quick_settings_disclosure_named_vpn, VPN_PACKAGE), mFooterText.getText()); diff --git a/packages/VpnDialogs/src/com/android/vpndialogs/ConfirmDialog.java b/packages/VpnDialogs/src/com/android/vpndialogs/ConfirmDialog.java index 72ce9c4efdc0..989470fdb2e9 100644 --- a/packages/VpnDialogs/src/com/android/vpndialogs/ConfirmDialog.java +++ b/packages/VpnDialogs/src/com/android/vpndialogs/ConfirmDialog.java @@ -29,6 +29,7 @@ import android.os.UserManager; import android.text.Html; import android.text.Html.ImageGetter; import android.util.Log; +import android.util.TypedValue; import android.view.View; import android.widget.Button; import android.widget.TextView; @@ -111,8 +112,16 @@ public class ConfirmDialog extends AlertActivity @Override public Drawable getDrawable(String source) { // Should only reach this when fetching the VPN icon for the warning string. - Drawable icon = getDrawable(R.drawable.ic_vpn_dialog); + final Drawable icon = getDrawable(R.drawable.ic_vpn_dialog); icon.setBounds(0, 0, icon.getIntrinsicWidth(), icon.getIntrinsicHeight()); + + final TypedValue tv = new TypedValue(); + if (getTheme().resolveAttribute(android.R.attr.textColorPrimary, tv, true)) { + icon.setTint(getColor(tv.resourceId)); + } else { + Log.w(TAG, "Unable to resolve theme color"); + } + return icon; } diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_bluetooth_share_icon.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_bluetooth_share_icon.xml new file mode 100644 index 000000000000..5f7d519ca996 --- /dev/null +++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_bluetooth_share_icon.xml @@ -0,0 +1,27 @@ +<!-- +/** + * Copyright (c) 2019, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:tint="@*android:color/accent_device_default" + android:viewportWidth="24" + android:viewportHeight="24"> + + <path + android:fillColor="@android:color/white" + android:pathData="M17.12,7.38c0-2.96-2.41-5.38-5.37-5.38H11v7.94L6.03,4.97c-0.29-0.29-0.77-0.29-1.06,0s-0.29,0.77,0,1.06L10.94,12 l-5.97,5.97c-0.29,0.29-0.29,0.77,0,1.06c0.15,0.15,0.34,0.22,0.53,0.22s0.38-0.07,0.53-0.22L11,14.06V22h0.75 c2.96,0,5.37-2.41,5.37-5.38c0-1.97-1.06-3.69-2.64-4.62C16.06,11.06,17.12,9.34,17.12,7.38z M15.62,16.62 c0,1.88-1.34,3.45-3.12,3.8v-7.6C14.28,13.17,15.62,14.75,15.62,16.62z M12.5,11.18v-7.6c1.78,0.35,3.12,1.92,3.12,3.8 S14.28,10.83,12.5,11.18z" /> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_qs_airplane.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_qs_airplane.xml new file mode 100644 index 000000000000..9743ceb327a7 --- /dev/null +++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_qs_airplane.xml @@ -0,0 +1,26 @@ +<!-- +/** + * Copyright (c) 2019, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="18dp" + android:height="18dp" + android:viewportWidth="24" + android:viewportHeight="24"> + + <path + android:fillColor="@android:color/white" + android:pathData="M22,15.89v-2.57c0-1.1-0.65-2.09-1.67-2.53L14.5,8.28V3.75c0-1.38-1.12-2.5-2.5-2.5s-2.5,1.12-2.5,2.5v4.53l-5.83,2.51 C2.65,11.22,2,12.22,2,13.32v2.57l7.5-1.28v3.03l-1.47,1.17C7.38,19.34,7,20.12,7,20.96v1.33l4.96-0.3L17,22.3v-1.33 c0-0.84-0.38-1.62-1.03-2.15l-1.47-1.17v-3.03L22,15.89z M15.03,19.98c0.23,0.18,0.38,0.44,0.44,0.72l-3.52-0.2l-3.43,0.2 c0.06-0.28,0.21-0.53,0.44-0.72L11,18.36v-5.53l-7.5,1.28v-0.79c0-0.5,0.3-0.95,0.76-1.15L11,9.27V3.75c0-0.55,0.45-1,1-1 s1,0.45,1,1v5.52l6.74,2.9c0.46,0.2,0.76,0.65,0.76,1.15v0.79L13,12.83v5.53L15.03,19.98z" /> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_qs_auto_rotate.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_qs_auto_rotate.xml new file mode 100644 index 000000000000..8dfa4a4f304c --- /dev/null +++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_qs_auto_rotate.xml @@ -0,0 +1,29 @@ +<!-- +/** + * Copyright (c) 2019, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<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="@android:color/white" + android:pathData="M2.75,6.5v4.75H7.5c0.41,0,0.75-0.34,0.75-0.75S7.91,9.75,7.5,9.75H5.39l4.5-4.22c0.89-0.84,2.27-0.82,3.13,0.05l4.94,4.95 c0.29,0.29,0.77,0.29,1.06,0c0.29-0.29,0.29-0.77,0-1.06l-4.94-4.95c-1.44-1.44-3.73-1.48-5.22-0.08L4.25,8.77V6.5 c0-0.41-0.34-0.75-0.75-0.75S2.75,6.09,2.75,6.5z" /> + <path + android:fillColor="@android:color/white" + android:pathData="M21.25,17.5v-4.75H16.5c-0.41,0-0.75,0.34-0.75,0.75s0.34,0.75,0.75,0.75h2.11l-4.5,4.22c-0.89,0.84-2.27,0.82-3.13-0.05 l-4.94-4.95c-0.29-0.29-0.77-0.29-1.06,0c-0.29,0.29-0.29,0.77,0,1.06l4.94,4.95c0.74,0.74,1.69,1.11,2.65,1.11 c0.92,0,1.84-0.34,2.57-1.02l4.62-4.33v2.27c0,0.41,0.34,0.75,0.75,0.75S21.25,17.91,21.25,17.5z" /> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_invert_colors.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_qs_bluetooth.xml index 0564c737c703..c12a2ebf4d9b 100644 --- a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_invert_colors.xml +++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_qs_bluetooth.xml @@ -21,8 +21,6 @@ android:viewportHeight="24"> <path - android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" /> - <path - android:fillColor="#000000" - android:pathData="M17.44,7.71,12.7,3a1,1,0,0,0-1.41,0h0L6.56,7.71a8.21,8.21,0,0,0-0.62,11.1,8,8,0,0,0,12.12,0A8.21,8.21,0,0,0,17.44,7.71ZM12,19.59A6,6,0,0,1,7.76,9.35L12,5.1Z" /> + android:fillColor="@android:color/white" + android:pathData="M17.12,7.38c0-2.96-2.41-5.38-5.37-5.38H11v7.94L6.03,4.97c-0.29-0.29-0.77-0.29-1.06,0s-0.29,0.77,0,1.06L10.94,12 l-5.97,5.97c-0.29,0.29-0.29,0.77,0,1.06c0.15,0.15,0.34,0.22,0.53,0.22s0.38-0.07,0.53-0.22L11,14.06V22h0.75 c2.96,0,5.37-2.41,5.37-5.38c0-1.97-1.06-3.69-2.64-4.62C16.06,11.06,17.12,9.34,17.12,7.38z M15.62,16.62 c0,1.88-1.34,3.45-3.12,3.8v-7.6C14.28,13.17,15.62,14.75,15.62,16.62z M12.5,11.18v-7.6c1.78,0.35,3.12,1.92,3.12,3.8 S14.28,10.83,12.5,11.18z" /> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_dnd.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_qs_dnd.xml index 3e32b3bd6664..d36464600e2e 100644 --- a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_dnd.xml +++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_qs_dnd.xml @@ -15,19 +15,15 @@ */ --> <vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" + android:width="17dp" + android:height="17dp" android:viewportWidth="24" android:viewportHeight="24"> <path - android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" /> + android:fillColor="@android:color/white" + android:pathData="M12,22c5.52,0,10-4.48,10-10c0-5.52-4.48-10-10-10S2,6.48,2,12C2,17.52,6.48,22,12,22z M12,3.5c4.69,0,8.5,3.81,8.5,8.5 c0,4.69-3.81,8.5-8.5,8.5S3.5,16.69,3.5,12C3.5,7.31,7.31,3.5,12,3.5z" /> <path - android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" /> - <path - android:fillColor="#000000" - android:pathData="M12,22A10,10,0,1,0,2,12,10,10,0,0,0,12,22ZM12,3a9,9,0,1,1-9,9A9,9,0,0,1,12,3Z" /> - <path - android:fillColor="#000000" - android:pathData="M7,12.5H17a0.5 0.5 ,0,0,0,0-1H7a0.5 0.5 ,0,0,0,0,1Z" /> + android:fillColor="@android:color/white" + android:pathData="M6.75,12.75h10.5c0.41,0,0.75-0.34,0.75-0.75s-0.34-0.75-0.75-0.75H6.75C6.34,11.25,6,11.59,6,12S6.34,12.75,6.75,12.75z" /> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_signal_flashlight.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_qs_flashlight.xml index 15266910de6c..cce36e30d753 100644 --- a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_signal_flashlight.xml +++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_qs_flashlight.xml @@ -21,13 +21,9 @@ android:viewportHeight="24"> <path - android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" /> + android:fillColor="@android:color/white" + android:pathData="M11,22h2c1.1,0,2-0.9,2-2V10c1.95-1.17,3-3.5,3-6V3H6v1c0,2.5,1.05,4.83,3,6v10C9,21.1,9.9,22,11,22z M16.48,4.5 C16.45,5.03,16.35,5.53,16.2,6H7.8C7.65,5.53,7.55,5.03,7.52,4.5H16.48z M8.51,7.5h6.99c-0.35,0.5-0.77,0.92-1.26,1.21L13.5,9.15 V20c0,0.28-0.22,0.5-0.5,0.5h-2c-0.28,0-0.5-0.22-0.5-0.5V9.15L9.77,8.71C9.28,8.42,8.85,8,8.51,7.5z" /> <path - android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" /> - <path - android:fillColor="#000000" - android:pathData="M11,22h2a2,2,0,0,0,2-2V10a6.84,6.84,0,0,0,3-6V3H6V4a6.84,6.84,0,0,0,3,6V20A2,2,0,0,0,11,22ZM17,4a8.26,8.26,0,0,1-0.07,1H7.07A8.26,8.26,0,0,1,7,4ZM7.28,6h9.45a5.24,5.24,0,0,1-2.24,3.14L14,9.43V20a1,1,0,0,1-1,1H11a1,1,0,0,1-1-1V9.43l-0.49-0.29A5.25,5.25,0,0,1,7.28,6Z" /> - <path - android:fillColor="#000000" + android:fillColor="@android:color/white" android:pathData="M 12 13 C 12.5522847498 13 13 13.4477152502 13 14 C 13 14.5522847498 12.5522847498 15 12 15 C 11.4477152502 15 11 14.5522847498 11 14 C 11 13.4477152502 11.4477152502 13 12 13 Z" /> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_settings_bluetooth.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_settings_bluetooth.xml new file mode 100644 index 000000000000..c12a2ebf4d9b --- /dev/null +++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_settings_bluetooth.xml @@ -0,0 +1,26 @@ +<!-- +/** + * Copyright (c) 2019, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<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="@android:color/white" + android:pathData="M17.12,7.38c0-2.96-2.41-5.38-5.37-5.38H11v7.94L6.03,4.97c-0.29-0.29-0.77-0.29-1.06,0s-0.29,0.77,0,1.06L10.94,12 l-5.97,5.97c-0.29,0.29-0.29,0.77,0,1.06c0.15,0.15,0.34,0.22,0.53,0.22s0.38-0.07,0.53-0.22L11,14.06V22h0.75 c2.96,0,5.37-2.41,5.37-5.38c0-1.97-1.06-3.69-2.64-4.62C16.06,11.06,17.12,9.34,17.12,7.38z M15.62,16.62 c0,1.88-1.34,3.45-3.12,3.8v-7.6C14.28,13.17,15.62,14.75,15.62,16.62z M12.5,11.18v-7.6c1.78,0.35,3.12,1.92,3.12,3.8 S14.28,10.83,12.5,11.18z" /> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_airplanemode_active.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_airplanemode_active.xml new file mode 100644 index 000000000000..8dbae49a1cb3 --- /dev/null +++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_airplanemode_active.xml @@ -0,0 +1,26 @@ +<!-- +/** + * Copyright (c) 2019, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<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="@android:color/white" + android:pathData="M22,15.89v-2.57c0-1.1-0.65-2.09-1.67-2.53L14.5,8.28V3.75c0-1.38-1.12-2.5-2.5-2.5s-2.5,1.12-2.5,2.5v4.53l-5.83,2.51 C2.65,11.22,2,12.22,2,13.32v2.57l7.5-1.28v3.03l-1.47,1.17C7.38,19.34,7,20.12,7,20.96v1.33l4.96-0.3L17,22.3v-1.33 c0-0.84-0.38-1.62-1.03-2.15l-1.47-1.17v-3.03L22,15.89z M15.03,19.98c0.23,0.18,0.38,0.44,0.44,0.72l-3.52-0.2l-3.43,0.2 c0.06-0.28,0.21-0.53,0.44-0.72L11,18.36v-5.53l-7.5,1.28v-0.79c0-0.5,0.3-0.95,0.76-1.15L11,9.27V3.75c0-0.55,0.45-1,1-1 s1,0.45,1,1v5.52l6.74,2.9c0.46,0.2,0.76,0.65,0.76,1.15v0.79L13,12.83v5.53L15.03,19.98z" /> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_lockscreen_ime.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_lockscreen_ime.xml deleted file mode 100644 index 04a2c24ce45a..000000000000 --- a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_lockscreen_ime.xml +++ /dev/null @@ -1,57 +0,0 @@ -<!-- -/** - * Copyright (c) 2019, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" - android:viewportWidth="24" - android:viewportHeight="24"> - - <path - android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" /> - <path - android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" /> - <path - android:fillColor="#000000" - android:pathData="M21,21a2,2,0,0,0,2-2V6a2,2,0,0,0-2-2H3A2,2,0,0,0,1,6V19a2,2,0,0,0,2,2ZM2,19V6A1,1,0,0,1,3,5H21a1,1,0,0,1,1,1V19a1,1,0,0,1-1,1H3A1,1,0,0,1,2,19Z" /> - <path - android:fillColor="#000000" - android:pathData="M 9.5 8 L 10.5 8 Q 11 8 11 8.5 L 11 9.5 Q 11 10 10.5 10 L 9.5 10 Q 9 10 9 9.5 L 9 8.5 Q 9 8 9.5 8 Z" /> - <path - android:fillColor="#000000" - android:pathData="M 5.5 8 L 6.5 8 Q 7 8 7 8.5 L 7 9.5 Q 7 10 6.5 10 L 5.5 10 Q 5 10 5 9.5 L 5 8.5 Q 5 8 5.5 8 Z" /> - <path - android:fillColor="#000000" - android:pathData="M 13.5 8 L 14.5 8 Q 15 8 15 8.5 L 15 9.5 Q 15 10 14.5 10 L 13.5 10 Q 13 10 13 9.5 L 13 8.5 Q 13 8 13.5 8 Z" /> - <path - android:fillColor="#000000" - android:pathData="M 9.5 12 L 10.5 12 Q 11 12 11 12.5 L 11 13.5 Q 11 14 10.5 14 L 9.5 14 Q 9 14 9 13.5 L 9 12.5 Q 9 12 9.5 12 Z" /> - <path - android:fillColor="#000000" - android:pathData="M 5.5 12 L 6.5 12 Q 7 12 7 12.5 L 7 13.5 Q 7 14 6.5 14 L 5.5 14 Q 5 14 5 13.5 L 5 12.5 Q 5 12 5.5 12 Z" /> - <path - android:fillColor="#000000" - android:pathData="M 13.5 12 L 14.5 12 Q 15 12 15 12.5 L 15 13.5 Q 15 14 14.5 14 L 13.5 14 Q 13 14 13 13.5 L 13 12.5 Q 13 12 13.5 12 Z" /> - <path - android:fillColor="#000000" - android:pathData="M 17.5 8 L 18.5 8 Q 19 8 19 8.5 L 19 9.5 Q 19 10 18.5 10 L 17.5 10 Q 17 10 17 9.5 L 17 8.5 Q 17 8 17.5 8 Z" /> - <path - android:fillColor="#000000" - android:pathData="M 17.5 12 L 18.5 12 Q 19 12 19 12.5 L 19 13.5 Q 19 14 18.5 14 L 17.5 14 Q 17 14 17 13.5 L 17 12.5 Q 17 12 17.5 12 Z" /> - <path - android:fillColor="#000000" - android:pathData="M8.5,17h7a0.5 0.5 ,0,0,0,0-1h-7a0.5 0.5 ,0,0,0,0,1Z" /> -</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_brightness_auto_on.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_brightness_auto_on.xml deleted file mode 100644 index fc990d87f2fb..000000000000 --- a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_brightness_auto_on.xml +++ /dev/null @@ -1,33 +0,0 @@ -<!-- -/** - * Copyright (c) 2019, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" - android:viewportWidth="24" - android:viewportHeight="24"> - - <path - android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" /> - <path - android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" /> - <path - android:fillColor="#000000" - android:pathData="M3.41,14.72A2,2,0,0,1,4,16.14V18a2,2,0,0,0,2,2H7.86a2,2,0,0,1,1.42 0.59 l1.31,1.31a2,2,0,0,0,2.82,0l1.31-1.31A2,2,0,0,1,16.14,20H18a2,2,0,0,0,2-2V16.14a2,2,0,0,1,0.59-1.42l1.31-1.31a2,2,0,0,0,0-2.82L20.59,9.28A2,2,0,0,1,20,7.86V6a2,2,0,0,0-2-2H16.14a2,2,0,0,1-1.42-0.59L13.41,2.1a2,2,0,0,0-2.82,0L9.28,3.41A2,2,0,0,1,7.86,4H6A2,2,0,0,0,4,6V7.86a2,2,0,0,1-0.59,1.42L2.1,10.59a2,2,0,0,0,0,2.82Zm-0.6-3.43L4.12,10A3,3,0,0,0,5,7.86V6A1,1,0,0,1,6,5H7.86A3,3,0,0,0,10,4.12l1.31-1.31a1,1,0,0,1,1.42,0L14,4.12A3,3,0,0,0,16.14,5H18a1,1,0,0,1,1,1V7.86A3,3,0,0,0,19.88,10l1.31,1.31a1,1,0,0,1,0,1.42L19.88,14A3,3,0,0,0,19,16.14V18a1,1,0,0,1-1,1H16.14a3,3,0,0,0-2.12 0.88 l-1.31,1.31a1,1,0,0,1-1.42,0L10,19.88A3,3,0,0,0,7.86,19H6a1,1,0,0,1-1-1V16.14A3,3,0,0,0,4.12,14L2.81,12.71a1,1,0,0,1,0-1.42Z" /> - <path - android:fillColor="#000000" - android:pathData="M10,14.61h4L14.85,17H17L13.11,7H10.87L7,17H9.15Zm1.92-5.44h0.11l1.29,3.71H10.63Z" /> -</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_cast_on.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_cast_on.xml deleted file mode 100644 index d12cf9ee85fd..000000000000 --- a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_cast_on.xml +++ /dev/null @@ -1,42 +0,0 @@ -<!-- -/** - * Copyright (c) 2019, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" - android:viewportWidth="24" - android:viewportHeight="24"> - - <path - android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" /> - <path - android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" /> - <path - android:fillColor="#000000" - android:pathData="M22,17.5V6.5A2.5,2.5,0,0,0,19.5,4H4.5A2.5,2.5,0,0,0,2,6.5v2a0.5 0.5 ,0,0,0,1,0v-2A1.5,1.5,0,0,1,4.5,5h15A1.5,1.5,0,0,1,21,6.5v11A1.5,1.5,0,0,1,19.5,19h-6a0.5 0.5 ,0,0,0,0,1h6A2.5,2.5,0,0,0,22,17.5Z" /> - <path - android:fillColor="#000000" - android:pathData="M2.21,19.61A1,1,0,0,0,3,20a1,1,0,0,0,0-2H3a1,1,0,0,0-0.79,1.61Z" /> - <path - android:fillColor="#000000" - android:pathData="M2.5,12A7.5,7.5,0,0,1,10,19.5a0.5 0.5 ,0,0,0,1,0A8.51,8.51,0,0,0,2.5,11a0.5 0.5 ,0,0,0,0,1Z" /> - <path - android:fillColor="#000000" - android:pathData="M2.5,16A3.5,3.5,0,0,1,6,19.5a0.5 0.5 ,0,0,0,1,0A4.51,4.51,0,0,0,2.5,15a0.5 0.5 ,0,0,0,0,1Z" /> - <path - android:fillColor="#000000" - android:pathData="M16.5,15h-3a0.5 0.5 ,0,0,0,0,1h3A1.5,1.5,0,0,0,18,14.5v-5A1.5,1.5,0,0,0,16.5,8H6.5a0.5 0.5 ,0,0,0,0,1h10a0.5 0.5 ,0,0,1,0.5 0.5 v5A0.5 0.5 ,0,0,1,16.5,15Z" /> -</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_settings_16dp.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_settings_16dp.xml deleted file mode 100644 index 33d172cd2517..000000000000 --- a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_settings_16dp.xml +++ /dev/null @@ -1,33 +0,0 @@ -<!-- -/** - * Copyright (c) 2019, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="16dp" - android:height="16dp" - android:viewportWidth="24" - android:viewportHeight="24"> - - <path - android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" /> - <path - android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" /> - <path - android:fillColor="#000000" - android:pathData="M5.31,19.26a1.6,1.6,0,0,0,0.53-0.09l1.8-0.7c0.26 0.16 0.52 0.31 0.79 0.45 l0.27,1.84A1.44,1.44,0,0,0,10.15,22h3.7a1.46,1.46,0,0,0,1.46-1.19l0.27-1.87c0.26-0.13 0.52 -0.28 0.78 -0.44l1.8 0.7 a1.47,1.47,0,0,0,0.54 0.1 A1.44,1.44,0,0,0,20,18.58l1.86-3.14a1.4,1.4,0,0,0-0.37-1.81l-1.52-1.17c0-0.14,0-0.29,0-0.45s0-0.3,0-0.44l1.52-1.17a1.41,1.41,0,0,0,0.36-1.83L20,5.47a1.46,1.46,0,0,0-1.29-0.73,1.69,1.69,0,0,0-0.53 0.09 l-1.8 0.7 c-0.26-0.16-0.52-0.31-0.79-0.45l-0.27-1.84A1.44,1.44,0,0,0,13.84,2h-3.7A1.45,1.45,0,0,0,8.7,3.22L8.43,5.08q-0.39 0.21 -0.78 0.45 L5.84,4.82a1.47,1.47,0,0,0-0.54-0.1,1.43,1.43,0,0,0-1.25 0.72 L2.2,8.55a1.37,1.37,0,0,0,0.37,1.83l1.52,1.17c0,0.14,0,0.3,0,0.45s0,0.3,0,0.44L2.56,13.61a1.42,1.42,0,0,0-0.36,1.83L4,18.53A1.46,1.46,0,0,0,5.31,19.26ZM3.16,14.4l1.53-1.16 0.43 -0.33,0-0.53c0-0.13,0-0.25,0-0.38s0-0.26,0-0.39l0-0.53-0.42-0.33L3.17,9.58a0.38 0.38 ,0,0,1-0.11-0.52L4.92,5.93a0.43 0.43 ,0,0,1,0.38-0.21 0.47 0.47,0,0,1,0.17,0l1.81 0.71 0.48 0.19 0.43-0.27A6.39,6.39,0,0,1,8.9,6l0.45-0.24 0.07 -0.5 0.27 -1.88A0.44 0.44 ,0,0,1,10.14,3h3.7a0.44 0.44 ,0,0,1,0.46 0.38 l0.27,1.85 0.08 0.51 0.46 0.24a5.3,5.3,0,0,1,0.7 0.4 l0.43 0.27 0.47-0.19,1.78-0.69a0.63 0.63 ,0,0,1,0.19,0,0.47 0.47 ,0,0,1,0.43 0.24 l1.83,3.08a0.42 0.42 ,0,0,1-0.1 0.55 l-1.52,1.16-0.42 0.33 ,0,0.53c0,0.13,0,0.25,0,0.38s0,0.26,0,0.39l0,0.53 0.42 0.33,1.51,1.15a0.42 0.42 ,0,0,1,0.13 0.52 l-1.87,3.16a0.43 0.43 ,0,0,1-0.39 0.21 0.57 0.57 ,0,0,1-0.18,0l-1.8-0.71-0.47-0.18-0.43 0.27 a7.46,7.46,0,0,1-0.71 0.41 l-0.45 0.24 -0.07 0.5 -0.27,1.86a0.47 0.47 ,0,0,1-0.47 0.34 h-3.7a0.44 0.44 ,0,0,1-0.46-0.38l-0.27-1.85-0.08-0.51L8.88,18a5.3,5.3,0,0,1-0.7-0.4l-0.43-0.27-0.47 0.19 -1.78 0.69 a0.58 0.58 ,0,0,1-0.19,0A0.48 0.48 ,0,0,1,4.89,18L3.08,15A0.42 0.42 ,0,0,1,3.16,14.4Z" /> - <path - android:fillColor="#000000" - android:pathData="M12,15.91A3.92,3.92,0,1,0,8,12,4,4,0,0,0,12,15.91Zm0-6.83A2.92,2.92,0,1,1,9,12,3,3,0,0,1,12,9.08Z" /> -</vector> diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_signal_airplane.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_signal_airplane.xml deleted file mode 100644 index a5ef380c4a4d..000000000000 --- a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_signal_airplane.xml +++ /dev/null @@ -1,30 +0,0 @@ -<!-- -/** - * Copyright (c) 2019, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" - android:viewportWidth="24" - android:viewportHeight="24"> - - <path - android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" /> - <path - android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" /> - <path - android:fillColor="#000000" - android:pathData="M2.8,15l7.2-0.73v3.49L8,19.38a1.52,1.52,0,0,0-0.54,1.16v1a0.52 0.52 ,0,0,0,0.17 0.38 0.51 0.51 ,0,0,0,0.39 0.12 L12,21.5l3.94 0.5 H16a0.5 0.5 ,0,0,0,0.33-0.12 0.52 0.52,0,0,0,0.17-0.38v-1A1.52,1.52,0,0,0,16,19.38l-2-1.62V14.27l7.2 0.73 a0.51 0.51 ,0,0,0,0.55-0.5,3.49,3.49,0,0,0-2.15-3.23L14,8.94V3.5a2,2,0,0,0-4,0V8.94L4.4,11.27A3.49,3.49,0,0,0,2.25,14.5a0.51 0.51 ,0,0,0,0.55 0.5 Zm2-2.81,5.9-2.45A0.5 0.5 ,0,0,0,11,9.28V3.5a1,1,0,0,1,2,0V9.28a0.5 0.5 ,0,0,0,0.31 0.46 l5.9,2.45a2.51,2.51,0,0,1,1.48,1.75l-7.14-0.72a0.52 0.52 ,0,0,0-0.38 0.13 0.5 0.5 ,0,0,0-0.17 0.37 V18a0.53 0.53 ,0,0,0,0.18 0.39 l2.14,1.76a0.53 0.53 ,0,0,1,0.18 0.39 v0.39l-3.44-0.43h-0.12l-3.44 0.43 v-0.39a0.53 0.53 ,0,0,1,0.18-0.39l2.14-1.76A0.53 0.53 ,0,0,0,11,18V13.72a0.5 0.5 ,0,0,0-0.17-0.37 0.52 0.52,0,0,0-0.38-0.13l-7.14 0.72 A2.51,2.51,0,0,1,4.79,12.19Z" /> -</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_bluetooth_share_icon.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_bluetooth_share_icon.xml new file mode 100644 index 000000000000..c5c3f0644de6 --- /dev/null +++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_bluetooth_share_icon.xml @@ -0,0 +1,27 @@ +<!-- +/** + * Copyright (c) 2019, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:tint="@*android:color/accent_device_default" + android:viewportWidth="24" + android:viewportHeight="24"> + + <path + android:fillColor="@android:color/white" + android:pathData="M17.21,6.79l-4.5-4.5c-0.29-0.29-0.72-0.37-1.09-0.22C11.25,2.23,11,2.6,11,3v6.59l-3.8-3.8c-0.39-0.39-1.02-0.39-1.41,0 c-0.39,0.39-0.39,1.02,0,1.41l4.8,4.8l-4.8,4.8c-0.39,0.39-0.39,1.02,0,1.41c0.39,0.39,1.02,0.39,1.41,0l3.8-3.8V21 c0,0.4,0.24,0.77,0.62,0.92C11.74,21.98,11.87,22,12,22c0.26,0,0.52-0.1,0.71-0.29l4.5-4.5c0.39-0.39,0.39-1.02,0-1.41L13.42,12 l3.79-3.79C17.6,7.82,17.6,7.18,17.21,6.79z M15.09,16.5L13,18.58v-4.17L15.09,16.5z M13,9.58V5.42l2.08,2.08L13,9.58z" /> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_qs_airplane.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_qs_airplane.xml new file mode 100644 index 000000000000..85260c0d0614 --- /dev/null +++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_qs_airplane.xml @@ -0,0 +1,26 @@ +<!-- +/** + * Copyright (c) 2019, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="18dp" + android:height="18dp" + android:viewportWidth="24" + android:viewportHeight="24"> + + <path + android:fillColor="@android:color/white" + android:pathData="M2.65,15.8L10,13.5V19l-1.6,1.2C8.15,20.39,8,20.69,8,21v0.67c0,0.17,0.14,0.28,0.31,0.24c1.94-0.55,1.3-0.37,3.19-0.91 c1.21,0.35,1.99,0.57,3.19,0.91c0.17,0.04,0.31-0.07,0.31-0.24V21c0-0.31-0.15-0.61-0.4-0.8L13,19v-5.5l7.35,2.3 c0.32,0.1,0.65-0.14,0.65-0.48v-0.49c0-0.52-0.27-1-0.7-1.27L13,9V3.5C13,2.67,12.33,2,11.5,2S10,2.67,10,3.5V9l-7.3,4.56 C2.27,13.83,2,14.31,2,14.83v0.49C2,15.66,2.33,15.9,2.65,15.8z" /> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_auto_rotate.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_qs_auto_rotate.xml index f823812ddf3f..bcdb618f8b24 100644 --- a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_auto_rotate.xml +++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_qs_auto_rotate.xml @@ -21,11 +21,9 @@ android:viewportHeight="24"> <path - android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" /> + android:fillColor="@android:color/white" + android:pathData="M16.41,10.96h2.83l-8.18-8.18c-0.62-0.62-1.65-0.6-2.29,0.04L4.27,7.31L2.85,5.89C2.54,5.58,2,5.8,2,6.25v4.25 C2,10.78,2.22,11,2.5,11h4.25c0.45,0,0.67-0.54,0.35-0.85L5.69,8.73l4.24-4.24L16.41,10.96z" /> <path - android:fillColor="#000000" - android:pathData="M16.41,11h2.83L11.05,2.78a1.62,1.62,0,0,0-2.29,0L4.27,7.31,2.85,5.89A0.5 0.5 ,0,0,0,2,6.25V10.5a0.5 0.5 ,0,0,0,0.5 0.5 H6.75a0.5 0.5 ,0,0,0,0.36-0.85L5.69,8.73,9.93,4.49Z" /> - <path - android:fillColor="#000000" - android:pathData="M22,13.51a0.5 0.5 ,0,0,0-0.5-0.5H17.25a0.5 0.5 ,0,0,0-0.36 0.85 l1.35,1.35-4.31,4.31L7.44,13H4.61l8.19,8.18a1.62,1.62,0,0,0,2.29,0l4.57-4.55,1.49,1.49a0.5 0.5 ,0,0,0,0.85-0.36Z" /> + android:fillColor="@android:color/white" + android:pathData="M22,13.51c0-0.28-0.22-0.5-0.5-0.5h-4.25c-0.45,0-0.67,0.54-0.35,0.85l1.34,1.34l-4.31,4.31l-6.48-6.48H4.61l8.19,8.19 c0.62,0.62,1.65,0.6,2.29-0.04l4.57-4.55l1.49,1.49c0.32,0.31,0.85,0.09,0.85-0.35V13.51z" /> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_qs_bluetooth.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_qs_bluetooth.xml new file mode 100644 index 000000000000..cf7cab5d5e64 --- /dev/null +++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_qs_bluetooth.xml @@ -0,0 +1,26 @@ +<!-- +/** + * Copyright (c) 2019, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<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="@android:color/white" + android:pathData="M17.21,6.79l-4.5-4.5c-0.29-0.29-0.72-0.37-1.09-0.22C11.25,2.23,11,2.6,11,3v6.59l-3.8-3.8c-0.39-0.39-1.02-0.39-1.41,0 c-0.39,0.39-0.39,1.02,0,1.41l4.8,4.8l-4.8,4.8c-0.39,0.39-0.39,1.02,0,1.41c0.39,0.39,1.02,0.39,1.41,0l3.8-3.8V21 c0,0.4,0.24,0.77,0.62,0.92C11.74,21.98,11.87,22,12,22c0.26,0,0.52-0.1,0.71-0.29l4.5-4.5c0.39-0.39,0.39-1.02,0-1.41L13.42,12 l3.79-3.79C17.6,7.82,17.6,7.18,17.21,6.79z M15.09,16.5L13,18.58v-4.17L15.09,16.5z M13,9.58V5.42l2.08,2.08L13,9.58z" /> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_dnd.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_qs_dnd.xml index e6086f3813c1..a094698a5d3f 100644 --- a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_dnd.xml +++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_qs_dnd.xml @@ -15,14 +15,12 @@ */ --> <vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" + android:width="17dp" + android:height="17dp" android:viewportWidth="24" android:viewportHeight="24"> <path - android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" /> - <path - android:fillColor="#000000" - android:pathData="M12,22A10,10,0,1,0,2,12,10,10,0,0,0,12,22ZM8,11h8a1,1,0,0,1,0,2H8a1,1,0,0,1,0-2Z" /> + android:fillColor="@android:color/white" + android:pathData="M12,22c5.52,0,10-4.48,10-10c0-5.52-4.48-10-10-10S2,6.48,2,12C2,17.52,6.48,22,12,22z M8,11h8c0.55,0,1,0.45,1,1 s-0.45,1-1,1H8c-0.55,0-1-0.45-1-1S7.45,11,8,11z" /> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_signal_flashlight.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_qs_flashlight.xml index 1ffb32b90144..4427305c4b0b 100644 --- a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_signal_flashlight.xml +++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_qs_flashlight.xml @@ -21,11 +21,9 @@ android:viewportHeight="24"> <path - android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" /> + android:fillColor="@android:color/white" + android:pathData="M10,22h4c0.55,0,1-0.45,1-1V10c1.1,0,2-0.9,2-2V5.5H7V8c0,1.1,0.9,2,2,2v11C9,21.55,9.45,22,10,22z M11,12 c0-0.55,0.45-1,1-1s1,0.45,1,1v2c0,0.55-0.45,1-1,1s-1-0.45-1-1V12z" /> <path - android:fillColor="#000000" - android:pathData="M10,22h4a1,1,0,0,0,1-1V10a2,2,0,0,0,2-2V5.5H7V8a2,2,0,0,0,2,2V21A1,1,0,0,0,10,22Zm2-10a1.5,1.5,0,1,1-1.5,1.5A1.5,1.5,0,0,1,12,12Z" /> - <path - android:fillColor="#000000" - android:pathData="M17,3a1,1,0,0,0-1-1H8A1,1,0,0,0,7,3V4H17Z" /> + android:fillColor="@android:color/white" + android:pathData="M17,3c0-0.55-0.45-1-1-1H8C7.45,2,7,2.45,7,3v0.96h10V3z" /> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_settings_bluetooth.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_settings_bluetooth.xml new file mode 100644 index 000000000000..cf7cab5d5e64 --- /dev/null +++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_settings_bluetooth.xml @@ -0,0 +1,26 @@ +<!-- +/** + * Copyright (c) 2019, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<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="@android:color/white" + android:pathData="M17.21,6.79l-4.5-4.5c-0.29-0.29-0.72-0.37-1.09-0.22C11.25,2.23,11,2.6,11,3v6.59l-3.8-3.8c-0.39-0.39-1.02-0.39-1.41,0 c-0.39,0.39-0.39,1.02,0,1.41l4.8,4.8l-4.8,4.8c-0.39,0.39-0.39,1.02,0,1.41c0.39,0.39,1.02,0.39,1.41,0l3.8-3.8V21 c0,0.4,0.24,0.77,0.62,0.92C11.74,21.98,11.87,22,12,22c0.26,0,0.52-0.1,0.71-0.29l4.5-4.5c0.39-0.39,0.39-1.02,0-1.41L13.42,12 l3.79-3.79C17.6,7.82,17.6,7.18,17.21,6.79z M15.09,16.5L13,18.58v-4.17L15.09,16.5z M13,9.58V5.42l2.08,2.08L13,9.58z" /> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_invert_colors.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_airplanemode_active.xml index 59e7838b9c67..bddc57ee70a7 100644 --- a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_invert_colors.xml +++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_airplanemode_active.xml @@ -21,10 +21,6 @@ android:viewportHeight="24"> <path - android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" /> - <path - android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" /> - <path - android:fillColor="#000000" - android:pathData="M12.62,2.23A1,1,0,0,0,12,2a1.07,1.07,0,0,0-0.63 0.22 C9.48,3.75,4,8.5,4,14a7.89,7.89,0,0,0,8,8,8,8,0,0,0,8-8C20,8.5,14.5,3.73,12.62,2.23ZM12,21a6.92,6.92,0,0,1-7-7C5,9.16,9.89,4.71,12,3Z" /> + android:fillColor="@android:color/white" + android:pathData="M2.65,15.8L10,13.5V19l-1.6,1.2C8.15,20.39,8,20.69,8,21v0.67c0,0.17,0.14,0.28,0.31,0.24c1.94-0.55,1.3-0.37,3.19-0.91 c1.21,0.35,1.99,0.57,3.19,0.91c0.17,0.04,0.31-0.07,0.31-0.24V21c0-0.31-0.15-0.61-0.4-0.8L13,19v-5.5l7.35,2.3 c0.32,0.1,0.65-0.14,0.65-0.48v-0.49c0-0.52-0.27-1-0.7-1.27L13,9V3.5C13,2.67,12.33,2,11.5,2S10,2.67,10,3.5V9l-7.3,4.56 C2.27,13.83,2,14.31,2,14.83v0.49C2,15.66,2.33,15.9,2.65,15.8z" /> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_lockscreen_ime.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_lockscreen_ime.xml deleted file mode 100644 index 8b9f5627a98b..000000000000 --- a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_lockscreen_ime.xml +++ /dev/null @@ -1,55 +0,0 @@ -<!-- -/** - * Copyright (c) 2019, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" - android:viewportWidth="24" - android:viewportHeight="24"> - - <path - android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" /> - <path - android:fillColor="#000000" - android:pathData="M3,21H21a2,2,0,0,0,2-2V6a2,2,0,0,0-2-2H3A2,2,0,0,0,1,6V19A2,2,0,0,0,3,21ZM3,6H21V19H3Z" /> - <path - android:fillColor="#000000" - android:pathData="M 9 8 H 11 V 10 H 9 V 8 Z" /> - <path - android:fillColor="#000000" - android:pathData="M 5 8 H 7 V 10 H 5 V 8 Z" /> - <path - android:fillColor="#000000" - android:pathData="M 8 16 H 16 V 17 H 8 V 16 Z" /> - <path - android:fillColor="#000000" - android:pathData="M 13 8 H 15 V 10 H 13 V 8 Z" /> - <path - android:fillColor="#000000" - android:pathData="M 9 12 H 11 V 14 H 9 V 12 Z" /> - <path - android:fillColor="#000000" - android:pathData="M 5 12 H 7 V 14 H 5 V 12 Z" /> - <path - android:fillColor="#000000" - android:pathData="M 13 12 H 15 V 14 H 13 V 12 Z" /> - <path - android:fillColor="#000000" - android:pathData="M 17 8 H 19 V 10 H 17 V 8 Z" /> - <path - android:fillColor="#000000" - android:pathData="M 17 12 H 19 V 14 H 17 V 12 Z" /> -</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_brightness_auto_on.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_brightness_auto_on.xml deleted file mode 100644 index f3b1c016c301..000000000000 --- a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_brightness_auto_on.xml +++ /dev/null @@ -1,31 +0,0 @@ -<!-- -/** - * Copyright (c) 2019, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" - android:viewportWidth="24" - android:viewportHeight="24"> - - <path - android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" /> - <path - android:fillColor="#000000" - android:pathData="M10,14.61h4L14.85,17H17L13.11,7H10.87L7,17H9.15Zm1.54-4.24 0.38 -1.2h0.11l0.38,1.2 0.91 ,2.51H10.63Z" /> - <path - android:fillColor="#000000" - android:pathData="M4,20H8.69L12,23.31,15.31,20H20V15.31L23.31,12,20,8.69V4H15.31L12,0.69,8.69,4H4V8.69L0.69,12,4,15.31Zm-0.48-8L6,9.52V6H9.52L12,3.52,14.48,6H18V9.52L20.48,12,18,14.48V18H14.48L12,20.48,9.52,18H6V14.48Z" /> -</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_cast_on.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_cast_on.xml deleted file mode 100644 index 0fd763b8d325..000000000000 --- a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_cast_on.xml +++ /dev/null @@ -1,40 +0,0 @@ -<!-- -/** - * Copyright (c) 2019, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" - android:viewportWidth="24" - android:viewportHeight="24"> - - <path - android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" /> - <path - android:fillColor="#000000" - android:pathData="M1.82,16.08a5,5,0,0,1,4.1,4.08,1,1,0,0,0,1,0.84,1,1,0,0,0,1-1.14,7,7,0,0,0-5.8-5.78,1,1,0,0,0-0.29,2Z" /> - <path - android:fillColor="#000000" - android:pathData="M19,7H5V8.63A13,13,0,0,1,13.37,17H19Z" /> - <path - android:fillColor="#000000" - android:pathData="M3,5H21V19H14v2h7a2,2,0,0,0,2-2V5a2,2,0,0,0-2-2H3A2,2,0,0,0,1,5V8H3Z" /> - <path - android:fillColor="#000000" - android:pathData="M1.85,12A9.06,9.06,0,0,1,10,20.12a1,1,0,0,0,1,0.88,1,1,0,0,0,1-1.1,11,11,0,0,0-9.87-9.85A1,1,0,0,0,1,11,1,1,0,0,0,1.85,12Z" /> - <path - android:fillColor="#000000" - android:pathData="M2,21H4a3,3,0,0,0-3-3v2A1,1,0,0,0,2,21Z" /> -</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_settings_16dp.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_settings_16dp.xml deleted file mode 100644 index d292b13c8faf..000000000000 --- a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_settings_16dp.xml +++ /dev/null @@ -1,28 +0,0 @@ -<!-- -/** - * Copyright (c) 2019, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="16dp" - android:height="16dp" - android:viewportWidth="24" - android:viewportHeight="24"> - - <path - android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" /> - <path - android:fillColor="#000000" - android:pathData="M21.64,8.39,20,5.63a1.12,1.12,0,0,0-1.36-0.5L16.54,6A7.26,7.26,0,0,0,15,5.12l-0.27-2.2A1.1,1.1,0,0,0,13.59,2H10.41a1.1,1.1,0,0,0-1.11 0.92 L9,5.11A7.1,7.1,0,0,0,7.46,6L5.32,5.12A1.12,1.12,0,0,0,4,5.62L2.36,8.38A1.1,1.1,0,0,0,2.6,9.8l1.94,1.45a6.06,6.06,0,0,0,0,0.75,6.34,6.34,0,0,0,0,0.76L2.6,14.2a1.09,1.09,0,0,0-0.24,1.41L4,18.37a1.12,1.12,0,0,0,1.36 0.5 L7.46,18A7.26,7.26,0,0,0,9,18.88l0.27,2.19a1.1,1.1,0,0,0,1.11 0.93 h3.18a1.11,1.11,0,0,0,1.11-0.92L15,18.89A7.26,7.26,0,0,0,16.54,18l2.14 0.91 a1.12,1.12,0,0,0,1.36-0.5l1.6-2.76a1.1,1.1,0,0,0-0.24-1.42l-1.94-1.45a7.24,7.24,0,0,0,0-1.52L21.4,9.8A1.09,1.09,0,0,0,21.64,8.39ZM12,15.5A3.5,3.5,0,1,1,15.5,12,3.5,3.5,0,0,1,12,15.5Z" /> -</vector> diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_signal_airplane.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_signal_airplane.xml deleted file mode 100644 index 999a9bf3cf45..000000000000 --- a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_signal_airplane.xml +++ /dev/null @@ -1,28 +0,0 @@ -<!-- -/** - * Copyright (c) 2019, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" - android:viewportWidth="24" - android:viewportHeight="24"> - - <path - android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" /> - <path - android:fillColor="#000000" - android:pathData="M3.15,15.8l7.35-2.3V19L8.9,20.2a1,1,0,0,0-0.4 0.8 v0.67a0.24 0.24 ,0,0,0,0.31 0.24 L12,21l3.19 0.91 a0.24 0.24 ,0,0,0,0.31-0.24V21a1,1,0,0,0-0.4-0.8L13.5,19V13.5l7.35,2.3a0.5 0.5 ,0,0,0,0.65-0.48v-0.49a1.5,1.5,0,0,0-0.7-1.27L13.5,9V3.5a1.5,1.5,0,0,0-3,0V9L3.2,13.56a1.5,1.5,0,0,0-0.7,1.27v0.49A0.5 0.5 ,0,0,0,3.15,15.8Z" /> -</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_bluetooth_share_icon.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_bluetooth_share_icon.xml new file mode 100644 index 000000000000..bd06e7cead0b --- /dev/null +++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_bluetooth_share_icon.xml @@ -0,0 +1,27 @@ +<!-- +/** + * Copyright (c) 2019, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:tint="@*android:color/accent_device_default" + android:viewportWidth="24" + android:viewportHeight="24"> + + <path + android:fillColor="@android:color/white" + android:pathData="M17.53,6.72l-4.75-4.75c-0.21-0.21-0.54-0.28-0.82-0.16C11.68,1.92,11.5,2.2,11.5,2.5v7.69L7.53,6.22 c-0.29-0.29-0.77-0.29-1.06,0s-0.29,0.77,0,1.06L11.19,12l-4.72,4.72c-0.29,0.29-0.29,0.77,0,1.06s0.77,0.29,1.06,0l3.97-3.97v7.69 c0,0.3,0.18,0.58,0.46,0.69c0.09,0.04,0.19,0.06,0.29,0.06c0.2,0,0.39-0.08,0.53-0.22l4.75-4.75c0.29-0.29,0.29-0.77,0-1.06 L13.31,12l4.22-4.22C17.82,7.49,17.82,7.01,17.53,6.72z M15.94,16.75L13,19.69v-5.88L15.94,16.75z M13,10.19V4.31l2.94,2.94 L13,10.19z" /> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_invert_colors.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_invert_colors.xml deleted file mode 100644 index 173824be8a64..000000000000 --- a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_invert_colors.xml +++ /dev/null @@ -1,28 +0,0 @@ -<!-- -/** - * Copyright (c) 2019, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" - android:viewportWidth="24" - android:viewportHeight="24"> - - <path - android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" /> - <path - android:fillColor="#000000" - android:pathData="M12.62,2.23A1,1,0,0,0,12,2a1.07,1.07,0,0,0-0.63 0.22 C9.48,3.75,4,8.5,4,14a7.89,7.89,0,0,0,8,8,8,8,0,0,0,8-8C20,8.5,14.5,3.73,12.62,2.23ZM5.5,14c0-4.4,4.32-8.53,6.5-10.33V20.49A6.43,6.43,0,0,1,5.5,14Z" /> -</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_qs_airplane.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_qs_airplane.xml new file mode 100644 index 000000000000..5f9bdd24518e --- /dev/null +++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_qs_airplane.xml @@ -0,0 +1,26 @@ +<!-- +/** + * Copyright (c) 2019, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="18dp" + android:height="18dp" + android:viewportWidth="24" + android:viewportHeight="24"> + + <path + android:fillColor="@android:color/white" + android:pathData="M2.52,16.17c0.32,0.23,0.74,0.31,1.11,0.19l5.87-1.84v3.87L8,19.52c-0.31,0.24-0.5,0.61-0.5,1v0.75 c0,0.69,0.56,1.25,1.25,1.25h6.5c0.69,0,1.25-0.56,1.25-1.25v-0.75c0-0.39-0.19-0.76-0.5-1l-1.5-1.12v-3.87l5.88,1.84 c0.38,0.12,0.79,0.05,1.11-0.19c0.32-0.23,0.51-0.61,0.51-1.01l0-1.84c0-0.63-0.34-1.21-0.89-1.52L14.5,8.06V4 c0-1.38-1.12-2.5-2.5-2.5S9.5,2.62,9.5,4v4.07L2.89,11.8C2.35,12.11,2,12.7,2,13.33l0,1.83C2.01,15.56,2.2,15.94,2.52,16.17z M3.63,13.11L11,8.94V4c0-0.55,0.45-1,1-1s1,0.45,1,1v4.94l7.37,4.17c0.08,0.04,0.13,0.13,0.13,0.22l0,1.5L13,12.48v6.66l2,1.5 v0.38H9v-0.38l2-1.5v-6.66l-7.5,2.34l0-1.49C3.5,13.24,3.55,13.15,3.63,13.11z" /> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_auto_rotate.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_qs_auto_rotate.xml index fe7ecfd9d615..0f9effdad996 100644 --- a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_auto_rotate.xml +++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_qs_auto_rotate.xml @@ -21,11 +21,9 @@ android:viewportHeight="24"> <path - android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" /> + android:fillColor="@android:color/white" + android:pathData="M3.5,7C3.09,7,2.75,7.34,2.75,7.75v2.73c0,0.41,0.34,0.75,0.75,0.75h2.75c0.41,0,0.75-0.34,0.75-0.75S6.66,9.73,6.25,9.73 H5.33l5.42-5.42l6.47,6.47c0.15,0.15,0.34,0.22,0.53,0.22s0.38-0.07,0.53-0.22c0.29-0.29,0.29-0.77,0-1.06l-7-7 c-0.29-0.29-0.77-0.29-1.06,0L4.25,8.69V7.75C4.25,7.34,3.91,7,3.5,7z" /> <path - android:fillColor="#000000" - android:pathData="M3,6.81a0.75 0.75 ,0,0,0-0.75 0.75 v2.83a0.74 0.74 ,0,0,0,0.75 0.75 H5.8a0.75 0.75 ,0,1,0,0-1.5h-1l5.6-5.59,7.07,7.06a0.75 0.75 ,0,0,0,1.06-1.06l-7.6-7.6a0.75 0.75 ,0,0,0-1.06,0L3.72,8.62V7.56A0.76 0.76 ,0,0,0,3,6.81Z" /> - <path - android:fillColor="#000000" - android:pathData="M21,12.85H18.21a0.75 0.75 ,0,0,0,0,1.5h1L13.59,20,6.52,12.89a0.75 0.75 ,0,0,0-1.06,0,0.74 0.74 ,0,0,0,0,1.06l7.6,7.6a0.75 0.75 ,0,0,0,1.06,0l6.17-6.17v1.06a0.75 0.75 ,0,1,0,1.5,0V13.6A0.76 0.76 ,0,0,0,21,12.85Z" /> + android:fillColor="@android:color/white" + android:pathData="M20.5,17c0.41,0,0.75-0.34,0.75-0.75V13.5c0-0.41-0.34-0.75-0.75-0.75h-2.75c-0.41,0-0.75,0.34-0.75,0.75 s0.34,0.75,0.75,0.75h0.94l-5.44,5.44l-6.47-6.47c-0.29-0.29-0.77-0.29-1.06,0s-0.29,0.77,0,1.06l7,7 c0.15,0.15,0.34,0.22,0.53,0.22s0.38-0.07,0.53-0.22l5.97-5.97v0.94C19.75,16.66,20.09,17,20.5,17z" /> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_qs_bluetooth.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_qs_bluetooth.xml new file mode 100644 index 000000000000..d2eb2d3fed26 --- /dev/null +++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_qs_bluetooth.xml @@ -0,0 +1,26 @@ +<!-- +/** + * Copyright (c) 2019, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<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="@android:color/white" + android:pathData="M17.53,6.72l-4.75-4.75c-0.21-0.21-0.54-0.28-0.82-0.16C11.68,1.92,11.5,2.2,11.5,2.5v7.69L7.53,6.22 c-0.29-0.29-0.77-0.29-1.06,0s-0.29,0.77,0,1.06L11.19,12l-4.72,4.72c-0.29,0.29-0.29,0.77,0,1.06s0.77,0.29,1.06,0l3.97-3.97v7.69 c0,0.3,0.18,0.58,0.46,0.69c0.09,0.04,0.19,0.06,0.29,0.06c0.2,0,0.39-0.08,0.53-0.22l4.75-4.75c0.29-0.29,0.29-0.77,0-1.06 L13.31,12l4.22-4.22C17.82,7.49,17.82,7.01,17.53,6.72z M15.94,16.75L13,19.69v-5.88L15.94,16.75z M13,10.19V4.31l2.94,2.94 L13,10.19z" /> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_qs_dnd.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_qs_dnd.xml new file mode 100644 index 000000000000..77a84ba9509d --- /dev/null +++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_qs_dnd.xml @@ -0,0 +1,29 @@ +<!-- +/** + * Copyright (c) 2019, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="17dp" + android:height="17dp" + android:viewportWidth="24" + android:viewportHeight="24"> + + <path + android:fillColor="@android:color/white" + android:pathData="M16.25,11.25h-8.5C7.34,11.25,7,11.59,7,12s0.34,0.75,0.75,0.75h8.5c0.41,0,0.75-0.34,0.75-0.75S16.66,11.25,16.25,11.25z" /> + <path + android:fillColor="@android:color/white" + android:pathData="M12,2C6.49,2,2,6.49,2,12s4.49,10,10,10c0,0,0.01,0,0.01,0c5.5,0,9.98-4.47,9.99-9.98V12C22,6.49,17.51,2,12,2z M20.5,12.02c0,4.68-3.81,8.48-8.49,8.48c0,0-0.01,0-0.01,0c-4.69,0-8.5-3.81-8.5-8.5S7.31,3.5,12,3.5s8.5,3.81,8.5,8.5V12.02z" /> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_signal_flashlight.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_qs_flashlight.xml index 3bde46fcb948..9168c20edff3 100644 --- a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_signal_flashlight.xml +++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_qs_flashlight.xml @@ -21,11 +21,9 @@ android:viewportHeight="24"> <path - android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" /> + android:fillColor="@android:color/white" + android:pathData="M17,2H7C6.59,2,6.25,2.34,6.25,2.75v5c0,0.14,0.04,0.27,0.11,0.39l1.89,3.07v10.04C8.25,21.66,8.59,22,9,22h6 c0.41,0,0.75-0.34,0.75-0.75v-9.79l1.89-3.07c0.07-0.12,0.11-0.25,0.11-0.39V2.75C17.75,2.34,17.41,2,17,2z M16.25,7.79 l-1.89,3.07c-0.07,0.12-0.11,0.25-0.11,0.39v9.25h-4.5V11c0-0.14-0.04-0.27-0.11-0.39L7.75,7.54V6.5h8.5V7.79z M16.25,5h-8.5V3.5 h8.5V5z" /> <path - android:fillColor="#000000" - android:pathData="M9,22h6a0.76 0.76 ,0,0,0,0.75-0.75V11.46l1.89-3.07A0.77 0.77 ,0,0,0,17.75,8V2.75A0.76 0.76 ,0,0,0,17,2H7a0.76 0.76 ,0,0,0-0.75 0.75 v5a0.77 0.77 ,0,0,0,0.11 0.39 l1.89,3.07v10A0.76 0.76 ,0,0,0,9,22ZM16.25,3.5V5H7.75V3.5Zm-8.5,4v-1h8.5V7.79l-1.89,3.07a0.77 0.77 ,0,0,0-0.11 0.39 V20.5H9.75V11a0.77 0.77 ,0,0,0-0.11-0.39Z" /> - <path - android:fillColor="#000000" + android:fillColor="@android:color/white" android:pathData="M 12 12.75 C 12.6903559373 12.75 13.25 13.3096440627 13.25 14 C 13.25 14.6903559373 12.6903559373 15.25 12 15.25 C 11.3096440627 15.25 10.75 14.6903559373 10.75 14 C 10.75 13.3096440627 11.3096440627 12.75 12 12.75 Z" /> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_settings_bluetooth.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_settings_bluetooth.xml new file mode 100644 index 000000000000..d2eb2d3fed26 --- /dev/null +++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_settings_bluetooth.xml @@ -0,0 +1,26 @@ +<!-- +/** + * Copyright (c) 2019, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<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="@android:color/white" + android:pathData="M17.53,6.72l-4.75-4.75c-0.21-0.21-0.54-0.28-0.82-0.16C11.68,1.92,11.5,2.2,11.5,2.5v7.69L7.53,6.22 c-0.29-0.29-0.77-0.29-1.06,0s-0.29,0.77,0,1.06L11.19,12l-4.72,4.72c-0.29,0.29-0.29,0.77,0,1.06s0.77,0.29,1.06,0l3.97-3.97v7.69 c0,0.3,0.18,0.58,0.46,0.69c0.09,0.04,0.19,0.06,0.29,0.06c0.2,0,0.39-0.08,0.53-0.22l4.75-4.75c0.29-0.29,0.29-0.77,0-1.06 L13.31,12l4.22-4.22C17.82,7.49,17.82,7.01,17.53,6.72z M15.94,16.75L13,19.69v-5.88L15.94,16.75z M13,10.19V4.31l2.94,2.94 L13,10.19z" /> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_auto_rotate.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_airplanemode_active.xml index f98e2b8b2a24..e884edb4ad47 100644 --- a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_auto_rotate.xml +++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_airplanemode_active.xml @@ -21,13 +21,6 @@ android:viewportHeight="24"> <path - android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" /> - <path - android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" /> - <path - android:fillColor="#000000" - android:pathData="M3.5,6a0.5 0.5 ,0,0,0-0.5 0.5 V11H7.5a0.5 0.5 ,0,0,0,0-1H4.76l5-4.65a2.49,2.49,0,0,1,3.48 0.05 l4.95,4.95a0.49 0.49 ,0,1,0,0.7-0.7L13.91,4.7A3.47,3.47,0,0,0,9,4.62L4,9.35V6.5A0.5 0.5 ,0,0,0,3.5,6Z" /> - <path - android:fillColor="#000000" - android:pathData="M20.5,18a0.5 0.5 ,0,0,0,0.5-0.5V13H16.5a0.5 0.5 ,0,0,0,0,1h2.74l-5,4.65a2.49,2.49,0,0,1-3.48,0l-5-5a0.49 0.49 ,0,0,0-0.7 0.7 l4.94,5a3.47,3.47,0,0,0,4.87 0.08 l5-4.73V17.5A0.5 0.5 ,0,0,0,20.5,18Z" /> + android:fillColor="@android:color/white" + android:pathData="M2.52,16.17c0.32,0.23,0.74,0.31,1.11,0.19l5.87-1.84v3.87L8,19.52c-0.31,0.24-0.5,0.61-0.5,1v0.75 c0,0.69,0.56,1.25,1.25,1.25h6.5c0.69,0,1.25-0.56,1.25-1.25v-0.75c0-0.39-0.19-0.76-0.5-1l-1.5-1.12v-3.87l5.88,1.84 c0.38,0.12,0.79,0.05,1.11-0.19c0.32-0.23,0.51-0.61,0.51-1.01l0-1.84c0-0.63-0.34-1.21-0.89-1.52L14.5,8.06V4 c0-1.38-1.12-2.5-2.5-2.5S9.5,2.62,9.5,4v4.07L2.89,11.8C2.35,12.11,2,12.7,2,13.33l0,1.83C2.01,15.56,2.2,15.94,2.52,16.17z M3.63,13.11L11,8.94V4c0-0.55,0.45-1,1-1s1,0.45,1,1v4.94l7.37,4.17c0.08,0.04,0.13,0.13,0.13,0.22l0,1.5L13,12.48v6.66l2,1.5 v0.38H9v-0.38l2-1.5v-6.66l-7.5,2.34l0-1.49C3.5,13.24,3.55,13.15,3.63,13.11z" /> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_dnd.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_dnd.xml deleted file mode 100644 index a9a32ee5bce4..000000000000 --- a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_dnd.xml +++ /dev/null @@ -1,31 +0,0 @@ -<!-- -/** - * Copyright (c) 2019, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" - android:viewportWidth="24" - android:viewportHeight="24"> - - <path - android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" /> - <path - android:fillColor="#000000" - android:pathData="M7.25,12.75h9.5a0.75 0.75 ,0,0,0,0-1.5H7.25a0.75 0.75 ,0,0,0,0,1.5Z" /> - <path - android:fillColor="#000000" - android:pathData="M12,22h0A10,10,0,0,0,22,12v0A10,10,0,1,0,12,22ZM12,3.5A8.51,8.51,0,0,1,20.5,12h0.75l-0.75,0A8.49,8.49,0,0,1,12,20.5h0a8.5,8.5,0,0,1,0-17Z" /> -</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_lockscreen_ime.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_lockscreen_ime.xml deleted file mode 100644 index 7897fa3a40a9..000000000000 --- a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_lockscreen_ime.xml +++ /dev/null @@ -1,55 +0,0 @@ -<!-- -/** - * Copyright (c) 2019, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" - android:viewportWidth="24" - android:viewportHeight="24"> - - <path - android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" /> - <path - android:fillColor="#000000" - android:pathData="M3,21H21a2,2,0,0,0,2-2V6a2,2,0,0,0-2-2H3A2,2,0,0,0,1,6V19A2,2,0,0,0,3,21ZM2.5,6A0.51 0.51 ,0,0,1,3,5.5H21a0.51 0.51 ,0,0,1,0.5 0.5 V19a0.51 0.51 ,0,0,1-0.5 0.5 H3a0.51 0.51 ,0,0,1-0.5-0.5Z" /> - <path - android:fillColor="#000000" - android:pathData="M 9.5 8 L 10.5 8 Q 11 8 11 8.5 L 11 9.5 Q 11 10 10.5 10 L 9.5 10 Q 9 10 9 9.5 L 9 8.5 Q 9 8 9.5 8 Z" /> - <path - android:fillColor="#000000" - android:pathData="M 5.5 8 L 6.5 8 Q 7 8 7 8.5 L 7 9.5 Q 7 10 6.5 10 L 5.5 10 Q 5 10 5 9.5 L 5 8.5 Q 5 8 5.5 8 Z" /> - <path - android:fillColor="#000000" - android:pathData="M8.75,17.5h6.5a0.75 0.75 ,0,0,0,0-1.5H8.75a0.75 0.75 ,0,0,0,0,1.5Z" /> - <path - android:fillColor="#000000" - android:pathData="M 13.5 8 L 14.5 8 Q 15 8 15 8.5 L 15 9.5 Q 15 10 14.5 10 L 13.5 10 Q 13 10 13 9.5 L 13 8.5 Q 13 8 13.5 8 Z" /> - <path - android:fillColor="#000000" - android:pathData="M 9.5 12 L 10.5 12 Q 11 12 11 12.5 L 11 13.5 Q 11 14 10.5 14 L 9.5 14 Q 9 14 9 13.5 L 9 12.5 Q 9 12 9.5 12 Z" /> - <path - android:fillColor="#000000" - android:pathData="M 5.5 12 L 6.5 12 Q 7 12 7 12.5 L 7 13.5 Q 7 14 6.5 14 L 5.5 14 Q 5 14 5 13.5 L 5 12.5 Q 5 12 5.5 12 Z" /> - <path - android:fillColor="#000000" - android:pathData="M 13.5 12 L 14.5 12 Q 15 12 15 12.5 L 15 13.5 Q 15 14 14.5 14 L 13.5 14 Q 13 14 13 13.5 L 13 12.5 Q 13 12 13.5 12 Z" /> - <path - android:fillColor="#000000" - android:pathData="M 17.5 8 L 18.5 8 Q 19 8 19 8.5 L 19 9.5 Q 19 10 18.5 10 L 17.5 10 Q 17 10 17 9.5 L 17 8.5 Q 17 8 17.5 8 Z" /> - <path - android:fillColor="#000000" - android:pathData="M 17.5 12 L 18.5 12 Q 19 12 19 12.5 L 19 13.5 Q 19 14 18.5 14 L 17.5 14 Q 17 14 17 13.5 L 17 12.5 Q 17 12 17.5 12 Z" /> -</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_brightness_auto_on.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_brightness_auto_on.xml deleted file mode 100644 index 9bf12749cca6..000000000000 --- a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_brightness_auto_on.xml +++ /dev/null @@ -1,52 +0,0 @@ -<!-- -/** - * Copyright (c) 2019, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" - android:viewportWidth="24" - android:viewportHeight="24"> - - <path - android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" /> - <path - android:fillColor="#000000" - android:pathData="M12.75,2.25V0.75a0.75 0.75 ,0,0,0-1.5,0v1.5a0.75 0.75 ,0,0,0,1.5,0Z" /> - <path - android:fillColor="#000000" - android:pathData="M4.57,5.64a0.79 0.79 ,0,0,0,1.07,0,0.77 0.77 ,0,0,0,0-1.07L4.58,3.51A0.76 0.76 ,0,0,0,3.51,4.58Z" /> - <path - android:fillColor="#000000" - android:pathData="M0.75,12.75h1.5a0.75 0.75 ,0,0,0,0-1.5H0.75a0.75 0.75 ,0,0,0,0,1.5Z" /> - <path - android:fillColor="#000000" - android:pathData="M3.51,20.49a0.76 0.76 ,0,0,0,1.07,0l1.06-1.06a0.76 0.76 ,0,1,0-1.07-1.07L3.51,19.42A0.77 0.77 ,0,0,0,3.51,20.49Z" /> - <path - android:fillColor="#000000" - android:pathData="M11.25,21.75v1.5a0.75 0.75 ,0,0,0,1.5,0v-1.5a0.75 0.75 ,0,0,0-1.5,0Z" /> - <path - android:fillColor="#000000" - android:pathData="M20,20.71a0.79 0.79 ,0,0,0,0.53-0.22 0.77 0.77,0,0,0,0-1.07l-1.06-1.06a0.76 0.76 ,0,0,0-1.07,1.07l1.06,1.06A0.79 0.79 ,0,0,0,20,20.71Z" /> - <path - android:fillColor="#000000" - android:pathData="M23.25,11.25h-1.5a0.75 0.75 ,0,0,0,0,1.5h1.5a0.75 0.75 ,0,0,0,0-1.5Z" /> - <path - android:fillColor="#000000" - android:pathData="M19.42,3.51,18.36,4.57a0.77 0.77 ,0,0,0,0,1.07 0.79 0.79,0,0,0,1.07,0l1.06-1.06a0.76 0.76 ,0,0,0-1.07-1.07Z" /> - <path - android:fillColor="#000000" - android:pathData="M14.85,17H17L13.11,7H10.87L7,17H9.15L10,14.61h4Zm-4.22-4.12,1.31-3.71h0.11l1.29,3.71Z" /> -</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_cast_on.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_cast_on.xml deleted file mode 100644 index 34ca21a76edc..000000000000 --- a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_cast_on.xml +++ /dev/null @@ -1,40 +0,0 @@ -<!-- -/** - * Copyright (c) 2019, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" - android:viewportWidth="24" - android:viewportHeight="24"> - - <path - android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" /> - <path - android:fillColor="#000000" - android:pathData="M22,18V5.5A1.5,1.5,0,0,0,20.5,4h-17A1.5,1.5,0,0,0,2,5.53V8.46a0.75 0.75 ,0,0,0,1.5,0v-3l17,0V18H13.15a0.75 0.75 ,0,1,0,0,1.5h7.38A1.5,1.5,0,0,0,22,18Z" /> - <path - android:fillColor="#000000" - android:pathData="M3.25,19.5a1.25,1.25,0,0,0,0-2.5h0a1.25,1.25,0,0,0,0,2.5Z" /> - <path - android:fillColor="#000000" - android:pathData="M2,11.25a0.76 0.76 ,0,0,0,0.75 0.75 A6.75,6.75,0,0,1,9.5,18.75a0.75 0.75 ,0,0,0,1.5,0A8.25,8.25,0,0,0,2.75,10.5 0.76 0.76,0,0,0,2,11.25Z" /> - <path - android:fillColor="#000000" - android:pathData="M2.75,15.25a3.5,3.5,0,0,1,3.5,3.5 0.75 0.75,0,0,0,1.5,0,5,5,0,0,0-5-5,0.75 0.75 ,0,0,0,0,1.5Z" /> - <path - android:fillColor="#000000" - android:pathData="M13.25,15a0.75 0.75 ,0,0,0,0,1.5h5a0.76 0.76 ,0,0,0,0.75-0.75v-8A0.76 0.76 ,0,0,0,18.25,7H5.75A0.76 0.76 ,0,0,0,5,7.75V8.5a0.75 0.75 ,0,0,0,1.5,0h11V15Z" /> -</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_settings_16dp.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_settings_16dp.xml deleted file mode 100644 index 4237323ca2f7..000000000000 --- a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_settings_16dp.xml +++ /dev/null @@ -1,31 +0,0 @@ -<!-- -/** - * Copyright (c) 2019, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="16dp" - android:height="16dp" - android:viewportWidth="24" - android:viewportHeight="24"> - - <path - android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" /> - <path - android:fillColor="#000000" - android:pathData="M2.2,15.53,4,18.7a1.46,1.46,0,0,0,1.28 0.75 ,1.61,1.61,0,0,0,0.53-0.1l1.8-0.72a9,9,0,0,0,0.79 0.46 L8.7,21a1.45,1.45,0,0,0,1.45,1.27h3.7A1.47,1.47,0,0,0,15.31,21l0.27-1.91c0.26-0.14 0.52 -0.29 0.78 -0.46l1.8 0.72 a1.47,1.47,0,0,0,0.54 0.1 A1.43,1.43,0,0,0,20,18.75l1.86-3.22a1.47,1.47,0,0,0-0.37-1.86l-1.52-1.19c0-0.15,0-0.3,0-0.46s0-0.31,0-0.46l1.52-1.19a1.47,1.47,0,0,0,0.36-1.88L20,5.31a1.46,1.46,0,0,0-1.29-0.75,1.71,1.71,0,0,0-0.53 0.1 l-1.8 0.72 a9,9,0,0,0-0.79-0.46L15.29,3a1.45,1.45,0,0,0-1.45-1.27h-3.7A1.46,1.46,0,0,0,8.7,3L8.43,4.92c-0.26 0.14 -0.52 0.29 -0.78 0.46 L5.84,4.65a1.47,1.47,0,0,0-0.54-0.1,1.42,1.42,0,0,0-1.25 0.73 L2.2,8.47a1.44,1.44,0,0,0,0.37,1.88l1.52,1.19c0,0.15,0,0.31,0,0.46s0,0.31,0,0.46L2.56,13.65A1.48,1.48,0,0,0,2.2,15.53ZM5,13.64l0.63-0.49,0-0.79c0-0.12,0-0.23,0-0.36s0-0.24,0-0.36l0-0.79L5,10.36,3.52,9.19,5.33,6.06l1.76 0.71 0.73 0.29 0.65-0.42a6.59,6.59,0,0,1,0.67-0.4l0.67-0.36 0.11 -0.75 0.26 -1.87h3.63l0.27,1.87 0.1 0.77 0.69 0.35a6,6,0,0,1,0.66 0.39 l0.65 0.42 0.73-0.29,1.76-0.71L20.5,9.21,19,10.38l-0.63 0.49 0.05 0.79 c0,0.12,0,0.23,0,0.36s0,0.24,0,0.36l-0.05 0.79 0.63 0.49 ,1.48,1.17L18.68,18l-1.76-0.7L16.19,17l-0.65 0.42 a6.59,6.59,0,0,1-0.67 0.4 l-0.67 0.36 -0.11 0.75 -0.26,1.84H10.18l-0.27-1.87-0.1-0.77-0.69-0.35a6,6,0,0,1-0.66-0.39L7.81,17l-0.73 0.29 L5.33,18,3.52,14.8Z" /> - <path - android:fillColor="#000000" - android:pathData="M12,16a4,4,0,1,0-4-4A4,4,0,0,0,12,16Zm0-6.5A2.5,2.5,0,1,1,9.5,12,2.5,2.5,0,0,1,12,9.5Z" /> -</vector> diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_signal_airplane.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_signal_airplane.xml deleted file mode 100644 index 2d36a3986107..000000000000 --- a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_signal_airplane.xml +++ /dev/null @@ -1,28 +0,0 @@ -<!-- -/** - * Copyright (c) 2019, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" - android:viewportWidth="24" - android:viewportHeight="24"> - - <path - android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" /> - <path - android:fillColor="#000000" - android:pathData="M2.52,16.17a1.25,1.25,0,0,0,1.11 0.19 L9.5,14.52v3.87L8,19.52a1.26,1.26,0,0,0-0.5,1v0.75a1.25,1.25,0,0,0,1.25,1.25h6.5a1.25,1.25,0,0,0,1.25-1.25v-0.75a1.26,1.26,0,0,0-0.5-1l-1.5-1.13V14.52l5.88,1.84a1.23,1.23,0,0,0,1.11-0.19,1.25,1.25,0,0,0,0.51-1V13.33a1.74,1.74,0,0,0-0.89-1.52L14.5,8.06V3.75a2.5,2.5,0,0,0-5,0V8.06L2.89,11.8A1.78,1.78,0,0,0,2,13.33v1.83A1.25,1.25,0,0,0,2.52,16.17Zm1.11-3.06L11,8.94V3.75a1,1,0,0,1,2,0V8.94l7.37,4.17a0.26 0.26 ,0,0,1,0.13 0.22 v1.49L13,12.48v6.66l2,1.5V21H9v-0.38l2-1.5V12.48L3.51,14.82V13.33A0.25 0.25 ,0,0,1,3.63,13.11Z" /> -</vector>
\ No newline at end of file diff --git a/proto/src/wifi.proto b/proto/src/wifi.proto index 1ce0c5292ab8..af77df60638a 100644 --- a/proto/src/wifi.proto +++ b/proto/src/wifi.proto @@ -1752,6 +1752,9 @@ message WifiIsUnusableEvent { // Firmware generated an alert TYPE_FIRMWARE_ALERT = 4; + + // IP Manager lost reachability to network neighbors + TYPE_IP_REACHABILITY_LOST = 5; } // What event triggered WifiIsUnusableEvent. @@ -2012,6 +2015,10 @@ message WifiUsabilityStatsEntry { // Whether the primary registered cell of current entry is same as that of previous entry optional bool is_same_registered_cell = 33; + + // The device mobility state + optional DeviceMobilityStatePnoScanStats.DeviceMobilityState + device_mobility_state = 34; } message WifiUsabilityStats { @@ -2041,6 +2048,9 @@ message WifiUsabilityStats { // Firmware generated an alert TYPE_FIRMWARE_ALERT = 4; + + // IP Manager lost reachability to network neighbors + TYPE_IP_REACHABILITY_LOST = 5; } // The current wifi usability state diff --git a/services/core/java/com/android/server/LocationManagerService.java b/services/core/java/com/android/server/LocationManagerService.java index 2ded1e58bf2d..be5838944bd0 100644 --- a/services/core/java/com/android/server/LocationManagerService.java +++ b/services/core/java/com/android/server/LocationManagerService.java @@ -323,16 +323,24 @@ public class LocationManagerService extends ILocationManager.Stub { }); mPackageManager.addOnPermissionsChangeListener( uid -> { - synchronized (mLock) { - onPermissionsChangedLocked(); - } + // listener invoked on ui thread, move to our thread to reduce risk of blocking + // ui thread + mHandler.post(() -> { + synchronized (mLock) { + onPermissionsChangedLocked(); + } + }); }); mActivityManager.addOnUidImportanceListener( (uid, importance) -> { - synchronized (mLock) { - onUidImportanceChangedLocked(uid, importance); - } + // listener invoked on ui thread, move to our thread to reduce risk of blocking + // ui thread + mHandler.post(() -> { + synchronized (mLock) { + onUidImportanceChangedLocked(uid, importance); + } + }); }, FOREGROUND_IMPORTANCE_CUTOFF); mContext.getContentResolver().registerContentObserver( @@ -394,9 +402,13 @@ public class LocationManagerService extends ILocationManager.Stub { LocalServices.getService(PowerManagerInternal.class); localPowerManager.registerLowPowerModeObserver(ServiceType.LOCATION, state -> { - synchronized (mLock) { - onBatterySaverModeChangedLocked(state.locationMode); - } + // listener invoked on ui thread, move to our thread to reduce risk of blocking + // ui thread + mHandler.post(() -> { + synchronized (mLock) { + onBatterySaverModeChangedLocked(state.locationMode); + } + }); }); new PackageMonitor() { diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java index 1a842f72fcb4..b3a667a5f7c1 100644 --- a/services/core/java/com/android/server/StorageManagerService.java +++ b/services/core/java/com/android/server/StorageManagerService.java @@ -3947,6 +3947,23 @@ class StorageManagerService extends IStorageManager.Stub case "ak.alizandro.smartaudiobookplayer": // b/129084042 case "com.campmobile.snow": // b/128803870 case "com.qnap.qfile": // b/126374406 + case "com.google.android.apps.photos": // b/125506293 + case "com.facebook.mlite": // b/126561155 + case "com.ss.android.ugc.trill": // b/126610656 + case "com.instagram.android": // b/127526615 + case "com.facebook.orca": // b/128255453 + case "org.videolan.vlc": // b/128391743 + case "vStudio.Android.Camera360": // b/128882110 + case "com.twitter.android": // b/128948908 + case "com.tumblr": // b/129022664 + case "com.sina.weibo": // b/129029018 + case "com.kwai.video": // b/129037235 + case "com.fotoable.photocollage": // b/129236353 + case "com.xvideostudio.videoeditor": // b/129247146 + case "app.buzz.share": // b/129304005 + case "com.ss.android.article.topbuzzvideo.en": // b/129303979 + case "com.linecorp.b612.android": // b/129318512 + case "com.google.android.GoogleCamera": // b/128326994 return true; } } diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java index 73e04399396a..1c9931616630 100644 --- a/services/core/java/com/android/server/TelephonyRegistry.java +++ b/services/core/java/com/android/server/TelephonyRegistry.java @@ -79,6 +79,7 @@ import java.util.List; import java.util.Map; import java.util.NoSuchElementException; import java.util.OptionalInt; +import java.util.stream.Collectors; /** * Since phone process can be restarted, this class provides a centralized place @@ -260,8 +261,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { static final int ENFORCE_PHONE_STATE_PERMISSION_MASK = PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR | PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR - | PhoneStateListener.LISTEN_EMERGENCY_NUMBER_LIST - | PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE; + | PhoneStateListener.LISTEN_EMERGENCY_NUMBER_LIST; static final int PRECISE_PHONE_STATE_PERMISSION_MASK = PhoneStateListener.LISTEN_PRECISE_CALL_STATE | @@ -822,7 +822,10 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } } if ((events & PhoneStateListener - .LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE) != 0) { + .LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE) != 0 + && TelephonyPermissions.checkReadPhoneStateOnAnyActiveSub( + r.context, r.callerPid, r.callerUid, r.callingPackage, + "listen_active_data_subid_change")) { try { r.callback.onActiveDataSubIdChanged(mActiveDataSubId); } catch (RemoteException ex) { @@ -1764,12 +1767,23 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { log("notifyActiveDataSubIdChanged: activeDataSubId=" + activeDataSubId); } + // Create a copy to prevent the IPC call while checking carrier privilege under the lock. + List<Record> copiedRecords; synchronized (mRecords) { - mActiveDataSubId = activeDataSubId; + copiedRecords = new ArrayList<>(mRecords); + } + mActiveDataSubId = activeDataSubId; - for (Record r : mRecords) { - if (r.matchPhoneStateListenerEvent( - PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE)) { + // Filter the record that does not listen to this change or does not have the permission. + copiedRecords = copiedRecords.stream().filter(r -> r.matchPhoneStateListenerEvent( + PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE) + && TelephonyPermissions.checkReadPhoneStateOnAnyActiveSub( + mContext, r.callerPid, r.callerUid, r.callingPackage, + "notifyActiveDataSubIdChanged")).collect(Collectors.toCollection(ArrayList::new)); + + synchronized (mRecords) { + for (Record r : copiedRecords) { + if (mRecords.contains(r)) { try { r.callback.onActiveDataSubIdChanged(activeDataSubId); } catch (RemoteException ex) { diff --git a/services/core/java/com/android/server/adb/AdbDebuggingManager.java b/services/core/java/com/android/server/adb/AdbDebuggingManager.java index 8ccb6e20a614..9325d257904a 100644 --- a/services/core/java/com/android/server/adb/AdbDebuggingManager.java +++ b/services/core/java/com/android/server/adb/AdbDebuggingManager.java @@ -307,7 +307,6 @@ public class AdbDebuggingManager { } cancelJobToUpdateAdbKeyStore(); - mAdbKeyStore = null; mConnectedKey = null; break; diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 05ec9543520d..d4bff007462a 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -8835,7 +8835,6 @@ public class ActivityManagerService extends IActivityManager.Stub mAtmInternal.updateTopComponentForFactoryTest(); retrieveSettings(); - final int currentUserId = mUserController.getCurrentUserId(); mUgmInternal.onSystemReady(); final PowerManagerInternal pmi = LocalServices.getService(PowerManagerInternal.class); @@ -8849,6 +8848,16 @@ public class ActivityManagerService extends IActivityManager.Stub } if (goingCallback != null) goingCallback.run(); + // Check the current user here as a user can be started inside goingCallback.run() from + // other system services. + final int currentUserId = mUserController.getCurrentUserId(); + Slog.i(TAG, "Current user:" + currentUserId); + if (currentUserId != UserHandle.USER_SYSTEM && !mUserController.isSystemUserStarted()) { + // User other than system user has started. Make sure that system user is already + // started before switching user. + throw new RuntimeException("System user not started while current user is:" + + currentUserId); + } traceLog.traceBegin("ActivityManagerStartApps"); mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, Integer.toString(currentUserId), currentUserId); diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java index 07c9cca3f6c3..cc4116ebb789 100644 --- a/services/core/java/com/android/server/am/UserController.java +++ b/services/core/java/com/android/server/am/UserController.java @@ -956,15 +956,26 @@ class UserController implements Handler.Callback { final int oldUserId = getCurrentUserId(); if (oldUserId == userId) { final UserState state = getStartedUserState(userId); - if (state != null && state.state == STATE_RUNNING_UNLOCKED) { - // We'll skip all later code, so we must tell listener it's already unlocked. - try { - unlockListener.onFinished(userId, null); - } catch (RemoteException ignore) { - // Ignore. + if (state == null) { + Slog.wtf(TAG, "Current user has no UserState"); + // continue starting. + } else { + if (userId == UserHandle.USER_SYSTEM && state.state == STATE_BOOTING) { + // system user start explicitly requested. should continue starting as it + // is not in running state. + } else { + if (state.state == STATE_RUNNING_UNLOCKED) { + // We'll skip all later code, so we must tell listener it's already + // unlocked. + try { + unlockListener.onFinished(userId, null); + } catch (RemoteException ignore) { + // Ignore. + } + } + return true; } } - return true; } if (foreground) { @@ -1743,6 +1754,24 @@ class UserController implements Handler.Callback { return state.state != UserState.STATE_STOPPING && state.state != UserState.STATE_SHUTDOWN; } + /** + * Check if system user is already started. Unlike other user, system user is in STATE_BOOTING + * even if it is not explicitly started. So isUserRunning cannot give the right state + * to check if system user is started or not. + * @return true if system user is started. + */ + boolean isSystemUserStarted() { + synchronized (mLock) { + UserState uss = mStartedUsers.get(UserHandle.USER_SYSTEM); + if (uss == null) { + return false; + } + return uss.state == UserState.STATE_RUNNING_LOCKED + || uss.state == UserState.STATE_RUNNING_UNLOCKING + || uss.state == UserState.STATE_RUNNING_UNLOCKED; + } + } + UserInfo getCurrentUser() { if ((mInjector.checkCallingPermission(INTERACT_ACROSS_USERS) != PackageManager.PERMISSION_GRANTED) && ( diff --git a/services/core/java/com/android/server/broadcastradio/hal2/BroadcastRadioService.java b/services/core/java/com/android/server/broadcastradio/hal2/BroadcastRadioService.java index b8810c8f379f..2df89821611c 100644 --- a/services/core/java/com/android/server/broadcastradio/hal2/BroadcastRadioService.java +++ b/services/core/java/com/android/server/broadcastradio/hal2/BroadcastRadioService.java @@ -24,6 +24,7 @@ import android.hardware.radio.ICloseHandle; import android.hardware.radio.ITuner; import android.hardware.radio.ITunerCallback; import android.hardware.radio.RadioManager; +import android.hardware.radio.RadioTuner; import android.hidl.manager.V1_0.IServiceManager; import android.hidl.manager.V1_0.IServiceNotification; import android.os.IHwBinder.DeathRecipient; @@ -49,9 +50,17 @@ public class BroadcastRadioService { @GuardedBy("mLock") private final Map<String, Integer> mServiceNameToModuleIdMap = new HashMap<>(); + // Map from module ID to RadioModule created by mServiceListener.onRegistration(). @GuardedBy("mLock") private final Map<Integer, RadioModule> mModules = new HashMap<>(); + // Map from module ID to TunerSession created by openSession(). + // + // Because this service currently implements a 1 AIDL to 1 HAL policy, mTunerSessions is used to + // enforce the "aggresive open" policy mandated for IBroadcastRadio.openSession(). In the + // future, this solution will be replaced with a multiple-AIDL to 1 HAL implementation. + private final Map<Integer, TunerSession> mTunerSessions = new HashMap<>(); + private IServiceNotification.Stub mServiceListener = new IServiceNotification.Stub() { @Override public void onRegistration(String fqName, String serviceName, boolean preexisting) { @@ -72,6 +81,7 @@ public class BroadcastRadioService { } Slog.v(TAG, "loaded broadcast radio module " + moduleId + ": " + serviceName + " (HAL 2.0)"); + closeTunerSessionLocked(moduleId); mModules.put(moduleId, module); if (newService) { @@ -96,6 +106,7 @@ public class BroadcastRadioService { synchronized (mLock) { int moduleId = (int) cookie; mModules.remove(moduleId); + closeTunerSessionLocked(moduleId); for (Map.Entry<String, Integer> entry : mServiceNameToModuleIdMap.entrySet()) { if (entry.getValue() == moduleId) { @@ -152,16 +163,20 @@ public class BroadcastRadioService { RadioModule module = null; synchronized (mLock) { module = mModules.get(moduleId); - } - if (module == null) { - throw new IllegalArgumentException("Invalid module ID"); + if (module == null) { + throw new IllegalArgumentException("Invalid module ID"); + } + closeTunerSessionLocked(moduleId); } - TunerSession session = module.openSession(callback); + TunerSession tunerSession = module.openSession(callback); + synchronized (mLock) { + mTunerSessions.put(moduleId, tunerSession); + } if (legacyConfig != null) { - session.setConfiguration(legacyConfig); + tunerSession.setConfiguration(legacyConfig); } - return session; + return tunerSession; } public ICloseHandle addAnnouncementListener(@NonNull int[] enabledTypes, @@ -183,4 +198,12 @@ public class BroadcastRadioService { } return aggregator; } + + private void closeTunerSessionLocked(int moduleId) { + TunerSession tunerSession = mTunerSessions.remove(moduleId); + if (tunerSession != null) { + Slog.d(TAG, "Closing previous TunerSession"); + tunerSession.close(RadioTuner.ERROR_HARDWARE_FAILURE); + } + } } diff --git a/services/core/java/com/android/server/broadcastradio/hal2/TunerSession.java b/services/core/java/com/android/server/broadcastradio/hal2/TunerSession.java index 9833507f8fce..05ca144ed3b9 100644 --- a/services/core/java/com/android/server/broadcastradio/hal2/TunerSession.java +++ b/services/core/java/com/android/server/broadcastradio/hal2/TunerSession.java @@ -17,6 +17,7 @@ package com.android.server.broadcastradio.hal2; import android.annotation.NonNull; +import android.annotation.Nullable; import android.graphics.Bitmap; import android.hardware.broadcastradio.V2_0.ConfigFlag; import android.hardware.broadcastradio.V2_0.ITunerSession; @@ -58,8 +59,22 @@ class TunerSession extends ITuner.Stub { @Override public void close() { + close(null); + } + + /** + * Closes the TunerSession. If error is non-null, the client's onError() callback is invoked + * first with the specified error, see {@link + * android.hardware.radio.RadioTuner.Callback#onError}. + * + * @param error Optional error to send to client before session is closed. + */ + public void close(@Nullable Integer error) { synchronized (mLock) { if (mIsClosed) return; + if (error != null) { + TunerCallback.dispatch(() -> mCallback.mClientCb.onError(error)); + } mIsClosed = true; } } diff --git a/services/core/java/com/android/server/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java index 99868099ad4d..b140c1b25320 100644 --- a/services/core/java/com/android/server/connectivity/Tethering.java +++ b/services/core/java/com/android/server/connectivity/Tethering.java @@ -409,21 +409,25 @@ public class Tethering extends BaseNetworkObserver { } private int setWifiTethering(final boolean enable) { - int rval = TETHER_ERROR_MASTER_ERROR; final long ident = Binder.clearCallingIdentity(); try { synchronized (mPublicSync) { - mWifiTetherRequested = enable; final WifiManager mgr = getWifiManager(); + if (mgr == null) { + mLog.e("setWifiTethering: failed to get WifiManager!"); + return TETHER_ERROR_SERVICE_UNAVAIL; + } if ((enable && mgr.startSoftAp(null /* use existing wifi config */)) || (!enable && mgr.stopSoftAp())) { - rval = TETHER_ERROR_NO_ERROR; + mWifiTetherRequested = enable; + return TETHER_ERROR_NO_ERROR; } } } finally { Binder.restoreCallingIdentity(ident); } - return rval; + + return TETHER_ERROR_MASTER_ERROR; } private void setBluetoothTethering(final boolean enable, final ResultReceiver receiver) { @@ -942,6 +946,11 @@ public class Tethering extends BaseNetworkObserver { public int setUsbTethering(boolean enable) { if (VDBG) Log.d(TAG, "setUsbTethering(" + enable + ")"); UsbManager usbManager = (UsbManager) mContext.getSystemService(Context.USB_SERVICE); + if (usbManager == null) { + mLog.e("setUsbTethering: failed to get UsbManager!"); + return TETHER_ERROR_SERVICE_UNAVAIL; + } + synchronized (mPublicSync) { usbManager.setCurrentFunctions(enable ? UsbManager.FUNCTION_RNDIS : UsbManager.FUNCTION_NONE); diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java index a2882de7ee7a..9e2fd4e9e91e 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java @@ -74,7 +74,15 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource { @GuardedBy("mLock") private boolean mSystemAudioControlFeatureEnabled; - private boolean mTvSystemAudioModeSupport; + /** + * Indicates if the TV that the current device is connected to supports System Audio Mode or not + * + * <p>If the current device has no information on this, keep mTvSystemAudioModeSupport null + * + * <p>The boolean will be reset to null every time when the current device goes to standby + * or loses its physical address. + */ + private Boolean mTvSystemAudioModeSupport = null; // Whether ARC is available or not. "true" means that ARC is established between TV and // AVR as audio receiver. @@ -321,7 +329,7 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource { @ServiceThreadOnly protected void onStandby(boolean initiatedByCec, int standbyAction) { assertRunOnServiceThread(); - mTvSystemAudioModeSupport = false; + mTvSystemAudioModeSupport = null; // Record the last state of System Audio Control before going to standby synchronized (mLock) { mService.writeStringSystemProperty( @@ -1029,12 +1037,11 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource { * <p>The result of the query may be cached until Audio device type is put in standby or loses * its physical address. */ - // TODO(amyjojo): making mTvSystemAudioModeSupport null originally and fix the logic. void queryTvSystemAudioModeSupport(TvSystemAudioModeSupportedCallback callback) { - if (!mTvSystemAudioModeSupport) { + if (mTvSystemAudioModeSupport == null) { addAndStartAction(new DetectTvSystemAudioModeSupportAction(this, callback)); } else { - callback.onResult(true); + callback.onResult(mTvSystemAudioModeSupport); } } diff --git a/services/core/java/com/android/server/om/OverlayManagerService.java b/services/core/java/com/android/server/om/OverlayManagerService.java index 37dd63a2f745..13ff873b8bb7 100644 --- a/services/core/java/com/android/server/om/OverlayManagerService.java +++ b/services/core/java/com/android/server/om/OverlayManagerService.java @@ -422,8 +422,6 @@ public final class OverlayManagerService extends SystemService { final OverlayInfo oi = mImpl.getOverlayInfo(packageName, userId); if (oi != null) { mImpl.onOverlayPackageUpgrading(packageName, userId); - } else { - mImpl.onTargetPackageUpgrading(packageName, userId); } } } diff --git a/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java b/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java index 15ed06311758..a3d63806b7e7 100644 --- a/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java +++ b/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java @@ -22,7 +22,6 @@ import static android.content.om.OverlayInfo.STATE_ENABLED_STATIC; import static android.content.om.OverlayInfo.STATE_MISSING_TARGET; import static android.content.om.OverlayInfo.STATE_NO_IDMAP; import static android.content.om.OverlayInfo.STATE_OVERLAY_UPGRADING; -import static android.content.om.OverlayInfo.STATE_TARGET_UPGRADING; import static com.android.server.om.OverlayManagerService.DEBUG; import static com.android.server.om.OverlayManagerService.TAG; @@ -30,12 +29,15 @@ import static com.android.server.om.OverlayManagerService.TAG; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.om.OverlayInfo; +import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.text.TextUtils; import android.util.ArrayMap; import android.util.ArraySet; import android.util.Slog; +import com.android.internal.util.ArrayUtils; + import java.io.PrintWriter; import java.util.ArrayList; import java.util.Iterator; @@ -54,8 +56,14 @@ import java.util.Set; * @see OverlayManagerService */ final class OverlayManagerServiceImpl { - // Flags to use in conjunction with updateState. + + /** + * @deprecated Not used. See {@link android.content.om.OverlayInfo#STATE_TARGET_UPGRADING}. + */ + @Deprecated private static final int FLAG_TARGET_IS_UPGRADING = 1 << 0; + + // Flags to use in conjunction with updateState. private static final int FLAG_OVERLAY_IS_UPGRADING = 1 << 1; private final PackageManagerHelper mPackageManager; @@ -247,9 +255,7 @@ final class OverlayManagerServiceImpl { Slog.d(TAG, "onTargetPackageAdded packageName=" + packageName + " userId=" + userId); } - if (updateAllOverlaysForTarget(packageName, userId, 0)) { - mListener.onOverlaysChanged(packageName, userId); - } + updateAndRefreshOverlaysForTarget(packageName, userId, 0); } void onTargetPackageChanged(@NonNull final String packageName, final int userId) { @@ -257,16 +263,7 @@ final class OverlayManagerServiceImpl { Slog.d(TAG, "onTargetPackageChanged packageName=" + packageName + " userId=" + userId); } - updateAllOverlaysForTarget(packageName, userId, 0); - } - - void onTargetPackageUpgrading(@NonNull final String packageName, final int userId) { - if (DEBUG) { - Slog.d(TAG, "onTargetPackageUpgrading packageName=" + packageName + " userId=" - + userId); - } - - updateAllOverlaysForTarget(packageName, userId, FLAG_TARGET_IS_UPGRADING); + updateAndRefreshOverlaysForTarget(packageName, userId, 0); } void onTargetPackageUpgraded(@NonNull final String packageName, final int userId) { @@ -274,7 +271,7 @@ final class OverlayManagerServiceImpl { Slog.d(TAG, "onTargetPackageUpgraded packageName=" + packageName + " userId=" + userId); } - updateAllOverlaysForTarget(packageName, userId, 0); + updateAndRefreshOverlaysForTarget(packageName, userId, 0); } void onTargetPackageRemoved(@NonNull final String packageName, final int userId) { @@ -282,22 +279,27 @@ final class OverlayManagerServiceImpl { Slog.d(TAG, "onTargetPackageRemoved packageName=" + packageName + " userId=" + userId); } - if (updateAllOverlaysForTarget(packageName, userId, 0)) { - mListener.onOverlaysChanged(packageName, userId); - } + updateAndRefreshOverlaysForTarget(packageName, userId, 0); } /** * Update the state of any overlays for this target. - * - * Returns true if the system should refresh the app's overlay paths (i.e. - * if the settings were modified for this target, or there is at least one - * enabled framework overlay). */ - private boolean updateAllOverlaysForTarget(@NonNull final String targetPackageName, + private void updateAndRefreshOverlaysForTarget(@NonNull final String targetPackageName, final int userId, final int flags) { + final List<OverlayInfo> ois = new ArrayList<>(); + + // Framework overlays added first because order matters when resolving a resource + if (!"android".equals(targetPackageName)) { + ois.addAll(mSettings.getOverlaysForTarget("android", userId)); + } + + // Then add the targeted, non-framework overlays which have higher priority + ois.addAll(mSettings.getOverlaysForTarget(targetPackageName, userId)); + + final List<String> enabledBaseCodePaths = new ArrayList<>(ois.size()); + boolean modified = false; - final List<OverlayInfo> ois = mSettings.getOverlaysForTarget(targetPackageName, userId); final int n = ois.size(); for (int i = 0; i < n; i++) { final OverlayInfo oi = ois.get(i); @@ -313,13 +315,35 @@ final class OverlayManagerServiceImpl { Slog.e(TAG, "failed to update settings", e); modified |= mSettings.remove(oi.packageName, userId); } + + if (oi.isEnabled() && overlayPackage.applicationInfo != null) { + enabledBaseCodePaths.add(overlayPackage.applicationInfo.getBaseCodePath()); + } } } - // check for enabled framework overlays - modified = modified || !getEnabledOverlayPackageNames("android", userId).isEmpty(); + if (!modified) { + PackageInfo packageInfo = mPackageManager.getPackageInfo(targetPackageName, userId); + ApplicationInfo appInfo = packageInfo == null ? null : packageInfo.applicationInfo; + String[] resourceDirs = appInfo == null ? null : appInfo.resourceDirs; + + // If the lists aren't the same length, the enabled overlays have changed + if (ArrayUtils.size(resourceDirs) != enabledBaseCodePaths.size()) { + modified = true; + } else if (resourceDirs != null) { + // If any element isn't equal, an overlay or the order of overlays has changed + for (int index = 0; index < resourceDirs.length; index++) { + if (!resourceDirs[index].equals(enabledBaseCodePaths.get(index))) { + modified = true; + break; + } + } + } + } - return modified; + if (modified) { + mListener.onOverlaysChanged(targetPackageName, userId); + } } void onOverlayPackageAdded(@NonNull final String packageName, final int userId) { @@ -670,10 +694,6 @@ final class OverlayManagerServiceImpl { @Nullable final PackageInfo overlayPackage, final int userId, final int flags) throws OverlayManagerSettings.BadKeyException { - if ((flags & FLAG_TARGET_IS_UPGRADING) != 0) { - return STATE_TARGET_UPGRADING; - } - if ((flags & FLAG_OVERLAY_IS_UPGRADING) != 0) { return STATE_OVERLAY_UPGRADING; } diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java index afa5ae907fc0..ce3c452044f8 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerService.java +++ b/services/core/java/com/android/server/pm/PackageInstallerService.java @@ -396,6 +396,11 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements } finally { IoUtils.closeQuietly(fis); } + // After all of the sessions were loaded, they are ready to be sealed and validated + for (int i = 0; i < mSessions.size(); ++i) { + PackageInstallerSession session = mSessions.valueAt(i); + session.sealAndValidateIfNecessary(); + } } @GuardedBy("mSessions") diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java index f1d4524cccac..5d539a4b1dda 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerSession.java +++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java @@ -231,6 +231,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { @GuardedBy("mLock") private boolean mSealed = false; @GuardedBy("mLock") + private boolean mShouldBeSealed = false; + @GuardedBy("mLock") private boolean mCommitted = false; @GuardedBy("mLock") private boolean mRelinquished = false; @@ -430,6 +432,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { this.updatedMillis = createdMillis; this.stageDir = stageDir; this.stageCid = stageCid; + this.mShouldBeSealed = sealed; if (childSessionIds != null) { for (int childSessionId : childSessionIds) { mChildSessionIds.put(childSessionId, 0); @@ -450,16 +453,6 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { mStagedSessionErrorCode = stagedSessionErrorCode; mStagedSessionErrorMessage = stagedSessionErrorMessage != null ? stagedSessionErrorMessage : ""; - if (sealed) { - synchronized (mLock) { - try { - sealAndValidateLocked(); - } catch (PackageManagerException | IOException e) { - destroyInternal(); - throw new IllegalArgumentException(e); - } - } - } } public SessionInfo generateInfo() { @@ -932,6 +925,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { @NonNull IntentSender statusReceiver, boolean forTransfer) { Preconditions.checkNotNull(statusReceiver); + List<PackageInstallerSession> childSessions = getChildSessions(); + final boolean wasSealed; synchronized (mLock) { assertCallerIsOwnerOrRootLocked(); @@ -963,7 +958,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { wasSealed = mSealed; if (!mSealed) { try { - sealAndValidateLocked(); + sealAndValidateLocked(childSessions); } catch (IOException e) { throw new IllegalArgumentException(e); } catch (PackageManagerException e) { @@ -994,21 +989,91 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { return true; } + /** Return a list of child sessions or null if the session is not multipackage + * + * <p> This method is handy to prevent potential deadlocks (b/123391593) + */ + private @Nullable List<PackageInstallerSession> getChildSessions() { + List<PackageInstallerSession> childSessions = null; + if (isMultiPackage()) { + final int[] childSessionIds = getChildSessionIds(); + childSessions = new ArrayList<>(childSessionIds.length); + for (int childSessionId : childSessionIds) { + childSessions.add(mSessionProvider.getSession(childSessionId)); + } + } + return childSessions; + } + + /** + * Assert multipackage install has consistent sessions. + * + * @throws PackageManagerException if child sessions don't match parent session + * in respect to staged and enable rollback parameters. + */ + @GuardedBy("mLock") + private void assertMultiPackageConsistencyLocked( + @NonNull List<PackageInstallerSession> childSessions) throws PackageManagerException { + for (PackageInstallerSession childSession : childSessions) { + // It might be that the parent session is loaded before all of it's child sessions are, + // e.g. when reading sessions from XML. Those sessions will be null here, and their + // conformance with the multipackage params will be checked when they're loaded. + if (childSession == null) { + continue; + } + assertConsistencyWithLocked(childSession); + } + } + + /** + * Assert consistency with the given session. + * + * @throws PackageManagerException if other sessions doesn't match this session + * in respect to staged and enable rollback parameters. + */ + @GuardedBy("mLock") + private void assertConsistencyWithLocked(PackageInstallerSession other) + throws PackageManagerException { + // Session groups must be consistent wrt to isStaged parameter. Non-staging session + // cannot be grouped with staging sessions. + if (this.params.isStaged != other.params.isStaged) { + throw new PackageManagerException( + PackageManager.INSTALL_FAILED_MULTIPACKAGE_INCONSISTENCY, + "Multipackage Inconsistency: session " + other.sessionId + + " and session " + sessionId + + " have inconsistent staged settings"); + } + if (this.params.getEnableRollback() != other.params.getEnableRollback()) { + throw new PackageManagerException( + PackageManager.INSTALL_FAILED_MULTIPACKAGE_INCONSISTENCY, + "Multipackage Inconsistency: session " + other.sessionId + + " and session " + sessionId + + " have inconsistent rollback settings"); + } + } + /** * Seal the session to prevent further modification and validate the contents of it. * * <p>The session will be sealed after calling this method even if it failed. * + * @param childSessions the child sessions of a multipackage that will be checked for + * consistency. Can be null if session is not multipackage. * @throws PackageManagerException if the session was sealed but something went wrong. If the * session was sealed this is the only possible exception. */ @GuardedBy("mLock") - private void sealAndValidateLocked() throws PackageManagerException, IOException { + private void sealAndValidateLocked(List<PackageInstallerSession> childSessions) + throws PackageManagerException, IOException { assertNoWriteFileTransfersOpenLocked(); assertPreparedAndNotDestroyedLocked("sealing of session"); mSealed = true; + if (childSessions != null) { + assertMultiPackageConsistencyLocked(childSessions); + } + if (params.isStaged) { final PackageInstallerSession activeSession = mStagingManager.getActiveSession(); final boolean anotherSessionAlreadyInProgress = @@ -1048,6 +1113,38 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } } + /** + * If session should be sealed, then it's sealed to prevent further modification + * and then it's validated. + * + * If the session was sealed but something went wrong then it's destroyed. + * + * <p> This is meant to be called after all of the sessions are loaded and added to + * PackageInstallerService + */ + void sealAndValidateIfNecessary() { + synchronized (mLock) { + if (!mShouldBeSealed) { + return; + } + } + List<PackageInstallerSession> childSessions = getChildSessions(); + synchronized (mLock) { + try { + sealAndValidateLocked(childSessions); + } catch (IOException e) { + throw new IllegalStateException(e); + } catch (PackageManagerException e) { + Slog.e(TAG, "Package not valid", e); + // Session is sealed but could not be verified, we need to destroy it. + destroyInternal(); + // Dispatch message to remove session from PackageInstallerService + dispatchSessionFinished( + e.error, ExceptionUtils.getCompleteMessage(e), null); + } + } + } + /** Update the timestamp of when the staged session last changed state */ public void markUpdated() { synchronized (mLock) { @@ -1076,12 +1173,14 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { throw new SecurityException("Can only transfer sessions that use public options"); } + List<PackageInstallerSession> childSessions = getChildSessions(); + synchronized (mLock) { assertCallerIsOwnerOrRootLocked(); assertPreparedAndNotSealedLocked("transfer"); try { - sealAndValidateLocked(); + sealAndValidateLocked(childSessions); } catch (IOException e) { throw new IllegalStateException(e); } catch (PackageManagerException e) { @@ -1132,14 +1231,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { // outside of the lock, because reading the child // sessions with the lock held could lead to deadlock // (b/123391593). - List<PackageInstallerSession> childSessions = null; - if (isMultiPackage()) { - final int[] childSessionIds = getChildSessionIds(); - childSessions = new ArrayList<>(childSessionIds.length); - for (int childSessionId : childSessionIds) { - childSessions.add(mSessionProvider.getSession(childSessionId)); - } - } + List<PackageInstallerSession> childSessions = getChildSessions(); try { synchronized (mLock) { @@ -1965,15 +2057,6 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { + " does not exist"), false, true).rethrowAsRuntimeException(); } - // Session groups must be consistent wrt to isStaged parameter. Non-staging session - // cannot be grouped with staging sessions. - if (this.params.isStaged ^ childSession.params.isStaged) { - throw new RemoteException("Unable to add child.", - new PackageManagerException("Child session " + childSessionId - + " and parent session " + this.sessionId + " do not have consistent" - + " staging session settings."), - false, true); - } synchronized (mLock) { assertCallerIsOwnerOrRootLocked(); assertPreparedAndNotSealedLocked("addChildSessionId"); diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 3833afc6c63b..3cab9e553e8e 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -20272,6 +20272,11 @@ public class PackageManagerService extends IPackageManager.Stub return mContext.getString(R.string.config_defaultTextClassifierPackage); } + @Override + public String getAttentionServicePackageName() { + return mContext.getString(R.string.config_defaultAttentionService); + } + private @Nullable String getDocumenterPackageName() { final Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT); intent.addCategory(Intent.CATEGORY_OPENABLE); diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java index 096335e884ad..6a1f223917b6 100644 --- a/services/core/java/com/android/server/pm/Settings.java +++ b/services/core/java/com/android/server/pm/Settings.java @@ -4383,6 +4383,7 @@ public final class Settings { ApplicationInfo.PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION, "PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION", ApplicationInfo.PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_UNRESIZEABLE, "PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_UNRESIZEABLE", ApplicationInfo.PRIVATE_FLAG_ALLOW_AUDIO_PLAYBACK_CAPTURE, "ALLOW_AUDIO_PLAYBACK_CAPTURE", + ApplicationInfo.PRIVATE_FLAG_ALLOW_EXTERNAL_STORAGE_SANDBOX, "ALLOW_EXTERNAL_STORAGE_SANDBOX", ApplicationInfo.PRIVATE_FLAG_BACKUP_IN_FOREGROUND, "BACKUP_IN_FOREGROUND", ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE, "CANT_SAVE_STATE", ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE, "DEFAULT_TO_DEVICE_PROTECTED_STORAGE", diff --git a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java index e6e2c76de829..18332001e268 100644 --- a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java +++ b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java @@ -740,6 +740,14 @@ public final class DefaultPermissionGrantPolicy { LOCATION_PERMISSIONS, CONTACTS_PERMISSIONS); } + // Atthention Service + String attentionServicePackageName = + mContext.getPackageManager().getAttentionServicePackageName(); + if (!TextUtils.isEmpty(attentionServicePackageName)) { + grantPermissionsToSystemPackage(attentionServicePackageName, userId, + CAMERA_PERMISSIONS); + } + // There is no real "marker" interface to identify the shared storage backup, it is // hardcoded in BackupManagerService.SHARED_BACKUP_AGENT_PACKAGE. grantSystemFixedPermissionsToSystemPackage("com.android.sharedstoragebackup", userId, diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index d4d752f454df..88109d32e55a 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -2223,6 +2223,11 @@ public class PhoneWindowManager implements WindowManagerPolicy { @Override public boolean canBeHiddenByKeyguardLw(WindowState win) { + + // Keyguard visibility of window from activities are determined over activity visibility. + if (win.getAppToken() != null) { + return false; + } switch (win.getAttrs().type) { case TYPE_STATUS_BAR: case TYPE_NAVIGATION_BAR: @@ -2236,19 +2241,30 @@ public class PhoneWindowManager implements WindowManagerPolicy { } private boolean shouldBeHiddenByKeyguard(WindowState win, WindowState imeTarget) { + final LayoutParams attrs = win.getAttrs(); - // Keyguard visibility of window from activities are determined over activity visibility. - if (win.getAppToken() != null) { - return false; + boolean hideDockDivider = attrs.type == TYPE_DOCK_DIVIDER + && !mWindowManagerInternal.isStackVisibleLw(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY); + if (hideDockDivider) { + return true; + } + + // If AOD is showing, the IME should be hidden. However, sometimes the AOD is considered + // hidden because it's in the process of hiding, but it's still being shown on screen. + // In that case, we want to continue hiding the IME until the windows have completed + // drawing. This way, we know that the IME can be safely shown since the other windows are + // now shown. + final boolean hideIme = win.isInputMethodWindow() + && (mAodShowing || !mDefaultDisplayPolicy.isWindowManagerDrawComplete()); + if (hideIme) { + return true; } - final LayoutParams attrs = win.getAttrs(); final boolean showImeOverKeyguard = imeTarget != null && imeTarget.isVisibleLw() && (imeTarget.canShowWhenLocked() || !canBeHiddenByKeyguardLw(imeTarget)); // Show IME over the keyguard if the target allows it - boolean allowWhenLocked = (win.isInputMethodWindow() || imeTarget == this) - && showImeOverKeyguard; + boolean allowWhenLocked = win.isInputMethodWindow() && showImeOverKeyguard; final boolean isKeyguardShowing = mKeyguardDelegate.isShowing(); @@ -2259,17 +2275,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { || (attrs.privateFlags & PRIVATE_FLAG_SYSTEM_ERROR) != 0; } - boolean hideDockDivider = attrs.type == TYPE_DOCK_DIVIDER - && !mWindowManagerInternal.isStackVisible(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY); - // If AOD is showing, the IME should be hidden. However, sometimes the AOD is considered - // hidden because it's in the process of hiding, but it's still being shown on screen. - // In that case, we want to continue hiding the IME until the windows have completed - // drawing. This way, we know that the IME can be safely shown since the other windows are - // now shown. - final boolean hideIme = win.isInputMethodWindow() - && (mAodShowing || !mDefaultDisplayPolicy.isWindowManagerDrawComplete()); - return (isKeyguardShowing && !allowWhenLocked && win.getDisplayId() == DEFAULT_DISPLAY) - || hideDockDivider || hideIme; + return isKeyguardShowing && !allowWhenLocked && win.getDisplayId() == DEFAULT_DISPLAY; } /** {@inheritDoc} */ diff --git a/services/core/java/com/android/server/power/batterysaver/BatterySaverPolicy.java b/services/core/java/com/android/server/power/batterysaver/BatterySaverPolicy.java index f23b68e28c34..38bdc62c5761 100644 --- a/services/core/java/com/android/server/power/batterysaver/BatterySaverPolicy.java +++ b/services/core/java/com/android/server/power/batterysaver/BatterySaverPolicy.java @@ -594,7 +594,7 @@ public class BatterySaverPolicy extends ContentObserver { boolean forceBackgroundCheck, int locationMode) { - this.adjustBrightnessFactor = adjustBrightnessFactor; + this.adjustBrightnessFactor = Math.min(1, Math.max(0, adjustBrightnessFactor)); this.advertiseIsEnabled = advertiseIsEnabled; this.deferFullBackup = deferFullBackup; this.deferKeyValueBackup = deferKeyValueBackup; @@ -613,7 +613,14 @@ public class BatterySaverPolicy extends ContentObserver { this.filesForNoninteractive = filesForNoninteractive; this.forceAllAppsStandby = forceAllAppsStandby; this.forceBackgroundCheck = forceBackgroundCheck; - this.locationMode = locationMode; + + if (locationMode < PowerManager.MIN_LOCATION_MODE + || PowerManager.MAX_LOCATION_MODE < locationMode) { + Slog.e(TAG, "Invalid location mode: " + locationMode); + this.locationMode = PowerManager.LOCATION_MODE_NO_CHANGE; + } else { + this.locationMode = locationMode; + } mHashCode = Objects.hash( adjustBrightnessFactor, diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java index 0c9f81525509..c2a4339eceda 100644 --- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java +++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java @@ -1719,6 +1719,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub final WallpaperData systemWallpaper = getWallpaperSafeLocked(userId, FLAG_SYSTEM); switchWallpaper(systemWallpaper, null); + notifyCallbacksLocked(systemWallpaper); } // Make sure that the SELinux labeling of all the relevant files is correct. diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index 5bbabfceda47..a93bdbaabdc7 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -1102,7 +1102,7 @@ final class ActivityRecord extends ConfigurationContainer { ActivityTaskManagerService.getInputDispatchingTimeoutLocked(this) * 1000000L, fullscreen, (info.flags & FLAG_SHOW_FOR_ALL_USERS) != 0, appInfo.targetSdkVersion, - info.screenOrientation, mRotationAnimationHint, info.configChanges, + info.screenOrientation, mRotationAnimationHint, mLaunchTaskBehind, isAlwaysFocusable()); if (DEBUG_TOKEN_MOVEMENT || DEBUG_ADD_REMOVE) { Slog.v(TAG, "addAppToken: " @@ -1151,11 +1151,11 @@ final class ActivityRecord extends ConfigurationContainer { AppWindowToken createAppWindow(WindowManagerService service, IApplicationToken token, boolean voiceInteraction, DisplayContent dc, long inputDispatchingTimeoutNanos, boolean fullscreen, boolean showForAllUsers, int targetSdk, int orientation, - int rotationAnimationHint, int configChanges, boolean launchTaskBehind, + int rotationAnimationHint, boolean launchTaskBehind, boolean alwaysFocusable) { return new AppWindowToken(service, token, mActivityComponent, voiceInteraction, dc, inputDispatchingTimeoutNanos, fullscreen, showForAllUsers, targetSdk, orientation, - rotationAnimationHint, configChanges, launchTaskBehind, alwaysFocusable, + rotationAnimationHint, launchTaskBehind, alwaysFocusable, this); } diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java index c1b9bbad1a3c..a53f85daaa25 100644 --- a/services/core/java/com/android/server/wm/AppWindowToken.java +++ b/services/core/java/com/android/server/wm/AppWindowToken.java @@ -153,7 +153,6 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree /** @see WindowContainer#fillsParent() */ private boolean mFillsParent; - boolean layoutConfigChanges; boolean mShowForAllUsers; int mTargetSdk; @@ -337,7 +336,7 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree AppWindowToken(WindowManagerService service, IApplicationToken token, ComponentName activityComponent, boolean voiceInteraction, DisplayContent dc, long inputDispatchingTimeoutNanos, boolean fullscreen, boolean showForAllUsers, - int targetSdk, int orientation, int rotationAnimationHint, int configChanges, + int targetSdk, int orientation, int rotationAnimationHint, boolean launchTaskBehind, boolean alwaysFocusable, ActivityRecord activityRecord) { this(service, token, activityComponent, voiceInteraction, dc, fullscreen); @@ -348,7 +347,6 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree mShowForAllUsers = showForAllUsers; mTargetSdk = targetSdk; mOrientation = orientation; - layoutConfigChanges = (configChanges & (CONFIG_SCREEN_SIZE | CONFIG_ORIENTATION)) != 0; mLaunchTaskBehind = launchTaskBehind; mAlwaysFocusable = alwaysFocusable; mRotationAnimationHint = rotationAnimationHint; @@ -1976,7 +1974,7 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree final boolean surfaceReady = w.isDrawnLw() // Regular case || w.mWinAnimator.mSurfaceDestroyDeferred // The preserved surface is still ready. || w.isDragResizeChanged(); // Waiting for relayoutWindow to call preserveSurface. - final boolean needsLetterbox = w.isLetterboxedAppWindow() && fillsParent() && surfaceReady; + final boolean needsLetterbox = surfaceReady && w.isLetterboxedAppWindow() && fillsParent(); if (needsLetterbox) { if (mLetterbox == null) { mLetterbox = new Letterbox(() -> makeChildSurface(null)); diff --git a/services/core/java/com/android/server/wm/BarController.java b/services/core/java/com/android/server/wm/BarController.java index 9bc8462c66e3..3bbe28d429c5 100644 --- a/services/core/java/com/android/server/wm/BarController.java +++ b/services/core/java/com/android/server/wm/BarController.java @@ -173,8 +173,9 @@ public class BarController { } final boolean wasVis = mWin.isVisibleLw(); final boolean wasAnim = mWin.isAnimatingLw(); - final boolean change = show ? mWin.showLw(!mNoAnimationOnNextShow && !skipAnimation()) - : mWin.hideLw(!mNoAnimationOnNextShow && !skipAnimation()); + final boolean skipAnim = skipAnimation(); + final boolean change = show ? mWin.showLw(!mNoAnimationOnNextShow && !skipAnim) + : mWin.hideLw(!mNoAnimationOnNextShow && !skipAnim); mNoAnimationOnNextShow = false; final int state = computeStateLw(wasVis, wasAnim, mWin, change); final boolean stateChanged = updateStateLw(state); diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 0c34e253a394..77055c1095d1 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -28,6 +28,7 @@ import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; import static android.content.res.Configuration.ORIENTATION_LANDSCAPE; import static android.content.res.Configuration.ORIENTATION_PORTRAIT; +import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.Display.FLAG_PRIVATE; import static android.view.Display.FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS; @@ -655,7 +656,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo if (DEBUG_LAYOUT && !w.mLayoutAttached) { Slog.v(TAG, "1ST PASS " + w + ": gone=" + gone + " mHaveFrame=" + w.mHaveFrame + " mLayoutAttached=" + w.mLayoutAttached - + " screen changed=" + w.isConfigChanged()); + + " config reported=" + w.isLastConfigReportedToClient()); final AppWindowToken atoken = w.mAppToken; if (gone) Slog.v(TAG, " GONE: mViewVisibility=" + w.mViewVisibility + " mRelayoutCalled=" + w.mRelayoutCalled + " hidden=" + w.mToken.isHidden() @@ -670,42 +671,34 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo // If this view is GONE, then skip it -- keep the current frame, and let the caller know // so they can ignore it if they want. (We do the normal layout for INVISIBLE windows, // since that means "perform layout as normal, just don't display"). - if (!gone || !w.mHaveFrame || w.mLayoutNeeded - || ((w.isConfigChanged() || w.setReportResizeHints()) - && !w.isGoneForLayoutLw() && - ((w.mAttrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0 || - (w.mHasSurface && w.mAppToken != null && - w.mAppToken.layoutConfigChanges)))) { - if (!w.mLayoutAttached) { - if (mTmpInitial) { - //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial"); - w.resetContentChanged(); - } - if (w.mAttrs.type == TYPE_DREAM) { - // Don't layout windows behind a dream, so that if it does stuff like hide - // the status bar we won't get a bad transition when it goes away. - mTmpWindow = w; - } - w.mLayoutNeeded = false; - w.prelayout(); - final boolean firstLayout = !w.isLaidOut(); - getDisplayPolicy().layoutWindowLw(w, null, mDisplayFrames); - w.mLayoutSeq = mLayoutSeq; - - // If this is the first layout, we need to initialize the last inset values as - // otherwise we'd immediately cause an unnecessary resize. - if (firstLayout) { - w.updateLastInsetValues(); - } + if ((!gone || !w.mHaveFrame || w.mLayoutNeeded) && !w.mLayoutAttached) { + if (mTmpInitial) { + w.resetContentChanged(); + } + if (w.mAttrs.type == TYPE_DREAM) { + // Don't layout windows behind a dream, so that if it does stuff like hide + // the status bar we won't get a bad transition when it goes away. + mTmpWindow = w; + } + w.mLayoutNeeded = false; + w.prelayout(); + final boolean firstLayout = !w.isLaidOut(); + getDisplayPolicy().layoutWindowLw(w, null, mDisplayFrames); + w.mLayoutSeq = mLayoutSeq; - if (w.mAppToken != null) { - w.mAppToken.layoutLetterbox(w); - } + // If this is the first layout, we need to initialize the last inset values as + // otherwise we'd immediately cause an unnecessary resize. + if (firstLayout) { + w.updateLastInsetValues(); + } - if (DEBUG_LAYOUT) Slog.v(TAG, " LAYOUT: mFrame=" + w.getFrameLw() - + " mContainingFrame=" + w.getContainingFrame() - + " mDisplayFrame=" + w.getDisplayFrameLw()); + if (w.mAppToken != null) { + w.mAppToken.layoutLetterbox(w); } + + if (DEBUG_LAYOUT) Slog.v(TAG, " LAYOUT: mFrame=" + w.getFrameLw() + + " mContainingFrame=" + w.getContainingFrame() + + " mDisplayFrame=" + w.getDisplayFrameLw()); } }; @@ -3094,7 +3087,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo /** Updates the layer assignment of windows on this display. */ void assignWindowLayers(boolean setLayoutNeeded) { - Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "assignWindowLayers"); + Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "assignWindowLayers"); assignChildLayers(getPendingTransaction()); if (setLayoutNeeded) { setLayoutNeeded(); @@ -3105,7 +3098,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo // prepareSurfaces. This allows us to synchronize Z-ordering changes with // the hiding and showing of surfaces. scheduleAnimation(); - Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER); + Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); } // TODO: This should probably be called any time a visual change is made to the hierarchy like @@ -3659,9 +3652,14 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo // FIRST AND ONE HALF LOOP: Make WindowManagerPolicy think it is animating. pendingLayoutChanges = 0; - mDisplayPolicy.beginPostLayoutPolicyLw(); - forAllWindows(mApplyPostLayoutPolicy, true /* traverseTopToBottom */); - pendingLayoutChanges |= mDisplayPolicy.finishPostLayoutPolicyLw(); + Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "applyPostLayoutPolicy"); + try { + mDisplayPolicy.beginPostLayoutPolicyLw(); + forAllWindows(mApplyPostLayoutPolicy, true /* traverseTopToBottom */); + pendingLayoutChanges |= mDisplayPolicy.finishPostLayoutPolicyLw(); + } finally { + Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); + } if (DEBUG_LAYOUT_REPEATS) surfacePlacer.debugLayoutRepeats( "after finishPostLayoutPolicyLw", pendingLayoutChanges); mInsetsStateController.onPostLayout(); @@ -3670,7 +3668,13 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo mTmpApplySurfaceChangesTransactionState.reset(); mTmpRecoveringMemory = recoveringMemory; - forAllWindows(mApplySurfaceChangesTransaction, true /* traverseTopToBottom */); + + Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "applyWindowSurfaceChanges"); + try { + forAllWindows(mApplySurfaceChangesTransaction, true /* traverseTopToBottom */); + } finally { + Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); + } prepareSurfaces(); mLastHasContent = mTmpApplySurfaceChangesTransactionState.displayHasContent; @@ -3720,11 +3724,6 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo out.set(left, top, left + width, top + height); } - @Override - public void getBounds(Rect out) { - calculateBounds(mDisplayInfo, out); - } - private void getBounds(Rect out, int orientation) { getBounds(out); @@ -3746,6 +3745,15 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo } void performLayout(boolean initial, boolean updateInputWindows) { + Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "performLayout"); + try { + performLayoutNoTrace(initial, updateInputWindows); + } finally { + Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); + } + } + + private void performLayoutNoTrace(boolean initial, boolean updateInputWindows) { if (!isLayoutNeeded()) { return; } @@ -3755,13 +3763,14 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo final int dh = mDisplayInfo.logicalHeight; if (DEBUG_LAYOUT) { Slog.v(TAG, "-------------------------------------"); - Slog.v(TAG, "performLayout: needed=" + isLayoutNeeded() + " dw=" + dw + " dh=" + dh); + Slog.v(TAG, "performLayout: needed=" + isLayoutNeeded() + " dw=" + dw + + " dh=" + dh); } mDisplayFrames.onDisplayInfoUpdated(mDisplayInfo, calculateDisplayCutoutForRotation(mDisplayInfo.rotation)); - // TODO: Not sure if we really need to set the rotation here since we are updating from the - // display info above... + // TODO: Not sure if we really need to set the rotation here since we are updating from + // the display info above... mDisplayFrames.mRotation = mRotation; mDisplayPolicy.beginLayoutLw(mDisplayFrames, getConfiguration().uiMode); @@ -4801,20 +4810,25 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo @Override void prepareSurfaces() { - final ScreenRotationAnimation screenRotationAnimation = - mWmService.mAnimator.getScreenRotationAnimationLocked(mDisplayId); - if (screenRotationAnimation != null && screenRotationAnimation.isAnimating()) { - screenRotationAnimation.getEnterTransformation().getMatrix().getValues(mTmpFloats); - mPendingTransaction.setMatrix(mWindowingLayer, - mTmpFloats[Matrix.MSCALE_X], mTmpFloats[Matrix.MSKEW_Y], - mTmpFloats[Matrix.MSKEW_X], mTmpFloats[Matrix.MSCALE_Y]); - mPendingTransaction.setPosition(mWindowingLayer, - mTmpFloats[Matrix.MTRANS_X], mTmpFloats[Matrix.MTRANS_Y]); - mPendingTransaction.setAlpha(mWindowingLayer, - screenRotationAnimation.getEnterTransformation().getAlpha()); - } - - super.prepareSurfaces(); + Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "prepareSurfaces"); + try { + final ScreenRotationAnimation screenRotationAnimation = + mWmService.mAnimator.getScreenRotationAnimationLocked(mDisplayId); + if (screenRotationAnimation != null && screenRotationAnimation.isAnimating()) { + screenRotationAnimation.getEnterTransformation().getMatrix().getValues(mTmpFloats); + mPendingTransaction.setMatrix(mWindowingLayer, + mTmpFloats[Matrix.MSCALE_X], mTmpFloats[Matrix.MSKEW_Y], + mTmpFloats[Matrix.MSKEW_X], mTmpFloats[Matrix.MSCALE_Y]); + mPendingTransaction.setPosition(mWindowingLayer, + mTmpFloats[Matrix.MTRANS_X], mTmpFloats[Matrix.MTRANS_Y]); + mPendingTransaction.setAlpha(mWindowingLayer, + screenRotationAnimation.getEnterTransformation().getAlpha()); + } + + super.prepareSurfaces(); + } finally { + Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); + } } void assignStackOrdering() { diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java index 95d894492594..1888e9474267 100644 --- a/services/core/java/com/android/server/wm/DisplayPolicy.java +++ b/services/core/java/com/android/server/wm/DisplayPolicy.java @@ -103,13 +103,16 @@ import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; import static com.android.server.wm.WindowManagerService.localLOGV; +import android.Manifest.permission; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.Px; import android.app.ActivityManager; import android.app.ActivityThread; import android.app.StatusBarManager; import android.content.Context; import android.content.Intent; +import android.content.pm.PackageManager; import android.content.res.Resources; import android.graphics.Insets; import android.graphics.PixelFormat; @@ -255,6 +258,9 @@ public class DisplayPolicy { private int[] mNavigationBarHeightForRotationInCarMode = new int[4]; private int[] mNavigationBarWidthForRotationInCarMode = new int[4]; + /** Cached value of {@link ScreenShapeHelper#getWindowOutsetBottomPx} */ + @Px private int mWindowOutsetBottom; + private final StatusBarController mStatusBarController = new StatusBarController(); private final BarController mNavigationBarController = new BarController("NavigationBar", @@ -731,6 +737,11 @@ public class DisplayPolicy { return true; } + private boolean hasStatusBarServicePermission(int pid, int uid) { + return mContext.checkPermission(permission.STATUS_BAR_SERVICE, pid, uid) + == PackageManager.PERMISSION_GRANTED; + } + /** * Sanitize the layout parameters coming from a client. Allows the policy * to do things like ensure that windows of a specific type can't take @@ -740,7 +751,7 @@ public class DisplayPolicy { * are modified in-place. */ public void adjustWindowParamsLw(WindowState win, WindowManager.LayoutParams attrs, - boolean hasStatusBarServicePermission) { + int callingPid, int callingUid) { final boolean isScreenDecor = (attrs.privateFlags & PRIVATE_FLAG_IS_SCREEN_DECOR) != 0; if (mScreenDecorWindows.contains(win)) { @@ -748,7 +759,7 @@ public class DisplayPolicy { // No longer has the flag set, so remove from the set. mScreenDecorWindows.remove(win); } - } else if (isScreenDecor && hasStatusBarServicePermission) { + } else if (isScreenDecor && hasStatusBarServicePermission(callingPid, callingUid)) { mScreenDecorWindows.add(win); } @@ -1159,7 +1170,7 @@ public class DisplayPolicy { final boolean useOutsets = outOutsets != null && shouldUseOutsets(attrs, fl); if (useOutsets) { - int outset = ScreenShapeHelper.getWindowOutsetBottomPx(mContext.getResources()); + int outset = mWindowOutsetBottom; if (outset > 0) { if (displayRotation == Surface.ROTATION_0) { outOutsets.bottom += outset; @@ -1479,12 +1490,13 @@ public class DisplayPolicy { } // apply any navigation bar insets sTmpRect.setEmpty(); - mStatusBar.getWindowFrames().setFrames(displayFrames.mUnrestricted /* parentFrame */, + final WindowFrames windowFrames = mStatusBar.getWindowFrames(); + windowFrames.setFrames(displayFrames.mUnrestricted /* parentFrame */, displayFrames.mUnrestricted /* displayFrame */, displayFrames.mStable /* overscanFrame */, displayFrames.mStable /* contentFrame */, displayFrames.mStable /* visibleFrame */, sTmpRect /* decorFrame */, displayFrames.mStable /* stableFrame */, displayFrames.mStable /* outsetFrame */); - mStatusBar.getWindowFrames().setDisplayCutout(displayFrames.mDisplayCutout); + windowFrames.setDisplayCutout(displayFrames.mDisplayCutout); // Let the status bar determine its size. mStatusBar.computeFrameLw(); @@ -1524,8 +1536,9 @@ public class DisplayPolicy { "dock=%s content=%s cur=%s", dockFrame.toString(), displayFrames.mContent.toString(), displayFrames.mCurrent.toString())); - if (!mStatusBar.isAnimatingLw() && !statusBarTranslucent - && !mStatusBarController.wasRecentlyTranslucent()) { + if (!statusBarTranslucent && !mStatusBarController.wasRecentlyTranslucent() + && !mStatusBar.isAnimatingLw()) { + // If the opaque status bar is currently requested to be visible, and not in the // process of animating on or off, then we can tell the app that it is covered by // it. @@ -2180,7 +2193,7 @@ public class DisplayPolicy { final Rect osf = windowFrames.mOutsetFrame; osf.set(cf.left, cf.top, cf.right, cf.bottom); windowFrames.setHasOutsets(true); - int outset = ScreenShapeHelper.getWindowOutsetBottomPx(mContext.getResources()); + int outset = mWindowOutsetBottom; if (outset > 0) { int rotation = displayFrames.mRotation; if (rotation == Surface.ROTATION_0) { @@ -2336,7 +2349,7 @@ public class DisplayPolicy { } // Voice interaction overrides both top fullscreen and top docked. - if (affectsSystemUi && win.getAttrs().type == TYPE_VOICE_INTERACTION) { + if (affectsSystemUi && attrs.type == TYPE_VOICE_INTERACTION) { if (mTopFullscreenOpaqueWindowState == null) { mTopFullscreenOpaqueWindowState = win; if (mTopFullscreenOpaqueOrDimmingWindowState == null) { @@ -2599,6 +2612,7 @@ public class DisplayPolicy { // EXPERIMENT END updateConfigurationAndScreenSizeDependentBehaviors(); + mWindowOutsetBottom = ScreenShapeHelper.getWindowOutsetBottomPx(mContext.getResources()); } void updateConfigurationAndScreenSizeDependentBehaviors() { diff --git a/services/core/java/com/android/server/wm/InputConsumerImpl.java b/services/core/java/com/android/server/wm/InputConsumerImpl.java index ab95e4b52dc6..8dae0163b612 100644 --- a/services/core/java/com/android/server/wm/InputConsumerImpl.java +++ b/services/core/java/com/android/server/wm/InputConsumerImpl.java @@ -16,6 +16,7 @@ package com.android.server.wm; +import android.graphics.Point; import android.graphics.Rect; import android.os.Binder; import android.os.IBinder; @@ -43,6 +44,9 @@ class InputConsumerImpl implements IBinder.DeathRecipient { final SurfaceControl mInputSurface; Rect mTmpClipRect = new Rect(); + private final Rect mTmpRect = new Rect(); + private final Point mOldPosition = new Point(); + private final Rect mOldWindowCrop = new Rect(); InputConsumerImpl(WindowManagerService service, IBinder token, String name, InputChannel inputChannel, int clientPid, UserHandle clientUser, int displayId) { @@ -112,16 +116,22 @@ class InputConsumerImpl implements IBinder.DeathRecipient { } void layout(SurfaceControl.Transaction t, int dw, int dh) { - t.setPosition(mInputSurface, 0, 0); - - mTmpClipRect.set(0, 0, dw, dh); - t.setWindowCrop(mInputSurface, mTmpClipRect); + mTmpRect.set(0, 0, dw, dh); + layout(t, mTmpRect); } void layout(SurfaceControl.Transaction t, Rect r) { - t.setPosition(mInputSurface, r.left, r.top); mTmpClipRect.set(0, 0, r.width(), r.height()); + + if (mOldPosition.equals(r.left, r.top) && mOldWindowCrop.equals(mTmpClipRect)) { + return; + } + + t.setPosition(mInputSurface, r.left, r.top); t.setWindowCrop(mInputSurface, mTmpClipRect); + + mOldPosition.set(r.left, r.top); + mOldWindowCrop.set(mTmpClipRect); } void hide(SurfaceControl.Transaction t) { diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java index 56694519b7fc..835b9b1885a3 100644 --- a/services/core/java/com/android/server/wm/InputMonitor.java +++ b/services/core/java/com/android/server/wm/InputMonitor.java @@ -16,6 +16,7 @@ package com.android.server.wm; +import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER; import static android.view.WindowManager.INPUT_CONSUMER_NAVIGATION; import static android.view.WindowManager.INPUT_CONSUMER_PIP; import static android.view.WindowManager.INPUT_CONSUMER_RECENTS_ANIMATION; @@ -190,8 +191,13 @@ final class InputMonitor { } void layoutInputConsumers(int dw, int dh) { - for (int i = mInputConsumers.size() - 1; i >= 0; i--) { - mInputConsumers.valueAt(i).layout(mInputTransaction, dw, dh); + try { + Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "layoutInputConsumer"); + for (int i = mInputConsumers.size() - 1; i >= 0; i--) { + mInputConsumers.valueAt(i).layout(mInputTransaction, dw, dh); + } + } finally { + Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); } } @@ -401,7 +407,7 @@ final class InputMonitor { final InputWindowHandle mInvalidInputWindow = new InputWindowHandle(null, null, mDisplayId); private void updateInputWindows(boolean inDrag) { - Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "updateInputWindows"); + Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "updateInputWindows"); navInputConsumer = getInputConsumer(INPUT_CONSUMER_NAVIGATION); pipInputConsumer = getInputConsumer(INPUT_CONSUMER_PIP); @@ -429,7 +435,7 @@ final class InputMonitor { mDisplayContent.scheduleAnimation(); - Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER); + Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); } @Override diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java index ed5f6658197b..1ca31f127b0d 100644 --- a/services/core/java/com/android/server/wm/RootWindowContainer.java +++ b/services/core/java/com/android/server/wm/RootWindowContainer.java @@ -16,6 +16,7 @@ package com.android.server.wm; +import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.Display.INVALID_DISPLAY; import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON; @@ -65,6 +66,7 @@ import android.os.Looper; import android.os.Message; import android.os.PowerManager; import android.os.RemoteException; +import android.os.Trace; import android.os.UserHandle; import android.util.ArraySet; import android.util.EventLog; @@ -551,18 +553,26 @@ class RootWindowContainer extends WindowContainer<DisplayContent> return leakedSurface || killedApps; } + void performSurfacePlacement(boolean recoveringMemory) { + Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "performSurfacePlacement"); + try { + performSurfacePlacementNoTrace(recoveringMemory); + } finally { + Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); + } + } + // "Something has changed! Let's make it correct now." // TODO: Super crazy long method that should be broken down... - void performSurfacePlacement(boolean recoveringMemory) { + void performSurfacePlacementNoTrace(boolean recoveringMemory) { if (DEBUG_WINDOW_TRACE) Slog.v(TAG, "performSurfacePlacementInner: entry. Called by " + Debug.getCallers(3)); int i; - boolean updateInputWindowsNeeded = false; if (mWmService.mFocusMayChange) { mWmService.mFocusMayChange = false; - updateInputWindowsNeeded = mWmService.updateFocusedWindowLocked( + mWmService.updateFocusedWindowLocked( UPDATE_FOCUS_WILL_PLACE_SURFACES, false /*updateInputWindows*/); } @@ -586,6 +596,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION performLayoutAndPlaceSurfaces"); + Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "applySurfaceChanges"); mWmService.openSurfaceTransaction(); try { applySurfaceChangesTransaction(recoveringMemory); @@ -593,6 +604,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> Slog.wtf(TAG, "Unhandled exception in Window Manager", e); } finally { mWmService.closeSurfaceTransaction("performLayoutAndPlaceSurfaces"); + Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION performLayoutAndPlaceSurfaces"); } @@ -621,10 +633,8 @@ class RootWindowContainer extends WindowContainer<DisplayContent> if (mWmService.mFocusMayChange) { mWmService.mFocusMayChange = false; - if (mWmService.updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES, - false /*updateInputWindows*/)) { - updateInputWindowsNeeded = true; - } + mWmService.updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES, + false /*updateInputWindows*/); } if (isLayoutNeeded()) { @@ -679,12 +689,6 @@ class RootWindowContainer extends WindowContainer<DisplayContent> } } - // Finally update all input windows now that the window changes have stabilized. - forAllDisplays(dc -> { - dc.getInputMonitor().updateInputWindowsLw(true /*force*/); - dc.updateSystemGestureExclusion(); - }); - mWmService.setHoldScreenLocked(mHoldScreen); if (!mWmService.mDisplayFrozen) { final int brightness = mScreenBrightness < 0 || mScreenBrightness > 1.0f @@ -710,7 +714,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> if (mWmService.mWaitingForDrawnCallback != null || (mOrientationChangeComplete && !isLayoutNeeded() - && !mUpdateRotation)) { + && !mUpdateRotation)) { mWmService.checkDrawnWindowsLocked(); } @@ -742,12 +746,11 @@ class RootWindowContainer extends WindowContainer<DisplayContent> mChildren.get(displayNdx).checkCompleteDeferredRemoval(); } - if (updateInputWindowsNeeded) { - forAllDisplays(dc -> { - dc.getInputMonitor().updateInputWindowsLw(false /*force*/); - }); - } - forAllDisplays(DisplayContent::updateTouchExcludeRegion); + forAllDisplays(dc -> { + dc.getInputMonitor().updateInputWindowsLw(true /*force*/); + dc.updateSystemGestureExclusion(); + dc.updateTouchExcludeRegion(); + }); // Check to see if we are now in a state where the screen should // be enabled, because the window obscured flags have changed. @@ -776,7 +779,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> } } - if (!curDisplay.isAppAnimating() && curDisplay.mAppTransition.isRunning()) { + if (curDisplay.mAppTransition.isRunning() && !curDisplay.isAppAnimating()) { // We have finished the animation of an app transition. To do this, we have // delayed a lot of operations like showing and hiding apps, moving apps in // Z-order, etc. diff --git a/services/core/java/com/android/server/wm/WindowFrames.java b/services/core/java/com/android/server/wm/WindowFrames.java index 20a874b7d0e8..9fe47604d704 100644 --- a/services/core/java/com/android/server/wm/WindowFrames.java +++ b/services/core/java/com/android/server/wm/WindowFrames.java @@ -244,8 +244,6 @@ public class WindowFrames { void calculateOutsets() { if (mHasOutsets) { InsetUtils.insetsBetweenFrames(mOutsetFrame, mContentFrame, mOutsets); - } else { - mOutsets.setEmpty(); } } @@ -373,7 +371,13 @@ public class WindowFrames { * Sets whether the frame has outsets. */ public void setHasOutsets(boolean hasOutsets) { + if (mHasOutsets == hasOutsets) { + return; + } mHasOutsets = hasOutsets; + if (!hasOutsets) { + mOutsets.setEmpty(); + } } /** diff --git a/services/core/java/com/android/server/wm/WindowManagerInternal.java b/services/core/java/com/android/server/wm/WindowManagerInternal.java index d3f3711db0d8..9d80425435ef 100644 --- a/services/core/java/com/android/server/wm/WindowManagerInternal.java +++ b/services/core/java/com/android/server/wm/WindowManagerInternal.java @@ -414,7 +414,7 @@ public abstract class WindowManagerInternal { OnHardKeyboardStatusChangeListener listener); /** Returns true if a stack in the windowing mode is currently visible. */ - public abstract boolean isStackVisible(int windowingMode); + public abstract boolean isStackVisibleLw(int windowingMode); /** * Requests the window manager to resend the windows for accessibility. diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 9e421c1d7db5..20d02ee5355e 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -1392,11 +1392,9 @@ public class WindowManagerService extends IWindowManager.Stub return WindowManagerGlobal.ADD_INVALID_DISPLAY; } - final boolean hasStatusBarServicePermission = - mContext.checkCallingOrSelfPermission(permission.STATUS_BAR_SERVICE) - == PackageManager.PERMISSION_GRANTED; final DisplayPolicy displayPolicy = displayContent.getDisplayPolicy(); - displayPolicy.adjustWindowParamsLw(win, win.mAttrs, hasStatusBarServicePermission); + displayPolicy.adjustWindowParamsLw(win, win.mAttrs, Binder.getCallingPid(), + Binder.getCallingUid()); win.setShowToOwnerOnlyLocked(mPolicy.checkShowToOwnerOnly(attrs)); res = displayPolicy.prepareAddWindowLw(win, attrs); @@ -1932,6 +1930,11 @@ public class WindowManagerService extends IWindowManager.Stub } } + private boolean hasStatusBarPermission(int pid, int uid) { + return mContext.checkPermission(permission.STATUS_BAR, pid, uid) + == PackageManager.PERMISSION_GRANTED; + } + public int relayoutWindow(Session session, IWindow client, int seq, LayoutParams attrs, int requestedWidth, int requestedHeight, int viewVisibility, int flags, long frameNumber, Rect outFrame, Rect outOverscanInsets, Rect outContentInsets, @@ -1940,13 +1943,8 @@ public class WindowManagerService extends IWindowManager.Stub SurfaceControl outSurfaceControl, InsetsState outInsetsState) { int result = 0; boolean configChanged; - final boolean hasStatusBarPermission = - mContext.checkCallingOrSelfPermission(permission.STATUS_BAR) - == PackageManager.PERMISSION_GRANTED; - final boolean hasStatusBarServicePermission = - mContext.checkCallingOrSelfPermission(permission.STATUS_BAR_SERVICE) - == PackageManager.PERMISSION_GRANTED; - + final int pid = Binder.getCallingPid(); + final int uid = Binder.getCallingUid(); long origId = Binder.clearCallingIdentity(); final int displayId; synchronized (mGlobalLock) { @@ -1973,13 +1971,13 @@ public class WindowManagerService extends IWindowManager.Stub int attrChanges = 0; int flagChanges = 0; if (attrs != null) { - displayPolicy.adjustWindowParamsLw(win, attrs, hasStatusBarServicePermission); + displayPolicy.adjustWindowParamsLw(win, attrs, pid, uid); // if they don't have the permission, mask out the status bar bits if (seq == win.mSeq) { int systemUiVisibility = attrs.systemUiVisibility | attrs.subtreeSystemUiVisibility; if ((systemUiVisibility & DISABLE_MASK) != 0) { - if (!hasStatusBarPermission) { + if (!hasStatusBarPermission(pid, uid)) { systemUiVisibility &= ~DISABLE_MASK; } } @@ -2050,7 +2048,6 @@ public class WindowManagerService extends IWindowManager.Stub && viewVisibility == View.VISIBLE; boolean imMayMove = (flagChanges & (FLAG_ALT_FOCUSABLE_IM | FLAG_NOT_FOCUSABLE)) != 0 || becameVisible; - final boolean isDefaultDisplay = win.isDefaultDisplay(); boolean focusMayChange = win.mViewVisibility != viewVisibility || ((flagChanges & FLAG_NOT_FOCUSABLE) != 0) || (!win.mRelayoutCalled); @@ -7215,11 +7212,9 @@ public class WindowManagerService extends IWindowManager.Stub } @Override - public boolean isStackVisible(int windowingMode) { - synchronized (mGlobalLock) { - final DisplayContent dc = getDefaultDisplayContentLocked(); - return dc.isStackVisible(windowingMode); - } + public boolean isStackVisibleLw(int windowingMode) { + final DisplayContent dc = getDefaultDisplayContentLocked(); + return dc.isStackVisible(windowingMode); } @Override diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 486b0da7b2bf..11288d27fce6 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -308,6 +308,9 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP */ private final MergedConfiguration mLastReportedConfiguration = new MergedConfiguration(); + /** @see #isLastConfigReportedToClient() */ + private boolean mLastConfigReportedToClient; + private final Configuration mTempConfiguration = new Configuration(); /** @@ -1201,7 +1204,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP } boolean didFrameInsetsChange = setReportResizeHints(); - boolean configChanged = isConfigChanged(); + boolean configChanged = !isLastConfigReportedToClient(); if (DEBUG_CONFIGURATION && configChanged) { Slog.v(TAG_WM, "Win " + this + " config changed: " + getConfiguration()); } @@ -1781,9 +1784,18 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP return getDisplayContent().getBounds().equals(getBounds()); } - /** Returns true if last applied config was not yet requested by client. */ - boolean isConfigChanged() { - return !getLastReportedConfiguration().equals(getConfiguration()); + /** + * @return {@code true} if last applied config was reported to the client already, {@code false} + * otherwise. + */ + boolean isLastConfigReportedToClient() { + return mLastConfigReportedToClient; + } + + @Override + void onMergedOverrideConfigurationChanged() { + super.onMergedOverrideConfigurationChanged(); + mLastConfigReportedToClient = false; } void onWindowReplacementTimeout() { @@ -2299,11 +2311,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP void prepareWindowToDisplayDuringRelayout(boolean wasVisible) { // We need to turn on screen regardless of visibility. boolean hasTurnScreenOnFlag = (mAttrs.flags & FLAG_TURN_SCREEN_ON) != 0; - boolean allowTheaterMode = - mWmService.mAllowTheaterModeWakeFromLayout || Settings.Global.getInt( - mWmService.mContext.getContentResolver(), Settings.Global.THEATER_MODE_ON, 0) - == 0; - boolean canTurnScreenOn = mAppToken == null || mAppToken.canTurnScreenOn(); // The screen will turn on if the following conditions are met // 1. The window has the flag FLAG_TURN_SCREEN_ON @@ -2317,6 +2324,11 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP // be occurring while turning off the screen. This would lead to the screen incorrectly // turning back on. if (hasTurnScreenOnFlag) { + boolean allowTheaterMode = mWmService.mAllowTheaterModeWakeFromLayout + || Settings.Global.getInt(mWmService.mContext.getContentResolver(), + Settings.Global.THEATER_MODE_ON, 0) == 0; + boolean canTurnScreenOn = mAppToken == null || mAppToken.canTurnScreenOn(); + if (allowTheaterMode && canTurnScreenOn && !mPowerManagerWrapper.isInteractive()) { if (DEBUG_VISIBILITY || DEBUG_POWER) { Slog.v(TAG, "Relayout window turning screen on: " + this); @@ -2365,6 +2377,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP void setLastReportedMergedConfiguration(MergedConfiguration config) { mLastReportedConfiguration.setTo(config); + mLastConfigReportedToClient = true; } void getLastReportedMergedConfiguration(MergedConfiguration config) { @@ -2512,6 +2525,10 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP } boolean showLw(boolean doAnimation, boolean requestAnim) { + if (mPolicyVisibility && mPolicyVisibilityAfterAnim) { + // Already showing. + return false; + } if (isHiddenFromUserLocked()) { return false; } @@ -2532,10 +2549,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP // This is an alert window that is currently force hidden. return false; } - if (mPolicyVisibility && mPolicyVisibilityAfterAnim) { - // Already showing. - return false; - } if (DEBUG_VISIBILITY) Slog.v(TAG, "Policy visibility true: " + this); if (doAnimation) { if (DEBUG_VISIBILITY) Slog.v(TAG, "doAnimation: mPolicyVisibility=" @@ -3529,7 +3542,10 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP } void transformClipRectFromScreenToSurfaceSpace(Rect clipRect) { - if (mHScale >= 0) { + if (mHScale == 1 && mVScale == 1) { + return; + } + if (mHScale >= 0) { clipRect.left = (int) (clipRect.left / mHScale); clipRect.right = (int) Math.ceil(clipRect.right / mHScale); } @@ -4385,7 +4401,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP // scale function because we want to round things to make the crop // always round to a larger rect to ensure we don't crop too // much and hide part of the window that should be seen. - if (inSizeCompatMode() && mInvGlobalScale != 1.0f) { + if (mInvGlobalScale != 1.0f && inSizeCompatMode()) { final float scale = mInvGlobalScale; systemDecorRect.left = (int) (systemDecorRect.left * scale - 0.5f); systemDecorRect.top = (int) (systemDecorRect.top * scale - 0.5f); @@ -4440,7 +4456,12 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP mWinAnimator.mEnteringAnimation = true; - prepareWindowToDisplayDuringRelayout(wasVisible); + Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "prepareToDisplay"); + try { + prepareWindowToDisplayDuringRelayout(wasVisible); + } finally { + Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); + } if ((attrChanges & FORMAT_CHANGED) != 0) { // If the format can't be changed in place, preserve the old surface until the app draws diff --git a/services/core/java/com/android/server/wm/WindowSurfaceController.java b/services/core/java/com/android/server/wm/WindowSurfaceController.java index acb98237b5d1..bef0f81e4dc1 100644 --- a/services/core/java/com/android/server/wm/WindowSurfaceController.java +++ b/services/core/java/com/android/server/wm/WindowSurfaceController.java @@ -56,6 +56,7 @@ class WindowSurfaceController { private float mSurfaceY = 0; private int mSurfaceW = 0; private int mSurfaceH = 0; + private Rect mSurfaceCrop = new Rect(0, 0, -1, -1); // Initialize to the identity matrix. private float mLastDsdx = 1; @@ -171,26 +172,15 @@ class WindowSurfaceController { } } - void disconnectInTransaction() { - if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) { - Slog.i(TAG, "Disconnecting client: " + this); - } - - try { - if (mSurfaceControl != null) { - mSurfaceControl.disconnect(); - } - } catch (RuntimeException e) { - Slog.w(TAG, "Error disconnecting surface in: " + this, e); - } - } - void setCropInTransaction(Rect clipRect, boolean recoveringMemory) { if (SHOW_TRANSACTIONS) logSurface( "CROP " + clipRect.toShortString(), null); try { if (clipRect.width() > 0 && clipRect.height() > 0) { - mSurfaceControl.setWindowCrop(clipRect); + if (!clipRect.equals(mSurfaceCrop)) { + mSurfaceControl.setWindowCrop(clipRect); + mSurfaceCrop.set(clipRect); + } mHiddenForCrop = false; updateVisibility(); } else { @@ -212,7 +202,11 @@ class WindowSurfaceController { "CLEAR CROP", null); try { Rect clipRect = new Rect(0, 0, -1, -1); + if (mSurfaceCrop.equals(clipRect)) { + return; + } mSurfaceControl.setWindowCrop(clipRect); + mSurfaceCrop.set(clipRect); } catch (RuntimeException e) { Slog.w(TAG, "Error setting clearing crop of " + this, e); if (!recoveringMemory) { @@ -221,12 +215,6 @@ class WindowSurfaceController { } } - void setLayerStackInTransaction(int layerStack) { - if (mSurfaceControl != null) { - mSurfaceControl.setLayerStack(layerStack); - } - } - void setPositionInTransaction(float left, float top, boolean recoveringMemory) { setPosition(null, left, top, recoveringMemory); } diff --git a/services/core/java/com/android/server/wm/utils/WmDisplayCutout.java b/services/core/java/com/android/server/wm/utils/WmDisplayCutout.java index 98bad93e09e2..3be5d3176df5 100644 --- a/services/core/java/com/android/server/wm/utils/WmDisplayCutout.java +++ b/services/core/java/com/android/server/wm/utils/WmDisplayCutout.java @@ -81,11 +81,24 @@ public class WmDisplayCutout { * @hide */ public WmDisplayCutout calculateRelativeTo(Rect frame) { + if (mFrameSize == null) { + return this; + } + final int insetRight = mFrameSize.getWidth() - frame.right; + final int insetBottom = mFrameSize.getHeight() - frame.bottom; + if (frame.left == 0 && frame.top == 0 && insetRight == 0 && insetBottom == 0) { + return this; + } + if (frame.left >= mInner.getSafeInsetLeft() + && frame.top >= mInner.getSafeInsetTop() + && insetRight >= mInner.getSafeInsetRight() + && insetBottom >= mInner.getSafeInsetBottom()) { + return NO_CUTOUT; + } if (mInner.isEmpty()) { return this; } - return inset(frame.left, frame.top, - mFrameSize.getWidth() - frame.right, mFrameSize.getHeight() - frame.bottom); + return inset(frame.left, frame.top, insetRight, insetBottom); } /** diff --git a/services/robotests/backup/Android.mk b/services/robotests/backup/Android.mk index cc59b0c9bb16..bd4ebbd393fa 100644 --- a/services/robotests/backup/Android.mk +++ b/services/robotests/backup/Android.mk @@ -26,7 +26,7 @@ LOCAL_MODULE_TAGS := optional LOCAL_PRIVILEGED_MODULE := true LOCAL_STATIC_JAVA_LIBRARIES := \ - bmgrlib \ + bmgr \ bu \ services.backup \ services.core \ diff --git a/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java b/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java index 04abeca1192e..f39c71682c61 100644 --- a/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java +++ b/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java @@ -34,7 +34,9 @@ import static com.google.android.collect.Sets.newHashSet; import static com.google.common.truth.Truth.assertWithMessage; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyBoolean; @@ -64,6 +66,7 @@ import android.os.IRemoteCallback; import android.os.Looper; import android.os.Message; import android.os.RemoteException; +import android.os.UserHandle; import android.os.UserManagerInternal; import android.platform.test.annotations.Presubmit; import android.util.Log; @@ -321,6 +324,14 @@ public class UserControllerTest { verify(mInjector.getWindowManager(), times(1)).setSwitchingUser(false); } + @Test + public void testExplicitSystenUserStartInBackground() { + setUpUser(UserHandle.USER_SYSTEM, 0); + assertFalse(mUserController.isSystemUserStarted()); + assertTrue(mUserController.startUser(UserHandle.USER_SYSTEM, false, null)); + assertTrue(mUserController.isSystemUserStarted()); + } + private void setUpUser(int userId, int flags) { UserInfo userInfo = new UserInfo(userId, "User" + userId, flags); when(mInjector.mUserManagerMock.getUserInfo(eq(userId))).thenReturn(userInfo); @@ -417,6 +428,12 @@ public class UserControllerTest { @Override void reportCurWakefulnessUsageEvent() { } + + @Override + boolean isRuntimeRestarted() { + // to pass all metrics related calls + return true; + } } private static class TestHandler extends Handler { diff --git a/services/tests/servicestests/src/com/android/server/backup/testutils/IPackageManagerStub.java b/services/tests/servicestests/src/com/android/server/backup/testutils/IPackageManagerStub.java index 4b3d9cf59487..0792414fef95 100644 --- a/services/tests/servicestests/src/com/android/server/backup/testutils/IPackageManagerStub.java +++ b/services/tests/servicestests/src/com/android/server/backup/testutils/IPackageManagerStub.java @@ -1148,6 +1148,11 @@ public class IPackageManagerStub implements IPackageManager { return null; } + @Override + public String getAttentionServicePackageName() throws RemoteException { + return null; + } + public String getIncidentReportApproverPackageName() throws RemoteException { return null; } diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTestsBase.java index 2ab48a926817..5cef38ded575 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTestsBase.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTestsBase.java @@ -38,6 +38,7 @@ import android.content.pm.PackageManager; import android.content.res.Resources; import android.graphics.Matrix; import android.graphics.RectF; +import android.os.Binder; import android.os.IBinder; import android.testing.TestableResources; import android.util.Pair; @@ -98,7 +99,8 @@ public class DisplayPolicyTestsBase extends WindowTestsBase { } void addWindow(WindowState win) { - mDisplayPolicy.adjustWindowParamsLw(win, win.mAttrs, true /* hasStatusBarPermission */); + mDisplayPolicy.adjustWindowParamsLw(win, win.mAttrs, Binder.getCallingPid(), + Binder.getCallingUid()); assertEquals(WindowManagerGlobal.ADD_OKAY, mDisplayPolicy.prepareAddWindowLw(win, win.mAttrs)); win.mHasSurface = true; diff --git a/telephony/java/android/telephony/AvailableNetworkInfo.java b/telephony/java/android/telephony/AvailableNetworkInfo.java index a15f959a96bd..a1c5bbefbbe1 100644 --- a/telephony/java/android/telephony/AvailableNetworkInfo.java +++ b/telephony/java/android/telephony/AvailableNetworkInfo.java @@ -27,8 +27,8 @@ import java.util.Objects; /** * Defines available network information which includes corresponding subscription id, - * network plmns and corresponding priority to be used for network selection by Alternative Network - * Service. + * network plmns and corresponding priority to be used for network selection by Opportunistic + * Network Service when passed through {@link TelephonyManager#updateAvailableNetworks} */ public final class AvailableNetworkInfo implements Parcelable { @@ -55,15 +55,19 @@ public final class AvailableNetworkInfo implements Parcelable { /** * Priority for the subscription id. - * Priorities are in the range of 1 to 3 where 1 - * has the highest priority. + * Priorities are in the range of {@link AvailableNetworkInfo#PRIORITY_LOW} to + * {@link AvailableNetworkInfo#PRIORITY_HIGH} + * Among all networks available after network scan, subId with highest priority is chosen + * for network selection. If there are more than one subId with highest priority then the + * network with highest RSRP is chosen. */ private int mPriority; /** * Describes the List of PLMN ids (MCC-MNC) associated with mSubId. - * If this entry is left empty, then the platform software will not scan the network - * to revalidate the input else platform will scan and verify specified PLMNs are available. + * Opportunistic Network Service will scan and verify specified PLMNs are available. + * If this entry is left empty, then the Opportunistic Network Service will not scan the network + * to validate the network availability. */ private ArrayList<String> mMccMncs; @@ -71,8 +75,8 @@ public final class AvailableNetworkInfo implements Parcelable { * Returns the frequency bands associated with the {@link #getMccMncs() MCC/MNCs}. * Opportunistic network service will use these bands to scan. * - * When no specific bands are specified (empty array or null) CBRS band (B48) will be - * used for network scan. + * When no specific bands are specified (empty array or null) CBRS band + * {@link AccessNetworkConstants.EutranBand.BAND_48} will be used for network scan. * * See {@link AccessNetworkConstants} for details. */ @@ -89,8 +93,12 @@ public final class AvailableNetworkInfo implements Parcelable { } /** - * Return priority for the subscription id. Valid value will be within - * [{@link AvailableNetworkInfo#PRIORITY_HIGH}, {@link AvailableNetworkInfo#PRIORITY_LOW}] + * Return priority for the subscription id. + * Priorities are in the range of {@link AvailableNetworkInfo#PRIORITY_LOW} to + * {@link AvailableNetworkInfo#PRIORITY_HIGH} + * Among all networks available after network scan, subId with highest priority is chosen + * for network selection. If there are more than one subId with highest priority then the + * network with highest RSRP is chosen. * @return priority level */ public int getPriority() { @@ -99,8 +107,9 @@ public final class AvailableNetworkInfo implements Parcelable { /** * Return List of PLMN ids (MCC-MNC) associated with the sub ID. - * If this entry is left empty, then the platform software will not scan the network - * to revalidate the input. + * Opportunistic Network Service will scan and verify specified PLMNs are available. + * If this entry is left empty, then the Opportunistic Network Service will not scan the network + * to validate the network availability. * @return list of PLMN ids */ public @NonNull List<String> getMccMncs() { @@ -112,6 +121,9 @@ public final class AvailableNetworkInfo implements Parcelable { * * The returned value is defined in either of {@link AccessNetworkConstants.GeranBand}, * {@link AccessNetworkConstants.UtranBand} and {@link AccessNetworkConstants.EutranBand} + * See {@link AccessNetworkConstants.AccessNetworkType} for details regarding different network + * types. When no specific bands are specified (empty array or null) CBRS band + * {@link AccessNetworkConstants.EutranBand#BAND_48} will be used for network scan. */ public @NonNull List<Integer> getBands() { return (List<Integer>) mBands.clone(); diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java index 6aca6935de22..0b44367e1935 100755 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -3123,14 +3123,14 @@ public class CarrierConfigManager { sDefaults.putString(KEY_5G_ICON_CONFIGURATION_STRING, "connected_mmwave:None,connected:5G,not_restricted:None,restricted:None"); sDefaults.putBoolean(KEY_ASCII_7_BIT_SUPPORT_FOR_LONG_MESSAGE_BOOL, false); + /* Default value is minimum RSRP level needed for SIGNAL_STRENGTH_GOOD */ + sDefaults.putInt(KEY_OPPORTUNISTIC_NETWORK_ENTRY_THRESHOLD_RSRP_INT, -108); /* Default value is minimum RSRP level needed for SIGNAL_STRENGTH_MODERATE */ - sDefaults.putInt(KEY_OPPORTUNISTIC_NETWORK_ENTRY_THRESHOLD_RSRP_INT, -118); - /* Default value is minimum RSRP level needed for SIGNAL_STRENGTH_POOR */ - sDefaults.putInt(KEY_OPPORTUNISTIC_NETWORK_EXIT_THRESHOLD_RSRP_INT, -128); + sDefaults.putInt(KEY_OPPORTUNISTIC_NETWORK_EXIT_THRESHOLD_RSRP_INT, -118); + /* Default value is minimum RSSNR level needed for SIGNAL_STRENGTH_GOOD */ + sDefaults.putInt(KEY_OPPORTUNISTIC_NETWORK_ENTRY_THRESHOLD_RSSNR_INT, 45); /* Default value is minimum RSSNR level needed for SIGNAL_STRENGTH_MODERATE */ - sDefaults.putInt(KEY_OPPORTUNISTIC_NETWORK_ENTRY_THRESHOLD_RSSNR_INT, 10); - /* Default value is minimum RSSNR level needed for SIGNAL_STRENGTH_POOR */ - sDefaults.putInt(KEY_OPPORTUNISTIC_NETWORK_EXIT_THRESHOLD_RSSNR_INT, -30); + sDefaults.putInt(KEY_OPPORTUNISTIC_NETWORK_EXIT_THRESHOLD_RSSNR_INT, 10); /* Default value is 1024 kbps */ sDefaults.putInt(KEY_OPPORTUNISTIC_NETWORK_ENTRY_THRESHOLD_BANDWIDTH_INT, 1024); /* Default value is 10 seconds */ diff --git a/telephony/java/android/telephony/PhoneStateListener.java b/telephony/java/android/telephony/PhoneStateListener.java index 918bf60c9fa7..373c5d27eec8 100644 --- a/telephony/java/android/telephony/PhoneStateListener.java +++ b/telephony/java/android/telephony/PhoneStateListener.java @@ -297,8 +297,11 @@ public class PhoneStateListener { * it could be the current active opportunistic subscription in use, or the * subscription user selected as default data subscription in DSDS mode. * - * Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE - * READ_PHONE_STATE} + * Requires Permission: No permission is required to listen, but notification requires + * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} or the calling + * app has carrier privileges (see {@link TelephonyManager#hasCarrierPrivileges}) + * on any active subscription. + * * @see #onActiveDataSubscriptionIdChanged */ public static final int LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE = 0x00400000; diff --git a/telephony/java/android/telephony/SmsManager.java b/telephony/java/android/telephony/SmsManager.java index 09046a679c37..63d427a6f3c4 100644 --- a/telephony/java/android/telephony/SmsManager.java +++ b/telephony/java/android/telephony/SmsManager.java @@ -951,8 +951,7 @@ public final class SmsManager { * @return associated subscription id */ public int getSubscriptionId() { - final int subId = (mSubId == DEFAULT_SUBSCRIPTION_ID) - ? getDefaultSmsSubscriptionId() : mSubId; + final int subId = getSubIdOrDefault(); boolean isSmsSimPickActivityNeeded = false; final Context context = ActivityThread.currentApplication().getApplicationContext(); try { @@ -985,6 +984,17 @@ public final class SmsManager { } /** + * @return the subscription ID associated with this {@link SmsManager} or the default set by the + * user if this instance was created using {@link SmsManager#getDefault}. + * + * If there is no default set by the user, this method returns + * {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID}. + */ + private int getSubIdOrDefault() { + return (mSubId == DEFAULT_SUBSCRIPTION_ID) ? getDefaultSmsSubscriptionId() : mSubId; + } + + /** * Returns the ISms service, or throws an UnsupportedOperationException if * the service does not exist. */ @@ -1151,8 +1161,9 @@ public final class SmsManager { try { ISms iSms = getISmsService(); if (iSms != null) { - success = iSms.enableCellBroadcastForSubscriber( - getSubscriptionId(), messageIdentifier, ranType); + // If getSubIdOrDefault() returns INVALID, we will use the default phone internally. + success = iSms.enableCellBroadcastForSubscriber(getSubIdOrDefault(), + messageIdentifier, ranType); } } catch (RemoteException ex) { // ignore it @@ -1187,8 +1198,9 @@ public final class SmsManager { try { ISms iSms = getISmsService(); if (iSms != null) { - success = iSms.disableCellBroadcastForSubscriber( - getSubscriptionId(), messageIdentifier, ranType); + // If getSubIdOrDefault() returns INVALID, we will use the default phone internally. + success = iSms.disableCellBroadcastForSubscriber(getSubIdOrDefault(), + messageIdentifier, ranType); } } catch (RemoteException ex) { // ignore it @@ -1230,7 +1242,8 @@ public final class SmsManager { try { ISms iSms = getISmsService(); if (iSms != null) { - success = iSms.enableCellBroadcastRangeForSubscriber(getSubscriptionId(), + // If getSubIdOrDefault() returns INVALID, we will use the default phone internally. + success = iSms.enableCellBroadcastRangeForSubscriber(getSubIdOrDefault(), startMessageId, endMessageId, ranType); } } catch (RemoteException ex) { @@ -1273,7 +1286,8 @@ public final class SmsManager { try { ISms iSms = getISmsService(); if (iSms != null) { - success = iSms.disableCellBroadcastRangeForSubscriber(getSubscriptionId(), + // If getSubIdOrDefault() returns INVALID, we will use the default phone internally. + success = iSms.disableCellBroadcastRangeForSubscriber(getSubIdOrDefault(), startMessageId, endMessageId, ranType); } } catch (RemoteException ex) { diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index e4debd6fcdca..6dd1691bbafc 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -10547,6 +10547,9 @@ public class TelephonyManager { /** * Set preferred opportunistic data subscription id. * + * Switch internet data to preferred opportunistic data subscription id. This api + * can result in lose of internet connectivity for short period of time while internet data + * is handed over. * <p>Requires that the calling app has carrier privileges on both primary and * secondary subscriptions (see * {@link #hasCarrierPrivileges}), or has permission @@ -10625,9 +10628,11 @@ public class TelephonyManager { * * This api should be called to inform OpportunisticNetwork Service about the availability * of a network at the current location. This information will be used by OpportunisticNetwork - * service to decide to attach to the network opportunistically. If an empty list is passed, + * service to enable modem stack and to attach to the network. If an empty list is passed, * it is assumed that no network is available and will result in disabling the modem stack - * to save power. + * to save power. This api do not switch internet data once network attach is completed. + * Use {@link TelephonyManager#setPreferredOpportunisticDataSubscription} + * to switch internet data after network attach is complete. * Requires that the calling app has carrier privileges on both primary and * secondary subscriptions (see {@link #hasCarrierPrivileges}), or has permission * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}. diff --git a/telephony/java/android/telephony/ims/ProvisioningManager.java b/telephony/java/android/telephony/ims/ProvisioningManager.java index 8cdf6a235749..cc037e3ea814 100644 --- a/telephony/java/android/telephony/ims/ProvisioningManager.java +++ b/telephony/java/android/telephony/ims/ProvisioningManager.java @@ -21,6 +21,7 @@ import android.annotation.CallbackExecutor; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresPermission; +import android.annotation.StringDef; import android.annotation.SystemApi; import android.annotation.WorkerThread; import android.content.Context; @@ -38,25 +39,36 @@ import android.telephony.ims.stub.ImsRegistrationImplBase; import com.android.internal.telephony.ITelephony; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.util.concurrent.Executor; /** * Manages IMS provisioning and configuration parameters, as well as callbacks for apps to listen * to changes in these configurations. * - * Note: IMS provisioning keys are defined per carrier or OEM using OMA-DM or other provisioning - * applications and may vary. For compatibility purposes, the first 100 integer values used in - * {@link #setProvisioningIntValue(int, int)} have been reserved for existing provisioning keys - * previously defined in the Android framework. Some common constants have been defined in this - * class to make integrating with other system apps easier. USE WITH CARE! + * IMS provisioning keys are defined per carrier or OEM using OMA-DM or other provisioning + * applications and may vary. It is up to the carrier and OEM applications to ensure that the + * correct provisioning keys are being used when integrating with a vendor's ImsService. * - * To avoid collisions, please use String based configurations when possible: - * {@link #setProvisioningStringValue(int, String)} and {@link #getProvisioningStringValue(int)}. + * Note: For compatibility purposes, the integer values [0 - 99] used in + * {@link #setProvisioningIntValue(int, int)} have been reserved for existing provisioning keys + * previously defined in the Android framework. Please do not redefine new provisioning keys in this + * range or it may generate collisions with existing keys. Some common constants have also been + * defined in this class to make integrating with other system apps easier. * @hide */ @SystemApi public class ProvisioningManager { + /**@hide*/ + @StringDef(prefix = "STRING_QUERY_RESULT_ERROR_", value = { + STRING_QUERY_RESULT_ERROR_GENERIC, + STRING_QUERY_RESULT_ERROR_NOT_READY + }) + @Retention(RetentionPolicy.SOURCE) + public @interface StringResultError {} + /** * The query from {@link #getProvisioningStringValue(int)} has resulted in an unspecified error. */ @@ -268,14 +280,13 @@ public class ProvisioningManager { * This operation is blocking and should not be performed on the UI thread. * * @param key A String that represents the provisioning key, which is defined by the OEM. - * @return a String value for the provided key, {@code null} if the key doesn't exist, or one - * of the following error codes: {@link #STRING_QUERY_RESULT_ERROR_GENERIC}, - * {@link #STRING_QUERY_RESULT_ERROR_NOT_READY}. + * @return a String value for the provided key, {@code null} if the key doesn't exist, or + * {@link StringResultError} if there was an error getting the value for the provided key. * @throws IllegalArgumentException if the key provided was invalid. */ @WorkerThread @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) - public @Nullable String getProvisioningStringValue(int key) { + public @Nullable @StringResultError String getProvisioningStringValue(int key) { try { return getITelephony().getImsProvisioningString(mSubId, key); } catch (RemoteException e) { diff --git a/telephony/java/com/android/internal/telephony/TelephonyPermissions.java b/telephony/java/com/android/internal/telephony/TelephonyPermissions.java index d93e58254b95..f5985b4ed1a7 100644 --- a/telephony/java/com/android/internal/telephony/TelephonyPermissions.java +++ b/telephony/java/com/android/internal/telephony/TelephonyPermissions.java @@ -164,6 +164,63 @@ public final class TelephonyPermissions { // We have READ_PHONE_STATE permission, so return true as long as the AppOps bit hasn't been // revoked. AppOpsManager appOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE); + return appOps.noteOp(AppOpsManager.OP_READ_PHONE_STATE, uid, callingPackage) + == AppOpsManager.MODE_ALLOWED; + } + + /** + * Check whether the app with the given pid/uid can read phone state, or has carrier + * privileges on any active subscription. + * + * <p>If the app does not have carrier privilege, this method will return {@code false} instead + * of throwing a SecurityException. Therefore, the callers cannot tell the difference + * between M+ apps which declare the runtime permission but do not have it, and pre-M apps + * which declare the static permission but had access revoked via AppOps. Apps in the former + * category expect SecurityExceptions; apps in the latter don't. So this method is suitable for + * use only if the behavior in both scenarios is meant to be identical. + * + * @return {@code true} if the app can read phone state or has carrier privilege; + * {@code false} otherwise. + */ + public static boolean checkReadPhoneStateOnAnyActiveSub( + Context context, int pid, int uid, String callingPackage, String message) { + return checkReadPhoneStateOnAnyActiveSub(context, TELEPHONY_SUPPLIER, pid, uid, + callingPackage, message); + } + + @VisibleForTesting + public static boolean checkReadPhoneStateOnAnyActiveSub( + Context context, Supplier<ITelephony> telephonySupplier, int pid, int uid, + String callingPackage, String message) { + try { + context.enforcePermission( + android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, pid, uid, message); + + // SKIP checking for run-time permission since caller has PRIVILEGED permission + return true; + } catch (SecurityException privilegedPhoneStateException) { + try { + context.enforcePermission( + android.Manifest.permission.READ_PHONE_STATE, pid, uid, message); + } catch (SecurityException phoneStateException) { + SubscriptionManager sm = (SubscriptionManager) context.getSystemService( + Context.TELEPHONY_SUBSCRIPTION_SERVICE); + int[] activeSubIds = sm.getActiveSubscriptionIdList(); + for (int activeSubId : activeSubIds) { + // If we don't have the runtime permission, but do have carrier privileges, that + // suffices for reading phone state. + if (getCarrierPrivilegeStatus(telephonySupplier, activeSubId, uid) + == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) { + return true; + } + } + return false; + } + } + + // We have READ_PHONE_STATE permission, so return true as long as the AppOps bit hasn't been + // revoked. + AppOpsManager appOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE); return appOps.noteOp(AppOpsManager.OP_READ_PHONE_STATE, uid, callingPackage) == AppOpsManager.MODE_ALLOWED; } diff --git a/tools/aapt2/dump/DumpManifest.cpp b/tools/aapt2/dump/DumpManifest.cpp index e17fb4783a45..92f1ddb292e1 100644 --- a/tools/aapt2/dump/DumpManifest.cpp +++ b/tools/aapt2/dump/DumpManifest.cpp @@ -2314,7 +2314,7 @@ std::unique_ptr<ManifestExtractor::Element> ManifestExtractor::Visit(xml::Elemen int DumpManifest(LoadedApk* apk, DumpManifestOptions& options, text::Printer* printer, IDiagnostics* diag) { ManifestExtractor extractor(apk, options); - return extractor.Dump(printer, diag); + return extractor.Dump(printer, diag) ? 0 : 1; } } // namespace aapt diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java index 78967e4a4a9f..be227e79909e 100644 --- a/wifi/java/android/net/wifi/WifiConfiguration.java +++ b/wifi/java/android/net/wifi/WifiConfiguration.java @@ -2190,22 +2190,7 @@ public class WifiConfiguration implements Parcelable { key += "-" + Integer.toString(UserHandle.getUserId(creatorUid)); } } else { - if (allowedKeyManagement.get(KeyMgmt.WPA_PSK)) { - key = SSID + KeyMgmt.strings[KeyMgmt.WPA_PSK]; - } else if (allowedKeyManagement.get(KeyMgmt.WPA_EAP) || - allowedKeyManagement.get(KeyMgmt.IEEE8021X)) { - key = SSID + KeyMgmt.strings[KeyMgmt.WPA_EAP]; - } else if (wepKeys[0] != null) { - key = SSID + "WEP"; - } else if (allowedKeyManagement.get(KeyMgmt.OWE)) { - key = SSID + KeyMgmt.strings[KeyMgmt.OWE]; - } else if (allowedKeyManagement.get(KeyMgmt.SAE)) { - key = SSID + KeyMgmt.strings[KeyMgmt.SAE]; - } else if (allowedKeyManagement.get(KeyMgmt.SUITE_B_192)) { - key = SSID + KeyMgmt.strings[KeyMgmt.SUITE_B_192]; - } else { - key = SSID + KeyMgmt.strings[KeyMgmt.NONE]; - } + key = getSsidAndSecurityTypeString(); if (!shared) { key += "-" + Integer.toString(UserHandle.getUserId(creatorUid)); } @@ -2215,6 +2200,30 @@ public class WifiConfiguration implements Parcelable { } /** @hide + * return the SSID + security type in String format. + */ + public String getSsidAndSecurityTypeString() { + String key; + if (allowedKeyManagement.get(KeyMgmt.WPA_PSK)) { + key = SSID + KeyMgmt.strings[KeyMgmt.WPA_PSK]; + } else if (allowedKeyManagement.get(KeyMgmt.WPA_EAP) + || allowedKeyManagement.get(KeyMgmt.IEEE8021X)) { + key = SSID + KeyMgmt.strings[KeyMgmt.WPA_EAP]; + } else if (wepKeys[0] != null) { + key = SSID + "WEP"; + } else if (allowedKeyManagement.get(KeyMgmt.OWE)) { + key = SSID + KeyMgmt.strings[KeyMgmt.OWE]; + } else if (allowedKeyManagement.get(KeyMgmt.SAE)) { + key = SSID + KeyMgmt.strings[KeyMgmt.SAE]; + } else if (allowedKeyManagement.get(KeyMgmt.SUITE_B_192)) { + key = SSID + KeyMgmt.strings[KeyMgmt.SUITE_B_192]; + } else { + key = SSID + KeyMgmt.strings[KeyMgmt.NONE]; + } + return key; + } + + /** @hide * get configKey, force calculating the config string */ public String configKey() { diff --git a/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java b/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java index d927052e0b2a..ba9fc786afe7 100644 --- a/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java +++ b/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java @@ -348,4 +348,47 @@ public class WifiConfigurationTest { } assertTrue(exceptionThrown); } + + /** + * Verifies that getSsidAndSecurityTypeString returns the correct String for networks of + * various different security types + */ + @Test + public void testGetSsidAndSecurityTypeString() { + WifiConfiguration config = new WifiConfiguration(); + final String mSsid = "TestAP"; + config.SSID = mSsid; + + // Test various combinations + config.allowedKeyManagement.set(KeyMgmt.WPA_PSK); + assertEquals(mSsid + KeyMgmt.strings[KeyMgmt.WPA_PSK], + config.getSsidAndSecurityTypeString()); + + config.allowedKeyManagement.clear(); + config.allowedKeyManagement.set(KeyMgmt.WPA_EAP); + assertEquals(mSsid + KeyMgmt.strings[KeyMgmt.WPA_EAP], + config.getSsidAndSecurityTypeString()); + + config.wepKeys[0] = "TestWep"; + config.allowedKeyManagement.clear(); + assertEquals(mSsid + "WEP", config.getSsidAndSecurityTypeString()); + + config.wepKeys[0] = null; + config.allowedKeyManagement.clear(); + config.allowedKeyManagement.set(KeyMgmt.OWE); + assertEquals(mSsid + KeyMgmt.strings[KeyMgmt.OWE], config.getSsidAndSecurityTypeString()); + + config.allowedKeyManagement.clear(); + config.allowedKeyManagement.set(KeyMgmt.SAE); + assertEquals(mSsid + KeyMgmt.strings[KeyMgmt.SAE], config.getSsidAndSecurityTypeString()); + + config.allowedKeyManagement.clear(); + config.allowedKeyManagement.set(KeyMgmt.SUITE_B_192); + assertEquals(mSsid + KeyMgmt.strings[KeyMgmt.SUITE_B_192], + config.getSsidAndSecurityTypeString()); + + config.allowedKeyManagement.clear(); + config.allowedKeyManagement.set(KeyMgmt.NONE); + assertEquals(mSsid + KeyMgmt.strings[KeyMgmt.NONE], config.getSsidAndSecurityTypeString()); + } } diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java index 600abc927b7f..fa17db1e956c 100644 --- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java +++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java @@ -1382,4 +1382,60 @@ i * Verify that a call to cancel WPS immediately returns a failure. r.run(); } } + + /** + * Test behavior of isEnhancedOpenSupported + * @throws Exception + */ + @Test + public void testIsEnhancedOpenSupported() throws Exception { + when(mWifiService.getSupportedFeatures()) + .thenReturn(new Long(WifiManager.WIFI_FEATURE_OWE)); + assertTrue(mWifiManager.isEnhancedOpenSupported()); + when(mWifiService.getSupportedFeatures()) + .thenReturn(new Long(~WifiManager.WIFI_FEATURE_OWE)); + assertFalse(mWifiManager.isEnhancedOpenSupported()); + } + + /** + * Test behavior of isWpa3SaeSupported + * @throws Exception + */ + @Test + public void testIsWpa3SaeSupported() throws Exception { + when(mWifiService.getSupportedFeatures()) + .thenReturn(new Long(WifiManager.WIFI_FEATURE_WPA3_SAE)); + assertTrue(mWifiManager.isWpa3SaeSupported()); + when(mWifiService.getSupportedFeatures()) + .thenReturn(new Long(~WifiManager.WIFI_FEATURE_WPA3_SAE)); + assertFalse(mWifiManager.isWpa3SaeSupported()); + } + + /** + * Test behavior of isWpa3SuiteBSupported + * @throws Exception + */ + @Test + public void testIsWpa3SuiteBSupported() throws Exception { + when(mWifiService.getSupportedFeatures()) + .thenReturn(new Long(WifiManager.WIFI_FEATURE_WPA3_SUITE_B)); + assertTrue(mWifiManager.isWpa3SuiteBSupported()); + when(mWifiService.getSupportedFeatures()) + .thenReturn(new Long(~WifiManager.WIFI_FEATURE_WPA3_SUITE_B)); + assertFalse(mWifiManager.isWpa3SuiteBSupported()); + } + + /** + * Test behavior of isEasyConnectSupported + * @throws Exception + */ + @Test + public void testIsEasyConnectSupported() throws Exception { + when(mWifiService.getSupportedFeatures()) + .thenReturn(new Long(WifiManager.WIFI_FEATURE_DPP)); + assertTrue(mWifiManager.isEasyConnectSupported()); + when(mWifiService.getSupportedFeatures()) + .thenReturn(new Long(~WifiManager.WIFI_FEATURE_DPP)); + assertFalse(mWifiManager.isEasyConnectSupported()); + } } |