Android8-ConnectedDeviceDashboardFragment

界面:

ConnectedDeviceDashboardFragment

继承关系:

package com.android.settings.connecteddevice;
public class ConnectedDeviceDashboardFragment extends DashboardFragment{}
->
package com.android.settings.dashboard;
public abstract class DashboardFragment extends SettingsPreferenceFragment
        implements
        SettingsDrawerActivity.CategoryListener,
        Indexable,
        SummaryLoader.SummaryConsumer {}
->
package com.android.settings;
public abstract class SettingsPreferenceFragment extends InstrumentedPreferenceFragment
        implements DialogCreatable {}
->
package com.android.settings.core;
public abstract class InstrumentedPreferenceFragment extends ObservablePreferenceFragment
        implements Instrumentable {}
->
package com.android.settings.core.lifecycle;
public abstract class ObservablePreferenceFragment extends PreferenceFragment {}
->
package android.support.v14.preference;
public abstract class PreferenceFragment extends Fragment implements
        PreferenceManager.OnPreferenceTreeClickListener,
        PreferenceManager.OnDisplayPreferenceDialogListener,
        PreferenceManager.OnNavigateToScreenListener,
        DialogPreference.TargetFragment {}

生命周期:

onAttach(Context context)
onCreate(Bundle savedInstanceState)
新增:onCreatePreferences(Bundle savedInstanceState, String rootKey)
onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState)
onViewCreated(View view, Bundle savedInstanceState)
onActivityCreated(Bundle savedInstanceState)
onStart()
onResume()
onPause()
onStop()
onDestroyView()

在onAttach(Context context)方法中设置Controller

DashboardFragment.class
private final Map<Class, PreferenceController> mPreferenceControllers = new ArrayMap<>();
    @Override
    public void onAttach(Context context) {
        super.onAttach(context);

        ....

        List<PreferenceController> controllers = getPreferenceControllers(context);
        if (controllers == null) {
            controllers = new ArrayList<>();
        }

        mPlaceholderPreferenceController =
                new DashboardTilePlaceholderPreferenceController(context);
        controllers.add(mPlaceholderPreferenceController);

        for (PreferenceController controller : controllers) {
            addPreferenceController(controller);
        }
    }
protected void addPreferenceController(PreferenceController controller) {
        mPreferenceControllers.put(controller.getClass(), controller);
    }

在onCreatePreferences(Bundle savedInstanceState, String rootKey)方法中设置PreferenceScreen数据:

ConnectedDeviceDashboardFragment.class
protected int getPreferenceScreenResId() {
        return R.xml.connected_devices;
}

R.xml.connected_devices:

<PreferenceScreen
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:title="@string/connected_devices_dashboard_title">

    <!-- 蓝牙-->
    <com.android.settings.widget.MasterSwitchPreference
      android:fragment="com.android.settings.bluetooth.BluetoothSettings"
      android:key="toggle_bluetooth"
      android:title="@string/bluetooth_settings_title"
      android:icon="@drawable/ic_settings_bluetooth"
      android:order="-7"/>

    <!-- NFC-->
    <SwitchPreference
        android:key="toggle_nfc"
        android:title="@string/nfc_quick_toggle_title"
        android:icon="@drawable/ic_nfc"
        android:summary="@string/nfc_quick_toggle_summary"
        android:order="-5"/>

    <!-- Android Bean-->
    <com.android.settingslib.RestrictedPreference
        android:fragment="com.android.settings.nfc.AndroidBeam"
        android:key="android_beam_settings"
        android:title="@string/android_beam_settings_title"
        android:icon="@drawable/ic_android"
        android:order="-4"/>

    <!-- USB-->
    <Preference
        android:key="usb_mode"
        android:title="@string/usb_pref"
        android:icon="@drawable/ic_usb"
        android:order="-3">
        <intent android:action="android.intent.action.MAIN"
                android:targetPackage="com.android.settings"
                android:targetClass="com.android.settings.deviceinfo.UsbModeChooserActivity"/>
    </Preference>

    <PreferenceCategory
        android:key="dashboard_tile_placeholder"
        android:order="50"/>

</PreferenceScreen>

解析R.xml.connected_devices绑定Controller

DashboardFragment.class
onCreatePreferences(Bundle savedInstanceState, String rootKey)
refreshAllPreferences(getLogTag());
private void displayResourceTiles() {
        //添加 xml
        final int resId = getPreferenceScreenResId();
        if (resId <= 0) {
            return;
        }
        //解析xml
        addPreferencesFromResource(resId);

        //绑定 controller
        final PreferenceScreen screen = getPreferenceScreen();
        Collection<PreferenceController> controllers = mPreferenceControllers.values();
        // xml中的item与controller建立联系
        for (PreferenceController controller : controllers) {
            controller.displayPreference(screen);
        }
    }

