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

Commit 2c1a8378 authored by Preethi Kandhalu's avatar Preethi Kandhalu
Browse files

[Media Quality] Add Temp Id Map to Sound Profile and refactor

Test: logs and CTS
Flag: android.media.tv.flags.media_quality_fw
Bug: 378708165

Change-Id: I962a88849934cee3eb3da7e5ddbb3235e79b25d8
parent 04d88228
Loading
Loading
Loading
Loading
+186 −182
Original line number Diff line number Diff line
@@ -58,12 +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> mTempIdMap;
    private final BiMap<Long, String> mPictureProfileTempIdMap;
    private final BiMap<Long, String> mSoundProfileTempIdMap;

    public MediaQualityService(Context context) {
        super(context);
        mContext = context;
        mTempIdMap = HashBiMap.create();
        mPictureProfileTempIdMap = HashBiMap.create();
        mSoundProfileTempIdMap = HashBiMap.create();
        mMediaQualityDbHelper = new MediaQualityDbHelper(mContext);
        mMediaQualityDbHelper.setWriteAheadLoggingEnabled(true);
        mMediaQualityDbHelper.setIdleConnectionTimeout(30);
@@ -86,26 +88,16 @@ 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);
            populateTempIdMap(id);
            pp.setProfileId(mTempIdMap.get(id));
            populateTempIdMap(mPictureProfileTempIdMap, id);
            pp.setProfileId(mPictureProfileTempIdMap.get(id));
            return pp;
        }

        private void populateTempIdMap(Long id) {
            if (id != null && mTempIdMap.get(id) == null) {
                String uuid = UUID.randomUUID().toString();
                while (mTempIdMap.inverse().containsKey(uuid)) {
                    uuid = UUID.randomUUID().toString();
                }
                mTempIdMap.put(id, uuid);
            }
        }

        @Override
        public void updatePictureProfile(String id, PictureProfile pp, int userId) {
            // TODO: implement
@@ -113,34 +105,27 @@ public class MediaQualityService extends SystemService {

        @Override
        public void removePictureProfile(String id, int userId) {
            Long intId = mTempIdMap.inverse().get(id);
            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);
                mTempIdMap.remove(intId);
                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) {
@@ -157,93 +142,11 @@ public class MediaQualityService extends SystemService {
            }
        }

        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 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 getPictureProfileWithTempIdFromCursor(Cursor cursor) {
            int colIndex = cursor.getColumnIndex(BaseParameters.PARAMETER_ID);
            Long dbId = colIndex != -1 ? cursor.getLong(colIndex) : null;
            populateTempIdMap(dbId);
            String tempId = mTempIdMap.get(dbId);

            colIndex = cursor.getColumnIndex(BaseParameters.PARAMETER_TYPE);
            int type = colIndex != -1 ? cursor.getInt(colIndex) : 0;

            colIndex = cursor.getColumnIndex(BaseParameters.PARAMETER_NAME);
            String name = colIndex != -1 ? cursor.getString(colIndex) : null;

            colIndex = cursor.getColumnIndex(BaseParameters.PARAMETER_INPUT_ID);
            String inputId = colIndex != -1 ? cursor.getString(colIndex) : null;

            colIndex = cursor.getColumnIndex(BaseParameters.PARAMETER_PACKAGE);
            String packageName = colIndex != -1 ? cursor.getString(colIndex) : null;

            colIndex = cursor.getColumnIndex(mMediaQualityDbHelper.SETTINGS);
            String settings = colIndex != -1 ? cursor.getString(colIndex) : null;

            return new PictureProfile(tempId, 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);
        }

@@ -254,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(getPictureProfileWithTempIdFromCursor(cursor));
                }
                return pictureProfiles;
            }
        }

        @Override
        public PictureProfileHandle getPictureProfileHandle(String id, int userId) {
            return null;
@@ -294,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
@@ -310,28 +197,27 @@ public class MediaQualityService extends SystemService {

        @Override
        public void removeSoundProfile(String id, int userId) {
            Long intId = mSoundProfileTempIdMap.inverse().get(id);
            if (intId != null) {
                SQLiteDatabase db = mMediaQualityDbHelper.getWritableDatabase();
                String selection = BaseParameters.PARAMETER_ID + " = ?";
            String[] selectionArgs = {id};
            db.delete(mMediaQualityDbHelper.SOUND_QUALITY_TABLE_NAME, selection, selectionArgs);
                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) {
@@ -344,7 +230,7 @@ public class MediaQualityService extends SystemService {
                    return null;
                }
                cursor.moveToFirst();
                return getSoundProfileFromCursor(cursor);
                return getSoundProfileWithTempIdFromCursor(cursor);
            }
        }

@@ -352,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);
        }

@@ -367,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,
@@ -381,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 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 List<SoundProfile> getSoundProfilesBasedOnConditions(String[] columns,
                String selection, String[] selectionArguments) {
        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;
            }