diff options
981 files changed, 23487 insertions, 13734 deletions
diff --git a/apct-tests/perftests/core/src/android/os/KernelCpuThreadReaderPerfTest.java b/apct-tests/perftests/core/src/android/os/KernelCpuThreadReaderPerfTest.java index 1f261882b2d3..da9ed6e49043 100644 --- a/apct-tests/perftests/core/src/android/os/KernelCpuThreadReaderPerfTest.java +++ b/apct-tests/perftests/core/src/android/os/KernelCpuThreadReaderPerfTest.java @@ -40,7 +40,7 @@ public class KernelCpuThreadReaderPerfTest { public final PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter(); private final KernelCpuThreadReader mKernelCpuThreadReader = - KernelCpuThreadReader.create(8, uid -> 1000 <= uid && uid < 2000, 0); + KernelCpuThreadReader.create(8, uid -> 1000 <= uid && uid < 2000); @Test public void timeReadCurrentProcessCpuUsage() { diff --git a/apct-tests/perftests/textclassifier/Android.bp b/apct-tests/perftests/textclassifier/Android.bp new file mode 100644 index 000000000000..49952dc1d009 --- /dev/null +++ b/apct-tests/perftests/textclassifier/Android.bp @@ -0,0 +1,25 @@ +// 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. + +android_test { + name: "TextClassifierPerfTests", + srcs: ["src/**/*.java"], + static_libs: [ + "androidx.test.rules", + "androidx.annotation_annotation", + "apct-perftests-utils", + ], + platform_apis: true, + test_suites: ["device-tests"], +} diff --git a/apct-tests/perftests/textclassifier/AndroidManifest.xml b/apct-tests/perftests/textclassifier/AndroidManifest.xml new file mode 100644 index 000000000000..7cf487f2eb7e --- /dev/null +++ b/apct-tests/perftests/textclassifier/AndroidManifest.xml @@ -0,0 +1,25 @@ +<?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. +--> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.perftests.textclassifier"> + + <application> + <uses-library android:name="android.test.runner" /> + </application> + + <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner" + android:targetPackage="com.android.perftests.textclassifier"/> +</manifest> diff --git a/apct-tests/perftests/textclassifier/AndroidTest.xml b/apct-tests/perftests/textclassifier/AndroidTest.xml new file mode 100644 index 000000000000..3df51b8ae67a --- /dev/null +++ b/apct-tests/perftests/textclassifier/AndroidTest.xml @@ -0,0 +1,28 @@ +<?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. +--> +<configuration description="Runs TextClassifierPerfTests metric instrumentation."> + <option name="test-suite-tag" value="apct" /> + <option name="test-suite-tag" value="apct-metric-instrumentation" /> + <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller"> + <option name="cleanup-apks" value="true" /> + <option name="test-file-name" value="TextClassifierPerfTests.apk" /> + </target_preparer> + + <test class="com.android.tradefed.testtype.AndroidJUnitTest" > + <option name="package" value="com.android.perftests.textclassifier" /> + <option name="hidden-api-checks" value="false"/> + </test> +</configuration> diff --git a/apct-tests/perftests/textclassifier/run.sh b/apct-tests/perftests/textclassifier/run.sh new file mode 100755 index 000000000000..c6782d1a72f2 --- /dev/null +++ b/apct-tests/perftests/textclassifier/run.sh @@ -0,0 +1,4 @@ +set -e +make TextClassifierPerfTests +adb shell cmd package compile -m speed -f com.android.perftests.textclassifier +adb shell am instrument -w -e class android.view.textclassifier.TextClassifierPerfTest com.android.perftests.textclassifier/androidx.test.runner.AndroidJUnitRunner diff --git a/apct-tests/perftests/core/src/android/textclassifier/TextClassifierPerfTest.java b/apct-tests/perftests/textclassifier/src/android/view/textclassifier/TextClassifierPerfTest.java index c5d89b234209..14a121d60c2e 100644 --- a/apct-tests/perftests/core/src/android/textclassifier/TextClassifierPerfTest.java +++ b/apct-tests/perftests/textclassifier/src/android/view/textclassifier/TextClassifierPerfTest.java @@ -13,15 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package android.textclassifier; +package android.view.textclassifier; import android.content.Context; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.view.textclassifier.ConversationActions; -import android.view.textclassifier.TextClassificationManager; -import android.view.textclassifier.TextClassifier; -import android.view.textclassifier.TextLanguage; import androidx.test.InstrumentationRegistry; import androidx.test.filters.LargeTest; diff --git a/api/current.txt b/api/current.txt index 1e6bf2c91711..1394ba33dddd 100644 --- a/api/current.txt +++ b/api/current.txt @@ -102,16 +102,13 @@ package android { field public static final String NFC_TRANSACTION_EVENT = "android.permission.NFC_TRANSACTION_EVENT"; field public static final String PACKAGE_USAGE_STATS = "android.permission.PACKAGE_USAGE_STATS"; field @Deprecated public static final String PERSISTENT_ACTIVITY = "android.permission.PERSISTENT_ACTIVITY"; - field public static final String PROCESS_OUTGOING_CALLS = "android.permission.PROCESS_OUTGOING_CALLS"; + field @Deprecated public static final String PROCESS_OUTGOING_CALLS = "android.permission.PROCESS_OUTGOING_CALLS"; field public static final String READ_CALENDAR = "android.permission.READ_CALENDAR"; field public static final String READ_CALL_LOG = "android.permission.READ_CALL_LOG"; field public static final String READ_CONTACTS = "android.permission.READ_CONTACTS"; - field @Deprecated public static final String READ_EXTERNAL_STORAGE = "android.permission.READ_EXTERNAL_STORAGE"; + field public static final String READ_EXTERNAL_STORAGE = "android.permission.READ_EXTERNAL_STORAGE"; field @Deprecated public static final String READ_INPUT_STATE = "android.permission.READ_INPUT_STATE"; field public static final String READ_LOGS = "android.permission.READ_LOGS"; - field public static final String READ_MEDIA_AUDIO = "android.permission.READ_MEDIA_AUDIO"; - field public static final String READ_MEDIA_IMAGES = "android.permission.READ_MEDIA_IMAGES"; - field public static final String READ_MEDIA_VIDEO = "android.permission.READ_MEDIA_VIDEO"; field public static final String READ_PHONE_NUMBERS = "android.permission.READ_PHONE_NUMBERS"; field public static final String READ_PHONE_STATE = "android.permission.READ_PHONE_STATE"; field public static final String READ_SMS = "android.permission.READ_SMS"; @@ -161,7 +158,7 @@ package android { field public static final String WRITE_CALENDAR = "android.permission.WRITE_CALENDAR"; field public static final String WRITE_CALL_LOG = "android.permission.WRITE_CALL_LOG"; field public static final String WRITE_CONTACTS = "android.permission.WRITE_CONTACTS"; - field @Deprecated public static final String WRITE_EXTERNAL_STORAGE = "android.permission.WRITE_EXTERNAL_STORAGE"; + field public static final String WRITE_EXTERNAL_STORAGE = "android.permission.WRITE_EXTERNAL_STORAGE"; field public static final String WRITE_GSERVICES = "android.permission.WRITE_GSERVICES"; field public static final String WRITE_SECURE_SETTINGS = "android.permission.WRITE_SECURE_SETTINGS"; field public static final String WRITE_SETTINGS = "android.permission.WRITE_SETTINGS"; @@ -177,13 +174,11 @@ package android { field public static final String CAMERA = "android.permission-group.CAMERA"; field public static final String CONTACTS = "android.permission-group.CONTACTS"; field public static final String LOCATION = "android.permission-group.LOCATION"; - field public static final String MEDIA_AURAL = "android.permission-group.MEDIA_AURAL"; - field public static final String MEDIA_VISUAL = "android.permission-group.MEDIA_VISUAL"; field public static final String MICROPHONE = "android.permission-group.MICROPHONE"; field public static final String PHONE = "android.permission-group.PHONE"; field public static final String SENSORS = "android.permission-group.SENSORS"; field public static final String SMS = "android.permission-group.SMS"; - field @Deprecated public static final String STORAGE = "android.permission-group.STORAGE"; + field public static final String STORAGE = "android.permission-group.STORAGE"; } public final class R { @@ -291,6 +286,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 @@ -6273,7 +6269,7 @@ package android.app { public final class UiAutomation { method public void adoptShellPermissionIdentity(); - method public void adoptShellPermissionIdentity(java.lang.String...); + method public void adoptShellPermissionIdentity(@Nullable java.lang.String...); method public void clearWindowAnimationFrameStats(); method public boolean clearWindowContentFrameStats(int); method public void dropShellPermissionIdentity(); @@ -8604,7 +8600,6 @@ package android.bluetooth { } @Deprecated public final class BluetoothHealth implements android.bluetooth.BluetoothProfile { - ctor @Deprecated public BluetoothHealth(); method @Deprecated public boolean connectChannelToSource(android.bluetooth.BluetoothDevice, android.bluetooth.BluetoothHealthAppConfiguration); method @Deprecated public boolean disconnectChannel(android.bluetooth.BluetoothDevice, android.bluetooth.BluetoothHealthAppConfiguration, int); method @Deprecated public java.util.List<android.bluetooth.BluetoothDevice> getConnectedDevices(); @@ -8628,7 +8623,6 @@ package android.bluetooth { } @Deprecated public final class BluetoothHealthAppConfiguration implements android.os.Parcelable { - ctor @Deprecated public BluetoothHealthAppConfiguration(); method @Deprecated public int describeContents(); method @Deprecated public int getDataType(); method @Deprecated public String getName(); @@ -11251,7 +11245,6 @@ package android.content.pm { public class LauncherApps { method public java.util.List<android.content.pm.LauncherActivityInfo> getActivityList(String, android.os.UserHandle); method @NonNull public java.util.List<android.content.pm.PackageInstaller.SessionInfo> getAllPackageInstallerSessions(); - method @Nullable public android.content.pm.LauncherApps.AppUsageLimit getAppUsageLimit(@NonNull String, @NonNull android.os.UserHandle); method public android.content.pm.ApplicationInfo getApplicationInfo(@NonNull String, int, @NonNull android.os.UserHandle) throws android.content.pm.PackageManager.NameNotFoundException; method public android.content.pm.LauncherApps.PinItemRequest getPinItemRequest(android.content.Intent); method public java.util.List<android.os.UserHandle> getProfiles(); @@ -11282,14 +11275,6 @@ package android.content.pm { field public static final String EXTRA_PIN_ITEM_REQUEST = "android.content.pm.extra.PIN_ITEM_REQUEST"; } - public static final class LauncherApps.AppUsageLimit implements android.os.Parcelable { - method public int describeContents(); - method public long getTotalUsageLimit(); - method public long getUsageRemaining(); - method public void writeToParcel(android.os.Parcel, int); - field @NonNull public static final android.os.Parcelable.Creator<android.content.pm.LauncherApps.AppUsageLimit> CREATOR; - } - public abstract static class LauncherApps.Callback { ctor public LauncherApps.Callback(); method public abstract void onPackageAdded(String, android.os.UserHandle); @@ -11453,7 +11438,7 @@ package android.content.pm { method @Nullable public android.graphics.Bitmap getAppIcon(); method @Nullable public CharSequence getAppLabel(); method @Nullable public String getAppPackageName(); - method public int[] getChildSessionIds(); + method @NonNull public int[] getChildSessionIds(); method public int getInstallLocation(); method public int getInstallReason(); method @Nullable public String getInstallerPackageName(); @@ -11534,107 +11519,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 @@ -15388,8 +15373,8 @@ package android.graphics.drawable { method public boolean setState(@NonNull int[]); method public void setTint(@ColorInt int); method public void setTintList(@Nullable android.content.res.ColorStateList); - method @Deprecated public void setTintMode(@NonNull android.graphics.PorterDuff.Mode); - method public void setTintMode(@NonNull android.graphics.BlendMode); + method @Deprecated public void setTintMode(@Nullable android.graphics.PorterDuff.Mode); + method public void setTintMode(@Nullable android.graphics.BlendMode); method public boolean setVisible(boolean, boolean); method public void unscheduleSelf(@NonNull Runnable); } @@ -17057,6 +17042,7 @@ package android.hardware.camera2 { public class CaptureFailure { method public long getFrameNumber(); + method @Nullable public String getPhysicalCameraId(); method public int getReason(); method @NonNull public android.hardware.camera2.CaptureRequest getRequest(); method public int getSequenceId(); @@ -23279,6 +23265,7 @@ package android.media { method @Deprecated public boolean registerRemoteController(android.media.RemoteController); method @Deprecated public int requestAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener, int, int); method public int requestAudioFocus(@NonNull android.media.AudioFocusRequest); + method public void setAllowedCapturePolicy(int); method @Deprecated public void setBluetoothA2dpOn(boolean); method public void setBluetoothScoOn(boolean); method public void setMicrophoneMute(boolean); @@ -28718,12 +28705,12 @@ package android.net { public static class ConnectivityManager.NetworkCallback { ctor public ConnectivityManager.NetworkCallback(); - method public void onAvailable(android.net.Network); + method public void onAvailable(@NonNull android.net.Network); method public void onBlockedStatusChanged(@NonNull android.net.Network, boolean); - method public void onCapabilitiesChanged(android.net.Network, android.net.NetworkCapabilities); - method public void onLinkPropertiesChanged(android.net.Network, android.net.LinkProperties); - method public void onLosing(android.net.Network, int); - method public void onLost(android.net.Network); + method public void onCapabilitiesChanged(@NonNull android.net.Network, @NonNull android.net.NetworkCapabilities); + method public void onLinkPropertiesChanged(@NonNull android.net.Network, @NonNull android.net.LinkProperties); + method public void onLosing(@NonNull android.net.Network, int); + method public void onLost(@NonNull android.net.Network); method public void onUnavailable(); } @@ -28755,6 +28742,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 @@ -28789,11 +28777,11 @@ package android.net { } public final class IpPrefix implements android.os.Parcelable { - method public boolean contains(java.net.InetAddress); + method public boolean contains(@NonNull java.net.InetAddress); method public int describeContents(); - method public java.net.InetAddress getAddress(); - method public int getPrefixLength(); - method public byte[] getRawAddress(); + method @NonNull public java.net.InetAddress getAddress(); + method @IntRange(from=0, to=128) public int getPrefixLength(); + method @NonNull public byte[] getRawAddress(); method public void writeToParcel(android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.net.IpPrefix> CREATOR; } @@ -28866,7 +28854,7 @@ package android.net { method public int describeContents(); method public java.net.InetAddress getAddress(); method public int getFlags(); - method public int getPrefixLength(); + method @IntRange(from=0, to=128) public int getPrefixLength(); method public int getScope(); method public void writeToParcel(android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.net.LinkAddress> CREATOR; @@ -29136,9 +29124,9 @@ package android.net { public final class RouteInfo implements android.os.Parcelable { method public int describeContents(); - method public android.net.IpPrefix getDestination(); - method public java.net.InetAddress getGateway(); - method public String getInterface(); + method @NonNull public android.net.IpPrefix getDestination(); + method @Nullable public java.net.InetAddress getGateway(); + method @Nullable public String getInterface(); method public boolean hasGateway(); method public boolean isDefaultRoute(); method public boolean matches(java.net.InetAddress); @@ -34657,9 +34645,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; @@ -42529,6 +42519,7 @@ package android.system { method public static int getpid(); method public static int getppid(); method public static java.net.SocketAddress getsockname(java.io.FileDescriptor) throws android.system.ErrnoException; + method @NonNull public static android.system.StructTimeval getsockoptTimeval(@NonNull java.io.FileDescriptor, int, int) throws android.system.ErrnoException; method public static int gettid(); method public static int getuid(); method public static byte[] getxattr(String, String) throws android.system.ErrnoException; @@ -42579,6 +42570,7 @@ package android.system { method @Deprecated public static void setgid(int) throws android.system.ErrnoException; method public static int setsid() throws android.system.ErrnoException; method public static void setsockoptInt(java.io.FileDescriptor, int, int, int) throws android.system.ErrnoException; + method public static void setsockoptTimeval(@NonNull java.io.FileDescriptor, int, int, @NonNull android.system.StructTimeval) throws android.system.ErrnoException; method @Deprecated public static void setuid(int) throws android.system.ErrnoException; method public static void setxattr(String, String, byte[], int) throws android.system.ErrnoException; method public static void shutdown(java.io.FileDescriptor, int) throws android.system.ErrnoException; @@ -42784,6 +42776,10 @@ package android.system { field public static final int F_SETOWN; field public static final int F_UNLCK; field public static final int F_WRLCK; + field public static final int ICMP6_ECHO_REPLY; + field public static final int ICMP6_ECHO_REQUEST; + field public static final int ICMP_ECHO; + field public static final int ICMP_ECHOREPLY; field public static final int IFA_F_DADFAILED; field public static final int IFA_F_DEPRECATED; field public static final int IFA_F_HOMEADDRESS; @@ -43156,6 +43152,13 @@ package android.system { field public final long tv_sec; } + public final class StructTimeval { + method @NonNull public static android.system.StructTimeval fromMillis(long); + method public long toMillis(); + field public final long tv_sec; + field public final long tv_usec; + } + public final class StructUtsname { ctor public StructUtsname(String, String, String, String, String); field public final String machine; @@ -52311,7 +52314,7 @@ package android.view.accessibility { method public java.util.List<android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction> getActionList(); method @Deprecated public int getActions(); method public java.util.List<java.lang.String> getAvailableExtraData(); - method public void getBoundsInParent(android.graphics.Rect); + method @Deprecated public void getBoundsInParent(android.graphics.Rect); method public void getBoundsInScreen(android.graphics.Rect); method public android.view.accessibility.AccessibilityNodeInfo getChild(int); method public int getChildCount(); @@ -52380,7 +52383,7 @@ package android.view.accessibility { method public boolean removeChild(android.view.View, int); method public void setAccessibilityFocused(boolean); method public void setAvailableExtraData(java.util.List<java.lang.String>); - method public void setBoundsInParent(android.graphics.Rect); + method @Deprecated public void setBoundsInParent(android.graphics.Rect); method public void setBoundsInScreen(android.graphics.Rect); method public void setCanOpenPopup(boolean); method public void setCheckable(boolean); diff --git a/api/system-current.txt b/api/system-current.txt index 48b1385a872f..394b1aaf3bac 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -119,9 +119,11 @@ package android { field public static final String MODIFY_PARENTAL_CONTROLS = "android.permission.MODIFY_PARENTAL_CONTROLS"; field public static final String MODIFY_QUIET_MODE = "android.permission.MODIFY_QUIET_MODE"; field public static final String MOVE_PACKAGE = "android.permission.MOVE_PACKAGE"; + field public static final String NETWORK_CARRIER_PROVISIONING = "android.permission.NETWORK_CARRIER_PROVISIONING"; field public static final String NETWORK_MANAGED_PROVISIONING = "android.permission.NETWORK_MANAGED_PROVISIONING"; field public static final String NETWORK_SCAN = "android.permission.NETWORK_SCAN"; field public static final String NETWORK_SETUP_WIZARD = "android.permission.NETWORK_SETUP_WIZARD"; + field public static final String NETWORK_SIGNAL_STRENGTH_WAKEUP = "android.permission.NETWORK_SIGNAL_STRENGTH_WAKEUP"; field public static final String NOTIFICATION_DURING_SETUP = "android.permission.NOTIFICATION_DURING_SETUP"; field public static final String NOTIFY_TV_INPUTS = "android.permission.NOTIFY_TV_INPUTS"; field public static final String OBSERVE_APP_USAGE = "android.permission.OBSERVE_APP_USAGE"; @@ -404,9 +406,9 @@ package android.app { method public int describeContents(); method public long getBeginTimeMillis(); method public long getEndTimeMillis(); - method public int getUidCount(); + method @IntRange(from=0) public int getUidCount(); method @Nullable public android.app.AppOpsManager.HistoricalUidOps getUidOps(int); - method @NonNull public android.app.AppOpsManager.HistoricalUidOps getUidOpsAt(int); + method @NonNull public android.app.AppOpsManager.HistoricalUidOps getUidOpsAt(@IntRange(from=0) int); method public void writeToParcel(android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.app.AppOpsManager.HistoricalOps> CREATOR; } @@ -426,8 +428,8 @@ package android.app { public static final class AppOpsManager.HistoricalPackageOps implements android.os.Parcelable { method public int describeContents(); method @Nullable public android.app.AppOpsManager.HistoricalOp getOp(@NonNull String); - method @NonNull public android.app.AppOpsManager.HistoricalOp getOpAt(int); - method public int getOpCount(); + method @NonNull public android.app.AppOpsManager.HistoricalOp getOpAt(@IntRange(from=0) int); + method @IntRange(from=0) public int getOpCount(); method @NonNull public String getPackageName(); method public void writeToParcel(@NonNull android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.app.AppOpsManager.HistoricalPackageOps> CREATOR; @@ -435,9 +437,9 @@ package android.app { public static final class AppOpsManager.HistoricalUidOps implements android.os.Parcelable { method public int describeContents(); - method public int getPackageCount(); + method @IntRange(from=0) public int getPackageCount(); method @Nullable public android.app.AppOpsManager.HistoricalPackageOps getPackageOps(@NonNull String); - method @NonNull public android.app.AppOpsManager.HistoricalPackageOps getPackageOpsAt(int); + method @NonNull public android.app.AppOpsManager.HistoricalPackageOps getPackageOpsAt(@IntRange(from=0) int); method public int getUid(); method public void writeToParcel(android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.app.AppOpsManager.HistoricalUidOps> CREATOR; @@ -1258,9 +1260,9 @@ package android.bluetooth { public final class BluetoothDevice implements android.os.Parcelable { method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean cancelBondProcess(); method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public String getMetadata(int); - method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean getSilenceMode(); method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public boolean isConnected(); method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public boolean isEncrypted(); + method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean isInSilenceMode(); method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean removeBond(); method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setMetadata(int, String); method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setPhonebookAccessPermission(int); @@ -1269,7 +1271,6 @@ package android.bluetooth { field public static final int ACCESS_REJECTED = 2; // 0x2 field public static final int ACCESS_UNKNOWN = 0; // 0x0 field public static final String ACTION_SILENCE_MODE_CHANGED = "android.bluetooth.device.action.SILENCE_MODE_CHANGED"; - field public static final String EXTRA_SILENCE_ENABLED = "android.bluetooth.device.extra.SILENCE_ENABLED"; field public static final int METADATA_COMPANION_APP = 4; // 0x4 field public static final int METADATA_ENHANCED_SETTINGS_UI_URI = 16; // 0x10 field public static final int METADATA_HARDWARE_VERSION = 3; // 0x3 @@ -1458,14 +1459,14 @@ package android.content.om { public final class OverlayInfo implements android.os.Parcelable { method public int describeContents(); + method @Nullable public String getCategory(); + method @NonNull public String getPackageName(); + method @Nullable public String getTargetOverlayableName(); + method @Nullable public String getTargetPackageName(); + method public int getUserId(); method public boolean isEnabled(); method public void writeToParcel(android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.content.om.OverlayInfo> CREATOR; - field public final String category; - field public final String packageName; - field public final String targetOverlayableName; - field public final String targetPackageName; - field public final int userId; } public class OverlayManager { @@ -1550,6 +1551,18 @@ package android.content.pm { field @NonNull public static final android.os.Parcelable.Creator<android.content.pm.IntentFilterVerificationInfo> CREATOR; } + public class LauncherApps { + method @Nullable public android.content.pm.LauncherApps.AppUsageLimit getAppUsageLimit(@NonNull String, @NonNull android.os.UserHandle); + } + + public static final class LauncherApps.AppUsageLimit implements android.os.Parcelable { + method public int describeContents(); + method public long getTotalUsageLimit(); + method public long getUsageRemaining(); + method public void writeToParcel(android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.content.pm.LauncherApps.AppUsageLimit> CREATOR; + } + public class PackageInstaller { method @RequiresPermission(android.Manifest.permission.INSTALL_PACKAGES) public void setPermissionsResult(int, boolean); } @@ -1593,53 +1606,52 @@ 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"; field public static final String FEATURE_BROADCAST_RADIO = "android.hardware.broadcastradio"; field public static final String FEATURE_TELEPHONY_CARRIERLOCK = "android.hardware.telephony.carrierlock"; field public static final int FLAG_PERMISSION_GRANTED_BY_DEFAULT = 32; // 0x20 - field public static final int FLAG_PERMISSION_HIDDEN = 1024; // 0x400 field public static final int FLAG_PERMISSION_POLICY_FIXED = 4; // 0x4 field public static final int FLAG_PERMISSION_REVIEW_REQUIRED = 64; // 0x40 field public static final int FLAG_PERMISSION_REVOKE_ON_UPGRADE = 8; // 0x8 @@ -1710,7 +1722,7 @@ package android.content.pm { method public void onPermissionsChanged(int); } - @IntDef(prefix={"FLAG_PERMISSION_"}, value={android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET, android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED, android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED, android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE, android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED, android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT, android.content.pm.PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED, android.content.pm.PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_DENIED, android.content.pm.PackageManager.FLAG_PERMISSION_HIDDEN}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface PackageManager.PermissionFlags { + @IntDef(prefix={"FLAG_PERMISSION_"}, value={android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET, android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED, android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED, android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE, android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED, android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT, android.content.pm.PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED, android.content.pm.PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_DENIED}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface PackageManager.PermissionFlags { } public class PermissionGroupInfo extends android.content.pm.PackageItemInfo implements android.os.Parcelable { @@ -4061,7 +4073,7 @@ package android.net { } public final class IpPrefix implements android.os.Parcelable { - ctor public IpPrefix(@NonNull java.net.InetAddress, int); + ctor public IpPrefix(@NonNull java.net.InetAddress, @IntRange(from=0, to=128) int); ctor public IpPrefix(@NonNull String); } @@ -4082,8 +4094,8 @@ package android.net { } public class LinkAddress implements android.os.Parcelable { - ctor public LinkAddress(java.net.InetAddress, int, int, int); - ctor public LinkAddress(@NonNull java.net.InetAddress, int); + ctor public LinkAddress(@NonNull java.net.InetAddress, @IntRange(from=0, to=128) int, int, int); + ctor public LinkAddress(@NonNull java.net.InetAddress, @IntRange(from=0, to=128) int); ctor public LinkAddress(@NonNull String); ctor public LinkAddress(@NonNull String, int, int); method public boolean isGlobalPreferred(); @@ -4147,7 +4159,7 @@ package android.net { } public static class NetworkRequest.Builder { - method @NonNull public android.net.NetworkRequest.Builder setSignalStrength(int); + method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_SIGNAL_STRENGTH_WAKEUP) public android.net.NetworkRequest.Builder setSignalStrength(int); } public class NetworkScoreManager { @@ -4264,8 +4276,8 @@ package android.net.apf { public final class ApfCapabilities implements android.os.Parcelable { ctor public ApfCapabilities(int, int, int); method public int describeContents(); - method public static boolean getApfDrop8023Frames(@NonNull android.content.Context); - method @NonNull public static int[] getApfEthTypeBlackList(@NonNull android.content.Context); + method public static boolean getApfDrop8023Frames(); + method @NonNull public static int[] getApfEtherTypeBlackList(); method public boolean hasDataAccess(); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator<android.net.apf.ApfCapabilities> CREATOR; @@ -4276,37 +4288,6 @@ package android.net.apf { } -package android.net.captiveportal { - - public final class CaptivePortalProbeResult { - ctor public CaptivePortalProbeResult(int); - ctor public CaptivePortalProbeResult(int, @Nullable String, @Nullable String); - ctor public CaptivePortalProbeResult(int, @Nullable String, @Nullable String, @Nullable android.net.captiveportal.CaptivePortalProbeSpec); - method public boolean isFailed(); - method public boolean isPartialConnectivity(); - method public boolean isPortal(); - method public boolean isSuccessful(); - field @NonNull public static final android.net.captiveportal.CaptivePortalProbeResult FAILED; - field public static final int FAILED_CODE = 599; // 0x257 - field public static final android.net.captiveportal.CaptivePortalProbeResult PARTIAL; - field public static final int PORTAL_CODE = 302; // 0x12e - field @NonNull public static final android.net.captiveportal.CaptivePortalProbeResult SUCCESS; - field public static final int SUCCESS_CODE = 204; // 0xcc - field @Nullable public final String detectUrl; - field @Nullable public final android.net.captiveportal.CaptivePortalProbeSpec probeSpec; - field @Nullable public final String redirectUrl; - } - - public abstract class CaptivePortalProbeSpec { - method @NonNull public String getEncodedSpec(); - method @NonNull public abstract android.net.captiveportal.CaptivePortalProbeResult getResult(int, @Nullable String); - method @NonNull public java.net.URL getUrl(); - method @NonNull public static java.util.Collection<android.net.captiveportal.CaptivePortalProbeSpec> parseCaptivePortalProbeSpecs(@NonNull String); - method @Nullable public static android.net.captiveportal.CaptivePortalProbeSpec parseSpecOrNull(@Nullable String); - } - -} - package android.net.metrics { public final class ApfProgramEvent implements android.net.metrics.IpConnectivityLog.Event { @@ -6055,6 +6036,7 @@ package android.provider { field public static final String ACTION_ENTERPRISE_PRIVACY_SETTINGS = "android.settings.ENTERPRISE_PRIVACY_SETTINGS"; field public static final String ACTION_LOCATION_CONTROLLER_EXTRA_PACKAGE_SETTINGS = "android.settings.LOCATION_CONTROLLER_EXTRA_PACKAGE_SETTINGS"; field public static final String ACTION_MANAGE_DOMAIN_URLS = "android.settings.MANAGE_DOMAIN_URLS"; + field public static final String ACTION_MANAGE_MORE_DEFAULT_APPS_SETTINGS = "android.settings.MANAGE_MORE_DEFAULT_APPS_SETTINGS"; field public static final String ACTION_NOTIFICATION_POLICY_ACCESS_DETAIL_SETTINGS = "android.settings.NOTIFICATION_POLICY_ACCESS_DETAIL_SETTINGS"; field public static final String ACTION_REQUEST_ENABLE_CONTENT_CAPTURE = "android.settings.REQUEST_ENABLE_CONTENT_CAPTURE"; field public static final String ACTION_SHOW_ADMIN_SUPPORT_DETAILS = "android.settings.SHOW_ADMIN_SUPPORT_DETAILS"; diff --git a/api/test-current.txt b/api/test-current.txt index 6f8f310f6a2c..bb4d2335f7e9 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -238,9 +238,9 @@ package android.app { method public int describeContents(); method public long getBeginTimeMillis(); method public long getEndTimeMillis(); - method public int getUidCount(); + method @IntRange(from=0) public int getUidCount(); method @Nullable public android.app.AppOpsManager.HistoricalUidOps getUidOps(int); - method @NonNull public android.app.AppOpsManager.HistoricalUidOps getUidOpsAt(int); + method @NonNull public android.app.AppOpsManager.HistoricalUidOps getUidOpsAt(@IntRange(from=0) int); method public void increaseAccessCount(int, int, @NonNull String, int, int, long); method public void increaseAccessDuration(int, int, @NonNull String, int, int, long); method public void increaseRejectCount(int, int, @NonNull String, int, int, long); @@ -264,8 +264,8 @@ package android.app { public static final class AppOpsManager.HistoricalPackageOps implements android.os.Parcelable { method public int describeContents(); method @Nullable public android.app.AppOpsManager.HistoricalOp getOp(@NonNull String); - method @NonNull public android.app.AppOpsManager.HistoricalOp getOpAt(int); - method public int getOpCount(); + method @NonNull public android.app.AppOpsManager.HistoricalOp getOpAt(@IntRange(from=0) int); + method @IntRange(from=0) public int getOpCount(); method @NonNull public String getPackageName(); method public void writeToParcel(@NonNull android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.app.AppOpsManager.HistoricalPackageOps> CREATOR; @@ -273,9 +273,9 @@ package android.app { public static final class AppOpsManager.HistoricalUidOps implements android.os.Parcelable { method public int describeContents(); - method public int getPackageCount(); + method @IntRange(from=0) public int getPackageCount(); method @Nullable public android.app.AppOpsManager.HistoricalPackageOps getPackageOps(@NonNull String); - method @NonNull public android.app.AppOpsManager.HistoricalPackageOps getPackageOpsAt(int); + method @NonNull public android.app.AppOpsManager.HistoricalPackageOps getPackageOpsAt(@IntRange(from=0) int); method public int getUid(); method public void writeToParcel(android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.app.AppOpsManager.HistoricalUidOps> CREATOR; @@ -315,7 +315,9 @@ package android.app { } public final class NotificationChannel implements android.os.Parcelable { + method public boolean isImportanceLockedByCriticalDeviceFunction(); method public boolean isImportanceLockedByOEM(); + method public void setImportanceLockedByCriticalDeviceFunction(boolean); method public void setImportanceLockedByOEM(boolean); } @@ -661,26 +663,27 @@ 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 + field public static final int FLAG_PERMISSION_POLICY_FIXED = 4; // 0x4 field public static final int FLAG_PERMISSION_REVIEW_REQUIRED = 64; // 0x40 field public static final int FLAG_PERMISSION_REVOKE_ON_UPGRADE = 8; // 0x8 field public static final int FLAG_PERMISSION_REVOKE_WHEN_REQUESTED = 128; // 0x80 + field public static final int FLAG_PERMISSION_SYSTEM_FIXED = 16; // 0x10 field public static final int FLAG_PERMISSION_USER_FIXED = 2; // 0x2 field public static final int FLAG_PERMISSION_USER_SET = 1; // 0x1 field public static final int MATCH_FACTORY_ONLY = 2097152; // 0x200000 @@ -1237,7 +1240,7 @@ package android.net { } public final class IpPrefix implements android.os.Parcelable { - ctor public IpPrefix(@NonNull java.net.InetAddress, int); + ctor public IpPrefix(@NonNull java.net.InetAddress, @IntRange(from=0, to=128) int); ctor public IpPrefix(@NonNull String); } @@ -1246,8 +1249,8 @@ package android.net { } public class LinkAddress implements android.os.Parcelable { - ctor public LinkAddress(java.net.InetAddress, int, int, int); - ctor public LinkAddress(@NonNull java.net.InetAddress, int); + ctor public LinkAddress(@NonNull java.net.InetAddress, @IntRange(from=0, to=128) int, int, int); + ctor public LinkAddress(@NonNull java.net.InetAddress, @IntRange(from=0, to=128) int); ctor public LinkAddress(@NonNull String); ctor public LinkAddress(@NonNull String, int, int); method public boolean isGlobalPreferred(); @@ -1356,8 +1359,8 @@ package android.net.apf { public final class ApfCapabilities implements android.os.Parcelable { ctor public ApfCapabilities(int, int, int); method public int describeContents(); - method public static boolean getApfDrop8023Frames(@NonNull android.content.Context); - method @NonNull public static int[] getApfEthTypeBlackList(@NonNull android.content.Context); + method public static boolean getApfDrop8023Frames(); + method @NonNull public static int[] getApfEtherTypeBlackList(); method public boolean hasDataAccess(); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator<android.net.apf.ApfCapabilities> CREATOR; @@ -1368,37 +1371,6 @@ package android.net.apf { } -package android.net.captiveportal { - - public final class CaptivePortalProbeResult { - ctor public CaptivePortalProbeResult(int); - ctor public CaptivePortalProbeResult(int, @Nullable String, @Nullable String); - ctor public CaptivePortalProbeResult(int, @Nullable String, @Nullable String, @Nullable android.net.captiveportal.CaptivePortalProbeSpec); - method public boolean isFailed(); - method public boolean isPartialConnectivity(); - method public boolean isPortal(); - method public boolean isSuccessful(); - field @NonNull public static final android.net.captiveportal.CaptivePortalProbeResult FAILED; - field public static final int FAILED_CODE = 599; // 0x257 - field public static final android.net.captiveportal.CaptivePortalProbeResult PARTIAL; - field public static final int PORTAL_CODE = 302; // 0x12e - field @NonNull public static final android.net.captiveportal.CaptivePortalProbeResult SUCCESS; - field public static final int SUCCESS_CODE = 204; // 0xcc - field @Nullable public final String detectUrl; - field @Nullable public final android.net.captiveportal.CaptivePortalProbeSpec probeSpec; - field @Nullable public final String redirectUrl; - } - - public abstract class CaptivePortalProbeSpec { - method @NonNull public String getEncodedSpec(); - method @NonNull public abstract android.net.captiveportal.CaptivePortalProbeResult getResult(int, @Nullable String); - method @NonNull public java.net.URL getUrl(); - method @NonNull public static java.util.Collection<android.net.captiveportal.CaptivePortalProbeSpec> parseCaptivePortalProbeSpecs(@NonNull String); - method @Nullable public static android.net.captiveportal.CaptivePortalProbeSpec parseSpecOrNull(@Nullable String); - } - -} - package android.net.metrics { public final class ApfProgramEvent implements android.net.metrics.IpConnectivityLog.Event { 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/idmap2/Android.bp b/cmds/idmap2/Android.bp index d757e4611158..18d56fa87cca 100644 --- a/cmds/idmap2/Android.bp +++ b/cmds/idmap2/Android.bp @@ -84,6 +84,7 @@ cc_test { "-readability-magic-numbers", ], host_supported: true, + test_suites: ["general-tests"], srcs: [ "tests/BinaryStreamVisitorTests.cpp", "tests/CommandLineOptionsTests.cpp", diff --git a/cmds/incidentd/src/FdBuffer.cpp b/cmds/incidentd/src/FdBuffer.cpp index 685c0677c8fa..b46c9e357fc4 100644 --- a/cmds/incidentd/src/FdBuffer.cpp +++ b/cmds/incidentd/src/FdBuffer.cpp @@ -31,7 +31,7 @@ namespace os { namespace incidentd { const ssize_t BUFFER_SIZE = 16 * 1024; // 16 KB -const ssize_t MAX_BUFFER_COUNT = 256; // 4 MB max +const ssize_t MAX_BUFFER_COUNT = 1536; // 24 MB max FdBuffer::FdBuffer() :mBuffer(new EncodedBuffer(BUFFER_SIZE)), 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/cmds/sm/src/com/android/commands/sm/Sm.java b/cmds/sm/src/com/android/commands/sm/Sm.java index 4a6f87f09d29..6033655c8513 100644 --- a/cmds/sm/src/com/android/commands/sm/Sm.java +++ b/cmds/sm/src/com/android/commands/sm/Sm.java @@ -103,8 +103,6 @@ public final class Sm { runSetVirtualDisk(); } else if ("set-isolated-storage".equals(op)) { runIsolatedStorage(); - } else if ("set-legacy-greylist".equals(op)) { - runLegacyGreylist(); } else { throw new IllegalArgumentException(); } @@ -306,12 +304,6 @@ public final class Sm { mSm.setDebugFlags(value, mask); } - public void runLegacyGreylist() throws RemoteException { - final boolean legacyGreylist = Boolean.parseBoolean(nextArg()); - mSm.setDebugFlags(legacyGreylist ? StorageManager.DEBUG_LEGACY_GREYLIST : 0, - StorageManager.DEBUG_LEGACY_GREYLIST); - } - public void runIdleMaint() throws RemoteException { final boolean im_run = "run".equals(nextArg()); if (im_run) { diff --git a/cmds/statsd/Android.bp b/cmds/statsd/Android.bp index 8cd409e5e8c1..017cb6d9221e 100644 --- a/cmds/statsd/Android.bp +++ b/cmds/statsd/Android.bp @@ -81,7 +81,7 @@ cc_defaults { "src/external/StatsPullerManager.cpp", "src/external/puller_util.cpp", "src/logd/LogEvent.cpp", - "src/logd/LogListener.cpp", + "src/logd/LogEventQueue.cpp", "src/matchers/CombinationLogMatchingTracker.cpp", "src/matchers/EventMatcherWizard.cpp", "src/matchers/matcher_util.cpp", @@ -226,6 +226,7 @@ cc_test { "tests/indexed_priority_queue_test.cpp", "tests/LogEntryMatcher_test.cpp", "tests/LogEvent_test.cpp", + "tests/log_event/LogEventQueue_test.cpp", "tests/MetricsManager_test.cpp", "tests/StatsLogProcessor_test.cpp", "tests/StatsService_test.cpp", diff --git a/cmds/statsd/src/StatsLogProcessor.cpp b/cmds/statsd/src/StatsLogProcessor.cpp index 286e76ec108a..df84b6a4dc34 100644 --- a/cmds/statsd/src/StatsLogProcessor.cpp +++ b/cmds/statsd/src/StatsLogProcessor.cpp @@ -602,6 +602,19 @@ void StatsLogProcessor::WriteDataToDiskLocked(const ConfigKey& key, void StatsLogProcessor::WriteMetricsActivationToDisk(int64_t currentTimeNs) { std::lock_guard<std::mutex> lock(mMetricsMutex); + + const int64_t timeNs = getElapsedRealtimeNs(); + // Do not write to disk if we already have in the last few seconds. + // This is to avoid overwriting files that would have the same name if we + // write twice in the same second. + if (static_cast<unsigned long long> (timeNs) < + mLastActiveMetricsWriteNs + WRITE_DATA_COOL_DOWN_SEC * NS_PER_SEC) { + ALOGI("Statsd skipping writing active metrics to disk. Already wrote data in last %d seconds", + WRITE_DATA_COOL_DOWN_SEC); + return; + } + mLastActiveMetricsWriteNs = timeNs; + ProtoOutputStream proto; for (const auto& pair : mMetricsManagers) { diff --git a/cmds/statsd/src/StatsLogProcessor.h b/cmds/statsd/src/StatsLogProcessor.h index e92b8971fd48..8de1881eb2b8 100644 --- a/cmds/statsd/src/StatsLogProcessor.h +++ b/cmds/statsd/src/StatsLogProcessor.h @@ -207,6 +207,9 @@ private: // Last time we wrote data to disk. int64_t mLastWriteTimeNs = 0; + // Last time we wrote active metrics to disk. + int64_t mLastActiveMetricsWriteNs = 0; + #ifdef VERY_VERBOSE_PRINTING bool mPrintAllLogs = false; #endif diff --git a/cmds/statsd/src/StatsService.cpp b/cmds/statsd/src/StatsService.cpp index 52ecdc8425af..14332528e992 100644 --- a/cmds/statsd/src/StatsService.cpp +++ b/cmds/statsd/src/StatsService.cpp @@ -65,8 +65,6 @@ constexpr const char* kOpUsage = "android:get_usage_stats"; // for StatsDataDumpProto const int FIELD_ID_REPORTS_LIST = 1; -// for TrainInfo experiment id serialization -const int FIELD_ID_EXPERIMENT_ID = 1; static binder::Status ok() { return binder::Status::ok(); @@ -132,34 +130,36 @@ binder::Status checkDumpAndUsageStats(const String16& packageName) { } \ } -StatsService::StatsService(const sp<Looper>& handlerLooper) - : mAnomalyAlarmMonitor(new AlarmMonitor(MIN_DIFF_TO_UPDATE_REGISTERED_ALARM_SECS, - [](const sp<IStatsCompanionService>& sc, int64_t timeMillis) { - if (sc != nullptr) { - sc->setAnomalyAlarm(timeMillis); - StatsdStats::getInstance().noteRegisteredAnomalyAlarmChanged(); - } - }, - [](const sp<IStatsCompanionService>& sc) { - if (sc != nullptr) { - sc->cancelAnomalyAlarm(); - StatsdStats::getInstance().noteRegisteredAnomalyAlarmChanged(); - } - })), - mPeriodicAlarmMonitor(new AlarmMonitor(MIN_DIFF_TO_UPDATE_REGISTERED_ALARM_SECS, - [](const sp<IStatsCompanionService>& sc, int64_t timeMillis) { - if (sc != nullptr) { - sc->setAlarmForSubscriberTriggering(timeMillis); - StatsdStats::getInstance().noteRegisteredPeriodicAlarmChanged(); - } - }, - [](const sp<IStatsCompanionService>& sc) { - if (sc != nullptr) { - sc->cancelAlarmForSubscriberTriggering(); - StatsdStats::getInstance().noteRegisteredPeriodicAlarmChanged(); - } - - })) { +StatsService::StatsService(const sp<Looper>& handlerLooper, shared_ptr<LogEventQueue> queue) + : mAnomalyAlarmMonitor(new AlarmMonitor( + MIN_DIFF_TO_UPDATE_REGISTERED_ALARM_SECS, + [](const sp<IStatsCompanionService>& sc, int64_t timeMillis) { + if (sc != nullptr) { + sc->setAnomalyAlarm(timeMillis); + StatsdStats::getInstance().noteRegisteredAnomalyAlarmChanged(); + } + }, + [](const sp<IStatsCompanionService>& sc) { + if (sc != nullptr) { + sc->cancelAnomalyAlarm(); + StatsdStats::getInstance().noteRegisteredAnomalyAlarmChanged(); + } + })), + mPeriodicAlarmMonitor(new AlarmMonitor( + MIN_DIFF_TO_UPDATE_REGISTERED_ALARM_SECS, + [](const sp<IStatsCompanionService>& sc, int64_t timeMillis) { + if (sc != nullptr) { + sc->setAlarmForSubscriberTriggering(timeMillis); + StatsdStats::getInstance().noteRegisteredPeriodicAlarmChanged(); + } + }, + [](const sp<IStatsCompanionService>& sc) { + if (sc != nullptr) { + sc->cancelAlarmForSubscriberTriggering(); + StatsdStats::getInstance().noteRegisteredPeriodicAlarmChanged(); + } + })), + mEventQueue(queue) { mUidMap = UidMap::getInstance(); mPullerManager = new StatsPullerManager(); StatsPuller::SetUidMap(mUidMap); @@ -201,11 +201,33 @@ StatsService::StatsService(const sp<Looper>& handlerLooper) mConfigManager->AddListener(mProcessor); init_system_properties(); + + if (mEventQueue != nullptr) { + std::thread pushedEventThread([this] { readLogs(); }); + pushedEventThread.detach(); + } } StatsService::~StatsService() { } +/* Runs on a dedicated thread to process pushed events. */ +void StatsService::readLogs() { + // Read forever..... long live statsd + while (1) { + // Block until an event is available. + auto event = mEventQueue->waitPop(); + // Pass it to StatsLogProcess to all configs/metrics + // At this point, the LogEventQueue is not blocked, so that the socketListener + // can read events from the socket and write to buffer to avoid data drop. + mProcessor->OnLogEvent(event.get()); + // The ShellSubscriber is only used by shell for local debugging. + if (mShellSubscriber != nullptr) { + mShellSubscriber->onLogEvent(*event); + } + } +} + void StatsService::init_system_properties() { mEngBuild = false; const prop_info* buildType = __system_property_find("ro.build.type"); @@ -1006,9 +1028,11 @@ void StatsService::Terminate() { ALOGI("StatsService::Terminating"); if (mProcessor != nullptr) { mProcessor->WriteDataToDisk(TERMINATION_SIGNAL_RECEIVED, FAST); + mProcessor->WriteMetricsActivationToDisk(getElapsedRealtimeNs()); } } +// Test only interface!!! void StatsService::OnLogEvent(LogEvent* event) { mProcessor->OnLogEvent(event); if (mShellSubscriber != nullptr) { @@ -1181,7 +1205,7 @@ Status StatsService::unregisterPullerCallback(int32_t atomTag, const String16& p Status StatsService::sendBinaryPushStateChangedAtom(const android::String16& trainName, int64_t trainVersionCode, int options, int32_t state, - const std::vector<int64_t>& experimentIds) { + const std::vector<int64_t>& experimentIdsIn) { uid_t uid = IPCThreadState::self()->getCallingUid(); // For testing if (uid == AID_ROOT || uid == AID_SYSTEM || uid == AID_SHELL) { @@ -1201,7 +1225,7 @@ Status StatsService::sendBinaryPushStateChangedAtom(const android::String16& tra bool readTrainInfoSuccess = false; InstallTrainInfo trainInfo; - if (trainVersionCode == -1 || experimentIds.empty() || trainName.size() == 0) { + if (trainVersionCode == -1 || experimentIdsIn.empty() || trainName.size() == 0) { readTrainInfoSuccess = StorageManager::readTrainInfo(trainInfo); } @@ -1209,27 +1233,19 @@ Status StatsService::sendBinaryPushStateChangedAtom(const android::String16& tra trainVersionCode = trainInfo.trainVersionCode; } - vector<uint8_t> experimentIdsProtoBuffer; - if (readTrainInfoSuccess && experimentIds.empty()) { - experimentIdsProtoBuffer = trainInfo.experimentIds; + // Find the right experiment IDs + std::vector<int64_t> experimentIds; + if (readTrainInfoSuccess && experimentIdsIn.empty()) { + experimentIds = trainInfo.experimentIds; } else { - ProtoOutputStream proto; - for (const auto& expId : experimentIds) { - proto.write(FIELD_TYPE_INT64 | FIELD_COUNT_REPEATED | FIELD_ID_EXPERIMENT_ID, - (long long)expId); - } - - experimentIdsProtoBuffer.resize(proto.size()); - size_t pos = 0; - sp<ProtoReader> reader = proto.data(); - while (reader->readBuffer() != NULL) { - size_t toRead = reader->currentToRead(); - std::memcpy(&(experimentIdsProtoBuffer[pos]), reader->readBuffer(), toRead); - pos += toRead; - reader->move(toRead); - } + experimentIds = experimentIdsIn; } + // Flatten the experiment IDs to proto + vector<uint8_t> experimentIdsProtoBuffer; + writeExperimentIdsToProto(experimentIds, &experimentIdsProtoBuffer); + + // Find the right train name std::string trainNameUtf8; if (readTrainInfoSuccess && trainName.size() == 0) { trainNameUtf8 = trainInfo.trainName; @@ -1244,7 +1260,34 @@ Status StatsService::sendBinaryPushStateChangedAtom(const android::String16& tra LogEvent event(trainNameUtf8, trainVersionCode, requiresStaging, rollbackEnabled, requiresLowLatencyMonitor, state, experimentIdsProtoBuffer, userId); mProcessor->OnLogEvent(&event); - StorageManager::writeTrainInfo(trainVersionCode, trainNameUtf8, state, experimentIdsProtoBuffer); + StorageManager::writeTrainInfo(trainVersionCode, trainNameUtf8, state, experimentIds); + return Status::ok(); +} + +Status StatsService::getRegisteredExperimentIds(std::vector<int64_t>* experimentIdsOut) { + uid_t uid = IPCThreadState::self()->getCallingUid(); + + // Caller must be granted these permissions + if (!checkCallingPermission(String16(kPermissionDump))) { + return exception(binder::Status::EX_SECURITY, + StringPrintf("UID %d lacks permission %s", uid, kPermissionDump)); + } + if (!checkCallingPermission(String16(kPermissionUsage))) { + return exception(binder::Status::EX_SECURITY, + StringPrintf("UID %d lacks permission %s", uid, kPermissionUsage)); + } + // TODO: add verifier permission + + // Read the latest train info + InstallTrainInfo trainInfo; + if (!StorageManager::readTrainInfo(trainInfo)) { + // No train info means no experiment IDs, return an empty list + experimentIdsOut->clear(); + return Status::ok(); + } + + // Copy the experiment IDs to the out vector + experimentIdsOut->assign(trainInfo.experimentIds.begin(), trainInfo.experimentIds.end()); return Status::ok(); } diff --git a/cmds/statsd/src/StatsService.h b/cmds/statsd/src/StatsService.h index d24565a63054..929d260dcd95 100644 --- a/cmds/statsd/src/StatsService.h +++ b/cmds/statsd/src/StatsService.h @@ -22,7 +22,7 @@ #include "anomaly/AlarmMonitor.h" #include "config/ConfigManager.h" #include "external/StatsPullerManager.h" -#include "logd/LogListener.h" +#include "logd/LogEventQueue.h" #include "packages/UidMap.h" #include "shell/ShellSubscriber.h" #include "statscompanion_util.h" @@ -52,11 +52,10 @@ namespace statsd { using android::hardware::Return; class StatsService : public BnStatsManager, - public LogListener, public IStats, public IBinder::DeathRecipient { public: - StatsService(const sp<Looper>& handlerLooper); + StatsService(const sp<Looper>& handlerLooper, std::shared_ptr<LogEventQueue> queue); virtual ~StatsService(); /** The anomaly alarm registered with AlarmManager won't be updated by less than this. */ @@ -92,7 +91,7 @@ public: void Terminate(); /** - * Called by LogReader when there's a log event to process. + * Test ONLY interface. In real world, StatsService reads from LogEventQueue. */ virtual void OnLogEvent(LogEvent* event); @@ -194,6 +193,11 @@ public: int32_t state, const std::vector<int64_t>& experimentIds) override; /** + * Binder call to get registered experiment IDs. + */ + virtual Status getRegisteredExperimentIds(std::vector<int64_t>* expIdsOut); + + /** * Binder call to get SpeakerImpedance atom. */ virtual Return<void> reportSpeakerImpedance(const SpeakerImpedance& speakerImpedance) override; @@ -278,6 +282,9 @@ private: */ void print_cmd_help(int out); + /* Runs on its dedicated thread to process pushed stats event from socket. */ + void readLogs(); + /** * Trigger a broadcast. */ @@ -410,6 +417,8 @@ private: sp<ShellSubscriber> mShellSubscriber; + std::shared_ptr<LogEventQueue> mEventQueue; + FRIEND_TEST(StatsServiceTest, TestAddConfig_simple); FRIEND_TEST(StatsServiceTest, TestAddConfig_empty); FRIEND_TEST(StatsServiceTest, TestAddConfig_invalid); diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto index aeac546de830..dc4413f5457c 100644 --- a/cmds/statsd/src/atoms.proto +++ b/cmds/statsd/src/atoms.proto @@ -41,6 +41,7 @@ import "frameworks/base/core/proto/android/server/location/enums.proto"; import "frameworks/base/core/proto/android/service/procstats_enum.proto"; import "frameworks/base/core/proto/android/service/usb.proto"; import "frameworks/base/core/proto/android/stats/connectivity/network_stack.proto"; +import "frameworks/base/core/proto/android/stats/connectivity/resolv_stats.proto"; import "frameworks/base/core/proto/android/stats/enums.proto"; import "frameworks/base/core/proto/android/stats/docsui/docsui_enums.proto"; import "frameworks/base/core/proto/android/stats/devicepolicy/device_policy.proto"; @@ -254,6 +255,11 @@ message Atom { PrivacyIndicatorsInteracted privacy_indicators_interacted = 180; AppInstallOnExternalStorageReported app_install_on_external_storage_reported = 181; NetworkStackReported network_stack_reported = 182; + AppMovedStorageReported app_moved_storage_reported = 183; + BiometricEnrolled biometric_enrolled = 184; + SystemServerWatchdogOccurred system_server_watchdog_occurred = 185; + TombStoneOccurred tomb_stone_occurred = 186; + BluetoothClassOfDeviceReported bluetooth_class_of_device_reported = 187; } // Pulled events will start at field 10000. @@ -2137,6 +2143,29 @@ message BluetoothSocketConnectionStateChanged { } /** + * Logs when Class of Device (CoD) value is learnt for a device during pairing or connection + * + * Logged from: + * packages/apps/Bluetooth/src/com/android/bluetooth/btservice/BondStateMachine.java + * packages/apps/Bluetooth/src/com/android/bluetooth/btservice/RemoteDevices.java + * + */ +message BluetoothClassOfDeviceReported { + // An identifier that can be used to match events for this device. + // Currently, this is a salted hash of the MAC address of this Bluetooth device. + // Salt: Randomly generated 256 bit value + // Hash algorithm: HMAC-SHA256 + // Size: 32 byte + // Default: null or empty if this is a server listener socket + optional bytes obfuscated_id = 1 [(android.os.statsd.log_mode) = MODE_BYTES]; + // Class of Device (CoD) value including both Major, Minor device class and service class + // Defined in: https://www.bluetooth.com/specifications/assigned-numbers/baseband + // Also defined in: https://developer.android.com/reference/android/bluetooth/BluetoothClass + // Default: 0 + optional int32 class_of_device = 2; +} + +/** * Logs when something is plugged into or removed from the USB-C connector. * * Logged from: @@ -3153,6 +3182,23 @@ message BiometricSystemHealthIssueDetected { optional android.hardware.biometrics.IssueEnum issue = 2; } +/** + * Logs when a biometric enrollment occurs. + * + * Logged from: + * frameworks/base/services/core/java/com/android/server/biometrics + */ +message BiometricEnrolled { + // Biometric modality that was used. + optional android.hardware.biometrics.ModalityEnum modality = 1; + // The associated user. Eg: 0 for owners, 10+ for others. Defined in android/os/UserHandle.java + optional int32 user = 2; + // The amount of time the enrollment took in milliseconds. + optional int64 latency_millis = 3; + // Whether or not the enrollment was successful. + optional bool success = 4; +} + message Notification { // Type of notification event. @@ -3279,6 +3325,9 @@ message BinaryPushStateChanged { INSTALLER_ROLLBACK_CANCEL_STAGED_DELETE_SESSION_INITIATED = 18; INSTALLER_ROLLBACK_CANCEL_STAGED_DELETE_SESSION_SUCCESS = 19; INSTALLER_ROLLBACK_CANCEL_STAGED_DELETE_SESSION_FAILURE = 20; + INSTALL_STAGED_CANCEL_REQUESTED = 21; + INSTALL_STAGED_CANCEL_SUCCESS = 22; + INSTALL_STAGED_CANCEL_FAILURE = 23; } optional State state = 6; // Possible experiment ids for monitoring this push. @@ -3446,6 +3495,47 @@ message PrivacyIndicatorsInteracted { optional string package_name = 2; } +/** + * Logs information about a package that is moved from the internal to external storage and vice + * versa. + * It logs the package name, the type of the external storage where the package is installed + * (if moved to external storage, or UNKNOWN if moved to internal storage), + * and the move type: if it's from internal to external or the other way around. + * + * Logged from: + frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java + */ +message AppMovedStorageReported { + enum MoveType { + UNKNOWN = 0; + TO_EXTERNAL = 1; + TO_INTERNAL = 2; + } + // The type of the external storage. + optional android.stats.storage.ExternalStorageType external_storage_type = 1; + // The type of move. + optional MoveType move_type = 2; + // The name of the package that was moved. + optional string package_name = 3; +} + +/** + * Logs when system server watchdog occurs. + * Logged from: + * frameworks/base/services/core/java/com/android/server/Watchdog.java + */ +message SystemServerWatchdogOccurred { + optional string subject = 1; +} + +/** + * Logs when new file added to tombstones. + * Logged from: + * frameworks/base/core/java/com/android/server/BootReceiver.java + */ +message TombStoneOccurred { +} + ////////////////////////////////////////////////////////////////////// // Pulled atoms below this line // ////////////////////////////////////////////////////////////////////// @@ -4950,53 +5040,39 @@ message AppCompacted { } /** - * Logs the latency period(in microseconds) and the return code of - * the DNS(Domain Name System) lookups. - * These 4 methods(GETADDRINFO,GETHOSTBYNAME,GETHOSTBYADDR,RES_NSEND) - * to get info(address or hostname) from DNS server(or DNS cache). - * Logged from: - * /system/netd/server/DnsProxyListener.cpp + * Logs a DNS lookup operation initiated by the system resolver on behalf of an application + * invoking native APIs such as getaddrinfo() or Java APIs such as Network#getAllByName(). + * + * The top-level message represents the entire lookup operation, which may result one or more + * queries to the recursive DNS resolvers. Those are individually logged in DnsQueryEvent to + * enable computing error rates and network latency and timeouts broken up by query type, + * transport, network interface, etc. */ message NetworkDnsEventReported { - // The types of the DNS lookups, as defined in - //system/netd/server/binder/android/net/metrics/INetdEventListener.aidl - enum EventType { - EVENT_UNKNOWN = 0; - EVENT_GETADDRINFO = 1; - EVENT_GETHOSTBYNAME = 2; - EVENT_GETHOSTBYADDR = 3; - EVENT_RES_NSEND = 4; - } - optional EventType event_type = 1; - // The return value of the DNS resolver for each DNS lookups. - //bionic/libc/include/netdb.h - //system/netd/resolv/include/netd_resolv/resolv.h - enum ReturnCode { - EAI_NO_ERROR = 0; - EAI_ADDRFAMILY = 1; - EAI_AGAIN = 2; - EAI_BADFLAGS = 3; - EAI_FAIL = 4; - EAI_FAMILY = 5; - EAI_MEMORY = 6; - EAI_NODATA = 7; - EAI_NONAME = 8; - EAI_SERVICE = 9; - EAI_SOCKTYPE = 10; - EAI_SYSTEM = 11; - EAI_BADHINTS = 12; - EAI_PROTOCOL = 13; - EAI_OVERFLOW = 14; - RESOLV_TIMEOUT = 255; - EAI_MAX = 256; - } - optional ReturnCode return_code = 2; + optional android.stats.connectivity.EventType event_type = 1; - // The latency period(in microseconds) it took for this DNS lookup to complete. + optional android.stats.connectivity.ReturnCode return_code = 2; + + // The latency in microseconds of the entire DNS lookup operation. optional int32 latency_micros = 3; + + optional android.stats.connectivity.DnsQueryEventRe dns_query_event_re = 4 [(log_mode) = MODE_BYTES]; + + // ResNSend flags defined in android/multinetwork.h + optional int32 flags = 5; + + optional android.net.NetworkCapabilitiesProto.Transport network_type = 6; + + // The DNS over TLS mode on a specific netId. + optional android.stats.connectivity.PrivateDnsModes private_dns_modes = 7; + + // Additional pass-through fields opaque to statsd. + // The DNS resolver Mainline module can add new fields here without requiring an OS update. + optional android.stats.connectivity.DnsCallEvent dns_call_event = 8 [(log_mode) = MODE_BYTES]; } + /** * Logs when a data stall event occurs. * @@ -5742,6 +5818,9 @@ message TrainInfo { INSTALLER_ROLLBACK_CANCEL_STAGED_DELETE_SESSION_INITIATED = 18; INSTALLER_ROLLBACK_CANCEL_STAGED_DELETE_SESSION_SUCCESS = 19; INSTALLER_ROLLBACK_CANCEL_STAGED_DELETE_SESSION_FAILURE = 20; + INSTALL_STAGED_CANCEL_REQUESTED = 21; + INSTALL_STAGED_CANCEL_SUCCESS = 22; + INSTALL_STAGED_CANCEL_FAILURE = 23; } optional Status status = 4; } diff --git a/cmds/statsd/src/guardrail/StatsdStats.cpp b/cmds/statsd/src/guardrail/StatsdStats.cpp index 29100aad81aa..74a4c87af7c3 100644 --- a/cmds/statsd/src/guardrail/StatsdStats.cpp +++ b/cmds/statsd/src/guardrail/StatsdStats.cpp @@ -50,6 +50,7 @@ const int FIELD_ID_ANOMALY_ALARM_STATS = 9; const int FIELD_ID_PERIODIC_ALARM_STATS = 12; const int FIELD_ID_SYSTEM_SERVER_RESTART = 15; const int FIELD_ID_LOGGER_ERROR_STATS = 16; +const int FIELD_ID_OVERFLOW = 18; const int FIELD_ID_ATOM_STATS_TAG = 1; const int FIELD_ID_ATOM_STATS_COUNT = 2; @@ -64,6 +65,10 @@ const int FIELD_ID_LOG_LOSS_STATS_TAG = 4; const int FIELD_ID_LOG_LOSS_STATS_UID = 5; const int FIELD_ID_LOG_LOSS_STATS_PID = 6; +const int FIELD_ID_OVERFLOW_COUNT = 1; +const int FIELD_ID_OVERFLOW_MAX_HISTORY = 2; +const int FIELD_ID_OVERFLOW_MIN_HISTORY = 3; + const int FIELD_ID_CONFIG_STATS_UID = 1; const int FIELD_ID_CONFIG_STATS_ID = 2; const int FIELD_ID_CONFIG_STATS_CREATION = 3; @@ -235,6 +240,22 @@ void StatsdStats::noteDataDropped(const ConfigKey& key, const size_t totalBytes) noteDataDropped(key, totalBytes, getWallClockSec()); } +void StatsdStats::noteEventQueueOverflow(int64_t oldestEventTimestampNs) { + lock_guard<std::mutex> lock(mLock); + + mOverflowCount++; + + int64_t history = getElapsedRealtimeNs() - oldestEventTimestampNs; + + if (history > mMaxQueueHistoryNs) { + mMaxQueueHistoryNs = history; + } + + if (history < mMinQueueHistoryNs) { + mMinQueueHistoryNs = history; + } +} + void StatsdStats::noteDataDropped(const ConfigKey& key, const size_t totalBytes, int32_t timeSec) { lock_guard<std::mutex> lock(mLock); auto it = mConfigStats.find(key); @@ -534,6 +555,9 @@ void StatsdStats::resetInternalLocked() { mPeriodicAlarmRegisteredStats = 0; mSystemServerRestartSec.clear(); mLogLossStats.clear(); + mOverflowCount = 0; + mMinQueueHistoryNs = kInt64Max; + mMaxQueueHistoryNs = 0; for (auto& config : mConfigStats) { config.second->broadcast_sent_time_sec.clear(); config.second->activation_time_sec.clear(); @@ -726,6 +750,9 @@ void StatsdStats::dumpStats(int out) const { (long long)loss.mWallClockSec, loss.mCount, loss.mLastError, loss.mLastTag, loss.mUid, loss.mPid); } + + dprintf(out, "Event queue overflow: %d; MaxHistoryNs: %lld; MinHistoryNs: %lld\n", + mOverflowCount, (long long)mMaxQueueHistoryNs, (long long)mMinQueueHistoryNs); } void addConfigStatsToProto(const ConfigStats& configStats, ProtoOutputStream* proto) { @@ -904,6 +931,16 @@ void StatsdStats::dumpStats(std::vector<uint8_t>* output, bool reset) { proto.end(token); } + if (mOverflowCount > 0) { + uint64_t token = proto.start(FIELD_TYPE_MESSAGE | FIELD_ID_OVERFLOW); + proto.write(FIELD_TYPE_INT32 | FIELD_ID_OVERFLOW_COUNT, (int32_t)mOverflowCount); + proto.write(FIELD_TYPE_INT64 | FIELD_ID_OVERFLOW_MAX_HISTORY, + (long long)mMaxQueueHistoryNs); + proto.write(FIELD_TYPE_INT64 | FIELD_ID_OVERFLOW_MIN_HISTORY, + (long long)mMinQueueHistoryNs); + proto.end(token); + } + for (const auto& restart : mSystemServerRestartSec) { proto.write(FIELD_TYPE_INT32 | FIELD_ID_SYSTEM_SERVER_RESTART | FIELD_COUNT_REPEATED, restart); diff --git a/cmds/statsd/src/guardrail/StatsdStats.h b/cmds/statsd/src/guardrail/StatsdStats.h index 434920ebe8c7..88ecccc32407 100644 --- a/cmds/statsd/src/guardrail/StatsdStats.h +++ b/cmds/statsd/src/guardrail/StatsdStats.h @@ -160,6 +160,8 @@ public: // Max platform atom tag number. static const int32_t kMaxPlatformAtomTag = 100000; + static const int64_t kInt64Max = 0x7fffffffffffffffLL; + /** * Report a new config has been received and report the static stats about the config. * @@ -419,6 +421,10 @@ public: */ void noteBucketUnknownCondition(int64_t metricId); + /* Reports one event has been dropped due to queue overflow, and the oldest event timestamp in + * the queue */ + void noteEventQueueOverflow(int64_t oldestEventTimestampNs); + /** * Reset the historical stats. Including all stats in icebox, and the tracked stats about * metrics, matchers, and atoms. The active configs will be kept and StatsdStats will continue @@ -522,6 +528,17 @@ private: int32_t mPid; }; + // Max of {(now - oldestEventTimestamp) when overflow happens}. + // This number is helpful to understand how SLOW statsd can be. + int64_t mMaxQueueHistoryNs = 0; + + // Min of {(now - oldestEventTimestamp) when overflow happens}. + // This number is helpful to understand how FAST the events floods to statsd. + int64_t mMinQueueHistoryNs = kInt64Max; + + // Total number of events that are lost due to queue overflow. + int32_t mOverflowCount = 0; + // Timestamps when we detect log loss, and the number of logs lost. std::list<LogLossStats> mLogLossStats; diff --git a/cmds/statsd/src/logd/LogEvent.cpp b/cmds/statsd/src/logd/LogEvent.cpp index d9f5415463e3..ca874b57170e 100644 --- a/cmds/statsd/src/logd/LogEvent.cpp +++ b/cmds/statsd/src/logd/LogEvent.cpp @@ -27,6 +27,9 @@ namespace android { namespace os { namespace statsd { +// for TrainInfo experiment id serialization +const int FIELD_ID_EXPERIMENT_ID = 1; + using namespace android::util; using android::util::ProtoOutputStream; using std::string; @@ -118,6 +121,7 @@ void LogEvent::createLogEvents(const StatsLogEventWrapper& statsLogEventWrapper, LogEvent::LogEvent(int32_t tagId, int64_t wallClockTimestampNs, int64_t elapsedTimestampNs) { mLogdTimestampNs = wallClockTimestampNs; + mElapsedTimestampNs = elapsedTimestampNs; mTagId = tagId; mLogUid = 0; mContext = create_android_logger(1937006964); // the event tag shared by all stats logs @@ -241,12 +245,15 @@ LogEvent::LogEvent(int64_t wallClockTimestampNs, int64_t elapsedTimestampNs, mValues.push_back( FieldValue(Field(mTagId, getSimpleField(1)), Value(trainInfo.trainVersionCode))); - mValues.push_back(FieldValue(Field(mTagId, getSimpleField(2)), Value(trainInfo.experimentIds))); + std::vector<uint8_t> experimentIdsProto; + writeExperimentIdsToProto(trainInfo.experimentIds, &experimentIdsProto); + mValues.push_back(FieldValue(Field(mTagId, getSimpleField(2)), Value(experimentIdsProto))); mValues.push_back(FieldValue(Field(mTagId, getSimpleField(3)), Value(trainInfo.trainName))); mValues.push_back(FieldValue(Field(mTagId, getSimpleField(4)), Value(trainInfo.status))); } -LogEvent::LogEvent(int32_t tagId, int64_t timestampNs) : LogEvent(tagId, timestampNs, 0) {} +LogEvent::LogEvent(int32_t tagId, int64_t timestampNs) : LogEvent(tagId, timestampNs, timestampNs) { +} LogEvent::LogEvent(int32_t tagId, int64_t timestampNs, int32_t uid) { mLogdTimestampNs = timestampNs; @@ -671,6 +678,24 @@ void LogEvent::ToProto(ProtoOutputStream& protoOutput) const { writeFieldValueTreeToStream(mTagId, getValues(), &protoOutput); } +void writeExperimentIdsToProto(const std::vector<int64_t>& experimentIds, std::vector<uint8_t>* protoOut) { + ProtoOutputStream proto; + for (const auto& expId : experimentIds) { + proto.write(FIELD_TYPE_INT64 | FIELD_COUNT_REPEATED | FIELD_ID_EXPERIMENT_ID, + (long long)expId); + } + + protoOut->resize(proto.size()); + size_t pos = 0; + sp<ProtoReader> reader = proto.data(); + while (reader->readBuffer() != NULL) { + size_t toRead = reader->currentToRead(); + std::memcpy(protoOut->data() + pos, reader->readBuffer(), toRead); + pos += toRead; + reader->move(toRead); + } +} + } // namespace statsd } // namespace os } // namespace android diff --git a/cmds/statsd/src/logd/LogEvent.h b/cmds/statsd/src/logd/LogEvent.h index 753a9a500c57..531ce299beef 100644 --- a/cmds/statsd/src/logd/LogEvent.h +++ b/cmds/statsd/src/logd/LogEvent.h @@ -60,8 +60,9 @@ struct InstallTrainInfo { int64_t trainVersionCode; std::string trainName; int32_t status; - std::vector<uint8_t> experimentIds; + std::vector<int64_t> experimentIds; }; + /** * Wrapper for the log_msg structure. */ @@ -239,6 +240,8 @@ private: uint32_t mLogUid; }; +void writeExperimentIdsToProto(const std::vector<int64_t>& experimentIds, std::vector<uint8_t>* protoOut); + } // namespace statsd } // namespace os } // namespace android diff --git a/cmds/statsd/src/logd/LogEventQueue.cpp b/cmds/statsd/src/logd/LogEventQueue.cpp new file mode 100644 index 000000000000..146464bbe774 --- /dev/null +++ b/cmds/statsd/src/logd/LogEventQueue.cpp @@ -0,0 +1,62 @@ +/* + * 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. + */ + +#define DEBUG false // STOPSHIP if true +#include "Log.h" + +#include "LogEventQueue.h" + +namespace android { +namespace os { +namespace statsd { + +using std::unique_lock; +using std::unique_ptr; + +unique_ptr<LogEvent> LogEventQueue::waitPop() { + std::unique_lock<std::mutex> lock(mMutex); + + if (mQueue.empty()) { + mCondition.wait(lock, [this] { return !this->mQueue.empty(); }); + } + + unique_ptr<LogEvent> item = std::move(mQueue.front()); + mQueue.pop(); + + return item; +} + +bool LogEventQueue::push(unique_ptr<LogEvent> item, int64_t* oldestTimestampNs) { + bool success; + { + std::unique_lock<std::mutex> lock(mMutex); + if (mQueue.size() < mQueueLimit) { + mQueue.push(std::move(item)); + success = true; + } else { + // safe operation as queue must not be empty. + *oldestTimestampNs = mQueue.front()->GetElapsedTimestampNs(); + success = false; + } + } + + mCondition.notify_one(); + return success; +} + +} // namespace statsd +} // namespace os +} // namespace android diff --git a/cmds/statsd/src/logd/LogEventQueue.h b/cmds/statsd/src/logd/LogEventQueue.h new file mode 100644 index 000000000000..b4fd63f119e6 --- /dev/null +++ b/cmds/statsd/src/logd/LogEventQueue.h @@ -0,0 +1,59 @@ +/* + * 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. + */ + +#pragma once + +#include "LogEvent.h" + +#include <condition_variable> +#include <memory> +#include <mutex> +#include <queue> +#include <thread> + +namespace android { +namespace os { +namespace statsd { + +/** + * A zero copy thread safe queue buffer for producing and consuming LogEvent. + */ +class LogEventQueue { +public: + explicit LogEventQueue(size_t maxSize) : mQueueLimit(maxSize){}; + + /** + * Blocking read one event from the queue. + */ + std::unique_ptr<LogEvent> waitPop(); + + /** + * Puts a LogEvent ptr to the end of the queue. + * Returns false on failure when the queue is full, and output the oldest event timestamp + * in the queue. + */ + bool push(std::unique_ptr<LogEvent> event, int64_t* oldestTimestampNs); + +private: + const size_t mQueueLimit; + std::condition_variable mCondition; + std::mutex mMutex; + std::queue<std::unique_ptr<LogEvent>> mQueue; +}; + +} // namespace statsd +} // namespace os +} // namespace android diff --git a/cmds/statsd/src/main.cpp b/cmds/statsd/src/main.cpp index eddc86eca798..68082c2dc4d2 100644 --- a/cmds/statsd/src/main.cpp +++ b/cmds/statsd/src/main.cpp @@ -80,8 +80,11 @@ int main(int /*argc*/, char** /*argv*/) { ::android::hardware::configureRpcThreadpool(1 /*threads*/, false /*willJoin*/); + std::shared_ptr<LogEventQueue> eventQueue = + std::make_shared<LogEventQueue>(2000 /*buffer limit. Buffer is NOT pre-allocated*/); + // Create the service - gStatsService = new StatsService(looper); + gStatsService = new StatsService(looper, eventQueue); if (defaultServiceManager()->addService(String16("stats"), gStatsService, false, IServiceManager::DUMP_FLAG_PRIORITY_NORMAL | IServiceManager::DUMP_FLAG_PROTO) != 0) { @@ -101,13 +104,13 @@ int main(int /*argc*/, char** /*argv*/) { gStatsService->Startup(); - sp<StatsSocketListener> socketListener = new StatsSocketListener(gStatsService); + sp<StatsSocketListener> socketListener = new StatsSocketListener(eventQueue); - ALOGI("using statsd socket"); - // Backlog and /proc/sys/net/unix/max_dgram_qlen set to large value - if (socketListener->startListener(600)) { - exit(1); - } + ALOGI("Statsd starts to listen to socket."); + // Backlog and /proc/sys/net/unix/max_dgram_qlen set to large value + if (socketListener->startListener(600)) { + exit(1); + } // Loop forever -- the reports run on this thread in a handler, and the // binder calls remain responsive in their pool of one thread. diff --git a/cmds/statsd/src/socket/StatsSocketListener.cpp b/cmds/statsd/src/socket/StatsSocketListener.cpp index aed926d74b26..92200f99c3cc 100755 --- a/cmds/statsd/src/socket/StatsSocketListener.cpp +++ b/cmds/statsd/src/socket/StatsSocketListener.cpp @@ -41,8 +41,8 @@ namespace statsd { static const int kLogMsgHeaderSize = 28; -StatsSocketListener::StatsSocketListener(const sp<LogListener>& listener) - : SocketListener(getLogSocket(), false /*start listen*/), mListener(listener) { +StatsSocketListener::StatsSocketListener(std::shared_ptr<LogEventQueue> queue) + : SocketListener(getLogSocket(), false /*start listen*/), mQueue(queue) { } StatsSocketListener::~StatsSocketListener() { @@ -134,10 +134,11 @@ bool StatsSocketListener::onDataAvailable(SocketClient* cli) { msg.entry.uid = cred->uid; memcpy(msg.buf + kLogMsgHeaderSize, ptr, n + 1); - LogEvent event(msg); - // Call the listener - mListener->OnLogEvent(&event); + int64_t oldestTimestamp; + if (!mQueue->push(std::make_unique<LogEvent>(msg), &oldestTimestamp)) { + StatsdStats::getInstance().noteEventQueueOverflow(oldestTimestamp); + } return true; } diff --git a/cmds/statsd/src/socket/StatsSocketListener.h b/cmds/statsd/src/socket/StatsSocketListener.h index b8185d2a32d2..2167a56445b9 100644 --- a/cmds/statsd/src/socket/StatsSocketListener.h +++ b/cmds/statsd/src/socket/StatsSocketListener.h @@ -17,7 +17,7 @@ #include <sysutils/SocketListener.h> #include <utils/RefBase.h> -#include "logd/LogListener.h" +#include "logd/LogEventQueue.h" // DEFAULT_OVERFLOWUID is defined in linux/highuid.h, which is not part of // the uapi headers for userspace to use. This value is filled in on the @@ -35,7 +35,7 @@ namespace statsd { class StatsSocketListener : public SocketListener, public virtual android::RefBase { public: - explicit StatsSocketListener(const sp<LogListener>& listener); + explicit StatsSocketListener(std::shared_ptr<LogEventQueue> queue); virtual ~StatsSocketListener(); @@ -47,7 +47,7 @@ private: /** * Who is going to get the events when they're read. */ - sp<LogListener> mListener; + std::shared_ptr<LogEventQueue> mQueue; }; } // namespace statsd } // namespace os diff --git a/cmds/statsd/src/stats_log.proto b/cmds/statsd/src/stats_log.proto index 967c352562f7..1dfc433cf0e2 100644 --- a/cmds/statsd/src/stats_log.proto +++ b/cmds/statsd/src/stats_log.proto @@ -460,6 +460,14 @@ message StatsdStatsReport { optional int32 pid = 6; } repeated LogLossStats detected_log_loss = 16; + + message EventQueueOverflow { + optional int32 count = 1; + optional int64 max_queue_history_ns = 2; + optional int64 min_queue_history_ns = 3; + } + + optional EventQueueOverflow queue_overflow = 18; } message AlertTriggerDetails { diff --git a/cmds/statsd/src/storage/StorageManager.cpp b/cmds/statsd/src/storage/StorageManager.cpp index 65b183c6fc96..cf8b97494a06 100644 --- a/cmds/statsd/src/storage/StorageManager.cpp +++ b/cmds/statsd/src/storage/StorageManager.cpp @@ -36,9 +36,17 @@ using android::util::FIELD_COUNT_REPEATED; using android::util::FIELD_TYPE_MESSAGE; using std::map; +/** + * NOTE: these directories are protected by SELinux, any changes here must also update + * the SELinux policies. + */ #define STATS_DATA_DIR "/data/misc/stats-data" #define STATS_SERVICE_DIR "/data/misc/stats-service" #define TRAIN_INFO_DIR "/data/misc/train-info" +#define TRAIN_INFO_PATH "/data/misc/train-info/train-info.bin" + +// Magic word at the start of the train info file, change this if changing the file format +const uint32_t TRAIN_INFO_FILE_MAGIC = 0xff7447ff; // for ConfigMetricsReportList const int FIELD_ID_REPORTS = 2; @@ -96,27 +104,42 @@ void StorageManager::writeFile(const char* file, const void* buffer, int numByte } bool StorageManager::writeTrainInfo(int64_t trainVersionCode, const std::string& trainName, - int32_t status, const std::vector<uint8_t>& experimentIds) { + int32_t status, const std::vector<int64_t>& experimentIds) { std::lock_guard<std::mutex> lock(sTrainInfoMutex); deleteAllFiles(TRAIN_INFO_DIR); - string file_name = StringPrintf("%s/%lld", TRAIN_INFO_DIR, (long long)trainVersionCode); - - int fd = open(file_name.c_str(), O_WRONLY | O_CREAT | O_CLOEXEC, S_IRUSR | S_IWUSR); + int fd = open(TRAIN_INFO_PATH, O_WRONLY | O_CREAT | O_CLOEXEC, S_IRUSR | S_IWUSR); if (fd == -1) { - VLOG("Attempt to access %s but failed", file_name.c_str()); + VLOG("Attempt to access %s but failed", TRAIN_INFO_PATH); return false; } size_t result; + // Write the magic word + result = write(fd, &TRAIN_INFO_FILE_MAGIC, sizeof(TRAIN_INFO_FILE_MAGIC)); + if (result != sizeof(TRAIN_INFO_FILE_MAGIC)) { + VLOG("Failed to wrtie train info magic"); + close(fd); + return false; + } + + // Write the train version + const size_t trainVersionCodeByteCount = sizeof(trainVersionCode); + result = write(fd, &trainVersionCode, trainVersionCodeByteCount); + if (result != trainVersionCodeByteCount) { + VLOG("Failed to wrtie train version code"); + close(fd); + return false; + } + // Write # of bytes in trainName to file const size_t trainNameSize = trainName.size(); const size_t trainNameSizeByteCount = sizeof(trainNameSize); result = write(fd, (uint8_t*)&trainNameSize, trainNameSizeByteCount); if (result != trainNameSizeByteCount) { - VLOG("Failed to write train name size for %s", file_name.c_str()); + VLOG("Failed to write train name size"); close(fd); return false; } @@ -124,7 +147,7 @@ bool StorageManager::writeTrainInfo(int64_t trainVersionCode, const std::string& // Write trainName to file result = write(fd, trainName.c_str(), trainNameSize); if (result != trainNameSize) { - VLOG("Failed to write train name for%s", file_name.c_str()); + VLOG("Failed to write train name"); close(fd); return false; } @@ -133,34 +156,38 @@ bool StorageManager::writeTrainInfo(int64_t trainVersionCode, const std::string& const size_t statusByteCount = sizeof(status); result = write(fd, (uint8_t*)&status, statusByteCount); if (result != statusByteCount) { - VLOG("Failed to write status for %s", file_name.c_str()); + VLOG("Failed to write status"); close(fd); return false; } - // Write experiment id size to file. - const size_t experimentIdSize = experimentIds.size(); - const size_t experimentIdsSizeByteCount = sizeof(experimentIdSize); - result = write(fd, (uint8_t*) &experimentIdSize, experimentIdsSizeByteCount); - if (result != experimentIdsSizeByteCount) { - VLOG("Failed to write experiment id size for %s", file_name.c_str()); + // Write experiment id count to file. + const size_t experimentIdsCount = experimentIds.size(); + const size_t experimentIdsCountByteCount = sizeof(experimentIdsCount); + result = write(fd, (uint8_t*) &experimentIdsCount, experimentIdsCountByteCount); + if (result != experimentIdsCountByteCount) { + VLOG("Failed to write experiment id count"); close(fd); return false; } // Write experimentIds to file - result = write(fd, experimentIds.data(), experimentIds.size()); - if (result == experimentIds.size()) { - VLOG("Successfully wrote %s", file_name.c_str()); - } else { - VLOG("Failed to write experiment ids for %s", file_name.c_str()); - close(fd); - return false; + for (size_t i = 0; i < experimentIdsCount; i++) { + const int64_t experimentId = experimentIds[i]; + const size_t experimentIdByteCount = sizeof(experimentId); + result = write(fd, &experimentId, experimentIdByteCount); + if (result == experimentIdByteCount) { + VLOG("Successfully wrote experiment IDs"); + } else { + VLOG("Failed to write experiment ids"); + close(fd); + return false; + } } result = fchown(fd, AID_STATSD, AID_STATSD); if (result) { - VLOG("Failed to chown %s to statsd", file_name.c_str()); + VLOG("Failed to chown train info file to statsd"); close(fd); return false; } @@ -172,88 +199,96 @@ bool StorageManager::writeTrainInfo(int64_t trainVersionCode, const std::string& bool StorageManager::readTrainInfo(InstallTrainInfo& trainInfo) { std::lock_guard<std::mutex> lock(sTrainInfoMutex); - unique_ptr<DIR, decltype(&closedir)> dir(opendir(TRAIN_INFO_DIR), closedir); - - if (dir == NULL) { - VLOG("Directory does not exist: %s", TRAIN_INFO_DIR); + int fd = open(TRAIN_INFO_PATH, O_RDONLY | O_CLOEXEC); + if (fd == -1) { + VLOG("Failed to open train-info.bin"); return false; } - dirent* de; - while ((de = readdir(dir.get()))) { - char* name = de->d_name; - if (name[0] == '.') { - continue; - } - - size_t result; + // Read the magic word + uint32_t magic; + size_t result = read(fd, &magic, sizeof(magic)); + if (result != sizeof(magic)) { + VLOG("Failed to read train info magic"); + close(fd); + return false; + } - trainInfo.trainVersionCode = StrToInt64(name); - string fullPath = StringPrintf("%s/%s", TRAIN_INFO_DIR, name); - int fd = open(fullPath.c_str(), O_RDONLY | O_CLOEXEC); - if (fd == -1) { - return false; - } + if (magic != TRAIN_INFO_FILE_MAGIC) { + VLOG("Train info magic was 0x%08x, expected 0x%08x", magic, TRAIN_INFO_FILE_MAGIC); + close(fd); + return false; + } - // Read # of bytes taken by trainName in the file. - size_t trainNameSize; - result = read(fd, &trainNameSize, sizeof(size_t)); - if (result != sizeof(size_t)) { - VLOG("Failed to read train name size from file %s", fullPath.c_str()); - close(fd); - return false; - } + // Read the train version code + const size_t trainVersionCodeByteCount(sizeof(trainInfo.trainVersionCode)); + result = read(fd, &trainInfo.trainVersionCode, trainVersionCodeByteCount); + if (result != trainVersionCodeByteCount) { + VLOG("Failed to read train version code from train info file"); + close(fd); + return false; + } - // Read trainName - trainInfo.trainName.resize(trainNameSize); - result = read(fd, trainInfo.trainName.data(), trainNameSize); - if (result != trainNameSize) { - VLOG("Failed to read train name from file %s", fullPath.c_str()); - close(fd); - return false; - } + // Read # of bytes taken by trainName in the file. + size_t trainNameSize; + result = read(fd, &trainNameSize, sizeof(size_t)); + if (result != sizeof(size_t)) { + VLOG("Failed to read train name size from train info file"); + close(fd); + return false; + } - // Read status - const size_t statusByteCount = sizeof(trainInfo.status); - result = read(fd, &trainInfo.status, statusByteCount); - if (result != statusByteCount) { - VLOG("Failed to read train status from file %s", fullPath.c_str()); - close(fd); - return false; - } + // Read trainName + trainInfo.trainName.resize(trainNameSize); + result = read(fd, trainInfo.trainName.data(), trainNameSize); + if (result != trainNameSize) { + VLOG("Failed to read train name from train info file"); + close(fd); + return false; + } - // Read experiment ids size. - size_t experimentIdSize; - result = read(fd, &experimentIdSize, sizeof(size_t)); - if (result != sizeof(size_t)) { - VLOG("Failed to read train experiment id size from file %s", fullPath.c_str()); - close(fd); - return false; - } + // Read status + const size_t statusByteCount = sizeof(trainInfo.status); + result = read(fd, &trainInfo.status, statusByteCount); + if (result != statusByteCount) { + VLOG("Failed to read train status from train info file"); + close(fd); + return false; + } - // Read experimentIds - trainInfo.experimentIds.resize(experimentIdSize); - result = read(fd, trainInfo.experimentIds.data(), experimentIdSize); - if (result != experimentIdSize) { - VLOG("Failed to read train experiment ids from file %s", fullPath.c_str()); - close(fd); - return false; - } + // Read experiment ids count. + size_t experimentIdsCount; + result = read(fd, &experimentIdsCount, sizeof(size_t)); + if (result != sizeof(size_t)) { + VLOG("Failed to read train experiment id count from train info file"); + close(fd); + return false; + } - // Expect to be at EOF. - char c; - result = read(fd, &c, 1); - if (result != 0) { - VLOG("Failed to read train info from file %s. Did not get expected EOF.", fullPath.c_str()); + // Read experimentIds + for (size_t i = 0; i < experimentIdsCount; i++) { + int64_t experimentId; + result = read(fd, &experimentId, sizeof(experimentId)); + if (result != sizeof(experimentId)) { + VLOG("Failed to read train experiment id from train info file"); close(fd); return false; } + trainInfo.experimentIds.push_back(experimentId); + } - VLOG("Read train info file successful: %s", fullPath.c_str()); + // Expect to be at EOF. + char c; + result = read(fd, &c, 1); + if (result != 0) { + VLOG("Failed to read train info from file. Did not get expected EOF."); close(fd); - return true; + return false; } - return false; + + VLOG("Read train info file successful"); + close(fd); + return true; } void StorageManager::deleteFile(const char* file) { diff --git a/cmds/statsd/src/storage/StorageManager.h b/cmds/statsd/src/storage/StorageManager.h index 88280cf218b3..dfcea65b0872 100644 --- a/cmds/statsd/src/storage/StorageManager.h +++ b/cmds/statsd/src/storage/StorageManager.h @@ -29,11 +29,6 @@ namespace statsd { using android::util::ProtoOutputStream; -struct TrainInfo { - int64_t trainVersionCode; - std::vector<uint8_t> experimentIds; -}; - class StorageManager : public virtual RefBase { public: /** @@ -45,7 +40,7 @@ public: * Writes train info. */ static bool writeTrainInfo(int64_t trainVersionCode, const std::string& trainName, - int32_t status, const std::vector<uint8_t>& experimentIds); + int32_t status, const std::vector<int64_t>& experimentIds); /** * Reads train info. diff --git a/cmds/statsd/tests/LogEvent_test.cpp b/cmds/statsd/tests/LogEvent_test.cpp index b03517e607b3..504ee22f72e4 100644 --- a/cmds/statsd/tests/LogEvent_test.cpp +++ b/cmds/statsd/tests/LogEvent_test.cpp @@ -645,6 +645,22 @@ TEST(LogEventTest, TestBinaryFieldAtom_empty) { EXPECT_EQ(orig_str, result_str); } +TEST(LogEventTest, TestWriteExperimentIdsToProto) { + std::vector<int64_t> expIds; + expIds.push_back(5038); + std::vector<uint8_t> proto; + + writeExperimentIdsToProto(expIds, &proto); + + EXPECT_EQ(proto.size(), 3); + // Proto wire format for field ID 1, varint + EXPECT_EQ(proto[0], 0x08); + // varint of 5038, 2 bytes long + EXPECT_EQ(proto[1], 0xae); + EXPECT_EQ(proto[2], 0x27); +} + + } // namespace statsd } // namespace os } // namespace android diff --git a/cmds/statsd/tests/StatsService_test.cpp b/cmds/statsd/tests/StatsService_test.cpp index 560fb9f02174..7c00531d560b 100644 --- a/cmds/statsd/tests/StatsService_test.cpp +++ b/cmds/statsd/tests/StatsService_test.cpp @@ -33,7 +33,7 @@ using android::util::ProtoOutputStream; #ifdef __ANDROID__ TEST(StatsServiceTest, TestAddConfig_simple) { - StatsService service(nullptr); + StatsService service(nullptr, nullptr); StatsdConfig config; config.set_id(12345); string serialized = config.SerializeAsString(); @@ -43,7 +43,7 @@ TEST(StatsServiceTest, TestAddConfig_simple) { } TEST(StatsServiceTest, TestAddConfig_empty) { - StatsService service(nullptr); + StatsService service(nullptr, nullptr); string serialized = ""; EXPECT_TRUE( @@ -51,7 +51,7 @@ TEST(StatsServiceTest, TestAddConfig_empty) { } TEST(StatsServiceTest, TestAddConfig_invalid) { - StatsService service(nullptr); + StatsService service(nullptr, nullptr); string serialized = "Invalid config!"; EXPECT_FALSE( @@ -69,7 +69,7 @@ TEST(StatsServiceTest, TestGetUidFromArgs) { int32_t uid; - StatsService service(nullptr); + StatsService service(nullptr, nullptr); service.mEngBuild = true; // "-1" diff --git a/cmds/statsd/tests/e2e/PartialBucket_e2e_test.cpp b/cmds/statsd/tests/e2e/PartialBucket_e2e_test.cpp index 3dff7f5d1320..309d251e4a89 100644 --- a/cmds/statsd/tests/e2e/PartialBucket_e2e_test.cpp +++ b/cmds/statsd/tests/e2e/PartialBucket_e2e_test.cpp @@ -111,7 +111,7 @@ StatsdConfig MakeGaugeMetricConfig(int64_t minTime) { } TEST(PartialBucketE2eTest, TestCountMetricWithoutSplit) { - StatsService service(nullptr); + StatsService service(nullptr, nullptr); SendConfig(service, MakeConfig()); int64_t start = getElapsedRealtimeNs(); // This is the start-time the metrics producers are // initialized with. @@ -126,7 +126,7 @@ TEST(PartialBucketE2eTest, TestCountMetricWithoutSplit) { } TEST(PartialBucketE2eTest, TestCountMetricNoSplitOnNewApp) { - StatsService service(nullptr); + StatsService service(nullptr, nullptr); SendConfig(service, MakeConfig()); int64_t start = getElapsedRealtimeNs(); // This is the start-time the metrics producers are // initialized with. @@ -146,7 +146,7 @@ TEST(PartialBucketE2eTest, TestCountMetricNoSplitOnNewApp) { } TEST(PartialBucketE2eTest, TestCountMetricSplitOnUpgrade) { - StatsService service(nullptr); + StatsService service(nullptr, nullptr); SendConfig(service, MakeConfig()); int64_t start = getElapsedRealtimeNs(); // This is the start-time the metrics producers are // initialized with. @@ -171,7 +171,7 @@ TEST(PartialBucketE2eTest, TestCountMetricSplitOnUpgrade) { } TEST(PartialBucketE2eTest, TestCountMetricSplitOnRemoval) { - StatsService service(nullptr); + StatsService service(nullptr, nullptr); SendConfig(service, MakeConfig()); int64_t start = getElapsedRealtimeNs(); // This is the start-time the metrics producers are // initialized with. @@ -195,7 +195,7 @@ TEST(PartialBucketE2eTest, TestCountMetricSplitOnRemoval) { } TEST(PartialBucketE2eTest, TestValueMetricWithoutMinPartialBucket) { - StatsService service(nullptr); + StatsService service(nullptr, nullptr); // Partial buckets don't occur when app is first installed. service.mUidMap->updateApp(1, String16(kApp1.c_str()), 1, 1, String16("v1"), String16("")); SendConfig(service, MakeValueMetricConfig(0)); @@ -213,7 +213,7 @@ TEST(PartialBucketE2eTest, TestValueMetricWithoutMinPartialBucket) { } TEST(PartialBucketE2eTest, TestValueMetricWithMinPartialBucket) { - StatsService service(nullptr); + StatsService service(nullptr, nullptr); // Partial buckets don't occur when app is first installed. service.mUidMap->updateApp(1, String16(kApp1.c_str()), 1, 1, String16("v1"), String16("")); SendConfig(service, MakeValueMetricConfig(60 * NS_PER_SEC /* One minute */)); @@ -237,7 +237,7 @@ TEST(PartialBucketE2eTest, TestValueMetricWithMinPartialBucket) { } TEST(PartialBucketE2eTest, TestGaugeMetricWithoutMinPartialBucket) { - StatsService service(nullptr); + StatsService service(nullptr, nullptr); // Partial buckets don't occur when app is first installed. service.mUidMap->updateApp(1, String16(kApp1.c_str()), 1, 1, String16("v1"), String16("")); SendConfig(service, MakeGaugeMetricConfig(0)); @@ -255,7 +255,7 @@ TEST(PartialBucketE2eTest, TestGaugeMetricWithoutMinPartialBucket) { } TEST(PartialBucketE2eTest, TestGaugeMetricWithMinPartialBucket) { - StatsService service(nullptr); + StatsService service(nullptr, nullptr); // Partial buckets don't occur when app is first installed. service.mUidMap->updateApp(1, String16(kApp1.c_str()), 1, 1, String16("v1"), String16("")); SendConfig(service, MakeGaugeMetricConfig(60 * NS_PER_SEC /* One minute */)); diff --git a/cmds/statsd/tests/log_event/LogEventQueue_test.cpp b/cmds/statsd/tests/log_event/LogEventQueue_test.cpp new file mode 100644 index 000000000000..f27d12957f11 --- /dev/null +++ b/cmds/statsd/tests/log_event/LogEventQueue_test.cpp @@ -0,0 +1,100 @@ +// 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. + +#include "logd/LogEventQueue.h" + +#include <gmock/gmock.h> +#include <gtest/gtest.h> +#include <thread> + +#include <stdio.h> + +namespace android { +namespace os { +namespace statsd { + +using namespace android; +using namespace testing; + +using std::unique_ptr; + +#ifdef __ANDROID__ +TEST(LogEventQueue_test, TestGoodConsumer) { + LogEventQueue queue(50); + int64_t timeBaseNs = 100; + std::thread writer([&queue, timeBaseNs] { + for (int i = 0; i < 100; i++) { + int64_t oldestEventNs; + bool success = queue.push(std::make_unique<LogEvent>(10, timeBaseNs + i * 1000), + &oldestEventNs); + EXPECT_TRUE(success); + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + } + }); + + std::thread reader([&queue, timeBaseNs] { + for (int i = 0; i < 100; i++) { + auto event = queue.waitPop(); + EXPECT_TRUE(event != nullptr); + // All events are in right order. + EXPECT_EQ(timeBaseNs + i * 1000, event->GetElapsedTimestampNs()); + } + }); + + reader.join(); + writer.join(); +} + +TEST(LogEventQueue_test, TestSlowConsumer) { + LogEventQueue queue(50); + int64_t timeBaseNs = 100; + std::thread writer([&queue, timeBaseNs] { + int failure_count = 0; + int64_t oldestEventNs; + for (int i = 0; i < 100; i++) { + bool success = queue.push(std::make_unique<LogEvent>(10, timeBaseNs + i * 1000), + &oldestEventNs); + if (!success) failure_count++; + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + } + + // There is some remote chance that reader thread not get chance to run before writer thread + // ends. That's why the following comparison is not "==". + // There will be at least 45 events lost due to overflow. + EXPECT_TRUE(failure_count >= 45); + // The oldest event must be at least the 6th event. + EXPECT_TRUE(oldestEventNs <= (100 + 5 * 1000)); + }); + + std::thread reader([&queue, timeBaseNs] { + // The consumer quickly processed 5 events, then it got stuck (not reading anymore). + for (int i = 0; i < 5; i++) { + auto event = queue.waitPop(); + EXPECT_TRUE(event != nullptr); + // All events are in right order. + EXPECT_EQ(timeBaseNs + i * 1000, event->GetElapsedTimestampNs()); + } + }); + + reader.join(); + writer.join(); +} + +#else +GTEST_LOG_(INFO) << "This test does nothing.\n"; +#endif + +} // namespace statsd +} // namespace os +} // namespace android diff --git a/config/hiddenapi-greylist-packages.txt b/config/hiddenapi-greylist-packages.txt new file mode 100644 index 000000000000..cae3bd94bc67 --- /dev/null +++ b/config/hiddenapi-greylist-packages.txt @@ -0,0 +1,2 @@ +org.ccil.cowan.tagsoup +org.ccil.cowan.tagsoup.jaxp diff --git a/config/hiddenapi-greylist.txt b/config/hiddenapi-greylist.txt index 95bdc364998f..c267e779983a 100644 --- a/config/hiddenapi-greylist.txt +++ b/config/hiddenapi-greylist.txt @@ -2488,108 +2488,3 @@ Lorg/apache/xpath/XPathContext;->setCurrentExpressionNodeStack(Lorg/apache/xml/u Lorg/apache/xpath/XPathContext;->setCurrentNodeStack(Lorg/apache/xml/utils/IntStack;)V Lorg/apache/xpath/XPathContext;->setSecureProcessing(Z)V Lorg/apache/xpath/XPathContext;->setVarStack(Lorg/apache/xpath/VariableStack;)V -Lorg/ccil/cowan/tagsoup/AttributesImpl;-><init>(Lorg/xml/sax/Attributes;)V -Lorg/ccil/cowan/tagsoup/AttributesImpl;->addAttribute(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V -Lorg/ccil/cowan/tagsoup/AttributesImpl;->data:[Ljava/lang/String; -Lorg/ccil/cowan/tagsoup/AttributesImpl;->length:I -Lorg/ccil/cowan/tagsoup/AttributesImpl;->setAttribute(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V -Lorg/ccil/cowan/tagsoup/AttributesImpl;->setValue(ILjava/lang/String;)V -Lorg/ccil/cowan/tagsoup/AutoDetector;->autoDetectingReader(Ljava/io/InputStream;)Ljava/io/Reader; -Lorg/ccil/cowan/tagsoup/Element;-><init>(Lorg/ccil/cowan/tagsoup/ElementType;Z)V -Lorg/ccil/cowan/tagsoup/Element;->anonymize()V -Lorg/ccil/cowan/tagsoup/Element;->atts()Lorg/ccil/cowan/tagsoup/AttributesImpl; -Lorg/ccil/cowan/tagsoup/Element;->canContain(Lorg/ccil/cowan/tagsoup/Element;)Z -Lorg/ccil/cowan/tagsoup/Element;->clean()V -Lorg/ccil/cowan/tagsoup/Element;->flags()I -Lorg/ccil/cowan/tagsoup/Element;->localName()Ljava/lang/String; -Lorg/ccil/cowan/tagsoup/Element;->name()Ljava/lang/String; -Lorg/ccil/cowan/tagsoup/Element;->namespace()Ljava/lang/String; -Lorg/ccil/cowan/tagsoup/Element;->next()Lorg/ccil/cowan/tagsoup/Element; -Lorg/ccil/cowan/tagsoup/Element;->parent()Lorg/ccil/cowan/tagsoup/ElementType; -Lorg/ccil/cowan/tagsoup/Element;->preclosed:Z -Lorg/ccil/cowan/tagsoup/Element;->setAttribute(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V -Lorg/ccil/cowan/tagsoup/Element;->setNext(Lorg/ccil/cowan/tagsoup/Element;)V -Lorg/ccil/cowan/tagsoup/Element;->theAtts:Lorg/ccil/cowan/tagsoup/AttributesImpl; -Lorg/ccil/cowan/tagsoup/Element;->theNext:Lorg/ccil/cowan/tagsoup/Element; -Lorg/ccil/cowan/tagsoup/Element;->theType:Lorg/ccil/cowan/tagsoup/ElementType; -Lorg/ccil/cowan/tagsoup/ElementType;-><init>(Ljava/lang/String;IIILorg/ccil/cowan/tagsoup/Schema;)V -Lorg/ccil/cowan/tagsoup/ElementType;->atts()Lorg/ccil/cowan/tagsoup/AttributesImpl; -Lorg/ccil/cowan/tagsoup/ElementType;->setAttribute(Lorg/ccil/cowan/tagsoup/AttributesImpl;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V -Lorg/ccil/cowan/tagsoup/ElementType;->theAtts:Lorg/ccil/cowan/tagsoup/AttributesImpl; -Lorg/ccil/cowan/tagsoup/ElementType;->theFlags:I -Lorg/ccil/cowan/tagsoup/ElementType;->theLocalName:Ljava/lang/String; -Lorg/ccil/cowan/tagsoup/ElementType;->theMemberOf:I -Lorg/ccil/cowan/tagsoup/ElementType;->theModel:I -Lorg/ccil/cowan/tagsoup/ElementType;->theName:Ljava/lang/String; -Lorg/ccil/cowan/tagsoup/ElementType;->theNamespace:Ljava/lang/String; -Lorg/ccil/cowan/tagsoup/ElementType;->theParent:Lorg/ccil/cowan/tagsoup/ElementType; -Lorg/ccil/cowan/tagsoup/ElementType;->theSchema:Lorg/ccil/cowan/tagsoup/Schema; -Lorg/ccil/cowan/tagsoup/HTMLScanner;-><init>()V -Lorg/ccil/cowan/tagsoup/HTMLSchema;-><init>()V -Lorg/ccil/cowan/tagsoup/jaxp/SAXFactoryImpl;-><init>()V -Lorg/ccil/cowan/tagsoup/jaxp/SAXParserImpl;-><init>()V -Lorg/ccil/cowan/tagsoup/jaxp/SAXParserImpl;->newInstance(Ljava/util/Map;)Lorg/ccil/cowan/tagsoup/jaxp/SAXParserImpl; -Lorg/ccil/cowan/tagsoup/Parser;-><init>()V -Lorg/ccil/cowan/tagsoup/Parser;->bogonsEmpty:Z -Lorg/ccil/cowan/tagsoup/Parser;->CDATAElements:Z -Lorg/ccil/cowan/tagsoup/Parser;->cleanPublicid(Ljava/lang/String;)Ljava/lang/String; -Lorg/ccil/cowan/tagsoup/Parser;->defaultAttributes:Z -Lorg/ccil/cowan/tagsoup/Parser;->etagchars:[C -Lorg/ccil/cowan/tagsoup/Parser;->expandEntities(Ljava/lang/String;)Ljava/lang/String; -Lorg/ccil/cowan/tagsoup/Parser;->getInputStream(Ljava/lang/String;Ljava/lang/String;)Ljava/io/InputStream; -Lorg/ccil/cowan/tagsoup/Parser;->ignorableWhitespace:Z -Lorg/ccil/cowan/tagsoup/Parser;->ignoreBogons:Z -Lorg/ccil/cowan/tagsoup/Parser;->lookupEntity([CII)I -Lorg/ccil/cowan/tagsoup/Parser;->makeName([CII)Ljava/lang/String; -Lorg/ccil/cowan/tagsoup/Parser;->pop()V -Lorg/ccil/cowan/tagsoup/Parser;->push(Lorg/ccil/cowan/tagsoup/Element;)V -Lorg/ccil/cowan/tagsoup/Parser;->rectify(Lorg/ccil/cowan/tagsoup/Element;)V -Lorg/ccil/cowan/tagsoup/Parser;->restart(Lorg/ccil/cowan/tagsoup/Element;)V -Lorg/ccil/cowan/tagsoup/Parser;->restartablyPop()V -Lorg/ccil/cowan/tagsoup/Parser;->rootBogons:Z -Lorg/ccil/cowan/tagsoup/Parser;->schemaProperty:Ljava/lang/String; -Lorg/ccil/cowan/tagsoup/Parser;->split(Ljava/lang/String;)[Ljava/lang/String; -Lorg/ccil/cowan/tagsoup/Parser;->theAttributeName:Ljava/lang/String; -Lorg/ccil/cowan/tagsoup/Parser;->theAutoDetector:Lorg/ccil/cowan/tagsoup/AutoDetector; -Lorg/ccil/cowan/tagsoup/Parser;->theContentHandler:Lorg/xml/sax/ContentHandler; -Lorg/ccil/cowan/tagsoup/Parser;->theDoctypeIsPresent:Z -Lorg/ccil/cowan/tagsoup/Parser;->theDoctypeSystemId:Ljava/lang/String; -Lorg/ccil/cowan/tagsoup/Parser;->theFeatures:Ljava/util/HashMap; -Lorg/ccil/cowan/tagsoup/Parser;->theLexicalHandler:Lorg/xml/sax/ext/LexicalHandler; -Lorg/ccil/cowan/tagsoup/Parser;->theNewElement:Lorg/ccil/cowan/tagsoup/Element; -Lorg/ccil/cowan/tagsoup/Parser;->thePCDATA:Lorg/ccil/cowan/tagsoup/Element; -Lorg/ccil/cowan/tagsoup/Parser;->thePITarget:Ljava/lang/String; -Lorg/ccil/cowan/tagsoup/Parser;->theSaved:Lorg/ccil/cowan/tagsoup/Element; -Lorg/ccil/cowan/tagsoup/Parser;->theScanner:Lorg/ccil/cowan/tagsoup/Scanner; -Lorg/ccil/cowan/tagsoup/Parser;->theSchema:Lorg/ccil/cowan/tagsoup/Schema; -Lorg/ccil/cowan/tagsoup/Parser;->theStack:Lorg/ccil/cowan/tagsoup/Element; -Lorg/ccil/cowan/tagsoup/Parser;->trimquotes(Ljava/lang/String;)Ljava/lang/String; -Lorg/ccil/cowan/tagsoup/Parser;->virginStack:Z -Lorg/ccil/cowan/tagsoup/PYXScanner;-><init>()V -Lorg/ccil/cowan/tagsoup/PYXWriter;-><init>(Ljava/io/Writer;)V -Lorg/ccil/cowan/tagsoup/ScanHandler;->aname([CII)V -Lorg/ccil/cowan/tagsoup/ScanHandler;->aval([CII)V -Lorg/ccil/cowan/tagsoup/ScanHandler;->entity([CII)V -Lorg/ccil/cowan/tagsoup/ScanHandler;->eof([CII)V -Lorg/ccil/cowan/tagsoup/ScanHandler;->etag([CII)V -Lorg/ccil/cowan/tagsoup/ScanHandler;->gi([CII)V -Lorg/ccil/cowan/tagsoup/ScanHandler;->pcdata([CII)V -Lorg/ccil/cowan/tagsoup/ScanHandler;->pi([CII)V -Lorg/ccil/cowan/tagsoup/ScanHandler;->stagc([CII)V -Lorg/ccil/cowan/tagsoup/Scanner;->startCDATA()V -Lorg/ccil/cowan/tagsoup/Schema;->elementType(Ljava/lang/String;III)V -Lorg/ccil/cowan/tagsoup/Schema;->getElementType(Ljava/lang/String;)Lorg/ccil/cowan/tagsoup/ElementType; -Lorg/ccil/cowan/tagsoup/Schema;->getEntity(Ljava/lang/String;)I -Lorg/ccil/cowan/tagsoup/Schema;->getPrefix()Ljava/lang/String; -Lorg/ccil/cowan/tagsoup/Schema;->getURI()Ljava/lang/String; -Lorg/ccil/cowan/tagsoup/Schema;->parent(Ljava/lang/String;Ljava/lang/String;)V -Lorg/ccil/cowan/tagsoup/Schema;->theElementTypes:Ljava/util/HashMap; -Lorg/ccil/cowan/tagsoup/Schema;->theEntities:Ljava/util/HashMap; -Lorg/ccil/cowan/tagsoup/Schema;->thePrefix:Ljava/lang/String; -Lorg/ccil/cowan/tagsoup/Schema;->theRoot:Lorg/ccil/cowan/tagsoup/ElementType; -Lorg/ccil/cowan/tagsoup/Schema;->theURI:Ljava/lang/String; -Lorg/ccil/cowan/tagsoup/XMLWriter;-><init>(Ljava/io/Writer;)V -Lorg/ccil/cowan/tagsoup/XMLWriter;->htmlMode:Z -Lorg/ccil/cowan/tagsoup/XMLWriter;->setOutput(Ljava/io/Writer;)V -Lorg/ccil/cowan/tagsoup/XMLWriter;->setOutputProperty(Ljava/lang/String;Ljava/lang/String;)V -Lorg/ccil/cowan/tagsoup/XMLWriter;->setPrefix(Ljava/lang/String;Ljava/lang/String;)V diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java index b039a60fbab3..883bcb896841 100644 --- a/core/java/android/app/Activity.java +++ b/core/java/android/app/Activity.java @@ -157,8 +157,9 @@ import java.util.List; * creating a window for you in which you can place your UI with * {@link #setContentView}. While activities are often presented to the user * as full-screen windows, they can also be used in other ways: as floating - * windows (via a theme with {@link android.R.attr#windowIsFloating} set) - * or embedded inside of another activity (using {@link ActivityGroup}). + * windows (via a theme with {@link android.R.attr#windowIsFloating} set), + * <a href="https://developer.android.com/guide/topics/ui/multi-window"> + * Multi-Window mode</a> or embedded into other windows. * * There are two methods almost all subclasses of Activity will implement: * @@ -169,10 +170,11 @@ import java.util.List; * to retrieve the widgets in that UI that you need to interact with * programmatically. * - * <li> {@link #onPause} is where you deal with the user leaving your - * activity. Most importantly, any changes made by the user should at this - * point be committed (usually to the - * {@link android.content.ContentProvider} holding the data). + * <li> {@link #onPause} is where you deal with the user pausing active + * interaction with the activity. Any changes made by the user should at + * this point be committed (usually to the + * {@link android.content.ContentProvider} holding the data). In this + * state the activity is still visible on screen. * </ul> * * <p>To be of use with {@link android.content.Context#startActivity Context.startActivity()}, all @@ -220,32 +222,31 @@ import java.util.List; * <a name="ActivityLifecycle"></a> * <h3>Activity Lifecycle</h3> * - * <p>Activities in the system are managed as an <em>activity stack</em>. - * When a new activity is started, it is placed on the top of the stack - * and becomes the running activity -- the previous activity always remains + * <p>Activities in the system are managed as + * <a href="https://developer.android.com/guide/components/activities/tasks-and-back-stack"> + * activity stacks</a>. When a new activity is started, it is usually placed on the top of the + * current stack and becomes the running activity -- the previous activity always remains * below it in the stack, and will not come to the foreground again until - * the new activity exits.</p> + * the new activity exits. There can be one or multiple activity stacks visible + * on screen.</p> * * <p>An activity has essentially four states:</p> * <ul> - * <li> If an activity is in the foreground of the screen (at the top of - * the stack), - * it is <em>active</em> or <em>running</em>. </li> - * <li>If an activity has lost focus but is still visible (that is, a new non-full-sized - * or transparent activity has focus on top of your activity), it - * is <em>paused</em>. A paused activity is completely alive (it - * maintains all state and member information and remains attached to - * the window manager), but can be killed by the system in extreme - * low memory situations. + * <li>If an activity is in the foreground of the screen (at the highest position of the topmost + * stack), it is <em>active</em> or <em>running</em>. This is usually the activity that the + * user is currently interacting with.</li> + * <li>If an activity has lost focus but is still presented to the user, it is <em>visible</em>. + * It is possible if a new non-full-sized or transparent activity has focus on top of your + * activity, another activity has higher position in multi-window mode, or the activity + * itself is not focusable in current windowing mode. Such activity is completely alive (it + * maintains all state and member information and remains attached to the window manager). * <li>If an activity is completely obscured by another activity, - * it is <em>stopped</em>. It still retains all state and member information, - * however, it is no longer visible to the user so its window is hidden - * and it will often be killed by the system when memory is needed - * elsewhere.</li> - * <li>If an activity is paused or stopped, the system can drop the activity - * from memory by either asking it to finish, or simply killing its - * process. When it is displayed again to the user, it must be - * completely restarted and restored to its previous state.</li> + * it is <em>stopped</em> or <em>hidden</em>. It still retains all state and member + * information, however, it is no longer visible to the user so its window is hidden + * and it will often be killed by the system when memory is needed elsewhere.</li> + * <li>The system can drop the activity from memory by either asking it to finish, + * or simply killing its process, making it <em>destroyed</em>. When it is displayed again + * to the user, it must be completely restarted and restored to its previous state.</li> * </ul> * * <p>The following diagram shows the important state paths of an Activity. @@ -283,7 +284,7 @@ import java.util.List; * <li>The <b>foreground lifetime</b> of an activity happens between a call to * {@link android.app.Activity#onResume} until a corresponding call to * {@link android.app.Activity#onPause}. During this time the activity is - * in front of all other activities and interacting with the user. An activity + * in visible, active and interacting with the user. An activity * can frequently go between the resumed and paused states -- for example when * the device goes to sleep, when an activity result is delivered, when a new * intent is delivered -- so the code in these methods should be fairly @@ -296,7 +297,8 @@ import java.util.List; * activities will implement {@link android.app.Activity#onCreate} * to do their initial setup; many will also implement * {@link android.app.Activity#onPause} to commit changes to data and - * otherwise prepare to stop interacting with the user. You should always + * prepare to pause interacting with the user, and {@link android.app.Activity#onStop} + * to handle no longer being visible on screen. You should always * call up to your superclass when implementing these methods.</p> * * </p> @@ -364,17 +366,17 @@ import java.util.List; * <td align="left" border="0">{@link android.app.Activity#onResume onResume()}</td> * <td>Called when the activity will start * interacting with the user. At this point your activity is at - * the top of the activity stack, with user input going to it. + * the top of its activity stack, with user input going to it. * <p>Always followed by <code>onPause()</code>.</td> * <td align="center">No</td> * <td align="center"><code>onPause()</code></td> * </tr> * * <tr><td align="left" border="0">{@link android.app.Activity#onPause onPause()}</td> - * <td>Called when the system is about to start resuming a previous - * activity. This is typically used to commit unsaved changes to - * persistent data, stop animations and other things that may be consuming - * CPU, etc. Implementations of this method must be very quick because + * <td>Called when the activity loses foreground state, is no longer focusable or before + * transition to stopped/hidden or destroyed state. The activity is still visible to + * user, so it's recommended to keep it visually active and continue updating the UI. + * Implementations of this method must be very quick because * the next activity will not be resumed until this method returns. * <p>Followed by either <code>onResume()</code> if the activity * returns back to the front, or <code>onStop()</code> if it becomes @@ -385,11 +387,10 @@ import java.util.List; * </tr> * * <tr><td colspan="2" align="left" border="0">{@link android.app.Activity#onStop onStop()}</td> - * <td>Called when the activity is no longer visible to the user, because - * another activity has been resumed and is covering this one. This - * may happen either because a new activity is being started, an existing - * one is being brought in front of this one, or this one is being - * destroyed. + * <td>Called when the activity is no longer visible to the user. This may happen either + * because a new activity is being started on top, an existing one is being brought in + * front of this one, or this one is being destroyed. This is typically used to stop + * animations and refreshing the UI, etc. * <p>Followed by either <code>onRestart()</code> if * this activity is coming back to interact with the user, or * <code>onDestroy()</code> if this activity is going away.</td> @@ -446,8 +447,9 @@ import java.util.List; * <p>For those methods that are not marked as being killable, the activity's * process will not be killed by the system starting from the time the method * is called and continuing after it returns. Thus an activity is in the killable - * state, for example, between after <code>onPause()</code> to the start of - * <code>onResume()</code>.</p> + * state, for example, between after <code>onStop()</code> to the start of + * <code>onResume()</code>. Keep in mind that under extreme memory pressure the + * system can kill the application process at any time.</p> * * <a name="ConfigurationChanges"></a> * <h3>Configuration Changes</h3> @@ -582,8 +584,8 @@ import java.util.List; * <p>This model is designed to prevent data loss when a user is navigating * between activities, and allows the system to safely kill an activity (because * system resources are needed somewhere else) at any time after it has been - * paused. Note this implies - * that the user pressing BACK from your activity does <em>not</em> + * stopped (or paused on platform versions before {@link android.os.Build.VERSION_CODES#HONEYCOMB}). + * Note this implies that the user pressing BACK from your activity does <em>not</em> * mean "cancel" -- it means to leave the activity with its current contents * saved away. Canceling edits in an activity must be provided through * some other mechanism, such as an explicit "revert" or "undo" option.</p> @@ -684,11 +686,12 @@ import java.util.List; * reached a memory paging state, so this is required in order to keep the user * interface responsive. * <li> <p>A <b>visible activity</b> (an activity that is visible to the user - * but not in the foreground, such as one sitting behind a foreground dialog) + * but not in the foreground, such as one sitting behind a foreground dialog + * or next to other activities in multi-window mode) * is considered extremely important and will not be killed unless that is * required to keep the foreground activity running. * <li> <p>A <b>background activity</b> (an activity that is not visible to - * the user and has been paused) is no longer critical, so the system may + * the user and has been stopped) is no longer critical, so the system may * safely kill its process to reclaim memory for other foreground or * visible processes. If its process needs to be killed, when the user navigates * back to the activity (making it visible on the screen again), its @@ -1685,7 +1688,12 @@ public class Activity extends ContextThemeWrapper /** * Called after {@link #onCreate} — or after {@link #onRestart} when * the activity had been stopped, but is now again being displayed to the - * user. It will be followed by {@link #onResume}. + * user. It will usually be followed by {@link #onResume}. This is a good place to begin + * drawing visual elements, running animations, etc. + * + * <p>You can call {@link #finish} from within this function, in + * which case {@link #onStop} will be immediately called after {@link #onStart} without the + * lifecycle transitions in-between ({@link #onResume}, {@link #onPause}, etc) executing. * * <p><em>Derived classes must call through to the super class's * implementation of this method. If they do not, an exception will be @@ -1751,14 +1759,15 @@ public class Activity extends ContextThemeWrapper /** * Called after {@link #onRestoreInstanceState}, {@link #onRestart}, or - * {@link #onPause}, for your activity to start interacting with the user. - * This is a good place to begin animations, open exclusive-access devices - * (such as the camera), etc. + * {@link #onPause}, for your activity to start interacting with the user. This is an indicator + * that the activity became active and ready to receive input. It is on top of an activity stack + * and visible to user. * - * <p>Keep in mind that onResume is not the best indicator that your activity - * is visible to the user; a system window such as the keyguard may be in - * front. Use {@link #onWindowFocusChanged} to know for certain that your - * activity is visible to the user (for example, to resume a game). + * <p>On platform versions prior to {@link android.os.Build.VERSION_CODES#Q} this is also a good + * place to try to open exclusive-access devices or to get access to singleton resources. + * Starting with {@link android.os.Build.VERSION_CODES#Q} there can be multiple resumed + * activities in the system simultaneously, so {@link #onTopResumedActivityChanged(boolean)} + * should be used for that purpose instead. * * <p><em>Derived classes must call through to the super class's * implementation of this method. If they do not, an exception will be @@ -1768,6 +1777,7 @@ public class Activity extends ContextThemeWrapper * @see #onRestart * @see #onPostResume * @see #onPause + * @see #onTopResumedActivityChanged(boolean) */ @CallSuper protected void onResume() { @@ -1816,7 +1826,7 @@ public class Activity extends ContextThemeWrapper } /** - * Called when activity gets or looses the top resumed position in the system. + * Called when activity gets or loses the top resumed position in the system. * * <p>Starting with {@link android.os.Build.VERSION_CODES#Q} multiple activities can be resumed * at the same time in multi-window and multi-display modes. This callback should be used @@ -1981,8 +1991,12 @@ public class Activity extends ContextThemeWrapper * called on the existing instance with the Intent that was used to * re-launch it. * - * <p>An activity will always be paused before receiving a new intent, so - * you can count on {@link #onResume} being called after this method. + * <p>An activity can never receive a new intent in the resumed state. You can count on + * {@link #onResume} being called after this method, though not necessarily immediately after + * the completion this callback. If the activity was resumed, it will be paused and new intent + * will be delivered, followed by {@link #onResume}. If the activity wasn't in the resumed + * state, then new intent can be delivered immediately, with {@link #onResume()} called + * sometime later when activity becomes active again. * * <p>Note that {@link #getIntent} still returns the original Intent. You * can use {@link #setIntent} to update it to this new Intent. @@ -2048,14 +2062,13 @@ public class Activity extends ContextThemeWrapper * returns to activity A, the state of the user interface can be restored * via {@link #onCreate} or {@link #onRestoreInstanceState}. * - * <p>Do not confuse this method with activity lifecycle callbacks such as - * {@link #onPause}, which is always called when an activity is being placed - * in the background or on its way to destruction, or {@link #onStop} which - * is called before destruction. One example of when {@link #onPause} and - * {@link #onStop} is called and not this method is when a user navigates back - * from activity B to activity A: there is no need to call {@link #onSaveInstanceState} - * on B because that particular instance will never be restored, so the - * system avoids calling it. An example when {@link #onPause} is called and + * <p>Do not confuse this method with activity lifecycle callbacks such as {@link #onPause}, + * which is always called when the user no longer actively interacts with an activity, or + * {@link #onStop} which is called when activity becomes invisible. One example of when + * {@link #onPause} and {@link #onStop} is called and not this method is when a user navigates + * back from activity B to activity A: there is no need to call {@link #onSaveInstanceState} + * on B because that particular instance will never be restored, + * so the system avoids calling it. An example when {@link #onPause} is called and * not {@link #onSaveInstanceState} is when activity B is launched in front of activity A: * the system may avoid calling {@link #onSaveInstanceState} on activity A if it isn't * killed during the lifetime of B since the state of the user interface of @@ -2154,9 +2167,8 @@ public class Activity extends ContextThemeWrapper /** - * Called as part of the activity lifecycle when an activity is going into - * the background, but has not (yet) been killed. The counterpart to - * {@link #onResume}. + * Called as part of the activity lifecycle when the user no longer actively interacts with the + * activity, but it is still visible on screen. The counterpart to {@link #onResume}. * * <p>When activity B is launched in front of activity A, this callback will * be invoked on A. B will not be created until A's {@link #onPause} returns, @@ -2166,22 +2178,20 @@ public class Activity extends ContextThemeWrapper * activity is editing, to present a "edit in place" model to the user and * making sure nothing is lost if there are not enough resources to start * the new activity without first killing this one. This is also a good - * place to do things like stop animations and other things that consume a - * noticeable amount of CPU in order to make the switch to the next activity - * as fast as possible, or to close resources that are exclusive access - * such as the camera. - * - * <p>In situations where the system needs more memory it may kill paused - * processes to reclaim resources. Because of this, you should be sure - * that all of your state is saved by the time you return from - * this function. In general {@link #onSaveInstanceState} is used to save - * per-instance state in the activity and this method is used to store - * global persistent data (in content providers, files, etc.) - * - * <p>After receiving this call you will usually receive a following call - * to {@link #onStop} (after the next activity has been resumed and - * displayed), however in some cases there will be a direct call back to - * {@link #onResume} without going through the stopped state. + * place to stop things that consume a noticeable amount of CPU in order to + * make the switch to the next activity as fast as possible. + * + * <p>On platform versions prior to {@link android.os.Build.VERSION_CODES#Q} this is also a good + * place to try to close exclusive-access devices or to release access to singleton resources. + * Starting with {@link android.os.Build.VERSION_CODES#Q} there can be multiple resumed + * activities in the system at the same time, so {@link #onTopResumedActivityChanged(boolean)} + * should be used for that purpose instead. + * + * <p>If an activity is launched on top, after receiving this call you will usually receive a + * following call to {@link #onStop} (after the next activity has been resumed and displayed + * above). However in some cases there will be a direct call back to {@link #onResume} without + * going through the stopped state. An activity can also rest in paused state in some cases when + * in multi-window mode, still visible to user. * * <p><em>Derived classes must call through to the super class's * implementation of this method. If they do not, an exception will be @@ -2364,7 +2374,8 @@ public class Activity extends ContextThemeWrapper /** * Called when you are no longer visible to the user. You will next * receive either {@link #onRestart}, {@link #onDestroy}, or nothing, - * depending on later user activity. + * depending on later user activity. This is a good place to stop + * refreshing UI, running animations and other visual things. * * <p><em>Derived classes must call through to the super class's * implementation of this method. If they do not, an exception will be @@ -3716,18 +3727,18 @@ public class Activity extends ContextThemeWrapper /** * Called when the current {@link Window} of the activity gains or loses - * focus. This is the best indicator of whether this activity is visible - * to the user. The default implementation clears the key tracking - * state, so should always be called. + * focus. This is the best indicator of whether this activity is the entity + * with which the user actively interacts. The default implementation + * clears the key tracking state, so should always be called. * * <p>Note that this provides information about global focus state, which - * is managed independently of activity lifecycles. As such, while focus + * is managed independently of activity lifecycle. As such, while focus * changes will generally have some relation to lifecycle changes (an * activity that is stopped will not generally get window focus), you * should not rely on any particular order between the callbacks here and * those in the other lifecycle methods such as {@link #onResume}. * - * <p>As a general rule, however, a resumed activity will have window + * <p>As a general rule, however, a foreground activity will have window * focus... unless it has displayed other dialogs or popups that take * input focus, in which case the activity itself will not have focus * when the other windows have it. Likewise, the system may display @@ -3735,11 +3746,24 @@ public class Activity extends ContextThemeWrapper * a system alert) which will temporarily take window input focus without * pausing the foreground activity. * + * <p>Starting with {@link android.os.Build.VERSION_CODES#Q} there can be + * multiple resumed activities at the same time in multi-window mode, so + * resumed state does not guarantee window focus even if there are no + * overlays above. + * + * <p>If the intent is to know when an activity is the topmost active, the + * one the user interacted with last among all activities but not including + * non-activity windows like dialogs and popups, then + * {@link #onTopResumedActivityChanged(boolean)} should be used. On platform + * versions prior to {@link android.os.Build.VERSION_CODES#Q}, + * {@link #onResume} is the best indicator. + * * @param hasFocus Whether the window of this activity has focus. * * @see #hasWindowFocus() * @see #onResume * @see View#onWindowFocusChanged(boolean) + * @see #onTopResumedActivityChanged(boolean) */ public void onWindowFocusChanged(boolean hasFocus) { } diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java index 023371d3b443..395c867de9d7 100644 --- a/core/java/android/app/ActivityManager.java +++ b/core/java/android/app/ActivityManager.java @@ -513,71 +513,75 @@ public class ActivityManager { /** @hide Process is hosting a foreground service with location type. */ public static final int PROCESS_STATE_FOREGROUND_SERVICE_LOCATION = 3; + /** @hide Process is bound to a TOP app. This is ranked below SERVICE_LOCATION so that + * it doesn't get the capability of location access while-in-use. */ + public static final int PROCESS_STATE_BOUND_TOP = 4; + /** @hide Process is hosting a foreground service. */ @UnsupportedAppUsage - public static final int PROCESS_STATE_FOREGROUND_SERVICE = 4; + public static final int PROCESS_STATE_FOREGROUND_SERVICE = 5; /** @hide Process is hosting a foreground service due to a system binding. */ @UnsupportedAppUsage - public static final int PROCESS_STATE_BOUND_FOREGROUND_SERVICE = 5; + public static final int PROCESS_STATE_BOUND_FOREGROUND_SERVICE = 6; /** @hide Process is important to the user, and something they are aware of. */ - public static final int PROCESS_STATE_IMPORTANT_FOREGROUND = 6; + public static final int PROCESS_STATE_IMPORTANT_FOREGROUND = 7; /** @hide Process is important to the user, but not something they are aware of. */ @UnsupportedAppUsage - public static final int PROCESS_STATE_IMPORTANT_BACKGROUND = 7; + public static final int PROCESS_STATE_IMPORTANT_BACKGROUND = 8; /** @hide Process is in the background transient so we will try to keep running. */ - public static final int PROCESS_STATE_TRANSIENT_BACKGROUND = 8; + public static final int PROCESS_STATE_TRANSIENT_BACKGROUND = 9; /** @hide Process is in the background running a backup/restore operation. */ - public static final int PROCESS_STATE_BACKUP = 9; + public static final int PROCESS_STATE_BACKUP = 10; /** @hide Process is in the background running a service. Unlike oom_adj, this level * is used for both the normal running in background state and the executing * operations state. */ @UnsupportedAppUsage - public static final int PROCESS_STATE_SERVICE = 10; + public static final int PROCESS_STATE_SERVICE = 11; /** @hide Process is in the background running a receiver. Note that from the * perspective of oom_adj, receivers run at a higher foreground level, but for our * prioritization here that is not necessary and putting them below services means * many fewer changes in some process states as they receive broadcasts. */ @UnsupportedAppUsage - public static final int PROCESS_STATE_RECEIVER = 11; + public static final int PROCESS_STATE_RECEIVER = 12; /** @hide Same as {@link #PROCESS_STATE_TOP} but while device is sleeping. */ - public static final int PROCESS_STATE_TOP_SLEEPING = 12; + public static final int PROCESS_STATE_TOP_SLEEPING = 13; /** @hide Process is in the background, but it can't restore its state so we want * to try to avoid killing it. */ - public static final int PROCESS_STATE_HEAVY_WEIGHT = 13; + public static final int PROCESS_STATE_HEAVY_WEIGHT = 14; /** @hide Process is in the background but hosts the home activity. */ @UnsupportedAppUsage - public static final int PROCESS_STATE_HOME = 14; + public static final int PROCESS_STATE_HOME = 15; /** @hide Process is in the background but hosts the last shown activity. */ - public static final int PROCESS_STATE_LAST_ACTIVITY = 15; + public static final int PROCESS_STATE_LAST_ACTIVITY = 16; /** @hide Process is being cached for later use and contains activities. */ @UnsupportedAppUsage - public static final int PROCESS_STATE_CACHED_ACTIVITY = 16; + public static final int PROCESS_STATE_CACHED_ACTIVITY = 17; /** @hide Process is being cached for later use and is a client of another cached * process that contains activities. */ - public static final int PROCESS_STATE_CACHED_ACTIVITY_CLIENT = 17; + public static final int PROCESS_STATE_CACHED_ACTIVITY_CLIENT = 18; /** @hide Process is being cached for later use and has an activity that corresponds * to an existing recent task. */ - public static final int PROCESS_STATE_CACHED_RECENT = 18; + public static final int PROCESS_STATE_CACHED_RECENT = 19; /** @hide Process is being cached for later use and is empty. */ - public static final int PROCESS_STATE_CACHED_EMPTY = 19; + public static final int PROCESS_STATE_CACHED_EMPTY = 20; /** @hide Process does not exist. */ - public static final int PROCESS_STATE_NONEXISTENT = 20; + public static final int PROCESS_STATE_NONEXISTENT = 21; // NOTE: If PROCESS_STATEs are added, then new fields must be added // to frameworks/base/core/proto/android/app/enums.proto and the following method must @@ -602,6 +606,8 @@ public class ActivityManager { return AppProtoEnums.PROCESS_STATE_PERSISTENT_UI; case PROCESS_STATE_TOP: return AppProtoEnums.PROCESS_STATE_TOP; + case PROCESS_STATE_BOUND_TOP: + return AppProtoEnums.PROCESS_STATE_BOUND_TOP; case PROCESS_STATE_FOREGROUND_SERVICE_LOCATION: case PROCESS_STATE_FOREGROUND_SERVICE: return AppProtoEnums.PROCESS_STATE_FOREGROUND_SERVICE; @@ -4037,7 +4043,7 @@ public class ActivityManager { * continues running even if the process is killed and restarted. To remove the watch, * use {@link #clearWatchHeapLimit()}. * - * <p>This API only work if the calling process has been marked as + * <p>This API only works if the calling process has been marked as * {@link ApplicationInfo#FLAG_DEBUGGABLE} or this is running on a debuggable * (userdebug or eng) build.</p> * diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 08239a1e7ed9..b2b1e775e94a 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) { } } @@ -5853,6 +5885,11 @@ public final class ActivityThread extends ClientTransactionHandler { private void handleBindApplication(AppBindData data) { // Register the UI Thread as a sensitive thread to the runtime. VMRuntime.registerSensitiveThread(); + // In the case the stack depth property exists, pass it down to the runtime. + String property = SystemProperties.get("debug.allocTracker.stackDepth"); + if (property.length() != 0) { + VMDebug.setAllocTrackerStackDepth(Integer.parseInt(property)); + } if (data.trackAllocation) { DdmVmInternal.enableRecentAllocations(true); } @@ -6905,9 +6942,6 @@ public final class ActivityThread extends ClientTransactionHandler { // If feature is disabled, we don't need to install if (!DEPRECATE_DATA_COLUMNS) return; - // If app is modern enough, we don't need to install - if (VMRuntime.getRuntime().getTargetSdkVersion() >= Build.VERSION_CODES.Q) return; - // Install interception and make sure it sticks! Os def = null; do { diff --git a/core/java/android/app/ActivityView.java b/core/java/android/app/ActivityView.java index 2ef085690f8f..8ec5e3a43218 100644 --- a/core/java/android/app/ActivityView.java +++ b/core/java/android/app/ActivityView.java @@ -27,6 +27,7 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.graphics.Insets; +import android.graphics.Region; import android.hardware.display.DisplayManager; import android.hardware.display.VirtualDisplay; import android.hardware.input.InputManager; @@ -46,6 +47,7 @@ import android.view.SurfaceSession; import android.view.SurfaceView; import android.view.View; import android.view.ViewGroup; +import android.view.ViewParent; import android.view.WindowManager; import android.view.WindowManagerGlobal; @@ -81,6 +83,9 @@ public class ActivityView extends ViewGroup { // Temp container to store view coordinates in window. private final int[] mLocationInWindow = new int[2]; + // The latest tap exclude region that we've sent to WM. + private final Region mTapExcludeRegion = new Region(); + private TaskStackListener mTaskStackListener; private final CloseGuard mGuard = CloseGuard.get(); @@ -279,11 +284,11 @@ public class ActivityView extends ViewGroup { } /** - * Triggers an update of {@link ActivityView}'s location in window to properly set touch exclude + * Triggers an update of {@link ActivityView}'s location in window to properly set tap exclude * regions and avoid focus switches by touches on this view. */ public void onLocationChanged() { - updateLocation(); + updateTapExcludeRegion(); } @Override @@ -291,15 +296,38 @@ public class ActivityView extends ViewGroup { mSurfaceView.layout(0 /* left */, 0 /* top */, r - l /* right */, b - t /* bottom */); } - /** Send current location and size to the WM to set tap exclude region for this view. */ - private void updateLocation() { + @Override + public boolean gatherTransparentRegion(Region region) { + // The tap exclude region may be affected by any view on top of it, so we detect the + // possible change by monitoring this function. + updateTapExcludeRegion(); + return super.gatherTransparentRegion(region); + } + + /** Compute and send current tap exclude region to WM for this view. */ + private void updateTapExcludeRegion() { if (!isAttachedToWindow()) { return; } + if (!canReceivePointerEvents()) { + cleanTapExcludeRegion(); + return; + } try { getLocationInWindow(mLocationInWindow); + final int x = mLocationInWindow[0]; + final int y = mLocationInWindow[1]; + mTapExcludeRegion.set(x, y, x + getWidth(), y + getHeight()); + + // There might be views on top of us. We need to subtract those areas from the tap + // exclude region. + final ViewParent parent = getParent(); + if (parent instanceof ViewGroup) { + ((ViewGroup) parent).subtractObscuredTouchableRegion(mTapExcludeRegion, this); + } + WindowManagerGlobal.getWindowSession().updateTapExcludeRegion(getWindow(), hashCode(), - mLocationInWindow[0], mLocationInWindow[1], getWidth(), getHeight()); + mTapExcludeRegion); } catch (RemoteException e) { e.rethrowAsRuntimeException(); } @@ -322,7 +350,7 @@ public class ActivityView extends ViewGroup { mVirtualDisplay.setDisplayState(true); } - updateLocation(); + updateTapExcludeRegion(); } @Override @@ -330,7 +358,7 @@ public class ActivityView extends ViewGroup { if (mVirtualDisplay != null) { mVirtualDisplay.resize(width, height, getBaseDisplayDensity()); } - updateLocation(); + updateTapExcludeRegion(); } @Override @@ -460,13 +488,14 @@ public class ActivityView extends ViewGroup { /** Report to server that tap exclude region on hosting display should be cleared. */ private void cleanTapExcludeRegion() { - if (!isAttachedToWindow()) { + if (!isAttachedToWindow() || mTapExcludeRegion.isEmpty()) { return; } - // Update tap exclude region with an empty rect to clean the state on server. + // Update tap exclude region with a null region to clean the state on server. try { WindowManagerGlobal.getWindowSession().updateTapExcludeRegion(getWindow(), hashCode(), - 0 /* left */, 0 /* top */, 0 /* width */, 0 /* height */); + null /* region */); + mTapExcludeRegion.setEmpty(); } catch (RemoteException e) { e.rethrowAsRuntimeException(); } diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java index 5ed4428b729b..4b0b8cb12d5e 100644 --- a/core/java/android/app/AppOpsManager.java +++ b/core/java/android/app/AppOpsManager.java @@ -18,6 +18,7 @@ package android.app; import android.Manifest; import android.annotation.IntDef; +import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresPermission; @@ -1543,11 +1544,11 @@ public class AppOpsManager { Manifest.permission.USE_BIOMETRIC, Manifest.permission.ACTIVITY_RECOGNITION, Manifest.permission.SMS_FINANCIAL_TRANSACTIONS, - Manifest.permission.READ_MEDIA_AUDIO, + null, null, // no permission for OP_WRITE_MEDIA_AUDIO - Manifest.permission.READ_MEDIA_VIDEO, + null, null, // no permission for OP_WRITE_MEDIA_VIDEO - Manifest.permission.READ_MEDIA_IMAGES, + null, null, // no permission for OP_WRITE_MEDIA_IMAGES null, // no permission for OP_LEGACY_STORAGE null, // no permission for OP_ACCESS_ACCESSIBILITY @@ -3114,7 +3115,7 @@ public class AppOpsManager { * * @see #getUidOpsAt(int) */ - public int getUidCount() { + public @IntRange(from = 0) int getUidCount() { if (mHistoricalUidOps == null) { return 0; } @@ -3130,7 +3131,7 @@ public class AppOpsManager { * * @see #getUidCount() */ - public @NonNull HistoricalUidOps getUidOpsAt(int index) { + public @NonNull HistoricalUidOps getUidOpsAt(@IntRange(from = 0) int index) { if (mHistoricalUidOps == null) { throw new IndexOutOfBoundsException(); } @@ -3391,7 +3392,7 @@ public class AppOpsManager { * * @see #getPackageOpsAt(int) */ - public int getPackageCount() { + public @IntRange(from = 0) int getPackageCount() { if (mHistoricalPackageOps == null) { return 0; } @@ -3407,7 +3408,7 @@ public class AppOpsManager { * * @see #getPackageCount() */ - public @NonNull HistoricalPackageOps getPackageOpsAt(int index) { + public @NonNull HistoricalPackageOps getPackageOpsAt(@IntRange(from = 0) int index) { if (mHistoricalPackageOps == null) { throw new IndexOutOfBoundsException(); } @@ -3626,7 +3627,7 @@ public class AppOpsManager { * @return The number historical app ops. * @see #getOpAt(int) */ - public int getOpCount() { + public @IntRange(from = 0) int getOpCount() { if (mHistoricalOps == null) { return 0; } @@ -3640,7 +3641,7 @@ public class AppOpsManager { * @return The op at the given index. * @see #getOpCount() */ - public @NonNull HistoricalOp getOpAt(int index) { + public @NonNull HistoricalOp getOpAt(@IntRange(from = 0) int index) { if (mHistoricalOps == null) { throw new IndexOutOfBoundsException(); } 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/Notification.java b/core/java/android/app/Notification.java index 5549d6b80ea6..0ab1a85372f5 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -617,6 +617,13 @@ public class Notification implements Parcelable */ public static final int FLAG_CAN_COLORIZE = 0x00000800; + /** + * Bit to be bitswised-ored into the {@link #flags} field that should be + * set if this notification can be shown as a bubble. + * @hide + */ + public static final int FLAG_BUBBLE = 0x00001000; + public int flags; /** @hide */ @@ -5564,7 +5571,7 @@ public class Notification implements Parcelable button.setTextColor(R.id.action0, textColor); rippleColor = textColor; } else if (getRawColor(p) != COLOR_DEFAULT && !isColorized(p) - && mTintActionButtons) { + && mTintActionButtons && !mInNightMode) { rippleColor = resolveContrastColor(p); button.setTextColor(R.id.action0, rippleColor); } else { @@ -6243,6 +6250,15 @@ public class Notification implements Parcelable return false; } + /** + * @return true if this is a notification that can show as a bubble. + * + * @hide + */ + public boolean isBubbleNotification() { + return (flags & Notification.FLAG_BUBBLE) != 0; + } + private boolean hasLargeIcon() { return mLargeIcon != null || largeIcon != null; } diff --git a/core/java/android/app/NotificationChannel.java b/core/java/android/app/NotificationChannel.java index 5cdf85a6ca13..69ec831b5d1d 100644 --- a/core/java/android/app/NotificationChannel.java +++ b/core/java/android/app/NotificationChannel.java @@ -170,6 +170,7 @@ public final class NotificationChannel implements Parcelable { private boolean mBlockableSystem = false; private boolean mAllowBubbles = DEFAULT_ALLOW_BUBBLE; private boolean mImportanceLockedByOEM; + private boolean mImportanceLockedDefaultApp; /** * Creates a notification channel. @@ -656,11 +657,27 @@ public final class NotificationChannel implements Parcelable { * @hide */ @TestApi + public void setImportanceLockedByCriticalDeviceFunction(boolean locked) { + mImportanceLockedDefaultApp = locked; + } + + /** + * @hide + */ + @TestApi public boolean isImportanceLockedByOEM() { return mImportanceLockedByOEM; } /** + * @hide + */ + @TestApi + public boolean isImportanceLockedByCriticalDeviceFunction() { + return mImportanceLockedDefaultApp; + } + + /** * Returns whether the user has chosen the importance of this channel, either to affirm the * initial selection from the app, or changed it to be higher or lower. * @see #getImportance() @@ -834,6 +851,9 @@ public final class NotificationChannel implements Parcelable { out.attribute(null, ATT_ALLOW_BUBBLE, Boolean.toString(canBubble())); } + // mImportanceLockedDefaultApp and mImportanceLockedByOEM have a different source of + // truth and so aren't written to this xml file + out.endTag(null, TAG_CHANNEL); } @@ -942,7 +962,8 @@ public final class NotificationChannel implements Parcelable { return sb.toString(); } - public static final @android.annotation.NonNull Creator<NotificationChannel> CREATOR = new Creator<NotificationChannel>() { + public static final @android.annotation.NonNull Creator<NotificationChannel> CREATOR = + new Creator<NotificationChannel>() { @Override public NotificationChannel createFromParcel(Parcel in) { return new NotificationChannel(in); @@ -983,7 +1004,8 @@ public final class NotificationChannel implements Parcelable { && Arrays.equals(mVibration, that.mVibration) && Objects.equals(getGroup(), that.getGroup()) && Objects.equals(getAudioAttributes(), that.getAudioAttributes()) - && mImportanceLockedByOEM == that.mImportanceLockedByOEM; + && mImportanceLockedByOEM == that.mImportanceLockedByOEM + && mImportanceLockedDefaultApp == that.mImportanceLockedDefaultApp; } @Override @@ -993,7 +1015,7 @@ public final class NotificationChannel implements Parcelable { getUserLockedFields(), isFgServiceShown(), mVibrationEnabled, mShowBadge, isDeleted(), getGroup(), getAudioAttributes(), isBlockableSystem(), mAllowBubbles, - mImportanceLockedByOEM); + mImportanceLockedByOEM, mImportanceLockedDefaultApp); result = 31 * result + Arrays.hashCode(mVibration); return result; } @@ -1022,6 +1044,7 @@ public final class NotificationChannel implements Parcelable { + ", mBlockableSystem=" + mBlockableSystem + ", mAllowBubbles=" + mAllowBubbles + ", mImportanceLockedByOEM=" + mImportanceLockedByOEM + + ", mImportanceLockedDefaultApp=" + mImportanceLockedDefaultApp + '}'; pw.println(prefix + output); } @@ -1049,6 +1072,7 @@ public final class NotificationChannel implements Parcelable { + ", mBlockableSystem=" + mBlockableSystem + ", mAllowBubbles=" + mAllowBubbles + ", mImportanceLockedByOEM=" + mImportanceLockedByOEM + + ", mImportanceLockedDefaultApp=" + mImportanceLockedDefaultApp + '}'; } 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/app/StatsManager.java b/core/java/android/app/StatsManager.java index 7aca2f209a5d..2e14d03a912c 100644 --- a/core/java/android/app/StatsManager.java +++ b/core/java/android/app/StatsManager.java @@ -411,6 +411,36 @@ public final class StatsManager { } /** + * Returns the experiments IDs registered with statsd, or an empty array if there aren't any. + * + * @throws StatsUnavailableException if unsuccessful due to failing to connect to stats service + * @hide + */ + @RequiresPermission(allOf = {DUMP, PACKAGE_USAGE_STATS}) + public long[] getRegisteredExperimentIds() + throws StatsUnavailableException { + synchronized (this) { + try { + IStatsManager service = getIStatsManagerLocked(); + if (service == null) { + if (DEBUG) { + Slog.d(TAG, "Failed to find statsd when getting experiment IDs"); + } + return new long[0]; + } + return service.getRegisteredExperimentIds(); + } catch (RemoteException e) { + if (DEBUG) { + Slog.d(TAG, + "Failed to connect to StatsCompanionService when getting " + + "registered experiment IDs"); + } + return new long[0]; + } + } + } + + /** * Registers a callback for an atom when that atom is to be pulled. The stats service will * invoke pullData in the callback when the stats service determines that this atom needs to be * pulled. Currently, this only works for atoms with tags above 100,000 that do not have a uid. diff --git a/core/java/android/app/UiAutomation.java b/core/java/android/app/UiAutomation.java index a021e3cb2d78..494467324581 100644 --- a/core/java/android/app/UiAutomation.java +++ b/core/java/android/app/UiAutomation.java @@ -22,6 +22,7 @@ import android.accessibilityservice.AccessibilityServiceInfo; import android.accessibilityservice.IAccessibilityServiceClient; import android.accessibilityservice.IAccessibilityServiceConnection; import android.annotation.NonNull; +import android.annotation.Nullable; import android.annotation.TestApi; import android.annotation.UnsupportedAppUsage; import android.graphics.Bitmap; @@ -390,10 +391,12 @@ public final class UiAutomation { * <strong>Note:<strong/> Calling this method adopts only the specified shell permissions * and overrides all adopted permissions via {@link #adoptShellPermissionIdentity()}. * + * @param permissions The permissions to adopt or <code>null</code> to adopt all. + * * @see #adoptShellPermissionIdentity() * @see #dropShellPermissionIdentity() */ - public void adoptShellPermissionIdentity(String... permissions) { + public void adoptShellPermissionIdentity(@Nullable String... permissions) { synchronized (mLock) { throwIfNotConnectedLocked(); } diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index 4b0c05f323cd..8a522656a13a 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -54,7 +54,6 @@ import android.net.NetworkUtils; import android.net.PrivateDnsConnectivityChecker; import android.net.ProxyInfo; import android.net.Uri; -import android.os.Binder; import android.os.Build; import android.os.Bundle; import android.os.ParcelFileDescriptor; @@ -5440,13 +5439,14 @@ public class DevicePolicyManager { } /** - * Called by a device or profile owner to set whether auto time is required. If auto time is - * required, no user will be able set the date and time and network date and time will be used. + * Called by a device owner, or alternatively a profile owner from Android 8.0 (API level 26) or + * higher, to set whether auto time is required. If auto time is required, no user will be able + * set the date and time and network date and time will be used. * <p> * Note: if auto time is required the user can still manually set the time zone. * <p> - * The calling device admin must be a device or profile owner. If it is not, a security - * exception will be thrown. + * The calling device admin must be a device owner, or alternatively a profile owner from + * Android 8.0 (API level 26) or higher. If it is not, a security exception will be thrown. * * @param admin Which {@link DeviceAdminReceiver} this request is associated with. * @param required Whether auto time is set required or not. @@ -6409,27 +6409,20 @@ public class DevicePolicyManager { * Returns whether the specified package can read the device identifiers. * * @param packageName The package name of the app to check for device identifier access. + * @param pid The process id of the package to be checked. + * @param uid The uid of the package to be checked. * @return whether the package can read the device identifiers. * * @hide */ - public boolean checkDeviceIdentifierAccess(String packageName) { - return checkDeviceIdentifierAccessAsUser(packageName, myUserId()); - } - - /** - * @hide - */ - @RequiresPermission(value = android.Manifest.permission.MANAGE_USERS, conditional = true) - public boolean checkDeviceIdentifierAccessAsUser(String packageName, int userId) { - throwIfParentInstance("checkDeviceIdentifierAccessAsUser"); + public boolean checkDeviceIdentifierAccess(String packageName, int pid, int uid) { + throwIfParentInstance("checkDeviceIdentifierAccess"); if (packageName == null) { return false; } if (mService != null) { try { - return mService.checkDeviceIdentifierAccess(packageName, userId, - Binder.getCallingPid(), Binder.getCallingUid()); + return mService.checkDeviceIdentifierAccess(packageName, pid, uid); } catch (RemoteException re) { throw re.rethrowFromSystemServer(); } @@ -10789,8 +10782,8 @@ public class DevicePolicyManager { } /** - * Returns whether the device is being used as a managed kiosk, as defined in the CDD. As of - * this release, these requirements are as follows: + * Returns whether the device is being used as a managed kiosk. These requirements are as + * follows: * <ul> * <li>The device is in Lock Task (therefore there is also a Device Owner app on the * device)</li> @@ -10829,11 +10822,11 @@ public class DevicePolicyManager { } /** - * Returns whether the device is being used as an unattended managed kiosk, as defined in the - * CDD. As of this release, these requirements are as follows: + * Returns whether the device is being used as an unattended managed kiosk. These requirements + * are as follows: * <ul> - * <li>The device is being used as a managed kiosk, as defined in the CDD and verified at - * {@link #isManagedKiosk()}</li> + * <li>The device is being used as a managed kiosk, as defined at {@link + * #isManagedKiosk()}</li> * <li>The device has not received user input for at least 30 minutes</li> * </ul> * diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl index 3c389e4aa38c..2b9641999019 100644 --- a/core/java/android/app/admin/IDevicePolicyManager.aidl +++ b/core/java/android/app/admin/IDevicePolicyManager.aidl @@ -156,7 +156,7 @@ interface IDevicePolicyManager { void clearProfileOwner(in ComponentName who); boolean hasUserSetupCompleted(); - boolean checkDeviceIdentifierAccess(in String packageName, int userHandle, int pid, int uid); + boolean checkDeviceIdentifierAccess(in String packageName, int pid, int uid); void setDeviceOwnerLockScreenInfo(in ComponentName who, CharSequence deviceOwnerInfo); CharSequence getDeviceOwnerLockScreenInfo(); diff --git a/core/java/android/app/usage/UsageStatsManager.java b/core/java/android/app/usage/UsageStatsManager.java index 26c8218a71ba..eb1ea90e4382 100644 --- a/core/java/android/app/usage/UsageStatsManager.java +++ b/core/java/android/app/usage/UsageStatsManager.java @@ -298,7 +298,10 @@ public final class UsageStatsManager { * * @param intervalType The time interval by which the stats are aggregated. * @param beginTime The inclusive beginning of the range of stats to include in the results. - * @param endTime The exclusive end of the range of stats to include in the results. + * Defined in terms of "Unix time", see + * {@link java.lang.System#currentTimeMillis}. + * @param endTime The exclusive end of the range of stats to include in the results. Defined + * in terms of "Unix time", see {@link java.lang.System#currentTimeMillis}. * @return A list of {@link UsageStats} * * @see #INTERVAL_DAILY @@ -329,7 +332,10 @@ public final class UsageStatsManager { * * @param intervalType The time interval by which the stats are aggregated. * @param beginTime The inclusive beginning of the range of stats to include in the results. - * @param endTime The exclusive end of the range of stats to include in the results. + * Defined in terms of "Unix time", see + * {@link java.lang.System#currentTimeMillis}. + * @param endTime The exclusive end of the range of stats to include in the results. Defined + * in terms of "Unix time", see {@link java.lang.System#currentTimeMillis}. * @return A list of {@link ConfigurationStats} */ public List<ConfigurationStats> queryConfigurations(int intervalType, long beginTime, @@ -364,7 +370,10 @@ public final class UsageStatsManager { * * @param intervalType The time interval by which the stats are aggregated. * @param beginTime The inclusive beginning of the range of stats to include in the results. - * @param endTime The exclusive end of the range of stats to include in the results. + * Defined in terms of "Unix time", see + * {@link java.lang.System#currentTimeMillis}. + * @param endTime The exclusive end of the range of stats to include in the results. Defined + * in terms of "Unix time", see {@link java.lang.System#currentTimeMillis}. * @return A list of {@link EventStats} * * @see #INTERVAL_DAILY @@ -393,7 +402,10 @@ public final class UsageStatsManager { * <p> The caller must have {@link android.Manifest.permission#PACKAGE_USAGE_STATS} </p> * * @param beginTime The inclusive beginning of the range of events to include in the results. - * @param endTime The exclusive end of the range of events to include in the results. + * Defined in terms of "Unix time", see + * {@link java.lang.System#currentTimeMillis}. + * @param endTime The exclusive end of the range of events to include in the results. Defined + * in terms of "Unix time", see {@link java.lang.System#currentTimeMillis}. * @return A {@link UsageEvents}. */ public UsageEvents queryEvents(long beginTime, long endTime) { @@ -413,7 +425,10 @@ public final class UsageStatsManager { * Like {@link #queryEvents(long, long)}, but only returns events for the calling package. * * @param beginTime The inclusive beginning of the range of events to include in the results. - * @param endTime The exclusive end of the range of events to include in the results. + * Defined in terms of "Unix time", see + * {@link java.lang.System#currentTimeMillis}. + * @param endTime The exclusive end of the range of events to include in the results. Defined + * in terms of "Unix time", see {@link java.lang.System#currentTimeMillis}. * @return A {@link UsageEvents} object. * * @see #queryEvents(long, long) @@ -438,7 +453,10 @@ public final class UsageStatsManager { * <p> The caller must have {@link android.Manifest.permission#PACKAGE_USAGE_STATS} </p> * * @param beginTime The inclusive beginning of the range of stats to include in the results. - * @param endTime The exclusive end of the range of stats to include in the results. + * Defined in terms of "Unix time", see + * {@link java.lang.System#currentTimeMillis}. + * @param endTime The exclusive end of the range of stats to include in the results. Defined + * in terms of "Unix time", see {@link java.lang.System#currentTimeMillis}. * @return A {@link java.util.Map} keyed by package name */ public Map<String, UsageStats> queryAndAggregateUsageStats(long beginTime, long endTime) { diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java index fa2c9f8a52ae..204d7e3ceca6 100644 --- a/core/java/android/bluetooth/BluetoothDevice.java +++ b/core/java/android/bluetooth/BluetoothDevice.java @@ -535,7 +535,6 @@ public final class BluetoothDevice implements Parcelable { /** * Intent to broadcast silence mode changed. * Alway contains the extra field {@link #EXTRA_DEVICE} - * Alway contains the extra field {@link #EXTRA_SILENCE_ENABLED} * * @hide */ @@ -545,16 +544,6 @@ public final class BluetoothDevice implements Parcelable { "android.bluetooth.device.action.SILENCE_MODE_CHANGED"; /** - * Used as an extra field in {@link #ACTION_SILENCE_MODE_CHANGED} intent, - * contains whether device is in silence mode as boolean. - * - * @hide - */ - @SystemApi - public static final String EXTRA_SILENCE_ENABLED = - "android.bluetooth.device.extra.SILENCE_ENABLED"; - - /** * Used as an extra field in {@link #ACTION_CONNECTION_ACCESS_REQUEST} intent. * * @hide @@ -1615,7 +1604,8 @@ public final class BluetoothDevice implements Parcelable { } /** - * Set the Bluetooth device silence mode. + * Sets whether the {@link BluetoothDevice} enters silence mode. Audio will not + * be routed to the {@link BluetoothDevice} if set to {@code true}. * * When the {@link BluetoothDevice} enters silence mode, and the {@link BluetoothDevice} * is an active device (for A2DP or HFP), the active device for that profile @@ -1635,6 +1625,7 @@ public final class BluetoothDevice implements Parcelable { * * @param silence true to enter silence mode, false to exit * @return true on success, false on error. + * @throws IllegalStateException if Bluetooth is not turned ON. * @hide */ @SystemApi @@ -1642,12 +1633,9 @@ public final class BluetoothDevice implements Parcelable { public boolean setSilenceMode(boolean silence) { final IBluetooth service = sService; if (service == null) { - return false; + throw new IllegalStateException("Bluetooth is not turned ON"); } try { - if (getSilenceMode() == silence) { - return true; - } return service.setSilenceMode(this, silence); } catch (RemoteException e) { Log.e(TAG, "setSilenceMode fail", e); @@ -1656,24 +1644,25 @@ public final class BluetoothDevice implements Parcelable { } /** - * Get the device silence mode status + * Check whether the {@link BluetoothDevice} is in silence mode * * <p> Requires {@link android.Manifest.permission#BLUETOOTH_PRIVILEGED}. * * @return true on device in silence mode, otherwise false. + * @throws IllegalStateException if Bluetooth is not turned ON. * @hide */ @SystemApi @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) - public boolean getSilenceMode() { + public boolean isInSilenceMode() { final IBluetooth service = sService; if (service == null) { - return false; + throw new IllegalStateException("Bluetooth is not turned ON"); } try { return service.getSilenceMode(this); } catch (RemoteException e) { - Log.e(TAG, "getSilenceMode fail", e); + Log.e(TAG, "isInSilenceMode fail", e); return false; } } diff --git a/core/java/android/bluetooth/BluetoothHealth.java b/core/java/android/bluetooth/BluetoothHealth.java index e2e56fd02ab7..5fd60e001693 100644 --- a/core/java/android/bluetooth/BluetoothHealth.java +++ b/core/java/android/bluetooth/BluetoothHealth.java @@ -99,6 +99,11 @@ public final class BluetoothHealth implements BluetoothProfile { @Deprecated public static final int CHANNEL_TYPE_STREAMING = 11; + /** + * Hide auto-created default constructor + * @hide + */ + BluetoothHealth() {} /** * Register an application configuration that acts as a Health SINK. diff --git a/core/java/android/bluetooth/BluetoothHealthAppConfiguration.java b/core/java/android/bluetooth/BluetoothHealthAppConfiguration.java index 88e06e58f9ce..2f66df258b53 100644 --- a/core/java/android/bluetooth/BluetoothHealthAppConfiguration.java +++ b/core/java/android/bluetooth/BluetoothHealthAppConfiguration.java @@ -33,6 +33,13 @@ import android.os.Parcelable; */ @Deprecated public final class BluetoothHealthAppConfiguration implements Parcelable { + + /** + * Hide auto-created default constructor + * @hide + */ + BluetoothHealthAppConfiguration() {} + @Override public int describeContents() { return 0; diff --git a/core/java/android/content/ContentCaptureOptions.java b/core/java/android/content/ContentCaptureOptions.java index 1727d341bd82..76c4fb8caa0b 100644 --- a/core/java/android/content/ContentCaptureOptions.java +++ b/core/java/android/content/ContentCaptureOptions.java @@ -136,13 +136,18 @@ public final class ContentCaptureOptions implements Parcelable { @Override public String toString() { if (lite) { - return "ContentCaptureOptions [(lite) loggingLevel=" + loggingLevel + "]"; + return "ContentCaptureOptions [loggingLevel=" + loggingLevel + " (lite)]"; } - return "ContentCaptureOptions [loggingLevel=" + loggingLevel + ", maxBufferSize=" - + maxBufferSize + ", idleFlushingFrequencyMs=" + idleFlushingFrequencyMs - + ", textChangeFlushingFrequencyMs=" + textChangeFlushingFrequencyMs - + ", logHistorySize=" + logHistorySize + ", whitelistedComponents=" - + whitelistedComponents + "]"; + final StringBuilder string = new StringBuilder("ContentCaptureOptions ["); + string.append("loggingLevel=").append(loggingLevel) + .append(", maxBufferSize=").append(maxBufferSize) + .append(", idleFlushingFrequencyMs=").append(idleFlushingFrequencyMs) + .append(", textChangeFlushingFrequencyMs=").append(textChangeFlushingFrequencyMs) + .append(", logHistorySize=").append(logHistorySize); + if (whitelistedComponents != null) { + string.append(", whitelisted=").append(whitelistedComponents); + } + return string.append(']').toString(); } /** @hide */ diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java index fa85f0ae1670..791c55196ecf 100644 --- a/core/java/android/content/ContentResolver.java +++ b/core/java/android/content/ContentResolver.java @@ -1313,6 +1313,12 @@ public abstract class ContentResolver implements ContentInterface { public final @Nullable ParcelFileDescriptor openFileDescriptor(@NonNull Uri uri, @NonNull String mode, @Nullable CancellationSignal cancellationSignal) throws FileNotFoundException { + try { + if (mWrapped != null) return mWrapped.openFile(uri, mode, cancellationSignal); + } catch (RemoteException e) { + return null; + } + AssetFileDescriptor afd = openAssetFileDescriptor(uri, mode, cancellationSignal); if (afd == null) { return null; @@ -1455,6 +1461,12 @@ public abstract class ContentResolver implements ContentInterface { Preconditions.checkNotNull(uri, "uri"); Preconditions.checkNotNull(mode, "mode"); + try { + if (mWrapped != null) return mWrapped.openAssetFile(uri, mode, cancellationSignal); + } catch (RemoteException e) { + return null; + } + String scheme = uri.getScheme(); if (SCHEME_ANDROID_RESOURCE.equals(scheme)) { if (!"r".equals(mode)) { @@ -1634,6 +1646,12 @@ public abstract class ContentResolver implements ContentInterface { Preconditions.checkNotNull(uri, "uri"); Preconditions.checkNotNull(mimeType, "mimeType"); + try { + if (mWrapped != null) return mWrapped.openTypedAssetFile(uri, mimeType, opts, cancellationSignal); + } catch (RemoteException e) { + return null; + } + IContentProvider unstableProvider = acquireUnstableProvider(uri); if (unstableProvider == null) { throw new FileNotFoundException("No content provider: " + uri); @@ -3525,12 +3543,7 @@ public abstract class ContentResolver implements ContentInterface { */ public @NonNull Bitmap loadThumbnail(@NonNull Uri uri, @NonNull Size size, @Nullable CancellationSignal signal) throws IOException { - Objects.requireNonNull(uri); - Objects.requireNonNull(size); - - try (ContentProviderClient client = acquireContentProviderClient(uri)) { - return loadThumbnail(client, uri, size, signal, ImageDecoder.ALLOCATOR_SOFTWARE); - } + return loadThumbnail(this, uri, size, signal, ImageDecoder.ALLOCATOR_SOFTWARE); } /** {@hide} */ diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index d7a2e1b80f84..af738da20621 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -427,7 +427,7 @@ public abstract class Context { * invisible background activities. This will impact the number of * recent activities the user can switch between without having them * restart. There is no guarantee this will be respected, as the system - * tries to balance such requests from one app vs. the importantance of + * tries to balance such requests from one app vs. the importance of * keeping other apps around. */ public static final int BIND_VISIBLE = 0x10000000; diff --git a/core/java/android/content/LocusId.java b/core/java/android/content/LocusId.java index c67ff7caaf64..283cea00b192 100644 --- a/core/java/android/content/LocusId.java +++ b/core/java/android/content/LocusId.java @@ -18,19 +18,50 @@ package android.content; import android.annotation.NonNull; import android.os.Parcel; import android.os.Parcelable; +import android.view.contentcapture.ContentCaptureManager; import com.android.internal.util.Preconditions; import java.io.PrintWriter; /** - * Identifier for an unique state in the application. + * An identifier for an unique state (locus) in the application. Should be stable across reboots and + * backup / restore. * - * <p>Should be stable across reboots and backup / restore. + * <p>Locus is a new concept introduced on + * {@link android.os.Build.VERSION_CODES#Q Android Q} and it lets the intelligence service provided + * by the Android System to correlate state between different subsystems such as content capture, + * shortcuts, and notifications. * - * <p>For example, a chat app could use the context to resume a conversation between 2 users. + * <p>For example, if your app provides an activiy representing a chat between 2 users + * (say {@code A} and {@code B}, this chat state could be represented by: + * + * <pre><code> + * LocusId chatId = new LocusId("Chat_A_B"); + * </code></pre> + * + * <p>And then you should use that {@code chatId} by: + * + * <ul> + * <li>Setting it in the chat notification (through + * {@link android.app.Notification.Builder#setLocusId(LocusId) + * Notification.Builder.setLocusId(chatId)}). + * <li>Setting it into the {@link android.content.pm.ShortcutInfo} (through + * {@link android.content.pm.ShortcutInfo.Builder#setLocusId(LocusId) + * ShortcutInfo.Builder.setLocusId(chatId)}), if you provide a launcher shortcut for that chat + * conversation. + * <li>Associating it with the {@link android.view.contentcapture.ContentCaptureContext} of the + * root view of the chat conversation activity (through + * {@link android.view.View#getContentCaptureSession()}, then + * {@link android.view.contentcapture.ContentCaptureContext.Builder + * new ContentCaptureContext.Builder(chatId).build()} and + * {@link android.view.contentcapture.ContentCaptureSession#setContentCaptureContext( + * android.view.contentcapture.ContentCaptureContext)} - see {@link ContentCaptureManager} + * for more info about content capture). + * <li>Configuring your app to launch the chat conversation through the + * {@link Intent#ACTION_VIEW_LOCUS} intent. + * </ul> */ -// TODO(b/123577059): make sure this is well documented and understandable public final class LocusId implements Parcelable { private final String mId; @@ -45,7 +76,7 @@ public final class LocusId implements Parcelable { } /** - * Gets the {@code id} associated with the locus. + * Gets the canonical {@code id} associated with the locus. */ @NonNull public String getId() { @@ -100,7 +131,7 @@ public final class LocusId implements Parcelable { parcel.writeString(mId); } - public static final @android.annotation.NonNull Parcelable.Creator<LocusId> CREATOR = + public static final @NonNull Parcelable.Creator<LocusId> CREATOR = new Parcelable.Creator<LocusId>() { @NonNull diff --git a/core/java/android/content/om/OverlayInfo.java b/core/java/android/content/om/OverlayInfo.java index aabe59d18383..91424f44d5d0 100644 --- a/core/java/android/content/om/OverlayInfo.java +++ b/core/java/android/content/om/OverlayInfo.java @@ -20,6 +20,7 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; +import android.annotation.UserIdInt; import android.os.Parcel; import android.os.Parcelable; @@ -44,8 +45,9 @@ public final class OverlayInfo implements Parcelable { STATE_DISABLED, STATE_ENABLED, STATE_ENABLED_STATIC, - STATE_TARGET_UPGRADING, - STATE_OVERLAY_UPGRADING, + // @Deprecated STATE_TARGET_UPGRADING, + STATE_TARGET_IS_BEING_REPLACED, + STATE_OVERLAY_IS_BEING_REPLACED, }) /** @hide */ @Retention(RetentionPolicy.SOURCE) @@ -93,18 +95,25 @@ public final class OverlayInfo implements Parcelable { public static final int STATE_ENABLED = 3; /** - * The target package is currently being upgraded; the state will change - * once the package installation has finished. + * The target package is currently being upgraded or downgraded; 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. */ - public static final int STATE_TARGET_UPGRADING = 4; + @Deprecated + public static final int STATE_TARGET_IS_BEING_REPLACED = 4; /** - * The overlay package is currently being upgraded; the state will change - * once the package installation has finished. + * The overlay package is currently being upgraded or downgraded; the state + * will change once the package installation has finished. * @hide */ - public static final int STATE_OVERLAY_UPGRADING = 5; + public static final int STATE_OVERLAY_IS_BEING_REPLACED = 5; /** * The overlay package is currently enabled because it is marked as @@ -128,7 +137,6 @@ public final class OverlayInfo implements Parcelable { * * @hide */ - @SystemApi public final String packageName; /** @@ -136,7 +144,6 @@ public final class OverlayInfo implements Parcelable { * * @hide */ - @SystemApi public final String targetPackageName; /** @@ -144,7 +151,6 @@ public final class OverlayInfo implements Parcelable { * * @hide */ - @SystemApi public final String targetOverlayableName; /** @@ -152,7 +158,6 @@ public final class OverlayInfo implements Parcelable { * * @hide */ - @SystemApi public final String category; /** @@ -171,7 +176,6 @@ public final class OverlayInfo implements Parcelable { * User handle for which this overlay applies * @hide */ - @SystemApi public final int userId; /** @@ -236,6 +240,56 @@ public final class OverlayInfo implements Parcelable { ensureValidState(); } + /** + * Returns package name of the current overlay. + * @hide + */ + @SystemApi + @NonNull + public String getPackageName() { + return packageName; + } + + /** + * Returns the target package name of the current overlay. + * @hide + */ + @SystemApi + @Nullable + public String getTargetPackageName() { + return targetPackageName; + } + + /** + * Returns the category of the current overlay. + * @hide\ + */ + @SystemApi + @Nullable + public String getCategory() { + return category; + } + + /** + * Returns user handle for which this overlay applies to. + * @hide + */ + @SystemApi + @UserIdInt + public int getUserId() { + return userId; + } + + /** + * Returns name of the target overlayable declaration. + * @hide + */ + @SystemApi + @Nullable + public String getTargetOverlayableName() { + return targetOverlayableName; + } + private void ensureValidState() { if (packageName == null) { throw new IllegalArgumentException("packageName must not be null"); @@ -253,8 +307,8 @@ public final class OverlayInfo implements Parcelable { case STATE_DISABLED: case STATE_ENABLED: case STATE_ENABLED_STATIC: - case STATE_TARGET_UPGRADING: - case STATE_OVERLAY_UPGRADING: + case STATE_TARGET_IS_BEING_REPLACED: + case STATE_OVERLAY_IS_BEING_REPLACED: break; default: throw new IllegalArgumentException("State " + state + " is not a valid state"); @@ -333,10 +387,10 @@ public final class OverlayInfo implements Parcelable { return "STATE_ENABLED"; case STATE_ENABLED_STATIC: return "STATE_ENABLED_STATIC"; - case STATE_TARGET_UPGRADING: - return "STATE_TARGET_UPGRADING"; - case STATE_OVERLAY_UPGRADING: - return "STATE_OVERLAY_UPGRADING"; + case STATE_TARGET_IS_BEING_REPLACED: + return "STATE_TARGET_IS_BEING_REPLACED"; + case STATE_OVERLAY_IS_BEING_REPLACED: + return "STATE_OVERLAY_IS_BEING_REPLACED"; default: return "<unknown state>"; } 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/LauncherApps.java b/core/java/android/content/pm/LauncherApps.java index 954deac97d6d..037a149bfe37 100644 --- a/core/java/android/content/pm/LauncherApps.java +++ b/core/java/android/content/pm/LauncherApps.java @@ -22,6 +22,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; +import android.annotation.SystemApi; import android.annotation.SystemService; import android.annotation.TestApi; import android.annotation.UnsupportedAppUsage; @@ -782,8 +783,10 @@ public class LauncherApps { * @return an {@link AppUsageLimit} object describing the app time limit containing * the given package with the smallest time remaining, or {@code null} if none exist. * @throws SecurityException when the caller is not the recents app. + * @hide */ @Nullable + @SystemApi public LauncherApps.AppUsageLimit getAppUsageLimit(@NonNull String packageName, @NonNull UserHandle user) { try { @@ -1739,7 +1742,9 @@ public class LauncherApps { * in this class. * * @see #getAppUsageLimit(String, UserHandle) + * @hide */ + @SystemApi public static final class AppUsageLimit implements Parcelable { private final long mTotalUsageLimit; private final long mUsageRemaining; diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java index 1e6cea39b44d..a96316b3d36e 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); @@ -2152,6 +2166,7 @@ public class PackageInstaller { * Returns the set of session IDs that will be committed when this session is commited if * this session is a multi-package session. */ + @NonNull public int[] getChildSessionIds() { return childSessionIds; } diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index b190b34aa03f..f0539c493bb1 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, @@ -2990,6 +2998,7 @@ public abstract class PackageManager { * @hide */ @SystemApi + @TestApi public static final int FLAG_PERMISSION_POLICY_FIXED = 1 << 2; /** @@ -3013,6 +3022,7 @@ public abstract class PackageManager { * @hide */ @SystemApi + @TestApi public static final int FLAG_PERMISSION_SYSTEM_FIXED = 1 << 4; /** @@ -3065,15 +3075,6 @@ public abstract class PackageManager { public static final int FLAG_PERMISSION_USER_SENSITIVE_WHEN_DENIED = 1 << 9; /** - * Permission flag: The permission should not be shown in the UI. - * - * @hide - */ - @SystemApi - @TestApi - public static final int FLAG_PERMISSION_HIDDEN = 1 << 10; - - /** * Mask for all permission flags present in Android P * * @deprecated This constant does not contain useful information and should never have been @@ -3091,7 +3092,7 @@ public abstract class PackageManager { * * @hide */ - public static final int MASK_PERMISSION_FLAGS_ALL = 0x7FF; + public static final int MASK_PERMISSION_FLAGS_ALL = 0x3FF; /** * Injected activity in app that forwards user to setting activity of that app. @@ -3214,7 +3215,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 +3241,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 +3265,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 +3362,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 +3377,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 +3395,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 +3413,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 +3427,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 +3442,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 +3468,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 +3477,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 +3488,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 +3509,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 +3559,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 +3576,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 +3592,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 +3609,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 +3623,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 +3638,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 +3657,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 +3675,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 +3695,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 +3706,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 +3717,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 +3728,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 +3744,7 @@ public abstract class PackageManager { * * @hide */ + @NonNull @TestApi public abstract String getPermissionControllerPackageName(); @@ -3761,7 +3780,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 +3789,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 +3797,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. @@ -3802,7 +3821,6 @@ public abstract class PackageManager { FLAG_PERMISSION_GRANTED_BY_DEFAULT, FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED, FLAG_PERMISSION_USER_SENSITIVE_WHEN_DENIED, - FLAG_PERMISSION_HIDDEN, /* FLAG_PERMISSION_REVOKE_WHEN_REQUESED */ @@ -3880,8 +3898,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 +3920,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 +3930,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 +3947,7 @@ public abstract class PackageManager { * * @hide */ + @NonNull @UnsupportedAppUsage public Intent buildRequestPermissionsIntent(@NonNull String[] permissions) { if (ArrayUtils.isEmpty(permissions)) { @@ -3946,8 +3966,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 +3977,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 +4052,7 @@ public abstract class PackageManager { * @hide */ @UnsupportedAppUsage - public abstract int getUidForSharedUser(String sharedUserName) + public abstract int getUidForSharedUser(@NonNull String sharedUserName) throws NameNotFoundException; /** @@ -4049,6 +4071,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 +4094,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 +4145,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 +4232,7 @@ public abstract class PackageManager { * available on the system, or null if none are installed. * */ + @Nullable public abstract String[] getSystemSharedLibraryNames(); /** @@ -4296,6 +4321,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 +4332,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 +4343,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 +4371,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 +4403,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 +4423,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 +4444,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 +4500,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 +4513,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 +4529,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 +4540,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 +4572,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 +4593,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 +4610,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 +4648,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 +4683,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 +4701,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 +4737,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 +4756,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 +4776,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 +4792,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 +4813,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 +4832,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 +4853,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 +4870,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 +4889,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 +4899,7 @@ public abstract class PackageManager { * * @return Drawable Image of the icon. */ + @NonNull public abstract Drawable getDefaultActivityIcon(); /** @@ -4859,7 +4913,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 +4932,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 +4944,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 +4961,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 +4978,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 +5000,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 +5015,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 +5035,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 +5050,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 +5083,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 +5099,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 +5117,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 +5133,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 +5154,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 +5174,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 +5185,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 +5203,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 +5217,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 +5227,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 +5236,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 +5255,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 +5291,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 +5303,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 +5319,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 +5396,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 +5420,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 +5445,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 +5460,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 +5476,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 +5490,7 @@ public abstract class PackageManager { * * @hide */ + @Nullable @TestApi @SystemApi @RequiresPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL) @@ -5428,7 +5512,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 +5530,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 +5556,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 +5579,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 +5590,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 +5607,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 +5626,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 +5648,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 +5674,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 +5708,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 +5738,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 +5750,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 +5763,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 +5774,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 +5792,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 +5819,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 +5837,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 +5869,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 +5914,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 +5936,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 +5964,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 +6073,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 +6083,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 +6092,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 +6109,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 +6121,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 +6132,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 +6151,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 +6160,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 +6377,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 +6387,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 +6471,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 +6503,7 @@ public abstract class PackageManager { * @return identity that uniquely identifies current device * @hide */ + @NonNull public abstract VerifierDeviceIdentity getVerifierDeviceIdentity(); /** @@ -6437,8 +6534,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 +6545,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 +6580,7 @@ public abstract class PackageManager { } /** {@hide} */ + @NonNull @UnsupportedAppUsage public static String installStatusToString(int status) { switch (status) { @@ -6582,7 +6685,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 +6696,7 @@ public abstract class PackageManager { } /** {@hide} */ + @NonNull @UnsupportedAppUsage public static String deleteStatusToString(int status) { switch (status) { @@ -6621,6 +6726,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"; @@ -6633,7 +6739,6 @@ public abstract class PackageManager { case FLAG_PERMISSION_REVOKE_WHEN_REQUESTED: return "REVOKE_WHEN_REQUESTED"; case FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED: return "USER_SENSITIVE_WHEN_GRANTED"; case FLAG_PERMISSION_USER_SENSITIVE_WHEN_DENIED: return "USER_SENSITIVE_WHEN_DENIED"; - case FLAG_PERMISSION_HIDDEN: return "HIDDEN"; default: return Integer.toString(flag); } } @@ -6668,8 +6773,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 +6800,7 @@ public abstract class PackageManager { * @see {@link android.content.Intent#ACTION_INSTANT_APP_RESOLVER_SETTINGS} * @hide */ + @Nullable @SystemApi public abstract ComponentName getInstantAppResolverSettingsComponent(); @@ -6705,6 +6811,7 @@ public abstract class PackageManager { * @see {@link android.content.Intent#ACTION_INSTALL_INSTANT_APP_PACKAGE} * @hide */ + @Nullable @SystemApi public abstract ComponentName getInstantAppInstallerComponent(); @@ -6714,7 +6821,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 +6866,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 +6946,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 +6971,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 +6981,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 +7014,7 @@ public abstract class PackageManager { * * @hide */ + @Nullable public String getAppPredictionServicePackageName() { throw new UnsupportedOperationException( "getAppPredictionServicePackageName not implemented in subclass"); @@ -6903,6 +7025,7 @@ public abstract class PackageManager { * * @hide */ + @Nullable public String getSystemCaptionsServicePackageName() { throw new UnsupportedOperationException( "getSystemCaptionsServicePackageName not implemented in subclass"); @@ -6928,7 +7051,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..93bc6d7eb583 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -2547,46 +2547,26 @@ public class PackageParser { // STOPSHIP(b/112545973): remove once feature enabled by default if (!StorageManager.hasIsolatedStorage()) { if ("android".equals(pkg.packageName)) { - final ArraySet<String> newGroups = new ArraySet<>(); - newGroups.add(android.Manifest.permission_group.MEDIA_AURAL); - newGroups.add(android.Manifest.permission_group.MEDIA_VISUAL); - - for (int i = pkg.permissionGroups.size() - 1; i >= 0; i--) { - final PermissionGroup pg = pkg.permissionGroups.get(i); - if (newGroups.contains(pg.info.name)) { - pkg.permissionGroups.remove(i); - } - } - final ArraySet<String> newPermissions = new ArraySet<>(); - newPermissions.add(android.Manifest.permission.READ_MEDIA_AUDIO); - newPermissions.add(android.Manifest.permission.READ_MEDIA_VIDEO); - newPermissions.add(android.Manifest.permission.READ_MEDIA_IMAGES); newPermissions.add(android.Manifest.permission.ACCESS_MEDIA_LOCATION); newPermissions.add(android.Manifest.permission.WRITE_OBB); - final ArraySet<String> removedPermissions = new ArraySet<>(); - removedPermissions.add(android.Manifest.permission.READ_EXTERNAL_STORAGE); - removedPermissions.add(android.Manifest.permission.WRITE_EXTERNAL_STORAGE); - for (int i = pkg.permissions.size() - 1; i >= 0; i--) { final Permission p = pkg.permissions.get(i); if (newPermissions.contains(p.info.name)) { pkg.permissions.remove(i); - } else if (removedPermissions.contains(p.info.name)) { - p.info.flags &= ~PermissionInfo.FLAG_REMOVED; } } } } else { if (FORCE_AUDIO_PACKAGES.contains(pkg.packageName)) { - pkg.requestedPermissions.add(android.Manifest.permission.READ_MEDIA_AUDIO); + pkg.requestedPermissions.add(android.Manifest.permission.READ_EXTERNAL_STORAGE); } if (FORCE_VIDEO_PACKAGES.contains(pkg.packageName)) { - pkg.requestedPermissions.add(android.Manifest.permission.READ_MEDIA_VIDEO); + pkg.requestedPermissions.add(android.Manifest.permission.READ_EXTERNAL_STORAGE); } if (FORCE_IMAGES_PACKAGES.contains(pkg.packageName)) { - pkg.requestedPermissions.add(android.Manifest.permission.READ_MEDIA_IMAGES); + pkg.requestedPermissions.add(android.Manifest.permission.READ_EXTERNAL_STORAGE); } } @@ -3689,6 +3669,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); @@ -4796,7 +4782,7 @@ public class PackageParser { // except for watches which always supported 1:1. minAspectRatio = owner.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.Q ? 0 - : mCallback.hasFeature(FEATURE_WATCH) + : (mCallback != null && mCallback.hasFeature(FEATURE_WATCH)) ? DEFAULT_PRE_Q_MIN_ASPECT_RATIO_WATCH : DEFAULT_PRE_Q_MIN_ASPECT_RATIO; } @@ -8373,71 +8359,36 @@ public class PackageParser { } // TODO(b/129261524): Clean up API - public static PackageInfo generatePackageInfoFromApex(File apexFile, boolean collectCerts) + /** + * PackageInfo parser specifically for apex files. + * NOTE: It will collect certificates + * + * @param apexFile + * @return PackageInfo + * @throws PackageParserException + */ + public static PackageInfo generatePackageInfoFromApex(File apexFile, int flags) throws PackageParserException { - PackageInfo pi = new PackageInfo(); - int parseFlags = 0; - if (collectCerts) { - parseFlags |= PARSE_COLLECT_CERTIFICATES; - try { - if (apexFile.getCanonicalPath().startsWith("/system")) { - // Don't need verify the APK integrity of APEXes on /system, just like - // we don't do that for APKs. - // TODO(b/126514108): we may be able to do this for APEXes on /data as well. - parseFlags |= PARSE_IS_SYSTEM_DIR; - } - } catch (IOException e) { - throw new PackageParserException(INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION, - "Failed to get path for " + apexFile.getPath(), e); - } - } - - PackageParser.ApkLite apk = PackageParser.parseApkLite(apexFile, parseFlags); - - // Properly fill in the ApplicationInfo with data from AndroidManifest - // Add ApplicationInfo to the PackageInfo. - // TODO(b/129267599) - ApplicationInfo ai = new ApplicationInfo(); - ai.packageName = apk.packageName; - ai.sourceDir = apexFile.getPath(); - ai.flags = ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_INSTALLED; - ai.enabled = true; - ai.minSdkVersion = apk.minSdkVersion; - ai.targetSdkVersion = apk.targetSdkVersion; - ai.targetSandboxVersion = PARSE_DEFAULT_TARGET_SANDBOX; - ai.setVersionCode(apk.getLongVersionCode()); - - pi.packageName = apk.packageName; - pi.splitNames = new String[]{apk.splitName}; - pi.setLongVersionCode(apk.getLongVersionCode()); - pi.applicationInfo = ai; - pi.coreApp = apk.coreApp; - - - if (collectCerts) { - if (apk.signingDetails.hasPastSigningCertificates()) { - // Package has included signing certificate rotation information. Return - // the oldest cert so that programmatic checks keep working even if unaware - // of key rotation. - pi.signatures = new Signature[1]; - pi.signatures[0] = apk.signingDetails.pastSigningCertificates[0]; - } else if (apk.signingDetails.hasSignatures()) { - // otherwise keep old behavior - int numberOfSigs = apk.signingDetails.signatures.length; - pi.signatures = new Signature[numberOfSigs]; - System.arraycopy(apk.signingDetails.signatures, 0, pi.signatures, 0, - numberOfSigs); - } + PackageParser pp = new PackageParser(); + final Package p = pp.parsePackage(apexFile, flags, false); + PackageUserState state = new PackageUserState(); + PackageInfo pi = generatePackageInfo(p, EmptyArray.INT, flags, 0, 0, + Collections.emptySet(), state); + + pi.applicationInfo.sourceDir = apexFile.getPath(); + pi.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_INSTALLED; + pi.isApex = true; - if (apk.signingDetails != SigningDetails.UNKNOWN) { + // Collect certificates + if ((flags & PackageManager.GET_SIGNING_CERTIFICATES) != 0) { + collectCertificates(p, apexFile, false); + if (p.mSigningDetails != SigningDetails.UNKNOWN) { // only return a valid SigningInfo if there is signing information to report - pi.signingInfo = new SigningInfo(apk.signingDetails); + pi.signingInfo = new SigningInfo(p.mSigningDetails); } else { pi.signingInfo = null; } } - - pi.isApex = true; return pi; } } 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/TranslatingCursor.java b/core/java/android/database/TranslatingCursor.java index d9165b4c1008..35cbdc764819 100644 --- a/core/java/android/database/TranslatingCursor.java +++ b/core/java/android/database/TranslatingCursor.java @@ -22,6 +22,7 @@ import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteQueryBuilder; import android.net.Uri; import android.os.CancellationSignal; +import android.util.ArraySet; import com.android.internal.util.ArrayUtils; @@ -59,7 +60,7 @@ public class TranslatingCursor extends CrossProcessCursorWrapper { private final boolean mDropLast; private final int mAuxiliaryColumnIndex; - private final int[] mTranslateColumnIndices; + private final ArraySet<Integer> mTranslateColumnIndices; public TranslatingCursor(@NonNull Cursor cursor, @NonNull Config config, @NonNull Translator translator, boolean dropLast) { @@ -70,9 +71,12 @@ public class TranslatingCursor extends CrossProcessCursorWrapper { mDropLast = dropLast; mAuxiliaryColumnIndex = cursor.getColumnIndexOrThrow(config.auxiliaryColumn); - mTranslateColumnIndices = new int[config.translateColumns.length]; - for (int i = 0; i < mTranslateColumnIndices.length; ++i) { - mTranslateColumnIndices[i] = cursor.getColumnIndex(config.translateColumns[i]); + mTranslateColumnIndices = new ArraySet<>(); + for (int i = 0; i < cursor.getColumnCount(); ++i) { + String columnName = cursor.getColumnName(i); + if (ArrayUtils.contains(config.translateColumns, columnName)) { + mTranslateColumnIndices.add(i); + } } } 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/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java index c39796b881ca..6a2d8d8fadbf 100644 --- a/core/java/android/hardware/camera2/CameraCharacteristics.java +++ b/core/java/android/hardware/camera2/CameraCharacteristics.java @@ -2680,10 +2680,12 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * MAXIMUM resolutions and anything smaller from the list given by * {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputSizes } are * guaranteed to work. - * The mandatory stream combination array will be {@code null} in case the device is a - * physical camera not independently exposed in - * {@link android.hardware.camera2.CameraManager#getCameraIdList } or is not backward - * compatible.</p> + * For a physical camera not independently exposed in + * {@link android.hardware.camera2.CameraManager#getCameraIdList }, the mandatory stream + * combinations for that physical camera Id are also generated, so that the application can + * configure them as physical streams via the logical camera. + * The mandatory stream combination array will be {@code null} in case the device is not + * backward compatible.</p> * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p> * <p><b>Limited capability</b> - * Present on all camera devices that report being at least {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED HARDWARE_LEVEL_LIMITED} devices in the @@ -3894,6 +3896,8 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * <p>In both cases, all images generated for a particular capture request still carry the same * timestamps, so that they can be used to look up the matching frame number and * onCaptureStarted callback.</p> + * <p>This tag is only applicable if the logical camera device supports concurrent physical + * streams from different physical cameras.</p> * <p><b>Possible values:</b> * <ul> * <li>{@link #LOGICAL_MULTI_CAMERA_SENSOR_SYNC_TYPE_APPROXIMATE APPROXIMATE}</li> diff --git a/core/java/android/hardware/camera2/CameraManager.java b/core/java/android/hardware/camera2/CameraManager.java index d5d25c5c869b..b0142ea981de 100644 --- a/core/java/android/hardware/camera2/CameraManager.java +++ b/core/java/android/hardware/camera2/CameraManager.java @@ -314,12 +314,10 @@ public final class CameraManager { } else { // Normal path: Get the camera characteristics directly from the camera service CameraMetadataNative info = cameraService.getCameraCharacteristics(cameraId); - if (!isHiddenPhysicalCamera(cameraId)) { - try { - info.setCameraId(Integer.parseInt(cameraId)); - } catch (NumberFormatException e) { - Log.e(TAG, "Failed to parse camera Id " + cameraId + " to integer"); - } + try { + info.setCameraId(Integer.parseInt(cameraId)); + } catch (NumberFormatException e) { + Log.e(TAG, "Failed to parse camera Id " + cameraId + " to integer"); } info.setDisplaySize(displaySize); diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java index a3e561c960ef..9e0ee5884199 100644 --- a/core/java/android/hardware/camera2/CameraMetadata.java +++ b/core/java/android/hardware/camera2/CameraMetadata.java @@ -825,14 +825,23 @@ public abstract class CameraMetadata<TKey> { public static final int REQUEST_AVAILABLE_CAPABILITIES_MOTION_TRACKING = 10; /** - * <p>The camera device is a logical camera backed by two or more physical cameras. In - * API level 28, the physical cameras must also be exposed to the application via - * {@link android.hardware.camera2.CameraManager#getCameraIdList }. Starting from API - * level 29, some or all physical cameras may not be independently exposed to the - * application, in which case the physical camera IDs will not be available in - * {@link android.hardware.camera2.CameraManager#getCameraIdList }. But the application - * can still query the physical cameras' characteristics by calling - * {@link android.hardware.camera2.CameraManager#getCameraCharacteristics }.</p> + * <p>The camera device is a logical camera backed by two or more physical cameras.</p> + * <p>In API level 28, the physical cameras must also be exposed to the application via + * {@link android.hardware.camera2.CameraManager#getCameraIdList }.</p> + * <p>Starting from API level 29, some or all physical cameras may not be independently + * exposed to the application, in which case the physical camera IDs will not be + * available in {@link android.hardware.camera2.CameraManager#getCameraIdList }. But the + * application can still query the physical cameras' characteristics by calling + * {@link android.hardware.camera2.CameraManager#getCameraCharacteristics }. Additionally, + * if a physical camera is hidden from camera ID list, the mandatory stream combinations + * for that physical camera must be supported through the logical camera using physical + * streams.</p> + * <p>Combinations of logical and physical streams, or physical streams from different + * physical cameras are not guaranteed. However, if the camera device supports + * {@link CameraDevice#isSessionConfigurationSupported }, + * application must be able to query whether a stream combination involving physical + * streams is supported by calling + * {@link CameraDevice#isSessionConfigurationSupported }.</p> * <p>Camera application shouldn't assume that there are at most 1 rear camera and 1 front * camera in the system. For an application that switches between front and back cameras, * the recommendation is to switch between the first rear camera and the first front @@ -857,24 +866,6 @@ public abstract class CameraMetadata<TKey> { * the same.</li> * <li>The logical camera must be LIMITED or higher device.</li> * </ul> - * <p>Both the logical camera device and its underlying physical devices support the - * mandatory stream combinations required for their device levels.</p> - * <p>Additionally, for each guaranteed stream combination, the logical camera supports:</p> - * <ul> - * <li>For each guaranteed stream combination, the logical camera supports replacing one - * logical {@link android.graphics.ImageFormat#YUV_420_888 YUV_420_888} - * or raw stream with two physical streams of the same size and format, each from a - * separate physical camera, given that the size and format are supported by both - * physical cameras.</li> - * <li>If the logical camera doesn't advertise RAW capability, but the underlying physical - * cameras do, the logical camera will support guaranteed stream combinations for RAW - * capability, except that the RAW streams will be physical streams, each from a separate - * physical camera. This is usually the case when the physical cameras have different - * sensor sizes.</li> - * </ul> - * <p>Using physical streams in place of a logical stream of the same size and format will - * not slow down the frame rate of the capture, as long as the minimum frame duration - * of the physical and logical streams are the same.</p> * <p>A logical camera device's dynamic metadata may contain * {@link CaptureResult#LOGICAL_MULTI_CAMERA_ACTIVE_PHYSICAL_ID android.logicalMultiCamera.activePhysicalId} to notify the application of the current * active physical camera Id. An active physical camera is the physical camera from which diff --git a/core/java/android/hardware/camera2/CaptureFailure.java b/core/java/android/hardware/camera2/CaptureFailure.java index cd2bc5f943e7..20ca4a338f01 100644 --- a/core/java/android/hardware/camera2/CaptureFailure.java +++ b/core/java/android/hardware/camera2/CaptureFailure.java @@ -17,6 +17,7 @@ package android.hardware.camera2; import android.annotation.IntDef; import android.annotation.NonNull; +import android.annotation.Nullable; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -61,17 +62,19 @@ public class CaptureFailure { private final boolean mDropped; private final int mSequenceId; private final long mFrameNumber; + private final String mErrorPhysicalCameraId; /** * @hide */ public CaptureFailure(CaptureRequest request, int reason, - boolean dropped, int sequenceId, long frameNumber) { + boolean dropped, int sequenceId, long frameNumber, String errorPhysicalCameraId) { mRequest = request; mReason = reason; mDropped = dropped; mSequenceId = sequenceId; mFrameNumber = frameNumber; + mErrorPhysicalCameraId = errorPhysicalCameraId; } /** @@ -155,4 +158,17 @@ public class CaptureFailure { public int getSequenceId() { return mSequenceId; } + + /** + * The physical camera device ID in case the capture failure comes from a {@link CaptureRequest} + * with configured physical camera streams for a logical camera. + * + * @return String The physical camera device ID of the respective failing output. + * {@code null} in case the capture request has no associated physical camera device. + * @see CaptureRequest.Builder#setPhysicalCameraKey + * @see android.hardware.camera2.params.OutputConfiguration#setPhysicalCameraId + */ + public @Nullable String getPhysicalCameraId() { + return mErrorPhysicalCameraId; + } } diff --git a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java index 57b608f0fd84..fc12b090b2f3 100644 --- a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java +++ b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java @@ -2232,6 +2232,7 @@ public class CameraDeviceImpl extends CameraDevice final int requestId = resultExtras.getRequestId(); final int subsequenceId = resultExtras.getSubsequenceId(); final long frameNumber = resultExtras.getFrameNumber(); + final String errorPhysicalCameraId = resultExtras.getErrorPhysicalCameraId(); final CaptureCallbackHolder holder = CameraDeviceImpl.this.mCaptureCallbackMap.get(requestId); @@ -2287,7 +2288,8 @@ public class CameraDeviceImpl extends CameraDevice reason, /*dropped*/ mayHaveBuffers, requestId, - frameNumber); + frameNumber, + errorPhysicalCameraId); failureDispatch = new Runnable() { @Override diff --git a/core/java/android/hardware/camera2/impl/CaptureResultExtras.java b/core/java/android/hardware/camera2/impl/CaptureResultExtras.java index edc3d91eaf12..1ff5bd562f2e 100644 --- a/core/java/android/hardware/camera2/impl/CaptureResultExtras.java +++ b/core/java/android/hardware/camera2/impl/CaptureResultExtras.java @@ -29,6 +29,7 @@ public class CaptureResultExtras implements Parcelable { private long frameNumber; private int partialResultCount; private int errorStreamId; + private String errorPhysicalCameraId; public static final @android.annotation.NonNull Parcelable.Creator<CaptureResultExtras> CREATOR = new Parcelable.Creator<CaptureResultExtras>() { @@ -49,7 +50,8 @@ public class CaptureResultExtras implements Parcelable { public CaptureResultExtras(int requestId, int subsequenceId, int afTriggerId, int precaptureTriggerId, long frameNumber, - int partialResultCount, int errorStreamId) { + int partialResultCount, int errorStreamId, + String errorPhysicalCameraId) { this.requestId = requestId; this.subsequenceId = subsequenceId; this.afTriggerId = afTriggerId; @@ -57,6 +59,7 @@ public class CaptureResultExtras implements Parcelable { this.frameNumber = frameNumber; this.partialResultCount = partialResultCount; this.errorStreamId = errorStreamId; + this.errorPhysicalCameraId = errorPhysicalCameraId; } @Override @@ -73,6 +76,12 @@ public class CaptureResultExtras implements Parcelable { dest.writeLong(frameNumber); dest.writeInt(partialResultCount); dest.writeInt(errorStreamId); + if ((errorPhysicalCameraId != null) && !errorPhysicalCameraId.isEmpty()) { + dest.writeBoolean(true); + dest.writeString(errorPhysicalCameraId); + } else { + dest.writeBoolean(false); + } } public void readFromParcel(Parcel in) { @@ -83,6 +92,14 @@ public class CaptureResultExtras implements Parcelable { frameNumber = in.readLong(); partialResultCount = in.readInt(); errorStreamId = in.readInt(); + boolean errorPhysicalCameraIdPresent = in.readBoolean(); + if (errorPhysicalCameraIdPresent) { + errorPhysicalCameraId = in.readString(); + } + } + + public String getErrorPhysicalCameraId() { + return errorPhysicalCameraId; } public int getRequestId() { diff --git a/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java b/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java index aff09f2a45f2..908ed0913ffc 100644 --- a/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java +++ b/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java @@ -109,11 +109,11 @@ public class LegacyCameraDevice implements AutoCloseable { } if (holder == null) { return new CaptureResultExtras(ILLEGAL_VALUE, ILLEGAL_VALUE, ILLEGAL_VALUE, - ILLEGAL_VALUE, ILLEGAL_VALUE, ILLEGAL_VALUE, ILLEGAL_VALUE); + ILLEGAL_VALUE, ILLEGAL_VALUE, ILLEGAL_VALUE, ILLEGAL_VALUE, null); } return new CaptureResultExtras(holder.getRequestId(), holder.getSubsequeceId(), /*afTriggerId*/0, /*precaptureTriggerId*/0, holder.getFrameNumber(), - /*partialResultCount*/1, errorStreamId); + /*partialResultCount*/1, errorStreamId, null); } /** diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java index 4a64128f146b..6ba4a30abe22 100644 --- a/core/java/android/net/ConnectivityManager.java +++ b/core/java/android/net/ConnectivityManager.java @@ -3234,7 +3234,7 @@ public class ConnectivityManager { * * @hide */ - public void onPreCheck(Network network) {} + public void onPreCheck(@NonNull Network network) {} /** * Called when the framework connects and has declared a new network ready for use. @@ -3247,8 +3247,9 @@ public class ConnectivityManager { * @param blocked Whether access to the {@link Network} is blocked due to system policy. * @hide */ - public void onAvailable(Network network, NetworkCapabilities networkCapabilities, - LinkProperties linkProperties, boolean blocked) { + public void onAvailable(@NonNull Network network, + @NonNull NetworkCapabilities networkCapabilities, + @NonNull LinkProperties linkProperties, boolean blocked) { // Internally only this method is called when a new network is available, and // it calls the callback in the same way and order that older versions used // to call so as not to change the behavior. @@ -3272,7 +3273,7 @@ public class ConnectivityManager { * * @param network The {@link Network} of the satisfying network. */ - public void onAvailable(Network network) {} + public void onAvailable(@NonNull Network network) {} /** * Called when the network is about to be disconnected. Often paired with an @@ -3288,7 +3289,7 @@ public class ConnectivityManager { * network connected. Note that the network may suffer a * hard loss at any time. */ - public void onLosing(Network network, int maxMsToLive) {} + public void onLosing(@NonNull Network network, int maxMsToLive) {} /** * Called when the framework has a hard loss of the network or when the @@ -3296,7 +3297,7 @@ public class ConnectivityManager { * * @param network The {@link Network} lost. */ - public void onLost(Network network) {} + public void onLost(@NonNull Network network) {} /** * Called if no network is found in the timeout time specified in @@ -3316,8 +3317,8 @@ public class ConnectivityManager { * @param networkCapabilities The new {@link android.net.NetworkCapabilities} for this * network. */ - public void onCapabilitiesChanged(Network network, - NetworkCapabilities networkCapabilities) {} + public void onCapabilitiesChanged(@NonNull Network network, + @NonNull NetworkCapabilities networkCapabilities) {} /** * Called when the network the framework connected to for this request @@ -3326,7 +3327,8 @@ public class ConnectivityManager { * @param network The {@link Network} whose link properties have changed. * @param linkProperties The new {@link LinkProperties} for this network. */ - public void onLinkPropertiesChanged(Network network, LinkProperties linkProperties) {} + public void onLinkPropertiesChanged(@NonNull Network network, + @NonNull LinkProperties linkProperties) {} /** * Called when the network the framework connected to for this request @@ -3337,7 +3339,7 @@ public class ConnectivityManager { * a tunnel, etc. * @hide */ - public void onNetworkSuspended(Network network) {} + public void onNetworkSuspended(@NonNull Network network) {} /** * Called when the network the framework connected to for this request @@ -3345,7 +3347,7 @@ public class ConnectivityManager { * preceded by a matching {@link NetworkCallback#onNetworkSuspended} call. * @hide */ - public void onNetworkResumed(Network network) {} + public void onNetworkResumed(@NonNull Network network) {} /** * Called when access to the specified network is blocked or unblocked. diff --git a/core/java/android/net/DnsResolver.java b/core/java/android/net/DnsResolver.java index 59802514c7a3..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 @@ -205,26 +216,32 @@ public final class DnsResolver { if (cancellationSignal != null && cancellationSignal.isCanceled()) { return; } + final Object lock = new Object(); final FileDescriptor queryfd; try { 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); - registerFDListener(executor, queryfd, callback); + 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 @@ -242,40 +259,187 @@ public final class DnsResolver { if (cancellationSignal != null && cancellationSignal.isCanceled()) { return; } + final Object lock = new Object(); final FileDescriptor queryfd; try { 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(); + } + + @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); - maybeAddCancellationSignal(cancellationSignal, queryfd); - registerFDListener(executor, queryfd, 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, - @NonNull FileDescriptor queryfd, @NonNull AnswerCallback<T> answerCallback) { + @NonNull FileDescriptor queryfd, @NonNull AnswerCallback<T> answerCallback, + @Nullable CancellationSignal cancellationSignal, @NonNull Object lock) { Looper.getMainLooper().getQueue().addOnFileDescriptorEventListener( queryfd, FD_EVENTS, (fd, events) -> { executor.execute(() -> { - byte[] answerbuf = null; - try { - answerbuf = resNetworkResult(fd); - } catch (ErrnoException e) { - Log.e(TAG, "resNetworkResult:" + e.toString()); - answerCallback.onQueryException(e); - return; - } - - try { - answerCallback.onAnswer( - answerCallback.parser.parse(answerbuf)); - } catch (ParseException e) { - answerCallback.onParseException(e); + synchronized (lock) { + if (cancellationSignal != null && cancellationSignal.isCanceled()) { + return; + } + byte[] answerbuf = null; + try { + answerbuf = resNetworkResult(fd); // Closes fd, marks it invalid. + } catch (ErrnoException e) { + Log.e(TAG, "resNetworkResult:" + e.toString()); + answerCallback.onQueryException(e); + return; + } + + try { + answerCallback.onAnswer( + answerCallback.parser.parse(answerbuf)); + } catch (ParseException e) { + answerCallback.onParseException(e); + } } }); // Unregister this fd listener @@ -283,15 +447,51 @@ public final class DnsResolver { }); } - private void maybeAddCancellationSignal(@Nullable CancellationSignal cancellationSignal, - @NonNull FileDescriptor queryfd) { - if (cancellationSignal == null) return; - cancellationSignal.setOnCancelListener( - () -> { - Looper.getMainLooper().getQueue() - .removeOnFileDescriptorEventListener(queryfd); - resNetworkCancel(queryfd); - }); + 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) { + cancellationSignal.setOnCancelListener(() -> { + synchronized (lock) { + 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 { diff --git a/core/java/android/net/IpPrefix.java b/core/java/android/net/IpPrefix.java index 402bffdc2a97..8cfe6df678c7 100644 --- a/core/java/android/net/IpPrefix.java +++ b/core/java/android/net/IpPrefix.java @@ -16,6 +16,7 @@ package android.net; +import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.SystemApi; import android.annotation.TestApi; @@ -71,7 +72,7 @@ public final class IpPrefix implements Parcelable { * * @hide */ - public IpPrefix(@NonNull byte[] address, int prefixLength) { + public IpPrefix(@NonNull byte[] address, @IntRange(from = 0, to = 128) int prefixLength) { this.address = address.clone(); this.prefixLength = prefixLength; checkAndMaskAddressAndPrefixLength(); @@ -88,7 +89,7 @@ public final class IpPrefix implements Parcelable { */ @SystemApi @TestApi - public IpPrefix(@NonNull InetAddress address, int prefixLength) { + public IpPrefix(@NonNull InetAddress address, @IntRange(from = 0, to = 128) int prefixLength) { // We don't reuse the (byte[], int) constructor because it calls clone() on the byte array, // which is unnecessary because getAddress() already returns a clone. this.address = address.getAddress(); @@ -150,13 +151,13 @@ public final class IpPrefix implements Parcelable { * * @return the address in the form of a byte array. */ - public InetAddress getAddress() { + public @NonNull InetAddress getAddress() { try { return InetAddress.getByAddress(address); } catch (UnknownHostException e) { // Cannot happen. InetAddress.getByAddress can only throw an exception if the byte // array is the wrong length, but we check that in the constructor. - return null; + throw new IllegalArgumentException("Address is invalid"); } } @@ -166,7 +167,7 @@ public final class IpPrefix implements Parcelable { * * @return the address in the form of a byte array. */ - public byte[] getRawAddress() { + public @NonNull byte[] getRawAddress() { return address.clone(); } @@ -175,6 +176,7 @@ public final class IpPrefix implements Parcelable { * * @return the prefix length. */ + @IntRange(from = 0, to = 128) public int getPrefixLength() { return prefixLength; } @@ -183,10 +185,10 @@ public final class IpPrefix implements Parcelable { * Determines whether the prefix contains the specified address. * * @param address An {@link InetAddress} to test. - * @return {@code true} if the prefix covers the given address. + * @return {@code true} if the prefix covers the given address. {@code false} otherwise. */ - public boolean contains(InetAddress address) { - byte[] addrBytes = (address == null) ? null : address.getAddress(); + public boolean contains(@NonNull InetAddress address) { + byte[] addrBytes = address.getAddress(); if (addrBytes == null || addrBytes.length != this.address.length) { return false; } @@ -201,7 +203,7 @@ public final class IpPrefix implements Parcelable { * @param otherPrefix the prefix to test * @hide */ - public boolean containsPrefix(IpPrefix otherPrefix) { + public boolean containsPrefix(@NonNull IpPrefix otherPrefix) { if (otherPrefix.getPrefixLength() < prefixLength) return false; final byte[] otherAddress = otherPrefix.getRawAddress(); NetworkUtils.maskRawAddress(otherAddress, prefixLength); diff --git a/core/java/android/net/LinkAddress.java b/core/java/android/net/LinkAddress.java index 333603f3a0f2..93dd2e4d7717 100644 --- a/core/java/android/net/LinkAddress.java +++ b/core/java/android/net/LinkAddress.java @@ -25,6 +25,7 @@ import static android.system.OsConstants.RT_SCOPE_LINK; import static android.system.OsConstants.RT_SCOPE_SITE; import static android.system.OsConstants.RT_SCOPE_UNIVERSE; +import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; @@ -170,7 +171,7 @@ public class LinkAddress implements Parcelable { * Constructs a new {@code LinkAddress} from an {@code InetAddress} and prefix length, with * the specified flags and scope. Flags and scope are not checked for validity. * @param address The IP address. - * @param prefixLength The prefix length. + * @param prefixLength The prefix length. Must be >= 0 and <= (32 or 128) (IPv4 or IPv6). * @param flags A bitmask of {@code IFA_F_*} values representing properties of the address. * @param scope An integer defining the scope in which the address is unique (e.g., * {@link OsConstants#RT_SCOPE_LINK} or {@link OsConstants#RT_SCOPE_SITE}). @@ -178,7 +179,8 @@ public class LinkAddress implements Parcelable { */ @SystemApi @TestApi - public LinkAddress(InetAddress address, int prefixLength, int flags, int scope) { + public LinkAddress(@NonNull InetAddress address, @IntRange(from = 0, to = 128) int prefixLength, + int flags, int scope) { init(address, prefixLength, flags, scope); } @@ -186,12 +188,13 @@ public class LinkAddress implements Parcelable { * Constructs a new {@code LinkAddress} from an {@code InetAddress} and a prefix length. * The flags are set to zero and the scope is determined from the address. * @param address The IP address. - * @param prefixLength The prefix length. + * @param prefixLength The prefix length. Must be >= 0 and <= (32 or 128) (IPv4 or IPv6). * @hide */ @SystemApi @TestApi - public LinkAddress(@NonNull InetAddress address, int prefixLength) { + public LinkAddress(@NonNull InetAddress address, + @IntRange(from = 0, to = 128) int prefixLength) { this(address, prefixLength, 0, 0); this.scope = scopeForUnicastAddress(address); } @@ -202,7 +205,7 @@ public class LinkAddress implements Parcelable { * @param interfaceAddress The interface address. * @hide */ - public LinkAddress(InterfaceAddress interfaceAddress) { + public LinkAddress(@NonNull InterfaceAddress interfaceAddress) { this(interfaceAddress.getAddress(), interfaceAddress.getNetworkPrefixLength()); } @@ -306,6 +309,7 @@ public class LinkAddress implements Parcelable { /** * Returns the prefix length of this {@code LinkAddress}. */ + @IntRange(from = 0, to = 128) public int getPrefixLength() { return prefixLength; } @@ -316,6 +320,7 @@ public class LinkAddress implements Parcelable { * @hide */ @UnsupportedAppUsage + @IntRange(from = 0, to = 128) public int getNetworkPrefixLength() { return getPrefixLength(); } diff --git a/core/java/android/net/LinkProperties.java b/core/java/android/net/LinkProperties.java index d5ca6642a3c3..d3f48acdd40e 100644 --- a/core/java/android/net/LinkProperties.java +++ b/core/java/android/net/LinkProperties.java @@ -316,9 +316,6 @@ public final class LinkProperties implements Parcelable { @SystemApi @TestApi public boolean removeLinkAddress(@NonNull LinkAddress toRemove) { - if (toRemove == null) { - return false; - } int i = findLinkAddressIndex(toRemove); if (i >= 0) { mLinkAddresses.remove(i); @@ -391,10 +388,7 @@ public final class LinkProperties implements Parcelable { @TestApi @SystemApi public boolean removeDnsServer(@NonNull InetAddress dnsServer) { - if (dnsServer != null) { - return mDnses.remove(dnsServer); - } - return false; + return mDnses.remove(dnsServer); } /** diff --git a/core/java/android/net/NetworkCapabilities.aidl b/core/java/android/net/NetworkCapabilities.aidl index cd7d71cad978..01d328605de4 100644 --- a/core/java/android/net/NetworkCapabilities.aidl +++ b/core/java/android/net/NetworkCapabilities.aidl @@ -17,5 +17,5 @@ package android.net; -parcelable NetworkCapabilities; +@JavaOnlyStableParcelable parcelable NetworkCapabilities; diff --git a/core/java/android/net/NetworkRequest.java b/core/java/android/net/NetworkRequest.java index 51cbed48e021..4270740cc722 100644 --- a/core/java/android/net/NetworkRequest.java +++ b/core/java/android/net/NetworkRequest.java @@ -17,6 +17,7 @@ package android.net; import android.annotation.NonNull; +import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.annotation.UnsupportedAppUsage; import android.net.NetworkCapabilities.NetCapability; @@ -343,10 +344,14 @@ public class NetworkRequest implements Parcelable { * current value. A value of {@code SIGNAL_STRENGTH_UNSPECIFIED} means no value when * received and has no effect when requesting a callback. * + * <p>This method requires the caller to hold the + * {@link android.Manifest.permission#NETWORK_SIGNAL_STRENGTH_WAKEUP} permission + * * @param signalStrength the bearer-specific signal strength. * @hide */ @SystemApi + @RequiresPermission(android.Manifest.permission.NETWORK_SIGNAL_STRENGTH_WAKEUP) public @NonNull Builder setSignalStrength(int signalStrength) { mNetworkCapabilities.setSignalStrength(signalStrength); return this; diff --git a/core/java/android/net/RouteInfo.java b/core/java/android/net/RouteInfo.java index b0239c839348..52d3fc48a3a5 100644 --- a/core/java/android/net/RouteInfo.java +++ b/core/java/android/net/RouteInfo.java @@ -16,6 +16,8 @@ package android.net; +import android.annotation.IntDef; +import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; import android.annotation.TestApi; @@ -24,6 +26,8 @@ import android.os.Build; import android.os.Parcel; import android.os.Parcelable; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.net.Inet4Address; import java.net.Inet6Address; import java.net.InetAddress; @@ -51,20 +55,32 @@ import java.util.Objects; * (IPv4 or IPv6). */ public final class RouteInfo implements Parcelable { + /** @hide */ + @IntDef(value = { + RTN_UNICAST, + RTN_UNREACHABLE, + RTN_THROW, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface RouteType {} + /** * The IP destination address for this route. */ + @NonNull private final IpPrefix mDestination; /** * The gateway address for this route. */ @UnsupportedAppUsage + @Nullable private final InetAddress mGateway; /** * The interface for this route. */ + @Nullable private final String mInterface; @@ -108,13 +124,14 @@ public final class RouteInfo implements Parcelable { * @param destination the destination prefix * @param gateway the IP address to route packets through * @param iface the interface name to send packets on + * @param type the type of this route * * @hide */ @SystemApi @TestApi public RouteInfo(@Nullable IpPrefix destination, @Nullable InetAddress gateway, - @Nullable String iface, int type) { + @Nullable String iface, @RouteType int type) { switch (type) { case RTN_UNICAST: case RTN_UNREACHABLE: @@ -173,10 +190,24 @@ public final class RouteInfo implements Parcelable { } /** - * @hide + * Constructs a {@code RouteInfo} object. + * + * If destination is null, then gateway must be specified and the + * constructed route is either the IPv4 default route <code>0.0.0.0</code> + * if the gateway is an instance of {@link Inet4Address}, or the IPv6 default + * route <code>::/0</code> if gateway is an instance of {@link Inet6Address}. + * <p> + * Destination and gateway may not both be null. + * + * @param destination the destination address and prefix in an {@link IpPrefix} + * @param gateway the {@link InetAddress} to route packets through + * @param iface the interface name to send packets on + * + * @hide */ @UnsupportedAppUsage - public RouteInfo(IpPrefix destination, InetAddress gateway, String iface) { + public RouteInfo(@Nullable IpPrefix destination, @Nullable InetAddress gateway, + @Nullable String iface) { this(destination, gateway, iface, RTN_UNICAST); } @@ -184,7 +215,8 @@ public final class RouteInfo implements Parcelable { * @hide */ @UnsupportedAppUsage - public RouteInfo(LinkAddress destination, InetAddress gateway, String iface) { + public RouteInfo(@Nullable LinkAddress destination, @Nullable InetAddress gateway, + @Nullable String iface) { this(destination == null ? null : new IpPrefix(destination.getAddress(), destination.getPrefixLength()), gateway, iface); @@ -205,7 +237,7 @@ public final class RouteInfo implements Parcelable { * * @hide */ - public RouteInfo(IpPrefix destination, InetAddress gateway) { + public RouteInfo(@Nullable IpPrefix destination, @Nullable InetAddress gateway) { this(destination, gateway, null); } @@ -215,7 +247,7 @@ public final class RouteInfo implements Parcelable { * TODO: Remove this. */ @UnsupportedAppUsage - public RouteInfo(LinkAddress destination, InetAddress gateway) { + public RouteInfo(@Nullable LinkAddress destination, @Nullable InetAddress gateway) { this(destination, gateway, null); } @@ -227,7 +259,7 @@ public final class RouteInfo implements Parcelable { * @hide */ @UnsupportedAppUsage - public RouteInfo(InetAddress gateway) { + public RouteInfo(@NonNull InetAddress gateway) { this((IpPrefix) null, gateway, null); } @@ -239,35 +271,36 @@ public final class RouteInfo implements Parcelable { * * @hide */ - public RouteInfo(IpPrefix destination) { + public RouteInfo(@NonNull IpPrefix destination) { this(destination, null, null); } /** * @hide */ - public RouteInfo(LinkAddress destination) { + public RouteInfo(@NonNull LinkAddress destination) { this(destination, null, null); } /** * @hide */ - public RouteInfo(IpPrefix destination, int type) { + public RouteInfo(@NonNull IpPrefix destination, @RouteType int type) { this(destination, null, null, type); } /** * @hide */ - public static RouteInfo makeHostRoute(InetAddress host, String iface) { + public static RouteInfo makeHostRoute(@NonNull InetAddress host, @Nullable String iface) { return makeHostRoute(host, null, iface); } /** * @hide */ - public static RouteInfo makeHostRoute(InetAddress host, InetAddress gateway, String iface) { + public static RouteInfo makeHostRoute(@Nullable InetAddress host, @Nullable InetAddress gateway, + @Nullable String iface) { if (host == null) return null; if (host instanceof Inet4Address) { @@ -290,6 +323,7 @@ public final class RouteInfo implements Parcelable { * * @return {@link IpPrefix} specifying the destination. This is never {@code null}. */ + @NonNull public IpPrefix getDestination() { return mDestination; } @@ -298,6 +332,7 @@ public final class RouteInfo implements Parcelable { * TODO: Convert callers to use IpPrefix and then remove. * @hide */ + @NonNull public LinkAddress getDestinationLinkAddress() { return new LinkAddress(mDestination.getAddress(), mDestination.getPrefixLength()); } @@ -308,6 +343,7 @@ public final class RouteInfo implements Parcelable { * @return {@link InetAddress} specifying the gateway or next hop. This may be * {@code null} for a directly-connected route." */ + @Nullable public InetAddress getGateway() { return mGateway; } @@ -317,6 +353,7 @@ public final class RouteInfo implements Parcelable { * * @return The name of the interface used for this route. */ + @Nullable public String getInterface() { return mInterface; } @@ -330,6 +367,7 @@ public final class RouteInfo implements Parcelable { */ @TestApi @SystemApi + @RouteType public int getType() { return mType; } @@ -401,6 +439,7 @@ public final class RouteInfo implements Parcelable { * @hide */ @UnsupportedAppUsage + @Nullable public static RouteInfo selectBestRoute(Collection<RouteInfo> routes, InetAddress dest) { if ((routes == null) || (dest == null)) return null; diff --git a/core/java/android/net/VpnService.java b/core/java/android/net/VpnService.java index ea245a4879c3..ed7cddcc6036 100644 --- a/core/java/android/net/VpnService.java +++ b/core/java/android/net/VpnService.java @@ -123,6 +123,11 @@ import java.util.Set; * app must promote itself to the foreground after it's launched or the system * will shut down the app. * + * <h3>Developer's guide</h3> + * + * <p>To learn more about developing VPN apps, read the + * <a href="{@docRoot}guide/topics/connectivity/vpn">VPN developer's guide</a>. + * * @see Builder */ public class VpnService extends Service { diff --git a/core/java/android/net/apf/ApfCapabilities.java b/core/java/android/net/apf/ApfCapabilities.java index 17a03c7c8933..4dd2ace59c62 100644 --- a/core/java/android/net/apf/ApfCapabilities.java +++ b/core/java/android/net/apf/ApfCapabilities.java @@ -19,14 +19,17 @@ package android.net.apf; import android.annotation.NonNull; import android.annotation.SystemApi; import android.annotation.TestApi; -import android.content.Context; +import android.content.res.Resources; import android.os.Parcel; import android.os.Parcelable; import com.android.internal.R; /** - * APF program support capabilities. + * APF program support capabilities. APF stands for Android Packet Filtering and it is a flexible + * way to drop unwanted network packets to save power. + * + * See documentation at hardware/google/apf/apf.h * * This class is immutable. * @hide @@ -104,10 +107,11 @@ public final class ApfCapabilities implements Parcelable { } /** - * Returns true if the APF interpreter advertises support for the data buffer access opcodes - * LDDW and STDW. + * Determines whether the APF interpreter advertises support for the data buffer access opcodes + * LDDW (LoaD Data Word) and STDW (STore Data Word). Full LDDW (LoaD Data Word) and + * STDW (STore Data Word) support is present from APFv4 on. * - * Full LDDW and STDW support is present from APFv4 on. + * @return {@code true} if the IWifiStaIface#readApfPacketFilterData is supported. */ public boolean hasDataAccess() { return apfVersionSupported >= 4; @@ -116,14 +120,14 @@ public final class ApfCapabilities implements Parcelable { /** * @return Whether the APF Filter in the device should filter out IEEE 802.3 Frames. */ - public static boolean getApfDrop8023Frames(@NonNull Context context) { - return context.getResources().getBoolean(R.bool.config_apfDrop802_3Frames); + public static boolean getApfDrop8023Frames() { + return Resources.getSystem().getBoolean(R.bool.config_apfDrop802_3Frames); } /** * @return An array of blacklisted EtherType, packets with EtherTypes within it will be dropped. */ - public static @NonNull int[] getApfEthTypeBlackList(@NonNull Context context) { - return context.getResources().getIntArray(R.array.config_apfEthTypeBlackList); + public static @NonNull int[] getApfEtherTypeBlackList() { + return Resources.getSystem().getIntArray(R.array.config_apfEthTypeBlackList); } } diff --git a/core/java/android/os/BatterySaverPolicyConfig.java b/core/java/android/os/BatterySaverPolicyConfig.java index bda4e27bf542..3801cbd48cdd 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; @@ -240,7 +241,10 @@ public final class BatterySaverPolicyConfig implements Parcelable { return mDisableOptionalSensors; } - /** Whether or not to disable sound trigger while in Battery Saver. */ + /** + * Whether or not to disable {@link android.hardware.soundtrigger.SoundTrigger} + * while in Battery Saver. + */ public boolean getDisableSoundTrigger() { return mDisableSoundTrigger; } @@ -260,7 +264,10 @@ public final class BatterySaverPolicyConfig implements Parcelable { return mEnableDataSaver; } - /** Whether or not to enable the network firewall while in Battery Saver. */ + /** + * Whether or not to enable network firewall rules to restrict background network use + * while in Battery Saver. + */ public boolean getEnableFirewall() { return mEnableFirewall; } @@ -280,7 +287,12 @@ public final class BatterySaverPolicyConfig implements Parcelable { return mForceAllAppsStandby; } - /** Whether or not to force background check while in Battery Saver. */ + /** + * Whether or not to force background check (disallow background services and manifest + * broadcast receivers) on all apps (not just apps targeting Android + * {@link Build.VERSION_CODES#O} and above) + * while in Battery Saver. + */ public boolean getForceBackgroundCheck() { return mForceBackgroundCheck; } @@ -400,7 +412,10 @@ public final class BatterySaverPolicyConfig implements Parcelable { return this; } - /** Set whether or not to disable sound trigger while in Battery Saver. */ + /** + * Set whether or not to disable {@link android.hardware.soundtrigger.SoundTrigger} + * while in Battery Saver. + */ @NonNull public Builder setDisableSoundTrigger(boolean disableSoundTrigger) { mDisableSoundTrigger = disableSoundTrigger; @@ -428,7 +443,10 @@ public final class BatterySaverPolicyConfig implements Parcelable { return this; } - /** Set whether or not to enable the network firewall while in Battery Saver. */ + /** + * Set whether or not to enable network firewall rules to restrict background network use + * while in Battery Saver. + */ @NonNull public Builder setEnableFirewall(boolean enableFirewall) { mEnableFirewall = enableFirewall; @@ -456,7 +474,12 @@ public final class BatterySaverPolicyConfig implements Parcelable { return this; } - /** Set whether or not to force background check while in Battery Saver. */ + /** + * Set whether or not to force background check (disallow background services and manifest + * broadcast receivers) on all apps (not just apps targeting Android + * {@link Build.VERSION_CODES#O} and above) + * while in Battery Saver. + */ @NonNull public Builder setForceBackgroundCheck(boolean forceBackgroundCheck) { mForceBackgroundCheck = forceBackgroundCheck; diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java index b64fe007bcd9..00d522bae27f 100644 --- a/core/java/android/os/BatteryStats.java +++ b/core/java/android/os/BatteryStats.java @@ -16,6 +16,7 @@ package android.os; +import static android.app.ActivityManager.PROCESS_STATE_BOUND_TOP; import static android.app.ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE_LOCATION; import android.annotation.UnsupportedAppUsage; @@ -859,7 +860,8 @@ public abstract class BatteryStats implements Parcelable { */ public static final int[] CRITICAL_PROC_STATES = { PROCESS_STATE_TOP, - PROCESS_STATE_FOREGROUND_SERVICE_LOCATION, PROCESS_STATE_FOREGROUND_SERVICE, + PROCESS_STATE_FOREGROUND_SERVICE_LOCATION, + PROCESS_STATE_BOUND_TOP, PROCESS_STATE_FOREGROUND_SERVICE, PROCESS_STATE_FOREGROUND }; diff --git a/core/java/android/os/ConditionVariable.java b/core/java/android/os/ConditionVariable.java index 1e820f945689..a13eaa6f19bf 100644 --- a/core/java/android/os/ConditionVariable.java +++ b/core/java/android/os/ConditionVariable.java @@ -104,32 +104,32 @@ public class ConditionVariable /** * Block the current thread until the condition is opened or until - * timeout milliseconds have passed. + * timeoutMs milliseconds have passed. * * <p> * If the condition is already opened, return immediately. * - * @param timeout the maximum time to wait in milliseconds. + * @param timeoutMs the maximum time to wait in milliseconds. * * @return true if the condition was opened, false if the call returns * because of the timeout. */ - public boolean block(long timeout) + public boolean block(long timeoutMs) { // Object.wait(0) means wait forever, to mimic this, we just // call the other block() method in that case. It simplifies // this code for the common case. - if (timeout != 0) { + if (timeoutMs != 0) { synchronized (this) { - long now = System.currentTimeMillis(); - long end = now + timeout; + long now = SystemClock.elapsedRealtime(); + long end = now + timeoutMs; while (!mCondition && now < end) { try { this.wait(end-now); } catch (InterruptedException e) { } - now = System.currentTimeMillis(); + now = SystemClock.elapsedRealtime(); } return mCondition; } 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/GraphicsEnvironment.java b/core/java/android/os/GraphicsEnvironment.java index 43ac5749fecb..53503f47ca74 100644 --- a/core/java/android/os/GraphicsEnvironment.java +++ b/core/java/android/os/GraphicsEnvironment.java @@ -337,6 +337,25 @@ public class GraphicsEnvironment { } /** + * Check for ANGLE debug package, but only for apps that can load them (dumpable) + */ + private String getAngleDebugPackage(Context context, Bundle coreSettings) { + final boolean appIsDebuggable = isDebuggable(context); + final boolean appIsProfileable = isProfileable(context); + final boolean deviceIsDebuggable = getCanLoadSystemLibraries() == 1; + if (appIsDebuggable || appIsProfileable || deviceIsDebuggable) { + + String debugPackage = + coreSettings.getString(Settings.Global.GLOBAL_SETTINGS_ANGLE_DEBUG_PACKAGE); + + if ((debugPackage != null) && (!debugPackage.isEmpty())) { + return debugPackage; + } + } + return ""; + } + + /** * Attempt to setup ANGLE with a temporary rules file. * True: Temporary rules file was loaded. * False: Temporary rules file was *not* loaded. @@ -502,11 +521,23 @@ public class GraphicsEnvironment { } final ApplicationInfo angleInfo; - try { - angleInfo = pm.getApplicationInfo(anglePkgName, PackageManager.MATCH_SYSTEM_ONLY); - } catch (PackageManager.NameNotFoundException e) { - Log.w(TAG, "ANGLE package '" + anglePkgName + "' not installed"); - return false; + String angleDebugPackage = getAngleDebugPackage(context, bundle); + if (!angleDebugPackage.isEmpty()) { + Log.i(TAG, "ANGLE debug package enabled: " + angleDebugPackage); + try { + // Note the debug package does not have to be pre-installed + angleInfo = pm.getApplicationInfo(angleDebugPackage, 0); + } catch (PackageManager.NameNotFoundException e) { + Log.w(TAG, "ANGLE debug package '" + angleDebugPackage + "' not installed"); + return false; + } + } else { + try { + angleInfo = pm.getApplicationInfo(anglePkgName, PackageManager.MATCH_SYSTEM_ONLY); + } catch (PackageManager.NameNotFoundException e) { + Log.w(TAG, "ANGLE package '" + anglePkgName + "' not installed"); + return false; + } } final String abi = chooseAbi(angleInfo); diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl index 6536fc991b30..03e8c154e3fc 100644 --- a/core/java/android/os/INetworkManagementService.aidl +++ b/core/java/android/os/INetworkManagementService.aidl @@ -330,12 +330,6 @@ interface INetworkManagementService */ void removeIdleTimer(String iface); - /** - * Configure name servers, search paths, and resolver parameters for the given network. - */ - void setDnsConfigurationForNetwork(int netId, in String[] servers, in String[] domains, - in int[] params, String tlsHostname, in String[] tlsServers); - void setFirewallEnabled(boolean enabled); boolean isFirewallEnabled(); void setFirewallInterfaceRule(String iface, boolean allow); @@ -381,11 +375,6 @@ interface INetworkManagementService void createVirtualNetwork(int netId, boolean secure); /** - * Remove a network. - */ - void removeNetwork(int netId); - - /** * Add an interface to a network. */ void addInterfaceToNetwork(String iface, int netId); diff --git a/core/java/android/os/IStatsManager.aidl b/core/java/android/os/IStatsManager.aidl index 6d4c5a034b54..311c86d08211 100644 --- a/core/java/android/os/IStatsManager.aidl +++ b/core/java/android/os/IStatsManager.aidl @@ -217,4 +217,9 @@ interface IStatsManager { */ oneway void sendBinaryPushStateChangedAtom(in String trainName, in long trainVersionCode, in int options, in int state, in long[] experimentId); + + /** + * Returns the most recently registered experiment IDs. + */ + long[] getRegisteredExperimentIds(); } 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/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java index 56c2f4ce9425..c57bf9141248 100644 --- a/core/java/android/os/storage/StorageManager.java +++ b/core/java/android/os/storage/StorageManager.java @@ -17,9 +17,6 @@ package android.os.storage; import static android.Manifest.permission.READ_EXTERNAL_STORAGE; -import static android.Manifest.permission.READ_MEDIA_AUDIO; -import static android.Manifest.permission.READ_MEDIA_IMAGES; -import static android.Manifest.permission.READ_MEDIA_VIDEO; import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE; import static android.app.AppOpsManager.OP_READ_EXTERNAL_STORAGE; import static android.app.AppOpsManager.OP_READ_MEDIA_AUDIO; @@ -155,8 +152,6 @@ public class StorageManager { public static final String PROP_ISOLATED_STORAGE = "persist.sys.isolated_storage"; /** {@hide} */ public static final String PROP_ISOLATED_STORAGE_SNAPSHOT = "sys.isolated_storage_snapshot"; - /** {@hide} */ - public static final String PROP_LEGACY_GREYLIST = "persist.sys.legacy_greylist"; /** {@hide} */ public static final String PROP_FORCE_AUDIO = "persist.fw.force_audio"; @@ -254,8 +249,6 @@ public class StorageManager { public static final int DEBUG_ISOLATED_STORAGE_FORCE_ON = 1 << 6; /** {@hide} */ public static final int DEBUG_ISOLATED_STORAGE_FORCE_OFF = 1 << 7; - /** {@hide} */ - public static final int DEBUG_LEGACY_GREYLIST = 1 << 8; /** {@hide} */ public static final int FLAG_STORAGE_DE = IInstalld.FLAG_STORAGE_DE; @@ -306,6 +299,7 @@ public class StorageManager { private final ContentResolver mResolver; private final IStorageManager mStorageManager; + private final AppOpsManager mAppOps; private final Looper mLooper; private final AtomicInteger mNextNonce = new AtomicInteger(0); @@ -516,6 +510,7 @@ public class StorageManager { mResolver = context.getContentResolver(); mLooper = looper; mStorageManager = IStorageManager.Stub.asInterface(ServiceManager.getServiceOrThrow("mount")); + mAppOps = mContext.getSystemService(AppOpsManager.class); } /** @@ -1666,7 +1661,7 @@ public class StorageManager { } } - final AppOpsManager appOps = context.getSystemService(AppOpsManager.class); + AppOpsManager appOps = context.getSystemService(AppOpsManager.class); final int mode = appOps.noteOpNoThrow(op, uid, packageName); switch (mode) { case AppOpsManager.MODE_ALLOWED: @@ -1701,8 +1696,7 @@ public class StorageManager { int pid, int uid, String packageName) { if (!checkPermissionAndAppOp(enforce, pid, uid, packageName, READ_EXTERNAL_STORAGE, OP_READ_EXTERNAL_STORAGE)) return false; - if (!checkPermissionAndAppOp(enforce, pid, uid, packageName, - READ_MEDIA_AUDIO, OP_READ_MEDIA_AUDIO)) return false; + mAppOps.noteOpNoThrow(OP_READ_MEDIA_AUDIO, uid, packageName); return true; } @@ -1711,8 +1705,7 @@ public class StorageManager { int pid, int uid, String packageName) { if (!checkPermissionAndAppOp(enforce, pid, uid, packageName, WRITE_EXTERNAL_STORAGE, OP_WRITE_EXTERNAL_STORAGE)) return false; - if (!checkPermissionAndAppOp(enforce, pid, uid, packageName, - READ_MEDIA_AUDIO, OP_WRITE_MEDIA_AUDIO)) return false; + mAppOps.noteOpNoThrow(OP_WRITE_MEDIA_AUDIO, uid, packageName); return true; } @@ -1721,8 +1714,7 @@ public class StorageManager { int pid, int uid, String packageName) { if (!checkPermissionAndAppOp(enforce, pid, uid, packageName, READ_EXTERNAL_STORAGE, OP_READ_EXTERNAL_STORAGE)) return false; - if (!checkPermissionAndAppOp(enforce, pid, uid, packageName, - READ_MEDIA_VIDEO, OP_READ_MEDIA_VIDEO)) return false; + mAppOps.noteOpNoThrow(OP_READ_MEDIA_VIDEO, uid, packageName); return true; } @@ -1731,8 +1723,7 @@ public class StorageManager { int pid, int uid, String packageName) { if (!checkPermissionAndAppOp(enforce, pid, uid, packageName, WRITE_EXTERNAL_STORAGE, OP_WRITE_EXTERNAL_STORAGE)) return false; - if (!checkPermissionAndAppOp(enforce, pid, uid, packageName, - READ_MEDIA_VIDEO, OP_WRITE_MEDIA_VIDEO)) return false; + mAppOps.noteOpNoThrow(OP_WRITE_MEDIA_VIDEO, uid, packageName); return true; } @@ -1741,8 +1732,7 @@ public class StorageManager { int pid, int uid, String packageName) { if (!checkPermissionAndAppOp(enforce, pid, uid, packageName, READ_EXTERNAL_STORAGE, OP_READ_EXTERNAL_STORAGE)) return false; - if (!checkPermissionAndAppOp(enforce, pid, uid, packageName, - READ_MEDIA_IMAGES, OP_READ_MEDIA_IMAGES)) return false; + mAppOps.noteOpNoThrow(OP_READ_MEDIA_IMAGES, uid, packageName); return true; } @@ -1751,8 +1741,7 @@ public class StorageManager { int pid, int uid, String packageName) { if (!checkPermissionAndAppOp(enforce, pid, uid, packageName, WRITE_EXTERNAL_STORAGE, OP_WRITE_EXTERNAL_STORAGE)) return false; - if (!checkPermissionAndAppOp(enforce, pid, uid, packageName, - READ_MEDIA_IMAGES, OP_WRITE_MEDIA_IMAGES)) return false; + mAppOps.noteOpNoThrow(OP_WRITE_MEDIA_IMAGES, uid, packageName); return true; } diff --git a/core/java/android/provider/DeviceConfig.java b/core/java/android/provider/DeviceConfig.java index 728d77ef941e..5631282b3bd3 100644 --- a/core/java/android/provider/DeviceConfig.java +++ b/core/java/android/provider/DeviceConfig.java @@ -299,27 +299,6 @@ public final class DeviceConfig { "device_identifier_access_restrictions_disabled"; } - /** - * Telephony related properties definitions. - * - * @hide - */ - public interface Telephony { - String NAMESPACE = "telephony"; - /** - * Ringer ramping time in milliseconds. - */ - String RAMPING_RINGER_DURATION = "ramping_ringer_duration"; - /** - * Whether to apply ramping ringer on incoming phone calls. - */ - String RAMPING_RINGER_ENABLED = "ramping_ringer_enabled"; - /** - * Vibration time in milliseconds before ramping ringer starts. - */ - String RAMPING_RINGER_VIBRATION_DURATION = "ramping_ringer_vibration_duration"; - } - private static final Object sLock = new Object(); @GuardedBy("sLock") private static ArrayMap<OnPropertyChangedListener, Pair<String, Executor>> sSingleListeners = diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java index 7feeeee0f790..bda6ed19d3c1 100644 --- a/core/java/android/provider/MediaStore.java +++ b/core/java/android/provider/MediaStore.java @@ -31,6 +31,7 @@ import android.annotation.UnsupportedAppUsage; import android.app.Activity; import android.app.AppGlobals; import android.content.ClipData; +import android.content.ContentInterface; import android.content.ContentProviderClient; import android.content.ContentResolver; import android.content.ContentUris; @@ -884,9 +885,7 @@ public final class MediaStore { * access this path. Instead of trying to open this path * directly, apps should use * {@link ContentResolver#openFileDescriptor(Uri, String)} - * to gain access. This value will always be {@code NULL} - * for apps targeting - * {@link android.os.Build.VERSION_CODES#Q} or higher. + * to gain access. */ @Deprecated @Column(Cursor.FIELD_TYPE_STRING) @@ -1714,11 +1713,9 @@ public final class MediaStore { url = cr.insert(EXTERNAL_CONTENT_URI, values); if (source != null) { - OutputStream imageOut = cr.openOutputStream(url); - try { - source.compress(Bitmap.CompressFormat.JPEG, 50, imageOut); - } finally { - imageOut.close(); + try (OutputStream out = new ParcelFileDescriptor.AutoCloseOutputStream( + cr.openFile(url, "w", null))) { + source.compress(Bitmap.CompressFormat.JPEG, 50, out); } long id = ContentUris.parseId(url); @@ -1959,9 +1956,7 @@ public final class MediaStore { * access this path. Instead of trying to open this path * directly, apps should use * {@link ContentResolver#loadThumbnail} - * to gain access. This value will always be - * {@code NULL} for apps targeting - * {@link android.os.Build.VERSION_CODES#Q} or higher. + * to gain access. */ @Deprecated @Column(Cursor.FIELD_TYPE_STRING) @@ -2442,9 +2437,7 @@ public final class MediaStore { * access this path. Instead of trying to open this path * directly, apps should use * {@link ContentResolver#openFileDescriptor(Uri, String)} - * to gain access. This value will always be - * {@code NULL} for apps targeting - * {@link android.os.Build.VERSION_CODES#Q} or higher. + * to gain access. */ @Deprecated @Column(Cursor.FIELD_TYPE_STRING) @@ -2734,9 +2727,7 @@ public final class MediaStore { * access this path. Instead of trying to open this path * directly, apps should use * {@link ContentResolver#loadThumbnail} - * to gain access. This value will always be - * {@code NULL} for apps targeting - * {@link android.os.Build.VERSION_CODES#Q} or higher. + * to gain access. */ @Deprecated @Column(Cursor.FIELD_TYPE_STRING) @@ -2823,9 +2814,7 @@ public final class MediaStore { * access this path. Instead of trying to open this path * directly, apps should use * {@link ContentResolver#loadThumbnail} - * to gain access. This value will always be - * {@code NULL} for apps targeting - * {@link android.os.Build.VERSION_CODES#Q} or higher. + * to gain access. */ @Deprecated @Column(Cursor.FIELD_TYPE_STRING) @@ -3193,9 +3182,7 @@ public final class MediaStore { * access this path. Instead of trying to open this path * directly, apps should use * {@link ContentResolver#openFileDescriptor(Uri, String)} - * to gain access. This value will always be - * {@code NULL} for apps targeting - * {@link android.os.Build.VERSION_CODES#Q} or higher. + * to gain access. */ @Deprecated @Column(Cursor.FIELD_TYPE_STRING) diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 1cab250b7d91..227c9d426915 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -1501,6 +1501,22 @@ public final class Settings { = "android.settings.MANAGE_DEFAULT_APPS_SETTINGS"; /** + * Activity Action: Show More default apps settings. + * <p> + * In some cases, a matching Activity may not exist, so ensure you safeguard against this. + * <p> + * Input: Nothing. + * <p> + * Output: Nothing. + * + * @hide + */ + @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) + @SystemApi + public static final String ACTION_MANAGE_MORE_DEFAULT_APPS_SETTINGS = + "android.settings.MANAGE_MORE_DEFAULT_APPS_SETTINGS"; + + /** * Activity Action: Show notification settings. * * @hide @@ -7751,15 +7767,6 @@ public final class Settings { "call_screening_default_component"; /** - * Specifies the component name currently configured to be the default application to - * perform the user-defined call redirection service with Telecom. - * @hide - */ - @UnsupportedAppUsage - public static final String CALL_REDIRECTION_DEFAULT_APPLICATION = - "call_redirection_default_application"; - - /** * Specifies the package name currently configured to be the emergency assistance application * * @see android.telephony.TelephonyManager#ACTION_EMERGENCY_ASSISTANCE @@ -11521,15 +11528,6 @@ public final class Settings { "background_activity_starts_enabled"; /** - * The packages temporarily whitelisted to be able so start activities from background. - * The list of packages is {@code ":"} colon delimited. - * - * @hide - */ - public static final String BACKGROUND_ACTIVITY_STARTS_PACKAGE_NAMES_WHITELIST = - "background_activity_starts_package_names_whitelist"; - - /** * @hide * @see com.android.server.appbinding.AppBindingConstants */ @@ -12453,6 +12451,14 @@ public final class Settings { public static final String GPU_DEBUG_APP = "gpu_debug_app"; /** + * Package containing ANGLE libraries other than system, which are only available + * to dumpable apps that opt-in. + * @hide + */ + public static final String GLOBAL_SETTINGS_ANGLE_DEBUG_PACKAGE = + "angle_debug_package"; + + /** * Force all PKGs to use ANGLE, regardless of any other settings * The value is a boolean (1 or 0). * @hide @@ -14726,7 +14732,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/service/carrier/CarrierIdentifier.java b/core/java/android/service/carrier/CarrierIdentifier.java index 6629233ef590..af5bf7475f95 100644 --- a/core/java/android/service/carrier/CarrierIdentifier.java +++ b/core/java/android/service/carrier/CarrierIdentifier.java @@ -20,6 +20,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.os.Parcel; import android.os.Parcelable; +import android.telephony.Rlog; import android.telephony.TelephonyManager; import com.android.internal.telephony.uicc.IccUtils; @@ -223,7 +224,7 @@ public class CarrierIdentifier implements Parcelable { + "mcc=" + mMcc + ",mnc=" + mMnc + ",spn=" + mSpn - + ",imsi=" + mImsi + + ",imsi=" + Rlog.pii(false, mImsi) + ",gid1=" + mGid1 + ",gid2=" + mGid2 + ",carrierid=" + mCarrierId diff --git a/core/java/android/service/contentcapture/ContentCaptureService.java b/core/java/android/service/contentcapture/ContentCaptureService.java index 7a35b9e8fa74..dc57a1591913 100644 --- a/core/java/android/service/contentcapture/ContentCaptureService.java +++ b/core/java/android/service/contentcapture/ContentCaptureService.java @@ -17,6 +17,8 @@ package android.service.contentcapture; import static android.view.contentcapture.ContentCaptureHelper.sDebug; import static android.view.contentcapture.ContentCaptureHelper.sVerbose; +import static android.view.contentcapture.ContentCaptureHelper.toList; +import static android.view.contentcapture.ContentCaptureSession.NO_SESSION_ID; import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage; @@ -36,9 +38,9 @@ import android.os.IBinder; import android.os.Looper; import android.os.RemoteException; import android.service.autofill.AutofillService; -import android.util.ArrayMap; import android.util.Log; import android.util.Slog; +import android.util.SparseIntArray; import android.view.contentcapture.ContentCaptureCondition; import android.view.contentcapture.ContentCaptureContext; import android.view.contentcapture.ContentCaptureEvent; @@ -53,7 +55,6 @@ import com.android.internal.os.IResultReceiver; import java.io.FileDescriptor; import java.io.PrintWriter; -import java.util.ArrayList; import java.util.List; import java.util.Set; @@ -117,7 +118,7 @@ public abstract class ContentCaptureService extends Service { } @Override - public void onSessionStarted(ContentCaptureContext context, String sessionId, int uid, + public void onSessionStarted(ContentCaptureContext context, int sessionId, int uid, IResultReceiver clientReceiver, int initialState) { mHandler.sendMessage(obtainMessage(ContentCaptureService::handleOnCreateSession, ContentCaptureService.this, context, sessionId, uid, clientReceiver, @@ -125,14 +126,14 @@ public abstract class ContentCaptureService extends Service { } @Override - public void onActivitySnapshot(String sessionId, SnapshotData snapshotData) { + public void onActivitySnapshot(int sessionId, SnapshotData snapshotData) { mHandler.sendMessage( obtainMessage(ContentCaptureService::handleOnActivitySnapshot, ContentCaptureService.this, sessionId, snapshotData)); } @Override - public void onSessionFinished(String sessionId) { + public void onSessionFinished(int sessionId) { mHandler.sendMessage(obtainMessage(ContentCaptureService::handleFinishSession, ContentCaptureService.this, sessionId)); } @@ -171,7 +172,7 @@ public abstract class ContentCaptureService extends Service { * <p>This map is populated when an session is started, which is called by the system server * and can be trusted. Then subsequent calls made by the app are verified against this map. */ - private final ArrayMap<String, Integer> mSessionUids = new ArrayMap<>(); + private final SparseIntArray mSessionUids = new SparseIntArray(); @CallSuper @Override @@ -240,11 +241,17 @@ public abstract class ContentCaptureService extends Service { */ public final void setContentCaptureConditions(@NonNull String packageName, @Nullable Set<ContentCaptureCondition> conditions) { - // TODO(b/129267994): implement - } + final IContentCaptureServiceCallback callback = mCallback; + if (callback == null) { + Log.w(TAG, "setContentCaptureConditions(): no server callback"); + return; + } - private <T> ArrayList<T> toList(@Nullable Set<T> set) { - return set == null ? null : new ArrayList<T>(set); + try { + callback.setContentCaptureConditions(packageName, toList(conditions)); + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + } } /** @@ -378,7 +385,7 @@ public abstract class ContentCaptureService extends Service { // so we don't need to create a temporary InteractionSessionId for each event. private void handleOnCreateSession(@NonNull ContentCaptureContext context, - @NonNull String sessionId, int uid, IResultReceiver clientReceiver, int initialState) { + int sessionId, int uid, IResultReceiver clientReceiver, int initialState) { mSessionUids.put(sessionId, uid); onCreateContentCaptureSession(context, new ContentCaptureSessionId(sessionId)); @@ -403,27 +410,27 @@ public abstract class ContentCaptureService extends Service { // Most events belong to the same session, so we can keep a reference to the last one // to avoid creating too many ContentCaptureSessionId objects - String lastSessionId = null; + int lastSessionId = NO_SESSION_ID; ContentCaptureSessionId sessionId = null; final List<ContentCaptureEvent> events = parceledEvents.getList(); for (int i = 0; i < events.size(); i++) { final ContentCaptureEvent event = events.get(i); if (!handleIsRightCallerFor(event, uid)) continue; - String sessionIdString = event.getSessionId(); - if (!sessionIdString.equals(lastSessionId)) { - sessionId = new ContentCaptureSessionId(sessionIdString); - lastSessionId = sessionIdString; + int sessionIdInt = event.getSessionId(); + if (sessionIdInt != lastSessionId) { + sessionId = new ContentCaptureSessionId(sessionIdInt); + lastSessionId = sessionIdInt; } switch (event.getType()) { case ContentCaptureEvent.TYPE_SESSION_STARTED: final ContentCaptureContext clientContext = event.getContentCaptureContext(); clientContext.setParentSessionId(event.getParentSessionId()); - mSessionUids.put(sessionIdString, uid); + mSessionUids.put(sessionIdInt, uid); onCreateContentCaptureSession(clientContext, sessionId); break; case ContentCaptureEvent.TYPE_SESSION_FINISHED: - mSessionUids.remove(sessionIdString); + mSessionUids.delete(sessionIdInt); onDestroyContentCaptureSession(sessionId); break; default: @@ -432,13 +439,12 @@ public abstract class ContentCaptureService extends Service { } } - private void handleOnActivitySnapshot(@NonNull String sessionId, - @NonNull SnapshotData snapshotData) { + private void handleOnActivitySnapshot(int sessionId, @NonNull SnapshotData snapshotData) { onActivitySnapshot(new ContentCaptureSessionId(sessionId), snapshotData); } - private void handleFinishSession(@NonNull String sessionId) { - mSessionUids.remove(sessionId); + private void handleFinishSession(int sessionId) { + mSessionUids.delete(sessionId); onDestroyContentCaptureSession(new ContentCaptureSessionId(sessionId)); } @@ -454,7 +460,7 @@ public abstract class ContentCaptureService extends Service { * Checks if the given {@code uid} owns the session associated with the event. */ private boolean handleIsRightCallerFor(@NonNull ContentCaptureEvent event, int uid) { - final String sessionId; + final int sessionId; switch (event.getType()) { case ContentCaptureEvent.TYPE_SESSION_STARTED: case ContentCaptureEvent.TYPE_SESSION_FINISHED: @@ -463,8 +469,7 @@ public abstract class ContentCaptureService extends Service { default: sessionId = event.getSessionId(); } - final Integer rightUid = mSessionUids.get(sessionId); - if (rightUid == null) { + if (mSessionUids.indexOfKey(sessionId) < 0) { if (sVerbose) { Log.v(TAG, "handleIsRightCallerFor(" + event + "): no session for " + sessionId + ": " + mSessionUids); @@ -472,6 +477,7 @@ public abstract class ContentCaptureService extends Service { // Just ignore, as the session could have been finished already return false; } + final int rightUid = mSessionUids.get(sessionId); if (rightUid != uid) { Log.e(TAG, "invalid call from UID " + uid + ": session " + sessionId + " belongs to " + rightUid); diff --git a/core/java/android/service/contentcapture/IContentCaptureService.aidl b/core/java/android/service/contentcapture/IContentCaptureService.aidl index 6be7a80653e9..03e1b7857837 100644 --- a/core/java/android/service/contentcapture/IContentCaptureService.aidl +++ b/core/java/android/service/contentcapture/IContentCaptureService.aidl @@ -35,10 +35,10 @@ import java.util.List; oneway interface IContentCaptureService { void onConnected(IBinder callback, boolean verbose, boolean debug); void onDisconnected(); - void onSessionStarted(in ContentCaptureContext context, String sessionId, int uid, + void onSessionStarted(in ContentCaptureContext context, int sessionId, int uid, in IResultReceiver clientReceiver, int initialState); - void onSessionFinished(String sessionId); - void onActivitySnapshot(String sessionId, in SnapshotData snapshotData); + void onSessionFinished(int sessionId); + void onActivitySnapshot(int sessionId, in SnapshotData snapshotData); void onUserDataRemovalRequest(in UserDataRemovalRequest request); void onActivityEvent(in ActivityEvent event); } diff --git a/core/java/android/service/contentcapture/IContentCaptureServiceCallback.aidl b/core/java/android/service/contentcapture/IContentCaptureServiceCallback.aidl index 8bc8defede80..0550ad3ea20c 100644 --- a/core/java/android/service/contentcapture/IContentCaptureServiceCallback.aidl +++ b/core/java/android/service/contentcapture/IContentCaptureServiceCallback.aidl @@ -17,6 +17,7 @@ package android.service.contentcapture; import android.content.ComponentName; +import android.view.contentcapture.ContentCaptureCondition; import java.util.List; @@ -27,5 +28,6 @@ import java.util.List; */ oneway interface IContentCaptureServiceCallback { void setContentCaptureWhitelist(in List<String> packages, in List<ComponentName> activities); + void setContentCaptureConditions(String packageName, in List<ContentCaptureCondition> conditions); void disableSelf(); } diff --git a/core/java/android/speech/tts/TtsEngines.java b/core/java/android/speech/tts/TtsEngines.java index a7b280b7b992..2fab40472bd5 100644 --- a/core/java/android/speech/tts/TtsEngines.java +++ b/core/java/android/speech/tts/TtsEngines.java @@ -15,8 +15,10 @@ */ package android.speech.tts; -import org.xmlpull.v1.XmlPullParserException; +import static android.provider.Settings.Secure.getString; +import android.annotation.NonNull; +import android.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.Intent; import android.content.pm.ApplicationInfo; @@ -27,10 +29,6 @@ import android.content.pm.ServiceInfo; import android.content.res.Resources; import android.content.res.TypedArray; import android.content.res.XmlResourceParser; - -import static android.provider.Settings.Secure.getString; - -import android.annotation.UnsupportedAppUsage; import android.provider.Settings; import android.speech.tts.TextToSpeech.Engine; import android.speech.tts.TextToSpeech.EngineInfo; @@ -39,6 +37,8 @@ import android.util.AttributeSet; import android.util.Log; import android.util.Xml; +import org.xmlpull.v1.XmlPullParserException; + import java.io.IOException; import java.util.ArrayList; import java.util.Collections; @@ -522,7 +522,8 @@ public class TtsEngines { * read back, will evaluate to {@link Locale#getDefault()}. */ @UnsupportedAppUsage - public synchronized void updateLocalePrefForEngine(String engineName, Locale newLocale) { + public synchronized void updateLocalePrefForEngine( + @NonNull String engineName, Locale newLocale) { final String prefList = Settings.Secure.getString(mContext.getContentResolver(), Settings.Secure.TTS_DEFAULT_LOCALE); if (DBG) { diff --git a/core/java/android/text/format/Formatter.java b/core/java/android/text/format/Formatter.java index 077d12de4d59..d7baa1086b2f 100644 --- a/core/java/android/text/format/Formatter.java +++ b/core/java/android/text/format/Formatter.java @@ -92,10 +92,15 @@ public final class Formatter { * @return formatted string with the number */ public static String formatFileSize(@Nullable Context context, long sizeBytes) { + return formatFileSize(context, sizeBytes, FLAG_SI_UNITS); + } + + /** @hide */ + public static String formatFileSize(@Nullable Context context, long sizeBytes, int flags) { if (context == null) { return ""; } - final BytesResult res = formatBytes(context.getResources(), sizeBytes, FLAG_SI_UNITS); + final BytesResult res = formatBytes(context.getResources(), sizeBytes, flags); return bidiWrap(context, context.getString(com.android.internal.R.string.fileSizeSuffix, res.value, res.units)); } diff --git a/core/java/android/util/ArrayMap.java b/core/java/android/util/ArrayMap.java index 436cb4ff7072..e2af6f5ed102 100644 --- a/core/java/android/util/ArrayMap.java +++ b/core/java/android/util/ArrayMap.java @@ -16,12 +16,12 @@ package android.util; -import libcore.util.EmptyArray; - import android.annotation.UnsupportedAppUsage; import com.android.internal.util.ArrayUtils; +import libcore.util.EmptyArray; + import java.util.Collection; import java.util.ConcurrentModificationException; import java.util.Map; @@ -453,6 +453,10 @@ public final class ArrayMap<K, V> implements Map<K, V> { * @return Returns the key stored at the given index. */ public K keyAt(int index) { + if (index >= mSize) { + // The array might be slightly bigger than mSize, in which case, indexing won't fail. + throw new ArrayIndexOutOfBoundsException(index); + } return (K)mArray[index << 1]; } @@ -462,6 +466,10 @@ public final class ArrayMap<K, V> implements Map<K, V> { * @return Returns the value stored at the given index. */ public V valueAt(int index) { + if (index >= mSize) { + // The array might be slightly bigger than mSize, in which case, indexing won't fail. + throw new ArrayIndexOutOfBoundsException(index); + } return (V)mArray[(index << 1) + 1]; } @@ -472,6 +480,10 @@ public final class ArrayMap<K, V> implements Map<K, V> { * @return Returns the previous value at the given index. */ public V setValueAt(int index, V value) { + if (index >= mSize) { + // The array might be slightly bigger than mSize, in which case, indexing won't fail. + throw new ArrayIndexOutOfBoundsException(index); + } index = (index << 1) + 1; V old = (V)mArray[index]; mArray[index] = value; @@ -665,6 +677,11 @@ public final class ArrayMap<K, V> implements Map<K, V> { * @return Returns the value that was stored at this index. */ public V removeAt(int index) { + if (index >= mSize) { + // The array might be slightly bigger than mSize, in which case, indexing won't fail. + throw new ArrayIndexOutOfBoundsException(index); + } + final Object old = mArray[(index << 1) + 1]; final int osize = mSize; final int nsize; diff --git a/core/java/android/util/FeatureFlagUtils.java b/core/java/android/util/FeatureFlagUtils.java index d64ec721634a..5d33b49e181b 100644 --- a/core/java/android/util/FeatureFlagUtils.java +++ b/core/java/android/util/FeatureFlagUtils.java @@ -56,7 +56,7 @@ public class FeatureFlagUtils { DEFAULT_FLAGS.put(DYNAMIC_SYSTEM, "false"); DEFAULT_FLAGS.put(SEAMLESS_TRANSFER, "false"); DEFAULT_FLAGS.put(HEARING_AID_SETTINGS, "false"); - DEFAULT_FLAGS.put(SAFETY_HUB, "false"); + DEFAULT_FLAGS.put(SAFETY_HUB, "true"); DEFAULT_FLAGS.put(SCREENRECORD_LONG_PRESS, "false"); DEFAULT_FLAGS.put(GLOBAL_ACTIONS_GRID_ENABLED, "true"); DEFAULT_FLAGS.put(GLOBAL_ACTIONS_PANEL_ENABLED, "true"); diff --git a/core/java/android/util/LongSparseArray.java b/core/java/android/util/LongSparseArray.java index cf49803a7225..e4de7045721b 100644 --- a/core/java/android/util/LongSparseArray.java +++ b/core/java/android/util/LongSparseArray.java @@ -21,9 +21,6 @@ import com.android.internal.util.GrowingArrayUtils; import libcore.util.EmptyArray; -import java.util.Arrays; -import java.util.Objects; - /** * SparseArray mapping longs to Objects. Unlike a normal array of Objects, * there can be gaps in the indices. It is intended to be more memory efficient @@ -147,6 +144,10 @@ public class LongSparseArray<E> implements Cloneable { * Removes the mapping at the specified index. */ public void removeAt(int index) { + if (index >= mSize) { + // The array might be slightly bigger than mSize, in which case, indexing won't fail. + throw new ArrayIndexOutOfBoundsException(index); + } if (mValues[index] != DELETED) { mValues[index] = DELETED; mGarbage = true; @@ -236,6 +237,10 @@ public class LongSparseArray<E> implements Cloneable { * key.</p> */ public long keyAt(int index) { + if (index >= mSize) { + // The array might be slightly bigger than mSize, in which case, indexing won't fail. + throw new ArrayIndexOutOfBoundsException(index); + } if (mGarbage) { gc(); } @@ -256,6 +261,10 @@ public class LongSparseArray<E> implements Cloneable { */ @SuppressWarnings("unchecked") public E valueAt(int index) { + if (index >= mSize) { + // The array might be slightly bigger than mSize, in which case, indexing won't fail. + throw new ArrayIndexOutOfBoundsException(index); + } if (mGarbage) { gc(); } @@ -269,6 +278,10 @@ public class LongSparseArray<E> implements Cloneable { * LongSparseArray stores. */ public void setValueAt(int index, E value) { + if (index >= mSize) { + // The array might be slightly bigger than mSize, in which case, indexing won't fail. + throw new ArrayIndexOutOfBoundsException(index); + } if (mGarbage) { gc(); } diff --git a/core/java/android/util/LongSparseLongArray.java b/core/java/android/util/LongSparseLongArray.java index 8dcdb4026246..f167f009a942 100644 --- a/core/java/android/util/LongSparseLongArray.java +++ b/core/java/android/util/LongSparseLongArray.java @@ -16,14 +16,13 @@ package android.util; +import android.annotation.UnsupportedAppUsage; + import com.android.internal.util.ArrayUtils; import com.android.internal.util.GrowingArrayUtils; -import android.annotation.UnsupportedAppUsage; import libcore.util.EmptyArray; -import java.util.Arrays; - /** * Map of {@code long} to {@code long}. Unlike a normal array of longs, there * can be gaps in the indices. It is intended to be more memory efficient than using a @@ -173,6 +172,10 @@ public class LongSparseLongArray implements Cloneable { * key.</p> */ public long keyAt(int index) { + if (index >= mSize) { + // The array might be slightly bigger than mSize, in which case, indexing won't fail. + throw new ArrayIndexOutOfBoundsException(index); + } return mKeys[index]; } @@ -188,6 +191,10 @@ public class LongSparseLongArray implements Cloneable { * associated with the largest key.</p> */ public long valueAt(int index) { + if (index >= mSize) { + // The array might be slightly bigger than mSize, in which case, indexing won't fail. + throw new ArrayIndexOutOfBoundsException(index); + } return mValues[index]; } diff --git a/core/java/android/util/SparseArray.java b/core/java/android/util/SparseArray.java index 89ea2d35fc2f..67dfb02a0b95 100644 --- a/core/java/android/util/SparseArray.java +++ b/core/java/android/util/SparseArray.java @@ -16,10 +16,11 @@ package android.util; +import android.annotation.UnsupportedAppUsage; + import com.android.internal.util.ArrayUtils; import com.android.internal.util.GrowingArrayUtils; -import android.annotation.UnsupportedAppUsage; import libcore.util.EmptyArray; /** @@ -171,6 +172,10 @@ public class SparseArray<E> implements Cloneable { * the behavior is undefined.</p> */ public void removeAt(int index) { + if (index >= mSize) { + // The array might be slightly bigger than mSize, in which case, indexing won't fail. + throw new ArrayIndexOutOfBoundsException(index); + } if (mValues[index] != DELETED) { mValues[index] = DELETED; mGarbage = true; @@ -279,6 +284,10 @@ public class SparseArray<E> implements Cloneable { * the behavior is undefined.</p> */ public int keyAt(int index) { + if (index >= mSize) { + // The array might be slightly bigger than mSize, in which case, indexing won't fail. + throw new ArrayIndexOutOfBoundsException(index); + } if (mGarbage) { gc(); } @@ -302,6 +311,10 @@ public class SparseArray<E> implements Cloneable { */ @SuppressWarnings("unchecked") public E valueAt(int index) { + if (index >= mSize) { + // The array might be slightly bigger than mSize, in which case, indexing won't fail. + throw new ArrayIndexOutOfBoundsException(index); + } if (mGarbage) { gc(); } @@ -317,6 +330,10 @@ public class SparseArray<E> implements Cloneable { * <p>For indices outside of the range <code>0...size()-1</code>, the behavior is undefined.</p> */ public void setValueAt(int index, E value) { + if (index >= mSize) { + // The array might be slightly bigger than mSize, in which case, indexing won't fail. + throw new ArrayIndexOutOfBoundsException(index); + } if (mGarbage) { gc(); } diff --git a/core/java/android/util/SparseBooleanArray.java b/core/java/android/util/SparseBooleanArray.java index d4c40954bdd1..03fa1c996027 100644 --- a/core/java/android/util/SparseBooleanArray.java +++ b/core/java/android/util/SparseBooleanArray.java @@ -16,10 +16,11 @@ package android.util; +import android.annotation.UnsupportedAppUsage; + import com.android.internal.util.ArrayUtils; import com.android.internal.util.GrowingArrayUtils; -import android.annotation.UnsupportedAppUsage; import libcore.util.EmptyArray; /** @@ -167,6 +168,10 @@ public class SparseBooleanArray implements Cloneable { * key.</p> */ public int keyAt(int index) { + if (index >= mSize) { + // The array might be slightly bigger than mSize, in which case, indexing won't fail. + throw new ArrayIndexOutOfBoundsException(index); + } return mKeys[index]; } @@ -182,6 +187,10 @@ public class SparseBooleanArray implements Cloneable { * associated with the largest key.</p> */ public boolean valueAt(int index) { + if (index >= mSize) { + // The array might be slightly bigger than mSize, in which case, indexing won't fail. + throw new ArrayIndexOutOfBoundsException(index); + } return mValues[index]; } @@ -189,11 +198,19 @@ public class SparseBooleanArray implements Cloneable { * Directly set the value at a particular index. */ public void setValueAt(int index, boolean value) { + if (index >= mSize) { + // The array might be slightly bigger than mSize, in which case, indexing won't fail. + throw new ArrayIndexOutOfBoundsException(index); + } mValues[index] = value; } /** @hide */ public void setKeyAt(int index, int key) { + if (index >= mSize) { + // The array might be slightly bigger than mSize, in which case, indexing won't fail. + throw new ArrayIndexOutOfBoundsException(index); + } mKeys[index] = key; } diff --git a/core/java/android/util/SparseIntArray.java b/core/java/android/util/SparseIntArray.java index 9e6bad1d9ae0..c68dc4edcfb7 100644 --- a/core/java/android/util/SparseIntArray.java +++ b/core/java/android/util/SparseIntArray.java @@ -16,14 +16,15 @@ package android.util; +import android.annotation.UnsupportedAppUsage; + import com.android.internal.util.ArrayUtils; import com.android.internal.util.GrowingArrayUtils; -import java.util.Arrays; - -import android.annotation.UnsupportedAppUsage; import libcore.util.EmptyArray; +import java.util.Arrays; + /** * SparseIntArrays map integers to integers. Unlike a normal array of integers, * there can be gaps in the indices. It is intended to be more memory efficient @@ -171,6 +172,10 @@ public class SparseIntArray implements Cloneable { * key.</p> */ public int keyAt(int index) { + if (index >= mSize) { + // The array might be slightly bigger than mSize, in which case, indexing won't fail. + throw new ArrayIndexOutOfBoundsException(index); + } return mKeys[index]; } @@ -186,6 +191,10 @@ public class SparseIntArray implements Cloneable { * associated with the largest key.</p> */ public int valueAt(int index) { + if (index >= mSize) { + // The array might be slightly bigger than mSize, in which case, indexing won't fail. + throw new ArrayIndexOutOfBoundsException(index); + } return mValues[index]; } @@ -193,6 +202,10 @@ public class SparseIntArray implements Cloneable { * Directly set the value at a particular index. */ public void setValueAt(int index, int value) { + if (index >= mSize) { + // The array might be slightly bigger than mSize, in which case, indexing won't fail. + throw new ArrayIndexOutOfBoundsException(index); + } mValues[index] = value; } diff --git a/core/java/android/util/SparseLongArray.java b/core/java/android/util/SparseLongArray.java index 81db2b7ff715..37a92024f374 100644 --- a/core/java/android/util/SparseLongArray.java +++ b/core/java/android/util/SparseLongArray.java @@ -182,6 +182,10 @@ public class SparseLongArray implements Cloneable { * key.</p> */ public int keyAt(int index) { + if (index >= mSize) { + // The array might be slightly bigger than mSize, in which case, indexing won't fail. + throw new ArrayIndexOutOfBoundsException(index); + } return mKeys[index]; } @@ -197,6 +201,10 @@ public class SparseLongArray implements Cloneable { * associated with the largest key.</p> */ public long valueAt(int index) { + if (index >= mSize) { + // The array might be slightly bigger than mSize, in which case, indexing won't fail. + throw new ArrayIndexOutOfBoundsException(index); + } return mValues[index]; } 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/GestureDetector.java b/core/java/android/view/GestureDetector.java index c794a69d3680..8fbbcf4b88c6 100644 --- a/core/java/android/view/GestureDetector.java +++ b/core/java/android/view/GestureDetector.java @@ -16,11 +16,20 @@ package android.view; +import static android.util.StatsLog.TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__DEEP_PRESS; +import static android.util.StatsLog.TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__DOUBLE_TAP; +import static android.util.StatsLog.TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__LONG_PRESS; +import static android.util.StatsLog.TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__SCROLL; +import static android.util.StatsLog.TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__SINGLE_TAP; +import static android.util.StatsLog.TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__UNKNOWN_CLASSIFICATION; + import android.annotation.UnsupportedAppUsage; import android.content.Context; import android.os.Build; import android.os.Handler; import android.os.Message; +import android.os.SystemClock; +import android.util.StatsLog; /** * Detects various gestures and events using the supplied {@link MotionEvent}s. @@ -251,8 +260,12 @@ public class GestureDetector { private boolean mAlwaysInTapRegion; private boolean mAlwaysInBiggerTapRegion; private boolean mIgnoreNextUpEvent; + // Whether a classification has been recorded by statsd for the current event stream. Reset on + // ACTION_DOWN. + private boolean mHasRecordedClassification; private MotionEvent mCurrentDownEvent; + private MotionEvent mCurrentMotionEvent; private MotionEvent mPreviousUpEvent; /** @@ -297,6 +310,7 @@ public class GestureDetector { break; case LONG_PRESS: + recordGestureClassification(msg.arg1); dispatchLongPress(); break; @@ -304,6 +318,8 @@ public class GestureDetector { // If the user's finger is still down, do not count it as a tap if (mDoubleTapListener != null) { if (!mStillDown) { + recordGestureClassification( + TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__SINGLE_TAP); mDoubleTapListener.onSingleTapConfirmed(mCurrentDownEvent); } else { mDeferConfirmSingleTap = true; @@ -501,6 +517,11 @@ public class GestureDetector { final int action = ev.getAction(); + if (mCurrentMotionEvent != null) { + mCurrentMotionEvent.recycle(); + } + mCurrentMotionEvent = MotionEvent.obtain(ev); + if (mVelocityTracker == null) { mVelocityTracker = VelocityTracker.obtain(); } @@ -569,6 +590,8 @@ public class GestureDetector { && isConsideredDoubleTap(mCurrentDownEvent, mPreviousUpEvent, ev)) { // This is a second tap mIsDoubleTapping = true; + recordGestureClassification( + TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__DOUBLE_TAP); // Give a callback with the first tap of the double-tap handled |= mDoubleTapListener.onDoubleTap(mCurrentDownEvent); // Give a callback with down event of the double-tap @@ -590,11 +613,17 @@ public class GestureDetector { mStillDown = true; mInLongPress = false; mDeferConfirmSingleTap = false; + mHasRecordedClassification = false; if (mIsLongpressEnabled) { mHandler.removeMessages(LONG_PRESS); - mHandler.sendEmptyMessageAtTime(LONG_PRESS, mCurrentDownEvent.getDownTime() - + ViewConfiguration.getLongPressTimeout()); + mHandler.sendMessageAtTime( + mHandler.obtainMessage( + LONG_PRESS, + TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__LONG_PRESS, + 0 /* arg2 */), + mCurrentDownEvent.getDownTime() + + ViewConfiguration.getLongPressTimeout()); } mHandler.sendEmptyMessageAtTime(SHOW_PRESS, mCurrentDownEvent.getDownTime() + TAP_TIMEOUT); @@ -613,6 +642,8 @@ public class GestureDetector { final float scrollY = mLastFocusY - focusY; if (mIsDoubleTapping) { // Give the move events of the double-tap + recordGestureClassification( + TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__DOUBLE_TAP); handled |= mDoubleTapListener.onDoubleTapEvent(ev); } else if (mAlwaysInTapRegion) { final int deltaX = (int) (focusX - mDownFocusX); @@ -635,8 +666,12 @@ public class GestureDetector { // reschedule long press with a modified timeout. mHandler.removeMessages(LONG_PRESS); final long longPressTimeout = ViewConfiguration.getLongPressTimeout(); - mHandler.sendEmptyMessageAtTime(LONG_PRESS, ev.getDownTime() - + (long) (longPressTimeout * multiplier)); + mHandler.sendMessageAtTime( + mHandler.obtainMessage( + LONG_PRESS, + TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__LONG_PRESS, + 0 /* arg2 */), + ev.getDownTime() + (long) (longPressTimeout * multiplier)); } // Inhibit default scroll. If a gesture is ambiguous, we prevent scroll // until the gesture is resolved. @@ -646,6 +681,8 @@ public class GestureDetector { } if (distance > slopSquare) { + recordGestureClassification( + TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__SCROLL); handled = mListener.onScroll(mCurrentDownEvent, ev, scrollX, scrollY); mLastFocusX = focusX; mLastFocusY = focusY; @@ -659,6 +696,7 @@ public class GestureDetector { mAlwaysInBiggerTapRegion = false; } } else if ((Math.abs(scrollX) >= 1) || (Math.abs(scrollY) >= 1)) { + recordGestureClassification(TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__SCROLL); handled = mListener.onScroll(mCurrentDownEvent, ev, scrollX, scrollY); mLastFocusX = focusX; mLastFocusY = focusY; @@ -667,7 +705,11 @@ public class GestureDetector { motionClassification == MotionEvent.CLASSIFICATION_DEEP_PRESS; if (deepPress && hasPendingLongPress) { mHandler.removeMessages(LONG_PRESS); - mHandler.sendEmptyMessage(LONG_PRESS); + mHandler.sendMessage( + mHandler.obtainMessage( + LONG_PRESS, + TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__DEEP_PRESS, + 0 /* arg2 */)); } break; @@ -676,11 +718,15 @@ public class GestureDetector { MotionEvent currentUpEvent = MotionEvent.obtain(ev); if (mIsDoubleTapping) { // Finally, give the up event of the double-tap + recordGestureClassification( + TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__DOUBLE_TAP); handled |= mDoubleTapListener.onDoubleTapEvent(ev); } else if (mInLongPress) { mHandler.removeMessages(TAP); mInLongPress = false; } else if (mAlwaysInTapRegion && !mIgnoreNextUpEvent) { + recordGestureClassification( + TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__SINGLE_TAP); handled = mListener.onSingleTapUp(ev); if (mDeferConfirmSingleTap && mDoubleTapListener != null) { mDoubleTapListener.onSingleTapConfirmed(ev); @@ -821,4 +867,26 @@ public class GestureDetector { mInLongPress = true; mListener.onLongPress(mCurrentDownEvent); } + + private void recordGestureClassification(int classification) { + if (mHasRecordedClassification + || classification + == TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__UNKNOWN_CLASSIFICATION) { + // Only record the first classification for an event stream. + return; + } + if (mCurrentDownEvent == null || mCurrentMotionEvent == null) { + // If the complete event stream wasn't seen, don't record anything. + mHasRecordedClassification = true; + return; + } + StatsLog.write( + StatsLog.TOUCH_GESTURE_CLASSIFIED, + getClass().getName(), + classification, + (int) (SystemClock.uptimeMillis() - mCurrentMotionEvent.getDownTime()), + (float) Math.hypot(mCurrentMotionEvent.getRawX() - mCurrentDownEvent.getRawX(), + mCurrentMotionEvent.getRawY() - mCurrentDownEvent.getRawY())); + mHasRecordedClassification = true; + } } diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl index 87efb3fbf6c0..d317df05cc6e 100644 --- a/core/java/android/view/IWindowSession.aidl +++ b/core/java/android/view/IWindowSession.aidl @@ -255,12 +255,11 @@ interface IWindowSession { void updatePointerIcon(IWindow window); /** - * Update a tap exclude region with a rectangular area identified by provided id in the window. - * Touches on this region will not switch focus to this window. Passing an empty rect will - * remove the area from the exclude region of this window. + * Update a tap exclude region identified by provided id in the window. Touches on this region + * will neither be dispatched to this window nor change the focus to this window. Passing an + * invalid region will remove the area from the exclude region of this window. */ - void updateTapExcludeRegion(IWindow window, int regionId, int left, int top, int width, - int height); + void updateTapExcludeRegion(IWindow window, int regionId, in Region region); /** * Called when the client has changed the local insets state, and now the server should reflect diff --git a/core/java/android/view/InsetsState.java b/core/java/android/view/InsetsState.java index 13b0cc038fce..b76f2a175346 100644 --- a/core/java/android/view/InsetsState.java +++ b/core/java/android/view/InsetsState.java @@ -17,7 +17,10 @@ package android.view; import static android.view.ViewRootImpl.NEW_INSETS_MODE_FULL; +import static android.view.ViewRootImpl.NEW_INSETS_MODE_NONE; +import static android.view.WindowInsets.Type.MANDATORY_SYSTEM_GESTURES; import static android.view.WindowInsets.Type.SIZE; +import static android.view.WindowInsets.Type.SYSTEM_GESTURES; import static android.view.WindowInsets.Type.indexOf; import android.annotation.IntDef; @@ -55,6 +58,12 @@ public class InsetsState implements Parcelable { TYPE_SIDE_BAR_1, TYPE_SIDE_BAR_2, TYPE_SIDE_BAR_3, + TYPE_TOP_GESTURES, + TYPE_BOTTOM_GESTURES, + TYPE_LEFT_GESTURES, + TYPE_RIGHT_GESTURES, + TYPE_TOP_TAPPABLE_ELEMENT, + TYPE_BOTTOM_TAPPABLE_ELEMENT, TYPE_IME }) public @interface InternalInsetType {} @@ -73,8 +82,16 @@ public class InsetsState implements Parcelable { public static final int TYPE_SIDE_BAR_2 = 2; public static final int TYPE_SIDE_BAR_3 = 3; + public static final int TYPE_TOP_GESTURES = 4; + public static final int TYPE_BOTTOM_GESTURES = 5; + public static final int TYPE_LEFT_GESTURES = 6; + public static final int TYPE_RIGHT_GESTURES = 7; + public static final int TYPE_TOP_TAPPABLE_ELEMENT = 8; + public static final int TYPE_BOTTOM_TAPPABLE_ELEMENT = 9; + /** Input method window. */ - public static final int TYPE_IME = 4; + public static final int TYPE_IME = 10; + static final int LAST_TYPE = TYPE_IME; // Derived types @@ -137,17 +154,6 @@ public class InsetsState implements Parcelable { && legacyContentInsets != null && legacyStableInsets != null) { WindowInsets.assignCompatInsets(typeInsetsMap, legacyContentInsets); WindowInsets.assignCompatInsets(typeMaxInsetsMap, legacyStableInsets); - - // TODO: set system gesture insets based on actual system gesture area. - typeInsetsMap[Type.indexOf(Type.systemGestures())] = Insets.of(legacyContentInsets); - typeInsetsMap[Type.indexOf(Type.mandatorySystemGestures())] = - Insets.of(legacyContentInsets); - typeInsetsMap[Type.indexOf(Type.tappableElement())] = Insets.of(legacyContentInsets); - - typeMaxInsetsMap[Type.indexOf(Type.systemGestures())] = Insets.of(legacyStableInsets); - typeMaxInsetsMap[Type.indexOf(Type.mandatorySystemGestures())] = - Insets.of(legacyStableInsets); - typeMaxInsetsMap[Type.indexOf(Type.tappableElement())] = Insets.of(legacyStableInsets); } for (int type = FIRST_TYPE; type <= LAST_TYPE; type++) { InsetsSource source = mSources.get(type); @@ -159,7 +165,9 @@ public class InsetsState implements Parcelable { && (type == TYPE_TOP_BAR || type == TYPE_NAVIGATION_BAR); boolean skipIme = source.getType() == TYPE_IME && (legacySoftInputMode & LayoutParams.SOFT_INPUT_ADJUST_RESIZE) == 0; - if (skipSystemBars || skipIme) { + boolean skipLegacyTypes = ViewRootImpl.sNewInsetsMode == NEW_INSETS_MODE_NONE + && (toPublicType(type) & Type.compatSystemInsets()) != 0; + if (skipSystemBars || skipIme || skipLegacyTypes) { typeVisibilityMap[indexOf(toPublicType(type))] = source.isVisible(); continue; } @@ -183,7 +191,25 @@ public class InsetsState implements Parcelable { @Nullable boolean[] typeVisibilityMap) { Insets insets = source.calculateInsets(relativeFrame, ignoreVisibility); - int index = indexOf(toPublicType(source.getType())); + int type = toPublicType(source.getType()); + processSourceAsPublicType(source, typeInsetsMap, typeSideMap, typeVisibilityMap, + insets, type); + + if (type == MANDATORY_SYSTEM_GESTURES) { + // Mandatory system gestures are also system gestures. + // TODO: find a way to express this more generally. One option would be to define + // Type.systemGestureInsets() as NORMAL | MANDATORY, but then we lose the + // ability to set systemGestureInsets() independently from + // mandatorySystemGestureInsets() in the Builder. + processSourceAsPublicType(source, typeInsetsMap, typeSideMap, typeVisibilityMap, + insets, SYSTEM_GESTURES); + } + } + + private void processSourceAsPublicType(InsetsSource source, Insets[] typeInsetsMap, + @InsetSide @Nullable SparseIntArray typeSideMap, + @Nullable boolean[] typeVisibilityMap, Insets insets, int type) { + int index = indexOf(type); Insets existing = typeInsetsMap[index]; if (existing == null) { typeInsetsMap[index] = insets; @@ -300,6 +326,15 @@ public class InsetsState implements Parcelable { return Type.SIDE_BARS; case TYPE_IME: return Type.IME; + case TYPE_TOP_GESTURES: + case TYPE_BOTTOM_GESTURES: + return Type.MANDATORY_SYSTEM_GESTURES; + case TYPE_LEFT_GESTURES: + case TYPE_RIGHT_GESTURES: + return Type.SYSTEM_GESTURES; + case TYPE_TOP_TAPPABLE_ELEMENT: + case TYPE_BOTTOM_TAPPABLE_ELEMENT: + return Type.TAPPABLE_ELEMENT; default: throw new IllegalArgumentException("Unknown type: " + type); } @@ -336,10 +371,20 @@ public class InsetsState implements Parcelable { return "TYPE_SIDE_BAR_2"; case TYPE_SIDE_BAR_3: return "TYPE_SIDE_BAR_3"; - case TYPE_IME: - return "TYPE_IME"; + case TYPE_TOP_GESTURES: + return "TYPE_TOP_GESTURES"; + case TYPE_BOTTOM_GESTURES: + return "TYPE_BOTTOM_GESTURES"; + case TYPE_LEFT_GESTURES: + return "TYPE_LEFT_GESTURES"; + case TYPE_RIGHT_GESTURES: + return "TYPE_RIGHT_GESTURES"; + case TYPE_TOP_TAPPABLE_ELEMENT: + return "TYPE_TOP_TAPPABLE_ELEMENT"; + case TYPE_BOTTOM_TAPPABLE_ELEMENT: + return "TYPE_BOTTOM_TAPPABLE_ELEMENT"; default: - return "TYPE_UNKNOWN"; + return "TYPE_UNKNOWN_" + type; } } diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java index 0043d3258772..e3b0b7a58438 100644 --- a/core/java/android/view/SurfaceControl.java +++ b/core/java/android/view/SurfaceControl.java @@ -978,17 +978,6 @@ public final class SurfaceControl implements Parcelable { } } - private static void closeTransaction(boolean sync) { - synchronized(SurfaceControl.class) { - if (sTransactionNestCount == 0) { - Log.e(TAG, "Call to SurfaceControl.closeTransaction without matching openTransaction"); - } else if (--sTransactionNestCount > 0) { - return; - } - sGlobalTransaction.apply(sync); - } - } - /** * Merge the supplied transaction in to the deprecated "global" transaction. * This clears the supplied transaction in an identical fashion to {@link Transaction#merge}. @@ -1003,19 +992,20 @@ public final class SurfaceControl implements Parcelable { } } - /** end a transaction - * @hide + /** end a transaction + * @hide */ @UnsupportedAppUsage public static void closeTransaction() { - closeTransaction(false); - } - - /** - * @hide - */ - public static void closeTransactionSync() { - closeTransaction(true); + synchronized(SurfaceControl.class) { + if (sTransactionNestCount == 0) { + Log.e(TAG, + "Call to SurfaceControl.closeTransaction without matching openTransaction"); + } else if (--sTransactionNestCount > 0) { + return; + } + sGlobalTransaction.apply(); + } } /** diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java index e931448652c0..8070e76d1b40 100644 --- a/core/java/android/view/SurfaceView.java +++ b/core/java/android/view/SurfaceView.java @@ -491,7 +491,7 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb if (mBackgroundControl == null) { return; } - if ((mSubLayer > 0) && ((mSurfaceFlags & SurfaceControl.OPAQUE) != 0)) { + if ((mSubLayer < 0) && ((mSurfaceFlags & SurfaceControl.OPAQUE) != 0)) { mBackgroundControl.show(); mBackgroundControl.setLayer(Integer.MIN_VALUE); } else { diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index c34613ea2828..65fe87fa8ca0 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -17,6 +17,10 @@ package android.view; import static android.content.res.Resources.ID_NULL; +import static android.util.StatsLog.TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__DEEP_PRESS; +import static android.util.StatsLog.TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__LONG_PRESS; +import static android.util.StatsLog.TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__SINGLE_TAP; +import static android.util.StatsLog.TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__UNKNOWN_CLASSIFICATION; import static android.view.ViewRootImpl.NEW_INSETS_MODE_FULL; import static android.view.accessibility.AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED; @@ -86,7 +90,6 @@ import android.os.Trace; import android.sysprop.DisplayProperties; import android.text.InputType; import android.text.TextUtils; -import android.util.ArrayMap; import android.util.AttributeSet; import android.util.FloatProperty; import android.util.LayoutDirection; @@ -97,6 +100,7 @@ import android.util.Property; import android.util.SparseArray; import android.util.SparseIntArray; import android.util.StateSet; +import android.util.StatsLog; import android.util.SuperNotCalledException; import android.util.TypedValue; import android.view.AccessibilityIterators.CharacterTextSegmentIterator; @@ -4063,11 +4067,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback, }, formatToHexString = true) /* @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 123769414) public int mPrivateFlags; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 123768943) int mPrivateFlags2; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 129147060) int mPrivateFlags3; private int mPrivateFlags4; @@ -7956,6 +7960,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)) { @@ -7971,6 +7977,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 @@ -8525,11 +8533,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } /** - * Populates a {@link ViewStructure} for Content Capture. + * Populates a {@link ViewStructure} for content capture. * - * <p>This method is called after a view is that is eligible for Content Capture + * <p>This method is called after a view is that is eligible for content capture * (for example, if it {@link #isImportantForAutofill()}, an intelligence service is enabled for - * the user, and the activity rendering the view is enabled for Content Capture) is laid out and + * the user, and the activity rendering the view is enabled for content capture) is laid out and * is visible. * * <p>The populated structure is then passed to the service through @@ -8548,6 +8556,16 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * {@code childStructure.getAutofillId()} or * {@link ContentCaptureSession#newAutofillId(AutofillId, long)}. * + * <p>When the virtual view hierarchy represents a web page, you should also: + * + * <ul> + * <li>Call {@link ContentCaptureManager#getContentCaptureConditions()} to infer content + * capture events should be generate for that URL. + * <li>Create a new {@link ContentCaptureSession} child for every HTML element that + * renders a new URL (like an {@code IFRAME}) and use that session to notify events from + * that subtree. + * </ul> + * * <p><b>Note: </b>the following methods of the {@code structure} will be ignored: * <ul> * <li>{@link ViewStructure#setChildCount(int)} @@ -9264,11 +9282,13 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } /** - * Hints the Android System whether this view is considered important for Content Capture, based + * Hints the Android System whether this view is considered important for content capture, based * on the value explicitly set by {@link #setImportantForContentCapture(int)} and heuristics * when it's {@link #IMPORTANT_FOR_CONTENT_CAPTURE_AUTO}. * - * @return whether the view is considered important for autofill. + * <p>See {@link ContentCaptureManager} for more info about content capture. + * + * @return whether the view is considered important for content capture. * * @see #setImportantForContentCapture(int) * @see #IMPORTANT_FOR_CONTENT_CAPTURE_AUTO @@ -9467,7 +9487,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * Sets the (optional) {@link ContentCaptureSession} associated with this view. * * <p>This method should be called when you need to associate a {@link ContentCaptureContext} to - * the Content Capture events associated with this view or its view hierarchy (if it's a + * the content capture events associated with this view or its view hierarchy (if it's a * {@link ViewGroup}). * * <p>For example, if your activity is associated with a web domain, first you would need to @@ -9498,7 +9518,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } /** - * Gets the session used to notify Content Capture events. + * Gets the session used to notify content capture events. * * @return session explicitly set by {@link #setContentCaptureSession(ContentCaptureSession)}, * inherited by ancestors, default session or {@code null} if content capture is disabled for @@ -9719,7 +9739,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } /** - * Dispatches the initial Content Capture events for a view structure. + * Dispatches the initial content capture events for a view structure. * * @hide */ @@ -12101,6 +12121,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() { @@ -12119,6 +12141,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); @@ -13900,6 +13924,16 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } /** + * Returns whether this view can receive pointer events. + * + * @return {@code true} if this view can receive pointer events. + * @hide + */ + protected boolean canReceivePointerEvents() { + return (mViewFlags & VISIBILITY_MASK) == VISIBLE || getAnimation() != null; + } + + /** * Filter the touch event to apply security policies. * * @param event The motion event to be filtered. @@ -14542,7 +14576,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback, if (clickable) { setPressed(true, x, y); } - checkForLongClick(ViewConfiguration.getLongPressTimeout(), x, y); + checkForLongClick( + ViewConfiguration.getLongPressTimeout(), + x, + y, + // This is not a touch gesture -- do not classify it as one. + TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__UNKNOWN_CLASSIFICATION); return true; } } @@ -15283,7 +15322,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback, mHasPerformedLongPress = false; if (!clickable) { - checkForLongClick(ViewConfiguration.getLongPressTimeout(), x, y); + checkForLongClick( + ViewConfiguration.getLongPressTimeout(), + x, + y, + TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__LONG_PRESS); break; } @@ -15307,7 +15350,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } else { // Not inside a scrolling container, so show the feedback right away setPressed(true, x, y); - checkForLongClick(ViewConfiguration.getLongPressTimeout(), x, y); + checkForLongClick( + ViewConfiguration.getLongPressTimeout(), + x, + y, + TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__LONG_PRESS); } break; @@ -15344,7 +15391,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * ambiguousMultiplier); // Subtract the time already spent delay -= event.getEventTime() - event.getDownTime(); - checkForLongClick(delay, x, y); + checkForLongClick( + delay, + x, + y, + TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__LONG_PRESS); } touchSlop *= ambiguousMultiplier; } @@ -15366,7 +15417,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback, if (deepPress && hasPendingLongPressCallback()) { // process the long click action immediately removeLongPressCallback(); - checkForLongClick(0 /* send immediately */, x, y); + checkForLongClick( + 0 /* send immediately */, + x, + y, + TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__DEEP_PRESS); } break; @@ -17939,7 +17994,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); } /** @@ -17965,7 +18020,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); } /** @@ -17995,11 +18050,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; @@ -18016,11 +18070,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; @@ -22565,12 +22617,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(); } } @@ -26122,7 +26169,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } } - private void checkForLongClick(long delay, float x, float y) { + private void checkForLongClick(long delay, float x, float y, int classification) { if ((mViewFlags & LONG_CLICKABLE) == LONG_CLICKABLE || (mViewFlags & TOOLTIP) == TOOLTIP) { mHasPerformedLongPress = false; @@ -26132,6 +26179,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, mPendingCheckForLongPress.setAnchor(x, y); mPendingCheckForLongPress.rememberWindowAttachCount(); mPendingCheckForLongPress.rememberPressedState(); + mPendingCheckForLongPress.setClassification(classification); postDelayed(mPendingCheckForLongPress, delay); } } @@ -27689,11 +27737,17 @@ public class View implements Drawable.Callback, KeyEvent.Callback, private float mX; private float mY; private boolean mOriginalPressedState; + /** + * The classification of the long click being checked: one of the + * StatsLog.TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__* constants. + */ + private int mClassification; @Override public void run() { if ((mOriginalPressedState == isPressed()) && (mParent != null) && mOriginalWindowAttachCount == mWindowAttachCount) { + recordGestureClassification(mClassification); if (performLongClick(mX, mY)) { mHasPerformedLongPress = true; } @@ -27712,6 +27766,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback, public void rememberPressedState() { mOriginalPressedState = isPressed(); } + + public void setClassification(int classification) { + mClassification = classification; + } } private final class CheckForTap implements Runnable { @@ -27724,17 +27782,28 @@ public class View implements Drawable.Callback, KeyEvent.Callback, setPressed(true, x, y); final long delay = ViewConfiguration.getLongPressTimeout() - ViewConfiguration.getTapTimeout(); - checkForLongClick(delay, x, y); + checkForLongClick(delay, x, y, TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__LONG_PRESS); } } private final class PerformClick implements Runnable { @Override public void run() { + recordGestureClassification(TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__SINGLE_TAP); performClickInternal(); } } + /** Records a classification for the current event stream. */ + private void recordGestureClassification(int classification) { + if (classification == TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__UNKNOWN_CLASSIFICATION) { + return; + } + // To avoid negatively impacting View performance, the latency and displacement metrics + // are omitted. + StatsLog.write(StatsLog.TOUCH_GESTURE_CLASSIFIED, getClass().getName(), classification); + } + /** * This method returns a ViewPropertyAnimator object, which can be used to animate * specific properties on this View. @@ -28578,8 +28647,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * hierarchy is traversed: value is either the view itself for appearead events, or its * autofill id for disappeared. */ - // TODO(b/121197119): use SparseArray once session id becomes integer - ArrayMap<String, ArrayList<Object>> mContentCaptureEvents; + SparseArray<ArrayList<Object>> mContentCaptureEvents; /** * Cached reference to the {@link ContentCaptureManager}. @@ -28609,9 +28677,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback, @NonNull View view, boolean appeared) { if (mContentCaptureEvents == null) { // Most of the time there will be just one session, so intial capacity is 1 - mContentCaptureEvents = new ArrayMap<>(1); + mContentCaptureEvents = new SparseArray<>(1); } - String sessionId = session.getId(); + int sessionId = session.getId(); // TODO: life would be much easier if we provided a MultiMap implementation somwhere... ArrayList<Object> events = mContentCaptureEvents.get(sessionId); if (events == null) { diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java index 4851476e3d70..937bd1b34e61 100644 --- a/core/java/android/view/ViewGroup.java +++ b/core/java/android/view/ViewGroup.java @@ -2011,7 +2011,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager for (int i = childrenCount - 1; i >= 0; i--) { final int childIndex = getAndVerifyPreorderedIndex(childrenCount, i, customOrder); final View child = getAndVerifyPreorderedView(preorderedList, children, childIndex); - if (!canViewReceivePointerEvents(child) + if (!child.canReceivePointerEvents() || !isTransformedTouchPointInView(x, y, child, null)) { continue; } @@ -2094,7 +2094,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager childrenCount, i, customOrder); final View child = getAndVerifyPreorderedView( preorderedList, children, childIndex); - if (!canViewReceivePointerEvents(child) + if (!child.canReceivePointerEvents() || !isTransformedTouchPointInView(x, y, child, null)) { continue; } @@ -2314,7 +2314,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager getAndVerifyPreorderedIndex(childrenCount, i, customOrder); final View child = getAndVerifyPreorderedView(preorderedList, children, childIndex); - if (!canViewReceivePointerEvents(child) + if (!child.canReceivePointerEvents() || !isTransformedTouchPointInView(x, y, child, null)) { continue; } @@ -2500,7 +2500,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager for (int i = childrenCount - 1; i >= 0; i--) { final int childIndex = getAndVerifyPreorderedIndex(childrenCount, i, customOrder); final View child = getAndVerifyPreorderedView(preorderedList, children, childIndex); - if (!canViewReceivePointerEvents(child) + if (!child.canReceivePointerEvents() || !isTransformedTouchPointInView(x, y, child, null)) { continue; } @@ -2680,7 +2680,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager i = childrenCount - 1; } - if (!canViewReceivePointerEvents(child) + if (!child.canReceivePointerEvents() || !isTransformedTouchPointInView(x, y, child, null)) { ev.setTargetAccessibilityFocus(false); continue; @@ -2970,15 +2970,6 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager } } - /** - * Returns true if a child view can receive pointer events. - * @hide - */ - private static boolean canViewReceivePointerEvents(@NonNull View child) { - return (child.mViewFlags & VISIBILITY_MASK) == VISIBLE - || child.getAnimation() != null; - } - private float[] getTempPoint() { if (mTempPoint == null) { mTempPoint = new float[2]; @@ -7199,6 +7190,46 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager } } + /** + * @hide + */ + @Override + public void subtractObscuredTouchableRegion(Region touchableRegion, View view) { + final int childrenCount = mChildrenCount; + final ArrayList<View> preorderedList = buildTouchDispatchChildList(); + final boolean customOrder = preorderedList == null && isChildrenDrawingOrderEnabled(); + final View[] children = mChildren; + for (int i = childrenCount - 1; i >= 0; i--) { + final int childIndex = getAndVerifyPreorderedIndex(childrenCount, i, customOrder); + final View child = getAndVerifyPreorderedView(preorderedList, children, childIndex); + if (child == view) { + // We've reached the target view. + break; + } + if (!child.canReceivePointerEvents()) { + // This child cannot be touched. Skip it. + continue; + } + applyOpToRegionByBounds(touchableRegion, child, Region.Op.DIFFERENCE); + } + + // The touchable region should not exceed the bounds of its container. + applyOpToRegionByBounds(touchableRegion, this, Region.Op.INTERSECT); + + final ViewParent parent = getParent(); + if (parent != null) { + parent.subtractObscuredTouchableRegion(touchableRegion, this); + } + } + + private static void applyOpToRegionByBounds(Region region, View view, Region.Op op) { + final int[] locationInWindow = new int[2]; + view.getLocationInWindow(locationInWindow); + final int x = locationInWindow[0]; + final int y = locationInWindow[1]; + region.op(x, y, x + view.getWidth(), y + view.getHeight(), op); + } + @Override public WindowInsets dispatchApplyWindowInsets(WindowInsets insets) { insets = super.dispatchApplyWindowInsets(insets); diff --git a/core/java/android/view/ViewParent.java b/core/java/android/view/ViewParent.java index 572e69b1a78c..feba7bb7f195 100644 --- a/core/java/android/view/ViewParent.java +++ b/core/java/android/view/ViewParent.java @@ -18,6 +18,7 @@ package android.view; import android.annotation.NonNull; import android.graphics.Rect; +import android.graphics.Region; import android.os.Bundle; import android.view.accessibility.AccessibilityEvent; @@ -660,4 +661,17 @@ public interface ViewParent { * @return true if the action was consumed by this ViewParent */ public boolean onNestedPrePerformAccessibilityAction(View target, int action, Bundle arguments); + + /** + * Given a touchable region of a child, this method reduces region by the bounds of all views on + * top of the child for which {@link View#canReceivePointerEvents} returns {@code true}. This + * applies recursively for all views in the view hierarchy on top of this one. + * + * @param touchableRegion The touchable region we want to modify. + * @param view A child view of this ViewGroup which indicates the z-order of the touchable + * region. + * @hide + */ + default void subtractObscuredTouchableRegion(Region touchableRegion, View view) { + } } diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 2880e7f13545..f3b7ad5e557c 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -1455,6 +1455,8 @@ public final class ViewRootImpl implements ViewParent, @Override public void onDescendantInvalidated(@NonNull View child, @NonNull View descendant) { + // TODO: Re-enable after camera is fixed or consider targetSdk checking this + // checkThread(); if ((descendant.mPrivateFlags & PFLAG_DRAW_ANIMATION) != 0) { mIsAnimating = true; } @@ -1915,16 +1917,10 @@ public final class ViewRootImpl implements ViewParent, } contentInsets = ensureInsetsNonNegative(contentInsets, "content"); stableInsets = ensureInsetsNonNegative(stableInsets, "stable"); - if (sNewInsetsMode != NEW_INSETS_MODE_NONE) { - mLastWindowInsets = mInsetsController.calculateInsets( - mContext.getResources().getConfiguration().isScreenRound(), - mAttachInfo.mAlwaysConsumeSystemBars, displayCutout, - contentInsets, stableInsets, mWindowAttributes.softInputMode); - } else { - mLastWindowInsets = new WindowInsets(contentInsets, stableInsets, - mContext.getResources().getConfiguration().isScreenRound(), - mAttachInfo.mAlwaysConsumeSystemBars, displayCutout); - } + mLastWindowInsets = mInsetsController.calculateInsets( + mContext.getResources().getConfiguration().isScreenRound(), + mAttachInfo.mAlwaysConsumeSystemBars, displayCutout, + contentInsets, stableInsets, mWindowAttributes.softInputMode); } return mLastWindowInsets; } @@ -1985,7 +1981,6 @@ public final class ViewRootImpl implements ViewParent, mIsInTraversal = true; mWillDrawSoon = true; boolean windowSizeMayChange = false; - boolean newSurface = false; boolean surfaceChanged = false; WindowManager.LayoutParams lp = mWindowAttributes; @@ -2386,13 +2381,7 @@ public final class ViewRootImpl implements ViewParent, if (!hadSurface) { if (mSurface.isValid()) { // If we are creating a new surface, then we need to - // completely redraw it. Also, when we get to the - // point of drawing it we will hold off and schedule - // a new traversal instead. This is so we can tell the - // window manager about all of the windows being displayed - // before actually drawing them, so it can display then - // all at once. - newSurface = true; + // completely redraw it. mFullRedrawNeeded = true; mPreviousTransparentRegion.setEmpty(); @@ -2777,7 +2766,7 @@ public final class ViewRootImpl implements ViewParent, boolean cancelDraw = mAttachInfo.mTreeObserver.dispatchOnPreDraw() || !isViewVisible; - if (!cancelDraw && !newSurface) { + if (!cancelDraw) { if (mPendingTransitions != null && mPendingTransitions.size() > 0) { for (int i = 0; i < mPendingTransitions.size(); ++i) { mPendingTransitions.get(i).startChangingAnimations(); @@ -2811,8 +2800,7 @@ public final class ViewRootImpl implements ViewParent, MainContentCaptureSession mainSession = mAttachInfo.mContentCaptureManager .getMainContentCaptureSession(); for (int i = 0; i < mAttachInfo.mContentCaptureEvents.size(); i++) { - String sessionId = mAttachInfo.mContentCaptureEvents - .keyAt(i); + int sessionId = mAttachInfo.mContentCaptureEvents.keyAt(i); mainSession.notifyViewTreeEvent(sessionId, /* started= */ true); ArrayList<Object> events = mAttachInfo.mContentCaptureEvents .valueAt(i); @@ -2827,8 +2815,8 @@ public final class ViewRootImpl implements ViewParent, Log.w(mTag, "no content capture session on view: " + view); continue for_each_event; } - String actualId = session.getId().toString(); - if (!actualId.equals(sessionId)) { + int actualId = session.getId(); + if (actualId != sessionId) { Log.w(mTag, "content capture session mismatch for view (" + view + "): was " + sessionId + " before, it's " + actualId + " now"); continue for_each_event; @@ -3986,7 +3974,7 @@ public final class ViewRootImpl implements ViewParent, void systemGestureExclusionChanged() { final List<Rect> rectsForWindowManager = mGestureExclusionTracker.computeChangedRects(); - if (rectsForWindowManager != null) { + if (rectsForWindowManager != null && mView != null) { try { mWindowSession.reportSystemGestureExclusionChanged(mWindow, rectsForWindowManager); } catch (RemoteException e) { diff --git a/core/java/android/view/WindowInsets.java b/core/java/android/view/WindowInsets.java index ffa769a424a9..2d292ef7b25c 100644 --- a/core/java/android/view/WindowInsets.java +++ b/core/java/android/view/WindowInsets.java @@ -29,9 +29,6 @@ import static android.view.WindowInsets.Type.TOP_BAR; import static android.view.WindowInsets.Type.all; import static android.view.WindowInsets.Type.compatSystemInsets; import static android.view.WindowInsets.Type.indexOf; -import static android.view.WindowInsets.Type.mandatorySystemGestures; -import static android.view.WindowInsets.Type.systemGestures; -import static android.view.WindowInsets.Type.tappableElement; import android.annotation.IntDef; import android.annotation.IntRange; @@ -225,10 +222,6 @@ public final class WindowInsets { } Insets[] typeInsetMap = new Insets[SIZE]; assignCompatInsets(typeInsetMap, insets); - // TODO: set system gesture insets based on actual system gesture area. - typeInsetMap[indexOf(systemGestures())] = Insets.of(insets); - typeInsetMap[indexOf(mandatorySystemGestures())] = Insets.of(insets); - typeInsetMap[indexOf(tappableElement())] = Insets.of(insets); return typeInsetMap; } diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java index 385d491f49ef..774a359e5d6c 100644 --- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java +++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java @@ -1682,17 +1682,29 @@ public class AccessibilityNodeInfo implements Parcelable { } /** - * Gets the node bounds in parent coordinates. + * Gets the node bounds in the viewParent's coordinates. + * {@link #getParent()} does not represent the source's viewParent. + * Instead it represents the result of {@link View#getParentForAccessibility()}, + * which returns the closest ancestor where {@link View#isImportantForAccessibility()} is true. + * So this method is not reliable. * * @param outBounds The output node bounds. + * @deprecated Use {@link #getBoundsInScreen(Rect)} instead. + * */ + @Deprecated public void getBoundsInParent(Rect outBounds) { outBounds.set(mBoundsInParent.left, mBoundsInParent.top, mBoundsInParent.right, mBoundsInParent.bottom); } /** - * Sets the node bounds in parent coordinates. + * Sets the node bounds in the viewParent's coordinates. + * {@link #getParent()} does not represent the source's viewParent. + * Instead it represents the result of {@link View#getParentForAccessibility()}, + * which returns the closest ancestor where {@link View#isImportantForAccessibility()} is true. + * So this method is not reliable. + * * <p> * <strong>Note:</strong> Cannot be called from an * {@link android.accessibilityservice.AccessibilityService}. @@ -1702,7 +1714,9 @@ public class AccessibilityNodeInfo implements Parcelable { * @param bounds The node bounds. * * @throws IllegalStateException If called from an AccessibilityService. + * @deprecated Accessibility services should not care about these bounds. */ + @Deprecated public void setBoundsInParent(Rect bounds) { enforceNotSealed(); mBoundsInParent.set(bounds.left, bounds.top, bounds.right, bounds.bottom); diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java index 77a0c4c5f4ee..6503a800acb7 100644 --- a/core/java/android/view/autofill/AutofillManager.java +++ b/core/java/android/view/autofill/AutofillManager.java @@ -2178,6 +2178,18 @@ public final class AutofillManager { boolean saveOnAllViewsInvisible, boolean saveOnFinish, @Nullable AutofillId[] fillableIds, @Nullable AutofillId saveTriggerId) { synchronized (mLock) { + if (sVerbose) { + Log.v(TAG, "setTrackedViews(): sessionId=" + sessionId + + ", trackedIds=" + Arrays.toString(trackedIds) + + ", saveOnAllViewsInvisible=" + saveOnAllViewsInvisible + + ", saveOnFinish=" + saveOnFinish + + ", fillableIds=" + Arrays.toString(fillableIds) + + ", saveTrigerId=" + saveTriggerId + + ", mFillableIds=" + mFillableIds + + ", mEnabled=" + mEnabled + + ", mSessionId=" + mSessionId); + + } if (mEnabled && mSessionId == sessionId) { if (saveOnAllViewsInvisible) { mTrackedViews = new TrackedViews(trackedIds); @@ -2192,10 +2204,6 @@ public final class AutofillManager { for (AutofillId id : fillableIds) { mFillableIds.add(id); } - if (sVerbose) { - Log.v(TAG, "setTrackedViews(): fillableIds=" + Arrays.toString(fillableIds) - + ", mFillableIds" + mFillableIds); - } } if (mSaveTriggerId != null && !mSaveTriggerId.equals(saveTriggerId)) { diff --git a/core/java/android/view/autofill/AutofillManagerInternal.java b/core/java/android/view/autofill/AutofillManagerInternal.java index d5862bd2f942..3de1a03d98e5 100644 --- a/core/java/android/view/autofill/AutofillManagerInternal.java +++ b/core/java/android/view/autofill/AutofillManagerInternal.java @@ -33,7 +33,10 @@ public abstract class AutofillManagerInternal { public abstract void onBackKeyPressed(); /** - * Gets autofill options for a package + * Gets autofill options for a package. + * + * <p><b>NOTE: </b>this method is called by the {@code ActivityManager} service and hence cannot + * hold the main service lock. * * @param packageName The package for which to query. * @param versionCode The package version code. diff --git a/cmds/statsd/src/logd/LogListener.cpp b/core/java/android/view/contentcapture/ContentCaptureCondition.aidl index ddb26f9fe565..99f8894408b3 100644 --- a/cmds/statsd/src/logd/LogListener.cpp +++ b/core/java/android/view/contentcapture/ContentCaptureCondition.aidl @@ -1,11 +1,11 @@ -/* - * Copyright (C) 2017 The Android Open Source Project +/** + * 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 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,18 +14,6 @@ * limitations under the License. */ -#include "logd/LogListener.h" +package android.view.contentcapture; -namespace android { -namespace os { -namespace statsd { - -LogListener::LogListener() { -} - -LogListener::~LogListener() { -} - -} // namespace statsd -} // namespace os -} // namespace android +parcelable ContentCaptureCondition; diff --git a/core/java/android/view/contentcapture/ContentCaptureCondition.java b/core/java/android/view/contentcapture/ContentCaptureCondition.java index ed872578d069..cf171d738524 100644 --- a/core/java/android/view/contentcapture/ContentCaptureCondition.java +++ b/core/java/android/view/contentcapture/ContentCaptureCondition.java @@ -20,6 +20,7 @@ import android.annotation.NonNull; import android.content.LocusId; import android.os.Parcel; import android.os.Parcelable; +import android.util.DebugUtils; import com.android.internal.util.Preconditions; @@ -58,7 +59,6 @@ public final class ContentCaptureCondition implements Parcelable { public ContentCaptureCondition(@NonNull LocusId locusId, @Flags int flags) { this.mLocusId = Preconditions.checkNotNull(locusId); this.mFlags = flags; - // TODO(b/129267994): check flags, add test case for null and invalid flags } /** @@ -79,6 +79,42 @@ public final class ContentCaptureCondition implements Parcelable { } @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + mFlags; + result = prime * result + ((mLocusId == null) ? 0 : mLocusId.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null) return false; + if (getClass() != obj.getClass()) return false; + final ContentCaptureCondition other = (ContentCaptureCondition) obj; + if (mFlags != other.mFlags) return false; + if (mLocusId == null) { + if (other.mLocusId != null) return false; + } else { + if (!mLocusId.equals(other.mLocusId)) return false; + } + return true; + } + + @Override + public String toString() { + final StringBuilder string = new StringBuilder(mLocusId.toString()); // LocusID is PII safe + if (mFlags != 0) { + string + .append(" (") + .append(DebugUtils.flagsToString(ContentCaptureCondition.class, "FLAG_", mFlags)) + .append(')'); + } + return string.toString(); + } + + @Override public int describeContents() { return 0; } diff --git a/core/java/android/view/contentcapture/ContentCaptureContext.java b/core/java/android/view/contentcapture/ContentCaptureContext.java index 5a27e94aa495..94e548fa0eeb 100644 --- a/core/java/android/view/contentcapture/ContentCaptureContext.java +++ b/core/java/android/view/contentcapture/ContentCaptureContext.java @@ -15,6 +15,8 @@ */ package android.view.contentcapture; +import static android.view.contentcapture.ContentCaptureSession.NO_SESSION_ID; + import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; @@ -35,9 +37,9 @@ import com.android.internal.util.Preconditions; import java.io.PrintWriter; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; - /** - * Context associated with a {@link ContentCaptureSession}. + * Context associated with a {@link ContentCaptureSession} - see {@link ContentCaptureManager} for + * more info. */ public final class ContentCaptureContext implements Parcelable { @@ -50,8 +52,7 @@ public final class ContentCaptureContext implements Parcelable { /** * Flag used to indicate that the app explicitly disabled content capture for the activity - * (using - * {@link android.view.contentcapture.ContentCaptureManager#setContentCaptureEnabled(boolean)}), + * (using {@link ContentCaptureManager#setContentCaptureEnabled(boolean)}), * in which case the service will just receive activity-level events. * * @hide @@ -107,7 +108,7 @@ public final class ContentCaptureContext implements Parcelable { private final int mDisplayId; // Fields below are set by the service upon "delivery" and are not marshalled in the parcel - private @Nullable String mParentSessionId; + private int mParentSessionId = NO_SESSION_ID; /** @hide */ public ContentCaptureContext(@Nullable ContentCaptureContext clientContext, @@ -198,11 +199,12 @@ public final class ContentCaptureContext implements Parcelable { @SystemApi @TestApi public @Nullable ContentCaptureSessionId getParentSessionId() { - return mParentSessionId == null ? null : new ContentCaptureSessionId(mParentSessionId); + return mParentSessionId == NO_SESSION_ID ? null + : new ContentCaptureSessionId(mParentSessionId); } /** @hide */ - public void setParentSessionId(@NonNull String parentSessionId) { + public void setParentSessionId(int parentSessionId) { mParentSessionId = parentSessionId; } @@ -260,9 +262,10 @@ public final class ContentCaptureContext implements Parcelable { * <li>A unique identifier of the application state (for example, a conversation between * 2 users in a chat app). * + * <p>See {@link ContentCaptureManager} for more info about the content capture context. + * * @param id id associated with this context. */ - // TODO(b/123577059): make sure this is well documented and understandable public Builder(@NonNull LocusId id) { mId = Preconditions.checkNotNull(id); } @@ -316,7 +319,7 @@ public final class ContentCaptureContext implements Parcelable { } pw.print(", taskId="); pw.print(mTaskId); pw.print(", displayId="); pw.print(mDisplayId); - if (mParentSessionId != null) { + if (mParentSessionId != NO_SESSION_ID) { pw.print(", parentId="); pw.print(mParentSessionId); } if (mFlags > 0) { @@ -348,7 +351,7 @@ public final class ContentCaptureContext implements Parcelable { builder.append(", hasExtras"); } } - if (mParentSessionId != null) { + if (mParentSessionId != NO_SESSION_ID) { builder.append(", parentId=").append(mParentSessionId); } return builder.append(']').toString(); diff --git a/core/java/android/view/contentcapture/ContentCaptureEvent.java b/core/java/android/view/contentcapture/ContentCaptureEvent.java index 8188e0592b9d..bd386292f95d 100644 --- a/core/java/android/view/contentcapture/ContentCaptureEvent.java +++ b/core/java/android/view/contentcapture/ContentCaptureEvent.java @@ -16,6 +16,7 @@ package android.view.contentcapture; import static android.view.contentcapture.ContentCaptureHelper.getSanitizedString; +import static android.view.contentcapture.ContentCaptureSession.NO_SESSION_ID; import android.annotation.IntDef; import android.annotation.NonNull; @@ -126,25 +127,25 @@ public final class ContentCaptureEvent implements Parcelable { @Retention(RetentionPolicy.SOURCE) public @interface EventType{} - private final @NonNull String mSessionId; + private final int mSessionId; private final int mType; private final long mEventTime; private @Nullable AutofillId mId; private @Nullable ArrayList<AutofillId> mIds; private @Nullable ViewNode mNode; private @Nullable CharSequence mText; - private @Nullable String mParentSessionId; + private int mParentSessionId = NO_SESSION_ID; private @Nullable ContentCaptureContext mClientContext; /** @hide */ - public ContentCaptureEvent(@NonNull String sessionId, int type, long eventTime) { + public ContentCaptureEvent(int sessionId, int type, long eventTime) { mSessionId = sessionId; mType = type; mEventTime = eventTime; } /** @hide */ - public ContentCaptureEvent(@NonNull String sessionId, int type) { + public ContentCaptureEvent(int sessionId, int type) { this(sessionId, type, System.currentTimeMillis()); } @@ -185,7 +186,7 @@ public final class ContentCaptureEvent implements Parcelable { * * @hide */ - public ContentCaptureEvent setParentSessionId(@NonNull String parentSessionId) { + public ContentCaptureEvent setParentSessionId(int parentSessionId) { mParentSessionId = parentSessionId; return this; } @@ -202,7 +203,7 @@ public final class ContentCaptureEvent implements Parcelable { /** @hide */ @NonNull - public String getSessionId() { + public int getSessionId() { return mSessionId; } @@ -212,7 +213,7 @@ public final class ContentCaptureEvent implements Parcelable { * @hide */ @Nullable - public String getParentSessionId() { + public int getParentSessionId() { return mParentSessionId; } @@ -357,10 +358,10 @@ public final class ContentCaptureEvent implements Parcelable { if (mNode != null) { pw.print(", mNode.id="); pw.print(mNode.getAutofillId()); } - if (mSessionId != null) { + if (mSessionId != NO_SESSION_ID) { pw.print(", sessionId="); pw.print(mSessionId); } - if (mParentSessionId != null) { + if (mParentSessionId != NO_SESSION_ID) { pw.print(", parentSessionId="); pw.print(mParentSessionId); } if (mText != null) { @@ -377,7 +378,7 @@ public final class ContentCaptureEvent implements Parcelable { final StringBuilder string = new StringBuilder("ContentCaptureEvent[type=") .append(getTypeAsString(mType)); string.append(", session=").append(mSessionId); - if (mType == TYPE_SESSION_STARTED && mParentSessionId != null) { + if (mType == TYPE_SESSION_STARTED && mParentSessionId != NO_SESSION_ID) { string.append(", parent=").append(mParentSessionId); } if (mId != null) { @@ -409,7 +410,7 @@ public final class ContentCaptureEvent implements Parcelable { @Override public void writeToParcel(Parcel parcel, int flags) { - parcel.writeString(mSessionId); + parcel.writeInt(mSessionId); parcel.writeInt(mType); parcel.writeLong(mEventTime); parcel.writeParcelable(mId, flags); @@ -417,7 +418,7 @@ public final class ContentCaptureEvent implements Parcelable { ViewNode.writeToParcel(parcel, mNode, flags); parcel.writeCharSequence(mText); if (mType == TYPE_SESSION_STARTED || mType == TYPE_SESSION_FINISHED) { - parcel.writeString(mParentSessionId); + parcel.writeInt(mParentSessionId); } if (mType == TYPE_SESSION_STARTED || mType == TYPE_CONTEXT_UPDATED) { parcel.writeParcelable(mClientContext, flags); @@ -430,7 +431,7 @@ public final class ContentCaptureEvent implements Parcelable { @Override @NonNull public ContentCaptureEvent createFromParcel(Parcel parcel) { - final String sessionId = parcel.readString(); + final int sessionId = parcel.readInt(); final int type = parcel.readInt(); final long eventTime = parcel.readLong(); final ContentCaptureEvent event = new ContentCaptureEvent(sessionId, type, eventTime); @@ -448,7 +449,7 @@ public final class ContentCaptureEvent implements Parcelable { } event.setText(parcel.readCharSequence()); if (type == TYPE_SESSION_STARTED || type == TYPE_SESSION_FINISHED) { - event.setParentSessionId(parcel.readString()); + event.setParentSessionId(parcel.readInt()); } if (type == TYPE_SESSION_STARTED || type == TYPE_CONTEXT_UPDATED) { event.setClientContext(parcel.readParcelable(null)); diff --git a/core/java/android/view/contentcapture/ContentCaptureHelper.java b/core/java/android/view/contentcapture/ContentCaptureHelper.java index 6bc382907457..c7ca2209d387 100644 --- a/core/java/android/view/contentcapture/ContentCaptureHelper.java +++ b/core/java/android/view/contentcapture/ContentCaptureHelper.java @@ -23,9 +23,14 @@ import static android.view.contentcapture.ContentCaptureManager.LOGGING_LEVEL_VE import android.annotation.Nullable; import android.os.Build; import android.provider.DeviceConfig; +import android.util.ArraySet; import android.util.Log; import android.view.contentcapture.ContentCaptureManager.LoggingLevel; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + /** * Helper class for this package and server's. * @@ -101,6 +106,22 @@ public final class ContentCaptureHelper { } } + /** + * Converts a set to a list. + */ + @Nullable + public static <T> ArrayList<T> toList(@Nullable Set<T> set) { + return set == null ? null : new ArrayList<T>(set); + } + + /** + * Converts a list to a set. + */ + @Nullable + public static <T> ArraySet<T> toSet(@Nullable List<T> list) { + return list == null ? null : new ArraySet<T>(list); + } + private ContentCaptureHelper() { throw new UnsupportedOperationException("contains only static methods"); } diff --git a/core/java/android/view/contentcapture/ContentCaptureManager.java b/core/java/android/view/contentcapture/ContentCaptureManager.java index 817b13011402..253935680cb8 100644 --- a/core/java/android/view/contentcapture/ContentCaptureManager.java +++ b/core/java/android/view/contentcapture/ContentCaptureManager.java @@ -17,6 +17,7 @@ package android.view.contentcapture; import static android.view.contentcapture.ContentCaptureHelper.sDebug; import static android.view.contentcapture.ContentCaptureHelper.sVerbose; +import static android.view.contentcapture.ContentCaptureHelper.toSet; import android.annotation.IntDef; import android.annotation.NonNull; @@ -28,12 +29,15 @@ import android.annotation.UiThread; import android.content.ComponentName; import android.content.ContentCaptureOptions; import android.content.Context; +import android.graphics.Canvas; import android.os.Handler; import android.os.IBinder; import android.os.Looper; import android.os.RemoteException; import android.os.ServiceManager; import android.util.Log; +import android.view.View; +import android.view.ViewStructure; import android.view.contentcapture.ContentCaptureSession.FlushReason; import com.android.internal.annotations.GuardedBy; @@ -43,10 +47,152 @@ import com.android.internal.util.SyncResultReceiver; import java.io.PrintWriter; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import java.util.ArrayList; import java.util.Set; /** - * TODO(b/123577059): add javadocs / mention it can be null + * <p>The {@link ContentCaptureManager} provides additional ways for for apps to + * integrate with the content capture subsystem. + * + * <p>Content capture provides real-time, continuous capture of application activity, display and + * events to an intelligence service that is provided by the Android system. The intelligence + * service then uses that info to mediate and speed user journey through different apps. For + * example, when the user receives a restaurant address in a chat app and switchs to a map app + * to search for that restaurant, the intelligence service could offer an autofill dialog to + * let the user automatically select its address. + * + * <p>Content capture was designed with two major concerns in mind: privacy and performance. + * + * <ul> + * <li><b>Privacy:</b> the intelligence service is a trusted component provided that is provided + * by the device manufacturer and that cannot be changed by the user (although the user can + * globaly disable content capture using the Android Settings app). This service can only use the + * data for in-device machine learning, which is enforced both by process isolation and + * <a href="https://source.android.com/compatibility/cdd">CDD requirements</a>. + * <li><b>Performance:</b> content capture is highly optimized to minimize its impact in the app + * jankiness and overall device system health. For example, its only enabled on apps (or even + * specific activities from an app) that were explicitly whitelisted by the intelligence service, + * and it buffers the events so they are sent in a batch to the service (see + * {@link #isContentCaptureEnabled()} for other cases when its disabled). + * </ul> + * + * <p>In fact, before using this manager, the app developer should check if it's available. Example: + * <code> + * ContentCaptureManager mgr = context.getSystemService(ContentCaptureManager.class); + * if (mgr != null && mgr.isContentCaptureEnabled()) { + * // ... + * } + * </code> + * + * <p>App developers usually don't need to explicitly interact with content capture, except when the + * app: + * + * <ul> + * <li>Can define a contextual {@link android.content.LocusId} to identify unique state (such as a + * conversation between 2 chat users). + * <li>Can have multiple view hierarchies with different contextual meaning (for example, a + * browser app with multiple tabs, each representing a different URL). + * <li>Contains custom views (that extend View directly and are not provided by the standard + * Android SDK. + * <li>Contains views that provide their own virtual hierarchy (like a web browser that render the + * HTML elements using a Canvas). + * </ul> + * + * <p>The main integration point with content capture is the {@link ContentCaptureSession}. A "main" + * session is automatically created by the Android System when content capture is enabled for the + * activity and its used by the standard Android views to notify the content capture service of + * events such as views being added, views been removed, and text changed by user input. The session + * could have a {@link ContentCaptureContext} to provide more contextual info about it, such as + * the locus associated with the view hierarchy (see {@link android.content.LocusId} for more info + * about locus). By default, the main session doesn't have a {@code ContentCaptureContext}, but you + * can change it after its created. Example: + * + * <pre><code> + * protected void onCreate(Bundle savedInstanceState) { + * // Initialize view structure + * ContentCaptureSession session = rootView.getContentCaptureSession(); + * if (session != null) { + * session.setContentCaptureContext(ContentCaptureContext.forLocusId("chat_UserA_UserB")); + * } + * } + * </code></pre> + * + * <p>If your activity contains view hierarchies with a different contextual meaning, you should + * created child sessions for each view hierarchy root. For example, if your activity is a browser, + * you could use the main session for the main URL being rendered, then child sessions for each + * {@code IFRAME}: + * + * <pre><code> + * ContentCaptureSession mMainSession; + * + * protected void onCreate(Bundle savedInstanceState) { + * // Initialize view structure... + * mMainSession = rootView.getContentCaptureSession(); + * if (mMainSession != null) { + * mMainSession.setContentCaptureContext( + * ContentCaptureContext.forLocusId("https://example.com")); + * } + * } + * + * private void loadIFrame(View iframeRootView, String url) { + * if (mMainSession != null) { + * ContentCaptureSession iFrameSession = mMainSession.newChild( + * ContentCaptureContext.forLocusId(url)); + * } + * iframeRootView.setContentCaptureSession(iFrameSession); + * } + * // Load iframe... + * } + * </code></pre> + * + * <p>If your activity has custom views (i.e., views that extend {@link View} directly and provide + * just one logical view, not a virtual tree hiearchy) and it provides content that's relevant for + * content capture (as of {@link android.os.Build.VERSION_CODES#Q Android Q}, the only relevant + * content is text), then your view implementation should: + * + * <ul> + * <li>Set it as important for content capture. + * <li>Fill {@link ViewStructure} used for content capture. + * <li>Notify the {@link ContentCaptureSession} when the text is changed by user input. + * </ul> + * + * <p>Here's an example of the relevant methods for an {@code EditText}-like view: + * + * <pre><code> + * public class MyEditText extends View { + * + * public MyEditText(...) { + * if (getImportantForContentCapture() == IMPORTANT_FOR_CONTENT_CAPTURE_AUTO) { + * setImportantForContentCapture(IMPORTANT_FOR_CONTENT_CAPTURE_YES); + * } + * } + * + * public void onProvideContentCaptureStructure(@NonNull ViewStructure structure, int flags) { + * super.onProvideContentCaptureStructure(structure, flags); + * + * structure.setText(getText(), getSelectionStart(), getSelectionEnd()); + * structure.setHint(getHint()); + * structure.setInputType(getInputType()); + * // set other properties like setTextIdEntry(), setTextLines(), setTextStyle(), + * // setMinTextEms(), setMaxTextEms(), setMaxTextLength() + * } + * + * private void onTextChanged() { + * if (isLaidOut() && isImportantForContentCapture() && isTextEditable()) { + * ContentCaptureManager mgr = mContext.getSystemService(ContentCaptureManager.class); + * if (cm != null && cm.isContentCaptureEnabled()) { + * ContentCaptureSession session = getContentCaptureSession(); + * if (session != null) { + * session.notifyViewTextChanged(getAutofillId(), getText()); + * } + * } + * } + * </code></pre> + * + * <p>If your view provides its own virtual hierarchy (for example, if it's a browser that draws + * the HTML using {@link Canvas} or native libraries in a different render process), then the view + * is also responsible to notify the session when the virtual elements appear and disappear - see + * {@link View#onProvideContentCaptureStructure(ViewStructure, int)} for more info. */ @SystemService(Context.CONTENT_CAPTURE_MANAGER_SERVICE) public final class ContentCaptureManager { @@ -69,7 +215,7 @@ public final class ContentCaptureManager { /** * DeviceConfig property used by {@code com.android.server.SystemServer} on start to decide - * whether the Content Capture service should be created or not + * whether the content capture service should be created or not * * <p>By default it should *NOT* be set (or set to {@code "default"}, so the decision is based * on whether the OEM provides an implementation for the service), but it can be overridden to: @@ -340,12 +486,12 @@ public final class ContentCaptureManager { * <p>There are many reasons it could be disabled, such as: * <ul> * <li>App itself disabled content capture through {@link #setContentCaptureEnabled(boolean)}. - * <li>Service disabled content capture for this specific activity. - * <li>Service disabled content capture for all activities of this package. - * <li>Service disabled content capture globally. - * <li>User disabled content capture globally (through Settings). - * <li>OEM disabled content capture globally. - * <li>Transient errors. + * <li>Intelligence service did not whitelist content capture for this activity's package. + * <li>Intelligence service did not whitelist content capture for this specific activity. + * <li>Intelligence service disabled content capture globally. + * <li>User disabled content capture globally through the Android Settings app. + * <li>Device manufacturer (OEM) disabled content capture globally. + * <li>Transient errors, such as intelligence service package being updated. * </ul> */ public boolean isContentCaptureEnabled() { @@ -369,11 +515,22 @@ public final class ContentCaptureManager { * capture events for websites the content capture service is not interested on. * * @return list of conditions, or {@code null} if the service didn't set any restriction - * (in which case content capture events should always be generated). + * (in which case content capture events should always be generated). If the list is empty, + * then it should not generate any event at all. */ @Nullable public Set<ContentCaptureCondition> getContentCaptureConditions() { - return null; // TODO(b/129267994): implement + // NOTE: we could cache the conditions on ContentCaptureOptions, but then it would be stick + // to the lifetime of the app. OTOH, by dynamically calling the server every time, we allow + // the service to fine tune how long-lived apps (like browsers) are whitelisted. + if (!isContentCaptureEnabled() && !mOptions.lite) return null; + + final SyncResultReceiver resultReceiver = syncRun( + (r) -> mService.getContentCaptureConditions(mContext.getPackageName(), r)); + + final ArrayList<ContentCaptureCondition> result = resultReceiver + .getParcelableListResult(); + return toSet(result); } /** @@ -393,12 +550,12 @@ public final class ContentCaptureManager { } /** - * Gets whether Content Capture is enabled for the given user. + * Gets whether content capture is enabled for the given user. * - * <p>This method is typically used by the Content Capture Service settings page, so it can + * <p>This method is typically used by the content capture service settings page, so it can * provide a toggle to enable / disable it. * - * @throws SecurityException if caller is not the app that owns the Content Capture service + * @throws SecurityException if caller is not the app that owns the content capture service * associated with the user. * * @hide @@ -406,21 +563,14 @@ public final class ContentCaptureManager { @SystemApi @TestApi public boolean isContentCaptureFeatureEnabled() { - final SyncResultReceiver resultReceiver = new SyncResultReceiver(SYNC_CALLS_TIMEOUT_MS); - final int resultCode; - try { - mService.isContentCaptureFeatureEnabled(resultReceiver); - resultCode = resultReceiver.getIntResult(); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } + final SyncResultReceiver resultReceiver = syncRun( + (r) -> mService.isContentCaptureFeatureEnabled(r)); + final int resultCode = resultReceiver.getIntResult(); switch (resultCode) { case RESULT_CODE_TRUE: return true; case RESULT_CODE_FALSE: return false; - case RESULT_CODE_SECURITY_EXCEPTION: - throw new SecurityException("caller is not user's ContentCapture service"); default: Log.wtf(TAG, "received invalid result: " + resultCode); return false; @@ -428,7 +578,7 @@ public final class ContentCaptureManager { } /** - * Called by the app to request the Content Capture service to remove user-data associated with + * Called by the app to request the content capture service to remove user-data associated with * some context. * * @param request object specifying what user data should be removed. @@ -443,6 +593,26 @@ public final class ContentCaptureManager { } } + /** + * Runs a sync method in the service, properly handling exceptions. + * + * @throws SecurityException if caller is not allowed to execute the method. + */ + @NonNull + private SyncResultReceiver syncRun(@NonNull MyRunnable r) { + final SyncResultReceiver resultReceiver = new SyncResultReceiver(SYNC_CALLS_TIMEOUT_MS); + try { + r.run(resultReceiver); + final int resultCode = resultReceiver.getIntResult(); + if (resultCode == RESULT_CODE_SECURITY_EXCEPTION) { + throw new SecurityException(resultReceiver.getStringResult()); + } + return resultReceiver; + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + /** @hide */ public void dump(String prefix, PrintWriter pw) { pw.print(prefix); pw.println("ContentCaptureManager"); @@ -466,4 +636,8 @@ public final class ContentCaptureManager { } } } + + private interface MyRunnable { + void run(@NonNull SyncResultReceiver receiver) throws RemoteException; + } } diff --git a/core/java/android/view/contentcapture/ContentCaptureSession.java b/core/java/android/view/contentcapture/ContentCaptureSession.java index ed1ca2a48850..7761038f8af1 100644 --- a/core/java/android/view/contentcapture/ContentCaptureSession.java +++ b/core/java/android/view/contentcapture/ContentCaptureSession.java @@ -38,7 +38,7 @@ import java.io.PrintWriter; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; -import java.util.UUID; +import java.util.Random; /** * Session used to notify a system-provided Content Capture service about events associated with @@ -48,6 +48,11 @@ public abstract class ContentCaptureSession implements AutoCloseable { private static final String TAG = ContentCaptureSession.class.getSimpleName(); + private static final Random sIdGenerator = new Random(); + + /** @hide */ + public static final int NO_SESSION_ID = 0; + /** * Initial state, when there is no session. * @@ -186,7 +191,7 @@ public abstract class ContentCaptureSession implements AutoCloseable { /** @hide */ @Nullable - protected final String mId; + protected final int mId; private int mState = UNKNOWN_STATE; @@ -210,13 +215,14 @@ public abstract class ContentCaptureSession implements AutoCloseable { /** @hide */ protected ContentCaptureSession() { - this(UUID.randomUUID().toString()); + this(getRandomSessionId()); } /** @hide */ @VisibleForTesting - public ContentCaptureSession(@NonNull String id) { - mId = Preconditions.checkNotNull(id); + public ContentCaptureSession(int id) { + Preconditions.checkArgument(id != NO_SESSION_ID); + mId = id; } // Used by ChildCOntentCaptureSession @@ -241,15 +247,8 @@ public abstract class ContentCaptureSession implements AutoCloseable { } /** @hide */ - @VisibleForTesting - public int getIdAsInt() { - // TODO(b/121197119): use sessionId instead of hashcode once it's changed to int - return mId.hashCode(); - } - - /** @hide */ @NonNull - public String getId() { + public int getId() { return mId; } @@ -415,7 +414,7 @@ public abstract class ContentCaptureSession implements AutoCloseable { // TODO(b/123036895): use a internalNotifyViewsDisappeared that optimizes how the event is // parcelized for (long id : virtualIds) { - internalNotifyViewDisappeared(new AutofillId(hostId, id, getIdAsInt())); + internalNotifyViewDisappeared(new AutofillId(hostId, id, mId)); } } @@ -464,7 +463,7 @@ public abstract class ContentCaptureSession implements AutoCloseable { public @NonNull AutofillId newAutofillId(@NonNull AutofillId hostId, long virtualChildId) { Preconditions.checkNotNull(hostId); Preconditions.checkArgument(hostId.isNonVirtual(), "hostId cannot be virtual: %s", hostId); - return new AutofillId(hostId, virtualChildId, getIdAsInt()); + return new AutofillId(hostId, virtualChildId, mId); } /** @@ -480,7 +479,7 @@ public abstract class ContentCaptureSession implements AutoCloseable { @NonNull public final ViewStructure newVirtualViewStructure(@NonNull AutofillId parentId, long virtualId) { - return new ViewNode.ViewStructureImpl(parentId, virtualId, getIdAsInt()); + return new ViewNode.ViewStructureImpl(parentId, virtualId, mId); } boolean isContentCaptureEnabled() { @@ -511,7 +510,7 @@ public abstract class ContentCaptureSession implements AutoCloseable { @Override public String toString() { - return mId; + return Integer.toString(mId); } /** @hide */ @@ -541,4 +540,12 @@ public abstract class ContentCaptureSession implements AutoCloseable { return "UNKOWN-" + reason; } } + + private static int getRandomSessionId() { + int id; + do { + id = sIdGenerator.nextInt(); + } while (id == NO_SESSION_ID); + return id; + } } diff --git a/core/java/android/view/contentcapture/ContentCaptureSessionId.java b/core/java/android/view/contentcapture/ContentCaptureSessionId.java index e7c350a12b92..2d350b27c4a3 100644 --- a/core/java/android/view/contentcapture/ContentCaptureSessionId.java +++ b/core/java/android/view/contentcapture/ContentCaptureSessionId.java @@ -27,7 +27,7 @@ import java.io.PrintWriter; */ public final class ContentCaptureSessionId implements Parcelable { - private final @NonNull String mValue; + private final @NonNull int mValue; /** * Creates a new instance. @@ -36,14 +36,14 @@ public final class ContentCaptureSessionId implements Parcelable { * * @hide */ - public ContentCaptureSessionId(@NonNull String value) { + public ContentCaptureSessionId(@NonNull int value) { mValue = value; } /** * @hide */ - public String getValue() { + public int getValue() { return mValue; } @@ -51,7 +51,7 @@ public final class ContentCaptureSessionId implements Parcelable { public int hashCode() { final int prime = 31; int result = 1; - result = prime * result + ((mValue == null) ? 0 : mValue.hashCode()); + result = prime * result + mValue; return result; } @@ -61,11 +61,7 @@ public final class ContentCaptureSessionId implements Parcelable { if (obj == null) return false; if (getClass() != obj.getClass()) return false; final ContentCaptureSessionId other = (ContentCaptureSessionId) obj; - if (mValue == null) { - if (other.mValue != null) return false; - } else if (!mValue.equals(other.mValue)) { - return false; - } + if (mValue != other.mValue) return false; return true; } @@ -77,9 +73,10 @@ public final class ContentCaptureSessionId implements Parcelable { */ @Override public String toString() { - return mValue; + return Integer.toString(mValue); } + /** @hide */ // TODO(b/111276913): dump to proto as well public void dump(PrintWriter pw) { @@ -93,16 +90,16 @@ public final class ContentCaptureSessionId implements Parcelable { @Override public void writeToParcel(Parcel parcel, int flags) { - parcel.writeString(mValue); + parcel.writeInt(mValue); } - public static final @android.annotation.NonNull Parcelable.Creator<ContentCaptureSessionId> CREATOR = + public static final @NonNull Parcelable.Creator<ContentCaptureSessionId> CREATOR = new Parcelable.Creator<ContentCaptureSessionId>() { @Override @NonNull public ContentCaptureSessionId createFromParcel(Parcel parcel) { - return new ContentCaptureSessionId(parcel.readString()); + return new ContentCaptureSessionId(parcel.readInt()); } @Override diff --git a/core/java/android/view/contentcapture/IContentCaptureManager.aidl b/core/java/android/view/contentcapture/IContentCaptureManager.aidl index 15fbaa2d7dab..7335073c59e0 100644 --- a/core/java/android/view/contentcapture/IContentCaptureManager.aidl +++ b/core/java/android/view/contentcapture/IContentCaptureManager.aidl @@ -42,13 +42,13 @@ oneway interface IContentCaptureManager { * {@link IContentCaptureContext#flags}). */ void startSession(IBinder activityToken, in ComponentName componentName, - String sessionId, int flags, in IResultReceiver result); + int sessionId, int flags, in IResultReceiver result); /** * Marks the end of a session for the calling user identified by * the corresponding {@code startSession}'s {@code sessionId}. */ - void finishSession(String sessionId); + void finishSession(int sessionId); /** * Returns the content capture service's component name (if enabled and @@ -72,4 +72,9 @@ oneway interface IContentCaptureManager { * Returns a ComponentName with the name of custom service activity, if defined. */ void getServiceSettingsActivity(in IResultReceiver result); + + /** + * Returns a list with the ContentCaptureConditions for the package (or null if not defined). + */ + void getContentCaptureConditions(String packageName, in IResultReceiver result); } diff --git a/core/java/android/view/contentcapture/MainContentCaptureSession.java b/core/java/android/view/contentcapture/MainContentCaptureSession.java index 790b8f9dde46..784cf9c32557 100644 --- a/core/java/android/view/contentcapture/MainContentCaptureSession.java +++ b/core/java/android/view/contentcapture/MainContentCaptureSession.java @@ -318,7 +318,7 @@ public final class MainContentCaptureSession extends ContentCaptureSession { if (!mEvents.isEmpty() && eventType == TYPE_VIEW_DISAPPEARED) { final ContentCaptureEvent lastEvent = mEvents.get(mEvents.size() - 1); if (lastEvent.getType() == TYPE_VIEW_DISAPPEARED - && event.getSessionId().equals(lastEvent.getSessionId())) { + && event.getSessionId() == lastEvent.getSessionId()) { if (sVerbose) { Log.v(TAG, "Buffering TYPE_VIEW_DISAPPEARED events for session " + lastEvent.getSessionId()); @@ -581,37 +581,35 @@ public final class MainContentCaptureSession extends ContentCaptureSession { // TODO(b/122454205): refactor "notifyXXXX" methods below to a common "Buffer" object that is // shared between ActivityContentCaptureSession and ChildContentCaptureSession objects. Such // change should also get get rid of the "internalNotifyXXXX" methods above - void notifyChildSessionStarted(@NonNull String parentSessionId, - @NonNull String childSessionId, @NonNull ContentCaptureContext clientContext) { + void notifyChildSessionStarted(int parentSessionId, int childSessionId, + @NonNull ContentCaptureContext clientContext) { sendEvent(new ContentCaptureEvent(childSessionId, TYPE_SESSION_STARTED) .setParentSessionId(parentSessionId).setClientContext(clientContext), FORCE_FLUSH); } - void notifyChildSessionFinished(@NonNull String parentSessionId, - @NonNull String childSessionId) { + void notifyChildSessionFinished(int parentSessionId, int childSessionId) { sendEvent(new ContentCaptureEvent(childSessionId, TYPE_SESSION_FINISHED) .setParentSessionId(parentSessionId), FORCE_FLUSH); } - void notifyViewAppeared(@NonNull String sessionId, @NonNull ViewStructureImpl node) { + void notifyViewAppeared(int sessionId, @NonNull ViewStructureImpl node) { sendEvent(new ContentCaptureEvent(sessionId, TYPE_VIEW_APPEARED) .setViewNode(node.mNode)); } /** Public because is also used by ViewRootImpl */ - public void notifyViewDisappeared(@NonNull String sessionId, @NonNull AutofillId id) { + public void notifyViewDisappeared(int sessionId, @NonNull AutofillId id) { sendEvent(new ContentCaptureEvent(sessionId, TYPE_VIEW_DISAPPEARED).setAutofillId(id)); } - void notifyViewTextChanged(@NonNull String sessionId, @NonNull AutofillId id, - @Nullable CharSequence text) { + void notifyViewTextChanged(int sessionId, @NonNull AutofillId id, @Nullable CharSequence text) { sendEvent(new ContentCaptureEvent(sessionId, TYPE_VIEW_TEXT_CHANGED).setAutofillId(id) .setText(text)); } /** Public because is also used by ViewRootImpl */ - public void notifyViewTreeEvent(@NonNull String sessionId, boolean started) { + public void notifyViewTreeEvent(int sessionId, boolean started) { final int type = started ? TYPE_VIEW_TREE_APPEARING : TYPE_VIEW_TREE_APPEARED; sendEvent(new ContentCaptureEvent(sessionId, type), FORCE_FLUSH); } @@ -622,8 +620,7 @@ public final class MainContentCaptureSession extends ContentCaptureSession { sendEvent(new ContentCaptureEvent(mId, type), FORCE_FLUSH); } - void notifyContextUpdated(@NonNull String sessionId, - @Nullable ContentCaptureContext context) { + void notifyContextUpdated(int sessionId, @Nullable ContentCaptureContext context) { sendEvent(new ContentCaptureEvent(sessionId, TYPE_CONTEXT_UPDATED) .setClientContext(context)); } diff --git a/core/java/android/view/textclassifier/ConfigParser.java b/core/java/android/view/textclassifier/ConfigParser.java index 8e0bdf9eaa85..b475412bf669 100644 --- a/core/java/android/view/textclassifier/ConfigParser.java +++ b/core/java/android/view/textclassifier/ConfigParser.java @@ -33,6 +33,10 @@ public final class ConfigParser { private final KeyValueListParser mParser; + // TODO: Re-enable DeviceConfig when it has reasonable performance or just delete the + // option of using DeviceConfig entirely. + static final boolean ENABLE_DEVICE_CONFIG = false; + public ConfigParser(@Nullable String textClassifierConstants) { final KeyValueListParser parser = new KeyValueListParser(','); try { @@ -48,39 +52,55 @@ public final class ConfigParser { * Reads a boolean flag. */ public boolean getBoolean(String key, boolean defaultValue) { - return DeviceConfig.getBoolean( - DeviceConfig.NAMESPACE_TEXTCLASSIFIER, - key, - mParser.getBoolean(key, defaultValue)); + if (ENABLE_DEVICE_CONFIG) { + return DeviceConfig.getBoolean( + DeviceConfig.NAMESPACE_TEXTCLASSIFIER, + key, + mParser.getBoolean(key, defaultValue)); + } else { + return mParser.getBoolean(key, defaultValue); + } } /** * Reads an integer flag. */ public int getInt(String key, int defaultValue) { - return DeviceConfig.getInt( - DeviceConfig.NAMESPACE_TEXTCLASSIFIER, - key, - mParser.getInt(key, defaultValue)); + if (ENABLE_DEVICE_CONFIG) { + return DeviceConfig.getInt( + DeviceConfig.NAMESPACE_TEXTCLASSIFIER, + key, + mParser.getInt(key, defaultValue)); + } else { + return mParser.getInt(key, defaultValue); + } } /** * Reads a float flag. */ public float getFloat(String key, float defaultValue) { - return DeviceConfig.getFloat( - DeviceConfig.NAMESPACE_TEXTCLASSIFIER, - key, - mParser.getFloat(key, defaultValue)); + if (ENABLE_DEVICE_CONFIG) { + return DeviceConfig.getFloat( + DeviceConfig.NAMESPACE_TEXTCLASSIFIER, + key, + mParser.getFloat(key, defaultValue)); + } else { + return mParser.getFloat(key, defaultValue); + } } /** * Reads a string flag. */ public String getString(String key, String defaultValue) { - return DeviceConfig.getString( - DeviceConfig.NAMESPACE_TEXTCLASSIFIER, - key, - mParser.getString(key, defaultValue)); + if (ENABLE_DEVICE_CONFIG) { + return DeviceConfig.getString( + DeviceConfig.NAMESPACE_TEXTCLASSIFIER, + key, + mParser.getString(key, defaultValue)); + } else { + return mParser.getString(key, defaultValue); + } } } diff --git a/core/java/android/view/textclassifier/TextClassificationManager.java b/core/java/android/view/textclassifier/TextClassificationManager.java index 868cbb1ce58e..fa898c3c89e0 100644 --- a/core/java/android/view/textclassifier/TextClassificationManager.java +++ b/core/java/android/view/textclassifier/TextClassificationManager.java @@ -197,7 +197,9 @@ public final class TextClassificationManager { if (mSettingsObserver != null) { getApplicationContext().getContentResolver() .unregisterContentObserver(mSettingsObserver); - DeviceConfig.removeOnPropertyChangedListener(mSettingsObserver); + if (ConfigParser.ENABLE_DEVICE_CONFIG) { + DeviceConfig.removeOnPropertyChangedListener(mSettingsObserver); + } } } finally { super.finalize(); @@ -292,10 +294,12 @@ public final class TextClassificationManager { Settings.Global.getUriFor(Settings.Global.TEXT_CLASSIFIER_CONSTANTS), false /* notifyForDescendants */, this); - DeviceConfig.addOnPropertyChangedListener( - DeviceConfig.NAMESPACE_TEXTCLASSIFIER, - ActivityThread.currentApplication().getMainExecutor(), - this); + if (ConfigParser.ENABLE_DEVICE_CONFIG) { + DeviceConfig.addOnPropertyChangedListener( + DeviceConfig.NAMESPACE_TEXTCLASSIFIER, + ActivityThread.currentApplication().getMainExecutor(), + this); + } } @Override diff --git a/core/java/android/webkit/IWebViewUpdateService.aidl b/core/java/android/webkit/IWebViewUpdateService.aidl index 10cfea166abd..1da0500727ad 100644 --- a/core/java/android/webkit/IWebViewUpdateService.aidl +++ b/core/java/android/webkit/IWebViewUpdateService.aidl @@ -71,18 +71,6 @@ interface IWebViewUpdateService { PackageInfo getCurrentWebViewPackage(); /** - * Used by Settings to determine whether a certain package can be enabled/disabled by the user - - * the package should not be modifiable in this way if it is a fallback package. - */ - @UnsupportedAppUsage - boolean isFallbackPackage(String packageName); - - /** - * Enable or disable the WebView package fallback mechanism. - */ - void enableFallbackLogic(boolean enable); - - /** * Used by Settings to determine whether multiprocess is enabled. */ boolean isMultiProcessEnabled(); diff --git a/core/java/android/webkit/WebViewFactory.java b/core/java/android/webkit/WebViewFactory.java index 4413585535f2..678a25223ef5 100644 --- a/core/java/android/webkit/WebViewFactory.java +++ b/core/java/android/webkit/WebViewFactory.java @@ -321,45 +321,6 @@ public final class WebViewFactory { } } - /** - * If the ApplicationInfo provided is for a stub WebView, fix up the object to include the - * required values from the donor package. If the ApplicationInfo is for a full WebView, - * leave it alone. Throws MissingWebViewPackageException if the donor is missing. - */ - private static void fixupStubApplicationInfo(ApplicationInfo ai, PackageManager pm) - throws MissingWebViewPackageException { - String donorPackageName = null; - if (ai.metaData != null) { - donorPackageName = ai.metaData.getString("com.android.webview.WebViewDonorPackage"); - } - if (donorPackageName != null) { - PackageInfo donorPackage; - try { - donorPackage = pm.getPackageInfo( - donorPackageName, - PackageManager.GET_SHARED_LIBRARY_FILES - | PackageManager.MATCH_DEBUG_TRIAGED_MISSING - | PackageManager.MATCH_UNINSTALLED_PACKAGES - | PackageManager.MATCH_FACTORY_ONLY); - } catch (PackageManager.NameNotFoundException e) { - throw new MissingWebViewPackageException("Failed to find donor package: " + - donorPackageName); - } - ApplicationInfo donorInfo = donorPackage.applicationInfo; - - // Replace the stub's code locations with the donor's. - ai.sourceDir = donorInfo.sourceDir; - ai.splitSourceDirs = donorInfo.splitSourceDirs; - ai.nativeLibraryDir = donorInfo.nativeLibraryDir; - ai.secondaryNativeLibraryDir = donorInfo.secondaryNativeLibraryDir; - - // Copy the donor's primary and secondary ABIs, since the stub doesn't have native code - // and so they are unset. - ai.primaryCpuAbi = donorInfo.primaryCpuAbi; - ai.secondaryCpuAbi = donorInfo.secondaryCpuAbi; - } - } - @UnsupportedAppUsage private static Context getWebViewContextAndSetProvider() throws MissingWebViewPackageException { Application initialApplication = AppGlobals.getInitialApplication(); @@ -411,7 +372,6 @@ public final class WebViewFactory { verifyPackageInfo(response.packageInfo, newPackageInfo); ApplicationInfo ai = newPackageInfo.applicationInfo; - fixupStubApplicationInfo(ai, pm); Trace.traceBegin(Trace.TRACE_TAG_WEBVIEW, "initialApplication.createApplicationContext"); @@ -494,18 +454,14 @@ public final class WebViewFactory { */ public static int onWebViewProviderChanged(PackageInfo packageInfo) { int startedRelroProcesses = 0; - ApplicationInfo originalAppInfo = new ApplicationInfo(packageInfo.applicationInfo); try { - fixupStubApplicationInfo(packageInfo.applicationInfo, - AppGlobals.getInitialApplication().getPackageManager()); - startedRelroProcesses = WebViewLibraryLoader.prepareNativeLibraries(packageInfo); } catch (Throwable t) { // Log and discard errors at this stage as we must not crash the system server. Log.e(LOGTAG, "error preparing webview native library", t); } - WebViewZygote.onWebViewProviderChanged(packageInfo, originalAppInfo); + WebViewZygote.onWebViewProviderChanged(packageInfo); return startedRelroProcesses; } diff --git a/core/java/android/webkit/WebViewZygote.java b/core/java/android/webkit/WebViewZygote.java index 09aa066549cb..62f54b943e11 100644 --- a/core/java/android/webkit/WebViewZygote.java +++ b/core/java/android/webkit/WebViewZygote.java @@ -16,8 +16,6 @@ package android.webkit; -import android.app.LoadedApk; -import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.os.AsyncTask; import android.os.Build; @@ -29,10 +27,6 @@ import android.util.Log; import com.android.internal.annotations.GuardedBy; -import java.io.File; -import java.util.ArrayList; -import java.util.List; - /** @hide */ public class WebViewZygote { private static final String LOGTAG = "WebViewZygote"; @@ -56,13 +50,6 @@ public class WebViewZygote { private static PackageInfo sPackage; /** - * Original ApplicationInfo for the selected WebView package before stub fixup. This is set from - * #onWebViewProviderChanged(). - */ - @GuardedBy("sLock") - private static ApplicationInfo sPackageOriginalAppInfo; - - /** * Flag for whether multi-process WebView is enabled. If this is {@code false}, the zygote * will not be started. */ @@ -110,11 +97,9 @@ public class WebViewZygote { } } - public static void onWebViewProviderChanged(PackageInfo packageInfo, - ApplicationInfo originalAppInfo) { + static void onWebViewProviderChanged(PackageInfo packageInfo) { synchronized (sLock) { sPackage = packageInfo; - sPackageOriginalAppInfo = originalAppInfo; // If multi-process is not enabled, then do not start the zygote service. if (!sMultiprocessEnabled) { @@ -165,34 +150,7 @@ public class WebViewZygote { Process.FIRST_ISOLATED_UID, Integer.MAX_VALUE); // TODO(b/123615476) deal with user-id ranges properly ZygoteProcess.waitForConnectionToZygote(sZygote.getPrimarySocketAddress()); - - if (sPackageOriginalAppInfo.sourceDir.equals(sPackage.applicationInfo.sourceDir)) { - // No stub WebView is involved here, so we can preload the package the "clean" way - // using the ApplicationInfo. - sZygote.preloadApp(sPackage.applicationInfo, abi); - } else { - // Legacy path to support the stub WebView. - // Reuse the logic from LoadedApk to determine the correct paths and pass them to - // the zygote as strings. - final List<String> zipPaths = new ArrayList<>(10); - final List<String> libPaths = new ArrayList<>(10); - LoadedApk.makePaths(null, false, sPackage.applicationInfo, zipPaths, libPaths); - final String librarySearchPath = TextUtils.join(File.pathSeparator, libPaths); - final String zip = (zipPaths.size() == 1) ? zipPaths.get(0) : - TextUtils.join(File.pathSeparator, zipPaths); - - String libFileName = WebViewFactory.getWebViewLibrary(sPackage.applicationInfo); - - // Use the original ApplicationInfo to determine what the original classpath would - // have been to use as a cache key. - LoadedApk.makePaths(null, false, sPackageOriginalAppInfo, zipPaths, null); - final String cacheKey = (zipPaths.size() == 1) ? zipPaths.get(0) : - TextUtils.join(File.pathSeparator, zipPaths); - - Log.d(LOGTAG, "Preloading package " + zip + " " + librarySearchPath); - sZygote.preloadPackageForAbi(zip, librarySearchPath, libFileName, cacheKey, - Build.SUPPORTED_ABIS[0]); - } + sZygote.preloadApp(sPackage.applicationInfo, abi); } catch (Exception e) { Log.e(LOGTAG, "Error connecting to webview zygote", e); stopZygoteLocked(); diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index a5a1a80cca88..a961783dab7c 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -10081,7 +10081,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } /** - * Return true iff there is a selection inside this text view. + * Return true iff there is a selection of nonzero length inside this text view. */ public boolean hasSelection() { final int selectionStart = getSelectionStart(); diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java index f29174b54383..a1d0cdc5789f 100644 --- a/core/java/com/android/internal/app/ChooserActivity.java +++ b/core/java/com/android/internal/app/ChooserActivity.java @@ -24,7 +24,6 @@ import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.animation.ValueAnimator; import android.annotation.IntDef; -import android.annotation.UnsupportedAppUsage; import android.app.Activity; import android.app.ActivityManager; import android.app.prediction.AppPredictionContext; @@ -188,7 +187,10 @@ public class ChooserActivity extends ResolverActivity { private Drawable mChooserRowLayer; private int mChooserRowServiceSpacing; + /** {@link ChooserActivity#getBaseScore} */ private static final float CALLER_TARGET_SCORE_BOOST = 900.f; + /** {@link ChooserActivity#getBaseScore} */ + private static final float SHORTCUT_TARGET_SCORE_BOOST = 10.f; private static final String TARGET_DETAILS_FRAGMENT_TAG = "targetDetailsFragment"; private final List<ChooserTargetServiceConnection> mServiceConnections = new ArrayList<>(); @@ -197,6 +199,11 @@ public class ChooserActivity extends ResolverActivity { private static final int CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT = 2; private static final int SHORTCUT_MANAGER_SHARE_TARGET_RESULT = 3; private static final int SHORTCUT_MANAGER_SHARE_TARGET_RESULT_COMPLETED = 4; + private static final int LIST_VIEW_UPDATE_MESSAGE = 5; + + private static final int LIST_VIEW_UPDATE_INTERVAL_IN_MILLIS = 250; + + private boolean mListViewDataChanged = false; @Retention(SOURCE) @IntDef({CONTENT_PREVIEW_FILE, CONTENT_PREVIEW_IMAGE, CONTENT_PREVIEW_TEXT}) @@ -213,10 +220,13 @@ public class ChooserActivity extends ResolverActivity { private final Handler mChooserHandler = new Handler() { @Override public void handleMessage(Message msg) { + if (mChooserListAdapter == null || isDestroyed()) { + return; + } + switch (msg.what) { case CHOOSER_TARGET_SERVICE_RESULT: if (DEBUG) Log.d(TAG, "CHOOSER_TARGET_SERVICE_RESULT"); - if (isDestroyed()) break; final ServiceResultInfo sri = (ServiceResultInfo) msg.obj; if (!mServiceConnections.contains(sri.connection)) { Log.w(TAG, "ChooserTargetServiceConnection " + sri.connection @@ -226,7 +236,7 @@ public class ChooserActivity extends ResolverActivity { } if (sri.resultTargets != null) { mChooserListAdapter.addServiceResults(sri.originalTarget, - sri.resultTargets); + sri.resultTargets, false); } unbindService(sri.connection); sri.connection.destroy(); @@ -240,21 +250,26 @@ public class ChooserActivity extends ResolverActivity { if (DEBUG) { Log.d(TAG, "CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT; unbinding services"); } - if (mChooserListAdapter == null || isDestroyed()) { - break; - } + unbindRemainingServices(); sendVoiceChoicesIfNeeded(); mChooserListAdapter.completeServiceTargetLoading(); break; + case LIST_VIEW_UPDATE_MESSAGE: + if (DEBUG) { + Log.d(TAG, "LIST_VIEW_UPDATE_MESSAGE; "); + } + + mChooserListAdapter.refreshListView(); + break; + case SHORTCUT_MANAGER_SHARE_TARGET_RESULT: if (DEBUG) Log.d(TAG, "SHORTCUT_MANAGER_SHARE_TARGET_RESULT"); - if (isDestroyed()) break; final ServiceResultInfo resultInfo = (ServiceResultInfo) msg.obj; if (resultInfo.resultTargets != null) { mChooserListAdapter.addServiceResults(resultInfo.originalTarget, - resultInfo.resultTargets); + resultInfo.resultTargets, true); } break; @@ -829,6 +844,7 @@ public class ChooserActivity extends ResolverActivity { mRefinementResultReceiver = null; } unbindRemainingServices(); + mChooserHandler.removeMessages(LIST_VIEW_UPDATE_MESSAGE); mChooserHandler.removeMessages(CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT); mChooserHandler.removeMessages(CHOOSER_TARGET_SERVICE_RESULT); if (USE_PREDICTION_MANAGER_FOR_DIRECT_TARGETS) { @@ -881,7 +897,8 @@ public class ChooserActivity extends ResolverActivity { final ListView listView = adapterView instanceof ListView ? (ListView) adapterView : null; mChooserListAdapter = (ChooserListAdapter) adapter; if (mCallerChooserTargets != null && mCallerChooserTargets.length > 0) { - mChooserListAdapter.addServiceResults(null, Lists.newArrayList(mCallerChooserTargets)); + mChooserListAdapter.addServiceResults(null, Lists.newArrayList(mCallerChooserTargets), + false); } mChooserRowAdapter = new ChooserRowAdapter(mChooserListAdapter); if (listView != null) { @@ -925,8 +942,6 @@ public class ChooserActivity extends ResolverActivity { if (isSendAction(in)) { in.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT | Intent.FLAG_ACTIVITY_MULTIPLE_TASK); - - in.fixUris(getUserId()); } } @@ -1194,7 +1209,7 @@ public class ChooserActivity extends ResolverActivity { null, // The ranking score for this target (0.0-1.0); the system will omit items with low // scores when there are too many Direct Share items. - 0.5f, + 1.0f, // The name of the component to be launched if this target is chosen. shareShortcut.getTargetComponent().clone(), // The extra values here will be merged into the Intent when this target is chosen. @@ -1383,15 +1398,6 @@ public class ChooserActivity extends ResolverActivity { } return false; } - - @Override - public float getScore(DisplayResolveInfo target) { - if (target == null) { - return CALLER_TARGET_SCORE_BOOST; - } - - return super.getScore(target); - } } @Override @@ -1480,7 +1486,7 @@ public class ChooserActivity extends ResolverActivity { } public float getModifiedScore() { - return 0.1f; + return -0.1f; } public ChooserTarget getChooserTarget() { @@ -1594,7 +1600,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); @@ -1802,8 +1808,6 @@ public class ChooserActivity extends ResolverActivity { private final List<TargetInfo> mCallerTargets = new ArrayList<>(); private boolean mShowServiceTargets; - private float mLateFee = 1.f; - private boolean mTargetsNeedPruning = false; private final BaseChooserTargetComparator mBaseTargetComparator @@ -1865,12 +1869,30 @@ 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)); } } } + @Override + public void notifyDataSetChanged() { + if (!mListViewDataChanged) { + mChooserHandler.sendEmptyMessageDelayed(LIST_VIEW_UPDATE_MESSAGE, + LIST_VIEW_UPDATE_INTERVAL_IN_MILLIS); + mListViewDataChanged = true; + } + } + + private void refreshListView() { + if (mListViewDataChanged) { + super.notifyDataSetChanged(); + } + mListViewDataChanged = false; + } + + private void createPlaceHolders() { mServiceTargets.clear(); for (int i = 0; i < MAX_SERVICE_TARGETS; i++) { @@ -1879,12 +1901,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); @@ -1898,7 +1914,7 @@ public class ChooserActivity extends ResolverActivity { } if (mServiceTargets != null) { - if (getDisplayInfoCount() == 0) { + if (getDisplayResolveInfoCount() == 0) { // b/109676071: When packages change, onListRebuilt() is called before // ResolverActivity.mDisplayList is re-populated; pruning now would cause the // list to disappear briefly, so instead we detect this case (the @@ -1911,12 +1927,14 @@ public class ChooserActivity extends ResolverActivity { if (DEBUG) { Log.d(TAG, "querying direct share targets from ShortcutManager"); } + queryDirectShareTargets(this); } if (USE_CHOOSER_TARGET_SERVICE_FOR_DIRECT_TARGETS) { if (DEBUG) { Log.d(TAG, "List built querying services"); } + queryTargetServices(this); } } @@ -2012,16 +2030,25 @@ public class ChooserActivity extends ResolverActivity { offset += callerTargetCount; return filtered ? super.getItem(position - offset) - : getDisplayInfoAt(position - offset); + : getDisplayResolveInfo(position - offset); } - public void addServiceResults(DisplayResolveInfo origTarget, List<ChooserTarget> targets) { + /** + * Evaluate targets for inclusion in the direct share area. May not be included + * if score is too low. + */ + public void addServiceResults(DisplayResolveInfo origTarget, List<ChooserTarget> targets, + boolean isShortcutResult) { if (DEBUG) { Log.d(TAG, "addServiceResults " + origTarget + ", " + targets.size() + " targets"); } - if (mTargetsNeedPruning && targets.size() > 0) { + if (targets.size() == 0) { + return; + } + + if (mTargetsNeedPruning) { // First proper update since we got an onListRebuilt() with (transient) 0 items. // Clear out the target list and rebuild. createPlaceHolders(); @@ -2030,39 +2057,64 @@ public class ChooserActivity extends ResolverActivity { // Add back any app-supplied direct share targets that may have been // wiped by this clear if (mCallerChooserTargets != null) { - addServiceResults(null, Lists.newArrayList(mCallerChooserTargets)); + addServiceResults(null, Lists.newArrayList(mCallerChooserTargets), false); } } - final float parentScore = getScore(origTarget); + final float baseScore = getBaseScore(origTarget, isShortcutResult); Collections.sort(targets, mBaseTargetComparator); float lastScore = 0; + boolean shouldNotify = false; for (int i = 0, N = Math.min(targets.size(), MAX_TARGETS_PER_SERVICE); i < N; i++) { final ChooserTarget target = targets.get(i); float targetScore = target.getScore(); - targetScore *= parentScore; - targetScore *= mLateFee; + targetScore *= baseScore; if (i > 0 && targetScore >= lastScore) { // Apply a decay so that the top app can't crowd out everything else. // This incents ChooserTargetServices to define what's truly better. targetScore = lastScore * 0.95f; } - insertServiceTarget(new SelectableTargetInfo(origTarget, target, targetScore)); + shouldNotify |= insertServiceTarget( + new SelectableTargetInfo(origTarget, target, targetScore)); if (DEBUG) { Log.d(TAG, " => " + target.toString() + " score=" + targetScore + " base=" + target.getScore() + " lastScore=" + lastScore - + " parentScore=" + parentScore - + " lateFee=" + mLateFee); + + " baseScore=" + baseScore); } lastScore = targetScore; } - mLateFee *= 0.95f; + if (shouldNotify) { + notifyDataSetChanged(); + } + } + + /** + * Use the scoring system along with artificial boosts to create up to 3 distinct buckets: + * <ol> + * <li>App-supplied targets + * <li>Prediction manager targets or Shortcut API targets + * <li>Legacy direct share targets + * </ol> + */ + private float getBaseScore(DisplayResolveInfo target, boolean isShortcutResult) { + if (target == null) { + return CALLER_TARGET_SCORE_BOOST; + } - notifyDataSetChanged(); + if (USE_PREDICTION_MANAGER_FOR_DIRECT_TARGETS) { + return SHORTCUT_TARGET_SCORE_BOOST; + } + + float score = super.getScore(target); + if (isShortcutResult) { + return score * SHORTCUT_TARGET_SCORE_BOOST; + } + + return score; } /** @@ -2078,25 +2130,32 @@ public class ChooserActivity extends ResolverActivity { notifyDataSetChanged(); } - private void insertServiceTarget(ChooserTargetInfo chooserTargetInfo) { + private boolean insertServiceTarget(ChooserTargetInfo chooserTargetInfo) { // Avoid inserting any potentially late results if (mServiceTargets.size() == 1 && mServiceTargets.get(0) instanceof EmptyTargetInfo) { - return; + return false; } final float newScore = chooserTargetInfo.getModifiedScore(); - for (int i = 0, N = mServiceTargets.size(); i < N; i++) { + int currentSize = mServiceTargets.size(); + for (int i = 0; i < Math.min(currentSize, MAX_SERVICE_TARGETS); i++) { final ChooserTargetInfo serviceTarget = mServiceTargets.get(i); if (serviceTarget == null) { mServiceTargets.set(i, chooserTargetInfo); - return; + return true; } else if (newScore > serviceTarget.getModifiedScore()) { mServiceTargets.add(i, chooserTargetInfo); - return; + return true; } } - mServiceTargets.add(chooserTargetInfo); + + if (currentSize < MAX_SERVICE_TARGETS) { + mServiceTargets.add(chooserTargetInfo); + return true; + } + + return false; } } @@ -2301,8 +2360,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 +2382,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 +2414,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 +2461,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 +2558,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 +2609,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 +2656,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 +2671,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/IntentForwarderActivity.java b/core/java/com/android/internal/app/IntentForwarderActivity.java index 3811fe44255d..a5f055f09562 100644 --- a/core/java/com/android/internal/app/IntentForwarderActivity.java +++ b/core/java/com/android/internal/app/IntentForwarderActivity.java @@ -115,6 +115,7 @@ public class IntentForwarderActivity extends Activity { // At this point, innerIntent is not null. Otherwise, canForward would have returned // false. innerIntent.prepareToLeaveUser(callingUserId); + innerIntent.fixUris(callingUserId); } else { newIntent.prepareToLeaveUser(callingUserId); } diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java index 84a1bed36e55..f671a753493e 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,41 @@ 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 final ApplicationInfo mAi; + private Context mCtx; + private final int mIconDpi; private final boolean mHasSubstitutePermission; + private final ApplicationInfo mAi; + + protected PackageManager mPm; - 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 +549,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 +570,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 +587,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 ActivityInfoPresentationGetter { private final ResolveInfo mRi; - - ResolveInfoPresentationGetter(ResolveInfo ri) { - super(ri.activityInfo.applicationInfo); + public ResolveInfoPresentationGetter(Context ctx, int iconDpi, ResolveInfo ri) { + super(ctx, iconDpi, ri.activityInfo); mRi = ri; } @Override - Drawable getIconSubstitute() { + Drawable getIconSubstituteInternal() { Drawable dr = null; try { // Do not use ResolveInfo#getIconResource() as it defaults to the app @@ -599,24 +612,38 @@ public class ResolverActivity extends Activity { + "couldn't find resources for package", e); } + // Fall back to ActivityInfo if no icon is found via ResolveInfo + if (dr == null) dr = super.getIconSubstituteInternal(); + return dr; } @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 +661,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 @@ -1201,7 +1234,7 @@ public class ResolverActivity extends Activity { final ImageView iconView = findViewById(R.id.icon); final DisplayResolveInfo iconInfo = mAdapter.getFilteredItem(); if (iconView != null && iconInfo != null) { - new LoadIconIntoViewTask(iconInfo, iconView).execute(); + new LoadIconTask(iconInfo, iconView).execute(); } } @@ -1713,34 +1746,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 +1794,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(); @@ -1912,14 +1875,6 @@ public class ResolverActivity extends Activity { return mDisplayList.size(); } - public int getDisplayInfoCount() { - return mDisplayList.size(); - } - - public DisplayResolveInfo getDisplayInfoAt(int index) { - return mDisplayList.get(index); - } - @Nullable public TargetInfo getItem(int position) { if (mFilterLastUsed && mLastChosenPosition >= 0 && position >= mLastChosenPosition) { @@ -1979,36 +1934,38 @@ 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(); + new LoadIconTask((DisplayResolveInfo) info, holder.icon).execute(); + } else { + holder.icon.setImageDrawable(info.getDisplayIcon()); } - holder.icon.setImageDrawable(info.getDisplayIcon()); } } @@ -2127,13 +2084,15 @@ public class ResolverActivity extends Activity { } - abstract class LoadIconTask extends AsyncTask<Void, Void, Drawable> { + class LoadIconTask extends AsyncTask<Void, Void, Drawable> { protected final DisplayResolveInfo mDisplayResolveInfo; private final ResolveInfo mResolveInfo; + private final ImageView mTargetView; - public LoadIconTask(DisplayResolveInfo dri) { + LoadIconTask(DisplayResolveInfo dri, ImageView target) { mDisplayResolveInfo = dri; mResolveInfo = dri.getResolveInfo(); + mTargetView = target; } @Override @@ -2143,37 +2102,12 @@ public class ResolverActivity extends Activity { @Override protected void onPostExecute(Drawable d) { - mDisplayResolveInfo.setDisplayIcon(d); - } - } - - class LoadAdapterIconTask extends LoadIconTask { - public LoadAdapterIconTask(DisplayResolveInfo dri) { - super(dri); - } - - @Override - protected void onPostExecute(Drawable d) { - super.onPostExecute(d); if (mProfileView != null && mAdapter.getOtherProfile() == mDisplayResolveInfo) { bindProfileView(); + } else { + mDisplayResolveInfo.setDisplayIcon(d); + mTargetView.setImageDrawable(d); } - mAdapter.notifyDataSetChanged(); - } - } - - class LoadIconIntoViewTask extends LoadIconTask { - private final ImageView mTargetView; - - public LoadIconIntoViewTask(DisplayResolveInfo dri, ImageView target) { - super(dri); - mTargetView = target; - } - - @Override - protected void onPostExecute(Drawable d) { - super.onPostExecute(d); - mTargetView.setImageDrawable(d); } } diff --git a/core/java/com/android/internal/app/procstats/ProcessState.java b/core/java/com/android/internal/app/procstats/ProcessState.java index 0e4897f9eb9c..b26efc0dbd10 100644 --- a/core/java/com/android/internal/app/procstats/ProcessState.java +++ b/core/java/com/android/internal/app/procstats/ProcessState.java @@ -79,6 +79,7 @@ public final class ProcessState { STATE_TOP, // ActivityManager.PROCESS_STATE_TOP STATE_IMPORTANT_FOREGROUND, // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE_LOCATION STATE_IMPORTANT_FOREGROUND, // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE + STATE_IMPORTANT_FOREGROUND, // ActivityManager.PROCESS_STATE_BOUND_TOP STATE_IMPORTANT_FOREGROUND, // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE STATE_IMPORTANT_FOREGROUND, // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND STATE_IMPORTANT_BACKGROUND, // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND diff --git a/core/java/com/android/internal/colorextraction/types/Tonal.java b/core/java/com/android/internal/colorextraction/types/Tonal.java index 9d85a039420c..b9aab21b1e4c 100644 --- a/core/java/com/android/internal/colorextraction/types/Tonal.java +++ b/core/java/com/android/internal/colorextraction/types/Tonal.java @@ -109,42 +109,20 @@ public class Tonal implements ExtractionType { final int mainColorsSize = mainColors.size(); final int hints = inWallpaperColors.getColorHints(); final boolean supportsDarkText = (hints & WallpaperColors.HINT_SUPPORTS_DARK_TEXT) != 0; - final boolean generatedFromBitmap = (hints & WallpaperColors.HINT_FROM_BITMAP) != 0; if (mainColorsSize == 0) { return false; } - // Decide what's the best color to use. - // We have 2 options: - // • Just pick the primary color - // • Filter out blacklisted colors. This is useful when palette is generated - // automatically from a bitmap. - Color bestColor = null; - final float[] hsl = new float[3]; - for (int i = 0; i < mainColorsSize; i++) { - final Color color = mainColors.get(i); - final int colorValue = color.toArgb(); - ColorUtils.RGBToHSL(Color.red(colorValue), Color.green(colorValue), - Color.blue(colorValue), hsl); - - // Stop when we find a color that meets our criteria - if (!generatedFromBitmap) { - bestColor = color; - break; - } - } - - // Fail if not found - if (bestColor == null) { - return false; - } + // Pick the primary color as the best color to use. + final Color bestColor = mainColors.get(0); // Tonal is not really a sort, it takes a color from the extracted // palette and finds a best fit amongst a collection of pre-defined // palettes. The best fit is tweaked to be closer to the source color // and replaces the original palette. int colorValue = bestColor.toArgb(); + final float[] hsl = new float[3]; ColorUtils.RGBToHSL(Color.red(colorValue), Color.green(colorValue), Color.blue(colorValue), hsl); diff --git a/core/java/com/android/internal/infra/GlobalWhitelistState.java b/core/java/com/android/internal/infra/GlobalWhitelistState.java new file mode 100644 index 000000000000..dfa59b7bd0ac --- /dev/null +++ b/core/java/com/android/internal/infra/GlobalWhitelistState.java @@ -0,0 +1,131 @@ +/* + * 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.internal.infra; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.annotation.UserIdInt; +import android.content.ComponentName; +import android.util.ArraySet; +import android.util.SparseArray; + +import com.android.internal.annotations.GuardedBy; + +import java.io.PrintWriter; +import java.util.List; + +/** + * Helper class used to manage a {@link WhitelistHelper} per user instance when the main service + * cannot hold a lock when external entities (typically {@code ActivityManagerService}) needs to + * get whitelist info. + * + * <p>This class is thread safe. + */ +public class GlobalWhitelistState { + + // Uses full-name to avoid collision with service-provided mLock + protected final Object mGlobalWhitelistStateLock = new Object(); + + @Nullable + @GuardedBy("mGlobalWhitelistStateLock") + protected SparseArray<WhitelistHelper> mWhitelisterHelpers; + + /** + * Sets the whitelist for the given user. + */ + public void setWhitelist(@UserIdInt int userId, @Nullable List<String> packageNames, + @Nullable List<ComponentName> components) { + synchronized (mGlobalWhitelistStateLock) { + if (mWhitelisterHelpers == null) { + mWhitelisterHelpers = new SparseArray<>(1); + } + WhitelistHelper helper = mWhitelisterHelpers.get(userId); + if (helper == null) { + helper = new WhitelistHelper(); + mWhitelisterHelpers.put(userId, helper); + } + helper.setWhitelist(packageNames, components); + } + } + + /** + * Checks if the given package is whitelisted for the given user. + */ + public boolean isWhitelisted(@UserIdInt int userId, @NonNull String packageName) { + synchronized (mGlobalWhitelistStateLock) { + if (mWhitelisterHelpers == null) return false; + final WhitelistHelper helper = mWhitelisterHelpers.get(userId); + return helper == null ? false : helper.isWhitelisted(packageName); + } + } + + /** + * Checks if the given component is whitelisted for the given user. + */ + public boolean isWhitelisted(@UserIdInt int userId, @NonNull ComponentName componentName) { + synchronized (mGlobalWhitelistStateLock) { + if (mWhitelisterHelpers == null) return false; + final WhitelistHelper helper = mWhitelisterHelpers.get(userId); + return helper == null ? false : helper.isWhitelisted(componentName); + } + } + + /** + * Gets the whitelisted components for the given package and user. + */ + public ArraySet<ComponentName> getWhitelistedComponents(@UserIdInt int userId, + @NonNull String packageName) { + synchronized (mGlobalWhitelistStateLock) { + if (mWhitelisterHelpers == null) return null; + final WhitelistHelper helper = mWhitelisterHelpers.get(userId); + return helper == null ? null : helper.getWhitelistedComponents(packageName); + } + } + + /** + * Resets the whitelist for the given user. + */ + public void resetWhitelist(@NonNull int userId) { + synchronized (mGlobalWhitelistStateLock) { + if (mWhitelisterHelpers == null) return; + mWhitelisterHelpers.remove(userId); + if (mWhitelisterHelpers.size() == 0) { + mWhitelisterHelpers = null; + } + } + } + + /** + * Dumps it! + */ + public void dump(@NonNull String prefix, @NonNull PrintWriter pw) { + pw.print(prefix); pw.print("State: "); + synchronized (mGlobalWhitelistStateLock) { + if (mWhitelisterHelpers == null) { + pw.println("empty"); + return; + } + pw.print(mWhitelisterHelpers.size()); pw.println(" services"); + final String prefix2 = prefix + " "; + for (int i = 0; i < mWhitelisterHelpers.size(); i++) { + final int userId = mWhitelisterHelpers.keyAt(i); + final WhitelistHelper helper = mWhitelisterHelpers.valueAt(i); + helper.dump(prefix2, "Whitelist for userId " + userId, pw); + } + } + } +} diff --git a/core/java/com/android/internal/infra/WhitelistHelper.java b/core/java/com/android/internal/infra/WhitelistHelper.java index 183b465afbfd..d7753db6b0f7 100644 --- a/core/java/com/android/internal/infra/WhitelistHelper.java +++ b/core/java/com/android/internal/infra/WhitelistHelper.java @@ -31,6 +31,7 @@ import java.util.List; /** * Helper class for keeping track of whitelisted packages/activities. * + * <p><b>NOTE: </b>this class is not thread safe. * @hide */ public final class WhitelistHelper { diff --git a/core/java/com/android/internal/os/KernelCpuThreadReader.java b/core/java/com/android/internal/os/KernelCpuThreadReader.java index e4de1586bc51..3686048cee15 100644 --- a/core/java/com/android/internal/os/KernelCpuThreadReader.java +++ b/core/java/com/android/internal/os/KernelCpuThreadReader.java @@ -92,24 +92,12 @@ public class KernelCpuThreadReader { /** Value returned when there was an error getting an integer ID value (e.g. PID, UID) */ private static final int ID_ERROR = -1; - /** Thread ID used when reporting CPU used by other threads */ - private static final int OTHER_THREADS_ID = -1; - - /** Thread name used when reporting CPU used by other threads */ - private static final String OTHER_THREADS_NAME = "__OTHER_THREADS"; - /** * When checking whether to report data for a thread, we check the UID of the thread's owner * against this predicate */ private Predicate<Integer> mUidPredicate; - /** - * If a thread has strictly less than {@code minimumTotalCpuUsageMillis} total CPU usage, it - * will not be reported - */ - private int mMinimumTotalCpuUsageMillis; - /** Where the proc filesystem is mounted */ private final Path mProcPath; @@ -138,13 +126,11 @@ public class KernelCpuThreadReader { public KernelCpuThreadReader( int numBuckets, Predicate<Integer> uidPredicate, - int minimumTotalCpuUsageMillis, Path procPath, Path initialTimeInStatePath, Injector injector) throws IOException { mUidPredicate = uidPredicate; - mMinimumTotalCpuUsageMillis = minimumTotalCpuUsageMillis; mProcPath = procPath; mProcTimeInStateReader = new ProcTimeInStateReader(initialTimeInStatePath); mInjector = injector; @@ -157,13 +143,11 @@ public class KernelCpuThreadReader { * @return the reader, null if an exception was thrown during creation */ @Nullable - public static KernelCpuThreadReader create( - int numBuckets, Predicate<Integer> uidPredicate, int minimumTotalCpuUsageMillis) { + public static KernelCpuThreadReader create(int numBuckets, Predicate<Integer> uidPredicate) { try { return new KernelCpuThreadReader( numBuckets, uidPredicate, - minimumTotalCpuUsageMillis, DEFAULT_PROC_PATH, DEFAULT_INITIAL_TIME_IN_STATE_PATH, new Injector()); @@ -259,18 +243,6 @@ public class KernelCpuThreadReader { } /** - * If a thread has strictly less than {@code minimumTotalCpuUsageMillis} total CPU usage, it - * will not be reported - */ - void setMinimumTotalCpuUsageMillis(int minimumTotalCpuUsageMillis) { - if (minimumTotalCpuUsageMillis < 0) { - Slog.w(TAG, "Negative minimumTotalCpuUsageMillis: " + minimumTotalCpuUsageMillis); - return; - } - mMinimumTotalCpuUsageMillis = minimumTotalCpuUsageMillis; - } - - /** * Read all of the CPU usage statistics for each child thread of a process * * @param processPath the {@code /proc} path of the thread @@ -292,7 +264,6 @@ public class KernelCpuThreadReader { + uid); } - int[] filteredThreadsCpuUsage = null; final Path allThreadsPath = processPath.resolve("task"); final ArrayList<ThreadCpuUsage> threadCpuUsages = new ArrayList<>(); try (DirectoryStream<Path> threadPaths = Files.newDirectoryStream(allThreadsPath)) { @@ -301,14 +272,6 @@ public class KernelCpuThreadReader { if (threadCpuUsage == null) { continue; } - if (mMinimumTotalCpuUsageMillis > totalCpuUsage(threadCpuUsage.usageTimesMillis)) { - if (filteredThreadsCpuUsage == null) { - filteredThreadsCpuUsage = new int[mFrequenciesKhz.length]; - } - filteredThreadsCpuUsage = - sumCpuUsage(filteredThreadsCpuUsage, threadCpuUsage.usageTimesMillis); - continue; - } threadCpuUsages.add(threadCpuUsage); } } catch (IOException e) { @@ -320,14 +283,6 @@ public class KernelCpuThreadReader { if (threadCpuUsages.isEmpty()) { return null; } - - // Add the filtered out thread CPU usage under an "other threads" ThreadCpuUsage - if (filteredThreadsCpuUsage != null) { - threadCpuUsages.add( - new ThreadCpuUsage( - OTHER_THREADS_ID, OTHER_THREADS_NAME, filteredThreadsCpuUsage)); - } - if (DEBUG) { Slog.d(TAG, "Read CPU usage of " + threadCpuUsages.size() + " threads"); } @@ -404,25 +359,6 @@ public class KernelCpuThreadReader { } } - /** Get the sum of all CPU usage across all frequencies */ - @SuppressWarnings("ForLoopReplaceableByForEach") - private static int totalCpuUsage(int[] cpuUsage) { - int total = 0; - for (int i = 0; i < cpuUsage.length; i++) { - total += cpuUsage[i]; - } - return total; - } - - /** Add two CPU frequency usages together */ - private static int[] sumCpuUsage(int[] a, int[] b) { - int[] summed = new int[a.length]; - for (int i = 0; i < a.length; i++) { - summed[i] = a[i] + b[i]; - } - return summed; - } - /** Puts frequencies and usage times into buckets */ @VisibleForTesting public static class FrequencyBucketCreator { @@ -553,9 +489,10 @@ public class KernelCpuThreadReader { public final int processId; public final String processName; public final int uid; - public final ArrayList<ThreadCpuUsage> threadCpuUsages; + public ArrayList<ThreadCpuUsage> threadCpuUsages; - ProcessCpuUsage( + @VisibleForTesting + public ProcessCpuUsage( int processId, String processName, int uid, @@ -571,9 +508,10 @@ public class KernelCpuThreadReader { public static class ThreadCpuUsage { public final int threadId; public final String threadName; - public final int[] usageTimesMillis; + public int[] usageTimesMillis; - ThreadCpuUsage(int threadId, String threadName, int[] usageTimesMillis) { + @VisibleForTesting + public ThreadCpuUsage(int threadId, String threadName, int[] usageTimesMillis) { this.threadId = threadId; this.threadName = threadName; this.usageTimesMillis = usageTimesMillis; diff --git a/core/java/com/android/internal/os/KernelCpuThreadReaderDiff.java b/core/java/com/android/internal/os/KernelCpuThreadReaderDiff.java new file mode 100644 index 000000000000..ffdc33c64f69 --- /dev/null +++ b/core/java/com/android/internal/os/KernelCpuThreadReaderDiff.java @@ -0,0 +1,305 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.internal.os; + +import android.annotation.Nullable; +import android.util.ArrayMap; +import android.util.Slog; + +import com.android.internal.annotations.VisibleForTesting; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +/** + * Delegates per-thread CPU collection to {@link KernelCpuThreadReader}, and calculates the + * difference between CPU usage at each call of {@link #getProcessCpuUsageDiffed()}. + * + * <p>Some notes on the diff calculation: + * + * <ul> + * <li>The diffing is done between each call of {@link #getProcessCpuUsageDiffed()}, i.e. call N + * of this method will return CPU used by threads between call N-1 and N. + * <li>The first call of {@link #getProcessCpuUsageDiffed()} will return no processes ("first + * call" is the first call in the lifetime of a {@link KernelCpuThreadReaderDiff} object). + * <li>If a thread does not exist at call N, but does exist at call N+1, the diff will assume that + * the CPU usage at call N was zero. Thus, the diff reported will be equivalent to the value + * returned by {@link KernelCpuThreadReader#getProcessCpuUsage()} at call N+1. + * <li>If an error occurs in {@link KernelCpuThreadReader} at call N, we will return no + * information for CPU usage between call N-1 and N (as we don't know the start value) and + * between N and N+1 (as we don't know the end value). Assuming all other calls are + * successful, the next call to return data will be N+2, for the period between N+1 and N+2. + * <li>If an error occurs in this class (but not in {@link KernelCpuThreadReader}) at call N, the + * data will only be dropped for call N, as we can still use the CPU data for the surrounding + * calls. + * </ul> + * + * <p>Additionally to diffing, this class also contains logic for thresholding reported threads. A + * thread will not be reported unless its total CPU usage is at least equal to the value set in + * {@link #setMinimumTotalCpuUsageMillis}. Filtered thread CPU usage is summed and reported under + * one "other threads" thread. This reduces the cardinality of the {@link + * #getProcessCpuUsageDiffed()} result. + * + * <p>Thresholding is done in this class, instead of {@link KernelCpuThreadReader}, and instead of + * WestWorld, because the thresholding should be done after diffing, not before. This is because of + * two issues with thresholding before diffing: + * + * <ul> + * <li>We would threshold less and less threads as thread uptime increases. + * <li>We would encounter errors as the filtered threads become unfiltered, as the "other threads" + * result could have negative diffs, and the newly unfiltered threads would have incorrect + * diffs that include CPU usage from when they were filtered. + * </ul> + * + * @hide Only for use within the system server + */ +@SuppressWarnings("ForLoopReplaceableByForEach") +public class KernelCpuThreadReaderDiff { + private static final String TAG = "KernelCpuThreadReaderDiff"; + + /** Thread ID used when reporting CPU used by other threads */ + private static final int OTHER_THREADS_ID = -1; + + /** Thread name used when reporting CPU used by other threads */ + private static final String OTHER_THREADS_NAME = "__OTHER_THREADS"; + + private final KernelCpuThreadReader mReader; + + /** + * CPU usage from the previous call of {@link #getProcessCpuUsageDiffed()}. Null if there was no + * previous call, or if the previous call failed + * + * <p>Maps the thread's identifier to the per-frequency CPU usage for that thread. The + * identifier contains the minimal amount of information to identify a thread (see {@link + * ThreadKey} for more information), thus reducing memory consumption. + */ + @Nullable private Map<ThreadKey, int[]> mPreviousCpuUsage; + + /** + * If a thread has strictly less than {@code minimumTotalCpuUsageMillis} total CPU usage, it + * will not be reported + */ + private int mMinimumTotalCpuUsageMillis; + + @VisibleForTesting + public KernelCpuThreadReaderDiff(KernelCpuThreadReader reader, int minimumTotalCpuUsageMillis) { + mReader = reader; + mMinimumTotalCpuUsageMillis = minimumTotalCpuUsageMillis; + mPreviousCpuUsage = null; + } + + /** + * Returns the difference in CPU usage since the last time this method was called. + * + * @see KernelCpuThreadReader#getProcessCpuUsage() + */ + @Nullable + public ArrayList<KernelCpuThreadReader.ProcessCpuUsage> getProcessCpuUsageDiffed() { + Map<ThreadKey, int[]> newCpuUsage = null; + try { + // Get the thread CPU usage and index them by ThreadKey + final ArrayList<KernelCpuThreadReader.ProcessCpuUsage> processCpuUsages = + mReader.getProcessCpuUsage(); + newCpuUsage = createCpuUsageMap(processCpuUsages); + // If there is no previous CPU usage, return nothing + if (mPreviousCpuUsage == null) { + return null; + } + + // Do diffing and thresholding for each process + for (int i = 0; i < processCpuUsages.size(); i++) { + KernelCpuThreadReader.ProcessCpuUsage processCpuUsage = processCpuUsages.get(i); + changeToDiffs(mPreviousCpuUsage, processCpuUsage); + applyThresholding(processCpuUsage); + } + return processCpuUsages; + } finally { + // Always update the previous CPU usage. If we haven't got an update, it will be set to + // null, so the next call knows there no previous values + mPreviousCpuUsage = newCpuUsage; + } + } + + /** @see KernelCpuThreadReader#getCpuFrequenciesKhz() */ + @Nullable + public int[] getCpuFrequenciesKhz() { + return mReader.getCpuFrequenciesKhz(); + } + + /** + * If a thread has strictly less than {@code minimumTotalCpuUsageMillis} total CPU usage, it + * will not be reported + */ + void setMinimumTotalCpuUsageMillis(int minimumTotalCpuUsageMillis) { + if (minimumTotalCpuUsageMillis < 0) { + Slog.w(TAG, "Negative minimumTotalCpuUsageMillis: " + minimumTotalCpuUsageMillis); + return; + } + mMinimumTotalCpuUsageMillis = minimumTotalCpuUsageMillis; + } + + /** + * Create a map of a thread's identifier to a thread's CPU usage. Used for fast indexing when + * calculating diffs + */ + private static Map<ThreadKey, int[]> createCpuUsageMap( + List<KernelCpuThreadReader.ProcessCpuUsage> processCpuUsages) { + final Map<ThreadKey, int[]> cpuUsageMap = new ArrayMap<>(); + for (int i = 0; i < processCpuUsages.size(); i++) { + KernelCpuThreadReader.ProcessCpuUsage processCpuUsage = processCpuUsages.get(i); + for (int j = 0; j < processCpuUsage.threadCpuUsages.size(); j++) { + KernelCpuThreadReader.ThreadCpuUsage threadCpuUsage = + processCpuUsage.threadCpuUsages.get(j); + cpuUsageMap.put( + new ThreadKey( + processCpuUsage.processId, + threadCpuUsage.threadId, + processCpuUsage.processName, + threadCpuUsage.threadName), + threadCpuUsage.usageTimesMillis); + } + } + return cpuUsageMap; + } + + /** + * Calculate the difference in per-frequency CPU usage for all threads in a process + * + * @param previousCpuUsage CPU usage from the last call, the base of the diff + * @param processCpuUsage CPU usage from the current call, this value is modified to contain the + * diffed values + */ + private static void changeToDiffs( + Map<ThreadKey, int[]> previousCpuUsage, + KernelCpuThreadReader.ProcessCpuUsage processCpuUsage) { + for (int i = 0; i < processCpuUsage.threadCpuUsages.size(); i++) { + KernelCpuThreadReader.ThreadCpuUsage threadCpuUsage = + processCpuUsage.threadCpuUsages.get(i); + final ThreadKey key = + new ThreadKey( + processCpuUsage.processId, + threadCpuUsage.threadId, + processCpuUsage.processName, + threadCpuUsage.threadName); + int[] previous = previousCpuUsage.get(key); + if (previous == null) { + // If there's no previous CPU usage, assume that it's zero + previous = new int[threadCpuUsage.usageTimesMillis.length]; + } + threadCpuUsage.usageTimesMillis = + cpuTimeDiff(threadCpuUsage.usageTimesMillis, previous); + } + } + + /** + * Filter out any threads with less than {@link #mMinimumTotalCpuUsageMillis} total CPU usage + * + * <p>The sum of the CPU usage of filtered threads is added under a single thread, labeled with + * {@link #OTHER_THREADS_ID} and {@link #OTHER_THREADS_NAME}. + * + * @param processCpuUsage CPU usage to apply thresholding to, this value is modified to change + * the threads it contains + */ + private void applyThresholding(KernelCpuThreadReader.ProcessCpuUsage processCpuUsage) { + int[] filteredThreadsCpuUsage = null; + final ArrayList<KernelCpuThreadReader.ThreadCpuUsage> thresholded = new ArrayList<>(); + for (int i = 0; i < processCpuUsage.threadCpuUsages.size(); i++) { + KernelCpuThreadReader.ThreadCpuUsage threadCpuUsage = + processCpuUsage.threadCpuUsages.get(i); + if (mMinimumTotalCpuUsageMillis > totalCpuUsage(threadCpuUsage.usageTimesMillis)) { + if (filteredThreadsCpuUsage == null) { + filteredThreadsCpuUsage = new int[threadCpuUsage.usageTimesMillis.length]; + } + addToCpuUsage(filteredThreadsCpuUsage, threadCpuUsage.usageTimesMillis); + continue; + } + thresholded.add(threadCpuUsage); + } + if (filteredThreadsCpuUsage != null) { + thresholded.add( + new KernelCpuThreadReader.ThreadCpuUsage( + OTHER_THREADS_ID, OTHER_THREADS_NAME, filteredThreadsCpuUsage)); + } + processCpuUsage.threadCpuUsages = thresholded; + } + + /** Get the sum of all CPU usage across all frequencies */ + private static int totalCpuUsage(int[] cpuUsage) { + int total = 0; + for (int i = 0; i < cpuUsage.length; i++) { + total += cpuUsage[i]; + } + return total; + } + + /** Add two CPU frequency usages together */ + private static void addToCpuUsage(int[] a, int[] b) { + for (int i = 0; i < a.length; i++) { + a[i] += b[i]; + } + } + + /** Subtract two CPU frequency usages from each other */ + private static int[] cpuTimeDiff(int[] a, int[] b) { + int[] difference = new int[a.length]; + for (int i = 0; i < a.length; i++) { + difference[i] = a[i] - b[i]; + } + return difference; + } + + /** + * Identifies a thread + * + * <p>Only stores the minimum amount of information to identify a thread. This includes the + * PID/TID, but as both are recycled as processes/threads end and begin, we also store the hash + * of the name of the process/thread. + */ + private static class ThreadKey { + private final int mProcessId; + private final int mThreadId; + private final int mProcessNameHash; + private final int mThreadNameHash; + + ThreadKey(int processId, int threadId, String processName, String threadName) { + this.mProcessId = processId; + this.mThreadId = threadId; + // Only store the hash to reduce memory consumption + this.mProcessNameHash = Objects.hash(processName); + this.mThreadNameHash = Objects.hash(threadName); + } + + @Override + public int hashCode() { + return Objects.hash(mProcessId, mThreadId, mProcessNameHash, mThreadNameHash); + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof ThreadKey)) { + return false; + } + ThreadKey other = (ThreadKey) obj; + return mProcessId == other.mProcessId + && mThreadId == other.mThreadId + && mProcessNameHash == other.mProcessNameHash + && mThreadNameHash == other.mThreadNameHash; + } + } +} diff --git a/core/java/com/android/internal/os/KernelCpuThreadReaderSettingsObserver.java b/core/java/com/android/internal/os/KernelCpuThreadReaderSettingsObserver.java index 3851ce6d9cbd..f8c0d9e4a27e 100644 --- a/core/java/com/android/internal/os/KernelCpuThreadReaderSettingsObserver.java +++ b/core/java/com/android/internal/os/KernelCpuThreadReaderSettingsObserver.java @@ -67,12 +67,14 @@ public class KernelCpuThreadReaderSettingsObserver extends ContentObserver { @Nullable private final KernelCpuThreadReader mKernelCpuThreadReader; + @Nullable private final KernelCpuThreadReaderDiff mKernelCpuThreadReaderDiff; + /** * @return returns a created {@link KernelCpuThreadReader} that will be modified by any change * in settings, returns null if creation failed */ @Nullable - public static KernelCpuThreadReader getSettingsModifiedReader(Context context) { + public static KernelCpuThreadReaderDiff getSettingsModifiedReader(Context context) { // Create the observer KernelCpuThreadReaderSettingsObserver settingsObserver = new KernelCpuThreadReaderSettingsObserver(context); @@ -82,7 +84,7 @@ public class KernelCpuThreadReaderSettingsObserver extends ContentObserver { .registerContentObserver( settingsUri, false, settingsObserver, UserHandle.USER_SYSTEM); // Return the observer's reader - return settingsObserver.mKernelCpuThreadReader; + return settingsObserver.mKernelCpuThreadReaderDiff; } private KernelCpuThreadReaderSettingsObserver(Context context) { @@ -90,9 +92,10 @@ public class KernelCpuThreadReaderSettingsObserver extends ContentObserver { mContext = context; mKernelCpuThreadReader = KernelCpuThreadReader.create( - NUM_BUCKETS_DEFAULT, - UidPredicate.fromString(COLLECTED_UIDS_DEFAULT), - MINIMUM_TOTAL_CPU_USAGE_MILLIS_DEFAULT); + NUM_BUCKETS_DEFAULT, UidPredicate.fromString(COLLECTED_UIDS_DEFAULT)); + mKernelCpuThreadReaderDiff = + new KernelCpuThreadReaderDiff( + mKernelCpuThreadReader, MINIMUM_TOTAL_CPU_USAGE_MILLIS_DEFAULT); } @Override @@ -130,7 +133,7 @@ public class KernelCpuThreadReaderSettingsObserver extends ContentObserver { mKernelCpuThreadReader.setNumBuckets( parser.getInt(NUM_BUCKETS_SETTINGS_KEY, NUM_BUCKETS_DEFAULT)); mKernelCpuThreadReader.setUidPredicate(uidPredicate); - mKernelCpuThreadReader.setMinimumTotalCpuUsageMillis( + mKernelCpuThreadReaderDiff.setMinimumTotalCpuUsageMillis( parser.getInt( MINIMUM_TOTAL_CPU_USAGE_MILLIS_SETTINGS_KEY, MINIMUM_TOTAL_CPU_USAGE_MILLIS_DEFAULT)); 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/java/com/android/internal/util/SyncResultReceiver.java b/core/java/com/android/internal/util/SyncResultReceiver.java index 60af5117489b..00e91017a9eb 100644 --- a/core/java/com/android/internal/util/SyncResultReceiver.java +++ b/core/java/com/android/internal/util/SyncResultReceiver.java @@ -19,10 +19,10 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.os.Bundle; import android.os.Parcelable; -import android.os.RemoteException; import com.android.internal.os.IResultReceiver; +import java.util.ArrayList; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; @@ -97,6 +97,15 @@ public final class SyncResultReceiver extends IResultReceiver.Stub { } /** + * Gets the result from an operation that returns a {@code Parcelable} list. + */ + @Nullable + public <P extends Parcelable> ArrayList<P> getParcelableListResult() throws TimeoutException { + waitResult(); + return mBundle == null ? null : mBundle.getParcelableArrayList(EXTRA); + } + + /** * Gets the optional result from an operation that returns an extra {@code int} (besides the * result code). * @@ -150,6 +159,17 @@ public final class SyncResultReceiver extends IResultReceiver.Stub { } /** + * Creates a bundle for a {@code Parcelable} list so it can be retrieved by + * {@link #getParcelableResult()}. + */ + @NonNull + public static Bundle bundleFor(@Nullable ArrayList<? extends Parcelable> value) { + final Bundle bundle = new Bundle(); + bundle.putParcelableArrayList(EXTRA, value); + return bundle; + } + + /** * Creates a bundle for an {@code int} value so it can be retrieved by * {@link #getParcelableResult()} - typically used to return an extra {@code int} (as the 1st * is returned as the result code). @@ -162,7 +182,7 @@ public final class SyncResultReceiver extends IResultReceiver.Stub { } /** @hide */ - public static final class TimeoutException extends RemoteException { + public static final class TimeoutException extends RuntimeException { private TimeoutException(String msg) { super(msg); } diff --git a/core/java/com/android/server/BootReceiver.java b/core/java/com/android/server/BootReceiver.java index 621d5a6e5c55..dc4f09a2af6f 100644 --- a/core/java/com/android/server/BootReceiver.java +++ b/core/java/com/android/server/BootReceiver.java @@ -307,6 +307,9 @@ public class BootReceiver extends BroadcastReceiver { if (tag.equals(TAG_TOMBSTONE) && fileContents.contains(">>> system_server <<<")) { addTextToDropBox(db, "system_server_native_crash", text, filename, maxSize); } + if (tag.equals(TAG_TOMBSTONE)) { + StatsLog.write(StatsLog.TOMB_STONE_OCCURRED); + } addTextToDropBox(db, tag, text, filename, maxSize); } diff --git a/core/java/com/android/server/SystemConfig.java b/core/java/com/android/server/SystemConfig.java index 561dcad390a9..9fc79cb606e6 100644 --- a/core/java/com/android/server/SystemConfig.java +++ b/core/java/com/android/server/SystemConfig.java @@ -1150,16 +1150,6 @@ public class SystemConfig { XmlUtils.skipCurrentTag(parser); } } - // If the storage model feature flag is disabled, we need to fiddle - // around with permission definitions to return us to pre-Q behavior. - // STOPSHIP(b/112545973): remove once feature enabled by default - if (!StorageManager.hasIsolatedStorage()) { - if (newPermissions.contains(android.Manifest.permission.READ_MEDIA_AUDIO) || - newPermissions.contains(android.Manifest.permission.READ_MEDIA_VIDEO) || - newPermissions.contains(android.Manifest.permission.READ_MEDIA_IMAGES)) { - return; - } - } if (!newPermissions.isEmpty()) { mSplitPermissions.add(new SplitPermissionInfo(splitPerm, newPermissions, targetSdk)); } diff --git a/core/jni/Android.bp b/core/jni/Android.bp index 664f7f47cf18..000c0449358a 100644 --- a/core/jni/Android.bp +++ b/core/jni/Android.bp @@ -303,6 +303,7 @@ cc_library_shared { "libnativewindow", "libhwui", "libdl", + "libdl_android", "libstatslog", "server_configurable_flags", ], 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/core/jni/android_media_AudioSystem.cpp b/core/jni/android_media_AudioSystem.cpp index 88713d10bb2d..a296d647657b 100644 --- a/core/jni/android_media_AudioSystem.cpp +++ b/core/jni/android_media_AudioSystem.cpp @@ -2229,6 +2229,11 @@ android_media_AudioSystem_isHapticPlaybackSupported(JNIEnv *env, jobject thiz) return AudioSystem::isHapticPlaybackSupported(); } +static jint +android_media_AudioSystem_setAllowedCapturePolicy(JNIEnv *env, jobject thiz, jint uid, jint flags) { + return AudioSystem::setAllowedCapturePolicy(uid, flags); +} + // ---------------------------------------------------------------------------- static const JNINativeMethod gMethods[] = { @@ -2304,6 +2309,7 @@ static const JNINativeMethod gMethods[] = { {"isHapticPlaybackSupported", "()Z", (void *)android_media_AudioSystem_isHapticPlaybackSupported}, {"getHwOffloadEncodingFormatsSupportedForA2DP", "(Ljava/util/ArrayList;)I", (void*)android_media_AudioSystem_getHwOffloadEncodingFormatsSupportedForA2DP}, + {"setAllowedCapturePolicy", "(II)I", (void *)android_media_AudioSystem_setAllowedCapturePolicy}, }; static const JNINativeMethod gEventHandlerMethods[] = { diff --git a/core/jni/android_net_NetUtils.cpp b/core/jni/android_net_NetUtils.cpp index d7a981ed3e9d..82acf6fb432b 100644 --- a/core/jni/android_net_NetUtils.cpp +++ b/core/jni/android_net_NetUtils.cpp @@ -470,6 +470,7 @@ static jbyteArray android_net_utils_resNetworkResult(JNIEnv *env, jobject thiz, std::vector<uint8_t> buf(MAXPACKETSIZE, 0); int res = resNetworkResult(fd, &rcode, buf.data(), MAXPACKETSIZE); + jniSetFileDescriptorOfFD(env, javaFd, -1); if (res < 0) { throwErrnoException(env, "resNetworkResult", -res); return nullptr; @@ -490,6 +491,7 @@ static jbyteArray android_net_utils_resNetworkResult(JNIEnv *env, jobject thiz, static void android_net_utils_resNetworkCancel(JNIEnv *env, jobject thiz, jobject javaFd) { int fd = jniGetFDFromFileDescriptor(env, javaFd); resNetworkCancel(fd); + jniSetFileDescriptorOfFD(env, javaFd, -1); } static jobject android_net_utils_getTcpRepairWindow(JNIEnv *env, jobject thiz, jobject javaFd) { diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp index 70b343624ea9..8dd7e8ea3b90 100644 --- a/core/jni/com_android_internal_os_Zygote.cpp +++ b/core/jni/com_android_internal_os_Zygote.cpp @@ -1634,6 +1634,8 @@ static void com_android_internal_os_Zygote_nativeSecurityInit(JNIEnv*, jclass) { // security_getenforce is not allowed on app process. Initialize and cache // the value before zygote forks. g_is_security_enforced = security_getenforce(); + + selinux_android_seapp_context_init(); } static void com_android_internal_os_Zygote_nativePreApplicationInit(JNIEnv*, jclass) { diff --git a/core/proto/android/app/enums.proto b/core/proto/android/app/enums.proto index 1754e426fe93..9abe92330cb0 100644 --- a/core/proto/android/app/enums.proto +++ b/core/proto/android/app/enums.proto @@ -38,6 +38,7 @@ enum AppTransitionReasonEnum { } // ActivityManager.java PROCESS_STATEs +// Next tag: 1021 enum ProcessStateEnum { // Unlike the ActivityManager PROCESS_STATE values, the ordering and numerical values // here are completely fixed and arbitrary. Order is irrelevant. @@ -56,9 +57,11 @@ enum ProcessStateEnum { // Process is hosting the current top activities. Note that this covers // all activities that are visible to the user. PROCESS_STATE_TOP = 1002; + // Process is bound to a TOP app. + PROCESS_STATE_BOUND_TOP = 1020; // Process is hosting a foreground service. PROCESS_STATE_FOREGROUND_SERVICE = 1003; - // Process is hosting a foreground service due to a system binding. + // Process is hosting a service bound by the system or another foreground app. PROCESS_STATE_BOUND_FOREGROUND_SERVICE = 1004; // Process is important to the user, and something they are aware of. PROCESS_STATE_IMPORTANT_FOREGROUND = 1005; diff --git a/core/proto/android/app/settings_enums.proto b/core/proto/android/app/settings_enums.proto index bf33ac67e333..d0295274dbe4 100644 --- a/core/proto/android/app/settings_enums.proto +++ b/core/proto/android/app/settings_enums.proto @@ -2328,4 +2328,7 @@ enum PageId { // OPEN: Settings > System > Aware > Info dialog DIALOG_AWARE_STATUS = 1701; + + // Open: Settings > app > bubble settings > confirmation dialog + DIALOG_APP_BUBBLE_SETTINGS = 1702; } diff --git a/core/proto/android/os/incident.proto b/core/proto/android/os/incident.proto index dfb6c0817043..9a9c9d14154b 100644 --- a/core/proto/android/os/incident.proto +++ b/core/proto/android/os/incident.proto @@ -48,6 +48,7 @@ import "frameworks/base/core/proto/android/service/notification.proto"; import "frameworks/base/core/proto/android/service/package.proto"; import "frameworks/base/core/proto/android/service/print.proto"; import "frameworks/base/core/proto/android/service/procstats.proto"; +import "frameworks/base/core/proto/android/service/restricted_image.proto"; import "frameworks/base/core/proto/android/service/usb.proto"; import "frameworks/base/core/proto/android/util/event_log_tags.proto"; import "frameworks/base/core/proto/android/util/log.proto"; @@ -314,6 +315,12 @@ message IncidentProto { (section).args = "role --proto" ]; + optional android.service.restricted_image.RestrictedImagesDumpProto restricted_images = 3025 [ + (section).type = SECTION_DUMPSYS, + (section).userdebug_and_eng_only = true, + (section).args = "incidentcompanion --restricted_image" + ]; + // Reserved for OEMs. extensions 50000 to 100000; } diff --git a/core/proto/android/providers/settings/global.proto b/core/proto/android/providers/settings/global.proto index d124feb2436e..b47097da0cdd 100644 --- a/core/proto/android/providers/settings/global.proto +++ b/core/proto/android/providers/settings/global.proto @@ -455,6 +455,8 @@ message GlobalSettingsProto { optional SettingProto show_angle_in_use_dialog = 15; // Game Driver - List of libraries in sphal accessible by Game Driver optional SettingProto game_driver_sphal_libraries = 16; + // ANGLE - External package containing ANGLE libraries + optional SettingProto angle_debug_package = 17; } optional Gpu gpu = 59; diff --git a/core/proto/android/service/restricted_image.proto b/core/proto/android/service/restricted_image.proto new file mode 100644 index 000000000000..4a33d478fbde --- /dev/null +++ b/core/proto/android/service/restricted_image.proto @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +syntax = "proto2"; +package android.service.restricted_image; + +option java_multiple_files = true; +option java_outer_classname = "RestrictedImage"; + +import "frameworks/base/core/proto/android/privacy.proto"; + +// Restricted Image proto is for collecting images from the user with their +// permission for the purpose of debugging photos. +message RestrictedImagesDumpProto { + option (android.msg_privacy).dest = DEST_EXPLICIT; + + repeated RestrictedImageSetProto sets = 1; +} + +message RestrictedImageSetProto { + option (android.msg_privacy).dest = DEST_EXPLICIT; + + // Name of the service producing the data. + optional string category = 1; + + // The images + repeated RestrictedImageProto images = 2; + + // Additional metadata + optional bytes metadata = 3; +} + +message RestrictedImageProto { + option (android.msg_privacy).dest = DEST_EXPLICIT; + + // Type of image data + optional string mime_type = 1; + + // The image data + optional bytes image_data = 2; + + // Metadata about the image. Typically this has another proto schema, + // but it is undefined exactly what that is in AOSP code. + optional bytes metadata = 3; +} diff --git a/core/proto/android/stats/connectivity/resolv_stats.proto b/core/proto/android/stats/connectivity/resolv_stats.proto new file mode 100644 index 000000000000..43eb67397fa5 --- /dev/null +++ b/core/proto/android/stats/connectivity/resolv_stats.proto @@ -0,0 +1,182 @@ +/* + * 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. + */ +syntax = "proto2"; +package android.stats.connectivity; +import "frameworks/base/core/proto/android/net/networkcapabilities.proto"; + +enum EventType { + EVENT_UNKNOWN = 0; + EVENT_GETADDRINFO = 1; + EVENT_GETHOSTBYNAME = 2; + EVENT_GETHOSTBYADDR = 3; + EVENT_RES_NSEND = 4; +} + +enum PrivateDnsModes { + OFF = 0; + OPPORTUNISTIC = 1; + STRICT = 2; +} +// The return value of the DNS resolver for each DNS lookups. +// bionic/libc/include/netdb.h +// system/netd/resolv/include/netd_resolv/resolv.h +enum ReturnCode { + RC_EAI_NO_ERROR = 0; + RC_EAI_ADDRFAMILY = 1; + RC_EAI_AGAIN = 2; + RC_EAI_BADFLAGS = 3; + RC_EAI_FAIL = 4; + RC_EAI_FAMILY = 5; + RC_EAI_MEMORY = 6; + RC_EAI_NODATA = 7; + RC_EAI_NONAME = 8; + RC_EAI_SERVICE = 9; + RC_EAI_SOCKTYPE = 10; + RC_EAI_SYSTEM = 11; + RC_EAI_BADHINTS = 12; + RC_EAI_PROTOCOL = 13; + RC_EAI_OVERFLOW = 14; + RC_RESOLV_TIMEOUT = 255; + RC_EAI_MAX = 256; +} + + +enum NsRcode { + ns_r_noerror = 0; // No error occurred. + ns_r_formerr = 1; // Format error. + ns_r_servfail = 2; // Server failure. + ns_r_nxdomain = 3; // Name error. + ns_r_notimpl = 4; // Unimplemented. + ns_r_refused = 5; // Operation refused. + // these are for BIND_UPDATE + ns_r_yxdomain = 6; // Name exists + ns_r_yxrrset = 7; // RRset exists + ns_r_nxrrset = 8; // RRset does not exist + ns_r_notauth = 9; // Not authoritative for zone + ns_r_notzone = 10; // Zone of record different from zone section + ns_r_max = 11; + // The following are EDNS extended rcodes + ns_r_badvers = 16; + // The following are TSIG errors + //ns_r_badsig = 16, + ns_r_badkey = 17; + ns_r_badtime = 18; +} + +// Currently defined type values for resources and queries. +enum NsType { + ns_t_invalid = 0; // Cookie. + ns_t_a = 1; // Host address. + ns_t_ns = 2; // Authoritative server. + ns_t_md = 3; // Mail destination. + ns_t_mf = 4; // Mail forwarder. + ns_t_cname = 5; // Canonical name. + ns_t_soa = 6; // Start of authority zone. + ns_t_mb = 7; // Mailbox domain name. + ns_t_mg = 8; // Mail group member. + ns_t_mr = 9; // Mail rename name. + ns_t_null = 10; // Null resource record. + ns_t_wks = 11; // Well known service. + ns_t_ptr = 12; // Domain name pointer. + ns_t_hinfo = 13; // Host information. + ns_t_minfo = 14; // Mailbox information. + ns_t_mx = 15; // Mail routing information. + ns_t_txt = 16; // Text strings. + ns_t_rp = 17; // Responsible person. + ns_t_afsdb = 18; // AFS cell database. + ns_t_x25 = 19; // X_25 calling address. + ns_t_isdn = 20; // ISDN calling address. + ns_t_rt = 21; // Router. + ns_t_nsap = 22; // NSAP address. + ns_t_nsap_ptr = 23; // Reverse NSAP lookup (deprecated). + ns_t_sig = 24; // Security signature. + ns_t_key = 25; // Security key. + ns_t_px = 26; // X.400 mail mapping. + ns_t_gpos = 27; // Geographical position (withdrawn). + ns_t_aaaa = 28; // IPv6 Address. + ns_t_loc = 29; // Location Information. + ns_t_nxt = 30; // Next domain (security). + ns_t_eid = 31; // Endpoint identifier. + ns_t_nimloc = 32; // Nimrod Locator. + ns_t_srv = 33; // Server Selection. + ns_t_atma = 34; // ATM Address + ns_t_naptr = 35; // Naming Authority PoinTeR + ns_t_kx = 36; // Key Exchange + ns_t_cert = 37; // Certification record + ns_t_a6 = 38; // IPv6 address (experimental) + ns_t_dname = 39; // Non-terminal DNAME + ns_t_sink = 40; // Kitchen sink (experimentatl) + ns_t_opt = 41; // EDNS0 option (meta-RR) + ns_t_apl = 42; // Address prefix list (RFC 3123) + ns_t_ds = 43; // Delegation Signer + ns_t_sshfp = 44; // SSH Fingerprint + ns_t_ipseckey = 45; // IPSEC Key + ns_t_rrsig = 46; // RRset Signature + ns_t_nsec = 47; // Negative security + ns_t_dnskey = 48; // DNS Key + ns_t_dhcid = 49; // Dynamic host configuratin identifier + ns_t_nsec3 = 50; // Negative security type 3 + ns_t_nsec3param = 51;// Negative security type 3 parameters + ns_t_hip = 55; // Host Identity Protocol + ns_t_spf = 99; // Sender Policy Framework + ns_t_tkey = 249; // Transaction key + ns_t_tsig = 250; // Transaction signature. + ns_t_ixfr = 251; // Incremental zone transfer. + ns_t_axfr = 252; // Transfer zone of authority. + ns_t_mailb = 253; // Transfer mailbox records. + ns_t_maila = 254; // Transfer mail agent records. + ns_t_any = 255; // Wildcard match. + ns_t_zxfr = 256; // BIND-specific, nonstandard. + ns_t_dlv = 32769; // DNSSEC look-aside validatation. + ns_t_max = 65536; +} + +enum IpVersion { + IPV4 = 0; + IPV6 = 1; + MIXED = 2; +} + +enum TransportType { + UDP = 0; + TCP = 1; + DOT = 2; + DOT_UDP = 3; + DOT_TCP = 4; +} + +message DnsQueryEvent { + optional NsRcode rrcode = 1; + optional NsType rrtype = 2; + optional bool cache_hit = 3; + optional IpVersion ipversion = 4; + optional TransportType transport = 5; + optional int32 packet_retransmits = 6; // Used only by the UDP transport + optional int32 reconnects = 7; // Used only by TCP and DOT + optional int32 latency_micros = 8; + optional int32 active_experiments = 9; + optional android.net.NetworkCapabilitiesProto.Transport network_type = 10; +} + +message DnsQueryEventRe { + repeated DnsQueryEvent dns_query_event = 1; +} + + +message DnsCallEvent { + +} + diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index cffa46c64b36..3788f479a1a4 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -629,6 +629,9 @@ <protected-broadcast android:name="android.intent.action.DEVICE_CUSTOMIZATION_READY" /> + <!-- For tether entitlement recheck--> + <protected-broadcast + android:name="com.android.server.connectivity.tethering.PROVISIONING_RECHECK_ALARM" /> <!-- ====================================================================== --> <!-- RUNTIME PERMISSIONS --> <!-- ====================================================================== --> @@ -786,8 +789,7 @@ <!-- ====================================================================== --> <eat-comment /> - <!-- Used for runtime permissions related to the shared external storage. - @deprecated replaced by new strongly-typed permission groups in Q. --> + <!-- Used for runtime permissions related to the shared external storage. --> <permission-group android:name="android.permission-group.STORAGE" android:icon="@drawable/perm_group_storage" android:label="@string/permgrouplab_storage" @@ -815,7 +817,6 @@ grants your app this permission. If you don't need this permission, be sure your <a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code targetSdkVersion}</a> is 4 or higher. - @deprecated replaced by new strongly-typed permission groups in Q. --> <permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:permissionGroup="android.permission-group.UNDEFINED" @@ -836,7 +837,6 @@ read/write files in your application-specific directories returned by {@link android.content.Context#getExternalFilesDir} and {@link android.content.Context#getExternalCacheDir}. - @deprecated replaced by new strongly-typed permission groups in Q. --> <permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:permissionGroup="android.permission-group.UNDEFINED" @@ -844,46 +844,6 @@ android:description="@string/permdesc_sdcardWrite" android:protectionLevel="dangerous" /> - <!-- Runtime permission controlling access to the user's shared aural media - collection. --> - <permission-group android:name="android.permission-group.MEDIA_AURAL" - android:icon="@drawable/perm_group_aural" - android:label="@string/permgrouplab_aural" - android:description="@string/permgroupdesc_aural" - android:request="@string/permgrouprequest_aural" - android:priority="910" /> - - <!-- Allows an application to read the user's shared audio collection. --> - <permission android:name="android.permission.READ_MEDIA_AUDIO" - android:permissionGroup="android.permission-group.UNDEFINED" - android:label="@string/permlab_audioRead" - android:description="@string/permdesc_audioRead" - android:protectionLevel="dangerous" /> - - <!-- Runtime permission controlling access to the user's shared visual media - collection, including images and videos. --> - <permission-group android:name="android.permission-group.MEDIA_VISUAL" - android:icon="@drawable/perm_group_visual" - android:label="@string/permgrouplab_visual" - android:description="@string/permgroupdesc_visual" - android:request="@string/permgrouprequest_visual" - android:requestDetail="@string/permgrouprequestdetail_visual" - android:priority="920" /> - - <!-- Allows an application to read the user's shared images collection. --> - <permission android:name="android.permission.READ_MEDIA_IMAGES" - android:permissionGroup="android.permission-group.UNDEFINED" - android:label="@string/permlab_imagesRead" - android:description="@string/permdesc_imagesRead" - android:protectionLevel="dangerous" /> - - <!-- Allows an application to read the user's shared video collection. --> - <permission android:name="android.permission.READ_MEDIA_VIDEO" - android:permissionGroup="android.permission-group.UNDEFINED" - android:label="@string/permlab_videoRead" - android:description="@string/permdesc_videoRead" - android:protectionLevel="dangerous" /> - <!-- Allows an application to access any geographic locations persisted in the user's shared collection. --> <permission android:name="android.permission.ACCESS_MEDIA_LOCATION" @@ -1011,6 +971,9 @@ call with the option to redirect the call to a different number or abort the call altogether. <p>Protection level: dangerous + + @deprecated Applications should use {@link android.telecom.CallRedirectionService} instead + of the {@link android.content.Intent#ACTION_NEW_OUTGOING_CALL} broadcast. --> <permission android:name="android.permission.PROCESS_OUTGOING_CALLS" android:permissionGroup="android.permission-group.UNDEFINED" @@ -1600,6 +1563,14 @@ <permission android:name="android.permission.NETWORK_MANAGED_PROVISIONING" android:protectionLevel="signature" /> + <!-- Allows Carrier Provisioning to call methods in Networking services + <p>Not for use by any other third-party or privileged applications. + @SystemApi + @hide This should only be used by CarrierProvisioning. + --> + <permission android:name="android.permission.NETWORK_CARRIER_PROVISIONING" + android:protectionLevel="signature|privileged" /> + <!-- #SystemApi @hide Allows applications to access information about LoWPAN interfaces. <p>Not for use by third-party applications. --> <permission android:name="android.permission.ACCESS_LOWPAN_STATE" @@ -1714,6 +1685,12 @@ <permission android:name="android.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS" android:protectionLevel="signature|privileged" /> + <!-- @SystemApi Allows an internal user to set signal strength in NetworkRequest. This kind of + request will wake up device when signal strength meets the given value. + @hide --> + <permission android:name="android.permission.NETWORK_SIGNAL_STRENGTH_WAKEUP" + android:protectionLevel="signature|privileged" /> + <!-- @SystemApi Allows a system application to access hardware packet offload capabilities. @hide --> <permission android:name="android.permission.PACKET_KEEPALIVE_OFFLOAD" diff --git a/packages/SystemUI/res/drawable/ic_signal_airplane.xml b/core/res/res/drawable/ic_qs_airplane.xml index f708ed9cb8a6..166d415a6dcc 100644 --- a/packages/SystemUI/res/drawable/ic_signal_airplane.xml +++ b/core/res/res/drawable/ic_qs_airplane.xml @@ -15,12 +15,11 @@ limitations under the License. --> <vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" + android:width="18dp" + android:height="18dp" android:viewportWidth="24" android:viewportHeight="24"> - -<path - android:fillColor="#FFFFFF" - android:pathData="M21,16v-2l-8-5V3.5C13,2.67,12.33,2,11.5,2S10,2.67,10,3.5V9l-8,5v2l8-2.5V19l-2,1.5V22l3.5-1l3.5,1v-1.5L13,19v-5.5L21,16z" /> + <path + android:fillColor="#FFFFFF" + android:pathData="M21,16v-2l-8-5V3.5C13,2.67,12.33,2,11.5,2S10,2.67,10,3.5V9l-8,5v2l8-2.5V19l-2,1.5V22l3.5-1l3.5,1v-1.5L13,19v-5.5L21,16z" /> </vector> 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 09a6aabf40bb..b361169ce1af 100644 --- a/packages/SystemUI/res/drawable/ic_dnd.xml +++ b/core/res/res/drawable/ic_qs_dnd.xml @@ -14,17 +14,12 @@ limitations under the License. --> <vector xmlns:android="http://schemas.android.com/apk/res/android" - android:height="24dp" + android:height="17dp" + android:width="17dp" android:viewportHeight="24.0" - android:viewportWidth="24.0" - android:width="24dp" - android:tint="?android:attr/colorControlNormal"> + android:viewportWidth="24.0" > <path - android:fillColor="#FFFFFFFF" - android:pathData="M12,2C6.48,2 2,6.48 2,12c0,5.52 4.48,10 10,10c5.52,0 10,-4.48 10,-10C22,6.48 17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8c0,-4.41 3.59,-8 8,-8c4.41,0 8,3.59 8,8C20,16.41 16.41,20 12,20z"/> - <path - android:fillColor="#FFFFFFFF" - android:pathData="M7,11h10v2h-10z"/> - + android:fillColor="@android:color/white" + android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8zM7,11h10v2L7,13z"/> </vector> 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-sw600dp/config.xml b/core/res/res/values-sw600dp/config.xml index 6edb88eb5347..e2c8d8a57e85 100644 --- a/core/res/res/values-sw600dp/config.xml +++ b/core/res/res/values-sw600dp/config.xml @@ -51,5 +51,9 @@ 4 - Snap to the long edges in each orientation and magnet to corners --> <integer name="config_pictureInPictureSnapMode">3</integer> + + <!-- Controls whether the nav bar can move from the bottom to the side in landscape. + Only applies if the device display is not square. --> + <bool name="config_navBarCanMove">false</bool> </resources> 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/config.xml b/core/res/res/values/config.xml index 05b5389ba0d8..ec2a6ae572c0 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -2442,6 +2442,16 @@ <!-- Maximum number of users we allow to be running at a time --> <integer name="config_multiuserMaxRunningUsers">3</integer> + <!-- Whether to delay user data locking for background user. + If false, user switched-out from user switching will still be in running state until + config_multiuserMaxRunningUsers is reached. Once config_multiuserMaxRunningUsers is + reached, user will be stopped and user data is locked. + If true, user switched out from user switching will always be stopped but its user data + is not locked. Total number of unlocked users will be limited by + config_multiuserMaxRunningUsers. Once that limit is reached, least recently stopped user + will be locked. --> + <bool name="config_multiuserDelayUserDataLocking">false</bool> + <!-- Whether UI for multi user should be shown --> <bool name="config_enableMultiUserUI">false</bool> @@ -3237,6 +3247,16 @@ 2: gestures only for back, home and overview --> <integer name="config_navBarInteractionMode">0</integer> + <!-- Controls whether the nav bar can move from the bottom to the side in landscape. + Only applies if the device display is not square. --> + <bool name="config_navBarCanMove">true</bool> + + <!-- Controls whether the navigation bar lets through taps. --> + <bool name="config_navBarTapThrough">false</bool> + + <!-- Controls the size of the back gesture inset. --> + <dimen name="config_backGestureInset">0dp</dimen> + <!-- Default insets [LEFT/RIGHTxTOP/BOTTOM] from the screen edge for picture-in-picture windows. These values are in DPs and will be converted to pixel sizes internally. --> <string translatable="false" name="config_defaultPictureInPictureScreenEdgeInsets">16x16</string> @@ -3961,7 +3981,7 @@ M5,17.5 V12 H3 L7,4.5 V10 h2 L5,17.5 z </string> <string name="config_batterymeterPowersavePath" translatable="false"> - M9.75,10l-2.5,0l0,-2.5l-2.5,0l0,2.5l-2.5,0l0,2.5l2.5,0l0,2.5l2.5,0l0,-2.5l2.5,0z + M9,10l-2,0l0,-2l-2,0l0,2l-2,0l0,2l2,0l0,2l2,0l0,-2l2,0z </string> <!-- A dual tone battery meter draws the perimeter path twice - once to define the shape @@ -3979,6 +3999,9 @@ <!-- Whether or not to enable automatic heap dumps for the system server on debuggable builds. --> <bool name="config_debugEnableAutomaticSystemServerHeapDumps">false</bool> + <!-- Trigger a heap dump if the system server pss usage exceeds this threshold. 400 MB --> + <integer name="config_debugSystemServerPssThresholdBytes">419430400</integer> + <!-- See DropBoxManagerService. The minimum period in milliseconds between broadcasts for entries with low priority dropbox tags. --> @@ -3989,8 +4012,16 @@ rated limited to a period defined by config_dropboxLowPriorityBroadcastRateLimitPeriod (high frequency broadcasts for the tag will be dropped) --> <string-array name="config_dropboxLowPriorityTags" translatable="false"> + <item>data_app_strictmode</item> + <item>data_app_wtf</item> <item>keymaster</item> + <item>netstats</item> + <item>system_app_strictmode</item> + <item>system_app_wtf</item> <item>system_server_strictmode</item> + <item>system_server_wtf</item> </string-array> + <!-- Which binder services to include in incident reports containing restricted images. --> + <string-array name="config_restrictedImagesServices" translatable="false"/> </resources> diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml index feecd020b087..c646fefad9d6 100644 --- a/core/res/res/values/dimens.xml +++ b/core/res/res/values/dimens.xml @@ -47,6 +47,9 @@ <dimen name="navigation_bar_height_landscape">48dp</dimen> <!-- Width of the navigation bar when it is placed vertically on the screen --> <dimen name="navigation_bar_width">48dp</dimen> + <!-- How much we expand the touchable region of the status bar below the notch to catch touches + that just start below the notch. --> + <dimen name="display_cutout_touchable_region_size">12dp</dimen> <!-- EXPERIMENT BEGIN --> <!-- Height of the bottom navigation bar frame; this is different than navigation_bar_height 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..b92033eeab7d 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -747,12 +747,12 @@ <b><xliff:g id="app_name" example="Gmail">%1$s</xliff:g></b> to record audio?</string> <!-- Title of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. [CHAR LIMIT=40]--> - <string name="permgrouplab_activityRecognition">Activity recognition</string> + <string name="permgrouplab_activityRecognition">Physical activity</string> <!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. [CHAR LIMIT=40]--> - <string name="permgroupdesc_activityRecognition">recognize activity</string> + <string name="permgroupdesc_activityRecognition">access your physical activity</string> <!-- Message shown to the user when the apps requests permission from this group. If ever possible this should stay below 80 characters (assuming the parameters takes 20 characters). Don't abbreviate until the message reaches 120 characters though. [CHAR LIMIT=120] --> <string name="permgrouprequest_activityRecognition">Allow - <b><xliff:g id="app_name" example="Gmail">%1$s</xliff:g></b> to recognize your physical activity?</string> + <b><xliff:g id="app_name" example="Gmail">%1$s</xliff:g></b> to access your physical activity?</string> <!-- Title of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. --> <string name="permgrouplab_camera">Camera</string> @@ -786,24 +786,6 @@ <string name="permgrouprequest_sensors">Allow <b><xliff:g id="app_name" example="Gmail">%1$s</xliff:g></b> to access sensor data about your vital signs?</string> - <!-- Title of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. --> - <string name="permgrouplab_aural">Music</string> - <!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. --> - <string name="permgroupdesc_aural">access your music</string> - <!-- Message shown to the user when the apps requests permission from this group. If ever possible this should stay below 80 characters (assuming the parameters takes 20 characters). Don't abbreviate until the message reaches 120 characters though. [CHAR LIMIT=120] --> - <string name="permgrouprequest_aural">Allow - <b><xliff:g id="app_name" example="Gmail">%1$s</xliff:g></b> to access your music?</string> - - <!-- Title of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. --> - <string name="permgrouplab_visual">Photos & videos</string> - <!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. --> - <string name="permgroupdesc_visual">access your photos & videos</string> - <!-- Message shown to the user when the apps requests permission from this group. If ever possible this should stay below 80 characters (assuming the parameters takes 20 characters). Don't abbreviate until the message reaches 120 characters though. [CHAR LIMIT=120] --> - <string name="permgrouprequest_visual">Allow - <b><xliff:g id="app_name" example="Gmail">%1$s</xliff:g></b> to access your photos and videos?</string> - <!-- Subtitle of the message shown to the user when the apps requests permission to access photos and videos [CHAR LIMIT=150]--> - <string name="permgrouprequestdetail_visual">This includes any locations tagged in your photos and videos</string> - <!-- Title for the capability of an accessibility service to retrieve window content. --> <string name="capability_title_canRetrieveWindowContent">Retrieve window content</string> <!-- Description for the capability of an accessibility service to retrieve window content. --> @@ -1432,28 +1414,16 @@ <string name="permdesc_useFingerprint">Allows the app to use fingerprint hardware for authentication</string> <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. --> - <string name="permlab_audioRead">read your music collection</string> - <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. --> - <string name="permdesc_audioRead">Allows the app to read your music collection.</string> - <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. --> <string name="permlab_audioWrite">modify your music collection</string> <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. --> <string name="permdesc_audioWrite">Allows the app to modify your music collection.</string> <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. --> - <string name="permlab_videoRead">read your video collection</string> - <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. --> - <string name="permdesc_videoRead">Allows the app to read your video collection.</string> - <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. --> <string name="permlab_videoWrite">modify your video collection</string> <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. --> <string name="permdesc_videoWrite">Allows the app to modify your video collection.</string> <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. --> - <string name="permlab_imagesRead">read your photo collection</string> - <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. --> - <string name="permdesc_imagesRead">Allows the app to read your photo collection.</string> - <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. --> <string name="permlab_imagesWrite">modify your photo collection</string> <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. --> <string name="permdesc_imagesWrite">Allows the app to modify your photo collection.</string> @@ -1582,25 +1552,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> @@ -3305,13 +3275,13 @@ <xliff:g id="proc" example="Android System">%1$s</xliff:g> process has exceeded its memory limit of <xliff:g id="size" example="350MB">%2$s</xliff:g>. A heap dump is available for you to share. Be careful: this heap dump can contain any sensitive personal information - that the process has access to.</string> + that the process has access to, which may include things you\u2019ve typed.</string> <!-- Text of dialog prompting the user to share a heap dump that they initiated [CHAR LIMIT=NONE] --> <string name="dump_heap_ready_text">A heap dump of <xliff:g id="proc" example="com.android.example">%1$s</xliff:g>\u2019s process is available for you to share. Be careful: this heap dump may contain any sensitive personal information - that the process has access to.</string> + that the process has access to, which may include things you\u2019ve typed.</string> <!-- Displayed in the title of the chooser for things to do with text that is to be sent to another application. For example, I can send @@ -4325,10 +4295,10 @@ <!-- Activity starter --> <!-- Toast message for blocking background activity starts feature running in permissive mode --> - <string name="activity_starter_block_bg_activity_starts_permissive">This background activity start from <xliff:g id="packageName" example="com.example">%1$s</xliff:g> will be blocked in future Q builds. See go/q-bg-block.</string> + <string name="activity_starter_block_bg_activity_starts_permissive">This background activity start from <xliff:g id="packageName" example="com.example">%1$s</xliff:g> will be blocked in future Q builds. See g.co/dev/bgblock.</string> <!-- Toast message for blocking background activity starts feature running in enforcing mode --> - <string name="activity_starter_block_bg_activity_starts_enforcing">Background activity start from <xliff:g id="packageName" example="com.example">%1$s</xliff:g> blocked. See go/q-bg-block. </string> + <string name="activity_starter_block_bg_activity_starts_enforcing">Background activity start from <xliff:g id="packageName" example="com.example">%1$s</xliff:g> blocked. See g.co/dev/bgblock. </string> <!-- Keyguard strings --> <!-- Message shown in pattern unlock after some number of unsuccessful attempts --> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index f72004b43460..3e23640ed872 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -498,6 +498,7 @@ <java-symbol type="integer" name="config_lockSoundVolumeDb" /> <java-symbol type="integer" name="config_multiuserMaximumUsers" /> <java-symbol type="integer" name="config_multiuserMaxRunningUsers" /> + <java-symbol type="bool" name="config_multiuserDelayUserDataLocking" /> <java-symbol type="integer" name="config_safe_media_volume_index" /> <java-symbol type="integer" name="config_safe_media_volume_usb_mB" /> <java-symbol type="integer" name="config_mobile_mtu" /> @@ -1443,6 +1444,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" /> @@ -1745,6 +1751,7 @@ <java-symbol type="dimen" name="navigation_bar_height_landscape_car_mode" /> <java-symbol type="dimen" name="navigation_bar_width_car_mode" /> <java-symbol type="dimen" name="status_bar_height" /> + <java-symbol type="dimen" name="display_cutout_touchable_region_size" /> <java-symbol type="dimen" name="quick_qs_offset_height" /> <java-symbol type="dimen" name="quick_qs_total_height" /> <java-symbol type="drawable" name="ic_jog_dial_sound_off" /> @@ -2838,6 +2845,9 @@ <java-symbol type="bool" name="config_forceWindowDrawsStatusBarBackground" /> <java-symbol type="integer" name="config_navBarOpacityMode" /> <java-symbol type="integer" name="config_navBarInteractionMode" /> + <java-symbol type="bool" name="config_navBarCanMove" /> + <java-symbol type="bool" name="config_navBarTapThrough" /> + <java-symbol type="dimen" name="config_backGestureInset" /> <java-symbol type="color" name="system_bar_background_semi_transparent" /> <!-- EditText suggestion popup. --> @@ -3224,6 +3234,7 @@ <java-symbol type="bool" name="config_batterymeterDualTone" /> <java-symbol type="bool" name="config_debugEnableAutomaticSystemServerHeapDumps" /> + <java-symbol type="integer" name="config_debugSystemServerPssThresholdBytes" /> <!-- Accessibility Shortcut --> <java-symbol type="string" name="accessibility_shortcut_warning_dialog_title" /> @@ -3680,6 +3691,7 @@ <java-symbol type="integer" name="config_attentionApiTimeout" /> <java-symbol type="string" name="config_incidentReportApproverPackage" /> + <java-symbol type="array" name="config_restrictedImagesServices" /> <!-- Display White-Balance --> <java-symbol type="integer" name="config_displayWhiteBalanceBrightnessSensorRate" /> diff --git a/core/tests/coretests/res/raw/com_android_tzdata.apex b/core/tests/coretests/res/raw/com_android_tzdata.apex Binary files differindex 06ea8fad6393..ca89bf66c8ff 100644 --- a/core/tests/coretests/res/raw/com_android_tzdata.apex +++ b/core/tests/coretests/res/raw/com_android_tzdata.apex diff --git a/core/tests/coretests/src/android/content/pm/PackageParserTest.java b/core/tests/coretests/src/android/content/pm/PackageParserTest.java index 0798c0c0805a..50e915d688d0 100644 --- a/core/tests/coretests/src/android/content/pm/PackageParserTest.java +++ b/core/tests/coretests/src/android/content/pm/PackageParserTest.java @@ -499,30 +499,20 @@ public class PackageParserTest { public void testApexPackageInfoGeneration() throws Exception { File apexFile = copyRawResourceToFile("com.android.tzdata.apex", R.raw.com_android_tzdata); - PackageInfo pi = PackageParser.generatePackageInfoFromApex(apexFile, false); + int flags = PackageManager.GET_META_DATA | PackageManager.GET_SIGNING_CERTIFICATES; + PackageInfo pi = PackageParser.generatePackageInfoFromApex(apexFile, flags); assertEquals("com.google.android.tzdata", pi.applicationInfo.packageName); assertTrue(pi.applicationInfo.enabled); assertEquals(28, pi.applicationInfo.targetSdkVersion); - assertEquals(1, pi.applicationInfo.longVersionCode); + assertEquals(191000070, pi.applicationInfo.longVersionCode); + assertNotNull(pi.applicationInfo.metaData); + assertEquals(apexFile.getPath(), pi.applicationInfo.sourceDir); + assertEquals("Bundle[{com.android.vending.derived.apk.id=1}]", + pi.applicationInfo.metaData.toString()); assertEquals("com.google.android.tzdata", pi.packageName); - assertTrue(pi.splitNames.length > 0); - assertEquals(1, pi.getLongVersionCode()); - assertNull(pi.signingInfo); - assertNull(pi.signatures); - assertTrue(pi.isApex); - - pi = PackageParser.generatePackageInfoFromApex(apexFile, true); - assertEquals("com.google.android.tzdata", pi.applicationInfo.packageName); - assertTrue(pi.applicationInfo.enabled); - assertEquals(28, pi.applicationInfo.targetSdkVersion); - assertEquals(1, pi.applicationInfo.longVersionCode); - - assertEquals("com.google.android.tzdata", pi.packageName); - assertTrue(pi.splitNames.length > 0); - assertEquals(1, pi.getLongVersionCode()); + assertEquals(191000070, pi.getLongVersionCode()); assertNotNull(pi.signingInfo); - assertNotNull(pi.signatures); assertTrue(pi.signingInfo.getApkContentsSigners().length > 0); assertTrue(pi.isApex); } diff --git a/core/tests/coretests/src/android/database/TranslatingCursorTest.java b/core/tests/coretests/src/android/database/TranslatingCursorTest.java new file mode 100644 index 000000000000..baca7ef24259 --- /dev/null +++ b/core/tests/coretests/src/android/database/TranslatingCursorTest.java @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.database; + +import static com.google.common.truth.Truth.assertThat; + +import android.database.TranslatingCursor.Translator; +import android.net.Uri; + +import junit.framework.TestCase; + +public class TranslatingCursorTest extends TestCase { + + public void testDuplicateColumnName() { + MatrixCursor base = new MatrixCursor(new String[] {"_id", "colA", "colB", "colA"}); + base.addRow(new Object[] { 0, "r1_a", "r1_b", "r1_a"}); + base.addRow(new Object[] { 1, "r2_a", "r2_b", "r2_a"}); + Translator translator = (data, idIndex, matchingColumn, cursor) -> data.toUpperCase(); + TranslatingCursor.Config config = new TranslatingCursor.Config(Uri.EMPTY, "_id", "colA"); + TranslatingCursor translating = new TranslatingCursor(base, config, translator, false); + + translating.moveToNext(); + String[] expected = new String[] { "ignored", "R1_A", "r1_b", "R1_A" }; + for (int i = 1; i < translating.getColumnCount(); i++) { + assertThat(translating.getString(i)).isEqualTo(expected[i]); + } + translating.moveToNext(); + expected = new String[] { "ignored", "R2_A", "r2_b", "R2_A" }; + for (int i = 1; i < translating.getColumnCount(); i++) { + assertThat(translating.getString(i)).isEqualTo(expected[i]); + } + } + +} diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java index 80250db581d4..c36ca829bb50 100644 --- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java +++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java @@ -131,7 +131,6 @@ public class SettingsBackupTest { Settings.Global.AUTOFILL_MAX_VISIBLE_DATASETS, Settings.Global.AUTOMATIC_POWER_SAVE_MODE, Settings.Global.BACKGROUND_ACTIVITY_STARTS_ENABLED, - Settings.Global.BACKGROUND_ACTIVITY_STARTS_PACKAGE_NAMES_WHITELIST, Settings.Global.BATTERY_CHARGING_STATE_UPDATE_DELAY, Settings.Global.BROADCAST_BG_CONSTANTS, Settings.Global.BROADCAST_FG_CONSTANTS, @@ -488,6 +487,7 @@ public class SettingsBackupTest { Settings.Global.GPU_DEBUG_APP, Settings.Global.GPU_DEBUG_LAYERS, Settings.Global.GPU_DEBUG_LAYERS_GLES, + Settings.Global.GLOBAL_SETTINGS_ANGLE_DEBUG_PACKAGE, Settings.Global.GLOBAL_SETTINGS_ANGLE_GL_DRIVER_ALL_ANGLE, Settings.Global.GLOBAL_SETTINGS_ANGLE_GL_DRIVER_SELECTION_PKGS, Settings.Global.GLOBAL_SETTINGS_ANGLE_GL_DRIVER_SELECTION_VALUES, @@ -610,7 +610,6 @@ public class SettingsBackupTest { Settings.Secure.BACKUP_ENABLED, Settings.Secure.BACKUP_PROVISIONED, Settings.Secure.BACKUP_TRANSPORT, - Settings.Secure.CALL_REDIRECTION_DEFAULT_APPLICATION, Settings.Secure.CALL_SCREENING_DEFAULT_COMPONENT, Settings.Secure.CAMERA_LIFT_TRIGGER_ENABLED, // Candidate for backup? Settings.Secure.CARRIER_APPS_HANDLED, diff --git a/core/tests/coretests/src/android/view/ViewGroupTest.java b/core/tests/coretests/src/android/view/ViewGroupTest.java new file mode 100644 index 000000000000..979a839d2ffe --- /dev/null +++ b/core/tests/coretests/src/android/view/ViewGroupTest.java @@ -0,0 +1,133 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.view; + +import static androidx.test.InstrumentationRegistry.getContext; + +import static org.junit.Assert.assertEquals; + +import android.content.Context; +import android.graphics.Region; +import android.platform.test.annotations.Presubmit; + +import androidx.test.filters.SmallTest; + +import org.junit.Test; + + +/** + * Test basic functions of ViewGroup. + * + * Build/Install/Run: + * atest FrameworksCoreTests:ViewGroupTest + */ +@Presubmit +@SmallTest +public class ViewGroupTest { + + /** + * Test if {@link ViewGroup#subtractObscuredTouchableRegion} works as expected. + * + * The view hierarchy: + * A---B---C + * \ \ + * \ --D + * \ + * E---F + * + * The layer and bounds of each view: + * F -- (invisible) + * E -- + * D ---- + * C ---------- + * B ------ + * A -------- + */ + @Test + public void testSubtractObscuredTouchableRegion() { + final Context context = getContext(); + final TestView viewA = new TestView(context, 8 /* right */); + final TestView viewB = new TestView(context, 6 /* right */); + final TestView viewC = new TestView(context, 10 /* right */); + final TestView viewD = new TestView(context, 4 /* right */); + final TestView viewE = new TestView(context, 2 /* right */); + final TestView viewF = new TestView(context, 2 /* right */); + + viewA.addView(viewB); + viewA.addView(viewE); + viewB.addView(viewC); + viewB.addView(viewD); + viewE.addView(viewF); + + viewF.setVisibility(View.INVISIBLE); + + final Region r = new Region(); + + getUnobscuredTouchableRegion(r, viewA); + assertRegionContainPoint(1 /* x */, r, true /* contain */); + assertRegionContainPoint(3 /* x */, r, true /* contain */); + assertRegionContainPoint(5 /* x */, r, true /* contain */); + assertRegionContainPoint(7 /* x */, r, true /* contain */); + assertRegionContainPoint(9 /* x */, r, false /* contain */); // Outside of bounds + + getUnobscuredTouchableRegion(r, viewB); + assertRegionContainPoint(1 /* x */, r, false /* contain */); // Obscured by E + assertRegionContainPoint(3 /* x */, r, true /* contain */); + assertRegionContainPoint(5 /* x */, r, true /* contain */); + assertRegionContainPoint(7 /* x */, r, false /* contain */); // Outside of bounds + + getUnobscuredTouchableRegion(r, viewC); + assertRegionContainPoint(1 /* x */, r, false /* contain */); // Obscured by D and E + assertRegionContainPoint(3 /* x */, r, false /* contain */); // Obscured by D + assertRegionContainPoint(5 /* x */, r, true /* contain */); + assertRegionContainPoint(7 /* x */, r, false /* contain */); // Outside of parent bounds + + getUnobscuredTouchableRegion(r, viewD); + assertRegionContainPoint(1 /* x */, r, false /* contain */); // Obscured by E + assertRegionContainPoint(3 /* x */, r, true /* contain */); + assertRegionContainPoint(5 /* x */, r, false /* contain */); // Outside of bounds + + getUnobscuredTouchableRegion(r, viewE); + assertRegionContainPoint(1 /* x */, r, true /* contain */); + assertRegionContainPoint(3 /* x */, r, false /* contain */); // Outside of bounds + } + + private static void getUnobscuredTouchableRegion(Region outRegion, View view) { + outRegion.set(view.getLeft(), view.getTop(), view.getRight(), view.getBottom()); + final ViewParent parent = view.getParent(); + if (parent != null) { + parent.subtractObscuredTouchableRegion(outRegion, view); + } + } + + private static void assertRegionContainPoint(int x, Region region, boolean contain) { + assertEquals(String.format("Touchable region must%s contain (%s, 0).", + (contain ? "" : " not"), x), contain, region.contains(x, 0 /* y */)); + } + + private static class TestView extends ViewGroup { + TestView(Context context, int right) { + super(context); + setFrame(0 /* left */, 0 /* top */, right, 1 /* bottom */); + } + + @Override + protected void onLayout(boolean changed, int l, int t, int r, int b) { + // We don't layout this view. + } + } +} diff --git a/core/tests/coretests/src/android/view/contentcapture/ContentCaptureEventTest.java b/core/tests/coretests/src/android/view/contentcapture/ContentCaptureEventTest.java index 2416de1b7d36..2008537c040a 100644 --- a/core/tests/coretests/src/android/view/contentcapture/ContentCaptureEventTest.java +++ b/core/tests/coretests/src/android/view/contentcapture/ContentCaptureEventTest.java @@ -49,13 +49,15 @@ public class ContentCaptureEventTest { private static final LocusId ID = new LocusId("WHATEVER"); + private static final int NO_SESSION_ID = 0; + // Not using @Mock because it's final - no need to be fancy here.... private final ContentCaptureContext mClientContext = new ContentCaptureContext.Builder(ID).build(); @Test public void testSetAutofillId_null() { - final ContentCaptureEvent event = new ContentCaptureEvent("42", TYPE_VIEW_DISAPPEARED); + final ContentCaptureEvent event = new ContentCaptureEvent(42, TYPE_VIEW_DISAPPEARED); assertThrows(NullPointerException.class, () -> event.setAutofillId(null)); assertThat(event.getId()).isNull(); @@ -64,7 +66,7 @@ public class ContentCaptureEventTest { @Test public void testSetAutofillIds_null() { - final ContentCaptureEvent event = new ContentCaptureEvent("42", TYPE_VIEW_DISAPPEARED); + final ContentCaptureEvent event = new ContentCaptureEvent(42, TYPE_VIEW_DISAPPEARED); assertThrows(NullPointerException.class, () -> event.setAutofillIds(null)); assertThat(event.getId()).isNull(); @@ -73,7 +75,7 @@ public class ContentCaptureEventTest { @Test public void testAddAutofillId_null() { - final ContentCaptureEvent event = new ContentCaptureEvent("42", TYPE_VIEW_DISAPPEARED); + final ContentCaptureEvent event = new ContentCaptureEvent(42, TYPE_VIEW_DISAPPEARED); assertThrows(NullPointerException.class, () -> event.addAutofillId(null)); assertThat(event.getId()).isNull(); @@ -82,7 +84,7 @@ public class ContentCaptureEventTest { @Test public void testSetAutofillId() { - final ContentCaptureEvent event = new ContentCaptureEvent("42", TYPE_VIEW_DISAPPEARED); + final ContentCaptureEvent event = new ContentCaptureEvent(42, TYPE_VIEW_DISAPPEARED); final AutofillId id = new AutofillId(108); event.setAutofillId(id); @@ -92,7 +94,7 @@ public class ContentCaptureEventTest { @Test public void testSetAutofillIds() { - final ContentCaptureEvent event = new ContentCaptureEvent("42", TYPE_VIEW_DISAPPEARED); + final ContentCaptureEvent event = new ContentCaptureEvent(42, TYPE_VIEW_DISAPPEARED); final AutofillId id = new AutofillId(108); final ArrayList<AutofillId> ids = new ArrayList<>(1); @@ -104,7 +106,7 @@ public class ContentCaptureEventTest { @Test public void testAddAutofillId() { - final ContentCaptureEvent event = new ContentCaptureEvent("42", TYPE_VIEW_DISAPPEARED); + final ContentCaptureEvent event = new ContentCaptureEvent(42, TYPE_VIEW_DISAPPEARED); final AutofillId id1 = new AutofillId(108); event.addAutofillId(id1); @@ -119,7 +121,7 @@ public class ContentCaptureEventTest { @Test public void testAddAutofillId_afterSetId() { - final ContentCaptureEvent event = new ContentCaptureEvent("42", TYPE_VIEW_DISAPPEARED); + final ContentCaptureEvent event = new ContentCaptureEvent(42, TYPE_VIEW_DISAPPEARED); final AutofillId id1 = new AutofillId(108); event.setAutofillId(id1); @@ -134,7 +136,7 @@ public class ContentCaptureEventTest { @Test public void testAddAutofillId_afterSetIds() { - final ContentCaptureEvent event = new ContentCaptureEvent("42", TYPE_VIEW_DISAPPEARED); + final ContentCaptureEvent event = new ContentCaptureEvent(42, TYPE_VIEW_DISAPPEARED); final AutofillId id1 = new AutofillId(108); final ArrayList<AutofillId> ids = new ArrayList<>(1); @@ -163,9 +165,9 @@ public class ContentCaptureEventTest { } private ContentCaptureEvent newEventForSessionStarted() { - final ContentCaptureEvent event = new ContentCaptureEvent("42", TYPE_SESSION_STARTED) + final ContentCaptureEvent event = new ContentCaptureEvent(42, TYPE_SESSION_STARTED) .setClientContext(mClientContext) - .setParentSessionId("108"); + .setParentSessionId(108); assertThat(event).isNotNull(); return event; } @@ -173,8 +175,8 @@ public class ContentCaptureEventTest { private void assertSessionStartedEvent(ContentCaptureEvent event) { assertThat(event.getType()).isEqualTo(TYPE_SESSION_STARTED); assertThat(event.getEventTime()).isAtLeast(MY_EPOCH); - assertThat(event.getSessionId()).isEqualTo("42"); - assertThat(event.getParentSessionId()).isEqualTo("108"); + assertThat(event.getSessionId()).isEqualTo(42); + assertThat(event.getParentSessionId()).isEqualTo(108); assertThat(event.getId()).isNull(); assertThat(event.getIds()).isNull(); assertThat(event.getText()).isNull(); @@ -186,17 +188,17 @@ public class ContentCaptureEventTest { @Test public void testSessionFinished_directly() { - final ContentCaptureEvent event = new ContentCaptureEvent("42", TYPE_SESSION_FINISHED) - .setParentSessionId("108"); + final ContentCaptureEvent event = new ContentCaptureEvent(42, TYPE_SESSION_FINISHED) + .setParentSessionId(108); assertThat(event).isNotNull(); assertSessionFinishedEvent(event); } @Test public void testSessionFinished_throughParcel() { - final ContentCaptureEvent event = new ContentCaptureEvent("42", TYPE_SESSION_FINISHED) + final ContentCaptureEvent event = new ContentCaptureEvent(42, TYPE_SESSION_FINISHED) .setClientContext(mClientContext) // should not be writting to parcel - .setParentSessionId("108"); + .setParentSessionId(108); assertThat(event).isNotNull(); final ContentCaptureEvent clone = cloneThroughParcel(event); assertSessionFinishedEvent(clone); @@ -205,8 +207,8 @@ public class ContentCaptureEventTest { private void assertSessionFinishedEvent(ContentCaptureEvent event) { assertThat(event.getType()).isEqualTo(TYPE_SESSION_FINISHED); assertThat(event.getEventTime()).isAtLeast(MY_EPOCH); - assertThat(event.getSessionId()).isEqualTo("42"); - assertThat(event.getParentSessionId()).isEqualTo("108"); + assertThat(event.getSessionId()).isEqualTo(42); + assertThat(event.getParentSessionId()).isEqualTo(108); assertThat(event.getId()).isNull(); assertThat(event.getIds()).isNull(); assertThat(event.getText()).isNull(); @@ -216,7 +218,7 @@ public class ContentCaptureEventTest { @Test public void testContextUpdated_directly() { - final ContentCaptureEvent event = new ContentCaptureEvent("42", TYPE_CONTEXT_UPDATED) + final ContentCaptureEvent event = new ContentCaptureEvent(42, TYPE_CONTEXT_UPDATED) .setClientContext(mClientContext); assertThat(event).isNotNull(); assertContextUpdatedEvent(event); @@ -224,7 +226,7 @@ public class ContentCaptureEventTest { @Test public void testContextUpdated_throughParcel() { - final ContentCaptureEvent event = new ContentCaptureEvent("42", TYPE_CONTEXT_UPDATED) + final ContentCaptureEvent event = new ContentCaptureEvent(42, TYPE_CONTEXT_UPDATED) .setClientContext(mClientContext); assertThat(event).isNotNull(); final ContentCaptureEvent clone = cloneThroughParcel(event); @@ -233,9 +235,9 @@ public class ContentCaptureEventTest { @Test public void testMergeEvent_typeViewTextChanged() { - final ContentCaptureEvent event = new ContentCaptureEvent("42", TYPE_VIEW_TEXT_CHANGED) + final ContentCaptureEvent event = new ContentCaptureEvent(42, TYPE_VIEW_TEXT_CHANGED) .setText("test"); - final ContentCaptureEvent event2 = new ContentCaptureEvent("43", TYPE_VIEW_TEXT_CHANGED) + final ContentCaptureEvent event2 = new ContentCaptureEvent(43, TYPE_VIEW_TEXT_CHANGED) .setText("empty"); event.mergeEvent(event2); @@ -244,14 +246,14 @@ public class ContentCaptureEventTest { @Test public void testMergeEvent_typeViewDisappeared() { - final ContentCaptureEvent event = new ContentCaptureEvent("42", TYPE_VIEW_DISAPPEARED) + final ContentCaptureEvent event = new ContentCaptureEvent(42, TYPE_VIEW_DISAPPEARED) .setAutofillId(new AutofillId(1)); - final ContentCaptureEvent event2 = new ContentCaptureEvent("43", TYPE_VIEW_DISAPPEARED) + final ContentCaptureEvent event2 = new ContentCaptureEvent(43, TYPE_VIEW_DISAPPEARED) .setAutofillId(new AutofillId(2)); final ArrayList<AutofillId> autofillIds = new ArrayList<>(); autofillIds.add(new AutofillId(3)); autofillIds.add(new AutofillId(4)); - final ContentCaptureEvent event3 = new ContentCaptureEvent("17", TYPE_VIEW_DISAPPEARED) + final ContentCaptureEvent event3 = new ContentCaptureEvent(17, TYPE_VIEW_DISAPPEARED) .setAutofillIds(autofillIds); event.mergeEvent(event2); @@ -264,24 +266,24 @@ public class ContentCaptureEventTest { @Test public void testMergeEvent_typeViewDisappeared_noIds() { - final ContentCaptureEvent event = new ContentCaptureEvent("42", TYPE_VIEW_DISAPPEARED) + final ContentCaptureEvent event = new ContentCaptureEvent(42, TYPE_VIEW_DISAPPEARED) .setAutofillId(new AutofillId(1)); - final ContentCaptureEvent event2 = new ContentCaptureEvent("43", TYPE_VIEW_DISAPPEARED); + final ContentCaptureEvent event2 = new ContentCaptureEvent(43, TYPE_VIEW_DISAPPEARED); assertThrows(IllegalArgumentException.class, () -> event.mergeEvent(event2)); } @Test public void testMergeEvent_nullArgument() { - final ContentCaptureEvent event = new ContentCaptureEvent("42", TYPE_VIEW_DISAPPEARED); + final ContentCaptureEvent event = new ContentCaptureEvent(42, TYPE_VIEW_DISAPPEARED); assertThrows(NullPointerException.class, () -> event.mergeEvent(null)); } @Test public void testMergeEvent_differentEventTypes() { - final ContentCaptureEvent event = new ContentCaptureEvent("42", TYPE_VIEW_DISAPPEARED) + final ContentCaptureEvent event = new ContentCaptureEvent(42, TYPE_VIEW_DISAPPEARED) .setText("test").setAutofillId(new AutofillId(1)); - final ContentCaptureEvent event2 = new ContentCaptureEvent("17", TYPE_VIEW_TEXT_CHANGED) + final ContentCaptureEvent event2 = new ContentCaptureEvent(17, TYPE_VIEW_TEXT_CHANGED) .setText("empty").setAutofillId(new AutofillId(2)); event.mergeEvent(event2); @@ -296,8 +298,8 @@ public class ContentCaptureEventTest { private void assertContextUpdatedEvent(ContentCaptureEvent event) { assertThat(event.getType()).isEqualTo(TYPE_CONTEXT_UPDATED); assertThat(event.getEventTime()).isAtLeast(MY_EPOCH); - assertThat(event.getSessionId()).isEqualTo("42"); - assertThat(event.getParentSessionId()).isNull(); + assertThat(event.getSessionId()).isEqualTo(42); + assertThat(event.getParentSessionId()).isEqualTo(NO_SESSION_ID); assertThat(event.getId()).isNull(); assertThat(event.getIds()).isNull(); assertThat(event.getText()).isNull(); diff --git a/core/tests/coretests/src/android/view/contentcapture/ContentCaptureSessionTest.java b/core/tests/coretests/src/android/view/contentcapture/ContentCaptureSessionTest.java index 013408e0bd12..81ce15a4d8d2 100644 --- a/core/tests/coretests/src/android/view/contentcapture/ContentCaptureSessionTest.java +++ b/core/tests/coretests/src/android/view/contentcapture/ContentCaptureSessionTest.java @@ -39,9 +39,9 @@ import org.mockito.junit.MockitoJUnitRunner; @RunWith(MockitoJUnitRunner.class) public class ContentCaptureSessionTest { - private ContentCaptureSession mSession1 = new MyContentCaptureSession("111"); + private ContentCaptureSession mSession1 = new MyContentCaptureSession(111); - private ContentCaptureSession mSession2 = new MyContentCaptureSession("2222"); + private ContentCaptureSession mSession2 = new MyContentCaptureSession(2222); @Mock private View mMockView; @@ -60,12 +60,12 @@ public class ContentCaptureSessionTest { assertThat(childId.getViewId()).isEqualTo(42); assertThat(childId.getVirtualChildLongId()).isEqualTo(108L); assertThat(childId.getVirtualChildIntId()).isEqualTo(View.NO_ID); - assertThat(childId.getSessionId()).isEqualTo(mSession1.getIdAsInt()); + assertThat(childId.getSessionId()).isEqualTo(mSession1.getId()); } @Test public void testNewAutofillId_differentSessions() { - assertThat(mSession1.getIdAsInt()).isNotSameAs(mSession2.getIdAsInt()); //sanity check + assertThat(mSession1.getId()).isNotEqualTo(mSession2.getId()); //sanity check final AutofillId parentId = new AutofillId(42); final AutofillId childId1 = mSession1.newAutofillId(parentId, 108L); final AutofillId childId2 = mSession2.newAutofillId(parentId, 108L); @@ -117,7 +117,7 @@ public class ContentCaptureSessionTest { // Cannot use @Spy because we need to pass the session id on constructor private class MyContentCaptureSession extends ContentCaptureSession { - private MyContentCaptureSession(String id) { + private MyContentCaptureSession(int id) { super(id); } diff --git a/core/tests/coretests/src/android/view/textclassifier/ConfigParserTest.java b/core/tests/coretests/src/android/view/textclassifier/ConfigParserTest.java index 1b3c72452339..f1cfe24762a8 100644 --- a/core/tests/coretests/src/android/view/textclassifier/ConfigParserTest.java +++ b/core/tests/coretests/src/android/view/textclassifier/ConfigParserTest.java @@ -26,6 +26,7 @@ import androidx.test.runner.AndroidJUnit4; import org.junit.After; import org.junit.Before; +import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; @@ -58,6 +59,7 @@ public class ConfigParserTest { } @Test + @Ignore // TODO: Re-enable once ConfigParser#ENABLE_DEVICE_CONFIG is finalized public void getBoolean_deviceConfig() { DeviceConfig.setProperty( DeviceConfig.NAMESPACE_TEXTCLASSIFIER, @@ -77,6 +79,7 @@ public class ConfigParserTest { } @Test + @Ignore // TODO: Re-enable once ConfigParser#ENABLE_DEVICE_CONFIG is finalized public void getInt_deviceConfig() { DeviceConfig.setProperty( DeviceConfig.NAMESPACE_TEXTCLASSIFIER, @@ -94,6 +97,7 @@ public class ConfigParserTest { } @Test + @Ignore // TODO: Re-enable once ConfigParser#ENABLE_DEVICE_CONFIG is finalized public void getFloat_deviceConfig() { DeviceConfig.setProperty( DeviceConfig.NAMESPACE_TEXTCLASSIFIER, @@ -111,6 +115,7 @@ public class ConfigParserTest { } @Test + @Ignore // TODO: Re-enable once ConfigParser#ENABLE_DEVICE_CONFIG is finalized public void getString_deviceConfig() { DeviceConfig.setProperty( DeviceConfig.NAMESPACE_TEXTCLASSIFIER, 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/core/tests/coretests/src/com/android/internal/os/KernelCpuThreadReaderDiffTest.java b/core/tests/coretests/src/com/android/internal/os/KernelCpuThreadReaderDiffTest.java new file mode 100644 index 000000000000..460fe47966ea --- /dev/null +++ b/core/tests/coretests/src/com/android/internal/os/KernelCpuThreadReaderDiffTest.java @@ -0,0 +1,242 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.internal.os; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.Mockito.mockitoSession; +import static org.mockito.Mockito.when; +import static org.testng.Assert.assertThrows; + +import static java.util.stream.Collectors.toList; + +import android.platform.test.annotations.Presubmit; + +import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.filters.SmallTest; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoSession; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; + +@Presubmit +@SmallTest +@RunWith(AndroidJUnit4.class) +public class KernelCpuThreadReaderDiffTest { + + private MockitoSession mMockingSessions; + @Mock KernelCpuThreadReader mMockReader; + + @Before + public void setUp() { + mMockingSessions = mockitoSession().initMocks(this).startMocking(); + } + + @After + public void tearDown() { + if (mMockingSessions != null) { + mMockingSessions.finishMocking(); + } + } + + @Test + public void test_empty() { + KernelCpuThreadReaderDiff kernelCpuThreadReaderDiff = + new KernelCpuThreadReaderDiff(mMockReader, 0); + assertThat(kernelCpuThreadReaderDiff.getProcessCpuUsageDiffed()).isNull(); + assertThat(kernelCpuThreadReaderDiff.getProcessCpuUsageDiffed()).isEmpty(); + } + + @Test + public void test_simple() { + when(mMockReader.getProcessCpuUsage()) + .thenReturn(createProcess(new int[] {100, 100, 100})) + .thenReturn(createProcess(new int[] {150, 160, 170})); + KernelCpuThreadReaderDiff kernelCpuThreadReaderDiff = + new KernelCpuThreadReaderDiff(mMockReader, 0); + assertThat(kernelCpuThreadReaderDiff.getProcessCpuUsageDiffed()).isNull(); + assertThat(cpuUsages(kernelCpuThreadReaderDiff.getProcessCpuUsageDiffed())) + .containsExactly(Arrays.asList(50, 60, 70)); + } + + @Test + public void test_failure() { + when(mMockReader.getProcessCpuUsage()) + .thenReturn(createProcess(new int[] {1})) + .thenReturn(createProcess(new int[] {2})) + .thenThrow(new RuntimeException()) + .thenReturn(createProcess(new int[] {4})) + .thenReturn(createProcess(new int[] {6})); + KernelCpuThreadReaderDiff kernelCpuThreadReaderDiff = + new KernelCpuThreadReaderDiff(mMockReader, 0); + assertThat(kernelCpuThreadReaderDiff.getProcessCpuUsageDiffed()).isNull(); + assertThat(cpuUsages(kernelCpuThreadReaderDiff.getProcessCpuUsageDiffed())) + .containsExactly(Collections.singletonList(1)); + assertThrows( + RuntimeException.class, + () -> cpuUsages(kernelCpuThreadReaderDiff.getProcessCpuUsageDiffed())); + assertThat(kernelCpuThreadReaderDiff.getProcessCpuUsageDiffed()).isNull(); + assertThat(cpuUsages(kernelCpuThreadReaderDiff.getProcessCpuUsageDiffed())) + .containsExactly(Collections.singletonList(2)); + } + + @Test + public void test_twoFailures() { + when(mMockReader.getProcessCpuUsage()) + .thenReturn(createProcess(new int[] {1})) + .thenReturn(createProcess(new int[] {2})) + .thenThrow(new RuntimeException()) + .thenThrow(new RuntimeException()) + .thenReturn(createProcess(new int[] {4})) + .thenReturn(createProcess(new int[] {6})); + KernelCpuThreadReaderDiff kernelCpuThreadReaderDiff = + new KernelCpuThreadReaderDiff(mMockReader, 0); + assertThat(kernelCpuThreadReaderDiff.getProcessCpuUsageDiffed()).isNull(); + assertThat(cpuUsages(kernelCpuThreadReaderDiff.getProcessCpuUsageDiffed())) + .containsExactly(Collections.singletonList(1)); + assertThrows( + RuntimeException.class, + () -> cpuUsages(kernelCpuThreadReaderDiff.getProcessCpuUsageDiffed())); + assertThrows( + RuntimeException.class, + () -> cpuUsages(kernelCpuThreadReaderDiff.getProcessCpuUsageDiffed())); + assertThat(kernelCpuThreadReaderDiff.getProcessCpuUsageDiffed()).isNull(); + assertThat(cpuUsages(kernelCpuThreadReaderDiff.getProcessCpuUsageDiffed())) + .containsExactly(Collections.singletonList(2)); + } + + @Test + public void test_negativeDiff() { + when(mMockReader.getProcessCpuUsage()) + .thenReturn(createProcess(new int[] {2})) + .thenReturn(createProcess(new int[] {1})); + KernelCpuThreadReaderDiff kernelCpuThreadReaderDiff = + new KernelCpuThreadReaderDiff(mMockReader, 0); + assertThat(kernelCpuThreadReaderDiff.getProcessCpuUsageDiffed()).isNull(); + assertThat(cpuUsages(kernelCpuThreadReaderDiff.getProcessCpuUsageDiffed())) + .containsExactly(Collections.singletonList(-1)); + } + + @Test + public void test_threshold() { + when(mMockReader.getProcessCpuUsage()) + .thenReturn(createProcess(new int[] {1})) + .thenReturn(createProcess(new int[] {10})) + .thenReturn(createProcess(new int[] {12})) + .thenReturn(createProcess(new int[] {20})); + KernelCpuThreadReaderDiff kernelCpuThreadReaderDiff = + new KernelCpuThreadReaderDiff(mMockReader, 5); + assertThat(kernelCpuThreadReaderDiff.getProcessCpuUsageDiffed()).isNull(); + + ArrayList<KernelCpuThreadReader.ProcessCpuUsage> processes1 = + kernelCpuThreadReaderDiff.getProcessCpuUsageDiffed(); + assertThat(cpuUsages(processes1)).containsExactly(Collections.singletonList(9)); + assertThat(threadNames(processes1)).containsExactly("thread0"); + + ArrayList<KernelCpuThreadReader.ProcessCpuUsage> processes2 = + kernelCpuThreadReaderDiff.getProcessCpuUsageDiffed(); + assertThat(cpuUsages(processes2)).containsExactly(Collections.singletonList(2)); + assertThat(threadNames(processes2)).containsExactly("__OTHER_THREADS"); + + ArrayList<KernelCpuThreadReader.ProcessCpuUsage> processes3 = + kernelCpuThreadReaderDiff.getProcessCpuUsageDiffed(); + assertThat(cpuUsages(processes3)).containsExactly(Collections.singletonList(8)); + assertThat(threadNames(processes3)).containsExactly("thread0"); + } + + @Test + public void test_newThread() { + when(mMockReader.getProcessCpuUsage()) + .thenReturn(createProcess(new int[] {1})) + .thenReturn(createProcess(new int[] {2})) + .thenReturn(createProcess(new int[] {4}, new int[] {5})); + KernelCpuThreadReaderDiff kernelCpuThreadReaderDiff = + new KernelCpuThreadReaderDiff(mMockReader, 0); + assertThat(kernelCpuThreadReaderDiff.getProcessCpuUsageDiffed()).isNull(); + + ArrayList<KernelCpuThreadReader.ProcessCpuUsage> processes1 = + kernelCpuThreadReaderDiff.getProcessCpuUsageDiffed(); + assertThat(cpuUsages(processes1)).containsExactly(Collections.singletonList(1)); + assertThat(threadNames(processes1)).containsExactly("thread0"); + + ArrayList<KernelCpuThreadReader.ProcessCpuUsage> processes2 = + kernelCpuThreadReaderDiff.getProcessCpuUsageDiffed(); + assertThat(cpuUsages(processes2)) + .containsExactly(Collections.singletonList(2), Collections.singletonList(5)); + assertThat(threadNames(processes2)).containsExactly("thread0", "thread1"); + } + + @Test + public void test_stoppedThread() { + when(mMockReader.getProcessCpuUsage()) + .thenReturn(createProcess(new int[] {1}, new int[] {1})) + .thenReturn(createProcess(new int[] {2}, new int[] {3})) + .thenReturn(createProcess(new int[] {4})); + KernelCpuThreadReaderDiff kernelCpuThreadReaderDiff = + new KernelCpuThreadReaderDiff(mMockReader, 0); + assertThat(kernelCpuThreadReaderDiff.getProcessCpuUsageDiffed()).isNull(); + + ArrayList<KernelCpuThreadReader.ProcessCpuUsage> processes1 = + kernelCpuThreadReaderDiff.getProcessCpuUsageDiffed(); + assertThat(cpuUsages(processes1)) + .containsExactly(Collections.singletonList(1), Collections.singletonList(2)); + assertThat(threadNames(processes1)).containsExactly("thread0", "thread1"); + + ArrayList<KernelCpuThreadReader.ProcessCpuUsage> processes2 = + kernelCpuThreadReaderDiff.getProcessCpuUsageDiffed(); + assertThat(cpuUsages(processes2)).containsExactly(Collections.singletonList(2)); + assertThat(threadNames(processes2)).containsExactly("thread0"); + } + + private ArrayList<KernelCpuThreadReader.ProcessCpuUsage> createProcess( + int[]... cpuUsageMillis) { + ArrayList<KernelCpuThreadReader.ThreadCpuUsage> threadCpuUsages = new ArrayList<>(); + for (int i = 0; i < cpuUsageMillis.length; i++) { + int[] cpuUsage = cpuUsageMillis[i]; + threadCpuUsages.add( + new KernelCpuThreadReader.ThreadCpuUsage(0, "thread" + i, cpuUsage)); + } + return new ArrayList<>( + Collections.singletonList( + new KernelCpuThreadReader.ProcessCpuUsage( + 0, "process", 0, threadCpuUsages))); + } + + private Collection<Collection<Integer>> cpuUsages( + Collection<KernelCpuThreadReader.ProcessCpuUsage> processCpuUsages) { + return processCpuUsages.stream() + .flatMap(p -> p.threadCpuUsages.stream()) + .map(t -> Arrays.stream(t.usageTimesMillis).boxed().collect(toList())) + .collect(toList()); + } + + private Collection<String> threadNames( + Collection<KernelCpuThreadReader.ProcessCpuUsage> processCpuUsages) { + return processCpuUsages.stream() + .flatMap(p -> p.threadCpuUsages.stream()) + .map(t -> t.threadName) + .collect(toList()); + } +} diff --git a/core/tests/coretests/src/com/android/internal/os/KernelCpuThreadReaderEndToEndTest.java b/core/tests/coretests/src/com/android/internal/os/KernelCpuThreadReaderEndToEndTest.java index e9cad0acfcc6..d43989c06a72 100644 --- a/core/tests/coretests/src/com/android/internal/os/KernelCpuThreadReaderEndToEndTest.java +++ b/core/tests/coretests/src/com/android/internal/os/KernelCpuThreadReaderEndToEndTest.java @@ -125,7 +125,7 @@ public class KernelCpuThreadReaderEndToEndTest { // Get thread data from KernelCpuThreadReader final KernelCpuThreadReader kernelCpuThreadReader = - KernelCpuThreadReader.create(8, uid -> uid == Process.myUid(), 0); + KernelCpuThreadReader.create(8, uid -> uid == Process.myUid()); assertNotNull(kernelCpuThreadReader); kernelCpuThreadReader.setUidPredicate(uid -> uid == Process.myUid()); final Optional<ProcessCpuUsage> currentProcessCpuUsage = diff --git a/core/tests/coretests/src/com/android/internal/os/KernelCpuThreadReaderTest.java b/core/tests/coretests/src/com/android/internal/os/KernelCpuThreadReaderTest.java index 61209e21dda8..ae847c125633 100644 --- a/core/tests/coretests/src/com/android/internal/os/KernelCpuThreadReaderTest.java +++ b/core/tests/coretests/src/com/android/internal/os/KernelCpuThreadReaderTest.java @@ -84,7 +84,6 @@ public class KernelCpuThreadReaderTest { final KernelCpuThreadReader kernelCpuThreadReader = new KernelCpuThreadReader( 8, uidPredicate, - 0, mProcDirectory.toPath(), mProcDirectory.toPath().resolve(uids[0] + "/task/" + uids[0] + "/time_in_state"), processUtils); @@ -103,90 +102,6 @@ public class KernelCpuThreadReaderTest { } } - @Test - public void testReader_filtersLowUsage() throws IOException { - int[] uids = new int[]{0, 1, 2, 3, 4}; - int[] cpuUsage = new int[]{10, 0, 2, 100, 3}; - int[] expectedUids = new int[]{0, 3, 4}; - Predicate<Integer> uidPredicate = uid -> true; - KernelCpuThreadReader.Injector processUtils = - new KernelCpuThreadReader.Injector() { - @Override - public int getUidForPid(int pid) { - return pid; - } - }; - - for (int i = 0; i < uids.length; i++) { - int uid = uids[i]; - setupDirectory( - mProcDirectory.toPath().resolve(String.valueOf(uid)), - new int[]{uid * 10}, - "process" + uid, - new String[]{"thread" + uid}, - new int[]{1000}, - new int[][]{{cpuUsage[i]}}); - } - final KernelCpuThreadReader kernelCpuThreadReader = new KernelCpuThreadReader( - 8, - uidPredicate, - 30, - mProcDirectory.toPath(), - mProcDirectory.toPath().resolve(uids[0] + "/task/" + uids[0] + "/time_in_state"), - processUtils); - ArrayList<KernelCpuThreadReader.ProcessCpuUsage> processCpuUsageByUids = - kernelCpuThreadReader.getProcessCpuUsage(); - processCpuUsageByUids.sort(Comparator.comparing(usage -> usage.uid)); - - assertEquals(expectedUids.length, processCpuUsageByUids.size()); - for (int i = 0; i < expectedUids.length; i++) { - KernelCpuThreadReader.ProcessCpuUsage processCpuUsage = - processCpuUsageByUids.get(i); - assertEquals(expectedUids[i], processCpuUsage.uid); - } - - } - - @Test - public void testReader_otherThreads() throws IOException { - final Path processPath = mProcDirectory.toPath().resolve("1000"); - setupDirectory( - processPath, - new int[]{1, 2, 3}, - "process", - new String[]{"thread1", "thread2", "thread3"}, - new int[]{1000, 2000}, - new int[][]{{0, 100}, {10, 0}, {0, 300}}); - KernelCpuThreadReader.Injector injector = - new KernelCpuThreadReader.Injector() { - @Override - public int getUidForPid(int pid) { - return 0; - } - }; - final KernelCpuThreadReader kernelCpuThreadReader = - new KernelCpuThreadReader( - 8, - uid -> true, - 2000, - mProcDirectory.toPath(), - processPath.resolve("task/1/time_in_state"), - injector); - ArrayList<KernelCpuThreadReader.ProcessCpuUsage> processCpuUsages = - kernelCpuThreadReader.getProcessCpuUsage(); - assertEquals(1, processCpuUsages.size()); - checkResults( - processCpuUsages.get(0), - kernelCpuThreadReader.getCpuFrequenciesKhz(), - 0, - 1000, - new int[] {-1, 3}, - "process", - new String[] {"__OTHER_THREADS", "thread3"}, - new int[] {1000, 2000}, - new int[][] {{10, 100}, {0, 300}}); - } - private void setupDirectory(Path processPath, int[] threadIds, String processName, String[] threadNames, int[] cpuFrequencies, int[][] cpuTimes) throws IOException { // Make /proc/$PID diff --git a/core/tests/overlaytests/device/Android.mk b/core/tests/overlaytests/device/Android.mk index 563074903cfe..c6d2a51b5224 100644 --- a/core/tests/overlaytests/device/Android.mk +++ b/core/tests/overlaytests/device/Android.mk @@ -21,7 +21,7 @@ LOCAL_PACKAGE_NAME := OverlayDeviceTests LOCAL_PRIVATE_PLATFORM_APIS := true LOCAL_STATIC_JAVA_LIBRARIES := androidx.test.rules LOCAL_COMPATIBILITY_SUITE := device-tests -LOCAL_TARGET_REQUIRED_MODULES := \ +LOCAL_REQUIRED_MODULES := \ OverlayDeviceTests_AppOverlayOne \ OverlayDeviceTests_AppOverlayTwo \ OverlayDeviceTests_FrameworkOverlay diff --git a/core/xsd/Android.bp b/core/xsd/Android.bp index 81669eb290db..738f33076ac9 100644 --- a/core/xsd/Android.bp +++ b/core/xsd/Android.bp @@ -2,5 +2,5 @@ xsd_config { name: "permission", srcs: ["permission.xsd"], api_dir: "schema", - package_name: "com.android.xml.permission", + package_name: "com.android.xml.permission.configfile", } diff --git a/core/xsd/permission.xsd b/core/xsd/permission.xsd index d90863b2c716..2ef2d04d3b34 100644 --- a/core/xsd/permission.xsd +++ b/core/xsd/permission.xsd @@ -60,8 +60,6 @@ <xs:attribute name="uid" type="xs:int"/> </xs:complexType> <xs:complexType name="split-permission"> - <xs:attribute name="name" type="xs:string"/> - <xs:attribute name="targetSdk" type="xs:int"/> <xs:sequence> <xs:element name="library" maxOccurs="unbounded"> <xs:complexType> @@ -69,6 +67,8 @@ </xs:complexType> </xs:element> </xs:sequence> + <xs:attribute name="name" type="xs:string"/> + <xs:attribute name="targetSdk" type="xs:int"/> </xs:complexType> <xs:complexType name="library"> <xs:attribute name="name" type="xs:string"/> @@ -78,6 +78,7 @@ <xs:complexType name="feature"> <xs:attribute name="name" type="xs:string"/> <xs:attribute name="notLowRam" type="xs:string"/> + <xs:attribute name="version" type="xs:int"/> </xs:complexType> <xs:complexType name="unavailable-feature"> <xs:attribute name="name" type="xs:string"/> @@ -124,7 +125,6 @@ <xs:attribute name="package" type="xs:string"/> </xs:complexType> <xs:complexType name="privapp-permissions"> - <xs:attribute name="package" type="xs:string"/> <xs:sequence> <xs:element name="permission" maxOccurs="unbounded"> <xs:complexType> @@ -137,9 +137,9 @@ </xs:complexType> </xs:element> </xs:sequence> + <xs:attribute name="package" type="xs:string"/> </xs:complexType> <xs:complexType name="oem-permissions"> - <xs:attribute name="package" type="xs:string"/> <xs:sequence> <xs:element name="permission" maxOccurs="unbounded"> <xs:complexType> @@ -152,6 +152,7 @@ </xs:complexType> </xs:element> </xs:sequence> + <xs:attribute name="package" type="xs:string"/> </xs:complexType> <xs:complexType name="hidden-api-whitelisted-app"> <xs:attribute name="package" type="xs:string"/> diff --git a/core/xsd/schema/current.txt b/core/xsd/schema/current.txt index 82bb0feac089..c25bc146045b 100644 --- a/core/xsd/schema/current.txt +++ b/core/xsd/schema/current.txt @@ -1,5 +1,5 @@ // Signature format: 2.0 -package com.android.xml.permission { +package com.android.xml.permission.configfile { public class AllowAssociation { ctor public AllowAssociation(); @@ -97,8 +97,10 @@ package com.android.xml.permission { ctor public Feature(); method public String getName(); method public String getNotLowRam(); + method public int getVersion(); method public void setName(String); method public void setNotLowRam(String); + method public void setVersion(int); } public class Group { @@ -125,8 +127,8 @@ package com.android.xml.permission { public class OemPermissions { ctor public OemPermissions(); - method public java.util.List<com.android.xml.permission.OemPermissions.DenyPermission> getDenyPermission(); - method public java.util.List<com.android.xml.permission.OemPermissions.Permission> getPermission(); + method public java.util.List<com.android.xml.permission.configfile.OemPermissions.DenyPermission> getDenyPermission(); + method public java.util.List<com.android.xml.permission.configfile.OemPermissions.Permission> getPermission(); method public String get_package(); method public void set_package(String); } @@ -151,37 +153,37 @@ package com.android.xml.permission { public class Permissions { ctor public Permissions(); - method public java.util.List<com.android.xml.permission.AllowAssociation> getAllowAssociation(); - method public java.util.List<com.android.xml.permission.AllowIgnoreLocationSettings> getAllowIgnoreLocationSettings(); - method public java.util.List<com.android.xml.permission.AllowImplicitBroadcast> getAllowImplicitBroadcast(); - method public java.util.List<com.android.xml.permission.AllowInDataUsageSave> getAllowInDataUsageSave(); - method public java.util.List<com.android.xml.permission.AllowInPowerSave> getAllowInPowerSave(); - method public java.util.List<com.android.xml.permission.AllowInPowerSaveExceptIdle> getAllowInPowerSaveExceptIdle(); - method public java.util.List<com.android.xml.permission.AllowUnthrottledLocation> getAllowUnthrottledLocation(); - method public java.util.List<com.android.xml.permission.AppLink> getAppLink(); - method public java.util.List<com.android.xml.permission.AssignPermission> getAssignPermission(); - method public java.util.List<com.android.xml.permission.BackupTransportWhitelistedService> getBackupTransportWhitelistedService(); - method public java.util.List<com.android.xml.permission.BugreportWhitelisted> getBugreportWhitelisted(); - method public java.util.List<com.android.xml.permission.DefaultEnabledVrApp> getDefaultEnabledVrApp(); - method public java.util.List<com.android.xml.permission.DisabledUntilUsedPreinstalledCarrierApp> getDisabledUntilUsedPreinstalledCarrierApp(); - method public java.util.List<com.android.xml.permission.DisabledUntilUsedPreinstalledCarrierAssociatedApp> getDisabledUntilUsedPreinstalledCarrierAssociatedApp(); - method public java.util.List<com.android.xml.permission.Feature> getFeature(); - method public java.util.List<com.android.xml.permission.Group> getGroup(); - method public java.util.List<com.android.xml.permission.HiddenApiWhitelistedApp> getHiddenApiWhitelistedApp(); - method public java.util.List<com.android.xml.permission.Library> getLibrary(); - method public java.util.List<com.android.xml.permission.OemPermissions> getOemPermissions(); - method public java.util.List<com.android.xml.permission.Permission> getPermission(); - method public java.util.List<com.android.xml.permission.PrivappPermissions> getPrivappPermissions(); - method public java.util.List<com.android.xml.permission.SplitPermission> getSplitPermission(); - method public java.util.List<com.android.xml.permission.SystemUserBlacklistedApp> getSystemUserBlacklistedApp(); - method public java.util.List<com.android.xml.permission.SystemUserWhitelistedApp> getSystemUserWhitelistedApp(); - method public java.util.List<com.android.xml.permission.UnavailableFeature> getUnavailableFeature(); + method public java.util.List<com.android.xml.permission.configfile.AllowAssociation> getAllowAssociation(); + method public java.util.List<com.android.xml.permission.configfile.AllowIgnoreLocationSettings> getAllowIgnoreLocationSettings(); + method public java.util.List<com.android.xml.permission.configfile.AllowImplicitBroadcast> getAllowImplicitBroadcast(); + method public java.util.List<com.android.xml.permission.configfile.AllowInDataUsageSave> getAllowInDataUsageSave(); + method public java.util.List<com.android.xml.permission.configfile.AllowInPowerSave> getAllowInPowerSave(); + method public java.util.List<com.android.xml.permission.configfile.AllowInPowerSaveExceptIdle> getAllowInPowerSaveExceptIdle(); + method public java.util.List<com.android.xml.permission.configfile.AllowUnthrottledLocation> getAllowUnthrottledLocation(); + method public java.util.List<com.android.xml.permission.configfile.AppLink> getAppLink(); + method public java.util.List<com.android.xml.permission.configfile.AssignPermission> getAssignPermission(); + method public java.util.List<com.android.xml.permission.configfile.BackupTransportWhitelistedService> getBackupTransportWhitelistedService(); + method public java.util.List<com.android.xml.permission.configfile.BugreportWhitelisted> getBugreportWhitelisted(); + method public java.util.List<com.android.xml.permission.configfile.DefaultEnabledVrApp> getDefaultEnabledVrApp(); + method public java.util.List<com.android.xml.permission.configfile.DisabledUntilUsedPreinstalledCarrierApp> getDisabledUntilUsedPreinstalledCarrierApp(); + method public java.util.List<com.android.xml.permission.configfile.DisabledUntilUsedPreinstalledCarrierAssociatedApp> getDisabledUntilUsedPreinstalledCarrierAssociatedApp(); + method public java.util.List<com.android.xml.permission.configfile.Feature> getFeature(); + method public java.util.List<com.android.xml.permission.configfile.Group> getGroup(); + method public java.util.List<com.android.xml.permission.configfile.HiddenApiWhitelistedApp> getHiddenApiWhitelistedApp(); + method public java.util.List<com.android.xml.permission.configfile.Library> getLibrary(); + method public java.util.List<com.android.xml.permission.configfile.OemPermissions> getOemPermissions(); + method public java.util.List<com.android.xml.permission.configfile.Permission> getPermission(); + method public java.util.List<com.android.xml.permission.configfile.PrivappPermissions> getPrivappPermissions(); + method public java.util.List<com.android.xml.permission.configfile.SplitPermission> getSplitPermission(); + method public java.util.List<com.android.xml.permission.configfile.SystemUserBlacklistedApp> getSystemUserBlacklistedApp(); + method public java.util.List<com.android.xml.permission.configfile.SystemUserWhitelistedApp> getSystemUserWhitelistedApp(); + method public java.util.List<com.android.xml.permission.configfile.UnavailableFeature> getUnavailableFeature(); } public class PrivappPermissions { ctor public PrivappPermissions(); - method public java.util.List<com.android.xml.permission.PrivappPermissions.DenyPermission> getDenyPermission(); - method public java.util.List<com.android.xml.permission.PrivappPermissions.Permission> getPermission(); + method public java.util.List<com.android.xml.permission.configfile.PrivappPermissions.DenyPermission> getDenyPermission(); + method public java.util.List<com.android.xml.permission.configfile.PrivappPermissions.Permission> getPermission(); method public String get_package(); method public void set_package(String); } @@ -200,7 +202,7 @@ package com.android.xml.permission { public class SplitPermission { ctor public SplitPermission(); - method public java.util.List<com.android.xml.permission.SplitPermission.Library> getLibrary(); + method public java.util.List<com.android.xml.permission.configfile.SplitPermission.Library> getLibrary(); method public String getName(); method public int getTargetSdk(); method public void setName(String); @@ -233,7 +235,7 @@ package com.android.xml.permission { public class XmlParser { ctor public XmlParser(); - method public static com.android.xml.permission.Permissions read(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException; + method public static com.android.xml.permission.configfile.Permissions read(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException; method public static String readText(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException; method public static void skip(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException; } diff --git a/data/etc/platform.xml b/data/etc/platform.xml index 28d311ec065d..0e957df4dc14 100644 --- a/data/etc/platform.xml +++ b/data/etc/platform.xml @@ -202,36 +202,6 @@ <new-permission name="android.permission.ACCESS_BACKGROUND_LOCATION" /> </split-permission> - <!-- STOPSHIP: change targetSdk to Q when SDK version finalised --> - <!-- Old apps might not understand the modern permission model, hence their view needs to be expanded --> - <split-permission name="android.permission.READ_EXTERNAL_STORAGE" - targetSdk="10000"> - <new-permission name="android.permission.READ_MEDIA_AUDIO" /> - <new-permission name="android.permission.READ_MEDIA_VIDEO" /> - <new-permission name="android.permission.READ_MEDIA_IMAGES" /> - </split-permission> - <!-- STOPSHIP: change targetSdk to Q when SDK version finalised --> - <split-permission name="android.permission.WRITE_EXTERNAL_STORAGE" - targetSdk="10000"> - <new-permission name="android.permission.READ_MEDIA_AUDIO" /> - <new-permission name="android.permission.READ_MEDIA_VIDEO" /> - <new-permission name="android.permission.READ_MEDIA_IMAGES" /> - </split-permission> - - <!-- An app using the typed media permissions might be grandfathered and then uses the old storage model --> - <split-permission name="android.permission.READ_MEDIA_AUDIO"> - <new-permission name="android.permission.READ_EXTERNAL_STORAGE" /> - <new-permission name="android.permission.WRITE_EXTERNAL_STORAGE" /> - </split-permission> - <split-permission name="android.permission.READ_MEDIA_VIDEO"> - <new-permission name="android.permission.READ_EXTERNAL_STORAGE" /> - <new-permission name="android.permission.WRITE_EXTERNAL_STORAGE" /> - </split-permission> - <split-permission name="android.permission.READ_MEDIA_IMAGES"> - <new-permission name="android.permission.READ_EXTERNAL_STORAGE" /> - <new-permission name="android.permission.WRITE_EXTERNAL_STORAGE" /> - </split-permission> - <!-- This is a list of all the libraries available for application code to link against. --> diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml index 2ea704129630..ed198e60902b 100644 --- a/data/etc/privapp-permissions-platform.xml +++ b/data/etc/privapp-permissions-platform.xml @@ -272,7 +272,10 @@ applications that come with the platform <permission name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/> <permission name="android.permission.MOVE_PACKAGE"/> <permission name="android.permission.OBSERVE_APP_USAGE"/> + <permission name="android.permission.NETWORK_SCAN"/> <permission name="android.permission.PACKAGE_USAGE_STATS" /> + <!-- Needed for test only --> + <permission name="android.permission.PACKET_KEEPALIVE_OFFLOAD" /> <permission name="android.permission.POWER_SAVER" /> <permission name="android.permission.READ_FRAME_BUFFER"/> <permission name="android.permission.READ_LOWPAN_CREDENTIAL"/> diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java index e4142a933f0f..adc04fb03e2a 100644 --- a/graphics/java/android/graphics/drawable/Drawable.java +++ b/graphics/java/android/graphics/drawable/Drawable.java @@ -688,20 +688,20 @@ public abstract class Drawable { * {@link #setColorFilter(int, PorterDuff.Mode)} overrides tint. * </p> * - * @param tintMode A Porter-Duff blending mode + * @param tintMode A Porter-Duff blending mode to apply to the drawable, a value of null sets + * the default Porter-Diff blending mode value + * of {@link PorterDuff.Mode#SRC_IN} * @see #setTint(int) * @see #setTintList(ColorStateList) * * @deprecated use {@link #setTintMode(BlendMode)} instead */ @Deprecated - public void setTintMode(@NonNull PorterDuff.Mode tintMode) { + public void setTintMode(@Nullable PorterDuff.Mode tintMode) { if (!mSetTintModeInvoked) { mSetTintModeInvoked = true; - BlendMode mode = BlendMode.fromValue(tintMode.nativeInt); - if (mode != null) { - setTintMode(mode); - } + BlendMode mode = tintMode != null ? BlendMode.fromValue(tintMode.nativeInt) : null; + setTintMode(mode != null ? mode : Drawable.DEFAULT_BLEND_MODE); mSetTintModeInvoked = false; } } @@ -716,17 +716,16 @@ public abstract class Drawable { * {@link #setColorFilter(ColorFilter)} * </p> * - * @param blendMode + * @param blendMode BlendMode to apply to the drawable, a value of null sets the default + * blend mode value of {@link BlendMode#SRC_IN} * @see #setTint(int) * @see #setTintList(ColorStateList) */ - public void setTintMode(@NonNull BlendMode blendMode) { + public void setTintMode(@Nullable BlendMode blendMode) { if (!mSetBlendModeInvoked) { mSetBlendModeInvoked = true; PorterDuff.Mode mode = BlendMode.blendModeToPorterDuffMode(blendMode); - if (mode != null) { - setTintMode(mode); - } + setTintMode(mode != null ? mode : Drawable.DEFAULT_TINT_MODE); mSetBlendModeInvoked = false; } } diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java index cdb3441d5225..6948bc4fd61b 100644 --- a/graphics/java/android/graphics/drawable/GradientDrawable.java +++ b/graphics/java/android/graphics/drawable/GradientDrawable.java @@ -1312,6 +1312,10 @@ public class GradientDrawable extends Drawable { y0 = r.top + (r.bottom - r.top) * st.mCenterY; float radius = st.mGradientRadius; + if (Float.compare(radius, 0.0f) == -1 || Float.isNaN(radius)) { + throw new IllegalArgumentException("Gradient radius must be a valid " + + "number greater than or equal to 0"); + } if (st.mGradientRadiusType == RADIUS_TYPE_FRACTION) { // Fall back to parent width or height if intrinsic // size is not specified. @@ -1759,75 +1763,68 @@ public class GradientDrawable extends Drawable { st.mGradientColors[1] = endColor; } - if (st.mGradient == LINEAR_GRADIENT) { - int angle = (int) a.getFloat(R.styleable.GradientDrawableGradient_angle, st.mAngle); - angle %= 360; + int angle = (int) a.getFloat(R.styleable.GradientDrawableGradient_angle, st.mAngle); + angle %= 360; - if (angle % 45 != 0) { - throw new XmlPullParserException(a.getPositionDescription() - + "<gradient> tag requires 'angle' attribute to " - + "be a multiple of 45"); - } + if (angle % 45 != 0) { + throw new XmlPullParserException(a.getPositionDescription() + + "<gradient> tag requires 'angle' attribute to " + + "be a multiple of 45"); + } - st.mAngle = angle; - - switch (angle) { - case 0: - st.mOrientation = Orientation.LEFT_RIGHT; - break; - case 45: - st.mOrientation = Orientation.BL_TR; - break; - case 90: - st.mOrientation = Orientation.BOTTOM_TOP; - break; - case 135: - st.mOrientation = Orientation.BR_TL; - break; - case 180: - st.mOrientation = Orientation.RIGHT_LEFT; - break; - case 225: - st.mOrientation = Orientation.TR_BL; - break; - case 270: - st.mOrientation = Orientation.TOP_BOTTOM; - break; - case 315: - st.mOrientation = Orientation.TL_BR; - break; - } - } else { - final TypedValue tv = a.peekValue(R.styleable.GradientDrawableGradient_gradientRadius); - if (tv != null) { - final float radius; - final @RadiusType int radiusType; - if (tv.type == TypedValue.TYPE_FRACTION) { - radius = tv.getFraction(1.0f, 1.0f); - - final int unit = (tv.data >> TypedValue.COMPLEX_UNIT_SHIFT) - & TypedValue.COMPLEX_UNIT_MASK; - if (unit == TypedValue.COMPLEX_UNIT_FRACTION_PARENT) { - radiusType = RADIUS_TYPE_FRACTION_PARENT; - } else { - radiusType = RADIUS_TYPE_FRACTION; - } - } else if (tv.type == TypedValue.TYPE_DIMENSION) { - radius = tv.getDimension(r.getDisplayMetrics()); - radiusType = RADIUS_TYPE_PIXELS; + st.mAngle = angle; + + switch (angle) { + case 0: + st.mOrientation = Orientation.LEFT_RIGHT; + break; + case 45: + st.mOrientation = Orientation.BL_TR; + break; + case 90: + st.mOrientation = Orientation.BOTTOM_TOP; + break; + case 135: + st.mOrientation = Orientation.BR_TL; + break; + case 180: + st.mOrientation = Orientation.RIGHT_LEFT; + break; + case 225: + st.mOrientation = Orientation.TR_BL; + break; + case 270: + st.mOrientation = Orientation.TOP_BOTTOM; + break; + case 315: + st.mOrientation = Orientation.TL_BR; + break; + } + + final TypedValue tv = a.peekValue(R.styleable.GradientDrawableGradient_gradientRadius); + if (tv != null) { + final float radius; + final @RadiusType int radiusType; + if (tv.type == TypedValue.TYPE_FRACTION) { + radius = tv.getFraction(1.0f, 1.0f); + + final int unit = (tv.data >> TypedValue.COMPLEX_UNIT_SHIFT) + & TypedValue.COMPLEX_UNIT_MASK; + if (unit == TypedValue.COMPLEX_UNIT_FRACTION_PARENT) { + radiusType = RADIUS_TYPE_FRACTION_PARENT; } else { - radius = tv.getFloat(); - radiusType = RADIUS_TYPE_PIXELS; + radiusType = RADIUS_TYPE_FRACTION; } - - st.mGradientRadius = radius; - st.mGradientRadiusType = radiusType; - } else if (st.mGradient == RADIAL_GRADIENT) { - throw new XmlPullParserException( - a.getPositionDescription() - + "<gradient> tag requires 'gradientRadius' " - + "attribute with radial type"); + } else if (tv.type == TypedValue.TYPE_DIMENSION) { + radius = tv.getDimension(r.getDisplayMetrics()); + radiusType = RADIUS_TYPE_PIXELS; + } else { + radius = tv.getFloat(); + radiusType = RADIUS_TYPE_PIXELS; } + + st.mGradientRadius = radius; + st.mGradientRadiusType = radiusType; } } diff --git a/keystore/java/android/security/KeyStore.java b/keystore/java/android/security/KeyStore.java index bfce17c3e6ab..f21fa5ef1486 100644 --- a/keystore/java/android/security/KeyStore.java +++ b/keystore/java/android/security/KeyStore.java @@ -17,7 +17,6 @@ package android.security; import android.annotation.UnsupportedAppUsage; -import android.app.ActivityManager; import android.app.ActivityThread; import android.app.Application; import android.app.KeyguardManager; @@ -45,24 +44,24 @@ import android.security.keystore.KeyExpiredException; import android.security.keystore.KeyNotYetValidException; import android.security.keystore.KeyPermanentlyInvalidatedException; import android.security.keystore.KeyProperties; -import android.security.keystore.KeyProtection; import android.security.keystore.KeystoreResponse; -import android.security.keystore.StrongBoxUnavailableException; import android.security.keystore.UserNotAuthenticatedException; import android.util.Log; + import com.android.org.bouncycastle.asn1.ASN1InputStream; import com.android.org.bouncycastle.asn1.pkcs.PrivateKeyInfo; -import java.math.BigInteger; + import java.io.ByteArrayInputStream; import java.io.IOException; +import java.math.BigInteger; import java.security.InvalidKeyException; import java.util.ArrayList; -import java.util.Arrays; import java.util.Date; import java.util.List; import java.util.Locale; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; + import sun.security.util.ObjectIdentifier; import sun.security.x509.AlgorithmId; @@ -492,8 +491,9 @@ public class KeyStore { } public boolean addRngEntropy(byte[] data, int flags) { + KeystoreResultPromise promise = new KeystoreResultPromise(); try { - KeystoreResultPromise promise = new KeystoreResultPromise(); + mBinder.asBinder().linkToDeath(promise, 0); int errorCode = mBinder.addRngEntropy(promise, data, flags); if (errorCode == NO_ERROR) { return promise.getFuture().get().getErrorCode() == NO_ERROR; @@ -506,6 +506,8 @@ public class KeyStore { } catch (ExecutionException | InterruptedException e) { Log.e(TAG, "AddRngEntropy completed with exception", e); return false; + } finally { + mBinder.asBinder().unlinkToDeath(promise, 0); } } @@ -537,7 +539,8 @@ public class KeyStore { } private class KeyCharacteristicsPromise - extends android.security.keystore.IKeystoreKeyCharacteristicsCallback.Stub { + extends android.security.keystore.IKeystoreKeyCharacteristicsCallback.Stub + implements IBinder.DeathRecipient { final private CompletableFuture<KeyCharacteristicsCallbackResult> future = new CompletableFuture<KeyCharacteristicsCallbackResult>(); @Override @@ -550,19 +553,30 @@ public class KeyStore { public final CompletableFuture<KeyCharacteristicsCallbackResult> getFuture() { return future; } + @Override + public void binderDied() { + future.completeExceptionally(new RemoteException("Keystore died")); + } }; private int generateKeyInternal(String alias, KeymasterArguments args, byte[] entropy, int uid, int flags, KeyCharacteristics outCharacteristics) throws RemoteException, ExecutionException, InterruptedException { KeyCharacteristicsPromise promise = new KeyCharacteristicsPromise(); - int error = mBinder.generateKey(promise, alias, args, entropy, uid, flags); - if (error != NO_ERROR) { - Log.e(TAG, "generateKeyInternal failed on request " + error); - return error; + int error = NO_ERROR; + KeyCharacteristicsCallbackResult result = null; + try { + mBinder.asBinder().linkToDeath(promise, 0); + error = mBinder.generateKey(promise, alias, args, entropy, uid, flags); + if (error != NO_ERROR) { + Log.e(TAG, "generateKeyInternal failed on request " + error); + return error; + } + result = promise.getFuture().get(); + } finally { + mBinder.asBinder().unlinkToDeath(promise, 0); } - KeyCharacteristicsCallbackResult result = promise.getFuture().get(); error = result.getKeystoreResponse().getErrorCode(); if (error != NO_ERROR) { Log.e(TAG, "generateKeyInternal failed on response " + error); @@ -604,10 +618,12 @@ public class KeyStore { public int getKeyCharacteristics(String alias, KeymasterBlob clientId, KeymasterBlob appId, int uid, KeyCharacteristics outCharacteristics) { + KeyCharacteristicsPromise promise = new KeyCharacteristicsPromise(); try { + mBinder.asBinder().linkToDeath(promise, 0); clientId = clientId != null ? clientId : new KeymasterBlob(new byte[0]); appId = appId != null ? appId : new KeymasterBlob(new byte[0]); - KeyCharacteristicsPromise promise = new KeyCharacteristicsPromise(); + int error = mBinder.getKeyCharacteristics(promise, alias, clientId, appId, uid); if (error != NO_ERROR) return error; @@ -625,6 +641,8 @@ public class KeyStore { } catch (ExecutionException | InterruptedException e) { Log.e(TAG, "GetKeyCharacteristics completed with exception", e); return SYSTEM_ERROR; + } finally { + mBinder.asBinder().unlinkToDeath(promise, 0); } } @@ -637,17 +655,23 @@ public class KeyStore { int uid, int flags, KeyCharacteristics outCharacteristics) throws RemoteException, ExecutionException, InterruptedException { KeyCharacteristicsPromise promise = new KeyCharacteristicsPromise(); - int error = mBinder.importKey(promise, alias, args, format, keyData, uid, flags); - if (error != NO_ERROR) return error; + mBinder.asBinder().linkToDeath(promise, 0); + try { + int error = mBinder.importKey(promise, alias, args, format, keyData, uid, flags); + if (error != NO_ERROR) return error; - KeyCharacteristicsCallbackResult result = promise.getFuture().get(); - error = result.getKeystoreResponse().getErrorCode(); - if (error != NO_ERROR) return error; + KeyCharacteristicsCallbackResult result = promise.getFuture().get(); - KeyCharacteristics characteristics = result.getKeyCharacteristics(); - if (characteristics == null) return SYSTEM_ERROR; - outCharacteristics.shallowCopyFrom(characteristics); - return NO_ERROR; + error = result.getKeystoreResponse().getErrorCode(); + if (error != NO_ERROR) return error; + + KeyCharacteristics characteristics = result.getKeyCharacteristics(); + if (characteristics == null) return SYSTEM_ERROR; + outCharacteristics.shallowCopyFrom(characteristics); + return NO_ERROR; + } finally { + mBinder.asBinder().unlinkToDeath(promise, 0); + } } public int importKey(String alias, KeymasterArguments args, int format, byte[] keyData, @@ -738,18 +762,25 @@ public class KeyStore { KeyCharacteristics outCharacteristics) throws RemoteException, ExecutionException, InterruptedException { KeyCharacteristicsPromise promise = new KeyCharacteristicsPromise(); - int error = mBinder.importWrappedKey(promise, wrappedKeyAlias, wrappedKey, wrappingKeyAlias, - maskingKey, args, rootSid, fingerprintSid); - if (error != NO_ERROR) return error; + mBinder.asBinder().linkToDeath(promise, 0); + try { + KeyCharacteristicsCallbackResult result = null; + int error = mBinder.importWrappedKey(promise, wrappedKeyAlias, wrappedKey, + wrappingKeyAlias, maskingKey, args, rootSid, fingerprintSid); + if (error != NO_ERROR) return error; - KeyCharacteristicsCallbackResult result = promise.getFuture().get(); - error = result.getKeystoreResponse().getErrorCode(); - if (error != NO_ERROR) return error; + KeyCharacteristicsCallbackResult esult = promise.getFuture().get(); - KeyCharacteristics characteristics = result.getKeyCharacteristics(); - if (characteristics == null) return SYSTEM_ERROR; - outCharacteristics.shallowCopyFrom(characteristics); - return NO_ERROR; + error = result.getKeystoreResponse().getErrorCode(); + if (error != NO_ERROR) return error; + + KeyCharacteristics characteristics = result.getKeyCharacteristics(); + if (characteristics == null) return SYSTEM_ERROR; + outCharacteristics.shallowCopyFrom(characteristics); + return NO_ERROR; + } finally { + mBinder.asBinder().unlinkToDeath(promise, 0); + } } public int importWrappedKey(String wrappedKeyAlias, byte[] wrappedKey, @@ -776,7 +807,8 @@ public class KeyStore { } private class ExportKeyPromise - extends android.security.keystore.IKeystoreExportKeyCallback.Stub { + extends android.security.keystore.IKeystoreExportKeyCallback.Stub + implements IBinder.DeathRecipient { final private CompletableFuture<ExportResult> future = new CompletableFuture<ExportResult>(); @Override public void onFinished(ExportResult exportKeyResult) throws android.os.RemoteException { @@ -785,14 +817,19 @@ public class KeyStore { public final CompletableFuture<ExportResult> getFuture() { return future; } + @Override + public void binderDied() { + future.completeExceptionally(new RemoteException("Keystore died")); + } }; public ExportResult exportKey(String alias, int format, KeymasterBlob clientId, KeymasterBlob appId, int uid) { + ExportKeyPromise promise = new ExportKeyPromise(); try { + mBinder.asBinder().linkToDeath(promise, 0); clientId = clientId != null ? clientId : new KeymasterBlob(new byte[0]); appId = appId != null ? appId : new KeymasterBlob(new byte[0]); - ExportKeyPromise promise = new ExportKeyPromise(); int error = mBinder.exportKey(promise, alias, format, clientId, appId, uid); if (error == NO_ERROR) { return promise.getFuture().get(); @@ -805,6 +842,8 @@ public class KeyStore { } catch (ExecutionException | InterruptedException e) { Log.e(TAG, "ExportKey completed with exception", e); return null; + } finally { + mBinder.asBinder().unlinkToDeath(promise, 0); } } public ExportResult exportKey(String alias, int format, KeymasterBlob clientId, @@ -813,7 +852,8 @@ public class KeyStore { } private class OperationPromise - extends android.security.keystore.IKeystoreOperationResultCallback.Stub { + extends android.security.keystore.IKeystoreOperationResultCallback.Stub + implements IBinder.DeathRecipient { final private CompletableFuture<OperationResult> future = new CompletableFuture<OperationResult>(); @Override public void onFinished(OperationResult operationResult) throws android.os.RemoteException { @@ -822,14 +862,19 @@ public class KeyStore { public final CompletableFuture<OperationResult> getFuture() { return future; } + @Override + public void binderDied() { + future.completeExceptionally(new RemoteException("Keystore died")); + } }; public OperationResult begin(String alias, int purpose, boolean pruneable, KeymasterArguments args, byte[] entropy, int uid) { + OperationPromise promise = new OperationPromise(); try { + mBinder.asBinder().linkToDeath(promise, 0); args = args != null ? args : new KeymasterArguments(); entropy = entropy != null ? entropy : new byte[0]; - OperationPromise promise = new OperationPromise(); int errorCode = mBinder.begin(promise, getToken(), alias, purpose, pruneable, args, entropy, uid); if (errorCode == NO_ERROR) { @@ -843,6 +888,8 @@ public class KeyStore { } catch (ExecutionException | InterruptedException e) { Log.e(TAG, "Begin completed with exception", e); return null; + } finally { + mBinder.asBinder().unlinkToDeath(promise, 0); } } @@ -854,10 +901,11 @@ public class KeyStore { } public OperationResult update(IBinder token, KeymasterArguments arguments, byte[] input) { + OperationPromise promise = new OperationPromise(); try { + mBinder.asBinder().linkToDeath(promise, 0); arguments = arguments != null ? arguments : new KeymasterArguments(); input = input != null ? input : new byte[0]; - OperationPromise promise = new OperationPromise(); int errorCode = mBinder.update(promise, token, arguments, input); if (errorCode == NO_ERROR) { return promise.getFuture().get(); @@ -870,16 +918,19 @@ public class KeyStore { } catch (ExecutionException | InterruptedException e) { Log.e(TAG, "Update completed with exception", e); return null; + } finally { + mBinder.asBinder().unlinkToDeath(promise, 0); } } public OperationResult finish(IBinder token, KeymasterArguments arguments, byte[] signature, byte[] entropy) { + OperationPromise promise = new OperationPromise(); try { + mBinder.asBinder().linkToDeath(promise, 0); arguments = arguments != null ? arguments : new KeymasterArguments(); entropy = entropy != null ? entropy : new byte[0]; signature = signature != null ? signature : new byte[0]; - OperationPromise promise = new OperationPromise(); int errorCode = mBinder.finish(promise, token, arguments, signature, entropy); if (errorCode == NO_ERROR) { return promise.getFuture().get(); @@ -892,6 +943,8 @@ public class KeyStore { } catch (ExecutionException | InterruptedException e) { Log.e(TAG, "Finish completed with exception", e); return null; + } finally { + mBinder.asBinder().unlinkToDeath(promise, 0); } } @@ -900,7 +953,8 @@ public class KeyStore { } private class KeystoreResultPromise - extends android.security.keystore.IKeystoreResponseCallback.Stub { + extends android.security.keystore.IKeystoreResponseCallback.Stub + implements IBinder.DeathRecipient { final private CompletableFuture<KeystoreResponse> future = new CompletableFuture<KeystoreResponse>(); @Override public void onFinished(KeystoreResponse keystoreResponse) throws android.os.RemoteException { @@ -909,11 +963,16 @@ public class KeyStore { public final CompletableFuture<KeystoreResponse> getFuture() { return future; } + @Override + public void binderDied() { + future.completeExceptionally(new RemoteException("Keystore died")); + } }; public int abort(IBinder token) { + KeystoreResultPromise promise = new KeystoreResultPromise(); try { - KeystoreResultPromise promise = new KeystoreResultPromise(); + mBinder.asBinder().linkToDeath(promise, 0); int errorCode = mBinder.abort(promise, token); if (errorCode == NO_ERROR) { return promise.getFuture().get().getErrorCode(); @@ -926,6 +985,8 @@ public class KeyStore { } catch (ExecutionException | InterruptedException e) { Log.e(TAG, "Abort completed with exception", e); return SYSTEM_ERROR; + } finally { + mBinder.asBinder().unlinkToDeath(promise, 0); } } @@ -1035,7 +1096,8 @@ public class KeyStore { } private class CertificateChainPromise - extends android.security.keystore.IKeystoreCertificateChainCallback.Stub { + extends android.security.keystore.IKeystoreCertificateChainCallback.Stub + implements IBinder.DeathRecipient { final private CompletableFuture<KeyAttestationCallbackResult> future = new CompletableFuture<KeyAttestationCallbackResult>(); @Override public void onFinished(KeystoreResponse keystoreResponse, @@ -1045,19 +1107,24 @@ public class KeyStore { public final CompletableFuture<KeyAttestationCallbackResult> getFuture() { return future; } + @Override + public void binderDied() { + future.completeExceptionally(new RemoteException("Keystore died")); + } }; public int attestKey( String alias, KeymasterArguments params, KeymasterCertificateChain outChain) { + CertificateChainPromise promise = new CertificateChainPromise(); try { + mBinder.asBinder().linkToDeath(promise, 0); if (params == null) { params = new KeymasterArguments(); } if (outChain == null) { outChain = new KeymasterCertificateChain(); } - CertificateChainPromise promise = new CertificateChainPromise(); int error = mBinder.attestKey(promise, alias, params); if (error != NO_ERROR) return error; KeyAttestationCallbackResult result = promise.getFuture().get(); @@ -1072,18 +1139,21 @@ public class KeyStore { } catch (ExecutionException | InterruptedException e) { Log.e(TAG, "AttestKey completed with exception", e); return SYSTEM_ERROR; + } finally { + mBinder.asBinder().unlinkToDeath(promise, 0); } } public int attestDeviceIds(KeymasterArguments params, KeymasterCertificateChain outChain) { + CertificateChainPromise promise = new CertificateChainPromise(); try { + mBinder.asBinder().linkToDeath(promise, 0); if (params == null) { params = new KeymasterArguments(); } if (outChain == null) { outChain = new KeymasterCertificateChain(); } - CertificateChainPromise promise = new CertificateChainPromise(); int error = mBinder.attestDeviceIds(promise, params); if (error != NO_ERROR) return error; KeyAttestationCallbackResult result = promise.getFuture().get(); @@ -1098,6 +1168,8 @@ public class KeyStore { } catch (ExecutionException | InterruptedException e) { Log.e(TAG, "AttestDevicdeIds completed with exception", e); return SYSTEM_ERROR; + } finally { + mBinder.asBinder().unlinkToDeath(promise, 0); } } diff --git a/keystore/tests/Android.bp b/keystore/tests/Android.bp new file mode 100644 index 000000000000..e9b22c140742 --- /dev/null +++ b/keystore/tests/Android.bp @@ -0,0 +1,26 @@ +// Copyright (C) 2017 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +android_test { + name: "KeystoreTests", + // LOCAL_MODULE := keystore + srcs: ["src/**/*.java"], + static_libs: [ + "androidx.test.rules", + "hamcrest-library", + ], + platform_apis: true, + libs: ["android.test.runner"], + certificate: "platform", +} diff --git a/keystore/tests/Android.mk b/keystore/tests/Android.mk deleted file mode 100644 index 99d3197f8bf3..000000000000 --- a/keystore/tests/Android.mk +++ /dev/null @@ -1,34 +0,0 @@ -# Copyright (C) 2017 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -LOCAL_PATH := $(call my-dir) -include $(CLEAR_VARS) - -# LOCAL_MODULE := keystore -LOCAL_MODULE_TAGS := tests - -LOCAL_SRC_FILES := $(call all-java-files-under, src) - -LOCAL_STATIC_JAVA_LIBRARIES := \ - androidx.test.rules hamcrest-library - -LOCAL_PACKAGE_NAME := KeystoreTests -LOCAL_PRIVATE_PLATFORM_APIS := true - -LOCAL_JAVA_LIBRARIES := android.test.runner - -LOCAL_CERTIFICATE := platform - -include $(BUILD_PACKAGE) - 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/RenderThread.cpp b/libs/hwui/renderthread/RenderThread.cpp index 6cce31943d03..b76e49ce94a0 100644 --- a/libs/hwui/renderthread/RenderThread.cpp +++ b/libs/hwui/renderthread/RenderThread.cpp @@ -209,8 +209,8 @@ void RenderThread::requireVkContext() { mVkManager->initialize(); GrContextOptions options; initGrContextOptions(options); - // TODO: get a string describing the SPIR-V compiler version and use it here - cacheManager().configureContext(&options, nullptr, 0); + auto vkDriverVersion = mVkManager->getDriverVersion(); + cacheManager().configureContext(&options, &vkDriverVersion, sizeof(vkDriverVersion)); sk_sp<GrContext> grContext = mVkManager->createContext(options); LOG_ALWAYS_FATAL_IF(!grContext.get()); setGrContext(grContext); @@ -408,12 +408,13 @@ bool RenderThread::isCurrent() { } void RenderThread::preload() { - std::thread eglInitThread([]() { - //TODO: don't load EGL drivers for Vulkan, when HW bitmap uploader is refactored. - eglGetDisplay(EGL_DEFAULT_DISPLAY); - }); - eglInitThread.detach(); - if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaVulkan) { + // EGL driver is always preloaded only if HWUI renders with GL. + if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaGL) { + std::thread eglInitThread([]() { + eglGetDisplay(EGL_DEFAULT_DISPLAY); + }); + eglInitThread.detach(); + } else { requireVkContext(); } HardwareBitmapUploader::initialize(); diff --git a/libs/hwui/renderthread/VulkanManager.cpp b/libs/hwui/renderthread/VulkanManager.cpp index c92909898652..4011329fa2da 100644 --- a/libs/hwui/renderthread/VulkanManager.cpp +++ b/libs/hwui/renderthread/VulkanManager.cpp @@ -170,6 +170,9 @@ void VulkanManager::setupDevice(GrVkExtensions& grExtensions, VkPhysicalDeviceFe VkPhysicalDeviceProperties physDeviceProperties; mGetPhysicalDeviceProperties(mPhysicalDevice, &physDeviceProperties); LOG_ALWAYS_FATAL_IF(physDeviceProperties.apiVersion < VK_MAKE_VERSION(1, 1, 0)); + mDriverVersion = physDeviceProperties.driverVersion; + + mIsQualcomm = physDeviceProperties.vendorID == 20803; // query to get the initial queue props size uint32_t queueCount; diff --git a/libs/hwui/renderthread/VulkanManager.h b/libs/hwui/renderthread/VulkanManager.h index c2d18029c731..a7a43cc39a45 100644 --- a/libs/hwui/renderthread/VulkanManager.h +++ b/libs/hwui/renderthread/VulkanManager.h @@ -82,6 +82,8 @@ public: sk_sp<GrContext> createContext(const GrContextOptions& options); + uint32_t getDriverVersion() const { return mDriverVersion; } + private: friend class VulkanSurface; // Sets up the VkInstance and VkDevice objects. Also fills out the passed in @@ -178,6 +180,14 @@ private: }; SwapBehavior mSwapBehavior = SwapBehavior::Discard; GrVkExtensions mExtensions; + uint32_t mDriverVersion = 0; + + // TODO: Remove once fix has landed. Temporaryly needed for workaround for setting up AHB + // surfaces on Qualcomm. Currently if you don't use VkSwapchain Qualcomm is not setting + // reporting that we need to use one of their private vendor usage bits which greatly effects + // performance if it is not used. + bool mIsQualcomm = false; + bool isQualcomm() const { return mIsQualcomm; } }; } /* namespace renderthread */ diff --git a/libs/hwui/renderthread/VulkanSurface.cpp b/libs/hwui/renderthread/VulkanSurface.cpp index 1708d3c0e093..36f540c47973 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; @@ -289,6 +299,10 @@ VulkanSurface* VulkanSurface::Create(ANativeWindow* window, ColorMode colorMode, } windowInfo.windowUsageFlags = hwbUsage.androidHardwareBufferUsage; + if (vkManager.isQualcomm()) { + windowInfo.windowUsageFlags = + windowInfo.windowUsageFlags | AHARDWAREBUFFER_USAGE_VENDOR_0; + } } else { ALOGE("VulkanSurface::Create() vkmGetPhysicalDeviceImageFormatProperties2 is missing"); @@ -357,10 +371,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 +405,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/location/Android.mk b/location/Android.mk deleted file mode 100644 index 50509c6f1a3c..000000000000 --- a/location/Android.mk +++ /dev/null @@ -1,17 +0,0 @@ -# Copyright (C) 2010 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -LOCAL_PATH := $(call my-dir) - -include $(call all-subdir-makefiles, $(LOCAL_PATH))
\ No newline at end of file diff --git a/location/java/android/location/GnssCapabilities.java b/location/java/android/location/GnssCapabilities.java index 6a35920e7fa2..badffd171720 100644 --- a/location/java/android/location/GnssCapabilities.java +++ b/location/java/android/location/GnssCapabilities.java @@ -77,15 +77,14 @@ public final class GnssCapabilities { }) public @interface Capability {} - /** - * @hide - */ + /** @hide */ public static final long INVALID_CAPABILITIES = -1; /** A bitmask of supported GNSS capabilities. */ private final long mGnssCapabilities; - static GnssCapabilities of(long gnssCapabilities) { + /** @hide */ + public static GnssCapabilities of(long gnssCapabilities) { return new GnssCapabilities(gnssCapabilities); } diff --git a/location/tests/Android.bp b/location/tests/Android.bp new file mode 100644 index 000000000000..8b137891791f --- /dev/null +++ b/location/tests/Android.bp @@ -0,0 +1 @@ + diff --git a/location/tests/Android.mk b/location/tests/Android.mk deleted file mode 100644 index 57848f353fd4..000000000000 --- a/location/tests/Android.mk +++ /dev/null @@ -1,3 +0,0 @@ -LOCAL_PATH:= $(call my-dir) - -include $(call all-makefiles-under, $(LOCAL_PATH))
\ No newline at end of file diff --git a/location/tests/locationtests/Android.bp b/location/tests/locationtests/Android.bp new file mode 100644 index 000000000000..1a4e2c7ba355 --- /dev/null +++ b/location/tests/locationtests/Android.bp @@ -0,0 +1,19 @@ +android_test { + name: "FrameworksLocationTests", + // Include all test java files. + srcs: ["src/**/*.java"], + libs: [ + "android.test.runner", + "android.test.base", + ], + platform_apis: true, + static_libs: [ + "androidx.test.rules", + "core-test-rules", + "guava", + "mockito-target-minus-junit4", + "frameworks-base-testutils", + "truth-prebuilt", + ], + test_suites: ["device-tests"], +} diff --git a/location/tests/locationtests/Android.mk b/location/tests/locationtests/Android.mk deleted file mode 100644 index 3dcf69426362..000000000000 --- a/location/tests/locationtests/Android.mk +++ /dev/null @@ -1,23 +0,0 @@ -LOCAL_PATH:= $(call my-dir) -include $(CLEAR_VARS) - -# We only want this apk build for tests. -LOCAL_MODULE_TAGS := tests - -# Include all test java files. -LOCAL_SRC_FILES := $(call all-java-files-under, src) - -LOCAL_JAVA_LIBRARIES := android.test.runner android.test.base -LOCAL_PACKAGE_NAME := FrameworksLocationTests -LOCAL_PRIVATE_PLATFORM_APIS := true - -LOCAL_STATIC_JAVA_LIBRARIES := \ - androidx.test.rules \ - core-test-rules \ - guava \ - mockito-target-minus-junit4 \ - frameworks-base-testutils \ - truth-prebuilt \ - -LOCAL_COMPATIBILITY_SUITE := device-tests -include $(BUILD_PACKAGE) diff --git a/media/java/android/media/AudioAttributes.java b/media/java/android/media/AudioAttributes.java index efb7f4698797..bf1063d0907f 100644 --- a/media/java/android/media/AudioAttributes.java +++ b/media/java/android/media/AudioAttributes.java @@ -20,6 +20,7 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.SystemApi; import android.annotation.UnsupportedAppUsage; +import android.media.audiopolicy.AudioProductStrategies; import android.os.Build; import android.os.Bundle; import android.os.Parcel; @@ -556,7 +557,7 @@ public final class AudioAttributes implements Parcelable { private int mContentType = CONTENT_TYPE_UNKNOWN; private int mSource = MediaRecorder.AudioSource.AUDIO_SOURCE_INVALID; private int mFlags = 0x0; - private boolean mMuteHapticChannels = false; + private boolean mMuteHapticChannels = true; private HashSet<String> mTags = new HashSet<String>(); private Bundle mBundle; @@ -709,20 +710,7 @@ public final class AudioAttributes implements Parcelable { * @throws IllegalArgumentException if the argument is not a valid value. */ public @NonNull Builder setAllowedCapturePolicy(@CapturePolicy int capturePolicy) { - switch (capturePolicy) { - case ALLOW_CAPTURE_BY_NONE: - mFlags |= FLAG_NO_MEDIA_PROJECTION | FLAG_NO_SYSTEM_CAPTURE; - break; - case ALLOW_CAPTURE_BY_SYSTEM: - mFlags |= FLAG_NO_MEDIA_PROJECTION; - mFlags &= ~FLAG_NO_SYSTEM_CAPTURE; - break; - case ALLOW_CAPTURE_BY_ALL: - mFlags &= ~FLAG_NO_SYSTEM_CAPTURE & ~FLAG_NO_MEDIA_PROJECTION; - break; - default: - throw new IllegalArgumentException("Unknown allow playback capture policy"); - } + mFlags = capturePolicyToFlags(capturePolicy, mFlags); return this; } @@ -794,6 +782,13 @@ public final class AudioAttributes implements Parcelable { */ @UnsupportedAppUsage public Builder setInternalLegacyStreamType(int streamType) { + final AudioProductStrategies ps = new AudioProductStrategies(); + if (ps.size() > 0) { + AudioAttributes attributes = ps.getAudioAttributesForLegacyStreamType(streamType); + if (attributes != null) { + return new Builder(attributes); + } + } switch(streamType) { case AudioSystem.STREAM_VOICE_CALL: mContentType = CONTENT_TYPE_SPEECH; @@ -893,7 +888,7 @@ public final class AudioAttributes implements Parcelable { /** * Specifying if haptic should be muted or not when playing audio-haptic coupled data. - * By default, haptic channels are enabled. + * By default, haptic channels are disabled. * @param muted true to force muting haptic channels. * @return the same Builder instance. */ @@ -1169,6 +1164,10 @@ public final class AudioAttributes implements Parcelable { AudioSystem.STREAM_MUSIC : AudioSystem.STREAM_TTS; } + final AudioProductStrategies ps = new AudioProductStrategies(); + if (ps.size() > 0) { + return ps.getLegacyStreamTypeForAudioAttributes(aa); + } // usage to stream type mapping switch (aa.getUsage()) { case USAGE_MEDIA: @@ -1207,6 +1206,24 @@ public final class AudioAttributes implements Parcelable { } } + static int capturePolicyToFlags(@CapturePolicy int capturePolicy, int flags) { + switch (capturePolicy) { + case ALLOW_CAPTURE_BY_NONE: + flags |= FLAG_NO_MEDIA_PROJECTION | FLAG_NO_SYSTEM_CAPTURE; + break; + case ALLOW_CAPTURE_BY_SYSTEM: + flags |= FLAG_NO_MEDIA_PROJECTION; + flags &= ~FLAG_NO_SYSTEM_CAPTURE; + break; + case ALLOW_CAPTURE_BY_ALL: + flags &= ~FLAG_NO_SYSTEM_CAPTURE & ~FLAG_NO_MEDIA_PROJECTION; + break; + default: + throw new IllegalArgumentException("Unknown allow playback capture policy"); + } + return flags; + } + /** @hide */ @IntDef({ USAGE_UNKNOWN, diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java index 7cb5e00e7684..dc5c6639375b 100644 --- a/media/java/android/media/AudioManager.java +++ b/media/java/android/media/AudioManager.java @@ -1478,6 +1478,30 @@ public class AudioManager { } } + /** + * Specifying if this audio may or may not be captured by other apps or the system. + * + * The default is {@link AudioAttributes#ALLOW_CAPTURE_BY_ALL}. + * + * Note that each audio track can also set its policy, in which case the most + * restrictive policy is always applied. + * + * @param capturePolicy one of + * {@link AudioAttributes#ALLOW_CAPTURE_BY_ALL}, + * {@link AudioAttributes#ALLOW_CAPTURE_BY_SYSTEM}, + * {@link AudioAttributes#ALLOW_CAPTURE_BY_NONE}. + * @throws IllegalArgumentException if the argument is not a valid value. + */ + public void setAllowedCapturePolicy(@AudioAttributes.CapturePolicy int capturePolicy) { + int flags = AudioAttributes.capturePolicyToFlags(capturePolicy, 0x0); + // TODO: got trough AudioService and save a cache to restore in case of AP crash + // TODO: also pass the package in case multiple packages have the same UID + int result = AudioSystem.setAllowedCapturePolicy(Process.myUid(), flags); + if (result != AudioSystem.AUDIO_STATUS_OK) { + Log.e(TAG, "Could not setAllowedCapturePolicy: " + result); + } + } + //==================================================================== // Offload query /** diff --git a/media/java/android/media/AudioPlaybackCaptureConfiguration.java b/media/java/android/media/AudioPlaybackCaptureConfiguration.java index 9ee6f8740568..bcaef032093d 100644 --- a/media/java/android/media/AudioPlaybackCaptureConfiguration.java +++ b/media/java/android/media/AudioPlaybackCaptureConfiguration.java @@ -29,13 +29,17 @@ import com.android.internal.util.Preconditions; * Configuration for capturing audio played by other apps. * * Only the following audio can be captured: - * - usage MUST be UNKNOWN or GAME or MEDIA. All other usages CAN NOT be capturable. - * - audio attributes MUST NOT have the FLAG_NO_CAPTURE + * - usage MUST be {@link AudioAttributes#USAGE_UNKNOWN} or {@link AudioAttributes#USAGE_GAME} + * or {@link AudioAttributes#USAGE_MEDIA}. All other usages CAN NOT be captured. + * - audio attributes MUST have its ${@link AudioAttributes.Builder#setAllowedCapturePolicy} + * to {@link AudioAttributes#ALLOW_CAPTURE_BY_ALL}. * - played by apps that MUST be in the same user profile as the capturing app * (eg work profile can not capture user profile apps and vice-versa). - * - played by apps that MUST NOT have in their manifest.xml the application - * attribute android:allowAudioPlaybackCapture="false" - * - played by apps that MUST have a targetSdkVersion higher or equal to 29 (Q). + * - played by apps for which the attribute allowAudioPlaybackCapture in their manifest + * MUST either be: + * * set to "true" + * * not set, and their targetSdkVersion MUST be equal or higher to + * {@link android.os.Build.VERSION_CODES#Q}. * * <p>An example for creating a capture configuration for capturing all media playback: * diff --git a/media/java/android/media/AudioRecord.java b/media/java/android/media/AudioRecord.java index a7760a80974d..2dd7f0fcd12b 100644 --- a/media/java/android/media/AudioRecord.java +++ b/media/java/android/media/AudioRecord.java @@ -25,6 +25,7 @@ import android.annotation.SystemApi; import android.annotation.TestApi; import android.annotation.UnsupportedAppUsage; import android.app.ActivityThread; +import android.media.MediaRecorder.Source; import android.media.audiopolicy.AudioMix; import android.media.audiopolicy.AudioPolicy; import android.media.projection.MediaProjection; @@ -539,7 +540,7 @@ public class AudioRecord implements AudioRouting, MicrophoneDirection, * @return the same Builder instance. * @throws IllegalArgumentException */ - public Builder setAudioSource(int source) throws IllegalArgumentException { + public Builder setAudioSource(@Source int source) throws IllegalArgumentException { Preconditions.checkState( mAudioPlaybackCaptureConfiguration == null, ERROR_MESSAGE_SOURCE_MISMATCH); diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java index ad255fe3d5a2..d105fa3d4587 100644 --- a/media/java/android/media/AudioSystem.java +++ b/media/java/android/media/AudioSystem.java @@ -1022,6 +1022,11 @@ public class AudioSystem public static native float getStreamVolumeDB(int stream, int index, int device); + /** + * @see AudioManager#setAllowedCapturePolicy() + */ + public static native int setAllowedCapturePolicy(int uid, int flags); + static boolean isOffloadSupported(@NonNull AudioFormat format, @NonNull AudioAttributes attr) { return native_is_offload_supported(format.getEncoding(), format.getSampleRate(), format.getChannelMask(), format.getChannelIndexMask(), diff --git a/media/java/android/media/HwAudioSource.java b/media/java/android/media/HwAudioSource.java index e53b7e898c6d..01a02f1d9f05 100644 --- a/media/java/android/media/HwAudioSource.java +++ b/media/java/android/media/HwAudioSource.java @@ -224,14 +224,4 @@ public class HwAudioSource extends PlayerBase { return new HwAudioSource(mAudioDeviceInfo, mAudioAttributes); } } - - /** - * Eliminate {@link #deprecateStreamTypeForPlayback(int, String, String)} in API list. - * TODO: remove this pseudo-override function - * @hide - */ - public static void deprecateStreamTypeForPlayback(int streamType, String className, - String opName) throws IllegalArgumentException { - // Do nothing. - } } diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java index 040152ac9b1d..1937edd69975 100644 --- a/media/java/android/media/MediaPlayer.java +++ b/media/java/android/media/MediaPlayer.java @@ -1103,7 +1103,7 @@ public class MediaPlayer extends PlayerBase setDataSource(afd); return true; } catch (NullPointerException | SecurityException | IOException ex) { - Log.w(TAG, "Couldn't open " + uri == null ? "null uri" : uri.toSafeString(), ex); + Log.w(TAG, "Couldn't open " + (uri == null ? "null uri" : uri.toSafeString()), ex); return false; } } diff --git a/media/java/android/media/MediaRecorder.java b/media/java/android/media/MediaRecorder.java index 575a0bb03f7b..63b22df12953 100644 --- a/media/java/android/media/MediaRecorder.java +++ b/media/java/android/media/MediaRecorder.java @@ -18,6 +18,7 @@ package android.media; import android.annotation.CallbackExecutor; import android.annotation.FloatRange; +import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresPermission; @@ -42,6 +43,8 @@ import java.io.File; import java.io.FileDescriptor; import java.io.IOException; import java.io.RandomAccessFile; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.List; @@ -355,6 +358,22 @@ public class MediaRecorder implements AudioRouting, public static final int HOTWORD = 1999; } + /** @hide */ + @IntDef({ + AudioSource.DEFAULT, + AudioSource.MIC, + AudioSource.VOICE_UPLINK, + AudioSource.VOICE_DOWNLINK, + AudioSource.VOICE_CALL, + AudioSource.CAMCORDER, + AudioSource.VOICE_RECOGNITION, + AudioSource.VOICE_COMMUNICATION, + AudioSource.UNPROCESSED, + AudioSource.VOICE_PERFORMANCE, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface Source {} + // TODO make AudioSource static (API change) and move this method inside the AudioSource class /** * @hide @@ -547,11 +566,11 @@ public class MediaRecorder implements AudioRouting, * to be specified before setting recording-parameters or encoders. Call * this only before setOutputFormat(). * - * @param audio_source the audio source to use + * @param audioSource the audio source to use * @throws IllegalStateException if it is called after setOutputFormat() * @see android.media.MediaRecorder.AudioSource */ - public native void setAudioSource(int audio_source) + public native void setAudioSource(@Source int audioSource) throws IllegalStateException; /** diff --git a/media/tests/MediaFrameworkTest/Android.bp b/media/tests/MediaFrameworkTest/Android.bp new file mode 100644 index 000000000000..f0fbc509cc9d --- /dev/null +++ b/media/tests/MediaFrameworkTest/Android.bp @@ -0,0 +1,14 @@ +android_test { + name: "mediaframeworktest", + srcs: ["**/*.java"], + libs: [ + "android.test.runner", + "android.test.base", + ], + static_libs: [ + "mockito-target-minus-junit4", + "androidx.test.rules", + "android-ex-camera2", + ], + platform_apis: true, +} diff --git a/media/tests/MediaFrameworkTest/Android.mk b/media/tests/MediaFrameworkTest/Android.mk deleted file mode 100644 index 167d255af74c..000000000000 --- a/media/tests/MediaFrameworkTest/Android.mk +++ /dev/null @@ -1,18 +0,0 @@ -LOCAL_PATH:= $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_MODULE_TAGS := tests - -LOCAL_SRC_FILES := $(call all-subdir-java-files) - -LOCAL_JAVA_LIBRARIES := android.test.runner android.test.base - -LOCAL_STATIC_JAVA_LIBRARIES := \ - mockito-target-minus-junit4 \ - androidx.test.rules \ - android-ex-camera2 - -LOCAL_PACKAGE_NAME := mediaframeworktest -LOCAL_PRIVATE_PLATFORM_APIS := true - -include $(BUILD_PACKAGE) diff --git a/media/tests/MtpTests/Android.bp b/media/tests/MtpTests/Android.bp new file mode 100644 index 000000000000..7d2c7c693fa5 --- /dev/null +++ b/media/tests/MtpTests/Android.bp @@ -0,0 +1,6 @@ +android_test { + name: "MtpTests", + srcs: ["**/*.java"], + static_libs: ["androidx.test.rules"], + platform_apis: true, +} diff --git a/media/tests/MtpTests/Android.mk b/media/tests/MtpTests/Android.mk deleted file mode 100644 index 4cee62e7dcbf..000000000000 --- a/media/tests/MtpTests/Android.mk +++ /dev/null @@ -1,13 +0,0 @@ -LOCAL_PATH:= $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_MODULE_TAGS := tests - -LOCAL_SRC_FILES := $(call all-subdir-java-files) - -LOCAL_STATIC_JAVA_LIBRARIES := androidx.test.rules - -LOCAL_PACKAGE_NAME := MtpTests -LOCAL_PRIVATE_PLATFORM_APIS := true - -include $(BUILD_PACKAGE) diff --git a/packages/CaptivePortalLogin/Android.bp b/packages/CaptivePortalLogin/Android.bp index bc614e9fc14c..a345091aa71e 100644 --- a/packages/CaptivePortalLogin/Android.bp +++ b/packages/CaptivePortalLogin/Android.bp @@ -23,6 +23,7 @@ android_app { static_libs: [ "androidx.legacy_legacy-support-v4", "metrics-constants-protos", + "captiveportal-lib", ], manifest: "AndroidManifest.xml", } diff --git a/packages/CaptivePortalLogin/AndroidManifest.xml b/packages/CaptivePortalLogin/AndroidManifest.xml index 44e0a659212a..a5286364dc26 100644 --- a/packages/CaptivePortalLogin/AndroidManifest.xml +++ b/packages/CaptivePortalLogin/AndroidManifest.xml @@ -18,7 +18,7 @@ --> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.captiveportallogin" - android:versionCode="11" + android:versionCode="200000000" android:versionName="Q-initial"> <uses-sdk android:minSdkVersion="28" android:targetSdkVersion="28" /> diff --git a/packages/CarSystemUI/res/layout/car_fullscreen_user_switcher.xml b/packages/CarSystemUI/res/layout/car_fullscreen_user_switcher.xml index 395eac1d2ccb..2fe9d21b0489 100644 --- a/packages/CarSystemUI/res/layout/car_fullscreen_user_switcher.xml +++ b/packages/CarSystemUI/res/layout/car_fullscreen_user_switcher.xml @@ -18,8 +18,7 @@ xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" - android:fitsSystemWindows="true" - android:visibility="gone"> + android:fitsSystemWindows="true"> <LinearLayout android:id="@+id/container" diff --git a/packages/CarSystemUI/res/layout/notification_center_activity.xml b/packages/CarSystemUI/res/layout/notification_center_activity.xml index 383aba4e400a..5c915b874dde 100644 --- a/packages/CarSystemUI/res/layout/notification_center_activity.xml +++ b/packages/CarSystemUI/res/layout/notification_center_activity.xml @@ -19,7 +19,8 @@ xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/notification_view" android:layout_width="match_parent" - android:layout_height="match_parent"> + android:layout_height="match_parent" + android:background="@color/notification_shade_background_color"> <View android:id="@+id/glass_pane" diff --git a/packages/CarSystemUI/res/layout/super_status_bar.xml b/packages/CarSystemUI/res/layout/super_status_bar.xml index 0594dce2ba22..9a074ddd7506 100644 --- a/packages/CarSystemUI/res/layout/super_status_bar.xml +++ b/packages/CarSystemUI/res/layout/super_status_bar.xml @@ -64,7 +64,6 @@ <include layout="@layout/car_top_navigation_bar" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_weight="1" /> </LinearLayout> @@ -80,6 +79,13 @@ android:layout_height="match_parent" android:visibility="invisible"/> + <include layout="@layout/notification_center_activity" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:layout_marginBottom="112dp" + android:visibility="invisible" + /> + <com.android.systemui.statusbar.ScrimView android:id="@+id/scrim_in_front" android:layout_width="match_parent" diff --git a/packages/CarSystemUI/res/values/config.xml b/packages/CarSystemUI/res/values/config.xml index c9f9dead6e81..d946fbc9520a 100644 --- a/packages/CarSystemUI/res/values/config.xml +++ b/packages/CarSystemUI/res/values/config.xml @@ -21,6 +21,7 @@ <string name="config_systemUIFactoryComponent" translatable="false"> com.android.systemui.CarSystemUIFactory </string> + <bool name="config_enableFullscreenUserSwitcher">true</bool> <!-- configure which system ui bars should be displayed --> @@ -28,30 +29,12 @@ <bool name="config_enableRightNavigationBar">false</bool> <bool name="config_enableBottomNavigationBar">true</bool> - <!-- SystemUI Services: The classes of the stuff to start. This is duplicated from core - SystemUi b/c it can't be overlayed at this level for now - --> - <string-array name="config_systemUIServiceComponents" translatable="false"> - <item>com.android.systemui.Dependency$DependencyCreator</item> - <item>com.android.systemui.util.NotificationChannels</item> - <item>com.android.systemui.notifications.NotificationsUI</item> - <item>com.android.systemui.statusbar.CommandQueue$CommandQueueStart</item> - <item>com.android.systemui.keyguard.KeyguardViewMediator</item> - <item>com.android.systemui.recents.Recents</item> - <item>com.android.systemui.volume.VolumeUI</item> - <item>com.android.systemui.stackdivider.Divider</item> - <item>com.android.systemui.SystemBars</item> - <item>com.android.systemui.usb.StorageNotification</item> - <item>com.android.systemui.power.PowerUI</item> - <item>com.android.systemui.media.RingtonePlayer</item> - <item>com.android.systemui.keyboard.KeyboardUI</item> - <item>com.android.systemui.pip.PipUI</item> - <item>com.android.systemui.shortcut.ShortcutKeyDispatcher</item> - <item>@string/config_systemUIVendorServiceComponent</item> - <item>com.android.systemui.util.leak.GarbageMonitor$Service</item> - <item>com.android.systemui.LatencyTester</item> - <item>com.android.systemui.globalactions.GlobalActionsComponent</item> - <item>com.android.systemui.ScreenDecorations</item> - <item>com.android.systemui.SliceBroadcastRelayHandler</item> - </string-array> + <bool name="config_hideNavWhenKeyguardBouncerShown">true</bool> + <bool name="config_enablePersistentDockedActivity">false</bool> + <string name="config_persistentDockedActivityIntentUri" translatable="false"></string> + + <!-- How many icons may be shown at once in the system bar. Includes any + slots that may be reused for things like IME control. --> + <integer name="config_maxNotificationIcons">0</integer> + </resources> diff --git a/packages/CarSystemUI/src/com/android/systemui/notifications/NotificationsUI.java b/packages/CarSystemUI/src/com/android/systemui/notifications/NotificationsUI.java deleted file mode 100644 index 2e2f3b7bea11..000000000000 --- a/packages/CarSystemUI/src/com/android/systemui/notifications/NotificationsUI.java +++ /dev/null @@ -1,469 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.systemui.notifications; - -import android.animation.Animator; -import android.animation.AnimatorListenerAdapter; -import android.animation.ValueAnimator; -import android.annotation.SuppressLint; -import android.app.ActivityManager; -import android.car.Car; -import android.car.CarNotConnectedException; -import android.car.drivingstate.CarUxRestrictionsManager; -import android.content.ComponentName; -import android.content.Context; -import android.content.ServiceConnection; -import android.content.res.Configuration; -import android.graphics.PixelFormat; -import android.os.IBinder; -import android.os.ServiceManager; -import android.util.Log; -import android.view.ContextThemeWrapper; -import android.view.GestureDetector; -import android.view.MotionEvent; -import android.view.View; -import android.view.ViewGroup; -import android.view.ViewTreeObserver; -import android.view.WindowManager; - -import androidx.annotation.NonNull; -import androidx.recyclerview.widget.RecyclerView; - -import com.android.car.notification.CarNotificationListener; -import com.android.car.notification.CarNotificationView; -import com.android.car.notification.CarUxRestrictionManagerWrapper; -import com.android.car.notification.NotificationClickHandlerFactory; -import com.android.car.notification.NotificationViewController; -import com.android.car.notification.PreprocessingManager; -import com.android.internal.statusbar.IStatusBarService; -import com.android.systemui.Dependency; -import com.android.systemui.R; -import com.android.systemui.SystemUI; -import com.android.systemui.statusbar.FlingAnimationUtils; -import com.android.systemui.statusbar.car.CarStatusBar; -import com.android.systemui.statusbar.policy.ConfigurationController; - -/** - * Standalone SystemUI for displaying Notifications that have been designed to be used in the car - */ -public class NotificationsUI extends SystemUI - implements ConfigurationController.ConfigurationListener { - - private static final String TAG = "NotificationsUI"; - // used to calculate how fast to open or close the window - private static final float DEFAULT_FLING_VELOCITY = 0; - // max time a fling animation takes - private static final float FLING_ANIMATION_MAX_TIME = 0.5f; - // acceleration rate for the fling animation - private static final float FLING_SPEED_UP_FACTOR = 0.6f; - private CarNotificationListener mCarNotificationListener; - private CarUxRestrictionsManager mCarUxRestrictionsManager; - private NotificationClickHandlerFactory mClickHandlerFactory; - private Car mCar; - private ViewGroup mCarNotificationWindow; - private NotificationViewController mNotificationViewController; - private boolean mIsShowing; - private boolean mIsTracking; - private boolean mNotificationListAtBottom; - private boolean mNotificationListAtBottomAtTimeOfTouch; - private CarUxRestrictionManagerWrapper mCarUxRestrictionManagerWrapper = - new CarUxRestrictionManagerWrapper(); - // Used in the Notification panel touch listener - private GestureDetector mGestureDetector; - // Used in scrollable content of the notifications - private GestureDetector mScrollUpDetector; - private View mContent; - private View.OnTouchListener mOnTouchListener; - private FlingAnimationUtils mFlingAnimationUtils; - private static int sSettleOpenPercentage; - private static int sSettleClosePercentage; - private CarStatusBar mCarStatusBar; - - /** - * Inits the window that hosts the notifications and establishes the connections - * to the car related services. - */ - @Override - public void start() { - sSettleOpenPercentage = mContext.getResources().getInteger( - R.integer.notification_settle_open_percentage); - sSettleClosePercentage = mContext.getResources().getInteger( - R.integer.notification_settle_close_percentage); - WindowManager windowManager = - (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE); - mFlingAnimationUtils = new FlingAnimationUtils(mContext, - FLING_ANIMATION_MAX_TIME, FLING_SPEED_UP_FACTOR); - mCarNotificationListener = new CarNotificationListener(); - // create a notification click handler that closes the notification ui if the an activity - // is launched successfully - mClickHandlerFactory = new NotificationClickHandlerFactory( - IStatusBarService.Stub.asInterface( - ServiceManager.getService(Context.STATUS_BAR_SERVICE)), - launchResult -> { - if (launchResult == ActivityManager.START_TASK_TO_FRONT - || launchResult == ActivityManager.START_SUCCESS) { - closeCarNotifications(DEFAULT_FLING_VELOCITY); - } - }); - mCarNotificationListener.registerAsSystemService(mContext, mCarUxRestrictionManagerWrapper, - mClickHandlerFactory); - mCar = Car.createCar(mContext, mCarConnectionListener); - mCar.connect(); - NotificationGestureListener gestureListener = new NotificationGestureListener(); - mGestureDetector = new GestureDetector(mContext, gestureListener); - mScrollUpDetector = new GestureDetector(mContext, new ScrollUpDetector()); - mOnTouchListener = new NotificationPanelTouchListener(); - mCarNotificationWindow = (ViewGroup) View.inflate(new ContextThemeWrapper(mContext, - R.style.Theme_Notification), - R.layout.navigation_bar_window, null); - mCarNotificationWindow - .setBackgroundColor(mContext.getColor(R.color.notification_shade_background_color)); - inflateNotificationContent(); - - WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams( - ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, - WindowManager.LayoutParams.TYPE_DISPLAY_OVERLAY, - WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE - | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL - | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH - | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH, - PixelFormat.TRANSLUCENT); - layoutParams.setTitle("Car Notification Window"); - // start in the hidden state - mCarNotificationWindow.setVisibility(View.GONE); - windowManager.addView(mCarNotificationWindow, layoutParams); - - // Add this object to the SystemUI component registry such that the status bar - // can get a reference to it. - putComponent(NotificationsUI.class, this); - Dependency.get(ConfigurationController.class).addCallback(this); - } - - @SuppressLint("ClickableViewAccessibility") - private void inflateNotificationContent() { - if (mNotificationViewController != null) { - mNotificationViewController.disable(); - } - mCarNotificationWindow.removeAllViews(); - - mContent = View.inflate(new ContextThemeWrapper(mContext, - com.android.car.notification.R.style.Theme_Notification), - R.layout.notification_center_activity, - mCarNotificationWindow); - // set the click handler such that we can dismiss the UI when a notification is clicked - CarNotificationView noteView = mCarNotificationWindow.findViewById(R.id.notification_view); - noteView.setClickHandlerFactory(mClickHandlerFactory); - - mContent.setOnTouchListener(mOnTouchListener); - // set initial translation after size is calculated - mContent.getViewTreeObserver().addOnGlobalLayoutListener( - new ViewTreeObserver.OnGlobalLayoutListener() { - @Override - public void onGlobalLayout() { - mContent.getViewTreeObserver().removeOnGlobalLayoutListener(this); - if (!mIsShowing && !mIsTracking) { - mContent.setTranslationY(mContent.getHeight() * -1); - } - } - }); - - RecyclerView notificationList = mCarNotificationWindow.findViewById(R.id.notifications); - // register a scroll listener so we can figure out if we are at the bottom of the - // list of notifications - notificationList.addOnScrollListener(new RecyclerView.OnScrollListener() { - @Override - public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) { - super.onScrolled(recyclerView, dx, dy); - if (!notificationList.canScrollVertically(1)) { - mNotificationListAtBottom = true; - return; - } - mNotificationListAtBottom = false; - mNotificationListAtBottomAtTimeOfTouch = false; - } - }); - // add a touch listener such that when the user scrolls up and they are at the bottom - // of the list we can start the closing of the view. - notificationList.setOnTouchListener(new NotificationListTouchListener()); - - // There's a view installed at a higher z-order such that we can intercept the ACTION_DOWN - // to set the initial click state. - mCarNotificationWindow.findViewById(R.id.glass_pane).setOnTouchListener((v, event) -> { - if (event.getActionMasked() == MotionEvent.ACTION_UP) { - mNotificationListAtBottomAtTimeOfTouch = false; - } - if (event.getActionMasked() == MotionEvent.ACTION_DOWN) { - mNotificationListAtBottomAtTimeOfTouch = mNotificationListAtBottom; - // register the down event with the gesture detectors so then know where the down - // started. This is needed because at this point we don't know which listener - // is going to handle scroll and fling events. - mGestureDetector.onTouchEvent(event); - mScrollUpDetector.onTouchEvent(event); - } - return false; - }); - - mNotificationViewController = new NotificationViewController( - mCarNotificationWindow - .findViewById(com.android.car.notification.R.id.notification_view), - PreprocessingManager.getInstance(mContext), - mCarNotificationListener, - mCarUxRestrictionManagerWrapper); - mNotificationViewController.enable(); - } - - // allows for day night switch - @Override - public void onConfigChanged(Configuration newConfig) { - inflateNotificationContent(); - } - - public void setStatusBar(CarStatusBar carStatusBar) { - mCarStatusBar = carStatusBar; - } - - public View.OnTouchListener getDragDownListener() { - return mOnTouchListener; - } - - /** - * This listener is attached to the notification list UI to intercept gestures if the user - * is scrolling up when the notification list is at the bottom - */ - private class ScrollUpDetector extends GestureDetector.SimpleOnGestureListener { - - @Override - public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { - return distanceY > 0; - } - - @Override - public boolean onSingleTapUp(MotionEvent motionEvent) { - closeCarNotifications(DEFAULT_FLING_VELOCITY); - return false; - } - } - - private class NotificationListTouchListener implements View.OnTouchListener { - - @Override - public boolean onTouch(View v, MotionEvent event) { - // reset mNotificationListAtBottomAtTimeOfTouch here since the "glass pane" will not - // get the up event - if (event.getActionMasked() == MotionEvent.ACTION_UP) { - mNotificationListAtBottomAtTimeOfTouch = false; - } - boolean wasScrolledUp = mScrollUpDetector.onTouchEvent(event); - - if (mIsTracking - || (mNotificationListAtBottomAtTimeOfTouch && mNotificationListAtBottom - && wasScrolledUp)) { - mOnTouchListener.onTouch(v, event); - // touch event should not be propagated further - return true; - } - return false; - } - } - - /** - * Touch listener installed on the notification panel. It is also used by the Nav and StatusBar - */ - private class NotificationPanelTouchListener implements View.OnTouchListener { - - @Override - public boolean onTouch(View v, MotionEvent event) { - boolean consumed = mGestureDetector.onTouchEvent(event); - if (consumed) { - return true; - } - if (!mIsTracking || event.getActionMasked() != MotionEvent.ACTION_UP) { - return false; - } - - float percentFromBottom = - Math.abs(mContent.getTranslationY() / mContent.getHeight()) * 100; - if (mIsShowing) { - if (percentFromBottom < sSettleOpenPercentage) { - // panel started to close but did not cross minimum threshold thus we open - // it back up - openCarNotifications(DEFAULT_FLING_VELOCITY); - return true; - } - // panel was lifted more than the threshold thus we close it the rest of the way - closeCarNotifications(DEFAULT_FLING_VELOCITY); - return true; - } - - if (percentFromBottom > sSettleClosePercentage) { - // panel was only peeked at thus close it back up - closeCarNotifications(DEFAULT_FLING_VELOCITY); - return true; - } - // panel has been open more than threshold thus open it the rest of the way - openCarNotifications(DEFAULT_FLING_VELOCITY); - return true; - - } - } - - /** - * Listener called by mGestureDetector. This will be initiated from the - * NotificationPanelTouchListener - */ - private class NotificationGestureListener extends GestureDetector.SimpleOnGestureListener { - private static final int SWIPE_UP_MIN_DISTANCE = 75; - private static final int SWIPE_DOWN_MIN_DISTANCE = 25; - private static final int SWIPE_MAX_OFF_PATH = 75; - private static final int SWIPE_THRESHOLD_VELOCITY = 200; - - @Override - public boolean onScroll(MotionEvent event1, MotionEvent event2, float distanceX, - float distanceY) { - if (mCarStatusBar == null || !mCarStatusBar.getIsUserSetup()) { - return true; - } - boolean isDown = event1.getY() - event2.getY() < 0; - // CarStatusBar and NavigationBar are identical so avoid the touch if it - // starts from NavigationBar to open. - if (event1.getRawY() > mCarNotificationWindow.getHeight() && isDown - && mCarNotificationWindow.getVisibility() == View.GONE) { - mIsTracking = false; - return true; - } - mIsTracking = true; - mCarNotificationWindow.setVisibility(View.VISIBLE); - - mContent.setTranslationY(Math.min(mContent.getTranslationY() - distanceY, 0)); - if (mContent.getTranslationY() == 0) { - mIsTracking = false; - } - return true; - } - - @Override - public boolean onFling(MotionEvent event1, MotionEvent event2, - float velocityX, float velocityY) { - if (Math.abs(event1.getX() - event2.getX()) > SWIPE_MAX_OFF_PATH - || Math.abs(velocityY) < SWIPE_THRESHOLD_VELOCITY) { - // swipe was not vertical or was not fast enough - return false; - } - - boolean isUp = velocityY < 0; - float distanceDelta = Math.abs(event1.getY() - event2.getY()); - if (isUp && distanceDelta > SWIPE_UP_MIN_DISTANCE) { - // fling up - mIsTracking = false; - closeCarNotifications(Math.abs(velocityY)); - return true; - - } else if (!isUp && distanceDelta > SWIPE_DOWN_MIN_DISTANCE - && (event1.getRawY() < mCarNotificationWindow.getHeight() - || mCarNotificationWindow.getVisibility() == View.VISIBLE)) { - // fling down - mIsTracking = false; - openCarNotifications(velocityY); - return true; - } - - return false; - } - } - - /** - * Connection callback to establish UX Restrictions - */ - private ServiceConnection mCarConnectionListener = new ServiceConnection() { - @Override - public void onServiceConnected(ComponentName name, IBinder service) { - try { - mCarUxRestrictionsManager = (CarUxRestrictionsManager) mCar.getCarManager( - Car.CAR_UX_RESTRICTION_SERVICE); - mCarUxRestrictionManagerWrapper - .setCarUxRestrictionsManager(mCarUxRestrictionsManager); - PreprocessingManager preprocessingManager = PreprocessingManager.getInstance( - mContext); - preprocessingManager - .setCarUxRestrictionManagerWrapper(mCarUxRestrictionManagerWrapper); - } catch (CarNotConnectedException e) { - Log.e(TAG, "Car not connected in CarConnectionListener", e); - } - } - - @Override - public void onServiceDisconnected(ComponentName name) { - Log.e(TAG, "Car service disconnected unexpectedly"); - } - }; - - /** - * Toggles the visibility of the notifications - */ - public void toggleShowingCarNotifications() { - if (mCarNotificationWindow.getVisibility() == View.VISIBLE) { - closeCarNotifications(DEFAULT_FLING_VELOCITY); - return; - } - openCarNotifications(DEFAULT_FLING_VELOCITY); - } - - /** - * Hides the notifications - */ - public void closeCarNotifications(float velocityY) { - float closedTranslation = mContent.getHeight() * -1; - ValueAnimator animator = - ValueAnimator.ofFloat(mContent.getTranslationY(), closedTranslation); - animator.addUpdateListener( - animation -> mContent.setTranslationY((Float) animation.getAnimatedValue())); - mFlingAnimationUtils.apply( - animator, mContent.getTranslationY(), closedTranslation, velocityY); - animator.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - mCarNotificationWindow.setVisibility(View.GONE); - } - }); - animator.start(); - mNotificationViewController.disable(); - mIsShowing = false; - mIsTracking = false; - RecyclerView notificationListView = mCarNotificationWindow.findViewById(R.id.notifications); - notificationListView.scrollToPosition(0); - } - - /** - * Sets the notifications to visible - */ - public void openCarNotifications(float velocityY) { - if (mCarStatusBar == null || !mCarStatusBar.getIsUserSetup()) { - return; - } - mCarNotificationWindow.setVisibility(View.VISIBLE); - - ValueAnimator animator = ValueAnimator.ofFloat(mContent.getTranslationY(), 0); - animator.addUpdateListener( - animation -> mContent.setTranslationY((Float) animation.getAnimatedValue())); - mFlingAnimationUtils.apply(animator, mContent.getTranslationY(), 0, velocityY); - animator.start(); - - mNotificationViewController.enable(); - mIsShowing = true; - mIsTracking = false; - } -} diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarNavigationBarView.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarNavigationBarView.java index afefa1b1fa56..a0f2367c65a4 100644 --- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarNavigationBarView.java +++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarNavigationBarView.java @@ -38,6 +38,7 @@ class CarNavigationBarView extends LinearLayout { private CarStatusBar mCarStatusBar; private Context mContext; private View mLockScreenButtons; + // used to wire in open/close gestures for notifications private OnTouchListener mStatusBarWindowTouchListener; @@ -65,26 +66,45 @@ class CarNavigationBarView extends LinearLayout { mDarkIconManager.setShouldLog(true); Dependency.get(StatusBarIconController.class).addIconGroup(mDarkIconManager); } + // needs to be clickable so that it will receive ACTION_MOVE events + setClickable(true); } + // Used to forward touch events even if the touch was initiated from a child component @Override public boolean onInterceptTouchEvent(MotionEvent ev) { - if (mStatusBarWindowTouchListener == null) { - return false; + if (mStatusBarWindowTouchListener != null) { + // forward touch events to the status bar window so it can add a drag down + // windows if required (Notification shade) + mStatusBarWindowTouchListener.onTouch(this, ev); } - // forward touch events to the status bar window so it can add a drag down - // windows if required (Notification shade) - mStatusBarWindowTouchListener.onTouch(this, ev); - return false; + return super.onInterceptTouchEvent(ev); } + void setStatusBar(CarStatusBar carStatusBar) { mCarStatusBar = carStatusBar; - mStatusBarWindowTouchListener = carStatusBar.getStatusBarWindowTouchListener(); + } + + /** + * Set a touch listener that will be called from onInterceptTouchEvent and onTouchEvent + * + * @param statusBarWindowTouchListener The listener to call from touch and intercept touch + */ + void setStatusBarWindowTouchListener(OnTouchListener statusBarWindowTouchListener) { + mStatusBarWindowTouchListener = statusBarWindowTouchListener; + } + + @Override + public boolean onTouchEvent(MotionEvent event) { + if (mStatusBarWindowTouchListener != null) { + mStatusBarWindowTouchListener.onTouch(this, event); + } + return super.onTouchEvent(event); } protected void onNotificationsClick(View v) { - mCarStatusBar.toggleCarNotifications(); + mCarStatusBar.togglePanel(); } /** diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java index abe9be87fe7b..9bcc1ab90e47 100644 --- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java +++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java @@ -16,17 +16,29 @@ package com.android.systemui.statusbar.car; +import android.app.ActivityManager; import android.app.ActivityTaskManager; import android.car.drivingstate.CarDrivingStateEvent; import android.graphics.PixelFormat; import android.graphics.drawable.Drawable; import android.util.Log; +import android.view.GestureDetector; import android.view.Gravity; +import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.view.ViewGroup.LayoutParams; import android.view.WindowManager; +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.android.car.notification.CarNotificationListener; +import com.android.car.notification.CarNotificationView; +import com.android.car.notification.CarUxRestrictionManagerWrapper; +import com.android.car.notification.NotificationClickHandlerFactory; +import com.android.car.notification.NotificationViewController; +import com.android.car.notification.PreprocessingManager; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.systemui.BatteryMeterView; import com.android.systemui.CarSystemUIFactory; @@ -37,7 +49,6 @@ import com.android.systemui.SystemUIFactory; import com.android.systemui.classifier.FalsingLog; import com.android.systemui.classifier.FalsingManager; import com.android.systemui.fragments.FragmentHostManager; -import com.android.systemui.notifications.NotificationsUI; import com.android.systemui.plugins.qs.QS; import com.android.systemui.qs.car.CarQSFragment; import com.android.systemui.shared.system.ActivityManagerWrapper; @@ -70,7 +81,6 @@ public class CarStatusBar extends StatusBar implements private BatteryMeterView mBatteryMeterView; private Drawable mNotificationPanelBackground; - private ConnectedDeviceSignalController mConnectedDeviceSignalController; private ViewGroup mNavigationBarWindow; private ViewGroup mLeftNavigationBarWindow; private ViewGroup mRightNavigationBarWindow; @@ -90,6 +100,17 @@ public class CarStatusBar extends StatusBar implements private DrivingStateHelper mDrivingStateHelper; private SwitchToGuestTimer mSwitchToGuestTimer; + // The container for the notifications. + private CarNotificationView mNotificationView; + private RecyclerView mNotificationList; + // The state of if the notification list is currently showing the bottom. + private boolean mNotificationListAtBottom; + // Was the notification list at the bottom when the user first touched the screen + private boolean mNotificationListAtBottomAtTimeOfTouch; + // To be attached to the navigation bars such that they can close the notification panel if + // it's open. + private View.OnTouchListener mNavBarNotificationTouchListener; + @Override public void start() { // get the provisioned state before calling the parent class since it's that flow that @@ -223,7 +244,6 @@ public class CarStatusBar extends StatusBar implements * Switch to the keyguard applicable content contained in the nav bars */ private void updateNavBarForKeyguardContent() { - getComponent(NotificationsUI.class).closeCarNotifications(0); if (mNavigationBarView != null) { mNavigationBarView.showKeyguardButtons(); } @@ -255,17 +275,150 @@ public class CarStatusBar extends StatusBar implements // when a device has connected by bluetooth. mBatteryMeterView.setVisibility(View.GONE); }); - addTemperatureViewToController(mStatusBarWindow); + + connectNotificationsUI(); + } + + /** + * Attach the notification listeners and controllers to the UI as well as build all the + * touch listeners needed for opening and closing the notification panel + */ + private void connectNotificationsUI() { + // Attached to the status bar to detect pull down of the notification shade. + GestureDetector openGestureDetector = new GestureDetector(mContext, + new OpenNotificationGestureListener() { + @Override + protected void openNotification() { + animateExpandNotificationsPanel(); + } + }); + // Attached to the notification ui to detect close request of the notification shade. + GestureDetector closeGestureDetector = new GestureDetector(mContext, + new CloseNotificationGestureListener() { + @Override + protected void close() { + animateCollapsePanels(); + } + }); + // Attached to the NavBars to close the notification shade + GestureDetector navBarCloseNotificationGestureDetector = new GestureDetector(mContext, + new NavBarCloseNotificationGestureListener() { + @Override + protected void close() { + animateCollapsePanels(); + } + }); + mNavBarNotificationTouchListener = + (v, event) -> navBarCloseNotificationGestureDetector.onTouchEvent(event); + // The following are the ui elements that the user would call the status bar. // This will set the status bar so it they can make call backs. CarNavigationBarView topBar = mStatusBarWindow.findViewById(R.id.car_top_bar); topBar.setStatusBar(this); - CarNavigationBarView qsTopBar = mStatusBarWindow.findViewById(R.id.qs_car_top_bar); - qsTopBar.setStatusBar(this); - getComponent(NotificationsUI.class).setStatusBar(this); + topBar.setStatusBarWindowTouchListener((v1, event1) -> + openGestureDetector.onTouchEvent(event1)); + + NotificationClickHandlerFactory clickHandlerFactory = new NotificationClickHandlerFactory( + mBarService, + launchResult -> { + if (launchResult == ActivityManager.START_TASK_TO_FRONT + || launchResult == ActivityManager.START_SUCCESS) { + animateCollapsePanels(); + } + }); + CarNotificationListener carNotificationListener = new CarNotificationListener(); + CarUxRestrictionManagerWrapper carUxRestrictionManagerWrapper = + new CarUxRestrictionManagerWrapper(); + carNotificationListener.registerAsSystemService(mContext, carUxRestrictionManagerWrapper, + clickHandlerFactory); + + mNotificationView = mStatusBarWindow.findViewById(R.id.notification_view); + View glassPane = mStatusBarWindow.findViewById(R.id.glass_pane); + mNotificationView.setClickHandlerFactory(clickHandlerFactory); + + // The glass pane is used to view touch events before passed to the notification list. + // This allows us to initialize gesture listeners and detect when to close the notifications + glassPane.setOnTouchListener((v, event) -> { + if (event.getActionMasked() == MotionEvent.ACTION_UP) { + mNotificationListAtBottomAtTimeOfTouch = false; + } + if (event.getActionMasked() == MotionEvent.ACTION_DOWN) { + mNotificationListAtBottomAtTimeOfTouch = mNotificationListAtBottom; + // Pass the down event to gesture detector so that it knows where the touch event + // started. + closeGestureDetector.onTouchEvent(event); + } + return false; + }); + mNotificationList = mNotificationView.findViewById(R.id.notifications); + mNotificationList.addOnScrollListener(new RecyclerView.OnScrollListener() { + @Override + public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) { + super.onScrolled(recyclerView, dx, dy); + if (!mNotificationList.canScrollVertically(1)) { + mNotificationListAtBottom = true; + return; + } + mNotificationListAtBottom = false; + mNotificationListAtBottomAtTimeOfTouch = false; + } + }); + mNotificationList.setOnTouchListener(new View.OnTouchListener() { + @Override + public boolean onTouch(View v, MotionEvent event) { + boolean handled = false; + if (mNotificationListAtBottomAtTimeOfTouch && mNotificationListAtBottom) { + handled = closeGestureDetector.onTouchEvent(event); + } + // Updating the mNotificationListAtBottomAtTimeOfTouch state has to be done after + // the event has been passed to the closeGestureDetector above, such that the + // closeGestureDetector sees the up event before the state has changed. + if (event.getActionMasked() == MotionEvent.ACTION_UP) { + mNotificationListAtBottomAtTimeOfTouch = false; + } + return handled; + } + }); + + NotificationViewController mNotificationViewController = new NotificationViewController( + mNotificationView, + PreprocessingManager.getInstance(mContext), + carNotificationListener, + carUxRestrictionManagerWrapper); + mNotificationViewController.enable(); } @Override + public void animateExpandNotificationsPanel() { + if (!mCommandQueue.panelsEnabled() || !mUserSetup) { + return; + } + // scroll to top + mNotificationList.scrollToPosition(0); + mStatusBarWindowController.setPanelVisible(true); + mNotificationView.setVisibility(View.VISIBLE); + // let the status bar know that the panel is open + setPanelExpanded(true); + } + + @Override + public void animateCollapsePanels(int flags, boolean force, boolean delayed, + float speedUpFactor) { + super.animateCollapsePanels(flags, force, delayed, speedUpFactor); + if (!mPanelExpanded || mNotificationView.getVisibility() == View.INVISIBLE) { + return; + } + mStatusBarWindowController.setStatusBarFocusable(false); + mStatusBarWindow.cancelExpandHelper(); + mStatusBarView.collapsePanel(true /* animate */, delayed, speedUpFactor); + mStatusBarWindowController.setPanelVisible(false); + mNotificationView.setVisibility(View.INVISIBLE); + // let the status bar know that the panel is cloased + setPanelExpanded(false); + } + + + @Override protected QS createDefaultQSFragment() { return new CarQSFragment(); } @@ -338,8 +491,8 @@ public class CarStatusBar extends StatusBar implements lp.setTitle("CarNavigationBar"); lp.windowAnimations = 0; mWindowManager.addView(mNavigationBarWindow, lp); - mNavigationBarWindow.setOnTouchListener(getStatusBarWindowTouchListener()); } + if (mShowLeft) { int width = mContext.getResources().getDimensionPixelSize( R.dimen.car_left_navigation_bar_width); @@ -389,6 +542,7 @@ public class CarStatusBar extends StatusBar implements } mNavigationBarView.setStatusBar(this); addTemperatureViewToController(mNavigationBarView); + mNavigationBarView.setStatusBarWindowTouchListener(mNavBarNotificationTouchListener); } private void buildLeft(int layout) { @@ -400,6 +554,7 @@ public class CarStatusBar extends StatusBar implements } mLeftNavigationBarView.setStatusBar(this); addTemperatureViewToController(mLeftNavigationBarView); + mLeftNavigationBarView.setStatusBarWindowTouchListener(mNavBarNotificationTouchListener); } @@ -412,6 +567,7 @@ public class CarStatusBar extends StatusBar implements } mRightNavigationBarView.setStatusBar(this); addTemperatureViewToController(mRightNavigationBarView); + mRightNavigationBarView.setStatusBarWindowTouchListener(mNavBarNotificationTouchListener); } @Override @@ -435,8 +591,6 @@ public class CarStatusBar extends StatusBar implements pw.println(mCarBatteryController); pw.print(" mBatteryMeterView="); pw.println(mBatteryMeterView); - pw.print(" mConnectedDeviceSignalController="); - pw.println(mConnectedDeviceSignalController); pw.print(" mNavigationBarView="); pw.println(mNavigationBarView); @@ -456,11 +610,6 @@ public class CarStatusBar extends StatusBar implements } } - @Override - protected View.OnTouchListener getStatusBarWindowTouchListener() { - // Gets the car specific notification touch listener - return getComponent(NotificationsUI.class).getDragDownListener(); - } @Override public void showBatteryView() { @@ -585,15 +734,6 @@ public class CarStatusBar extends StatusBar implements true /* dismissShade */, true /* afterKeyguardGone */, true /* deferred */); } - @Override - public void animateExpandNotificationsPanel() { - // Because space is usually constrained in the auto use-case, there should not be a - // pinned notification when the shade has been expanded. Ensure this by removing all heads- - // up notifications. - mHeadsUpManager.releaseAllImmediately(); - super.animateExpandNotificationsPanel(); - } - /** * Ensures that relevant child views are appropriately recreated when the device's density * changes. @@ -620,12 +760,73 @@ public class CarStatusBar extends StatusBar implements return mUserSetup; } - public void toggleCarNotifications() { - getComponent(NotificationsUI.class).toggleShowingCarNotifications(); + + // TODO: add settle down/up logic + private static final int SWIPE_UP_MIN_DISTANCE = 75; + private static final int SWIPE_DOWN_MIN_DISTANCE = 25; + private static final int SWIPE_MAX_OFF_PATH = 75; + private static final int SWIPE_THRESHOLD_VELOCITY = 200; + // Only responsible for open hooks. Since once the panel opens it covers all elements + // there is no need to merge with close. + private abstract class OpenNotificationGestureListener extends + GestureDetector.SimpleOnGestureListener { + + @Override + public boolean onFling(MotionEvent event1, MotionEvent event2, + float velocityX, float velocityY) { + if (Math.abs(event1.getX() - event2.getX()) > SWIPE_MAX_OFF_PATH + || Math.abs(velocityY) < SWIPE_THRESHOLD_VELOCITY) { + // swipe was not vertical or was not fast enough + return false; + } + boolean isDown = velocityY > 0; + float distanceDelta = Math.abs(event1.getY() - event2.getY()); + if (isDown && distanceDelta > SWIPE_DOWN_MIN_DISTANCE) { + openNotification(); + return true; + } + + return false; + } + protected abstract void openNotification(); } - @Override - public void maybeEscalateHeadsUp() { - // Never send full screen intent in car. + // to be installed on the open panel notification panel + private abstract class CloseNotificationGestureListener extends + GestureDetector.SimpleOnGestureListener { + + @Override + public boolean onFling(MotionEvent event1, MotionEvent event2, + float velocityX, float velocityY) { + if (Math.abs(event1.getX() - event2.getX()) > SWIPE_MAX_OFF_PATH + || Math.abs(velocityY) < SWIPE_THRESHOLD_VELOCITY) { + // swipe was not vertical or was not fast enough + return false; + } + boolean isUp = velocityY < 0; + float distanceDelta = Math.abs(event1.getY() - event2.getY()); + if (isUp && distanceDelta > SWIPE_UP_MIN_DISTANCE) { + close(); + return true; + } + return false; + } + protected abstract void close(); + } + + // to be installed on the nav bars + private abstract class NavBarCloseNotificationGestureListener extends + CloseNotificationGestureListener { + @Override + public boolean onSingleTapUp(MotionEvent e) { + close(); + return super.onSingleTapUp(e); + } + + @Override + public void onLongPress(MotionEvent e) { + close(); + super.onLongPress(e); + } } } diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java index f896cf1bf10c..0a167d9acf98 100644 --- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java +++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java @@ -38,7 +38,9 @@ public class FullscreenUserSwitcher { public FullscreenUserSwitcher(CarStatusBar statusBar, ViewStub containerStub, Context context) { mStatusBar = statusBar; mParent = containerStub.inflate(); - mParent.setVisibility(View.VISIBLE); + // Hide the user grid by default. It will only be made visible by clicking on a cancel + // button in a bouncer. + hide(); View container = mParent.findViewById(R.id.container); // Initialize user grid. @@ -49,10 +51,6 @@ public class FullscreenUserSwitcher { mUserGridView.buildAdapter(); mUserGridView.setUserSelectionListener(this::onUserSelected); - // Hide the user grid by default. It will only be made visible by clicking on a cancel - // button in a bouncer. - hide(); - mShortAnimDuration = container.getResources() .getInteger(android.R.integer.config_shortAnimTime); } @@ -61,21 +59,21 @@ public class FullscreenUserSwitcher { * Makes user grid visible. */ public void show() { - mUserGridView.setVisibility(View.VISIBLE); + mParent.setVisibility(View.VISIBLE); } /** * Hides the user grid. */ public void hide() { - mUserGridView.setVisibility(View.INVISIBLE); + mParent.setVisibility(View.INVISIBLE); } /** * @return {@code true} if user grid is visible, {@code false} otherwise. */ public boolean isVisible() { - return mUserGridView.getVisibility() == View.VISIBLE; + return mParent.getVisibility() == View.VISIBLE; } /** diff --git a/packages/ExtServices/AndroidManifest.xml b/packages/ExtServices/AndroidManifest.xml index 76e2fe7f3956..45a59a32ec17 100644 --- a/packages/ExtServices/AndroidManifest.xml +++ b/packages/ExtServices/AndroidManifest.xml @@ -17,7 +17,7 @@ <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:androidprv="http://schemas.android.com/apk/prv/res/android" package="android.ext.services" - android:versionCode="1" + android:versionCode="200000000" android:versionName="1" coreApp="true"> @@ -26,6 +26,7 @@ <uses-permission android:name="android.permission.MONITOR_DEFAULT_SMS_PACKAGE" /> <uses-permission android:name="android.permission.REQUEST_NOTIFICATION_ASSISTANT_SERVICE" /> + <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-sdk android:targetSdkVersion="28" @@ -78,6 +79,13 @@ </intent-filter> </service> + <service android:name=".watchdog.ExplicitHealthCheckServiceImpl" + android:permission="android.permission.BIND_EXPLICIT_HEALTH_CHECK_SERVICE"> + <intent-filter> + <action android:name="android.service.watchdog.ExplicitHealthCheckService" /> + </intent-filter> + </service> + <activity android:name=".notification.CopyCodeActivity" android:exported="false" android:theme="@android:style/Theme.NoDisplay"/> diff --git a/packages/ExtServices/src/android/ext/services/watchdog/ExplicitHealthCheckServiceImpl.java b/packages/ExtServices/src/android/ext/services/watchdog/ExplicitHealthCheckServiceImpl.java new file mode 100644 index 000000000000..040e2ab26874 --- /dev/null +++ b/packages/ExtServices/src/android/ext/services/watchdog/ExplicitHealthCheckServiceImpl.java @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.ext.services.watchdog; + +import android.content.ComponentName; +import android.content.Intent; +import android.service.watchdog.ExplicitHealthCheckService; +import android.util.Log; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * Routes explicit health check requests to the appropriate {@link ExplicitHealthChecker}. + */ +public final class ExplicitHealthCheckServiceImpl extends ExplicitHealthCheckService { + private static final String TAG = "ExplicitHealthCheckServiceImpl"; + // TODO: Add build dependency on NetworkStack stable AIDL so we can stop hard coding class name + private static final String NETWORK_STACK_CONNECTOR_CLASS = + "android.net.INetworkStackConnector"; + // Modified only #onCreate, using concurrent collection to ensure thread visibility + private final Map<String, ExplicitHealthChecker> mSupportedCheckers = new ConcurrentHashMap<>(); + + @Override + public void onCreate() { + super.onCreate(); + initHealthCheckers(); + } + + @Override + public void onRequestHealthCheck(String packageName) { + ExplicitHealthChecker checker = mSupportedCheckers.get(packageName); + if (checker != null) { + checker.request(); + } else { + Log.w(TAG, "Ignoring request for explicit health check for unsupported package " + + packageName); + } + } + + @Override + public void onCancelHealthCheck(String packageName) { + ExplicitHealthChecker checker = mSupportedCheckers.get(packageName); + if (checker != null) { + checker.cancel(); + } else { + Log.w(TAG, "Ignoring request to cancel explicit health check for unsupported package " + + packageName); + } + } + + @Override + public List<String> onGetSupportedPackages() { + return new ArrayList<>(mSupportedCheckers.keySet()); + } + + @Override + public List<String> onGetRequestedPackages() { + List<String> packages = new ArrayList<>(); + Iterator<ExplicitHealthChecker> it = mSupportedCheckers.values().iterator(); + // Could potentially race, where we read a checker#isPending and it changes before we + // return list. However, if it races and it is in the list, the caller might call #cancel + // which would fail, but that is fine. If it races and it ends up *not* in the list, it was + // already cancelled, so there's no need for the caller to cancel it + while (it.hasNext()) { + ExplicitHealthChecker checker = it.next(); + if (checker.isPending()) { + packages.add(checker.getPackageName()); + } + } + return packages; + } + + private void initHealthCheckers() { + Intent intent = new Intent(NETWORK_STACK_CONNECTOR_CLASS); + ComponentName comp = intent.resolveSystemService(getPackageManager(), 0); + if (comp != null) { + String networkStackPackageName = comp.getPackageName(); + mSupportedCheckers.put(networkStackPackageName, + new NetworkChecker(this, networkStackPackageName)); + } else { + // On Go devices, or any device that does not ship the network stack module. + // The network stack will live in system_server process, so no need to monitor. + Log.i(TAG, "Network stack module not found"); + } + } +} diff --git a/packages/ExtServices/src/android/ext/services/watchdog/ExplicitHealthChecker.java b/packages/ExtServices/src/android/ext/services/watchdog/ExplicitHealthChecker.java new file mode 100644 index 000000000000..650878e43d7c --- /dev/null +++ b/packages/ExtServices/src/android/ext/services/watchdog/ExplicitHealthChecker.java @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.ext.services.watchdog; + +/** + * A type of explicit health check that can be performed on a device, e.g network health check + */ +interface ExplicitHealthChecker { + /** + * Requests a checker to listen to explicit health checks for {@link #getPackageName}. + * {@link #isPending} will now return {@code true}. + */ + void request(); + + /** + * Cancels a pending explicit health check request for {@link #getPackageName}. + * {@link #isPending} will now return {@code false}. + */ + void cancel(); + + /** + * Returns {@code true} if a request is pending, {@code false} otherwise. + */ + boolean isPending(); + + /** + * Returns the package name this checker can make requests for. + */ + String getPackageName(); +} diff --git a/packages/ExtServices/src/android/ext/services/watchdog/NetworkChecker.java b/packages/ExtServices/src/android/ext/services/watchdog/NetworkChecker.java new file mode 100644 index 000000000000..32375e6a9bbc --- /dev/null +++ b/packages/ExtServices/src/android/ext/services/watchdog/NetworkChecker.java @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.ext.services.watchdog; + +import android.net.ConnectivityManager; +import android.net.Network; +import android.net.NetworkCapabilities; +import android.net.NetworkRequest; +import android.service.watchdog.ExplicitHealthCheckService; + +import com.android.internal.annotations.GuardedBy; + +/** + * Observes the network stack via the ConnectivityManager. + */ +final class NetworkChecker extends ConnectivityManager.NetworkCallback + implements ExplicitHealthChecker { + private static final String TAG = "NetworkChecker"; + + private final Object mLock = new Object(); + private final ExplicitHealthCheckService mService; + private final String mPackageName; + @GuardedBy("mLock") + private boolean mIsPending; + + NetworkChecker(ExplicitHealthCheckService service, String packageName) { + mService = service; + mPackageName = packageName; + } + + @Override + public void request() { + synchronized (mLock) { + if (mIsPending) { + return; + } + mService.getSystemService(ConnectivityManager.class).registerNetworkCallback( + new NetworkRequest.Builder().build(), this); + mIsPending = true; + } + } + + @Override + public void cancel() { + synchronized (mLock) { + if (!mIsPending) { + return; + } + mService.getSystemService(ConnectivityManager.class).unregisterNetworkCallback(this); + mIsPending = false; + } + } + + @Override + public boolean isPending() { + synchronized (mLock) { + return mIsPending; + } + } + + @Override + public String getPackageName() { + return mPackageName; + } + + // TODO(b/120598832): Also monitor NetworkCallback#onAvailable to see if we have any + // available networks that may be unusable. This could be additional signal to our heuristics + @Override + public void onCapabilitiesChanged(Network network, NetworkCapabilities capabilities) { + synchronized (mLock) { + if (mIsPending + && capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)) { + mService.notifyHealthCheckPassed(mPackageName); + cancel(); + } + } + } +} diff --git a/packages/NetworkStackPermissionStub/Android.bp b/packages/NetworkPermissionConfig/Android.bp index 8cee92e5fe6d..d0d3276c0e32 100644 --- a/packages/NetworkStackPermissionStub/Android.bp +++ b/packages/NetworkPermissionConfig/Android.bp @@ -16,7 +16,7 @@ // Stub APK to define permissions for NetworkStack android_app { - name: "NetworkStackPermissionStub", + name: "NetworkPermissionConfig", // TODO: mark app as hasCode=false in manifest once soong stops complaining about apps without // a classes.dex. srcs: ["src/**/*.java"], diff --git a/packages/NetworkStackPermissionStub/AndroidManifest.xml b/packages/NetworkPermissionConfig/AndroidManifest.xml index e83f0503d280..34f987c8f0d4 100644 --- a/packages/NetworkStackPermissionStub/AndroidManifest.xml +++ b/packages/NetworkPermissionConfig/AndroidManifest.xml @@ -17,7 +17,7 @@ */ --> <manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.android.networkstack.permissionstub" + package="com.android.networkstack.permissionconfig" android:sharedUserId="android.uid.networkstack" android:versionCode="11" android:versionName="Q-initial"> @@ -36,5 +36,5 @@ <permission android:name="android.permission.MAINLINE_NETWORK_STACK" android:protectionLevel="signature"/> - <application android:name="com.android.server.NetworkStackPermissionStub"/> + <application android:name="com.android.server.NetworkPermissionConfig"/> </manifest> diff --git a/packages/NetworkStackPermissionStub/src/com/android/server/NetworkStackPermissionStub.java b/packages/NetworkPermissionConfig/src/com/android/server/NetworkPermissionConfig.java index 01e59d28d995..c904e2363689 100644 --- a/packages/NetworkStackPermissionStub/src/com/android/server/NetworkStackPermissionStub.java +++ b/packages/NetworkPermissionConfig/src/com/android/server/NetworkPermissionConfig.java @@ -19,8 +19,8 @@ package com.android.server; import android.app.Application; /** - * Empty application for NetworkStackStub that only exists because soong builds complain if APKs - * have no source file. + * Empty application for NetworkPermissionConfig that only exists because + * soong builds complain if APKs have no source file. */ -public class NetworkStackPermissionStub extends Application { +public class NetworkPermissionConfig extends Application { } diff --git a/packages/NetworkStack/Android.bp b/packages/NetworkStack/Android.bp index 0bd5c5f59133..57a3db586c53 100644 --- a/packages/NetworkStack/Android.bp +++ b/packages/NetworkStack/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +java_library { + name: "captiveportal-lib", + srcs: ["common/**/*.java"], + libs: [ + "androidx.annotation_annotation", + ], + sdk_version: "system_current", +} + java_defaults { name: "NetworkStackCommon", sdk_version: "system_current", @@ -35,6 +44,7 @@ android_library { "networkstack-aidl-interfaces-java", "datastallprotosnano", "networkstackprotosnano", + "captiveportal-lib", ], manifest: "AndroidManifestBase.xml", } @@ -53,7 +63,7 @@ java_defaults { proguard_flags_files: ["proguard.flags"], }, // The permission configuration *must* be included to ensure security of the device - required: ["NetworkStackPermissionStub"], + required: ["NetworkPermissionConfig"], } // Non-updatable network stack running in the system server process for devices not using the module diff --git a/packages/NetworkStack/AndroidManifest.xml b/packages/NetworkStack/AndroidManifest.xml index b0a7923d65f4..b4588e01dc79 100644 --- a/packages/NetworkStack/AndroidManifest.xml +++ b/packages/NetworkStack/AndroidManifest.xml @@ -17,9 +17,28 @@ */ --> <manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.android.networkstack" - android:sharedUserId="android.uid.networkstack"> + package="com.android.networkstack" + android:sharedUserId="android.uid.networkstack" + android:versionCode="200000000" + android:versionName="29 system image" +> + <uses-sdk android:minSdkVersion="28" android:targetSdkVersion="28" /> + + <!-- Permissions must be defined here, and not in the base manifest, as the network stack + running in the system server process does not need any permission, and having privileged + permissions added would cause crashes on startup unless they are also added to the + privileged permissions whitelist for that package. --> + <uses-permission android:name="android.permission.INTERNET" /> + <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> + <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> + <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> + <uses-permission android:name="android.permission.CONNECTIVITY_INTERNAL" /> + <!-- Send latency broadcast as current user --> + <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" /> + <uses-permission android:name="android.permission.WAKE_LOCK" /> + <uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE" /> + <uses-permission android:name="android.permission.READ_DEVICE_CONFIG" /> <!-- Signature permission defined in NetworkStackStub --> <uses-permission android:name="android.permission.MAINLINE_NETWORK_STACK" /> <application> diff --git a/packages/NetworkStack/AndroidManifestBase.xml b/packages/NetworkStack/AndroidManifestBase.xml index f69e4b2bb795..d00a55143605 100644 --- a/packages/NetworkStack/AndroidManifestBase.xml +++ b/packages/NetworkStack/AndroidManifestBase.xml @@ -20,19 +20,14 @@ package="com.android.networkstack" android:versionCode="11" android:versionName="Q-initial"> - <uses-permission android:name="android.permission.INTERNET" /> - <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> - <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> - <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> - <uses-permission android:name="android.permission.CONNECTIVITY_INTERNAL" /> - <!-- Send latency broadcast as current user --> - <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" /> - <uses-permission android:name="android.permission.WAKE_LOCK" /> - <uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE" /> <application android:label="NetworkStack" android:defaultToDeviceProtectedStorage="true" android:directBootAware="true" android:usesCleartextTraffic="true"> + + <service android:name="com.android.server.connectivity.ipmemorystore.RegularMaintenanceJobService" + android:permission="android.permission.BIND_JOB_SERVICE" > + </service> </application> </manifest> diff --git a/core/java/android/net/captiveportal/CaptivePortalProbeResult.java b/packages/NetworkStack/common/CaptivePortalProbeResult.java index a1d3de248a96..48cd48b30085 100644 --- a/core/java/android/net/captiveportal/CaptivePortalProbeResult.java +++ b/packages/NetworkStack/common/CaptivePortalProbeResult.java @@ -16,17 +16,13 @@ package android.net.captiveportal; -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.annotation.SystemApi; -import android.annotation.TestApi; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; /** * Result of calling isCaptivePortal(). * @hide */ -@SystemApi -@TestApi public final class CaptivePortalProbeResult { public static final int SUCCESS_CODE = 204; public static final int FAILED_CODE = 599; diff --git a/core/java/android/net/captiveportal/CaptivePortalProbeSpec.java b/packages/NetworkStack/common/CaptivePortalProbeSpec.java index 6c6a16c4534e..bf983a50ab51 100644 --- a/core/java/android/net/captiveportal/CaptivePortalProbeSpec.java +++ b/packages/NetworkStack/common/CaptivePortalProbeSpec.java @@ -19,16 +19,12 @@ package android.net.captiveportal; import static android.net.captiveportal.CaptivePortalProbeResult.PORTAL_CODE; import static android.net.captiveportal.CaptivePortalProbeResult.SUCCESS_CODE; -import static com.android.internal.util.Preconditions.checkNotNull; - -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.annotation.SystemApi; -import android.annotation.TestApi; import android.text.TextUtils; import android.util.Log; -import com.android.internal.annotations.VisibleForTesting; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.VisibleForTesting; import java.net.MalformedURLException; import java.net.URL; @@ -40,8 +36,6 @@ import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; /** @hide */ -@SystemApi -@TestApi public abstract class CaptivePortalProbeSpec { private static final String TAG = CaptivePortalProbeSpec.class.getSimpleName(); private static final String REGEX_SEPARATOR = "@@/@@"; @@ -50,8 +44,7 @@ public abstract class CaptivePortalProbeSpec { private final String mEncodedSpec; private final URL mUrl; - CaptivePortalProbeSpec(@NonNull String encodedSpec, @NonNull URL url) - throws NullPointerException { + CaptivePortalProbeSpec(@NonNull String encodedSpec, @NonNull URL url) { mEncodedSpec = checkNotNull(encodedSpec); mUrl = checkNotNull(url); } @@ -193,4 +186,10 @@ public abstract class CaptivePortalProbeSpec { // No value is a match ("no location header" passes the location rule for non-redirects) return pattern == null || TextUtils.isEmpty(value) || pattern.matcher(value).matches(); } + + // Throws NullPointerException if the input is null. + private static <T> T checkNotNull(T object) { + if (object == null) throw new NullPointerException(); + return object; + } } diff --git a/packages/NetworkStack/src/android/net/apf/ApfFilter.java b/packages/NetworkStack/src/android/net/apf/ApfFilter.java index 3dd90eeff767..d2f32591cbbe 100644 --- a/packages/NetworkStack/src/android/net/apf/ApfFilter.java +++ b/packages/NetworkStack/src/android/net/apf/ApfFilter.java @@ -74,6 +74,7 @@ import java.net.SocketException; import java.net.UnknownHostException; import java.nio.BufferUnderflowException; import java.nio.ByteBuffer; +import java.nio.ByteOrder; import java.util.ArrayList; import java.util.Arrays; @@ -282,6 +283,7 @@ public class ApfFilter { private static final byte[] ETH_BROADCAST_MAC_ADDRESS = {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff }; // TODO: Make these offsets relative to end of link-layer header; don't include ETH_HEADER_LEN. + private static final int IPV4_TOTAL_LENGTH_OFFSET = ETH_HEADER_LEN + 2; private static final int IPV4_FRAGMENT_OFFSET_OFFSET = ETH_HEADER_LEN + 6; // Endianness is not an issue for this constant because the APF interpreter always operates in // network byte order. @@ -881,10 +883,23 @@ public class ApfFilter { protected final TcpKeepaliveAckData mPacket; protected final byte[] mSrcDstAddr; + protected final byte[] mPortSeqAckFingerprint; TcpKeepaliveAck(final TcpKeepaliveAckData packet, final byte[] srcDstAddr) { mPacket = packet; mSrcDstAddr = srcDstAddr; + mPortSeqAckFingerprint = generatePortSeqAckFingerprint(mPacket.srcPort, + mPacket.dstPort, mPacket.seq, mPacket.ack); + } + + static byte[] generatePortSeqAckFingerprint(int srcPort, int dstPort, int seq, int ack) { + final ByteBuffer fp = ByteBuffer.allocate(12); + fp.order(ByteOrder.BIG_ENDIAN); + fp.putShort((short) srcPort); + fp.putShort((short) dstPort); + fp.putInt(seq); + fp.putInt(ack); + return fp.array(); } static byte[] concatArrays(final byte[]... arr) { @@ -919,10 +934,6 @@ public class ApfFilter { private class TcpKeepaliveAckV4 extends TcpKeepaliveAck { private static final int IPV4_SRC_ADDR_OFFSET = IP_HEADER_OFFSET + 12; - private static final int IPV4_TCP_SRC_PORT_OFFSET = 0; - private static final int IPV4_TCP_DST_PORT_OFFSET = 2; - private static final int IPV4_TCP_SEQ_OFFSET = 4; - private static final int IPV4_TCP_ACK_OFFSET = 8; TcpKeepaliveAckV4(final TcpKeepalivePacketDataParcelable sentKeepalivePacket) { this(new TcpKeepaliveAckData(sentKeepalivePacket)); @@ -934,12 +945,12 @@ public class ApfFilter { @Override void generateFilterLocked(ApfGenerator gen) throws IllegalInstructionException { final String nextFilterLabel = "keepalive_ack" + getUniqueNumberLocked(); - gen.addLoad8(Register.R0, IPV4_PROTOCOL_OFFSET); - gen.addJumpIfR0NotEquals(IPPROTO_TCP, nextFilterLabel); + gen.addLoadImmediate(Register.R0, ETH_HEADER_LEN + IPV4_SRC_ADDR_OFFSET); gen.addJumpIfBytesNotEqual(Register.R0, mSrcDstAddr, nextFilterLabel); - // Pass the packet if it's not zero-sized : + // Skip to the next filter if it's not zero-sized : + // TCP_HEADER_SIZE + IPV4_HEADER_SIZE - ipv4_total_length == 0 // Load the IP header size into R1 gen.addLoadFromMemory(Register.R1, gen.IPV4_HEADER_SIZE_MEMORY_SLOT); // Load the TCP header size into R0 (it's indexed by R1) @@ -947,27 +958,18 @@ public class ApfFilter { // Size offset is in the top nibble, but it must be multiplied by 4, and the two // top bits of the low nibble are guaranteed to be zeroes. Right-shift R0 by 2. gen.addRightShift(2); - // R0 += R1 -> R0 contains TCP + IP headers lenght - gen.addAddR1(); - // Add the Ethernet header length to R0. - gen.addLoadImmediate(Register.R1, ETH_HEADER_LEN); + // R0 += R1 -> R0 contains TCP + IP headers length gen.addAddR1(); - // Compare total length of headers to the size of the packet. - gen.addLoadFromMemory(Register.R1, gen.PACKET_SIZE_MEMORY_SLOT); + // Load IPv4 total length + gen.addLoad16(Register.R1, IPV4_TOTAL_LENGTH_OFFSET); gen.addNeg(Register.R0); gen.addAddR1(); gen.addJumpIfR0NotEquals(0, nextFilterLabel); - // Add IPv4 header length gen.addLoadFromMemory(Register.R1, gen.IPV4_HEADER_SIZE_MEMORY_SLOT); - gen.addLoad16Indexed(Register.R0, ETH_HEADER_LEN + IPV4_TCP_SRC_PORT_OFFSET); - gen.addJumpIfR0NotEquals(mPacket.srcPort, nextFilterLabel); - gen.addLoad16Indexed(Register.R0, ETH_HEADER_LEN + IPV4_TCP_DST_PORT_OFFSET); - gen.addJumpIfR0NotEquals(mPacket.dstPort, nextFilterLabel); - gen.addLoad32Indexed(Register.R0, ETH_HEADER_LEN + IPV4_TCP_SEQ_OFFSET); - gen.addJumpIfR0NotEquals(mPacket.seq, nextFilterLabel); - gen.addLoad32Indexed(Register.R0, ETH_HEADER_LEN + IPV4_TCP_ACK_OFFSET); - gen.addJumpIfR0NotEquals(mPacket.ack, nextFilterLabel); + gen.addLoadImmediate(Register.R0, ETH_HEADER_LEN); + gen.addAddR1(); + gen.addJumpIfBytesNotEqual(Register.R0, mPortSeqAckFingerprint, nextFilterLabel); maybeSetupCounter(gen, Counter.DROPPED_IPV4_KEEPALIVE_ACK); gen.addJump(mCountAndDropLabel); @@ -1169,9 +1171,10 @@ public class ApfFilter { gen.addJumpIfR0Equals(broadcastAddr, mCountAndDropLabel); } - // If any keepalive filters, - generateKeepaliveFilter(gen); + // If any keepalive filter matches, drop + generateV4KeepaliveFilters(gen); + // Otherwise, this is an IPv4 unicast, pass // If L2 broadcast packet, drop. // TODO: can we invert this condition to fall through to the common pass case below? maybeSetupCounter(gen, Counter.PASSED_IPV4_UNICAST); @@ -1180,7 +1183,7 @@ public class ApfFilter { maybeSetupCounter(gen, Counter.DROPPED_IPV4_L2_BROADCAST); gen.addJump(mCountAndDropLabel); } else { - generateKeepaliveFilter(gen); + generateV4KeepaliveFilters(gen); } // Otherwise, pass @@ -1188,12 +1191,25 @@ public class ApfFilter { gen.addJump(mCountAndPassLabel); } - private void generateKeepaliveFilter(ApfGenerator gen) throws IllegalInstructionException { + private void generateV4KeepaliveFilters(ApfGenerator gen) throws IllegalInstructionException { + final String skipV4KeepaliveFilter = "skip_v4_keepalive_filter"; + final boolean haveV4KeepaliveAcks = NetworkStackUtils.any(mKeepaliveAcks, + ack -> ack instanceof TcpKeepaliveAckV4); + + // If no keepalive acks + if (!haveV4KeepaliveAcks) return; + + // If not tcp, skip keepalive filters + gen.addLoad8(Register.R0, IPV4_PROTOCOL_OFFSET); + gen.addJumpIfR0NotEquals(IPPROTO_TCP, skipV4KeepaliveFilter); + // Drop IPv4 Keepalive acks for (int i = 0; i < mKeepaliveAcks.size(); ++i) { final TcpKeepaliveAck ack = mKeepaliveAcks.valueAt(i); if (ack instanceof TcpKeepaliveAckV4) ack.generateFilterLocked(gen); } + + gen.defineLabel(skipV4KeepaliveFilter); } /** @@ -1244,11 +1260,14 @@ public class ApfFilter { maybeSetupCounter(gen, Counter.DROPPED_IPV6_NON_ICMP_MULTICAST); gen.addLoad8(Register.R0, IPV6_DEST_ADDR_OFFSET); gen.addJumpIfR0Equals(0xff, mCountAndDropLabel); + // If any keepalive filter matches, drop + generateV6KeepaliveFilters(gen); // Not multicast. Pass. maybeSetupCounter(gen, Counter.PASSED_IPV6_UNICAST_NON_ICMP); gen.addJump(mCountAndPassLabel); gen.defineLabel(skipIPv6MulticastFilterLabel); } else { + generateV6KeepaliveFilters(gen); // If not ICMPv6, pass. maybeSetupCounter(gen, Counter.PASSED_IPV6_NON_ICMP); gen.addJumpIfR0NotEquals(IPPROTO_ICMPV6, mCountAndPassLabel); @@ -1272,12 +1291,27 @@ public class ApfFilter { maybeSetupCounter(gen, Counter.DROPPED_IPV6_MULTICAST_NA); gen.addJump(mCountAndDropLabel); gen.defineLabel(skipUnsolicitedMulticastNALabel); + } + + private void generateV6KeepaliveFilters(ApfGenerator gen) throws IllegalInstructionException { + final String skipV6KeepaliveFilter = "skip_v6_keepalive_filter"; + final boolean haveV6KeepaliveAcks = NetworkStackUtils.any(mKeepaliveAcks, + ack -> ack instanceof TcpKeepaliveAckV6); + + // If no keepalive acks + if (!haveV6KeepaliveAcks) return; + + // If not tcp, skip keepalive filters + gen.addLoad8(Register.R0, IPV6_NEXT_HEADER_OFFSET); + gen.addJumpIfR0NotEquals(IPPROTO_TCP, skipV6KeepaliveFilter); // Drop IPv6 Keepalive acks for (int i = 0; i < mKeepaliveAcks.size(); ++i) { final TcpKeepaliveAck ack = mKeepaliveAcks.valueAt(i); if (ack instanceof TcpKeepaliveAckV6) ack.generateFilterLocked(gen); } + + gen.defineLabel(skipV6KeepaliveFilter); } /** @@ -1294,6 +1328,8 @@ public class ApfFilter { * <li>Pass all non-IPv4 and non-IPv6 packets, * <li>Drop IPv6 ICMPv6 NAs to ff02::1. * <li>Drop IPv6 ICMPv6 RSs. + * <li>Filter IPv4 packets (see generateIPv4FilterLocked()) + * <li>Filter IPv6 packets (see generateIPv6FilterLocked()) * <li>Let execution continue off the end of the program for IPv6 ICMPv6 packets. This allows * insertion of RA filters here, or if there aren't any, just passes the packets. * </ul> @@ -1737,7 +1773,7 @@ public class ApfFilter { } pw.decreaseIndent(); - pw.println("Keepalive filter:"); + pw.println("Keepalive filters:"); pw.increaseIndent(); for (int i = 0; i < mKeepaliveAcks.size(); ++i) { final TcpKeepaliveAck keepaliveAck = mKeepaliveAcks.valueAt(i); diff --git a/packages/NetworkStack/src/android/net/apf/ApfGenerator.java b/packages/NetworkStack/src/android/net/apf/ApfGenerator.java index 809327a0b79d..44ce2db8547c 100644 --- a/packages/NetworkStack/src/android/net/apf/ApfGenerator.java +++ b/packages/NetworkStack/src/android/net/apf/ApfGenerator.java @@ -108,7 +108,7 @@ public class ApfGenerator { private String mLabel; // When mOpcode == Opcodes.JNEBS: private byte[] mCompareBytes; - // Offset in bytes from the begining of this program. Set by {@link ApfGenerator#generate}. + // Offset in bytes from the beginning of this program. Set by {@link ApfGenerator#generate}. int offset; Instruction(Opcodes opcode, Register register) { @@ -431,7 +431,7 @@ public class ApfGenerator { /** * Add an instruction to the end of the program to load the byte at offset {@code offset} - * bytes from the begining of the packet into {@code register}. + * bytes from the beginning of the packet into {@code register}. */ public ApfGenerator addLoad8(Register register, int offset) { Instruction instruction = new Instruction(Opcodes.LDB, register); @@ -442,7 +442,7 @@ public class ApfGenerator { /** * Add an instruction to the end of the program to load 16-bits at offset {@code offset} - * bytes from the begining of the packet into {@code register}. + * bytes from the beginning of the packet into {@code register}. */ public ApfGenerator addLoad16(Register register, int offset) { Instruction instruction = new Instruction(Opcodes.LDH, register); @@ -453,7 +453,7 @@ public class ApfGenerator { /** * Add an instruction to the end of the program to load 32-bits at offset {@code offset} - * bytes from the begining of the packet into {@code register}. + * bytes from the beginning of the packet into {@code register}. */ public ApfGenerator addLoad32(Register register, int offset) { Instruction instruction = new Instruction(Opcodes.LDW, register); @@ -464,7 +464,7 @@ public class ApfGenerator { /** * Add an instruction to the end of the program to load a byte from the packet into - * {@code register}. The offset of the loaded byte from the begining of the packet is + * {@code register}. The offset of the loaded byte from the beginning of the packet is * the sum of {@code offset} and the value in register R1. */ public ApfGenerator addLoad8Indexed(Register register, int offset) { diff --git a/packages/NetworkStack/src/android/net/ip/IpClient.java b/packages/NetworkStack/src/android/net/ip/IpClient.java index 7a06af41f951..c1f178a7f5f1 100644 --- a/packages/NetworkStack/src/android/net/ip/IpClient.java +++ b/packages/NetworkStack/src/android/net/ip/IpClient.java @@ -1389,8 +1389,8 @@ public class IpClient extends StateMachine { apfConfig.apfCapabilities = mConfiguration.mApfCapabilities; apfConfig.multicastFilter = mMulticastFiltering; // Get the Configuration for ApfFilter from Context - apfConfig.ieee802_3Filter = ApfCapabilities.getApfDrop8023Frames(mContext); - apfConfig.ethTypeBlackList = ApfCapabilities.getApfEthTypeBlackList(mContext); + apfConfig.ieee802_3Filter = ApfCapabilities.getApfDrop8023Frames(); + apfConfig.ethTypeBlackList = ApfCapabilities.getApfEtherTypeBlackList(); mApfFilter = ApfFilter.maybeCreate(mContext, apfConfig, mInterfaceParams, mCallback); // TODO: investigate the effects of any multicast filtering racing/interfering with the // rest of this IP configuration startup. diff --git a/packages/NetworkStack/src/android/net/util/NetworkStackUtils.java b/packages/NetworkStack/src/android/net/util/NetworkStackUtils.java index 481dbdadbac0..9d2df57901fb 100644 --- a/packages/NetworkStack/src/android/net/util/NetworkStackUtils.java +++ b/packages/NetworkStack/src/android/net/util/NetworkStackUtils.java @@ -17,10 +17,15 @@ package android.net.util; import android.annotation.NonNull; +import android.annotation.Nullable; +import android.provider.DeviceConfig; +import android.util.SparseArray; import java.io.FileDescriptor; import java.io.IOException; import java.util.List; +import java.util.function.Predicate; + /** * Collection of utilities for the network stack. @@ -65,4 +70,32 @@ public class NetworkStackUtils { } return array; } + + /** + * @return True if there exists at least one element in the sparse array for which + * condition {@code predicate} + */ + public static <T> boolean any(SparseArray<T> array, Predicate<T> predicate) { + for (int i = 0; i < array.size(); ++i) { + if (predicate.test(array.valueAt(i))) { + return true; + } + } + return false; + } + + /** + * Look up the value of a property for a particular namespace from {@link DeviceConfig}. + * @param namespace The namespace containing the property to look up. + * @param name The name of the property to look up. + * @param defaultValue The value to return if the property does not exist or has no non-null + * value. + * @return the corresponding value, or defaultValue if none exists. + */ + @Nullable + public static String getDeviceConfigProperty(@NonNull String namespace, @NonNull String name, + @Nullable String defaultValue) { + String value = DeviceConfig.getProperty(namespace, name); + return value != null ? value : defaultValue; + } } diff --git a/packages/NetworkStack/src/com/android/server/NetworkStackService.java b/packages/NetworkStack/src/com/android/server/NetworkStackService.java index 19e9108d2fc8..a0a90fde518f 100644 --- a/packages/NetworkStack/src/com/android/server/NetworkStackService.java +++ b/packages/NetworkStack/src/com/android/server/NetworkStackService.java @@ -35,7 +35,9 @@ import android.net.INetd; import android.net.INetworkMonitor; import android.net.INetworkMonitorCallbacks; import android.net.INetworkStackConnector; +import android.net.LinkProperties; import android.net.Network; +import android.net.NetworkCapabilities; import android.net.PrivateDnsConfigParcel; import android.net.dhcp.DhcpServer; import android.net.dhcp.DhcpServingParams; @@ -301,15 +303,9 @@ public class NetworkStackService extends Service { } @Override - public void notifySystemReady() { + public void notifyNetworkConnected(LinkProperties lp, NetworkCapabilities nc) { checkNetworkStackCallingPermission(); - mNm.notifySystemReady(); - } - - @Override - public void notifyNetworkConnected() { - checkNetworkStackCallingPermission(); - mNm.notifyNetworkConnected(); + mNm.notifyNetworkConnected(lp, nc); } @Override @@ -319,15 +315,15 @@ public class NetworkStackService extends Service { } @Override - public void notifyLinkPropertiesChanged() { + public void notifyLinkPropertiesChanged(LinkProperties lp) { checkNetworkStackCallingPermission(); - mNm.notifyLinkPropertiesChanged(); + mNm.notifyLinkPropertiesChanged(lp); } @Override - public void notifyNetworkCapabilitiesChanged() { + public void notifyNetworkCapabilitiesChanged(NetworkCapabilities nc) { checkNetworkStackCallingPermission(); - mNm.notifyNetworkCapabilitiesChanged(); + mNm.notifyNetworkCapabilitiesChanged(nc); } } } diff --git a/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java b/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java index f3476ed1566f..6f31f9b56ace 100644 --- a/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java +++ b/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java @@ -78,6 +78,7 @@ import android.telephony.SignalStrength; import android.telephony.TelephonyManager; import android.text.TextUtils; import android.util.Log; +import android.util.Pair; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.RingBufferIndices; @@ -221,19 +222,31 @@ public class NetworkMonitor extends StateMachine { * Message to self indicating captive portal detection is completed. * obj = CaptivePortalProbeResult for detection result; */ - public static final int CMD_PROBE_COMPLETE = 16; + private static final int CMD_PROBE_COMPLETE = 16; /** * ConnectivityService notifies NetworkMonitor of DNS query responses event. * arg1 = returncode in OnDnsEvent which indicates the response code for the DNS query. */ - public static final int EVENT_DNS_NOTIFICATION = 17; + private static final int EVENT_DNS_NOTIFICATION = 17; /** * ConnectivityService notifies NetworkMonitor that the user accepts partial connectivity and * NetworkMonitor should ignore the https probe. */ - public static final int EVENT_ACCEPT_PARTIAL_CONNECTIVITY = 18; + private static final int EVENT_ACCEPT_PARTIAL_CONNECTIVITY = 18; + + /** + * ConnectivityService notifies NetworkMonitor of changed LinkProperties. + * obj = new LinkProperties. + */ + private static final int EVENT_LINK_PROPERTIES_CHANGED = 19; + + /** + * ConnectivityService notifies NetworkMonitor of changed NetworkCapabilities. + * obj = new NetworkCapabilities. + */ + private static final int EVENT_NETWORK_CAPABILITIES_CHANGED = 20; // Start mReevaluateDelayMs at this value and double. private static final int INITIAL_REEVALUATE_DELAY_MS = 1000; @@ -285,8 +298,6 @@ public class NetworkMonitor extends StateMachine { // Avoids surfacing "Sign in to network" notification. private boolean mDontDisplaySigninNotification = false; - private volatile boolean mSystemReady = false; - private final State mDefaultState = new DefaultState(); private final State mValidatedState = new ValidatedState(); private final State mMaybeNotifyState = new MaybeNotifyState(); @@ -379,10 +390,8 @@ public class NetworkMonitor extends StateMachine { mDataStallValidDnsTimeThreshold = getDataStallValidDnsTimeThreshold(); mDataStallEvaluationType = getDataStallEvalutionType(); - // mLinkProperties and mNetworkCapbilities must never be null or we will NPE. - // Provide empty objects in case we are started and the network disconnects before - // we can ever fetch them. - // TODO: Delete ASAP. + // Provide empty LinkProperties and NetworkCapabilities to make sure they are never null, + // even before notifyNetworkConnected. mLinkProperties = new LinkProperties(); mNetworkCapabilities = new NetworkCapabilities(null); } @@ -423,19 +432,18 @@ public class NetworkMonitor extends StateMachine { } /** - * Send a notification to NetworkMonitor indicating that the system is ready. + * Send a notification to NetworkMonitor indicating that the network is now connected. */ - public void notifySystemReady() { - // No need to run on the handler thread: mSystemReady is volatile and read only once on the - // isCaptivePortal() thread. - mSystemReady = true; + public void notifyNetworkConnected(LinkProperties lp, NetworkCapabilities nc) { + sendMessage(CMD_NETWORK_CONNECTED, new Pair<>( + new LinkProperties(lp), new NetworkCapabilities(nc))); } - /** - * Send a notification to NetworkMonitor indicating that the network is now connected. - */ - public void notifyNetworkConnected() { - sendMessage(CMD_NETWORK_CONNECTED); + private void updateConnectedNetworkAttributes(Message connectedMsg) { + final Pair<LinkProperties, NetworkCapabilities> attrs = + (Pair<LinkProperties, NetworkCapabilities>) connectedMsg.obj; + mLinkProperties = attrs.first; + mNetworkCapabilities = attrs.second; } /** @@ -448,37 +456,15 @@ public class NetworkMonitor extends StateMachine { /** * Send a notification to NetworkMonitor indicating that link properties have changed. */ - public void notifyLinkPropertiesChanged() { - getHandler().post(() -> { - updateLinkProperties(); - }); - } - - private void updateLinkProperties() { - final LinkProperties lp = mCm.getLinkProperties(mNetwork); - // If null, we should soon get a message that the network was disconnected, and will stop. - if (lp != null) { - // TODO: send LinkProperties parceled in notifyLinkPropertiesChanged() and start(). - mLinkProperties = lp; - } + public void notifyLinkPropertiesChanged(final LinkProperties lp) { + sendMessage(EVENT_LINK_PROPERTIES_CHANGED, new LinkProperties(lp)); } /** * Send a notification to NetworkMonitor indicating that network capabilities have changed. */ - public void notifyNetworkCapabilitiesChanged() { - getHandler().post(() -> { - updateNetworkCapabilities(); - }); - } - - private void updateNetworkCapabilities() { - final NetworkCapabilities nc = mCm.getNetworkCapabilities(mNetwork); - // If null, we should soon get a message that the network was disconnected, and will stop. - if (nc != null) { - // TODO: send NetworkCapabilities parceled in notifyNetworkCapsChanged() and start(). - mNetworkCapabilities = nc; - } + public void notifyNetworkCapabilitiesChanged(final NetworkCapabilities nc) { + sendMessage(EVENT_NETWORK_CAPABILITIES_CHANGED, new NetworkCapabilities(nc)); } /** @@ -547,16 +533,10 @@ public class NetworkMonitor extends StateMachine { // does not entail any real state (hence no enter() or exit() routines). private class DefaultState extends State { @Override - public void enter() { - // TODO: have those passed parceled in start() and remove this - updateLinkProperties(); - updateNetworkCapabilities(); - } - - @Override public boolean processMessage(Message message) { switch (message.what) { case CMD_NETWORK_CONNECTED: + updateConnectedNetworkAttributes(message); logNetworkEvent(NetworkEvent.NETWORK_CONNECTED); transitionTo(mEvaluatingState); return HANDLED; @@ -660,6 +640,12 @@ public class NetworkMonitor extends StateMachine { case EVENT_ACCEPT_PARTIAL_CONNECTIVITY: mAcceptPartialConnectivity = true; break; + case EVENT_LINK_PROPERTIES_CHANGED: + mLinkProperties = (LinkProperties) message.obj; + break; + case EVENT_NETWORK_CAPABILITIES_CHANGED: + mNetworkCapabilities = (NetworkCapabilities) message.obj; + break; default: break; } @@ -684,6 +670,7 @@ public class NetworkMonitor extends StateMachine { public boolean processMessage(Message message) { switch (message.what) { case CMD_NETWORK_CONNECTED: + updateConnectedNetworkAttributes(message); transitionTo(mValidatedState); break; case CMD_EVALUATE_PRIVATE_DNS: @@ -1594,10 +1581,6 @@ public class NetworkMonitor extends StateMachine { */ private void sendNetworkConditionsBroadcast(boolean responseReceived, boolean isCaptivePortal, long requestTimestampMs, long responseTimestampMs) { - if (!mSystemReady) { - return; - } - Intent latencyBroadcast = new Intent(NetworkMonitorUtils.ACTION_NETWORK_CONDITIONS_MEASURED); if (mNetworkCapabilities.hasTransport(TRANSPORT_WIFI)) { diff --git a/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreDatabase.java b/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreDatabase.java index 4d4ceed9cb52..764e2d07ce3d 100644 --- a/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreDatabase.java +++ b/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreDatabase.java @@ -72,6 +72,10 @@ public class IpMemoryStoreDatabase { public static final String COLNAME_ASSIGNEDV4ADDRESS = "assignedV4Address"; public static final String COLTYPE_ASSIGNEDV4ADDRESS = "INTEGER"; + public static final String COLNAME_ASSIGNEDV4ADDRESSEXPIRY = "assignedV4AddressExpiry"; + // The lease expiry timestamp in uint of milliseconds + public static final String COLTYPE_ASSIGNEDV4ADDRESSEXPIRY = "BIGINT"; + // Please note that the group hint is only a *hint*, hence its name. The client can offer // this information to nudge the grouping in the decision it thinks is right, but it can't // decide for the memory store what is the same L3 network. @@ -86,13 +90,14 @@ public class IpMemoryStoreDatabase { public static final String COLTYPE_MTU = "INTEGER DEFAULT -1"; public static final String CREATE_TABLE = "CREATE TABLE IF NOT EXISTS " - + TABLENAME + " (" - + COLNAME_L2KEY + " " + COLTYPE_L2KEY + " PRIMARY KEY NOT NULL, " - + COLNAME_EXPIRYDATE + " " + COLTYPE_EXPIRYDATE + ", " - + COLNAME_ASSIGNEDV4ADDRESS + " " + COLTYPE_ASSIGNEDV4ADDRESS + ", " - + COLNAME_GROUPHINT + " " + COLTYPE_GROUPHINT + ", " - + COLNAME_DNSADDRESSES + " " + COLTYPE_DNSADDRESSES + ", " - + COLNAME_MTU + " " + COLTYPE_MTU + ")"; + + TABLENAME + " (" + + COLNAME_L2KEY + " " + COLTYPE_L2KEY + " PRIMARY KEY NOT NULL, " + + COLNAME_EXPIRYDATE + " " + COLTYPE_EXPIRYDATE + ", " + + COLNAME_ASSIGNEDV4ADDRESS + " " + COLTYPE_ASSIGNEDV4ADDRESS + ", " + + COLNAME_ASSIGNEDV4ADDRESSEXPIRY + " " + COLTYPE_ASSIGNEDV4ADDRESSEXPIRY + ", " + + COLNAME_GROUPHINT + " " + COLTYPE_GROUPHINT + ", " + + COLNAME_DNSADDRESSES + " " + COLTYPE_DNSADDRESSES + ", " + + COLNAME_MTU + " " + COLTYPE_MTU + ")"; public static final String DROP_TABLE = "DROP TABLE IF EXISTS " + TABLENAME; } @@ -134,8 +139,9 @@ public class IpMemoryStoreDatabase { /** The SQLite DB helper */ public static class DbHelper extends SQLiteOpenHelper { // Update this whenever changing the schema. - private static final int SCHEMA_VERSION = 2; + private static final int SCHEMA_VERSION = 4; private static final String DATABASE_FILENAME = "IpMemoryStore.db"; + private static final String TRIGGER_NAME = "delete_cascade_to_private"; public DbHelper(@NonNull final Context context) { super(context, DATABASE_FILENAME, null, SCHEMA_VERSION); @@ -147,16 +153,38 @@ public class IpMemoryStoreDatabase { public void onCreate(@NonNull final SQLiteDatabase db) { db.execSQL(NetworkAttributesContract.CREATE_TABLE); db.execSQL(PrivateDataContract.CREATE_TABLE); + createTrigger(db); } /** Called when the database is upgraded */ @Override public void onUpgrade(@NonNull final SQLiteDatabase db, final int oldVersion, final int newVersion) { - // No upgrade supported yet. - db.execSQL(NetworkAttributesContract.DROP_TABLE); - db.execSQL(PrivateDataContract.DROP_TABLE); - onCreate(db); + try { + if (oldVersion < 2) { + // upgrade from version 1 to version 2 + // since we starts from version 2, do nothing here + } + + if (oldVersion < 3) { + // upgrade from version 2 to version 3 + final String sqlUpgradeAddressExpiry = "alter table" + + " " + NetworkAttributesContract.TABLENAME + " ADD" + + " " + NetworkAttributesContract.COLNAME_ASSIGNEDV4ADDRESSEXPIRY + + " " + NetworkAttributesContract.COLTYPE_ASSIGNEDV4ADDRESSEXPIRY; + db.execSQL(sqlUpgradeAddressExpiry); + } + + if (oldVersion < 4) { + createTrigger(db); + } + } catch (SQLiteException e) { + Log.e(TAG, "Could not upgrade to the new version", e); + // create database with new version + db.execSQL(NetworkAttributesContract.DROP_TABLE); + db.execSQL(PrivateDataContract.DROP_TABLE); + onCreate(db); + } } /** Called when the database is downgraded */ @@ -166,8 +194,20 @@ public class IpMemoryStoreDatabase { // Downgrades always nuke all data and recreate an empty table. db.execSQL(NetworkAttributesContract.DROP_TABLE); db.execSQL(PrivateDataContract.DROP_TABLE); + db.execSQL("DROP TRIGGER " + TRIGGER_NAME); onCreate(db); } + + private void createTrigger(@NonNull final SQLiteDatabase db) { + final String createTrigger = "CREATE TRIGGER " + TRIGGER_NAME + + " DELETE ON " + NetworkAttributesContract.TABLENAME + + " BEGIN" + + " DELETE FROM " + PrivateDataContract.TABLENAME + " WHERE OLD." + + NetworkAttributesContract.COLNAME_L2KEY + + "=" + PrivateDataContract.COLNAME_L2KEY + + "; END;"; + db.execSQL(createTrigger); + } } @NonNull @@ -204,6 +244,10 @@ public class IpMemoryStoreDatabase { values.put(NetworkAttributesContract.COLNAME_ASSIGNEDV4ADDRESS, inet4AddressToIntHTH(attributes.assignedV4Address)); } + if (null != attributes.assignedV4AddressExpiry) { + values.put(NetworkAttributesContract.COLNAME_ASSIGNEDV4ADDRESSEXPIRY, + attributes.assignedV4AddressExpiry); + } if (null != attributes.groupHint) { values.put(NetworkAttributesContract.COLNAME_GROUPHINT, attributes.groupHint); } @@ -251,6 +295,8 @@ public class IpMemoryStoreDatabase { final NetworkAttributes.Builder builder = new NetworkAttributes.Builder(); final int assignedV4AddressInt = getInt(cursor, NetworkAttributesContract.COLNAME_ASSIGNEDV4ADDRESS, 0); + final long assignedV4AddressExpiry = getLong(cursor, + NetworkAttributesContract.COLNAME_ASSIGNEDV4ADDRESSEXPIRY, 0); final String groupHint = getString(cursor, NetworkAttributesContract.COLNAME_GROUPHINT); final byte[] dnsAddressesBlob = getBlob(cursor, NetworkAttributesContract.COLNAME_DNSADDRESSES); @@ -258,6 +304,9 @@ public class IpMemoryStoreDatabase { if (0 != assignedV4AddressInt) { builder.setAssignedV4Address(intToInet4AddressHTH(assignedV4AddressInt)); } + if (0 != assignedV4AddressExpiry) { + builder.setAssignedV4AddressExpiry(assignedV4AddressExpiry); + } builder.setGroupHint(groupHint); if (null != dnsAddressesBlob) { builder.setDnsAddresses(decodeAddressList(dnsAddressesBlob)); @@ -305,7 +354,7 @@ public class IpMemoryStoreDatabase { } // If the attributes are null, this will only write the expiry. - // Returns an int out of Status.{SUCCESS,ERROR_*} + // Returns an int out of Status.{SUCCESS, ERROR_*} static int storeNetworkAttributes(@NonNull final SQLiteDatabase db, @NonNull final String key, final long expiry, @Nullable final NetworkAttributes attributes) { final ContentValues cv = toContentValues(key, attributes, expiry); @@ -330,7 +379,7 @@ public class IpMemoryStoreDatabase { return Status.ERROR_STORAGE; } - // Returns an int out of Status.{SUCCESS,ERROR_*} + // Returns an int out of Status.{SUCCESS, ERROR_*} static int storeBlob(@NonNull final SQLiteDatabase db, @NonNull final String key, @NonNull final String clientId, @NonNull final String name, @NonNull final byte[] data) { @@ -493,6 +542,93 @@ public class IpMemoryStoreDatabase { return bestKey; } + // Drops all records that are expired. Relevance has decayed to zero of these records. Returns + // an int out of Status.{SUCCESS, ERROR_*} + static int dropAllExpiredRecords(@NonNull final SQLiteDatabase db) { + db.beginTransaction(); + try { + // Deletes NetworkAttributes that have expired. + db.delete(NetworkAttributesContract.TABLENAME, + NetworkAttributesContract.COLNAME_EXPIRYDATE + " < ?", + new String[]{Long.toString(System.currentTimeMillis())}); + db.setTransactionSuccessful(); + } catch (SQLiteException e) { + Log.e(TAG, "Could not delete data from memory store", e); + return Status.ERROR_STORAGE; + } finally { + db.endTransaction(); + } + + // Execute vacuuming here if above operation has no exception. If above operation got + // exception, vacuuming can be ignored for reducing unnecessary consumption. + try { + db.execSQL("VACUUM"); + } catch (SQLiteException e) { + // Do nothing. + } + return Status.SUCCESS; + } + + // Drops number of records that start from the lowest expiryDate. Returns an int out of + // Status.{SUCCESS, ERROR_*} + static int dropNumberOfRecords(@NonNull final SQLiteDatabase db, int number) { + if (number <= 0) { + return Status.ERROR_ILLEGAL_ARGUMENT; + } + + // Queries number of NetworkAttributes that start from the lowest expiryDate. + final Cursor cursor = db.query(NetworkAttributesContract.TABLENAME, + new String[] {NetworkAttributesContract.COLNAME_EXPIRYDATE}, // columns + null, // selection + null, // selectionArgs + null, // groupBy + null, // having + NetworkAttributesContract.COLNAME_EXPIRYDATE, // orderBy + Integer.toString(number)); // limit + if (cursor == null || cursor.getCount() <= 0) return Status.ERROR_GENERIC; + cursor.moveToLast(); + + //Get the expiryDate from last record. + final long expiryDate = getLong(cursor, NetworkAttributesContract.COLNAME_EXPIRYDATE, 0); + cursor.close(); + + db.beginTransaction(); + try { + // Deletes NetworkAttributes that expiryDate are lower than given value. + db.delete(NetworkAttributesContract.TABLENAME, + NetworkAttributesContract.COLNAME_EXPIRYDATE + " <= ?", + new String[]{Long.toString(expiryDate)}); + db.setTransactionSuccessful(); + } catch (SQLiteException e) { + Log.e(TAG, "Could not delete data from memory store", e); + return Status.ERROR_STORAGE; + } finally { + db.endTransaction(); + } + + // Execute vacuuming here if above operation has no exception. If above operation got + // exception, vacuuming can be ignored for reducing unnecessary consumption. + try { + db.execSQL("VACUUM"); + } catch (SQLiteException e) { + // Do nothing. + } + return Status.SUCCESS; + } + + static int getTotalRecordNumber(@NonNull final SQLiteDatabase db) { + // Query the total number of NetworkAttributes + final Cursor cursor = db.query(NetworkAttributesContract.TABLENAME, + new String[] {"COUNT(*)"}, // columns + null, // selection + null, // selectionArgs + null, // groupBy + null, // having + null); // orderBy + cursor.moveToFirst(); + return cursor == null ? 0 : cursor.getInt(0); + } + // Helper methods private static String getString(final Cursor cursor, final String columnName) { final int columnIndex = cursor.getColumnIndex(columnName); diff --git a/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreService.java b/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreService.java index f801b355c43e..5650f2125737 100644 --- a/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreService.java +++ b/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreService.java @@ -22,6 +22,7 @@ import static android.net.ipmemorystore.Status.ERROR_ILLEGAL_ARGUMENT; import static android.net.ipmemorystore.Status.SUCCESS; import static com.android.server.connectivity.ipmemorystore.IpMemoryStoreDatabase.EXPIRY_ERROR; +import static com.android.server.connectivity.ipmemorystore.RegularMaintenanceJobService.InterruptMaintenance; import android.annotation.NonNull; import android.annotation.Nullable; @@ -43,6 +44,9 @@ import android.net.ipmemorystore.StatusParcelable; import android.os.RemoteException; import android.util.Log; +import com.android.internal.annotations.VisibleForTesting; + +import java.io.File; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -57,8 +61,17 @@ import java.util.concurrent.Executors; public class IpMemoryStoreService extends IIpMemoryStore.Stub { private static final String TAG = IpMemoryStoreService.class.getSimpleName(); private static final int MAX_CONCURRENT_THREADS = 4; + private static final int DATABASE_SIZE_THRESHOLD = 10 * 1024 * 1024; //10MB + private static final int MAX_DROP_RECORD_TIMES = 500; + private static final int MIN_DELETE_NUM = 5; private static final boolean DBG = true; + // Error codes below are internal and used for notifying status beteween IpMemoryStore modules. + static final int ERROR_INTERNAL_BASE = -1_000_000_000; + // This error code is used for maintenance only to notify RegularMaintenanceJobService that + // full maintenance job has been interrupted. + static final int ERROR_INTERNAL_INTERRUPTED = ERROR_INTERNAL_BASE - 1; + @NonNull final Context mContext; @Nullable @@ -111,6 +124,7 @@ public class IpMemoryStoreService extends IIpMemoryStore.Stub { // with judicious subclassing of ThreadPoolExecutor, but that's a lot of dangerous // complexity for little benefit in this case. mExecutor = Executors.newWorkStealingPool(MAX_CONCURRENT_THREADS); + RegularMaintenanceJobService.schedule(mContext, this); } /** @@ -125,6 +139,7 @@ public class IpMemoryStoreService extends IIpMemoryStore.Stub { // guarantee the threads can be terminated in any given amount of time. mExecutor.shutdownNow(); if (mDb != null) mDb.close(); + RegularMaintenanceJobService.unschedule(mContext); } /** Helper function to make a status object */ @@ -394,4 +409,89 @@ public class IpMemoryStoreService extends IIpMemoryStore.Stub { } }); } + + /** Get db size threshold. */ + @VisibleForTesting + protected int getDbSizeThreshold() { + return DATABASE_SIZE_THRESHOLD; + } + + private long getDbSize() { + final File dbFile = new File(mDb.getPath()); + try { + return dbFile.length(); + } catch (final SecurityException e) { + if (DBG) Log.e(TAG, "Read db size access deny.", e); + // Return zero value if can't get disk usage exactly. + return 0; + } + } + + /** Check if db size is over the threshold. */ + @VisibleForTesting + boolean isDbSizeOverThreshold() { + return getDbSize() > getDbSizeThreshold(); + } + + /** + * Full maintenance. + * + * @param listener A listener to inform of the completion of this call. + */ + void fullMaintenance(@NonNull final IOnStatusListener listener, + @NonNull final InterruptMaintenance interrupt) { + mExecutor.execute(() -> { + try { + if (null == mDb) { + listener.onComplete(makeStatus(ERROR_DATABASE_CANNOT_BE_OPENED)); + return; + } + + // Interrupt maintenance because the scheduling job has been canceled. + if (checkForInterrupt(listener, interrupt)) return; + + int result = SUCCESS; + // Drop all records whose relevance has decayed to zero. + // This is the first step to decrease memory store size. + result = IpMemoryStoreDatabase.dropAllExpiredRecords(mDb); + + if (checkForInterrupt(listener, interrupt)) return; + + // Aggregate historical data in passes + // TODO : Waiting for historical data implement. + + // Check if db size meets the storage goal(10MB). If not, keep dropping records and + // aggregate historical data until the storage goal is met. Use for loop with 500 + // times restriction to prevent infinite loop (Deleting records always fail and db + // size is still over the threshold) + for (int i = 0; isDbSizeOverThreshold() && i < MAX_DROP_RECORD_TIMES; i++) { + if (checkForInterrupt(listener, interrupt)) return; + + final int totalNumber = IpMemoryStoreDatabase.getTotalRecordNumber(mDb); + final long dbSize = getDbSize(); + final float decreaseRate = (dbSize == 0) + ? 0 : (float) (dbSize - getDbSizeThreshold()) / (float) dbSize; + final int deleteNumber = Math.max( + (int) (totalNumber * decreaseRate), MIN_DELETE_NUM); + + result = IpMemoryStoreDatabase.dropNumberOfRecords(mDb, deleteNumber); + + if (checkForInterrupt(listener, interrupt)) return; + + // Aggregate historical data + // TODO : Waiting for historical data implement. + } + listener.onComplete(makeStatus(result)); + } catch (final RemoteException e) { + // Client at the other end died + } + }); + } + + private boolean checkForInterrupt(@NonNull final IOnStatusListener listener, + @NonNull final InterruptMaintenance interrupt) throws RemoteException { + if (!interrupt.isInterrupted()) return false; + listener.onComplete(makeStatus(ERROR_INTERNAL_INTERRUPTED)); + return true; + } } diff --git a/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/RegularMaintenanceJobService.java b/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/RegularMaintenanceJobService.java new file mode 100644 index 000000000000..2775fde4c8b9 --- /dev/null +++ b/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/RegularMaintenanceJobService.java @@ -0,0 +1,140 @@ +/* + * 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.server.connectivity.ipmemorystore; + +import android.app.job.JobInfo; +import android.app.job.JobParameters; +import android.app.job.JobScheduler; +import android.app.job.JobService; +import android.content.ComponentName; +import android.content.Context; +import android.net.ipmemorystore.IOnStatusListener; +import android.net.ipmemorystore.Status; +import android.net.ipmemorystore.StatusParcelable; +import android.os.IBinder; +import android.os.RemoteException; +import android.util.Log; + +import java.util.ArrayList; +import java.util.concurrent.TimeUnit; + +/** + * Regular maintenance job service. + * @hide + */ +public final class RegularMaintenanceJobService extends JobService { + // Must be unique within the system server uid. + public static final int REGULAR_MAINTENANCE_ID = 3345678; + + /** + * Class for interrupt check of maintenance job. + */ + public static final class InterruptMaintenance { + private volatile boolean mIsInterrupted; + private final int mJobId; + + public InterruptMaintenance(int jobId) { + mJobId = jobId; + mIsInterrupted = false; + } + + public int getJobId() { + return mJobId; + } + + public void setInterrupted(boolean interrupt) { + mIsInterrupted = interrupt; + } + + public boolean isInterrupted() { + return mIsInterrupted; + } + } + + private static final ArrayList<InterruptMaintenance> sInterruptList = new ArrayList<>(); + private static IpMemoryStoreService sIpMemoryStoreService; + + @Override + public boolean onStartJob(JobParameters params) { + if (sIpMemoryStoreService == null) { + Log.wtf("RegularMaintenanceJobService", + "Can not start job because sIpMemoryStoreService is null."); + return false; + } + final InterruptMaintenance im = new InterruptMaintenance(params.getJobId()); + sInterruptList.add(im); + + sIpMemoryStoreService.fullMaintenance(new IOnStatusListener() { + @Override + public void onComplete(final StatusParcelable statusParcelable) throws RemoteException { + final Status result = new Status(statusParcelable); + if (!result.isSuccess()) { + Log.e("RegularMaintenanceJobService", "Regular maintenance failed." + + " Error is " + result.resultCode); + } + sInterruptList.remove(im); + jobFinished(params, !result.isSuccess()); + } + + @Override + public IBinder asBinder() { + return null; + } + }, im); + return true; + } + + @Override + public boolean onStopJob(JobParameters params) { + final int jobId = params.getJobId(); + for (InterruptMaintenance im : sInterruptList) { + if (im.getJobId() == jobId) { + im.setInterrupted(true); + } + } + return true; + } + + /** Schedule regular maintenance job */ + static void schedule(Context context, IpMemoryStoreService ipMemoryStoreService) { + final JobScheduler jobScheduler = + (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE); + + final ComponentName maintenanceJobName = + new ComponentName(context, RegularMaintenanceJobService.class); + + // Regular maintenance is scheduled for when the device is idle with access power and a + // minimum interval of one day. + final JobInfo regularMaintenanceJob = + new JobInfo.Builder(REGULAR_MAINTENANCE_ID, maintenanceJobName) + .setRequiresDeviceIdle(true) + .setRequiresCharging(true) + .setRequiresBatteryNotLow(true) + .setPeriodic(TimeUnit.HOURS.toMillis(24)).build(); + + jobScheduler.schedule(regularMaintenanceJob); + sIpMemoryStoreService = ipMemoryStoreService; + } + + /** Unschedule regular maintenance job */ + static void unschedule(Context context) { + final JobScheduler jobScheduler = + (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE); + jobScheduler.cancel(REGULAR_MAINTENANCE_ID); + sIpMemoryStoreService = null; + } +} diff --git a/packages/NetworkStack/tests/Android.bp b/packages/NetworkStack/tests/Android.bp index aadf99ec37d0..0535af30681c 100644 --- a/packages/NetworkStack/tests/Android.bp +++ b/packages/NetworkStack/tests/Android.bp @@ -45,6 +45,8 @@ android_test { "libcrypto", "libcutils", "libdexfile", + "ld-android", + "libdl_android", "libhidl-gen-utils", "libhidlbase", "libhidltransport", diff --git a/packages/NetworkStack/tests/src/android/net/apf/ApfTest.java b/packages/NetworkStack/tests/src/android/net/apf/ApfTest.java index 88a05d506aa4..a0e508f130a5 100644 --- a/packages/NetworkStack/tests/src/android/net/apf/ApfTest.java +++ b/packages/NetworkStack/tests/src/android/net/apf/ApfTest.java @@ -1006,7 +1006,7 @@ public class ApfTest { private static final int IPV4_HEADER_LEN = 20; private static final int IPV4_VERSION_IHL_OFFSET = ETH_HEADER_LEN + 0; - private static final int IPV4_TOTAL_LENGTH_OFFSET = ETH_HEADER_LEN + 2; + private static final int IPV4_TOTAL_LENGTH_OFFSET = ETH_HEADER_LEN + 2; private static final int IPV4_PROTOCOL_OFFSET = ETH_HEADER_LEN + 9; private static final int IPV4_SRC_ADDR_OFFSET = ETH_HEADER_LEN + 12; private static final int IPV4_DEST_ADDR_OFFSET = ETH_HEADER_LEN + 16; diff --git a/tests/net/java/android/net/captiveportal/CaptivePortalProbeSpecTest.java b/packages/NetworkStack/tests/src/android/net/captiveportal/CaptivePortalProbeSpecTest.java index f948086ac79b..f948086ac79b 100644 --- a/tests/net/java/android/net/captiveportal/CaptivePortalProbeSpecTest.java +++ b/packages/NetworkStack/tests/src/android/net/captiveportal/CaptivePortalProbeSpecTest.java diff --git a/packages/NetworkStack/tests/src/com/android/server/connectivity/NetworkMonitorTest.java b/packages/NetworkStack/tests/src/com/android/server/connectivity/NetworkMonitorTest.java index d732c4e81d83..6665aae65d90 100644 --- a/packages/NetworkStack/tests/src/com/android/server/connectivity/NetworkMonitorTest.java +++ b/packages/NetworkStack/tests/src/com/android/server/connectivity/NetworkMonitorTest.java @@ -26,6 +26,8 @@ import static android.provider.Settings.Global.DATA_STALL_EVALUATION_TYPE_DNS; import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.mockito.ArgumentMatchers.anyString; @@ -60,6 +62,7 @@ import android.net.wifi.WifiManager; import android.os.Bundle; import android.os.ConditionVariable; import android.os.Handler; +import android.os.RemoteException; import android.os.SystemClock; import android.provider.Settings; import android.telephony.CellSignalStrength; @@ -73,6 +76,7 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; +import org.mockito.Captor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.mockito.Spy; @@ -107,6 +111,7 @@ public class NetworkMonitorTest { private @Spy Network mNetwork = new Network(TEST_NETID); private @Mock DataStallStatsUtils mDataStallStatsUtils; private @Mock WifiInfo mWifiInfo; + private @Captor ArgumentCaptor<String> mNetworkTestedRedirectUrlCaptor; private static final int TEST_NETID = 4242; @@ -122,7 +127,7 @@ public class NetworkMonitorTest { private static final int HANDLER_TIMEOUT_MS = 1000; - private static final LinkProperties TEST_LINKPROPERTIES = new LinkProperties(); + private static final LinkProperties TEST_LINK_PROPERTIES = new LinkProperties(); private static final NetworkCapabilities METERED_CAPABILITIES = new NetworkCapabilities() .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR) @@ -182,10 +187,6 @@ public class NetworkMonitorTest { InetAddresses.parseNumericAddress("192.168.0.0") }).when(mNetwork).getAllByName(any()); - // Default values. Individual tests can override these. - when(mCm.getLinkProperties(any())).thenReturn(TEST_LINKPROPERTIES); - when(mCm.getNetworkCapabilities(any())).thenReturn(METERED_CAPABILITIES); - setMinDataStallEvaluateInterval(500); setDataStallEvaluationType(DATA_STALL_EVALUATION_TYPE_DNS); setValidDataStallDnsTimeThreshold(500); @@ -195,10 +196,9 @@ public class NetworkMonitorTest { private class WrappedNetworkMonitor extends NetworkMonitor { private long mProbeTime = 0; - WrappedNetworkMonitor(Context context, Network network, IpConnectivityLog logger, - Dependencies deps, DataStallStatsUtils statsUtils) { - super(context, mCallbacks, network, logger, - new SharedLog("test_nm"), deps, statsUtils); + WrappedNetworkMonitor() { + super(mContext, mCallbacks, mNetwork, mLogger, mValidationLogger, mDependencies, + mDataStallStatsUtils); } @Override @@ -216,33 +216,30 @@ public class NetworkMonitorTest { } } - private WrappedNetworkMonitor makeMeteredWrappedNetworkMonitor() { - final WrappedNetworkMonitor nm = new WrappedNetworkMonitor( - mContext, mNetwork, mLogger, mDependencies, mDataStallStatsUtils); - when(mCm.getNetworkCapabilities(any())).thenReturn(METERED_CAPABILITIES); + private WrappedNetworkMonitor makeMonitor() { + final WrappedNetworkMonitor nm = new WrappedNetworkMonitor(); nm.start(); waitForIdle(nm.getHandler()); return nm; } - private WrappedNetworkMonitor makeNotMeteredWrappedNetworkMonitor() { - final WrappedNetworkMonitor nm = new WrappedNetworkMonitor( - mContext, mNetwork, mLogger, mDependencies, mDataStallStatsUtils); - when(mCm.getNetworkCapabilities(any())).thenReturn(NOT_METERED_CAPABILITIES); - nm.start(); - waitForIdle(nm.getHandler()); + private WrappedNetworkMonitor makeMeteredNetworkMonitor() { + final WrappedNetworkMonitor nm = makeMonitor(); + setNetworkCapabilities(nm, METERED_CAPABILITIES); return nm; } - private NetworkMonitor makeMonitor() { - final NetworkMonitor nm = new NetworkMonitor( - mContext, mCallbacks, mNetwork, mLogger, mValidationLogger, - mDependencies, mDataStallStatsUtils); - nm.start(); - waitForIdle(nm.getHandler()); + private WrappedNetworkMonitor makeNotMeteredNetworkMonitor() { + final WrappedNetworkMonitor nm = makeMonitor(); + setNetworkCapabilities(nm, NOT_METERED_CAPABILITIES); return nm; } + private void setNetworkCapabilities(NetworkMonitor nm, NetworkCapabilities nc) { + nm.notifyNetworkCapabilitiesChanged(nc); + waitForIdle(nm.getHandler()); + } + private void waitForIdle(Handler handler) { final ConditionVariable cv = new ConditionVariable(false); handler.post(cv::open); @@ -256,7 +253,7 @@ public class NetworkMonitorTest { setSslException(mHttpsConnection); setPortal302(mHttpConnection); - assertPortal(makeMonitor().isCaptivePortal()); + runPortalNetworkTest(); } @Test @@ -264,17 +261,7 @@ public class NetworkMonitorTest { setStatus(mHttpsConnection, 204); setStatus(mHttpConnection, 500); - assertNotPortal(makeMonitor().isCaptivePortal()); - } - - @Test - public void testIsCaptivePortal_HttpsProbeFailedHttpSuccessNotUsed() throws IOException { - setSslException(mHttpsConnection); - // Even if HTTP returns a 204, do not use the result unless HTTPS succeeded - setStatus(mHttpConnection, 204); - setStatus(mFallbackConnection, 500); - - assertFailed(makeMonitor().isCaptivePortal()); + runNotPortalNetworkTest(); } @Test @@ -283,17 +270,17 @@ public class NetworkMonitorTest { setStatus(mHttpConnection, 500); setPortal302(mFallbackConnection); - assertPortal(makeMonitor().isCaptivePortal()); + runPortalNetworkTest(); } @Test public void testIsCaptivePortal_FallbackProbeIsNotPortal() throws IOException { setSslException(mHttpsConnection); setStatus(mHttpConnection, 500); - setStatus(mFallbackConnection, 204); + setStatus(mFallbackConnection, 500); // Fallback probe did not see portal, HTTPS failed -> inconclusive - assertFailed(makeMonitor().isCaptivePortal()); + runFailedNetworkTest(); } @Test @@ -310,15 +297,15 @@ public class NetworkMonitorTest { // TEST_OTHER_FALLBACK_URL is third when(mRandom.nextInt()).thenReturn(2); - final NetworkMonitor monitor = makeMonitor(); - // First check always uses the first fallback URL: inconclusive - assertFailed(monitor.isCaptivePortal()); + final NetworkMonitor monitor = runNetworkTest(NETWORK_TEST_RESULT_INVALID); + assertNull(mNetworkTestedRedirectUrlCaptor.getValue()); verify(mFallbackConnection, times(1)).getResponseCode(); verify(mOtherFallbackConnection, never()).getResponseCode(); // Second check uses the URL chosen by Random - assertPortal(monitor.isCaptivePortal()); + final CaptivePortalProbeResult result = monitor.isCaptivePortal(); + assertTrue(result.isPortal()); verify(mOtherFallbackConnection, times(1)).getResponseCode(); } @@ -328,7 +315,7 @@ public class NetworkMonitorTest { setStatus(mHttpConnection, 500); setStatus(mFallbackConnection, 404); - assertFailed(makeMonitor().isCaptivePortal()); + runFailedNetworkTest(); verify(mFallbackConnection, times(1)).getResponseCode(); verify(mOtherFallbackConnection, never()).getResponseCode(); } @@ -342,7 +329,7 @@ public class NetworkMonitorTest { setStatus(mHttpConnection, 500); setPortal302(mOtherFallbackConnection); - assertPortal(makeMonitor().isCaptivePortal()); + runPortalNetworkTest(); verify(mOtherFallbackConnection, times(1)).getResponseCode(); verify(mFallbackConnection, never()).getResponseCode(); } @@ -360,12 +347,12 @@ public class NetworkMonitorTest { } @Test - public void testIsCaptivePortal_FallbackSpecIsNotPortal() throws IOException { + public void testIsCaptivePortal_FallbackSpecIsPartial() throws IOException { setupFallbackSpec(); set302(mOtherFallbackConnection, "https://www.google.com/test?q=3"); - // HTTPS failed, fallback spec did not see a portal -> inconclusive - assertFailed(makeMonitor().isCaptivePortal()); + // HTTPS failed, fallback spec went through -> partial connectivity + runPartialConnectivityNetworkTest(); verify(mOtherFallbackConnection, times(1)).getResponseCode(); verify(mFallbackConnection, never()).getResponseCode(); } @@ -375,7 +362,7 @@ public class NetworkMonitorTest { setupFallbackSpec(); set302(mOtherFallbackConnection, "http://login.portal.example.com"); - assertPortal(makeMonitor().isCaptivePortal()); + runPortalNetworkTest(); } @Test @@ -384,20 +371,20 @@ public class NetworkMonitorTest { setSslException(mHttpsConnection); setPortal302(mHttpConnection); - assertNotPortal(makeMonitor().isCaptivePortal()); + runNotPortalNetworkTest(); } @Test public void testIsDataStall_EvaluationDisabled() { setDataStallEvaluationType(0); - WrappedNetworkMonitor wrappedMonitor = makeMeteredWrappedNetworkMonitor(); + WrappedNetworkMonitor wrappedMonitor = makeMeteredNetworkMonitor(); wrappedMonitor.setLastProbeTime(SystemClock.elapsedRealtime() - 100); assertFalse(wrappedMonitor.isDataStall()); } @Test public void testIsDataStall_EvaluationDnsOnNotMeteredNetwork() { - WrappedNetworkMonitor wrappedMonitor = makeNotMeteredWrappedNetworkMonitor(); + WrappedNetworkMonitor wrappedMonitor = makeNotMeteredNetworkMonitor(); wrappedMonitor.setLastProbeTime(SystemClock.elapsedRealtime() - 100); makeDnsTimeoutEvent(wrappedMonitor, DEFAULT_DNS_TIMEOUT_THRESHOLD); assertTrue(wrappedMonitor.isDataStall()); @@ -405,7 +392,7 @@ public class NetworkMonitorTest { @Test public void testIsDataStall_EvaluationDnsOnMeteredNetwork() { - WrappedNetworkMonitor wrappedMonitor = makeMeteredWrappedNetworkMonitor(); + WrappedNetworkMonitor wrappedMonitor = makeMeteredNetworkMonitor(); wrappedMonitor.setLastProbeTime(SystemClock.elapsedRealtime() - 100); assertFalse(wrappedMonitor.isDataStall()); @@ -416,7 +403,7 @@ public class NetworkMonitorTest { @Test public void testIsDataStall_EvaluationDnsWithDnsTimeoutCount() { - WrappedNetworkMonitor wrappedMonitor = makeMeteredWrappedNetworkMonitor(); + WrappedNetworkMonitor wrappedMonitor = makeMeteredNetworkMonitor(); wrappedMonitor.setLastProbeTime(SystemClock.elapsedRealtime() - 1000); makeDnsTimeoutEvent(wrappedMonitor, 3); assertFalse(wrappedMonitor.isDataStall()); @@ -430,7 +417,7 @@ public class NetworkMonitorTest { // Set the value to larger than the default dns log size. setConsecutiveDnsTimeoutThreshold(51); - wrappedMonitor = makeMeteredWrappedNetworkMonitor(); + wrappedMonitor = makeMeteredNetworkMonitor(); wrappedMonitor.setLastProbeTime(SystemClock.elapsedRealtime() - 1000); makeDnsTimeoutEvent(wrappedMonitor, 50); assertFalse(wrappedMonitor.isDataStall()); @@ -442,7 +429,7 @@ public class NetworkMonitorTest { @Test public void testIsDataStall_EvaluationDnsWithDnsTimeThreshold() { // Test dns events happened in valid dns time threshold. - WrappedNetworkMonitor wrappedMonitor = makeMeteredWrappedNetworkMonitor(); + WrappedNetworkMonitor wrappedMonitor = makeMeteredNetworkMonitor(); wrappedMonitor.setLastProbeTime(SystemClock.elapsedRealtime() - 100); makeDnsTimeoutEvent(wrappedMonitor, DEFAULT_DNS_TIMEOUT_THRESHOLD); assertFalse(wrappedMonitor.isDataStall()); @@ -451,7 +438,7 @@ public class NetworkMonitorTest { // Test dns events happened before valid dns time threshold. setValidDataStallDnsTimeThreshold(0); - wrappedMonitor = makeMeteredWrappedNetworkMonitor(); + wrappedMonitor = makeMeteredNetworkMonitor(); wrappedMonitor.setLastProbeTime(SystemClock.elapsedRealtime() - 100); makeDnsTimeoutEvent(wrappedMonitor, DEFAULT_DNS_TIMEOUT_THRESHOLD); assertFalse(wrappedMonitor.isDataStall()); @@ -464,24 +451,13 @@ public class NetworkMonitorTest { setSslException(mHttpsConnection); setStatus(mHttpConnection, 500); setStatus(mFallbackConnection, 404); - when(mCm.getNetworkCapabilities(any())).thenReturn(METERED_CAPABILITIES); - final NetworkMonitor nm = makeMonitor(); - nm.notifyNetworkConnected(); - - verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1)) - .notifyNetworkTested(NETWORK_TEST_RESULT_INVALID, null); + runFailedNetworkTest(); } @Test public void testNoInternetCapabilityValidated() throws Exception { - when(mCm.getNetworkCapabilities(any())).thenReturn(NO_INTERNET_CAPABILITIES); - - final NetworkMonitor nm = makeMonitor(); - nm.notifyNetworkConnected(); - - verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1)) - .notifyNetworkTested(NETWORK_TEST_RESULT_VALID, null); + runNetworkTest(NO_INTERNET_CAPABILITIES, NETWORK_TEST_RESULT_VALID); verify(mNetwork, never()).openConnection(any()); } @@ -491,7 +467,7 @@ public class NetworkMonitorTest { setPortal302(mHttpConnection); final NetworkMonitor nm = makeMonitor(); - nm.notifyNetworkConnected(); + nm.notifyNetworkConnected(TEST_LINK_PROPERTIES, METERED_CAPABILITIES); verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1)) .showProvisioningNotification(any(), any()); @@ -522,7 +498,7 @@ public class NetworkMonitorTest { @Test public void testDataStall_StallSuspectedAndSendMetrics() throws IOException { - WrappedNetworkMonitor wrappedMonitor = makeNotMeteredWrappedNetworkMonitor(); + WrappedNetworkMonitor wrappedMonitor = makeNotMeteredNetworkMonitor(); wrappedMonitor.setLastProbeTime(SystemClock.elapsedRealtime() - 1000); makeDnsTimeoutEvent(wrappedMonitor, 5); assertTrue(wrappedMonitor.isDataStall()); @@ -531,7 +507,7 @@ public class NetworkMonitorTest { @Test public void testDataStall_NoStallSuspectedAndSendMetrics() throws IOException { - WrappedNetworkMonitor wrappedMonitor = makeNotMeteredWrappedNetworkMonitor(); + WrappedNetworkMonitor wrappedMonitor = makeNotMeteredNetworkMonitor(); wrappedMonitor.setLastProbeTime(SystemClock.elapsedRealtime() - 1000); makeDnsTimeoutEvent(wrappedMonitor, 3); assertFalse(wrappedMonitor.isDataStall()); @@ -540,7 +516,7 @@ public class NetworkMonitorTest { @Test public void testCollectDataStallMetrics() { - WrappedNetworkMonitor wrappedMonitor = makeNotMeteredWrappedNetworkMonitor(); + WrappedNetworkMonitor wrappedMonitor = makeNotMeteredNetworkMonitor(); when(mTelephony.getDataNetworkType()).thenReturn(TelephonyManager.NETWORK_TYPE_LTE); when(mTelephony.getNetworkOperator()).thenReturn(TEST_MCCMNC); @@ -578,14 +554,11 @@ public class NetworkMonitorTest { setSslException(mHttpsConnection); setStatus(mHttpConnection, 204); - final NetworkMonitor nm = makeMonitor(); - nm.notifyNetworkConnected(); - verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1)) - .notifyNetworkTested(NETWORK_TEST_RESULT_PARTIAL_CONNECTIVITY, null); + final NetworkMonitor nm = runNetworkTest(NETWORK_TEST_RESULT_PARTIAL_CONNECTIVITY); nm.setAcceptPartialConnectivity(); verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1)) - .notifyNetworkTested(NETWORK_TEST_RESULT_VALID, null); + .notifyNetworkTested(eq(NETWORK_TEST_RESULT_VALID), any()); } @Test @@ -593,12 +566,12 @@ public class NetworkMonitorTest { setStatus(mHttpsConnection, 500); setStatus(mHttpConnection, 204); setStatus(mFallbackConnection, 500); - assertPartialConnectivity(makeMonitor().isCaptivePortal()); + runPartialConnectivityNetworkTest(); setStatus(mHttpsConnection, 500); setStatus(mHttpConnection, 500); setStatus(mFallbackConnection, 204); - assertPartialConnectivity(makeMonitor().isCaptivePortal()); + runPartialConnectivityNetworkTest(); } private void makeDnsTimeoutEvent(WrappedNetworkMonitor wrappedMonitor, int count) { @@ -660,26 +633,41 @@ public class NetworkMonitorTest { eq(Settings.Global.CAPTIVE_PORTAL_MODE), anyInt())).thenReturn(mode); } - private void assertPortal(CaptivePortalProbeResult result) { - assertTrue(result.isPortal()); - assertFalse(result.isFailed()); - assertFalse(result.isSuccessful()); + private void runPortalNetworkTest() { + runNetworkTest(NETWORK_TEST_RESULT_INVALID); + assertNotNull(mNetworkTestedRedirectUrlCaptor.getValue()); } - private void assertNotPortal(CaptivePortalProbeResult result) { - assertFalse(result.isPortal()); - assertFalse(result.isFailed()); - assertTrue(result.isSuccessful()); + private void runNotPortalNetworkTest() { + runNetworkTest(NETWORK_TEST_RESULT_VALID); + assertNull(mNetworkTestedRedirectUrlCaptor.getValue()); } - private void assertFailed(CaptivePortalProbeResult result) { - assertFalse(result.isPortal()); - assertTrue(result.isFailed()); - assertFalse(result.isSuccessful()); + private void runFailedNetworkTest() { + runNetworkTest(NETWORK_TEST_RESULT_INVALID); + assertNull(mNetworkTestedRedirectUrlCaptor.getValue()); } - private void assertPartialConnectivity(CaptivePortalProbeResult result) { - assertTrue(result.isPartialConnectivity()); + private void runPartialConnectivityNetworkTest() { + runNetworkTest(NETWORK_TEST_RESULT_PARTIAL_CONNECTIVITY); + assertNull(mNetworkTestedRedirectUrlCaptor.getValue()); + } + + private NetworkMonitor runNetworkTest(int testResult) { + return runNetworkTest(METERED_CAPABILITIES, testResult); + } + + private NetworkMonitor runNetworkTest(NetworkCapabilities nc, int testResult) { + final NetworkMonitor monitor = makeMonitor(); + monitor.notifyNetworkConnected(TEST_LINK_PROPERTIES, nc); + try { + verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1)) + .notifyNetworkTested(eq(testResult), mNetworkTestedRedirectUrlCaptor.capture()); + } catch (RemoteException e) { + fail("Unexpected exception: " + e); + } + + return monitor; } private void setSslException(HttpURLConnection connection) throws IOException { diff --git a/packages/NetworkStack/tests/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreServiceTest.java b/packages/NetworkStack/tests/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreServiceTest.java index d0e58b817e9d..94cc58919459 100644 --- a/packages/NetworkStack/tests/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreServiceTest.java +++ b/packages/NetworkStack/tests/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreServiceTest.java @@ -16,6 +16,8 @@ package com.android.server.connectivity.ipmemorystore; +import static com.android.server.connectivity.ipmemorystore.RegularMaintenanceJobService.InterruptMaintenance; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; @@ -24,6 +26,7 @@ import static org.junit.Assert.fail; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.doReturn; +import android.app.job.JobScheduler; import android.content.Context; import android.net.ipmemorystore.Blob; import android.net.ipmemorystore.IOnBlobRetrievedListener; @@ -37,6 +40,7 @@ import android.net.ipmemorystore.SameL3NetworkResponse; import android.net.ipmemorystore.SameL3NetworkResponseParcelable; import android.net.ipmemorystore.Status; import android.net.ipmemorystore.StatusParcelable; +import android.os.ConditionVariable; import android.os.IBinder; import android.os.RemoteException; @@ -69,6 +73,9 @@ public class IpMemoryStoreServiceTest { private static final String TEST_CLIENT_ID = "testClientId"; private static final String TEST_DATA_NAME = "testData"; + private static final int TEST_DATABASE_SIZE_THRESHOLD = 100 * 1024; //100KB + private static final int DEFAULT_TIMEOUT_MS = 5000; + private static final int LONG_TIMEOUT_MS = 30000; private static final int FAKE_KEY_COUNT = 20; private static final String[] FAKE_KEYS; static { @@ -80,6 +87,8 @@ public class IpMemoryStoreServiceTest { @Mock private Context mMockContext; + @Mock + private JobScheduler mMockJobScheduler; private File mDbFile; private IpMemoryStoreService mService; @@ -91,7 +100,22 @@ public class IpMemoryStoreServiceTest { final File dir = context.getFilesDir(); mDbFile = new File(dir, "test.db"); doReturn(mDbFile).when(mMockContext).getDatabasePath(anyString()); - mService = new IpMemoryStoreService(mMockContext); + doReturn(mMockJobScheduler).when(mMockContext) + .getSystemService(Context.JOB_SCHEDULER_SERVICE); + mService = new IpMemoryStoreService(mMockContext) { + @Override + protected int getDbSizeThreshold() { + return TEST_DATABASE_SIZE_THRESHOLD; + } + + @Override + boolean isDbSizeOverThreshold() { + // Add a 100ms delay here for pausing maintenance job a while. Interrupted flag can + // be set at this time. + waitForMs(100); + return super.isDbSizeOverThreshold(); + } + }; } @After @@ -200,10 +224,15 @@ public class IpMemoryStoreServiceTest { // Helper method to factorize some boilerplate private void doLatched(final String timeoutMessage, final Consumer<CountDownLatch> functor) { + doLatched(timeoutMessage, functor, DEFAULT_TIMEOUT_MS); + } + + private void doLatched(final String timeoutMessage, final Consumer<CountDownLatch> functor, + final int timeout) { final CountDownLatch latch = new CountDownLatch(1); functor.accept(latch); try { - if (!latch.await(5000, TimeUnit.MILLISECONDS)) { + if (!latch.await(timeout, TimeUnit.MILLISECONDS)) { fail(timeoutMessage); } } catch (InterruptedException e) { @@ -224,10 +253,51 @@ public class IpMemoryStoreServiceTest { }))); } + /** Insert large data that db size will be over threshold for maintenance test usage. */ + private void insertFakeDataAndOverThreshold() { + try { + final NetworkAttributes.Builder na = new NetworkAttributes.Builder(); + na.setAssignedV4Address((Inet4Address) Inet4Address.getByName("1.2.3.4")); + na.setGroupHint("hint1"); + na.setMtu(219); + na.setDnsAddresses(Arrays.asList(Inet6Address.getByName("0A1C:2E40:480A::1CA6"))); + final byte[] data = new byte[]{-3, 6, 8, -9, 12, -128, 0, 89, 112, 91, -34}; + final long time = System.currentTimeMillis() - 1; + for (int i = 0; i < 1000; i++) { + int errorCode = IpMemoryStoreDatabase.storeNetworkAttributes( + mService.mDb, + "fakeKey" + i, + // Let first 100 records get expiry. + i < 100 ? time : time + TimeUnit.HOURS.toMillis(i), + na.build()); + assertEquals(errorCode, Status.SUCCESS); + + errorCode = IpMemoryStoreDatabase.storeBlob( + mService.mDb, "fakeKey" + i, TEST_CLIENT_ID, TEST_DATA_NAME, data); + assertEquals(errorCode, Status.SUCCESS); + } + + // After added 5000 records, db size is larger than fake threshold(100KB). + assertTrue(mService.isDbSizeOverThreshold()); + } catch (final UnknownHostException e) { + fail("Insert fake data fail"); + } + } + + /** Wait for assigned time. */ + private void waitForMs(long ms) { + try { + Thread.sleep(ms); + } catch (final InterruptedException e) { + fail("Thread was interrupted"); + } + } + @Test public void testNetworkAttributes() throws UnknownHostException { final NetworkAttributes.Builder na = new NetworkAttributes.Builder(); na.setAssignedV4Address((Inet4Address) Inet4Address.getByName("1.2.3.4")); + na.setAssignedV4AddressExpiry(System.currentTimeMillis() + 7_200_000); na.setGroupHint("hint1"); na.setMtu(219); final String l2Key = FAKE_KEYS[0]; @@ -257,6 +327,8 @@ public class IpMemoryStoreServiceTest { + status.resultCode, status.isSuccess()); assertEquals(l2Key, key); assertEquals(attributes.assignedV4Address, attr.assignedV4Address); + assertEquals(attributes.assignedV4AddressExpiry, + attr.assignedV4AddressExpiry); assertEquals(attributes.groupHint, attr.groupHint); assertEquals(attributes.mtu, attr.mtu); assertEquals(attributes2.dnsAddresses, attr.dnsAddresses); @@ -278,7 +350,7 @@ public class IpMemoryStoreServiceTest { // Verify that this test does not miss any new field added later. // If any field is added to NetworkAttributes it must be tested here for storing // and retrieving. - assertEquals(4, Arrays.stream(NetworkAttributes.class.getDeclaredFields()) + assertEquals(5, Arrays.stream(NetworkAttributes.class.getDeclaredFields()) .filter(f -> !Modifier.isStatic(f.getModifiers())).count()); } @@ -341,7 +413,7 @@ public class IpMemoryStoreServiceTest { status.isSuccess()); assertEquals(l2Key, key); assertEquals(name, TEST_DATA_NAME); - Arrays.equals(b.data, data); + assertTrue(Arrays.equals(b.data, data)); latch.countDown(); }))); @@ -503,4 +575,64 @@ public class IpMemoryStoreServiceTest { latch.countDown(); }))); } + + + @Test + public void testFullMaintenance() { + insertFakeDataAndOverThreshold(); + + final InterruptMaintenance im = new InterruptMaintenance(0/* Fake JobId */); + // Do full maintenance and then db size should go down and meet the threshold. + doLatched("Maintenance unexpectedly completed successfully", latch -> + mService.fullMaintenance(onStatus((status) -> { + assertTrue("Execute full maintenance failed: " + + status.resultCode, status.isSuccess()); + latch.countDown(); + }), im), LONG_TIMEOUT_MS); + + // Assume that maintenance is successful, db size shall meet the threshold. + assertFalse(mService.isDbSizeOverThreshold()); + } + + @Test + public void testInterruptMaintenance() { + insertFakeDataAndOverThreshold(); + + final InterruptMaintenance im = new InterruptMaintenance(0/* Fake JobId */); + + // Test interruption immediately. + im.setInterrupted(true); + // Do full maintenance and the expectation is not completed by interruption. + doLatched("Maintenance unexpectedly completed successfully", latch -> + mService.fullMaintenance(onStatus((status) -> { + assertFalse(status.isSuccess()); + latch.countDown(); + }), im), LONG_TIMEOUT_MS); + + // Assume that no data are removed, db size shall be over the threshold. + assertTrue(mService.isDbSizeOverThreshold()); + + // Reset the flag and test interruption during maintenance. + im.setInterrupted(false); + + final ConditionVariable latch = new ConditionVariable(); + // Do full maintenance and the expectation is not completed by interruption. + mService.fullMaintenance(onStatus((status) -> { + assertFalse(status.isSuccess()); + latch.open(); + }), im); + + // Give a little bit of time for maintenance to start up for realism + waitForMs(50); + // Interrupt maintenance job. + im.setInterrupted(true); + + if (!latch.block(LONG_TIMEOUT_MS)) { + fail("Maintenance unexpectedly completed successfully"); + } + + // Assume that only do dropAllExpiredRecords method in previous maintenance, db size shall + // still be over the threshold. + assertTrue(mService.isDbSizeOverThreshold()); + } } diff --git a/packages/OsuLogin/res/values/strings.xml b/packages/OsuLogin/res/values/strings.xml index 06fa8c7b1e8f..14de0f503769 100644 --- a/packages/OsuLogin/res/values/strings.xml +++ b/packages/OsuLogin/res/values/strings.xml @@ -3,4 +3,6 @@ <string name="app_name">OsuLogin</string> <!-- action bar label [CHAR LIMIT=32] --> <string name="action_bar_label">Online Sign Up</string> + <!-- toast message [CHAR LIMIT=32] --> + <string name="sign_up_failed">Sign-up failed</string> </resources> diff --git a/packages/OsuLogin/src/com/android/hotspot2/osu/OsuLoginActivity.java b/packages/OsuLogin/src/com/android/hotspot2/osu/OsuLoginActivity.java index 82e33cc4aff9..3a994d741956 100644 --- a/packages/OsuLogin/src/com/android/hotspot2/osu/OsuLoginActivity.java +++ b/packages/OsuLogin/src/com/android/hotspot2/osu/OsuLoginActivity.java @@ -38,6 +38,7 @@ import android.webkit.WebSettings; import android.webkit.WebView; import android.webkit.WebViewClient; import android.widget.ProgressBar; +import android.widget.Toast; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; @@ -63,6 +64,7 @@ public class OsuLoginActivity extends Activity { private SwipeRefreshLayout mSwipeRefreshLayout; private ProgressBar mProgressBar; private boolean mForceDisconnect = true; + boolean mRedirectResponseReceived = false; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { @@ -141,6 +143,9 @@ public class OsuLoginActivity extends Activity { Log.d(TAG, "Lost for the current Network, close the browser"); } mForceDisconnect = false; // It is already disconnected. + if (!mRedirectResponseReceived) { + showSignUpFailedToast(); + } if (mNetwork.equals(network)) { finishAndRemoveTask(); } @@ -229,9 +234,13 @@ public class OsuLoginActivity extends Activity { return ""; } + private void showSignUpFailedToast() { + Toast.makeText(getApplicationContext(), R.string.sign_up_failed, + Toast.LENGTH_SHORT).show(); + } + private class OsuWebViewClient extends WebViewClient { boolean mPageError = false; - boolean mRedirectResponseReceived = false; @Override public void onPageStarted(WebView view, String urlString, Bitmap favicon) { diff --git a/packages/PackageInstaller/Android.bp b/packages/PackageInstaller/Android.bp new file mode 100644 index 000000000000..9420954748c4 --- /dev/null +++ b/packages/PackageInstaller/Android.bp @@ -0,0 +1,28 @@ +// 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. + +android_app { + name: "PackageInstaller", + + srcs: ["src/**/*.java"], + + certificate: "platform", + privileged: true, + platform_apis: true, + + static_libs: [ + "xz-java", + "androidx.leanback_leanback", + ], +} diff --git a/packages/PackageInstaller/AndroidManifest.xml b/packages/PackageInstaller/AndroidManifest.xml index 62535b635e44..b0e2700a1f30 100644 --- a/packages/PackageInstaller/AndroidManifest.xml +++ b/packages/PackageInstaller/AndroidManifest.xml @@ -43,14 +43,12 @@ <action android:name="android.intent.action.VIEW" /> <action android:name="android.intent.action.INSTALL_PACKAGE" /> <category android:name="android.intent.category.DEFAULT" /> - <data android:scheme="file" /> <data android:scheme="content" /> <data android:mimeType="application/vnd.android.package-archive" /> </intent-filter> <intent-filter android:priority="1"> <action android:name="android.intent.action.INSTALL_PACKAGE" /> <category android:name="android.intent.category.DEFAULT" /> - <data android:scheme="file" /> <data android:scheme="package" /> <data android:scheme="content" /> </intent-filter> diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java b/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java index 441dbac24928..bde1b25b914f 100644 --- a/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java +++ b/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java @@ -26,6 +26,7 @@ import android.app.AppGlobals; import android.app.AppOpsManager; import android.app.Dialog; import android.app.DialogFragment; +import android.app.admin.DevicePolicyManager; import android.content.ActivityNotFoundException; import android.content.ContentResolver; import android.content.Context; @@ -427,7 +428,7 @@ public class PackageInstallerActivity extends AlertActivity { if (mAllowUnknownSources || !isInstallRequestFromUnknownSource(getIntent())) { initiateInstall(); } else { - // Check for unknown sources restriction + // Check for unknown sources restrictions. final int unknownSourcesRestrictionSource = mUserManager.getUserRestrictionSource( UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, Process.myUserHandle()); final int unknownSourcesGlobalRestrictionSource = mUserManager.getUserRestrictionSource( @@ -436,16 +437,28 @@ public class PackageInstallerActivity extends AlertActivity { & (unknownSourcesRestrictionSource | unknownSourcesGlobalRestrictionSource); if (systemRestriction != 0) { showDialogInner(DLG_UNKNOWN_SOURCES_RESTRICTED_FOR_USER); - } else if (unknownSourcesRestrictionSource != UserManager.RESTRICTION_NOT_SET - || unknownSourcesGlobalRestrictionSource != UserManager.RESTRICTION_NOT_SET) { - startActivity(new Intent(Settings.ACTION_SHOW_ADMIN_SUPPORT_DETAILS)); - finish(); + } else if (unknownSourcesRestrictionSource != UserManager.RESTRICTION_NOT_SET) { + startAdminSupportDetailsActivity(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES); + } else if (unknownSourcesGlobalRestrictionSource != UserManager.RESTRICTION_NOT_SET) { + startAdminSupportDetailsActivity( + UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY); } else { handleUnknownSources(); } } } + private void startAdminSupportDetailsActivity(String restriction) { + // If the given restriction is set by an admin, display information about the + // admin enforcing the restriction for the affected user. + final DevicePolicyManager dpm = getSystemService(DevicePolicyManager.class); + final Intent showAdminSupportDetailsIntent = dpm.createAdminSupportIntent(restriction); + if (showAdminSupportDetailsIntent != null) { + startActivity(showAdminSupportDetailsIntent); + } + finish(); + } + private void handleUnknownSources() { if (mOriginatingPackage == null) { Log.i(TAG, "No source found for package " + mPkgInfo.packageName); diff --git a/packages/SettingsLib/AdaptiveIcon/Android.bp b/packages/SettingsLib/AdaptiveIcon/Android.bp new file mode 100644 index 000000000000..7f4442deecd6 --- /dev/null +++ b/packages/SettingsLib/AdaptiveIcon/Android.bp @@ -0,0 +1,13 @@ +android_library { + name: "SettingsLibAdaptiveIcon", + + srcs: ["src/**/*.java"], + resource_dirs: ["res"], + + static_libs: [ + "androidx.annotation_annotation", + "SettingsLibTile" + ], + + min_sdk_version: "21", +} diff --git a/packages/SettingsLib/AdaptiveIcon/AndroidManifest.xml b/packages/SettingsLib/AdaptiveIcon/AndroidManifest.xml new file mode 100644 index 000000000000..256b8f3ea477 --- /dev/null +++ b/packages/SettingsLib/AdaptiveIcon/AndroidManifest.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2019 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.settingslib.widget"> + + <uses-sdk android:minSdkVersion="21" /> + +</manifest> diff --git a/packages/SettingsLib/AdaptiveIcon/res/values/colors.xml b/packages/SettingsLib/AdaptiveIcon/res/values/colors.xml new file mode 100644 index 000000000000..76d106a067dd --- /dev/null +++ b/packages/SettingsLib/AdaptiveIcon/res/values/colors.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2019 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<resources> + <color name="homepage_generic_icon_background">#1A73E8</color> + + <color name="bt_outline_color">#1f000000</color> <!-- icon outline color --> +</resources> diff --git a/packages/SettingsLib/AdaptiveIcon/res/values/dimens.xml b/packages/SettingsLib/AdaptiveIcon/res/values/dimens.xml new file mode 100644 index 000000000000..7f5b58c48abb --- /dev/null +++ b/packages/SettingsLib/AdaptiveIcon/res/values/dimens.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2019 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources> + <!-- Dashboard foreground image inset (from background edge to foreground edge) --> + <dimen name="dashboard_tile_foreground_image_inset">6dp</dimen> + + <!-- Stroke size of adaptive outline --> + <dimen name="adaptive_outline_stroke">1dp</dimen> +</resources>
\ No newline at end of file diff --git a/packages/SettingsLib/AdaptiveIcon/src/com/android/settingslib/widget/AdaptiveIcon.java b/packages/SettingsLib/AdaptiveIcon/src/com/android/settingslib/widget/AdaptiveIcon.java new file mode 100644 index 000000000000..fc93650a6b85 --- /dev/null +++ b/packages/SettingsLib/AdaptiveIcon/src/com/android/settingslib/widget/AdaptiveIcon.java @@ -0,0 +1,130 @@ +/* + * 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.settingslib.widget; + +import static androidx.annotation.VisibleForTesting.NONE; + +import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_ICON_BACKGROUND_ARGB; +import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_ICON_BACKGROUND_HINT; + +import android.content.Context; +import android.content.pm.PackageManager; +import android.graphics.PorterDuff; +import android.graphics.drawable.Drawable; +import android.graphics.drawable.LayerDrawable; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.VisibleForTesting; + +import com.android.settingslib.drawer.Tile; + +/** + * Adaptive icon that can set background color + */ +public class AdaptiveIcon extends LayerDrawable { + + private static final String TAG = "AdaptiveHomepageIcon"; + + @VisibleForTesting(otherwise = NONE) + int mBackgroundColor = -1; + private AdaptiveConstantState mAdaptiveConstantState; + + public AdaptiveIcon(Context context, Drawable foreground) { + super(new Drawable[]{ + new AdaptiveIconShapeDrawable(context.getResources()), + foreground + }); + final int insetPx = context.getResources() + .getDimensionPixelSize(R.dimen.dashboard_tile_foreground_image_inset); + setLayerInset(1 /* index */, insetPx, insetPx, insetPx, insetPx); + mAdaptiveConstantState = new AdaptiveConstantState(context, foreground); + } + + /** + * According {@code tile} metaData to set background color + */ + public void setBackgroundColor(Context context, Tile tile) { + final Bundle metaData = tile.getMetaData(); + try { + if (metaData != null) { + // Load from bg.argb first + int bgColor = metaData.getInt(META_DATA_PREFERENCE_ICON_BACKGROUND_ARGB, + 0 /* default */); + // Not found, load from bg.hint + if (bgColor == 0) { + final int colorRes = metaData.getInt(META_DATA_PREFERENCE_ICON_BACKGROUND_HINT, + 0 /* default */); + if (colorRes != 0) { + bgColor = context.getPackageManager() + .getResourcesForApplication(tile.getPackageName()) + .getColor(colorRes, null /* theme */); + } + } + // If found anything, use it. + if (bgColor != 0) { + setBackgroundColor(bgColor); + return; + } + } + } catch (PackageManager.NameNotFoundException e) { + Log.e(TAG, "Failed to set background color for " + tile.getPackageName()); + } + setBackgroundColor(context.getColor(R.color.homepage_generic_icon_background)); + } + + /** + * Set background color by {@code color} + */ + public void setBackgroundColor(int color) { + mBackgroundColor = color; + getDrawable(0).setColorFilter(color, PorterDuff.Mode.SRC_ATOP); + Log.d(TAG, "Setting background color " + mBackgroundColor); + mAdaptiveConstantState.mColor = color; + } + + @Override + public ConstantState getConstantState() { + return mAdaptiveConstantState; + } + + @VisibleForTesting + static class AdaptiveConstantState extends ConstantState { + Context mContext; + Drawable mDrawable; + int mColor; + + AdaptiveConstantState(Context context, Drawable drawable) { + this.mContext = context; + this.mDrawable = drawable; + } + + @Override + public Drawable newDrawable() { + final AdaptiveIcon + icon = new AdaptiveIcon(mContext, mDrawable); + icon.setBackgroundColor(mColor); + + return icon; + } + + @Override + public int getChangingConfigurations() { + return 0; + } + } +} diff --git a/packages/SettingsLib/AdaptiveIcon/src/com/android/settingslib/widget/AdaptiveIconShapeDrawable.java b/packages/SettingsLib/AdaptiveIcon/src/com/android/settingslib/widget/AdaptiveIconShapeDrawable.java new file mode 100644 index 000000000000..4d7610cf97b6 --- /dev/null +++ b/packages/SettingsLib/AdaptiveIcon/src/com/android/settingslib/widget/AdaptiveIconShapeDrawable.java @@ -0,0 +1,59 @@ +/* + * 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.settingslib.widget; + +import android.content.res.Resources; +import android.content.res.Resources.Theme; +import android.graphics.Path; +import android.graphics.drawable.AdaptiveIconDrawable; +import android.graphics.drawable.ShapeDrawable; +import android.graphics.drawable.shapes.PathShape; +import android.util.AttributeSet; +import android.util.PathParser; + +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; + +import java.io.IOException; + +/** + * Draws a filled {@link ShapeDrawable} using the path from {@link AdaptiveIconDrawable}. + */ +public class AdaptiveIconShapeDrawable extends ShapeDrawable { + public AdaptiveIconShapeDrawable() { + super(); + } + + public AdaptiveIconShapeDrawable(Resources resources) { + super(); + init(resources); + } + + @Override + public void inflate(Resources r, XmlPullParser parser, AttributeSet attrs, Theme theme) + throws XmlPullParserException, IOException { + super.inflate(r, parser, attrs, theme); + init(r); + } + + private void init(Resources resources) { + final float pathSize = AdaptiveIconDrawable.MASK_SIZE; + final Path path = new Path(PathParser.createPathFromPathData( + resources.getString(com.android.internal.R.string.config_icon_mask))); + setShape(new PathShape(path, pathSize, pathSize)); + } +} diff --git a/packages/SettingsLib/AdaptiveIcon/src/com/android/settingslib/widget/AdaptiveOutlineDrawable.java b/packages/SettingsLib/AdaptiveIcon/src/com/android/settingslib/widget/AdaptiveOutlineDrawable.java new file mode 100644 index 000000000000..1c65bc248961 --- /dev/null +++ b/packages/SettingsLib/AdaptiveIcon/src/com/android/settingslib/widget/AdaptiveOutlineDrawable.java @@ -0,0 +1,87 @@ +/* + * 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.settingslib.widget; + +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.Path; +import android.graphics.Rect; +import android.graphics.drawable.AdaptiveIconDrawable; +import android.graphics.drawable.DrawableWrapper; +import android.util.PathParser; + +import androidx.annotation.VisibleForTesting; + +/** + * Adaptive outline drawable with white plain background color and black outline + */ +public class AdaptiveOutlineDrawable extends DrawableWrapper { + @VisibleForTesting + final Paint mOutlinePaint; + private Path mPath; + private final int mInsetPx; + private final Bitmap mBitmap; + + public AdaptiveOutlineDrawable(Resources resources, Bitmap bitmap) { + super(new AdaptiveIconShapeDrawable(resources)); + + getDrawable().setTint(Color.WHITE); + mPath = new Path(PathParser.createPathFromPathData( + resources.getString(com.android.internal.R.string.config_icon_mask))); + mOutlinePaint = new Paint(); + mOutlinePaint.setColor(resources.getColor(R.color.bt_outline_color, null)); + mOutlinePaint.setStyle(Paint.Style.STROKE); + mOutlinePaint.setStrokeWidth(resources.getDimension(R.dimen.adaptive_outline_stroke)); + mOutlinePaint.setAntiAlias(true); + + mInsetPx = resources + .getDimensionPixelSize(R.dimen.dashboard_tile_foreground_image_inset); + mBitmap = bitmap; + } + + @Override + public void draw(Canvas canvas) { + super.draw(canvas); + final Rect bounds = getBounds(); + final float pathSize = AdaptiveIconDrawable.MASK_SIZE; + + final float scaleX = (bounds.right - bounds.left) / pathSize; + final float scaleY = (bounds.bottom - bounds.top) / pathSize; + + final int count = canvas.save(); + canvas.scale(scaleX, scaleY); + // Draw outline + canvas.drawPath(mPath, mOutlinePaint); + canvas.restoreToCount(count); + + // Draw the foreground icon + canvas.drawBitmap(mBitmap, bounds.left + mInsetPx, bounds.top + mInsetPx, null); + } + + @Override + public int getIntrinsicHeight() { + return mBitmap.getHeight() + 2 * mInsetPx; + } + + @Override + public int getIntrinsicWidth() { + return mBitmap.getWidth() + 2 * mInsetPx; + } +} diff --git a/packages/SettingsLib/Android.bp b/packages/SettingsLib/Android.bp index 730e9e134e3d..b532621cd617 100644 --- a/packages/SettingsLib/Android.bp +++ b/packages/SettingsLib/Android.bp @@ -22,6 +22,7 @@ android_library { "SettingsLibEntityHeaderWidgets", "SettingsLibBarChartPreference", "SettingsLibProgressBar", + "SettingsLibAdaptiveIcon", ], // ANDROIDMK TRANSLATION ERROR: unsupported assignment to LOCAL_SHARED_JAVA_LIBRARIES diff --git a/packages/SettingsLib/BarChartPreference/res/layout/settings_bar_chart.xml b/packages/SettingsLib/BarChartPreference/res/layout/settings_bar_chart.xml index 9b3d1dfb6568..25246d63f2b7 100644 --- a/packages/SettingsLib/BarChartPreference/res/layout/settings_bar_chart.xml +++ b/packages/SettingsLib/BarChartPreference/res/layout/settings_bar_chart.xml @@ -20,17 +20,11 @@ xmlns:settings="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginStart="10dp" - android:layout_marginEnd="10dp" - android:gravity="center" - android:orientation="vertical"> + style="@style/SettingsBarChart"> <TextView android:id="@+id/bar_chart_title" - android:layout_width="wrap_content" - android:layout_height="48dp" - android:gravity="center" - android:textAppearance="@style/BarChart.Text.HeaderTitle"/> + style="@style/SettingsBarChartTitle"/> <LinearLayout android:id="@+id/bar_views_container" @@ -46,36 +40,29 @@ <com.android.settingslib.widget.BarView android:id="@+id/bar_view1" - style="@style/BarViewStyle" - settings:barColor="#A142F4"/> + style="@style/SettingsBarViewStyle" + settings:barColor="@color/settings_bar_view_1_color"/> <com.android.settingslib.widget.BarView android:id="@+id/bar_view2" - style="@style/BarViewStyle" - settings:barColor="#24C1E0"/> + style="@style/SettingsBarViewStyle" + settings:barColor="@color/settings_bar_view_2_color"/> <com.android.settingslib.widget.BarView android:id="@+id/bar_view3" - style="@style/BarViewStyle" - settings:barColor="#4285F4"/> + style="@style/SettingsBarViewStyle" + settings:barColor="@color/settings_bar_view_3_color"/> <com.android.settingslib.widget.BarView android:id="@+id/bar_view4" - style="@style/BarViewStyle" - settings:barColor="#009688"/> + style="@style/SettingsBarViewStyle" + settings:barColor="@color/settings_bar_view_4_color"/> </LinearLayout> <Button android:id="@+id/bar_chart_details" - style="@android:style/Widget.DeviceDefault.Button.Borderless.Colored" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:gravity="center"/> + style="@style/SettingsBarChartDetailsButton"/> </LinearLayout> <TextView android:id="@+id/empty_view" - android:layout_width="match_parent" - android:layout_height="@dimen/settings_bar_view_max_height" - android:gravity="center" - android:visibility="gone" - android:textAppearance="@style/BarChart.Text.Summary"/> + style="@style/SettingsBarChartEmptyText"/> </LinearLayout> diff --git a/packages/SettingsLib/BarChartPreference/res/layout/settings_bar_view.xml b/packages/SettingsLib/BarChartPreference/res/layout/settings_bar_view.xml index 093c5debaab7..e5d8284f91eb 100644 --- a/packages/SettingsLib/BarChartPreference/res/layout/settings_bar_view.xml +++ b/packages/SettingsLib/BarChartPreference/res/layout/settings_bar_view.xml @@ -24,33 +24,19 @@ <View android:id="@+id/bar_view" - android:layout_width="8dp" - android:layout_height="wrap_content"/> + android:layout_height="wrap_content" + style="@style/SettingsBarChartBar"/> <ImageView android:id="@+id/icon_view" - android:layout_width="@dimen/settings_bar_view_icon_size" - android:layout_height="@dimen/settings_bar_view_icon_size" - android:scaleType="fitCenter" - android:layout_marginTop="12dp"/> + style="@style/SettingsBarChartBarIcon"/> <TextView android:id="@+id/bar_title" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_marginTop="12dp" - android:singleLine="true" - android:ellipsize="marquee" - android:textAppearance="@style/BarChart.Text.Title"/> + style="@style/SettingsBarChartBarTitle"/> <TextView android:id="@+id/bar_summary" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_marginTop="4dp" - android:layout_marginBottom="12dp" - android:singleLine="true" - android:ellipsize="marquee" - android:textAppearance="@style/BarChart.Text.Summary"/> + style="@style/SettingsBarChartBarSummary"/> </LinearLayout>
\ No newline at end of file diff --git a/packages/SettingsLib/BarChartPreference/res/values/colors.xml b/packages/SettingsLib/BarChartPreference/res/values/colors.xml new file mode 100644 index 000000000000..f10fb1261fa1 --- /dev/null +++ b/packages/SettingsLib/BarChartPreference/res/values/colors.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2019 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources> + <color name="settings_bar_view_1_color">#A142F4</color> + <color name="settings_bar_view_2_color">#24C1E0</color> + <color name="settings_bar_view_3_color">#4285F4</color> + <color name="settings_bar_view_4_color">#009688</color> +</resources>
\ No newline at end of file diff --git a/packages/SettingsLib/BarChartPreference/res/values/styles.xml b/packages/SettingsLib/BarChartPreference/res/values/styles.xml index 094f8aa79ba3..8302c0118adf 100644 --- a/packages/SettingsLib/BarChartPreference/res/values/styles.xml +++ b/packages/SettingsLib/BarChartPreference/res/values/styles.xml @@ -16,7 +16,29 @@ --> <resources> - <style name="BarViewStyle"> + + <style name="SettingsBarChart"> + <item name="android:layout_marginStart">10dp</item> + <item name="android:layout_marginEnd">10dp</item> + <item name="android:gravity">center</item> + <item name="android:orientation">vertical</item> + </style> + + <style name="SettingsBarChartTitle"> + <item name="android:layout_width">wrap_content</item> + <item name="android:layout_height">48dp</item> + <item name="android:gravity">center</item> + <item name="android:textAppearance">@style/BarChart.Text.HeaderTitle</item> + </style> + + <style name="SettingsBarChartDetailsButton" + parent="@android:style/Widget.DeviceDefault.Button.Borderless.Colored"> + <item name="android:layout_width">wrap_content</item> + <item name="android:layout_height">wrap_content</item> + <item name="android:gravity">center</item> + </style> + + <style name="SettingsBarViewStyle"> <item name="android:layout_width">0dp</item> <item name="android:layout_height">250dp</item> <item name="android:layout_weight">1</item> @@ -24,6 +46,44 @@ <item name="android:layout_marginEnd">8dp</item> </style> + <style name="SettingsBarChartEmptyText"> + <item name="android:layout_width">match_parent</item> + <item name="android:layout_height">@dimen/settings_bar_view_max_height</item> + <item name="android:gravity">center</item> + <item name="android:visibility">gone</item> + <item name="android:textAppearance">@style/BarChart.Text.Summary</item> + </style> + + <style name="SettingsBarChartBar"> + <item name="android:layout_width">8dp</item> + </style> + + <style name="SettingsBarChartBarIcon"> + <item name="android:layout_width">@dimen/settings_bar_view_icon_size</item> + <item name="android:layout_height">@dimen/settings_bar_view_icon_size</item> + <item name="android:scaleType">fitCenter</item> + <item name="android:layout_marginTop">12dp</item> + </style> + + <style name="SettingsBarChartBarTitle"> + <item name="android:layout_width">wrap_content</item> + <item name="android:layout_height">wrap_content</item> + <item name="android:layout_marginTop">12dp</item> + <item name="android:singleLine">true</item> + <item name="android:ellipsize">marquee</item> + <item name="android:textAppearance">@style/BarChart.Text.Title</item> + </style> + + <style name="SettingsBarChartBarSummary"> + <item name="android:layout_width">wrap_content</item> + <item name="android:layout_height">wrap_content</item> + <item name="android:layout_marginTop">4dp</item> + <item name="android:layout_marginBottom">12dp</item> + <item name="android:singleLine">true</item> + <item name="android:ellipsize">marquee</item> + <item name="android:textAppearance">@style/BarChart.Text.Summary</item> + </style> + <style name="BarChart.Text" parent="@android:style/TextAppearance.Material.Subhead"> <item name="android:fontFamily">@*android:string/config_headlineFontFamilyMedium</item> diff --git a/packages/SettingsLib/EntityHeaderWidgets/res/layout/app_entities_header.xml b/packages/SettingsLib/EntityHeaderWidgets/res/layout/app_entities_header.xml index 716fc8ded734..71bbd5bd105a 100644 --- a/packages/SettingsLib/EntityHeaderWidgets/res/layout/app_entities_header.xml +++ b/packages/SettingsLib/EntityHeaderWidgets/res/layout/app_entities_header.xml @@ -20,8 +20,8 @@ android:id="@+id/app_entities_header" android:layout_width="match_parent" android:layout_height="wrap_content" - android:paddingStart="24dp" - android:paddingEnd="8dp" + android:paddingStart="16dp" + android:paddingEnd="16dp" android:gravity="center" android:orientation="vertical"> diff --git a/packages/SettingsLib/EntityHeaderWidgets/res/layout/app_view.xml b/packages/SettingsLib/EntityHeaderWidgets/res/layout/app_view.xml index 013d2d004471..0db6dfb94dd6 100644 --- a/packages/SettingsLib/EntityHeaderWidgets/res/layout/app_view.xml +++ b/packages/SettingsLib/EntityHeaderWidgets/res/layout/app_view.xml @@ -20,7 +20,8 @@ android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" - android:layout_marginEnd="16dp" + android:layout_marginStart="8dp" + android:layout_marginEnd="8dp" android:gravity="center" android:clickable="true" android:background="@*android:drawable/btn_borderless_material" diff --git a/packages/SettingsLib/LayoutPreference/res/layout/settings_entity_header.xml b/packages/SettingsLib/LayoutPreference/res/layout/settings_entity_header.xml index da575dbd7fac..3f0a06c68689 100644 --- a/packages/SettingsLib/LayoutPreference/res/layout/settings_entity_header.xml +++ b/packages/SettingsLib/LayoutPreference/res/layout/settings_entity_header.xml @@ -46,6 +46,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:singleLine="false" + android:gravity="center" android:ellipsize="marquee" android:textDirection="locale" android:layout_marginTop="8dp"/> diff --git a/packages/SettingsLib/Tile/Android.bp b/packages/SettingsLib/Tile/Android.bp new file mode 100644 index 000000000000..bf16ef317fd8 --- /dev/null +++ b/packages/SettingsLib/Tile/Android.bp @@ -0,0 +1,11 @@ +android_library { + name: "SettingsLibTile", + + srcs: ["src/**/*.java"], + + static_libs: [ + "androidx.annotation_annotation", + ], + + min_sdk_version: "21", +} diff --git a/packages/SettingsLib/Tile/AndroidManifest.xml b/packages/SettingsLib/Tile/AndroidManifest.xml new file mode 100644 index 000000000000..b13532e2a5fd --- /dev/null +++ b/packages/SettingsLib/Tile/AndroidManifest.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2019 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.settingslib.drawer"> + + <uses-sdk android:minSdkVersion="21" /> + +</manifest> diff --git a/packages/SettingsLib/src/com/android/settingslib/drawer/DashboardCategory.java b/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/DashboardCategory.java index a3dda658bec7..7b062b1ac9a9 100644 --- a/packages/SettingsLib/src/com/android/settingslib/drawer/DashboardCategory.java +++ b/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/DashboardCategory.java @@ -1,11 +1,11 @@ -/** - * Copyright (C) 2015 The Android Open Source Project +/* + * 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 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.android.settingslib.drawer; import static java.lang.String.CASE_INSENSITIVE_ORDER; @@ -26,6 +25,9 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +/** + * The category for handle {@link Tile} + */ public class DashboardCategory implements Parcelable { /** @@ -67,18 +69,30 @@ public class DashboardCategory implements Parcelable { return result; } + /** + * Add tile + */ public synchronized void addTile(Tile tile) { mTiles.add(tile); } + /** + * Remove tile + */ public synchronized void removeTile(int n) { mTiles.remove(n); } + /** + * Get size of tile + */ public int getTilesCount() { return mTiles.size(); } + /** + * Get tile + */ public Tile getTile(int n) { return mTiles.get(n); } diff --git a/packages/SettingsLib/src/com/android/settingslib/drawer/Tile.java b/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/Tile.java index d28b00a7ed39..0ffd471e64af 100644 --- a/packages/SettingsLib/src/com/android/settingslib/drawer/Tile.java +++ b/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/Tile.java @@ -1,11 +1,11 @@ -/** - * Copyright (C) 2015 The Android Open Source Project +/* + * 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 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -33,6 +33,7 @@ import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.res.Resources; +import android.content.res.TypedArray; import android.graphics.drawable.Icon; import android.os.Bundle; import android.os.Parcel; @@ -84,8 +85,8 @@ public class Tile implements Parcelable { mActivityPackage = in.readString(); mActivityName = in.readString(); mIntent = new Intent().setClassName(mActivityPackage, mActivityName); - final int N = in.readInt(); - for (int i = 0; i < N; i++) { + final int number = in.readInt(); + for (int i = 0; i < number; i++) { userHandle.add(UserHandle.CREATOR.createFromParcel(in)); } mCategory = in.readString(); @@ -101,9 +102,9 @@ public class Tile implements Parcelable { public void writeToParcel(Parcel dest, int flags) { dest.writeString(mActivityPackage); dest.writeString(mActivityName); - final int N = userHandle.size(); - dest.writeInt(N); - for (int i = 0; i < N; i++) { + final int size = userHandle.size(); + dest.writeInt(size); + for (int i = 0; i < size; i++) { userHandle.get(i).writeToParcel(dest, flags); } dest.writeString(mCategory); @@ -151,6 +152,9 @@ public class Tile implements Parcelable { } } + /** + * Check whether title has order. + */ public boolean hasOrder() { return mMetaData.containsKey(META_DATA_KEY_ORDER) && mMetaData.get(META_DATA_KEY_ORDER) instanceof Integer; @@ -262,6 +266,9 @@ public class Tile implements Parcelable { } } + /** + * Check whether title has key. + */ public boolean hasKey() { return mMetaData != null && mMetaData.containsKey(META_DATA_PREFERENCE_KEYHINT); } @@ -293,7 +300,15 @@ public class Tile implements Parcelable { } } if (iconResId != 0) { - return Icon.createWithResource(activityInfo.packageName, iconResId); + final Icon icon = Icon.createWithResource(activityInfo.packageName, iconResId); + if (isIconTintable(context)) { + final TypedArray a = context.obtainStyledAttributes(new int[] { + android.R.attr.colorControlNormal}); + final int tintColor = a.getColor(0, 0); + a.recycle(); + icon.setTint(tintColor); + } + return icon; } else { return null; } @@ -303,16 +318,12 @@ public class Tile implements Parcelable { * Whether the icon can be tinted. This is true when icon needs to be monochrome (single-color) */ public boolean isIconTintable(Context context) { + ensureMetadataNotStale(context); if (mMetaData != null && mMetaData.containsKey(TileUtils.META_DATA_PREFERENCE_ICON_TINTABLE)) { return mMetaData.getBoolean(TileUtils.META_DATA_PREFERENCE_ICON_TINTABLE); } - ensureMetadataNotStale(context); - final String pkgName = context.getPackageName(); - // If this drawable is coming from outside Settings, tint it to match the color. - final ActivityInfo activityInfo = getActivityInfo(context); - return activityInfo != null - && !TextUtils.equals(pkgName, activityInfo.packageName); + return false; } /** @@ -361,9 +372,12 @@ public class Tile implements Parcelable { } }; + /** + * Check whether title is only have primary profile + */ public boolean isPrimaryProfileOnly() { - String profile = mMetaData != null ? - mMetaData.getString(META_DATA_KEY_PROFILE) : PROFILE_ALL; + String profile = mMetaData != null + ? mMetaData.getString(META_DATA_KEY_PROFILE) : PROFILE_ALL; profile = (profile != null ? profile : PROFILE_ALL); return TextUtils.equals(profile, PROFILE_PRIMARY); } diff --git a/packages/SettingsLib/src/com/android/settingslib/drawer/TileUtils.java b/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/TileUtils.java index 91892abdfb44..31925ab64ec3 100644 --- a/packages/SettingsLib/src/com/android/settingslib/drawer/TileUtils.java +++ b/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/TileUtils.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 The Android Open Source Project + * 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. @@ -11,7 +11,7 @@ * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and - * limitations under the License + * limitations under the License. */ package com.android.settingslib.drawer; @@ -39,6 +39,10 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +/** + * Utils is a helper class that contains profile key, meta data, settings action + * and static methods for get icon or text from uri. + */ public class TileUtils { private static final boolean DEBUG_TIMING = false; diff --git a/packages/SettingsLib/res/drawable/ic_media_device.xml b/packages/SettingsLib/res/drawable/ic_media_device.xml new file mode 100644 index 000000000000..5a6aeb4a8e23 --- /dev/null +++ b/packages/SettingsLib/res/drawable/ic_media_device.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2019 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:viewportWidth="24" + android:viewportHeight="24" + android:width="24dp" + android:height="24dp" + android:tint="?android:attr/colorControlNormal"> + <path + android:fillColor="#00000000" + android:fillAlpha=".1" + android:pathData="M0 0h24v24H0z" /> + <path + android:fillColor="#00000000" + android:pathData="M0 0h24v24H0z" /> + <path + android:fillColor="#000000" + android:pathData="M21 3H3c-1.1 0-2 0.9-2 2v3h2V5h18v14h-7v2h7c1.1 0 2 -0.9 2-2V5c0-1.1 -0.9-2-2-2zM1 18v3h3c0-1.66-1.34-3-3-3zm0-4v2c2.76 0 5 2.24 5 5h2c0-3.87-3.13-7-7-7zm0-4v2c4.97 0 9 4.03 9 9h2c0-6.08-4.93-11-11-11z" /> +</vector>
\ No newline at end of file diff --git a/packages/SettingsLib/res/values/arrays.xml b/packages/SettingsLib/res/values/arrays.xml index ed3c11cd3ca3..39c55fd1925c 100644 --- a/packages/SettingsLib/res/values/arrays.xml +++ b/packages/SettingsLib/res/values/arrays.xml @@ -603,4 +603,26 @@ <item>3</item><item>3</item> </array> + <!-- Bluetooth icon foreground colors --> + <integer-array name="bt_icon_fg_colors"> + <item>@color/bt_color_icon_1</item> + <item>@color/bt_color_icon_2</item> + <item>@color/bt_color_icon_3</item> + <item>@color/bt_color_icon_4</item> + <item>@color/bt_color_icon_5</item> + <item>@color/bt_color_icon_6</item> + <item>@color/bt_color_icon_7</item> + </integer-array> + + <!-- Bluetooth icon background colors --> + <integer-array name="bt_icon_bg_colors"> + <item>@color/bt_color_bg_1</item> + <item>@color/bt_color_bg_2</item> + <item>@color/bt_color_bg_3</item> + <item>@color/bt_color_bg_4</item> + <item>@color/bt_color_bg_5</item> + <item>@color/bt_color_bg_6</item> + <item>@color/bt_color_bg_7</item> + </integer-array> + </resources> diff --git a/packages/SettingsLib/res/values/colors.xml b/packages/SettingsLib/res/values/colors.xml index 66bbb3a6c890..209b2cb7afd3 100644 --- a/packages/SettingsLib/res/values/colors.xml +++ b/packages/SettingsLib/res/values/colors.xml @@ -19,4 +19,20 @@ <color name="usage_graph_dots">@*android:color/tertiary_device_default_settings</color> <color name="list_divider_color">#64000000</color> + + <color name="bt_color_icon_1">#b4a50e0e</color> <!-- 72% Material Red 900 --> + <color name="bt_color_icon_2">#b40d652d</color> <!-- 72% Material Green 900 --> + <color name="bt_color_icon_3">#b4e37400</color> <!-- 72% Material Yellow 900 --> + <color name="bt_color_icon_4">#b4b06000</color> <!-- 72% Material Orange 900 --> + <color name="bt_color_icon_5">#b49c166b</color> <!-- 72% Material Pink 900 --> + <color name="bt_color_icon_6">#b4681da8</color> <!-- 72% Material Purple 900 --> + <color name="bt_color_icon_7">#b4007b83</color> <!-- 72% Material Cyan 900 --> + + <color name="bt_color_bg_1">#fad2cf</color> <!-- Material Red 100 --> + <color name="bt_color_bg_2">#ceead6</color> <!-- Material Green 100 --> + <color name="bt_color_bg_3">#feefc3</color> <!-- Material Yellow 100 --> + <color name="bt_color_bg_4">#fedfc8</color> <!-- Material Orange 100 --> + <color name="bt_color_bg_5">#fdcfe8</color> <!-- Material Pink 100 --> + <color name="bt_color_bg_6">#e9d2fd</color> <!-- Material Purple 100 --> + <color name="bt_color_bg_7">#cbf0f8</color> <!-- Material Cyan 100 --> </resources> diff --git a/packages/SettingsLib/res/values/dimens.xml b/packages/SettingsLib/res/values/dimens.xml index a9c5061f6d87..2cb9d4b14aa7 100644 --- a/packages/SettingsLib/res/values/dimens.xml +++ b/packages/SettingsLib/res/values/dimens.xml @@ -91,6 +91,7 @@ <!-- How far to inset the rounded edges --> <dimen name="stat_sys_mobile_signal_circle_inset">0.9dp</dimen> - + <!-- Size of nearby icon --> + <dimen name="bt_nearby_icon_size">24dp</dimen> </resources> diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothUtils.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothUtils.java index bb8c8a6768ed..46e9129d9cf8 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothUtils.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothUtils.java @@ -1,18 +1,30 @@ package com.android.settingslib.bluetooth; import android.bluetooth.BluetoothClass; +import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothProfile; import android.content.Context; +import android.content.Intent; +import android.content.res.Resources; +import android.graphics.Bitmap; import android.graphics.drawable.Drawable; +import android.net.Uri; +import android.provider.MediaStore; +import android.util.Log; import android.util.Pair; import androidx.annotation.DrawableRes; import com.android.settingslib.R; +import com.android.settingslib.widget.AdaptiveIcon; +import com.android.settingslib.widget.AdaptiveOutlineDrawable; +import java.io.IOException; import java.util.List; public class BluetoothUtils { + private static final String TAG = "BluetoothUtils"; + public static final boolean V = false; // verbose logging public static final boolean D = true; // regular logging @@ -112,4 +124,74 @@ public class BluetoothUtils { public static Drawable getBluetoothDrawable(Context context, @DrawableRes int resId) { return context.getDrawable(resId); } + + /** + * Get colorful bluetooth icon with description + */ + public static Pair<Drawable, String> getBtRainbowDrawableWithDescription(Context context, + CachedBluetoothDevice cachedDevice) { + final Pair<Drawable, String> pair = BluetoothUtils.getBtClassDrawableWithDescription( + context, cachedDevice); + final BluetoothDevice bluetoothDevice = cachedDevice.getDevice(); + final boolean untetheredHeadset = bluetoothDevice != null + ? Boolean.parseBoolean(bluetoothDevice.getMetadata( + BluetoothDevice.METADATA_IS_UNTHETHERED_HEADSET)) + : false; + final int iconSize = context.getResources().getDimensionPixelSize( + R.dimen.bt_nearby_icon_size); + final Resources resources = context.getResources(); + + // Deal with untethered headset + if (untetheredHeadset) { + final String uriString = bluetoothDevice != null + ? bluetoothDevice.getMetadata(BluetoothDevice.METADATA_MAIN_ICON) + : null; + final Uri iconUri = uriString != null ? Uri.parse(uriString) : null; + if (iconUri != null) { + try { + context.getContentResolver().takePersistableUriPermission(iconUri, + Intent.FLAG_GRANT_READ_URI_PERMISSION); + } catch (SecurityException e) { + Log.e(TAG, "Failed to take persistable permission for: " + iconUri); + } + try { + final Bitmap bitmap = MediaStore.Images.Media.getBitmap( + context.getContentResolver(), iconUri); + if (bitmap != null) { + final Bitmap resizedBitmap = Bitmap.createScaledBitmap(bitmap, iconSize, + iconSize, false); + bitmap.recycle(); + final AdaptiveOutlineDrawable drawable = new AdaptiveOutlineDrawable( + resources, resizedBitmap); + return new Pair<>(drawable, pair.second); + } + } catch (IOException e) { + Log.e(TAG, "Failed to get drawable for: " + iconUri, e); + } + } + } + + return new Pair<>(buildBtRainbowDrawable(context, + pair.first, cachedDevice.getAddress().hashCode()), pair.second); + } + + /** + * Build Bluetooth device icon with rainbow + */ + public static Drawable buildBtRainbowDrawable(Context context, Drawable drawable, + int hashCode) { + final Resources resources = context.getResources(); + + // Deal with normal headset + final int[] iconFgColors = resources.getIntArray(R.array.bt_icon_fg_colors); + final int[] iconBgColors = resources.getIntArray(R.array.bt_icon_bg_colors); + + // get color index based on mac address + final int index = Math.abs(hashCode % iconBgColors.length); + drawable.setTint(iconFgColors[index]); + final Drawable adaptiveIcon = new AdaptiveIcon(context, drawable); + ((AdaptiveIcon) adaptiveIcon).setBackgroundColor(iconBgColors[index]); + + return adaptiveIcon; + } } diff --git a/packages/SettingsLib/src/com/android/settingslib/graph/ThemedBatteryDrawable.kt b/packages/SettingsLib/src/com/android/settingslib/graph/ThemedBatteryDrawable.kt index 1bb6c443f29b..239b1d464ea3 100644 --- a/packages/SettingsLib/src/com/android/settingslib/graph/ThemedBatteryDrawable.kt +++ b/packages/SettingsLib/src/com/android/settingslib/graph/ThemedBatteryDrawable.kt @@ -130,11 +130,12 @@ open class ThemedBatteryDrawable(private val context: Context, frameColor: Int) } private val errorPaint = Paint(Paint.ANTI_ALIAS_FLAG).also { p -> - p.color = Utils.getColorErrorDefaultColor(context) + p.color = Utils.getColorStateListDefaultColor(context, R.color.batterymeter_plus_color) p.alpha = 255 p.isDither = true p.strokeWidth = 0f p.style = Paint.Style.FILL_AND_STROKE + p.blendMode = BlendMode.SRC } // Only used if dualTone is set to true @@ -201,10 +202,6 @@ open class ThemedBatteryDrawable(private val context: Context, frameColor: Int) if (!invertFillIcon) { c.drawPath(scaledBolt, fillPaint) } - } else if (powerSaveEnabled) { - // Clip out the plus shape - unifiedPath.op(scaledPlus, Path.Op.DIFFERENCE) - c.drawPath(scaledPlus, errorPaint) } if (dualTone) { @@ -243,10 +240,8 @@ open class ThemedBatteryDrawable(private val context: Context, frameColor: Int) } else if (powerSaveEnabled) { // If power save is enabled draw the perimeter path with colorError c.drawPath(scaledPerimeter, errorPaint) - - // But always put path protection around the plus sign - c.clipOutPath(scaledPlus) - c.drawPath(scaledPlus, fillColorStrokeProtection) + // And draw the plus sign on top of the fill + c.drawPath(scaledPlus, errorPaint) } } diff --git a/packages/SettingsLib/src/com/android/settingslib/media/BluetoothMediaDevice.java b/packages/SettingsLib/src/com/android/settingslib/media/BluetoothMediaDevice.java index 3092b9960c7e..2711e3175957 100644 --- a/packages/SettingsLib/src/com/android/settingslib/media/BluetoothMediaDevice.java +++ b/packages/SettingsLib/src/com/android/settingslib/media/BluetoothMediaDevice.java @@ -18,8 +18,11 @@ package com.android.settingslib.media; import android.bluetooth.BluetoothClass; import android.bluetooth.BluetoothDevice; import android.content.Context; +import android.graphics.drawable.Drawable; import android.util.Log; +import android.util.Pair; +import com.android.settingslib.bluetooth.BluetoothUtils; import com.android.settingslib.bluetooth.CachedBluetoothDevice; /** @@ -48,9 +51,10 @@ public class BluetoothMediaDevice extends MediaDevice { } @Override - public int getIcon() { - //TODO(b/117129183): This is not final icon for bluetooth device, just for demo. - return com.android.internal.R.drawable.ic_bt_headphones_a2dp; + public Drawable getIcon() { + final Pair<Drawable, String> pair = BluetoothUtils + .getBtRainbowDrawableWithDescription(mContext, mCachedDevice); + return pair.first; } @Override diff --git a/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaDevice.java b/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaDevice.java index 95f3d3d0f769..732e8dba3e44 100644 --- a/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaDevice.java +++ b/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaDevice.java @@ -16,10 +16,14 @@ package com.android.settingslib.media; import android.content.Context; +import android.graphics.drawable.Drawable; import android.widget.Toast; import androidx.mediarouter.media.MediaRouter; +import com.android.settingslib.R; +import com.android.settingslib.bluetooth.BluetoothUtils; + /** * InfoMediaDevice extends MediaDevice to represents wifi device. */ @@ -46,9 +50,10 @@ public class InfoMediaDevice extends MediaDevice { } @Override - public int getIcon() { - //TODO(b/121083246): This is not final icon for cast device, just for demo. - return com.android.internal.R.drawable.ic_settings_print; + public Drawable getIcon() { + //TODO(b/120669861): Return remote device icon uri once api is ready. + return BluetoothUtils.buildBtRainbowDrawable(mContext, + mContext.getDrawable(R.drawable.ic_media_device), getId().hashCode()); } @Override diff --git a/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java b/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java index 9b9e80310c18..53a852069478 100644 --- a/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java +++ b/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java @@ -16,6 +16,7 @@ package com.android.settingslib.media; import android.content.Context; +import android.graphics.drawable.Drawable; import android.text.TextUtils; import androidx.annotation.IntDef; @@ -70,11 +71,11 @@ public abstract class MediaDevice implements Comparable<MediaDevice> { public abstract String getSummary(); /** - * Get resource id of MediaDevice. + * Get icon of MediaDevice. * - * @return resource id of MediaDevice. + * @return drawable of icon. */ - public abstract int getIcon(); + public abstract Drawable getIcon(); /** * Get unique ID that represent MediaDevice diff --git a/packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java b/packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java index 8c3fcc077edc..af91c3464194 100644 --- a/packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java +++ b/packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java @@ -16,10 +16,12 @@ package com.android.settingslib.media; import android.content.Context; +import android.graphics.drawable.Drawable; import android.util.Log; import com.android.settingslib.R; import com.android.settingslib.bluetooth.A2dpProfile; +import com.android.settingslib.bluetooth.BluetoothUtils; import com.android.settingslib.bluetooth.HearingAidProfile; import com.android.settingslib.bluetooth.LocalBluetoothManager; import com.android.settingslib.bluetooth.LocalBluetoothProfileManager; @@ -56,8 +58,9 @@ public class PhoneMediaDevice extends MediaDevice { } @Override - public int getIcon() { - return R.drawable.ic_smartphone; + public Drawable getIcon() { + return BluetoothUtils.buildBtRainbowDrawable(mContext, + mContext.getDrawable(R.drawable.ic_smartphone), getId().hashCode()); } @Override diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java index 3acbcd3f6b41..8a88a4c64d0a 100644 --- a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java +++ b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java @@ -53,6 +53,7 @@ import android.os.UserHandle; import android.text.TextUtils; import android.util.ArraySet; import android.util.Log; +import android.util.Pair; import androidx.annotation.NonNull; @@ -65,8 +66,10 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.HashMap; import java.util.Iterator; +import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.atomic.AtomicInteger; @@ -197,6 +200,9 @@ public class AccessPoint implements Comparable<AccessPoint> { private final Context mContext; + private WifiManager mWifiManager; + private WifiManager.ActionListener mConnectListener; + private String ssid; private String bssid; private int security; @@ -1068,8 +1074,10 @@ public class AccessPoint implements Comparable<AccessPoint> { /** * Starts the OSU Provisioning flow. */ - public void startOsuProvisioning() { - mContext.getSystemService(WifiManager.class).startSubscriptionProvisioning( + public void startOsuProvisioning(@Nullable WifiManager.ActionListener connectListener) { + mConnectListener = connectListener; + + getWifiManager().startSubscriptionProvisioning( mOsuProvider, mContext.getMainExecutor(), new AccessPointProvisioningCallback() @@ -1539,12 +1547,20 @@ public class AccessPoint implements Comparable<AccessPoint> { return string; } + private WifiManager getWifiManager() { + if (mWifiManager == null) { + mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE); + } + return mWifiManager; + } + /** * Callbacks relaying changes to the AccessPoint representation. * * <p>All methods are invoked on the Main Thread. */ public interface AccessPointListener { + /** * Indicates a change to the externally visible state of the AccessPoint trigger by an * update of ScanResults, saved configuration state, connection state, or score @@ -1561,7 +1577,6 @@ public class AccessPoint implements Comparable<AccessPoint> { * changed */ @MainThread void onAccessPointChanged(AccessPoint accessPoint); - /** * Indicates the "wifi pie signal level" has changed, retrieved via calls to * {@link AccessPoint#getLevel()}. @@ -1643,11 +1658,46 @@ public class AccessPoint implements Comparable<AccessPoint> { mOsuProvisioningComplete = true; mOsuFailure = null; mOsuStatus = null; + ThreadUtils.postOnMainThread(() -> { if (mAccessPointListener != null) { mAccessPointListener.onAccessPointChanged(AccessPoint.this); } }); + + // Connect to the freshly provisioned network. + WifiManager wifiManager = getWifiManager(); + + PasspointConfiguration passpointConfig = wifiManager + .getMatchingPasspointConfigsForOsuProviders(Collections.singleton(mOsuProvider)) + .get(mOsuProvider); + if (passpointConfig == null) { + Log.e(TAG, "Missing PasspointConfiguration for newly provisioned network!"); + if (mConnectListener != null) { + mConnectListener.onFailure(0); + } + return; + } + + String fqdn = passpointConfig.getHomeSp().getFqdn(); + for (Pair<WifiConfiguration, Map<Integer, List<ScanResult>>> pairing : + wifiManager.getAllMatchingWifiConfigs(wifiManager.getScanResults())) { + WifiConfiguration config = pairing.first; + if (TextUtils.equals(config.FQDN, fqdn)) { + List<ScanResult> homeScans = + pairing.second.get(WifiManager.PASSPOINT_HOME_NETWORK); + List<ScanResult> roamingScans = + pairing.second.get(WifiManager.PASSPOINT_ROAMING_NETWORK); + + AccessPoint connectionAp = + new AccessPoint(mContext, config, homeScans, roamingScans); + wifiManager.connect(connectionAp.getConfig(), mConnectListener); + return; + } + } + if (mConnectListener != null) { + mConnectListener.onFailure(0); + } } } } diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java index fdc0fd33e6d7..5f2bc4e1d490 100644 --- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java +++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java @@ -84,7 +84,7 @@ public class WifiTracker implements LifecycleObserver, OnStart, OnStop, OnDestro private static final long DEFAULT_MAX_CACHED_SCORE_AGE_MILLIS = 20 * DateUtils.MINUTE_IN_MILLIS; /** Maximum age of scan results to hold onto while actively scanning. **/ - private static final long MAX_SCAN_RESULT_AGE_MILLIS = 15000; + @VisibleForTesting static final long MAX_SCAN_RESULT_AGE_MILLIS = 15000; private static final String TAG = "WifiTracker"; private static final boolean DBG() { @@ -142,6 +142,13 @@ public class WifiTracker implements LifecycleObserver, OnStart, OnStop, OnDestro */ private boolean mStaleScanResults = true; + /** + * Tracks whether the latest SCAN_RESULTS_AVAILABLE_ACTION contained new scans. If not, then + * we treat the last scan as an aborted scan and increase the eviction timeout window to avoid + * completely flushing the AP list before the next successful scan completes. + */ + private boolean mLastScanSucceeded = true; + // Does not need to be locked as it only updated on the worker thread, with the exception of // during onStart, which occurs before the receiver is registered on the work handler. private final HashMap<String, ScanResult> mScanResultCache = new HashMap<>(); @@ -478,17 +485,22 @@ public class WifiTracker implements LifecycleObserver, OnStart, OnStop, OnDestro } /** - * Remove old scan results from the cache. + * Remove old scan results from the cache. If {@link #mLastScanSucceeded} is false, then + * increase the timeout window to avoid completely flushing the AP list before the next + * successful scan completes. * * <p>Should only ever be invoked from {@link #updateScanResultCache(List)} when * {@link #mStaleScanResults} is false. */ private void evictOldScans() { + long evictionTimeoutMillis = mLastScanSucceeded ? MAX_SCAN_RESULT_AGE_MILLIS + : MAX_SCAN_RESULT_AGE_MILLIS * 2; + long nowMs = SystemClock.elapsedRealtime(); for (Iterator<ScanResult> iter = mScanResultCache.values().iterator(); iter.hasNext(); ) { ScanResult result = iter.next(); // result timestamp is in microseconds - if (nowMs - result.timestamp / 1000 > MAX_SCAN_RESULT_AGE_MILLIS) { + if (nowMs - result.timestamp / 1000 > evictionTimeoutMillis) { iter.remove(); } } @@ -840,6 +852,8 @@ public class WifiTracker implements LifecycleObserver, OnStart, OnStop, OnDestro WifiManager.WIFI_STATE_UNKNOWN)); } else if (WifiManager.SCAN_RESULTS_AVAILABLE_ACTION.equals(action)) { mStaleScanResults = false; + mLastScanSucceeded = + intent.getBooleanExtra(WifiManager.EXTRA_RESULTS_UPDATED, true); fetchScansAndConfigsAndUpdateAccessPoints(); } else if (WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION.equals(action) diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java index 9c8e3f4fe543..8e4027164587 100644 --- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java +++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java @@ -41,6 +41,7 @@ import android.net.wifi.ScanResult; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiEnterpriseConfig; import android.net.wifi.WifiInfo; +import android.net.wifi.WifiManager; import android.net.wifi.WifiNetworkScoreCache; import android.net.wifi.WifiSsid; import android.net.wifi.hotspot2.OsuProvider; @@ -53,6 +54,7 @@ import android.os.SystemClock; import android.text.SpannableString; import android.text.format.DateUtils; import android.util.ArraySet; +import android.util.Pair; import androidx.test.InstrumentationRegistry; import androidx.test.filters.SmallTest; @@ -72,6 +74,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.CountDownLatch; @@ -95,9 +98,12 @@ public class AccessPointTest { private Context mContext; private WifiInfo mWifiInfo; + @Mock private Context mMockContext; + @Mock private WifiManager mMockWifiManager; @Mock private RssiCurve mockBadgeCurve; @Mock private WifiNetworkScoreCache mockWifiNetworkScoreCache; @Mock private AccessPoint.AccessPointListener mMockAccessPointListener; + @Mock private WifiManager.ActionListener mMockConnectListener; private static final int NETWORK_ID = 123; private static final int DEFAULT_RSSI = -55; @@ -1360,6 +1366,9 @@ public class AccessPointTest { .isEqualTo(mContext.getString(R.string.tap_to_sign_up)); } + /** + * Verifies that the summary of an OSU entry updates based on provisioning status. + */ @Test public void testOsuAccessPointSummary_showsProvisioningUpdates() { AccessPoint osuAccessPoint = new AccessPoint(mContext, createOsuProvider(), @@ -1411,4 +1420,82 @@ public class AccessPointTest { assertThat(osuAccessPoint.getSummary()) .isEqualTo(mContext.getString(R.string.osu_sign_up_complete)); } + + /** + * Verifies that after provisioning through an OSU provider, we connect to the freshly + * provisioned network. + */ + @Test + public void testOsuAccessPoint_connectsAfterProvisioning() { + // Set up mock for WifiManager.getAllMatchingWifiConfigs + WifiConfiguration config = new WifiConfiguration(); + config.FQDN = "fqdn"; + Map<Integer, List<ScanResult>> scanMapping = new HashMap<>(); + scanMapping.put(WifiManager.PASSPOINT_HOME_NETWORK, mScanResults); + Pair<WifiConfiguration, Map<Integer, List<ScanResult>>> configMapPair = + new Pair<>(config, scanMapping); + List<Pair<WifiConfiguration, Map<Integer, List<ScanResult>>>> matchingWifiConfig = + new ArrayList<>(); + matchingWifiConfig.add(configMapPair); + when(mMockWifiManager.getAllMatchingWifiConfigs(any())).thenReturn(matchingWifiConfig); + + // Set up mock for WifiManager.getMatchingPasspointConfigsForOsuProviders + OsuProvider provider = createOsuProvider(); + PasspointConfiguration passpointConfig = new PasspointConfiguration(); + HomeSp homeSp = new HomeSp(); + homeSp.setFqdn("fqdn"); + homeSp.setFriendlyName("Test Provider"); + passpointConfig.setHomeSp(homeSp); + Map<OsuProvider, PasspointConfiguration> osuProviderConfigMap = new HashMap<>(); + osuProviderConfigMap.put(provider, passpointConfig); + when(mMockWifiManager + .getMatchingPasspointConfigsForOsuProviders(Collections.singleton(provider))) + .thenReturn(osuProviderConfigMap); + + when(mMockContext.getSystemService(Context.WIFI_SERVICE)).thenReturn(mMockWifiManager); + + AccessPoint osuAccessPoint = new AccessPoint(mMockContext, provider, mScanResults); + osuAccessPoint.setListener(mMockAccessPointListener); + + AccessPoint.AccessPointProvisioningCallback provisioningCallback = + osuAccessPoint.new AccessPointProvisioningCallback(); + provisioningCallback.onProvisioningComplete(); + + verify(mMockWifiManager).connect(any(), any()); + } + + /** + * Verifies that after provisioning through an OSU provider, we call the connect listener's + * onFailure() method if we cannot find the network we just provisioned. + */ + @Test + public void testOsuAccessPoint_noMatchingConfigsAfterProvisioning_callsOnFailure() { + // Set up mock for WifiManager.getAllMatchingWifiConfigs + when(mMockWifiManager.getAllMatchingWifiConfigs(any())).thenReturn(new ArrayList<>()); + + // Set up mock for WifiManager.getMatchingPasspointConfigsForOsuProviders + OsuProvider provider = createOsuProvider(); + PasspointConfiguration passpointConfig = new PasspointConfiguration(); + HomeSp homeSp = new HomeSp(); + homeSp.setFqdn("fqdn"); + homeSp.setFriendlyName("Test Provider"); + passpointConfig.setHomeSp(homeSp); + Map<OsuProvider, PasspointConfiguration> osuProviderConfigMap = new HashMap<>(); + osuProviderConfigMap.put(provider, passpointConfig); + when(mMockWifiManager + .getMatchingPasspointConfigsForOsuProviders(Collections.singleton(provider))) + .thenReturn(osuProviderConfigMap); + + when(mMockContext.getSystemService(Context.WIFI_SERVICE)).thenReturn(mMockWifiManager); + + AccessPoint osuAccessPoint = new AccessPoint(mMockContext, provider, mScanResults); + osuAccessPoint.setListener(mMockAccessPointListener); + osuAccessPoint.startOsuProvisioning(mMockConnectListener); + + AccessPoint.AccessPointProvisioningCallback provisioningCallback = + osuAccessPoint.new AccessPointProvisioningCallback(); + provisioningCallback.onProvisioningComplete(); + + verify(mMockConnectListener).onFailure(anyInt()); + } } diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java index edf414ddf323..683ec8bb5a6c 100644 --- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java +++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java @@ -270,7 +270,7 @@ public class WifiTrackerTest { SystemClock.elapsedRealtime() * 1000 /* microsecond timestamp */); } - private static ScanResult buildStaleScanResult() { + private static ScanResult buildScanResultWithTimestamp(long timestampMillis) { return new ScanResult( WifiSsid.createFromAsciiEncoded(SSID_3), BSSID_3, @@ -280,7 +280,7 @@ public class WifiTrackerTest { "", // capabilities RSSI_3, 0, // frequency - 0 /* microsecond timestamp */); + timestampMillis * 1000 /* microsecond timestamp */); } private static WifiConfiguration buildPasspointConfiguration(String fqdn, String friendlyName) { @@ -379,6 +379,12 @@ public class WifiTrackerTest { tracker.mReceiver.onReceive(mContext, i); } + private void sendFailedScanResults(WifiTracker tracker) throws InterruptedException { + Intent i = new Intent(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION); + i.putExtra(WifiManager.EXTRA_RESULTS_UPDATED, false); + tracker.mReceiver.onReceive(mContext, i); + } + private void sendUpdatedScores() throws InterruptedException { Bundle attr1 = new Bundle(); attr1.putParcelable(ScoredNetwork.ATTRIBUTES_KEY_BADGING_CURVE, mockBadgeCurve1); @@ -982,8 +988,8 @@ public class WifiTrackerTest { @Test public void onStart_updateScanResults_evictOldScanResult() { - when(mockWifiManager.getScanResults()).thenReturn( - Arrays.asList(buildScanResult1(), buildScanResult2(), buildStaleScanResult())); + when(mockWifiManager.getScanResults()).thenReturn(Arrays.asList( + buildScanResult1(), buildScanResult2(), buildScanResultWithTimestamp(0))); WifiTracker tracker = createMockedWifiTracker(); tracker.forceUpdate(); @@ -995,6 +1001,33 @@ public class WifiTrackerTest { } /** + * Verifies that a failed scan reported on SCAN_RESULTS_AVAILABLE_ACTION should increase the + * ScanResult eviction timeout to twice the default. + */ + @Test + public void failedScan_increasesEvictionTimeout() throws InterruptedException { + when(mockWifiManager.getScanResults()).thenReturn(Arrays.asList( + buildScanResult1(), buildScanResult2(), buildScanResultWithTimestamp( + SystemClock.elapsedRealtime() - WifiTracker.MAX_SCAN_RESULT_AGE_MILLIS))); + WifiTracker tracker = createMockedWifiTracker(); + + sendFailedScanResults(tracker); + + // Failed scan increases timeout window to include the stale scan + assertThat(tracker.getAccessPoints()).hasSize(3); + assertThat(tracker.getAccessPoints().get(0).getBssid()).isEqualTo(BSSID_1); + assertThat(tracker.getAccessPoints().get(1).getBssid()).isEqualTo(BSSID_2); + assertThat(tracker.getAccessPoints().get(2).getBssid()).isEqualTo(BSSID_3); + + sendScanResults(tracker); + + // Successful scan resets the timeout window to remove the stale scan + assertThat(tracker.getAccessPoints()).hasSize(2); + assertThat(tracker.getAccessPoints().get(0).getBssid()).isEqualTo(BSSID_1); + assertThat(tracker.getAccessPoints().get(1).getBssid()).isEqualTo(BSSID_2); + } + + /** * Verifies that updatePasspointAccessPoints will only return AccessPoints whose * isPasspoint() evaluates as true. */ diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothUtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothUtilsTest.java index b713e08eb67e..b228cf7c10c6 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothUtilsTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothUtilsTest.java @@ -15,15 +15,20 @@ */ package com.android.settingslib.bluetooth; +import static com.google.common.truth.Truth.assertThat; + import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.bluetooth.BluetoothClass; +import android.bluetooth.BluetoothDevice; import android.content.Context; import android.graphics.drawable.Drawable; import android.util.Pair; +import com.android.settingslib.widget.AdaptiveIcon; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -38,6 +43,9 @@ public class BluetoothUtilsTest { @Mock(answer = Answers.RETURNS_DEEP_STUBS) private CachedBluetoothDevice mCachedBluetoothDevice; + @Mock + private BluetoothDevice mBluetoothDevice; + private Context mContext; @Before @@ -66,4 +74,16 @@ public class BluetoothUtilsTest { verify(mContext).getDrawable(com.android.internal.R.drawable.ic_bt_laptop); } + + @Test + public void getBtRainbowDrawableWithDescription_normalHeadset_returnAdaptiveIcon() { + when(mBluetoothDevice.getMetadata( + BluetoothDevice.METADATA_IS_UNTHETHERED_HEADSET)).thenReturn("false"); + when(mCachedBluetoothDevice.getDevice()).thenReturn(mBluetoothDevice); + when(mCachedBluetoothDevice.getAddress()).thenReturn("1f:aa:bb"); + + assertThat(BluetoothUtils.getBtRainbowDrawableWithDescription( + RuntimeEnvironment.application, + mCachedBluetoothDevice).first).isInstanceOf(AdaptiveIcon.class); + } }
\ No newline at end of file diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileTest.java index bfda888c9617..d0d1e58effaa 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileTest.java @@ -116,16 +116,11 @@ public class TileTest { } @Test - public void isIconTintable_noMetadata_shouldReturnPackageNameCheck() { - final Tile tile1 = new Tile(mActivityInfo, "category"); - assertThat(tile1.isIconTintable(RuntimeEnvironment.application)).isFalse(); - - final ActivityInfo activityInfo = new ActivityInfo(); - activityInfo.packageName = "blah"; - activityInfo.name = "abc"; + public void isIconTintable_noTintableMetadata_shouldReturnFalse() { + final Tile tile = new Tile(mActivityInfo, "category"); + mActivityInfo.metaData.putInt(META_DATA_PREFERENCE_ICON, android.R.drawable.ic_info); - final Tile tile2 = new Tile(activityInfo, "category"); - assertThat(tile2.isIconTintable(RuntimeEnvironment.application)).isTrue(); + assertThat(tile.isIconTintable(RuntimeEnvironment.application)).isFalse(); } @Test diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java index c8927110b097..aa1ac4ecd334 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java @@ -205,10 +205,6 @@ public class TileUtilsTest { null /* defaultCategory */, outTiles, false /* usePriority */); assertThat(outTiles.size()).isEqualTo(1); assertThat(outTiles.get(0).getTitle(mContext)).isEqualTo("my localized title"); - - // Icon should be tintable because the tile is not from settings package, and - // "forceTintExternalIcon" is set - assertThat(outTiles.get(0).isIconTintable(mContext)).isTrue(); } @Test diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/AdaptiveIconTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/AdaptiveIconTest.java new file mode 100644 index 000000000000..ed6b9b0a135e --- /dev/null +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/AdaptiveIconTest.java @@ -0,0 +1,139 @@ +/* + * 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.settingslib.widget; + +import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_ICON_BACKGROUND_ARGB; +import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_ICON_BACKGROUND_HINT; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.content.Context; +import android.content.pm.ActivityInfo; +import android.graphics.Color; +import android.graphics.PorterDuff; +import android.graphics.drawable.ColorDrawable; +import android.graphics.drawable.Icon; +import android.graphics.drawable.ShapeDrawable; +import android.os.Bundle; + +import com.android.settingslib.R; +import com.android.settingslib.drawer.CategoryKey; +import com.android.settingslib.drawer.Tile; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.RuntimeEnvironment; + +@RunWith(RobolectricTestRunner.class) +public class AdaptiveIconTest { + + private Context mContext; + private ActivityInfo mActivityInfo; + + @Before + public void setUp() { + mContext = RuntimeEnvironment.application; + mActivityInfo = new ActivityInfo(); + mActivityInfo.packageName = mContext.getPackageName(); + mActivityInfo.name = "class"; + mActivityInfo.metaData = new Bundle(); + } + + @Test + public void createIcon_shouldSetBackgroundAndInset() { + final AdaptiveIcon icon = + new AdaptiveIcon(mContext, new ColorDrawable(Color.BLACK)); + + assertThat(icon.getNumberOfLayers()).isEqualTo(2); + assertThat(icon.getDrawable(0)).isInstanceOf(AdaptiveIconShapeDrawable.class); + } + + @Test + public void setBackgroundColor_shouldUpdateColorFilter() { + final AdaptiveIcon icon = + spy(new AdaptiveIcon(mContext, new ColorDrawable(Color.BLACK))); + final ShapeDrawable background = mock(ShapeDrawable.class); + when(icon.getDrawable(0)).thenReturn(background); + + icon.setBackgroundColor(Color.BLUE); + + verify(background).setColorFilter(Color.BLUE, PorterDuff.Mode.SRC_ATOP); + } + + @Test + public void setBackgroundColor_externalTileWithBackgroundColorRawValue_shouldUpdateIcon() { + final Tile tile = spy(new Tile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE)); + mActivityInfo.metaData.putInt(META_DATA_PREFERENCE_ICON_BACKGROUND_ARGB, 0xff0000); + doReturn(Icon.createWithResource(mContext, R.drawable.ic_system_update)) + .when(tile).getIcon(mContext); + final AdaptiveIcon icon = + new AdaptiveIcon(mContext, new ColorDrawable(Color.BLACK)); + + icon.setBackgroundColor(mContext, tile); + assertThat(icon.mBackgroundColor).isEqualTo(0xff0000); + } + + @Test + public void setBackgroundColor_tileWithoutBackgroundColor_shouldSetDefaultBackgroundColor() { + final Tile tile = spy(new Tile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE)); + doReturn(Icon.createWithResource(mContext, R.drawable.ic_system_update)) + .when(tile).getIcon(mContext); + final AdaptiveIcon icon = new AdaptiveIcon(mContext, new ColorDrawable(Color.BLACK)); + + icon.setBackgroundColor(mContext, tile); + + assertThat(icon.mBackgroundColor) + .isEqualTo(mContext.getColor(R.color.homepage_generic_icon_background)); + } + + @Test + public void onBindTile_externalTileWithBackgroundColorHint_shouldUpdateIcon() { + final Tile tile = spy(new Tile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE)); + mActivityInfo.metaData.putInt(META_DATA_PREFERENCE_ICON_BACKGROUND_HINT, + R.color.bt_outline_color); + doReturn(Icon.createWithResource(mContext, R.drawable.ic_system_update)) + .when(tile).getIcon(mContext); + + final AdaptiveIcon icon = + new AdaptiveIcon(mContext, new ColorDrawable(Color.BLACK)); + icon.setBackgroundColor(mContext, tile); + + assertThat(icon.mBackgroundColor) + .isEqualTo(mContext.getColor(R.color.bt_outline_color)); + } + + @Test + public void getConstantState_returnCorrectState() { + final AdaptiveIcon icon = + new AdaptiveIcon(mContext, new ColorDrawable(Color.BLACK)); + icon.setBackgroundColor(Color.YELLOW); + + final AdaptiveIcon.AdaptiveConstantState state = + (AdaptiveIcon.AdaptiveConstantState) icon.getConstantState(); + + assertThat(state.mColor).isEqualTo(Color.YELLOW); + assertThat(state.mContext).isEqualTo(mContext); + } +} diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/AdaptiveOutlineDrawableTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/AdaptiveOutlineDrawableTest.java new file mode 100644 index 000000000000..71d55bc3de2a --- /dev/null +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/AdaptiveOutlineDrawableTest.java @@ -0,0 +1,44 @@ +/* + * 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.settingslib.widget; + +import static com.google.common.truth.Truth.assertThat; + +import android.content.res.Resources; +import android.graphics.Paint; + +import com.android.settingslib.R; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.RuntimeEnvironment; + +@RunWith(RobolectricTestRunner.class) +public class AdaptiveOutlineDrawableTest { + + @Test + public void constructor_initPaint() { + final Resources resources = RuntimeEnvironment.application.getResources(); + final AdaptiveOutlineDrawable drawable = new AdaptiveOutlineDrawable(resources, null); + + assertThat(drawable.mOutlinePaint.getStyle()).isEqualTo(Paint.Style.STROKE); + assertThat(drawable.mOutlinePaint.getStrokeWidth()).isWithin(0.01f).of( + resources.getDimension(R.dimen.adaptive_outline_stroke)); + } + +} diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java index e374db310737..f597a1a85d01 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java @@ -686,6 +686,9 @@ class SettingsProtoDumpUtil { Settings.Global.GPU_DEBUG_LAYERS, GlobalSettingsProto.Gpu.DEBUG_LAYERS); dumpSetting(s, p, + Settings.Global.GLOBAL_SETTINGS_ANGLE_DEBUG_PACKAGE, + GlobalSettingsProto.Gpu.ANGLE_DEBUG_PACKAGE); + dumpSetting(s, p, Settings.Global.GLOBAL_SETTINGS_ANGLE_GL_DRIVER_ALL_ANGLE, GlobalSettingsProto.Gpu.ANGLE_GL_DRIVER_ALL_ANGLE); dumpSetting(s, p, diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java index 4b342b37ac20..296f7a144ffe 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java @@ -16,6 +16,7 @@ package com.android.providers.settings; +import static android.os.Process.INVALID_UID; import static android.os.Process.ROOT_UID; import static android.os.Process.SHELL_UID; import static android.os.Process.SYSTEM_UID; @@ -2777,7 +2778,7 @@ public class SettingsProvider extends ContentProvider { boolean someSettingChanged = false; Setting setting = settingsState.getSettingLocked(name); if (!SettingsState.isSystemPackage(getContext(), - setting.getPackageName())) { + setting.getPackageName(), INVALID_UID, userId)) { if (prefix != null && !setting.getName().startsWith(prefix)) { continue; } @@ -2797,7 +2798,7 @@ public class SettingsProvider extends ContentProvider { boolean someSettingChanged = false; Setting setting = settingsState.getSettingLocked(name); if (!SettingsState.isSystemPackage(getContext(), - setting.getPackageName())) { + setting.getPackageName(), INVALID_UID, userId)) { if (prefix != null && !setting.getName().startsWith(prefix)) { continue; } @@ -4410,7 +4411,7 @@ public class SettingsProvider extends ContentProvider { } try { final boolean systemSet = SettingsState.isSystemPackage(getContext(), - setting.getPackageName(), callingUid); + setting.getPackageName(), callingUid, userId); if (systemSet) { settings.insertSettingLocked(name, setting.getValue(), setting.getTag(), true, setting.getPackageName()); diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java index 521163f50ca1..c05c4cdf72d7 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java @@ -17,6 +17,7 @@ package com.android.providers.settings; import static android.os.Process.FIRST_APPLICATION_UID; +import static android.os.Process.INVALID_UID; import android.annotation.NonNull; import android.content.Context; @@ -1124,11 +1125,16 @@ final class SettingsState { return sb.toString(); } + // Check if a specific package belonging to the caller is part of the system package. public static boolean isSystemPackage(Context context, String packageName) { - return isSystemPackage(context, packageName, Binder.getCallingUid()); + final int callingUid = Binder.getCallingUid(); + final int callingUserId = UserHandle.getUserId(callingUid); + return isSystemPackage(context, packageName, callingUid, callingUserId); } - public static boolean isSystemPackage(Context context, String packageName, int callingUid) { + // Check if a specific package, uid, and user ID are part of the system package. + public static boolean isSystemPackage(Context context, String packageName, int uid, + int userId) { synchronized (sLock) { if (SYSTEM_PACKAGE_NAME.equals(packageName)) { return true; @@ -1140,26 +1146,19 @@ final class SettingsState { return false; } - // Native services running as a special UID get a pass - final int callingAppId = UserHandle.getAppId(callingUid); - if (callingAppId < FIRST_APPLICATION_UID) { - sSystemUids.put(callingAppId, callingAppId); - return true; + if (uid != INVALID_UID) { + // Native services running as a special UID get a pass + final int callingAppId = UserHandle.getAppId(uid); + if (callingAppId < FIRST_APPLICATION_UID) { + sSystemUids.put(callingAppId, callingAppId); + return true; + } } - // While some callers may have permissions to manipulate cross user - // settings or some settings are stored in the parent of a managed - // profile for the purpose of determining whether the other end is a - // system component we need to use the user id of the caller for - // pulling information about the caller from the package manager. - final int callingUserId = UserHandle.getUserId(callingUid); - final long identity = Binder.clearCallingIdentity(); try { - final int uid; try { - uid = context.getPackageManager().getPackageUidAsUser(packageName, 0, - callingUserId); + uid = context.getPackageManager().getPackageUidAsUser(packageName, 0, userId); } catch (PackageManager.NameNotFoundException e) { return false; } @@ -1187,7 +1186,7 @@ final class SettingsState { PackageInfo packageInfo; try { packageInfo = context.getPackageManager().getPackageInfoAsUser( - packageName, PackageManager.GET_SIGNATURES, callingUserId); + packageName, PackageManager.GET_SIGNATURES, userId); if ((packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0 && (packageInfo.applicationInfo.flags diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml index c06dbfd6537d..2a9456dd723c 100644 --- a/packages/Shell/AndroidManifest.xml +++ b/packages/Shell/AndroidManifest.xml @@ -125,6 +125,8 @@ <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" /> <uses-permission android:name="android.permission.MOUNT_FORMAT_FILESYSTEMS" /> <uses-permission android:name="android.permission.MODIFY_PHONE_STATE" /> + <!-- Shell only holds android.permission.NETWORK_SCAN in order to to enable CTS testing --> + <uses-permission android:name="android.permission.NETWORK_SCAN" /> <uses-permission android:name="android.permission.REGISTER_CALL_PROVIDER" /> <uses-permission android:name="android.permission.REGISTER_CONNECTION_MANAGER" /> <uses-permission android:name="android.permission.REGISTER_SIM_SUBSCRIPTION" /> @@ -181,6 +183,8 @@ <!-- Permission needed to run network tests in CTS --> <uses-permission android:name="android.permission.MANAGE_TEST_NETWORKS" /> + <!-- Permission needed to test tcp keepalive offload. --> + <uses-permission android:name="android.permission.PACKET_KEEPALIVE_OFFLOAD" /> <!-- Permission needed to run keyguard manager tests in CTS --> <uses-permission android:name="android.permission.CONTROL_KEYGUARD_SECURE_NOTIFICATIONS" /> diff --git a/packages/Shell/tests/Android.mk b/packages/Shell/tests/Android.mk index b93ddde16e4a..44ff3383d566 100644 --- a/packages/Shell/tests/Android.mk +++ b/packages/Shell/tests/Android.mk @@ -9,7 +9,7 @@ LOCAL_SRC_FILES := $(call all-java-files-under, src) LOCAL_JAVA_LIBRARIES := android.test.runner android.test.base android.test.mock LOCAL_STATIC_JAVA_LIBRARIES := \ - android-support-test \ + androidx.test.rules \ mockito-target-minus-junit4 \ ub-uiautomator \ junit \ diff --git a/packages/Shell/tests/AndroidManifest.xml b/packages/Shell/tests/AndroidManifest.xml index 6d564c640fcd..e845ef95b28e 100644 --- a/packages/Shell/tests/AndroidManifest.xml +++ b/packages/Shell/tests/AndroidManifest.xml @@ -36,7 +36,7 @@ </activity> </application> - <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner" + <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner" android:targetPackage="com.android.shell" android:label="Tests for Shell" /> diff --git a/packages/Shell/tests/AndroidTest.xml b/packages/Shell/tests/AndroidTest.xml index e592d82bfaf7..e03b68a03d0e 100644 --- a/packages/Shell/tests/AndroidTest.xml +++ b/packages/Shell/tests/AndroidTest.xml @@ -22,7 +22,7 @@ <option name="test-tag" value="ShellTests" /> <test class="com.android.tradefed.testtype.AndroidJUnitTest" > <option name="package" value="com.android.shell.tests" /> - <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" /> + <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" /> <option name="hidden-api-checks" value="false"/> </test> </configuration> diff --git a/packages/Shell/tests/src/com/android/shell/BugreportProgressServiceTest.java b/packages/Shell/tests/src/com/android/shell/BugreportProgressServiceTest.java index cef74ae39c60..433eca23080e 100644 --- a/packages/Shell/tests/src/com/android/shell/BugreportProgressServiceTest.java +++ b/packages/Shell/tests/src/com/android/shell/BugreportProgressServiceTest.java @@ -20,7 +20,6 @@ import static com.android.shell.BugreportProgressService.findSendToAccount; import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertNull; -import static org.mockito.Matchers.anyInt; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.when; @@ -29,12 +28,12 @@ import android.accounts.AccountManager; import android.content.Context; import android.os.UserHandle; import android.os.UserManager; -import android.support.test.filters.SmallTest; -import android.support.test.runner.AndroidJUnit4; import android.test.mock.MockContext; import android.util.Pair; -import org.junit.Before; +import androidx.test.filters.SmallTest; +import androidx.test.runner.AndroidJUnit4; + import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; diff --git a/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java b/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java index e69b0a81b97e..3a71632cf1ca 100644 --- a/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java +++ b/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java @@ -42,34 +42,6 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import java.io.BufferedOutputStream; -import java.io.BufferedWriter; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStreamWriter; -import java.io.Writer; -import java.text.NumberFormat; -import java.util.ArrayList; -import java.util.List; -import java.util.SortedSet; -import java.util.TreeSet; -import java.util.zip.ZipEntry; -import java.util.zip.ZipInputStream; -import java.util.zip.ZipOutputStream; - -import libcore.io.Streams; - -import org.junit.After; -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TestName; -import org.junit.runner.RunWith; - import android.app.ActivityManager; import android.app.ActivityManager.RunningServiceInfo; import android.app.Instrumentation; @@ -82,9 +54,6 @@ import android.os.Bundle; import android.os.SystemClock; import android.os.SystemProperties; import android.service.notification.StatusBarNotification; -import android.support.test.InstrumentationRegistry; -import android.support.test.filters.LargeTest; -import android.support.test.runner.AndroidJUnit4; import android.support.test.uiautomator.UiDevice; import android.support.test.uiautomator.UiObject; import android.support.test.uiautomator.UiObjectNotFoundException; @@ -92,8 +61,39 @@ import android.text.TextUtils; import android.text.format.DateUtils; import android.util.Log; +import androidx.test.InstrumentationRegistry; +import androidx.test.filters.LargeTest; +import androidx.test.runner.AndroidJUnit4; + import com.android.shell.ActionSendMultipleConsumerActivity.CustomActionSendMultipleListener; +import libcore.io.Streams; + +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestName; +import org.junit.runner.RunWith; + +import java.io.BufferedOutputStream; +import java.io.BufferedWriter; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStreamWriter; +import java.io.Writer; +import java.text.NumberFormat; +import java.util.ArrayList; +import java.util.List; +import java.util.SortedSet; +import java.util.TreeSet; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; +import java.util.zip.ZipOutputStream; + /** * Integration tests for {@link BugreportReceiver}. * <p> diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml index 938c457cf33f..abd2b7684526 100644 --- a/packages/SystemUI/AndroidManifest.xml +++ b/packages/SystemUI/AndroidManifest.xml @@ -35,7 +35,7 @@ <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> <!-- Used to read wallpaper --> - <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" /> + <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <!-- Used to read storage for all users --> <uses-permission android:name="android.permission.WRITE_MEDIA_STORAGE" /> 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_alarm.xml b/packages/SystemUI/res/drawable/ic_alarm.xml new file mode 100644 index 000000000000..1c1adcd149bf --- /dev/null +++ b/packages/SystemUI/res/drawable/ic_alarm.xml @@ -0,0 +1,25 @@ +<!-- + Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:height="17dp" + android:width="17dp" + android:viewportHeight="24" + android:viewportWidth="24"> + <path + android:fillColor="#FFFFFF" + android:pathData="M13,8h-2v5.41l3.79,3.8 1.42,-1.42 -3.21,-3.2zM12,4c-4.97,0 -9,4.03 -9,9s4.03,9 9,9 9,-4.03 9,-9 -4.03,-9 -9,-9zM12,20c-3.86,0 -7,-3.14 -7,-7s3.14,-7 7,-7 7,3.14 7,7 -3.14,7 -7,7zM16.056,3.346l1.282,-1.535 4.607,3.85 -1.28,1.54zM2.056,5.654L6.663,1.81l1.28,1.536L3.338,7.19z"/> + +</vector> diff --git a/packages/SystemUI/res/drawable/ic_alarm_dim.xml b/packages/SystemUI/res/drawable/ic_alarm_dim.xml new file mode 100644 index 000000000000..37ab873d504c --- /dev/null +++ b/packages/SystemUI/res/drawable/ic_alarm_dim.xml @@ -0,0 +1,26 @@ +<!-- + Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:height="17dp" + android:width="17dp" + android:viewportHeight="24" + android:viewportWidth="24"> + <path + android:fillColor="#FFFFFF" + android:fillAlpha="0.3" + android:pathData="M13,8h-2v5.41l3.79,3.8 1.42,-1.42 -3.21,-3.2zM12,4c-4.97,0 -9,4.03 -9,9s4.03,9 9,9 9,-4.03 9,-9 -4.03,-9 -9,-9zM12,20c-3.86,0 -7,-3.14 -7,-7s3.14,-7 7,-7 7,3.14 7,7 -3.14,7 -7,7zM16.056,3.346l1.282,-1.535 4.607,3.85 -1.28,1.54zM2.056,5.654L6.663,1.81l1.28,1.536L3.338,7.19z"/> + +</vector> diff --git a/packages/SystemUI/res/drawable/ic_bluetooth_connected.xml b/packages/SystemUI/res/drawable/ic_bluetooth_connected.xml new file mode 100644 index 000000000000..125082c49bdc --- /dev/null +++ b/packages/SystemUI/res/drawable/ic_bluetooth_connected.xml @@ -0,0 +1,30 @@ +<!-- +Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="17dp" + android:height="17dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + <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"/> + <path + android:fillColor="@android:color/white" + android:pathData="M5,12m-1.5,0a1.5,1.5 0,1 1,3 0a1.5,1.5 0,1 1,-3 0"/> + <path + android:fillColor="@android:color/white" + android:pathData="M19,12m-1.5,0a1.5,1.5 0,1 1,3 0a1.5,1.5 0,1 1,-3 0"/> +</vector>
\ No newline at end of file diff --git a/packages/SystemUI/res/drawable/ic_camera.xml b/packages/SystemUI/res/drawable/ic_camera.xml new file mode 100644 index 000000000000..b330875864d3 --- /dev/null +++ b/packages/SystemUI/res/drawable/ic_camera.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2019 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License + --> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="17dp" + android:height="17dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + <path + android:fillColor="#FFF" + android:pathData="M20,5h-3.17L15,3H9L7.17,5H4C2.9,5 2,5.9 2,7v12c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2V7C22,5.9 21.1,5 20,5zM20,19H4V7h16V19zM12,9c-2.21,0 -4,1.79 -4,4c0,2.21 1.79,4 4,4s4,-1.79 4,-4C16,10.79 14.21,9 12,9z"/> +</vector> diff --git a/packages/SystemUI/res/drawable/ic_qs_cast_off.xml b/packages/SystemUI/res/drawable/ic_cast.xml index 9e57577d13e1..a2c2eb2806f6 100644 --- a/packages/SystemUI/res/drawable/ic_qs_cast_off.xml +++ b/packages/SystemUI/res/drawable/ic_cast.xml @@ -14,11 +14,11 @@ Copyright (C) 2017 The Android Open Source Project limitations under the License. --> <vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="64dp" - android:height="64dp" + android:width="24dp" + android:height="24dp" android:viewportWidth="24.0" android:viewportHeight="24.0"> <path - android:pathData="M1,18v2c0,0.55 0.45,1 1,1h2c0,-1.66 -1.34,-3 -3,-3zM0.97,15.06c-0.01,0.51 0.35,0.93 0.85,1.02 2.08,0.36 3.74,2 4.1,4.08 0.09,0.48 0.5,0.84 0.99,0.84 0.61,0 1.09,-0.54 1,-1.14a6.996,6.996 0,0 0,-5.8 -5.78c-0.59,-0.09 -1.12,0.38 -1.14,0.98zM0.97,11.03c-0.01,0.52 0.37,0.96 0.88,1.01 4.26,0.43 7.68,3.82 8.1,8.08 0.05,0.5 0.48,0.88 0.99,0.88 0.59,0 1.06,-0.51 1,-1.1 -0.52,-5.21 -4.66,-9.34 -9.87,-9.85 -0.57,-0.05 -1.08,0.4 -1.1,0.98zM21,3L3,3c-1.1,0 -2,0.9 -2,2v3h2L3,5h18v14h-7v2h7c1.1,0 2,-0.9 2,-2L23,5c0,-1.1 -0.9,-2 -2,-2z" - android:fillColor="#FFFFFFFF" /> + android:fillColor="@android:color/white" + android:pathData="M21,3L3,3c-1.1,0 -2,0.9 -2,2v3h2L3,5h18v14h-7v2h7c1.1,0 2,-0.9 2,-2L23,5c0,-1.1 -0.9,-2 -2,-2zM1,18v3h3c0,-1.66 -1.34,-3 -3,-3zM1,14v2c2.76,0 5,2.24 5,5h2c0,-3.87 -3.13,-7 -7,-7zM1,10v2c4.97,0 9,4.03 9,9h2c0,-6.08 -4.93,-11 -11,-11z"/> </vector> diff --git a/packages/SystemUI/res/drawable/ic_qs_vpn.xml b/packages/SystemUI/res/drawable/ic_cast_connected.xml index 6567d123f5d5..995fd498f19e 100644 --- a/packages/SystemUI/res/drawable/ic_qs_vpn.xml +++ b/packages/SystemUI/res/drawable/ic_cast_connected.xml @@ -1,5 +1,5 @@ <!-- -Copyright (C) 2014 The Android Open Source Project +Copyright (C) 2017 The Android Open Source Project Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,14 +14,13 @@ Copyright (C) 2014 The Android Open Source Project limitations under the License. --> <vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="12.0dp" - android:height="12.0dp" + android:width="17dp" + android:height="17dp" android:viewportWidth="24.0" android:viewportHeight="24.0"> + <path android:fillColor="#FFFFFFFF" - android:pathData="M12.09,9C11.11,7.5 9.43,6.5 7.5,6.5C4.46,6.5 2,8.96 2,12c0,3.04 2.46,5.5 5.5,5.5c1.93,0 3.61,-1 4.59,-2.5H14v3h6v-3h2V9H12.09zM20,13h-2v3h-2v-3h-5.16c-0.43,1.44 -1.76,2.5 -3.34,2.5C5.57,15.5 4,13.93 4,12c0,-1.93 1.57,-3.5 3.5,-3.5c1.58,0 2.9,1.06 3.34,2.5H20V13z"/> - <path - android:fillColor="#FFFFFFFF" - android:pathData="M7.5,12m-1.5,0a1.5,1.5 0,1 1,3 0a1.5,1.5 0,1 1,-3 0"/> + android:pathData="M1,18v3h3C4,19.34 2.66,18 1,18zM1,14v2c2.76,0 5,2.24 5,5h2C8,17.13 4.87,14 1,14zM19,7H5v1.63c3.96,1.28 7.09,4.41 8.37,8.37H19V7zM1,10v2c4.97,0 9,4.03 9,9h2C12,14.92 7.07,10 1,10zM21,3H3C1.9,3 1,3.9 1,5v3h2V5h18v14h-7v2h7c1.1,0 2,-0.9 2,-2V5C23,3.9 22.1,3 21,3"/> + </vector> diff --git a/packages/SystemUI/res/drawable/ic_data_saver.xml b/packages/SystemUI/res/drawable/ic_data_saver.xml index 0f027ee7afb1..cc3f539db8d3 100644 --- a/packages/SystemUI/res/drawable/ic_data_saver.xml +++ b/packages/SystemUI/res/drawable/ic_data_saver.xml @@ -14,15 +14,11 @@ limitations under the License. --> <vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" + android:width="18dp" + android:height="18dp" android:viewportWidth="24.0" - android:viewportHeight="24.0" - android:tint="?android:attr/colorControlNormal"> + android:viewportHeight="24.0"> <path - android:pathData="M16,12c0,0.55 -0.45,1 -1,1h-2v2c0,0.55 -0.45,1 -1,1s-1,-0.45 -1,-1v-2L9,13c-0.55,0 -1,-0.45 -1,-1s0.45,-1 1,-1h2L11,9c0,-0.55 0.45,-1 1,-1s1,0.45 1,1v2h2c0.55,0 1,0.45 1,1zM17.69,16.87a7.437,7.437 0,0 1,-5.93 2.63c-3.82,-0.12 -7.03,-3.25 -7.25,-7.07 -0.21,-3.84 2.48,-7.1 6.07,-7.79 0.24,-0.04 0.42,-0.24 0.42,-0.48L11,2.62c0,-0.3 -0.27,-0.55 -0.57,-0.5A10.02,10.02 0,0 0,2.09 13.4c0.59,4.4 4.16,7.94 8.56,8.52a9.99,9.99 0,0 0,9.14 -3.65,0.5 0.5,0 0,0 -0.15,-0.74l-1.32,-0.76a0.469,0.469 0,0 0,-0.63 0.1z" + android:pathData="M11,8v3L8,11v2h3v3h2v-3h3v-2h-3L13,8zM13,2.05v3.03c3.39,0.49 6,3.39 6,6.92 0,0.9 -0.18,1.75 -0.48,2.54l2.6,1.53c0.56,-1.24 0.88,-2.62 0.88,-4.07 0,-5.18 -3.95,-9.45 -9,-9.95zM12,19c-3.87,0 -7,-3.13 -7,-7 0,-3.53 2.61,-6.43 6,-6.92L11,2.05c-5.06,0.5 -9,4.76 -9,9.95 0,5.52 4.47,10 9.99,10 3.31,0 6.24,-1.61 8.06,-4.09l-2.6,-1.53C16.17,17.98 14.21,19 12,19z" android:fillColor="#FFFFFFFF"/> - <path - android:pathData="M13.41,4.64a0.493,0.493 0,0 1,-0.41 -0.48L13,2.62c0,-0.3 0.27,-0.55 0.57,-0.5C18.35,2.88 22,7.01 22,12c0,1.23 -0.23,2.41 -0.64,3.5 -0.11,0.28 -0.45,0.4 -0.72,0.24l-1.33,-0.77a0.484,0.484 0,0 1,-0.21 -0.59c0.25,-0.75 0.39,-1.55 0.39,-2.38 0.01,-3.65 -2.62,-6.69 -6.08,-7.36z" - android:fillColor="#54FFFFFF" /> </vector> diff --git a/packages/SystemUI/res/drawable/ic_data_saver_off.xml b/packages/SystemUI/res/drawable/ic_data_saver_off.xml index 29e6c912b797..d8e9bc46b434 100644 --- a/packages/SystemUI/res/drawable/ic_data_saver_off.xml +++ b/packages/SystemUI/res/drawable/ic_data_saver_off.xml @@ -17,9 +17,8 @@ android:width="24.0dp" android:height="24.0dp" android:viewportWidth="24.0" - android:viewportHeight="24.0" - android:tint="?android:attr/colorControlNormal"> + android:viewportHeight="24.0"> <path android:fillColor="#FFFFFFFF" - android:pathData="M18.32,16.75l1.32,0.76c0.26,0.15 0.34,0.51 0.15,0.74 -2.09,2.6 -5.44,4.14 -9.14,3.65 -4.4,-0.58 -7.96,-4.12 -8.56,-8.52C1.34,7.8 5.21,2.95 10.43,2.12c0.3,-0.05 0.57,0.2 0.57,0.5v1.53c0,0.24 -0.18,0.44 -0.41,0.49 -3.6,0.69 -6.29,3.95 -6.07,7.79 0.21,3.82 3.43,6.95 7.25,7.07 2.37,0.08 4.51,-0.96 5.93,-2.63a0.48,0.48 0,0 1,0.62 -0.12zM19.5,12c0,0.83 -0.14,1.63 -0.39,2.38 -0.08,0.23 0.01,0.47 0.21,0.59l1.33,0.77c0.26,0.15 0.61,0.04 0.72,-0.24 0.4,-1.09 0.63,-2.27 0.63,-3.5 0,-4.99 -3.65,-9.12 -8.43,-9.88 -0.3,-0.04 -0.57,0.2 -0.57,0.5v1.53c0,0.24 0.18,0.44 0.41,0.48 3.46,0.68 6.09,3.72 6.09,7.37z" /> + android:pathData="M13,2.05v3.03c3.39,0.49 6,3.39 6,6.92 0,0.9 -0.18,1.75 -0.48,2.54l2.6,1.53c0.56,-1.24 0.88,-2.62 0.88,-4.07 0,-5.18 -3.95,-9.45 -9,-9.95zM12,19c-3.87,0 -7,-3.13 -7,-7 0,-3.53 2.61,-6.43 6,-6.92V2.05c-5.06,0.5 -9,4.76 -9,9.95 0,5.52 4.47,10 9.99,10 3.31,0 6.24,-1.61 8.06,-4.09l-2.6,-1.53C16.17,17.98 14.21,19 12,19z"/> </vector> diff --git a/packages/SystemUI/res/drawable/ic_headset.xml b/packages/SystemUI/res/drawable/ic_headset.xml index 27efe80c5ae0..797a80ac6916 100644 --- a/packages/SystemUI/res/drawable/ic_headset.xml +++ b/packages/SystemUI/res/drawable/ic_headset.xml @@ -13,19 +13,12 @@ See the License for the specific language governing permissions and limitations under the License. --> -<inset xmlns:android="http://schemas.android.com/apk/res/android" - android:insetLeft="2.5dp" - android:insetRight="2.5dp"> - <vector - android:width="17.0dp" - android:height="17.0dp" - android:viewportWidth="24" - android:viewportHeight="24"> - <group - android:translateY="-1"> - <path - android:fillColor="#FFFFFFFF" - android:pathData="M19,15v3c0,0.55 -0.45,1 -1,1h-1v-4H19M7,15v4H6c-0.55,0 -1,-0.45 -1,-1v-3H7M12,2c-4.97,0 -9,4.03 -9,9v7c0,1.66 1.34,3 3,3h3v-8H5v-2c0,-3.87 3.13,-7 7,-7s7,3.13 7,7v2h-4v8h3c1.66,0 3,-1.34 3,-3v-7C21,6.03 16.97,2 12,2L12,2z"/> - </group> - </vector> -</inset> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="17.0dp" + android:height="17.0dp" + android:viewportWidth="24" + android:viewportHeight="24"> + <path + android:fillColor="#FFFFFFFF" + android:pathData="M19,15v3c0,0.55 -0.45,1 -1,1h-1v-4h2M7,15v4H6c-0.55,0 -1,-0.45 -1,-1v-3h2m5,-13c-4.97,0 -9,4.03 -9,9v7c0,1.66 1.34,3 3,3h3v-8H5v-2c0,-3.87 3.13,-7 7,-7s7,3.13 7,7v2h-4v8h3c1.66,0 3,-1.34 3,-3v-7c0,-4.97 -4.03,-9 -9,-9z" /> +</vector> diff --git a/packages/SystemUI/res/drawable/ic_headset_mic.xml b/packages/SystemUI/res/drawable/ic_headset_mic.xml index 1260e0f42949..b3f006d15bb5 100644 --- a/packages/SystemUI/res/drawable/ic_headset_mic.xml +++ b/packages/SystemUI/res/drawable/ic_headset_mic.xml @@ -13,16 +13,12 @@ See the License for the specific language governing permissions and limitations under the License. --> -<inset xmlns:android="http://schemas.android.com/apk/res/android" - android:insetLeft="2.5dp" - android:insetRight="2.5dp"> - <vector - android:width="17.0dp" - android:height="17.0dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - <path - android:fillColor="#FFFFFFFF" - android:pathData="M12,1c-4.97,0 -9,4.03 -9,9v7c0,1.66 1.34,3 3,3h3v-8H5v-1.71C5,6.45 7.96,3.11 11.79,3C15.76,2.89 19,6.06 19,10v2h-4v8h4v1h-6v2h6c1.1,0 2,-0.9 2,-2V10C21,5.03 16.97,1 12,1zM7,14v4H6c-0.55,0 -1,-0.45 -1,-1v-3H7zM19,18h-2v-4h2V18z"/> - </vector> -</inset> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="17.0dp" + android:height="17.0dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + <path + android:fillColor="#FFFFFFFF" + android:pathData="M12,1c-4.97,0 -9,4.03 -9,9v7c0,1.66 1.34,3 3,3h3v-8H5v-1.71C5,6.45 7.96,3.11 11.79,3C15.76,2.89 19,6.06 19,10v2h-4v8h4v1h-6v2h6c1.1,0 2,-0.9 2,-2V10C21,5.03 16.97,1 12,1zM7,14v4H6c-0.55,0 -1,-0.45 -1,-1v-3H7zM19,18h-2v-4h2V18z" /> +</vector> diff --git a/packages/SystemUI/res/drawable/ic_hotspot.xml b/packages/SystemUI/res/drawable/ic_hotspot.xml index 8450bf6ce60c..b6fa798d8bb6 100644 --- a/packages/SystemUI/res/drawable/ic_hotspot.xml +++ b/packages/SystemUI/res/drawable/ic_hotspot.xml @@ -15,14 +15,12 @@ limitations under the License. --> <vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="48dp" - android:height="48dp" + android:width="18dp" + android:height="18dp" android:viewportWidth="24.0" android:viewportHeight="24.0"> - <group - android:translateY="-0.32"> - <path - android:pathData="M12,11c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2zM18,13a6,6 0,0 0,-6.75 -5.95c-2.62,0.32 -4.78,2.41 -5.18,5.02 -0.32,2.14 0.49,4.11 1.92,5.39 0.48,0.43 1.24,0.33 1.56,-0.23 0.24,-0.42 0.14,-0.94 -0.22,-1.26a3.99,3.99 0,0 1,-1.22 -3.94,3.954 3.954,0 0,1 2.9,-2.91A4.007,4.007 0,0 1,16 13c0,1.18 -0.51,2.23 -1.33,2.96 -0.36,0.33 -0.47,0.85 -0.23,1.27 0.31,0.54 1.04,0.69 1.5,0.28A5.97,5.97 0,0 0,18 13zM10.83,3.07c-4.62,0.52 -8.35,4.33 -8.78,8.96a9.966,9.966 0,0 0,4.02 9.01c0.48,0.35 1.16,0.2 1.46,-0.31 0.25,-0.43 0.14,-0.99 -0.26,-1.29 -2.28,-1.69 -3.65,-4.55 -3.16,-7.7 0.54,-3.5 3.46,-6.29 6.98,-6.68C15.91,4.51 20,8.28 20,13c0,2.65 -1.29,4.98 -3.27,6.44 -0.4,0.3 -0.51,0.85 -0.26,1.29 0.3,0.52 0.98,0.66 1.46,0.31A9.96,9.96 0,0 0,22 13c0,-5.91 -5.13,-10.62 -11.17,-9.93z" - android:fillColor="#FFFFFFFF"/> - </group> + <path + android:fillColor="#FFFFFF" + android:pathData="M12,7c-3.31,0 -6,2.69 -6,6 0,1.66 0.68,3.15 1.76,4.24l1.42,-1.42C8.45,15.1 8,14.11 8,13c0,-2.21 1.79,-4 4,-4s4,1.79 4,4c0,1.11 -0.45,2.1 -1.18,2.82l1.42,1.42C17.32,16.15 18,14.66 18,13c0,-3.31 -2.69,-6 -6,-6zM12,3C6.48,3 2,7.48 2,13c0,2.76 1.12,5.26 2.93,7.07l1.41,-1.41C4.9,17.21 4,15.21 4,13c0,-4.42 3.58,-8 8,-8s8,3.58 8,8c0,2.21 -0.9,4.2 -2.35,5.65l1.41,1.41C20.88,18.26 22,15.76 22,13c0,-5.52 -4.48,-10 -10,-10zM12,11c-1.1,0 -2,0.9 -2,2 0,0.55 0.23,1.05 0.59,1.41 0.36,0.36 0.86,0.59 1.41,0.59s1.05,-0.23 1.41,-0.59c0.36,-0.36 0.59,-0.86 0.59,-1.41 0,-1.1 -0.9,-2 -2,-2z" /> + </vector> diff --git a/packages/SystemUI/res/drawable/ic_hotspot_unavailable.xml b/packages/SystemUI/res/drawable/ic_hotspot_unavailable.xml deleted file mode 100644 index 7641998a8cd9..000000000000 --- a/packages/SystemUI/res/drawable/ic_hotspot_unavailable.xml +++ /dev/null @@ -1,61 +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:name="root" - android:height="48dp" - android:width="48dp" - android:viewportHeight="48" - android:viewportWidth="48" > - <group - android:name="ic_hotspot" - android:translateX="23.97354" - android:translateY="24.26306" > - <group - android:name="ic_hotspot_pivot" - android:translateX="-23.21545" - android:translateY="-18.86649" > - <clip-path - android:name="mask" - android:pathData="M 38.8337860107,-40.3974914551 c 0.0,0.0 -38.4077911377,30.8523712158 -38.4077911377,30.8523712158 c 0.0,0.0 43.1884765625,43.515335083 43.1884765625,43.515335083 c 0.0,0.0 -2.4169921875,2.57838439941 -2.4169921875,2.57838439941 c 0.0,0.0 -42.9885101318,-43.0112609863 -42.9885101318,-43.0112609863 c 0.0,0.0 -32.6199798584,25.1699066162 -32.6199798584,25.1699066162 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 27.6589050293,-22.6579437256 27.6589050293,-22.6579437256 c 0.0,0.0 -30.8645172119,-34.00390625 -30.8645172119,-34.00390625 c 0.0,0.0 2.70756530762,-1.99278259277 2.70756530762,-1.99278259277 c 0.0,0.0 1.53030395508,-0.876571655273 1.53030395508,-0.876571655274 c 0.0,0.0 2.85780334473,-3.12069702148 2.85780334473,-3.12069702148 c 0.0,0.0 13.0984039307,13.025604248 13.0984039307,13.025604248 c 0.0,0.0 -3.13299560547,2.82977294922 -3.13299560547,2.82977294922 c 0.0,0.0 16.571762085,22.0471801758 16.571762085,22.0471801758 c 0.0,0.0 42.8175811768,-34.3554534912 42.8175811768,-34.3554534912 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z" /> - <group - android:name="cross" > - <path - android:name="cross_1" - android:pathData="M 4.44044494629,2.24310302734 c 0.0,0.0 35.4000396729,35.3999633789 35.4000396729,35.3999633789 " - android:strokeColor="#FFFFFFFF" - android:strokeAlpha="1" - android:strokeWidth="3.5" - android:fillColor="#00000000" /> - </group> - <group - android:name="hotspot" - android:translateX="23.481" - android:translateY="18.71151" > - <group - android:name="circles" - android:translateX="-0.23909" - android:translateY="-0.10807" > - <path - android:name="circle_3" - android:pathData="M 0.0843505859375,-2.93901062012 c -2.30102539062,0.0 -4.16702270508,1.86602783203 -4.16702270508,4.16702270508 c 0.0,2.29898071289 1.86599731445,4.16598510742 4.16702270508,4.16598510742 c 2.29998779297,0.0 4.16598510742,-1.86700439453 4.16598510742,-4.16598510742 c 0.0,-2.30099487305 -1.86599731445,-4.16702270508 -4.16598510742,-4.16702270508 Z M 11.1185302734,5.83390808105 c 0.0,0.0 0.0009765625,0.00100708007812 0.0009765625,0.00100708007812 c 0.14501953125,-0.356994628906 0.27099609375,-0.725006103516 0.382995605469,-1.09799194336 c 0.0570068359375,-0.195007324219 0.101013183594,-0.394989013672 0.149017333984,-0.595001220703 c 0.0690002441406,-0.281005859375 0.126983642578,-0.563995361328 0.175994873047,-0.851989746094 c 0.0270080566406,-0.169006347656 0.0559997558594,-0.337005615234 0.0759887695313,-0.509002685547 c 0.0580139160156,-0.468017578125 0.0970153808594,-0.942993164062 0.0970153808593,-1.4280090332 c 0.0,0.0 0.0,-0.00100708007812 0.0,-0.00100708007812 c 0.0,-5.03900146484 -3.11099243164,-9.3450012207 -7.5119934082,-11.1229858398 c -0.00601196289062,-0.00299072265625 -0.0130004882812,-0.0050048828125 -0.0190124511719,-0.00701904296875 c -0.686004638672,-0.275970458984 -1.39999389648,-0.492980957031 -2.14099121094,-0.638977050781 c -0.072998046875,-0.0150146484375 -0.149017333984,-0.02099609375 -0.222991943359,-0.0339965820313 c -0.302001953125,-0.0540161132812 -0.605010986328,-0.106018066406 -0.916015625,-0.136016845703 c -0.389984130859,-0.0390014648438 -0.786987304688,-0.0599975585938 -1.18899536133,-0.0599975585937 c -0.402008056641,0.0 -0.799011230469,0.02099609375 -1.19000244141,0.0599975585937 c -0.304992675781,0.0299987792969 -0.602996826172,0.0809936523438 -0.901000976563,0.132995605469 c -0.0790100097656,0.0150146484375 -0.160003662109,0.02099609375 -0.238006591797,0.0370178222656 c -0.368988037109,0.0719909667969 -0.730987548828,0.164001464844 -1.08700561523,0.269989013672 c -0.00299072265625,0.00100708007812 -0.0059814453125,0.00201416015625 -0.00900268554687,0.0020141601562 c -0.351989746094,0.10498046875 -0.694000244141,0.226989746094 -1.0309753418,0.361999511719 c -0.0110168457031,0.00399780273438 -0.0220031738281,0.00698852539062 -0.0320129394531,0.0119934082031 c -4.40200805664,1.77798461914 -7.51098632812,6.083984375 -7.5119934082,11.1229858398 c 0.0,0.00799560546875 0.00198364257812,0.0160217285156 0.0019836425781,0.0240173339844 c 0.00100708007812,0.475006103516 0.0380249023438,0.940002441406 0.0950012207032,1.39898681641 c 0.02001953125,0.175994873047 0.0490112304688,0.348999023438 0.0780029296875,0.523010253906 c 0.0469970703125,0.281982421875 0.105010986328,0.557983398438 0.171997070312,0.833984375 c 0.0480041503906,0.204010009766 0.093017578125,0.410003662109 0.152008056641,0.610015869141 c 0.110992431641,0.372009277344 0.238006591797,0.736999511719 0.382019042969,1.09298706055 c 0.0,0.0 0.0009765625,0.0 0.0009765625,0.0 c 1.00701904297,2.48400878906 2.81301879883,4.56100463867 5.11001586914,5.89501953125 c 0.0,0.0 2.01599121094,-3.48300170898 2.01599121094,-3.48300170898 c -2.03900146484,-1.18402099609 -3.5119934082,-3.22500610352 -3.89898681641,-5.63900756836 c 0.0,0.0 0.0009765625,-0.00100708007812 0.0009765625,-0.00100708007812 c -0.0220031738281,-0.130981445312 -0.0369873046875,-0.265991210938 -0.052978515625,-0.399993896484 c -0.0290222167969,-0.274993896484 -0.0570068359375,-0.552001953125 -0.0570068359375,-0.834991455078 c 0.0,0.0 0.0,-0.0190124511719 0.0,-0.0190124511719 c 0.0,-3.98999023438 2.92498779297,-7.28900146484 6.74398803711,-7.89199829102 c 0.0,0.0 0.0180053710938,0.0169982910156 0.0180053710938,0.0169982910156 c 0.404998779297,-0.0639953613281 0.81298828125,-0.125 1.23599243164,-0.125 c 0.0,0.0 0.00201416015625,0.0 0.00201416015624,0.0 c 0.0,0.0 0.00299072265625,0.0 0.00299072265626,0.0 c 0.423004150391,0.0 0.830017089844,0.0610046386719 1.23501586914,0.125 c 0.0,0.0 0.0169982910156,-0.0180053710938 0.0169982910156,-0.0180053710938 c 3.81997680664,0.60400390625 6.74499511719,3.90301513672 6.74499511719,7.89199829102 c 0.0,0.292999267578 -0.0280151367188,0.578002929688 -0.0589904785156,0.861999511719 c -0.0150146484375,0.132019042969 -0.0290222167969,0.264007568359 -0.051025390625,0.393005371094 c -0.385986328125,2.41500854492 -1.85897827148,4.45599365234 -3.89797973633,5.64001464844 c 0.0,0.0 2.01599121094,3.48300170898 2.01599121094,3.48300170898 c 2.29699707031,-1.33401489258 4.10299682617,-3.41101074219 5.11001586914,-5.89602661133 Z M 19.9300231934,2.95698547363 c 0.0059814453125,-0.0659790039062 0.0159912109375,-0.130981445312 0.02099609375,-0.196990966797 c 0.031982421875,-0.462005615234 0.0479736328125,-0.928009033203 0.0489807128906,-1.39700317383 c 0,0.0 0,-0.00997924804688 0,-0.00997924804687 c 0,0.0 0,-0.00100708007812 0,-0.00100708007813 c 0,-7.22500610352 -3.84399414062,-13.5360107422 -9.58599853516,-17.0500183105 c -1.06500244141,-0.652984619141 -2.19299316406,-1.20599365234 -3.37799072266,-1.65197753906 c -0.157989501953,-0.0599975585938 -0.317016601562,-0.118011474609 -0.476989746094,-0.174011230469 c -0.317016601562,-0.110992431641 -0.634002685547,-0.218994140625 -0.9580078125,-0.31298828125 c -0.470001220703,-0.139007568359 -0.944000244141,-0.264007568359 -1.4280090332,-0.368011474609 c -0.186004638672,-0.0390014648438 -0.376983642578,-0.0669860839844 -0.565002441406,-0.101013183594 c -0.414001464844,-0.0759887695312 -0.832000732422,-0.140991210938 -1.25500488281,-0.190979003906 c -0.184997558594,-0.0220031738281 -0.369995117188,-0.0429992675781 -0.556976318359,-0.0599975585937 c -0.592010498047,-0.0530090332031 -1.18801879883,-0.0899963378906 -1.79602050781,-0.0899963378907 c -0.605987548828,0.0 -1.20300292969,0.0369873046875 -1.79598999023,0.0899963378907 c -0.186004638672,0.0169982910156 -0.371002197266,0.0379943847656 -0.555999755859,0.0599975585937 c -0.423004150391,0.0499877929688 -0.842010498047,0.114990234375 -1.25601196289,0.190979003906 c -0.18798828125,0.0350036621094 -0.377990722656,0.06201171875 -0.563995361328,0.101013183594 c -0.483001708984,0.10400390625 -0.959991455078,0.22900390625 -1.42999267578,0.368011474609 c -0.321990966797,0.093994140625 -0.638000488281,0.201995849609 -0.953002929688,0.311981201172 c -0.162994384766,0.0570068359375 -0.324005126953,0.115997314453 -0.484985351562,0.177001953125 c -1.18099975586,0.445007324219 -2.30599975586,0.997009277344 -3.36801147461,1.64700317383 c -0.00201416015625,0.00100708007812 -0.00399780273438,0.00201416015625 -0.0060119628907,0.0029907226562 c -5.74099731445,3.51400756836 -9.58499145508,9.82501220703 -9.58599853516,17.0500183105 c 0,0.0 0,0.00100708007812 0,0.00100708007813 c 0,0.0059814453125 0.00100708007812,0.0130004882812 0.0010070800781,0.0199890136719 c 0.0,0.466003417969 0.0169982910156,0.928009033203 0.0490112304688,1.38598632812 c 0.0050048828125,0.0690002441406 0.0159912109375,0.136016845703 0.02099609375,0.206024169922 c 0.031982421875,0.401000976562 0.0719909667969,0.799987792969 0.127990722656,1.19400024414 c 0.00201416015625,0.0189819335938 0.00701904296875,0.0369873046875 0.010009765625,0.0569763183594 c 0.888000488281,6.17202758789 4.59799194336,11.4250183105 9.7799987793,14.4309997559 c 0.0,0.0 2.00198364258,-3.458984375 2.00198364258,-3.458984375 c -2.58599853516,-1.5 -4.708984375,-3.70401000977 -6.11697387695,-6.34399414063 c 0.0,0.0 0.0169982910156,-0.0180053710938 0.0169982910156,-0.0180053710938 c -0.890014648438,-1.67098999023 -1.50601196289,-3.5110168457 -1.76000976562,-5.46499633789 c -0.00698852539062,-0.0500183105469 -0.010009765625,-0.102020263672 -0.0159912109375,-0.152008056641 c -0.0330200195312,-0.273010253906 -0.0610046386719,-0.545989990234 -0.0800170898437,-0.821990966797 c -0.0220031738281,-0.343017578125 -0.0350036621094,-0.68701171875 -0.0350036621094,-1.03500366211 c 0,-6.53701782227 3.92599487305,-12.1480102539 9.54299926758,-14.6310119629 c 0.157012939453,-0.0700073242188 0.313995361328,-0.135986328125 0.472015380859,-0.199981689453 c 0.373992919922,-0.151000976562 0.751983642578,-0.294006347656 1.13900756836,-0.417022705078 c 0.108978271484,-0.0350036621094 0.221984863281,-0.0619812011719 0.332000732422,-0.0950012207031 c 0.349975585938,-0.102996826172 0.705993652344,-0.194976806641 1.06597900391,-0.273986816406 c 0.114013671875,-0.0249938964844 0.227996826172,-0.052001953125 0.342010498047,-0.0750122070313 c 0.440002441406,-0.0869750976562 0.885986328125,-0.154998779297 1.33700561523,-0.203979492188 c 0.10400390625,-0.0120239257812 0.209991455078,-0.02001953125 0.315002441406,-0.0299987792969 c 0.47998046875,-0.0429992675781 0.963989257812,-0.072998046875 1.45397949219,-0.072998046875 c 0.492004394531,0.0 0.975006103516,0.0299987792969 1.45401000977,0.072998046875 c 0.105987548828,0.00997924804688 0.212005615234,0.0179748535156 0.316986083984,0.0299987792969 c 0.450012207031,0.0489807128906 0.89501953125,0.117004394531 1.33502197266,0.203002929688 c 0.115997314453,0.0239868164062 0.22998046875,0.0509948730469 0.345001220703,0.0769958496094 c 0.358001708984,0.0780029296875 0.710998535156,0.169982910156 1.06097412109,0.272003173828 c 0.111022949219,0.0329895019531 0.226013183594,0.0609741210938 0.336029052734,0.0969848632813 c 0.385986328125,0.123016357422 0.761993408203,0.265014648438 1.13497924805,0.415008544922 c 0.160003662109,0.0650024414062 0.319000244141,0.131988525391 0.477020263672,0.201995849609 c 5.61599731445,2.48400878906 9.53997802734,8.09399414062 9.53997802734,14.6310119629 c 0,0.346984863281 -0.0130004882812,0.690979003906 -0.0350036621094,1.03399658203 c -0.0179748535156,0.274993896484 -0.0469970703125,0.548004150391 -0.0789794921875,0.819000244141 c -0.00601196289062,0.052001953125 -0.010009765625,0.10498046875 -0.0160217285156,0.154998779297 c -0.252990722656,1.95498657227 -0.871002197266,3.79400634766 -1.75997924805,5.46499633789 c 0.0,0.0 0.0169982910156,0.0180053710938 0.0169982910156,0.0180053710938 c -1.40802001953,2.63998413086 -3.53100585938,4.84399414062 -6.11700439453,6.34399414063 c 0.0,0.0 2.00198364258,3.458984375 2.00198364258,3.458984375 c 5.18402099609,-3.00698852539 8.89501953125,-8.26300048828 9.78100585938,-14.4379882813 c 0.00201416015625,-0.0169982910156 0.00601196289062,-0.0320129394531 0.0079956054688,-0.0490112304688 c 0.0570068359375,-0.39697265625 0.0970153808594,-0.798980712891 0.129028320312,-1.20300292969 Z" - android:fillColor="#FFFFFFFF" - android:fillAlpha="1" /> - </group> - </group> - </group> - </group> -</vector> diff --git a/packages/SystemUI/res/drawable/ic_location.xml b/packages/SystemUI/res/drawable/ic_location.xml new file mode 100644 index 000000000000..50ba523fcd3e --- /dev/null +++ b/packages/SystemUI/res/drawable/ic_location.xml @@ -0,0 +1,27 @@ +<!-- + ~ 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="17dp" + android:height="17dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + <path + android:fillColor="#FFFFFFFF" + android:pathData="M12,2C8.13,2 5,5.13 5,9c0,5.25 7,13 7,13s7,-7.75 7,-13C19,5.13 15.87,2 12,2zM7,9c0,-2.76 2.24,-5 5,-5s5,2.24 5,5c0,2.88 -2.88,7.19 -5,9.88C9.92,16.21 7,11.85 7,9z"/> + <path + android:fillColor="#FFFFFFFF" + android:pathData="M12,9m-2.5,0a2.5,2.5 0,1 1,5 0a2.5,2.5 0,1 1,-5 0"/> +</vector> diff --git a/packages/SystemUI/res/drawable/ic_qs_bluetooth_connected.xml b/packages/SystemUI/res/drawable/ic_qs_bluetooth_connected.xml deleted file mode 100644 index dd124b713a72..000000000000 --- a/packages/SystemUI/res/drawable/ic_qs_bluetooth_connected.xml +++ /dev/null @@ -1,32 +0,0 @@ -<!-- -Copyright (C) 2017 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" - android:viewportWidth="24" - android:viewportHeight="24" - android:tint="?android:attr/colorControlNormal"> - - <path - android:fillColor="#FFFFFFFF" - android:pathData="M17.71,7.71L12,2h-1v7.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L11,14.41V22h1l5.71-5.71L13.41,12L17.71,7.71z M13,5.83 l1.88,1.88L13,9.59V5.83z M14.88,16.29L13,18.17v-3.76L14.88,16.29z" /> - <path - android:fillColor="#FFFFFFFF" - android:pathData="M 5 10.5 C 5.82842712475 10.5 6.5 11.1715728753 6.5 12 C 6.5 12.8284271247 5.82842712475 13.5 5 13.5 C 4.17157287525 13.5 3.5 12.8284271247 3.5 12 C 3.5 11.1715728753 4.17157287525 10.5 5 10.5 Z" /> - <path - android:fillColor="#FFFFFFFF" - android:pathData="M 19 10.5 C 19.8284271247 10.5 20.5 11.1715728753 20.5 12 C 20.5 12.8284271247 19.8284271247 13.5 19 13.5 C 18.1715728753 13.5 17.5 12.8284271247 17.5 12 C 17.5 11.1715728753 18.1715728753 10.5 19 10.5 Z" /> -</vector> diff --git a/packages/SystemUI/res/drawable/ic_qs_bluetooth_on.xml b/packages/SystemUI/res/drawable/ic_qs_bluetooth_on.xml index 220c63ccca6d..1c867064773c 100644 --- a/packages/SystemUI/res/drawable/ic_qs_bluetooth_on.xml +++ b/packages/SystemUI/res/drawable/ic_qs_bluetooth_on.xml @@ -14,13 +14,11 @@ Copyright (C) 2017 The Android Open Source Project 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" - android:tint="?android:attr/colorControlNormal"> - + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> <path - android:fillColor="#FFFFFFFF" - android:pathData="M17.71,7.71L12,2h-1v7.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L11,14.41V22h1l5.71-5.71L13.41,12L17.71,7.71z M13,5.83 l1.88,1.88L13,9.59V5.83z M14.88,16.29L13,18.17v-3.76L14.88,16.29z" /> -</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/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_cast_on.xml b/packages/SystemUI/res/drawable/ic_qs_cast_on.xml deleted file mode 100644 index 3dda87cf7e8b..000000000000 --- a/packages/SystemUI/res/drawable/ic_qs_cast_on.xml +++ /dev/null @@ -1,25 +0,0 @@ -<!-- -Copyright (C) 2017 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="64dp" - android:height="64dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - - <path - android:fillColor="#FFFFFFFF" - android:pathData="M1,18v2c0,0.55 0.45,1 1,1h2c0,-1.66 -1.34,-3 -3,-3zM0.97,15.06c-0.01,0.51 0.35,0.93 0.85,1.02 2.08,0.36 3.74,2 4.1,4.08 0.09,0.48 0.5,0.84 0.99,0.84 0.61,0 1.09,-0.54 1,-1.14a6.996,6.996 0,0 0,-5.8 -5.78c-0.59,-0.09 -1.12,0.38 -1.14,0.98zM19,7L5,7v1.63c3.96,1.28 7.09,4.41 8.37,8.37L19,17L19,7zM0.97,11.03c-0.01,0.52 0.37,0.96 0.88,1.01 4.26,0.43 7.68,3.82 8.1,8.08 0.05,0.5 0.48,0.88 0.99,0.88 0.59,0 1.06,-0.51 1,-1.1 -0.52,-5.21 -4.66,-9.34 -9.87,-9.85 -0.57,-0.05 -1.08,0.4 -1.1,0.98zM21,3L3,3c-1.1,0 -2,0.9 -2,2v3h2L3,5h18v14h-7v2h7c1.1,0 2,-0.9 2,-2L23,5c0,-1.1 -0.9,-2 -2,-2z" /> -</vector> diff --git a/packages/SystemUI/res/drawable/ic_volume_alarm.xml b/packages/SystemUI/res/drawable/ic_volume_alarm.xml index 996e488e8c81..771b466dc6d1 100644 --- a/packages/SystemUI/res/drawable/ic_volume_alarm.xml +++ b/packages/SystemUI/res/drawable/ic_volume_alarm.xml @@ -14,14 +14,12 @@ limitations under the License. --> <vector xmlns:android="http://schemas.android.com/apk/res/android" - android:height="24.0dp" - android:viewportHeight="24.0" - android:viewportWidth="24.0" - android:width="24.0dp" - android:tint="?android:attr/colorControlNormal"> - + android:height="24dp" + android:width="24dp" + android:viewportHeight="24" + android:viewportWidth="24"> <path android:fillColor="#FFFFFF" - android:pathData="M2.7,6.5c-0.4,-0.4 -0.3,-1 0.1,-1.4l3,-2.6c0.4,-0.4 1,-0.3 1.4,0.1C7.6,3 7.5,3.7 7.1,4l-3,2.6C3.6,7 3,6.9 2.7,6.5zM21.3,5.1l-3.1,-2.6c-0.4,-0.4 -0.99,-0.31 -1.4,0.1c-0.4,0.4 -0.3,1 0.1,1.4L20,6.6c0.41,0.37 1,0.3 1.4,-0.1C21.73,6.12 21.7,5.4 21.3,5.1zM21,13c0,5 -4,9 -9,9s-9,-4 -9,-9s4,-9 9,-9S21,8 21,13zM19.1,13c0,-3.9 -3.2,-7.1 -7.1,-7.1S4.9,9.1 4.9,13s3.2,7.1 7.1,7.1S19.1,16.9 19.1,13zM11.75,8C11.34,8 11,8.34 11,8.75V14l4.14,2.48c0.34,0.21 0.77,0.1 0.98,-0.24s0.09,-0.79 -0.25,-0.99l-3.37,-2v-4.5C12.5,8.34 12.16,8 11.75,8z"/> + android:pathData="M13,8h-2v5.41l3.79,3.8 1.42,-1.42 -3.21,-3.2zM12,4c-4.97,0 -9,4.03 -9,9s4.03,9 9,9 9,-4.03 9,-9 -4.03,-9 -9,-9zM12,20c-3.86,0 -7,-3.14 -7,-7s3.14,-7 7,-7 7,3.14 7,7 -3.14,7 -7,7zM16.056,3.346l1.282,-1.535 4.607,3.85 -1.28,1.54zM2.056,5.654L6.663,1.81l1.28,1.536L3.338,7.19z"/> </vector> diff --git a/packages/SystemUI/res/drawable/ic_volume_alarm_mute.xml b/packages/SystemUI/res/drawable/ic_volume_alarm_mute.xml index 02fb1e702438..18e273669854 100644 --- a/packages/SystemUI/res/drawable/ic_volume_alarm_mute.xml +++ b/packages/SystemUI/res/drawable/ic_volume_alarm_mute.xml @@ -22,6 +22,6 @@ <path android:fillColor="#FFFFFF" - android:pathData="M21.35,6.49c-0.35,0.42 -0.98,0.47 -1.4,0.12l-3.07,-2.57a1,1 0,1 1,1.29 -1.53l3.07,2.57c0.42,0.35 0.47,0.98 0.11,1.41zM20.72,20.09a0.9,0.9 0,0 1,0 1.27,0.9 0.9,0 0,1 -1.27,0l-1.57,-1.57A8.875,8.875 0,0 1,12 22c-4.98,0 -9,-4.03 -9,-9 0,-2.25 0.83,-4.31 2.2,-5.89l-0.8,-0.8 -0.41,0.35a1,1 0,0 1,-1.35 -0.06,1 1,0 0,1 0.07,-1.47l0.27,-0.23 -0.7,-0.7a0.9,0.9 0,0 1,0 -1.27c0.35,-0.35 0.93,-0.35 1.28,0l17.16,17.16zM16.54,18.45L6.55,8.46A7.041,7.041 0,0 0,4.9 13c0,3.91 3.19,7.1 7.1,7.1 1.73,0 3.31,-0.62 4.54,-1.65zM7.17,3.98A0.997,0.997 0,1 0,5.9 2.44l-0.16,0.13 1.42,1.42 0.01,-0.01zM12,4c-1.41,0 -2.73,0.33 -3.92,0.91l1.45,1.45c0.77,-0.29 1.6,-0.46 2.47,-0.46 3.91,0 7.1,3.18 7.1,7.1 0,0.87 -0.17,1.7 -0.45,2.47l1.44,1.44c0.58,-1.18 0.91,-2.5 0.91,-3.91a9,9 0,0 0,-9 -9z"/> + android:pathData="M16.056,3.346l1.282,-1.535 4.607,3.85 -1.28,1.54zM9.35,6.52C10.17,6.19 11.06,6 12,6c3.86,0 7,3.14 7,7 0,0.94 -0.19,1.83 -0.52,2.65l1.5,1.5C20.63,15.91 21,14.5 21,13c0,-4.97 -4.03,-9 -9,-9 -1.5,0 -2.91,0.37 -4.15,1.02l1.5,1.5zM17.42,17.42L7.58,7.58 6.16,6.16l-0.72,-0.72 -1.42,-1.42 -1.21,-1.21 -1.42,1.41L2.48,5.3l-0.42,0.35 1.28,1.54 0.56,-0.47 0.9,0.9C3.67,9.12 3,10.98 3,13c0,4.97 4.03,9 9,9 2.02,0 3.88,-0.67 5.38,-1.79l2.4,2.4 1.41,-1.41 -2.35,-2.35 -1.42,-1.43zM12,20c-3.86,0 -7,-3.14 -7,-7 0,-1.46 0.46,-2.82 1.23,-3.94l9.71,9.71C14.82,19.54 13.46,20 12,20zM7.94,3.35L6.66,1.81l-1.1,0.92 1.42,1.42z"/> </vector> diff --git a/packages/SystemUI/res/drawable/ic_volume_ringer_vibrate.xml b/packages/SystemUI/res/drawable/ic_volume_ringer_vibrate.xml index aa13f1e2a9e7..314e06cc93b0 100644 --- a/packages/SystemUI/res/drawable/ic_volume_ringer_vibrate.xml +++ b/packages/SystemUI/res/drawable/ic_volume_ringer_vibrate.xml @@ -14,11 +14,10 @@ limitations under the License. --> <vector xmlns:android="http://schemas.android.com/apk/res/android" - android:height="24dp" + android:height="19dp" + android:width="19dp" android:viewportHeight="24.0" - android:viewportWidth="24.0" - android:width="24dp" - android:tint="?android:attr/colorControlNormal" > + android:viewportWidth="24.0"> <path android:fillColor="#FFFFFFFF" diff --git a/packages/SystemUI/res/drawable/stat_sys_airplane_mode.xml b/packages/SystemUI/res/drawable/stat_sys_airplane_mode.xml index 2655bcda3c57..0f8c57183950 100644 --- a/packages/SystemUI/res/drawable/stat_sys_airplane_mode.xml +++ b/packages/SystemUI/res/drawable/stat_sys_airplane_mode.xml @@ -16,16 +16,5 @@ ** limitations under the License. */ --> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="17.25dp" - android:height="18dp" - android:viewportWidth="19.65" - android:viewportHeight="20.5"> - <group - android:translateX="1.3" - android:translateY="1.7"> - <path - android:pathData="M16.01,9.87l-6.24,-3.9v-4.7C9.77,0.57 9.21,0 8.5,0S7.23,0.57 7.23,1.28v4.7L0.99,9.88c-0.37,0.23 -0.6,0.64 -0.6,1.08v0.41c0,0.29 0.29,0.5 0.55,0.41l6.27,-1.97v4.7l-1.37,1.02c-0.21,0.16 -0.34,0.41 -0.34,0.68v0.57c0,0.15 0.12,0.23 0.27,0.2 1.67,-0.47 1.12,-0.31 2.73,-0.78 1.03,0.3 1.7,0.49 2.72,0.78 0.15,0.03 0.27,-0.06 0.27,-0.2v-0.57c0,-0.27 -0.13,-0.52 -0.34,-0.68l-1.37,-1.02v-4.7l6.27,1.97c0.28,0.09 0.55,-0.12 0.55,-0.41v-0.41c0.01,-0.45 -0.23,-0.87 -0.59,-1.09z" - android:fillColor="#FFF"/> - </group> -</vector> +<inset xmlns:android="http://schemas.android.com/apk/res/android" + android:drawable="@*android:drawable/ic_qs_airplane" /> diff --git a/packages/SystemUI/res/drawable/stat_sys_alarm.xml b/packages/SystemUI/res/drawable/stat_sys_alarm.xml index 0e9319c63eaa..b9bebec5baba 100644 --- a/packages/SystemUI/res/drawable/stat_sys_alarm.xml +++ b/packages/SystemUI/res/drawable/stat_sys_alarm.xml @@ -1,35 +1,21 @@ -<?xml version="1.0" encoding="utf-8"?> <!-- -** -** Copyright 2017, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. + * + * Copyright 2017, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ --> <inset xmlns:android="http://schemas.android.com/apk/res/android" android:insetLeft="2.5dp" - android:insetRight="2.5dp"> - <vector - android:width="17dp" - android:height="17dp" - android:viewportWidth="19.3" - android:viewportHeight="19.3"> - <group - android:translateX="1.2" - android:translateY="1.2"> - <path - android:pathData="M0.97,3.97c-0.32,-0.33 -0.24,-0.81 0.08,-1.13L3.47,0.74C3.79,0.42 4.28,0.5 4.6,0.82s0.24,0.89 -0.08,1.13L2.1,4.05c-0.4,0.32 -0.89,0.24 -1.13,-0.08zM15.97,2.84l-2.5,-2.1c-0.32,-0.32 -0.8,-0.25 -1.13,0.08 -0.32,0.32 -0.24,0.81 0.08,1.13l2.5,2.1c0.33,0.3 0.81,0.24 1.13,-0.08 0.27,-0.31 0.25,-0.89 -0.08,-1.13zM15.73,9.21c0,4.03 -3.23,7.26 -7.26,7.26s-7.26,-3.23 -7.26,-7.26 3.23,-7.26 7.26,-7.26 7.26,3.23 7.26,7.26zM14.2,9.21c0,-3.15 -2.58,-5.73 -5.73,-5.73S2.74,6.06 2.74,9.21s2.58,5.73 5.73,5.73 5.73,-2.59 5.73,-5.73zM8.27,5.18c-0.33,0 -0.6,0.27 -0.6,0.6v4.23l3.34,2c0.27,0.17 0.62,0.08 0.79,-0.19s0.07,-0.64 -0.2,-0.8L8.87,9.41L8.87,5.78c0,-0.33 -0.27,-0.6 -0.6,-0.6z" - android:fillColor="#FFF"/> - </group> - </vector> -</inset> + android:insetRight="2.5dp" + android:drawable="@drawable/ic_alarm" /> diff --git a/packages/SystemUI/res/drawable/stat_sys_alarm_dim.xml b/packages/SystemUI/res/drawable/stat_sys_alarm_dim.xml index c8e2ac19a4e2..cf1119d80fa3 100644 --- a/packages/SystemUI/res/drawable/stat_sys_alarm_dim.xml +++ b/packages/SystemUI/res/drawable/stat_sys_alarm_dim.xml @@ -15,18 +15,5 @@ --> <inset xmlns:android="http://schemas.android.com/apk/res/android" android:insetLeft="2.5dp" - android:insetRight="2.5dp"> - - <vector - android:width="17dp" - android:height="17dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - - <path - android:fillColor="#4dffffff" - android:pathData="M22.0,5.7l-4.6,-3.9l-1.3,1.5l4.6,3.9L22.0,5.7zM7.9,3.4L6.6,1.9L2.0,5.7l1.3,1.5L7.9,3.4zM12.5,8.0L11.0,8.0l0.0,6.0l4.7,2.9l0.8,-1.2l-4.0,-2.4L12.5,8.0zM12.0,4.0c-5.0,0.0 -9.0,4.0 -9.0,9.0c0.0,5.0 4.0,9.0 9.0,9.0s9.0,-4.0 9.0,-9.0C21.0,8.0 17.0,4.0 12.0,4.0zM12.0,20.0c-3.9,0.0 -7.0,-3.1 -7.0,-7.0c0.0,-3.9 3.1,-7.0 7.0,-7.0c3.9,0.0 7.0,3.1 7.0,7.0C19.0,16.9 15.9,20.0 12.0,20.0z"/> - - </vector> - -</inset>
\ No newline at end of file + android:insetRight="2.5dp" + android:drawable="@drawable/ic_alarm_dim" /> 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_camera.xml b/packages/SystemUI/res/drawable/stat_sys_camera.xml index eb3e9632dd35..c914262571ea 100644 --- a/packages/SystemUI/res/drawable/stat_sys_camera.xml +++ b/packages/SystemUI/res/drawable/stat_sys_camera.xml @@ -18,14 +18,5 @@ --> <inset xmlns:android="http://schemas.android.com/apk/res/android" android:insetLeft="3dp" - android:insetRight="3dp"> - <vector - android:width="17dp" - android:height="17dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - <path - android:fillColor="#FFF" - android:pathData="M20,5h-3.17L15,3H9L7.17,5H4C2.9,5 2,5.9 2,7v12c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2V7C22,5.9 21.1,5 20,5zM20,19H4V7h16V19zM12,9c-2.21,0 -4,1.79 -4,4c0,2.21 1.79,4 4,4s4,-1.79 4,-4C16,10.79 14.21,9 12,9z"/> - </vector> -</inset> + android:insetRight="3dp" + android:drawable="@drawable/ic_camera" />
\ No newline at end of file diff --git a/packages/SystemUI/res/drawable/stat_sys_cast.xml b/packages/SystemUI/res/drawable/stat_sys_cast.xml index 5228085b5dc5..de7ec9d628bb 100644 --- a/packages/SystemUI/res/drawable/stat_sys_cast.xml +++ b/packages/SystemUI/res/drawable/stat_sys_cast.xml @@ -15,14 +15,5 @@ Copyright (C) 2017 The Android Open Source Project --> <inset xmlns:android="http://schemas.android.com/apk/res/android" android:insetLeft="2.5dp" - android:insetRight="2.5dp"> - <vector android:width="17dp" - android:height="17dp" - android:viewportWidth="17.0" - android:viewportHeight="17.0"> - - <path - android:fillColor="#FFFFFFFF" - android:pathData="M0.71,12.75v1.42c0,0.39 0.32,0.71 0.71,0.71h1.42C2.83,13.7 1.88,12.75 0.71,12.75zM0.69,10.67c-0.01,0.36 0.25,0.66 0.6,0.72c1.47,0.26 2.65,1.42 2.9,2.89c0.06,0.34 0.35,0.6 0.7,0.6c0.43,0 0.77,-0.38 0.71,-0.81c-0.34,-2.11 -2,-3.76 -4.11,-4.09C1.08,9.91 0.7,10.24 0.69,10.67zM13.46,4.96H3.54v1.15c2.81,0.91 5.02,3.12 5.93,5.93h3.99V4.96zM0.69,7.81C0.68,8.18 0.95,8.49 1.31,8.53c3.02,0.3 5.44,2.71 5.74,5.72c0.04,0.35 0.34,0.62 0.7,0.62c0.42,0 0.75,-0.36 0.71,-0.78c-0.37,-3.69 -3.3,-6.62 -6.99,-6.98C1.06,7.08 0.7,7.4 0.69,7.81zM14.88,2.12H2.12c-0.78,0 -1.42,0.64 -1.42,1.42v2.12h1.42V3.54h12.75v9.92H9.92v1.42h4.96c0.78,0 1.42,-0.64 1.42,-1.42V3.54C16.29,2.76 15.65,2.12 14.88,2.12z" /> - </vector> -</inset> + android:insetRight="2.5dp" + android:drawable="@drawable/ic_cast_connected" />
\ No newline at end of file diff --git a/packages/SystemUI/res/drawable/stat_sys_data_bluetooth.xml b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth.xml deleted file mode 100644 index 4dc0e4baa397..000000000000 --- a/packages/SystemUI/res/drawable/stat_sys_data_bluetooth.xml +++ /dev/null @@ -1,31 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -** -** Copyright 2017, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="17dp" - android:height="17dp" - android:viewportWidth="17.0" - android:viewportHeight="17.0"> - <group - android:translateY="0.5" - android:translateX="0.5" > - <path - android:pathData="M8.84,8l2.62,-2.62c0.29,-0.29 0.29,-0.75 0,-1.04L8.33,1.22L8.31,1.2c-0.3,-0.28 -0.76,-0.26 -1.03,0.04c-0.13,0.13 -0.2,0.31 -0.2,0.5v4.51L4.24,3.4c-0.29,-0.29 -0.74,-0.29 -1.03,0s-0.29,0.74 0,1.03L6.78,8l-3.56,3.56c-0.29,0.29 -0.29,0.74 0,1.03s0.74,0.29 1.03,0l2.83,-2.83v4.51c0,0.4 0.33,0.73 0.73,0.73c0.18,0 0.36,-0.07 0.5,-0.2l0.03,-0.03l3.12,-3.12c0.29,-0.29 0.29,-0.75 0,-1.04L8.84,8zM8.47,6.37V3.36l1.5,1.5L8.47,6.37zM8.47,12.63V9.62l1.5,1.5L8.47,12.63z" - android:fillColor="#FFFFFF"/> - </group> -</vector> diff --git a/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected.xml b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected.xml index c8a444064fd6..8d9e561df793 100644 --- a/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected.xml +++ b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected.xml @@ -1,31 +1,17 @@ -<?xml version="1.0" encoding="utf-8"?> <!-- -** -** Copyright 2017, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ +Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. --> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="17dp" - android:height="17dp" - android:viewportWidth="18.0" - android:viewportHeight="18.0"> - <group - android:translateY="0.5" - android:translateX="0.5" > - <path - android:pathData="M9.57,8.5l2.79,-2.78c0.3,-0.3 0.3,-0.8 0,-1.1L9.04,1.29L9.02,1.27C8.7,0.98 8.21,1 7.91,1.31C7.78,1.45 7.71,1.64 7.71,1.84v4.79L4.69,3.61c-0.3,-0.3 -0.79,-0.3 -1.09,0s-0.3,0.79 0,1.09L7.39,8.5L3.6,12.29c-0.3,0.3 -0.3,0.79 0,1.09s0.79,0.3 1.09,0l3.01,-3.01v4.8c0,0.42 0.35,0.77 0.77,0.77c0.19,0 0.39,-0.07 0.53,-0.21l0.04,-0.04l3.32,-3.32c0.3,-0.3 0.3,-0.8 0,-1.1L9.57,8.5zM9.19,6.77v-3.2l1.6,1.6L9.19,6.77zM9.19,13.42v-3.2l1.6,1.6L9.19,13.42zM4.03,9.29c-0.44,0.44 -1.15,0.44 -1.58,0C2.02,8.86 2.02,8.16 2.45,7.72l0.01,-0.01C2.89,7.27 3.59,7.27 4.02,7.7l0.01,0.01C4.47,8.15 4.47,8.85 4.03,9.29zM14.44,7.71c0.44,0.44 0.44,1.15 0,1.58c-0.44,0.44 -1.15,0.44 -1.58,0c-0.44,-0.43 -0.44,-1.13 -0.01,-1.57l0.01,-0.01C13.3,7.28 14,7.27 14.43,7.7C14.44,7.7 14.44,7.71 14.44,7.71z" - android:fillColor="#FFFFFF"/> - </group> -</vector> +<inset xmlns:android="http://schemas.android.com/apk/res/android" + android:drawable="@drawable/ic_bluetooth_connected" />
\ No newline at end of file diff --git a/packages/SystemUI/res/drawable/stat_sys_data_saver.xml b/packages/SystemUI/res/drawable/stat_sys_data_saver.xml index fed7caec377a..022350173a35 100644 --- a/packages/SystemUI/res/drawable/stat_sys_data_saver.xml +++ b/packages/SystemUI/res/drawable/stat_sys_data_saver.xml @@ -18,26 +18,5 @@ --> <inset xmlns:android="http://schemas.android.com/apk/res/android" android:insetLeft="2.5dp" - android:insetRight="2.5dp" > - <vector - android:width="18dp" - android:height="18dp" - android:viewportWidth="19.0" - android:viewportHeight="19.0"> - <group - android:translateX="1.0" - android:translateY="1.0"> - <path - android:pathData="M11.5,8.5c0,0.41 -0.34,0.74 -0.74,0.74L9.24,9.24v1.5c0,0.41 -0.34,0.74 -0.74,0.74s-0.74,-0.34 -0.74,-0.74v-1.5h-1.5c-0.41,0 -0.74,-0.34 -0.74,-0.74s0.34,-0.74 0.74,-0.74h1.5v-1.5c0,-0.41 0.34,-0.74 0.74,-0.74s0.74,0.34 0.74,0.74v1.5h1.5c0.42,-0.01 0.76,0.33 0.76,0.74z" - android:fillColor="#FFF"/> - <path - android:pathData="M13.23,12.05l0.99,0.57c0.19,0.12 0.25,0.38 0.12,0.55A7.452,7.452 0,0 1,7.5 15.9c-3.29,-0.44 -5.96,-3.08 -6.41,-6.38 -0.57,-4.17 2.33,-7.8 6.23,-8.42 0.23,-0.04 0.44,0.15 0.44,0.37v1.15c0,0.18 -0.14,0.33 -0.31,0.37 -2.7,0.52 -4.71,2.96 -4.55,5.83 0.16,2.86 2.57,5.21 5.43,5.29 1.77,0.06 3.38,-0.72 4.44,-1.97 0.11,-0.14 0.31,-0.18 0.46,-0.09z" - android:fillColor="#FFF" /> - <path - android:pathData="M14.11,8.5c0,0.62 -0.11,1.22 -0.29,1.78 -0.06,0.17 0.01,0.35 0.16,0.45l1,0.57c0.19,0.12 0.46,0.03 0.54,-0.18 0.3,-0.82 0.47,-1.7 0.47,-2.62 0,-3.73 -2.73,-6.82 -6.31,-7.39a0.377,0.377 0,0 0,-0.44 0.37v1.15c0,0.18 0.14,0.33 0.31,0.36 2.59,0.51 4.56,2.78 4.56,5.51z" - android:fillAlpha="0.3" - android:fillColor="#FFF" /> - - </group> - </vector> -</inset> + android:insetRight="2.5dp" + android:drawable="@drawable/ic_data_saver" />
\ No newline at end of file diff --git a/packages/SystemUI/res/drawable/stat_sys_dnd.xml b/packages/SystemUI/res/drawable/stat_sys_dnd.xml index 68a06d013bf7..aa352b42cf04 100644 --- a/packages/SystemUI/res/drawable/stat_sys_dnd.xml +++ b/packages/SystemUI/res/drawable/stat_sys_dnd.xml @@ -18,17 +18,5 @@ --> <inset xmlns:android="http://schemas.android.com/apk/res/android" android:insetLeft="2.5dp" - android:insetRight="2.5dp" > - <vector - android:width="17dp" - android:height="17dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - <path - android:fillColor="#FFFFFFFF" - android:pathData="M12,2C6.48,2 2,6.48 2,12c0,5.52 4.48,10 10,10c5.52,0 10,-4.48 10,-10C22,6.48 17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8c0,-4.41 3.59,-8 8,-8c4.41,0 8,3.59 8,8C20,16.41 16.41,20 12,20z"/> - <path - android:fillColor="#FFFFFFFF" - android:pathData="M7,11h10v2h-10z"/> - </vector> -</inset> + android:insetRight="2.5dp" + android:drawable="@*android:drawable/ic_qs_dnd" />
\ No newline at end of file diff --git a/packages/SystemUI/res/drawable/stat_sys_zen_important.xml b/packages/SystemUI/res/drawable/stat_sys_headset.xml index 1262617589d5..361c6659c5e4 100644 --- a/packages/SystemUI/res/drawable/stat_sys_zen_important.xml +++ b/packages/SystemUI/res/drawable/stat_sys_headset.xml @@ -1,7 +1,7 @@ <!-- -Copyright (C) 2014 The Android Open Source Project + Copyright (C) 2016 The Android Open Source Project - Licensed under the Apache License, Version 2.0 (the "License"); + Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at @@ -15,14 +15,5 @@ Copyright (C) 2014 The Android Open Source Project --> <inset xmlns:android="http://schemas.android.com/apk/res/android" android:insetLeft="2.5dp" - android:insetRight="2.5dp"> - <vector android:width="18dp" - android:height="18dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - - <path - android:fillColor="#FFFFFFFF" - android:pathData="M12.0,17.273l6.1800003,3.7269993 -1.6350002,-7.0290003 5.455,-4.7269993 -7.191,-0.6170006 -2.809,-6.627 -2.809,6.627 -7.191,0.6170006 5.455,4.7269993 -1.6349998,7.0290003z"/> - </vector> -</inset> + android:insetRight="2.5dp" + android:drawable="@drawable/ic_headset" /> diff --git a/packages/SystemUI/res/drawable/stat_sys_headset_mic.xml b/packages/SystemUI/res/drawable/stat_sys_headset_mic.xml new file mode 100644 index 000000000000..b424caa6e12c --- /dev/null +++ b/packages/SystemUI/res/drawable/stat_sys_headset_mic.xml @@ -0,0 +1,19 @@ +<!-- + Copyright (C) 2016 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<inset xmlns:android="http://schemas.android.com/apk/res/android" + android:insetLeft="2.5dp" + android:insetRight="2.5dp" + android:drawable="@drawable/ic_headset_mic" /> diff --git a/packages/SystemUI/res/drawable/stat_sys_hotspot.xml b/packages/SystemUI/res/drawable/stat_sys_hotspot.xml index 4f52777339c5..361b00ae0598 100644 --- a/packages/SystemUI/res/drawable/stat_sys_hotspot.xml +++ b/packages/SystemUI/res/drawable/stat_sys_hotspot.xml @@ -15,18 +15,5 @@ Copyright (C) 2017 The Android Open Source Project --> <inset xmlns:android="http://schemas.android.com/apk/res/android" android:insetLeft="2.5dp" - android:insetRight="2.5dp"> - <vector - android:width="18.0dp" - android:height="18.0dp" - android:viewportWidth="18.0" - android:viewportHeight="18.0"> - <group - android:translateX="0.5" - android:translateY="0.5" > - <path - android:pathData="M8.5,7.79c-0.78,0 -1.42,0.64 -1.42,1.42c0,0.78 0.64,1.42 1.42,1.42s1.42,-0.64 1.42,-1.42C9.92,8.43 9.28,7.79 8.5,7.79zM12.75,9.21c0,-2.35 -1.9,-4.25 -4.25,-4.25c-0.18,0 -0.35,0.01 -0.53,0.03C6.11,5.22 4.58,6.7 4.3,8.55c-0.23,1.52 0.35,2.91 1.36,3.82C6,12.67 6.54,12.6 6.76,12.2c0.17,-0.3 0.1,-0.67 -0.16,-0.89c-0.78,-0.7 -1.12,-1.77 -0.86,-2.79C5.99,7.5 6.78,6.71 7.8,6.46C9.32,6.08 10.86,7 11.25,8.52c0.06,0.23 0.09,0.46 0.09,0.69c0,0.84 -0.36,1.58 -0.94,2.1c-0.25,0.23 -0.33,0.6 -0.16,0.9c0.22,0.38 0.74,0.49 1.06,0.2C12.22,11.6 12.75,10.43 12.75,9.21zM7.63,1.85C4.19,2.24 1.42,5.07 1.1,8.52c-0.26,2.61 0.88,5.15 2.99,6.7c0.36,0.26 0.86,0.15 1.09,-0.23c0.19,-0.32 0.1,-0.74 -0.19,-0.96c-1.7,-1.26 -2.71,-3.38 -2.35,-5.73c0.4,-2.6 2.57,-4.68 5.19,-4.97c3.59,-0.41 6.63,2.4 6.63,5.91c0,1.97 -0.96,3.7 -2.43,4.79c-0.3,0.22 -0.38,0.63 -0.19,0.96c0.22,0.39 0.73,0.49 1.09,0.23c1.9,-1.4 3.03,-3.62 3.03,-5.98C15.94,4.84 12.12,1.34 7.63,1.85z" - android:fillColor="#FFFFFFFF"/> - </group> - </vector> -</inset> + android:insetRight="2.5dp" + android:drawable="@drawable/ic_hotspot" /> diff --git a/packages/SystemUI/res/drawable/stat_sys_location.xml b/packages/SystemUI/res/drawable/stat_sys_location.xml index bdb0b0c2c29f..7a5aeb9ae558 100644 --- a/packages/SystemUI/res/drawable/stat_sys_location.xml +++ b/packages/SystemUI/res/drawable/stat_sys_location.xml @@ -14,18 +14,6 @@ ~ limitations under the License --> <inset xmlns:android="http://schemas.android.com/apk/res/android" - android:insetLeft="1.5dp" - android:insetRight="1.5dp"> - <vector - android:width="17dp" - android:height="17dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - <path - android:fillColor="#FFFFFFFF" - android:pathData="M12,2C8.13,2 5,5.13 5,9c0,5.25 7,13 7,13s7,-7.75 7,-13C19,5.13 15.87,2 12,2zM7,9c0,-2.76 2.24,-5 5,-5s5,2.24 5,5c0,2.88 -2.88,7.19 -5,9.88C9.92,16.21 7,11.85 7,9z"/> - <path - android:fillColor="#FFFFFFFF" - android:pathData="M12,9m-2.5,0a2.5,2.5 0,1 1,5 0a2.5,2.5 0,1 1,-5 0"/> - </vector> -</inset>
\ No newline at end of file + android:insetLeft="2.5dp" + android:insetRight="2.5dp" + android:drawable="@drawable/ic_location" /> diff --git a/packages/SystemUI/res/drawable/stat_sys_ringer_vibrate.xml b/packages/SystemUI/res/drawable/stat_sys_ringer_vibrate.xml index 0b72f75ff97d..21a4c1703d31 100644 --- a/packages/SystemUI/res/drawable/stat_sys_ringer_vibrate.xml +++ b/packages/SystemUI/res/drawable/stat_sys_ringer_vibrate.xml @@ -1,36 +1,19 @@ -<?xml version="1.0" encoding="utf-8"?> <!-- -** -** Copyright 2017, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ + Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. --> <inset xmlns:android="http://schemas.android.com/apk/res/android" android:insetLeft="2.5dp" - android:insetRight="2.5dp"> - <vector - android:width="19dp" - android:height="19dp" - android:viewportWidth="23.0" - android:viewportHeight="23.0"> - <group - android:translateX="-0.5" - android:translateY="-0.5"> - <path - android:fillColor="#F00" - android:pathData="M1,9h2v6H1V9zM4,17h2V7H4V17zM21,9v6h2V9H21zM18,17h2V7h-2V17zM17,5.5v13c0,0.83 -0.67,1.5 -1.5,1.5h-7C7.67,20 7,19.33 7,18.5v-13C7,4.67 7.67,4 8.5,4h7C16.33,4 17,4.67 17,5.5zM15,6H9v12h6V6z"/> - - </group> - </vector> -</inset> + android:insetRight="2.5dp" + android:drawable="@drawable/ic_volume_ringer_vibrate" />
\ No newline at end of file diff --git a/packages/SystemUI/res/drawable/stat_sys_zen_none.xml b/packages/SystemUI/res/drawable/stat_sys_zen_none.xml deleted file mode 100644 index 92914a8dd988..000000000000 --- a/packages/SystemUI/res/drawable/stat_sys_zen_none.xml +++ /dev/null @@ -1,28 +0,0 @@ -<!-- -Copyright (C) 2014 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<inset xmlns:android="http://schemas.android.com/apk/res/android" - android:insetLeft="2.5dp" - android:insetRight="2.5dp"> - <vector android:width="17dp" - android:height="17dp" - android:viewportWidth="48.0" - android:viewportHeight="48.0"> - - <path - android:fillColor="#FFFFFFFF" - android:pathData="M24.0,4.0C13.0,4.0 4.0,13.0 4.0,24.0c0.0,11.0 9.0,20.0 20.0,20.0c11.0,0.0 20.0,-9.0 20.0,-20.0C44.0,13.0 35.0,4.0 24.0,4.0zM24.0,40.0c-8.8,0.0 -16.0,-7.2 -16.0,-16.0c0.0,-3.7 1.3,-7.1 3.4,-9.8l22.4,22.4C31.1,38.7 27.7,40.0 24.0,40.0zM36.6,33.8L14.2,11.4C16.9,9.3 20.3,8.0 24.0,8.0c8.8,0.0 16.0,7.2 16.0,16.0C40.0,27.7 38.7,31.1 36.6,33.8z"/> - </vector> -</inset> 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/bubble_expanded_view.xml b/packages/SystemUI/res/layout/bubble_expanded_view.xml index 56a3cd5499e3..bdc4ebdee054 100644 --- a/packages/SystemUI/res/layout/bubble_expanded_view.xml +++ b/packages/SystemUI/res/layout/bubble_expanded_view.xml @@ -33,35 +33,13 @@ android:layout_height="wrap_content" android:animateLayoutChanges="true"> - <LinearLayout - android:id="@+id/header_layout" - android:layout_height="@dimen/bubble_expanded_header_height" - android:layout_width="match_parent" - android:animateLayoutChanges="true" - android:gravity="end|center_vertical" - android:orientation="horizontal"> - - <ImageButton - android:id="@+id/deep_link_button" - android:layout_width="@dimen/bubble_header_icon_size" - android:layout_height="@dimen/bubble_header_icon_size" - android:src="@drawable/ic_open_in_new" - android:scaleType="center" - android:tint="?android:attr/colorForeground" - android:background="?android:attr/selectableItemBackground" - /> - - <ImageButton - android:id="@id/settings_button" - android:layout_width="@dimen/bubble_header_icon_size" - android:layout_height="@dimen/bubble_header_icon_size" - android:src="@drawable/ic_settings" - android:scaleType="center" - android:tint="?android:attr/colorForeground" - android:background="?android:attr/selectableItemBackground" - /> - - </LinearLayout> + <ImageView + android:id="@+id/settings_button" + android:layout_width="@dimen/bubble_header_icon_size" + android:layout_height="@dimen/bubble_header_icon_size" + android:src="@drawable/ic_settings" + android:scaleType="center" + android:layout_gravity="end"/> <include layout="@layout/bubble_permission_view" android:id="@+id/permission_layout" diff --git a/packages/SystemUI/res/layout/keyboard_shortcut_app_item.xml b/packages/SystemUI/res/layout/keyboard_shortcut_app_item.xml index d49aff9abc01..3786812db827 100644 --- a/packages/SystemUI/res/layout/keyboard_shortcut_app_item.xml +++ b/packages/SystemUI/res/layout/keyboard_shortcut_app_item.xml @@ -39,7 +39,7 @@ android:layout_height="wrap_content" android:paddingEnd="12dp" android:paddingBottom="4dp" - android:textColor="@color/ksh_keyword_color" + android:textColor="?android:attr/textColorPrimary" android:textSize="16sp" android:maxLines="5" android:singleLine="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/colors.xml b/packages/SystemUI/res/values/colors.xml index b82c250e2bd2..290d75b4de9c 100644 --- a/packages/SystemUI/res/values/colors.xml +++ b/packages/SystemUI/res/values/colors.xml @@ -129,7 +129,6 @@ <!-- Keyboard shortcuts colors --> <color name="ksh_application_group_color">#fff44336</color> - <color name="ksh_keyword_color">#d9000000</color> <color name="ksh_key_item_color">@color/material_grey_600</color> <color name="ksh_key_item_background">@color/material_grey_100</color> diff --git a/packages/SystemUI/res/values/config_car.xml b/packages/SystemUI/res/values/config_car.xml deleted file mode 100644 index 2c549bc8ce2d..000000000000 --- a/packages/SystemUI/res/values/config_car.xml +++ /dev/null @@ -1,31 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -/* -** Copyright 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. -*/ ---> - -<resources> - <!-- These next two work together, if you enable this first one you need to provide an intent - uri that will be launched into the docked window. --> - <bool name="config_enablePersistentDockedActivity">false</bool> - <string name="config_persistentDockedActivityIntentUri" translatable="false"></string> - - <!-- configure which system ui bars should be displayed --> - <bool name="config_enableLeftNavigationBar">false</bool> - <bool name="config_enableRightNavigationBar">false</bool> - <bool name="config_enableBottomNavigationBar">true</bool> - <bool name="config_hideNavWhenKeyguardBouncerShown">true</bool> -</resources> diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index 039eca694e24..6eb279affc4f 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -23,8 +23,6 @@ <dimen name="navigation_bar_size">@*android:dimen/navigation_bar_height</dimen> <!-- Minimum swipe distance to catch the swipe gestures to invoke assist or switch tasks. --> <dimen name="navigation_bar_min_swipe_distance">48dp</dimen> - <!-- The default distance from a side of the device to start an edge swipe from --> - <dimen name="navigation_bar_default_edge_width">48dp</dimen> <dimen name="navigation_bar_default_edge_height">500dp</dimen> <!-- thickness (height) of the dead zone at the top of the navigation bar, @@ -341,6 +339,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> @@ -983,10 +983,6 @@ <!-- How much into a DisplayCutout's bounds we can go, on each side --> <dimen name="display_cutout_margin_consumption">0px</dimen> - <!-- How much we expand the touchable region of the status bar below the notch to catch touches - that just start below the notch. --> - <dimen name="display_cutout_touchable_region_size">12dp</dimen> - <!-- Padding below Ongoing App Ops dialog title --> <dimen name="ongoing_appops_dialog_sep">16dp</dimen> <!--Padding around text items in Ongoing App Ops dialog --> 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/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml index a6a6e6b6fea2..7c123eff2044 100644 --- a/packages/SystemUI/res/values/styles.xml +++ b/packages/SystemUI/res/values/styles.xml @@ -316,6 +316,7 @@ <style name="qs_theme" parent="@*android:style/Theme.DeviceDefault.QuickSettings"> <item name="lightIconTheme">@style/QSIconTheme</item> <item name="darkIconTheme">@style/QSIconTheme</item> + <item name="android:colorError">@*android:color/error_color_material_dark</item> <item name="android:windowIsFloating">true</item> </style> diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/QuickStepContract.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/QuickStepContract.java index 46f4c8689196..d0c17b7f6738 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/QuickStepContract.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/QuickStepContract.java @@ -112,4 +112,22 @@ public class QuickStepContract { return context.getResources().getInteger( com.android.internal.R.integer.config_navBarInteractionMode); } + + /** + * @return {@code true} if the navbar can be clicked through + */ + public static boolean isNavBarClickThrough(Context context) { + return context.getResources().getBoolean( + com.android.internal.R.bool.config_navBarTapThrough); + } + + /** + * @return the edge sensitivity width in px + */ + public static int getEdgeSensitivityWidth(Context context) { + return context.getResources().getDimensionPixelSize( + com.android.internal.R.dimen.config_backGestureInset); + } + + } 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..64e56f955058 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,7 @@ 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 java.util.function.Supplier; import javax.inject.Inject; import javax.inject.Singleton; @@ -64,14 +53,9 @@ import javax.inject.Singleton; public final class ClockManager { private static final String TAG = "ClockOptsProvider"; - private static final String DEFAULT_CLOCK_ID = "default"; - private final List<ClockInfo> mClockInfos = new ArrayList<>(); - /** - * Map from expected value stored in settings to supplier of custom clock face. - */ - private final Map<String, ClockPlugin> mClocks = new ArrayMap<>(); - @Nullable private ClockPlugin mCurrentClock; + private final AvailableClocks mPreviewClocks; + private final List<Supplier<ClockPlugin>> mBuiltinClocks = new ArrayList<>(); private final Context mContext; private final ContentResolver mContentResolver; @@ -90,21 +74,6 @@ public final class ClockManager { } }; - private final PluginListener<ClockPlugin> mClockPluginListener = - new PluginListener<ClockPlugin>() { - @Override - public void onPluginConnected(ClockPlugin plugin, Context pluginContext) { - addClockPlugin(plugin); - reload(); - } - - @Override - public void onPluginDisconnected(ClockPlugin plugin) { - removeClockPlugin(plugin); - reload(); - } - }; - private final PluginManager mPluginManager; /** @@ -120,15 +89,23 @@ public final class ClockManager { } }; @Nullable private DockManager mDockManager; + /** * When docked, the DOCKED_CLOCK_FACE setting will be checked for the custom clock face * to show. */ private boolean mIsDocked; - private final List<ClockChangedListener> mListeners = new ArrayList<>(); + /** + * Listeners for onClockChanged event. + * + * Each listener must receive a separate clock plugin instance. Otherwise, there could be + * problems like attempting to attach a view that already has a parent. To deal with this issue, + * each listener is associated with a collection of available clocks. When onClockChanged is + * fired the current clock plugin instance is retrieved from that listeners available clocks. + */ + private final Map<ClockChangedListener, AvailableClocks> mListeners = new ArrayMap<>(); - private final SysuiColorExtractor mColorExtractor; private final int mWidth; private final int mHeight; @@ -144,17 +121,18 @@ public final class ClockManager { ContentResolver contentResolver, SettingsWrapper settingsWrapper) { mContext = context; mPluginManager = pluginManager; - mColorExtractor = colorExtractor; mContentResolver = contentResolver; mSettingsWrapper = settingsWrapper; + mPreviewClocks = new AvailableClocks(); 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)); + addBuiltinClock(() -> new DefaultClockController(res, layoutInflater, colorExtractor)); + addBuiltinClock(() -> new BubbleClockController(res, layoutInflater, colorExtractor)); + addBuiltinClock(() -> new StretchAnalogClockController(res, layoutInflater, + colorExtractor)); + addBuiltinClock(() -> new TypeClockController(res, layoutInflater, colorExtractor)); // Store the size of the display for generation of clock preview. DisplayMetrics dm = res.getDisplayMetrics(); @@ -169,7 +147,12 @@ public final class ClockManager { if (mListeners.isEmpty()) { register(); } - mListeners.add(listener); + AvailableClocks availableClocks = new AvailableClocks(); + for (int i = 0; i < mBuiltinClocks.size(); i++) { + availableClocks.addClockPlugin(mBuiltinClocks.get(i).get()); + } + mListeners.put(listener, availableClocks); + mPluginManager.addPluginListener(availableClocks, ClockPlugin.class, true); reload(); } @@ -177,7 +160,8 @@ public final class ClockManager { * Remove listener added with {@link addOnClockChangedListener}. */ public void removeOnClockChangedListener(ClockChangedListener listener) { - mListeners.remove(listener); + AvailableClocks availableClocks = mListeners.remove(listener); + mPluginManager.removePluginListener(availableClocks); if (mListeners.isEmpty()) { unregister(); } @@ -187,16 +171,16 @@ public final class ClockManager { * Get information about available clock faces. */ List<ClockInfo> getClockInfos() { - return mClockInfos; + return mPreviewClocks.getInfo(); } /** * Get the current clock. - * @returns current custom clock or null for default. + * @return current custom clock or null for default. */ @Nullable ClockPlugin getCurrentClock() { - return mCurrentClock; + return mPreviewClocks.getCurrentClock(); } @VisibleForTesting @@ -209,114 +193,14 @@ public final class ClockManager { return mContentObserver; } - private void addClockPlugin(ClockPlugin plugin) { - final String id = plugin.getClass().getName(); - mClocks.put(plugin.getClass().getName(), plugin); - mClockInfos.add(ClockInfo.builder() - .setName(plugin.getName()) - .setTitle(plugin.getTitle()) - .setId(id) - .setThumbnail(() -> plugin.getThumbnail()) - .setPreview(() -> getClockPreview(id)) - .build()); - } - - private void removeClockPlugin(ClockPlugin plugin) { - final String id = plugin.getClass().getName(); - mClocks.remove(id); - for (int i = 0; i < mClockInfos.size(); i++) { - if (id.equals(mClockInfos.get(i).getId())) { - mClockInfos.remove(i); - break; - } - } - } - - /** - * 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 - // listeners. This should be fine for now since there is only a single listener. - mListeners.get(i).onClockChanged(plugin); - } + private void addBuiltinClock(Supplier<ClockPlugin> pluginSupplier) { + ClockPlugin plugin = pluginSupplier.get(); + mPreviewClocks.addClockPlugin(plugin); + mBuiltinClocks.add(pluginSupplier); } private void register() { - mPluginManager.addPluginListener(mClockPluginListener, ClockPlugin.class, true); + mPluginManager.addPluginListener(mPreviewClocks, ClockPlugin.class, true); mContentResolver.registerContentObserver( Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_CUSTOM_CLOCK_FACE), false, mContentObserver); @@ -332,7 +216,7 @@ public final class ClockManager { } private void unregister() { - mPluginManager.removePluginListener(mClockPluginListener); + mPluginManager.removePluginListener(mPreviewClocks); mContentResolver.unregisterContentObserver(mContentObserver); if (mDockManager != null) { mDockManager.removeListener(mDockEventListener); @@ -340,30 +224,16 @@ public final class ClockManager { } private void reload() { - mCurrentClock = getClockPlugin(); - if (mCurrentClock instanceof DefaultClockController) { - notifyClockChanged(null); - } else { - notifyClockChanged(mCurrentClock); - } - } - - private ClockPlugin getClockPlugin() { - ClockPlugin plugin = null; - if (mIsDocked) { - final String name = mSettingsWrapper.getDockedClockFace(); - if (name != null) { - plugin = mClocks.get(name); - if (plugin != null) { - return plugin; - } + mPreviewClocks.reload(); + mListeners.forEach((listener, clocks) -> { + clocks.reload(); + ClockPlugin clock = clocks.getCurrentClock(); + if (clock instanceof DefaultClockController) { + listener.onClockChanged(null); + } else { + listener.onClockChanged(clock); } - } - final String name = mSettingsWrapper.getLockScreenCustomClockFace(); - if (name != null) { - plugin = mClocks.get(name); - } - return plugin; + }); } /** @@ -377,4 +247,106 @@ public final class ClockManager { */ void onClockChanged(ClockPlugin clock); } + + /** + * Collection of available clocks. + */ + private final class AvailableClocks implements PluginListener<ClockPlugin> { + + /** + * Map from expected value stored in settings to plugin for custom clock face. + */ + private final Map<String, ClockPlugin> mClocks = new ArrayMap<>(); + + /** + * Metadata about available clocks, such as name and preview images. + */ + private final List<ClockInfo> mClockInfo = new ArrayList<>(); + + /** + * Active ClockPlugin. + */ + @Nullable private ClockPlugin mCurrentClock; + + @Override + public void onPluginConnected(ClockPlugin plugin, Context pluginContext) { + addClockPlugin(plugin); + reload(); + } + + @Override + public void onPluginDisconnected(ClockPlugin plugin) { + removeClockPlugin(plugin); + reload(); + } + + /** + * Get the current clock. + * @return current custom clock or null for default. + */ + @Nullable + ClockPlugin getCurrentClock() { + return mCurrentClock; + } + + /** + * Get information about available clock faces. + */ + List<ClockInfo> getInfo() { + return mClockInfo; + } + + /** + * Adds a clock plugin to the collection of available clocks. + * + * @param plugin The plugin to add. + */ + void addClockPlugin(ClockPlugin plugin) { + final String id = plugin.getClass().getName(); + mClocks.put(plugin.getClass().getName(), plugin); + mClockInfo.add(ClockInfo.builder() + .setName(plugin.getName()) + .setTitle(plugin.getTitle()) + .setId(id) + .setThumbnail(plugin::getThumbnail) + .setPreview(() -> plugin.getPreview(mWidth, mHeight)) + .build()); + } + + private void removeClockPlugin(ClockPlugin plugin) { + final String id = plugin.getClass().getName(); + mClocks.remove(id); + for (int i = 0; i < mClockInfo.size(); i++) { + if (id.equals(mClockInfo.get(i).getId())) { + mClockInfo.remove(i); + break; + } + } + } + + /** + * Update the current clock. + */ + void reload() { + mCurrentClock = getClockPlugin(); + } + + private ClockPlugin getClockPlugin() { + ClockPlugin plugin = null; + if (ClockManager.this.isDocked()) { + final String name = mSettingsWrapper.getDockedClockFace(); + if (name != null) { + plugin = mClocks.get(name); + if (plugin != null) { + return plugin; + } + } + } + final String name = mSettingsWrapper.getLockScreenCustomClockFace(); + if (name != null) { + plugin = mClocks.get(name); + } + return plugin; + } + } } 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/BubbleController.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java index e84c64838fd6..3aa9f73939ac 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java @@ -293,6 +293,17 @@ public class BubbleController implements BubbleExpandedView.OnBubbleBlockedListe } /** + * Request the stack expand if needed, then select the specified Bubble as current. + * + * @param notificationKey the notification key for the bubble to be selected + */ + public void expandStackAndSelectBubble(String notificationKey) { + if (mStackView != null && mBubbleData.getBubble(notificationKey) != null) { + mStackView.setExpandedBubble(notificationKey); + } + } + + /** * Tell the stack of bubbles to be dismissed, this will remove all of the bubbles in the stack. */ void dismissStack(@DismissReason int reason) { diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java index 559c9f6dd04b..6c2db76e19e1 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java @@ -38,8 +38,11 @@ import android.content.res.TypedArray; import android.graphics.Color; import android.graphics.Insets; import android.graphics.Point; +import android.graphics.drawable.AdaptiveIconDrawable; +import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.graphics.drawable.GradientDrawable; +import android.graphics.drawable.InsetDrawable; import android.graphics.drawable.ShapeDrawable; import android.os.RemoteException; import android.os.ServiceManager; @@ -53,7 +56,6 @@ import android.view.View; import android.view.ViewGroup; import android.view.WindowInsets; import android.widget.FrameLayout; -import android.widget.ImageButton; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; @@ -80,10 +82,7 @@ public class BubbleExpandedView extends LinearLayout implements View.OnClickList private View mPointerView; private int mPointerMargin; - // Header - private View mHeaderView; - private ImageButton mDeepLinkIcon; - private ImageButton mSettingsIcon; + private ImageView mSettingsIcon; // Permission view private View mPermissionView; @@ -195,7 +194,6 @@ public class BubbleExpandedView extends LinearLayout implements View.OnClickList mPointerView.setBackground(triangleDrawable); FrameLayout viewWrapper = findViewById(R.id.header_permission_wrapper); - viewWrapper.setBackground(createHeaderPermissionBackground(bgColor)); LayoutTransition transition = new LayoutTransition(); transition.setDuration(200); @@ -212,18 +210,16 @@ public class BubbleExpandedView extends LinearLayout implements View.OnClickList viewWrapper.setLayoutTransition(transition); viewWrapper.getLayoutTransition().enableTransitionType(LayoutTransition.CHANGING); - mHeaderHeight = getContext().getResources().getDimensionPixelSize( R.dimen.bubble_expanded_header_height); mPermissionHeight = getContext().getResources().getDimensionPixelSize( R.dimen.bubble_permission_height); - mHeaderView = findViewById(R.id.header_layout); - mDeepLinkIcon = findViewById(R.id.deep_link_button); + + mPermissionView = findViewById(R.id.permission_layout); mSettingsIcon = findViewById(R.id.settings_button); - mDeepLinkIcon.setOnClickListener(this); mSettingsIcon.setOnClickListener(this); + updateHeaderColor(); - mPermissionView = findViewById(R.id.permission_layout); findViewById(R.id.no_bubbles_button).setOnClickListener(this); findViewById(R.id.yes_bubbles_button).setOnClickListener(this); @@ -381,17 +377,31 @@ public class BubbleExpandedView extends LinearLayout implements View.OnClickList } /** - * Update bubble expanded view header when user toggles dark mode. + * Update header color and icon shape when theme changes. */ void updateHeaderColor() { - mHeaderView.setBackgroundColor(mContext.getColor(R.attr.colorAccent)); + TypedArray ta = mContext.obtainStyledAttributes( + new int[] {android.R.attr.colorBackgroundFloating, android.R.attr.colorForeground}); + int backgroundColor = ta.getColor(0, Color.WHITE /* default */); + int foregroundColor = ta.getColor(1, Color.BLACK /* default */); + ta.recycle(); + + mPermissionView.setBackground(createHeaderPermissionBackground(backgroundColor)); + + Drawable settingsIcon = mSettingsIcon.getDrawable(); + settingsIcon.setTint(foregroundColor); + + int mIconInset = getResources().getDimensionPixelSize(R.dimen.bubble_icon_inset); + InsetDrawable foreground = new InsetDrawable(settingsIcon, mIconInset); + ColorDrawable background = new ColorDrawable(backgroundColor); + AdaptiveIconDrawable adaptiveIcon = new AdaptiveIconDrawable(background, + foreground); + mSettingsIcon.setImageDrawable(adaptiveIcon); } private void updateHeaderView() { mSettingsIcon.setContentDescription(getResources().getString( R.string.bubbles_settings_button_description, mAppName)); - mDeepLinkIcon.setContentDescription(getResources().getString( - R.string.bubbles_deep_link_button_description, mAppName)); } private void updatePermissionView() { @@ -404,11 +414,9 @@ public class BubbleExpandedView extends LinearLayout implements View.OnClickList Log.w(TAG, e); } if (hasUserApprovedBubblesForPackage) { - mHeaderView.setVisibility(VISIBLE); - mPermissionView.setVisibility(GONE); + showSettingsIcon(); } else { - mHeaderView.setVisibility(GONE); - mPermissionView.setVisibility(VISIBLE); + showPermissionView(); ((ImageView) mPermissionView.findViewById(R.id.pkgicon)).setImageDrawable(mAppIcon); ((TextView) mPermissionView.findViewById(R.id.pkgname)).setText(mAppName); ((TextView) mPermissionView.findViewById(R.id.prompt)).setText( @@ -505,18 +513,7 @@ public class BubbleExpandedView extends LinearLayout implements View.OnClickList } Notification n = mEntry.notification.getNotification(); int id = view.getId(); - if (id == R.id.deep_link_button) { - mStackView.collapseStack(() -> { - try { - n.contentIntent.send(); - logBubbleClickEvent(mEntry, - StatsLog.BUBBLE_UICHANGED__ACTION__HEADER_GO_TO_APP); - } catch (PendingIntent.CanceledException e) { - Log.w(TAG, "Failed to send intent for bubble with key: " - + (mEntry != null ? mEntry.key : " null entry")); - } - }); - } else if (id == R.id.settings_button) { + if (id == R.id.settings_button) { Intent intent = getSettingsIntent(mEntry.notification.getPackageName(), mEntry.notification.getUid()); mStackView.collapseStack(() -> { @@ -538,8 +535,7 @@ public class BubbleExpandedView extends LinearLayout implements View.OnClickList mEntry.notification.getUid(), allowed); if (allowed) { - mPermissionView.setVisibility(GONE); - mHeaderView.setVisibility(VISIBLE); + showSettingsIcon(); } else if (mOnBubbleBlockedListener != null) { mOnBubbleBlockedListener.onBubbleBlocked(mEntry); } @@ -552,6 +548,17 @@ public class BubbleExpandedView extends LinearLayout implements View.OnClickList } } + void showSettingsIcon() { + mPermissionView.setVisibility(GONE); + mSettingsIcon.setVisibility(VISIBLE); + } + + void showPermissionView() { + mSettingsIcon.setVisibility(GONE); + mPermissionView.setVisibility(VISIBLE); + + } + /** * Update appearance of the expanded view being displayed. */ 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/bubbles/animation/PhysicsAnimationLayout.java b/packages/SystemUI/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayout.java index 8731b6b9767c..0f659c338ce8 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayout.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayout.java @@ -799,4 +799,9 @@ public class PhysicsAnimationLayout extends FrameLayout { } } } + + @Override + protected boolean canReceivePointerEvents() { + return false; + } } diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeDockHandler.java b/packages/SystemUI/src/com/android/systemui/doze/DozeDockHandler.java index a4592d554f0e..3c6dc7317357 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeDockHandler.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeDockHandler.java @@ -87,7 +87,8 @@ public class DozeDockHandler implements DozeMachine.Part { } private void requestPulseOutNow(State dozeState) { - if (dozeState == State.DOZE_REQUEST_PULSE || dozeState == State.DOZE_PULSING) { + if (dozeState == State.DOZE_REQUEST_PULSE || dozeState == State.DOZE_PULSING + || dozeState == State.DOZE_PULSING_BRIGHT) { final int pulseReason = mMachine.getPulseReason(); if (pulseReason == DozeLog.PULSE_REASON_DOCKING) { mDozeHost.stopPulsing(); diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java b/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java index 36e28dc0156d..060765495f48 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java @@ -71,7 +71,7 @@ public class DozeFactory { new DozeScreenState(wrappedService, handler, params, wakeLock), createDozeScreenBrightness(context, wrappedService, sensorManager, host, params, handler), - new DozeWallpaperState(context, machine), + new DozeWallpaperState(context), new DozeDockHandler(context, machine, host, config, handler, dockManager) }); diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java b/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java index bd7a421e9762..3c9d4a9704a0 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java @@ -33,7 +33,11 @@ public interface DozeHost { boolean isProvisioned(); boolean isBlockingDoze(); - void extendPulse(); + /** + * Makes a current pulse last for twice as long. + * @param reason why we're extending it. + */ + void extendPulse(int reason); void setAnimateWakeup(boolean animateWakeup); void setAnimateScreenOff(boolean animateScreenOff); diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java b/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java index c243899c6bc9..8bf2256a4f80 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java @@ -59,6 +59,8 @@ public class DozeMachine { DOZE_REQUEST_PULSE, /** Pulse is showing. Device is awake and showing UI. */ DOZE_PULSING, + /** Pulse is showing with bright wallpaper. Device is awake and showing UI. */ + DOZE_PULSING_BRIGHT, /** Pulse is done showing. Followed by transition to DOZE or DOZE_AOD. */ DOZE_PULSE_DONE, /** Doze is done. DozeService is finished. */ @@ -84,6 +86,7 @@ public class DozeMachine { switch (this) { case DOZE_REQUEST_PULSE: case DOZE_PULSING: + case DOZE_PULSING_BRIGHT: return true; default: return false; @@ -101,6 +104,7 @@ public class DozeMachine { case DOZE: return Display.STATE_OFF; case DOZE_PULSING: + case DOZE_PULSING_BRIGHT: return Display.STATE_ON; case DOZE_AOD: case DOZE_AOD_PAUSING: @@ -188,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; } @@ -202,6 +209,7 @@ public class DozeMachine { Assert.isMainThread(); Preconditions.checkState(mState == State.DOZE_REQUEST_PULSE || mState == State.DOZE_PULSING + || mState == State.DOZE_PULSING_BRIGHT || mState == State.DOZE_PULSE_DONE, "must be in pulsing state, but is " + mState); return mPulseReason; } @@ -283,7 +291,8 @@ public class DozeMachine { break; case DOZE_PULSE_DONE: Preconditions.checkState( - mState == State.DOZE_REQUEST_PULSE || mState == State.DOZE_PULSING); + mState == State.DOZE_REQUEST_PULSE || mState == State.DOZE_PULSING + || mState == State.DOZE_PULSING_BRIGHT); break; default: break; 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 7189a48fed1f..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) { @@ -168,7 +169,7 @@ public class DozeTriggers implements DozeMachine.Part { } else if (isPickup) { gentleWakeUp(pulseReason); } else { - mDozeHost.extendPulse(); + mDozeHost.extendPulse(pulseReason); } }, sensorPerformedProxCheck || (mDockManager != null && mDockManager.isDocked()), pulseReason); @@ -212,7 +213,8 @@ public class DozeTriggers implements DozeMachine.Part { final boolean pausing = (state == DozeMachine.State.DOZE_AOD_PAUSING); final boolean aod = (state == DozeMachine.State.DOZE_AOD); - if (state == DozeMachine.State.DOZE_PULSING) { + if (state == DozeMachine.State.DOZE_PULSING + || state == DozeMachine.State.DOZE_PULSING_BRIGHT) { boolean ignoreTouch = near; if (DEBUG) Log.i(TAG, "Prox changed, ignore touch = " + ignoreTouch); mDozeHost.onIgnoreTouchWhilePulsing(ignoreTouch); @@ -227,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) { @@ -244,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); } @@ -276,6 +284,7 @@ public class DozeTriggers implements DozeMachine.Part { mDozeSensors.setListening(false); break; case DOZE_PULSING: + case DOZE_PULSING_BRIGHT: mDozeSensors.setTouchscreenSensorsListening(false); mDozeSensors.setProxListening(true); break; @@ -306,7 +315,16 @@ public class DozeTriggers implements DozeMachine.Part { private void requestPulse(final int reason, boolean performedProxCheck) { Assert.isMainThread(); - mDozeHost.extendPulse(); + mDozeHost.extendPulse(reason); + + // When already pulsing we're allowed to show the wallpaper directly without + // requesting a new pulse. + if (mMachine.getState() == DozeMachine.State.DOZE_PULSING + && reason == DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN) { + mMachine.requestState(DozeMachine.State.DOZE_PULSING_BRIGHT); + return; + } + if (mPulsePending || !mAllowPulseTriggers || !canPulse()) { if (mAllowPulseTriggers) { DozeLog.tracePulseDropped(mContext, mPulsePending, mMachine.getState(), diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java index 847182d3ad35..51e96d2eecad 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java @@ -94,7 +94,10 @@ public class DozeUi implements DozeMachine.Part { @Override public void onPulseStarted() { try { - mMachine.requestState(DozeMachine.State.DOZE_PULSING); + mMachine.requestState( + reason == DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN + ? DozeMachine.State.DOZE_PULSING_BRIGHT + : DozeMachine.State.DOZE_PULSING); } catch (IllegalStateException e) { // It's possible that the pulse was asynchronously cancelled while // we were waiting for it to start (under stress conditions.) @@ -148,6 +151,7 @@ public class DozeUi implements DozeMachine.Part { switch (state) { case DOZE_REQUEST_PULSE: case DOZE_PULSING: + case DOZE_PULSING_BRIGHT: case DOZE_PULSE_DONE: mHost.setAnimateWakeup(true); break; diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeWallpaperState.java b/packages/SystemUI/src/com/android/systemui/doze/DozeWallpaperState.java index ca9f24fd236f..1b3cd881b949 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeWallpaperState.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeWallpaperState.java @@ -38,19 +38,17 @@ public class DozeWallpaperState implements DozeMachine.Part { private final IWallpaperManager mWallpaperManagerService; private final DozeParameters mDozeParameters; - private final DozeMachine mMachine; private boolean mIsAmbientMode; - public DozeWallpaperState(Context context, DozeMachine machine) { - this(machine, IWallpaperManager.Stub.asInterface( + public DozeWallpaperState(Context context) { + this(IWallpaperManager.Stub.asInterface( ServiceManager.getService(Context.WALLPAPER_SERVICE)), DozeParameters.getInstance(context)); } @VisibleForTesting - DozeWallpaperState(DozeMachine machine, IWallpaperManager wallpaperManagerService, + DozeWallpaperState(IWallpaperManager wallpaperManagerService, DozeParameters parameters) { - mMachine = machine; mWallpaperManagerService = wallpaperManagerService; mDozeParameters = parameters; } @@ -65,16 +63,13 @@ public class DozeWallpaperState implements DozeMachine.Part { case DOZE_AOD_PAUSED: case DOZE_REQUEST_PULSE: case DOZE_PULSE_DONE: - isAmbientMode = true; - break; case DOZE_PULSING: - isAmbientMode = - mMachine.getPulseReason() != DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN; + isAmbientMode = true; break; + case DOZE_PULSING_BRIGHT: default: isAmbientMode = false; } - final boolean animated; if (isAmbientMode) { animated = mDozeParameters.shouldControlScreenOff(); diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java index f07887ee6353..dcacd0fbc644 100644 --- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java +++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java @@ -439,6 +439,9 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, @Override public void onUiModeChanged() { mContext.getTheme().applyStyle(mContext.getThemeResId(), true); + if (mDialog.isShowing()) { + mDialog.refreshDialog(); + } } public void destroy() { @@ -1577,7 +1580,9 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, boolean panelEnabled = initializePanel(); if (!panelEnabled) { - mBackgroundDrawable = new GradientDrawable(mContext); + if (mBackgroundDrawable == null) { + mBackgroundDrawable = new GradientDrawable(mContext); + } mScrimAlpha = ScrimController.GRADIENT_SCRIM_ALPHA; } else { mBackgroundDrawable = mContext.getDrawable( @@ -1720,10 +1725,14 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, mKeyguardShowing = keyguardShowing; } + public void refreshDialog() { + initializeLayout(); + mGlobalActionsLayout.updateList(); + } + public void onRotate(int from, int to) { if (mShowing && isGridEnabled(mContext)) { - initializeLayout(); - mGlobalActionsLayout.updateList(); + refreshDialog(); } } } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java index b03b872b877f..6f50baa53e38 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java @@ -286,8 +286,9 @@ public class KeyguardSliceProvider extends SliceProvider implements RowBuilder dndBuilder = new RowBuilder(mDndUri) .setContentDescription(getContext().getResources() .getString(R.string.accessibility_quick_settings_dnd)) - .addEndItem(IconCompat.createWithResource(getContext(), R.drawable.stat_sys_dnd), - ListBuilder.ICON_IMAGE); + .addEndItem( + IconCompat.createWithResource(getContext(), R.drawable.stat_sys_dnd), + ListBuilder.ICON_IMAGE); builder.addRow(dndBuilder); } diff --git a/packages/SystemUI/src/com/android/systemui/power/BatteryStateSnapshot.kt b/packages/SystemUI/src/com/android/systemui/power/BatteryStateSnapshot.kt index d7a2d9acf3b5..02ad0f1766bd 100644 --- a/packages/SystemUI/src/com/android/systemui/power/BatteryStateSnapshot.kt +++ b/packages/SystemUI/src/com/android/systemui/power/BatteryStateSnapshot.kt @@ -17,7 +17,8 @@ data class BatteryStateSnapshot( val timeRemainingMillis: Long, val severeThresholdMillis: Long, val lowThresholdMillis: Long, - val isBasedOnUsage: Boolean + val isBasedOnUsage: Boolean, + val isLowWarningEnabled: Boolean ) { /** * Returns whether hybrid warning logic/copy should be used for this snapshot @@ -48,7 +49,8 @@ data class BatteryStateSnapshot( NO_ESTIMATE_AVAILABLE.toLong(), NO_ESTIMATE_AVAILABLE.toLong(), NO_ESTIMATE_AVAILABLE.toLong(), - false + false, + true ) { this.isHybrid = false } diff --git a/packages/SystemUI/src/com/android/systemui/power/EnhancedEstimates.java b/packages/SystemUI/src/com/android/systemui/power/EnhancedEstimates.java index bd130f4b40f3..a87922792616 100644 --- a/packages/SystemUI/src/com/android/systemui/power/EnhancedEstimates.java +++ b/packages/SystemUI/src/com/android/systemui/power/EnhancedEstimates.java @@ -23,4 +23,9 @@ public interface EnhancedEstimates { * show a severe warning to the user. */ long getSevereWarningThreshold(); + + /** + * Returns a boolean indicating if the low warning should be shown at all or not. + */ + boolean getLowWarningEnabled(); } diff --git a/packages/SystemUI/src/com/android/systemui/power/EnhancedEstimatesImpl.java b/packages/SystemUI/src/com/android/systemui/power/EnhancedEstimatesImpl.java index 3f2417638f1a..bfb809ecbf34 100644 --- a/packages/SystemUI/src/com/android/systemui/power/EnhancedEstimatesImpl.java +++ b/packages/SystemUI/src/com/android/systemui/power/EnhancedEstimatesImpl.java @@ -21,4 +21,9 @@ public class EnhancedEstimatesImpl implements EnhancedEstimates { public long getSevereWarningThreshold() { return 0; } + + @Override + public boolean getLowWarningEnabled() { + return true; + } } diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java index 18638606a251..4e41108f6496 100644 --- a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java +++ b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java @@ -284,7 +284,8 @@ public class PowerUI extends SystemUI { plugged, bucket, mBatteryStatus, mLowBatteryReminderLevels[1], mLowBatteryReminderLevels[0], estimate.getEstimateMillis(), mEnhancedEstimates.getSevereWarningThreshold(), - mEnhancedEstimates.getLowWarningThreshold(), estimate.isBasedOnUsage()); + mEnhancedEstimates.getLowWarningThreshold(), estimate.isBasedOnUsage(), + mEnhancedEstimates.getLowWarningEnabled()); } else { if (DEBUG) { Slog.d(TAG, "using standard"); @@ -351,7 +352,6 @@ public class PowerUI extends SystemUI { Slog.d(TAG, "Low warning marked as shown this cycle"); mLowWarningShownThisChargeCycle = true; } - } else if (shouldDismissHybridWarning(currentSnapshot)) { if (DEBUG) { Slog.d(TAG, "Dismissing warning"); @@ -375,8 +375,9 @@ public class PowerUI extends SystemUI { return false; } - // Only show the low warning once per charge cycle & no battery saver - final boolean canShowWarning = !mLowWarningShownThisChargeCycle && !snapshot.isPowerSaver() + // Only show the low warning if enabled once per charge cycle & no battery saver + final boolean canShowWarning = snapshot.isLowWarningEnabled() + && !mLowWarningShownThisChargeCycle && !snapshot.isPowerSaver() && (snapshot.getTimeRemainingMillis() < snapshot.getLowThresholdMillis() || snapshot.getBatteryLevel() <= snapshot.getLowLevelThreshold()); @@ -386,6 +387,7 @@ public class PowerUI extends SystemUI { || snapshot.getBatteryLevel() <= snapshot.getSevereLevelThreshold()); final boolean canShow = canShowWarning || canShowSevereWarning; + if (DEBUG) { Slog.d(TAG, "Enhanced trigger is: " + canShow + "\nwith battery snapshot:" + " mLowWarningShownThisChargeCycle: " + mLowWarningShownThisChargeCycle 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/PagedTileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java index 76dfddb78c80..bb159a9ba2e8 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java +++ b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java @@ -62,6 +62,7 @@ public class PagedTileLayout extends ViewPager implements QSTileLayout { private int mLayoutOrientation; private int mLayoutDirection; private int mHorizontalClipBound; + private final Rect mClippingRect; public PagedTileLayout(Context context, AttributeSet attrs) { super(context, attrs); @@ -71,6 +72,7 @@ public class PagedTileLayout extends ViewPager implements QSTileLayout { setCurrentItem(0, false); mLayoutOrientation = getResources().getConfiguration().orientation; mLayoutDirection = getLayoutDirection(); + mClippingRect = new Rect(); } public void saveInstanceState(Bundle outState) { @@ -280,8 +282,8 @@ public class PagedTileLayout extends ViewPager implements QSTileLayout { @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { super.onLayout(changed, l, t, r, b); - Rect clipBounds = new Rect(mHorizontalClipBound, 0, (r-l) - mHorizontalClipBound, b - t); - setClipBounds(clipBounds); + mClippingRect.set(mHorizontalClipBound, 0, (r - l) - mHorizontalClipBound, b - t); + setClipBounds(mClippingRect); } @Override 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 387de716844c..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,8 +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_signal_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 5b85498574a7..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; @@ -288,7 +289,7 @@ public class BluetoothTile extends QSTileImpl<BooleanState> { // This method returns Pair<Drawable, String> while first value is the drawable return BluetoothDeviceLayerDrawable.createLayerDrawable( context, - R.drawable.ic_qs_bluetooth_connected, + R.drawable.ic_bluetooth_connected, mBatteryLevel, mIconScale); } @@ -309,7 +310,7 @@ public class BluetoothTile extends QSTileImpl<BooleanState> { @Override public Drawable getDrawable(Context context) { // This method returns Pair<Drawable, String> - the first value is the drawable. - return context.getDrawable(R.drawable.ic_qs_bluetooth_connected); + return context.getDrawable(R.drawable.ic_bluetooth_connected); } } @@ -383,12 +384,12 @@ 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(); if (state == BluetoothProfile.STATE_CONNECTED) { - item.iconResId = R.drawable.ic_qs_bluetooth_connected; + item.iconResId = R.drawable.ic_bluetooth_connected; int batteryLevel = device.getBatteryLevel(); if (batteryLevel != BluetoothDevice.BATTERY_LEVEL_UNKNOWN) { item.icon = new BluetoothBatteryTileIcon(batteryLevel,1 /* iconScale */); diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java index bdebf79d823b..415870c590a3 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java @@ -202,8 +202,8 @@ public class CastTile extends QSTileImpl<BooleanState> { if (connecting && !state.value) { state.secondaryLabel = mContext.getString(R.string.quick_settings_connecting); } - state.icon = ResourceIcon.get(state.value ? R.drawable.ic_qs_cast_on - : R.drawable.ic_qs_cast_off); + state.icon = ResourceIcon.get(state.value ? R.drawable.ic_cast_connected + : R.drawable.ic_cast); if (mWifiConnected || state.value) { state.state = state.value ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE; if (!state.value) { @@ -334,7 +334,7 @@ public class CastTile extends QSTileImpl<BooleanState> { for (CastDevice device : devices) { if (device.state == CastDevice.STATE_CONNECTED) { final Item item = new Item(); - item.iconResId = R.drawable.ic_qs_cast_on; + item.iconResId = R.drawable.ic_cast_connected; item.line1 = getDeviceName(device); item.line2 = mContext.getString(R.string.quick_settings_connected); item.tag = device; @@ -354,7 +354,7 @@ public class CastTile extends QSTileImpl<BooleanState> { final CastDevice device = mVisibleOrder.get(id); if (!devices.contains(device)) continue; final Item item = new Item(); - item.iconResId = R.drawable.ic_qs_cast_off; + item.iconResId = R.drawable.ic_cast; item.line1 = getDeviceName(device); if (device.state == CastDevice.STATE_CONNECTING) { item.line2 = mContext.getString(R.string.quick_settings_connecting); 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/LocationTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java index a0f4e24d2f93..837ea9fc5f4e 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java @@ -37,7 +37,7 @@ import javax.inject.Inject; /** Quick settings tile: Location **/ public class LocationTile extends QSTileImpl<BooleanState> { - private final Icon mIcon = ResourceIcon.get(com.android.internal.R.drawable.ic_signal_location); + private final Icon mIcon = ResourceIcon.get(R.drawable.ic_location); private final LocationController mController; private final KeyguardMonitor mKeyguard; 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/recents/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java index 494e6cde5a1c..ead39c69730e 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java +++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java @@ -439,6 +439,9 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis mSupportsRoundedCornersOnWindows = ScreenDecorationsUtils .supportsRoundedCornersOnWindows(mContext.getResources()); + // Assumes device always starts with back button until launcher tells it that it does not + mBackButtonAlpha = 1.0f; + // Listen for the package update changes. if (mDeviceProvisionedController.getCurrentUser() == UserHandle.USER_SYSTEM) { updateEnabledState(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcuts.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcuts.java index 7f39e474f6c6..7e6ddcfea762 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcuts.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcuts.java @@ -128,7 +128,8 @@ public final class KeyboardShortcuts { private KeyCharacterMap mBackupKeyCharacterMap; private KeyboardShortcuts(Context context) { - this.mContext = new ContextThemeWrapper(context, android.R.style.Theme_DeviceDefault_Light); + this.mContext = new ContextThemeWrapper( + context, android.R.style.Theme_DeviceDefault_Settings); this.mPackageManager = AppGlobals.getPackageManager(); loadResources(context); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ScrimView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ScrimView.java index cb9060bc9574..cf6e64cef365 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/ScrimView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/ScrimView.java @@ -289,4 +289,9 @@ public class ScrimView extends View implements ConfigurationController.Configura } } } + + @Override + protected boolean canReceivePointerEvents() { + return false; + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationClicker.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationClicker.java index b788f537316b..fd2f72062be7 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationClicker.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationClicker.java @@ -78,8 +78,7 @@ public final class NotificationClicker implements View.OnClickListener { row.setJustClicked(true); DejankUtils.postAfterTraversal(() -> row.setJustClicked(false)); - // If it was a bubble we should close it - if (row.getEntry().isBubble()) { + if (!row.getEntry().isBubble()) { mBubbleController.collapseStack(); } @@ -95,7 +94,8 @@ public final class NotificationClicker implements View.OnClickListener { */ public void register(ExpandableNotificationRow row, StatusBarNotification sbn) { Notification notification = sbn.getNotification(); - if (notification.contentIntent != null || notification.fullScreenIntent != null) { + if (notification.contentIntent != null || notification.fullScreenIntent != null + || row.getEntry().isBubble()) { row.setOnClickListener(this); } else { row.setOnClickListener(null); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt index 3433fa8ffff0..1e506ad0ee94 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt @@ -163,6 +163,7 @@ class NotificationWakeUpCoordinator @Inject constructor( private fun handleAnimationFinished() { if (mLinearDozeAmount == 0.0f || mLinearVisibilityAmount == 0.0f) { mEntrySetToClearWhenFinished.forEach { it.setAmbientGoingAway(false) } + mEntrySetToClearWhenFinished.clear() } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationRowBinderImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationRowBinderImpl.java index b91cdaf9ae80..d3e5af8c729e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationRowBinderImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationRowBinderImpl.java @@ -220,8 +220,6 @@ public class NotificationRowBinderImpl implements NotificationRowBinder { StatusBarNotification sbn, ExpandableNotificationRow row) { row.setIsLowPriority(entry.ambient); - // bind the click event to the content area - checkNotNull(mNotificationClicker).register(row, sbn); // Extract target SDK version. try { @@ -257,6 +255,9 @@ public class NotificationRowBinderImpl implements NotificationRowBinder { row.setNeedsRedaction( Dependency.get(NotificationLockscreenUserManager.class).needsRedaction(entry)); row.inflateViews(); + + // bind the click event to the content area + checkNotNull(mNotificationClicker).register(row, sbn); } private void logNotificationExpansion(String key, boolean userAction, boolean expanded) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java index 9630727c8f3d..d287b92876b5 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java @@ -552,6 +552,9 @@ public class ExpandableNotificationRow extends ActivatableNotificationView mEntry.mIsSystemNotification = isSystemNotification(mContext, mStatusBarNotification); } + isNonblockable |= mEntry.channel.isImportanceLockedByOEM(); + isNonblockable |= mEntry.channel.isImportanceLockedByCriticalDeviceFunction(); + if (!isNonblockable && mEntry != null && mEntry.mIsSystemNotification != null) { if (mEntry.mIsSystemNotification) { if (mEntry.channel != null diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java index ce206816bf1d..bbb17c2f19ad 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java @@ -399,7 +399,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd private final ViewOutlineProvider mOutlineProvider = new ViewOutlineProvider() { @Override public void getOutline(View view, Outline outline) { - if (mAmbientState.isDarkAtAll() && !mAmbientState.isFullyDark() || !mShowDarkShelf) { + if (mAmbientState.isDarkAtAll() || !mShowDarkShelf) { outline.setRoundRect(mBackgroundAnimationRect, mCornerRadius); } else { ViewOutlineProvider.BACKGROUND.getOutline(view, outline); 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/BiometricUnlockController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java index ca452093eb20..2e85fea4615f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java @@ -414,7 +414,9 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback { return MODE_WAKE_AND_UNLOCK_FROM_DREAM; } if (mStatusBarKeyguardViewManager.isShowing()) { - if (mStatusBarKeyguardViewManager.isBouncerShowing() && unlockingAllowed) { + if ((mStatusBarKeyguardViewManager.isBouncerShowing() + || mStatusBarKeyguardViewManager.isBouncerPartiallyVisible()) + && unlockingAllowed) { return MODE_DISMISS_BOUNCER; } else if (unlockingAllowed) { return faceStayingOnKeyguard ? MODE_ONLY_WAKE : MODE_UNLOCK; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DarkIconDispatcherImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DarkIconDispatcherImpl.java index 08a10dc925e3..ac58e681dbbc 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DarkIconDispatcherImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DarkIconDispatcherImpl.java @@ -36,7 +36,8 @@ import javax.inject.Singleton; /** */ @Singleton -public class DarkIconDispatcherImpl implements SysuiDarkIconDispatcher { +public class DarkIconDispatcherImpl implements SysuiDarkIconDispatcher, + LightBarTransitionsController.DarkIntensityApplier { private final LightBarTransitionsController mTransitionsController; private final Rect mTintArea = new Rect(); @@ -54,8 +55,7 @@ public class DarkIconDispatcherImpl implements SysuiDarkIconDispatcher { mDarkModeIconColorSingleTone = context.getColor(R.color.dark_mode_icon_color_single_tone); mLightModeIconColorSingleTone = context.getColor(R.color.light_mode_icon_color_single_tone); - mTransitionsController = new LightBarTransitionsController(context, - this::setIconTintInternal); + mTransitionsController = new LightBarTransitionsController(context, this); } public LightBarTransitionsController getTransitionsController() { @@ -104,13 +104,19 @@ public class DarkIconDispatcherImpl implements SysuiDarkIconDispatcher { applyIconTint(); } - private void setIconTintInternal(float darkIntensity) { + @Override + public void applyDarkIntensity(float darkIntensity) { mDarkIntensity = darkIntensity; mIconTint = (int) ArgbEvaluator.getInstance().evaluate(darkIntensity, mLightModeIconColorSingleTone, mDarkModeIconColorSingleTone); applyIconTint(); } + @Override + public int getTintAnimationDuration() { + return LightBarTransitionsController.DEFAULT_TINT_ANIMATION_DURATION; + } + private void applyIconTint() { for (int i = 0; i < mReceivers.size(); i++) { mReceivers.valueAt(i).onDarkChanged(mTintArea, mDarkIntensity, mIconTint); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java index 236c72c5cc2c..0731a568ae7d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java @@ -108,16 +108,13 @@ public class DemoStatusIcons extends StatusIconContainer implements DemoMode, Da } String zen = args.getString("zen"); if (zen != null) { - int iconId = zen.equals("important") ? R.drawable.stat_sys_zen_important - : zen.equals("none") ? R.drawable.stat_sys_zen_none - : 0; + int iconId = zen.equals("dnd") ? R.drawable.stat_sys_dnd : 0; updateSlot("zen", null, iconId); } String bt = args.getString("bluetooth"); if (bt != null) { - int iconId = bt.equals("disconnected") ? R.drawable.stat_sys_data_bluetooth - : bt.equals("connected") ? R.drawable.stat_sys_data_bluetooth_connected - : 0; + int iconId = bt.equals("connected") + ? R.drawable.stat_sys_data_bluetooth_connected : 0; updateSlot("bluetooth", null, iconId); } String location = args.getString("location"); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java index 9844d8e5a67a..b7a154d67c10 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java @@ -140,7 +140,7 @@ public class HeadsUpManagerPhone extends HeadsUpManager implements Dumpable, mHeadsUpInset = mStatusBarHeight + resources.getDimensionPixelSize( R.dimen.heads_up_status_bar_padding); mDisplayCutoutTouchableRegionSize = resources.getDimensionPixelSize( - R.dimen.display_cutout_touchable_region_size); + com.android.internal.R.dimen.display_cutout_touchable_region_size); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java index 5afff814c111..1d2ca9f13c8e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java @@ -334,6 +334,11 @@ public class KeyguardBouncer { && mExpansion == EXPANSION_VISIBLE && !isAnimatingAway(); } + public boolean isPartiallyVisible() { + return (mShowingSoon || (mRoot != null && mRoot.getVisibility() == View.VISIBLE)) + && mExpansion != EXPANSION_HIDDEN && !isAnimatingAway(); + } + /** * @return {@code true} when bouncer's pre-hide animation already started but isn't completely * hidden yet, {@code false} otherwise. diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarTransitionsController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarTransitionsController.java index b622688a8ac6..d7097309ce20 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarTransitionsController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarTransitionsController.java @@ -16,9 +16,6 @@ package com.android.systemui.statusbar.phone; -import static com.android.systemui.statusbar.phone.NavBarTintController.DEFAULT_COLOR_ADAPT_TRANSITION_TIME; -import static com.android.systemui.statusbar.phone.NavBarTintController.MIN_COLOR_ADAPT_TRANSITION_TIME; - import android.animation.ValueAnimator; import android.content.Context; import android.os.Bundle; @@ -52,7 +49,6 @@ public class LightBarTransitionsController implements Dumpable, Callbacks, private final DarkIntensityApplier mApplier; private final KeyguardMonitor mKeyguardMonitor; private final StatusBarStateController mStatusBarStateController; - private NavBarTintController mColorAdaptionController; private boolean mTransitionDeferring; private long mTransitionDeferringStartTime; @@ -118,7 +114,8 @@ public class LightBarTransitionsController implements Dumpable, Callbacks, } if (mTransitionPending && mTintChangePending) { mTintChangePending = false; - animateIconTint(mPendingDarkIntensity, 0 /* delay */, getTintAnimationDuration()); + animateIconTint(mPendingDarkIntensity, 0 /* delay */, + mApplier.getTintAnimationDuration()); } mTransitionPending = false; } @@ -159,15 +156,8 @@ public class LightBarTransitionsController implements Dumpable, Callbacks, Math.max(0, mTransitionDeferringStartTime - SystemClock.uptimeMillis()), mTransitionDeferringDuration); } else { - animateIconTint(dark ? 1.0f : 0.0f, 0 /* delay */, getTintAnimationDuration()); - } - } - - public long getTintAnimationDuration() { - if (NavBarTintController.isEnabled(mContext)) { - return Math.max(DEFAULT_COLOR_ADAPT_TRANSITION_TIME, MIN_COLOR_ADAPT_TRANSITION_TIME); + animateIconTint(dark ? 1.0f : 0.0f, 0 /* delay */, mApplier.getTintAnimationDuration()); } - return DEFAULT_TINT_ANIMATION_DURATION; } public float getCurrentDarkIntensity() { @@ -243,5 +233,6 @@ public class LightBarTransitionsController implements Dumpable, Callbacks, */ public interface DarkIntensityApplier { void applyDarkIntensity(float darkIntensity); + int getTintAnimationDuration(); } } 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..8ff6cc9b3d93 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarTransitions.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarTransitions.java @@ -16,7 +16,11 @@ package com.android.systemui.statusbar.phone; +import static com.android.systemui.statusbar.phone.NavBarTintController.DEFAULT_COLOR_ADAPT_TRANSITION_TIME; +import static com.android.systemui.statusbar.phone.NavBarTintController.MIN_COLOR_ADAPT_TRANSITION_TIME; + import android.content.Context; +import android.graphics.Rect; import android.os.Handler; import android.os.RemoteException; import android.os.ServiceManager; @@ -30,7 +34,8 @@ import com.android.internal.statusbar.IStatusBarService; import com.android.systemui.Dependency; import com.android.systemui.R; -public final class NavigationBarTransitions extends BarTransitions { +public final class NavigationBarTransitions extends BarTransitions implements + LightBarTransitionsController.DarkIntensityApplier { private final NavigationBarView mView; private final IStatusBarService mBarService; @@ -58,8 +63,7 @@ public final class NavigationBarTransitions extends BarTransitions { mView = view; mBarService = IStatusBarService.Stub.asInterface( ServiceManager.getService(Context.STATUS_BAR_SERVICE)); - mLightTransitionsController = new LightBarTransitionsController(view.getContext(), - this::applyDarkIntensity); + mLightTransitionsController = new LightBarTransitionsController(view.getContext(), this); mAllowAutoDimWallpaperNotVisible = view.getContext().getResources() .getBoolean(R.bool.config_navigation_bar_enable_auto_dim_no_visible_wallpaper); @@ -105,6 +109,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 +127,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) { @@ -164,4 +173,12 @@ public final class NavigationBarTransitions extends BarTransitions { } mView.onDarkIntensityChange(darkIntensity); } + + @Override + public int getTintAnimationDuration() { + if (NavBarTintController.isEnabled(mView.getContext())) { + return Math.max(DEFAULT_COLOR_ADAPT_TRANSITION_TIME, MIN_COLOR_ADAPT_TRANSITION_TIME); + } + return LightBarTransitionsController.DEFAULT_TINT_ANIMATION_DURATION; + } } 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 bfbe886eed98..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(); } } @@ -1195,7 +1207,8 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav if (DEBUG) Log.d(TAG, String.format( "onMeasure: (%dx%d) old: (%dx%d)", w, h, getMeasuredWidth(), getMeasuredHeight())); - final boolean newVertical = w > 0 && h > w; + final boolean newVertical = w > 0 && h > w + && !QuickStepContract.isGesturalMode(getContext()); if (newVertical != mIsVertical) { mIsVertical = newVertical; if (DEBUG) { @@ -1205,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); } @@ -1231,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(); } } @@ -1416,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/src/com/android/systemui/statusbar/phone/NavigationPrototypeController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationPrototypeController.java index 7ea72c79501d..47a10547688b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationPrototypeController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationPrototypeController.java @@ -17,7 +17,9 @@ package com.android.systemui.statusbar.phone; import android.annotation.IntDef; +import android.content.ComponentCallbacks; import android.content.Context; +import android.content.res.Configuration; import android.content.res.Resources; import android.database.ContentObserver; import android.graphics.Point; @@ -25,6 +27,8 @@ import android.net.Uri; import android.os.Handler; import android.provider.Settings; +import com.android.systemui.shared.system.QuickStepContract; + import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -33,7 +37,7 @@ import java.lang.annotation.RetentionPolicy; * prototypes to run in the system. The class will handle communication changes from the settings * app and call back to listeners. */ -public class NavigationPrototypeController extends ContentObserver { +public class NavigationPrototypeController extends ContentObserver implements ComponentCallbacks { private static final String HIDE_BACK_BUTTON_SETTING = "quickstepcontroller_hideback"; private static final String HIDE_HOME_BUTTON_SETTING = "quickstepcontroller_hidehome"; private static final String PROTOTYPE_ENABLED = "prototype_enabled"; @@ -85,9 +89,9 @@ public class NavigationPrototypeController extends ContentObserver { registerObserver(HIDE_HOME_BUTTON_SETTING); registerObserver(GESTURE_MATCH_SETTING); registerObserver(NAV_COLOR_ADAPT_ENABLE_SETTING); - registerObserver(EDGE_SENSITIVITY_WIDTH_SETTING); registerObserver(SHOW_HOME_HANDLE_SETTING); registerObserver(ENABLE_ASSISTANT_GESTURE); + mContext.registerComponentCallbacks(this); } /** @@ -95,6 +99,7 @@ public class NavigationPrototypeController extends ContentObserver { */ public void unregister() { mContext.getContentResolver().unregisterContentObserver(this); + mContext.unregisterComponentCallbacks(this); } @Override @@ -115,9 +120,6 @@ public class NavigationPrototypeController extends ContentObserver { } else if (path.endsWith(NAV_COLOR_ADAPT_ENABLE_SETTING)) { mListener.onColorAdaptChanged( NavBarTintController.isEnabled(mContext)); - } else if (path.endsWith(EDGE_SENSITIVITY_WIDTH_SETTING)) { - mListener.onEdgeSensitivityChanged(getEdgeSensitivityWidth(), - getEdgeSensitivityHeight()); } else if (path.endsWith(SHOW_HOME_HANDLE_SETTING)) { mListener.onHomeHandleVisiblilityChanged(showHomeHandle()); } else if (path.endsWith(ENABLE_ASSISTANT_GESTURE)) { @@ -130,8 +132,7 @@ public class NavigationPrototypeController extends ContentObserver { * @return the width for edge swipe */ public int getEdgeSensitivityWidth() { - // TODO: Move into resource - return convertDpToPixel(getGlobalInt(EDGE_SENSITIVITY_WIDTH_SETTING, 48)); + return QuickStepContract.getEdgeSensitivityWidth(mContext); } /** @@ -203,6 +204,18 @@ public class NavigationPrototypeController extends ContentObserver { return (int) (dp * Resources.getSystem().getDisplayMetrics().density); } + @Override + public void onConfigurationChanged(Configuration newConfig) { + if (mListener != null) { + mListener.onEdgeSensitivityChanged(getEdgeSensitivityWidth(), + getEdgeSensitivityHeight()); + } + } + + @Override + public void onLowMemory() { + } + public interface OnPrototypeChangedListener { void onGestureRemap(@GestureAction int[] actions); void onBackButtonVisibilityChanged(boolean visible); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java index 02bad736723d..cff38550daf9 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java @@ -152,9 +152,11 @@ public class NotificationPanelView extends PanelView implements private KeyguardUserSwitcher mKeyguardUserSwitcher; @VisibleForTesting protected KeyguardStatusBarView mKeyguardStatusBar; - private ViewGroup mBigClockContainer; + @VisibleForTesting + protected ViewGroup mBigClockContainer; private QS mQs; - private FrameLayout mQsFrame; + @VisibleForTesting + protected FrameLayout mQsFrame; @VisibleForTesting protected KeyguardStatusView mKeyguardStatusView; private View mQsNavbarScrim; @@ -266,6 +268,7 @@ public class NotificationPanelView extends PanelView implements private int mIndicationBottomPadding; private int mAmbientIndicationBottomPadding; private boolean mIsFullWidth; + private boolean mBlockingExpansionForCurrentTouch; /** * Current dark amount that follows regular interpolation curve of animation. @@ -983,6 +986,11 @@ public class NotificationPanelView extends PanelView implements return false; } initDownStates(event); + // Make sure the next touch won't the blocked after the current ends. + if (event.getAction() == MotionEvent.ACTION_UP + || event.getAction() == MotionEvent.ACTION_CANCEL) { + mBlockingExpansionForCurrentTouch = false; + } if (!mIsExpanding && mPulseExpansionHandler.onTouchEvent(event)) { // We're expanding all the other ones shouldn't get this anymore return true; @@ -1662,7 +1670,7 @@ public class NotificationPanelView extends PanelView implements if (!mQsExpansionEnabled || mCollapsedOnDown) { return false; } - View header = mKeyguardShowing ? mKeyguardStatusBar : mQs.getHeader(); + View header = mKeyguardShowing || mQs == null ? mKeyguardStatusBar : mQs.getHeader(); final boolean onHeader = x >= mQsFrame.getX() && x <= mQsFrame.getX() + mQsFrame.getWidth() && y >= header.getTop() && y <= header.getBottom(); @@ -2337,7 +2345,7 @@ public class NotificationPanelView extends PanelView implements @Override protected boolean isTrackingBlocked() { - return mConflictingQsExpansionGesture && mQsExpanded; + return mConflictingQsExpansionGesture && mQsExpanded || mBlockingExpansionForCurrentTouch; } public boolean isQsExpanded() { @@ -2937,6 +2945,14 @@ public class NotificationPanelView extends PanelView implements updateLockIcon(); } + /** + * Do not let the user drag the shade up and down for the current touch session. + * This is necessary to avoid shade expansion while/after the bouncer is dismissed. + */ + public void blockExpansionForCurrentTouch() { + mBlockingExpansionForCurrentTouch = mTracking; + } + @Override public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { super.dump(fd, pw, args); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java index b7a78738828e..183fdb46a795 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java @@ -201,7 +201,7 @@ public class PhoneStatusBarPolicy mIconController.setIconVisibility(mSlotAlarmClock, false); // zen - mIconController.setIcon(mSlotZen, R.drawable.stat_sys_zen_important, null); + mIconController.setIcon(mSlotZen, R.drawable.stat_sys_dnd, null); mIconController.setIconVisibility(mSlotZen, false); // volume @@ -339,11 +339,11 @@ public class PhoneStatusBarPolicy zenDescription = mContext.getString(R.string.quick_settings_dnd_label); } else if (zen == Global.ZEN_MODE_NO_INTERRUPTIONS) { zenVisible = true; - zenIconId = R.drawable.stat_sys_zen_none; + zenIconId = R.drawable.stat_sys_dnd; zenDescription = mContext.getString(R.string.interruption_level_none); } else if (zen == Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS) { zenVisible = true; - zenIconId = R.drawable.stat_sys_zen_important; + zenIconId = R.drawable.stat_sys_dnd; zenDescription = mContext.getString(R.string.interruption_level_priority); } @@ -388,13 +388,12 @@ public class PhoneStatusBarPolicy } private final void updateBluetooth() { - int iconId = R.drawable.stat_sys_data_bluetooth; + int iconId = R.drawable.stat_sys_data_bluetooth_connected; String contentDescription = mContext.getString(R.string.accessibility_quick_settings_bluetooth_on); boolean bluetoothVisible = false; if (mBluetooth != null) { if (mBluetooth.isBluetoothConnected()) { - iconId = R.drawable.stat_sys_data_bluetooth_connected; contentDescription = mContext.getString(R.string.accessibility_bluetooth_connected); bluetoothVisible = mBluetooth.isBluetoothEnabled(); } @@ -582,8 +581,8 @@ public class PhoneStatusBarPolicy String contentDescription = mContext.getString(hasMic ? R.string.accessibility_status_bar_headset : R.string.accessibility_status_bar_headphones); - mIconController.setIcon(mSlotHeadset, hasMic ? R.drawable.ic_headset_mic - : R.drawable.ic_headset, contentDescription); + mIconController.setIcon(mSlotHeadset, hasMic ? R.drawable.stat_sys_headset_mic + : R.drawable.stat_sys_headset, contentDescription); mIconController.setIconVisibility(mSlotHeadset, true); } else { mIconController.setIconVisibility(mSlotHeadset, false); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java index 25cb7d0573da..8053ec7e5838 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java @@ -29,7 +29,6 @@ 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.statusbar.phone.NavigationBarView.WINDOW_TARGET_BOTTOM; -import static com.android.systemui.statusbar.phone.NavigationPrototypeController.EDGE_SENSITIVITY_WIDTH_SETTING; import android.annotation.Nullable; import android.content.Context; @@ -264,10 +263,7 @@ public class QuickStepController implements GestureHelper { mNavigationBarView.transformMatrixToLocal(mTransformLocalMatrix); mAllowGestureDetection = true; mNotificationsVisibleOnDown = !mNavigationBarView.isNotificationsFullyCollapsed(); - final int defaultRegionThreshold = mContext.getResources() - .getDimensionPixelOffset(R.dimen.navigation_bar_default_edge_width); - mGestureRegionThreshold = convertDpToPixel(getIntGlobalSetting(mContext, - EDGE_SENSITIVITY_WIDTH_SETTING, defaultRegionThreshold)); + mGestureRegionThreshold = QuickStepContract.getEdgeSensitivityWidth(mContext); break; } case MotionEvent.ACTION_MOVE: { @@ -357,7 +353,7 @@ public class QuickStepController implements GestureHelper { if (mCurrentAction != null) { mCurrentAction.endGesture(); } - } else if (QuickStepContract.isGesturalMode(mContext) + } else if (QuickStepContract.isNavBarClickThrough(mContext) && !mClickThroughPressed) { // Enable click through functionality where no gesture has been detected and // not passed the drag slop so inject a touch event at the same location diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java index 1949badf0513..0d2fe13b9a09 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java @@ -92,7 +92,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, OnCo /** * Scrim opacity when the phone is about to wake-up. */ - public static final float AOD2_SCRIM_ALPHA = 0.6f; + public static final float WAKE_SENSOR_SCRIM_ALPHA = 0.6f; /** * A scrim varies its opacity based on a busyness factor, for example * how many notifications are currently visible. @@ -458,6 +458,23 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, OnCo mState.AOD.setAodFrontScrimAlpha(alpha); } + /** + * If the lock screen sensor is active. + */ + public void setWakeLockScreenSensorActive(boolean active) { + for (ScrimState state : ScrimState.values()) { + state.setWakeLockScreenSensorActive(active); + } + + if (mState == ScrimState.PULSING) { + float newBehindAlpha = mState.getBehindAlpha(); + if (mCurrentBehindAlpha != newBehindAlpha) { + mCurrentBehindAlpha = newBehindAlpha; + updateScrims(); + } + } + } + protected void scheduleUpdate() { if (mUpdatePending) return; @@ -904,10 +921,6 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, OnCo } } - public void setPulseReason(int pulseReason) { - ScrimState.PULSING.setPulseReason(pulseReason); - } - public interface Callback { default void onStart() { } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java index 2f161d5cd192..d152ecd8b930 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java @@ -19,7 +19,6 @@ package com.android.systemui.statusbar.phone; import android.graphics.Color; import android.os.Trace; -import com.android.systemui.doze.DozeLog; import com.android.systemui.statusbar.ScrimView; import com.android.systemui.statusbar.notification.stack.StackStateAnimator; @@ -129,16 +128,15 @@ public enum ScrimState { @Override public void prepare(ScrimState previousState) { mCurrentInFrontAlpha = 0f; - if (mPulseReason == DozeLog.PULSE_REASON_NOTIFICATION - || mPulseReason == DozeLog.PULSE_REASON_DOCKING - || mPulseReason == DozeLog.PULSE_REASON_INTENT) { - mCurrentBehindAlpha = previousState.getBehindAlpha(); - } else { - mCurrentBehindAlpha = ScrimController.AOD2_SCRIM_ALPHA; - } mCurrentBehindTint = Color.BLACK; mBlankScreen = mDisplayRequiresBlanking; } + + @Override + public float getBehindAlpha() { + return mWakeLockScreenSensorActive ? ScrimController.WAKE_SENSOR_SCRIM_ALPHA + : AOD.getBehindAlpha(); + } }, /** @@ -199,7 +197,7 @@ public enum ScrimState { int mIndex; boolean mHasBackdrop; boolean mLaunchingAffordanceWithPreview; - int mPulseReason; + boolean mWakeLockScreenSensorActive; ScrimState(int index) { mIndex = index; @@ -264,10 +262,6 @@ public enum ScrimState { mAodFrontScrimAlpha = aodFrontScrimAlpha; } - public void setPulseReason(int pulseReason) { - mPulseReason = pulseReason; - } - public void setScrimBehindAlphaKeyguard(float scrimBehindAlphaKeyguard) { mScrimBehindAlphaKeyguard = scrimBehindAlphaKeyguard; } @@ -287,4 +281,8 @@ public enum ScrimState { public void setHasBackdrop(boolean hasBackdrop) { mHasBackdrop = hasBackdrop; } + + public void setWakeLockScreenSensorActive(boolean active) { + mWakeLockScreenSensorActive = active; + } }
\ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java index 5d52359480e6..ed66b4b86748 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java @@ -25,6 +25,7 @@ import static android.app.StatusBarManager.WindowVisibleState; import static android.app.StatusBarManager.windowStateToString; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY; +import static com.android.systemui.Dependency.BG_HANDLER; import static com.android.systemui.Dependency.MAIN_HANDLER; import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_ASLEEP; import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_AWAKE; @@ -434,6 +435,9 @@ public class StatusBar extends SystemUI implements DemoMode, public void onUserSetupChanged() { final boolean userSetup = mDeviceProvisionedController.isUserSetup( mDeviceProvisionedController.getCurrentUser()); + // STOPSHIP(kozynski, b/129405675) Remove log + Log.d(TAG, "mUserSetupObserver - DeviceProvisionedListener called for user " + + mDeviceProvisionedController.getCurrentUser()); if (MULTIUSER_DEBUG) { Log.d(TAG, String.format("User setup changed: userSetup=%s mUserSetup=%s", userSetup, mUserSetup)); @@ -1073,7 +1077,7 @@ public class StatusBar extends SystemUI implements DemoMode, mLockscreenUserManager, shadeController, mKeyguardMonitor, mNotificationInterruptionStateProvider, mMetricsLogger, new LockPatternUtils(mContext), Dependency.get(MAIN_HANDLER), - mActivityIntentHelper); + Dependency.get(BG_HANDLER), mActivityIntentHelper, mBubbleController); mGutsManager.setNotificationActivityStarter(mNotificationActivityStarter); @@ -1297,13 +1301,16 @@ public class StatusBar extends SystemUI implements DemoMode, * the user intends to use the lock screen user switcher, QS in not needed. */ private void updateQsExpansionEnabled() { - mNotificationPanel.setQsExpansionEnabled(mDeviceProvisionedController.isDeviceProvisioned() + final boolean expandEnabled = mDeviceProvisionedController.isDeviceProvisioned() && (mUserSetup || mUserSwitcherController == null || !mUserSwitcherController.isSimpleUserSwitcher()) && ((mDisabled2 & StatusBarManager.DISABLE2_NOTIFICATION_SHADE) == 0) && ((mDisabled2 & StatusBarManager.DISABLE2_QUICK_SETTINGS) == 0) && !mDozing - && !ONLY_CORE_APPS); + && !ONLY_CORE_APPS; + mNotificationPanel.setQsExpansionEnabled(expandEnabled); + // STOPSHIP(kozynski, b/129405675) Remove log + Log.d(TAG, "updateQsExpansionEnabled - QS Expand enabled: " + expandEnabled); } public void addQsTile(ComponentName tile) { @@ -3575,6 +3582,9 @@ public class StatusBar extends SystemUI implements DemoMode, updateHideIconsForBouncer(true /* animate */); mCommandQueue.recomputeDisableFlags(mDisplayId, true /* animate */); updateScrimController(); + if (!mBouncerShowing) { + updatePanelExpansionForKeyguard(); + } } /** @@ -3902,7 +3912,6 @@ public class StatusBar extends SystemUI implements DemoMode, @Override public void pulseWhileDozing(@NonNull PulseCallback callback, int reason) { - mScrimController.setPulseReason(reason); if (reason == DozeLog.PULSE_REASON_SENSOR_LONG_PRESS) { mPowerManager.wakeUp(SystemClock.uptimeMillis(), PowerManager.WAKE_REASON_GESTURE, "com.android.systemui:LONG_PRESS"); @@ -3910,6 +3919,10 @@ public class StatusBar extends SystemUI implements DemoMode, return; } + if (reason == DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN) { + mScrimController.setWakeLockScreenSensorActive(true); + } + boolean passiveAuthInterrupt = reason == DozeLog.PULSE_REASON_NOTIFICATION; // Set the state to pulsing, so ScrimController will know what to do once we ask it to // execute the transition. The pulse callback will then be invoked when the scrims @@ -3928,6 +3941,7 @@ public class StatusBar extends SystemUI implements DemoMode, mPulsing = false; callback.onPulseFinished(); updateNotificationPanelTouchState(); + mScrimController.setWakeLockScreenSensorActive(false); setPulsing(false); } @@ -4004,7 +4018,10 @@ public class StatusBar extends SystemUI implements DemoMode, } @Override - public void extendPulse() { + public void extendPulse(int reason) { + if (reason == DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN) { + mScrimController.setWakeLockScreenSensorActive(true); + } if (mDozeScrimController.isPulsing() && mAmbientPulseManager.hasNotifications()) { mAmbientPulseManager.extendPulse(); } else { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java index cbaabf719985..92cd28009386 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java @@ -419,6 +419,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb } else if (finishRunnable != null) { finishRunnable.run(); } + mNotificationPanelView.blockExpansionForCurrentTouch(); } /** @@ -572,6 +573,10 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb return mBouncer.isShowing(); } + public boolean isBouncerPartiallyVisible() { + return mBouncer.isPartiallyVisible(); + } + public boolean isFullscreenBouncer() { return mBouncer.isFullscreenBouncer(); } @@ -760,9 +765,10 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb } public boolean bouncerNeedsScrimming() { - return mOccluded || mBouncer.willDismissWithAction() || mBouncer.needsFullscreenBouncer() + return mOccluded || mBouncer.willDismissWithAction() || mStatusBar.isFullScreenUserSwitcherState() - || (mBouncer.isShowing() && mBouncer.isScrimmed()); + || (mBouncer.isShowing() && mBouncer.isScrimmed()) + || mBouncer.isFullscreenBouncer(); } public void dump(PrintWriter pw) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java index 215f5c4dfc5b..e4af15cf7dd1 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java @@ -48,6 +48,7 @@ import com.android.systemui.Dependency; import com.android.systemui.EventLogTags; import com.android.systemui.UiOffloadThread; import com.android.systemui.assist.AssistManager; +import com.android.systemui.bubbles.BubbleController; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.CommandQueue; @@ -98,7 +99,9 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit private final CommandQueue mCommandQueue; private final IDreamManager mDreamManager; private final Handler mMainThreadHandler; + private final Handler mBackgroundHandler; private final ActivityIntentHelper mActivityIntentHelper; + private final BubbleController mBubbleController; private boolean mIsCollapsingToShowActivityOverLockscreen; @@ -125,7 +128,9 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit MetricsLogger metricsLogger, LockPatternUtils lockPatternUtils, Handler mainThreadHandler, - ActivityIntentHelper activityIntentHelper) { + Handler backgroundHandler, + ActivityIntentHelper activityIntentHelper, + BubbleController bubbleController) { mContext = context; mNotificationPanel = panel; mPresenter = presenter; @@ -147,6 +152,7 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit mAssistManager = assistManager; mGroupManager = groupManager; mLockPatternUtils = lockPatternUtils; + mBackgroundHandler = backgroundHandler; mEntryManager.addNotificationEntryListener(new NotificationEntryListener() { @Override public void onPendingEntryAdded(NotificationEntry entry) { @@ -156,6 +162,7 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit mStatusBarRemoteInputCallback = remoteInputCallback; mMainThreadHandler = mainThreadHandler; mActivityIntentHelper = activityIntentHelper; + mBubbleController = bubbleController; } /** @@ -178,14 +185,24 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit final PendingIntent intent = notification.contentIntent != null ? notification.contentIntent : notification.fullScreenIntent; + final boolean isBubble = row.getEntry().isBubble(); + + // This code path is now executed for notification without a contentIntent. + // The only valid case is Bubble notifications. Guard against other cases + // entering here. + if (intent == null && !isBubble) { + Log.e(TAG, "onNotificationClicked called for non-clickable notification!"); + return; + } + final String notificationKey = sbn.getKey(); - boolean isActivityIntent = intent.isActivity(); + boolean isActivityIntent = intent != null && intent.isActivity() && !isBubble; final boolean afterKeyguardGone = isActivityIntent && mActivityIntentHelper.wouldLaunchResolverActivity(intent.getIntent(), mLockscreenUserManager.getCurrentUserId()); final boolean wasOccluded = mShadeController.isOccluded(); - boolean showOverLockscreen = mKeyguardMonitor.isShowing() + boolean showOverLockscreen = mKeyguardMonitor.isShowing() && intent != null && mActivityIntentHelper.wouldShowOverLockscreen(intent.getIntent(), mLockscreenUserManager.getCurrentUserId()); ActivityStarter.OnDismissAction postKeyguardAction = @@ -244,9 +261,8 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit mShadeController.addAfterKeyguardGoneRunnable(runnable); mShadeController.collapsePanel(); } else { - new Thread(runnable).start(); + mBackgroundHandler.postAtFrontOfQueue(runnable); } - return !mNotificationPanel.isFullyCollapsed(); } @@ -287,6 +303,7 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit } Intent fillInIntent = null; NotificationEntry entry = row.getEntry(); + final boolean isBubble = entry.isBubble(); CharSequence remoteInputText = null; if (!TextUtils.isEmpty(entry.remoteInputText)) { remoteInputText = entry.remoteInputText; @@ -295,8 +312,12 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit fillInIntent = new Intent().putExtra(Notification.EXTRA_REMOTE_INPUT_DRAFT, remoteInputText.toString()); } - startNotificationIntent(intent, fillInIntent, row, wasOccluded, isActivityIntent); - if (isActivityIntent) { + if (isBubble) { + expandBubbleStackOnMainThread(notificationKey); + } else { + startNotificationIntent(intent, fillInIntent, row, wasOccluded, isActivityIntent); + } + if (isActivityIntent || isBubble) { mAssistManager.hideAssist(); } if (shouldCollapse()) { @@ -316,18 +337,29 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit } catch (RemoteException ex) { // system process is dead if we're here. } - if (parentToCancelFinal != null) { - removeNotification(parentToCancelFinal); - } - if (shouldAutoCancel(sbn) - || mRemoteInputManager.isNotificationKeptForRemoteInputHistory( - notificationKey)) { - // Automatically remove all notifications that we may have kept around longer - removeNotification(sbn); + if (!isBubble) { + if (parentToCancelFinal != null) { + removeNotification(parentToCancelFinal); + } + if (shouldAutoCancel(sbn) + || mRemoteInputManager.isNotificationKeptForRemoteInputHistory( + notificationKey)) { + // Automatically remove all notifications that we may have kept around longer + removeNotification(sbn); + } } mIsCollapsingToShowActivityOverLockscreen = false; } + private void expandBubbleStackOnMainThread(String notificationKey) { + if (Looper.getMainLooper().isCurrentThread()) { + mBubbleController.expandStackAndSelectBubble(notificationKey); + } else { + mMainThreadHandler.post( + () -> mBubbleController.expandStackAndSelectBubble(notificationKey)); + } + } + private void startNotificationIntent(PendingIntent intent, Intent fillInIntent, ExpandableNotificationRow row, boolean wasOccluded, boolean isActivityIntent) { RemoteAnimationAdapter adapter = mActivityLaunchAnimator.getLaunchAnimation(row, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceProvisionedControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceProvisionedControllerImpl.java index f5e745f650a9..db2523e40ded 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceProvisionedControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceProvisionedControllerImpl.java @@ -21,9 +21,10 @@ import android.content.ContentResolver; import android.content.Context; import android.database.ContentObserver; import android.net.Uri; +import android.os.Handler; import android.provider.Settings.Global; import android.provider.Settings.Secure; -import android.os.Handler; +import android.util.Log; import com.android.systemui.settings.CurrentUserTracker; @@ -39,6 +40,7 @@ import javax.inject.Singleton; public class DeviceProvisionedControllerImpl extends CurrentUserTracker implements DeviceProvisionedController { + private static final String TAG = DeviceProvisionedControllerImpl.class.getSimpleName(); private final ArrayList<DeviceProvisionedListener> mListeners = new ArrayList<>(); private final ContentResolver mContentResolver; private final Context mContext; @@ -59,6 +61,8 @@ public class DeviceProvisionedControllerImpl extends CurrentUserTracker implemen mSettingsObserver = new ContentObserver(mainHandler) { @Override public void onChange(boolean selfChange, Uri uri, int userId) { + // STOPSHIP(kozynski, b/129405675) Remove log + Log.d(TAG, "Setting change: " + uri); if (mUserSetupUri.equals(uri)) { notifySetupChanged(); } else { diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java index e5f709a995e5..35a245000628 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java +++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java @@ -288,7 +288,7 @@ public class VolumeDialogImpl implements VolumeDialog, addRow(AudioManager.STREAM_RING, R.drawable.ic_volume_ringer, R.drawable.ic_volume_ringer_mute, true, false); addRow(STREAM_ALARM, - R.drawable.ic_volume_alarm, R.drawable.ic_volume_alarm_mute, true, false); + R.drawable.ic_alarm, R.drawable.ic_volume_alarm_mute, true, false); addRow(AudioManager.STREAM_VOICE_CALL, com.android.internal.R.drawable.ic_phone, com.android.internal.R.drawable.ic_phone, false, false); 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/ClockManagerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/clock/ClockManagerTest.java index 46b1833c2d6c..f2ad958c57ab 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/clock/ClockManagerTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/clock/ClockManagerTest.java @@ -18,6 +18,8 @@ package com.android.keyguard.clock; import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.reset; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.content.ContentResolver; @@ -31,6 +33,7 @@ import com.android.systemui.SysuiTestCase; import com.android.systemui.colorextraction.SysuiColorExtractor; import com.android.systemui.dock.DockManager; import com.android.systemui.dock.DockManagerFake; +import com.android.systemui.plugins.ClockPlugin; import com.android.systemui.shared.plugins.PluginManager; import com.android.systemui.util.InjectionInflationController; @@ -38,6 +41,7 @@ import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; @@ -57,7 +61,8 @@ public final class ClockManagerTest extends SysuiTestCase { @Mock SysuiColorExtractor mMockColorExtractor; @Mock ContentResolver mMockContentResolver; @Mock SettingsWrapper mMockSettingsWrapper; - @Mock ClockManager.ClockChangedListener mMockListener; + @Mock ClockManager.ClockChangedListener mMockListener1; + @Mock ClockManager.ClockChangedListener mMockListener2; @Before public void setUp() { @@ -73,13 +78,17 @@ public final class ClockManagerTest extends SysuiTestCase { mMockPluginManager, mMockColorExtractor, mMockContentResolver, mMockSettingsWrapper); - mClockManager.addOnClockChangedListener(mMockListener); + mClockManager.addOnClockChangedListener(mMockListener1); + mClockManager.addOnClockChangedListener(mMockListener2); + reset(mMockListener1, mMockListener2); + mContentObserver = mClockManager.getContentObserver(); } @After public void tearDown() { - mClockManager.removeOnClockChangedListener(mMockListener); + mClockManager.removeOnClockChangedListener(mMockListener1); + mClockManager.removeOnClockChangedListener(mMockListener2); } @Test @@ -116,6 +125,34 @@ public final class ClockManagerTest extends SysuiTestCase { } @Test + public void onClockChanged_customClock() { + // GIVEN that settings is set to the bubble clock face + when(mMockSettingsWrapper.getLockScreenCustomClockFace()).thenReturn(BUBBLE_CLOCK); + // WHEN settings change event is fired + mContentObserver.onChange(false); + // THEN the plugin is the bubble clock face. + ArgumentCaptor<ClockPlugin> captor = ArgumentCaptor.forClass(ClockPlugin.class); + verify(mMockListener1).onClockChanged(captor.capture()); + assertThat(captor.getValue()).isInstanceOf(BUBBLE_CLOCK_CLASS); + } + + @Test + public void onClockChanged_uniqueInstances() { + // GIVEN that settings is set to the bubble clock face + when(mMockSettingsWrapper.getLockScreenCustomClockFace()).thenReturn(BUBBLE_CLOCK); + // WHEN settings change event is fired + mContentObserver.onChange(false); + // THEN the listeners receive separate instances of the Bubble clock plugin. + ArgumentCaptor<ClockPlugin> captor1 = ArgumentCaptor.forClass(ClockPlugin.class); + ArgumentCaptor<ClockPlugin> captor2 = ArgumentCaptor.forClass(ClockPlugin.class); + verify(mMockListener1).onClockChanged(captor1.capture()); + verify(mMockListener2).onClockChanged(captor2.capture()); + assertThat(captor1.getValue()).isInstanceOf(BUBBLE_CLOCK_CLASS); + assertThat(captor2.getValue()).isInstanceOf(BUBBLE_CLOCK_CLASS); + assertThat(captor1.getValue()).isNotSameAs(captor2.getValue()); + } + + @Test public void getCurrentClock_badSettingsValue() { // GIVEN that settings contains a value that doesn't correspond to a // custom clock face. 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/bubbles/BubbleControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java index 14bc71b6a142..9fa85d307d2a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java @@ -438,6 +438,22 @@ public class BubbleControllerTest extends SysuiTestCase { } @Test + public void testExpandStackAndSelectBubble_removedFirst() { + final String key = mRow.getEntry().key; + + mEntryListener.onPendingEntryAdded(mRow.getEntry()); + mBubbleController.updateBubble(mRow.getEntry(), true /* updatePosition */); + + assertTrue(mRow.getEntry().isBubble()); + + // Simulate notification cancellation. + mEntryListener.onEntryRemoved(mRow.getEntry(), null /* notificationVisibility (unused) */, + false /* removedbyUser */); + + mBubbleController.expandStackAndSelectBubble(key); + } + + @Test public void testMarkNewNotificationAsBubble() { mEntryListener.onPendingEntryAdded(mRow.getEntry()); assertTrue(mRow.getEntry().isBubble()); diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/StackAnimationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/StackAnimationControllerTest.java index 096f205e7a56..50fadef8aaf2 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/StackAnimationControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/StackAnimationControllerTest.java @@ -199,6 +199,7 @@ public class StackAnimationControllerTest extends PhysicsAnimationLayoutTestCase } @Test + @Ignore("Flaky") public void testRestoredAtRestingPosition() throws InterruptedException { mStackController.flingStackThenSpringToEdge(0, 5000, 5000); diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeHostFake.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeHostFake.java index dc4287287b03..abfa755671db 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeHostFake.java +++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeHostFake.java @@ -86,7 +86,7 @@ class DozeHostFake implements DozeHost { } @Override - public void extendPulse() { + public void extendPulse(int reason) { pulseExtended = true; } 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/doze/DozeWallpaperStateTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeWallpaperStateTest.java index beba905279aa..87ae85f6d302 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeWallpaperStateTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeWallpaperStateTest.java @@ -45,12 +45,11 @@ public class DozeWallpaperStateTest extends SysuiTestCase { private DozeWallpaperState mDozeWallpaperState; @Mock IWallpaperManager mIWallpaperManager; @Mock DozeParameters mDozeParameters; - @Mock DozeMachine mMachine; @Before public void setUp() { MockitoAnnotations.initMocks(this); - mDozeWallpaperState = new DozeWallpaperState(mMachine, mIWallpaperManager, mDozeParameters); + mDozeWallpaperState = new DozeWallpaperState(mIWallpaperManager, mDozeParameters); } @Test @@ -110,28 +109,18 @@ public class DozeWallpaperStateTest extends SysuiTestCase { } @Test - public void testTransitionTo_notificationPulseIsAmbientMode() throws RemoteException { - when(mMachine.getPulseReason()).thenReturn(DozeLog.PULSE_REASON_NOTIFICATION); - mDozeWallpaperState.transitionTo(DozeMachine.State.DOZE_REQUEST_PULSE, - DozeMachine.State.DOZE_PULSING); - verify(mIWallpaperManager).setInAmbientMode(eq(true), eq(0L)); - } - - @Test public void testTransitionTo_wakeFromPulseIsNotAmbientMode() throws RemoteException { - when(mMachine.getPulseReason()).thenReturn(DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN); mDozeWallpaperState.transitionTo(DozeMachine.State.DOZE_AOD, DozeMachine.State.DOZE_REQUEST_PULSE); reset(mIWallpaperManager); mDozeWallpaperState.transitionTo(DozeMachine.State.DOZE_REQUEST_PULSE, - DozeMachine.State.DOZE_PULSING); + DozeMachine.State.DOZE_PULSING_BRIGHT); verify(mIWallpaperManager).setInAmbientMode(eq(false), anyLong()); } @Test public void testTransitionTo_animatesWhenWakingUpFromPulse() throws RemoteException { - when(mMachine.getPulseReason()).thenReturn(DozeLog.PULSE_REASON_NOTIFICATION); mDozeWallpaperState.transitionTo(DozeMachine.State.DOZE_REQUEST_PULSE, DozeMachine.State.DOZE_PULSING); reset(mIWallpaperManager); diff --git a/packages/SystemUI/tests/src/com/android/systemui/power/PowerUITest.java b/packages/SystemUI/tests/src/com/android/systemui/power/PowerUITest.java index f51e4731a390..5928a07487d9 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/power/PowerUITest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/power/PowerUITest.java @@ -265,6 +265,12 @@ public class PowerUITest extends SysuiTestCase { state.mIsPowerSaver = true; shouldShow = mPowerUI.shouldShowHybridWarning(state.get()); assertThat(shouldShow).isFalse(); + + state.mIsPowerSaver = false; + // if disabled we should not show the low warning. + state.mIsLowLevelWarningEnabled = false; + shouldShow = mPowerUI.shouldShowHybridWarning(state.get()); + assertThat(shouldShow).isFalse(); } @Test @@ -365,7 +371,7 @@ public class PowerUITest extends SysuiTestCase { assertThat(refreshedEstimate.getEstimateMillis()).isEqualTo(BELOW_HYBRID_THRESHOLD); BatteryStateSnapshot snapshot = new BatteryStateSnapshot( BATTERY_LEVEL_10, false, false, 0, BatteryManager.BATTERY_HEALTH_GOOD, - 0, 0, -1, 0, 0, false); + 0, 0, -1, 0, 0, false, true); mPowerUI.mLastBatteryStateSnapshot = snapshot; // query again since the estimate was -1 @@ -375,7 +381,7 @@ public class PowerUITest extends SysuiTestCase { assertThat(refreshedEstimate.getEstimateMillis()).isEqualTo(BELOW_SEVERE_HYBRID_THRESHOLD); snapshot = new BatteryStateSnapshot( BATTERY_LEVEL_10, false, false, 0, BatteryManager.BATTERY_HEALTH_GOOD, 0, - 0, BELOW_SEVERE_HYBRID_THRESHOLD, 0, 0, false); + 0, BELOW_SEVERE_HYBRID_THRESHOLD, 0, 0, false, true); mPowerUI.mLastBatteryStateSnapshot = snapshot; // Battery level hasn't changed, so we don't query again @@ -536,13 +542,14 @@ public class PowerUITest extends SysuiTestCase { public long mTimeRemainingMillis = Duration.ofHours(24).toMillis(); public boolean mIsBasedOnUsage = true; public boolean mIsHybrid = true; + public boolean mIsLowLevelWarningEnabled = true; public BatteryStateSnapshot get() { if (mIsHybrid) { return new BatteryStateSnapshot(mBatteryLevel, mIsPowerSaver, mPlugged, mBucket, mBatteryStatus, mSevereLevelThreshold, mLowLevelThreshold, mTimeRemainingMillis, mSevereThresholdMillis, mLowThresholdMillis, - mIsBasedOnUsage); + mIsBasedOnUsage, mIsLowLevelWarningEnabled); } else { return new BatteryStateSnapshot(mBatteryLevel, mIsPowerSaver, mPlugged, mBucket, mBatteryStatus, mSevereLevelThreshold, mLowLevelThreshold); 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/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java index 8c5f6f24ee79..7e089a653b9e 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java @@ -151,6 +151,16 @@ public class NotificationTestHelper { /** * Returns an {@link ExpandableNotificationRow} that should be shown as a bubble. + */ + public ExpandableNotificationRow createBubble() + throws Exception { + Notification n = createNotification(false /* isGroupSummary */, + null /* groupKey */, makeBubbleMetadata(null)); + return generateRow(n, PKG, UID, USER_HANDLE, 0 /* extraInflationFlags */, IMPORTANCE_HIGH); + } + + /** + * Returns an {@link ExpandableNotificationRow} that should be shown as a bubble. * * @param deleteIntent the intent to assign to {@link BubbleMetadata#deleteIntent} */ @@ -212,7 +222,7 @@ public class NotificationTestHelper { * * @return a notification with no special properties */ - private Notification createNotification() { + public Notification createNotification() { return createNotification(false /* isGroupSummary */, null /* groupKey */); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java index 0aa103fa27da..8077e3fbaa0a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java @@ -37,7 +37,9 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.app.AppOpsManager; +import android.app.Notification; import android.app.NotificationChannel; +import android.os.UserHandle; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.testing.TestableLooper.RunWithLooper; @@ -355,4 +357,30 @@ public class ExpandableNotificationRowTest extends SysuiTestCase { mGroupRow.setUserExpanded(true); Assert.assertTrue(mGroupRow.isExpanded()); } + + @Test + public void testGetIsNonblockable() throws Exception { + ExpandableNotificationRow row = + mNotificationTestHelper.createRow(mNotificationTestHelper.createNotification()); + + assertFalse(row.getIsNonblockable()); + } + + @Test + public void testGetIsNonblockable_oemLocked() throws Exception { + ExpandableNotificationRow row = + mNotificationTestHelper.createRow(mNotificationTestHelper.createNotification()); + row.getEntry().channel.setImportanceLockedByOEM(true); + + assertTrue(row.getIsNonblockable()); + } + + @Test + public void testGetIsNonblockable_criticalDeviceFunction() throws Exception { + ExpandableNotificationRow row = + mNotificationTestHelper.createRow(mNotificationTestHelper.createNotification()); + row.getEntry().channel.setImportanceLockedByCriticalDeviceFunction(true); + + assertTrue(row.getIsNonblockable()); + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java index 3b56e45ea354..6d6af4759e7a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java @@ -16,6 +16,8 @@ package com.android.systemui.statusbar.phone; +import static com.google.common.truth.Truth.assertThat; + import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.inOrder; import static org.mockito.Mockito.verify; @@ -23,6 +25,8 @@ import static org.mockito.Mockito.when; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; +import android.view.MotionEvent; +import android.view.ViewGroup; import androidx.test.filters.SmallTest; @@ -32,6 +36,7 @@ import com.android.systemui.SysuiTestCase; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.AmbientPulseManager; import com.android.systemui.statusbar.NotificationLockscreenUserManager; +import com.android.systemui.statusbar.NotificationShelf; import com.android.systemui.statusbar.PulseExpansionHandler; import com.android.systemui.statusbar.StatusBarStateControllerImpl; import com.android.systemui.statusbar.SysuiStatusBarStateController; @@ -54,6 +59,8 @@ import org.mockito.MockitoAnnotations; public class NotificationPanelViewTest extends SysuiTestCase { @Mock + private StatusBar mStatusBar; + @Mock private SysuiStatusBarStateController mStatusBarStateController; @Mock private NotificationStackScrollLayout mNotificationStackScrollLayout; @@ -62,12 +69,33 @@ public class NotificationPanelViewTest extends SysuiTestCase { @Mock private KeyguardBottomAreaView mKeyguardBottomArea; @Mock + private KeyguardBottomAreaView mQsFrame; + @Mock + private ViewGroup mBigClockContainer; + @Mock + private ScrimController mScrimController; + @Mock + private NotificationIconAreaController mNotificationAreaController; + @Mock + private HeadsUpManagerPhone mHeadsUpManager; + @Mock + private NotificationShelf mNotificationShelf; + @Mock + private NotificationGroupManager mGroupManager; + @Mock private KeyguardStatusBarView mKeyguardStatusBar; + @Mock + private HeadsUpTouchHelper.Callback mHeadsUpCallback; + @Mock + private PanelBar mPanelBar; private NotificationPanelView mNotificationPanelView; @Before public void setup() { MockitoAnnotations.initMocks(this); + when(mNotificationStackScrollLayout.getHeight()).thenReturn(1000); + when(mNotificationStackScrollLayout.getHeadsUpCallback()).thenReturn(mHeadsUpCallback); + when(mHeadsUpCallback.getContext()).thenReturn(mContext); mDependency.injectTestDependency(StatusBarStateController.class, mStatusBarStateController); mDependency.injectMockDependency(ShadeController.class); @@ -80,6 +108,8 @@ public class NotificationPanelViewTest extends SysuiTestCase { new StatusBarStateControllerImpl()); PulseExpansionHandler expansionHandler = new PulseExpansionHandler(mContext, coordinator); mNotificationPanelView = new TestableNotificationPanelView(coordinator, expansionHandler); + mNotificationPanelView.setHeadsUpManager(mHeadsUpManager); + mNotificationPanelView.setBar(mPanelBar); } @Test @@ -105,6 +135,37 @@ public class NotificationPanelViewTest extends SysuiTestCase { verify(mNotificationStackScrollLayout).setShowDarkShelf(eq(false)); } + @Test + public void testSetExpandedHeight() { + mNotificationPanelView.setExpandedHeight(200); + assertThat((int) mNotificationPanelView.getExpandedHeight()).isEqualTo(200); + } + + @Test + public void testOnTouchEvent_expansionCanBeBlocked() { + mNotificationPanelView.onTouchEvent(MotionEvent.obtain(0L /* downTime */, + 0L /* eventTime */, MotionEvent.ACTION_DOWN, 0f /* x */, 0f /* y */, + 0 /* metaState */)); + mNotificationPanelView.onTouchEvent(MotionEvent.obtain(0L /* downTime */, + 0L /* eventTime */, MotionEvent.ACTION_MOVE, 0f /* x */, 200f /* y */, + 0 /* metaState */)); + assertThat((int) mNotificationPanelView.getExpandedHeight()).isEqualTo(200); + assertThat(mNotificationPanelView.isTrackingBlocked()).isFalse(); + + mNotificationPanelView.blockExpansionForCurrentTouch(); + mNotificationPanelView.onTouchEvent(MotionEvent.obtain(0L /* downTime */, + 0L /* eventTime */, MotionEvent.ACTION_MOVE, 0f /* x */, 300f /* y */, + 0 /* metaState */)); + // Expansion should not have changed because it was blocked + assertThat((int) mNotificationPanelView.getExpandedHeight()).isEqualTo(200); + assertThat(mNotificationPanelView.isTrackingBlocked()).isTrue(); + + mNotificationPanelView.onTouchEvent(MotionEvent.obtain(0L /* downTime */, + 0L /* eventTime */, MotionEvent.ACTION_UP, 0f /* x */, 300f /* y */, + 0 /* metaState */)); + assertThat(mNotificationPanelView.isTrackingBlocked()).isFalse(); + } + private class TestableNotificationPanelView extends NotificationPanelView { TestableNotificationPanelView(NotificationWakeUpCoordinator coordinator, PulseExpansionHandler expansionHandler) { @@ -116,6 +177,14 @@ public class NotificationPanelViewTest extends SysuiTestCase { mKeyguardStatusView = NotificationPanelViewTest.this.mKeyguardStatusView; mKeyguardStatusBar = NotificationPanelViewTest.this.mKeyguardStatusBar; mKeyguardBottomArea = NotificationPanelViewTest.this.mKeyguardBottomArea; + mBigClockContainer = NotificationPanelViewTest.this.mBigClockContainer; + mQsFrame = NotificationPanelViewTest.this.mQsFrame; + initDependencies(NotificationPanelViewTest.this.mStatusBar, + NotificationPanelViewTest.this.mGroupManager, + NotificationPanelViewTest.this.mNotificationShelf, + NotificationPanelViewTest.this.mHeadsUpManager, + NotificationPanelViewTest.this.mNotificationAreaController, + NotificationPanelViewTest.this.mScrimController); } } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java index 539851f45153..191c983ad156 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java @@ -46,7 +46,6 @@ import androidx.test.filters.SmallTest; import com.android.internal.colorextraction.ColorExtractor.GradientColors; import com.android.internal.util.function.TriConsumer; import com.android.systemui.SysuiTestCase; -import com.android.systemui.doze.DozeLog; import com.android.systemui.statusbar.ScrimView; import com.android.systemui.util.wakelock.WakeLock; import com.android.systemui.utils.os.FakeHandler; @@ -140,7 +139,6 @@ public class ScrimControllerTest extends SysuiTestCase { assertScrimVisibility(VISIBILITY_FULLY_TRANSPARENT, VISIBILITY_FULLY_TRANSPARENT); // Pulsing notification should conserve AOD wallpaper. - mScrimController.setPulseReason(DozeLog.PULSE_REASON_NOTIFICATION); mScrimController.transitionTo(ScrimState.PULSING); mScrimController.finishAnimationsImmediately(); assertScrimVisibility(VISIBILITY_FULLY_TRANSPARENT, VISIBILITY_FULLY_TRANSPARENT); @@ -225,14 +223,17 @@ public class ScrimControllerTest extends SysuiTestCase { mScrimController.finishAnimationsImmediately(); assertScrimVisibility(VISIBILITY_FULLY_TRANSPARENT, VISIBILITY_FULLY_OPAQUE); - mScrimController.setPulseReason(DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN); mScrimController.transitionTo(ScrimState.PULSING); mScrimController.finishAnimationsImmediately(); // Front scrim should be transparent // Back scrim should be semi-transparent so the user can see the wallpaper // Pulse callback should have been invoked - assertScrimVisibility(VISIBILITY_FULLY_TRANSPARENT, VISIBILITY_SEMI_TRANSPARENT); + assertScrimVisibility(VISIBILITY_FULLY_TRANSPARENT, VISIBILITY_FULLY_OPAQUE); assertScrimTint(mScrimBehind, true /* tinted */); + + mScrimController.setWakeLockScreenSensorActive(true); + mScrimController.finishAnimationsImmediately(); + assertScrimVisibility(VISIBILITY_FULLY_TRANSPARENT, VISIBILITY_SEMI_TRANSPARENT); } @Test @@ -486,7 +487,6 @@ public class ScrimControllerTest extends SysuiTestCase { @Test public void testHoldsPulsingWallpaperAnimationLock() { // Pre-conditions - mScrimController.setPulseReason(DozeLog.PULSE_REASON_NOTIFICATION); mScrimController.transitionTo(ScrimState.PULSING); mScrimController.finishAnimationsImmediately(); reset(mWakeLock); @@ -508,30 +508,6 @@ public class ScrimControllerTest extends SysuiTestCase { } @Test - public void testWillHidePulsingWallpaper_whenNotification() { - mScrimController.setWallpaperSupportsAmbientMode(false); - mScrimController.transitionTo(ScrimState.AOD); - mScrimController.finishAnimationsImmediately(); - mScrimController.setPulseReason(DozeLog.PULSE_REASON_NOTIFICATION); - mScrimController.transitionTo(ScrimState.PULSING); - mScrimController.finishAnimationsImmediately(); - assertScrimVisibility(VISIBILITY_FULLY_TRANSPARENT, VISIBILITY_FULLY_OPAQUE); - assertScrimTint(mScrimBehind, true); - } - - @Test - public void testWillHidePulsingWallpaper_whenDocking() { - mScrimController.setWallpaperSupportsAmbientMode(false); - mScrimController.transitionTo(ScrimState.AOD); - mScrimController.finishAnimationsImmediately(); - mScrimController.setPulseReason(DozeLog.PULSE_REASON_DOCKING); - mScrimController.transitionTo(ScrimState.PULSING); - mScrimController.finishAnimationsImmediately(); - assertScrimVisibility(VISIBILITY_FULLY_TRANSPARENT, VISIBILITY_FULLY_OPAQUE); - assertScrimTint(mScrimBehind, true); - } - - @Test public void testConservesExpansionOpacityAfterTransition() { mScrimController.transitionTo(ScrimState.UNLOCKED); mScrimController.setPanelExpansion(0.5f); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java index 20af1ac5a42f..41e82cbeac36 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java @@ -24,7 +24,10 @@ import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.verifyZeroInteractions; import static org.mockito.Mockito.when; import android.app.KeyguardManager; @@ -49,6 +52,7 @@ import com.android.internal.widget.LockPatternUtils; import com.android.systemui.ActivityIntentHelper; import com.android.systemui.SysuiTestCase; import com.android.systemui.assist.AssistManager; +import com.android.systemui.bubbles.BubbleController; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.CommandQueue; @@ -101,22 +105,23 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase { private KeyguardMonitor mKeyguardMonitor; @Mock private Handler mHandler; + @Mock + private BubbleController mBubbleController; @Mock private ActivityIntentHelper mActivityIntentHelper; @Mock private PendingIntent mContentIntent; @Mock - private NotificationData mNotificationData; - @Mock - private NotificationEntry mNotificationEntry; + private Intent mContentIntentInner; @Mock - private NotificationEntry mBubbleEntry; + private NotificationData mNotificationData; private NotificationActivityStarter mNotificationActivityStarter; private NotificationTestHelper mNotificationTestHelper; - ExpandableNotificationRow mNotificationRow; + private ExpandableNotificationRow mNotificationRow; + private ExpandableNotificationRow mBubbleNotificationRow; private final Answer<Void> mCallOnDismiss = answerVoid( (ActivityStarter.OnDismissAction dismissAction, Runnable cancel, @@ -129,14 +134,32 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase { when(mRemoteInputManager.getController()).thenReturn(mRemoteInputController); when(mEntryManager.getNotificationData()).thenReturn(mNotificationData); - mActiveNotifications = new ArrayList<>(); - mActiveNotifications.add(mNotificationEntry); - mActiveNotifications.add(mBubbleEntry); - when(mNotificationData.getActiveNotifications()).thenReturn(mActiveNotifications); - when(mNotificationEntry.getRow()).thenReturn(mNotificationRow); + when(mContentIntent.isActivity()).thenReturn(true); + when(mContentIntent.getCreatorUserHandle()).thenReturn(UserHandle.of(1)); + when(mContentIntent.getIntent()).thenReturn(mContentIntentInner); mNotificationTestHelper = new NotificationTestHelper(mContext); + + // Create standard notification with contentIntent mNotificationRow = mNotificationTestHelper.createRow(); + StatusBarNotification sbn = mNotificationRow.getStatusBarNotification(); + sbn.getNotification().contentIntent = mContentIntent; + sbn.getNotification().flags |= Notification.FLAG_AUTO_CANCEL; + + // Create bubble notification row with contentIntent + mBubbleNotificationRow = mNotificationTestHelper.createBubble(); + StatusBarNotification bubbleSbn = mBubbleNotificationRow.getStatusBarNotification(); + bubbleSbn.getNotification().contentIntent = mContentIntent; + bubbleSbn.getNotification().flags |= Notification.FLAG_AUTO_CANCEL; + // Do what BubbleController's NotificationEntryListener#onPendingEntryAdded does: + mBubbleNotificationRow.getEntry().setIsBubble(true); + mBubbleNotificationRow.getEntry().setShowInShadeWhenBubble(true); + + mActiveNotifications = new ArrayList<>(); + mActiveNotifications.add(mNotificationRow.getEntry()); + mActiveNotifications.add(mBubbleNotificationRow.getEntry()); + when(mNotificationData.getActiveNotifications()).thenReturn(mActiveNotifications); + when(mStatusBarStateController.getState()).thenReturn(StatusBarState.SHADE); mNotificationActivityStarter = new StatusBarNotificationActivityStarter(getContext(), mock(CommandQueue.class), mAssistManager, mock(NotificationPanelView.class), @@ -147,16 +170,8 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase { mock(StatusBarRemoteInputCallback.class), mock(NotificationGroupManager.class), mock(NotificationLockscreenUserManager.class), mShadeController, mKeyguardMonitor, mock(NotificationInterruptionStateProvider.class), mock(MetricsLogger.class), - mock(LockPatternUtils.class), mHandler, mActivityIntentHelper); - - - when(mContentIntent.isActivity()).thenReturn(true); - when(mContentIntent.getCreatorUserHandle()).thenReturn(UserHandle.of(1)); - - // SBNActivityStarter expects contentIntent or fullScreenIntent to be set - mNotificationRow.getEntry().notification.getNotification().contentIntent = mContentIntent; - - when(mStatusBarStateController.getState()).thenReturn(StatusBarState.SHADE); + mock(LockPatternUtils.class), mHandler, mHandler, mActivityIntentHelper, + mBubbleController); // set up dismissKeyguardThenExecute to synchronously invoke the OnDismissAction arg doAnswer(mCallOnDismiss).when(mActivityStarter).dismissKeyguardThenExecute( @@ -173,33 +188,26 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase { // set up Handler to synchronously invoke the Runnable arg doAnswer(answerVoid(Runnable::run)) .when(mHandler).post(any(Runnable.class)); + + doAnswer(answerVoid(Runnable::run)) + .when(mHandler).postAtFrontOfQueue(any(Runnable.class)); } @Test - public void testOnNotificationClicked_whileKeyguardVisible() + public void testOnNotificationClicked_keyGuardShowing() throws PendingIntent.CanceledException, RemoteException { // Given + StatusBarNotification sbn = mNotificationRow.getStatusBarNotification(); + sbn.getNotification().contentIntent = mContentIntent; + sbn.getNotification().flags |= Notification.FLAG_AUTO_CANCEL; + when(mKeyguardMonitor.isShowing()).thenReturn(true); when(mShadeController.isOccluded()).thenReturn(true); - when(mContentIntent.isActivity()).thenReturn(true); - when(mActivityIntentHelper.wouldShowOverLockscreen(any(Intent.class), anyInt())) - .thenReturn(false); - when(mActivityIntentHelper.wouldLaunchResolverActivity(any(Intent.class), anyInt())) - .thenReturn(false); - - StatusBarNotification statusBarNotification = mNotificationRow.getEntry().notification; - statusBarNotification.getNotification().flags |= Notification.FLAG_AUTO_CANCEL; // When - mNotificationActivityStarter.onNotificationClicked(statusBarNotification, - mNotificationRow); + mNotificationActivityStarter.onNotificationClicked(sbn, mNotificationRow); // Then - verify(mActivityStarter).dismissKeyguardThenExecute( - any(ActivityStarter.OnDismissAction.class), - any() /* cancel */, - anyBoolean() /* afterKeyguardGone */); - verify(mShadeController, atLeastOnce()).collapsePanel(); verify(mContentIntent).sendAndReturnResult( @@ -214,9 +222,100 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase { verify(mAssistManager).hideAssist(); verify(mStatusBarService).onNotificationClick( - eq(mNotificationRow.getEntry().key), any(NotificationVisibility.class)); + eq(sbn.getKey()), any(NotificationVisibility.class)); // Notification is removed due to FLAG_AUTO_CANCEL - verify(mEntryManager).performRemoveNotification(eq(statusBarNotification)); + verify(mEntryManager).performRemoveNotification(eq(sbn)); + } + + @Test + public void testOnNotificationClicked_bubble_noContentIntent_noKeyGuard() + throws RemoteException { + StatusBarNotification sbn = mBubbleNotificationRow.getStatusBarNotification(); + + // Given + sbn.getNotification().contentIntent = null; + + // When + mNotificationActivityStarter.onNotificationClicked(sbn, mBubbleNotificationRow); + + // Then + verify(mBubbleController).expandStackAndSelectBubble(eq(sbn.getKey())); + + // This is called regardless, and simply short circuits when there is nothing to do. + verify(mShadeController, atLeastOnce()).collapsePanel(); + + verify(mAssistManager).hideAssist(); + + verify(mStatusBarService).onNotificationClick( + eq(sbn.getKey()), any(NotificationVisibility.class)); + + // The content intent should NOT be sent on click. + verifyZeroInteractions(mContentIntent); + + // Notification should not be cancelled. + verify(mEntryManager, never()).performRemoveNotification(eq(sbn)); + } + + @Test + public void testOnNotificationClicked_bubble_noContentIntent_keyGuardShowing() + throws RemoteException { + StatusBarNotification sbn = mBubbleNotificationRow.getStatusBarNotification(); + + // Given + sbn.getNotification().contentIntent = null; + when(mKeyguardMonitor.isShowing()).thenReturn(true); + when(mShadeController.isOccluded()).thenReturn(true); + + // When + mNotificationActivityStarter.onNotificationClicked(sbn, mBubbleNotificationRow); + + // Then + verify(mBubbleController).expandStackAndSelectBubble(eq(sbn.getKey())); + + verify(mShadeController, atLeastOnce()).collapsePanel(); + + verify(mAssistManager).hideAssist(); + + verify(mStatusBarService).onNotificationClick( + eq(sbn.getKey()), any(NotificationVisibility.class)); + + // The content intent should NOT be sent on click. + verifyZeroInteractions(mContentIntent); + + // Notification should not be cancelled. + verify(mEntryManager, never()).performRemoveNotification(eq(sbn)); + } + + @Test + public void testOnNotificationClicked_bubble_withContentIntent_keyGuardShowing() + throws RemoteException { + StatusBarNotification sbn = mBubbleNotificationRow.getStatusBarNotification(); + + // Given + sbn.getNotification().contentIntent = mContentIntent; + when(mKeyguardMonitor.isShowing()).thenReturn(true); + when(mShadeController.isOccluded()).thenReturn(true); + + // When + mNotificationActivityStarter.onNotificationClicked(sbn, mBubbleNotificationRow); + + // Then + verify(mBubbleController).expandStackAndSelectBubble(eq(sbn.getKey())); + + verify(mShadeController, atLeastOnce()).collapsePanel(); + + verify(mAssistManager).hideAssist(); + + verify(mStatusBarService).onNotificationClick( + eq(sbn.getKey()), any(NotificationVisibility.class)); + + // The content intent should NOT be sent on click. + verify(mContentIntent).getIntent(); + verify(mContentIntent).isActivity(); + verifyNoMoreInteractions(mContentIntent); + + // Notification should not be cancelled. + verify(mEntryManager, never()).performRemoveNotification(eq(sbn)); } } 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..b45b9101cce8 --- /dev/null +++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_bluetooth_share_icon.xml @@ -0,0 +1,20 @@ + +<!-- + 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 android:height="24dp" android:tint="@*android:color/accent_device_default" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <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_bt_headphones_a2dp.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_bt_headphones_a2dp.xml index 4d8c366fff53..b4307a4c2548 100644 --- a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_bt_headphones_a2dp.xml +++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_bt_headphones_a2dp.xml @@ -1,30 +1,20 @@ + <!-- -/** - * 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. - */ + 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,18V11A9,9,0,0,0,3,11v7a2.93,2.93,0,0,0,2.88,3H8V13H4V11a8,8,0,0,1,16,0v2H16v8h2.12A2.93,2.93,0,0,0,21,18ZM7,14v6H5.88A1.92,1.92,0,0,1,4,18V14Zm13,4a1.92,1.92,0,0,1-1.88,2H17V14h3Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M21,17.78V11c0-4.96-4.04-9-9-9s-9,4.04-9,9v6.78C3,19.56,4.41,21,6.13,21H9v-8H4.5v-2c0-4.13,3.36-7.5,7.5-7.5 s7.5,3.36,7.5,7.5v2H15v8h2.87C19.59,21,21,19.56,21,17.78z M7.5,19.5H6.13c-0.9,0-1.63-0.77-1.63-1.72V14.5h3V19.5z M19.5,17.78 c0,0.95-0.73,1.72-1.63,1.72H16.5v-5h3V17.78z"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_expand_more.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_expand_more.xml index ab6aec5bc416..69b7e0b7d1b7 100644 --- a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_expand_more.xml +++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_expand_more.xml @@ -1,30 +1,20 @@ + <!-- -/** - * 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. - */ + 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="M18.35,9.65a0.48 0.48 ,0,0,0-0.7,0L12,15.28,6.35,9.65a0.49 0.49 ,0,0,0-0.7 0.7 L12,16.7l6.35-6.35A0.48 0.48 ,0,0,0,18.35,9.65Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M19.78,8.22c-0.29-0.29-0.77-0.29-1.06,0L12,14.94L5.28,8.22c-0.29-0.29-0.77-0.29-1.06,0s-0.29,0.77,0,1.06L12,17.06 l7.78-7.78C20.07,8.99,20.07,8.51,19.78,8.22z"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_faster_emergency.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_faster_emergency.xml new file mode 100644 index 000000000000..fe238d9b0aec --- /dev/null +++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_faster_emergency.xml @@ -0,0 +1,21 @@ + +<!-- + 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 android:height="24dp" android:tint="?android:attr/colorError" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M16.5,10.75h-3.25V7.5c0-0.28-0.22-0.5-0.5-0.5h-1.5c-0.28,0-0.5,0.22-0.5,0.5v3.25H7.5c-0.28,0-0.5,0.22-0.5,0.5v1.5 c0,0.28,0.22,0.5,0.5,0.5h3.25v3.25c0,0.28,0.22,0.5,0.5,0.5h1.5c0.28,0,0.5-0.22,0.5-0.5v-3.25h3.25c0.28,0,0.5-0.22,0.5-0.5v-1.5 C17,10.97,16.78,10.75,16.5,10.75z"/> + <path android:fillColor="@android:color/white" android:pathData="M18,4.5c0.83,0,1.5,0.67,1.5,1.5v13.5h-15V6c0-0.83,0.67-1.5,1.5-1.5H18 M18,3H6C4.34,3,3,4.34,3,6v15h18V6 C21,4.34,19.66,3,18,3L18,3z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_info_outline_24.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_info_outline_24.xml index 0e108ca7924c..7f060a4e555e 100644 --- a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_info_outline_24.xml +++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_info_outline_24.xml @@ -1,36 +1,22 @@ + <!-- -/** - * 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. - */ + 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="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="M12,11a0.5 0.5 ,0,0,0-0.5 0.5 v5a0.5 0.5 ,0,0,0,1,0v-5A0.5 0.5 ,0,0,0,12,11Z" /> - <path - android:fillColor="#000000" - android:pathData="M 12 7 C 12.4142135624 7 12.75 7.33578643763 12.75 7.75 C 12.75 8.16421356237 12.4142135624 8.5 12 8.5 C 11.5857864376 8.5 11.25 8.16421356237 11.25 7.75 C 11.25 7.33578643763 11.5857864376 7 12 7 Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M11.99,2C6.47,2,2,6.48,2,12c0,5.52,4.47,10,9.99,10C17.52,22,22,17.52,22,12C22,6.48,17.52,2,11.99,2z M11.99,20.5 c-4.68,0-8.49-3.81-8.49-8.5c0-4.69,3.81-8.5,8.49-8.5c4.69,0,8.51,3.81,8.51,8.5C20.5,16.69,16.68,20.5,11.99,20.5z"/> + <path android:fillColor="@android:color/white" android:pathData="M12,10.5c-0.41,0-0.75,0.34-0.75,0.75v5c0,0.41,0.34,0.75,0.75,0.75s0.75-0.34,0.75-0.75v-5 C12.75,10.84,12.41,10.5,12,10.5z"/> + <path android:fillColor="@android:color/white" android:pathData="M 12 7 C 12.5522847498 7 13 7.44771525017 13 8 C 13 8.55228474983 12.5522847498 9 12 9 C 11.4477152502 9 11 8.55228474983 11 8 C 11 7.44771525017 11.4477152502 7 12 7 Z"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_invert_colors.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_invert_colors.xml deleted file mode 100644 index 59e7838b9c67..000000000000 --- a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_invert_colors.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="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" /> -</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_lock.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_lock.xml new file mode 100644 index 000000000000..a5cef0d4aa3a --- /dev/null +++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_lock.xml @@ -0,0 +1,21 @@ + +<!-- + 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 android:height="32dp" android:tint="?android:attr/textColor" android:viewportHeight="24" android:viewportWidth="24" android:width="32dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M11.25,14.79v1.46c0,0.41,0.34,0.75,0.75,0.75s0.75-0.34,0.75-0.75v-1.46c0.45-0.26,0.75-0.74,0.75-1.29 c0-0.83-0.67-1.5-1.5-1.5s-1.5,0.67-1.5,1.5C10.5,14.05,10.8,14.53,11.25,14.79z"/> + <path android:fillColor="@android:color/white" android:pathData="M12,1C9.79,1,8,2.88,8,5v3H5v10c0,1.66,1.34,3,3,3h8c1.66,0,3-1.34,3-3V8h-3V5C16,2.88,14.21,1,12,1z M9.5,5 c0-1.33,1.17-2.5,2.5-2.5s2.5,1.17,2.5,2.5v3h-5V5z M17.5,9.5V18c0,0.83-0.67,1.5-1.5,1.5H8c-0.83,0-1.5-0.67-1.5-1.5V9.5H8h8H17.5 z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_lock_bugreport.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_lock_bugreport.xml new file mode 100644 index 000000000000..3cef2ae5b2dd --- /dev/null +++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_lock_bugreport.xml @@ -0,0 +1,22 @@ + +<!-- + 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 android:height="24dp" android:tint="?android:attr/colorControlNormal" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M2.75,13.25H6v2.65l-2.56,1.16c-0.38,0.17-0.54,0.62-0.37,0.99c0.12,0.28,0.4,0.44,0.68,0.44c0.1,0,0.21-0.02,0.31-0.07 L6,17.55V21h12v-3.45l1.94,0.88c0.1,0.05,0.21,0.07,0.31,0.07c0.29,0,0.56-0.16,0.68-0.44c0.17-0.38,0-0.82-0.37-0.99L18,15.9 v-2.65h3.25c0.41,0,0.75-0.34,0.75-0.75s-0.34-0.75-0.75-0.75H18V11c0-0.46-0.06-0.9-0.15-1.33l2.71-1.23 c0.38-0.17,0.54-0.62,0.37-0.99c-0.17-0.38-0.62-0.54-0.99-0.37l-2.61,1.18c-0.52-1-1.31-1.84-2.28-2.41l0.67-1.84 c0.14-0.39-0.06-0.82-0.45-0.96C14.87,2.9,14.44,3.1,14.3,3.49l-0.63,1.76C13.14,5.09,12.58,5,12,5s-1.14,0.09-1.67,0.24L9.7,3.49 C9.56,3.1,9.12,2.89,8.74,3.03C8.35,3.18,8.14,3.6,8.29,3.99l0.67,1.84C7.98,6.41,7.19,7.25,6.67,8.25L4.06,7.07 c-0.38-0.17-0.82,0-0.99,0.37c-0.17,0.38,0,0.82,0.37,0.99l2.71,1.23C6.06,10.1,6,10.54,6,11v0.75H2.75C2.34,11.75,2,12.09,2,12.5 S2.34,13.25,2.75,13.25z M7.5,11c0-2.48,2.02-4.5,4.5-4.5s4.5,2.02,4.5,4.5v8.5h-9V11z"/> + <path android:fillColor="@android:color/white" android:pathData="M14,14.75c0-0.41-0.34-0.75-0.75-0.75h-2.5C10.34,14,10,14.34,10,14.75s0.34,0.75,0.75,0.75h2.5 C13.66,15.5,14,15.16,14,14.75z"/> + <path android:fillColor="@android:color/white" android:pathData="M10.75,12h2.5c0.41,0,0.75-0.34,0.75-0.75s-0.34-0.75-0.75-0.75h-2.5c-0.41,0-0.75,0.34-0.75,0.75S10.34,12,10.75,12z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_lock_open.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_lock_open.xml new file mode 100644 index 000000000000..0f7a5521b306 --- /dev/null +++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_lock_open.xml @@ -0,0 +1,21 @@ + +<!-- + 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 android:height="32dp" android:tint="?android:attr/textColor" android:viewportHeight="24" android:viewportWidth="24" android:width="32dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M11.25,14.79v1.46c0,0.41,0.34,0.75,0.75,0.75s0.75-0.34,0.75-0.75v-1.46c0.45-0.26,0.75-0.74,0.75-1.29 c0-0.83-0.67-1.5-1.5-1.5s-1.5,0.67-1.5,1.5C10.5,14.05,10.8,14.53,11.25,14.79z"/> + <path android:fillColor="@android:color/white" android:pathData="M19,2.5c1.35,0,2.5,1.18,2.5,2.57c0,0.41,0.34,0.75,0.75,0.75S23,5.48,23,5.07C23,2.86,21.17,1,19,1s-4,1.86-4,4.07V8H5v10 c0,1.66,1.34,3,3,3h8c1.66,0,3-1.34,3-3V8h-2.5V5.07C16.5,3.68,17.65,2.5,19,2.5z M17.5,18c0,0.83-0.67,1.5-1.5,1.5H8 c-0.83,0-1.5-0.67-1.5-1.5V9.5h11V18z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_lock_power_off.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_lock_power_off.xml new file mode 100644 index 000000000000..d0e21a1cbcc4 --- /dev/null +++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_lock_power_off.xml @@ -0,0 +1,21 @@ + +<!-- + 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 android:height="24dp" android:tint="?android:attr/colorControlNormal" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M12,13c-0.41,0-0.75-0.34-0.75-0.75v-9.5C11.25,2.33,11.59,2,12,2s0.75,0.34,0.75,0.75v9.5C12.75,12.66,12.41,13,12,13z"/> + <path android:fillColor="@android:color/white" android:pathData="M12,21c-4.96,0-9-4.02-9-8.96c0-2.5,1.06-4.9,2.91-6.6c0.31-0.28,0.78-0.26,1.06,0.05C7.25,5.8,7.23,6.27,6.92,6.55 C5.38,7.96,4.5,9.96,4.5,12.04c0,4.11,3.36,7.46,7.5,7.46s7.5-3.34,7.5-7.46c0-2.08-0.88-4.08-2.42-5.49 c-0.3-0.28-0.33-0.75-0.05-1.06c0.28-0.3,0.75-0.33,1.06-0.05c1.85,1.69,2.91,4.1,2.91,6.6C21,16.98,16.96,21,12,21z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_lockscreen_ime.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_lockscreen_ime.xml index 04a2c24ce45a..310490338a17 100644 --- a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_lockscreen_ime.xml +++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_lockscreen_ime.xml @@ -1,57 +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. - */ + 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 android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M21,4H3C1.9,4,1,4.9,1,6v13c0,1.1,0.9,2,2,2h18c1.1,0,2-0.9,2-2V6C23,4.9,22.1,4,21,4z M21.5,19c0,0.27-0.23,0.5-0.5,0.5 H3c-0.27,0-0.5-0.23-0.5-0.5V6c0-0.27,0.23-0.5,0.5-0.5h18c0.27,0,0.5,0.23,0.5,0.5V19z"/> + <path android:fillColor="@android:color/white" android:pathData="M9.75,8h0.5C10.66,8,11,8.34,11,8.75v0.5C11,9.66,10.66,10,10.25,10h-0.5C9.34,10,9,9.66,9,9.25v-0.5 C9,8.34,9.34,8,9.75,8z"/> + <path android:fillColor="@android:color/white" android:pathData="M5.75,8h0.5C6.66,8,7,8.34,7,8.75v0.5C7,9.66,6.66,10,6.25,10h-0.5C5.34,10,5,9.66,5,9.25v-0.5C5,8.34,5.34,8,5.75,8z"/> + <path android:fillColor="@android:color/white" android:pathData="M13.75,8h0.5C14.66,8,15,8.34,15,8.75v0.5C15,9.66,14.66,10,14.25,10h-0.5C13.34,10,13,9.66,13,9.25v-0.5 C13,8.34,13.34,8,13.75,8z"/> + <path android:fillColor="@android:color/white" android:pathData="M9.75,12h0.5c0.41,0,0.75,0.34,0.75,0.75v0.5c0,0.41-0.34,0.75-0.75,0.75h-0.5C9.34,14,9,13.66,9,13.25v-0.5 C9,12.34,9.34,12,9.75,12z"/> + <path android:fillColor="@android:color/white" android:pathData="M5.75,12h0.5C6.66,12,7,12.34,7,12.75v0.5C7,13.66,6.66,14,6.25,14h-0.5C5.34,14,5,13.66,5,13.25v-0.5 C5,12.34,5.34,12,5.75,12z"/> + <path android:fillColor="@android:color/white" android:pathData="M13.75,12h0.5c0.41,0,0.75,0.34,0.75,0.75v0.5c0,0.41-0.34,0.75-0.75,0.75h-0.5C13.34,14,13,13.66,13,13.25v-0.5 C13,12.34,13.34,12,13.75,12z"/> + <path android:fillColor="@android:color/white" android:pathData="M17.75,8h0.5C18.66,8,19,8.34,19,8.75v0.5C19,9.66,18.66,10,18.25,10h-0.5C17.34,10,17,9.66,17,9.25v-0.5 C17,8.34,17.34,8,17.75,8z"/> + <path android:fillColor="@android:color/white" android:pathData="M17.75,12h0.5c0.41,0,0.75,0.34,0.75,0.75v0.5c0,0.41-0.34,0.75-0.75,0.75h-0.5C17.34,14,17,13.66,17,13.25v-0.5 C17,12.34,17.34,12,17.75,12z"/> + <path android:fillColor="@android:color/white" android:pathData="M15.5,17h-7C8.22,17,8,16.78,8,16.5S8.22,16,8.5,16h7c0.28,0,0.5,0.22,0.5,0.5S15.78,17,15.5,17z"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_mode_edit.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_mode_edit.xml index f9b0f6cbccc6..87edcc4e1d3a 100644 --- a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_mode_edit.xml +++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_mode_edit.xml @@ -1,30 +1,21 @@ + <!-- -/** - * 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. - */ + 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,21H7.18L20.41,7.77a2,2,0,0,0,0-2.83L19.06,3.59a2,2,0,0,0-2.83,0L3,16.82ZM16.94,4.3a1,1,0,0,1,1.41,0l1.36,1.35a1,1,0,0,1,0.29 0.7 ,1,1,0,0,1-0.3 0.71 l-2,2L15,6.26ZM4,17.23,14.26,7,17,9.74,6.77,20H4Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M20.41,4.94l-1.35-1.35c-0.39-0.39-0.9-0.58-1.41-0.58s-1.03,0.2-1.41,0.58L3,16.82V21h4.18L20.41,7.77 C21.2,6.99,21.2,5.72,20.41,4.94z M6.56,19.5H4.5v-2.06l9.94-9.94l2.06,2.06L6.56,19.5z M19.35,6.71L17.56,8.5L15.5,6.44l1.79-1.79 c0.13-0.13,0.28-0.15,0.35-0.15S17.87,4.52,18,4.65l1.36,1.36c0.12,0.12,0.15,0.25,0.15,0.35S19.48,6.58,19.35,6.71z"/> + <path android:fillColor="@android:color/white" android:pathData="M10.75,19.5c-0.41,0-0.75,0.34-0.75,0.75S10.34,21,10.75,21h9.5c0.41,0,0.75-0.34,0.75-0.75s-0.34-0.75-0.75-0.75H10.75z"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_phone.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_phone.xml index ac47a86abb6e..e3534d63d6e6 100644 --- a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_phone.xml +++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_phone.xml @@ -1,30 +1,20 @@ + <!-- -/** - * 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. - */ + 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,18.06a3.22,3.22,0,0,0-5.49-2.28L13.26,18A17.13,17.13,0,0,1,9.2,15.1,18.37,18.37,0,0,1,6,10.69L8.22,8.48A3.19,3.19,0,0,0,9,5.33,3.24,3.24,0,0,0,6,3H3.49s0,0,0,0L3.39,3l-0.1,0-0.07 0.05 -0.08 0.06 a0.35 0.35 ,0,0,0-0.05 0.08 A0.35 0.35 ,0,0,0,3,3.3a0.36 0.36 ,0,0,0,0,0.1 0.24 0.24,0,0,0,0,0.08v0H3a19.11,19.11,0,0,0,5.5,12.3,18.38,18.38,0,0,0,12,5.2h0a0.58 0.58 ,0,0,0,0.19,0,0.18 0.18 ,0,0,0,0.07-0.05l0.09-0.06,0-0.07a0.35 0.35 ,0,0,0,0.05-0.08 0.29 0.29,0,0,0,0-0.1s0-0.05,0-0.08h0ZM4.06,4H6A2.22,2.22,0,0,1,7.52,7.78l-2,2A18.05,18.05,0,0,1,4.06,4ZM14.21,18.5l2-2A2.22,2.22,0,0,1,20,18.06V20A17.64,17.64,0,0,1,14.21,18.5Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M9.71,4.56C9.28,3.06,7.89,2,6.32,2L3,1.99l0.05,0.8c0.29,4.81,2.32,9.34,5.71,12.77c3.35,3.26,7.77,5.18,12.45,5.41 L21.99,21v-3.31c0-1.56-1.04-2.96-2.54-3.39c-1.24-0.36-2.58-0.02-3.5,0.89l-2.19,2.19c-1.43-0.77-2.76-1.74-3.95-2.89 c-1.27-1.28-2.33-2.73-3.16-4.3l2.16-2.16C9.72,7.13,10.06,5.8,9.71,4.56z M17.01,16.25c0.53-0.53,1.3-0.73,2.02-0.51 c0.86,0.25,1.46,1.06,1.46,1.96v1.72c-1.84-0.17-3.62-0.62-5.3-1.34L17.01,16.25z M7.75,6.98L5.97,8.76 C5.26,7.09,4.8,5.32,4.61,3.49l1.71,0c0.9,0,1.7,0.61,1.95,1.48C8.47,5.69,8.27,6.45,7.75,6.98z"/> </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..0908925b774e --- /dev/null +++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_qs_airplane.xml @@ -0,0 +1,20 @@ + +<!-- + 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 android:height="18dp" android:viewportHeight="24" android:viewportWidth="24" android:width="18dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <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..239893d7dd82 --- /dev/null +++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_qs_auto_rotate.xml @@ -0,0 +1,21 @@ + +<!-- + 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 android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <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/IconPackCircularAndroidOverlay/res/drawable/ic_qs_bluetooth.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_qs_bluetooth.xml new file mode 100644 index 000000000000..ba0dfc64696d --- /dev/null +++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_qs_bluetooth.xml @@ -0,0 +1,20 @@ + +<!-- + 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 android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <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_dnd.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_qs_dnd.xml new file mode 100644 index 000000000000..0c309c887e77 --- /dev/null +++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_qs_dnd.xml @@ -0,0 +1,21 @@ + +<!-- + 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 android:height="17dp" android:viewportHeight="24" android:viewportWidth="24" android:width="17dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path 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: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/IconPackCircularAndroidOverlay/res/drawable/ic_qs_flashlight.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_qs_flashlight.xml new file mode 100644 index 000000000000..9c21da6bb952 --- /dev/null +++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_qs_flashlight.xml @@ -0,0 +1,21 @@ + +<!-- + 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 android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path 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: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_qs_night_display_on.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_qs_night_display_on.xml index 8ee7e2fc7666..fa2538190ffb 100644 --- a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_qs_night_display_on.xml +++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_qs_night_display_on.xml @@ -1,30 +1,20 @@ + <!-- -/** - * 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. - */ + 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.36,15.7a0.51 0.51 ,0,0,0-0.51-0.22,11.59,11.59,0,0,1-2.07 0.2 A11.5,11.5,0,0,1,8.31,4.17a10.91,10.91,0,0,1,0.2-2.08 0.51 0.51,0,0,0-0.22-0.51 0.5 0.5,0,0,0-0.55,0A10.57,10.57,0,1,0,22.36,16.25 0.5 0.5,0,0,0,22.36,15.7ZM13.55,20A9.59,9.59,0,0,1,7.36,3.12a9.34,9.34,0,0,0-0.05,1A12.46,12.46,0,0,0,20.82,16.63,9.49,9.49,0,0,1,13.55,20Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M22.88,16.06c-0.17-0.25-0.46-0.38-0.76-0.32c-0.75,0.14-1.46,0.2-2.15,0.2c-6.57,0-11.91-5.34-11.91-11.91 c0-0.69,0.07-1.4,0.2-2.15c0.05-0.3-0.07-0.59-0.32-0.76c-0.25-0.17-0.58-0.17-0.83,0C3.91,3.24,2,6.79,2,10.62 C2,16.89,7.11,22,13.38,22c3.83,0,7.38-1.91,9.49-5.11C23.04,16.64,23.04,16.31,22.88,16.06z M13.38,20.5 c-5.45,0-9.88-4.43-9.88-9.88c0-2.73,1.12-5.3,3.07-7.15C6.56,3.66,6.56,3.85,6.56,4.04c0,7.58,6.36,13.75,13.98,13.39 C18.69,19.38,16.12,20.5,13.38,20.5z"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_restart.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_restart.xml new file mode 100644 index 000000000000..d4fdaddae52e --- /dev/null +++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_restart.xml @@ -0,0 +1,21 @@ + +<!-- + 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 android:height="24dp" android:tint="?android:attr/colorControlNormal" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M12.03,2.96c-0.29-0.29-0.77-0.29-1.06,0L7.94,6l3.04,3.04c0.15,0.15,0.34,0.22,0.53,0.22s0.38-0.07,0.53-0.22 c0.29-0.29,0.29-0.77,0-1.06l-1.37-1.37C11.1,6.52,11.55,6.47,12,6.47c3.58,0,6.5,2.92,6.5,6.5c0,3.05-2.07,5.66-5.04,6.33 c-0.4,0.09-0.66,0.5-0.56,0.9c0.08,0.35,0.39,0.58,0.73,0.58c0.06,0,0.11-0.01,0.17-0.02c3.65-0.84,6.21-4.04,6.21-7.8 c0-4.41-3.59-8-8-8c-0.33,0-0.65,0.03-0.98,0.07l1.01-1.01C12.33,3.73,12.33,3.26,12.03,2.96z"/> + <path android:fillColor="@android:color/white" android:pathData="M7,7.66C6.69,7.39,6.22,7.42,5.95,7.74C4.69,9.19,4,11.05,4,12.97c0,3.75,2.55,6.96,6.21,7.8 c0.06,0.01,0.11,0.02,0.17,0.02c0.34,0,0.65-0.24,0.73-0.58c0.09-0.4-0.16-0.81-0.56-0.9c-2.97-0.68-5.04-3.29-5.04-6.33 c0-1.56,0.56-3.07,1.58-4.25C7.35,8.41,7.32,7.93,7,7.66z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_screenshot.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_screenshot.xml new file mode 100644 index 000000000000..7b07000407d4 --- /dev/null +++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_screenshot.xml @@ -0,0 +1,22 @@ + +<!-- + 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 android:height="24dp" android:tint="?android:attr/colorControlNormal" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M15,22c1.66,0,3-1.34,3-3V5c0-1.66-1.34-3-3-3H9C7.34,2,6,3.34,6,5v14c0,1.66,1.34,3,3,3H15z M7.5,6.5h9v11h-9V6.5z M9,3.5 h6c0.83,0,1.5,0.67,1.5,1.5h-9C7.5,4.17,8.17,3.5,9,3.5z M7.5,19h9c0,0.83-0.67,1.5-1.5,1.5H9C8.17,20.5,7.5,19.83,7.5,19z"/> + <path android:fillColor="@android:color/white" android:pathData="M13,8.25c0-0.41-0.34-0.75-0.75-0.75H8.5v3.75C8.5,11.66,8.84,12,9.25,12S10,11.66,10,11.25V9h2.25 C12.66,9,13,8.66,13,8.25z"/> + <path android:fillColor="@android:color/white" android:pathData="M14.75,12C14.34,12,14,12.34,14,12.75V15h-2.25C11.34,15,11,15.34,11,15.75s0.34,0.75,0.75,0.75h3.75v-3.75 C15.5,12.34,15.16,12,14.75,12z"/> +</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..ba0dfc64696d --- /dev/null +++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_settings_bluetooth.xml @@ -0,0 +1,20 @@ + +<!-- + 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 android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <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_signal_location.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_signal_location.xml index 25535c7bfc3e..f16fbc1ccb91 100644 --- a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_signal_location.xml +++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_signal_location.xml @@ -1,33 +1,21 @@ + <!-- -/** - * 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. - */ + 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="M12,21.5s7-5.34,7-11.25A7.13,7.13,0,0,0,12,3a7.13,7.13,0,0,0-7,7.25C5,16.16,12,21.5,12,21.5ZM12,4a6.13,6.13,0,0,1,6,6.25c0,4.37-4.37,8.54-6,10-1.63-1.4-6-5.57-6-9.95A6.13,6.13,0,0,1,12,4Z" /> - <path - android:fillColor="#000000" - android:pathData="M15,10a3,3,0,1,0-3,3A3,3,0,0,0,15,10Zm-5,0a2,2,0,1,1,2,2A2,2,0,0,1,10,10Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M12,21.5c0,0,7-5.34,7-11.25c0-4-3.13-7.25-7-7.25c-3.87,0-7,3.25-7,7.25C5,16.16,12,21.5,12,21.5z M12,4.5 c3.03,0,5.5,2.58,5.5,5.75c0,3.91-3.74,7.72-5.51,9.29C9.9,17.68,6.5,13.89,6.5,10.25C6.5,7.08,8.97,4.5,12,4.5z"/> + <path android:fillColor="@android:color/white" android:pathData="M15,10c0-1.66-1.34-3-3-3c-1.66,0-3,1.34-3,3c0,1.66,1.34,3,3,3C13.66,13,15,11.66,15,10z M10.5,10 c0-0.83,0.67-1.5,1.5-1.5s1.5,0.67,1.5,1.5s-0.67,1.5-1.5,1.5S10.5,10.83,10.5,10z"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_wifi_signal_0.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_wifi_signal_0.xml index b73fcb25d7f6..6afdbcb589a1 100644 --- a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_wifi_signal_0.xml +++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_wifi_signal_0.xml @@ -1,51 +1,23 @@ + <!-- -/** - * 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. - */ + 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:fillAlpha="0.3" - android:strokeAlpha="0.3" - android:strokeWidth="1" - android:pathData="M 11.99 16.5 C 12.8184271247 16.5 13.49 17.1715728753 13.49 18 C 13.49 18.8284271247 12.8184271247 19.5 11.99 19.5 C 11.1615728753 19.5 10.49 18.8284271247 10.49 18 C 10.49 17.1715728753 11.1615728753 16.5 11.99 16.5 Z" /> - <path - android:fillColor="#000000" - android:fillAlpha="0.3" - android:strokeAlpha="0.3" - android:strokeWidth="1" - android:pathData="M18.76,11.8a0.54 0.54 ,0,0,0,0.36-0.14 0.51 0.51,0,0,0,0-0.71A10.08,10.08,0,0,0,4.87,11a0.5 0.5 ,0,0,0,0,0.71 0.51 0.51,0,0,0,0.71,0,9.07,9.07,0,0,1,12.83,0A0.54 0.54 ,0,0,0,18.76,11.8Z" /> - <path - android:fillColor="#000000" - android:fillAlpha="0.3" - android:strokeAlpha="0.3" - android:strokeWidth="1" - android:pathData="M2.15,8.85a0.48 0.48 ,0,0,0,0.7,0,12.8,12.8,0,0,1,18.3,0,0.48 0.48 ,0,0,0,0.7,0,0.48 0.48 ,0,0,0,0-0.7,13.77,13.77,0,0,0-19.7,0A0.48 0.48 ,0,0,0,2.15,8.85Z" /> - <path - android:fillColor="#000000" - android:fillAlpha="0.3" - android:strokeAlpha="0.3" - android:strokeWidth="1" - android:pathData="M15.93,14.64a0.49 0.49 ,0,0,0,0.35-0.15 0.5 0.5,0,0,0,0-0.71,6.08,6.08,0,0,0-8.58,0,0.51 0.51 ,0,0,0,0,0.71 0.5 0.5,0,0,0,0.71,0,5.08,5.08,0,0,1,7.16,0A0.51 0.51 ,0,0,0,15.93,14.64Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillAlpha="0.3" android:fillColor="@android:color/white" android:pathData="M 12 17 C 12.8284271247 17 13.5 17.6715728753 13.5 18.5 C 13.5 19.3284271247 12.8284271247 20 12 20 C 11.1715728753 20 10.5 19.3284271247 10.5 18.5 C 10.5 17.6715728753 11.1715728753 17 12 17 Z" android:strokeAlpha="0.3" android:strokeWidth="1"/> + <path android:fillAlpha="0.3" android:fillColor="@android:color/white" android:pathData="M19.42,11.84c-0.19,0-0.38-0.07-0.53-0.22C17.05,9.77,14.6,8.75,12,8.75s-5.05,1.02-6.89,2.86 c-0.29,0.29-0.77,0.29-1.06,0c-0.29-0.29-0.29-0.77,0-1.06C6.17,8.43,9,7.25,12,7.25s5.83,1.17,7.95,3.3 c0.29,0.29,0.29,0.77,0,1.06C19.8,11.76,19.61,11.84,19.42,11.84z" android:strokeAlpha="0.3" android:strokeWidth="1"/> + <path android:fillAlpha="0.3" android:fillColor="@android:color/white" android:pathData="M22.61,8.65c-0.19,0-0.38-0.07-0.53-0.22C19.38,5.74,15.81,4.25,12,4.25S4.62,5.74,1.92,8.43c-0.29,0.29-0.77,0.29-1.06,0 s-0.29-0.77,0-1.06C3.84,4.39,7.79,2.75,12,2.75s8.16,1.64,11.14,4.61c0.29,0.29,0.29,0.77,0,1.06 C22.99,8.57,22.8,8.65,22.61,8.65z" android:strokeAlpha="0.3" android:strokeWidth="1"/> + <path android:fillAlpha="0.3" android:fillColor="@android:color/white" android:pathData="M16.25,15c-0.19,0-0.38-0.07-0.53-0.22c-1-0.99-2.32-1.53-3.73-1.53c-1.41,0-2.73,0.54-3.73,1.53 c-0.29,0.29-0.77,0.29-1.06-0.01c-0.29-0.29-0.29-0.77,0.01-1.06c1.28-1.27,2.98-1.96,4.78-1.96c1.8,0,3.5,0.7,4.78,1.96 c0.29,0.29,0.3,0.77,0.01,1.06C16.64,14.93,16.45,15,16.25,15z" android:strokeAlpha="0.3" android:strokeWidth="1"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_wifi_signal_1.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_wifi_signal_1.xml index 69b1bd8683f7..20baa6329f4c 100644 --- a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_wifi_signal_1.xml +++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_wifi_signal_1.xml @@ -1,48 +1,23 @@ + <!-- -/** - * 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. - */ + 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="M 11.99 16.5 C 12.8184271247 16.5 13.49 17.1715728753 13.49 18 C 13.49 18.8284271247 12.8184271247 19.5 11.99 19.5 C 11.1615728753 19.5 10.49 18.8284271247 10.49 18 C 10.49 17.1715728753 11.1615728753 16.5 11.99 16.5 Z" /> - <path - android:fillColor="#000000" - android:fillAlpha="0.3" - android:strokeAlpha="0.3" - android:strokeWidth="1" - android:pathData="M18.76,11.8a0.54 0.54 ,0,0,0,0.36-0.14 0.51 0.51,0,0,0,0-0.71A10.08,10.08,0,0,0,4.87,11a0.5 0.5 ,0,0,0,0,0.71 0.51 0.51,0,0,0,0.71,0,9.07,9.07,0,0,1,12.83,0A0.54 0.54 ,0,0,0,18.76,11.8Z" /> - <path - android:fillColor="#000000" - android:fillAlpha="0.3" - android:strokeAlpha="0.3" - android:strokeWidth="1" - android:pathData="M21.85,8.15a13.77,13.77,0,0,0-19.7,0,0.49 0.49 ,0,0,0,0.7 0.7 ,12.8,12.8,0,0,1,18.3,0,0.48 0.48 ,0,0,0,0.7,0A0.48 0.48 ,0,0,0,21.85,8.15Z" /> - <path - android:fillColor="#000000" - android:fillAlpha="0.3" - android:strokeAlpha="0.3" - android:strokeWidth="1" - android:pathData="M15.93,14.64a0.49 0.49 ,0,0,0,0.35-0.15 0.5 0.5,0,0,0,0-0.71,6.08,6.08,0,0,0-8.58,0,0.51 0.51 ,0,0,0,0,0.71 0.5 0.5,0,0,0,0.71,0,5.08,5.08,0,0,1,7.16,0A0.51 0.51 ,0,0,0,15.93,14.64Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M 12 17 C 12.8284271247 17 13.5 17.6715728753 13.5 18.5 C 13.5 19.3284271247 12.8284271247 20 12 20 C 11.1715728753 20 10.5 19.3284271247 10.5 18.5 C 10.5 17.6715728753 11.1715728753 17 12 17 Z"/> + <path android:fillAlpha="0.3" android:fillColor="@android:color/white" android:pathData="M19.42,11.84c-0.19,0-0.38-0.07-0.53-0.22C17.05,9.77,14.6,8.75,12,8.75s-5.05,1.02-6.89,2.86 c-0.29,0.29-0.77,0.29-1.06,0c-0.29-0.29-0.29-0.77,0-1.06C6.17,8.43,9,7.25,12,7.25s5.83,1.17,7.95,3.3 c0.29,0.29,0.29,0.77,0,1.06C19.8,11.76,19.61,11.84,19.42,11.84z" android:strokeAlpha="0.3" android:strokeWidth="1"/> + <path android:fillAlpha="0.3" android:fillColor="@android:color/white" android:pathData="M22.61,8.65c-0.19,0-0.38-0.07-0.53-0.22C19.38,5.74,15.81,4.25,12,4.25S4.62,5.74,1.92,8.43 c-0.29,0.29-0.77,0.29-1.06,0s-0.29-0.77,0-1.06C3.84,4.39,7.79,2.75,12,2.75s8.16,1.64,11.14,4.61c0.29,0.29,0.29,0.77,0,1.06 C22.99,8.57,22.8,8.65,22.61,8.65z" android:strokeAlpha="0.3" android:strokeWidth="1"/> + <path android:fillAlpha="0.3" android:fillColor="@android:color/white" android:pathData="M16.25,15c-0.19,0-0.38-0.07-0.53-0.22c-1-0.99-2.32-1.53-3.73-1.53c-1.41,0-2.73,0.54-3.73,1.53 c-0.29,0.29-0.77,0.29-1.06-0.01c-0.29-0.29-0.29-0.77,0.01-1.06c1.28-1.27,2.98-1.96,4.78-1.96c1.8,0,3.5,0.7,4.78,1.96 c0.29,0.29,0.3,0.77,0.01,1.06C16.64,14.93,16.45,15,16.25,15z" android:strokeAlpha="0.3" android:strokeWidth="1"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_wifi_signal_2.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_wifi_signal_2.xml index 353fccb53e57..b50bddedd8de 100644 --- a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_wifi_signal_2.xml +++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_wifi_signal_2.xml @@ -1,45 +1,23 @@ + <!-- -/** - * 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. - */ + 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="M 11.99 16.5 C 12.8184271247 16.5 13.49 17.1715728753 13.49 18 C 13.49 18.8284271247 12.8184271247 19.5 11.99 19.5 C 11.1615728753 19.5 10.49 18.8284271247 10.49 18 C 10.49 17.1715728753 11.1615728753 16.5 11.99 16.5 Z" /> - <path - android:fillColor="#000000" - android:fillAlpha="0.3" - android:strokeAlpha="0.3" - android:strokeWidth="1" - android:pathData="M18.76,11.8a0.54 0.54 ,0,0,0,0.36-0.14 0.51 0.51,0,0,0,0-0.71A10.08,10.08,0,0,0,4.87,11a0.5 0.5 ,0,0,0,0,0.71 0.51 0.51,0,0,0,0.71,0,9.07,9.07,0,0,1,12.83,0A0.54 0.54 ,0,0,0,18.76,11.8Z" /> - <path - android:fillColor="#000000" - android:fillAlpha="0.3" - android:strokeAlpha="0.3" - android:strokeWidth="1" - android:pathData="M21.85,8.15a13.77,13.77,0,0,0-19.7,0,0.49 0.49 ,0,0,0,0.7 0.7 ,12.8,12.8,0,0,1,18.3,0,0.48 0.48 ,0,0,0,0.7,0A0.48 0.48 ,0,0,0,21.85,8.15Z" /> - <path - android:fillColor="#000000" - android:pathData="M15.93,14.64a0.49 0.49 ,0,0,0,0.35-0.15 0.5 0.5,0,0,0,0-0.71,6.08,6.08,0,0,0-8.58,0,0.51 0.51 ,0,0,0,0,0.71 0.5 0.5,0,0,0,0.71,0,5.07,5.07,0,0,1,7.16,0A0.51 0.51 ,0,0,0,15.93,14.64Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M 12 17 C 12.8284271247 17 13.5 17.6715728753 13.5 18.5 C 13.5 19.3284271247 12.8284271247 20 12 20 C 11.1715728753 20 10.5 19.3284271247 10.5 18.5 C 10.5 17.6715728753 11.1715728753 17 12 17 Z"/> + <path android:fillAlpha="0.3" android:fillColor="@android:color/white" android:pathData="M19.42,11.84c-0.19,0-0.38-0.07-0.53-0.22C17.05,9.77,14.6,8.75,12,8.75s-5.05,1.02-6.89,2.86 c-0.29,0.29-0.77,0.29-1.06,0c-0.29-0.29-0.29-0.77,0-1.06C6.17,8.43,9,7.25,12,7.25s5.83,1.17,7.95,3.3 c0.29,0.29,0.29,0.77,0,1.06C19.8,11.76,19.61,11.84,19.42,11.84z" android:strokeAlpha="0.3" android:strokeWidth="1"/> + <path android:fillAlpha="0.3" android:fillColor="@android:color/white" android:pathData="M22.61,8.65c-0.19,0-0.38-0.07-0.53-0.22C19.38,5.74,15.81,4.25,12,4.25S4.62,5.74,1.92,8.43c-0.29,0.29-0.77,0.29-1.06,0 s-0.29-0.77,0-1.06C3.84,4.39,7.79,2.75,12,2.75s8.16,1.64,11.14,4.61c0.29,0.29,0.29,0.77,0,1.06 C22.99,8.57,22.8,8.65,22.61,8.65z" android:strokeAlpha="0.3" android:strokeWidth="1"/> + <path android:fillColor="@android:color/white" android:pathData="M16.25,15c-0.19,0-0.38-0.07-0.53-0.22c-1-0.99-2.32-1.53-3.73-1.53s-2.73,0.54-3.73,1.53c-0.29,0.29-0.77,0.29-1.06-0.01 s-0.29-0.77,0.01-1.06c1.28-1.27,2.98-1.96,4.78-1.96s3.5,0.7,4.78,1.96c0.29,0.29,0.3,0.77,0.01,1.06 C16.64,14.93,16.45,15,16.25,15z"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_wifi_signal_3.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_wifi_signal_3.xml index a8bade5cef58..9398c69c7e26 100644 --- a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_wifi_signal_3.xml +++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_wifi_signal_3.xml @@ -1,42 +1,23 @@ + <!-- -/** - * 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. - */ + 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="M 11.99 16.5 C 12.8184271247 16.5 13.49 17.1715728753 13.49 18 C 13.49 18.8284271247 12.8184271247 19.5 11.99 19.5 C 11.1615728753 19.5 10.49 18.8284271247 10.49 18 C 10.49 17.1715728753 11.1615728753 16.5 11.99 16.5 Z" /> - <path - android:fillColor="#000000" - android:pathData="M18.76,11.8a0.54 0.54 ,0,0,0,0.36-0.14 0.51 0.51,0,0,0,0-0.71A10.08,10.08,0,0,0,4.87,11a0.5 0.5 ,0,0,0,0,0.71 0.51 0.51,0,0,0,0.71,0,9.07,9.07,0,0,1,12.83,0A0.54 0.54 ,0,0,0,18.76,11.8Z" /> - <path - android:fillColor="#000000" - android:fillAlpha="0.3" - android:strokeAlpha="0.3" - android:strokeWidth="1" - android:pathData="M21.5,9a0.47 0.47 ,0,0,0,0.35-0.15 0.48 0.48,0,0,0,0-0.7,13.77,13.77,0,0,0-19.7,0,0.49 0.49 ,0,0,0,0.7 0.7 ,12.8,12.8,0,0,1,18.3,0A0.47 0.47 ,0,0,0,21.5,9Z" /> - <path - android:fillColor="#000000" - android:pathData="M15.93,14.64a0.49 0.49 ,0,0,0,0.35-0.15 0.5 0.5,0,0,0,0-0.71,6.08,6.08,0,0,0-8.58,0,0.51 0.51 ,0,0,0,0,0.71 0.5 0.5,0,0,0,0.71,0,5.07,5.07,0,0,1,7.16,0A0.51 0.51 ,0,0,0,15.93,14.64Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M 12 17 C 12.8284271247 17 13.5 17.6715728753 13.5 18.5 C 13.5 19.3284271247 12.8284271247 20 12 20 C 11.1715728753 20 10.5 19.3284271247 10.5 18.5 C 10.5 17.6715728753 11.1715728753 17 12 17 Z"/> + <path android:fillColor="@android:color/white" android:pathData="M19.42,11.84c-0.19,0-0.38-0.07-0.53-0.22C17.05,9.77,14.6,8.75,12,8.75s-5.05,1.02-6.89,2.86 c-0.29,0.29-0.77,0.29-1.06,0c-0.29-0.29-0.29-0.77,0-1.06C6.17,8.43,9,7.25,12,7.25s5.83,1.17,7.95,3.3 c0.29,0.29,0.29,0.77,0,1.06C19.8,11.76,19.61,11.84,19.42,11.84z"/> + <path android:fillAlpha="0.3" android:fillColor="@android:color/white" android:pathData="M22.61,8.65c-0.19,0-0.38-0.07-0.53-0.22C19.38,5.74,15.81,4.25,12,4.25S4.62,5.74,1.92,8.43c-0.29,0.29-0.77,0.29-1.06,0 s-0.29-0.77,0-1.06C3.84,4.39,7.79,2.75,12,2.75s8.16,1.64,11.14,4.61c0.29,0.29,0.29,0.77,0,1.06 C22.99,8.57,22.8,8.65,22.61,8.65z" android:strokeAlpha="0.3" android:strokeWidth="1"/> + <path android:fillColor="@android:color/white" android:pathData="M16.25,15c-0.19,0-0.38-0.07-0.53-0.22c-1-0.99-2.32-1.53-3.73-1.53s-2.73,0.54-3.73,1.53c-0.29,0.29-0.77,0.29-1.06-0.01 s-0.29-0.77,0.01-1.06c1.28-1.27,2.98-1.96,4.78-1.96s3.5,0.7,4.78,1.96c0.29,0.29,0.3,0.77,0.01,1.06 C16.64,14.93,16.45,15,16.25,15z"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_wifi_signal_4.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_wifi_signal_4.xml index a4afffd6dbfd..c66a406d5b59 100644 --- a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_wifi_signal_4.xml +++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_wifi_signal_4.xml @@ -1,39 +1,23 @@ + <!-- -/** - * 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. - */ + 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="M 11.99 16.5 C 12.8184271247 16.5 13.49 17.1715728753 13.49 18 C 13.49 18.8284271247 12.8184271247 19.5 11.99 19.5 C 11.1615728753 19.5 10.49 18.8284271247 10.49 18 C 10.49 17.1715728753 11.1615728753 16.5 11.99 16.5 Z" /> - <path - android:fillColor="#000000" - android:pathData="M18.76,11.8a0.54 0.54 ,0,0,0,0.36-0.14 0.51 0.51,0,0,0,0-0.71A10.08,10.08,0,0,0,4.87,11a0.5 0.5 ,0,0,0,0,0.71 0.51 0.51,0,0,0,0.71,0,9.07,9.07,0,0,1,12.83,0A0.54 0.54 ,0,0,0,18.76,11.8Z" /> - <path - android:fillColor="#000000" - android:pathData="M21.5,9a0.47 0.47 ,0,0,0,0.35-0.15 0.48 0.48,0,0,0,0-0.7,13.77,13.77,0,0,0-19.7,0,0.49 0.49 ,0,0,0,0.7 0.7 ,12.8,12.8,0,0,1,18.3,0A0.47 0.47 ,0,0,0,21.5,9Z" /> - <path - android:fillColor="#000000" - android:pathData="M15.93,14.64a0.49 0.49 ,0,0,0,0.35-0.15 0.5 0.5,0,0,0,0-0.71,6.08,6.08,0,0,0-8.58,0,0.51 0.51 ,0,0,0,0,0.71 0.5 0.5,0,0,0,0.71,0,5.08,5.08,0,0,1,7.16,0A0.51 0.51 ,0,0,0,15.93,14.64Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M 12 17 C 12.8284271247 17 13.5 17.6715728753 13.5 18.5 C 13.5 19.3284271247 12.8284271247 20 12 20 C 11.1715728753 20 10.5 19.3284271247 10.5 18.5 C 10.5 17.6715728753 11.1715728753 17 12 17 Z"/> + <path android:fillColor="@android:color/white" android:pathData="M19.42,11.84c-0.19,0-0.38-0.07-0.53-0.22C17.05,9.77,14.6,8.75,12,8.75s-5.05,1.02-6.89,2.86 c-0.29,0.29-0.77,0.29-1.06,0c-0.29-0.29-0.29-0.77,0-1.06C6.17,8.43,9,7.25,12,7.25s5.83,1.17,7.95,3.3 c0.29,0.29,0.29,0.77,0,1.06C19.8,11.76,19.61,11.84,19.42,11.84z"/> + <path android:fillColor="@android:color/white" android:pathData="M22.61,8.65c-0.19,0-0.38-0.07-0.53-0.22C19.38,5.74,15.81,4.25,12,4.25S4.62,5.74,1.92,8.43c-0.29,0.29-0.77,0.29-1.06,0 s-0.29-0.77,0-1.06C3.84,4.39,7.79,2.75,12,2.75s8.16,1.64,11.14,4.61c0.29,0.29,0.29,0.77,0,1.06 C22.99,8.57,22.8,8.65,22.61,8.65z"/> + <path android:fillColor="@android:color/white" android:pathData="M16.25,15c-0.19,0-0.38-0.07-0.53-0.22c-1-0.99-2.32-1.53-3.73-1.53c-1.41,0-2.73,0.54-3.73,1.53 c-0.29,0.29-0.77,0.29-1.06-0.01c-0.29-0.29-0.29-0.77,0.01-1.06c1.28-1.27,2.98-1.96,4.78-1.96c1.8,0,3.5,0.7,4.78,1.96 c0.29,0.29,0.3,0.77,0.01,1.06C16.64,14.93,16.45,15,16.25,15z"/> </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..6212a5135769 --- /dev/null +++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_airplanemode_active.xml @@ -0,0 +1,20 @@ + +<!-- + 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 android:height="24dp" android:tint="?android:attr/colorControlNormal" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <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/IconPackCircularSettingsOverlay/res/drawable/ic_apps.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_apps.xml index dbac48dfbf35..d11d2c28f1da 100644 --- a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_apps.xml +++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_apps.xml @@ -1,54 +1,28 @@ + <!-- -/** - * 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. - */ + 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="#FFFFFF" - android:pathData="M6,4A2,2,0,0,0,6,8H7.5A0.5 0.5 ,0,0,0,8,7.5V6A2,2,0,0,0,6,4Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M12,8h1.5a0.5 0.5 ,0,0,0,0.5-0.5V6a2,2,0,1,0-2,2Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M20,6a2,2,0,1,0-2,2h1.5a0.5 0.5 ,0,0,0,0.5-0.5Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M6,14H7.5a0.5 0.5 ,0,0,0,0.5-0.5V12a2,2,0,1,0-2,2Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M12,14h1.5a0.5 0.5 ,0,0,0,0.5-0.5V12a2,2,0,1,0-2,2Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M20,12a2,2,0,1,0-2,2h1.5a0.5 0.5 ,0,0,0,0.5-0.5Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M6,20H7.5a0.5 0.5 ,0,0,0,0.5-0.5V18a2,2,0,1,0-2,2Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M12,20h1.5a0.5 0.5 ,0,0,0,0.5-0.5V18a2,2,0,1,0-2,2Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M20,18a2,2,0,1,0-2,2h1.5a0.5 0.5 ,0,0,0,0.5-0.5Z" /> -</vector> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M 6 4 C 7.10456949966 4 8 4.89543050034 8 6 C 8 7.10456949966 7.10456949966 8 6 8 C 4.89543050034 8 4 7.10456949966 4 6 C 4 4.89543050034 4.89543050034 4 6 4 Z"/> + <path android:fillColor="@android:color/white" android:pathData="M 12 4 C 13.1045694997 4 14 4.89543050034 14 6 C 14 7.10456949966 13.1045694997 8 12 8 C 10.8954305003 8 10 7.10456949966 10 6 C 10 4.89543050034 10.8954305003 4 12 4 Z"/> + <path android:fillColor="@android:color/white" android:pathData="M 18 4 C 19.1045694997 4 20 4.89543050034 20 6 C 20 7.10456949966 19.1045694997 8 18 8 C 16.8954305003 8 16 7.10456949966 16 6 C 16 4.89543050034 16.8954305003 4 18 4 Z"/> + <path android:fillColor="@android:color/white" android:pathData="M 6 10 C 7.10456949966 10 8 10.8954305003 8 12 C 8 13.1045694997 7.10456949966 14 6 14 C 4.89543050034 14 4 13.1045694997 4 12 C 4 10.8954305003 4.89543050034 10 6 10 Z"/> + <path android:fillColor="@android:color/white" android:pathData="M 12 10 C 13.1045694997 10 14 10.8954305003 14 12 C 14 13.1045694997 13.1045694997 14 12 14 C 10.8954305003 14 10 13.1045694997 10 12 C 10 10.8954305003 10.8954305003 10 12 10 Z"/> + <path android:fillColor="@android:color/white" android:pathData="M 18 10 C 19.1045694997 10 20 10.8954305003 20 12 C 20 13.1045694997 19.1045694997 14 18 14 C 16.8954305003 14 16 13.1045694997 16 12 C 16 10.8954305003 16.8954305003 10 18 10 Z"/> + <path android:fillColor="@android:color/white" android:pathData="M 6 16 C 7.10456949966 16 8 16.8954305003 8 18 C 8 19.1045694997 7.10456949966 20 6 20 C 4.89543050034 20 4 19.1045694997 4 18 C 4 16.8954305003 4.89543050034 16 6 16 Z"/> + <path android:fillColor="@android:color/white" android:pathData="M 12 16 C 13.1045694997 16 14 16.8954305003 14 18 C 14 19.1045694997 13.1045694997 20 12 20 C 10.8954305003 20 10 19.1045694997 10 18 C 10 16.8954305003 10.8954305003 16 12 16 Z"/> + <path android:fillColor="@android:color/white" android:pathData="M 18 16 C 19.1045694997 16 20 16.8954305003 20 18 C 20 19.1045694997 19.1045694997 20 18 20 C 16.8954305003 20 16 19.1045694997 16 18 C 16 16.8954305003 16.8954305003 16 18 16 Z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_data_saver.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_data_saver.xml new file mode 100644 index 000000000000..ccbaecd28584 --- /dev/null +++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_data_saver.xml @@ -0,0 +1,22 @@ + +<!-- + 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 android:height="24dp" android:tint="?android:attr/colorControlNormal" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M12,7a0.76 0.76 ,0,0,0-0.75 0.75 v3.5H7.75a0.75 0.75 ,0,0,0,0,1.5h3.5v3.5a0.75 0.75 ,0,0,0,1.5,0v-3.5h3.5a0.75 0.75 ,0,0,0,0-1.5h-3.5V7.75A0.76 0.76 ,0,0,0,12,7Z"/> + <path android:fillColor="@android:color/white" android:pathData="M3.36,7A10,10,0,0,0,20.27,17.64L18.1,16.39A7.5,7.5,0,1,1,11.25,4.56V2.05A10,10,0,0,0,3.36,7Z"/> + <path android:fillColor="@android:color/white" android:pathData="M21,16.35a10,10,0,0,0-8.27-14.3V4.56a7.48,7.48,0,0,1,6.1,10.54Z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_devices_other.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_devices_other.xml index a407bd6539f6..c64995c07e8f 100644 --- a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_devices_other.xml +++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_devices_other.xml @@ -1,36 +1,22 @@ + <!-- -/** - * 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. - */ + 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="#FFFFFF" - android:pathData="M2,16.5A2.5,2.5,0,0,0,4.5,19h2a0.5 0.5 ,0,0,0,0-1h-2A1.5,1.5,0,0,1,3,16.5v-9A1.5,1.5,0,0,1,4.5,6h17a0.5 0.5 ,0,0,0,0-1H4.5A2.5,2.5,0,0,0,2,7.5Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M14,16a3,3,0,1,0-3,3A3,3,0,0,0,14,16ZM9,16a2,2,0,1,1,2,2A2,2,0,0,1,9,16Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M22,17V10a2,2,0,0,0-2-2H17a2,2,0,0,0-2,2v7a2,2,0,0,0,2,2h3A2,2,0,0,0,22,17Zm-6,0V10a1,1,0,0,1,1-1h3a1,1,0,0,1,1,1v7a1,1,0,0,1-1,1H17A1,1,0,0,1,16,17Z" /> -</vector> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M7.25,18.25c0-0.41-0.34-0.75-0.75-0.75H3V8.25C3,7.01,4.01,6,5.25,6h16C21.66,6,22,5.66,22,5.25S21.66,4.5,21.25,4.5h-16 C3.18,4.5,1.5,6.18,1.5,8.25V19h5C6.91,19,7.25,18.66,7.25,18.25z"/> + <path android:fillColor="@android:color/white" android:pathData="M14,16c0-1.66-1.34-3-3-3s-3,1.34-3,3s1.34,3,3,3S14,17.66,14,16z M9.5,16c0-0.83,0.67-1.5,1.5-1.5s1.5,0.67,1.5,1.5 s-0.67,1.5-1.5,1.5S9.5,16.83,9.5,16z"/> + <path android:fillColor="@android:color/white" android:pathData="M20,19c1.1,0,2-0.9,2-2v-7c0-1.1-0.9-2-2-2h-3c-1.1,0-2,0.9-2,2v7c0,1.1,0.9,2,2,2H20z M16.5,17v-7 c0-0.28,0.22-0.5,0.5-0.5h3c0.28,0,0.5,0.22,0.5,0.5v7c0,0.28-0.22,0.5-0.5,0.5h-3C16.72,17.5,16.5,17.28,16.5,17z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_help.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_help.xml index c9068478487f..3945ce5c6780 100644 --- a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_help.xml +++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_help.xml @@ -1,36 +1,22 @@ + <!-- -/** - * 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. - */ + 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="#FFFFFF" - android:pathData="M12,22h0A10,10,0,0,0,22,12v0A10,10,0,1,0,12,22ZM12,3a9,9,0,1,1-9,9A9,9,0,0,1,12,3Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M8.62,9.65a0.5 0.5 ,0,0,0,0.61-0.37,2.94,2.94,0,0,1,5-1.41A2.64,2.64,0,0,1,15,10a2.27,2.27,0,0,1-1,1.69l-0.44 0.26 a3.21,3.21,0,0,0-1.91,2.47A0.49 0.49 ,0,0,0,12,15h0.08a0.5 0.5 ,0,0,0,0.49-0.42A2.25,2.25,0,0,1,14,12.81l0.5-0.29A3.27,3.27,0,0,0,16,10.09,3.62,3.62,0,0,0,14.9,7.16a4,4,0,0,0-5.6,0A4.06,4.06,0,0,0,8.25,9.05 0.5 0.5,0,0,0,8.62,9.65Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M 12 16.25 C 12.4142135624 16.25 12.75 16.5857864376 12.75 17 C 12.75 17.4142135624 12.4142135624 17.75 12 17.75 C 11.5857864376 17.75 11.25 17.4142135624 11.25 17 C 11.25 16.5857864376 11.5857864376 16.25 12 16.25 Z" /> -</vector> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M12,22c0,0,0.01,0,0.01,0c5.51,0,9.98-4.46,9.99-9.98c0-0.01,0-0.01,0-0.02c0-5.52-4.48-10-10-10S2,6.48,2,12 S6.48,22,12,22z M12,3.5c4.69,0,8.5,3.81,8.5,8.52c-0.01,4.68-3.81,8.48-8.5,8.48c-4.69,0-8.5-3.81-8.5-8.5 C3.5,7.31,7.31,3.5,12,3.5z"/> + <path android:fillColor="@android:color/white" android:pathData="M8.57,9.89c0.4,0.1,0.81-0.15,0.9-0.56c0.12-0.5,0.36-0.94,0.71-1.29c1.06-1.06,2.78-1.06,3.84,0 c0.53,0.53,0.79,1.23,0.72,1.92c-0.06,0.62-0.39,1.15-0.92,1.5c-0.17,0.11-0.35,0.19-0.52,0.27c-0.7,0.33-1.67,0.78-1.93,2.37 c-0.07,0.41,0.21,0.8,0.61,0.86C12.02,14.99,12.06,15,12.1,15c0.36,0,0.68-0.26,0.74-0.62c0.14-0.82,0.48-0.98,1.09-1.26 c0.25-0.11,0.49-0.23,0.72-0.38c0.91-0.6,1.48-1.53,1.58-2.61c0.12-1.14-0.31-2.28-1.15-3.13c-1.64-1.64-4.32-1.64-5.96,0 c-0.54,0.54-0.93,1.24-1.11,2C7.92,9.39,8.16,9.8,8.57,9.89z"/> + <path android:fillColor="@android:color/white" android:pathData="M 12 16.5 C 12.5522847498 16.5 13 16.9477152502 13 17.5 C 13 18.0522847498 12.5522847498 18.5 12 18.5 C 11.4477152502 18.5 11 18.0522847498 11 17.5 C 11 16.9477152502 11.4477152502 16.5 12 16.5 Z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_phone_info.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_phone_info.xml index f3419d4b8db5..948e2ab78138 100644 --- a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_phone_info.xml +++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_phone_info.xml @@ -1,36 +1,22 @@ + <!-- -/** - * 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. - */ + 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="#FFFFFF" - android:pathData="M15,22a3,3,0,0,0,3-3V5a3,3,0,0,0-3-3H9A3,3,0,0,0,6,5V19a3,3,0,0,0,3,3ZM7,6H17V18H7ZM9,3h6a2,2,0,0,1,2,2H7A2,2,0,0,1,9,3ZM7,19H17a2,2,0,0,1-2,2H9A2,2,0,0,1,7,19Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M12,10.5a0.5 0.5 ,0,0,0-0.5 0.5 v4.5a0.5 0.5 ,0,0,0,1,0V11A0.5 0.5 ,0,0,0,12,10.5Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M 12 8 C 12.4142135624 8 12.75 8.33578643763 12.75 8.75 C 12.75 9.16421356237 12.4142135624 9.5 12 9.5 C 11.5857864376 9.5 11.25 9.16421356237 11.25 8.75 C 11.25 8.33578643763 11.5857864376 8 12 8 Z" /> -</vector> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M15,22c1.66,0,3-1.34,3-3V5c0-1.66-1.34-3-3-3H9C7.34,2,6,3.34,6,5v14c0,1.66,1.34,3,3,3H15z M7.5,6.5h9v11h-9V6.5z M9,3.5 h6c0.83,0,1.5,0.67,1.5,1.5h-9C7.5,4.17,8.17,3.5,9,3.5z M7.5,19h9c0,0.83-0.67,1.5-1.5,1.5H9C8.17,20.5,7.5,19.83,7.5,19z"/> + <path android:fillColor="@android:color/white" android:pathData="M12,11.5c-0.41,0-0.75,0.34-0.75,0.75v3c0,0.41,0.34,0.75,0.75,0.75s0.75-0.34,0.75-0.75v-3 C12.75,11.84,12.41,11.5,12,11.5z"/> + <path android:fillColor="@android:color/white" android:pathData="M 12 8 C 12.5522847498 8 13 8.44771525017 13 9 C 13 9.55228474983 12.5522847498 10 12 10 C 11.4477152502 10 11 9.55228474983 11 9 C 11 8.44771525017 11.4477152502 8 12 8 Z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_accessibility.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_accessibility.xml index 8a8ddec7501e..80a40b282afa 100644 --- a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_accessibility.xml +++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_accessibility.xml @@ -1,42 +1,24 @@ + <!-- -/** - * 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. - */ + 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="#FFFFFF" - android:pathData="M21,5.35A0.51 0.51 ,0,0,0,20.37,5,37.25,37.25,0,0,1,3.63,5,0.51 0.51 ,0,0,0,3,5.35 0.51 0.51,0,0,0,3.37,6,32.05,32.05,0,0,0,9,6.87V20a0.5 0.5 ,0,0,0,1,0V13.5h4V20a0.5 0.5 ,0,0,0,1,0V6.87A32.05,32.05,0,0,0,20.63,6,0.51 0.51 ,0,0,0,21,5.35Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M 12 22 C 12.5522847498 22 13 22.4477152502 13 23 C 13 23.5522847498 12.5522847498 24 12 24 C 11.4477152502 24 11 23.5522847498 11 23 C 11 22.4477152502 11.4477152502 22 12 22 Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M 16 22 C 16.5522847498 22 17 22.4477152502 17 23 C 17 23.5522847498 16.5522847498 24 16 24 C 15.4477152502 24 15 23.5522847498 15 23 C 15 22.4477152502 15.4477152502 22 16 22 Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M 8 22 C 8.55228474983 22 9 22.4477152502 9 23 C 9 23.5522847498 8.55228474983 24 8 24 C 7.44771525017 24 7 23.5522847498 7 23 C 7 22.4477152502 7.44771525017 22 8 22 Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M 12 1 C 13.1045694997 1 14 1.89543050034 14 3 C 14 4.10456949966 13.1045694997 5 12 5 C 10.8954305003 5 10 4.10456949966 10 3 C 10 1.89543050034 10.8954305003 1 12 1 Z" /> -</vector> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M3.03,5.54c-0.11,0.4,0.13,0.81,0.53,0.92C5.24,6.91,7.07,7.2,9,7.35v8.15v3.75C9,19.66,9.34,20,9.75,20 s0.75-0.34,0.75-0.75V15.5c0-0.83,0.67-1.5,1.5-1.5s1.5,0.67,1.5,1.5v3.75c0,0.41,0.34,0.75,0.75,0.75S15,19.66,15,19.25V15.5V7.35 c1.93-0.15,3.76-0.44,5.44-0.89c0.4-0.11,0.64-0.52,0.53-0.92c-0.11-0.4-0.51-0.64-0.92-0.53C17.64,5.66,14.93,5.98,12,5.98 S6.36,5.66,3.94,5.01C3.54,4.9,3.13,5.14,3.03,5.54z"/> + <path android:fillColor="@android:color/white" android:pathData="M 8 22 C 8.55228474983 22 9 22.4477152502 9 23 C 9 23.5522847498 8.55228474983 24 8 24 C 7.44771525017 24 7 23.5522847498 7 23 C 7 22.4477152502 7.44771525017 22 8 22 Z"/> + <path android:fillColor="@android:color/white" android:pathData="M 16 22 C 16.5522847498 22 17 22.4477152502 17 23 C 17 23.5522847498 16.5522847498 24 16 24 C 15.4477152502 24 15 23.5522847498 15 23 C 15 22.4477152502 15.4477152502 22 16 22 Z"/> + <path android:fillColor="@android:color/white" android:pathData="M 12 22 C 12.5522847498 22 13 22.4477152502 13 23 C 13 23.5522847498 12.5522847498 24 12 24 C 11.4477152502 24 11 23.5522847498 11 23 C 11 22.4477152502 11.4477152502 22 12 22 Z"/> + <path android:fillColor="@android:color/white" android:pathData="M 12 1 C 13.1045694997 1 14 1.89543050034 14 3 C 14 4.10456949966 13.1045694997 5 12 5 C 10.8954305003 5 10 4.10456949966 10 3 C 10 1.89543050034 10.8954305003 1 12 1 Z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_accounts.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_accounts.xml index 01fc4b9a886b..5360e9bba636 100644 --- a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_accounts.xml +++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_accounts.xml @@ -1,33 +1,21 @@ + <!-- -/** - * 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. - */ + 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="#FFFFFF" - android:pathData="M12,22A10,10,0,1,0,2,12,10,10,0,0,0,12,22Zm0-1a9,9,0,0,1-7-3.31,10.37,10.37,0,0,1,13.94,0A9,9,0,0,1,12,21ZM3,12a9,9,0,0,1,18,0,8.88,8.88,0,0,1-1.45,4.88,11.35,11.35,0,0,0-15.1,0A8.83,8.83,0,0,1,3,12Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M15.5,9.5A3.5,3.5,0,1,0,12,13,3.5,3.5,0,0,0,15.5,9.5Zm-6,0A2.5,2.5,0,1,1,12,12,2.5,2.5,0,0,1,9.5,9.5Z" /> -</vector> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M12,6c-1.93,0-3.5,1.57-3.5,3.5S10.07,13,12,13s3.5-1.57,3.5-3.5S13.93,6,12,6z M12,11.5c-1.1,0-2-0.9-2-2c0-1.1,0.9-2,2-2 c1.1,0,2,0.9,2,2C14,10.6,13.1,11.5,12,11.5z"/> + <path android:fillColor="@android:color/white" android:pathData="M12,2C6.48,2,2,6.48,2,12s4.48,10,10,10s10-4.48,10-10S17.52,2,12,2z M12,20.5c-2.57,0-4.86-1.15-6.42-2.95 C7.25,16.21,9.45,15.5,12,15.5c2.55,0,4.75,0.71,6.42,2.05C16.86,19.35,14.57,20.5,12,20.5z M12,14c-2.82,0-5.38,0.82-7.3,2.33 C3.94,15.06,3.5,13.58,3.5,12c0-4.69,3.81-8.5,8.5-8.5c4.69,0,8.5,3.81,8.5,8.5c0,1.58-0.44,3.06-1.2,4.33 C17.38,14.82,14.82,14,12,14z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_battery_white.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_battery_white.xml index b43923fec380..bd700c4058ab 100644 --- a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_battery_white.xml +++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_battery_white.xml @@ -1,30 +1,20 @@ + <!-- -/** - * 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. - */ + 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="#FFFFFF" - android:pathData="M14,4a1,1,0,0,0-1-1H11a1,1,0,0,0-1,1H9A2,2,0,0,0,7,6V19a2,2,0,0,0,2,2h6a2,2,0,0,0,2-2V6a2,2,0,0,0-2-2Z" /> -</vector> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M14,4c0-0.55-0.45-1-1-1h-2c-0.55,0-1,0.45-1,1H9C7.34,4,6,5.34,6,7v12c0,1.66,1.34,3,3,3h6c1.66,0,3-1.34,3-3V7 c0-1.66-1.34-3-3-3H14z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_delete.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_delete.xml new file mode 100644 index 000000000000..c66f9189f564 --- /dev/null +++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_delete.xml @@ -0,0 +1,22 @@ + +<!-- + 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 android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M9,20h6c1.66,0,3-1.34,3-3V6h0.5c0.41,0,0.75-0.34,0.75-0.75S18.91,4.5,18.5,4.5H18h-3l-1-1h-4l-1,1H6H5.5 c-0.41,0-0.75,0.34-0.75,0.75S5.09,6,5.5,6H6v11C6,18.66,7.34,20,9,20z M16.5,6v11c0,0.83-0.67,1.5-1.5,1.5H9 c-0.83,0-1.5-0.67-1.5-1.5V6H16.5z"/> + <path android:fillColor="@android:color/white" android:pathData="M13.97,16c0.41,0,0.75-0.34,0.75-0.75v-6.5c0-0.41-0.34-0.75-0.75-0.75s-0.75,0.34-0.75,0.75v6.5 C13.22,15.66,13.55,16,13.97,16z"/> + <path android:fillColor="@android:color/white" android:pathData="M10,16c0.41,0,0.75-0.34,0.75-0.75v-6.5C10.75,8.34,10.41,8,10,8S9.25,8.34,9.25,8.75v6.5C9.25,15.66,9.59,16,10,16z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_display_white.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_display_white.xml index 580271b3da24..1180633e4a5e 100644 --- a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_display_white.xml +++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_display_white.xml @@ -1,33 +1,21 @@ + <!-- -/** - * 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. - */ + 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="#FFFFFF" - 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="#FFFFFF" - android:pathData="M17,12a5,5,0,0,0-5-5V17A5,5,0,0,0,17,12Z" /> -</vector> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M17,12c0-2.76-2.24-5-5-5v10C14.76,17,17,14.76,17,12z"/> + <path android:fillColor="@android:color/white" android:pathData="M4,15.31V18c0,1.1,0.9,2,2,2h2.69l1.9,1.9c0.39,0.39,0.9,0.59,1.41,0.59s1.02-0.2,1.41-0.59l1.9-1.9H18c1.1,0,2-0.9,2-2 v-2.69l1.9-1.9c0.78-0.78,0.78-2.05,0-2.83L20,8.69V6c0-1.1-0.9-2-2-2h-2.69l-1.9-1.9c-0.39-0.39-0.9-0.59-1.41-0.59 s-1.02,0.2-1.41,0.59L8.69,4H6C4.9,4,4,4.9,4,6v2.69l-1.9,1.9c-0.78,0.78-0.78,2.05,0,2.83L4,15.31z M3.16,11.65l1.9-1.9L5.5,9.31 V8.69V6c0-0.28,0.22-0.5,0.5-0.5h2.69h0.62l0.44-0.44l1.9-1.9c0.13-0.13,0.28-0.15,0.35-0.15c0.08,0,0.23,0.02,0.35,0.15l1.9,1.9 l0.44,0.44h0.62H18c0.28,0,0.5,0.22,0.5,0.5v2.69v0.62l0.44,0.44l1.9,1.9c0.13,0.13,0.15,0.28,0.15,0.35s-0.02,0.23-0.15,0.35 l-1.9,1.9l-0.44,0.44v0.62V18c0,0.28-0.22,0.5-0.5,0.5h-2.69h-0.62l-0.44,0.44l-1.9,1.9c-0.13,0.13-0.28,0.15-0.35,0.15 c-0.08,0-0.23-0.02-0.35-0.15l-1.9-1.9L9.31,18.5H8.69H6c-0.28,0-0.5-0.22-0.5-0.5v-2.69v-0.62l-0.44-0.44l-1.9-1.9 C3.04,12.23,3.02,12.08,3.02,12S3.04,11.77,3.16,11.65z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_location.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_location.xml index 37d5576ea9fc..f16fbc1ccb91 100644 --- a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_location.xml +++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_location.xml @@ -1,33 +1,21 @@ + <!-- -/** - * 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. - */ + 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="#FFFFFF" - android:pathData="M12,21.5s7-5.34,7-11.25A7.13,7.13,0,0,0,12,3a7.13,7.13,0,0,0-7,7.25C5,16.16,12,21.5,12,21.5ZM12,4a6.13,6.13,0,0,1,6,6.25c0,4.37-4.37,8.54-6,10-1.63-1.4-6-5.57-6-9.95A6.13,6.13,0,0,1,12,4Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M15,10a3,3,0,1,0-3,3A3,3,0,0,0,15,10Zm-5,0a2,2,0,1,1,2,2A2,2,0,0,1,10,10Z" /> -</vector> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M12,21.5c0,0,7-5.34,7-11.25c0-4-3.13-7.25-7-7.25c-3.87,0-7,3.25-7,7.25C5,16.16,12,21.5,12,21.5z M12,4.5 c3.03,0,5.5,2.58,5.5,5.75c0,3.91-3.74,7.72-5.51,9.29C9.9,17.68,6.5,13.89,6.5,10.25C6.5,7.08,8.97,4.5,12,4.5z"/> + <path android:fillColor="@android:color/white" android:pathData="M15,10c0-1.66-1.34-3-3-3c-1.66,0-3,1.34-3,3c0,1.66,1.34,3,3,3C13.66,13,15,11.66,15,10z M10.5,10 c0-0.83,0.67-1.5,1.5-1.5s1.5,0.67,1.5,1.5s-0.67,1.5-1.5,1.5S10.5,10.83,10.5,10z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_privacy.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_privacy.xml index 32f9e533a29b..f48fc11dea0a 100644 --- a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_privacy.xml +++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_privacy.xml @@ -1,36 +1,22 @@ + <!-- -/** - * 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. - */ + 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="#FFFFFF" - android:pathData="M12,17a9.48,9.48,0,0,1-8.92-5.5A9.48,9.48,0,0,1,12,6a9.5,9.5,0,0,1,8.65,5h1.13A10.5,10.5,0,0,0,12,5,10.47,10.47,0,0,0,2,11.5,10.47,10.47,0,0,0,12,18a11.48,11.48,0,0,0,4-0.7V16.22A10.48,10.48,0,0,1,12,17Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M12,8a3.5,3.5,0,1,0,3.5,3.5A3.5,3.5,0,0,0,12,8Zm0,6a2.5,2.5,0,1,1,2.5-2.5A2.5,2.5,0,0,1,12,14Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M22,15V14a2,2,0,0,0-4,0v1a1,1,0,0,0-1,1v3a1,1,0,0,0,1,1h4a1,1,0,0,0,1-1V16A1,1,0,0,0,22,15Zm-3,0V14a1,1,0,0,1,2,0v1Z" /> -</vector> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M12,16.5c-3.74,0-6.89-1.9-8.37-5c1.47-3.1,4.62-5,8.37-5c3.53,0,6.52,1.71,8.08,4.5h1.7C20.09,7.3,16.35,5,12,5 C7.45,5,3.57,7.51,2,11.5C3.57,15.49,7.45,18,12,18c1.41,0,2.76-0.24,4-0.7v-1.62C14.79,16.21,13.44,16.5,12,16.5z"/> + <path android:fillColor="@android:color/white" android:pathData="M12,8c-1.93,0-3.5,1.57-3.5,3.5S10.07,15,12,15s3.5-1.57,3.5-3.5S13.93,8,12,8z M12,13.5c-1.1,0-2-0.9-2-2s0.9-2,2-2 c1.1,0,2,0.9,2,2S13.1,13.5,12,13.5z"/> + <path android:fillColor="@android:color/white" android:pathData="M22,14c0-1.1-0.9-2-2-2c-1.1,0-2,0.9-2,2c0,0.37,0,0.7,0,1h-1v4c0,0.55,0.45,1,1,1h4c0.55,0,1-0.45,1-1v-4h-1 C22,14.65,22,14.28,22,14z M19,14c0-0.55,0.45-1,1-1s1,0.45,1,1v1h-2V14z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_security_white.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_security_white.xml index 71d427ac0506..736dad3097cb 100644 --- a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_security_white.xml +++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_security_white.xml @@ -1,33 +1,21 @@ + <!-- -/** - * 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. - */ + 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="#FFFFFF" - android:pathData="M12,12a1.5,1.5,0,0,0-0.5,2.91V16.5a0.5 0.5 ,0,0,0,1,0V14.91A1.5,1.5,0,0,0,12,12Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M23,5a4,4,0,0,0-8,0V8H6A1,1,0,0,0,5,9v9a3,3,0,0,0,3,3h8a3,3,0,0,0,3-3V9a1,1,0,0,0-1-1H16V5a3,3,0,0,1,6,0,0.5 0.5 ,0,0,0,1,0ZM18,9v9a2,2,0,0,1-2,2H8a2,2,0,0,1-2-2V9H18Z" /> -</vector> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M11.25,14.79v1.46c0,0.41,0.34,0.75,0.75,0.75s0.75-0.34,0.75-0.75v-1.46c0.45-0.26,0.75-0.74,0.75-1.29 c0-0.83-0.67-1.5-1.5-1.5s-1.5,0.67-1.5,1.5C10.5,14.05,10.8,14.53,11.25,14.79z"/> + <path android:fillColor="@android:color/white" android:pathData="M19,2.5c1.35,0,2.5,1.18,2.5,2.57c0,0.41,0.34,0.75,0.75,0.75S23,5.48,23,5.07C23,2.86,21.17,1,19,1s-4,1.86-4,4.07V8H5v10 c0,1.66,1.34,3,3,3h8c1.66,0,3-1.34,3-3V8h-2.5V5.07C16.5,3.68,17.65,2.5,19,2.5z M17.5,18c0,0.83-0.67,1.5-1.5,1.5H8 c-0.83,0-1.5-0.67-1.5-1.5V9.5h11V18z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_system_dashboard_white.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_system_dashboard_white.xml index f4b29aef3693..7f060a4e555e 100644 --- a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_system_dashboard_white.xml +++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_system_dashboard_white.xml @@ -1,36 +1,22 @@ + <!-- -/** - * 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. - */ + 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="#FFFFFF" - 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="#FFFFFF" - android:pathData="M12,11a0.5 0.5 ,0,0,0-0.5 0.5 v5a0.5 0.5 ,0,0,0,1,0v-5A0.5 0.5 ,0,0,0,12,11Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M 12 7 C 12.4142135624 7 12.75 7.33578643763 12.75 7.75 C 12.75 8.16421356237 12.4142135624 8.5 12 8.5 C 11.5857864376 8.5 11.25 8.16421356237 11.25 7.75 C 11.25 7.33578643763 11.5857864376 7 12 7 Z" /> -</vector> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M11.99,2C6.47,2,2,6.48,2,12c0,5.52,4.47,10,9.99,10C17.52,22,22,17.52,22,12C22,6.48,17.52,2,11.99,2z M11.99,20.5 c-4.68,0-8.49-3.81-8.49-8.5c0-4.69,3.81-8.5,8.49-8.5c4.69,0,8.51,3.81,8.51,8.5C20.5,16.69,16.68,20.5,11.99,20.5z"/> + <path android:fillColor="@android:color/white" android:pathData="M12,10.5c-0.41,0-0.75,0.34-0.75,0.75v5c0,0.41,0.34,0.75,0.75,0.75s0.75-0.34,0.75-0.75v-5 C12.75,10.84,12.41,10.5,12,10.5z"/> + <path android:fillColor="@android:color/white" android:pathData="M 12 7 C 12.5522847498 7 13 7.44771525017 13 8 C 13 8.55228474983 12.5522847498 9 12 9 C 11.4477152502 9 11 8.55228474983 11 8 C 11 7.44771525017 11.4477152502 7 12 7 Z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_wireless_white.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_wireless_white.xml index 85abfff8c53b..00a4a073f1bc 100644 --- a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_wireless_white.xml +++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_wireless_white.xml @@ -1,39 +1,23 @@ + <!-- -/** - * 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. - */ + 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="#FFFFFF" - android:pathData="M 11.99 16.5 C 12.8184271247 16.5 13.49 17.1715728753 13.49 18 C 13.49 18.8284271247 12.8184271247 19.5 11.99 19.5 C 11.1615728753 19.5 10.49 18.8284271247 10.49 18 C 10.49 17.1715728753 11.1615728753 16.5 11.99 16.5 Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M18.76,11.8a0.54 0.54 ,0,0,0,0.36-0.14 0.51 0.51,0,0,0,0-0.71A10.08,10.08,0,0,0,4.87,11a0.5 0.5 ,0,0,0,0,0.71 0.51 0.51,0,0,0,0.71,0,9.07,9.07,0,0,1,12.83,0A0.54 0.54 ,0,0,0,18.76,11.8Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M2.15,8.15a0.49 0.49 ,0,0,0,0.7 0.7 ,12.8,12.8,0,0,1,18.3,0,0.48 0.48 ,0,0,0,0.7,0,0.48 0.48 ,0,0,0,0-0.7A13.77,13.77,0,0,0,2.15,8.15Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M15.93,14.64a0.49 0.49 ,0,0,0,0.35-0.15 0.5 0.5,0,0,0,0-0.71,6.08,6.08,0,0,0-8.58,0,0.51 0.51 ,0,0,0,0,0.71 0.5 0.5,0,0,0,0.71,0,5.07,5.07,0,0,1,7.16,0A0.51 0.51 ,0,0,0,15.93,14.64Z" /> -</vector> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M 12 17 C 12.8284271247 17 13.5 17.6715728753 13.5 18.5 C 13.5 19.3284271247 12.8284271247 20 12 20 C 11.1715728753 20 10.5 19.3284271247 10.5 18.5 C 10.5 17.6715728753 11.1715728753 17 12 17 Z"/> + <path android:fillColor="@android:color/white" android:pathData="M19.42,11.84c-0.19,0-0.38-0.07-0.53-0.22C17.05,9.77,14.6,8.75,12,8.75s-5.05,1.02-6.89,2.86 c-0.29,0.29-0.77,0.29-1.06,0c-0.29-0.29-0.29-0.77,0-1.06C6.17,8.43,9,7.25,12,7.25s5.83,1.17,7.95,3.3 c0.29,0.29,0.29,0.77,0,1.06C19.8,11.76,19.61,11.84,19.42,11.84z"/> + <path android:fillColor="@android:color/white" android:pathData="M22.61,8.65c-0.19,0-0.38-0.07-0.53-0.22C19.38,5.74,15.81,4.25,12,4.25S4.62,5.74,1.92,8.43c-0.29,0.29-0.77,0.29-1.06,0 s-0.29-0.77,0-1.06C3.84,4.39,7.79,2.75,12,2.75s8.16,1.64,11.14,4.61c0.29,0.29,0.29,0.77,0,1.06 C22.99,8.57,22.8,8.65,22.61,8.65z"/> + <path android:fillColor="@android:color/white" android:pathData="M16.25,15c-0.19,0-0.38-0.07-0.53-0.22c-1-0.99-2.32-1.53-3.73-1.53s-2.73,0.54-3.73,1.53c-0.29,0.29-0.77,0.29-1.06-0.01 s-0.29-0.77,0.01-1.06c1.28-1.27,2.98-1.96,4.78-1.96s3.5,0.7,4.78,1.96c0.29,0.29,0.3,0.77,0.01,1.06 C16.64,14.93,16.45,15,16.25,15z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_storage_white.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_storage_white.xml index ea7a97f7685d..1ee5ee069901 100644 --- a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_storage_white.xml +++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_storage_white.xml @@ -1,45 +1,25 @@ + <!-- -/** - * 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. - */ + 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="#FFFFFF" - android:pathData="M3,5V7A1,1,0,0,0,4,8H20a1,1,0,0,0,1-1V5a2,2,0,0,0-2-2H5A2,2,0,0,0,3,5ZM20,5V7H4V5A1,1,0,0,1,5,4H19A1,1,0,0,1,20,5Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M3,19a1,1,0,0,0,1,1H20a1,1,0,0,0,1-1V17a2,2,0,0,0-2-2H5a2,2,0,0,0-2,2Zm1-2a1,1,0,0,1,1-1H19a1,1,0,0,1,1,1v2H4Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M3,13a1,1,0,0,0,1,1H20a1,1,0,0,0,1-1V11a2,2,0,0,0-2-2H5a2,2,0,0,0-2,2Zm1-2a1,1,0,0,1,1-1H19a1,1,0,0,1,1,1v2H4Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M 6.01 4.75 C 6.42421356237 4.75 6.76 5.08578643763 6.76 5.5 C 6.76 5.91421356237 6.42421356237 6.25 6.01 6.25 C 5.59578643763 6.25 5.26 5.91421356237 5.26 5.5 C 5.26 5.08578643763 5.59578643763 4.75 6.01 4.75 Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M 6.01 10.75 C 6.42421356237 10.75 6.76 11.0857864376 6.76 11.5 C 6.76 11.9142135624 6.42421356237 12.25 6.01 12.25 C 5.59578643763 12.25 5.26 11.9142135624 5.26 11.5 C 5.26 11.0857864376 5.59578643763 10.75 6.01 10.75 Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M 6.01 16.75 C 6.42421356237 16.75 6.76 17.0857864376 6.76 17.5 C 6.76 17.9142135624 6.42421356237 18.25 6.01 18.25 C 5.59578643763 18.25 5.26 17.9142135624 5.26 17.5 C 5.26 17.0857864376 5.59578643763 16.75 6.01 16.75 Z" /> -</vector> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M21,17c0-1.1-0.9-2-2-2H5c-1.1,0-2,0.9-2,2v3h18V17z M19.5,18.5h-15V17c0-0.28,0.22-0.5,0.5-0.5h14 c0.28,0,0.5,0.22,0.5,0.5V18.5z"/> + <path android:fillColor="@android:color/white" android:pathData="M21,5c0-1.1-0.9-2-2-2H5C3.9,3,3,3.9,3,5v3h18V5z M19.5,6.5h-15V5c0-0.28,0.22-0.5,0.5-0.5h14c0.28,0,0.5,0.22,0.5,0.5V6.5 z"/> + <path android:fillColor="@android:color/white" android:pathData="M21,11c0-1.1-0.9-2-2-2H5c-1.1,0-2,0.9-2,2v3h18V11z M19.5,12.5h-15V11c0-0.28,0.22-0.5,0.5-0.5h14 c0.28,0,0.5,0.22,0.5,0.5V12.5z"/> + <path android:fillColor="@android:color/white" android:pathData="M 6.01 4.75 C 6.42421356237 4.75 6.76 5.08578643763 6.76 5.5 C 6.76 5.91421356237 6.42421356237 6.25 6.01 6.25 C 5.59578643763 6.25 5.26 5.91421356237 5.26 5.5 C 5.26 5.08578643763 5.59578643763 4.75 6.01 4.75 Z"/> + <path android:fillColor="@android:color/white" android:pathData="M 6.01 10.75 C 6.42421356237 10.75 6.76 11.0857864376 6.76 11.5 C 6.76 11.9142135624 6.42421356237 12.25 6.01 12.25 C 5.59578643763 12.25 5.26 11.9142135624 5.26 11.5 C 5.26 11.0857864376 5.59578643763 10.75 6.01 10.75 Z"/> + <path android:fillColor="@android:color/white" android:pathData="M 6.01 16.75 C 6.42421356237 16.75 6.76 17.0857864376 6.76 17.5 C 6.76 17.9142135624 6.42421356237 18.25 6.01 18.25 C 5.59578643763 18.25 5.26 17.9142135624 5.26 17.5 C 5.26 17.0857864376 5.59578643763 16.75 6.01 16.75 Z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_volume_up_24dp.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_volume_up_24dp.xml index 7ed248d7e8b1..7d9dc206d19a 100644 --- a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_volume_up_24dp.xml +++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_volume_up_24dp.xml @@ -1,36 +1,22 @@ + <!-- -/** - * 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. - */ + 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="#FFFFFF" - android:pathData="M13.79,13.79a0.5 0.5 ,0,0,0,0.21,1,0.54 0.54 ,0,0,0,0.21-0.05,2.92,2.92,0,0,0,0-5.39 0.49 0.49,0,0,0-0.66 0.24 0.5 0.5 ,0,0,0,0.24 0.67 ,1.93,1.93,0,0,1,0,3.58Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M13.89,17.67a0.5 0.5 ,0,0,0,0.11,1l0.11,0a6.78,6.78,0,0,0,0-13.28 0.5 0.5,0,1,0-0.22,1,5.79,5.79,0,0,1,0,11.34Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M5,15H7l4.15,4.15a0.47 0.47 ,0,0,0,0.35 0.14 0.5 0.5 ,0,0,0,0.5-0.5V5.21a0.5 0.5 ,0,0,0-0.5-0.5 0.47 0.47,0,0,0-0.35 0.14 L7,9H5a2,2,0,0,0-2,2v2A2,2,0,0,0,5,15ZM4,11a1,1,0,0,1,1-1H7.41l0.3-0.29L11,6.41V17.59l-3.29-3.3L7.41,14H5a1,1,0,0,1-1-1Z" /> -</vector> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M14.44,13.56c-0.38,0.17-0.54,0.62-0.37,0.99c0.13,0.28,0.4,0.44,0.68,0.44c0.1,0,0.21-0.02,0.31-0.07 C16.26,14.37,17,13.25,17,12c0-1.25-0.74-2.37-1.93-2.93c-0.37-0.17-0.82-0.01-1,0.37c-0.17,0.38-0.01,0.82,0.36,1 c0.66,0.3,1.07,0.9,1.07,1.57S15.09,13.26,14.44,13.56z"/> + <path android:fillColor="@android:color/white" android:pathData="M14.59,17.42c-0.4,0.09-0.66,0.49-0.57,0.9c0.08,0.35,0.39,0.59,0.73,0.59c0.05,0,0.11-0.01,0.16-0.02 c3.29-0.74,5.59-3.57,5.59-6.89s-2.3-6.15-5.59-6.89c-0.41-0.08-0.81,0.17-0.9,0.57s0.16,0.8,0.57,0.9C17.19,7.16,19,9.39,19,12 S17.19,16.84,14.59,17.42z"/> + <path android:fillColor="@android:color/white" android:pathData="M7,15l4.15,4.15c0.1,0.1,0.23,0.15,0.35,0.15c0.26,0,0.5-0.2,0.5-0.5V5.21c0-0.3-0.25-0.5-0.5-0.5 c-0.12,0-0.25,0.05-0.35,0.15L7,9H5c-1.1,0-2,0.9-2,2v2c0,1.1,0.9,2,2,2H7z M4.5,13v-2c0-0.28,0.22-0.5,0.5-0.5h2.62l2.88-2.88 v8.76L7.62,13.5H5C4.72,13.5,4.5,13.28,4.5,13z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_wifi_tethering.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_wifi_tethering.xml index 10c15923215f..dcf507aefe86 100644 --- a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_wifi_tethering.xml +++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_wifi_tethering.xml @@ -1,36 +1,22 @@ + <!-- -/** - * 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. - */ + 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="#FFFFFF" - android:pathData="M 12 11 C 12.8284271247 11 13.5 11.6715728753 13.5 12.5 C 13.5 13.3284271247 12.8284271247 14 12 14 C 11.1715728753 14 10.5 13.3284271247 10.5 12.5 C 10.5 11.6715728753 11.1715728753 11 12 11 Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M15.18,16.39a0.51 0.51 ,0,0,0,0.71,0,5.5,5.5,0,0,0,0-7.78,5.52,5.52,0,0,0-7.78,0,5.5,5.5,0,0,0,0,7.78 0.5 0.5,0,0,0,0.35 0.15 0.51 0.51 ,0,0,0,0.36-0.15 0.51 0.51,0,0,0,0-0.71,4.5,4.5,0,1,1,6.36,0A0.51 0.51 ,0,0,0,15.18,16.39Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M18,19.22a0.49 0.49 ,0,0,0,0.35 0.14 0.5 0.5 ,0,0,0,0.36-0.14,9.5,9.5,0,1,0-13.44,0,0.51 0.51 ,0,0,0,0.71,0,0.5 0.5 ,0,0,0,0-0.71,8.5,8.5,0,0,1,12-12,8.5,8.5,0,0,1,0,12A0.5 0.5 ,0,0,0,18,19.22Z" /> -</vector> +<vector android:height="24dp" android:tint="?android:attr/colorControlNormal" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M12,14c-0.83,0-1.5-0.67-1.5-1.5S11.17,11,12,11s1.5,0.67,1.5,1.5S12.83,14,12,14z"/> + <path android:fillColor="@android:color/white" android:pathData="M8.46,16.79c-0.19,0-0.38-0.07-0.53-0.22c-1.09-1.09-1.68-2.53-1.68-4.07s0.6-2.98,1.68-4.07 c2.24-2.24,5.89-2.24,8.13,0c1.09,1.09,1.68,2.53,1.68,4.07s-0.6,2.98-1.68,4.07c-0.29,0.29-0.77,0.29-1.06,0 s-0.29-0.77,0-1.06c0.8-0.8,1.24-1.87,1.24-3c0-1.14-0.44-2.2-1.24-3.01c-1.66-1.66-4.35-1.66-6.01,0 c-0.8,0.8-1.24,1.87-1.24,3c0,1.14,0.44,2.2,1.24,3.01c0.29,0.29,0.29,0.77,0,1.06C8.85,16.71,8.66,16.79,8.46,16.79z"/> + <path android:fillColor="@android:color/white" android:pathData="M18.36,19.61c-0.19,0-0.38-0.07-0.53-0.22c-0.29-0.29-0.29-0.77,0-1.06c1.56-1.56,2.42-3.63,2.42-5.83 s-0.86-4.28-2.42-5.83c-3.22-3.22-8.45-3.22-11.67,0C4.61,8.22,3.75,10.3,3.75,12.5s0.86,4.28,2.42,5.83 c0.29,0.29,0.29,0.77,0,1.06s-0.77,0.29-1.06,0c-1.84-1.84-2.86-4.29-2.86-6.89s1.01-5.05,2.86-6.89c3.8-3.8,9.99-3.8,13.79,0 c1.84,1.84,2.86,4.29,2.86,6.89s-1.01,5.05-2.86,6.89C18.75,19.54,18.56,19.61,18.36,19.61z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_alarm.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_alarm.xml new file mode 100644 index 000000000000..ae4af5016c9a --- /dev/null +++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_alarm.xml @@ -0,0 +1,23 @@ + +<!-- + 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 android:height="17dp" android:viewportHeight="24" android:viewportWidth="24" android:width="17dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M12,4c-4.97,0-9,4.03-9,9c0,4.97,4.03,9,9,9s9-4.03,9-9C21,8.03,16.97,4,12,4z M12,20.5c-4.14,0-7.5-3.36-7.5-7.5 S7.86,5.5,12,5.5s7.5,3.36,7.5,7.5S16.14,20.5,12,20.5z"/> + <path android:fillColor="@android:color/white" android:pathData="M17.1,4.22c0.13-0.15,0.31-0.25,0.51-0.26c0.2-0.02,0.39,0.04,0.55,0.17l1.53,1.29c0.15,0.13,0.25,0.31,0.26,0.51 c0.02,0.2-0.04,0.39-0.17,0.54c-0.27,0.32-0.23,0.79,0.09,1.06c0.14,0.12,0.31,0.18,0.48,0.18c0.21,0,0.43-0.09,0.57-0.27 c0.8-0.95,0.68-2.37-0.27-3.17l-1.53-1.29c-0.46-0.39-1.04-0.57-1.64-0.52c-0.6,0.05-1.14,0.33-1.53,0.79 c-0.27,0.32-0.23,0.79,0.09,1.06C16.37,4.58,16.84,4.54,17.1,4.22z"/> + <path android:fillColor="@android:color/white" android:pathData="M3.65,7.71c0.17,0,0.34-0.06,0.48-0.18c0.32-0.27,0.36-0.74,0.09-1.06C4.09,6.32,4.03,6.13,4.05,5.93 c0.02-0.2,0.11-0.38,0.26-0.51l1.53-1.29C5.99,4,6.19,3.94,6.39,3.96c0.2,0.02,0.38,0.11,0.51,0.26c0.27,0.32,0.74,0.36,1.06,0.09 c0.32-0.27,0.36-0.74,0.09-1.06C7.66,2.8,7.11,2.52,6.52,2.46C5.92,2.41,5.34,2.6,4.88,2.98L3.34,4.28 C2.39,5.07,2.27,6.5,3.07,7.44C3.22,7.62,3.43,7.71,3.65,7.71z"/> + <path android:fillColor="@android:color/white" android:pathData="M12.75,12.69V7.75C12.75,7.34,12.41,7,12,7s-0.75,0.34-0.75,0.75v5.56l2.7,2.7c0.15,0.15,0.34,0.22,0.53,0.22 s0.38-0.07,0.53-0.22c0.29-0.29,0.29-0.77,0-1.06L12.75,12.69z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_alarm_dim.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_alarm_dim.xml new file mode 100644 index 000000000000..ae4af5016c9a --- /dev/null +++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_alarm_dim.xml @@ -0,0 +1,23 @@ + +<!-- + 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 android:height="17dp" android:viewportHeight="24" android:viewportWidth="24" android:width="17dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M12,4c-4.97,0-9,4.03-9,9c0,4.97,4.03,9,9,9s9-4.03,9-9C21,8.03,16.97,4,12,4z M12,20.5c-4.14,0-7.5-3.36-7.5-7.5 S7.86,5.5,12,5.5s7.5,3.36,7.5,7.5S16.14,20.5,12,20.5z"/> + <path android:fillColor="@android:color/white" android:pathData="M17.1,4.22c0.13-0.15,0.31-0.25,0.51-0.26c0.2-0.02,0.39,0.04,0.55,0.17l1.53,1.29c0.15,0.13,0.25,0.31,0.26,0.51 c0.02,0.2-0.04,0.39-0.17,0.54c-0.27,0.32-0.23,0.79,0.09,1.06c0.14,0.12,0.31,0.18,0.48,0.18c0.21,0,0.43-0.09,0.57-0.27 c0.8-0.95,0.68-2.37-0.27-3.17l-1.53-1.29c-0.46-0.39-1.04-0.57-1.64-0.52c-0.6,0.05-1.14,0.33-1.53,0.79 c-0.27,0.32-0.23,0.79,0.09,1.06C16.37,4.58,16.84,4.54,17.1,4.22z"/> + <path android:fillColor="@android:color/white" android:pathData="M3.65,7.71c0.17,0,0.34-0.06,0.48-0.18c0.32-0.27,0.36-0.74,0.09-1.06C4.09,6.32,4.03,6.13,4.05,5.93 c0.02-0.2,0.11-0.38,0.26-0.51l1.53-1.29C5.99,4,6.19,3.94,6.39,3.96c0.2,0.02,0.38,0.11,0.51,0.26c0.27,0.32,0.74,0.36,1.06,0.09 c0.32-0.27,0.36-0.74,0.09-1.06C7.66,2.8,7.11,2.52,6.52,2.46C5.92,2.41,5.34,2.6,4.88,2.98L3.34,4.28 C2.39,5.07,2.27,6.5,3.07,7.44C3.22,7.62,3.43,7.71,3.65,7.71z"/> + <path android:fillColor="@android:color/white" android:pathData="M12.75,12.69V7.75C12.75,7.34,12.41,7,12,7s-0.75,0.34-0.75,0.75v5.56l2.7,2.7c0.15,0.15,0.34,0.22,0.53,0.22 s0.38-0.07,0.53-0.22c0.29-0.29,0.29-0.77,0-1.06L12.75,12.69z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_bluetooth_connected.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_bluetooth_connected.xml new file mode 100644 index 000000000000..c8f07aa164ec --- /dev/null +++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_bluetooth_connected.xml @@ -0,0 +1,22 @@ + +<!-- + 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 android:height="17dp" android:viewportHeight="24" android:viewportWidth="24" android:width="17dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M 19 11 C 19.5522847498 11 20 11.4477152502 20 12 C 20 12.5522847498 19.5522847498 13 19 13 C 18.4477152502 13 18 12.5522847498 18 12 C 18 11.4477152502 18.4477152502 11 19 11 Z"/> + <path android:fillColor="@android:color/white" android:pathData="M 5 11 C 5.55228474983 11 6 11.4477152502 6 12 C 6 12.5522847498 5.55228474983 13 5 13 C 4.44771525017 13 4 12.5522847498 4 12 C 4 11.4477152502 4.44771525017 11 5 11 Z"/> + <path android:fillColor="@android:color/white" android:pathData="M4.97,4.97c-0.29,0.29-0.29,0.77,0,1.06L10.94,12l-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.22 s0.38-0.07,0.53-0.22L11,14.06V22h0.75c2.96,0,5.37-2.41,5.37-5.38c0-1.97-1.06-3.69-2.64-4.62c1.58-0.94,2.64-2.66,2.64-4.62 c0-2.96-2.41-5.38-5.37-5.38H11v7.94L6.03,4.97C5.74,4.68,5.26,4.68,4.97,4.97z M12.5,3.57c1.78,0.35,3.12,1.92,3.12,3.8 s-1.34,3.45-3.12,3.8V3.57z M12.5,12.82c1.78,0.35,3.12,1.92,3.12,3.8s-1.34,3.45-3.12,3.8V12.82z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_brightness_thumb.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_brightness_thumb.xml index 04ee7cd109a0..a8eccbdc30fc 100644 --- a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_brightness_thumb.xml +++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_brightness_thumb.xml @@ -1,33 +1,22 @@ + <!-- -/** - * 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. - */ + 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="?android:attr/colorControlActivated" - 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="?android:attr/colorControlActivated" - android:pathData="M 12 7 C 14.7614237492 7 17 9.23857625085 17 12 C 17 14.7614237492 14.7614237492 17 12 17 C 9.23857625085 17 7 14.7614237492 7 12 C 7 9.23857625085 9.23857625085 7 12 7 Z" /> -</vector> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="?android:attr/colorPrimary" android:pathData="M18.94,9.75L18.5,9.31V8.69V6c0-0.28-0.22-0.5-0.5-0.5h-2.69h-0.62l-0.44-0.44l-1.9-1.9 C12.23,3.04,12.08,3.02,12,3.02c-0.08,0-0.23,0.02-0.35,0.15l-1.9,1.9L9.31,5.5H8.69H6C5.72,5.5,5.5,5.72,5.5,6v2.69v0.62 L5.06,9.75l-1.9,1.9C3.04,11.77,3.02,11.92,3.02,12s0.02,0.23,0.15,0.35l1.9,1.9l0.44,0.44v0.62V18c0,0.28,0.22,0.5,0.5,0.5h2.69 h0.62l0.44,0.44l1.9,1.9c0.13,0.13,0.28,0.15,0.35,0.15c0.08,0,0.23-0.02,0.35-0.15l1.9-1.9l0.44-0.44h0.62H18 c0.28,0,0.5-0.22,0.5-0.5v-2.69v-0.62l0.44-0.44l1.9-1.9c0.13-0.13,0.15-0.28,0.15-0.35s-0.02-0.23-0.15-0.35L18.94,9.75z M12,17 c-2.76,0-5-2.24-5-5s2.24-5,5-5s5,2.24,5,5S14.76,17,12,17z"/> + <path android:fillColor="?android:attr/colorControlActivated" android:pathData="M21.9,10.59L20,8.69V6c0-1.1-0.9-2-2-2h-2.69l-1.9-1.9c-0.39-0.39-0.9-0.59-1.41-0.59s-1.02,0.2-1.41,0.59L8.69,4H6 C4.9,4,4,4.9,4,6v2.69l-1.9,1.9c-0.78,0.78-0.78,2.05,0,2.83l1.9,1.9V18c0,1.1,0.9,2,2,2h2.69l1.9,1.9 c0.39,0.39,0.9,0.59,1.41,0.59s1.02-0.2,1.41-0.59l1.9-1.9H18c1.1,0,2-0.9,2-2v-2.69l1.9-1.9C22.68,12.63,22.68,11.37,21.9,10.59z M20.84,12.35l-1.9,1.9l-0.44,0.44v0.62V18c0,0.28-0.22,0.5-0.5,0.5h-2.69h-0.62l-0.44,0.44l-1.9,1.9 c-0.13,0.13-0.28,0.15-0.35,0.15c-0.08,0-0.23-0.02-0.35-0.15l-1.9-1.9L9.31,18.5H8.69H6c-0.28,0-0.5-0.22-0.5-0.5v-2.69v-0.62 l-0.44-0.44l-1.9-1.9C3.04,12.23,3.02,12.08,3.02,12s0.02-0.23,0.15-0.35l1.9-1.9L5.5,9.31V8.69V6c0-0.28,0.22-0.5,0.5-0.5h2.69 h0.62l0.44-0.44l1.9-1.9c0.13-0.13,0.28-0.15,0.35-0.15c0.08,0,0.23,0.02,0.35,0.15l1.9,1.9l0.44,0.44h0.62H18 c0.28,0,0.5,0.22,0.5,0.5v2.69v0.62l0.44,0.44l1.9,1.9c0.13,0.13,0.15,0.28,0.15,0.35S20.96,12.23,20.84,12.35z"/> + <path android:fillColor="?android:attr/colorControlActivated" android:pathData="M 12 7 C 14.7614237492 7 17 9.23857625085 17 12 C 17 14.7614237492 14.7614237492 17 12 17 C 9.23857625085 17 7 14.7614237492 7 12 C 7 9.23857625085 9.23857625085 7 12 7 Z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_camera.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_camera.xml new file mode 100644 index 000000000000..66b4a35b87b2 --- /dev/null +++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_camera.xml @@ -0,0 +1,21 @@ + +<!-- + 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 android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M22,8c0-1.66-1.34-3-3-3h-2l-2-2H9L7,5H5C3.34,5,2,6.34,2,8v13h20V8z M20.5,19.5h-17V8c0-0.83,0.67-1.5,1.5-1.5h14 c0.83,0,1.5,0.67,1.5,1.5V19.5z"/> + <path android:fillColor="@android:color/white" android:pathData="M12,8.5c-2.49,0-4.5,2.01-4.5,4.5s2.01,4.5,4.5,4.5s4.5-2.01,4.5-4.5S14.49,8.5,12,8.5z M12,16c-1.65,0-3-1.35-3-3 c0-1.65,1.35-3,3-3c1.65,0,3,1.35,3,3C15,14.65,13.65,16,12,16z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_cast.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_cast.xml new file mode 100644 index 000000000000..1d7d5e9cd3e0 --- /dev/null +++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_cast.xml @@ -0,0 +1,23 @@ + +<!-- + 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 android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M2.25,9C2.66,9,3,8.66,3,8.25v-1C3,6.01,4.01,5,5.25,5h13.5C19.99,5,21,6.01,21,7.25V19h-7.25C13.34,19,13,19.34,13,19.75 s0.34,0.75,0.75,0.75h8.75V7.25c0-2.07-1.68-3.75-3.75-3.75H5.25C3.18,3.5,1.5,5.18,1.5,7.25v1C1.5,8.66,1.84,9,2.25,9z"/> + <path android:fillColor="@android:color/white" android:pathData="M2.38,20.49c0.3,0.04,0.6-0.06,0.83-0.29c0.39-0.39,0.39-1.02,0-1.41c-0.39-0.39-1.02-0.39-1.41,0l0.01-0.01 c0,0-0.01,0.01-0.01,0.01c-0.39,0.39-0.39,1.02,0,1.41C1.96,20.37,2.16,20.47,2.38,20.49z"/> + <path android:fillColor="@android:color/white" android:pathData="M2.25,12.5c4,0,7.25,3.25,7.25,7.25c0,0.41,0.34,0.75,0.75,0.75S11,20.16,11,19.75C11,14.93,7.07,11,2.25,11 c-0.41,0-0.75,0.34-0.75,0.75S1.84,12.5,2.25,12.5z"/> + <path android:fillColor="@android:color/white" android:pathData="M2.25,16.5c1.79,0,3.25,1.46,3.25,3.25c0,0.41,0.34,0.75,0.75,0.75S7,20.16,7,19.75C7,17.13,4.87,15,2.25,15 c-0.41,0-0.75,0.34-0.75,0.75S1.84,16.5,2.25,16.5z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_cast_connected.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_cast_connected.xml new file mode 100644 index 000000000000..1656b0bf1b68 --- /dev/null +++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_cast_connected.xml @@ -0,0 +1,24 @@ + +<!-- + 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 android:height="17dp" android:viewportHeight="24" android:viewportWidth="24" android:width="17dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M2.25,9C2.66,9,3,8.66,3,8.25v-1C3,6.01,4.01,5,5.25,5h13.5C19.99,5,21,6.01,21,7.25V19h-7.25C13.34,19,13,19.34,13,19.75 s0.34,0.75,0.75,0.75h8.75V7.25c0-2.07-1.68-3.75-3.75-3.75H5.25C3.18,3.5,1.5,5.18,1.5,7.25v1C1.5,8.66,1.84,9,2.25,9z"/> + <path android:fillColor="@android:color/white" android:pathData="M2.38,20.49c0.3,0.04,0.6-0.06,0.83-0.29c0.39-0.39,0.39-1.02,0-1.41c-0.39-0.39-1.02-0.39-1.41,0l0.01-0.01 c0,0-0.01,0.01-0.01,0.01c-0.39,0.39-0.39,1.02,0,1.41C1.96,20.37,2.16,20.47,2.38,20.49z"/> + <path android:fillColor="@android:color/white" android:pathData="M2.25,12.5c4,0,7.25,3.25,7.25,7.25c0,0.41,0.34,0.75,0.75,0.75S11,20.16,11,19.75C11,14.93,7.07,11,2.25,11 c-0.41,0-0.75,0.34-0.75,0.75S1.84,12.5,2.25,12.5z"/> + <path android:fillColor="@android:color/white" android:pathData="M2.25,16.5c1.79,0,3.25,1.46,3.25,3.25c0,0.41,0.34,0.75,0.75,0.75S7,20.16,7,19.75C7,17.13,4.87,15,2.25,15 c-0.41,0-0.75,0.34-0.75,0.75S1.84,16.5,2.25,16.5z"/> + <path android:fillColor="@android:color/white" android:pathData="M13.75,15C13.34,15,13,15.34,13,15.75s0.34,0.75,0.75,0.75h4c0.41,0,0.75-0.34,0.75-0.75v-6.5c0-0.96-0.79-1.75-1.75-1.75 H6.25C5.84,7.5,5.5,7.84,5.5,8.25S5.84,9,6.25,9h10.5C16.89,9,17,9.11,17,9.25V15H13.75z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_close_white.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_close_white.xml new file mode 100644 index 000000000000..4c2e143d9221 --- /dev/null +++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_close_white.xml @@ -0,0 +1,20 @@ + +<!-- + 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 android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M20.03,3.97c-0.29-0.29-0.77-0.29-1.06,0L12,10.94L5.03,3.97c-0.29-0.29-0.77-0.29-1.06,0s-0.29,0.77,0,1.06L10.94,12 l-6.97,6.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.22L12,13.06l6.97,6.97 c0.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.06L13.06,12l6.97-6.97 C20.32,4.74,20.32,4.26,20.03,3.97z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_data_saver.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_data_saver.xml new file mode 100644 index 000000000000..56708713683c --- /dev/null +++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_data_saver.xml @@ -0,0 +1,22 @@ + +<!-- + 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 android:height="18dp " android:viewportHeight="24" android:viewportWidth="24" android:width="18dp " xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M12,7a0.76 0.76 ,0,0,0-0.75 0.75 v3.5H7.75a0.75 0.75 ,0,0,0,0,1.5h3.5v3.5a0.75 0.75 ,0,0,0,1.5,0v-3.5h3.5a0.75 0.75 ,0,0,0,0-1.5h-3.5V7.75A0.76 0.76 ,0,0,0,12,7Z"/> + <path android:fillColor="@android:color/white" android:pathData="M3.36,7A10,10,0,0,0,20.27,17.64L18.1,16.39A7.5,7.5,0,1,1,11.25,4.56V2.05A10,10,0,0,0,3.36,7Z"/> + <path android:fillColor="@android:color/white" android:pathData="M21,16.35a10,10,0,0,0-8.27-14.3V4.56a7.48,7.48,0,0,1,6.1,10.54Z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_data_saver_off.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_data_saver_off.xml index d25350a9688f..2921dd8a06d0 100644 --- a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_data_saver_off.xml +++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_data_saver_off.xml @@ -1,36 +1,21 @@ + <!-- -/** - * 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. - */ + 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="M12,7.5a0.5 0.5 ,0,0,0-0.5 0.5 v3.5H8a0.5 0.5 ,0,0,0,0,1h3.5V16a0.5 0.5 ,0,0,0,1,0V12.5H16a0.5 0.5 ,0,0,0,0-1H12.5V8A0.5 0.5 ,0,0,0,12,7.5Z" /> - <path - android:fillColor="#000000" - android:pathData="M22,12a10,10,0,0,0-9-9.95v3A7,7,0,0,1,19,12a7.12,7.12,0,0,1-0.48,2.54h0l2.6,1.53A9.88,9.88,0,0,0,22,12Z" /> - <path - android:fillColor="#000000" - android:pathData="M2.09,13.39a10,10,0,0,0,18,4.52l-2.6-1.53h0A7,7,0,1,1,11,5.08v-3A10,10,0,0,0,2.09,13.39Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M3.36,7A10,10,0,0,0,20.27,17.64L18.1,16.39A7.5,7.5,0,1,1,11.25,4.56V2.05A10,10,0,0,0,3.36,7Z"/> + <path android:fillColor="@android:color/white" android:pathData="M21,16.35a10,10,0,0,0-8.27-14.3V4.56a7.48,7.48,0,0,1,6.1,10.54Z"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_dnd.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_dnd.xml deleted file mode 100644 index 3e32b3bd6664..000000000000 --- a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_dnd.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="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" /> -</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_drag_handle.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_drag_handle.xml index 793b32fbd7e5..81cc9759f488 100644 --- a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_drag_handle.xml +++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_drag_handle.xml @@ -1,33 +1,21 @@ + <!-- -/** - * 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. - */ + 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="M19.5,9H4.5a0.5 0.5 ,0,0,0,0,1h15a0.5 0.5 ,0,0,0,0-1Z" /> - <path - android:fillColor="#000000" - android:pathData="M19.5,14H4.5a0.5 0.5 ,0,0,0,0,1h15a0.5 0.5 ,0,0,0,0-1Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M4.75,10.5h14.5c0.41,0,0.75-0.34,0.75-0.75S19.66,9,19.25,9H4.75C4.34,9,4,9.34,4,9.75S4.34,10.5,4.75,10.5z"/> + <path android:fillColor="@android:color/white" android:pathData="M4.75,15h14.5c0.41,0,0.75-0.34,0.75-0.75s-0.34-0.75-0.75-0.75H4.75C4.34,13.5,4,13.84,4,14.25S4.34,15,4.75,15z"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_headset.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_headset.xml index 4d8c366fff53..71c76b5022fb 100644 --- a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_headset.xml +++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_headset.xml @@ -1,30 +1,20 @@ + <!-- -/** - * 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. - */ + 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,18V11A9,9,0,0,0,3,11v7a2.93,2.93,0,0,0,2.88,3H8V13H4V11a8,8,0,0,1,16,0v2H16v8h2.12A2.93,2.93,0,0,0,21,18ZM7,14v6H5.88A1.92,1.92,0,0,1,4,18V14Zm13,4a1.92,1.92,0,0,1-1.88,2H17V14h3Z" /> +<vector android:height="17dp" android:viewportHeight="24" android:viewportWidth="24" android:width="17dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M21,17.78V11c0-4.96-4.04-9-9-9s-9,4.04-9,9v6.78C3,19.56,4.41,21,6.13,21H9v-8H4.5v-2c0-4.13,3.36-7.5,7.5-7.5 s7.5,3.36,7.5,7.5v2H15v8h2.87C19.59,21,21,19.56,21,17.78z M7.5,19.5H6.13c-0.9,0-1.63-0.77-1.63-1.72V14.5h3V19.5z M19.5,17.78 c0,0.95-0.73,1.72-1.63,1.72H16.5v-5h3V17.78z"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_headset_mic.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_headset_mic.xml new file mode 100644 index 000000000000..231163bf196f --- /dev/null +++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_headset_mic.xml @@ -0,0 +1,21 @@ + +<!-- + 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 android:height="17dp" android:viewportHeight="24" android:viewportWidth="24" android:width="17dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:pathData="M0,0h24v24H0V0z"/> + <path android:fillColor="@android:color/white" android:pathData="M12,1c-4.96,0-9,4.04-9,9v6.78C3,18.56,4.41,20,6.13,20H9v-8H4.5v-2c0-4.13,3.36-7.5,7.5-7.5s7.5,3.36,7.5,7.5v2H15v8h2.87 c0.59,0,1.13-0.18,1.6-0.47c-0.14,1.11-1.08,1.97-2.22,1.97h-4.5c-0.41,0-0.75,0.34-0.75,0.75S12.34,23,12.75,23h4.5 c2.07,0,3.75-1.68,3.75-3.75V10C21,5.04,16.96,1,12,1z M7.5,18.5H6.13c-0.9,0-1.63-0.77-1.63-1.72V13.5h3V18.5z M17.87,18.5H16.5 v-5h3V16v0.78C19.5,17.73,18.77,18.5,17.87,18.5z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_hotspot.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_hotspot.xml index 670449ac8574..895123ca1759 100644 --- a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_hotspot.xml +++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_hotspot.xml @@ -1,36 +1,22 @@ + <!-- -/** - * 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. - */ + 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="M 12 11 C 12.8284271247 11 13.5 11.6715728753 13.5 12.5 C 13.5 13.3284271247 12.8284271247 14 12 14 C 11.1715728753 14 10.5 13.3284271247 10.5 12.5 C 10.5 11.6715728753 11.1715728753 11 12 11 Z" /> - <path - android:fillColor="#000000" - android:pathData="M15.18,16.39a0.51 0.51 ,0,0,0,0.71,0,5.5,5.5,0,0,0,0-7.78,5.52,5.52,0,0,0-7.78,0,5.5,5.5,0,0,0,0,7.78 0.5 0.5,0,0,0,0.35 0.15 0.51 0.51 ,0,0,0,0.36-0.15 0.51 0.51,0,0,0,0-0.71,4.5,4.5,0,1,1,6.36,0A0.51 0.51 ,0,0,0,15.18,16.39Z" /> - <path - android:fillColor="#000000" - android:pathData="M18,19.22a0.49 0.49 ,0,0,0,0.35 0.14 0.5 0.5 ,0,0,0,0.36-0.14,9.5,9.5,0,1,0-13.44,0,0.51 0.51 ,0,0,0,0.71,0,0.5 0.5 ,0,0,0,0-0.71,8.5,8.5,0,0,1,12-12,8.5,8.5,0,0,1,0,12A0.5 0.5 ,0,0,0,18,19.22Z" /> +<vector android:height="18dp" android:viewportHeight="24" android:viewportWidth="24" android:width="18dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M12,14c-0.83,0-1.5-0.67-1.5-1.5S11.17,11,12,11s1.5,0.67,1.5,1.5S12.83,14,12,14z"/> + <path android:fillColor="@android:color/white" android:pathData="M8.46,16.79c-0.19,0-0.38-0.07-0.53-0.22c-1.09-1.09-1.68-2.53-1.68-4.07s0.6-2.98,1.68-4.07 c2.24-2.24,5.89-2.24,8.13,0c1.09,1.09,1.68,2.53,1.68,4.07s-0.6,2.98-1.68,4.07c-0.29,0.29-0.77,0.29-1.06,0 s-0.29-0.77,0-1.06c0.8-0.8,1.24-1.87,1.24-3c0-1.14-0.44-2.2-1.24-3.01c-1.66-1.66-4.35-1.66-6.01,0 c-0.8,0.8-1.24,1.87-1.24,3c0,1.14,0.44,2.2,1.24,3.01c0.29,0.29,0.29,0.77,0,1.06C8.85,16.71,8.66,16.79,8.46,16.79z"/> + <path android:fillColor="@android:color/white" android:pathData="M18.36,19.61c-0.19,0-0.38-0.07-0.53-0.22c-0.29-0.29-0.29-0.77,0-1.06c1.56-1.56,2.42-3.63,2.42-5.83 s-0.86-4.28-2.42-5.83c-3.22-3.22-8.45-3.22-11.67,0C4.61,8.22,3.75,10.3,3.75,12.5s0.86,4.28,2.42,5.83 c0.29,0.29,0.29,0.77,0,1.06s-0.77,0.29-1.06,0c-1.84-1.84-2.86-4.29-2.86-6.89s1.01-5.05,2.86-6.89c3.8-3.8,9.99-3.8,13.79,0 c1.84,1.84,2.86,4.29,2.86,6.89s-1.01,5.05-2.86,6.89C18.75,19.54,18.56,19.61,18.36,19.61z"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_info.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_info.xml index 0e108ca7924c..7f060a4e555e 100644 --- a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_info.xml +++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_info.xml @@ -1,36 +1,22 @@ + <!-- -/** - * 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. - */ + 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="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="M12,11a0.5 0.5 ,0,0,0-0.5 0.5 v5a0.5 0.5 ,0,0,0,1,0v-5A0.5 0.5 ,0,0,0,12,11Z" /> - <path - android:fillColor="#000000" - android:pathData="M 12 7 C 12.4142135624 7 12.75 7.33578643763 12.75 7.75 C 12.75 8.16421356237 12.4142135624 8.5 12 8.5 C 11.5857864376 8.5 11.25 8.16421356237 11.25 7.75 C 11.25 7.33578643763 11.5857864376 7 12 7 Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M11.99,2C6.47,2,2,6.48,2,12c0,5.52,4.47,10,9.99,10C17.52,22,22,17.52,22,12C22,6.48,17.52,2,11.99,2z M11.99,20.5 c-4.68,0-8.49-3.81-8.49-8.5c0-4.69,3.81-8.5,8.49-8.5c4.69,0,8.51,3.81,8.51,8.5C20.5,16.69,16.68,20.5,11.99,20.5z"/> + <path android:fillColor="@android:color/white" android:pathData="M12,10.5c-0.41,0-0.75,0.34-0.75,0.75v5c0,0.41,0.34,0.75,0.75,0.75s0.75-0.34,0.75-0.75v-5 C12.75,10.84,12.41,10.5,12,10.5z"/> + <path android:fillColor="@android:color/white" android:pathData="M 12 7 C 12.5522847498 7 13 7.44771525017 13 8 C 13 8.55228474983 12.5522847498 9 12 9 C 11.4477152502 9 11 8.55228474983 11 8 C 11 7.44771525017 11.4477152502 7 12 7 Z"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_info_outline.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_info_outline.xml new file mode 100644 index 000000000000..7f060a4e555e --- /dev/null +++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_info_outline.xml @@ -0,0 +1,22 @@ + +<!-- + 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 android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M11.99,2C6.47,2,2,6.48,2,12c0,5.52,4.47,10,9.99,10C17.52,22,22,17.52,22,12C22,6.48,17.52,2,11.99,2z M11.99,20.5 c-4.68,0-8.49-3.81-8.49-8.5c0-4.69,3.81-8.5,8.49-8.5c4.69,0,8.51,3.81,8.51,8.5C20.5,16.69,16.68,20.5,11.99,20.5z"/> + <path android:fillColor="@android:color/white" android:pathData="M12,10.5c-0.41,0-0.75,0.34-0.75,0.75v5c0,0.41,0.34,0.75,0.75,0.75s0.75-0.34,0.75-0.75v-5 C12.75,10.84,12.41,10.5,12,10.5z"/> + <path android:fillColor="@android:color/white" android:pathData="M 12 7 C 12.5522847498 7 13 7.44771525017 13 8 C 13 8.55228474983 12.5522847498 9 12 9 C 11.4477152502 9 11 8.55228474983 11 8 C 11 7.44771525017 11.4477152502 7 12 7 Z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_invert_colors.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_invert_colors.xml new file mode 100644 index 000000000000..5c516f706843 --- /dev/null +++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_invert_colors.xml @@ -0,0 +1,20 @@ + +<!-- + 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 android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M12,2.27L12,2.27C7.02,7.25,4.02,9.61,4.02,14.02C4.02,18.43,7.59,22,12,22s7.98-3.57,7.98-7.98 c0-2.48-0.95-4.31-2.67-6.33C15.98,6.12,14.18,4.45,12,2.27z M5.52,14.02c0-3.26,2.08-5.3,5.85-9.01C11.57,4.8,11.79,4.6,12,4.38 V20.5C8.43,20.5,5.52,17.59,5.52,14.02z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_location.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_location.xml new file mode 100644 index 000000000000..1daa5a5aa99a --- /dev/null +++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_location.xml @@ -0,0 +1,21 @@ + +<!-- + 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 android:height="17dp" android:viewportHeight="24" android:viewportWidth="24" android:width="17dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M12,21.5c0,0,7-5.34,7-11.25c0-4-3.13-7.25-7-7.25c-3.87,0-7,3.25-7,7.25C5,16.16,12,21.5,12,21.5z M12,4.5 c3.03,0,5.5,2.58,5.5,5.75c0,3.91-3.74,7.72-5.51,9.29C9.9,17.68,6.5,13.89,6.5,10.25C6.5,7.08,8.97,4.5,12,4.5z"/> + <path android:fillColor="@android:color/white" android:pathData="M15,10c0-1.66-1.34-3-3-3c-1.66,0-3,1.34-3,3c0,1.66,1.34,3,3,3C13.66,13,15,11.66,15,10z M10.5,10 c0-0.83,0.67-1.5,1.5-1.5s1.5,0.67,1.5,1.5s-0.67,1.5-1.5,1.5S10.5,10.83,10.5,10z"/> +</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 index 04a2c24ce45a..310490338a17 100644 --- a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_lockscreen_ime.xml +++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_lockscreen_ime.xml @@ -1,57 +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. - */ + 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 android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M21,4H3C1.9,4,1,4.9,1,6v13c0,1.1,0.9,2,2,2h18c1.1,0,2-0.9,2-2V6C23,4.9,22.1,4,21,4z M21.5,19c0,0.27-0.23,0.5-0.5,0.5 H3c-0.27,0-0.5-0.23-0.5-0.5V6c0-0.27,0.23-0.5,0.5-0.5h18c0.27,0,0.5,0.23,0.5,0.5V19z"/> + <path android:fillColor="@android:color/white" android:pathData="M9.75,8h0.5C10.66,8,11,8.34,11,8.75v0.5C11,9.66,10.66,10,10.25,10h-0.5C9.34,10,9,9.66,9,9.25v-0.5 C9,8.34,9.34,8,9.75,8z"/> + <path android:fillColor="@android:color/white" android:pathData="M5.75,8h0.5C6.66,8,7,8.34,7,8.75v0.5C7,9.66,6.66,10,6.25,10h-0.5C5.34,10,5,9.66,5,9.25v-0.5C5,8.34,5.34,8,5.75,8z"/> + <path android:fillColor="@android:color/white" android:pathData="M13.75,8h0.5C14.66,8,15,8.34,15,8.75v0.5C15,9.66,14.66,10,14.25,10h-0.5C13.34,10,13,9.66,13,9.25v-0.5 C13,8.34,13.34,8,13.75,8z"/> + <path android:fillColor="@android:color/white" android:pathData="M9.75,12h0.5c0.41,0,0.75,0.34,0.75,0.75v0.5c0,0.41-0.34,0.75-0.75,0.75h-0.5C9.34,14,9,13.66,9,13.25v-0.5 C9,12.34,9.34,12,9.75,12z"/> + <path android:fillColor="@android:color/white" android:pathData="M5.75,12h0.5C6.66,12,7,12.34,7,12.75v0.5C7,13.66,6.66,14,6.25,14h-0.5C5.34,14,5,13.66,5,13.25v-0.5 C5,12.34,5.34,12,5.75,12z"/> + <path android:fillColor="@android:color/white" android:pathData="M13.75,12h0.5c0.41,0,0.75,0.34,0.75,0.75v0.5c0,0.41-0.34,0.75-0.75,0.75h-0.5C13.34,14,13,13.66,13,13.25v-0.5 C13,12.34,13.34,12,13.75,12z"/> + <path android:fillColor="@android:color/white" android:pathData="M17.75,8h0.5C18.66,8,19,8.34,19,8.75v0.5C19,9.66,18.66,10,18.25,10h-0.5C17.34,10,17,9.66,17,9.25v-0.5 C17,8.34,17.34,8,17.75,8z"/> + <path android:fillColor="@android:color/white" android:pathData="M17.75,12h0.5c0.41,0,0.75,0.34,0.75,0.75v0.5c0,0.41-0.34,0.75-0.75,0.75h-0.5C17.34,14,17,13.66,17,13.25v-0.5 C17,12.34,17.34,12,17.75,12z"/> + <path android:fillColor="@android:color/white" android:pathData="M15.5,17h-7C8.22,17,8,16.78,8,16.5S8.22,16,8.5,16h7c0.28,0,0.5,0.22,0.5,0.5S15.78,17,15.5,17z"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_notifications_alert.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_notifications_alert.xml index 2b9e3719961d..e3b4ef7dd69f 100644 --- a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_notifications_alert.xml +++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_notifications_alert.xml @@ -1,39 +1,23 @@ + <!-- -/** - * 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. - */ + 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="M12,2.5A1.5,1.5,0,0,0,10.5,4v0.2A6,6,0,0,0,6,10v5.5a0.5 0.5 ,0,0,1-0.5 0.5 A1.5,1.5,0,0,0,4,17.5v1a0.5 0.5 ,0,0,0,0.5 0.5 h15a0.5 0.5 ,0,0,0,0.5-0.5v-1A1.5,1.5,0,0,0,18.5,16a0.5 0.5 ,0,0,1-0.5-0.5V10a6,6,0,0,0-4.5-5.8V4A1.5,1.5,0,0,0,12,2.5ZM17,10v5.5A1.5,1.5,0,0,0,18.5,17a0.5 0.5 ,0,0,1,0.5 0.5 V18H5v-0.5a0.5 0.5 ,0,0,1,0.5-0.5A1.5,1.5,0,0,0,7,15.5V10a5,5,0,0,1,10,0Z" /> - <path - android:fillColor="#000000" - android:pathData="M14,20H10a2,2,0,0,0,4,0Z" /> - <path - android:fillColor="#000000" - android:pathData="M6,3.2a9.24,9.24,0,0,0-3.26,7.05 0.5 0.5,0,0,0,1,0A8.25,8.25,0,0,1,6.66,4,0.5 0.5 ,0,0,0,6,3.2Z" /> - <path - android:fillColor="#000000" - android:pathData="M21.25,10.25A9.24,9.24,0,0,0,18,3.2a0.5 0.5 ,0,0,0-0.65 0.76 ,8.25,8.25,0,0,1,2.91,6.29 0.5 0.5,0,0,0,1,0Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M5.85,3.01C3.72,4.82,2.5,7.46,2.5,10.25C2.5,10.66,2.84,11,3.25,11S4,10.66,4,10.25c0-2.35,1.03-4.57,2.82-6.1 C7.14,3.88,7.17,3.41,6.91,3.1C6.64,2.78,6.17,2.74,5.85,3.01z"/> + <path android:fillColor="@android:color/white" android:pathData="M21.5,10.25c0-2.79-1.22-5.43-3.35-7.24c-0.32-0.27-0.79-0.23-1.06,0.08c-0.27,0.32-0.23,0.79,0.08,1.06 C18.97,5.68,20,7.9,20,10.25c0,0.41,0.34,0.75,0.75,0.75S21.5,10.66,21.5,10.25z"/> + <path android:fillColor="@android:color/white" android:pathData="M12,2.5c-0.83,0-1.5,0.67-1.5,1.5v0.7C7.91,5.36,6,7.71,6,10.5V15c0,0.55-0.45,1-1,1s-1,0.45-1,1v2h16v-2 c0-0.55-0.45-1-1-1s-1-0.45-1-1v-4.5c0-2.79-1.91-5.14-4.5-5.8V4C13.5,3.17,12.83,2.5,12,2.5z M16.5,10.5V15 c0,1.21,0.86,2.22,2,2.45v0.05h-13v-0.05c1.14-0.23,2-1.24,2-2.45v-4.5C7.5,8.02,9.52,6,12,6S16.5,8.02,16.5,10.5z"/> + <path android:fillColor="@android:color/white" android:pathData="M14,20h-4c0,1.1,0.9,2,2,2S14,21.1,14,20z"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_notifications_silence.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_notifications_silence.xml index 838f75268d69..e60b7da2c53a 100644 --- a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_notifications_silence.xml +++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_notifications_silence.xml @@ -1,36 +1,22 @@ + <!-- -/** - * 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. - */ + 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="M12,5a5,5,0,0,1,5,5v5.17l3,3V17.5A1.5,1.5,0,0,0,18.5,16a0.5 0.5 ,0,0,1-0.5-0.5V10a6,6,0,0,0-4.5-5.8V4a1.5,1.5,0,0,0-3,0v0.2A6,6,0,0,0,7.68,5.85l0.71 0.71 A5,5,0,0,1,12,5Z" /> - <path - android:fillColor="#000000" - android:pathData="M14,20H10a2,2,0,0,0,4,0Z" /> - <path - android:fillColor="#000000" - android:pathData="M20.85,21.15l-18-18a0.48 0.48 ,0,0,0-0.7,0h0a0.48 0.48 ,0,0,0,0,0.7L6.33,8A6.06,6.06,0,0,0,6,10v5.5a0.5 0.5 ,0,0,1-0.5 0.5 A1.5,1.5,0,0,0,4,17.5v1a0.5 0.5 ,0,0,0,0.5 0.5 H17.29l2.86,2.85a0.48 0.48 ,0,0,0,0.7,0h0A0.48 0.48 ,0,0,0,20.85,21.15ZM5,18v-0.5a0.5 0.5 ,0,0,1,0.5-0.5A1.5,1.5,0,0,0,7,15.5V10a4.83,4.83,0,0,1,0.15-1.15L16.29,18Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M12,6c2.48,0,4.5,2.02,4.5,4.5v3.8l3.5,3.5V17c0-0.55-0.45-1-1-1s-1-0.45-1-1v-4.5c0-2.79-1.91-5.14-4.5-5.8V4 c0-0.83-0.67-1.5-1.5-1.5S10.5,3.17,10.5,4v0.7C9.61,4.93,8.8,5.35,8.13,5.92L9.2,7C9.97,6.38,10.94,6,12,6z"/> + <path android:fillColor="@android:color/white" android:pathData="M14,20h-4c0,1.1,0.9,2,2,2S14,21.1,14,20z"/> + <path android:fillColor="@android:color/white" android:pathData="M21.03,20.97l-18-18c-0.29-0.29-0.77-0.29-1.06,0c0,0,0,0,0,0c-0.29,0.29-0.29,0.77,0,1.06l4.4,4.4 C6.14,9.08,6,9.77,6,10.5V15c0,0.55-0.45,1-1,1s-1,0.45-1,1v2h12.94l3.03,3.03c0.15,0.15,0.34,0.22,0.53,0.22s0.38-0.07,0.53-0.22 c0,0,0,0,0,0C21.32,21.74,21.32,21.26,21.03,20.97z M5.5,17.5v-0.05c1.14-0.23,2-1.24,2-2.45v-4.5c0-0.29,0.03-0.58,0.09-0.85 l7.85,7.85H5.5z"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_power_low.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_power_low.xml new file mode 100644 index 000000000000..388e1d3d69b3 --- /dev/null +++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_power_low.xml @@ -0,0 +1,22 @@ + +<!-- + 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 android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M12,13.5c0.41,0,0.75-0.34,0.75-0.75v-4C12.75,8.34,12.41,8,12,8s-0.75,0.34-0.75,0.75v4C11.25,13.16,11.59,13.5,12,13.5z"/> + <path android:fillColor="@android:color/white" android:pathData="M 12 15 C 12.5522847498 15 13 15.4477152502 13 16 C 13 16.5522847498 12.5522847498 17 12 17 C 11.4477152502 17 11 16.5522847498 11 16 C 11 15.4477152502 11.4477152502 15 12 15 Z"/> + <path android:fillColor="@android:color/white" android:pathData="M14,4c0-0.55-0.45-1-1-1h-2c-0.55,0-1,0.45-1,1H9C7.34,4,6,5.34,6,7v12c0,1.66,1.34,3,3,3h6c1.66,0,3-1.34,3-3V7 c0-1.66-1.34-3-3-3H14z M16.5,7v12c0,0.83-0.67,1.5-1.5,1.5H9c-0.83,0-1.5-0.67-1.5-1.5V7c0-0.83,0.67-1.5,1.5-1.5h6 C15.83,5.5,16.5,6.17,16.5,7z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_power_saver.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_power_saver.xml new file mode 100644 index 000000000000..2d04510d9f29 --- /dev/null +++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_power_saver.xml @@ -0,0 +1,21 @@ + +<!-- + 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 android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M9.75,13.75h1.5v1.5c0,0.41,0.34,0.75,0.75,0.75s0.75-0.34,0.75-0.75v-1.5h1.5c0.41,0,0.75-0.34,0.75-0.75 s-0.34-0.75-0.75-0.75h-1.5v-1.5c0-0.41-0.34-0.75-0.75-0.75s-0.75,0.34-0.75,0.75v1.5h-1.5C9.34,12.25,9,12.59,9,13 S9.34,13.75,9.75,13.75z"/> + <path android:fillColor="@android:color/white" android:pathData="M6,19c0,1.66,1.34,3,3,3h6c1.66,0,3-1.34,3-3V7c0-1.66-1.34-3-3-3h-1c0-0.55-0.45-1-1-1h-2c-0.55,0-1,0.45-1,1H9 C7.34,4,6,5.34,6,7V19z M7.5,7c0-0.83,0.67-1.5,1.5-1.5h6c0.83,0,1.5,0.67,1.5,1.5v12c0,0.83-0.67,1.5-1.5,1.5H9 c-0.83,0-1.5-0.67-1.5-1.5V7z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_auto_rotate.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_auto_rotate.xml deleted file mode 100644 index f98e2b8b2a24..000000000000 --- a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_auto_rotate.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.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" /> -</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_bluetooth_connecting.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_bluetooth_connecting.xml index 10b1cbf68543..86bfecc7d08c 100644 --- a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_bluetooth_connecting.xml +++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_bluetooth_connecting.xml @@ -1,36 +1,22 @@ + <!-- -/** - * 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. - */ + 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="M18.16,17.37a0.51 0.51 ,0,0,0,0.71,0,7.76,7.76,0,0,0,0-10.68 0.5 0.5,0,1,0-0.74 0.68 ,6.74,6.74,0,0,1,0,9.32A0.51 0.51 ,0,0,0,18.16,17.37Z" /> - <path - android:fillColor="#000000" - android:pathData="M16.27,14.47a0.51 0.51 ,0,0,0,0.7,0,3.48,3.48,0,0,0,0-4.92l-0.72 0.7 a2.47,2.47,0,0,1,0,3.51A0.5 0.5 ,0,0,0,16.27,14.47Z" /> - <path - android:fillColor="#000000" - android:pathData="M3.15,18.15a0.48 0.48 ,0,0,0,0,0.7 0.48 0.48,0,0,0,0.7,0L9,13.71V22h0.5a5.25,5.25,0,0,0,2.25-10A5.25,5.25,0,0,0,9.5,2H9v8.29L3.85,5.15a0.49 0.49 ,0,0,0-0.7 0.7 L9,11.71v0.58Zm10.63-1.4A4.26,4.26,0,0,1,10,21V12.53A4.26,4.26,0,0,1,13.78,16.75ZM10,3a4.25,4.25,0,0,1,0,8.44Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M18.2,16.49c-0.28,0.3-0.26,0.78,0.04,1.06c0.14,0.13,0.33,0.2,0.51,0.2c0.2,0,0.4-0.08,0.55-0.24 c1.42-1.53,2.2-3.49,2.2-5.51c0-2.02-0.78-3.97-2.2-5.51c-0.28-0.3-0.76-0.32-1.06-0.04c-0.3,0.28-0.32,0.76-0.04,1.06 C19.36,8.77,20,10.36,20,12C20,13.64,19.36,15.23,18.2,16.49z"/> + <path android:fillColor="@android:color/white" android:pathData="M16.35,9.36c-0.29,0.29-0.29,0.77,0,1.06C16.77,10.85,17,11.41,17,12s-0.23,1.16-0.66,1.58c-0.29,0.29-0.3,0.77,0,1.06 c0.15,0.15,0.34,0.22,0.53,0.22c0.19,0,0.38-0.07,0.53-0.22c0.71-0.7,1.1-1.64,1.1-2.64c0-1-0.39-1.94-1.09-2.64 C17.12,9.07,16.64,9.07,16.35,9.36z"/> + <path android:fillColor="@android:color/white" android:pathData="M2.97,19.03c0.15,0.15,0.34,0.22,0.53,0.22s0.38-0.07,0.53-0.22L9,14.06V22h0.75c2.96,0,5.37-2.41,5.37-5.38 c0-1.97-1.06-3.69-2.64-4.62c1.58-0.94,2.64-2.66,2.64-4.62C15.12,4.41,12.71,2,9.75,2H9v7.94L4.03,4.97 c-0.29-0.29-0.77-0.29-1.06,0s-0.29,0.77,0,1.06L8.94,12l-5.97,5.97C2.68,18.26,2.68,18.74,2.97,19.03z M10.5,3.57 c1.78,0.35,3.12,1.92,3.12,3.8s-1.34,3.45-3.12,3.8V3.57z M10.5,12.82c1.78,0.35,3.12,1.92,3.12,3.8s-1.34,3.45-3.12,3.8V12.82z"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_bluetooth_on.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_bluetooth_on.xml index e8664f6807a0..48b0dda1dc00 100644 --- a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_bluetooth_on.xml +++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_bluetooth_on.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="M16.78,7.25A5.27,5.27,0,0,0,11.5,2H11v8.29L5.85,5.15a0.49 0.49 ,0,0,0-0.7 0.7 L11,11.71v0.58L5.15,18.15a0.48 0.48 ,0,0,0,0,0.7 0.48 0.48,0,0,0,0.7,0L11,13.71V22h0.5a5.25,5.25,0,0,0,2.25-10A5.25,5.25,0,0,0,16.78,7.25Zm-1,9.5A4.26,4.26,0,0,1,12,21V12.53A4.26,4.26,0,0,1,15.78,16.75ZM12,11.47V3a4.25,4.25,0,0,1,0,8.44Z" /> + android:fillColor="#FFFFFF" + 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_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_cancel.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_cancel.xml index 40de6093f372..ee7ad6eff3d3 100644 --- a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_cancel.xml +++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_cancel.xml @@ -1,33 +1,21 @@ + <!-- -/** - * 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. - */ + 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="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.15,16.85a0.48 0.48 ,0,0,0,0.7,0L12,12.71l4.15,4.14a0.48 0.48 ,0,0,0,0.7,0,0.48 0.48 ,0,0,0,0-0.7L12.71,12l4.14-4.15a0.49 0.49 ,0,1,0-0.7-0.7L12,11.29,7.85,7.15a0.49 0.49 ,0,0,0-0.7 0.7 L11.29,12,7.15,16.15A0.48 0.48 ,0,0,0,7.15,16.85Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M12,22c5.52,0,10-4.48,10-10S17.52,2,12,2S2,6.48,2,12S6.48,22,12,22z M12,3.5c4.69,0,8.5,3.81,8.5,8.5s-3.81,8.5-8.5,8.5 c-4.69,0-8.5-3.81-8.5-8.5C3.5,7.31,7.31,3.5,12,3.5z"/> + <path android:fillColor="@android:color/white" android:pathData="M6.97,17.03c0.15,0.15,0.34,0.22,0.53,0.22s0.38-0.07,0.53-0.22L12,13.06l3.97,3.97c0.15,0.15,0.34,0.22,0.53,0.22 s0.38-0.07,0.53-0.22c0.29-0.29,0.29-0.77,0-1.06L13.06,12l3.97-3.97c0.29-0.29,0.29-0.77,0-1.06s-0.77-0.29-1.06,0L12,10.94 L8.03,6.97c-0.29-0.29-0.77-0.29-1.06,0s-0.29,0.77,0,1.06L10.94,12l-3.97,3.97C6.68,16.26,6.68,16.74,6.97,17.03z"/> </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_qs_no_sim.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_no_sim.xml index e17d646ce157..799aaa0dcebf 100644 --- a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_no_sim.xml +++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_no_sim.xml @@ -1,33 +1,21 @@ + <!-- -/** - * 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. - */ + 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="M10.41,4H17a1,1,0,0,1,1,1V16.17l1,1V5a2,2,0,0,0-2-2H10L7.42,5.58l0.7 0.71 Z" /> - <path - android:fillColor="#000000" - android:pathData="M20.85,21.15l-18-18a0.48 0.48 ,0,0,0-0.7,0h0a0.48 0.48 ,0,0,0,0,0.7l3.5,3.5L5,8V19a2,2,0,0,0,2,2H17a2,2,0,0,0,1.55-0.75l1.6,1.6a0.48 0.48 ,0,0,0,0.7,0h0A0.48 0.48 ,0,0,0,20.85,21.15ZM17,20H7a1,1,0,0,1-1-1V8.41l0.35-0.35L17.83,19.53A1,1,0,0,1,17,20Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M10.62,4.5H16c0.83,0,1.5,0.67,1.5,1.5v9.3l1.5,1.5V6c0-1.66-1.34-3-3-3h-6L7.6,5.4l1.06,1.06L10.62,4.5z"/> + <path android:fillColor="@android:color/white" android:pathData="M5,8v10c0,1.66,1.34,3,3,3h8c0.81,0,1.55-0.33,2.09-0.85l1.88,1.88c0.15,0.15,0.34,0.22,0.53,0.22s0.38-0.07,0.53-0.22 c0,0,0,0,0,0c0.29-0.29,0.29-0.77,0-1.06l-18-18c-0.29-0.29-0.77-0.29-1.06,0c0,0,0,0,0,0c-0.29,0.29-0.29,0.77,0,1.06l3.5,3.5L5,8 z M16,19.5H8c-0.83,0-1.5-0.67-1.5-1.5V8.62l0.03-0.03l10.5,10.5C16.76,19.34,16.4,19.5,16,19.5z"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_vpn.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_vpn.xml deleted file mode 100644 index e5c1f4e830c3..000000000000 --- a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_vpn.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="M7.5,9A2.5,2.5,0,1,0,10,11.5,2.5,2.5,0,0,0,7.5,9Zm0,4A1.5,1.5,0,1,1,9,11.5,1.5,1.5,0,0,1,7.5,13Z" /> - <path - android:fillColor="#000000" - android:pathData="M21.5,9H12.39A5.5,5.5,0,0,0,2.12,10.32,5.58,5.58,0,0,0,3.23,15a5.49,5.49,0,0,0,9.16-1H15v1.5A1.5,1.5,0,0,0,16.5,17h2A1.5,1.5,0,0,0,20,15.5V14h1.5a0.5 0.5 ,0,0,0,0.5-0.5v-4A0.5 0.5 ,0,0,0,21.5,9ZM21,13H19.5a0.5 0.5 ,0,0,0-0.5 0.5 v2a0.5 0.5 ,0,0,1-0.5 0.5 h-2a0.5 0.5 ,0,0,1-0.5-0.5v-2a0.5 0.5 ,0,0,0-0.5-0.5H12.08a0.51 0.51 ,0,0,0-0.46 0.3 ,4.5,4.5,0,0,1-7.61,1,4.57,4.57,0,0,1-0.91-3.82A4.48,4.48,0,0,1,6.7,7.07,4.53,4.53,0,0,1,11.62,9.7a0.51 0.51 ,0,0,0,0.46 0.3 H21Z" /> -</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_wifi_0.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_wifi_0.xml index ad48771ee67a..e90bd08c05b2 100644 --- a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_wifi_0.xml +++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_wifi_0.xml @@ -1,54 +1,24 @@ + <!-- -/** - * 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. - */ + 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:fillAlpha="0.3" - android:strokeAlpha="0.3" - android:strokeWidth="1" - android:pathData="M 11.99 16.5 C 12.8184271247 16.5 13.49 17.1715728753 13.49 18 C 13.49 18.8284271247 12.8184271247 19.5 11.99 19.5 C 11.1615728753 19.5 10.49 18.8284271247 10.49 18 C 10.49 17.1715728753 11.1615728753 16.5 11.99 16.5 Z" /> - <path - android:fillColor="#000000" - android:fillAlpha="0.3" - android:strokeAlpha="0.3" - android:strokeWidth="1" - android:pathData="M4.87,11a0.5 0.5 ,0,0,0,0,0.71 0.51 0.51,0,0,0,0.71,0,9.07,9.07,0,0,1,12.83,0,0.52 0.52 ,0,0,0,0.71,0,0.51 0.51 ,0,0,0,0-0.71A10.08,10.08,0,0,0,4.87,11Z" /> - <path - android:fillColor="#000000" - android:fillAlpha="0.3" - android:strokeAlpha="0.3" - android:strokeWidth="1" - android:pathData="M21.5,9a0.47 0.47 ,0,0,0,0.35-0.15 0.48 0.48,0,0,0,0-0.7,13.77,13.77,0,0,0-19.7,0,0.49 0.49 ,0,0,0,0.7 0.7 ,12.8,12.8,0,0,1,18.3,0A0.47 0.47 ,0,0,0,21.5,9Z" /> - <path - android:fillColor="#000000" - android:fillAlpha="0.3" - android:strokeAlpha="0.3" - android:strokeWidth="1" - android:pathData="M7.7,13.78a0.51 0.51 ,0,0,0,0,0.71 0.5 0.5,0,0,0,0.71,0,5.06,5.06,0,0,1,6.77-0.32,3.85,3.85,0,0,1,0.82-0.62A6.08,6.08,0,0,0,7.7,13.78Z" /> - <path - android:fillColor="#000000" - android:pathData="M16.15,15.15a0.48 0.48 ,0,0,0,0,0.7L18.29,18l-2.14,2.15a0.48 0.48 ,0,0,0,0,0.7 0.48 0.48,0,0,0,0.7,0L19,18.71l2.15,2.14a0.48 0.48 ,0,0,0,0.7,0,0.48 0.48 ,0,0,0,0-0.7L19.71,18l2.14-2.15a0.49 0.49 ,0,1,0-0.7-0.7L19,17.29l-2.15-2.14A0.48 0.48 ,0,0,0,16.15,15.15Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillAlpha="0.3" android:fillColor="@android:color/white" android:pathData="M12,11.75c-1.8,0-3.5,0.7-4.78,1.96c-0.29,0.29-0.3,0.77-0.01,1.06c0.29,0.29,0.77,0.3,1.06,0.01 c1-0.99,2.32-1.53,3.73-1.53c0.89,0,1.73,0.24,2.5,0.65c0.46-0.37,0.99-0.65,1.58-0.79C14.9,12.24,13.49,11.75,12,11.75z" android:strokeAlpha="0.3" android:strokeWidth="1"/> + <path android:fillColor="@android:color/white" android:pathData="M21.92,16.08c-0.29-0.29-0.77-0.29-1.06,0L19,17.94l-1.86-1.86c-0.29-0.29-0.77-0.29-1.06,0s-0.29,0.77,0,1.06L17.94,19 l-1.86,1.86c-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.22L19,20.06l1.86,1.86 c0.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.06L20.06,19l1.86-1.86 C22.22,16.84,22.22,16.37,21.92,16.08z"/> + <path android:fillAlpha="0.3" android:fillColor="@android:color/white" android:pathData="M13.5,18.5c0-0.44-0.2-0.84-0.5-1.11C12.73,17.15,12.39,17,12,17c-0.83,0-1.5,0.67-1.5,1.5S11.17,20,12,20 c0.39,0,0.73-0.15,1-0.39C13.3,19.34,13.5,18.95,13.5,18.5z" android:strokeAlpha="0.3" android:strokeWidth="1"/> + <path android:fillAlpha="0.3" android:fillColor="@android:color/white" android:pathData="M18.89,11.62c0.15,0.15,0.34,0.22,0.53,0.22c0.19,0,0.38-0.07,0.53-0.22c0.29-0.29,0.29-0.77,0-1.06 C17.83,8.43,15,7.25,12,7.25s-5.83,1.17-7.95,3.3c-0.29,0.29-0.29,0.77,0,1.06c0.29,0.29,0.77,0.29,1.06,0 C6.95,9.77,9.4,8.75,12,8.75S17.05,9.77,18.89,11.62z" android:strokeAlpha="0.3" android:strokeWidth="1"/> + <path android:fillAlpha="0.3" android:fillColor="@android:color/white" android:pathData="M22.08,8.43c0.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.06 C20.16,4.39,16.21,2.75,12,2.75S3.84,4.39,0.86,7.37c-0.29,0.29-0.29,0.77,0,1.06s0.77,0.29,1.06,0C4.62,5.74,8.19,4.25,12,4.25 S19.38,5.74,22.08,8.43z" android:strokeAlpha="0.3" android:strokeWidth="1"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_wifi_1.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_wifi_1.xml index cc87827dbf3a..ef405adb56de 100644 --- a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_wifi_1.xml +++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_wifi_1.xml @@ -1,51 +1,24 @@ + <!-- -/** - * 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. - */ + 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="M 11.99 16.5 C 12.8184271247 16.5 13.49 17.1715728753 13.49 18 C 13.49 18.8284271247 12.8184271247 19.5 11.99 19.5 C 11.1615728753 19.5 10.49 18.8284271247 10.49 18 C 10.49 17.1715728753 11.1615728753 16.5 11.99 16.5 Z" /> - <path - android:fillColor="#000000" - android:fillAlpha="0.3" - android:strokeAlpha="0.3" - android:strokeWidth="1" - android:pathData="M5.58,11.66a9.07,9.07,0,0,1,12.83,0,0.52 0.52 ,0,0,0,0.71,0,0.51 0.51 ,0,0,0,0-0.71A10.08,10.08,0,0,0,4.87,11a0.5 0.5 ,0,0,0,0,0.71A0.51 0.51 ,0,0,0,5.58,11.66Z" /> - <path - android:fillColor="#000000" - android:fillAlpha="0.3" - android:strokeAlpha="0.3" - android:strokeWidth="1" - android:pathData="M2.15,8.85a0.48 0.48 ,0,0,0,0.7,0,12.8,12.8,0,0,1,18.3,0,0.48 0.48 ,0,0,0,0.7,0,0.48 0.48 ,0,0,0,0-0.7,13.77,13.77,0,0,0-19.7,0A0.48 0.48 ,0,0,0,2.15,8.85Z" /> - <path - android:fillColor="#000000" - android:fillAlpha="0.3" - android:strokeAlpha="0.3" - android:strokeWidth="1" - android:pathData="M7.7,13.78a0.51 0.51 ,0,0,0,0,0.71 0.5 0.5,0,0,0,0.71,0,5.06,5.06,0,0,1,6.77-0.32,3.85,3.85,0,0,1,0.82-0.62A6.08,6.08,0,0,0,7.7,13.78Z" /> - <path - android:fillColor="#000000" - android:pathData="M16.15,20.85a0.48 0.48 ,0,0,0,0.7,0L19,18.71l2.15,2.14a0.48 0.48 ,0,0,0,0.7,0,0.48 0.48 ,0,0,0,0-0.7L19.71,18l2.14-2.15a0.49 0.49 ,0,1,0-0.7-0.7L19,17.29l-2.15-2.14a0.49 0.49 ,0,0,0-0.7 0.7 L18.29,18l-2.14,2.15A0.48 0.48 ,0,0,0,16.15,20.85Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillAlpha="0.3" android:fillColor="@android:color/white" android:pathData="M12,11.75c-1.8,0-3.5,0.7-4.78,1.96c-0.29,0.29-0.3,0.77-0.01,1.06c0.29,0.29,0.77,0.3,1.06,0.01 c1-0.99,2.32-1.53,3.73-1.53c0.89,0,1.73,0.24,2.5,0.65c0.46-0.37,0.99-0.65,1.58-0.79C14.9,12.24,13.49,11.75,12,11.75z" android:strokeAlpha="0.3" android:strokeWidth="1"/> + <path android:fillColor="@android:color/white" android:pathData="M21.92,16.08c-0.29-0.29-0.77-0.29-1.06,0L19,17.94l-1.86-1.86c-0.29-0.29-0.77-0.29-1.06,0s-0.29,0.77,0,1.06L17.94,19 l-1.86,1.86c-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.22L19,20.06l1.86,1.86 c0.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.06L20.06,19l1.86-1.86 C22.22,16.84,22.22,16.37,21.92,16.08z"/> + <path android:fillColor="@android:color/white" android:pathData="M13.5,18.5c0-0.44-0.2-0.84-0.5-1.11C12.73,17.15,12.39,17,12,17c-0.83,0-1.5,0.67-1.5,1.5S11.17,20,12,20 c0.39,0,0.73-0.15,1-0.39C13.3,19.34,13.5,18.95,13.5,18.5z"/> + <path android:fillAlpha="0.3" android:fillColor="@android:color/white" android:pathData="M18.89,11.62c0.15,0.15,0.34,0.22,0.53,0.22c0.19,0,0.38-0.07,0.53-0.22c0.29-0.29,0.29-0.77,0-1.06 C17.83,8.43,15,7.25,12,7.25s-5.83,1.17-7.95,3.3c-0.29,0.29-0.29,0.77,0,1.06c0.29,0.29,0.77,0.29,1.06,0 C6.95,9.77,9.4,8.75,12,8.75S17.05,9.77,18.89,11.62z" android:strokeAlpha="0.3" android:strokeWidth="1"/> + <path android:fillAlpha="0.3" android:fillColor="@android:color/white" android:pathData="M22.08,8.43c0.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.06 C20.16,4.39,16.21,2.75,12,2.75S3.84,4.39,0.86,7.37c-0.29,0.29-0.29,0.77,0,1.06s0.77,0.29,1.06,0C4.62,5.74,8.19,4.25,12,4.25 S19.38,5.74,22.08,8.43z" android:strokeAlpha="0.3" android:strokeWidth="1"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_wifi_2.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_wifi_2.xml index eceaa743284a..60798d6fe0c0 100644 --- a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_wifi_2.xml +++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_wifi_2.xml @@ -1,48 +1,24 @@ + <!-- -/** - * 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. - */ + 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="M 11.99 16.5 C 12.8184271247 16.5 13.49 17.1715728753 13.49 18 C 13.49 18.8284271247 12.8184271247 19.5 11.99 19.5 C 11.1615728753 19.5 10.49 18.8284271247 10.49 18 C 10.49 17.1715728753 11.1615728753 16.5 11.99 16.5 Z" /> - <path - android:fillColor="#000000" - android:fillAlpha="0.3" - android:strokeAlpha="0.3" - android:strokeWidth="1" - android:pathData="M18.41,11.66a0.52 0.52 ,0,0,0,0.71,0,0.51 0.51 ,0,0,0,0-0.71A10.08,10.08,0,0,0,4.87,11a0.5 0.5 ,0,0,0,0,0.71 0.51 0.51,0,0,0,0.71,0,9.07,9.07,0,0,1,12.83,0Z" /> - <path - android:fillColor="#000000" - android:fillAlpha="0.3" - android:strokeAlpha="0.3" - android:strokeWidth="1" - android:pathData="M21.5,9a0.47 0.47 ,0,0,0,0.35-0.15 0.48 0.48,0,0,0,0-0.7,13.77,13.77,0,0,0-19.7,0,0.49 0.49 ,0,0,0,0.7 0.7 ,12.8,12.8,0,0,1,18.3,0A0.47 0.47 ,0,0,0,21.5,9Z" /> - <path - android:fillColor="#000000" - android:pathData="M7.7,13.78a0.51 0.51 ,0,0,0,0,0.71 0.5 0.5,0,0,0,0.71,0,5.06,5.06,0,0,1,6.77-0.32,3.85,3.85,0,0,1,0.82-0.62A6.08,6.08,0,0,0,7.7,13.78Z" /> - <path - android:fillColor="#000000" - android:pathData="M16.15,15.15a0.48 0.48 ,0,0,0,0,0.7L18.29,18l-2.14,2.15a0.48 0.48 ,0,0,0,0,0.7 0.48 0.48,0,0,0,0.7,0L19,18.71l2.15,2.14a0.48 0.48 ,0,0,0,0.7,0,0.48 0.48 ,0,0,0,0-0.7L19.71,18l2.14-2.15a0.49 0.49 ,0,1,0-0.7-0.7L19,17.29l-2.15-2.14A0.48 0.48 ,0,0,0,16.15,15.15Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M12,11.75c-1.8,0-3.5,0.7-4.78,1.96c-0.29,0.29-0.3,0.77-0.01,1.06c0.29,0.29,0.77,0.3,1.06,0.01 c1-0.99,2.32-1.53,3.73-1.53c0.89,0,1.73,0.24,2.5,0.65c0.46-0.37,0.99-0.65,1.58-0.79C14.9,12.24,13.49,11.75,12,11.75z"/> + <path android:fillColor="@android:color/white" android:pathData="M21.92,16.08c-0.29-0.29-0.77-0.29-1.06,0L19,17.94l-1.86-1.86c-0.29-0.29-0.77-0.29-1.06,0s-0.29,0.77,0,1.06L17.94,19 l-1.86,1.86c-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.22L19,20.06l1.86,1.86 c0.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.06L20.06,19l1.86-1.86 C22.22,16.84,22.22,16.37,21.92,16.08z"/> + <path android:fillColor="@android:color/white" android:pathData="M13.5,18.5c0-0.44-0.2-0.84-0.5-1.11C12.73,17.15,12.39,17,12,17c-0.83,0-1.5,0.67-1.5,1.5S11.17,20,12,20 c0.39,0,0.73-0.15,1-0.39C13.3,19.34,13.5,18.95,13.5,18.5z"/> + <path android:fillAlpha="0.3" android:fillColor="@android:color/white" android:pathData="M18.89,11.62c0.15,0.15,0.34,0.22,0.53,0.22c0.19,0,0.38-0.07,0.53-0.22c0.29-0.29,0.29-0.77,0-1.06 C17.83,8.43,15,7.25,12,7.25s-5.83,1.17-7.95,3.3c-0.29,0.29-0.29,0.77,0,1.06c0.29,0.29,0.77,0.29,1.06,0 C6.95,9.77,9.4,8.75,12,8.75S17.05,9.77,18.89,11.62z" android:strokeAlpha="0.3" android:strokeWidth="1"/> + <path android:fillAlpha="0.3" android:fillColor="@android:color/white" android:pathData="M22.08,8.43c0.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.06 C20.16,4.39,16.21,2.75,12,2.75S3.84,4.39,0.86,7.37c-0.29,0.29-0.29,0.77,0,1.06s0.77,0.29,1.06,0C4.62,5.74,8.19,4.25,12,4.25 S19.38,5.74,22.08,8.43z" android:strokeAlpha="0.3" android:strokeWidth="1"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_wifi_3.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_wifi_3.xml index 7640376dfe4a..acd2c9acfa52 100644 --- a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_wifi_3.xml +++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_wifi_3.xml @@ -1,45 +1,24 @@ + <!-- -/** - * 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. - */ + 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="M 11.99 16.5 C 12.8184271247 16.5 13.49 17.1715728753 13.49 18 C 13.49 18.8284271247 12.8184271247 19.5 11.99 19.5 C 11.1615728753 19.5 10.49 18.8284271247 10.49 18 C 10.49 17.1715728753 11.1615728753 16.5 11.99 16.5 Z" /> - <path - android:fillColor="#000000" - android:pathData="M18.41,11.66a0.52 0.52 ,0,0,0,0.71,0,0.51 0.51 ,0,0,0,0-0.71A10.08,10.08,0,0,0,4.87,11a0.5 0.5 ,0,0,0,0,0.71 0.51 0.51,0,0,0,0.71,0,9.07,9.07,0,0,1,12.83,0Z" /> - <path - android:fillColor="#000000" - android:fillAlpha="0.3" - android:strokeAlpha="0.3" - android:strokeWidth="1" - android:pathData="M2.15,8.85a0.48 0.48 ,0,0,0,0.7,0,12.8,12.8,0,0,1,18.3,0,0.48 0.48 ,0,0,0,0.7,0,0.48 0.48 ,0,0,0,0-0.7,13.77,13.77,0,0,0-19.7,0A0.48 0.48 ,0,0,0,2.15,8.85Z" /> - <path - android:fillColor="#000000" - android:pathData="M12,12A6.05,6.05,0,0,0,7.7,13.78a0.51 0.51 ,0,0,0,0,0.71 0.5 0.5,0,0,0,0.71,0,5,5,0,0,1,6.77-0.32,3.77,3.77,0,0,1,0.84-0.63A6,6,0,0,0,12,12Z" /> - <path - android:fillColor="#000000" - android:pathData="M16.15,15.15a0.48 0.48 ,0,0,0,0,0.7L18.29,18l-2.14,2.15a0.48 0.48 ,0,0,0,0,0.7 0.48 0.48,0,0,0,0.7,0L19,18.71l2.15,2.14a0.48 0.48 ,0,0,0,0.7,0,0.48 0.48 ,0,0,0,0-0.7L19.71,18l2.14-2.15a0.49 0.49 ,0,1,0-0.7-0.7L19,17.29l-2.15-2.14A0.48 0.48 ,0,0,0,16.15,15.15Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M12,11.75c-1.8,0-3.5,0.7-4.78,1.96c-0.29,0.29-0.3,0.77-0.01,1.06c0.29,0.29,0.77,0.3,1.06,0.01 c1-0.99,2.32-1.53,3.73-1.53c0.89,0,1.73,0.24,2.5,0.65c0.46-0.37,0.99-0.65,1.58-0.79C14.9,12.24,13.49,11.75,12,11.75z"/> + <path android:fillColor="@android:color/white" android:pathData="M21.92,16.08c-0.29-0.29-0.77-0.29-1.06,0L19,17.94l-1.86-1.86c-0.29-0.29-0.77-0.29-1.06,0s-0.29,0.77,0,1.06L17.94,19 l-1.86,1.86c-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.22L19,20.06l1.86,1.86 c0.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.06L20.06,19l1.86-1.86 C22.22,16.84,22.22,16.37,21.92,16.08z"/> + <path android:fillColor="@android:color/white" android:pathData="M13.5,18.5c0-0.44-0.2-0.84-0.5-1.11C12.73,17.15,12.39,17,12,17c-0.83,0-1.5,0.67-1.5,1.5S11.17,20,12,20 c0.39,0,0.73-0.15,1-0.39C13.3,19.34,13.5,18.95,13.5,18.5z"/> + <path android:fillColor="@android:color/white" android:pathData="M18.89,11.62c0.15,0.15,0.34,0.22,0.53,0.22c0.19,0,0.38-0.07,0.53-0.22c0.29-0.29,0.29-0.77,0-1.06 C17.83,8.43,15,7.25,12,7.25s-5.83,1.17-7.95,3.3c-0.29,0.29-0.29,0.77,0,1.06c0.29,0.29,0.77,0.29,1.06,0 C6.95,9.77,9.4,8.75,12,8.75S17.05,9.77,18.89,11.62z"/> + <path android:fillAlpha="0.3" android:fillColor="@android:color/white" android:pathData="M22.08,8.43c0.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.06 C20.16,4.39,16.21,2.75,12,2.75S3.84,4.39,0.86,7.37c-0.29,0.29-0.29,0.77,0,1.06s0.77,0.29,1.06,0C4.62,5.74,8.19,4.25,12,4.25 S19.38,5.74,22.08,8.43z" android:strokeAlpha="0.3" android:strokeWidth="1"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_wifi_4.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_wifi_4.xml index 8213e1cfc4f5..3bb1a96297e4 100644 --- a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_wifi_4.xml +++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_wifi_4.xml @@ -1,42 +1,24 @@ + <!-- -/** - * 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. - */ + 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="M 11.99 16.5 C 12.8184271247 16.5 13.49 17.1715728753 13.49 18 C 13.49 18.8284271247 12.8184271247 19.5 11.99 19.5 C 11.1615728753 19.5 10.49 18.8284271247 10.49 18 C 10.49 17.1715728753 11.1615728753 16.5 11.99 16.5 Z" /> - <path - android:fillColor="#000000" - android:pathData="M18.41,11.66a0.52 0.52 ,0,0,0,0.71,0,0.51 0.51 ,0,0,0,0-0.71A10.08,10.08,0,0,0,4.87,11a0.5 0.5 ,0,0,0,0,0.71 0.51 0.51,0,0,0,0.71,0,9.07,9.07,0,0,1,12.83,0Z" /> - <path - android:fillColor="#000000" - android:pathData="M21.5,9a0.47 0.47 ,0,0,0,0.35-0.15 0.48 0.48,0,0,0,0-0.7,13.77,13.77,0,0,0-19.7,0,0.49 0.49 ,0,0,0,0.7 0.7 ,12.8,12.8,0,0,1,18.3,0A0.47 0.47 ,0,0,0,21.5,9Z" /> - <path - android:fillColor="#000000" - android:pathData="M12,12A6.05,6.05,0,0,0,7.7,13.78a0.51 0.51 ,0,0,0,0,0.71 0.5 0.5,0,0,0,0.71,0,5,5,0,0,1,6.77-0.32,3.77,3.77,0,0,1,0.84-0.63A6,6,0,0,0,12,12Z" /> - <path - android:fillColor="#000000" - android:pathData="M16.15,15.15a0.48 0.48 ,0,0,0,0,0.7L18.29,18l-2.14,2.15a0.48 0.48 ,0,0,0,0,0.7 0.48 0.48,0,0,0,0.7,0L19,18.71l2.15,2.14a0.48 0.48 ,0,0,0,0.7,0,0.48 0.48 ,0,0,0,0-0.7L19.71,18l2.14-2.15a0.49 0.49 ,0,1,0-0.7-0.7L19,17.29l-2.15-2.14A0.48 0.48 ,0,0,0,16.15,15.15Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M12,11.75c-1.8,0-3.5,0.7-4.78,1.96c-0.29,0.29-0.3,0.77-0.01,1.06c0.29,0.29,0.77,0.3,1.06,0.01 c1-0.99,2.32-1.53,3.73-1.53c0.89,0,1.73,0.24,2.5,0.65c0.46-0.37,0.99-0.65,1.58-0.79C14.9,12.24,13.49,11.75,12,11.75z"/> + <path android:fillColor="@android:color/white" android:pathData="M21.92,16.08c-0.29-0.29-0.77-0.29-1.06,0L19,17.94l-1.86-1.86c-0.29-0.29-0.77-0.29-1.06,0s-0.29,0.77,0,1.06L17.94,19 l-1.86,1.86c-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.22L19,20.06l1.86,1.86 c0.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.06L20.06,19l1.86-1.86 C22.22,16.84,22.22,16.37,21.92,16.08z"/> + <path android:fillColor="@android:color/white" android:pathData="M13.5,18.5c0-0.44-0.2-0.84-0.5-1.11C12.73,17.15,12.39,17,12,17c-0.83,0-1.5,0.67-1.5,1.5S11.17,20,12,20 c0.39,0,0.73-0.15,1-0.39C13.3,19.34,13.5,18.95,13.5,18.5z"/> + <path android:fillColor="@android:color/white" android:pathData="M18.89,11.62c0.15,0.15,0.34,0.22,0.53,0.22c0.19,0,0.38-0.07,0.53-0.22c0.29-0.29,0.29-0.77,0-1.06 C17.83,8.43,15,7.25,12,7.25s-5.83,1.17-7.95,3.3c-0.29,0.29-0.29,0.77,0,1.06c0.29,0.29,0.77,0.29,1.06,0 C6.95,9.77,9.4,8.75,12,8.75S17.05,9.77,18.89,11.62z"/> + <path android:fillColor="@android:color/white" android:pathData="M22.08,8.43c0.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.06C20.16,4.39,16.21,2.75,12,2.75 S3.84,4.39,0.86,7.37c-0.29,0.29-0.29,0.77,0,1.06s0.77,0.29,1.06,0C4.62,5.74,8.19,4.25,12,4.25S19.38,5.74,22.08,8.43z"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_wifi_disconnected.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_wifi_disconnected.xml index 86c03c6da6ce..906b3e71c69e 100644 --- a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_wifi_disconnected.xml +++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_wifi_disconnected.xml @@ -1,57 +1,25 @@ + <!-- -/** - * 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. - */ + 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:fillAlpha="0.3" - android:strokeAlpha="0.3" - android:strokeWidth="1" - android:pathData="M 11.99 16.5 C 12.8184271247 16.5 13.49 17.1715728753 13.49 18 C 13.49 18.8284271247 12.8184271247 19.5 11.99 19.5 C 11.1615728753 19.5 10.49 18.8284271247 10.49 18 C 10.49 17.1715728753 11.1615728753 16.5 11.99 16.5 Z" /> - <path - android:fillColor="#000000" - android:fillAlpha="0.3" - android:strokeAlpha="0.3" - android:strokeWidth="1" - android:pathData="M12,8A10,10,0,0,0,4.87,11a0.5 0.5 ,0,0,0,0,0.71 0.51 0.51,0,0,0,0.71,0,9.08,9.08,0,0,1,9.94-1.95A5.11,5.11,0,0,1,16.35,9,10,10,0,0,0,12,8Z" /> - <path - android:fillColor="#000000" - android:fillAlpha="0.3" - android:strokeAlpha="0.3" - android:strokeWidth="1" - android:pathData="M21.85,8.15a13.77,13.77,0,0,0-19.7,0,0.49 0.49 ,0,0,0,0.7 0.7 ,12.79,12.79,0,0,1,17.42-0.79A5.51,5.51,0,0,1,22,8.6 0.47 0.47,0,0,0,21.85,8.15Z" /> - <path - android:fillColor="#000000" - android:fillAlpha="0.3" - android:strokeAlpha="0.3" - android:strokeWidth="1" - android:pathData="M7.7,13.78a0.51 0.51 ,0,0,0,0,0.71 0.5 0.5,0,0,0,0.71,0A5.06,5.06,0,0,1,14,13.43a5.9,5.9,0,0,1,0.11-1A6.07,6.07,0,0,0,7.7,13.78Z" /> - <path - android:fillColor="#000000" - android:pathData="M17.1,11.27a3.42,3.42,0,0,0-0.89,1.64 0.5 0.5,0,0,0,0.37 0.6 0.5 0.5 ,0,0,0,0.6-0.37A2.56,2.56,0,0,1,17.81,12a2.4,2.4,0,0,1,3.38,0,2.18,2.18,0,0,1,0.64,1.76A1.85,1.85,0,0,1,21,15.12a3.13,3.13,0,0,1-0.36 0.22 A2.8,2.8,0,0,0,19,17.5a0.51 0.51 ,0,0,0,0.41 0.58 h0.08a0.5 0.5 ,0,0,0,0.5-0.41,1.81,1.81,0,0,1,1.14-1.46l0.42-0.26a2.86,2.86,0,0,0,1.27-2.12,3.21,3.21,0,0,0-0.92-2.56A3.43,3.43,0,0,0,17.1,11.27Z" /> - <path - android:fillColor="#000000" - android:pathData="M 19.5 19.5 C 19.9142135624 19.5 20.25 19.8357864376 20.25 20.25 C 20.25 20.6642135624 19.9142135624 21 19.5 21 C 19.0857864376 21 18.75 20.6642135624 18.75 20.25 C 18.75 19.8357864376 19.0857864376 19.5 19.5 19.5 Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillAlpha="0.3" android:fillColor="@android:color/white" android:pathData="M12,7.25c-3,0-5.83,1.17-7.95,3.3c-0.29,0.29-0.29,0.77,0,1.06c0.29,0.29,0.77,0.29,1.06,0 C6.95,9.77,9.4,8.75,12,8.75c1.17,0,2.31,0.22,3.38,0.61c0.46-0.4,0.98-0.73,1.55-0.96C15.41,7.66,13.74,7.25,12,7.25z" android:strokeAlpha="0.3" android:strokeWidth="1"/> + <path android:fillAlpha="0.3" android:fillColor="@android:color/white" android:pathData="M22.08,8.43c0.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.06 C20.16,4.39,16.21,2.75,12,2.75S3.84,4.39,0.86,7.37c-0.29,0.29-0.29,0.77,0,1.06s0.77,0.29,1.06,0C4.62,5.74,8.19,4.25,12,4.25 S19.38,5.74,22.08,8.43z" android:strokeAlpha="0.3" android:strokeWidth="1"/> + <path android:fillAlpha="0.3" android:fillColor="@android:color/white" android:pathData="M12,11.75c-1.8,0-3.5,0.7-4.78,1.96c-0.29,0.29-0.3,0.77-0.01,1.06c0.29,0.29,0.77,0.3,1.06,0.01 c1-0.99,2.32-1.53,3.73-1.53c0.52,0,1.02,0.1,1.5,0.24c0-0.53,0.08-1.03,0.22-1.51C13.16,11.84,12.59,11.75,12,11.75z" android:strokeAlpha="0.3" android:strokeWidth="1"/> + <path android:fillAlpha="0.3" android:fillColor="@android:color/white" android:pathData="M 12 17 C 12.8284271247 17 13.5 17.6715728753 13.5 18.5 C 13.5 19.3284271247 12.8284271247 20 12 20 C 11.1715728753 20 10.5 19.3284271247 10.5 18.5 C 10.5 17.6715728753 11.1715728753 17 12 17 Z" android:strokeAlpha="0.3" android:strokeWidth="1"/> + <path android:fillColor="@android:color/white" android:pathData="M16.42,11.09c-0.47,0.48-0.8,1.09-0.95,1.76c-0.09,0.4,0.16,0.81,0.56,0.9c0.4,0.1,0.81-0.16,0.9-0.56 c0.09-0.41,0.29-0.77,0.56-1.05c0.81-0.83,2.21-0.83,3.02,0c0.42,0.43,0.63,1,0.57,1.57c-0.05,0.5-0.31,0.92-0.72,1.2 c-0.11,0.08-0.23,0.14-0.35,0.21c-0.64,0.37-1.51,0.88-1.75,2.34c-0.07,0.41,0.21,0.79,0.62,0.86c0.04,0.01,0.08,0.01,0.12,0.01 c0.36,0,0.68-0.26,0.74-0.63c0.13-0.76,0.48-0.97,1.03-1.28c0.15-0.09,0.3-0.17,0.44-0.27c0.79-0.53,1.28-1.35,1.37-2.3 c0.1-1.01-0.26-2.02-0.99-2.77C20.21,9.68,17.8,9.68,16.42,11.09z"/> + <path android:fillColor="@android:color/white" android:pathData="M 19 20 C 19.5522847498 20 20 20.4477152502 20 21 C 20 21.5522847498 19.5522847498 22 19 22 C 18.4477152502 22 18 21.5522847498 18 21 C 18 20.4477152502 18.4477152502 20 19 20 Z"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_screenshot_delete.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_screenshot_delete.xml index 174f36ed9771..c66f9189f564 100644 --- a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_screenshot_delete.xml +++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_screenshot_delete.xml @@ -1,36 +1,22 @@ + <!-- -/** - * 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. - */ + 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="M9,20h6a3,3,0,0,0,3-3V6h0.5a0.5 0.5 ,0,0,0,0-1H15L14,4H10L9,5H5.5a0.5 0.5 ,0,0,0,0,1H6V17A3,3,0,0,0,9,20ZM17,6V17a2,2,0,0,1-2,2H9a2,2,0,0,1-2-2V6Z" /> - <path - android:fillColor="#000000" - android:pathData="M14,16a0.5 0.5 ,0,0,0,0.5-0.5v-7A0.5 0.5 ,0,0,0,14,8a0.5 0.5 ,0,0,0-0.5 0.5 v7A0.5 0.5 ,0,0,0,14,16Z" /> - <path - android:fillColor="#000000" - android:pathData="M10,16a0.5 0.5 ,0,0,0,0.5-0.5v-7a0.5 0.5 ,0,0,0-1,0v7A0.5 0.5 ,0,0,0,10,16Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M9,20h6c1.66,0,3-1.34,3-3V6h0.5c0.41,0,0.75-0.34,0.75-0.75S18.91,4.5,18.5,4.5H18h-3l-1-1h-4l-1,1H6H5.5 c-0.41,0-0.75,0.34-0.75,0.75S5.09,6,5.5,6H6v11C6,18.66,7.34,20,9,20z M16.5,6v11c0,0.83-0.67,1.5-1.5,1.5H9 c-0.83,0-1.5-0.67-1.5-1.5V6H16.5z"/> + <path android:fillColor="@android:color/white" android:pathData="M13.97,16c0.41,0,0.75-0.34,0.75-0.75v-6.5c0-0.41-0.34-0.75-0.75-0.75s-0.75,0.34-0.75,0.75v6.5 C13.22,15.66,13.55,16,13.97,16z"/> + <path android:fillColor="@android:color/white" android:pathData="M10,16c0.41,0,0.75-0.34,0.75-0.75v-6.5C10.75,8.34,10.41,8,10,8S9.25,8.34,9.25,8.75v6.5C9.25,15.66,9.59,16,10,16z"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_settings.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_settings.xml new file mode 100644 index 000000000000..eb4b99b7e7f2 --- /dev/null +++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_settings.xml @@ -0,0 +1,20 @@ + +<!-- + 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 android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M12,8.5c-1.93,0-3.5,1.57-3.5,3.5s1.57,3.5,3.5,3.5c1.93,0,3.5-1.57,3.5-3.5S13.93,8.5,12,8.5z M12,14c-1.1,0-2-0.9-2-2 s0.9-2,2-2c1.1,0,2,0.9,2,2S13.1,14,12,14z M21.29,13.9l-1.83-1.05c-0.3-0.17-0.49-0.49-0.48-0.84v-0.01 c0-0.35,0.18-0.67,0.48-0.84l1.83-1.05c0.48-0.28,0.64-0.89,0.37-1.37l-2-3.46c-0.19-0.32-0.52-0.5-0.87-0.5 c-0.17,0-0.34,0.04-0.5,0.13l-1.84,1.06c-0.14,0.08-0.29,0.12-0.45,0.12c-0.17,0-0.35-0.05-0.5-0.14c0,0-0.01,0-0.01-0.01 C15.2,5.77,15,5.47,15,5.12V3c0-0.55-0.45-1-1-1h-4C9.45,2,9,2.45,9,3v2.12c0,0.34-0.2,0.65-0.5,0.82c0,0-0.01,0-0.01,0.01 c-0.16,0.09-0.33,0.14-0.5,0.14c-0.15,0-0.31-0.04-0.45-0.12L5.71,4.9c-0.16-0.09-0.33-0.13-0.5-0.13c-0.35,0-0.68,0.18-0.87,0.5 l-2,3.46C2.06,9.21,2.23,9.82,2.71,10.1l1.83,1.05c0.3,0.17,0.49,0.49,0.48,0.84v0.01c0,0.35-0.18,0.67-0.48,0.84L2.71,13.9 c-0.48,0.28-0.64,0.89-0.37,1.37l2,3.46c0.19,0.32,0.52,0.5,0.87,0.5c0.17,0,0.34-0.04,0.5-0.13l1.84-1.06 c0.14-0.08,0.29-0.12,0.45-0.12c0.17,0,0.35,0.05,0.5,0.14c0,0,0.01,0,0.01,0.01C8.8,18.23,9,18.53,9,18.88V21c0,0.55,0.45,1,1,1h4 c0.55,0,1-0.45,1-1v-2.12c0-0.34,0.2-0.65,0.5-0.82c0,0,0.01,0,0.01-0.01c0.16-0.09,0.33-0.14,0.5-0.14c0.15,0,0.31,0.04,0.45,0.12 l1.84,1.06c0.16,0.09,0.33,0.13,0.5,0.13c0.35,0,0.68-0.18,0.87-0.5l2-3.46C21.94,14.79,21.77,14.18,21.29,13.9z M18.61,17.55 l-1.41-0.81c-0.36-0.21-0.78-0.32-1.2-0.32c-0.43,0-0.86,0.12-1.25,0.34c-0.77,0.44-1.25,1.25-1.25,2.12v1.62h-3v-1.62 c0-0.87-0.48-1.68-1.26-2.12c-0.38-0.22-0.81-0.33-1.25-0.33c-0.42,0-0.84,0.11-1.2,0.32l-1.41,0.81l-1.5-2.6l1.39-0.8 c0.76-0.44,1.24-1.26,1.23-2.15c0-0.88-0.47-1.7-1.23-2.14l-1.39-0.8l1.5-2.6L6.8,7.26c0.36,0.21,0.78,0.32,1.2,0.32 c0.43,0,0.86-0.12,1.25-0.34c0.77-0.44,1.25-1.25,1.25-2.12V3.5h3v1.62c0,0.87,0.48,1.68,1.26,2.12c0.38,0.22,0.81,0.33,1.25,0.33 c0.42,0,0.84-0.11,1.2-0.32l1.41-0.81l1.5,2.6l-1.39,0.8c-0.76,0.44-1.24,1.26-1.23,2.15c0,0.88,0.47,1.7,1.23,2.14l1.39,0.8 L18.61,17.55z"/> +</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 index 33d172cd2517..73d353a62393 100644 --- a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_settings_16dp.xml +++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_settings_16dp.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="#FFFFFF" + android:pathData="M12,8.5c-1.93,0-3.5,1.57-3.5,3.5s1.57,3.5,3.5,3.5c1.93,0,3.5-1.57,3.5-3.5S13.93,8.5,12,8.5z M12,14c-1.1,0-2-0.9-2-2 s0.9-2,2-2c1.1,0,2,0.9,2,2S13.1,14,12,14z" /> <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> + android:fillColor="#FFFFFF" + android:pathData="M19.47,11.15l1.83-1.05c0.48-0.28,0.64-0.89,0.37-1.37l-2-3.46c-0.19-0.32-0.52-0.5-0.87-0.5c-0.17,0-0.34,0.04-0.5,0.13 l-1.84,1.06c-0.14,0.08-0.29,0.12-0.45,0.12c-0.17,0-0.35-0.05-0.5-0.14c0,0-0.01,0-0.01-0.01C15.2,5.77,15,5.47,15,5.12V3 c0-0.55-0.45-1-1-1h-4C9.45,2,9,2.45,9,3v2.12c0,0.34-0.2,0.65-0.5,0.82c0,0-0.01,0-0.01,0.01c-0.16,0.09-0.33,0.14-0.5,0.14 c-0.15,0-0.31-0.04-0.45-0.12L5.71,4.9c-0.16-0.09-0.33-0.13-0.5-0.13c-0.35,0-0.68,0.18-0.87,0.5l-2,3.46 C2.06,9.21,2.23,9.82,2.71,10.1l1.83,1.05c0.3,0.17,0.49,0.49,0.48,0.84c0,0,0,0.01,0,0.01c0,0.35-0.18,0.67-0.48,0.84L2.71,13.9 c-0.48,0.28-0.64,0.89-0.37,1.37l2,3.46c0.19,0.32,0.52,0.5,0.87,0.5c0.17,0,0.34-0.04,0.5-0.13l1.84-1.06 c0.14-0.08,0.29-0.12,0.45-0.12c0.17,0,0.35,0.05,0.5,0.14c0,0,0.01,0,0.01,0.01C8.8,18.23,9,18.53,9,18.88V21c0,0.55,0.45,1,1,1h4 c0.55,0,1-0.45,1-1v-2.12c0-0.34,0.2-0.65,0.5-0.82c0,0,0.01,0,0.01-0.01c0.16-0.09,0.33-0.14,0.5-0.14c0.15,0,0.31,0.04,0.45,0.12 l1.84,1.06c0.16,0.09,0.33,0.13,0.5,0.13c0.35,0,0.68-0.18,0.87-0.5l2-3.46c0.28-0.48,0.11-1.09-0.37-1.37l-1.83-1.05 c-0.3-0.17-0.49-0.49-0.48-0.84c0,0,0-0.01,0-0.01C18.98,11.65,19.17,11.33,19.47,11.15z M18.72,14.15l1.39,0.8l-1.5,2.6 l-1.41-0.81c-0.36-0.21-0.78-0.32-1.2-0.32c-0.43,0-0.86,0.12-1.25,0.34c-0.77,0.44-1.25,1.25-1.25,2.12v1.62h-3v-1.62 c0-0.87-0.48-1.68-1.26-2.12c-0.38-0.22-0.81-0.33-1.25-0.33c-0.42,0-0.84,0.11-1.2,0.32l-1.41,0.81l-1.5-2.6l1.39-0.8 c0.76-0.44,1.24-1.26,1.23-2.15c0-0.88-0.47-1.7-1.23-2.14l-1.39-0.8l1.5-2.6L6.8,7.26c0.36,0.21,0.78,0.32,1.2,0.32 c0.43,0,0.86-0.12,1.25-0.34c0.77-0.44,1.25-1.25,1.25-2.12V3.5h3v1.62c0,0.87,0.48,1.68,1.26,2.12c0.38,0.22,0.81,0.33,1.25,0.33 c0.42,0,0.84-0.11,1.2-0.32l1.41-0.81l1.5,2.6l-1.39,0.8c-0.76,0.44-1.24,1.26-1.23,2.15C17.48,12.89,17.96,13.71,18.72,14.15z" /> +</vector>
\ No newline at end of file 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/IconPackCircularSystemUIOverlay/res/drawable/ic_signal_flashlight.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_signal_flashlight.xml deleted file mode 100644 index 15266910de6c..000000000000 --- a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_signal_flashlight.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="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: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/IconPackCircularSystemUIOverlay/res/drawable/ic_swap_vert.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_swap_vert.xml index 2f3ac2ed407e..528c718b7412 100644 --- a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_swap_vert.xml +++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_swap_vert.xml @@ -1,33 +1,21 @@ + <!-- -/** - * 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. - */ + 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="M18.85,16.65a0.48 0.48 ,0,0,0-0.7,0L16,18.79V10.5a0.5 0.5 ,0,0,0-1,0v8.29l-2.15-2.14a0.49 0.49 ,0,0,0-0.7 0.7 l3.35,3.36,3.35-3.36A0.48 0.48 ,0,0,0,18.85,16.65Z" /> - <path - android:fillColor="#000000" - android:pathData="M11.85,6.64l-3-3h0L8.5,3.29l-0.35 0.35 h0l-3,3a0.5 0.5 ,0,0,0,0,0.71 0.5 0.5,0,0,0,0.7,0L8,5.2v8.3a0.5 0.5 ,0,0,0,1,0V5.2l2.15,2.15a0.48 0.48 ,0,0,0,0.7,0A0.5 0.5 ,0,0,0,11.85,6.64Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M19.78,16.72c-0.29-0.29-0.77-0.29-1.06,0l-2.47,2.47v-8.44c0-0.41-0.34-0.75-0.75-0.75s-0.75,0.34-0.75,0.75v8.44 l-2.47-2.47c-0.29-0.29-0.77-0.29-1.06,0s-0.29,0.77,0,1.06l4.28,4.28l4.28-4.28C20.07,17.49,20.07,17.01,19.78,16.72z"/> + <path android:fillColor="@android:color/white" android:pathData="M7.75,4.81v8.44C7.75,13.66,8.09,14,8.5,14s0.75-0.34,0.75-0.75V4.81l2.47,2.47c0.15,0.15,0.34,0.22,0.53,0.22 s0.38-0.07,0.53-0.22c0.29-0.29,0.29-0.77,0-1.06L8.5,1.94L4.22,6.22c-0.29,0.29-0.29,0.77,0,1.06s0.77,0.29,1.06,0L7.75,4.81z"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_tune_black_16dp.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_tune_black_16dp.xml new file mode 100644 index 000000000000..858126ebcbb3 --- /dev/null +++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_tune_black_16dp.xml @@ -0,0 +1,25 @@ + +<!-- + 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 android:height="16dp" android:viewportHeight="24" android:viewportWidth="24" android:width="16dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M20.25,4.75h-2.4C17.55,4.02,16.84,3.5,16,3.5c-1.1,0-2,0.9-2,2c0,1.1,0.9,2,2,2c0.84,0,1.55-0.52,1.85-1.25h2.4 C20.66,6.25,21,5.91,21,5.5S20.66,4.75,20.25,4.75z"/> + <path android:fillColor="@android:color/white" android:pathData="M11.98,4.75H3.75C3.34,4.75,3,5.09,3,5.5s0.34,0.75,0.75,0.75h8.23c0.01,0,0.01,0,0.02,0V4.75 C11.99,4.75,11.99,4.75,11.98,4.75z"/> + <path android:fillColor="@android:color/white" android:pathData="M20.25,17.75h-5.4c-0.3-0.73-1.01-1.25-1.85-1.25c-1.1,0-2,0.9-2,2c0,1.1,0.9,2,2,2c0.84,0,1.55-0.52,1.85-1.25h5.4 c0.41,0,0.75-0.34,0.75-0.75S20.66,17.75,20.25,17.75z"/> + <path android:fillColor="@android:color/white" android:pathData="M8.98,17.75H3.75C3.34,17.75,3,18.09,3,18.5s0.34,0.75,0.75,0.75h5.23c0.01,0,0.01,0,0.02,0v-1.49 C8.99,17.75,8.99,17.75,8.98,17.75z"/> + <path android:fillColor="@android:color/white" android:pathData="M7,10c-0.84,0-1.55,0.52-1.85,1.25h-1.4C3.34,11.25,3,11.59,3,12s0.34,0.75,0.75,0.75h1.4C5.45,13.48,6.16,14,7,14 c1.1,0,2-0.9,2-2C9,10.9,8.1,10,7,10z"/> + <path android:fillColor="@android:color/white" android:pathData="M20.25,11.25h-9.23c-0.01,0-0.01,0-0.02,0v1.49c0.01,0,0.01,0,0.02,0h9.23c0.41,0,0.75-0.34,0.75-0.75 S20.66,11.25,20.25,11.25z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_volume_alarm.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_volume_alarm.xml index c67e8970454e..0779913379d4 100644 --- a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_volume_alarm.xml +++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_volume_alarm.xml @@ -21,19 +21,15 @@ android:viewportHeight="24"> <path - android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" /> + android:fillColor="#FFFFFF" + android:pathData="M12,4c-4.97,0-9,4.03-9,9c0,4.97,4.03,9,9,9s9-4.03,9-9C21,8.03,16.97,4,12,4z M12,20.5c-4.14,0-7.5-3.36-7.5-7.5 S7.86,5.5,12,5.5s7.5,3.36,7.5,7.5S16.14,20.5,12,20.5z" /> <path - android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" /> + android:fillColor="#FFFFFF" + android:pathData="M17.1,4.22c0.13-0.15,0.31-0.25,0.51-0.26c0.2-0.02,0.39,0.04,0.55,0.17l1.53,1.29c0.15,0.13,0.25,0.31,0.26,0.51 c0.02,0.2-0.04,0.39-0.17,0.54c-0.27,0.32-0.23,0.79,0.09,1.06c0.14,0.12,0.31,0.18,0.48,0.18c0.21,0,0.43-0.09,0.57-0.27 c0.8-0.95,0.68-2.37-0.27-3.17l-1.53-1.29c-0.46-0.39-1.04-0.57-1.64-0.52c-0.6,0.05-1.14,0.33-1.53,0.79 c-0.27,0.32-0.23,0.79,0.09,1.06C16.37,4.58,16.84,4.54,17.1,4.22z" /> <path - android:fillColor="#000000" - android:pathData="M12,4a9,9,0,1,0,9,9A9,9,0,0,0,12,4Zm0,17a8,8,0,1,1,8-8A8,8,0,0,1,12,21Z" /> + android:fillColor="#FFFFFF" + android:pathData="M3.65,7.71c0.17,0,0.34-0.06,0.48-0.18c0.32-0.27,0.36-0.74,0.09-1.06C4.09,6.32,4.03,6.13,4.05,5.93 c0.02-0.2,0.11-0.38,0.26-0.51l1.53-1.29C5.99,4,6.19,3.94,6.39,3.96c0.2,0.02,0.38,0.11,0.51,0.26c0.27,0.32,0.74,0.36,1.06,0.09 c0.32-0.27,0.36-0.74,0.09-1.06C7.66,2.8,7.11,2.52,6.52,2.46C5.92,2.41,5.34,2.6,4.88,2.98L3.34,4.28 C2.39,5.07,2.27,6.5,3.07,7.44C3.22,7.62,3.43,7.71,3.65,7.71z" /> <path - android:fillColor="#000000" - android:pathData="M17.51,2.71a2,2,0,0,0-1.36 0.71 0.5 0.5 ,0,0,0,0.76 0.64 ,1,1,0,0,1,1.41-0.12l1.53,1.29a1,1,0,0,1,0.35 0.68 ,1,1,0,0,1-0.23 0.73 0.49 0.49 ,0,0,0,0.06 0.7 0.51 0.51 ,0,0,0,0.32 0.12 0.5 0.5 ,0,0,0,0.39-0.18,2,2,0,0,0,0.46-1.46,2,2,0,0,0-0.7-1.35L19,3.18A1.92,1.92,0,0,0,17.51,2.71Z" /> - <path - android:fillColor="#000000" - android:pathData="M3.65,7.46A0.51 0.51 ,0,0,0,4,7.34 0.49 0.49,0,0,0,4,6.64a1,1,0,0,1-0.23-0.73,1,1,0,0,1,0.35-0.68L5.68,3.94a1,1,0,0,1,0.73-0.23,1,1,0,0,1,0.68 0.35 0.5 0.5 ,0,1,0,0.76-0.64,2,2,0,0,0-1.36-0.71A1.92,1.92,0,0,0,5,3.18L3.5,4.47a2,2,0,0,0-0.7,1.35,2,2,0,0,0,0.46,1.46A0.5 0.5 ,0,0,0,3.65,7.46Z" /> - <path - android:fillColor="#000000" - android:pathData="M12.5,12.79V8a0.5 0.5 ,0,0,0-1,0v5.21l3.13,3.12a0.47 0.47 ,0,0,0,0.35 0.15 0.5 0.5 ,0,0,0,0.35-0.85Z" /> + android:fillColor="#FFFFFF" + android:pathData="M12.75,12.69V7.75C12.75,7.34,12.41,7,12,7s-0.75,0.34-0.75,0.75v5.56l2.7,2.7c0.15,0.15,0.34,0.22,0.53,0.22 s0.38-0.07,0.53-0.22c0.29-0.29,0.29-0.77,0-1.06L12.75,12.69z" /> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_volume_alarm_mute.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_volume_alarm_mute.xml new file mode 100644 index 000000000000..383f6d8746fa --- /dev/null +++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_volume_alarm_mute.xml @@ -0,0 +1,23 @@ + +<!-- + 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 android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M8.55,6.35C9.58,5.81,10.76,5.5,12,5.5c4.14,0,7.5,3.36,7.5,7.5c0,1.24-0.31,2.42-0.85,3.45l1.1,1.1 C20.54,16.22,21,14.66,21,13c0-4.97-4.03-9-9-9c-1.66,0-3.22,0.46-4.55,1.25L8.55,6.35z"/> + <path android:fillColor="@android:color/white" android:pathData="M17.1,4.22c0.13-0.15,0.31-0.25,0.51-0.26c0.2-0.02,0.39,0.04,0.55,0.17l1.53,1.29c0.15,0.13,0.25,0.31,0.26,0.51 c0.02,0.2-0.04,0.39-0.17,0.54c-0.27,0.32-0.23,0.79,0.09,1.06c0.14,0.12,0.31,0.18,0.48,0.18c0.21,0,0.43-0.09,0.57-0.27 c0.8-0.95,0.68-2.37-0.27-3.17l-1.53-1.29c-0.46-0.39-1.04-0.57-1.64-0.52c-0.6,0.05-1.14,0.33-1.53,0.79 c-0.27,0.32-0.23,0.79,0.09,1.06C16.37,4.58,16.84,4.54,17.1,4.22z"/> + <path android:fillColor="@android:color/white" android:pathData="M6.39,3.96c0.2,0.02,0.38,0.11,0.51,0.26c0.27,0.32,0.74,0.36,1.06,0.09c0.32-0.27,0.36-0.74,0.09-1.06 C7.66,2.8,7.11,2.52,6.52,2.46c-0.52-0.04-1.03,0.1-1.46,0.39l1.12,1.12C6.25,3.97,6.32,3.95,6.39,3.96z"/> + <path android:fillColor="@android:color/white" android:pathData="M3.03,2.97c-0.29-0.29-0.77-0.29-1.06,0c0,0,0,0,0,0c-0.29,0.29-0.29,0.77,0,1.06L2.84,4.9C2.39,5.69,2.45,6.71,3.07,7.44 c0.15,0.18,0.36,0.27,0.57,0.27c0.17,0,0.34-0.06,0.48-0.18c0.32-0.27,0.36-0.74,0.09-1.06c-0.09-0.1-0.13-0.22-0.15-0.35 l1.06,1.06C3.8,8.76,3,10.78,3,13c0,4.97,4.03,9,9,9c2.22,0,4.24-0.8,5.81-2.13l2.16,2.16c0.15,0.15,0.34,0.22,0.53,0.22 s0.38-0.07,0.53-0.22c0,0,0,0,0,0c0.29-0.29,0.29-0.77,0-1.06L3.03,2.97z M12,20.5c-4.14,0-7.5-3.36-7.5-7.5 c0-1.8,0.64-3.45,1.7-4.74L16.74,18.8C15.45,19.86,13.8,20.5,12,20.5z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_volume_ringer_vibrate.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_volume_ringer_vibrate.xml new file mode 100644 index 000000000000..5dcccdff019f --- /dev/null +++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_volume_ringer_vibrate.xml @@ -0,0 +1,24 @@ + +<!-- + 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 android:height="19dp" android:viewportHeight="24" android:viewportWidth="24" android:width="19dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M9,4C7.9,4,7,4.9,7,6v12c0,1.1,0.9,2,2,2h6c1.1,0,2-0.9,2-2V6c0-1.1-0.9-2-2-2H9z M15.5,6v12c0,0.28-0.22,0.5-0.5,0.5H9 c-0.28,0-0.5-0.22-0.5-0.5V6c0-0.28,0.22-0.5,0.5-0.5h6C15.28,5.5,15.5,5.72,15.5,6z"/> + <path android:fillColor="@android:color/white" android:pathData="M18.75,17c0.41,0,0.75-0.34,0.75-0.75v-8.5C19.5,7.34,19.16,7,18.75,7S18,7.34,18,7.75v8.5C18,16.66,18.34,17,18.75,17z"/> + <path android:fillColor="@android:color/white" android:pathData="M21.75,9C21.34,9,21,9.34,21,9.75v4.5c0,0.41,0.34,0.75,0.75,0.75s0.75-0.34,0.75-0.75v-4.5C22.5,9.34,22.16,9,21.75,9z"/> + <path android:fillColor="@android:color/white" android:pathData="M3,14.25v-4.5C3,9.34,2.66,9,2.25,9S1.5,9.34,1.5,9.75v4.5C1.5,14.66,1.84,15,2.25,15S3,14.66,3,14.25z"/> + <path android:fillColor="@android:color/white" android:pathData="M4.5,16.25C4.5,16.66,4.84,17,5.25,17S6,16.66,6,16.25v-8.5C6,7.34,5.66,7,5.25,7S4.5,7.34,4.5,7.75V16.25z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/stat_sys_camera.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/stat_sys_camera.xml new file mode 100644 index 000000000000..66b4a35b87b2 --- /dev/null +++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/stat_sys_camera.xml @@ -0,0 +1,21 @@ + +<!-- + 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 android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M22,8c0-1.66-1.34-3-3-3h-2l-2-2H9L7,5H5C3.34,5,2,6.34,2,8v13h20V8z M20.5,19.5h-17V8c0-0.83,0.67-1.5,1.5-1.5h14 c0.83,0,1.5,0.67,1.5,1.5V19.5z"/> + <path android:fillColor="@android:color/white" android:pathData="M12,8.5c-2.49,0-4.5,2.01-4.5,4.5s2.01,4.5,4.5,4.5s4.5-2.01,4.5-4.5S14.49,8.5,12,8.5z M12,16c-1.65,0-3-1.35-3-3 c0-1.65,1.35-3,3-3c1.65,0,3,1.35,3,3C15,14.65,13.65,16,12,16z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/stat_sys_mic_none.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/stat_sys_mic_none.xml new file mode 100644 index 000000000000..15c2be7b0929 --- /dev/null +++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/stat_sys_mic_none.xml @@ -0,0 +1,21 @@ + +<!-- + 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 android:height="18dp" android:viewportHeight="24" android:viewportWidth="24" android:width="18dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M11.25,17.96v3.29c0,0.41,0.34,0.75,0.75,0.75s0.75-0.34,0.75-0.75v-3.29c3.51-0.38,6.25-3.39,6.25-7.04 c0-0.41-0.34-0.75-0.75-0.75s-0.75,0.34-0.75,0.75c0,3.08-2.47,5.58-5.5,5.58S6.5,14,6.5,10.92c0-0.41-0.34-0.75-0.75-0.75 S5,10.5,5,10.92C5,14.57,7.74,17.58,11.25,17.96z"/> + <path android:fillColor="@android:color/white" android:pathData="M9,5v6c0,1.66,1.34,3,3,3s3-1.34,3-3V5c0-1.66-1.34-3-3-3S9,3.34,9,5z M13.5,5v6c0,0.83-0.67,1.5-1.5,1.5 s-1.5-0.67-1.5-1.5V5c0-0.83,0.67-1.5,1.5-1.5S13.5,4.17,13.5,5z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/stat_sys_vpn_ic.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/stat_sys_vpn_ic.xml new file mode 100644 index 000000000000..752c33dabedf --- /dev/null +++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/stat_sys_vpn_ic.xml @@ -0,0 +1,21 @@ + +<!-- + 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 android:height="17dp" android:viewportHeight="24" android:viewportWidth="24" android:width="17dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M 7.5 9.5 C 8.60456949966 9.5 9.5 10.3954305003 9.5 11.5 C 9.5 12.6045694997 8.60456949966 13.5 7.5 13.5 C 6.39543050034 13.5 5.5 12.6045694997 5.5 11.5 C 5.5 10.3954305003 6.39543050034 9.5 7.5 9.5 Z"/> + <path android:fillColor="@android:color/white" android:pathData="M21,9h-8.63C11.46,7.22,9.63,6,7.5,6C7.16,6,6.81,6.03,6.46,6.1C4.32,6.49,2.57,8.18,2.13,10.3C1.38,13.86,4.07,17,7.5,17 c2.13,0,3.96-1.22,4.87-3H14v3h6v-3h1c0.55,0,1-0.45,1-1v-3C22,9.45,21.55,9,21,9z M20.5,12.5h-2v3h-3v-3h-4.14 c-0.45,1.72-2,3-3.86,3c-2.21,0-4-1.79-4-4s1.79-4,4-4c1.86,0,3.41,1.28,3.86,3h9.14V12.5z"/> +</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..3e7c1d7a67e2 --- /dev/null +++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_bluetooth_share_icon.xml @@ -0,0 +1,20 @@ + +<!-- + 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 android:height="24dp" android:tint="@*android:color/accent_device_default" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <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_bt_headphones_a2dp.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_bt_headphones_a2dp.xml index 428d453955ff..0a5abfee81e2 100644 --- a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_bt_headphones_a2dp.xml +++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_bt_headphones_a2dp.xml @@ -1,28 +1,20 @@ + <!-- -/** - * 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. - */ + 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="M21,18V11a9,9,0,0,0-9.6-9A9.21,9.21,0,0,0,3,11.31V17.2C3,19.66,4.34,21,6,21H8a1,1,0,0,0,1-1V14a1,1,0,0,0-1-1H5V11.29A7.19,7.19,0,0,1,11.79,4,7,7,0,0,1,19,11v2H16a1,1,0,0,0-1,1v6a1,1,0,0,0,1,1h2A3,3,0,0,0,21,18Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M21,18v-7c0-5.17-4.36-9.32-9.6-8.98C6.62,2.33,3,6.52,3,11.31v5.89C3,19.66,4.34,21,6,21h2c0.55,0,1-0.45,1-1v-6 c0-0.55-0.45-1-1-1H5v-1.71C5,7.45,7.96,4.11,11.79,4C15.76,3.89,19,7.06,19,11v2h-3c-0.55,0-1,0.45-1,1v6c0,0.55,0.45,1,1,1h2 C19.66,21,21,19.66,21,18z"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_expand_more.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_expand_more.xml index 3ef7dd177d43..e7f09a13e72f 100644 --- a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_expand_more.xml +++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_expand_more.xml @@ -1,28 +1,20 @@ + <!-- -/** - * 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. - */ + 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="M19.29,8.29a1,1,0,0,0-1.41,0L12,14.17,6.12,8.29A1,1,0,1,0,4.71,9.71l6.58,6.58a1,1,0,0,0,1.42,0l6.58-6.58A1,1,0,0,0,19.29,8.29Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M19.29,8.29c-0.39-0.39-1.02-0.39-1.41,0L12,14.17L6.12,8.29c-0.39-0.39-1.02-0.39-1.41,0c-0.39,0.39-0.39,1.02,0,1.41 l6.59,6.59c0.39,0.39,1.02,0.39,1.41,0l6.59-6.59C19.68,9.32,19.68,8.68,19.29,8.29z"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_faster_emergency.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_faster_emergency.xml new file mode 100644 index 000000000000..eecf69809a1f --- /dev/null +++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_faster_emergency.xml @@ -0,0 +1,21 @@ + +<!-- + 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 android:height="24dp" android:tint="?android:attr/colorError" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:pathData="M0 0h24v24H0z"/> + <path android:fillColor="@android:color/white" android:pathData="M19 3H5c-1.1 0-1.99 0.9 -1.99 2L3 19c0 1.1 0.9 2 2 2h14c1.1 0 2-0.9 2-2V5c0-1.1-0.9-2-2-2zm-1 11h-4v4h-4v-4H6v-4h4V6h4v4h4v4z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_info_outline_24.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_info_outline_24.xml index e39a2a0eb286..9a178775a81b 100644 --- a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_info_outline_24.xml +++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_info_outline_24.xml @@ -1,28 +1,20 @@ + <!-- -/** - * 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. - */ + 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,12A10,10,0,1,0,12,2,10,10,0,0,0,2,12Zm11,5.42a1,1,0,0,1-2,0V10.68a1,1,0,0,1,2,0ZM12,5.58a1.35,1.35,0,1,1-1.35,1.35A1.34,1.34,0,0,1,12,5.58Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M12,2C6.48,2,2,6.48,2,12c0,5.52,4.48,10,10,10s10-4.48,10-10C22,6.48,17.52,2,12,2z M13,17c0,0.55-0.45,1-1,1s-1-0.45-1-1 v-5c0-0.55,0.45-1,1-1s1,0.45,1,1V17z M12,9.25c-0.69,0-1.25-0.56-1.25-1.25S11.31,6.75,12,6.75S13.25,7.31,13.25,8 S12.69,9.25,12,9.25z"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_invert_colors.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_invert_colors.xml deleted file mode 100644 index 0564c737c703..000000000000 --- a/packages/overlays/IconPackFilledAndroidOverlay/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="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" /> -</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_lock.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_lock.xml new file mode 100644 index 000000000000..13a5c0dfcacb --- /dev/null +++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_lock.xml @@ -0,0 +1,20 @@ + +<!-- + 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 android:height="32dp" android:tint="?android:attr/textColor" android:viewportHeight="24" android:viewportWidth="24" android:width="32dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M4,10v10c0,1.1,0.9,2,2,2h12c1.1,0,2-0.9,2-2V10c0-1.1-0.9-2-2-2h-2c0-1.1,0-2.36,0-3c0-2.21-1.79-4-4-4C9.79,1,8,2.79,8,5 c0,0.56,0,1.86,0,3H6C4.9,8,4,8.9,4,10z M12,17c-1.1,0-2-0.9-2-2c0-1.1,0.9-2,2-2s2,0.9,2,2C14,16.1,13.1,17,12,17z M10,5 c0-1.1,0.9-2,2-2s2,0.9,2,2v3h-4V5z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_lock_bugreport.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_lock_bugreport.xml new file mode 100644 index 000000000000..de37f9fd8d0d --- /dev/null +++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_lock_bugreport.xml @@ -0,0 +1,20 @@ + +<!-- + 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 android:height="24dp" android:tint="?android:attr/colorControlNormal" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M3,17c0,0.55,0.45,1,1,1h2.81c1.04,1.79,2.97,3,5.19,3s4.15-1.21,5.19-3H20c0.55,0,1-0.45,1-1s-0.45-1-1-1h-2.09 c0.05-0.33,0.09-0.66,0.09-1v-1h2c0.55,0,1-0.45,1-1s-0.45-1-1-1h-2v-1c0-0.34-0.04-0.67-0.09-1H20c0.55,0,1-0.45,1-1s-0.45-1-1-1 h-2.81c-0.45-0.78-1.07-1.45-1.82-1.96l0.93-0.93c0.39-0.39,0.39-1.02,0-1.41s-1.02-0.39-1.41,0l-1.47,1.47 C12.96,5.06,12.49,5,12,5s-0.96,0.06-1.41,0.17L9.12,3.7c-0.39-0.39-1.02-0.39-1.41,0c-0.39,0.39-0.39,1.02,0,1.41l0.92,0.92 C7.88,6.55,7.26,7.22,6.81,8H4C3.45,8,3,8.45,3,9s0.45,1,1,1h2.09C6.04,10.33,6,10.66,6,11v1H4c-0.55,0-1,0.45-1,1s0.45,1,1,1h2v1 c0,0.34,0.04,0.67,0.09,1H4C3.45,16,3,16.45,3,17z M10,10h4v2h-4V10z M10,14h4v2h-4V14z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_lock_open.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_lock_open.xml new file mode 100644 index 000000000000..e1b5bad8de0f --- /dev/null +++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_lock_open.xml @@ -0,0 +1,20 @@ + +<!-- + 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 android:height="32dp" android:tint="?android:attr/textColor" android:viewportHeight="24" android:viewportWidth="24" android:width="32dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M18,1c-2.21,0-4,1.79-4,4v3H6c-1.1,0-2,0.9-2,2v10c0,1.1,0.9,2,2,2h12c1.1,0,2-0.9,2-2V10c0-1.1-0.9-2-2-2h-2V5 c0-1.1,0.9-2,2-2s2,0.9,2,2c0,0.55,0.45,1,1,1s1-0.45,1-1C22,2.79,20.21,1,18,1z M12,17c-1.1,0-2-0.9-2-2c0-1.1,0.9-2,2-2 s2,0.9,2,2C14,16.1,13.1,17,12,17z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_lock_power_off.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_lock_power_off.xml new file mode 100644 index 000000000000..ad46d1eac5f4 --- /dev/null +++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_lock_power_off.xml @@ -0,0 +1,21 @@ + +<!-- + 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 android:height="24dp" android:tint="?android:attr/colorControlNormal" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M12,13c0.6,0,1-0.4,1-1V4c0-0.6-0.4-1-1-1s-1,0.4-1,1v8C11,12.6,11.4,13,12,13z"/> + <path android:fillColor="@android:color/white" android:pathData="M18.6,5.9c-0.4-0.4-1.1-0.4-1.5,0c-0.4,0.4-0.4,1,0,1.4c1.3,1.4,2.1,3.4,1.8,5.6c-0.4,3.2-3,5.7-6.2,6.1 C8.6,19.4,5,16.1,5,12c0-1.8,0.7-3.5,1.9-4.8c0.4-0.4,0.4-1,0-1.4c-0.4-0.4-1-0.4-1.4,0C4,7.4,3.1,9.5,3,11.7 c-0.1,4.9,3.8,9.1,8.7,9.3c5.1,0.2,9.3-3.9,9.3-9C21,9.6,20.1,7.5,18.6,5.9z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_lockscreen_ime.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_lockscreen_ime.xml index 8b9f5627a98b..28ad305f1efe 100644 --- a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_lockscreen_ime.xml +++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_lockscreen_ime.xml @@ -1,55 +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. - */ + 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 android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M21,4H3C1.9,4,1,4.9,1,6v13c0,1.1,0.9,2,2,2h18c1.1,0,2-0.9,2-2V6C23,4.9,22.1,4,21,4z M21,19H3V6h18V19z"/> + <path android:fillColor="@android:color/white" android:pathData="M9.5,10h1c0.28,0,0.5-0.22,0.5-0.5v-1C11,8.22,10.78,8,10.5,8h-1C9.22,8,9,8.22,9,8.5v1C9,9.78,9.22,10,9.5,10z"/> + <path android:fillColor="@android:color/white" android:pathData="M5.5,10h1C6.78,10,7,9.78,7,9.5v-1C7,8.22,6.78,8,6.5,8h-1C5.22,8,5,8.22,5,8.5v1C5,9.78,5.22,10,5.5,10z"/> + <path android:fillColor="@android:color/white" android:pathData="M13.5,10h1c0.28,0,0.5-0.22,0.5-0.5v-1C15,8.22,14.78,8,14.5,8h-1C13.22,8,13,8.22,13,8.5v1C13,9.78,13.22,10,13.5,10z"/> + <path android:fillColor="@android:color/white" android:pathData="M9.5,14h1c0.28,0,0.5-0.22,0.5-0.5v-1c0-0.28-0.22-0.5-0.5-0.5h-1C9.22,12,9,12.22,9,12.5v1C9,13.78,9.22,14,9.5,14z"/> + <path android:fillColor="@android:color/white" android:pathData="M5.5,14h1C6.78,14,7,13.78,7,13.5v-1C7,12.22,6.78,12,6.5,12h-1C5.22,12,5,12.22,5,12.5v1C5,13.78,5.22,14,5.5,14z"/> + <path android:fillColor="@android:color/white" android:pathData="M13.5,14h1c0.28,0,0.5-0.22,0.5-0.5v-1c0-0.28-0.22-0.5-0.5-0.5h-1c-0.28,0-0.5,0.22-0.5,0.5v1C13,13.78,13.22,14,13.5,14 z"/> + <path android:fillColor="@android:color/white" android:pathData="M17.5,10h1c0.28,0,0.5-0.22,0.5-0.5v-1C19,8.22,18.78,8,18.5,8h-1C17.22,8,17,8.22,17,8.5v1C17,9.78,17.22,10,17.5,10z"/> + <path android:fillColor="@android:color/white" android:pathData="M17.5,14h1c0.28,0,0.5-0.22,0.5-0.5v-1c0-0.28-0.22-0.5-0.5-0.5h-1c-0.28,0-0.5,0.22-0.5,0.5v1C17,13.78,17.22,14,17.5,14 z"/> + <path android:fillColor="@android:color/white" android:pathData="M8.5,17h7c0.28,0,0.5-0.22,0.5-0.5S15.78,16,15.5,16h-7C8.22,16,8,16.22,8,16.5S8.22,17,8.5,17z"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_mode_edit.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_mode_edit.xml index 217845dd0249..31d2de7b0513 100644 --- a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_mode_edit.xml +++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_mode_edit.xml @@ -1,31 +1,21 @@ + <!-- -/** - * 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. - */ + 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="M20.71,7a1,1,0,0,0,0-1.41h0L18.37,3.29a1,1,0,0,0-1.41,0h0L15.13,5.12l3.75,3.75Z" /> - <path - android:fillColor="#000000" - android:pathData="M3,18.08V20.5a0.5 0.5 ,0,0,0,0.5 0.5 H5.92a2,2,0,0,0,1.41-0.59L17.81,9.94,14.06,6.19,3.59,16.66A2,2,0,0,0,3,18.08Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M3.29,16.96C3.11,17.14,3,17.4,3,17.66v2.84C3,20.78,3.22,21,3.5,21h2.84c0.27,0,0.52-0.11,0.71-0.29L17.81,9.94 l-3.75-3.75L3.29,16.96z"/> + <path android:fillColor="@android:color/white" android:pathData="M20.71,5.63C20.71,5.63,20.71,5.63,20.71,5.63l-2.34-2.34c-0.39-0.39-1.02-0.39-1.41,0c0,0,0,0,0,0l-1.83,1.83l3.75,3.75 l1.83-1.83C21.1,6.65,21.1,6.02,20.71,5.63z"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_phone.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_phone.xml index 2eaa368f147e..6a3d3b8f10c6 100644 --- a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_phone.xml +++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_phone.xml @@ -1,28 +1,20 @@ + <!-- -/** - * 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. - */ + 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="M9.78,7.06,9.13,3.8a1,1,0,0,0-1-0.8H4A1,1,0,0,0,3,4a17.92,17.92,0,0,0,2.43,8,18.08,18.08,0,0,0,6.5,6.5,17.92,17.92,0,0,0,8,2.43,1,1,0,0,0,1-1V15.82a1,1,0,0,0-0.8-1l-3.26-0.65a1,1,0,0,0-0.9 0.27 l-2.62,2.62a16.14,16.14,0,0,1-6.5-6.5L9.51,8A1,1,0,0,0,9.78,7.06Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M9.78,7.06L9.13,3.8C9.04,3.34,8.63,3,8.15,3H4C3.44,3,2.97,3.47,3,4.03c0.17,2.91,1.04,5.63,2.43,8.01 c1.57,2.69,3.81,4.93,6.5,6.5c2.38,1.39,5.1,2.26,8.01,2.43c0.56,0.03,1.03-0.44,1.03-1v-4.15c0-0.48-0.34-0.89-0.8-0.98 l-3.26-0.65c-0.33-0.07-0.67,0.04-0.9,0.27l-2.62,2.62c-2.75-1.49-5.01-3.75-6.5-6.5l2.62-2.62C9.75,7.72,9.85,7.38,9.78,7.06z"/> </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..92ea82bc3f93 --- /dev/null +++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_qs_airplane.xml @@ -0,0 +1,20 @@ + +<!-- + 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 android:height="18dp" android:viewportHeight="24" android:viewportWidth="24" android:width="18dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <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/IconPackFilledAndroidOverlay/res/drawable/ic_qs_auto_rotate.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_qs_auto_rotate.xml new file mode 100644 index 000000000000..f5d52d192548 --- /dev/null +++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_qs_auto_rotate.xml @@ -0,0 +1,21 @@ + +<!-- + 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 android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path 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="@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..2749ec699d6c --- /dev/null +++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_qs_bluetooth.xml @@ -0,0 +1,20 @@ + +<!-- + 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 android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <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_dnd.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_qs_dnd.xml new file mode 100644 index 000000000000..88f2bab2d4e1 --- /dev/null +++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_qs_dnd.xml @@ -0,0 +1,20 @@ + +<!-- + 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 android:height="17dp" android:viewportHeight="24" android:viewportWidth="24" android:width="17dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path 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/IconPackFilledAndroidOverlay/res/drawable/ic_qs_flashlight.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_qs_flashlight.xml new file mode 100644 index 000000000000..fa701ded6352 --- /dev/null +++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_qs_flashlight.xml @@ -0,0 +1,21 @@ + +<!-- + 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 android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path 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="@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_qs_night_display_on.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_qs_night_display_on.xml index f12beeca93ea..d4f34840bc06 100644 --- a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_qs_night_display_on.xml +++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_qs_night_display_on.xml @@ -1,28 +1,20 @@ + <!-- -/** - * 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. - */ + 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="M17.32,4.13a1,1,0,0,0-0.19-1.9A10,10,0,1,0,15,22a9.91,9.91,0,0,0,2.12-0.23,1,1,0,0,0,0.2-1.9,8.48,8.48,0,0,1,0-15.74Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M21.82,16.31c-0.17-0.25-0.47-0.38-0.76-0.32c-0.71,0.13-1.37,0.19-2.03,0.19c-6.19,0-11.22-5.05-11.22-11.26 C7.81,4.27,7.87,3.6,8,2.88c0.05-0.3-0.08-0.59-0.33-0.76c-0.25-0.17-0.58-0.16-0.83,0C3.81,4.14,2,7.52,2,11.16 C2,17.14,6.85,22,12.8,22c3.63,0,7-1.82,9.01-4.87C21.98,16.88,21.98,16.56,21.82,16.31z"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_restart.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_restart.xml new file mode 100644 index 000000000000..f0b9db44971e --- /dev/null +++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_restart.xml @@ -0,0 +1,21 @@ + +<!-- + 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 android:height="24dp" android:tint="?android:attr/colorControlNormal" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M6,12c0-0.71,0.11-1.34,0.35-1.93c0.2-0.51-0.05-1.09-0.56-1.3c-0.52-0.21-1.1,0.05-1.3,0.56C4.16,10.16,4,11.03,4,12 c0,4.07,3.06,7.44,7,7.94v-2.03C8.17,17.43,6,14.97,6,12z"/> + <path android:fillColor="@android:color/white" android:pathData="M12.01,4V1.72c0-0.45-0.54-0.67-0.86-0.35L7.43,5.13c-0.2,0.2-0.19,0.53,0.02,0.72l3.73,3.45 c0.32,0.3,0.84,0.07,0.84-0.37V6C15.32,6.01,18,8.69,18,12c0,2.97-2.17,5.43-5,5.91v2.03c3.94-0.5,7-3.86,7-7.94 C20,7.59,16.42,4.01,12.01,4z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_screenshot.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_screenshot.xml new file mode 100644 index 000000000000..da10874d53ad --- /dev/null +++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_screenshot.xml @@ -0,0 +1,22 @@ + +<!-- + 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 android:height="24dp" android:tint="?android:attr/colorControlNormal" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M17,23c1.1,0,2-0.9,2-2V3c0-1.1-0.9-2-2-2H7C5.9,1,5,1.9,5,3v18c0,1.1,0.9,2,2,2H17z M7,4h10v16H7V4z"/> + <path android:fillColor="@android:color/white" android:pathData="M11.25,5H9C8.45,5,8,5.45,8,6v2.25C8,8.66,8.34,9,8.75,9S9.5,8.66,9.5,8.25V6.5h1.75C11.66,6.5,12,6.16,12,5.75 C12,5.34,11.66,5,11.25,5z"/> + <path android:fillColor="@android:color/white" android:pathData="M15.25,15c-0.41,0-0.75,0.34-0.75,0.75v1.75h-1.75c-0.41,0-0.75,0.34-0.75,0.75c0,0.41,0.34,0.75,0.75,0.75H15 c0.55,0,1-0.45,1-1v-2.25C16,15.34,15.66,15,15.25,15z"/> +</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..2749ec699d6c --- /dev/null +++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_settings_bluetooth.xml @@ -0,0 +1,20 @@ + +<!-- + 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 android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <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_signal_location.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_signal_location.xml index 1d107b9df3a5..c759080f9e91 100644 --- a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_signal_location.xml +++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_signal_location.xml @@ -1,28 +1,20 @@ + <!-- -/** - * 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. - */ + 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,2A7,7,0,0,0,5,9c0,4.17,4.42,9.92,6.24,12.11a1,1,0,0,0,1.53,0C14.58,18.92,19,13.17,19,9A7,7,0,0,0,12,2Zm0,9.5A2.5,2.5,0,1,1,14.5,9,2.5,2.5,0,0,1,12,11.5Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M12.77,21.11C14.58,18.92,19,13.17,19,9c0-3.87-3.13-7-7-7S5,5.13,5,9c0,4.17,4.42,9.92,6.24,12.11 C11.64,21.59,12.37,21.59,12.77,21.11z M9.5,9c0-1.38,1.12-2.5,2.5-2.5s2.5,1.12,2.5,2.5c0,1.38-1.12,2.5-2.5,2.5S9.5,10.38,9.5,9z"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_wifi_signal_0.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_wifi_signal_0.xml index 0f7c5899a237..01a0a287ac3c 100644 --- a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_wifi_signal_0.xml +++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_wifi_signal_0.xml @@ -1,31 +1,20 @@ + <!-- -/** - * 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. - */ + 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:fillAlpha="0.3" - android:strokeAlpha="0.3" - android:strokeWidth="1" - android:pathData="M23.66,8.11a1.06,1.06,0,0,0-0.22-1.54A20.58,20.58,0,0,0,12,3,20.55,20.55,0,0,0,0.56,6.57,1.07,1.07,0,0,0,0.33,8.11L11.16,21.6a1.07,1.07,0,0,0,1.66,0Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillAlpha="0.3" android:fillColor="@android:color/white" android:pathData="M23.66,8.11c0.39-0.48,0.29-1.19-0.22-1.54C21.67,5.36,17.55,3,12,3C6.44,3,2.33,5.36,0.56,6.57 C0.05,6.92-0.05,7.63,0.33,8.11L11.16,21.6c0.42,0.53,1.23,0.53,1.66,0L23.66,8.11z" android:strokeAlpha="0.3" android:strokeWidth="1"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_wifi_signal_1.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_wifi_signal_1.xml index aa13b7e8f173..86a0a71b3bb0 100644 --- a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_wifi_signal_1.xml +++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_wifi_signal_1.xml @@ -1,34 +1,21 @@ + <!-- -/** - * 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. - */ + 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:fillAlpha="0.3" - android:strokeAlpha="0.3" - android:strokeWidth="1" - android:pathData="M23.66,8.11a1.06,1.06,0,0,0-0.22-1.54A20.58,20.58,0,0,0,12,3,20.55,20.55,0,0,0,0.56,6.57,1.07,1.07,0,0,0,0.33,8.11L11.16,21.6a1.07,1.07,0,0,0,1.66,0Z" /> - <path - android:fillColor="#000000" - android:pathData="M12.82,21.6l5.11-6.36a9,9,0,0,0-11.87,0l5.1,6.35A1.07,1.07,0,0,0,12.82,21.6Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillAlpha="0.3" android:fillColor="@android:color/white" android:pathData="M23.66,8.11c0.39-0.48,0.29-1.19-0.22-1.54C21.67,5.36,17.55,3,12,3C6.44,3,2.33,5.36,0.56,6.57 C0.05,6.92-0.05,7.63,0.33,8.11L11.16,21.6c0.42,0.53,1.23,0.53,1.66,0L23.66,8.11z" android:strokeAlpha="0.3" android:strokeWidth="1"/> + <path android:fillColor="@android:color/white" android:pathData="M12.82,21.6l5.11-6.36C16.29,13.79,14.18,13,12,13c-2.28,0-4.35,0.85-5.94,2.25l5.1,6.35 C11.59,22.13,12.39,22.13,12.82,21.6z"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_wifi_signal_2.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_wifi_signal_2.xml index b6d1b7229101..243d9dbea62d 100644 --- a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_wifi_signal_2.xml +++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_wifi_signal_2.xml @@ -1,34 +1,21 @@ + <!-- -/** - * 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. - */ + 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:fillAlpha="0.3" - android:strokeAlpha="0.3" - android:strokeWidth="1" - android:pathData="M23.66,8.11a1.06,1.06,0,0,0-0.22-1.54A20.58,20.58,0,0,0,12,3,20.55,20.55,0,0,0,0.56,6.57,1.07,1.07,0,0,0,0.33,8.11L11.16,21.6a1.07,1.07,0,0,0,1.66,0Z" /> - <path - android:fillColor="#000000" - android:pathData="M12.82,21.6l7-8.7a12,12,0,0,0-15.63,0l7,8.7A1.07,1.07,0,0,0,12.82,21.6Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillAlpha="0.3" android:fillColor="@android:color/white" android:pathData="M23.66,8.11c0.39-0.48,0.29-1.19-0.22-1.54C21.67,5.36,17.55,3,12,3C6.44,3,2.33,5.36,0.56,6.57 C0.05,6.92-0.05,7.63,0.33,8.11L11.16,21.6c0.42,0.53,1.23,0.53,1.66,0L23.66,8.11z" android:strokeAlpha="0.3" android:strokeWidth="1"/> + <path android:fillColor="@android:color/white" android:pathData="M12.82,21.6l6.99-8.7C17.71,11.1,14.99,10,12,10s-5.72,1.1-7.82,2.91l6.98,8.7C11.59,22.13,12.39,22.13,12.82,21.6z"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_wifi_signal_3.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_wifi_signal_3.xml index fe5718264029..c054b2255eca 100644 --- a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_wifi_signal_3.xml +++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_wifi_signal_3.xml @@ -1,34 +1,21 @@ + <!-- -/** - * 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. - */ + 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:fillAlpha="0.3" - android:strokeAlpha="0.3" - android:strokeWidth="1" - android:pathData="M23.66,8.11a1.06,1.06,0,0,0-0.22-1.54A20.58,20.58,0,0,0,12,3,20.55,20.55,0,0,0,0.56,6.57,1.07,1.07,0,0,0,0.33,8.11L11.16,21.6a1.07,1.07,0,0,0,1.66,0Z" /> - <path - android:fillColor="#000000" - android:pathData="M12.82,21.6l8.25-10.26a14,14,0,0,0-18.14,0l8.23,10.26A1.07,1.07,0,0,0,12.82,21.6Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillAlpha="0.3" android:fillColor="@android:color/white" android:pathData="M23.66,8.11c0.39-0.48,0.29-1.19-0.22-1.54C21.67,5.36,17.55,3,12,3C6.44,3,2.33,5.36,0.56,6.57 C0.05,6.92-0.05,7.63,0.33,8.11L11.16,21.6c0.42,0.53,1.23,0.53,1.66,0L23.66,8.11z" android:strokeAlpha="0.3" android:strokeWidth="1"/> + <path android:fillColor="@android:color/white" android:pathData="M12.82,21.6l8.25-10.26C18.54,9.18,15.32,8,12,8c-3.46,0-6.63,1.26-9.07,3.35l8.23,10.26 C11.59,22.13,12.39,22.13,12.82,21.6z"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_wifi_signal_4.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_wifi_signal_4.xml index d8aa0c2f45e4..ee26fc7aaeb5 100644 --- a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_wifi_signal_4.xml +++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_wifi_signal_4.xml @@ -1,28 +1,20 @@ + <!-- -/** - * 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. - */ + 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,3A20.55,20.55,0,0,0,0.56,6.57,1.07,1.07,0,0,0,0.33,8.11L11.16,21.6a1.07,1.07,0,0,0,1.66,0L23.66,8.11a1.06,1.06,0,0,0-0.22-1.54A20.58,20.58,0,0,0,12,3Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M12,3C6.44,3,2.33,5.36,0.56,6.57C0.05,6.92-0.05,7.63,0.33,8.11L11.16,21.6c0.42,0.53,1.23,0.53,1.66,0L23.66,8.11 c0.39-0.48,0.29-1.19-0.22-1.54C21.67,5.36,17.55,3,12,3z"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_airplanemode_active.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_airplanemode_active.xml new file mode 100644 index 000000000000..ebd7a28eab93 --- /dev/null +++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_airplanemode_active.xml @@ -0,0 +1,20 @@ + +<!-- + 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 android:height="24dp" android:tint="?android:attr/colorControlNormal" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <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/IconPackFilledSettingsOverlay/res/drawable/ic_apps.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_apps.xml index 015e73e81180..670e1810fa70 100644 --- a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_apps.xml +++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_apps.xml @@ -1,52 +1,28 @@ + <!-- -/** - * 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. - */ + 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="#FFFFFF" - android:pathData="M 4.5 4 L 7.5 4 Q 8 4 8 4.5 L 8 7.5 Q 8 8 7.5 8 L 4.5 8 Q 4 8 4 7.5 L 4 4.5 Q 4 4 4.5 4 Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M 10.5 4 L 13.5 4 Q 14 4 14 4.5 L 14 7.5 Q 14 8 13.5 8 L 10.5 8 Q 10 8 10 7.5 L 10 4.5 Q 10 4 10.5 4 Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M 16.5 4 L 19.5 4 Q 20 4 20 4.5 L 20 7.5 Q 20 8 19.5 8 L 16.5 8 Q 16 8 16 7.5 L 16 4.5 Q 16 4 16.5 4 Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M 4.5 10 L 7.5 10 Q 8 10 8 10.5 L 8 13.5 Q 8 14 7.5 14 L 4.5 14 Q 4 14 4 13.5 L 4 10.5 Q 4 10 4.5 10 Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M 10.5 10 L 13.5 10 Q 14 10 14 10.5 L 14 13.5 Q 14 14 13.5 14 L 10.5 14 Q 10 14 10 13.5 L 10 10.5 Q 10 10 10.5 10 Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M 16.5 10 L 19.5 10 Q 20 10 20 10.5 L 20 13.5 Q 20 14 19.5 14 L 16.5 14 Q 16 14 16 13.5 L 16 10.5 Q 16 10 16.5 10 Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M 4.5 16 L 7.5 16 Q 8 16 8 16.5 L 8 19.5 Q 8 20 7.5 20 L 4.5 20 Q 4 20 4 19.5 L 4 16.5 Q 4 16 4.5 16 Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M 10.5 16 L 13.5 16 Q 14 16 14 16.5 L 14 19.5 Q 14 20 13.5 20 L 10.5 20 Q 10 20 10 19.5 L 10 16.5 Q 10 16 10.5 16 Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M 16.5 16 L 19.5 16 Q 20 16 20 16.5 L 20 19.5 Q 20 20 19.5 20 L 16.5 20 Q 16 20 16 19.5 L 16 16.5 Q 16 16 16.5 16 Z" /> -</vector> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M7.5,4h-3C4.22,4,4,4.22,4,4.5v3C4,7.78,4.22,8,4.5,8h3C7.78,8,8,7.78,8,7.5v-3C8,4.22,7.78,4,7.5,4z"/> + <path android:fillColor="@android:color/white" android:pathData="M13.5,4h-3C10.22,4,10,4.22,10,4.5v3C10,7.78,10.22,8,10.5,8h3C13.78,8,14,7.78,14,7.5v-3C14,4.22,13.78,4,13.5,4z"/> + <path android:fillColor="@android:color/white" android:pathData="M19.5,4h-3C16.22,4,16,4.22,16,4.5v3C16,7.78,16.22,8,16.5,8h3C19.78,8,20,7.78,20,7.5v-3C20,4.22,19.78,4,19.5,4z"/> + <path android:fillColor="@android:color/white" android:pathData="M7.5,10h-3C4.22,10,4,10.22,4,10.5v3C4,13.78,4.22,14,4.5,14h3C7.78,14,8,13.78,8,13.5v-3C8,10.22,7.78,10,7.5,10z"/> + <path android:fillColor="@android:color/white" android:pathData="M13.5,10h-3c-0.28,0-0.5,0.22-0.5,0.5v3c0,0.28,0.22,0.5,0.5,0.5h3c0.28,0,0.5-0.22,0.5-0.5v-3C14,10.22,13.78,10,13.5,10 z"/> + <path android:fillColor="@android:color/white" android:pathData="M19.5,10h-3c-0.28,0-0.5,0.22-0.5,0.5v3c0,0.28,0.22,0.5,0.5,0.5h3c0.28,0,0.5-0.22,0.5-0.5v-3C20,10.22,19.78,10,19.5,10 z"/> + <path android:fillColor="@android:color/white" android:pathData="M7.5,16h-3C4.22,16,4,16.22,4,16.5v3C4,19.78,4.22,20,4.5,20h3C7.78,20,8,19.78,8,19.5v-3C8,16.22,7.78,16,7.5,16z"/> + <path android:fillColor="@android:color/white" android:pathData="M13.5,16h-3c-0.28,0-0.5,0.22-0.5,0.5v3c0,0.28,0.22,0.5,0.5,0.5h3c0.28,0,0.5-0.22,0.5-0.5v-3C14,16.22,13.78,16,13.5,16 z"/> + <path android:fillColor="@android:color/white" android:pathData="M19.5,16h-3c-0.28,0-0.5,0.22-0.5,0.5v3c0,0.28,0.22,0.5,0.5,0.5h3c0.28,0,0.5-0.22,0.5-0.5v-3C20,16.22,19.78,16,19.5,16 z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_data_saver.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_data_saver.xml new file mode 100644 index 000000000000..103985b67adb --- /dev/null +++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_data_saver.xml @@ -0,0 +1,22 @@ + +<!-- + 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 android:height="24dp" android:tint="?android:attr/colorControlNormal" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M11,11H9c-0.55,0-1,0.45-1,1s0.45,1,1,1h2v2c0,0.55,0.45,1,1,1s1-0.45,1-1v-2h2c0.55,0,1-0.45,1-1s-0.45-1-1-1h-2V9 c0-0.55-0.45-1-1-1s-1,0.45-1,1V11z"/> + <path android:fillColor="@android:color/white" android:pathData="M13,2.05v2.52c3.66,0.49,6.5,3.63,6.5,7.43c0,1.01-0.2,1.97-0.56,2.85l2.18,1.26C21.68,14.85,22,13.46,22,12 C22,6.81,18.05,2.55,13,2.05z"/> + <path android:fillColor="@android:color/white" android:pathData="M12,19.5c-4.14,0-7.5-3.36-7.5-7.5c0-3.8,2.84-6.93,6.5-7.43V2.05C5.95,2.55,2,6.81,2,12c0,5.52,4.48,10,10,10 c3.34,0,6.3-1.65,8.11-4.17l-2.18-1.26C16.56,18.35,14.41,19.5,12,19.5z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_devices_other.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_devices_other.xml index 0b12655a23f4..f5be375b5d18 100644 --- a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_devices_other.xml +++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_devices_other.xml @@ -1,34 +1,22 @@ + <!-- -/** - * 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. - */ + 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="#FFFFFF" - android:pathData="M3,20H6a1,1,0,0,0,0-2H3V6H20a1,1,0,0,0,0-2H3A2,2,0,0,0,1,6V18A2,2,0,0,0,3,20Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M23,19V9a1.08,1.08,0,0,0-1-1H16a1.08,1.08,0,0,0-1,1V19a1.08,1.08,0,0,0,1,1h6A1.08,1.08,0,0,0,23,19Zm-2-1H17V10h4Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M9,12v1.78a3,3,0,0,0,0,4.44V20h4V18.22a3,3,0,0,0,0-4.44V12Zm2,5.5A1.5,1.5,0,1,1,12.5,16,1.5,1.5,0,0,1,11,17.5Z" /> -</vector> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M6,18H3V6h17c0.55,0,1-0.45,1-1s-0.45-1-1-1H3C1.9,4,1,4.9,1,6v12c0,1.1,0.9,2,2,2h3c0.55,0,1-0.45,1-1S6.55,18,6,18z"/> + <path android:fillColor="@android:color/white" android:pathData="M13,12H9v1.78C8.39,14.33,8,15.11,8,16s0.39,1.67,1,2.22V20h4v-1.78c0.61-0.55,1-1.34,1-2.22s-0.39-1.67-1-2.22V12z M11,17.5c-0.83,0-1.5-0.67-1.5-1.5c0-0.83,0.67-1.5,1.5-1.5s1.5,0.67,1.5,1.5C12.5,16.83,11.83,17.5,11,17.5z"/> + <path android:fillColor="@android:color/white" android:pathData="M22,8h-6c-0.5,0-1,0.5-1,1v10c0,0.5,0.5,1,1,1h6c0.5,0,1-0.5,1-1V9C23,8.5,22.5,8,22,8z M21,18h-4v-8h4V18z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_help.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_help.xml index 097894d663e0..7b41ed4b3455 100644 --- a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_help.xml +++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_help.xml @@ -1,28 +1,20 @@ + <!-- -/** - * 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. - */ + 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="#FFFFFF" - android:pathData="M12,2A10,10,0,1,0,22,12,10,10,0,0,0,12,2Zm0,16.81a1.3,1.3,0,1,1,1.3-1.3A1.3,1.3,0,0,1,12,18.81Zm1.07-4.62a1,1,0,0,1-1.13 0.79 ,1,1,0,0,1-0.83-1.23c0.52-2.61,2.66-2.84,2.87-4.5a2,2,0,0,0-1.34-2.17,2,2,0,0,0-2.55,1.37,1,1,0,1,1-1.93-0.53A4,4,0,0,1,16,9.13C15.92,11.57,13.5,11.74,13.07,14.19Z" /> -</vector> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path 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,18.96 c-0.69,0-1.25-0.56-1.25-1.25c0-0.69,0.56-1.25,1.25-1.25s1.25,0.56,1.25,1.25C13.25,18.4,12.69,18.96,12,18.96z M8.16,7.92 c0.63-2.25,2.91-3.38,5.05-2.74c1.71,0.51,2.84,2.16,2.78,3.95c-0.07,2.44-2.49,2.61-2.92,5.06c-0.09,0.52-0.59,0.87-1.13,0.79 c-0.57-0.08-0.94-0.66-0.83-1.23c0.52-2.61,2.66-2.84,2.87-4.5c0.12-0.96-0.42-1.87-1.34-2.17c-1.04-0.33-2.21,0.16-2.55,1.37 C9.97,8.9,9.57,9.19,9.12,9.19C8.46,9.19,7.99,8.56,8.16,7.92z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_phone_info.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_phone_info.xml index 80f3d1e707a9..c6b3d040c497 100644 --- a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_phone_info.xml +++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_phone_info.xml @@ -1,34 +1,22 @@ + <!-- -/** - * 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. - */ + 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="#FFFFFF" - android:pathData="M7,1A2,2,0,0,0,5,3V21a2,2,0,0,0,2,2H17a2,2,0,0,0,2-2V3a2,2,0,0,0-2-2ZM17,19H7V5H17Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M12,11.62a1,1,0,0,0-1,0.9v3.59a1,1,0,0,0,2,0V12.52A1,1,0,0,0,12,11.62Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M 12 7.06 C 12.6903559373 7.06 13.25 7.61964406271 13.25 8.31 C 13.25 9.00035593729 12.6903559373 9.56 12 9.56 C 11.3096440627 9.56 10.75 9.00035593729 10.75 8.31 C 10.75 7.61964406271 11.3096440627 7.06 12 7.06 Z" /> -</vector> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M17,1.01L7,1C5.9,1,5,1.9,5,3v18c0,1.1,0.9,2,2,2h10c1.1,0,2-0.9,2-2V3C19,1.9,18.1,1.01,17,1.01z M17,19H7V5h10V19z"/> + <path android:fillColor="@android:color/white" android:pathData="M 12 7 C 12.6903559373 7 13.25 7.55964406271 13.25 8.25 C 13.25 8.94035593729 12.6903559373 9.5 12 9.5 C 11.3096440627 9.5 10.75 8.94035593729 10.75 8.25 C 10.75 7.55964406271 11.3096440627 7 12 7 Z"/> + <path android:fillColor="@android:color/white" android:pathData="M12,11c-0.55,0-1,0.4-1,0.9v4.21c0,0.5,0.45,0.9,1,0.9s1-0.4,1-0.9V11.9C13,11.4,12.55,11,12,11z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_accessibility.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_accessibility.xml index 9c8287bb3f8c..93df380e71d0 100644 --- a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_accessibility.xml +++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_accessibility.xml @@ -1,40 +1,24 @@ + <!-- -/** - * 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. - */ + 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="#FFFFFF" - android:pathData="M20.76,5l0-0.06a1,1,0,0,0-1.2-0.72A35.66,35.66,0,0,1,12,5a35.66,35.66,0,0,1-7.54-0.76A1,1,0,0,0,3.26,5l0,0.06A1,1,0,0,0,4,6.24,37,37,0,0,0,9,7V19a1,1,0,0,0,2,0V14h2v5a1,1,0,0,0,2,0V7a37,37,0,0,0,5-0.76A1,1,0,0,0,20.76,5Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M 12 0 C 13.1045694997 0 14 0.895430500338 14 2 C 14 3.10456949966 13.1045694997 4 12 4 C 10.8954305003 4 10 3.10456949966 10 2 C 10 0.895430500338 10.8954305003 0 12 0 Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M 12 22 C 12.5522847498 22 13 22.4477152502 13 23 C 13 23.5522847498 12.5522847498 24 12 24 C 11.4477152502 24 11 23.5522847498 11 23 C 11 22.4477152502 11.4477152502 22 12 22 Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M 16 22 C 16.5522847498 22 17 22.4477152502 17 23 C 17 23.5522847498 16.5522847498 24 16 24 C 15.4477152502 24 15 23.5522847498 15 23 C 15 22.4477152502 15.4477152502 22 16 22 Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M 8 22 C 8.55228474983 22 9 22.4477152502 9 23 C 9 23.5522847498 8.55228474983 24 8 24 C 7.44771525017 24 7 23.5522847498 7 23 C 7 22.4477152502 7.44771525017 22 8 22 Z" /> -</vector> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M20.76,5.02l-0.02-0.06c-0.13-0.53-0.67-0.85-1.2-0.73C17.16,4.77,14.49,5,12,5S6.84,4.77,4.46,4.24 c-0.54-0.12-1.07,0.19-1.2,0.73L3.24,5.02C3.11,5.56,3.43,6.12,3.97,6.24C5.59,6.61,7.34,6.86,9,7v12c0,0.55,0.45,1,1,1 s1-0.45,1-1v-5h2v5c0,0.55,0.45,1,1,1s1-0.45,1-1V7c1.66-0.14,3.41-0.39,5.03-0.76C20.57,6.12,20.89,5.56,20.76,5.02z"/> + <path android:fillColor="@android:color/white" android:pathData="M 12 0 C 13.1045694997 0 14 0.895430500338 14 2 C 14 3.10456949966 13.1045694997 4 12 4 C 10.8954305003 4 10 3.10456949966 10 2 C 10 0.895430500338 10.8954305003 0 12 0 Z"/> + <path android:fillColor="@android:color/white" android:pathData="M 12 22 C 12.5522847498 22 13 22.4477152502 13 23 C 13 23.5522847498 12.5522847498 24 12 24 C 11.4477152502 24 11 23.5522847498 11 23 C 11 22.4477152502 11.4477152502 22 12 22 Z"/> + <path android:fillColor="@android:color/white" android:pathData="M 16 22 C 16.5522847498 22 17 22.4477152502 17 23 C 17 23.5522847498 16.5522847498 24 16 24 C 15.4477152502 24 15 23.5522847498 15 23 C 15 22.4477152502 15.4477152502 22 16 22 Z"/> + <path android:fillColor="@android:color/white" android:pathData="M 8 22 C 8.55228474983 22 9 22.4477152502 9 23 C 9 23.5522847498 8.55228474983 24 8 24 C 7.44771525017 24 7 23.5522847498 7 23 C 7 22.4477152502 7.44771525017 22 8 22 Z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_accounts.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_accounts.xml index ea418a8006d5..77ec8ea64e80 100644 --- a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_accounts.xml +++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_accounts.xml @@ -1,31 +1,20 @@ + <!-- -/** - * 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. - */ + 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="#FFFFFF" - android:pathData="M12,22A10,10,0,1,0,2,12,10,10,0,0,0,12,22ZM12,4a8,8,0,0,1,6.36,12.83c-1.43-1.74-4.9-2.33-6.36-2.33s-4.93 0.59 -6.36,2.33A8,8,0,0,1,12,4Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M 12 6 C 13.9329966244 6 15.5 7.56700337559 15.5 9.5 C 15.5 11.4329966244 13.9329966244 13 12 13 C 10.0670033756 13 8.5 11.4329966244 8.5 9.5 C 8.5 7.56700337559 10.0670033756 6 12 6 Z" /> -</vector> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M12,2C6.48,2,2,6.48,2,12s4.48,10,10,10s10-4.48,10-10S17.52,2,12,2z M12,6c1.93,0,3.5,1.57,3.5,3.5S13.93,13,12,13 s-3.5-1.57-3.5-3.5S10.07,6,12,6z M12,20c-2.65,0-5-1.3-6.46-3.29C5.88,16.43,8.29,14.5,12,14.5s6.12,1.93,6.46,2.21 C17,18.7,14.65,20,12,20z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_battery_white.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_battery_white.xml index 1c5df00d27ef..08f27c494e58 100644 --- a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_battery_white.xml +++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_battery_white.xml @@ -1,28 +1,20 @@ + <!-- -/** - * 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. - */ + 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="#FFFFFF" - android:pathData="M10,2V4H8.33A1.34,1.34,0,0,0,7,5.33V20.66A1.34,1.34,0,0,0,8.33,22h7.33A1.34,1.34,0,0,0,17,20.67V5.33A1.34,1.34,0,0,0,15.67,4H14V2Z" /> -</vector> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M10,2v2H8.33C7.6,4,7,4.6,7,5.33v15.33C7,21.4,7.6,22,8.33,22h7.33C16.4,22,17,21.4,17,20.67V5.33C17,4.6,16.4,4,15.67,4 H14V2H10z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_delete.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_delete.xml new file mode 100644 index 000000000000..c59fb59fa1b6 --- /dev/null +++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_delete.xml @@ -0,0 +1,21 @@ + +<!-- + 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 android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M18,4h-2.5l-0.71-0.71C14.61,3.11,14.35,3,14.09,3H9.9C9.64,3,9.38,3.11,9.2,3.29L8.49,4h-2.5c-0.55,0-1,0.45-1,1 s0.45,1,1,1h12c0.55,0,1-0.45,1-1C19,4.45,18.55,4,18,4z"/> + <path android:fillColor="@android:color/white" android:pathData="M6,19c0,1.1,0.9,2,2,2h8c1.1,0,2-0.9,2-2V7H6V19z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_display_white.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_display_white.xml index 02e15d2d0638..3b32cbfc918d 100644 --- a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_display_white.xml +++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_display_white.xml @@ -1,28 +1,20 @@ + <!-- -/** - * 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. - */ + 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="#FFFFFF" - android:pathData="M4,15.3V19a1,1,0,0,0,1,1H8.69l2.6,2.6a1,1,0,0,0,1.41,0L15.3,20H19a1,1,0,0,0,1-1V15.31l2.6-2.6a1,1,0,0,0,0-1.41L20,8.69V5a1,1,0,0,0-1-1H15.31l-2.6-2.6a1,1,0,0,0-1.41,0L8.69,4H5A1,1,0,0,0,4,5V8.69l-2.6,2.6a1,1,0,0,0,0,1.41ZM12,6a6,6,0,0,1,0,12Z" /> -</vector> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M4,15.3V19c0,0.55,0.45,1,1,1h3.69l2.6,2.6c0.39,0.39,1.02,0.39,1.41,0l2.6-2.6H19c0.55,0,1-0.45,1-1v-3.69l2.6-2.6 c0.39-0.39,0.39-1.02,0-1.41L20,8.69V5c0-0.55-0.45-1-1-1h-3.69l-2.6-2.6c-0.39-0.39-1.02-0.39-1.41,0L8.69,4H5C4.45,4,4,4.45,4,5 v3.69l-2.6,2.6c-0.39,0.39-0.39,1.02,0,1.41L4,15.3z M12,6c3.31,0,6,2.69,6,6s-2.69,6-6,6V6z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_location.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_location.xml index 818236b88a9a..c759080f9e91 100644 --- a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_location.xml +++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_location.xml @@ -1,28 +1,20 @@ + <!-- -/** - * 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. - */ + 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="#FFFFFF" - android:pathData="M12,2A7,7,0,0,0,5,9c0,4.17,4.42,9.92,6.24,12.11a1,1,0,0,0,1.53,0C14.58,18.92,19,13.17,19,9A7,7,0,0,0,12,2Zm0,9.5A2.5,2.5,0,1,1,14.5,9,2.5,2.5,0,0,1,12,11.5Z" /> -</vector> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M12.77,21.11C14.58,18.92,19,13.17,19,9c0-3.87-3.13-7-7-7S5,5.13,5,9c0,4.17,4.42,9.92,6.24,12.11 C11.64,21.59,12.37,21.59,12.77,21.11z M9.5,9c0-1.38,1.12-2.5,2.5-2.5s2.5,1.12,2.5,2.5c0,1.38-1.12,2.5-2.5,2.5S9.5,10.38,9.5,9z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_privacy.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_privacy.xml index b0808822ee01..9b74c81159ad 100644 --- a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_privacy.xml +++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_privacy.xml @@ -1,34 +1,22 @@ + <!-- -/** - * 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. - */ + 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="#FFFFFF" - android:pathData="M12,19a12,12,0,0,0,2-0.17v-2A10.13,10.13,0,0,1,12,17a9.77,9.77,0,0,1-8.82-5.5,9.82,9.82,0,0,1,17.64,0H23a11.82,11.82,0,0,0-22,0A11.83,11.83,0,0,0,12,19Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M16.5,11.5a4.55,4.55,0,1,0-2.38,3.95,5,5,0,0,1,2.31-3.22A4.4,4.4,0,0,0,16.5,11.5ZM12,14.2a2.7,2.7,0,1,1,2.7-2.7A2.7,2.7,0,0,1,12,14.2Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M23,21V17a1.08,1.08,0,0,0-1-1v-0.5a2.5,2.5,0,0,0-5,0V16a1.08,1.08,0,0,0-1,1v4a1.08,1.08,0,0,0,1,1h5A1.08,1.08,0,0,0,23,21Zm-2.5-5h-2v-0.5a1,1,0,0,1,2,0Z" /> -</vector> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M16.48,11.7c0.74-0.44,1.6-0.7,2.52-0.7h3.78C20.93,6.88,16.81,4,12,4C7,4,2.73,7.11,1,11.5C2.73,15.89,7,19,12,19 c0.68,0,1.35-0.06,2-0.17V16c0-0.18,0.03-0.34,0.05-0.51C13.43,15.8,12.74,16,12,16c-2.49,0-4.5-2.01-4.5-4.5 C7.5,9.01,9.51,7,12,7s4.5,2.01,4.5,4.5C16.5,11.57,16.48,11.64,16.48,11.7z"/> + <path android:fillColor="@android:color/white" android:pathData="M 12 9 C 13.3807118746 9 14.5 10.1192881254 14.5 11.5 C 14.5 12.8807118746 13.3807118746 14 12 14 C 10.6192881254 14 9.5 12.8807118746 9.5 11.5 C 9.5 10.1192881254 10.6192881254 9 12 9 Z"/> + <path android:fillColor="@android:color/white" android:pathData="M22,16v-0.5c0-1.4-1.1-2.5-2.5-2.5S17,14.1,17,15.5V16c-0.5,0-1,0.5-1,1v4c0,0.5,0.5,1,1,1h5c0.5,0,1-0.5,1-1v-4 C23,16.5,22.5,16,22,16z M20.5,16h-2v-0.5c0-0.53,0.47-1,1-1s1,0.47,1,1V16z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_security_white.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_security_white.xml index 39ac0d717d6b..9f1bd70b912a 100644 --- a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_security_white.xml +++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_security_white.xml @@ -1,28 +1,20 @@ + <!-- -/** - * 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. - */ + 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="#FFFFFF" - android:pathData="M23,6a1,1,0,0,0,0.92-1.2A5,5,0,0,0,18.57,1a5.15,5.15,0,0,0-4.51,5.19V8H6a2,2,0,0,0-2,2V20a2,2,0,0,0,2,2H18a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2H16V6.12A3.18,3.18,0,0,1,18.44,3a3.1,3.1,0,0,1,3.62,2.27A1,1,0,0,0,23,6ZM12,17a2,2,0,1,1,2-2A2,2,0,0,1,12,17Z" /> -</vector> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M18,1c-2.21,0-4,1.79-4,4v3H6c-1.1,0-2,0.9-2,2v10c0,1.1,0.9,2,2,2h12c1.1,0,2-0.9,2-2V10c0-1.1-0.9-2-2-2h-2V5 c0-1.1,0.9-2,2-2s2,0.9,2,2c0,0.55,0.45,1,1,1s1-0.45,1-1C22,2.79,20.21,1,18,1z M12,17c-1.1,0-2-0.9-2-2c0-1.1,0.9-2,2-2 s2,0.9,2,2C14,16.1,13.1,17,12,17z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_system_dashboard_white.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_system_dashboard_white.xml index 3c29998da5c4..9a178775a81b 100644 --- a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_system_dashboard_white.xml +++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_system_dashboard_white.xml @@ -1,28 +1,20 @@ + <!-- -/** - * 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. - */ + 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="#FFFFFF" - android:pathData="M2,12A10,10,0,1,0,12,2,10,10,0,0,0,2,12Zm11,5.42a1,1,0,0,1-2,0V10.68a1,1,0,0,1,2,0ZM12,5.58a1.35,1.35,0,1,1-1.35,1.35A1.34,1.34,0,0,1,12,5.58Z" /> -</vector> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M12,2C6.48,2,2,6.48,2,12c0,5.52,4.48,10,10,10s10-4.48,10-10C22,6.48,17.52,2,12,2z M13,17c0,0.55-0.45,1-1,1s-1-0.45-1-1 v-5c0-0.55,0.45-1,1-1s1,0.45,1,1V17z M12,9.25c-0.69,0-1.25-0.56-1.25-1.25S11.31,6.75,12,6.75S13.25,7.31,13.25,8 S12.69,9.25,12,9.25z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_wireless_white.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_wireless_white.xml index 8fa846eeb345..96fa6951cac5 100644 --- a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_wireless_white.xml +++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_wireless_white.xml @@ -1,34 +1,22 @@ + <!-- -/** - * 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. - */ + 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="#FFFFFF" - android:pathData="M11.29,19.29a1,1,0,0,0,1.42,0L14,18a1,1,0,0,0-0.22-1.58A3.92,3.92,0,0,0,12,16a4,4,0,0,0-1.77 0.41 A1,1,0,0,0,10,18Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M17.6,14.39l0.71-0.71a1,1,0,0,0-0.08-1.49,10,10,0,0,0-12.44,0,1,1,0,0,0-0.08,1.49l0.7 0.72 a1,1,0,0,0,1.32 0.08 A6.91,6.91,0,0,1,12,13a7,7,0,0,1,4.29,1.47A1,1,0,0,0,17.6,14.39Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M21.83,10.16l0.71-0.71A1,1,0,0,0,22.48,8a15.79,15.79,0,0,0-20.92,0,1,1,0,0,0-0.07,1.47l0.71 0.71 a1,1,0,0,0,1.35 0.07 ,12.79,12.79,0,0,1,16.94,0A1,1,0,0,0,21.83,10.16Z" /> -</vector> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M11.29,19.29c0.39,0.39,1.03,0.4,1.42,0L14,18c0.47-0.47,0.38-1.28-0.22-1.58C13.25,16.15,12.64,16,12,16 c-0.64,0-1.24,0.15-1.77,0.41c-0.59,0.29-0.69,1.11-0.22,1.58L11.29,19.29z"/> + <path android:fillColor="@android:color/white" android:pathData="M17.6,14.39l0.71-0.71c0.42-0.42,0.39-1.12-0.08-1.5C16.52,10.82,14.35,10,12,10c-2.34,0-4.5,0.81-6.21,2.17 c-0.47,0.37-0.51,1.07-0.09,1.49l0.71,0.71c0.35,0.36,0.92,0.39,1.32,0.08C8.91,13.54,10.39,13,12,13c1.61,0,3.1,0.55,4.29,1.47 C16.69,14.78,17.25,14.75,17.6,14.39z"/> + <path android:fillColor="@android:color/white" android:pathData="M21.83,10.16l0.71-0.71c0.42-0.42,0.38-1.09-0.06-1.48C19.68,5.5,16.01,4,12,4C8.01,4,4.36,5.49,1.56,7.94 C1.12,8.33,1.08,9,1.49,9.41l0.71,0.71c0.37,0.37,0.96,0.4,1.35,0.06C5.81,8.2,8.77,7,12,7c3.25,0,6.22,1.22,8.49,3.22 C20.88,10.56,21.47,10.53,21.83,10.16z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_storage_white.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_storage_white.xml index 82733b6e5128..0d563327acd1 100644 --- a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_storage_white.xml +++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_storage_white.xml @@ -1,34 +1,22 @@ + <!-- -/** - * 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. - */ + 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="#FFFFFF" - android:pathData="M4,14H20a2,2,0,0,0,0-4H4a2,2,0,0,0,0,4Zm1-3.1A1.1,1.1,0,1,1,3.9,12,1.1,1.1,0,0,1,5,10.9Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M4,8H20a2,2,0,0,0,0-4H4A2,2,0,0,0,4,8ZM5,4.9A1.1,1.1,0,1,1,3.9,6,1.1,1.1,0,0,1,5,4.9Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M4,20H20a2,2,0,0,0,0-4H4a2,2,0,0,0,0,4Zm1-3.1A1.1,1.1,0,1,1,3.9,18,1.1,1.1,0,0,1,5,16.9Z" /> -</vector> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M19,10H5c-1.1,0-2,0.9-2,2c0,1.1,0.9,2,2,2h14c1.1,0,2-0.9,2-2C21,10.9,20.1,10,19,10z M6,13.1c-0.61,0-1.1-0.49-1.1-1.1 s0.49-1.1,1.1-1.1s1.1,0.49,1.1,1.1S6.61,13.1,6,13.1z"/> + <path android:fillColor="@android:color/white" android:pathData="M21,18c0-1.1-0.9-2-2-2H5c-1.1,0-2,0.9-2,2c0,1.1,0.9,2,2,2h14C20.1,20,21,19.1,21,18z M6,19.1c-0.61,0-1.1-0.49-1.1-1.1 s0.49-1.1,1.1-1.1s1.1,0.49,1.1,1.1S6.61,19.1,6,19.1z"/> + <path android:fillColor="@android:color/white" android:pathData="M19,4H5C3.9,4,3,4.9,3,6c0,1.1,0.9,2,2,2h14c1.1,0,2-0.9,2-2C21,4.9,20.1,4,19,4z M6,7.1C5.39,7.1,4.9,6.61,4.9,6 S5.39,4.9,6,4.9S7.1,5.39,7.1,6S6.61,7.1,6,7.1z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_volume_up_24dp.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_volume_up_24dp.xml index 9587e54082e8..5cd1acd43f71 100644 --- a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_volume_up_24dp.xml +++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_volume_up_24dp.xml @@ -1,34 +1,22 @@ + <!-- -/** - * 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. - */ + 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="#FFFFFF" - android:pathData="M10.29,5.7,7,9H4a1,1,0,0,0-1,1v4a1,1,0,0,0,1,1H7l3.29,3.29A1,1,0,0,0,12,17.58V6.41A1,1,0,0,0,10.29,5.7Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M16.5,12A4.5,4.5,0,0,0,14,8V16A4.47,4.47,0,0,0,16.5,12Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M14,19.54a0.91 0.91 ,0,0,0,1.22 0.86 ,9,9,0,0,0,0-16.8A0.91 0.91 ,0,0,0,14,4.46v0.19a0.92 0.92 ,0,0,0,0.61 0.85 ,7,7,0,0,1,0,13,0.92 0.92 ,0,0,0-0.61 0.85 Z" /> -</vector> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M20.4,8.78c-0.91-2.39-2.8-4.27-5.18-5.18C14.63,3.37,14,3.83,14,4.46v0.19c0,0.38,0.25,0.71,0.61,0.85 C17.18,6.54,19,9.06,19,12s-1.82,5.46-4.39,6.5C14.25,18.64,14,18.97,14,19.35v0.19c0,0.63,0.63,1.08,1.22,0.86 C19.86,18.62,22.18,13.42,20.4,8.78z"/> + <path android:fillColor="@android:color/white" android:pathData="M16.5,12c0-1.71-0.97-3.27-2.5-4.03v8.05C15.48,15.29,16.5,13.77,16.5,12z"/> + <path android:fillColor="@android:color/white" android:pathData="M10.29,5.7L7,9H4c-0.55,0-1,0.45-1,1v4c0,0.55,0.45,1,1,1h3l3.29,3.29c0.63,0.63,1.71,0.18,1.71-0.71V6.41 C12,5.52,10.92,5.07,10.29,5.7z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_wifi_tethering.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_wifi_tethering.xml index 84c347b9f0ff..43ca3cfaec2b 100644 --- a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_wifi_tethering.xml +++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_wifi_tethering.xml @@ -1,34 +1,22 @@ + <!-- -/** - * 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. - */ + 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="#FFFFFF" - android:pathData="M15.46,16.46h0A1,1,0,0,0,17,16.35,5.9,5.9,0,0,0,18,13,6,6,0,1,0,7,16.35a1,1,0,0,0,1.51 0.11 h0a1,1,0,0,0,0.11-1.29A3.9,3.9,0,0,1,8,12.44a4,4,0,1,1,7.32,2.73A1,1,0,0,0,15.46,16.46Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M10.86,3.06A10,10,0,0,0,4.19,19.25a1,1,0,0,0,1.49 0.07 A1,1,0,0,0,5.75,18a8.05,8.05,0,0,1-1.59-6.61A8,8,0,0,1,20,13a7.89,7.89,0,0,1-1.77,5,1,1,0,0,0,0.08,1.31h0a1,1,0,0,0,1.49-0.07A9.9,9.9,0,0,0,22,13,10,10,0,0,0,10.86,3.06Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M10,13a2,2,0,1,0,2-2A2,2,0,0,0,10,13Z" /> -</vector> +<vector android:height="24dp" android:tint="?android:attr/colorControlNormal" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M15.46,16.46L15.46,16.46c0.44,0.44,1.17,0.4,1.51-0.1C17.62,15.4,18,14.25,18,13c0-3.75-3.45-6.7-7.34-5.86 c-2.24,0.48-4.04,2.3-4.52,4.54c-0.37,1.75,0.02,3.38,0.89,4.67c0.34,0.51,1.08,0.54,1.51,0.11l0.01-0.01 c0.34-0.34,0.37-0.88,0.1-1.28c-0.5-0.76-0.75-1.71-0.61-2.74c0.23-1.74,1.67-3.17,3.41-3.4C13.9,8.71,16,10.61,16,13 c0,0.8-0.24,1.54-0.64,2.17C15.09,15.58,15.11,16.11,15.46,16.46z"/> + <path android:fillColor="@android:color/white" android:pathData="M10.86,3.06c-4.65,0.51-8.39,4.34-8.82,9c-0.25,2.72,0.6,5.25,2.15,7.18c0.37,0.46,1.07,0.49,1.49,0.07 C6.04,18.96,6.07,18.4,5.75,18c-1.4-1.75-2.09-4.1-1.6-6.61c0.61-3.13,3.14-5.65,6.28-6.24C15.54,4.18,20,8.07,20,13 c0,1.9-0.66,3.63-1.77,5c-0.32,0.39-0.28,0.96,0.08,1.31l0,0c0.42,0.42,1.12,0.39,1.49-0.08c1.38-1.7,2.2-3.88,2.2-6.24 C22,7.1,16.89,2.4,10.86,3.06z"/> + <path android:fillColor="@android:color/white" android:pathData="M 12 11 C 13.1045694997 11 14 11.8954305003 14 13 C 14 14.1045694997 13.1045694997 15 12 15 C 10.8954305003 15 10 14.1045694997 10 13 C 10 11.8954305003 10.8954305003 11 12 11 Z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_alarm.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_alarm.xml new file mode 100644 index 000000000000..a80cd718a807 --- /dev/null +++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_alarm.xml @@ -0,0 +1,22 @@ + +<!-- + 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 android:height="17dp" android:viewportHeight="24" android:viewportWidth="24" android:width="17dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M4.1,6.6l3-2.6c0.4-0.3,0.5-1,0.1-1.4c-0.4-0.4-1-0.5-1.4-0.1l-3,2.6c-0.4,0.4-0.5,1-0.1,1.4C3,6.9,3.6,7,4.1,6.6z"/> + <path android:fillColor="@android:color/white" android:pathData="M12,4c-5,0-9,4-9,9s4,9,9,9s9-4,9-9S17,4,12,4z M16.12,16.24c-0.21,0.34-0.64,0.45-0.98,0.24L11,14V8.75 C11,8.34,11.34,8,11.75,8s0.75,0.34,0.75,0.75v4.5l3.37,2C16.21,15.45,16.33,15.9,16.12,16.24z"/> + <path android:fillColor="@android:color/white" android:pathData="M21.3,5.1l-3.1-2.6c-0.4-0.4-0.99-0.31-1.4,0.1c-0.4,0.4-0.3,1,0.1,1.4L20,6.6c0.41,0.37,1,0.3,1.4-0.1 C21.73,6.12,21.7,5.4,21.3,5.1z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_alarm_dim.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_alarm_dim.xml new file mode 100644 index 000000000000..a80cd718a807 --- /dev/null +++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_alarm_dim.xml @@ -0,0 +1,22 @@ + +<!-- + 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 android:height="17dp" android:viewportHeight="24" android:viewportWidth="24" android:width="17dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M4.1,6.6l3-2.6c0.4-0.3,0.5-1,0.1-1.4c-0.4-0.4-1-0.5-1.4-0.1l-3,2.6c-0.4,0.4-0.5,1-0.1,1.4C3,6.9,3.6,7,4.1,6.6z"/> + <path android:fillColor="@android:color/white" android:pathData="M12,4c-5,0-9,4-9,9s4,9,9,9s9-4,9-9S17,4,12,4z M16.12,16.24c-0.21,0.34-0.64,0.45-0.98,0.24L11,14V8.75 C11,8.34,11.34,8,11.75,8s0.75,0.34,0.75,0.75v4.5l3.37,2C16.21,15.45,16.33,15.9,16.12,16.24z"/> + <path android:fillColor="@android:color/white" android:pathData="M21.3,5.1l-3.1-2.6c-0.4-0.4-0.99-0.31-1.4,0.1c-0.4,0.4-0.3,1,0.1,1.4L20,6.6c0.41,0.37,1,0.3,1.4-0.1 C21.73,6.12,21.7,5.4,21.3,5.1z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_bluetooth_connected.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_bluetooth_connected.xml new file mode 100644 index 000000000000..a0144a452900 --- /dev/null +++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_bluetooth_connected.xml @@ -0,0 +1,22 @@ + +<!-- + 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 android:height="17dp" android:viewportHeight="24" android:viewportWidth="24" android:width="17dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M20.06,10.94c-0.01-0.01-0.01-0.01-0.02-0.02c-0.59-0.58-1.53-0.57-2.1,0.02l-0.01,0.01c-0.58,0.59-0.58,1.53,0.01,2.11 c0.58,0.59,1.53,0.59,2.12,0C20.65,12.48,20.65,11.53,20.06,10.94z"/> + <path android:fillColor="@android:color/white" android:pathData="M6.06,10.94l-0.01-0.01c-0.59-0.58-1.53-0.58-2.11,0.01l-0.01,0.01c-0.58,0.59-0.58,1.53,0.01,2.11 c0.58,0.59,1.53,0.59,2.12,0S6.65,11.53,6.06,10.94z"/> + <path android:fillColor="@android:color/white" android:pathData="M13.51,12l3.75-3.74c0.41-0.41,0.41-1.07,0-1.48l-4.47-4.47l-0.03-0.03c-0.42-0.39-1.08-0.37-1.48,0.05 C11.1,2.52,11,2.78,11,3.04v6.44L6.95,5.43c-0.41-0.41-1.06-0.41-1.47,0c-0.41,0.41-0.41,1.06,0,1.47l5.09,5.1l-5.09,5.09 c-0.41,0.41-0.41,1.06,0,1.47c0.41,0.41,1.06,0.41,1.47,0L11,14.51v6.45c0,0.57,0.47,1.04,1.04,1.04c0.26,0,0.52-0.1,0.71-0.28 l0.05-0.05l4.46-4.46c0.41-0.41,0.41-1.07,0-1.48L13.51,12z M12.99,5.37l2.15,2.15l-2.15,2.15V5.37z M12.99,18.62v-4.3l2.15,2.15 L12.99,18.62z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_brightness_thumb.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_brightness_thumb.xml index fce6e94b5d67..74f57193c74a 100644 --- a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_brightness_thumb.xml +++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_brightness_thumb.xml @@ -1,28 +1,21 @@ + <!-- -/** - * 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. - */ + 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="?android:attr/colorControlActivated" - android:pathData="M4,15.3V19a1,1,0,0,0,1,1H8.69l2.6,2.6a1,1,0,0,0,1.41,0L15.3,20H19a1,1,0,0,0,1-1V15.31l2.6-2.6a1,1,0,0,0,0-1.41L20,8.69V5a1,1,0,0,0-1-1H15.31l-2.6-2.6a1,1,0,0,0-1.41,0L8.69,4H5A1,1,0,0,0,4,5V8.69l-2.6,2.6a1,1,0,0,0,0,1.41ZM12,7a5,5,0,1,1-5,5A5,5,0,0,1,12,7Z" /> -</vector> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="?android:attr/colorControlActivated" android:pathData="M4,15.3V19c0,0.55,0.45,1,1,1h3.69l2.6,2.6c0.39,0.39,1.02,0.39,1.41,0l2.6-2.6H19c0.55,0,1-0.45,1-1v-3.69l2.6-2.6 c0.39-0.39,0.39-1.02,0-1.41L20,8.69V5c0-0.55-0.45-1-1-1h-3.69l-2.6-2.6c-0.39-0.39-1.02-0.39-1.41,0L8.69,4H5C4.45,4,4,4.45,4,5 v3.69l-2.6,2.6c-0.39,0.39-0.39,1.02,0,1.41L4,15.3z M12,7c2.76,0,5,2.24,5,5s-2.24,5-5,5s-5-2.24-5-5S9.24,7,12,7z"/> + <path android:fillColor="?android:attr/colorPrimary" android:pathData="M 12 7 C 14.7614237492 7 17 9.23857625085 17 12 C 17 14.7614237492 14.7614237492 17 12 17 C 9.23857625085 17 7 14.7614237492 7 12 C 7 9.23857625085 9.23857625085 7 12 7 Z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_camera.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_camera.xml new file mode 100644 index 000000000000..9bfbe1c27659 --- /dev/null +++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_camera.xml @@ -0,0 +1,21 @@ + +<!-- + 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 android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M 12 8.8 C 13.7673111995 8.8 15.2 10.2326888005 15.2 12 C 15.2 13.7673111995 13.7673111995 15.2 12 15.2 C 10.2326888005 15.2 8.8 13.7673111995 8.8 12 C 8.8 10.2326888005 10.2326888005 8.8 12 8.8 Z"/> + <path android:fillColor="@android:color/white" android:pathData="M20,4h-3.17L15,2H9L7.17,4H4C2.9,4,2,4.9,2,6v12c0,1.1,0.9,2,2,2h16c1.1,0,2-0.9,2-2V6C22,4.9,21.1,4,20,4z M12,17 c-2.76,0-5-2.24-5-5s2.24-5,5-5s5,2.24,5,5S14.76,17,12,17z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_cast.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_cast.xml new file mode 100644 index 000000000000..7b5efbd61a8f --- /dev/null +++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_cast.xml @@ -0,0 +1,23 @@ + +<!-- + 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 android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M2.11,14.08C1.52,13.99,1.02,14.46,1,15.06c-0.01,0.51,0.32,0.93,0.82,1.02c2.08,0.36,3.74,2,4.1,4.08 C6.01,20.64,6.42,21,6.91,21c0.61,0,1.09-0.54,1-1.14C7.42,16.88,5.09,14.56,2.11,14.08z"/> + <path android:fillColor="@android:color/white" android:pathData="M1,18v2c0,0.55,0.45,1,1,1h2C4,19.34,2.66,18,1,18z"/> + <path android:fillColor="@android:color/white" android:pathData="M21,3H3C1.9,3,1,3.9,1,5v3h2V5h18v14h-7v2h7c1.1,0,2-0.9,2-2V5C23,3.9,22.1,3,21,3z"/> + <path android:fillColor="@android:color/white" android:pathData="M2.07,10.05C1.5,10,1.02,10.45,1,11.03c-0.01,0.52,0.34,0.96,0.85,1.01c4.26,0.43,7.68,3.82,8.1,8.08 C10,20.62,10.43,21,10.94,21c0.59,0,1.06-0.51,1-1.1C11.42,14.69,7.28,10.56,2.07,10.05z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_cast_connected.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_cast_connected.xml new file mode 100644 index 000000000000..03f9cde25f9a --- /dev/null +++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_cast_connected.xml @@ -0,0 +1,24 @@ + +<!-- + 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 android:height="17dp" android:viewportHeight="24" android:viewportWidth="24" android:width="17dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M2.07,10.05C1.5,10,1.02,10.45,1,11.03c-0.01,0.52,0.34,0.96,0.85,1.01c4.26,0.43,7.68,3.82,8.1,8.08 C10,20.62,10.43,21,10.94,21c0.59,0,1.06-0.51,1-1.1C11.42,14.69,7.28,10.56,2.07,10.05z"/> + <path android:fillColor="@android:color/white" android:pathData="M2.11,14.08C1.52,13.99,1.02,14.46,1,15.06c-0.01,0.51,0.32,0.93,0.82,1.02c2.08,0.36,3.74,2,4.1,4.08 C6.01,20.64,6.42,21,6.91,21c0.61,0,1.09-0.54,1-1.14C7.42,16.88,5.09,14.56,2.11,14.08z"/> + <path android:fillColor="@android:color/white" android:pathData="M21,3H3C1.9,3,1,3.9,1,5v3h2V5h18v14h-7v2h7c1.1,0,2-0.9,2-2V5C23,3.9,22.1,3,21,3z"/> + <path android:fillColor="@android:color/white" android:pathData="M19,7H5v1.63c3.96,1.28,7.09,4.41,8.37,8.37H19V7z"/> + <path android:fillColor="@android:color/white" android:pathData="M1,18v2c0,0.55,0.45,1,1,1h2C4,19.34,2.66,18,1,18z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_close_white.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_close_white.xml new file mode 100644 index 000000000000..20471092ee6c --- /dev/null +++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_close_white.xml @@ -0,0 +1,20 @@ + +<!-- + 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 android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M5.7,18.3c0.39,0.39,1.02,0.39,1.41,0L12,13.41l4.89,4.89c0.39,0.39,1.02,0.39,1.41,0s0.39-1.02,0-1.41L13.41,12l4.89-4.89 c0.38-0.38,0.38-1.02,0-1.4c-0.39-0.39-1.02-0.39-1.41,0c0,0,0,0,0,0L12,10.59L7.11,5.7c-0.39-0.39-1.02-0.39-1.41,0 s-0.39,1.02,0,1.41L10.59,12L5.7,16.89C5.31,17.28,5.31,17.91,5.7,18.3z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_data_saver.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_data_saver.xml new file mode 100644 index 000000000000..b01cada6487c --- /dev/null +++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_data_saver.xml @@ -0,0 +1,22 @@ + +<!-- + 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 android:height="18dp " android:viewportHeight="24" android:viewportWidth="24" android:width="18dp " xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M11,11H9c-0.55,0-1,0.45-1,1s0.45,1,1,1h2v2c0,0.55,0.45,1,1,1s1-0.45,1-1v-2h2c0.55,0,1-0.45,1-1s-0.45-1-1-1h-2V9 c0-0.55-0.45-1-1-1s-1,0.45-1,1V11z"/> + <path android:fillColor="@android:color/white" android:pathData="M13,2.05v2.52c3.66,0.49,6.5,3.63,6.5,7.43c0,1.01-0.2,1.97-0.56,2.85l2.18,1.26C21.68,14.85,22,13.46,22,12 C22,6.81,18.05,2.55,13,2.05z"/> + <path android:fillColor="@android:color/white" android:pathData="M12,19.5c-4.14,0-7.5-3.36-7.5-7.5c0-3.8,2.84-6.93,6.5-7.43V2.05C5.95,2.55,2,6.81,2,12c0,5.52,4.48,10,10,10 c3.34,0,6.3-1.65,8.11-4.17l-2.18-1.26C16.56,18.35,14.41,19.5,12,19.5z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_data_saver_off.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_data_saver_off.xml index 0949dc9d9d1b..e6a64acc9981 100644 --- a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_data_saver_off.xml +++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_data_saver_off.xml @@ -1,34 +1,21 @@ + <!-- -/** - * 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. - */ + 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,8a1,1,0,0,0-1,1v2H9a1,1,0,0,0,0,2h2v2a1,1,0,0,0,2,0V13h2a1,1,0,0,0,0-2H13V9A1,1,0,0,0,12,8Z" /> - <path - android:fillColor="#000000" - android:pathData="M21.37,15.5A10.15,10.15,0,0,0,22,12a10,10,0,0,0-8.43-9.88 0.51 0.51,0,0,0-0.57 0.5 V4.15a0.49 0.49 ,0,0,0,0.41 0.48 ,7.5,7.5,0,0,1,5.7,9.75 0.49 0.49,0,0,0,0.21 0.59 l1.33 0.77 A0.51 0.51 ,0,0,0,21.37,15.5Z" /> - <path - android:fillColor="#000000" - android:pathData="M10.43,2.12a10,10,0,1,0,9.36,16.13 0.5 0.5,0,0,0-0.15-0.74l-1.32-0.76a0.48 0.48 ,0,0,0-0.62 0.12 ,7.44,7.44,0,0,1-5.93,2.63,7.58,7.58,0,0,1-7.25-7.07,7.5,7.5,0,0,1,6.07-7.79A0.51 0.51 ,0,0,0,11,4.15V2.62A0.5 0.5 ,0,0,0,10.43,2.12Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M13,4.57c3.66,0.49,6.5,3.63,6.5,7.43c0,1.01-0.2,1.97-0.56,2.85l2.18,1.26C21.68,14.85,22,13.46,22,12 c0-5.19-3.95-9.45-9-9.95V4.57z"/> + <path android:fillColor="@android:color/white" android:pathData="M17.93,16.57c-1.37,1.78-3.52,2.93-5.93,2.93c-4.14,0-7.5-3.36-7.5-7.5c0-3.8,2.84-6.93,6.5-7.43V2.05 C5.95,2.55,2,6.81,2,12c0,5.52,4.48,10,10,10c3.34,0,6.3-1.65,8.11-4.17L17.93,16.57z"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_dnd.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_dnd.xml deleted file mode 100644 index e6086f3813c1..000000000000 --- a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_dnd.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,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" /> -</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_drag_handle.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_drag_handle.xml index 8f6db4925441..083beafe3567 100644 --- a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_drag_handle.xml +++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_drag_handle.xml @@ -1,31 +1,21 @@ + <!-- -/** - * 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. - */ + 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="M19,9H5a1,1,0,0,0,0,2H19a1,1,0,0,0,0-2Z" /> - <path - android:fillColor="#000000" - android:pathData="M19,13H5a1,1,0,0,0,0,2H19a1,1,0,0,0,0-2Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M19,13H5c-0.55,0-1,0.45-1,1s0.45,1,1,1h14c0.55,0,1-0.45,1-1S19.55,13,19,13z"/> + <path android:fillColor="@android:color/white" android:pathData="M19,9H5c-0.55,0-1,0.45-1,1s0.45,1,1,1h14c0.55,0,1-0.45,1-1S19.55,9,19,9z"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_headset.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_headset.xml index 428d453955ff..92e0f08614f2 100644 --- a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_headset.xml +++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_headset.xml @@ -1,28 +1,20 @@ + <!-- -/** - * 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. - */ + 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="M21,18V11a9,9,0,0,0-9.6-9A9.21,9.21,0,0,0,3,11.31V17.2C3,19.66,4.34,21,6,21H8a1,1,0,0,0,1-1V14a1,1,0,0,0-1-1H5V11.29A7.19,7.19,0,0,1,11.79,4,7,7,0,0,1,19,11v2H16a1,1,0,0,0-1,1v6a1,1,0,0,0,1,1h2A3,3,0,0,0,21,18Z" /> +<vector android:height="17dp" android:viewportHeight="24" android:viewportWidth="24" android:width="17dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M21,18v-7c0-5.17-4.36-9.32-9.6-8.98C6.62,2.33,3,6.52,3,11.31v5.89C3,19.66,4.34,21,6,21h2c0.55,0,1-0.45,1-1v-6 c0-0.55-0.45-1-1-1H5v-1.71C5,7.45,7.96,4.11,11.79,4C15.76,3.89,19,7.06,19,11v2h-3c-0.55,0-1,0.45-1,1v6c0,0.55,0.45,1,1,1h2 C19.66,21,21,19.66,21,18z"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_headset_mic.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_headset_mic.xml new file mode 100644 index 000000000000..ef0524abdaa8 --- /dev/null +++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_headset_mic.xml @@ -0,0 +1,21 @@ + +<!-- + 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 android:height="17dp" android:viewportHeight="24" android:viewportWidth="24" android:width="17dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:pathData="M0,0h24v24H0V0z"/> + <path android:fillColor="@android:color/white" android:pathData="M11.4,1.02C6.62,1.33,3,5.52,3,10.31L3,17c0,1.66,1.34,3,3,3h2c0.55,0,1-0.45,1-1v-6c0-0.55-0.45-1-1-1H5l0-1.71 C5,6.45,7.96,3.11,11.79,3C15.76,2.89,19,6.06,19,10v2h-3c-0.55,0-1,0.45-1,1v6c0,0.55,0.45,1,1,1h3v1h-6c-0.55,0-1,0.45-1,1v0 c0,0.55,0.45,1,1,1h5c1.66,0,3-1.34,3-3V10C21,4.83,16.64,0.68,11.4,1.02z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_hotspot.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_hotspot.xml index 00241f8e2132..602b0f14cc1d 100644 --- a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_hotspot.xml +++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_hotspot.xml @@ -1,34 +1,22 @@ + <!-- -/** - * 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. - */ + 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="M15.46,16.46h0A1,1,0,0,0,17,16.35,5.9,5.9,0,0,0,18,13,6,6,0,1,0,7,16.35a1,1,0,0,0,1.51 0.11 h0a1,1,0,0,0,0.11-1.29A3.9,3.9,0,0,1,8,12.44a4,4,0,1,1,7.32,2.73A1,1,0,0,0,15.46,16.46Z" /> - <path - android:fillColor="#000000" - android:pathData="M10.86,3.06A10,10,0,0,0,4.19,19.25a1,1,0,0,0,1.49 0.07 A1,1,0,0,0,5.75,18a8.05,8.05,0,0,1-1.59-6.61A8,8,0,0,1,20,13a7.89,7.89,0,0,1-1.77,5,1,1,0,0,0,0.08,1.31h0a1,1,0,0,0,1.49-0.07A9.9,9.9,0,0,0,22,13,10,10,0,0,0,10.86,3.06Z" /> - <path - android:fillColor="#000000" - android:pathData="M10,13a2,2,0,1,0,2-2A2,2,0,0,0,10,13Z" /> +<vector android:height="18dp" android:viewportHeight="24" android:viewportWidth="24" android:width="18dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M15.46,16.46L15.46,16.46c0.44,0.44,1.17,0.4,1.51-0.1C17.62,15.4,18,14.25,18,13c0-3.75-3.45-6.7-7.34-5.86 c-2.24,0.48-4.04,2.3-4.52,4.54c-0.37,1.75,0.02,3.38,0.89,4.67c0.34,0.51,1.08,0.54,1.51,0.11l0.01-0.01 c0.34-0.34,0.37-0.88,0.1-1.28c-0.5-0.76-0.75-1.71-0.61-2.74c0.23-1.74,1.67-3.17,3.41-3.4C13.9,8.71,16,10.61,16,13 c0,0.8-0.24,1.54-0.64,2.17C15.09,15.58,15.11,16.11,15.46,16.46z"/> + <path android:fillColor="@android:color/white" android:pathData="M10.86,3.06c-4.65,0.51-8.39,4.34-8.82,9c-0.25,2.72,0.6,5.25,2.15,7.18c0.37,0.46,1.07,0.49,1.49,0.07 C6.04,18.96,6.07,18.4,5.75,18c-1.4-1.75-2.09-4.1-1.6-6.61c0.61-3.13,3.14-5.65,6.28-6.24C15.54,4.18,20,8.07,20,13 c0,1.9-0.66,3.63-1.77,5c-0.32,0.39-0.28,0.96,0.08,1.31l0,0c0.42,0.42,1.12,0.39,1.49-0.08c1.38-1.7,2.2-3.88,2.2-6.24 C22,7.1,16.89,2.4,10.86,3.06z"/> + <path android:fillColor="@android:color/white" android:pathData="M 12 11 C 13.1045694997 11 14 11.8954305003 14 13 C 14 14.1045694997 13.1045694997 15 12 15 C 10.8954305003 15 10 14.1045694997 10 13 C 10 11.8954305003 10.8954305003 11 12 11 Z"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_info.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_info.xml index e39a2a0eb286..9a178775a81b 100644 --- a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_info.xml +++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_info.xml @@ -1,28 +1,20 @@ + <!-- -/** - * 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. - */ + 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,12A10,10,0,1,0,12,2,10,10,0,0,0,2,12Zm11,5.42a1,1,0,0,1-2,0V10.68a1,1,0,0,1,2,0ZM12,5.58a1.35,1.35,0,1,1-1.35,1.35A1.34,1.34,0,0,1,12,5.58Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M12,2C6.48,2,2,6.48,2,12c0,5.52,4.48,10,10,10s10-4.48,10-10C22,6.48,17.52,2,12,2z M13,17c0,0.55-0.45,1-1,1s-1-0.45-1-1 v-5c0-0.55,0.45-1,1-1s1,0.45,1,1V17z M12,9.25c-0.69,0-1.25-0.56-1.25-1.25S11.31,6.75,12,6.75S13.25,7.31,13.25,8 S12.69,9.25,12,9.25z"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_info_outline.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_info_outline.xml new file mode 100644 index 000000000000..9a178775a81b --- /dev/null +++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_info_outline.xml @@ -0,0 +1,20 @@ + +<!-- + 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 android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M12,2C6.48,2,2,6.48,2,12c0,5.52,4.48,10,10,10s10-4.48,10-10C22,6.48,17.52,2,12,2z M13,17c0,0.55-0.45,1-1,1s-1-0.45-1-1 v-5c0-0.55,0.45-1,1-1s1,0.45,1,1V17z M12,9.25c-0.69,0-1.25-0.56-1.25-1.25S11.31,6.75,12,6.75S13.25,7.31,13.25,8 S12.69,9.25,12,9.25z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_invert_colors.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_invert_colors.xml new file mode 100644 index 000000000000..653f856e2202 --- /dev/null +++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_invert_colors.xml @@ -0,0 +1,20 @@ + +<!-- + 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 android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M12.7,3.39c-0.1-0.1-0.21-0.17-0.33-0.22C12.25,3.13,12.12,3.1,12,3.1c-0.26,0-0.51,0.1-0.71,0.29L6.56,8.13 c-3,3-3.4,7.89-0.62,11.1C7.54,21.08,9.77,22,12,22c2.23,0,4.45-0.92,6.05-2.76c2.79-3.21,2.39-8.11-0.61-11.11L12.7,3.39z M7.45,17.92c-2.04-2.36-1.81-6.04,0.52-8.38L12,5.51l0,0V20C10.25,20,8.6,19.24,7.45,17.92z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_location.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_location.xml new file mode 100644 index 000000000000..d736b4115ae5 --- /dev/null +++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_location.xml @@ -0,0 +1,20 @@ + +<!-- + 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 android:height="17dp" android:viewportHeight="24" android:viewportWidth="24" android:width="17dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M12.77,21.11C14.58,18.92,19,13.17,19,9c0-3.87-3.13-7-7-7S5,5.13,5,9c0,4.17,4.42,9.92,6.24,12.11 C11.64,21.59,12.37,21.59,12.77,21.11z M9.5,9c0-1.38,1.12-2.5,2.5-2.5s2.5,1.12,2.5,2.5c0,1.38-1.12,2.5-2.5,2.5S9.5,10.38,9.5,9z"/> +</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 index 8b9f5627a98b..28ad305f1efe 100644 --- a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_lockscreen_ime.xml +++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_lockscreen_ime.xml @@ -1,55 +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. - */ + 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 android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M21,4H3C1.9,4,1,4.9,1,6v13c0,1.1,0.9,2,2,2h18c1.1,0,2-0.9,2-2V6C23,4.9,22.1,4,21,4z M21,19H3V6h18V19z"/> + <path android:fillColor="@android:color/white" android:pathData="M9.5,10h1c0.28,0,0.5-0.22,0.5-0.5v-1C11,8.22,10.78,8,10.5,8h-1C9.22,8,9,8.22,9,8.5v1C9,9.78,9.22,10,9.5,10z"/> + <path android:fillColor="@android:color/white" android:pathData="M5.5,10h1C6.78,10,7,9.78,7,9.5v-1C7,8.22,6.78,8,6.5,8h-1C5.22,8,5,8.22,5,8.5v1C5,9.78,5.22,10,5.5,10z"/> + <path android:fillColor="@android:color/white" android:pathData="M13.5,10h1c0.28,0,0.5-0.22,0.5-0.5v-1C15,8.22,14.78,8,14.5,8h-1C13.22,8,13,8.22,13,8.5v1C13,9.78,13.22,10,13.5,10z"/> + <path android:fillColor="@android:color/white" android:pathData="M9.5,14h1c0.28,0,0.5-0.22,0.5-0.5v-1c0-0.28-0.22-0.5-0.5-0.5h-1C9.22,12,9,12.22,9,12.5v1C9,13.78,9.22,14,9.5,14z"/> + <path android:fillColor="@android:color/white" android:pathData="M5.5,14h1C6.78,14,7,13.78,7,13.5v-1C7,12.22,6.78,12,6.5,12h-1C5.22,12,5,12.22,5,12.5v1C5,13.78,5.22,14,5.5,14z"/> + <path android:fillColor="@android:color/white" android:pathData="M13.5,14h1c0.28,0,0.5-0.22,0.5-0.5v-1c0-0.28-0.22-0.5-0.5-0.5h-1c-0.28,0-0.5,0.22-0.5,0.5v1C13,13.78,13.22,14,13.5,14 z"/> + <path android:fillColor="@android:color/white" android:pathData="M17.5,10h1c0.28,0,0.5-0.22,0.5-0.5v-1C19,8.22,18.78,8,18.5,8h-1C17.22,8,17,8.22,17,8.5v1C17,9.78,17.22,10,17.5,10z"/> + <path android:fillColor="@android:color/white" android:pathData="M17.5,14h1c0.28,0,0.5-0.22,0.5-0.5v-1c0-0.28-0.22-0.5-0.5-0.5h-1c-0.28,0-0.5,0.22-0.5,0.5v1C17,13.78,17.22,14,17.5,14 z"/> + <path android:fillColor="@android:color/white" android:pathData="M8.5,17h7c0.28,0,0.5-0.22,0.5-0.5S15.78,16,15.5,16h-7C8.22,16,8,16.22,8,16.5S8.22,17,8.5,17z"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_notifications_alert.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_notifications_alert.xml index 7858b0533fb4..c2e0af3dd7b9 100644 --- a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_notifications_alert.xml +++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_notifications_alert.xml @@ -1,37 +1,23 @@ + <!-- -/** - * 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. - */ + 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="M5.4,3.27A10.45,10.45,0,0,0,2.15,9.34a1,1,0,0,0,2,0.33A8.44,8.44,0,0,1,6.77,4.73a1,1,0,0,0,0-1.43A1,1,0,0,0,5.4,3.27Z" /> - <path - android:fillColor="#000000" - android:pathData="M19.88,9.66a1,1,0,1,0,2-0.32A10.51,10.51,0,0,0,18.6,3.28a1,1,0,0,0-1.4,0,1,1,0,0,0,0,1.42A8.5,8.5,0,0,1,19.88,9.66Z" /> - <path - android:fillColor="#000000" - android:pathData="M14,20H10a2,2,0,0,0,4,0Z" /> - <path - android:fillColor="#000000" - android:pathData="M12,2.5A1.5,1.5,0,0,0,10.5,4v0.68C7.63,5.36,6,7.92,6,11v5L3.85,18.15a0.5 0.5 ,0,0,0,0,0.71A0.48 0.48 ,0,0,0,4.2,19H19.8a0.49 0.49 ,0,0,0,0.35-0.85L18,16V11c0-3.07-1.64-5.64-4.5-6.32V4A1.5,1.5,0,0,0,12,2.5ZM16,11v6H8V11c0-2.48,1.51-4.5,4-4.5S16,8.52,16,11Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M4.12,9.67C4.42,7.73,5.38,6,6.77,4.73C7.19,4.35,7.2,3.7,6.8,3.3c-0.39-0.39-1-0.39-1.4-0.03 C3.7,4.84,2.52,6.96,2.15,9.34c-0.1,0.61,0.37,1.16,0.99,1.16C3.63,10.5,4.04,10.15,4.12,9.67z"/> + <path android:fillColor="@android:color/white" android:pathData="M18.6,3.28c-0.4-0.37-1.02-0.36-1.4,0.02c-0.4,0.4-0.38,1.04,0.03,1.42c1.38,1.27,2.35,3,2.65,4.94 c0.08,0.49,0.5,0.84,0.98,0.84c0.61,0,1.09-0.55,0.99-1.16C21.47,6.96,20.29,4.84,18.6,3.28z"/> + <path android:fillColor="@android:color/white" android:pathData="M12,22c1.1,0,2-0.9,2-2h-4C10,21.1,10.9,22,12,22z"/> + <path android:fillColor="@android:color/white" android:pathData="M18,16v-5c0-3.07-1.64-5.64-4.5-6.32V4c0-0.83-0.67-1.5-1.5-1.5S10.5,3.17,10.5,4v0.68C7.63,5.36,6,7.92,6,11v5 l-2.15,2.15c-0.19,0.2-0.19,0.51,0.01,0.71C3.95,18.95,4.07,19,4.2,19h15.6c0.45,0,0.67-0.54,0.35-0.85L18,16z"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_notifications_silence.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_notifications_silence.xml index 2cefe4b92b0e..c9a600e67edd 100644 --- a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_notifications_silence.xml +++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_notifications_silence.xml @@ -1,34 +1,22 @@ + <!-- -/** - * 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. - */ + 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="M20.73,19.46l-0.6-0.6L5.54,4.26A0.9 0.9 ,0,1,0,4.27,5.53l2.4,2.4A7.35,7.35,0,0,0,6,11v5L3.85,18.15a0.5 0.5 ,0,0,0,0,0.71A0.48 0.48 ,0,0,0,4.2,19H17.73l1.73,1.73a0.9 0.9 ,0,0,0,1.27,0A0.88 0.88 ,0,0,0,20.73,19.46Z" /> - <path - android:fillColor="#000000" - android:pathData="M12,2.5A1.5,1.5,0,0,0,10.5,4v0.68a5.62,5.62,0,0,0-1.7 0.72 L18,14.6V11c0-3.07-1.64-5.64-4.5-6.32V4A1.5,1.5,0,0,0,12,2.5Z" /> - <path - android:fillColor="#000000" - android:pathData="M14,20H10a2,2,0,0,0,4,0Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M12,22c1.1,0,2-0.9,2-2h-4C10,21.1,10.9,22,12,22z"/> + <path android:fillColor="@android:color/white" android:pathData="M18,11c0-3.07-1.64-5.64-4.5-6.32V4c0-0.83-0.67-1.5-1.5-1.5S10.5,3.17,10.5,4v0.68C9.72,4.86,9.04,5.2,8.46,5.63 L18,15.17V11z"/> + <path android:fillColor="@android:color/white" android:pathData="M20.49,20.49L3.52,3.52c-0.39-0.39-1.02-0.39-1.41,0c-0.39,0.39-0.39,1.02,0,1.41l4.14,4.14C6.09,9.68,6,10.33,6,11v5 l-2.15,2.15c-0.19,0.2-0.19,0.51,0.01,0.71C3.95,18.95,4.07,19,4.2,19h11.97l2.91,2.91c0.39,0.39,1.02,0.39,1.41,0 C20.88,21.52,20.88,20.88,20.49,20.49z"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_power_low.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_power_low.xml new file mode 100644 index 000000000000..3106029ee40e --- /dev/null +++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_power_low.xml @@ -0,0 +1,20 @@ + +<!-- + 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 android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M10,2v2H8.33C7.6,4,7,4.6,7,5.33v15.33C7,21.4,7.6,22,8.33,22h7.33C16.4,22,17,21.4,17,20.67V5.33C17,4.6,16.4,4,15.67,4 H14V2H10z M11,8.89c0-0.5,0.45-0.9,1-0.9s1,0.4,1,0.9V13c0,0.55-0.45,1-1,1s-1-0.45-1-1V8.89z M12,18.75 c-0.69,0-1.25-0.56-1.25-1.25s0.56-1.25,1.25-1.25s1.25,0.56,1.25,1.25S12.69,18.75,12,18.75z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_power_saver.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_power_saver.xml new file mode 100644 index 000000000000..e81a7bc29154 --- /dev/null +++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_power_saver.xml @@ -0,0 +1,20 @@ + +<!-- + 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 android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M10,2v2H8.33C7.6,4,7,4.6,7,5.33v15.33C7,21.4,7.6,22,8.33,22h7.33C16.4,22,17,21.4,17,20.67V5.33C17,4.6,16.4,4,15.67,4 H14V2H10z M15,13c0,0.55-0.45,1-1,1h-1v1c0,0.55-0.45,1-1,1s-1-0.45-1-1v-1h-1c-0.55,0-1-0.45-1-1s0.45-1,1-1h1v-1 c0-0.55,0.45-1,1-1s1,0.45,1,1v1h1C14.55,12,15,12.45,15,13z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_auto_rotate.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_auto_rotate.xml deleted file mode 100644 index f823812ddf3f..000000000000 --- a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_auto_rotate.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="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" /> -</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_bluetooth_connecting.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_bluetooth_connecting.xml index f64bd309e204..61b301cf02c9 100644 --- a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_bluetooth_connecting.xml +++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_bluetooth_connecting.xml @@ -1,34 +1,22 @@ + <!-- -/** - * 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. - */ + 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="M18.67,16.42A0.84 0.84 ,0,0,0,20,16.19a9.83,9.83,0,0,0,1-4.3,10,10,0,0,0-0.91-4.12 0.85 0.85,0,0,0-1.39-0.23 0.87 0.87,0,0,0-0.17,1,8.71,8.71,0,0,1,0,7A0.84 0.84 ,0,0,0,18.67,16.42Z" /> - <path - android:fillColor="#000000" - android:pathData="M3.48,18.56a1,1,0,0,0,1.47,0l4.05-4V21a1,1,0,0,0,1,1,1.07,1.07,0,0,0,0.71-0.27l0.05-0.05,4.46-4.46a1,1,0,0,0,0-1.48L11.51,12l3.75-3.73a1,1,0,0,0,0-1.48L10.79,2.32l0,0A1,1,0,0,0,9,3V9.49L5,5.43A1,1,0,0,0,3.48,6.9L8.57,12,3.48,17.09A1,1,0,0,0,3.48,18.56ZM11,5.38l2.15,2.15L11,9.68Zm0,8.94,2.15,2.15L11,18.62Z" /> - <path - android:fillColor="#000000" - android:pathData="M15,11.3a1,1,0,0,0,0,1.42l1.61,1.61A6.44,6.44,0,0,0,17,12a6.54,6.54,0,0,0-0.43-2.31Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M14.95,11.3c-0.39,0.39-0.39,1.03,0,1.42l1.61,1.61C16.84,13.61,17,12.82,17,12s-0.16-1.59-0.43-2.31L14.95,11.3z"/> + <path android:fillColor="@android:color/white" android:pathData="M11.51,12l3.75-3.73c0.41-0.41,0.41-1.07,0-1.48l-4.47-4.47l-0.03-0.03C10.57,2.11,10.32,2,10.04,2C9.47,2,9,2.47,9,3.04 v6.45L4.95,5.43c-0.41-0.41-1.06-0.41-1.47,0c-0.41,0.41-0.41,1.06,0,1.47L8.57,12l-5.09,5.09c-0.41,0.41-0.41,1.06,0,1.47 c0.41,0.41,1.06,0.41,1.47,0L9,14.51v6.45C9,21.53,9.47,22,10.04,22c0.28,0,0.53-0.11,0.71-0.27l0.05-0.05l4.46-4.46 c0.41-0.41,0.41-1.07,0-1.48L11.51,12z M10.99,5.38l2.15,2.15l-2.15,2.15V5.38z M10.99,18.62v-4.3l2.15,2.15L10.99,18.62z"/> + <path android:fillColor="@android:color/white" android:pathData="M20.08,7.77c-0.24-0.54-0.96-0.66-1.39-0.23c-0.26,0.26-0.32,0.65-0.17,0.98c0.47,1.07,0.72,2.24,0.72,3.47 c0,1.24-0.26,2.43-0.73,3.49c-0.14,0.32-0.09,0.69,0.16,0.94c0.4,0.4,1.09,0.29,1.34-0.23c0.63-1.3,0.98-2.76,0.98-4.3 C20.98,10.43,20.66,9.03,20.08,7.77z"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_bluetooth_on.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_bluetooth_on.xml index b014083c5e3a..dbae2e95e187 100644 --- a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_bluetooth_on.xml +++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_bluetooth_on.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.21,6.79l-4.5-4.5A1,1,0,0,0,11,3V9.59L7.2,5.78A1,1,0,0,0,5.79,7.2l4.8,4.8-4.8,4.8A1,1,0,0,0,7.2,18.22L11,14.41V21a1,1,0,0,0,0.62 0.92 A0.84 0.84 ,0,0,0,12,22a1,1,0,0,0,0.71-0.29l4.5-4.5a1,1,0,0,0,0-1.42L13.42,12l3.79-3.79A1,1,0,0,0,17.21,6.79ZM15.09,16.5,13,18.58V14.42ZM13,9.58V5.42L15.09,7.5Z" /> + android:fillColor="#FFFFFF" + 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_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_cancel.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_cancel.xml index 0403d818f758..fe0130e3b498 100644 --- a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_cancel.xml +++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_cancel.xml @@ -1,28 +1,20 @@ + <!-- -/** - * 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. - */ + 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,2A10,10,0,1,0,22,12,10,10,0,0,0,12,2Zm4.3,12.89a1,1,0,0,1,0,1.41,1,1,0,0,1-1.41,0h0L12,13.41,9.11,16.3A1,1,0,1,1,7.7,14.89L10.59,12,7.7,9.11A1,1,0,1,1,9.11,7.7L12,10.59,14.89,7.7A1,1,0,1,1,16.3,9.11L13.41,12Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M12,22c5.53,0,10-4.47,10-10S17.53,2,12,2S2,6.47,2,12S6.47,22,12,22z M7.7,9.11c-0.39-0.39-0.39-1.02,0-1.41 s1.02-0.39,1.41,0L12,10.59l2.89-2.89c0.39-0.39,1.02-0.39,1.41,0c0.39,0.39,0.39,1.02,0,1.41L13.41,12l2.89,2.89 c0.38,0.38,0.38,1.02,0,1.41c-0.39,0.39-1.02,0.39-1.41,0c0,0,0,0,0,0L12,13.41L9.11,16.3c-0.39,0.39-1.02,0.39-1.41,0 s-0.39-1.02,0-1.41L10.59,12L7.7,9.11z"/> </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_qs_no_sim.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_no_sim.xml index a488ee10a229..b753c55a2ed3 100644 --- a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_no_sim.xml +++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_no_sim.xml @@ -1,31 +1,21 @@ + <!-- -/** - * 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. - */ + 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="M17,3H10L7.66,5.34,19,16.68V5A2,2,0,0,0,17,3Z" /> - <path - android:fillColor="#000000" - android:pathData="M20.73,22.23a0.9 0.9 ,0,0,0,0-1.27L4.28,4.51A0.88 0.88 ,0,0,0,3,4.5H3A0.9 0.9 ,0,0,0,3,5.78l2,2V19a2,2,0,0,0,2,2H17a2,2,0,0,0,1-0.26l1.49,1.49A0.9 0.9 ,0,0,0,20.73,22.23Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M19,5c0-1.1-0.9-2-2-2h-7L7.91,5.09L19,16.17V5z"/> + <path android:fillColor="@android:color/white" android:pathData="M20.49,20.49L3.52,3.52c-0.39-0.39-1.02-0.39-1.41,0c-0.39,0.39-0.39,1.02,0,1.41l2.98,2.98L5,8v11c0,1.1,0.9,2,2,2h10 c0.34,0,0.65-0.09,0.93-0.24l1.15,1.15c0.39,0.39,1.02,0.39,1.41,0C20.88,21.52,20.88,20.88,20.49,20.49z"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_vpn.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_vpn.xml deleted file mode 100644 index ee2677d6b4bc..000000000000 --- a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_vpn.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="M21,10H12.65a6,6,0,1,0,0,4H16v2a2,2,0,0,0,4,0V14h1a2,2,0,0,0,0-4ZM7,14a2,2,0,1,1,2-2A2,2,0,0,1,7,14Z" /> -</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_wifi_0.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_wifi_0.xml index 395b2e2f3fc4..16c4fb557110 100644 --- a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_wifi_0.xml +++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_wifi_0.xml @@ -1,31 +1,21 @@ + <!-- -/** - * 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. - */ + 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="M23.43,6.57A20.54,20.54,0,0,0,12,3,20.55,20.55,0,0,0,0.56,6.57,1.07,1.07,0,0,0,0.33,8.11L11.16,21.6a1.07,1.07,0,0,0,1.66,0L14,20.13V12h6.54l3.12-3.89A1.06,1.06,0,0,0,23.43,6.57Z" /> - <path - android:fillColor="#000000" - android:pathData="M22.32,14.68a1,1,0,0,0-1.37,0l-1.44,1.44-1.45-1.45a1,1,0,0,0-1.37,0h0a1,1,0,0,0,0,1.37l1.45,1.45L16.68,19h0a1,1,0,0,0,0,1.37h0a1,1,0,0,0,1.37,0l1.45-1.45L21,20.32A1,1,0,0,0,22.32,19L20.87,17.5l1.45-1.45A1,1,0,0,0,22.32,14.68Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M23.43,6.57C21.66,5.36,17.55,3,12,3C6.44,3,2.33,5.36,0.56,6.57C0.05,6.92-0.05,7.63,0.33,8.11L11.16,21.6 c0.42,0.53,1.23,0.53,1.66,0L14,20.13V12h6.54l3.12-3.89C24.05,7.63,23.94,6.92,23.43,6.57z"/> + <path android:fillColor="@android:color/white" android:pathData="M22.32,14.68c-0.38-0.38-0.99-0.38-1.37,0l-1.44,1.44l-1.45-1.45c-0.38-0.38-0.99-0.38-1.37,0l-0.01,0.01c0,0,0,0,0,0 c-0.38,0.38-0.37,0.99,0,1.37l1.45,1.45l-1.45,1.45c0,0,0,0,0,0c-0.38,0.38-0.37,0.99,0,1.37l0.01,0.01 c0.38,0.38,0.99,0.38,1.37,0l1.45-1.45l1.44,1.44c0.38,0.38,0.99,0.38,1.37,0s0.38-0.99,0-1.37l-1.45-1.45l1.45-1.45 C22.7,15.67,22.7,15.06,22.32,14.68z"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_wifi_1.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_wifi_1.xml index f24bb24fcc90..6dae92744dd5 100644 --- a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_wifi_1.xml +++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_wifi_1.xml @@ -1,34 +1,21 @@ + <!-- -/** - * 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. - */ + 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:fillAlpha="0.3" - android:strokeAlpha="0.3" - android:strokeWidth="1" - android:pathData="M14,12h6.54l3.12-3.89a1.06,1.06,0,0,0-0.22-1.54A20.58,20.58,0,0,0,12,3,20.55,20.55,0,0,0,0.56,6.57,1.07,1.07,0,0,0,0.33,8.11L11.16,21.6a1.07,1.07,0,0,0,1.66,0L14,20.13Z" /> - <path - android:fillColor="#000000" - android:pathData="M22.71,15.67,20.88,17.5l1.83,1.83a1,1,0,0,1,0,1.38h0a1,1,0,0,1-1.38,0L19.5,18.88l-1.83,1.83a1,1,0,0,1-1.38,0h0a1,1,0,0,1,0-1.38l1.83-1.83-1.82-1.82a1,1,0,0,1,0-1.38h0a1,1,0,0,1,1.38,0L19.5,16.1l1.82-1.82a1,1,0,0,1,1.38,0h0A1,1,0,0,1,22.71,15.67Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillAlpha="0.3" android:fillColor="@android:color/white" android:pathData="M14,12h6.54l3.12-3.89c0.39-0.48,0.29-1.19-0.22-1.54C21.67,5.36,17.55,3,12,3C6.44,3,2.33,5.36,0.56,6.57 C0.05,6.92-0.05,7.63,0.33,8.11L11.16,21.6c0.42,0.53,1.23,0.53,1.66,0L14,20.13V12z" android:strokeAlpha="0.3" android:strokeWidth="1"/> + <path android:fillColor="@android:color/white" android:pathData="M22.71,15.67l-1.83,1.83l1.83,1.83c0.38,0.38,0.38,1,0,1.38l0,0c-0.38,0.38-1,0.39-1.38,0l-1.83-1.83l-1.83,1.83 c-0.38,0.38-1,0.38-1.38,0l-0.01-0.01c-0.38-0.38-0.38-1,0-1.38l1.83-1.83l-1.82-1.82c-0.38-0.38-0.38-1,0-1.38l0.01-0.01 c0.38-0.38,1-0.38,1.38,0l1.82,1.82l1.82-1.82c0.38-0.38,1-0.38,1.38,0l0,0C23.09,14.67,23.09,15.29,22.71,15.67z"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_wifi_2.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_wifi_2.xml index 4491abb53633..5f3d85cd4fb0 100644 --- a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_wifi_2.xml +++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_wifi_2.xml @@ -1,34 +1,21 @@ + <!-- -/** - * 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. - */ + 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:fillAlpha="0.3" - android:strokeAlpha="0.3" - android:strokeWidth="1" - android:pathData="M14,12h6.54l3.12-3.89a1.06,1.06,0,0,0-0.22-1.54A20.58,20.58,0,0,0,12,3,20.55,20.55,0,0,0,0.56,6.57,1.07,1.07,0,0,0,0.33,8.11L11.16,21.6a1.07,1.07,0,0,0,1.66,0L14,20.13Z" /> - <path - android:fillColor="#000000" - android:pathData="M14,20.13,12.82,21.6a1.07,1.07,0,0,1-1.66,0l-5.1-6.35A9,9,0,0,1,12,13a8.76,8.76,0,0,1,2,0.23Zm8.71-5.84h0a1,1,0,0,0-1.38,0l-1.82,1.82-1.82-1.82a1,1,0,0,0-1.38,0h0a1,1,0,0,0,0,1.38l1.82,1.82-1.83,1.83a1,1,0,0,0,0,1.38h0a1,1,0,0,0,1.38,0l1.83-1.83,1.83,1.83a1,1,0,0,0,1.38,0h0a1,1,0,0,0,0-1.38l-1.83-1.83,1.83-1.83A1,1,0,0,0,22.71,14.29Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillAlpha="0.3" android:fillColor="@android:color/white" android:pathData="M14,12h6.54l3.12-3.89c0.39-0.48,0.29-1.19-0.22-1.54C21.67,5.36,17.55,3,12,3C6.44,3,2.33,5.36,0.56,6.57 C0.05,6.92-0.05,7.63,0.33,8.11L11.16,21.6c0.42,0.53,1.23,0.53,1.66,0L14,20.13V12z" android:strokeAlpha="0.3" android:strokeWidth="1"/> + <path android:fillColor="@android:color/white" android:pathData="M14,20.13l-1.18,1.47c-0.43,0.53-1.23,0.53-1.66,0l-5.1-6.35C7.65,13.85,9.72,13,12,13c0.69,0,1.36,0.08,2,0.23V20.13z M22.71,14.29L22.71,14.29c-0.38-0.38-1-0.39-1.38,0l-1.82,1.82l-1.82-1.82c-0.38-0.38-1-0.38-1.38,0L16.3,14.3 c-0.38,0.38-0.38,1,0,1.38l1.82,1.82l-1.83,1.83c-0.38,0.38-0.38,1,0,1.38l0.01,0.01c0.38,0.38,1,0.38,1.38,0l1.83-1.83 l1.83,1.83c0.38,0.38,1,0.38,1.38,0l0,0c0.38-0.38,0.38-1,0-1.38l-1.83-1.83l1.83-1.83C23.09,15.29,23.09,14.67,22.71,14.29z"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_wifi_3.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_wifi_3.xml index cd4f78f5f9aa..11797cc4067d 100644 --- a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_wifi_3.xml +++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_wifi_3.xml @@ -1,34 +1,21 @@ + <!-- -/** - * 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. - */ + 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:fillAlpha="0.3" - android:strokeAlpha="0.3" - android:strokeWidth="1" - android:pathData="M14,12h6.54l3.12-3.89a1.06,1.06,0,0,0-0.22-1.54A20.58,20.58,0,0,0,12,3,20.55,20.55,0,0,0,0.56,6.57,1.07,1.07,0,0,0,0.33,8.11L11.16,21.6a1.07,1.07,0,0,0,1.66,0L14,20.13Z" /> - <path - android:fillColor="#000000" - android:pathData="M14,20.13,12.82,21.6a1.07,1.07,0,0,1-1.66,0l-7-8.7A12,12,0,0,1,18.62,12H14Zm8.71-5.84h0a1,1,0,0,0-1.38,0l-1.82,1.82-1.82-1.82a1,1,0,0,0-1.38,0h0a1,1,0,0,0,0,1.38l1.82,1.82-1.83,1.83a1,1,0,0,0,0,1.38h0a1,1,0,0,0,1.38,0l1.83-1.83,1.83,1.83a1,1,0,0,0,1.38,0h0a1,1,0,0,0,0-1.38l-1.83-1.83,1.83-1.83A1,1,0,0,0,22.71,14.29Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillAlpha="0.3" android:fillColor="@android:color/white" android:pathData="M14,12h6.54l3.12-3.89c0.39-0.48,0.29-1.19-0.22-1.54C21.67,5.36,17.55,3,12,3C6.44,3,2.33,5.36,0.56,6.57 C0.05,6.92-0.05,7.63,0.33,8.11L11.16,21.6c0.42,0.53,1.23,0.53,1.66,0L14,20.13V12z" android:strokeAlpha="0.3" android:strokeWidth="1"/> + <path android:fillColor="@android:color/white" android:pathData="M14,20.13l-1.18,1.47c-0.43,0.53-1.23,0.53-1.66,0l-6.98-8.7C6.28,11.1,9.01,10,12,10c2.45,0,4.72,0.74,6.62,2H14 V20.13z M22.71,14.29L22.71,14.29c-0.38-0.38-1-0.39-1.38,0l-1.82,1.82l-1.82-1.82c-0.38-0.38-1-0.38-1.38,0L16.3,14.3 c-0.38,0.38-0.38,1,0,1.38l1.82,1.82l-1.83,1.83c-0.38,0.38-0.38,1,0,1.38l0.01,0.01c0.38,0.38,1,0.38,1.38,0l1.83-1.83 l1.83,1.83c0.38,0.38,1,0.38,1.38,0l0,0c0.38-0.38,0.38-1,0-1.38l-1.83-1.83l1.83-1.83C23.09,15.29,23.09,14.67,22.71,14.29z"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_wifi_4.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_wifi_4.xml index 47ee8324ecba..9996002757a2 100644 --- a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_wifi_4.xml +++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_wifi_4.xml @@ -1,34 +1,21 @@ + <!-- -/** - * 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. - */ + 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:fillAlpha="0.3" - android:strokeAlpha="0.3" - android:strokeWidth="1" - android:pathData="M14,12h6.54l3.12-3.89a1.06,1.06,0,0,0-0.22-1.54A20.58,20.58,0,0,0,12,3,20.55,20.55,0,0,0,0.56,6.57,1.07,1.07,0,0,0,0.33,8.11L11.16,21.6a1.07,1.07,0,0,0,1.66,0L14,20.13Z" /> - <path - android:fillColor="#000000" - android:pathData="M14,20.13,12.82,21.6a1.07,1.07,0,0,1-1.66,0L2.93,11.35a14,14,0,0,1,18.14,0l-0.53 0.66 H14Zm8.71-5.84h0a1,1,0,0,0-1.38,0l-1.82,1.82-1.82-1.82a1,1,0,0,0-1.38,0h0a1,1,0,0,0,0,1.38l1.82,1.82-1.83,1.83a1,1,0,0,0,0,1.38h0a1,1,0,0,0,1.38,0l1.83-1.83,1.83,1.83a1,1,0,0,0,1.38,0h0a1,1,0,0,0,0-1.38l-1.83-1.83,1.83-1.83A1,1,0,0,0,22.71,14.29Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillAlpha="0.3" android:fillColor="@android:color/white" android:pathData="M14,12h6.54l3.12-3.89c0.39-0.48,0.29-1.19-0.22-1.54C21.67,5.36,17.55,3,12,3C6.44,3,2.33,5.36,0.56,6.57 C0.05,6.92-0.05,7.63,0.33,8.11L11.16,21.6c0.42,0.53,1.23,0.53,1.66,0L14,20.13V12z" android:strokeAlpha="0.3" android:strokeWidth="1"/> + <path android:fillColor="@android:color/white" android:pathData="M14,20.13l-1.18,1.47c-0.43,0.53-1.23,0.53-1.66,0L2.93,11.35C5.37,9.26,8.54,8,12,8s6.62,1.26,9.07,3.34L20.54,12H14 V20.13z M22.71,14.29L22.71,14.29c-0.38-0.38-1-0.39-1.38,0l-1.82,1.82l-1.82-1.82c-0.38-0.38-1-0.38-1.38,0L16.3,14.3 c-0.38,0.38-0.38,1,0,1.38l1.82,1.82l-1.83,1.83c-0.38,0.38-0.38,1,0,1.38l0.01,0.01c0.38,0.38,1,0.38,1.38,0l1.83-1.83 l1.83,1.83c0.38,0.38,1,0.38,1.38,0l0,0c0.38-0.38,0.38-1,0-1.38l-1.83-1.83l1.83-1.83C23.09,15.29,23.09,14.67,22.71,14.29z"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_wifi_disconnected.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_wifi_disconnected.xml index 8bef29c5d69f..906e53a23914 100644 --- a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_wifi_disconnected.xml +++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_wifi_disconnected.xml @@ -1,34 +1,22 @@ + <!-- -/** - * 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. - */ + 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="M14.61,13a5,5,0,0,1,5-5A4.93,4.93,0,0,1,22.8,9.18l0.86-1.07a1.06,1.06,0,0,0-0.22-1.54A20.58,20.58,0,0,0,12,3,20.55,20.55,0,0,0,0.56,6.57,1.07,1.07,0,0,0,0.33,8.11L11.16,21.6a1.07,1.07,0,0,0,1.66,0l3.74-4.66A5,5,0,0,1,14.61,13Z" /> - <path - android:fillColor="#000000" - android:pathData="M20,22a1.1,1.1,0,1,0-1.1-1.1A1.1,1.1,0,0,0,20,22Z" /> - <path - android:fillColor="#000000" - android:pathData="M22.69,15.48a2.79,2.79,0,0,0,0.82-2,3.51,3.51,0,0,0-6.82-1.15 0.86 0.86,0,0,0,0.81,1.14 0.89 0.89,0,0,0,0.84-0.55,1.75,1.75,0,0,1,3.41 0.55 ,1.79,1.79,0,0,1-0.51,1.24l-1.09,1.1a3.21,3.21,0,0,0-1,2.12s0,0.05,0,0.08A0.89 0.89 ,0,0,0,20,19a0.87 0.87 ,0,0,0,0.87-0.77,2.85,2.85,0,0,1,1-1.95Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M20,8h3.72c0.3-0.47,0.2-1.1-0.28-1.43C21.67,5.36,17.55,3,12,3C6.44,3,2.33,5.36,0.56,6.57 C0.05,6.92-0.05,7.63,0.33,8.11L11.16,21.6c0.42,0.53,1.23,0.53,1.66,0l1.68-2.09V13.5C14.5,10.46,16.96,8,20,8z"/> + <path android:fillColor="@android:color/white" android:pathData="M20,10c-1.53,0-2.84,0.99-3.31,2.36c-0.19,0.56,0.23,1.14,0.81,1.14c0.36,0,0.72-0.21,0.84-0.55 c0.23-0.7,0.89-1.2,1.66-1.2c0.97,0,1.75,0.78,1.75,1.75c0,0.48-0.2,0.92-0.51,1.24l-1.09,1.1c-0.69,0.69-0.92,1.38-0.99,2.2 C19.12,18.55,19.52,19,20.04,19c0.44,0,0.83-0.33,0.87-0.77c0.07-0.79,0.31-1.27,1-1.95l0.78-0.8c0.5-0.5,0.82-1.2,0.82-1.97 C23.5,11.57,21.93,10,20,10z"/> + <path android:fillColor="@android:color/white" android:pathData="M20,19.86c-0.33,0-0.63,0.15-0.83,0.39c-0.18,0.2-0.29,0.45-0.29,0.74c0,0.62,0.5,1.12,1.12,1.12s1.12-0.5,1.12-1.12 c0-0.29-0.12-0.54-0.29-0.74C20.63,20.02,20.33,19.86,20,19.86z"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_screenshot_delete.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_screenshot_delete.xml index 447d848755cf..c59fb59fa1b6 100644 --- a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_screenshot_delete.xml +++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_screenshot_delete.xml @@ -1,31 +1,21 @@ + <!-- -/** - * 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. - */ + 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="M18,4H15.5l-0.71-0.71a1,1,0,0,0-0.7-0.29H9.9a1,1,0,0,0-0.7 0.29 L8.49,4H6A1,1,0,0,0,6,6H18a1,1,0,0,0,1-1A1,1,0,0,0,18,4Z" /> - <path - android:fillColor="#000000" - android:pathData="M18,19V7H6V19a2,2,0,0,0,2,2h8A2,2,0,0,0,18,19Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M18,4h-2.5l-0.71-0.71C14.61,3.11,14.35,3,14.09,3H9.9C9.64,3,9.38,3.11,9.2,3.29L8.49,4h-2.5c-0.55,0-1,0.45-1,1 s0.45,1,1,1h12c0.55,0,1-0.45,1-1C19,4.45,18.55,4,18,4z"/> + <path android:fillColor="@android:color/white" android:pathData="M6,19c0,1.1,0.9,2,2,2h8c1.1,0,2-0.9,2-2V7H6V19z"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_settings.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_settings.xml new file mode 100644 index 000000000000..938b53359186 --- /dev/null +++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_settings.xml @@ -0,0 +1,20 @@ + +<!-- + 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 android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M21.64,8.39l-1.6-2.76c-0.28-0.48-0.88-0.7-1.36-0.5l-2.14,0.91c-0.48-0.37-1.01-0.68-1.57-0.92l-0.27-2.2 C14.64,2.4,14.14,2,13.59,2h-3.18C9.86,2,9.36,2.4,9.3,2.92L9.04,5.11c-0.57,0.24-1.1,0.55-1.58,0.92L5.32,5.12 c-0.48-0.2-1.08,0.02-1.36,0.5l-1.6,2.76C2.08,8.86,2.18,9.48,2.6,9.8l1.94,1.45C4.51,11.49,4.5,11.74,4.5,12s0.01,0.51,0.04,0.76 L2.6,14.2c-0.42,0.31-0.52,0.94-0.24,1.41l1.6,2.76c0.28,0.48,0.88,0.7,1.36,0.5l2.14-0.91c0.48,0.37,1.01,0.68,1.57,0.92 l0.27,2.19C9.36,21.6,9.86,22,10.41,22h3.18c0.55,0,1.04-0.4,1.11-0.92l0.27-2.19c0.56-0.24,1.09-0.55,1.57-0.92l2.14,0.91 c0.48,0.2,1.08-0.02,1.36-0.5l1.6-2.76c0.28-0.48,0.18-1.1-0.24-1.42l-1.94-1.45c0.03-0.25,0.04-0.5,0.04-0.76 s-0.01-0.51-0.04-0.76L21.4,9.8C21.82,9.49,21.92,8.86,21.64,8.39z M12,15.5c-1.93,0-3.5-1.57-3.5-3.5s1.57-3.5,3.5-3.5 s3.5,1.57,3.5,3.5S13.93,15.5,12,15.5z"/> +</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 index d292b13c8faf..2a93a69e0ea9 100644 --- a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_settings_16dp.xml +++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_settings_16dp.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="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> + android:fillColor="#FFFFFF" + android:pathData="M21.64,8.39l-1.6-2.76c-0.28-0.48-0.88-0.7-1.36-0.5l-2.14,0.91c-0.48-0.37-1.01-0.68-1.57-0.92l-0.27-2.2 C14.64,2.4,14.14,2,13.59,2h-3.18C9.86,2,9.36,2.4,9.3,2.92L9.04,5.11c-0.57,0.24-1.1,0.55-1.58,0.92L5.32,5.12 c-0.48-0.2-1.08,0.02-1.36,0.5l-1.6,2.76C2.08,8.86,2.18,9.48,2.6,9.8l1.94,1.45C4.51,11.49,4.5,11.74,4.5,12s0.01,0.51,0.04,0.76 L2.6,14.2c-0.42,0.31-0.52,0.94-0.24,1.41l1.6,2.76c0.28,0.48,0.88,0.7,1.36,0.5l2.14-0.91c0.48,0.37,1.01,0.68,1.57,0.92 l0.27,2.19C9.36,21.6,9.86,22,10.41,22h3.18c0.55,0,1.04-0.4,1.11-0.92l0.27-2.19c0.56-0.24,1.09-0.55,1.57-0.92l2.14,0.91 c0.48,0.2,1.08-0.02,1.36-0.5l1.6-2.76c0.28-0.48,0.18-1.1-0.24-1.42l-1.94-1.45c0.03-0.25,0.04-0.5,0.04-0.76 s-0.01-0.51-0.04-0.76L21.4,9.8C21.82,9.49,21.92,8.86,21.64,8.39z M12,15.5c-1.93,0-3.5-1.57-3.5-3.5s1.57-3.5,3.5-3.5 s3.5,1.57,3.5,3.5S13.93,15.5,12,15.5z" /> +</vector>
\ No newline at end of file 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/IconPackFilledSystemUIOverlay/res/drawable/ic_signal_flashlight.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_signal_flashlight.xml deleted file mode 100644 index 1ffb32b90144..000000000000 --- a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_signal_flashlight.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,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" /> -</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_swap_vert.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_swap_vert.xml index 43a01c63dbdc..d1a402301ad0 100644 --- a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_swap_vert.xml +++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_swap_vert.xml @@ -1,31 +1,21 @@ + <!-- -/** - * 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. - */ + 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="M18,17H16V11a1,1,0,0,0-2,0v6H12a0.53 0.53 ,0,0,0-0.37 0.9 l2.95,2.94a0.53 0.53 ,0,0,0,0.75,0l3-2.94A0.52 0.52 ,0,0,0,18,17Z" /> - <path - android:fillColor="#000000" - android:pathData="M12.32,6.09l-3-2.95a0.52 0.52 ,0,0,0-0.74,0h0L5.68,6.09a0.53 0.53 ,0,0,0,0.37 0.9 H8v6a1,1,0,0,0,2,0V7H12A0.52 0.52 ,0,0,0,12.32,6.09Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M17.95,17.01H16V11c0-0.55-0.45-1-1-1s-1,0.45-1,1v6.01h-1.96c-0.47,0-0.7,0.57-0.37,0.9l2.95,2.94 c0.21,0.21,0.54,0.21,0.75,0l2.95-2.94C18.66,17.58,18.42,17.01,17.95,17.01z"/> + <path android:fillColor="@android:color/white" android:pathData="M12.32,6.09L9.37,3.14c-0.2-0.21-0.54-0.21-0.74-0.01c0,0-0.01,0.01-0.01,0.01L5.68,6.09c-0.33,0.33-0.1,0.9,0.37,0.9H8 V13c0,0.55,0.45,1,1,1s1-0.45,1-1V6.99h1.95C12.42,6.99,12.66,6.42,12.32,6.09z"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_tune_black_16dp.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_tune_black_16dp.xml new file mode 100644 index 000000000000..cd4e7f43436b --- /dev/null +++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_tune_black_16dp.xml @@ -0,0 +1,25 @@ + +<!-- + 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 android:height="16dp" android:viewportHeight="24" android:viewportWidth="24" android:width="16dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M8,9c-0.55,0-1,0.45-1,1v1H4c-0.55,0-1,0.45-1,1c0,0.55,0.45,1,1,1h3v1c0,0.55,0.45,1,1,1s1-0.45,1-1v-4 C9,9.45,8.55,9,8,9z"/> + <path android:fillColor="@android:color/white" android:pathData="M20,5h-3V4c0-0.55-0.45-1-1-1s-1,0.45-1,1v4c0,0.55,0.45,1,1,1s1-0.45,1-1V7h3c0.55,0,1-0.45,1-1C21,5.45,20.55,5,20,5z"/> + <path android:fillColor="@android:color/white" android:pathData="M20,11h-9v2h9c0.55,0,1-0.45,1-1C21,11.45,20.55,11,20,11z"/> + <path android:fillColor="@android:color/white" android:pathData="M20,17h-7v-1c0-0.55-0.45-1-1-1s-1,0.45-1,1v4c0,0.55,0.45,1,1,1s1-0.45,1-1v-1h7c0.55,0,1-0.45,1-1S20.55,17,20,17z"/> + <path android:fillColor="@android:color/white" android:pathData="M4,7h9V5H4C3.45,5,3,5.45,3,6C3,6.55,3.45,7,4,7z"/> + <path android:fillColor="@android:color/white" android:pathData="M3,18c0,0.55,0.45,1,1,1h5v-2H4C3.45,17,3,17.45,3,18z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_volume_alarm.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_volume_alarm.xml index c300bed51aea..f282ddc0caee 100644 --- a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_volume_alarm.xml +++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_volume_alarm.xml @@ -21,14 +21,12 @@ android:viewportHeight="24"> <path - android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" /> + android:fillColor="#FFFFFF" + android:pathData="M4.1,6.6l3-2.6c0.4-0.3,0.5-1,0.1-1.4c-0.4-0.4-1-0.5-1.4-0.1l-3,2.6c-0.4,0.4-0.5,1-0.1,1.4C3,6.9,3.6,7,4.1,6.6z" /> <path - android:fillColor="#000000" - android:pathData="M16.8,2.6A1,1,0,0,0,16.9,4L20,6.6a1,1,0,0,0,1.4-0.1,1,1,0,0,0-0.1-1.4L18.2,2.5A1,1,0,0,0,16.8,2.6Z" /> + android:fillColor="#FFFFFF" + android:pathData="M12,4c-5,0-9,4-9,9s4,9,9,9s9-4,9-9S17,4,12,4z M16.12,16.24c-0.21,0.34-0.64,0.45-0.98,0.24L11,14V8.75 C11,8.34,11.34,8,11.75,8s0.75,0.34,0.75,0.75v4.5l3.37,2C16.21,15.45,16.33,15.9,16.12,16.24z" /> <path - android:fillColor="#000000" - android:pathData="M4.1,6.6,7.1,4A1,1,0,1,0,5.8,2.5l-3,2.6a1,1,0,0,0-0.1,1.4A1,1,0,0,0,4.1,6.6Z" /> - <path - android:fillColor="#000000" - android:pathData="M3,13a9,9,0,1,0,9-9A9,9,0,0,0,3,13Zm8-4.25a0.75 0.75 ,0,0,1,1.5,0v4.5l3.37,2a0.72 0.72 ,0,0,1,0.25,1,0.71 0.71 ,0,0,1-1,0.24L11,14Z" /> + android:fillColor="#FFFFFF" + android:pathData="M21.3,5.1l-3.1-2.6c-0.4-0.4-0.99-0.31-1.4,0.1c-0.4,0.4-0.3,1,0.1,1.4L20,6.6c0.41,0.37,1,0.3,1.4-0.1 C21.73,6.12,21.7,5.4,21.3,5.1z" /> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_volume_alarm_mute.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_volume_alarm_mute.xml new file mode 100644 index 000000000000..1a9835042257 --- /dev/null +++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_volume_alarm_mute.xml @@ -0,0 +1,23 @@ + +<!-- + 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 android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M12,4c-1.5,0-2.91,0.37-4.15,1.02l12.13,12.13C20.63,15.91,21,14.5,21,13C21,8.03,16.97,4,12,4z"/> + <path android:fillColor="@android:color/white" android:pathData="M7.1,4c0.4-0.3,0.5-1,0.1-1.4c-0.4-0.4-1-0.5-1.4-0.1L5.55,2.72l1.41,1.41L7.1,4z"/> + <path android:fillColor="@android:color/white" android:pathData="M21.3,5.1l-3.1-2.6c-0.4-0.4-0.99-0.31-1.4,0.1c-0.4,0.4-0.3,1,0.1,1.4L20,6.6c0.41,0.37,1,0.3,1.4-0.1 C21.73,6.12,21.7,5.4,21.3,5.1z"/> + <path android:fillColor="@android:color/white" android:pathData="M3.52,3.52c-0.39-0.39-1.02-0.39-1.41,0c-0.39,0.39-0.39,1.02,0,1.41l0.47,0.47C2.38,5.77,2.39,6.19,2.7,6.5 c0.26,0.34,0.74,0.44,1.19,0.22l0.91,0.91C3.67,9.13,3,10.98,3,13c0,4.97,4.03,9,9,9c2.02,0,3.87-0.67,5.38-1.79l1.7,1.7 c0.39,0.39,1.02,0.39,1.41,0c0.39-0.39,0.39-1.02,0-1.41L3.52,3.52z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_volume_ringer_vibrate.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_volume_ringer_vibrate.xml new file mode 100644 index 000000000000..1f925d554241 --- /dev/null +++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_volume_ringer_vibrate.xml @@ -0,0 +1,24 @@ + +<!-- + 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 android:height="19dp" android:viewportHeight="24" android:viewportWidth="24" android:width="19dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M19,7c-0.55,0-1,0.45-1,1v8c0,0.55,0.45,1,1,1s1-0.45,1-1V8C20,7.45,19.55,7,19,7z"/> + <path android:fillColor="@android:color/white" android:pathData="M5,7C4.45,7,4,7.45,4,8v8c0,0.55,0.45,1,1,1s1-0.45,1-1V8C6,7.45,5.55,7,5,7z"/> + <path android:fillColor="@android:color/white" android:pathData="M22,9c-0.55,0-1,0.45-1,1v4c0,0.55,0.45,1,1,1s1-0.45,1-1v-4C23,9.45,22.55,9,22,9z"/> + <path android:fillColor="@android:color/white" android:pathData="M16,4H8C7.45,4,7,4.45,7,5v14c0,0.55,0.45,1,1,1h8c0.55,0,1-0.45,1-1V5C17,4.45,16.55,4,16,4z"/> + <path android:fillColor="@android:color/white" android:pathData="M2,9c-0.55,0-1,0.45-1,1v4c0,0.55,0.45,1,1,1s1-0.45,1-1v-4C3,9.45,2.55,9,2,9z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/stat_sys_camera.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/stat_sys_camera.xml new file mode 100644 index 000000000000..9bfbe1c27659 --- /dev/null +++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/stat_sys_camera.xml @@ -0,0 +1,21 @@ + +<!-- + 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 android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M 12 8.8 C 13.7673111995 8.8 15.2 10.2326888005 15.2 12 C 15.2 13.7673111995 13.7673111995 15.2 12 15.2 C 10.2326888005 15.2 8.8 13.7673111995 8.8 12 C 8.8 10.2326888005 10.2326888005 8.8 12 8.8 Z"/> + <path android:fillColor="@android:color/white" android:pathData="M20,4h-3.17L15,2H9L7.17,4H4C2.9,4,2,4.9,2,6v12c0,1.1,0.9,2,2,2h16c1.1,0,2-0.9,2-2V6C22,4.9,21.1,4,20,4z M12,17 c-2.76,0-5-2.24-5-5s2.24-5,5-5s5,2.24,5,5S14.76,17,12,17z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/stat_sys_mic_none.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/stat_sys_mic_none.xml new file mode 100644 index 000000000000..d7f78117d794 --- /dev/null +++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/stat_sys_mic_none.xml @@ -0,0 +1,21 @@ + +<!-- + 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 android:height="18dp" android:viewportHeight="24" android:viewportWidth="24" android:width="18dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M12,14c1.66,0,3-1.34,3-3V5c0-1.66-1.34-3-3-3S9,3.34,9,5v6C9,12.66,10.34,14,12,14z"/> + <path android:fillColor="@android:color/white" android:pathData="M6.09,11L6.09,11c-0.61,0-1.09,0.54-1,1.14c0.49,3,2.89,5.34,5.91,5.78V20c0,0.55,0.45,1,1,1s1-0.45,1-1v-2.08 c3.02-0.44,5.42-2.78,5.91-5.78c0.1-0.6-0.39-1.14-1-1.14h0c-0.49,0-0.9,0.36-0.98,0.85C16.52,14.21,14.47,16,12,16 s-4.52-1.79-4.93-4.15C6.99,11.36,6.58,11,6.09,11z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/stat_sys_vpn_ic.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/stat_sys_vpn_ic.xml new file mode 100644 index 000000000000..90ef49047f47 --- /dev/null +++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/stat_sys_vpn_ic.xml @@ -0,0 +1,20 @@ + +<!-- + 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 android:height="17dp" android:viewportHeight="24" android:viewportWidth="24" android:width="17dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M21,10h-8.35C11.7,7.31,8.9,5.5,5.78,6.12C3.49,6.58,1.62,8.41,1.14,10.7C0.32,14.57,3.26,18,7,18c2.61,0,4.83-1.67,5.65-4 H16v2c0,1.1,0.9,2,2,2s2-0.9,2-2v-2h1c1.1,0,2-0.9,2-2C23,10.9,22.1,10,21,10z M7,14c-1.1,0-2-0.9-2-2c0-1.1,0.9-2,2-2s2,0.9,2,2 C9,13.1,8.1,14,7,14z"/> +</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..53cbd3cba010 --- /dev/null +++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_bluetooth_share_icon.xml @@ -0,0 +1,20 @@ + +<!-- + 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 android:height="24dp" android:tint="@*android:color/accent_device_default" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <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_bt_headphones_a2dp.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_bt_headphones_a2dp.xml index 264e2122aa50..0e80234a92c5 100644 --- a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_bt_headphones_a2dp.xml +++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_bt_headphones_a2dp.xml @@ -1,28 +1,20 @@ + <!-- -/** - * 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. - */ + 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="M21.5,18V11.5C21.5,5.82,17.68,2,12,2S2.5,5.82,2.5,11.5V18a3,3,0,0,0,3,3H7a1.5,1.5,0,0,0,1.5-1.5V14A1.5,1.5,0,0,0,7,12.5H4v-1c0-4.86,3.14-8,8-8s8,3.14,8,8v1H17A1.5,1.5,0,0,0,15.5,14v5.5A1.5,1.5,0,0,0,17,21h1.5A3,3,0,0,0,21.5,18ZM7,19.5H5.5A1.5,1.5,0,0,1,4,18V14H7ZM20,18a1.5,1.5,0,0,1-1.5,1.5H17V14h3Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M14.75,2.01h-5.5c-3.72,0-6.75,3.03-6.75,6.75v3.74v1V18c0,1.66,1.34,3,3,3H7c0.83,0,1.5-0.67,1.5-1.5V14 c0-0.83-0.67-1.5-1.5-1.5H4V8.76c0-2.9,2.36-5.25,5.25-5.25h5.5c2.89,0,5.25,2.35,5.25,5.25v3.74h-3c-0.83,0-1.5,0.67-1.5,1.5v5.5 c0,0.83,0.67,1.5,1.5,1.5h1.5c1.66,0,3-1.34,3-3v-4.5v-1V8.76C21.5,5.04,18.47,2.01,14.75,2.01z M7,19.5H5.5 C4.67,19.5,4,18.83,4,18v-4h3V19.5z M20,18c0,0.83-0.67,1.5-1.5,1.5H17V14h3V18z"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_expand_more.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_expand_more.xml index 407adacec5d1..ba7a9fd6a36d 100644 --- a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_expand_more.xml +++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_expand_more.xml @@ -1,28 +1,20 @@ + <!-- -/** - * 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. - */ + 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="M18.54,8.48a0.75 0.75 ,0,0,0-1.06,0L12,13.82,6.52,8.46a0.75 0.75 ,0,0,0-1.06,0,0.75 0.75 ,0,0,0,0,1.06l5.74,5.62a1.11,1.11,0,0,0,0.78 0.36 ,1.09,1.09,0,0,0,0.77-0.36l5.75-5.62A0.75 0.75 ,0,0,0,18.54,8.48Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M18.79,8.23c-0.29-0.3-0.76-0.3-1.06-0.01L12,13.82L6.27,8.21C5.98,7.92,5.5,7.93,5.21,8.23C4.92,8.52,4.93,9,5.23,9.29 l6,5.87c0.24,0.24,0.51,0.37,0.78,0.37c0.27,0,0.53-0.12,0.77-0.36l6-5.88C19.07,9,19.08,8.52,18.79,8.23z"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_faster_emergency.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_faster_emergency.xml new file mode 100644 index 000000000000..713fda8a7dad --- /dev/null +++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_faster_emergency.xml @@ -0,0 +1,21 @@ + +<!-- + 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 android:height="24dp" android:tint="?android:attr/colorError" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M19.5,4.5v15h-15v-15H19.5 M19.5,3h-15C3.67,3,3,3.67,3,4.5v15C3,20.33,3.67,21,4.5,21h15c0.83,0,1.5-0.67,1.5-1.5v-15 C21,3.67,20.33,3,19.5,3L19.5,3z"/> + <path android:fillColor="@android:color/white" android:pathData="M16.6,10.75h-3.35V7.4c0-0.22-0.18-0.4-0.4-0.4h-1.7c-0.22,0-0.4,0.18-0.4,0.4v3.35H7.4c-0.22,0-0.4,0.18-0.4,0.4v1.7 c0,0.22,0.18,0.4,0.4,0.4h3.35v3.35c0,0.22,0.18,0.4,0.4,0.4h1.7c0.22,0,0.4-0.18,0.4-0.4v-3.35h3.35c0.22,0,0.4-0.18,0.4-0.4v-1.7 C17,10.93,16.82,10.75,16.6,10.75z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_info_outline_24.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_info_outline_24.xml index 642ac421fe99..00a95234eb51 100644 --- a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_info_outline_24.xml +++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_info_outline_24.xml @@ -1,34 +1,22 @@ + <!-- -/** - * 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. - */ + 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="M19.07,4.93A10,10,0,1,0,22,12,10,10,0,0,0,19.07,4.93ZM18,18a8.5,8.5,0,1,1,2.5-6A8.53,8.53,0,0,1,18,18Z" /> - <path - android:fillColor="#000000" - android:pathData="M12,10a0.76 0.76 ,0,0,0-0.75 0.75 v5.5a0.75 0.75 ,0,0,0,1.5,0v-5.5A0.76 0.76 ,0,0,0,12,10Z" /> - <path - android:fillColor="#000000" - android:pathData="M 12 7 C 12.5522847498 7 13 7.44771525017 13 8 C 13 8.55228474983 12.5522847498 9 12 9 C 11.4477152502 9 11 8.55228474983 11 8 C 11 7.44771525017 11.4477152502 7 12 7 Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M4.92,4.94c-3.9,3.91-3.9,10.24,0.01,14.14s10.24,3.9,14.14-0.01C20.95,17.2,22,14.65,22,12c0-2.65-1.06-5.19-2.93-7.07 C15.16,1.03,8.83,1.03,4.92,4.94z M18,18c-1.6,1.59-3.76,2.48-6.02,2.48c-4.69-0.01-8.49-3.83-8.48-8.52 c0.01-4.69,3.83-8.49,8.52-8.48c4.69,0.01,8.49,3.83,8.48,8.52C20.49,14.25,19.6,16.41,18,18z"/> + <path android:fillColor="@android:color/white" android:pathData="M 12 7 C 12.5522847498 7 13 7.44771525017 13 8 C 13 8.55228474983 12.5522847498 9 12 9 C 11.4477152502 9 11 8.55228474983 11 8 C 11 7.44771525017 11.4477152502 7 12 7 Z"/> + <path android:fillColor="@android:color/white" android:pathData="M12,10.5c-0.41,0-0.75,0.34-0.75,0.75v5c0,0.41,0.34,0.75,0.75,0.75s0.75-0.34,0.75-0.75v-5 C12.75,10.84,12.41,10.5,12,10.5z"/> </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_lock.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_lock.xml new file mode 100644 index 000000000000..2161d8813ec5 --- /dev/null +++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_lock.xml @@ -0,0 +1,21 @@ + +<!-- + 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 android:height="32dp" android:tint="?android:attr/textColor" android:viewportHeight="24" android:viewportWidth="24" android:width="32dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M18.5,8.5H16V5.12c-0.04-2.05-1.82-3.73-3.99-3.67C9.82,1.4,8.04,3.07,8,5.14V8.5H5.5C4.67,8.5,4,9.17,4,10v10 c0,0.83,0.67,1.5,1.5,1.5h13c0.83,0,1.5-0.67,1.5-1.5V10C20,9.17,19.33,8.5,18.5,8.5z M9.5,5.15c0.02-1.23,1.13-2.23,2.51-2.19 c1.36-0.04,2.47,0.96,2.49,2.18V8.5h-5V5.15z M18.5,20h-13V10h13V20z"/> + <path android:fillColor="@android:color/white" android:pathData="M 12 13.5 C 12.8284271247 13.5 13.5 14.1715728753 13.5 15 C 13.5 15.8284271247 12.8284271247 16.5 12 16.5 C 11.1715728753 16.5 10.5 15.8284271247 10.5 15 C 10.5 14.1715728753 11.1715728753 13.5 12 13.5 Z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_lock_bugreport.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_lock_bugreport.xml new file mode 100644 index 000000000000..919046ee7b0b --- /dev/null +++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_lock_bugreport.xml @@ -0,0 +1,22 @@ + +<!-- + 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 android:height="24dp" android:tint="?android:attr/colorControlNormal" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M18,13.5h1.26c0.41,0,0.75-0.34,0.75-0.75S19.67,12,19.26,12H18v-1c0-0.52-0.07-1.02-0.2-1.5h1.46 c0.41,0,0.75-0.34,0.75-0.75S19.67,8,19.26,8h-2.07c-0.5-0.86-1.2-1.58-2.03-2.1l1.37-1.37c0.29-0.29,0.29-0.77,0-1.06 c-0.29-0.29-0.77-0.29-1.06,0l-1.78,1.78C13.16,5.09,12.59,5,12,5s-1.16,0.09-1.69,0.25L8.53,3.47c-0.29-0.29-0.77-0.29-1.06,0 s-0.29,0.77,0,1.06L8.84,5.9C8,6.42,7.3,7.14,6.81,8H4.74C4.33,8,3.99,8.34,3.99,8.75S4.33,9.5,4.74,9.5H6.2 C6.07,9.98,6,10.48,6,11v1H4.74c-0.41,0-0.75,0.34-0.75,0.75s0.34,0.75,0.75,0.75H6V15c0,0.34,0.04,0.67,0.09,1H4.74 c-0.41,0-0.75,0.34-0.75,0.75s0.34,0.75,0.75,0.75h1.81C7.5,19.56,9.58,21,12,21s4.5-1.44,5.45-3.5h1.81 c0.41,0,0.75-0.34,0.75-0.75S19.67,16,19.26,16h-1.35c0.05-0.33,0.09-0.66,0.09-1V13.5z M16.5,15c0,2.48-2.02,4.5-4.5,4.5 S7.5,17.48,7.5,15v-4c0-2.48,2.02-4.5,4.5-4.5s4.5,2.02,4.5,4.5V15z"/> + <path android:fillColor="@android:color/white" android:pathData="M13.25,14h-2.5C10.34,14,10,14.34,10,14.75s0.34,0.75,0.75,0.75h2.5c0.41,0,0.75-0.34,0.75-0.75S13.66,14,13.25,14z"/> + <path android:fillColor="@android:color/white" android:pathData="M13.25,10.5h-2.5c-0.41,0-0.75,0.34-0.75,0.75S10.34,12,10.75,12h2.5c0.41,0,0.75-0.34,0.75-0.75S13.66,10.5,13.25,10.5z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_lock_open.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_lock_open.xml new file mode 100644 index 000000000000..719e63f2d5c6 --- /dev/null +++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_lock_open.xml @@ -0,0 +1,21 @@ + +<!-- + 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 android:height="32dp" android:tint="?android:attr/textColor" android:viewportHeight="24" android:viewportWidth="24" android:width="32dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M 12 13.5 C 12.8284271247 13.5 13.5 14.1715728753 13.5 15 C 13.5 15.8284271247 12.8284271247 16.5 12 16.5 C 11.1715728753 16.5 10.5 15.8284271247 10.5 15 C 10.5 14.1715728753 11.1715728753 13.5 12 13.5 Z"/> + <path android:fillColor="@android:color/white" android:pathData="M18.51,1.46c-2.19-0.06-3.98,1.61-4.01,3.68V8.5h-9C4.67,8.5,4,9.17,4,10v10c0,0.83,0.67,1.5,1.5,1.5h13 c0.83,0,1.5-0.67,1.5-1.5V10c0-0.83-0.67-1.5-1.5-1.5H16V5.15c0.02-1.23,1.14-2.23,2.51-2.19C19.9,2.93,20.98,3.92,21,5.15 c0.01,0.41,0.36,0.71,0.76,0.74c0.41-0.01,0.74-0.35,0.74-0.76C22.46,3.07,20.7,1.39,18.51,1.46z M18.5,10v10h-13V10H18.5z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_lock_power_off.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_lock_power_off.xml new file mode 100644 index 000000000000..d0e21a1cbcc4 --- /dev/null +++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_lock_power_off.xml @@ -0,0 +1,21 @@ + +<!-- + 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 android:height="24dp" android:tint="?android:attr/colorControlNormal" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M12,13c-0.41,0-0.75-0.34-0.75-0.75v-9.5C11.25,2.33,11.59,2,12,2s0.75,0.34,0.75,0.75v9.5C12.75,12.66,12.41,13,12,13z"/> + <path android:fillColor="@android:color/white" android:pathData="M12,21c-4.96,0-9-4.02-9-8.96c0-2.5,1.06-4.9,2.91-6.6c0.31-0.28,0.78-0.26,1.06,0.05C7.25,5.8,7.23,6.27,6.92,6.55 C5.38,7.96,4.5,9.96,4.5,12.04c0,4.11,3.36,7.46,7.5,7.46s7.5-3.34,7.5-7.46c0-2.08-0.88-4.08-2.42-5.49 c-0.3-0.28-0.33-0.75-0.05-1.06c0.28-0.3,0.75-0.33,1.06-0.05c1.85,1.69,2.91,4.1,2.91,6.6C21,16.98,16.96,21,12,21z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_lockscreen_ime.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_lockscreen_ime.xml index 7897fa3a40a9..6b91dcdef907 100644 --- a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_lockscreen_ime.xml +++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_lockscreen_ime.xml @@ -1,55 +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. - */ + 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 android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M21,4H3C1.9,4,1,4.9,1,6v13c0,1.1,0.9,2,2,2h18c1.1,0,2-0.9,2-2V6C23,4.9,22.1,4,21,4z M21.5,19c0,0.27-0.23,0.5-0.5,0.5 H3c-0.27,0-0.5-0.23-0.5-0.5V6c0-0.27,0.23-0.5,0.5-0.5h18c0.27,0,0.5,0.23,0.5,0.5V19z"/> + <path android:fillColor="@android:color/white" android:pathData="M9.5,10h1c0.28,0,0.5-0.22,0.5-0.5v-1C11,8.22,10.78,8,10.5,8h-1C9.22,8,9,8.22,9,8.5v1C9,9.78,9.22,10,9.5,10z"/> + <path android:fillColor="@android:color/white" android:pathData="M6.5,8h-1C5.22,8,5,8.22,5,8.5v1C5,9.78,5.22,10,5.5,10h1C6.78,10,7,9.78,7,9.5v-1C7,8.22,6.78,8,6.5,8z"/> + <path android:fillColor="@android:color/white" android:pathData="M15.25,16h-6.5C8.34,16,8,16.34,8,16.75c0,0.41,0.34,0.75,0.75,0.75h6.5c0.41,0,0.75-0.34,0.75-0.75 C16,16.34,15.66,16,15.25,16z"/> + <path android:fillColor="@android:color/white" android:pathData="M13.5,10h1c0.28,0,0.5-0.22,0.5-0.5v-1C15,8.22,14.78,8,14.5,8h-1C13.22,8,13,8.22,13,8.5v1C13,9.78,13.22,10,13.5,10z"/> + <path android:fillColor="@android:color/white" android:pathData="M9.5,14h1c0.28,0,0.5-0.22,0.5-0.5v-1c0-0.28-0.22-0.5-0.5-0.5h-1C9.22,12,9,12.22,9,12.5v1C9,13.78,9.22,14,9.5,14z"/> + <path android:fillColor="@android:color/white" android:pathData="M6.5,12h-1C5.22,12,5,12.22,5,12.5v1C5,13.78,5.22,14,5.5,14h1C6.78,14,7,13.78,7,13.5v-1C7,12.22,6.78,12,6.5,12z"/> + <path android:fillColor="@android:color/white" android:pathData="M13.5,14h1c0.28,0,0.5-0.22,0.5-0.5v-1c0-0.28-0.22-0.5-0.5-0.5h-1c-0.28,0-0.5,0.22-0.5,0.5v1C13,13.78,13.22,14,13.5,14 z"/> + <path android:fillColor="@android:color/white" android:pathData="M18.5,8h-1C17.22,8,17,8.22,17,8.5v1c0,0.28,0.22,0.5,0.5,0.5h1c0.28,0,0.5-0.22,0.5-0.5v-1C19,8.22,18.78,8,18.5,8z"/> + <path android:fillColor="@android:color/white" android:pathData="M18.5,12h-1c-0.28,0-0.5,0.22-0.5,0.5v1c0,0.28,0.22,0.5,0.5,0.5h1c0.28,0,0.5-0.22,0.5-0.5v-1C19,12.22,18.78,12,18.5,12 z"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_mode_edit.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_mode_edit.xml index 8532bdd29db5..a341880e5773 100644 --- a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_mode_edit.xml +++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_mode_edit.xml @@ -1,28 +1,20 @@ + <!-- -/** - * 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. - */ + 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.35,21.15h0.07l3.88-0.6a1,1,0,0,0,0.56-0.28L21,7.07h0A0.75 0.75 ,0,0,0,21,6L18,3h0a0.73 0.73 ,0,0,0-0.52-0.21A0.74 0.74 ,0,0,0,17,3L15.51,4.45h0L14.44,5.5h0L3.73,16.14a1,1,0,0,0-0.28 0.56 l-0.6,3.88A0.51 0.51 ,0,0,0,3.35,21.15ZM17.5,4.59l1.95,1.94-0.93 0.93 L16.57,5.51ZM4.91,17.09,15.51,6.56l2,2L6.91,19.09l-2.37 0.37 Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M20.08,5.08l-1.17-1.17c-0.39-0.39-0.9-0.58-1.41-0.58c-0.51,0-1.02,0.2-1.41,0.59L3.29,16.71C3.11,16.89,3,17.15,3,17.41 l0,2.59c0,0.55,0.45,1,1,1c0,0,0,0,0,0L6.59,21c0.26,0,0.52-0.11,0.71-0.29l10.68-10.68l0,0l1.06-1.06l0,0l1.05-1.06 C20.87,7.13,20.87,5.86,20.08,5.08z M6.38,19.5l-1.88,0l0-1.88L15.03,7.09l1.88,1.88L6.38,19.5z M19.02,6.85l-1.06,1.06l-1.88-1.88 l1.05-1.05c0.13-0.13,0.28-0.15,0.35-0.15c0.08,0,0.23,0.02,0.35,0.15l1.17,1.17c0.13,0.13,0.15,0.28,0.15,0.35 C19.17,6.57,19.15,6.72,19.02,6.85z"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_phone.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_phone.xml index c62203dc893f..b57d509e21b1 100644 --- a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_phone.xml +++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_phone.xml @@ -1,28 +1,20 @@ + <!-- -/** - * 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. - */ + 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="M21,16.35A1.41,1.41,0,0,0,20,15l-2.42-0.73a1.43,1.43,0,0,0-1.41 0.34 l-2.95,2.87a16.48,16.48,0,0,1-3.74-2.7,17.33,17.33,0,0,1-3-4L9.36,7.94a1.42,1.42,0,0,0,0.37-1.36L9.07,4.12a1.43,1.43,0,0,0-1.37-1h-4a0.56 0.56 ,0,0,0-0.12,0,0.58 0.58 ,0,0,0-0.14,0,0.54 0.54 ,0,0,0-0.12 0.09 l-0.11 0.08 a0.94 0.94 ,0,0,0-0.09 0.12 l-0.07 0.12 ,0,0.15s0,0.08,0,0.12v0a18.53,18.53,0,0,0,5.42,12,18.25,18.25,0,0,0,11.79,5.07h0a0.72 0.72 ,0,0,0,0.29-0.06l0.08-0.05a0.53 0.53 ,0,0,0,0.15-0.11 0.31 0.31,0,0,0,0.07-0.09 0.67 0.67,0,0,0,0.09-0.14 0.53 0.53,0,0,0,0-0.12 0.37 0.37,0,0,0,0-0.15h0V16.35ZM8.3,6.88,5.81,9.33A17.23,17.23,0,0,1,4.58,4.58H7.64Zm8.83,8.82,2.37 0.72 v2.93a17.06,17.06,0,0,1-4.85-1.19Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M21,16.35c0-0.62-0.4-1.17-1.01-1.35l-2.42-0.73c-0.5-0.15-1.04-0.02-1.41,0.34l-2.96,2.87c-1.36-0.72-2.62-1.62-3.74-2.7 c-1.2-1.2-2.19-2.56-2.97-4.02l2.87-2.82c0.36-0.36,0.5-0.88,0.37-1.37L9.07,4.12C8.9,3.51,8.34,3.08,7.7,3.08H3.75 c-0.01,0-0.01,0-0.02,0c-0.01,0-0.02,0-0.02,0c-0.05,0-0.08,0.02-0.13,0.03C3.53,3.13,3.48,3.13,3.44,3.15 C3.39,3.17,3.36,3.21,3.32,3.24C3.28,3.26,3.24,3.29,3.21,3.32C3.17,3.36,3.15,3.4,3.12,3.44C3.1,3.48,3.07,3.52,3.05,3.56 c-0.02,0.05-0.02,0.1-0.03,0.15C3.02,3.75,3,3.79,3,3.83c0,0.01,0,0.01,0,0.02c0,0.01,0,0.02,0,0.02c0.28,4.51,2.2,8.76,5.42,11.98 c3.18,3.06,7.37,4.86,11.8,5.07c0.01,0,0.02,0,0.04,0c0,0,0,0,0,0s0,0,0,0c0,0,0,0,0,0c0.1,0,0.2-0.02,0.29-0.06 c0.03-0.01,0.05-0.04,0.08-0.05c0.05-0.03,0.11-0.06,0.15-0.1c0.03-0.03,0.04-0.06,0.07-0.09c0.03-0.04,0.07-0.09,0.09-0.14 c0.02-0.04,0.02-0.08,0.03-0.12C20.98,20.3,21,20.26,21,20.2c0-0.01,0-0.01,0-0.02c0-0.01,0-0.01,0-0.02V16.35z M8.3,6.88 L5.81,9.33c-0.63-1.51-1.05-3.1-1.23-4.74h3.05L8.3,6.88z M17.13,15.7l2.37,0.71v2.93c-1.68-0.16-3.31-0.56-4.85-1.19L17.13,15.7z"/> </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..01accfb9e438 --- /dev/null +++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_qs_airplane.xml @@ -0,0 +1,20 @@ + +<!-- + 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 android:height="18dp" android:viewportHeight="24" android:viewportWidth="24" android:width="18dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <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/IconPackRoundedAndroidOverlay/res/drawable/ic_qs_auto_rotate.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_qs_auto_rotate.xml new file mode 100644 index 000000000000..159381030e91 --- /dev/null +++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_qs_auto_rotate.xml @@ -0,0 +1,21 @@ + +<!-- + 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 android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path 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="@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..d49b81eb782f --- /dev/null +++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_qs_bluetooth.xml @@ -0,0 +1,20 @@ + +<!-- + 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 android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <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..8b5f98e622eb --- /dev/null +++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_qs_dnd.xml @@ -0,0 +1,21 @@ + +<!-- + 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 android:height="17dp" android:viewportHeight="24" android:viewportWidth="24" android:width="17dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <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/IconPackRoundedAndroidOverlay/res/drawable/ic_qs_flashlight.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_qs_flashlight.xml new file mode 100644 index 000000000000..2481763ef816 --- /dev/null +++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_qs_flashlight.xml @@ -0,0 +1,21 @@ + +<!-- + 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 android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path 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="@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_qs_night_display_on.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_qs_night_display_on.xml index 96ce11c2b918..e26d64724c4d 100644 --- a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_qs_night_display_on.xml +++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_qs_night_display_on.xml @@ -1,28 +1,20 @@ + <!-- -/** - * 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. - */ + 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.63,16.12a0.75 0.75 ,0,0,0-0.76-0.32,12.23,12.23,0,0,1-2.12 0.2 A11.76,11.76,0,0,1,8,4.25a12.23,12.23,0,0,1,0.2-2.12 0.73 0.73,0,0,0-0.32-0.76 0.74 0.74,0,0,0-0.83,0A11.25,11.25,0,1,0,22.63,17,0.74 0.74 ,0,0,0,22.63,16.12ZM13.25,20.5A9.75,9.75,0,0,1,6.51,3.71c0,0.18,0,0.36,0,0.54A13.27,13.27,0,0,0,20.29,17.49,9.71,9.71,0,0,1,13.25,20.5Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M22.63,16.12c-0.17-0.25-0.47-0.38-0.76-0.33c-0.74,0.14-1.44,0.2-2.12,0.2C13.27,16,8,10.73,8,4.25 c0-0.68,0.07-1.38,0.2-2.12c0.05-0.3-0.07-0.59-0.33-0.76C7.63,1.2,7.3,1.2,7.05,1.37C3.89,3.46,2,6.97,2,10.75 C2,16.95,7.05,22,13.25,22c3.78,0,7.29-1.89,9.38-5.05C22.8,16.7,22.8,16.37,22.63,16.12z M13.25,20.5c-5.38,0-9.75-4.37-9.75-9.75 c0-2.69,1.1-5.22,3.01-7.04C6.5,3.89,6.5,4.07,6.5,4.25c0,7.49,6.28,13.57,13.79,13.24C18.47,19.4,15.94,20.5,13.25,20.5z"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_restart.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_restart.xml new file mode 100644 index 000000000000..425fd816398c --- /dev/null +++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_restart.xml @@ -0,0 +1,21 @@ + +<!-- + 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 android:height="24dp" android:tint="?android:attr/colorControlNormal" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M12.03,2.96c-0.29-0.29-0.77-0.29-1.06,0l-2.51,2.5C8.33,5.61,8.25,5.8,8.25,6s0.08,0.39,0.22,0.53l2.51,2.5 c0.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-1.34-1.34C11.12,6.55,11.56,6.5,12,6.5 c3.58,0,6.5,2.92,6.5,6.5c0,3.05-2.07,5.66-5.04,6.34c-0.4,0.09-0.66,0.5-0.56,0.9c0.08,0.35,0.39,0.58,0.73,0.58 c0.06,0,0.11-0.01,0.17-0.02C17.45,19.96,20,16.75,20,13c0-4.41-3.59-8-8-8c-0.34,0-0.68,0.03-1.01,0.07l1.05-1.05 C12.33,3.73,12.33,3.26,12.03,2.96z"/> + <path android:fillColor="@android:color/white" android:pathData="M7,7.69C6.69,7.42,6.22,7.46,5.95,7.77C4.69,9.22,4,11.08,4,13c0,3.75,2.55,6.96,6.21,7.8c0.06,0.01,0.11,0.02,0.17,0.02 c0.34,0,0.65-0.24,0.73-0.58c0.09-0.4-0.16-0.81-0.56-0.9C7.57,18.66,5.5,16.05,5.5,13c0-1.56,0.56-3.07,1.58-4.25 C7.35,8.44,7.32,7.96,7,7.69z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_screenshot.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_screenshot.xml new file mode 100644 index 000000000000..ef033e6a181e --- /dev/null +++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_screenshot.xml @@ -0,0 +1,22 @@ + +<!-- + 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 android:height="24dp" android:tint="?android:attr/colorControlNormal" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M15.25,12c-0.41,0-0.75,0.34-0.75,0.75v2.75h-2.75c-0.41,0-0.75,0.34-0.75,0.75S11.34,17,11.75,17h3.5 c0.41,0,0.75-0.34,0.75-0.75v-3.5C16,12.34,15.66,12,15.25,12z"/> + <path android:fillColor="@android:color/white" android:pathData="M13,7.75C13,7.34,12.66,7,12.25,7h-3.5C8.34,7,8,7.34,8,7.75v3.5C8,11.66,8.34,12,8.75,12s0.75-0.34,0.75-0.75V8.5h2.75 C12.66,8.5,13,8.16,13,7.75z"/> + <path android:fillColor="@android:color/white" android:pathData="M16,23c1.66,0,3-1.34,3-3V4c0-1.66-1.34-3-3-3H8C6.34,1,5,2.34,5,4v16c0,1.66,1.34,3,3,3H16z M8,2.5h8 c0.83,0,1.5,0.67,1.5,1.5h-11C6.5,3.17,7.17,2.5,8,2.5z M6.5,5.5h11v13h-11V5.5z M6.5,20h11c0,0.83-0.67,1.5-1.5,1.5H8 C7.17,21.5,6.5,20.83,6.5,20z"/> +</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..d49b81eb782f --- /dev/null +++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_settings_bluetooth.xml @@ -0,0 +1,20 @@ + +<!-- + 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 android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <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_signal_location.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_signal_location.xml index eb94952fa24c..133ccea15c5b 100644 --- a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_signal_location.xml +++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_signal_location.xml @@ -1,31 +1,21 @@ + <!-- -/** - * 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. - */ + 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="M15,10a3,3,0,1,0-3,3A3,3,0,0,0,15,10Zm-4.5,0A1.5,1.5,0,1,1,12,11.5,1.5,1.5,0,0,1,10.5,10Z" /> - <path - android:fillColor="#000000" - android:pathData="M11.37,21.76A1,1,0,0,0,12,22a1,1,0,0,0,0.62-0.22C14.5,20.26,20,15.5,20,10a8,8,0,0,0-8-8,7.89,7.89,0,0,0-8,8C4,15.5,9.48,20.25,11.37,21.76ZM12,3.51A6.5,6.5,0,0,1,18.5,10c0,4.4-4.31,8.53-6.5,10.34C9.82,18.54,5.5,14.4,5.5,10A6.43,6.43,0,0,1,12,3.51Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M12,7c-1.66,0-3,1.34-3,3s1.34,3,3,3s3-1.34,3-3S13.66,7,12,7z M12,11.5c-0.83,0-1.5-0.67-1.5-1.5s0.67-1.5,1.5-1.5 s1.5,0.67,1.5,1.5S12.83,11.5,12,11.5z"/> + <path android:fillColor="@android:color/white" android:pathData="M12,2.01c-4.5,0-8,3.49-8,8c0,5.49,5.48,10.24,7.37,11.76c0.19,0.15,0.41,0.22,0.63,0.22c0.22,0,0.44-0.07,0.62-0.22 C14.5,20.26,20,15.5,20,10C20,5.72,16.5,2.01,12,2.01z M12,20.34c-2.18-1.8-6.5-5.94-6.5-10.34c0-3.64,2.86-6.5,6.5-6.5 c3.58,0,6.5,2.91,6.5,6.49C18.5,14.4,14.19,18.53,12,20.34z"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_wifi_signal_0.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_wifi_signal_0.xml index 96d04c3e8edd..8aeb60a831d3 100644 --- a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_wifi_signal_0.xml +++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_wifi_signal_0.xml @@ -1,49 +1,20 @@ + <!-- -/** - * 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. - */ + 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:fillAlpha="0.3" - android:strokeAlpha="0.3" - android:strokeWidth="1" - android:pathData="M22.8,7.25a0.73 0.73 ,0,0,1,0,1l0,0a0.83 0.83 ,0,0,1-1.05,0,13.16,13.16,0,0,0-9.7-4,13.34,13.34,0,0,0-9.7,4,0.72 0.72 ,0,0,1-1,0l0,0a0.76 0.76 ,0,0,1,0-1.05A14.77,14.77,0,0,1,12,2.8,14.51,14.51,0,0,1,22.8,7.25Z" /> - <path - android:fillColor="#000000" - android:fillAlpha="0.3" - android:strokeAlpha="0.3" - android:strokeWidth="1" - android:pathData="M8.3,14.8a0.73 0.73 ,0,0,1-1,0l0,0a0.76 0.76 ,0,0,1,0-1,6.73,6.73,0,0,1,9.52,0l0,0h0a0.75 0.75 ,0,0,1,0.12,1.05 0.75 0.75,0,0,1-1.05 0.12 l-0.07-0.07a0,0,0,0,1-0.05,0h0A5.28,5.28,0,0,0,8.3,14.8Z" /> - <path - android:fillColor="#000000" - android:fillAlpha="0.3" - android:strokeAlpha="0.3" - android:strokeWidth="1" - android:pathData="M20.05,10.75A0.74 0.74 ,0,0,1,19,11.8h0a10.15,10.15,0,0,0-6.95-3,9.93,9.93,0,0,0-7,3,0.74 0.74 ,0,0,1-1-1.05,11.36,11.36,0,0,1,8.05-3.5A11.43,11.43,0,0,1,20.05,10.75Z" /> - <path - android:fillColor="#000000" - android:fillAlpha="0.3" - android:strokeAlpha="0.3" - android:strokeWidth="1" - android:pathData="M 12 17 C 12.8284271247 17 13.5 17.6715728753 13.5 18.5 C 13.5 19.3284271247 12.8284271247 20 12 20 C 11.1715728753 20 10.5 19.3284271247 10.5 18.5 C 10.5 17.6715728753 11.1715728753 17 12 17 Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M12,2C7.75,2,3.88,3.66,0.99,6.38C0.41,6.92,0.36,7.82,0.86,8.43l10.37,12.63c0.2,0.24,0.49,0.37,0.77,0.37 s0.57-0.12,0.77-0.37L23.14,8.43c0.5-0.61,0.45-1.51-0.13-2.05C20.12,3.66,16.25,2,12,2z M12,19.64L2.01,7.48 C4.74,4.91,8.29,3.5,12,3.5s7.26,1.41,9.98,3.98L12,19.64z"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_wifi_signal_1.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_wifi_signal_1.xml index b88732067ef4..01155ea3fbc4 100644 --- a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_wifi_signal_1.xml +++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_wifi_signal_1.xml @@ -1,46 +1,20 @@ + <!-- -/** - * 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. - */ + 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:fillAlpha="0.3" - android:strokeAlpha="0.3" - android:strokeWidth="1" - android:pathData="M16.77,13.71a6.74,6.74,0,0,0-9.54,0,0.75 0.75 ,0,0,0,1.06,1.06h0a5.25,5.25,0,0,1,7.42,0h0a0.08 0.08 ,0,0,1,0,0,0.75 0.75 ,0,0,0,1.17-1,0.8 0.8 ,0,0,0-0.17-0.15Z" /> - <path - android:fillColor="#000000" - android:pathData="M 12 17 C 12.8284271247 17 13.5 17.6715728753 13.5 18.5 C 13.5 19.3284271247 12.8284271247 20 12 20 C 11.1715728753 20 10.5 19.3284271247 10.5 18.5 C 10.5 17.6715728753 11.1715728753 17 12 17 Z" /> - <path - android:fillColor="#000000" - android:fillAlpha="0.3" - android:strokeAlpha="0.3" - android:strokeWidth="1" - android:pathData="M20,10.73a11.51,11.51,0,0,0-8-3.5,11.55,11.55,0,0,0-8,3.5 0.75 0.75,0,0,0,0.95,1.15A0.38 0.38 ,0,0,0,5,11.77a10.12,10.12,0,0,1,7-3,10.1,10.1,0,0,1,7,3,0.75 0.75 ,0,0,0,1.06,0,0.77 0.77 ,0,0,0,0-1.07Z" /> - <path - android:fillColor="#000000" - android:fillAlpha="0.3" - android:strokeAlpha="0.3" - android:strokeWidth="1" - android:pathData="M22.79,7.23A14.76,14.76,0,0,0,12,2.75,14.72,14.72,0,0,0,1.23,7.2a0.75 0.75 ,0,0,0,1.07,1,13.25,13.25,0,0,1,9.7-4,13.27,13.27,0,0,1,9.72,4,0.75 0.75 ,0,0,0,1.07-1Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M12,2C7.75,2,3.88,3.66,0.99,6.38C0.41,6.92,0.36,7.82,0.86,8.43l6.72,8.19c0,0,0,0,0,0l0.52,0.64l3.12,3.8 c0.2,0.24,0.49,0.37,0.77,0.37s0.57-0.12,0.77-0.37l3.12-3.8l0.52-0.64c0,0,0,0,0,0l6.72-8.19c0.5-0.61,0.45-1.51-0.13-2.05 C20.12,3.66,16.25,2,12,2z M15.77,15.04c-0.09-0.14-0.19-0.28-0.3-0.41c-0.82-1-2.07-1.64-3.47-1.64s-2.65,0.64-3.47,1.64 c-0.11,0.13-0.21,0.27-0.3,0.41L2.01,7.48C4.74,4.91,8.29,3.5,12,3.5s7.26,1.41,9.98,3.98L15.77,15.04z"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_wifi_signal_2.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_wifi_signal_2.xml index af41245bcf14..bf5a35870df1 100644 --- a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_wifi_signal_2.xml +++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_wifi_signal_2.xml @@ -1,43 +1,20 @@ + <!-- -/** - * 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. - */ + 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="M16.77,13.71a6.74,6.74,0,0,0-9.54,0,0.75 0.75 ,0,0,0,1.06,1.06h0a5.25,5.25,0,0,1,7.42,0h0a0.08 0.08 ,0,0,1,0,0,0.75 0.75 ,0,0,0,1.17-1,0.8 0.8 ,0,0,0-0.17-0.15Z" /> - <path - android:fillColor="#000000" - android:pathData="M 12 17 C 12.8284271247 17 13.5 17.6715728753 13.5 18.5 C 13.5 19.3284271247 12.8284271247 20 12 20 C 11.1715728753 20 10.5 19.3284271247 10.5 18.5 C 10.5 17.6715728753 11.1715728753 17 12 17 Z" /> - <path - android:fillColor="#000000" - android:fillAlpha="0.3" - android:strokeAlpha="0.3" - android:strokeWidth="1" - android:pathData="M20,10.73a11.51,11.51,0,0,0-8-3.5,11.55,11.55,0,0,0-8,3.5 0.75 0.75,0,0,0,0.95,1.15A0.38 0.38 ,0,0,0,5,11.77a10.12,10.12,0,0,1,7-3,10.1,10.1,0,0,1,7,3,0.75 0.75 ,0,0,0,1.06,0,0.77 0.77 ,0,0,0,0-1.07Z" /> - <path - android:fillColor="#000000" - android:fillAlpha="0.3" - android:strokeAlpha="0.3" - android:strokeWidth="1" - android:pathData="M22.79,7.23A14.76,14.76,0,0,0,12,2.75,14.72,14.72,0,0,0,1.23,7.2a0.75 0.75 ,0,0,0,1.07,1,13.25,13.25,0,0,1,9.7-4,13.27,13.27,0,0,1,9.72,4,0.75 0.75 ,0,0,0,1.07-1Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M12,2C7.75,2,3.88,3.66,0.99,6.38C0.41,6.92,0.36,7.82,0.86,8.43l10.37,12.63c0.2,0.24,0.49,0.37,0.77,0.37 s0.57-0.12,0.77-0.37L23.14,8.43c0.5-0.61,0.45-1.51-0.13-2.05C20.12,3.66,16.25,2,12,2z M17.72,12.68 c-0.11-0.13-0.21-0.27-0.33-0.39c-1.36-1.42-3.27-2.3-5.39-2.3s-4.03,0.88-5.39,2.3c-0.12,0.12-0.22,0.26-0.33,0.39l-4.27-5.2 C4.74,4.91,8.29,3.5,12,3.5s7.26,1.41,9.98,3.98L17.72,12.68z"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_wifi_signal_3.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_wifi_signal_3.xml index c13764395261..ff8c305cb9dd 100644 --- a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_wifi_signal_3.xml +++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_wifi_signal_3.xml @@ -1,40 +1,20 @@ + <!-- -/** - * 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. - */ + 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="M16.77,13.71a6.74,6.74,0,0,0-9.54,0,0.75 0.75 ,0,0,0,1.06,1.06h0a5.25,5.25,0,0,1,7.42,0h0a0.08 0.08 ,0,0,1,0,0,0.75 0.75 ,0,0,0,1.17-1,0.8 0.8 ,0,0,0-0.17-0.15Z" /> - <path - android:fillColor="#000000" - android:pathData="M 12 17 C 12.8284271247 17 13.5 17.6715728753 13.5 18.5 C 13.5 19.3284271247 12.8284271247 20 12 20 C 11.1715728753 20 10.5 19.3284271247 10.5 18.5 C 10.5 17.6715728753 11.1715728753 17 12 17 Z" /> - <path - android:fillColor="#000000" - android:pathData="M20,10.73a11.51,11.51,0,0,0-8-3.5,11.55,11.55,0,0,0-8,3.5 0.75 0.75,0,0,0,0.95,1.15A0.38 0.38 ,0,0,0,5,11.77a10.12,10.12,0,0,1,7-3,10.1,10.1,0,0,1,7,3,0.75 0.75 ,0,0,0,1.06,0,0.77 0.77 ,0,0,0,0-1.07Z" /> - <path - android:fillColor="#000000" - android:fillAlpha="0.3" - android:strokeAlpha="0.3" - android:strokeWidth="1" - android:pathData="M22.79,7.23A14.76,14.76,0,0,0,12,2.75,14.72,14.72,0,0,0,1.23,7.2a0.75 0.75 ,0,0,0,1.07,1,13.25,13.25,0,0,1,9.7-4,13.27,13.27,0,0,1,9.72,4,0.75 0.75 ,0,0,0,1.07-1Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M12,2C7.75,2,3.88,3.66,0.99,6.38C0.41,6.92,0.36,7.82,0.86,8.43l2.44,2.98c0,0,0,0,0,0l7.93,9.65 c0.4,0.49,1.15,0.49,1.55,0l7.93-9.65c0,0,0,0,0,0l2.44-2.98c0.5-0.61,0.45-1.51-0.13-2.05C20.12,3.66,16.25,2,12,2z M19.71,10.25 c-0.09-0.09-0.17-0.19-0.27-0.27C17.51,8.12,14.9,6.99,12,6.99S6.49,8.13,4.56,9.98c-0.09,0.09-0.18,0.18-0.26,0.27L2.01,7.48 C4.74,4.91,8.29,3.5,12,3.5s7.26,1.41,9.98,3.98L19.71,10.25z"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_wifi_signal_4.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_wifi_signal_4.xml index b8f2d78ba6b8..e31a55046e83 100644 --- a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_wifi_signal_4.xml +++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_wifi_signal_4.xml @@ -1,37 +1,20 @@ + <!-- -/** - * 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. - */ + 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="M20,11.79a0.77 0.77 ,0,0,0,0-1.07h0a11.59,11.59,0,0,0-8-3.5,11.63,11.63,0,0,0-8,3.5 0.77 0.77,0,0,0,0,1.07 0.76 0.76,0,0,0,1.07,0,10.12,10.12,0,0,1,7-3,10.12,10.12,0,0,1,7,3A0.75 0.75 ,0,0,0,20,11.79Z" /> - <path - android:fillColor="#000000" - android:pathData="M15.78,14.82a0.57 0.57 ,0,0,0,0.16 0.15 0.75 0.75 ,0,0,0,1-0.2 0.76 0.76,0,0,0-0.2-1,6.77,6.77,0,0,0-9.55,0,0.76 0.76 ,0,0,0,0,1,0.75 0.75 ,0,0,0,1.06,0h0a5.24,5.24,0,0,1,7.42,0A0.08 0.08 ,0,0,0,15.78,14.82Z" /> - <path - android:fillColor="#000000" - android:pathData="M 12 17 C 12.8284271247 17 13.5 17.6715728753 13.5 18.5 C 13.5 19.3284271247 12.8284271247 20 12 20 C 11.1715728753 20 10.5 19.3284271247 10.5 18.5 C 10.5 17.6715728753 11.1715728753 17 12 17 Z" /> - <path - android:fillColor="#000000" - android:pathData="M2.3,8.25a13.25,13.25,0,0,1,9.7-4,13.27,13.27,0,0,1,9.72,4,0.73 0.73 ,0,0,0,1,0,0.75 0.75 ,0,0,0,0.05-1.06A14.76,14.76,0,0,0,12,2.75,14.76,14.76,0,0,0,1.22,7.2a0.77 0.77 ,0,0,0,0,1A0.75 0.75 ,0,0,0,2.3,8.25Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M12,2C7.75,2,3.88,3.66,0.99,6.38C0.41,6.92,0.36,7.82,0.86,8.43l10.37,12.63c0.4,0.49,1.15,0.49,1.55,0L23.14,8.43 c0.5-0.61,0.45-1.51-0.13-2.05C20.12,3.66,16.25,2,12,2z"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_airplanemode_active.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_airplanemode_active.xml new file mode 100644 index 000000000000..ed642779fc35 --- /dev/null +++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_airplanemode_active.xml @@ -0,0 +1,20 @@ + +<!-- + 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 android:height="24dp" android:tint="?android:attr/colorControlNormal" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <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/IconPackRoundedSettingsOverlay/res/drawable/ic_apps.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_apps.xml index 62acfc66b5df..1dca653e064b 100644 --- a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_apps.xml +++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_apps.xml @@ -1,52 +1,28 @@ + <!-- -/** - * 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. - */ + 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="#FFFFFF" - android:pathData="M 5.5 4 L 6.5 4 Q 8 4 8 5.5 L 8 6.5 Q 8 8 6.5 8 L 5.5 8 Q 4 8 4 6.5 L 4 5.5 Q 4 4 5.5 4 Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M 11.5 4 L 12.5 4 Q 14 4 14 5.5 L 14 6.5 Q 14 8 12.5 8 L 11.5 8 Q 10 8 10 6.5 L 10 5.5 Q 10 4 11.5 4 Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M 17.5 4 L 18.5 4 Q 20 4 20 5.5 L 20 6.5 Q 20 8 18.5 8 L 17.5 8 Q 16 8 16 6.5 L 16 5.5 Q 16 4 17.5 4 Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M 5.5 10 L 6.5 10 Q 8 10 8 11.5 L 8 12.5 Q 8 14 6.5 14 L 5.5 14 Q 4 14 4 12.5 L 4 11.5 Q 4 10 5.5 10 Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M 11.5 10 L 12.5 10 Q 14 10 14 11.5 L 14 12.5 Q 14 14 12.5 14 L 11.5 14 Q 10 14 10 12.5 L 10 11.5 Q 10 10 11.5 10 Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M 17.5 10 L 18.5 10 Q 20 10 20 11.5 L 20 12.5 Q 20 14 18.5 14 L 17.5 14 Q 16 14 16 12.5 L 16 11.5 Q 16 10 17.5 10 Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M 5.5 16 L 6.5 16 Q 8 16 8 17.5 L 8 18.5 Q 8 20 6.5 20 L 5.5 20 Q 4 20 4 18.5 L 4 17.5 Q 4 16 5.5 16 Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M 11.5 16 L 12.5 16 Q 14 16 14 17.5 L 14 18.5 Q 14 20 12.5 20 L 11.5 20 Q 10 20 10 18.5 L 10 17.5 Q 10 16 11.5 16 Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M 17.5 16 L 18.5 16 Q 20 16 20 17.5 L 20 18.5 Q 20 20 18.5 20 L 17.5 20 Q 16 20 16 18.5 L 16 17.5 Q 16 16 17.5 16 Z" /> -</vector> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M6.5,4h-1C4.67,4,4,4.67,4,5.5v1C4,7.33,4.67,8,5.5,8h1C7.33,8,8,7.33,8,6.5v-1C8,4.67,7.33,4,6.5,4z"/> + <path android:fillColor="@android:color/white" android:pathData="M12.5,4h-1C10.67,4,10,4.67,10,5.5v1C10,7.33,10.67,8,11.5,8h1C13.33,8,14,7.33,14,6.5v-1C14,4.67,13.33,4,12.5,4z"/> + <path android:fillColor="@android:color/white" android:pathData="M18.5,4h-1C16.67,4,16,4.67,16,5.5v1C16,7.33,16.67,8,17.5,8h1C19.33,8,20,7.33,20,6.5v-1C20,4.67,19.33,4,18.5,4z"/> + <path android:fillColor="@android:color/white" android:pathData="M6.5,10h-1C4.67,10,4,10.67,4,11.5v1C4,13.33,4.67,14,5.5,14h1C7.33,14,8,13.33,8,12.5v-1C8,10.67,7.33,10,6.5,10z"/> + <path android:fillColor="@android:color/white" android:pathData="M12.5,10h-1c-0.83,0-1.5,0.67-1.5,1.5v1c0,0.83,0.67,1.5,1.5,1.5h1c0.83,0,1.5-0.67,1.5-1.5v-1C14,10.67,13.33,10,12.5,10 z"/> + <path android:fillColor="@android:color/white" android:pathData="M18.5,10h-1c-0.83,0-1.5,0.67-1.5,1.5v1c0,0.83,0.67,1.5,1.5,1.5h1c0.83,0,1.5-0.67,1.5-1.5v-1C20,10.67,19.33,10,18.5,10 z"/> + <path android:fillColor="@android:color/white" android:pathData="M6.5,16h-1C4.67,16,4,16.67,4,17.5v1C4,19.33,4.67,20,5.5,20h1C7.33,20,8,19.33,8,18.5v-1C8,16.67,7.33,16,6.5,16z"/> + <path android:fillColor="@android:color/white" android:pathData="M12.5,16h-1c-0.83,0-1.5,0.67-1.5,1.5v1c0,0.83,0.67,1.5,1.5,1.5h1c0.83,0,1.5-0.67,1.5-1.5v-1C14,16.67,13.33,16,12.5,16 z"/> + <path android:fillColor="@android:color/white" android:pathData="M18.5,16h-1c-0.83,0-1.5,0.67-1.5,1.5v1c0,0.83,0.67,1.5,1.5,1.5h1c0.83,0,1.5-0.67,1.5-1.5v-1C20,16.67,19.33,16,18.5,16 z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_data_saver.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_data_saver.xml new file mode 100644 index 000000000000..5fa15f43d043 --- /dev/null +++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_data_saver.xml @@ -0,0 +1,22 @@ + +<!-- + 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 android:height="24dp" android:tint="?android:attr/colorControlNormal" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M3.36,7A10,10,0,0,0,20.27,17.64L18.1,16.39A7.5,7.5,0,1,1,11.25,4.56V2.05A10,10,0,0,0,3.36,7Z"/> + <path android:fillColor="@android:color/white" android:pathData="M21,16.35a10,10,0,0,0-8.27-14.3V4.56a7.48,7.48,0,0,1,6.1,10.54Z"/> + <path android:fillColor="@android:color/white" android:pathData="M8,12a0.76 0.76 ,0,0,0,0.75 0.75 h2.5v2.5a0.75 0.75 ,0,0,0,1.5,0v-2.5h2.5a0.75 0.75 ,0,0,0,0-1.5h-2.5V8.75a0.75 0.75 ,0,0,0-1.5,0v2.5H8.75A0.76 0.76 ,0,0,0,8,12Z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_devices_other.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_devices_other.xml index be7f297a88e9..1317fa99ba87 100644 --- a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_devices_other.xml +++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_devices_other.xml @@ -1,34 +1,22 @@ + <!-- -/** - * 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. - */ + 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="#FFFFFF" - android:pathData="M22,18V10a1.5,1.5,0,0,0-1.5-1.5h-4A1.5,1.5,0,0,0,15,10v8a1.5,1.5,0,0,0,1.5,1.5h4A1.5,1.5,0,0,0,22,18Zm-5.5-8h4v8h-4Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M13,17a2.5,2.5,0,1,0-2.5,2.5A2.5,2.5,0,0,0,13,17ZM9.5,17a1,1,0,1,1,1,1A1,1,0,0,1,9.5,17Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M21.25,4H3.5A1.5,1.5,0,0,0,2,5.5V18a1.5,1.5,0,0,0,1.5,1.5H5.25a0.75 0.75 ,0,0,0,0-1.5H3.5V5.5H21.25a0.75 0.75 ,0,0,0,0-1.5Z" /> -</vector> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M5.25,18H3.5V5.5h17.75C21.66,5.5,22,5.16,22,4.75S21.66,4,21.25,4H3.5C2.67,4,2,4.67,2,5.5V18c0,0.83,0.67,1.5,1.5,1.5 h1.75C5.66,19.5,6,19.16,6,18.75S5.66,18,5.25,18z"/> + <path android:fillColor="@android:color/white" android:pathData="M10.5,14.5C9.12,14.5,8,15.62,8,17s1.12,2.5,2.5,2.5S13,18.38,13,17S11.88,14.5,10.5,14.5z M10.5,18c-0.55,0-1-0.45-1-1 s0.45-1,1-1s1,0.45,1,1S11.05,18,10.5,18z"/> + <path android:fillColor="@android:color/white" android:pathData="M20.5,8.5h-4C15.67,8.5,15,9.17,15,10v8c0,0.83,0.67,1.5,1.5,1.5h4c0.83,0,1.5-0.67,1.5-1.5v-8 C22,9.17,21.33,8.5,20.5,8.5z M20.5,18h-4v-8h4V18z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_help.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_help.xml index e8c3e47f75ef..36f296584331 100644 --- a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_help.xml +++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_help.xml @@ -1,34 +1,22 @@ + <!-- -/** - * 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. - */ + 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="#FFFFFF" - 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" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M8.67,10a0.77 0.77 ,0,0,0,0.91-0.56,2.48,2.48,0,0,1,0.65-1.19,2.57,2.57,0,0,1,3.54,0A2.2,2.2,0,0,1,14.43,10a1.81,1.81,0,0,1-0.84,1.37c-0.13 0.09 -0.26 0.16 -0.4 0.24 a3.3,3.3,0,0,0-1.93,2.51 0.76 0.76,0,0,0,0.62 0.87 H12a0.75 0.75 ,0,0,0,0.74-0.62,1.84,1.84,0,0,1,1.19-1.46l0.49-0.29a3.32,3.32,0,0,0,1.5-2.48,3.71,3.71,0,0,0-1.09-3,4.1,4.1,0,0,0-5.66,0,4,4,0,0,0-1.05,1.9A0.75 0.75 ,0,0,0,8.67,10Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M 12 16 C 12.5522847498 16 13 16.4477152502 13 17 C 13 17.5522847498 12.5522847498 18 12 18 C 11.4477152502 18 11 17.5522847498 11 17 C 11 16.4477152502 11.4477152502 16 12 16 Z" /> -</vector> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M12,22c0,0,0.01,0,0.01,0c5.5,0,9.98-4.47,9.99-9.98V12c0-5.51-4.49-10-10-10S2,6.49,2,12S6.49,22,12,22z M12,3.5 c4.69,0,8.5,3.81,8.5,8.5v0.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.5z"/> + <path android:fillColor="@android:color/white" android:pathData="M8.67,9.98c0.4,0.1,0.81-0.15,0.9-0.56c0.11-0.47,0.33-0.86,0.65-1.19c0.94-0.94,2.59-0.94,3.54,0 c0.49,0.49,0.73,1.13,0.67,1.76c-0.06,0.57-0.36,1.06-0.84,1.38c-0.13,0.08-0.26,0.16-0.4,0.24c-0.7,0.4-1.67,0.94-1.93,2.51 c-0.07,0.41,0.21,0.8,0.61,0.86C11.92,15,11.96,15,12,15c0.36,0,0.68-0.26,0.74-0.62c0.15-0.87,0.58-1.12,1.19-1.46 c0.17-0.09,0.33-0.19,0.49-0.29c0.87-0.58,1.41-1.46,1.51-2.48c0.11-1.08-0.29-2.17-1.1-2.97c-1.51-1.51-4.15-1.51-5.66,0 c-0.52,0.51-0.88,1.17-1.05,1.9C8.02,9.48,8.27,9.88,8.67,9.98z"/> + <path android:fillColor="@android:color/white" android:pathData="M 12 16 C 12.5522847498 16 13 16.4477152502 13 17 C 13 17.5522847498 12.5522847498 18 12 18 C 11.4477152502 18 11 17.5522847498 11 17 C 11 16.4477152502 11.4477152502 16 12 16 Z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_phone_info.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_phone_info.xml index e5e57d4e4cb6..35422fcaaef1 100644 --- a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_phone_info.xml +++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_phone_info.xml @@ -1,34 +1,22 @@ + <!-- -/** - * 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. - */ + 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="#FFFFFF" - android:pathData="M8,1A3,3,0,0,0,5,4V20a3,3,0,0,0,3,3h8a3,3,0,0,0,3-3V4a3,3,0,0,0-3-3Zm8,20.5H8A1.5,1.5,0,0,1,6.5,20h11A1.5,1.5,0,0,1,16,21.5Zm1.5-3H6.5V5.5h11ZM17.5,4H6.5A1.5,1.5,0,0,1,8,2.5h8A1.5,1.5,0,0,1,17.5,4Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M12,11.25a0.76 0.76 ,0,0,0-0.75 0.75 v4a0.75 0.75 ,0,0,0,1.5,0V12A0.76 0.76 ,0,0,0,12,11.25Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M 12 7 C 12.5522847498 7 13 7.44771525017 13 8 C 13 8.55228474983 12.5522847498 9 12 9 C 11.4477152502 9 11 8.55228474983 11 8 C 11 7.44771525017 11.4477152502 7 12 7 Z" /> -</vector> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M8,1C6.34,1,5,2.34,5,4v16c0,1.66,1.34,3,3,3h8c1.66,0,3-1.34,3-3V4c0-1.66-1.34-3-3-3H8z M16,21.5H8 c-0.83,0-1.5-0.67-1.5-1.5h11C17.5,20.83,16.83,21.5,16,21.5z M17.5,18.5h-11v-13h11V18.5z M17.5,4h-11c0-0.83,0.67-1.5,1.5-1.5h8 C16.83,2.5,17.5,3.17,17.5,4z"/> + <path android:fillColor="@android:color/white" android:pathData="M12,10.5c-0.41,0-0.75,0.34-0.75,0.75v5c0,0.41,0.34,0.75,0.75,0.75s0.75-0.34,0.75-0.75v-5 C12.75,10.84,12.41,10.5,12,10.5z"/> + <path android:fillColor="@android:color/white" android:pathData="M 12 7 C 12.5522847498 7 13 7.44771525017 13 8 C 13 8.55228474983 12.5522847498 9 12 9 C 11.4477152502 9 11 8.55228474983 11 8 C 11 7.44771525017 11.4477152502 7 12 7 Z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_accessibility.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_accessibility.xml index 1ac58b520590..2d24cd17e7b8 100644 --- a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_accessibility.xml +++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_accessibility.xml @@ -1,40 +1,24 @@ + <!-- -/** - * 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. - */ + 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="#FFFFFF" - android:pathData="M14.25,2.5A2.25,2.25,0,1,0,12,4.75,2.25,2.25,0,0,0,14.25,2.5Zm-3,0a0.75 0.75 ,0,1,1,0.75 0.75 A0.76 0.76 ,0,0,1,11.25,2.5Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M20.72,5.28a0.77 0.77 ,0,0,0-0.94-0.5,29.53,29.53,0,0,1-7.78,1,29.72,29.72,0,0,1-7.78-1,0.75 0.75 ,0,0,0-0.44,1.44A28.14,28.14,0,0,0,9,7.12V19a0.75 0.75 ,0,0,0,1.5,0V14h3v5A0.75 0.75 ,0,0,0,15,19V7.12a28.14,28.14,0,0,0,5.22-0.9A0.76 0.76 ,0,0,0,20.72,5.28Zm-7.22,2V12.5h-3V7.25Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M 8 22 C 8.55228474983 22 9 22.4477152502 9 23 C 9 23.5522847498 8.55228474983 24 8 24 C 7.44771525017 24 7 23.5522847498 7 23 C 7 22.4477152502 7.44771525017 22 8 22 Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M 12 22 C 12.5522847498 22 13 22.4477152502 13 23 C 13 23.5522847498 12.5522847498 24 12 24 C 11.4477152502 24 11 23.5522847498 11 23 C 11 22.4477152502 11.4477152502 22 12 22 Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M 16 22 C 16.5522847498 22 17 22.4477152502 17 23 C 17 23.5522847498 16.5522847498 24 16 24 C 15.4477152502 24 15 23.5522847498 15 23 C 15 22.4477152502 15.4477152502 22 16 22 Z" /> -</vector> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M 12 0.5 C 13.1045694997 0.5 14 1.39543050034 14 2.5 C 14 3.60456949966 13.1045694997 4.5 12 4.5 C 10.8954305003 4.5 10 3.60456949966 10 2.5 C 10 1.39543050034 10.8954305003 0.5 12 0.5 Z"/> + <path android:fillColor="@android:color/white" android:pathData="M20.72,5.28c-0.12-0.4-0.54-0.62-0.94-0.5C19.75,4.79,16.55,5.75,12,5.75c-4.53,0-7.75-0.96-7.78-0.97 c-0.39-0.12-0.81,0.1-0.94,0.5c-0.12,0.4,0.1,0.81,0.5,0.94C3.89,6.25,5.89,6.85,9,7.12v12.13C9,19.66,9.34,20,9.75,20 s0.75-0.34,0.75-0.75V14h3v5.25c0,0.41,0.34,0.75,0.75,0.75S15,19.66,15,19.25V7.12c3.11-0.27,5.11-0.87,5.22-0.9 C20.61,6.1,20.84,5.68,20.72,5.28z"/> + <path android:fillColor="@android:color/white" android:pathData="M 8 22 C 8.55228474983 22 9 22.4477152502 9 23 C 9 23.5522847498 8.55228474983 24 8 24 C 7.44771525017 24 7 23.5522847498 7 23 C 7 22.4477152502 7.44771525017 22 8 22 Z"/> + <path android:fillColor="@android:color/white" android:pathData="M 12 22 C 12.5522847498 22 13 22.4477152502 13 23 C 13 23.5522847498 12.5522847498 24 12 24 C 11.4477152502 24 11 23.5522847498 11 23 C 11 22.4477152502 11.4477152502 22 12 22 Z"/> + <path android:fillColor="@android:color/white" android:pathData="M 16 22 C 16.5522847498 22 17 22.4477152502 17 23 C 17 23.5522847498 16.5522847498 24 16 24 C 15.4477152502 24 15 23.5522847498 15 23 C 15 22.4477152502 15.4477152502 22 16 22 Z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_accounts.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_accounts.xml index 90da97f76324..710ed5e4e0b6 100644 --- a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_accounts.xml +++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_accounts.xml @@ -1,31 +1,21 @@ + <!-- -/** - * 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. - */ + 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="#FFFFFF" - android:pathData="M6.21,20.14l0.08 0.06 A10,10,0,0,0,12,22h0a10,10,0,0,0,5.76-1.84h0A10,10,0,0,0,22,12v0A10,10,0,1,0,6.21,20.14Zm5.8 0.36 h0a8.45,8.45,0,0,1-4.5-1.3V15.75A0.76 0.76 ,0,0,1,8.25,15h7.5a0.76 0.76 ,0,0,1,0.75 0.75 V19.2A8.39,8.39,0,0,1,12,20.5Zm0-17A8.51,8.51,0,0,1,20.5,12h0.75l-0.75,0A8.47,8.47,0,0,1,18,18V15.75a2.25,2.25,0,0,0-2.25-2.25H8.25A2.25,2.25,0,0,0,6,15.75V18A8.49,8.49,0,0,1,12,3.5Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M12,12h0A3,3,0,1,0,9,9H9A3,3,0,0,0,12,12ZM10.5,9A1.5,1.5,0,1,1,12,10.5h0A1.5,1.5,0,0,1,10.5,9Z" /> -</vector> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M12,2C6.49,2,2,6.49,2,12c0,3.36,1.67,6.33,4.21,8.14c0.02,0.02,0.05,0.04,0.07,0.06C7.91,21.33,9.88,22,12,22 c0,0,0.01,0,0.01,0c2.15,0,4.13-0.69,5.76-1.84c0,0,0.01,0,0.01-0.01c2.55-1.81,4.22-4.77,4.22-8.13V12C22,6.49,17.51,2,12,2z M16.5,19.2c-1.3,0.82-2.84,1.3-4.49,1.3c0,0-0.01,0-0.01,0c-1.65,0-3.19-0.48-4.5-1.3v-3.45C7.5,15.34,7.84,15,8.25,15h7.5 c0.41,0,0.75,0.34,0.75,0.75V19.2z M20.5,12.02c0,2.34-0.96,4.47-2.5,6v-2.27c0-1.24-1.01-2.25-2.25-2.25h-7.5 C7.01,13.5,6,14.51,6,15.75v2.26C4.46,16.47,3.5,14.35,3.5,12c0-4.69,3.81-8.5,8.5-8.5s8.5,3.81,8.5,8.5V12.02z"/> + <path android:fillColor="@android:color/white" android:pathData="M12,6c-1.65,0-3,1.35-3,3v0.01C9,10.66,10.35,12,11.99,12c0,0,0,0,0.01,0c1.65,0,3-1.35,3-3S13.65,6,12,6z M12,10.5 C12,10.5,12,10.5,12,10.5c-0.83,0-1.5-0.67-1.5-1.49V9c0-0.83,0.67-1.5,1.5-1.5s1.5,0.67,1.5,1.5S12.83,10.5,12,10.5z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_battery_white.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_battery_white.xml index 3f3b95a942d2..bdeb9fc408f7 100644 --- a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_battery_white.xml +++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_battery_white.xml @@ -1,28 +1,20 @@ + <!-- -/** - * 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. - */ + 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="#FFFFFF" - android:pathData="M13,2.49H11a1,1,0,0,0-1,1V4H7A1,1,0,0,0,6,5V21a1,1,0,0,0,1,1H17a1,1,0,0,0,1-1V5a1,1,0,0,0-1-1H14V3.49A1,1,0,0,0,13,2.49Z" /> -</vector> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M13,2.49h-2c-0.55,0-1,0.45-1,1V4H7C6.45,4,6,4.45,6,5v16c0,0.55,0.45,1,1,1h10c0.55,0,1-0.45,1-1V5c0-0.55-0.45-1-1-1h-3 V3.49C14,2.94,13.55,2.49,13,2.49z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_delete.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_delete.xml new file mode 100644 index 000000000000..7297658c2ade --- /dev/null +++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_delete.xml @@ -0,0 +1,22 @@ + +<!-- + 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 android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M20,4h-1h-4c0-0.55-0.45-1-1-1h-4C9.45,3,9,3.45,9,4H5H4C3.59,4,3.25,4.34,3.25,4.75S3.59,5.5,4,5.5h1V18 c0,1.66,1.34,3,3,3h8c1.66,0,3-1.34,3-3V5.5h1c0.41,0,0.75-0.34,0.75-0.75S20.41,4,20,4z M17.5,18c0,0.83-0.67,1.5-1.5,1.5H8 c-0.83,0-1.5-0.67-1.5-1.5V5.5h11V18z"/> + <path android:fillColor="@android:color/white" android:pathData="M14.25,8c-0.41,0-0.75,0.34-0.75,0.75v7.5c0,0.41,0.34,0.75,0.75,0.75S15,16.66,15,16.25v-7.5C15,8.34,14.66,8,14.25,8z"/> + <path android:fillColor="@android:color/white" android:pathData="M9.75,8C9.34,8,9,8.34,9,8.75v7.5C9,16.66,9.34,17,9.75,17s0.75-0.34,0.75-0.75v-7.5C10.5,8.34,10.16,8,9.75,8z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_display_white.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_display_white.xml index 54993e2b6ae8..41d9e5d0a213 100644 --- a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_display_white.xml +++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_display_white.xml @@ -1,52 +1,20 @@ + <!-- -/** - * 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. - */ + 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="#FFFFFF" - android:pathData="M19.5,12h0A7.5,7.5,0,1,0,12,19.5h0A7.49,7.49,0,0,0,19.5,12ZM12,18h0a6,6,0,1,1,6-6h0a6,6,0,0,1-6,6Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M 12 1.5 C 12.4142135624 1.5 12.75 1.83578643763 12.75 2.25 C 12.75 2.66421356237 12.4142135624 3 12 3 C 11.5857864376 3 11.25 2.66421356237 11.25 2.25 C 11.25 1.83578643763 11.5857864376 1.5 12 1.5 Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M 5.1 4.35 C 5.51421356237 4.35 5.85 4.68578643763 5.85 5.1 C 5.85 5.51421356237 5.51421356237 5.85 5.1 5.85 C 4.68578643763 5.85 4.35 5.51421356237 4.35 5.1 C 4.35 4.68578643763 4.68578643763 4.35 5.1 4.35 Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M 2.25 11.25 C 2.66421356237 11.25 3 11.5857864376 3 12 C 3 12.4142135624 2.66421356237 12.75 2.25 12.75 C 1.83578643763 12.75 1.5 12.4142135624 1.5 12 C 1.5 11.5857864376 1.83578643763 11.25 2.25 11.25 Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M 5.1 18.15 C 5.51421356237 18.15 5.85 18.4857864376 5.85 18.9 C 5.85 19.3142135624 5.51421356237 19.65 5.1 19.65 C 4.68578643763 19.65 4.35 19.3142135624 4.35 18.9 C 4.35 18.4857864376 4.68578643763 18.15 5.1 18.15 Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M 12 21 C 12.4142135624 21 12.75 21.3357864376 12.75 21.75 C 12.75 22.1642135624 12.4142135624 22.5 12 22.5 C 11.5857864376 22.5 11.25 22.1642135624 11.25 21.75 C 11.25 21.3357864376 11.5857864376 21 12 21 Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M 18.9 18.15 C 19.3142135624 18.15 19.65 18.4857864376 19.65 18.9 C 19.65 19.3142135624 19.3142135624 19.65 18.9 19.65 C 18.4857864376 19.65 18.15 19.3142135624 18.15 18.9 C 18.15 18.4857864376 18.4857864376 18.15 18.9 18.15 Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M 21.75 11.25 C 22.1642135624 11.25 22.5 11.5857864376 22.5 12 C 22.5 12.4142135624 22.1642135624 12.75 21.75 12.75 C 21.3357864376 12.75 21 12.4142135624 21 12 C 21 11.5857864376 21.3357864376 11.25 21.75 11.25 Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M 18.9 4.35 C 19.3142135624 4.35 19.65 4.68578643763 19.65 5.1 C 19.65 5.51421356237 19.3142135624 5.85 18.9 5.85 C 18.4857864376 5.85 18.15 5.51421356237 18.15 5.1 C 18.15 4.68578643763 18.4857864376 4.35 18.9 4.35 Z" /> -</vector> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M20.49,11.26h-1.03c-0.15-1.51-0.74-2.88-1.65-3.99l0.73-0.73c0.29-0.29,0.29-0.77,0-1.06s-0.77-0.29-1.06,0L16.75,6.2 c-1.11-0.91-2.49-1.51-4-1.66V3.5c0-0.41-0.34-0.75-0.75-0.75s-0.75,0.34-0.75,0.75v1.04c-1.5,0.15-2.88,0.75-3.99,1.65L6.53,5.46 c-0.29-0.29-0.77-0.29-1.06,0s-0.29,0.77,0,1.06L6.2,7.25c-0.91,1.11-1.51,2.49-1.66,3.99H3.51c-0.41,0-0.75,0.34-0.75,0.75 s0.34,0.75,0.75,0.75h1.03c0.15,1.51,0.74,2.88,1.65,3.99l-0.73,0.73c-0.29,0.29-0.29,0.77,0,1.06c0.15,0.15,0.34,0.22,0.53,0.22 s0.38-0.07,0.53-0.22l0.73-0.73c1.11,0.91,2.48,1.51,3.98,1.66v1.02c0,0.41,0.34,0.75,0.75,0.75s0.75-0.34,0.75-0.75v-1.02 c1.48-0.14,2.86-0.71,4.01-1.65l0.73,0.73c0.15,0.15,0.34,0.22,0.53,0.22c0.19,0,0.38-0.07,0.53-0.22c0.29-0.29,0.29-0.77,0-1.06 l-0.72-0.72c0.94-1.14,1.51-2.52,1.66-4h1.03c0.41,0,0.75-0.34,0.75-0.75S20.9,11.26,20.49,11.26z M12,18c-3.31,0-6-2.69-6-6 s2.69-6,6-6s6,2.69,6,6S15.31,18,12,18z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_location.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_location.xml index 26aa3086ff06..133ccea15c5b 100644 --- a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_location.xml +++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_location.xml @@ -1,31 +1,21 @@ + <!-- -/** - * 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. - */ + 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="#FFFFFF" - android:pathData="M15,10a3,3,0,1,0-3,3A3,3,0,0,0,15,10Zm-4.5,0A1.5,1.5,0,1,1,12,11.5,1.5,1.5,0,0,1,10.5,10Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M11.37,21.76A1,1,0,0,0,12,22a1,1,0,0,0,0.62-0.22C14.5,20.26,20,15.5,20,10a8,8,0,0,0-8-8,7.89,7.89,0,0,0-8,8C4,15.5,9.48,20.25,11.37,21.76ZM12,3.51A6.5,6.5,0,0,1,18.5,10c0,4.4-4.31,8.53-6.5,10.34C9.82,18.54,5.5,14.4,5.5,10A6.43,6.43,0,0,1,12,3.51Z" /> -</vector> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M12,7c-1.66,0-3,1.34-3,3s1.34,3,3,3s3-1.34,3-3S13.66,7,12,7z M12,11.5c-0.83,0-1.5-0.67-1.5-1.5s0.67-1.5,1.5-1.5 s1.5,0.67,1.5,1.5S12.83,11.5,12,11.5z"/> + <path android:fillColor="@android:color/white" android:pathData="M12,2.01c-4.5,0-8,3.49-8,8c0,5.49,5.48,10.24,7.37,11.76c0.19,0.15,0.41,0.22,0.63,0.22c0.22,0,0.44-0.07,0.62-0.22 C14.5,20.26,20,15.5,20,10C20,5.72,16.5,2.01,12,2.01z M12,20.34c-2.18-1.8-6.5-5.94-6.5-10.34c0-3.64,2.86-6.5,6.5-6.5 c3.58,0,6.5,2.91,6.5,6.49C18.5,14.4,14.19,18.53,12,20.34z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_privacy.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_privacy.xml index a6619bdcdb06..df9be5de492f 100644 --- a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_privacy.xml +++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_privacy.xml @@ -1,34 +1,22 @@ + <!-- -/** - * 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. - */ + 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="#FFFFFF" - android:pathData="M12,8a4,4,0,0,0,0,8,3.94,3.94,0,0,0,2.23-0.68,5.06,5.06,0,0,1,1.67-2.47A4,4,0,0,0,16,12,4,4,0,0,0,12,8Zm0,6.5A2.5,2.5,0,1,1,14.5,12,2.5,2.5,0,0,1,12,14.5Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M1.55,12.27C1.67,12.58,4.58,20,12,20a10.57,10.57,0,0,0,2-0.21V18.27a8.44,8.44,0,0,1-2,0.23c-5.72,0-8.37-5.22-8.94-6.5C3.63,10.75,6.33,5.5,12,5.5s8.38,5.22,9,6.5l-0.06 0.12 a4.84,4.84,0,0,1,1.28 0.8 c0.17-0.36 0.27 -0.6 0.29 -0.65a0.72 0.72 ,0,0,0,0-0.54C22.34,11.42,19.43,4,12,4S1.67,11.42,1.55,11.73A0.72 0.72 ,0,0,0,1.55,12.27Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M21.25,16.5v-0.66a2.26,2.26,0,0,0-4.5,0v0.66H16V22h6V16.5Zm-3,0v-0.66c0-0.29 0.38 -0.59 0.75 -0.59s0.75 0.3 0.75 0.59 v0.66Z" /> -</vector> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M12,8c-2.21,0-4,1.79-4,4s1.79,4,4,4c0.76,0,1.46-0.22,2.06-0.59c0.16-1.38,0.88-2.59,1.94-3.39c0-0.01,0-0.02,0-0.02 C16,9.79,14.21,8,12,8z M12,14.5c-1.38,0-2.5-1.12-2.5-2.5s1.12-2.5,2.5-2.5c1.38,0,2.5,1.12,2.5,2.5S13.38,14.5,12,14.5z"/> + <path android:fillColor="@android:color/white" android:pathData="M3.09,12C3.73,10.81,6.43,6.5,12,6.5c4.53,0,7.14,2.79,8.31,4.5h1.77C21.1,9.28,18.05,5,12,5c-7.4,0-10.32,6.42-10.44,6.7 c-0.09,0.19-0.09,0.41,0,0.61C1.68,12.58,4.61,19,12,19c0.71,0,1.37-0.07,2-0.18V17.3c-0.62,0.13-1.28,0.2-2,0.2 C6.39,17.5,3.73,13.21,3.09,12z"/> + <path android:fillColor="@android:color/white" android:pathData="M21,16c0-0.35,0-0.72,0-1c0-1.1-0.9-2-2-2c-1.1,0-2,0.9-2,2c0,0.37,0,0.7,0,1c-0.55,0-1,0.45-1,1v3c0,0.55,0.45,1,1,1h4 c0.55,0,1-0.45,1-1v-3C22,16.45,21.55,16,21,16z M20,16h-2v-1c0-0.55,0.45-1,1-1s1,0.45,1,1V16z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_security_white.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_security_white.xml index d769f4f5e8d4..a45e41649078 100644 --- a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_security_white.xml +++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_security_white.xml @@ -1,31 +1,21 @@ + <!-- -/** - * 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. - */ + 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="#FFFFFF" - android:pathData="M 12 13.5 C 12.8284271247 13.5 13.5 14.1715728753 13.5 15 C 13.5 15.8284271247 12.8284271247 16.5 12 16.5 C 11.1715728753 16.5 10.5 15.8284271247 10.5 15 C 10.5 14.1715728753 11.1715728753 13.5 12 13.5 Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M18.51,3A2.32,2.32,0,0,1,21,5.15a0.79 0.79 ,0,0,0,0.76 0.74 0.75 0.75 ,0,0,0,0.74-0.77,3.8,3.8,0,0,0-4-3.66,3.83,3.83,0,0,0-4,3.68V8.5h-9A1.5,1.5,0,0,0,4,10V20a1.5,1.5,0,0,0,1.5,1.5h13A1.5,1.5,0,0,0,20,20V10a1.5,1.5,0,0,0-1.5-1.5H16V5.15A2.35,2.35,0,0,1,18.51,3Zm0,17H5.5V10h13Z" /> -</vector> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M 12 13.5 C 12.8284271247 13.5 13.5 14.1715728753 13.5 15 C 13.5 15.8284271247 12.8284271247 16.5 12 16.5 C 11.1715728753 16.5 10.5 15.8284271247 10.5 15 C 10.5 14.1715728753 11.1715728753 13.5 12 13.5 Z"/> + <path android:fillColor="@android:color/white" android:pathData="M18.51,1.46c-2.19-0.06-3.98,1.61-4.01,3.68V8.5h-9C4.67,8.5,4,9.17,4,10v10c0,0.83,0.67,1.5,1.5,1.5h13 c0.83,0,1.5-0.67,1.5-1.5V10c0-0.83-0.67-1.5-1.5-1.5H16V5.15c0.02-1.23,1.14-2.23,2.51-2.19C19.9,2.93,20.98,3.92,21,5.15 c0.01,0.41,0.36,0.71,0.76,0.74c0.41-0.01,0.74-0.35,0.74-0.76C22.46,3.07,20.7,1.39,18.51,1.46z M18.5,10v10h-13V10H18.5z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_system_dashboard_white.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_system_dashboard_white.xml index ee990f92dc46..00a95234eb51 100644 --- a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_system_dashboard_white.xml +++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_system_dashboard_white.xml @@ -1,34 +1,22 @@ + <!-- -/** - * 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. - */ + 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="#FFFFFF" - android:pathData="M19.07,4.93A10,10,0,1,0,22,12,10,10,0,0,0,19.07,4.93ZM18,18a8.5,8.5,0,1,1,2.5-6A8.53,8.53,0,0,1,18,18Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M12,10a0.76 0.76 ,0,0,0-0.75 0.75 v5.5a0.75 0.75 ,0,0,0,1.5,0v-5.5A0.76 0.76 ,0,0,0,12,10Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M 12 7 C 12.5522847498 7 13 7.44771525017 13 8 C 13 8.55228474983 12.5522847498 9 12 9 C 11.4477152502 9 11 8.55228474983 11 8 C 11 7.44771525017 11.4477152502 7 12 7 Z" /> -</vector> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M4.92,4.94c-3.9,3.91-3.9,10.24,0.01,14.14s10.24,3.9,14.14-0.01C20.95,17.2,22,14.65,22,12c0-2.65-1.06-5.19-2.93-7.07 C15.16,1.03,8.83,1.03,4.92,4.94z M18,18c-1.6,1.59-3.76,2.48-6.02,2.48c-4.69-0.01-8.49-3.83-8.48-8.52 c0.01-4.69,3.83-8.49,8.52-8.48c4.69,0.01,8.49,3.83,8.48,8.52C20.49,14.25,19.6,16.41,18,18z"/> + <path android:fillColor="@android:color/white" android:pathData="M 12 7 C 12.5522847498 7 13 7.44771525017 13 8 C 13 8.55228474983 12.5522847498 9 12 9 C 11.4477152502 9 11 8.55228474983 11 8 C 11 7.44771525017 11.4477152502 7 12 7 Z"/> + <path android:fillColor="@android:color/white" android:pathData="M12,10.5c-0.41,0-0.75,0.34-0.75,0.75v5c0,0.41,0.34,0.75,0.75,0.75s0.75-0.34,0.75-0.75v-5 C12.75,10.84,12.41,10.5,12,10.5z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_wireless_white.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_wireless_white.xml index ffd2c64a6909..2e8032849759 100644 --- a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_wireless_white.xml +++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_wireless_white.xml @@ -1,37 +1,23 @@ + <!-- -/** - * 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. - */ + 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="#FFFFFF" - android:pathData="M15.78,14.82a0.57 0.57 ,0,0,0,0.16 0.15 0.75 0.75 ,0,0,0,1-0.2 0.76 0.76,0,0,0-0.2-1,6.77,6.77,0,0,0-9.55,0,0.76 0.76 ,0,0,0,0,1,0.75 0.75 ,0,0,0,1.06,0h0a5.24,5.24,0,0,1,7.42,0A0.08 0.08 ,0,0,0,15.78,14.82Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M 12 17 C 12.8284271247 17 13.5 17.6715728753 13.5 18.5 C 13.5 19.3284271247 12.8284271247 20 12 20 C 11.1715728753 20 10.5 19.3284271247 10.5 18.5 C 10.5 17.6715728753 11.1715728753 17 12 17 Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M20,11.79a0.77 0.77 ,0,0,0,0-1.07h0a11.59,11.59,0,0,0-8-3.5,11.63,11.63,0,0,0-8,3.5 0.77 0.77,0,0,0,0,1.07 0.76 0.76,0,0,0,1.07,0,10.12,10.12,0,0,1,7-3,10.12,10.12,0,0,1,7,3A0.75 0.75 ,0,0,0,20,11.79Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M12,2.75A14.76,14.76,0,0,0,1.22,7.2a0.77 0.77 ,0,0,0,0,1,0.75 0.75 ,0,0,0,1.06,0,13.25,13.25,0,0,1,9.7-4,13.27,13.27,0,0,1,9.72,4,0.73 0.73 ,0,0,0,1,0,0.75 0.75 ,0,0,0,0.05-1.06A14.76,14.76,0,0,0,12,2.75Z" /> -</vector> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M12,2.75C7.95,2.69,4.05,4.3,1.22,7.2C0.96,7.5,0.97,7.95,1.24,8.23C1.53,8.53,2,8.54,2.3,8.25c2.55-2.61,6.05-4.06,9.7-4 c3.65-0.06,7.17,1.4,9.72,4.02c0.28,0.27,0.73,0.28,1.03,0.01c0.31-0.28,0.33-0.75,0.05-1.06C19.96,4.32,16.06,2.69,12,2.75z"/> + <path android:fillColor="@android:color/white" android:pathData="M15.78,14.82c0.05,0.06,0.1,0.11,0.17,0.15c0.34,0.23,0.81,0.14,1.04-0.21s0.14-0.81-0.21-1.04 c-2.64-2.64-6.91-2.64-9.55,0c-0.27,0.29-0.27,0.73,0,1.02c0.28,0.3,0.76,0.32,1.06,0.04h0.03c0,0,0,0,0.01-0.01 c2.05-2.05,5.37-2.04,7.42,0.01C15.75,14.8,15.76,14.81,15.78,14.82z"/> + <path android:fillColor="@android:color/white" android:pathData="M 12 17 C 12.8284271247 17 13.5 17.6715728753 13.5 18.5 C 13.5 19.3284271247 12.8284271247 20 12 20 C 11.1715728753 20 10.5 19.3284271247 10.5 18.5 C 10.5 17.6715728753 11.1715728753 17 12 17 Z"/> + <path android:fillColor="@android:color/white" android:pathData="M20.03,11.79c0.3-0.29,0.3-0.77,0.01-1.06h-0.01c-2.12-2.18-5.01-3.44-8.04-3.5c-3.04,0.06-5.93,1.32-8.05,3.5 c-0.29,0.3-0.28,0.77,0.01,1.06c0.3,0.29,0.77,0.28,1.06-0.01c1.85-1.88,4.36-2.96,7-3c2.62,0.05,5.11,1.13,6.95,3 C19.25,12.07,19.73,12.08,20.03,11.79z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_storage_white.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_storage_white.xml index e6125db20e7a..a2e429dd6c06 100644 --- a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_storage_white.xml +++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_storage_white.xml @@ -1,43 +1,25 @@ + <!-- -/** - * 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. - */ + 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="#FFFFFF" - android:pathData="M21,2.75A0.76 0.76 ,0,0,0,20.25,2H3.75A0.76 0.76 ,0,0,0,3,2.75v4.5A0.76 0.76 ,0,0,0,3.75,8h16.5A0.76 0.76 ,0,0,0,21,7.25ZM19.5,6.5H4.5v-3h15Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M 5.25 4.25 H 6.75 V 5.75 H 5.25 V 4.25 Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M21,9.75A0.76 0.76 ,0,0,0,20.25,9H3.75A0.76 0.76 ,0,0,0,3,9.75v4.5a0.76 0.76 ,0,0,0,0.75 0.75 h16.5a0.76 0.76 ,0,0,0,0.75-0.75ZM19.5,13.5H4.5v-3h15Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M 5.25 11.25 H 6.75 V 12.75 H 5.25 V 11.25 Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M21,21.25v-4.5a0.76 0.76 ,0,0,0-0.75-0.75H3.75a0.76 0.76 ,0,0,0-0.75 0.75 v4.5a0.76 0.76 ,0,0,0,0.75 0.75 h16.5A0.76 0.76 ,0,0,0,21,21.25Zm-1.5-0.75H4.5v-3h15Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M 5.25 18.25 H 6.75 V 19.75 H 5.25 V 18.25 Z" /> -</vector> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M20.25,2H3.75C3.34,2,3,2.34,3,2.75v4.5C3,7.66,3.34,8,3.75,8h16.5C20.66,8,21,7.66,21,7.25v-4.5C21,2.34,20.66,2,20.25,2 z M19.5,6.5h-15v-3h15V6.5z"/> + <path android:fillColor="@android:color/white" android:pathData="M 5.25 4.25 H 6.75 V 5.75 H 5.25 V 4.25 Z"/> + <path android:fillColor="@android:color/white" android:pathData="M20.25,9H3.75C3.34,9,3,9.34,3,9.75v4.5C3,14.66,3.34,15,3.75,15h16.5c0.41,0,0.75-0.34,0.75-0.75v-4.5 C21,9.34,20.66,9,20.25,9z M19.5,13.5h-15v-3h15V13.5z"/> + <path android:fillColor="@android:color/white" android:pathData="M 5.25 11.25 H 6.75 V 12.75 H 5.25 V 11.25 Z"/> + <path android:fillColor="@android:color/white" android:pathData="M20.25,16H3.75C3.34,16,3,16.34,3,16.75v4.5C3,21.66,3.34,22,3.75,22h16.5c0.41,0,0.75-0.34,0.75-0.75v-4.5 C21,16.34,20.66,16,20.25,16z M19.5,20.5h-15v-3h15V20.5z"/> + <path android:fillColor="@android:color/white" android:pathData="M 5.25 18.25 H 6.75 V 19.75 H 5.25 V 18.25 Z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_volume_up_24dp.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_volume_up_24dp.xml index 76d3e5f051c6..ca737924998a 100644 --- a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_volume_up_24dp.xml +++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_volume_up_24dp.xml @@ -1,34 +1,22 @@ + <!-- -/** - * 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. - */ + 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="#FFFFFF" - android:pathData="M5.69,16l5,5a0.77 0.77 ,0,0,0,0.53 0.22 0.75 0.75 ,0,0,0,0.29-0.06A0.74 0.74 ,0,0,0,12,20.5V3.5A0.75 0.75 ,0,0,0,10.72,3l-5,5H3.49A1.52,1.52,0,0,0,2,9.5v5A1.5,1.5,0,0,0,3.5,16ZM3.5,9.5H6a0.75 0.75 ,0,0,0,0.53-0.22l4-4V18.69l-4-4A0.75 0.75 ,0,0,0,6,14.5H3.5Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M13.52,20.64a0.77 0.77 ,0,0,0,0.73 0.56 0.63 0.63 ,0,0,0,0.19,0,9.48,9.48,0,0,0,0-18.34 0.75 0.75,0,0,0-0.92 0.53 0.76 0.76 ,0,0,0,0.54 0.92 ,8,8,0,0,1,0,15.44A0.76 0.76 ,0,0,0,13.52,20.64Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M13.85,15a0.76 0.76 ,0,0,0-0.24,1,0.78 0.78 ,0,0,0,0.64 0.35 0.83 0.83 ,0,0,0,0.4-0.11,5,5,0,0,0,1.6-6.88,5.2,5.2,0,0,0-1.6-1.6A0.75 0.75 ,0,1,0,13.85,9,3.33,3.33,0,0,1,15,10.16,3.47,3.47,0,0,1,13.85,15Z" /> -</vector> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M5.69,16l5.03,5.03c0.14,0.14,0.34,0.22,0.53,0.22c0.1,0,0.19-0.02,0.29-0.06C11.82,21.08,12,20.8,12,20.5v-17 c0-0.3-0.18-0.58-0.46-0.69c-0.28-0.11-0.6-0.05-0.82,0.16L5.69,8H3.49C2.68,8.01,2.01,8.68,2,9.5v5C2,15.33,2.67,16,3.5,16H5.69z M3.5,9.5H6c0.2,0,0.39-0.08,0.53-0.22l3.97-3.97v13.38l-3.97-3.97C6.39,14.58,6.2,14.5,6,14.5H3.5V9.5z"/> + <path android:fillColor="@android:color/white" android:pathData="M13.52,20.64c0.09,0.34,0.39,0.56,0.72,0.56c0.06,0,0.13-0.01,0.19-0.02c3.29-0.87,5.88-3.46,6.75-6.75 c1.34-5.06-1.69-10.26-6.75-11.59c-0.4-0.11-0.81,0.13-0.92,0.53c-0.11,0.4,0.13,0.81,0.53,0.92c4.26,1.13,6.8,5.5,5.68,9.76 c-0.73,2.77-2.91,4.95-5.68,5.68C13.66,19.83,13.42,20.24,13.52,20.64z"/> + <path android:fillColor="@android:color/white" android:pathData="M13.85,14.96c-0.35,0.22-0.46,0.68-0.24,1.03c0.14,0.23,0.39,0.35,0.64,0.35c0.14,0,0.27-0.04,0.4-0.11 c1.13-0.7,1.92-1.81,2.22-3.1c0.3-1.3,0.08-2.64-0.62-3.77c-0.4-0.65-0.96-1.2-1.6-1.6C14.29,7.54,13.83,7.65,13.61,8 c-0.22,0.35-0.11,0.81,0.24,1.03c0.45,0.28,0.84,0.67,1.12,1.12c0.49,0.79,0.65,1.73,0.44,2.64C15.2,13.7,14.65,14.47,13.85,14.96z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_wifi_tethering.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_wifi_tethering.xml index eadd300404a9..419710d18bfb 100644 --- a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_wifi_tethering.xml +++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_wifi_tethering.xml @@ -1,34 +1,22 @@ + <!-- -/** - * 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. - */ + 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="#FFFFFF" - android:pathData="M 12 11 C 12.8284271247 11 13.5 11.6715728753 13.5 12.5 C 13.5 13.3284271247 12.8284271247 14 12 14 C 11.1715728753 14 10.5 13.3284271247 10.5 12.5 C 10.5 11.6715728753 11.1715728753 11 12 11 Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M15,16.57a0.75 0.75 ,0,0,0,1.06,0,5.75,5.75,0,1,0-8.14,0,0.79 0.79 ,0,0,0,0.53 0.22 A0.75 0.75 ,0,0,0,9,16.57a0.74 0.74 ,0,0,0,0-1.06,4.25,4.25,0,1,1,6,0A0.75 0.75 ,0,0,0,15,16.57Z" /> - <path - android:fillColor="#FFFFFF" - android:pathData="M18.36,19.61a0.71 0.71 ,0,0,0,0.53-0.22A9.74,9.74,0,0,0,5.11,5.61a9.73,9.73,0,0,0,0,13.78 0.74 0.74,0,0,0,1.06,0,0.75 0.75 ,0,0,0,0-1.06A8.24,8.24,0,0,1,17.83,6.67a8.23,8.23,0,0,1,0,11.66 0.75 0.75,0,0,0,0,1.06A0.74 0.74 ,0,0,0,18.36,19.61Z" /> -</vector> +<vector android:height="24dp" android:tint="?android:attr/colorControlNormal" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M 12 11 C 12.8284271247 11 13.5 11.6715728753 13.5 12.5 C 13.5 13.3284271247 12.8284271247 14 12 14 C 11.1715728753 14 10.5 13.3284271247 10.5 12.5 C 10.5 11.6715728753 11.1715728753 11 12 11 Z"/> + <path android:fillColor="@android:color/white" android:pathData="M15.01,16.57c0.29,0.29,0.77,0.29,1.06,0c1.09-1.09,1.68-2.53,1.68-4.07s-0.6-2.98-1.68-4.07c-2.24-2.24-5.89-2.24-8.13,0 c-1.09,1.09-1.68,2.53-1.68,4.07s0.6,2.98,1.68,4.07c0.15,0.15,0.34,0.22,0.53,0.22s0.38-0.07,0.53-0.22 c0.29-0.29,0.29-0.77,0-1.06c-0.8-0.8-1.24-1.87-1.24-3.01c0-1.13,0.44-2.2,1.24-3c1.66-1.66,4.35-1.66,6.01,0 c0.8,0.8,1.24,1.87,1.24,3.01c0,1.13-0.44,2.2-1.24,3C14.71,15.8,14.71,16.27,15.01,16.57z"/> + <path android:fillColor="@android:color/white" android:pathData="M18.36,19.61c0.19,0,0.38-0.07,0.53-0.22c1.84-1.84,2.86-4.29,2.86-6.89s-1.01-5.05-2.86-6.89c-3.8-3.8-9.99-3.8-13.79,0 C3.26,7.45,2.25,9.9,2.25,12.5s1.01,5.05,2.86,6.89c0.29,0.29,0.77,0.29,1.06,0s0.29-0.77,0-1.06c-1.56-1.56-2.42-3.63-2.42-5.83 s0.86-4.28,2.42-5.83c3.22-3.22,8.45-3.22,11.67,0c1.56,1.56,2.42,3.63,2.42,5.83s-0.86,4.28-2.42,5.83 c-0.29,0.29-0.29,0.77,0,1.06C17.98,19.54,18.17,19.61,18.36,19.61z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_alarm.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_alarm.xml new file mode 100644 index 000000000000..e9590bf3b39c --- /dev/null +++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_alarm.xml @@ -0,0 +1,23 @@ + +<!-- + 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 android:height="17dp" android:viewportHeight="24" android:viewportWidth="24" android:width="17dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M13.93,16.02c0.15,0.15,0.34,0.22,0.53,0.22c0.19,0,0.38-0.07,0.53-0.22c0.29-0.29,0.3-0.77,0.01-1.06l-2.25-2.28V7.75 C12.75,7.34,12.41,7,12,7s-0.75,0.34-0.75,0.75V13c0,0.2,0.08,0.39,0.22,0.53L13.93,16.02z"/> + <path android:fillColor="@android:color/white" android:pathData="M16.4,2.55c-0.25,0.33-0.18,0.8,0.15,1.05l4.02,3c0.13,0.1,0.29,0.15,0.45,0.15c0.23,0,0.45-0.1,0.6-0.3 c0.25-0.33,0.18-0.8-0.15-1.05l-4.02-3C17.12,2.15,16.65,2.22,16.4,2.55z"/> + <path android:fillColor="@android:color/white" android:pathData="M2.98,6.75c0.16,0,0.31-0.05,0.45-0.15l4.02-3c0.33-0.25,0.4-0.72,0.15-1.05C7.35,2.22,6.88,2.15,6.55,2.4l-4.02,3 C2.2,5.65,2.13,6.12,2.38,6.45C2.52,6.65,2.75,6.75,2.98,6.75z"/> + <path android:fillColor="@android:color/white" android:pathData="M3.08,13c0,4.96,4,9,8.92,9c0,0,0.01,0,0.01,0c2.38,0,4.61-0.93,6.3-2.63c1.68-1.7,2.61-3.95,2.61-6.35V13 c0-4.96-4-9-8.92-9S3.08,8.04,3.08,13z M12,5.5c4.09,0,7.42,3.36,7.42,7.5v0.02c0,2-0.78,3.88-2.18,5.3 c-1.4,1.41-3.26,2.19-5.23,2.19c0,0-0.01,0-0.01,0c-4.09,0-7.42-3.36-7.42-7.5S7.91,5.5,12,5.5z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_alarm_dim.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_alarm_dim.xml new file mode 100644 index 000000000000..e9590bf3b39c --- /dev/null +++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_alarm_dim.xml @@ -0,0 +1,23 @@ + +<!-- + 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 android:height="17dp" android:viewportHeight="24" android:viewportWidth="24" android:width="17dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M13.93,16.02c0.15,0.15,0.34,0.22,0.53,0.22c0.19,0,0.38-0.07,0.53-0.22c0.29-0.29,0.3-0.77,0.01-1.06l-2.25-2.28V7.75 C12.75,7.34,12.41,7,12,7s-0.75,0.34-0.75,0.75V13c0,0.2,0.08,0.39,0.22,0.53L13.93,16.02z"/> + <path android:fillColor="@android:color/white" android:pathData="M16.4,2.55c-0.25,0.33-0.18,0.8,0.15,1.05l4.02,3c0.13,0.1,0.29,0.15,0.45,0.15c0.23,0,0.45-0.1,0.6-0.3 c0.25-0.33,0.18-0.8-0.15-1.05l-4.02-3C17.12,2.15,16.65,2.22,16.4,2.55z"/> + <path android:fillColor="@android:color/white" android:pathData="M2.98,6.75c0.16,0,0.31-0.05,0.45-0.15l4.02-3c0.33-0.25,0.4-0.72,0.15-1.05C7.35,2.22,6.88,2.15,6.55,2.4l-4.02,3 C2.2,5.65,2.13,6.12,2.38,6.45C2.52,6.65,2.75,6.75,2.98,6.75z"/> + <path android:fillColor="@android:color/white" android:pathData="M3.08,13c0,4.96,4,9,8.92,9c0,0,0.01,0,0.01,0c2.38,0,4.61-0.93,6.3-2.63c1.68-1.7,2.61-3.95,2.61-6.35V13 c0-4.96-4-9-8.92-9S3.08,8.04,3.08,13z M12,5.5c4.09,0,7.42,3.36,7.42,7.5v0.02c0,2-0.78,3.88-2.18,5.3 c-1.4,1.41-3.26,2.19-5.23,2.19c0,0-0.01,0-0.01,0c-4.09,0-7.42-3.36-7.42-7.5S7.91,5.5,12,5.5z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_bluetooth_connected.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_bluetooth_connected.xml new file mode 100644 index 000000000000..dcaba7cd26d1 --- /dev/null +++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_bluetooth_connected.xml @@ -0,0 +1,22 @@ + +<!-- + 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 android:height="17dp" android:viewportHeight="24" android:viewportWidth="24" android:width="17dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <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.97 v7.69c0,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"/> + <path android:fillColor="@android:color/white" android:pathData="M 5 11 C 5.55228474983 11 6 11.4477152502 6 12 C 6 12.5522847498 5.55228474983 13 5 13 C 4.44771525017 13 4 12.5522847498 4 12 C 4 11.4477152502 4.44771525017 11 5 11 Z"/> + <path android:fillColor="@android:color/white" android:pathData="M 19 11 C 19.5522847498 11 20 11.4477152502 20 12 C 20 12.5522847498 19.5522847498 13 19 13 C 18.4477152502 13 18 12.5522847498 18 12 C 18 11.4477152502 18.4477152502 11 19 11 Z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_brightness_thumb.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_brightness_thumb.xml index abfcfce79a9b..27a15c67f337 100644 --- a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_brightness_thumb.xml +++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_brightness_thumb.xml @@ -1,52 +1,21 @@ + <!-- -/** - * 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. - */ + 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="?android:attr/colorControlActivated" - android:pathData="M12,19.5h0A7.49,7.49,0,0,0,19.5,12h0A7.5,7.5,0,1,0,12,19.5ZM12,6a6,6,0,0,1,6,6h0a6,6,0,0,1-6,6h0A6,6,0,0,1,12,6Z" /> - <path - android:fillColor="?android:attr/colorControlActivated" - android:pathData="M11.25 0.75 v1.5a0.75 0.75 ,0,0,0,1.5,0V0.75a0.75 0.75 ,0,0,0-1.5,0Z" /> - <path - android:fillColor="?android:attr/colorControlActivated" - android:pathData="M4.58,3.51A0.76 0.76 ,0,0,0,3.51,4.58L4.57,5.64a0.79 0.79 ,0,0,0,1.07,0,0.77 0.77 ,0,0,0,0-1.07Z" /> - <path - android:fillColor="?android:attr/colorControlActivated" - android:pathData="M3,12a0.76 0.76 ,0,0,0-0.75-0.75H0.75a0.75 0.75 ,0,0,0,0,1.5h1.5A0.76 0.76 ,0,0,0,3,12Z" /> - <path - android:fillColor="?android:attr/colorControlActivated" - 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="?android:attr/colorControlActivated" - 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="?android:attr/colorControlActivated" - android:pathData="M18.36,18.36a0.77 0.77 ,0,0,0,0,1.07l1.06,1.06a0.76 0.76 ,0,0,0,1.07,0,0.77 0.77 ,0,0,0,0-1.07l-1.06-1.06A0.77 0.77 ,0,0,0,18.36,18.36Z" /> - <path - android:fillColor="?android:attr/colorControlActivated" - 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="?android:attr/colorControlActivated" - 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" /> -</vector> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="?android:attr/colorControlActivated" android:pathData="M22.46,11.25h-3.02c-0.15-1.51-0.75-2.88-1.66-4l2.17-2.17c0.29-0.29,0.29-0.77,0-1.06s-0.77-0.29-1.06,0l-2.18,2.18 c-1.11-0.91-2.49-1.51-3.99-1.66V1.5c0-0.41-0.34-0.75-0.75-0.75s-0.75,0.34-0.75,0.75v3.04c-1.5,0.15-2.88,0.75-3.99,1.65 L5.06,4.01C4.77,3.71,4.29,3.71,4,4.01S3.71,4.77,4,5.07l2.18,2.18c-0.91,1.11-1.51,2.48-1.66,3.98H1.48 c-0.41,0-0.75,0.34-0.75,0.75s0.34,0.75,0.75,0.75h3.04c0.15,1.51,0.74,2.88,1.65,3.99L3.99,18.9c-0.29,0.29-0.29,0.77,0,1.06 c0.15,0.15,0.34,0.22,0.53,0.22s0.38-0.07,0.53-0.22l2.17-2.17c1.11,0.91,2.49,1.52,3.99,1.67v3.02c0,0.41,0.34,0.75,0.75,0.75 s0.75-0.34,0.75-0.75v-3.02c1.48-0.14,2.86-0.71,4.01-1.65l2.16,2.16c0.15,0.15,0.34,0.22,0.53,0.22s0.38-0.07,0.53-0.22 c0.29-0.29,0.29-0.77,0-1.06l-2.16-2.16c0.94-1.15,1.52-2.53,1.66-4.01h3.02c0.41,0,0.75-0.34,0.75-0.75S22.88,11.25,22.46,11.25z M12,18c-3.31,0-6-2.69-6-6s2.69-6,6-6s6,2.69,6,6S15.31,18,12,18z"/> + <path android:fillColor="?android:attr/colorPrimary" android:pathData="M 12 6 C 15.313708499 6 18 8.68629150102 18 12 C 18 15.313708499 15.313708499 18 12 18 C 8.68629150102 18 6 15.313708499 6 12 C 6 8.68629150102 8.68629150102 6 12 6 Z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_camera.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_camera.xml new file mode 100644 index 000000000000..ab73718b6d4a --- /dev/null +++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_camera.xml @@ -0,0 +1,21 @@ + +<!-- + 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 android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M22,7c0-1.1-0.9-2-2-2h-3l-1.41-1.41C15.21,3.21,14.7,3,14.17,3H9.83C9.3,3,8.79,3.21,8.41,3.59L7,5H4C2.9,5,2,5.9,2,7v12 c0,1.1,0.9,2,2,2h16c1.1,0,2-0.9,2-2V7z M20.5,19c0,0.28-0.22,0.5-0.5,0.5H4c-0.28,0-0.5-0.22-0.5-0.5V7c0-0.28,0.22-0.5,0.5-0.5 h3.62l1.85-1.85C9.57,4.55,9.69,4.5,9.83,4.5h4.34c0.13,0,0.26,0.05,0.35,0.15l1.85,1.85H20c0.28,0,0.5,0.22,0.5,0.5V19z"/> + <path android:fillColor="@android:color/white" android:pathData="M12,9c-2.21,0-4,1.79-4,4c0,2.21,1.79,4,4,4c2.21,0,4-1.79,4-4C16,10.79,14.21,9,12,9z M12,15.5c-1.38,0-2.5-1.12-2.5-2.5 c0-1.38,1.12-2.5,2.5-2.5c1.38,0,2.5,1.12,2.5,2.5C14.5,14.38,13.38,15.5,12,15.5z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_cast.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_cast.xml new file mode 100644 index 000000000000..b1107af38752 --- /dev/null +++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_cast.xml @@ -0,0 +1,23 @@ + +<!-- + 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 android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M2.75,14.25C2.34,14.25,2,14.59,2,15s0.34,0.75,0.75,0.75c1.93,0,3.5,1.57,3.5,3.5C6.25,19.66,6.59,20,7,20 s0.75-0.34,0.75-0.75C7.75,16.49,5.51,14.25,2.75,14.25z"/> + <path android:fillColor="@android:color/white" android:pathData="M3.25,17.5h0.03C3.27,17.5,3.26,17.5,3.25,17.5C2.56,17.5,2,18.06,2,18.75C2,19.44,2.56,20,3.25,20s1.25-0.56,1.25-1.25 S3.94,17.5,3.25,17.5z"/> + <path android:fillColor="@android:color/white" android:pathData="M20.5,4h-17C3.49,4,3.48,4,3.47,4C2.64,4.02,1.98,4.7,2,5.53v3.18c0,0.41,0.34,0.75,0.75,0.75S3.5,9.12,3.5,8.71 c0-1.96,0-3.21,0-3.21l17,0.03V18.5h-7.35c-0.41,0-0.75,0.34-0.75,0.75S12.74,20,13.15,20h7.35c0.01,0,0.02,0,0.03,0 c0.83-0.02,1.49-0.7,1.47-1.53V5.53c0-0.01,0-0.02,0-0.03C22,4.67,21.33,4,20.5,4z"/> + <path android:fillColor="@android:color/white" android:pathData="M2.75,11C2.34,11,2,11.34,2,11.75s0.34,0.75,0.75,0.75c3.73,0,6.75,3.02,6.75,6.75c0,0.41,0.34,0.75,0.75,0.75 S11,19.66,11,19.25C11,14.69,7.31,11,2.75,11z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_cast_connected.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_cast_connected.xml new file mode 100644 index 000000000000..548a65a38910 --- /dev/null +++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_cast_connected.xml @@ -0,0 +1,24 @@ + +<!-- + 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 android:height="17dp" android:viewportHeight="24" android:viewportWidth="24" android:width="17dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M20.5,4h-17C3.49,4,3.48,4,3.47,4C2.64,4.02,1.98,4.7,2,5.53v3.18c0,0.41,0.34,0.75,0.75,0.75S3.5,9.12,3.5,8.71 c0-1.96,0-3.21,0-3.21l17,0.03V18.5h-7.35c-0.41,0-0.75,0.34-0.75,0.75S12.74,20,13.15,20h7.35c0.01,0,0.02,0,0.03,0 c0.83-0.02,1.49-0.7,1.47-1.53V5.53c0-0.01,0-0.02,0-0.03C22,4.67,21.33,4,20.5,4z"/> + <path android:fillColor="@android:color/white" android:pathData="M3.25,17.5h0.03C3.27,17.5,3.26,17.5,3.25,17.5C2.56,17.5,2,18.06,2,18.75C2,19.44,2.56,20,3.25,20s1.25-0.56,1.25-1.25 S3.94,17.5,3.25,17.5z"/> + <path android:fillColor="@android:color/white" android:pathData="M2.75,11C2.34,11,2,11.34,2,11.75s0.34,0.75,0.75,0.75c3.73,0,6.75,3.02,6.75,6.75c0,0.41,0.34,0.75,0.75,0.75 S11,19.66,11,19.25C11,14.69,7.31,11,2.75,11z"/> + <path android:fillColor="@android:color/white" android:pathData="M2.75,14.25C2.34,14.25,2,14.59,2,15s0.34,0.75,0.75,0.75c1.93,0,3.5,1.57,3.5,3.5C6.25,19.66,6.59,20,7,20 s0.75-0.34,0.75-0.75C7.75,16.49,5.51,14.25,2.75,14.25z"/> + <path android:fillColor="@android:color/white" android:pathData="M13.25,15.5c-0.41,0-0.75,0.34-0.75,0.75S12.84,17,13.25,17h5c0.41,0,0.75-0.34,0.75-0.75v-8.5C19,7.34,18.66,7,18.25,7 H5.75C5.34,7,5,7.34,5,7.75v1C5,9.16,5.34,9.5,5.75,9.5S6.5,9.16,6.5,8.75V8.5h11v7H13.25z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_close_white.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_close_white.xml new file mode 100644 index 000000000000..2243cabca5e6 --- /dev/null +++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_close_white.xml @@ -0,0 +1,20 @@ + +<!-- + 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 android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M18.78,5.22c-0.29-0.29-0.77-0.29-1.06,0L12,10.94L6.28,5.22c-0.29-0.29-0.77-0.29-1.06,0s-0.29,0.77,0,1.06L10.94,12 l-5.72,5.72c-0.29,0.29-0.29,0.77,0,1.06C5.37,18.93,5.56,19,5.75,19s0.38-0.07,0.53-0.22L12,13.06l5.72,5.72 c0.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.06L13.06,12l5.72-5.72 C19.07,5.99,19.07,5.51,18.78,5.22z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_data_saver.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_data_saver.xml new file mode 100644 index 000000000000..bbb4df0ce764 --- /dev/null +++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_data_saver.xml @@ -0,0 +1,22 @@ + +<!-- + 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 android:height="18dp " android:viewportHeight="24" android:viewportWidth="24" android:width="18dp " xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M3.36,7A10,10,0,0,0,20.27,17.64L18.1,16.39A7.5,7.5,0,1,1,11.25,4.56V2.05A10,10,0,0,0,3.36,7Z"/> + <path android:fillColor="@android:color/white" android:pathData="M21,16.35a10,10,0,0,0-8.27-14.3V4.56a7.48,7.48,0,0,1,6.1,10.54Z"/> + <path android:fillColor="@android:color/white" android:pathData="M8,12a0.76 0.76 ,0,0,0,0.75 0.75 h2.5v2.5a0.75 0.75 ,0,0,0,1.5,0v-2.5h2.5a0.75 0.75 ,0,0,0,0-1.5h-2.5V8.75a0.75 0.75 ,0,0,0-1.5,0v2.5H8.75A0.76 0.76 ,0,0,0,8,12Z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_data_saver_off.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_data_saver_off.xml index 1158b2761a51..2921dd8a06d0 100644 --- a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_data_saver_off.xml +++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_data_saver_off.xml @@ -1,34 +1,21 @@ + <!-- -/** - * 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. - */ + 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,12a10,10,0,0,0-9-9.95v3A7,7,0,0,1,19,12a7.12,7.12,0,0,1-0.48,2.54h0l2.6,1.53A9.88,9.88,0,0,0,22,12Z" /> - <path - android:fillColor="#000000" - android:pathData="M2.09,13.39a10,10,0,0,0,18,4.52l-2.6-1.53h0A7,7,0,1,1,11,5.08v-3A10,10,0,0,0,2.09,13.39Z" /> - <path - android:fillColor="#000000" - android:pathData="M11.25,8v3.25H8a0.75 0.75 ,0,0,0,0,1.5h3.25V16a0.75 0.75 ,0,0,0,1.5,0V12.75H16a0.75 0.75 ,0,0,0,0-1.5H12.75V8a0.75 0.75 ,0,0,0-1.5,0Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M3.36,7A10,10,0,0,0,20.27,17.64L18.1,16.39A7.5,7.5,0,1,1,11.25,4.56V2.05A10,10,0,0,0,3.36,7Z"/> + <path android:fillColor="@android:color/white" android:pathData="M21,16.35a10,10,0,0,0-8.27-14.3V4.56a7.48,7.48,0,0,1,6.1,10.54Z"/> </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_drag_handle.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_drag_handle.xml index 915597e170e6..31c1c4ed3c5b 100644 --- a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_drag_handle.xml +++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_drag_handle.xml @@ -1,31 +1,21 @@ + <!-- -/** - * 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. - */ + 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="M4,10.5H20A0.75 0.75 ,0,0,0,20,9H4a0.75 0.75 ,0,0,0,0,1.5Z" /> - <path - android:fillColor="#000000" - android:pathData="M4,15H20a0.75 0.75 ,0,0,0,0-1.5H4A0.75 0.75 ,0,0,0,4,15Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M5.75,10.5h12.5c0.41,0,0.75-0.34,0.75-0.75S18.66,9,18.25,9H5.75C5.34,9,5,9.34,5,9.75S5.34,10.5,5.75,10.5z"/> + <path android:fillColor="@android:color/white" android:pathData="M18.25,13.5H5.75C5.34,13.5,5,13.84,5,14.25S5.34,15,5.75,15h12.5c0.41,0,0.75-0.34,0.75-0.75S18.66,13.5,18.25,13.5z"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_headset.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_headset.xml index 264e2122aa50..409fac3d4acf 100644 --- a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_headset.xml +++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_headset.xml @@ -1,28 +1,20 @@ + <!-- -/** - * 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. - */ + 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="M21.5,18V11.5C21.5,5.82,17.68,2,12,2S2.5,5.82,2.5,11.5V18a3,3,0,0,0,3,3H7a1.5,1.5,0,0,0,1.5-1.5V14A1.5,1.5,0,0,0,7,12.5H4v-1c0-4.86,3.14-8,8-8s8,3.14,8,8v1H17A1.5,1.5,0,0,0,15.5,14v5.5A1.5,1.5,0,0,0,17,21h1.5A3,3,0,0,0,21.5,18ZM7,19.5H5.5A1.5,1.5,0,0,1,4,18V14H7ZM20,18a1.5,1.5,0,0,1-1.5,1.5H17V14h3Z" /> +<vector android:height="17dp" android:viewportHeight="24" android:viewportWidth="24" android:width="17dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M14.75,2.01h-5.5c-3.72,0-6.75,3.03-6.75,6.75v3.74v1V18c0,1.66,1.34,3,3,3H7c0.83,0,1.5-0.67,1.5-1.5V14 c0-0.83-0.67-1.5-1.5-1.5H4V8.76c0-2.9,2.36-5.25,5.25-5.25h5.5c2.89,0,5.25,2.35,5.25,5.25v3.74h-3c-0.83,0-1.5,0.67-1.5,1.5v5.5 c0,0.83,0.67,1.5,1.5,1.5h1.5c1.66,0,3-1.34,3-3v-4.5v-1V8.76C21.5,5.04,18.47,2.01,14.75,2.01z M7,19.5H5.5 C4.67,19.5,4,18.83,4,18v-4h3V19.5z M20,18c0,0.83-0.67,1.5-1.5,1.5H17V14h3V18z"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_headset_mic.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_headset_mic.xml new file mode 100644 index 000000000000..74318aea5906 --- /dev/null +++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_headset_mic.xml @@ -0,0 +1,20 @@ + +<!-- + 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 android:height="17dp" android:viewportHeight="24" android:viewportWidth="24" android:width="17dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M14.75,1.01h-5.5c-3.72,0-6.75,3.03-6.75,6.75V17c0,1.66,1.34,3,3,3H7c0.83,0,1.5-0.67,1.5-1.5V13c0-0.83-0.67-1.5-1.5-1.5 H4V7.76c0-2.89,2.35-5.25,5.25-5.25h5.5c2.9,0,5.25,2.36,5.25,5.25v3.74h-3c-0.83,0-1.5,0.67-1.5,1.5v5.5c0,0.83,0.67,1.5,1.5,1.5 h1.5c0.53,0,1.03-0.15,1.46-0.4c-0.17,1.07-1.09,1.9-2.21,1.9h-5c-0.41,0-0.75,0.34-0.75,0.75S12.34,23,12.75,23h5 c2.07,0,3.75-1.68,3.75-3.75V7.76C21.5,4.04,18.47,1.01,14.75,1.01z M7,18.5H5.5C4.67,18.5,4,17.83,4,17v-4h3V18.5z M18.5,18.5H17 V13h3v4C20,17.83,19.33,18.5,18.5,18.5z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_hotspot.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_hotspot.xml index ae78a147afd6..7aca4d71b993 100644 --- a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_hotspot.xml +++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_hotspot.xml @@ -1,34 +1,22 @@ + <!-- -/** - * 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. - */ + 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="M 12 11 C 12.8284271247 11 13.5 11.6715728753 13.5 12.5 C 13.5 13.3284271247 12.8284271247 14 12 14 C 11.1715728753 14 10.5 13.3284271247 10.5 12.5 C 10.5 11.6715728753 11.1715728753 11 12 11 Z" /> - <path - android:fillColor="#000000" - android:pathData="M15,16.57a0.75 0.75 ,0,0,0,1.06,0,5.75,5.75,0,1,0-8.14,0,0.79 0.79 ,0,0,0,0.53 0.22 A0.75 0.75 ,0,0,0,9,16.57a0.74 0.74 ,0,0,0,0-1.06,4.25,4.25,0,1,1,6,0A0.75 0.75 ,0,0,0,15,16.57Z" /> - <path - android:fillColor="#000000" - android:pathData="M18.36,19.61a0.71 0.71 ,0,0,0,0.53-0.22A9.74,9.74,0,0,0,5.11,5.61a9.73,9.73,0,0,0,0,13.78 0.74 0.74,0,0,0,1.06,0,0.75 0.75 ,0,0,0,0-1.06A8.24,8.24,0,0,1,17.83,6.67a8.23,8.23,0,0,1,0,11.66 0.75 0.75,0,0,0,0,1.06A0.74 0.74 ,0,0,0,18.36,19.61Z" /> +<vector android:height="18dp" android:viewportHeight="24" android:viewportWidth="24" android:width="18dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M 12 11 C 12.8284271247 11 13.5 11.6715728753 13.5 12.5 C 13.5 13.3284271247 12.8284271247 14 12 14 C 11.1715728753 14 10.5 13.3284271247 10.5 12.5 C 10.5 11.6715728753 11.1715728753 11 12 11 Z"/> + <path android:fillColor="@android:color/white" android:pathData="M15.01,16.57c0.29,0.29,0.77,0.29,1.06,0c1.09-1.09,1.68-2.53,1.68-4.07s-0.6-2.98-1.68-4.07c-2.24-2.24-5.89-2.24-8.13,0 c-1.09,1.09-1.68,2.53-1.68,4.07s0.6,2.98,1.68,4.07c0.15,0.15,0.34,0.22,0.53,0.22s0.38-0.07,0.53-0.22 c0.29-0.29,0.29-0.77,0-1.06c-0.8-0.8-1.24-1.87-1.24-3.01c0-1.13,0.44-2.2,1.24-3c1.66-1.66,4.35-1.66,6.01,0 c0.8,0.8,1.24,1.87,1.24,3.01c0,1.13-0.44,2.2-1.24,3C14.71,15.8,14.71,16.27,15.01,16.57z"/> + <path android:fillColor="@android:color/white" android:pathData="M18.36,19.61c0.19,0,0.38-0.07,0.53-0.22c1.84-1.84,2.86-4.29,2.86-6.89s-1.01-5.05-2.86-6.89c-3.8-3.8-9.99-3.8-13.79,0 C3.26,7.45,2.25,9.9,2.25,12.5s1.01,5.05,2.86,6.89c0.29,0.29,0.77,0.29,1.06,0s0.29-0.77,0-1.06c-1.56-1.56-2.42-3.63-2.42-5.83 s0.86-4.28,2.42-5.83c3.22-3.22,8.45-3.22,11.67,0c1.56,1.56,2.42,3.63,2.42,5.83s-0.86,4.28-2.42,5.83 c-0.29,0.29-0.29,0.77,0,1.06C17.98,19.54,18.17,19.61,18.36,19.61z"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_info.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_info.xml index 642ac421fe99..00a95234eb51 100644 --- a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_info.xml +++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_info.xml @@ -1,34 +1,22 @@ + <!-- -/** - * 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. - */ + 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="M19.07,4.93A10,10,0,1,0,22,12,10,10,0,0,0,19.07,4.93ZM18,18a8.5,8.5,0,1,1,2.5-6A8.53,8.53,0,0,1,18,18Z" /> - <path - android:fillColor="#000000" - android:pathData="M12,10a0.76 0.76 ,0,0,0-0.75 0.75 v5.5a0.75 0.75 ,0,0,0,1.5,0v-5.5A0.76 0.76 ,0,0,0,12,10Z" /> - <path - android:fillColor="#000000" - android:pathData="M 12 7 C 12.5522847498 7 13 7.44771525017 13 8 C 13 8.55228474983 12.5522847498 9 12 9 C 11.4477152502 9 11 8.55228474983 11 8 C 11 7.44771525017 11.4477152502 7 12 7 Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M4.92,4.94c-3.9,3.91-3.9,10.24,0.01,14.14s10.24,3.9,14.14-0.01C20.95,17.2,22,14.65,22,12c0-2.65-1.06-5.19-2.93-7.07 C15.16,1.03,8.83,1.03,4.92,4.94z M18,18c-1.6,1.59-3.76,2.48-6.02,2.48c-4.69-0.01-8.49-3.83-8.48-8.52 c0.01-4.69,3.83-8.49,8.52-8.48c4.69,0.01,8.49,3.83,8.48,8.52C20.49,14.25,19.6,16.41,18,18z"/> + <path android:fillColor="@android:color/white" android:pathData="M 12 7 C 12.5522847498 7 13 7.44771525017 13 8 C 13 8.55228474983 12.5522847498 9 12 9 C 11.4477152502 9 11 8.55228474983 11 8 C 11 7.44771525017 11.4477152502 7 12 7 Z"/> + <path android:fillColor="@android:color/white" android:pathData="M12,10.5c-0.41,0-0.75,0.34-0.75,0.75v5c0,0.41,0.34,0.75,0.75,0.75s0.75-0.34,0.75-0.75v-5 C12.75,10.84,12.41,10.5,12,10.5z"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_info_outline.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_info_outline.xml new file mode 100644 index 000000000000..00a95234eb51 --- /dev/null +++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_info_outline.xml @@ -0,0 +1,22 @@ + +<!-- + 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 android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M4.92,4.94c-3.9,3.91-3.9,10.24,0.01,14.14s10.24,3.9,14.14-0.01C20.95,17.2,22,14.65,22,12c0-2.65-1.06-5.19-2.93-7.07 C15.16,1.03,8.83,1.03,4.92,4.94z M18,18c-1.6,1.59-3.76,2.48-6.02,2.48c-4.69-0.01-8.49-3.83-8.48-8.52 c0.01-4.69,3.83-8.49,8.52-8.48c4.69,0.01,8.49,3.83,8.48,8.52C20.49,14.25,19.6,16.41,18,18z"/> + <path android:fillColor="@android:color/white" android:pathData="M 12 7 C 12.5522847498 7 13 7.44771525017 13 8 C 13 8.55228474983 12.5522847498 9 12 9 C 11.4477152502 9 11 8.55228474983 11 8 C 11 7.44771525017 11.4477152502 7 12 7 Z"/> + <path android:fillColor="@android:color/white" android:pathData="M12,10.5c-0.41,0-0.75,0.34-0.75,0.75v5c0,0.41,0.34,0.75,0.75,0.75s0.75-0.34,0.75-0.75v-5 C12.75,10.84,12.41,10.5,12,10.5z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_invert_colors.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_invert_colors.xml new file mode 100644 index 000000000000..347c2bd6511c --- /dev/null +++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_invert_colors.xml @@ -0,0 +1,20 @@ + +<!-- + 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 android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M12.62,2.23c-0.18-0.15-0.4-0.22-0.62-0.22c-0.22,0-0.45,0.08-0.63,0.22C9.48,3.75,4,8.5,4,13.99c0,4.51,3.5,8,8,8 s8-3.71,8-7.99C20,8.5,14.5,3.73,12.62,2.23z M5.5,13.99c0-4.4,4.32-8.53,6.5-10.34v16.83C8.36,20.49,5.5,17.64,5.5,13.99z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_location.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_location.xml new file mode 100644 index 000000000000..b4ea6b434d03 --- /dev/null +++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_location.xml @@ -0,0 +1,21 @@ + +<!-- + 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 android:height="17dp" android:viewportHeight="24" android:viewportWidth="24" android:width="17dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M12,7c-1.66,0-3,1.34-3,3s1.34,3,3,3s3-1.34,3-3S13.66,7,12,7z M12,11.5c-0.83,0-1.5-0.67-1.5-1.5s0.67-1.5,1.5-1.5 s1.5,0.67,1.5,1.5S12.83,11.5,12,11.5z"/> + <path android:fillColor="@android:color/white" android:pathData="M12,2.01c-4.5,0-8,3.49-8,8c0,5.49,5.48,10.24,7.37,11.76c0.19,0.15,0.41,0.22,0.63,0.22c0.22,0,0.44-0.07,0.62-0.22 C14.5,20.26,20,15.5,20,10C20,5.72,16.5,2.01,12,2.01z M12,20.34c-2.18-1.8-6.5-5.94-6.5-10.34c0-3.64,2.86-6.5,6.5-6.5 c3.58,0,6.5,2.91,6.5,6.49C18.5,14.4,14.19,18.53,12,20.34z"/> +</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 index 7897fa3a40a9..6b91dcdef907 100644 --- a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_lockscreen_ime.xml +++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_lockscreen_ime.xml @@ -1,55 +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. - */ + 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 android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M21,4H3C1.9,4,1,4.9,1,6v13c0,1.1,0.9,2,2,2h18c1.1,0,2-0.9,2-2V6C23,4.9,22.1,4,21,4z M21.5,19c0,0.27-0.23,0.5-0.5,0.5 H3c-0.27,0-0.5-0.23-0.5-0.5V6c0-0.27,0.23-0.5,0.5-0.5h18c0.27,0,0.5,0.23,0.5,0.5V19z"/> + <path android:fillColor="@android:color/white" android:pathData="M9.5,10h1c0.28,0,0.5-0.22,0.5-0.5v-1C11,8.22,10.78,8,10.5,8h-1C9.22,8,9,8.22,9,8.5v1C9,9.78,9.22,10,9.5,10z"/> + <path android:fillColor="@android:color/white" android:pathData="M6.5,8h-1C5.22,8,5,8.22,5,8.5v1C5,9.78,5.22,10,5.5,10h1C6.78,10,7,9.78,7,9.5v-1C7,8.22,6.78,8,6.5,8z"/> + <path android:fillColor="@android:color/white" android:pathData="M15.25,16h-6.5C8.34,16,8,16.34,8,16.75c0,0.41,0.34,0.75,0.75,0.75h6.5c0.41,0,0.75-0.34,0.75-0.75 C16,16.34,15.66,16,15.25,16z"/> + <path android:fillColor="@android:color/white" android:pathData="M13.5,10h1c0.28,0,0.5-0.22,0.5-0.5v-1C15,8.22,14.78,8,14.5,8h-1C13.22,8,13,8.22,13,8.5v1C13,9.78,13.22,10,13.5,10z"/> + <path android:fillColor="@android:color/white" android:pathData="M9.5,14h1c0.28,0,0.5-0.22,0.5-0.5v-1c0-0.28-0.22-0.5-0.5-0.5h-1C9.22,12,9,12.22,9,12.5v1C9,13.78,9.22,14,9.5,14z"/> + <path android:fillColor="@android:color/white" android:pathData="M6.5,12h-1C5.22,12,5,12.22,5,12.5v1C5,13.78,5.22,14,5.5,14h1C6.78,14,7,13.78,7,13.5v-1C7,12.22,6.78,12,6.5,12z"/> + <path android:fillColor="@android:color/white" android:pathData="M13.5,14h1c0.28,0,0.5-0.22,0.5-0.5v-1c0-0.28-0.22-0.5-0.5-0.5h-1c-0.28,0-0.5,0.22-0.5,0.5v1C13,13.78,13.22,14,13.5,14 z"/> + <path android:fillColor="@android:color/white" android:pathData="M18.5,8h-1C17.22,8,17,8.22,17,8.5v1c0,0.28,0.22,0.5,0.5,0.5h1c0.28,0,0.5-0.22,0.5-0.5v-1C19,8.22,18.78,8,18.5,8z"/> + <path android:fillColor="@android:color/white" android:pathData="M18.5,12h-1c-0.28,0-0.5,0.22-0.5,0.5v1c0,0.28,0.22,0.5,0.5,0.5h1c0.28,0,0.5-0.22,0.5-0.5v-1C19,12.22,18.78,12,18.5,12 z"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_notifications_alert.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_notifications_alert.xml index 74311e783e99..bfd820f20fee 100644 --- a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_notifications_alert.xml +++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_notifications_alert.xml @@ -1,37 +1,23 @@ + <!-- -/** - * 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. - */ + 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="M14,20H10a2,2,0,0,0,4,0Z" /> - <path - android:fillColor="#000000" - android:pathData="M12,2.5a1.25,1.25,0,0,0-1.25,1.25v0.78A6,6,0,0,0,6,10.4V17H4.75a0.75 0.75 ,0,0,0,0,1.5h14.5a0.75 0.75 ,0,0,0,0-1.5H18V10.4a6,6,0,0,0-4.75-5.87V3.75A1.25,1.25,0,0,0,12,2.5Zm4.5,7.9V17h-9V10.4a4.5,4.5,0,1,1,9,0Z" /> - <path - android:fillColor="#000000" - android:pathData="M5.85,3A9.49,9.49,0,0,0,2.5,10.25a0.75 0.75 ,0,0,0,1.5,0,8,8,0,0,1,2.82-6.1A0.75 0.75 ,0,1,0,5.85,3Z" /> - <path - android:fillColor="#000000" - android:pathData="M18.15,3a0.75 0.75 ,0,1,0-1,1.14A8,8,0,0,1,20,10.25a0.75 0.75 ,0,0,0,1.5,0A9.49,9.49,0,0,0,18.15,3Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M14,20h-4c0,1.1,0.9,2,2,2S14,21.1,14,20z"/> + <path android:fillColor="@android:color/white" android:pathData="M12,2.5c-0.69,0-1.25,0.56-1.25,1.25v0.77C8.04,5.11,6,7.51,6,10.4V17H4.75C4.34,17,4,17.34,4,17.75s0.34,0.75,0.75,0.75 h14.5c0.41,0,0.75-0.34,0.75-0.75S19.66,17,19.25,17H18v-6.6c0-2.88-2.04-5.29-4.75-5.87V3.75C13.25,3.06,12.69,2.5,12,2.5z M16.5,10.4V17h-9v-6.6c0-2.48,2.02-4.5,4.5-4.5S16.5,7.91,16.5,10.4z"/> + <path android:fillColor="@android:color/white" android:pathData="M5.85,3.01C3.72,4.82,2.5,7.46,2.5,10.25C2.5,10.66,2.84,11,3.25,11S4,10.66,4,10.25c0-2.35,1.03-4.57,2.82-6.1 C7.14,3.88,7.17,3.41,6.91,3.1C6.64,2.78,6.17,2.74,5.85,3.01z"/> + <path android:fillColor="@android:color/white" android:pathData="M18.15,3.01c-0.32-0.27-0.79-0.23-1.06,0.08c-0.27,0.32-0.23,0.79,0.08,1.06C18.97,5.68,20,7.9,20,10.25 c0,0.41,0.34,0.75,0.75,0.75s0.75-0.34,0.75-0.75C21.5,7.46,20.28,4.82,18.15,3.01z"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_notifications_silence.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_notifications_silence.xml index a93c45b2cc68..b70f9ed74746 100644 --- a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_notifications_silence.xml +++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_notifications_silence.xml @@ -1,34 +1,22 @@ + <!-- -/** - * 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. - */ + 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="M14,20H10a2,2,0,0,0,4,0Z" /> - <path - android:fillColor="#000000" - android:pathData="M12,5.9a4.5,4.5,0,0,1,4.5,4.5v3.92l1.5,1.5V10.4a6,6,0,0,0-4.75-5.87V3.75a1.25,1.25,0,0,0-2.5,0v0.78A5.92,5.92,0,0,0,8.06,5.88L9.14,7A4.45,4.45,0,0,1,12,5.9Z" /> - <path - android:fillColor="#000000" - android:pathData="M21,22A0.75 0.75 ,0,0,0,21,21L3,3A0.75 0.75 ,0,0,0,2,3H2A0.75 0.75 ,0,0,0,2,4L6.35,8.41a6,6,0,0,0-0.35,2V17H4.75a0.75 0.75 ,0,0,0,0,1.5H16.44L20,22A0.75 0.75 ,0,0,0,21,22ZM7.5,17V10.4a3.84,3.84,0,0,1,0.08-0.76L14.94,17Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M14,20h-4c0,1.1,0.9,2,2,2S14,21.1,14,20z"/> + <path android:fillColor="@android:color/white" android:pathData="M12,5.9c2.48,0,4.5,2.02,4.5,4.5v3.92l1.5,1.5V10.4c0-2.88-2.04-5.29-4.75-5.87V3.75c0-0.69-0.56-1.25-1.25-1.25 s-1.25,0.56-1.25,1.25v0.77C9.73,4.74,8.82,5.22,8.06,5.88l1.08,1.08C9.92,6.3,10.91,5.9,12,5.9z"/> + <path android:fillColor="@android:color/white" android:pathData="M21.03,22.03c0.29-0.29,0.29-0.77,0-1.06l-18-18c-0.29-0.29-0.77-0.29-1.06,0c0,0,0,0,0,0c-0.29,0.29-0.29,0.77,0,1.06 l4.38,4.37C6.13,9.03,6,9.7,6,10.4V17H4.75C4.34,17,4,17.34,4,17.75s0.34,0.75,0.75,0.75h11.69l3.53,3.53 c0.15,0.15,0.34,0.22,0.53,0.22S20.88,22.18,21.03,22.03C21.03,22.03,21.03,22.03,21.03,22.03z M7.5,17v-6.6 c0-0.26,0.03-0.51,0.08-0.76L14.94,17H7.5z"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_power_low.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_power_low.xml new file mode 100644 index 000000000000..c6c713fa3af6 --- /dev/null +++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_power_low.xml @@ -0,0 +1,22 @@ + +<!-- + 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 android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M12,14.5c0.41,0,0.75-0.34,0.75-0.75v-5C12.75,8.34,12.41,8,12,8s-0.75,0.34-0.75,0.75v5C11.25,14.16,11.59,14.5,12,14.5z"/> + <path android:fillColor="@android:color/white" android:pathData="M 12.01 16 C 12.5622847498 16 13.01 16.4477152502 13.01 17 C 13.01 17.5522847498 12.5622847498 18 12.01 18 C 11.4577152502 18 11.01 17.5522847498 11.01 17 C 11.01 16.4477152502 11.4577152502 16 12.01 16 Z"/> + <path android:fillColor="@android:color/white" android:pathData="M17,4h-3V3.49c0-0.55-0.45-1-1-1h-2c-0.55,0-1,0.45-1,1V4H7C6.45,4,6,4.45,6,5v16c0,0.55,0.45,1,1,1h10c0.55,0,1-0.45,1-1 V5C18,4.45,17.55,4,17,4z M16.5,20.5h-9v-15h9V20.5z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_power_saver.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_power_saver.xml new file mode 100644 index 000000000000..e2669d948e87 --- /dev/null +++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_power_saver.xml @@ -0,0 +1,21 @@ + +<!-- + 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 android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M9.74,13.75h1.5v1.5c0,0.41,0.34,0.75,0.75,0.75s0.75-0.34,0.75-0.75v-1.5h1.5c0.41,0,0.75-0.34,0.75-0.75 s-0.34-0.75-0.75-0.75h-1.5v-1.5c0-0.41-0.34-0.75-0.75-0.75s-0.75,0.34-0.75,0.75v1.5h-1.5c-0.41,0-0.75,0.34-0.75,0.75 S9.33,13.75,9.74,13.75z"/> + <path android:fillColor="@android:color/white" android:pathData="M17,4h-3V3.49c0-0.55-0.45-1-1-1h-2c-0.55,0-1,0.45-1,1V4H7C6.45,4,6,4.45,6,5v16c0,0.55,0.45,1,1,1h10c0.55,0,1-0.45,1-1 V5C18,4.45,17.55,4,17,4z M16.5,20.5h-9v-15h9V20.5z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_auto_rotate.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_auto_rotate.xml deleted file mode 100644 index fe7ecfd9d615..000000000000 --- a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_auto_rotate.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="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" /> -</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_bluetooth_connecting.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_bluetooth_connecting.xml index 70282d4a2c13..739c1102aa86 100644 --- a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_bluetooth_connecting.xml +++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_bluetooth_connecting.xml @@ -1,34 +1,22 @@ + <!-- -/** - * 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. - */ + 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="M4.47,17.78a0.75 0.75 ,0,0,0,1.06,0l4-4V21.5a0.74 0.74 ,0,0,0,0.46 0.69 0.75 0.75 ,0,0,0,0.29 0.06 0.77 0.77 ,0,0,0,0.53-0.22l4.75-4.75a0.75 0.75 ,0,0,0,0-1.06L11.31,12l4.22-4.22a0.75 0.75 ,0,0,0,0-1.06L10.78,2A0.75 0.75 ,0,0,0,10,1.81a0.74 0.74 ,0,0,0-0.46 0.69 v7.69l-4-4A0.75 0.75 ,0,0,0,4.47,7.28L9.19,12,4.47,16.72A0.75 0.75 ,0,0,0,4.47,17.78ZM11,4.31l2.94,2.94L11,10.19Zm0,9.5,2.94,2.94L11,19.69Z" /> - <path - android:fillColor="#000000" - android:pathData="M 16 11 C 16.5522847498 11 17 11.4477152502 17 12 C 17 12.5522847498 16.5522847498 13 16 13 C 15.4477152502 13 15 12.5522847498 15 12 C 15 11.4477152502 15.4477152502 11 16 11 Z" /> - <path - android:fillColor="#000000" - android:pathData="M18.55,16.37a0.74 0.74 ,0,0,0,0.45 0.15 0.77 0.77 ,0,0,0,0.6-0.3,7,7,0,0,0,0-8.42 0.76 0.76,0,0,0-1.05-0.15 0.75 0.75,0,0,0-0.15,1,5.53,5.53,0,0,1,0,6.62A0.75 0.75 ,0,0,0,18.55,16.37Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M11.31,12l4.22-4.22c0.29-0.29,0.29-0.77,0-1.06l-4.75-4.75c-0.21-0.21-0.54-0.28-0.82-0.16C9.68,1.92,9.5,2.2,9.5,2.5 v7.69L5.53,6.22c-0.29-0.29-0.77-0.29-1.06,0s-0.29,0.77,0,1.06L9.19,12l-4.72,4.72c-0.29,0.29-0.29,0.77,0,1.06s0.77,0.29,1.06,0 l3.97-3.97v7.69c0,0.3,0.18,0.58,0.46,0.69c0.09,0.04,0.19,0.06,0.29,0.06c0.19,0,0.39-0.08,0.53-0.22l4.75-4.75 c0.29-0.29,0.29-0.77,0-1.06L11.31,12z M11,4.31l2.94,2.94L11,10.19V4.31z M11,19.69v-5.88l2.94,2.94L11,19.69z"/> + <path android:fillColor="@android:color/white" android:pathData="M 16 11 C 16.5522847498 11 17 11.4477152502 17 12 C 17 12.5522847498 16.5522847498 13 16 13 C 15.4477152502 13 15 12.5522847498 15 12 C 15 11.4477152502 15.4477152502 11 16 11 Z"/> + <path android:fillColor="@android:color/white" android:pathData="M19.6,7.8c-0.25-0.33-0.72-0.4-1.05-0.15c-0.33,0.25-0.4,0.72-0.15,1.05c0.72,0.96,1.1,2.1,1.1,3.31 c0,1.2-0.38,2.35-1.1,3.31c-0.25,0.33-0.18,0.8,0.15,1.05c0.13,0.1,0.29,0.15,0.45,0.15c0.23,0,0.45-0.1,0.6-0.3 C20.52,15,21,13.54,21,12.01S20.52,9.02,19.6,7.8z"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_bluetooth_on.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_bluetooth_on.xml index dfef14b226c2..f2e6050d97ac 100644 --- a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_bluetooth_on.xml +++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_bluetooth_on.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.53,6.72,12.78,2a0.75 0.75 ,0,0,0-1.28 0.53 v7.69l-4-4A0.75 0.75 ,0,0,0,6.47,7.28L11.19,12,6.47,16.72a0.75 0.75 ,0,0,0,1.06,1.06l4-4V21.5a0.74 0.74 ,0,0,0,0.46 0.69 0.74 0.74 ,0,0,0,0.82-0.16l4.75-4.75a0.75 0.75 ,0,0,0,0-1.06L13.31,12l4.22-4.22A0.75 0.75 ,0,0,0,17.53,6.72Zm-1.59,10L13,19.69V13.81ZM13,10.19V4.31l2.94,2.94Z" /> + android:fillColor="#FFFFFF" + 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/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_cancel.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_cancel.xml index cc819a0d71c8..9ee53c2e73c8 100644 --- a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_cancel.xml +++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_cancel.xml @@ -1,31 +1,21 @@ + <!-- -/** - * 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. - */ + 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,2A10,10,0,1,0,22,12,10,10,0,0,0,12,2Zm0,18.5A8.5,8.5,0,1,1,20.5,12,8.51,8.51,0,0,1,12,20.5Z" /> - <path - android:fillColor="#000000" - android:pathData="M16.6,7.4a0.75 0.75 ,0,0,0-1.06,0L12,10.94,8.46,7.4A0.75 0.75 ,0,0,0,7.4,8.46L10.94,12,7.4,15.54a0.75 0.75 ,0,0,0,0,1.06 0.79 0.79,0,0,0,0.53 0.22 0.75 0.75 ,0,0,0,0.53-0.22L12,13.06l3.54,3.54a0.75 0.75 ,0,0,0,0.53 0.22 0.79 0.79 ,0,0,0,0.53-0.22 0.75 0.75,0,0,0,0-1.06L13.06,12,16.6,8.46A0.75 0.75 ,0,0,0,16.6,7.4Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M12,2C6.48,2,2,6.48,2,12s4.48,10,10,10c5.52,0,10-4.48,10-10S17.52,2,12,2z M12,20.5c-4.69,0-8.5-3.81-8.5-8.5 c0-4.69,3.81-8.5,8.5-8.5c4.69,0,8.5,3.81,8.5,8.5C20.5,16.69,16.69,20.5,12,20.5z"/> + <path android:fillColor="@android:color/white" android:pathData="M13.01,11.95l2.76-2.66c0.3-0.29,0.31-0.76,0.02-1.06c-0.29-0.3-0.76-0.31-1.06-0.02l-2.78,2.68L9.28,8.22 c-0.29-0.29-0.77-0.29-1.06,0s-0.29,0.77,0,1.06l2.65,2.65l-2.89,2.78c-0.3,0.29-0.31,0.76-0.02,1.06C8.11,15.92,8.3,16,8.5,16 c0.19,0,0.37-0.07,0.52-0.21l2.91-2.8l2.79,2.79c0.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.06 L13.01,11.95z"/> </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_qs_no_sim.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_no_sim.xml index 7020463cb3a9..f39c2c07da60 100644 --- a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_no_sim.xml +++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_no_sim.xml @@ -1,31 +1,21 @@ + <!-- -/** - * 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. - */ + 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.62,4.5H17a0.5 0.5 ,0,0,1,0.5 0.5 V15.32l1.5,1.5V5a2,2,0,0,0-2-2H10L7.59,5.41,8.65,6.47Z" /> - <path - android:fillColor="#000000" - android:pathData="M21,21,3,3A0.75 0.75 ,0,0,0,2,3H2A0.75 0.75 ,0,0,0,2,4l3.5,3.5L5,8V19a2,2,0,0,0,2,2H17a2,2,0,0,0,1.38-0.56L20,22A0.75 0.75 ,0,0,0,21,22h0A0.75 0.75 ,0,0,0,21,21ZM17,19.5H7a0.5 0.5 ,0,0,1-0.5-0.5V8.62l0,0L17.32,19.38A0.53 0.53 ,0,0,1,17,19.5Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M10.62,4.5H17c0.28,0,0.5,0.22,0.5,0.5v10.32l1.5,1.5V5c0-1.1-0.9-2-2-2h-7L7.59,5.41l1.06,1.06L10.62,4.5z"/> + <path android:fillColor="@android:color/white" android:pathData="M21.03,20.97l-18-18c-0.29-0.29-0.77-0.29-1.06,0c0,0,0,0,0,0c-0.29,0.29-0.29,0.77,0,1.06l3.5,3.5L5,8v11c0,1.1,0.9,2,2,2 h10c0.54,0,1.02-0.21,1.38-0.56l1.59,1.59c0.15,0.15,0.34,0.22,0.53,0.22s0.38-0.07,0.53-0.22c0,0,0,0,0,0 C21.32,21.74,21.32,21.26,21.03,20.97z M17,19.5H7c-0.28,0-0.5-0.22-0.5-0.5V8.62l0.03-0.03l10.79,10.79 C17.23,19.45,17.12,19.5,17,19.5z"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_vpn.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_vpn.xml deleted file mode 100644 index 65c56f831462..000000000000 --- a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_vpn.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="M21,9.5H11.37a5.25,5.25,0,1,0,0,5H14.5v1A1.5,1.5,0,0,0,16,17h2.5A1.5,1.5,0,0,0,20,15.5v-1h1A1.5,1.5,0,0,0,22.5,13V11A1.5,1.5,0,0,0,21,9.5ZM21,13H18.5v2.5H16V13H10.4l-0.19 0.46 A3.75,3.75,0,1,1,6.09,8.31a3.57,3.57,0,0,1,0.65-0.06,3.76,3.76,0,0,1,3.47,2.29l0.19 0.46 H21Z" /> - <path - android:fillColor="#000000" - android:pathData="M6.75,9.75A2.25,2.25,0,1,0,9,12,2.25,2.25,0,0,0,6.75,9.75Zm0,3A0.75 0.75 ,0,1,1,7.5,12,0.76 0.76 ,0,0,1,6.75,12.75Z" /> -</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_wifi_0.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_wifi_0.xml index ff02c59c1fe7..793bae597226 100644 --- a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_wifi_0.xml +++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_wifi_0.xml @@ -1,52 +1,21 @@ + <!-- -/** - * 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. - */ + 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:fillAlpha="0.3" - android:strokeAlpha="0.3" - android:strokeWidth="1" - android:pathData="M21.7,8.3a0.83 0.83 ,0,0,0,1.05,0l0,0a0.73 0.73 ,0,0,0,0-1A14.51,14.51,0,0,0,12,2.8,14.77,14.77,0,0,0,1.25,7.25a0.76 0.76 ,0,0,0,0,1.05l0,0a0.72 0.72 ,0,0,0,1,0,13.34,13.34,0,0,1,9.7-4A13.16,13.16,0,0,1,21.7,8.3Z" /> - <path - android:fillColor="#000000" - android:fillAlpha="0.3" - android:strokeAlpha="0.3" - android:strokeWidth="1" - android:pathData="M19,11.8a0.74 0.74 ,0,0,0,1.05-1.05,11.43,11.43,0,0,0-8-3.5,11.36,11.36,0,0,0-8,3.5 0.74 0.74,0,0,0,1,1.05,9.93,9.93,0,0,1,7-3A10.15,10.15,0,0,1,19,11.8Z" /> - <path - android:fillColor="#000000" - android:fillAlpha="0.3" - android:strokeAlpha="0.3" - android:strokeWidth="1" - android:pathData="M7.25,13.75a0.76 0.76 ,0,0,0,0,1l0,0a0.73 0.73 ,0,0,0,1,0,5.28,5.28,0,0,1,6.2-0.9,3.87,3.87,0,0,1,1.57-0.78A6.73,6.73,0,0,0,7.25,13.75Z" /> - <path - android:fillColor="#000000" - android:pathData="M21.92,16.08a0.74 0.74 ,0,0,0-1.06,0L19,17.94l-1.86-1.86a0.75 0.75 ,0,0,0-1.06,1.06L17.94,19l-1.86,1.86a0.74 0.74 ,0,0,0,0,1.06 0.73 0.73,0,0,0,0.53 0.22 0.74 0.74 ,0,0,0,0.53-0.22L19,20.06l1.86,1.86a0.74 0.74 ,0,0,0,0.53 0.22 0.73 0.73 ,0,0,0,0.53-0.22 0.74 0.74,0,0,0,0-1.06L20.06,19l1.86-1.86A0.74 0.74 ,0,0,0,21.92,16.08Z" /> - <path - android:fillColor="#000000" - android:fillAlpha="0.3" - android:strokeAlpha="0.3" - android:strokeWidth="1" - android:pathData="M13.5,18.5a1.5,1.5,0,0,0-0.5-1.11,1.5,1.5,0,1,0,0,2.22A1.5,1.5,0,0,0,13.5,18.5Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillAlpha="0.3" android:fillColor="@android:color/white" android:pathData="M13,18.42l-1,1.22L2.01,7.48C4.74,4.91,8.29,3.5,12,3.5s7.26,1.41,9.98,3.98L18.27,12h1.94l2.93-3.57 c0.5-0.61,0.45-1.51-0.13-2.05C20.12,3.66,16.25,2,12,2C7.75,2,3.88,3.66,0.99,6.38C0.41,6.92,0.36,7.82,0.86,8.43l10.37,12.63 c0.2,0.24,0.49,0.37,0.77,0.37s0.57-0.12,0.77-0.37L13,20.78V18.42z" android:strokeAlpha="0.3" android:strokeWidth="1"/> + <path android:fillColor="@android:color/white" android:pathData="M19.56,17.5l2.22-2.22c0.29-0.29,0.29-0.77,0-1.06s-0.77-0.29-1.06,0l-2.22,2.22l-2.22-2.22c-0.29-0.29-0.77-0.29-1.06,0 s-0.29,0.77,0,1.06l2.22,2.22l-2.22,2.22c-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.22 l2.22-2.22l2.22,2.22c0.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.06L19.56,17.5z"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_wifi_1.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_wifi_1.xml index 6a645a38c807..4893b48921b6 100644 --- a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_wifi_1.xml +++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_wifi_1.xml @@ -1,49 +1,21 @@ + <!-- -/** - * 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. - */ + 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:fillAlpha="0.3" - android:strokeAlpha="0.3" - android:strokeWidth="1" - android:pathData="M7.23,13.71a0.75 0.75 ,0,0,0,1.06,1.06,5.23,5.23,0,0,1,6.22-0.88,4,4,0,0,1,1.57-0.78A6.75,6.75,0,0,0,7.23,13.71Z" /> - <path - android:fillColor="#000000" - android:fillAlpha="0.3" - android:strokeAlpha="0.3" - android:strokeWidth="1" - android:pathData="M19,11.77a0.75 0.75 ,0,0,0,1.06,0,0.77 0.77 ,0,0,0,0-1.07h0a11.59,11.59,0,0,0-8-3.5,11.63,11.63,0,0,0-8,3.5 0.75 0.75,0,0,0-0.1,1.06 0.74 0.74,0,0,0,1,0.1A0.38 0.38 ,0,0,0,5,11.77a10.12,10.12,0,0,1,7-3A10.1,10.1,0,0,1,19,11.77Z" /> - <path - android:fillColor="#000000" - android:fillAlpha="0.3" - android:strokeAlpha="0.3" - android:strokeWidth="1" - android:pathData="M21.72,8.27a0.75 0.75 ,0,0,0,1.07-1A14.76,14.76,0,0,0,12,2.75,14.76,14.76,0,0,0,1.22,7.2a0.76 0.76 ,0,0,0,0.05,1.06 0.76 0.76,0,0,0,1,0,13.25,13.25,0,0,1,9.7-4A13.27,13.27,0,0,1,21.72,8.27Z" /> - <path - android:fillColor="#000000" - android:pathData="M21.92,16.08a0.74 0.74 ,0,0,0-1.06,0L19,17.94l-1.86-1.86a0.75 0.75 ,0,0,0-1.06,1.06L17.94,19l-1.86,1.86a0.74 0.74 ,0,0,0,0,1.06 0.73 0.73,0,0,0,0.53 0.22 0.74 0.74 ,0,0,0,0.53-0.22L19,20.06l1.86,1.86a0.74 0.74 ,0,0,0,0.53 0.22 0.73 0.73 ,0,0,0,0.53-0.22 0.74 0.74,0,0,0,0-1.06L20.06,19l1.86-1.86A0.74 0.74 ,0,0,0,21.92,16.08Z" /> - <path - android:fillColor="#000000" - android:pathData="M13.5,18.5a1.5,1.5,0,0,0-0.5-1.11,1.5,1.5,0,1,0,0,2.22A1.5,1.5,0,0,0,13.5,18.5Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillAlpha="0.3" android:fillColor="@android:color/white" android:pathData="M13,13.11c-0.32-0.08-0.66-0.12-1-0.12c-1.4,0-2.65,0.64-3.47,1.64c-0.11,0.13-0.21,0.27-0.3,0.41L2.01,7.48 C4.74,4.91,8.29,3.5,12,3.5s7.26,1.41,9.98,3.98L18.27,12h1.94l2.93-3.57c0.5-0.61,0.45-1.51-0.13-2.05C20.12,3.66,16.25,2,12,2 C7.75,2,3.88,3.66,0.99,6.38C0.41,6.92,0.36,7.82,0.86,8.43l6.72,8.19c0,0,0,0,0,0l4.41,5.37H12l1-1.21V13.11z" android:strokeAlpha="0.3" android:strokeWidth="1"/> + <path android:fillColor="@android:color/white" android:pathData="M19.56,17.5l2.22-2.22c0.29-0.29,0.29-0.77,0-1.06s-0.77-0.29-1.06,0l-2.22,2.22l-2.22-2.22c-0.29-0.29-0.77-0.29-1.06,0 s-0.29,0.77,0,1.06l2.22,2.22l-2.22,2.22c-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.22 l2.22-2.22l2.22,2.22c0.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.06L19.56,17.5z"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_wifi_2.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_wifi_2.xml index b2207f9f7976..4757f0fa80ec 100644 --- a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_wifi_2.xml +++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_wifi_2.xml @@ -1,46 +1,21 @@ + <!-- -/** - * 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. - */ + 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.23,13.71a0.75 0.75 ,0,0,0,1.06,1.06,5.23,5.23,0,0,1,6.22-0.88,4,4,0,0,1,1.57-0.78A6.75,6.75,0,0,0,7.23,13.71Z" /> - <path - android:fillColor="#000000" - android:fillAlpha="0.3" - android:strokeAlpha="0.3" - android:strokeWidth="1" - android:pathData="M21.72,8.27a0.75 0.75 ,0,0,0,1.07-1A14.76,14.76,0,0,0,12,2.75,14.76,14.76,0,0,0,1.22,7.2a0.76 0.76 ,0,0,0,0.05,1.06 0.76 0.76,0,0,0,1,0,13.25,13.25,0,0,1,9.7-4A13.27,13.27,0,0,1,21.72,8.27Z" /> - <path - android:fillColor="#000000" - android:fillAlpha="0.3" - android:strokeAlpha="0.3" - android:strokeWidth="1" - android:pathData="M19,11.77a0.75 0.75 ,0,0,0,1.06,0,0.77 0.77 ,0,0,0,0-1.07h0a11.59,11.59,0,0,0-8-3.5,11.63,11.63,0,0,0-8,3.5 0.75 0.75,0,0,0-0.1,1.06 0.74 0.74,0,0,0,1,0.1A0.38 0.38 ,0,0,0,5,11.77a10.12,10.12,0,0,1,7-3A10.1,10.1,0,0,1,19,11.77Z" /> - <path - android:fillColor="#000000" - android:pathData="M21.92,16.08a0.74 0.74 ,0,0,0-1.06,0L19,17.94l-1.86-1.86a0.75 0.75 ,0,0,0-1.06,1.06L17.94,19l-1.86,1.86a0.74 0.74 ,0,0,0,0,1.06 0.73 0.73,0,0,0,0.53 0.22 0.74 0.74 ,0,0,0,0.53-0.22L19,20.06l1.86,1.86a0.74 0.74 ,0,0,0,0.53 0.22 0.73 0.73 ,0,0,0,0.53-0.22 0.74 0.74,0,0,0,0-1.06L20.06,19l1.86-1.86A0.74 0.74 ,0,0,0,21.92,16.08Z" /> - <path - android:fillColor="#000000" - android:pathData="M13.5,18.5a1.5,1.5,0,0,0-0.5-1.11,1.5,1.5,0,1,0,0,2.22A1.5,1.5,0,0,0,13.5,18.5Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillAlpha="0.3" android:fillColor="@android:color/white" android:pathData="M13,12h4.08c-1.33-1.24-3.12-2.01-5.08-2.01c-2.12,0-4.03,0.88-5.39,2.3c-0.12,0.12-0.22,0.26-0.33,0.39 l-4.27-5.2C4.74,4.91,8.29,3.5,12,3.5s7.26,1.41,9.98,3.98L18.27,12h1.94l2.93-3.57c0.5-0.61,0.45-1.51-0.13-2.05 C20.12,3.66,16.25,2,12,2C7.75,2,3.88,3.66,0.99,6.38C0.41,6.92,0.36,7.82,0.86,8.43l10.37,12.63c0.2,0.24,0.49,0.37,0.77,0.37 s0.57-0.12,0.77-0.37L13,20.78v0V12z" android:strokeAlpha="0.3" android:strokeWidth="1"/> + <path android:fillColor="@android:color/white" android:pathData="M21.78,14.22c-0.29-0.29-0.77-0.29-1.06,0l-2.22,2.22l-2.22-2.22c-0.29-0.29-0.77-0.29-1.06,0s-0.29,0.77,0,1.06l2.22,2.22 l-2.22,2.22c-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.22l2.22-2.22l2.22,2.22 c0.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-2.22-2.22l2.22-2.22 C22.07,14.99,22.07,14.51,21.78,14.22z"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_wifi_3.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_wifi_3.xml index 6dd92a031963..6d9059d8ee94 100644 --- a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_wifi_3.xml +++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_wifi_3.xml @@ -1,43 +1,21 @@ + <!-- -/** - * 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. - */ + 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.23,13.71a0.75 0.75 ,0,0,0,1.06,1.06,5.23,5.23,0,0,1,6.22-0.88,4,4,0,0,1,1.57-0.78A6.75,6.75,0,0,0,7.23,13.71Z" /> - <path - android:fillColor="#000000" - android:fillAlpha="0.3" - android:strokeAlpha="0.3" - android:strokeWidth="1" - android:pathData="M21.72,8.27a0.75 0.75 ,0,0,0,1.07-1A14.76,14.76,0,0,0,12,2.75,14.76,14.76,0,0,0,1.22,7.2a0.76 0.76 ,0,0,0,0.05,1.06 0.76 0.76,0,0,0,1,0,13.25,13.25,0,0,1,9.7-4A13.27,13.27,0,0,1,21.72,8.27Z" /> - <path - android:fillColor="#000000" - android:pathData="M19,11.77a0.75 0.75 ,0,0,0,1.06,0,0.77 0.77 ,0,0,0,0-1.07h0a11.59,11.59,0,0,0-8-3.5,11.63,11.63,0,0,0-8,3.5 0.75 0.75,0,0,0-0.1,1.06 0.74 0.74,0,0,0,1,0.1A0.38 0.38 ,0,0,0,5,11.77a10.12,10.12,0,0,1,7-3A10.1,10.1,0,0,1,19,11.77Z" /> - <path - android:fillColor="#000000" - android:pathData="M21.92,16.08a0.74 0.74 ,0,0,0-1.06,0L19,17.94l-1.86-1.86a0.75 0.75 ,0,0,0-1.06,1.06L17.94,19l-1.86,1.86a0.74 0.74 ,0,0,0,0,1.06 0.73 0.73,0,0,0,0.53 0.22 0.74 0.74 ,0,0,0,0.53-0.22L19,20.06l1.86,1.86a0.74 0.74 ,0,0,0,0.53 0.22 0.73 0.73 ,0,0,0,0.53-0.22 0.74 0.74,0,0,0,0-1.06L20.06,19l1.86-1.86A0.74 0.74 ,0,0,0,21.92,16.08Z" /> - <path - android:fillColor="#000000" - android:pathData="M13.5,18.5a1.5,1.5,0,0,0-0.5-1.11,1.5,1.5,0,1,0,0,2.22A1.5,1.5,0,0,0,13.5,18.5Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillAlpha="0.3" android:fillColor="@android:color/white" android:pathData="M13,12h7.21c0,0,0.49-0.59,0.49-0.59l2.44-2.98c0.5-0.61,0.45-1.51-0.13-2.05C20.12,3.66,16.25,2,12,2 C7.75,2,3.88,3.66,0.99,6.38C0.41,6.92,0.36,7.82,0.86,8.43l2.44,2.98c0,0,0,0,0,0l7.93,9.65c0,0,0,0,0,0l0,0 c0.2,0.24,0.49,0.37,0.77,0.37s0.57-0.12,0.77-0.37L13,20.78V12z M4.65,9.9c-0.03,0.02-0.36,0.35-0.36,0.35L2.01,7.48 C4.74,4.91,8.29,3.5,12,3.5s7.26,1.41,9.98,3.98l-2.28,2.77c-0.09-0.09-0.33-0.33-0.36-0.35C17.43,8.1,14.86,6.99,12,6.99 S6.57,8.1,4.65,9.9z" android:strokeAlpha="0.3" android:strokeWidth="1"/> + <path android:fillColor="@android:color/white" android:pathData="M19.56,17.5l2.22-2.22c0.29-0.29,0.29-0.77,0-1.06s-0.77-0.29-1.06,0l-2.22,2.22l-2.22-2.22c-0.29-0.29-0.77-0.29-1.06,0 s-0.29,0.77,0,1.06l2.22,2.22l-2.22,2.22c-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.22 l2.22-2.22l2.22,2.22c0.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.06L19.56,17.5z"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_wifi_4.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_wifi_4.xml index 13b00699346c..a7d504869b9a 100644 --- a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_wifi_4.xml +++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_wifi_4.xml @@ -1,40 +1,21 @@ + <!-- -/** - * 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. - */ + 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.23,13.71a0.75 0.75 ,0,0,0,1.06,1.06,5.23,5.23,0,0,1,6.22-0.88,4,4,0,0,1,1.57-0.78A6.75,6.75,0,0,0,7.23,13.71Z" /> - <path - android:fillColor="#000000" - android:pathData="M2.3,8.25a13.25,13.25,0,0,1,9.7-4,13.27,13.27,0,0,1,9.72,4,0.75 0.75 ,0,0,0,1.07-1A14.76,14.76,0,0,0,12,2.75,14.76,14.76,0,0,0,1.22,7.2a0.76 0.76 ,0,0,0,0.05,1.06A0.76 0.76 ,0,0,0,2.3,8.25Z" /> - <path - android:fillColor="#000000" - android:pathData="M19,11.77a0.75 0.75 ,0,0,0,1.06,0,0.77 0.77 ,0,0,0,0-1.07h0a11.59,11.59,0,0,0-8-3.5,11.63,11.63,0,0,0-8,3.5 0.75 0.75,0,0,0-0.1,1.06 0.74 0.74,0,0,0,1,0.1A0.38 0.38 ,0,0,0,5,11.77a10.12,10.12,0,0,1,7-3A10.1,10.1,0,0,1,19,11.77Z" /> - <path - android:fillColor="#000000" - android:pathData="M16.08,16.08a0.74 0.74 ,0,0,0,0,1.06L17.94,19l-1.86,1.86a0.74 0.74 ,0,0,0,0,1.06 0.73 0.73,0,0,0,0.53 0.22 0.74 0.74 ,0,0,0,0.53-0.22L19,20.06l1.86,1.86a0.74 0.74 ,0,0,0,0.53 0.22 0.73 0.73 ,0,0,0,0.53-0.22 0.74 0.74,0,0,0,0-1.06L20.06,19l1.86-1.86a0.75 0.75 ,0,0,0-1.06-1.06L19,17.94l-1.86-1.86A0.74 0.74 ,0,0,0,16.08,16.08Z" /> - <path - android:fillColor="#000000" - android:pathData="M13.5,18.5a1.5,1.5,0,0,0-0.5-1.11,1.5,1.5,0,1,0,0,2.22A1.5,1.5,0,0,0,13.5,18.5Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillAlpha="0.3" android:fillColor="@android:color/white" android:pathData="M13,12h7.21l2.93-3.57c0.5-0.61,0.45-1.51-0.13-2.05C20.12,3.66,16.25,2,12,2S3.88,3.66,0.99,6.38 C0.41,6.92,0.36,7.82,0.86,8.43l10.37,12.63c0.4,0.49,1.15,0.49,1.55,0L13,20.78V12z" android:strokeAlpha="0.3" android:strokeWidth="1"/> + <path android:fillColor="@android:color/white" android:pathData="M19.56,17.5l2.22-2.22c0.29-0.29,0.29-0.77,0-1.06s-0.77-0.29-1.06,0l-2.22,2.22l-2.22-2.22c-0.29-0.29-0.77-0.29-1.06,0 s-0.29,0.77,0,1.06l2.22,2.22l-2.22,2.22c-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.22 l2.22-2.22l2.22,2.22c0.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.06L19.56,17.5z"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_wifi_disconnected.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_wifi_disconnected.xml index c6607a77f146..bed6c8cc4c56 100644 --- a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_wifi_disconnected.xml +++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_wifi_disconnected.xml @@ -1,55 +1,22 @@ + <!-- -/** - * 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. - */ + 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:fillAlpha="0.3" - android:strokeAlpha="0.3" - android:strokeWidth="1" - android:pathData="M21.7,8.3a0.83 0.83 ,0,0,0,1.05,0l0,0a0.73 0.73 ,0,0,0,0-1A14.51,14.51,0,0,0,12,2.8,14.77,14.77,0,0,0,1.25,7.25a0.76 0.76 ,0,0,0,0,1.05l0,0a0.72 0.72 ,0,0,0,1,0,13.34,13.34,0,0,1,9.7-4A13.16,13.16,0,0,1,21.7,8.3Z" /> - <path - android:fillColor="#000000" - android:fillAlpha="0.3" - android:strokeAlpha="0.3" - android:strokeWidth="1" - android:pathData="M12.05,7.25a11.36,11.36,0,0,0-8,3.5 0.74 0.74,0,0,0,1,1.05,9.93,9.93,0,0,1,7-3,9.94,9.94,0,0,1,3.25 0.64 ,5.58,5.58,0,0,1,1.56-1A11.38,11.38,0,0,0,12.05,7.25Z" /> - <path - android:fillColor="#000000" - android:fillAlpha="0.3" - android:strokeAlpha="0.3" - android:strokeWidth="1" - android:pathData="M7.25,13.75a0.76 0.76 ,0,0,0,0,1l0,0a0.73 0.73 ,0,0,0,1,0,5.26,5.26,0,0,1,5.2-1.3A5.48,5.48,0,0,1,13.72,12,6.73,6.73,0,0,0,7.25,13.75Z" /> - <path - android:fillColor="#000000" - android:fillAlpha="0.3" - android:strokeAlpha="0.3" - android:strokeWidth="1" - android:pathData="M 12 17 C 12.8284271247 17 13.5 17.6715728753 13.5 18.5 C 13.5 19.3284271247 12.8284271247 20 12 20 C 11.1715728753 20 10.5 19.3284271247 10.5 18.5 C 10.5 17.6715728753 11.1715728753 17 12 17 Z" /> - <path - android:fillColor="#000000" - android:pathData="M16.42,11.09a3.66,3.66,0,0,0-1,1.76 0.73 0.73,0,0,0,0.56 0.9 0.74 0.74 ,0,0,0,0.9-0.56,2.23,2.23,0,0,1,0.56-1,2.14,2.14,0,0,1,3,0,2,2,0,0,1,0.57,1.57,1.61,1.61,0,0,1-0.72,1.2,3.13,3.13,0,0,1-0.34 0.21 ,3.07,3.07,0,0,0-1.76,2.34 0.75 0.75,0,0,0,0.62 0.86 H19a0.75 0.75 ,0,0,0,0.74-0.62,1.62,1.62,0,0,1,1-1.29c0.15-0.09 0.3 -0.17 0.44 -0.27a3.14,3.14,0,0,0,1.37-2.29,3.46,3.46,0,0,0-1-2.77A3.68,3.68,0,0,0,16.42,11.09Z" /> - <path - android:fillColor="#000000" - android:pathData="M 19 20 C 19.5522847498 20 20 20.4477152502 20 21 C 20 21.5522847498 19.5522847498 22 19 22 C 18.4477152502 22 18 21.5522847498 18 21 C 18 20.4477152502 18.4477152502 20 19 20 Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillAlpha="0.3" android:fillColor="@android:color/white" android:pathData="M14.48,16.62L12,19.64L2.01,7.48C4.74,4.91,8.29,3.5,12,3.5c3.71,0,7.26,1.41,9.98,3.98L21.56,8 c0.66,0,1.3,0,1.82,0c0.21-0.55,0.09-1.19-0.36-1.62C20.12,3.66,16.25,2,12,2C7.75,2,3.88,3.66,0.99,6.38 C0.41,6.92,0.36,7.82,0.86,8.43l10.37,12.63c0.2,0.24,0.49,0.37,0.77,0.37s0.57-0.12,0.77-0.37l2.73-3.32 C15.11,17.42,14.76,17.04,14.48,16.62z" android:strokeAlpha="0.3" android:strokeWidth="1"/> + <path android:fillColor="@android:color/white" android:pathData="M21.58,11.09c-1.38-1.41-3.79-1.41-5.16,0c-0.47,0.48-0.8,1.09-0.95,1.76c-0.09,0.4,0.16,0.81,0.56,0.9 c0.4,0.1,0.81-0.16,0.9-0.56c0.09-0.41,0.29-0.77,0.56-1.05c0.81-0.83,2.21-0.83,3.02,0c0.42,0.43,0.63,1,0.57,1.57 c-0.05,0.5-0.31,0.92-0.72,1.2c-0.11,0.08-0.23,0.14-0.35,0.21c-0.64,0.37-1.51,0.88-1.75,2.34c-0.07,0.41,0.21,0.79,0.62,0.86 c0.04,0.01,0.08,0.01,0.12,0.01c0.36,0,0.68-0.26,0.74-0.63c0.13-0.76,0.48-0.97,1.03-1.28c0.15-0.09,0.3-0.17,0.44-0.27 c0.79-0.53,1.28-1.35,1.37-2.3C22.68,12.85,22.32,11.84,21.58,11.09z"/> + <path android:fillColor="@android:color/white" android:pathData="M 19 20 C 19.5522847498 20 20 20.4477152502 20 21 C 20 21.5522847498 19.5522847498 22 19 22 C 18.4477152502 22 18 21.5522847498 18 21 C 18 20.4477152502 18.4477152502 20 19 20 Z"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_screenshot_delete.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_screenshot_delete.xml index 9b424902d1e2..7297658c2ade 100644 --- a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_screenshot_delete.xml +++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_screenshot_delete.xml @@ -1,34 +1,22 @@ + <!-- -/** - * 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. - */ + 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="M8,21h8a3,3,0,0,0,3-3V5.5h1A0.75 0.75 ,0,0,0,20,4H15a1,1,0,0,0-1-1H10A1,1,0,0,0,9,4H4A0.75 0.75 ,0,0,0,4,5.5H5V18A3,3,0,0,0,8,21ZM9,5.5h8.5V18A1.5,1.5,0,0,1,16,19.5H8A1.5,1.5,0,0,1,6.5,18V5.5Z" /> - <path - android:fillColor="#000000" - android:pathData="M 13.5 8 H 15 V 17 H 13.5 V 8 Z" /> - <path - android:fillColor="#000000" - android:pathData="M 9 8 H 10.5 V 17 H 9 V 8 Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M20,4h-1h-4c0-0.55-0.45-1-1-1h-4C9.45,3,9,3.45,9,4H5H4C3.59,4,3.25,4.34,3.25,4.75S3.59,5.5,4,5.5h1V18 c0,1.66,1.34,3,3,3h8c1.66,0,3-1.34,3-3V5.5h1c0.41,0,0.75-0.34,0.75-0.75S20.41,4,20,4z M17.5,18c0,0.83-0.67,1.5-1.5,1.5H8 c-0.83,0-1.5-0.67-1.5-1.5V5.5h11V18z"/> + <path android:fillColor="@android:color/white" android:pathData="M14.25,8c-0.41,0-0.75,0.34-0.75,0.75v7.5c0,0.41,0.34,0.75,0.75,0.75S15,16.66,15,16.25v-7.5C15,8.34,14.66,8,14.25,8z"/> + <path android:fillColor="@android:color/white" android:pathData="M9.75,8C9.34,8,9,8.34,9,8.75v7.5C9,16.66,9.34,17,9.75,17s0.75-0.34,0.75-0.75v-7.5C10.5,8.34,10.16,8,9.75,8z"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_settings.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_settings.xml new file mode 100644 index 000000000000..0fc673b563e2 --- /dev/null +++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_settings.xml @@ -0,0 +1,21 @@ + +<!-- + 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 android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M2.43,15.45l1.79,3.09c0.25,0.45,0.74,0.73,1.25,0.73c0.17,0,0.35-0.03,0.52-0.09l1.76-0.7c0.25,0.17,0.51,0.31,0.77,0.45 l0.26,1.84c0.09,0.71,0.69,1.24,1.42,1.24h3.61c0.72,0,1.33-0.53,1.43-1.19l0.26-1.86c0.25-0.14,0.51-0.28,0.76-0.45l1.76,0.7 c0.17,0.07,0.35,0.1,0.53,0.1c0.5,0,0.98-0.27,1.23-0.72l1.82-3.14c0.34-0.61,0.19-1.38-0.36-1.82l-1.48-1.16 c0.01-0.15,0.02-0.29,0.02-0.45s-0.01-0.3-0.02-0.45l1.48-1.16c0.55-0.43,0.7-1.19,0.35-1.84l-1.8-3.1 c-0.25-0.45-0.74-0.73-1.26-0.73c-0.17,0-0.35,0.03-0.52,0.09l-1.76,0.7c-0.25-0.17-0.51-0.31-0.77-0.45l-0.26-1.84 c-0.09-0.71-0.69-1.24-1.42-1.24h-3.61c-0.71,0-1.32,0.54-1.41,1.22L8.52,5.09C8.26,5.23,8.01,5.37,7.75,5.54L5.99,4.83 c-0.17-0.07-0.35-0.1-0.52-0.1c-0.5,0-0.98,0.27-1.22,0.72L2.43,8.55c-0.36,0.61-0.21,1.4,0.36,1.84l1.48,1.16 C4.27,11.7,4.26,11.85,4.26,12c0,0.16,0.01,0.3,0.02,0.45l-1.49,1.16C2.24,14.04,2.09,14.8,2.43,15.45z M5.2,13.63l0.63-0.49 l-0.05-0.79c-0.01-0.11-0.01-0.58,0-0.7l0.05-0.79L5.2,10.37L3.77,9.25l1.74-3l1.69,0.68l0.73,0.29l0.66-0.43 c0.19-0.13,0.4-0.25,0.65-0.38l0.67-0.36L10,5.3l0.25-1.79h3.48l0.26,1.8l0.11,0.76l0.69,0.36c0.23,0.12,0.44,0.24,0.64,0.37 l0.65,0.43l0.72-0.29l1.7-0.68l1.75,3.02l-1.43,1.12l-0.62,0.49l0.05,0.79c0.01,0.11,0.01,0.58,0,0.7l-0.05,0.79l0.62,0.49 l1.43,1.12l-1.74,3.02l-1.69-0.68l-0.72-0.29l-0.65,0.43c-0.19,0.13-0.4,0.25-0.65,0.38l-0.67,0.36l-0.11,0.75l-0.25,1.77h-3.5 L10,18.71l-0.11-0.76l-0.69-0.36c-0.23-0.12-0.44-0.24-0.64-0.37l-0.65-0.43l-0.72,0.29L5.5,17.76l-1.73-3.01L5.2,13.63z"/> + <path android:fillColor="@android:color/white" android:pathData="M12,16c2.21,0,4-1.79,4-4s-1.79-4-4-4c-2.21,0-4,1.79-4,4S9.79,16,12,16z M12,9.5c1.38,0,2.5,1.12,2.5,2.5 s-1.12,2.5-2.5,2.5c-1.38,0-2.5-1.12-2.5-2.5S10.62,9.5,12,9.5z"/> +</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 index 4237323ca2f7..66d1cb970ea6 100644 --- a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_settings_16dp.xml +++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_settings_16dp.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="#FFFFFF" + android:pathData="M2.43,15.45l1.79,3.09c0.25,0.45,0.74,0.73,1.25,0.73c0.17,0,0.35-0.03,0.52-0.09l1.76-0.7c0.25,0.17,0.51,0.31,0.77,0.45 l0.26,1.84c0.09,0.71,0.69,1.24,1.42,1.24h3.61c0.72,0,1.33-0.53,1.43-1.19l0.26-1.86c0.25-0.14,0.51-0.28,0.76-0.45l1.76,0.7 c0.17,0.07,0.35,0.1,0.53,0.1c0.5,0,0.98-0.27,1.23-0.72l1.82-3.14c0.34-0.61,0.19-1.38-0.36-1.82l-1.48-1.16 c0.01-0.15,0.02-0.29,0.02-0.45s-0.01-0.3-0.02-0.45l1.48-1.16c0.55-0.43,0.7-1.19,0.35-1.84l-1.8-3.1 c-0.25-0.45-0.74-0.73-1.26-0.73c-0.17,0-0.35,0.03-0.52,0.09l-1.76,0.7c-0.25-0.17-0.51-0.31-0.77-0.45l-0.26-1.84 c-0.09-0.71-0.69-1.24-1.42-1.24h-3.61c-0.71,0-1.32,0.54-1.41,1.22L8.52,5.09C8.26,5.23,8.01,5.37,7.75,5.54L5.99,4.83 c-0.17-0.07-0.35-0.1-0.52-0.1c-0.5,0-0.98,0.27-1.22,0.72L2.43,8.55c-0.36,0.61-0.21,1.4,0.36,1.84l1.48,1.16 C4.27,11.7,4.26,11.85,4.26,12c0,0.16,0.01,0.3,0.02,0.45l-1.49,1.16C2.24,14.04,2.09,14.8,2.43,15.45z M5.2,13.63l0.63-0.49 l-0.05-0.79C5.77,12.24,5.76,12.12,5.76,12c0-0.11,0.01-0.24,0.02-0.35l0.05-0.79L5.2,10.37L3.77,9.25l1.74-3l1.69,0.68l0.73,0.29 l0.66-0.43c0.19-0.13,0.4-0.25,0.65-0.38l0.67-0.36L10,5.3l0.25-1.79h3.48l0.26,1.8l0.11,0.76l0.69,0.36 c0.23,0.12,0.44,0.24,0.64,0.37l0.65,0.43l0.72-0.29l1.7-0.68l1.75,3.02l-1.43,1.12l-0.62,0.49l0.05,0.79 c0.01,0.11,0.02,0.23,0.02,0.35c0,0.12-0.01,0.23-0.02,0.35l-0.05,0.79l0.62,0.49l1.43,1.12l-1.74,3.02l-1.69-0.68l-0.72-0.29 l-0.65,0.43c-0.19,0.13-0.4,0.25-0.65,0.38l-0.67,0.36l-0.11,0.75l-0.25,1.77h-3.5L10,18.71l-0.11-0.76l-0.69-0.36 c-0.23-0.12-0.44-0.24-0.64-0.37l-0.65-0.43l-0.72,0.29L5.5,17.76l-1.73-3.01L5.2,13.63z" /> <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> + android:fillColor="#FFFFFF" + android:pathData="M12,16c2.21,0,4-1.79,4-4s-1.79-4-4-4c-2.21,0-4,1.79-4,4S9.79,16,12,16z M12,9.5c1.38,0,2.5,1.12,2.5,2.5 s-1.12,2.5-2.5,2.5c-1.38,0-2.5-1.12-2.5-2.5S10.62,9.5,12,9.5z" /> +</vector>
\ No newline at end of file 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/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_signal_flashlight.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_signal_flashlight.xml deleted file mode 100644 index 3bde46fcb948..000000000000 --- a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_signal_flashlight.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="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: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/IconPackRoundedSystemUIOverlay/res/drawable/ic_swap_vert.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_swap_vert.xml index 297d8865d184..f4c1ba1b7230 100644 --- a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_swap_vert.xml +++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_swap_vert.xml @@ -1,31 +1,21 @@ + <!-- -/** - * 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. - */ + 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="M6,8,8.25,5.81V13a0.75 0.75 ,0,1,0,1.5,0V5.81L12,8A0.75 0.75 ,0,0,0,13,8,0.75 0.75 ,0,0,0,13,7l-3.5-3.5a0.75 0.75 ,0,0,0-1.06,0L5,7A0.75 0.75 ,0,1,0,6,8Z" /> - <path - android:fillColor="#000000" - android:pathData="M19,16A0.75 0.75 ,0,0,0,18,16l-2.22,2.22V11a0.75 0.75 ,0,0,0-1.5,0v7.21L12,16A0.75 0.75 ,0,1,0,11,17l3.5,3.5a0.75 0.75 ,0,0,0,1.06,0L19,17A0.75 0.75 ,0,0,0,19,16Z" /> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M19.03,16.99c-0.29-0.29-0.77-0.29-1.06,0l-2.22,2.22v-8.46c0-0.41-0.34-0.75-0.75-0.75s-0.75,0.34-0.75,0.75v8.46 l-2.22-2.22c-0.29-0.29-0.77-0.29-1.06,0s-0.29,0.77,0,1.06l3.5,3.5c0.15,0.15,0.34,0.22,0.53,0.22s0.38-0.07,0.53-0.22l3.5-3.5 C19.32,17.76,19.32,17.29,19.03,16.99z"/> + <path android:fillColor="@android:color/white" android:pathData="M11.97,7.01c0.29,0.29,0.77,0.29,1.06,0s0.29-0.77,0-1.06l-3.5-3.5C9.38,2.3,9.19,2.23,9,2.23S8.62,2.3,8.47,2.45 l-3.5,3.5c-0.29,0.29-0.29,0.77,0,1.06s0.77,0.29,1.06,0l2.22-2.22v8.46C8.25,13.66,8.59,14,9,14s0.75-0.34,0.75-0.75V4.79 L11.97,7.01z"/> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_tune_black_16dp.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_tune_black_16dp.xml new file mode 100644 index 000000000000..41abc926831a --- /dev/null +++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_tune_black_16dp.xml @@ -0,0 +1,25 @@ + +<!-- + 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 android:height="16dp" android:viewportHeight="24" android:viewportWidth="24" android:width="16dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M3.75,4.75C3.34,4.75,3,5.09,3,5.5s0.34,0.75,0.75,0.75H14v-1.5H3.75z"/> + <path android:fillColor="@android:color/white" android:pathData="M20.25,4.75H17v-1.5c0-0.41-0.34-0.75-0.75-0.75S15.5,2.84,15.5,3.25v4.5c0,0.41,0.34,0.75,0.75,0.75S17,8.16,17,7.75v-1.5 h3.25C20.66,6.25,21,5.91,21,5.5S20.66,4.75,20.25,4.75z"/> + <path android:fillColor="@android:color/white" android:pathData="M20.25,11.25H10v1.5h10.25c0.41,0,0.75-0.34,0.75-0.75S20.66,11.25,20.25,11.25z"/> + <path android:fillColor="@android:color/white" android:pathData="M3.75,17.75C3.34,17.75,3,18.09,3,18.5s0.34,0.75,0.75,0.75H10v-1.5H3.75z"/> + <path android:fillColor="@android:color/white" android:pathData="M20.25,17.75H13v-1.5c0-0.41-0.34-0.75-0.75-0.75s-0.75,0.34-0.75,0.75v4.5c0,0.41,0.34,0.75,0.75,0.75S13,21.16,13,20.75 v-1.5h7.25c0.41,0,0.75-0.34,0.75-0.75S20.66,17.75,20.25,17.75z"/> + <path android:fillColor="@android:color/white" android:pathData="M8.5,9.75C8.5,9.34,8.16,9,7.75,9S7,9.34,7,9.75v1.5H3.75C3.34,11.25,3,11.59,3,12s0.34,0.75,0.75,0.75H7v1.5 C7,14.66,7.34,15,7.75,15s0.75-0.34,0.75-0.75V9.75z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_volume_alarm.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_volume_alarm.xml index 167d15f5181b..bd7f23491dc5 100644 --- a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_volume_alarm.xml +++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_volume_alarm.xml @@ -21,17 +21,15 @@ android:viewportHeight="24"> <path - android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" /> + android:fillColor="#FFFFFF" + android:pathData="M13.93,16.02c0.15,0.15,0.34,0.22,0.53,0.22c0.19,0,0.38-0.07,0.53-0.22c0.29-0.29,0.3-0.77,0.01-1.06l-2.25-2.28V7.75 C12.75,7.34,12.41,7,12,7s-0.75,0.34-0.75,0.75V13c0,0.2,0.08,0.39,0.22,0.53L13.93,16.02z" /> <path - android:fillColor="#000000" - android:pathData="M14.43,16.52a0.76 0.76 ,0,0,0,0.54 0.23 0.79 0.79 ,0,0,0,0.53-0.22 0.75 0.75,0,0,0,0-1.06l-2.75-2.78V8a0.75 0.75 ,0,0,0-1.5,0v5a0.75 0.75 ,0,0,0,0.22 0.53 Z" /> + android:fillColor="#FFFFFF" + android:pathData="M16.4,2.55c-0.25,0.33-0.18,0.8,0.15,1.05l4.02,3c0.13,0.1,0.29,0.15,0.45,0.15c0.23,0,0.45-0.1,0.6-0.3 c0.25-0.33,0.18-0.8-0.15-1.05l-4.02-3C17.12,2.15,16.65,2.22,16.4,2.55z" /> <path - android:fillColor="#000000" - android:pathData="M16.4,2.55a0.75 0.75 ,0,0,0,0.15,1.05l4,3a0.78 0.78 ,0,0,0,0.45 0.15 0.73 0.73 ,0,0,0,0.6-0.3 0.75 0.75,0,0,0-0.15-1l-4-3A0.75 0.75 ,0,0,0,16.4,2.55Z" /> + android:fillColor="#FFFFFF" + android:pathData="M2.98,6.75c0.16,0,0.31-0.05,0.45-0.15l4.02-3c0.33-0.25,0.4-0.72,0.15-1.05C7.35,2.22,6.88,2.15,6.55,2.4l-4.02,3 C2.2,5.65,2.13,6.12,2.38,6.45C2.52,6.65,2.75,6.75,2.98,6.75z" /> <path - android:fillColor="#000000" - android:pathData="M3,6.75a0.78 0.78 ,0,0,0,0.45-0.15l4-3a0.75 0.75 ,0,1,0-0.9-1.2l-4,3a0.75 0.75 ,0,0,0-0.15,1A0.73 0.73 ,0,0,0,3,6.75Z" /> - <path - android:fillColor="#000000" - android:pathData="M3.08,13A9,9,0,0,0,12,22h0a8.81,8.81,0,0,0,6.3-2.63A9,9,0,0,0,20.92,13v0A8.92,8.92,0,1,0,3.08,13ZM12,5.5A7.47,7.47,0,0,1,19.42,13h0.75l-0.75,0a7.47,7.47,0,0,1-2.18,5.29A7.33,7.33,0,0,1,12,20.5h0a7.5,7.5,0,0,1,0-15Z" /> + android:fillColor="#FFFFFF" + android:pathData="M3.08,13c0,4.96,4,9,8.92,9c0,0,0.01,0,0.01,0c2.38,0,4.61-0.93,6.3-2.63c1.68-1.7,2.61-3.95,2.61-6.35V13 c0-4.96-4-9-8.92-9S3.08,8.04,3.08,13z M12,5.5c4.09,0,7.42,3.36,7.42,7.5h0.75l-0.75,0.02c0,2-0.78,3.88-2.18,5.3 c-1.4,1.41-3.26,2.19-5.23,2.19c0,0-0.01,0-0.01,0c-4.09,0-7.42-3.36-7.42-7.5S7.91,5.5,12,5.5z" /> </vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_volume_alarm_mute.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_volume_alarm_mute.xml new file mode 100644 index 000000000000..aa0c74031c80 --- /dev/null +++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_volume_alarm_mute.xml @@ -0,0 +1,24 @@ + +<!-- + 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 android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M11.25,7.75v1.32l1.5,1.5V7.75C12.75,7.34,12.41,7,12,7S11.25,7.34,11.25,7.75z"/> + <path android:fillColor="@android:color/white" android:pathData="M21.47,5.4l-4.02-3c-0.33-0.25-0.8-0.18-1.05,0.15c-0.25,0.33-0.18,0.8,0.15,1.05l4.02,3c0.13,0.1,0.29,0.15,0.45,0.15 c0.23,0,0.45-0.1,0.6-0.3C21.87,6.12,21.8,5.65,21.47,5.4z"/> + <path android:fillColor="@android:color/white" android:pathData="M7.45,3.6c0.33-0.25,0.4-0.72,0.15-1.05C7.35,2.22,6.88,2.15,6.55,2.4L5.42,3.24l1.07,1.07L7.45,3.6z"/> + <path android:fillColor="@android:color/white" android:pathData="M18.6,16.42l1.1,1.1c0.78-1.35,1.21-2.9,1.21-4.51V13c0-4.96-4-9-8.92-9c-1.66,0-3.21,0.47-4.55,1.27l1.1,1.1 C9.58,5.82,10.75,5.5,12,5.5c4.09,0,7.42,3.36,7.42,7.5v0.02C19.42,14.22,19.13,15.38,18.6,16.42z"/> + <path android:fillColor="@android:color/white" android:pathData="M4.67,4.61c-0.29-0.29-0.77-0.29-1.06,0L3.6,4.6L2.53,5.4C2.2,5.65,2.13,6.12,2.38,6.45c0.15,0.2,0.37,0.3,0.6,0.3 c0.16,0,0.31-0.05,0.45-0.15l0.64-0.48l1.1,1.1C3.87,8.79,3.08,10.8,3.08,13c0,4.96,4,9,8.92,9c0,0,0.01,0,0.01,0 c2.14,0,4.17-0.76,5.78-2.15l1.93,1.93c0.15,0.15,0.34,0.22,0.53,0.22s0.38-0.07,0.53-0.22c0,0,0,0,0,0 c0.29-0.29,0.29-0.77,0-1.06L4.67,4.61z M12.01,20.5C12.01,20.5,12,20.5,12.01,20.5c-4.1,0-7.43-3.36-7.43-7.5 c0-1.78,0.62-3.42,1.65-4.71l5.29,5.29l2.92,2.95c0.03,0.03,0.06,0.04,0.09,0.06l2.2,2.2C15.4,19.9,13.75,20.5,12.01,20.5z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_volume_ringer_vibrate.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_volume_ringer_vibrate.xml new file mode 100644 index 000000000000..9f4d035a50dd --- /dev/null +++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_volume_ringer_vibrate.xml @@ -0,0 +1,24 @@ + +<!-- + 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 android:height="19dp" android:viewportHeight="24" android:viewportWidth="24" android:width="19dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M9,4C7.9,4,7,4.9,7,6v12c0,1.1,0.9,2,2,2h6c1.1,0,2-0.9,2-2V6c0-1.1-0.9-2-2-2H9z M15.5,6v12c0,0.28-0.22,0.5-0.5,0.5H9 c-0.28,0-0.5-0.22-0.5-0.5V6c0-0.28,0.22-0.5,0.5-0.5h6C15.28,5.5,15.5,5.72,15.5,6z"/> + <path android:fillColor="@android:color/white" android:pathData="M19.25,17c0.41,0,0.75-0.34,0.75-0.75v-8.5C20,7.34,19.66,7,19.25,7S18.5,7.34,18.5,7.75v8.5C18.5,16.66,18.84,17,19.25,17 z"/> + <path android:fillColor="@android:color/white" android:pathData="M22.25,9c-0.41,0-0.75,0.34-0.75,0.75v4.5c0,0.41,0.34,0.75,0.75,0.75S23,14.66,23,14.25v-4.5C23,9.34,22.66,9,22.25,9z"/> + <path android:fillColor="@android:color/white" android:pathData="M2.5,14.25v-4.5C2.5,9.34,2.16,9,1.75,9S1,9.34,1,9.75v4.5C1,14.66,1.34,15,1.75,15S2.5,14.66,2.5,14.25z"/> + <path android:fillColor="@android:color/white" android:pathData="M4,16.25C4,16.66,4.34,17,4.75,17s0.75-0.34,0.75-0.75v-8.5C5.5,7.34,5.16,7,4.75,7S4,7.34,4,7.75V16.25z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/stat_sys_camera.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/stat_sys_camera.xml new file mode 100644 index 000000000000..ab73718b6d4a --- /dev/null +++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/stat_sys_camera.xml @@ -0,0 +1,21 @@ + +<!-- + 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 android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M22,7c0-1.1-0.9-2-2-2h-3l-1.41-1.41C15.21,3.21,14.7,3,14.17,3H9.83C9.3,3,8.79,3.21,8.41,3.59L7,5H4C2.9,5,2,5.9,2,7v12 c0,1.1,0.9,2,2,2h16c1.1,0,2-0.9,2-2V7z M20.5,19c0,0.28-0.22,0.5-0.5,0.5H4c-0.28,0-0.5-0.22-0.5-0.5V7c0-0.28,0.22-0.5,0.5-0.5 h3.62l1.85-1.85C9.57,4.55,9.69,4.5,9.83,4.5h4.34c0.13,0,0.26,0.05,0.35,0.15l1.85,1.85H20c0.28,0,0.5,0.22,0.5,0.5V19z"/> + <path android:fillColor="@android:color/white" android:pathData="M12,9c-2.21,0-4,1.79-4,4c0,2.21,1.79,4,4,4c2.21,0,4-1.79,4-4C16,10.79,14.21,9,12,9z M12,15.5c-1.38,0-2.5-1.12-2.5-2.5 c0-1.38,1.12-2.5,2.5-2.5c1.38,0,2.5,1.12,2.5,2.5C14.5,14.38,13.38,15.5,12,15.5z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/stat_sys_mic_none.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/stat_sys_mic_none.xml new file mode 100644 index 000000000000..8baf94dc6528 --- /dev/null +++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/stat_sys_mic_none.xml @@ -0,0 +1,21 @@ + +<!-- + 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 android:height="18dp" android:viewportHeight="24" android:viewportWidth="24" android:width="18dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M12,15.5c1.93,0,3.5-1.57,3.5-3.5V5.5C15.5,3.57,13.93,2,12,2S8.5,3.57,8.5,5.5V12C8.5,13.93,10.07,15.5,12,15.5z M10,5.5 c0-1.1,0.9-2,2-2s2,0.9,2,2V12c0,1.1-0.9,2-2,2s-2-0.9-2-2V5.5z"/> + <path android:fillColor="@android:color/white" android:pathData="M17.75,11.25C17.34,11.25,17,11.59,17,12c0,2.76-2.24,5-5,5s-5-2.24-5-5c0-0.41-0.34-0.75-0.75-0.75S5.5,11.59,5.5,12 c0,3.33,2.52,6.08,5.75,6.45v2.8c0,0.41,0.34,0.75,0.75,0.75s0.75-0.34,0.75-0.75v-2.8c3.23-0.37,5.75-3.12,5.75-6.45 C18.5,11.59,18.16,11.25,17.75,11.25z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/stat_sys_vpn_ic.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/stat_sys_vpn_ic.xml new file mode 100644 index 000000000000..468c8b6cb4dc --- /dev/null +++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/stat_sys_vpn_ic.xml @@ -0,0 +1,21 @@ + +<!-- + 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 android:height="17dp" android:viewportHeight="24" android:viewportWidth="24" android:width="17dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M 6.5 9.5 C 7.60456949966 9.5 8.5 10.3954305003 8.5 11.5 C 8.5 12.6045694997 7.60456949966 13.5 6.5 13.5 C 5.39543050034 13.5 4.5 12.6045694997 4.5 11.5 C 4.5 10.3954305003 5.39543050034 9.5 6.5 9.5 Z"/> + <path android:fillColor="@android:color/white" android:pathData="M22,9H11.39C10.48,7.22,8.64,6,6.5,6C6.15,6,5.8,6.03,5.44,6.1c-2.13,0.4-3.88,2.09-4.32,4.22C0.38,13.87,3.08,17,6.5,17 c2.14,0,3.98-1.22,4.89-3H15v2c0,0.55,0.45,1,1,1h4c0.55,0,1-0.45,1-1v-2h1c0.55,0,1-0.45,1-1v-3C23,9.45,22.55,9,22,9z M21.5,12.5 h-2v3h-3v-3h-6.14c-0.45,1.72-2,3-3.86,3c-2.21,0-4-1.79-4-4c0-2.21,1.79-4,4-4c1.86,0,3.41,1.28,3.86,3H21.5V12.5z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/NavigationBarModeGesturalOverlay/res/values/config.xml b/packages/overlays/NavigationBarModeGesturalOverlay/res/values/config.xml index 48c37695d4a1..23d2e7babdcc 100644 --- a/packages/overlays/NavigationBarModeGesturalOverlay/res/values/config.xml +++ b/packages/overlays/NavigationBarModeGesturalOverlay/res/values/config.xml @@ -22,4 +22,15 @@ 1: 2 button mode (back, home buttons + swipe up for overview) 2: gestures only for back, home and overview --> <integer name="config_navBarInteractionMode">2</integer> -</resources>
\ No newline at end of file + + <!-- Controls whether the nav bar can move from the bottom to the side in landscape. + Only applies if the device display is not square. --> + <bool name="config_navBarCanMove">false</bool> + + <!-- Controls whether the navigation bar lets through taps. --> + <bool name="config_navBarTapThrough">true</bool> + + <!-- Controls the size of the back gesture inset. --> + <dimen name="config_backGestureInset">48dp</dimen> + +</resources> diff --git a/packages/overlays/NavigationBarModeGesturalOverlay/res/values/dimens.xml b/packages/overlays/NavigationBarModeGesturalOverlay/res/values/dimens.xml index 721d11be8cb5..c839b2c2eb76 100644 --- a/packages/overlays/NavigationBarModeGesturalOverlay/res/values/dimens.xml +++ b/packages/overlays/NavigationBarModeGesturalOverlay/res/values/dimens.xml @@ -19,6 +19,8 @@ <resources> <!-- Height of the bottom navigation / system bar. --> <dimen name="navigation_bar_height">16dp</dimen> + <!-- Height of the bottom navigation bar in portrait; often the same as @dimen/navigation_bar_height --> + <dimen name="navigation_bar_height_landscape">16dp</dimen> <!-- Width of the navigation bar when it is placed vertically on the screen --> <dimen name="navigation_bar_width">16dp</dimen> <!-- Height of the bottom navigation / system bar. --> diff --git a/proto/src/metrics_constants/metrics_constants.proto b/proto/src/metrics_constants/metrics_constants.proto index f52b94ff9ea1..ce39a709e637 100644 --- a/proto/src/metrics_constants/metrics_constants.proto +++ b/proto/src/metrics_constants/metrics_constants.proto @@ -7158,6 +7158,10 @@ message MetricsEvent { // OPEN: Settings > System > Aware > Info dialog DIALOG_AWARE_STATUS = 1701; + + // Open: Settings > app > bubble settings > confirmation dialog + DIALOG_APP_BUBBLE_SETTINGS = 1702; + // ---- End Q Constants, all Q constants go above this line ---- // Add new aosp constants above this line. // END OF AOSP CONSTANTS diff --git a/proto/src/wifi.proto b/proto/src/wifi.proto index 1ce0c5292ab8..bd72976ab7d1 100644 --- a/proto/src/wifi.proto +++ b/proto/src/wifi.proto @@ -533,6 +533,9 @@ message WifiLog { // Network Suggestion API surface metrics. optional WifiNetworkSuggestionApiLog wifi_network_suggestion_api_log = 142; + + // WifiLock statistics + optional WifiLockStats wifi_lock_stats = 143; } // Information that gets logged for every WiFi connection. @@ -1752,6 +1755,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 +2018,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 +2051,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 @@ -2051,6 +2064,10 @@ message WifiUsabilityStats { // What event triggered WifiUsabilityStats. optional UsabilityStatsTriggerType trigger_type = 3; + + // Firmware alert code. Only valid when the stats was triggered by a firmware + // alert, otherwise -1. + optional int32 firmware_alert_code = 4 [default = -1]; } message DeviceMobilityStatePnoScanStats { @@ -2451,3 +2468,30 @@ message WifiNetworkSuggestionApiLog { // Histogram for size of the network lists provided by various apps on the device. repeated HistogramBucketInt32 network_list_size_histogram = 4; } + +// WifiLock metrics +message WifiLockStats { + // Amount of time wifi is actively in HIGH_PERF mode (ms) + // This means the lock takes effect and the device takes the actions required for this mode + optional int64 high_perf_active_time_ms = 1; + + // Amount of time wifi is actively in LOW_LATENCY mode (ms) + // This means the lock takes effect and the device takes the actions required for this mode + optional int64 low_latency_active_time_ms = 2; + + // Histogram of HIGH_PERF lock acquisition duration (seconds) + // Note that acquiring the lock does not necessarily mean that device is actively in that mode + repeated HistogramBucketInt32 high_perf_lock_acq_duration_sec_histogram = 3; + + // Histogram of LOW_LATENCY lock acquisition duration (seconds) + // Note that acquiring the lock does not necessarily mean that device is actively in that mode + repeated HistogramBucketInt32 low_latency_lock_acq_duration_sec_histogram = 4; + + // Histogram of HIGH_PERF active session duration (seconds) + // This means the lock takes effect and the device takes the actions required for this mode + repeated HistogramBucketInt32 high_perf_active_session_duration_sec_histogram = 5; + + // Histogram of LOW_LATENCY active session duration (seconds) + // This means the lock takes effect and the device takes the actions required for this mode + repeated HistogramBucketInt32 low_latency_active_session_duration_sec_histogram = 6; +} diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java index 904817e1763e..6e2c2280a8b9 100644 --- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java +++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java @@ -2552,6 +2552,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub pw.append(", autoclickEnabled=" + userState.mIsAutoclickEnabled); pw.append(", nonInteractiveUiTimeout=" + userState.mNonInteractiveUiTimeout); pw.append(", interactiveUiTimeout=" + userState.mInteractiveUiTimeout); + pw.append(", installedServiceCount=" + userState.mInstalledServices.size()); if (mUiAutomationManager.isUiAutomationRunningLocked()) { pw.append(", "); mUiAutomationManager.dumpUiAutomationService(fd, pw, args); @@ -2559,7 +2560,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub } pw.append("}"); pw.println(); - pw.append(" services:{"); + pw.append(" Bound services:{"); final int serviceCount = userState.mBoundServices.size(); for (int j = 0; j < serviceCount; j++) { if (j > 0) { @@ -2570,6 +2571,30 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub AccessibilityServiceConnection service = userState.mBoundServices.get(j); service.dump(fd, pw, args); } + pw.println("}"); + pw.append(" Enabled services:{"); + Iterator<ComponentName> it = userState.mEnabledServices.iterator(); + if (it.hasNext()) { + ComponentName componentName = it.next(); + pw.append(componentName.toShortString()); + while (it.hasNext()) { + componentName = it.next(); + pw.append(", "); + pw.append(componentName.toShortString()); + } + } + pw.println("}"); + pw.append(" Binding services:{"); + it = userState.mBindingServices.iterator(); + if (it.hasNext()) { + ComponentName componentName = it.next(); + pw.append(componentName.toShortString()); + while (it.hasNext()) { + componentName = it.next(); + pw.append(", "); + pw.append(componentName.toShortString()); + } + } pw.println("}]"); pw.println(); } @@ -2585,6 +2610,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub pw.append(window.toString()); pw.append(']'); } + pw.println(); } } } @@ -4100,6 +4126,13 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub return mBindingServices; } + /** + * Returns enabled service list. + */ + public Set<ComponentName> getEnabledServicesLocked() { + return mEnabledServices; + } + public int getSoftKeyboardShowMode() { return mSoftKeyboardShowMode; } diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityServiceConnection.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityServiceConnection.java index 3bd6220b4767..b66caa5e324a 100644 --- a/services/accessibility/java/com/android/server/accessibility/AccessibilityServiceConnection.java +++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityServiceConnection.java @@ -123,12 +123,12 @@ class AccessibilityServiceConnection extends AbstractAccessibilityServiceConnect synchronized (mLock) { UserState userState = mUserStateWeakReference.get(); if (userState == null) return; - if (userState.mEnabledServices.remove(mComponentName)) { + if (userState.getEnabledServicesLocked().remove(mComponentName)) { final long identity = Binder.clearCallingIdentity(); try { mSystemSupport.persistComponentNamesToSettingLocked( Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, - userState.mEnabledServices, userState.mUserId); + userState.getEnabledServicesLocked(), userState.mUserId); } finally { Binder.restoreCallingIdentity(identity); } @@ -183,6 +183,14 @@ class AccessibilityServiceConnection extends AbstractAccessibilityServiceConnect mWasConnectedAndDied = false; serviceInterface = mServiceInterface; } + // There's a chance that service is removed from enabled_accessibility_services setting + // key, but skip unbinding because of it's in binding state. Unbinds it if it's + // not in enabled service list. + if (serviceInterface != null + && !userState.getEnabledServicesLocked().contains(mComponentName)) { + mSystemSupport.onClientChangeLocked(false); + return; + } } if (serviceInterface == null) { binderDied(); diff --git a/services/accessibility/java/com/android/server/accessibility/UiAutomationManager.java b/services/accessibility/java/com/android/server/accessibility/UiAutomationManager.java index 4bbf68271eb9..72c84e28f24f 100644 --- a/services/accessibility/java/com/android/server/accessibility/UiAutomationManager.java +++ b/services/accessibility/java/com/android/server/accessibility/UiAutomationManager.java @@ -64,9 +64,7 @@ class UiAutomationManager { public void binderDied() { mUiAutomationServiceOwner.unlinkToDeath(this, 0); mUiAutomationServiceOwner = null; - if (mUiAutomationService != null) { - destroyUiAutomationService(); - } + destroyUiAutomationService(); } }; @@ -201,17 +199,20 @@ class UiAutomationManager { private void destroyUiAutomationService() { synchronized (mLock) { - mUiAutomationService.mServiceInterface.asBinder().unlinkToDeath(mUiAutomationService, - 0); - mUiAutomationService.onRemoved(); - mUiAutomationService.resetLocked(); - mUiAutomationService = null; - mUiAutomationFlags = 0; - if (mUiAutomationServiceOwner != null) { - mUiAutomationServiceOwner.unlinkToDeath(mUiAutomationServiceOwnerDeathRecipient, 0); - mUiAutomationServiceOwner = null; + if (mUiAutomationService != null) { + mUiAutomationService.mServiceInterface.asBinder().unlinkToDeath( + mUiAutomationService, 0); + mUiAutomationService.onRemoved(); + mUiAutomationService.resetLocked(); + mUiAutomationService = null; + mUiAutomationFlags = 0; + if (mUiAutomationServiceOwner != null) { + mUiAutomationServiceOwner.unlinkToDeath( + mUiAutomationServiceOwnerDeathRecipient, 0); + mUiAutomationServiceOwner = null; + } + mSystemSupport.onClientChangeLocked(false); } - mSystemSupport.onClientChangeLocked(false); } } diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java index 7020e7ea6965..fdc3567aa002 100644 --- a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java +++ b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java @@ -42,6 +42,7 @@ import android.content.pm.UserInfo; import android.database.ContentObserver; import android.graphics.Rect; import android.os.Binder; +import android.os.Build; import android.os.Bundle; import android.os.IBinder; import android.os.Parcelable; @@ -61,6 +62,7 @@ import android.util.ArrayMap; import android.util.LocalLog; import android.util.Slog; import android.util.SparseArray; +import android.util.SparseBooleanArray; import android.view.autofill.AutofillId; import android.view.autofill.AutofillManager; import android.view.autofill.AutofillManager.SmartSuggestionMode; @@ -72,6 +74,8 @@ import android.view.autofill.IAutoFillManagerClient; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.infra.AbstractRemoteService; +import com.android.internal.infra.GlobalWhitelistState; +import com.android.internal.infra.WhitelistHelper; import com.android.internal.os.IResultReceiver; import com.android.internal.util.DumpUtils; import com.android.internal.util.Preconditions; @@ -146,6 +150,7 @@ public final class AutofillManagerService private final LocalLog mWtfHistory = new LocalLog(50); private final AutofillCompatState mAutofillCompatState = new AutofillCompatState(); + private final LocalService mLocalService = new LocalService(); private final ActivityManagerInternal mAm; @@ -178,6 +183,8 @@ public final class AutofillManagerService @GuardedBy("mLock") int mAugmentedServiceRequestTimeoutMs; + final AugmentedAutofillState mAugmentedAutofillState = new AugmentedAutofillState(); + public AutofillManagerService(Context context) { super(context, new SecureSettingsServiceNameResolver(context, Settings.Secure.AUTOFILL_SERVICE), @@ -187,7 +194,7 @@ public final class AutofillManagerService DeviceConfig.addOnPropertyChangedListener(DeviceConfig.NAMESPACE_AUTOFILL, ActivityThread.currentApplication().getMainExecutor(), - (namespace, key, value) -> onDeviceConfigChange(key, value)); + (namespace, key, value) -> onDeviceConfigChange(key)); setLogLevelFromSettings(); setMaxPartitionsFromSettings(); @@ -201,15 +208,20 @@ public final class AutofillManagerService mAugmentedAutofillResolver = new FrameworkResourcesServiceNameResolver(getContext(), com.android.internal.R.string.config_defaultAugmentedAutofillService); mAugmentedAutofillResolver.setOnTemporaryServiceNameChangedCallback( - (u, s) -> getServiceForUserLocked(u).updateRemoteAugmentedAutofillService()); + (u, s, t) -> onAugmentedServiceNameChanged(u, s, t)); if (mSupportedSmartSuggestionModes != AutofillManager.FLAG_SMART_SUGGESTION_OFF) { - // Must eager load the services so they bind to the augmented autofill service final UserManager um = getContext().getSystemService(UserManager.class); final List<UserInfo> users = um.getUsers(); for (int i = 0; i < users.size(); i++) { final int userId = users.get(i).id; + // Must eager load the services so they bind to the augmented autofill service getServiceForUserLocked(userId); + + // And also set the global state + mAugmentedAutofillState.setServiceInfo(userId, + mAugmentedAutofillResolver.getServiceName(userId), + mAugmentedAutofillResolver.isTemporary(userId)); } } } @@ -258,7 +270,7 @@ public final class AutofillManagerService } } - private void onDeviceConfigChange(@NonNull String key, @Nullable String value) { + private void onDeviceConfigChange(@NonNull String key) { switch (key) { case AutofillManager.DEVICE_CONFIG_AUTOFILL_SMART_SUGGESTION_SUPPORTED_MODES: case AutofillManager.DEVICE_CONFIG_AUGMENTED_SERVICE_IDLE_UNBIND_TIMEOUT: @@ -270,6 +282,14 @@ public final class AutofillManagerService } } + private void onAugmentedServiceNameChanged(@UserIdInt int userId, @Nullable String serviceName, + boolean isTemporary) { + mAugmentedAutofillState.setServiceInfo(userId, serviceName, isTemporary); + synchronized (mLock) { + getServiceForUserLocked(userId).updateRemoteAugmentedAutofillService(); + } + } + @Override // from AbstractMasterSystemService protected AutofillManagerServiceImpl newServiceLocked(@UserIdInt int resolvedUserId, boolean disabled) { @@ -783,15 +803,7 @@ public final class AutofillManagerService final boolean compatModeEnabled = mAutofillCompatState.isCompatibilityModeRequested( packageName, versionCode, userId); final AutofillOptions options = new AutofillOptions(loggingLevel, compatModeEnabled); - - synchronized (mLock) { - final AutofillManagerServiceImpl service = - getServiceForUserLocked(UserHandle.getCallingUserId()); - if (service != null) { - service.setAugmentedAutofillWhitelistLocked(options, packageName); - } - } - + mAugmentedAutofillState.injectAugmentedAutofillInfo(options, userId, packageName); return options; } } @@ -934,6 +946,89 @@ public final class AutofillManagerService } } + /** + * Augmented autofill metadata associated with all services. + * + * <p>This object is defined here instead of on each {@link AutofillManagerServiceImpl} because + * it cannot hold a lock on the main lock when + * {@link AugmentedAutofillState#injectAugmentedAutofillInfo(AutofillOptions, int, String)} + * is called by external services. + */ + static final class AugmentedAutofillState extends GlobalWhitelistState { + + @GuardedBy("mGlobalWhitelistStateLock") + private final SparseArray<String> mServicePackages = new SparseArray<>(); + @GuardedBy("mGlobalWhitelistStateLock") + private final SparseBooleanArray mTemporaryServices = new SparseBooleanArray(); + + private void setServiceInfo(@UserIdInt int userId, @Nullable String serviceName, + boolean isTemporary) { + synchronized (mGlobalWhitelistStateLock) { + if (isTemporary) { + mTemporaryServices.put(userId, true); + } else { + mTemporaryServices.delete(userId); + } + if (serviceName != null) { + final ComponentName componentName = + ComponentName.unflattenFromString(serviceName); + if (componentName == null) { + Slog.w(TAG, "setServiceInfo(): invalid name: " + serviceName); + mServicePackages.remove(userId); + } else { + mServicePackages.put(userId, componentName.getPackageName()); + } + } else { + mServicePackages.remove(userId); + } + } + } + + public void injectAugmentedAutofillInfo(@NonNull AutofillOptions options, + @UserIdInt int userId, @NonNull String packageName) { + synchronized (mGlobalWhitelistStateLock) { + if (mWhitelisterHelpers == null) return; + final WhitelistHelper helper = mWhitelisterHelpers.get(userId); + if (helper != null) { + options.augmentedAutofillEnabled = helper.isWhitelisted(packageName); + options.whitelistedActivitiesForAugmentedAutofill = helper + .getWhitelistedComponents(packageName); + } + } + } + + @Override + public boolean isWhitelisted(@UserIdInt int userId, @NonNull ComponentName componentName) { + synchronized (mGlobalWhitelistStateLock) { + if (!super.isWhitelisted(userId, componentName)) return false; + + if (Build.IS_USER && mTemporaryServices.get(userId)) { + final String packageName = componentName.getPackageName(); + if (!packageName.equals(mServicePackages.get(userId))) { + Slog.w(TAG, "Ignoring package " + packageName + " for augmented autofill " + + "while using temporary service " + mServicePackages.get(userId)); + return false; + } + } + } + return true; + } + + @Override + public void dump(@NonNull String prefix, @NonNull PrintWriter pw) { + super.dump(prefix, pw); + + synchronized (mGlobalWhitelistStateLock) { + if (mServicePackages.size() > 0) { + pw.print(prefix); pw.print("Service packages: "); pw.println(mServicePackages); + } + if (mTemporaryServices.size() > 0) { + pw.print(prefix); pw.print("Temp services: "); pw.println(mTemporaryServices); + } + } + } + } + final class AutoFillManagerServiceStub extends IAutoFillManager.Stub { @Override public void addClient(IAutoFillManagerClient client, ComponentName componentName, @@ -1370,6 +1465,8 @@ public final class AutofillManagerService pw.println(); pw.println("WTF history:"); pw.println(); mWtfHistory.reverseDump(fd, pw, args); } + pw.println("Augmented Autofill State: "); + mAugmentedAutofillState.dump(prefix, pw); } } finally { sDebug = realDebug; diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java index fe540bf3a8cf..4bd6fbd39de4 100644 --- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java +++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java @@ -31,7 +31,6 @@ import android.annotation.Nullable; import android.app.ActivityManagerInternal; import android.app.ActivityTaskManager; import android.app.IActivityTaskManager; -import android.content.AutofillOptions; import android.content.ComponentName; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; @@ -40,7 +39,6 @@ import android.graphics.Rect; import android.metrics.LogMaker; import android.os.AsyncTask; import android.os.Binder; -import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; @@ -76,7 +74,6 @@ import android.view.autofill.IAutoFillManagerClient; import com.android.internal.R; import com.android.internal.annotations.GuardedBy; -import com.android.internal.infra.WhitelistHelper; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.server.LocalServices; @@ -170,12 +167,6 @@ final class AutofillManagerServiceImpl @Nullable private ServiceInfo mRemoteAugmentedAutofillServiceInfo; - /** - * List of packages/activities that are whitelisted to be trigger augmented autofill. - */ - @GuardedBy("mLock") - private final WhitelistHelper mAugmentedWhitelistHelper = new WhitelistHelper(); - AutofillManagerServiceImpl(AutofillManagerService master, Object lock, LocalLog uiLatencyHistory, LocalLog wtfHistory, int userId, AutoFillUI ui, AutofillCompatState autofillCompatState, @@ -951,8 +942,6 @@ final class AutofillManagerServiceImpl pw.println(mRemoteAugmentedAutofillServiceInfo); } - mAugmentedWhitelistHelper.dump(prefix, "Augmented autofill whitelist", pw); - pw.print(prefix); pw.print("Field classification enabled: "); pw.println(isFieldClassificationEnabledLocked()); pw.print(prefix); pw.print("Compat pkgs: "); @@ -1234,27 +1223,7 @@ final class AutofillManagerServiceImpl @GuardedBy("mLock") boolean isWhitelistedForAugmentedAutofillLocked(@NonNull ComponentName componentName) { - if (Build.IS_USER && mMaster.mAugmentedAutofillResolver.isTemporary(mUserId)) { - final String serviceName = mMaster.mAugmentedAutofillResolver.getServiceName(mUserId); - final ComponentName component = ComponentName.unflattenFromString(serviceName); - final String servicePackage = component == null ? null : component.getPackageName(); - final String packageName = componentName.getPackageName(); - if (!packageName.equals(servicePackage)) { - Slog.w(TAG, "Ignoring package " + packageName + " for augmented autofill while " - + "using temporary service " + servicePackage); - return false; - } - } - - return mAugmentedWhitelistHelper.isWhitelisted(componentName); - } - - @GuardedBy("mLock") - void setAugmentedAutofillWhitelistLocked(@NonNull AutofillOptions options, - @NonNull String packageName) { - options.augmentedAutofillEnabled = mAugmentedWhitelistHelper.isWhitelisted(packageName); - options.whitelistedActivitiesForAugmentedAutofill = mAugmentedWhitelistHelper - .getWhitelistedComponents(packageName); + return mMaster.mAugmentedAutofillState.isWhitelisted(mUserId, componentName); } /** @@ -1268,7 +1237,7 @@ final class AutofillManagerServiceImpl if (mMaster.verbose) { Slog.v(TAG, "whitelisting packages: " + packages + "and activities: " + components); } - mAugmentedWhitelistHelper.setWhitelist(packages, components); + mMaster.mAugmentedAutofillState.setWhitelist(mUserId, packages, components); } } @@ -1280,7 +1249,7 @@ final class AutofillManagerServiceImpl if (mMaster.verbose) { Slog.v(TAG, "resetting augmented autofill whitelist"); } - whitelistForAugmentedAutofillPackages(null, null); + mMaster.mAugmentedAutofillState.resetWhitelist(mUserId); } private void sendStateToClients(boolean resetClient) { diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java index c62794d3e3d2..0402b8fb9285 100644 --- a/services/autofill/java/com/android/server/autofill/Session.java +++ b/services/autofill/java/com/android/server/autofill/Session.java @@ -2540,13 +2540,14 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState boolean saveOnFinish = true; final SaveInfo saveInfo = response.getSaveInfo(); final AutofillId saveTriggerId; + final int flags; if (saveInfo != null) { saveTriggerId = saveInfo.getTriggerId(); if (saveTriggerId != null) { writeLog(MetricsEvent.AUTOFILL_EXPLICIT_SAVE_TRIGGER_DEFINITION); } - mSaveOnAllViewsInvisible = - (saveInfo.getFlags() & SaveInfo.FLAG_SAVE_ON_ALL_VIEWS_INVISIBLE) != 0; + flags = saveInfo.getFlags(); + mSaveOnAllViewsInvisible = (flags & SaveInfo.FLAG_SAVE_ON_ALL_VIEWS_INVISIBLE) != 0; // We only need to track views if we want to save once they become invisible. if (mSaveOnAllViewsInvisible) { @@ -2561,11 +2562,12 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState Collections.addAll(trackedViews, saveInfo.getOptionalIds()); } } - if ((saveInfo.getFlags() & SaveInfo.FLAG_DONT_SAVE_ON_FINISH) != 0) { + if ((flags & SaveInfo.FLAG_DONT_SAVE_ON_FINISH) != 0) { saveOnFinish = false; } } else { + flags = 0; saveTriggerId = null; } @@ -2592,7 +2594,8 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState try { if (sVerbose) { Slog.v(TAG, "updateTrackedIdsLocked(): " + trackedViews + " => " + fillableIds - + " triggerId: " + saveTriggerId + " saveOnFinish:" + saveOnFinish); + + " triggerId: " + saveTriggerId + " saveOnFinish:" + saveOnFinish + + " flags: " + flags + " hasSaveInfo: " + (saveInfo != null)); } mClient.setTrackedViews(id, toArray(trackedViews), mSaveOnAllViewsInvisible, saveOnFinish, toArray(fillableIds), saveTriggerId); diff --git a/services/backup/java/com/android/server/backup/Trampoline.java b/services/backup/java/com/android/server/backup/Trampoline.java index 8f0c5d812e1c..bb0aba0c2e88 100644 --- a/services/backup/java/com/android/server/backup/Trampoline.java +++ b/services/backup/java/com/android/server/backup/Trampoline.java @@ -395,7 +395,7 @@ public class Trampoline extends IBackupManager.Stub { @Override public boolean isBackupServiceActive(int userId) { synchronized (mStateLock) { - return isUserReadyForBackup(userId); + return mService != null && isBackupActivatedForUser(userId); } } diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java index 3865b2779466..a7404bc63e2a 100644 --- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java +++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java @@ -72,7 +72,9 @@ import com.android.internal.util.ArrayUtils; import com.android.internal.util.CollectionUtils; import com.android.internal.util.function.pooled.PooledLambda; import com.android.server.FgThread; +import com.android.server.LocalServices; import com.android.server.SystemService; +import com.android.server.wm.ActivityTaskManagerInternal; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; @@ -84,6 +86,7 @@ import java.io.FileInputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; import java.util.Objects; import java.util.Set; @@ -519,6 +522,11 @@ public class CompanionDeviceManagerService extends SystemService implements Bind if (size(old) == size(associations)) return; Set<Association> finalAssociations = associations; + Set<String> companionAppPackages = new HashSet<>(); + for (Association association : finalAssociations) { + companionAppPackages.add(association.companionAppPackage); + } + file.write((out) -> { XmlSerializer xml = Xml.newSerializer(); try { @@ -542,6 +550,9 @@ public class CompanionDeviceManagerService extends SystemService implements Bind } }); + ActivityTaskManagerInternal atmInternal = LocalServices.getService( + ActivityTaskManagerInternal.class); + atmInternal.setCompanionAppPackages(userId, companionAppPackages); } } diff --git a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java index b2760e037f44..9b02c4e72cfc 100644 --- a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java +++ b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java @@ -18,6 +18,7 @@ package com.android.server.contentcapture; import static android.Manifest.permission.MANAGE_CONTENT_CAPTURE; import static android.content.Context.CONTENT_CAPTURE_MANAGER_SERVICE; +import static android.view.contentcapture.ContentCaptureHelper.toList; import static android.view.contentcapture.ContentCaptureManager.RESULT_CODE_FALSE; import static android.view.contentcapture.ContentCaptureManager.RESULT_CODE_OK; import static android.view.contentcapture.ContentCaptureManager.RESULT_CODE_SECURITY_EXCEPTION; @@ -40,6 +41,7 @@ import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.UserInfo; import android.database.ContentObserver; import android.os.Binder; +import android.os.Build; import android.os.Bundle; import android.os.IBinder; import android.os.RemoteException; @@ -50,9 +52,12 @@ import android.os.UserManager; import android.provider.DeviceConfig; import android.provider.Settings; import android.service.contentcapture.ActivityEvent.ActivityEventType; +import android.util.ArraySet; import android.util.LocalLog; import android.util.Slog; +import android.util.SparseArray; import android.util.SparseBooleanArray; +import android.view.contentcapture.ContentCaptureCondition; import android.view.contentcapture.ContentCaptureHelper; import android.view.contentcapture.ContentCaptureManager; import android.view.contentcapture.IContentCaptureManager; @@ -60,6 +65,7 @@ import android.view.contentcapture.UserDataRemovalRequest; import com.android.internal.annotations.GuardedBy; import com.android.internal.infra.AbstractRemoteService; +import com.android.internal.infra.GlobalWhitelistState; import com.android.internal.os.IResultReceiver; import com.android.internal.util.DumpUtils; import com.android.internal.util.Preconditions; @@ -117,10 +123,13 @@ public final class ContentCaptureManagerService extends @GuardedBy("mLock") int mDevCfgLogHistorySize; @GuardedBy("mLock") int mDevCfgIdleUnbindTimeoutMs; + final GlobalContentCaptureOptions mGlobalContentCaptureOptions = + new GlobalContentCaptureOptions(); + public ContentCaptureManagerService(@NonNull Context context) { super(context, new FrameworkResourcesServiceNameResolver(context, com.android.internal.R.string.config_defaultContentCaptureService), - UserManager.DISALLOW_CONTENT_CAPTURE, /* refreshServiceOnPackageUpdate=*/ false); + UserManager.DISALLOW_CONTENT_CAPTURE, /* refreshServiceOnPackageUpdate= */ false); DeviceConfig.addOnPropertyChangedListener(DeviceConfig.NAMESPACE_CONTENT_CAPTURE, ActivityThread.currentApplication().getMainExecutor(), (namespace, key, value) -> onDeviceConfigChange(key, value)); @@ -136,12 +145,12 @@ public final class ContentCaptureManagerService extends mRequestsHistory = null; } - // Sets which services are disabled by settings final UserManager um = getContext().getSystemService(UserManager.class); final List<UserInfo> users = um.getUsers(); for (int i = 0; i < users.size(); i++) { final int userId = users.get(i).id; final boolean disabled = !isEnabledBySettings(userId); + // Sets which services are disabled by settings if (disabled) { Slog.i(mTag, "user " + userId + " disabled by settings"); if (mDisabledBySettings == null) { @@ -149,6 +158,10 @@ public final class ContentCaptureManagerService extends } mDisabledBySettings.put(userId, true); } + // Sets the global options for the service. + mGlobalContentCaptureOptions.setServiceInfo(userId, + mServiceNameResolver.getServiceName(userId), + mServiceNameResolver.isTemporary(userId)); } } @@ -188,6 +201,14 @@ public final class ContentCaptureManagerService extends } @Override // from AbstractMasterSystemService + protected void onServiceNameChanged(@UserIdInt int userId, @NonNull String serviceName, + boolean isTemporary) { + mGlobalContentCaptureOptions.setServiceInfo(userId, serviceName, isTemporary); + + super.onServiceNameChanged(userId, serviceName, isTemporary); + } + + @Override // from AbstractMasterSystemService protected void enforceCallingPermissionForManagement() { getContext().enforceCallingPermission(MANAGE_CONTENT_CAPTURE, mTag); } @@ -429,23 +450,16 @@ public final class ContentCaptureManagerService extends } @GuardedBy("mLock") - private boolean assertCalledByServiceLocked(@NonNull String methodName, @UserIdInt int userId, - int callingUid, @NonNull IResultReceiver result) { - final boolean isService = isCalledByServiceLocked(methodName, userId, callingUid); - if (isService) return true; - - try { - result.send(RESULT_CODE_SECURITY_EXCEPTION, /* resultData= */ null); - } catch (RemoteException e) { - Slog.w(mTag, "Unable to send isContentCaptureFeatureEnabled(): " + e); + private void assertCalledByServiceLocked(@NonNull String methodName) { + if (!isCalledByServiceLocked(methodName)) { + throw new SecurityException("caller is not user's ContentCapture service"); } - return false; } @GuardedBy("mLock") - private boolean isCalledByServiceLocked(@NonNull String methodName, @UserIdInt int userId, - int callingUid) { - + private boolean isCalledByServiceLocked(@NonNull String methodName) { + final int userId = UserHandle.getCallingUserId(); + final int callingUid = Binder.getCallingUid(); final String serviceName = mServiceNameResolver.getServiceName(userId); if (serviceName == null) { Slog.e(mTag, methodName + ": called by UID " + callingUid @@ -453,7 +467,7 @@ public final class ContentCaptureManagerService extends return false; } - final ComponentName serviceComponent = ComponentName.unflattenFromString(serviceName); + final ComponentName serviceComponent = ComponentName.unflattenFromString(serviceName); if (serviceComponent == null) { Slog.w(mTag, methodName + ": invalid service name: " + serviceName); return false; @@ -478,6 +492,27 @@ public final class ContentCaptureManagerService extends return true; } + /** + * Executes the given {@code runnable} and if it throws a {@link SecurityException}, + * send it back to the receiver. + * + * @return whether the exception was thrown or not. + */ + private boolean throwsSecurityException(@NonNull IResultReceiver result, + @NonNull Runnable runable) { + try { + runable.run(); + return false; + } catch (SecurityException e) { + try { + result.send(RESULT_CODE_SECURITY_EXCEPTION, bundleFor(e.getMessage())); + } catch (RemoteException e2) { + Slog.w(mTag, "Unable to send security exception (" + e + "): ", e2); + } + } + return true; + } + @Override // from AbstractMasterSystemService protected void dumpLocked(String prefix, PrintWriter pw) { super.dumpLocked(prefix, pw); @@ -496,13 +531,15 @@ public final class ContentCaptureManagerService extends pw.print(prefix2); pw.print("logHistorySize: "); pw.println(mDevCfgLogHistorySize); pw.print(prefix2); pw.print("idleUnbindTimeoutMs: "); pw.println(mDevCfgIdleUnbindTimeoutMs); + pw.print(prefix); pw.println("Global Options:"); + mGlobalContentCaptureOptions.dump(prefix2, pw); } final class ContentCaptureManagerServiceStub extends IContentCaptureManager.Stub { @Override public void startSession(@NonNull IBinder activityToken, - @NonNull ComponentName componentName, @NonNull String sessionId, int flags, + @NonNull ComponentName componentName, int sessionId, int flags, @NonNull IResultReceiver result) { Preconditions.checkNotNull(activityToken); Preconditions.checkNotNull(sessionId); @@ -519,7 +556,7 @@ public final class ContentCaptureManagerService extends } @Override - public void finishSession(@NonNull String sessionId) { + public void finishSession(int sessionId) { Preconditions.checkNotNull(sessionId); final int userId = UserHandle.getCallingUserId(); @@ -547,6 +584,8 @@ public final class ContentCaptureManagerService extends @Override public void removeUserData(@NonNull UserDataRemovalRequest request) { Preconditions.checkNotNull(request); + assertCalledByPackageOwner(request.getPackageName()); + final int userId = UserHandle.getCallingUserId(); synchronized (mLock) { final ContentCapturePerUserService service = getServiceForUserLocked(userId); @@ -556,13 +595,14 @@ public final class ContentCaptureManagerService extends @Override public void isContentCaptureFeatureEnabled(@NonNull IResultReceiver result) { - final int userId = UserHandle.getCallingUserId(); boolean enabled; synchronized (mLock) { - final boolean isService = assertCalledByServiceLocked( - "isContentCaptureFeatureEnabled()", userId, Binder.getCallingUid(), result); - if (!isService) return; + if (throwsSecurityException(result, + () -> assertCalledByServiceLocked("isContentCaptureFeatureEnabled()"))) { + return; + } + final int userId = UserHandle.getCallingUserId(); enabled = !mDisabledByDeviceConfig && !isDisabledBySettingsLocked(userId); } try { @@ -574,15 +614,8 @@ public final class ContentCaptureManagerService extends @Override public void getServiceSettingsActivity(@NonNull IResultReceiver result) { - try { - enforceCallingPermissionForManagement(); - } catch (SecurityException e) { - try { - result.send(RESULT_CODE_SECURITY_EXCEPTION, bundleFor(e.getMessage())); - } catch (RemoteException e2) { - Slog.w(mTag, "Unable to send getServiceSettingsIntent() exception: " + e2); - return; - } + if (throwsSecurityException(result, () -> enforceCallingPermissionForManagement())) { + return; } final int userId = UserHandle.getCallingUserId(); @@ -600,13 +633,34 @@ public final class ContentCaptureManagerService extends } @Override + public void getContentCaptureConditions(@NonNull String packageName, + @NonNull IResultReceiver result) { + if (throwsSecurityException(result, () -> assertCalledByPackageOwner(packageName))) { + return; + } + + final int userId = UserHandle.getCallingUserId(); + final ArrayList<ContentCaptureCondition> conditions; + synchronized (mLock) { + final ContentCapturePerUserService service = getServiceForUserLocked(userId); + conditions = service == null ? null + : toList(service.getContentCaptureConditionsLocked(packageName)); + } + try { + result.send(RESULT_CODE_OK, bundleFor(conditions)); + } catch (RemoteException e) { + Slog.w(mTag, "Unable to send getServiceComponentName(): " + e); + } + } + + @Override public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { if (!DumpUtils.checkDumpPermission(getContext(), mTag, pw)) return; boolean showHistory = true; if (args != null) { for (String arg : args) { - switch(arg) { + switch (arg) { case "--no-history": showHistory = false; break; @@ -670,13 +724,7 @@ public final class ContentCaptureManagerService extends @Override public ContentCaptureOptions getOptionsForPackage(int userId, @NonNull String packageName) { - synchronized (mLock) { - final ContentCapturePerUserService service = peekServiceForUserLocked(userId); - if (service != null) { - return service.getOptionsForPackageLocked(packageName); - } - } - return null; + return mGlobalContentCaptureOptions.getOptions(userId, packageName); } @Override @@ -690,4 +738,92 @@ public final class ContentCaptureManagerService extends } } } + + /** + * Content capture options associated with all services. + * + * <p>This object is defined here instead of on each {@link ContentCapturePerUserService} + * because it cannot hold a lock on the main lock when + * {@link GlobalContentCaptureOptions#getOptions(int, String)} is called by external services. + */ + final class GlobalContentCaptureOptions extends GlobalWhitelistState { + + @GuardedBy("mGlobalWhitelistStateLock") + private final SparseArray<String> mServicePackages = new SparseArray<>(); + @GuardedBy("mGlobalWhitelistStateLock") + private final SparseBooleanArray mTemporaryServices = new SparseBooleanArray(); + + private void setServiceInfo(@UserIdInt int userId, @Nullable String serviceName, + boolean isTemporary) { + synchronized (mGlobalWhitelistStateLock) { + if (isTemporary) { + mTemporaryServices.put(userId, true); + } else { + mTemporaryServices.delete(userId); + } + if (serviceName != null) { + final ComponentName componentName = + ComponentName.unflattenFromString(serviceName); + if (componentName == null) { + Slog.w(mTag, "setServiceInfo(): invalid name: " + serviceName); + mServicePackages.remove(userId); + } else { + mServicePackages.put(userId, componentName.getPackageName()); + } + } else { + mServicePackages.remove(userId); + } + } + } + + @Nullable + @GuardedBy("mGlobalWhitelistStateLock") + public ContentCaptureOptions getOptions(@UserIdInt int userId, + @NonNull String packageName) { + synchronized (mGlobalWhitelistStateLock) { + if (!isWhitelisted(userId, packageName)) { + if (packageName.equals(mServicePackages.get(userId))) { + if (verbose) Slog.v(mTag, "getOptionsForPackage() lite for " + packageName); + return new ContentCaptureOptions(mDevCfgLoggingLevel); + } + if (verbose) { + Slog.v(mTag, "getOptionsForPackage(" + packageName + "): not whitelisted"); + } + return null; + } + + final ArraySet<ComponentName> whitelistedComponents = + getWhitelistedComponents(userId, packageName); + if (Build.IS_USER && mServiceNameResolver.isTemporary(userId)) { + if (!packageName.equals(mServicePackages.get(userId))) { + Slog.w(mTag, "Ignoring package " + packageName + + " while using temporary service " + mServicePackages.get(userId)); + return null; + } + } + final ContentCaptureOptions options = new ContentCaptureOptions(mDevCfgLoggingLevel, + mDevCfgMaxBufferSize, mDevCfgIdleFlushingFrequencyMs, + mDevCfgTextChangeFlushingFrequencyMs, mDevCfgLogHistorySize, + whitelistedComponents); + if (verbose) { + Slog.v(mTag, "getOptionsForPackage(" + packageName + "): " + options); + } + return options; + } + } + + @Override + public void dump(@NonNull String prefix, @NonNull PrintWriter pw) { + super.dump(prefix, pw); + + synchronized (mGlobalWhitelistStateLock) { + if (mServicePackages.size() > 0) { + pw.print(prefix); pw.print("Service packages: "); pw.println(mServicePackages); + } + if (mTemporaryServices.size() > 0) { + pw.print(prefix); pw.print("Temp services: "); pw.println(mTemporaryServices); + } + } + } + } } diff --git a/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java b/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java index f0c6f7e7b0b8..564952697250 100644 --- a/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java +++ b/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java @@ -17,6 +17,7 @@ package com.android.server.contentcapture; import static android.service.contentcapture.ContentCaptureService.setClientState; +import static android.view.contentcapture.ContentCaptureSession.NO_SESSION_ID; import static android.view.contentcapture.ContentCaptureSession.STATE_DISABLED; import static android.view.contentcapture.ContentCaptureSession.STATE_DUPLICATED_ID; import static android.view.contentcapture.ContentCaptureSession.STATE_INTERNAL_ERROR; @@ -54,6 +55,8 @@ import android.service.contentcapture.SnapshotData; import android.util.ArrayMap; import android.util.ArraySet; import android.util.Slog; +import android.util.SparseArray; +import android.view.contentcapture.ContentCaptureCondition; import android.view.contentcapture.UserDataRemovalRequest; import com.android.internal.annotations.GuardedBy; @@ -78,8 +81,7 @@ final class ContentCapturePerUserService private static final String TAG = ContentCapturePerUserService.class.getSimpleName(); @GuardedBy("mLock") - private final ArrayMap<String, ContentCaptureServerSession> mSessions = - new ArrayMap<>(); + private final SparseArray<ContentCaptureServerSession> mSessions = new SparseArray<>(); /** * Reference to the remote service. @@ -101,6 +103,13 @@ final class ContentCapturePerUserService private final WhitelistHelper mWhitelistHelper = new WhitelistHelper(); /** + * List of conditions keyed by package. + */ + @GuardedBy("mLock") + private final ArrayMap<String, ArraySet<ContentCaptureCondition>> mConditionsByPkg = + new ArrayMap<>(); + + /** * When {@code true}, remote service died but service state is kept so it's restored after * the system re-binds to it. */ @@ -226,9 +235,8 @@ final class ContentCapturePerUserService // TODO(b/119613670): log metrics @GuardedBy("mLock") public void startSessionLocked(@NonNull IBinder activityToken, - @NonNull ActivityPresentationInfo activityPresentationInfo, - @NonNull String sessionId, int uid, int flags, - @NonNull IResultReceiver clientReceiver) { + @NonNull ActivityPresentationInfo activityPresentationInfo, int sessionId, int uid, + int flags, @NonNull IResultReceiver clientReceiver) { if (activityPresentationInfo == null) { Slog.w(TAG, "basic activity info is null"); setClientState(clientReceiver, STATE_DISABLED | STATE_INTERNAL_ERROR, @@ -238,7 +246,8 @@ final class ContentCapturePerUserService final int taskId = activityPresentationInfo.taskId; final int displayId = activityPresentationInfo.displayId; final ComponentName componentName = activityPresentationInfo.componentName; - final boolean whiteListed = isWhitelistedLocked(componentName); + final boolean whiteListed = mMaster.mGlobalContentCaptureOptions.isWhitelisted(mUserId, + componentName); final ComponentName serviceComponentName = getServiceComponentName(); final boolean enabled = isEnabledLocked(); if (mMaster.mRequestsHistory != null) { @@ -315,14 +324,9 @@ final class ContentCapturePerUserService newSession.notifySessionStartedLocked(clientReceiver); } - @GuardedBy("mLock") - private boolean isWhitelistedLocked(@NonNull ComponentName componentName) { - return mWhitelistHelper.isWhitelisted(componentName); - } - // TODO(b/119613670): log metrics @GuardedBy("mLock") - public void finishSessionLocked(@NonNull String sessionId) { + public void finishSessionLocked(int sessionId) { if (!isEnabledLocked()) { return; } @@ -386,8 +390,8 @@ final class ContentCapturePerUserService @GuardedBy("mLock") public boolean sendActivityAssistDataLocked(@NonNull IBinder activityToken, @NonNull Bundle data) { - final String id = getSessionId(activityToken); - if (id != null) { + final int id = getSessionId(activityToken); + if (id != NO_SESSION_ID) { final ContentCaptureServerSession session = mSessions.get(id); final Bundle assistData = data.getBundle(ASSIST_KEY_DATA); final AssistStructure assistStructure = data.getParcelable(ASSIST_KEY_STRUCTURE); @@ -403,7 +407,7 @@ final class ContentCapturePerUserService } @GuardedBy("mLock") - public void removeSessionLocked(@NonNull String sessionId) { + public void removeSessionLocked(int sessionId) { mSessions.remove(sessionId); } @@ -480,7 +484,7 @@ final class ContentCapturePerUserService return null; } } - ContentCaptureOptions options = new ContentCaptureOptions(mMaster.mDevCfgLoggingLevel, + final ContentCaptureOptions options = new ContentCaptureOptions(mMaster.mDevCfgLoggingLevel, mMaster.mDevCfgMaxBufferSize, mMaster.mDevCfgIdleFlushingFrequencyMs, mMaster.mDevCfgTextChangeFlushingFrequencyMs, mMaster.mDevCfgLogHistorySize, whitelistedComponents); @@ -491,6 +495,13 @@ final class ContentCapturePerUserService } @GuardedBy("mLock") + @Nullable + ArraySet<ContentCaptureCondition> getContentCaptureConditionsLocked( + @NonNull String packageName) { + return mConditionsByPkg.get(packageName); + } + + @GuardedBy("mLock") void onActivityEventLocked(@NonNull ComponentName componentName, @ActivityEventType int type) { if (mRemoteService == null) { if (mMaster.debug) Slog.d(mTag, "onActivityEvent(): no remote service"); @@ -522,9 +533,7 @@ final class ContentCapturePerUserService mRemoteService.dump(prefix2, pw); } - mWhitelistHelper.dump(prefix, "Whitelist", pw); - - if (mSessions.isEmpty()) { + if (mSessions.size() == 0) { pw.print(prefix); pw.println("no sessions"); } else { final int sessionsSize = mSessions.size(); @@ -542,14 +551,14 @@ final class ContentCapturePerUserService * Returns the session id associated with the given activity. */ @GuardedBy("mLock") - private String getSessionId(@NonNull IBinder activityToken) { + private int getSessionId(@NonNull IBinder activityToken) { for (int i = 0; i < mSessions.size(); i++) { ContentCaptureServerSession session = mSessions.valueAt(i); if (session.isActivitySession(activityToken)) { return mSessions.keyAt(i); } } - return null; + return NO_SESSION_ID; } /** @@ -560,7 +569,7 @@ final class ContentCapturePerUserService if (mMaster.verbose) { Slog.v(TAG, "resetting content capture whitelist"); } - mWhitelistHelper.setWhitelist((List) null, null); + mMaster.mGlobalContentCaptureOptions.resetWhitelist(mUserId); } private final class ContentCaptureServiceRemoteCallback extends @@ -576,9 +585,24 @@ final class ContentCapturePerUserService + ", " + (activities == null ? "null_activities" : activities.size() + " activities") + ")"); } + mMaster.mGlobalContentCaptureOptions.setWhitelist(mUserId, packages, activities); + } + + @Override + public void setContentCaptureConditions(String packageName, + List<ContentCaptureCondition> conditions) { + if (mMaster.verbose) { + Slog.v(TAG, "setContentCaptureConditions(" + packageName + "): " + + (conditions == null ? "null" : conditions.size() + " conditions")); + } synchronized (mLock) { - mWhitelistHelper.setWhitelist(packages, activities); + if (conditions == null) { + mConditionsByPkg.remove(packageName); + } else { + mConditionsByPkg.put(packageName, new ArraySet<>(conditions)); + } } + // TODO(b/119613670): log metrics } @Override diff --git a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureServerSession.java b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureServerSession.java index 9b2c05f7fa79..1ad66d869eae 100644 --- a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureServerSession.java +++ b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureServerSession.java @@ -16,6 +16,7 @@ package com.android.server.contentcapture; import static android.service.contentcapture.ContentCaptureService.setClientState; +import static android.view.contentcapture.ContentCaptureSession.NO_SESSION_ID; import static android.view.contentcapture.ContentCaptureSession.STATE_ACTIVE; import static android.view.contentcapture.ContentCaptureSession.STATE_DISABLED; import static android.view.contentcapture.ContentCaptureSession.STATE_SERVICE_RESURRECTED; @@ -57,7 +58,7 @@ final class ContentCaptureServerSession { /** * Canonical session id. */ - private final String mId; + private final int mId; /** * UID of the app whose contents is being captured. @@ -66,11 +67,12 @@ final class ContentCaptureServerSession { ContentCaptureServerSession(@NonNull IBinder activityToken, @NonNull ContentCapturePerUserService service, @NonNull ComponentName appComponentName, - @NonNull IResultReceiver sessionStateReceiver, - int taskId, int displayId, @NonNull String sessionId, int uid, int flags) { + @NonNull IResultReceiver sessionStateReceiver, int taskId, int displayId, int sessionId, + int uid, int flags) { + Preconditions.checkArgument(sessionId != NO_SESSION_ID); mActivityToken = activityToken; mService = service; - mId = Preconditions.checkNotNull(sessionId); + mId = sessionId; mUid = uid; mContentCaptureContext = new ContentCaptureContext(/* clientContext= */ null, appComponentName, taskId, displayId, flags); diff --git a/services/contentcapture/java/com/android/server/contentcapture/RemoteContentCaptureService.java b/services/contentcapture/java/com/android/server/contentcapture/RemoteContentCaptureService.java index 0afe252d96bd..3fa3fdf6d36e 100644 --- a/services/contentcapture/java/com/android/server/contentcapture/RemoteContentCaptureService.java +++ b/services/contentcapture/java/com/android/server/contentcapture/RemoteContentCaptureService.java @@ -98,9 +98,8 @@ final class RemoteContentCaptureService * Called by {@link ContentCaptureServerSession} to generate a call to the * {@link RemoteContentCaptureService} to indicate the session was created. */ - public void onSessionStarted(@Nullable ContentCaptureContext context, - @NonNull String sessionId, int uid, @NonNull IResultReceiver clientReceiver, - int initialState) { + public void onSessionStarted(@Nullable ContentCaptureContext context, int sessionId, int uid, + @NonNull IResultReceiver clientReceiver, int initialState) { scheduleAsyncRequest( (s) -> s.onSessionStarted(context, sessionId, uid, clientReceiver, initialState)); } @@ -109,15 +108,14 @@ final class RemoteContentCaptureService * Called by {@link ContentCaptureServerSession} to generate a call to the * {@link RemoteContentCaptureService} to indicate the session was finished. */ - public void onSessionFinished(@NonNull String sessionId) { + public void onSessionFinished(int sessionId) { scheduleAsyncRequest((s) -> s.onSessionFinished(sessionId)); } /** * Called by {@link ContentCaptureServerSession} to send snapshot data to the service. */ - public void onActivitySnapshotRequest(@NonNull String sessionId, - @NonNull SnapshotData snapshotData) { + public void onActivitySnapshotRequest(int sessionId, @NonNull SnapshotData snapshotData) { scheduleAsyncRequest((s) -> s.onActivitySnapshot(sessionId, snapshotData)); } diff --git a/services/core/Android.bp b/services/core/Android.bp index c154240f2b9a..9e1b3b8abc99 100644 --- a/services/core/Android.bp +++ b/services/core/Android.bp @@ -51,6 +51,7 @@ java_library_static { "android.hardware.configstore-V1.0-java", "android.hardware.contexthub-V1.0-java", "android.hidl.manager-V1.2-java", + "dnsresolver_aidl_interface-java", "netd_aidl_interface-java", "netd_event_listener_interface-java", ], diff --git a/services/core/java/com/android/server/BatteryService.java b/services/core/java/com/android/server/BatteryService.java index 39f7f0f0d1a8..6a9f5b651016 100644 --- a/services/core/java/com/android/server/BatteryService.java +++ b/services/core/java/com/android/server/BatteryService.java @@ -357,10 +357,27 @@ public final class BatteryService extends SystemService { && (oldPlugged || mLastBatteryLevel > mLowBatteryWarningLevel); } + private boolean shouldShutdownLocked() { + if (mHealthInfo.batteryLevel > 0) { + return false; + } + + // Battery-less devices should not shutdown. + if (!mHealthInfo.batteryPresent) { + return false; + } + + // If battery state is not CHARGING, shutdown. + // - If battery present and state == unknown, this is an unexpected error state. + // - If level <= 0 and state == full, this is also an unexpected state + // - All other states (NOT_CHARGING, DISCHARGING) means it is not charging. + return mHealthInfo.batteryStatus != BatteryManager.BATTERY_STATUS_CHARGING; + } + private void shutdownIfNoPowerLocked() { // shut down gracefully if our battery is critically low and we are not powered. // wait until the system has booted before attempting to display the shutdown dialog. - if (mHealthInfo.batteryLevel == 0 && !isPoweredLocked(BatteryManager.BATTERY_PLUGGED_ANY)) { + if (shouldShutdownLocked()) { mHandler.post(new Runnable() { @Override public void run() { diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index 2be92cde68ec..8ad23b0e3074 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -63,6 +63,7 @@ import android.net.ConnectionInfo; import android.net.ConnectivityManager; import android.net.ICaptivePortal; import android.net.IConnectivityManager; +import android.net.IDnsResolver; import android.net.IIpConnectivityMetrics; import android.net.INetd; import android.net.INetdEventCallback; @@ -294,6 +295,8 @@ public class ConnectivityService extends IConnectivityManager.Stub private INetworkManagementService mNMS; @VisibleForTesting + protected IDnsResolver mDnsResolver; + @VisibleForTesting protected INetd mNetd; private INetworkStatsService mStatsService; private INetworkPolicyManager mPolicyManager; @@ -525,6 +528,11 @@ public class ConnectivityService extends IConnectivityManager.Stub return sMagicDecoderRing.get(what, Integer.toString(what)); } + private static IDnsResolver getDnsResolver() { + return IDnsResolver.Stub + .asInterface(ServiceManager.getService("dnsresolver")); + } + /** Handler thread used for both of the handlers below. */ @VisibleForTesting protected final HandlerThread mHandlerThread; @@ -810,13 +818,14 @@ public class ConnectivityService extends IConnectivityManager.Stub public ConnectivityService(Context context, INetworkManagementService netManager, INetworkStatsService statsService, INetworkPolicyManager policyManager) { - this(context, netManager, statsService, policyManager, new IpConnectivityLog()); + this(context, netManager, statsService, policyManager, + getDnsResolver(), new IpConnectivityLog()); } @VisibleForTesting protected ConnectivityService(Context context, INetworkManagementService netManager, INetworkStatsService statsService, INetworkPolicyManager policyManager, - IpConnectivityLog logger) { + IDnsResolver dnsresolver, IpConnectivityLog logger) { if (DBG) log("ConnectivityService starting up"); mSystemProperties = getSystemProperties(); @@ -853,6 +862,7 @@ public class ConnectivityService extends IConnectivityManager.Stub mPolicyManagerInternal = checkNotNull( LocalServices.getService(NetworkPolicyManagerInternal.class), "missing NetworkPolicyManagerInternal"); + mDnsResolver = checkNotNull(dnsresolver, "missing IDnsResolver"); mProxyTracker = makeProxyTracker(); mNetd = NetdService.getInstance(); @@ -1006,7 +1016,7 @@ public class ConnectivityService extends IConnectivityManager.Stub mMultipathPolicyTracker = new MultipathPolicyTracker(mContext, mHandler); - mDnsManager = new DnsManager(mContext, mNMS, mSystemProperties); + mDnsManager = new DnsManager(mContext, mDnsResolver, mSystemProperties); registerPrivateDnsSettingsCallbacks(); } @@ -1882,6 +1892,15 @@ public class ConnectivityService extends IConnectivityManager.Stub return false; } + private boolean checkAnyPermissionOf(int pid, int uid, String... permissions) { + for (String permission : permissions) { + if (mContext.checkPermission(permission, pid, uid) == PERMISSION_GRANTED) { + return true; + } + } + return false; + } + private void enforceAnyPermissionOf(String... permissions) { if (!checkAnyPermissionOf(permissions)) { throw new SecurityException("Requires one of the following permissions: " @@ -1956,6 +1975,12 @@ public class ConnectivityService extends IConnectivityManager.Stub NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK); } + private boolean checkNetworkSignalStrengthWakeupPermission(int pid, int uid) { + return checkAnyPermissionOf(pid, uid, + android.Manifest.permission.NETWORK_SIGNAL_STRENGTH_WAKEUP, + NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK); + } + private void enforceConnectivityRestrictedNetworksPermission() { try { mContext.enforceCallingOrSelfPermission( @@ -3021,9 +3046,9 @@ public class ConnectivityService extends IConnectivityManager.Stub // NetworkFactories, so network traffic isn't interrupted for an unnecessarily // long time. try { - mNMS.removeNetwork(nai.network.netId); - } catch (Exception e) { - loge("Exception removing network: " + e); + mNetd.networkDestroy(nai.network.netId); + } catch (RemoteException | ServiceSpecificException e) { + loge("Exception destroying network: " + e); } mDnsManager.removeNetwork(nai.network); } @@ -3728,16 +3753,6 @@ public class ConnectivityService extends IConnectivityManager.Stub break; } case EVENT_SYSTEM_READY: { - for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) { - // Might have been called already in handleRegisterNetworkAgent since - // mSystemReady is set before sending EVENT_SYSTEM_READY, but calling - // this several times is fine. - try { - nai.networkMonitor().notifySystemReady(); - } catch (RemoteException e) { - e.rethrowFromSystemServer(); - } - } mMultipathPolicyTracker.start(); break; } @@ -4952,13 +4967,19 @@ public class ConnectivityService extends IConnectivityManager.Stub } } - // This checks that the passed capabilities either do not request a specific SSID, or the - // calling app has permission to do so. + // This checks that the passed capabilities either do not request a specific SSID/SignalStrength + // , or the calling app has permission to do so. private void ensureSufficientPermissionsForRequest(NetworkCapabilities nc, int callerPid, int callerUid) { if (null != nc.getSSID() && !checkSettingsPermission(callerPid, callerUid)) { throw new SecurityException("Insufficient permissions to request a specific SSID"); } + + if (nc.hasSignalStrength() + && !checkNetworkSignalStrengthWakeupPermission(callerPid, callerUid)) { + throw new SecurityException( + "Insufficient permissions to request a specific signal strength"); + } } private ArrayList<Integer> getSignalStrengthThresholds(NetworkAgentInfo nai) { @@ -5372,10 +5393,10 @@ public class ConnectivityService extends IConnectivityManager.Stub final NetworkCapabilities nc = new NetworkCapabilities(networkCapabilities); final NetworkAgentInfo nai = new NetworkAgentInfo(messenger, new AsyncChannel(), new Network(reserveNetId()), new NetworkInfo(networkInfo), lp, nc, currentScore, - mContext, mTrackerHandler, new NetworkMisc(networkMisc), this, mNetd, mNMS, - factorySerialNumber); + mContext, mTrackerHandler, new NetworkMisc(networkMisc), this, mNetd, mDnsResolver, + mNMS, factorySerialNumber); // Make sure the network capabilities reflect what the agent info says. - nai.networkCapabilities = mixInCapabilities(nai, nc); + nai.setNetworkCapabilities(mixInCapabilities(nai, nc)); final String extraInfo = networkInfo.getExtraInfo(); final String name = TextUtils.isEmpty(extraInfo) ? nai.networkCapabilities.getSSID() : extraInfo; @@ -5406,15 +5427,6 @@ public class ConnectivityService extends IConnectivityManager.Stub synchronized (mNetworkForNetId) { mNetworkForNetId.put(nai.network.netId, nai); } - synchronized (this) { - if (mSystemReady) { - try { - networkMonitor.notifySystemReady(); - } catch (RemoteException e) { - e.rethrowFromSystemServer(); - } - } - } try { networkMonitor.start(); @@ -5468,12 +5480,12 @@ public class ConnectivityService extends IConnectivityManager.Stub // Start or stop DNS64 detection and 464xlat according to network state. networkAgent.clatd.update(); notifyIfacesChangedForNetworkStats(); + try { + networkAgent.networkMonitor().notifyLinkPropertiesChanged(newLp); + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + } if (networkAgent.everConnected) { - try { - networkAgent.networkMonitor().notifyLinkPropertiesChanged(); - } catch (RemoteException e) { - e.rethrowFromSystemServer(); - } notifyNetworkCallbacks(networkAgent, ConnectivityManager.CALLBACK_IP_CHANGED); } } @@ -5701,7 +5713,7 @@ public class ConnectivityService extends IConnectivityManager.Stub final NetworkCapabilities prevNc; synchronized (nai) { prevNc = nai.networkCapabilities; - nai.networkCapabilities = newNc; + nai.setNetworkCapabilities(newNc); } updateUids(nai, prevNc, newNc); @@ -5716,11 +5728,6 @@ public class ConnectivityService extends IConnectivityManager.Stub // If the requestable capabilities have changed or the score changed, we can't have been // called by rematchNetworkAndRequests, so it's safe to start a rematch. rematchAllNetworksAndRequests(nai, oldScore); - try { - nai.networkMonitor().notifyNetworkCapabilitiesChanged(); - } catch (RemoteException e) { - e.rethrowFromSystemServer(); - } notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_CAP_CHANGED); } @@ -5979,11 +5986,6 @@ public class ConnectivityService extends IConnectivityManager.Stub } if (capabilitiesChanged) { - try { - nai.networkMonitor().notifyNetworkCapabilitiesChanged(); - } catch (RemoteException e) { - e.rethrowFromSystemServer(); - } notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_CAP_CHANGED); } @@ -6392,7 +6394,8 @@ public class ConnectivityService extends IConnectivityManager.Stub if (networkAgent.networkMisc.acceptPartialConnectivity) { networkAgent.networkMonitor().setAcceptPartialConnectivity(); } - networkAgent.networkMonitor().notifyNetworkConnected(); + networkAgent.networkMonitor().notifyNetworkConnected( + networkAgent.linkProperties, networkAgent.networkCapabilities); } catch (RemoteException e) { e.rethrowFromSystemServer(); } diff --git a/services/core/java/com/android/server/ExplicitHealthCheckController.java b/services/core/java/com/android/server/ExplicitHealthCheckController.java index f50364d70bc7..164837ab98dd 100644 --- a/services/core/java/com/android/server/ExplicitHealthCheckController.java +++ b/services/core/java/com/android/server/ExplicitHealthCheckController.java @@ -39,7 +39,9 @@ import android.text.TextUtils; import android.util.Slog; import com.android.internal.annotations.GuardedBy; +import com.android.internal.util.Preconditions; +import java.util.Collections; import java.util.List; import java.util.function.Consumer; @@ -50,10 +52,22 @@ class ExplicitHealthCheckController { private static final String TAG = "ExplicitHealthCheckController"; private final Object mLock = new Object(); private final Context mContext; - @GuardedBy("mLock") @Nullable private StateCallback mStateCallback; + + // Called everytime the service is connected, so the watchdog can sync it's state with + // the health check service. In practice, should never be null after it has been #setEnabled. + @GuardedBy("mLock") @Nullable private Runnable mOnConnected; + // Called everytime a package passes the health check, so the watchdog is notified of the + // passing check. In practice, should never be null after it has been #setEnabled. + @GuardedBy("mLock") @Nullable private Consumer<String> mPassedConsumer; + // Actual binder object to the explicit health check service. @GuardedBy("mLock") @Nullable private IExplicitHealthCheckService mRemoteService; - @GuardedBy("mLock") @Nullable private ServiceConnection mConnection; + // Cache for packages supporting explicit health checks. This cache should not change while + // the health check service is running. @GuardedBy("mLock") @Nullable private List<String> mSupportedPackages; + // Connection to the explicit health check service, necessary to unbind + @GuardedBy("mLock") @Nullable private ServiceConnection mConnection; + // Bind state of the explicit health check service. + @GuardedBy("mLock") private boolean mEnabled; ExplicitHealthCheckController(Context context) { mContext = context; @@ -61,28 +75,40 @@ class ExplicitHealthCheckController { /** * Requests an explicit health check for {@code packageName}. - * After this request, the callback registered on {@link startService} can receive explicit + * After this request, the callback registered on {@link #setCallbacks} can receive explicit * health check passed results. * * @throws IllegalStateException if the service is not started */ public void request(String packageName) throws RemoteException { synchronized (mLock) { + if (!mEnabled) { + return; + } + enforceServiceReadyLocked(); + + Slog.i(TAG, "Requesting health check for package " + packageName); mRemoteService.request(packageName); } } /** * Cancels all explicit health checks for {@code packageName}. - * After this request, the callback registered on {@link startService} can no longer receive + * After this request, the callback registered on {@link #setCallbacks} can no longer receive * explicit health check passed results. * * @throws IllegalStateException if the service is not started */ public void cancel(String packageName) throws RemoteException { synchronized (mLock) { + if (!mEnabled) { + return; + } + enforceServiceReadyLocked(); + + Slog.i(TAG, "Cancelling health check for package " + packageName); mRemoteService.cancel(packageName); } } @@ -95,13 +121,21 @@ class ExplicitHealthCheckController { */ public void getSupportedPackages(Consumer<List<String>> consumer) throws RemoteException { synchronized (mLock) { + if (!mEnabled) { + consumer.accept(Collections.emptyList()); + return; + } + enforceServiceReadyLocked(); + if (mSupportedPackages == null) { + Slog.d(TAG, "Getting health check supported packages"); mRemoteService.getSupportedPackages(new RemoteCallback(result -> { mSupportedPackages = result.getStringArrayList(EXTRA_SUPPORTED_PACKAGES); consumer.accept(mSupportedPackages); })); } else { + Slog.d(TAG, "Getting cached health check supported packages"); consumer.accept(mSupportedPackages); } } @@ -115,95 +149,113 @@ class ExplicitHealthCheckController { */ public void getRequestedPackages(Consumer<List<String>> consumer) throws RemoteException { synchronized (mLock) { + if (!mEnabled) { + consumer.accept(Collections.emptyList()); + return; + } + enforceServiceReadyLocked(); + + Slog.d(TAG, "Getting health check requested packages"); mRemoteService.getRequestedPackages(new RemoteCallback( result -> consumer.accept( result.getStringArrayList(EXTRA_REQUESTED_PACKAGES)))); } } + /** Enables or disables explicit health checks. */ + public void setEnabled(boolean enabled) { + synchronized (mLock) { + if (enabled == mEnabled) { + return; + } + + Slog.i(TAG, "Setting explicit health checks enabled " + enabled); + mEnabled = enabled; + if (enabled) { + bindService(); + } else { + unbindService(); + } + } + } + /** - * Starts the explicit health check service. - * - * @param stateCallback will receive important state changes changes - * @param passedConsumer will accept packages that pass explicit health checks - * - * @throws IllegalStateException if the service is already started + * Sets callbacks to listen to important events from the controller. + * Should be called at initialization. */ - public void startService(StateCallback stateCallback, Consumer<String> passedConsumer) { + public void setCallbacks(Runnable onConnected, Consumer<String> passedConsumer) { + Preconditions.checkNotNull(onConnected); + Preconditions.checkNotNull(passedConsumer); + mOnConnected = onConnected; + mPassedConsumer = passedConsumer; + } + + /** Binds to the explicit health check service. */ + private void bindService() { synchronized (mLock) { if (mRemoteService != null) { - throw new IllegalStateException("Explicit health check service already started."); + return; + } + ComponentName component = getServiceComponentNameLocked(); + if (component == null) { + Slog.wtf(TAG, "Explicit health check service not found"); + return; } - mStateCallback = stateCallback; + + Intent intent = new Intent(); + intent.setComponent(component); + // TODO: Fix potential race conditions during mConnection state transitions. + // E.g after #onServiceDisconected, the mRemoteService object is invalid until + // we get an #onServiceConnected. mConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { - synchronized (mLock) { - mRemoteService = IExplicitHealthCheckService.Stub.asInterface(service); - try { - mRemoteService.setCallback(new RemoteCallback(result -> { - String packageName = - result.getString(EXTRA_HEALTH_CHECK_PASSED_PACKAGE); - if (!TextUtils.isEmpty(packageName)) { - passedConsumer.accept(packageName); - } else { - Slog.w(TAG, "Empty package passed explicit health check?"); - } - })); - mStateCallback.onStart(); - Slog.i(TAG, "Explicit health check service is connected " + name); - } catch (RemoteException e) { - Slog.wtf(TAG, "Coud not setCallback on explicit health check service"); - } - } + initState(service); + Slog.i(TAG, "Explicit health check service is connected " + name); } @Override @MainThread public void onServiceDisconnected(ComponentName name) { - resetState(); + // Service crashed or process was killed, #onServiceConnected will be called. + // Don't need to re-bind. Slog.i(TAG, "Explicit health check service is disconnected " + name); } @Override public void onBindingDied(ComponentName name) { - resetState(); + // Application hosting service probably got updated + // Need to re-bind. + synchronized (mLock) { + if (mEnabled) { + unbindService(); + bindService(); + } + } Slog.i(TAG, "Explicit health check service binding is dead " + name); } @Override public void onNullBinding(ComponentName name) { - resetState(); - Slog.i(TAG, "Explicit health check service binding is null " + name); + // Should never happen. Service returned null from #onBind. + Slog.wtf(TAG, "Explicit health check service binding is null?? " + name); } }; - ComponentName component = getServiceComponentNameLocked(); - if (component != null) { - Intent intent = new Intent(); - intent.setComponent(component); - mContext.bindServiceAsUser(intent, mConnection, Context.BIND_AUTO_CREATE, - UserHandle.of(UserHandle.USER_SYSTEM)); - } + Slog.i(TAG, "Binding to explicit health service"); + mContext.bindServiceAsUser(intent, mConnection, Context.BIND_AUTO_CREATE, + UserHandle.of(UserHandle.USER_SYSTEM)); } } - // TODO: Differentiate between expected vs unexpected stop? - /** Callback to receive important {@link ExplicitHealthCheckController} state changes. */ - abstract static class StateCallback { - /** The controller is ready and we can request explicit health checks for packages */ - public void onStart() {} - - /** The controller is not ready and we cannot request explicit health checks for packages */ - public void onStop() {} - } - - /** Stops the explicit health check service. */ - public void stopService() { + /** Unbinds the explicit health check service. */ + private void unbindService() { synchronized (mLock) { if (mRemoteService != null) { + Slog.i(TAG, "Unbinding from explicit health service"); mContext.unbindService(mConnection); + mRemoteService = null; } } } @@ -247,19 +299,41 @@ class ExplicitHealthCheckController { return name; } - private void resetState() { + private void initState(IBinder service) { synchronized (mLock) { - mStateCallback.onStop(); - mStateCallback = null; mSupportedPackages = null; - mRemoteService = null; - mConnection = null; + mRemoteService = IExplicitHealthCheckService.Stub.asInterface(service); + try { + mRemoteService.setCallback(new RemoteCallback(result -> { + String packageName = result.getString(EXTRA_HEALTH_CHECK_PASSED_PACKAGE); + if (!TextUtils.isEmpty(packageName)) { + synchronized (mLock) { + if (mPassedConsumer == null) { + Slog.w(TAG, "Health check passed for package " + packageName + + "but no consumer registered."); + } else { + mPassedConsumer.accept(packageName); + } + } + } else { + Slog.w(TAG, "Empty package passed explicit health check?"); + } + })); + if (mOnConnected == null) { + Slog.w(TAG, "Health check service connected but no runnable registered."); + } else { + mOnConnected.run(); + } + } catch (RemoteException e) { + Slog.wtf(TAG, "Could not setCallback on explicit health check service"); + } } } @GuardedBy("mLock") private void enforceServiceReadyLocked() { if (mRemoteService == null) { + // TODO: Try to bind to service throw new IllegalStateException("Explicit health check service not ready"); } } diff --git a/services/core/java/com/android/server/LocationManagerService.java b/services/core/java/com/android/server/LocationManagerService.java index 2ded1e58bf2d..3410d8d86852 100644 --- a/services/core/java/com/android/server/LocationManagerService.java +++ b/services/core/java/com/android/server/LocationManagerService.java @@ -52,6 +52,7 @@ import android.location.Address; import android.location.Criteria; import android.location.GeocoderParams; import android.location.Geofence; +import android.location.GnssCapabilities; import android.location.GnssMeasurementCorrections; import android.location.IBatchedLocationCallback; import android.location.IGnssMeasurementsListener; @@ -102,6 +103,7 @@ import com.android.server.location.GeocoderProxy; import com.android.server.location.GeofenceManager; import com.android.server.location.GeofenceProxy; import com.android.server.location.GnssBatchingProvider; +import com.android.server.location.GnssCapabilitiesProvider; import com.android.server.location.GnssLocationProvider; import com.android.server.location.GnssMeasurementCorrectionsProvider; import com.android.server.location.GnssMeasurementsProvider; @@ -249,8 +251,8 @@ public class LocationManagerService extends ILocationManager.Stub { private int[] mCurrentUserProfiles = new int[]{UserHandle.USER_SYSTEM}; private GnssLocationProvider.GnssSystemInfoProvider mGnssSystemInfoProvider; - private GnssLocationProvider.GnssMetricsProvider mGnssMetricsProvider; + private GnssCapabilitiesProvider mGnssCapabilitiesProvider; private GnssBatchingProvider mGnssBatchingProvider; @GuardedBy("mLock") @@ -323,16 +325,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 +404,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() { @@ -761,6 +775,7 @@ public class LocationManagerService extends ILocationManager.Stub { mGnssSystemInfoProvider = gnssProvider.getGnssSystemInfoProvider(); mGnssBatchingProvider = gnssProvider.getGnssBatchingProvider(); mGnssMetricsProvider = gnssProvider.getGnssMetricsProvider(); + mGnssCapabilitiesProvider = gnssProvider.getGnssCapabilitiesProvider(); mGnssStatusProvider = gnssProvider.getGnssStatusProvider(); mNetInitiatedListener = gnssProvider.getNetInitiatedListener(); mGnssMeasurementsProvider = gnssProvider.getGnssMeasurementsProvider(); @@ -2958,10 +2973,10 @@ public class LocationManagerService extends ILocationManager.Stub { mContext.enforceCallingPermission( android.Manifest.permission.LOCATION_HARDWARE, "Location Hardware permission not granted to obtain GNSS chipset capabilities."); - if (!hasGnssPermissions(packageName) || mGnssMeasurementCorrectionsProvider == null) { - return -1; + if (!hasGnssPermissions(packageName) || mGnssCapabilitiesProvider == null) { + return GnssCapabilities.INVALID_CAPABILITIES; } - return mGnssMeasurementCorrectionsProvider.getCapabilities(); + return mGnssCapabilitiesProvider.getGnssCapabilities(); } @Override diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java index 61a718231dd4..d1ae284512d2 100644 --- a/services/core/java/com/android/server/NetworkManagementService.java +++ b/services/core/java/com/android/server/NetworkManagementService.java @@ -1610,20 +1610,6 @@ public class NetworkManagementService extends INetworkManagementService.Stub { } @Override - public void setDnsConfigurationForNetwork(int netId, String[] servers, String[] domains, - int[] params, String tlsHostname, String[] tlsServers) { - mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); - - final String[] tlsFingerprints = new String[0]; - try { - mNetdService.setResolverConfiguration( - netId, servers, domains, params, tlsHostname, tlsServers, tlsFingerprints); - } catch (RemoteException e) { - throw new RuntimeException(e); - } - } - - @Override public void addVpnUidRanges(int netId, UidRange[] ranges) { mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); @@ -2082,21 +2068,6 @@ public class NetworkManagementService extends INetworkManagementService.Stub { } @Override - public void removeNetwork(int netId) { - mContext.enforceCallingOrSelfPermission(NETWORK_STACK, TAG); - - try { - mNetdService.networkDestroy(netId); - } catch (ServiceSpecificException e) { - Log.w(TAG, "removeNetwork(" + netId + "): ", e); - throw e; - } catch (RemoteException e) { - Log.w(TAG, "removeNetwork(" + netId + "): ", e); - throw e.rethrowAsRuntimeException(); - } - } - - @Override public void addInterfaceToNetwork(String iface, int netId) { modifyInterfaceInNetwork(MODIFY_OPERATION_ADD, netId, iface); } diff --git a/services/core/java/com/android/server/PackageWatchdog.java b/services/core/java/com/android/server/PackageWatchdog.java index 660109cf6114..2ba4d975a6b0 100644 --- a/services/core/java/com/android/server/PackageWatchdog.java +++ b/services/core/java/com/android/server/PackageWatchdog.java @@ -26,11 +26,12 @@ import android.content.pm.VersionedPackage; import android.os.Environment; import android.os.Handler; import android.os.Looper; +import android.os.RemoteException; import android.os.SystemClock; import android.text.TextUtils; import android.util.ArrayMap; +import android.util.ArraySet; import android.util.AtomicFile; -import android.util.Log; import android.util.Slog; import android.util.Xml; @@ -54,10 +55,12 @@ import java.io.InputStream; import java.lang.annotation.Retention; import java.nio.charset.StandardCharsets; import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Set; +import java.util.function.Consumer; /** * Monitors the health of packages on the system and notifies interested observers when packages @@ -84,10 +87,10 @@ public class PackageWatchdog { private final Object mLock = new Object(); // System server context private final Context mContext; - // Handler to run package cleanup runnables - private final Handler mTimerHandler; - // Handler for processing IO and observer actions - private final Handler mWorkerHandler; + // Handler to run short running tasks + private final Handler mShortTaskHandler; + // Handler for processing IO and long running tasks + private final Handler mLongTaskHandler; // Contains (observer-name -> observer-handle) that have ever been registered from // previous boots. Observers with all packages expired are periodically pruned. // It is saved to disk on system shutdown and repouplated on startup so it survives reboots. @@ -97,6 +100,12 @@ public class PackageWatchdog { private final AtomicFile mPolicyFile; // Runnable to prune monitored packages that have expired private final Runnable mPackageCleanup; + private final ExplicitHealthCheckController mHealthCheckController; + // Flag to control whether explicit health checks are supported or not + @GuardedBy("mLock") + private boolean mIsHealthCheckEnabled = true; + @GuardedBy("mLock") + private boolean mIsPackagesReady; // Last SystemClock#uptimeMillis a package clean up was executed. // 0 if mPackageCleanup not running. private long mUptimeAtLastRescheduleMs; @@ -104,32 +113,30 @@ public class PackageWatchdog { // 0 if mPackageCleanup not running. private long mDurationAtLastReschedule; - // TODO(b/120598832): Remove redundant context param private PackageWatchdog(Context context) { - mContext = context; - mPolicyFile = new AtomicFile(new File(new File(Environment.getDataDirectory(), "system"), - "package-watchdog.xml")); - mTimerHandler = new Handler(Looper.myLooper()); - mWorkerHandler = BackgroundThread.getHandler(); - mPackageCleanup = this::rescheduleCleanup; - loadFromFile(); + // Needs to be constructed inline + this(context, new AtomicFile( + new File(new File(Environment.getDataDirectory(), "system"), + "package-watchdog.xml")), + new Handler(Looper.myLooper()), BackgroundThread.getHandler(), + new ExplicitHealthCheckController(context)); } /** - * Creates a PackageWatchdog for testing that uses the same {@code looper} for all handlers - * and creates package-watchdog.xml in an apps data directory. + * Creates a PackageWatchdog that allows injecting dependencies. */ @VisibleForTesting - PackageWatchdog(Context context, Looper looper) { + PackageWatchdog(Context context, AtomicFile policyFile, Handler shortTaskHandler, + Handler longTaskHandler, ExplicitHealthCheckController controller) { mContext = context; - mPolicyFile = new AtomicFile(new File(context.getFilesDir(), "package-watchdog.xml")); - mTimerHandler = new Handler(looper); - mWorkerHandler = mTimerHandler; + mPolicyFile = policyFile; + mShortTaskHandler = shortTaskHandler; + mLongTaskHandler = longTaskHandler; mPackageCleanup = this::rescheduleCleanup; + mHealthCheckController = controller; loadFromFile(); } - /** Creates or gets singleton instance of PackageWatchdog. */ public static PackageWatchdog getInstance(Context context) { synchronized (PackageWatchdog.class) { @@ -141,6 +148,20 @@ public class PackageWatchdog { } /** + * Called during boot to notify when packages are ready on the device so we can start + * binding. + */ + public void onPackagesReady() { + synchronized (mLock) { + mIsPackagesReady = true; + mHealthCheckController.setCallbacks(this::updateHealthChecks, + packageName -> onHealthCheckPassed(packageName)); + // Controller is disabled at creation until here where we may enable it + mHealthCheckController.setEnabled(mIsHealthCheckEnabled); + } + } + + /** * Registers {@code observer} to listen for package failures * * <p>Observers are expected to call this on boot. It does not specify any packages but @@ -163,40 +184,63 @@ public class PackageWatchdog { * Starts observing the health of the {@code packages} for {@code observer} and notifies * {@code observer} of any package failures within the monitoring duration. * - * <p>If monitoring a package with {@code withExplicitHealthCheck}, at the end of the monitoring - * duration if {@link #onExplicitHealthCheckPassed} was never called, + * <p>If monitoring a package supporting explicit health check, at the end of the monitoring + * duration if {@link #onHealthCheckPassed} was never called, * {@link PackageHealthObserver#execute} will be called as if the package failed. * * <p>If {@code observer} is already monitoring a package in {@code packageNames}, * the monitoring window of that package will be reset to {@code durationMs} and the health - * check state will be reset to a default depending on {@code withExplictHealthCheck}. + * check state will be reset to a default depending on if the package is contained in + * {@link mPackagesWithExplicitHealthCheckEnabled}. * * @throws IllegalArgumentException if {@code packageNames} is empty * or {@code durationMs} is less than 1 */ - public void startObservingHealth(PackageHealthObserver observer, List<String> packageNames, - long durationMs, boolean withExplicitHealthCheck) { - if (packageNames.isEmpty() || durationMs < 1) { + public void startObservingHealth(PackageHealthObserver observer, List<String> packages, + long durationMs) { + if (packages.isEmpty() || durationMs < 1) { throw new IllegalArgumentException("Observation not started, no packages specified" + "or invalid duration"); } + if (!mIsPackagesReady) { + // TODO: Queue observation requests when packages are not ready + Slog.w(TAG, "Attempt to observe when packages not ready"); + return; + } + + try { + Slog.i(TAG, "Getting packages supporting explicit health check"); + mHealthCheckController.getSupportedPackages(supportedPackages -> + startObservingInner(observer, packages, durationMs, supportedPackages)); + } catch (RemoteException e) { + Slog.wtf(TAG, "Failed to fetch supported explicit health check packages"); + } + } + + private void startObservingInner(PackageHealthObserver observer, + List<String> packageNames, long durationMs, + List<String> healthCheckSupportedPackages) { + Slog.i(TAG, "Start observing packages " + packageNames + + ". Explicit health check supported packages " + healthCheckSupportedPackages); List<MonitoredPackage> packages = new ArrayList<>(); for (int i = 0; i < packageNames.size(); i++) { - // When observing packages withExplicitHealthCheck, - // MonitoredPackage#mHasExplicitHealthCheckPassed will be false initially. - packages.add(new MonitoredPackage(packageNames.get(i), durationMs, - !withExplicitHealthCheck)); + String packageName = packageNames.get(i); + boolean shouldEnableHealthCheck = healthCheckSupportedPackages.contains(packageName); + // If we should enable explicit health check for a package, + // MonitoredPackage#mHasHealthCheckPassed will be false + // until PackageWatchdog#onHealthCheckPassed + packages.add(new MonitoredPackage(packageName, durationMs, !shouldEnableHealthCheck)); } synchronized (mLock) { ObserverInternal oldObserver = mAllObservers.get(observer.getName()); if (oldObserver == null) { - Slog.d(TAG, observer.getName() + " started monitoring health of packages " - + packageNames); + Slog.d(TAG, observer.getName() + " started monitoring health " + + "of packages " + packageNames); mAllObservers.put(observer.getName(), new ObserverInternal(observer.getName(), packages)); } else { - Slog.d(TAG, observer.getName() + " added the following packages to monitor " - + packageNames); + Slog.d(TAG, observer.getName() + " added the following " + + "packages to monitor " + packageNames); oldObserver.updatePackages(packages); } } @@ -204,9 +248,97 @@ public class PackageWatchdog { // Always reschedule because we may need to expire packages // earlier than we are already scheduled for rescheduleCleanup(); + updateHealthChecks(); saveToFileAsync(); } + private void requestCheck(String packageName) { + try { + Slog.d(TAG, "Requesting explicit health check for " + packageName); + mHealthCheckController.request(packageName); + } catch (RemoteException e) { + Slog.wtf(TAG, "Failed to request explicit health check for " + packageName, e); + } + } + + private void cancelCheck(String packageName) { + try { + Slog.d(TAG, "Cancelling explicit health check for " + packageName); + mHealthCheckController.cancel(packageName); + } catch (RemoteException e) { + Slog.wtf(TAG, "Failed to cancel explicit health check for " + packageName, e); + } + } + + private void actOnDifference(Collection<String> collection1, Collection<String> collection2, + Consumer<String> action) { + Iterator<String> iterator = collection1.iterator(); + while (iterator.hasNext()) { + String packageName = iterator.next(); + if (!collection2.contains(packageName)) { + action.accept(packageName); + } + } + } + + private void updateChecksInner(List<String> supportedPackages, + List<String> previousRequestedPackages) { + boolean shouldUpdateFile = false; + + synchronized (mLock) { + Slog.i(TAG, "Updating explicit health checks. Supported packages: " + supportedPackages + + ". Requested packages: " + previousRequestedPackages); + Set<String> newRequestedPackages = new ArraySet<>(); + Iterator<ObserverInternal> oit = mAllObservers.values().iterator(); + while (oit.hasNext()) { + ObserverInternal observer = oit.next(); + Iterator<MonitoredPackage> pit = + observer.mPackages.values().iterator(); + while (pit.hasNext()) { + MonitoredPackage monitoredPackage = pit.next(); + String packageName = monitoredPackage.mName; + if (!monitoredPackage.mHasPassedHealthCheck) { + if (supportedPackages.contains(packageName)) { + newRequestedPackages.add(packageName); + } else { + shouldUpdateFile = true; + monitoredPackage.mHasPassedHealthCheck = true; + } + } + } + } + // TODO: Support ending the binding if newRequestedPackages is empty. + // Will have to re-bind when we #startObservingHealth. + + // Cancel packages no longer requested + actOnDifference(previousRequestedPackages, newRequestedPackages, p -> cancelCheck(p)); + // Request packages not yet requested + actOnDifference(newRequestedPackages, previousRequestedPackages, p -> requestCheck(p)); + } + + if (shouldUpdateFile) { + saveToFileAsync(); + } + } + + private void updateHealthChecks() { + mShortTaskHandler.post(() -> { + try { + Slog.i(TAG, "Updating explicit health checks for all available packages"); + mHealthCheckController.getSupportedPackages(supported -> { + try { + mHealthCheckController.getRequestedPackages( + requested -> updateChecksInner(supported, requested)); + } catch (RemoteException e) { + Slog.e(TAG, "Failed to get requested health check packages", e); + } + }); + } catch (RemoteException e) { + Slog.e(TAG, "Failed to get supported health check package", e); + } + }); + } + /** * Unregisters {@code observer} from listening to package failure. * Additionally, this stops observing any packages that may have previously been observed @@ -250,7 +382,7 @@ public class PackageWatchdog { * <p>This method could be called frequently if there is a severe problem on the device. */ public void onPackageFailure(List<VersionedPackage> packages) { - mWorkerHandler.post(() -> { + mLongTaskHandler.post(() -> { synchronized (mLock) { if (mAllObservers.isEmpty()) { return; @@ -286,49 +418,32 @@ public class PackageWatchdog { }); } - /** - * Updates the observers monitoring {@code packageName} that explicit health check has passed. - * - * <p> This update is strictly for registered observers at the time of the call - * Observers that register after this signal will have no knowledge of prior signals and will - * effectively behave as if the explicit health check hasn't passed for {@code packageName}. - * - * <p> {@code packageName} can still be considered failed if reported by - * {@link #onPackageFailure} before the package expires. - * - * <p> Triggered by components outside the system server when they are fully functional after an - * update. - */ - public void onExplicitHealthCheckPassed(String packageName) { - Slog.i(TAG, "Health check passed for package: " + packageName); - boolean shouldUpdateFile = false; - synchronized (mLock) { - for (int observerIdx = 0; observerIdx < mAllObservers.size(); observerIdx++) { - ObserverInternal observer = mAllObservers.valueAt(observerIdx); - MonitoredPackage monitoredPackage = observer.mPackages.get(packageName); - if (monitoredPackage != null && !monitoredPackage.mHasPassedHealthCheck) { - monitoredPackage.mHasPassedHealthCheck = true; - shouldUpdateFile = true; - } - } - } - if (shouldUpdateFile) { - saveToFileAsync(); - } - } - // TODO(b/120598832): Optimize write? Maybe only write a separate smaller file? // This currently adds about 7ms extra to shutdown thread /** Writes the package information to file during shutdown. */ public void writeNow() { if (!mAllObservers.isEmpty()) { - mWorkerHandler.removeCallbacks(this::saveToFile); + mLongTaskHandler.removeCallbacks(this::saveToFile); pruneObservers(SystemClock.uptimeMillis() - mUptimeAtLastRescheduleMs); saveToFile(); Slog.i(TAG, "Last write to update package durations"); } } + // TODO(b/120598832): Set depending on DeviceConfig flag + /** + * Enables or disables explicit health checks. + * <p> If explicit health checks are enabled, the health check service is started. + * <p> If explicit health checks are disabled, pending explicit health check requests are + * passed and the health check service is stopped. + */ + public void setExplicitHealthCheckEnabled(boolean enabled) { + synchronized (mLock) { + mIsHealthCheckEnabled = enabled; + mHealthCheckController.setEnabled(enabled); + } + } + /** Possible severity values of the user impact of a {@link PackageHealthObserver#execute}. */ @Retention(SOURCE) @IntDef(value = {PackageHealthObserverImpact.USER_IMPACT_NONE, @@ -371,6 +486,37 @@ public class PackageWatchdog { String getName(); } + /** + * Updates the observers monitoring {@code packageName} that explicit health check has passed. + * + * <p> This update is strictly for registered observers at the time of the call + * Observers that register after this signal will have no knowledge of prior signals and will + * effectively behave as if the explicit health check hasn't passed for {@code packageName}. + * + * <p> {@code packageName} can still be considered failed if reported by + * {@link #onPackageFailure} before the package expires. + * + * <p> Triggered by components outside the system server when they are fully functional after an + * update. + */ + private void onHealthCheckPassed(String packageName) { + Slog.i(TAG, "Health check passed for package: " + packageName); + boolean shouldUpdateFile = false; + synchronized (mLock) { + for (int observerIdx = 0; observerIdx < mAllObservers.size(); observerIdx++) { + ObserverInternal observer = mAllObservers.valueAt(observerIdx); + MonitoredPackage monitoredPackage = observer.mPackages.get(packageName); + if (monitoredPackage != null && !monitoredPackage.mHasPassedHealthCheck) { + monitoredPackage.mHasPassedHealthCheck = true; + shouldUpdateFile = true; + } + } + } + if (shouldUpdateFile) { + saveToFileAsync(); + } + } + /** Reschedules handler to prune expired packages from observers. */ private void rescheduleCleanup() { synchronized (mLock) { @@ -393,8 +539,8 @@ public class PackageWatchdog { || nextDurationToScheduleMs < remainingDurationMs) { // First schedule or an earlier reschedule pruneObservers(elapsedDurationMs); - mTimerHandler.removeCallbacks(mPackageCleanup); - mTimerHandler.postDelayed(mPackageCleanup, nextDurationToScheduleMs); + mShortTaskHandler.removeCallbacks(mPackageCleanup); + mShortTaskHandler.postDelayed(mPackageCleanup, nextDurationToScheduleMs); mDurationAtLastReschedule = nextDurationToScheduleMs; mUptimeAtLastRescheduleMs = uptimeMs; } @@ -437,7 +583,7 @@ public class PackageWatchdog { List<MonitoredPackage> failedPackages = observer.updateMonitoringDurations(elapsedMs); if (!failedPackages.isEmpty()) { - onExplicitHealthCheckFailed(observer, failedPackages); + onHealthCheckFailed(observer, failedPackages); } if (observer.mPackages.isEmpty()) { Slog.i(TAG, "Discarding observer " + observer.mName + ". All packages expired"); @@ -445,12 +591,13 @@ public class PackageWatchdog { } } } + updateHealthChecks(); saveToFileAsync(); } - private void onExplicitHealthCheckFailed(ObserverInternal observer, + private void onHealthCheckFailed(ObserverInternal observer, List<MonitoredPackage> failedPackages) { - mWorkerHandler.post(() -> { + mLongTaskHandler.post(() -> { synchronized (mLock) { PackageHealthObserver registeredObserver = observer.mRegisteredObserver; if (registeredObserver != null) { @@ -458,6 +605,7 @@ public class PackageWatchdog { for (int i = 0; i < failedPackages.size(); i++) { String packageName = failedPackages.get(i).mName; long versionCode = 0; + Slog.i(TAG, "Explicit health check failed for package " + packageName); try { versionCode = pm.getPackageInfo( packageName, 0 /* flags */).getLongVersionCode(); @@ -498,7 +646,7 @@ public class PackageWatchdog { } catch (FileNotFoundException e) { // Nothing to monitor } catch (IOException | NumberFormatException | XmlPullParserException e) { - Log.wtf(TAG, "Unable to read monitored packages, deleting file", e); + Slog.wtf(TAG, "Unable to read monitored packages, deleting file", e); mPolicyFile.delete(); } finally { IoUtils.closeQuietly(infile); @@ -542,8 +690,8 @@ public class PackageWatchdog { } private void saveToFileAsync() { - mWorkerHandler.removeCallbacks(this::saveToFile); - mWorkerHandler.post(this::saveToFile); + mLongTaskHandler.removeCallbacks(this::saveToFile); + mLongTaskHandler.post(this::saveToFile); } /** diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java index 1a842f72fcb4..4598d3ef7f4b 100644 --- a/services/core/java/com/android/server/StorageManagerService.java +++ b/services/core/java/com/android/server/StorageManagerService.java @@ -25,8 +25,6 @@ import static android.app.AppOpsManager.OP_LEGACY_STORAGE; import static android.app.AppOpsManager.OP_READ_EXTERNAL_STORAGE; import static android.app.AppOpsManager.OP_REQUEST_INSTALL_PACKAGES; import static android.app.AppOpsManager.OP_WRITE_EXTERNAL_STORAGE; -import static android.content.pm.PackageManager.FLAG_PERMISSION_HIDDEN; -import static android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; import static android.content.pm.PackageManager.GET_PERMISSIONS; import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE; import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE; @@ -81,7 +79,6 @@ import android.content.res.ObbInfo; import android.database.ContentObserver; import android.net.Uri; import android.os.Binder; -import android.os.Build; import android.os.DropBoxManager; import android.os.Environment; import android.os.Environment.UserEnvironment; @@ -213,9 +210,6 @@ class StorageManagerService extends IStorageManager.Stub private static final boolean ENABLE_ISOLATED_STORAGE = StorageManager.hasIsolatedStorage(); - private static final boolean ENABLE_LEGACY_GREYLIST = SystemProperties - .getBoolean(StorageManager.PROP_LEGACY_GREYLIST, true); - /** * If {@code 1}, enables the isolated storage feature. If {@code -1}, * disables the isolated storage feature. If {@code 0}, uses the default @@ -310,17 +304,9 @@ class StorageManagerService extends IStorageManager.Stub private static final String ATTR_LAST_TRIM_MILLIS = "lastTrimMillis"; private static final String ATTR_LAST_BENCH_MILLIS = "lastBenchMillis"; - private static final String[] LEGACY_STORAGE_PERMISSIONS = { - Manifest.permission.READ_EXTERNAL_STORAGE, - Manifest.permission.WRITE_EXTERNAL_STORAGE - }; - private static final String[] ALL_STORAGE_PERMISSIONS = { Manifest.permission.READ_EXTERNAL_STORAGE, - Manifest.permission.WRITE_EXTERNAL_STORAGE, - Manifest.permission.READ_MEDIA_AUDIO, - Manifest.permission.READ_MEDIA_VIDEO, - Manifest.permission.READ_MEDIA_IMAGES + Manifest.permission.WRITE_EXTERNAL_STORAGE }; private final AtomicFile mSettingsFile; @@ -1735,7 +1721,7 @@ class StorageManagerService extends IStorageManager.Stub } final List<PackageInfo> pkgs = pm.getPackagesHoldingPermissions( - LEGACY_STORAGE_PERMISSIONS, + ALL_STORAGE_PERMISSIONS, MATCH_UNINSTALLED_PACKAGES | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE | GET_PERMISSIONS); for (PackageInfo pkg : pkgs) { @@ -1752,26 +1738,6 @@ class StorageManagerService extends IStorageManager.Stub if (lastAccess > 0) { appOps.setUidMode(AppOpsManager.OP_LEGACY_STORAGE, uid, AppOpsManager.MODE_ALLOWED); - - // Grandfather pre-Q app by granting all permissions and fixing them. The user - // needs to uninstall the app to revoke the permissions. - // TODO: Deal with shard Uids - if (pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.Q) { - for (String perm : ALL_STORAGE_PERMISSIONS) { - if (ArrayUtils.contains(pkg.requestedPermissions, perm)) { - pm.grantRuntimePermission(packageName, perm, user); - - int flags = FLAG_PERMISSION_SYSTEM_FIXED; - if (!ArrayUtils.contains(LEGACY_STORAGE_PERMISSIONS, perm)) { - flags |= FLAG_PERMISSION_HIDDEN; - } - - pm.updatePermissionFlags(perm, packageName, - FLAG_PERMISSION_SYSTEM_FIXED | FLAG_PERMISSION_HIDDEN, - flags, user); - } - } - } } } } @@ -2425,23 +2391,6 @@ class StorageManagerService extends IStorageManager.Stub Binder.restoreCallingIdentity(token); } } - - if ((mask & StorageManager.DEBUG_LEGACY_GREYLIST) != 0) { - final boolean enabled = (flags & StorageManager.DEBUG_LEGACY_GREYLIST) != 0; - - final long token = Binder.clearCallingIdentity(); - try { - SystemProperties.set(StorageManager.PROP_LEGACY_GREYLIST, - Boolean.toString(enabled)); - - // Perform hard reboot to kick policy into place - mHandler.post(() -> { - mContext.getSystemService(PowerManager.class).reboot(null); - }); - } finally { - Binder.restoreCallingIdentity(token); - } - } } @Override @@ -3915,8 +3864,11 @@ class StorageManagerService extends IStorageManager.Stub // they hold the runtime permission final boolean hasLegacy = mIAppOpsService.checkOperation(OP_LEGACY_STORAGE, uid, packageName) == MODE_ALLOWED; - final boolean hasGreylist = isLegacyGreylisted(packageName); - if ((hasLegacy || hasGreylist) && hasStorage) { + // STOPSHIP: only use app-op once permission model has fully landed + final boolean requestedLegacy = !mIPackageManager + .getApplicationInfo(packageName, 0, UserHandle.getUserId(uid)) + .isExternalStorageSandboxAllowed(); + if ((hasLegacy || requestedLegacy) && hasStorage) { return Zygote.MOUNT_EXTERNAL_LEGACY; } else { return Zygote.MOUNT_EXTERNAL_WRITE; @@ -3927,32 +3879,6 @@ class StorageManagerService extends IStorageManager.Stub return Zygote.MOUNT_EXTERNAL_NONE; } - private boolean isLegacyGreylisted(String packageName) { - // TODO: decide legacy defaults at install time based on signals - if (ENABLE_LEGACY_GREYLIST) { - // STOPSHIP: remove this temporary workaround once developers - // fix bugs where they're opening _data paths in native code - switch (packageName) { - case "com.facebook.katana": // b/123996076 - case "jp.naver.line.android": // b/124767356 - case "com.mxtech.videoplayer.ad": // b/124531483 - case "com.whatsapp": // b/124766614 - case "com.maxmpz.audioplayer": // b/127886230 - case "com.estrongs.android.pop": // b/127926473 - case "com.roidapp.photogrid": // b/128269119 - case "com.cleanmaster.mguard": // b/128384413 - case "com.skype.raider": // b/128487044 - case "org.telegram.messenger": // b/128652960 - case "com.jrtstudio.AnotherMusicPlayer": // b/129084562 - case "ak.alizandro.smartaudiobookplayer": // b/129084042 - case "com.campmobile.snow": // b/128803870 - case "com.qnap.qfile": // b/126374406 - return true; - } - } - return false; - } - private static class Callbacks extends Handler { private static final int MSG_STORAGE_STATE_CHANGED = 1; private static final int MSG_VOLUME_STATE_CHANGED = 2; diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java index 8b10267f32ff..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 | @@ -627,11 +627,6 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { r.callingPackage = callingPackage; r.callerUid = Binder.getCallingUid(); r.callerPid = Binder.getCallingPid(); - if (r.subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID && r.subId != subId) { - throw new IllegalArgumentException( - "PhoneStateListener cannot concurrently listen on multiple " + - "subscriptions. Previously registered on subId: " + r.subId); - } // Legacy applications pass SubscriptionManager.DEFAULT_SUB_ID, // force all illegal subId to SubscriptionManager.DEFAULT_SUB_ID if (!SubscriptionManager.isValidSubscriptionId(subId)) { @@ -827,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) { @@ -1769,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/Watchdog.java b/services/core/java/com/android/server/Watchdog.java index 1aeb6898fa13..afcf954371cc 100644 --- a/services/core/java/com/android/server/Watchdog.java +++ b/services/core/java/com/android/server/Watchdog.java @@ -40,6 +40,7 @@ import android.system.StructRlimit; import android.util.EventLog; import android.util.Log; import android.util.Slog; +import android.util.StatsLog; import com.android.internal.os.ZygoteConnectionConstants; import com.android.server.am.ActivityManagerService; @@ -539,6 +540,7 @@ public class Watchdog extends Thread { mActivity.addErrorToDropBox( "watchdog", null, "system_server", null, null, null, subject, null, stack, null); + StatsLog.write(StatsLog.SYSTEM_SERVER_WATCHDOG_OCCURRED, subject); } }; dropboxThread.start(); 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/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java index cef245ba332f..f0982d3aa142 100644 --- a/services/core/java/com/android/server/am/ActiveServices.java +++ b/services/core/java/com/android/server/am/ActiveServices.java @@ -1344,7 +1344,8 @@ public final class ActiveServices { if (!r.isForeground) { final ServiceMap smap = getServiceMapLocked(r.userId); if (smap != null) { - ActiveForegroundApp active = smap.mActiveForegroundApps.get(r.packageName); + ActiveForegroundApp active = smap.mActiveForegroundApps + .get(r.packageName); if (active == null) { active = new ActiveForegroundApp(); active.mPackageName = r.packageName; @@ -1524,8 +1525,9 @@ public final class ActiveServices { boolean anyClientActivities = false; for (int i=proc.services.size()-1; i>=0 && !anyClientActivities; i--) { ServiceRecord sr = proc.services.valueAt(i); - for (int conni=sr.connections.size()-1; conni>=0 && !anyClientActivities; conni--) { - ArrayList<ConnectionRecord> clist = sr.connections.valueAt(conni); + ArrayMap<IBinder, ArrayList<ConnectionRecord>> connections = sr.getConnections(); + for (int conni = connections.size() - 1; conni >= 0 && !anyClientActivities; conni--) { + ArrayList<ConnectionRecord> clist = connections.valueAt(conni); for (int cri=clist.size()-1; cri>=0; cri--) { ConnectionRecord cr = clist.get(cri); if (cr.binding.client == null || cr.binding.client == proc) { @@ -1752,10 +1754,10 @@ public final class ActiveServices { callerApp.uid, callerApp.processName, callingPackage); IBinder binder = connection.asBinder(); - ArrayList<ConnectionRecord> clist = s.connections.get(binder); + ArrayList<ConnectionRecord> clist = s.getConnections().get(binder); if (clist == null) { clist = new ArrayList<ConnectionRecord>(); - s.connections.put(binder, clist); + s.putConnection(binder, clist); } clist.add(c); b.connections.add(c); @@ -1855,8 +1857,9 @@ public final class ActiveServices { b.binder = service; b.requested = true; b.received = true; - for (int conni=r.connections.size()-1; conni>=0; conni--) { - ArrayList<ConnectionRecord> clist = r.connections.valueAt(conni); + ArrayMap<IBinder, ArrayList<ConnectionRecord>> connections = r.getConnections(); + for (int conni = connections.size() - 1; conni >= 0; conni--) { + ArrayList<ConnectionRecord> clist = connections.valueAt(conni); for (int i=0; i<clist.size(); i++) { ConnectionRecord c = clist.get(i); if (!filter.equals(c.binding.intent.intent)) { @@ -2722,6 +2725,10 @@ public final class ActiveServices { updateServiceClientActivitiesLocked(app, null, true); + if (newService && created) { + app.addBoundClientUidsOfNewService(r); + } + // If the service is in the started state, and there are no // pending arguments, then fake up one so its onStartCommand() will // be called. @@ -2881,8 +2888,9 @@ public final class ActiveServices { // Report to all of the connections that the service is no longer // available. - for (int conni=r.connections.size()-1; conni>=0; conni--) { - ArrayList<ConnectionRecord> c = r.connections.valueAt(conni); + ArrayMap<IBinder, ArrayList<ConnectionRecord>> connections = r.getConnections(); + for (int conni = connections.size() - 1; conni >= 0; conni--) { + ArrayList<ConnectionRecord> c = connections.valueAt(conni); for (int i=0; i<c.size(); i++) { ConnectionRecord cr = c.get(i); // There is still a connection to the service that is @@ -3013,6 +3021,7 @@ public final class ActiveServices { r.stats.stopLaunchedLocked(); } r.app.services.remove(r); + r.app.updateBoundClientUids(); if (r.whitelistManager) { updateWhitelistManagerLocked(r.app); } @@ -3065,11 +3074,11 @@ public final class ActiveServices { IBinder binder = c.conn.asBinder(); AppBindRecord b = c.binding; ServiceRecord s = b.service; - ArrayList<ConnectionRecord> clist = s.connections.get(binder); + ArrayList<ConnectionRecord> clist = s.getConnections().get(binder); if (clist != null) { clist.remove(c); if (clist.size() == 0) { - s.connections.remove(binder); + s.removeConnection(binder); } } b.connections.remove(c); @@ -3294,6 +3303,7 @@ public final class ActiveServices { if (finishing) { if (r.app != null && !r.app.isPersistent()) { r.app.services.remove(r); + r.app.updateBoundClientUids(); if (r.whitelistManager) { updateWhitelistManagerLocked(r.app); } @@ -3389,6 +3399,7 @@ public final class ActiveServices { Slog.i(TAG, " Force stopping service " + service); if (service.app != null && !service.app.isPersistent()) { service.app.services.remove(service); + service.app.updateBoundClientUids(); if (service.whitelistManager) { updateWhitelistManagerLocked(service.app); } @@ -3504,8 +3515,9 @@ public final class ActiveServices { Iterator<ServiceRecord> it = app.services.iterator(); while (it.hasNext()) { ServiceRecord r = it.next(); - for (int conni=r.connections.size()-1; conni>=0; conni--) { - ArrayList<ConnectionRecord> cl = r.connections.valueAt(conni); + ArrayMap<IBinder, ArrayList<ConnectionRecord>> connections = r.getConnections(); + for (int conni=connections.size()-1; conni>=0; conni--) { + ArrayList<ConnectionRecord> cl = connections.valueAt(conni); for (int i=0; i<cl.size(); i++) { ConnectionRecord c = cl.get(i); if (c.binding.client != app) { @@ -3542,6 +3554,7 @@ public final class ActiveServices { } if (sr.app != app && sr.app != null && !sr.app.isPersistent()) { sr.app.services.remove(sr); + sr.app.updateBoundClientUids(); } sr.setProcess(null); sr.isolatedProc = null; @@ -3605,6 +3618,7 @@ public final class ActiveServices { // so make sure the service is cleaned out of it. if (!app.isPersistent()) { app.services.removeAt(i); + app.updateBoundClientUids(); } // Sanity check: if the service listed for the app is not one @@ -3655,6 +3669,7 @@ public final class ActiveServices { if (!allowRestart) { app.services.clear(); + app.clearBoundClientUids(); // Make sure there are no more restarting services for this process. for (int i=mRestartingServices.size()-1; i>=0; i--) { @@ -3701,7 +3716,7 @@ public final class ActiveServices { info.foreground = r.isForeground; info.activeSince = r.createRealTime; info.started = r.startRequested; - info.clientCount = r.connections.size(); + info.clientCount = r.getConnections().size(); info.crashCount = r.crashCount; info.lastActivityTime = r.lastActivity; if (r.isForeground) { @@ -3717,8 +3732,9 @@ public final class ActiveServices { info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS; } - for (int conni=r.connections.size()-1; conni>=0; conni--) { - ArrayList<ConnectionRecord> connl = r.connections.valueAt(conni); + ArrayMap<IBinder, ArrayList<ConnectionRecord>> connections = r.getConnections(); + for (int conni = connections.size() - 1; conni >= 0; conni--) { + ArrayList<ConnectionRecord> connl = connections.valueAt(conni); for (int i=0; i<connl.size(); i++) { ConnectionRecord conn = connl.get(i); if (conn.clientLabel != 0) { @@ -3787,9 +3803,10 @@ public final class ActiveServices { public PendingIntent getRunningServiceControlPanelLocked(ComponentName name) { int userId = UserHandle.getUserId(Binder.getCallingUid()); ServiceRecord r = getServiceByNameLocked(name, userId); + ArrayMap<IBinder, ArrayList<ConnectionRecord>> connections = r.getConnections(); if (r != null) { - for (int conni=r.connections.size()-1; conni>=0; conni--) { - ArrayList<ConnectionRecord> conn = r.connections.valueAt(conni); + for (int conni = connections.size() - 1; conni >= 0; conni--) { + ArrayList<ConnectionRecord> conn = connections.valueAt(conni); for (int i=0; i<conn.size(); i++) { if (conn.get(i).clientIntent != null) { return conn.get(i).clientIntent; @@ -4080,11 +4097,12 @@ public final class ActiveServices { pw.print(" started="); pw.print(r.startRequested); pw.print(" connections="); - pw.println(r.connections.size()); - if (r.connections.size() > 0) { + ArrayMap<IBinder, ArrayList<ConnectionRecord>> connections = r.getConnections(); + pw.println(connections.size()); + if (connections.size() > 0) { pw.println(" Connections:"); - for (int conni=0; conni<r.connections.size(); conni++) { - ArrayList<ConnectionRecord> clist = r.connections.valueAt(conni); + for (int conni = 0; conni < connections.size(); conni++) { + ArrayList<ConnectionRecord> clist = connections.valueAt(conni); for (int i = 0; i < clist.size(); i++) { ConnectionRecord conn = clist.get(i); pw.print(" "); diff --git a/services/core/java/com/android/server/am/ActivityManagerConstants.java b/services/core/java/com/android/server/am/ActivityManagerConstants.java index 1751856066fb..d7decb4126fc 100644 --- a/services/core/java/com/android/server/am/ActivityManagerConstants.java +++ b/services/core/java/com/android/server/am/ActivityManagerConstants.java @@ -20,8 +20,10 @@ import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK import android.app.ActivityThread; import android.content.ContentResolver; +import android.content.Context; import android.database.ContentObserver; import android.net.Uri; +import android.os.Build; import android.os.Handler; import android.provider.DeviceConfig; import android.provider.DeviceConfig.OnPropertyChangedListener; @@ -38,6 +40,7 @@ import java.io.PrintWriter; * Settings constants that can modify the activity manager's behavior. */ final class ActivityManagerConstants extends ContentObserver { + private static final String TAG = "ActivityManagerConstants"; // Key names stored in the settings value. private static final String KEY_BACKGROUND_SETTLE_TIME = "background_settle_time"; @@ -113,6 +116,22 @@ final class ActivityManagerConstants extends ContentObserver { */ private static final String KEY_MAX_CACHED_PROCESSES = "max_cached_processes"; + /** + * Default value for mFlagBackgroundActivityStartsEnabled if not explicitly set in + * Settings.Global. This allows it to be set experimentally unless it has been + * enabled/disabled in developer options. Defaults to true. + */ + private static final String KEY_DEFAULT_BACKGROUND_ACTIVITY_STARTS_ENABLED = + "default_background_activity_starts_enabled"; + + /** + * The packages temporarily whitelisted to be able to start activities from background. + * The list of packages is {@code ":"} colon delimited. + */ + private static final String KEY_BACKGROUND_ACTIVITY_STARTS_PACKAGE_NAMES_WHITELIST = + "background_activity_starts_package_names_whitelist"; + + // Maximum number of cached processes we will allow. public int MAX_CACHED_PROCESSES = DEFAULT_MAX_CACHED_PROCESSES; @@ -239,7 +258,8 @@ final class ActivityManagerConstants extends ContentObserver { volatile boolean mFlagActivityStartsLoggingEnabled; // Indicates whether the background activity starts is enabled. - // Controlled by Settings.Global.BACKGROUND_ACTIVITY_STARTS_ENABLED + // Controlled by Settings.Global.BACKGROUND_ACTIVITY_STARTS_ENABLED. + // If not set explicitly the default is controlled by DeviceConfig. volatile boolean mFlagBackgroundActivityStartsEnabled; volatile ArraySet<String> mPackageNamesWhitelistedForBgActivityStarts = new ArraySet<>(); @@ -272,6 +292,16 @@ final class ActivityManagerConstants extends ContentObserver { // memory trimming. public int CUR_TRIM_CACHED_PROCESSES; + private static final long MIN_AUTOMATIC_HEAP_DUMP_PSS_THRESHOLD_BYTES = 100 * 1024; // 100 KB + + private final boolean mSystemServerAutomaticHeapDumpEnabled; + + /** Package to report to when the memory usage exceeds the limit. */ + private final String mSystemServerAutomaticHeapDumpPackageName; + + /** Byte limit for dump heap monitoring. */ + private long mSystemServerAutomaticHeapDumpPssThresholdBytes; + private static final Uri ACTIVITY_MANAGER_CONSTANTS_URI = Settings.Global.getUriFor( Settings.Global.ACTIVITY_MANAGER_CONSTANTS); @@ -282,23 +312,41 @@ final class ActivityManagerConstants extends ContentObserver { Settings.Global.getUriFor( Settings.Global.BACKGROUND_ACTIVITY_STARTS_ENABLED); - private static final Uri BACKGROUND_ACTIVITY_STARTS_PACKAGE_NAMES_WHITELIST_URI = - Settings.Global.getUriFor( - Settings.Global.BACKGROUND_ACTIVITY_STARTS_PACKAGE_NAMES_WHITELIST); + private static final Uri ENABLE_AUTOMATIC_SYSTEM_SERVER_HEAP_DUMPS_URI = + Settings.Global.getUriFor(Settings.Global.ENABLE_AUTOMATIC_SYSTEM_SERVER_HEAP_DUMPS); private final OnPropertyChangedListener mOnDeviceConfigChangedListener = new OnPropertyChangedListener() { @Override public void onPropertyChanged(String namespace, String name, String value) { - if (KEY_MAX_CACHED_PROCESSES.equals(name)) { - updateMaxCachedProcesses(); + if (name == null) { + return; + } + switch (name) { + case KEY_MAX_CACHED_PROCESSES: + updateMaxCachedProcesses(); + break; + case KEY_DEFAULT_BACKGROUND_ACTIVITY_STARTS_ENABLED: + case KEY_BACKGROUND_ACTIVITY_STARTS_PACKAGE_NAMES_WHITELIST: + updateBackgroundActivityStarts(); + break; + default: + break; } } }; - public ActivityManagerConstants(ActivityManagerService service, Handler handler) { + ActivityManagerConstants(Context context, ActivityManagerService service, Handler handler) { super(handler); mService = service; + mSystemServerAutomaticHeapDumpEnabled = Build.IS_DEBUGGABLE + && context.getResources().getBoolean( + com.android.internal.R.bool.config_debugEnableAutomaticSystemServerHeapDumps); + mSystemServerAutomaticHeapDumpPackageName = context.getPackageName(); + mSystemServerAutomaticHeapDumpPssThresholdBytes = Math.max( + MIN_AUTOMATIC_HEAP_DUMP_PSS_THRESHOLD_BYTES, + context.getResources().getInteger( + com.android.internal.R.integer.config_debugSystemServerPssThresholdBytes)); } public void start(ContentResolver resolver) { @@ -306,17 +354,20 @@ final class ActivityManagerConstants extends ContentObserver { mResolver.registerContentObserver(ACTIVITY_MANAGER_CONSTANTS_URI, false, this); mResolver.registerContentObserver(ACTIVITY_STARTS_LOGGING_ENABLED_URI, false, this); mResolver.registerContentObserver(BACKGROUND_ACTIVITY_STARTS_ENABLED_URI, false, this); - mResolver.registerContentObserver(BACKGROUND_ACTIVITY_STARTS_PACKAGE_NAMES_WHITELIST_URI, - false, this); + if (mSystemServerAutomaticHeapDumpEnabled) { + mResolver.registerContentObserver(ENABLE_AUTOMATIC_SYSTEM_SERVER_HEAP_DUMPS_URI, + false, this); + } updateConstants(); - updateActivityStartsLoggingEnabled(); - updateBackgroundActivityStartsEnabled(); - updateBackgroundActivityStartsPackageNamesWhitelist(); + if (mSystemServerAutomaticHeapDumpEnabled) { + updateEnableAutomaticSystemServerHeapDumps(); + } DeviceConfig.addOnPropertyChangedListener(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, ActivityThread.currentApplication().getMainExecutor(), mOnDeviceConfigChangedListener); updateMaxCachedProcesses(); - + updateActivityStartsLoggingEnabled(); + updateBackgroundActivityStarts(); } public void setOverrideMaxCachedProcesses(int value) { @@ -340,9 +391,9 @@ final class ActivityManagerConstants extends ContentObserver { } else if (ACTIVITY_STARTS_LOGGING_ENABLED_URI.equals(uri)) { updateActivityStartsLoggingEnabled(); } else if (BACKGROUND_ACTIVITY_STARTS_ENABLED_URI.equals(uri)) { - updateBackgroundActivityStartsEnabled(); - } else if (BACKGROUND_ACTIVITY_STARTS_PACKAGE_NAMES_WHITELIST_URI.equals(uri)) { - updateBackgroundActivityStartsPackageNamesWhitelist(); + updateBackgroundActivityStarts(); + } else if (ENABLE_AUTOMATIC_SYSTEM_SERVER_HEAP_DUMPS_URI.equals(uri)) { + updateEnableAutomaticSystemServerHeapDumps(); } } @@ -430,24 +481,58 @@ final class ActivityManagerConstants extends ContentObserver { Settings.Global.ACTIVITY_STARTS_LOGGING_ENABLED, 1) == 1; } - private void updateBackgroundActivityStartsEnabled() { - mFlagBackgroundActivityStartsEnabled = Settings.Global.getInt(mResolver, - Settings.Global.BACKGROUND_ACTIVITY_STARTS_ENABLED, 1) == 1; + private void updateBackgroundActivityStarts() { + String whitelistedPackageNames = null; + int settingsValue = Settings.Global.getInt(mResolver, + Settings.Global.BACKGROUND_ACTIVITY_STARTS_ENABLED, -1); + + // If the user has explicitly enabled or disabled, that affects all apps. + // Otherwise we take the default state and whitelist from DeviceConfig. + if (settingsValue >= 0) { + mFlagBackgroundActivityStartsEnabled = settingsValue != 0; + } else { + boolean enabledInDeviceConfig = DeviceConfig.getBoolean( + DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, + KEY_DEFAULT_BACKGROUND_ACTIVITY_STARTS_ENABLED, + /*defaultValue*/ true); + mFlagBackgroundActivityStartsEnabled = enabledInDeviceConfig; + if (!enabledInDeviceConfig) { + whitelistedPackageNames = DeviceConfig.getProperty( + DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, + KEY_BACKGROUND_ACTIVITY_STARTS_PACKAGE_NAMES_WHITELIST); + } + } + if (TextUtils.isEmpty(whitelistedPackageNames)) { + if (!mPackageNamesWhitelistedForBgActivityStarts.isEmpty()) { + mPackageNamesWhitelistedForBgActivityStarts = new ArraySet<>(); + } + } else { + ArraySet<String> newSet = new ArraySet<>(); + SimpleStringSplitter splitter = new SimpleStringSplitter(':'); + splitter.setString(whitelistedPackageNames); + while (splitter.hasNext()) { + newSet.add(splitter.next()); + } + mPackageNamesWhitelistedForBgActivityStarts = newSet; + } } - private void updateBackgroundActivityStartsPackageNamesWhitelist() { - final String setting = Settings.Global.getString(mResolver, - Settings.Global.BACKGROUND_ACTIVITY_STARTS_PACKAGE_NAMES_WHITELIST); - if (TextUtils.isEmpty(setting)) { + private void updateEnableAutomaticSystemServerHeapDumps() { + if (!mSystemServerAutomaticHeapDumpEnabled) { + Slog.wtf(TAG, + "updateEnableAutomaticSystemServerHeapDumps called when leak detection " + + "disabled"); return; } - ArraySet<String> newSet = new ArraySet<>(); - SimpleStringSplitter splitter = new SimpleStringSplitter(':'); - splitter.setString(setting); - while (splitter.hasNext()) { - newSet.add(splitter.next()); - } - mPackageNamesWhitelistedForBgActivityStarts = newSet; + // Monitoring is on by default, so if the setting hasn't been set by the user, + // monitoring should be on. + final boolean enabled = Settings.Global.getInt(mResolver, + Settings.Global.ENABLE_AUTOMATIC_SYSTEM_SERVER_HEAP_DUMPS, 1) == 1; + + // Setting the threshold to 0 stops the checking. + final long threshold = enabled ? mSystemServerAutomaticHeapDumpPssThresholdBytes : 0; + mService.setDumpHeapDebugLimit(null, 0, threshold, + mSystemServerAutomaticHeapDumpPackageName); } private void updateMaxCachedProcesses() { @@ -460,7 +545,7 @@ final class ActivityManagerConstants extends ContentObserver { : mOverrideMaxCachedProcesses; } catch (NumberFormatException e) { // Bad flag value from Phenotype, revert to default. - Slog.e("ActivityManagerConstants", + Slog.e(TAG, "Unable to parse flag for max_cached_processes: " + maxCachedProcessesFlag, e); CUR_MAX_CACHED_PROCESSES = DEFAULT_MAX_CACHED_PROCESSES; } diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 05ec9543520d..a5932ccc1a5c 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -2135,6 +2135,8 @@ public class ActivityManagerService extends IActivityManager.Stub mService.mServices.systemServicesReady(); } else if (phase == PHASE_ACTIVITY_MANAGER_READY) { mService.startBroadcastObservers(); + } else if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) { + mService.mPackageWatchdog.onPackagesReady(); } } @@ -2288,7 +2290,8 @@ public class ActivityManagerService extends IActivityManager.Stub mBatteryStatsService = null; mHandler = hasHandlerThread ? new MainHandler(handlerThread.getLooper()) : null; mHandlerThread = handlerThread; - mConstants = hasHandlerThread ? new ActivityManagerConstants(this, mHandler) : null; + mConstants = hasHandlerThread + ? new ActivityManagerConstants(mContext, this, mHandler) : null; final ActiveUids activeUids = new ActiveUids(this, false /* postChangesToAtm */); mProcessList.init(this, activeUids); mOomAdjuster = new OomAdjuster(this, mProcessList, activeUids); @@ -2336,7 +2339,7 @@ public class ActivityManagerService extends IActivityManager.Stub mProcStartHandlerThread.start(); mProcStartHandler = new Handler(mProcStartHandlerThread.getLooper()); - mConstants = new ActivityManagerConstants(this, mHandler); + mConstants = new ActivityManagerConstants(mContext, this, mHandler); final ActiveUids activeUids = new ActiveUids(this, true /* postChangesToAtm */); mProcessList.init(this, activeUids); mOomAdjuster = new OomAdjuster(this, mProcessList, activeUids); @@ -8769,6 +8772,8 @@ public class ActivityManagerService extends IActivityManager.Stub com.android.internal.R.bool.config_customUserSwitchUi); mUserController.mMaxRunningUsers = res.getInteger( com.android.internal.R.integer.config_multiuserMaxRunningUsers); + mUserController.mDelayUserDataLocking = res.getBoolean( + com.android.internal.R.bool.config_multiuserDelayUserDataLocking); mWaitForNetworkTimeoutMs = waitForNetworkTimeoutMs; } @@ -8835,7 +8840,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 +8853,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); @@ -15321,18 +15335,20 @@ public class ActivityManagerService extends IActivityManager.Stub final ProcessRecord callerApp = getRecordForAppLocked(caller); final int callingPid = Binder.getCallingPid(); final int callingUid = Binder.getCallingUid(); + final long origId = Binder.clearCallingIdentity(); - int res = broadcastIntentLocked(callerApp, - callerApp != null ? callerApp.info.packageName : null, - intent, resolvedType, resultTo, resultCode, resultData, resultExtras, - requiredPermissions, appOp, bOptions, serialized, sticky, - callingPid, callingUid, callingUid, callingPid, userId); - Binder.restoreCallingIdentity(origId); - return res; + try { + return broadcastIntentLocked(callerApp, + callerApp != null ? callerApp.info.packageName : null, + intent, resolvedType, resultTo, resultCode, resultData, resultExtras, + requiredPermissions, appOp, bOptions, serialized, sticky, + callingPid, callingUid, callingUid, callingPid, userId); + } finally { + Binder.restoreCallingIdentity(origId); + } } } - int broadcastIntentInPackage(String packageName, int uid, int realCallingUid, int realCallingPid, Intent intent, String resolvedType, IIntentReceiver resultTo, int resultCode, String resultData, Bundle resultExtras, @@ -15344,13 +15360,15 @@ public class ActivityManagerService extends IActivityManager.Stub final long origId = Binder.clearCallingIdentity(); String[] requiredPermissions = requiredPermission == null ? null : new String[] {requiredPermission}; - int res = broadcastIntentLocked(null, packageName, intent, resolvedType, - resultTo, resultCode, resultData, resultExtras, - requiredPermissions, OP_NONE, bOptions, serialized, - sticky, -1, uid, realCallingUid, realCallingPid, userId, - allowBackgroundActivityStarts); - Binder.restoreCallingIdentity(origId); - return res; + try { + return broadcastIntentLocked(null, packageName, intent, resolvedType, + resultTo, resultCode, resultData, resultExtras, + requiredPermissions, OP_NONE, bOptions, serialized, + sticky, -1, uid, realCallingUid, realCallingPid, userId, + allowBackgroundActivityStarts); + } finally { + Binder.restoreCallingIdentity(origId); + } } } diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java index cc901821030a..8a462dabd14c 100644 --- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java +++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java @@ -16,7 +16,6 @@ package com.android.server.am; -import static android.app.ActivityManagerInternal.ALLOW_FULL_ONLY; import static android.app.ActivityTaskManager.INVALID_TASK_ID; import static android.app.ActivityTaskManager.RESIZE_MODE_SYSTEM; import static android.app.ActivityTaskManager.RESIZE_MODE_USER; @@ -306,9 +305,7 @@ final class ActivityManagerShellCommand extends ShellCommand { mSamplingInterval = 0; mAutoStop = false; mStreaming = false; - mUserId = mInternal.mUserController.handleIncomingUser(Binder.getCallingPid(), - Binder.getCallingUid(), defUser, false, ALLOW_FULL_ONLY, - "ActivityManagerShellCommand", null); + mUserId = defUser; mDisplayId = INVALID_DISPLAY; mWindowingMode = WINDOWING_MODE_UNDEFINED; mActivityType = ACTIVITY_TYPE_UNDEFINED; diff --git a/services/core/java/com/android/server/am/ConnectionRecord.java b/services/core/java/com/android/server/am/ConnectionRecord.java index a1c941e085a6..fe9554255feb 100644 --- a/services/core/java/com/android/server/am/ConnectionRecord.java +++ b/services/core/java/com/android/server/am/ConnectionRecord.java @@ -109,6 +109,14 @@ final class ConnectionRecord { clientPackageName = _clientPackageName; } + public boolean hasFlag(final int flag) { + return (flags & flag) != 0; + } + + public boolean notHasFlag(final int flag) { + return (flags & flag) == 0; + } + public void startAssociationIfNeeded() { // If we don't already have an active association, create one... but only if this // is an association between two different processes. diff --git a/services/core/java/com/android/server/am/CoreSettingsObserver.java b/services/core/java/com/android/server/am/CoreSettingsObserver.java index 06d015234011..cb587de01f14 100644 --- a/services/core/java/com/android/server/am/CoreSettingsObserver.java +++ b/services/core/java/com/android/server/am/CoreSettingsObserver.java @@ -58,6 +58,8 @@ final class CoreSettingsObserver extends ContentObserver { sGlobalSettingToTypeMap.put( Settings.Global.DEBUG_VIEW_ATTRIBUTES_APPLICATION_PACKAGE, String.class); sGlobalSettingToTypeMap.put( + Settings.Global.GLOBAL_SETTINGS_ANGLE_DEBUG_PACKAGE, String.class); + sGlobalSettingToTypeMap.put( Settings.Global.GLOBAL_SETTINGS_ANGLE_GL_DRIVER_ALL_ANGLE, String.class); sGlobalSettingToTypeMap.put( Settings.Global.GLOBAL_SETTINGS_ANGLE_GL_DRIVER_SELECTION_PKGS, String.class); diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java index c1b9a20d143d..5d47c9dfdddd 100644 --- a/services/core/java/com/android/server/am/OomAdjuster.java +++ b/services/core/java/com/android/server/am/OomAdjuster.java @@ -16,10 +16,19 @@ package com.android.server.am; +import static android.app.ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE; +import static android.app.ActivityManager.PROCESS_STATE_BOUND_TOP; import static android.app.ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; import static android.app.ActivityManager.PROCESS_STATE_CACHED_EMPTY; +import static android.app.ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE; +import static android.app.ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE_LOCATION; +import static android.app.ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; +import static android.app.ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; import static android.app.ActivityManager.PROCESS_STATE_LAST_ACTIVITY; import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT; +import static android.app.ActivityManager.PROCESS_STATE_SERVICE; +import static android.app.ActivityManager.PROCESS_STATE_TOP; +import static android.app.ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND; import static android.os.Process.SCHED_OTHER; import static android.os.Process.THREAD_GROUP_BG_NONINTERACTIVE; import static android.os.Process.THREAD_GROUP_DEFAULT; @@ -53,12 +62,14 @@ import android.app.usage.UsageEvents; import android.content.Context; import android.os.Binder; import android.os.Debug; +import android.os.IBinder; import android.os.PowerManagerInternal; import android.os.Process; import android.os.RemoteException; import android.os.SystemClock; import android.os.Trace; import android.os.UserHandle; +import android.util.ArrayMap; import android.util.ArraySet; import android.util.Slog; import android.util.proto.ProtoOutputStream; @@ -411,7 +422,7 @@ public final class OomAdjuster { app.kill("cached #" + numCached, true); } break; - case ActivityManager.PROCESS_STATE_CACHED_EMPTY: + case PROCESS_STATE_CACHED_EMPTY: if (numEmpty > mConstants.CUR_TRIM_EMPTY_PROCESSES && app.lastActivityTime < oldTime) { app.kill("empty for " @@ -716,7 +727,7 @@ public final class OomAdjuster { if (app.thread == null) { app.adjSeq = mAdjSeq; app.setCurrentSchedulingGroup(ProcessList.SCHED_GROUP_BACKGROUND); - app.setCurProcState(ActivityManager.PROCESS_STATE_CACHED_EMPTY); + app.setCurProcState(PROCESS_STATE_CACHED_EMPTY); app.curAdj = ProcessList.CACHED_APP_MAX_ADJ; app.setCurRawAdj(ProcessList.CACHED_APP_MAX_ADJ); app.completedAdjSeq = app.adjSeq; @@ -771,7 +782,7 @@ public final class OomAdjuster { app.setCurrentSchedulingGroup(ProcessList.SCHED_GROUP_TOP_APP); } else { // screen off, restrict UI scheduling - app.setCurProcState(ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE); + app.setCurProcState(PROCESS_STATE_BOUND_FOREGROUND_SERVICE); app.setCurrentSchedulingGroup(ProcessList.SCHED_GROUP_RESTRICTED); } } @@ -795,7 +806,7 @@ public final class OomAdjuster { boolean foregroundActivities = false; mTmpBroadcastQueue.clear(); - if (PROCESS_STATE_CUR_TOP == ActivityManager.PROCESS_STATE_TOP && app == TOP_APP) { + if (PROCESS_STATE_CUR_TOP == PROCESS_STATE_TOP && app == TOP_APP) { // The last app on the list is the foreground app. adj = ProcessList.FOREGROUND_APP_ADJ; schedGroup = ProcessList.SCHED_GROUP_TOP_APP; @@ -818,7 +829,7 @@ public final class OomAdjuster { adj = ProcessList.FOREGROUND_APP_ADJ; schedGroup = ProcessList.SCHED_GROUP_DEFAULT; app.adjType = "instrumentation"; - procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE; + procState = PROCESS_STATE_FOREGROUND_SERVICE; if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making instrumentation: " + app); } @@ -842,7 +853,7 @@ public final class OomAdjuster { schedGroup = app.execServicesFg ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND; app.adjType = "exec-service"; - procState = ActivityManager.PROCESS_STATE_SERVICE; + procState = PROCESS_STATE_SERVICE; if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making exec-service: " + app); } @@ -862,7 +873,7 @@ public final class OomAdjuster { // At this point we don't actually know the adjustment. Use the cached adj // value that the caller wants us to. adj = cachedAdj; - procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; + procState = PROCESS_STATE_CACHED_EMPTY; app.cached = true; app.empty = true; app.adjType = "cch-empty"; @@ -897,23 +908,28 @@ public final class OomAdjuster { } if (adj > ProcessList.PERCEPTIBLE_APP_ADJ - || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE_LOCATION) { + || procState > PROCESS_STATE_FOREGROUND_SERVICE_LOCATION) { if (app.hasForegroundServices()) { // The user is aware of this app, so make it visible. adj = ProcessList.PERCEPTIBLE_APP_ADJ; - procState = app.hasLocationForegroundServices() - ? ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE_LOCATION - : ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE; + if (app.hasLocationForegroundServices()) { + procState = PROCESS_STATE_FOREGROUND_SERVICE_LOCATION; + app.adjType = "fg-service-location"; + + } else { + procState = PROCESS_STATE_FOREGROUND_SERVICE; + app.adjType = "fg-service"; + } app.cached = false; - app.adjType = "fg-service"; schedGroup = ProcessList.SCHED_GROUP_DEFAULT; if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { - reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to fg service: " + app); + reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to " + app.adjType + ": " + + app + " "); } } else if (app.hasOverlayUi()) { // The process is display an overlay UI. adj = ProcessList.PERCEPTIBLE_APP_ADJ; - procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; + procState = PROCESS_STATE_IMPORTANT_FOREGROUND; app.cached = false; app.adjType = "has-overlay-ui"; schedGroup = ProcessList.SCHED_GROUP_DEFAULT; @@ -928,7 +944,7 @@ public final class OomAdjuster { // services so that it can finish performing any persistence/processing of in-memory state. if (app.hasForegroundServices() && adj > ProcessList.PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ && (app.lastTopTime + mConstants.TOP_TO_FGS_GRACE_DURATION > now - || app.setProcState <= ActivityManager.PROCESS_STATE_TOP)) { + || app.setProcState <= PROCESS_STATE_TOP)) { adj = ProcessList.PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ; app.adjType = "fg-service-act"; if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { @@ -937,13 +953,13 @@ public final class OomAdjuster { } if (adj > ProcessList.PERCEPTIBLE_APP_ADJ - || procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) { + || procState > PROCESS_STATE_TRANSIENT_BACKGROUND) { if (app.forcingToImportant != null) { // This is currently used for toasts... they are not interactive, and // we don't want them to cause the app to become fully foreground (and // thus out of background check), so we yes the best background level we can. adj = ProcessList.PERCEPTIBLE_APP_ADJ; - procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND; + procState = PROCESS_STATE_TRANSIENT_BACKGROUND; app.cached = false; app.adjType = "force-imp"; app.adjSource = app.forcingToImportant; @@ -1039,8 +1055,8 @@ public final class OomAdjuster { if (adj > ProcessList.BACKUP_APP_ADJ) { if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app); adj = ProcessList.BACKUP_APP_ADJ; - if (procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) { - procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND; + if (procState > PROCESS_STATE_TRANSIENT_BACKGROUND) { + procState = PROCESS_STATE_TRANSIENT_BACKGROUND; } app.adjType = "backup"; if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { @@ -1057,21 +1073,16 @@ public final class OomAdjuster { } } - boolean mayBeTop = false; - String mayBeTopType = null; - Object mayBeTopSource = null; - Object mayBeTopTarget = null; - for (int is = app.services.size() - 1; is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND - || procState > ActivityManager.PROCESS_STATE_TOP); + || procState > PROCESS_STATE_TOP); is--) { ServiceRecord s = app.services.valueAt(is); if (s.startRequested) { app.hasStartedServices = true; - if (procState > ActivityManager.PROCESS_STATE_SERVICE) { - procState = ActivityManager.PROCESS_STATE_SERVICE; + if (procState > PROCESS_STATE_SERVICE) { + procState = PROCESS_STATE_SERVICE; app.adjType = "started-services"; if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { reportOomAdjMessageLocked(TAG_OOM_ADJ, @@ -1110,16 +1121,17 @@ public final class OomAdjuster { } } - for (int conni = s.connections.size() - 1; + ArrayMap<IBinder, ArrayList<ConnectionRecord>> serviceConnections = s.getConnections(); + for (int conni = serviceConnections.size() - 1; conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND - || procState > ActivityManager.PROCESS_STATE_TOP); + || procState > PROCESS_STATE_TOP); conni--) { - ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); + ArrayList<ConnectionRecord> clist = serviceConnections.valueAt(conni); for (int i = 0; i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND - || procState > ActivityManager.PROCESS_STATE_TOP); + || procState > PROCESS_STATE_TOP); i++) { // XXX should compute this based on the max of // all connected clients. @@ -1145,7 +1157,7 @@ public final class OomAdjuster { // If the other app is cached for any reason, for purposes here // we are going to consider it empty. The specific cached state // doesn't propagate except under certain conditions. - clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; + clientProcState = PROCESS_STATE_CACHED_EMPTY; } String adjType = null; if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { @@ -1216,6 +1228,7 @@ public final class OomAdjuster { newAdj = clientAdj; } else { if (adj > ProcessList.VISIBLE_APP_ADJ) { + // TODO: Is this too limiting for apps bound from TOP? newAdj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ); } else { newAdj = adj; @@ -1244,55 +1257,50 @@ public final class OomAdjuster { schedGroup = ProcessList.SCHED_GROUP_DEFAULT; } } - if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { - if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { - // Special handling of clients who are in the top state. - // We *may* want to consider this process to be in the - // top state as well, but only if there is not another - // reason for it to be running. Being on the top is a - // special state, meaning you are specifically running - // for the current top app. If the process is already - // running in the background for some other reason, it - // is more important to continue considering it to be - // in the background state. - mayBeTop = true; - mayBeTopType = "service"; - mayBeTopSource = cr.binding.client; - mayBeTopTarget = s.instanceName; - clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; + if (clientProcState < PROCESS_STATE_TOP) { + // Special handling for above-top states (persistent + // processes). These should not bring the current process + // into the top state, since they are not on top. Instead + // give them the best bound state after that. + if ((cr.flags & Context.BIND_FOREGROUND_SERVICE) != 0) { + clientProcState = + PROCESS_STATE_BOUND_FOREGROUND_SERVICE; + } else if (mService.mWakefulness + == PowerManagerInternal.WAKEFULNESS_AWAKE + && (cr.flags & Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE) + != 0) { + clientProcState = + PROCESS_STATE_BOUND_FOREGROUND_SERVICE; } else { - // Special handling for above-top states (persistent - // processes). These should not bring the current process - // into the top state, since they are not on top. Instead - // give them the best state after that. - if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) { - clientProcState = - ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE; - } else if (mService.mWakefulness - == PowerManagerInternal.WAKEFULNESS_AWAKE && - (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE) - != 0) { - clientProcState = - ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE; - } else { - clientProcState = - ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; - } + clientProcState = + PROCESS_STATE_IMPORTANT_FOREGROUND; + } + } else if (clientProcState == PROCESS_STATE_TOP) { + if (cr.notHasFlag(Context.BIND_INCLUDE_CAPABILITIES)) { + // Go at most to BOUND_TOP, unless requested to elevate + // to client's state. + clientProcState = PROCESS_STATE_BOUND_TOP; + } + } else if (clientProcState + <= PROCESS_STATE_FOREGROUND_SERVICE) { + if (cr.notHasFlag(Context.BIND_INCLUDE_CAPABILITIES)) { + clientProcState = PROCESS_STATE_FOREGROUND_SERVICE; } } } else if ((cr.flags & Context.BIND_IMPORTANT_BACKGROUND) == 0) { if (clientProcState < - ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) { + PROCESS_STATE_TRANSIENT_BACKGROUND) { clientProcState = - ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND; + PROCESS_STATE_TRANSIENT_BACKGROUND; } } else { if (clientProcState < - ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { + PROCESS_STATE_IMPORTANT_BACKGROUND) { clientProcState = - ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; + PROCESS_STATE_IMPORTANT_BACKGROUND; } } + if (schedGroup < ProcessList.SCHED_GROUP_TOP_APP && (cr.flags & Context.BIND_SCHEDULE_LIKE_TOP_APP) != 0) { schedGroup = ProcessList.SCHED_GROUP_TOP_APP; @@ -1301,6 +1309,7 @@ public final class OomAdjuster { if (!trackedProcState) { cr.trackProcState(clientProcState, mAdjSeq, now); } + if (procState > clientProcState) { procState = clientProcState; app.setCurRawProcState(procState); @@ -1308,7 +1317,7 @@ public final class OomAdjuster { adjType = "service"; } } - if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND + if (procState < PROCESS_STATE_IMPORTANT_BACKGROUND && (cr.flags & Context.BIND_SHOWING_UI) != 0) { app.setPendingUiClean(true); } @@ -1363,13 +1372,13 @@ public final class OomAdjuster { for (int provi = app.pubProviders.size() - 1; provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND - || procState > ActivityManager.PROCESS_STATE_TOP); + || procState > PROCESS_STATE_TOP); provi--) { ContentProviderRecord cpr = app.pubProviders.valueAt(provi); for (int i = cpr.connections.size() - 1; i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND - || procState > ActivityManager.PROCESS_STATE_TOP); + || procState > PROCESS_STATE_TOP); i--) { ContentProviderConnection conn = cpr.connections.get(i); ProcessRecord client = conn.client; @@ -1389,7 +1398,7 @@ public final class OomAdjuster { if (clientProcState >= PROCESS_STATE_CACHED_ACTIVITY) { // If the other app is cached for any reason, for purposes here // we are going to consider it empty. - clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; + clientProcState = PROCESS_STATE_CACHED_EMPTY; } String adjType = null; if (adj > clientAdj) { @@ -1404,34 +1413,18 @@ public final class OomAdjuster { } app.cached &= client.cached; } - if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { - if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { - // Special handling of clients who are in the top state. - // We *may* want to consider this process to be in the - // top state as well, but only if there is not another - // reason for it to be running. Being on the top is a - // special state, meaning you are specifically running - // for the current top app. If the process is already - // running in the background for some other reason, it - // is more important to continue considering it to be - // in the background state. - mayBeTop = true; - clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; - mayBeTopType = adjType = "provider-top"; - mayBeTopSource = client; - mayBeTopTarget = cpr.name; + + if (clientProcState <= PROCESS_STATE_FOREGROUND_SERVICE) { + if (adjType == null) { + adjType = "provider"; + } + if (clientProcState == PROCESS_STATE_TOP) { + clientProcState = PROCESS_STATE_BOUND_TOP; } else { - // Special handling for above-top states (persistent - // processes). These should not bring the current process - // into the top state, since they are not on top. Instead - // give them the best state after that. - clientProcState = - ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE; - if (adjType == null) { - adjType = "provider"; - } + clientProcState = PROCESS_STATE_BOUND_FOREGROUND_SERVICE; } } + conn.trackProcState(clientProcState, mAdjSeq, now); if (procState > clientProcState) { procState = clientProcState; @@ -1471,8 +1464,8 @@ public final class OomAdjuster { "Raise adj to external provider: " + app); } } - if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { - procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; + if (procState > PROCESS_STATE_IMPORTANT_FOREGROUND) { + procState = PROCESS_STATE_IMPORTANT_FOREGROUND; app.setCurRawProcState(procState); if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { reportOomAdjMessageLocked(TAG_OOM_ADJ, @@ -1504,53 +1497,7 @@ public final class OomAdjuster { } } - if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { - // A client of one of our services or providers is in the top state. We - // *may* want to be in the top state, but not if we are already running in - // the background for some other reason. For the decision here, we are going - // to pick out a few specific states that we want to remain in when a client - // is top (states that tend to be longer-term) and otherwise allow it to go - // to the top state. - switch (procState) { - case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE: - case ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE: - case ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE_LOCATION: - // Something else is keeping it at this level, just leave it. - break; - case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: - case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: - case ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND: - case ActivityManager.PROCESS_STATE_SERVICE: - // These all are longer-term states, so pull them up to the top - // of the background states, but not all the way to the top state. - procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE; - app.adjType = mayBeTopType; - app.adjSource = mayBeTopSource; - app.adjTarget = mayBeTopTarget; - if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { - reportOomAdjMessageLocked(TAG_OOM_ADJ, "May be top raise to " + mayBeTopType - + ": " + app + ", due to " + mayBeTopSource - + " adj=" + adj + " procState=" - + ProcessList.makeProcStateString(procState)); - } - break; - default: - // Otherwise, top is a better choice, so take it. - procState = ActivityManager.PROCESS_STATE_TOP; - app.adjType = mayBeTopType; - app.adjSource = mayBeTopSource; - app.adjTarget = mayBeTopTarget; - if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { - reportOomAdjMessageLocked(TAG_OOM_ADJ, "May be top raise to " + mayBeTopType - + ": " + app + ", due to " + mayBeTopSource - + " adj=" + adj + " procState=" - + ProcessList.makeProcStateString(procState)); - } - break; - } - } - - if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { + if (procState >= PROCESS_STATE_CACHED_EMPTY) { if (app.hasClientActivities()) { // This is a cached process, but with client activities. Mark it so. procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; @@ -1604,8 +1551,8 @@ public final class OomAdjuster { // Put bound foreground services in a special sched group for additional // restrictions on screen off - if (procState >= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE && - mService.mWakefulness != PowerManagerInternal.WAKEFULNESS_AWAKE) { + if (procState >= PROCESS_STATE_BOUND_FOREGROUND_SERVICE + && mService.mWakefulness != PowerManagerInternal.WAKEFULNESS_AWAKE) { if (schedGroup > ProcessList.SCHED_GROUP_RESTRICTED) { schedGroup = ProcessList.SCHED_GROUP_RESTRICTED; } @@ -1902,8 +1849,8 @@ public final class OomAdjuster { + " (" + app.getCurProcState() + ")" + ": " + app.adjType; reportOomAdjMessageLocked(TAG_OOM_ADJ, msg); } - boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE; - boolean curImportant = app.getCurProcState() < ActivityManager.PROCESS_STATE_SERVICE; + boolean setImportant = app.setProcState < PROCESS_STATE_SERVICE; + boolean curImportant = app.getCurProcState() < PROCESS_STATE_SERVICE; if (setImportant && !curImportant) { // This app is no longer something we consider important enough to allow to use // arbitrary amounts of battery power. Note its current CPU time to later know to @@ -1966,10 +1913,11 @@ public final class OomAdjuster { // To avoid some abuse patterns, we are going to be careful about what we consider // to be an app interaction. Being the top activity doesn't count while the display // is sleeping, nor do short foreground services. - if (app.getCurProcState() <= ActivityManager.PROCESS_STATE_TOP) { + if (app.getCurProcState() <= PROCESS_STATE_TOP + || app.getCurProcState() == PROCESS_STATE_BOUND_TOP) { isInteraction = true; app.setFgInteractionTime(0); - } else if (app.getCurProcState() <= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) { + } else if (app.getCurProcState() <= PROCESS_STATE_FOREGROUND_SERVICE) { if (app.getFgInteractionTime() == 0) { app.setFgInteractionTime(nowElapsed); isInteraction = false; @@ -1979,7 +1927,7 @@ public final class OomAdjuster { } } else { isInteraction = - app.getCurProcState() <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; + app.getCurProcState() <= PROCESS_STATE_IMPORTANT_FOREGROUND; app.setFgInteractionTime(0); } if (isInteraction @@ -2001,8 +1949,8 @@ public final class OomAdjuster { } private void maybeUpdateLastTopTime(ProcessRecord app, long nowUptime) { - if (app.setProcState <= ActivityManager.PROCESS_STATE_TOP - && app.getCurProcState() > ActivityManager.PROCESS_STATE_TOP) { + if (app.setProcState <= PROCESS_STATE_TOP + && app.getCurProcState() > PROCESS_STATE_TOP) { app.lastTopTime = nowUptime; } } diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java index d02fd7387f59..f1f40d49ccd1 100644 --- a/services/core/java/com/android/server/am/ProcessList.java +++ b/services/core/java/com/android/server/am/ProcessList.java @@ -769,6 +769,9 @@ public final class ProcessList { case ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE_LOCATION: procState = "FGSL"; break; + case ActivityManager.PROCESS_STATE_BOUND_TOP: + procState = "BTOP"; + break; case ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE: procState = "FGS "; break; @@ -836,6 +839,9 @@ public final class ProcessList { case ActivityManager.PROCESS_STATE_TOP: return AppProtoEnums.PROCESS_STATE_TOP; case ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE_LOCATION: + return AppProtoEnums.PROCESS_STATE_FOREGROUND_SERVICE; + case ActivityManager.PROCESS_STATE_BOUND_TOP: + return AppProtoEnums.PROCESS_STATE_BOUND_TOP; case ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE: return AppProtoEnums.PROCESS_STATE_FOREGROUND_SERVICE; case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE: @@ -966,6 +972,7 @@ public final class ProcessList { PROC_MEM_TOP, // ActivityManager.PROCESS_STATE_TOP PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE_LOCATION PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE + PROC_MEM_TOP, // ActivityManager.PROCESS_STATE_BOUND_TOP PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java index a90e994c1ee8..ce13cd88a192 100644 --- a/services/core/java/com/android/server/am/ProcessRecord.java +++ b/services/core/java/com/android/server/am/ProcessRecord.java @@ -259,6 +259,8 @@ class ProcessRecord implements WindowProcessListener { // A set of tokens that currently contribute to this process being temporarily whitelisted // to start activities even if it's not in the foreground final ArraySet<Binder> mAllowBackgroundActivityStartsTokens = new ArraySet<>(); + // a set of UIDs of all bound clients + private ArraySet<Integer> mBoundClientUids = new ArraySet<>(); String isolatedEntryPoint; // Class to run on start if this is a special isolated process. String[] isolatedEntryPointArgs; // Arguments to pass to isolatedEntryPoint's main(). @@ -1193,6 +1195,53 @@ class ProcessRecord implements WindowProcessListener { !mAllowBackgroundActivityStartsTokens.isEmpty()); } + void addBoundClientUids(ArraySet<Integer> clientUids) { + mBoundClientUids.addAll(clientUids); + mWindowProcessController.setBoundClientUids(mBoundClientUids); + } + + void updateBoundClientUids() { + if (services.isEmpty()) { + clearBoundClientUids(); + return; + } + // grab a set of clientUids of all connections of all services + ArraySet<Integer> boundClientUids = new ArraySet<>(); + final int K = services.size(); + for (int j = 0; j < K; j++) { + ArrayMap<IBinder, ArrayList<ConnectionRecord>> conns = + services.valueAt(j).getConnections(); + final int N = conns.size(); + for (int conni = 0; conni < N; conni++) { + ArrayList<ConnectionRecord> c = conns.valueAt(conni); + for (int i = 0; i < c.size(); i++) { + boundClientUids.add(c.get(i).clientUid); + } + } + } + mBoundClientUids = boundClientUids; + mWindowProcessController.setBoundClientUids(mBoundClientUids); + } + + void addBoundClientUidsOfNewService(ServiceRecord sr) { + if (sr == null) { + return; + } + ArrayMap<IBinder, ArrayList<ConnectionRecord>> conns = sr.getConnections(); + for (int conni = conns.size() - 1; conni >= 0; conni--) { + ArrayList<ConnectionRecord> c = conns.valueAt(conni); + for (int i = 0; i < c.size(); i++) { + mBoundClientUids.add(c.get(i).clientUid); + } + } + mWindowProcessController.setBoundClientUids(mBoundClientUids); + } + + void clearBoundClientUids() { + mBoundClientUids.clear(); + mWindowProcessController.setBoundClientUids(mBoundClientUids); + } + void setActiveInstrumentation(ActiveInstrumentation instr) { mInstr = instr; boolean isInstrumenting = instr != null; diff --git a/services/core/java/com/android/server/am/ServiceRecord.java b/services/core/java/com/android/server/am/ServiceRecord.java index eeaa7de85b5c..217fd6d71888 100644 --- a/services/core/java/com/android/server/am/ServiceRecord.java +++ b/services/core/java/com/android/server/am/ServiceRecord.java @@ -38,6 +38,7 @@ import android.os.SystemClock; import android.os.UserHandle; import android.provider.Settings; import android.util.ArrayMap; +import android.util.ArraySet; import android.util.Slog; import android.util.TimeUtils; import android.util.proto.ProtoOutputStream; @@ -88,7 +89,7 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN final ArrayMap<Intent.FilterComparison, IntentBindRecord> bindings = new ArrayMap<Intent.FilterComparison, IntentBindRecord>(); // All active bindings to the service. - final ArrayMap<IBinder, ArrayList<ConnectionRecord>> connections + private final ArrayMap<IBinder, ArrayList<ConnectionRecord>> connections = new ArrayMap<IBinder, ArrayList<ConnectionRecord>>(); // IBinder -> ConnectionRecord of all bound clients @@ -542,6 +543,7 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN } } else if (app != null) { app.removeAllowBackgroundActivityStartsToken(this); + app.updateBoundClientUids(); } app = _proc; if (pendingConnectionGroup > 0 && _proc != null) { @@ -563,6 +565,33 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN } } } + if (_proc != null) { + _proc.updateBoundClientUids(); + } + } + + ArrayMap<IBinder, ArrayList<ConnectionRecord>> getConnections() { + return connections; + } + + void putConnection(IBinder binder, ArrayList<ConnectionRecord> clist) { + connections.put(binder, clist); + // if we have a process attached, add bound client uids of this connection to it + if (app != null) { + ArraySet<Integer> boundClientUids = new ArraySet<>(); + for (int i = 0; i < clist.size(); i++) { + boundClientUids.add(clist.get(i).clientUid); + } + app.addBoundClientUids(boundClientUids); + } + } + + void removeConnection(IBinder binder) { + connections.remove(binder); + // if we have a process attached, tell it to update the state of bound clients + if (app != null) { + app.updateBoundClientUids(); + } } void updateHasBindingWhitelistingBgActivityStarts() { diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java index 07c9cca3f6c3..2bd91985eafb 100644 --- a/services/core/java/com/android/server/am/UserController.java +++ b/services/core/java/com/android/server/am/UserController.java @@ -241,6 +241,20 @@ class UserController implements Handler.Callback { volatile boolean mBootCompleted; + /** + * In this mode, user is always stopped when switched out but locking of user data is + * postponed until total number of unlocked users in the system reaches mMaxRunningUsers. + * Once total number of unlocked users reach mMaxRunningUsers, least recentely used user + * will be locked. + */ + boolean mDelayUserDataLocking; + /** + * Keep track of last active users for mDelayUserDataLocking. + * The latest stopped user is placed in front while the least recently stopped user in back. + */ + @GuardedBy("mLock") + private final ArrayList<Integer> mLastActiveUsers = new ArrayList<>(); + UserController(ActivityManagerService service) { this(new Injector(service)); } @@ -738,7 +752,9 @@ class UserController implements Handler.Callback { void finishUserStopped(UserState uss) { final int userId = uss.mHandle.getIdentifier(); final boolean stopped; + boolean lockUser = true; ArrayList<IStopUserCallback> callbacks; + int userIdToLock = userId; synchronized (mLock) { callbacks = new ArrayList<>(uss.mStopCallbacks); if (mStartedUsers.get(userId) != uss || uss.state != UserState.STATE_SHUTDOWN) { @@ -749,9 +765,12 @@ class UserController implements Handler.Callback { mStartedUsers.remove(userId); mUserLru.remove(Integer.valueOf(userId)); updateStartedUserArrayLU(); + userIdToLock = updateUserToLockLU(userId); + if (userIdToLock == UserHandle.USER_NULL) { + lockUser = false; + } } } - if (stopped) { mInjector.getUserManagerInternal().removeUserState(userId); mInjector.activityManagerOnUserStopped(userId); @@ -776,18 +795,22 @@ class UserController implements Handler.Callback { mInjector.getUserManager().removeUserEvenWhenDisallowed(userId); } + if (!lockUser) { + return; + } + final int userIdToLockF = userIdToLock; // Evict the user's credential encryption key. Performed on FgThread to make it // serialized with call to UserManagerService.onBeforeUnlockUser in finishUserUnlocking // to prevent data corruption. FgThread.getHandler().post(() -> { synchronized (mLock) { - if (mStartedUsers.get(userId) != null) { + if (mStartedUsers.get(userIdToLockF) != null) { Slog.w(TAG, "User was restarted, skipping key eviction"); return; } } try { - getStorageManager().lockUserKey(userId); + mInjector.getStorageManager().lockUserKey(userIdToLockF); } catch (RemoteException re) { throw re.rethrowAsRuntimeException(); } @@ -796,6 +819,39 @@ class UserController implements Handler.Callback { } /** + * For mDelayUserDataLocking mode, storage once unlocked is kept unlocked. + * Total number of unlocked user storage is limited by mMaxRunningUsers. + * If there are more unlocked users, evict and lock the least recently stopped user and + * lock that user's data. Regardless of the mode, ephemeral user is always locked + * immediately. + * + * @return user id to lock. UserHandler.USER_NULL will be returned if no user should be locked. + */ + @GuardedBy("mLock") + private int updateUserToLockLU(int userId) { + int userIdToLock = userId; + if (mDelayUserDataLocking && !getUserInfo(userId).isEphemeral() + && !hasUserRestriction(UserManager.DISALLOW_RUN_IN_BACKGROUND, userId)) { + mLastActiveUsers.remove((Integer) userId); // arg should be object, not index + mLastActiveUsers.add(0, userId); + int totalUnlockedUsers = mStartedUsers.size() + mLastActiveUsers.size(); + if (totalUnlockedUsers > mMaxRunningUsers) { // should lock a user + userIdToLock = mLastActiveUsers.get(mLastActiveUsers.size() - 1); + mLastActiveUsers.remove(mLastActiveUsers.size() - 1); + Slog.i(TAG, "finishUserStopped, stopping user:" + userId + + " lock user:" + userIdToLock); + } else { + Slog.i(TAG, "finishUserStopped, user:" + userId + + ",skip locking"); + // do not lock + userIdToLock = UserHandle.USER_NULL; + + } + } + return userIdToLock; + } + + /** * Determines the list of users that should be stopped together with the specified * {@code userId}. The returned list includes {@code userId}. */ @@ -896,9 +952,6 @@ class UserController implements Handler.Callback { } } - private IStorageManager getStorageManager() { - return IStorageManager.Stub.asInterface(ServiceManager.getService("mount")); - } boolean startUser(final int userId, final boolean foreground) { return startUser(userId, foreground, null); } @@ -956,15 +1009,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) { @@ -1188,7 +1252,7 @@ class UserController implements Handler.Callback { UserState uss; if (!StorageManager.isUserKeyUnlocked(userId)) { final UserInfo userInfo = getUserInfo(userId); - final IStorageManager storageManager = getStorageManager(); + final IStorageManager storageManager = mInjector.getStorageManager(); try { // We always want to unlock user storage, even user is not started yet storageManager.unlockUserKey(userId, userInfo.serialNumber, token, secret); @@ -1323,9 +1387,9 @@ class UserController implements Handler.Callback { if (oldUserId == UserHandle.USER_SYSTEM) { return; } - // For now, only check for user restriction. Additional checks can be added here + // If running in background is disabled or mDelayUserDataLocking mode, stop the user. boolean disallowRunInBg = hasUserRestriction(UserManager.DISALLOW_RUN_IN_BACKGROUND, - oldUserId); + oldUserId) || mDelayUserDataLocking; if (!disallowRunInBg) { return; } @@ -1743,6 +1807,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) && ( @@ -2004,6 +2086,8 @@ class UserController implements Handler.Callback { pw.println(mUserProfileGroupIds.valueAt(i)); } } + pw.println(" mCurrentUserId:" + mCurrentUserId); + pw.println(" mLastActiveUsers:" + mLastActiveUsers); } } @@ -2297,5 +2381,9 @@ class UserController implements Handler.Callback { protected boolean isCallerRecents(int callingUid) { return mService.mAtmInternal.isCallerRecents(callingUid); } + + protected IStorageManager getStorageManager() { + return IStorageManager.Stub.asInterface(ServiceManager.getService("mount")); + } } } diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java index 2e5dd3b0941e..c9e7cfa73259 100644 --- a/services/core/java/com/android/server/appop/AppOpsService.java +++ b/services/core/java/com/android/server/appop/AppOpsService.java @@ -153,6 +153,7 @@ public class AppOpsService extends IAppOpsService.Stub { UID_STATE_TOP, // ActivityManager.PROCESS_STATE_TOP UID_STATE_FOREGROUND_SERVICE_LOCATION, // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE_LOCATION + UID_STATE_FOREGROUND, // ActivityManager.PROCESS_STATE_BOUND_TOP UID_STATE_FOREGROUND_SERVICE, // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE UID_STATE_FOREGROUND, // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE UID_STATE_FOREGROUND, // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND diff --git a/services/core/java/com/android/server/audio/AudioDeviceInventory.java b/services/core/java/com/android/server/audio/AudioDeviceInventory.java index 5ec8cfa37e4d..5f624ba9be9d 100644 --- a/services/core/java/com/android/server/audio/AudioDeviceInventory.java +++ b/services/core/java/com/android/server/audio/AudioDeviceInventory.java @@ -896,7 +896,7 @@ public final class AudioDeviceInventory { final long ident = Binder.clearCallingIdentity(); try { - ActivityManager.broadcastStickyIntent(intent, UserHandle.USER_ALL); + ActivityManager.broadcastStickyIntent(intent, UserHandle.USER_CURRENT); } finally { Binder.restoreCallingIdentity(ident); } diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index 82a4f1df2e10..32781a90348b 100644 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -640,6 +640,26 @@ public class AudioService extends IAudioService.Stub sAudioVolumeGroups = new AudioVolumeGroups(); // Initialize volume + // Priority 1 - Android Property + // Priority 2 - Audio Policy Service + // Priority 3 - Default Value + if (sAudioProductStrategies.size() > 0) { + int numStreamTypes = AudioSystem.getNumStreamTypes(); + + for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) { + AudioAttributes attr = + sAudioProductStrategies.getAudioAttributesForLegacyStreamType(streamType); + int maxVolume = AudioSystem.getMaxVolumeIndexForAttributes(attr); + if (maxVolume != -1) { + MAX_STREAM_VOLUME[streamType] = maxVolume; + } + int minVolume = AudioSystem.getMinVolumeIndexForAttributes(attr); + if (minVolume != -1) { + MIN_STREAM_VOLUME[streamType] = minVolume; + } + } + } + int maxCallVolume = SystemProperties.getInt("ro.config.vc_call_vol_steps", -1); if (maxCallVolume != -1) { MAX_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] = maxCallVolume; @@ -1468,6 +1488,11 @@ public class AudioService extends IAudioService.Stub } private int rescaleIndex(int index, int srcStream, int dstStream) { + int max = mStreamStates[srcStream].getMaxIndex(); + if (max == 0) { + Log.e(TAG, "rescaleIndex : Max index should not be zero"); + return mStreamStates[srcStream].getMinIndex(); + } final int rescaled = (index * mStreamStates[dstStream].getMaxIndex() + mStreamStates[srcStream].getMaxIndex() / 2) diff --git a/services/core/java/com/android/server/audio/RecordingActivityMonitor.java b/services/core/java/com/android/server/audio/RecordingActivityMonitor.java index b2c7ff3bfdf6..87b272b434d7 100644 --- a/services/core/java/com/android/server/audio/RecordingActivityMonitor.java +++ b/services/core/java/com/android/server/audio/RecordingActivityMonitor.java @@ -69,6 +69,9 @@ public final class RecordingActivityMonitor implements AudioSystem.AudioRecordin AudioEffect.Descriptor[] effects, int activeSource, String packName) { if (MediaRecorder.isSystemOnlyAudioSource(source)) { + // still want to log event, it just won't appear in recording configurations + sEventLogger.log(new RecordingEvent(event, uid, session, source, packName) + .printLog(TAG)); return; } String clientEffectName = clientEffects.length == 0 ? "None" : clientEffects[0].name; diff --git a/services/core/java/com/android/server/biometrics/EnrollClient.java b/services/core/java/com/android/server/biometrics/EnrollClient.java index d5e626a8b9fe..e656d9809582 100644 --- a/services/core/java/com/android/server/biometrics/EnrollClient.java +++ b/services/core/java/com/android/server/biometrics/EnrollClient.java @@ -36,6 +36,7 @@ public abstract class EnrollClient extends ClientMonitor { private final byte[] mCryptoToken; private final BiometricUtils mBiometricUtils; private final int[] mDisabledFeatures; + private long mEnrollmentStartTimeMs; public abstract boolean shouldVibrate(); @@ -61,6 +62,9 @@ public abstract class EnrollClient extends ClientMonitor { int remaining) { if (remaining == 0) { mBiometricUtils.addBiometricForUser(getContext(), getTargetUserId(), identifier); + logOnEnrolled(getTargetUserId(), + System.currentTimeMillis() - mEnrollmentStartTimeMs, + true /* enrollSuccessful */); } notifyUserActivity(); return sendEnrollResult(identifier, remaining); @@ -89,6 +93,7 @@ public abstract class EnrollClient extends ClientMonitor { @Override public int start() { + mEnrollmentStartTimeMs = System.currentTimeMillis(); final int timeout = (int) (ENROLLMENT_TIMEOUT_MS / MS_PER_SEC); try { final ArrayList<Integer> disabledFeatures = new ArrayList<>(); @@ -127,10 +132,6 @@ public abstract class EnrollClient extends ClientMonitor { } catch (RemoteException e) { Slog.e(getLogTag(), "stopEnrollment failed", e); } - if (initiatedByClient) { - onError(getHalDeviceId(), BiometricConstants.BIOMETRIC_ERROR_CANCELED, - 0 /* vendorCode */); - } mAlreadyCancelled = true; return 0; } @@ -155,4 +156,17 @@ public abstract class EnrollClient extends ClientMonitor { return true; // Invalid for EnrollClient } + /** + * Called when we get notification from the biometric's HAL that an error has occurred with the + * current operation. Common to authenticate, enroll, enumerate and remove. + * @param error + * @return true if client should be removed + */ + @Override + public boolean onError(long deviceId, int error, int vendorCode) { + logOnEnrolled(getTargetUserId(), System.currentTimeMillis() - mEnrollmentStartTimeMs, + false /* enrollSuccessful */); + return super.onError(deviceId, error, vendorCode); + } + } diff --git a/services/core/java/com/android/server/biometrics/LoggableMonitor.java b/services/core/java/com/android/server/biometrics/LoggableMonitor.java index 3b75b95fb0b9..b0577cd79ac4 100644 --- a/services/core/java/com/android/server/biometrics/LoggableMonitor.java +++ b/services/core/java/com/android/server/biometrics/LoggableMonitor.java @@ -150,4 +150,23 @@ public abstract class LoggableMonitor { authState, latency); } + + protected final void logOnEnrolled(int targetUserId, long latency, boolean enrollSuccessful) { + if (DEBUG) { + Slog.v(TAG, "Enrolled! Modality: " + statsModality() + + ", User: " + targetUserId + + ", Client: " + statsClient() + + ", Latency: " + latency + + ", Success: " + enrollSuccessful); + } else { + Slog.v(TAG, "Enroll latency: " + latency); + } + + StatsLog.write(StatsLog.BIOMETRIC_ENROLLED, + statsModality(), + targetUserId, + latency, + enrollSuccessful); + } + } diff --git a/services/core/java/com/android/server/biometrics/face/FaceService.java b/services/core/java/com/android/server/biometrics/face/FaceService.java index c385991e1c7b..fe762c06458a 100644 --- a/services/core/java/com/android/server/biometrics/face/FaceService.java +++ b/services/core/java/com/android/server/biometrics/face/FaceService.java @@ -39,12 +39,16 @@ import android.hardware.face.FaceManager; import android.hardware.face.IFaceService; import android.hardware.face.IFaceServiceReceiver; import android.os.Binder; +import android.os.Build; import android.os.Environment; import android.os.IBinder; import android.os.RemoteException; import android.os.SELinux; import android.os.UserHandle; import android.os.UserManager; +import android.service.restricted_image.RestrictedImagesDumpProto; +import android.service.restricted_image.RestrictedImageProto; +import android.service.restricted_image.RestrictedImageSetProto; import android.util.Slog; import android.util.proto.ProtoOutputStream; @@ -281,7 +285,9 @@ public class FaceService extends BiometricServiceBase { final long ident = Binder.clearCallingIdentity(); try { - if (args.length > 0 && "--proto".equals(args[0])) { + if (args.length == 1 && "--restricted_image".equals(args[0])) { + dumpRestrictedImage(fd); + } else if (args.length > 0 && "--proto".equals(args[0])) { dumpProto(fd); } else { dumpInternal(pw); @@ -1063,4 +1069,74 @@ public class FaceService extends BiometricServiceBase { mPerformanceMap.clear(); mCryptoPerformanceMap.clear(); } + + private void dumpRestrictedImage(FileDescriptor fd) { + // WARNING: CDD restricts image data from leaving TEE unencrypted on + // production devices: + // [C-1-10] MUST not allow unencrypted access to identifiable biometric + // data or any data derived from it (such as embeddings) to the + // Application Processor outside the context of the TEE. + // As such, this API should only be enabled for testing purposes on + // engineering and userdebug builds. All modules in the software stack + // MUST enforce final build products do NOT have this functionality. + // Additionally, the following check MUST NOT be removed. + if (!(Build.IS_ENG || Build.IS_USERDEBUG)) { + return; + } + + final ProtoOutputStream proto = new ProtoOutputStream(fd); + + final long setToken = proto.start(RestrictedImagesDumpProto.SETS); + + // Name of the service + proto.write(RestrictedImageSetProto.CATEGORY, "face"); + + // Individual images + for (int i = 0; i < 5; i++) { + final long imageToken = proto.start(RestrictedImageSetProto.IMAGES); + proto.write(RestrictedImageProto.MIME_TYPE, "image/png"); + proto.write(RestrictedImageProto.IMAGE_DATA, new byte[] { + // png image data + -119, 80, 78, 71, 13, 10, 26, 10, + 0, 0, 0, 13, 73, 72, 68, 82, + 0, 0, 0, 100, 0, 0, 0, 100, + 1, 3, 0, 0, 0, 74, 44, 7, + 23, 0, 0, 0, 4, 103, 65, 77, + 65, 0, 0, -79, -113, 11, -4, 97, + 5, 0, 0, 0, 1, 115, 82, 71, + 66, 0, -82, -50, 28, -23, 0, 0, + 0, 6, 80, 76, 84, 69, -1, -1, + -1, 0, 0, 0, 85, -62, -45, 126, + 0, 0, 0, -115, 73, 68, 65, 84, + 56, -53, -19, -46, -79, 17, -128, 32, + 12, 5, -48, 120, 22, -106, -116, -32, + 40, -84, 101, -121, -93, 57, 10, 35, + 88, 82, 112, 126, 3, -60, 104, 6, + -112, 70, 127, -59, -69, -53, 29, 33, + -127, -24, 79, -49, -52, -15, 41, 36, + 34, -105, 85, 124, -14, 88, 27, 6, + 28, 68, 1, 82, 62, 22, -95, -108, + 55, -95, 40, -9, -110, -12, 98, -107, + 76, -41, -105, -62, -50, 111, -60, 46, + -14, -4, 24, -89, 42, -103, 16, 63, + -72, -11, -15, 48, -62, 102, -44, 102, + -73, -56, 56, -21, -128, 92, -70, -124, + 117, -46, -67, -77, 82, 80, 121, -44, + -56, 116, 93, -45, -90, -5, -29, -24, + -83, -75, 52, -34, 55, -22, 102, -21, + -105, -124, -23, 71, 87, -7, -25, -59, + -100, -73, -92, -122, -7, -109, -49, -80, + -89, 0, 0, 0, 0, 73, 69, 78, + 68, -82, 66, 96, -126 + }); + // proto.write(RestrictedImageProto.METADATA, flattened_protobuf); + proto.end(imageToken); + } + + // Face service metadata + // proto.write(RestrictedImageSetProto.METADATA, flattened_protobuf); + + proto.end(setToken); + proto.flush(); + } } 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/DnsManager.java b/services/core/java/com/android/server/connectivity/DnsManager.java index d8bb635f2ce8..1913635f80e2 100644 --- a/services/core/java/com/android/server/connectivity/DnsManager.java +++ b/services/core/java/com/android/server/connectivity/DnsManager.java @@ -30,13 +30,15 @@ import static android.provider.Settings.Global.PRIVATE_DNS_SPECIFIER; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; +import android.net.IDnsResolver; import android.net.LinkProperties; import android.net.Network; import android.net.NetworkUtils; import android.net.Uri; import android.net.shared.PrivateDnsConfig; import android.os.Binder; -import android.os.INetworkManagementService; +import android.os.RemoteException; +import android.os.ServiceSpecificException; import android.os.UserHandle; import android.provider.Settings; import android.text.TextUtils; @@ -229,7 +231,7 @@ public class DnsManager { private final Context mContext; private final ContentResolver mContentResolver; - private final INetworkManagementService mNMS; + private final IDnsResolver mDnsResolver; private final MockableSystemProperties mSystemProperties; // TODO: Replace these Maps with SparseArrays. private final Map<Integer, PrivateDnsConfig> mPrivateDnsMap; @@ -243,10 +245,10 @@ public class DnsManager { private String mPrivateDnsMode; private String mPrivateDnsSpecifier; - public DnsManager(Context ctx, INetworkManagementService nms, MockableSystemProperties sp) { + public DnsManager(Context ctx, IDnsResolver dnsResolver, MockableSystemProperties sp) { mContext = ctx; mContentResolver = mContext.getContentResolver(); - mNMS = nms; + mDnsResolver = dnsResolver; mSystemProperties = sp; mPrivateDnsMap = new HashMap<>(); mPrivateDnsValidationMap = new HashMap<>(); @@ -260,6 +262,12 @@ public class DnsManager { } public void removeNetwork(Network network) { + try { + mDnsResolver.clearResolverConfiguration(network.netId); + } catch (RemoteException | ServiceSpecificException e) { + Slog.e(TAG, "Error clearing DNS configuration: " + e); + return; + } mPrivateDnsMap.remove(network.netId); mPrivateDnsValidationMap.remove(network.netId); } @@ -344,10 +352,12 @@ public class DnsManager { Slog.d(TAG, String.format("setDnsConfigurationForNetwork(%d, %s, %s, %s, %s, %s)", netId, Arrays.toString(assignedServers), Arrays.toString(domainStrs), Arrays.toString(params), tlsHostname, Arrays.toString(tlsServers))); + final String[] tlsFingerprints = new String[0]; try { - mNMS.setDnsConfigurationForNetwork( - netId, assignedServers, domainStrs, params, tlsHostname, tlsServers); - } catch (Exception e) { + mDnsResolver.setResolverConfiguration( + netId, assignedServers, domainStrs, params, + tlsHostname, tlsServers, tlsFingerprints); + } catch (RemoteException | ServiceSpecificException e) { Slog.e(TAG, "Error setting DNS configuration: " + e); return; } diff --git a/services/core/java/com/android/server/connectivity/KeepaliveTracker.java b/services/core/java/com/android/server/connectivity/KeepaliveTracker.java index d7a57b992eef..35f7ea3ae0fe 100644 --- a/services/core/java/com/android/server/connectivity/KeepaliveTracker.java +++ b/services/core/java/com/android/server/connectivity/KeepaliveTracker.java @@ -132,6 +132,7 @@ public class KeepaliveTracker { private static final int NOT_STARTED = 1; private static final int STARTING = 2; private static final int STARTED = 3; + private static final int STOPPING = 4; private int mStartedState = NOT_STARTED; KeepaliveInfo(@NonNull ISocketKeepaliveCallback callback, @@ -314,6 +315,7 @@ public class KeepaliveTracker { } } if (NOT_STARTED != mStartedState) { + mStartedState = STOPPING; Log.d(TAG, "Stopping keepalive " + mSlot + " on " + mNai.name()); if (mType == TYPE_NATT) { mNai.asyncChannel.sendMessage(CMD_STOP_SOCKET_KEEPALIVE, mSlot); @@ -456,8 +458,8 @@ public class KeepaliveTracker { ki = mKeepalives.get(nai).get(slot); } catch(NullPointerException e) {} if (ki == null) { - Log.e(TAG, "Event " + message.what + " for unknown keepalive " + slot + " on " - + nai.name()); + Log.e(TAG, "Event " + message.what + "," + slot + "," + reason + + " for unknown keepalive " + slot + " on " + nai.name()); return; } @@ -476,27 +478,30 @@ public class KeepaliveTracker { // messages in order. // TODO : clarify this code and get rid of mStartedState. Using a StateMachine is an // option. - if (reason == SUCCESS && KeepaliveInfo.STARTING == ki.mStartedState) { - // Keepalive successfully started. - if (DBG) Log.d(TAG, "Started keepalive " + slot + " on " + nai.name()); - ki.mStartedState = KeepaliveInfo.STARTED; - try { - ki.mCallback.onStarted(slot); - } catch (RemoteException e) { - Log.w(TAG, "Discarded onStarted(" + slot + ") callback"); - } - } else { - // Keepalive successfully stopped, or error. - if (reason == SUCCESS) { - // The message indicated success stopping : don't call handleStopKeepalive. - if (DBG) Log.d(TAG, "Successfully stopped keepalive " + slot + " on " + nai.name()); + if (KeepaliveInfo.STARTING == ki.mStartedState) { + if (SUCCESS == reason) { + // Keepalive successfully started. + if (DBG) Log.d(TAG, "Started keepalive " + slot + " on " + nai.name()); + ki.mStartedState = KeepaliveInfo.STARTED; + try { + ki.mCallback.onStarted(slot); + } catch (RemoteException e) { + Log.w(TAG, "Discarded onStarted(" + slot + ") callback"); + } } else { - // The message indicated some error trying to start or during the course of - // keepalive : do call handleStopKeepalive. + Log.d(TAG, "Failed to start keepalive " + slot + " on " + nai.name() + + ": " + reason); + // The message indicated some error trying to start: do call handleStopKeepalive. handleStopKeepalive(nai, slot, reason); - if (DBG) Log.d(TAG, "Keepalive " + slot + " on " + nai.name() + " error " + reason); } + } else if (KeepaliveInfo.STOPPING == ki.mStartedState) { + // The message indicated result of stopping : don't call handleStopKeepalive. + Log.d(TAG, "Stopped keepalive " + slot + " on " + nai.name() + + " stopped: " + reason); ki.mStartedState = KeepaliveInfo.NOT_STARTED; + } else { + Log.wtf(TAG, "Event " + message.what + "," + slot + "," + reason + + " for keepalive in wrong state: " + ki.toString()); } } diff --git a/services/core/java/com/android/server/connectivity/Nat464Xlat.java b/services/core/java/com/android/server/connectivity/Nat464Xlat.java index 262ba7a475bb..66bd27c1a76b 100644 --- a/services/core/java/com/android/server/connectivity/Nat464Xlat.java +++ b/services/core/java/com/android/server/connectivity/Nat464Xlat.java @@ -17,6 +17,7 @@ package com.android.server.connectivity; import android.net.ConnectivityManager; +import android.net.IDnsResolver; import android.net.INetd; import android.net.InetAddresses; import android.net.InterfaceConfiguration; @@ -65,6 +66,7 @@ public class Nat464Xlat extends BaseNetworkObserver { NetworkInfo.State.SUSPENDED, }; + private final IDnsResolver mDnsResolver; private final INetd mNetd; private final INetworkManagementService mNMService; @@ -84,7 +86,9 @@ public class Nat464Xlat extends BaseNetworkObserver { private Inet6Address mIPv6Address; private State mState = State.IDLE; - public Nat464Xlat(NetworkAgentInfo nai, INetd netd, INetworkManagementService nmService) { + public Nat464Xlat(NetworkAgentInfo nai, INetd netd, IDnsResolver dnsResolver, + INetworkManagementService nmService) { + mDnsResolver = dnsResolver; mNetd = netd; mNMService = nmService; mNetwork = nai; @@ -269,7 +273,7 @@ public class Nat464Xlat extends BaseNetworkObserver { private void startPrefixDiscovery() { try { - mNetd.resolverStartPrefix64Discovery(getNetId()); + mDnsResolver.startPrefix64Discovery(getNetId()); mState = State.DISCOVERING; } catch (RemoteException | ServiceSpecificException e) { Slog.e(TAG, "Error starting prefix discovery on netId " + getNetId() + ": " + e); @@ -278,7 +282,7 @@ public class Nat464Xlat extends BaseNetworkObserver { private void stopPrefixDiscovery() { try { - mNetd.resolverStopPrefix64Discovery(getNetId()); + mDnsResolver.stopPrefix64Discovery(getNetId()); } catch (RemoteException | ServiceSpecificException e) { Slog.e(TAG, "Error stopping prefix discovery on netId " + getNetId() + ": " + e); } diff --git a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java index 8f2825ca72d8..cfa91314f490 100644 --- a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java +++ b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java @@ -17,6 +17,7 @@ package com.android.server.connectivity; import android.content.Context; +import android.net.IDnsResolver; import android.net.INetd; import android.net.INetworkMonitor; import android.net.LinkProperties; @@ -29,6 +30,7 @@ import android.net.NetworkState; import android.os.Handler; import android.os.INetworkManagementService; import android.os.Messenger; +import android.os.RemoteException; import android.os.SystemClock; import android.util.Log; import android.util.SparseArray; @@ -120,7 +122,8 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> { // This Network object is always valid. public final Network network; public LinkProperties linkProperties; - // This should only be modified via ConnectivityService.updateCapabilities(). + // This should only be modified by ConnectivityService, via setNetworkCapabilities(). + // TODO: make this private with a getter. public NetworkCapabilities networkCapabilities; public final NetworkMisc networkMisc; // Indicates if netd has been told to create this Network. From this point on the appropriate @@ -255,7 +258,7 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> { public NetworkAgentInfo(Messenger messenger, AsyncChannel ac, Network net, NetworkInfo info, LinkProperties lp, NetworkCapabilities nc, int score, Context context, Handler handler, NetworkMisc misc, ConnectivityService connService, INetd netd, - INetworkManagementService nms, int factorySerialNumber) { + IDnsResolver dnsResolver, INetworkManagementService nms, int factorySerialNumber) { this.messenger = messenger; asyncChannel = ac; network = net; @@ -263,7 +266,7 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> { linkProperties = lp; networkCapabilities = nc; currentScore = score; - clatd = new Nat464Xlat(this, netd, nms); + clatd = new Nat464Xlat(this, netd, dnsResolver, nms); mConnService = connService; mContext = context; mHandler = handler; @@ -278,6 +281,25 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> { mNetworkMonitor = networkMonitor; } + /** + * Set the NetworkCapabilities on this NetworkAgentInfo. Also attempts to notify NetworkMonitor + * of the new capabilities, if NetworkMonitor has been created. + * + * <p>If {@link NetworkMonitor#notifyNetworkCapabilitiesChanged(NetworkCapabilities)} fails, + * the exception is logged but not reported to callers. + */ + public void setNetworkCapabilities(NetworkCapabilities nc) { + networkCapabilities = nc; + final INetworkMonitor nm = mNetworkMonitor; + if (nm != null) { + try { + nm.notifyNetworkCapabilitiesChanged(nc); + } catch (RemoteException e) { + Log.e(TAG, "Error notifying NetworkMonitor of updated NetworkCapabilities", e); + } + } + } + public ConnectivityService connService() { return mConnService; } diff --git a/services/core/java/com/android/server/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java index 37fe3d094179..b140c1b25320 100644 --- a/services/core/java/com/android/server/connectivity/Tethering.java +++ b/services/core/java/com/android/server/connectivity/Tethering.java @@ -82,7 +82,6 @@ import android.os.Handler; import android.os.INetworkManagementService; import android.os.Looper; import android.os.Message; -import android.os.Parcel; import android.os.RemoteCallbackList; import android.os.RemoteException; import android.os.ResultReceiver; @@ -230,8 +229,15 @@ public class Tethering extends BaseNetworkObserver { IntentFilter filter = new IntentFilter(); filter.addAction(ACTION_CARRIER_CONFIG_CHANGED); - mEntitlementMgr = mDeps.getEntitlementManager(mContext, mTetherMasterSM, - mLog, systemProperties); + // EntitlementManager will send EVENT_UPSTREAM_PERMISSION_CHANGED when cellular upstream + // permission is changed according to entitlement check result. + mEntitlementMgr = mDeps.getEntitlementManager(mContext, mTetherMasterSM, mLog, + TetherMasterSM.EVENT_UPSTREAM_PERMISSION_CHANGED, systemProperties); + mEntitlementMgr.setOnUiEntitlementFailedListener((int downstream) -> { + mLog.log("OBSERVED UiEnitlementFailed"); + stopTethering(downstream); + }); + mCarrierConfigChange = new VersionedBroadcastListener( "CarrierConfigChangeListener", mContext, mHandler, filter, (Intent ignored) -> { @@ -363,55 +369,28 @@ public class Tethering extends BaseNetworkObserver { } public void startTethering(int type, ResultReceiver receiver, boolean showProvisioningUi) { - mEntitlementMgr.startTethering(type); - if (!mEntitlementMgr.isTetherProvisioningRequired()) { - enableTetheringInternal(type, true, receiver); - return; - } - - final ResultReceiver proxyReceiver = getProxyReceiver(type, receiver); - if (showProvisioningUi) { - mEntitlementMgr.runUiTetherProvisioningAndEnable(type, proxyReceiver); - } else { - mEntitlementMgr.runSilentTetherProvisioningAndEnable(type, proxyReceiver); - } + mEntitlementMgr.startProvisioningIfNeeded(type, showProvisioningUi); + enableTetheringInternal(type, true /* enabled */, receiver); } public void stopTethering(int type) { - enableTetheringInternal(type, false, null); - mEntitlementMgr.stopTethering(type); - if (mEntitlementMgr.isTetherProvisioningRequired()) { - // There are lurking bugs where the notion of "provisioning required" or - // "tethering supported" may change without notifying tethering properly, then - // tethering can't shutdown correctly. - // TODO: cancel re-check all the time - if (mDeps.isTetheringSupported()) { - mEntitlementMgr.cancelTetherProvisioningRechecks(type); - } - } + enableTetheringInternal(type, false /* disabled */, null); + mEntitlementMgr.stopProvisioningIfNeeded(type); } /** - * Enables or disables tethering for the given type. This should only be called once - * provisioning has succeeded or is not necessary. It will also schedule provisioning rechecks - * for the specified interface. + * Enables or disables tethering for the given type. If provisioning is required, it will + * schedule provisioning rechecks for the specified interface. */ private void enableTetheringInternal(int type, boolean enable, ResultReceiver receiver) { - boolean isProvisioningRequired = enable && mEntitlementMgr.isTetherProvisioningRequired(); int result; switch (type) { case TETHERING_WIFI: result = setWifiTethering(enable); - if (isProvisioningRequired && result == TETHER_ERROR_NO_ERROR) { - mEntitlementMgr.scheduleProvisioningRechecks(type); - } sendTetherResult(receiver, result); break; case TETHERING_USB: result = setUsbTethering(enable); - if (isProvisioningRequired && result == TETHER_ERROR_NO_ERROR) { - mEntitlementMgr.scheduleProvisioningRechecks(type); - } sendTetherResult(receiver, result); break; case TETHERING_BLUETOOTH: @@ -430,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) { @@ -469,46 +452,11 @@ public class Tethering extends BaseNetworkObserver { ? TETHER_ERROR_NO_ERROR : TETHER_ERROR_MASTER_ERROR; sendTetherResult(receiver, result); - if (enable && mEntitlementMgr.isTetherProvisioningRequired()) { - mEntitlementMgr.scheduleProvisioningRechecks(TETHERING_BLUETOOTH); - } adapter.closeProfileProxy(BluetoothProfile.PAN, proxy); } }, BluetoothProfile.PAN); } - /** - * Creates a proxy {@link ResultReceiver} which enables tethering if the provisioning result - * is successful before firing back up to the wrapped receiver. - * - * @param type The type of tethering being enabled. - * @param receiver A ResultReceiver which will be called back with an int resultCode. - * @return The proxy receiver. - */ - private ResultReceiver getProxyReceiver(final int type, final ResultReceiver receiver) { - ResultReceiver rr = new ResultReceiver(null) { - @Override - protected void onReceiveResult(int resultCode, Bundle resultData) { - // If provisioning is successful, enable tethering, otherwise just send the error. - if (resultCode == TETHER_ERROR_NO_ERROR) { - enableTetheringInternal(type, true, receiver); - } else { - sendTetherResult(receiver, resultCode); - } - mEntitlementMgr.updateEntitlementCacheValue(type, resultCode); - } - }; - - // The following is necessary to avoid unmarshalling issues when sending the receiver - // across processes. - Parcel parcel = Parcel.obtain(); - rr.writeToParcel(parcel,0); - parcel.setDataPosition(0); - ResultReceiver receiverForSending = ResultReceiver.CREATOR.createFromParcel(parcel); - parcel.recycle(); - return receiverForSending; - } - public int tether(String iface) { return tether(iface, IpServer.STATE_TETHERED); } @@ -787,6 +735,7 @@ public class Tethering extends BaseNetworkObserver { if (!usbConnected && mRndisEnabled) { // Turn off tethering if it was enabled and there is a disconnect. tetherMatchingInterfaces(IpServer.STATE_AVAILABLE, TETHERING_USB); + mEntitlementMgr.stopProvisioningIfNeeded(TETHERING_USB); } else if (usbConfigured && rndisEnabled) { // Tether if rndis is enabled and usb is configured. tetherMatchingInterfaces(IpServer.STATE_TETHERED, TETHERING_USB); @@ -813,6 +762,7 @@ public class Tethering extends BaseNetworkObserver { case WifiManager.WIFI_AP_STATE_FAILED: default: disableWifiIpServingLocked(ifname, curState); + mEntitlementMgr.stopProvisioningIfNeeded(TETHERING_WIFI); break; } } @@ -996,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); @@ -1090,6 +1045,8 @@ public class Tethering extends BaseNetworkObserver { // we treated the error and want now to clear it static final int CMD_CLEAR_ERROR = BASE_MASTER + 6; static final int EVENT_IFACE_UPDATE_LINKPROPERTIES = BASE_MASTER + 7; + // Events from EntitlementManager to choose upstream again. + static final int EVENT_UPSTREAM_PERMISSION_CHANGED = BASE_MASTER + 8; private final State mInitialState; private final State mTetherModeAliveState; @@ -1504,6 +1461,7 @@ public class Tethering extends BaseNetworkObserver { } break; } + case EVENT_UPSTREAM_PERMISSION_CHANGED: case CMD_UPSTREAM_CHANGED: updateUpstreamWanted(); if (!mUpstreamWanted) break; @@ -1694,7 +1652,8 @@ public class Tethering extends BaseNetworkObserver { } public void systemReady() { - mUpstreamNetworkMonitor.startTrackDefaultNetwork(mDeps.getDefaultNetworkRequest()); + mUpstreamNetworkMonitor.startTrackDefaultNetwork(mDeps.getDefaultNetworkRequest(), + mEntitlementMgr); } /** Get the latest value of the tethering entitlement check. */ @@ -1755,6 +1714,11 @@ public class Tethering extends BaseNetworkObserver { cfg.dump(pw); pw.decreaseIndent(); + pw.println("Entitlement:"); + pw.increaseIndent(); + mEntitlementMgr.dump(pw); + pw.decreaseIndent(); + synchronized (mPublicSync) { pw.println("Tether state:"); pw.increaseIndent(); diff --git a/services/core/java/com/android/server/connectivity/tethering/EntitlementManager.java b/services/core/java/com/android/server/connectivity/tethering/EntitlementManager.java index 70ab38983446..764a6ebc2d98 100644 --- a/services/core/java/com/android/server/connectivity/tethering/EntitlementManager.java +++ b/services/core/java/com/android/server/connectivity/tethering/EntitlementManager.java @@ -18,9 +18,11 @@ package com.android.server.connectivity.tethering; import static android.net.ConnectivityManager.EXTRA_ADD_TETHER_TYPE; import static android.net.ConnectivityManager.EXTRA_PROVISION_CALLBACK; -import static android.net.ConnectivityManager.EXTRA_REM_TETHER_TYPE; import static android.net.ConnectivityManager.EXTRA_RUN_PROVISION; -import static android.net.ConnectivityManager.EXTRA_SET_ALARM; +import static android.net.ConnectivityManager.TETHERING_BLUETOOTH; +import static android.net.ConnectivityManager.TETHERING_INVALID; +import static android.net.ConnectivityManager.TETHERING_USB; +import static android.net.ConnectivityManager.TETHERING_WIFI; import static android.net.ConnectivityManager.TETHER_ERROR_ENTITLEMENT_UNKONWN; import static android.net.ConnectivityManager.TETHER_ERROR_NO_ERROR; import static android.net.ConnectivityManager.TETHER_ERROR_PROVISION_FAILED; @@ -28,17 +30,24 @@ import static android.net.ConnectivityManager.TETHER_ERROR_PROVISION_FAILED; import static com.android.internal.R.string.config_wifi_tether_enable; import android.annotation.Nullable; +import android.app.AlarmManager; +import android.app.PendingIntent; +import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; import android.content.Intent; +import android.content.IntentFilter; import android.content.res.Resources; import android.net.util.SharedLog; import android.os.Binder; import android.os.Bundle; import android.os.Handler; +import android.os.Looper; +import android.os.Message; import android.os.Parcel; import android.os.PersistableBundle; import android.os.ResultReceiver; +import android.os.SystemClock; import android.os.UserHandle; import android.provider.Settings; import android.telephony.CarrierConfigManager; @@ -46,48 +55,93 @@ import android.util.ArraySet; import android.util.Log; import android.util.SparseIntArray; -import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.StateMachine; import com.android.server.connectivity.MockableSystemProperties; +import java.io.PrintWriter; + /** - * This class encapsulates entitlement/provisioning mechanics - * provisioning check only applies to the use of the mobile network as an upstream + * Re-check tethering provisioning for enabled downstream tether types. + * Reference ConnectivityManager.TETHERING_{@code *} for each tether type. * + * All methods of this class must be accessed from the thread of tethering + * state machine. * @hide */ public class EntitlementManager { private static final String TAG = EntitlementManager.class.getSimpleName(); private static final boolean DBG = false; + @VisibleForTesting + protected static final String DISABLE_PROVISIONING_SYSPROP_KEY = "net.tethering.noprovisioning"; + private static final String ACTION_PROVISIONING_ALARM = + "com.android.server.connectivity.tethering.PROVISIONING_RECHECK_ALARM"; + // {@link ComponentName} of the Service used to run tether provisioning. private static final ComponentName TETHER_SERVICE = ComponentName.unflattenFromString( Resources.getSystem().getString(config_wifi_tether_enable)); - protected static final String DISABLE_PROVISIONING_SYSPROP_KEY = "net.tethering.noprovisioning"; + private static final int MS_PER_HOUR = 60 * 60 * 1000; + private static final int EVENT_START_PROVISIONING = 0; + private static final int EVENT_STOP_PROVISIONING = 1; + private static final int EVENT_UPSTREAM_CHANGED = 2; + private static final int EVENT_MAYBE_RUN_PROVISIONING = 3; + private static final int EVENT_GET_ENTITLEMENT_VALUE = 4; + // The ArraySet contains enabled downstream types, ex: // {@link ConnectivityManager.TETHERING_WIFI} // {@link ConnectivityManager.TETHERING_USB} // {@link ConnectivityManager.TETHERING_BLUETOOTH} - @GuardedBy("mCurrentTethers") private final ArraySet<Integer> mCurrentTethers; private final Context mContext; + private final int mPermissionChangeMessageCode; private final MockableSystemProperties mSystemProperties; private final SharedLog mLog; - private final Handler mMasterHandler; private final SparseIntArray mEntitlementCacheValue; - @Nullable - private TetheringConfiguration mConfig; + private final EntitlementHandler mHandler; + private @Nullable TetheringConfiguration mConfig; + private final StateMachine mTetherMasterSM; + // Key: ConnectivityManager.TETHERING_*(downstream). + // Value: ConnectivityManager.TETHER_ERROR_{NO_ERROR or PROVISION_FAILED}(provisioning result). + private final SparseIntArray mCellularPermitted; + private PendingIntent mProvisioningRecheckAlarm; + private boolean mCellularUpstreamPermitted = true; + private boolean mUsingCellularAsUpstream = false; + private boolean mNeedReRunProvisioningUi = false; + private OnUiEntitlementFailedListener mListener; public EntitlementManager(Context ctx, StateMachine tetherMasterSM, SharedLog log, - MockableSystemProperties systemProperties) { + int permissionChangeMessageCode, MockableSystemProperties systemProperties) { + mContext = ctx; mLog = log.forSubComponent(TAG); mCurrentTethers = new ArraySet<Integer>(); + mCellularPermitted = new SparseIntArray(); mSystemProperties = systemProperties; mEntitlementCacheValue = new SparseIntArray(); - mMasterHandler = tetherMasterSM.getHandler(); + mTetherMasterSM = tetherMasterSM; + mPermissionChangeMessageCode = permissionChangeMessageCode; + final Handler masterHandler = tetherMasterSM.getHandler(); + // Create entitlement's own handler which is associated with TetherMaster thread + // let all entitlement processes run in the same thread. + mHandler = new EntitlementHandler(masterHandler.getLooper()); + mContext.registerReceiver(mReceiver, new IntentFilter(ACTION_PROVISIONING_ALARM), + null, mHandler); + } + + public void setOnUiEntitlementFailedListener(final OnUiEntitlementFailedListener listener) { + mListener = listener; + } + + /** Callback fired when UI entitlement failed. */ + public interface OnUiEntitlementFailedListener { + /** + * Ui entitlement check fails in |downstream|. + * + * @param downstream tethering type from ConnectivityManager.TETHERING_{@code *}. + */ + void onUiEntitlementFailed(int downstream); } /** @@ -99,24 +153,118 @@ public class EntitlementManager { } /** - * Tell EntitlementManager that a given type of tethering has been enabled + * Check if cellular upstream is permitted. + */ + public boolean isCellularUpstreamPermitted() { + return mCellularUpstreamPermitted; + } + + /** + * This is called when tethering starts. + * Launch provisioning app if upstream is cellular. * - * @param type Tethering type + * @param downstreamType tethering type from ConnectivityManager.TETHERING_{@code *} + * @param showProvisioningUi a boolean indicating whether to show the + * provisioning app UI if there is one. */ - public void startTethering(int type) { - synchronized (mCurrentTethers) { - mCurrentTethers.add(type); + public void startProvisioningIfNeeded(int downstreamType, boolean showProvisioningUi) { + mHandler.sendMessage(mHandler.obtainMessage(EVENT_START_PROVISIONING, + downstreamType, encodeBool(showProvisioningUi))); + } + + private void handleStartProvisioningIfNeeded(int type, boolean showProvisioningUi) { + if (!isValidDownstreamType(type)) return; + + if (!mCurrentTethers.contains(type)) mCurrentTethers.add(type); + + if (isTetherProvisioningRequired()) { + // If provisioning is required and the result is not available yet, + // cellular upstream should not be allowed. + if (mCellularPermitted.size() == 0) { + mCellularUpstreamPermitted = false; + } + // If upstream is not cellular, provisioning app would not be launched + // till upstream change to cellular. + if (mUsingCellularAsUpstream) { + if (showProvisioningUi) { + runUiTetherProvisioning(type); + } else { + runSilentTetherProvisioning(type); + } + mNeedReRunProvisioningUi = false; + } else { + mNeedReRunProvisioningUi |= showProvisioningUi; + } + } else { + mCellularUpstreamPermitted = true; } } /** * Tell EntitlementManager that a given type of tethering has been disabled * - * @param type Tethering type + * @param type tethering type from ConnectivityManager.TETHERING_{@code *} */ - public void stopTethering(int type) { - synchronized (mCurrentTethers) { - mCurrentTethers.remove(type); + public void stopProvisioningIfNeeded(int type) { + mHandler.sendMessage(mHandler.obtainMessage(EVENT_STOP_PROVISIONING, type, 0)); + } + + private void handleStopProvisioningIfNeeded(int type) { + if (!isValidDownstreamType(type)) return; + + mCurrentTethers.remove(type); + // There are lurking bugs where the notion of "provisioning required" or + // "tethering supported" may change without without tethering being notified properly. + // Remove the mapping all the time no matter provisioning is required or not. + removeDownstreamMapping(type); + } + + /** + * Notify EntitlementManager if upstream is cellular or not. + * + * @param isCellular whether tethering upstream is cellular. + */ + public void notifyUpstream(boolean isCellular) { + mHandler.sendMessage(mHandler.obtainMessage( + EVENT_UPSTREAM_CHANGED, encodeBool(isCellular), 0)); + } + + private void handleNotifyUpstream(boolean isCellular) { + if (DBG) { + Log.d(TAG, "notifyUpstream: " + isCellular + + ", mCellularUpstreamPermitted: " + mCellularUpstreamPermitted + + ", mNeedReRunProvisioningUi: " + mNeedReRunProvisioningUi); + } + mUsingCellularAsUpstream = isCellular; + + if (mUsingCellularAsUpstream) { + handleMaybeRunProvisioning(); + } + } + + /** Run provisioning if needed */ + public void maybeRunProvisioning() { + mHandler.sendMessage(mHandler.obtainMessage(EVENT_MAYBE_RUN_PROVISIONING)); + } + + private void handleMaybeRunProvisioning() { + if (mCurrentTethers.size() == 0 || !isTetherProvisioningRequired()) { + return; + } + + // Whenever any entitlement value changes, all downstreams will re-evaluate whether they + // are allowed. Therefore even if the silent check here ends in a failure and the UI later + // yields success, then the downstream that got a failure will re-evaluate as a result of + // the change and get the new correct value. + for (Integer downstream : mCurrentTethers) { + if (mCellularPermitted.indexOfKey(downstream) < 0) { + if (mNeedReRunProvisioningUi) { + mNeedReRunProvisioningUi = false; + runUiTetherProvisioning(downstream); + } else { + runSilentTetherProvisioning(downstream); + } + } } } @@ -138,23 +286,32 @@ public class EntitlementManager { } /** - * Re-check tethering provisioning for enabled downstream tether types. + * Re-check tethering provisioning for all enabled tether types. * Reference ConnectivityManager.TETHERING_{@code *} for each tether type. + * + * Note: this method is only called from TetherMaster on the handler thread. + * If there are new callers from different threads, the logic should move to + * masterHandler to avoid race conditions. */ public void reevaluateSimCardProvisioning() { - synchronized (mEntitlementCacheValue) { - mEntitlementCacheValue.clear(); - } + if (DBG) Log.d(TAG, "reevaluateSimCardProvisioning"); - if (!mConfig.hasMobileHotspotProvisionApp()) return; - if (carrierConfigAffirmsEntitlementCheckNotRequired()) return; + if (!mHandler.getLooper().isCurrentThread()) { + // Except for test, this log should not appear in normal flow. + mLog.log("reevaluateSimCardProvisioning() don't run in TetherMaster thread"); + } + mEntitlementCacheValue.clear(); + mCellularPermitted.clear(); - final ArraySet<Integer> reevaluateType; - synchronized (mCurrentTethers) { - reevaluateType = new ArraySet<Integer>(mCurrentTethers); + // TODO: refine provisioning check to isTetherProvisioningRequired() ?? + if (!mConfig.hasMobileHotspotProvisionApp() + || carrierConfigAffirmsEntitlementCheckNotRequired()) { + evaluateCellularPermission(); + return; } - for (Integer type : reevaluateType) { - startProvisionIntent(type); + + if (mUsingCellularAsUpstream) { + handleMaybeRunProvisioning(); } } @@ -189,7 +346,16 @@ public class EntitlementManager { return !isEntitlementCheckRequired; } - public void runSilentTetherProvisioningAndEnable(int type, ResultReceiver receiver) { + /** + * Run no UI tethering provisioning check. + * @param type tethering type from ConnectivityManager.TETHERING_{@code *} + */ + protected void runSilentTetherProvisioning(int type) { + if (DBG) Log.d(TAG, "runSilentTetherProvisioning: " + type); + // For silent provisioning, settings would stop tethering when entitlement fail. + ResultReceiver receiver = buildProxyReceiver(type, + false/* notifyFail */, null); + Intent intent = new Intent(); intent.putExtra(EXTRA_ADD_TETHER_TYPE, type); intent.putExtra(EXTRA_RUN_PROVISION, true); @@ -203,12 +369,21 @@ public class EntitlementManager { } } - public void runUiTetherProvisioningAndEnable(int type, ResultReceiver receiver) { + /** + * Run the UI-enabled tethering provisioning check. + * @param type tethering type from ConnectivityManager.TETHERING_{@code *} + */ + @VisibleForTesting + protected void runUiTetherProvisioning(int type) { + ResultReceiver receiver = buildProxyReceiver(type, + true/* notifyFail */, null); runUiTetherProvisioning(type, receiver); } @VisibleForTesting protected void runUiTetherProvisioning(int type, ResultReceiver receiver) { + if (DBG) Log.d(TAG, "runUiTetherProvisioning: " + type); + Intent intent = new Intent(Settings.ACTION_TETHER_PROVISIONING); intent.putExtra(EXTRA_ADD_TETHER_TYPE, type); intent.putExtra(EXTRA_PROVISION_CALLBACK, receiver); @@ -221,56 +396,210 @@ public class EntitlementManager { } } - // Used by the SIM card change observation code. - // TODO: De-duplicate with above code, where possible. - private void startProvisionIntent(int tetherType) { - final Intent startProvIntent = new Intent(); - startProvIntent.putExtra(EXTRA_ADD_TETHER_TYPE, tetherType); - startProvIntent.putExtra(EXTRA_RUN_PROVISION, true); - startProvIntent.setComponent(TETHER_SERVICE); - mContext.startServiceAsUser(startProvIntent, UserHandle.CURRENT); + // Not needed to check if this don't run on the handler thread because it's private. + private void scheduleProvisioningRechecks() { + if (mProvisioningRecheckAlarm == null) { + final int period = mConfig.provisioningCheckPeriod; + if (period <= 0) return; + + Intent intent = new Intent(ACTION_PROVISIONING_ALARM); + mProvisioningRecheckAlarm = PendingIntent.getBroadcast(mContext, 0, intent, 0); + AlarmManager alarmManager = (AlarmManager) mContext.getSystemService( + Context.ALARM_SERVICE); + long periodMs = period * MS_PER_HOUR; + long firstAlarmTime = SystemClock.elapsedRealtime() + periodMs; + alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME, firstAlarmTime, periodMs, + mProvisioningRecheckAlarm); + } } - public void scheduleProvisioningRechecks(int type) { - Intent intent = new Intent(); - intent.putExtra(EXTRA_ADD_TETHER_TYPE, type); - intent.putExtra(EXTRA_SET_ALARM, true); - intent.setComponent(TETHER_SERVICE); - final long ident = Binder.clearCallingIdentity(); - try { - mContext.startServiceAsUser(intent, UserHandle.CURRENT); - } finally { - Binder.restoreCallingIdentity(ident); + private void cancelTetherProvisioningRechecks() { + if (mProvisioningRecheckAlarm != null) { + AlarmManager alarmManager = (AlarmManager) mContext.getSystemService( + Context.ALARM_SERVICE); + alarmManager.cancel(mProvisioningRecheckAlarm); + mProvisioningRecheckAlarm = null; } } - public void cancelTetherProvisioningRechecks(int type) { - Intent intent = new Intent(); - intent.putExtra(EXTRA_REM_TETHER_TYPE, type); - intent.setComponent(TETHER_SERVICE); - final long ident = Binder.clearCallingIdentity(); - try { - mContext.startServiceAsUser(intent, UserHandle.CURRENT); - } finally { - Binder.restoreCallingIdentity(ident); + private void evaluateCellularPermission() { + final boolean oldPermitted = mCellularUpstreamPermitted; + mCellularUpstreamPermitted = (!isTetherProvisioningRequired() + || mCellularPermitted.indexOfValue(TETHER_ERROR_NO_ERROR) > -1); + + if (DBG) { + Log.d(TAG, "Cellular permission change from " + oldPermitted + + " to " + mCellularUpstreamPermitted); + } + + if (mCellularUpstreamPermitted != oldPermitted) { + mLog.log("Cellular permission change: " + mCellularUpstreamPermitted); + mTetherMasterSM.sendMessage(mPermissionChangeMessageCode); + } + // Only schedule periodic re-check when tether is provisioned + // and the result is ok. + if (mCellularUpstreamPermitted && mCellularPermitted.size() > 0) { + scheduleProvisioningRechecks(); + } else { + cancelTetherProvisioningRechecks(); + } + } + + /** + * Add the mapping between provisioning result and tethering type. + * Notify UpstreamNetworkMonitor if Cellular permission changes. + * + * @param type tethering type from ConnectivityManager.TETHERING_{@code *} + * @param resultCode Provisioning result + */ + protected void addDownstreamMapping(int type, int resultCode) { + if (DBG) { + Log.d(TAG, "addDownstreamMapping: " + type + ", result: " + resultCode + + " ,TetherTypeRequested: " + mCurrentTethers.contains(type)); } + if (!mCurrentTethers.contains(type)) return; + + mCellularPermitted.put(type, resultCode); + evaluateCellularPermission(); } - private ResultReceiver buildProxyReceiver(int type, final ResultReceiver receiver) { - ResultReceiver rr = new ResultReceiver(mMasterHandler) { + /** + * Remove the mapping for input tethering type. + * @param type tethering type from ConnectivityManager.TETHERING_{@code *} + */ + protected void removeDownstreamMapping(int type) { + if (DBG) Log.d(TAG, "removeDownstreamMapping: " + type); + mCellularPermitted.delete(type); + evaluateCellularPermission(); + } + + private final BroadcastReceiver mReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + if (ACTION_PROVISIONING_ALARM.equals(intent.getAction())) { + mLog.log("Received provisioning alarm"); + reevaluateSimCardProvisioning(); + } + } + }; + + private class EntitlementHandler extends Handler { + EntitlementHandler(Looper looper) { + super(looper); + } + + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case EVENT_START_PROVISIONING: + handleStartProvisioningIfNeeded(msg.arg1, toBool(msg.arg2)); + break; + case EVENT_STOP_PROVISIONING: + handleStopProvisioningIfNeeded(msg.arg1); + break; + case EVENT_UPSTREAM_CHANGED: + handleNotifyUpstream(toBool(msg.arg1)); + break; + case EVENT_MAYBE_RUN_PROVISIONING: + handleMaybeRunProvisioning(); + break; + case EVENT_GET_ENTITLEMENT_VALUE: + handleGetLatestTetheringEntitlementValue(msg.arg1, (ResultReceiver) msg.obj, + toBool(msg.arg2)); + break; + default: + mLog.log("Unknown event: " + msg.what); + break; + } + } + } + + private static boolean toBool(int encodedBoolean) { + return encodedBoolean != 0; + } + + private static int encodeBool(boolean b) { + return b ? 1 : 0; + } + + private static boolean isValidDownstreamType(int type) { + switch (type) { + case TETHERING_BLUETOOTH: + case TETHERING_USB: + case TETHERING_WIFI: + return true; + default: + return false; + } + } + + /** + * Dump the infromation of EntitlementManager. + * @param pw {@link PrintWriter} is used to print formatted + */ + public void dump(PrintWriter pw) { + pw.print("mCellularUpstreamPermitted: "); + pw.println(mCellularUpstreamPermitted); + for (Integer type : mCurrentTethers) { + pw.print("Type: "); + pw.print(typeString(type)); + if (mCellularPermitted.indexOfKey(type) > -1) { + pw.print(", Value: "); + pw.println(errorString(mCellularPermitted.get(type))); + } else { + pw.println(", Value: empty"); + } + } + } + + private static String typeString(int type) { + switch (type) { + case TETHERING_BLUETOOTH: return "TETHERING_BLUETOOTH"; + case TETHERING_INVALID: return "TETHERING_INVALID"; + case TETHERING_USB: return "TETHERING_USB"; + case TETHERING_WIFI: return "TETHERING_WIFI"; + default: + return String.format("TETHERING UNKNOWN TYPE (%d)", type); + } + } + + private static String errorString(int value) { + switch (value) { + case TETHER_ERROR_ENTITLEMENT_UNKONWN: return "TETHER_ERROR_ENTITLEMENT_UNKONWN"; + case TETHER_ERROR_NO_ERROR: return "TETHER_ERROR_NO_ERROR"; + case TETHER_ERROR_PROVISION_FAILED: return "TETHER_ERROR_PROVISION_FAILED"; + default: + return String.format("UNKNOWN ERROR (%d)", value); + } + } + + private ResultReceiver buildProxyReceiver(int type, boolean notifyFail, + final ResultReceiver receiver) { + ResultReceiver rr = new ResultReceiver(mHandler) { @Override protected void onReceiveResult(int resultCode, Bundle resultData) { int updatedCacheValue = updateEntitlementCacheValue(type, resultCode); - receiver.send(updatedCacheValue, null); + addDownstreamMapping(type, updatedCacheValue); + if (updatedCacheValue == TETHER_ERROR_PROVISION_FAILED && notifyFail) { + mListener.onUiEntitlementFailed(type); + } + if (receiver != null) receiver.send(updatedCacheValue, null); } }; return writeToParcel(rr); } + // Instances of ResultReceiver need to be public classes for remote processes to be able + // to load them (otherwise, ClassNotFoundException). For private classes, this method + // performs a trick : round-trip parceling any instance of ResultReceiver will return a + // vanilla instance of ResultReceiver sharing the binder token with the original receiver. + // The binder token has a reference to the original instance of the private class and will + // still call its methods, and can be sent over. However it cannot be used for anything + // else than sending over a Binder call. + // While round-trip parceling is not great, there is currently no other way of generating + // a vanilla instance of ResultReceiver because all its fields are private. private ResultReceiver writeToParcel(final ResultReceiver receiver) { - // This is necessary to avoid unmarshalling issues when sending the receiver - // across processes. Parcel parcel = Parcel.obtain(); receiver.writeToParcel(parcel, 0); parcel.setDataPosition(0); @@ -286,38 +615,41 @@ public class EntitlementManager { * @param resultCode last entitlement value * @return the last updated entitlement value */ - public int updateEntitlementCacheValue(int type, int resultCode) { + private int updateEntitlementCacheValue(int type, int resultCode) { if (DBG) { Log.d(TAG, "updateEntitlementCacheValue: " + type + ", result: " + resultCode); } - synchronized (mEntitlementCacheValue) { - if (resultCode == TETHER_ERROR_NO_ERROR) { - mEntitlementCacheValue.put(type, resultCode); - return resultCode; - } else { - mEntitlementCacheValue.put(type, TETHER_ERROR_PROVISION_FAILED); - return TETHER_ERROR_PROVISION_FAILED; - } + if (resultCode == TETHER_ERROR_NO_ERROR) { + mEntitlementCacheValue.put(type, resultCode); + return resultCode; + } else { + mEntitlementCacheValue.put(type, TETHER_ERROR_PROVISION_FAILED); + return TETHER_ERROR_PROVISION_FAILED; } } /** Get the last value of the tethering entitlement check. */ public void getLatestTetheringEntitlementResult(int downstream, ResultReceiver receiver, boolean showEntitlementUi) { + mHandler.sendMessage(mHandler.obtainMessage(EVENT_GET_ENTITLEMENT_VALUE, + downstream, encodeBool(showEntitlementUi), receiver)); + + } + + private void handleGetLatestTetheringEntitlementValue(int downstream, ResultReceiver receiver, + boolean showEntitlementUi) { + if (!isTetherProvisioningRequired()) { receiver.send(TETHER_ERROR_NO_ERROR, null); return; } - final int cacheValue; - synchronized (mEntitlementCacheValue) { - cacheValue = mEntitlementCacheValue.get( + final int cacheValue = mEntitlementCacheValue.get( downstream, TETHER_ERROR_ENTITLEMENT_UNKONWN); - } if (cacheValue == TETHER_ERROR_NO_ERROR || !showEntitlementUi) { receiver.send(cacheValue, null); } else { - ResultReceiver proxy = buildProxyReceiver(downstream, receiver); + ResultReceiver proxy = buildProxyReceiver(downstream, false/* notifyFail */, receiver); runUiTetherProvisioning(downstream, proxy); } } diff --git a/services/core/java/com/android/server/connectivity/tethering/TetheringConfiguration.java b/services/core/java/com/android/server/connectivity/tethering/TetheringConfiguration.java index 935b79546d63..8427b6eceab9 100644 --- a/services/core/java/com/android/server/connectivity/tethering/TetheringConfiguration.java +++ b/services/core/java/com/android/server/connectivity/tethering/TetheringConfiguration.java @@ -30,6 +30,7 @@ import static com.android.internal.R.array.config_tether_upstream_types; import static com.android.internal.R.array.config_tether_usb_regexs; import static com.android.internal.R.array.config_tether_wifi_regexs; import static com.android.internal.R.bool.config_tether_upstream_automatic; +import static com.android.internal.R.integer.config_mobile_hotspot_provision_check_period; import static com.android.internal.R.string.config_mobile_hotspot_provision_app_no_ui; import android.content.ContentResolver; @@ -94,6 +95,7 @@ public class TetheringConfiguration { public final String[] provisioningApp; public final String provisioningAppNoUi; + public final int provisioningCheckPeriod; public final int subId; @@ -121,6 +123,9 @@ public class TetheringConfiguration { provisioningApp = getResourceStringArray(res, config_mobile_hotspot_provision_app); provisioningAppNoUi = getProvisioningAppNoUi(res); + provisioningCheckPeriod = getResourceInteger(res, + config_mobile_hotspot_provision_check_period, + 0 /* No periodic re-check */); configLog.log(toString()); } @@ -311,6 +316,14 @@ public class TetheringConfiguration { } } + private static int getResourceInteger(Resources res, int resId, int defaultValue) { + try { + return res.getInteger(resId); + } catch (Resources.NotFoundException e404) { + return defaultValue; + } + } + private static boolean getEnableLegacyDhcpServer(Context ctx) { final ContentResolver cr = ctx.getContentResolver(); final int intVal = Settings.Global.getInt(cr, TETHER_ENABLE_LEGACY_DHCP_SERVER, 0); diff --git a/services/core/java/com/android/server/connectivity/tethering/TetheringDependencies.java b/services/core/java/com/android/server/connectivity/tethering/TetheringDependencies.java index 173d7860e4ac..a0aad7c50481 100644 --- a/services/core/java/com/android/server/connectivity/tethering/TetheringDependencies.java +++ b/services/core/java/com/android/server/connectivity/tethering/TetheringDependencies.java @@ -83,8 +83,8 @@ public class TetheringDependencies { * Get a reference to the EntitlementManager to be used by tethering. */ public EntitlementManager getEntitlementManager(Context ctx, StateMachine target, - SharedLog log, MockableSystemProperties systemProperties) { - return new EntitlementManager(ctx, target, log, systemProperties); + SharedLog log, int what, MockableSystemProperties systemProperties) { + return new EntitlementManager(ctx, target, log, what, systemProperties); } /** diff --git a/services/core/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java b/services/core/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java index 3ac311b3e13a..3a9e21f943d8 100644 --- a/services/core/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java +++ b/services/core/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java @@ -16,36 +16,32 @@ package com.android.server.connectivity.tethering; -import static android.net.ConnectivityManager.getNetworkTypeName; -import static android.net.ConnectivityManager.TYPE_NONE; import static android.net.ConnectivityManager.TYPE_MOBILE_DUN; import static android.net.ConnectivityManager.TYPE_MOBILE_HIPRI; +import static android.net.ConnectivityManager.TYPE_NONE; +import static android.net.ConnectivityManager.getNetworkTypeName; import static android.net.NetworkCapabilities.NET_CAPABILITY_DUN; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN; import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; import android.content.Context; -import android.os.Handler; -import android.os.Looper; -import android.os.Process; import android.net.ConnectivityManager; import android.net.ConnectivityManager.NetworkCallback; import android.net.IpPrefix; -import android.net.LinkAddress; import android.net.LinkProperties; import android.net.Network; import android.net.NetworkCapabilities; import android.net.NetworkRequest; import android.net.NetworkState; -import android.net.util.NetworkConstants; import android.net.util.PrefixUtils; import android.net.util.SharedLog; +import android.os.Handler; +import android.os.Process; import android.util.Log; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.StateMachine; -import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Set; @@ -97,10 +93,13 @@ public class UpstreamNetworkMonitor { private final HashMap<Network, NetworkState> mNetworkMap = new HashMap<>(); private HashSet<IpPrefix> mLocalPrefixes; private ConnectivityManager mCM; + private EntitlementManager mEntitlementMgr; private NetworkCallback mListenAllCallback; private NetworkCallback mDefaultNetworkCallback; private NetworkCallback mMobileNetworkCallback; private boolean mDunRequired; + // Whether the current default upstream is mobile or not. + private boolean mIsDefaultCellularUpstream; // The current system default network (not really used yet). private Network mDefaultInternetNetwork; // The current upstream network used for tethering. @@ -113,6 +112,7 @@ public class UpstreamNetworkMonitor { mLog = log.forSubComponent(TAG); mWhat = what; mLocalPrefixes = new HashSet<>(); + mIsDefaultCellularUpstream = false; } @VisibleForTesting @@ -122,7 +122,15 @@ public class UpstreamNetworkMonitor { mCM = cm; } - public void startTrackDefaultNetwork(NetworkRequest defaultNetworkRequest) { + /** + * Tracking the system default network. This method should be called when system is ready. + * + * @param defaultNetworkRequest should be the same as ConnectivityService default request + * @param entitle a EntitlementManager object to communicate between EntitlementManager and + * UpstreamNetworkMonitor + */ + public void startTrackDefaultNetwork(NetworkRequest defaultNetworkRequest, + EntitlementManager entitle) { // This is not really a "request", just a way of tracking the system default network. // It's guaranteed not to actually bring up any networks because it's the same request // as the ConnectivityService default request, and thus shares fate with it. We can't @@ -133,6 +141,9 @@ public class UpstreamNetworkMonitor { mDefaultNetworkCallback = new UpstreamNetworkCallback(CALLBACK_DEFAULT_INTERNET); cm().requestNetwork(trackDefaultRequest, mDefaultNetworkCallback, mHandler); } + if (mEntitlementMgr == null) { + mEntitlementMgr = entitle; + } } public void startObserveAllNetworks() { @@ -168,11 +179,15 @@ public class UpstreamNetworkMonitor { } public void registerMobileNetworkRequest() { + if (!isCellularUpstreamPermitted()) { + mLog.i("registerMobileNetworkRequest() is not permitted"); + releaseMobileNetworkRequest(); + return; + } if (mMobileNetworkCallback != null) { mLog.e("registerMobileNetworkRequest() already registered"); return; } - // The following use of the legacy type system cannot be removed until // after upstream selection no longer finds networks by legacy type. // See also http://b/34364553 . @@ -206,29 +221,32 @@ public class UpstreamNetworkMonitor { // becomes available and useful we (a) file a request to keep it up as // necessary and (b) change all upstream tracking state accordingly (by // passing LinkProperties up to Tethering). - // - // Next TODO: return NetworkState instead of just the type. public NetworkState selectPreferredUpstreamType(Iterable<Integer> preferredTypes) { final TypeStatePair typeStatePair = findFirstAvailableUpstreamByType( - mNetworkMap.values(), preferredTypes); + mNetworkMap.values(), preferredTypes, isCellularUpstreamPermitted()); mLog.log("preferred upstream type: " + getNetworkTypeName(typeStatePair.type)); switch (typeStatePair.type) { case TYPE_MOBILE_DUN: case TYPE_MOBILE_HIPRI: + // Tethering just selected mobile upstream in spite of the default network being + // not mobile. This can happen because of the priority list. + // Notify EntitlementManager to check permission for using mobile upstream. + if (!mIsDefaultCellularUpstream) { + mEntitlementMgr.maybeRunProvisioning(); + } // If we're on DUN, put our own grab on it. registerMobileNetworkRequest(); break; case TYPE_NONE: + // If we found NONE and mobile upstream is permitted we don't want to do this + // as we want any previous requests to keep trying to bring up something we can use. + if (!isCellularUpstreamPermitted()) releaseMobileNetworkRequest(); break; default: - /* If we've found an active upstream connection that's not DUN/HIPRI - * we should stop any outstanding DUN/HIPRI requests. - * - * If we found NONE we don't want to do this as we want any previous - * requests to keep trying to bring up something we can use. - */ + // If we've found an active upstream connection that's not DUN/HIPRI + // we should stop any outstanding DUN/HIPRI requests. releaseMobileNetworkRequest(); break; } @@ -241,10 +259,12 @@ public class UpstreamNetworkMonitor { final NetworkState dfltState = (mDefaultInternetNetwork != null) ? mNetworkMap.get(mDefaultInternetNetwork) : null; - if (!mDunRequired) return dfltState; - if (isNetworkUsableAndNotCellular(dfltState)) return dfltState; + if (!isCellularUpstreamPermitted()) return null; + + if (!mDunRequired) return dfltState; + // Find a DUN network. Note that code in Tethering causes a DUN request // to be filed, but this might be moved into this class in future. return findFirstDunNetwork(mNetworkMap.values()); @@ -258,6 +278,15 @@ public class UpstreamNetworkMonitor { return (Set<IpPrefix>) mLocalPrefixes.clone(); } + private boolean isCellularUpstreamPermitted() { + if (mEntitlementMgr != null) { + return mEntitlementMgr.isCellularUpstreamPermitted(); + } else { + // This flow should only happens in testing. + return true; + } + } + private void handleAvailable(Network network) { if (mNetworkMap.containsKey(network)) return; @@ -388,8 +417,14 @@ public class UpstreamNetworkMonitor { public void onCapabilitiesChanged(Network network, NetworkCapabilities newNc) { if (mCallbackType == CALLBACK_DEFAULT_INTERNET) { mDefaultInternetNetwork = network; + final boolean newIsCellular = isCellular(newNc); + if (mIsDefaultCellularUpstream != newIsCellular) { + mIsDefaultCellularUpstream = newIsCellular; + mEntitlementMgr.notifyUpstream(newIsCellular); + } return; } + handleNetCap(network, newNc); } @@ -424,8 +459,11 @@ public class UpstreamNetworkMonitor { public void onLost(Network network) { if (mCallbackType == CALLBACK_DEFAULT_INTERNET) { mDefaultInternetNetwork = null; + mIsDefaultCellularUpstream = false; + mEntitlementMgr.notifyUpstream(false); return; } + handleLost(network); // Any non-LISTEN_ALL callback will necessarily concern a network that will // also match the LISTEN_ALL callback by construction of the LISTEN_ALL callback. @@ -454,7 +492,8 @@ public class UpstreamNetworkMonitor { } private static TypeStatePair findFirstAvailableUpstreamByType( - Iterable<NetworkState> netStates, Iterable<Integer> preferredTypes) { + Iterable<NetworkState> netStates, Iterable<Integer> preferredTypes, + boolean isCellularUpstreamPermitted) { final TypeStatePair result = new TypeStatePair(); for (int type : preferredTypes) { @@ -466,6 +505,10 @@ public class UpstreamNetworkMonitor { ConnectivityManager.getNetworkTypeName(type)); continue; } + if (!isCellularUpstreamPermitted && isCellular(nc)) { + continue; + } + nc.setSingleUid(Process.myUid()); for (NetworkState value : netStates) { diff --git a/services/core/java/com/android/server/content/ContentService.java b/services/core/java/com/android/server/content/ContentService.java index 4e4b15fc5b9b..ba4dcdbb7ee3 100644 --- a/services/core/java/com/android/server/content/ContentService.java +++ b/services/core/java/com/android/server/content/ContentService.java @@ -1317,7 +1317,9 @@ public final class ContentService extends IContentService.Stub { final int procState = ami.getUidProcessState(callingUid); final boolean isUidActive = ami.isUidActive(callingUid); - if (procState <= ActivityManager.PROCESS_STATE_TOP) { + // Providers bound by a TOP app will get PROCESS_STATE_BOUND_TOP, so include those as well + if (procState <= ActivityManager.PROCESS_STATE_TOP + || procState == ActivityManager.PROCESS_STATE_BOUND_TOP) { return ContentResolver.SYNC_EXEMPTION_PROMOTE_BUCKET_WITH_TEMP; } if (procState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND || isUidActive) { diff --git a/services/core/java/com/android/server/contentcapture/ContentCaptureManagerInternal.java b/services/core/java/com/android/server/contentcapture/ContentCaptureManagerInternal.java index fa7d3fca75b5..ad04b7d10433 100644 --- a/services/core/java/com/android/server/contentcapture/ContentCaptureManagerInternal.java +++ b/services/core/java/com/android/server/contentcapture/ContentCaptureManagerInternal.java @@ -49,6 +49,9 @@ public abstract class ContentCaptureManagerInternal { /** * Gets the content capture options for the given user and package, or {@code null} if the * package is not whitelisted by the service. + * + * <p><b>NOTE: </b>this method is called by the {@code ActivityManager} service and hence cannot + * hold the main service lock. */ @Nullable public abstract ContentCaptureOptions getOptionsForPackage(@UserIdInt int userId, diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java index 10f7db5e3a73..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( @@ -961,7 +969,10 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource { @ServiceThreadOnly void doManualPortSwitching(int portId, IHdmiControlCallback callback) { assertRunOnServiceThread(); - // TODO: validate port ID + if (!mService.isValidPortId(portId)) { + invokeCallback(callback, HdmiControlManager.RESULT_TARGET_NOT_AVAILABLE); + return; + } if (portId == getLocalActivePort()) { invokeCallback(callback, HdmiControlManager.RESULT_SUCCESS); return; @@ -1026,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/incident/IncidentCompanionService.java b/services/core/java/com/android/server/incident/IncidentCompanionService.java index 55e054b6c8cd..9989c1a511ad 100644 --- a/services/core/java/com/android/server/incident/IncidentCompanionService.java +++ b/services/core/java/com/android/server/incident/IncidentCompanionService.java @@ -23,7 +23,10 @@ import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.UserInfo; +import android.content.res.Resources; import android.os.Binder; +import android.os.Build; +import android.os.IBinder; import android.os.IIncidentAuthListener; import android.os.IIncidentCompanion; import android.os.IIncidentManager; @@ -49,6 +52,12 @@ public class IncidentCompanionService extends SystemService { static final String TAG = "IncidentCompanionService"; /** + * Dump argument for proxying restricted image dumps to the services + * listed in the config. + */ + private static String[] RESTRICTED_IMAGE_DUMP_ARGS = new String[] { "--restricted_image" }; + + /** * The two permissions, for sendBroadcastAsUserMultiplePermissions. */ private static final String[] DUMP_AND_USAGE_STATS_PERMISSIONS = new String[] { @@ -260,7 +269,42 @@ public class IncidentCompanionService extends SystemService { if (!DumpUtils.checkDumpPermission(getContext(), TAG, writer)) { return; } - mPendingReports.dump(fd, writer, args); + + if (args.length == 1 && "--restricted_image".equals(args[0])) { + // Does NOT clearCallingIdentity + dumpRestrictedImages(fd); + } else { + // Regular dump + mPendingReports.dump(fd, writer, args); + } + } + + /** + * Proxy for the restricted images section. + */ + private void dumpRestrictedImages(FileDescriptor fd) { + // Only supported on eng or userdebug. + if (!(Build.IS_ENG || Build.IS_USERDEBUG)) { + return; + } + + final Resources res = getContext().getResources(); + final String[] services = res.getStringArray( + com.android.internal.R.array.config_restrictedImagesServices); + final int servicesCount = services.length; + for (int i = 0; i < servicesCount; i++) { + final String name = services[i]; + Log.d(TAG, "Looking up service " + name); + final IBinder service = ServiceManager.getService(name); + if (service != null) { + Log.d(TAG, "Calling dump on service: " + name); + try { + service.dump(fd, RESTRICTED_IMAGE_DUMP_ARGS); + } catch (RemoteException ex) { + Log.w(TAG, "dump --restricted_image of " + name + " threw", ex); + } + } + } } /** @@ -300,7 +344,7 @@ public class IncidentCompanionService extends SystemService { android.Manifest.permission.DUMP, null); getContext().enforceCallingOrSelfPermission( android.Manifest.permission.PACKAGE_USAGE_STATS, null); - if (pkg == null) { + if (pkg != null) { enforceCallerIsSameApp(pkg); } } diff --git a/services/core/java/com/android/server/infra/AbstractMasterSystemService.java b/services/core/java/com/android/server/infra/AbstractMasterSystemService.java index ed894ee0bee8..098b0e9d4d39 100644 --- a/services/core/java/com/android/server/infra/AbstractMasterSystemService.java +++ b/services/core/java/com/android/server/infra/AbstractMasterSystemService.java @@ -181,9 +181,8 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem mServiceNameResolver = serviceNameResolver; if (mServiceNameResolver != null) { - mServiceNameResolver - .setOnTemporaryServiceNameChangedCallback( - (u, s) -> updateCachedServiceLocked(u)); + mServiceNameResolver.setOnTemporaryServiceNameChangedCallback( + (u, s, t) -> onServiceNameChanged(u, s, t)); } if (disallowProperty == null) { @@ -582,6 +581,23 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem } /** + * Called when the service name changed (typically when using temporary services). + * + * <p>By default, it calls {@link #updateCachedServiceLocked(int)}; subclasses must either call + * that same method, or {@code super.onServiceNameChanged()}. + * + * @param userId user handle. + * @param serviceName the new service name. + * @param isTemporary whether the new service is temporary. + */ + protected void onServiceNameChanged(@UserIdInt int userId, @Nullable String serviceName, + boolean isTemporary) { + synchronized (mLock) { + updateCachedServiceLocked(userId); + } + } + + /** * Visits all services in the cache. */ @GuardedBy("mLock") @@ -600,6 +616,23 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem mServicesCache.clear(); } + /** + * Asserts that the given package name is owned by the UID making this call. + * + * @throws SecurityException when it's not... + */ + protected final void assertCalledByPackageOwner(@NonNull String packageName) { + Preconditions.checkNotNull(packageName); + final int uid = Binder.getCallingUid(); + final String[] packages = getContext().getPackageManager().getPackagesForUid(uid); + if (packages != null) { + for (String candidate : packages) { + if (packageName.equals(candidate)) return; // Found it + } + } + throw new SecurityException("UID " + uid + " does not own " + packageName); + } + // TODO(b/117779333): support proto protected void dumpLocked(@NonNull String prefix, @NonNull PrintWriter pw) { boolean realDebug = debug; diff --git a/services/core/java/com/android/server/infra/FrameworkResourcesServiceNameResolver.java b/services/core/java/com/android/server/infra/FrameworkResourcesServiceNameResolver.java index d20481331e56..35d59561fdeb 100644 --- a/services/core/java/com/android/server/infra/FrameworkResourcesServiceNameResolver.java +++ b/services/core/java/com/android/server/infra/FrameworkResourcesServiceNameResolver.java @@ -155,7 +155,8 @@ public final class FrameworkResourcesServiceNameResolver implements ServiceNameR } mTemporaryServiceExpiration = SystemClock.elapsedRealtime() + durationMs; mTemporaryHandler.sendEmptyMessageDelayed(MSG_RESET_TEMPORARY_SERVICE, durationMs); - notifyTemporaryServiceNameChangedLocked(userId, componentName); + notifyTemporaryServiceNameChangedLocked(userId, componentName, + /* isTemporary= */ true); } } @@ -169,7 +170,8 @@ public final class FrameworkResourcesServiceNameResolver implements ServiceNameR mTemporaryHandler.removeMessages(MSG_RESET_TEMPORARY_SERVICE); mTemporaryHandler = null; } - notifyTemporaryServiceNameChangedLocked(userId, /* newTemporaryName= */ null); + notifyTemporaryServiceNameChangedLocked(userId, /* newTemporaryName= */ null, + /* isTemporary= */ false); } } @@ -235,9 +237,9 @@ public final class FrameworkResourcesServiceNameResolver implements ServiceNameR } private void notifyTemporaryServiceNameChangedLocked(@UserIdInt int userId, - @Nullable String newTemporaryName) { + @Nullable String newTemporaryName, boolean isTemporary) { if (mOnSetCallback != null) { - mOnSetCallback.onNameResolved(userId, newTemporaryName); + mOnSetCallback.onNameResolved(userId, newTemporaryName, isTemporary); } } } diff --git a/services/core/java/com/android/server/infra/ServiceNameResolver.java b/services/core/java/com/android/server/infra/ServiceNameResolver.java index 8c348ebbfcd4..e20c45992e05 100644 --- a/services/core/java/com/android/server/infra/ServiceNameResolver.java +++ b/services/core/java/com/android/server/infra/ServiceNameResolver.java @@ -39,7 +39,8 @@ public interface ServiceNameResolver { /** * The name change callback. */ - void onNameResolved(@UserIdInt int userId, @Nullable String serviceName); + void onNameResolved(@UserIdInt int userId, @Nullable String serviceName, + boolean isTemporary); } /** diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java index 622c49e67967..5abc73eb255a 100644 --- a/services/core/java/com/android/server/input/InputManagerService.java +++ b/services/core/java/com/android/server/input/InputManagerService.java @@ -1809,6 +1809,10 @@ public class InputManagerService extends IInputManager.Stub } // Native callback. + private void onPointerDownOutsideFocus(IBinder touchedToken) { + } + + // Native callback. private int getVirtualKeyQuietTimeMillis() { return mContext.getResources().getInteger( com.android.internal.R.integer.config_virtualKeyQuietTimeMillis); diff --git a/services/core/java/com/android/server/job/JobStore.java b/services/core/java/com/android/server/job/JobStore.java index 62553067996d..64c23affcf8c 100644 --- a/services/core/java/com/android/server/job/JobStore.java +++ b/services/core/java/com/android/server/job/JobStore.java @@ -40,6 +40,7 @@ import android.util.Slog; import android.util.SparseArray; import android.util.Xml; +import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.ArrayUtils; import com.android.internal.util.BitUtils; @@ -85,9 +86,10 @@ public final class JobStore { private static final boolean DEBUG = JobSchedulerService.DEBUG; /** Threshold to adjust how often we want to write to the db. */ - private static final int MAX_OPS_BEFORE_WRITE = 1; + private static final long JOB_PERSIST_DELAY = 2000L; final Object mLock; + final Object mWriteScheduleLock; // used solely for invariants around write scheduling final JobSet mJobSet; // per-caller-uid and per-source-uid tracking final Context mContext; @@ -95,7 +97,11 @@ public final class JobStore { private final long mXmlTimestamp; private boolean mRtcGood; - private int mDirtyOperations; + @GuardedBy("mWriteScheduleLock") + private boolean mWriteScheduled; + + @GuardedBy("mWriteScheduleLock") + private boolean mWriteInProgress; private static final Object sSingletonLock = new Object(); private final AtomicFile mJobsFile; @@ -131,8 +137,8 @@ public final class JobStore { */ private JobStore(Context context, Object lock, File dataDir) { mLock = lock; + mWriteScheduleLock = new Object(); mContext = context; - mDirtyOperations = 0; File systemDir = new File(dataDir, "system"); File jobDir = new File(systemDir, "job"); @@ -322,13 +328,14 @@ public final class JobStore { * track incremental changes. */ private void maybeWriteStatusToDiskAsync() { - mDirtyOperations++; - if (mDirtyOperations >= MAX_OPS_BEFORE_WRITE) { - if (DEBUG) { - Slog.v(TAG, "Writing jobs to disk."); + synchronized (mWriteScheduleLock) { + if (!mWriteScheduled) { + if (DEBUG) { + Slog.v(TAG, "Scheduling persist of jobs to disk."); + } + mIoHandler.postDelayed(mWriteRunnable, JOB_PERSIST_DELAY); + mWriteScheduled = mWriteInProgress = true; } - mIoHandler.removeCallbacks(mWriteRunnable); - mIoHandler.post(mWriteRunnable); } } @@ -338,6 +345,34 @@ public final class JobStore { } /** + * Wait for any pending write to the persistent store to clear + * @param maxWaitMillis Maximum time from present to wait + * @return {@code true} if I/O cleared as expected, {@code false} if the wait + * timed out before the pending write completed. + */ + @VisibleForTesting + public boolean waitForWriteToCompleteForTesting(long maxWaitMillis) { + final long start = SystemClock.uptimeMillis(); + final long end = start + maxWaitMillis; + synchronized (mWriteScheduleLock) { + while (mWriteInProgress) { + final long now = SystemClock.uptimeMillis(); + if (now >= end) { + // still not done and we've hit the end; failure + return false; + } + try { + mWriteScheduleLock.wait(now - start + maxWaitMillis); + } catch (InterruptedException e) { + // Spurious; keep waiting + break; + } + } + } + return true; + } + + /** * Runnable that writes {@link #mJobSet} out to xml. * NOTE: This Runnable locks on mLock */ @@ -346,6 +381,16 @@ public final class JobStore { public void run() { final long startElapsed = sElapsedRealtimeClock.millis(); final List<JobStatus> storeCopy = new ArrayList<JobStatus>(); + // Intentionally allow new scheduling of a write operation *before* we clone + // the job set. If we reset it to false after cloning, there's a window in + // which no new write will be scheduled but mLock is not held, i.e. a new + // job might appear and fail to be recognized as needing a persist. The + // potential cost is one redundant write of an identical set of jobs in the + // rare case of that specific race, but by doing it this way we avoid quite + // a bit of lock contention. + synchronized (mWriteScheduleLock) { + mWriteScheduled = false; + } synchronized (mLock) { // Clone the jobs so we can release the lock before writing. mJobSet.forEachJob(null, (job) -> { @@ -359,6 +404,10 @@ public final class JobStore { Slog.v(TAG, "Finished writing, took " + (sElapsedRealtimeClock.millis() - startElapsed) + "ms"); } + synchronized (mWriteScheduleLock) { + mWriteInProgress = false; + mWriteScheduleLock.notifyAll(); + } } private void writeJobsMapImpl(List<JobStatus> jobList) { @@ -402,7 +451,6 @@ public final class JobStore { FileOutputStream fos = mJobsFile.startWrite(startTime); fos.write(baos.toByteArray()); mJobsFile.finishWrite(fos); - mDirtyOperations = 0; } catch (IOException e) { if (DEBUG) { Slog.v(TAG, "Error writing out job data.", e); @@ -979,38 +1027,6 @@ public final class JobStore { : JobStatus.NO_LATEST_RUNTIME; return Pair.create(earliestRunTimeRtc, latestRunTimeRtc); } - - /** - * Convenience function to read out and convert deadline and delay from xml into elapsed real - * time. - * @return A {@link android.util.Pair}, where the first value is the earliest elapsed runtime - * and the second is the latest elapsed runtime. - */ - private Pair<Long, Long> buildExecutionTimesFromXml(XmlPullParser parser) - throws NumberFormatException { - // Pull out execution time data. - final long nowWallclock = sSystemClock.millis(); - final long nowElapsed = sElapsedRealtimeClock.millis(); - - long earliestRunTimeElapsed = JobStatus.NO_EARLIEST_RUNTIME; - long latestRunTimeElapsed = JobStatus.NO_LATEST_RUNTIME; - String val = parser.getAttributeValue(null, "deadline"); - if (val != null) { - long latestRuntimeWallclock = Long.parseLong(val); - long maxDelayElapsed = - Math.max(latestRuntimeWallclock - nowWallclock, 0); - latestRunTimeElapsed = nowElapsed + maxDelayElapsed; - } - val = parser.getAttributeValue(null, "delay"); - if (val != null) { - long earliestRuntimeWallclock = Long.parseLong(val); - long minDelayElapsed = - Math.max(earliestRuntimeWallclock - nowWallclock, 0); - earliestRunTimeElapsed = nowElapsed + minDelayElapsed; - - } - return Pair.create(earliestRunTimeElapsed, latestRunTimeElapsed); - } } static final class JobSet { diff --git a/services/core/java/com/android/server/job/controllers/QuotaController.java b/services/core/java/com/android/server/job/controllers/QuotaController.java index 5a0b991bc7de..1820acfaf293 100644 --- a/services/core/java/com/android/server/job/controllers/QuotaController.java +++ b/services/core/java/com/android/server/job/controllers/QuotaController.java @@ -769,6 +769,91 @@ public final class QuotaController extends StateController { mMaxExecutionTimeMs - stats.executionTimeInMaxPeriodMs); } + /** + * Returns the amount of time, in milliseconds, until the package would have reached its + * duration quota, assuming it has a job counting towards its quota the entire time. This takes + * into account any {@link TimingSession}s that may roll out of the window as the job is + * running. + */ + @VisibleForTesting + long getTimeUntilQuotaConsumedLocked(final int userId, @NonNull final String packageName) { + final long nowElapsed = sElapsedRealtimeClock.millis(); + final int standbyBucket = JobSchedulerService.standbyBucketForPackage( + packageName, userId, nowElapsed); + if (standbyBucket == NEVER_INDEX) { + return 0; + } + List<TimingSession> sessions = mTimingSessions.get(userId, packageName); + if (sessions == null || sessions.size() == 0) { + return mAllowedTimePerPeriodMs; + } + + final ExecutionStats stats = getExecutionStatsLocked(userId, packageName, standbyBucket); + final long startWindowElapsed = nowElapsed - stats.windowSizeMs; + final long startMaxElapsed = nowElapsed - MAX_PERIOD_MS; + final long allowedTimeRemainingMs = mAllowedTimePerPeriodMs - stats.executionTimeInWindowMs; + final long maxExecutionTimeRemainingMs = + mMaxExecutionTimeMs - stats.executionTimeInMaxPeriodMs; + + // Regular ACTIVE case. Since the bucket size equals the allowed time, the app jobs can + // essentially run until they reach the maximum limit. + if (stats.windowSizeMs == mAllowedTimePerPeriodMs) { + return calculateTimeUntilQuotaConsumedLocked( + sessions, startMaxElapsed, maxExecutionTimeRemainingMs); + } + + // Need to check both max time and period time in case one is less than the other. + // For example, max time remaining could be less than bucket time remaining, but sessions + // contributing to the max time remaining could phase out enough that we'd want to use the + // bucket value. + return Math.min( + calculateTimeUntilQuotaConsumedLocked( + sessions, startMaxElapsed, maxExecutionTimeRemainingMs), + calculateTimeUntilQuotaConsumedLocked( + sessions, startWindowElapsed, allowedTimeRemainingMs)); + } + + /** + * Calculates how much time it will take, in milliseconds, until the quota is fully consumed. + * + * @param windowStartElapsed The start of the window, in the elapsed realtime timebase. + * @param deadSpaceMs How much time can be allowed to count towards the quota + */ + private long calculateTimeUntilQuotaConsumedLocked(@NonNull List<TimingSession> sessions, + final long windowStartElapsed, long deadSpaceMs) { + long timeUntilQuotaConsumedMs = 0; + long start = windowStartElapsed; + for (int i = 0; i < sessions.size(); ++i) { + TimingSession session = sessions.get(i); + + if (session.endTimeElapsed < windowStartElapsed) { + // Outside of window. Ignore. + continue; + } else if (session.startTimeElapsed <= windowStartElapsed) { + // Overlapping session. Can extend time by portion of session in window. + timeUntilQuotaConsumedMs += session.endTimeElapsed - windowStartElapsed; + start = session.endTimeElapsed; + } else { + // Completely within the window. Can only consider if there's enough dead space + // to get to the start of the session. + long diff = session.startTimeElapsed - start; + if (diff > deadSpaceMs) { + break; + } + timeUntilQuotaConsumedMs += diff + + (session.endTimeElapsed - session.startTimeElapsed); + deadSpaceMs -= diff; + start = session.endTimeElapsed; + } + } + // Will be non-zero if the loop didn't look at any sessions. + timeUntilQuotaConsumedMs += deadSpaceMs; + if (timeUntilQuotaConsumedMs > mMaxExecutionTimeMs) { + Slog.wtf(TAG, "Calculated quota consumed time too high: " + timeUntilQuotaConsumedMs); + } + return timeUntilQuotaConsumedMs; + } + /** Returns the execution stats of the app in the most recent window. */ @VisibleForTesting @NonNull @@ -1483,7 +1568,7 @@ public final class QuotaController extends StateController { return; } Message msg = mHandler.obtainMessage(MSG_REACHED_QUOTA, mPkg); - final long timeRemainingMs = getRemainingExecutionTimeLocked(mPkg.userId, + final long timeRemainingMs = getTimeUntilQuotaConsumedLocked(mPkg.userId, mPkg.packageName); if (DEBUG) { Slog.i(TAG, "Job for " + mPkg + " has " + timeRemainingMs + "ms left."); @@ -1642,6 +1727,8 @@ public final class QuotaController extends StateController { // job is currently running. // Reschedule message Message rescheduleMsg = obtainMessage(MSG_REACHED_QUOTA, pkg); + timeRemainingMs = getTimeUntilQuotaConsumedLocked(pkg.userId, + pkg.packageName); if (DEBUG) { Slog.d(TAG, pkg + " has " + timeRemainingMs + "ms left."); } diff --git a/services/core/java/com/android/server/location/GnssCapabilitiesProvider.java b/services/core/java/com/android/server/location/GnssCapabilitiesProvider.java new file mode 100644 index 000000000000..98085b8e219b --- /dev/null +++ b/services/core/java/com/android/server/location/GnssCapabilitiesProvider.java @@ -0,0 +1,143 @@ +/* + * 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.server.location; + +import android.location.GnssCapabilities; +import android.util.Log; + +import com.android.internal.annotations.GuardedBy; + +/** + * Provides GNSS capabilities supported by the GNSS HAL implementation. + */ +public class GnssCapabilitiesProvider { + private static final String TAG = "GnssCapabilitiesProvider"; + private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); + + // Bit masks for capabilities in {@link android.location.GnssCapabilities}. + private static final long GNSS_CAPABILITY_LOW_POWER_MODE = + 1L << GnssCapabilities.LOW_POWER_MODE; + private static final long GNSS_CAPABILITY_SATELLITE_BLACKLIST = + 1L << GnssCapabilities.SATELLITE_BLACKLIST; + private static final long GNSS_CAPABILITY_GEOFENCING = 1L << GnssCapabilities.GEOFENCING; + private static final long GNSS_CAPABILITY_MEASUREMENTS = 1L << GnssCapabilities.MEASUREMENTS; + private static final long GNSS_CAPABILITY_NAV_MESSAGES = 1L << GnssCapabilities.NAV_MESSAGES; + private static final long GNSS_CAPABILITY_MEASUREMENT_CORRECTIONS = + 1L << GnssCapabilities.MEASUREMENT_CORRECTIONS; + private static final long GNSS_CAPABILITY_MEASUREMENT_CORRECTIONS_LOS_SATS = + 1L << GnssCapabilities.MEASUREMENT_CORRECTIONS_LOS_SATS; + private static final long GNSS_CAPABILITY_MEASUREMENT_CORRECTIONS_EXCESS_PATH_LENGTH = + 1L << GnssCapabilities.MEASUREMENT_CORRECTIONS_EXCESS_PATH_LENGTH; + private static final long GNSS_CAPABILITY_MEASUREMENT_CORRECTIONS_REFLECTING_PLANE = + 1L << GnssCapabilities.MEASUREMENT_CORRECTIONS_REFLECTING_PLANE; + + private static final long GNSS_CAPABILITIES_TOP_HAL = + GNSS_CAPABILITY_LOW_POWER_MODE | GNSS_CAPABILITY_SATELLITE_BLACKLIST + | GNSS_CAPABILITY_GEOFENCING | GNSS_CAPABILITY_MEASUREMENTS + | GNSS_CAPABILITY_NAV_MESSAGES; + + private static final long GNSS_CAPABILITIES_SUB_HAL_MEASUREMENT_CORRECTIONS = + GNSS_CAPABILITY_MEASUREMENT_CORRECTIONS + | GNSS_CAPABILITY_MEASUREMENT_CORRECTIONS_LOS_SATS + | GNSS_CAPABILITY_MEASUREMENT_CORRECTIONS_EXCESS_PATH_LENGTH + | GNSS_CAPABILITY_MEASUREMENT_CORRECTIONS_REFLECTING_PLANE; + + // Capabilities in {@link android.location.GnssCapabilities} supported by GNSS chipset. + @GuardedBy("this") + private long mGnssCapabilities; + + /** + * Returns the capabilities supported by the GNSS chipset. + * + * <p>The capabilities are described in {@link android.location.GnssCapabilities} and + * their integer values correspond to the bit positions in the returned {@code long} value. + */ + public long getGnssCapabilities() { + synchronized (this) { + return mGnssCapabilities; + } + } + + /** + * Updates the general capabilities exposed through {@link android.location.GnssCapabilities}. + */ + void setTopHalCapabilities(int topHalCapabilities, + boolean hasGeofencingCapability, boolean hasMeasurementsCapability, + boolean hasNavMessagesCapability) { + long gnssCapabilities = 0; + if (hasCapability(topHalCapabilities, + GnssLocationProvider.GPS_CAPABILITY_LOW_POWER_MODE)) { + gnssCapabilities |= GNSS_CAPABILITY_LOW_POWER_MODE; + } + if (hasCapability(topHalCapabilities, + GnssLocationProvider.GPS_CAPABILITY_SATELLITE_BLACKLIST)) { + gnssCapabilities |= GNSS_CAPABILITY_SATELLITE_BLACKLIST; + } + if (hasGeofencingCapability) { + gnssCapabilities |= GNSS_CAPABILITY_GEOFENCING; + } + if (hasMeasurementsCapability) { + gnssCapabilities |= GNSS_CAPABILITY_MEASUREMENTS; + } + if (hasNavMessagesCapability) { + gnssCapabilities |= GNSS_CAPABILITY_NAV_MESSAGES; + } + + synchronized (this) { + mGnssCapabilities &= ~GNSS_CAPABILITIES_TOP_HAL; + mGnssCapabilities |= gnssCapabilities; + if (DEBUG) { + Log.d(TAG, "setTopHalCapabilities, mGnssCapabilities=0x" + Long.toHexString( + mGnssCapabilities) + ", " + GnssCapabilities.of(mGnssCapabilities)); + } + } + } + + /** + * Updates the measurement corrections related capabilities exposed through + * {@link android.location.GnssCapabilities}. + */ + void setSubHalMeasurementCorrectionsCapabilities(int measurementCorrectionsCapabilities) { + long gnssCapabilities = GNSS_CAPABILITY_MEASUREMENT_CORRECTIONS; + if (hasCapability(measurementCorrectionsCapabilities, + GnssMeasurementCorrectionsProvider.CAPABILITY_LOS_SATS)) { + gnssCapabilities |= GNSS_CAPABILITY_MEASUREMENT_CORRECTIONS_LOS_SATS; + } + if (hasCapability(measurementCorrectionsCapabilities, + GnssMeasurementCorrectionsProvider.CAPABILITY_EXCESS_PATH_LENGTH)) { + gnssCapabilities |= GNSS_CAPABILITY_MEASUREMENT_CORRECTIONS_EXCESS_PATH_LENGTH; + } + if (hasCapability(measurementCorrectionsCapabilities, + GnssMeasurementCorrectionsProvider.CAPABILITY_REFLECTING_PLANE)) { + gnssCapabilities |= GNSS_CAPABILITY_MEASUREMENT_CORRECTIONS_REFLECTING_PLANE; + } + + synchronized (this) { + mGnssCapabilities &= ~GNSS_CAPABILITIES_SUB_HAL_MEASUREMENT_CORRECTIONS; + mGnssCapabilities |= gnssCapabilities; + if (DEBUG) { + Log.d(TAG, "setSubHalMeasurementCorrectionsCapabilities, mGnssCapabilities=0x" + + Long.toHexString(mGnssCapabilities) + ", " + GnssCapabilities.of( + mGnssCapabilities)); + } + } + } + + private static boolean hasCapability(int halCapabilities, int capability) { + return (halCapabilities & capability) != 0; + } +} diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java index 8249999033a4..be34adb1fca4 100644 --- a/services/core/java/com/android/server/location/GnssLocationProvider.java +++ b/services/core/java/com/android/server/location/GnssLocationProvider.java @@ -173,8 +173,8 @@ public class GnssLocationProvider extends AbstractLocationProvider implements public static final int GPS_CAPABILITY_MEASUREMENTS = 0x0000040; public static final int GPS_CAPABILITY_NAV_MESSAGES = 0x0000080; - private static final int GPS_CAPABILITY_LOW_POWER_MODE = 0x0000100; - private static final int GPS_CAPABILITY_SATELLITE_BLACKLIST = 0x0000200; + static final int GPS_CAPABILITY_LOW_POWER_MODE = 0x0000100; + static final int GPS_CAPABILITY_SATELLITE_BLACKLIST = 0x0000200; // The AGPS SUPL mode private static final int AGPS_SUPL_MODE_MSA = 0x02; @@ -338,8 +338,8 @@ public class GnssLocationProvider extends AbstractLocationProvider implements // true if we started navigation private boolean mStarted; - // capabilities of the GPS engine - private volatile int mEngineCapabilities; + // capabilities reported through the top level IGnssCallback.hal + private volatile int mTopHalCapabilities; // true if XTRA is supported private boolean mSupportsXtra; @@ -359,8 +359,8 @@ public class GnssLocationProvider extends AbstractLocationProvider implements // The WorkSource associated with the most recent client request (i.e, most recent call to // setRequest). private WorkSource mWorkSource = null; - // True if gps should be disabled (used to support battery saver mode in settings). - private boolean mDisableGps = false; + // True if gps should be disabled because of PowerManager controls + private boolean mDisableGpsForPowerManager = false; /** * Properties loaded from PROPERTIES_FILE. @@ -385,6 +385,8 @@ public class GnssLocationProvider extends AbstractLocationProvider implements private final NtpTimeHelper mNtpTimeHelper; private final GnssBatchingProvider mGnssBatchingProvider; private final GnssGeofenceProvider mGnssGeofenceProvider; + private final GnssCapabilitiesProvider mGnssCapabilitiesProvider; + // Available only on GNSS HAL 2.0 implementations and later. private GnssVisibilityControl mGnssVisibilityControl; @@ -538,18 +540,19 @@ public class GnssLocationProvider extends AbstractLocationProvider implements private void updateLowPowerMode() { // Disable GPS if we are in device idle mode. - boolean disableGps = mPowerManager.isDeviceIdleMode(); + boolean disableGpsForPowerManager = mPowerManager.isDeviceIdleMode(); final PowerSaveState result = mPowerManager.getPowerSaveState(ServiceType.LOCATION); switch (result.locationMode) { case PowerManager.LOCATION_MODE_GPS_DISABLED_WHEN_SCREEN_OFF: case PowerManager.LOCATION_MODE_ALL_DISABLED_WHEN_SCREEN_OFF: // If we are in battery saver mode and the screen is off, disable GPS. - disableGps |= result.batterySaverEnabled && !mPowerManager.isInteractive(); + disableGpsForPowerManager |= + result.batterySaverEnabled && !mPowerManager.isInteractive(); break; } - if (disableGps != mDisableGps) { - mDisableGps = disableGps; + if (disableGpsForPowerManager != mDisableGpsForPowerManager) { + mDisableGpsForPowerManager = disableGpsForPowerManager; updateEnabled(); updateRequirements(); } @@ -592,10 +595,8 @@ public class GnssLocationProvider extends AbstractLocationProvider implements mWakeupIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_WAKEUP), 0); mTimeoutIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_TIMEOUT), 0); - mNetworkConnectivityHandler = new GnssNetworkConnectivityHandler( - context, - GnssLocationProvider.this::onNetworkAvailable, - looper); + mNetworkConnectivityHandler = new GnssNetworkConnectivityHandler(context, + GnssLocationProvider.this::onNetworkAvailable, looper); // App ops service to keep track of who is accessing the GPS mAppOps = mContext.getSystemService(AppOpsManager.class); @@ -613,6 +614,7 @@ public class GnssLocationProvider extends AbstractLocationProvider implements // while IO initialization and registration is delegated to our internal handler // this approach is just fine because events are posted to our handler anyway mGnssConfiguration = new GnssConfiguration(mContext); + mGnssCapabilitiesProvider = new GnssCapabilitiesProvider(); // Create a GPS net-initiated handler (also needed by handleInitialize) mNIHandler = new GpsNetInitiatedHandler(context, mNetInitiatedListener, @@ -953,11 +955,19 @@ public class GnssLocationProvider extends AbstractLocationProvider implements private void updateEnabled() { synchronized (mLock) { - boolean enabled = - ((mProviderRequest != null && mProviderRequest.reportLocation - && mProviderRequest.locationSettingsIgnored) || ( - mContext.getSystemService(LocationManager.class).isLocationEnabled() - && !mDisableGps)) && !mShutdown; + // Generally follow location setting + boolean enabled = mContext.getSystemService(LocationManager.class).isLocationEnabled(); + + // ... but disable if PowerManager overrides + enabled &= !mDisableGpsForPowerManager; + + // .. but enable anyway, if there's an active settings-ignored request (e.g. ELS) + enabled |= (mProviderRequest != null && mProviderRequest.reportLocation + && mProviderRequest.locationSettingsIgnored); + + // ... and, finally, disable anyway, if device is being shut down + enabled &= !mShutdown; + if (enabled == mEnabled) { return; } @@ -1271,12 +1281,8 @@ public class GnssLocationProvider extends AbstractLocationProvider implements mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, now + mFixInterval, mWakeupIntent); } - public int getGnssCapabilities() { - return mEngineCapabilities; - } - private boolean hasCapability(int capability) { - return ((mEngineCapabilities & capability) != 0); + return (mTopHalCapabilities & capability) != 0; } @NativeEntryPoint @@ -1484,27 +1490,52 @@ public class GnssLocationProvider extends AbstractLocationProvider implements } @NativeEntryPoint - private void setEngineCapabilities(final int capabilities, boolean hasSubHalCapabilityFlags) { - // send to handler thread for fast native return, and in-order handling + private void setTopHalCapabilities(int topHalCapabilities, boolean hasSubHalCapabilityFlags) { + // The IGnssCallback.hal@2.0 removed sub-HAL capability flags from the Capabilities enum + // and instead uses the sub-HAL non-null handle returned from IGnss.hal@2.0 to indicate + // support. Therefore, the 'hasSubHalCapabilityFlags' parameter is needed to tell if the + // 'capabilities' parameter includes the sub-HAL capability flags or not. Old HALs + // which explicitly set the sub-HAL capability bits must continue to work. mHandler.post(() -> { - mEngineCapabilities = capabilities; + mTopHalCapabilities = topHalCapabilities; if (hasCapability(GPS_CAPABILITY_ON_DEMAND_TIME)) { mNtpTimeHelper.enablePeriodicTimeInjection(); requestUtcTime(); } - mGnssMeasurementsProvider.onCapabilitiesUpdated(capabilities, hasSubHalCapabilityFlags); - mGnssNavigationMessageProvider.onCapabilitiesUpdated(capabilities, - hasSubHalCapabilityFlags); + boolean hasGeofencingCapability; + boolean hasMeasurementsCapability; + boolean hasNavMessagesCapability; + if (hasSubHalCapabilityFlags) { + hasGeofencingCapability = hasCapability(GPS_CAPABILITY_GEOFENCING); + hasMeasurementsCapability = hasCapability(GPS_CAPABILITY_MEASUREMENTS); + hasNavMessagesCapability = hasCapability(GPS_CAPABILITY_NAV_MESSAGES); + } else { + hasGeofencingCapability = mGnssGeofenceProvider.isHardwareGeofenceSupported(); + hasMeasurementsCapability = mGnssMeasurementsProvider.isAvailableInPlatform(); + hasNavMessagesCapability = mGnssNavigationMessageProvider.isAvailableInPlatform(); + } + + mGnssMeasurementsProvider.onCapabilitiesUpdated(hasMeasurementsCapability); + mGnssNavigationMessageProvider.onCapabilitiesUpdated(hasNavMessagesCapability); restartRequests(); + + mGnssCapabilitiesProvider.setTopHalCapabilities(topHalCapabilities, + hasGeofencingCapability, hasMeasurementsCapability, hasNavMessagesCapability); }); } @NativeEntryPoint - private void setMeasurementCorrectionsCapabilities(final int capabilities) { - mHandler.post(() -> mGnssMeasurementCorrectionsProvider.onCapabilitiesUpdated( - capabilities)); + private void setSubHalMeasurementCorrectionsCapabilities(int subHalCapabilities) { + mHandler.post(() -> { + if (!mGnssMeasurementCorrectionsProvider.onCapabilitiesUpdated(subHalCapabilities)) { + return; + } + + mGnssCapabilitiesProvider.setSubHalMeasurementCorrectionsCapabilities( + subHalCapabilities); + }); } private void restartRequests() { @@ -1605,6 +1636,13 @@ public class GnssLocationProvider extends AbstractLocationProvider implements return () -> mGnssMetrics.dumpGnssMetricsAsProtoString(); } + /** + * @hide + */ + public GnssCapabilitiesProvider getGnssCapabilitiesProvider() { + return mGnssCapabilitiesProvider; + } + @NativeEntryPoint private void reportLocationBatch(Location[] locationArray) { List<Location> locations = new ArrayList<>(Arrays.asList(locationArray)); @@ -2133,8 +2171,8 @@ public class GnssLocationProvider extends AbstractLocationProvider implements .append(mGnssMeasurementsProvider.isRegistered()).append('\n'); s.append(" mGnssNavigationMessageProvider.isRegistered()=") .append(mGnssNavigationMessageProvider.isRegistered()).append('\n'); - s.append(" mDisableGps (battery saver mode)=").append(mDisableGps).append('\n'); - s.append(" mEngineCapabilities=0x").append(Integer.toHexString(mEngineCapabilities)); + s.append(" mDisableGpsForPowerManager=").append(mDisableGpsForPowerManager).append('\n'); + s.append(" mTopHalCapabilities=0x").append(Integer.toHexString(mTopHalCapabilities)); s.append(" ( "); if (hasCapability(GPS_CAPABILITY_SCHEDULING)) s.append("SCHEDULING "); if (hasCapability(GPS_CAPABILITY_MSB)) s.append("MSB "); diff --git a/services/core/java/com/android/server/location/GnssMeasurementCorrectionsProvider.java b/services/core/java/com/android/server/location/GnssMeasurementCorrectionsProvider.java index 21627876a49e..82528caa0b4e 100644 --- a/services/core/java/com/android/server/location/GnssMeasurementCorrectionsProvider.java +++ b/services/core/java/com/android/server/location/GnssMeasurementCorrectionsProvider.java @@ -34,9 +34,9 @@ public class GnssMeasurementCorrectionsProvider { private static final String TAG = "GnssMeasurementCorrectionsProvider"; // These must match with the Capabilities enum in IMeasurementCorrectionsCallback.hal. - private static final int CAPABILITY_LOS_SATS = 0x0000001; - private static final int CAPABILITY_EXCESS_PATH_LENGTH = 0x0000002; - private static final int CAPABILITY_REFLECTING_PLANE = 0x0000004; + static final int CAPABILITY_LOS_SATS = 0x0000001; + static final int CAPABILITY_EXCESS_PATH_LENGTH = 0x0000002; + static final int CAPABILITY_REFLECTING_PLANE = 0x0000004; private static final int INVALID_CAPABILITIES = 1 << 31; @@ -83,21 +83,23 @@ public class GnssMeasurementCorrectionsProvider { } /** Handle measurement corrections capabilities update from the GNSS HAL implementation. */ - void onCapabilitiesUpdated(int capabilities) { + boolean onCapabilitiesUpdated(int capabilities) { if (hasCapability(capabilities, CAPABILITY_LOS_SATS) || hasCapability(capabilities, CAPABILITY_EXCESS_PATH_LENGTH)) { mCapabilities = capabilities; + return true; } else { Log.e(TAG, "Failed to set capabilities. Received capabilities 0x" + Integer.toHexString(capabilities) + " does not contain the mandatory " + "LOS_SATS or the EXCESS_PATH_LENGTH capability."); + return false; } } /** * Returns the measurement corrections specific capabilities of the GNSS HAL implementation. */ - public int getCapabilities() { + int getCapabilities() { return mCapabilities; } @@ -122,14 +124,14 @@ public class GnssMeasurementCorrectionsProvider { return s.toString(); } - private boolean isCapabilitiesReceived() { - return mCapabilities != INVALID_CAPABILITIES; - } - private static boolean hasCapability(int halCapabilities, int capability) { return (halCapabilities & capability) != 0; } + private boolean isCapabilitiesReceived() { + return mCapabilities != INVALID_CAPABILITIES; + } + @VisibleForTesting static class GnssMeasurementCorrectionsProviderNative { public boolean isMeasurementCorrectionsSupported() { diff --git a/services/core/java/com/android/server/location/GnssMeasurementsProvider.java b/services/core/java/com/android/server/location/GnssMeasurementsProvider.java index 844735a02eeb..ec05c310e68d 100644 --- a/services/core/java/com/android/server/location/GnssMeasurementsProvider.java +++ b/services/core/java/com/android/server/location/GnssMeasurementsProvider.java @@ -105,15 +105,7 @@ public abstract class GnssMeasurementsProvider } /** Handle GNSS capabilities update from the GNSS HAL implementation. */ - public void onCapabilitiesUpdated(int capabilities, boolean hasSubHalCapabilityFlags) { - // The IGnssCallback.hal@2.0 removed sub-HAL capability flags from the Capabilities enum - // and instead uses the sub-HAL non-null handle returned from IGnss.hal@2.0 to indicate - // support. Therefore, the 'hasSubHalCapabilityFlags' parameter is needed to tell if the - // 'capabilities' parameter includes the sub-HAL capability flags or not. Old HALs - // which explicitly set the sub-HAL capability bits must continue to work. - final boolean isGnssMeasurementsSupported = hasSubHalCapabilityFlags - ? (capabilities & GnssLocationProvider.GPS_CAPABILITY_MEASUREMENTS) != 0 - : mNative.isMeasurementSupported(); + public void onCapabilitiesUpdated(boolean isGnssMeasurementsSupported) { setSupported(isGnssMeasurementsSupported); updateResult(); } diff --git a/services/core/java/com/android/server/location/GnssNavigationMessageProvider.java b/services/core/java/com/android/server/location/GnssNavigationMessageProvider.java index 7e8b599129c3..4c45ef665789 100644 --- a/services/core/java/com/android/server/location/GnssNavigationMessageProvider.java +++ b/services/core/java/com/android/server/location/GnssNavigationMessageProvider.java @@ -92,15 +92,7 @@ public abstract class GnssNavigationMessageProvider } /** Handle GNSS capabilities update from the GNSS HAL implementation */ - public void onCapabilitiesUpdated(int capabilities, boolean hasSubHalCapabilityFlags) { - // The IGnssCallback.hal@2.0 removed sub-HAL capability flags from the Capabilities enum - // and instead uses the sub-HAL non-null handle returned from IGnss.hal@2.0 to indicate - // support. Therefore, the 'hasSubHalCapabilityFlags' parameter is needed to tell if the - // 'capabilities' parameter includes the sub-HAL capability flags or not. Old HALs - // which explicitly set the sub-HAL capability bits must continue to work. - final boolean isGnssNavigationMessageSupported = hasSubHalCapabilityFlags - ? (capabilities & GnssLocationProvider.GPS_CAPABILITY_NAV_MESSAGES) != 0 - : mNative.isNavigationMessageSupported(); + public void onCapabilitiesUpdated(boolean isGnssNavigationMessageSupported) { setSupported(isGnssNavigationMessageSupported); updateResult(); } diff --git a/services/core/java/com/android/server/location/GnssNetworkConnectivityHandler.java b/services/core/java/com/android/server/location/GnssNetworkConnectivityHandler.java index c06b03b0063e..ab75b21e41ca 100644 --- a/services/core/java/com/android/server/location/GnssNetworkConnectivityHandler.java +++ b/services/core/java/com/android/server/location/GnssNetworkConnectivityHandler.java @@ -27,6 +27,7 @@ import android.os.Handler; import android.os.Looper; import android.os.PowerManager; import android.provider.Telephony.Carriers; +import android.telephony.ServiceState; import android.telephony.TelephonyManager; import android.util.Log; @@ -591,13 +592,25 @@ class GnssNetworkConnectivityHandler { } TelephonyManager phone = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE); + ServiceState serviceState = phone.getServiceState(); + String projection = null; + String selection = null; + // Carrier configuration may override framework roaming state, we need to use the actual // modem roaming state instead of the framework roaming state. - boolean isDataRoamingFromRegistration = phone.getServiceState() - .getDataRoamingFromRegistration(); - String projection = isDataRoamingFromRegistration ? Carriers.ROAMING_PROTOCOL : - Carriers.PROTOCOL; - String selection = String.format("current = 1 and apn = '%s' and carrier_enabled = 1", apn); + if (serviceState != null && serviceState.getDataRoamingFromRegistration()) { + projection = Carriers.ROAMING_PROTOCOL; + } else { + projection = Carriers.PROTOCOL; + } + // No SIM case for emergency + if (TelephonyManager.NETWORK_TYPE_UNKNOWN == phone.getNetworkType() + && AGPS_TYPE_EIMS == mAGpsType) { + selection = String.format( + "type like '%%emergency%%' and apn = '%s' and carrier_enabled = 1", apn); + } else { + selection = String.format("current = 1 and apn = '%s' and carrier_enabled = 1", apn); + } try (Cursor cursor = mContext.getContentResolver().query( Carriers.CONTENT_URI, new String[]{projection}, @@ -613,7 +626,7 @@ class GnssNetworkConnectivityHandler { Log.e(TAG, "Error encountered on APN query for: " + apn, e); } - return APN_INVALID; + return APN_IPV4V6; } private int translateToApnIpType(String ipProtocol, String apn) { @@ -630,7 +643,7 @@ class GnssNetworkConnectivityHandler { // we hit the default case so the ipProtocol is not recognized String message = String.format("Unknown IP Protocol: %s, for APN: %s", ipProtocol, apn); Log.e(TAG, message); - return APN_INVALID; + return APN_IPV4V6; } // AGPS support diff --git a/services/core/java/com/android/server/location/GnssSatelliteBlacklistHelper.java b/services/core/java/com/android/server/location/GnssSatelliteBlacklistHelper.java index 77951aa70bb5..eb99a851115f 100644 --- a/services/core/java/com/android/server/location/GnssSatelliteBlacklistHelper.java +++ b/services/core/java/com/android/server/location/GnssSatelliteBlacklistHelper.java @@ -20,7 +20,6 @@ import java.util.List; class GnssSatelliteBlacklistHelper { private static final String TAG = "GnssBlacklistHelper"; - private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); private static final String BLACKLIST_DELIMITER = ","; private final Context mContext; @@ -55,9 +54,7 @@ class GnssSatelliteBlacklistHelper { if (blacklist == null) { blacklist = ""; } - if (DEBUG) { - Log.d(TAG, String.format("Update GNSS satellite blacklist: %s", blacklist)); - } + Log.i(TAG, String.format("Update GNSS satellite blacklist: %s", blacklist)); List<Integer> blacklistValues; try { diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java index 75b62cb349af..af58b195a491 100644 --- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java +++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java @@ -1335,7 +1335,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { case TYPE_WARNING: { title = res.getText(R.string.data_usage_warning_title); body = res.getString(R.string.data_usage_warning_body, - Formatter.formatFileSize(mContext, totalBytes)); + Formatter.formatFileSize(mContext, totalBytes, Formatter.FLAG_IEC_UNITS)); builder.setSmallIcon(R.drawable.stat_notify_error); @@ -1383,7 +1383,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } final long overBytes = totalBytes - policy.limitBytes; body = res.getString(R.string.data_usage_limit_snoozed_body, - Formatter.formatFileSize(mContext, overBytes)); + Formatter.formatFileSize(mContext, overBytes, Formatter.FLAG_IEC_UNITS)); builder.setOngoing(true); builder.setSmallIcon(R.drawable.stat_notify_error); diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 20b898760389..bfab85b5211b 100644 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -17,7 +17,11 @@ package com.android.server.notification; import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; +import static android.app.Notification.FLAG_AUTOGROUP_SUMMARY; +import static android.app.Notification.FLAG_BUBBLE; import static android.app.Notification.FLAG_FOREGROUND_SERVICE; +import static android.app.Notification.FLAG_NO_CLEAR; +import static android.app.Notification.FLAG_ONGOING_EVENT; import static android.app.NotificationManager.ACTION_APP_BLOCK_STATE_CHANGED; import static android.app.NotificationManager.ACTION_NOTIFICATION_CHANNEL_BLOCK_STATE_CHANGED; import static android.app.NotificationManager.ACTION_NOTIFICATION_CHANNEL_GROUP_BLOCK_STATE_CHANGED; @@ -84,6 +88,7 @@ import static com.android.server.utils.PriorityDump.PRIORITY_ARG_NORMAL; import android.Manifest; import android.Manifest.permission; +import android.annotation.CallbackExecutor; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ActivityManager; @@ -107,6 +112,8 @@ import android.app.UriGrantsManager; import android.app.admin.DeviceAdminInfo; import android.app.admin.DevicePolicyManagerInternal; import android.app.backup.BackupManager; +import android.app.role.OnRoleHoldersChangedListener; +import android.app.role.RoleManager; import android.app.usage.UsageEvents; import android.app.usage.UsageStatsManagerInternal; import android.companion.ICompanionDeviceManager; @@ -151,6 +158,7 @@ import android.os.ShellCallback; import android.os.SystemClock; import android.os.SystemProperties; import android.os.UserHandle; +import android.os.UserManager; import android.os.VibrationEffect; import android.os.Vibrator; import android.provider.DeviceConfig; @@ -216,7 +224,6 @@ import com.android.server.lights.LightsManager; import com.android.server.notification.ManagedServices.ManagedServiceInfo; import com.android.server.notification.ManagedServices.UserProfiles; import com.android.server.pm.PackageManagerService; -import com.android.server.pm.UserManagerService; import com.android.server.policy.PhoneWindowManager; import com.android.server.statusbar.StatusBarManagerInternal; import com.android.server.uri.UriGrantsManagerInternal; @@ -249,6 +256,7 @@ import java.util.List; import java.util.Map.Entry; import java.util.Objects; import java.util.Set; +import java.util.concurrent.Executor; import java.util.concurrent.TimeUnit; import java.util.function.BiConsumer; @@ -300,6 +308,12 @@ public class NotificationManagerService extends SystemService { Adjustment.KEY_TEXT_REPLIES, Adjustment.KEY_USER_SENTIMENT}; + static final String[] NON_BLOCKABLE_DEFAULT_ROLES = new String[] { + RoleManager.ROLE_DIALER, + RoleManager.ROLE_SMS, + RoleManager.ROLE_EMERGENCY + }; + // When #matchesCallFilter is called from the ringer, wait at most // 3s to resolve the contacts. This timeout is required since // ContactsProvider might take a long time to start up. @@ -343,6 +357,8 @@ public class NotificationManagerService extends SystemService { private IDeviceIdleController mDeviceIdleController; private IUriGrantsManager mUgm; private UriGrantsManagerInternal mUgmInternal; + private RoleObserver mRoleObserver; + private UserManager mUm; final IBinder mForegroundToken = new Binder(); private WorkerHandler mHandler; @@ -553,18 +569,13 @@ public class NotificationManagerService extends SystemService { } } - UserManagerService getUserManagerService() { - return UserManagerService.getInstance(); - } - void readPolicyXml(InputStream stream, boolean forRestore, int userId) throws XmlPullParserException, NumberFormatException, IOException { final XmlPullParser parser = Xml.newPullParser(); parser.setInput(stream, StandardCharsets.UTF_8.name()); XmlUtils.beginDocument(parser, TAG_NOTIFICATION_POLICY); boolean migratedManagedServices = false; - boolean ineligibleForManagedServices = forRestore - && getUserManagerService().isManagedProfile(userId); + boolean ineligibleForManagedServices = forRestore && mUm.isManagedProfile(userId); int outerDepth = parser.getDepth(); while (XmlUtils.nextElementWithin(parser, outerDepth)) { if (ZenModeConfig.ZEN_TAG.equals(parser.getName())) { @@ -612,7 +623,8 @@ public class NotificationManagerService extends SystemService { mAssistants.resetDefaultAssistantsIfNecessary(); } - private void loadPolicyFile() { + @VisibleForTesting + protected void loadPolicyFile() { if (DBG) Slog.d(TAG, "loadPolicyFile"); synchronized (mPolicyFile) { InputStream infile = null; @@ -836,7 +848,7 @@ public class NotificationManagerService extends SystemService { } } cancelNotification(callingUid, callingPid, pkg, tag, id, 0, - Notification.FLAG_ONGOING_EVENT | FLAG_FOREGROUND_SERVICE, + FLAG_ONGOING_EVENT | FLAG_FOREGROUND_SERVICE, true, userId, REASON_CANCEL, nv.rank, nv.count,null); nv.recycle(); } @@ -1530,7 +1542,8 @@ public class NotificationManagerService extends SystemService { NotificationUsageStats usageStats, AtomicFile policyFile, ActivityManager activityManager, GroupHelper groupHelper, IActivityManager am, UsageStatsManagerInternal appUsageStats, DevicePolicyManagerInternal dpm, - IUriGrantsManager ugm, UriGrantsManagerInternal ugmInternal, AppOpsManager appOps) { + IUriGrantsManager ugm, UriGrantsManagerInternal ugmInternal, AppOpsManager appOps, + UserManager userManager) { Resources resources = getContext().getResources(); mMaxPackageEnqueueRate = Settings.Global.getFloat(getContext().getContentResolver(), Settings.Global.MAX_NOTIFICATION_ENQUEUE_RATE, @@ -1552,6 +1565,7 @@ public class NotificationManagerService extends SystemService { mDeviceIdleController = IDeviceIdleController.Stub.asInterface( ServiceManager.getService(Context.DEVICE_IDLE_CONTROLLER)); mDpm = dpm; + mUm = userManager; mHandler = new WorkerHandler(looper); mRankingThread.start(); @@ -1697,14 +1711,16 @@ public class NotificationManagerService extends SystemService { AppGlobals.getPackageManager()), new ConditionProviders(getContext(), mUserProfiles, AppGlobals.getPackageManager()), null, snoozeHelper, new NotificationUsageStats(getContext()), - new AtomicFile(new File(systemDir, "notification_policy.xml"), "notification-policy"), + new AtomicFile(new File( + systemDir, "notification_policy.xml"), "notification-policy"), (ActivityManager) getContext().getSystemService(Context.ACTIVITY_SERVICE), getGroupHelper(), ActivityManager.getService(), LocalServices.getService(UsageStatsManagerInternal.class), LocalServices.getService(DevicePolicyManagerInternal.class), UriGrantsManager.getService(), LocalServices.getService(UriGrantsManagerInternal.class), - (AppOpsManager) getContext().getSystemService(Context.APP_OPS_SERVICE)); + (AppOpsManager) getContext().getSystemService(Context.APP_OPS_SERVICE), + getContext().getSystemService(UserManager.class)); // register for various Intents IntentFilter filter = new IntentFilter(); @@ -1827,6 +1843,9 @@ public class NotificationManagerService extends SystemService { mAudioManagerInternal = getLocalService(AudioManagerInternal.class); mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class); mZenModeHelper.onSystemReady(); + mRoleObserver = new RoleObserver(getContext().getSystemService(RoleManager.class), + getContext().getMainExecutor()); + mRoleObserver.init(); } else if (phase == SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) { // This observer will force an update when observe is called, causing us to // bind to listener services. @@ -2324,7 +2343,7 @@ public class NotificationManagerService extends SystemService { // Don't allow client applications to cancel foreground service notis or autobundled // summaries. final int mustNotHaveFlags = isCallingUidSystem() ? 0 : - (FLAG_FOREGROUND_SERVICE | Notification.FLAG_AUTOGROUP_SUMMARY); + (FLAG_FOREGROUND_SERVICE | FLAG_AUTOGROUP_SUMMARY); cancelNotification(Binder.getCallingUid(), Binder.getCallingPid(), pkg, tag, id, 0, mustNotHaveFlags, false, userId, REASON_APP_CANCEL, null); } @@ -3128,7 +3147,7 @@ public class NotificationManagerService extends SystemService { private void cancelNotificationFromListenerLocked(ManagedServiceInfo info, int callingUid, int callingPid, String pkg, String tag, int id, int userId) { cancelNotification(callingUid, callingPid, pkg, tag, id, 0, - Notification.FLAG_ONGOING_EVENT | FLAG_FOREGROUND_SERVICE, + FLAG_ONGOING_EVENT | FLAG_FOREGROUND_SERVICE | FLAG_BUBBLE, true, userId, REASON_LISTENER_CANCEL, info); } @@ -4219,7 +4238,7 @@ public class NotificationManagerService extends SystemService { .setGroupSummary(true) .setGroupAlertBehavior(Notification.GROUP_ALERT_CHILDREN) .setGroup(GroupHelper.AUTOGROUP_KEY) - .setFlag(Notification.FLAG_AUTOGROUP_SUMMARY, true) + .setFlag(FLAG_AUTOGROUP_SUMMARY, true) .setFlag(Notification.FLAG_GROUP_SUMMARY, true) .setColor(adjustedSbn.getNotification().color) .setLocalOnly(true) @@ -4740,6 +4759,20 @@ public class NotificationManagerService extends SystemService { } } + /** + * Updates the flags for this notification to reflect whether it is a bubble or not. + */ + private void flagNotificationForBubbles(NotificationRecord r, String pkg, int userId) { + Notification notification = r.getNotification(); + boolean canBubble = mPreferencesHelper.areBubblesAllowed(pkg, userId) + && r.getChannel().canBubble(); + if (notification.getBubbleMetadata() != null && canBubble) { + notification.flags |= FLAG_BUBBLE; + } else { + notification.flags &= ~FLAG_BUBBLE; + } + } + private void doChannelWarningToast(CharSequence toastText) { Binder.withCleanCallingIdentity(() -> { final int defaultWarningEnabled = Build.IS_DEBUGGABLE ? 1 : 0; @@ -5095,6 +5128,9 @@ public class NotificationManagerService extends SystemService { final int id = n.getId(); final String tag = n.getTag(); + // We need to fix the notification up a little for bubbles + flagNotificationForBubbles(r, pkg, callingUid); + // Handle grouped notifications and bail out early if we // can to avoid extracting signals. handleGroupedNotificationLocked(r, old, callingUid, callingPid); @@ -5196,8 +5232,8 @@ public class NotificationManagerService extends SystemService { // Ensure if this is a foreground service that the proper additional // flags are set. if ((notification.flags & FLAG_FOREGROUND_SERVICE) != 0) { - notification.flags |= Notification.FLAG_ONGOING_EVENT - | Notification.FLAG_NO_CLEAR; + notification.flags |= FLAG_ONGOING_EVENT + | FLAG_NO_CLEAR; } mRankingHelper.extractSignals(r); @@ -6654,8 +6690,11 @@ public class NotificationManagerService extends SystemService { null, userId, 0, 0, reason, listenerName); FlagChecker flagChecker = (int flags) -> { - if ((flags & (Notification.FLAG_ONGOING_EVENT | Notification.FLAG_NO_CLEAR)) - != 0) { + int flagsToCheck = FLAG_ONGOING_EVENT | FLAG_NO_CLEAR; + if (REASON_LISTENER_CANCEL_ALL == reason) { + flagsToCheck |= FLAG_BUBBLE; + } + if ((flags & flagsToCheck) != 0) { return false; } return true; @@ -8074,6 +8113,98 @@ public class NotificationManagerService extends SystemService { } } + class RoleObserver implements OnRoleHoldersChangedListener { + // Role name : user id : list of approved packages + private ArrayMap<String, ArrayMap<Integer, ArraySet<String>>> mNonBlockableDefaultApps; + + private final RoleManager mRm; + private final Executor mExecutor; + + RoleObserver(@NonNull RoleManager roleManager, + @NonNull @CallbackExecutor Executor executor) { + mRm = roleManager; + mExecutor = executor; + } + + public void init() { + List<UserInfo> users = mUm.getUsers(); + mNonBlockableDefaultApps = new ArrayMap<>(); + for (int i = 0; i < NON_BLOCKABLE_DEFAULT_ROLES.length; i++) { + final ArrayMap<Integer, ArraySet<String>> userToApprovedList = new ArrayMap<>(); + mNonBlockableDefaultApps.put(NON_BLOCKABLE_DEFAULT_ROLES[i], userToApprovedList); + for (int j = 0; j < users.size(); j++) { + Integer userId = users.get(j).getUserHandle().getIdentifier(); + ArraySet<String> approvedForUserId = new ArraySet<>(mRm.getRoleHoldersAsUser( + NON_BLOCKABLE_DEFAULT_ROLES[i], UserHandle.of(userId))); + userToApprovedList.put(userId, approvedForUserId); + mPreferencesHelper.updateDefaultApps(userId, null, approvedForUserId); + } + } + + mRm.addOnRoleHoldersChangedListenerAsUser(mExecutor, this, UserHandle.ALL); + } + + @VisibleForTesting + public boolean isApprovedPackageForRoleForUser(String role, String pkg, int userId) { + return mNonBlockableDefaultApps.get(role).get(userId).contains(pkg); + } + + /** + * Convert the assistant-role holder into settings. The rest of the system uses the + * settings. + * + * @param roleName the name of the role whose holders are changed + * @param user the user for this role holder change + */ + @Override + public void onRoleHoldersChanged(@NonNull String roleName, @NonNull UserHandle user) { + // we only care about a couple of the roles they'll tell us about + boolean relevantChange = false; + for (int i = 0; i < NON_BLOCKABLE_DEFAULT_ROLES.length; i++) { + if (NON_BLOCKABLE_DEFAULT_ROLES[i].equals(roleName)) { + relevantChange = true; + break; + } + } + + if (!relevantChange) { + return; + } + + ArraySet<String> roleHolders = new ArraySet<>(mRm.getRoleHoldersAsUser(roleName, user)); + + // find the diff + ArrayMap<Integer, ArraySet<String>> prevApprovedForRole = + mNonBlockableDefaultApps.getOrDefault(roleName, new ArrayMap<>()); + ArraySet<String> previouslyApproved = + prevApprovedForRole.getOrDefault(user.getIdentifier(), new ArraySet<>()); + + ArraySet<String> toRemove = new ArraySet<>(); + ArraySet<String> toAdd = new ArraySet<>(); + + for (String previous : previouslyApproved) { + if (!roleHolders.contains(previous)) { + toRemove.add(previous); + } + } + for (String nowApproved : roleHolders) { + if (!previouslyApproved.contains(nowApproved)) { + toAdd.add(nowApproved); + } + } + + // store newly approved apps + prevApprovedForRole.put(user.getIdentifier(), roleHolders); + mNonBlockableDefaultApps.put(roleName, prevApprovedForRole); + + // update what apps can be blocked + mPreferencesHelper.updateDefaultApps(user.getIdentifier(), toRemove, toAdd); + + // RoleManager is the source of truth for this data so we don't need to trigger a + // write of the notification policy xml for this change + } + } + public static final class DumpFilter { public boolean filtered = false; public String pkgFilter; diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java index de9312041c41..4ed24ec7971b 100644 --- a/services/core/java/com/android/server/notification/NotificationRecord.java +++ b/services/core/java/com/android/server/notification/NotificationRecord.java @@ -783,7 +783,8 @@ public final class NotificationRecord { // Consider Notification Assistant and system overrides to importance. If both, system wins. if (!getChannel().hasUserSetImportance() && mAssistantImportance != IMPORTANCE_UNSPECIFIED - && !getChannel().isImportanceLockedByOEM()) { + && !getChannel().isImportanceLockedByOEM() + && !getChannel().isImportanceLockedByCriticalDeviceFunction()) { mImportance = mAssistantImportance; mImportanceExplanationCode = MetricsEvent.IMPORTANCE_EXPLANATION_ASST; } @@ -1290,13 +1291,11 @@ public final class NotificationRecord { lm.addTaggedData(MetricsEvent.FIELD_NOTIFICATION_IMPORTANCE_INITIAL, stats.naturalImportance); } - // Log Assistant override if it was itself overridden by System. Since System can't be - // overridden, it never needs logging. - if (mImportanceExplanationCode == MetricsEvent.IMPORTANCE_EXPLANATION_SYSTEM - && mAssistantImportance != IMPORTANCE_UNSPECIFIED) { - lm.addTaggedData(MetricsEvent.FIELD_NOTIFICATION_IMPORTANCE_ASST, + } + // Log Assistant override if present, whether or not importance calculation is complete. + if (mAssistantImportance != IMPORTANCE_UNSPECIFIED) { + lm.addTaggedData(MetricsEvent.FIELD_NOTIFICATION_IMPORTANCE_ASST, mAssistantImportance); - } } return lm; } diff --git a/services/core/java/com/android/server/notification/PreferencesHelper.java b/services/core/java/com/android/server/notification/PreferencesHelper.java index 660309cd578d..a3e90dcff83e 100644 --- a/services/core/java/com/android/server/notification/PreferencesHelper.java +++ b/services/core/java/com/android/server/notification/PreferencesHelper.java @@ -37,6 +37,8 @@ import android.service.notification.NotificationListenerService; import android.service.notification.RankingHelperProto; import android.text.TextUtils; import android.util.ArrayMap; +import android.util.ArraySet; +import android.util.Pair; import android.util.Slog; import android.util.SparseBooleanArray; import android.util.proto.ProtoOutputStream; @@ -100,6 +102,7 @@ public class PreferencesHelper implements RankingConfig { private static final boolean DEFAULT_SHOW_BADGE = true; private static final boolean DEFAULT_ALLOW_BUBBLE = true; private static final boolean DEFAULT_OEM_LOCKED_IMPORTANCE = false; + private static final boolean DEFAULT_APP_LOCKED_IMPORTANCE = false; /** * Default value for what fields are user locked. See {@link LockableAppFields} for all lockable @@ -659,6 +662,7 @@ public class PreferencesHelper implements RankingConfig { channel.setImportanceLockedByOEM(true); } } + channel.setImportanceLockedByCriticalDeviceFunction(r.defaultAppLockedImportance); if (channel.getLockscreenVisibility() == Notification.VISIBILITY_PUBLIC) { channel.setLockscreenVisibility( NotificationListenerService.Ranking.VISIBILITY_NO_OVERRIDE); @@ -707,6 +711,10 @@ public class PreferencesHelper implements RankingConfig { if (updatedChannel.isImportanceLockedByOEM()) { updatedChannel.setImportance(channel.getImportance()); } + updatedChannel.setImportanceLockedByCriticalDeviceFunction(r.defaultAppLockedImportance); + if (updatedChannel.isImportanceLockedByCriticalDeviceFunction()) { + updatedChannel.setImportance(channel.getImportance()); + } r.channels.put(updatedChannel.getId(), updatedChannel); @@ -844,6 +852,26 @@ public class PreferencesHelper implements RankingConfig { } } + public void updateDefaultApps(int userId, ArraySet<String> toRemove, ArraySet<String> toAdd) { + synchronized (mPackagePreferences) { + for (PackagePreferences p : mPackagePreferences.values()) { + if (userId == UserHandle.getUserId(p.uid)) { + if (toRemove != null && toRemove.contains(p.pkg)) { + p.defaultAppLockedImportance = false; + for (NotificationChannel channel : p.channels.values()) { + channel.setImportanceLockedByCriticalDeviceFunction(false); + } + } else if (toAdd != null && toAdd.contains(p.pkg)) { + p.defaultAppLockedImportance = true; + for (NotificationChannel channel : p.channels.values()) { + channel.setImportanceLockedByCriticalDeviceFunction(true); + } + } + } + } + } + } + public NotificationChannelGroup getNotificationChannelGroupWithChannels(String pkg, int uid, String groupId, boolean includeDeleted) { Preconditions.checkNotNull(pkg); @@ -1729,8 +1757,11 @@ public class PreferencesHelper implements RankingConfig { boolean showBadge = DEFAULT_SHOW_BADGE; boolean allowBubble = DEFAULT_ALLOW_BUBBLE; int lockedAppFields = DEFAULT_LOCKED_APP_FIELDS; + // these fields are loaded on boot from a different source of truth and so are not + // written to notification policy xml boolean oemLockedImportance = DEFAULT_OEM_LOCKED_IMPORTANCE; List<String> futureOemLockedChannels = new ArrayList<>(); + boolean defaultAppLockedImportance = DEFAULT_APP_LOCKED_IMPORTANCE; Delegate delegate = null; ArrayMap<String, NotificationChannel> channels = new ArrayMap<>(); diff --git a/services/core/java/com/android/server/om/OverlayManagerService.java b/services/core/java/com/android/server/om/OverlayManagerService.java index 37dd63a2f745..6e98d6e67844 100644 --- a/services/core/java/com/android/server/om/OverlayManagerService.java +++ b/services/core/java/com/android/server/om/OverlayManagerService.java @@ -345,7 +345,7 @@ public final class OverlayManagerService extends SystemService { switch (action) { case ACTION_PACKAGE_ADDED: if (replacing) { - onPackageUpgraded(packageName, userIds); + onPackageReplaced(packageName, userIds); } else { onPackageAdded(packageName, userIds); } @@ -355,7 +355,7 @@ public final class OverlayManagerService extends SystemService { break; case ACTION_PACKAGE_REMOVED: if (replacing) { - onPackageUpgrading(packageName, userIds); + onPackageReplacing(packageName, userIds); } else { onPackageRemoved(packageName, userIds); } @@ -412,18 +412,16 @@ public final class OverlayManagerService extends SystemService { } } - private void onPackageUpgrading(@NonNull final String packageName, + private void onPackageReplacing(@NonNull final String packageName, @NonNull final int[] userIds) { try { - traceBegin(TRACE_TAG_RRO, "OMS#onPackageUpgrading " + packageName); + traceBegin(TRACE_TAG_RRO, "OMS#onPackageReplacing " + packageName); for (int userId : userIds) { synchronized (mLock) { mPackageManager.forgetPackageInfo(packageName, userId); final OverlayInfo oi = mImpl.getOverlayInfo(packageName, userId); if (oi != null) { - mImpl.onOverlayPackageUpgrading(packageName, userId); - } else { - mImpl.onTargetPackageUpgrading(packageName, userId); + mImpl.onOverlayPackageReplacing(packageName, userId); } } } @@ -432,10 +430,10 @@ public final class OverlayManagerService extends SystemService { } } - private void onPackageUpgraded(@NonNull final String packageName, + private void onPackageReplaced(@NonNull final String packageName, @NonNull final int[] userIds) { try { - traceBegin(TRACE_TAG_RRO, "OMS#onPackageUpgraded " + packageName); + traceBegin(TRACE_TAG_RRO, "OMS#onPackageReplaced " + packageName); for (int userId : userIds) { synchronized (mLock) { final PackageInfo pi = mPackageManager.getPackageInfo(packageName, userId, @@ -443,9 +441,9 @@ public final class OverlayManagerService extends SystemService { if (pi != null) { mPackageManager.cachePackageInfo(packageName, userId, pi); if (pi.isOverlayPackage()) { - mImpl.onOverlayPackageUpgraded(packageName, userId); + mImpl.onOverlayPackageReplaced(packageName, userId); } else { - mImpl.onTargetPackageUpgraded(packageName, userId); + mImpl.onTargetPackageReplaced(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..ec53e98ec547 100644 --- a/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java +++ b/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java @@ -21,8 +21,8 @@ import static android.content.om.OverlayInfo.STATE_ENABLED; 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 android.content.om.OverlayInfo.STATE_OVERLAY_IS_BEING_REPLACED; +import static android.content.om.OverlayInfo.STATE_TARGET_IS_BEING_REPLACED; import static com.android.server.om.OverlayManagerService.DEBUG; import static com.android.server.om.OverlayManagerService.TAG; @@ -30,12 +30,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,9 +57,14 @@ import java.util.Set; * @see OverlayManagerService */ final class OverlayManagerServiceImpl { + /** + * @deprecated Not used. See {@link android.content.om.OverlayInfo#STATE_TARGET_UPGRADING}. + */ + @Deprecated + private static final int FLAG_TARGET_IS_BEING_REPLACED = 1 << 0; + // Flags to use in conjunction with updateState. - private static final int FLAG_TARGET_IS_UPGRADING = 1 << 0; - private static final int FLAG_OVERLAY_IS_UPGRADING = 1 << 1; + private static final int FLAG_OVERLAY_IS_BEING_REPLACED = 1 << 1; private final PackageManagerHelper mPackageManager; private final IdmapManager mIdmapManager; @@ -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,24 +263,24 @@ final class OverlayManagerServiceImpl { Slog.d(TAG, "onTargetPackageChanged packageName=" + packageName + " userId=" + userId); } - updateAllOverlaysForTarget(packageName, userId, 0); + updateAndRefreshOverlaysForTarget(packageName, userId, 0); } - void onTargetPackageUpgrading(@NonNull final String packageName, final int userId) { + void onTargetPackageReplacing(@NonNull final String packageName, final int userId) { if (DEBUG) { - Slog.d(TAG, "onTargetPackageUpgrading packageName=" + packageName + " userId=" + Slog.d(TAG, "onTargetPackageReplacing packageName=" + packageName + " userId=" + userId); } - updateAllOverlaysForTarget(packageName, userId, FLAG_TARGET_IS_UPGRADING); + updateAndRefreshOverlaysForTarget(packageName, userId, 0); } - void onTargetPackageUpgraded(@NonNull final String packageName, final int userId) { + void onTargetPackageReplaced(@NonNull final String packageName, final int userId) { if (DEBUG) { - Slog.d(TAG, "onTargetPackageUpgraded packageName=" + packageName + " userId=" + userId); + Slog.d(TAG, "onTargetPackageReplaced packageName=" + packageName + " userId=" + userId); } - updateAllOverlaysForTarget(packageName, userId, 0); + updateAndRefreshOverlaysForTarget(packageName, userId, 0); } void onTargetPackageRemoved(@NonNull final String packageName, final int userId) { @@ -282,22 +288,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 +324,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) { @@ -364,15 +397,16 @@ final class OverlayManagerServiceImpl { } } - void onOverlayPackageUpgrading(@NonNull final String packageName, final int userId) { + void onOverlayPackageReplacing(@NonNull final String packageName, final int userId) { if (DEBUG) { - Slog.d(TAG, "onOverlayPackageUpgrading packageName=" + packageName + " userId=" + Slog.d(TAG, "onOverlayPackageReplacing packageName=" + packageName + " userId=" + userId); } try { final OverlayInfo oi = mSettings.getOverlayInfo(packageName, userId); - if (updateState(oi.targetPackageName, packageName, userId, FLAG_OVERLAY_IS_UPGRADING)) { + if (updateState(oi.targetPackageName, packageName, userId, + FLAG_OVERLAY_IS_BEING_REPLACED)) { removeIdmapIfPossible(oi); mListener.onOverlaysChanged(oi.targetPackageName, userId); } @@ -381,15 +415,15 @@ final class OverlayManagerServiceImpl { } } - void onOverlayPackageUpgraded(@NonNull final String packageName, final int userId) { + void onOverlayPackageReplaced(@NonNull final String packageName, final int userId) { if (DEBUG) { - Slog.d(TAG, "onOverlayPackageUpgraded packageName=" + packageName + " userId=" + Slog.d(TAG, "onOverlayPackageReplaced packageName=" + packageName + " userId=" + userId); } final PackageInfo pkg = mPackageManager.getPackageInfo(packageName, userId); if (pkg == null) { - Slog.w(TAG, "overlay package " + packageName + " was upgraded, but couldn't be found"); + Slog.w(TAG, "overlay package " + packageName + " was replaced, but couldn't be found"); onOverlayPackageRemoved(packageName, userId); return; } @@ -670,12 +704,12 @@ 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_TARGET_IS_BEING_REPLACED) != 0) { + return STATE_TARGET_IS_BEING_REPLACED; } - if ((flags & FLAG_OVERLAY_IS_UPGRADING) != 0) { - return STATE_OVERLAY_UPGRADING; + if ((flags & FLAG_OVERLAY_IS_BEING_REPLACED) != 0) { + return STATE_OVERLAY_IS_BEING_REPLACED; } // assert expectation on overlay package: can only be null if the flags are used diff --git a/services/core/java/com/android/server/om/OverlayManagerSettings.java b/services/core/java/com/android/server/om/OverlayManagerSettings.java index 667dfa19af15..36b5beb7bbb2 100644 --- a/services/core/java/com/android/server/om/OverlayManagerSettings.java +++ b/services/core/java/com/android/server/om/OverlayManagerSettings.java @@ -309,7 +309,6 @@ final class OverlayManagerSettings { pw.println("mTargetOverlayableName.: " + item.getTargetOverlayableName()); pw.println("mBaseCodePath..........: " + item.getBaseCodePath()); pw.println("mState.................: " + OverlayInfo.stateToString(item.getState())); - pw.println("mState.................: " + OverlayInfo.stateToString(item.getState())); pw.println("mIsEnabled.............: " + item.isEnabled()); pw.println("mIsStatic..............: " + item.isStatic()); pw.println("mPriority..............: " + item.mPriority); diff --git a/services/core/java/com/android/server/pm/ApexManager.java b/services/core/java/com/android/server/pm/ApexManager.java index 5fdd872409c0..944aef5ab223 100644 --- a/services/core/java/com/android/server/pm/ApexManager.java +++ b/services/core/java/com/android/server/pm/ApexManager.java @@ -27,6 +27,7 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; import android.content.pm.PackageParser; import android.content.pm.PackageParser.PackageParserException; import android.os.RemoteException; @@ -95,7 +96,8 @@ class ApexManager { } try { list.add(PackageParser.generatePackageInfoFromApex( - new File(ai.packagePath), true /* collect certs */)); + new File(ai.packagePath), PackageManager.GET_META_DATA + | PackageManager.GET_SIGNING_CERTIFICATES)); } catch (PackageParserException pe) { throw new IllegalStateException("Unable to parse: " + ai, pe); } diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java index afa5ae907fc0..e4cb283fe864 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerService.java +++ b/services/core/java/com/android/server/pm/PackageInstallerService.java @@ -360,7 +360,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements final long age = System.currentTimeMillis() - session.createdMillis; final long timeSinceUpdate = - System.currentTimeMillis() - session.updatedMillis; + System.currentTimeMillis() - session.getUpdatedMillis(); final boolean valid; if (session.isStaged()) { if (timeSinceUpdate >= MAX_TIME_SINCE_UPDATE_MILLIS @@ -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") @@ -493,10 +498,11 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements } } - if (callingUid == Process.SYSTEM_UID) { + if (Build.IS_DEBUGGABLE || isDowngradeAllowedForCaller(callingUid)) { params.installFlags |= PackageManager.INSTALL_ALLOW_DOWNGRADE; } else { params.installFlags &= ~PackageManager.INSTALL_ALLOW_DOWNGRADE; + params.installFlags &= ~PackageManager.INSTALL_REQUEST_DOWNGRADE; } boolean isApex = (params.installFlags & PackageManager.INSTALL_APEX) != 0; @@ -616,6 +622,11 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements return sessionId; } + private boolean isDowngradeAllowedForCaller(int callingUid) { + return callingUid == Process.SYSTEM_UID || callingUid == Process.ROOT_UID + || callingUid == Process.SHELL_UID; + } + @Override public void updateSessionAppIcon(int sessionId, Bitmap appIcon) { synchronized (mSessions) { @@ -808,7 +819,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements final PackageDeleteObserverAdapter adapter = new PackageDeleteObserverAdapter(mContext, statusReceiver, versionedPackage.getPackageName(), - !canSilentlyInstallPackage, userId); + canSilentlyInstallPackage, userId); if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DELETE_PACKAGES) == PackageManager.PERMISSION_GRANTED) { // Sweet, call straight through! diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java index f1d4524cccac..d2a160b29a8b 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerSession.java +++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java @@ -202,7 +202,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { /** Timestamp of the last time this session changed state */ @GuardedBy("mLock") - long updatedMillis; + private long updatedMillis; /** Uid of the creator of this session. */ private final int mOriginalInstallerUid; @@ -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() { @@ -844,17 +837,34 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { @Override public void commit(@NonNull IntentSender statusReceiver, boolean forTransfer) { - if (!markAsCommitted(statusReceiver, forTransfer /* enforce */)) { + if (!markAsCommitted(statusReceiver, forTransfer)) { return; } if (isMultiPackage()) { - final SparseIntArray remainingSessions = mChildSessionIds.clone(); - final ChildStatusIntentReceiver localIntentReceiver = - new ChildStatusIntentReceiver(remainingSessions, statusReceiver); - for (int childSessionId : getChildSessionIds()) { - mSessionProvider.getSession(childSessionId) - .markAsCommitted(localIntentReceiver.getIntentSender(), forTransfer); + final IntentSender childIntentSender = + new ChildStatusIntentReceiver(remainingSessions, statusReceiver) + .getIntentSender(); + RuntimeException commitException = null; + boolean commitFailed = false; + for (int i = mChildSessionIds.size() - 1; i >= 0; --i) { + final int childSessionId = mChildSessionIds.keyAt(i); + try { + // commit all children, regardless if any of them fail; we'll throw/return + // as appropriate once all children have been processed + if (!mSessionProvider.getSession(childSessionId) + .markAsCommitted(childIntentSender, forTransfer)) { + commitFailed = true; + } + } catch (RuntimeException e) { + commitException = e; + } + } + if (commitException != null) { + throw commitException; + } + if (commitFailed) { + return; } } mHandler.obtainMessage(MSG_COMMIT).sendToTarget(); @@ -932,6 +942,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 +975,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 +1006,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 +1130,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 +1190,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 +1248,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) { @@ -1741,6 +1850,15 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } } + /** + * @return the timestamp of when this session last changed state + */ + public long getUpdatedMillis() { + synchronized (mLock) { + return updatedMillis; + } + } + String getInstallerPackageName() { synchronized (mLock) { return mInstallerPackageName; @@ -1965,15 +2083,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 eec1e539b2d7..098225f9e820 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -1941,8 +1941,13 @@ public class PackageManagerService extends IPackageManager.Stub // Send broadcast package appeared if external for all users if (isExternal(res.pkg)) { if (!update) { + final StorageManager storage = + mContext.getSystemService(StorageManager.class); + VolumeInfo volume = + storage.findVolumeByUuid( + res.pkg.applicationInfo.storageUuid.toString()); int packageExternalStorageType = - getPackageExternalStorageType(res.pkg); + getPackageExternalStorageType(volume, isExternal(res.pkg)); // If the package was installed externally, log it. if (packageExternalStorageType != StorageEnums.UNKNOWN) { StatsLog.write(StatsLog.APP_INSTALL_ON_EXTERNAL_STORAGE_REPORTED, @@ -2039,15 +2044,16 @@ public class PackageManagerService extends IPackageManager.Stub /** * Gets the type of the external storage a package is installed on. - * @param pkg The package for which to get the external storage type. - * @return {@link StorageEnum#TYPE_UNKNOWN} if it is not stored externally or the corresponding - * {@link StorageEnum} storage type value if it is. + * @param packageVolume The storage volume of the package. + * @param packageIsExternal true if the package is currently installed on + * external/removable/unprotected storage. + * @return {@link StorageEnum#TYPE_UNKNOWN} if the package is not stored externally or the + * corresponding {@link StorageEnum} storage type value if it is. */ - private int getPackageExternalStorageType(PackageParser.Package pkg) { - final StorageManager storage = mContext.getSystemService(StorageManager.class); - VolumeInfo volume = storage.findVolumeByUuid(pkg.applicationInfo.storageUuid.toString()); - if (volume != null) { - DiskInfo disk = volume.getDisk(); + private static int getPackageExternalStorageType(VolumeInfo packageVolume, + boolean packageIsExternal) { + if (packageVolume != null) { + DiskInfo disk = packageVolume.getDisk(); if (disk != null) { if (disk.isSd()) { return StorageEnums.SD_CARD; @@ -2055,7 +2061,7 @@ public class PackageManagerService extends IPackageManager.Stub if (disk.isUsb()) { return StorageEnums.USB; } - if (isExternal(pkg)) { + if (packageIsExternal) { return StorageEnums.OTHER; } } @@ -2965,7 +2971,7 @@ public class PackageManagerService extends IPackageManager.Stub // Now that we know all of the shared libraries, update all clients to have // the correct library paths. - updateAllSharedLibrariesLPw(null); + updateAllSharedLibrariesLocked(null, Collections.unmodifiableMap(mPackages)); for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) { // NOTE: We ignore potential failures here during a system scan (like @@ -3496,7 +3502,7 @@ public class PackageManagerService extends IPackageManager.Stub private @NonNull String getRequiredInstallerLPr() { final Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE); intent.addCategory(Intent.CATEGORY_DEFAULT); - intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE); + intent.setDataAndType(Uri.parse("content://com.example/foo.apk"), PACKAGE_MIME_TYPE); final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE, MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, @@ -10016,11 +10022,11 @@ public class PackageManagerService extends IPackageManager.Stub } @GuardedBy("mPackages") - private void updateSharedLibrariesLPr(PackageParser.Package pkg, - PackageParser.Package changingLib) throws PackageManagerException { + private void updateSharedLibrariesLocked(PackageParser.Package pkg, + PackageParser.Package changingLib, Map<String, PackageParser.Package> availablePackages) + throws PackageManagerException { final ArrayList<SharedLibraryInfo> sharedLibraryInfos = - collectSharedLibraryInfos(pkg, Collections.unmodifiableMap(mPackages), - mSharedLibraries, null); + collectSharedLibraryInfos(pkg, availablePackages, mSharedLibraries, null); executeSharedLibrariesUpdateLPr(pkg, changingLib, sharedLibraryInfos); } @@ -10112,7 +10118,6 @@ public class PackageManagerService extends IPackageManager.Stub + " library " + libName + " version " + libraryInfo.getLongVersion() + "; failing!"); } - PackageParser.Package libPkg = availablePackages.get(libraryInfo.getPackageName()); if (libPkg == null) { @@ -10120,12 +10125,8 @@ public class PackageManagerService extends IPackageManager.Stub "Package " + packageName + " requires unavailable static shared" + " library; failing!"); } - final String[] expectedCertDigests = requiredCertDigests[i]; - - if (expectedCertDigests.length > 1) { - // For apps targeting O MR1 we require explicit enumeration of all certs. final String[] libCertDigests = (targetSdk >= Build.VERSION_CODES.O_MR1) ? PackageUtils.computeSignaturesSha256Digests( @@ -10157,7 +10158,6 @@ public class PackageManagerService extends IPackageManager.Stub } } } else { - // lib signing cert could have rotated beyond the one expected, check to see // if the new one has been blessed by the old if (!libPkg.mSigningDetails.hasSha256Certificate( @@ -10169,7 +10169,6 @@ public class PackageManagerService extends IPackageManager.Stub } } } - if (outUsedLibraries == null) { outUsedLibraries = new ArrayList<>(); } @@ -10180,7 +10179,7 @@ public class PackageManagerService extends IPackageManager.Stub } private static boolean hasString(List<String> list, List<String> which) { - if (list == null) { + if (list == null || which == null) { return false; } for (int i=list.size()-1; i>=0; i--) { @@ -10194,39 +10193,63 @@ public class PackageManagerService extends IPackageManager.Stub } @GuardedBy("mPackages") - private ArrayList<PackageParser.Package> updateAllSharedLibrariesLPw( - PackageParser.Package changingPkg) { - ArrayList<PackageParser.Package> res = null; - for (PackageParser.Package pkg : mPackages.values()) { - if (changingPkg != null - && !hasString(pkg.usesLibraries, changingPkg.libraryNames) - && !hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames) - && !ArrayUtils.contains(pkg.usesStaticLibraries, - changingPkg.staticSharedLibName)) { - return null; - } - if (res == null) { - res = new ArrayList<>(); - } - res.add(pkg); - try { - updateSharedLibrariesLPr(pkg, changingPkg); - } catch (PackageManagerException e) { - // If a system app update or an app and a required lib missing we - // delete the package and for updated system apps keep the data as - // it is better for the user to reinstall than to be in an limbo - // state. Also libs disappearing under an app should never happen - // - just in case. - if (!pkg.isSystem() || pkg.isUpdatedSystemApp()) { - final int flags = pkg.isUpdatedSystemApp() - ? PackageManager.DELETE_KEEP_DATA : 0; - deletePackageLIF(pkg.packageName, null, true, sUserManager.getUserIds(), - flags , null, true, null); + private ArrayList<PackageParser.Package> updateAllSharedLibrariesLocked( + PackageParser.Package updatedPkg, + Map<String, PackageParser.Package> availablePackages) { + ArrayList<PackageParser.Package> resultList = null; + // Set of all descendants of a library; used to eliminate cycles + ArraySet<String> descendants = null; + // The current list of packages that need updating + ArrayList<PackageParser.Package> needsUpdating = null; + if (updatedPkg != null) { + needsUpdating = new ArrayList<>(1); + needsUpdating.add(updatedPkg); + } + do { + final PackageParser.Package changingPkg = + (needsUpdating == null) ? null : needsUpdating.remove(0); + for (int i = mPackages.size() - 1; i >= 0; --i) { + final PackageParser.Package pkg = mPackages.valueAt(i); + if (changingPkg != null + && !hasString(pkg.usesLibraries, changingPkg.libraryNames) + && !hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames) + && !ArrayUtils.contains(pkg.usesStaticLibraries, + changingPkg.staticSharedLibName)) { + continue; + } + if (resultList == null) { + resultList = new ArrayList<>(); + } + resultList.add(pkg); + // if we're updating a shared library, all of its descendants must be updated + if (changingPkg != null) { + if (descendants == null) { + descendants = new ArraySet<>(); + } + if (!descendants.contains(pkg.packageName)) { + descendants.add(pkg.packageName); + needsUpdating.add(pkg); + } + } + try { + updateSharedLibrariesLocked(pkg, changingPkg, availablePackages); + } catch (PackageManagerException e) { + // If a system app update or an app and a required lib missing we + // delete the package and for updated system apps keep the data as + // it is better for the user to reinstall than to be in an limbo + // state. Also libs disappearing under an app should never happen + // - just in case. + if (!pkg.isSystem() || pkg.isUpdatedSystemApp()) { + final int flags = pkg.isUpdatedSystemApp() + ? PackageManager.DELETE_KEEP_DATA : 0; + deletePackageLIF(pkg.packageName, null, true, sUserManager.getUserIds(), + flags , null, true, null); + } + Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage()); } - Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage()); } - } - return res; + } while (needsUpdating != null && needsUpdating.size() > 0); + return resultList; } @GuardedBy({"mInstallLock", "mPackages"}) @@ -11648,19 +11671,19 @@ public class PackageManagerService extends IPackageManager.Stub for (SharedLibraryInfo info : reconciledPkg.allowedSharedLibraryInfos) { commitSharedLibraryInfoLocked(info); } + final Map<String, PackageParser.Package> combinedPackages = + reconciledPkg.getCombinedPackages(); try { // Shared libraries for the package need to be updated. - updateSharedLibrariesLPr(pkg, null); + updateSharedLibrariesLocked(pkg, null, combinedPackages); } catch (PackageManagerException e) { Slog.e(TAG, "updateSharedLibrariesLPr failed: ", e); } - } - - if (reconciledPkg.hasDynamicSharedLibraries() && (scanFlags & SCAN_BOOTING) == 0) { - // If we are not booting, we need to update any applications - // that are clients of our shared library. If we are booting, - // this will all be done once the scan is complete. - clientLibPkgs = updateAllSharedLibrariesLPw(pkg); + // Update all applications that use this library. Skip when booting + // since this will be done after all packages are scaned. + if ((scanFlags & SCAN_BOOTING) == 0) { + clientLibPkgs = updateAllSharedLibrariesLocked(pkg, combinedPackages); + } } } @@ -15749,6 +15772,7 @@ public class PackageManagerService extends IPackageManager.Stub * TODO: move most of the data contained her into a PackageSetting for commit. */ private static class ReconciledPackage { + public final ReconcileRequest request; public final PackageSetting pkgSetting; public final ScanResult scanResult; // TODO: Remove install-specific details from the reconcile result @@ -15762,14 +15786,18 @@ public class PackageManagerService extends IPackageManager.Stub public ArrayList<SharedLibraryInfo> collectedSharedLibraryInfos; public final boolean removeAppKeySetData; - private ReconciledPackage(InstallArgs installArgs, PackageSetting pkgSetting, + private ReconciledPackage(ReconcileRequest request, + InstallArgs installArgs, + PackageSetting pkgSetting, PackageInstalledInfo installResult, - PrepareResult prepareResult, ScanResult scanResult, + PrepareResult prepareResult, + ScanResult scanResult, DeletePackageAction deletePackageAction, List<SharedLibraryInfo> allowedSharedLibraryInfos, SigningDetails signingDetails, boolean sharedUserSignaturesChanged, boolean removeAppKeySetData) { + this.request = request; this.installArgs = installArgs; this.pkgSetting = pkgSetting; this.installResult = installResult; @@ -15782,9 +15810,20 @@ public class PackageManagerService extends IPackageManager.Stub this.removeAppKeySetData = removeAppKeySetData; } - public boolean hasDynamicSharedLibraries() { - return !ArrayUtils.isEmpty(allowedSharedLibraryInfos) - && allowedSharedLibraryInfos.get(0).getType() != SharedLibraryInfo.TYPE_STATIC; + /** + * Returns a combined set of packages containing the packages already installed combined + * with the package(s) currently being installed. The to-be installed packages take + * precedence and may shadow already installed packages. + */ + private Map<String, PackageParser.Package> getCombinedPackages() { + final ArrayMap<String, PackageParser.Package> combinedPackages = + new ArrayMap<>(request.allPackages.size() + request.scannedPackages.size()); + + combinedPackages.putAll(request.allPackages); + for (ScanResult scanResult : request.scannedPackages.values()) { + combinedPackages.put(scanResult.pkgSetting.name, scanResult.request.pkg); + } + return combinedPackages; } } @@ -15974,7 +16013,7 @@ public class PackageManagerService extends IPackageManager.Stub } result.put(installPackageName, - new ReconciledPackage(installArgs, scanResult.pkgSetting, + new ReconciledPackage(request, installArgs, scanResult.pkgSetting, res, request.preparedPackages.get(installPackageName), scanResult, deletePackageAction, allowedSharedLibInfos, signingDetails, sharedUserSignaturesChanged, removeAppKeySetData)); @@ -18409,7 +18448,7 @@ public class PackageManagerService extends IPackageManager.Stub try { // update shared libraries for the newly re-installed system package - updateSharedLibrariesLPr(pkg, null); + updateSharedLibrariesLocked(pkg, null, Collections.unmodifiableMap(mPackages)); } catch (PackageManagerException e) { Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage()); } @@ -20233,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); @@ -20483,7 +20527,7 @@ public class PackageManagerService extends IPackageManager.Stub prepareAppDataAfterInstallLIF(pkg); synchronized (mPackages) { try { - updateSharedLibrariesLPr(pkg, null); + updateSharedLibrariesLocked(pkg, null, mPackages); } catch (PackageManagerException e) { Slog.e(TAG, "updateAllSharedLibrariesLPw failed: ", e); } @@ -22494,6 +22538,7 @@ public class PackageManagerService extends IPackageManager.Stub final int targetSdkVersion; final PackageFreezer freezer; final int[] installedUserIds; + final boolean isCurrentLocationExternal; // reader synchronized (mPackages) { @@ -22540,6 +22585,7 @@ public class PackageManagerService extends IPackageManager.Stub "Failed to move already frozen package"); } + isCurrentLocationExternal = isExternal(pkg); codeFile = new File(pkg.codePath); installerPackageName = ps.installerPackageName; packageAbiOverride = ps.cpuAbiOverrideString; @@ -22642,6 +22688,7 @@ public class PackageManagerService extends IPackageManager.Stub case PackageInstaller.STATUS_SUCCESS: mMoveCallbacks.notifyStatusChanged(moveId, PackageManager.MOVE_SUCCEEDED); + logAppMovedStorage(packageName, isCurrentLocationExternal); break; case PackageInstaller.STATUS_FAILURE_STORAGE: mMoveCallbacks.notifyStatusChanged(moveId, @@ -22700,6 +22747,36 @@ public class PackageManagerService extends IPackageManager.Stub mHandler.sendMessage(msg); } + /** + * Logs that an app has been moved from internal to external storage and vice versa. + * @param packageName The package that was moved. + */ + private void logAppMovedStorage(String packageName, boolean isPreviousLocationExternal) { + final PackageParser.Package pkg; + synchronized (mPackages) { + pkg = mPackages.get(packageName); + } + if (pkg == null) { + return; + } + + final StorageManager storage = mContext.getSystemService(StorageManager.class); + VolumeInfo volume = storage.findVolumeByUuid(pkg.applicationInfo.storageUuid.toString()); + int packageExternalStorageType = getPackageExternalStorageType(volume, isExternal(pkg)); + + if (!isPreviousLocationExternal && isExternal(pkg)) { + // Move from internal to external storage. + StatsLog.write(StatsLog.APP_MOVED_STORAGE_REPORTED, packageExternalStorageType, + StatsLog.APP_MOVED_STORAGE_REPORTED__MOVE_TYPE__TO_EXTERNAL, + packageName); + } else if (isPreviousLocationExternal && !isExternal(pkg)) { + // Move from external to internal storage. + StatsLog.write(StatsLog.APP_MOVED_STORAGE_REPORTED, packageExternalStorageType, + StatsLog.APP_MOVED_STORAGE_REPORTED__MOVE_TYPE__TO_INTERNAL, + packageName); + } + } + @Override public int movePrimaryStorage(String volumeUuid) throws RemoteException { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null); @@ -23294,6 +23371,23 @@ public class PackageManagerService extends IPackageManager.Stub } return results; } + + @Override + public int getLocationFlags(String packageName) throws RemoteException { + int callingUser = UserHandle.getUserId(Binder.getCallingUid()); + ApplicationInfo appInfo = getApplicationInfo(packageName, + /*flags*/ 0, + /*userId*/ callingUser); + if (appInfo == null) { + throw new RemoteException( + "Couldn't get ApplicationInfo for package " + packageName); + } + return ((appInfo.isSystemApp() ? IPackageManagerNative.LOCATION_SYSTEM : 0) + | (appInfo.isVendor() ? IPackageManagerNative.LOCATION_VENDOR : 0) + | (appInfo.isProduct() ? IPackageManagerNative.LOCATION_PRODUCT : 0) + | (appInfo.isProductServices() + ? IPackageManagerNative.LOCATION_PRODUCT_SERVICES : 0)); + } } private class PackageManagerInternalImpl extends PackageManagerInternal { 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/StagingManager.java b/services/core/java/com/android/server/pm/StagingManager.java index 39c731c92135..a0f0a3178d1b 100644 --- a/services/core/java/com/android/server/pm/StagingManager.java +++ b/services/core/java/com/android/server/pm/StagingManager.java @@ -44,11 +44,13 @@ import android.os.ParcelFileDescriptor; import android.os.PowerManager; import android.os.RemoteException; import android.os.ServiceManager; +import android.os.storage.IStorageManager; import android.util.Slog; import android.util.SparseArray; import android.util.apk.ApkSignatureVerifier; import com.android.internal.annotations.GuardedBy; +import com.android.internal.content.PackageHelper; import com.android.internal.os.BackgroundThread; import java.io.File; @@ -253,6 +255,21 @@ public class StagingManager { } } + // Make sure we start a filesystem checkpoint on the next boot. + try { + IStorageManager storageManager = PackageHelper.getStorageManager(); + if (storageManager.supportsCheckpoint()) { + storageManager.startCheckpoint(1 /* numRetries */); + } + } catch (RemoteException e) { + // While StorageManager lives in the same process, the native implementation + // it calls through lives in 'vold'; so, this call can fail if 'vold' isn't + // reachable. + // Since we can live without filesystem checkpointing, just warn in this case + // and continue. + Slog.w(TAG, "Could not start filesystem checkpoint."); + } + session.setStagedSessionReady(); if (sessionContainsApex(session) && !mApexManager.markStagedSessionReady(session.sessionId)) { @@ -367,8 +384,10 @@ public class StagingManager { PackageInstaller.SessionParams params = originalSession.params.copy(); params.isStaged = false; params.installFlags |= PackageManager.INSTALL_DISABLE_VERIFICATION; + // TODO(b/129744602): use the userid from the original session. int apkSessionId = mPi.createSession( - params, originalSession.getInstallerPackageName(), originalSession.userId); + params, originalSession.getInstallerPackageName(), + 0 /* UserHandle.SYSTEM */); PackageInstallerSession apkSession = mPi.getSession(apkSessionId); try { @@ -448,8 +467,10 @@ public class StagingManager { } PackageInstaller.SessionParams params = session.params.copy(); params.isStaged = false; + // TODO(b/129744602): use the userid from the original session. int apkParentSessionId = mPi.createSession( - params, session.getInstallerPackageName(), session.userId); + params, session.getInstallerPackageName(), + 0 /* UserHandle.SYSTEM */); PackageInstallerSession apkParentSession = mPi.getSession(apkParentSessionId); try { apkParentSession.open(); 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..5c386b47b1b1 100644 --- a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java +++ b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java @@ -186,40 +186,12 @@ public final class DefaultPermissionGrantPolicy { SENSORS_PERMISSIONS.add(Manifest.permission.BODY_SENSORS); } - @Deprecated private static final Set<String> STORAGE_PERMISSIONS = new ArraySet<>(); static { STORAGE_PERMISSIONS.add(Manifest.permission.READ_EXTERNAL_STORAGE); STORAGE_PERMISSIONS.add(Manifest.permission.WRITE_EXTERNAL_STORAGE); } - private static final Set<String> MEDIA_AURAL_PERMISSIONS = new ArraySet<>(); - static { - // STOPSHIP(b/112545973): remove once feature enabled by default - if (StorageManager.hasIsolatedStorage()) { - MEDIA_AURAL_PERMISSIONS.add(Manifest.permission.READ_MEDIA_AUDIO); - - // STOPSHIP(b/124466734): remove these manual grants once the legacy - // permission logic is unified with PermissionController - MEDIA_AURAL_PERMISSIONS.add(Manifest.permission.READ_EXTERNAL_STORAGE); - MEDIA_AURAL_PERMISSIONS.add(Manifest.permission.WRITE_EXTERNAL_STORAGE); - } - } - - private static final Set<String> MEDIA_VISUAL_PERMISSIONS = new ArraySet<>(); - static { - // STOPSHIP(b/112545973): remove once feature enabled by default - if (StorageManager.hasIsolatedStorage()) { - MEDIA_VISUAL_PERMISSIONS.add(Manifest.permission.READ_MEDIA_VIDEO); - MEDIA_VISUAL_PERMISSIONS.add(Manifest.permission.READ_MEDIA_IMAGES); - - // STOPSHIP(b/124466734): remove these manual grants once the legacy - // permission logic is unified with PermissionController - MEDIA_VISUAL_PERMISSIONS.add(Manifest.permission.READ_EXTERNAL_STORAGE); - MEDIA_VISUAL_PERMISSIONS.add(Manifest.permission.WRITE_EXTERNAL_STORAGE); - } - } - private static final int MSG_READ_DEFAULT_PERMISSION_EXCEPTIONS = 1; private static final String ACTION_TRACK = "com.android.fitness.TRACK"; @@ -474,8 +446,7 @@ public final class DefaultPermissionGrantPolicy { // Media provider grantSystemFixedPermissionsToSystemPackage( getDefaultProviderAuthorityPackage(MediaStore.AUTHORITY, userId), userId, - STORAGE_PERMISSIONS, MEDIA_AURAL_PERMISSIONS, MEDIA_VISUAL_PERMISSIONS, - PHONE_PERMISSIONS); + STORAGE_PERMISSIONS, PHONE_PERMISSIONS); // Downloads provider grantSystemFixedPermissionsToSystemPackage( @@ -597,7 +568,7 @@ public final class DefaultPermissionGrantPolicy { grantPermissionsToSystemPackage( getDefaultSystemHandlerActivityPackageForCategory( Intent.CATEGORY_APP_GALLERY, userId), - userId, STORAGE_PERMISSIONS, MEDIA_VISUAL_PERMISSIONS); + userId, STORAGE_PERMISSIONS); // Email grantPermissionsToSystemPackage( @@ -647,7 +618,7 @@ public final class DefaultPermissionGrantPolicy { grantPermissionsToSystemPackage(packageName, userId, CONTACTS_PERMISSIONS, CALENDAR_PERMISSIONS, MICROPHONE_PERMISSIONS, PHONE_PERMISSIONS, SMS_PERMISSIONS, CAMERA_PERMISSIONS, - SENSORS_PERMISSIONS, STORAGE_PERMISSIONS, MEDIA_AURAL_PERMISSIONS); + SENSORS_PERMISSIONS, STORAGE_PERMISSIONS); grantSystemFixedPermissionsToSystemPackage(packageName, userId, ALWAYS_LOCATION_PERMISSIONS, ACTIVITY_RECOGNITION_PERMISSIONS); } @@ -665,7 +636,7 @@ public final class DefaultPermissionGrantPolicy { .setDataAndType(Uri.fromFile(new File("foo.mp3")), AUDIO_MIME_TYPE); grantPermissionsToSystemPackage( getDefaultSystemHandlerActivityPackage(musicIntent, userId), userId, - STORAGE_PERMISSIONS, MEDIA_AURAL_PERMISSIONS); + STORAGE_PERMISSIONS); // Home Intent homeIntent = new Intent(Intent.ACTION_MAIN) @@ -729,7 +700,7 @@ public final class DefaultPermissionGrantPolicy { grantSystemFixedPermissionsToSystemPackage( getDefaultSystemHandlerActivityPackage( RingtoneManager.ACTION_RINGTONE_PICKER, userId), - userId, STORAGE_PERMISSIONS, MEDIA_AURAL_PERMISSIONS); + userId, STORAGE_PERMISSIONS); // TextClassifier Service String textClassifierPackageName = @@ -740,6 +711,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/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java index 3029f51d4e09..86a399465ee0 100644 --- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java +++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java @@ -17,20 +17,14 @@ package com.android.server.pm.permission; import static android.Manifest.permission.READ_EXTERNAL_STORAGE; -import static android.Manifest.permission.READ_MEDIA_AUDIO; -import static android.Manifest.permission.READ_MEDIA_IMAGES; -import static android.Manifest.permission.READ_MEDIA_VIDEO; import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE; import static android.app.AppOpsManager.MODE_ALLOWED; import static android.app.AppOpsManager.MODE_ERRORED; import static android.app.AppOpsManager.MODE_FOREGROUND; -import static android.app.AppOpsManager.MODE_IGNORED; -import static android.app.AppOpsManager.OP_LEGACY_STORAGE; import static android.app.AppOpsManager.OP_NONE; import static android.app.AppOpsManager.permissionToOp; import static android.app.AppOpsManager.permissionToOpCode; import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT; -import static android.content.pm.PackageManager.FLAG_PERMISSION_HIDDEN; import static android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED; import static android.content.pm.PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED; import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE; @@ -1155,8 +1149,6 @@ public class PermissionManagerService { updatedUserIds); updatedUserIds = setInitialGrantForNewImplicitPermissionsLocked(origPermissions, permissionsState, pkg, updatedUserIds); - updatedUserIds = applyLegacyStoragePermissionModel(origPermissions, permissionsState, - pkg, updatedUserIds); setAppOpsLocked(permissionsState, pkg); } @@ -1476,184 +1468,6 @@ public class PermissionManagerService { } /** - * Pre-Q apps use READ/WRITE_EXTERNAL_STORAGE, post-Q apps use READ_MEDIA_AUDIO/VIDEO/IMAGES. - * - * <p>There is the special case of the grandfathered post-Q app that has all legacy and modern - * permissions system-fixed granted. The only way to remove these permissions is to uninstall - * the app. - * - * @param origPs The permission state of the package before the update - * @param ps The permissions state of the package - * @param pkg The package - * @param updatedUserIds The userIds we have already been updated before - * - * @return The userIds that have been updated - * - * @see com.android.server.StorageManagerService#applyLegacyStorage() - */ - private @NonNull int[] applyLegacyStoragePermissionModel(@NonNull PermissionsState origPs, - @NonNull PermissionsState ps, @NonNull PackageParser.Package pkg, - @NonNull int[] updatedUserIds) { - AppOpsManagerInternal appOpsManager = LocalServices.getService(AppOpsManagerInternal.class); - int[] users = UserManagerService.getInstance().getUserIds(); - - boolean isQApp = pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.Q; - boolean isPreMApp = pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M; - int appId = getAppId(pkg.applicationInfo.uid); - - int numRequestedPerms = pkg.requestedPermissions.size(); - for (int i = 0; i < numRequestedPerms; i++) { - String perm = pkg.requestedPermissions.get(i); - - boolean isLegacyStoragePermission = false; - boolean isModernStoragePermission = false; - switch (perm) { - case READ_EXTERNAL_STORAGE: - case WRITE_EXTERNAL_STORAGE: - isLegacyStoragePermission = true; - break; - case READ_MEDIA_AUDIO: - case READ_MEDIA_VIDEO: - case READ_MEDIA_IMAGES: - isModernStoragePermission = true; - break; - default: - // 'perm' is not a storage permission, skip it - continue; - } - - BasePermission bp = mSettings.getPermissionLocked(perm); - - for (int userId : users) { - boolean useLegacyStoragePermissionModel; - if (isQApp) { - useLegacyStoragePermissionModel = appOpsManager.checkOperationUnchecked( - OP_LEGACY_STORAGE, getUid(userId, appId), pkg.packageName) - == MODE_ALLOWED; - } else { - useLegacyStoragePermissionModel = true; - } - - int origCombinedLegacyFlags = - origPs.getPermissionFlags(READ_EXTERNAL_STORAGE, userId) - | origPs.getPermissionFlags(WRITE_EXTERNAL_STORAGE, userId); - - int origCombinedModernFlags = origPs.getPermissionFlags(READ_MEDIA_AUDIO, userId) - | origPs.getPermissionFlags(READ_MEDIA_VIDEO, userId) - | origPs.getPermissionFlags(READ_MEDIA_IMAGES, userId); - - boolean oldPermAreLegacyStorageModel = - (origCombinedLegacyFlags & FLAG_PERMISSION_HIDDEN) == 0; - boolean oldPermAreModernStorageModel = - (origCombinedModernFlags & FLAG_PERMISSION_HIDDEN) == 0; - - if (oldPermAreLegacyStorageModel && oldPermAreModernStorageModel) { - // This only happens after an platform upgrade from before Q - oldPermAreModernStorageModel = false; - } - - boolean shouldBeHidden; - boolean shouldBeFixed; - boolean shouldBeGranted = false; - boolean shouldBeRevoked = false; - int userFlags = -1; - if (useLegacyStoragePermissionModel) { - shouldBeHidden = isModernStoragePermission; - shouldBeFixed = isQApp || isModernStoragePermission; - - if (shouldBeFixed) { - userFlags = 0; - shouldBeGranted = true; - shouldBeRevoked = false; - } else if (oldPermAreModernStorageModel) { - // Inherit grant state on permission model change - userFlags = origCombinedModernFlags; - - shouldBeGranted = origPs.hasRuntimePermission(READ_MEDIA_AUDIO, userId) - || origPs.hasRuntimePermission(READ_MEDIA_VIDEO, userId) - || origPs.hasRuntimePermission(READ_MEDIA_IMAGES, userId); - - shouldBeRevoked = !shouldBeGranted; - } - } else { - shouldBeHidden = isLegacyStoragePermission; - shouldBeFixed = isLegacyStoragePermission; - - if (shouldBeFixed) { - userFlags = 0; - shouldBeGranted = true; - shouldBeRevoked = false; - } else if (oldPermAreLegacyStorageModel) { - // Inherit grant state on permission model change - userFlags = origCombinedLegacyFlags; - - shouldBeGranted = origPs.hasRuntimePermission(READ_EXTERNAL_STORAGE, userId) - || origPs.hasRuntimePermission(WRITE_EXTERNAL_STORAGE, userId); - - if ((origCombinedLegacyFlags & FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0 - && !isPreMApp) { - shouldBeGranted = false; - } - - shouldBeRevoked = !shouldBeGranted; - } - } - - // Granted permissions can never be user fixed - if (shouldBeGranted & userFlags != -1) { - userFlags &= ~FLAG_PERMISSION_USER_FIXED; - } - - boolean changed = false; - synchronized (mLock) { - if (shouldBeGranted) { - if (isPreMApp) { - setAppOpMode(perm, pkg, userId, MODE_ALLOWED); - } else if (!ps.hasRuntimePermission(perm, userId)) { - ps.grantRuntimePermission(bp, userId); - changed = true; - } - } - - if (shouldBeRevoked) { - if (isPreMApp) { - setAppOpMode(perm, pkg, userId, MODE_IGNORED); - } else if (ps.hasRuntimePermission(perm, userId)) { - ps.revokeRuntimePermission(bp, userId); - changed = true; - } - } - - if (shouldBeFixed) { - changed |= ps.updatePermissionFlags(mSettings.getPermissionLocked(perm), - userId, FLAG_PERMISSION_SYSTEM_FIXED, FLAG_PERMISSION_SYSTEM_FIXED); - } - - if (userFlags != -1) { - changed |= ps.updatePermissionFlags(mSettings.getPermissionLocked(perm), - userId, USER_PERMISSION_FLAGS, userFlags); - } - - changed |= ps.updatePermissionFlags(mSettings.getPermissionLocked(perm), userId, - FLAG_PERMISSION_HIDDEN, - shouldBeHidden ? FLAG_PERMISSION_HIDDEN : 0); - - if (shouldBeHidden) { - changed |= ps.updatePermissionFlags(mSettings.getPermissionLocked(perm), - userId, FLAG_PERMISSION_REVIEW_REQUIRED, 0); - } - } - - if (changed) { - updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId); - } - } - } - - return updatedUserIds; - } - - /** * Fix app-op modes for runtime permissions. * * @param permsState The state of the permissions of the package diff --git a/services/core/java/com/android/server/pm/permission/TEST_MAPPING b/services/core/java/com/android/server/pm/permission/TEST_MAPPING index c610ed09a5a2..2280d3fd9134 100644 --- a/services/core/java/com/android/server/pm/permission/TEST_MAPPING +++ b/services/core/java/com/android/server/pm/permission/TEST_MAPPING @@ -19,9 +19,6 @@ }, { "include-filter": "android.permission.cts.PermissionFlagsTest" - }, - { - "include-filter": "android.permission.cts.DualStoragePermissionModelTest" } ] }, diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index 7c87462cd63f..0e0fc120dbfd 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -206,7 +206,6 @@ import com.android.internal.policy.IShortcutService; import com.android.internal.policy.PhoneWindow; import com.android.internal.statusbar.IStatusBarService; import com.android.internal.util.ArrayUtils; -import com.android.internal.util.ScreenshotHelper; import com.android.server.ExtconStateObserver; import com.android.server.ExtconUEventObserver; import com.android.server.GestureLauncherService; @@ -377,7 +376,6 @@ public class PhoneWindowManager implements WindowManagerPolicy { BurnInProtectionHelper mBurnInProtectionHelper; private DisplayFoldController mDisplayFoldController; AppOpsManager mAppOpsManager; - private ScreenshotHelper mScreenshotHelper; private boolean mHasFeatureWatch; private boolean mHasFeatureLeanback; private boolean mHasFeatureHdmiCec; @@ -1601,7 +1599,8 @@ public class PhoneWindowManager implements WindowManagerPolicy { return -1; } - handleShortPressOnHome(mDisplayId); + // Post to main thread to avoid blocking input pipeline. + mHandler.post(() -> handleShortPressOnHome(mDisplayId)); return -1; } @@ -1638,7 +1637,8 @@ public class PhoneWindowManager implements WindowManagerPolicy { } } else if ((event.getFlags() & KeyEvent.FLAG_LONG_PRESS) != 0) { if (!keyguardOn) { - handleLongPressOnHome(event.getDeviceId()); + // Post to main thread to avoid blocking input pipeline. + mHandler.post(() -> handleLongPressOnHome(event.getDeviceId())); } } return -1; @@ -1923,7 +1923,6 @@ public class PhoneWindowManager implements WindowManagerPolicy { mWindowManagerFuncs.onKeyguardShowingAndNotOccludedChanged(); } }); - mScreenshotHelper = new ScreenshotHelper(mContext); } /** @@ -2226,6 +2225,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: @@ -2239,19 +2243,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(); @@ -2262,17 +2277,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/rollback/RollbackManagerServiceImpl.java b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java index 6630926b8bfe..068e78a2bd8a 100644 --- a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java +++ b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java @@ -225,6 +225,22 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub { public ParceledListSlice getAvailableRollbacks() { enforceManageRollbacks("getAvailableRollbacks"); + // Wait for the handler thread to get the list of available rollbacks + // to get the most up-to-date results. This is intended to reduce test + // flakiness when checking available rollbacks immediately after + // installing a package with rollback enabled. + final LinkedBlockingQueue<Boolean> result = new LinkedBlockingQueue<>(); + getHandler().post(() -> result.offer(true)); + + try { + result.take(); + } catch (InterruptedException ie) { + // We may not get the most up-to-date information, but whatever we + // can get now is better than nothing, so log but otherwise ignore + // the exception. + Log.w(TAG, "Interrupted while waiting for handler thread in getAvailableRollbacks"); + } + synchronized (mLock) { ensureRollbackDataLoadedLocked(); List<RollbackInfo> rollbacks = new ArrayList<>(); diff --git a/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java b/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java index 9348806c0e59..d8f07feb1ddb 100644 --- a/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java +++ b/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java @@ -166,8 +166,7 @@ public final class RollbackPackageHealthObserver implements PackageHealthObserve * This may cause {@code packages} to be rolled back if they crash too freqeuntly. */ public void startObservingHealth(List<String> packages, long durationMs) { - PackageWatchdog.getInstance(mContext).startObservingHealth(this, packages, durationMs, - false /* withExplicitHealthCheck */); + PackageWatchdog.getInstance(mContext).startObservingHealth(this, packages, durationMs); } /** Verifies the rollback state after a reboot. */ diff --git a/services/core/java/com/android/server/stats/StatsCompanionService.java b/services/core/java/com/android/server/stats/StatsCompanionService.java index 15148f3af194..f83b3ea10e05 100644 --- a/services/core/java/com/android/server/stats/StatsCompanionService.java +++ b/services/core/java/com/android/server/stats/StatsCompanionService.java @@ -110,6 +110,7 @@ import com.android.internal.os.BatteryStatsHelper; import com.android.internal.os.BinderCallsStats.ExportedCallStat; import com.android.internal.os.KernelCpuSpeedReader; import com.android.internal.os.KernelCpuThreadReader; +import com.android.internal.os.KernelCpuThreadReaderDiff; import com.android.internal.os.KernelCpuThreadReaderSettingsObserver; import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidActiveTimeReader; import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidClusterTimeReader; @@ -262,7 +263,7 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { private StoragedUidIoStatsReader mStoragedUidIoStatsReader = new StoragedUidIoStatsReader(); @Nullable - private final KernelCpuThreadReader mKernelCpuThreadReader; + private final KernelCpuThreadReaderDiff mKernelCpuThreadReader; private long mDebugElapsedClockPreviousValue = 0; private long mDebugElapsedClockPullCount = 0; @@ -1726,7 +1727,7 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { throw new IllegalStateException("mKernelCpuThreadReader is null"); } ArrayList<KernelCpuThreadReader.ProcessCpuUsage> processCpuUsages = - this.mKernelCpuThreadReader.getProcessCpuUsage(); + this.mKernelCpuThreadReader.getProcessCpuUsageDiffed(); if (processCpuUsages == null) { throw new IllegalStateException("processCpuUsages is null"); } diff --git a/services/core/java/com/android/server/storage/CacheQuotaStrategy.java b/services/core/java/com/android/server/storage/CacheQuotaStrategy.java index 7a35bf7bba12..2df7370f8296 100644 --- a/services/core/java/com/android/server/storage/CacheQuotaStrategy.java +++ b/services/core/java/com/android/server/storage/CacheQuotaStrategy.java @@ -66,7 +66,6 @@ import java.io.InputStream; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; -import java.util.Map; /** * CacheQuotaStrategy is a strategy for determining cache quotas using usage stats and foreground @@ -296,26 +295,24 @@ public class CacheQuotaStrategy implements RemoteCallback.OnResultListener { * @return the number of bytes that were free on the device when the quotas were last calced. */ public long setupQuotasFromFile() throws IOException { - FileInputStream stream; - try { - stream = mPreviousValuesFile.openRead(); + Pair<Long, List<CacheQuotaHint>> cachedValues = null; + try (FileInputStream stream = mPreviousValuesFile.openRead()) { + try { + cachedValues = readFromXml(stream); + } catch (XmlPullParserException e) { + throw new IllegalStateException(e.getMessage()); + } } catch (FileNotFoundException e) { // The file may not exist yet -- this isn't truly exceptional. return -1; } - Pair<Long, List<CacheQuotaHint>> cachedValues = null; - try { - cachedValues = readFromXml(stream); - } catch (XmlPullParserException e) { - throw new IllegalStateException(e.getMessage()); - } - if (cachedValues == null) { Slog.e(TAG, "An error occurred while parsing the cache quota file."); return -1; } pushProcessedQuotas(cachedValues.second); + return cachedValues.first; } diff --git a/services/core/java/com/android/server/textclassifier/TextClassificationManagerService.java b/services/core/java/com/android/server/textclassifier/TextClassificationManagerService.java index a5d291f94751..5f00148335a7 100644 --- a/services/core/java/com/android/server/textclassifier/TextClassificationManagerService.java +++ b/services/core/java/com/android/server/textclassifier/TextClassificationManagerService.java @@ -425,9 +425,12 @@ public final class TextClassificationManagerService extends ITextClassifierServi if (packageName == null) return; try { - final int uid = context.getPackageManager() + final int packageUid = context.getPackageManager() .getPackageUidAsUser(packageName, UserHandle.getCallingUserId()); - Preconditions.checkArgument(Binder.getCallingUid() == uid); + final int callingUid = Binder.getCallingUid(); + Preconditions.checkArgument(callingUid == packageUid + // Trust the system process: + || callingUid == android.os.Process.SYSTEM_UID); } catch (Exception e) { throw new RemoteException( String.format("Invalid package: name=%s, error=%s", packageName, e)); diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java index 0c9f81525509..d52ba169768f 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. @@ -2670,7 +2671,10 @@ public class WallpaperManagerService extends IWallpaperManager.Stub wallpaper.connection.mReply = null; } try { - wallpaper.connection.mService.detach(); + // It can be null if user switching happens before service connection. + if (wallpaper.connection.mService != null) { + wallpaper.connection.mService.detach(); + } } catch (RemoteException e) { Slog.w(TAG, "Failed detaching wallpaper service ", e); } diff --git a/services/core/java/com/android/server/webkit/SystemImpl.java b/services/core/java/com/android/server/webkit/SystemImpl.java index 4aa2b3722749..56a6c3cb99b2 100644 --- a/services/core/java/com/android/server/webkit/SystemImpl.java +++ b/services/core/java/com/android/server/webkit/SystemImpl.java @@ -19,19 +19,15 @@ package com.android.server.webkit; import android.app.ActivityManager; import android.app.AppGlobals; import android.content.Context; -import android.content.pm.ApplicationInfo; -import android.content.pm.IPackageDeleteObserver; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.UserInfo; import android.content.res.XmlResourceParser; -import android.database.ContentObserver; import android.os.Build; import android.os.RemoteException; import android.os.UserHandle; import android.os.UserManager; -import android.provider.Settings.Global; import android.provider.Settings; import android.util.AndroidRuntimeException; import android.util.Log; @@ -42,12 +38,12 @@ import android.webkit.WebViewZygote; import com.android.internal.util.XmlUtils; +import org.xmlpull.v1.XmlPullParserException; + import java.io.IOException; import java.util.ArrayList; import java.util.List; -import org.xmlpull.v1.XmlPullParserException; - /** * Default implementation for the WebView preparation Utility interface. * @hide @@ -77,7 +73,6 @@ public class SystemImpl implements SystemInterface { private SystemImpl() { int numFallbackPackages = 0; int numAvailableByDefaultPackages = 0; - int numAvByDefaultAndNotFallback = 0; XmlResourceParser parser = null; List<WebViewProviderInfo> webViewProviders = new ArrayList<WebViewProviderInfo>(); try { @@ -121,9 +116,6 @@ public class SystemImpl implements SystemInterface { } if (currentProvider.availableByDefault) { numAvailableByDefaultPackages++; - if (!currentProvider.isFallback) { - numAvByDefaultAndNotFallback++; - } } webViewProviders.add(currentProvider); } @@ -140,10 +132,6 @@ public class SystemImpl implements SystemInterface { throw new AndroidRuntimeException("There must be at least one WebView package " + "that is available by default"); } - if (numAvByDefaultAndNotFallback == 0) { - throw new AndroidRuntimeException("There must be at least one WebView package " - + "that is available by default and not a fallback"); - } mWebViewProviderPackages = webViewProviders.toArray(new WebViewProviderInfo[webViewProviders.size()]); } @@ -222,23 +210,6 @@ public class SystemImpl implements SystemInterface { } @Override - public void uninstallAndDisablePackageForAllUsers(Context context, String packageName) { - enablePackageForAllUsers(context, packageName, false); - try { - PackageManager pm = AppGlobals.getInitialApplication().getPackageManager(); - ApplicationInfo applicationInfo = pm.getApplicationInfo(packageName, 0); - if (applicationInfo != null && applicationInfo.isUpdatedSystemApp()) { - pm.deletePackage(packageName, new IPackageDeleteObserver.Stub() { - public void packageDeleted(String packageName, int returnCode) { - enablePackageForAllUsers(context, packageName, false); - } - }, PackageManager.DELETE_SYSTEM_APP | PackageManager.DELETE_ALL_USERS); - } - } catch (NameNotFoundException e) { - } - } - - @Override public void enablePackageForAllUsers(Context context, String packageName, boolean enable) { UserManager userManager = (UserManager)context.getSystemService(Context.USER_SERVICE); for(UserInfo userInfo : userManager.getUsers()) { @@ -246,8 +217,7 @@ public class SystemImpl implements SystemInterface { } } - @Override - public void enablePackageForUser(String packageName, boolean enable, int userId) { + private void enablePackageForUser(String packageName, boolean enable, int userId) { try { AppGlobals.getPackageManager().setApplicationEnabledSetting( packageName, diff --git a/services/core/java/com/android/server/webkit/SystemInterface.java b/services/core/java/com/android/server/webkit/SystemInterface.java index 405fe7d41e61..3fb52790621a 100644 --- a/services/core/java/com/android/server/webkit/SystemInterface.java +++ b/services/core/java/com/android/server/webkit/SystemInterface.java @@ -19,7 +19,6 @@ package com.android.server.webkit; import android.content.Context; import android.content.pm.PackageInfo; import android.content.pm.PackageManager.NameNotFoundException; -import android.database.ContentObserver; import android.webkit.UserPackage; import android.webkit.WebViewProviderInfo; @@ -45,9 +44,7 @@ public interface SystemInterface { public boolean isFallbackLogicEnabled(); public void enableFallbackLogic(boolean enable); - public void uninstallAndDisablePackageForAllUsers(Context context, String packageName); public void enablePackageForAllUsers(Context context, String packageName, boolean enable); - public void enablePackageForUser(String packageName, boolean enable, int userId); public boolean systemIsDebuggable(); public PackageInfo getPackageInfoForProvider(WebViewProviderInfo configInfo) diff --git a/services/core/java/com/android/server/webkit/WebViewUpdateService.java b/services/core/java/com/android/server/webkit/WebViewUpdateService.java index d7458f2f6e1a..0abe68f270f3 100644 --- a/services/core/java/com/android/server/webkit/WebViewUpdateService.java +++ b/services/core/java/com/android/server/webkit/WebViewUpdateService.java @@ -241,32 +241,6 @@ public class WebViewUpdateService extends SystemService { } @Override // Binder call - public boolean isFallbackPackage(String packageName) { - return WebViewUpdateService.this.mImpl.isFallbackPackage(packageName); - } - - @Override // Binder call - public void enableFallbackLogic(boolean enable) { - if (getContext().checkCallingPermission( - android.Manifest.permission.WRITE_SECURE_SETTINGS) - != PackageManager.PERMISSION_GRANTED) { - String msg = "Permission Denial: enableFallbackLogic() from pid=" - + Binder.getCallingPid() - + ", uid=" + Binder.getCallingUid() - + " requires " + android.Manifest.permission.WRITE_SECURE_SETTINGS; - Slog.w(TAG, msg); - throw new SecurityException(msg); - } - - long callingId = Binder.clearCallingIdentity(); - try { - WebViewUpdateService.this.mImpl.enableFallbackLogic(enable); - } finally { - Binder.restoreCallingIdentity(callingId); - } - } - - @Override // Binder call public boolean isMultiProcessEnabled() { return WebViewUpdateService.this.mImpl.isMultiProcessEnabled(); } diff --git a/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java b/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java index d4949b6893d7..f704c30402d3 100644 --- a/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java +++ b/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java @@ -16,48 +16,36 @@ package com.android.server.webkit; import android.content.Context; -import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; -import android.content.pm.Signature; import android.os.UserHandle; -import android.util.Slog; -import android.webkit.UserPackage; import android.webkit.WebViewProviderInfo; import android.webkit.WebViewProviderResponse; import java.io.PrintWriter; -import java.lang.Integer; -import java.util.List; /** * Implementation of the WebViewUpdateService. * This class doesn't depend on the android system like the actual Service does and can be used * directly by tests (as long as they implement a SystemInterface). * - * This class implements two main features - handling WebView fallback packages and keeping track - * of, and preparing, the current WebView implementation. The fallback mechanism is meant to be - * uncoupled from the rest of the WebView preparation and does not store any state. The code for - * choosing and preparing a WebView implementation needs to keep track of a couple of different - * things such as what package is used as WebView implementation. + * This class keeps track of and prepares the current WebView implementation, and needs to keep + * track of a couple of different things such as what package is used as WebView implementation. * * The public methods in this class are accessed from WebViewUpdateService either on the UI thread - * or on one of multiple Binder threads. This means that the code in this class needs to be - * thread-safe. The fallback mechanism shares (almost) no information between threads which makes - * it easier to argue about thread-safety (in theory, if timed badly, the fallback mechanism can - * incorrectly enable/disable a fallback package but that fault will be corrected when we later - * receive an intent for that enabling/disabling). On the other hand, the WebView preparation code - * shares state between threads meaning that code that chooses a new WebView implementation or - * checks which implementation is being used needs to hold a lock. + * or on one of multiple Binder threads. The WebView preparation code shares state between threads + * meaning that code that chooses a new WebView implementation or checks which implementation is + * being used needs to hold a lock. * * The WebViewUpdateService can be accessed in a couple of different ways. * 1. It is started from the SystemServer at boot - at that point we just initiate some state such * as the WebView preparation class. * 2. The SystemServer calls WebViewUpdateService.prepareWebViewInSystemServer. This happens at boot * and the WebViewUpdateService should not have been accessed before this call. In this call we - * enable/disable fallback packages and then choose WebView implementation for the first time. + * migrate away from the old fallback logic if necessary and then choose WebView implementation for + * the first time. * 3. The update service listens for Intents related to package installs and removals. These intents - * are received and processed on the UI thread. Each intent can result in enabling/disabling - * fallback packages and changing WebView implementation. + * are received and processed on the UI thread. Each intent can result in changing WebView + * implementation. * 4. The update service can be reached through Binder calls which are handled on specific binder * threads. These calls can be made from any process. Generally they are used for changing WebView * implementation (from Settings), getting information about the current WebView implementation (for @@ -86,35 +74,15 @@ public class WebViewUpdateServiceImpl { // We don't early out here in different cases where we could potentially early-out (e.g. if // we receive PACKAGE_CHANGED for another user than the system user) since that would // complicate this logic further and open up for more edge cases. - updateFallbackStateOnPackageChange(packageName, changedState); mWebViewUpdater.packageStateChanged(packageName, changedState); } void prepareWebViewInSystemServer() { - updateFallbackStateOnBoot(); + migrateFallbackStateOnBoot(); mWebViewUpdater.prepareWebViewInSystemServer(); mSystemInterface.notifyZygote(isMultiProcessEnabled()); } - private boolean existsValidNonFallbackProvider(WebViewProviderInfo[] providers) { - for (WebViewProviderInfo provider : providers) { - if (provider.availableByDefault && !provider.isFallback) { - // userPackages can contain null objects. - List<UserPackage> userPackages = - mSystemInterface.getPackageInfoForProviderAllUsers(mContext, provider); - if (WebViewUpdater.isInstalledAndEnabledForAllUsers(userPackages) && - // Checking validity of the package for the system user (rather than all - // users) since package validity depends not on the user but on the package - // itself. - mWebViewUpdater.isValidProvider(provider, - userPackages.get(UserHandle.USER_SYSTEM).getPackageInfo())) { - return true; - } - } - } - return false; - } - void handleNewUser(int userId) { // The system user is always started at boot, and by that point we have already run one // round of the package-changing logic (through prepareWebViewInSystemServer()), so early @@ -128,14 +96,11 @@ public class WebViewUpdateServiceImpl { } /** - * Called when a user was added or removed to ensure fallback logic and WebView preparation are - * triggered. This has to be done since the WebView package we use depends on the enabled-state + * Called when a user was added or removed to ensure WebView preparation is triggered. + * This has to be done since the WebView package we use depends on the enabled-state * of packages for all users (so adding or removing a user might cause us to change package). */ private void handleUserChange() { - if (mSystemInterface.isFallbackLogicEnabled()) { - updateFallbackState(mSystemInterface.getWebViewPackages()); - } // Potentially trigger package-changing logic. mWebViewUpdater.updateCurrentWebViewPackage(null); } @@ -164,60 +129,22 @@ public class WebViewUpdateServiceImpl { return mWebViewUpdater.getCurrentWebViewPackage(); } - void enableFallbackLogic(boolean enable) { - mSystemInterface.enableFallbackLogic(enable); - } - - private void updateFallbackStateOnBoot() { - if (!mSystemInterface.isFallbackLogicEnabled()) return; - - WebViewProviderInfo[] webviewProviders = mSystemInterface.getWebViewPackages(); - updateFallbackState(webviewProviders); - } - /** - * Handle the enabled-state of our fallback package, i.e. if there exists some non-fallback - * package that is valid (and available by default) then disable the fallback package, - * otherwise, enable the fallback package. + * If the fallback logic is enabled, re-enable any fallback package for all users, then + * disable the fallback logic. + * + * This migrates away from the old fallback mechanism to the new state where packages are never + * automatically enableenableisabled. */ - private void updateFallbackStateOnPackageChange(String changedPackage, int changedState) { + private void migrateFallbackStateOnBoot() { if (!mSystemInterface.isFallbackLogicEnabled()) return; WebViewProviderInfo[] webviewProviders = mSystemInterface.getWebViewPackages(); - - // A package was changed / updated / downgraded, early out if it is not one of the - // webview packages that are available by default. - boolean changedPackageAvailableByDefault = false; - for (WebViewProviderInfo provider : webviewProviders) { - if (provider.packageName.equals(changedPackage)) { - if (provider.availableByDefault) { - changedPackageAvailableByDefault = true; - } - break; - } - } - if (!changedPackageAvailableByDefault) return; - updateFallbackState(webviewProviders); - } - - private void updateFallbackState(WebViewProviderInfo[] webviewProviders) { - // If there exists a valid and enabled non-fallback package - disable the fallback - // package, otherwise, enable it. WebViewProviderInfo fallbackProvider = getFallbackProvider(webviewProviders); - if (fallbackProvider == null) return; - boolean existsValidNonFallbackProvider = existsValidNonFallbackProvider(webviewProviders); - - List<UserPackage> userPackages = - mSystemInterface.getPackageInfoForProviderAllUsers(mContext, fallbackProvider); - if (existsValidNonFallbackProvider && !isDisabledForAllUsers(userPackages)) { - mSystemInterface.uninstallAndDisablePackageForAllUsers(mContext, - fallbackProvider.packageName); - } else if (!existsValidNonFallbackProvider - && !WebViewUpdater.isInstalledAndEnabledForAllUsers(userPackages)) { - // Enable the fallback package for all users. - mSystemInterface.enablePackageForAllUsers(mContext, - fallbackProvider.packageName, true); + if (fallbackProvider != null) { + mSystemInterface.enablePackageForAllUsers(mContext, fallbackProvider.packageName, true); } + mSystemInterface.enableFallbackLogic(false); } /** @@ -232,15 +159,6 @@ public class WebViewUpdateServiceImpl { return null; } - boolean isFallbackPackage(String packageName) { - if (packageName == null || !mSystemInterface.isFallbackLogicEnabled()) return false; - - WebViewProviderInfo[] webviewPackages = mSystemInterface.getWebViewPackages(); - WebViewProviderInfo fallbackProvider = getFallbackProvider(webviewPackages); - return (fallbackProvider != null - && packageName.equals(fallbackProvider.packageName)); - } - boolean isMultiProcessEnabled() { int settingValue = mSystemInterface.getMultiProcessSetting(mContext); if (mSystemInterface.isMultiProcessDefaultEnabled()) { @@ -262,15 +180,6 @@ public class WebViewUpdateServiceImpl { } } - private static boolean isDisabledForAllUsers(List<UserPackage> userPackages) { - for (UserPackage userPackage : userPackages) { - if (userPackage.getPackageInfo() != null && userPackage.isEnabledPackage()) { - return false; - } - } - return true; - } - /** * Dump the state of this Service. */ diff --git a/services/core/java/com/android/server/webkit/WebViewUpdateServiceShellCommand.java b/services/core/java/com/android/server/webkit/WebViewUpdateServiceShellCommand.java index 3199ed47503e..7529c4157101 100644 --- a/services/core/java/com/android/server/webkit/WebViewUpdateServiceShellCommand.java +++ b/services/core/java/com/android/server/webkit/WebViewUpdateServiceShellCommand.java @@ -37,10 +37,6 @@ class WebViewUpdateServiceShellCommand extends ShellCommand { final PrintWriter pw = getOutPrintWriter(); try { switch(cmd) { - case "enable-redundant-packages": - return enableFallbackLogic(false); - case "disable-redundant-packages": - return enableFallbackLogic(true); case "set-webview-implementation": return setWebViewImplementation(); case "enable-multiprocess": @@ -56,13 +52,6 @@ class WebViewUpdateServiceShellCommand extends ShellCommand { return -1; } - private int enableFallbackLogic(boolean enable) throws RemoteException { - final PrintWriter pw = getOutPrintWriter(); - mInterface.enableFallbackLogic(enable); - pw.println("Success"); - return 0; - } - private int setWebViewImplementation() throws RemoteException { final PrintWriter pw = getOutPrintWriter(); String shellChosenPackage = getNextArg(); @@ -104,13 +93,6 @@ class WebViewUpdateServiceShellCommand extends ShellCommand { pw.println(" help"); pw.println(" Print this help text."); pw.println(""); - pw.println(" enable-redundant-packages"); - pw.println(" Allow a fallback package to be installed and enabled even when a"); - pw.println(" more-preferred package is available. This command is useful when testing"); - pw.println(" fallback packages."); - pw.println(" disable-redundant-packages"); - pw.println(" Disallow installing and enabling fallback packages when a more-preferred"); - pw.println(" package is available."); helpSetWebViewImplementation(); pw.println(" enable-multiprocess"); pw.println(" Enable multi-process mode for WebView"); diff --git a/services/core/java/com/android/server/webkit/WebViewUpdater.java b/services/core/java/com/android/server/webkit/WebViewUpdater.java index f270715175b2..a460040d0a60 100644 --- a/services/core/java/com/android/server/webkit/WebViewUpdater.java +++ b/services/core/java/com/android/server/webkit/WebViewUpdater.java @@ -20,7 +20,6 @@ import android.content.pm.PackageInfo; import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.Signature; import android.os.UserHandle; -import android.util.Base64; import android.util.Slog; import android.webkit.UserPackage; import android.webkit.WebViewFactory; @@ -29,7 +28,6 @@ import android.webkit.WebViewProviderResponse; import java.io.PrintWriter; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; /** @@ -140,13 +138,17 @@ class WebViewUpdater { try { synchronized(mLock) { mCurrentWebViewPackage = findPreferredWebViewPackage(); - // Don't persist the user-chosen setting across boots if the package being - // chosen is not used (could be disabled or uninstalled) so that the user won't - // be surprised by the device switching to using a certain webview package, - // that was uninstalled/disabled a long time ago, if it is installed/enabled - // again. - mSystemInterface.updateUserSetting(mContext, - mCurrentWebViewPackage.packageName); + String userSetting = mSystemInterface.getUserChosenWebViewProvider(mContext); + if (userSetting != null + && !userSetting.equals(mCurrentWebViewPackage.packageName)) { + // Don't persist the user-chosen setting across boots if the package being + // chosen is not used (could be disabled or uninstalled) so that the user won't + // be surprised by the device switching to using a certain webview package, + // that was uninstalled/disabled a long time ago, if it is installed/enabled + // again. + mSystemInterface.updateUserSetting(mContext, + mCurrentWebViewPackage.packageName); + } onWebViewProviderChanged(mCurrentWebViewPackage); } } catch (Throwable t) { @@ -470,9 +472,9 @@ class WebViewUpdater { /** * Gets the minimum version code allowed for a valid provider. It is the minimum versionCode - * of all available-by-default and non-fallback WebView provider packages. If there is no - * such WebView provider package on the system, then return -1, which means all positive - * versionCode WebView packages are accepted. + * of all available-by-default WebView provider packages. If there is no such WebView provider + * package on the system, then return -1, which means all positive versionCode WebView packages + * are accepted. * * Note that this is a private method in WebViewUpdater that handles a variable * (mMinimumVersionCode) which is shared between threads. Furthermore, this method does not @@ -485,7 +487,7 @@ class WebViewUpdater { long minimumVersionCode = -1; for (WebViewProviderInfo provider : mSystemInterface.getWebViewPackages()) { - if (provider.availableByDefault && !provider.isFallback) { + if (provider.availableByDefault) { try { long versionCode = mSystemInterface.getFactoryPackageVersion(provider.packageName); diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index 5bbabfceda47..91ec4a083ed9 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); } @@ -2730,30 +2730,40 @@ final class ActivityRecord extends ConfigurationContainer { final int appHeight = resolvedAppBounds.height(); final int parentAppWidth = parentAppBounds.width(); final int parentAppHeight = parentAppBounds.height(); + if (parentAppWidth == appWidth && parentAppHeight == appHeight) { + // Matched the parent bounds. + return false; + } + if (parentAppWidth > appWidth && parentAppHeight > appHeight) { + // Both sides are smaller than the parent. + return true; + } if (parentAppWidth < appWidth || parentAppHeight < appHeight) { // One side is larger than the parent. return true; } - if (info.hasFixedAspectRatio()) { + // The rest of the condition is that only one side is smaller than the parent, but it still + // needs to exclude the cases where the size is limited by the fixed aspect ratio. + if (info.maxAspectRatio > 0) { final float aspectRatio = (0.5f + Math.max(appWidth, appHeight)) / Math.min(appWidth, appHeight); + if (aspectRatio >= info.maxAspectRatio) { + // The current size has reached the max aspect ratio. + return false; + } + } + if (info.minAspectRatio > 0) { + // The activity should have at least the min aspect ratio, so this checks if the parent + // still has available space to provide larger aspect ratio. final float parentAspectRatio = (0.5f + Math.max(parentAppWidth, parentAppHeight)) / Math.min(parentAppWidth, parentAppHeight); - // Check if the parent still has available space in long side. - if (aspectRatio < parentAspectRatio - && (aspectRatio < info.maxAspectRatio || info.minAspectRatio > 0)) { - return true; + if (parentAspectRatio <= info.minAspectRatio) { + // The long side has reached the parent. + return false; } } - - final Rect resolvedBounds = resolvedConfig.windowConfiguration.getBounds(); - // If the width or height is the same as parent, it is already the best fit of the override - // bounds, therefore this condition is considered as not size compatibility mode. Here uses - // right and bottom as width and height of parent because the bounds may contain decor - // insets which has been accounted in override bounds. See {@link #computeBounds}. - return parentAppBounds.right != resolvedBounds.width() - && parentAppBounds.bottom != resolvedBounds.height(); + return true; } /** diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java index ea1db406b8df..cd15587918ec 100644 --- a/services/core/java/com/android/server/wm/ActivityStarter.java +++ b/services/core/java/com/android/server/wm/ActivityStarter.java @@ -114,6 +114,7 @@ import android.os.UserHandle; import android.os.UserManager; import android.service.voice.IVoiceInteractionSession; import android.text.TextUtils; +import android.util.ArraySet; import android.util.EventLog; import android.util.Pools.SynchronizedPool; import android.util.Slog; @@ -607,6 +608,7 @@ class ActivityStarter { boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity, TaskRecord inTask, boolean allowPendingRemoteAnimationRegistryLookup, PendingIntentRecord originatingPendingIntent, boolean allowBackgroundActivityStart) { + mSupervisor.getActivityMetricsLogger().notifyActivityLaunching(intent); int err = ActivityManager.START_SUCCESS; // Pull the optional Ephemeral Installer-only bundle out of the options early. final Bundle verificationBundle @@ -927,8 +929,10 @@ class ActivityStarter { mService.onStartActivitySetDidAppSwitch(); mController.doPendingActivityLaunches(false); - return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags, + final int res = startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags, true /* doResume */, checkedOptions, inTask, outActivity); + mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(res, outActivity[0]); + return res; } private boolean shouldAbortBackgroundActivityStart(int callingUid, int callingPid, @@ -945,7 +949,8 @@ class ActivityStarter { final boolean callingUidHasAnyVisibleWindow = mService.mWindowManager.mRoot.isAnyNonToastWindowVisibleForUid(callingUid); final boolean isCallingUidForeground = callingUidHasAnyVisibleWindow - || callingUidProcState == ActivityManager.PROCESS_STATE_TOP; + || callingUidProcState == ActivityManager.PROCESS_STATE_TOP + || callingUidProcState == ActivityManager.PROCESS_STATE_BOUND_TOP; final boolean isCallingUidPersistentSystemProcess = (callingUid == Process.SYSTEM_UID) || callingUidProcState <= ActivityManager.PROCESS_STATE_PERSISTENT_UI; if (isCallingUidForeground || isCallingUidPersistentSystemProcess) { @@ -1001,6 +1006,10 @@ class ActivityStarter { if (callerApp.hasActivityInVisibleTask()) { return false; } + // don't abort if the caller is bound by a UID that's currently foreground + if (isBoundByForegroundUid(callerApp)) { + return false; + } } // don't abort if the callingUid has START_ACTIVITIES_FROM_BACKGROUND permission if (mService.checkPermission(START_ACTIVITIES_FROM_BACKGROUND, callingPid, callingUid) @@ -1015,6 +1024,11 @@ class ActivityStarter { if (mService.isDeviceOwner(callingPackage)) { return false; } + // don't abort if the callingPackage has companion device + final int callingUserId = UserHandle.getUserId(callingUid); + if (mService.isAssociatedCompanionApp(callingUserId, callingPackage)) { + return false; + } // don't abort if the callingPackage is temporarily whitelisted if (mService.isPackageNameWhitelistedForBgActivityStarts(callingPackage)) { Slog.w(TAG, "Background activity start for " + callingPackage @@ -1045,6 +1059,18 @@ class ActivityStarter { return true; } + private boolean isBoundByForegroundUid(WindowProcessController callerApp) { + final ArraySet<Integer> boundClientUids = callerApp.getBoundClientUids(); + for (int i = boundClientUids.size() - 1; i >= 0; --i) { + final int uid = boundClientUids.valueAt(i); + if (mService.mWindowManager.mRoot.isAnyNonToastWindowVisibleForUid(uid) + || mService.getUidState(uid) == ActivityManager.PROCESS_STATE_TOP) { + return true; + } + } + return false; + } + /** * Creates a launch intent for the given auxiliary resolution data. */ diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java index fc7646f8ae4e..b2e5b6ab7a1a 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java @@ -510,4 +510,7 @@ public abstract class ActivityTaskManagerInternal { * Called by DevicePolicyManagerService to set the package name of the device owner. */ public abstract void setDeviceOwnerPackageName(String deviceOwnerPkg); + + /** Set all associated companion app that belongs to an userId. */ + public abstract void setCompanionAppPackages(int userId, Set<String> companionAppPackages); } diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java index 7ea7cf1cd015..98c37e65b9ac 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java @@ -191,6 +191,7 @@ import android.os.Message; import android.os.PersistableBundle; import android.os.PowerManager; import android.os.PowerManagerInternal; +import android.os.Process; import android.os.RemoteException; import android.os.ServiceManager; import android.os.StrictMode; @@ -243,6 +244,7 @@ import com.android.internal.util.FastPrintWriter; import com.android.internal.util.Preconditions; import com.android.internal.util.function.pooled.PooledLambda; import com.android.server.AttributeCache; +import com.android.server.DeviceIdleController; import com.android.server.LocalServices; import com.android.server.SystemService; import com.android.server.SystemServiceManager; @@ -425,6 +427,9 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { private static final long START_AS_CALLER_TOKEN_EXPIRED_TIMEOUT = START_AS_CALLER_TOKEN_TIMEOUT_IMPL + 20 * MINUTE_IN_MILLIS; + // How long to whitelist the Services for when requested. + private static final int SERVICE_LAUNCH_IDLE_WHITELIST_DURATION_MS = 5 * 1000; + // Activity tokens of system activities that are delegating their call to // #startActivityByCaller, keyed by the permissionToken granted to the delegate. final HashMap<IBinder, IBinder> mStartActivitySources = new HashMap<>(); @@ -438,6 +443,9 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { // VoiceInteractionManagerService ComponentName mActiveVoiceInteractionServiceComponent; + // A map userId and all its companion app packages + private final Map<Integer, Set<String>> mCompanionAppPackageMap = new ArrayMap<>(); + VrController mVrController; KeyguardController mKeyguardController; private final ClientLifecycleManager mLifecycleManager; @@ -2076,7 +2084,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { synchronized (mGlobalLock) { final long ident = Binder.clearCallingIdentity(); try { - getRecentTasks().removeAllVisibleTasks(); + getRecentTasks().removeAllVisibleTasks(mAmInternal.getCurrentUserId()); } finally { Binder.restoreCallingIdentity(ident); } @@ -2967,7 +2975,8 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { if (TextUtils.equals(pae.intent.getAction(), android.service.voice.VoiceInteractionService.SERVICE_INTERFACE)) { pae.intent.putExtras(pae.extras); - mContext.startServiceAsUser(pae.intent, new UserHandle(pae.userHandle)); + + startVoiceInteractionServiceAsUser(pae.intent, pae.userHandle, "AssistContext"); } else { pae.intent.replaceExtras(pae.extras); pae.intent.setFlags(FLAG_ACTIVITY_NEW_TASK @@ -2986,6 +2995,34 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } } + /** + * Workaround for historical API which starts the Assist service with a non-foreground + * {@code startService()} call. + */ + private void startVoiceInteractionServiceAsUser( + Intent intent, int userHandle, String reason) { + // Resolve the intent to find out which package we need to whitelist. + ResolveInfo resolveInfo = + mContext.getPackageManager().resolveServiceAsUser(intent, 0, userHandle); + if (resolveInfo == null || resolveInfo.serviceInfo == null) { + Slog.e(TAG, "VoiceInteractionService intent does not resolve. Not starting."); + return; + } + intent.setPackage(resolveInfo.serviceInfo.packageName); + + // Whitelist background services temporarily. + LocalServices.getService(DeviceIdleController.LocalService.class) + .addPowerSaveTempWhitelistApp(Process.myUid(), intent.getPackage(), + SERVICE_LAUNCH_IDLE_WHITELIST_DURATION_MS, userHandle, false, reason); + + // Finally, try to start the service. + try { + mContext.startServiceAsUser(intent, UserHandle.of(userHandle)); + } catch (RuntimeException e) { + Slog.e(TAG, "VoiceInteractionService failed to start.", e); + } + } + @Override public int addAppTask(IBinder activityToken, Intent intent, ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException { @@ -5875,6 +5912,14 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } } + boolean isAssociatedCompanionApp(int userId, String packageName) { + final Set<String> allPackages = mCompanionAppPackageMap.get(userId); + if (allPackages == null) { + return false; + } + return allPackages.contains(packageName); + } + final class H extends Handler { static final int REPORT_TIME_TRACKER_MSG = 1; @@ -7248,5 +7293,17 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { ActivityTaskManagerService.this.setDeviceOwnerPackageName(deviceOwnerPkg); } } + + @Override + public void setCompanionAppPackages(int userId, Set<String> companionAppPackages) { + // Deep copy all content to make sure we do not rely on the source + final Set<String> result = new HashSet<>(); + for (String pkg : companionAppPackages) { + result.add(pkg); + } + synchronized (mGlobalLock) { + mCompanionAppPackageMap.put(userId, result); + } + } } } 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..90bb494232c7 100644 --- a/services/core/java/com/android/server/wm/BarController.java +++ b/services/core/java/com/android/server/wm/BarController.java @@ -51,6 +51,7 @@ public class BarController { private static final int MSG_NAV_BAR_VISIBILITY_CHANGED = 1; protected final String mTag; + protected final int mDisplayId; private final int mTransientFlag; private final int mUnhideFlag; private final int mTranslucentFlag; @@ -74,9 +75,10 @@ public class BarController { private OnBarVisibilityChangedListener mVisibilityChangeListener; - BarController(String tag, int transientFlag, int unhideFlag, int translucentFlag, + BarController(String tag, int displayId, int transientFlag, int unhideFlag, int translucentFlag, int statusBarManagerId, int translucentWmFlag, int transparentFlag) { mTag = "BarController." + tag; + mDisplayId = displayId; mTransientFlag = transientFlag; mUnhideFlag = unhideFlag; mTranslucentFlag = translucentFlag; @@ -173,8 +175,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); @@ -229,7 +232,7 @@ public class BarController { public void run() { StatusBarManagerInternal statusbar = getStatusBarInternal(); if (statusbar != null) { - statusbar.setWindowState(mWin.getDisplayId(), mStatusBarManagerId, state); + statusbar.setWindowState(mDisplayId, mStatusBarManagerId, state); } } }); diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index bec72f5686df..e7dac9dfd727 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()); } }; @@ -1525,7 +1518,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo final int shortSizeDp = shortSize * DisplayMetrics.DENSITY_DEFAULT / mBaseDisplayDensity; final int longSizeDp = longSize * DisplayMetrics.DENSITY_DEFAULT / mBaseDisplayDensity; - mDisplayPolicy.configure(width, height, shortSizeDp); + mDisplayPolicy.updateConfigurationAndScreenSizeDependentBehaviors(); mDisplayRotation.configure(width, height, shortSizeDp, longSizeDp); mDisplayFrames.onDisplayInfoUpdated(mDisplayInfo, @@ -1734,7 +1727,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo mWmService.mH.sendEmptyMessage(REPORT_HARD_KEYBOARD_STATUS_CHANGE); } - mDisplayPolicy.updateConfigurationDependentBehaviors(); + mDisplayPolicy.updateConfigurationAndScreenSizeDependentBehaviors(); // Let the policy update hidden states. config.keyboardHidden = Configuration.KEYBOARDHIDDEN_NO; @@ -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 @@ -3219,13 +3212,11 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo "Proposed new IME target: " + target + " for display: " + getDisplayId()); // Now, a special case -- if the last target's window is in the process of exiting, but - // not removed, and the new target is home, keep on the last target to avoid flicker. - // Home is a special case since its above other stacks in the ordering list, but layed - // out below the others. + // not removed, keep on the last target to avoid IME flicker. if (curTarget != null && !curTarget.mRemoved && curTarget.isDisplayedLw() - && curTarget.isClosing() && (target == null || target.isActivityTypeHome())) { - if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, "New target is home while current target is " - + "closing, not changing"); + && curTarget.isClosing()) { + if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, "Not changing target till current window is" + + " closing and not removed"); return curTarget; } @@ -3659,9 +3650,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 +3666,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 +3722,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 +3743,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 +3761,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 +4808,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 6605f3c605ed..bbb857f4c24c 100644 --- a/services/core/java/com/android/server/wm/DisplayPolicy.java +++ b/services/core/java/com/android/server/wm/DisplayPolicy.java @@ -26,6 +26,8 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static android.content.res.Configuration.UI_MODE_TYPE_CAR; import static android.content.res.Configuration.UI_MODE_TYPE_MASK; import static android.view.InsetsState.TYPE_TOP_BAR; +import static android.view.InsetsState.TYPE_TOP_GESTURES; +import static android.view.InsetsState.TYPE_TOP_TAPPABLE_ELEMENT; import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; import static android.view.ViewRootImpl.NEW_INSETS_MODE_NONE; import static android.view.WindowManager.INPUT_CONSUMER_NAVIGATION; @@ -40,6 +42,7 @@ import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR; import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_OVERSCAN; import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN; import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS; +import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION; import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS; import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW; @@ -103,13 +106,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; @@ -149,6 +155,7 @@ import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.ScreenShapeHelper; import com.android.internal.util.ScreenshotHelper; +import com.android.internal.util.function.TriConsumer; import com.android.internal.widget.PointerLocationView; import com.android.server.LocalServices; import com.android.server.UiThread; @@ -212,6 +219,12 @@ public class DisplayPolicy { private final Object mServiceAcquireLock = new Object(); private StatusBarManagerInternal mStatusBarManagerInternal; + @Px + private int mBottomGestureAdditionalInset; + @Px + private int mSideGestureInset; + private boolean mNavigationBarLetsThroughTaps; + private StatusBarManagerInternal getStatusBarManagerInternal() { synchronized (mServiceAcquireLock) { if (mStatusBarManagerInternal == null) { @@ -255,15 +268,12 @@ public class DisplayPolicy { private int[] mNavigationBarHeightForRotationInCarMode = new int[4]; private int[] mNavigationBarWidthForRotationInCarMode = new int[4]; - private final StatusBarController mStatusBarController = new StatusBarController(); + /** Cached value of {@link ScreenShapeHelper#getWindowOutsetBottomPx} */ + @Px private int mWindowOutsetBottom; + + private final StatusBarController mStatusBarController; - private final BarController mNavigationBarController = new BarController("NavigationBar", - View.NAVIGATION_BAR_TRANSIENT, - View.NAVIGATION_BAR_UNHIDE, - View.NAVIGATION_BAR_TRANSLUCENT, - StatusBarManager.WINDOW_NAVIGATION_BAR, - FLAG_TRANSLUCENT_NAVIGATION, - View.NAVIGATION_BAR_TRANSPARENT); + private final BarController mNavigationBarController; private final BarController.OnBarVisibilityChangedListener mNavBarVisibilityListener = new BarController.OnBarVisibilityChangedListener() { @@ -410,12 +420,22 @@ public class DisplayPolicy { mDisplayContent = displayContent; mLock = service.getWindowManagerLock(); + final int displayId = displayContent.getDisplayId(); + mStatusBarController = new StatusBarController(displayId); + mNavigationBarController = new BarController("NavigationBar", + displayId, + View.NAVIGATION_BAR_TRANSIENT, + View.NAVIGATION_BAR_UNHIDE, + View.NAVIGATION_BAR_TRANSLUCENT, + StatusBarManager.WINDOW_NAVIGATION_BAR, + FLAG_TRANSLUCENT_NAVIGATION, + View.NAVIGATION_BAR_TRANSPARENT); + final Resources r = mContext.getResources(); mCarDockEnablesAccelerometer = r.getBoolean(R.bool.config_carDockEnablesAccelerometer); mDeskDockEnablesAccelerometer = r.getBoolean(R.bool.config_deskDockEnablesAccelerometer); mTranslucentDecorEnabled = r.getBoolean(R.bool.config_enableTranslucentDecor); mForceShowSystemBarsFromExternal = r.getBoolean(R.bool.config_forceShowSystemBars); - updateConfigurationDependentBehaviors(); mAccessibilityManager = (AccessibilityManager) mContext.getSystemService( Context.ACCESSIBILITY_SERVICE); @@ -522,7 +542,6 @@ public class DisplayPolicy { if (mWindowSleepToken != null) { return; } - final int displayId = displayContent.getDisplayId(); mWindowSleepToken = service.mAtmInternal.acquireSleepToken( "WindowSleepTokenOnDisplay" + displayId, displayId); }; @@ -567,15 +586,6 @@ public class DisplayPolicy { return mDisplayContent.getDisplayId(); } - void configure(int width, int height, int shortSizeDp) { - // Allow the navigation bar to move on non-square small devices (phones). - mNavigationBarCanMove = width != height && shortSizeDp < 600; - } - - void updateConfigurationDependentBehaviors() { - mNavBarOpacityMode = mContext.getResources().getInteger(R.integer.config_navBarOpacityMode); - } - public void setHdmiPlugged(boolean plugged) { setHdmiPlugged(plugged, false /* force */); } @@ -741,6 +751,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 @@ -750,7 +765,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)) { @@ -758,7 +773,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); } @@ -856,11 +871,14 @@ public class DisplayPolicy { if (mDisplayContent.isDefaultDisplay) { mService.mPolicy.setKeyguardCandidateLw(win); } - mDisplayContent.setInsetProvider(TYPE_TOP_BAR, win, + final TriConsumer<DisplayFrames, WindowState, Rect> frameProvider = (displayFrames, windowState, rect) -> { rect.top = 0; rect.bottom = getStatusBarHeight(displayFrames); - }); + }; + mDisplayContent.setInsetProvider(TYPE_TOP_BAR, win, frameProvider); + mDisplayContent.setInsetProvider(TYPE_TOP_GESTURES, win, frameProvider); + mDisplayContent.setInsetProvider(TYPE_TOP_TAPPABLE_ELEMENT, win, frameProvider); break; case TYPE_NAVIGATION_BAR: mContext.enforceCallingOrSelfPermission( @@ -877,6 +895,31 @@ public class DisplayPolicy { mNavBarVisibilityListener, true); mDisplayContent.setInsetProvider(InsetsState.TYPE_NAVIGATION_BAR, win, null /* frameProvider */); + mDisplayContent.setInsetProvider(InsetsState.TYPE_BOTTOM_GESTURES, win, + (displayFrames, windowState, inOutFrame) -> { + inOutFrame.top -= mBottomGestureAdditionalInset; + }); + mDisplayContent.setInsetProvider(InsetsState.TYPE_LEFT_GESTURES, win, + (displayFrames, windowState, inOutFrame) -> { + inOutFrame.left = 0; + inOutFrame.top = 0; + inOutFrame.bottom = displayFrames.mDisplayHeight; + inOutFrame.right = displayFrames.mUnrestricted.left + mSideGestureInset; + }); + mDisplayContent.setInsetProvider(InsetsState.TYPE_RIGHT_GESTURES, win, + (displayFrames, windowState, inOutFrame) -> { + inOutFrame.left = displayFrames.mUnrestricted.right - mSideGestureInset; + inOutFrame.top = 0; + inOutFrame.bottom = displayFrames.mDisplayHeight; + inOutFrame.right = displayFrames.mDisplayWidth; + }); + mDisplayContent.setInsetProvider(InsetsState.TYPE_BOTTOM_TAPPABLE_ELEMENT, win, + (displayFrames, windowState, inOutFrame) -> { + if ((windowState.getAttrs().flags & FLAG_NOT_TOUCHABLE) != 0 + || mNavigationBarLetsThroughTaps) { + inOutFrame.setEmpty(); + } + }); if (DEBUG_LAYOUT) Slog.i(TAG, "NAVIGATION BAR: " + mNavigationBar); break; case TYPE_NAVIGATION_BAR_PANEL: @@ -1169,7 +1212,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; @@ -1489,12 +1532,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(); @@ -1534,8 +1578,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. @@ -2190,7 +2235,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) { @@ -2346,7 +2391,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) { @@ -2541,6 +2586,7 @@ public class DisplayPolicy { */ public void onOverlayChangedLw() { onConfigurationChanged(); + mSystemGestures.onConfigurationChanged(); } /** @@ -2602,9 +2648,31 @@ public class DisplayPolicy { res.getDimensionPixelSize(R.dimen.navigation_bar_width_car_mode); } + mNavBarOpacityMode = res.getInteger(R.integer.config_navBarOpacityMode); + mSideGestureInset = res.getDimensionPixelSize(R.dimen.config_backGestureInset); + mNavigationBarLetsThroughTaps = res.getBoolean(R.bool.config_navBarTapThrough); + // EXPERIMENT TODO(b/113952590): Remove once experiment in bug is completed mExperiments.onConfigurationChanged(uiContext); // EXPERIMENT END + + // EXPERIMENT: TODO(b/113952590): Replace with real code after experiment. + // This should calculate how much above the frame we accept gestures. Currently, + // we extend the frame to capture the gestures, so this is 0. + mBottomGestureAdditionalInset = mExperiments.getNavigationBarFrameHeight() + - mExperiments.getNavigationBarFrameHeight(); + // EXPERIMENT END + + updateConfigurationAndScreenSizeDependentBehaviors(); + mWindowOutsetBottom = ScreenShapeHelper.getWindowOutsetBottomPx(mContext.getResources()); + } + + void updateConfigurationAndScreenSizeDependentBehaviors() { + final Context uiContext = getSystemUiContext(); + final Resources res = uiContext.getResources(); + mNavigationBarCanMove = + mDisplayContent.mBaseDisplayWidth != mDisplayContent.mBaseDisplayHeight + && res.getBoolean(R.bool.config_navBarCanMove); } @VisibleForTesting @@ -2960,6 +3028,8 @@ public class DisplayPolicy { mLastDockedStackSysUiFlags = dockedVisibility; mLastFocusNeedsMenu = needsMenu; mFocusedApp = win.getAppToken(); + mLastNonDockedStackBounds.set(mNonDockedStackBounds); + mLastDockedStackBounds.set(mDockedStackBounds); final Rect fullscreenStackBounds = new Rect(mNonDockedStackBounds); final Rect dockedStackBounds = new Rect(mDockedStackBounds); mHandler.post(() -> { @@ -3411,6 +3481,10 @@ public class DisplayPolicy { } if (mNavigationBar != null) { pw.print(prefix); pw.print("mNavigationBar="); pw.println(mNavigationBar); + pw.print(prefix); pw.print("mNavBarOpacityMode="); pw.println(mNavBarOpacityMode); + pw.print(prefix); pw.print("mNavigationBarCanMove="); pw.println(mNavigationBarCanMove); + pw.print(prefix); pw.print("mNavigationBarPosition="); + pw.println(mNavigationBarPosition); } if (mFocusedWindow != null) { pw.print(prefix); pw.print("mFocusedWindow="); pw.println(mFocusedWindow); 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..f85fdb6c3882 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); } } @@ -245,7 +251,7 @@ final class InputMonitor { final boolean hasFocus, final boolean hasWallpaper) { // Add a window to our list of input windows. inputWindowHandle.name = child.toString(); - flags = child.getSurfaceTouchableRegion(inputWindowHandle.touchableRegion, flags); + flags = child.getSurfaceTouchableRegion(inputWindowHandle, flags); inputWindowHandle.layoutParamsFlags = flags; inputWindowHandle.layoutParamsType = type; inputWindowHandle.dispatchingTimeoutNanos = child.getInputDispatchingTimeoutNanos(); @@ -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/RecentTasks.java b/services/core/java/com/android/server/wm/RecentTasks.java index 24b02133ff3c..d6c7b21e16b2 100644 --- a/services/core/java/com/android/server/wm/RecentTasks.java +++ b/services/core/java/com/android/server/wm/RecentTasks.java @@ -653,10 +653,10 @@ class RecentTasks { } } - void removeAllVisibleTasks() { + void removeAllVisibleTasks(int userId) { for (int i = mTasks.size() - 1; i >= 0; --i) { final TaskRecord tr = mTasks.get(i); - if (isVisibleRecentTask(tr)) { + if (tr.userId == userId && isVisibleRecentTask(tr)) { mTasks.remove(i); notifyTaskRemoved(tr, true /* wasTrimmed */, true /* killProcess */); } 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/Session.java b/services/core/java/com/android/server/wm/Session.java index 9b634f959fca..22b030dd1620 100644 --- a/services/core/java/com/android/server/wm/Session.java +++ b/services/core/java/com/android/server/wm/Session.java @@ -426,11 +426,10 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient { } @Override - public void updateTapExcludeRegion(IWindow window, int regionId, int left, int top, int width, - int height) { + public void updateTapExcludeRegion(IWindow window, int regionId, Region region) { final long identity = Binder.clearCallingIdentity(); try { - mService.updateTapExcludeRegion(window, regionId, left, top, width, height); + mService.updateTapExcludeRegion(window, regionId, region); } finally { Binder.restoreCallingIdentity(identity); } diff --git a/services/core/java/com/android/server/wm/StatusBarController.java b/services/core/java/com/android/server/wm/StatusBarController.java index 6db606d2a30b..f4260d32a77d 100644 --- a/services/core/java/com/android/server/wm/StatusBarController.java +++ b/services/core/java/com/android/server/wm/StatusBarController.java @@ -36,22 +36,22 @@ public class StatusBarController extends BarController { private Runnable mAppTransitionPending = () -> { StatusBarManagerInternal statusBar = getStatusBarInternal(); - if (statusBar != null && mWin != null) { - statusBar.appTransitionPending(mWin.getDisplayId()); + if (statusBar != null) { + statusBar.appTransitionPending(mDisplayId); } }; private Runnable mAppTransitionCancelled = () -> { StatusBarManagerInternal statusBar = getStatusBarInternal(); - if (statusBar != null && mWin != null) { - statusBar.appTransitionCancelled(mWin.getDisplayId()); + if (statusBar != null) { + statusBar.appTransitionCancelled(mDisplayId); } }; private Runnable mAppTransitionFinished = () -> { StatusBarManagerInternal statusBar = getStatusBarInternal(); - if (statusBar != null && mWin != null) { - statusBar.appTransitionFinished(mWin.getDisplayId()); + if (statusBar != null) { + statusBar.appTransitionFinished(mDisplayId); } }; @@ -65,8 +65,8 @@ public class StatusBarController extends BarController { long statusBarAnimationStartTime, long statusBarAnimationDuration) { mHandler.post(() -> { StatusBarManagerInternal statusBar = getStatusBarInternal(); - if (statusBar != null && mWin != null) { - statusBar.appTransitionStarting(mWin.getDisplayId(), + if (statusBar != null) { + statusBar.appTransitionStarting(mDisplayId, statusBarAnimationStartTime, statusBarAnimationDuration); } }); @@ -84,8 +84,9 @@ public class StatusBarController extends BarController { } }; - StatusBarController() { + StatusBarController(int displayId) { super("StatusBar", + displayId, View.STATUS_BAR_TRANSIENT, View.STATUS_BAR_UNHIDE, View.STATUS_BAR_TRANSLUCENT, diff --git a/services/core/java/com/android/server/wm/SurfaceAnimator.java b/services/core/java/com/android/server/wm/SurfaceAnimator.java index 35b8641371be..67686a586a65 100644 --- a/services/core/java/com/android/server/wm/SurfaceAnimator.java +++ b/services/core/java/com/android/server/wm/SurfaceAnimator.java @@ -82,6 +82,11 @@ class SurfaceAnimator { return; } final Runnable resetAndInvokeFinish = () -> { + // We need to check again if the animation has been replaced with a new + // animation because the animatable may defer to finish. + if (anim != mAnimation) { + return; + } reset(mAnimatable.getPendingTransaction(), true /* destroyLeash */); if (animationFinishedCallback != null) { animationFinishedCallback.run(); diff --git a/services/core/java/com/android/server/wm/SystemGesturesPointerEventListener.java b/services/core/java/com/android/server/wm/SystemGesturesPointerEventListener.java index bd4e542033c5..35afaedb0b43 100644 --- a/services/core/java/com/android/server/wm/SystemGesturesPointerEventListener.java +++ b/services/core/java/com/android/server/wm/SystemGesturesPointerEventListener.java @@ -17,9 +17,13 @@ package com.android.server.wm; import android.content.Context; +import android.graphics.Rect; +import android.hardware.display.DisplayManagerGlobal; import android.os.Handler; import android.os.SystemClock; import android.util.Slog; +import android.view.Display; +import android.view.DisplayCutout; import android.view.GestureDetector; import android.view.InputDevice; import android.view.MotionEvent; @@ -46,8 +50,9 @@ class SystemGesturesPointerEventListener implements PointerEventListener { private final Context mContext; private final Handler mHandler; - private final int mSwipeStartThreshold; - private final int mSwipeDistanceThreshold; + private int mDisplayCutoutTouchableRegionSize; + private int mSwipeStartThreshold; + private int mSwipeDistanceThreshold; private final Callbacks mCallbacks; private final int[] mDownPointerId = new int[MAX_TRACKED_POINTERS]; private final float[] mDownX = new float[MAX_TRACKED_POINTERS]; @@ -65,14 +70,33 @@ class SystemGesturesPointerEventListener implements PointerEventListener { private long mLastFlingTime; SystemGesturesPointerEventListener(Context context, Handler handler, Callbacks callbacks) { - mContext = context; + mContext = checkNull("context", context); mHandler = handler; mCallbacks = checkNull("callbacks", callbacks); - mSwipeStartThreshold = checkNull("context", context).getResources() + + onConfigurationChanged(); + } + + void onConfigurationChanged() { + mSwipeStartThreshold = mContext.getResources() .getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height); + + final Display display = DisplayManagerGlobal.getInstance() + .getRealDisplay(Display.DEFAULT_DISPLAY); + final DisplayCutout displayCutout = display.getCutout(); + if (displayCutout != null) { + final Rect bounds = displayCutout.getBoundingRectTop(); + if (!bounds.isEmpty()) { + // Expand swipe start threshold such that we can catch touches that just start below + // the notch area + mDisplayCutoutTouchableRegionSize = mContext.getResources().getDimensionPixelSize( + com.android.internal.R.dimen.display_cutout_touchable_region_size); + mSwipeStartThreshold += mDisplayCutoutTouchableRegionSize; + } + } mSwipeDistanceThreshold = mSwipeStartThreshold; if (DEBUG) Slog.d(TAG, "mSwipeStartThreshold=" + mSwipeStartThreshold - + " mSwipeDistanceThreshold=" + mSwipeDistanceThreshold); + + " mSwipeDistanceThreshold=" + mSwipeDistanceThreshold); } private static <T> T checkNull(String name, T arg) { diff --git a/services/core/java/com/android/server/wm/TapExcludeRegionHolder.java b/services/core/java/com/android/server/wm/TapExcludeRegionHolder.java index 0a4ab67f033d..22f529b28b8e 100644 --- a/services/core/java/com/android/server/wm/TapExcludeRegionHolder.java +++ b/services/core/java/com/android/server/wm/TapExcludeRegionHolder.java @@ -21,38 +21,35 @@ import android.graphics.Region; import android.util.SparseArray; /** - * A holder that contains a collection of rectangular areas identified by int id. Each individual - * region can be updated separately. + * A holder that contains a collection of regions identified by int id. Each individual region can + * be updated separately. */ class TapExcludeRegionHolder { - private SparseArray<Rect> mTapExcludeRects = new SparseArray<>(); + private SparseArray<Region> mTapExcludeRegions = new SparseArray<>(); /** Update the specified region with provided position and size. */ - void updateRegion(int regionId, int left, int top, int width, int height) { - if (width <= 0 || height <= 0) { - // A region became empty - remove it. - mTapExcludeRects.remove(regionId); + void updateRegion(int regionId, Region region) { + // Remove the previous one because there is a new one incoming. + mTapExcludeRegions.remove(regionId); + + if (region == null || region.isEmpty()) { + // The incoming region is invalid. Don't use it. return; } - Rect region = mTapExcludeRects.get(regionId); - if (region == null) { - region = new Rect(); - } - region.set(left, top, left + width, top + height); - mTapExcludeRects.put(regionId, region); + mTapExcludeRegions.put(regionId, region); } /** * Union the provided region with current region formed by this container. */ - void amendRegion(Region region, Rect boundingRegion) { - for (int i = mTapExcludeRects.size() - 1; i>= 0 ; --i) { - final Rect rect = mTapExcludeRects.valueAt(i); - if (boundingRegion != null) { - rect.intersect(boundingRegion); + void amendRegion(Region region, Rect bounds) { + for (int i = mTapExcludeRegions.size() - 1; i >= 0; --i) { + final Region r = mTapExcludeRegions.valueAt(i); + if (bounds != null) { + r.op(bounds, Region.Op.INTERSECT); } - region.union(rect); + region.op(r, Region.Op.UNION); } } } 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 4aa844ff4f49..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); @@ -6696,24 +6693,23 @@ public class WindowManagerService extends IWindowManager.Stub } /** - * Update a tap exclude region with a rectangular area in the window identified by the provided - * id. Touches down on this region will not: + * Update a tap exclude region in the window identified by the provided id. Touches down on this + * region will not: * <ol> * <li>Switch focus to this window.</li> * <li>Move the display of this window to top.</li> * <li>Send the touch events to this window.</li> * </ol> - * Passing an empty rect will remove the area from the exclude region of this window. + * Passing an invalid region will remove the area from the exclude region of this window. */ - void updateTapExcludeRegion(IWindow client, int regionId, int left, int top, int width, - int height) { + void updateTapExcludeRegion(IWindow client, int regionId, Region region) { synchronized (mGlobalLock) { final WindowState callingWin = windowForClientLocked(null, client, false); if (callingWin == null) { Slog.w(TAG_WM, "Bad requesting window " + client); return; } - callingWin.updateTapExcludeRegion(regionId, left, top, width, height); + callingWin.updateTapExcludeRegion(regionId, region); } } @@ -7216,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/WindowProcessController.java b/services/core/java/com/android/server/wm/WindowProcessController.java index 1b4aa26f7fb1..33561d3a41d6 100644 --- a/services/core/java/com/android/server/wm/WindowProcessController.java +++ b/services/core/java/com/android/server/wm/WindowProcessController.java @@ -149,6 +149,8 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio // Set to true if this process is currently temporarily whitelisted to start activities even if // it's not in the foreground private volatile boolean mAllowBackgroundActivityStarts; + // Set of UIDs of clients currently bound to this process + private volatile ArraySet<Integer> mBoundClientUids = new ArraySet<Integer>(); // Thread currently set for VR scheduling int mVrThreadTid; @@ -297,6 +299,11 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio return mPendingUiClean; } + /** @return {@code true} if the process registered to a display as a config listener. */ + boolean registeredForDisplayConfigChanges() { + return mDisplayId != INVALID_DISPLAY; + } + void postPendingUiCleanMsg(boolean pendingUiClean) { if (mListener == null) return; // Posting on handler so WM lock isn't held when we call into AM. @@ -368,6 +375,14 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio return mAllowBackgroundActivityStarts; } + public void setBoundClientUids(ArraySet<Integer> boundClientUids) { + mBoundClientUids = boundClientUids; + } + + public ArraySet<Integer> getBoundClientUids() { + return mBoundClientUids; + } + public void setInstrumenting(boolean instrumenting, boolean hasBackgroundActivityStartPrivileges) { mInstrumenting = instrumenting; diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index f143c70efc9d..08ade37c995c 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -72,6 +72,7 @@ import static android.view.WindowManagerGlobal.RELAYOUT_RES_DRAG_RESIZING_FREEFO import static android.view.WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME; import static android.view.WindowManagerGlobal.RELAYOUT_RES_SURFACE_CHANGED; +import static com.android.server.am.ActivityManagerService.MY_PID; import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; import static com.android.server.policy.WindowManagerPolicy.TRANSIT_ENTER; import static com.android.server.policy.WindowManagerPolicy.TRANSIT_EXIT; @@ -213,7 +214,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP static final String TAG = TAG_WITH_CLASS_NAME ? "WindowState" : TAG_WM; // The minimal size of a window within the usable area of the freeform stack. - // TODO(multi-window): fix the min sizes when we have mininum width/height support, + // TODO(multi-window): fix the min sizes when we have minimum width/height support, // use hard-coded min sizes for now. static final int MINIMUM_VISIBLE_WIDTH_IN_DP = 48; static final int MINIMUM_VISIBLE_HEIGHT_IN_DP = 32; @@ -307,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(); /** @@ -1200,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()); } @@ -1780,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() { @@ -2183,8 +2196,11 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP } } - int getSurfaceTouchableRegion(Region region, int flags) { + int getSurfaceTouchableRegion(InputWindowHandle inputWindowHandle, int flags) { final boolean modal = (flags & (FLAG_NOT_TOUCH_MODAL | FLAG_NOT_FOCUSABLE)) == 0; + final Region region = inputWindowHandle.touchableRegion; + setTouchableRegionCropIfNeeded(inputWindowHandle); + if (mAppToken != null && !mAppToken.getResolvedOverrideBounds().isEmpty()) { // There may have touchable letterboxes around the activity, so in order to let the // letterboxes are able to receive touch event and slip to activity, the activity with @@ -2252,6 +2268,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP region.set(-dw, -dh, dw + dw, dh + dh); // Subtract the area that cannot be touched. region.op(touchExcludeRegion, Region.Op.DIFFERENCE); + inputWindowHandle.setTouchableRegionCrop(null); } touchExcludeRegion.recycle(); } else { @@ -2298,11 +2315,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 @@ -2316,6 +2328,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); @@ -2349,12 +2366,11 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP private Configuration getProcessGlobalConfiguration() { // For child windows we want to use the pid for the parent window in case the the child // window was added from another process. - final int pid = getParentWindow() != null ? getParentWindow().mSession.mPid : mSession.mPid; + final WindowState parentWindow = getParentWindow(); + final int pid = parentWindow != null ? parentWindow.mSession.mPid : mSession.mPid; final Configuration processConfig = mWmService.mAtmService.getGlobalConfigurationForPid(pid); - mTempConfiguration.setTo(processConfig == null - ? mWmService.mRoot.getConfiguration() : processConfig); - return mTempConfiguration; + return processConfig; } void getMergedConfiguration(MergedConfiguration outConfiguration) { @@ -2365,6 +2381,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP void setLastReportedMergedConfiguration(MergedConfiguration config) { mLastReportedConfiguration.setTo(config); + mLastConfigReportedToClient = true; } void getLastReportedMergedConfiguration(MergedConfiguration config) { @@ -2512,6 +2529,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 +2553,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=" @@ -2926,6 +2943,20 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP subtractTouchExcludeRegionIfNeeded(outRegion); } + private void setTouchableRegionCropIfNeeded(InputWindowHandle handle) { + final Task task = getTask(); + if (task == null || !task.cropWindowsToStackBounds()) { + return; + } + + final TaskStack stack = task.mStack; + if (stack == null) { + return; + } + + handle.setTouchableRegionCrop(stack.getSurfaceControl()); + } + private void cropRegionToStackBoundsIfNeeded(Region region) { final Task task = getTask(); if (task == null || !task.cropWindowsToStackBounds()) { @@ -2989,11 +3020,29 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP return mAppToken.mFrozenMergedConfig.peek(); } + // If the process has not registered to any display to listen to the configuration change, + // we can simply return the mFullConfiguration as default. + if (!registeredForDisplayConfigChanges()) { + return super.getConfiguration(); + } + // We use the process config this window is associated with as the based global config since - // the process can override it config, but isn't part of the window hierarchy. - final Configuration config = getProcessGlobalConfiguration(); - config.updateFrom(getMergedOverrideConfiguration()); - return config; + // the process can override its config, but isn't part of the window hierarchy. + mTempConfiguration.setTo(getProcessGlobalConfiguration()); + mTempConfiguration.updateFrom(getMergedOverrideConfiguration()); + return mTempConfiguration; + } + + /** @return {@code true} if the process registered to a display as a config listener. */ + private boolean registeredForDisplayConfigChanges() { + final WindowState parentWindow = getParentWindow(); + final Session session = parentWindow != null ? parentWindow.mSession : mSession; + // System process or invalid process cannot register to display config change. + if (session.mPid == MY_PID || session.mPid < 0) return false; + WindowProcessController app = + mWmService.mAtmService.getProcessController(session.mPid, session.mUid); + if (app == null || !app.registeredForDisplayConfigChanges()) return false; + return true; } void reportResized() { @@ -3511,7 +3560,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); } @@ -4367,7 +4419,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); @@ -4422,7 +4474,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 @@ -4837,10 +4894,10 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP } /** - * Update a tap exclude region with a rectangular area identified by provided id. The requested - * area will be clipped to the window bounds. + * Update a tap exclude region identified by provided id. The requested area will be clipped to + * the window bounds. */ - void updateTapExcludeRegion(int regionId, int left, int top, int width, int height) { + void updateTapExcludeRegion(int regionId, Region region) { final DisplayContent currentDisplay = getDisplayContent(); if (currentDisplay == null) { throw new IllegalStateException("Trying to update window not attached to any display."); @@ -4854,7 +4911,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP currentDisplay.mTapExcludeProvidingWindows.add(this); } - mTapExcludeRegionHolder.updateRegion(regionId, left, top, width, height); + mTapExcludeRegionHolder.updateRegion(regionId, region); // Trigger touch exclude region update on current display. currentDisplay.updateTouchExcludeRegion(); // Trigger touchable region update for this window. 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/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp index 3d84bd40fb5a..3d6c8684e6d8 100644 --- a/services/core/jni/com_android_server_input_InputManagerService.cpp +++ b/services/core/jni/com_android_server_input_InputManagerService.cpp @@ -96,6 +96,7 @@ static struct { jmethodID interceptKeyBeforeDispatching; jmethodID dispatchUnhandledKey; jmethodID checkInjectEventsPermission; + jmethodID onPointerDownOutsideFocus; jmethodID getVirtualKeyQuietTimeMillis; jmethodID getExcludedDeviceNames; jmethodID getInputPortAssociations; @@ -259,6 +260,7 @@ public: virtual void pokeUserActivity(nsecs_t eventTime, int32_t eventType); virtual bool checkInjectEventsPermissionNonReentrant( int32_t injectorPid, int32_t injectorUid); + virtual void onPointerDownOutsideFocus(const sp<IBinder>& touchedToken); /* --- PointerControllerPolicyInterface implementation --- */ @@ -1205,6 +1207,15 @@ bool NativeInputManager::checkInjectEventsPermissionNonReentrant( return result; } +void NativeInputManager::onPointerDownOutsideFocus(const sp<IBinder>& touchedToken) { + ATRACE_CALL(); + JNIEnv* env = jniEnv(); + + jobject touchedTokenObj = javaObjectForIBinder(env, touchedToken); + env->CallVoidMethod(mServiceObj, gServiceClassInfo.onPointerDownOutsideFocus, touchedTokenObj); + checkAndClearExceptionFromCallback(env, "onPointerDownOutsideFocus"); +} + void NativeInputManager::loadPointerIcon(SpriteIcon* icon, int32_t displayId) { ATRACE_CALL(); JNIEnv* env = jniEnv(); @@ -1809,6 +1820,9 @@ int register_android_server_InputManager(JNIEnv* env) { GET_METHOD_ID(gServiceClassInfo.checkInjectEventsPermission, clazz, "checkInjectEventsPermission", "(II)Z"); + GET_METHOD_ID(gServiceClassInfo.onPointerDownOutsideFocus, clazz, + "onPointerDownOutsideFocus", "(Landroid/os/IBinder;)V"); + GET_METHOD_ID(gServiceClassInfo.getVirtualKeyQuietTimeMillis, clazz, "getVirtualKeyQuietTimeMillis", "()I"); diff --git a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp index 0b47b29e8d44..f447f475684d 100644 --- a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp +++ b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp @@ -52,7 +52,7 @@ static jmethodID method_reportStatus; static jmethodID method_reportSvStatus; static jmethodID method_reportAGpsStatus; static jmethodID method_reportNmea; -static jmethodID method_setEngineCapabilities; +static jmethodID method_setTopHalCapabilities; static jmethodID method_setGnssYearOfHardware; static jmethodID method_setGnssHardwareModelName; static jmethodID method_xtraDownloadRequest; @@ -71,7 +71,7 @@ static jmethodID method_reportMeasurementData; static jmethodID method_reportNavigationMessages; static jmethodID method_reportLocationBatch; static jmethodID method_reportGnssServiceDied; -static jmethodID method_setMeasurementCorrectionsCapabilities; +static jmethodID method_setSubHalMeasurementCorrectionsCapabilities; static jmethodID method_correctionsGetLatitudeDegrees; static jmethodID method_correctionsGetLongitudeDegrees; static jmethodID method_correctionsGetAltitudeMeters; @@ -754,7 +754,7 @@ Return <void> GnssCallback::gnssSetCapabilitesCbImpl(uint32_t capabilities, ALOGD("%s: capabilities=%du, hasSubHalCapabilityFlags=%d\n", __func__, capabilities, hasSubHalCapabilityFlags); JNIEnv* env = getJniEnv(); - env->CallVoidMethod(mCallbacksObj, method_setEngineCapabilities, capabilities, + env->CallVoidMethod(mCallbacksObj, method_setTopHalCapabilities, capabilities, boolToJbool(hasSubHalCapabilityFlags)); checkAndClearExceptionFromCallback(env, __FUNCTION__); return Void(); @@ -1237,7 +1237,8 @@ struct MeasurementCorrectionsCallback : public IMeasurementCorrectionsCallback { Return<void> MeasurementCorrectionsCallback::setCapabilitiesCb(uint32_t capabilities) { ALOGD("%s: %du\n", __func__, capabilities); JNIEnv* env = getJniEnv(); - env->CallVoidMethod(mCallbacksObj, method_setMeasurementCorrectionsCapabilities, capabilities); + env->CallVoidMethod(mCallbacksObj, method_setSubHalMeasurementCorrectionsCapabilities, + capabilities); checkAndClearExceptionFromCallback(env, __FUNCTION__); return Void(); } @@ -1541,7 +1542,7 @@ static void android_location_GnssLocationProvider_init_once(JNIEnv* env, jclass method_reportSvStatus = env->GetMethodID(clazz, "reportSvStatus", "(I[I[F[F[F[F)V"); method_reportAGpsStatus = env->GetMethodID(clazz, "reportAGpsStatus", "(II[B)V"); method_reportNmea = env->GetMethodID(clazz, "reportNmea", "(J)V"); - method_setEngineCapabilities = env->GetMethodID(clazz, "setEngineCapabilities", "(IZ)V"); + method_setTopHalCapabilities = env->GetMethodID(clazz, "setTopHalCapabilities", "(IZ)V"); method_setGnssYearOfHardware = env->GetMethodID(clazz, "setGnssYearOfHardware", "(I)V"); method_setGnssHardwareModelName = env->GetMethodID(clazz, "setGnssHardwareModelName", "(Ljava/lang/String;)V"); @@ -1581,8 +1582,8 @@ static void android_location_GnssLocationProvider_init_once(JNIEnv* env, jclass "(Ljava/lang/String;BLjava/lang/String;BLjava/lang/String;BZZ)V"); method_isInEmergencySession = env->GetMethodID(clazz, "isInEmergencySession", "()Z"); - method_setMeasurementCorrectionsCapabilities = env->GetMethodID(clazz, - "setMeasurementCorrectionsCapabilities", "(I)V"); + method_setSubHalMeasurementCorrectionsCapabilities = env->GetMethodID(clazz, + "setSubHalMeasurementCorrectionsCapabilities", "(I)V"); jclass measCorrClass = env->FindClass("android/location/GnssMeasurementCorrections"); method_correctionsGetLatitudeDegrees = env->GetMethodID( diff --git a/services/core/xsd/Android.bp b/services/core/xsd/Android.bp index 5e1ea897b86e..98e4343e6e57 100644 --- a/services/core/xsd/Android.bp +++ b/services/core/xsd/Android.bp @@ -2,5 +2,5 @@ xsd_config { name: "default-permissions", srcs: ["default-permissions.xsd"], api_dir: "schema", - package_name: "com.android.server.pm.permission", + package_name: "com.android.server.pm.permission.configfile", } diff --git a/services/core/xsd/default-permissions.xsd b/services/core/xsd/default-permissions.xsd index d800a26cdceb..2e32be0009ba 100644 --- a/services/core/xsd/default-permissions.xsd +++ b/services/core/xsd/default-permissions.xsd @@ -27,7 +27,7 @@ </xs:element> <xs:complexType name="exception"> <xs:sequence> - <xs:element name="permission" type="permission"/> + <xs:element name="permission" type="permission" maxOccurs="unbounded"/> </xs:sequence> <xs:attribute name="package" type="xs:string"/> <xs:attribute name="sha256-cert-digest" type="xs:string"/> diff --git a/services/core/xsd/schema/current.txt b/services/core/xsd/schema/current.txt index 4e67e5c235a0..a2092e3a99dc 100644 --- a/services/core/xsd/schema/current.txt +++ b/services/core/xsd/schema/current.txt @@ -1,21 +1,20 @@ // Signature format: 2.0 -package com.android.server.pm.permission { +package com.android.server.pm.permission.configfile { public class Exception { ctor public Exception(); method public String getBrand(); - method public com.android.server.pm.permission.Permission getPermission(); + method public java.util.List<com.android.server.pm.permission.configfile.Permission> getPermission(); method public String getSha256CertDigest(); method public String get_package(); method public void setBrand(String); - method public void setPermission(com.android.server.pm.permission.Permission); method public void setSha256CertDigest(String); method public void set_package(String); } public class Exceptions { ctor public Exceptions(); - method public java.util.List<com.android.server.pm.permission.Exception> getException(); + method public java.util.List<com.android.server.pm.permission.configfile.Exception> getException(); } public class Permission { @@ -28,7 +27,7 @@ package com.android.server.pm.permission { public class XmlParser { ctor public XmlParser(); - method public static com.android.server.pm.permission.Exceptions read(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException; + method public static com.android.server.pm.permission.configfile.Exceptions read(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException; method public static String readText(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException; method public static void skip(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException; } diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java b/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java index 2bf6f357bec8..cfa99445f45f 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java @@ -15,17 +15,10 @@ */ package com.android.server.devicepolicy; -import android.app.admin.DevicePolicyManager; import android.app.admin.IDevicePolicyManager; -import android.app.admin.StartInstallingUpdateCallback; -import android.content.ComponentName; -import android.os.ParcelFileDescriptor; import com.android.server.SystemService; -import java.util.Collections; -import java.util.List; - /** * Defines the required interface for IDevicePolicyManager implemenation. * @@ -63,83 +56,4 @@ abstract class BaseIDevicePolicyManager extends IDevicePolicyManager.Stub { public void clearSystemUpdatePolicyFreezePeriodRecord() { } - - @Override - public long forceNetworkLogs() { - return 0; - } - - @Override - public long forceSecurityLogs() { - return 0; - } - - @Override - public boolean checkDeviceIdentifierAccess(String packageName, int userHandle, int pid, - int uid) { - return false; - } - - @Override - public int setGlobalPrivateDns(ComponentName who, int mode, String privateDnsHost) { - return DevicePolicyManager.PRIVATE_DNS_SET_ERROR_FAILURE_SETTING; - } - - @Override - public int getGlobalPrivateDnsMode(ComponentName who) { - return DevicePolicyManager.PRIVATE_DNS_MODE_UNKNOWN; - } - - @Override - public String getGlobalPrivateDnsHost(ComponentName who) { - return null; - } - - @Override - public void grantDeviceIdsAccessToProfileOwner(ComponentName who, int userId) { } - - @Override - public int getPasswordComplexity() { - return DevicePolicyManager.PASSWORD_COMPLEXITY_NONE; - } - - @Override - public void installUpdateFromFile(ComponentName admin, - ParcelFileDescriptor updateFileDescriptor, StartInstallingUpdateCallback listener) {} - - @Override - public void setCrossProfileCalendarPackages(ComponentName admin, List<String> packageNames) { - } - - @Override - public List<String> getCrossProfileCalendarPackages(ComponentName admin) { - return Collections.emptyList(); - } - - @Override - public boolean isPackageAllowedToAccessCalendarForUser(String packageName, - int userHandle) { - return false; - } - - @Override - public List<String> getCrossProfileCalendarPackagesForUser(int userHandle) { - return Collections.emptyList(); - } - - @Override - public boolean isManagedKiosk() { - return false; - } - - @Override - public boolean isUnattendedManagedKiosk() { - return false; - } - - @Override - public boolean startViewCalendarEventInManagedProfile(String packageName, long eventId, - long start, long end, boolean allDay, int flags) { - return false; - } } diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 633367ab2fe8..b5c845a9d012 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -8398,13 +8398,40 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } @Override - public boolean checkDeviceIdentifierAccess(String packageName, int userHandle, int pid, - int uid) { + public boolean checkDeviceIdentifierAccess(String packageName, int pid, int uid) { // If the caller is not a system app then it should only be able to check its own device // identifier access. - int callingAppId = UserHandle.getAppId(mInjector.binderGetCallingUid()); - if (callingAppId >= Process.FIRST_APPLICATION_UID - && callingAppId != UserHandle.getAppId(uid)) { + int callingUid = mInjector.binderGetCallingUid(); + int callingPid = mInjector.binderGetCallingPid(); + if (UserHandle.getAppId(callingUid) >= Process.FIRST_APPLICATION_UID + && (callingUid != uid || callingPid != pid)) { + String message = String.format( + "Calling uid %d, pid %d cannot check device identifier access for package %s " + + "(uid=%d, pid=%d)", callingUid, callingPid, packageName, uid, pid); + Log.w(LOG_TAG, message); + throw new SecurityException(message); + } + // Verify that the specified packages matches the provided uid. + int userId = UserHandle.getUserId(uid); + try { + ApplicationInfo appInfo = mIPackageManager.getApplicationInfo(packageName, 0, userId); + // Since this call goes directly to PackageManagerService a NameNotFoundException is not + // thrown but null data can be returned; if the appInfo for the specified package cannot + // be found then return false to prevent crashing the app. + if (appInfo == null) { + Log.w(LOG_TAG, + String.format("appInfo could not be found for package %s", packageName)); + return false; + } else if (uid != appInfo.uid) { + String message = String.format("Package %s (uid=%d) does not match provided uid %d", + packageName, appInfo.uid, uid); + Log.w(LOG_TAG, message); + throw new SecurityException(message); + } + } catch (RemoteException e) { + // If an exception is caught obtaining the appInfo just return false to prevent crashing + // apps due to an internal error. + Log.e(LOG_TAG, "Exception caught obtaining appInfo for package " + packageName, e); return false; } // A device or profile owner must also have the READ_PHONE_STATE permission to access device @@ -8421,7 +8448,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { return true; } // Allow access to the profile owner for the specified user, or delegate cert installer - ComponentName profileOwner = getProfileOwnerAsUser(userHandle); + ComponentName profileOwner = getProfileOwnerAsUser(userId); if (profileOwner != null && (profileOwner.getPackageName().equals(packageName) || isCallerDelegate(packageName, uid, DELEGATION_CERT_INSTALL))) { return true; @@ -11180,48 +11207,51 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override public Intent createUserRestrictionSupportIntent(int userId, String userRestriction) { - int source; - long ident = mInjector.binderClearCallingIdentity(); + final long ident = mInjector.binderClearCallingIdentity(); try { - source = mUserManager.getUserRestrictionSource(userRestriction, - UserHandle.of(userId)); + final List<UserManager.EnforcingUser> sources = mUserManager + .getUserRestrictionSources(userRestriction, UserHandle.of(userId)); + if (sources == null || sources.isEmpty()) { + // The restriction is not enforced. + return null; + } else if (sources.size() > 1) { + // In this case, we'll show an admin support dialog that does not + // specify the admin. + // TODO(b/128928355): if this restriction is enforced by multiple DPCs, return + // the admin for the calling user. + return DevicePolicyManagerService.this.createShowAdminSupportIntent( + null, userId); + } + final UserManager.EnforcingUser enforcingUser = sources.get(0); + final int sourceType = enforcingUser.getUserRestrictionSource(); + final int enforcingUserId = enforcingUser.getUserHandle().getIdentifier(); + if (sourceType == UserManager.RESTRICTION_SOURCE_PROFILE_OWNER) { + // Restriction was enforced by PO + final ComponentName profileOwner = mOwners.getProfileOwnerComponent( + enforcingUserId); + if (profileOwner != null) { + return DevicePolicyManagerService.this.createShowAdminSupportIntent( + profileOwner, enforcingUserId); + } + } else if (sourceType == UserManager.RESTRICTION_SOURCE_DEVICE_OWNER) { + // Restriction was enforced by DO + final Pair<Integer, ComponentName> deviceOwner = + mOwners.getDeviceOwnerUserIdAndComponent(); + if (deviceOwner != null) { + return DevicePolicyManagerService.this.createShowAdminSupportIntent( + deviceOwner.second, deviceOwner.first); + } + } else if (sourceType == UserManager.RESTRICTION_SOURCE_SYSTEM) { + /* + * In this case, the user restriction is enforced by the system. + * So we won't show an admin support intent, even if it is also + * enforced by a profile/device owner. + */ + return null; + } } finally { mInjector.binderRestoreCallingIdentity(ident); } - if ((source & UserManager.RESTRICTION_SOURCE_SYSTEM) != 0) { - /* - * In this case, the user restriction is enforced by the system. - * So we won't show an admin support intent, even if it is also - * enforced by a profile/device owner. - */ - return null; - } - boolean enforcedByDo = (source & UserManager.RESTRICTION_SOURCE_DEVICE_OWNER) != 0; - boolean enforcedByPo = (source & UserManager.RESTRICTION_SOURCE_PROFILE_OWNER) != 0; - if (enforcedByDo && enforcedByPo) { - // In this case, we'll show an admin support dialog that does not - // specify the admin. - return DevicePolicyManagerService.this.createShowAdminSupportIntent(null, userId); - } else if (enforcedByPo) { - final ComponentName profileOwner = mOwners.getProfileOwnerComponent(userId); - if (profileOwner != null) { - return DevicePolicyManagerService.this - .createShowAdminSupportIntent(profileOwner, userId); - } - // This could happen if another thread has changed the profile owner since we called - // getUserRestrictionSource - return null; - } else if (enforcedByDo) { - final Pair<Integer, ComponentName> deviceOwner - = mOwners.getDeviceOwnerUserIdAndComponent(); - if (deviceOwner != null) { - return DevicePolicyManagerService.this - .createShowAdminSupportIntent(deviceOwner.second, deviceOwner.first); - } - // This could happen if another thread has changed the device owner since we called - // getUserRestrictionSource - return null; - } return null; } diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index d4ccb0b77bca..9d09c4c3637b 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -2133,6 +2133,11 @@ public final class SystemServer { traceBeginAndSlog("StartNetworkStack"); try { + // Note : the network stack is creating on-demand objects that need to send + // broadcasts, which means it currently depends on being started after + // ActivityManagerService.mSystemReady and ActivityManagerService.mProcessesReady + // are set to true. Be careful if moving this to a different place in the + // startup sequence. NetworkStackClient.getInstance().start(context); } catch (Throwable e) { reportWtf("starting Network Stack", e); diff --git a/services/net/Android.bp b/services/net/Android.bp index 7ef0ac4e1b84..8f48f5b3d292 100644 --- a/services/net/Android.bp +++ b/services/net/Android.bp @@ -58,6 +58,7 @@ java_library_static { name: "services.net", srcs: ["java/**/*.java"], static_libs: [ + "dnsresolver_aidl_interface-java", "netd_aidl_interface-java", "networkstack-aidl-interfaces-java", ] diff --git a/services/net/java/android/net/INetworkMonitor.aidl b/services/net/java/android/net/INetworkMonitor.aidl index 1b0e1d788ff3..b32ef12ab24d 100644 --- a/services/net/java/android/net/INetworkMonitor.aidl +++ b/services/net/java/android/net/INetworkMonitor.aidl @@ -15,6 +15,8 @@ */ package android.net; +import android.net.LinkProperties; +import android.net.NetworkCapabilities; import android.net.PrivateDnsConfigParcel; /** @hide */ @@ -45,9 +47,8 @@ oneway interface INetworkMonitor { void forceReevaluation(int uid); void notifyPrivateDnsChanged(in PrivateDnsConfigParcel config); void notifyDnsResponse(int returnCode); - void notifySystemReady(); - void notifyNetworkConnected(); + void notifyNetworkConnected(in LinkProperties lp, in NetworkCapabilities nc); void notifyNetworkDisconnected(); - void notifyLinkPropertiesChanged(); - void notifyNetworkCapabilitiesChanged(); -}
\ No newline at end of file + void notifyLinkPropertiesChanged(in LinkProperties lp); + void notifyNetworkCapabilitiesChanged(in NetworkCapabilities nc); +} diff --git a/services/net/java/android/net/ipmemorystore/NetworkAttributes.java b/services/net/java/android/net/ipmemorystore/NetworkAttributes.java index 6a9eae00e3ff..e76976991797 100644 --- a/services/net/java/android/net/ipmemorystore/NetworkAttributes.java +++ b/services/net/java/android/net/ipmemorystore/NetworkAttributes.java @@ -60,6 +60,13 @@ public class NetworkAttributes { public final Inet4Address assignedV4Address; private static final float WEIGHT_ASSIGNEDV4ADDR = 300.0f; + // The lease expiry timestamp of v4 address allocated from DHCP server, in milliseconds. + @Nullable + public final Long assignedV4AddressExpiry; + // lease expiry doesn't imply any correlation between "the same lease expiry value" and "the + // same L3 network". + private static final float WEIGHT_ASSIGNEDV4ADDREXPIRY = 0.0f; + // Optionally supplied by the client if it has an opinion on L3 network. For example, this // could be a hash of the SSID + security type on WiFi. @Nullable @@ -81,6 +88,7 @@ public class NetworkAttributes { /** @hide */ @VisibleForTesting public static final float TOTAL_WEIGHT = WEIGHT_ASSIGNEDV4ADDR + + WEIGHT_ASSIGNEDV4ADDREXPIRY + WEIGHT_GROUPHINT + WEIGHT_DNSADDRESSES + WEIGHT_MTU; @@ -89,11 +97,16 @@ public class NetworkAttributes { @VisibleForTesting public NetworkAttributes( @Nullable final Inet4Address assignedV4Address, + @Nullable final Long assignedV4AddressExpiry, @Nullable final String groupHint, @Nullable final List<InetAddress> dnsAddresses, @Nullable final Integer mtu) { if (mtu != null && mtu < 0) throw new IllegalArgumentException("MTU can't be negative"); + if (assignedV4AddressExpiry != null && assignedV4AddressExpiry <= 0) { + throw new IllegalArgumentException("lease expiry can't be negative or zero"); + } this.assignedV4Address = assignedV4Address; + this.assignedV4AddressExpiry = assignedV4AddressExpiry; this.groupHint = groupHint; this.dnsAddresses = null == dnsAddresses ? null : Collections.unmodifiableList(new ArrayList<>(dnsAddresses)); @@ -105,6 +118,8 @@ public class NetworkAttributes { // The call to the other constructor must be the first statement of this constructor, // so everything has to be inline this((Inet4Address) getByAddressOrNull(parcelable.assignedV4Address), + parcelable.assignedV4AddressExpiry > 0 + ? parcelable.assignedV4AddressExpiry : null, parcelable.groupHint, blobArrayToInetAddressList(parcelable.dnsAddresses), parcelable.mtu >= 0 ? parcelable.mtu : null); @@ -150,6 +165,8 @@ public class NetworkAttributes { final NetworkAttributesParcelable parcelable = new NetworkAttributesParcelable(); parcelable.assignedV4Address = (null == assignedV4Address) ? null : assignedV4Address.getAddress(); + parcelable.assignedV4AddressExpiry = + (null == assignedV4AddressExpiry) ? 0 : assignedV4AddressExpiry; parcelable.groupHint = groupHint; parcelable.dnsAddresses = inetAddressListToBlobArray(dnsAddresses); parcelable.mtu = (null == mtu) ? -1 : mtu; @@ -168,6 +185,8 @@ public class NetworkAttributes { public float getNetworkGroupSamenessConfidence(@NonNull final NetworkAttributes o) { final float samenessScore = samenessContribution(WEIGHT_ASSIGNEDV4ADDR, assignedV4Address, o.assignedV4Address) + + samenessContribution(WEIGHT_ASSIGNEDV4ADDREXPIRY, assignedV4AddressExpiry, + o.assignedV4AddressExpiry) + samenessContribution(WEIGHT_GROUPHINT, groupHint, o.groupHint) + samenessContribution(WEIGHT_DNSADDRESSES, dnsAddresses, o.dnsAddresses) + samenessContribution(WEIGHT_MTU, mtu, o.mtu); @@ -189,6 +208,8 @@ public class NetworkAttributes { @Nullable private Inet4Address mAssignedAddress; @Nullable + private Long mAssignedAddressExpiry; + @Nullable private String mGroupHint; @Nullable private List<InetAddress> mDnsAddresses; @@ -206,6 +227,20 @@ public class NetworkAttributes { } /** + * Set the lease expiry timestamp of assigned v4 address. + * @param assignedV4AddressExpiry The lease expiry timestamp of assigned v4 address. + * @return This builder. + */ + public Builder setAssignedV4AddressExpiry( + @Nullable final Long assignedV4AddressExpiry) { + if (null != assignedV4AddressExpiry && assignedV4AddressExpiry <= 0) { + throw new IllegalArgumentException("lease expiry can't be negative or zero"); + } + mAssignedAddressExpiry = assignedV4AddressExpiry; + return this; + } + + /** * Set the group hint. * @param groupHint The group hint. * @return This builder. @@ -248,14 +283,15 @@ public class NetworkAttributes { * @return The built NetworkAttributes object. */ public NetworkAttributes build() { - return new NetworkAttributes(mAssignedAddress, mGroupHint, mDnsAddresses, mMtu); + return new NetworkAttributes(mAssignedAddress, mAssignedAddressExpiry, + mGroupHint, mDnsAddresses, mMtu); } } /** @hide */ public boolean isEmpty() { - return (null == assignedV4Address) && (null == groupHint) - && (null == dnsAddresses) && (null == mtu); + return (null == assignedV4Address) && (null == assignedV4AddressExpiry) + && (null == groupHint) && (null == dnsAddresses) && (null == mtu); } @Override @@ -263,6 +299,7 @@ public class NetworkAttributes { if (!(o instanceof NetworkAttributes)) return false; final NetworkAttributes other = (NetworkAttributes) o; return Objects.equals(assignedV4Address, other.assignedV4Address) + && Objects.equals(assignedV4AddressExpiry, other.assignedV4AddressExpiry) && Objects.equals(groupHint, other.groupHint) && Objects.equals(dnsAddresses, other.dnsAddresses) && Objects.equals(mtu, other.mtu); @@ -270,7 +307,8 @@ public class NetworkAttributes { @Override public int hashCode() { - return Objects.hash(assignedV4Address, groupHint, dnsAddresses, mtu); + return Objects.hash(assignedV4Address, assignedV4AddressExpiry, + groupHint, dnsAddresses, mtu); } /** Pretty print */ @@ -286,6 +324,13 @@ public class NetworkAttributes { nullFields.add("assignedV4Addr"); } + if (null != assignedV4AddressExpiry) { + resultJoiner.add("assignedV4AddressExpiry :"); + resultJoiner.add(assignedV4AddressExpiry.toString()); + } else { + nullFields.add("assignedV4AddressExpiry"); + } + if (null != groupHint) { resultJoiner.add("groupHint :"); resultJoiner.add(groupHint); diff --git a/services/net/java/android/net/ipmemorystore/NetworkAttributesParcelable.aidl b/services/net/java/android/net/ipmemorystore/NetworkAttributesParcelable.aidl index 0894d7260915..997eb2b5128b 100644 --- a/services/net/java/android/net/ipmemorystore/NetworkAttributesParcelable.aidl +++ b/services/net/java/android/net/ipmemorystore/NetworkAttributesParcelable.aidl @@ -30,6 +30,7 @@ import android.net.ipmemorystore.Blob; */ parcelable NetworkAttributesParcelable { byte[] assignedV4Address; + long assignedV4AddressExpiry; String groupHint; Blob[] dnsAddresses; int mtu; 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/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java index cad71a26a76b..08f6a372de86 100644 --- a/services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java @@ -722,6 +722,147 @@ public class QuotaControllerTest { assertEquals(expectedStats, newStatsRare); } + /** + * Test getTimeUntilQuotaConsumedLocked when the determination is based within the bucket + * window. + */ + @Test + public void testGetTimeUntilQuotaConsumedLocked_BucketWindow() { + final long now = JobSchedulerService.sElapsedRealtimeClock.millis(); + // Close to RARE boundary. + mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE, + createTimingSession(now - (24 * HOUR_IN_MILLIS - 30 * SECOND_IN_MILLIS), + 30 * SECOND_IN_MILLIS, 5)); + // Far away from FREQUENT boundary. + mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE, + createTimingSession(now - (7 * HOUR_IN_MILLIS), 3 * MINUTE_IN_MILLIS, 5)); + // Overlap WORKING_SET boundary. + mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE, + createTimingSession(now - (2 * HOUR_IN_MILLIS + MINUTE_IN_MILLIS), + 3 * MINUTE_IN_MILLIS, 5)); + // Close to ACTIVE boundary. + mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE, + createTimingSession(now - (9 * MINUTE_IN_MILLIS), 3 * MINUTE_IN_MILLIS, 5)); + + setStandbyBucket(RARE_INDEX); + assertEquals(30 * SECOND_IN_MILLIS, + mQuotaController.getRemainingExecutionTimeLocked(SOURCE_USER_ID, SOURCE_PACKAGE)); + assertEquals(MINUTE_IN_MILLIS, + mQuotaController.getTimeUntilQuotaConsumedLocked(SOURCE_USER_ID, SOURCE_PACKAGE)); + + setStandbyBucket(FREQUENT_INDEX); + assertEquals(MINUTE_IN_MILLIS, + mQuotaController.getRemainingExecutionTimeLocked(SOURCE_USER_ID, SOURCE_PACKAGE)); + assertEquals(MINUTE_IN_MILLIS, + mQuotaController.getTimeUntilQuotaConsumedLocked(SOURCE_USER_ID, SOURCE_PACKAGE)); + + setStandbyBucket(WORKING_INDEX); + assertEquals(5 * MINUTE_IN_MILLIS, + mQuotaController.getRemainingExecutionTimeLocked(SOURCE_USER_ID, SOURCE_PACKAGE)); + assertEquals(7 * MINUTE_IN_MILLIS, + mQuotaController.getTimeUntilQuotaConsumedLocked(SOURCE_USER_ID, SOURCE_PACKAGE)); + + // ACTIVE window = allowed time, so jobs can essentially run non-stop until they reach the + // max execution time. + setStandbyBucket(ACTIVE_INDEX); + assertEquals(7 * MINUTE_IN_MILLIS, + mQuotaController.getRemainingExecutionTimeLocked(SOURCE_USER_ID, SOURCE_PACKAGE)); + assertEquals(mConstants.QUOTA_CONTROLLER_MAX_EXECUTION_TIME_MS - 9 * MINUTE_IN_MILLIS, + mQuotaController.getTimeUntilQuotaConsumedLocked(SOURCE_USER_ID, SOURCE_PACKAGE)); + } + + /** + * Test getTimeUntilQuotaConsumedLocked when the app is close to the max execution limit. + */ + @Test + public void testGetTimeUntilQuotaConsumedLocked_MaxExecution() { + final long now = JobSchedulerService.sElapsedRealtimeClock.millis(); + // Overlap boundary. + mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE, + createTimingSession( + now - (24 * HOUR_IN_MILLIS + 8 * MINUTE_IN_MILLIS), 4 * HOUR_IN_MILLIS, 5)); + + setStandbyBucket(WORKING_INDEX); + assertEquals(8 * MINUTE_IN_MILLIS, + mQuotaController.getRemainingExecutionTimeLocked(SOURCE_USER_ID, SOURCE_PACKAGE)); + // Max time will phase out, so should use bucket limit. + assertEquals(10 * MINUTE_IN_MILLIS, + mQuotaController.getTimeUntilQuotaConsumedLocked(SOURCE_USER_ID, SOURCE_PACKAGE)); + + mQuotaController.getTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE).clear(); + // Close to boundary. + mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE, + createTimingSession(now - (24 * HOUR_IN_MILLIS - MINUTE_IN_MILLIS), + 4 * HOUR_IN_MILLIS - 5 * MINUTE_IN_MILLIS, 5)); + + setStandbyBucket(WORKING_INDEX); + assertEquals(5 * MINUTE_IN_MILLIS, + mQuotaController.getRemainingExecutionTimeLocked(SOURCE_USER_ID, SOURCE_PACKAGE)); + assertEquals(10 * MINUTE_IN_MILLIS, + mQuotaController.getTimeUntilQuotaConsumedLocked(SOURCE_USER_ID, SOURCE_PACKAGE)); + + mQuotaController.getTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE).clear(); + // Far from boundary. + mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE, + createTimingSession( + now - (20 * HOUR_IN_MILLIS), 4 * HOUR_IN_MILLIS - 3 * MINUTE_IN_MILLIS, 5)); + + setStandbyBucket(WORKING_INDEX); + assertEquals(3 * MINUTE_IN_MILLIS, + mQuotaController.getRemainingExecutionTimeLocked(SOURCE_USER_ID, SOURCE_PACKAGE)); + assertEquals(3 * MINUTE_IN_MILLIS, + mQuotaController.getTimeUntilQuotaConsumedLocked(SOURCE_USER_ID, SOURCE_PACKAGE)); + } + + /** + * Test getTimeUntilQuotaConsumedLocked when the max execution time and bucket window time + * remaining are equal. + */ + @Test + public void testGetTimeUntilQuotaConsumedLocked_EqualTimeRemaining() { + final long now = JobSchedulerService.sElapsedRealtimeClock.millis(); + setStandbyBucket(FREQUENT_INDEX); + + // Overlap boundary. + mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE, + createTimingSession( + now - (24 * HOUR_IN_MILLIS + 11 * MINUTE_IN_MILLIS), + 4 * HOUR_IN_MILLIS, + 5)); + mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE, + createTimingSession( + now - (8 * HOUR_IN_MILLIS + MINUTE_IN_MILLIS), 3 * MINUTE_IN_MILLIS, 5)); + + // Both max and bucket time have 8 minutes left. + assertEquals(8 * MINUTE_IN_MILLIS, + mQuotaController.getRemainingExecutionTimeLocked(SOURCE_USER_ID, SOURCE_PACKAGE)); + // Max time essentially free. Bucket time has 2 min phase out plus original 8 minute + // window time. + assertEquals(10 * MINUTE_IN_MILLIS, + mQuotaController.getTimeUntilQuotaConsumedLocked(SOURCE_USER_ID, SOURCE_PACKAGE)); + + mQuotaController.getTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE).clear(); + // Overlap boundary. + mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE, + createTimingSession( + now - (24 * HOUR_IN_MILLIS + MINUTE_IN_MILLIS), 2 * MINUTE_IN_MILLIS, 5)); + mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE, + createTimingSession( + now - (20 * HOUR_IN_MILLIS), + 3 * HOUR_IN_MILLIS + 48 * MINUTE_IN_MILLIS, + 5)); + mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE, + createTimingSession( + now - (8 * HOUR_IN_MILLIS + MINUTE_IN_MILLIS), 3 * MINUTE_IN_MILLIS, 5)); + + // Both max and bucket time have 8 minutes left. + assertEquals(8 * MINUTE_IN_MILLIS, + mQuotaController.getRemainingExecutionTimeLocked(SOURCE_USER_ID, SOURCE_PACKAGE)); + // Max time only has one minute phase out. Bucket time has 2 minute phase out. + assertEquals(9 * MINUTE_IN_MILLIS, + mQuotaController.getTimeUntilQuotaConsumedLocked(SOURCE_USER_ID, SOURCE_PACKAGE)); + } + @Test public void testIsWithinQuotaLocked_NeverApp() { assertFalse(mQuotaController.isWithinQuotaLocked(0, "com.android.test.never", NEVER_INDEX)); @@ -1902,7 +2043,10 @@ public class QuotaControllerTest { // window, so as the package "reaches its quota" it will have more to keep running. mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE, createTimingSession(now - 2 * HOUR_IN_MILLIS, - 10 * MINUTE_IN_MILLIS - remainingTimeMs, 1)); + 10 * SECOND_IN_MILLIS - remainingTimeMs, 1)); + mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE, + createTimingSession(now - HOUR_IN_MILLIS, + 9 * MINUTE_IN_MILLIS + 50 * SECOND_IN_MILLIS, 1)); assertEquals(remainingTimeMs, mQuotaController.getRemainingExecutionTimeLocked(jobStatus)); // Start the job. @@ -1919,6 +2063,18 @@ public class QuotaControllerTest { // amount of remaining time left its quota. assertEquals(remainingTimeMs, mQuotaController.getRemainingExecutionTimeLocked(SOURCE_USER_ID, SOURCE_PACKAGE)); - verify(handler, atLeast(1)).sendMessageDelayed(any(), eq(remainingTimeMs)); + // Handler is told to check when the quota will be consumed, not when the initial + // remaining time is over. + verify(handler, atLeast(1)).sendMessageDelayed(any(), eq(10 * SECOND_IN_MILLIS)); + verify(handler, never()).sendMessageDelayed(any(), eq(remainingTimeMs)); + + // After 10 seconds, the job should finally be out of quota. + advanceElapsedClock(10 * SECOND_IN_MILLIS - remainingTimeMs); + // Wait for some extra time to allow for job processing. + verify(mJobSchedulerService, + timeout(12 * SECOND_IN_MILLIS).times(1)) + .onControllerStateChanged(); + assertFalse(jobStatus.isConstraintSatisfied(JobStatus.CONSTRAINT_WITHIN_QUOTA)); + verify(handler, never()).sendMessageDelayed(any(), anyInt()); } } diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityServiceConnectionTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityServiceConnectionTest.java index 2ed25eab50c0..f3364974231b 100644 --- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityServiceConnectionTest.java +++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityServiceConnectionTest.java @@ -23,10 +23,12 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.accessibilityservice.AccessibilityServiceInfo; +import android.accessibilityservice.IAccessibilityServiceClient; import android.content.ComponentName; import android.content.Context; import android.content.Intent; @@ -46,6 +48,7 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; import java.util.Arrays; +import java.util.Collections; import java.util.HashSet; @@ -149,4 +152,21 @@ public class AccessibilityServiceConnectionTest { assertTrue(mConnection.getServiceInfo().crashed); verify(mMockKeyEventDispatcher).flush(mConnection); } + + @Test + public void connectedService_notInEnabledServiceList_doNotInitClient() + throws RemoteException { + IBinder mockBinder = mock(IBinder.class); + IAccessibilityServiceClient mockClient = mock(IAccessibilityServiceClient.class); + when(mockBinder.queryLocalInterface(any())).thenReturn(mockClient); + when(mMockUserState.getEnabledServicesLocked()) + .thenReturn(Collections.emptySet()); + setServiceBinding(COMPONENT_NAME); + + mConnection.bindLocked(); + mConnection.onServiceConnected(COMPONENT_NAME, mockBinder); + mHandler.sendAllMessages(); + verify(mMockSystemSupport, times(2)).onClientChangeLocked(false); + verify(mockClient, times(0)).init(any(), anyInt(), any()); + } } 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..46d076184eef 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,13 +66,17 @@ 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.os.storage.IStorageManager; import android.platform.test.annotations.Presubmit; import android.util.Log; + import androidx.test.filters.FlakyTest; import androidx.test.filters.SmallTest; +import com.android.server.FgThread; import com.android.server.pm.UserManagerService; import com.android.server.wm.WindowManagerService; @@ -79,7 +85,9 @@ import org.junit.Before; import org.junit.Test; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; +import java.util.HashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; @@ -92,12 +100,20 @@ import java.util.Set; */ @SmallTest @Presubmit + public class UserControllerTest { - private static final int TEST_USER_ID = 10; + // Use big enough user id to avoid picking up already active user id. + private static final int TEST_USER_ID = 100; + private static final int TEST_USER_ID1 = 101; + private static final int TEST_USER_ID2 = 102; private static final int NONEXIST_USER_ID = 2; private static final String TAG = UserControllerTest.class.getSimpleName(); + + private static final long HANDLER_WAIT_TIME_MS = 100; + private UserController mUserController; private TestInjector mInjector; + private final HashMap<Integer, UserState> mUserStates = new HashMap<>(); private static final List<String> START_FOREGROUND_USER_ACTIONS = newArrayList( Intent.ACTION_USER_STARTED, @@ -127,6 +143,11 @@ public class UserControllerTest { doNothing().when(mInjector).startHomeActivity(anyInt(), anyString()); doReturn(false).when(mInjector).stackSupervisorSwitchUser(anyInt(), any()); doNothing().when(mInjector).stackSupervisorResumeFocusedStackTopActivity(); + doNothing().when(mInjector).systemServiceManagerCleanupUser(anyInt()); + doNothing().when(mInjector).activityManagerForceStopPackage(anyInt(), anyString()); + doNothing().when(mInjector).activityManagerOnUserStopped(anyInt()); + doNothing().when(mInjector).clearBroadcastQueueForUser(anyInt()); + doNothing().when(mInjector).stackSupervisorRemoveUser(anyInt()); mUserController = new UserController(mInjector); setUpUser(TEST_USER_ID, 0); }); @@ -258,7 +279,7 @@ public class UserControllerTest { } @Test - public void testContinueUserSwitch() { + public void testContinueUserSwitch() throws RemoteException { // Start user -- this will update state of mUserController mUserController.startUser(TEST_USER_ID, true); Message reportMsg = mInjector.mHandler.getMessageForCode(REPORT_USER_SWITCH_MSG); @@ -270,11 +291,11 @@ public class UserControllerTest { // Verify that continueUserSwitch worked as expected mUserController.continueUserSwitch(userState, oldUserId, newUserId); verify(mInjector.getWindowManager(), times(1)).stopFreezingScreen(); - continueUserSwitchAssertions(); + continueUserSwitchAssertions(TEST_USER_ID, false); } @Test - public void testContinueUserSwitchUIDisabled() { + public void testContinueUserSwitchUIDisabled() throws RemoteException { mUserController.mUserSwitchUiEnabled = false; // Start user -- this will update state of mUserController mUserController.startUser(TEST_USER_ID, true); @@ -287,16 +308,21 @@ public class UserControllerTest { // Verify that continueUserSwitch worked as expected mUserController.continueUserSwitch(userState, oldUserId, newUserId); verify(mInjector.getWindowManager(), never()).stopFreezingScreen(); - continueUserSwitchAssertions(); + continueUserSwitchAssertions(TEST_USER_ID, false); } - private void continueUserSwitchAssertions() { - Set<Integer> expectedCodes = Collections.singleton(REPORT_USER_SWITCH_COMPLETE_MSG); + private void continueUserSwitchAssertions(int expectedUserId, boolean backgroundUserStopping) + throws RemoteException { + Set<Integer> expectedCodes = new LinkedHashSet<>(); + expectedCodes.add(REPORT_USER_SWITCH_COMPLETE_MSG); + if (backgroundUserStopping) { + expectedCodes.add(0); // this is for directly posting in stopping. + } Set<Integer> actualCodes = mInjector.mHandler.getMessageCodes(); assertEquals("Unexpected message sent", expectedCodes, actualCodes); Message msg = mInjector.mHandler.getMessageForCode(REPORT_USER_SWITCH_COMPLETE_MSG); assertNotNull(msg); - assertEquals("Unexpected userId", TEST_USER_ID, msg.arg1); + assertEquals("Unexpected userId", expectedUserId, msg.arg1); } @Test @@ -321,6 +347,128 @@ 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()); + } + + /** + * Test stopping of user from max running users limit. + */ + @Test + public void testUserStoppingForMultipleUsersNormalMode() + throws InterruptedException, RemoteException { + setUpUser(TEST_USER_ID1, 0); + setUpUser(TEST_USER_ID2, 0); + mUserController.mMaxRunningUsers = 3; + int numerOfUserSwitches = 1; + addForegroundUserAndContinueUserSwitch(TEST_USER_ID, UserHandle.USER_SYSTEM, + numerOfUserSwitches, false); + // running: user 0, USER_ID + assertTrue(mUserController.canStartMoreUsers()); + assertEquals(Arrays.asList(new Integer[] {0, TEST_USER_ID}), + mUserController.getRunningUsersLU()); + + numerOfUserSwitches++; + addForegroundUserAndContinueUserSwitch(TEST_USER_ID1, TEST_USER_ID, + numerOfUserSwitches, false); + // running: user 0, USER_ID, USER_ID1 + assertFalse(mUserController.canStartMoreUsers()); + assertEquals(Arrays.asList(new Integer[] {0, TEST_USER_ID, TEST_USER_ID1}), + mUserController.getRunningUsersLU()); + + numerOfUserSwitches++; + addForegroundUserAndContinueUserSwitch(TEST_USER_ID2, TEST_USER_ID1, + numerOfUserSwitches, false); + UserState ussUser2 = mUserStates.get(TEST_USER_ID2); + // skip middle step and call this directly. + mUserController.finishUserSwitch(ussUser2); + waitForHandlerToComplete(mInjector.mHandler, HANDLER_WAIT_TIME_MS); + // running: user 0, USER_ID1, USER_ID2 + // USER_ID should be stopped as it is least recently used non user0. + assertFalse(mUserController.canStartMoreUsers()); + assertEquals(Arrays.asList(new Integer[] {0, TEST_USER_ID1, TEST_USER_ID2}), + mUserController.getRunningUsersLU()); + } + + /** + * This test tests delayed locking mode using 4 users. As core logic of delayed locking is + * happening in finishUserStopped call, the test also calls finishUserStopped while skipping + * all middle steps which takes too much work to mock. + */ + @Test + public void testUserStoppingForMultipleUsersDelayedLockingMode() + throws InterruptedException, RemoteException { + setUpUser(TEST_USER_ID1, 0); + setUpUser(TEST_USER_ID2, 0); + mUserController.mMaxRunningUsers = 3; + mUserController.mDelayUserDataLocking = true; + int numerOfUserSwitches = 1; + addForegroundUserAndContinueUserSwitch(TEST_USER_ID, UserHandle.USER_SYSTEM, + numerOfUserSwitches, false); + // running: user 0, USER_ID + assertTrue(mUserController.canStartMoreUsers()); + assertEquals(Arrays.asList(new Integer[] {0, TEST_USER_ID}), + mUserController.getRunningUsersLU()); + numerOfUserSwitches++; + + addForegroundUserAndContinueUserSwitch(TEST_USER_ID1, TEST_USER_ID, + numerOfUserSwitches, true); + // running: user 0, USER_ID1 + // stopped + unlocked: USER_ID + numerOfUserSwitches++; + assertTrue(mUserController.canStartMoreUsers()); + assertEquals(Arrays.asList(new Integer[] {0, TEST_USER_ID1}), + mUserController.getRunningUsersLU()); + // Skip all other steps and test unlock delaying only + UserState uss = mUserStates.get(TEST_USER_ID); + uss.setState(UserState.STATE_SHUTDOWN); // necessary state change from skipped part + mUserController.finishUserStopped(uss); + // Cannot mock FgThread handler, so confirm that there is no posted message left before + // checking. + waitForHandlerToComplete(FgThread.getHandler(), HANDLER_WAIT_TIME_MS); + verify(mInjector.mStorageManagerMock, times(0)) + .lockUserKey(anyInt()); + + addForegroundUserAndContinueUserSwitch(TEST_USER_ID2, TEST_USER_ID1, + numerOfUserSwitches, true); + // running: user 0, USER_ID2 + // stopped + unlocked: USER_ID1 + // stopped + locked: USER_ID + assertTrue(mUserController.canStartMoreUsers()); + assertEquals(Arrays.asList(new Integer[] {0, TEST_USER_ID2}), + mUserController.getRunningUsersLU()); + UserState ussUser1 = mUserStates.get(TEST_USER_ID1); + ussUser1.setState(UserState.STATE_SHUTDOWN); + mUserController.finishUserStopped(ussUser1); + waitForHandlerToComplete(FgThread.getHandler(), HANDLER_WAIT_TIME_MS); + verify(mInjector.mStorageManagerMock, times(1)) + .lockUserKey(TEST_USER_ID); + } + + private void addForegroundUserAndContinueUserSwitch(int newUserId, int expectedOldUserId, + int expectedNumberOfCalls, boolean expectOldUserStopping) + throws RemoteException { + // Start user -- this will update state of mUserController + mUserController.startUser(newUserId, true); + Message reportMsg = mInjector.mHandler.getMessageForCode(REPORT_USER_SWITCH_MSG); + assertNotNull(reportMsg); + UserState userState = (UserState) reportMsg.obj; + int oldUserId = reportMsg.arg1; + assertEquals(expectedOldUserId, oldUserId); + assertEquals(newUserId, reportMsg.arg2); + mUserStates.put(newUserId, userState); + mInjector.mHandler.clearAllRecordedMessages(); + // Verify that continueUserSwitch worked as expected + mUserController.continueUserSwitch(userState, oldUserId, newUserId); + verify(mInjector.getWindowManager(), times(expectedNumberOfCalls)) + .stopFreezingScreen(); + continueUserSwitchAssertions(newUserId, expectOldUserStopping); + } + private void setUpUser(int userId, int flags) { UserInfo userInfo = new UserInfo(userId, "User" + userId, flags); when(mInjector.mUserManagerMock.getUserInfo(eq(userId))).thenReturn(userInfo); @@ -334,6 +482,22 @@ public class UserControllerTest { return result; } + private void waitForHandlerToComplete(Handler handler, long waitTimeMs) + throws InterruptedException { + if (!handler.hasMessagesOrCallbacks()) { // if nothing queued, do not wait. + return; + } + final Object lock = new Object(); + synchronized (lock) { + handler.post(() -> { + synchronized (lock) { + lock.notify(); + } + }); + lock.wait(waitTimeMs); + } + } + // Should be public to allow mocking private static class TestInjector extends UserController.Injector { public final TestHandler mHandler; @@ -342,8 +506,11 @@ public class UserControllerTest { public final List<Intent> mSentIntents = new ArrayList<>(); private final TestHandler mUiHandler; + + private final IStorageManager mStorageManagerMock; private final UserManagerInternal mUserManagerInternalMock; private final WindowManagerService mWindowManagerMock; + private final Context mCtx; TestInjector(Context ctx) { @@ -356,6 +523,7 @@ public class UserControllerTest { mUserManagerMock = mock(UserManagerService.class); mUserManagerInternalMock = mock(UserManagerInternal.class); mWindowManagerMock = mock(WindowManagerService.class); + mStorageManagerMock = mock(IStorageManager.class); } @Override @@ -417,6 +585,17 @@ public class UserControllerTest { @Override void reportCurWakefulnessUsageEvent() { } + + @Override + boolean isRuntimeRestarted() { + // to pass all metrics related calls + return true; + } + + @Override + protected IStorageManager getStorageManager() { + return mStorageManagerMock; + } } private static class TestHandler extends Handler { diff --git a/services/tests/servicestests/src/com/android/server/backup/TrampolineTest.java b/services/tests/servicestests/src/com/android/server/backup/TrampolineTest.java index dd79aad52fd2..29cbf988fd56 100644 --- a/services/tests/servicestests/src/com/android/server/backup/TrampolineTest.java +++ b/services/tests/servicestests/src/com/android/server/backup/TrampolineTest.java @@ -95,6 +95,7 @@ public class TrampolineTest { new ComponentName("package2", "class2") }; private static final int NON_USER_SYSTEM = UserHandle.USER_SYSTEM + 1; + private static final int UNSTARTED_NON_USER_SYSTEM = UserHandle.USER_SYSTEM + 2; @UserIdInt private int mUserId; @@ -126,8 +127,6 @@ public class TrampolineTest { private TrampolineTestable mTrampoline; private File mTestDir; private File mSuppressFile; - private File mActivatedFile; - private File mRememberActivatedFile; @Before public void setUp() throws Exception { @@ -141,6 +140,7 @@ public class TrampolineTest { when(mUserManagerMock.getUserInfo(UserHandle.USER_SYSTEM)).thenReturn(mUserInfoMock); when(mUserManagerMock.getUserInfo(NON_USER_SYSTEM)).thenReturn(mUserInfoMock); + when(mUserManagerMock.getUserInfo(UNSTARTED_NON_USER_SYSTEM)).thenReturn(mUserInfoMock); TrampolineTestable.sBackupManagerServiceMock = mBackupManagerServiceMock; TrampolineTestable.sCallingUserId = UserHandle.USER_SYSTEM; @@ -154,18 +154,31 @@ public class TrampolineTest { mSuppressFile = new File(mTestDir, "suppress"); TrampolineTestable.sSuppressFile = mSuppressFile; - mActivatedFile = new File(mTestDir, "activate-" + NON_USER_SYSTEM); - TrampolineTestable.sActivatedFiles.append(NON_USER_SYSTEM, mActivatedFile); - mRememberActivatedFile = new File(mTestDir, "rem-activate-" + NON_USER_SYSTEM); - TrampolineTestable.sRememberActivatedFiles.append(NON_USER_SYSTEM, mRememberActivatedFile); + setUpStateFilesForNonSystemUser(NON_USER_SYSTEM); + setUpStateFilesForNonSystemUser(UNSTARTED_NON_USER_SYSTEM); mTrampoline = new TrampolineTestable(mContextMock); } + private void setUpStateFilesForNonSystemUser(int userId) { + File activatedFile = new File(mTestDir, "activate-" + userId); + TrampolineTestable.sActivatedFiles.append(userId, activatedFile); + File rememberActivatedFile = new File(mTestDir, "rem-activate-" + userId); + TrampolineTestable.sRememberActivatedFiles.append(userId, rememberActivatedFile); + } + @After public void tearDown() throws Exception { mSuppressFile.delete(); - mActivatedFile.delete(); + deleteFiles(TrampolineTestable.sActivatedFiles); + deleteFiles(TrampolineTestable.sRememberActivatedFiles); + } + + private void deleteFiles(SparseArray<File> files) { + int numFiles = files.size(); + for (int i = 0; i < numFiles; i++) { + files.valueAt(i).delete(); + } } @Test @@ -245,6 +258,16 @@ public class TrampolineTest { } @Test + public void + isBackupServiceActive_forUnstartedNonSystemUser_returnsTrueWhenSystemAndUserActivated() + throws Exception { + mTrampoline.initializeService(); + mTrampoline.setBackupServiceActive(UNSTARTED_NON_USER_SYSTEM, true); + + assertTrue(mTrampoline.isBackupServiceActive(UNSTARTED_NON_USER_SYSTEM)); + } + + @Test public void setBackupServiceActive_forSystemUserAndCallerSystemUid_serviceCreated() { mTrampoline.initializeService(); TrampolineTestable.sCallingUid = Process.SYSTEM_UID; @@ -421,7 +444,8 @@ public class TrampolineTest { mTrampoline.setBackupServiceActive(NON_USER_SYSTEM, true); - assertTrue(RandomAccessFileUtils.readBoolean(mRememberActivatedFile, false)); + assertTrue(RandomAccessFileUtils.readBoolean( + TrampolineTestable.sRememberActivatedFiles.get(NON_USER_SYSTEM), false)); } @Test @@ -430,7 +454,8 @@ public class TrampolineTest { mTrampoline.setBackupServiceActive(NON_USER_SYSTEM, false); - assertFalse(RandomAccessFileUtils.readBoolean(mRememberActivatedFile, true)); + assertFalse(RandomAccessFileUtils.readBoolean( + TrampolineTestable.sRememberActivatedFiles.get(NON_USER_SYSTEM), true)); } @Test @@ -440,7 +465,8 @@ public class TrampolineTest { mTrampoline.setBackupServiceActive(NON_USER_SYSTEM, true); mTrampoline.setBackupServiceActive(NON_USER_SYSTEM, false); - assertFalse(RandomAccessFileUtils.readBoolean(mRememberActivatedFile, true)); + assertFalse(RandomAccessFileUtils.readBoolean( + TrampolineTestable.sRememberActivatedFiles.get(NON_USER_SYSTEM), true)); } @Test 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/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java index 5b1970004971..cbabb0b350d1 100644 --- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java @@ -100,7 +100,6 @@ import com.android.server.pm.UserRestrictionsUtils; import org.hamcrest.BaseMatcher; import org.hamcrest.Description; import org.mockito.Mockito; -import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; import java.io.File; @@ -242,29 +241,23 @@ public class DevicePolicyManagerTest extends DpmTestBase { final Map<Pair<String, UserHandle>, Bundle> appRestrictions = new HashMap<>(); // UM.setApplicationRestrictions() will save to appRestrictions. - doAnswer(new Answer<Void>() { - @Override - public Void answer(InvocationOnMock invocation) throws Throwable { - String pkg = (String) invocation.getArguments()[0]; - Bundle bundle = (Bundle) invocation.getArguments()[1]; - UserHandle user = (UserHandle) invocation.getArguments()[2]; + doAnswer((Answer<Void>) invocation -> { + String pkg = (String) invocation.getArguments()[0]; + Bundle bundle = (Bundle) invocation.getArguments()[1]; + UserHandle user = (UserHandle) invocation.getArguments()[2]; - appRestrictions.put(Pair.create(pkg, user), bundle); + appRestrictions.put(Pair.create(pkg, user), bundle); - return null; - } + return null; }).when(getServices().userManager).setApplicationRestrictions( anyString(), nullable(Bundle.class), any(UserHandle.class)); // UM.getApplicationRestrictions() will read from appRestrictions. - doAnswer(new Answer<Bundle>() { - @Override - public Bundle answer(InvocationOnMock invocation) throws Throwable { - String pkg = (String) invocation.getArguments()[0]; - UserHandle user = (UserHandle) invocation.getArguments()[1]; - - return appRestrictions.get(Pair.create(pkg, user)); - } + doAnswer((Answer<Bundle>) invocation -> { + String pkg = (String) invocation.getArguments()[0]; + UserHandle user = (UserHandle) invocation.getArguments()[1]; + + return appRestrictions.get(Pair.create(pkg, user)); }).when(getServices().userManager).getApplicationRestrictions( anyString(), any(UserHandle.class)); @@ -2243,11 +2236,13 @@ public class DevicePolicyManagerTest extends DpmTestBase { intent = dpm.createAdminSupportIntent(UserManager.DISALLOW_ADJUST_VOLUME); assertNull(intent); - // Permission that is set by device owner returns correct intent - when(getServices().userManager.getUserRestrictionSource( + // UM.getUserRestrictionSources() will return a list of size 1 with the caller resource. + doAnswer((Answer<List<UserManager.EnforcingUser>>) invocation -> Collections.singletonList( + new UserManager.EnforcingUser( + UserHandle.myUserId(), UserManager.RESTRICTION_SOURCE_DEVICE_OWNER)) + ).when(getServices().userManager).getUserRestrictionSources( eq(UserManager.DISALLOW_ADJUST_VOLUME), - eq(UserHandle.getUserHandleForUid(mContext.binder.callingUid)))) - .thenReturn(UserManager.RESTRICTION_SOURCE_DEVICE_OWNER); + eq(UserHandle.getUserHandleForUid(UserHandle.myUserId()))); intent = dpm.createAdminSupportIntent(UserManager.DISALLOW_ADJUST_VOLUME); assertNotNull(intent); assertEquals(Settings.ACTION_SHOW_ADMIN_SUPPORT_DETAILS, intent.getAction()); diff --git a/services/tests/servicestests/src/com/android/server/job/JobStoreTest.java b/services/tests/servicestests/src/com/android/server/job/JobStoreTest.java index 78751a1e2ad5..3a0f4c24ee29 100644 --- a/services/tests/servicestests/src/com/android/server/job/JobStoreTest.java +++ b/services/tests/servicestests/src/com/android/server/job/JobStoreTest.java @@ -31,7 +31,6 @@ import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; import com.android.internal.util.HexDump; -import com.android.server.IoThread; import com.android.server.LocalServices; import com.android.server.job.JobStore.JobSet; import com.android.server.job.controllers.JobStatus; @@ -45,8 +44,6 @@ import java.time.Clock; import java.time.ZoneOffset; import java.util.Arrays; import java.util.Iterator; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; /** * Test reading and writing correctly from file. @@ -96,14 +93,12 @@ public class JobStoreTest { @After public void tearDown() throws Exception { mTaskStoreUnderTest.clear(); + mTaskStoreUnderTest.waitForWriteToCompleteForTesting(5_000L); } private void waitForPendingIo() throws Exception { - final CountDownLatch latch = new CountDownLatch(1); - IoThread.getHandler().post(() -> { - latch.countDown(); - }); - latch.await(10, TimeUnit.SECONDS); + assertTrue("Timed out waiting for persistence I/O to complete", + mTaskStoreUnderTest.waitForWriteToCompleteForTesting(5_000L)); } @Test diff --git a/services/tests/servicestests/src/com/android/server/webkit/TestSystemImpl.java b/services/tests/servicestests/src/com/android/server/webkit/TestSystemImpl.java index 26853a9a7fa5..3f687c81ad29 100644 --- a/services/tests/servicestests/src/com/android/server/webkit/TestSystemImpl.java +++ b/services/tests/servicestests/src/com/android/server/webkit/TestSystemImpl.java @@ -88,19 +88,13 @@ public class TestSystemImpl implements SystemInterface { } @Override - public void uninstallAndDisablePackageForAllUsers(Context context, String packageName) { - enablePackageForAllUsers(context, packageName, false); - } - - @Override public void enablePackageForAllUsers(Context context, String packageName, boolean enable) { for(int userId : mUsers) { enablePackageForUser(packageName, enable, userId); } } - @Override - public void enablePackageForUser(String packageName, boolean enable, int userId) { + private void enablePackageForUser(String packageName, boolean enable, int userId) { Map<Integer, PackageInfo> userPackages = mPackages.get(packageName); if (userPackages == null) { throw new IllegalArgumentException("There is no package called " + packageName); diff --git a/services/tests/servicestests/src/com/android/server/webkit/WebViewUpdateServiceTest.java b/services/tests/servicestests/src/com/android/server/webkit/WebViewUpdateServiceTest.java index bf89cd064812..2e60866b9a5b 100644 --- a/services/tests/servicestests/src/com/android/server/webkit/WebViewUpdateServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/webkit/WebViewUpdateServiceTest.java @@ -41,7 +41,6 @@ import org.mockito.ArgumentMatcher; import org.mockito.Matchers; import org.mockito.Mockito; -import java.lang.Integer; import java.util.concurrent.CountDownLatch; /** @@ -68,27 +67,32 @@ public class WebViewUpdateServiceTest { } private void setupWithPackages(WebViewProviderInfo[] packages) { - setupWithPackages(packages, true); + setupWithAllParameters(packages, false /* fallbackLogicEnabled */, 1 /* numRelros */, + true /* isDebuggable */, false /* multiProcessDefault */); } - private void setupWithPackages(WebViewProviderInfo[] packages, - boolean fallbackLogicEnabled) { - setupWithPackages(packages, fallbackLogicEnabled, 1); + private void setupWithPackagesAndFallbackLogic(WebViewProviderInfo[] packages) { + setupWithAllParameters(packages, true /* fallbackLogicEnabled */, 1 /* numRelros */, + true /* isDebuggable */, false /* multiProcessDefault */); } - private void setupWithPackages(WebViewProviderInfo[] packages, - boolean fallbackLogicEnabled, int numRelros) { - setupWithPackages(packages, fallbackLogicEnabled, numRelros, - true /* isDebuggable == true -> don't check package signatures */); + private void setupWithPackagesAndRelroCount(WebViewProviderInfo[] packages, int numRelros) { + setupWithAllParameters(packages, false /* fallbackLogicEnabled */, numRelros, + true /* isDebuggable */, false /* multiProcessDefault */); } - private void setupWithPackages(WebViewProviderInfo[] packages, - boolean fallbackLogicEnabled, int numRelros, boolean isDebuggable) { - setupWithPackages(packages, fallbackLogicEnabled, numRelros, isDebuggable, - false /* multiProcessDefault */); + private void setupWithPackagesNonDebuggable(WebViewProviderInfo[] packages) { + setupWithAllParameters(packages, false /* fallbackLogicEnabled */, 1 /* numRelros */, + false /* isDebuggable */, false /* multiProcessDefault */); } - private void setupWithPackages(WebViewProviderInfo[] packages, + private void setupWithPackagesAndMultiProcess(WebViewProviderInfo[] packages, + boolean multiProcessDefault) { + setupWithAllParameters(packages, false /* fallbackLogicEnabled */, 1 /* numRelros */, + true /* isDebuggable */, multiProcessDefault); + } + + private void setupWithAllParameters(WebViewProviderInfo[] packages, boolean fallbackLogicEnabled, int numRelros, boolean isDebuggable, boolean multiProcessDefault) { TestSystemImpl testing = new TestSystemImpl(packages, fallbackLogicEnabled, numRelros, @@ -119,7 +123,7 @@ public class WebViewUpdateServiceTest { private void checkCertainPackageUsedAfterWebViewBootPreparation(String expectedProviderName, WebViewProviderInfo[] webviewPackages, int numRelros) { - setupWithPackages(webviewPackages, true, numRelros); + setupWithPackagesAndRelroCount(webviewPackages, numRelros); // Add (enabled and valid) package infos for each provider setEnabledAndValidPackageInfos(webviewPackages); @@ -289,8 +293,7 @@ public class WebViewUpdateServiceTest { Base64.encodeToString( validSignature.toByteArray(), Base64.DEFAULT)}) }; - setupWithPackages(packages, true /* fallback logic enabled */, 1 /* numRelros */, - false /* isDebuggable */); + setupWithPackagesNonDebuggable(packages); mTestSystemImpl.setPackageInfo(createPackageInfo(invalidPackage, true /* enabled */, true /* valid */, true /* installed */, new Signature[]{invalidPackageSignature} , 0 /* updateTime */)); @@ -510,82 +513,75 @@ public class WebViewUpdateServiceTest { } } + /** + * Scenario for testing migrating away from the fallback logic. + * We start with a primary package that's a disabled fallback, and an enabled secondary, + * so that the fallback being re-enabled will cause a provider switch, as that covers + * the most complex case. + */ @Test - public void testRunFallbackLogicIfEnabled() { - checkFallbackLogicBeingRun(true); - } - - @Test - public void testDontRunFallbackLogicIfDisabled() { - checkFallbackLogicBeingRun(false); - } - - private void checkFallbackLogicBeingRun(boolean fallbackLogicEnabled) { + public void testFallbackLogicMigration() { String primaryPackage = "primary"; - String fallbackPackage = "fallback"; + String secondaryPackage = "secondary"; WebViewProviderInfo[] packages = new WebViewProviderInfo[] { new WebViewProviderInfo( - primaryPackage, "", true /* default available */, false /* fallback */, null), + primaryPackage, "", true /* default available */, true /* fallback */, null), new WebViewProviderInfo( - fallbackPackage, "", true /* default available */, true /* fallback */, null)}; - setupWithPackages(packages, fallbackLogicEnabled); - setEnabledAndValidPackageInfos(packages); + secondaryPackage, "", true /* default available */, false /* fallback */, + null)}; + setupWithPackagesAndFallbackLogic(packages); + mTestSystemImpl.setPackageInfo( + createPackageInfo(primaryPackage, false /* enabled */ , true /* valid */, + true /* installed */)); + mTestSystemImpl.setPackageInfo( + createPackageInfo(secondaryPackage, true /* enabled */ , true /* valid */, + true /* installed */)); + // Check that the boot time logic re-enables and chooses the primary, and disables the + // fallback logic. runWebViewBootPreparationOnMainSync(); - // Verify that we disable the fallback package if fallback logic enabled, and don't disable - // the fallback package if that logic is disabled - if (fallbackLogicEnabled) { - Mockito.verify(mTestSystemImpl).uninstallAndDisablePackageForAllUsers( - Matchers.anyObject(), Mockito.eq(fallbackPackage)); - } else { - Mockito.verify(mTestSystemImpl, Mockito.never()).uninstallAndDisablePackageForAllUsers( - Matchers.anyObject(), Matchers.anyObject()); - } - Mockito.verify(mTestSystemImpl).onWebViewProviderChanged( - Mockito.argThat(new IsPackageInfoWithName(primaryPackage))); + Mockito.verify(mTestSystemImpl).enablePackageForAllUsers( + Matchers.anyObject(), Mockito.eq(primaryPackage), Mockito.eq(true)); + checkPreparationPhasesForPackage(primaryPackage, 1); + assertFalse(mTestSystemImpl.isFallbackLogicEnabled()); - // Enable fallback package - mTestSystemImpl.setPackageInfo(createPackageInfo(fallbackPackage, true /* enabled */, + // Disable primary again + mTestSystemImpl.setPackageInfo(createPackageInfo(primaryPackage, false /* enabled */, true /* valid */, true /* installed */)); - mWebViewUpdateServiceImpl.packageStateChanged( - fallbackPackage, WebViewUpdateService.PACKAGE_CHANGED, TestSystemImpl.PRIMARY_USER_ID); + mWebViewUpdateServiceImpl.packageStateChanged(primaryPackage, + WebViewUpdateService.PACKAGE_CHANGED, TestSystemImpl.PRIMARY_USER_ID); + checkPreparationPhasesForPackage(secondaryPackage, 1); - if (fallbackLogicEnabled) { - // Check that we have now disabled the fallback package twice - Mockito.verify(mTestSystemImpl, Mockito.times(2)).uninstallAndDisablePackageForAllUsers( - Matchers.anyObject(), Mockito.eq(fallbackPackage)); - } else { - // Check that we still haven't disabled any package - Mockito.verify(mTestSystemImpl, Mockito.never()).uninstallAndDisablePackageForAllUsers( - Matchers.anyObject(), Matchers.anyObject()); - } + // Run boot logic again and check that we didn't re-enable the primary a second time. + runWebViewBootPreparationOnMainSync(); + Mockito.verify(mTestSystemImpl, Mockito.times(1)).enablePackageForAllUsers( + Matchers.anyObject(), Mockito.eq(primaryPackage), Mockito.eq(true)); + checkPreparationPhasesForPackage(secondaryPackage, 2); } /** - * Scenario for installing primary package when fallback enabled. - * 1. Start with only fallback installed - * 2. Install non-fallback - * 3. Fallback should be disabled + * Scenario for installing primary package when secondary in use. + * 1. Start with only secondary installed + * 2. Install primary + * 3. Primary should be used */ @Test - public void testInstallingNonFallbackPackage() { + public void testInstallingPrimaryPackage() { String primaryPackage = "primary"; - String fallbackPackage = "fallback"; + String secondaryPackage = "secondary"; WebViewProviderInfo[] packages = new WebViewProviderInfo[] { new WebViewProviderInfo( primaryPackage, "", true /* default available */, false /* fallback */, null), new WebViewProviderInfo( - fallbackPackage, "", true /* default available */, true /* fallback */, null)}; - setupWithPackages(packages, true /* isFallbackLogicEnabled */); + secondaryPackage, "", true /* default available */, false /* fallback */, + null)}; + setupWithPackages(packages); mTestSystemImpl.setPackageInfo( - createPackageInfo(fallbackPackage, true /* enabled */ , true /* valid */, + createPackageInfo(secondaryPackage, true /* enabled */ , true /* valid */, true /* installed */)); runWebViewBootPreparationOnMainSync(); - Mockito.verify(mTestSystemImpl, Mockito.never()).uninstallAndDisablePackageForAllUsers( - Matchers.anyObject(), Matchers.anyObject()); - - checkPreparationPhasesForPackage(fallbackPackage, + checkPreparationPhasesForPackage(secondaryPackage, 1 /* first preparation for this package*/); // Install primary package @@ -595,24 +591,22 @@ public class WebViewUpdateServiceTest { mWebViewUpdateServiceImpl.packageStateChanged(primaryPackage, WebViewUpdateService.PACKAGE_ADDED_REPLACED, TestSystemImpl.PRIMARY_USER_ID); - // Verify fallback disabled, primary package used as provider, and fallback package killed - Mockito.verify(mTestSystemImpl).uninstallAndDisablePackageForAllUsers( - Matchers.anyObject(), Mockito.eq(fallbackPackage)); + // Verify primary package used as provider, and secondary package killed checkPreparationPhasesForPackage(primaryPackage, 1 /* first preparation for this package*/); - Mockito.verify(mTestSystemImpl).killPackageDependents(Mockito.eq(fallbackPackage)); + Mockito.verify(mTestSystemImpl).killPackageDependents(Mockito.eq(secondaryPackage)); } @Test - public void testFallbackChangesEnabledStateSingleUser() { + public void testRemovingPrimarySelectsSecondarySingleUser() { for (PackageRemovalType removalType : REMOVAL_TYPES) { - checkFallbackChangesEnabledState(false /* multiUser */, removalType); + checkRemovingPrimarySelectsSecondary(false /* multiUser */, removalType); } } @Test - public void testFallbackChangesEnabledStateMultiUser() { + public void testRemovingPrimarySelectsSecondaryMultiUser() { for (PackageRemovalType removalType : REMOVAL_TYPES) { - checkFallbackChangesEnabledState(true /* multiUser */, removalType); + checkRemovingPrimarySelectsSecondary(true /* multiUser */, removalType); } } @@ -626,16 +620,17 @@ public class WebViewUpdateServiceTest { private PackageRemovalType[] REMOVAL_TYPES = PackageRemovalType.class.getEnumConstants(); - public void checkFallbackChangesEnabledState(boolean multiUser, + public void checkRemovingPrimarySelectsSecondary(boolean multiUser, PackageRemovalType removalType) { String primaryPackage = "primary"; - String fallbackPackage = "fallback"; + String secondaryPackage = "secondary"; WebViewProviderInfo[] packages = new WebViewProviderInfo[] { new WebViewProviderInfo( primaryPackage, "", true /* default available */, false /* fallback */, null), new WebViewProviderInfo( - fallbackPackage, "", true /* default available */, true /* fallback */, null)}; - setupWithPackages(packages, true /* fallbackLogicEnabled */); + secondaryPackage, "", true /* default available */, false /* fallback */, + null)}; + setupWithPackages(packages); int secondaryUserId = 10; int userIdToChangePackageFor = multiUser ? secondaryUserId : TestSystemImpl.PRIMARY_USER_ID; if (multiUser) { @@ -645,18 +640,12 @@ public class WebViewUpdateServiceTest { setEnabledAndValidPackageInfosForUser(TestSystemImpl.PRIMARY_USER_ID, packages); runWebViewBootPreparationOnMainSync(); - - // Verify fallback disabled at boot when primary package enabled - checkEnablePackageForUserCalled(fallbackPackage, false, multiUser - ? new int[] {TestSystemImpl.PRIMARY_USER_ID, secondaryUserId} - : new int[] {TestSystemImpl.PRIMARY_USER_ID}, 1 /* numUsages */); - checkPreparationPhasesForPackage(primaryPackage, 1); boolean enabled = !(removalType == PackageRemovalType.DISABLE); boolean installed = !(removalType == PackageRemovalType.UNINSTALL); boolean hidden = (removalType == PackageRemovalType.HIDE); - // Disable primary package and ensure fallback becomes enabled and used + // Disable primary package and ensure secondary becomes used mTestSystemImpl.setPackageInfoForUser(userIdToChangePackageFor, createPackageInfo(primaryPackage, enabled /* enabled */, true /* valid */, installed /* installed */, null /* signature */, 0 /* updateTime */, @@ -665,15 +654,9 @@ public class WebViewUpdateServiceTest { removalType == PackageRemovalType.DISABLE ? WebViewUpdateService.PACKAGE_CHANGED : WebViewUpdateService.PACKAGE_REMOVED, userIdToChangePackageFor); // USER ID + checkPreparationPhasesForPackage(secondaryPackage, 1); - checkEnablePackageForUserCalled(fallbackPackage, true, multiUser - ? new int[] {TestSystemImpl.PRIMARY_USER_ID, secondaryUserId} - : new int[] {TestSystemImpl.PRIMARY_USER_ID}, 1 /* numUsages */); - - checkPreparationPhasesForPackage(fallbackPackage, 1); - - - // Again enable primary package and verify primary is used and fallback becomes disabled + // Again enable primary package and verify primary is used mTestSystemImpl.setPackageInfoForUser(userIdToChangePackageFor, createPackageInfo(primaryPackage, true /* enabled */, true /* valid */, true /* installed */)); @@ -681,60 +664,9 @@ public class WebViewUpdateServiceTest { removalType == PackageRemovalType.DISABLE ? WebViewUpdateService.PACKAGE_CHANGED : WebViewUpdateService.PACKAGE_ADDED, userIdToChangePackageFor); - - // Verify fallback is disabled a second time when primary package becomes enabled - checkEnablePackageForUserCalled(fallbackPackage, false, multiUser - ? new int[] {TestSystemImpl.PRIMARY_USER_ID, secondaryUserId} - : new int[] {TestSystemImpl.PRIMARY_USER_ID}, 2 /* numUsages */); - checkPreparationPhasesForPackage(primaryPackage, 2); } - private void checkEnablePackageForUserCalled(String packageName, boolean expectEnabled, - int[] userIds, int numUsages) { - for (int userId : userIds) { - Mockito.verify(mTestSystemImpl, Mockito.times(numUsages)).enablePackageForUser( - Mockito.eq(packageName), Mockito.eq(expectEnabled), Mockito.eq(userId)); - } - } - - @Test - public void testAddUserWhenFallbackLogicEnabled() { - checkAddingNewUser(true); - } - - @Test - public void testAddUserWhenFallbackLogicDisabled() { - checkAddingNewUser(false); - } - - public void checkAddingNewUser(boolean fallbackLogicEnabled) { - String primaryPackage = "primary"; - String fallbackPackage = "fallback"; - WebViewProviderInfo[] packages = new WebViewProviderInfo[] { - new WebViewProviderInfo( - primaryPackage, "", true /* default available */, false /* fallback */, null), - new WebViewProviderInfo( - fallbackPackage, "", true /* default available */, true /* fallback */, null)}; - setupWithPackages(packages, fallbackLogicEnabled); - setEnabledAndValidPackageInfosForUser(TestSystemImpl.PRIMARY_USER_ID, packages); - int newUser = 100; - mTestSystemImpl.addUser(newUser); - setEnabledAndValidPackageInfosForUser(newUser, packages); - mWebViewUpdateServiceImpl.handleNewUser(newUser); - if (fallbackLogicEnabled) { - // Verify fallback package becomes disabled for new user - Mockito.verify(mTestSystemImpl).enablePackageForUser( - Mockito.eq(fallbackPackage), Mockito.eq(false) /* enable */, - Mockito.eq(newUser)); - } else { - // Verify that we don't disable fallback for new user - Mockito.verify(mTestSystemImpl, Mockito.never()).enablePackageForUser( - Mockito.anyObject(), Matchers.anyBoolean() /* enable */, - Matchers.anyInt() /* user */); - } - } - /** * Ensures that adding a new user for which the current WebView package is uninstalled causes a * change of WebView provider. @@ -742,13 +674,14 @@ public class WebViewUpdateServiceTest { @Test public void testAddingNewUserWithUninstalledPackage() { String primaryPackage = "primary"; - String fallbackPackage = "fallback"; + String secondaryPackage = "secondary"; WebViewProviderInfo[] packages = new WebViewProviderInfo[] { new WebViewProviderInfo( primaryPackage, "", true /* default available */, false /* fallback */, null), new WebViewProviderInfo( - fallbackPackage, "", true /* default available */, true /* fallback */, null)}; - setupWithPackages(packages, true /* fallbackLogicEnabled */); + secondaryPackage, "", true /* default available */, false /* fallback */, + null)}; + setupWithPackages(packages); setEnabledAndValidPackageInfosForUser(TestSystemImpl.PRIMARY_USER_ID, packages); int newUser = 100; mTestSystemImpl.addUser(newUser); @@ -757,18 +690,10 @@ public class WebViewUpdateServiceTest { createPackageInfo(primaryPackage, true /* enabled */, true /* valid */, false /* installed */)); mTestSystemImpl.setPackageInfoForUser(newUser, - createPackageInfo(fallbackPackage, false /* enabled */, true /* valid */, + createPackageInfo(secondaryPackage, true /* enabled */, true /* valid */, true /* installed */)); mWebViewUpdateServiceImpl.handleNewUser(newUser); - // Verify fallback package doesn't become disabled for the primary user. - Mockito.verify(mTestSystemImpl, Mockito.never()).enablePackageForUser( - Mockito.anyObject(), Mockito.eq(false) /* enable */, - Mockito.eq(TestSystemImpl.PRIMARY_USER_ID) /* user */); - // Verify that we enable the fallback package for the secondary user. - Mockito.verify(mTestSystemImpl, Mockito.times(1)).enablePackageForUser( - Mockito.eq(fallbackPackage), Mockito.eq(true) /* enable */, - Mockito.eq(newUser) /* user */); - checkPreparationPhasesForPackage(fallbackPackage, 1 /* numRelros */); + checkPreparationPhasesForPackage(secondaryPackage, 1 /* numRelros */); } /** @@ -874,7 +799,8 @@ public class WebViewUpdateServiceTest { setupWithPackages(packages); // Only 'install' nonChosenPackage mTestSystemImpl.setPackageInfo( - createPackageInfo(nonChosenPackage, true /* enabled */, true /* valid */, true /* installed */)); + createPackageInfo(nonChosenPackage, true /* enabled */, true /* valid */, + true /* installed */)); // Set user-chosen package mTestSystemImpl.updateUserSetting(null, chosenPackage); @@ -1024,7 +950,8 @@ public class WebViewUpdateServiceTest { checkPreparationPhasesForPackage(thirdPackage, 1); mTestSystemImpl.setPackageInfo( - createPackageInfo(secondPackage, true /* enabled */, false /* valid */, true /* installed */)); + createPackageInfo(secondPackage, true /* enabled */, false /* valid */, + true /* installed */)); // Try to switch to the invalid second package, this should result in switching to the first // package, since that is more preferred than the third one. @@ -1084,40 +1011,17 @@ public class WebViewUpdateServiceTest { 100000 /* candidate version */, false /* expected validity */); } - @Test - public void testMinimumSystemVersionUsedFallbackIgnored() { - checkPackageVersions(new int[]{300000, 400000, 500000, 600000, 700000} /* system versions */, - 200000 /* candidate version */, false /* expected validity */, true /* add fallback */, - 100000 /* fallback version */, false /* expected validity of fallback */); - } - - @Test - public void testFallbackValid() { - checkPackageVersions(new int[]{300000, 400000, 500000, 600000, 700000} /* system versions */, - 200000/* candidate version */, false /* expected validity */, true /* add fallback */, - 300000 /* fallback version */, true /* expected validity of fallback */); - } - - private void checkPackageVersions(int[] systemVersions, int candidateVersion, - boolean candidateShouldBeValid) { - checkPackageVersions(systemVersions, candidateVersion, candidateShouldBeValid, - false, 0, false); - } - /** * Utility method for checking that package version restriction works as it should. * I.e. that a package with lower version than the system-default is not valid and that a * package with greater than or equal version code is considered valid. */ private void checkPackageVersions(int[] systemVersions, int candidateVersion, - boolean candidateShouldBeValid, boolean addFallback, int fallbackVersion, - boolean fallbackShouldBeValid) { + boolean candidateShouldBeValid) { int numSystemPackages = systemVersions.length; - int numFallbackPackages = (addFallback ? 1 : 0); - int numPackages = systemVersions.length + 1 + numFallbackPackages; + int numPackages = systemVersions.length + 1; String candidatePackage = "candidatePackage"; String systemPackage = "systemPackage"; - String fallbackPackage = "fallbackPackage"; // Each package needs a valid signature since we set isDebuggable to false Signature signature = new Signature("11"); @@ -1126,8 +1030,7 @@ public class WebViewUpdateServiceTest { // Set up config // 1. candidatePackage - // 2-N. default available non-fallback packages - // N+1. default available fallback package + // 2-N. default available packages WebViewProviderInfo[] packages = new WebViewProviderInfo[numPackages]; packages[0] = new WebViewProviderInfo(candidatePackage, "", false /* available by default */, false /* fallback */, @@ -1137,14 +1040,7 @@ public class WebViewUpdateServiceTest { true /* available by default */, false /* fallback */, new String[]{encodedSignatureString}); } - if (addFallback) { - packages[packages.length-1] = new WebViewProviderInfo(fallbackPackage, "", - true /* available by default */, true /* fallback */, - new String[]{encodedSignatureString}); - } - - setupWithPackages(packages, true /* fallback logic enabled */, 1 /* numRelros */, - false /* isDebuggable */); + setupWithPackagesNonDebuggable(packages); // Set package infos mTestSystemImpl.setPackageInfo( @@ -1157,12 +1053,6 @@ public class WebViewUpdateServiceTest { true /* installed */, new Signature[]{signature}, 0 /* updateTime */, false /* hidden */, systemVersions[n-1], true /* isSystemApp */)); } - if (addFallback) { - mTestSystemImpl.setPackageInfo( - createPackageInfo(fallbackPackage, true /* enabled */, true /* valid */, - true /* installed */, new Signature[]{signature}, 0 /* updateTime */, - false /* hidden */, fallbackVersion, true /* isSystemApp */)); - } WebViewProviderInfo[] validPackages = mWebViewUpdateServiceImpl.getValidWebViewPackages(); int expectedNumValidPackages = numSystemPackages; @@ -1175,15 +1065,6 @@ public class WebViewUpdateServiceTest { } } - if (fallbackShouldBeValid) { - expectedNumValidPackages += numFallbackPackages; - } else { - // Ensure the fallback package is not one of the valid packages - for(int n = 0; n < validPackages.length; n++) { - assertFalse(fallbackPackage.equals(validPackages[n].packageName)); - } - } - assertEquals(expectedNumValidPackages, validPackages.length); runWebViewBootPreparationOnMainSync(); @@ -1212,7 +1093,7 @@ public class WebViewUpdateServiceTest { WebViewProviderInfo[] webviewPackages = new WebViewProviderInfo[] { new WebViewProviderInfo(testPackageName, "", true /*default available*/, false /* fallback */, null)}; - setupWithPackages(webviewPackages, true /* fallback logic enabled */, 1 /* numRelros */); + setupWithPackages(webviewPackages); mTestSystemImpl.setPackageInfo(createPackageInfo(testPackageName, true /* enabled */, true /* valid */, false /* installed */)); @@ -1250,7 +1131,7 @@ public class WebViewUpdateServiceTest { new WebViewProviderInfo(installedPackage, "", true /* available by default */, false /* fallback */, null)}; - setupWithPackages(webviewPackages, true /* fallback logic enabled */, 1 /* numRelros */); + setupWithPackages(webviewPackages); int secondaryUserId = 5; if (multiUser) { mTestSystemImpl.addUser(secondaryUserId); @@ -1301,7 +1182,7 @@ public class WebViewUpdateServiceTest { new WebViewProviderInfo(installedPackage, "", true /* available by default */, false /* fallback */, null)}; - setupWithPackages(webviewPackages, true /* fallback logic enabled */, 1 /* numRelros */); + setupWithPackages(webviewPackages); int secondaryUserId = 412; mTestSystemImpl.addUser(secondaryUserId); @@ -1356,7 +1237,7 @@ public class WebViewUpdateServiceTest { new WebViewProviderInfo(installedPackage, "", true /* available by default */, false /* fallback */, null)}; - setupWithPackages(webviewPackages, true /* fallback logic enabled */, 1 /* numRelros */); + setupWithPackages(webviewPackages); int secondaryUserId = 4; mTestSystemImpl.addUser(secondaryUserId); @@ -1377,78 +1258,25 @@ public class WebViewUpdateServiceTest { } @Test - public void testFallbackEnabledIfPrimaryUninstalledSingleUser() { - checkFallbackEnabledIfPrimaryUninstalled(false /* multiUser */); - } - - @Test - public void testFallbackEnabledIfPrimaryUninstalledMultiUser() { - checkFallbackEnabledIfPrimaryUninstalled(true /* multiUser */); - } - - /** - * Ensures that fallback becomes enabled at boot if the primary package is uninstalled for some - * user. - */ - private void checkFallbackEnabledIfPrimaryUninstalled(boolean multiUser) { - String primaryPackage = "primary"; - String fallbackPackage = "fallback"; - WebViewProviderInfo[] packages = new WebViewProviderInfo[] { - new WebViewProviderInfo( - primaryPackage, "", true /* default available */, false /* fallback */, null), - new WebViewProviderInfo( - fallbackPackage, "", true /* default available */, true /* fallback */, null)}; - setupWithPackages(packages, true /* fallback logic enabled */); - int secondaryUserId = 5; - if (multiUser) { - mTestSystemImpl.addUser(secondaryUserId); - // Install all packages for the primary user. - setEnabledAndValidPackageInfosForUser(TestSystemImpl.PRIMARY_USER_ID, packages); - // Only install fallback package for secondary user. - mTestSystemImpl.setPackageInfoForUser(secondaryUserId, - createPackageInfo(primaryPackage, true /* enabled */, - true /* valid */, false /* installed */)); - mTestSystemImpl.setPackageInfoForUser(secondaryUserId, - createPackageInfo(fallbackPackage, false /* enabled */, - true /* valid */, true /* installed */)); - } else { - mTestSystemImpl.setPackageInfo(createPackageInfo(primaryPackage, true /* enabled */, - true /* valid */, false /* installed */)); - mTestSystemImpl.setPackageInfo(createPackageInfo(fallbackPackage, false /* enabled */, - true /* valid */, true /* installed */)); - } - - runWebViewBootPreparationOnMainSync(); - // Verify that we enable the fallback package - Mockito.verify(mTestSystemImpl).enablePackageForAllUsers( - Mockito.anyObject(), Mockito.eq(fallbackPackage), Mockito.eq(true) /* enable */); - - checkPreparationPhasesForPackage(fallbackPackage, 1 /* first preparation phase */); - } - - @Test public void testPreparationRunsIffNewPackage() { String primaryPackage = "primary"; - String fallbackPackage = "fallback"; + String secondaryPackage = "secondary"; WebViewProviderInfo[] packages = new WebViewProviderInfo[] { new WebViewProviderInfo( primaryPackage, "", true /* default available */, false /* fallback */, null), new WebViewProviderInfo( - fallbackPackage, "", true /* default available */, true /* fallback */, null)}; - setupWithPackages(packages, true /* fallback logic enabled */); + secondaryPackage, "", true /* default available */, false /* fallback */, + null)}; + setupWithPackages(packages); mTestSystemImpl.setPackageInfo(createPackageInfo(primaryPackage, true /* enabled */, true /* valid */, true /* installed */, null /* signatures */, 10 /* lastUpdateTime*/ )); - mTestSystemImpl.setPackageInfo(createPackageInfo(fallbackPackage, true /* enabled */, + mTestSystemImpl.setPackageInfo(createPackageInfo(secondaryPackage, true /* enabled */, true /* valid */, true /* installed */)); runWebViewBootPreparationOnMainSync(); checkPreparationPhasesForPackage(primaryPackage, 1 /* first preparation phase */); - Mockito.verify(mTestSystemImpl, Mockito.times(1)).enablePackageForUser( - Mockito.eq(fallbackPackage), Mockito.eq(false) /* enable */, - Matchers.anyInt() /* user */); - mWebViewUpdateServiceImpl.packageStateChanged(primaryPackage, WebViewUpdateService.PACKAGE_ADDED_REPLACED, 0 /* userId */); @@ -1459,9 +1287,6 @@ public class WebViewUpdateServiceTest { // package still has the same update-time so we shouldn't run preparation here Mockito.verify(mTestSystemImpl, Mockito.times(1)).onWebViewProviderChanged( Mockito.argThat(new IsPackageInfoWithName(primaryPackage))); - Mockito.verify(mTestSystemImpl, Mockito.times(1)).enablePackageForUser( - Mockito.eq(fallbackPackage), Mockito.eq(false) /* enable */, - Matchers.anyInt() /* user */); // Ensure we can still load the package WebViewProviderResponse response = mWebViewUpdateServiceImpl.waitForAndGetProvider(); @@ -1496,7 +1321,7 @@ public class WebViewUpdateServiceTest { firstPackage.versionName = "first package version"; WebViewProviderInfo[] packages = new WebViewProviderInfo[] { new WebViewProviderInfo(firstPackage.packageName, "", true, false, null)}; - setupWithPackages(packages, true); + setupWithPackages(packages); mTestSystemImpl.setPackageInfo(firstPackage); runWebViewBootPreparationOnMainSync(); @@ -1542,9 +1367,7 @@ public class WebViewUpdateServiceTest { WebViewProviderInfo[] packages = new WebViewProviderInfo[] { new WebViewProviderInfo( primaryPackage, "", true /* default available */, false /* fallback */, null)}; - setupWithPackages(packages, true /* fallback logic enabled */, 1 /* numRelros */, - true /* debuggable */, - enabledByDefault /* not multiprocess by default */); + setupWithPackagesAndMultiProcess(packages, enabledByDefault); mTestSystemImpl.setPackageInfo(createPackageInfo(primaryPackage, true /* enabled */, true /* valid */, true /* installed */, null /* signatures */, 10 /* lastUpdateTime*/, false /* not hidden */, 1000 /* versionCode */, @@ -1599,8 +1422,7 @@ public class WebViewUpdateServiceTest { WebViewProviderInfo[] packages = new WebViewProviderInfo[] { new WebViewProviderInfo( primaryPackage, "", true /* default available */, false /* fallback */, null)}; - setupWithPackages(packages, true /* fallback logic enabled */, 1 /* numRelros */, - true /* debuggable */, enabledByDefault /* multiprocess by default */); + setupWithPackagesAndMultiProcess(packages, enabledByDefault); mTestSystemImpl.setPackageInfo(createPackageInfo(primaryPackage, true /* enabled */, true /* valid */, true /* installed */, null /* signatures */, 10 /* lastUpdateTime*/, false /* not hidden */, 1000 /* versionCode */, @@ -1638,7 +1460,7 @@ public class WebViewUpdateServiceTest { WebViewProviderInfo[] packages = new WebViewProviderInfo[] { new WebViewProviderInfo(oldSdkPackage.packageName, "", true, false, null), currentSdkProviderInfo, newSdkProviderInfo}; - setupWithPackages(packages, true); + setupWithPackages(packages); ; mTestSystemImpl.setPackageInfo(newSdkPackage); mTestSystemImpl.setPackageInfo(currentSdkPackage); diff --git a/services/tests/uiservicestests/AndroidManifest.xml b/services/tests/uiservicestests/AndroidManifest.xml index aa3135ff18da..3ff85c8806ce 100644 --- a/services/tests/uiservicestests/AndroidManifest.xml +++ b/services/tests/uiservicestests/AndroidManifest.xml @@ -29,6 +29,7 @@ <uses-permission android:name="android.permission.DEVICE_POWER" /> <uses-permission android:name="android.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> + <uses-permission android:name="android.permission.OBSERVE_ROLE_HOLDERS" /> <application android:debuggable="true"> <uses-library android:name="android.test.runner" /> diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java index a9eb6ec5db1e..6f1bd87f14f7 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java @@ -18,6 +18,7 @@ package com.android.server.notification; import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_GONE; +import static android.app.Notification.FLAG_BUBBLE; import static android.app.Notification.FLAG_FOREGROUND_SERVICE; import static android.app.NotificationManager.EXTRA_BLOCKED_STATE; import static android.app.NotificationManager.IMPORTANCE_DEFAULT; @@ -79,6 +80,7 @@ import android.app.Notification.MessagingStyle.Message; import android.app.NotificationChannel; import android.app.NotificationChannelGroup; import android.app.NotificationManager; +import android.app.PendingIntent; import android.app.admin.DevicePolicyManagerInternal; import android.app.usage.UsageStatsManagerInternal; import android.companion.ICompanionDeviceManager; @@ -92,6 +94,7 @@ import android.content.pm.PackageManager; import android.content.pm.ParceledListSlice; import android.content.res.Resources; import android.graphics.Color; +import android.graphics.drawable.Icon; import android.media.AudioManager; import android.net.Uri; import android.os.Binder; @@ -101,6 +104,7 @@ import android.os.IBinder; import android.os.Process; import android.os.RemoteException; import android.os.UserHandle; +import android.os.UserManager; import android.provider.DeviceConfig; import android.provider.MediaStore; import android.provider.Settings; @@ -133,7 +137,6 @@ import com.android.server.lights.Light; import com.android.server.lights.LightsManager; import com.android.server.notification.NotificationManagerService.NotificationAssistants; import com.android.server.notification.NotificationManagerService.NotificationListeners; -import com.android.server.pm.UserManagerService; import com.android.server.uri.UriGrantsManagerInternal; import com.android.server.wm.WindowManagerInternal; @@ -149,7 +152,6 @@ import org.mockito.stubbing.Answer; import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; import java.io.File; -import java.io.FileInputStream; import java.io.FileOutputStream; import java.util.ArrayList; import java.util.Arrays; @@ -226,23 +228,21 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Mock AppOpsManager mAppOpsManager; @Mock - private UserManagerService mUserMangerService; - @Mock private TestableNotificationManagerService.NotificationAssistantAccessGrantedCallback mNotificationAssistantAccessGrantedCallback; + @Mock + UserManager mUm; // Use a Testable subclass so we can simulate calls from the system without failing. private static class TestableNotificationManagerService extends NotificationManagerService { int countSystemChecks = 0; boolean isSystemUid = true; int countLogSmartSuggestionsVisible = 0; - UserManagerService mUserManagerService; @Nullable NotificationAssistantAccessGrantedCallback mNotificationAssistantAccessGrantedCallback; - TestableNotificationManagerService(Context context, UserManagerService userManagerService) { + TestableNotificationManagerService(Context context) { super(context); - mUserManagerService = userManagerService; } @Override @@ -279,11 +279,6 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { } @Override - UserManagerService getUserManagerService() { - return mUserManagerService; - } - - @Override protected void setNotificationAssistantAccessGrantedForUserInternal( ComponentName assistant, int userId, boolean granted) { if (mNotificationAssistantAccessGrantedCallback != null) { @@ -326,7 +321,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { LocalServices.removeServiceForTest(WindowManagerInternal.class); LocalServices.addService(WindowManagerInternal.class, mWindowManagerInternal); - mService = new TestableNotificationManagerService(mContext, mUserMangerService); + mService = new TestableNotificationManagerService(mContext); // Use this testable looper. mTestableLooper = TestableLooper.get(this); @@ -379,7 +374,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { mCompanionMgr, mSnoozeHelper, mUsageStats, mPolicyFile, mActivityManager, mGroupHelper, mAm, mAppUsageStats, mock(DevicePolicyManagerInternal.class), mUgm, mUgmInternal, - mAppOpsManager); + mAppOpsManager, mUm); mService.onBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY); } catch (SecurityException e) { if (!e.getMessage().contains("Permission Denial: not allowed to send broadcast")) { @@ -507,6 +502,13 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { false); } + private Notification.BubbleMetadata.Builder getBasicBubbleMetadataBuilder() { + PendingIntent pi = PendingIntent.getActivity(mContext, 0, new Intent(), 0); + return new Notification.BubbleMetadata.Builder() + .setIntent(pi) + .setIcon(Icon.createWithResource(mContext, android.R.drawable.sym_def_app_icon)); + } + @Test public void testCreateNotificationChannels_SingleChannel() throws Exception { final NotificationChannel channel = @@ -1920,8 +1922,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { } @Test - public void testHasCompanionDevice_noService() throws Exception { - mService = new TestableNotificationManagerService(mContext, mUserMangerService); + public void testHasCompanionDevice_noService() { + mService = new TestableNotificationManagerService(mContext); assertFalse(mService.hasCompanionDevice(mListener)); } @@ -2623,7 +2625,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { + "<service_listing approved=\"test\" user=\"10\" primary=\"true\" />" + "</dnd_apps>" + "</notification-policy>"; - when(mUserMangerService.isManagedProfile(10)).thenReturn(true); + when(mUm.isManagedProfile(10)).thenReturn(true); mService.readPolicyXml( new BufferedInputStream(new ByteArrayInputStream(policyXml.getBytes())), true, @@ -2647,7 +2649,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { + "<service_listing approved=\"test\" user=\"10\" primary=\"true\" />" + "</dnd_apps>" + "</notification-policy>"; - when(mUserMangerService.isManagedProfile(10)).thenReturn(false); + when(mUm.isManagedProfile(10)).thenReturn(false); mService.readPolicyXml( new BufferedInputStream(new ByteArrayInputStream(policyXml.getBytes())), true, @@ -4290,7 +4292,209 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { .onGranted(eq(xmlConfig), eq(0), eq(true)); } + @Test + public void testFlagBubbleNotifs_flagIfAllowed() throws RemoteException { + // Bubbles are allowed! + mService.setPreferencesHelper(mPreferencesHelper); + when(mPreferencesHelper.areBubblesAllowed(anyString(), anyInt())).thenReturn(true); + when(mPreferencesHelper.getNotificationChannel( + anyString(), anyInt(), anyString(), anyBoolean())).thenReturn( + mTestNotificationChannel); + when(mPreferencesHelper.getImportance(anyString(), anyInt())).thenReturn( + mTestNotificationChannel.getImportance()); + + // Notif with bubble metadata + Notification.BubbleMetadata data = getBasicBubbleMetadataBuilder().build(); + Notification.Builder nb = new Notification.Builder(mContext, + mTestNotificationChannel.getId()) + .setContentTitle("foo") + .setBubbleMetadata(data) + .setSmallIcon(android.R.drawable.sym_def_app_icon); + + StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1, null, mUid, 0, + nb.build(), new UserHandle(mUid), null, 0); + NotificationRecord nr = new NotificationRecord(mContext, sbn, mTestNotificationChannel); + + mBinderService.enqueueNotificationWithTag(PKG, PKG, null, + nr.sbn.getId(), nr.sbn.getNotification(), nr.sbn.getUserId()); + waitForIdle(); + + // yes allowed, yes bubble + assertTrue(mService.getNotificationRecord( + sbn.getKey()).getNotification().isBubbleNotification()); + } + + @Test + public void testFlagBubbleNotifs_noFlagIfNotAllowed() throws RemoteException { + // Bubbles are NOT allowed! + mService.setPreferencesHelper(mPreferencesHelper); + when(mPreferencesHelper.areBubblesAllowed(anyString(), anyInt())).thenReturn(false); + when(mPreferencesHelper.getNotificationChannel( + anyString(), anyInt(), anyString(), anyBoolean())).thenReturn( + mTestNotificationChannel); + when(mPreferencesHelper.getImportance(anyString(), anyInt())).thenReturn( + mTestNotificationChannel.getImportance()); + + // Notif with bubble metadata + Notification.BubbleMetadata data = getBasicBubbleMetadataBuilder().build(); + Notification.Builder nb = new Notification.Builder(mContext, + mTestNotificationChannel.getId()) + .setContentTitle("foo") + .setBubbleMetadata(data) + .setSmallIcon(android.R.drawable.sym_def_app_icon); + + StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1, null, mUid, 0, + nb.build(), new UserHandle(mUid), null, 0); + NotificationRecord nr = new NotificationRecord(mContext, sbn, mTestNotificationChannel); + + // Post the notification + mBinderService.enqueueNotificationWithTag(PKG, PKG, null, + nr.sbn.getId(), nr.sbn.getNotification(), nr.sbn.getUserId()); + waitForIdle(); + + // not allowed, no bubble + assertFalse(mService.getNotificationRecord( + sbn.getKey()).getNotification().isBubbleNotification()); + } + + @Test + public void testFlagBubbleNotifs_noFlagIfNotBubble() throws RemoteException { + // Bubbles are allowed! + mService.setPreferencesHelper(mPreferencesHelper); + when(mPreferencesHelper.areBubblesAllowed(anyString(), anyInt())).thenReturn(true); + when(mPreferencesHelper.getNotificationChannel( + anyString(), anyInt(), anyString(), anyBoolean())).thenReturn( + mTestNotificationChannel); + when(mPreferencesHelper.getImportance(anyString(), anyInt())).thenReturn( + mTestNotificationChannel.getImportance()); + + // Notif WITHOUT bubble metadata + Notification.Builder nb = new Notification.Builder(mContext, + mTestNotificationChannel.getId()) + .setContentTitle("foo") + .setSmallIcon(android.R.drawable.sym_def_app_icon); + + StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1, null, mUid, 0, + nb.build(), new UserHandle(mUid), null, 0); + NotificationRecord nr = new NotificationRecord(mContext, sbn, mTestNotificationChannel); + + // Post the notification + mBinderService.enqueueNotificationWithTag(PKG, PKG, null, + nr.sbn.getId(), nr.sbn.getNotification(), nr.sbn.getUserId()); + waitForIdle(); + + // no bubble metadata, no bubble + assertFalse(mService.getNotificationRecord( + sbn.getKey()).getNotification().isBubbleNotification()); + } + @Test + public void testFlagBubbleNotifs_noFlagIfChannelNotBubble() throws RemoteException { + // Bubbles are allowed! + mService.setPreferencesHelper(mPreferencesHelper); + when(mPreferencesHelper.areBubblesAllowed(anyString(), anyInt())).thenReturn(true); + when(mPreferencesHelper.getNotificationChannel( + anyString(), anyInt(), anyString(), anyBoolean())).thenReturn( + mTestNotificationChannel); + when(mPreferencesHelper.getImportance(anyString(), anyInt())).thenReturn( + mTestNotificationChannel.getImportance()); + + // But not on this channel! + mTestNotificationChannel.setAllowBubbles(false); + + // Notif with bubble metadata + Notification.BubbleMetadata data = getBasicBubbleMetadataBuilder().build(); + Notification.Builder nb = new Notification.Builder(mContext, + mTestNotificationChannel.getId()) + .setContentTitle("foo") + .setBubbleMetadata(data) + .setSmallIcon(android.R.drawable.sym_def_app_icon); + + StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1, null, mUid, 0, + nb.build(), new UserHandle(mUid), null, 0); + NotificationRecord nr = new NotificationRecord(mContext, sbn, mTestNotificationChannel); + + // Post the notification + mBinderService.enqueueNotificationWithTag(PKG, PKG, null, + nr.sbn.getId(), nr.sbn.getNotification(), nr.sbn.getUserId()); + waitForIdle(); + + // channel not allowed, no bubble + assertFalse(mService.getNotificationRecord( + sbn.getKey()).getNotification().isBubbleNotification()); + } + + @Test + public void testCancelAllNotifications_cancelsBubble() throws Exception { + final NotificationRecord nr = generateNotificationRecord(mTestNotificationChannel); + nr.sbn.getNotification().flags |= FLAG_BUBBLE; + mService.addNotification(nr); + + mBinderService.cancelAllNotifications(PKG, nr.sbn.getUserId()); + waitForIdle(); + + StatusBarNotification[] notifs = mBinderService.getActiveNotifications(PKG); + assertEquals(0, notifs.length); + assertEquals(0, mService.getNotificationRecordCount()); + } + + @Test + public void testAppCancelNotifications_cancelsBubbles() throws Exception { + final NotificationRecord nrBubble = generateNotificationRecord(mTestNotificationChannel); + nrBubble.sbn.getNotification().flags |= FLAG_BUBBLE; + + // Post the notification + mBinderService.enqueueNotificationWithTag(PKG, PKG, null, + nrBubble.sbn.getId(), nrBubble.sbn.getNotification(), nrBubble.sbn.getUserId()); + waitForIdle(); + + StatusBarNotification[] notifs = mBinderService.getActiveNotifications(PKG); + assertEquals(1, notifs.length); + assertEquals(1, mService.getNotificationRecordCount()); + + mBinderService.cancelNotificationWithTag(PKG, null, nrBubble.sbn.getId(), + nrBubble.sbn.getUserId()); + waitForIdle(); + + StatusBarNotification[] notifs2 = mBinderService.getActiveNotifications(PKG); + assertEquals(0, notifs2.length); + assertEquals(0, mService.getNotificationRecordCount()); + } + + @Test + public void testCancelAllNotificationsFromListener_ignoresBubbles() throws Exception { + final NotificationRecord nrNormal = generateNotificationRecord(mTestNotificationChannel); + final NotificationRecord nrBubble = generateNotificationRecord(mTestNotificationChannel); + nrBubble.sbn.getNotification().flags |= FLAG_BUBBLE; + + mService.addNotification(nrNormal); + mService.addNotification(nrBubble); + + mService.getBinderService().cancelNotificationsFromListener(null, null); + waitForIdle(); + + StatusBarNotification[] notifs = mBinderService.getActiveNotifications(PKG); + assertEquals(1, notifs.length); + assertEquals(1, mService.getNotificationRecordCount()); + } + + @Test + public void testCancelNotificationsFromListener_ignoresBubbles() throws Exception { + final NotificationRecord nrNormal = generateNotificationRecord(mTestNotificationChannel); + final NotificationRecord nrBubble = generateNotificationRecord(mTestNotificationChannel); + nrBubble.sbn.getNotification().flags |= FLAG_BUBBLE; + + mService.addNotification(nrNormal); + mService.addNotification(nrBubble); + + String[] keys = {nrNormal.sbn.getKey(), nrBubble.sbn.getKey()}; + mService.getBinderService().cancelNotificationsFromListener(null, keys); + waitForIdle(); + + StatusBarNotification[] notifs = mBinderService.getActiveNotifications(PKG); + assertEquals(1, notifs.length); + assertEquals(1, mService.getNotificationRecordCount()); + } public void testGetAllowedAssistantCapabilities() throws Exception { List<String> capabilities = mBinderService.getAllowedAssistantCapabilities(null); diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordTest.java index e375195af5c9..7c2235050caf 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordTest.java @@ -477,8 +477,9 @@ public class NotificationRecordTest extends UiServiceTestCase { assertEquals(MetricsEvent.IMPORTANCE_EXPLANATION_APP, logMaker.getTaggedData( MetricsEvent.FIELD_NOTIFICATION_IMPORTANCE_INITIAL_EXPLANATION)); - // This field is only populated if the assistant was itself overridden by the system. - assertNull(logMaker.getTaggedData(MetricsEvent.FIELD_NOTIFICATION_IMPORTANCE_ASST)); + // This field is populated whenever mImportanceExplanationCode is. + assertEquals(IMPORTANCE_LOW, + logMaker.getTaggedData(MetricsEvent.FIELD_NOTIFICATION_IMPORTANCE_ASST)); } @Test @@ -952,7 +953,31 @@ public class NotificationRecordTest extends UiServiceTestCase { } @Test - public void testApplyImportanceAdjustmentsForNonOemLockedChannels() { + public void testIgnoreImportanceAdjustmentsForDefaultAppLockedChannels() { + NotificationChannel channel = new NotificationChannel("a", "a", IMPORTANCE_DEFAULT); + channel.setImportanceLockedByCriticalDeviceFunction(true); + + StatusBarNotification sbn = getNotification(PKG_O, true /* noisy */, + true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */, + false /* lights */, false /* defaultLights */, groupId /* group */); + NotificationRecord record = new NotificationRecord(mMockContext, sbn, channel); + + assertEquals(IMPORTANCE_DEFAULT, record.getImportance()); + + Bundle bundle = new Bundle(); + bundle.putInt(KEY_IMPORTANCE, IMPORTANCE_LOW); + Adjustment adjustment = new Adjustment( + PKG_O, record.getKey(), bundle, "", record.getUserId()); + + record.addAdjustment(adjustment); + record.applyAdjustments(); + record.calculateImportance(); + + assertEquals(IMPORTANCE_DEFAULT, record.getImportance()); + } + + @Test + public void testApplyImportanceAdjustmentsForNonOemDefaultAppLockedChannels() { NotificationChannel channel = new NotificationChannel("a", "a", IMPORTANCE_DEFAULT); channel.setImportanceLockedByOEM(false); diff --git a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java index 39e47ecb1b22..87f10a4e077c 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java @@ -62,11 +62,9 @@ import android.provider.Settings.Secure; import android.test.suitebuilder.annotation.SmallTest; import android.testing.TestableContentResolver; import android.util.ArrayMap; +import android.util.ArraySet; import android.util.Xml; -import androidx.test.InstrumentationRegistry; -import androidx.test.runner.AndroidJUnit4; - import com.android.internal.util.FastXmlSerializer; import com.android.server.UiServiceTestCase; @@ -91,6 +89,9 @@ import java.util.Map; import java.util.Objects; import java.util.concurrent.ThreadLocalRandom; +import androidx.test.InstrumentationRegistry; +import androidx.test.runner.AndroidJUnit4; + @SmallTest @RunWith(AndroidJUnit4.class) public class PreferencesHelperTest extends UiServiceTestCase { @@ -2442,4 +2443,153 @@ public class PreferencesHelperTest extends UiServiceTestCase { assertEquals(IMPORTANCE_HIGH, mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false).getImportance()); } + + @Test + public void testUpdateDefaultApps_add_multiUser() { + NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH); + NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW); + NotificationChannel c = new NotificationChannel("c", "c", IMPORTANCE_DEFAULT); + // different uids, same package + mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false); + mHelper.createNotificationChannel(PKG_O, UID_O, b, false, false); + mHelper.createNotificationChannel(PKG_O, UserHandle.PER_USER_RANGE + 1, c, true, true); + + ArraySet<String> toAdd = new ArraySet<>(); + toAdd.add(PKG_O); + mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, toAdd); + + assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false) + .isImportanceLockedByCriticalDeviceFunction()); + assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, b.getId(), false) + .isImportanceLockedByCriticalDeviceFunction()); + assertFalse(mHelper.getNotificationChannel( + PKG_O, UserHandle.PER_USER_RANGE + 1, c.getId(), false) + .isImportanceLockedByCriticalDeviceFunction()); + } + + @Test + public void testUpdateDefaultApps_add_onlyGivenPkg() { + NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH); + NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW); + mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false); + mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, b, false, false); + + ArraySet<String> toAdd = new ArraySet<>(); + toAdd.add(PKG_O); + mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, toAdd); + + + assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false) + .isImportanceLockedByCriticalDeviceFunction()); + assertFalse(mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, b.getId(), false) + .isImportanceLockedByCriticalDeviceFunction()); + } + + @Test + public void testUpdateDefaultApps_remove() { + NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH); + NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW); + // different uids, same package + mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false); + mHelper.createNotificationChannel(PKG_O, UID_O, b, false, false); + + ArraySet<String> toAdd = new ArraySet<>(); + toAdd.add(PKG_O); + mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, toAdd); + + assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false) + .isImportanceLockedByCriticalDeviceFunction()); + assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, b.getId(), false) + .isImportanceLockedByCriticalDeviceFunction()); + + ArraySet<String> toRemove = new ArraySet<>(); + toRemove.add(PKG_O); + mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), toRemove, null); + + assertFalse(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false) + .isImportanceLockedByCriticalDeviceFunction()); + assertFalse(mHelper.getNotificationChannel(PKG_O, UID_O, b.getId(), false) + .isImportanceLockedByCriticalDeviceFunction()); + } + + @Test + public void testUpdateDefaultApps_addAndRemove() { + NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH); + NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW); + mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false); + mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, b, false, false); + + ArraySet<String> toAdd = new ArraySet<>(); + toAdd.add(PKG_O); + mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, toAdd); + + + assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false) + .isImportanceLockedByCriticalDeviceFunction()); + assertFalse(mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, b.getId(), false) + .isImportanceLockedByCriticalDeviceFunction()); + + // now the default is PKG_N_MR1 + ArraySet<String> toRemove = new ArraySet<>(); + toRemove.add(PKG_O); + toAdd = new ArraySet<>(); + toAdd.add(PKG_N_MR1); + mHelper.updateDefaultApps(USER.getIdentifier(), toRemove, toAdd); + + assertFalse(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false) + .isImportanceLockedByCriticalDeviceFunction()); + assertTrue(mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, b.getId(), false) + .isImportanceLockedByCriticalDeviceFunction()); + } + + @Test + public void testUpdateDefaultApps_appDoesNotExist_noCrash() { + ArraySet<String> toAdd = new ArraySet<>(); + toAdd.add(PKG_O); + ArraySet<String> toRemove = new ArraySet<>(); + toRemove.add(PKG_N_MR1); + mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), toRemove, toAdd); + } + + @Test + public void testUpdateDefaultApps_channelDoesNotExistYet() { + NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH); + NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW); + mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false); + + ArraySet<String> toAdd = new ArraySet<>(); + toAdd.add(PKG_O); + mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, toAdd); + + assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false) + .isImportanceLockedByCriticalDeviceFunction()); + + mHelper.createNotificationChannel(PKG_O, UID_O, b, true, false); + assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, b.getId(), false) + .isImportanceLockedByCriticalDeviceFunction()); + } + + @Test + public void testUpdateNotificationChannel_defaultAppLockedImportance() { + NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH); + mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false); + ArraySet<String> toAdd = new ArraySet<>(); + toAdd.add(PKG_O); + mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, toAdd); + + NotificationChannel update = new NotificationChannel("a", "a", IMPORTANCE_NONE); + update.setAllowBubbles(false); + + mHelper.updateNotificationChannel(PKG_O, UID_O, update, true); + + assertEquals(IMPORTANCE_HIGH, + mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false).getImportance()); + assertEquals(false, + mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false).canBubble()); + + mHelper.updateNotificationChannel(PKG_O, UID_O, update, false); + + assertEquals(IMPORTANCE_HIGH, + mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false).getImportance()); + } } diff --git a/services/tests/uiservicestests/src/com/android/server/notification/RoleObserverTest.java b/services/tests/uiservicestests/src/com/android/server/notification/RoleObserverTest.java new file mode 100644 index 000000000000..91d3e5e4d7f6 --- /dev/null +++ b/services/tests/uiservicestests/src/com/android/server/notification/RoleObserverTest.java @@ -0,0 +1,391 @@ +/* + * 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.server.notification; + +import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; +import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_GONE; +import static android.app.Notification.FLAG_FOREGROUND_SERVICE; +import static android.app.NotificationManager.EXTRA_BLOCKED_STATE; +import static android.app.NotificationManager.IMPORTANCE_DEFAULT; +import static android.app.NotificationManager.IMPORTANCE_HIGH; +import static android.app.NotificationManager.IMPORTANCE_LOW; +import static android.app.NotificationManager.IMPORTANCE_MAX; +import static android.app.NotificationManager.IMPORTANCE_NONE; +import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED; +import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_AMBIENT; +import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_BADGE; +import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_FULL_SCREEN_INTENT; +import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_LIGHTS; +import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_NOTIFICATION_LIST; +import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_PEEK; +import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_SCREEN_OFF; +import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_SCREEN_ON; +import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_STATUS_BAR; +import static android.app.role.RoleManager.ROLE_DIALER; +import static android.app.role.RoleManager.ROLE_EMERGENCY; +import static android.app.role.RoleManager.ROLE_SMS; +import static android.content.pm.PackageManager.FEATURE_WATCH; +import static android.content.pm.PackageManager.PERMISSION_DENIED; +import static android.content.pm.PackageManager.PERMISSION_GRANTED; +import static android.os.Build.VERSION_CODES.O_MR1; +import static android.os.Build.VERSION_CODES.P; +import static android.service.notification.Adjustment.KEY_IMPORTANCE; +import static android.service.notification.Adjustment.KEY_USER_SENTIMENT; +import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE; +import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEUTRAL; + +import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertFalse; +import static junit.framework.Assert.assertNotNull; +import static junit.framework.Assert.assertNull; +import static junit.framework.Assert.assertTrue; +import static junit.framework.Assert.fail; + +import static org.mockito.Matchers.anyBoolean; +import static org.mockito.Matchers.anyLong; +import static org.mockito.Matchers.anyString; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.anyInt; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.reset; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.timeout; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.app.ActivityManager; +import android.app.AppOpsManager; +import android.app.IActivityManager; +import android.app.INotificationManager; +import android.app.ITransientNotification; +import android.app.IUriGrantsManager; +import android.app.Notification; +import android.app.Notification.MessagingStyle.Message; +import android.app.NotificationChannel; +import android.app.NotificationChannelGroup; +import android.app.NotificationManager; +import android.app.admin.DevicePolicyManagerInternal; +import android.app.role.RoleManager; +import android.app.usage.UsageStatsManagerInternal; +import android.companion.ICompanionDeviceManager; +import android.content.ComponentName; +import android.content.ContentUris; +import android.content.Context; +import android.content.Intent; +import android.content.pm.ApplicationInfo; +import android.content.pm.IPackageManager; +import android.content.pm.PackageManager; +import android.content.pm.ParceledListSlice; +import android.content.pm.UserInfo; +import android.graphics.Color; +import android.media.AudioManager; +import android.net.Uri; +import android.os.Binder; +import android.os.Build; +import android.os.Bundle; +import android.os.IBinder; +import android.os.Looper; +import android.os.Process; +import android.os.RemoteException; +import android.os.UserHandle; +import android.os.UserManager; +import android.provider.DeviceConfig; +import android.provider.MediaStore; +import android.provider.Settings; +import android.service.notification.Adjustment; +import android.service.notification.NotificationListenerService; +import android.service.notification.NotificationStats; +import android.service.notification.NotifyingApp; +import android.service.notification.StatusBarNotification; +import android.test.suitebuilder.annotation.SmallTest; +import android.testing.AndroidTestingRunner; +import android.testing.TestableContext; +import android.testing.TestableLooper; +import android.testing.TestableLooper.RunWithLooper; +import android.testing.TestablePermissions; +import android.text.Html; +import android.util.ArrayMap; +import android.util.ArraySet; +import android.util.AtomicFile; + +import com.android.internal.R; +import com.android.internal.config.sysui.SystemUiDeviceConfigFlags; +import com.android.internal.statusbar.NotificationVisibility; +import com.android.server.LocalServices; +import com.android.server.UiServiceTestCase; +import com.android.server.lights.Light; +import com.android.server.lights.LightsManager; +import com.android.server.notification.NotificationManagerService.NotificationAssistants; +import com.android.server.notification.NotificationManagerService.NotificationListeners; +import com.android.server.uri.UriGrantsManagerInternal; +import com.android.server.wm.WindowManagerInternal; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.mockito.stubbing.Answer; + +import java.io.BufferedInputStream; +import java.io.ByteArrayInputStream; +import java.io.FileInputStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.Executor; +import java.util.function.Consumer; + +import androidx.annotation.Nullable; +import androidx.test.InstrumentationRegistry; + +@SmallTest +@RunWith(AndroidTestingRunner.class) +@RunWithLooper +public class RoleObserverTest extends UiServiceTestCase { + private TestableNotificationManagerService mService; + private NotificationManagerService.RoleObserver mRoleObserver; + + private TestableContext mContext = spy(getContext()); + + @Mock + private PreferencesHelper mPreferencesHelper; + @Mock + private UserManager mUm; + @Mock + private Executor mExecutor; + @Mock + private RoleManager mRoleManager; + + private List<UserInfo> mUsers; + + private static class TestableNotificationManagerService extends NotificationManagerService { + + TestableNotificationManagerService(Context context) { + super(context); + } + + @Override + protected void handleSavePolicyFile() { + return; + } + + @Override + protected void loadPolicyFile() { + return; + } + } + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + + LocalServices.removeServiceForTest(WindowManagerInternal.class); + LocalServices.addService(WindowManagerInternal.class, mock(WindowManagerInternal.class)); + + mUsers = new ArrayList<>(); + mUsers.add(new UserInfo(0, "system", 0)); + mUsers.add(new UserInfo(10, "second", 0)); + when(mUm.getUsers()).thenReturn(mUsers); + + mService = new TestableNotificationManagerService(mContext); + mRoleObserver = mService.new RoleObserver(mRoleManager, mExecutor); + + try { + mService.init(mock(Looper.class), + mock(IPackageManager.class), mock(PackageManager.class), + mock(LightsManager.class), + mock(NotificationListeners.class), mock(NotificationAssistants.class), + mock(ConditionProviders.class), mock(ICompanionDeviceManager.class), + mock(SnoozeHelper.class), mock(NotificationUsageStats.class), + mock(AtomicFile.class), mock(ActivityManager.class), + mock(GroupHelper.class), mock(IActivityManager.class), + mock(UsageStatsManagerInternal.class), + mock(DevicePolicyManagerInternal.class), mock(IUriGrantsManager.class), + mock(UriGrantsManagerInternal.class), + mock(AppOpsManager.class), mUm); + } catch (SecurityException e) { + if (!e.getMessage().contains("Permission Denial: not allowed to send broadcast")) { + throw e; + } + } + mService.setPreferencesHelper(mPreferencesHelper); + } + + @Test + public void testInit() { + List<String> dialer0 = new ArrayList<>(); + dialer0.add("dialer"); + List<String> emer0 = new ArrayList<>(); + emer0.add("emergency"); + List<String> sms10 = new ArrayList<>(); + sms10.add("sms"); + when(mRoleManager.getRoleHoldersAsUser( + ROLE_DIALER, + mUsers.get(0).getUserHandle())). + thenReturn(dialer0); + when(mRoleManager.getRoleHoldersAsUser( + ROLE_EMERGENCY, + mUsers.get(0).getUserHandle())). + thenReturn(emer0); + when(mRoleManager.getRoleHoldersAsUser( + ROLE_SMS, + mUsers.get(1).getUserHandle())). + thenReturn(sms10); + + mRoleObserver.init(); + + // verify internal records of current state of the world + assertTrue(mRoleObserver.isApprovedPackageForRoleForUser( + ROLE_DIALER, dialer0.get(0), mUsers.get(0).id)); + assertFalse(mRoleObserver.isApprovedPackageForRoleForUser( + ROLE_DIALER, dialer0.get(0), mUsers.get(1).id)); + assertFalse(mRoleObserver.isApprovedPackageForRoleForUser( + ROLE_SMS, dialer0.get(0), mUsers.get(1).id)); + + assertTrue(mRoleObserver.isApprovedPackageForRoleForUser( + ROLE_EMERGENCY, emer0.get(0), mUsers.get(0).id)); + assertFalse(mRoleObserver.isApprovedPackageForRoleForUser( + ROLE_EMERGENCY, emer0.get(0), mUsers.get(1).id)); + + assertFalse(mRoleObserver.isApprovedPackageForRoleForUser( + ROLE_SMS, sms10.get(0), mUsers.get(0).id)); + assertFalse(mRoleObserver.isApprovedPackageForRoleForUser( + ROLE_DIALER, sms10.get(0), mUsers.get(0).id)); + assertTrue(mRoleObserver.isApprovedPackageForRoleForUser( + ROLE_SMS, sms10.get(0), mUsers.get(1).id)); + + // make sure we're listening to updates + verify(mRoleManager, times(1)).addOnRoleHoldersChangedListenerAsUser( + eq(mExecutor), any(), eq(UserHandle.ALL)); + + // make sure we told pref helper about the state of the world + verify(mPreferencesHelper, times(1)).updateDefaultApps(0, null, new ArraySet<>(dialer0)); + verify(mPreferencesHelper, times(1)).updateDefaultApps(0, null, new ArraySet<>(emer0)); + verify(mPreferencesHelper, times(1)).updateDefaultApps(10, null, new ArraySet<>(sms10)); + } + + @Test + public void testSwapDefault() { + List<String> dialer0 = new ArrayList<>(); + dialer0.add("dialer"); + + when(mRoleManager.getRoleHoldersAsUser( + ROLE_DIALER, + mUsers.get(0).getUserHandle())). + thenReturn(dialer0); + + mRoleObserver.init(); + + List<String> newDefault = new ArrayList<>(); + newDefault.add("phone"); + + when(mRoleManager.getRoleHoldersAsUser( + ROLE_DIALER, + mUsers.get(0).getUserHandle())). + thenReturn(newDefault); + + mRoleObserver.onRoleHoldersChanged(ROLE_DIALER, UserHandle.of(0)); + + verify(mPreferencesHelper, times(1)).updateDefaultApps( + 0, new ArraySet<>(dialer0), new ArraySet<>(newDefault)); + } + + @Test + public void testSwapDefault_multipleOverlappingApps() { + List<String> dialer0 = new ArrayList<>(); + dialer0.add("dialer"); + dialer0.add("phone"); + + when(mRoleManager.getRoleHoldersAsUser( + ROLE_DIALER, + mUsers.get(0).getUserHandle())). + thenReturn(dialer0); + + mRoleObserver.init(); + + assertTrue(mRoleObserver.isApprovedPackageForRoleForUser(ROLE_DIALER, "phone", 0)); + assertFalse(mRoleObserver.isApprovedPackageForRoleForUser(ROLE_DIALER, "emerPhone", 0)); + assertTrue(mRoleObserver.isApprovedPackageForRoleForUser(ROLE_DIALER, "dialer", 0)); + + List<String> newDefault = new ArrayList<>(); + newDefault.add("phone"); + newDefault.add("emerPhone"); + + when(mRoleManager.getRoleHoldersAsUser( + ROLE_DIALER, + mUsers.get(0).getUserHandle())). + thenReturn(newDefault); + + mRoleObserver.onRoleHoldersChanged(ROLE_DIALER, UserHandle.of(0)); + + ArraySet<String> expectedRemove = new ArraySet<>(); + expectedRemove.add("dialer"); + ArraySet<String> expectedAdd = new ArraySet<>(); + expectedAdd.add("emerPhone"); + + verify(mPreferencesHelper, times(1)).updateDefaultApps( + 0, expectedRemove, expectedAdd); + + assertTrue(mRoleObserver.isApprovedPackageForRoleForUser(ROLE_DIALER, "phone", 0)); + assertTrue(mRoleObserver.isApprovedPackageForRoleForUser(ROLE_DIALER, "emerPhone", 0)); + assertFalse(mRoleObserver.isApprovedPackageForRoleForUser(ROLE_DIALER, "dialer", 0)); + } + + @Test + public void testSwapDefault_newUser() { + List<String> dialer0 = new ArrayList<>(); + dialer0.add("dialer"); + + when(mRoleManager.getRoleHoldersAsUser( + ROLE_DIALER, + mUsers.get(0).getUserHandle())). + thenReturn(dialer0); + + mRoleObserver.init(); + + List<String> dialer10 = new ArrayList<>(); + dialer10.add("phone"); + + when(mRoleManager.getRoleHoldersAsUser( + ROLE_DIALER, + mUsers.get(1).getUserHandle())). + thenReturn(dialer10); + + mRoleObserver.onRoleHoldersChanged(ROLE_DIALER, UserHandle.of(10)); + + ArraySet<String> expectedRemove = new ArraySet<>(); + ArraySet<String> expectedAdd = new ArraySet<>(); + expectedAdd.add("phone"); + + verify(mPreferencesHelper, times(1)).updateDefaultApps( + 10, expectedRemove, expectedAdd); + + assertTrue(mRoleObserver.isApprovedPackageForRoleForUser(ROLE_DIALER, "phone", 10)); + assertTrue(mRoleObserver.isApprovedPackageForRoleForUser(ROLE_DIALER, "dialer", 0)); + } +} diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ScheduleCalendarTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ScheduleCalendarTest.java index 042c9d99eb8c..3b1537639973 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/ScheduleCalendarTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/ScheduleCalendarTest.java @@ -415,6 +415,39 @@ public class ScheduleCalendarTest extends UiServiceTestCase { } @Test + public void testIsAlarmInSchedule_alarmAndNowInSchedule_sameScheduleTrigger_daylightSavings() { + Calendar alarm = getDaylightSavingsDay(); + alarm.set(Calendar.HOUR_OF_DAY, 23); + alarm.set(Calendar.MINUTE, 15); + alarm.set(Calendar.SECOND, 0); + alarm.set(Calendar.MILLISECOND, 0); + + Calendar now = getDaylightSavingsDay(); + now.set(Calendar.HOUR_OF_DAY, 2); + now.set(Calendar.MINUTE, 10); + now.set(Calendar.SECOND, 0); + now.set(Calendar.MILLISECOND, 0); + now.add(Calendar.DATE, 1); // add a day, on daylight savings this becomes 3:10am + + final Calendar tempToday = getDaylightSavingsDay(); + final Calendar tempTomorrow = getDaylightSavingsDay(); + tempTomorrow.add(Calendar.DATE, 1); + mScheduleInfo.days = new int[] {tempToday.get(Calendar.DAY_OF_WEEK), + tempTomorrow.get(Calendar.DAY_OF_WEEK)}; + + mScheduleInfo.startHour = 22; + mScheduleInfo.startMinute = 15; + mScheduleInfo.endHour = 3; + mScheduleInfo.endMinute = 15; + mScheduleCalendar.setSchedule(mScheduleInfo); + + assertTrue(mScheduleCalendar.isInSchedule(alarm.getTimeInMillis())); + assertTrue(mScheduleCalendar.isInSchedule(now.getTimeInMillis())); + assertTrue(mScheduleCalendar.isAlarmInSchedule(alarm.getTimeInMillis(), + now.getTimeInMillis())); + } + + @Test public void testIsAlarmInSchedule_alarmAndNowInSchedule_sameScheduleTrigger() { Calendar alarm = new GregorianCalendar(); alarm.set(Calendar.HOUR_OF_DAY, 23); @@ -424,10 +457,10 @@ public class ScheduleCalendarTest extends UiServiceTestCase { Calendar now = new GregorianCalendar(); now.set(Calendar.HOUR_OF_DAY, 2); - now.set(Calendar.MINUTE, 15); + now.set(Calendar.MINUTE, 10); now.set(Calendar.SECOND, 0); now.set(Calendar.MILLISECOND, 0); - now.add(Calendar.DATE, 1); // add a day + now.add(Calendar.DATE, 1); // add a day, on daylight savings this becomes 3:10am mScheduleInfo.days = new int[] {getTodayDay(), getTodayDay(1)}; mScheduleInfo.startHour = 22; @@ -481,4 +514,11 @@ public class ScheduleCalendarTest extends UiServiceTestCase { cal.add(Calendar.DATE, offset); return cal.get(Calendar.DAY_OF_WEEK); } + + + private Calendar getDaylightSavingsDay() { + // the day before daylight savings in the US - March 9, 2019 + Calendar daylightSavingsDay = new GregorianCalendar(2019, 2, 9); + return daylightSavingsDay; + } } diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java index d580557638cf..32e96a592207 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java @@ -438,8 +438,11 @@ public class ActivityRecordTests extends ActivityTestsBase { doReturn(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) .when(mActivity.mAppWindowToken).getOrientationIgnoreVisibility(); mActivity.info.resizeMode = ActivityInfo.RESIZE_MODE_UNRESIZEABLE; - mActivity.info.maxAspectRatio = 1; + mActivity.info.minAspectRatio = mActivity.info.maxAspectRatio = 1; ensureActivityConfiguration(); + // The parent configuration doesn't change since the first resolved configuration, so the + // activity shouldn't be in the size compatibility mode. + assertFalse(mActivity.inSizeCompatMode()); final Rect appBounds = mActivity.getWindowConfiguration().getAppBounds(); // Ensure the app bounds keep the declared aspect ratio. 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 85b2f7b41e67..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; @@ -86,7 +87,6 @@ public class DisplayPolicyTestsBase extends WindowTestsBase { Math.min(DISPLAY_WIDTH, DISPLAY_HEIGHT) * DENSITY_DEFAULT / DISPLAY_DENSITY; mDisplayContent.getDisplayRotation().configure( DISPLAY_WIDTH, DISPLAY_HEIGHT, shortSizeDp, longSizeDp); - mDisplayPolicy.configure(DISPLAY_WIDTH, DISPLAY_HEIGHT, shortSizeDp); mDisplayPolicy.onConfigurationChanged(); mStatusBarWindow.mAttrs.gravity = Gravity.TOP; @@ -99,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/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java index 08e6ce4287a5..af048586b425 100644 --- a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java @@ -625,7 +625,7 @@ public class RecentTasksTest extends ActivityTestsBase { // excludedTask is not trimmed. assertTrimmed(mTasks.get(0)); - mRecentTasks.removeAllVisibleTasks(); + mRecentTasks.removeAllVisibleTasks(TEST_USER_0_ID); // Only visible tasks removed. assertTrimmed(mTasks.get(0), mTasks.get(1), mTasks.get(2), mTasks.get(3)); @@ -849,11 +849,31 @@ public class RecentTasksTest extends ActivityTestsBase { mRecentTasks.add(t7); // Remove all the visible tasks and ensure that they are removed - mRecentTasks.removeAllVisibleTasks(); + mRecentTasks.removeAllVisibleTasks(TEST_USER_0_ID); assertTrimmed(t1, t2, t3, t4, t5, t6, t7); } @Test + public void testRemoveAllVisibleTasksPerUser() { + mRecentTasks.setParameters(-1 /* min */, 3 /* max */, 100 /* ms */); + + // Create a visible task per user + TaskRecord t1 = createTaskBuilder(".Task1") + .setUserId(TEST_USER_0_ID) + .build(); + mRecentTasks.add(t1); + + TaskRecord t2 = createTaskBuilder(".Task1") + .setUserId(TEST_USER_1_ID) + .build(); + mRecentTasks.add(t2); + + // Remove all the visible tasks and ensure that they are removed + mRecentTasks.removeAllVisibleTasks(TEST_USER_0_ID); + assertTrimmed(t1); + } + + @Test public void testNotRestoreRecentTaskApis() { final TaskRecord task = createTaskBuilder(".Task").build(); final int taskId = task.taskId; diff --git a/services/tests/wmtests/src/com/android/server/wm/SurfaceAnimatorTest.java b/services/tests/wmtests/src/com/android/server/wm/SurfaceAnimatorTest.java index 88ac96d74df6..4f03726e7631 100644 --- a/services/tests/wmtests/src/com/android/server/wm/SurfaceAnimatorTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/SurfaceAnimatorTest.java @@ -181,15 +181,10 @@ public class SurfaceAnimatorTest extends WindowTestsBase { public void testDeferFinish() { // Start animation - mDeferFinishAnimatable.mSurfaceAnimator.startAnimation(mTransaction, mSpec, - true /* hidden */); - final ArgumentCaptor<OnAnimationFinishedCallback> callbackCaptor = ArgumentCaptor.forClass( - OnAnimationFinishedCallback.class); - assertAnimating(mDeferFinishAnimatable); - verify(mSpec).startAnimation(any(), any(), callbackCaptor.capture()); + final OnAnimationFinishedCallback onFinishedCallback = startDeferFinishAnimatable(mSpec); // Finish the animation but then make sure we are deferring. - callbackCaptor.getValue().onAnimationFinished(mSpec); + onFinishedCallback.onAnimationFinished(mSpec); assertAnimating(mDeferFinishAnimatable); // Now end defer finishing. @@ -199,6 +194,36 @@ public class SurfaceAnimatorTest extends WindowTestsBase { verify(mTransaction).remove(eq(mDeferFinishAnimatable.mLeash)); } + @Test + public void testDeferFinishDoNotFinishNextAnimation() { + // Start the first animation. + final OnAnimationFinishedCallback onFinishedCallback = startDeferFinishAnimatable(mSpec); + onFinishedCallback.onAnimationFinished(mSpec); + // The callback is the resetAndInvokeFinish in {@link SurfaceAnimator#getFinishedCallback}. + final Runnable firstDeferFinishCallback = mDeferFinishAnimatable.mEndDeferFinishCallback; + + // Start the second animation. + mDeferFinishAnimatable.mSurfaceAnimator.cancelAnimation(); + startDeferFinishAnimatable(mSpec2); + mDeferFinishAnimatable.mFinishedCallbackCalled = false; + + // Simulate the first deferred callback is executed from + // {@link AnimatingAppWindowTokenRegistry#endDeferringFinished}. + firstDeferFinishCallback.run(); + // The second animation should not be finished. + assertFalse(mDeferFinishAnimatable.mFinishedCallbackCalled); + } + + private OnAnimationFinishedCallback startDeferFinishAnimatable(AnimationAdapter anim) { + mDeferFinishAnimatable.mSurfaceAnimator.startAnimation(mTransaction, anim, + true /* hidden */); + final ArgumentCaptor<OnAnimationFinishedCallback> callbackCaptor = ArgumentCaptor.forClass( + OnAnimationFinishedCallback.class); + assertAnimating(mDeferFinishAnimatable); + verify(anim).startAnimation(any(), any(), callbackCaptor.capture()); + return callbackCaptor.getValue(); + } + private void assertAnimating(MyAnimatable animatable) { assertTrue(animatable.mSurfaceAnimator.isAnimating()); assertNotNull(animatable.mSurfaceAnimator.getAnimation()); diff --git a/services/usb/java/com/android/server/usb/UsbPortManager.java b/services/usb/java/com/android/server/usb/UsbPortManager.java index 96e12ce837ca..749258e76f79 100644 --- a/services/usb/java/com/android/server/usb/UsbPortManager.java +++ b/services/usb/java/com/android/server/usb/UsbPortManager.java @@ -965,7 +965,6 @@ public class UsbPortManager { private void handlePortLocked(PortInfo portInfo, IndentingPrintWriter pw) { sendPortChangedBroadcastLocked(portInfo); - enableContaminantDetectionIfNeeded(portInfo, pw); logToStatsd(portInfo, pw); updateContaminantNotification(); } @@ -977,6 +976,7 @@ public class UsbPortManager { private void handlePortChangedLocked(PortInfo portInfo, IndentingPrintWriter pw) { logAndPrint(Log.INFO, pw, "USB port changed: " + portInfo); + enableContaminantDetectionIfNeeded(portInfo, pw); handlePortLocked(portInfo, pw); } diff --git a/startop/iorap/tests/Android.bp b/startop/iorap/tests/Android.bp index 4359978f5814..3e60ad448cae 100644 --- a/startop/iorap/tests/Android.bp +++ b/startop/iorap/tests/Android.bp @@ -16,32 +16,48 @@ java_library { name: "libiorap-java-test-lib", srcs: ["src/**/*.kt"], - static_libs: [ - // Non-test dependencies - - // library under test - "services.startop.iorap", - // need the system_server code to be on the classpath, - "services.core", - - // Test Dependencies - - // test android dependencies - "platform-test-annotations", - "androidx.test.rules", - // test framework dependencies - "mockito-target-inline-minus-junit4", - // "mockito-target-minus-junit4", + // Non-test dependencies + // library under test + "services.startop.iorap", + // need the system_server code to be on the classpath, + "services.core", + // Test Dependencies + // test android dependencies + "platform-test-annotations", + "androidx.test.rules", + // test framework dependencies + "mockito-target-inline-minus-junit4", + // "mockito-target-minus-junit4", // Mockito also requires JNI (see Android.mk) // and android:debuggable=true (see AndroidManifest.xml) - "truth-prebuilt", + "truth-prebuilt", ], - // sdk_version: "current", // certificate: "platform", - - libs: ["android.test.base", "android.test.runner"], - + libs: [ + "android.test.base", + "android.test.runner", + ], // test_suites: ["device-tests"], } + +android_test { + name: "libiorap-java-tests", + dxflags: ["--multi-dex"], + test_suites: ["device-tests"], + static_libs: ["libiorap-java-test-lib"], + compile_multilib: "both", + jni_libs: [ + "libdexmakerjvmtiagent", + "libstaticjvmtiagent", + "libmultiplejvmtiagentsinterferenceagent", + ], + libs: [ + "android.test.base", + "android.test.runner", + ], + // Use private APIs + certificate: "platform", + platform_apis: true, +} diff --git a/startop/iorap/tests/Android.mk b/startop/iorap/tests/Android.mk deleted file mode 100644 index fa8c8b5fba89..000000000000 --- a/startop/iorap/tests/Android.mk +++ /dev/null @@ -1,49 +0,0 @@ -# Copyright (C) 2018 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# android_test does not support JNI libraries -# TODO: once b/80095087 is fixed, rewrite this back to android_test -LOCAL_PATH := $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_MODULE_TAGS := tests - -LOCAL_JACK_FLAGS := --multi-dex native -LOCAL_DX_FLAGS := --multi-dex - -LOCAL_PACKAGE_NAME := libiorap-java-tests -LOCAL_COMPATIBILITY_SUITE := device-tests - -LOCAL_STATIC_JAVA_LIBRARIES := \ - libiorap-java-test-lib - -LOCAL_MULTILIB := both - -LOCAL_JNI_SHARED_LIBRARIES := \ - libdexmakerjvmtiagent \ - libstaticjvmtiagent \ - libmultiplejvmtiagentsinterferenceagent - -LOCAL_JAVA_LIBRARIES := \ - android.test.base \ - android.test.runner - -# Use private APIs -LOCAL_CERTIFICATE := platform -LOCAL_PRIVATE_PLATFORM_APIS := true - -# Disable presubmit test until it works with disabled iorap by default. -LOCAL_PRESUBMIT_DISABLED := true - -include $(BUILD_PACKAGE) diff --git a/telephony/java/android/provider/Telephony.java b/telephony/java/android/provider/Telephony.java index 3106e40e076e..52e0ebd334b5 100644 --- a/telephony/java/android/provider/Telephony.java +++ b/telephony/java/android/provider/Telephony.java @@ -35,6 +35,7 @@ import android.database.Cursor; import android.database.sqlite.SqliteWrapper; import android.net.Uri; import android.os.Build; +import android.os.Parcel; import android.telephony.Rlog; import android.telephony.ServiceState; import android.telephony.SmsMessage; @@ -4130,32 +4131,24 @@ public final class Telephony { */ public static ContentValues getContentValuesForServiceState(ServiceState state) { ContentValues values = new ContentValues(); - values.put(VOICE_REG_STATE, state.getVoiceRegState()); - values.put(DATA_REG_STATE, state.getDataRegState()); - values.put(VOICE_ROAMING_TYPE, state.getVoiceRoamingType()); - values.put(DATA_ROAMING_TYPE, state.getDataRoamingType()); - values.put(VOICE_OPERATOR_ALPHA_LONG, state.getVoiceOperatorAlphaLong()); - values.put(VOICE_OPERATOR_ALPHA_SHORT, state.getVoiceOperatorAlphaShort()); - values.put(VOICE_OPERATOR_NUMERIC, state.getVoiceOperatorNumeric()); - values.put(DATA_OPERATOR_ALPHA_LONG, state.getDataOperatorAlphaLong()); - values.put(DATA_OPERATOR_ALPHA_SHORT, state.getDataOperatorAlphaShort()); - values.put(DATA_OPERATOR_NUMERIC, state.getDataOperatorNumeric()); - values.put(IS_MANUAL_NETWORK_SELECTION, state.getIsManualSelection()); - values.put(RIL_VOICE_RADIO_TECHNOLOGY, state.getRilVoiceRadioTechnology()); - values.put(RIL_DATA_RADIO_TECHNOLOGY, state.getRilDataRadioTechnology()); - values.put(CSS_INDICATOR, state.getCssIndicator()); - values.put(NETWORK_ID, state.getCdmaNetworkId()); - values.put(SYSTEM_ID, state.getCdmaSystemId()); - values.put(CDMA_ROAMING_INDICATOR, state.getCdmaRoamingIndicator()); - values.put(CDMA_DEFAULT_ROAMING_INDICATOR, state.getCdmaDefaultRoamingIndicator()); - values.put(CDMA_ERI_ICON_INDEX, state.getCdmaEriIconIndex()); - values.put(CDMA_ERI_ICON_MODE, state.getCdmaEriIconMode()); - values.put(IS_EMERGENCY_ONLY, state.isEmergencyOnly()); - values.put(IS_USING_CARRIER_AGGREGATION, state.isUsingCarrierAggregation()); + final Parcel p = Parcel.obtain(); + state.writeToParcel(p, 0); + // Turn the parcel to byte array. Safe to do this because the content values were never + // written into a persistent storage. ServiceStateProvider keeps values in the memory. + values.put(SERVICE_STATE, p.marshall()); return values; } /** + * The current service state. + * + * This is the entire {@link ServiceState} object in byte array. + * + * @hide + */ + public static final String SERVICE_STATE = "service_state"; + + /** * An integer value indicating the current voice service state. * <p> * Valid values: {@link ServiceState#STATE_IN_SERVICE}, 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 fffa935ff3c5..2ee35b24fb04 100755 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -2571,6 +2571,22 @@ public class CarrierConfigManager { "emergency_number_prefix_string_array"; /** + * Smart forwarding config. Smart forwarding is a feature to configure call forwarding to a + * different SIM in the device when one SIM is not reachable. The config here specifies a smart + * forwarding component that will launch UI for changing the configuration. An empty string + * indicates that no smart forwarding component is specified. + * + * Currently, only one non-empty configuration of smart forwarding component within system will + * be used when multiple SIMs are inserted. + * + * Empty string by default. + * + * @hide + */ + public static final String KEY_SMART_FORWARDING_CONFIG_COMPONENT_NAME_STRING = + "smart_forwarding_config_component_name_string"; + + /** * Indicates when a carrier has a primary subscription and an opportunistic subscription active, * and when Internet data is switched to opportunistic network, whether to still show * signal bar of primary network. By default it will be false, meaning whenever data @@ -2774,7 +2790,7 @@ public class CarrierConfigManager { sDefaults.putBoolean(KEY_CARRIER_FORCE_DISABLE_ETWS_CMAS_TEST_BOOL, false); sDefaults.putBoolean(KEY_CARRIER_VOLTE_PROVISIONING_REQUIRED_BOOL, false); sDefaults.putBoolean(KEY_CARRIER_UT_PROVISIONING_REQUIRED_BOOL, false); - sDefaults.putBoolean(KEY_CARRIER_SUPPORTS_SS_OVER_UT_BOOL, true); + sDefaults.putBoolean(KEY_CARRIER_SUPPORTS_SS_OVER_UT_BOOL, false); sDefaults.putBoolean(KEY_CARRIER_VOLTE_OVERRIDE_WFC_PROVISIONING_BOOL, false); sDefaults.putBoolean(KEY_CARRIER_VOLTE_TTY_SUPPORTED_BOOL, true); sDefaults.putBoolean(KEY_CARRIER_ALLOW_TURNOFF_IMS_BOOL, true); @@ -3130,6 +3146,7 @@ public class CarrierConfigManager { sDefaults.putBoolean(KEY_USE_USIM_BOOL, false); sDefaults.putBoolean(KEY_SHOW_WFC_LOCATION_PRIVACY_POLICY_BOOL, true); sDefaults.putBoolean(KEY_AUTO_CANCEL_CS_REJECT_NOTIFICATION, false); + sDefaults.putString(KEY_SMART_FORWARDING_CONFIG_COMPONENT_NAME_STRING, ""); sDefaults.putBoolean(KEY_ALWAYS_SHOW_PRIMARY_SIGNAL_BAR_IN_OPPORTUNISTIC_NETWORK_BOOLEAN, false); } diff --git a/telephony/java/android/telephony/CellIdentity.java b/telephony/java/android/telephony/CellIdentity.java index e5aadad60129..374527749354 100644 --- a/telephony/java/android/telephony/CellIdentity.java +++ b/telephony/java/android/telephony/CellIdentity.java @@ -110,6 +110,22 @@ public abstract class CellIdentity implements Parcelable { } /** + * @return MCC or null for CDMA + * @hide + */ + public String getMccString() { + return mMccStr; + } + + /** + * @return MNC or null for CDMA + * @hide + */ + public String getMncString() { + return mMncStr; + } + + /** * Returns the channel number of the cell identity. * * @hide diff --git a/telephony/java/android/telephony/CellIdentityCdma.java b/telephony/java/android/telephony/CellIdentityCdma.java index daf80f558ca5..4c00611b2355 100644 --- a/telephony/java/android/telephony/CellIdentityCdma.java +++ b/telephony/java/android/telephony/CellIdentityCdma.java @@ -109,6 +109,13 @@ public final class CellIdentityCdma extends CellIdentity { return new CellIdentityCdma(this); } + /** @hide */ + public CellIdentityCdma sanitizeLocationInfo() { + return new CellIdentityCdma(CellInfo.UNAVAILABLE, CellInfo.UNAVAILABLE, + CellInfo.UNAVAILABLE, CellInfo.UNAVAILABLE, CellInfo.UNAVAILABLE, + mAlphaLong, mAlphaShort); + } + /** * Take the latitude and longitude in 1/4 seconds and see if * the reported location is on Null Island. diff --git a/telephony/java/android/telephony/CellIdentityGsm.java b/telephony/java/android/telephony/CellIdentityGsm.java index 6328afcd54a8..5e44bf2e37a8 100644 --- a/telephony/java/android/telephony/CellIdentityGsm.java +++ b/telephony/java/android/telephony/CellIdentityGsm.java @@ -97,6 +97,12 @@ public final class CellIdentityGsm extends CellIdentity { return new CellIdentityGsm(this); } + /** @hide */ + public CellIdentityGsm sanitizeLocationInfo() { + return new CellIdentityGsm(CellInfo.UNAVAILABLE, CellInfo.UNAVAILABLE, CellInfo.UNAVAILABLE, + CellInfo.UNAVAILABLE, mMccStr, mMncStr, mAlphaLong, mAlphaShort); + } + /** * @return 3-digit Mobile Country Code, 0..999, * {@link android.telephony.CellInfo#UNAVAILABLE UNAVAILABLE} if unavailable. diff --git a/telephony/java/android/telephony/CellIdentityLte.java b/telephony/java/android/telephony/CellIdentityLte.java index e112004836a8..2dd72d6ea69c 100644 --- a/telephony/java/android/telephony/CellIdentityLte.java +++ b/telephony/java/android/telephony/CellIdentityLte.java @@ -113,6 +113,13 @@ public final class CellIdentityLte extends CellIdentity { cid.mMncStr, cid.mAlphaLong, cid.mAlphaShort); } + /** @hide */ + public CellIdentityLte sanitizeLocationInfo() { + return new CellIdentityLte(CellInfo.UNAVAILABLE, CellInfo.UNAVAILABLE, CellInfo.UNAVAILABLE, + CellInfo.UNAVAILABLE, CellInfo.UNAVAILABLE, + mMccStr, mMncStr, mAlphaLong, mAlphaShort); + } + CellIdentityLte copy() { return new CellIdentityLte(this); } diff --git a/telephony/java/android/telephony/CellIdentityNr.java b/telephony/java/android/telephony/CellIdentityNr.java index 4be52a322c03..62d23cee3bf5 100644 --- a/telephony/java/android/telephony/CellIdentityNr.java +++ b/telephony/java/android/telephony/CellIdentityNr.java @@ -46,7 +46,7 @@ public final class CellIdentityNr extends CellIdentity { * * @hide */ - public CellIdentityNr(int pci, int tac, int nrArfcn, String mccStr, String mncStr, + public CellIdentityNr(int pci, int tac, int nrArfcn, String mccStr, String mncStr, long nci, String alphal, String alphas) { super(TAG, CellInfo.TYPE_NR, mccStr, mncStr, alphal, alphas); mPci = pci; @@ -55,6 +55,12 @@ public final class CellIdentityNr extends CellIdentity { mNci = nci; } + /** @hide */ + public CellIdentityNr sanitizeLocationInfo() { + return new CellIdentityNr(CellInfo.UNAVAILABLE, CellInfo.UNAVAILABLE, CellInfo.UNAVAILABLE, + mMccStr, mMncStr, CellInfo.UNAVAILABLE, mAlphaLong, mAlphaShort); + } + /** * @return a CellLocation object for this CellIdentity. * @hide diff --git a/telephony/java/android/telephony/CellIdentityTdscdma.java b/telephony/java/android/telephony/CellIdentityTdscdma.java index 19b11b666018..a591bd15f95f 100644 --- a/telephony/java/android/telephony/CellIdentityTdscdma.java +++ b/telephony/java/android/telephony/CellIdentityTdscdma.java @@ -90,6 +90,12 @@ public final class CellIdentityTdscdma extends CellIdentity { cid.uarfcn, cid.operatorNames.alphaLong, cid.operatorNames.alphaShort); } + /** @hide */ + public CellIdentityTdscdma sanitizeLocationInfo() { + return new CellIdentityTdscdma(mMccStr, mMncStr, CellInfo.UNAVAILABLE, CellInfo.UNAVAILABLE, + CellInfo.UNAVAILABLE, CellInfo.UNAVAILABLE, mAlphaLong, mAlphaShort); + } + CellIdentityTdscdma copy() { return new CellIdentityTdscdma(this); } diff --git a/telephony/java/android/telephony/CellIdentityWcdma.java b/telephony/java/android/telephony/CellIdentityWcdma.java index b1944af18abc..674c40c2d36f 100644 --- a/telephony/java/android/telephony/CellIdentityWcdma.java +++ b/telephony/java/android/telephony/CellIdentityWcdma.java @@ -91,6 +91,13 @@ public final class CellIdentityWcdma extends CellIdentity { cid.mMncStr, cid.mAlphaLong, cid.mAlphaShort); } + /** @hide */ + public CellIdentityWcdma sanitizeLocationInfo() { + return new CellIdentityWcdma(CellInfo.UNAVAILABLE, CellInfo.UNAVAILABLE, + CellInfo.UNAVAILABLE, CellInfo.UNAVAILABLE, mMccStr, mMncStr, + mAlphaLong, mAlphaShort); + } + CellIdentityWcdma copy() { return new CellIdentityWcdma(this); } diff --git a/telephony/java/android/telephony/CellInfo.java b/telephony/java/android/telephony/CellInfo.java index 1796034431a6..7edc91cd67e8 100644 --- a/telephony/java/android/telephony/CellInfo.java +++ b/telephony/java/android/telephony/CellInfo.java @@ -197,6 +197,11 @@ public abstract class CellInfo implements Parcelable { @NonNull public abstract CellSignalStrength getCellSignalStrength(); + /** @hide */ + public CellInfo sanitizeLocationInfo() { + return null; + } + /** * Gets the connection status of this cell. * diff --git a/telephony/java/android/telephony/CellInfoCdma.java b/telephony/java/android/telephony/CellInfoCdma.java index 82bb3961e10c..a4570e41dc26 100644 --- a/telephony/java/android/telephony/CellInfoCdma.java +++ b/telephony/java/android/telephony/CellInfoCdma.java @@ -90,6 +90,15 @@ public final class CellInfoCdma extends CellInfo implements Parcelable { public CellSignalStrengthCdma getCellSignalStrength() { return mCellSignalStrengthCdma; } + + /** @hide */ + @Override + public CellInfo sanitizeLocationInfo() { + CellInfoCdma result = new CellInfoCdma(this); + result.mCellIdentityCdma = mCellIdentityCdma.sanitizeLocationInfo(); + return result; + } + /** @hide */ public void setCellSignalStrength(CellSignalStrengthCdma css) { mCellSignalStrengthCdma = css; diff --git a/telephony/java/android/telephony/CellInfoGsm.java b/telephony/java/android/telephony/CellInfoGsm.java index 59fcd1e5c67a..ce32bc1b9cb7 100644 --- a/telephony/java/android/telephony/CellInfoGsm.java +++ b/telephony/java/android/telephony/CellInfoGsm.java @@ -84,6 +84,15 @@ public final class CellInfoGsm extends CellInfo implements Parcelable { public CellSignalStrengthGsm getCellSignalStrength() { return mCellSignalStrengthGsm; } + + /** @hide */ + @Override + public CellInfo sanitizeLocationInfo() { + CellInfoGsm result = new CellInfoGsm(this); + result.mCellIdentityGsm = mCellIdentityGsm.sanitizeLocationInfo(); + return result; + } + /** @hide */ public void setCellSignalStrength(CellSignalStrengthGsm css) { mCellSignalStrengthGsm = css; diff --git a/telephony/java/android/telephony/CellInfoLte.java b/telephony/java/android/telephony/CellInfoLte.java index 08dafe11e0d0..01ee20a7fa1e 100644 --- a/telephony/java/android/telephony/CellInfoLte.java +++ b/telephony/java/android/telephony/CellInfoLte.java @@ -96,6 +96,15 @@ public final class CellInfoLte extends CellInfo implements Parcelable { if (DBG) log("getCellSignalStrength: " + mCellSignalStrengthLte); return mCellSignalStrengthLte; } + + /** @hide */ + @Override + public CellInfo sanitizeLocationInfo() { + CellInfoLte result = new CellInfoLte(this); + result.mCellIdentityLte = mCellIdentityLte.sanitizeLocationInfo(); + return result; + } + /** @hide */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public void setCellSignalStrength(CellSignalStrengthLte css) { diff --git a/telephony/java/android/telephony/CellInfoNr.java b/telephony/java/android/telephony/CellInfoNr.java index 0227610024a4..ba4a907fdce8 100644 --- a/telephony/java/android/telephony/CellInfoNr.java +++ b/telephony/java/android/telephony/CellInfoNr.java @@ -36,6 +36,13 @@ public final class CellInfoNr extends CellInfo { mCellSignalStrength = CellSignalStrengthNr.CREATOR.createFromParcel(in); } + private CellInfoNr(CellInfoNr other, boolean sanitizeLocationInfo) { + super(other); + mCellIdentity = sanitizeLocationInfo ? other.mCellIdentity.sanitizeLocationInfo() + : other.mCellIdentity; + mCellSignalStrength = other.mCellSignalStrength; + } + @Override @NonNull public CellIdentity getCellIdentity() { @@ -48,6 +55,12 @@ public final class CellInfoNr extends CellInfo { return mCellSignalStrength; } + /** @hide */ + @Override + public CellInfo sanitizeLocationInfo() { + return new CellInfoNr(this, true); + } + @Override public int hashCode() { return Objects.hash(super.hashCode(), mCellIdentity, mCellSignalStrength); diff --git a/telephony/java/android/telephony/CellInfoTdscdma.java b/telephony/java/android/telephony/CellInfoTdscdma.java index 1830086ba448..ccafda61a177 100644 --- a/telephony/java/android/telephony/CellInfoTdscdma.java +++ b/telephony/java/android/telephony/CellInfoTdscdma.java @@ -91,6 +91,14 @@ public final class CellInfoTdscdma extends CellInfo implements Parcelable { } /** @hide */ + @Override + public CellInfo sanitizeLocationInfo() { + CellInfoTdscdma result = new CellInfoTdscdma(this); + result.mCellIdentityTdscdma = mCellIdentityTdscdma.sanitizeLocationInfo(); + return result; + } + + /** @hide */ public void setCellSignalStrength(CellSignalStrengthTdscdma css) { mCellSignalStrengthTdscdma = css; } diff --git a/telephony/java/android/telephony/CellInfoWcdma.java b/telephony/java/android/telephony/CellInfoWcdma.java index 02dbb1a5ee40..1b32178db337 100644 --- a/telephony/java/android/telephony/CellInfoWcdma.java +++ b/telephony/java/android/telephony/CellInfoWcdma.java @@ -84,6 +84,15 @@ public final class CellInfoWcdma extends CellInfo implements Parcelable { public CellSignalStrengthWcdma getCellSignalStrength() { return mCellSignalStrengthWcdma; } + + /** @hide */ + @Override + public CellInfo sanitizeLocationInfo() { + CellInfoWcdma result = new CellInfoWcdma(this); + result.mCellIdentityWcdma = mCellIdentityWcdma.sanitizeLocationInfo(); + return result; + } + /** @hide */ public void setCellSignalStrength(CellSignalStrengthWcdma css) { mCellSignalStrengthWcdma = css; diff --git a/telephony/java/android/telephony/DataSpecificRegistrationInfo.java b/telephony/java/android/telephony/DataSpecificRegistrationInfo.java index fbf488e590fd..465c2b1be3d9 100644 --- a/telephony/java/android/telephony/DataSpecificRegistrationInfo.java +++ b/telephony/java/android/telephony/DataSpecificRegistrationInfo.java @@ -74,16 +74,25 @@ public final class DataSpecificRegistrationInfo implements Parcelable { private final LteVopsSupportInfo mLteVopsSupportInfo; /** + * Indicates if it's using carrier aggregation + * + * @hide + */ + public final boolean isUsingCarrierAggregation; + + /** * @hide */ DataSpecificRegistrationInfo( int maxDataCalls, boolean isDcNrRestricted, boolean isNrAvailable, - boolean isEnDcAvailable, LteVopsSupportInfo lteVops) { + boolean isEnDcAvailable, LteVopsSupportInfo lteVops, + boolean isUsingCarrierAggregation) { this.maxDataCalls = maxDataCalls; this.isDcNrRestricted = isDcNrRestricted; this.isNrAvailable = isNrAvailable; this.isEnDcAvailable = isEnDcAvailable; this.mLteVopsSupportInfo = lteVops; + this.isUsingCarrierAggregation = isUsingCarrierAggregation; } private DataSpecificRegistrationInfo(Parcel source) { @@ -92,6 +101,7 @@ public final class DataSpecificRegistrationInfo implements Parcelable { isNrAvailable = source.readBoolean(); isEnDcAvailable = source.readBoolean(); mLteVopsSupportInfo = LteVopsSupportInfo.CREATOR.createFromParcel(source); + isUsingCarrierAggregation = source.readBoolean(); } @Override @@ -101,6 +111,7 @@ public final class DataSpecificRegistrationInfo implements Parcelable { dest.writeBoolean(isNrAvailable); dest.writeBoolean(isEnDcAvailable); mLteVopsSupportInfo.writeToParcel(dest, flags); + dest.writeBoolean(isUsingCarrierAggregation); } @Override @@ -116,7 +127,8 @@ public final class DataSpecificRegistrationInfo implements Parcelable { .append(" isDcNrRestricted = " + isDcNrRestricted) .append(" isNrAvailable = " + isNrAvailable) .append(" isEnDcAvailable = " + isEnDcAvailable) - .append(mLteVopsSupportInfo.toString()) + .append(" " + mLteVopsSupportInfo.toString()) + .append(" isUsingCarrierAggregation = " + isUsingCarrierAggregation) .append(" }") .toString(); } @@ -124,7 +136,7 @@ public final class DataSpecificRegistrationInfo implements Parcelable { @Override public int hashCode() { return Objects.hash(maxDataCalls, isDcNrRestricted, isNrAvailable, isEnDcAvailable, - mLteVopsSupportInfo); + mLteVopsSupportInfo, isUsingCarrierAggregation); } @Override @@ -138,7 +150,8 @@ public final class DataSpecificRegistrationInfo implements Parcelable { && this.isDcNrRestricted == other.isDcNrRestricted && this.isNrAvailable == other.isNrAvailable && this.isEnDcAvailable == other.isEnDcAvailable - && this.mLteVopsSupportInfo.equals(other.mLteVopsSupportInfo); + && this.mLteVopsSupportInfo.equals(other.mLteVopsSupportInfo) + && this.isUsingCarrierAggregation == other.isUsingCarrierAggregation; } public static final @NonNull Parcelable.Creator<DataSpecificRegistrationInfo> CREATOR = diff --git a/telephony/java/android/telephony/NetworkRegistrationInfo.java b/telephony/java/android/telephony/NetworkRegistrationInfo.java index 1dc29979dc61..2bb02e7af1e0 100644 --- a/telephony/java/android/telephony/NetworkRegistrationInfo.java +++ b/telephony/java/android/telephony/NetworkRegistrationInfo.java @@ -251,12 +251,13 @@ public final class NetworkRegistrationInfo implements Parcelable { @Nullable CellIdentity cellIdentity, int maxDataCalls, boolean isDcNrRestricted, boolean isNrAvailable, boolean isEndcAvailable, - LteVopsSupportInfo lteVopsSupportInfo) { + LteVopsSupportInfo lteVopsSupportInfo, + boolean isUsingCarrierAggregation) { this(domain, transportType, registrationState, accessNetworkTechnology, rejectCause, emergencyOnly, availableServices, cellIdentity); - mDataSpecificInfo = new DataSpecificRegistrationInfo( - maxDataCalls, isDcNrRestricted, isNrAvailable, isEndcAvailable, lteVopsSupportInfo); + maxDataCalls, isDcNrRestricted, isNrAvailable, isEndcAvailable, lteVopsSupportInfo, + isUsingCarrierAggregation); updateNrState(mDataSpecificInfo); } diff --git a/telephony/java/android/telephony/PhoneCapability.java b/telephony/java/android/telephony/PhoneCapability.java index 119f587e27c4..17b7963f0194 100644 --- a/telephony/java/android/telephony/PhoneCapability.java +++ b/telephony/java/android/telephony/PhoneCapability.java @@ -30,6 +30,25 @@ import java.util.Objects; * @hide */ public class PhoneCapability implements Parcelable { + // Hardcoded default DSDS capability. + public static final PhoneCapability DEFAULT_DSDS_CAPABILITY; + // Hardcoded default Single SIM single standby capability. + public static final PhoneCapability DEFAULT_SSSS_CAPABILITY; + + static { + ModemInfo modemInfo1 = new ModemInfo(0, 0, true, true); + ModemInfo modemInfo2 = new ModemInfo(1, 0, true, true); + + List<ModemInfo> logicalModemList = new ArrayList<>(); + logicalModemList.add(modemInfo1); + logicalModemList.add(modemInfo2); + DEFAULT_DSDS_CAPABILITY = new PhoneCapability(1, 1, 0, logicalModemList, false); + + logicalModemList = new ArrayList<>(); + logicalModemList.add(modemInfo1); + DEFAULT_SSSS_CAPABILITY = new PhoneCapability(1, 1, 0, logicalModemList, false); + } + public final int maxActiveVoiceCalls; public final int maxActiveData; public final int max5G; 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/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java index 14eac87f1575..a933da753c41 100644 --- a/telephony/java/android/telephony/SubscriptionManager.java +++ b/telephony/java/android/telephony/SubscriptionManager.java @@ -2587,8 +2587,7 @@ public class SubscriptionManager { * {@link NetworkCapabilities#NET_CAPABILITY_VALIDATED}. * @param executor The executor of where the callback will execute. * @param callback Callback will be triggered once it succeeds or failed. - * See {@link TelephonyManager.SetOpportunisticSubscriptionResult} - * for more details. Pass null if don't care about the result. + * Pass null if don't care about the result. * * @hide * @@ -2596,7 +2595,8 @@ public class SubscriptionManager { @SystemApi @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setPreferredDataSubscriptionId(int subId, boolean needValidation, - @Nullable @CallbackExecutor Executor executor, @Nullable Consumer<Integer> callback) { + @Nullable @CallbackExecutor Executor executor, @Nullable + @TelephonyManager.SetOpportunisticSubscriptionResult Consumer<Integer> callback) { if (VDBG) logd("[setPreferredDataSubscriptionId]+ subId:" + subId); try { ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub")); diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index ffd5b16b8d67..f393cba4b8f1 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -4845,22 +4845,18 @@ public class TelephonyManager { * Registers a listener object to receive notification of changes * in specified telephony states. * <p> - * To register a listener, pass a {@link PhoneStateListener} and specify at least one telephony - * state of interest in the events argument. - * - * At registration, and when a specified telephony state changes, the telephony manager invokes - * the appropriate callback method on the listener object and passes the current (updated) - * values. + * To register a listener, pass a {@link PhoneStateListener} + * and specify at least one telephony state of interest in + * the events argument. + * + * At registration, and when a specified telephony state + * changes, the telephony manager invokes the appropriate + * callback method on the listener object and passes the + * current (updated) values. * <p> - * To un-register a listener, pass the listener object and set the events argument to + * To unregister a listener, pass the listener object and set the + * events argument to * {@link PhoneStateListener#LISTEN_NONE LISTEN_NONE} (0). - * - * If this TelephonyManager object has been created with {@link #createForSubscriptionId}, - * applies to the given subId. Otherwise, applies to - * {@link SubscriptionManager#getDefaultSubscriptionId()}. To listen events for multiple subIds, - * pass a separate listener object to each TelephonyManager object created with - * {@link #createForSubscriptionId}. - * * Note: if you call this method while in the middle of a binder transaction, you <b>must</b> * call {@link android.os.Binder#clearCallingIdentity()} before calling this method. A * {@link SecurityException} will be thrown otherwise. @@ -4875,18 +4871,17 @@ public class TelephonyManager { if (mContext == null) return; try { boolean notifyNow = (getITelephony() != null); + // If the listener has not explicitly set the subId (for example, created with the + // default constructor), replace the subId so it will listen to the account the + // telephony manager is created with. + if (listener.mSubId == null) { + listener.mSubId = mSubId; + } + ITelephonyRegistry registry = getTelephonyRegistry(); if (registry != null) { - // listen to the subId the telephony manager is created with. Ignore subId in - // PhoneStateListener. - registry.listenForSubscriber(mSubId, getOpPackageName(), + registry.listenForSubscriber(listener.mSubId, getOpPackageName(), listener.callback, events, notifyNow); - // TODO: remove this once we remove PhoneStateListener constructor with subId. - if (events == PhoneStateListener.LISTEN_NONE) { - listener.mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; - } else { - listener.mSubId = mSubId; - } } else { Rlog.w(TAG, "telephony registry not ready."); } @@ -6959,6 +6954,17 @@ public class TelephonyManager { * app has carrier privileges (see {@link #hasCarrierPrivileges}) * and {@link android.Manifest.permission#ACCESS_FINE_LOCATION}. * + * If the system-wide location switch is off, apps may still call this API, with the + * following constraints: + * <ol> + * <li>The app must hold the {@code android.permission.NETWORK_SCAN} permission.</li> + * <li>The app must not supply any specific bands or channels to scan.</li> + * <li>The app must only specify MCC/MNC pairs that are + * associated to a SIM in the device.</li> + * <li>Returned results will have no meaningful info other than signal strength + * and MCC/MNC info.</li> + * </ol> + * * @param request Contains all the RAT with bands/channels that need to be scanned. * @param executor The executor through which the callback should be invoked. Since the scan * request may trigger multiple callbacks and they must be invoked in the same order as @@ -10552,6 +10558,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 @@ -10630,9 +10639,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}. @@ -10703,6 +10714,25 @@ public class TelephonyManager { } /** + * It indicates whether modem is enabled or not per slot. + * It's the corresponding status of {@link #enableModemForSlot}. + * + * @param slotIndex which slot it's checking. + * @hide + */ + public boolean isModemEnabledForSlot(int slotIndex) { + try { + ITelephony telephony = getITelephony(); + if (telephony != null) { + return telephony.isModemEnabledForSlot(slotIndex, mContext.getOpPackageName()); + } + } catch (RemoteException ex) { + Log.e(TAG, "enableModem RemoteException", ex); + } + return false; + } + + /** * Broadcast intent action for network country code changes. * * <p> diff --git a/telephony/java/android/telephony/TelephonyScanManager.java b/telephony/java/android/telephony/TelephonyScanManager.java index 91f74b867fa0..28747dab38db 100644 --- a/telephony/java/android/telephony/TelephonyScanManager.java +++ b/telephony/java/android/telephony/TelephonyScanManager.java @@ -53,6 +53,11 @@ public final class TelephonyScanManager { public static final int CALLBACK_SCAN_ERROR = 2; /** @hide */ public static final int CALLBACK_SCAN_COMPLETE = 3; + /** @hide */ + public static final int CALLBACK_RESTRICTED_SCAN_RESULTS = 4; + + /** @hide */ + public static final int INVALID_SCAN_ID = -1; /** * The caller of @@ -129,6 +134,7 @@ public final class TelephonyScanManager { } switch (message.what) { + case CALLBACK_RESTRICTED_SCAN_RESULTS: case CALLBACK_SCAN_RESULTS: try { final Bundle b = message.getData(); @@ -137,9 +143,9 @@ public final class TelephonyScanManager { for (int i = 0; i < parcelables.length; i++) { ci[i] = (CellInfo) parcelables[i]; } - executor.execute(() ->{ + executor.execute(() -> { Rlog.d(TAG, "onResults: " + ci.toString()); - callback.onResults((List<CellInfo>) Arrays.asList(ci)); + callback.onResults(Arrays.asList(ci)); }); } catch (Exception e) { Rlog.e(TAG, "Exception in networkscan callback onResults", e); @@ -200,6 +206,10 @@ public final class TelephonyScanManager { if (telephony != null) { int scanId = telephony.requestNetworkScan( subId, request, mMessenger, new Binder(), callingPackage); + if (scanId == INVALID_SCAN_ID) { + Rlog.e(TAG, "Failed to initiate network scan"); + return null; + } saveScanInfo(scanId, request, executor, callback); return new NetworkScan(scanId, subId); } 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/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl index 9e2d9ee4696b..8332ffe889f3 100644 --- a/telephony/java/com/android/internal/telephony/ITelephony.aidl +++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl @@ -1958,5 +1958,7 @@ interface ITelephony { /** * Get the IRadio HAL Version encoded as 100 * MAJOR_VERSION + MINOR_VERSION or -1 if unknown */ - int getRadioHalVersion(); + int getRadioHalVersion(); + + boolean isModemEnabledForSlot(int slotIndex, String callingPackage); } diff --git a/telephony/java/com/android/internal/telephony/TelephonyPermissions.java b/telephony/java/com/android/internal/telephony/TelephonyPermissions.java index d93e58254b95..c9b038c7c7d6 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; } @@ -288,8 +345,8 @@ public final class TelephonyPermissions { // Allow access to a device / profile owner app. DevicePolicyManager devicePolicyManager = (DevicePolicyManager) context.getSystemService( Context.DEVICE_POLICY_SERVICE); - if (devicePolicyManager != null && devicePolicyManager.checkDeviceIdentifierAccessAsUser( - callingPackage, Binder.getCallingUserHandle().getIdentifier())) { + if (devicePolicyManager != null && devicePolicyManager.checkDeviceIdentifierAccess( + callingPackage, pid, uid)) { return true; } return false; diff --git a/tests/FlickerTests/AndroidTest.xml b/tests/FlickerTests/AndroidTest.xml index 41cb74af911c..e36f97656f2a 100644 --- a/tests/FlickerTests/AndroidTest.xml +++ b/tests/FlickerTests/AndroidTest.xml @@ -17,6 +17,7 @@ </target_preparer> <test class="com.android.tradefed.testtype.AndroidJUnitTest"> <option name="package" value="com.android.server.wm.flicker"/> + <option name="exclude-annotation" value="org.junit.Ignore" /> <option name="shell-timeout" value="6600s" /> <option name="test-timeout" value="6000s" /> <option name="hidden-api-checks" value="false" /> diff --git a/packages/PackageInstaller/Android.mk b/tests/GamePerformance/Android.mk index ab5483c8afb8..58654de34029 100644 --- a/packages/PackageInstaller/Android.mk +++ b/tests/GamePerformance/Android.mk @@ -16,17 +16,24 @@ LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) +# Don't include this package in any target +LOCAL_MODULE_TAGS := tests + +LOCAL_DEX_PREOPT := false + +LOCAL_PROGUARD_ENABLED := disabled + LOCAL_SRC_FILES := $(call all-java-files-under, src) -LOCAL_PACKAGE_NAME := PackageInstaller +LOCAL_STATIC_JAVA_LIBRARIES := android-support-test + +LOCAL_JAVA_LIBRARIES := android.test.base android.test.runner + +LOCAL_PACKAGE_NAME := GamePerformance -LOCAL_CERTIFICATE := platform -LOCAL_PRIVILEGED_MODULE := true LOCAL_PRIVATE_PLATFORM_APIS := true -LOCAL_STATIC_JAVA_LIBRARIES := xz-java -LOCAL_STATIC_ANDROID_LIBRARIES := androidx.leanback_leanback +LOCAL_CERTIFICATE := platform + include $(BUILD_PACKAGE) - -include $(call all-makefiles-under, $(LOCAL_PATH)) diff --git a/tests/GamePerformance/AndroidManifest.xml b/tests/GamePerformance/AndroidManifest.xml new file mode 100644 index 000000000000..b331e2c07e14 --- /dev/null +++ b/tests/GamePerformance/AndroidManifest.xml @@ -0,0 +1,40 @@ +<?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. + --> + +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="android.gameperformance"> + <uses-sdk android:minSdkVersion="25"/> + <uses-feature android:glEsVersion="0x00020000" android:required="true" /> + + <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> + <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> + <application android:theme="@style/noeffects"> + <uses-library android:name="android.test.runner" /> + <activity android:name="android.gameperformance.GamePerformanceActivity" > + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + <uses-library android:name="android.test.runner" /> + </application> + + <!-- self-instrumenting test package. --> + <instrumentation android:name="android.test.InstrumentationTestRunner" + android:targetPackage="android.gameperformance"> + </instrumentation> +</manifest> diff --git a/tests/GamePerformance/res/values/themes.xml b/tests/GamePerformance/res/values/themes.xml new file mode 100644 index 000000000000..63130717fe72 --- /dev/null +++ b/tests/GamePerformance/res/values/themes.xml @@ -0,0 +1,25 @@ +<?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. + --> +<resources> + <style name="noeffects" parent="@android:style/Theme.Holo.NoActionBar.Fullscreen"> + <item name="android:windowNoTitle">true</item> + <item name="android:windowFullscreen">true</item> + <item name="android:fadingEdge">none</item> + <item name="android:windowContentTransitions">false</item> + <item name="android:windowAnimationStyle">@null</item> + </style> +</resources> diff --git a/tests/GamePerformance/src/android/gameperformance/ATraceRunner.java b/tests/GamePerformance/src/android/gameperformance/ATraceRunner.java new file mode 100644 index 000000000000..25754fd79a72 --- /dev/null +++ b/tests/GamePerformance/src/android/gameperformance/ATraceRunner.java @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.gameperformance; + +import java.io.BufferedReader; +import java.io.FileWriter; +import java.io.IOException; +import java.io.InputStreamReader; + +import android.app.Instrumentation; +import android.os.AsyncTask; +import android.os.ParcelFileDescriptor; +import android.util.Log; + +/** + * Helper that runs atrace command for required duration and category. Results are read from + * the output of atrace and serialized to the provided file. We cannot use direct atrace to + * file because atrace is executed in UI automator context and analysis is done in test context. + * In last case output file is not accessible from the both contexts. + */ +public class ATraceRunner extends AsyncTask<Void, Integer, Boolean>{ + private final static String TAG = "ATraceRunner"; + + // Report that atrace is done. + public interface Delegate { + public void onProcessed(boolean success); + } + + private final Instrumentation mInstrumentation; + private final String mOutput; + private final int mTimeInSeconds; + private final String mCategory; + private final Delegate mDelegate; + + public ATraceRunner(Instrumentation instrumentation, + String output, + int timeInSeconds, + String category, + Delegate delegate) { + mInstrumentation = instrumentation; + mOutput = output; + mTimeInSeconds = timeInSeconds; + mCategory = category; + mDelegate = delegate; + } + + @Override + protected Boolean doInBackground(Void... params) { + BufferedReader bufferedReader = null; + FileWriter writer = null; + try { + // Run the command. + final String cmd = "atrace -t " + mTimeInSeconds + " " + mCategory; + Log.i(TAG, "Running atrace... " + cmd); + writer = new FileWriter(mOutput); + final ParcelFileDescriptor fd = + mInstrumentation.getUiAutomation().executeShellCommand(cmd); + bufferedReader = new BufferedReader( + new InputStreamReader(new ParcelFileDescriptor.AutoCloseInputStream(fd))); + String line; + while ((line = bufferedReader.readLine()) != null) { + writer.write(line); + writer.write("\n"); + } + Log.i(TAG, "Running atrace... DONE"); + return true; + } catch (IOException e) { + Log.i(TAG, "atrace failed", e); + return false; + } finally { + Utils.closeQuietly(bufferedReader); + Utils.closeQuietly(writer); + } + } + + @Override + protected void onPostExecute(Boolean result) { + mDelegate.onProcessed(result); + } + +} diff --git a/tests/GamePerformance/src/android/gameperformance/CustomOpenGLView.java b/tests/GamePerformance/src/android/gameperformance/CustomOpenGLView.java new file mode 100644 index 000000000000..2b37280ae9b5 --- /dev/null +++ b/tests/GamePerformance/src/android/gameperformance/CustomOpenGLView.java @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.gameperformance; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +import javax.microedition.khronos.egl.EGLConfig; +import javax.microedition.khronos.opengles.GL10; + +import android.content.Context; +import android.opengl.GLES20; +import android.opengl.GLSurfaceView; + +public class CustomOpenGLView extends GLSurfaceView { + private Random mRandom; + private List<Long> mFrameTimes; + + public CustomOpenGLView(Context context) { + super(context); + + mRandom = new Random(); + mFrameTimes = new ArrayList<Long>(); + + setEGLContextClientVersion(2); + + setRenderer(new GLSurfaceView.Renderer() { + @Override + public void onSurfaceCreated(GL10 gl, EGLConfig config) { + GLES20.glClearColor(1.0f, 0.0f, 0.0f, 1.0f); + gl.glClearDepthf(1.0f); + gl.glEnable(GL10.GL_DEPTH_TEST); + gl.glDepthFunc(GL10.GL_LEQUAL); + + gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, + GL10.GL_NICEST); } + + @Override + public void onSurfaceChanged(GL10 gl, int width, int height) { + GLES20.glViewport(0, 0, width, height); + } + + @Override + public void onDrawFrame(GL10 gl) { + GLES20.glClearColor( + mRandom.nextFloat(), mRandom.nextFloat(), mRandom.nextFloat(), 1.0f); + gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); + synchronized (mFrameTimes) { + mFrameTimes.add(System.currentTimeMillis()); + } + } + }); + setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY); + } + + /** + * Resets frame times in order to calculate fps for different test pass. + */ + public void resetFrameTimes() { + synchronized (mFrameTimes) { + mFrameTimes.clear(); + } + } + + /** + * Returns current fps based on collected frame times. + */ + public double getFps() { + synchronized (mFrameTimes) { + if (mFrameTimes.size() < 2) { + return 0.0f; + } + return 1000.0 * mFrameTimes.size() / + (mFrameTimes.get(mFrameTimes.size() - 1) - mFrameTimes.get(0)); + } + } +} diff --git a/tests/GamePerformance/src/android/gameperformance/CustomSurfaceView.java b/tests/GamePerformance/src/android/gameperformance/CustomSurfaceView.java new file mode 100644 index 000000000000..a46668dd9e24 --- /dev/null +++ b/tests/GamePerformance/src/android/gameperformance/CustomSurfaceView.java @@ -0,0 +1,190 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.gameperformance; + +import java.util.ArrayList; +import java.util.List; + +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.PixelFormat; +import android.os.Handler; +import android.os.HandlerThread; +import android.os.Trace; +import android.view.Surface; +import android.view.SurfaceHolder; +import android.view.SurfaceView; + +/** + * Minimal SurfaceView that sends buffer on request. + */ +public class CustomSurfaceView extends SurfaceView implements SurfaceHolder.Callback { + // Tag for trace when buffer is requested. + public final static String LOCAL_REQUEST_BUFFER = "localRequestBuffer"; + // Tag for trace when buffer is posted. + public final static String LOCAL_POST_BUFFER = "localPostBuffer"; + + private final Object mSurfaceLock = new Object(); + // Keeps frame times. Used to calculate fps. + private List<Long> mFrameTimes; + // Surface to send. + private Surface mSurface; + private Handler mHandler; + + private Runnable mInvalidateSurfaceTask = new Runnable() { + @Override + public void run() { + synchronized (mSurfaceLock) { + if (mSurface == null) { + return; + } + invalidateSurface(true, true); + mHandler.post(this); + } + } + }; + + public CustomSurfaceView(Context context) { + super(context); + mFrameTimes = new ArrayList<Long>(); + getHolder().addCallback(this); + getHolder().setFormat(PixelFormat.OPAQUE); + + HandlerThread thread = new HandlerThread("SurfaceInvalidator"); + thread.start(); + mHandler = new Handler(thread.getLooper()); + } + + /** + * Resets frame times in order to calculate fps for different test pass. + */ + public void resetFrameTimes() { + synchronized (mSurfaceLock) { + mFrameTimes.clear(); + } + } + + /** + * Returns current fps based on collected frame times. + */ + public double getFps() { + synchronized (mSurfaceLock) { + if (mFrameTimes.size() < 2) { + return 0.0f; + } + return 1000.0 * mFrameTimes.size() / + (mFrameTimes.get(mFrameTimes.size() - 1) - mFrameTimes.get(0)); + } + } + + /** + * Invalidates surface. + * @param traceCalls set to true in case we need register trace calls. Not used for warm-up. + * @param drawFps perform drawing current fps on surface to have some payload on surface. + */ + public void invalidateSurface(boolean traceCalls, boolean drawFps) { + synchronized (mSurfaceLock) { + if (mSurface == null) { + throw new IllegalStateException("Surface is not ready"); + } + if (traceCalls) { + Trace.traceBegin(Trace.TRACE_TAG_GRAPHICS, LOCAL_REQUEST_BUFFER); + } + Canvas canvas = mSurface.lockHardwareCanvas(); + if (traceCalls) { + Trace.traceEnd(Trace.TRACE_TAG_GRAPHICS); + } + + if (drawFps) { + int textSize = canvas.getHeight() / 24; + Paint paint = new Paint(); + paint.setTextSize(textSize); + paint.setColor(0xFFFF8040); + canvas.drawARGB(92, 255, 255, 255); + canvas.drawText("FPS: " + String.format("%.2f", getFps()), 10, 300, paint); + } + + if (traceCalls) { + Trace.traceBegin(Trace.TRACE_TAG_GRAPHICS, LOCAL_POST_BUFFER); + } + mSurface.unlockCanvasAndPost(canvas); + if (traceCalls) { + Trace.traceEnd(Trace.TRACE_TAG_GRAPHICS); + } + + mFrameTimes.add(System.currentTimeMillis()); + } + } + + /** + * Wait until surface is created and ready to use or return immediately if surface + * already exists. + */ + public void waitForSurfaceReady() { + synchronized (mSurfaceLock) { + if (mSurface == null) { + try { + mSurfaceLock.wait(5000); + } catch(InterruptedException e) { + e.printStackTrace(); + } + } + if (mSurface == null) + throw new IllegalStateException("Surface is not ready."); + } + } + + /** + * Waits until surface is destroyed or return immediately if surface does not exist. + */ + public void waitForSurfaceDestroyed() { + synchronized (mSurfaceLock) { + if (mSurface != null) { + try { + mSurfaceLock.wait(5000); + } catch(InterruptedException e) { + } + } + if (mSurface != null) + throw new IllegalStateException("Surface still exists."); + } + } + + + @Override + public void surfaceCreated(SurfaceHolder holder) { + } + + @Override + public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { + // This method is always called at least once, after surfaceCreated. + synchronized (mSurfaceLock) { + mSurface = holder.getSurface(); + mSurfaceLock.notify(); + mHandler.post(mInvalidateSurfaceTask); + } + } + + @Override + public void surfaceDestroyed(SurfaceHolder holder) { + synchronized (mSurfaceLock) { + mHandler.removeCallbacks(mInvalidateSurfaceTask); + mSurface = null; + mSurfaceLock.notify(); + } + } +} diff --git a/tests/GamePerformance/src/android/gameperformance/GamePerformanceActivity.java b/tests/GamePerformance/src/android/gameperformance/GamePerformanceActivity.java new file mode 100644 index 000000000000..b0e6196b53d7 --- /dev/null +++ b/tests/GamePerformance/src/android/gameperformance/GamePerformanceActivity.java @@ -0,0 +1,132 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.gameperformance; + +import java.util.concurrent.CountDownLatch; + +import android.app.Activity; +import android.graphics.Rect; +import android.os.Bundle; +import android.view.ViewGroup; +import android.view.WindowManager; +import android.widget.RelativeLayout; + +/** + * Minimal activity that holds SurfaceView or GLSurfaceView. + * call attachSurfaceView or attachOpenGLView to switch views. + */ +public class GamePerformanceActivity extends Activity { + private CustomSurfaceView mSurfaceView = null; + private CustomOpenGLView mOpenGLView = null; + private RelativeLayout mRootLayout; + + public void attachSurfaceView() throws InterruptedException { + synchronized (mRootLayout) { + if (mSurfaceView != null) { + return; + } + final CountDownLatch latch = new CountDownLatch(1); + runOnUiThread(new Runnable() { + @Override + public void run() { + if (mOpenGLView != null) { + mRootLayout.removeView(mOpenGLView); + mOpenGLView = null; + } + mSurfaceView = new CustomSurfaceView(GamePerformanceActivity.this); + mRootLayout.addView(mSurfaceView); + latch.countDown(); + } + }); + latch.await(); + mSurfaceView.waitForSurfaceReady(); + } + } + + public void attachOpenGLView() throws InterruptedException { + synchronized (mRootLayout) { + if (mOpenGLView != null) { + return; + } + final CountDownLatch latch = new CountDownLatch(1); + runOnUiThread(new Runnable() { + @Override + public void run() { + if (mSurfaceView != null) { + mRootLayout.removeView(mSurfaceView); + mSurfaceView = null; + } + mOpenGLView = new CustomOpenGLView(GamePerformanceActivity.this); + mRootLayout.addView(mOpenGLView); + latch.countDown(); + } + }); + latch.await(); + } + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + + // To layouts in parent. First contains list of Surfaces and second + // controls. Controls stay on top. + mRootLayout = new RelativeLayout(this); + mRootLayout.setLayoutParams(new ViewGroup.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.MATCH_PARENT)); + + Rect rect = new Rect(); + getWindow().getDecorView().getWindowVisibleDisplayFrame(rect); + + mOpenGLView = new CustomOpenGLView(this); + mRootLayout.addView(mOpenGLView); + + setContentView(mRootLayout); + } + + public void resetFrameTimes() { + if (mSurfaceView != null) { + mSurfaceView.resetFrameTimes(); + } else if (mOpenGLView != null) { + mOpenGLView.resetFrameTimes(); + } else { + throw new IllegalStateException("Nothing attached"); + } + } + + public double getFps() { + if (mSurfaceView != null) { + return mSurfaceView.getFps(); + } else if (mOpenGLView != null) { + return mOpenGLView.getFps(); + } else { + throw new IllegalStateException("Nothing attached"); + } + } + + @Override + protected void onResume() { + super.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + } +}
\ No newline at end of file diff --git a/tests/GamePerformance/src/android/gameperformance/GamePerformanceTest.java b/tests/GamePerformance/src/android/gameperformance/GamePerformanceTest.java new file mode 100644 index 000000000000..e5de7d75886e --- /dev/null +++ b/tests/GamePerformance/src/android/gameperformance/GamePerformanceTest.java @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.gameperformance; + +import java.io.File; +import java.io.IOException; +import java.util.Map; +import java.util.concurrent.CountDownLatch; + +import android.app.Activity; +import android.content.Context; +import android.graphics.PixelFormat; +import android.os.Build; +import android.os.Bundle; +import android.os.Trace; +import android.test.ActivityInstrumentationTestCase2; +import android.test.suitebuilder.annotation.SmallTest; +import android.util.Log; + +public class GamePerformanceTest extends + ActivityInstrumentationTestCase2<GamePerformanceActivity> { + private final static String TAG = "GamePerformanceTest"; + + private final static int GRAPHIC_BUFFER_WARMUP_LOOP_CNT = 60; + + public GamePerformanceTest() { + super(GamePerformanceActivity.class); + } + + @SmallTest + public void testGraphicBufferMetrics() throws IOException, InterruptedException { + Bundle status = new Bundle(); + + for (int i = 0; i < 2; ++i) { + if (i == 0) { + getActivity().attachSurfaceView(); + } else { + getActivity().attachOpenGLView(); + } + + // Perform warm-up. + Thread.sleep(2000); + + // Once atrace is done, this one is triggered. + CountDownLatch latch = new CountDownLatch(1); + + final String passTag = i == 0 ? "surface" : "opengl"; + final String output = (new File(getInstrumentation().getContext().getFilesDir(), + "atrace_" + passTag + ".log")).getAbsolutePath(); + Log.i(TAG, "Collecting traces to " + output); + new ATraceRunner(getInstrumentation(), output, 5, "gfx", new ATraceRunner.Delegate() { + @Override + public void onProcessed(boolean success) { + latch.countDown(); + } + }).execute(); + + // Reset frame times and perform invalidation loop while atrace is running. + getActivity().resetFrameTimes(); + latch.await(); + + // Copy results. + final Map<String, Double> metrics = + GraphicBufferMetrics.processGraphicBufferResult(output, passTag); + for (Map.Entry<String, Double> metric : metrics.entrySet()) { + status.putDouble(metric.getKey(), metric.getValue()); + } + // Also record FPS. + status.putDouble(passTag + "_fps", getActivity().getFps()); + } + + getInstrumentation().sendStatus(Activity.RESULT_OK, status); + } +} diff --git a/tests/GamePerformance/src/android/gameperformance/GraphicBufferMetrics.java b/tests/GamePerformance/src/android/gameperformance/GraphicBufferMetrics.java new file mode 100644 index 000000000000..dffce1acdec3 --- /dev/null +++ b/tests/GamePerformance/src/android/gameperformance/GraphicBufferMetrics.java @@ -0,0 +1,530 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.gameperformance; + +import java.io.BufferedReader; +import java.io.FileReader; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.StringTokenizer; +import java.util.TreeMap; +import java.util.TreeSet; + +/** + * Utility class that performs analysis of atrace logs. This is implemented without Android + * dependencies and therefore can be used in stand-alone mode. + * Idea of this is to track atrace gfx event from graphics buffer producer/consumer. + * We analyze here from surfaceflinger + * queueBuffer - event when buffer was queued. + * acquireBuffer - event when buffer was requested for composition. + * releaseBuffer - even when buffer was released after composition. + * This also track events, issued locally + * localPostBuffer - event when buffer was posted from the local app. + * + * queueBuffer, acquireBuffer, releaseBuffer is accompanied with buffer name so we + * can track life-cycle of particular buffer. + * We don't have such information for localPostBuffer, however we can track next queueBuffer + * from surfaceflinger corresponds to previous localPostBuffer. + * + * Following results are calculated: + * post_time_[min/max/avr]_mcs - time for localPostBuffer duration. + * ready_time_[min/max/avr]_mcs - time from localPostBuffer to when buffer was acquired by + * surfaceflinger. + * latency_[min/max/avr]_mcs - time from localPostBuffer to when buffer was released by + * surfaceflinger. + * missed_frame_percents - percentage of missed frames (frames that do not have right sequence + * of events). + * + * Following is example of atrace logs from different platforms + * <...>-5237 (-----) [000] ...1 228.380392: tracing_mark_write: B|11|SurfaceView - android.gameperformance/android.gameperformance.GamePerformanceActivity#0: 2 + * surfaceflinger-5855 ( 5855) [001] ...1 169.627364: tracing_mark_write: B|24|acquireBuffer + * HwBinder:617_2-652 ( 617) [002] d..1 360262.921756: sde_evtlog: 617|sde_encoder_virt_atomic_check:855|19|0|0|0|0|0|0|0|0|0|0|0|0|0|0 + */ +public class GraphicBufferMetrics { + private final static String TAG = "GraphicBufferMetrics"; + + private final static String KEY_POST_TIME = "post_time"; + private final static String KEY_READY_TIME = "ready_time"; + private final static String KEY_LATENCY = "latency"; + private final static String SUFFIX_MIN = "min"; + private final static String SUFFIX_MAX = "max"; + private final static String SUFFIX_MEDIAN = "median"; + private final static String KEY_MISSED_FRAME_RATE = "missed_frame_percents"; + + private final static int EVENT_POST_BUFFER = 0; + private final static int EVENT_QUEUE_BUFFER = 1; + private final static int EVENT_ACQUIRE_BUFFER = 2; + private final static int EVENT_RELEASE_BUFFER = 3; + + // atrace prints this line. Used as a marker to make sure that we can parse its output. + private final static String ATRACE_HEADER = + "# TASK-PID TGID CPU# |||| TIMESTAMP FUNCTION"; + + private final static String[] KNOWN_PHRASES = new String[] { + "capturing trace... done", "TRACE:"}; + private final static List<String> KNWON_PHRASES_LIST = Arrays.asList(KNOWN_PHRASES); + + // Type of the atrace event we can parse and analyze. + private final static String FUNCTION_TRACING_MARK_WRITE = "tracing_mark_write"; + + // Trace event we can ignore. It contains current timestamp information for the atrace output. + private final static String TRACE_EVENT_CLOCK_SYNC = "trace_event_clock_sync:"; + + // Threshold we consider test passes successfully. If we cannot collect enough amount of frames + // let fail the test. 50 is calculated 10 frames per second running for five seconds. + private final static int MINIMAL_SAMPLE_CNT_TO_PASS = 50; + + /** + * Raw event in atrace. Stored hierarchically. + */ + private static class RawEvent { + // Parent of this event or null for the root holder. + public final RawEvent mParent; + // Time of the event in mcs. + public final long mTime; + // Duration of the event in mcs. + public long mDuration; + // Name/body of the event. + public final String mName; + // Children events. + public final List<RawEvent> mChildren; + + public RawEvent(RawEvent parent, long time, String name) { + mParent = parent; + mTime = time; + mName = name; + mDuration = -1; + mChildren = new ArrayList<>(); + } + + /** + * Recursively finds child events. + * @param path specify path to events. For example a/b. That means to find child with name + * 'a' of the current event and in this child find child with name 'b'. Path + * can consist from only one segment and that means we analyze only children of + * the current event. + * @param collector to collect found events. + */ + public void findEvents(String path, List<RawEvent> collector) { + final int separator = path.indexOf('/'); + final String current = separator > 0 ? path.substring(0, separator) : path; + final String nextPath = separator > 0 ? path.substring(separator + 1) : null; + for (RawEvent child : mChildren) { + if (child.mName.equals(current)) { + if (nextPath != null) { + child.findEvents(nextPath, collector); + } else { + collector.add(child); + } + } + } + } + + public void dump(String prefix) { + System.err.print(prefix); + System.err.println(mTime + "[" + mDuration + "] " + mName); + for (RawEvent e : mChildren) { + e.dump(prefix + " "); + } + } + } + + /** + * Describes graphic buffer event. local post, queued, acquired, released. + */ + private static class BufferEvent { + public final int mType; + public final long mTime; + public final long mDuration; + public final String mBufferId; + + public BufferEvent(int type, long time, long duration, String bufferId) { + mType = type; + mTime = time; + mDuration = duration; + mBufferId = bufferId; + } + + @Override + public String toString() { + return "Type: " + mType + ". Time: " + mTime + + "[" + mDuration + "]. Buffer: " + mBufferId + "."; + } + } + + /** + * Returns true if given char is digit. + */ + private static boolean isDigitChar(char c) { + return (c >= '0') && (c <= '9'); + } + + /** + * Returns true if given char is digit or '.'. + */ + private static boolean isDoubleDigitChar(char c) { + return (c == '.') || isDigitChar(c); + } + + /** + * Convert timestamp string that represents double value in seconds to long time that represents + * timestamp in microseconds. + */ + private static long getTimeStamp(String timeStampStr) { + return (long)(1000000.0 * Double.parseDouble(timeStampStr)); + } + + /** + * Reads atrace log and build event model. Result is a map, where key specifies event for the + * particular thread. Value is the synthetic root RawEvent that holds all events for the + * thread. Events are stored hierarchically. + */ + private static Map<Integer, RawEvent> buildEventModel(String fileName) throws IOException { + Map<Integer, RawEvent> result = new HashMap<>(); + + BufferedReader bufferedReader = null; + String line = ""; + boolean headerDetected = false; + try { + bufferedReader = new BufferedReader(new FileReader(fileName)); + while ((line = bufferedReader.readLine()) != null) { + // Make sure we find comment that describes output format we can with. + headerDetected |= line.equals(ATRACE_HEADER); + // Skip comments. + if (line.startsWith("#")) { + continue; + } + // Skip known service output + if (KNWON_PHRASES_LIST.contains(line)) { + continue; + } + + if (!headerDetected) { + // We don't know the format of this line. + throw new IllegalStateException("Header was not detected"); + } + + // TASK-PID in header exists at position 12. PID position 17 should contains first + // digit of thread id after the '-'. + if (!isDigitChar(line.charAt(17)) || line.charAt(16) != '-') { + throw new IllegalStateException("Failed to parse thread id: " + line); + } + int rightIndex = line.indexOf(' ', 17); + final String threadIdStr = line.substring(17, rightIndex); + final int threadId = Integer.parseInt(threadIdStr); + + // TIMESTAMP in header exists at position 45 + // This position should point in the middle of timestamp which is ended by ':'. + int leftIndex = 45; + while (isDoubleDigitChar(line.charAt(leftIndex))) { + --leftIndex; + } + rightIndex = line.indexOf(':', 45); + + final String timeStampString = line.substring(leftIndex + 1, rightIndex); + final long timeStampMcs = getTimeStamp(timeStampString); + + // Find function name, pointed by FUNCTION. Long timestamp can shift if position + // so use end of timestamp to find the function which is ended by ':'. + leftIndex = rightIndex + 1; + while (Character.isWhitespace(line.charAt(leftIndex))) { + ++leftIndex; + } + rightIndex = line.indexOf(':', leftIndex); + final String function = line.substring(leftIndex, rightIndex); + + if (!function.equals(FUNCTION_TRACING_MARK_WRITE)) { + continue; + } + + // Rest of the line is event body. + leftIndex = rightIndex + 1; + while (Character.isWhitespace(line.charAt(leftIndex))) { + ++leftIndex; + } + + final String event = line.substring(leftIndex); + if (event.startsWith(TRACE_EVENT_CLOCK_SYNC)) { + continue; + } + + // Parse event, for example: + // B|615|SurfaceView - android.gameperformance.GamePerformanceActivity#0: 1 + // E|615 + // C|11253|operation id|2 + StringTokenizer eventTokenizer = new StringTokenizer(event, "|"); + final String eventType = eventTokenizer.nextToken(); + + // Attach root on demand. + if (!result.containsKey(threadId)) { + result.put(threadId, new RawEvent(null /* parent */, + timeStampMcs, + "#ROOT_" + threadId)); + } + + switch (eventType) { + case "B": { + // Log entry starts. + eventTokenizer.nextToken(); // PID + String eventText = eventTokenizer.nextToken(); + while (eventTokenizer.hasMoreTokens()) { + eventText += " "; + eventText += eventTokenizer.nextToken(); + } + RawEvent parent = result.get(threadId); + RawEvent current = new RawEvent(parent, timeStampMcs, eventText); + parent.mChildren.add(current); + result.put(threadId, current); + } + break; + case "E": { + // Log entry ends. + RawEvent current = result.get(threadId); + current.mDuration = timeStampMcs - current.mTime; + if (current.mParent == null) { + // Detect a tail of the previous call. Remove last child element if it + // exists once it does not belong to the root. + if (!current.mChildren.isEmpty()) { + current.mChildren.remove(current.mChildren.size() -1); + } + } else { + result.put(threadId, current.mParent); + } + } + break; + case "C": + // Counter, ignore + break; + default: + throw new IllegalStateException( + "Unrecognized trace: " + line + " # " + eventType + " # " + event); + } + } + + // Detect incomplete events and detach from the root. + Set<Integer> threadIds = new TreeSet<>(); + threadIds.addAll(result.keySet()); + for (int threadId : threadIds) { + RawEvent root = result.get(threadId); + if (root.mParent == null) { + // Last trace was closed. + continue; + } + // Find the root. + while (root.mParent != null) { + root = root.mParent; + } + // Discard latest incomplete element. + root.mChildren.remove(root.mChildren.size() - 1); + result.put(threadId, root); + } + } catch (Exception e) { + throw new IOException("Failed to process " + line, e); + } finally { + Utils.closeQuietly(bufferedReader); + } + + return result; + } + + /** + * Processes provided atrace log and calculates graphics buffer metrics. + * @param fileName name of atrace log file. + * @param testTag tag to separate results for the different passes. + */ + public static Map<String, Double> processGraphicBufferResult( + String fileName, String testTag) throws IOException { + final Map<Integer, RawEvent> model = buildEventModel(fileName); + + List<RawEvent> collectorPostBuffer = new ArrayList<>(); + List<RawEvent> collectorQueueBuffer = new ArrayList<>(); + List<RawEvent> collectorReleaseBuffer = new ArrayList<>(); + List<RawEvent> collectorAcquireBuffer = new ArrayList<>(); + + // Collect required events. + for (RawEvent root : model.values()) { + // Surface view + root.findEvents("localPostBuffer", collectorPostBuffer); + // OpengGL view + root.findEvents("eglSwapBuffersWithDamageKHR", collectorPostBuffer); + + root.findEvents("queueBuffer", collectorQueueBuffer); + root.findEvents("onMessageReceived/handleMessageInvalidate/latchBuffer/" + + "updateTexImage/acquireBuffer", + collectorAcquireBuffer); + // PI stack + root.findEvents( + "onMessageReceived/handleMessageRefresh/postComposition/releaseBuffer", + collectorReleaseBuffer); + // NYC stack + root.findEvents( + "onMessageReceived/handleMessageRefresh/releaseBuffer", + collectorReleaseBuffer); + } + + // Convert raw event to buffer events. + List<BufferEvent> bufferEvents = new ArrayList<>(); + for (RawEvent event : collectorPostBuffer) { + bufferEvents.add( + new BufferEvent(EVENT_POST_BUFFER, event.mTime, event.mDuration, null)); + } + toBufferEvents(EVENT_QUEUE_BUFFER, collectorQueueBuffer, bufferEvents); + toBufferEvents(EVENT_ACQUIRE_BUFFER, collectorAcquireBuffer, bufferEvents); + toBufferEvents(EVENT_RELEASE_BUFFER, collectorReleaseBuffer, bufferEvents); + + // Sort events based on time. These events are originally taken from different threads so + // order is not always preserved. + Collections.sort(bufferEvents, new Comparator<BufferEvent>() { + @Override + public int compare(BufferEvent o1, BufferEvent o2) { + if (o1.mTime < o2.mTime) { + return -1; + } if (o1.mTime > o2.mTime) { + return +1; + } else { + return 0; + } + } + }); + + // Collect samples. + List<Long> postTimes = new ArrayList<>(); + List<Long> readyTimes = new ArrayList<>(); + List<Long> latencyTimes = new ArrayList<>(); + long missedCnt = 0; + + for (int i = 0; i < bufferEvents.size(); ++i) { + if (bufferEvents.get(i).mType != EVENT_POST_BUFFER) { + continue; + } + final int queueIndex = findNextOfType(bufferEvents, i + 1, EVENT_QUEUE_BUFFER); + if (queueIndex < 0) { + break; + } + final int acquireIndex = findNextOfBufferId(bufferEvents, queueIndex + 1, + bufferEvents.get(queueIndex).mBufferId); + if (acquireIndex < 0) { + break; + } + if (bufferEvents.get(acquireIndex).mType != EVENT_ACQUIRE_BUFFER) { + // Was not actually presented. + ++missedCnt; + continue; + } + final int releaseIndex = findNextOfBufferId(bufferEvents, acquireIndex + 1, + bufferEvents.get(queueIndex).mBufferId); + if (releaseIndex < 0) { + break; + } + if (bufferEvents.get(releaseIndex).mType != EVENT_RELEASE_BUFFER) { + // Was not actually presented. + ++missedCnt; + continue; + } + + postTimes.add(bufferEvents.get(i).mDuration); + readyTimes.add( + bufferEvents.get(acquireIndex).mTime - bufferEvents.get(i).mTime); + latencyTimes.add( + bufferEvents.get(releaseIndex).mTime - bufferEvents.get(i).mTime); + } + + if (postTimes.size() < MINIMAL_SAMPLE_CNT_TO_PASS) { + throw new IllegalStateException("Too few sample cnt: " + postTimes.size() +". " + + MINIMAL_SAMPLE_CNT_TO_PASS + " is required."); + } + + Map<String, Double> status = new TreeMap<>(); + addResults(status, testTag, KEY_POST_TIME, postTimes); + addResults(status, testTag, KEY_READY_TIME, readyTimes); + addResults(status, testTag, KEY_LATENCY, latencyTimes); + status.put(testTag + "_" + KEY_MISSED_FRAME_RATE, + 100.0 * missedCnt / (missedCnt + postTimes.size())); + return status; + } + + private static void addResults( + Map<String, Double> status, String tag, String key, List<Long> times) { + Collections.sort(times); + long min = times.get(0); + long max = times.get(0); + for (long time : times) { + min = Math.min(min, time); + max = Math.max(max, time); + } + status.put(tag + "_" + key + "_" + SUFFIX_MIN, (double)min); + status.put(tag + "_" + key + "_" + SUFFIX_MAX, (double)max); + status.put(tag + "_" + key + "_" + SUFFIX_MEDIAN, (double)times.get(times.size() / 2)); + } + + // Helper to convert surface flinger events to buffer events. + private static void toBufferEvents( + int type, List<RawEvent> rawEvents, List<BufferEvent> bufferEvents) { + for (RawEvent event : rawEvents) { + if (event.mChildren.isEmpty()) { + throw new IllegalStateException("Buffer name is expected"); + } + final String bufferName = event.mChildren.get(0).mName; + if (bufferName.startsWith("SurfaceView - android.gameperformance")) { + bufferEvents.add( + new BufferEvent(type, event.mTime, event.mDuration, bufferName)); + } + } + } + + private static int findNextOfType(List<BufferEvent> events, int startIndex, int type) { + for (int i = startIndex; i < events.size(); ++i) { + if (events.get(i).mType == type) { + return i; + } + } + return -1; + } + + private static int findNextOfBufferId( + List<BufferEvent> events, int startIndex, String bufferId) { + for (int i = startIndex; i < events.size(); ++i) { + if (bufferId.equals(events.get(i).mBufferId)) { + return i; + } + } + return -1; + } + + public static void main(String[] args) { + if (args.length != 1) { + System.err.println("Usage: " + TAG + " atrace.log"); + return; + } + + try { + System.out.println("Results:"); + for (Map.Entry<?, ?> entry : + processGraphicBufferResult(args[0], "default").entrySet()) { + System.out.println(" " + entry.getKey() + " = " + entry.getValue()); + } + } catch (IOException e) { + e.printStackTrace(); + } + } +} diff --git a/cmds/statsd/src/logd/LogListener.h b/tests/GamePerformance/src/android/gameperformance/Utils.java index d8b06e9fab92..64819712bf6d 100644 --- a/cmds/statsd/src/logd/LogListener.h +++ b/tests/GamePerformance/src/android/gameperformance/Utils.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 The Android Open Source Project + * Copyright (C) 2018 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,28 +13,19 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +package android.gameperformance; -#pragma once +import java.io.Closeable; +import java.io.IOException; -#include "logd/LogEvent.h" - -#include <utils/RefBase.h> - -namespace android { -namespace os { -namespace statsd { - -/** - * Callback for LogReader - */ -class LogListener : public virtual android::RefBase { -public: - LogListener(); - virtual ~LogListener(); - - virtual void OnLogEvent(LogEvent* msg) = 0; -}; - -} // namespace statsd -} // namespace os -} // namespace android +public class Utils { + public static void closeQuietly(Closeable closeable) { + try { + if (closeable != null) { + closeable.close(); + } + } catch (IOException e) { + // Ignore + } + } +} diff --git a/tests/Internal/Android.bp b/tests/Internal/Android.bp index 4cb9f8d5e1e6..e233fed7e785 100644 --- a/tests/Internal/Android.bp +++ b/tests/Internal/Android.bp @@ -10,6 +10,7 @@ android_test { "junit", "androidx.test.rules", "mockito-target-minus-junit4", + "truth-prebuilt", ], java_resource_dirs: ["res"], certificate: "platform", diff --git a/tests/Internal/src/com/android/internal/colorextraction/types/TonalTest.java b/tests/Internal/src/com/android/internal/colorextraction/types/TonalTest.java index 300182dd5791..768e47c03b17 100644 --- a/tests/Internal/src/com/android/internal/colorextraction/types/TonalTest.java +++ b/tests/Internal/src/com/android/internal/colorextraction/types/TonalTest.java @@ -15,6 +15,8 @@ */ package com.android.internal.colorextraction.types; +import static com.google.common.truth.Truth.assertThat; + import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; @@ -67,6 +69,36 @@ public class TonalTest { } @Test + public void extractInto_fromBitmap() { + Tonal tonal = new Tonal(InstrumentationRegistry.getContext()); + GradientColors normal = new GradientColors(); + GradientColors dark = new GradientColors(); + GradientColors extraDark = new GradientColors(); + WallpaperColors wallColors = new WallpaperColors(Color.valueOf(Color.RED), null, null, + WallpaperColors.HINT_FROM_BITMAP); + + // WHEN colors are extracted from a wallpaper with only a red primary color. + tonal.extractInto(wallColors, normal, dark, extraDark); + // THEN the main extracted color is red + assertThat(normal.getMainColor()).isEqualTo(Color.RED); + } + + @Test + public void extractInto_supportsDarkText() { + Tonal tonal = new Tonal(InstrumentationRegistry.getContext()); + GradientColors normal = new GradientColors(); + GradientColors dark = new GradientColors(); + GradientColors extraDark = new GradientColors(); + WallpaperColors wallColors = new WallpaperColors(Color.valueOf(Color.RED), null, null, + WallpaperColors.HINT_SUPPORTS_DARK_TEXT); + + // WHEN colors are extracted from a wallpaper with only a red primary color. + tonal.extractInto(wallColors, normal, dark, extraDark); + // THEN the main extracted color is red + assertThat(normal.getMainColor()).isEqualTo(Color.RED); + } + + @Test public void colorRange_containsColor() { Tonal.ColorRange colorRange = new Tonal.ColorRange(new Range<>(0f, 50f), new Range<>(0f, 1f), new Range<>(0f, 1f)); diff --git a/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java b/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java index d0c261279c9d..28af7cee8f38 100644 --- a/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java +++ b/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java @@ -19,11 +19,16 @@ package com.android.server; import static com.android.server.PackageWatchdog.TRIGGER_FAILURE_COUNT; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import android.content.Context; import android.content.pm.VersionedPackage; +import android.os.Handler; +import android.os.RemoteException; import android.os.test.TestLooper; +import android.util.AtomicFile; import androidx.test.InstrumentationRegistry; @@ -36,11 +41,14 @@ import org.junit.Test; import java.io.File; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.concurrent.TimeUnit; +import java.util.function.Consumer; -// TODO(zezeozue): Write test without using PackageWatchdog#getPackages. Just rely on +// TODO: Write test without using PackageWatchdog#getPackages. Just rely on // behavior of observers receiving crash notifications or not to determine if it's registered +// TODO: Use Truth in tests. /** * Test PackageWatchdog. */ @@ -77,12 +85,11 @@ public class PackageWatchdogTest { TestObserver observer3 = new TestObserver(OBSERVER_NAME_3); // Start observing for observer1 which will be unregistered - watchdog.startObservingHealth(observer1, Arrays.asList(APP_A), SHORT_DURATION, false); + watchdog.startObservingHealth(observer1, Arrays.asList(APP_A), SHORT_DURATION); // Start observing for observer2 which will expire - watchdog.startObservingHealth(observer2, Arrays.asList(APP_A, APP_B), SHORT_DURATION, - false); + watchdog.startObservingHealth(observer2, Arrays.asList(APP_A, APP_B), SHORT_DURATION); // Start observing for observer3 which will have expiry duration reduced - watchdog.startObservingHealth(observer3, Arrays.asList(APP_A), LONG_DURATION, false); + watchdog.startObservingHealth(observer3, Arrays.asList(APP_A), LONG_DURATION); // Verify packages observed at start // 1 @@ -145,9 +152,8 @@ public class PackageWatchdogTest { TestObserver observer1 = new TestObserver(OBSERVER_NAME_1); TestObserver observer2 = new TestObserver(OBSERVER_NAME_2); - watchdog1.startObservingHealth(observer1, Arrays.asList(APP_A), SHORT_DURATION, false); - watchdog1.startObservingHealth(observer2, Arrays.asList(APP_A, APP_B), SHORT_DURATION, - false); + watchdog1.startObservingHealth(observer1, Arrays.asList(APP_A), SHORT_DURATION); + watchdog1.startObservingHealth(observer2, Arrays.asList(APP_A, APP_B), SHORT_DURATION); // Verify 2 observers are registered and saved internally // 1 @@ -193,8 +199,8 @@ public class PackageWatchdogTest { TestObserver observer1 = new TestObserver(OBSERVER_NAME_1); TestObserver observer2 = new TestObserver(OBSERVER_NAME_2); - watchdog.startObservingHealth(observer2, Arrays.asList(APP_A), SHORT_DURATION, false); - watchdog.startObservingHealth(observer1, Arrays.asList(APP_A), SHORT_DURATION, false); + watchdog.startObservingHealth(observer2, Arrays.asList(APP_A), SHORT_DURATION); + watchdog.startObservingHealth(observer1, Arrays.asList(APP_A), SHORT_DURATION); // Then fail APP_A below the threshold for (int i = 0; i < TRIGGER_FAILURE_COUNT - 1; i++) { @@ -220,8 +226,8 @@ public class PackageWatchdogTest { TestObserver observer2 = new TestObserver(OBSERVER_NAME_2); - watchdog.startObservingHealth(observer2, Arrays.asList(APP_A), SHORT_DURATION, false); - watchdog.startObservingHealth(observer1, Arrays.asList(APP_B), SHORT_DURATION, false); + watchdog.startObservingHealth(observer2, Arrays.asList(APP_A), SHORT_DURATION); + watchdog.startObservingHealth(observer1, Arrays.asList(APP_B), SHORT_DURATION); // Then fail APP_C (not observed) above the threshold for (int i = 0; i < TRIGGER_FAILURE_COUNT; i++) { @@ -255,7 +261,7 @@ public class PackageWatchdogTest { } }; - watchdog.startObservingHealth(observer, Arrays.asList(APP_A), SHORT_DURATION, false); + watchdog.startObservingHealth(observer, Arrays.asList(APP_A), SHORT_DURATION); // Then fail APP_A (different version) above the threshold for (int i = 0; i < TRIGGER_FAILURE_COUNT; i++) { @@ -288,13 +294,13 @@ public class PackageWatchdogTest { // Start observing for all impact observers watchdog.startObservingHealth(observerNone, Arrays.asList(APP_A, APP_B, APP_C, APP_D), - SHORT_DURATION, false); + SHORT_DURATION); watchdog.startObservingHealth(observerHigh, Arrays.asList(APP_A, APP_B, APP_C), - SHORT_DURATION, false); + SHORT_DURATION); watchdog.startObservingHealth(observerMid, Arrays.asList(APP_A, APP_B), - SHORT_DURATION, false); + SHORT_DURATION); watchdog.startObservingHealth(observerLow, Arrays.asList(APP_A), - SHORT_DURATION, false); + SHORT_DURATION); // Then fail all apps above the threshold for (int i = 0; i < TRIGGER_FAILURE_COUNT; i++) { @@ -346,8 +352,8 @@ public class PackageWatchdogTest { PackageHealthObserverImpact.USER_IMPACT_MEDIUM); // Start observing for observerFirst and observerSecond with failure handling - watchdog.startObservingHealth(observerFirst, Arrays.asList(APP_A), LONG_DURATION, false); - watchdog.startObservingHealth(observerSecond, Arrays.asList(APP_A), LONG_DURATION, false); + watchdog.startObservingHealth(observerFirst, Arrays.asList(APP_A), LONG_DURATION); + watchdog.startObservingHealth(observerSecond, Arrays.asList(APP_A), LONG_DURATION); // Then fail APP_A above the threshold for (int i = 0; i < TRIGGER_FAILURE_COUNT; i++) { @@ -424,8 +430,8 @@ public class PackageWatchdogTest { PackageHealthObserverImpact.USER_IMPACT_HIGH); // Start observing for observer1 and observer2 with failure handling - watchdog.startObservingHealth(observer2, Arrays.asList(APP_A), SHORT_DURATION, false); - watchdog.startObservingHealth(observer1, Arrays.asList(APP_A), SHORT_DURATION, false); + watchdog.startObservingHealth(observer2, Arrays.asList(APP_A), SHORT_DURATION); + watchdog.startObservingHealth(observer1, Arrays.asList(APP_A), SHORT_DURATION); // Then fail APP_A above the threshold for (int i = 0; i < TRIGGER_FAILURE_COUNT; i++) { @@ -442,11 +448,12 @@ public class PackageWatchdogTest { } /** - * Test explicit health check status determines package failure or success on expiry + * Test package passing explicit health checks does not fail and vice versa. */ @Test - public void testPackageFailureExplicitHealthCheck() throws Exception { - PackageWatchdog watchdog = createWatchdog(); + public void testExplicitHealthChecks() throws Exception { + TestController controller = new TestController(); + PackageWatchdog watchdog = createWatchdog(controller, true /* withPackagesReady */); TestObserver observer1 = new TestObserver(OBSERVER_NAME_1, PackageHealthObserverImpact.USER_IMPACT_HIGH); TestObserver observer2 = new TestObserver(OBSERVER_NAME_2, @@ -457,21 +464,36 @@ public class PackageWatchdogTest { // Start observing with explicit health checks for APP_A and APP_B respectively // with observer1 and observer2 - watchdog.startObservingHealth(observer1, Arrays.asList(APP_A), SHORT_DURATION, true); - watchdog.startObservingHealth(observer2, Arrays.asList(APP_B), SHORT_DURATION, true); - // Explicit health check passed for APP_A (observer1 is aware) - watchdog.onExplicitHealthCheckPassed(APP_A); - // Start observing APP_A with explicit health checks for observer3. + controller.setSupportedPackages(Arrays.asList(APP_A, APP_B)); + watchdog.startObservingHealth(observer1, Arrays.asList(APP_A), SHORT_DURATION); + watchdog.startObservingHealth(observer2, Arrays.asList(APP_B), SHORT_DURATION); + + // Run handler so requests are dispatched to the controller + mTestLooper.dispatchAll(); + + // Verify we requested health checks for APP_A and APP_B + List<String> requestedPackages = controller.getRequestedPackages(); + assertEquals(2, requestedPackages.size()); + assertEquals(APP_A, requestedPackages.get(0)); + assertEquals(APP_B, requestedPackages.get(1)); + + // Then health check passed for APP_A (observer1 is aware) + controller.setPackagePassed(APP_A); + + // Then start observing APP_A with explicit health checks for observer3. // Observer3 didn't exist when we got the explicit health check above, so // it starts out with a non-passing explicit health check and has to wait for a pass // otherwise it would be notified of APP_A failure on expiry - watchdog.startObservingHealth(observer3, Arrays.asList(APP_A), SHORT_DURATION, true); + watchdog.startObservingHealth(observer3, Arrays.asList(APP_A), SHORT_DURATION); // Then expire observers Thread.sleep(SHORT_DURATION); // Run handler so package failures are dispatched to observers mTestLooper.dispatchAll(); + // Verify we cancelled all requests on expiry + assertEquals(0, controller.getRequestedPackages().size()); + // Verify observer1 is not notified assertEquals(0, observer1.mFailedPackages.size()); @@ -484,9 +506,96 @@ public class PackageWatchdogTest { assertEquals(APP_A, observer3.mFailedPackages.get(0)); } + /** + * Test explicit health check state can be disabled and enabled correctly. + */ + @Test + public void testExplicitHealthCheckStateChanges() throws Exception { + TestController controller = new TestController(); + PackageWatchdog watchdog = createWatchdog(controller, true /* withPackagesReady */); + TestObserver observer = new TestObserver(OBSERVER_NAME_1, + PackageHealthObserverImpact.USER_IMPACT_MEDIUM); + + // Start observing with explicit health checks for APP_A and APP_B + controller.setSupportedPackages(Arrays.asList(APP_A, APP_B, APP_C)); + watchdog.startObservingHealth(observer, Arrays.asList(APP_A), SHORT_DURATION); + watchdog.startObservingHealth(observer, Arrays.asList(APP_B), LONG_DURATION); + + // Run handler so requests are dispatched to the controller + mTestLooper.dispatchAll(); + + // Verify we requested health checks for APP_A and APP_B + List<String> requestedPackages = controller.getRequestedPackages(); + assertEquals(2, requestedPackages.size()); + assertEquals(APP_A, requestedPackages.get(0)); + assertEquals(APP_B, requestedPackages.get(1)); + + // Disable explicit health checks (marks APP_A and APP_B as passed) + watchdog.setExplicitHealthCheckEnabled(false); + + // Run handler so requests/cancellations are dispatched to the controller + mTestLooper.dispatchAll(); + + // Verify all checks are cancelled + assertEquals(0, controller.getRequestedPackages().size()); + + // Then expire APP_A + Thread.sleep(SHORT_DURATION); + mTestLooper.dispatchAll(); + + // Verify APP_A is not failed (APP_B) is not expired yet + assertEquals(0, observer.mFailedPackages.size()); + + // Re-enable explicit health checks + watchdog.setExplicitHealthCheckEnabled(true); + + // Run handler so requests/cancellations are dispatched to the controller + mTestLooper.dispatchAll(); + + // Verify no requests are made cos APP_A is expired and APP_B was marked as passed + assertEquals(0, controller.getRequestedPackages().size()); + + // Then set new supported packages + controller.setSupportedPackages(Arrays.asList(APP_C)); + // Start observing APP_A and APP_C; only APP_C has support for explicit health checks + watchdog.startObservingHealth(observer, Arrays.asList(APP_A, APP_C), SHORT_DURATION); + + // Run handler so requests/cancellations are dispatched to the controller + mTestLooper.dispatchAll(); + + // Verify requests are only made for APP_C + requestedPackages = controller.getRequestedPackages(); + assertEquals(1, requestedPackages.size()); + assertEquals(APP_C, requestedPackages.get(0)); + + // Then expire APP_A and APP_C + Thread.sleep(SHORT_DURATION); + mTestLooper.dispatchAll(); + + // Verify only APP_C is failed because explicit health checks was not supported for APP_A + assertEquals(1, observer.mFailedPackages.size()); + assertEquals(APP_C, observer.mFailedPackages.get(0)); + } + private PackageWatchdog createWatchdog() { - return new PackageWatchdog(InstrumentationRegistry.getContext(), - mTestLooper.getLooper()); + return createWatchdog(new TestController(), true /* withPackagesReady */); + } + + private PackageWatchdog createWatchdog(TestController controller, boolean withPackagesReady) { + Context context = InstrumentationRegistry.getContext(); + AtomicFile policyFile = + new AtomicFile(new File(context.getFilesDir(), "package-watchdog.xml")); + Handler handler = new Handler(mTestLooper.getLooper()); + PackageWatchdog watchdog = + new PackageWatchdog(context, policyFile, handler, handler, controller); + // Verify controller is not automatically started + assertFalse(controller.mIsEnabled); + if (withPackagesReady) { + watchdog.onPackagesReady(); + // Verify controller by default is started when packages are ready + assertTrue(controller.mIsEnabled); + } + return watchdog; } private static class TestObserver implements PackageHealthObserver { @@ -517,4 +626,69 @@ public class PackageWatchdogTest { return mName; } } + + private static class TestController extends ExplicitHealthCheckController { + TestController() { + super(null /* controller */); + } + + private boolean mIsEnabled; + private List<String> mSupportedPackages = new ArrayList<>(); + private List<String> mRequestedPackages = new ArrayList<>(); + private Runnable mStateChangedRunnable; + private Consumer<String> mPassedConsumer; + + @Override + public void request(String packageName) throws RemoteException { + if (!mRequestedPackages.contains(packageName)) { + mRequestedPackages.add(packageName); + } + } + + @Override + public void cancel(String packageName) throws RemoteException { + mRequestedPackages.remove(packageName); + } + + @Override + public void getSupportedPackages(Consumer<List<String>> consumer) throws RemoteException { + consumer.accept(mIsEnabled ? mSupportedPackages : Collections.emptyList()); + } + + @Override + public void getRequestedPackages(Consumer<List<String>> consumer) throws RemoteException { + // Pass copy to prevent ConcurrentModificationException during test + consumer.accept( + mIsEnabled ? new ArrayList<>(mRequestedPackages) : Collections.emptyList()); + } + + @Override + public void setEnabled(boolean enabled) { + mIsEnabled = enabled; + mStateChangedRunnable.run(); + } + + @Override + public void setCallbacks(Runnable stateChangedRunnable, Consumer<String> passedConsumer) { + mStateChangedRunnable = stateChangedRunnable; + mPassedConsumer = passedConsumer; + } + + public void setSupportedPackages(List<String> packages) { + mSupportedPackages.clear(); + mSupportedPackages.addAll(packages); + } + + public void setPackagePassed(String packageName) { + mPassedConsumer.accept(packageName); + } + + public List<String> getRequestedPackages() { + if (mIsEnabled) { + return mRequestedPackages; + } else { + return Collections.emptyList(); + } + } + } } diff --git a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTest.java b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTest.java index 834743d7ffed..d41a5d68912e 100644 --- a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTest.java +++ b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTest.java @@ -108,10 +108,6 @@ public class RollbackTest { } // The app should not be available for rollback. - // TODO: See if there is a way to remove this race condition - // between when the app is uninstalled and when the previously - // available rollback, if any, is removed. - Thread.sleep(1000); assertNull(getUniqueRollbackInfoForPackage(rm.getAvailableRollbacks(), TEST_APP_A)); // There should be no recently committed rollbacks for this package. @@ -127,10 +123,6 @@ public class RollbackTest { assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_A)); // The app should now be available for rollback. - // TODO: See if there is a way to remove this race condition - // between when the app is installed and when the rollback - // is made available. - Thread.sleep(1000); RollbackInfo rollback = getUniqueRollbackInfoForPackage( rm.getAvailableRollbacks(), TEST_APP_A); assertRollbackInfoEquals(TEST_APP_A, 2, 1, rollback); @@ -187,11 +179,6 @@ public class RollbackTest { assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_B)); // Both test apps should now be available for rollback. - // TODO: See if there is a way to remove this race condition - // between when the app is installed and when the rollback - // is made available. - Thread.sleep(1000); - RollbackInfo rollbackA = getUniqueRollbackInfoForPackage( rm.getAvailableRollbacks(), TEST_APP_A); assertRollbackInfoEquals(TEST_APP_A, 2, 1, rollbackA); @@ -246,11 +233,6 @@ public class RollbackTest { assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_B)); // The app should now be available for rollback. - // TODO: See if there is a way to remove this race condition - // between when the app is installed and when the rollback - // is made available. - Thread.sleep(1000); - RollbackInfo rollbackA = getUniqueRollbackInfoForPackage( rm.getAvailableRollbacks(), TEST_APP_A); assertRollbackInfoForAandB(rollbackA); @@ -297,10 +279,6 @@ public class RollbackTest { assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_A)); // The app should now be available for rollback. - // TODO: See if there is a way to remove this race condition - // between when the app is installed and when the rollback - // is made available. - Thread.sleep(1000); RollbackInfo rollback = getUniqueRollbackInfoForPackage( rm.getAvailableRollbacks(), TEST_APP_A); @@ -481,10 +459,6 @@ public class RollbackTest { assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_A)); // The app should now be available for rollback. - // TODO: See if there is a way to remove this race condition - // between when the app is installed and when the rollback - // is made available. - Thread.sleep(1000); RollbackInfo rollback = getUniqueRollbackInfoForPackage( rm.getAvailableRollbacks(), TEST_APP_A); assertRollbackInfoEquals(TEST_APP_A, 2, 1, rollback); @@ -610,10 +584,6 @@ public class RollbackTest { // Both test apps should now be available for rollback, and the // RollbackInfo returned for the rollbacks should be correct. - // TODO: See if there is a way to remove this race condition - // between when the app is installed and when the rollback - // is made available. - Thread.sleep(1000); RollbackInfo rollbackA = getUniqueRollbackInfoForPackage( rm.getAvailableRollbacks(), TEST_APP_A); assertRollbackInfoEquals(TEST_APP_A, 2, 1, rollbackA); @@ -709,11 +679,6 @@ public class RollbackTest { // been enabled. assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_A)); - // TODO: See if there is a way to remove this race condition - // between when the app is installed and when the rollback - // would be made available. - Thread.sleep(1000); - RollbackTestUtils.adoptShellPermissionIdentity( Manifest.permission.TEST_MANAGE_ROLLBACKS); RollbackManager rm = RollbackTestUtils.getRollbackManager(); @@ -745,11 +710,6 @@ public class RollbackTest { // been enabled because the test app is not a module. assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_A)); - // TODO: See if there is a way to remove this race condition - // between when the app is installed and when the rollback - // would be made available. - Thread.sleep(1000); - RollbackManager rm = RollbackTestUtils.getRollbackManager(); assertNull(getUniqueRollbackInfoForPackage(rm.getAvailableRollbacks(), TEST_APP_A)); } finally { @@ -844,10 +804,6 @@ public class RollbackTest { // Both test apps should now be available for rollback, and the // targetPackage returned for rollback should be correct. - // TODO: See if there is a way to remove this race condition - // between when the app is installed and when the rollback - // is made available. - Thread.sleep(1000); RollbackInfo rollbackA = getUniqueRollbackInfoForPackage( rm.getAvailableRollbacks(), TEST_APP_A); assertRollbackInfoEquals(TEST_APP_A, 2, 1, rollbackA); diff --git a/tests/net/java/android/net/IpPrefixTest.java b/tests/net/java/android/net/IpPrefixTest.java index 3cc0e368d381..abf019afed44 100644 --- a/tests/net/java/android/net/IpPrefixTest.java +++ b/tests/net/java/android/net/IpPrefixTest.java @@ -231,7 +231,6 @@ public class IpPrefixTest { assertFalse(p.contains(Address("2001:db8:f00::ace:d00e"))); assertFalse(p.contains(Address("2001:db8:f00::bad:d00d"))); assertFalse(p.contains(Address("2001:4868:4860::8888"))); - assertFalse(p.contains((InetAddress)null)); assertFalse(p.contains(Address("8.8.8.8"))); p = new IpPrefix("192.0.2.0/23"); diff --git a/tests/net/java/android/net/ipmemorystore/ParcelableTests.java b/tests/net/java/android/net/ipmemorystore/ParcelableTests.java index 76cccc95742d..1a3ea6096c82 100644 --- a/tests/net/java/android/net/ipmemorystore/ParcelableTests.java +++ b/tests/net/java/android/net/ipmemorystore/ParcelableTests.java @@ -44,6 +44,8 @@ public class ParcelableTests { assertEquals(in, new NetworkAttributes(parcelingRoundTrip(in.toParcelable()))); builder.setAssignedV4Address((Inet4Address) Inet4Address.getByName("1.2.3.4")); + // lease will expire in two hours + builder.setAssignedV4AddressExpiry(System.currentTimeMillis() + 7_200_000); // groupHint stays null this time around builder.setDnsAddresses(Collections.emptyList()); builder.setMtu(18); @@ -51,6 +53,7 @@ public class ParcelableTests { assertEquals(in, new NetworkAttributes(parcelingRoundTrip(in.toParcelable()))); builder.setAssignedV4Address((Inet4Address) Inet4Address.getByName("6.7.8.9")); + builder.setAssignedV4AddressExpiry(System.currentTimeMillis() + 3_600_000); builder.setGroupHint("groupHint"); builder.setDnsAddresses(Arrays.asList( InetAddress.getByName("ACA1:652B:0911:DE8F:1200:115E:913B:AA2A"), @@ -66,7 +69,7 @@ public class ParcelableTests { // Verify that this test does not miss any new field added later. // If any field is added to NetworkAttributes it must be tested here for parceling // roundtrip. - assertEquals(4, Arrays.stream(NetworkAttributes.class.getDeclaredFields()) + assertEquals(5, Arrays.stream(NetworkAttributes.class.getDeclaredFields()) .filter(f -> !Modifier.isStatic(f.getModifiers())).count()); } diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java index b35de59d7fcc..44380cce1c77 100644 --- a/tests/net/java/com/android/server/ConnectivityServiceTest.java +++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java @@ -104,6 +104,7 @@ import android.net.ConnectivityManager.PacketKeepalive; import android.net.ConnectivityManager.PacketKeepaliveCallback; import android.net.ConnectivityManager.TooManyRequestsException; import android.net.ConnectivityThread; +import android.net.IDnsResolver; import android.net.INetd; import android.net.INetworkMonitor; import android.net.INetworkMonitorCallbacks; @@ -240,6 +241,7 @@ public class ConnectivityServiceTest { private static final String CLAT_PREFIX = "v4-"; private static final String MOBILE_IFNAME = "test_rmnet_data0"; private static final String WIFI_IFNAME = "test_wlan0"; + private static final String[] EMPTY_STRING_ARRAY = new String[0]; private MockContext mServiceContext; private WrappedConnectivityService mService; @@ -256,6 +258,7 @@ public class ConnectivityServiceTest { @Mock INetworkManagementService mNetworkManagementService; @Mock INetworkStatsService mStatsService; @Mock INetworkPolicyManager mNpm; + @Mock IDnsResolver mMockDnsResolver; @Mock INetd mMockNetd; @Mock NetworkStackClient mNetworkStack; @@ -496,7 +499,7 @@ public class ConnectivityServiceTest { }; try { - doAnswer(validateAnswer).when(mNetworkMonitor).notifyNetworkConnected(); + doAnswer(validateAnswer).when(mNetworkMonitor).notifyNetworkConnected(any(), any()); doAnswer(validateAnswer).when(mNetworkMonitor).forceReevaluation(anyInt()); } catch (RemoteException e) { fail(e.getMessage()); @@ -1053,8 +1056,8 @@ public class ConnectivityServiceTest { public WrappedConnectivityService(Context context, INetworkManagementService netManager, INetworkStatsService statsService, INetworkPolicyManager policyManager, - IpConnectivityLog log, INetd netd) { - super(context, netManager, statsService, policyManager, log); + IpConnectivityLog log, INetd netd, IDnsResolver dnsResolver) { + super(context, netManager, statsService, policyManager, dnsResolver, log); mNetd = netd; mLingerDelayMs = TEST_LINGER_DELAY_MS; } @@ -1218,7 +1221,8 @@ public class ConnectivityServiceTest { mStatsService, mNpm, mock(IpConnectivityLog.class), - mMockNetd); + mMockNetd, + mMockDnsResolver); final ArgumentCaptor<INetworkPolicyListener> policyListenerCaptor = ArgumentCaptor.forClass(INetworkPolicyListener.class); @@ -3043,6 +3047,47 @@ public class ConnectivityServiceTest { } @Test + public void testInvalidSignalStrength() { + NetworkRequest r = new NetworkRequest.Builder() + .addCapability(NET_CAPABILITY_INTERNET) + .addTransportType(TRANSPORT_WIFI) + .setSignalStrength(-75) + .build(); + // Registering a NetworkCallback with signal strength but w/o NETWORK_SIGNAL_STRENGTH_WAKEUP + // permission should get SecurityException. + try { + mCm.registerNetworkCallback(r, new NetworkCallback()); + fail("Expected SecurityException filing a callback with signal strength"); + } catch (SecurityException expected) { + // expected + } + + try { + mCm.registerNetworkCallback(r, PendingIntent.getService( + mServiceContext, 0, new Intent(), 0)); + fail("Expected SecurityException filing a callback with signal strength"); + } catch (SecurityException expected) { + // expected + } + + // Requesting a Network with signal strength should get IllegalArgumentException. + try { + mCm.requestNetwork(r, new NetworkCallback()); + fail("Expected IllegalArgumentException filing a request with signal strength"); + } catch (IllegalArgumentException expected) { + // expected + } + + try { + mCm.requestNetwork(r, PendingIntent.getService( + mServiceContext, 0, new Intent(), 0)); + fail("Expected IllegalArgumentException filing a request with signal strength"); + } catch (IllegalArgumentException expected) { + // expected + } + } + + @Test public void testRegisterDefaultNetworkCallback() throws Exception { final TestNetworkCallback defaultNetworkCallback = new TestNetworkCallback(); mCm.registerDefaultNetworkCallback(defaultNetworkCallback); @@ -4777,14 +4822,14 @@ public class ConnectivityServiceTest { ArgumentCaptor<String[]> tlsServers = ArgumentCaptor.forClass(String[].class); // Clear any interactions that occur as a result of CS starting up. - reset(mNetworkManagementService); + reset(mMockDnsResolver); - final String[] EMPTY_STRING_ARRAY = new String[0]; mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR); waitForIdle(); - verify(mNetworkManagementService, never()).setDnsConfigurationForNetwork( - anyInt(), eq(EMPTY_STRING_ARRAY), any(), any(), eq(""), eq(EMPTY_STRING_ARRAY)); - verifyNoMoreInteractions(mNetworkManagementService); + verify(mMockDnsResolver, never()).setResolverConfiguration( + anyInt(), eq(EMPTY_STRING_ARRAY), any(), any(), eq(""), + eq(EMPTY_STRING_ARRAY), eq(EMPTY_STRING_ARRAY)); + verifyNoMoreInteractions(mMockDnsResolver); final LinkProperties cellLp = new LinkProperties(); cellLp.setInterfaceName(MOBILE_IFNAME); @@ -4801,28 +4846,29 @@ public class ConnectivityServiceTest { mCellNetworkAgent.connect(false); waitForIdle(); // CS tells netd about the empty DNS config for this network. - verify(mNetworkManagementService, atLeastOnce()).setDnsConfigurationForNetwork( - anyInt(), eq(EMPTY_STRING_ARRAY), any(), any(), eq(""), eq(EMPTY_STRING_ARRAY)); - reset(mNetworkManagementService); + verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration( + anyInt(), eq(EMPTY_STRING_ARRAY), any(), any(), eq(""), + eq(EMPTY_STRING_ARRAY), eq(EMPTY_STRING_ARRAY)); + reset(mMockDnsResolver); cellLp.addDnsServer(InetAddress.getByName("2001:db8::1")); mCellNetworkAgent.sendLinkProperties(cellLp); waitForIdle(); - verify(mNetworkManagementService, atLeastOnce()).setDnsConfigurationForNetwork( + verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration( anyInt(), mStringArrayCaptor.capture(), any(), any(), - eq(""), tlsServers.capture()); + eq(""), tlsServers.capture(), eq(EMPTY_STRING_ARRAY)); assertEquals(1, mStringArrayCaptor.getValue().length); assertTrue(ArrayUtils.contains(mStringArrayCaptor.getValue(), "2001:db8::1")); // Opportunistic mode. assertTrue(ArrayUtils.contains(tlsServers.getValue(), "2001:db8::1")); - reset(mNetworkManagementService); + reset(mMockDnsResolver); cellLp.addDnsServer(InetAddress.getByName("192.0.2.1")); mCellNetworkAgent.sendLinkProperties(cellLp); waitForIdle(); - verify(mNetworkManagementService, atLeastOnce()).setDnsConfigurationForNetwork( + verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration( anyInt(), mStringArrayCaptor.capture(), any(), any(), - eq(""), tlsServers.capture()); + eq(""), tlsServers.capture(), eq(EMPTY_STRING_ARRAY)); assertEquals(2, mStringArrayCaptor.getValue().length); assertTrue(ArrayUtils.containsAll(mStringArrayCaptor.getValue(), new String[]{"2001:db8::1", "192.0.2.1"})); @@ -4830,7 +4876,7 @@ public class ConnectivityServiceTest { assertEquals(2, tlsServers.getValue().length); assertTrue(ArrayUtils.containsAll(tlsServers.getValue(), new String[]{"2001:db8::1", "192.0.2.1"})); - reset(mNetworkManagementService); + reset(mMockDnsResolver); final String TLS_SPECIFIER = "tls.example.com"; final String TLS_SERVER6 = "2001:db8:53::53"; @@ -4840,22 +4886,21 @@ public class ConnectivityServiceTest { new PrivateDnsConfig(TLS_SPECIFIER, TLS_IPS).toParcel()); waitForIdle(); - verify(mNetworkManagementService, atLeastOnce()).setDnsConfigurationForNetwork( + verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration( anyInt(), mStringArrayCaptor.capture(), any(), any(), - eq(TLS_SPECIFIER), eq(TLS_SERVERS)); + eq(TLS_SPECIFIER), eq(TLS_SERVERS), eq(EMPTY_STRING_ARRAY)); assertEquals(2, mStringArrayCaptor.getValue().length); assertTrue(ArrayUtils.containsAll(mStringArrayCaptor.getValue(), new String[]{"2001:db8::1", "192.0.2.1"})); - reset(mNetworkManagementService); + reset(mMockDnsResolver); } @Test public void testPrivateDnsSettingsChange() throws Exception { - final String[] EMPTY_STRING_ARRAY = new String[0]; ArgumentCaptor<String[]> tlsServers = ArgumentCaptor.forClass(String[].class); // Clear any interactions that occur as a result of CS starting up. - reset(mNetworkManagementService); + reset(mMockDnsResolver); // The default on Android is opportunistic mode ("Automatic"). setPrivateDnsSettings(PRIVATE_DNS_MODE_OPPORTUNISTIC, "ignored.example.com"); @@ -4868,9 +4913,10 @@ public class ConnectivityServiceTest { mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR); waitForIdle(); // CS tells netd about the empty DNS config for this network. - verify(mNetworkManagementService, never()).setDnsConfigurationForNetwork( - anyInt(), eq(EMPTY_STRING_ARRAY), any(), any(), eq(""), eq(EMPTY_STRING_ARRAY)); - verifyNoMoreInteractions(mNetworkManagementService); + verify(mMockDnsResolver, never()).setResolverConfiguration( + anyInt(), eq(EMPTY_STRING_ARRAY), any(), any(), eq(""), + eq(EMPTY_STRING_ARRAY), eq(EMPTY_STRING_ARRAY)); + verifyNoMoreInteractions(mMockDnsResolver); final LinkProperties cellLp = new LinkProperties(); cellLp.setInterfaceName(MOBILE_IFNAME); @@ -4889,9 +4935,9 @@ public class ConnectivityServiceTest { mCellNetworkAgent.sendLinkProperties(cellLp); mCellNetworkAgent.connect(false); waitForIdle(); - verify(mNetworkManagementService, atLeastOnce()).setDnsConfigurationForNetwork( + verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration( anyInt(), mStringArrayCaptor.capture(), any(), any(), - eq(""), tlsServers.capture()); + eq(""), tlsServers.capture(), eq(EMPTY_STRING_ARRAY)); assertEquals(2, mStringArrayCaptor.getValue().length); assertTrue(ArrayUtils.containsAll(mStringArrayCaptor.getValue(), new String[]{"2001:db8::1", "192.0.2.1"})); @@ -4899,7 +4945,7 @@ public class ConnectivityServiceTest { assertEquals(2, tlsServers.getValue().length); assertTrue(ArrayUtils.containsAll(tlsServers.getValue(), new String[]{"2001:db8::1", "192.0.2.1"})); - reset(mNetworkManagementService); + reset(mMockDnsResolver); cellNetworkCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent); cellNetworkCallback.expectCallback(CallbackState.NETWORK_CAPABILITIES, mCellNetworkAgent); @@ -4911,26 +4957,26 @@ public class ConnectivityServiceTest { assertNull(((LinkProperties)cbi.arg).getPrivateDnsServerName()); setPrivateDnsSettings(PRIVATE_DNS_MODE_OFF, "ignored.example.com"); - verify(mNetworkManagementService, times(1)).setDnsConfigurationForNetwork( + verify(mMockDnsResolver, times(1)).setResolverConfiguration( anyInt(), mStringArrayCaptor.capture(), any(), any(), - eq(""), eq(EMPTY_STRING_ARRAY)); + eq(""), eq(EMPTY_STRING_ARRAY), eq(EMPTY_STRING_ARRAY)); assertEquals(2, mStringArrayCaptor.getValue().length); assertTrue(ArrayUtils.containsAll(mStringArrayCaptor.getValue(), new String[]{"2001:db8::1", "192.0.2.1"})); - reset(mNetworkManagementService); + reset(mMockDnsResolver); cellNetworkCallback.assertNoCallback(); setPrivateDnsSettings(PRIVATE_DNS_MODE_OPPORTUNISTIC, "ignored.example.com"); - verify(mNetworkManagementService, atLeastOnce()).setDnsConfigurationForNetwork( + verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration( anyInt(), mStringArrayCaptor.capture(), any(), any(), - eq(""), tlsServers.capture()); + eq(""), tlsServers.capture(), eq(EMPTY_STRING_ARRAY)); assertEquals(2, mStringArrayCaptor.getValue().length); assertTrue(ArrayUtils.containsAll(mStringArrayCaptor.getValue(), new String[]{"2001:db8::1", "192.0.2.1"})); assertEquals(2, tlsServers.getValue().length); assertTrue(ArrayUtils.containsAll(tlsServers.getValue(), new String[]{"2001:db8::1", "192.0.2.1"})); - reset(mNetworkManagementService); + reset(mMockDnsResolver); cellNetworkCallback.assertNoCallback(); setPrivateDnsSettings(PRIVATE_DNS_MODE_PROVIDER_HOSTNAME, "strict.example.com"); @@ -5761,6 +5807,7 @@ public class ConnectivityServiceTest { cellLp.addRoute(new RouteInfo((IpPrefix) null, myIpv6.getAddress(), MOBILE_IFNAME)); cellLp.addRoute(new RouteInfo(myIpv6, null, MOBILE_IFNAME)); reset(mNetworkManagementService); + reset(mMockDnsResolver); when(mNetworkManagementService.getInterfaceConfig(CLAT_PREFIX + MOBILE_IFNAME)) .thenReturn(getClatInterfaceConfig(myIpv4)); @@ -5768,7 +5815,7 @@ public class ConnectivityServiceTest { mCellNetworkAgent.sendLinkProperties(cellLp); mCellNetworkAgent.connect(true); networkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); - verify(mMockNetd, times(1)).resolverStartPrefix64Discovery(cellNetId); + verify(mMockDnsResolver, times(1)).startPrefix64Discovery(cellNetId); // Switching default network updates TCP buffer sizes. verifyTcpBufferSizeChange(ConnectivityService.DEFAULT_TCP_BUFFER_SIZES); @@ -5778,17 +5825,22 @@ public class ConnectivityServiceTest { cellLp.addLinkAddress(myIpv4); mCellNetworkAgent.sendLinkProperties(cellLp); networkCallback.expectCallback(CallbackState.LINK_PROPERTIES, mCellNetworkAgent); - verify(mMockNetd, times(1)).resolverStopPrefix64Discovery(cellNetId); + verify(mMockDnsResolver, times(1)).stopPrefix64Discovery(cellNetId); + verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration( + eq(cellNetId), eq(EMPTY_STRING_ARRAY), any(), any(), + eq(""), eq(EMPTY_STRING_ARRAY), eq(EMPTY_STRING_ARRAY)); verifyNoMoreInteractions(mMockNetd); + verifyNoMoreInteractions(mMockDnsResolver); reset(mMockNetd); + reset(mMockDnsResolver); // Remove IPv4 address. Expect prefix discovery to be started again. cellLp.removeLinkAddress(myIpv4); cellLp.removeRoute(new RouteInfo(myIpv4, null, MOBILE_IFNAME)); mCellNetworkAgent.sendLinkProperties(cellLp); networkCallback.expectCallback(CallbackState.LINK_PROPERTIES, mCellNetworkAgent); - verify(mMockNetd, times(1)).resolverStartPrefix64Discovery(cellNetId); + verify(mMockDnsResolver, times(1)).startPrefix64Discovery(cellNetId); // When NAT64 prefix discovery succeeds, LinkProperties are updated and clatd is started. Nat464Xlat clat = mService.getNat464Xlat(mCellNetworkAgent); @@ -5818,6 +5870,12 @@ public class ConnectivityServiceTest { assertNotEquals(stackedLpsAfterChange, Collections.EMPTY_LIST); assertEquals(makeClatLinkProperties(myIpv4), stackedLpsAfterChange.get(0)); + verify(mMockDnsResolver, times(1)).setResolverConfiguration( + eq(cellNetId), mStringArrayCaptor.capture(), any(), any(), + eq(""), eq(EMPTY_STRING_ARRAY), eq(EMPTY_STRING_ARRAY)); + assertEquals(1, mStringArrayCaptor.getValue().length); + assertTrue(ArrayUtils.contains(mStringArrayCaptor.getValue(), "8.8.8.8")); + // Add ipv4 address, expect that clatd and prefix discovery are stopped and stacked // linkproperties are cleaned up. cellLp.addLinkAddress(myIpv4); @@ -5825,7 +5883,7 @@ public class ConnectivityServiceTest { mCellNetworkAgent.sendLinkProperties(cellLp); networkCallback.expectCallback(CallbackState.LINK_PROPERTIES, mCellNetworkAgent); verify(mMockNetd, times(1)).clatdStop(MOBILE_IFNAME); - verify(mMockNetd, times(1)).resolverStopPrefix64Discovery(cellNetId); + verify(mMockDnsResolver, times(1)).stopPrefix64Discovery(cellNetId); // As soon as stop is called, the linkproperties lose the stacked interface. networkCallback.expectCallback(CallbackState.LINK_PROPERTIES, mCellNetworkAgent); @@ -5840,7 +5898,9 @@ public class ConnectivityServiceTest { networkCallback.assertNoCallback(); verifyNoMoreInteractions(mMockNetd); + verifyNoMoreInteractions(mMockDnsResolver); reset(mMockNetd); + reset(mMockDnsResolver); // Stopping prefix discovery causes netd to tell us that the NAT64 prefix is gone. mService.mNetdEventCallback.onNat64PrefixEvent(cellNetId, false /* added */, @@ -5854,7 +5914,7 @@ public class ConnectivityServiceTest { cellLp.removeDnsServer(InetAddress.getByName("8.8.8.8")); mCellNetworkAgent.sendLinkProperties(cellLp); networkCallback.expectCallback(CallbackState.LINK_PROPERTIES, mCellNetworkAgent); - verify(mMockNetd, times(1)).resolverStartPrefix64Discovery(cellNetId); + verify(mMockDnsResolver, times(1)).startPrefix64Discovery(cellNetId); mService.mNetdEventCallback.onNat64PrefixEvent(cellNetId, true /* added */, kNat64PrefixString, 96); networkCallback.expectCallback(CallbackState.LINK_PROPERTIES, mCellNetworkAgent); @@ -5937,6 +5997,7 @@ public class ConnectivityServiceTest { // Disconnect cell reset(mNetworkManagementService); + reset(mMockNetd); mCellNetworkAgent.disconnect(); networkCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent); // LOST callback is triggered earlier than removing idle timer. Broadcast should also be @@ -5944,8 +6005,9 @@ public class ConnectivityServiceTest { // unexpectedly before network being removed. waitForIdle(); verify(mNetworkManagementService, times(0)).removeIdleTimer(eq(MOBILE_IFNAME)); - verify(mNetworkManagementService, times(1)).removeNetwork( - eq(mCellNetworkAgent.getNetwork().netId)); + verify(mMockNetd, times(1)).networkDestroy(eq(mCellNetworkAgent.getNetwork().netId)); + verify(mMockDnsResolver, times(1)) + .clearResolverConfiguration(eq(mCellNetworkAgent.getNetwork().netId)); // Disconnect wifi ConditionVariable cv = waitForConnectivityBroadcasts(1); diff --git a/tests/net/java/com/android/server/connectivity/DnsManagerTest.java b/tests/net/java/com/android/server/connectivity/DnsManagerTest.java index 15ba43df832f..8fa0ab979a54 100644 --- a/tests/net/java/com/android/server/connectivity/DnsManagerTest.java +++ b/tests/net/java/com/android/server/connectivity/DnsManagerTest.java @@ -29,13 +29,13 @@ import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.when; import android.content.Context; +import android.net.IDnsResolver; import android.net.IpPrefix; import android.net.LinkAddress; import android.net.LinkProperties; import android.net.Network; import android.net.RouteInfo; import android.net.shared.PrivateDnsConfig; -import android.os.INetworkManagementService; import android.provider.Settings; import android.test.mock.MockContentResolver; @@ -73,7 +73,7 @@ public class DnsManagerTest { MockContentResolver mContentResolver; @Mock Context mCtx; - @Mock INetworkManagementService mNMService; + @Mock IDnsResolver mMockDnsResolver; @Mock MockableSystemProperties mSystemProperties; @Before @@ -83,7 +83,7 @@ public class DnsManagerTest { mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider()); when(mCtx.getContentResolver()).thenReturn(mContentResolver); - mDnsManager = new DnsManager(mCtx, mNMService, mSystemProperties); + mDnsManager = new DnsManager(mCtx, mMockDnsResolver, mSystemProperties); // Clear the private DNS settings Settings.Global.putString(mContentResolver, PRIVATE_DNS_DEFAULT_MODE, ""); diff --git a/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java b/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java index 6de4aa1be1ea..142769f61335 100644 --- a/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java +++ b/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java @@ -32,6 +32,7 @@ import android.app.PendingIntent; import android.content.Context; import android.content.res.Resources; import android.net.ConnectivityManager; +import android.net.IDnsResolver; import android.net.INetd; import android.net.Network; import android.net.NetworkCapabilities; @@ -69,6 +70,7 @@ public class LingerMonitorTest { LingerMonitor mMonitor; @Mock ConnectivityService mConnService; + @Mock IDnsResolver mDnsResolver; @Mock INetd mNetd; @Mock INetworkManagementService mNMS; @Mock Context mCtx; @@ -353,7 +355,7 @@ public class LingerMonitorTest { caps.addCapability(0); caps.addTransportType(transport); NetworkAgentInfo nai = new NetworkAgentInfo(null, null, new Network(netId), info, null, - caps, 50, mCtx, null, mMisc, mConnService, mNetd, mNMS, + caps, 50, mCtx, null, mMisc, mConnService, mNetd, mDnsResolver, mNMS, NetworkFactory.SerialNumber.NONE); nai.everValidated = true; return nai; diff --git a/tests/net/java/com/android/server/connectivity/Nat464XlatTest.java b/tests/net/java/com/android/server/connectivity/Nat464XlatTest.java index cc09fb7ba66f..b709af1a02f1 100644 --- a/tests/net/java/com/android/server/connectivity/Nat464XlatTest.java +++ b/tests/net/java/com/android/server/connectivity/Nat464XlatTest.java @@ -27,6 +27,7 @@ import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; import android.net.ConnectivityManager; +import android.net.IDnsResolver; import android.net.INetd; import android.net.InterfaceConfiguration; import android.net.IpPrefix; @@ -63,6 +64,7 @@ public class Nat464XlatTest { @Mock ConnectivityService mConnectivity; @Mock NetworkMisc mMisc; + @Mock IDnsResolver mDnsResolver; @Mock INetd mNetd; @Mock INetworkManagementService mNms; @Mock InterfaceConfiguration mConfig; @@ -72,7 +74,7 @@ public class Nat464XlatTest { Handler mHandler; Nat464Xlat makeNat464Xlat() { - return new Nat464Xlat(mNai, mNetd, mNms) { + return new Nat464Xlat(mNai, mNetd, mDnsResolver, mNms) { @Override protected int getNetId() { return NETID; } @@ -205,7 +207,7 @@ public class Nat464XlatTest { verify(mNms).unregisterObserver(eq(nat)); assertTrue(c.getValue().getStackedLinks().isEmpty()); assertFalse(c.getValue().getAllInterfaceNames().contains(STACKED_IFACE)); - verify(mNetd).resolverStopPrefix64Discovery(eq(NETID)); + verify(mDnsResolver).stopPrefix64Discovery(eq(NETID)); assertIdle(nat); // Stacked interface removed notification arrives and is ignored. @@ -331,7 +333,7 @@ public class Nat464XlatTest { verify(mNetd).clatdStop(eq(BASE_IFACE)); verify(mConnectivity, times(2)).handleUpdateLinkProperties(eq(mNai), c.capture()); verify(mNms).unregisterObserver(eq(nat)); - verify(mNetd).resolverStopPrefix64Discovery(eq(NETID)); + verify(mDnsResolver).stopPrefix64Discovery(eq(NETID)); assertTrue(c.getValue().getStackedLinks().isEmpty()); assertFalse(c.getValue().getAllInterfaceNames().contains(STACKED_IFACE)); assertIdle(nat); @@ -358,7 +360,7 @@ public class Nat464XlatTest { verify(mNetd).clatdStop(eq(BASE_IFACE)); verify(mNms).unregisterObserver(eq(nat)); - verify(mNetd).resolverStopPrefix64Discovery(eq(NETID)); + verify(mDnsResolver).stopPrefix64Discovery(eq(NETID)); assertIdle(nat); // In-flight interface up notification arrives: no-op @@ -390,7 +392,7 @@ public class Nat464XlatTest { verify(mNetd).clatdStop(eq(BASE_IFACE)); verify(mNms).unregisterObserver(eq(nat)); - verify(mNetd).resolverStopPrefix64Discovery(eq(NETID)); + verify(mDnsResolver).stopPrefix64Discovery(eq(NETID)); assertIdle(nat); verifyNoMoreInteractions(mNetd, mNms, mConnectivity); diff --git a/tests/net/java/com/android/server/connectivity/tethering/EntitlementManagerTest.java b/tests/net/java/com/android/server/connectivity/tethering/EntitlementManagerTest.java index bac509802258..d28ab708f051 100644 --- a/tests/net/java/com/android/server/connectivity/tethering/EntitlementManagerTest.java +++ b/tests/net/java/com/android/server/connectivity/tethering/EntitlementManagerTest.java @@ -16,6 +16,7 @@ package com.android.server.connectivity.tethering; +import static android.net.ConnectivityManager.TETHERING_BLUETOOTH; import static android.net.ConnectivityManager.TETHERING_USB; import static android.net.ConnectivityManager.TETHERING_WIFI; import static android.net.ConnectivityManager.TETHER_ERROR_ENTITLEMENT_UNKONWN; @@ -30,6 +31,8 @@ import static org.junit.Assert.fail; import static org.mockito.Matchers.anyBoolean; import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.content.ContentResolver; @@ -72,12 +75,14 @@ public final class EntitlementManagerTest { private static final int EVENT_EM_UPDATE = 1; private static final String[] PROVISIONING_APP_NAME = {"some", "app"}; + private static final String PROVISIONING_NO_UI_APP_NAME = "no_ui_app"; @Mock private CarrierConfigManager mCarrierConfigManager; @Mock private Context mContext; @Mock private MockableSystemProperties mSystemProperties; @Mock private Resources mResources; @Mock private SharedLog mLog; + @Mock private EntitlementManager.OnUiEntitlementFailedListener mEntitlementFailedListener; // Like so many Android system APIs, these cannot be mocked because it is marked final. // We have to use the real versions. @@ -107,18 +112,31 @@ public final class EntitlementManagerTest { public class WrappedEntitlementManager extends EntitlementManager { public int fakeEntitlementResult = TETHER_ERROR_ENTITLEMENT_UNKONWN; - public boolean everRunUiEntitlement = false; + public int uiProvisionCount = 0; + public int silentProvisionCount = 0; public WrappedEntitlementManager(Context ctx, StateMachine target, - SharedLog log, MockableSystemProperties systemProperties) { - super(ctx, target, log, systemProperties); + SharedLog log, int what, MockableSystemProperties systemProperties) { + super(ctx, target, log, what, systemProperties); + } + + public void reset() { + fakeEntitlementResult = TETHER_ERROR_ENTITLEMENT_UNKONWN; + uiProvisionCount = 0; + silentProvisionCount = 0; } @Override protected void runUiTetherProvisioning(int type, ResultReceiver receiver) { - everRunUiEntitlement = true; + uiProvisionCount++; receiver.send(fakeEntitlementResult, null); } + + @Override + protected void runSilentTetherProvisioning(int type) { + silentProvisionCount++; + addDownstreamMapping(type, fakeEntitlementResult); + } } @Before @@ -141,7 +159,9 @@ public final class EntitlementManagerTest { mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider()); mMockContext = new MockContext(mContext); mSM = new TestStateMachine(); - mEnMgr = new WrappedEntitlementManager(mMockContext, mSM, mLog, mSystemProperties); + mEnMgr = new WrappedEntitlementManager(mMockContext, mSM, mLog, EVENT_EM_UPDATE, + mSystemProperties); + mEnMgr.setOnUiEntitlementFailedListener(mEntitlementFailedListener); mEnMgr.updateConfiguration( new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID)); } @@ -158,7 +178,9 @@ public final class EntitlementManagerTest { // Produce some acceptable looking provision app setting if requested. when(mResources.getStringArray(R.array.config_mobile_hotspot_provision_app)) .thenReturn(PROVISIONING_APP_NAME); - // Don't disable tethering provisioning unless requested. + when(mResources.getString(R.string.config_mobile_hotspot_provision_app_no_ui)) + .thenReturn(PROVISIONING_NO_UI_APP_NAME); + // Don't disable tethering provisioning unless requested. when(mSystemProperties.getBoolean(eq(EntitlementManager.DISABLE_PROVISIONING_SYSPROP_KEY), anyBoolean())).thenReturn(false); // Act like the CarrierConfigManager is present and ready unless told otherwise. @@ -229,7 +251,6 @@ public final class EntitlementManagerTest { final CountDownLatch mCallbacklatch = new CountDownLatch(1); // 1. Entitlement check is not required. mEnMgr.fakeEntitlementResult = TETHER_ERROR_NO_ERROR; - mEnMgr.everRunUiEntitlement = false; ResultReceiver receiver = new ResultReceiver(null) { @Override protected void onReceiveResult(int resultCode, Bundle resultData) { @@ -238,14 +259,15 @@ public final class EntitlementManagerTest { } }; mEnMgr.getLatestTetheringEntitlementResult(TETHERING_WIFI, receiver, true); + mLooper.dispatchAll(); callbackTimeoutHelper(mCallbacklatch); - assertFalse(mEnMgr.everRunUiEntitlement); + assertEquals(0, mEnMgr.uiProvisionCount); + mEnMgr.reset(); setupForRequiredProvisioning(); mEnMgr.updateConfiguration(new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID)); // 2. No cache value and don't need to run entitlement check. - mEnMgr.everRunUiEntitlement = false; receiver = new ResultReceiver(null) { @Override protected void onReceiveResult(int resultCode, Bundle resultData) { @@ -254,11 +276,12 @@ public final class EntitlementManagerTest { } }; mEnMgr.getLatestTetheringEntitlementResult(TETHERING_WIFI, receiver, false); + mLooper.dispatchAll(); callbackTimeoutHelper(mCallbacklatch); - assertFalse(mEnMgr.everRunUiEntitlement); + assertEquals(0, mEnMgr.uiProvisionCount); + mEnMgr.reset(); // 3. No cache value and ui entitlement check is needed. mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISION_FAILED; - mEnMgr.everRunUiEntitlement = false; receiver = new ResultReceiver(null) { @Override protected void onReceiveResult(int resultCode, Bundle resultData) { @@ -269,10 +292,10 @@ public final class EntitlementManagerTest { mEnMgr.getLatestTetheringEntitlementResult(TETHERING_WIFI, receiver, true); mLooper.dispatchAll(); callbackTimeoutHelper(mCallbacklatch); - assertTrue(mEnMgr.everRunUiEntitlement); + assertEquals(1, mEnMgr.uiProvisionCount); + mEnMgr.reset(); // 4. Cache value is TETHER_ERROR_PROVISION_FAILED and don't need to run entitlement check. mEnMgr.fakeEntitlementResult = TETHER_ERROR_NO_ERROR; - mEnMgr.everRunUiEntitlement = false; receiver = new ResultReceiver(null) { @Override protected void onReceiveResult(int resultCode, Bundle resultData) { @@ -281,11 +304,12 @@ public final class EntitlementManagerTest { } }; mEnMgr.getLatestTetheringEntitlementResult(TETHERING_WIFI, receiver, false); + mLooper.dispatchAll(); callbackTimeoutHelper(mCallbacklatch); - assertFalse(mEnMgr.everRunUiEntitlement); + assertEquals(0, mEnMgr.uiProvisionCount); + mEnMgr.reset(); // 5. Cache value is TETHER_ERROR_PROVISION_FAILED and ui entitlement check is needed. mEnMgr.fakeEntitlementResult = TETHER_ERROR_NO_ERROR; - mEnMgr.everRunUiEntitlement = false; receiver = new ResultReceiver(null) { @Override protected void onReceiveResult(int resultCode, Bundle resultData) { @@ -296,10 +320,10 @@ public final class EntitlementManagerTest { mEnMgr.getLatestTetheringEntitlementResult(TETHERING_WIFI, receiver, true); mLooper.dispatchAll(); callbackTimeoutHelper(mCallbacklatch); - assertTrue(mEnMgr.everRunUiEntitlement); + assertEquals(1, mEnMgr.uiProvisionCount); + mEnMgr.reset(); // 6. Cache value is TETHER_ERROR_NO_ERROR. mEnMgr.fakeEntitlementResult = TETHER_ERROR_NO_ERROR; - mEnMgr.everRunUiEntitlement = false; receiver = new ResultReceiver(null) { @Override protected void onReceiveResult(int resultCode, Bundle resultData) { @@ -308,10 +332,11 @@ public final class EntitlementManagerTest { } }; mEnMgr.getLatestTetheringEntitlementResult(TETHERING_WIFI, receiver, true); + mLooper.dispatchAll(); callbackTimeoutHelper(mCallbacklatch); - assertFalse(mEnMgr.everRunUiEntitlement); + assertEquals(0, mEnMgr.uiProvisionCount); + mEnMgr.reset(); // 7. Test get value for other downstream type. - mEnMgr.everRunUiEntitlement = false; receiver = new ResultReceiver(null) { @Override protected void onReceiveResult(int resultCode, Bundle resultData) { @@ -320,19 +345,152 @@ public final class EntitlementManagerTest { } }; mEnMgr.getLatestTetheringEntitlementResult(TETHERING_USB, receiver, false); + mLooper.dispatchAll(); callbackTimeoutHelper(mCallbacklatch); - assertFalse(mEnMgr.everRunUiEntitlement); + assertEquals(0, mEnMgr.uiProvisionCount); + mEnMgr.reset(); } void callbackTimeoutHelper(final CountDownLatch latch) throws Exception { if (!latch.await(1, TimeUnit.SECONDS)) { - fail("Timout, fail to recieve callback"); + fail("Timout, fail to receive callback"); } } + + @Test + public void verifyPermissionResult() { + setupForRequiredProvisioning(); + mEnMgr.notifyUpstream(true); + mEnMgr.updateConfiguration(new TetheringConfiguration(mMockContext, mLog, + INVALID_SUBSCRIPTION_ID)); + mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISION_FAILED; + mEnMgr.startProvisioningIfNeeded(TETHERING_WIFI, true); + mLooper.dispatchAll(); + assertFalse(mEnMgr.isCellularUpstreamPermitted()); + mEnMgr.stopProvisioningIfNeeded(TETHERING_WIFI); + mLooper.dispatchAll(); + mEnMgr.fakeEntitlementResult = TETHER_ERROR_NO_ERROR; + mEnMgr.startProvisioningIfNeeded(TETHERING_WIFI, true); + mLooper.dispatchAll(); + assertTrue(mEnMgr.isCellularUpstreamPermitted()); + } + + @Test + public void verifyPermissionIfAllNotApproved() { + setupForRequiredProvisioning(); + mEnMgr.notifyUpstream(true); + mEnMgr.updateConfiguration(new TetheringConfiguration(mMockContext, mLog, + INVALID_SUBSCRIPTION_ID)); + mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISION_FAILED; + mEnMgr.startProvisioningIfNeeded(TETHERING_WIFI, true); + mLooper.dispatchAll(); + assertFalse(mEnMgr.isCellularUpstreamPermitted()); + mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISION_FAILED; + mEnMgr.startProvisioningIfNeeded(TETHERING_USB, true); + mLooper.dispatchAll(); + assertFalse(mEnMgr.isCellularUpstreamPermitted()); + mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISION_FAILED; + mEnMgr.startProvisioningIfNeeded(TETHERING_BLUETOOTH, true); + mLooper.dispatchAll(); + assertFalse(mEnMgr.isCellularUpstreamPermitted()); + } + + @Test + public void verifyPermissionIfAnyApproved() { + setupForRequiredProvisioning(); + mEnMgr.notifyUpstream(true); + mEnMgr.updateConfiguration(new TetheringConfiguration(mMockContext, mLog, + INVALID_SUBSCRIPTION_ID)); + mEnMgr.fakeEntitlementResult = TETHER_ERROR_NO_ERROR; + mEnMgr.startProvisioningIfNeeded(TETHERING_WIFI, true); + mLooper.dispatchAll(); + assertTrue(mEnMgr.isCellularUpstreamPermitted()); + mLooper.dispatchAll(); + mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISION_FAILED; + mEnMgr.startProvisioningIfNeeded(TETHERING_USB, true); + mLooper.dispatchAll(); + assertTrue(mEnMgr.isCellularUpstreamPermitted()); + mEnMgr.stopProvisioningIfNeeded(TETHERING_WIFI); + mLooper.dispatchAll(); + assertFalse(mEnMgr.isCellularUpstreamPermitted()); + + } + + @Test + public void testRunTetherProvisioning() { + setupForRequiredProvisioning(); + mEnMgr.updateConfiguration(new TetheringConfiguration(mMockContext, mLog, + INVALID_SUBSCRIPTION_ID)); + // 1. start ui provisioning, upstream is mobile + mEnMgr.fakeEntitlementResult = TETHER_ERROR_NO_ERROR; + mEnMgr.notifyUpstream(true); + mLooper.dispatchAll(); + mEnMgr.startProvisioningIfNeeded(TETHERING_USB, true); + mLooper.dispatchAll(); + assertEquals(1, mEnMgr.uiProvisionCount); + assertEquals(0, mEnMgr.silentProvisionCount); + assertTrue(mEnMgr.isCellularUpstreamPermitted()); + mEnMgr.reset(); + // 2. start no-ui provisioning + mEnMgr.fakeEntitlementResult = TETHER_ERROR_NO_ERROR; + mEnMgr.startProvisioningIfNeeded(TETHERING_WIFI, false); + mLooper.dispatchAll(); + assertEquals(0, mEnMgr.uiProvisionCount); + assertEquals(1, mEnMgr.silentProvisionCount); + assertTrue(mEnMgr.isCellularUpstreamPermitted()); + mEnMgr.reset(); + // 3. tear down mobile, then start ui provisioning + mEnMgr.notifyUpstream(false); + mLooper.dispatchAll(); + mEnMgr.startProvisioningIfNeeded(TETHERING_BLUETOOTH, true); + mLooper.dispatchAll(); + assertEquals(0, mEnMgr.uiProvisionCount); + assertEquals(0, mEnMgr.silentProvisionCount); + mEnMgr.reset(); + // 4. switch upstream back to mobile + mEnMgr.fakeEntitlementResult = TETHER_ERROR_NO_ERROR; + mEnMgr.notifyUpstream(true); + mLooper.dispatchAll(); + assertEquals(1, mEnMgr.uiProvisionCount); + assertEquals(0, mEnMgr.silentProvisionCount); + assertTrue(mEnMgr.isCellularUpstreamPermitted()); + mEnMgr.reset(); + // 5. tear down mobile, then switch SIM + mEnMgr.notifyUpstream(false); + mLooper.dispatchAll(); + mEnMgr.reevaluateSimCardProvisioning(); + assertEquals(0, mEnMgr.uiProvisionCount); + assertEquals(0, mEnMgr.silentProvisionCount); + mEnMgr.reset(); + // 6. switch upstream back to mobile again + mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISION_FAILED; + mEnMgr.notifyUpstream(true); + mLooper.dispatchAll(); + assertEquals(0, mEnMgr.uiProvisionCount); + assertEquals(3, mEnMgr.silentProvisionCount); + mEnMgr.reset(); + } + + @Test + public void testCallStopTetheringWhenUiProvisioningFail() { + setupForRequiredProvisioning(); + mEnMgr.updateConfiguration(new TetheringConfiguration(mMockContext, mLog, + INVALID_SUBSCRIPTION_ID)); + verify(mEntitlementFailedListener, times(0)).onUiEntitlementFailed(TETHERING_WIFI); + mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISION_FAILED; + mEnMgr.notifyUpstream(true); + mLooper.dispatchAll(); + mEnMgr.startProvisioningIfNeeded(TETHERING_WIFI, true); + mLooper.dispatchAll(); + assertEquals(1, mEnMgr.uiProvisionCount); + verify(mEntitlementFailedListener, times(1)).onUiEntitlementFailed(TETHERING_WIFI); + } + + public class TestStateMachine extends StateMachine { public final ArrayList<Message> messages = new ArrayList<>(); - private final State mLoggingState = - new EntitlementManagerTest.TestStateMachine.LoggingState(); + private final State + mLoggingState = new EntitlementManagerTest.TestStateMachine.LoggingState(); class LoggingState extends State { @Override public void enter() { diff --git a/tests/net/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitorTest.java b/tests/net/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitorTest.java index 5a1f853e75a9..0d276cbd1b85 100644 --- a/tests/net/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitorTest.java +++ b/tests/net/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitorTest.java @@ -90,6 +90,7 @@ public class UpstreamNetworkMonitorTest { private static final NetworkRequest mDefaultRequest = new NetworkRequest.Builder().build(); @Mock private Context mContext; + @Mock private EntitlementManager mEntitleMgr; @Mock private IConnectivityManager mCS; @Mock private SharedLog mLog; @@ -103,6 +104,7 @@ public class UpstreamNetworkMonitorTest { reset(mCS); reset(mLog); when(mLog.forSubComponent(anyString())).thenReturn(mLog); + when(mEntitleMgr.isCellularUpstreamPermitted()).thenReturn(true); mCM = spy(new TestConnectivityManager(mContext, mCS)); mSM = new TestStateMachine(); @@ -138,7 +140,7 @@ public class UpstreamNetworkMonitorTest { @Test public void testDefaultNetworkIsTracked() throws Exception { assertTrue(mCM.hasNoCallbacks()); - mUNM.startTrackDefaultNetwork(mDefaultRequest); + mUNM.startTrackDefaultNetwork(mDefaultRequest, mEntitleMgr); mUNM.startObserveAllNetworks(); assertEquals(1, mCM.trackingDefault.size()); @@ -151,7 +153,7 @@ public class UpstreamNetworkMonitorTest { public void testListensForAllNetworks() throws Exception { assertTrue(mCM.listening.isEmpty()); - mUNM.startTrackDefaultNetwork(mDefaultRequest); + mUNM.startTrackDefaultNetwork(mDefaultRequest, mEntitleMgr); mUNM.startObserveAllNetworks(); assertFalse(mCM.listening.isEmpty()); assertTrue(mCM.isListeningForAll()); @@ -162,7 +164,7 @@ public class UpstreamNetworkMonitorTest { @Test public void testCallbacksRegistered() { - mUNM.startTrackDefaultNetwork(mDefaultRequest); + mUNM.startTrackDefaultNetwork(mDefaultRequest, mEntitleMgr); verify(mCM, times(1)).requestNetwork( eq(mDefaultRequest), any(NetworkCallback.class), any(Handler.class)); mUNM.startObserveAllNetworks(); @@ -285,7 +287,7 @@ public class UpstreamNetworkMonitorTest { final Collection<Integer> preferredTypes = new ArrayList<>(); preferredTypes.add(TYPE_WIFI); - mUNM.startTrackDefaultNetwork(mDefaultRequest); + mUNM.startTrackDefaultNetwork(mDefaultRequest, mEntitleMgr); mUNM.startObserveAllNetworks(); // There are no networks, so there is nothing to select. assertSatisfiesLegacyType(TYPE_NONE, mUNM.selectPreferredUpstreamType(preferredTypes)); @@ -319,6 +321,14 @@ public class UpstreamNetworkMonitorTest { NetworkRequest netReq = (NetworkRequest) mCM.requested.values().toArray()[0]; assertTrue(netReq.networkCapabilities.hasTransport(TRANSPORT_CELLULAR)); assertFalse(netReq.networkCapabilities.hasCapability(NET_CAPABILITY_DUN)); + // mobile is not permitted, we should not use HIPRI. + when(mEntitleMgr.isCellularUpstreamPermitted()).thenReturn(false); + assertSatisfiesLegacyType(TYPE_NONE, mUNM.selectPreferredUpstreamType(preferredTypes)); + assertEquals(0, mCM.requested.size()); + // mobile change back to permitted, HIRPI should come back + when(mEntitleMgr.isCellularUpstreamPermitted()).thenReturn(true); + assertSatisfiesLegacyType(TYPE_MOBILE_HIPRI, + mUNM.selectPreferredUpstreamType(preferredTypes)); wifiAgent.fakeConnect(); // WiFi is up, and we should prefer it over cell. @@ -347,11 +357,19 @@ public class UpstreamNetworkMonitorTest { netReq = (NetworkRequest) mCM.requested.values().toArray()[0]; assertTrue(netReq.networkCapabilities.hasTransport(TRANSPORT_CELLULAR)); assertTrue(netReq.networkCapabilities.hasCapability(NET_CAPABILITY_DUN)); + // mobile is not permitted, we should not use DUN. + when(mEntitleMgr.isCellularUpstreamPermitted()).thenReturn(false); + assertSatisfiesLegacyType(TYPE_NONE, mUNM.selectPreferredUpstreamType(preferredTypes)); + assertEquals(0, mCM.requested.size()); + // mobile change back to permitted, DUN should come back + when(mEntitleMgr.isCellularUpstreamPermitted()).thenReturn(true); + assertSatisfiesLegacyType(TYPE_MOBILE_DUN, + mUNM.selectPreferredUpstreamType(preferredTypes)); } @Test public void testGetCurrentPreferredUpstream() throws Exception { - mUNM.startTrackDefaultNetwork(mDefaultRequest); + mUNM.startTrackDefaultNetwork(mDefaultRequest, mEntitleMgr); mUNM.startObserveAllNetworks(); mUNM.updateMobileRequiresDun(false); @@ -361,37 +379,46 @@ public class UpstreamNetworkMonitorTest { mCM.makeDefaultNetwork(cellAgent); assertEquals(cellAgent.networkId, mUNM.getCurrentPreferredUpstream().network); - // [1] WiFi connects but not validated/promoted to default -> mobile selected. + // [1] Mobile connects but not permitted -> null selected + when(mEntitleMgr.isCellularUpstreamPermitted()).thenReturn(false); + assertEquals(null, mUNM.getCurrentPreferredUpstream()); + when(mEntitleMgr.isCellularUpstreamPermitted()).thenReturn(true); + + // [2] WiFi connects but not validated/promoted to default -> mobile selected. final TestNetworkAgent wifiAgent = new TestNetworkAgent(mCM, TRANSPORT_WIFI); wifiAgent.fakeConnect(); assertEquals(cellAgent.networkId, mUNM.getCurrentPreferredUpstream().network); - // [2] WiFi validates and is promoted to the default network -> WiFi selected. + // [3] WiFi validates and is promoted to the default network -> WiFi selected. mCM.makeDefaultNetwork(wifiAgent); assertEquals(wifiAgent.networkId, mUNM.getCurrentPreferredUpstream().network); - // [3] DUN required, no other changes -> WiFi still selected + // [4] DUN required, no other changes -> WiFi still selected mUNM.updateMobileRequiresDun(true); assertEquals(wifiAgent.networkId, mUNM.getCurrentPreferredUpstream().network); - // [4] WiFi no longer validated, mobile becomes default, DUN required -> null selected. + // [5] WiFi no longer validated, mobile becomes default, DUN required -> null selected. mCM.makeDefaultNetwork(cellAgent); assertEquals(null, mUNM.getCurrentPreferredUpstream()); // TODO: make sure that a DUN request has been filed. This is currently // triggered by code over in Tethering, but once that has been moved // into UNM we should test for this here. - // [5] DUN network arrives -> DUN selected + // [6] DUN network arrives -> DUN selected final TestNetworkAgent dunAgent = new TestNetworkAgent(mCM, TRANSPORT_CELLULAR); dunAgent.networkCapabilities.addCapability(NET_CAPABILITY_DUN); dunAgent.networkCapabilities.removeCapability(NET_CAPABILITY_INTERNET); dunAgent.fakeConnect(); assertEquals(dunAgent.networkId, mUNM.getCurrentPreferredUpstream().network); + + // [7] Mobile is not permitted -> null selected + when(mEntitleMgr.isCellularUpstreamPermitted()).thenReturn(false); + assertEquals(null, mUNM.getCurrentPreferredUpstream()); } @Test public void testLocalPrefixes() throws Exception { - mUNM.startTrackDefaultNetwork(mDefaultRequest); + mUNM.startTrackDefaultNetwork(mDefaultRequest, mEntitleMgr); mUNM.startObserveAllNetworks(); // [0] Test minimum set of local prefixes. @@ -492,6 +519,26 @@ public class UpstreamNetworkMonitorTest { assertTrue(local.isEmpty()); } + @Test + public void testSelectMobileWhenMobileIsNotDefault() { + final Collection<Integer> preferredTypes = new ArrayList<>(); + // Mobile has higher pirority than wifi. + preferredTypes.add(TYPE_MOBILE_HIPRI); + preferredTypes.add(TYPE_WIFI); + mUNM.startTrackDefaultNetwork(mDefaultRequest, mEntitleMgr); + mUNM.startObserveAllNetworks(); + // Setup wifi and make wifi as default network. + final TestNetworkAgent wifiAgent = new TestNetworkAgent(mCM, TRANSPORT_WIFI); + wifiAgent.fakeConnect(); + mCM.makeDefaultNetwork(wifiAgent); + // Setup mobile network. + final TestNetworkAgent cellAgent = new TestNetworkAgent(mCM, TRANSPORT_CELLULAR); + cellAgent.fakeConnect(); + + assertSatisfiesLegacyType(TYPE_MOBILE_HIPRI, + mUNM.selectPreferredUpstreamType(preferredTypes)); + verify(mEntitleMgr, times(1)).maybeRunProvisioning(); + } private void assertSatisfiesLegacyType(int legacyType, NetworkState ns) { if (legacyType == TYPE_NONE) { assertTrue(ns == null); diff --git a/tests/net/java/com/android/server/net/ipmemorystore/NetworkAttributesTest.java b/tests/net/java/com/android/server/net/ipmemorystore/NetworkAttributesTest.java index dc2018543050..fb84611cb662 100644 --- a/tests/net/java/com/android/server/net/ipmemorystore/NetworkAttributesTest.java +++ b/tests/net/java/com/android/server/net/ipmemorystore/NetworkAttributesTest.java @@ -57,6 +57,7 @@ public class NetworkAttributesTest { final NetworkAttributes na = new NetworkAttributes( (Inet4Address) Inet4Address.getByAddress(new byte[] {1, 2, 3, 4}), + System.currentTimeMillis() + 7_200_000, "some hint", Arrays.asList(Inet4Address.getByAddress(new byte[] {5, 6, 7, 8}), Inet4Address.getByAddress(new byte[] {9, 0, 1, 2})), diff --git a/tests/testables/src/android/testing/TestableContext.java b/tests/testables/src/android/testing/TestableContext.java index fff9635992d4..e2668bc4281f 100644 --- a/tests/testables/src/android/testing/TestableContext.java +++ b/tests/testables/src/android/testing/TestableContext.java @@ -296,13 +296,13 @@ public class TestableContext extends ContextWrapper implements TestRule { @Override public void registerComponentCallbacks(ComponentCallbacks callback) { if (mComponent != null) mComponent.getLeakInfo(callback).addAllocation(new Throwable()); - super.registerComponentCallbacks(callback); + getBaseContext().registerComponentCallbacks(callback); } @Override public void unregisterComponentCallbacks(ComponentCallbacks callback) { if (mComponent != null) mComponent.getLeakInfo(callback).clearAllocations(); - super.unregisterComponentCallbacks(callback); + getBaseContext().unregisterComponentCallbacks(callback); } public TestablePermissions getTestablePermissions() { diff --git a/tools/aapt2/ResourceParser_test.cpp b/tools/aapt2/ResourceParser_test.cpp index 53361414e9b8..857792192902 100644 --- a/tools/aapt2/ResourceParser_test.cpp +++ b/tools/aapt2/ResourceParser_test.cpp @@ -217,6 +217,29 @@ TEST_F(ResourceParserTest, ParseStyledStringWithWhitespace) { EXPECT_THAT(str->value->spans[1].last_char, Eq(13u)); } +TEST_F(ResourceParserTest, ParseStringTranslatableAttribute) { + // If there is no translate attribute the default is 'true' + EXPECT_TRUE(TestParse(R"(<string name="foo1">Translate</string>)")); + String* str = test::GetValue<String>(&table_, "string/foo1"); + ASSERT_THAT(str, NotNull()); + ASSERT_TRUE(str->IsTranslatable()); + + // Explicit 'true' translate attribute + EXPECT_TRUE(TestParse(R"(<string name="foo2" translatable="true">Translate</string>)")); + str = test::GetValue<String>(&table_, "string/foo2"); + ASSERT_THAT(str, NotNull()); + ASSERT_TRUE(str->IsTranslatable()); + + // Explicit 'false' translate attribute + EXPECT_TRUE(TestParse(R"(<string name="foo3" translatable="false">Do not translate</string>)")); + str = test::GetValue<String>(&table_, "string/foo3"); + ASSERT_THAT(str, NotNull()); + ASSERT_FALSE(str->IsTranslatable()); + + // Invalid value for the translate attribute, should be boolean ('true' or 'false') + EXPECT_FALSE(TestParse(R"(<string name="foo4" translatable="yes">Translate</string>)")); +} + TEST_F(ResourceParserTest, IgnoreXliffTagsOtherThanG) { std::string input = R"( <string name="foo" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> diff --git a/tools/aapt2/ResourceTable.cpp b/tools/aapt2/ResourceTable.cpp index 7c0619f33851..1773b5a8addf 100644 --- a/tools/aapt2/ResourceTable.cpp +++ b/tools/aapt2/ResourceTable.cpp @@ -357,37 +357,6 @@ bool ResourceTable::AddResourceWithId(const ResourceNameRef& name, const Resourc (validate_resources_ ? ResolveValueCollision : IgnoreCollision), diag); } -bool ResourceTable::AddFileReference(const ResourceNameRef& name, - const ConfigDescription& config, - const Source& source, - const StringPiece& path, - IDiagnostics* diag) { - return AddFileReferenceImpl(name, config, source, path, nullptr, - (validate_resources_ ? ResourceNameValidator : SkipNameValidator), - diag); -} - -bool ResourceTable::AddFileReferenceMangled(const ResourceNameRef& name, - const ConfigDescription& config, const Source& source, - const StringPiece& path, io::IFile* file, - IDiagnostics* diag) { - return AddFileReferenceImpl(name, config, source, path, file, - (validate_resources_ ? ResourceNameValidator : SkipNameValidator), - diag); -} - -bool ResourceTable::AddFileReferenceImpl(const ResourceNameRef& name, - const ConfigDescription& config, const Source& source, - const StringPiece& path, io::IFile* file, - NameValidator name_validator, IDiagnostics* diag) { - std::unique_ptr<FileReference> fileRef = - util::make_unique<FileReference>(string_pool.MakeRef(path)); - fileRef->SetSource(source); - fileRef->file = file; - return AddResourceImpl(name, ResourceId{}, config, StringPiece{}, std::move(fileRef), - name_validator, ResolveValueCollision, diag); -} - bool ResourceTable::AddResourceMangled(const ResourceNameRef& name, const ConfigDescription& config, const StringPiece& product, std::unique_ptr<Value> value, IDiagnostics* diag) { @@ -512,11 +481,6 @@ bool ResourceTable::SetVisibility(const ResourceNameRef& name, const Visibility& return SetVisibilityImpl(name, visibility, {}, ResourceNameValidator, diag); } -bool ResourceTable::SetVisibilityMangled(const ResourceNameRef& name, const Visibility& visibility, - IDiagnostics* diag) { - return SetVisibilityImpl(name, visibility, {}, SkipNameValidator, diag); -} - bool ResourceTable::SetVisibilityWithId(const ResourceNameRef& name, const Visibility& visibility, const ResourceId& res_id, IDiagnostics* diag) { return SetVisibilityImpl(name, visibility, res_id, ResourceNameValidator, diag); @@ -634,11 +598,6 @@ bool ResourceTable::SetOverlayable(const ResourceNameRef& name, const Overlayabl return SetOverlayableImpl(name, overlayable, ResourceNameValidator, diag); } -bool ResourceTable::SetOverlayableMangled(const ResourceNameRef& name, - const OverlayableItem& overlayable, IDiagnostics* diag) { - return SetOverlayableImpl(name, overlayable, SkipNameValidator, diag); -} - bool ResourceTable::SetOverlayableImpl(const ResourceNameRef& name, const OverlayableItem& overlayable, NameValidator name_validator, IDiagnostics *diag) { diff --git a/tools/aapt2/ResourceTable.h b/tools/aapt2/ResourceTable.h index 32dfd260e53c..7ed78975a01d 100644 --- a/tools/aapt2/ResourceTable.h +++ b/tools/aapt2/ResourceTable.h @@ -239,13 +239,6 @@ class ResourceTable { const android::StringPiece& product, std::unique_ptr<Value> value, IDiagnostics* diag); - bool AddFileReference(const ResourceNameRef& name, const android::ConfigDescription& config, - const Source& source, const android::StringPiece& path, IDiagnostics* diag); - - bool AddFileReferenceMangled(const ResourceNameRef& name, const android::ConfigDescription& config, - const Source& source, const android::StringPiece& path, - io::IFile* file, IDiagnostics* diag); - // Same as AddResource, but doesn't verify the validity of the name. This is used // when loading resources from an existing binary resource table that may have mangled names. bool AddResourceMangled(const ResourceNameRef& name, const android::ConfigDescription& config, @@ -260,8 +253,6 @@ class ResourceTable { bool GetValidateResources(); bool SetVisibility(const ResourceNameRef& name, const Visibility& visibility, IDiagnostics* diag); - bool SetVisibilityMangled(const ResourceNameRef& name, const Visibility& visibility, - IDiagnostics* diag); bool SetVisibilityWithId(const ResourceNameRef& name, const Visibility& visibility, const ResourceId& res_id, IDiagnostics* diag); bool SetVisibilityWithIdMangled(const ResourceNameRef& name, const Visibility& visibility, @@ -269,8 +260,6 @@ class ResourceTable { bool SetOverlayable(const ResourceNameRef& name, const OverlayableItem& overlayable, IDiagnostics *diag); - bool SetOverlayableMangled(const ResourceNameRef& name, const OverlayableItem& overlayable, - IDiagnostics* diag); bool SetAllowNew(const ResourceNameRef& name, const AllowNew& allow_new, IDiagnostics* diag); bool SetAllowNewMangled(const ResourceNameRef& name, const AllowNew& allow_new, @@ -333,10 +322,6 @@ class ResourceTable { NameValidator name_validator, const CollisionResolverFunc& conflict_resolver, IDiagnostics* diag); - bool AddFileReferenceImpl(const ResourceNameRef& name, const android::ConfigDescription& config, - const Source& source, const android::StringPiece& path, io::IFile* file, - NameValidator name_validator, IDiagnostics* diag); - bool SetVisibilityImpl(const ResourceNameRef& name, const Visibility& visibility, const ResourceId& res_id, NameValidator name_validator, IDiagnostics* diag); @@ -347,10 +332,6 @@ class ResourceTable { bool SetOverlayableImpl(const ResourceNameRef &name, const OverlayableItem& overlayable, NameValidator name_validator, IDiagnostics *diag); - bool SetSymbolStateImpl(const ResourceNameRef& name, const ResourceId& res_id, - const Visibility& symbol, NameValidator name_validator, - IDiagnostics* diag); - // Controls whether the table validates resource names and prevents duplicate resource names bool validate_resources_ = true; diff --git a/tools/aapt2/cmd/Compile.cpp b/tools/aapt2/cmd/Compile.cpp index 2ec1ab31a58c..9b81369fa9f0 100644 --- a/tools/aapt2/cmd/Compile.cpp +++ b/tools/aapt2/cmd/Compile.cpp @@ -143,6 +143,8 @@ static bool CompileTable(IAaptContext* context, const CompileOptions& options, const ResourcePathData& path_data, io::IFile* file, IArchiveWriter* writer, const std::string& output_path) { TRACE_CALL(); + // Filenames starting with "donottranslate" are not localizable + bool translatable_file = path_data.name.find("donottranslate") != 0; ResourceTable table; { auto fin = file->OpenInputStream(); @@ -157,9 +159,7 @@ static bool CompileTable(IAaptContext* context, const CompileOptions& options, ResourceParserOptions parser_options; parser_options.error_on_positional_arguments = !options.legacy_mode; - - // If the filename includes donottranslate, then the default translatable is false. - parser_options.translatable = path_data.name.find("donottranslate") == std::string::npos; + parser_options.translatable = translatable_file; // If visibility was forced, we need to use it when creating a new resource and also error if // we try to parse the <public>, <public-group>, <java-symbol> or <symbol> tags. @@ -172,7 +172,7 @@ static bool CompileTable(IAaptContext* context, const CompileOptions& options, } } - if (options.pseudolocalize) { + if (options.pseudolocalize && translatable_file) { // Generate pseudo-localized strings (en-XA and ar-XB). // These are created as weak symbols, and are only generated from default // configuration diff --git a/tools/aapt2/cmd/Compile_test.cpp b/tools/aapt2/cmd/Compile_test.cpp index c0c05cda35e7..5f637bd8d582 100644 --- a/tools/aapt2/cmd/Compile_test.cpp +++ b/tools/aapt2/cmd/Compile_test.cpp @@ -27,6 +27,8 @@ namespace aapt { +using CompilerTest = CommandTestFixture; + std::string BuildPath(std::vector<std::string> args) { std::string out; if (args.empty()) { @@ -51,7 +53,7 @@ int TestCompile(const std::string& path, const std::string& outDir, bool legacy, return CompileCommand(&diag).Execute(args, &std::cerr); } -TEST(CompilerTest, MultiplePeriods) { +TEST_F(CompilerTest, MultiplePeriods) { StdErrDiagnostics diag; std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build(); const std::string kResDir = BuildPath({android::base::Dirname(android::base::GetExecutablePath()), @@ -108,7 +110,7 @@ TEST(CompilerTest, MultiplePeriods) { ASSERT_EQ(::android::base::utf8::unlink(path5_out.c_str()), 0); } -TEST(CompilerTest, DirInput) { +TEST_F(CompilerTest, DirInput) { StdErrDiagnostics diag; std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build(); const std::string kResDir = BuildPath({android::base::Dirname(android::base::GetExecutablePath()), @@ -138,7 +140,7 @@ TEST(CompilerTest, DirInput) { ASSERT_EQ(::android::base::utf8::unlink(kOutputFlata.c_str()), 0); } -TEST(CompilerTest, ZipInput) { +TEST_F(CompilerTest, ZipInput) { StdErrDiagnostics diag; std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build(); const std::string kResZip = @@ -169,4 +171,86 @@ TEST(CompilerTest, ZipInput) { ASSERT_EQ(::android::base::utf8::unlink(kOutputFlata.c_str()), 0); } -} // namespace aapt
\ No newline at end of file +/* + * This tests the "protection" from pseudo-translation of + * non-translatable files (starting with 'donotranslate') + * and strings (with the translatable="false" attribute) + * + * We check 4 string files, 2 translatable, and 2 not (based on file name) + * Each file contains 2 strings, one translatable, one not (attribute based) + * Each of these files are compiled and linked into one .apk, then we load the + * strings from the apk and check if there are pseudo-translated strings. + */ + +// Using 000 and 111 because they are not changed by pseudo-translation, +// making our life easier. +constexpr static const char sTranslatableXmlContent[] = + "<?xml version=\"1.0\" encoding=\"utf-8\"?>" + "<resources>" + " <string name=\"normal\">000</string>" + " <string name=\"non_translatable\" translatable=\"false\">111</string>" + "</resources>"; + +static void AssertTranslations(CommandTestFixture *ctf, std::string file_name, + std::vector<std::string> expected) { + + StdErrDiagnostics diag; + + const std::string source_file = ctf->GetTestPath("/res/values/" + file_name + ".xml"); + const std::string compiled_files_dir = ctf->GetTestPath("/compiled_" + file_name); + const std::string out_apk = ctf->GetTestPath("/" + file_name + ".apk"); + + CHECK(ctf->WriteFile(source_file, sTranslatableXmlContent)); + CHECK(file::mkdirs(compiled_files_dir.data())); + + ASSERT_EQ(CompileCommand(&diag).Execute({ + source_file, + "-o", compiled_files_dir, + "-v", + "--pseudo-localize" + }, &std::cerr), 0); + + ASSERT_TRUE(ctf->Link({ + "--manifest", ctf->GetDefaultManifest(), + "-o", out_apk + }, compiled_files_dir, &diag)); + + std::unique_ptr<LoadedApk> apk = LoadedApk::LoadApkFromPath(out_apk, &diag); + + ResourceTable* table = apk->GetResourceTable(); + ASSERT_NE(table, nullptr); + table->string_pool.Sort(); + + const std::vector<std::unique_ptr<StringPool::Entry>>& pool_strings = + table->string_pool.strings(); + + // The actual / expected vectors have the same size + const size_t pool_size = pool_strings.size(); + ASSERT_EQ(pool_size, expected.size()); + + for (size_t i = 0; i < pool_size; i++) { + std::string actual = pool_strings[i]->value; + ASSERT_EQ(actual, expected[i]); + } +} + +TEST_F(CompilerTest, DoNotTranslateTest) { + // The first string (000) is translatable, the second is not + // ar-XB uses "\u200F\u202E...\u202C\u200F" + std::vector<std::string> expected_translatable = { + "000", "111", // default locale + "[000 one]", // en-XA + "\xE2\x80\x8F\xE2\x80\xAE" "000" "\xE2\x80\xAC\xE2\x80\x8F", // ar-XB + }; + AssertTranslations(this, "foo", expected_translatable); + AssertTranslations(this, "foo_donottranslate", expected_translatable); + + // No translatable strings because these are non-translatable files + std::vector<std::string> expected_not_translatable = { + "000", "111", // default locale + }; + AssertTranslations(this, "donottranslate", expected_not_translatable); + AssertTranslations(this, "donottranslate_foo", expected_not_translatable); +} + +} // namespace aapt 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/tools/hiddenapi/generate_hiddenapi_lists.py b/tools/hiddenapi/generate_hiddenapi_lists.py index 6781eba05534..c856cc36d6f6 100755 --- a/tools/hiddenapi/generate_hiddenapi_lists.py +++ b/tools/hiddenapi/generate_hiddenapi_lists.py @@ -21,6 +21,7 @@ from collections import defaultdict import os import sys import re +import functools # Names of flags recognized by the `hiddenapi` tool. FLAG_WHITELIST = "whitelist" @@ -58,6 +59,10 @@ ALL_FLAGS_SET = set(ALL_FLAGS) # script to skip any entries which do not exist any more. FLAG_IGNORE_CONFLICTS_SUFFIX = "-ignore-conflicts" +# Suffix used in command line args to express that all apis within a given set +# of packages should be assign the given flag. +FLAG_PACKAGES_SUFFIX = "-packages" + # Regex patterns of fields/methods used in serialization. These are # considered public API despite being hidden. SERIALIZATION_PATTERNS = [ @@ -91,12 +96,16 @@ def get_args(): for flag in ALL_FLAGS: ignore_conflicts_flag = flag + FLAG_IGNORE_CONFLICTS_SUFFIX + packages_flag = flag + FLAG_PACKAGES_SUFFIX parser.add_argument('--' + flag, dest=flag, nargs='*', default=[], metavar='TXT_FILE', help='lists of entries with flag "' + flag + '"') parser.add_argument('--' + ignore_conflicts_flag, dest=ignore_conflicts_flag, nargs='*', default=[], metavar='TXT_FILE', help='lists of entries with flag "' + flag + '". skip entry if missing or flag conflict.') + parser.add_argument('--' + packages_flag, dest=packages_flag, nargs='*', + default=[], metavar='TXT_FILE', + help='lists of packages to be added to ' + flag + ' list') return parser.parse_args() @@ -128,6 +137,19 @@ def write_lines(filename, lines): with open(filename, 'w') as f: f.writelines(lines) +def extract_package(signature): + """Extracts the package from a signature. + + Args: + signature (string): JNI signature of a method or field. + + Returns: + The package name of the class containing the field/method. + """ + full_class_name = signature.split(";->")[0] + package_name = full_class_name[1:full_class_name.rindex("/")] + return package_name.replace('/', '.') + class FlagsDict: def __init__(self): self._dict_keyset = set() @@ -206,7 +228,10 @@ class FlagsDict: self._dict_keyset.update([ csv[0] for csv in csv_values ]) # Check that all flags are known. - csv_flags = set(reduce(lambda x, y: set(x).union(y), [ csv[1:] for csv in csv_values ], [])) + csv_flags = set(functools.reduce( + lambda x, y: set(x).union(y), + [ csv[1:] for csv in csv_values ], + [])) self._check_flags_set(csv_flags, source) # Iterate over all CSV lines, find entry in dict and append flags to it. @@ -273,6 +298,15 @@ def main(argv): valid_entries = flags.get_valid_subset_of_unassigned_apis(read_lines(filename)) flags.assign_flag(flag, valid_entries, filename) + # All members in the specified packages will be assigned the appropriate flag. + for flag in ALL_FLAGS: + for filename in args[flag + FLAG_PACKAGES_SUFFIX]: + packages_needing_list = set(read_lines(filename)) + should_add_signature_to_list = lambda sig,lists: extract_package( + sig) in packages_needing_list and not lists + valid_entries = flags.filter_apis(should_add_signature_to_list) + flags.assign_flag(flag, valid_entries) + # Assign all remaining entries to the blacklist. flags.assign_flag(FLAG_BLACKLIST, flags.filter_apis(HAS_NO_API_LIST_ASSIGNED)) diff --git a/tools/hiddenapi/generate_hiddenapi_lists_test.py b/tools/hiddenapi/generate_hiddenapi_lists_test.py index 249f37db5a82..4dc880b107d3 100755 --- a/tools/hiddenapi/generate_hiddenapi_lists_test.py +++ b/tools/hiddenapi/generate_hiddenapi_lists_test.py @@ -18,33 +18,23 @@ import unittest from generate_hiddenapi_lists import * class TestHiddenapiListGeneration(unittest.TestCase): - def test_init(self): - # Check empty lists - flags = FlagsDict([], []) - self.assertEquals(flags.generate_csv(), []) - - # Check valid input - two public and two private API signatures. - flags = FlagsDict(['A', 'B'], ['C', 'D']) - self.assertEquals(flags.generate_csv(), - [ 'A,' + FLAG_WHITELIST, 'B,' + FLAG_WHITELIST, 'C', 'D' ]) - - # Check invalid input - overlapping public/private API signatures. - with self.assertRaises(AssertionError): - flags = FlagsDict(['A', 'B'], ['B', 'C', 'D']) def test_filter_apis(self): # Initialize flags so that A and B are put on the whitelist and # C, D, E are left unassigned. Try filtering for the unassigned ones. - flags = FlagsDict(['A', 'B'], ['C', 'D', 'E']) + flags = FlagsDict() + flags.parse_and_merge_csv(['A,' + FLAG_WHITELIST, 'B,' + FLAG_WHITELIST, + 'C', 'D', 'E']) filter_set = flags.filter_apis(lambda api, flags: not flags) self.assertTrue(isinstance(filter_set, set)) self.assertEqual(filter_set, set([ 'C', 'D', 'E' ])) def test_get_valid_subset_of_unassigned_keys(self): # Create flags where only A is unassigned. - flags = FlagsDict(['A'], ['B', 'C']) + flags = FlagsDict() + flags.parse_and_merge_csv(['A,' + FLAG_WHITELIST, 'B', 'C']) flags.assign_flag(FLAG_GREYLIST, set(['C'])) - self.assertEquals(flags.generate_csv(), + self.assertEqual(flags.generate_csv(), [ 'A,' + FLAG_WHITELIST, 'B', 'C,' + FLAG_GREYLIST ]) # Check three things: @@ -55,44 +45,30 @@ class TestHiddenapiListGeneration(unittest.TestCase): flags.get_valid_subset_of_unassigned_apis(set(['A', 'B', 'D'])), set([ 'B' ])) def test_parse_and_merge_csv(self): - flags = FlagsDict(['A'], ['B']) - self.assertEquals(flags.generate_csv(), [ 'A,' + FLAG_WHITELIST, 'B' ]) + flags = FlagsDict() # Test empty CSV entry. - flags.parse_and_merge_csv(['B']) - self.assertEquals(flags.generate_csv(), [ 'A,' + FLAG_WHITELIST, 'B' ]) - - # Test assigning an already assigned flag. - flags.parse_and_merge_csv(['A,' + FLAG_WHITELIST]) - self.assertEquals(flags.generate_csv(), [ 'A,' + FLAG_WHITELIST, 'B' ]) + self.assertEqual(flags.generate_csv(), []) # Test new additions. flags.parse_and_merge_csv([ 'A,' + FLAG_GREYLIST, 'B,' + FLAG_BLACKLIST + ',' + FLAG_GREYLIST_MAX_O ]) self.assertEqual(flags.generate_csv(), - [ 'A,' + FLAG_GREYLIST + "," + FLAG_WHITELIST, + [ 'A,' + FLAG_GREYLIST, 'B,' + FLAG_BLACKLIST + "," + FLAG_GREYLIST_MAX_O ]) - # Test unknown API signature. - with self.assertRaises(AssertionError): - flags.parse_and_merge_csv([ 'C' ]) - # Test unknown flag. with self.assertRaises(AssertionError): - flags.parse_and_merge_csv([ 'A,foo' ]) + flags.parse_and_merge_csv([ 'C,foo' ]) def test_assign_flag(self): - flags = FlagsDict(['A'], ['B']) - self.assertEquals(flags.generate_csv(), [ 'A,' + FLAG_WHITELIST, 'B' ]) - - # Test assigning an already assigned flag. - flags.assign_flag(FLAG_WHITELIST, set([ 'A' ])) - self.assertEquals(flags.generate_csv(), [ 'A,' + FLAG_WHITELIST, 'B' ]) + flags = FlagsDict() + flags.parse_and_merge_csv(['A,' + FLAG_WHITELIST, 'B']) # Test new additions. flags.assign_flag(FLAG_GREYLIST, set([ 'A', 'B' ])) - self.assertEquals(flags.generate_csv(), + self.assertEqual(flags.generate_csv(), [ 'A,' + FLAG_GREYLIST + "," + FLAG_WHITELIST, 'B,' + FLAG_GREYLIST ]) # Test invalid API signature. @@ -103,5 +79,18 @@ class TestHiddenapiListGeneration(unittest.TestCase): with self.assertRaises(AssertionError): flags.assign_flag('foo', set([ 'A' ])) + def test_extract_package(self): + signature = 'Lcom/foo/bar/Baz;->method1()Lcom/bar/Baz;' + expected_package = 'com.foo.bar' + self.assertEqual(extract_package(signature), expected_package) + + signature = 'Lcom/foo1/bar/MyClass;->method2()V' + expected_package = 'com.foo1.bar' + self.assertEqual(extract_package(signature), expected_package) + + signature = 'Lcom/foo_bar/baz/MyClass;->method3()V' + expected_package = 'com.foo_bar.baz' + self.assertEqual(extract_package(signature), expected_package) + if __name__ == '__main__': unittest.main() 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/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 06a99e2f3718..9b3796f57d30 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -2424,8 +2424,11 @@ public class WifiManager { * @throws {@link java.lang.SecurityException} if the caller is missing required permissions. * * @deprecated Starting with Build.VERSION_CODES#Q, applications are not allowed to - * enable/disable Wi-Fi regardless of application's target SDK. This API will have no effect - * and will always return false. + * enable/disable Wi-Fi. + * <b>Compatibility Note:</b> For applications targeting + * {@link android.os.Build.VERSION_CODES#Q} or above, this API will always return {@code false} + * and will have no effect. If apps are targeting an older SDK ( + * {@link android.os.Build.VERSION_CODES#P} or below), they can continue to use this API. */ @Deprecated public boolean setWifiEnabled(boolean enabled) { 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()); + } } |