PreferenceFragment.class
public void addPreferencesFromResource(@XmlRes int preferencesResId) {
        requirePreferenceManager();

        setPreferenceScreen(
                mPreferenceManager.inflateFromResource(mStyledContext, preferencesResId, getPreferenceScreen())
        );
    }

public void setPreferenceScreen(PreferenceScreen preferenceScreen) {
        if (mPreferenceManager.setPreferences(preferenceScreen) && preferenceScreen != null) {
            onUnbindPreferences();
            mHavePrefs = true;
            if (mInitDone) {
                postBindPreferences();
            }
        }
    }
PreferenceManager.class
public boolean setPreferences(PreferenceScreen preferenceScreen) {
        if (preferenceScreen != mPreferenceScreen) {
            if (mPreferenceScreen != null) {
                mPreferenceScreen.onDetached();
            }
            mPreferenceScreen = preferenceScreen;
            return true;
        }

        return false;
    }

Preference初始化

package com.android.settings.widget;
public class MasterSwitchPreference extends TwoTargetPreference {}
package com.android.settingslib;
public class TwoTargetPreference extends Preference {}
package android.support.v7.preference;
public class Preference implements Comparable<Preference> {}

connected_devices.xml
<!-- 蓝牙item-->
    <com.android.settings.widget.MasterSwitchPreference
      android:fragment="com.android.settings.bluetooth.BluetoothSettings"
      android:key="toggle_bluetooth"
      android:title="@string/bluetooth_settings_title"
      android:icon="@drawable/ic_settings_bluetooth"
      android:order="-7"/>

MasterSwitchPreference.class
public MasterSwitchPreference(Context context, AttributeSet attrs,
            int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

@Override
    // <Switch />
    protected int getSecondTargetResId() {
        return R.layout.preference_widget_master_switch;
    }

TwoTargetPreference.class
public TwoTargetPreference(Context context) {
        super(context);
        init();
    }

    private void init() {
        setLayoutResource(R.layout.preference_two_target);
        final int secondTargetResId = getSecondTargetResId();
        if (secondTargetResId != 0) {
            setWidgetLayoutResource(secondTargetResId);
        }

Preference.class
public Preference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        mContext = context;

        final TypedArray a = context.obtainStyledAttributes(
                attrs, R.styleable.Preference, defStyleAttr, defStyleRes);

        mIconResId = TypedArrayUtils.getResourceId(a, R.styleable.Preference_icon,
                R.styleable.Preference_android_icon, 0);

        mKey = TypedArrayUtils.getString(a, R.styleable.Preference_key,
                R.styleable.Preference_android_key);

        mTitle = TypedArrayUtils.getText(a, R.styleable.Preference_title,
                R.styleable.Preference_android_title);

        mSummary = TypedArrayUtils.getText(a, R.styleable.Preference_summary,
                R.styleable.Preference_android_summary);

        mOrder = TypedArrayUtils.getInt(a, R.styleable.Preference_order,
                R.styleable.Preference_android_order, DEFAULT_ORDER);

        mFragment = TypedArrayUtils.getString(a, R.styleable.Preference_fragment,
                R.styleable.Preference_android_fragment);

        mLayoutResId = TypedArrayUtils.getResourceId(a, R.styleable.Preference_layout,
                R.styleable.Preference_android_layout, R.layout.preference);

        mWidgetLayoutResId = TypedArrayUtils.getResourceId(a, R.styleable.Preference_widgetLayout,
                R.styleable.Preference_android_widgetLayout, 0);

        mEnabled = TypedArrayUtils.getBoolean(a, R.styleable.Preference_enabled,
                R.styleable.Preference_android_enabled, true);

        mSelectable = TypedArrayUtils.getBoolean(a, R.styleable.Preference_selectable,
                R.styleable.Preference_android_selectable, true);

        mPersistent = TypedArrayUtils.getBoolean(a, R.styleable.Preference_persistent,
                R.styleable.Preference_android_persistent, true);

        mDependencyKey = TypedArrayUtils.getString(a, R.styleable.Preference_dependency,
                R.styleable.Preference_android_dependency);

        mAllowDividerAbove = TypedArrayUtils.getBoolean(a, R.styleable.Preference_allowDividerAbove,
                R.styleable.Preference_allowDividerAbove, mSelectable);

        mAllowDividerBelow = TypedArrayUtils.getBoolean(a, R.styleable.Preference_allowDividerBelow,
                R.styleable.Preference_allowDividerBelow, mSelectable);

        if (a.hasValue(R.styleable.Preference_defaultValue)) {
            mDefaultValue = onGetDefaultValue(a, R.styleable.Preference_defaultValue);
        } else if (a.hasValue(R.styleable.Preference_android_defaultValue)) {
            mDefaultValue = onGetDefaultValue(a, R.styleable.Preference_android_defaultValue);
        }

        mShouldDisableView =
                TypedArrayUtils.getBoolean(a, R.styleable.Preference_shouldDisableView,
                        R.styleable.Preference_android_shouldDisableView, true);

        mHasSingleLineTitleAttr = a.hasValue(R.styleable.Preference_singleLineTitle);
        if (mHasSingleLineTitleAttr) {
            mSingleLineTitle = TypedArrayUtils.getBoolean(a, R.styleable.Preference_singleLineTitle,
                R.styleable.Preference_android_singleLineTitle, true);
        }

        mIconSpaceReserved = TypedArrayUtils.getBoolean(a, R.styleable.Preference_iconSpaceReserved,
                R.styleable.Preference_android_iconSpaceReserved, false);

        a.recycle();
    }

Preference绑定数据

public class PreferenceGroupAdapter extends RecyclerView.Adapter<PreferenceViewHolder>
        implements Preference.OnPreferenceChangeInternalListener,
        PreferenceGroup.PreferencePositionCallback {}
中调用
@Override
    public void onBindViewHolder(PreferenceViewHolder holder, int position) {
        final Preference preference = getItem(position);
        preference.onBindViewHolder(holder);
    }

MasterSwitchPreference.class
@Override
    public void onBindViewHolder(PreferenceViewHolder holder) {
        super.onBindViewHolder(holder);
        final View widgetView = holder.findViewById(android.R.id.widget_frame);
        if (widgetView != null) {
            widgetView.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (mSwitch != null && !mSwitch.isEnabled()) {
                        return;
                    }
                    setChecked(!mChecked);
                    if (!callChangeListener(mChecked)) {
                        setChecked(!mChecked);
                    } else {
                        persistBoolean(mChecked);
                    }
                }
            });
        }

        mSwitch = (Switch) holder.findViewById(R.id.switchWidget);
        if (mSwitch != null) {
            mSwitch.setContentDescription(getTitle());
            mSwitch.setChecked(mChecked);//false
            mSwitch.setEnabled(mEnableSwitch);//true
        }
    }

