diff options
10 files changed, 679 insertions, 1 deletions
diff --git a/media/java/android/media/quality/AmbientBacklightEvent.aidl b/media/java/android/media/quality/AmbientBacklightEvent.aidl new file mode 100644 index 000000000000..174cd461e846 --- /dev/null +++ b/media/java/android/media/quality/AmbientBacklightEvent.aidl @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.media.quality; + +parcelable AmbientBacklightEvent; diff --git a/media/java/android/media/quality/AmbientBacklightEvent.java b/media/java/android/media/quality/AmbientBacklightEvent.java new file mode 100644 index 000000000000..3bc6b86c0615 --- /dev/null +++ b/media/java/android/media/quality/AmbientBacklightEvent.java @@ -0,0 +1,136 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.media.quality; + +import android.annotation.IntDef; +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.os.Parcel; +import android.os.Parcelable; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.util.Objects; + +/** + * @hide + */ +public final class AmbientBacklightEvent implements Parcelable { + + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef({AMBIENT_BACKLIGHT_EVENT_ENABLED, AMBIENT_BACKLIGHT_EVENT_DISABLED, + AMBIENT_BACKLIGHT_EVENT_METADATA, + AMBIENT_BACKLIGHT_EVENT_INTERRUPTED}) + public @interface AmbientBacklightEventTypes {} + + /** + * Event type for ambient backlight events. The ambient backlight is enabled. + */ + public static final int AMBIENT_BACKLIGHT_EVENT_ENABLED = 1; + + /** + * Event type for ambient backlight events. The ambient backlight is disabled. + */ + public static final int AMBIENT_BACKLIGHT_EVENT_DISABLED = 2; + + /** + * Event type for ambient backlight events. The ambient backlight metadata is + * available. + */ + public static final int AMBIENT_BACKLIGHT_EVENT_METADATA = 3; + + /** + * Event type for ambient backlight events. The ambient backlight event is preempted by another + * application. + */ + public static final int AMBIENT_BACKLIGHT_EVENT_INTERRUPTED = 4; + + private final int mEventType; + @Nullable + private final AmbientBacklightMetadata mMetadata; + + public AmbientBacklightEvent(int eventType, + @Nullable AmbientBacklightMetadata metadata) { + mEventType = eventType; + mMetadata = metadata; + } + + private AmbientBacklightEvent(Parcel in) { + mEventType = in.readInt(); + mMetadata = in.readParcelable(AmbientBacklightMetadata.class.getClassLoader()); + } + + public int getEventType() { + return mEventType; + } + + @Nullable + public AmbientBacklightMetadata getMetadata() { + return mMetadata; + } + + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { + dest.writeInt(mEventType); + dest.writeParcelable(mMetadata, flags); + } + + @Override + public int describeContents() { + return 0; + } + + public static final @NonNull Parcelable.Creator<AmbientBacklightEvent> CREATOR = + new Parcelable.Creator<AmbientBacklightEvent>() { + public AmbientBacklightEvent createFromParcel(Parcel in) { + return new AmbientBacklightEvent(in); + } + + public AmbientBacklightEvent[] newArray(int size) { + return new AmbientBacklightEvent[size]; + } + }; + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (!(obj instanceof AmbientBacklightEvent)) { + return false; + } + + AmbientBacklightEvent other = (AmbientBacklightEvent) obj; + return mEventType == other.mEventType + && Objects.equals(mMetadata, other.mMetadata); + } + + @Override + public int hashCode() { + return mEventType * 31 + (mMetadata != null ? mMetadata.hashCode() : 0); + } + + @Override + public String toString() { + return "AmbientBacklightEvent{" + + "mEventType=" + mEventType + + ", mMetadata=" + mMetadata + + '}'; + } +} diff --git a/media/java/android/media/quality/AmbientBacklightMetadata.aidl b/media/java/android/media/quality/AmbientBacklightMetadata.aidl new file mode 100644 index 000000000000..b95a474fbf90 --- /dev/null +++ b/media/java/android/media/quality/AmbientBacklightMetadata.aidl @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.media.quality; + +parcelable AmbientBacklightMetadata;
\ No newline at end of file diff --git a/media/java/android/media/quality/AmbientBacklightMetadata.java b/media/java/android/media/quality/AmbientBacklightMetadata.java new file mode 100644 index 000000000000..fc779348de11 --- /dev/null +++ b/media/java/android/media/quality/AmbientBacklightMetadata.java @@ -0,0 +1,127 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.media.quality; + +import android.os.Parcel; +import android.os.Parcelable; + +import androidx.annotation.NonNull; + +import java.util.Arrays; + +/** + * @hide + */ +public class AmbientBacklightMetadata implements Parcelable { + @NonNull + private final String mPackageName; + private final int mCompressAlgorithm; + private final int mSource; + private final int mColorFormat; + private final int mHorizontalZonesNumber; + private final int mVerticalZonesNumber; + @NonNull + private final int[] mZonesColors; + + public AmbientBacklightMetadata(@NonNull String packageName, int compressAlgorithm, + int source, int colorFormat, int horizontalZonesNumber, int verticalZonesNumber, + @NonNull int[] zonesColors) { + mPackageName = packageName; + mCompressAlgorithm = compressAlgorithm; + mSource = source; + mColorFormat = colorFormat; + mHorizontalZonesNumber = horizontalZonesNumber; + mVerticalZonesNumber = verticalZonesNumber; + mZonesColors = zonesColors; + } + + private AmbientBacklightMetadata(Parcel in) { + mPackageName = in.readString(); + mCompressAlgorithm = in.readInt(); + mSource = in.readInt(); + mColorFormat = in.readInt(); + mHorizontalZonesNumber = in.readInt(); + mVerticalZonesNumber = in.readInt(); + mZonesColors = in.createIntArray(); + } + + @NonNull + public String getPackageName() { + return mPackageName; + } + + public int getCompressAlgorithm() { + return mCompressAlgorithm; + } + + public int getSource() { + return mSource; + } + + public int getColorFormat() { + return mColorFormat; + } + + public int getHorizontalZonesNumber() { + return mHorizontalZonesNumber; + } + + public int getVerticalZonesNumber() { + return mVerticalZonesNumber; + } + + @NonNull + public int[] getZonesColors() { + return mZonesColors; + } + + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { + dest.writeString(mPackageName); + dest.writeInt(mCompressAlgorithm); + dest.writeInt(mSource); + dest.writeInt(mColorFormat); + dest.writeInt(mHorizontalZonesNumber); + dest.writeInt(mVerticalZonesNumber); + dest.writeIntArray(mZonesColors); + } + + @Override + public int describeContents() { + return 0; + } + + public static final @NonNull Parcelable.Creator<AmbientBacklightMetadata> CREATOR = + new Parcelable.Creator<AmbientBacklightMetadata>() { + public AmbientBacklightMetadata createFromParcel(Parcel in) { + return new AmbientBacklightMetadata(in); + } + + public AmbientBacklightMetadata[] newArray(int size) { + return new AmbientBacklightMetadata[size]; + } + }; + + @Override + public String toString() { + return "AmbientBacklightMetadata{packageName=" + mPackageName + + ", compressAlgorithm=" + mCompressAlgorithm + ", source=" + mSource + + ", colorFormat=" + mColorFormat + ", horizontalZonesNumber=" + + mHorizontalZonesNumber + ", verticalZonesNumber=" + mVerticalZonesNumber + + ", zonesColors=" + Arrays.toString(mZonesColors) + "}"; + } +} diff --git a/media/java/android/media/quality/AmbientBacklightSettings.aidl b/media/java/android/media/quality/AmbientBacklightSettings.aidl new file mode 100644 index 000000000000..e2cdd03194cd --- /dev/null +++ b/media/java/android/media/quality/AmbientBacklightSettings.aidl @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.media.quality; + +parcelable AmbientBacklightSettings; diff --git a/media/java/android/media/quality/AmbientBacklightSettings.java b/media/java/android/media/quality/AmbientBacklightSettings.java new file mode 100644 index 000000000000..391eb225bcab --- /dev/null +++ b/media/java/android/media/quality/AmbientBacklightSettings.java @@ -0,0 +1,203 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.media.quality; + +import android.annotation.IntDef; +import android.os.Parcel; +import android.os.Parcelable; + +import androidx.annotation.NonNull; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * @hide + */ +public class AmbientBacklightSettings implements Parcelable { + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef({SOURCE_NONE, SOURCE_AUDIO, SOURCE_VIDEO, SOURCE_AUDIO_VIDEO}) + public @interface Source {} + + /** + * The detection is disabled. + */ + public static final int SOURCE_NONE = 0; + + /** + * The detection is enabled for audio. + */ + public static final int SOURCE_AUDIO = 1; + + /** + * The detection is enabled for video. + */ + public static final int SOURCE_VIDEO = 2; + + /** + * The detection is enabled for audio and video. + */ + public static final int SOURCE_AUDIO_VIDEO = 3; + + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef({COLOR_FORMAT_RGB888}) + public @interface ColorFormat {} + + /** + * The color format is RGB888. + */ + public static final int COLOR_FORMAT_RGB888 = 1; + + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef({ALGORITHM_NONE, ALGORITHM_RLE}) + public @interface CompressAlgorithm {} + + /** + * The compress algorithm is disabled. + */ + public static final int ALGORITHM_NONE = 0; + + /** + * The compress algorithm is RLE. + */ + public static final int ALGORITHM_RLE = 1; + + /** + * The source of the ambient backlight. + */ + private final int mSource; + + /** + * The maximum framerate for the ambient backlight. + */ + private final int mMaxFps; + + /** + * The color format for the ambient backlight. + */ + private final int mColorFormat; + + /** + * The number of zones in horizontal direction. + */ + private final int mHorizontalZonesNumber; + + /** + * The number of zones in vertical direction. + */ + private final int mVerticalZonesNumber; + + /** + * The flag to indicate whether the letterbox is omitted. + */ + private final boolean mIsLetterboxOmitted; + + /** + * The color threshold for the ambient backlight. + */ + private final int mThreshold; + + public AmbientBacklightSettings(int source, int maxFps, int colorFormat, + int horizontalZonesNumber, int verticalZonesNumber, boolean isLetterboxOmitted, + int threshold) { + mSource = source; + mMaxFps = maxFps; + mColorFormat = colorFormat; + mHorizontalZonesNumber = horizontalZonesNumber; + mVerticalZonesNumber = verticalZonesNumber; + mIsLetterboxOmitted = isLetterboxOmitted; + mThreshold = threshold; + } + + private AmbientBacklightSettings(Parcel in) { + mSource = in.readInt(); + mMaxFps = in.readInt(); + mColorFormat = in.readInt(); + mHorizontalZonesNumber = in.readInt(); + mVerticalZonesNumber = in.readInt(); + mIsLetterboxOmitted = in.readBoolean(); + mThreshold = in.readInt(); + } + + @Source + public int getSource() { + return mSource; + } + + public int getMaxFps() { + return mMaxFps; + } + + @ColorFormat + public int getColorFormat() { + return mColorFormat; + } + + public int getHorizontalZonesNumber() { + return mHorizontalZonesNumber; + } + + public int getVerticalZonesNumber() { + return mVerticalZonesNumber; + } + + public boolean isLetterboxOmitted() { + return mIsLetterboxOmitted; + } + + public int getThreshold() { + return mThreshold; + } + + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { + dest.writeInt(mSource); + dest.writeInt(mMaxFps); + dest.writeInt(mColorFormat); + dest.writeInt(mHorizontalZonesNumber); + dest.writeInt(mVerticalZonesNumber); + dest.writeBoolean(mIsLetterboxOmitted); + dest.writeInt(mThreshold); + } + + @Override + public int describeContents() { + return 0; + } + + public static final @NonNull Parcelable.Creator<AmbientBacklightSettings> CREATOR = + new Parcelable.Creator<AmbientBacklightSettings>() { + public AmbientBacklightSettings createFromParcel(Parcel in) { + return new AmbientBacklightSettings(in); + } + + public AmbientBacklightSettings[] newArray(int size) { + return new AmbientBacklightSettings[size]; + } + }; + + @Override + public String toString() { + return "AmbientBacklightSettings{Source=" + mSource + ", MaxFps=" + mMaxFps + + ", ColorFormat=" + mColorFormat + ", HorizontalZonesNumber=" + + mHorizontalZonesNumber + ", VerticalZonesNumber=" + mVerticalZonesNumber + + ", IsLetterboxOmitted=" + mIsLetterboxOmitted + ", Threshold=" + mThreshold + "}"; + } +} diff --git a/media/java/android/media/quality/IAmbientBacklightCallback.aidl b/media/java/android/media/quality/IAmbientBacklightCallback.aidl new file mode 100644 index 000000000000..159f5b7b5e71 --- /dev/null +++ b/media/java/android/media/quality/IAmbientBacklightCallback.aidl @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.media.quality; + +import android.media.quality.AmbientBacklightEvent; + +/** @hide */ +oneway interface IAmbientBacklightCallback { + void onAmbientBacklightEvent(in AmbientBacklightEvent event); +} diff --git a/media/java/android/media/quality/IMediaQualityManager.aidl b/media/java/android/media/quality/IMediaQualityManager.aidl index 83f8e795c138..e6c79dd9681f 100644 --- a/media/java/android/media/quality/IMediaQualityManager.aidl +++ b/media/java/android/media/quality/IMediaQualityManager.aidl @@ -16,6 +16,8 @@ package android.media.quality; +import android.media.quality.AmbientBacklightSettings; +import android.media.quality.IAmbientBacklightCallback; import android.media.quality.IPictureProfileCallback; import android.media.quality.ISoundProfileCallback; import android.media.quality.ParamCapability; @@ -45,6 +47,7 @@ interface IMediaQualityManager { void registerPictureProfileCallback(in IPictureProfileCallback cb); void registerSoundProfileCallback(in ISoundProfileCallback cb); + void registerAmbientBacklightCallback(in IAmbientBacklightCallback cb); List<ParamCapability> getParamCapabilities(in List<String> names); @@ -55,4 +58,7 @@ interface IMediaQualityManager { boolean isSuperResolutionEnabled(); void setAutoSoundQualityEnabled(in boolean enabled); boolean isAutoSoundQualityEnabled(); -}
\ No newline at end of file + + void setAmbientBacklightSettings(in AmbientBacklightSettings settings); + void setAmbientBacklightEnabled(in boolean enabled); +} diff --git a/media/java/android/media/quality/MediaQualityManager.java b/media/java/android/media/quality/MediaQualityManager.java index 23f3b59faaed..1237d673162c 100644 --- a/media/java/android/media/quality/MediaQualityManager.java +++ b/media/java/android/media/quality/MediaQualityManager.java @@ -50,6 +50,9 @@ public final class MediaQualityManager { private final List<PictureProfileCallbackRecord> mPpCallbackRecords = new ArrayList<>(); // @GuardedBy("mLock") private final List<SoundProfileCallbackRecord> mSpCallbackRecords = new ArrayList<>(); + // @GuardedBy("mLock") + private final List<AmbientBacklightCallbackRecord> mAbCallbackRecords = new ArrayList<>(); + /** * @hide @@ -115,10 +118,22 @@ public final class MediaQualityManager { } } }; + IAmbientBacklightCallback abCallback = new IAmbientBacklightCallback.Stub() { + @Override + public void onAmbientBacklightEvent(AmbientBacklightEvent event) { + synchronized (mLock) { + for (AmbientBacklightCallbackRecord record : mAbCallbackRecords) { + record.postAmbientBacklightEvent(event); + } + } + } + }; + try { if (mService != null) { mService.registerPictureProfileCallback(ppCallback); mService.registerSoundProfileCallback(spCallback); + mService.registerAmbientBacklightCallback(abCallback); } } catch (RemoteException e) { throw e.rethrowFromSystemServer(); @@ -455,6 +470,68 @@ public final class MediaQualityManager { } } + /** + * Registers a {@link AmbientBacklightCallback}. + * @hide + */ + public void registerAmbientBacklightCallback( + @NonNull @CallbackExecutor Executor executor, + @NonNull AmbientBacklightCallback callback) { + Preconditions.checkNotNull(callback); + Preconditions.checkNotNull(executor); + synchronized (mLock) { + mAbCallbackRecords.add(new AmbientBacklightCallbackRecord(callback, executor)); + } + } + + /** + * Unregisters the existing {@link AmbientBacklightCallback}. + * @hide + */ + public void unregisterAmbientBacklightCallback( + @NonNull final AmbientBacklightCallback callback) { + Preconditions.checkNotNull(callback); + synchronized (mLock) { + for (Iterator<AmbientBacklightCallbackRecord> it = mAbCallbackRecords.iterator(); + it.hasNext(); ) { + AmbientBacklightCallbackRecord record = it.next(); + if (record.getCallback() == callback) { + it.remove(); + break; + } + } + } + } + + /** + * Set the ambient backlight settings. + * + * @param settings The settings to use for the backlight detector. + */ + public void setAmbientBacklightSettings( + @NonNull AmbientBacklightSettings settings) { + Preconditions.checkNotNull(settings); + try { + mService.setAmbientBacklightSettings(settings); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * Enables or disables the ambient backlight detection. + * + * @param enabled {@code true} to enable, {@code false} to disable. + */ + public void setAmbientBacklightEnabled(boolean enabled) { + try { + mService.setAmbientBacklightEnabled(enabled); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + private static final class PictureProfileCallbackRecord { private final PictureProfileCallback mCallback; private final Executor mExecutor; @@ -539,6 +616,29 @@ public final class MediaQualityManager { } } + private static final class AmbientBacklightCallbackRecord { + private final AmbientBacklightCallback mCallback; + private final Executor mExecutor; + + AmbientBacklightCallbackRecord(AmbientBacklightCallback callback, Executor executor) { + mCallback = callback; + mExecutor = executor; + } + + public AmbientBacklightCallback getCallback() { + return mCallback; + } + + public void postAmbientBacklightEvent(AmbientBacklightEvent event) { + mExecutor.execute(new Runnable() { + @Override + public void run() { + mCallback.onAmbientBacklightEvent(event); + } + }); + } + } + /** * Callback used to monitor status of picture profiles. * @hide @@ -592,4 +692,16 @@ public final class MediaQualityManager { public void onError(int errorCode) { } } + + /** + * Callback used to monitor status of ambient backlight. + * @hide + */ + public abstract static class AmbientBacklightCallback { + /** + * Called when new ambient backlight event is emitted. + */ + public void onAmbientBacklightEvent(AmbientBacklightEvent event) { + } + } } diff --git a/services/core/java/com/android/server/media/quality/MediaQualityService.java b/services/core/java/com/android/server/media/quality/MediaQualityService.java index e15d41497968..a45ea1d8369d 100644 --- a/services/core/java/com/android/server/media/quality/MediaQualityService.java +++ b/services/core/java/com/android/server/media/quality/MediaQualityService.java @@ -17,6 +17,8 @@ package com.android.server.media.quality; import android.content.Context; +import android.media.quality.AmbientBacklightSettings; +import android.media.quality.IAmbientBacklightCallback; import android.media.quality.IMediaQualityManager; import android.media.quality.IPictureProfileCallback; import android.media.quality.ISoundProfileCallback; @@ -119,6 +121,17 @@ public class MediaQualityService extends SystemService { public void registerSoundProfileCallback(final ISoundProfileCallback callback) { } + @Override + public void registerAmbientBacklightCallback(IAmbientBacklightCallback callback) { + } + + @Override + public void setAmbientBacklightSettings(AmbientBacklightSettings settings) { + } + + @Override + public void setAmbientBacklightEnabled(boolean enabled) { + } @Override public List<ParamCapability> getParamCapabilities(List<String> names) { |