If users click to pair a not foundable device and then close the Settings page, Settings will crash becasue dialog holder is closed. This CL is part of the fix. It set the context to null when the activity stops. Bug: 306548036 Test: atest Change-Id: If68e3e9cd62216ad83b2e5058f504fce35e36a06
169 lines
5.9 KiB
Java
169 lines
5.9 KiB
Java
/*
|
|
* Copyright (C) 2023 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
package com.android.settings.connecteddevice.fastpair;
|
|
|
|
import android.bluetooth.BluetoothAdapter;
|
|
import android.content.BroadcastReceiver;
|
|
import android.content.Context;
|
|
import android.content.Intent;
|
|
import android.content.IntentFilter;
|
|
import android.content.pm.PackageManager;
|
|
import android.util.Log;
|
|
|
|
import androidx.annotation.NonNull;
|
|
import androidx.annotation.VisibleForTesting;
|
|
import androidx.lifecycle.DefaultLifecycleObserver;
|
|
import androidx.lifecycle.LifecycleOwner;
|
|
import androidx.preference.Preference;
|
|
import androidx.preference.PreferenceGroup;
|
|
import androidx.preference.PreferenceScreen;
|
|
|
|
import com.android.settings.connecteddevice.DevicePreferenceCallback;
|
|
import com.android.settings.core.BasePreferenceController;
|
|
import com.android.settings.core.PreferenceControllerMixin;
|
|
import com.android.settings.flags.Flags;
|
|
import com.android.settings.overlay.FeatureFactory;
|
|
|
|
/**
|
|
* Controller to maintain the {@link PreferenceGroup} for all Fast Pair devices. It uses {@link
|
|
* DevicePreferenceCallback} to add/remove {@link Preference}
|
|
*/
|
|
public class FastPairDeviceGroupController extends BasePreferenceController
|
|
implements PreferenceControllerMixin, DefaultLifecycleObserver, DevicePreferenceCallback {
|
|
|
|
private static final String TAG = "FastPairDeviceGroupCtr";
|
|
|
|
private static final String KEY = "fast_pair_device_list";
|
|
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
|
|
|
|
@VisibleForTesting PreferenceGroup mPreferenceGroup;
|
|
private final FastPairDeviceUpdater mFastPairDeviceUpdater;
|
|
private final BluetoothAdapter mBluetoothAdapter;
|
|
@VisibleForTesting IntentFilter mIntentFilter;
|
|
|
|
@VisibleForTesting
|
|
BroadcastReceiver mReceiver =
|
|
new BroadcastReceiver() {
|
|
@Override
|
|
public void onReceive(Context context, Intent intent) {
|
|
updatePreferenceVisibility();
|
|
}
|
|
};
|
|
|
|
public FastPairDeviceGroupController(Context context) {
|
|
super(context, KEY);
|
|
if (Flags.enableSubsequentPairSettingsIntegration()) {
|
|
FastPairFeatureProvider fastPairFeatureProvider =
|
|
FeatureFactory.getFeatureFactory().getFastPairFeatureProvider();
|
|
mFastPairDeviceUpdater =
|
|
fastPairFeatureProvider.getFastPairDeviceUpdater(context, this);
|
|
} else {
|
|
Log.d(TAG, "Flag disabled. Ignored.");
|
|
mFastPairDeviceUpdater = null;
|
|
}
|
|
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
|
|
mIntentFilter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
|
|
}
|
|
|
|
@Override
|
|
public void onStart(@NonNull LifecycleOwner owner) {
|
|
if (mFastPairDeviceUpdater != null) {
|
|
mFastPairDeviceUpdater.setPreferenceContext(mContext);
|
|
mFastPairDeviceUpdater.registerCallback();
|
|
} else {
|
|
if (DEBUG) {
|
|
Log.d(TAG, "Callback register: Fast Pair device updater is null. Ignore.");
|
|
}
|
|
}
|
|
mContext.registerReceiver(mReceiver, mIntentFilter, Context.RECEIVER_EXPORTED_UNAUDITED);
|
|
}
|
|
|
|
@Override
|
|
public void onStop(@NonNull LifecycleOwner owner) {
|
|
if (mFastPairDeviceUpdater != null) {
|
|
mFastPairDeviceUpdater.setPreferenceContext(null);
|
|
mFastPairDeviceUpdater.unregisterCallback();
|
|
} else {
|
|
if (DEBUG) {
|
|
Log.d(TAG, "Callback unregister: Fast Pair device updater is null. Ignore.");
|
|
}
|
|
}
|
|
mContext.unregisterReceiver(mReceiver);
|
|
}
|
|
|
|
@Override
|
|
public void displayPreference(PreferenceScreen screen) {
|
|
mPreferenceGroup = screen.findPreference(KEY);
|
|
mPreferenceGroup.setVisible(false);
|
|
|
|
if (isAvailable()) {
|
|
final Context context = screen.getContext();
|
|
mFastPairDeviceUpdater.setPreferenceContext(context);
|
|
mFastPairDeviceUpdater.forceUpdate();
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public int getAvailabilityStatus() {
|
|
return (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH)
|
|
&& mFastPairDeviceUpdater != null)
|
|
? AVAILABLE
|
|
: UNSUPPORTED_ON_DEVICE;
|
|
}
|
|
|
|
@Override
|
|
public String getPreferenceKey() {
|
|
return KEY;
|
|
}
|
|
|
|
@Override
|
|
public void onDeviceAdded(Preference preference) {
|
|
if (preference == null) {
|
|
if (DEBUG) {
|
|
Log.d(TAG, "onDeviceAdded receives null preference. Ignore.");
|
|
}
|
|
return;
|
|
}
|
|
mPreferenceGroup.addPreference(preference);
|
|
updatePreferenceVisibility();
|
|
}
|
|
|
|
@Override
|
|
public void onDeviceRemoved(Preference preference) {
|
|
if (preference == null) {
|
|
if (DEBUG) {
|
|
Log.d(TAG, "onDeviceRemoved receives null preference. Ignore.");
|
|
}
|
|
return;
|
|
}
|
|
mPreferenceGroup.removePreference(preference);
|
|
updatePreferenceVisibility();
|
|
}
|
|
|
|
private void updatePreferenceVisibility() {
|
|
mPreferenceGroup.setVisible(
|
|
mBluetoothAdapter != null
|
|
&& mBluetoothAdapter.isEnabled()
|
|
&& mPreferenceGroup.getPreferenceCount() > 0);
|
|
}
|
|
|
|
@VisibleForTesting
|
|
public void setPreferenceGroup(PreferenceGroup preferenceGroup) {
|
|
mPreferenceGroup = preferenceGroup;
|
|
}
|
|
}
|