TwoTargetPreference.class
@Override
    public void onBindViewHolder(PreferenceViewHolder holder) {
        super.onBindViewHolder(holder);
        final View divider = holder.findViewById(R.id.two_target_divider);
        final View widgetFrame = holder.findViewById(android.R.id.widget_frame);
        final boolean shouldHideSecondTarget = shouldHideSecondTarget();
        if (divider != null) {
            divider.setVisibility(shouldHideSecondTarget ? View.GONE : View.VISIBLE);
        }
        if (widgetFrame != null) {
            widgetFrame.setVisibility(shouldHideSecondTarget ? View.GONE : View.VISIBLE);
        }
    }

Preference.class 
public void onBindViewHolder(PreferenceViewHolder holder) {
        //item的点击事件
        holder.itemView.setOnClickListener(mClickListener);

        绑定xml中的数据
        ....
    }

Preference的点击事件

Preference.class
private final View.OnClickListener mClickListener = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            performClick(v);
        }
    };
@RestrictTo(LIBRARY_GROUP)
    protected void performClick(View view) {
        performClick();
    }
@RestrictTo(LIBRARY_GROUP)
    public void performClick() {

        if (!isEnabled()) {
            return;
        }

        //1.子类重写
        onClick();
        //2.Preference.OnPreferenceClickListener
        if (mOnClickListener != null && mOnClickListener.onPreferenceClick(this)) {
            return;
        }
        //3.PreferenceManager.OnPreferenceTreeClickListener
        PreferenceManager preferenceManager = getPreferenceManager();
        if (preferenceManager != null) {
            PreferenceManager.OnPreferenceTreeClickListener listener = preferenceManager
                    .getOnPreferenceTreeClickListener();
                    //把当前的Preference回调给调用者
            if (listener != null && listener.onPreferenceTreeClick(this)) {
                return;
            }
        }
        //4.Intent启动
        if (mIntent != null) {
            Context context = getContext();
            context.startActivity(mIntent);
        }
    }
 protected void onClick() {
    }

PreferenceManager.OnPreferenceTreeClickListener在PreferenceFragment.class中实现
PreferenceFragment.class
@Override
    public void onStart() {
        super.onStart();
        //添加点击事件
        mPreferenceManager.setOnPreferenceTreeClickListener(this);
        mPreferenceManager.setOnDisplayPreferenceDialogListener(this);
    }

    @Override
    public void onStop() {
        super.onStop();
        //移除点击事件
        mPreferenceManager.setOnPreferenceTreeClickListener(null);
        mPreferenceManager.setOnDisplayPreferenceDialogListener(null);
    }
