Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c83a8015 authored by Hai Zhang's avatar Hai Zhang
Browse files

Fix request role dialog buttons missing with too many items.

The "don't ask again" check box was added as a custom view to the
alert dialog, and because we were using the list view in content panel
at the same time, AlertDialogLayout refuses to handle layout with its
special logic when both panels are used, and causes list view to take
up all the space with no space left for button bar. This can happen
for any device in landscape mode if there are a lot of candidate apps.

This CL uses a custom list view inside the custom view added to the
alert dialog, so that AlertController will hide the content
panel. This way AlertDialogLayout will only see the custom panel and
layout properly.

Fixes: 135549535
Test: manual && atest RoleManagerTest
Change-Id: I9e376279f10e8258f531ab27349c8cfb80d6f575
parent 1e4bc148
Loading
Loading
Loading
Loading
+6 −2
Original line number Diff line number Diff line
@@ -16,12 +16,16 @@
  ~ limitations under the License.
  -->

<FrameLayout
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    style="@style/RequestRoleView">

    <ListView
        android:id="@+id/list"
        style="@style/RequestRoleViewListView" />

    <CheckBox
        android:id="@+id/dont_ask_again"
        android:text="@string/request_role_dont_ask_again"
        style="@style/RequestRoleViewCheckbox" />
</FrameLayout>
</LinearLayout>
+1 −0
Original line number Diff line number Diff line
@@ -164,6 +164,7 @@

            <!-- START REQUEST ROLE DIALOG VIEW -->
            <item type="style" name="RequestRoleView" />
            <item type="style" name="RequestRoleViewListView" />
            <item type="style" name="RequestRoleViewCheckbox" />
            <!-- END REQUEST ROLE DIALOG VIEW -->

+15 −4
Original line number Diff line number Diff line
@@ -711,15 +711,26 @@
    <style name="RequestRoleView">
        <item name="android:layout_width">match_parent</item>
        <item name="android:layout_height">wrap_content</item>
        <item name="android:paddingStart">?android:dialogPreferredPadding</item>
        <item name="android:paddingEnd">?android:dialogPreferredPadding</item>
        <item name="android:clipChildren">false</item>
        <item name="android:clipToPadding">false</item>
        <!-- @android:dimen/dialog_title_divider_material -->
        <item name="android:paddingTop">8dp</item>
        <item name="android:orientation">vertical</item>
    </style>

    <style name="RequestRoleViewListView">
        <item name="android:layout_width">match_parent</item>
        <item name="android:layout_height">0dp</item>
        <item name="android:layout_weight">1</item>
        <item name="android:cacheColorHint">@null</item>
        <item name="android:divider">?android:listDividerAlertDialog</item>
        <item name="android:overScrollMode">ifContentScrolls</item>
        <item name="android:scrollIndicators">top|bottom</item>
    </style>

    <style name="RequestRoleViewCheckbox">
        <item name="android:layout_width">match_parent</item>
        <item name="android:layout_height">wrap_content</item>
        <item name="android:layout_marginStart">?android:dialogPreferredPadding</item>
        <item name="android:layout_marginEnd">?android:dialogPreferredPadding</item>
        <item name="android:minHeight">?android:listPreferredItemHeightSmall</item>
        <item name="android:paddingStart">16dp</item>
        <item name="android:textAppearance">@style/android:TextAppearance.Material.Subhead</item>
