Android12 不依賴運(yùn)行時(shí)權(quán)限使用藍(lán)牙Sco

背景

在Android 12+上,Android添加了一個(gè)新的運(yùn)行時(shí)權(quán)限BLUETOOTH_CONNECT,官方解釋是

Required to be able to connect to paired Bluetooth devices. 看起來要配對(duì)藍(lán)牙就一定需要這個(gè)權(quán)限了??墒沁@個(gè)權(quán)限是Dangerous,這樣就得彈窗申請(qǐng)了,有沒有可能不用這個(gè)權(quán)限,依舊可以配對(duì)藍(lán)牙。

通過分析業(yè)界的產(chǎn)品,發(fā)現(xiàn)有的產(chǎn)品可以做到,這樣就需要看看是如何實(shí)現(xiàn)的了。

分析

首先dumpsys 看看能否找到線索,分析音頻藍(lán)牙相關(guān)的調(diào)用就需要看 dumpsys audio, dumpsys media.metrics, 在機(jī)器上操作了下,發(fā)現(xiàn)的確使用了通話音量,并且也有連接sco的記錄,這就證明了這個(gè)產(chǎn)品的確做到了。

比如dumpsys audio下有以下信息記錄:

10-18 11:35:14:511 setCommunicationRouteForClient for pid: 20191 device: AudioDeviceAttributes: role:output type:bt_sco addr: from API: startBluetoothSco()) from u/pid:10324/20191
10-18 11:35:14:512 startBluetoothSco()) from u/pid:10324/20191
10-18 11:35:14:529 onUpdateCommunicationRoute, preferredCommunicationDevice: null eventSource: startBluetoothSco()) from u/pid:10324/20191
10-18 11:35:14:542 removePreferredDevicesForStrategySync, strategy: 15
10-18 11:35:15:309 onUpdateCommunicationRoute, preferredCommunicationDevice: AudioDeviceAttributes: role:output type:bt_sco addr:9C:FC:28:59:5E:C1 eventSource: setBluetoothScoOn(true) from u/pid:1002/13471
10-18 11:35:15:312 onUpdateCommunicationRoute, preferredCommunicationDevice: AudioDeviceAttributes: role:output type:bt_sco addr:9C:FC:28:59:5E:C1 eventSource: BtHelper.receiveBtEvent
10-18 11:35:15:313 setPreferredDevicesForStrategySync, strategy: 15 devices: [AudioDeviceAttributes: role:output type:bt_sco addr:9C:FC:28:59:5E:C1]

可是dumpsys 里看不出來調(diào)用什么接口感知到藍(lán)牙設(shè)備了,接下來就得通過hook了,對(duì)于這種問題,應(yīng)該用objection就夠了。和音頻相關(guān)的類主要是Audio.Media.AudioManager, 那直接hook這個(gè)類的所有方法就好了。

指令如下:

 android hooking watch class android.media.AudioManager

這時(shí)候操作下應(yīng)用,就看到了一個(gè)可疑的調(diào)用registerAudioDeviceCallback

接下來繼續(xù)hook這個(gè)方法

android hooking watch class_method android.media.AudioManager.registerAudioDeviceCallback --dump-args --dump-ba
cktrace --dump-return

這下子就看到了具體調(diào)用了

[usb] # (agent) [681721] Called android.media.AudioManager.registerAudioDeviceCallback(android.media.AudioDeviceCallback, android.os.Handler)
(agent) [681721] Backtrace:
        android.media.AudioManager.registerAudioDeviceCallback(Native Method)

這樣就基本鎖定了方向,接下來研究下這個(gè)方法,

     * Registers an {@link AudioDeviceCallback} object to receive notifications of changes
     * to the set of connected audio devices.
     * @param callback The {@link AudioDeviceCallback} object to receive connect/disconnect
     * notifications.
     * @param handler Specifies the {@link Handler} object for the thread on which to execute
     * the callback. If <code>null</code>, the {@link Handler} associated with the main
     * {@link Looper} will be used.
     */
    public void registerAudioDeviceCallback(AudioDeviceCallback callback,
            @Nullable Handler handler) {
        synchronized (mDeviceCallbacks) {
            if (callback != null && !mDeviceCallbacks.containsKey(callback)) {
                if (mDeviceCallbacks.size() == 0) {
                    if (mPortListener == null) {
                        mPortListener = new OnAmPortUpdateListener();
                    }
                    registerAudioPortUpdateListener(mPortListener);
                }
                NativeEventHandlerDelegate delegate =
                        new NativeEventHandlerDelegate(callback, handler);
                mDeviceCallbacks.put(callback, delegate);
                broadcastDeviceListChange_sync(delegate.getHandler());
            }
        }
    }

看起來這個(gè)方法會(huì)以回調(diào)形式提供所有的路由設(shè)備變化,而藍(lán)牙對(duì)應(yīng)的Flag就是TYPE_BLUETOOTH_A2DP, TYPE_BLUETOOTH_SCO,用demo 驗(yàn)證了下,的確不需要運(yùn)行時(shí)權(quán)限也可以感知到。

到了這兒還沒有結(jié)束,對(duì)于Android12, 通過廣播感知sco的連接狀態(tài)也需要運(yùn)行時(shí)權(quán)限,看了下對(duì)比產(chǎn)品,沒有感知sco的連接結(jié)果,而我們的產(chǎn)品有這塊的檢測(cè),為了保持邏輯一致,也需要想辦法感知到到sco的連接結(jié)果。這下就不能對(duì)比了,不過看了下開啟sco的api,有如下的介紹:

 /**
     * Start bluetooth SCO audio connection.
     * <p>Requires Permission:
     *   {@link android.Manifest.permission#MODIFY_AUDIO_SETTINGS}.
     * <p>This method can be used by applications wanting to send and received audio
     * to/from a bluetooth SCO headset while the phone is not in call.
     * <p>As the SCO connection establishment can take several seconds,
     * applications should not rely on the connection to be available when the method
     * returns but instead register to receive the intent {@link #ACTION_SCO_AUDIO_STATE_UPDATED}
     * and wait for the state to be {@link #SCO_AUDIO_STATE_CONNECTED}.
     * <p>As the ACTION_SCO_AUDIO_STATE_UPDATED intent is sticky, the application can check the SCO
     * audio state before calling startBluetoothSco() by reading the intent returned by the receiver
     * registration. If the state is already CONNECTED, no state change will be received via the
     * intent after calling startBluetoothSco(). It is however useful to call startBluetoothSco()
     * so that the connection stays active in case the current initiator stops the connection.
     * <p>Unless the connection is already active as described above, the state will always
     * transition from DISCONNECTED to CONNECTING and then either to CONNECTED if the connection
     * succeeds or back to DISCONNECTED if the connection fails (e.g no headset is connected).
     * <p>When finished with the SCO connection or if the establishment fails, the application must
     * call {@link #stopBluetoothSco()} to clear the request and turn down the bluetooth connection.
     * <p>Even if a SCO connection is established, the following restrictions apply on audio
     * output streams so that they can be routed to SCO headset:

也就是通過注冊(cè)ACTION_SCO_AUDIO_STATE_UPDATED 廣播,由于這個(gè)廣播是粘性的,那么就可以同步感知到sco連接結(jié)果了。再在demo上驗(yàn)證了下,的確沒問題。

安全隱私話題越來越被重視,對(duì)于產(chǎn)品,涉及到使用運(yùn)行時(shí)權(quán)限一定需要謹(jǐn)慎一些。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容