Merge "CDM device profiles UI"

This commit is contained in:
TreeHugger Robot
2020-11-21 00:54:10 +00:00
committed by Android (Google) Code Review
8 changed files with 106 additions and 15 deletions

View File

@@ -29,14 +29,15 @@
android:id="@+id/button_cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@android:string/cancel"
android:text="@string/consent_no"
android:textColor="?android:attr/textColorSecondary"
style="@android:style/Widget.Material.Button.Borderless.Colored"
/>
<Button
android:id="@+id/button_pair"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@android:string/ok"
android:text="@string/consent_yes"
style="@android:style/Widget.Material.Button.Borderless.Colored"
/>
</LinearLayout>

View File

@@ -23,11 +23,13 @@
<include layout="@layout/title" />
<include layout="@layout/profile_summary" />
<ListView
android:id="@+id/device_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/title"
android:layout_below="@+id/profile_summary"
android:layout_above="@+id/buttons"
style="@android:style/Widget.Material.ListView"
/>

View File

@@ -23,6 +23,8 @@
<include layout="@layout/title" />
<include layout="@layout/profile_summary" />
<include layout="@layout/buttons" />
</LinearLayout>

View File

@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2020 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/profile_summary"
android:layout_below="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:textColor="?android:attr/textColorSecondary"
android:textSize="14sp"
android:gravity="center"
/>

View File

@@ -20,5 +20,6 @@
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
style="@*android:style/TextAppearance.Widget.Toolbar.Title"
/>

View File

@@ -20,9 +20,21 @@
<string name="app_label">Companion Device Manager</string>
<!-- Title of the device selection dialog. -->
<string name="chooser_title">Link with &lt;strong&gt;<xliff:g id="app_name" example="Android Wear">%1$s</xliff:g>&lt;/strong&gt;</string>
<string name="chooser_title">Choose a <xliff:g id="profile_name" example="watch">%1$s</xliff:g> to be managed by &lt;strong&gt;<xliff:g id="app_name" example="Android Wear">%2$s</xliff:g>&lt;/strong&gt;</string>
<!-- Title of the device pairing confirmation dialog. -->
<string name="confirmation_title">Link &lt;strong&gt;<xliff:g id="app_name" example="Android Wear">%1$s</xliff:g>&lt;/strong&gt; with &lt;strong&gt;<xliff:g id="device_name" example="ASUS ZenWatch 2">%2$s</xliff:g>&lt;/strong&gt;</string>
<!-- The generic placeholder for a device type when nothing specific is known about it [CHAR LIMIT=30] -->
<string name="profile_name_generic">device</string>
<!-- Title of the device association confirmation dialog. -->
<string name="confirmation_title">Set &lt;strong&gt;<xliff:g id="app_name" example="Android Wear">%1$s</xliff:g>&lt;/strong&gt; to manage your <xliff:g id="profile_name" example="watch">%2$s</xliff:g> - &lt;strong&gt;<xliff:g id="device_name" example="ASUS ZenWatch 2">%3$s</xliff:g>&lt;/strong&gt;</string>
<!-- Text of the device profile permissions explanation in the association dialog. -->
<string name="profile_summary"><xliff:g id="app_name" example="Android Wear">%1$s</xliff:g> is needed to manage your <xliff:g id="profile_name" example="watch">%2$s</xliff:g>. <xliff:g id="app_name2" example="Android Wear">%3$s</xliff:g> will get access to <xliff:g id="permissions" example="Notifications, Calendar and Phone">%4$s</xliff:g> while the <xliff:g id="profile_name2" example="watch">%5$s</xliff:g> is connected.</string>
<!-- Positive button for the device-app association consent dialog [CHAR LIMIT=30] -->
<string name="consent_yes">Yes</string>
<!-- Negative button for the device-app association consent dialog [CHAR LIMIT=30] -->
<string name="consent_no">No thanks</string>
</resources>

View File