/**
     * {@inheritDoc}
     */
    @Override
    public boolean onPreferenceTreeClick(Preference preference) {
        if (preference.getFragment() != null) {
            boolean handled = false;
            //getCallbackFragment()在v17 LeanbackPreference中实现
            if (getCallbackFragment() instanceof OnPreferenceStartFragmentCallback) {
                handled = ((OnPreferenceStartFragmentCallback) getCallbackFragment())
                        .onPreferenceStartFragment(this, preference);
            }
            //PreferenceFragment.OnPreferenceStartFragmentCallback在SettingsActivity中实现
            if (!handled && getActivity() instanceof OnPreferenceStartFragmentCallback) {
                handled = ((OnPreferenceStartFragmentCallback) getActivity())
                        .onPreferenceStartFragment(this, preference);
            }
            return handled;
        }
        return false;
    }

SettingsActivity.class
//xml中配置的Fragment
@Override
    public boolean onPreferenceStartFragment(PreferenceFragment caller, Preference pref) {
        startPreferencePanel(caller, pref.getFragment(), pref.getExtras(), -1, pref.getTitle(),
                null, 0);
        //返回true消费当前事件
        return true;
    }

PreferenceManager的传递:

PreferenceManager.class在PreferenceFragment.class的onCreate(...)方法初始化,然后通过xml解析,传递给顶层的PreferenceScreen。
PreferenceInflater.class在PreferenceManager.class的inflateFromResource(...)方法初始化。然后解析xml生成Preference。
解析方法调用顺序:
inflate(...)->rInflate(...)<->rInflate(...),在rInflate(...)中会向PreferenceScreen.class添加Preference.class,调用PreferenceGroup.class中的addItemFromInflater(...)->addPreference(...),
PreferenceGroup.class
public boolean addPreference(Preference preference) {
        ...
        //获取Group的的PreferenceManager
        final PreferenceManager preferenceManager = getPreferenceManager();
        ...
        //将PreferenceManager传递给子Preference
        preference.onAttachedToHierarchy(preferenceManager, id);
        ...
        return true;
    }

蓝牙Preference:
蓝牙Preference

BluetoothMasterSwitchPreferenceController.class初始化

package com.android.settings.bluetooth;
public class BluetoothMasterSwitchPreferenceController extends PreferenceController
        implements OnSummaryChangeListener,
        LifecycleObserver, OnResume, OnPause, OnStart, OnStop {}
->
package com.android.settings.core;        
public abstract class PreferenceController extends AbstractPreferenceController{}
->
package com.android.settingslib.core;
public abstract class AbstractPreferenceController {}

在ConnectedDeviceDashboardFragment.class的List<PreferenceController> getPreferenceControllers(...)方法中初始化
final BluetoothMasterSwitchPreferenceController bluetoothPreferenceController =
                new BluetoothMasterSwitchPreferenceController(
                        context,
                        Utils.getLocalBtManager(context));

//构造方法
@VisibleForTesting
    public BluetoothMasterSwitchPreferenceController(
            Context context,
            LocalBluetoothManager bluetoothManager, RestrictionUtils restrictionUtils) {
        super(context);
        //初始化
        mBluetoothManager = bluetoothManager;
        mSummaryUpdater = new BluetoothSummaryUpdater(mContext, this, mBluetoothManager);
        mRestrictionUtils = restrictionUtils;
    }

