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

Commit f0e54789 authored by Haofan Wang's avatar Haofan Wang Committed by Android (Google) Code Review
Browse files

Merge changes Ifb3e4974,I20628a18,If76023c7 into main

* changes:
  Notify application about previous stream status
  Fix getCurrentPictureProfileForTvInput returns profile of another input id
  Revert regression CLs
parents 01be0040 568530db
Loading
Loading
Loading
Loading
+15 −0
Original line number Original line Diff line number Diff line
@@ -396,6 +396,21 @@ public final class PictureProfile implements Parcelable {
        mParams.putString(key, value);
        mParams.putString(key, value);
    }
    }


    /**
     * Copies all info from the given profile
     * @hide
     */
    public static PictureProfile copyFrom(PictureProfile orig) {
        return new PictureProfile(
                orig.mId,
                orig.mType,
                orig.mName,
                orig.mInputId,
                orig.mPackageName,
                new PersistableBundle(orig.mParams),
                orig.mHandle);
    }

    /**
    /**
     * Gets profile handle
     * Gets profile handle
     * @hide
     * @hide
+52 −13
Original line number Original line Diff line number Diff line
@@ -143,7 +143,9 @@ public class MediaQualityService extends SystemService {
    private final Object mUserStateLock = new Object();
    private final Object mUserStateLock = new Object();
    // A global lock for ambient backlight objects.
    // A global lock for ambient backlight objects.
    private final Object mAmbientBacklightLock = new Object();
    private final Object mAmbientBacklightLock = new Object();
    private final StreamStatusMapping mStreamStatusMapping = new StreamStatusMapping();

    private final Map<Long, PictureProfile> mHandleToPictureProfile = new HashMap<>();
    private final BiMap<Long, Long> mCurrentPictureHandleToOriginal = new BiMap<>();
    private final Set<Long> mPictureProfileForHal = new HashSet<>();
    private final Set<Long> mPictureProfileForHal = new HashSet<>();


    public MediaQualityService(Context context) {
    public MediaQualityService(Context context) {
@@ -541,7 +543,7 @@ public class MediaQualityService extends SystemService {
            );
            );
            if (defaultPictureProfileId != -1) {
            if (defaultPictureProfileId != -1) {
                PictureProfile currentDefaultPictureProfile =
                PictureProfile currentDefaultPictureProfile =
                        mStreamStatusMapping.getCurrent(defaultPictureProfileId);
                        mHandleToPictureProfile.get(defaultPictureProfileId);
                if (currentDefaultPictureProfile != null) {
                if (currentDefaultPictureProfile != null) {
                    return currentDefaultPictureProfile;
                    return currentDefaultPictureProfile;
                } else {
                } else {
@@ -723,7 +725,7 @@ public class MediaQualityService extends SystemService {
                    PictureProfile p = MediaQualityUtils.convertCursorToPictureProfileWithTempId(
                    PictureProfile p = MediaQualityUtils.convertCursorToPictureProfileWithTempId(
                            cursor, mPictureProfileTempIdMap);
                            cursor, mPictureProfileTempIdMap);
                    handle = p.getHandle().getId();
                    handle = p.getHandle().getId();
                    PictureProfile current = mStreamStatusMapping.getCurrent(handle);
                    PictureProfile current = mHandleToPictureProfile.get(handle);
                    if (current != null) {
                    if (current != null) {
                        long currentHandle = current.getHandle().getId();
                        long currentHandle = current.getHandle().getId();
                        mHalNotifier.notifyHalOnPictureProfileChange(
                        mHalNotifier.notifyHalOnPictureProfileChange(
@@ -1937,7 +1939,12 @@ public class MediaQualityService extends SystemService {
            // TODO: only notify HAL when the profile is active / being used
            // TODO: only notify HAL when the profile is active / being used
            if (mPpChangedListener != null) {
            if (mPpChangedListener != null) {
                try {
                try {
                    Long idForHal = mStreamStatusMapping.getOriginal(dbId);
                    Long idForHal = dbId;
                    Long originalHandle = mCurrentPictureHandleToOriginal.getValue(dbId);
                    if (originalHandle != null) {
                        // the original id is used in HAL because of status change
                        idForHal = originalHandle;
                    }
                    mPpChangedListener.onPictureProfileChanged(convertToHalPictureProfile(idForHal,
                    mPpChangedListener.onPictureProfileChanged(convertToHalPictureProfile(idForHal,
                            params));
                            params));
                } catch (RemoteException e) {
                } catch (RemoteException e) {
@@ -2049,7 +2056,8 @@ public class MediaQualityService extends SystemService {
                    if (param.getTag() == PictureParameter.activeProfile
                    if (param.getTag() == PictureParameter.activeProfile
                            && !param.getActiveProfile()) {
                            && !param.getActiveProfile()) {
                        synchronized (mPictureProfileLock) {
                        synchronized (mPictureProfileLock) {
                            mStreamStatusMapping.removeMapping(dbId);
                            mHandleToPictureProfile.remove(dbId);
                            mCurrentPictureHandleToOriginal.removeValue(dbId);
                        }
                        }
                        break;
                        break;
                    }
                    }
@@ -2114,7 +2122,7 @@ public class MediaQualityService extends SystemService {
            mHandler.post(() -> {
            mHandler.post(() -> {
                synchronized (mPictureProfileLock) {
                synchronized (mPictureProfileLock) {
                    // get from map if exists
                    // get from map if exists
                    PictureProfile previous = mStreamStatusMapping.getCurrent(profileHandle);
                    PictureProfile previous = mHandleToPictureProfile.get(profileHandle);
                    if (previous == null) {
                    if (previous == null) {
                        Slog.d(TAG, "Previous profile not in the map");
                        Slog.d(TAG, "Previous profile not in the map");
                        // get from DB if not exists
                        // get from DB if not exists
@@ -2175,7 +2183,25 @@ public class MediaQualityService extends SystemService {
                            PersistableBundle currentSdrParameter = currentSdr.getParameters();
                            PersistableBundle currentSdrParameter = currentSdr.getParameters();
                            currentSdrParameter.putString(
                            currentSdrParameter.putString(
                                    STREAM_STATUS_NOT_CREATED, newStatus);
                                    STREAM_STATUS_NOT_CREATED, newStatus);
                            mStreamStatusMapping.setCurrent(profileHandle, currentSdr);
                            currentSdrParameter.putString(STREAM_STATUS, PictureProfile.STATUS_SDR);
                            // Add previous stream status information so that application can use
                            // this flag to indicate that there is a onStreamStatusChange.
                            currentSdrParameter.putString(PREVIOUS_STREAM_STATUS, profileStatus);
                            currentSdr.addStringParameter(STREAM_STATUS, PictureProfile.STATUS_SDR);
                            // PREVIOUS_STREAM_STATUS is used for one time, so copy the current
                            // profile
                            PictureProfile currentCopy = PictureProfile.copyFrom(currentSdr);
                            currentCopy.addStringParameter(PREVIOUS_STREAM_STATUS, profileStatus);
                            mHandleToPictureProfile.put(profileHandle, currentSdr);
                            mCurrentPictureHandleToOriginal.removeValue(profileHandle);
                            mCurrentPictureHandleToOriginal.put(
                                    currentSdr.getHandle().getId(), profileHandle);
                            mMqManagerNotifier.notifyOnPictureProfileUpdated(
                                    currentCopy.getProfileId(), currentCopy, Process.INVALID_UID,
                                    Process.INVALID_PID);

                            mPictureProfileForHal.add(profileHandle);
                            mPictureProfileForHal.add(currentSdr.getHandle().getId());
                            mHalNotifier.notifyHalOnPictureProfileChange(profileHandle,
                            mHalNotifier.notifyHalOnPictureProfileChange(profileHandle,
                                    currentSdrParameter);
                                    currentSdrParameter);


@@ -2189,11 +2215,16 @@ public class MediaQualityService extends SystemService {
                        // flag to indicate that there is a onStreamStatusChange.
                        // flag to indicate that there is a onStreamStatusChange.
                        currentProfileParameters.putString(PREVIOUS_STREAM_STATUS, profileStatus);
                        currentProfileParameters.putString(PREVIOUS_STREAM_STATUS, profileStatus);
                        current.addStringParameter(STREAM_STATUS, newStatus);
                        current.addStringParameter(STREAM_STATUS, newStatus);
                        current.addStringParameter(PREVIOUS_STREAM_STATUS, profileStatus);
                        // PREVIOUS_STREAM_STATUS is used for one time, so copy the current profile
                        mStreamStatusMapping.setCurrent(profileHandle, current);
                        PictureProfile currentCopy = PictureProfile.copyFrom(current);
                        currentCopy.addStringParameter(PREVIOUS_STREAM_STATUS, profileStatus);
                        mHandleToPictureProfile.put(profileHandle, current);
                        mCurrentPictureHandleToOriginal.removeValue(profileHandle);
                        mCurrentPictureHandleToOriginal.put(
                                current.getHandle().getId(), profileHandle);
                        // TODO: use package name to notify
                        // TODO: use package name to notify
                        mMqManagerNotifier.notifyOnPictureProfileUpdated(
                        mMqManagerNotifier.notifyOnPictureProfileUpdated(
                                current.getProfileId(), current, Process.INVALID_UID,
                                currentCopy.getProfileId(), currentCopy, Process.INVALID_UID,
                                Process.INVALID_PID);
                                Process.INVALID_PID);


                        mPictureProfileForHal.add(profileHandle);
                        mPictureProfileForHal.add(profileHandle);
@@ -2210,6 +2241,7 @@ public class MediaQualityService extends SystemService {
                        // to SDR
                        // to SDR
                        PictureProfile current = getSdrPictureProfile(profileName, previous);
                        PictureProfile current = getSdrPictureProfile(profileName, previous);
                        if (current == null) {
                        if (current == null) {
                            Slog.d(TAG, "The current SDR profile is null");
                            return;
                            return;
                        }
                        }
                        PersistableBundle currentProfileParameters = current.getParameters();
                        PersistableBundle currentProfileParameters = current.getParameters();
@@ -2219,11 +2251,16 @@ public class MediaQualityService extends SystemService {
                        // flag to indicate that there is a onStreamStatusChange.
                        // flag to indicate that there is a onStreamStatusChange.
                        currentProfileParameters.putString(PREVIOUS_STREAM_STATUS, profileStatus);
                        currentProfileParameters.putString(PREVIOUS_STREAM_STATUS, profileStatus);
                        current.addStringParameter(STREAM_STATUS, PictureProfile.STATUS_SDR);
                        current.addStringParameter(STREAM_STATUS, PictureProfile.STATUS_SDR);
                        current.addStringParameter(PREVIOUS_STREAM_STATUS, profileStatus);
                        // PREVIOUS_STREAM_STATUS is used for one time, so copy the current profile
                        mStreamStatusMapping.setCurrent(profileHandle, current);
                        PictureProfile currentCopy = PictureProfile.copyFrom(current);
                        currentCopy.addStringParameter(PREVIOUS_STREAM_STATUS, profileStatus);
                        mHandleToPictureProfile.put(profileHandle, current);
                        mCurrentPictureHandleToOriginal.removeValue(profileHandle);
                        mCurrentPictureHandleToOriginal.put(
                                current.getHandle().getId(), profileHandle);
                        // TODO: use package name to notify
                        // TODO: use package name to notify
                        mMqManagerNotifier.notifyOnPictureProfileUpdated(
                        mMqManagerNotifier.notifyOnPictureProfileUpdated(
                                current.getProfileId(), current, Process.INVALID_UID,
                                currentCopy.getProfileId(), currentCopy, Process.INVALID_UID,
                                Process.INVALID_PID);
                                Process.INVALID_PID);


                        mPictureProfileForHal.add(current.getHandle().getId());
                        mPictureProfileForHal.add(current.getHandle().getId());
@@ -2588,6 +2625,8 @@ public class MediaQualityService extends SystemService {
    }
    }


    private PictureProfile getSdrPictureProfile(String profileName, PictureProfile previous) {
    private PictureProfile getSdrPictureProfile(String profileName, PictureProfile previous) {
        Log.d(TAG, "getSdrPictureProfile: profileName = " + profileName
                + " previous profile name = " + previous.getName());
        String selection = BaseParameters.PARAMETER_TYPE + " = ? AND "
        String selection = BaseParameters.PARAMETER_TYPE + " = ? AND "
                + BaseParameters.PARAMETER_PACKAGE + " = ? AND ("
                + BaseParameters.PARAMETER_PACKAGE + " = ? AND ("
                + BaseParameters.PARAMETER_NAME + " = ? OR "
                + BaseParameters.PARAMETER_NAME + " = ? OR "
+0 −149
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2025 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.server.media.quality;

import android.media.quality.PictureProfile;
import android.util.Log;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

public class StreamStatusMapping {
    private static final String TAG = "StreamStatusMapping";

    // original profile handle -> mapped handles
    private final Map<Long, Set<Long>> mOriginalToHandles = new HashMap<>();

    // original profile handle -> currently used profile object
    private final Map<Long, PictureProfile> mOriginalToCurrent = new HashMap<>();

    // mapped handles -> original profile handle
    private final Map<Long, Long> mHandleToOriginal = new HashMap<>();

    public StreamStatusMapping() {
    }


    /**
     * Maps a number to an original number.
     *
     * If the number is already mapped to a different original, the mapping is moved.
     *
     * @return true if the operation was successful.
     */
    public boolean put(long original, long toAdd) {
        if (original == toAdd) {
            Log.e(TAG, "same key and value:" + original);
            return false;
        }
        if (mOriginalToHandles.containsKey(toAdd)) {
            Log.e(TAG, "the value to add is in mOriginalToHandles:" + toAdd);
            return false;
        }
        if (mHandleToOriginal.containsKey(original)) {
            Log.e(TAG, "the original handle is in mHandleToOriginal:" + original);
            return false;
        }
        // Check if the number to add is already mapped to a different original.
        Long oldOriginal = mHandleToOriginal.get(toAdd);
        if (oldOriginal != null) {
            // If it's already mapped to the *same* original, do nothing.
            if (oldOriginal.equals(original)) {
                return true;
            }
            // If it's mapped to a *different* original, we must remove the old mapping.
            Set<Long> mappedSet = mOriginalToHandles.get(oldOriginal);
            if (mappedSet != null) {
                mappedSet.remove(toAdd);
                if (mappedSet.isEmpty()) {
                    mOriginalToHandles.remove(oldOriginal);
                }
            }
        }
        // Add the new mapping
        Set<Long> mappedSet = mOriginalToHandles.get(original);
        if (mappedSet == null) {
            mappedSet = new HashSet<>();
        }
        mappedSet.add(toAdd);
        mOriginalToHandles.put(original, mappedSet);
        mHandleToOriginal.put(toAdd, original);
        return true;
    }

    /**
     * Checks if the given number is mapped with any original number.
     */
    public long getOriginal(long handle) {
        Long original = mHandleToOriginal.get(handle);
        if (original != null) {
            return original;
        }
        // if no existing mapping, use the handle itself
        return handle;
    }

    /**
     * Sets current profile
     */
    public boolean setCurrent(long original, PictureProfile pp) {
        if (pp == null || pp.getHandle() == null) {
            return false;
        }
        long handle = pp.getHandle().getId();
        if (!put(original, handle)) {
            return false;
        }
        mOriginalToCurrent.put(original, pp);
        return true;
    }

    /**
     * Gets current profile
     */
    public PictureProfile getCurrent(long original) {
        return mOriginalToCurrent.get(original);
    }

    /**
     * Removes all the mapping of a handle
     */
    public void removeMapping(long original) {
        Set<Long> mappedSet = mOriginalToHandles.get(original);
        if (mappedSet != null) {
            for (Long handle : mappedSet) {
                mHandleToOriginal.remove(handle);
            }
            mOriginalToHandles.remove(original);
        }
        mOriginalToCurrent.remove(original);
    }


    /**
     * Checks if a given number is currently registered as an original number.
     * An original number is one that has at least one number mapped to it.
     *
     * @param number The number to check.
     * @return true if the number is an original number, false otherwise or if the input is null.
     */
    public boolean isOriginal(long number) {
        return mOriginalToHandles.containsKey(number);
    }
}