1 /* 2 * Copyright (C) 2024 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.settings.applications.credentials; 18 19 import android.content.Context; 20 import android.credentials.flags.Flags; 21 import android.util.AttributeSet; 22 import android.view.View; 23 import android.widget.Button; 24 25 import androidx.annotation.NonNull; 26 import androidx.annotation.Nullable; 27 import androidx.preference.Preference; 28 import androidx.preference.PreferenceViewHolder; 29 30 import com.android.internal.annotations.VisibleForTesting; 31 import com.android.settings.R; 32 import com.android.settings.widget.GearPreference; 33 34 /** 35 * This preference is shown at the top of the "passwords & accounts" screen and allows the user to 36 * pick their primary credential manager provider. 37 */ 38 public class PrimaryProviderPreference extends GearPreference { 39 shouldUseNewSettingsUi()40 public static boolean shouldUseNewSettingsUi() { 41 return Flags.newSettingsUi(); 42 } 43 44 private @Nullable Button mChangeButton = null; 45 private @Nullable Button mOpenButton = null; 46 private @Nullable View mButtonFrameView = null; 47 private @Nullable View mGearView = null; 48 private @Nullable Delegate mDelegate = null; 49 private boolean mButtonsCompactMode = false; 50 private boolean mOpenButtonVisible = false; 51 52 /** Called to send messages back to the parent controller. */ 53 public static interface Delegate { onOpenButtonClicked()54 void onOpenButtonClicked(); 55 onChangeButtonClicked()56 void onChangeButtonClicked(); 57 } 58 PrimaryProviderPreference( @onNull Context context, @NonNull AttributeSet attrs, int defStyleAttr, int defStyleRes)59 public PrimaryProviderPreference( 60 @NonNull Context context, 61 @NonNull AttributeSet attrs, 62 int defStyleAttr, 63 int defStyleRes) { 64 super(context, attrs, defStyleAttr, defStyleRes); 65 initializeNewSettingsUi(); 66 } 67 PrimaryProviderPreference( @onNull Context context, @NonNull AttributeSet attrs)68 public PrimaryProviderPreference( 69 @NonNull Context context, 70 @NonNull AttributeSet attrs) { 71 super(context, attrs); 72 initializeNewSettingsUi(); 73 } 74 initializeNewSettingsUi()75 private void initializeNewSettingsUi() { 76 if (!shouldUseNewSettingsUi()) { 77 return; 78 } 79 80 // Change the layout to the new settings ui. 81 setLayoutResource(R.layout.preference_credential_manager_with_buttons); 82 } 83 84 @Override onBindViewHolder(@onNull PreferenceViewHolder holder)85 public void onBindViewHolder(@NonNull PreferenceViewHolder holder) { 86 super.onBindViewHolder(holder); 87 88 if (shouldUseNewSettingsUi()) { 89 onBindViewHolderNewSettingsUi(holder); 90 } else { 91 onBindViewHolderOldSettingsUi(holder); 92 } 93 } 94 onBindViewHolderOldSettingsUi(PreferenceViewHolder holder)95 private void onBindViewHolderOldSettingsUi(PreferenceViewHolder holder) { 96 setOnPreferenceClickListener( 97 new Preference.OnPreferenceClickListener() { 98 public boolean onPreferenceClick(@NonNull Preference preference) { 99 if (mDelegate != null) { 100 mDelegate.onOpenButtonClicked(); 101 return true; 102 } 103 104 return false; 105 } 106 }); 107 108 // Setup the gear icon to handle opening the change provider scenario. 109 mGearView = holder.findViewById(R.id.settings_button); 110 mGearView.setVisibility(View.VISIBLE); 111 mGearView.setOnClickListener( 112 new View.OnClickListener() { 113 public void onClick(@NonNull View v) { 114 if (mDelegate != null) { 115 mDelegate.onChangeButtonClicked(); 116 } 117 } 118 }); 119 } 120 onBindViewHolderNewSettingsUi(PreferenceViewHolder holder)121 private void onBindViewHolderNewSettingsUi(PreferenceViewHolder holder) { 122 mOpenButton = (Button) holder.findViewById(R.id.open_button); 123 mOpenButton.setOnClickListener( 124 new View.OnClickListener() { 125 public void onClick(@NonNull View v) { 126 if (mDelegate != null) { 127 mDelegate.onOpenButtonClicked(); 128 } 129 } 130 }); 131 setVisibility(mOpenButton, mOpenButtonVisible); 132 holder.itemView.setClickable(false); 133 134 mChangeButton = (Button) holder.findViewById(R.id.change_button); 135 mChangeButton.setOnClickListener( 136 new View.OnClickListener() { 137 public void onClick(@NonNull View v) { 138 if (mDelegate != null) { 139 mDelegate.onChangeButtonClicked(); 140 } 141 } 142 }); 143 144 mButtonFrameView = holder.findViewById(R.id.credman_button_frame); 145 updateButtonFramePadding(); 146 } 147 setOpenButtonVisible(boolean isVisible)148 public void setOpenButtonVisible(boolean isVisible) { 149 if (mOpenButton != null) { 150 mOpenButton.setVisibility(isVisible ? View.VISIBLE : View.GONE); 151 setVisibility(mOpenButton, isVisible); 152 } 153 154 mOpenButtonVisible = isVisible; 155 } 156 updateButtonFramePadding()157 private void updateButtonFramePadding() { 158 if (mButtonFrameView == null) { 159 return; 160 } 161 162 int paddingLeft = mButtonsCompactMode ? 163 getContext().getResources().getDimensionPixelSize( 164 R.dimen.credman_primary_provider_pref_left_padding) : 165 getContext().getResources().getDimensionPixelSize( 166 R.dimen.credman_primary_provider_pref_left_padding_compact); 167 168 mButtonFrameView.setPadding( 169 paddingLeft, 170 mButtonFrameView.getPaddingTop(), 171 paddingLeft, 172 mButtonFrameView.getPaddingBottom()); 173 } 174 setButtonsCompactMode(boolean isCompactMode)175 public void setButtonsCompactMode(boolean isCompactMode) { 176 mButtonsCompactMode = isCompactMode; 177 updateButtonFramePadding(); 178 } 179 setDelegate(@onNull Delegate delegate)180 public void setDelegate(@NonNull Delegate delegate) { 181 mDelegate = delegate; 182 } 183 184 @Override shouldHideSecondTarget()185 protected boolean shouldHideSecondTarget() { 186 return shouldUseNewSettingsUi(); 187 } 188 189 @VisibleForTesting getOpenButton()190 public @Nullable Button getOpenButton() { 191 return mOpenButton; 192 } 193 194 @VisibleForTesting getChangeButton()195 public @Nullable Button getChangeButton() { 196 return mChangeButton; 197 } 198 199 @VisibleForTesting getButtonFrameView()200 public @Nullable View getButtonFrameView() { 201 return mButtonFrameView; 202 } 203 204 @VisibleForTesting getGearView()205 public @Nullable View getGearView() { 206 return mGearView; 207 } 208 setVisibility(View view, boolean isVisible)209 private static void setVisibility(View view, boolean isVisible) { 210 view.setVisibility(isVisible ? View.VISIBLE : View.GONE); 211 } 212 } 213