@Override
    public boolean isAvailable() {
        return true;

//Preference与Controller绑定时调用
AbstractPreferenceController.class
public void displayPreference(PreferenceScreen screen) {
      if (isAvailable()) {
          //BluetoothMasterSwitchPreferenceController未实现
          if (this instanceof Preference.OnPreferenceChangeListener) {
              final Preference preference = screen.findPreference(getPreferenceKey());
              preference.setOnPreferenceChangeListener(
                      (Preference.OnPreferenceChangeListener) this);
          }
      } else {
          removePreference(screen, getPreferenceKey());
      }
  }

@Override
    public void displayPreference(PreferenceScreen screen) {
        super.displayPreference(screen);
        //根据key="toggle_bluetooth"找到item
        mBtPreference = (MasterSwitchPreference) screen.findPreference(KEY_TOGGLE_BLUETOOTH);
        mBluetoothEnabler = new BluetoothEnabler(
                mContext,
                new MasterSwitchController(mBtPreference),
                FeatureFactory.getFactory(mContext).getMetricsFeatureProvider(),
                mBluetoothManager,
                MetricsEvent.ACTION_SETTINGS_MASTER_SWITCH_BLUETOOTH_TOGGLE,
                mRestrictionUtils);
    }    

LocalBluetoothManager初始化:

package com.android.settings.bluetooth;
Utils.class
public static LocalBluetoothManager getLocalBtManager(Context context) {
        return LocalBluetoothManager.getInstance(context, mOnInitCallback);
    }
private static final BluetoothManagerCallback mOnInitCallback = new BluetoothManagerCallback() {
        @Override
        public void onBluetoothManagerInitialized(Context appContext,
                LocalBluetoothManager bluetoothManager) {
            //只是set listener
            com.android.settingslib.bluetooth.Utils.setErrorListener(mErrorListener);
        }
    };

package com.android.settingslib.bluetooth;
LocalBluetoothManager.class
public static synchronized LocalBluetoothManager getInstance(Context context,
                                                                 BluetoothManagerCallback onInitCallback) {
        if (sInstance == null) {
            //adapter
            LocalBluetoothAdapter adapter = LocalBluetoothAdapter.getInstance();
            if (adapter == null) {
                return null;
            }
            // This will be around as long as this process is
            //只要这个过程存在,它就会存在
            Context appContext = context.getApplicationContext();
            //manager
            sInstance = new LocalBluetoothManager(adapter, appContext);
            if (onInitCallback != null) {
                onInitCallback.onBluetoothManagerInitialized(appContext, sInstance);
            }
        }

        return sInstance;
    }

public interface BluetoothManagerCallback {
        void onBluetoothManagerInitialized(Context appContext,
                                           LocalBluetoothManager bluetoothManager);
    }

private LocalBluetoothManager(LocalBluetoothAdapter adapter, Context context) {
        mContext = context;
        mLocalAdapter = adapter;
        //1。
        mCachedDeviceManager = new CachedBluetoothDeviceManager(context, this);
        //2.蓝牙广播事件管理
        mEventManager = new BluetoothEventManager(
                mLocalAdapter,
                mCachedDeviceManager,
                context);
        //3。
        mProfileManager = new LocalBluetoothProfileManager(
                context,
                mLocalAdapter,
                mCachedDeviceManager,
                mEventManager);
    }

LocalBluetoothAdapter.class
package com.android.settingslib.bluetooth;
static synchronized LocalBluetoothAdapter getInstance() {
        if (sInstance == null) {
            //package android.bluetooth;
            BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
            if (adapter != null) {
                //包装成LocalBluetoothAdapter
                sInstance = new LocalBluetoothAdapter(adapter);
            }
        }

        return sInstance;
    }
//构造函数
private LocalBluetoothAdapter(BluetoothAdapter adapter) {
        mAdapter = adapter;
    }

BluetoothAdapter.class
package android.bluetooth;
public static synchronized BluetoothAdapter getDefaultAdapter() {
        if (sAdapter == null) {
            IBinder b = ServiceManager.getService(BLUETOOTH_MANAGER_SERVICE);
            if (b != null) {
                //获取IBluetoothManager
                IBluetoothManager managerService = IBluetoothManager.Stub.asInterface(b);
                //包装成BluetoothAdapter
                sAdapter = new BluetoothAdapter(managerService);
            } else {
                Log.e(TAG, "Bluetooth binder is null");
            }
        }
        return sAdapter;
    }
BluetoothAdapter(IBluetoothManager managerService) {
        if (managerService == null) {
            throw new IllegalArgumentException("bluetooth manager service is null");
        }
        try {
            //写锁
            mServiceLock.writeLock().lock();
            mService = managerService.registerAdapter(mManagerCallback);
        } catch (RemoteException e) {
            Log.e(TAG, "", e);
        } finally {
            mServiceLock.writeLock().unlock();
        }
        mManagerService = managerService;
        mLeScanClients = new HashMap<LeScanCallback, ScanCallback>();
        mToken = new Binder();
    }
final private IBluetoothManagerCallback mManagerCallback =
        new IBluetoothManagerCallback.Stub() {
            public void onBluetoothServiceUp(IBluetooth bluetoothService) {
                ....
            }

            public void onBluetoothServiceDown() {
                ....
            }

            public void onBrEdrDown() {
                ....
            }
    };

CachedBluetoothDeviceManager.class
package com.android.settingslib.bluetooth;
CachedBluetoothDeviceManager(Context context, LocalBluetoothManager localBtManager) {
        mContext = context;
        mBtManager = localBtManager;
    }

BluetoothEventManager.class
package com.android.settingslib.bluetooth;
BluetoothEventManager(LocalBluetoothAdapter adapter,
                          CachedBluetoothDeviceManager deviceManager,
                          Context context) {
        mLocalAdapter = adapter;
        mDeviceManager = deviceManager;

        mAdapterIntentFilter = new IntentFilter();
        mProfileIntentFilter = new IntentFilter();

        //广播Action 和 Handler 缓存
        mHandlerMap = new HashMap<String, Handler>();
        mContext = context;

        // 自定义广播
        // Bluetooth on/off broadcasts
        addHandler(BluetoothAdapter.ACTION_STATE_CHANGED, new AdapterStateChangedHandler());

        // Generic connected/not broadcast
        addHandler(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED,
                new ConnectionStateChangedHandler());

        // Discovery broadcasts
        addHandler(BluetoothAdapter.ACTION_DISCOVERY_STARTED, new ScanningStateChangedHandler(true));
        addHandler(BluetoothAdapter.ACTION_DISCOVERY_FINISHED, new ScanningStateChangedHandler(false));
        addHandler(BluetoothDevice.ACTION_FOUND, new DeviceFoundHandler());
        addHandler(BluetoothDevice.ACTION_DISAPPEARED, new DeviceDisappearedHandler());
        addHandler(BluetoothDevice.ACTION_NAME_CHANGED, new NameChangedHandler());
        addHandler(BluetoothDevice.ACTION_ALIAS_CHANGED, new NameChangedHandler());

        // Pairing broadcasts
        addHandler(BluetoothDevice.ACTION_BOND_STATE_CHANGED, new BondStateChangedHandler());
        addHandler(BluetoothDevice.ACTION_PAIRING_CANCEL, new PairingCancelHandler());

        // Fine-grained state broadcasts
        addHandler(BluetoothDevice.ACTION_CLASS_CHANGED, new ClassChangedHandler());
        addHandler(BluetoothDevice.ACTION_UUID, new UuidChangedHandler());

        // Dock event broadcasts
        addHandler(Intent.ACTION_DOCK_EVENT, new DockEventHandler());

        mContext.registerReceiver(mBroadcastReceiver, mAdapterIntentFilter, null, mReceiverHandler);
    }

interface Handler {
        void onReceive(Context context, Intent intent, BluetoothDevice device);
    }

//Handler 非 android.os.Handler
private void addHandler(String action, Handler handler) {
        mHandlerMap.put(action, handler);
        mAdapterIntentFilter.addAction(action);
    }

private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);

            Handler handler = mHandlerMap.get(action);
            if (handler != null) {
                handler.onReceive(context, intent, device);
            }
        }
    };

