diff --git a/packages/CompanionDeviceManager/Android.bp b/packages/CompanionDeviceManager/Android.bp index 9f5bfd40e7e35..f6458c26f3094 100644 --- a/packages/CompanionDeviceManager/Android.bp +++ b/packages/CompanionDeviceManager/Android.bp @@ -41,6 +41,7 @@ android_app { "androidx.lifecycle_lifecycle-livedata", "androidx.lifecycle_lifecycle-extensions", "androidx.recyclerview_recyclerview", + "androidx-constraintlayout_constraintlayout", "androidx.appcompat_appcompat", ], diff --git a/packages/CompanionDeviceManager/res/drawable-night/ic_apps.xml b/packages/CompanionDeviceManager/res/drawable-night/ic_permission_app_streaming.xml similarity index 100% rename from packages/CompanionDeviceManager/res/drawable-night/ic_apps.xml rename to packages/CompanionDeviceManager/res/drawable-night/ic_permission_app_streaming.xml diff --git a/packages/CompanionDeviceManager/res/drawable-night/ic_permission_calendar.xml b/packages/CompanionDeviceManager/res/drawable-night/ic_permission_calendar.xml new file mode 100644 index 0000000000000..d7ea3a21fb000 --- /dev/null +++ b/packages/CompanionDeviceManager/res/drawable-night/ic_permission_calendar.xml @@ -0,0 +1,25 @@ + + + + + \ No newline at end of file diff --git a/packages/CompanionDeviceManager/res/drawable-night/ic_permission_contacts.xml b/packages/CompanionDeviceManager/res/drawable-night/ic_permission_contacts.xml new file mode 100644 index 0000000000000..41e404468b154 --- /dev/null +++ b/packages/CompanionDeviceManager/res/drawable-night/ic_permission_contacts.xml @@ -0,0 +1,25 @@ + + + + + \ No newline at end of file diff --git a/packages/CompanionDeviceManager/res/drawable-night/ic_permission_nearby_devices.xml b/packages/CompanionDeviceManager/res/drawable-night/ic_permission_nearby_devices.xml new file mode 100644 index 0000000000000..161186155340b --- /dev/null +++ b/packages/CompanionDeviceManager/res/drawable-night/ic_permission_nearby_devices.xml @@ -0,0 +1,25 @@ + + + + + \ No newline at end of file diff --git a/packages/CompanionDeviceManager/res/drawable-night/ic_notifications.xml b/packages/CompanionDeviceManager/res/drawable-night/ic_permission_notifications.xml similarity index 100% rename from packages/CompanionDeviceManager/res/drawable-night/ic_notifications.xml rename to packages/CompanionDeviceManager/res/drawable-night/ic_permission_notifications.xml diff --git a/packages/CompanionDeviceManager/res/drawable-night/ic_permission_phone.xml b/packages/CompanionDeviceManager/res/drawable-night/ic_permission_phone.xml new file mode 100644 index 0000000000000..49467edc7b269 --- /dev/null +++ b/packages/CompanionDeviceManager/res/drawable-night/ic_permission_phone.xml @@ -0,0 +1,25 @@ + + + + + \ No newline at end of file diff --git a/packages/CompanionDeviceManager/res/drawable-night/ic_permission_sms.xml b/packages/CompanionDeviceManager/res/drawable-night/ic_permission_sms.xml new file mode 100644 index 0000000000000..859c06fa63f58 --- /dev/null +++ b/packages/CompanionDeviceManager/res/drawable-night/ic_permission_sms.xml @@ -0,0 +1,25 @@ + + + + + \ No newline at end of file diff --git a/packages/CompanionDeviceManager/res/drawable-night/ic_storage.xml b/packages/CompanionDeviceManager/res/drawable-night/ic_permission_storage.xml similarity index 100% rename from packages/CompanionDeviceManager/res/drawable-night/ic_storage.xml rename to packages/CompanionDeviceManager/res/drawable-night/ic_permission_storage.xml diff --git a/packages/CompanionDeviceManager/res/drawable/btn_expand_less.xml b/packages/CompanionDeviceManager/res/drawable/btn_expand_less.xml new file mode 100644 index 0000000000000..99db560975ee3 --- /dev/null +++ b/packages/CompanionDeviceManager/res/drawable/btn_expand_less.xml @@ -0,0 +1,24 @@ + + + + + \ No newline at end of file diff --git a/packages/CompanionDeviceManager/res/drawable/btn_expand_more.xml b/packages/CompanionDeviceManager/res/drawable/btn_expand_more.xml new file mode 100644 index 0000000000000..8518cfa2377a6 --- /dev/null +++ b/packages/CompanionDeviceManager/res/drawable/btn_expand_more.xml @@ -0,0 +1,24 @@ + + + + + \ No newline at end of file diff --git a/packages/CompanionDeviceManager/res/drawable/ic_device_other.xml b/packages/CompanionDeviceManager/res/drawable/ic_device_other.xml index 2a8eb24bcf1f9..15f6987bb5514 100644 --- a/packages/CompanionDeviceManager/res/drawable/ic_device_other.xml +++ b/packages/CompanionDeviceManager/res/drawable/ic_device_other.xml @@ -15,7 +15,8 @@ ~ limitations under the License. --> diff --git a/packages/CompanionDeviceManager/res/drawable/ic_apps.xml b/packages/CompanionDeviceManager/res/drawable/ic_permission_app_streaming.xml similarity index 100% rename from packages/CompanionDeviceManager/res/drawable/ic_apps.xml rename to packages/CompanionDeviceManager/res/drawable/ic_permission_app_streaming.xml diff --git a/packages/CompanionDeviceManager/res/drawable/ic_permission_calendar.xml b/packages/CompanionDeviceManager/res/drawable/ic_permission_calendar.xml new file mode 100644 index 0000000000000..3dc53e7df8cd7 --- /dev/null +++ b/packages/CompanionDeviceManager/res/drawable/ic_permission_calendar.xml @@ -0,0 +1,24 @@ + + + + + \ No newline at end of file diff --git a/packages/CompanionDeviceManager/res/drawable/ic_permission_contacts.xml b/packages/CompanionDeviceManager/res/drawable/ic_permission_contacts.xml new file mode 100644 index 0000000000000..2dfda8d4cc95c --- /dev/null +++ b/packages/CompanionDeviceManager/res/drawable/ic_permission_contacts.xml @@ -0,0 +1,25 @@ + + + + + \ No newline at end of file diff --git a/packages/CompanionDeviceManager/res/drawable/ic_permission_nearby_devices.xml b/packages/CompanionDeviceManager/res/drawable/ic_permission_nearby_devices.xml new file mode 100644 index 0000000000000..49a6fe37d6d76 --- /dev/null +++ b/packages/CompanionDeviceManager/res/drawable/ic_permission_nearby_devices.xml @@ -0,0 +1,25 @@ + + + + + \ No newline at end of file diff --git a/packages/CompanionDeviceManager/res/drawable/ic_notifications.xml b/packages/CompanionDeviceManager/res/drawable/ic_permission_notifications.xml similarity index 100% rename from packages/CompanionDeviceManager/res/drawable/ic_notifications.xml rename to packages/CompanionDeviceManager/res/drawable/ic_permission_notifications.xml diff --git a/packages/CompanionDeviceManager/res/drawable/ic_permission_phone.xml b/packages/CompanionDeviceManager/res/drawable/ic_permission_phone.xml new file mode 100644 index 0000000000000..cc1c5b56c4470 --- /dev/null +++ b/packages/CompanionDeviceManager/res/drawable/ic_permission_phone.xml @@ -0,0 +1,24 @@ + + + + + \ No newline at end of file diff --git a/packages/CompanionDeviceManager/res/drawable/ic_permission_sms.xml b/packages/CompanionDeviceManager/res/drawable/ic_permission_sms.xml new file mode 100644 index 0000000000000..7f76a60000dee --- /dev/null +++ b/packages/CompanionDeviceManager/res/drawable/ic_permission_sms.xml @@ -0,0 +1,25 @@ + + + + + \ No newline at end of file diff --git a/packages/CompanionDeviceManager/res/drawable/ic_storage.xml b/packages/CompanionDeviceManager/res/drawable/ic_permission_storage.xml similarity index 100% rename from packages/CompanionDeviceManager/res/drawable/ic_storage.xml rename to packages/CompanionDeviceManager/res/drawable/ic_permission_storage.xml diff --git a/packages/CompanionDeviceManager/res/drawable/ic_permission_watch.xml b/packages/CompanionDeviceManager/res/drawable/ic_permission_watch.xml new file mode 100644 index 0000000000000..dd247ee3b7f35 --- /dev/null +++ b/packages/CompanionDeviceManager/res/drawable/ic_permission_watch.xml @@ -0,0 +1,25 @@ + + + + + + \ No newline at end of file diff --git a/packages/CompanionDeviceManager/res/layout/activity_confirmation.xml b/packages/CompanionDeviceManager/res/layout/activity_confirmation.xml index 520ade892f513..22805f62c4496 100644 --- a/packages/CompanionDeviceManager/res/layout/activity_confirmation.xml +++ b/packages/CompanionDeviceManager/res/layout/activity_confirmation.xml @@ -57,36 +57,39 @@ android:layout_height="0dp" android:layout_weight="1"> - + + + + - - - - - + diff --git a/packages/CompanionDeviceManager/res/layout/helper_confirmation.xml b/packages/CompanionDeviceManager/res/layout/helper_confirmation.xml index 1f922b97bfc44..ddff2cb6ab139 100644 --- a/packages/CompanionDeviceManager/res/layout/helper_confirmation.xml +++ b/packages/CompanionDeviceManager/res/layout/helper_confirmation.xml @@ -46,6 +46,7 @@ android:layout_height="wrap_content" android:gravity="center" android:textColor="?android:attr/textColorPrimary" + style="@style/TextAppearance" android:textSize="22sp" /> diff --git a/packages/CompanionDeviceManager/res/layout/list_item_device.xml b/packages/CompanionDeviceManager/res/layout/list_item_device.xml index d4439f9e7e643..ac5294ad373aa 100644 --- a/packages/CompanionDeviceManager/res/layout/list_item_device.xml +++ b/packages/CompanionDeviceManager/res/layout/list_item_device.xml @@ -39,6 +39,6 @@ android:layout_height="wrap_content" android:paddingStart="24dp" android:paddingEnd="24dp" - android:textAppearance="?android:attr/textAppearanceListItemSmall"/> + style="@style/TextAppearance"/> diff --git a/packages/CompanionDeviceManager/res/layout/list_item_permission.xml b/packages/CompanionDeviceManager/res/layout/list_item_permission.xml index a3d71b953be09..ab2d815063eb9 100644 --- a/packages/CompanionDeviceManager/res/layout/list_item_permission.xml +++ b/packages/CompanionDeviceManager/res/layout/list_item_permission.xml @@ -34,26 +34,43 @@ android:contentDescription="@null"/> + android:padding="6dp" + android:layout_weight="1"> + android:layout_marginTop="2dp" + style="@style/TextAppearance" + android:textColor="?android:attr/textColorPrimary"/> + + \ No newline at end of file diff --git a/packages/CompanionDeviceManager/res/values/strings.xml b/packages/CompanionDeviceManager/res/values/strings.xml index 83dbbf32377bc..97201e2034633 100644 --- a/packages/CompanionDeviceManager/res/values/strings.xml +++ b/packages/CompanionDeviceManager/res/values/strings.xml @@ -31,16 +31,13 @@ Choose a %1$s to be managed by <strong>%2$s</strong> - This app is needed to manage your %1$s. %2$s will be allowed to interact with your notifications and access your Phone, SMS, Contacts, Calendar, Call logs and Nearby devices permissions. + The app is needed to manage your %1$s. %2$s will be allowed to interact with your notifications and access your Phone, SMS, Contacts, Calendar, Call logs and Nearby devices permissions. + + + The app is needed to manage your %1$s. %2$s will be allowed to interact with these permissions: - - Apps - - - Stream your phone\u2019s apps - Allow <strong>%1$s</strong> to access this information from your phone @@ -66,18 +63,6 @@ - - Notifications - - - Can read all notifications, including information like contacts, messages, and photos - - - Photos and media - - - - Google Play services @@ -117,4 +102,57 @@ More Information Button + + + + Phone + + + SMS + + + Contacts + + + Calendar + + + Nearby devices + + + Photos and media + + + Notifications + + + Apps + + + Can access your phone number and network info. Required for making calls and VoIP, voicemail, call redirect, and editing call logs + + + + + + + Can read, create, or edit our contact list, as well as access the list of all accounts used on your device + + + + + + + + + + + Can read all notifications, including information like contacts, messages, and photos + + + Stream your phone\u2019s apps + + + + diff --git a/packages/CompanionDeviceManager/res/values/styles.xml b/packages/CompanionDeviceManager/res/values/styles.xml index 2000d9675ca46..3c75cd5b86683 100644 --- a/packages/CompanionDeviceManager/res/values/styles.xml +++ b/packages/CompanionDeviceManager/res/values/styles.xml @@ -36,7 +36,7 @@ - @@ -73,6 +75,7 @@ false 14sp @android:color/system_neutral1_900 + @android:style/TextAppearance.DeviceDefault.Medium @drawable/btn_positive_bottom @@ -85,6 +88,7 @@ 14sp @android:color/system_neutral1_900 4dp + @android:style/TextAppearance.DeviceDefault.Medium @drawable/btn_negative_top @@ -93,13 +97,17 @@ 100dp 36dp false + 14sp + @android:style/TextAppearance.DeviceDefault.Medium @drawable/btn_negative_multiple_devices + + + \ No newline at end of file diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceActivity.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceActivity.java index a7e1a5954aea3..0493444d9b6d6 100644 --- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceActivity.java +++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceActivity.java @@ -30,9 +30,14 @@ import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTE import static com.android.companiondevicemanager.CompanionDeviceDiscoveryService.DiscoveryState; import static com.android.companiondevicemanager.CompanionDeviceDiscoveryService.DiscoveryState.FINISHED_TIMEOUT; -import static com.android.companiondevicemanager.PermissionListAdapter.TYPE_APPS; -import static com.android.companiondevicemanager.PermissionListAdapter.TYPE_NOTIFICATION; -import static com.android.companiondevicemanager.PermissionListAdapter.TYPE_STORAGE; +import static com.android.companiondevicemanager.PermissionListAdapter.PERMISSION_APP_STREAMING; +import static com.android.companiondevicemanager.PermissionListAdapter.PERMISSION_CALENDAR; +import static com.android.companiondevicemanager.PermissionListAdapter.PERMISSION_CONTACTS; +import static com.android.companiondevicemanager.PermissionListAdapter.PERMISSION_NEARBY_DEVICES; +import static com.android.companiondevicemanager.PermissionListAdapter.PERMISSION_NOTIFICATION; +import static com.android.companiondevicemanager.PermissionListAdapter.PERMISSION_PHONE; +import static com.android.companiondevicemanager.PermissionListAdapter.PERMISSION_SMS; +import static com.android.companiondevicemanager.PermissionListAdapter.PERMISSION_STORAGE; import static com.android.companiondevicemanager.Utils.getApplicationLabel; import static com.android.companiondevicemanager.Utils.getHtmlFromResources; import static com.android.companiondevicemanager.Utils.getIcon; @@ -54,6 +59,9 @@ import android.companion.IAssociationRequestCallback; import android.content.Intent; import android.content.pm.PackageManager; import android.content.res.Configuration; +import android.graphics.BlendMode; +import android.graphics.BlendModeColorFilter; +import android.graphics.Color; import android.graphics.drawable.Drawable; import android.net.MacAddress; import android.os.Bundle; @@ -63,6 +71,7 @@ import android.os.ResultReceiver; import android.text.Spanned; import android.util.Log; import android.view.View; +import android.view.ViewTreeObserver; import android.widget.Button; import android.widget.ImageButton; import android.widget.ImageView; @@ -71,12 +80,14 @@ import android.widget.ProgressBar; import android.widget.RelativeLayout; import android.widget.TextView; +import androidx.constraintlayout.widget.ConstraintLayout; import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentManager; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; /** @@ -139,8 +150,14 @@ public class CompanionDeviceActivity extends FragmentActivity implements // Present for multiple devices' association requests only. private Button mButtonNotAllowMultipleDevices; + // Present for top and bottom borders for permissions list and device list. + private View mBorderTop; + private View mBorderBottom; + private LinearLayout mAssociationConfirmationDialog; - private LinearLayout mMultipleDeviceList; + // Contains device list, permission list and top/bottom borders. + private ConstraintLayout mConstraintList; + // Only present for self-managed association requests. private RelativeLayout mVendorHeader; // The recycler view is only shown for multiple-device regular association request, after @@ -149,7 +166,7 @@ public class CompanionDeviceActivity extends FragmentActivity implements private @Nullable DeviceListAdapter mDeviceAdapter; - // The recycler view is only shown for selfManaged association request. + // The recycler view is only shown for selfManaged and singleDevice association request. private @Nullable RecyclerView mPermissionListRecyclerView; private @Nullable PermissionListAdapter mPermissionListAdapter; @@ -163,6 +180,8 @@ public class CompanionDeviceActivity extends FragmentActivity implements private @Nullable List mPermissionTypes; + private LinearLayoutManager mPermissionsLayoutManager = new LinearLayoutManager(this); + @Override public void onCreate(Bundle savedInstanceState) { if (DEBUG) Log.d(TAG, "onCreate()"); @@ -210,7 +229,6 @@ public class CompanionDeviceActivity extends FragmentActivity implements boolean forCancelDialog = intent.getBooleanExtra(EXTRA_FORCE_CANCEL_CONFIRMATION, false); if (forCancelDialog) { - Log.i(TAG, "Cancelling the user confirmation"); cancel(false, false); @@ -281,10 +299,13 @@ public class CompanionDeviceActivity extends FragmentActivity implements setContentView(R.layout.activity_confirmation); - mMultipleDeviceList = findViewById(R.id.multiple_device_list); + mConstraintList = findViewById(R.id.constraint_list); mAssociationConfirmationDialog = findViewById(R.id.association_confirmation); mVendorHeader = findViewById(R.id.vendor_header); + mBorderTop = findViewById(R.id.border_top); + mBorderBottom = findViewById(R.id.border_bottom); + mTitle = findViewById(R.id.title); mSummary = findViewById(R.id.summary); @@ -452,10 +473,11 @@ public class CompanionDeviceActivity extends FragmentActivity implements return; } + // TODO(b/253644212): Add maps for profile -> title, summary, permissions switch (deviceProfile) { case DEVICE_PROFILE_APP_STREAMING: title = getHtmlFromResources(this, R.string.title_app_streaming, deviceName); - mPermissionTypes.add(TYPE_APPS); + mPermissionTypes.add(PERMISSION_APP_STREAMING); break; case DEVICE_PROFILE_AUTOMOTIVE_PROJECTION: @@ -465,25 +487,27 @@ public class CompanionDeviceActivity extends FragmentActivity implements case DEVICE_PROFILE_COMPUTER: title = getHtmlFromResources(this, R.string.title_computer, deviceName); - mPermissionTypes.add(TYPE_NOTIFICATION); - mPermissionTypes.add(TYPE_STORAGE); + mPermissionTypes.addAll(Arrays.asList(PERMISSION_NOTIFICATION, PERMISSION_STORAGE)); break; default: throw new RuntimeException("Unsupported profile " + deviceProfile); } + // Summary is not needed for selfManaged dialog. mSummary.setVisibility(View.GONE); - mPermissionListAdapter.setPermissionType(mPermissionTypes); - mPermissionListRecyclerView.setAdapter(mPermissionListAdapter); - mPermissionListRecyclerView.setLayoutManager(new LinearLayoutManager(this)); + setupPermissionList(); mTitle.setText(title); mVendorHeaderName.setText(vendorName); - mDeviceListRecyclerView.setVisibility(View.GONE); - mProfileIcon.setVisibility(View.GONE); mVendorHeader.setVisibility(View.VISIBLE); + mVendorHeader.setVisibility(View.VISIBLE); + mProfileIcon.setVisibility(View.GONE); + mDeviceListRecyclerView.setVisibility(View.GONE); + // Top and bottom borders should be gone for selfManaged dialog. + mBorderTop.setVisibility(View.GONE); + mBorderBottom.setVisibility(View.GONE); } private void initUiForSingleDevice(CharSequence appLabel) { @@ -491,11 +515,15 @@ public class CompanionDeviceActivity extends FragmentActivity implements final String deviceProfile = mRequest.getDeviceProfile(); + mPermissionTypes = new ArrayList<>(); + CompanionDeviceDiscoveryService.getScanResult().observe(this, deviceFilterPairs -> updateSingleDeviceUi( deviceFilterPairs, deviceProfile, appLabel)); mSingleDeviceSpinner.setVisibility(View.VISIBLE); + // Hide permission list and confirmation dialog first before the + // first matched device is found. mPermissionListRecyclerView.setVisibility(View.GONE); mDeviceListRecyclerView.setVisibility(View.GONE); mAssociationConfirmationDialog.setVisibility(View.GONE); @@ -526,11 +554,20 @@ public class CompanionDeviceActivity extends FragmentActivity implements title = getHtmlFromResources(this, R.string.confirmation_title, appLabel, deviceName); summary = getHtmlFromResources(this, R.string.summary_generic); profileIcon = getIcon(this, R.drawable.ic_device_other); + // Summary is not needed for null profile. mSummary.setVisibility(View.GONE); + mConstraintList.setVisibility(View.GONE); } else if (deviceProfile.equals(DEVICE_PROFILE_WATCH)) { - title = getHtmlFromResources(this, R.string.confirmation_title, appLabel, profileName); - summary = getHtmlFromResources(this, R.string.summary_watch, deviceName, appLabel); + title = getHtmlFromResources(this, R.string.confirmation_title, appLabel, deviceName); + summary = getHtmlFromResources( + this, R.string.summary_watch_single_device, profileName, appLabel); profileIcon = getIcon(this, R.drawable.ic_watch); + + mPermissionTypes.addAll(Arrays.asList( + PERMISSION_NOTIFICATION, PERMISSION_PHONE, PERMISSION_SMS, PERMISSION_CONTACTS, + PERMISSION_CALENDAR, PERMISSION_NEARBY_DEVICES)); + + setupPermissionList(); } else { throw new RuntimeException("Unsupported profile " + deviceProfile); } @@ -585,8 +622,9 @@ public class CompanionDeviceActivity extends FragmentActivity implements // "Remove" consent button: users would need to click on the list item. mButtonAllow.setVisibility(View.GONE); mButtonNotAllow.setVisibility(View.GONE); + mDeviceListRecyclerView.setVisibility(View.VISIBLE); mButtonNotAllowMultipleDevices.setVisibility(View.VISIBLE); - mMultipleDeviceList.setVisibility(View.VISIBLE); + mConstraintList.setVisibility(View.VISIBLE); mMultipleDeviceSpinner.setVisibility(View.VISIBLE); } @@ -643,6 +681,80 @@ public class CompanionDeviceActivity extends FragmentActivity implements return mApproved || mCancelled; } + // Set up the mPermissionListRecyclerView, including set up the adapter, + // initiate the layoutManager for the recyclerview, add listeners for monitoring the scrolling + // and when mPermissionListRecyclerView is fully populated. + // Lastly, disable the Allow and Don't allow buttons. + private void setupPermissionList() { + mPermissionListAdapter.setPermissionType(mPermissionTypes); + mPermissionListRecyclerView.setAdapter(mPermissionListAdapter); + mPermissionListRecyclerView.setLayoutManager(mPermissionsLayoutManager); + + disableButtons(); + + // Enable buttons once users scroll down to the bottom of the permission list. + mPermissionListRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { + @Override + public void onScrollStateChanged(RecyclerView recyclerView, int newState) { + super.onScrollStateChanged(recyclerView, newState); + if (!recyclerView.canScrollVertically(1)) { + enableButtons(); + } + } + }); + // Enable buttons if last item in the permission list is visible to the users when + // mPermissionListRecyclerView is fully populated. + mPermissionListRecyclerView.getViewTreeObserver().addOnGlobalLayoutListener( + new ViewTreeObserver.OnGlobalLayoutListener() { + @Override + public void onGlobalLayout() { + LinearLayoutManager layoutManager = + (LinearLayoutManager) mPermissionListRecyclerView + .getLayoutManager(); + int lastVisibleItemPosition = + layoutManager.findLastCompletelyVisibleItemPosition(); + int numItems = mPermissionListRecyclerView.getAdapter().getItemCount(); + + if (lastVisibleItemPosition >= numItems - 1) { + enableButtons(); + } + + mPermissionListRecyclerView.getViewTreeObserver() + .removeOnGlobalLayoutListener(this); + } + }); + + mConstraintList.setVisibility(View.VISIBLE); + mPermissionListRecyclerView.setVisibility(View.VISIBLE); + } + + // Disable and grey out the Allow and Don't allow buttons if the last permission in the + // permission list is not visible to the users. + private void disableButtons() { + mButtonAllow.setEnabled(false); + mButtonNotAllow.setEnabled(false); + mButtonAllow.setTextColor( + getResources().getColor(android.R.color.system_neutral1_400, null)); + mButtonNotAllow.setTextColor( + getResources().getColor(android.R.color.system_neutral1_400, null)); + mButtonAllow.getBackground().setColorFilter( + (new BlendModeColorFilter(Color.LTGRAY, BlendMode.DARKEN))); + mButtonNotAllow.getBackground().setColorFilter( + (new BlendModeColorFilter(Color.LTGRAY, BlendMode.DARKEN))); + } + // Enable and restore the color for the Allow and Don't allow buttons if the last permission in + // the permission list is visible to the users. + private void enableButtons() { + mButtonAllow.setEnabled(true); + mButtonNotAllow.setEnabled(true); + mButtonAllow.getBackground().setColorFilter(null); + mButtonNotAllow.getBackground().setColorFilter(null); + mButtonAllow.setTextColor( + getResources().getColor(android.R.color.system_neutral1_900, null)); + mButtonNotAllow.setTextColor( + getResources().getColor(android.R.color.system_neutral1_900, null)); + } + private final ResultReceiver mOnAssociationCreatedReceiver = new ResultReceiver(Handler.getMain()) { @Override diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/PermissionListAdapter.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/PermissionListAdapter.java index 895b729ea8c7f..0ee94a2c39218 100644 --- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/PermissionListAdapter.java +++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/PermissionListAdapter.java @@ -27,6 +27,7 @@ import android.util.ArrayMap; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.ImageButton; import android.widget.ImageView; import android.widget.TextView; @@ -37,37 +38,58 @@ import java.util.Map; class PermissionListAdapter extends RecyclerView.Adapter { private final Context mContext; - private List mPermissions; + // Add the expand buttons if permissions are more than PERMISSION_SIZE in the permission list. + private static final int PERMISSION_SIZE = 2; - static final int TYPE_NOTIFICATION = 0; - static final int TYPE_STORAGE = 1; - static final int TYPE_APPS = 2; + static final int PERMISSION_NOTIFICATION = 0; + static final int PERMISSION_STORAGE = 1; + static final int PERMISSION_APP_STREAMING = 2; + static final int PERMISSION_PHONE = 3; + static final int PERMISSION_SMS = 4; + static final int PERMISSION_CONTACTS = 5; + static final int PERMISSION_CALENDAR = 6; + static final int PERMISSION_NEARBY_DEVICES = 7; private static final Map sTitleMap; static { final Map map = new ArrayMap<>(); - map.put(TYPE_NOTIFICATION, R.string.permission_notification); - map.put(TYPE_STORAGE, R.string.permission_storage); - map.put(TYPE_APPS, R.string.permission_apps); + map.put(PERMISSION_NOTIFICATION, R.string.permission_notification); + map.put(PERMISSION_STORAGE, R.string.permission_storage); + map.put(PERMISSION_APP_STREAMING, R.string.permission_app_streaming); + map.put(PERMISSION_PHONE, R.string.permission_phone); + map.put(PERMISSION_SMS, R.string.permission_sms); + map.put(PERMISSION_CONTACTS, R.string.permission_contacts); + map.put(PERMISSION_CALENDAR, R.string.permission_calendar); + map.put(PERMISSION_NEARBY_DEVICES, R.string.permission_nearby_devices); sTitleMap = unmodifiableMap(map); } private static final Map sSummaryMap; static { final Map map = new ArrayMap<>(); - map.put(TYPE_NOTIFICATION, R.string.permission_notification_summary); - map.put(TYPE_STORAGE, R.string.permission_storage_summary); - map.put(TYPE_APPS, R.string.permission_apps_summary); + map.put(PERMISSION_NOTIFICATION, R.string.permission_notification_summary); + map.put(PERMISSION_STORAGE, R.string.permission_storage_summary); + map.put(PERMISSION_APP_STREAMING, R.string.permission_app_streaming_summary); + map.put(PERMISSION_PHONE, R.string.permission_phone_summary); + map.put(PERMISSION_SMS, R.string.permission_sms_summary); + map.put(PERMISSION_CONTACTS, R.string.permission_contacts_summary); + map.put(PERMISSION_CALENDAR, R.string.permission_calendar_summary); + map.put(PERMISSION_NEARBY_DEVICES, R.string.permission_nearby_devices_summary); sSummaryMap = unmodifiableMap(map); } private static final Map sIconMap; static { final Map map = new ArrayMap<>(); - map.put(TYPE_NOTIFICATION, R.drawable.ic_notifications); - map.put(TYPE_STORAGE, R.drawable.ic_storage); - map.put(TYPE_APPS, R.drawable.ic_apps); + map.put(PERMISSION_NOTIFICATION, R.drawable.ic_permission_notifications); + map.put(PERMISSION_STORAGE, R.drawable.ic_permission_storage); + map.put(PERMISSION_APP_STREAMING, R.drawable.ic_permission_app_streaming); + map.put(PERMISSION_PHONE, R.drawable.ic_permission_phone); + map.put(PERMISSION_SMS, R.drawable.ic_permission_sms); + map.put(PERMISSION_CONTACTS, R.drawable.ic_permission_contacts); + map.put(PERMISSION_CALENDAR, R.drawable.ic_permission_calendar); + map.put(PERMISSION_NEARBY_DEVICES, R.drawable.ic_permission_nearby_devices); sIconMap = unmodifiableMap(map); } @@ -82,6 +104,29 @@ class PermissionListAdapter extends RecyclerView.Adapter PERMISSION_SIZE) { + view.setOnClickListener(v -> { + if ((Integer) viewHolder.mExpandButton.getTag() == R.drawable.btn_expand_more) { + viewHolder.mExpandButton.setImageResource(R.drawable.btn_expand_less); + + if (viewHolder.mSummary != null) { + viewHolder.mPermissionSummary.setText(viewHolder.mSummary); + } + + viewHolder.mPermissionSummary.setVisibility(View.VISIBLE); + viewHolder.mExpandButton.setTag(R.drawable.btn_expand_less); + } else { + viewHolder.mExpandButton.setImageResource(R.drawable.btn_expand_more); + viewHolder.mPermissionSummary.setVisibility(View.GONE); + viewHolder.mExpandButton.setTag(R.drawable.btn_expand_more); + } + }); + } + return viewHolder; } @@ -91,8 +136,15 @@ class PermissionListAdapter extends RecyclerView.Adapter