• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.settings.homepage.contextualcards.slices;
18 
19 import android.content.Context;
20 import android.net.Uri;
21 import android.os.Handler;
22 import android.os.HandlerThread;
23 import android.os.Looper;
24 import android.os.Process;
25 import android.util.Log;
26 
27 import androidx.annotation.Nullable;
28 
29 import com.android.settings.slices.SliceBackgroundWorker;
30 import com.android.settingslib.bluetooth.BluetoothCallback;
31 import com.android.settingslib.bluetooth.CachedBluetoothDevice;
32 import com.android.settingslib.bluetooth.LocalBluetoothManager;
33 
34 public class BluetoothUpdateWorker extends SliceBackgroundWorker implements BluetoothCallback {
35 
36     private static final String TAG = "BluetoothUpdateWorker";
37 
38     private static LocalBluetoothManager sLocalBluetoothManager;
39 
40     private LoadBtManagerHandler mLoadBtManagerHandler;
41 
BluetoothUpdateWorker(Context context, Uri uri)42     public BluetoothUpdateWorker(Context context, Uri uri) {
43         super(context, uri);
44         mLoadBtManagerHandler = LoadBtManagerHandler.getInstance(context);
45         if (sLocalBluetoothManager == null) {
46             mLoadBtManagerHandler.startLoadingBtManager(this);
47         }
48     }
49 
50     /** Initialize {@link LocalBluetoothManager} in the background */
initLocalBtManager(Context context)51     public static void initLocalBtManager(Context context) {
52         if (sLocalBluetoothManager == null) {
53             LoadBtManagerHandler.getInstance(context).startLoadingBtManager();
54         }
55     }
56 
57     @Nullable
getLocalBtManager()58     static LocalBluetoothManager getLocalBtManager() {
59         return sLocalBluetoothManager;
60     }
61 
62     @Override
onSlicePinned()63     protected void onSlicePinned() {
64         final LocalBluetoothManager localBtManager = mLoadBtManagerHandler.getLocalBtManager();
65         if (localBtManager == null) {
66             return;
67         }
68         localBtManager.getEventManager().registerCallback(this);
69     }
70 
71     @Override
onSliceUnpinned()72     protected void onSliceUnpinned() {
73         final LocalBluetoothManager localBtManager = mLoadBtManagerHandler.getLocalBtManager();
74         if (localBtManager == null) {
75             return;
76         }
77         localBtManager.getEventManager().unregisterCallback(this);
78     }
79 
80     @Override
close()81     public void close() {
82     }
83 
84     @Override
onAclConnectionStateChanged(CachedBluetoothDevice cachedDevice, int state)85     public void onAclConnectionStateChanged(CachedBluetoothDevice cachedDevice, int state) {
86         notifySliceChange();
87     }
88 
89     @Override
onActiveDeviceChanged(CachedBluetoothDevice activeDevice, int bluetoothProfile)90     public void onActiveDeviceChanged(CachedBluetoothDevice activeDevice, int bluetoothProfile) {
91         notifySliceChange();
92     }
93 
94     @Override
onBluetoothStateChanged(int bluetoothState)95     public void onBluetoothStateChanged(int bluetoothState) {
96         notifySliceChange();
97     }
98 
99     @Override
onConnectionStateChanged(CachedBluetoothDevice cachedDevice, int state)100     public void onConnectionStateChanged(CachedBluetoothDevice cachedDevice, int state) {
101         notifySliceChange();
102     }
103 
104     @Override
onProfileConnectionStateChanged(CachedBluetoothDevice cachedDevice, int state, int bluetoothProfile)105     public void onProfileConnectionStateChanged(CachedBluetoothDevice cachedDevice, int state,
106             int bluetoothProfile) {
107         notifySliceChange();
108     }
109 
110     private static class LoadBtManagerHandler extends Handler {
111 
112         private static LoadBtManagerHandler sHandler;
113 
114         private final Runnable mLoadBtManagerTask;
115         private final Context mContext;
116         private BluetoothUpdateWorker mWorker;
117 
getInstance(Context context)118         private static LoadBtManagerHandler getInstance(Context context) {
119             if (sHandler == null) {
120                 final HandlerThread workerThread = new HandlerThread(TAG,
121                         Process.THREAD_PRIORITY_BACKGROUND);
122                 workerThread.start();
123                 sHandler = new LoadBtManagerHandler(context, workerThread.getLooper());
124             }
125             return sHandler;
126         }
127 
LoadBtManagerHandler(Context context, Looper looper)128         private LoadBtManagerHandler(Context context, Looper looper) {
129             super(looper);
130             mContext = context;
131             mLoadBtManagerTask = () -> {
132                 Log.d(TAG, "LoadBtManagerHandler: start loading...");
133                 final long startTime = System.currentTimeMillis();
134                 sLocalBluetoothManager = getLocalBtManager();
135                 Log.d(TAG, "LoadBtManagerHandler took " + (System.currentTimeMillis() - startTime)
136                         + " ms");
137             };
138         }
139 
getLocalBtManager()140         private LocalBluetoothManager getLocalBtManager() {
141             if (sLocalBluetoothManager != null) {
142                 return sLocalBluetoothManager;
143             }
144             return LocalBluetoothManager.getInstance(mContext,
145                     (context, btManager) -> {
146                         if (mWorker != null) {
147                             // notify change if the worker is ready
148                             mWorker.notifySliceChange();
149                         }
150                     });
151         }
152 
startLoadingBtManager()153         private void startLoadingBtManager() {
154             if (!hasCallbacks(mLoadBtManagerTask)) {
155                 post(mLoadBtManagerTask);
156             }
157         }
158 
startLoadingBtManager(BluetoothUpdateWorker worker)159         private void startLoadingBtManager(BluetoothUpdateWorker worker) {
160             mWorker = worker;
161             startLoadingBtManager();
162         }
163     }
164 }