[MQ] Add more media profile methods
Test: mmm
Flag: android.media.tv.flags.media_quality_fw
Bug: 374849325
Change-Id: If6084856e7f7ee409ef7e38fb7b04c1f0db6dd53
diff --git a/media/java/android/media/quality/IMediaQualityManager.aidl b/media/java/android/media/quality/IMediaQualityManager.aidl
index e413a50..8c17236 100644
--- a/media/java/android/media/quality/IMediaQualityManager.aidl
+++ b/media/java/android/media/quality/IMediaQualityManager.aidl
@@ -16,7 +16,10 @@
package android.media.quality;
+import android.media.quality.IPictureProfileCallback;
+import android.media.quality.ISoundProfileCallback;
import android.media.quality.PictureProfile;
+import android.media.quality.SoundProfile;
/**
* Interface for Media Quality Manager
@@ -24,8 +27,21 @@
*/
interface IMediaQualityManager {
PictureProfile createPictureProfile(in PictureProfile pp);
+ void updatePictureProfile(in long id, in PictureProfile pp);
+ void removePictureProfile(in long id);
PictureProfile getPictureProfileById(in long id);
List<PictureProfile> getPictureProfilesByPackage(in String packageName);
List<PictureProfile> getAvailablePictureProfiles();
- List<PictureProfile> getAvailableAllPictureProfiles();
+ List<PictureProfile> getAllPictureProfiles();
+
+ SoundProfile createSoundProfile(in SoundProfile pp);
+ void updateSoundProfile(in long id, in SoundProfile pp);
+ void removeSoundProfile(in long id);
+ SoundProfile getSoundProfileById(in long id);
+ List<SoundProfile> getSoundProfilesByPackage(in String packageName);
+ List<SoundProfile> getAvailableSoundProfiles();
+ List<SoundProfile> getAllSoundProfiles();
+
+ void registerPictureProfileCallback(in IPictureProfileCallback cb);
+ void registerSoundProfileCallback(in ISoundProfileCallback cb);
}
\ No newline at end of file
diff --git a/media/java/android/media/quality/IPictureProfileCallback.aidl b/media/java/android/media/quality/IPictureProfileCallback.aidl
index 5deb029..05441cd 100644
--- a/media/java/android/media/quality/IPictureProfileCallback.aidl
+++ b/media/java/android/media/quality/IPictureProfileCallback.aidl
@@ -26,4 +26,5 @@
oneway interface IPictureProfileCallback {
void onPictureProfileAdded(in long id, in PictureProfile p);
void onPictureProfileUpdated(in long id, in PictureProfile p);
+ void onPictureProfileRemoved(in long id, in PictureProfile p);
}
diff --git a/media/java/android/media/quality/ISoundProfileCallback.aidl b/media/java/android/media/quality/ISoundProfileCallback.aidl
new file mode 100644
index 0000000..72d1524
--- /dev/null
+++ b/media/java/android/media/quality/ISoundProfileCallback.aidl
@@ -0,0 +1,30 @@
+/*
+ * 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.SoundProfile;
+
+/**
+ * Interface to receive callbacks from IMediaQuality.
+ * @hide
+ */
+oneway interface ISoundProfileCallback {
+ void onSoundProfileAdded(in long id, in SoundProfile p);
+ void onSoundProfileUpdated(in long id, in SoundProfile p);
+ void onSoundProfileRemoved(in long id, in SoundProfile p);
+}
diff --git a/media/java/android/media/quality/MediaQualityManager.java b/media/java/android/media/quality/MediaQualityManager.java
index 03dc24d..61600ed 100644
--- a/media/java/android/media/quality/MediaQualityManager.java
+++ b/media/java/android/media/quality/MediaQualityManager.java
@@ -48,6 +48,8 @@
private final Object mLock = new Object();
// @GuardedBy("mLock")
private final List<PictureProfileCallbackRecord> mPpCallbackRecords = new ArrayList<>();
+ // @GuardedBy("mLock")
+ private final List<SoundProfileCallbackRecord> mSpCallbackRecords = new ArrayList<>();
/**
* @hide
@@ -55,7 +57,7 @@
public MediaQualityManager(Context context, IMediaQualityManager service) {
mContext = context;
mService = service;
- IPictureProfileCallback mqCallback = new IPictureProfileCallback.Stub() {
+ IPictureProfileCallback ppCallback = new IPictureProfileCallback.Stub() {
@Override
public void onPictureProfileAdded(long profileId, PictureProfile profile) {
synchronized (mLock) {
@@ -74,14 +76,60 @@
}
}
}
+ @Override
+ public void onPictureProfileRemoved(long profileId, PictureProfile profile) {
+ synchronized (mLock) {
+ for (PictureProfileCallbackRecord record : mPpCallbackRecords) {
+ // TODO: filter callback record
+ record.postPictureProfileRemoved(profileId, profile);
+ }
+ }
+ }
};
+ ISoundProfileCallback spCallback = new ISoundProfileCallback.Stub() {
+ @Override
+ public void onSoundProfileAdded(long profileId, SoundProfile profile) {
+ synchronized (mLock) {
+ for (SoundProfileCallbackRecord record : mSpCallbackRecords) {
+ // TODO: filter callback record
+ record.postSoundProfileAdded(profileId, profile);
+ }
+ }
+ }
+ @Override
+ public void onSoundProfileUpdated(long profileId, SoundProfile profile) {
+ synchronized (mLock) {
+ for (SoundProfileCallbackRecord record : mSpCallbackRecords) {
+ // TODO: filter callback record
+ record.postSoundProfileUpdated(profileId, profile);
+ }
+ }
+ }
+ @Override
+ public void onSoundProfileRemoved(long profileId, SoundProfile profile) {
+ synchronized (mLock) {
+ for (SoundProfileCallbackRecord record : mSpCallbackRecords) {
+ // TODO: filter callback record
+ record.postSoundProfileRemoved(profileId, profile);
+ }
+ }
+ }
+ };
+ try {
+ if (mService != null) {
+ mService.registerPictureProfileCallback(ppCallback);
+ mService.registerSoundProfileCallback(spCallback);
+ }
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
}
/**
* Registers a {@link PictureProfileCallback}.
* @hide
*/
- public void registerCallback(
+ public void registerPictureProfileCallback(
@NonNull @CallbackExecutor Executor executor,
@NonNull PictureProfileCallback callback) {
Preconditions.checkNotNull(callback);
@@ -95,7 +143,7 @@
* Unregisters the existing {@link PictureProfileCallback}.
* @hide
*/
- public void unregisterCallback(@NonNull final PictureProfileCallback callback) {
+ public void unregisterPictureProfileCallback(@NonNull final PictureProfileCallback callback) {
Preconditions.checkNotNull(callback);
synchronized (mLock) {
for (Iterator<PictureProfileCallbackRecord> it = mPpCallbackRecords.iterator();
@@ -143,11 +191,11 @@
}
}
- /** @SystemApi all stored picture profiles */
+ /** @SystemApi all stored picture profiles of all packages */
@RequiresPermission(android.Manifest.permission.MANAGE_GLOBAL_PICTURE_QUALITY_SERVICE)
- public List<PictureProfile> getAvailableAllPictureProfiles() {
+ public List<PictureProfile> getAllPictureProfiles() {
try {
- return mService.getAvailableAllPictureProfiles();
+ return mService.getAllPictureProfiles();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -167,6 +215,144 @@
}
}
+
+ /**
+ * Updates an existing picture profile and store it in the system.
+ */
+ public void updatePictureProfile(long profileId, PictureProfile pp) {
+ try {
+ mService.updatePictureProfile(profileId, pp);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+
+ /**
+ * Removes a picture profile from the system.
+ */
+ public void removePictureProfile(long profileId) {
+ try {
+ mService.removePictureProfile(profileId);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Registers a {@link SoundProfileCallback}.
+ * @hide
+ */
+ public void registerSoundProfileCallback(
+ @NonNull @CallbackExecutor Executor executor,
+ @NonNull SoundProfileCallback callback) {
+ Preconditions.checkNotNull(callback);
+ Preconditions.checkNotNull(executor);
+ synchronized (mLock) {
+ mSpCallbackRecords.add(new SoundProfileCallbackRecord(callback, executor));
+ }
+ }
+
+ /**
+ * Unregisters the existing {@link SoundProfileCallback}.
+ * @hide
+ */
+ public void unregisterSoundProfileCallback(@NonNull final SoundProfileCallback callback) {
+ Preconditions.checkNotNull(callback);
+ synchronized (mLock) {
+ for (Iterator<SoundProfileCallbackRecord> it = mSpCallbackRecords.iterator();
+ it.hasNext(); ) {
+ SoundProfileCallbackRecord record = it.next();
+ if (record.getCallback() == callback) {
+ it.remove();
+ break;
+ }
+ }
+ }
+ }
+
+
+ /**
+ * Gets sound profile by given profile ID.
+ * @return the corresponding sound profile if available; {@code null} if the ID doesn't
+ * exist or the profile is not accessible to the caller.
+ */
+ public SoundProfile getSoundProfileById(long profileId) {
+ try {
+ return mService.getSoundProfileById(profileId);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+
+ /** @SystemApi gets profiles that available to the given package */
+ @RequiresPermission(android.Manifest.permission.MANAGE_GLOBAL_PICTURE_QUALITY_SERVICE)
+ public List<SoundProfile> getSoundProfilesByPackage(String packageName) {
+ try {
+ return mService.getSoundProfilesByPackage(packageName);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /** Gets profiles that available to the caller package */
+ public List<SoundProfile> getAvailableSoundProfiles() {
+ try {
+ return mService.getAvailableSoundProfiles();
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /** @SystemApi all stored sound profiles of all packages */
+ @RequiresPermission(android.Manifest.permission.MANAGE_GLOBAL_PICTURE_QUALITY_SERVICE)
+ public List<SoundProfile> getAllSoundProfiles() {
+ try {
+ return mService.getAllSoundProfiles();
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+
+ /**
+ * Creates a sound profile and store it in the system.
+ *
+ * @return the stored profile with an assigned profile ID.
+ */
+ public SoundProfile createSoundProfile(SoundProfile sp) {
+ try {
+ return mService.createSoundProfile(sp);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+
+ /**
+ * Updates an existing sound profile and store it in the system.
+ */
+ public void updateSoundProfile(long profileId, SoundProfile sp) {
+ try {
+ mService.updateSoundProfile(profileId, sp);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+
+ /**
+ * Removes a sound profile from the system.
+ */
+ public void removeSoundProfile(long profileId) {
+ try {
+ mService.removeSoundProfile(profileId);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
private static final class PictureProfileCallbackRecord {
private final PictureProfileCallback mCallback;
private final Executor mExecutor;
@@ -198,6 +384,57 @@
}
});
}
+
+ public void postPictureProfileRemoved(final long id, PictureProfile profile) {
+ mExecutor.execute(new Runnable() {
+ @Override
+ public void run() {
+ mCallback.onPictureProfileRemoved(id, profile);
+ }
+ });
+ }
+ }
+
+ private static final class SoundProfileCallbackRecord {
+ private final SoundProfileCallback mCallback;
+ private final Executor mExecutor;
+
+ SoundProfileCallbackRecord(SoundProfileCallback callback, Executor executor) {
+ mCallback = callback;
+ mExecutor = executor;
+ }
+
+ public SoundProfileCallback getCallback() {
+ return mCallback;
+ }
+
+ public void postSoundProfileAdded(final long id, SoundProfile profile) {
+
+ mExecutor.execute(new Runnable() {
+ @Override
+ public void run() {
+ mCallback.onSoundProfileAdded(id, profile);
+ }
+ });
+ }
+
+ public void postSoundProfileUpdated(final long id, SoundProfile profile) {
+ mExecutor.execute(new Runnable() {
+ @Override
+ public void run() {
+ mCallback.onSoundProfileUpdated(id, profile);
+ }
+ });
+ }
+
+ public void postSoundProfileRemoved(final long id, SoundProfile profile) {
+ mExecutor.execute(new Runnable() {
+ @Override
+ public void run() {
+ mCallback.onSoundProfileRemoved(id, profile);
+ }
+ });
+ }
}
/**
@@ -215,5 +452,42 @@
*/
public void onPictureProfileUpdated(long id, PictureProfile profile) {
}
+ /**
+ * @hide
+ */
+ public void onPictureProfileRemoved(long id, PictureProfile profile) {
+ }
+ /**
+ * @hide
+ */
+ public void onError(int errorCode) {
+ }
+ }
+
+ /**
+ * Callback used to monitor status of sound profiles.
+ * @hide
+ */
+ public abstract static class SoundProfileCallback {
+ /**
+ * @hide
+ */
+ public void onSoundProfileAdded(long id, SoundProfile profile) {
+ }
+ /**
+ * @hide
+ */
+ public void onSoundProfileUpdated(long id, SoundProfile profile) {
+ }
+ /**
+ * @hide
+ */
+ public void onSoundProfileRemoved(long id, SoundProfile profile) {
+ }
+ /**
+ * @hide
+ */
+ public void onError(int errorCode) {
+ }
}
}
diff --git a/media/java/android/media/quality/SoundProfile.java b/media/java/android/media/quality/SoundProfile.java
index e0fcf9d..20d117b 100644
--- a/media/java/android/media/quality/SoundProfile.java
+++ b/media/java/android/media/quality/SoundProfile.java
@@ -18,6 +18,7 @@
import android.annotation.FlaggedApi;
import android.media.tv.flags.Flags;
+import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
@@ -37,6 +38,8 @@
private final String mInputId;
@Nullable
private final String mPackageName;
+ @NonNull
+ private final Bundle mParams;
protected SoundProfile(Parcel in) {
if (in.readByte() == 0) {
@@ -47,6 +50,7 @@
mName = in.readString();
mInputId = in.readString();
mPackageName = in.readString();
+ mParams = in.readBundle();
}
@Override
@@ -60,6 +64,7 @@
dest.writeString(mName);
dest.writeString(mInputId);
dest.writeString(mPackageName);
+ dest.writeBundle(mParams);
}
@Override
@@ -89,12 +94,14 @@
@Nullable Long id,
@NonNull String name,
@Nullable String inputId,
- @Nullable String packageName) {
+ @Nullable String packageName,
+ @NonNull Bundle params) {
this.mId = id;
this.mName = name;
com.android.internal.util.AnnotationValidations.validate(NonNull.class, null, name);
this.mInputId = inputId;
this.mPackageName = packageName;
+ this.mParams = params;
}
@Nullable
@@ -116,6 +123,10 @@
public String getPackageName() {
return mPackageName;
}
+ @NonNull
+ public Bundle getParameters() {
+ return new Bundle(mParams);
+ }
/**
* A builder for {@link SoundProfile}
@@ -129,6 +140,8 @@
private String mInputId;
@Nullable
private String mPackageName;
+ @NonNull
+ private Bundle mParams;
/**
* Creates a new Builder.
@@ -181,6 +194,14 @@
}
/**
+ * Sets profile parameters.
+ */
+ @NonNull
+ public Builder setParameters(@NonNull Bundle params) {
+ mParams = new Bundle(params);
+ return this;
+ }
+ /**
* Builds the instance.
*/
@NonNull
@@ -190,7 +211,8 @@
mId,
mName,
mInputId,
- mPackageName);
+ mPackageName,
+ mParams);
return o;
}
}
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 d265b6a..57c9f51 100644
--- a/services/core/java/com/android/server/media/quality/MediaQualityService.java
+++ b/services/core/java/com/android/server/media/quality/MediaQualityService.java
@@ -18,7 +18,10 @@
import android.content.Context;
import android.media.quality.IMediaQualityManager;
+import android.media.quality.IPictureProfileCallback;
+import android.media.quality.ISoundProfileCallback;
import android.media.quality.PictureProfile;
+import android.media.quality.SoundProfile;
import com.android.server.SystemService;
@@ -53,6 +56,14 @@
return pp;
}
@Override
+ public void updatePictureProfile(long id, PictureProfile pp) {
+ // TODO: implement
+ }
+ @Override
+ public void removePictureProfile(long id) {
+ // TODO: implement
+ }
+ @Override
public PictureProfile getPictureProfileById(long id) {
return null;
}
@@ -65,8 +76,46 @@
return new ArrayList<>();
}
@Override
- public List<PictureProfile> getAvailableAllPictureProfiles() {
+ public List<PictureProfile> getAllPictureProfiles() {
return new ArrayList<>();
}
+
+ @Override
+ public SoundProfile createSoundProfile(SoundProfile pp) {
+ // TODO: implement
+ return pp;
+ }
+ @Override
+ public void updateSoundProfile(long id, SoundProfile pp) {
+ // TODO: implement
+ }
+ @Override
+ public void removeSoundProfile(long id) {
+ // TODO: implement
+ }
+ @Override
+ public SoundProfile getSoundProfileById(long id) {
+ return null;
+ }
+ @Override
+ public List<SoundProfile> getSoundProfilesByPackage(String packageName) {
+ return new ArrayList<>();
+ }
+ @Override
+ public List<SoundProfile> getAvailableSoundProfiles() {
+ return new ArrayList<>();
+ }
+ @Override
+ public List<SoundProfile> getAllSoundProfiles() {
+ return new ArrayList<>();
+ }
+
+
+ @Override
+ public void registerPictureProfileCallback(final IPictureProfileCallback callback) {
+ }
+ @Override
+ public void registerSoundProfileCallback(final ISoundProfileCallback callback) {
+ }
}
}