+27 −25
Original line number Diff line number Diff line
@@ -76,7 +76,9 @@ public class RequestRoleFragment extends DialogFragment {

    private Role mRole;

    private ListView mListView;
    private Adapter mAdapter;
    @Nullable
    private CheckBox mDontAskAgainCheck;

    private RequestRoleViewModel mViewModel;
@@ -145,20 +147,27 @@ public class RequestRoleFragment extends DialogFragment {

        LayoutInflater inflater = LayoutInflater.from(context);
        View titleLayout = inflater.inflate(R.layout.request_role_title, null);
        ImageView iconImage = titleLayout.findViewById(R.id.icon);
        ImageView iconImage = titleLayout.requireViewById(R.id.icon);
        iconImage.setImageDrawable(icon);
        TextView titleText = titleLayout.findViewById(R.id.title);
        TextView titleText = titleLayout.requireViewById(R.id.title);
        titleText.setText(title);

        mAdapter = new Adapter(mRole);
        View viewLayout = inflater.inflate(R.layout.request_role_view, null);
        mListView = viewLayout.requireViewById(R.id.list);
        mListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
        mListView.setOnItemClickListener((parent, view, position, id) -> onItemClicked(position));
        mAdapter = new Adapter(mListView, mRole);
        if (savedInstanceState != null) {
            mAdapter.onRestoreInstanceState(savedInstanceState);
        }
        mListView.setAdapter(mAdapter);

        View viewLayout = null;
        if (UserDeniedManager.getInstance(context).isDeniedOnce(mRoleName, mPackageName)) {
            viewLayout = inflater.inflate(R.layout.request_role_view, null);
            mDontAskAgainCheck = viewLayout.findViewById(R.id.dont_ask_again);
        CheckBox dontAskAgainCheck = viewLayout.requireViewById(R.id.dont_ask_again);
        boolean isDeniedOnce = UserDeniedManager.getInstance(context).isDeniedOnce(mRoleName,
                mPackageName);
        dontAskAgainCheck.setVisibility(isDeniedOnce ? View.VISIBLE : View.GONE);
        if (isDeniedOnce) {
            mDontAskAgainCheck = dontAskAgainCheck;
            mDontAskAgainCheck.setOnClickListener(view -> updateUi());
            if (savedInstanceState != null) {
                boolean dontAskAgain = savedInstanceState.getBoolean(STATE_DONT_ASK_AGAIN);
@@ -169,8 +178,6 @@ public class RequestRoleFragment extends DialogFragment {

        AlertDialog dialog = builder
                .setCustomTitle(titleLayout)
                .setSingleChoiceItems(mAdapter, AdapterView.INVALID_POSITION, (dialog2, which) ->
                        onItemClicked(which))
                .setView(viewLayout)
                // Set the positive button listener later to avoid the automatic dismiss behavior.
                .setPositiveButton(R.string.request_role_set_as_default, null)
@@ -216,8 +223,6 @@ public class RequestRoleFragment extends DialogFragment {
        };
        mPackageRemovalMonitor.register();

        mAdapter.setListView(getDialog().getListView());

        // Postponed to onStart() so that the list view in dialog is created.
        mViewModel = ViewModelProviders.of(this, new RequestRoleViewModel.Factory(mRole,
                requireActivity().getApplication())).get(RequestRoleViewModel.class);
@@ -333,12 +338,12 @@ public class RequestRoleFragment extends DialogFragment {
    }

    private void updateUi() {
        AlertDialog dialog = getDialog();
        boolean enabled = mViewModel.getManageRoleHolderStateLiveData().getValue()
                == ManageRoleHolderStateLiveData.STATE_IDLE;
        dialog.getListView().setEnabled(enabled);
        mListView.setEnabled(enabled);
        boolean dontAskAgain = mDontAskAgainCheck != null && mDontAskAgainCheck.isChecked();
        mAdapter.setDontAskAgain(dontAskAgain);
        AlertDialog dialog = getDialog();
        dialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(enabled && (dontAskAgain
                || !mAdapter.isHolderApplicationChecked()));
        dialog.getButton(AlertDialog.BUTTON_NEGATIVE).setEnabled(enabled);
@@ -464,6 +469,9 @@ public class RequestRoleFragment extends DialogFragment {

        private static final int LAYOUT_TRANSITION_DURATION_MILLIS = 150;

        @NonNull
        private final ListView mListView;

        @NonNull
        private final Role mRole;

@@ -474,8 +482,6 @@ public class RequestRoleFragment extends DialogFragment {

        private boolean mHasHolderApplication;

        private ListView mListView;

        private boolean mDontAskAgain;

        // If user has ever clicked an item to mark it as checked, we no longer automatically mark
@@ -487,7 +493,8 @@ public class RequestRoleFragment extends DialogFragment {
        @Nullable
        private String mPendingUserCheckedPackageName;

        Adapter(@NonNull Role role) {
        Adapter(@NonNull ListView listView, @NonNull Role role) {
            mListView = listView;
            mRole = role;
        }

@@ -506,10 +513,6 @@ public class RequestRoleFragment extends DialogFragment {
            }
        }

        public void setListView(@NonNull ListView listView) {
            mListView = listView;
        }

        public void setDontAskAgain(boolean dontAskAgain) {
            if (mDontAskAgain == dontAskAgain) {
                return;
@@ -732,11 +735,10 @@ public class RequestRoleFragment extends DialogFragment {
            public final TextView subtitleText;

            ViewHolder(@NonNull View view) {
                iconImage = Objects.requireNonNull(view.findViewById(R.id.icon));
                titleAndSubtitleLayout = Objects.requireNonNull(view.findViewById(
                        R.id.title_and_subtitle));
                titleText = Objects.requireNonNull(view.findViewById(R.id.title));
                subtitleText = Objects.requireNonNull(view.findViewById(R.id.subtitle));
                iconImage = view.requireViewById(R.id.icon);
                titleAndSubtitleLayout = view.requireViewById(R.id.title_and_subtitle);
                titleText = view.requireViewById(R.id.title);
                subtitleText = view.requireViewById(R.id.subtitle);
            }
        }
    }