Loading services/core/java/com/android/server/media/quality/MediaQualityService.java +14 −28 Original line number Original line Diff line number Diff line Loading @@ -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) { Loading Loading @@ -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 { Loading Loading @@ -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( Loading Loading @@ -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) { Loading Loading @@ -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; } } Loading Loading @@ -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 Loading Loading @@ -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 = Loading @@ -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); Loading @@ -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); Loading @@ -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(); Loading @@ -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); Loading Loading @@ -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 }; }; Loading services/core/java/com/android/server/media/quality/StreamStatusMapping.java 0 → 100644 +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); } } Loading
services/core/java/com/android/server/media/quality/MediaQualityService.java +14 −28 Original line number Original line Diff line number Diff line Loading @@ -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) { Loading Loading @@ -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 { Loading Loading @@ -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( Loading Loading @@ -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) { Loading Loading @@ -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; } } Loading Loading @@ -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 Loading Loading @@ -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 = Loading @@ -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); Loading @@ -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); Loading @@ -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(); Loading @@ -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); Loading Loading @@ -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 }; }; Loading
services/core/java/com/android/server/media/quality/StreamStatusMapping.java 0 → 100644 +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); } }