@@ -17,11 +17,13 @@
package com.android.companiondevicemanager;
import static android.companion.BluetoothDeviceFilterUtils.getDeviceMacAddress;
import static android.text.TextUtils.withoutPrefix;
import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
import static java.util.Objects.requireNonNull;
import android.app.Activity;
import android.companion.AssociationRequest;
import android.companion.CompanionDeviceManager;
import android.content.Intent;
import android.content.pm.PackageManager;
@@ -62,12 +64,19 @@ public class DeviceChooserActivity extends Activity {
getWindow().addSystemFlags(SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
if (getService().mRequest.isSingleDevice()) {
String deviceProfile = getRequest().getDeviceProfile();
String profileName = deviceProfile == null
? getString(R.string.profile_name_generic)
//TODO introduce PermissionController APIs to resolve UI values
: withoutPrefix("android.app.role.COMPANION_DEVICE_", deviceProfile).toLowerCase();
if (getRequest().isSingleDevice()) {
setContentView(R.layout.device_confirmation);
final DeviceFilterPair selectedDevice = getService().mDevicesFound.get(0);
setTitle(Html.fromHtml(getString(
R.string.confirmation_title,
getCallingAppName(),
profileName,
selectedDevice.getDisplayName()), 0));
mPairButton = findViewById(R.id.button_pair);
mPairButton.setOnClickListener(v -> onDeviceConfirmed(getService().mSelectedDevice));
@@ -77,7 +86,9 @@ public class DeviceChooserActivity extends Activity {
setContentView(R.layout.device_chooser);
mPairButton = findViewById(R.id.button_pair);
mPairButton.setVisibility(View.GONE);
setTitle(Html.fromHtml(getString(R.string.chooser_title, getCallingAppName()), 0));
setTitle(Html.fromHtml(getString(R.string.chooser_title,
profileName,
getCallingAppName()), 0));
mDeviceListView = findViewById(R.id.device_list);
final DeviceDiscoveryService.DevicesAdapter adapter = getService().mDevicesAdapter;
mDeviceListView.setAdapter(adapter);
@@ -97,12 +108,33 @@ public class DeviceChooserActivity extends Activity {
});
mDeviceListView.addFooterView(mLoadingIndicator = getProgressBar(), null, false);
}
TextView profileSummary = findViewById(R.id.profile_summary);
if (deviceProfile != null) {
//TODO introduce PermissionController APIs to resolve UI values
String privileges = "Notifications, Phone, Contacts and Calendar";
profileSummary.setVisibility(View.VISIBLE);
profileSummary.setText(getString(R.string.profile_summary,
getCallingAppName(),
profileName,
getCallingAppName(),
privileges,
profileName));
} else {
profileSummary.setVisibility(View.GONE);
}
getService().mActivity = this;
mCancelButton = findViewById(R.id.button_cancel);
mCancelButton.setOnClickListener(v -> cancel());
}
private AssociationRequest getRequest() {
return getService().mRequest;
}
private void cancel() {
getService().onCancel();
setResult(RESULT_CANCELED);
@@ -132,7 +164,7 @@ public class DeviceChooserActivity extends Activity {
@Override
public String getCallingPackage() {
return requireNonNull(getService().mRequest.getCallingPackage());
return requireNonNull(getRequest().getCallingPackage());
}
@Override

View File

@@ -64,7 +64,7 @@ import android.util.SparseArray;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.TextView;
import com.android.internal.infra.AndroidFuture;
@@ -329,7 +329,7 @@ public class DeviceDiscoveryService extends Service {
mServiceCallback.cancel(true);
}
class DevicesAdapter extends ArrayAdapter<DeviceFilterPair> {
class DevicesAdapter extends BaseAdapter {
private Drawable BLUETOOTH_ICON = icon(android.R.drawable.stat_sys_data_bluetooth);
private Drawable WIFI_ICON = icon(com.android.internal.R.drawable.ic_wifi_signal_3);
@@ -341,10 +341,6 @@ public class DeviceDiscoveryService extends Service {
return icon;
}
public DevicesAdapter() {
super(DeviceDiscoveryService.this, 0, mDevicesFound);
}
@Override
public View getView(
int position,
@@ -391,6 +387,21 @@ public class DeviceDiscoveryService extends Service {
mColors.put(colorAttr, result);
return result;
}
@Override
public int getCount() {
return mDevicesFound.size();
}
@Override
public DeviceFilterPair getItem(int position) {
return mDevicesFound.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
}
/**