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 */
16package com.android.car.settings.bluetooth;
17
18import android.bluetooth.BluetoothDevice;
19import android.os.Bundle;
20import android.support.car.ui.PagedListView;
21import android.text.Editable;
22import android.text.TextWatcher;
23import android.util.Log;
24import android.view.View;
25import android.widget.Button;
26import android.widget.EditText;
27
28import com.android.car.settings.common.CarSettingActivity;
29import com.android.car.settings.R;
30import com.android.car.settings.common.NoDividerItemDecoration;
31import com.android.car.settings.common.TypedPagedListAdapter;
32
33import com.android.settingslib.bluetooth.CachedBluetoothDevice;
34import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
35import com.android.settingslib.bluetooth.LocalBluetoothManager;
36import com.android.settingslib.bluetooth.LocalBluetoothProfile;
37import com.android.settingslib.bluetooth.MapProfile;
38import com.android.settingslib.bluetooth.PanProfile;
39import com.android.settingslib.bluetooth.PbapServerProfile;
40
41import java.util.ArrayList;
42
43/**
44 * Shows details about a bluetooth device, including actions related to the device,
45 * e.g. forget etc. The intent should include information about the device, use that to
46 * render UI, e.g. show name etc.
47 */
48public class BluetoothDetailActivity extends CarSettingActivity implements
49        BluetoothProfileLineItem.DataChangedListener {
50    private static final String TAG = "BluetoothDetailActivity";
51    public static final String BT_DEVICE_KEY = "btDeviceKey";
52
53    private BluetoothDevice mDevice;
54    private CachedBluetoothDevice mCachedDevice;
55    private PagedListView mListView;
56    private TypedPagedListAdapter mPagedListAdapter;
57    private LocalBluetoothManager mLocalManager;
58    private CachedBluetoothDeviceManager mDeviceManager;
59    private EditText mNameView;
60    private Button mOkButton;
61
62    @Override
63    protected void onCreate(Bundle savedInstanceState) {
64        super.onCreate(savedInstanceState);
65        setContentView(R.layout.bluetooth_details);
66        mListView = (PagedListView) findViewById(R.id.list);
67        mListView.setDefaultItemDecoration(new NoDividerItemDecoration(this));
68        mListView.setDarkMode();
69
70        if (getIntent() != null && getIntent().getExtras() != null) {
71            mDevice = getIntent().getExtras().getParcelable(BT_DEVICE_KEY);
72        }
73        if (mDevice == null) {
74            Log.w(TAG, "No bluetooth device set.");
75            return;
76        }
77
78        mLocalManager = LocalBluetoothManager.getInstance(this /* context */ , null /* listener */);
79        if (mLocalManager == null) {
80            Log.e(TAG, "Bluetooth is not supported on this device");
81            return;
82        }
83        mDeviceManager = mLocalManager.getCachedDeviceManager();
84        mCachedDevice = mDeviceManager.findDevice(mDevice);
85        if (mCachedDevice == null) {
86            mCachedDevice = mDeviceManager.addDevice(
87                    mLocalManager.getBluetoothAdapter(),
88                    mLocalManager.getProfileManager(),
89                    mDevice);
90        }
91
92        mNameView = (EditText) findViewById(R.id.bt_name);
93        mNameView.setText(mDevice.getName());
94        setupForgetButton();
95        setupOkButton();
96
97        mPagedListAdapter = new TypedPagedListAdapter(this /* context */, getProfileLineItems());
98        mListView.setAdapter(mPagedListAdapter);
99    }
100
101    @Override
102    public void setupActionBar() {
103        super.setupActionBar();
104        getActionBar().setCustomView(R.layout.action_bar_with_button);
105        getActionBar().setDisplayShowCustomEnabled(true);
106    }
107
108    @Override
109    public void onDataChanged() {
110        mPagedListAdapter.notifyDataSetChanged();
111    }
112
113    private ArrayList<TypedPagedListAdapter.LineItem> getProfileLineItems() {
114        ArrayList<TypedPagedListAdapter.LineItem> lineItems = new ArrayList<>();
115        for (LocalBluetoothProfile profile : mCachedDevice.getConnectableProfiles()) {
116            lineItems.add(new BluetoothProfileLineItem(
117                    this /* context */, profile, mCachedDevice, this));
118        }
119
120        int pbapPermission = mCachedDevice.getPhonebookPermissionChoice();
121        // Only provide PBAP cabability if the client device has requested PBAP.
122        if (pbapPermission != CachedBluetoothDevice.ACCESS_UNKNOWN) {
123            PbapServerProfile psp = mLocalManager.getProfileManager().getPbapProfile();
124            lineItems.add(new BluetoothProfileLineItem(
125                    this /* context */, psp, mCachedDevice, this));
126        }
127
128        int mapPermission = mCachedDevice.getMessagePermissionChoice();
129        if (mapPermission != CachedBluetoothDevice.ACCESS_UNKNOWN) {
130            MapProfile mapProfile = mLocalManager.getProfileManager().getMapProfile();
131            lineItems.add(new BluetoothProfileLineItem(
132                    this /* context */, mapProfile, mCachedDevice, this));
133        }
134        return lineItems;
135    }
136
137    private void setupForgetButton() {
138        Button fortgetButton = (Button) findViewById(R.id.action_button2);
139        fortgetButton.setVisibility(View.VISIBLE);
140        fortgetButton.setText(R.string.forget);
141        fortgetButton.setOnClickListener(v -> {
142            mCachedDevice.unpair();
143            finish();
144        });
145    }
146
147    private void setupOkButton() {
148        mOkButton = (Button) findViewById(R.id.action_button1);
149        mOkButton.setText(R.string.okay);
150        // before the text gets changed, always set it in a disabled state.
151        mOkButton.setEnabled(false);
152        mNameView.addTextChangedListener(new TextWatcher() {
153            @Override
154            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
155                // don't care
156            }
157
158            @Override
159            public void onTextChanged(CharSequence s, int start, int before, int count) {
160                // dont' care
161            }
162
163            @Override
164            public void afterTextChanged(Editable s) {
165                mOkButton.setEnabled(!s.toString().equals(mDevice.getName()));
166            }
167        });
168        mOkButton.setOnClickListener(v -> {
169            mCachedDevice.setName(mNameView.getText().toString());
170            finish();
171        });
172    }
173}
174