LocalBluetoothProfileManager.class
package com.android.settingslib.bluetooth;
LocalBluetoothProfileManager(Context context,
                                 LocalBluetoothAdapter adapter,
                                 CachedBluetoothDeviceManager deviceManager,
                                 BluetoothEventManager eventManager) {

        mContext = context;

        mLocalAdapter = adapter;
        mDeviceManager = deviceManager;
        mEventManager = eventManager;
        mUsePbapPce = mContext.getResources().getBoolean(R.bool.enable_pbap_pce_profile);
        // MAP Client is typically used in the same situations as PBAP Client
        //MAP客户机通常与PBAP客户机在相同的情况下使用
        mUseMapClient = mContext.getResources().getBoolean(R.bool.enable_pbap_pce_profile);
        // pass this reference to adapter and event manager (circular dependency)
        //将此引用传递给适配器和事件管理器(循环依赖项)
        mLocalAdapter.setProfileManager(this);
        mEventManager.setProfileManager(this);

        ParcelUuid[] uuids = adapter.getUuids();

        // uuids may be null if Bluetooth is turned off
        if (uuids != null) {
            updateLocalProfiles(uuids);
        }

        // Always add HID and PAN profiles
        mHidProfile = new HidProfile(context, mLocalAdapter, mDeviceManager, this);
        addProfile(mHidProfile, HidProfile.NAME,
                BluetoothInputDevice.ACTION_CONNECTION_STATE_CHANGED);

        mPanProfile = new PanProfile(context);
        addPanProfile(mPanProfile, PanProfile.NAME,
                BluetoothPan.ACTION_CONNECTION_STATE_CHANGED);

        if (DEBUG) Log.d(TAG, "Adding local MAP profile");
        if (mUseMapClient) {
            mMapClientProfile = new MapClientProfile(mContext, mLocalAdapter, mDeviceManager, this);
            addProfile(mMapClientProfile, MapClientProfile.NAME,
                    BluetoothMapClient.ACTION_CONNECTION_STATE_CHANGED);
        } else {
            mMapProfile = new MapProfile(mContext, mLocalAdapter, mDeviceManager, this);
            addProfile(mMapProfile, MapProfile.NAME,
                    BluetoothMap.ACTION_CONNECTION_STATE_CHANGED);
        }

        //Create PBAP server profile, but do not add it to list of profiles
        // as we do not need to monitor the profile as part of profile list
        mPbapProfile = new PbapServerProfile(context);

        if (DEBUG) Log.d(TAG, "LocalBluetoothProfileManager construction complete");
    }

