Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9075f39f authored by Yixiao Luo's avatar Yixiao Luo
Browse files

[Media Quality] Picture profile application

Support the following use cases:
  - Applying app-selected picture profile using KEY_PICTURE_PROFILE_INSTANCE or
    KEY_PICTURE_PROFILE_ID on MediaCodec.configure()
  - Applying app-selected picture profile using KEY_PICTURE_PROFILE_INSTANCE or
    KEY_PICTURE_PROFILE_ID on MediaCodec.setParameters()
  - Applying app-default picture profile from MediaQualityService on
    MediaCodec.configure()

Bug: 391947448, 394391342
Test: m
Flag: android.media.tv.flags.apply_picture_profiles

Change-Id: Iaaa8a7f3ee6e3a3dbe8d208da7a63bbbb0ab9197
parent f4740b36
Loading
Loading
Loading
Loading
+68 −4
Original line number Diff line number Diff line
@@ -50,6 +50,7 @@ import android.os.Message;
import android.os.PersistableBundle;
import android.os.Trace;
import android.view.Surface;
import android.util.Log;

import java.io.IOException;
import java.lang.annotation.Retention;
@@ -1656,6 +1657,7 @@ import java.util.function.Supplier;
 </table>
 */
final public class MediaCodec {
    private static final String TAG = "MediaCodec";

