diff options
36 files changed, 433 insertions, 176 deletions
diff --git a/core/java/android/app/people/OWNERS b/core/java/android/app/people/OWNERS new file mode 100644 index 000000000000..7371a88df237 --- /dev/null +++ b/core/java/android/app/people/OWNERS @@ -0,0 +1,4 @@ +# Bug component: 978868 + +danningc@google.com +juliacr@google.com
\ No newline at end of file diff --git a/core/java/android/os/TransactionTooLargeException.java b/core/java/android/os/TransactionTooLargeException.java index 10abf26420f1..4d5b2a10f3fe 100644 --- a/core/java/android/os/TransactionTooLargeException.java +++ b/core/java/android/os/TransactionTooLargeException.java @@ -23,9 +23,11 @@ import android.os.RemoteException; * During a remote procedure call, the arguments and the return value of the call * are transferred as {@link Parcel} objects stored in the Binder transaction buffer. * If the arguments or the return value are too large to fit in the transaction buffer, - * then the call will fail and {@link TransactionTooLargeException} will be thrown. + * then the call will fail. {@link TransactionTooLargeException} is thrown as a + * heuristic when a transaction is large, and it fails, since these are the transactions + * which are most likely to overfill the transaction buffer. * </p><p> - * The Binder transaction buffer has a limited fixed size, currently 1Mb, which + * The Binder transaction buffer has a limited fixed size, currently 1MB, which * is shared by all transactions in progress for the process. Consequently this * exception can be thrown when there are many transactions in progress even when * most of the individual transactions are of moderate size. diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java index 9991367e6bfd..a2dab707b373 100644 --- a/core/java/android/view/Display.java +++ b/core/java/android/view/Display.java @@ -687,6 +687,19 @@ public final class Display { } /** + * Gets the default brightness configured for the display. + * + * @return Default brightness between 0.0-1.0 + * @hide + */ + public float getBrightnessDefault() { + synchronized (this) { + updateDisplayInfoLocked(); + return mDisplayInfo.brightnessDefault; + } + } + + /** * Gets the size of the display, in pixels. * Value returned by this method does not necessarily represent the actual raw size * (native resolution) of the display. diff --git a/core/java/android/view/DisplayInfo.java b/core/java/android/view/DisplayInfo.java index 0ac030513728..fc42cd07950e 100644 --- a/core/java/android/view/DisplayInfo.java +++ b/core/java/android/view/DisplayInfo.java @@ -275,6 +275,27 @@ public final class DisplayInfo implements Parcelable { // TODO (b/114338689): Remove the flag and use IWindowManager#getRemoveContentMode public int removeMode = Display.REMOVE_MODE_MOVE_CONTENT_TO_PRIMARY; + /** + * @hide + * The current minimum brightness constraint of the display. Value between 0.0 and 1.0, + * derived from the config constraints of the display device of this logical display. + */ + public float brightnessMinimum; + + /** + * @hide + * The current maximum brightness constraint of the display. Value between 0.0 and 1.0, + * derived from the config constraints of the display device of this logical display. + */ + public float brightnessMaximum; + + /** + * @hide + * The current default brightness of the display. Value between 0.0 and 1.0, + * derived from the configuration of the display device of this logical display. + */ + public float brightnessDefault; + public static final @android.annotation.NonNull Creator<DisplayInfo> CREATOR = new Creator<DisplayInfo>() { @Override public DisplayInfo createFromParcel(Parcel source) { @@ -339,7 +360,10 @@ public final class DisplayInfo implements Parcelable { && ownerUid == other.ownerUid && Objects.equals(ownerPackageName, other.ownerPackageName) && removeMode == other.removeMode - && refreshRateOverride == other.refreshRateOverride; + && refreshRateOverride == other.refreshRateOverride + && brightnessMinimum == other.brightnessMinimum + && brightnessMaximum == other.brightnessMaximum + && brightnessDefault == other.brightnessDefault; } @Override @@ -384,6 +408,9 @@ public final class DisplayInfo implements Parcelable { ownerPackageName = other.ownerPackageName; removeMode = other.removeMode; refreshRateOverride = other.refreshRateOverride; + brightnessMinimum = other.brightnessMinimum; + brightnessMaximum = other.brightnessMaximum; + brightnessDefault = other.brightnessDefault; } public void readFromParcel(Parcel source) { @@ -430,6 +457,9 @@ public final class DisplayInfo implements Parcelable { uniqueId = source.readString8(); removeMode = source.readInt(); refreshRateOverride = source.readFloat(); + brightnessMinimum = source.readFloat(); + brightnessMaximum = source.readFloat(); + brightnessDefault = source.readFloat(); } @Override @@ -475,6 +505,9 @@ public final class DisplayInfo implements Parcelable { dest.writeString8(uniqueId); dest.writeInt(removeMode); dest.writeFloat(refreshRateOverride); + dest.writeFloat(brightnessMinimum); + dest.writeFloat(brightnessMaximum); + dest.writeFloat(brightnessDefault); } @Override @@ -698,7 +731,12 @@ public final class DisplayInfo implements Parcelable { sb.append(removeMode); sb.append(", refreshRateOverride "); sb.append(refreshRateOverride); - + sb.append(", brightnessMinimum "); + sb.append(brightnessMinimum); + sb.append(", brightnessMaximum "); + sb.append(brightnessMaximum); + sb.append(", brightnessDefault "); + sb.append(brightnessDefault); sb.append("}"); return sb.toString(); } diff --git a/core/java/android/view/OWNERS b/core/java/android/view/OWNERS index bae6ee85c064..e66b17aa4426 100644 --- a/core/java/android/view/OWNERS +++ b/core/java/android/view/OWNERS @@ -33,6 +33,9 @@ per-file SimulatedDpad.java = file:/services/core/java/com/android/server/input/ per-file InputWindowHandle.java = file:/services/core/java/com/android/server/input/OWNERS per-file InputWindowHandle.java = file:/services/core/java/com/android/server/wm/OWNERS +# Notifications +per-file Notification*.java = file:/services/core/java/com/android/server/notification/OWNERS + # Surface per-file Surface.java = file:/graphics/java/android/graphics/OWNERS per-file Surface.java = file:/services/core/java/com/android/server/wm/OWNERS diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java index e06413783fe4..666ee6e606a7 100644 --- a/core/java/com/android/internal/app/ChooserActivity.java +++ b/core/java/com/android/internal/app/ChooserActivity.java @@ -182,7 +182,7 @@ public class ChooserActivity extends ResolverActivity implements * To be used for shared element transition into this activity. * @hide */ - public static final String FIRST_IMAGE_PREVIEW_TRANSITION_NAME = "chooser_preview_image_1"; + public static final String FIRST_IMAGE_PREVIEW_TRANSITION_NAME = "screenshot_preview_image"; private static final String PREF_NUM_SHEET_EXPANSIONS = "pref_num_sheet_expansions"; diff --git a/core/java/com/android/internal/app/OWNERS b/core/java/com/android/internal/app/OWNERS index 382b49e68e6f..c5a956a81d8d 100644 --- a/core/java/com/android/internal/app/OWNERS +++ b/core/java/com/android/internal/app/OWNERS @@ -2,3 +2,4 @@ per-file *AppOp* = file:/core/java/android/permission/OWNERS per-file *Resolver* = file:/packages/SystemUI/OWNERS per-file *Chooser* = file:/packages/SystemUI/OWNERS per-file SimpleIconFactory.java = file:/packages/SystemUI/OWNERS +per-file NetInitiatedActivity.java = file:/location/java/android/location/OWNERS diff --git a/core/java/com/android/internal/util/FastDataOutput.java b/core/java/com/android/internal/util/FastDataOutput.java index 83d26e181228..cf5b2966d889 100644 --- a/core/java/com/android/internal/util/FastDataOutput.java +++ b/core/java/com/android/internal/util/FastDataOutput.java @@ -115,8 +115,7 @@ public class FastDataOutput implements DataOutput, Flushable, Closeable { // Magnitude of this returned value indicates the number of bytes // required to encode the string; sign indicates success/failure - int len = CharsetUtils.toModifiedUtf8Bytes(s, mBufferPtr, mBufferPos + 2, - mBufferCap - mBufferPos - 2); + int len = CharsetUtils.toModifiedUtf8Bytes(s, mBufferPtr, mBufferPos + 2, mBufferCap); if (Math.abs(len) > MAX_UNSIGNED_SHORT) { throw new IOException("Modified UTF-8 length too large: " + len); } diff --git a/core/tests/coretests/src/android/service/notification/OWNERS b/core/tests/coretests/src/android/service/notification/OWNERS new file mode 100644 index 000000000000..1502b6071b80 --- /dev/null +++ b/core/tests/coretests/src/android/service/notification/OWNERS @@ -0,0 +1,2 @@ +include platform/frameworks/base:/services/core/java/com/android/server/notification/OWNERS + diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java index 4bf01f7cffac..7f3389599a51 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java @@ -474,8 +474,10 @@ public class BubbleExpandedView extends LinearLayout { Bundle extras = new Bundle(); extras.putBinder(EXTRA_BUBBLE_CONTROLLER, ObjectWrapper.wrap(mController)); target.putExtras(extras); + // TODO(b/175352055) Please replace FLAG_MUTABLE_UNAUDITED below + // with either FLAG_IMMUTABLE (recommended) or FLAG_MUTABLE. mPendingIntent = PendingIntent.getActivity(mContext, 0 /* requestCode */, - target, PendingIntent.FLAG_UPDATE_CURRENT); + target, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE_UNAUDITED); mSettingsIcon.setVisibility(GONE); } diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java index ecdba1fe5b12..602686244388 100644 --- a/location/java/android/location/LocationManager.java +++ b/location/java/android/location/LocationManager.java @@ -2601,6 +2601,9 @@ public class LocationManager { * Returns the batch size (in number of Location objects) that are supported by the batching * interface. * + * Prior to Android S this call requires the {@link Manifest.permission#LOCATION_HARDWARE} + * permission. + * * @return Maximum number of location objects that can be returned * @deprecated Do not use * @hide diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp index fda1e3641daa..9021864a5a86 100644 --- a/packages/SystemUI/Android.bp +++ b/packages/SystemUI/Android.bp @@ -63,6 +63,7 @@ android_library { "androidx.recyclerview_recyclerview", "androidx.preference_preference", "androidx.appcompat_appcompat", + "androidx.concurrent_concurrent-futures", "androidx.mediarouter_mediarouter", "androidx.palette_palette", "androidx.legacy_legacy-preference-v14", @@ -130,6 +131,7 @@ android_library { "androidx.recyclerview_recyclerview", "androidx.preference_preference", "androidx.appcompat_appcompat", + "androidx.concurrent_concurrent-futures", "androidx.mediarouter_mediarouter", "androidx.palette_palette", "androidx.legacy_legacy-preference-v14", diff --git a/packages/SystemUI/res/values-sw600dp-land/config.xml b/packages/SystemUI/res/values-sw600dp-land/config.xml index 3b00ad1bf0c4..6dff2e3ef6c2 100644 --- a/packages/SystemUI/res/values-sw600dp-land/config.xml +++ b/packages/SystemUI/res/values-sw600dp-land/config.xml @@ -16,4 +16,7 @@ --> <resources> <integer name="quick_settings_num_columns">3</integer> + + <!-- Max number of columns for quick controls area --> + <integer name="controls_max_columns">2</integer> </resources> diff --git a/packages/SystemUI/res/values-sw600dp/config.xml b/packages/SystemUI/res/values-sw600dp/config.xml index d886f00cf028..2f5e8eaa2263 100644 --- a/packages/SystemUI/res/values-sw600dp/config.xml +++ b/packages/SystemUI/res/values-sw600dp/config.xml @@ -35,4 +35,7 @@ <!-- Whether wallet view is shown in landscape / seascape orientations --> <bool name="global_actions_show_landscape_wallet_view">true</bool> + <!-- Max number of columns for quick controls area --> + <integer name="controls_max_columns">4</integer> + </resources> diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java index 65a6f29892f0..60a14be1c2fa 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java @@ -26,6 +26,7 @@ import android.content.res.TypedArray; import android.graphics.PixelFormat; import android.graphics.Point; import android.graphics.RectF; +import android.hardware.display.DisplayManager; import android.hardware.fingerprint.FingerprintManager; import android.hardware.fingerprint.FingerprintSensorPropertiesInternal; import android.hardware.fingerprint.IUdfpsOverlayController; @@ -166,7 +167,7 @@ class UdfpsController implements DozeReceiver { @Main Resources resources, LayoutInflater inflater, @Nullable FingerprintManager fingerprintManager, - PowerManager powerManager, + DisplayManager displayManager, WindowManager windowManager, SystemSettings systemSettings, @NonNull StatusBarStateController statusBarStateController, @@ -246,7 +247,7 @@ class UdfpsController implements DozeReceiver { mBacklightToNitsSpline = Spline.createSpline(normalizedBacklightRange, nitsRange); mNitsToHbmBacklightSpline = Spline.createSpline(hbmNitsRange, normalizedBacklightRange); - mDefaultBrightness = obtainDefaultBrightness(powerManager); + mDefaultBrightness = obtainDefaultBrightness(mContext); // TODO(b/160025856): move to the "dump" method. Log.v(TAG, String.format("ctor | mNitsRange: [%f, %f]", nitsRange[0], @@ -450,14 +451,9 @@ class UdfpsController implements DozeReceiver { } } - private static float obtainDefaultBrightness(PowerManager powerManager) { - if (powerManager == null) { - Log.e(TAG, "PowerManager is unavailable. Can't obtain default brightness."); - return 0f; - } - return MathUtils.constrain(powerManager.getBrightnessConstraint( - PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_DEFAULT), PowerManager.BRIGHTNESS_MIN, - PowerManager.BRIGHTNESS_MAX); + private static float obtainDefaultBrightness(Context context) { + return MathUtils.constrain(context.getDisplay().getBrightnessDefault(), + PowerManager.BRIGHTNESS_MIN, PowerManager.BRIGHTNESS_MAX); } private static float[] toFloatArray(TypedArray array) { diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java b/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java index 334693589503..57a41d914910 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java @@ -57,7 +57,7 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.config.sysui.SystemUiDeviceConfigFlags; import com.android.systemui.R; import com.android.systemui.SystemUIFactory; -import com.android.systemui.screenshot.ScreenshotController.SavedImageData.ShareTransition; +import com.android.systemui.screenshot.ScreenshotController.SavedImageData.ActionTransition; import java.io.File; import java.io.IOException; @@ -98,11 +98,11 @@ class SaveImageInBackgroundTask extends AsyncTask<Void, Void, Void> { private final String mScreenshotId; private final boolean mSmartActionsEnabled; private final Random mRandom = new Random(); - private final Supplier<ShareTransition> mSharedElementTransition; + private final Supplier<ActionTransition> mSharedElementTransition; SaveImageInBackgroundTask(Context context, ScreenshotSmartActions screenshotSmartActions, ScreenshotController.SaveImageInBackgroundData data, - Supplier<ShareTransition> sharedElementTransition) { + Supplier<ActionTransition> sharedElementTransition) { mContext = context; mScreenshotSmartActions = screenshotSmartActions; mImageData = new ScreenshotController.SavedImageData(); @@ -239,7 +239,7 @@ class SaveImageInBackgroundTask extends AsyncTask<Void, Void, Void> { mImageData.uri = uri; mImageData.smartActions = smartActions; mImageData.shareTransition = createShareAction(mContext, mContext.getResources(), uri); - mImageData.editAction = createEditAction(mContext, mContext.getResources(), uri); + mImageData.editTransition = createEditAction(mContext, mContext.getResources(), uri); mImageData.deleteAction = createDeleteAction(mContext, mContext.getResources(), uri); mParams.mActionsReadyListener.onActionsReady(mImageData); @@ -293,9 +293,9 @@ class SaveImageInBackgroundTask extends AsyncTask<Void, Void, Void> { * Assumes that the action intent is sent immediately after being supplied. */ @VisibleForTesting - Supplier<ShareTransition> createShareAction(Context context, Resources r, Uri uri) { + Supplier<ActionTransition> createShareAction(Context context, Resources r, Uri uri) { return () -> { - ShareTransition transition = mSharedElementTransition.get(); + ActionTransition transition = mSharedElementTransition.get(); // Note: Both the share and edit actions are proxied through ActionProxyReceiver in // order to do some common work like dismissing the keyguard and sending @@ -348,52 +348,57 @@ class SaveImageInBackgroundTask extends AsyncTask<Void, Void, Void> { Icon.createWithResource(r, R.drawable.ic_screenshot_share), r.getString(com.android.internal.R.string.share), shareAction); - transition.shareAction = shareActionBuilder.build(); + transition.action = shareActionBuilder.build(); return transition; }; } @VisibleForTesting - Notification.Action createEditAction(Context context, Resources r, Uri uri) { - // Note: Both the share and edit actions are proxied through ActionProxyReceiver in - // order to do some common work like dismissing the keyguard and sending - // closeSystemWindows - - // Create an edit intent, if a specific package is provided as the editor, then - // launch that directly - String editorPackage = context.getString(R.string.config_screenshotEditor); - Intent editIntent = new Intent(Intent.ACTION_EDIT); - if (!TextUtils.isEmpty(editorPackage)) { - editIntent.setComponent(ComponentName.unflattenFromString(editorPackage)); - } - editIntent.setDataAndType(uri, "image/png"); - editIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); - editIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION); - editIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); + Supplier<ActionTransition> createEditAction(Context context, Resources r, Uri uri) { + return () -> { + ActionTransition transition = mSharedElementTransition.get(); + // Note: Both the share and edit actions are proxied through ActionProxyReceiver in + // order to do some common work like dismissing the keyguard and sending + // closeSystemWindows - PendingIntent pendingIntent = PendingIntent.getActivityAsUser(context, 0, - editIntent, PendingIntent.FLAG_IMMUTABLE, null, UserHandle.CURRENT); + // Create an edit intent, if a specific package is provided as the editor, then + // launch that directly + String editorPackage = context.getString(R.string.config_screenshotEditor); + Intent editIntent = new Intent(Intent.ACTION_EDIT); + if (!TextUtils.isEmpty(editorPackage)) { + editIntent.setComponent(ComponentName.unflattenFromString(editorPackage)); + } + editIntent.setDataAndType(uri, "image/png"); + editIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + editIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION); + editIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); - // Make sure pending intents for the system user are still unique across users - // by setting the (otherwise unused) request code to the current user id. - int requestCode = mContext.getUserId(); + PendingIntent pendingIntent = PendingIntent.getActivityAsUser( + context, 0, editIntent, PendingIntent.FLAG_IMMUTABLE, + transition.bundle, UserHandle.CURRENT); - // Create a edit action - PendingIntent editAction = PendingIntent.getBroadcastAsUser(context, requestCode, - new Intent(context, ActionProxyReceiver.class) - .putExtra(ScreenshotController.EXTRA_ACTION_INTENT, pendingIntent) - .putExtra(ScreenshotController.EXTRA_ID, mScreenshotId) - .putExtra(ScreenshotController.EXTRA_SMART_ACTIONS_ENABLED, - mSmartActionsEnabled) - .setAction(Intent.ACTION_EDIT) - .addFlags(Intent.FLAG_RECEIVER_FOREGROUND), - PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE, - UserHandle.SYSTEM); - Notification.Action.Builder editActionBuilder = new Notification.Action.Builder( - Icon.createWithResource(r, R.drawable.ic_screenshot_edit), - r.getString(com.android.internal.R.string.screenshot_edit), editAction); + // Make sure pending intents for the system user are still unique across users + // by setting the (otherwise unused) request code to the current user id. + int requestCode = mContext.getUserId(); + + // Create a edit action + PendingIntent editAction = PendingIntent.getBroadcastAsUser(context, requestCode, + new Intent(context, ActionProxyReceiver.class) + .putExtra(ScreenshotController.EXTRA_ACTION_INTENT, pendingIntent) + .putExtra(ScreenshotController.EXTRA_ID, mScreenshotId) + .putExtra(ScreenshotController.EXTRA_SMART_ACTIONS_ENABLED, + mSmartActionsEnabled) + .setAction(Intent.ACTION_EDIT) + .addFlags(Intent.FLAG_RECEIVER_FOREGROUND), + PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE, + UserHandle.SYSTEM); + Notification.Action.Builder editActionBuilder = new Notification.Action.Builder( + Icon.createWithResource(r, R.drawable.ic_screenshot_edit), + r.getString(com.android.internal.R.string.screenshot_edit), editAction); - return editActionBuilder.build(); + transition.action = editActionBuilder.build(); + return transition; + }; } @VisibleForTesting diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java index d2fe5d284a97..68d7343ec144 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java @@ -78,7 +78,7 @@ import com.android.internal.logging.UiEventLogger; import com.android.internal.policy.PhoneWindow; import com.android.settingslib.applications.InterestingConfigChanges; import com.android.systemui.R; -import com.android.systemui.screenshot.ScreenshotController.SavedImageData.ShareTransition; +import com.android.systemui.screenshot.ScreenshotController.SavedImageData.ActionTransition; import com.android.systemui.util.DeviceConfigProxy; import java.util.List; @@ -111,17 +111,17 @@ public class ScreenshotController { */ static class SavedImageData { public Uri uri; - public Supplier<ShareTransition> shareTransition; - public Notification.Action editAction; + public Supplier<ActionTransition> shareTransition; + public Supplier<ActionTransition> editTransition; public Notification.Action deleteAction; public List<Notification.Action> smartActions; /** - * POD for shared element transition to share sheet. + * POD for shared element transition. */ - static class ShareTransition { + static class ActionTransition { public Bundle bundle; - public Notification.Action shareAction; + public Notification.Action action; public Runnable onCancelRunnable; } @@ -131,7 +131,7 @@ public class ScreenshotController { public void reset() { uri = null; shareTransition = null; - editAction = null; + editTransition = null; deleteAction = null; smartActions = null; } @@ -339,6 +339,10 @@ public class ScreenshotController { } } + boolean isPendingSharedTransition() { + return mScreenshotView.isPendingSharedTransition(); + } + /** * Update resources on configuration change. Reinflate for theme/color changes. */ @@ -462,7 +466,7 @@ public class ScreenshotController { Log.d(TAG, "saveScreenshot: screenshotView is already attached, resetting. " + "(dismissing=" + mScreenshotView.isDismissing() + ")"); } - mScreenshotView.reset(); + reloadAssets(); } mScreenBitmap = screenshot; @@ -605,7 +609,7 @@ public class ScreenshotController { } mSaveInBgTask = new SaveImageInBackgroundTask(mContext, mScreenshotSmartActions, data, - getShareTransitionSupplier()); + getActionTransitionSupplier()); mSaveInBgTask.execute(); } @@ -659,7 +663,7 @@ public class ScreenshotController { * Supplies the necessary bits for the shared element transition to share sheet. * Note that once supplied, the action intent to share must be sent immediately after. */ - private Supplier<ShareTransition> getShareTransitionSupplier() { + private Supplier<ActionTransition> getActionTransitionSupplier() { return () -> { ExitTransitionCallbacks cb = new ExitTransitionCallbacks() { @Override @@ -668,7 +672,8 @@ public class ScreenshotController { } @Override - public void onFinish() { } + public void onFinish() { + } }; Pair<ActivityOptions, ExitTransitionCoordinator> transition = @@ -677,7 +682,7 @@ public class ScreenshotController { ChooserActivity.FIRST_IMAGE_PREVIEW_TRANSITION_NAME)); transition.second.startExit(); - ShareTransition supply = new ShareTransition(); + ActionTransition supply = new ActionTransition(); supply.bundle = transition.first.toBundle(); supply.onCancelRunnable = () -> ActivityOptions.stopSharedElementAnimation(mWindow); return supply; diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java index 357702ada82b..c6e0acead8b7 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java @@ -73,7 +73,7 @@ import android.widget.LinearLayout; import com.android.internal.logging.UiEventLogger; import com.android.systemui.R; -import com.android.systemui.screenshot.ScreenshotController.SavedImageData.ShareTransition; +import com.android.systemui.screenshot.ScreenshotController.SavedImageData.ActionTransition; import com.android.systemui.shared.system.QuickStepContract; import java.util.ArrayList; @@ -105,7 +105,6 @@ public class ScreenshotView extends FrameLayout implements private static final long SCREENSHOT_DISMISS_Y_DURATION_MS = 350; private static final long SCREENSHOT_DISMISS_ALPHA_DURATION_MS = 183; private static final long SCREENSHOT_DISMISS_ALPHA_OFFSET_MS = 50; // delay before starting fade - private static final long SCREENSHOT_DISMISS_SHARE_OFFSET_MS = 300; // delay after share clicked private static final float SCREENSHOT_ACTIONS_START_SCALE_X = .7f; private static final float ROUNDED_CORNER_RADIUS = .05f; private static final int SWIPE_PADDING_DP = 12; // extra padding around views to allow swipe @@ -140,7 +139,7 @@ public class ScreenshotView extends FrameLayout implements private UiEventLogger mUiEventLogger; private ScreenshotViewCallback mCallbacks; private Animator mDismissAnimation; - private boolean mIgnoreDismiss; + private boolean mPendingSharedTransition; private final ArrayList<ScreenshotActionChip> mSmartChips = new ArrayList<>(); private PendingInteraction mPendingInteraction; @@ -292,6 +291,10 @@ public class ScreenshotView extends FrameLayout implements requestFocus(); } + View getScreenshotPreview() { + return mScreenshotPreview; + } + /** * Set up the logger and callback on dismissal. * @@ -529,44 +532,22 @@ public class ScreenshotView extends FrameLayout implements }); return animator; } - protected View getScreenshotPreview() { - return mScreenshotPreview; - } void setChipIntents(ScreenshotController.SavedImageData imageData) { mShareChip.setOnClickListener(v -> { - ShareTransition transition = imageData.shareTransition.get(); - try { - mIgnoreDismiss = true; - transition.shareAction.actionIntent.send(); - mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_SHARE_TAPPED); - - // Ensures that we delay dismissing until transition has started. - postDelayed(() -> { - mIgnoreDismiss = false; - animateDismissal(); - }, SCREENSHOT_DISMISS_SHARE_OFFSET_MS); - } catch (PendingIntent.CanceledException e) { - mIgnoreDismiss = false; - if (transition.onCancelRunnable != null) { - transition.onCancelRunnable.run(); - } - Log.e(TAG, "Share intent cancelled", e); - } + mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_SHARE_TAPPED); + startSharedTransition( + imageData.shareTransition.get()); + }); + mEditChip.setOnClickListener(v -> { + mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_EDIT_TAPPED); + startSharedTransition( + imageData.editTransition.get()); }); - mEditChip.setPendingIntent(imageData.editAction.actionIntent, - () -> { - mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_EDIT_TAPPED); - animateDismissal(); - }); mScreenshotPreview.setOnClickListener(v -> { - try { - imageData.editAction.actionIntent.send(); - } catch (PendingIntent.CanceledException e) { - Log.e(TAG, "PendingIntent was cancelled", e); - } mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_PREVIEW_TAPPED); - animateDismissal(); + startSharedTransition( + imageData.editTransition.get()); }); if (mPendingInteraction != null) { @@ -605,12 +586,16 @@ public class ScreenshotView extends FrameLayout implements return (mDismissAnimation != null && mDismissAnimation.isRunning()); } + boolean isPendingSharedTransition() { + return mPendingSharedTransition; + } + void animateDismissal() { - animateDismissal(createScreenshotDismissAnimation()); + animateDismissal(createScreenshotTranslateDismissAnimation()); } private void animateDismissal(Animator dismissAnimation) { - if (mIgnoreDismiss) { + if (mPendingSharedTransition) { return; } if (DEBUG_WINDOW) { @@ -665,6 +650,7 @@ public class ScreenshotView extends FrameLayout implements getViewTreeObserver().removeOnComputeInternalInsetsListener(this); // Clear any references to the bitmap mScreenshotPreview.setImageDrawable(null); + mPendingSharedTransition = false; mActionsContainerBackground.setVisibility(View.GONE); mActionsContainer.setVisibility(View.GONE); mBackgroundProtection.setAlpha(0f); @@ -692,7 +678,23 @@ public class ScreenshotView extends FrameLayout implements mScreenshotSelectorView.stop(); } - private AnimatorSet createScreenshotDismissAnimation() { + private void startSharedTransition(ActionTransition transition) { + try { + mPendingSharedTransition = true; + transition.action.actionIntent.send(); + + // fade out non-preview UI + createScreenshotFadeDismissAnimation().start(); + } catch (PendingIntent.CanceledException e) { + mPendingSharedTransition = false; + if (transition.onCancelRunnable != null) { + transition.onCancelRunnable.run(); + } + Log.e(TAG, "Intent cancelled", e); + } + } + + private AnimatorSet createScreenshotTranslateDismissAnimation() { ValueAnimator alphaAnim = ValueAnimator.ofFloat(0, 1); alphaAnim.setStartDelay(SCREENSHOT_DISMISS_ALPHA_OFFSET_MS); alphaAnim.setDuration(SCREENSHOT_DISMISS_ALPHA_DURATION_MS); @@ -719,6 +721,19 @@ public class ScreenshotView extends FrameLayout implements return animSet; } + private ValueAnimator createScreenshotFadeDismissAnimation() { + ValueAnimator alphaAnim = ValueAnimator.ofFloat(0, 1); + alphaAnim.addUpdateListener(animation -> { + float alpha = 1 - animation.getAnimatedFraction(); + mDismissButton.setAlpha(alpha); + mActionsContainerBackground.setAlpha(alpha); + mActionsContainer.setAlpha(alpha); + mBackgroundProtection.setAlpha(alpha); + }); + alphaAnim.setDuration(600); + return alphaAnim; + } + /** * Create a drawable using the size of the bitmap and insets as the fractional inset parameters. */ diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java b/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java index c2b20d37f3f3..7621587ac838 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java @@ -72,7 +72,9 @@ public class TakeScreenshotService extends Service { if (DEBUG_DISMISS) { Log.d(TAG, "Received ACTION_CLOSE_SYSTEM_DIALOGS"); } - mScreenshot.dismissScreenshot(false); + if (!mScreenshot.isPendingSharedTransition()) { + mScreenshot.dismissScreenshot(false); + } } } }; diff --git a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessController.java b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessController.java index be10c26df5bf..a3b5f27933be 100644 --- a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessController.java +++ b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessController.java @@ -316,8 +316,7 @@ public class BrightnessController implements ToggleSlider.Listener { PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_MINIMUM); mMaximumBacklight = pm.getBrightnessConstraint( PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_MAXIMUM); - mDefaultBacklight = pm.getBrightnessConstraint( - PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_DEFAULT); + mDefaultBacklight = mContext.getDisplay().getBrightnessDefault(); mMinimumBacklightForVr = pm.getBrightnessConstraint( PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_MINIMUM_VR); mMaximumBacklightForVr = pm.getBrightnessConstraint( diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java index 7f8372e4bc44..a65c35290478 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java @@ -27,6 +27,7 @@ import static org.mockito.Mockito.when; import android.content.res.Resources; import android.content.res.TypedArray; import android.hardware.biometrics.SensorProperties; +import android.hardware.display.DisplayManager; import android.hardware.fingerprint.FingerprintManager; import android.hardware.fingerprint.FingerprintSensorProperties; import android.hardware.fingerprint.FingerprintSensorPropertiesInternal; @@ -84,7 +85,7 @@ public class UdfpsControllerTest extends SysuiTestCase { @Mock private FingerprintManager mFingerprintManager; @Mock - private PowerManager mPowerManager; + private DisplayManager mDisplayManager; @Mock private WindowManager mWindowManager; @Mock @@ -124,7 +125,7 @@ public class UdfpsControllerTest extends SysuiTestCase { mResources, mLayoutInflater, mFingerprintManager, - mPowerManager, + mDisplayManager, mWindowManager, mSystemSettings, mStatusBarStateController, diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotNotificationSmartActionsTest.java b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotNotificationSmartActionsTest.java index 6759c9075356..c79416a76fb2 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotNotificationSmartActionsTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotNotificationSmartActionsTest.java @@ -43,7 +43,7 @@ import androidx.test.filters.SmallTest; import com.android.systemui.SystemUIFactory; import com.android.systemui.SysuiTestCase; -import com.android.systemui.screenshot.ScreenshotController.SavedImageData.ShareTransition; +import com.android.systemui.screenshot.ScreenshotController.SavedImageData.ActionTransition; import org.junit.Before; import org.junit.Test; @@ -177,10 +177,10 @@ public class ScreenshotNotificationSmartActionsTest extends SysuiTestCase { data.mActionsReadyListener = null; SaveImageInBackgroundTask task = new SaveImageInBackgroundTask(mContext, mScreenshotSmartActions, data, - ShareTransition::new); + ActionTransition::new); Notification.Action shareAction = task.createShareAction(mContext, mContext.getResources(), - Uri.parse("Screenshot_123.png")).get().shareAction; + Uri.parse("Screenshot_123.png")).get().action; Intent intent = shareAction.actionIntent.getIntent(); assertNotNull(intent); @@ -205,10 +205,10 @@ public class ScreenshotNotificationSmartActionsTest extends SysuiTestCase { data.mActionsReadyListener = null; SaveImageInBackgroundTask task = new SaveImageInBackgroundTask(mContext, mScreenshotSmartActions, data, - ShareTransition::new); + ActionTransition::new); Notification.Action editAction = task.createEditAction(mContext, mContext.getResources(), - Uri.parse("Screenshot_123.png")); + Uri.parse("Screenshot_123.png")).get().action; Intent intent = editAction.actionIntent.getIntent(); assertNotNull(intent); @@ -233,7 +233,7 @@ public class ScreenshotNotificationSmartActionsTest extends SysuiTestCase { data.mActionsReadyListener = null; SaveImageInBackgroundTask task = new SaveImageInBackgroundTask(mContext, mScreenshotSmartActions, data, - ShareTransition::new); + ActionTransition::new); Notification.Action deleteAction = task.createDeleteAction(mContext, mContext.getResources(), diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/InflatedSmartRepliesTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/InflatedSmartRepliesTest.java index 8ee15bb36834..32675c92d3f9 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/InflatedSmartRepliesTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/InflatedSmartRepliesTest.java @@ -425,7 +425,8 @@ public class InflatedSmartRepliesTest extends SysuiTestCase { private void setupAppGeneratedReplies( CharSequence[] smartReplies, boolean allowSystemGeneratedReplies) { PendingIntent pendingIntent = - PendingIntent.getBroadcast(mContext, 0, TEST_INTENT, 0); + PendingIntent.getBroadcast(mContext, 0, TEST_INTENT, + PendingIntent.FLAG_MUTABLE); Notification.Action action = new Notification.Action.Builder(null, "Test Action", pendingIntent).build(); when(mRemoteInput.getChoices()).thenReturn(smartReplies); @@ -456,7 +457,8 @@ public class InflatedSmartRepliesTest extends SysuiTestCase { } private Notification.Action.Builder createActionBuilder(String actionTitle, Intent intent) { - PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0, intent, 0); + PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0, intent, + PendingIntent.FLAG_MUTABLE); return new Notification.Action.Builder(mActionIcon, actionTitle, pendingIntent); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputViewTest.java index 4fb85ad1bb4d..a844d099d43a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputViewTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputViewTest.java @@ -102,7 +102,7 @@ public class RemoteInputViewTest extends SysuiTestCase { private void setTestPendingIntent(RemoteInputView view) { PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0, - new Intent(TEST_ACTION), 0); + new Intent(TEST_ACTION), PendingIntent.FLAG_MUTABLE); RemoteInput input = new RemoteInput.Builder(TEST_RESULT_KEY).build(); view.setPendingIntent(pendingIntent); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java index 836a81e42193..5de62b908c64 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java @@ -492,7 +492,8 @@ public class SmartReplyViewTest extends SysuiTestCase { private SmartReplyView.SmartReplies createSmartReplies(CharSequence[] choices, boolean fromAssistant) { PendingIntent pendingIntent = - PendingIntent.getBroadcast(mContext, 0, new Intent(TEST_ACTION), 0); + PendingIntent.getBroadcast(mContext, 0, new Intent(TEST_ACTION), + PendingIntent.FLAG_MUTABLE); RemoteInput input = new RemoteInput.Builder(TEST_RESULT_KEY).setChoices(choices).build(); return new SmartReplyView.SmartReplies( Arrays.asList(choices), input, pendingIntent, fromAssistant); @@ -508,7 +509,7 @@ public class SmartReplyViewTest extends SysuiTestCase { private Notification.Action createAction(String actionTitle) { PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0, - new Intent(TEST_ACTION), 0); + new Intent(TEST_ACTION), PendingIntent.FLAG_MUTABLE); return new Notification.Action.Builder(mActionIcon, actionTitle, pendingIntent).build(); } diff --git a/services/core/java/com/android/server/content/SyncManager.java b/services/core/java/com/android/server/content/SyncManager.java index 6ae410a49786..fe89903c02d7 100644 --- a/services/core/java/com/android/server/content/SyncManager.java +++ b/services/core/java/com/android/server/content/SyncManager.java @@ -3838,12 +3838,10 @@ public class SyncManager { } UserHandle user = new UserHandle(userId); - // TODO(b/174186839) Please replace FLAG_MUTABLE_UNAUDITED below - // with either FLAG_IMMUTABLE (recommended) or FLAG_MUTABLE. final PendingIntent pendingIntent = PendingIntent .getActivityAsUser(mContext, 0, clickIntent, - PendingIntent.FLAG_CANCEL_CURRENT - | PendingIntent.FLAG_MUTABLE_UNAUDITED, null, user); + PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE, + null, user); CharSequence tooManyDeletesDescFormat = mContext.getResources().getText( R.string.contentServiceTooManyDeletesNotificationDesc); diff --git a/services/core/java/com/android/server/display/DisplayDeviceConfig.java b/services/core/java/com/android/server/display/DisplayDeviceConfig.java index 574d8c6d848a..0a30e07165f9 100644 --- a/services/core/java/com/android/server/display/DisplayDeviceConfig.java +++ b/services/core/java/com/android/server/display/DisplayDeviceConfig.java @@ -16,10 +16,13 @@ package com.android.server.display; +import android.content.Context; import android.os.Environment; +import android.os.PowerManager; import android.util.Slog; import android.view.DisplayAddress; +import com.android.internal.BrightnessSynchronizer; import com.android.server.display.config.DisplayConfiguration; import com.android.server.display.config.DisplayQuirks; import com.android.server.display.config.NitsMap; @@ -33,6 +36,7 @@ import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; +import java.math.BigDecimal; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -49,6 +53,7 @@ public class DisplayDeviceConfig { public static final String QUIRK_CAN_SET_BRIGHTNESS_VIA_HWC = "canSetBrightnessViaHwc"; + private static final float BRIGHTNESS_DEFAULT = 0.5f; private static final String ETC_DIR = "etc"; private static final String DISPLAY_CONFIG_DIR = "displayconfig"; private static final String CONFIG_FILE_FORMAT = "display_%s.xml"; @@ -57,11 +62,21 @@ public class DisplayDeviceConfig { private static final String NO_SUFFIX_FORMAT = "%d"; private static final long STABLE_FLAG = 1L << 62; + // Float.NaN (used as invalid for brightness) cannot be stored in config.xml + // so -2 is used instead + private static final float INVALID_BRIGHTNESS_IN_CONFIG = -2f; + private float[] mNits; private float[] mBrightness; + private float mBrightnessMinimum = Float.NaN; + private float mBrightnessMaximum = Float.NaN; + private float mBrightnessDefault = Float.NaN; private List<String> mQuirks; - private DisplayDeviceConfig() { + private final Context mContext; + + private DisplayDeviceConfig(Context context) { + mContext = context; } /** @@ -72,37 +87,50 @@ public class DisplayDeviceConfig { * <li>physicalDisplayId without a stable flag (old system)</li> * <li>portId</li> * </ol> + * * @param physicalDisplayId The display ID for which to load the configuration. * @return A configuration instance for the specified display. */ - public static DisplayDeviceConfig create(long physicalDisplayId) { + public static DisplayDeviceConfig create(Context context, long physicalDisplayId, + boolean isDefaultDisplay) { DisplayDeviceConfig config; - config = loadConfigFromDirectory(Environment.getProductDirectory(), physicalDisplayId); + config = loadConfigFromDirectory(context, Environment.getProductDirectory(), + physicalDisplayId); if (config != null) { return config; } - config = loadConfigFromDirectory(Environment.getVendorDirectory(), physicalDisplayId); + config = loadConfigFromDirectory(context, Environment.getVendorDirectory(), + physicalDisplayId); if (config != null) { return config; } - return null; + // If no config can be loaded from any ddc xml at all, + // prepare a whole config using the global config.xml. + // Guaranteed not null + if (isDefaultDisplay) { + config = getConfigFromGlobalXml(context); + } else { + config = getConfigFromPmValues(context); + } + return config; } - private static DisplayDeviceConfig loadConfigFromDirectory( + private static DisplayDeviceConfig loadConfigFromDirectory(Context context, File baseDirectory, long physicalDisplayId) { DisplayDeviceConfig config; // Create config using filename from physical ID (including "stable" bit). - config = getConfigFromSuffix(baseDirectory, STABLE_ID_SUFFIX_FORMAT, physicalDisplayId); + config = getConfigFromSuffix(context, baseDirectory, STABLE_ID_SUFFIX_FORMAT, + physicalDisplayId); if (config != null) { return config; } // Create config using filename from physical ID (excluding "stable" bit). final long withoutStableFlag = physicalDisplayId & ~STABLE_FLAG; - config = getConfigFromSuffix(baseDirectory, NO_SUFFIX_FORMAT, withoutStableFlag); + config = getConfigFromSuffix(context, baseDirectory, NO_SUFFIX_FORMAT, withoutStableFlag); if (config != null) { return config; } @@ -111,14 +139,8 @@ public class DisplayDeviceConfig { final DisplayAddress.Physical physicalAddress = DisplayAddress.fromPhysicalDisplayId(physicalDisplayId); int port = physicalAddress.getPort(); - config = getConfigFromSuffix(baseDirectory, PORT_SUFFIX_FORMAT, port); - if (config != null) { - return config; - } - - // None of these files exist. - return null; - + config = getConfigFromSuffix(context, baseDirectory, PORT_SUFFIX_FORMAT, port); + return config; } /** @@ -139,6 +161,18 @@ public class DisplayDeviceConfig { return mBrightness; } + public float getBrightnessMinimum() { + return mBrightnessMinimum; + } + + public float getBrightnessMaximum() { + return mBrightnessMaximum; + } + + public float getBrightnessDefault() { + return mBrightnessDefault; + } + /** * @param quirkValue The quirk to test. * @return {@code true} if the specified quirk is present in this configuration, @@ -153,12 +187,15 @@ public class DisplayDeviceConfig { String str = "DisplayDeviceConfig{" + "mBrightness=" + Arrays.toString(mBrightness) + ", mNits=" + Arrays.toString(mNits) + + ", mBrightnessMinimum=" + mBrightnessMinimum + + ", mBrightnessMaximum=" + mBrightnessMaximum + + ", mBrightnessDefault=" + mBrightnessDefault + ", mQuirks=" + mQuirks + "}"; return str; } - private static DisplayDeviceConfig getConfigFromSuffix(File baseDirectory, + private static DisplayDeviceConfig getConfigFromSuffix(Context context, File baseDirectory, String suffixFormat, long idNumber) { final String suffix = String.format(suffixFormat, idNumber); @@ -167,13 +204,25 @@ public class DisplayDeviceConfig { baseDirectory, ETC_DIR, DISPLAY_CONFIG_DIR, filename); if (filePath.exists()) { - final DisplayDeviceConfig config = new DisplayDeviceConfig(); + final DisplayDeviceConfig config = new DisplayDeviceConfig(context); config.initFromFile(filePath); return config; } return null; } + private static DisplayDeviceConfig getConfigFromGlobalXml(Context context) { + DisplayDeviceConfig config = new DisplayDeviceConfig(context); + config.initFromGlobalXml(); + return config; + } + + private static DisplayDeviceConfig getConfigFromPmValues(Context context) { + DisplayDeviceConfig config = new DisplayDeviceConfig(context); + config.initFromPmValues(); + return config; + } + private void initFromFile(File configFile) { if (!configFile.exists()) { // Display configuration files aren't required to exist. @@ -187,16 +236,87 @@ public class DisplayDeviceConfig { try (InputStream in = new BufferedInputStream(new FileInputStream(configFile))) { final DisplayConfiguration config = XmlParser.read(in); - loadBrightnessMap(config); - loadQuirks(config); + if (config != null) { + loadBrightnessMap(config); + loadBrightnessDefaultFromDdcXml(config); + loadBrightnessConstraintsFromConfigXml(); + loadQuirks(config); + } else { + Slog.w(TAG, "DisplayDeviceConfig file is null"); + } } catch (IOException | DatatypeConfigurationException | XmlPullParserException e) { Slog.e(TAG, "Encountered an error while reading/parsing display config file: " + configFile, e); } } + private void initFromGlobalXml() { + // If no ddc exists, use config.xml + loadBrightnessDefaultFromConfigXml(); + loadBrightnessConstraintsFromConfigXml(); + } + + private void initFromPmValues() { + mBrightnessMinimum = PowerManager.BRIGHTNESS_MIN; + mBrightnessMaximum = PowerManager.BRIGHTNESS_MAX; + mBrightnessDefault = BRIGHTNESS_DEFAULT; + } + + private void loadBrightnessDefaultFromDdcXml(DisplayConfiguration config) { + // Default brightness values are stored in the displayDeviceConfig file, + // Or we fallback standard values if not. + // Priority 1: Value in the displayDeviceConfig + // Priority 2: Value in the config.xml (float) + // Priority 3: Value in the config.xml (int) + if (config != null) { + BigDecimal configBrightnessDefault = config.getScreenBrightnessDefault(); + if (configBrightnessDefault != null) { + mBrightnessDefault = configBrightnessDefault.floatValue(); + } else { + mBrightnessDefault = BRIGHTNESS_DEFAULT; + } + } + } + + private void loadBrightnessDefaultFromConfigXml() { + // Priority 1: Value in the config.xml (float) + // Priority 2: Value in the config.xml (int) + final float def = mContext.getResources().getFloat(com.android.internal.R.dimen + .config_screenBrightnessSettingDefaultFloat); + if (def == INVALID_BRIGHTNESS_IN_CONFIG) { + mBrightnessDefault = BrightnessSynchronizer.brightnessIntToFloat( + mContext.getResources().getInteger(com.android.internal.R.integer + .config_screenBrightnessSettingDefault)); + } else { + mBrightnessDefault = def; + } + } + + private void loadBrightnessConstraintsFromConfigXml() { + // TODO(b/175373898) add constraints (min / max) to ddc. + final float min = mContext.getResources().getFloat(com.android.internal.R.dimen + .config_screenBrightnessSettingMinimumFloat); + final float max = mContext.getResources().getFloat(com.android.internal.R.dimen + .config_screenBrightnessSettingMaximumFloat); + if (min == INVALID_BRIGHTNESS_IN_CONFIG || max == INVALID_BRIGHTNESS_IN_CONFIG) { + mBrightnessMinimum = BrightnessSynchronizer.brightnessIntToFloat( + mContext.getResources().getInteger(com.android.internal.R.integer + .config_screenBrightnessSettingMinimum)); + mBrightnessMaximum = BrightnessSynchronizer.brightnessIntToFloat( + mContext.getResources().getInteger(com.android.internal.R.integer + .config_screenBrightnessSettingMaximum)); + } else { + mBrightnessMinimum = min; + mBrightnessMaximum = max; + } + } + private void loadBrightnessMap(DisplayConfiguration config) { final NitsMap map = config.getScreenBrightnessMap(); + // Map may not exist in config file + if (map == null) { + return; + } final List<Point> points = map.getPoint(); final int size = points.size(); diff --git a/services/core/java/com/android/server/display/DisplayDeviceInfo.java b/services/core/java/com/android/server/display/DisplayDeviceInfo.java index 468d8259db18..2641ee7ed33e 100644 --- a/services/core/java/com/android/server/display/DisplayDeviceInfo.java +++ b/services/core/java/com/android/server/display/DisplayDeviceInfo.java @@ -25,6 +25,8 @@ import android.view.DisplayCutout; import android.view.DisplayEventReceiver; import android.view.Surface; +import com.android.internal.BrightnessSynchronizer; + import java.util.Arrays; import java.util.Objects; @@ -337,6 +339,10 @@ final class DisplayDeviceInfo { public DisplayEventReceiver.FrameRateOverride[] frameRateOverrides = new DisplayEventReceiver.FrameRateOverride[0]; + public float brightnessMinimum; + public float brightnessMaximum; + public float brightnessDefault; + public void setAssumedDensityForExternalDisplay(int width, int height) { densityDpi = Math.min(width, height) * DisplayMetrics.DENSITY_XHIGH / 1080; // Technically, these values should be smaller than the apparent density @@ -391,7 +397,11 @@ final class DisplayDeviceInfo { || !Objects.equals(deviceProductInfo, other.deviceProductInfo) || ownerUid != other.ownerUid || !Objects.equals(ownerPackageName, other.ownerPackageName) - || !Objects.equals(frameRateOverrides, other.frameRateOverrides)) { + || !Objects.equals(frameRateOverrides, other.frameRateOverrides) + || !BrightnessSynchronizer.floatEquals(brightnessMinimum, other.brightnessMinimum) + || !BrightnessSynchronizer.floatEquals(brightnessMaximum, other.brightnessMaximum) + || !BrightnessSynchronizer.floatEquals(brightnessDefault, + other.brightnessDefault)) { diff |= DIFF_OTHER; } return diff; @@ -431,6 +441,9 @@ final class DisplayDeviceInfo { ownerUid = other.ownerUid; ownerPackageName = other.ownerPackageName; frameRateOverrides = other.frameRateOverrides; + brightnessMinimum = other.brightnessMinimum; + brightnessMaximum = other.brightnessMaximum; + brightnessDefault = other.brightnessDefault; } // For debugging purposes @@ -471,6 +484,9 @@ final class DisplayDeviceInfo { for (DisplayEventReceiver.FrameRateOverride frameRateOverride : frameRateOverrides) { sb.append(frameRateOverride).append(" "); } + sb.append(", brightnessMinimum ").append(brightnessMinimum); + sb.append(", brightnessMaximum ").append(brightnessMaximum); + sb.append(", brightnessDefault ").append(brightnessDefault); sb.append(flagsToString(flags)); sb.append("}"); return sb.toString(); diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java index 2c7cd5bce514..6fa244e2d9ee 100644 --- a/services/core/java/com/android/server/display/DisplayManagerService.java +++ b/services/core/java/com/android/server/display/DisplayManagerService.java @@ -288,9 +288,6 @@ public final class DisplayManagerService extends SystemService { @GuardedBy("mSyncRoot") private final SparseArray<Float> mDisplayBrightnesses = new SparseArray<>(); - // The default brightness. - private final float mDisplayDefaultBrightness; - // Set to true when there are pending display changes that have yet to be applied // to the surface flinger state. private boolean mPendingTraversal; @@ -416,9 +413,6 @@ public final class DisplayManagerService extends SystemService { mMinimumBrightnessCurve = new Curve(lux, nits); mMinimumBrightnessSpline = Spline.createSpline(lux, nits); - PowerManager pm = mContext.getSystemService(PowerManager.class); - mDisplayDefaultBrightness = pm.getBrightnessConstraint( - PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_DEFAULT); mCurrentUserId = UserHandle.USER_SYSTEM; ColorSpace[] colorSpaces = SurfaceControl.getCompositionColorSpaces(); mWideColorSpace = colorSpaces[1]; @@ -1108,7 +1102,7 @@ public final class DisplayManagerService extends SystemService { } addDisplayPowerControllerLocked(displayId); mDisplayStates.append(displayId, Display.STATE_OFF); - mDisplayBrightnesses.append(displayId, mDisplayDefaultBrightness); + mDisplayBrightnesses.append(displayId, display.getDisplayInfoLocked().brightnessDefault); DisplayManagerGlobal.invalidateLocalDisplayInfoCaches(); @@ -1876,7 +1870,7 @@ public final class DisplayManagerService extends SystemService { } final DisplayPowerController displayPowerController = new DisplayPowerController( mContext, mDisplayPowerCallbacks, mPowerHandler, mSensorManager, - mDisplayBlanker, displayId); + mDisplayBlanker, mLogicalDisplayMapper.getLocked(displayId)); mDisplayPowerControllers.append(displayId, displayPowerController); } diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java index f48826055028..e31704f03cd9 100644 --- a/services/core/java/com/android/server/display/DisplayPowerController.java +++ b/services/core/java/com/android/server/display/DisplayPowerController.java @@ -163,6 +163,9 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call // The display blanker. private final DisplayBlanker mBlanker; + // The LogicalDisplay tied to this DisplayPowerController. + private final LogicalDisplay mLogicalDisplay; + // The ID of the LogicalDisplay tied to this DisplayPowerController. private final int mDisplayId; @@ -406,7 +409,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call */ public DisplayPowerController(Context context, DisplayPowerCallbacks callbacks, Handler handler, - SensorManager sensorManager, DisplayBlanker blanker, int displayId) { + SensorManager sensorManager, DisplayBlanker blanker, LogicalDisplay logicalDisplay) { mHandler = new DisplayControllerHandler(handler.getLooper()); mBrightnessTracker = new BrightnessTracker(context, null); mSettingsObserver = new SettingsObserver(mHandler); @@ -418,9 +421,10 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call mContext = context; mBrightnessSynchronizer = new BrightnessSynchronizer(context); mBrightnessSynchronizer.startSynchronizing(); - mDisplayId = displayId; + mLogicalDisplay = logicalDisplay; + mDisplayId = mLogicalDisplay.getDisplayIdLocked(); - PowerManager pm = context.getSystemService(PowerManager.class); + PowerManager pm = context.getSystemService(PowerManager.class); final Resources resources = context.getResources(); @@ -439,7 +443,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call mScreenBrightnessRangeMaximum = clampAbsoluteBrightness( pm.getBrightnessConstraint(PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_MAXIMUM)); mScreenBrightnessDefault = clampAbsoluteBrightness( - pm.getBrightnessConstraint(PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_DEFAULT)); + mLogicalDisplay.getDisplayInfoLocked().brightnessDefault); // VR SETTINGS mScreenBrightnessForVrDefault = clampAbsoluteBrightness( @@ -1833,6 +1837,9 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call pw.println(); pw.println("Display Power Controller Configuration:"); + pw.println(" mScreenBrightnessRangeMinimum=" + mScreenBrightnessRangeMinimum); + pw.println(" mScreenBrightnessRangeMaximum=" + mScreenBrightnessRangeMaximum); + pw.println(" mScreenBrightnessRangeDefault=" + mScreenBrightnessDefault); pw.println(" mScreenBrightnessDozeConfig=" + mScreenBrightnessDozeConfig); pw.println(" mScreenBrightnessDimConfig=" + mScreenBrightnessDimConfig); pw.println(" mScreenBrightnessDefault=" + mScreenBrightnessDefault); diff --git a/services/core/java/com/android/server/display/LocalDisplayAdapter.java b/services/core/java/com/android/server/display/LocalDisplayAdapter.java index 9b8ed3a2dd8c..8198e510f8e2 100644 --- a/services/core/java/com/android/server/display/LocalDisplayAdapter.java +++ b/services/core/java/com/android/server/display/LocalDisplayAdapter.java @@ -415,7 +415,9 @@ final class LocalDisplayAdapter extends DisplayAdapter { Spline sysToNits = null; // Load the mapping from nits to HAL brightness range (display-device-config.xml) - mDisplayDeviceConfig = DisplayDeviceConfig.create(mPhysicalDisplayId); + final Context context = getOverlayContext(); + mDisplayDeviceConfig = DisplayDeviceConfig.create(context, mPhysicalDisplayId, + mIsDefaultDisplay); if (mDisplayDeviceConfig == null) { return; } @@ -431,9 +433,9 @@ final class LocalDisplayAdapter extends DisplayAdapter { nitsToHal = Spline.createSpline(halNits, halBrightness); // Load the mapping from system brightness range to nits (config.xml) - final Resources res = getOverlayContext().getResources(); + final Resources res = context.getResources(); final float[] sysNits = BrightnessMappingStrategy.getFloatArray(res.obtainTypedArray( - com.android.internal.R.array.config_screenBrightnessNits)); + com.android.internal.R.array.config_screenBrightnessNits)); final int[] sysBrightness = res.getIntArray( com.android.internal.R.array.config_screenBrightnessBacklight); if (sysNits.length == 0 || sysBrightness.length != sysNits.length) { @@ -630,6 +632,15 @@ final class LocalDisplayAdapter extends DisplayAdapter { // The display is trusted since it is created by system. mInfo.flags |= DisplayDeviceInfo.FLAG_TRUSTED; + if (mDisplayDeviceConfig != null) { + mInfo.brightnessMinimum = mDisplayDeviceConfig.getBrightnessMinimum(); + mInfo.brightnessMaximum = mDisplayDeviceConfig.getBrightnessMaximum(); + mInfo.brightnessDefault = mDisplayDeviceConfig.getBrightnessDefault(); + } else { + mInfo.brightnessMinimum = PowerManager.BRIGHTNESS_MIN; + mInfo.brightnessMaximum = PowerManager.BRIGHTNESS_MAX; + mInfo.brightnessDefault = 0.5f; + } } return mInfo; } @@ -997,7 +1008,7 @@ final class LocalDisplayAdapter extends DisplayAdapter { pw.println(" " + mSupportedModes.valueAt(i)); } pw.println("mSupportedColorModes=" + mSupportedColorModes.toString()); - pw.print("mDisplayDeviceConfig=" + mDisplayDeviceConfig); + pw.println("mDisplayDeviceConfig=" + mDisplayDeviceConfig); } private int findDisplayConfigIdLocked(int modeId, int configGroup) { diff --git a/services/core/java/com/android/server/display/LogicalDisplay.java b/services/core/java/com/android/server/display/LogicalDisplay.java index d80e1687f67f..5bf83db4ee34 100644 --- a/services/core/java/com/android/server/display/LogicalDisplay.java +++ b/services/core/java/com/android/server/display/LogicalDisplay.java @@ -366,7 +366,9 @@ final class LogicalDisplay { mBaseDisplayInfo.displayCutout = maskCutout ? null : deviceInfo.displayCutout; mBaseDisplayInfo.displayId = mDisplayId; updateFrameRateOverrides(deviceInfo); - + mBaseDisplayInfo.brightnessMinimum = deviceInfo.brightnessMinimum; + mBaseDisplayInfo.brightnessMaximum = deviceInfo.brightnessMaximum; + mBaseDisplayInfo.brightnessDefault = deviceInfo.brightnessDefault; mPrimaryDisplayDeviceInfo = deviceInfo; mInfo.set(null); } diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index 6919ceaa5a9f..6e4806f84bf4 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -2698,8 +2698,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { float stepFloat = (maxFloat - minFloat) / BRIGHTNESS_STEPS * direction; float brightnessFloat = Settings.System.getFloatForUser( mContext.getContentResolver(), Settings.System.SCREEN_BRIGHTNESS_FLOAT, - mPowerManager.getBrightnessConstraint( - PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_DEFAULT), + mContext.getDisplay().getBrightnessDefault(), UserHandle.USER_CURRENT_OR_SELF); brightnessFloat += stepFloat; // Make sure we don't go beyond the limits. diff --git a/services/core/xsd/display-device-config/display-device-config.xsd b/services/core/xsd/display-device-config/display-device-config.xsd index d6709910d133..88964b746aca 100644 --- a/services/core/xsd/display-device-config/display-device-config.xsd +++ b/services/core/xsd/display-device-config/display-device-config.xsd @@ -29,6 +29,10 @@ <xs:annotation name="nonnull"/> <xs:annotation name="final"/> </xs:element> + <xs:element type="nonNegativeDecimal" name="screenBrightnessDefault"> + <xs:annotation name="nonnull"/> + <xs:annotation name="final"/> + </xs:element> <xs:element type="displayQuirks" name="quirks" minOccurs="0" maxOccurs="1" /> </xs:sequence> </xs:complexType> diff --git a/services/core/xsd/display-device-config/schema/current.txt b/services/core/xsd/display-device-config/schema/current.txt index e68ca260f55f..6906fda5b76f 100644 --- a/services/core/xsd/display-device-config/schema/current.txt +++ b/services/core/xsd/display-device-config/schema/current.txt @@ -4,8 +4,10 @@ package com.android.server.display.config { public class DisplayConfiguration { ctor public DisplayConfiguration(); method public com.android.server.display.config.DisplayQuirks getQuirks(); + method @NonNull public final java.math.BigDecimal getScreenBrightnessDefault(); method @NonNull public final com.android.server.display.config.NitsMap getScreenBrightnessMap(); method public void setQuirks(com.android.server.display.config.DisplayQuirks); + method public final void setScreenBrightnessDefault(@NonNull java.math.BigDecimal); method public final void setScreenBrightnessMap(@NonNull com.android.server.display.config.NitsMap); } diff --git a/telephony/java/android/telephony/SmsManager.java b/telephony/java/android/telephony/SmsManager.java index e145fcfa2dff..e06dcdb7e736 100644 --- a/telephony/java/android/telephony/SmsManager.java +++ b/telephony/java/android/telephony/SmsManager.java @@ -638,7 +638,7 @@ public final class SmsManager { persistMessage, messageId); } catch (RemoteException e) { Log.e(TAG, "sendTextMessageInternal: Couldn't send SMS, exception - " - + e.getMessage() + " id: " + messageId); + + e.getMessage() + " " + formatCrossStackMessageId(messageId)); notifySmsError(sentIntent, RESULT_REMOTE_EXCEPTION); } } @@ -658,7 +658,7 @@ public final class SmsManager { persistMessage, messageId); } catch (RemoteException e) { Log.e(TAG, "sendTextMessageInternal (no persist): Couldn't send SMS, exception - " - + e.getMessage() + " id: " + messageId); + + e.getMessage() + " " + formatCrossStackMessageId(messageId)); notifySmsError(sentIntent, RESULT_REMOTE_EXCEPTION); } } @@ -1072,8 +1072,7 @@ public final class SmsManager { deliveryIntents, persistMessage, messageId); } catch (RemoteException e) { Log.e(TAG, "sendMultipartTextMessageInternal: Couldn't send SMS - " - + e.getMessage() + " id: " - + messageId); + + e.getMessage() + " " + formatCrossStackMessageId(messageId)); notifySmsError(sentIntents, RESULT_REMOTE_EXCEPTION); } } @@ -1094,7 +1093,7 @@ public final class SmsManager { } } catch (RemoteException e) { Log.e(TAG, "sendMultipartTextMessageInternal: Couldn't send SMS - " - + e.getMessage() + " id: " + messageId); + + e.getMessage() + " " + formatCrossStackMessageId(messageId)); notifySmsError(sentIntents, RESULT_REMOTE_EXCEPTION); } } @@ -3150,4 +3149,8 @@ public final class SmsManager { ex.rethrowFromSystemServer(); } } + + private static String formatCrossStackMessageId(long id) { + return "{x-message-id:" + id + "}"; + } } |