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