BluetoothSummaryUpdater.class初始化:

package com.android.settings.bluetooth;
public final class BluetoothSummaryUpdater extends SummaryUpdater implements BluetoothCallback {}

//构造函数
 public BluetoothSummaryUpdater(Context context, OnSummaryChangeListener listener,
            LocalBluetoothManager bluetoothManager) {
        super(context, listener);
        mBluetoothManager = bluetoothManager;
        mBluetoothAdapter = mBluetoothManager != null
            ? mBluetoothManager.getBluetoothAdapter() : null;
    }
//OnSummaryChangeListener的回调函数
@Override
    public void onSummaryChanged(String summary) {
        if (mBtPreference != null) {
            mBtPreference.setSummary(summary);
        }
    }

RestrictionUtils.class初始化:
public class RestrictionUtils {
public RestrictionUtils() {}
/**
* Utility method to check if user restriction is enforced on the current user.
*检查当前用户是否受到用户限制的实用方法。
*

It helps with testing - override it to avoid calling static method which calls system
* API.
* 它有助于测试——覆盖它以避免调用调用系统API的静态方法。
*/
public EnforcedAdmin checkIfRestrictionEnforced(Context context, String restriction) {
return RestrictedLockUtils.checkIfRestrictionEnforced(
context, restriction, UserHandle.myUserId());
}
}

package com.android.settings.bluetooth;

BluetoothEnabler.class初始化

package com.android.settings.bluetooth;
public final class BluetoothEnabler implements SwitchWidgetController.OnSwitchChangeListener{}

public BluetoothEnabler(Context context, SwitchWidgetController switchWidget,
            MetricsFeatureProvider metricsFeatureProvider, LocalBluetoothManager manager,
            int metricsEvent, RestrictionUtils restrictionUtils) {
        mContext = context;
        mMetricsFeatureProvider = metricsFeatureProvider;

        //处理switch
        mSwitchWidget = switchWidget;
        mSwitch = mSwitchWidget.getSwitch();
        mSwitchWidget.setListener(this);

        mValidListener = false;
        mMetricsEvent = metricsEvent;

        if (manager == null) {
            // Bluetooth is not supported
            mLocalAdapter = null;
            mSwitchWidget.setEnabled(false);
        } else {
            mLocalAdapter = manager.getBluetoothAdapter();
        }
        mIntentFilter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
        mRestrictionUtils = restrictionUtils;
    }

BluetoothMasterSwitchPreferenceController.class生命周期

public void onResume() {
        mSummaryUpdater.register(true);
    }

    @Override
    public void onPause() {
        mSummaryUpdater.register(false);
    }

//mSummaryUpdater.register(true)
@Override
    public void register(boolean listening) {
        if (mBluetoothAdapter == null) {
            return;
        }
        if (listening) {
            mEnabled = mBluetoothAdapter.isEnabled();
            //蓝牙连接状态
            mConnectionState = mBluetoothAdapter.getConnectionState();
            notifyChangeIfNeeded();
            //蓝牙事件监听
            mBluetoothManager.getEventManager().registerCallback(this);
            /*
            public interface BluetoothCallback {
                void onBluetoothStateChanged(int bluetoothState);
                void onScanningStateChanged(boolean started);
                void onDeviceAdded(CachedBluetoothDevice cachedDevice);
                void onDeviceDeleted(CachedBluetoothDevice cachedDevice);
                void onDeviceBondStateChanged(CachedBluetoothDevice cachedDevice, int bondState);
                void onConnectionStateChanged(CachedBluetoothDevice cachedDevice, int state);
            }
            * */
        } else {
            mBluetoothManager.getEventManager().unregisterCallback(this);
        }
    }
/**
     * Notifies the listener when there is update in summary
     * 在摘要中有更新时通知侦听器
     */
    protected void notifyChangeIfNeeded() {
        String summary = getSummary();
        //状态改变
        if (!TextUtils.equals(mSummary, summary)) {
            mSummary = summary;
            if (mListener != null) {
                mListener.onSummaryChanged(summary);
            }
        }
    }
@Override
    public String getSummary() {
        if (!mEnabled) {
            return mContext.getString(R.string.bluetooth_disabled);
        }
        switch (mConnectionState) {
            case BluetoothAdapter.STATE_CONNECTED:
                return getConnectedDeviceSummary();
            case BluetoothAdapter.STATE_CONNECTING:
                return mContext.getString(R.string.bluetooth_connecting);
            case BluetoothAdapter.STATE_DISCONNECTING:
                return mContext.getString(R.string.bluetooth_disconnecting);
            default:
                return mContext.getString(R.string.disconnected);
        }
    }

