diff options
70 files changed, 958 insertions, 290 deletions
diff --git a/DREAM_MANAGER_OWNERS b/DREAM_MANAGER_OWNERS new file mode 100644 index 000000000000..48bde6024cba --- /dev/null +++ b/DREAM_MANAGER_OWNERS @@ -0,0 +1 @@ +brycelee@google.com diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp index 77b74e9898b8..5adcd930e341 100644 --- a/cmds/bootanimation/BootAnimation.cpp +++ b/cmds/bootanimation/BootAnimation.cpp @@ -707,11 +707,11 @@ void BootAnimation::resizeSurface(int newWidth, int newHeight) { eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); eglDestroySurface(mDisplay, mSurface); - mFlingerSurfaceControl->updateDefaultBufferSize(newWidth, newHeight); const auto limitedSize = limitSurfaceSize(newWidth, newHeight); mWidth = limitedSize.width; mHeight = limitedSize.height; + mFlingerSurfaceControl->updateDefaultBufferSize(mWidth, mHeight); EGLConfig config = getEglConfig(mDisplay); EGLSurface surface = eglCreateWindowSurface(mDisplay, config, mFlingerSurface.get(), nullptr); if (eglMakeCurrent(mDisplay, surface, surface, mContext) == EGL_FALSE) { diff --git a/cmds/uiautomator/library/core-src/com/android/uiautomator/core/AccessibilityNodeInfoDumper.java b/cmds/uiautomator/library/core-src/com/android/uiautomator/core/AccessibilityNodeInfoDumper.java index 488292d68620..f726361effd6 100644 --- a/cmds/uiautomator/library/core-src/com/android/uiautomator/core/AccessibilityNodeInfoDumper.java +++ b/cmds/uiautomator/library/core-src/com/android/uiautomator/core/AccessibilityNodeInfoDumper.java @@ -292,13 +292,17 @@ public class AccessibilityNodeInfoDumper { int childCount = node.getChildCount(); for (int x = 0; x < childCount; x++) { AccessibilityNodeInfo childNode = node.getChild(x); - + if (childNode == null) { + continue; + } if (!safeCharSeqToString(childNode.getContentDescription()).isEmpty() - || !safeCharSeqToString(childNode.getText()).isEmpty()) + || !safeCharSeqToString(childNode.getText()).isEmpty()) { return true; + } - if (childNafCheck(childNode)) + if (childNafCheck(childNode)) { return true; + } } return false; } diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java index 2a7dbab2bfd1..e7e3a8563319 100644 --- a/core/java/android/accessibilityservice/AccessibilityService.java +++ b/core/java/android/accessibilityservice/AccessibilityService.java @@ -364,12 +364,12 @@ public abstract class AccessibilityService extends Service { public static final int GESTURE_SWIPE_UP_AND_RIGHT = 14; /** - * The user has performed an down and left gesture on the touch screen. + * The user has performed a down and left gesture on the touch screen. */ public static final int GESTURE_SWIPE_DOWN_AND_LEFT = 15; /** - * The user has performed an down and right gesture on the touch screen. + * The user has performed a down and right gesture on the touch screen. */ public static final int GESTURE_SWIPE_DOWN_AND_RIGHT = 16; diff --git a/core/java/android/accounts/AccountManager.java b/core/java/android/accounts/AccountManager.java index 7ee3413550af..497d47adc7cc 100644 --- a/core/java/android/accounts/AccountManager.java +++ b/core/java/android/accounts/AccountManager.java @@ -2015,7 +2015,7 @@ public class AccountManager { * null for no callback * @param handler {@link Handler} identifying the callback thread, * null for the main thread - * @return An {@link AccountManagerFuture} which resolves to a Boolean indicated wether it + * @return An {@link AccountManagerFuture} which resolves to a Boolean indicated whether it * succeeded. * @hide */ diff --git a/core/java/android/app/OWNERS b/core/java/android/app/OWNERS index 712f3e534a1c..02f00ba006d8 100644 --- a/core/java/android/app/OWNERS +++ b/core/java/android/app/OWNERS @@ -60,6 +60,9 @@ per-file ReceiverInfo* = file:/BROADCASTS_OWNERS # ComponentCaller per-file ComponentCaller.java = file:COMPONENT_CALLER_OWNERS +# DreamManager +per-file DreamManager.java = file:/DREAM_MANAGER_OWNERS + # GrammaticalInflectionManager per-file *GrammaticalInflection* = file:/services/core/java/com/android/server/grammaticalinflection/OWNERS diff --git a/core/java/android/net/NetworkPolicyManager.java b/core/java/android/net/NetworkPolicyManager.java index 594ec18d9996..334b2316b268 100644 --- a/core/java/android/net/NetworkPolicyManager.java +++ b/core/java/android/net/NetworkPolicyManager.java @@ -173,6 +173,12 @@ public class NetworkPolicyManager { public static final String FIREWALL_CHAIN_NAME_LOW_POWER_STANDBY = "low_power_standby"; /** @hide */ public static final String FIREWALL_CHAIN_NAME_BACKGROUND = "background"; + /** @hide */ + public static final String FIREWALL_CHAIN_NAME_METERED_ALLOW = "metered_allow"; + /** @hide */ + public static final String FIREWALL_CHAIN_NAME_METERED_DENY_USER = "metered_deny_user"; + /** @hide */ + public static final String FIREWALL_CHAIN_NAME_METERED_DENY_ADMIN = "metered_deny_admin"; private static final boolean ALLOW_PLATFORM_APP_POLICY = true; diff --git a/core/java/android/permission/OWNERS b/core/java/android/permission/OWNERS index d2f4b50eaa1b..857bacd34714 100644 --- a/core/java/android/permission/OWNERS +++ b/core/java/android/permission/OWNERS @@ -1,14 +1,13 @@ # Bug component: 137825 -augale@google.com evanseverson@google.com fayey@google.com jaysullivan@google.com joecastro@google.com -kvakil@google.com mrulhania@google.com ntmyren@google.com rmacgregor@google.com theianchen@google.com yutingfang@google.com zhanghai@google.com +kiranmr@google.com diff --git a/core/java/android/security/flags.aconfig b/core/java/android/security/flags.aconfig index 7d1c86bb2a37..aadc8db903eb 100644 --- a/core/java/android/security/flags.aconfig +++ b/core/java/android/security/flags.aconfig @@ -79,8 +79,15 @@ flag { } flag { - name: "report_primary_auth_attempts" - namespace: "biometrics" - description: "Report primary auth attempts from LockSettingsService" - bug: "285053096" + name: "report_primary_auth_attempts" + namespace: "biometrics" + description: "Report primary auth attempts from LockSettingsService" + bug: "285053096" +} + +flag { + name: "dump_attestation_verifications" + namespace: "hardware_backed_security" + description: "Add a dump capability for attestation_verification service" + bug: "335498868" } diff --git a/core/java/android/view/FocusFinder.java b/core/java/android/view/FocusFinder.java index 064bc6947fc4..5c49e24439bb 100644 --- a/core/java/android/view/FocusFinder.java +++ b/core/java/android/view/FocusFinder.java @@ -129,7 +129,7 @@ public class FocusFinder { } ViewGroup effective = null; ViewParent nextParent = focused.getParent(); - do { + while (nextParent instanceof ViewGroup) { if (nextParent == root) { return effective != null ? effective : root; } @@ -143,7 +143,7 @@ public class FocusFinder { effective = vg; } nextParent = nextParent.getParent(); - } while (nextParent instanceof ViewGroup); + } return root; } diff --git a/core/java/com/android/internal/content/om/OverlayConfigParser.java b/core/java/com/android/internal/content/om/OverlayConfigParser.java index faaf7d5cef18..8132652ed6f4 100644 --- a/core/java/com/android/internal/content/om/OverlayConfigParser.java +++ b/core/java/com/android/internal/content/om/OverlayConfigParser.java @@ -24,6 +24,8 @@ import android.content.pm.PackagePartitions; import android.content.pm.PackagePartitions.SystemPartition; import android.os.Build; import android.os.FileUtils; +import android.os.SystemProperties; +import android.text.TextUtils; import android.util.ArraySet; import android.util.Log; import android.util.Xml; @@ -241,6 +243,18 @@ public final class OverlayConfigParser { } } + @FunctionalInterface + public interface SysPropWrapper{ + /** + * Get system property + * + * @param property the key to look up. + * + * @return The property value if found, empty string otherwise. + */ + String get(String property); + } + /** * Retrieves overlays configured within the partition in increasing priority order. * @@ -320,6 +334,76 @@ public final class OverlayConfigParser { } /** + * Expand the property inside a rro configuration path. + * + * A RRO configuration can contain a property, this method expands + * the property to its value. + * + * Only read only properties allowed, prefixed with ro. Other + * properties will raise exception. + * + * Only a single property in the path is allowed. + * + * Example "${ro.boot.hardware.sku}/config.xml" would expand to + * "G020N/config.xml" + * + * @param configPath path to expand + * @param sysPropWrapper method used for reading properties + * + * @return The expanded path. Returns null if configPath is null. + */ + @VisibleForTesting + public static String expandProperty(String configPath, + SysPropWrapper sysPropWrapper) { + if (configPath == null) { + return null; + } + + int propStartPos = configPath.indexOf("${"); + if (propStartPos == -1) { + // No properties inside the string, return as is + return configPath; + } + + final StringBuilder sb = new StringBuilder(); + sb.append(configPath.substring(0, propStartPos)); + + // Read out the end position + int propEndPos = configPath.indexOf("}", propStartPos); + if (propEndPos == -1) { + throw new IllegalStateException("Malformed property, unmatched braces, in: " + + configPath); + } + + // Confirm that there is only one property inside the string + if (configPath.indexOf("${", propStartPos + 2) != -1) { + throw new IllegalStateException("Only a single property supported in path: " + + configPath); + } + + final String propertyName = configPath.substring(propStartPos + 2, propEndPos); + if (!propertyName.startsWith("ro.")) { + throw new IllegalStateException("Only read only properties can be used when " + + "merging RRO config files: " + propertyName); + } + final String propertyValue = sysPropWrapper.get(propertyName); + if (TextUtils.isEmpty(propertyValue)) { + throw new IllegalStateException("Property is empty or doesn't exist: " + propertyName); + } + Log.d(TAG, String.format("Using property in overlay config path: \"%s\"", propertyName)); + sb.append(propertyValue); + + // propEndPos points to '}', need to step to next character, might be outside of string + propEndPos = propEndPos + 1; + // Append the remainder, if exists + if (propEndPos < configPath.length()) { + sb.append(configPath.substring(propEndPos)); + } + + return sb.toString(); + } + + /** * Parses a <merge> tag within an overlay configuration file. * * Merge tags allow for other configuration files to be "merged" at the current parsing @@ -331,10 +415,21 @@ public final class OverlayConfigParser { @Nullable OverlayScanner scanner, @Nullable Map<String, ParsedOverlayInfo> packageManagerOverlayInfos, @NonNull ParsingContext parsingContext) { - final String path = parser.getAttributeValue(null, "path"); + final String path; + + try { + SysPropWrapper sysPropWrapper = p -> { + return SystemProperties.get(p, ""); + }; + path = expandProperty(parser.getAttributeValue(null, "path"), sysPropWrapper); + } catch (IllegalStateException e) { + throw new IllegalStateException(String.format("<merge> path expand error in %s at %s", + configFile, parser.getPositionDescription()), e); + } + if (path == null) { - throw new IllegalStateException(String.format("<merge> without path in %s at %s" - + configFile, parser.getPositionDescription())); + throw new IllegalStateException(String.format("<merge> without path in %s at %s", + configFile, parser.getPositionDescription())); } if (path.startsWith("/")) { diff --git a/core/java/com/android/internal/ravenwood/RavenwoodEnvironment.java b/core/java/com/android/internal/ravenwood/RavenwoodEnvironment.java new file mode 100644 index 000000000000..1340156321b2 --- /dev/null +++ b/core/java/com/android/internal/ravenwood/RavenwoodEnvironment.java @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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.ravenwood; + +/** + * Class to interact with the Ravenwood environment. + */ +@android.ravenwood.annotation.RavenwoodKeepWholeClass +public class RavenwoodEnvironment { + private static RavenwoodEnvironment sInstance = new RavenwoodEnvironment(); + + private RavenwoodEnvironment() { + } + + /** + * @return the singleton instance. + */ + public static RavenwoodEnvironment getInstance() { + return sInstance; + } + + /** + * USE IT SPARINGLY! Returns true if it's running on Ravenwood, hostside test environment. + * + * <p>Using this allows code to behave differently on a real device and on Ravenwood, but + * generally speaking, that's a bad idea because we want the test target code to behave + * differently. + * + * <p>This should be only used when different behavior is absolutely needed. + * + * <p>If someone needs it without having access to the SDK, the following hack would work too. + * <code>System.getProperty("java.class.path").contains("ravenwood")</code> + */ + @android.ravenwood.annotation.RavenwoodReplace + public boolean isRunningOnRavenwood() { + return false; + } + + public boolean isRunningOnRavenwood$ravenwood() { + return true; + } +} diff --git a/core/tests/coretests/Android.bp b/core/tests/coretests/Android.bp index 871feb65bc75..99909a1d3c7b 100644 --- a/core/tests/coretests/Android.bp +++ b/core/tests/coretests/Android.bp @@ -211,6 +211,8 @@ android_ravenwood_test { "src/com/android/internal/util/**/*.java", "src/com/android/internal/power/EnergyConsumerStatsTest.java", ":FrameworksCoreTests{.aapt.srcjar}", + "src/com/android/internal/ravenwood/**/*.java", + ":FrameworksCoreTests-aidl", ":FrameworksCoreTests-helpers", ":FrameworksCoreTestDoubles-sources", diff --git a/core/tests/coretests/src/android/net/OWNERS b/core/tests/coretests/src/android/net/OWNERS index a779c00814cb..beb77dc8f4fd 100644 --- a/core/tests/coretests/src/android/net/OWNERS +++ b/core/tests/coretests/src/android/net/OWNERS @@ -1,4 +1,5 @@ include /services/core/java/com/android/server/net/OWNERS -per-file SSL*,Uri*,Url* = prb@google.com,oth@google.com,narayan@google.com,ngeoffray@google.com +per-file SSL*,Url* = prb@google.com,oth@google.com,narayan@google.com,ngeoffray@google.com per-file SntpClient* = file:/services/core/java/com/android/server/timedetector/OWNERS +per-file Uri* = varunshah@google.com diff --git a/core/tests/coretests/src/com/android/internal/content/res/OverlayConfigParserTest.java b/core/tests/coretests/src/com/android/internal/content/res/OverlayConfigParserTest.java new file mode 100644 index 000000000000..4eccbe5f1dc4 --- /dev/null +++ b/core/tests/coretests/src/com/android/internal/content/res/OverlayConfigParserTest.java @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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.content.res; + +import static com.android.internal.content.om.OverlayConfigParser.SysPropWrapper; + +import static org.junit.Assert.assertEquals; + +import android.platform.test.annotations.Presubmit; + +import androidx.test.runner.AndroidJUnit4; + +import com.android.internal.content.om.OverlayConfigParser; + +import org.junit.Test; +import org.junit.runner.RunWith; + +@Presubmit +@RunWith(AndroidJUnit4.class) +public class OverlayConfigParserTest { + @Test(expected = IllegalStateException.class) + public void testMergePropNotRoProp() { + SysPropWrapper sysProp = p -> { + return "dummy_value"; + }; + OverlayConfigParser.expandProperty("${persist.value}/path", sysProp); + } + + @Test(expected = IllegalStateException.class) + public void testMergePropMissingEndBracket() { + SysPropWrapper sysProp = p -> { + return "dummy_value"; + }; + OverlayConfigParser.expandProperty("${ro.value/path", sysProp); + } + + @Test(expected = IllegalStateException.class) + public void testMergeOnlyPropStart() { + SysPropWrapper sysProp = p -> { + return "dummy_value"; + }; + OverlayConfigParser.expandProperty("path/${", sysProp); + } + + @Test(expected = IllegalStateException.class) + public void testMergePropInProp() { + SysPropWrapper sysProp = p -> { + return "dummy_value"; + }; + OverlayConfigParser.expandProperty("path/${${ro.value}}", sysProp); + } + + /** + * The path is only allowed to contain one property. + */ + @Test(expected = IllegalStateException.class) + public void testMergePropMultipleProps() { + SysPropWrapper sysProp = p -> { + return "dummy_value"; + }; + OverlayConfigParser.expandProperty("${ro.value}/path${ro.value2}/path", sysProp); + } + + @Test + public void testMergePropOneProp() { + final SysPropWrapper sysProp = p -> { + if ("ro.value".equals(p)) { + return "dummy_value"; + } else { + return "invalid"; + } + }; + + // Property in the beginnig of the string + String result = OverlayConfigParser.expandProperty("${ro.value}/path", + sysProp); + assertEquals("dummy_value/path", result); + + // Property in the middle of the string + result = OverlayConfigParser.expandProperty("path/${ro.value}/file", + sysProp); + assertEquals("path/dummy_value/file", result); + + // Property at the of the string + result = OverlayConfigParser.expandProperty("path/${ro.value}", + sysProp); + assertEquals("path/dummy_value", result); + + // Property is the entire string + result = OverlayConfigParser.expandProperty("${ro.value}", + sysProp); + assertEquals("dummy_value", result); + } + + @Test + public void testMergePropNoProp() { + final SysPropWrapper sysProp = p -> { + return "dummy_value"; + }; + + final String path = "no_props/path"; + String result = OverlayConfigParser.expandProperty(path, sysProp); + assertEquals(path, result); + } +} diff --git a/core/tests/coretests/src/com/android/internal/ravenwood/RavenwoodEnvironmentTest.java b/core/tests/coretests/src/com/android/internal/ravenwood/RavenwoodEnvironmentTest.java new file mode 100644 index 000000000000..d1ef61b2e365 --- /dev/null +++ b/core/tests/coretests/src/com/android/internal/ravenwood/RavenwoodEnvironmentTest.java @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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.ravenwood; + +import static junit.framework.TestCase.assertEquals; + +import android.platform.test.ravenwood.RavenwoodRule; + +import androidx.test.runner.AndroidJUnit4; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(AndroidJUnit4.class) +public class RavenwoodEnvironmentTest { + @Rule + public final RavenwoodRule mRavenwood = new RavenwoodRule(); + + @Test + public void testIsRunningOnRavenwood() { + assertEquals(RavenwoodRule.isUnderRavenwood(), + RavenwoodEnvironment.getInstance().isRunningOnRavenwood()); + } +} diff --git a/graphics/java/android/graphics/BitmapFactory.java b/graphics/java/android/graphics/BitmapFactory.java index d915b746e0cc..1c2014183bb7 100644 --- a/graphics/java/android/graphics/BitmapFactory.java +++ b/graphics/java/android/graphics/BitmapFactory.java @@ -143,7 +143,7 @@ public class BitmapFactory { * the decoder will try to pick the best matching config based on the * system's screen depth, and characteristics of the original image such * as if it has per-pixel alpha (requiring a config that also does). - * + * * Image are loaded with the {@link Bitmap.Config#ARGB_8888} config by * default. */ @@ -183,7 +183,7 @@ public class BitmapFactory { /** * If true (which is the default), the resulting bitmap will have its - * color channels pre-multipled by the alpha channel. + * color channels pre-multiplied by the alpha channel. * * <p>This should NOT be set to false for images to be directly drawn by * the view system or through a {@link Canvas}. The view system and @@ -221,9 +221,9 @@ public class BitmapFactory { * if {@link #inScaled} is set (which it is by default} and this * density does not match {@link #inTargetDensity}, then the bitmap * will be scaled to the target density before being returned. - * + * * <p>If this is 0, - * {@link BitmapFactory#decodeResource(Resources, int)}, + * {@link BitmapFactory#decodeResource(Resources, int)}, * {@link BitmapFactory#decodeResource(Resources, int, android.graphics.BitmapFactory.Options)}, * and {@link BitmapFactory#decodeResourceStream} * will fill in the density associated with the resource. The other @@ -242,29 +242,29 @@ public class BitmapFactory { * This is used in conjunction with {@link #inDensity} and * {@link #inScaled} to determine if and how to scale the bitmap before * returning it. - * + * * <p>If this is 0, - * {@link BitmapFactory#decodeResource(Resources, int)}, + * {@link BitmapFactory#decodeResource(Resources, int)}, * {@link BitmapFactory#decodeResource(Resources, int, android.graphics.BitmapFactory.Options)}, * and {@link BitmapFactory#decodeResourceStream} * will fill in the density associated the Resources object's * DisplayMetrics. The other * functions will leave it as-is and no scaling for density will be * performed. - * + * * @see #inDensity * @see #inScreenDensity * @see #inScaled * @see android.util.DisplayMetrics#densityDpi */ public int inTargetDensity; - + /** * The pixel density of the actual screen that is being used. This is * purely for applications running in density compatibility code, where * {@link #inTargetDensity} is actually the density the application * sees rather than the real screen density. - * + * * <p>By setting this, you * allow the loading code to avoid scaling a bitmap that is currently * in the screen density up/down to the compatibility density. Instead, @@ -274,18 +274,18 @@ public class BitmapFactory { * Bitmap.getScaledWidth} and {@link Bitmap#getScaledHeight * Bitmap.getScaledHeight} to account for any different between the * bitmap's density and the target's density. - * + * * <p>This is never set automatically for the caller by * {@link BitmapFactory} itself. It must be explicitly set, since the * caller must deal with the resulting bitmap in a density-aware way. - * + * * @see #inDensity * @see #inTargetDensity * @see #inScaled * @see android.util.DisplayMetrics#densityDpi */ public int inScreenDensity; - + /** * When this flag is set, if {@link #inDensity} and * {@link #inTargetDensity} are not 0, the @@ -345,7 +345,7 @@ public class BitmapFactory { * ignored. * * In {@link android.os.Build.VERSION_CODES#KITKAT} and below, this - * field works in conjuction with inPurgeable. If inPurgeable is false, + * field works in conjunction with inPurgeable. If inPurgeable is false, * then this field is ignored. If inPurgeable is true, then this field * determines whether the bitmap can share a reference to the input * data (inputstream, array, etc.) or if it must make a deep copy. @@ -583,11 +583,11 @@ public class BitmapFactory { opts.inDensity = density; } } - + if (opts.inTargetDensity == 0 && res != null) { opts.inTargetDensity = res.getDisplayMetrics().densityDpi; } - + return decodeStream(is, pad, opts); } @@ -611,8 +611,8 @@ public class BitmapFactory { public static Bitmap decodeResource(Resources res, int id, Options opts) { validate(opts); Bitmap bm = null; - InputStream is = null; - + InputStream is = null; + try { final TypedValue value = new TypedValue(); is = res.openRawResource(id, value); diff --git a/graphics/java/android/graphics/Canvas.java b/graphics/java/android/graphics/Canvas.java index d1aceafc4e2c..5291f7b4c16c 100644 --- a/graphics/java/android/graphics/Canvas.java +++ b/graphics/java/android/graphics/Canvas.java @@ -52,7 +52,7 @@ import java.lang.annotation.RetentionPolicy; * Canvas and Drawables</a> developer guide.</p></div> */ public class Canvas extends BaseCanvas { - private static int sCompatiblityVersion = 0; + private static int sCompatibilityVersion = 0; private static boolean sCompatibilityRestore = false; private static boolean sCompatibilitySetBitmap = false; @@ -71,7 +71,7 @@ public class Canvas extends BaseCanvas { // Maximum bitmap size as defined in Skia's native code // (see SkCanvas.cpp, SkDraw.cpp) - private static final int MAXMIMUM_BITMAP_SIZE = 32766; + private static final int MAXIMUM_BITMAP_SIZE = 32766; // Use a Holder to allow static initialization of Canvas in the boot image. private static class NoImagePreloadHolder { @@ -316,7 +316,7 @@ public class Canvas extends BaseCanvas { * @see #getMaximumBitmapHeight() */ public int getMaximumBitmapWidth() { - return MAXMIMUM_BITMAP_SIZE; + return MAXIMUM_BITMAP_SIZE; } /** @@ -327,7 +327,7 @@ public class Canvas extends BaseCanvas { * @see #getMaximumBitmapWidth() */ public int getMaximumBitmapHeight() { - return MAXMIMUM_BITMAP_SIZE; + return MAXIMUM_BITMAP_SIZE; } // the SAVE_FLAG constants must match their native equivalents @@ -408,7 +408,7 @@ public class Canvas extends BaseCanvas { public static final int ALL_SAVE_FLAG = 0x1F; private static void checkValidSaveFlags(int saveFlags) { - if (sCompatiblityVersion >= Build.VERSION_CODES.P + if (sCompatibilityVersion >= Build.VERSION_CODES.P && saveFlags != ALL_SAVE_FLAG) { throw new IllegalArgumentException( "Invalid Layer Save Flag - only ALL_SAVE_FLAGS is allowed"); @@ -817,7 +817,7 @@ public class Canvas extends BaseCanvas { } private static void checkValidClipOp(@NonNull Region.Op op) { - if (sCompatiblityVersion >= Build.VERSION_CODES.P + if (sCompatibilityVersion >= Build.VERSION_CODES.P && op != Region.Op.INTERSECT && op != Region.Op.DIFFERENCE) { throw new IllegalArgumentException( "Invalid Region.Op - only INTERSECT and DIFFERENCE are allowed"); @@ -1383,7 +1383,7 @@ public class Canvas extends BaseCanvas { } /*package*/ static void setCompatibilityVersion(int apiLevel) { - sCompatiblityVersion = apiLevel; + sCompatibilityVersion = apiLevel; sCompatibilityRestore = apiLevel < Build.VERSION_CODES.M; sCompatibilitySetBitmap = apiLevel < Build.VERSION_CODES.O; nSetCompatibilityVersion(apiLevel); diff --git a/graphics/java/android/graphics/ComposePathEffect.java b/graphics/java/android/graphics/ComposePathEffect.java index 3fc9eb5aea15..7d59ecea948e 100644 --- a/graphics/java/android/graphics/ComposePathEffect.java +++ b/graphics/java/android/graphics/ComposePathEffect.java @@ -20,13 +20,13 @@ public class ComposePathEffect extends PathEffect { /** * Construct a PathEffect whose effect is to apply first the inner effect - * and the the outer pathEffect (e.g. outer(inner(path))). + * and the outer pathEffect (e.g. outer(inner(path))). */ public ComposePathEffect(PathEffect outerpe, PathEffect innerpe) { native_instance = nativeCreate(outerpe.native_instance, innerpe.native_instance); } - + private static native long nativeCreate(long nativeOuterpe, long nativeInnerpe); } diff --git a/graphics/java/android/graphics/FontFamily.java b/graphics/java/android/graphics/FontFamily.java index f50de1665453..91fa1a6a236c 100644 --- a/graphics/java/android/graphics/FontFamily.java +++ b/graphics/java/android/graphics/FontFamily.java @@ -215,7 +215,7 @@ public class FontFamily { @CriticalNative private static native long nGetFamilyReleaseFunc(); - // By passing -1 to weigth argument, the weight value is resolved by OS/2 table in the font. + // By passing -1 to weight argument, the weight value is resolved by OS/2 table in the font. // By passing -1 to italic argument, the italic value is resolved by OS/2 table in the font. private static native boolean nAddFont(long builderPtr, ByteBuffer font, int ttcIndex, int weight, int isItalic); diff --git a/graphics/java/android/graphics/FontListParser.java b/graphics/java/android/graphics/FontListParser.java index 52b0b95d3e76..2d3ffb5d31ff 100644 --- a/graphics/java/android/graphics/FontListParser.java +++ b/graphics/java/android/graphics/FontListParser.java @@ -127,7 +127,7 @@ public class FontListParser { parser.setInput(is, null); parser.nextTag(); return readFamilies(parser, systemFontDir, oemCustomization, updatableFontMap, - lastModifiedDate, configVersion, false /* filter out the non-exising files */); + lastModifiedDate, configVersion, false /* filter out the non-existing files */); } } @@ -254,7 +254,7 @@ public class FontListParser { * @param parser An XML parser. * @param fontDir a font directory name. * @param updatableFontMap a updated font file map. - * @param allowNonExistingFile true to allow font file that doesn't exists + * @param allowNonExistingFile true to allow font file that doesn't exist. * @return a FontFamily instance. null if no font files are available in this FontFamily. */ public static @Nullable FontConfig.FontFamily readFamily(XmlPullParser parser, String fontDir, diff --git a/graphics/java/android/graphics/FrameInfo.java b/graphics/java/android/graphics/FrameInfo.java index b3615ff60bce..8f1282897780 100644 --- a/graphics/java/android/graphics/FrameInfo.java +++ b/graphics/java/android/graphics/FrameInfo.java @@ -24,7 +24,7 @@ import java.lang.annotation.RetentionPolicy; /** * Class that contains all the timing information for the current frame. This * is used in conjunction with the hardware renderer to provide - * continous-monitoring jank events + * continuous-monitoring jank events * * All times in nanoseconds from CLOCK_MONOTONIC/System.nanoTime() * diff --git a/graphics/java/android/graphics/Interpolator.java b/graphics/java/android/graphics/Interpolator.java index 104546454fa9..418922f767bb 100644 --- a/graphics/java/android/graphics/Interpolator.java +++ b/graphics/java/android/graphics/Interpolator.java @@ -25,13 +25,13 @@ public class Interpolator { mFrameCount = 2; native_instance = nativeConstructor(valueCount, 2); } - + public Interpolator(int valueCount, int frameCount) { mValueCount = valueCount; mFrameCount = frameCount; native_instance = nativeConstructor(valueCount, frameCount); } - + /** * Reset the Interpolator to have the specified number of values and an * implicit keyFrame count of 2 (just a start and end). After this call the @@ -40,7 +40,7 @@ public class Interpolator { public void reset(int valueCount) { reset(valueCount, 2); } - + /** * Reset the Interpolator to have the specified number of values and * keyFrames. After this call the values for each keyFrame must be assigned @@ -51,20 +51,20 @@ public class Interpolator { mFrameCount = frameCount; nativeReset(native_instance, valueCount, frameCount); } - + public final int getKeyFrameCount() { return mFrameCount; } - + public final int getValueCount() { return mValueCount; } - + /** * Assign the keyFrame (specified by index) a time value and an array of key - * values (with an implicity blend array of [0, 0, 1, 1] giving linear + * values (with an implicitly blend array of [0, 0, 1, 1] giving linear * transition to the next set of key values). - * + * * @param index The index of the key frame to assign * @param msec The time (in mililiseconds) for this key frame. Based on the * SystemClock.uptimeMillis() clock @@ -77,7 +77,7 @@ public class Interpolator { /** * Assign the keyFrame (specified by index) a time value and an array of key * values and blend array. - * + * * @param index The index of the key frame to assign * @param msec The time (in mililiseconds) for this key frame. Based on the * SystemClock.uptimeMillis() clock @@ -96,7 +96,7 @@ public class Interpolator { } nativeSetKeyFrame(native_instance, index, msec, values, blend); } - + /** * Set a repeat count (which may be fractional) for the interpolator, and * whether the interpolator should mirror its repeats. The default settings @@ -107,7 +107,7 @@ public class Interpolator { nativeSetRepeatMirror(native_instance, repeatCount, mirror); } } - + public enum Result { NORMAL, FREEZE_START, @@ -127,7 +127,7 @@ public class Interpolator { * return whether the specified time was within the range of key times * (NORMAL), was before the first key time (FREEZE_START) or after the last * key time (FREEZE_END). In any event, computed values are always returned. - * + * * @param msec The time (in milliseconds) used to sample into the * Interpolator. Based on the SystemClock.uptimeMillis() clock * @param values Where to write the computed values (may be NULL). @@ -143,13 +143,13 @@ public class Interpolator { default: return Result.FREEZE_END; } } - + @Override protected void finalize() throws Throwable { nativeDestructor(native_instance); native_instance = 0; // Other finalizers can still call us. } - + private int mValueCount; private int mFrameCount; private long native_instance; diff --git a/graphics/java/android/graphics/LightingColorFilter.java b/graphics/java/android/graphics/LightingColorFilter.java index 0aa6f1282c1a..fe73a1a70b9c 100644 --- a/graphics/java/android/graphics/LightingColorFilter.java +++ b/graphics/java/android/graphics/LightingColorFilter.java @@ -16,8 +16,8 @@ // This file was generated from the C++ include file: SkColorFilter.h // Any changes made to this file will be discarded by the build. -// To change this file, either edit the include, or device/tools/gluemaker/main.cpp, -// or one of the auxilary file specifications in device/tools/gluemaker. +// To change this file, either edit the include, or device/tools/gluemaker/main.cpp, +// or one of the auxiliary file specifications in device/tools/gluemaker. package android.graphics; diff --git a/graphics/java/android/graphics/LinearGradient.java b/graphics/java/android/graphics/LinearGradient.java index 56d912b1eada..087937144b97 100644 --- a/graphics/java/android/graphics/LinearGradient.java +++ b/graphics/java/android/graphics/LinearGradient.java @@ -63,7 +63,7 @@ public class LinearGradient extends Shader { * @param colors The sRGB colors to be distributed along the gradient line * @param positions May be null. The relative positions [0..1] of * each corresponding color in the colors array. If this is null, - * the the colors are distributed evenly along the gradient line. + * the colors are distributed evenly along the gradient line. * @param tile The Shader tiling mode */ public LinearGradient(float x0, float y0, float x1, float y1, @NonNull @ColorInt int[] colors, @@ -82,7 +82,7 @@ public class LinearGradient extends Shader { * @param colors The colors to be distributed along the gradient line * @param positions May be null. The relative positions [0..1] of * each corresponding color in the colors array. If this is null, - * the the colors are distributed evenly along the gradient line. + * the colors are distributed evenly along the gradient line. * @param tile The Shader tiling mode * * @throws IllegalArgumentException if there are less than two colors, the colors do diff --git a/graphics/java/android/graphics/Matrix.java b/graphics/java/android/graphics/Matrix.java index bc58febc388b..66553d87e944 100644 --- a/graphics/java/android/graphics/Matrix.java +++ b/graphics/java/android/graphics/Matrix.java @@ -559,7 +559,7 @@ public class Matrix { /** * Set the matrix to the scale and translate values that map the source rectangle to the - * destination rectangle, returning true if the the result can be represented. + * destination rectangle, returning true if the result can be represented. * * @param src the source rectangle to map from. * @param dst the destination rectangle to map to. diff --git a/graphics/java/android/graphics/Mesh.java b/graphics/java/android/graphics/Mesh.java index a4bce9eb5e88..6be8332e784b 100644 --- a/graphics/java/android/graphics/Mesh.java +++ b/graphics/java/android/graphics/Mesh.java @@ -271,7 +271,7 @@ public class Mesh { * not have a uniform with that name or if the uniform is declared with a type other than int * or int[1] then an IllegalArgumentException is thrown. * - * @param uniformName name matching the int uniform delcared in the shader program. + * @param uniformName name matching the int uniform declared in the shader program. * @param value value corresponding to the int uniform with the given name. */ public void setIntUniform(@NonNull String uniformName, int value) { @@ -283,7 +283,7 @@ public class Mesh { * not have a uniform with that name or if the uniform is declared with a type other than ivec2 * or int[2] then an IllegalArgumentException is thrown. * - * @param uniformName name matching the int uniform delcared in the shader program. + * @param uniformName name matching the int uniform declared in the shader program. * @param value1 first value corresponding to the int uniform with the given name. * @param value2 second value corresponding to the int uniform with the given name. */ @@ -296,7 +296,7 @@ public class Mesh { * not have a uniform with that name or if the uniform is declared with a type other than ivec3 * or int[3] then an IllegalArgumentException is thrown. * - * @param uniformName name matching the int uniform delcared in the shader program. + * @param uniformName name matching the int uniform declared in the shader program. * @param value1 first value corresponding to the int uniform with the given name. * @param value2 second value corresponding to the int uniform with the given name. * @param value3 third value corresponding to the int uniform with the given name. @@ -310,7 +310,7 @@ public class Mesh { * not have a uniform with that name or if the uniform is declared with a type other than ivec4 * or int[4] then an IllegalArgumentException is thrown. * - * @param uniformName name matching the int uniform delcared in the shader program. + * @param uniformName name matching the int uniform declared in the shader program. * @param value1 first value corresponding to the int uniform with the given name. * @param value2 second value corresponding to the int uniform with the given name. * @param value3 third value corresponding to the int uniform with the given name. @@ -327,7 +327,7 @@ public class Mesh { * int (for N=1), ivecN, or int[N], where N is the length of the values param, then an * IllegalArgumentException is thrown. * - * @param uniformName name matching the int uniform delcared in the shader program. + * @param uniformName name matching the int uniform declared in the shader program. * @param values int values corresponding to the vec4 int uniform with the given name. */ public void setIntUniform(@NonNull String uniformName, @NonNull int[] values) { diff --git a/graphics/java/android/graphics/NinePatch.java b/graphics/java/android/graphics/NinePatch.java index af2095713ec2..382269f74366 100644 --- a/graphics/java/android/graphics/NinePatch.java +++ b/graphics/java/android/graphics/NinePatch.java @@ -22,12 +22,12 @@ import android.compat.annotation.UnsupportedAppUsage; * The NinePatch class permits drawing a bitmap in nine or more sections. * Essentially, it allows the creation of custom graphics that will scale the * way that you define, when content added within the image exceeds the normal - * bounds of the graphic. For a thorough explanation of a NinePatch image, - * read the discussion in the + * bounds of the graphic. For a thorough explanation of a NinePatch image, + * read the discussion in the * <a href="{@docRoot}guide/topics/graphics/2d-graphics.html#nine-patch">2D * Graphics</a> document. * <p> - * The <a href="{@docRoot}guide/developing/tools/draw9patch.html">Draw 9-Patch</a> + * The <a href="{@docRoot}guide/developing/tools/draw9patch.html">Draw 9-Patch</a> * tool offers an extremely handy way to create your NinePatch images, * using a WYSIWYG graphics editor. * </p> @@ -104,7 +104,7 @@ public class NinePatch { this(bitmap, chunk, null); } - /** + /** * Create a drawable projection from a bitmap to nine patches. * * @param bitmap The bitmap describing the patches. @@ -122,7 +122,7 @@ public class NinePatch { protected void finalize() throws Throwable { try { if (mNativeChunk != 0) { - // only attempt to destroy correctly initilized chunks + // only attempt to destroy correctly initialized chunks nativeFinalize(mNativeChunk); mNativeChunk = 0; } @@ -169,8 +169,8 @@ public class NinePatch { public Bitmap getBitmap() { return mBitmap; } - - /** + + /** * Draws the NinePatch. This method will use the paint returned by {@link #getPaint()}. * * @param canvas A container for the current matrix and clip used to draw the NinePatch. @@ -180,7 +180,7 @@ public class NinePatch { canvas.drawPatch(this, location, mPaint); } - /** + /** * Draws the NinePatch. This method will use the paint returned by {@link #getPaint()}. * * @param canvas A container for the current matrix and clip used to draw the NinePatch. @@ -190,7 +190,7 @@ public class NinePatch { canvas.drawPatch(this, location, mPaint); } - /** + /** * Draws the NinePatch. This method will ignore the paint returned * by {@link #getPaint()} and use the specified paint instead. * diff --git a/graphics/java/android/graphics/PathMeasure.java b/graphics/java/android/graphics/PathMeasure.java index 5500c5217de4..2c6cfa5c2e3d 100644 --- a/graphics/java/android/graphics/PathMeasure.java +++ b/graphics/java/android/graphics/PathMeasure.java @@ -25,14 +25,14 @@ public class PathMeasure { * setPath. * * Note that once a path is associated with the measure object, it is - * undefined if the path is subsequently modified and the the measure object + * undefined if the path is subsequently modified and the measure object * is used. If the path is modified, you must call setPath with the path. */ public PathMeasure() { mPath = null; native_instance = native_create(0, false); } - + /** * Create a PathMeasure object associated with the specified path object * (already created and specified). The measure object can now return the @@ -40,7 +40,7 @@ public class PathMeasure { * path. * * Note that once a path is associated with the measure object, it is - * undefined if the path is subsequently modified and the the measure object + * undefined if the path is subsequently modified and the measure object * is used. If the path is modified, you must call setPath with the path. * * @param path The path that will be measured by this object @@ -121,7 +121,7 @@ public class PathMeasure { * such as <code>dst.rLineTo(0, 0)</code>.</p> */ public boolean getSegment(float startD, float stopD, Path dst, boolean startWithMoveTo) { - // Skia used to enforce this as part of it's API, but has since relaxed that restriction + // Skia used to enforce this as part of its API, but has since relaxed that restriction // so to maintain consistency in our API we enforce the preconditions here. float length = getLength(); if (startD < 0) { diff --git a/graphics/java/android/graphics/Rasterizer.java b/graphics/java/android/graphics/Rasterizer.java index 29d82fa1d98b..575095426563 100644 --- a/graphics/java/android/graphics/Rasterizer.java +++ b/graphics/java/android/graphics/Rasterizer.java @@ -16,8 +16,8 @@ // This file was generated from the C++ include file: SkRasterizer.h // Any changes made to this file will be discarded by the build. -// To change this file, either edit the include, or device/tools/gluemaker/main.cpp, -// or one of the auxilary file specifications in device/tools/gluemaker. +// To change this file, either edit the include, or device/tools/gluemaker/main.cpp, +// or one of the auxiliary file specifications in device/tools/gluemaker. package android.graphics; diff --git a/graphics/java/android/graphics/Rect.java b/graphics/java/android/graphics/Rect.java index 411a10b85bd2..5211e3a75d09 100644 --- a/graphics/java/android/graphics/Rect.java +++ b/graphics/java/android/graphics/Rect.java @@ -165,7 +165,7 @@ public final class Rect implements Parcelable { public String toShortString() { return toShortString(new StringBuilder(32)); } - + /** * Return a string representation of the rectangle in a compact form. * @hide @@ -184,7 +184,7 @@ public final class Rect implements Parcelable { * * <p>You can later recover the Rect from this string through * {@link #unflattenFromString(String)}. - * + * * @return Returns a new String of the form "left top right bottom" */ @NonNull @@ -314,7 +314,7 @@ public final class Rect implements Parcelable { public final int height() { return bottom - top; } - + /** * @return the horizontal center of the rectangle. If the computed value * is fractional, this method returns the largest integer that is @@ -323,7 +323,7 @@ public final class Rect implements Parcelable { public final int centerX() { return (left + right) >> 1; } - + /** * @return the vertical center of the rectangle. If the computed value * is fractional, this method returns the largest integer that is @@ -332,14 +332,14 @@ public final class Rect implements Parcelable { public final int centerY() { return (top + bottom) >> 1; } - + /** * @return the exact horizontal center of the rectangle as a float. */ public final float exactCenterX() { return (left + right) * 0.5f; } - + /** * @return the exact vertical center of the rectangle as a float. */ @@ -493,7 +493,7 @@ public final class Rect implements Parcelable { * @param top The top of the rectangle being tested for containment * @param right The right side of the rectangle being tested for containment * @param bottom The bottom of the rectangle being tested for containment - * @return true iff the the 4 specified sides of a rectangle are inside or + * @return true iff the 4 specified sides of a rectangle are inside or * equal to this rectangle */ public boolean contains(int left, int top, int right, int bottom) { @@ -548,7 +548,7 @@ public final class Rect implements Parcelable { } return false; } - + /** * If the specified rectangle intersects this rectangle, return true and set * this rectangle to that intersection, otherwise return false and do not @@ -670,7 +670,7 @@ public final class Rect implements Parcelable { public void union(@NonNull Rect r) { union(r.left, r.top, r.right, r.bottom); } - + /** * Update this Rect to enclose itself and the [x,y] coordinate. There is no * check to see that this rectangle is non-empty. diff --git a/graphics/java/android/graphics/RectF.java b/graphics/java/android/graphics/RectF.java index ff50a0c55e6c..5b9b7641111b 100644 --- a/graphics/java/android/graphics/RectF.java +++ b/graphics/java/android/graphics/RectF.java @@ -38,7 +38,7 @@ public class RectF implements Parcelable { public float top; public float right; public float bottom; - + /** * Create a new empty RectF. All coordinates are initialized to 0. */ @@ -78,7 +78,7 @@ public class RectF implements Parcelable { bottom = r.bottom; } } - + public RectF(@Nullable Rect r) { if (r == null) { left = top = right = bottom = 0.0f; @@ -121,7 +121,7 @@ public class RectF implements Parcelable { public String toShortString() { return toShortString(new StringBuilder(32)); } - + /** * Return a string representation of the rectangle in a compact form. * @hide @@ -134,7 +134,7 @@ public class RectF implements Parcelable { sb.append(','); sb.append(bottom); sb.append(']'); return sb.toString(); } - + /** * Print short representation to given writer. * @hide @@ -183,14 +183,14 @@ public class RectF implements Parcelable { public final float centerY() { return (top + bottom) * 0.5f; } - + /** * Set the rectangle to (0,0,0,0) */ public void setEmpty() { left = right = top = bottom = 0; } - + /** * Set the rectangle's coordinates to the specified values. Note: no range * checking is performed, so it is up to the caller to ensure that @@ -220,7 +220,7 @@ public class RectF implements Parcelable { this.right = src.right; this.bottom = src.bottom; } - + /** * Copy the coordinates from src into this rectangle. * @@ -261,7 +261,7 @@ public class RectF implements Parcelable { left = newLeft; top = newTop; } - + /** * Inset the rectangle by (dx,dy). If dx is positive, then the sides are * moved inwards, making the rectangle narrower. If dx is negative, then the @@ -293,7 +293,7 @@ public class RectF implements Parcelable { return left < right && top < bottom // check for empty first && x >= left && x < right && y >= top && y < bottom; } - + /** * Returns true iff the 4 specified sides of a rectangle are inside or equal * to this rectangle. i.e. is this rectangle a superset of the specified @@ -303,7 +303,7 @@ public class RectF implements Parcelable { * @param top The top of the rectangle being tested for containment * @param right The right side of the rectangle being tested for containment * @param bottom The bottom of the rectangle being tested for containment - * @return true iff the the 4 specified sides of a rectangle are inside or + * @return true iff the 4 specified sides of a rectangle are inside or * equal to this rectangle */ public boolean contains(float left, float top, float right, float bottom) { @@ -313,7 +313,7 @@ public class RectF implements Parcelable { && this.left <= left && this.top <= top && this.right >= right && this.bottom >= bottom; } - + /** * Returns true iff the specified rectangle r is inside or equal to this * rectangle. An empty rectangle never contains another rectangle. @@ -329,7 +329,7 @@ public class RectF implements Parcelable { && left <= r.left && top <= r.top && right >= r.right && bottom >= r.bottom; } - + /** * If the rectangle specified by left,top,right,bottom intersects this * rectangle, return true and set this rectangle to that intersection, @@ -367,7 +367,7 @@ public class RectF implements Parcelable { } return false; } - + /** * If the specified rectangle intersects this rectangle, return true and set * this rectangle to that intersection, otherwise return false and do not @@ -382,7 +382,7 @@ public class RectF implements Parcelable { public boolean intersect(@NonNull RectF r) { return intersect(r.left, r.top, r.right, r.bottom); } - + /** * If rectangles a and b intersect, return true and set this rectangle to * that intersection, otherwise return false and do not change this @@ -406,7 +406,7 @@ public class RectF implements Parcelable { } return false; } - + /** * Returns true if this rectangle intersects the specified rectangle. * In no event is this rectangle modified. No check is performed to see @@ -426,7 +426,7 @@ public class RectF implements Parcelable { return this.left < right && left < this.right && this.top < bottom && top < this.bottom; } - + /** * Returns true iff the two specified rectangles intersect. In no event are * either of the rectangles modified. To record the intersection, @@ -441,7 +441,7 @@ public class RectF implements Parcelable { return a.left < b.right && b.left < a.right && a.top < b.bottom && b.top < a.bottom; } - + /** * Set the dst integer Rect by rounding this rectangle's coordinates * to their nearest integer values. @@ -489,7 +489,7 @@ public class RectF implements Parcelable { } } } - + /** * Update this Rect to enclose itself and the specified rectangle. If the * specified rectangle is empty, nothing is done. If this rectangle is empty @@ -500,7 +500,7 @@ public class RectF implements Parcelable { public void union(@NonNull RectF r) { union(r.left, r.top, r.right, r.bottom); } - + /** * Update this Rect to enclose itself and the [x,y] coordinate. There is no * check to see that this rectangle is non-empty. @@ -520,7 +520,7 @@ public class RectF implements Parcelable { bottom = y; } } - + /** * Swap top/bottom or left/right if there are flipped (i.e. left > right * and/or top > bottom). This can be called if @@ -548,7 +548,7 @@ public class RectF implements Parcelable { public int describeContents() { return 0; } - + /** * Write this rectangle to the specified parcel. To restore a rectangle from * a parcel, use readFromParcel() @@ -561,7 +561,7 @@ public class RectF implements Parcelable { out.writeFloat(right); out.writeFloat(bottom); } - + public static final @android.annotation.NonNull Parcelable.Creator<RectF> CREATOR = new Parcelable.Creator<RectF>() { /** * Return a new rectangle from the data in the specified parcel. @@ -572,7 +572,7 @@ public class RectF implements Parcelable { r.readFromParcel(in); return r; } - + /** * Return an array of rectangles of the specified size. */ @@ -581,7 +581,7 @@ public class RectF implements Parcelable { return new RectF[size]; } }; - + /** * Set the rectangle's coordinates from the data stored in the specified * parcel. To write a rectangle to a parcel, call writeToParcel(). diff --git a/graphics/java/android/graphics/RenderNode.java b/graphics/java/android/graphics/RenderNode.java index 27325694073c..0650b7817729 100644 --- a/graphics/java/android/graphics/RenderNode.java +++ b/graphics/java/android/graphics/RenderNode.java @@ -765,12 +765,12 @@ public final class RenderNode { * Default value is false. See * {@link #setProjectBackwards(boolean)} for a description of what this entails. * - * @param shouldRecieve True if this RenderNode is a projection receiver, false otherwise. + * @param shouldReceive True if this RenderNode is a projection receiver, false otherwise. * Default is false. * @return True if the value changed, false if the new value was the same as the previous value. */ - public boolean setProjectionReceiver(boolean shouldRecieve) { - return nSetProjectionReceiver(mNativeRenderNode, shouldRecieve); + public boolean setProjectionReceiver(boolean shouldReceive) { + return nSetProjectionReceiver(mNativeRenderNode, shouldReceive); } /** @@ -1799,7 +1799,7 @@ public final class RenderNode { private static native boolean nSetProjectBackwards(long renderNode, boolean shouldProject); @CriticalNative - private static native boolean nSetProjectionReceiver(long renderNode, boolean shouldRecieve); + private static native boolean nSetProjectionReceiver(long renderNode, boolean shouldReceive); @CriticalNative private static native boolean nSetOutlineRoundRect(long renderNode, int left, int top, diff --git a/graphics/java/android/graphics/SurfaceTexture.java b/graphics/java/android/graphics/SurfaceTexture.java index dd82fed03087..c1b531fb2d9c 100644 --- a/graphics/java/android/graphics/SurfaceTexture.java +++ b/graphics/java/android/graphics/SurfaceTexture.java @@ -318,7 +318,7 @@ public class SurfaceTexture { } /** - * Releases the the texture content. This is needed in single buffered mode to allow the image + * Releases the texture content. This is needed in single buffered mode to allow the image * content producer to take ownership of the image buffer. * <p> * For more information see {@link #SurfaceTexture(int, boolean)}. @@ -431,7 +431,7 @@ public class SurfaceTexture { * error. * <p> * Note that while calling this method causes all the buffers to be freed - * from the perspective of the the SurfaceTexture, if there are additional + * from the perspective of the SurfaceTexture, if there are additional * references on the buffers (e.g. if a buffer is referenced by a client or * by OpenGL ES as a texture) then those buffer will remain allocated. * <p> diff --git a/graphics/java/android/graphics/Typeface.java b/graphics/java/android/graphics/Typeface.java index 4c4e8fa9c088..fd788167a0d8 100644 --- a/graphics/java/android/graphics/Typeface.java +++ b/graphics/java/android/graphics/Typeface.java @@ -600,7 +600,7 @@ public class Typeface { * {@link #setWeight} and {@link #setItalic}. * * If {@link #setWeight} is not called, the fallback family keeps the default weight. - * Similary, if {@link #setItalic} is not called, the fallback family keeps the default + * Similarly, if {@link #setItalic} is not called, the fallback family keeps the default * italic information. For example, calling {@code builder.setFallback("sans-serif-light")} * is equivalent to calling {@code builder.setFallback("sans-serif").setWeight(300)} in * terms of fallback. The default weight and italic information are overridden by calling @@ -794,7 +794,7 @@ public class Typeface { /** * Returns the maximum capacity of custom fallback families. * - * This includes the the first font family passed to the constructor. + * This includes the first font family passed to the constructor. * It is guaranteed that the value will be greater than or equal to 64. * * @return the maximum number of font families for the custom fallback @@ -816,7 +816,7 @@ public class Typeface { /** * Sets a system fallback by name. * - * You can specify generic font familiy names or OEM specific family names. If the system + * You can specify generic font family names or OEM specific family names. If the system * don't have a specified fallback, the default fallback is used instead. * For more information about generic font families, see <a * href="https://www.w3.org/TR/css-fonts-4/#generic-font-families">CSS specification</a> diff --git a/graphics/java/android/graphics/Xfermode.java b/graphics/java/android/graphics/Xfermode.java index 81769e2e21bf..6bb22a12280e 100644 --- a/graphics/java/android/graphics/Xfermode.java +++ b/graphics/java/android/graphics/Xfermode.java @@ -16,8 +16,8 @@ // This file was generated from the C++ include file: SkXfermode.h // Any changes made to this file will be discarded by the build. -// To change this file, either edit the include, or device/tools/gluemaker/main.cpp, -// or one of the auxilary file specifications in device/tools/gluemaker. +// To change this file, either edit the include, or device/tools/gluemaker/main.cpp, +// or one of the auxiliary file specifications in device/tools/gluemaker. package android.graphics; @@ -28,7 +28,7 @@ import android.os.Build; * Xfermode is the base class for objects that are called to implement custom * "transfer-modes" in the drawing pipeline. The static function Create(Modes) * can be called to return an instance of any of the predefined subclasses as - * specified in the Modes enum. When an Xfermode is assigned to an Paint, then + * specified in the Modes enum. When an Xfermode is assigned to a Paint, then * objects drawn with that paint have the xfermode applied. */ public class Xfermode { diff --git a/graphics/java/android/graphics/YuvImage.java b/graphics/java/android/graphics/YuvImage.java index ce35b55d526f..b0c7f202f23a 100644 --- a/graphics/java/android/graphics/YuvImage.java +++ b/graphics/java/android/graphics/YuvImage.java @@ -63,7 +63,7 @@ public class YuvImage { private int mWidth; /** - * The height of the the image. + * The height of the image. */ private int mHeight; diff --git a/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java b/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java index 688425a77ab5..7ee7d6beec78 100644 --- a/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java +++ b/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java @@ -98,7 +98,7 @@ public class AdaptiveIconDrawable extends Drawable implements Drawable.Callback * extra content to reveal within the clip path when performing affine transformations on the * layers. * - * Each layers will reserve 25% of it's width and height. + * Each layers will reserve 25% of its width and height. * * As a result, the view port of the layers is smaller than their intrinsic width and height. */ diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java index 4972e928dd22..7f2feac2278d 100644 --- a/graphics/java/android/graphics/drawable/Drawable.java +++ b/graphics/java/android/graphics/drawable/Drawable.java @@ -839,7 +839,7 @@ public abstract class Drawable { } /** - * Describes the current state, as a union of primitve states, such as + * Describes the current state, as a union of primitive states, such as * {@link android.R.attr#state_focused}, * {@link android.R.attr#state_selected}, etc. * Some drawables may modify their imagery based on the selected state. diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java index 166a795e1661..29d033e64aea 100644 --- a/graphics/java/android/graphics/drawable/GradientDrawable.java +++ b/graphics/java/android/graphics/drawable/GradientDrawable.java @@ -936,7 +936,7 @@ public class GradientDrawable extends Drawable { } /** - * Retrn the inner radius of the ring + * Return the inner radius of the ring * * @see #setInnerRadius(int) * @attr ref android.R.styleable#GradientDrawable_innerRadius diff --git a/graphics/java/android/graphics/drawable/shapes/PathShape.java b/graphics/java/android/graphics/drawable/shapes/PathShape.java index 393fdee87bb8..299f6d5cddfa 100644 --- a/graphics/java/android/graphics/drawable/shapes/PathShape.java +++ b/graphics/java/android/graphics/drawable/shapes/PathShape.java @@ -93,7 +93,7 @@ public class PathShape extends Shape { && Float.compare(pathShape.mStdHeight, mStdHeight) == 0 && Float.compare(pathShape.mScaleX, mScaleX) == 0 && Float.compare(pathShape.mScaleY, mScaleY) == 0 - // Path does not have equals implementation but incase it gains one, use it here + // Path does not have equals implementation but in case it gains one, use it here && Objects.equals(mPath, pathShape.mPath); } diff --git a/graphics/java/android/graphics/fonts/Font.java b/graphics/java/android/graphics/fonts/Font.java index 28cc05162cbb..9aea246dbd06 100644 --- a/graphics/java/android/graphics/fonts/Font.java +++ b/graphics/java/android/graphics/fonts/Font.java @@ -787,7 +787,7 @@ public final class Font { return false; } - // ByteBuffer#equals compares all bytes which is not performant for e.g HashMap. Since + // ByteBuffer#equals compares all bytes which is not performant for e.g. HashMap. Since // underlying native font object holds buffer address, check if this buffer points exactly // the same address as a shortcut of equality. For being compatible with of API30 or before, // check buffer position even if the buffer points the same address. diff --git a/graphics/java/android/graphics/fonts/FontFileUtil.java b/graphics/java/android/graphics/fonts/FontFileUtil.java index ff38282255f2..abcafb666576 100644 --- a/graphics/java/android/graphics/fonts/FontFileUtil.java +++ b/graphics/java/android/graphics/fonts/FontFileUtil.java @@ -34,7 +34,7 @@ import java.util.Set; */ public class FontFileUtil { - private FontFileUtil() {} // Do not instanciate + private FontFileUtil() {} // Do not instantiate /** * Unpack the weight value from packed integer. @@ -87,7 +87,7 @@ public class FontFileUtil { } if (weight != -1 && italic != -1) { - // Both weight/italic style are specifeid by variation settings. + // Both weight/italic style are specified by variation settings. // No need to look into OS/2 table. // TODO: Good to look HVAR table to check if this font supports wght/ital axes. return pack(weight, italic == 1); diff --git a/graphics/java/android/graphics/fonts/SystemFonts.java b/graphics/java/android/graphics/fonts/SystemFonts.java index 3ef714ed8bdf..6e20034c838a 100644 --- a/graphics/java/android/graphics/fonts/SystemFonts.java +++ b/graphics/java/android/graphics/fonts/SystemFonts.java @@ -151,7 +151,7 @@ public final class SystemFonts { } else if (defaultFamily != null) { familyListSet.familyList.add(defaultFamily); } else { - // There is no valid for for default fallback. Ignore. + // There is no valid for default fallback. Ignore. } } } diff --git a/graphics/java/android/graphics/text/LineBreaker.java b/graphics/java/android/graphics/text/LineBreaker.java index 0e3fb163ef75..06ff4c5c5f36 100644 --- a/graphics/java/android/graphics/text/LineBreaker.java +++ b/graphics/java/android/graphics/text/LineBreaker.java @@ -368,8 +368,8 @@ public class LineBreaker { * @see LineBreaker#computeLineBreaks */ public static class Result { - // Following two contstant must be synced with minikin's line breaker. - // TODO(nona): Remove these constatns by introducing native methods. + // Following two constants must be synced with minikin's line breaker. + // TODO(nona): Remove these constants by introducing native methods. private static final int TAB_MASK = 0x20000000; private static final int HYPHEN_MASK = 0xFF; private static final int START_HYPHEN_MASK = 0x18; // 0b11000 diff --git a/graphics/java/android/graphics/text/PositionedGlyphs.java b/graphics/java/android/graphics/text/PositionedGlyphs.java index 7932e3334063..fe20089901e1 100644 --- a/graphics/java/android/graphics/text/PositionedGlyphs.java +++ b/graphics/java/android/graphics/text/PositionedGlyphs.java @@ -137,7 +137,7 @@ public final class PositionedGlyphs { * Returns the glyph ID used for drawing the glyph at the given index. * * @param index the glyph index - * @return An glyph ID of the font. + * @return A glyph ID of the font. */ @IntRange(from = 0) public int getGlyphId(@IntRange(from = 0) int index) { diff --git a/libs/androidfw/fuzz/resourcefile_fuzzer/Android.bp b/libs/androidfw/fuzz/resourcefile_fuzzer/Android.bp index b511244c4a30..619658923865 100644 --- a/libs/androidfw/fuzz/resourcefile_fuzzer/Android.bp +++ b/libs/androidfw/fuzz/resourcefile_fuzzer/Android.bp @@ -19,6 +19,7 @@ package { // to get the below license kinds: // SPDX-license-identifier-Apache-2.0 default_applicable_licenses: ["frameworks_base_libs_androidfw_license"], + default_team: "trendy_team_android_resources", } cc_fuzz { @@ -31,7 +32,7 @@ cc_fuzz { static_libs: ["libgmock"], target: { android: { - shared_libs:[ + shared_libs: [ "libandroidfw", "libbase", "libcutils", @@ -52,4 +53,15 @@ cc_fuzz { ], }, }, + fuzz_config: { + cc: [ + "android-resources@google.com", + ], + componentid: 568761, + description: "The fuzzer targets the APIs of libandroidfw", + vector: "local_no_privileges_required", + service_privilege: "privileged", + users: "multi_user", + fuzzed_code_usage: "shipped", + }, } diff --git a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java index 25ac3c9d9074..635dc420f18c 100644 --- a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java +++ b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java @@ -172,7 +172,7 @@ public class DynamicSystemInstallationService extends Service // This is for testing only now private boolean mEnableWhenCompleted; - private boolean mOneShot; + private boolean mOneShot = true; private boolean mHideNotification; private InstallationAsyncTask.Progress mInstallTaskProgress; diff --git a/proto/src/am_capabilities.proto b/proto/src/am_capabilities.proto index fc9f7a4590bd..c2b3ac2aaa78 100644 --- a/proto/src/am_capabilities.proto +++ b/proto/src/am_capabilities.proto @@ -15,8 +15,16 @@ message FrameworkCapability { string name = 1; } +message VMInfo { + // The value of the "java.vm.name" system property + string name = 1; + // The value of the "java.vm.version" system property + string version = 2; +} + message Capabilities { repeated Capability values = 1; repeated VMCapability vm_capabilities = 2; repeated FrameworkCapability framework_capabilities = 3; + VMInfo vm_info = 4; } diff --git a/ravenwood/ravenwood-annotation-allowed-classes.txt b/ravenwood/ravenwood-annotation-allowed-classes.txt index 13908f1732e1..56eb658a3f2d 100644 --- a/ravenwood/ravenwood-annotation-allowed-classes.txt +++ b/ravenwood/ravenwood-annotation-allowed-classes.txt @@ -1,5 +1,7 @@ # Only classes listed here can use the Ravenwood annotations. +com.android.internal.ravenwood.* + com.android.internal.util.ArrayUtils com.android.internal.os.BatteryStatsHistory com.android.internal.os.BatteryStatsHistory$TraceDelegate diff --git a/services/companion/java/com/android/server/companion/securechannel/SecureChannel.java b/services/companion/java/com/android/server/companion/securechannel/SecureChannel.java index 0e66fbc020a1..71a182225013 100644 --- a/services/companion/java/com/android/server/companion/securechannel/SecureChannel.java +++ b/services/companion/java/com/android/server/companion/securechannel/SecureChannel.java @@ -23,6 +23,7 @@ import android.content.Context; import android.os.Build; import android.util.Slog; +import com.google.security.cryptauth.lib.securegcm.ukey2.AlertException; import com.google.security.cryptauth.lib.securegcm.ukey2.BadHandleException; import com.google.security.cryptauth.lib.securegcm.ukey2.CryptoException; import com.google.security.cryptauth.lib.securegcm.ukey2.D2DConnectionContextV1; @@ -203,7 +204,8 @@ public class SecureChannel { * * This method must only be called from one of the two participants. */ - public void establishSecureConnection() throws IOException, SecureChannelException { + public void establishSecureConnection() throws IOException, + SecureChannelException, HandshakeException { if (isSecured()) { Slog.d(TAG, "Channel is already secure."); return; @@ -334,7 +336,7 @@ public class SecureChannel { } } - private void initiateHandshake() throws IOException, BadHandleException { + private void initiateHandshake() throws IOException, BadHandleException , HandshakeException { if (mConnectionContext != null) { Slog.d(TAG, "Ukey2 handshake is already completed."); return; @@ -394,8 +396,8 @@ public class SecureChannel { } } - private void exchangeHandshake() - throws IOException, HandshakeException, BadHandleException, CryptoException { + private void exchangeHandshake() throws IOException, HandshakeException, + BadHandleException, CryptoException, AlertException { if (mConnectionContext != null) { Slog.d(TAG, "Ukey2 handshake is already completed."); return; diff --git a/services/core/java/com/android/server/PinnerService.java b/services/core/java/com/android/server/PinnerService.java index c5c2b0b5dd59..a19bb1d6f308 100644 --- a/services/core/java/com/android/server/PinnerService.java +++ b/services/core/java/com/android/server/PinnerService.java @@ -885,6 +885,7 @@ public final class PinnerService extends SystemService { } synchronized (this) { pinnedApp.mFiles.add(pf); + mPinnedFiles.put(pf.fileName, pf); } apkPinSizeLimit -= pf.bytesPinned; @@ -1356,18 +1357,6 @@ public final class PinnerService extends SystemService { public List<PinnedFileStat> getPinnerStats() { ArrayList<PinnedFileStat> stats = new ArrayList<>(); - Collection<PinnedApp> pinnedApps; - synchronized(this) { - pinnedApps = mPinnedApps.values(); - } - for (PinnedApp pinnedApp : pinnedApps) { - for (PinnedFile pf : pinnedApp.mFiles) { - PinnedFileStat stat = - new PinnedFileStat(pf.fileName, pf.bytesPinned, pf.groupName); - stats.add(stat); - } - } - Collection<PinnedFile> pinnedFiles; synchronized(this) { pinnedFiles = mPinnedFiles.values(); diff --git a/services/core/java/com/android/server/WallpaperUpdateReceiver.java b/services/core/java/com/android/server/WallpaperUpdateReceiver.java index 2812233815a6..42391a55fed6 100644 --- a/services/core/java/com/android/server/WallpaperUpdateReceiver.java +++ b/services/core/java/com/android/server/WallpaperUpdateReceiver.java @@ -24,7 +24,6 @@ import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; import android.content.Intent; -import android.graphics.Bitmap; import android.os.AsyncTask; import android.os.ParcelFileDescriptor; import android.util.Slog; @@ -59,10 +58,10 @@ public class WallpaperUpdateReceiver extends BroadcastReceiver { return; } if (DEBUG) Slog.d(TAG, "Set customized default_wallpaper."); - Bitmap blank = Bitmap.createBitmap(1, 1, Bitmap.Config.ALPHA_8); - // set a blank wallpaper to force a redraw of default_wallpaper - wallpaperManager.setBitmap(blank); - wallpaperManager.setResource(com.android.internal.R.drawable.default_wallpaper); + // Check if it is not a live wallpaper set + if (wallpaperManager.getWallpaperInfo() == null) { + wallpaperManager.clearWallpaper(); + } } catch (Exception e) { Slog.w(TAG, "Failed to customize system wallpaper." + e); } diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java index c13f02ebdf1b..9a173663383d 100644 --- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java +++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java @@ -127,6 +127,7 @@ import com.android.server.am.nano.Capabilities; import com.android.server.am.nano.Capability; import com.android.server.am.nano.FrameworkCapability; import com.android.server.am.nano.VMCapability; +import com.android.server.am.nano.VMInfo; import com.android.server.compat.PlatformCompat; import com.android.server.pm.UserManagerInternal; import com.android.server.utils.Slogf; @@ -438,6 +439,8 @@ final class ActivityManagerShellCommand extends ShellCommand { return -1; } } + String vmName = System.getProperty("java.vm.name", "?"); + String vmVersion = System.getProperty("java.vm.version", "?"); if (outputAsProtobuf) { Capabilities capabilities = new Capabilities(); @@ -464,6 +467,11 @@ final class ActivityManagerShellCommand extends ShellCommand { capabilities.frameworkCapabilities[i] = cap; } + VMInfo vmInfo = new VMInfo(); + vmInfo.name = vmName; + vmInfo.version = vmVersion; + capabilities.vmInfo = vmInfo; + try { getRawOutputStream().write(Capabilities.toByteArray(capabilities)); } catch (IOException e) { @@ -483,6 +491,8 @@ final class ActivityManagerShellCommand extends ShellCommand { for (String capability : Debug.getFeatureList()) { pw.println("framework:" + capability); } + pw.println("vm_name:" + vmName); + pw.println("vm_version:" + vmVersion); } return 0; } diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index 5e6cf1ab73c6..69c6752fce1f 100644 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -4408,7 +4408,8 @@ public class AudioService extends IAudioService.Stub || usage == AudioAttributes.USAGE_VOICE_COMMUNICATION_SIGNALLING) { voiceActive = true; } - if (usage == AudioAttributes.USAGE_MEDIA || usage == AudioAttributes.USAGE_GAME) { + if (usage == AudioAttributes.USAGE_MEDIA || usage == AudioAttributes.USAGE_GAME + || usage == AudioAttributes.USAGE_UNKNOWN) { mediaActive = true; } } @@ -9680,9 +9681,9 @@ public class AudioService extends IAudioService.Stub mContentResolver.registerContentObserver(Settings.Global.getUriFor( Settings.Global.DOCK_AUDIO_MEDIA_ENABLED), false, this); mContentResolver.registerContentObserver(Settings.System.getUriFor( - Settings.System.MASTER_MONO), false, this); + Settings.System.MASTER_MONO), false, this, UserHandle.USER_ALL); mContentResolver.registerContentObserver(Settings.System.getUriFor( - Settings.System.MASTER_BALANCE), false, this); + Settings.System.MASTER_BALANCE), false, this, UserHandle.USER_ALL); mEncodedSurroundMode = mSettings.getGlobalInt( mContentResolver, Settings.Global.ENCODED_SURROUND_OUTPUT, diff --git a/services/core/java/com/android/server/audio/MusicFxHelper.java b/services/core/java/com/android/server/audio/MusicFxHelper.java index 85b3b49ecf78..cf0b2ae15618 100644 --- a/services/core/java/com/android/server/audio/MusicFxHelper.java +++ b/services/core/java/com/android/server/audio/MusicFxHelper.java @@ -70,6 +70,8 @@ public class MusicFxHelper { // The binder token identifying the UidObserver registration. private IBinder mUidObserverToken = null; + private boolean mIsBound; + // Package name and list of open audio sessions for this package private static class PackageSessions { String mPackageName; @@ -90,7 +92,6 @@ public class MusicFxHelper { * observer will also be removed, and observer token reset to null */ private class MySparseArray extends SparseArray<PackageSessions> { - private final String mMusicFxPackageName = "com.android.musicfx"; @RequiresPermission(anyOf = { android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, @@ -110,6 +111,7 @@ public class MusicFxHelper { if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { Intent bindIntent = new Intent().setClassName(mMusicFxPackageName, "com.android.musicfx.KeepAliveService"); + mIsBound = true; mContext.bindServiceAsUser( bindIntent, mMusicFxBindConnection, Context.BIND_AUTO_CREATE, UserHandle.of(getCurrentUserId())); @@ -158,9 +160,12 @@ public class MusicFxHelper { Log.e(TAG, "RemoteException with unregisterUidObserver: " + e); } mUidObserverToken = null; - mContext.unbindService(mMusicFxBindConnection); - Log.i(TAG, "last session closed, unregister UID observer, and unbind " - + mMusicFxPackageName); + if (mIsBound) { + mContext.unbindService(mMusicFxBindConnection); + mIsBound = false; + Log.i(TAG, "last session closed, unregister UID observer, and unbind " + + mMusicFxPackageName); + } } } } @@ -229,6 +234,10 @@ public class MusicFxHelper { if (ril != null && ril.size() != 0) { ResolveInfo ri = ril.get(0); final String senderPackageName = intent.getStringExtra(AudioEffect.EXTRA_PACKAGE_NAME); + if (senderPackageName == null) { + Log.w(TAG, "Intent package name must not be null"); + return; + } try { if (ri != null && ri.activityInfo != null && ri.activityInfo.packageName != null) { final int senderUid = pm.getPackageUidAsUser(senderPackageName, @@ -265,7 +274,7 @@ public class MusicFxHelper { + senderUid + ", package: " + senderPackageName + ", abort"); return false; } - if (pkgSessions.mPackageName != senderPackageName) { + if (!pkgSessions.mPackageName.equals(senderPackageName)) { Log.w(TAG, "Inconsistency package names for UID open: " + senderUid + " prev: " + pkgSessions.mPackageName + ", now: " + senderPackageName); return false; @@ -297,7 +306,7 @@ public class MusicFxHelper { Log.e(TAG, senderPackageName + " UID " + senderUid + " does not exist in map, abort"); return false; } - if (pkgSessions.mPackageName != senderPackageName) { + if (!pkgSessions.mPackageName.equals(senderPackageName)) { Log.w(TAG, "Inconsistency package names for UID " + senderUid + " close, prev: " + pkgSessions.mPackageName + ", now: " + senderPackageName); return false; diff --git a/services/core/java/com/android/server/audio/SpatializerHelper.java b/services/core/java/com/android/server/audio/SpatializerHelper.java index 4f7f31dfa7dc..5be2291ff056 100644 --- a/services/core/java/com/android/server/audio/SpatializerHelper.java +++ b/services/core/java/com/android/server/audio/SpatializerHelper.java @@ -342,9 +342,6 @@ public class SpatializerHelper { //------------------------------------------------------ // routing monitoring synchronized void onRoutingUpdated() { - if (!mFeatureEnabled) { - return; - } switch (mState) { case STATE_UNINITIALIZED: case STATE_NOT_SUPPORTED: @@ -388,7 +385,7 @@ public class SpatializerHelper { setDispatchAvailableState(false); } - boolean enabled = able && enabledAvailable.first; + boolean enabled = mFeatureEnabled && able && enabledAvailable.first; if (enabled) { loglogi("Enabling Spatial Audio since enabled for media device:" + currentDevice); diff --git a/services/core/java/com/android/server/net/NetworkManagementService.java b/services/core/java/com/android/server/net/NetworkManagementService.java index d25f52973085..5ea3e70f7957 100644 --- a/services/core/java/com/android/server/net/NetworkManagementService.java +++ b/services/core/java/com/android/server/net/NetworkManagementService.java @@ -20,6 +20,9 @@ import static android.Manifest.permission.CONNECTIVITY_INTERNAL; import static android.net.ConnectivityManager.FIREWALL_CHAIN_BACKGROUND; import static android.net.ConnectivityManager.FIREWALL_CHAIN_DOZABLE; import static android.net.ConnectivityManager.FIREWALL_CHAIN_LOW_POWER_STANDBY; +import static android.net.ConnectivityManager.FIREWALL_CHAIN_METERED_ALLOW; +import static android.net.ConnectivityManager.FIREWALL_CHAIN_METERED_DENY_ADMIN; +import static android.net.ConnectivityManager.FIREWALL_CHAIN_METERED_DENY_USER; import static android.net.ConnectivityManager.FIREWALL_CHAIN_POWERSAVE; import static android.net.ConnectivityManager.FIREWALL_CHAIN_RESTRICTED; import static android.net.ConnectivityManager.FIREWALL_CHAIN_STANDBY; @@ -31,6 +34,9 @@ import static android.net.INetd.FIREWALL_RULE_DENY; import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_BACKGROUND; import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_DOZABLE; import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_LOW_POWER_STANDBY; +import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_METERED_ALLOW; +import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_METERED_DENY_ADMIN; +import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_METERED_DENY_USER; import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_POWERSAVE; import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_RESTRICTED; import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_STANDBY; @@ -143,6 +149,8 @@ public class NetworkManagementService extends INetworkManagementService.Stub { private final Object mQuotaLock = new Object(); private final Object mRulesLock = new Object(); + private final boolean mUseMeteredFirewallChains; + /** Set of interfaces with active quotas. */ @GuardedBy("mQuotaLock") private HashMap<String, Long> mActiveQuotas = Maps.newHashMap(); @@ -150,9 +158,11 @@ public class NetworkManagementService extends INetworkManagementService.Stub { @GuardedBy("mQuotaLock") private HashMap<String, Long> mActiveAlerts = Maps.newHashMap(); /** Set of UIDs denied on metered networks. */ + // TODO: b/336693007 - Remove once NPMS has completely migrated to metered firewall chains. @GuardedBy("mRulesLock") private SparseBooleanArray mUidRejectOnMetered = new SparseBooleanArray(); /** Set of UIDs allowed on metered networks. */ + // TODO: b/336693007 - Remove once NPMS has completely migrated to metered firewall chains. @GuardedBy("mRulesLock") private SparseBooleanArray mUidAllowOnMetered = new SparseBooleanArray(); /** Set of UIDs with cleartext penalties. */ @@ -196,10 +206,32 @@ public class NetworkManagementService extends INetworkManagementService.Stub { @GuardedBy("mRulesLock") private final SparseIntArray mUidFirewallBackgroundRules = new SparseIntArray(); + /** + * Contains the per-UID firewall rules that are used to allowlist the app from metered-network + * restrictions when data saver is enabled. + */ + @GuardedBy("mRulesLock") + private final SparseIntArray mUidMeteredFirewallAllowRules = new SparseIntArray(); + + /** + * Contains the per-UID firewall rules that are used to deny app access to metered networks + * due to user action. + */ + @GuardedBy("mRulesLock") + private final SparseIntArray mUidMeteredFirewallDenyUserRules = new SparseIntArray(); + + /** + * Contains the per-UID firewall rules that are used to deny app access to metered networks + * due to admin action. + */ + @GuardedBy("mRulesLock") + private final SparseIntArray mUidMeteredFirewallDenyAdminRules = new SparseIntArray(); + /** Set of states for the child firewall chains. True if the chain is active. */ @GuardedBy("mRulesLock") final SparseBooleanArray mFirewallChainStates = new SparseBooleanArray(); + // TODO: b/336693007 - Remove once NPMS has completely migrated to metered firewall chains. @GuardedBy("mQuotaLock") private volatile boolean mDataSaverMode; @@ -217,6 +249,15 @@ public class NetworkManagementService extends INetworkManagementService.Stub { mContext = context; mDeps = deps; + mUseMeteredFirewallChains = Flags.useMeteredFirewallChains(); + + if (mUseMeteredFirewallChains) { + // These firewalls are always on and currently ConnectivityService does not allow + // changing their enabled state. + mFirewallChainStates.put(FIREWALL_CHAIN_METERED_DENY_USER, true); + mFirewallChainStates.put(FIREWALL_CHAIN_METERED_DENY_ADMIN, true); + } + mDaemonHandler = new Handler(FgThread.get().getLooper()); mNetdUnsolicitedEventListener = new NetdUnsolicitedEventListener(); @@ -410,33 +451,39 @@ public class NetworkManagementService extends INetworkManagementService.Stub { } } - SparseBooleanArray uidRejectOnQuota = null; - SparseBooleanArray uidAcceptOnQuota = null; - synchronized (mRulesLock) { - size = mUidRejectOnMetered.size(); - if (size > 0) { - if (DBG) Slog.d(TAG, "Pushing " + size + " UIDs to metered denylist rules"); - uidRejectOnQuota = mUidRejectOnMetered; - mUidRejectOnMetered = new SparseBooleanArray(); - } + if (!mUseMeteredFirewallChains) { + SparseBooleanArray uidRejectOnQuota = null; + SparseBooleanArray uidAcceptOnQuota = null; + synchronized (mRulesLock) { + size = mUidRejectOnMetered.size(); + if (size > 0) { + if (DBG) { + Slog.d(TAG, "Pushing " + size + " UIDs to metered denylist rules"); + } + uidRejectOnQuota = mUidRejectOnMetered; + mUidRejectOnMetered = new SparseBooleanArray(); + } - size = mUidAllowOnMetered.size(); - if (size > 0) { - if (DBG) Slog.d(TAG, "Pushing " + size + " UIDs to metered allowlist rules"); - uidAcceptOnQuota = mUidAllowOnMetered; - mUidAllowOnMetered = new SparseBooleanArray(); + size = mUidAllowOnMetered.size(); + if (size > 0) { + if (DBG) { + Slog.d(TAG, "Pushing " + size + " UIDs to metered allowlist rules"); + } + uidAcceptOnQuota = mUidAllowOnMetered; + mUidAllowOnMetered = new SparseBooleanArray(); + } } - } - if (uidRejectOnQuota != null) { - for (int i = 0; i < uidRejectOnQuota.size(); i++) { - setUidOnMeteredNetworkDenylist(uidRejectOnQuota.keyAt(i), - uidRejectOnQuota.valueAt(i)); + if (uidRejectOnQuota != null) { + for (int i = 0; i < uidRejectOnQuota.size(); i++) { + setUidOnMeteredNetworkDenylist(uidRejectOnQuota.keyAt(i), + uidRejectOnQuota.valueAt(i)); + } } - } - if (uidAcceptOnQuota != null) { - for (int i = 0; i < uidAcceptOnQuota.size(); i++) { - setUidOnMeteredNetworkAllowlist(uidAcceptOnQuota.keyAt(i), - uidAcceptOnQuota.valueAt(i)); + if (uidAcceptOnQuota != null) { + for (int i = 0; i < uidAcceptOnQuota.size(); i++) { + setUidOnMeteredNetworkAllowlist(uidAcceptOnQuota.keyAt(i), + uidAcceptOnQuota.valueAt(i)); + } } } @@ -459,8 +506,16 @@ public class NetworkManagementService extends INetworkManagementService.Stub { syncFirewallChainLocked(FIREWALL_CHAIN_RESTRICTED, "restricted "); syncFirewallChainLocked(FIREWALL_CHAIN_LOW_POWER_STANDBY, "low power standby "); syncFirewallChainLocked(FIREWALL_CHAIN_BACKGROUND, FIREWALL_CHAIN_NAME_BACKGROUND); + if (mUseMeteredFirewallChains) { + syncFirewallChainLocked(FIREWALL_CHAIN_METERED_ALLOW, + FIREWALL_CHAIN_NAME_METERED_ALLOW); + syncFirewallChainLocked(FIREWALL_CHAIN_METERED_DENY_USER, + FIREWALL_CHAIN_NAME_METERED_DENY_USER); + syncFirewallChainLocked(FIREWALL_CHAIN_METERED_DENY_ADMIN, + FIREWALL_CHAIN_NAME_METERED_DENY_ADMIN); + } - final int[] chains = { + final int[] chainsToEnable = { FIREWALL_CHAIN_STANDBY, FIREWALL_CHAIN_DOZABLE, FIREWALL_CHAIN_POWERSAVE, @@ -469,14 +524,13 @@ public class NetworkManagementService extends INetworkManagementService.Stub { FIREWALL_CHAIN_BACKGROUND, }; - for (int chain : chains) { + for (int chain : chainsToEnable) { if (getFirewallChainState(chain)) { setFirewallChainEnabled(chain, true); } } } - try { getBatteryStats().noteNetworkStatsEnabled(); } catch (RemoteException e) { @@ -1077,6 +1131,14 @@ public class NetworkManagementService extends INetworkManagementService.Stub { mContext.getSystemService(ConnectivityManager.class) .setDataSaverEnabled(enable); mDataSaverMode = enable; + if (mUseMeteredFirewallChains) { + // Copy mDataSaverMode state to FIREWALL_CHAIN_METERED_ALLOW + // until ConnectivityService allows manipulation of the data saver mode via + // FIREWALL_CHAIN_METERED_ALLOW. + synchronized (mRulesLock) { + mFirewallChainStates.put(FIREWALL_CHAIN_METERED_ALLOW, enable); + } + } return true; } else { final boolean changed = mNetdService.bandwidthEnableDataSaver(enable); @@ -1191,9 +1253,9 @@ public class NetworkManagementService extends INetworkManagementService.Stub { setFirewallChainState(chain, enable); } - final String chainName = getFirewallChainName(chain); - if (chain == FIREWALL_CHAIN_NONE) { - throw new IllegalArgumentException("Bad child chain: " + chainName); + if (!isValidFirewallChainForSetEnabled(chain)) { + throw new IllegalArgumentException("Invalid chain for setFirewallChainEnabled: " + + NetworkPolicyLogger.getFirewallChainName(chain)); } final ConnectivityManager cm = mContext.getSystemService(ConnectivityManager.class); @@ -1205,38 +1267,29 @@ public class NetworkManagementService extends INetworkManagementService.Stub { } } - private String getFirewallChainName(int chain) { - switch (chain) { - case FIREWALL_CHAIN_STANDBY: - return FIREWALL_CHAIN_NAME_STANDBY; - case FIREWALL_CHAIN_DOZABLE: - return FIREWALL_CHAIN_NAME_DOZABLE; - case FIREWALL_CHAIN_POWERSAVE: - return FIREWALL_CHAIN_NAME_POWERSAVE; - case FIREWALL_CHAIN_RESTRICTED: - return FIREWALL_CHAIN_NAME_RESTRICTED; - case FIREWALL_CHAIN_LOW_POWER_STANDBY: - return FIREWALL_CHAIN_NAME_LOW_POWER_STANDBY; - case FIREWALL_CHAIN_BACKGROUND: - return FIREWALL_CHAIN_NAME_BACKGROUND; - default: - throw new IllegalArgumentException("Bad child chain: " + chain); - } + private boolean isValidFirewallChainForSetEnabled(int chain) { + return switch (chain) { + case FIREWALL_CHAIN_STANDBY, FIREWALL_CHAIN_DOZABLE, FIREWALL_CHAIN_POWERSAVE, + FIREWALL_CHAIN_RESTRICTED, FIREWALL_CHAIN_LOW_POWER_STANDBY, + FIREWALL_CHAIN_BACKGROUND -> true; + // METERED_* firewall chains are not yet supported by + // ConnectivityService#setFirewallChainEnabled. + default -> false; + }; } private int getFirewallType(int chain) { switch (chain) { case FIREWALL_CHAIN_STANDBY: + case FIREWALL_CHAIN_METERED_DENY_ADMIN: + case FIREWALL_CHAIN_METERED_DENY_USER: return FIREWALL_DENYLIST; case FIREWALL_CHAIN_DOZABLE: - return FIREWALL_ALLOWLIST; case FIREWALL_CHAIN_POWERSAVE: - return FIREWALL_ALLOWLIST; case FIREWALL_CHAIN_RESTRICTED: - return FIREWALL_ALLOWLIST; case FIREWALL_CHAIN_LOW_POWER_STANDBY: - return FIREWALL_ALLOWLIST; case FIREWALL_CHAIN_BACKGROUND: + case FIREWALL_CHAIN_METERED_ALLOW: return FIREWALL_ALLOWLIST; default: return isFirewallEnabled() ? FIREWALL_ALLOWLIST : FIREWALL_DENYLIST; @@ -1360,6 +1413,12 @@ public class NetworkManagementService extends INetworkManagementService.Stub { return mUidFirewallLowPowerStandbyRules; case FIREWALL_CHAIN_BACKGROUND: return mUidFirewallBackgroundRules; + case FIREWALL_CHAIN_METERED_ALLOW: + return mUidMeteredFirewallAllowRules; + case FIREWALL_CHAIN_METERED_DENY_USER: + return mUidMeteredFirewallDenyUserRules; + case FIREWALL_CHAIN_METERED_DENY_ADMIN: + return mUidMeteredFirewallDenyAdminRules; case FIREWALL_CHAIN_NONE: return mUidFirewallRules; default: @@ -1378,6 +1437,10 @@ public class NetworkManagementService extends INetworkManagementService.Stub { protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return; + pw.println("Flags:"); + pw.println(Flags.FLAG_USE_METERED_FIREWALL_CHAINS + ": " + mUseMeteredFirewallChains); + pw.println(); + synchronized (mQuotaLock) { pw.print("Active quota ifaces: "); pw.println(mActiveQuotas.toString()); pw.print("Active alert ifaces: "); pw.println(mActiveAlerts.toString()); @@ -1416,6 +1479,27 @@ public class NetworkManagementService extends INetworkManagementService.Stub { pw.print("UID firewall background chain enabled: "); pw.println(getFirewallChainState(FIREWALL_CHAIN_BACKGROUND)); dumpUidFirewallRule(pw, FIREWALL_CHAIN_NAME_BACKGROUND, mUidFirewallBackgroundRules); + + pw.print("UID firewall metered allow chain enabled (Data saver mode): "); + // getFirewallChainState should maintain a duplicated state from mDataSaverMode when + // mUseMeteredFirewallChains is enabled. + pw.println(getFirewallChainState(FIREWALL_CHAIN_METERED_ALLOW)); + dumpUidFirewallRule(pw, FIREWALL_CHAIN_NAME_METERED_ALLOW, + mUidMeteredFirewallAllowRules); + + pw.print("UID firewall metered deny_user chain enabled (always-on): "); + // This always-on state should be reflected by getFirewallChainState when + // mUseMeteredFirewallChains is enabled. + pw.println(getFirewallChainState(FIREWALL_CHAIN_METERED_DENY_USER)); + dumpUidFirewallRule(pw, FIREWALL_CHAIN_NAME_METERED_DENY_USER, + mUidMeteredFirewallDenyUserRules); + + pw.print("UID firewall metered deny_admin chain enabled (always-on): "); + // This always-on state should be reflected by getFirewallChainState when + // mUseMeteredFirewallChains is enabled. + pw.println(getFirewallChainState(FIREWALL_CHAIN_METERED_DENY_ADMIN)); + dumpUidFirewallRule(pw, FIREWALL_CHAIN_NAME_METERED_DENY_ADMIN, + mUidMeteredFirewallDenyAdminRules); } pw.print("Firewall enabled: "); pw.println(mFirewallEnabled); @@ -1520,14 +1604,40 @@ public class NetworkManagementService extends INetworkManagementService.Stub { if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because it is in background"); return true; } - if (mUidRejectOnMetered.get(uid)) { - if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because of no metered data" - + " in the background"); - return true; - } - if (mDataSaverMode && !mUidAllowOnMetered.get(uid)) { - if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because of data saver mode"); - return true; + if (mUseMeteredFirewallChains) { + if (getFirewallChainState(FIREWALL_CHAIN_METERED_DENY_USER) + && mUidMeteredFirewallDenyUserRules.get(uid) == FIREWALL_RULE_DENY) { + if (DBG) { + Slog.d(TAG, "Uid " + uid + " restricted because of user-restricted metered" + + " data in the background"); + } + return true; + } + if (getFirewallChainState(FIREWALL_CHAIN_METERED_DENY_ADMIN) + && mUidMeteredFirewallDenyAdminRules.get(uid) == FIREWALL_RULE_DENY) { + if (DBG) { + Slog.d(TAG, "Uid " + uid + " restricted because of admin-restricted metered" + + " data in the background"); + } + return true; + } + if (getFirewallChainState(FIREWALL_CHAIN_METERED_ALLOW) + && mUidMeteredFirewallAllowRules.get(uid) != FIREWALL_RULE_ALLOW) { + if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because of data saver mode"); + return true; + } + } else { + if (mUidRejectOnMetered.get(uid)) { + if (DBG) { + Slog.d(TAG, "Uid " + uid + + " restricted because of no metered data in the background"); + } + return true; + } + if (mDataSaverMode && !mUidAllowOnMetered.get(uid)) { + if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because of data saver mode"); + return true; + } } return false; } diff --git a/services/core/java/com/android/server/net/NetworkPolicyLogger.java b/services/core/java/com/android/server/net/NetworkPolicyLogger.java index 8e2d7780204a..681aa8aef219 100644 --- a/services/core/java/com/android/server/net/NetworkPolicyLogger.java +++ b/services/core/java/com/android/server/net/NetworkPolicyLogger.java @@ -19,6 +19,9 @@ import static android.net.ConnectivityManager.BLOCKED_REASON_NONE; import static android.net.ConnectivityManager.FIREWALL_CHAIN_BACKGROUND; import static android.net.ConnectivityManager.FIREWALL_CHAIN_DOZABLE; import static android.net.ConnectivityManager.FIREWALL_CHAIN_LOW_POWER_STANDBY; +import static android.net.ConnectivityManager.FIREWALL_CHAIN_METERED_ALLOW; +import static android.net.ConnectivityManager.FIREWALL_CHAIN_METERED_DENY_ADMIN; +import static android.net.ConnectivityManager.FIREWALL_CHAIN_METERED_DENY_USER; import static android.net.ConnectivityManager.FIREWALL_CHAIN_POWERSAVE; import static android.net.ConnectivityManager.FIREWALL_CHAIN_RESTRICTED; import static android.net.ConnectivityManager.FIREWALL_CHAIN_STANDBY; @@ -28,6 +31,9 @@ import static android.net.NetworkPolicyManager.ALLOWED_REASON_NONE; import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_BACKGROUND; import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_DOZABLE; import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_LOW_POWER_STANDBY; +import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_METERED_ALLOW; +import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_METERED_DENY_ADMIN; +import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_METERED_DENY_USER; import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_POWERSAVE; import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_RESTRICTED; import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_STANDBY; @@ -379,7 +385,7 @@ public class NetworkPolicyLogger { return "Interfaces of netId=" + netId + " changed to " + newIfaces; } - private static String getFirewallChainName(int chain) { + static String getFirewallChainName(int chain) { switch (chain) { case FIREWALL_CHAIN_DOZABLE: return FIREWALL_CHAIN_NAME_DOZABLE; @@ -393,6 +399,12 @@ public class NetworkPolicyLogger { return FIREWALL_CHAIN_NAME_LOW_POWER_STANDBY; case FIREWALL_CHAIN_BACKGROUND: return FIREWALL_CHAIN_NAME_BACKGROUND; + case FIREWALL_CHAIN_METERED_ALLOW: + return FIREWALL_CHAIN_NAME_METERED_ALLOW; + case FIREWALL_CHAIN_METERED_DENY_USER: + return FIREWALL_CHAIN_NAME_METERED_DENY_USER; + case FIREWALL_CHAIN_METERED_DENY_ADMIN: + return FIREWALL_CHAIN_NAME_METERED_DENY_ADMIN; default: return String.valueOf(chain); } diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java index c6fca9b76f8e..a26ac615ba40 100644 --- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java +++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java @@ -60,6 +60,9 @@ import static android.net.ConnectivityManager.CONNECTIVITY_ACTION; import static android.net.ConnectivityManager.FIREWALL_CHAIN_BACKGROUND; import static android.net.ConnectivityManager.FIREWALL_CHAIN_DOZABLE; import static android.net.ConnectivityManager.FIREWALL_CHAIN_LOW_POWER_STANDBY; +import static android.net.ConnectivityManager.FIREWALL_CHAIN_METERED_ALLOW; +import static android.net.ConnectivityManager.FIREWALL_CHAIN_METERED_DENY_ADMIN; +import static android.net.ConnectivityManager.FIREWALL_CHAIN_METERED_DENY_USER; import static android.net.ConnectivityManager.FIREWALL_CHAIN_POWERSAVE; import static android.net.ConnectivityManager.FIREWALL_CHAIN_RESTRICTED; import static android.net.ConnectivityManager.FIREWALL_CHAIN_STANDBY; @@ -514,6 +517,12 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { */ private boolean mBackgroundNetworkRestricted; + /** + * Whether or not metered firewall chains should be used for uid policy controlling access to + * metered networks. + */ + private boolean mUseMeteredFirewallChains; + // See main javadoc for instructions on how to use these locks. final Object mUidRulesFirstLock = new Object(); final Object mNetworkPoliciesSecondLock = new Object(); @@ -997,6 +1006,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { mAppStandby = LocalServices.getService(AppStandbyInternal.class); mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class); + mUseMeteredFirewallChains = Flags.useMeteredFirewallChains(); + synchronized (mUidRulesFirstLock) { synchronized (mNetworkPoliciesSecondLock) { updatePowerSaveAllowlistUL(); @@ -4030,8 +4041,10 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { fout.println(); fout.println("Flags:"); - fout.println("Network blocked for TOP_SLEEPING and above: " + fout.println(Flags.FLAG_NETWORK_BLOCKED_FOR_TOP_SLEEPING_AND_ABOVE + ": " + mBackgroundNetworkRestricted); + fout.println(Flags.FLAG_USE_METERED_FIREWALL_CHAINS + ": " + + mUseMeteredFirewallChains); fout.println(); fout.println("mRestrictBackgroundLowPowerMode: " + mRestrictBackgroundLowPowerMode); @@ -5367,23 +5380,44 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { postUidRulesChangedMsg(uid, uidRules); } - // Note that the conditionals below are for avoiding unnecessary calls to netd. - // TODO: Measure the performance for doing a no-op call to netd so that we can - // remove the conditionals to simplify the logic below. We can also further reduce - // some calls to netd if they turn out to be costly. - final int denylistReasons = BLOCKED_METERED_REASON_ADMIN_DISABLED - | BLOCKED_METERED_REASON_USER_RESTRICTED; - if ((oldEffectiveBlockedReasons & denylistReasons) != BLOCKED_REASON_NONE - || (newEffectiveBlockedReasons & denylistReasons) != BLOCKED_REASON_NONE) { - setMeteredNetworkDenylist(uid, - (newEffectiveBlockedReasons & denylistReasons) != BLOCKED_REASON_NONE); - } - final int allowlistReasons = ALLOWED_METERED_REASON_FOREGROUND - | ALLOWED_METERED_REASON_USER_EXEMPTED; - if ((oldAllowedReasons & allowlistReasons) != ALLOWED_REASON_NONE - || (newAllowedReasons & allowlistReasons) != ALLOWED_REASON_NONE) { - setMeteredNetworkAllowlist(uid, - (newAllowedReasons & allowlistReasons) != ALLOWED_REASON_NONE); + if (mUseMeteredFirewallChains) { + if ((newEffectiveBlockedReasons & BLOCKED_METERED_REASON_ADMIN_DISABLED) + != BLOCKED_REASON_NONE) { + setUidFirewallRuleUL(FIREWALL_CHAIN_METERED_DENY_ADMIN, uid, FIREWALL_RULE_DENY); + } else { + setUidFirewallRuleUL(FIREWALL_CHAIN_METERED_DENY_ADMIN, uid, FIREWALL_RULE_DEFAULT); + } + if ((newEffectiveBlockedReasons & BLOCKED_METERED_REASON_USER_RESTRICTED) + != BLOCKED_REASON_NONE) { + setUidFirewallRuleUL(FIREWALL_CHAIN_METERED_DENY_USER, uid, FIREWALL_RULE_DENY); + } else { + setUidFirewallRuleUL(FIREWALL_CHAIN_METERED_DENY_USER, uid, FIREWALL_RULE_DEFAULT); + } + if ((newAllowedReasons & (ALLOWED_METERED_REASON_FOREGROUND + | ALLOWED_METERED_REASON_USER_EXEMPTED)) != ALLOWED_REASON_NONE) { + setUidFirewallRuleUL(FIREWALL_CHAIN_METERED_ALLOW, uid, FIREWALL_RULE_ALLOW); + } else { + setUidFirewallRuleUL(FIREWALL_CHAIN_METERED_ALLOW, uid, FIREWALL_RULE_DEFAULT); + } + } else { + // Note that the conditionals below are for avoiding unnecessary calls to netd. + // TODO: Measure the performance for doing a no-op call to netd so that we can + // remove the conditionals to simplify the logic below. We can also further reduce + // some calls to netd if they turn out to be costly. + final int denylistReasons = BLOCKED_METERED_REASON_ADMIN_DISABLED + | BLOCKED_METERED_REASON_USER_RESTRICTED; + if ((oldEffectiveBlockedReasons & denylistReasons) != BLOCKED_REASON_NONE + || (newEffectiveBlockedReasons & denylistReasons) != BLOCKED_REASON_NONE) { + setMeteredNetworkDenylist(uid, + (newEffectiveBlockedReasons & denylistReasons) != BLOCKED_REASON_NONE); + } + final int allowlistReasons = ALLOWED_METERED_REASON_FOREGROUND + | ALLOWED_METERED_REASON_USER_EXEMPTED; + if ((oldAllowedReasons & allowlistReasons) != ALLOWED_REASON_NONE + || (newAllowedReasons & allowlistReasons) != ALLOWED_REASON_NONE) { + setMeteredNetworkAllowlist(uid, + (newAllowedReasons & allowlistReasons) != ALLOWED_REASON_NONE); + } } } @@ -6143,6 +6177,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } else if (chain == FIREWALL_CHAIN_BACKGROUND) { mUidFirewallBackgroundRules.put(uid, rule); } + // Note that we do not need keep a separate cache of uid rules for chains that we do + // not call #setUidFirewallRulesUL for. try { mNetworkManager.setFirewallUidRule(chain, uid, rule); @@ -6200,10 +6236,19 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { FIREWALL_RULE_DEFAULT); mNetworkManager.setFirewallUidRule(FIREWALL_CHAIN_BACKGROUND, uid, FIREWALL_RULE_DEFAULT); - mNetworkManager.setUidOnMeteredNetworkAllowlist(uid, false); - mLogger.meteredAllowlistChanged(uid, false); - mNetworkManager.setUidOnMeteredNetworkDenylist(uid, false); - mLogger.meteredDenylistChanged(uid, false); + if (mUseMeteredFirewallChains) { + mNetworkManager.setFirewallUidRule(FIREWALL_CHAIN_METERED_DENY_ADMIN, uid, + FIREWALL_RULE_DEFAULT); + mNetworkManager.setFirewallUidRule(FIREWALL_CHAIN_METERED_DENY_USER, uid, + FIREWALL_RULE_DEFAULT); + mNetworkManager.setFirewallUidRule(FIREWALL_CHAIN_METERED_ALLOW, uid, + FIREWALL_RULE_DEFAULT); + } else { + mNetworkManager.setUidOnMeteredNetworkAllowlist(uid, false); + mLogger.meteredAllowlistChanged(uid, false); + mNetworkManager.setUidOnMeteredNetworkDenylist(uid, false); + mLogger.meteredDenylistChanged(uid, false); + } } catch (IllegalStateException e) { Log.wtf(TAG, "problem resetting firewall uid rules for " + uid, e); } catch (RemoteException e) { diff --git a/services/core/java/com/android/server/net/flags.aconfig b/services/core/java/com/android/server/net/flags.aconfig index d9491de52d87..e986dd81b94b 100644 --- a/services/core/java/com/android/server/net/flags.aconfig +++ b/services/core/java/com/android/server/net/flags.aconfig @@ -7,3 +7,13 @@ flag { description: "Block network access for apps in a low importance background state" bug: "304347838" } + +flag { + name: "use_metered_firewall_chains" + namespace: "backstage_power" + description: "Use metered firewall chains to control access to metered networks" + bug: "336693007" + metadata { + purpose: PURPOSE_BUGFIX + } +} diff --git a/services/core/java/com/android/server/pm/AppDataHelper.java b/services/core/java/com/android/server/pm/AppDataHelper.java index 79d17534ab26..348452e8f097 100644 --- a/services/core/java/com/android/server/pm/AppDataHelper.java +++ b/services/core/java/com/android/server/pm/AppDataHelper.java @@ -534,9 +534,12 @@ public class AppDataHelper { } else { storageFlags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE; } - List<String> deferPackages = reconcileAppsDataLI(StorageManager.UUID_PRIVATE_INTERNAL, - UserHandle.USER_SYSTEM, storageFlags, true /* migrateAppData */, - true /* onlyCoreApps */); + final List<String> deferPackages; + synchronized (mPm.mInstallLock) { + deferPackages = reconcileAppsDataLI(StorageManager.UUID_PRIVATE_INTERNAL, + UserHandle.USER_SYSTEM, storageFlags, true /* migrateAppData */, + true /* onlyCoreApps */); + } Future<?> prepareAppDataFuture = SystemServerInitThreadPool.submit(() -> { TimingsTraceLog traceLog = new TimingsTraceLog("SystemServerTimingAsync", Trace.TRACE_TAG_PACKAGE_MANAGER); diff --git a/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java b/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java index 93f26aefb692..c85ceac9ea55 100644 --- a/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java +++ b/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java @@ -642,6 +642,8 @@ public final class RollbackPackageHealthObserver implements PackageHealthObserve .getPackages() .get(0) .getVersionRolledBackFrom(); + Slog.i(TAG, "Rolling back high impact rollback for package: " + + firstRollback.getPackageName()); rollbackPackage(sortedHighImpactRollbacks.get(0), firstRollback, rollbackReason); } diff --git a/services/core/java/com/android/server/rollback/WatchdogRollbackLogger.java b/services/core/java/com/android/server/rollback/WatchdogRollbackLogger.java index 519c0edfc532..7fc02923bfed 100644 --- a/services/core/java/com/android/server/rollback/WatchdogRollbackLogger.java +++ b/services/core/java/com/android/server/rollback/WatchdogRollbackLogger.java @@ -293,6 +293,8 @@ public final class WatchdogRollbackLogger { return "REASON_APP_NOT_RESPONDING"; case WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_REASON__REASON_NATIVE_CRASH_DURING_BOOT: return "REASON_NATIVE_CRASH_DURING_BOOT"; + case WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_REASON__REASON_BOOT_LOOPING: + return "REASON_BOOT_LOOP"; default: return "UNKNOWN"; } diff --git a/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java b/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java index 622e70279700..54d101a3c1cf 100644 --- a/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java +++ b/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java @@ -243,12 +243,12 @@ public final class ProfcollectForwardingService extends SystemService { return; } sSelfService.mIProfcollect.process(); - jobFinished(params, false); } catch (RemoteException e) { Log.e(LOG_TAG, "Failed to process profiles in background: " + e.getMessage()); } }); + jobFinished(params, false); return true; } diff --git a/services/tests/apexsystemservices/OWNERS b/services/tests/apexsystemservices/OWNERS index 0295b9e99326..8b6675ad22d7 100644 --- a/services/tests/apexsystemservices/OWNERS +++ b/services/tests/apexsystemservices/OWNERS @@ -1,4 +1 @@ -omakoto@google.com -satayev@google.com - include platform/packages/modules/common:/OWNERS diff --git a/services/tests/servicestests/AndroidTest.xml b/services/tests/servicestests/AndroidTest.xml index b1d50399416a..84bafdac0a0c 100644 --- a/services/tests/servicestests/AndroidTest.xml +++ b/services/tests/servicestests/AndroidTest.xml @@ -25,6 +25,13 @@ value="/data/local/tmp/cts/content/broken_shortcut.xml" /> </target_preparer> + <target_preparer class="com.android.tradefed.targetprep.DeviceSetup"> + <option name="force-skip-system-props" value="true" /> + <option name="set-global-setting" key="verifier_engprod" value="1" /> + <option name="set-global-setting" key="verifier_verify_adb_installs" value="0" /> + <option name="restore-settings" value="true" /> + </target_preparer> + <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller"> <option name="cleanup-apks" value="true" /> <option name="install-arg" value="-t" /> diff --git a/services/tests/servicestests/src/com/android/server/audio/MusicFxHelperTest.java b/services/tests/servicestests/src/com/android/server/audio/MusicFxHelperTest.java index 472a82c02937..d5638e9346f6 100644 --- a/services/tests/servicestests/src/com/android/server/audio/MusicFxHelperTest.java +++ b/services/tests/servicestests/src/com/android/server/audio/MusicFxHelperTest.java @@ -57,8 +57,9 @@ public class MusicFxHelperTest { private ResolveInfo mResolveInfo1 = new ResolveInfo(); private ResolveInfo mResolveInfo2 = new ResolveInfo(); - private final String mTestPkg1 = "testPkg1", mTestPkg2 = "testPkg2", mTestPkg3 = "testPkg3"; - private final String mMusicFxPkgName = "com.android.musicfx"; + private final String mTestPkg1 = new String("testPkg1"), mTestPkg2 = new String("testPkg2"), + mTestPkg3 = new String("testPkg3"), mTestPkg1Equivalent = new String("testPkg1"); + private final String mMusicFxPkgName = new String("com.android.musicfx"); private final int mTestUid1 = 1, mTestUid2 = 2, mTestUid3 = 3, mMusicFxUid = 78; private final int mTestSession1 = 11, mTestSession2 = 22, mTestSession3 = 33; @@ -191,7 +192,8 @@ public class MusicFxHelperTest { public void testCloseBroadcastIntent() { Log.i(TAG, "running testCloseBroadcastIntent"); - closeSessionWithResList(null, 0, 0, null, mTestSession1, mTestUid1); + closeSessionWithResList(null, 0 /* unbind */, 0 /* broadcast */, null /* packageName */, + mTestSession1, mTestUid1); } /** @@ -225,8 +227,10 @@ public class MusicFxHelperTest { public void testBroadcastIntentWithNoPackageAndNoBroadcastReceiver() { Log.i(TAG, "running testBroadcastIntentWithNoPackageAndNoBroadcastReceiver"); - openSessionWithResList(mEmptyList, 0, 0, null, mTestSession1, mTestUid1); - closeSessionWithResList(mEmptyList, 0, 0, null, mTestSession1, mTestUid1); + openSessionWithResList(mEmptyList, 0 /* bind */, 0 /* broadcast */, null /* packageName */, + mTestSession1, mTestUid1); + closeSessionWithResList(mEmptyList, 0 /* unbind */, 0 /* broadcast */, + null /* packageName */, mTestSession1, mTestUid1); } /** @@ -236,37 +240,63 @@ public class MusicFxHelperTest { public void testBroadcastIntentWithNoPackageAndOneBroadcastReceiver() { Log.i(TAG, "running testBroadcastIntentWithNoPackageAndOneBroadcastReceiver"); + openSessionWithResList(mSingleList, 0 /* bind */, 0 /* broadcast */, + null /* packageName */, mTestSession1, mTestUid1); + closeSessionWithResList(mSingleList, 0 /* unbind */, 0 /* broadcast */, + null /* packageName */, mTestSession1, mTestUid1); + } + + /** + * OPEN/CLOSE AUDIO_EFFECT_CONTROL_SESSION with two broadcast receivers. + */ + @Test + public void testBroadcastIntentWithNoPackageAndTwoBroadcastReceivers() { + Log.i(TAG, "running testBroadcastIntentWithNoPackageAndTwoBroadcastReceivers"); + + openSessionWithResList(mDoubleList, 0 /* bind */, 0 /* broadcast */, + null /* packageName */, mTestSession1, mTestUid1); + closeSessionWithResList(mDoubleList, 0 /* bind */, 0 /* broadcast */, + null /* packageName */, mTestSession1, mTestUid1); + } + + @Test + public void testBroadcastIntentWithPackageAndOneBroadcastReceiver() { + Log.i(TAG, "running testBroadcastIntentWithPackageAndOneBroadcastReceiver"); + int broadcasts = 1, bind = 1, unbind = 1; - openSessionWithResList(mSingleList, bind, broadcasts, null, mTestSession1, mTestUid1); + openSessionWithResList(mSingleList, bind, broadcasts, mTestPkg1, mTestSession1, mTestUid1); + broadcasts = broadcasts + 1; - closeSessionWithResList(mSingleList, unbind, broadcasts, null, mTestSession1, mTestUid1); + closeSessionWithResList(mSingleList, unbind, broadcasts, mTestPkg1, mTestSession1, + mTestUid1); // repeat with different session ID broadcasts = broadcasts + 1; bind = bind + 1; unbind = unbind + 1; - openSessionWithResList(mSingleList, bind, broadcasts, null, mTestSession2, mTestUid1); + openSessionWithResList(mSingleList, bind, broadcasts, mTestPkg2, mTestSession2, mTestUid1); broadcasts = broadcasts + 1; - closeSessionWithResList(mSingleList, unbind, broadcasts, null, mTestSession2, mTestUid1); + closeSessionWithResList(mSingleList, unbind, broadcasts, mTestPkg2, mTestSession2, + mTestUid1); // repeat with different UID broadcasts = broadcasts + 1; bind = bind + 1; unbind = unbind + 1; - openSessionWithResList(mSingleList, bind, broadcasts, null, mTestSession1, mTestUid2); + openSessionWithResList(mSingleList, bind, broadcasts, mTestPkg3, mTestSession1, mTestUid2); broadcasts = broadcasts + 1; - closeSessionWithResList(mSingleList, unbind, broadcasts, null, mTestSession1, mTestUid2); + closeSessionWithResList(mSingleList, unbind, broadcasts, mTestPkg3, mTestSession1, + mTestUid2); } - /** - * OPEN/CLOSE AUDIO_EFFECT_CONTROL_SESSION with two broadcast receivers. - */ @Test - public void testBroadcastIntentWithNoPackageAndTwoBroadcastReceivers() { - Log.i(TAG, "running testBroadcastIntentWithNoPackageAndTwoBroadcastReceivers"); + public void testBroadcastIntentWithPackageAndTwoBroadcastReceivers() { + Log.i(TAG, "running testBroadcastIntentWithPackageAndTwoBroadcastReceivers"); - openSessionWithResList(mDoubleList, 1, 1, null, mTestSession1, mTestUid1); - closeSessionWithResList(mDoubleList, 1, 2, null, mTestSession1, mTestUid1); + openSessionWithResList(mDoubleList, 1 /* bind */, 1 /* broadcast */, + mTestPkg1 /* packageName */, mTestSession1, mTestUid1); + closeSessionWithResList(mDoubleList, 1 /* unbind */, 2 /* broadcast */, + mTestPkg1 /* packageName */, mTestSession1, mTestUid1); } /** @@ -639,4 +669,18 @@ public class MusicFxHelperTest { unbind = unbind + 1; sendMessage(MusicFxHelper.MSG_EFFECT_CLIENT_GONE, mTestUid3, unbind, broadcasts); } + + /** + * Test audio session open/close with same package name value but different String object. + */ + @Test + public void testSessionOpenCloseWithSamePackageNameValueButDiffObject() { + Log.i(TAG, "running testSessionOpenCloseWithSamePackageNameValueButDiffObject"); + int broadcasts = 1; + openSessionWithResList(mSingleList, 1 /* bind */, broadcasts, mTestPkg1, mTestSession1, + mTestUid1); + closeSessionWithResList(mSingleList, 1 /* unbind */, broadcasts + 1, mTestPkg1Equivalent, + mTestSession1, mTestUid1); + } + } diff --git a/services/tests/servicestests/src/com/android/server/net/NetworkManagementServiceTest.java b/services/tests/servicestests/src/com/android/server/net/NetworkManagementServiceTest.java index d6d2b6d9abd2..2a49a868d1f7 100644 --- a/services/tests/servicestests/src/com/android/server/net/NetworkManagementServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/net/NetworkManagementServiceTest.java @@ -19,9 +19,16 @@ package com.android.server.net; import static android.net.ConnectivityManager.FIREWALL_CHAIN_BACKGROUND; import static android.net.ConnectivityManager.FIREWALL_CHAIN_DOZABLE; import static android.net.ConnectivityManager.FIREWALL_CHAIN_LOW_POWER_STANDBY; +import static android.net.ConnectivityManager.FIREWALL_CHAIN_METERED_ALLOW; +import static android.net.ConnectivityManager.FIREWALL_CHAIN_METERED_DENY_ADMIN; +import static android.net.ConnectivityManager.FIREWALL_CHAIN_METERED_DENY_USER; import static android.net.ConnectivityManager.FIREWALL_CHAIN_POWERSAVE; import static android.net.ConnectivityManager.FIREWALL_CHAIN_RESTRICTED; import static android.net.ConnectivityManager.FIREWALL_CHAIN_STANDBY; +import static android.net.ConnectivityManager.FIREWALL_RULE_ALLOW; +import static android.net.ConnectivityManager.FIREWALL_RULE_DEFAULT; +import static android.net.ConnectivityManager.FIREWALL_RULE_DENY; +import static android.platform.test.flag.junit.SetFlagsRule.DefaultInitValueType.DEVICE_DEFAULT; import static android.util.DebugUtils.valueToString; import static org.junit.Assert.assertEquals; @@ -51,7 +58,10 @@ import android.os.PermissionEnforcer; import android.os.Process; import android.os.RemoteException; import android.os.test.FakePermissionEnforcer; +import android.platform.test.annotations.DisableFlags; +import android.platform.test.annotations.EnableFlags; import android.platform.test.annotations.Presubmit; +import android.platform.test.flag.junit.SetFlagsRule; import android.test.suitebuilder.annotation.SmallTest; import android.util.ArrayMap; @@ -62,6 +72,7 @@ import com.android.modules.utils.build.SdkLevel; import org.junit.After; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; @@ -84,6 +95,9 @@ public class NetworkManagementServiceTest { @Mock private IBatteryStats.Stub mBatteryStatsService; @Mock private INetd.Stub mNetdService; + @Rule + public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(DEVICE_DEFAULT); + private static final int TEST_UID = 111; @NonNull @@ -254,6 +268,7 @@ public class NetworkManagementServiceTest { } @Test + @DisableFlags(Flags.FLAG_USE_METERED_FIREWALL_CHAINS) public void testMeteredNetworkRestrictions() throws RemoteException { // Make sure the mocked netd method returns true. doReturn(true).when(mNetdService).bandwidthEnableDataSaver(anyBoolean()); @@ -295,6 +310,69 @@ public class NetworkManagementServiceTest { } @Test + @EnableFlags(Flags.FLAG_USE_METERED_FIREWALL_CHAINS) + public void testMeteredNetworkRestrictionsByAdminChain() { + mNMService.setFirewallUidRule(FIREWALL_CHAIN_METERED_DENY_ADMIN, TEST_UID, + FIREWALL_RULE_DENY); + verify(mCm).setUidFirewallRule(FIREWALL_CHAIN_METERED_DENY_ADMIN, TEST_UID, + FIREWALL_RULE_DENY); + assertTrue("Should be true since mobile data usage is restricted by admin chain", + mNMService.isNetworkRestricted(TEST_UID)); + + mNMService.setFirewallUidRule(FIREWALL_CHAIN_METERED_DENY_ADMIN, TEST_UID, + FIREWALL_RULE_DEFAULT); + verify(mCm).setUidFirewallRule(FIREWALL_CHAIN_METERED_DENY_ADMIN, TEST_UID, + FIREWALL_RULE_DEFAULT); + assertFalse("Should be false since mobile data usage is no longer restricted by admin", + mNMService.isNetworkRestricted(TEST_UID)); + } + + @Test + @EnableFlags(Flags.FLAG_USE_METERED_FIREWALL_CHAINS) + public void testMeteredNetworkRestrictionsByUserChain() { + mNMService.setFirewallUidRule(FIREWALL_CHAIN_METERED_DENY_USER, TEST_UID, + FIREWALL_RULE_DENY); + verify(mCm).setUidFirewallRule(FIREWALL_CHAIN_METERED_DENY_USER, TEST_UID, + FIREWALL_RULE_DENY); + assertTrue("Should be true since mobile data usage is restricted by user chain", + mNMService.isNetworkRestricted(TEST_UID)); + + mNMService.setFirewallUidRule(FIREWALL_CHAIN_METERED_DENY_USER, TEST_UID, + FIREWALL_RULE_DEFAULT); + verify(mCm).setUidFirewallRule(FIREWALL_CHAIN_METERED_DENY_USER, TEST_UID, + FIREWALL_RULE_DEFAULT); + assertFalse("Should be false since mobile data usage is no longer restricted by user", + mNMService.isNetworkRestricted(TEST_UID)); + } + + @Test + @EnableFlags(Flags.FLAG_USE_METERED_FIREWALL_CHAINS) + public void testDataSaverRestrictionsWithAllowChain() { + mNMService.setDataSaverModeEnabled(true); + verify(mCm).setDataSaverEnabled(true); + + assertTrue("Should be true since data saver is on and the uid is not allowlisted", + mNMService.isNetworkRestricted(TEST_UID)); + + mNMService.setFirewallUidRule(FIREWALL_CHAIN_METERED_ALLOW, TEST_UID, FIREWALL_RULE_ALLOW); + verify(mCm).setUidFirewallRule(FIREWALL_CHAIN_METERED_ALLOW, TEST_UID, FIREWALL_RULE_ALLOW); + assertFalse("Should be false since data saver is on and the uid is allowlisted", + mNMService.isNetworkRestricted(TEST_UID)); + + // remove uid from allowlist and turn datasaver off again + + mNMService.setFirewallUidRule(FIREWALL_CHAIN_METERED_ALLOW, TEST_UID, + FIREWALL_RULE_DEFAULT); + verify(mCm).setUidFirewallRule(FIREWALL_CHAIN_METERED_ALLOW, TEST_UID, + FIREWALL_RULE_DEFAULT); + mNMService.setDataSaverModeEnabled(false); + verify(mCm).setDataSaverEnabled(false); + + assertFalse("Network should not be restricted when data saver is off", + mNMService.isNetworkRestricted(TEST_UID)); + } + + @Test public void testFirewallChains() { final ArrayMap<Integer, ArrayMap<Integer, Boolean>> expected = new ArrayMap<>(); // Dozable chain diff --git a/tools/aapt/Symbol.h b/tools/aapt/Symbol.h index de1d60cbae42..24c3208d9081 100644 --- a/tools/aapt/Symbol.h +++ b/tools/aapt/Symbol.h @@ -40,7 +40,7 @@ struct Symbol { }; /** - * A specific defintion of a symbol, defined with a configuration and a definition site. + * A specific definition of a symbol, defined with a configuration and a definition site. */ struct SymbolDefinition { inline SymbolDefinition(); @@ -92,4 +92,3 @@ bool SymbolDefinition::operator<(const SymbolDefinition& rhs) const { } #endif // AAPT_SYMBOL_H - |