diff options
31 files changed, 847 insertions, 112 deletions
diff --git a/apct-tests/perftests/core/src/android/libcore/AdditionPerfTest.java b/apct-tests/perftests/core/src/android/libcore/AdditionPerfTest.java index ea3d172b2e5f..aa47e0a29695 100644 --- a/apct-tests/perftests/core/src/android/libcore/AdditionPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/AdditionPerfTest.java @@ -37,79 +37,71 @@ public class AdditionPerfTest { public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter(); @Test - public int timeAddConstantToLocalInt() { + public void timeAddConstantToLocalInt() { BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); int result = 0; while (state.keepRunning()) { result += 123; } - return result; } @Test - public int timeAddTwoLocalInts() { + public void timeAddTwoLocalInts() { BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); int result = 0; int constant = 123; while (state.keepRunning()) { result += constant; } - return result; } @Test - public long timeAddConstantToLocalLong() { + public void timeAddConstantToLocalLong() { BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); long result = 0; while (state.keepRunning()) { result += 123L; } - return result; } @Test - public long timeAddTwoLocalLongs() { + public void timeAddTwoLocalLongs() { BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); long result = 0; long constant = 123L; while (state.keepRunning()) { result += constant; } - return result; } @Test - public float timeAddConstantToLocalFloat() { + public void timeAddConstantToLocalFloat() { BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); float result = 0.0f; while (state.keepRunning()) { result += 123.0f; } - return result; } @Test - public float timeAddTwoLocalFloats() { + public void timeAddTwoLocalFloats() { BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); float result = 0.0f; float constant = 123.0f; while (state.keepRunning()) { result += constant; } - return result; } @Test - public double timeAddConstantToLocalDouble() { + public void timeAddConstantToLocalDouble() { BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); double result = 0.0; while (state.keepRunning()) { result += 123.0; } - return result; } @Test - public double timeAddTwoLocalDoubles() { + public void timeAddTwoLocalDoubles() { BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); double result = 0.0; double constant = 123.0; while (state.keepRunning()) { result += constant; } - return result; } } diff --git a/core/api/test-current.txt b/core/api/test-current.txt index 59db4d6b284c..d7c7bb174e45 100644 --- a/core/api/test-current.txt +++ b/core/api/test-current.txt @@ -683,6 +683,7 @@ package android.content { ctor public AttributionSource(int, @Nullable String, @Nullable String); ctor public AttributionSource(int, @Nullable String, @Nullable String, @NonNull android.os.IBinder); ctor public AttributionSource(int, @Nullable String, @Nullable String, @Nullable java.util.Set<java.lang.String>, @Nullable android.content.AttributionSource); + method public void enforceCallingPid(); } public final class AutofillOptions implements android.os.Parcelable { diff --git a/core/java/android/content/AttributionSource.java b/core/java/android/content/AttributionSource.java index 157e709a67f0..3f2fa2188d24 100644 --- a/core/java/android/content/AttributionSource.java +++ b/core/java/android/content/AttributionSource.java @@ -155,8 +155,8 @@ public final class AttributionSource implements Parcelable { this(AttributionSourceState.CREATOR.createFromParcel(in)); // Since we just unpacked this object as part of it transiting a Binder - // call, this is the perfect time to enforce that its UID can be trusted - enforceCallingUid(); + // call, this is the perfect time to enforce that its UID and PID can be trusted + enforceCallingUidAndPid(); } /** @hide */ @@ -259,13 +259,24 @@ public final class AttributionSource implements Parcelable { } /** + * If you are handling an IPC and you don't trust the caller you need to validate whether the + * attribution source is one for the calling app to prevent the caller to pass you a source from + * another app without including themselves in the attribution chain. + * + * @throws SecurityException if the attribution source cannot be trusted to be from the caller. + */ + private void enforceCallingUidAndPid() { + enforceCallingUid(); + enforceCallingPid(); + } + + /** * If you are handling an IPC and you don't trust the caller you need to validate * whether the attribution source is one for the calling app to prevent the caller * to pass you a source from another app without including themselves in the * attribution chain. * - * @throws SecurityException if the attribution source cannot be trusted to be - * from the caller. + * @throws SecurityException if the attribution source cannot be trusted to be from the caller. */ public void enforceCallingUid() { if (!checkCallingUid()) { @@ -294,6 +305,33 @@ public final class AttributionSource implements Parcelable { return true; } + /** + * Validate that the pid being claimed for the calling app is not spoofed + * + * @throws SecurityException if the attribution source cannot be trusted to be from the caller. + * @hide + */ + @TestApi + public void enforceCallingPid() { + if (!checkCallingPid()) { + throw new SecurityException("Calling pid: " + Binder.getCallingPid() + + " doesn't match source pid: " + mAttributionSourceState.pid); + } + } + + /** + * Validate that the pid being claimed for the calling app is not spoofed + * + * @return if the attribution source cannot be trusted to be from the caller. + */ + private boolean checkCallingPid() { + final int callingPid = Binder.getCallingPid(); + if (mAttributionSourceState.pid != -1 && callingPid != mAttributionSourceState.pid) { + return false; + } + return true; + } + @Override public String toString() { if (Build.IS_DEBUGGABLE) { diff --git a/core/java/android/content/pm/LauncherApps.java b/core/java/android/content/pm/LauncherApps.java index a8a5837385cb..0f9acadb11f9 100644 --- a/core/java/android/content/pm/LauncherApps.java +++ b/core/java/android/content/pm/LauncherApps.java @@ -739,7 +739,7 @@ public class LauncherApps { * {@link #startMainActivity(ComponentName, UserHandle, Rect, Bundle)}. * * @param component The ComponentName of the activity to launch - * @param startActivityOptions Options to pass to startActivity + * @param startActivityOptions This parameter is no longer supported * @param user The UserHandle of the profile * @hide */ @@ -751,7 +751,8 @@ public class LauncherApps { Log.i(TAG, "GetMainActivityLaunchIntent " + component + " " + user); } try { - return mService.getActivityLaunchIntent(component, startActivityOptions, user); + // due to b/209607104, startActivityOptions will be ignored + return mService.getActivityLaunchIntent(component, null /* opts */, user); } catch (RemoteException re) { throw re.rethrowFromSystemServer(); } @@ -846,7 +847,7 @@ public class LauncherApps { * * @param packageName The packageName of the shortcut * @param shortcutId The id of the shortcut - * @param opts Options to pass to the PendingIntent + * @param opts This parameter is no longer supported * @param user The UserHandle of the profile */ @Nullable @@ -858,8 +859,9 @@ public class LauncherApps { Log.i(TAG, "GetShortcutIntent " + packageName + "/" + shortcutId + " " + user); } try { + // due to b/209607104, opts will be ignored return mService.getShortcutIntent( - mContext.getPackageName(), packageName, shortcutId, opts, user); + mContext.getPackageName(), packageName, shortcutId, null /* opts */, user); } catch (RemoteException re) { throw re.rethrowFromSystemServer(); } diff --git a/core/java/android/debug/AdbManager.java b/core/java/android/debug/AdbManager.java index 7714dd80f910..243f80187185 100644 --- a/core/java/android/debug/AdbManager.java +++ b/core/java/android/debug/AdbManager.java @@ -38,6 +38,7 @@ public class AdbManager { * * @hide */ + @RequiresPermission(android.Manifest.permission.MANAGE_DEBUGGING) public static final String WIRELESS_DEBUG_STATE_CHANGED_ACTION = "com.android.server.adb.WIRELESS_DEBUG_STATUS"; @@ -46,6 +47,7 @@ public class AdbManager { * * @hide */ + @RequiresPermission(android.Manifest.permission.MANAGE_DEBUGGING) public static final String WIRELESS_DEBUG_PAIRED_DEVICES_ACTION = "com.android.server.adb.WIRELESS_DEBUG_PAIRED_DEVICES"; @@ -59,6 +61,7 @@ public class AdbManager { * * @hide */ + @RequiresPermission(android.Manifest.permission.MANAGE_DEBUGGING) public static final String WIRELESS_DEBUG_PAIRING_RESULT_ACTION = "com.android.server.adb.WIRELESS_DEBUG_PAIRING_RESULT"; diff --git a/core/java/android/net/Ikev2VpnProfile.java b/core/java/android/net/Ikev2VpnProfile.java index 1b503b11816f..ba0546aceb95 100644 --- a/core/java/android/net/Ikev2VpnProfile.java +++ b/core/java/android/net/Ikev2VpnProfile.java @@ -824,9 +824,9 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile { * authentication method may be set. This method will overwrite any previously set * authentication method. * - * <p>It's not allowed to set this if this {@link Builder} is constructed from an - * {@link IkeTunnelConnectionParams}. This information should be retrieved from - * {@link IkeTunnelConnectionParams} + * <p>If this {@link Builder} is constructed with an {@link IkeTunnelConnectionParams}, + * authentication details should be configured there, and calling this method will result + * in an exception being thrown. * * @param user the username to be used for EAP-MSCHAPv2 authentication * @param pass the password to be used for EAP-MSCHAPv2 authentication @@ -864,9 +864,9 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile { * Only one authentication method may be set. This method will overwrite any previously set * authentication method. * - * <p>It's not allowed to set this if this {@link Builder} is constructed from an - * {@link IkeTunnelConnectionParams}. This information should be retrieved from - * {@link IkeTunnelConnectionParams} + * <p>If this {@link Builder} is constructed with an {@link IkeTunnelConnectionParams}, + * authentication details should be configured there, and calling this method will result in + * an exception being thrown. * * @param userCert the username to be used for RSA Digital signiture authentication * @param key the PrivateKey instance associated with the user ceritificate, used for @@ -906,9 +906,9 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile { * authentication method may be set. This method will overwrite any previously set * authentication method. * - * <p>It's not allowed to set this if this {@link Builder} is constructed from an - * {@link IkeTunnelConnectionParams}. This information should be retrieved from - * {@link IkeTunnelConnectionParams} + * <p>If this {@link Builder} is constructed with an {@link IkeTunnelConnectionParams}, + * authentication details should be configured there, and calling this method will result in + * an exception being thrown. * * @param psk the key to be used for Pre-Shared Key authentication * @return this {@link Builder} object to facilitate chaining of method calls @@ -1042,9 +1042,9 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile { * Authentication, and one that provides Encryption. Authenticated Encryption with * Associated Data (AEAD) algorithms provide both Authentication and Encryption. * - * <p>It's not allowed to set this if this {@link Builder} is constructed from an - * {@link IkeTunnelConnectionParams}. This information should be retrieved from - * {@link IkeTunnelConnectionParams} + * <p>If this {@link Builder} is constructed with an {@link IkeTunnelConnectionParams}, + * authentication details should be configured there, and calling this method will result in + * an exception being thrown. * * <p>By default, this profile will use any algorithm defined in {@link IpSecAlgorithm}, * with the exception of those considered insecure (as described above). diff --git a/core/java/android/net/NetworkPolicyManager.java b/core/java/android/net/NetworkPolicyManager.java index 43ae4fc0a41b..2c2a703b16e2 100644 --- a/core/java/android/net/NetworkPolicyManager.java +++ b/core/java/android/net/NetworkPolicyManager.java @@ -176,6 +176,9 @@ public class NetworkPolicyManager { public static final int FOREGROUND_THRESHOLD_STATE = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE; + /** @hide */ + public static final int TOP_THRESHOLD_STATE = ActivityManager.PROCESS_STATE_BOUND_TOP; + /** * {@link Intent} extra that indicates which {@link NetworkTemplate} rule it * applies to. @@ -247,6 +250,20 @@ public class NetworkPolicyManager { */ public static final int ALLOWED_REASON_RESTRICTED_MODE_PERMISSIONS = 1 << 4; /** + * Flag to indicate that app is exempt from certain network restrictions because of it being + * in the bound top or top procstate. + * + * @hide + */ + public static final int ALLOWED_REASON_TOP = 1 << 5; + /** + * Flag to indicate that app is exempt from low power standby restrictions because of it being + * allowlisted. + * + * @hide + */ + public static final int ALLOWED_REASON_LOW_POWER_STANDBY_ALLOWLIST = 1 << 6; + /** * Flag to indicate that app is exempt from certain metered network restrictions because user * explicitly exempted it. * @@ -770,6 +787,14 @@ public class NetworkPolicyManager { || (capability & ActivityManager.PROCESS_CAPABILITY_NETWORK) != 0; } + /** @hide */ + public static boolean isProcStateAllowedWhileInLowPowerStandby(@Nullable UidState uidState) { + if (uidState == null) { + return false; + } + return uidState.procState <= TOP_THRESHOLD_STATE; + } + /** * Returns true if {@param procState} is considered foreground and as such will be allowed * to access network when the device is in data saver mode. Otherwise, false. diff --git a/core/java/com/android/internal/app/HarmfulAppWarningActivity.java b/core/java/com/android/internal/app/HarmfulAppWarningActivity.java index ce2d229d41b3..33209e110123 100644 --- a/core/java/com/android/internal/app/HarmfulAppWarningActivity.java +++ b/core/java/com/android/internal/app/HarmfulAppWarningActivity.java @@ -16,6 +16,8 @@ package com.android.internal.app; +import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS; + import android.content.Context; import android.content.DialogInterface; import android.content.Intent; @@ -27,6 +29,7 @@ import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.TextView; + import com.android.internal.R; /** @@ -48,6 +51,7 @@ public class HarmfulAppWarningActivity extends AlertActivity implements protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + getWindow().addSystemFlags(SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS); final Intent intent = getIntent(); mPackageName = intent.getStringExtra(Intent.EXTRA_PACKAGE_NAME); mTarget = intent.getParcelableExtra(Intent.EXTRA_INTENT); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java index f0b2716f05d8..a201616db208 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java @@ -825,6 +825,10 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, } private void fadeExistingPip(boolean show) { + if (mLeash == null || !mLeash.isValid()) { + Log.w(TAG, "Invalid leash on fadeExistingPip: " + mLeash); + return; + } final float alphaStart = show ? 0 : 1; final float alphaEnd = show ? 1 : 0; mPipAnimationController diff --git a/libs/hwui/jni/Bitmap.cpp b/libs/hwui/jni/Bitmap.cpp index 05278f24ebbd..4003f0b65fb5 100755 --- a/libs/hwui/jni/Bitmap.cpp +++ b/libs/hwui/jni/Bitmap.cpp @@ -686,16 +686,14 @@ static binder_status_t readBlob(AParcel* parcel, T inPlaceCallback, U ashmemCall } return data->ptr != nullptr; })); - inPlaceCallback(std::move(data.ptr), data.size); - return STATUS_OK; + return inPlaceCallback(std::move(data.ptr), data.size); } else if (type == BlobType::ASHMEM) { int rawFd = -1; int32_t size = 0; ON_ERROR_RETURN(AParcel_readInt32(parcel, &size)); ON_ERROR_RETURN(AParcel_readParcelFileDescriptor(parcel, &rawFd)); android::base::unique_fd fd(rawFd); - ashmemCallback(std::move(fd), size); - return STATUS_OK; + return ashmemCallback(std::move(fd), size); } else { // Although the above if/else was "exhaustive" guard against unknown types return STATUS_UNKNOWN_ERROR; @@ -768,7 +766,7 @@ static binder_status_t writeBlob(AParcel* parcel, const int32_t size, const void // framework, we may need to update this maximum size. static constexpr size_t kMaxColorSpaceSerializedBytes = 80; -static constexpr auto RuntimeException = "java/lang/RuntimeException"; +static constexpr auto BadParcelableException = "android/os/BadParcelableException"; static bool validateImageInfo(const SkImageInfo& info, int32_t rowBytes) { // TODO: Can we avoid making a SkBitmap for this? @@ -809,7 +807,7 @@ static jobject Bitmap_createFromParcel(JNIEnv* env, jobject, jobject parcel) { kRGB_565_SkColorType != colorType && kARGB_4444_SkColorType != colorType && kAlpha_8_SkColorType != colorType) { - jniThrowExceptionFmt(env, RuntimeException, + jniThrowExceptionFmt(env, BadParcelableException, "Bitmap_createFromParcel unknown colortype: %d\n", colorType); return NULL; } @@ -821,7 +819,7 @@ static jobject Bitmap_createFromParcel(JNIEnv* env, jobject, jobject parcel) { return NULL; } if (!Bitmap::computeAllocationSize(rowBytes, height, &allocationSize)) { - jniThrowExceptionFmt(env, RuntimeException, + jniThrowExceptionFmt(env, BadParcelableException, "Received bad bitmap size: width=%d, height=%d, rowBytes=%d", width, height, rowBytes); return NULL; @@ -831,13 +829,23 @@ static jobject Bitmap_createFromParcel(JNIEnv* env, jobject, jobject parcel) { p.get(), // In place callback [&](std::unique_ptr<int8_t[]> buffer, int32_t size) { + if (allocationSize > size) { + android_errorWriteLog(0x534e4554, "213169612"); + return STATUS_BAD_VALUE; + } nativeBitmap = Bitmap::allocateHeapBitmap(allocationSize, imageInfo, rowBytes); if (nativeBitmap) { - memcpy(nativeBitmap->pixels(), buffer.get(), size); + memcpy(nativeBitmap->pixels(), buffer.get(), allocationSize); + return STATUS_OK; } + return STATUS_NO_MEMORY; }, // Ashmem callback [&](android::base::unique_fd fd, int32_t size) { + if (allocationSize > size) { + android_errorWriteLog(0x534e4554, "213169612"); + return STATUS_BAD_VALUE; + } int flags = PROT_READ; if (isMutable) { flags |= PROT_WRITE; @@ -846,18 +854,21 @@ static jobject Bitmap_createFromParcel(JNIEnv* env, jobject, jobject parcel) { if (addr == MAP_FAILED) { const int err = errno; ALOGW("mmap failed, error %d (%s)", err, strerror(err)); - return; + return STATUS_NO_MEMORY; } nativeBitmap = Bitmap::createFrom(imageInfo, rowBytes, fd.release(), addr, size, !isMutable); + return STATUS_OK; }); - if (error != STATUS_OK) { + + if (error != STATUS_OK && error != STATUS_NO_MEMORY) { // TODO: Stringify the error, see signalExceptionForError in android_util_Binder.cpp - jniThrowExceptionFmt(env, RuntimeException, "Failed to read from Parcel, error=%d", error); + jniThrowExceptionFmt(env, BadParcelableException, "Failed to read from Parcel, error=%d", + error); return nullptr; } - if (!nativeBitmap) { - jniThrowRuntimeException(env, "Could not allocate java pixel ref."); + if (error == STATUS_NO_MEMORY || !nativeBitmap) { + jniThrowRuntimeException(env, "Could not allocate bitmap data."); return nullptr; } diff --git a/media/TEST_MAPPING b/media/TEST_MAPPING index a7ed09118817..4385a807774f 100644 --- a/media/TEST_MAPPING +++ b/media/TEST_MAPPING @@ -1,6 +1,14 @@ { "presubmit": [ { + "name": "CtsCameraTestCases", + "options" : [ + { + "include-filter": "android.hardware.camera2.cts.ImageReaderTest#testP010" + } + ] + }, + { "name": "GtsMediaTestCases", "options" : [ { diff --git a/media/jni/android_media_ImageReader.cpp b/media/jni/android_media_ImageReader.cpp index 5174c0c04dbf..f8066fee91de 100644 --- a/media/jni/android_media_ImageReader.cpp +++ b/media/jni/android_media_ImageReader.cpp @@ -589,6 +589,12 @@ static jint ImageReader_imageSetup(JNIEnv* env, jobject thiz, jobject image) { // (HAL_PIXEL_FORMAT_YCbCr_420_888) as HAL_PIXEL_FORMAT_YCbCr_420_888. ALOGV("%s: Treat buffer format to 0x%x as HAL_PIXEL_FORMAT_YCbCr_420_888", __FUNCTION__, bufferFormat); + } else if (imgReaderFmt == HAL_PIXEL_FORMAT_YCBCR_P010 && + isPossibly10BitYUV(bufferFormat)) { + // Treat formats that are compatible with flexible 10-bit YUV + // (HAL_PIXEL_FORMAT_YCBCR_P010) as HAL_PIXEL_FORMAT_YCBCR_P010. + ALOGV("%s: Treat buffer format to 0x%x as HAL_PIXEL_FORMAT_YCBCR_P010", + __FUNCTION__, bufferFormat); } else if (imgReaderFmt == HAL_PIXEL_FORMAT_BLOB && bufferFormat == HAL_PIXEL_FORMAT_RGBA_8888) { // Using HAL_PIXEL_FORMAT_RGBA_8888 Gralloc buffers containing JPEGs to get around diff --git a/media/jni/android_media_Utils.cpp b/media/jni/android_media_Utils.cpp index 39b560b393a9..f4a39b3469bb 100644 --- a/media/jni/android_media_Utils.cpp +++ b/media/jni/android_media_Utils.cpp @@ -17,7 +17,10 @@ // #define LOG_NDEBUG 0 #define LOG_TAG "AndroidMediaUtils" +#include <aidl/android/hardware/graphics/common/PlaneLayoutComponentType.h> #include <hardware/camera3.h> +#include <ui/GraphicBufferMapper.h> +#include <ui/GraphicTypes.h> #include <utils/Log.h> #include "android_media_Utils.h" @@ -81,6 +84,32 @@ bool isPossiblyYUV(PixelFormat format) { } } +bool isPossibly10BitYUV(PixelFormat format) { + switch (static_cast<int>(format)) { + case HAL_PIXEL_FORMAT_RGBA_8888: + case HAL_PIXEL_FORMAT_RGBX_8888: + case HAL_PIXEL_FORMAT_RGB_888: + case HAL_PIXEL_FORMAT_RGB_565: + case HAL_PIXEL_FORMAT_BGRA_8888: + case HAL_PIXEL_FORMAT_Y8: + case HAL_PIXEL_FORMAT_Y16: + case HAL_PIXEL_FORMAT_RAW16: + case HAL_PIXEL_FORMAT_RAW12: + case HAL_PIXEL_FORMAT_RAW10: + case HAL_PIXEL_FORMAT_RAW_OPAQUE: + case HAL_PIXEL_FORMAT_BLOB: + case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED: + case HAL_PIXEL_FORMAT_YV12: + case HAL_PIXEL_FORMAT_YCbCr_420_888: + case HAL_PIXEL_FORMAT_YCrCb_420_SP: + return false; + + case HAL_PIXEL_FORMAT_YCBCR_P010: + default: + return true; + } +} + uint32_t Image_getBlobSize(LockedImage* buffer, bool usingRGBAOverride) { ALOGV("%s", __FUNCTION__); LOG_ALWAYS_FATAL_IF(buffer == NULL, "Input buffer is NULL!!!"); @@ -279,6 +308,27 @@ status_t getLockedImageInfo(LockedImage* buffer, int idx, return BAD_VALUE; } + if (buffer->dataCb && buffer->dataCr) { + pData = + (idx == 0) ? + buffer->data : + (idx == 1) ? + buffer->dataCb : + buffer->dataCr; + // only map until last pixel + if (idx == 0) { + pStride = 2; + rStride = buffer->stride; + dataSize = buffer->stride * (buffer->height - 1) + buffer->width * 2; + } else { + pStride = buffer->chromaStep; + rStride = buffer->chromaStride; + dataSize = buffer->chromaStride * (buffer->height / 2 - 1) + + buffer->chromaStep * (buffer->width / 2); + } + break; + } + ySize = (buffer->stride * 2) * buffer->height; cSize = ySize / 2; pStride = (idx == 0) ? 2 : 4; @@ -404,6 +454,7 @@ status_t getLockedImageInfo(LockedImage* buffer, int idx, rStride = buffer->stride * 3; break; default: + ALOGV("%s: unrecognized format 0x%x", __FUNCTION__, fmt); return BAD_VALUE; } @@ -415,6 +466,79 @@ status_t getLockedImageInfo(LockedImage* buffer, int idx, return OK; } +static status_t extractP010Gralloc4PlaneLayout( + sp<GraphicBuffer> buffer, void *pData, int format, LockedImage *outputImage) { + using aidl::android::hardware::graphics::common::PlaneLayoutComponent; + using aidl::android::hardware::graphics::common::PlaneLayoutComponentType; + + GraphicBufferMapper& mapper = GraphicBufferMapper::get(); + std::vector<ui::PlaneLayout> planeLayouts; + status_t res = mapper.getPlaneLayouts(buffer->handle, &planeLayouts); + if (res != OK) { + return res; + } + constexpr int64_t Y_PLANE_COMPONENTS = int64_t(PlaneLayoutComponentType::Y); + constexpr int64_t CBCR_PLANE_COMPONENTS = + int64_t(PlaneLayoutComponentType::CB) | int64_t(PlaneLayoutComponentType::CR); + uint8_t *dataY = nullptr; + uint8_t *dataCb = nullptr; + uint8_t *dataCr = nullptr; + uint32_t strideY = 0; + uint32_t strideCbCr = 0; + for (const ui::PlaneLayout &layout : planeLayouts) { + ALOGV("gralloc4 plane: %s", layout.toString().c_str()); + int64_t components = 0; + for (const PlaneLayoutComponent &component : layout.components) { + if (component.sizeInBits != 10) { + return BAD_VALUE; + } + components |= component.type.value; + } + if (components == Y_PLANE_COMPONENTS) { + if (layout.sampleIncrementInBits != 16) { + return BAD_VALUE; + } + if (layout.components[0].offsetInBits != 6) { + return BAD_VALUE; + } + dataY = (uint8_t *)pData + layout.offsetInBytes; + strideY = layout.strideInBytes; + } else if (components == CBCR_PLANE_COMPONENTS) { + if (layout.sampleIncrementInBits != 32) { + return BAD_VALUE; + } + for (const PlaneLayoutComponent &component : layout.components) { + if (component.type.value == int64_t(PlaneLayoutComponentType::CB) + && component.offsetInBits != 6) { + return BAD_VALUE; + } + if (component.type.value == int64_t(PlaneLayoutComponentType::CR) + && component.offsetInBits != 22) { + return BAD_VALUE; + } + } + dataCb = (uint8_t *)pData + layout.offsetInBytes; + dataCr = (uint8_t *)pData + layout.offsetInBytes + 2; + strideCbCr = layout.strideInBytes; + } else { + return BAD_VALUE; + } + } + + outputImage->data = dataY; + outputImage->width = buffer->getWidth(); + outputImage->height = buffer->getHeight(); + outputImage->format = format; + outputImage->flexFormat = HAL_PIXEL_FORMAT_YCBCR_P010; + outputImage->stride = strideY; + + outputImage->dataCb = dataCb; + outputImage->dataCr = dataCr; + outputImage->chromaStride = strideCbCr; + outputImage->chromaStep = 4; + return OK; +} + status_t lockImageFromBuffer(sp<GraphicBuffer> buffer, uint32_t inUsage, const Rect& rect, int fenceFd, LockedImage* outputImage) { ALOGV("%s: Try to lock the GraphicBuffer", __FUNCTION__); @@ -433,11 +557,12 @@ status_t lockImageFromBuffer(sp<GraphicBuffer> buffer, uint32_t inUsage, status_t res; int format = buffer->getPixelFormat(); int flexFormat = format; + if (isPossiblyYUV(format)) { res = buffer->lockAsyncYCbCr(inUsage, rect, &ycbcr, fenceFd); if (res != OK) { - ALOGW("lockAsyncYCbCr failed with error %d", res); + ALOGW("lockAsyncYCbCr failed with error %d (format = 0x%x)", res, format); } pData = ycbcr.y; @@ -451,6 +576,11 @@ status_t lockImageFromBuffer(sp<GraphicBuffer> buffer, uint32_t inUsage, ALOGE("Lock buffer failed!"); return res; } + if (isPossibly10BitYUV(format) + && OK == extractP010Gralloc4PlaneLayout(buffer, pData, format, outputImage)) { + ALOGV("%s: Successfully locked the P010 image", __FUNCTION__); + return OK; + } } outputImage->data = reinterpret_cast<uint8_t*>(pData); diff --git a/media/jni/android_media_Utils.h b/media/jni/android_media_Utils.h index 12841c097943..4feb4f516f1e 100644 --- a/media/jni/android_media_Utils.h +++ b/media/jni/android_media_Utils.h @@ -35,6 +35,8 @@ bool isFormatOpaque(int format); bool isPossiblyYUV(PixelFormat format); +bool isPossibly10BitYUV(PixelFormat format); + status_t getLockedImageInfo(LockedImage* buffer, int idx, int32_t containerFormat, uint8_t **base, uint32_t *size, int *pixelStride, int *rowStride); diff --git a/packages/SettingsLib/res/drawable/ic_4g_lte_mobiledata.xml b/packages/SettingsLib/res/drawable/ic_4g_lte_mobiledata.xml new file mode 100644 index 000000000000..43a82fa2d86e --- /dev/null +++ b/packages/SettingsLib/res/drawable/ic_4g_lte_mobiledata.xml @@ -0,0 +1,25 @@ +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="42.3281dp" + android:height="24dp" + android:viewportWidth="42.3281" + android:viewportHeight="24"> + <path + android:fillColor="#FFFFFFFF" + android:pathData="M10.7871,12.959H11.8477V14.1016H10.7871V16H9.3633V14.1016H5.6777L5.6367,13.2344L9.3164,7.4688H10.7871V12.959ZM7.1309,12.959H9.3633V9.3965L9.2578,9.584L7.1309,12.959ZM19.5586,14.8926C19.25,15.2949 18.8223,15.5996 18.2754,15.8066C17.7285,16.0137 17.1074,16.1172 16.4121,16.1172C15.6973,16.1172 15.0645,15.9551 14.5137,15.6309C13.9629,15.3066 13.5371,14.8438 13.2363,14.2422C12.9395,13.6367 12.7852,12.9316 12.7734,12.127V11.459C12.7734,10.1699 13.082,9.1641 13.6992,8.4414C14.3164,7.7148 15.1777,7.3516 16.2832,7.3516C17.2324,7.3516 17.9863,7.5859 18.5449,8.0547C19.1035,8.5234 19.4395,9.1992 19.5527,10.082H18.0996C17.9355,9.0547 17.3398,8.541 16.3125,8.541C15.6484,8.541 15.1426,8.7813 14.7949,9.2617C14.4512,9.7383 14.2734,10.4395 14.2617,11.3652V12.0215C14.2617,12.9434 14.4551,13.6602 14.8418,14.1719C15.2324,14.6797 15.7734,14.9336 16.4648,14.9336C17.2227,14.9336 17.7617,14.7617 18.082,14.418V12.748H16.3242V11.623H19.5586V14.8926ZM25.6582,14.8164H29.5312V16H24.1758V7.4688H25.6582V14.8164ZM35.625,8.6641H32.9648V16H31.4941V8.6641H28.8574V7.4688H35.625V8.6641ZM41.7363,12.1914H38.2324V14.8164H42.3281V16H36.75V7.4688H42.2871V8.6641H38.2324V11.0195H41.7363V12.1914Z" /> + +</vector> diff --git a/packages/SettingsLib/res/drawable/ic_4g_lte_plus_mobiledata.xml b/packages/SettingsLib/res/drawable/ic_4g_lte_plus_mobiledata.xml new file mode 100644 index 000000000000..b80c47af23d2 --- /dev/null +++ b/packages/SettingsLib/res/drawable/ic_4g_lte_plus_mobiledata.xml @@ -0,0 +1,29 @@ +<!-- + Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="49.65dp" + android:height="24dp" + android:viewportWidth="49.65" + android:viewportHeight="24"> + <path + android:fillColor="#FFFFFFFF" + android:pathData="M10.7871,12.959H11.8477V14.1016H10.7871V16H9.3633V14.1016H5.6777L5.6367,13.2344L9.3164,7.4688H10.7871V12.959ZM7.1309,12.959H9.3633V9.3965L9.2578,9.584L7.1309,12.959ZM19.5586,14.8926C19.25,15.2949 18.8223,15.5996 18.2754,15.8066C17.7285,16.0137 17.1074,16.1172 16.4121,16.1172C15.6973,16.1172 15.0645,15.9551 14.5137,15.6309C13.9629,15.3066 13.5371,14.8438 13.2363,14.2422C12.9395,13.6367 12.7852,12.9316 12.7734,12.127V11.459C12.7734,10.1699 13.082,9.1641 13.6992,8.4414C14.3164,7.7148 15.1777,7.3516 16.2832,7.3516C17.2324,7.3516 17.9863,7.5859 18.5449,8.0547C19.1035,8.5234 19.4395,9.1992 19.5527,10.082H18.0996C17.9355,9.0547 17.3398,8.541 16.3125,8.541C15.6484,8.541 15.1426,8.7813 14.7949,9.2617C14.4512,9.7383 14.2734,10.4395 14.2617,11.3652V12.0215C14.2617,12.9434 14.4551,13.6602 14.8418,14.1719C15.2324,14.6797 15.7734,14.9336 16.4648,14.9336C17.2227,14.9336 17.7617,14.7617 18.082,14.418V12.748H16.3242V11.623H19.5586V14.8926ZM25.6582,14.8164H29.5312V16H24.1758V7.4688H25.6582V14.8164ZM35.625,8.6641H32.9648V16H31.4941V8.6641H28.8574V7.4688H35.625V8.6641ZM41.7363,12.1914H38.2324V14.8164H42.3281V16H36.75V7.4688H42.2871V8.6641H38.2324V11.0195H41.7363V12.1914Z" /> + + <path + android:fillColor="#FFFFFFFF" + android:pathData="M 47.3 9.74L 47.3 7.39L 46 7.39L 46 9.74L 43.65 9.74L 43.65 11.04L 46 11.04L 46 13.39L 47.3 13.39L 47.3 11.04L 49.65 11.04L 49.65 9.74Z" /> + +</vector> diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml index 534e41c42467..6ca15c1f3fc3 100644 --- a/packages/SettingsLib/res/values/strings.xml +++ b/packages/SettingsLib/res/values/strings.xml @@ -1478,6 +1478,12 @@ <!-- Content description of the data connection type LTE+. [CHAR LIMIT=NONE] --> <string name="data_connection_lte_plus">LTE+</string> + <!-- Content description of the data connection type 4G LTE . [CHAR LIMIT=NONE] --> + <string name="data_connection_4g_lte" translatable="false">4G LTE</string> + + <!-- Content description of the data connection type 4G LTE+ . [CHAR LIMIT=NONE] --> + <string name="data_connection_4g_lte_plus" translatable="false">4G LTE+</string> + <!-- Content description of the data connection type 5Ge with HTML styling. DO NOT TRANSLATE [CHAR LIMIT=NONE] --> <string name="data_connection_5ge_html" translate="false"> <i>5G <small>E</small></i> </string> diff --git a/packages/SettingsLib/src/com/android/settingslib/mobile/MobileMappings.java b/packages/SettingsLib/src/com/android/settingslib/mobile/MobileMappings.java index 5e91a147318e..c94195477cfc 100644 --- a/packages/SettingsLib/src/com/android/settingslib/mobile/MobileMappings.java +++ b/packages/SettingsLib/src/com/android/settingslib/mobile/MobileMappings.java @@ -160,6 +160,19 @@ public class MobileMappings { TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_LTE_CA), TelephonyIcons.FOUR_G_PLUS); } + } else if (config.show4glteForLte) { + networkToIconLookup.put(toIconKey( + TelephonyManager.NETWORK_TYPE_LTE), + TelephonyIcons.FOUR_G_LTE); + if (config.hideLtePlus) { + networkToIconLookup.put(toDisplayIconKey( + TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_LTE_CA), + TelephonyIcons.FOUR_G_LTE); + } else { + networkToIconLookup.put(toDisplayIconKey( + TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_LTE_CA), + TelephonyIcons.FOUR_G_LTE_PLUS); + } } else { networkToIconLookup.put(toIconKey( TelephonyManager.NETWORK_TYPE_LTE), @@ -200,6 +213,7 @@ public class MobileMappings { public boolean show4gFor3g = false; public boolean alwaysShowCdmaRssi = false; public boolean show4gForLte = false; + public boolean show4glteForLte = false; public boolean hideLtePlus = false; public boolean hspaDataDistinguishable; public boolean alwaysShowDataRatIcon = false; @@ -228,6 +242,8 @@ public class MobileMappings { CarrierConfigManager.KEY_ALWAYS_SHOW_DATA_RAT_ICON_BOOL); config.show4gForLte = b.getBoolean( CarrierConfigManager.KEY_SHOW_4G_FOR_LTE_DATA_ICON_BOOL); + config.show4glteForLte = b.getBoolean( + CarrierConfigManager.KEY_SHOW_4GLTE_FOR_LTE_DATA_ICON_BOOL); config.show4gFor3g = b.getBoolean( CarrierConfigManager.KEY_SHOW_4G_FOR_3G_DATA_ICON_BOOL); config.hideLtePlus = b.getBoolean( diff --git a/packages/SettingsLib/src/com/android/settingslib/mobile/TelephonyIcons.java b/packages/SettingsLib/src/com/android/settingslib/mobile/TelephonyIcons.java index d4e58f7a2fc4..23e0923d7280 100644 --- a/packages/SettingsLib/src/com/android/settingslib/mobile/TelephonyIcons.java +++ b/packages/SettingsLib/src/com/android/settingslib/mobile/TelephonyIcons.java @@ -39,6 +39,8 @@ public class TelephonyIcons { public static final int ICON_3G = R.drawable.ic_3g_mobiledata; public static final int ICON_4G = R.drawable.ic_4g_mobiledata; public static final int ICON_4G_PLUS = R.drawable.ic_4g_plus_mobiledata; + public static final int ICON_4G_LTE = R.drawable.ic_4g_lte_mobiledata; + public static final int ICON_4G_LTE_PLUS = R.drawable.ic_4g_lte_plus_mobiledata; public static final int ICON_5G_E = R.drawable.ic_5g_e_mobiledata; public static final int ICON_1X = R.drawable.ic_1x_mobiledata; public static final int ICON_5G = R.drawable.ic_5g_mobiledata; @@ -225,6 +227,34 @@ public class TelephonyIcons { TelephonyIcons.ICON_LTE_PLUS ); + public static final MobileIconGroup FOUR_G_LTE = new MobileIconGroup( + "4G LTE", + null, + null, + AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH, + 0, + 0, + 0, + 0, + AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH[0], + R.string.data_connection_4g_lte, + TelephonyIcons.ICON_4G_LTE + ); + + public static final MobileIconGroup FOUR_G_LTE_PLUS = new MobileIconGroup( + "4G LTE+", + null, + null, + AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH, + 0, + 0, + 0, + 0, + AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH[0], + R.string.data_connection_4g_lte_plus, + TelephonyIcons.ICON_4G_LTE_PLUS + ); + public static final MobileIconGroup LTE_CA_5G_E = new MobileIconGroup( "5Ge", null, @@ -327,6 +357,8 @@ public class TelephonyIcons { ICON_NAME_TO_ICON.put("h+", H_PLUS); ICON_NAME_TO_ICON.put("4g", FOUR_G); ICON_NAME_TO_ICON.put("4g+", FOUR_G_PLUS); + ICON_NAME_TO_ICON.put("4glte", FOUR_G_LTE); + ICON_NAME_TO_ICON.put("4glte+", FOUR_G_LTE_PLUS); ICON_NAME_TO_ICON.put("5ge", LTE_CA_5G_E); ICON_NAME_TO_ICON.put("lte", LTE); ICON_NAME_TO_ICON.put("lte+", LTE_PLUS); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java index f14cc93c2046..9f440606a365 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java @@ -279,11 +279,11 @@ public class NotificationStackScrollLayoutController { @Override public void onThemeChanged() { - updateShowEmptyShadeView(); mView.updateCornerRadius(); mView.updateBgColor(); mView.updateDecorViews(); mView.reinflateViews(); + updateShowEmptyShadeView(); updateFooter(); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java index 2c70a5fd9ce7..c4567df914f0 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java @@ -376,6 +376,11 @@ public class StackScrollAlgorithm { final float stackHeight = ambientState.getStackHeight() - shelfHeight - scrimPadding; final float stackEndHeight = ambientState.getStackEndHeight() - shelfHeight - scrimPadding; + if (stackEndHeight == 0f) { + // This should not happen, since even when the shade is empty we show EmptyShadeView + // but check just in case, so we don't return infinity or NaN. + return 0f; + } return stackHeight / stackEndHeight; } diff --git a/services/core/java/com/android/server/adb/AdbDebuggingManager.java b/services/core/java/com/android/server/adb/AdbDebuggingManager.java index f591b26f1770..297d28dadde3 100644 --- a/services/core/java/com/android/server/adb/AdbDebuggingManager.java +++ b/services/core/java/com/android/server/adb/AdbDebuggingManager.java @@ -18,6 +18,7 @@ package com.android.server.adb; import static com.android.internal.util.dump.DumpUtils.writeStringIfNotNull; +import android.annotation.NonNull; import android.annotation.TestApi; import android.app.ActivityManager; import android.app.Notification; @@ -170,6 +171,12 @@ public class AdbDebuggingManager { mAdbConnectionInfo = new AdbConnectionInfo(); } + static void sendBroadcastWithDebugPermission(@NonNull Context context, @NonNull Intent intent, + @NonNull UserHandle userHandle) { + context.sendBroadcastAsUser(intent, userHandle, + android.Manifest.permission.MANAGE_DEBUGGING); + } + class PairingThread extends Thread implements NsdManager.RegistrationListener { private NsdManager mNsdManager; private String mPublicKey; @@ -1278,7 +1285,7 @@ public class AdbDebuggingManager { ? AdbManager.WIRELESS_STATUS_CONNECTED : AdbManager.WIRELESS_STATUS_DISCONNECTED); intent.putExtra(AdbManager.WIRELESS_DEBUG_PORT_EXTRA, port); - mContext.sendBroadcastAsUser(intent, UserHandle.ALL); + AdbDebuggingManager.sendBroadcastWithDebugPermission(mContext, intent, UserHandle.ALL); } private void onAdbdWifiServerConnected(int port) { @@ -1350,7 +1357,8 @@ public class AdbDebuggingManager { if (publicKey == null) { Intent intent = new Intent(AdbManager.WIRELESS_DEBUG_PAIRING_RESULT_ACTION); intent.putExtra(AdbManager.WIRELESS_STATUS_EXTRA, AdbManager.WIRELESS_STATUS_FAIL); - mContext.sendBroadcastAsUser(intent, UserHandle.ALL); + AdbDebuggingManager.sendBroadcastWithDebugPermission(mContext, intent, + UserHandle.ALL); } else { Intent intent = new Intent(AdbManager.WIRELESS_DEBUG_PAIRING_RESULT_ACTION); intent.putExtra(AdbManager.WIRELESS_STATUS_EXTRA, @@ -1366,7 +1374,8 @@ public class AdbDebuggingManager { device.guid = hostname; device.connected = false; intent.putExtra(AdbManager.WIRELESS_PAIR_DEVICE_EXTRA, device); - mContext.sendBroadcastAsUser(intent, UserHandle.ALL); + AdbDebuggingManager.sendBroadcastWithDebugPermission(mContext, intent, + UserHandle.ALL); // Add the key into the keystore mAdbKeyStore.setLastConnectionTime(publicKey, System.currentTimeMillis()); @@ -1380,14 +1389,14 @@ public class AdbDebuggingManager { intent.putExtra(AdbManager.WIRELESS_STATUS_EXTRA, AdbManager.WIRELESS_STATUS_CONNECTED); intent.putExtra(AdbManager.WIRELESS_DEBUG_PORT_EXTRA, port); - mContext.sendBroadcastAsUser(intent, UserHandle.ALL); + AdbDebuggingManager.sendBroadcastWithDebugPermission(mContext, intent, UserHandle.ALL); } private void sendPairedDevicesToUI(Map<String, PairDevice> devices) { Intent intent = new Intent(AdbManager.WIRELESS_DEBUG_PAIRED_DEVICES_ACTION); // Map is not serializable, so need to downcast intent.putExtra(AdbManager.WIRELESS_DEVICES_EXTRA, (HashMap) devices); - mContext.sendBroadcastAsUser(intent, UserHandle.ALL); + AdbDebuggingManager.sendBroadcastWithDebugPermission(mContext, intent, UserHandle.ALL); } private void updateUIPairCode(String code) { @@ -1397,7 +1406,7 @@ public class AdbDebuggingManager { intent.putExtra(AdbManager.WIRELESS_PAIRING_CODE_EXTRA, code); intent.putExtra(AdbManager.WIRELESS_STATUS_EXTRA, AdbManager.WIRELESS_STATUS_PAIRING_CODE); - mContext.sendBroadcastAsUser(intent, UserHandle.ALL); + AdbDebuggingManager.sendBroadcastWithDebugPermission(mContext, intent, UserHandle.ALL); } } diff --git a/services/core/java/com/android/server/adb/AdbService.java b/services/core/java/com/android/server/adb/AdbService.java index 7a4d2ce50cd3..2845fbfc6ebf 100644 --- a/services/core/java/com/android/server/adb/AdbService.java +++ b/services/core/java/com/android/server/adb/AdbService.java @@ -459,7 +459,7 @@ public class AdbService extends IAdbManager.Stub { ? AdbManager.WIRELESS_STATUS_CONNECTED : AdbManager.WIRELESS_STATUS_DISCONNECTED); intent.putExtra(AdbManager.WIRELESS_DEBUG_PORT_EXTRA, port); - mContext.sendBroadcastAsUser(intent, UserHandle.ALL); + AdbDebuggingManager.sendBroadcastWithDebugPermission(mContext, intent, UserHandle.ALL); Slog.i(TAG, "sent port broadcast port=" + port); } diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerInternal.java b/services/core/java/com/android/server/net/NetworkPolicyManagerInternal.java index 8ef42ff97aad..3cb587812c2a 100644 --- a/services/core/java/com/android/server/net/NetworkPolicyManagerInternal.java +++ b/services/core/java/com/android/server/net/NetworkPolicyManagerInternal.java @@ -91,4 +91,10 @@ public abstract class NetworkPolicyManagerInternal { */ public abstract void setMeteredRestrictedPackagesAsync( Set<String> packageNames, int userId); + + /** Informs that Low Power Standby has become active */ + public abstract void setLowPowerStandbyActive(boolean active); + + /** Informs that the Low Power Standby allowlist has changed */ + public abstract void setLowPowerStandbyAllowlist(int[] uids); } diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java index 67b44696d326..ea851ba9669f 100644 --- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java +++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java @@ -46,17 +46,19 @@ import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_USER_RESTRI import static android.net.ConnectivityManager.BLOCKED_REASON_APP_STANDBY; import static android.net.ConnectivityManager.BLOCKED_REASON_BATTERY_SAVER; import static android.net.ConnectivityManager.BLOCKED_REASON_DOZE; +import static android.net.ConnectivityManager.BLOCKED_REASON_LOW_POWER_STANDBY; import static android.net.ConnectivityManager.BLOCKED_REASON_NONE; import static android.net.ConnectivityManager.BLOCKED_REASON_RESTRICTED_MODE; import static android.net.ConnectivityManager.CONNECTIVITY_ACTION; +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_POWERSAVE; +import static android.net.ConnectivityManager.FIREWALL_CHAIN_RESTRICTED; +import static android.net.ConnectivityManager.FIREWALL_CHAIN_STANDBY; import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLED; import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED; import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_WHITELISTED; import static android.net.ConnectivityManager.TYPE_MOBILE; -import static android.net.INetd.FIREWALL_CHAIN_DOZABLE; -import static android.net.INetd.FIREWALL_CHAIN_POWERSAVE; -import static android.net.INetd.FIREWALL_CHAIN_RESTRICTED; -import static android.net.INetd.FIREWALL_CHAIN_STANDBY; import static android.net.INetd.FIREWALL_RULE_ALLOW; import static android.net.INetd.FIREWALL_RULE_DENY; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED; @@ -69,11 +71,13 @@ import static android.net.NetworkPolicyManager.ALLOWED_METERED_REASON_MASK; import static android.net.NetworkPolicyManager.ALLOWED_METERED_REASON_SYSTEM; import static android.net.NetworkPolicyManager.ALLOWED_METERED_REASON_USER_EXEMPTED; import static android.net.NetworkPolicyManager.ALLOWED_REASON_FOREGROUND; +import static android.net.NetworkPolicyManager.ALLOWED_REASON_LOW_POWER_STANDBY_ALLOWLIST; import static android.net.NetworkPolicyManager.ALLOWED_REASON_NONE; import static android.net.NetworkPolicyManager.ALLOWED_REASON_POWER_SAVE_ALLOWLIST; import static android.net.NetworkPolicyManager.ALLOWED_REASON_POWER_SAVE_EXCEPT_IDLE_ALLOWLIST; import static android.net.NetworkPolicyManager.ALLOWED_REASON_RESTRICTED_MODE_PERMISSIONS; import static android.net.NetworkPolicyManager.ALLOWED_REASON_SYSTEM; +import static android.net.NetworkPolicyManager.ALLOWED_REASON_TOP; import static android.net.NetworkPolicyManager.EXTRA_NETWORK_TEMPLATE; import static android.net.NetworkPolicyManager.FIREWALL_RULE_DEFAULT; import static android.net.NetworkPolicyManager.POLICY_ALLOW_METERED_BACKGROUND; @@ -87,6 +91,7 @@ import static android.net.NetworkPolicyManager.RULE_REJECT_RESTRICTED_MODE; import static android.net.NetworkPolicyManager.RULE_TEMPORARY_ALLOW_METERED; import static android.net.NetworkPolicyManager.SUBSCRIPTION_OVERRIDE_UNMETERED; import static android.net.NetworkPolicyManager.isProcStateAllowedWhileIdleOrPowerSaveMode; +import static android.net.NetworkPolicyManager.isProcStateAllowedWhileInLowPowerStandby; import static android.net.NetworkPolicyManager.isProcStateAllowedWhileOnRestrictBackground; import static android.net.NetworkPolicyManager.resolveNetworkId; import static android.net.NetworkPolicyManager.uidPoliciesToString; @@ -477,6 +482,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { volatile boolean mRestrictBackgroundChangedInBsm; @GuardedBy("mUidRulesFirstLock") volatile boolean mRestrictedNetworkingMode; + @GuardedBy("mUidRulesFirstLock") + volatile boolean mLowPowerStandbyActive; private final boolean mSuppressDefaultPolicy; @@ -516,6 +523,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { final SparseIntArray mUidFirewallPowerSaveRules = new SparseIntArray(); @GuardedBy("mUidRulesFirstLock") final SparseIntArray mUidFirewallRestrictedModeRules = new SparseIntArray(); + @GuardedBy("mUidRulesFirstLock") + final SparseIntArray mUidFirewallLowPowerStandbyModeRules = new SparseIntArray(); /** Set of states for the child firewall chains. True if the chain is active. */ @GuardedBy("mUidRulesFirstLock") @@ -544,6 +553,9 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { @GuardedBy("mUidRulesFirstLock") private final SparseBooleanArray mPowerSaveTempWhitelistAppIds = new SparseBooleanArray(); + @GuardedBy("mUidRulesFirstLock") + private final SparseBooleanArray mLowPowerStandbyAllowlistUids = new SparseBooleanArray(); + /** * UIDs that have been allowlisted temporarily to be able to have network access despite being * idle. Other power saving restrictions still apply. @@ -3785,6 +3797,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { fout.print("Restrict power: "); fout.println(mRestrictPower); fout.print("Device idle: "); fout.println(mDeviceIdleMode); fout.print("Restricted networking mode: "); fout.println(mRestrictedNetworkingMode); + fout.print("Low Power Standby mode: "); fout.println(mLowPowerStandbyActive); synchronized (mMeteredIfacesLock) { fout.print("Metered ifaces: "); fout.println(mMeteredIfaces); @@ -3920,6 +3933,18 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { fout.decreaseIndent(); } + size = mLowPowerStandbyAllowlistUids.size(); + if (size > 0) { + fout.println("Low Power Standby allowlist uids:"); + fout.increaseIndent(); + for (int i = 0; i < size; i++) { + fout.print("UID="); + fout.print(mLowPowerStandbyAllowlistUids.keyAt(i)); + fout.println(); + } + fout.decreaseIndent(); + } + final SparseBooleanArray knownUids = new SparseBooleanArray(); collectKeys(mUidState, knownUids); collectKeys(mUidBlockedState, knownUids); @@ -4001,6 +4026,12 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { return isProcStateAllowedWhileIdleOrPowerSaveMode(uidState); } + @GuardedBy("mUidRulesFirstLock") + private boolean isUidTop(int uid) { + final UidState uidState = mUidState.get(uid); + return isProcStateAllowedWhileInLowPowerStandby(uidState); + } + /** * Process state of UID changed; if needed, will trigger * {@link #updateRulesForDataUsageRestrictionsUL(int)} and @@ -4017,8 +4048,10 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { // state changed, push updated rules mUidState.put(uid, newUidState); updateRestrictBackgroundRulesOnUidStatusChangedUL(uid, oldUidState, newUidState); - if (isProcStateAllowedWhileIdleOrPowerSaveMode(oldUidState) - != isProcStateAllowedWhileIdleOrPowerSaveMode(newUidState)) { + boolean allowedWhileIdleOrPowerSaveModeChanged = + isProcStateAllowedWhileIdleOrPowerSaveMode(oldUidState) + != isProcStateAllowedWhileIdleOrPowerSaveMode(newUidState); + if (allowedWhileIdleOrPowerSaveModeChanged) { updateRuleForAppIdleUL(uid); if (mDeviceIdleMode) { updateRuleForDeviceIdleUL(uid); @@ -4028,6 +4061,17 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } updateRulesForPowerRestrictionsUL(uid); } + if (mLowPowerStandbyActive) { + boolean allowedInLpsChanged = + isProcStateAllowedWhileInLowPowerStandby(oldUidState) + != isProcStateAllowedWhileInLowPowerStandby(newUidState); + if (allowedInLpsChanged) { + if (!allowedWhileIdleOrPowerSaveModeChanged) { + updateRulesForPowerRestrictionsUL(uid); + } + updateRuleForLowPowerStandbyUL(uid); + } + } return true; } } finally { @@ -4051,6 +4095,9 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { updateRuleForRestrictPowerUL(uid); } updateRulesForPowerRestrictionsUL(uid); + if (mLowPowerStandbyActive) { + updateRuleForLowPowerStandbyUL(uid); + } return true; } } @@ -4254,6 +4301,50 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } } + @GuardedBy("mUidRulesFirstLock") + void updateRulesForLowPowerStandbyUL() { + Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRulesForLowPowerStandbyUL"); + try { + if (mLowPowerStandbyActive) { + mUidFirewallLowPowerStandbyModeRules.clear(); + for (int i = mUidState.size() - 1; i >= 0; i--) { + final int uid = mUidState.keyAt(i); + UidBlockedState uidBlockedState = mUidBlockedState.get(uid); + if (hasInternetPermissionUL(uid) && uidBlockedState != null + && (uidBlockedState.effectiveBlockedReasons + & BLOCKED_REASON_LOW_POWER_STANDBY) == 0) { + mUidFirewallLowPowerStandbyModeRules.put(mUidBlockedState.keyAt(i), + FIREWALL_RULE_ALLOW); + } + } + setUidFirewallRulesUL(FIREWALL_CHAIN_LOW_POWER_STANDBY, + mUidFirewallLowPowerStandbyModeRules, CHAIN_TOGGLE_ENABLE); + } else { + setUidFirewallRulesUL(FIREWALL_CHAIN_LOW_POWER_STANDBY, null, CHAIN_TOGGLE_DISABLE); + } + } finally { + Trace.traceEnd(Trace.TRACE_TAG_NETWORK); + } + } + + @GuardedBy("mUidRulesFirstLock") + void updateRuleForLowPowerStandbyUL(int uid) { + if (!hasInternetPermissionUL(uid)) { + return; + } + + final UidBlockedState uidBlockedState = mUidBlockedState.get(uid); + if (mUidState.contains(uid) && uidBlockedState != null + && (uidBlockedState.effectiveBlockedReasons & BLOCKED_REASON_LOW_POWER_STANDBY) + == 0) { + mUidFirewallLowPowerStandbyModeRules.put(uid, FIREWALL_RULE_ALLOW); + setUidFirewallRuleUL(FIREWALL_CHAIN_LOW_POWER_STANDBY, uid, FIREWALL_RULE_ALLOW); + } else { + mUidFirewallLowPowerStandbyModeRules.delete(uid); + setUidFirewallRuleUL(FIREWALL_CHAIN_LOW_POWER_STANDBY, uid, FIREWALL_RULE_DEFAULT); + } + } + /** * Returns whether a uid is allowlisted from power saving restrictions (eg: Battery Saver, Doze * mode, and app idle). @@ -4283,6 +4374,14 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { return mPowerSaveWhitelistExceptIdleAppIds.get(appId); } + /** + * Returns whether a uid is allowlisted from low power standby restrictions. + */ + @GuardedBy("mUidRulesFirstLock") + private boolean isAllowlistedFromLowPowerStandbyUL(int uid) { + return mLowPowerStandbyAllowlistUids.get(uid); + } + // NOTE: since both fw_dozable and fw_powersave uses the same map // (mPowerSaveTempWhitelistAppIds) for allowlisting, we can reuse their logic in this method. @GuardedBy("mUidRulesFirstLock") @@ -4620,6 +4719,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { mPowerSaveTempWhitelistAppIds.delete(uid); mAppIdleTempWhitelistAppIds.delete(uid); mUidFirewallRestrictedModeRules.delete(uid); + mUidFirewallLowPowerStandbyModeRules.delete(uid); synchronized (mUidStateCallbackInfos) { mUidStateCallbackInfos.remove(uid); } @@ -4845,6 +4945,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } final boolean isForeground = isUidForegroundOnRestrictPowerUL(uid); + final boolean isTop = isUidTop(uid); final boolean isWhitelisted = isWhitelistedFromPowerSaveUL(uid, mDeviceIdleMode); @@ -4858,17 +4959,21 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { int newAllowedReasons = ALLOWED_REASON_NONE; newBlockedReasons |= (mRestrictPower ? BLOCKED_REASON_BATTERY_SAVER : 0); newBlockedReasons |= (mDeviceIdleMode ? BLOCKED_REASON_DOZE : 0); + newBlockedReasons |= (mLowPowerStandbyActive ? BLOCKED_REASON_LOW_POWER_STANDBY : 0); newBlockedReasons |= (isUidIdle ? BLOCKED_REASON_APP_STANDBY : 0); newBlockedReasons |= (uidBlockedState.blockedReasons & BLOCKED_REASON_RESTRICTED_MODE); newAllowedReasons |= (isSystem(uid) ? ALLOWED_REASON_SYSTEM : 0); newAllowedReasons |= (isForeground ? ALLOWED_REASON_FOREGROUND : 0); + newAllowedReasons |= (isTop ? ALLOWED_REASON_TOP : 0); newAllowedReasons |= (isWhitelistedFromPowerSaveUL(uid, true) ? ALLOWED_REASON_POWER_SAVE_ALLOWLIST : 0); newAllowedReasons |= (isWhitelistedFromPowerSaveExceptIdleUL(uid) ? ALLOWED_REASON_POWER_SAVE_EXCEPT_IDLE_ALLOWLIST : 0); newAllowedReasons |= (uidBlockedState.allowedReasons & ALLOWED_REASON_RESTRICTED_MODE_PERMISSIONS); + newAllowedReasons |= (isAllowlistedFromLowPowerStandbyUL(uid)) + ? ALLOWED_REASON_LOW_POWER_STANDBY_ALLOWLIST : 0; uidBlockedState.blockedReasons = (uidBlockedState.blockedReasons & BLOCKED_METERED_REASON_MASK) | newBlockedReasons; @@ -4890,6 +4995,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { + ", mRestrictPower: " + mRestrictPower + ", mDeviceIdleMode: " + mDeviceIdleMode + ", isForeground=" + isForeground + + ", isTop=" + isTop + ", isWhitelisted=" + isWhitelisted + ", oldUidBlockedState=" + previousUidBlockedState.toString() + ", newUidBlockedState=" + uidBlockedState.toString()); @@ -5421,6 +5527,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { mUidFirewallPowerSaveRules.put(uid, rule); } else if (chain == FIREWALL_CHAIN_RESTRICTED) { mUidFirewallRestrictedModeRules.put(uid, rule); + } else if (chain == FIREWALL_CHAIN_LOW_POWER_STANDBY) { + mUidFirewallLowPowerStandbyModeRules.put(uid, rule); } try { @@ -5468,6 +5576,9 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { .setFirewallUidRule(FIREWALL_CHAIN_POWERSAVE, uid, FIREWALL_RULE_DEFAULT); mNetworkManager .setFirewallUidRule(FIREWALL_CHAIN_RESTRICTED, uid, FIREWALL_RULE_DEFAULT); + mNetworkManager + .setFirewallUidRule(FIREWALL_CHAIN_LOW_POWER_STANDBY, uid, + FIREWALL_RULE_DEFAULT); mNetworkManager.setUidOnMeteredNetworkAllowlist(uid, false); mNetworkManager.setUidOnMeteredNetworkDenylist(uid, false); } catch (IllegalStateException e) { @@ -5747,6 +5858,67 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { mHandler.obtainMessage(MSG_METERED_RESTRICTED_PACKAGES_CHANGED, userId, 0, packageNames).sendToTarget(); } + + @Override + public void setLowPowerStandbyActive(boolean active) { + Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "setLowPowerStandbyActive"); + try { + synchronized (mUidRulesFirstLock) { + if (mLowPowerStandbyActive == active) { + return; + } + mLowPowerStandbyActive = active; + synchronized (mNetworkPoliciesSecondLock) { + if (!mSystemReady) return; + } + + forEachUid("updateRulesForRestrictPower", + uid -> updateRulesForPowerRestrictionsUL(uid)); + updateRulesForLowPowerStandbyUL(); + } + } finally { + Trace.traceEnd(Trace.TRACE_TAG_NETWORK); + } + } + + @Override + public void setLowPowerStandbyAllowlist(int[] uids) { + synchronized (mUidRulesFirstLock) { + final SparseBooleanArray changedUids = new SparseBooleanArray(); + for (int i = 0; i < mLowPowerStandbyAllowlistUids.size(); i++) { + final int oldUid = mLowPowerStandbyAllowlistUids.keyAt(i); + if (!ArrayUtils.contains(uids, oldUid)) { + changedUids.put(oldUid, true); + } + } + + for (int i = 0; i < changedUids.size(); i++) { + final int deletedUid = changedUids.keyAt(i); + mLowPowerStandbyAllowlistUids.delete(deletedUid); + } + + for (int newUid : uids) { + if (mLowPowerStandbyAllowlistUids.indexOfKey(newUid) < 0) { + changedUids.append(newUid, true); + mLowPowerStandbyAllowlistUids.append(newUid, true); + } + } + + if (!mLowPowerStandbyActive) { + return; + } + + synchronized (mNetworkPoliciesSecondLock) { + if (!mSystemReady) return; + } + + for (int i = 0; i < changedUids.size(); i++) { + final int changedUid = changedUids.keyAt(i); + updateRulesForPowerRestrictionsUL(changedUid); + updateRuleForLowPowerStandbyUL(changedUid); + } + } + } } private void setMeteredRestrictedPackagesInternal(Set<String> packageNames, int userId) { @@ -5904,6 +6076,9 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { effectiveBlockedReasons &= ~BLOCKED_METERED_REASON_DATA_SAVER; effectiveBlockedReasons &= ~BLOCKED_METERED_REASON_USER_RESTRICTED; } + if ((allowedReasons & ALLOWED_REASON_TOP) != 0) { + effectiveBlockedReasons &= ~BLOCKED_REASON_LOW_POWER_STANDBY; + } if ((allowedReasons & ALLOWED_REASON_POWER_SAVE_ALLOWLIST) != 0) { effectiveBlockedReasons &= ~BLOCKED_REASON_BATTERY_SAVER; effectiveBlockedReasons &= ~BLOCKED_REASON_DOZE; @@ -5919,6 +6094,10 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { if ((allowedReasons & ALLOWED_METERED_REASON_USER_EXEMPTED) != 0) { effectiveBlockedReasons &= ~BLOCKED_METERED_REASON_DATA_SAVER; } + if ((allowedReasons & ALLOWED_REASON_LOW_POWER_STANDBY_ALLOWLIST) != 0) { + effectiveBlockedReasons &= ~BLOCKED_REASON_LOW_POWER_STANDBY; + } + return effectiveBlockedReasons; } @@ -5943,6 +6122,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { BLOCKED_REASON_DOZE, BLOCKED_REASON_APP_STANDBY, BLOCKED_REASON_RESTRICTED_MODE, + BLOCKED_REASON_LOW_POWER_STANDBY, BLOCKED_METERED_REASON_DATA_SAVER, BLOCKED_METERED_REASON_USER_RESTRICTED, BLOCKED_METERED_REASON_ADMIN_DISABLED, @@ -5951,9 +6131,11 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { private static final int[] ALLOWED_REASONS = { ALLOWED_REASON_SYSTEM, ALLOWED_REASON_FOREGROUND, + ALLOWED_REASON_TOP, ALLOWED_REASON_POWER_SAVE_ALLOWLIST, ALLOWED_REASON_POWER_SAVE_EXCEPT_IDLE_ALLOWLIST, ALLOWED_REASON_RESTRICTED_MODE_PERMISSIONS, + ALLOWED_REASON_LOW_POWER_STANDBY_ALLOWLIST, ALLOWED_METERED_REASON_USER_EXEMPTED, ALLOWED_METERED_REASON_SYSTEM, ALLOWED_METERED_REASON_FOREGROUND, @@ -5971,6 +6153,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { return "APP_STANDBY"; case BLOCKED_REASON_RESTRICTED_MODE: return "RESTRICTED_MODE"; + case BLOCKED_REASON_LOW_POWER_STANDBY: + return "LOW_POWER_STANDBY"; case BLOCKED_METERED_REASON_DATA_SAVER: return "DATA_SAVER"; case BLOCKED_METERED_REASON_USER_RESTRICTED: @@ -5991,12 +6175,16 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { return "SYSTEM"; case ALLOWED_REASON_FOREGROUND: return "FOREGROUND"; + case ALLOWED_REASON_TOP: + return "TOP"; case ALLOWED_REASON_POWER_SAVE_ALLOWLIST: return "POWER_SAVE_ALLOWLIST"; case ALLOWED_REASON_POWER_SAVE_EXCEPT_IDLE_ALLOWLIST: return "POWER_SAVE_EXCEPT_IDLE_ALLOWLIST"; case ALLOWED_REASON_RESTRICTED_MODE_PERMISSIONS: return "RESTRICTED_MODE_PERMISSIONS"; + case ALLOWED_REASON_LOW_POWER_STANDBY_ALLOWLIST: + return "LOW_POWER_STANDBY_ALLOWLIST"; case ALLOWED_METERED_REASON_USER_EXEMPTED: return "METERED_USER_EXEMPTED"; case ALLOWED_METERED_REASON_SYSTEM: @@ -6063,7 +6251,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { int powerBlockedReasons = BLOCKED_REASON_APP_STANDBY | BLOCKED_REASON_DOZE - | BLOCKED_REASON_BATTERY_SAVER; + | BLOCKED_REASON_BATTERY_SAVER + | BLOCKED_REASON_LOW_POWER_STANDBY; if ((effectiveBlockedReasons & powerBlockedReasons) != 0) { uidRule |= RULE_REJECT_ALL; } else if ((blockedReasons & powerBlockedReasons) != 0) { diff --git a/services/core/java/com/android/server/pm/LauncherAppsService.java b/services/core/java/com/android/server/pm/LauncherAppsService.java index 419b72675c49..24b9f48e71a6 100644 --- a/services/core/java/com/android/server/pm/LauncherAppsService.java +++ b/services/core/java/com/android/server/pm/LauncherAppsService.java @@ -815,7 +815,7 @@ public class LauncherAppsService extends SystemService { PendingIntent injectCreatePendingIntent(int requestCode, @NonNull Intent[] intents, int flags, Bundle options, String ownerPackage, int ownerUserId) { return mActivityManagerInternal.getPendingIntentActivityAsApp(requestCode, intents, - flags, options, ownerPackage, ownerUserId); + flags, null /* options */, ownerPackage, ownerUserId); } @Override @@ -1117,7 +1117,7 @@ public class LauncherAppsService extends SystemService { // calling identity to mirror the startActivityAsUser() call which does not validate // the calling user return PendingIntent.getActivityAsUser(mContext, 0 /* requestCode */, launchIntent, - FLAG_IMMUTABLE, opts, user); + FLAG_IMMUTABLE, null /* options */, user); } finally { Binder.restoreCallingIdentity(ident); } diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index f580bd078a0d..e70517f3080b 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -7380,7 +7380,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A mSizeCompatBounds = null; mCompatDisplayInsets = null; - onRequestedOverrideConfigurationChanged(getRequestedOverrideConfiguration()); + // Clear config override in #updateCompatDisplayInsets(). + onRequestedOverrideConfigurationChanged(EMPTY); } @Override diff --git a/services/tests/servicestests/src/com/android/server/adb/AdbDebuggingManagerTest.java b/services/tests/servicestests/src/com/android/server/adb/AdbDebuggingManagerTest.java index cffff66b64f1..02cf971a8076 100644 --- a/services/tests/servicestests/src/com/android/server/adb/AdbDebuggingManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/adb/AdbDebuggingManagerTest.java @@ -23,7 +23,14 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import android.content.BroadcastReceiver; import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.pm.PackageManager; +import android.debug.AdbManager; +import android.debug.IAdbManager; +import android.os.ServiceManager; import android.provider.Settings; import android.util.Log; @@ -105,6 +112,7 @@ public final class AdbDebuggingManagerTest { public void tearDown() throws Exception { mKeyStore.deleteKeyStore(); setAllowedConnectionTime(mOriginalAllowedConnectionTime); + dropShellPermissionIdentity(); } /** @@ -813,6 +821,108 @@ public final class AdbDebuggingManagerTest { return hasAtLeastOneLetter; } + CountDownLatch mAdbActionLatch = new CountDownLatch(1); + private final BroadcastReceiver mReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + Log.i(TAG, "Received intent action=" + action); + if (AdbManager.WIRELESS_DEBUG_PAIRED_DEVICES_ACTION.equals(action)) { + assertEquals("Received broadcast without MANAGE_DEBUGGING permission.", + context.checkSelfPermission(android.Manifest.permission.MANAGE_DEBUGGING), + PackageManager.PERMISSION_GRANTED); + Log.i(TAG, "action=" + action + " paired_device=" + intent.getSerializableExtra( + AdbManager.WIRELESS_DEVICES_EXTRA).toString()); + mAdbActionLatch.countDown(); + } else if (AdbManager.WIRELESS_DEBUG_STATE_CHANGED_ACTION.equals(action)) { + assertEquals("Received broadcast without MANAGE_DEBUGGING permission.", + context.checkSelfPermission(android.Manifest.permission.MANAGE_DEBUGGING), + PackageManager.PERMISSION_GRANTED); + int status = intent.getIntExtra(AdbManager.WIRELESS_STATUS_EXTRA, + AdbManager.WIRELESS_STATUS_DISCONNECTED); + Log.i(TAG, "action=" + action + " status=" + status); + mAdbActionLatch.countDown(); + } else if (AdbManager.WIRELESS_DEBUG_PAIRING_RESULT_ACTION.equals(action)) { + assertEquals("Received broadcast without MANAGE_DEBUGGING permission.", + context.checkSelfPermission(android.Manifest.permission.MANAGE_DEBUGGING), + PackageManager.PERMISSION_GRANTED); + Integer res = intent.getIntExtra( + AdbManager.WIRELESS_STATUS_EXTRA, + AdbManager.WIRELESS_STATUS_FAIL); + Log.i(TAG, "action=" + action + " result=" + res); + + if (res.equals(AdbManager.WIRELESS_STATUS_PAIRING_CODE)) { + String pairingCode = intent.getStringExtra( + AdbManager.WIRELESS_PAIRING_CODE_EXTRA); + Log.i(TAG, "pairingCode=" + pairingCode); + } else if (res.equals(AdbManager.WIRELESS_STATUS_CONNECTED)) { + int port = intent.getIntExtra(AdbManager.WIRELESS_DEBUG_PORT_EXTRA, 0); + Log.i(TAG, "port=" + port); + } + mAdbActionLatch.countDown(); + } + } + }; + + private void adoptShellPermissionIdentity() { + InstrumentationRegistry.getInstrumentation().getUiAutomation() + .adoptShellPermissionIdentity(android.Manifest.permission.MANAGE_DEBUGGING); + } + + private void dropShellPermissionIdentity() { + InstrumentationRegistry.getInstrumentation().getUiAutomation() + .dropShellPermissionIdentity(); + } + + @Test + public void testBroadcastReceiverWithPermissions() throws Exception { + adoptShellPermissionIdentity(); + final IAdbManager mAdbManager = IAdbManager.Stub.asInterface( + ServiceManager.getService(Context.ADB_SERVICE)); + IntentFilter intentFilter = + new IntentFilter(AdbManager.WIRELESS_DEBUG_PAIRED_DEVICES_ACTION); + intentFilter.addAction(AdbManager.WIRELESS_DEBUG_STATE_CHANGED_ACTION); + intentFilter.addAction(AdbManager.WIRELESS_DEBUG_PAIRING_RESULT_ACTION); + assertEquals("Context does not have MANAGE_DEBUGGING permission.", + mContext.checkSelfPermission(android.Manifest.permission.MANAGE_DEBUGGING), + PackageManager.PERMISSION_GRANTED); + try { + mContext.registerReceiver(mReceiver, intentFilter); + mAdbManager.enablePairingByPairingCode(); + if (!mAdbActionLatch.await(TIMEOUT, TIMEOUT_TIME_UNIT)) { + fail("Receiver did not receive adb intent action within the timeout duration"); + } + } finally { + mContext.unregisterReceiver(mReceiver); + } + } + + @Test + public void testBroadcastReceiverWithoutPermissions() throws Exception { + adoptShellPermissionIdentity(); + final IAdbManager mAdbManager = IAdbManager.Stub.asInterface( + ServiceManager.getService(Context.ADB_SERVICE)); + IntentFilter intentFilter = + new IntentFilter(AdbManager.WIRELESS_DEBUG_PAIRED_DEVICES_ACTION); + intentFilter.addAction(AdbManager.WIRELESS_DEBUG_STATE_CHANGED_ACTION); + intentFilter.addAction(AdbManager.WIRELESS_DEBUG_PAIRING_RESULT_ACTION); + mAdbManager.enablePairingByPairingCode(); + + dropShellPermissionIdentity(); + assertEquals("Context has MANAGE_DEBUGGING permission.", + mContext.checkSelfPermission(android.Manifest.permission.MANAGE_DEBUGGING), + PackageManager.PERMISSION_DENIED); + try { + mContext.registerReceiver(mReceiver, intentFilter); + + if (mAdbActionLatch.await(TIMEOUT, TIMEOUT_TIME_UNIT)) { + fail("Broadcast receiver received adb action intent without debug permissions"); + } + } finally { + mContext.unregisterReceiver(mReceiver); + } + } + /** * Runs an adb test with the provided configuration. * diff --git a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java index f865a50978b5..af8ac6f412f5 100644 --- a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java @@ -23,11 +23,13 @@ import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_USER_RESTRI import static android.net.ConnectivityManager.BLOCKED_REASON_APP_STANDBY; import static android.net.ConnectivityManager.BLOCKED_REASON_BATTERY_SAVER; import static android.net.ConnectivityManager.BLOCKED_REASON_DOZE; +import static android.net.ConnectivityManager.BLOCKED_REASON_LOW_POWER_STANDBY; import static android.net.ConnectivityManager.BLOCKED_REASON_NONE; import static android.net.ConnectivityManager.CONNECTIVITY_ACTION; +import static android.net.ConnectivityManager.FIREWALL_CHAIN_LOW_POWER_STANDBY; +import static android.net.ConnectivityManager.FIREWALL_CHAIN_RESTRICTED; import static android.net.ConnectivityManager.TYPE_MOBILE; import static android.net.ConnectivityManager.TYPE_WIFI; -import static android.net.INetd.FIREWALL_CHAIN_RESTRICTED; import static android.net.INetd.FIREWALL_RULE_ALLOW; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING; import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; @@ -38,8 +40,10 @@ import static android.net.NetworkPolicy.WARNING_DISABLED; import static android.net.NetworkPolicyManager.ALLOWED_METERED_REASON_FOREGROUND; import static android.net.NetworkPolicyManager.ALLOWED_METERED_REASON_SYSTEM; import static android.net.NetworkPolicyManager.ALLOWED_REASON_FOREGROUND; +import static android.net.NetworkPolicyManager.ALLOWED_REASON_LOW_POWER_STANDBY_ALLOWLIST; import static android.net.NetworkPolicyManager.ALLOWED_REASON_NONE; import static android.net.NetworkPolicyManager.ALLOWED_REASON_SYSTEM; +import static android.net.NetworkPolicyManager.ALLOWED_REASON_TOP; import static android.net.NetworkPolicyManager.FIREWALL_RULE_DEFAULT; import static android.net.NetworkPolicyManager.POLICY_ALLOW_METERED_BACKGROUND; import static android.net.NetworkPolicyManager.POLICY_NONE; @@ -200,6 +204,7 @@ import java.time.ZonedDateTime; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; +import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashSet; import java.util.List; @@ -1877,55 +1882,99 @@ public class NetworkPolicyManagerServiceTest { } @Test + public void testLowPowerStandbyAllowlist() throws Exception { + callOnUidStateChanged(UID_A, ActivityManager.PROCESS_STATE_TOP, 0); + callOnUidStateChanged(UID_B, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, 0); + callOnUidStateChanged(UID_C, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, 0); + expectHasInternetPermission(UID_A, true); + expectHasInternetPermission(UID_B, true); + expectHasInternetPermission(UID_C, true); + + final NetworkPolicyManagerInternal internal = LocalServices + .getService(NetworkPolicyManagerInternal.class); + + Map<Integer, Integer> firewallUidRules = new ArrayMap<>(); + doAnswer(arg -> { + int[] uids = arg.getArgument(1); + int[] rules = arg.getArgument(2); + assertTrue(uids.length == rules.length); + + for (int i = 0; i < uids.length; ++i) { + firewallUidRules.put(uids[i], rules[i]); + } + return null; + }).when(mNetworkManager).setFirewallUidRules(eq(FIREWALL_CHAIN_LOW_POWER_STANDBY), + any(int[].class), any(int[].class)); + + internal.setLowPowerStandbyAllowlist(new int[] { UID_B }); + internal.setLowPowerStandbyActive(true); + assertEquals(FIREWALL_RULE_ALLOW, firewallUidRules.get(UID_A).intValue()); + assertEquals(FIREWALL_RULE_ALLOW, firewallUidRules.get(UID_B).intValue()); + assertFalse(mService.isUidNetworkingBlocked(UID_A, false)); + assertFalse(mService.isUidNetworkingBlocked(UID_B, false)); + assertTrue(mService.isUidNetworkingBlocked(UID_C, false)); + + internal.setLowPowerStandbyActive(false); + assertFalse(mService.isUidNetworkingBlocked(UID_A, false)); + assertFalse(mService.isUidNetworkingBlocked(UID_B, false)); + assertFalse(mService.isUidNetworkingBlocked(UID_C, false)); + } + + @Test public void testUpdateEffectiveBlockedReasons() { - final SparseArray<Pair<Integer, Integer>> effectiveBlockedReasons = new SparseArray<>(); - effectiveBlockedReasons.put(BLOCKED_REASON_NONE, - Pair.create(BLOCKED_REASON_NONE, ALLOWED_REASON_NONE)); - - effectiveBlockedReasons.put(BLOCKED_REASON_NONE, - Pair.create(BLOCKED_REASON_BATTERY_SAVER, ALLOWED_REASON_SYSTEM)); - effectiveBlockedReasons.put(BLOCKED_REASON_NONE, - Pair.create(BLOCKED_REASON_BATTERY_SAVER | BLOCKED_REASON_DOZE, - ALLOWED_REASON_SYSTEM)); - effectiveBlockedReasons.put(BLOCKED_REASON_NONE, - Pair.create(BLOCKED_METERED_REASON_DATA_SAVER, - ALLOWED_METERED_REASON_SYSTEM)); - effectiveBlockedReasons.put(BLOCKED_REASON_NONE, - Pair.create(BLOCKED_METERED_REASON_DATA_SAVER - | BLOCKED_METERED_REASON_USER_RESTRICTED, - ALLOWED_METERED_REASON_SYSTEM)); - - effectiveBlockedReasons.put(BLOCKED_METERED_REASON_DATA_SAVER, + final Map<Pair<Integer, Integer>, Integer> effectiveBlockedReasons = new HashMap<>(); + effectiveBlockedReasons.put(Pair.create(BLOCKED_REASON_NONE, ALLOWED_REASON_NONE), + BLOCKED_REASON_NONE); + + effectiveBlockedReasons.put( + Pair.create(BLOCKED_REASON_BATTERY_SAVER, ALLOWED_REASON_SYSTEM), + BLOCKED_REASON_NONE); + effectiveBlockedReasons.put(Pair.create(BLOCKED_REASON_BATTERY_SAVER | BLOCKED_REASON_DOZE, + ALLOWED_REASON_SYSTEM), BLOCKED_REASON_NONE); + effectiveBlockedReasons.put( + Pair.create(BLOCKED_METERED_REASON_DATA_SAVER, ALLOWED_METERED_REASON_SYSTEM), + BLOCKED_REASON_NONE); + effectiveBlockedReasons.put(Pair.create(BLOCKED_METERED_REASON_DATA_SAVER + | BLOCKED_METERED_REASON_USER_RESTRICTED, + ALLOWED_METERED_REASON_SYSTEM), BLOCKED_REASON_NONE); + + effectiveBlockedReasons.put( Pair.create(BLOCKED_REASON_BATTERY_SAVER | BLOCKED_METERED_REASON_DATA_SAVER, - ALLOWED_REASON_SYSTEM)); - effectiveBlockedReasons.put(BLOCKED_REASON_APP_STANDBY, + ALLOWED_REASON_SYSTEM), BLOCKED_METERED_REASON_DATA_SAVER); + effectiveBlockedReasons.put( Pair.create(BLOCKED_REASON_APP_STANDBY | BLOCKED_METERED_REASON_USER_RESTRICTED, - ALLOWED_METERED_REASON_SYSTEM)); - - effectiveBlockedReasons.put(BLOCKED_REASON_NONE, - Pair.create(BLOCKED_REASON_BATTERY_SAVER, ALLOWED_REASON_FOREGROUND)); - effectiveBlockedReasons.put(BLOCKED_REASON_NONE, - Pair.create(BLOCKED_REASON_BATTERY_SAVER | BLOCKED_REASON_DOZE, - ALLOWED_REASON_FOREGROUND)); - effectiveBlockedReasons.put(BLOCKED_REASON_NONE, - Pair.create(BLOCKED_METERED_REASON_DATA_SAVER, ALLOWED_METERED_REASON_FOREGROUND)); - effectiveBlockedReasons.put(BLOCKED_REASON_NONE, - Pair.create(BLOCKED_METERED_REASON_DATA_SAVER - | BLOCKED_METERED_REASON_USER_RESTRICTED, - ALLOWED_METERED_REASON_FOREGROUND)); - effectiveBlockedReasons.put(BLOCKED_METERED_REASON_DATA_SAVER, + ALLOWED_METERED_REASON_SYSTEM), BLOCKED_REASON_APP_STANDBY); + + effectiveBlockedReasons.put( + Pair.create(BLOCKED_REASON_BATTERY_SAVER, ALLOWED_REASON_FOREGROUND), + BLOCKED_REASON_NONE); + effectiveBlockedReasons.put(Pair.create(BLOCKED_REASON_BATTERY_SAVER | BLOCKED_REASON_DOZE, + ALLOWED_REASON_FOREGROUND), BLOCKED_REASON_NONE); + effectiveBlockedReasons.put( + Pair.create(BLOCKED_METERED_REASON_DATA_SAVER, ALLOWED_METERED_REASON_FOREGROUND), + BLOCKED_REASON_NONE); + effectiveBlockedReasons.put(Pair.create(BLOCKED_METERED_REASON_DATA_SAVER + | BLOCKED_METERED_REASON_USER_RESTRICTED, + ALLOWED_METERED_REASON_FOREGROUND), BLOCKED_REASON_NONE); + effectiveBlockedReasons.put( Pair.create(BLOCKED_REASON_BATTERY_SAVER | BLOCKED_METERED_REASON_DATA_SAVER, - ALLOWED_REASON_FOREGROUND)); - effectiveBlockedReasons.put(BLOCKED_REASON_BATTERY_SAVER, - Pair.create(BLOCKED_REASON_BATTERY_SAVER - | BLOCKED_METERED_REASON_USER_RESTRICTED, - ALLOWED_METERED_REASON_FOREGROUND)); + ALLOWED_REASON_FOREGROUND), BLOCKED_METERED_REASON_DATA_SAVER); + effectiveBlockedReasons.put(Pair.create(BLOCKED_REASON_BATTERY_SAVER + | BLOCKED_METERED_REASON_USER_RESTRICTED, + ALLOWED_METERED_REASON_FOREGROUND), BLOCKED_REASON_BATTERY_SAVER); + + effectiveBlockedReasons.put(Pair.create(BLOCKED_REASON_LOW_POWER_STANDBY, + ALLOWED_REASON_FOREGROUND), BLOCKED_REASON_LOW_POWER_STANDBY); + effectiveBlockedReasons.put(Pair.create(BLOCKED_REASON_LOW_POWER_STANDBY, + ALLOWED_REASON_TOP), BLOCKED_REASON_NONE); + effectiveBlockedReasons.put(Pair.create(BLOCKED_REASON_LOW_POWER_STANDBY, + ALLOWED_REASON_LOW_POWER_STANDBY_ALLOWLIST), BLOCKED_REASON_NONE); // TODO: test more combinations of blocked reasons. - for (int i = 0; i < effectiveBlockedReasons.size(); ++i) { - final int expectedEffectiveBlockedReasons = effectiveBlockedReasons.keyAt(i); - final int blockedReasons = effectiveBlockedReasons.valueAt(i).first; - final int allowedReasons = effectiveBlockedReasons.valueAt(i).second; + for (Map.Entry<Pair<Integer, Integer>, Integer> test : effectiveBlockedReasons.entrySet()) { + final int expectedEffectiveBlockedReasons = test.getValue(); + final int blockedReasons = test.getKey().first; + final int allowedReasons = test.getKey().second; final String errorMsg = "Expected=" + blockedReasonsToString(expectedEffectiveBlockedReasons) + "; blockedReasons=" + blockedReasonsToString(blockedReasons) diff --git a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java index 9639aa78fd5b..dc378dc8cab2 100644 --- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java @@ -76,6 +76,7 @@ import android.content.pm.ActivityInfo; import android.content.pm.ActivityInfo.ScreenOrientation; import android.content.res.Configuration; import android.graphics.Rect; +import android.os.UserHandle; import android.platform.test.annotations.Presubmit; import android.provider.DeviceConfig; import android.provider.DeviceConfig.Properties; @@ -2181,6 +2182,29 @@ public class SizeCompatTests extends WindowTestsBase { .computeAspectRatio(sizeCompatAppBounds), delta); } + @Test + public void testClearSizeCompat_resetOverrideConfig() { + final int origDensity = 480; + final int newDensity = 520; + final DisplayContent display = new TestDisplayContent.Builder(mAtm, 600, 800) + .setDensityDpi(origDensity) + .build(); + setUpApp(display); + prepareUnresizable(mActivity, -1.f /* maxAspect */, SCREEN_ORIENTATION_PORTRAIT); + + // Activity should enter size compat with old density after display density change. + display.setForcedDensity(newDensity, UserHandle.USER_CURRENT); + + assertScaled(); + assertEquals(origDensity, mActivity.getConfiguration().densityDpi); + + // Activity should exit size compat with new density. + mActivity.clearSizeCompatMode(); + + assertFitted(); + assertEquals(newDensity, mActivity.getConfiguration().densityDpi); + } + private void assertHorizontalPositionForDifferentDisplayConfigsForLandscapeActivity( float letterboxHorizontalPositionMultiplier) { // Set up a display in landscape and ignoring orientation request. diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java index b85426b3b4b0..83c78cd0236c 100644 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -1900,6 +1900,13 @@ public class CarrierConfigManager { "show_4g_for_lte_data_icon_bool"; /** + * Boolean indicating if default data account should show 4G LTE or 4G icon. + * @hide + */ + public static final String KEY_SHOW_4GLTE_FOR_LTE_DATA_ICON_BOOL = + "show_4glte_for_lte_data_icon_bool"; + + /** * Boolean indicating if default data account should show 4G icon when in 3G. */ public static final String KEY_SHOW_4G_FOR_3G_DATA_ICON_BOOL = @@ -6239,6 +6246,7 @@ public class CarrierConfigManager { sDefaults.putBoolean(KEY_SPN_DISPLAY_RULE_USE_ROAMING_FROM_SERVICE_STATE_BOOL, false); sDefaults.putBoolean(KEY_ALWAYS_SHOW_DATA_RAT_ICON_BOOL, false); sDefaults.putBoolean(KEY_SHOW_4G_FOR_LTE_DATA_ICON_BOOL, false); + sDefaults.putBoolean(KEY_SHOW_4GLTE_FOR_LTE_DATA_ICON_BOOL, false); sDefaults.putBoolean(KEY_SHOW_4G_FOR_3G_DATA_ICON_BOOL, false); sDefaults.putString(KEY_OPERATOR_NAME_FILTER_PATTERN_STRING, ""); sDefaults.putString(KEY_SHOW_CARRIER_DATA_ICON_PATTERN_STRING, ""); |