Preference.class
package android.support.v7.preference;
public void setSummary(CharSequence summary) {
        if ((summary == null && mSummary != null)
                || (summary != null && !summary.equals(mSummary))) {
            mSummary = summary;
            notifyChanged();
        }
    }
protected void notifyChanged() {
        if (mListener != null) {
            mListener.onPreferenceChange(this);
        }
    }
interface OnPreferenceChangeInternalListener {
        void onPreferenceChange(Preference preference);

        void onPreferenceHierarchyChange(Preference preference);

        void onPreferenceVisibilityChange(Preference preference);
    }

PreferenceGroupAdapter.class
package android.support.v7.preference;
public class PreferenceGroupAdapter extends RecyclerView.Adapter<PreferenceViewHolder>
        implements Preference.OnPreferenceChangeInternalListener,
        PreferenceGroup.PreferencePositionCallback {}

@Override
    public void onPreferenceChange(Preference preference) {
        final int index = mPreferenceList.indexOf(preference);
        // If we don't find the preference, we don't need to notify anyone
        if (index != -1) {
            // Send the pref object as a placeholder to ensure the view holder is recycled in place
            //通知RecyclerView刷新指定item
            notifyItemChanged(index, preference);
        }
    }

 @Override
    public void onStart() {
        if (mBluetoothEnabler != null) {
            mBluetoothEnabler.resume(mContext);
        }
    }

    @Override
    public void onStop() {
        if (mBluetoothEnabler != null) {
            mBluetoothEnabler.pause();
        }
    }

BluetoothEnabler.class
public void resume(Context context) {
        if (mContext != context) {
            mContext = context;
        }

        maybeEnforceRestrictions();

        if (mLocalAdapter == null) {
            mSwitchWidget.setEnabled(false);
            return;
        }

        // Bluetooth state is not sticky, so set it manually
        //蓝牙状态不粘,所以手动设置
        handleStateChanged(mLocalAdapter.getBluetoothState());

        mSwitchWidget.startListening();
        mContext.registerReceiver(mReceiver, mIntentFilter);
        mValidListener = true;
    }

/**
     * Enforces user restrictions disallowing Bluetooth (or its configuration) if there are any.
     *强制用户禁止蓝牙(或其配置),如果有的话。
     * @return if there was any user restriction to enforce.
     * 如果需要执行任何用户限制。
     */
    @VisibleForTesting
    boolean maybeEnforceRestrictions() {
        EnforcedAdmin admin = mRestrictionUtils.checkIfRestrictionEnforced(
                mContext, UserManager.DISALLOW_BLUETOOTH);
        if (admin == null) {
            admin = mRestrictionUtils.checkIfRestrictionEnforced(
                    mContext, UserManager.DISALLOW_CONFIG_BLUETOOTH);
        }
        mSwitchWidget.setDisabledByAdmin(admin);
        if (admin != null) {
            mSwitchWidget.setChecked(false);
            if (mSwitch != null) {
                mSwitch.setEnabled(false);
                mSwitch.setChecked(false);
            }
        }
        return admin != null;
    }
/**
     * If admin is not null, disables the switch.
     * Otherwise, keep it enabled.
     *
     * 如果admin不为空,则禁用开关。否则,保持启用。
     */
    public void setDisabledByAdmin(EnforcedAdmin admin) {
        setSwitchEnabled(admin == null);
    }
public void setSwitchEnabled(boolean enabled) {
        mEnableSwitch = enabled;
        if (mSwitch != null) {
            mSwitch.setEnabled(enabled);
        }
    }

void handleStateChanged(int state) {
        switch (state) {
            case BluetoothAdapter.STATE_TURNING_ON:
                mSwitchWidget.setEnabled(false);
                break;
            case BluetoothAdapter.STATE_ON:
                setChecked(true);
                mSwitchWidget.setEnabled(true);
                break;
            case BluetoothAdapter.STATE_TURNING_OFF:
                mSwitchWidget.setEnabled(false);
                break;
            case BluetoothAdapter.STATE_OFF:
                setChecked(false);
                mSwitchWidget.setEnabled(true);
                break;
            default:
                setChecked(false);
                mSwitchWidget.setEnabled(true);
        }
    }

private void setChecked(boolean isChecked) {
        if (isChecked != mSwitchWidget.isChecked()) {
            // set listener to null, so onCheckedChanged won't be called
            // if the checked status on Switch isn't changed by user click
            if (mValidListener) {
                mSwitchWidget.stopListening();
            }
            mSwitchWidget.setChecked(isChecked);
            if (mValidListener) {
                mSwitchWidget.startListening();
            }
        }
    }

猜你喜欢

转载自blog.csdn.net/elzza/article/details/81560845