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

Commit 161235ad authored by Shubang Lu's avatar Shubang Lu Committed by Android (Google) Code Review
Browse files

Merge "[MQ] Refactor profile mapping for stream status" into main

parents 1d74ee41 a0a0388c
Loading
Loading
Loading
Loading
+14 −28
Original line number Original line Diff line number Diff line
@@ -143,9 +143,7 @@ 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) {
@@ -543,7 +541,7 @@ public class MediaQualityService extends SystemService {
            );
            );
            if (defaultPictureProfileId != -1) {
            if (defaultPictureProfileId != -1) {
                PictureProfile currentDefaultPictureProfile =
                PictureProfile currentDefaultPictureProfile =
                        mHandleToPictureProfile.get(defaultPictureProfileId);
                        mStreamStatusMapping.getCurrent(defaultPictureProfileId);
                if (currentDefaultPictureProfile != null) {
                if (currentDefaultPictureProfile != null) {
                    return currentDefaultPictureProfile;
                    return currentDefaultPictureProfile;
                } else {
                } else {
@@ -725,7 +723,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 = mHandleToPictureProfile.get(handle);
                    PictureProfile current = mStreamStatusMapping.getCurrent(handle);
                    if (current != null) {
                    if (current != null) {
                        long currentHandle = current.getHandle().getId();
                        long currentHandle = current.getHandle().getId();
                        mHalNotifier.notifyHalOnPictureProfileChange(
                        mHalNotifier.notifyHalOnPictureProfileChange(
@@ -1939,12 +1937,7 @@ 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 = dbId;
                    Long idForHal = mStreamStatusMapping.getOriginal(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) {
@@ -2056,8 +2049,7 @@ public class MediaQualityService extends SystemService {
                    if (param.getTag() == PictureParameter.activeProfile
                    if (param.getTag() == PictureParameter.activeProfile
                            && !param.getActiveProfile()) {
                            && !param.getActiveProfile()) {
                        synchronized (mPictureProfileLock) {
                        synchronized (mPictureProfileLock) {
                            mHandleToPictureProfile.remove(dbId);
                            mStreamStatusMapping.removeMapping(dbId);
                            mCurrentPictureHandleToOriginal.removeValue(dbId);
                        }
                        }
                        break;
                        break;
                    }
                    }
@@ -2122,7 +2114,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 = mHandleToPictureProfile.get(profileHandle);
                    PictureProfile previous = mStreamStatusMapping.getCurrent(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
@@ -2151,10 +2143,12 @@ public class MediaQualityService extends SystemService {
                        Slog.d(TAG, "The new status is " + newStatus);
                        Slog.d(TAG, "The new status is " + newStatus);
                        String selection = BaseParameters.PARAMETER_TYPE + " = ? AND "
                        String selection = BaseParameters.PARAMETER_TYPE + " = ? AND "
                                + BaseParameters.PARAMETER_PACKAGE + " = ? AND "
                                + BaseParameters.PARAMETER_PACKAGE + " = ? AND "
                                + BaseParameters.PARAMETER_INPUT_ID + " = ? AND "
                                + BaseParameters.PARAMETER_NAME + " = ?";
                                + BaseParameters.PARAMETER_NAME + " = ?";
                        String[] selectionArguments = {
                        String[] selectionArguments = {
                                Integer.toString(previous.getProfileType()),
                                Integer.toString(previous.getProfileType()),
                                previous.getPackageName(),
                                previous.getPackageName(),
                                previous.getInputId(),
                                profileName + "/" + newStatus
                                profileName + "/" + newStatus
                        };
                        };
                        List<PictureProfile> list =
                        List<PictureProfile> list =
@@ -2175,10 +2169,7 @@ 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);
                            mHandleToPictureProfile.put(profileHandle, currentSdr);
                            mStreamStatusMapping.setCurrent(profileHandle, currentSdr);
                            mCurrentPictureHandleToOriginal.removeValue(profileHandle);
                            mCurrentPictureHandleToOriginal.put(
                                    currentSdr.getHandle().getId(), profileHandle);
                            mHalNotifier.notifyHalOnPictureProfileChange(profileHandle,
                            mHalNotifier.notifyHalOnPictureProfileChange(profileHandle,
                                    currentSdrParameter);
                                    currentSdrParameter);


@@ -2191,10 +2182,7 @@ public class MediaQualityService extends SystemService {
                        // Add previous stream status information so that application can use this
                        // Add previous stream status information so that application can use this
                        // 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);
                        mHandleToPictureProfile.put(profileHandle, current);
                        mStreamStatusMapping.setCurrent(profileHandle, current);
                        mCurrentPictureHandleToOriginal.removeValue(profileHandle);
                        mCurrentPictureHandleToOriginal.put(
                                current.getHandle().getId(), profileHandle);
                        mMqManagerNotifier.notifyOnPictureProfileUpdated(
                        mMqManagerNotifier.notifyOnPictureProfileUpdated(
                                current.getProfileId(), current, Process.INVALID_UID,
                                current.getProfileId(), current, Process.INVALID_UID,
                                Process.INVALID_PID);
                                Process.INVALID_PID);
@@ -2213,7 +2201,6 @@ 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();
@@ -2222,10 +2209,7 @@ public class MediaQualityService extends SystemService {
                        // Add previous stream status information so that application can use this
                        // Add previous stream status information so that application can use this
                        // 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);
                        mHandleToPictureProfile.put(profileHandle, current);
                        mStreamStatusMapping.setCurrent(profileHandle, current);
                        mCurrentPictureHandleToOriginal.removeValue(profileHandle);
                        mCurrentPictureHandleToOriginal.put(
                                current.getHandle().getId(), profileHandle);
                        mMqManagerNotifier.notifyOnPictureProfileUpdated(
                        mMqManagerNotifier.notifyOnPictureProfileUpdated(
                                current.getProfileId(), current, Process.INVALID_UID,
                                current.getProfileId(), current, Process.INVALID_UID,
                                Process.INVALID_PID);
                                Process.INVALID_PID);
@@ -2593,12 +2577,14 @@ public class MediaQualityService extends SystemService {


    private PictureProfile getSdrPictureProfile(String profileName, PictureProfile previous) {
    private PictureProfile getSdrPictureProfile(String profileName, PictureProfile previous) {
        String selection = BaseParameters.PARAMETER_TYPE + " = ? AND "
        String selection = BaseParameters.PARAMETER_TYPE + " = ? AND "
                + BaseParameters.PARAMETER_PACKAGE + " = ? AND ("
                + BaseParameters.PARAMETER_PACKAGE + " = ? AND "
                + BaseParameters.PARAMETER_INPUT_ID + " = ? AND ("
                + BaseParameters.PARAMETER_NAME + " = ? OR "
                + BaseParameters.PARAMETER_NAME + " = ? OR "
                + BaseParameters.PARAMETER_NAME + " = ?)";
                + BaseParameters.PARAMETER_NAME + " = ?)";
        String[] selectionArguments = {
        String[] selectionArguments = {
                Integer.toString(previous.getProfileType()),
                Integer.toString(previous.getProfileType()),
                previous.getPackageName(),
                previous.getPackageName(),
                previous.getInputId(),
                profileName,
                profileName,
                profileName + "/" + PictureProfile.STATUS_SDR
                profileName + "/" + PictureProfile.STATUS_SDR
        };
        };
+149 −0
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);
    }
}