1 /* 2 * Copyright (C) 2023 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.server.autofill.ui; 18 19 import static com.android.server.autofill.Helper.sDebug; 20 21 import android.annotation.Nullable; 22 import android.content.Context; 23 import android.util.AttributeSet; 24 import android.util.DisplayMetrics; 25 import android.util.Slog; 26 import android.widget.LinearLayout; 27 28 import com.android.internal.R; 29 30 /** 31 {@link LinearLayout} that displays content of save dialog. 32 */ 33 public class BottomSheetLayout extends LinearLayout { 34 35 private static final String TAG = "BottomSheetLayout"; 36 BottomSheetLayout(Context context)37 public BottomSheetLayout(Context context) { 38 super(context); 39 } 40 BottomSheetLayout(Context context, @Nullable AttributeSet attrs)41 public BottomSheetLayout(Context context, @Nullable AttributeSet attrs) { 42 super(context, attrs); 43 } 44 BottomSheetLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr)45 public BottomSheetLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { 46 super(context, attrs, defStyleAttr); 47 } 48 49 @Override onMeasure(int widthSpec, int heightSpec)50 public void onMeasure(int widthSpec, int heightSpec) { 51 if (getContext() == null || getContext().getResources() == null) { 52 super.onMeasure(widthSpec, heightSpec); 53 Slog.w(TAG, "onMeasure failed due to missing context or missing resources."); 54 return; 55 } 56 57 if (getChildCount() == 0) { 58 // Should not happen 59 super.onMeasure(widthSpec, heightSpec); 60 Slog.wtf(TAG, "onMeasure failed due to missing children views."); 61 return; 62 } 63 64 DisplayMetrics displayMetrics = getContext().getResources().getDisplayMetrics(); 65 66 final int pxOffset = getContext().getResources().getDimensionPixelSize( 67 R.dimen.autofill_dialog_offset); 68 final int outerMargin = getContext().getResources().getDimensionPixelSize( 69 R.dimen.autofill_save_outer_margin); 70 71 final boolean includeHorizontalSpace = 72 getContext().getResources().getBoolean( 73 R.bool.autofill_dialog_horizontal_space_included); 74 75 76 final int screenHeight = displayMetrics.heightPixels; 77 final int screenWidth = displayMetrics.widthPixels; 78 79 final int maxHeight = screenHeight - pxOffset - outerMargin; 80 81 int maxWidth = screenWidth; 82 83 if (includeHorizontalSpace) { 84 maxWidth -= 2 * pxOffset; 85 } 86 87 maxWidth = 88 Math.min(maxWidth, getContext().getResources().getDimensionPixelSize( 89 R.dimen.autofill_dialog_max_width)); 90 91 super.onMeasure(MeasureSpec.makeMeasureSpec(maxWidth, MeasureSpec.EXACTLY), 92 MeasureSpec.makeMeasureSpec(maxHeight, MeasureSpec.AT_MOST)); 93 94 95 if (sDebug) { 96 Slog.d(TAG, "onMeasure() values in dp:" 97 + " screenHeight: " + screenHeight / displayMetrics.density + ", screenWidth: " 98 + screenWidth / displayMetrics.density 99 + ", maxHeight: " + maxHeight / displayMetrics.density 100 + ", maxWidth: " + maxWidth / displayMetrics.density + ", getMeasuredWidth(): " 101 + getMeasuredWidth() / displayMetrics.density + ", getMeasuredHeight(): " 102 + getMeasuredHeight() / displayMetrics.density); 103 } 104 setMeasuredDimension(getMeasuredWidth(), getMeasuredHeight()); 105 } 106 107 108 } 109