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

Commit 01c78053 authored by Jason Hsu's avatar Jason Hsu Committed by Gerrit Code Review
Browse files

Merge "Add new metadata APIs get/set for is_microphone_for_call_enabled" into main

parents 0ffe3470 d7f88b60
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -325,6 +325,12 @@ interface IBluetooth
    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
    int getActiveAudioDevicePolicy(in BluetoothDevice device, in AttributionSource source);

    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
    int setMicrophonePreferredForCalls(in BluetoothDevice device, in boolean enabled, in AttributionSource source);

    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
    boolean isMicrophonePreferredForCalls(in BluetoothDevice device, in AttributionSource source);

    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED)")
    oneway void killBluetoothProcess();
}
+49 −0
Original line number Diff line number Diff line
@@ -4327,6 +4327,55 @@ public class AdapterService extends Service {
            service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
            return service.mDatabaseManager.getActiveAudioDevicePolicy(device);
        }

        @Override
        public int setMicrophonePreferredForCalls(
                BluetoothDevice device, boolean enabled, AttributionSource source) {
            requireNonNull(device);
            AdapterService service = getService();
            if (service == null) {
                return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED;
            }
            if (!callerIsSystemOrActiveOrManagedUser(
                    service, TAG, "setMicrophonePreferredForCalls")) {
                return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ALLOWED;
            }
            if (!BluetoothAdapter.checkBluetoothAddress(device.getAddress())) {
                throw new IllegalArgumentException("device cannot have an invalid address");
            }
            if (!Utils.checkConnectPermissionForDataDelivery(
                    service, source, "AdapterService setMicrophonePreferredForCalls")) {
                return BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_CONNECT_PERMISSION;
            }

            service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
            return service.mDatabaseManager.setMicrophonePreferredForCalls(device, enabled);
        }

        @Override
        public boolean isMicrophonePreferredForCalls(
                BluetoothDevice device, AttributionSource source) {
            requireNonNull(device);
            AdapterService service = getService();
            if (service == null) {
                return true;
            }
            if (!callerIsSystemOrActiveOrManagedUser(
                    service, TAG, "isMicrophonePreferredForCalls")) {
                throw new IllegalStateException(
                        "Caller is not the system or part of the active/managed user");
            }
            if (!BluetoothAdapter.checkBluetoothAddress(device.getAddress())) {
                throw new IllegalArgumentException("device cannot have an invalid address");
            }
            if (!Utils.checkConnectPermissionForDataDelivery(
                    service, source, "AdapterService isMicrophonePreferredForCalls")) {
                return true;
            }

            service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
            return service.mDatabaseManager.isMicrophonePreferredForCalls(device);
        }
    }

    /**
+50 −0
Original line number Diff line number Diff line
@@ -1092,6 +1092,56 @@ public class DatabaseManager {
        }
    }

    /**
     * Sets the preferred microphone for calls enable status for this device. See {@link
     * BluetoothDevice#setMicrophonePreferredForCalls()} for more details.
     *
     * @param device is the remote device for which we set the preferred microphone for calls enable
     *     status
     * @param enabled {@code true} to enable the preferred microphone for calls
     * @return whether the preferred microphone for call enable status was set properly
     */
    public int setMicrophonePreferredForCalls(BluetoothDevice device, boolean enabled) {
        synchronized (mMetadataCache) {
            String address = device.getAddress();

            if (!mMetadataCache.containsKey(address)) {
                Log.e(TAG, "device is not bonded");
                return BluetoothStatusCodes.ERROR_DEVICE_NOT_BONDED;
            }

            Metadata metadata = mMetadataCache.get(address);
            Log.i(TAG, "setMicrophoneForCallEnabled(" + device + ", " + enabled + ")");
            metadata.is_preferred_microphone_for_calls = enabled;

            updateDatabase(metadata);
        }
        return BluetoothStatusCodes.SUCCESS;
    }

    /**
     * Gets the preferred microphone for calls enable status for this device. See {@link
     * BluetoothDevice#isMicrophonePreferredForCalls()} for more details.
     *
     * @param device is the remote device for which we get the preferred microphone for calls enable
     *     status
     * @return {@code true} if the preferred microphone is enabled for calls
     */
    public boolean isMicrophonePreferredForCalls(BluetoothDevice device) {
        synchronized (mMetadataCache) {
            String address = device.getAddress();

            if (!mMetadataCache.containsKey(address)) {
                Log.e(TAG, "device is not bonded");
                return true;
            }

            Metadata metadata = mMetadataCache.get(address);

            return metadata.is_preferred_microphone_for_calls;
        }
    }

    /**
     * Get the {@link Looper} for the handler thread. This is used in testing and helper objects
     *
+6 −0
Original line number Diff line number Diff line
@@ -73,6 +73,9 @@ public class Metadata {
    /** This is used to indicate whether device's active audio policy */
    public int active_audio_device_policy;

    /** This is used to indicate whether device's microphone prefer to use during calls */
    public boolean is_preferred_microphone_for_calls;

    Metadata(String address) {
        this(address, false, false);
    }
@@ -91,6 +94,7 @@ public class Metadata {
        preferred_output_only_profile = 0;
        preferred_duplex_profile = 0;
        active_audio_device_policy = BluetoothDevice.ACTIVE_AUDIO_DEVICE_POLICY_DEFAULT;
        is_preferred_microphone_for_calls = true;
    }

    static final class Builder {
@@ -470,6 +474,8 @@ public class Metadata {
                .append(publicMetadata)
                .append("), hfp client audio policy(")
                .append(audioPolicyMetadata)
                .append("), is_preferred_microphone_for_calls(")
                .append(is_preferred_microphone_for_calls)
                .append(")}");

        return builder.toString();
+22 −0
Original line number Diff line number Diff line
@@ -671,4 +671,26 @@ public abstract class MetadataDatabase extends RoomDatabase {
                    }
                }
            };

    @VisibleForTesting
    static final Migration MIGRATION_120_121 =
            new Migration(120, 121) {
                @Override
                public void migrate(SupportSQLiteDatabase database) {
                    try {
                        database.execSQL(
                                "ALTER TABLE metadata ADD COLUMN"
                                        + " `is_preferred_microphone_for_calls` INTEGER NOT NULL"
                                        + " DEFAULT 1");
                    } catch (SQLException ex) {
                        // Check if user has new schema, but is just missing the version update
                        Cursor cursor = database.query("SELECT * FROM metadata");
                        if (cursor == null
                                || cursor.getColumnIndex("is_preferred_microphone_for_calls")
                                        == -1) {
                            throw ex;
                        }
                    }
                }
            };
}
Loading