diff options
author | 2024-12-02 18:00:11 +0000 | |
---|---|---|
committer | 2024-12-02 18:00:11 +0000 | |
commit | dc5236d9f1a819d479994e85fd2c6ebcfba2806e (patch) | |
tree | d11e2a661c108c75e8c98c752fb907abe7558f04 | |
parent | 1786be4ac43161fac0a7e07959c5d9377a1d6c4a (diff) | |
parent | 2c1a837847e58fef587c2911b242be7ce70ff138 (diff) |
Merge changes I962a8884,If095b33c into main
* changes:
[Media Quality] Add Temp Id Map to Sound Profile and refactor
[Media Quality] Implement Remove Picture Profile API & temp map functionality
-rw-r--r-- | services/core/Android.bp | 1 | ||||
-rw-r--r-- | services/core/java/com/android/server/media/quality/MediaQualityService.java | 363 |
2 files changed, 202 insertions, 162 deletions
diff --git a/services/core/Android.bp b/services/core/Android.bp index 08206150cebb..ffa259b536ec 100644 --- a/services/core/Android.bp +++ b/services/core/Android.bp @@ -221,6 +221,7 @@ java_library_static { "securebox", "apache-commons-math", "battery_saver_flag_lib", + "guava", "notification_flags_lib", "power_hint_flags_lib", "biometrics_flags_lib", 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 65d0ab337400..14eeb3dc78f8 100644 --- a/services/core/java/com/android/server/media/quality/MediaQualityService.java +++ b/services/core/java/com/android/server/media/quality/MediaQualityService.java @@ -35,6 +35,9 @@ import android.util.Log; import com.android.server.SystemService; +import com.google.common.collect.BiMap; +import com.google.common.collect.HashBiMap; + import org.json.JSONException; import org.json.JSONObject; @@ -43,6 +46,7 @@ import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.stream.Collectors; +import java.util.UUID; /** * This service manage picture profile and sound profile for TV setting. Also communicates with the @@ -54,10 +58,14 @@ public class MediaQualityService extends SystemService { private static final String TAG = "MediaQualityService"; private final Context mContext; private final MediaQualityDbHelper mMediaQualityDbHelper; + private final BiMap<Long, String> mPictureProfileTempIdMap; + private final BiMap<Long, String> mSoundProfileTempIdMap; public MediaQualityService(Context context) { super(context); mContext = context; + mPictureProfileTempIdMap = HashBiMap.create(); + mSoundProfileTempIdMap = HashBiMap.create(); mMediaQualityDbHelper = new MediaQualityDbHelper(mContext); mMediaQualityDbHelper.setWriteAheadLoggingEnabled(true); mMediaQualityDbHelper.setIdleConnectionTimeout(30); @@ -80,11 +88,14 @@ public class MediaQualityService extends SystemService { values.put(BaseParameters.PARAMETER_NAME, pp.getName()); values.put(BaseParameters.PARAMETER_PACKAGE, pp.getPackageName()); values.put(BaseParameters.PARAMETER_INPUT_ID, pp.getInputId()); - values.put(mMediaQualityDbHelper.SETTINGS, bundleToJson(pp.getParameters())); + values.put(mMediaQualityDbHelper.SETTINGS, persistableBundleToJson(pp.getParameters())); // id is auto-generated by SQLite upon successful insertion of row - long id = db.insert(mMediaQualityDbHelper.PICTURE_QUALITY_TABLE_NAME, null, values); - return new PictureProfile.Builder(pp).setProfileId(Long.toString(id)).build(); + Long id = db.insert(mMediaQualityDbHelper.PICTURE_QUALITY_TABLE_NAME, + null, values); + populateTempIdMap(mPictureProfileTempIdMap, id); + pp.setProfileId(mPictureProfileTempIdMap.get(id)); + return pp; } @Override @@ -94,26 +105,27 @@ public class MediaQualityService extends SystemService { @Override public void removePictureProfile(String id, int userId) { - // TODO: implement + Long intId = mPictureProfileTempIdMap.inverse().get(id); + if (intId != null) { + SQLiteDatabase db = mMediaQualityDbHelper.getWritableDatabase(); + String selection = BaseParameters.PARAMETER_ID + " = ?"; + String[] selectionArgs = {Long.toString(intId)}; + db.delete(mMediaQualityDbHelper.PICTURE_QUALITY_TABLE_NAME, selection, + selectionArgs); + mPictureProfileTempIdMap.remove(intId); + } } @Override public PictureProfile getPictureProfile(int type, String name, int userId) { - SQLiteDatabase db = mMediaQualityDbHelper.getReadableDatabase(); - String selection = BaseParameters.PARAMETER_TYPE + " = ? AND " + BaseParameters.PARAMETER_NAME + " = ?"; String[] selectionArguments = {Integer.toString(type), name}; try ( - Cursor cursor = db.query( + Cursor cursor = getCursorAfterQuerying( mMediaQualityDbHelper.PICTURE_QUALITY_TABLE_NAME, - getAllPictureProfileColumns(), - selection, - selectionArguments, - /*groupBy=*/ null, - /*having=*/ null, - /*orderBy=*/ null) + getAllMediaProfileColumns(), selection, selectionArguments) ) { int count = cursor.getCount(); if (count == 0) { @@ -122,93 +134,19 @@ public class MediaQualityService extends SystemService { if (count > 1) { Log.wtf(TAG, String.format(Locale.US, "%d entries found for type=%d and name=%s" + " in %s. Should only ever be 0 or 1.", count, type, name, - mMediaQualityDbHelper.PICTURE_QUALITY_TABLE_NAME)); + mMediaQualityDbHelper.PICTURE_QUALITY_TABLE_NAME)); return null; } cursor.moveToFirst(); - return getPictureProfileFromCursor(cursor); - } - } - - private String bundleToJson(PersistableBundle bundle) { - JSONObject jsonObject = new JSONObject(); - if (bundle == null) { - return jsonObject.toString(); - } - for (String key : bundle.keySet()) { - try { - jsonObject.put(key, bundle.getString(key)); - } catch (JSONException e) { - Log.e(TAG, "Unable to serialize ", e); - } - } - return jsonObject.toString(); - } - - private PersistableBundle jsonToBundle(String jsonString) { - JSONObject jsonObject = null; - PersistableBundle bundle = new PersistableBundle(); - - try { - jsonObject = new JSONObject(jsonString); - - Iterator<String> keys = jsonObject.keys(); - while (keys.hasNext()) { - String key = keys.next(); - Object value = jsonObject.get(key); - - if (value instanceof String) { - bundle.putString(key, (String) value); - } else if (value instanceof Integer) { - bundle.putInt(key, (Integer) value); - } else if (value instanceof Boolean) { - bundle.putBoolean(key, (Boolean) value); - } else if (value instanceof Double) { - bundle.putDouble(key, (Double) value); - } else if (value instanceof Long) { - bundle.putLong(key, (Long) value); - } - } - } catch (JSONException e) { - throw new RuntimeException(e); + return getPictureProfileWithTempIdFromCursor(cursor); } - - return bundle; - } - - private String[] getAllPictureProfileColumns() { - return new String[]{ - BaseParameters.PARAMETER_ID, - BaseParameters.PARAMETER_TYPE, - BaseParameters.PARAMETER_NAME, - BaseParameters.PARAMETER_INPUT_ID, - BaseParameters.PARAMETER_PACKAGE, - mMediaQualityDbHelper.SETTINGS - }; - } - - private PictureProfile getPictureProfileFromCursor(Cursor cursor) { - String returnId = cursor.getString(cursor.getColumnIndexOrThrow( - BaseParameters.PARAMETER_ID)); - int type = cursor.getInt(cursor.getColumnIndexOrThrow( - BaseParameters.PARAMETER_TYPE)); - String name = cursor.getString(cursor.getColumnIndexOrThrow( - BaseParameters.PARAMETER_NAME)); - String inputId = cursor.getString(cursor.getColumnIndexOrThrow( - BaseParameters.PARAMETER_INPUT_ID)); - String packageName = cursor.getString(cursor.getColumnIndexOrThrow( - BaseParameters.PARAMETER_PACKAGE)); - String settings = cursor.getString( - cursor.getColumnIndexOrThrow(mMediaQualityDbHelper.SETTINGS)); - return new PictureProfile(returnId, type, name, inputId, - packageName, jsonToBundle(settings)); } @Override public List<PictureProfile> getPictureProfilesByPackage(String packageName, int userId) { String selection = BaseParameters.PARAMETER_PACKAGE + " = ?"; String[] selectionArguments = {packageName}; - return getPictureProfilesBasedOnConditions(getAllPictureProfileColumns(), selection, + return getPictureProfilesBasedOnConditions(getAllMediaProfileColumns(), selection, selectionArguments); } @@ -219,36 +157,15 @@ public class MediaQualityService extends SystemService { @Override public List<String> getPictureProfilePackageNames(int userId) { - String [] column = {BaseParameters.PARAMETER_NAME}; + String [] column = {BaseParameters.PARAMETER_PACKAGE}; List<PictureProfile> pictureProfiles = getPictureProfilesBasedOnConditions(column, null, null); return pictureProfiles.stream() - .map(PictureProfile::getName) + .map(PictureProfile::getPackageName) + .distinct() .collect(Collectors.toList()); } - private List<PictureProfile> getPictureProfilesBasedOnConditions(String[] columns, - String selection, String[] selectionArguments) { - SQLiteDatabase db = mMediaQualityDbHelper.getReadableDatabase(); - - try ( - Cursor cursor = db.query( - mMediaQualityDbHelper.PICTURE_QUALITY_TABLE_NAME, - columns, - selection, - selectionArguments, - /*groupBy=*/ null, - /*having=*/ null, - /*orderBy=*/ null) - ) { - List<PictureProfile> pictureProfiles = new ArrayList<>(); - while (cursor.moveToNext()) { - pictureProfiles.add(getPictureProfileFromCursor(cursor)); - } - return pictureProfiles; - } - } - @Override public PictureProfileHandle getPictureProfileHandle(String id, int userId) { return null; @@ -259,13 +176,18 @@ public class MediaQualityService extends SystemService { SQLiteDatabase db = mMediaQualityDbHelper.getWritableDatabase(); ContentValues values = new ContentValues(); + values.put(BaseParameters.PARAMETER_TYPE, sp.getProfileType()); values.put(BaseParameters.PARAMETER_NAME, sp.getName()); values.put(BaseParameters.PARAMETER_PACKAGE, sp.getPackageName()); values.put(BaseParameters.PARAMETER_INPUT_ID, sp.getInputId()); - values.put(mMediaQualityDbHelper.SETTINGS, bundleToJson(sp.getParameters())); + values.put(mMediaQualityDbHelper.SETTINGS, persistableBundleToJson(sp.getParameters())); - long id = db.insert(mMediaQualityDbHelper.SOUND_QUALITY_TABLE_NAME, null, values); - return new SoundProfile.Builder(sp).setProfileId(Long.toString(id)).build(); + // id is auto-generated by SQLite upon successful insertion of row + Long id = db.insert(mMediaQualityDbHelper.SOUND_QUALITY_TABLE_NAME, + null, values); + populateTempIdMap(mSoundProfileTempIdMap, id); + sp.setProfileId(mSoundProfileTempIdMap.get(id)); + return sp; } @Override @@ -275,28 +197,27 @@ public class MediaQualityService extends SystemService { @Override public void removeSoundProfile(String id, int userId) { - SQLiteDatabase db = mMediaQualityDbHelper.getWritableDatabase(); - String selection = BaseParameters.PARAMETER_ID + " = ?"; - String[] selectionArgs = {id}; - db.delete(mMediaQualityDbHelper.SOUND_QUALITY_TABLE_NAME, selection, selectionArgs); + Long intId = mSoundProfileTempIdMap.inverse().get(id); + if (intId != null) { + SQLiteDatabase db = mMediaQualityDbHelper.getWritableDatabase(); + String selection = BaseParameters.PARAMETER_ID + " = ?"; + String[] selectionArgs = {Long.toString(intId)}; + db.delete(mMediaQualityDbHelper.SOUND_QUALITY_TABLE_NAME, selection, + selectionArgs); + mSoundProfileTempIdMap.remove(intId); + } } @Override public SoundProfile getSoundProfile(int type, String id, int userId) { - SQLiteDatabase db = mMediaQualityDbHelper.getReadableDatabase(); - - String selection = BaseParameters.PARAMETER_ID + " = ?"; - String[] selectionArguments = {id}; + String selection = BaseParameters.PARAMETER_TYPE + " = ? AND " + + BaseParameters.PARAMETER_NAME + " = ?"; + String[] selectionArguments = {String.valueOf(type), id}; try ( - Cursor cursor = db.query( + Cursor cursor = getCursorAfterQuerying( mMediaQualityDbHelper.SOUND_QUALITY_TABLE_NAME, - getAllSoundProfileColumns(), - selection, - selectionArguments, - /*groupBy=*/ null, - /*having=*/ null, - /*orderBy=*/ null) + getAllMediaProfileColumns(), selection, selectionArguments) ) { int count = cursor.getCount(); if (count == 0) { @@ -309,7 +230,7 @@ public class MediaQualityService extends SystemService { return null; } cursor.moveToFirst(); - return getSoundProfileFromCursor(cursor); + return getSoundProfileWithTempIdFromCursor(cursor); } } @@ -317,7 +238,7 @@ public class MediaQualityService extends SystemService { public List<SoundProfile> getSoundProfilesByPackage(String packageName, int userId) { String selection = BaseParameters.PARAMETER_PACKAGE + " = ?"; String[] selectionArguments = {packageName}; - return getSoundProfilesBasedOnConditions(getAllSoundProfileColumns(), selection, + return getSoundProfilesBasedOnConditions(getAllMediaProfileColumns(), selection, selectionArguments); } @@ -332,13 +253,79 @@ public class MediaQualityService extends SystemService { List<SoundProfile> soundProfiles = getSoundProfilesBasedOnConditions(column, null, null); return soundProfiles.stream() - .map(SoundProfile::getName) + .map(SoundProfile::getPackageName) + .distinct() .collect(Collectors.toList()); } - private String[] getAllSoundProfileColumns() { + private void populateTempIdMap(BiMap<Long, String> map, Long id) { + if (id != null && map.get(id) == null) { + String uuid = UUID.randomUUID().toString(); + while (map.inverse().containsKey(uuid)) { + uuid = UUID.randomUUID().toString(); + } + map.put(id, uuid); + } + } + + private String persistableBundleToJson(PersistableBundle bundle) { + JSONObject json = new JSONObject(); + for (String key : bundle.keySet()) { + Object value = bundle.get(key); + try { + if (value instanceof String) { + json.put(key, bundle.getString(key)); + } else if (value instanceof Integer) { + json.put(key, bundle.getInt(key)); + } else if (value instanceof Long) { + json.put(key, bundle.getLong(key)); + } else if (value instanceof Boolean) { + json.put(key, bundle.getBoolean(key)); + } else if (value instanceof Double) { + json.put(key, bundle.getDouble(key)); + } + } catch (JSONException e) { + Log.e(TAG, "Unable to serialize ", e); + } + } + return json.toString(); + } + + private PersistableBundle jsonToBundle(String jsonString) { + PersistableBundle bundle = new PersistableBundle(); + if (jsonString != null) { + JSONObject jsonObject = null; + try { + jsonObject = new JSONObject(jsonString); + + Iterator<String> keys = jsonObject.keys(); + while (keys.hasNext()) { + String key = keys.next(); + Object value = jsonObject.get(key); + + if (value instanceof String) { + bundle.putString(key, (String) value); + } else if (value instanceof Integer) { + bundle.putInt(key, (Integer) value); + } else if (value instanceof Boolean) { + bundle.putBoolean(key, (Boolean) value); + } else if (value instanceof Double) { + bundle.putDouble(key, (Double) value); + } else if (value instanceof Long) { + bundle.putLong(key, (Long) value); + } + } + } catch (JSONException e) { + throw new RuntimeException(e); + } + } + return bundle; + } + + private String[] getAllMediaProfileColumns() { return new String[]{ BaseParameters.PARAMETER_ID, + BaseParameters.PARAMETER_TYPE, BaseParameters.PARAMETER_NAME, BaseParameters.PARAMETER_INPUT_ID, BaseParameters.PARAMETER_PACKAGE, @@ -346,40 +333,92 @@ public class MediaQualityService extends SystemService { }; } - private SoundProfile getSoundProfileFromCursor(Cursor cursor) { - String returnId = cursor.getString( - cursor.getColumnIndexOrThrow(BaseParameters.PARAMETER_ID)); - int type = cursor.getInt( - cursor.getColumnIndexOrThrow(BaseParameters.PARAMETER_TYPE)); - String name = cursor.getString( - cursor.getColumnIndexOrThrow(BaseParameters.PARAMETER_NAME)); - String inputId = cursor.getString( - cursor.getColumnIndexOrThrow(BaseParameters.PARAMETER_INPUT_ID)); - String packageName = cursor.getString( - cursor.getColumnIndexOrThrow(BaseParameters.PARAMETER_PACKAGE)); - String settings = cursor.getString( - cursor.getColumnIndexOrThrow(mMediaQualityDbHelper.SETTINGS)); - return new SoundProfile(returnId, type, name, inputId, packageName, - jsonToBundle(settings)); + private PictureProfile getPictureProfileWithTempIdFromCursor(Cursor cursor) { + return new PictureProfile( + getTempId(mPictureProfileTempIdMap, cursor), + getType(cursor), + getName(cursor), + getInputId(cursor), + getPackageName(cursor), + jsonToBundle(getSettingsString(cursor)) + ); } - private List<SoundProfile> getSoundProfilesBasedOnConditions(String[] columns, - String selection, String[] selectionArguments) { + private SoundProfile getSoundProfileWithTempIdFromCursor(Cursor cursor) { + return new SoundProfile( + getTempId(mSoundProfileTempIdMap, cursor), + getType(cursor), + getName(cursor), + getInputId(cursor), + getPackageName(cursor), + jsonToBundle(getSettingsString(cursor)) + ); + } + + private String getTempId(BiMap<Long, String> map, Cursor cursor) { + int colIndex = cursor.getColumnIndex(BaseParameters.PARAMETER_ID); + Long dbId = colIndex != -1 ? cursor.getLong(colIndex) : null; + populateTempIdMap(map, dbId); + return map.get(dbId); + } + + private int getType(Cursor cursor) { + int colIndex = cursor.getColumnIndex(BaseParameters.PARAMETER_TYPE); + return colIndex != -1 ? cursor.getInt(colIndex) : 0; + } + + private String getName(Cursor cursor) { + int colIndex = cursor.getColumnIndex(BaseParameters.PARAMETER_NAME); + return colIndex != -1 ? cursor.getString(colIndex) : null; + } + + private String getInputId(Cursor cursor) { + int colIndex = cursor.getColumnIndex(BaseParameters.PARAMETER_INPUT_ID); + return colIndex != -1 ? cursor.getString(colIndex) : null; + } + + private String getPackageName(Cursor cursor) { + int colIndex = cursor.getColumnIndex(BaseParameters.PARAMETER_PACKAGE); + return colIndex != -1 ? cursor.getString(colIndex) : null; + } + + private String getSettingsString(Cursor cursor) { + int colIndex = cursor.getColumnIndex(mMediaQualityDbHelper.SETTINGS); + return colIndex != -1 ? cursor.getString(colIndex) : null; + } + + private Cursor getCursorAfterQuerying(String table, String[] columns, String selection, + String[] selectionArgs) { SQLiteDatabase db = mMediaQualityDbHelper.getReadableDatabase(); + return db.query(table, columns, selection, selectionArgs, + /*groupBy=*/ null, /*having=*/ null, /*orderBy=*/ null); + } + private List<PictureProfile> getPictureProfilesBasedOnConditions(String[] columns, + String selection, String[] selectionArguments) { try ( - Cursor cursor = db.query( - mMediaQualityDbHelper.SOUND_QUALITY_TABLE_NAME, - columns, - selection, - selectionArguments, - /*groupBy=*/ null, - /*having=*/ null, - /*orderBy=*/ null) + Cursor cursor = getCursorAfterQuerying( + mMediaQualityDbHelper.PICTURE_QUALITY_TABLE_NAME, columns, selection, + selectionArguments) + ) { + List<PictureProfile> pictureProfiles = new ArrayList<>(); + while (cursor.moveToNext()) { + pictureProfiles.add(getPictureProfileWithTempIdFromCursor(cursor)); + } + return pictureProfiles; + } + } + + private List<SoundProfile> getSoundProfilesBasedOnConditions(String[] columns, + String selection, String[] selectionArguments) { + try ( + Cursor cursor = getCursorAfterQuerying( + mMediaQualityDbHelper.SOUND_QUALITY_TABLE_NAME, columns, selection, + selectionArguments) ) { List<SoundProfile> soundProfiles = new ArrayList<>(); while (cursor.moveToNext()) { - soundProfiles.add(getSoundProfileFromCursor(cursor)); + soundProfiles.add(getSoundProfileWithTempIdFromCursor(cursor)); } return soundProfiles; } |