    /**
     * Per buffer metadata includes an offset and size specifying
@@ -2496,6 +2498,49 @@ final public class MediaCodec {
                    }
                    keys[i] = "audio-hw-sync";
                    values[i] = AudioSystem.getAudioHwSyncForSession(sessionId);
                } else if (applyPictureProfiles() && mediaQualityFw()
                        && entry.getKey().equals(MediaFormat.KEY_PICTURE_PROFILE_INSTANCE)) {
                    PictureProfile pictureProfile = null;
                    try {
                        pictureProfile = (PictureProfile) entry.getValue();
                    } catch (ClassCastException e) {
                        throw new IllegalArgumentException(
                                "Cannot cast the instance parameter to PictureProfile!");
                    } catch (Exception e) {
                        Log.e(TAG, Log.getStackTraceString(e));
                        throw new IllegalArgumentException("Unexpected exception when casting the "
                                + "instance parameter to PictureProfile!");
                    }
                    if (pictureProfile == null) {
                        throw new IllegalArgumentException(
                                "Picture profile instance parameter is null!");
                    }
                    PictureProfileHandle handle = pictureProfile.getHandle();
                    if (handle != PictureProfileHandle.NONE) {
                        keys[i] = PARAMETER_KEY_PICTURE_PROFILE_HANDLE;
                        values[i] = Long.valueOf(handle.getId());
                    }
                } else if (applyPictureProfiles() && mediaQualityFw()
                        && entry.getKey().equals(MediaFormat.KEY_PICTURE_PROFILE_ID)) {
                    String pictureProfileId = null;
                    try {
                        pictureProfileId = (String) entry.getValue();
                    } catch (ClassCastException e) {
                        throw new IllegalArgumentException(
                                "Cannot cast the KEY_PICTURE_PROFILE_ID parameter to String!");
                    } catch (Exception e) {
                        Log.e(TAG, Log.getStackTraceString(e));
                        throw new IllegalArgumentException("Unexpected exception when casting the "
                                + "KEY_PICTURE_PROFILE_ID parameter!");
                    }
                    if (pictureProfileId == null) {
                        throw new IllegalArgumentException(
                                "KEY_PICTURE_PROFILE_ID parameter is null!");
                    }
                    if (!pictureProfileId.isEmpty()) {
                        keys[i] = MediaFormat.KEY_PICTURE_PROFILE_ID;
                        values[i] = pictureProfileId;
                    }
                } else {
                    keys[i] = entry.getKey();
                    values[i] = entry.getValue();
@@ -5424,7 +5469,7 @@ final public class MediaCodec {
                    throw new IllegalArgumentException(
                            "Cannot cast the instance parameter to PictureProfile!");
                } catch (Exception e) {
                    android.util.Log.getStackTraceString(e);
                    Log.e(TAG, Log.getStackTraceString(e));
                    throw new IllegalArgumentException("Unexpected exception when casting the "
                                                       + "instance parameter to PictureProfile!");
                }
@@ -5437,6 +5482,26 @@ final public class MediaCodec {
                    keys[i] = PARAMETER_KEY_PICTURE_PROFILE_HANDLE;
                    values[i] = Long.valueOf(handle.getId());
                }
            } else if (applyPictureProfiles() && mediaQualityFw()
                    && key.equals(MediaFormat.KEY_PICTURE_PROFILE_ID)) {
                String pictureProfileId = null;
                try {
                    pictureProfileId = (String) params.get(key);
                } catch (ClassCastException e) {
                    throw new IllegalArgumentException(
                            "Cannot cast the KEY_PICTURE_PROFILE_ID parameter to String!");
                } catch (Exception e) {
                    Log.e(TAG, Log.getStackTraceString(e));
                    throw new IllegalArgumentException("Unexpected exception when casting the "
                            + "KEY_PICTURE_PROFILE_ID parameter!");
                }
                if (pictureProfileId == null) {
                    throw new IllegalArgumentException("KEY_PICTURE_PROFILE_ID parameter is null!");
                }
                if (!pictureProfileId.isEmpty()) {
                    keys[i] = MediaFormat.KEY_PICTURE_PROFILE_ID;
                    values[i] = pictureProfileId;
                }
            } else {
                keys[i] = key;
                Object value = params.get(key);
@@ -5455,10 +5520,9 @@ final public class MediaCodec {
    }

    private void logAndRun(String message, Runnable r) {
        final String TAG = "MediaCodec";
        android.util.Log.d(TAG, "enter: " + message);
        Log.d(TAG, "enter: " + message);
        r.run();
        android.util.Log.d(TAG, "exit : " + message);
        Log.d(TAG, "exit : " + message);
    }

    /**
+3 −0
Original line number Diff line number Diff line
@@ -46,6 +46,9 @@ interface IMediaQualityManager {
    List<String> getPictureProfileAllowList(int userId);
    void setPictureProfileAllowList(in List<String> packages, int userId);
    List<PictureProfileHandle> getPictureProfileHandle(in String[] id, int userId);
    long getPictureProfileHandleValue(in String id, int userId);
    long getDefaultPictureProfileHandleValue(int userId);
    void notifyPictureProfileHandleSelection(in long handle, int userId);

    void createSoundProfile(in SoundProfile pp, int userId);
    void updateSoundProfile(in String id, in SoundProfile pp, int userId);
+33 −0
Original line number Diff line number Diff line
@@ -105,6 +105,7 @@ public class MediaQualityService extends SystemService {
    private final MediaQualityDbHelper mMediaQualityDbHelper;
    private final BiMap<Long, String> mPictureProfileTempIdMap;
    private final BiMap<Long, String> mSoundProfileTempIdMap;
    private final Map<String, Long> mPackageDefaultPictureProfileHandleMap = new HashMap<>();
    private IMediaQuality mMediaQuality;
    private PictureProfileAdjustmentListenerImpl mPictureProfileAdjListener;
    private SoundProfileAdjustmentListenerImpl mSoundProfileAdjListener;
@@ -184,6 +185,8 @@ public class MediaQualityService extends SystemService {
                mMediaQuality.setPictureProfileAdjustmentListener(mPictureProfileAdjListener);
                mMediaQuality.setSoundProfileAdjustmentListener(mSoundProfileAdjListener);

                // TODO: populate mPackageDefaultPictureProfileHandleMap

            } catch (RemoteException e) {
                Slog.e(TAG, "Failed to set ambient backlight detector callback", e);
            }
@@ -443,6 +446,36 @@ public class MediaQualityService extends SystemService {
            return toReturn;
        }

        @GuardedBy("mPictureProfileLock")
        @Override
        public long getPictureProfileHandleValue(String id, int userId) {
            synchronized (mPictureProfileLock) {
                Long value = mPictureProfileTempIdMap.getKey(id);
                return value != null ? value : -1;
            }
        }

        @GuardedBy("mPictureProfileLock")
        @Override
        public long getDefaultPictureProfileHandleValue(int userId) {
            synchronized (mPictureProfileLock) {
                String packageName = getPackageOfCallingUid();
                Long value = null;
                if (packageName != null) {
                    value = mPackageDefaultPictureProfileHandleMap.get(packageName);
                }
                return value != null ? value : -1;
            }
        }

        @GuardedBy("mPictureProfileLock")
        @Override
        public void notifyPictureProfileHandleSelection(long handle, int userId) {
            PictureProfile profile = mMqDatabaseUtils.getPictureProfile(handle);
            if (profile != null) {
                mHalNotifier.notifyHalOnPictureProfileChange(handle, profile.getParameters());
            }
        }

        @GuardedBy("mSoundProfileLock")
        @Override