OSDN Git Service

Merge "Fix Bluetooth device details crash on screen rotation" into oc-dr1-dev
[android-x86/packages-apps-Settings.git] / src / com / android / settings / bluetooth / BluetoothDeviceDetailsFragment.java
1 /*
2  * Copyright (C) 2017 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.bluetooth;
18
19 import static android.os.UserManager.DISALLOW_CONFIG_BLUETOOTH;
20
21 import android.bluetooth.BluetoothDevice;
22 import android.content.Context;
23 import android.os.Bundle;
24 import android.support.annotation.VisibleForTesting;
25 import android.view.Menu;
26 import android.view.MenuInflater;
27 import android.view.MenuItem;
28
29 import com.android.internal.logging.nano.MetricsProto;
30 import com.android.settings.R;
31 import com.android.settings.core.PreferenceController;
32 import com.android.settings.dashboard.RestrictedDashboardFragment;
33 import com.android.settingslib.bluetooth.CachedBluetoothDevice;
34 import com.android.settingslib.bluetooth.LocalBluetoothManager;
35 import com.android.settingslib.core.lifecycle.Lifecycle;
36
37 import java.util.ArrayList;
38 import java.util.List;
39
40 public class BluetoothDeviceDetailsFragment extends RestrictedDashboardFragment {
41     public static final String KEY_DEVICE_ADDRESS = "device_address";
42     private static final String TAG = "BTDeviceDetailsFrg";
43
44     @VisibleForTesting
45     static int EDIT_DEVICE_NAME_ITEM_ID = Menu.FIRST;
46
47     /**
48      * An interface to let tests override the normal mechanism for looking up the
49      * CachedBluetoothDevice and LocalBluetoothManager, and substitute their own mocks instead.
50      * This is only needed in situations where you instantiate the fragment indirectly (eg via an
51      * intent) and can't use something like spying on an instance you construct directly via
52      * newInstance.
53      */
54     @VisibleForTesting
55     interface TestDataFactory {
56         CachedBluetoothDevice getDevice(String deviceAddress);
57         LocalBluetoothManager getManager(Context context);
58     }
59
60     @VisibleForTesting
61     static TestDataFactory sTestDataFactory;
62
63     private String mDeviceAddress;
64     private LocalBluetoothManager mManager;
65     private CachedBluetoothDevice mCachedDevice;
66
67     public BluetoothDeviceDetailsFragment() {
68         super(DISALLOW_CONFIG_BLUETOOTH);
69     }
70
71     @VisibleForTesting
72     LocalBluetoothManager getLocalBluetoothManager(Context context) {
73         if (sTestDataFactory != null) {
74             return sTestDataFactory.getManager(context);
75         }
76         return Utils.getLocalBtManager(context);
77     }
78
79     @VisibleForTesting
80     CachedBluetoothDevice getCachedDevice(String deviceAddress) {
81         if (sTestDataFactory != null) {
82             return sTestDataFactory.getDevice(deviceAddress);
83         }
84         BluetoothDevice remoteDevice =
85                 mManager.getBluetoothAdapter().getRemoteDevice(deviceAddress);
86         return mManager.getCachedDeviceManager().findDevice(remoteDevice);
87     }
88
89     public static BluetoothDeviceDetailsFragment newInstance(String deviceAddress) {
90         Bundle args = new Bundle(1);
91         args.putString(KEY_DEVICE_ADDRESS, deviceAddress);
92         BluetoothDeviceDetailsFragment fragment = new BluetoothDeviceDetailsFragment();
93         fragment.setArguments(args);
94         return fragment;
95     }
96
97     @Override
98     public void onAttach(Context context) {
99         mDeviceAddress = getArguments().getString(KEY_DEVICE_ADDRESS);
100         mManager = getLocalBluetoothManager(context);
101         mCachedDevice = getCachedDevice(mDeviceAddress);
102         super.onAttach(context);
103     }
104
105     @Override
106     public int getMetricsCategory() {
107         return MetricsProto.MetricsEvent.BLUETOOTH_DEVICE_DETAILS;
108     }
109
110     @Override
111     protected String getLogTag() {
112         return TAG;
113     }
114
115     @Override
116     protected int getPreferenceScreenResId() {
117         return R.xml.bluetooth_device_details_fragment;
118     }
119
120     @Override
121     public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
122         MenuItem item = menu.add(0, EDIT_DEVICE_NAME_ITEM_ID, 0, R.string.bluetooth_rename_button);
123         item.setIcon(R.drawable.ic_mode_edit);
124         item.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
125         super.onCreateOptionsMenu(menu, inflater);
126     }
127
128     @Override
129     public boolean onOptionsItemSelected(MenuItem menuItem) {
130         if (menuItem.getItemId() == EDIT_DEVICE_NAME_ITEM_ID) {
131             RemoteDeviceNameDialogFragment.newInstance(mCachedDevice).show(
132                     getFragmentManager(), RemoteDeviceNameDialogFragment.TAG);
133             return true;
134         }
135         return super.onOptionsItemSelected(menuItem);
136     }
137
138     @Override
139     protected List<PreferenceController> getPreferenceControllers(Context context) {
140         ArrayList<PreferenceController> controllers = new ArrayList<>();
141
142         if (mCachedDevice != null) {
143             Lifecycle lifecycle = getLifecycle();
144             controllers.add(new BluetoothDetailsHeaderController(context, this, mCachedDevice,
145                     lifecycle));
146             controllers.add(new BluetoothDetailsButtonsController(context, this, mCachedDevice,
147                     lifecycle));
148             controllers.add(new BluetoothDetailsProfilesController(context, this, mManager,
149                     mCachedDevice, lifecycle));
150             controllers.add(new BluetoothDetailsMacAddressController(context, this, mCachedDevice,
151                     lifecycle));
152         }
153         return controllers;
154     }
155 }