• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.companiondevicemanager;
18 
19 import static android.companion.BluetoothDeviceFilterUtils.getDeviceMacAddress;
20 import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
21 
22 import static java.util.Objects.requireNonNull;
23 
24 import android.app.Activity;
25 import android.companion.CompanionDeviceManager;
26 import android.content.Intent;
27 import android.content.pm.PackageManager;
28 import android.content.res.Resources;
29 import android.database.DataSetObserver;
30 import android.os.Bundle;
31 import android.text.Html;
32 import android.util.Log;
33 import android.view.Gravity;
34 import android.view.View;
35 import android.widget.ListView;
36 import android.widget.ProgressBar;
37 import android.widget.TextView;
38 
39 import com.android.companiondevicemanager.DeviceDiscoveryService.DeviceFilterPair;
40 import com.android.internal.util.Preconditions;
41 
42 public class DeviceChooserActivity extends Activity {
43 
44     private static final boolean DEBUG = false;
45     private static final String LOG_TAG = "DeviceChooserActivity";
46 
47     View mLoadingIndicator = null;
48     ListView mDeviceListView;
49     private View mPairButton;
50     private View mCancelButton;
51 
52     @Override
onCreate(Bundle savedInstanceState)53     public void onCreate(Bundle savedInstanceState) {
54         super.onCreate(savedInstanceState);
55 
56         if (DEBUG) Log.i(LOG_TAG, "Started with intent " + getIntent());
57 
58         if (getService().mDevicesFound.isEmpty()) {
59             Log.e(LOG_TAG, "About to show UI, but no devices to show");
60         }
61 
62         getWindow().addSystemFlags(SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
63 
64         if (getService().mRequest.isSingleDevice()) {
65             setContentView(R.layout.device_confirmation);
66             final DeviceFilterPair selectedDevice = getService().mDevicesFound.get(0);
67             setTitle(Html.fromHtml(getString(
68                     R.string.confirmation_title,
69                     getCallingAppName(),
70                     selectedDevice.getDisplayName()), 0));
71             mPairButton = findViewById(R.id.button_pair);
72             mPairButton.setOnClickListener(v -> onDeviceConfirmed(getService().mSelectedDevice));
73             getService().mSelectedDevice = selectedDevice;
74             onSelectionUpdate();
75         } else {
76             setContentView(R.layout.device_chooser);
77             mPairButton = findViewById(R.id.button_pair);
78             mPairButton.setVisibility(View.GONE);
79             setTitle(Html.fromHtml(getString(R.string.chooser_title, getCallingAppName()), 0));
80             mDeviceListView = findViewById(R.id.device_list);
81             final DeviceDiscoveryService.DevicesAdapter adapter = getService().mDevicesAdapter;
82             mDeviceListView.setAdapter(adapter);
83             adapter.registerDataSetObserver(new DataSetObserver() {
84                 @Override
85                 public void onChanged() {
86                     onSelectionUpdate();
87                 }
88             });
89             mDeviceListView.addFooterView(mLoadingIndicator = getProgressBar(), null, false);
90         }
91         getService().mActivity = this;
92 
93         mCancelButton = findViewById(R.id.button_cancel);
94         mCancelButton.setOnClickListener(v -> cancel());
95     }
96 
cancel()97     private void cancel() {
98         getService().onCancel();
99         setResult(RESULT_CANCELED);
100         finish();
101     }
102 
103     @Override
onStop()104     protected void onStop() {
105         super.onStop();
106         if (!isFinishing() && !isChangingConfigurations()) {
107             cancel();
108         }
109     }
110 
getCallingAppName()111     private CharSequence getCallingAppName() {
112         try {
113             final PackageManager packageManager = getPackageManager();
114             String callingPackage = Preconditions.checkStringNotEmpty(
115                     getCallingPackage(),
116                     "This activity must be called for result");
117             return packageManager.getApplicationLabel(
118                     packageManager.getApplicationInfo(callingPackage, 0));
119         } catch (PackageManager.NameNotFoundException e) {
120             throw new RuntimeException(e);
121         }
122     }
123 
124     @Override
getCallingPackage()125     public String getCallingPackage() {
126         return requireNonNull(getService().mRequest.getCallingPackage());
127     }
128 
129     @Override
setTitle(CharSequence title)130     public void setTitle(CharSequence title) {
131         final TextView titleView = findViewById(R.id.title);
132         final int padding = getPadding(getResources());
133         titleView.setPadding(padding, padding, padding, padding);
134         titleView.setText(title);
135     }
136 
137     //TODO put in resources xmls
getProgressBar()138     private ProgressBar getProgressBar() {
139         final ProgressBar progressBar = new ProgressBar(this);
140         progressBar.setForegroundGravity(Gravity.CENTER_HORIZONTAL);
141         final int padding = getPadding(getResources());
142         progressBar.setPadding(padding, padding, padding, padding);
143         return progressBar;
144     }
145 
getPadding(Resources r)146     static int getPadding(Resources r) {
147         return r.getDimensionPixelSize(R.dimen.padding);
148     }
149 
onSelectionUpdate()150     private void onSelectionUpdate() {
151         DeviceFilterPair selectedDevice = getService().mSelectedDevice;
152         if (mPairButton.getVisibility() != View.VISIBLE && selectedDevice != null) {
153             onDeviceConfirmed(selectedDevice);
154         } else {
155             mPairButton.setEnabled(selectedDevice != null);
156         }
157     }
158 
getService()159     private DeviceDiscoveryService getService() {
160         return DeviceDiscoveryService.sInstance;
161     }
162 
onDeviceConfirmed(DeviceFilterPair selectedDevice)163    protected void onDeviceConfirmed(DeviceFilterPair selectedDevice) {
164         getService().onDeviceSelected(
165                 getCallingPackage(), getDeviceMacAddress(selectedDevice.device));
166         setResult(RESULT_OK,
167                 new Intent().putExtra(CompanionDeviceManager.EXTRA_DEVICE, selectedDevice.device));
168         finish();
169     }
170 }