From 3ed860add8b83a9d69d7726bc636b8486a70039f Mon Sep 17 00:00:00 2001 From: Brian Carlstrom Date: Thu, 14 Jan 2016 22:55:02 -0800 Subject: Revert "Make request permissions dialog layout robost" This reverts commit ecaeae17f52d6562d23dfec91e44bc3c0b4a6d13. --- .../permission/ui/GrantPermissionsActivity.java | 15 ------------- .../ui/GrantPermissionsDefaultViewHandler.java | 1 + .../permission/ui/ManualLayoutFrame.java | 25 +++++----------------- 3 files changed, 6 insertions(+), 35 deletions(-) (limited to 'src') diff --git a/src/com/android/packageinstaller/permission/ui/GrantPermissionsActivity.java b/src/com/android/packageinstaller/permission/ui/GrantPermissionsActivity.java index 7e216636..ffa8bf35 100644 --- a/src/com/android/packageinstaller/permission/ui/GrantPermissionsActivity.java +++ b/src/com/android/packageinstaller/permission/ui/GrantPermissionsActivity.java @@ -25,7 +25,6 @@ import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.PermissionInfo; -import android.content.res.Configuration; import android.content.res.Resources; import android.graphics.drawable.Icon; import android.hardware.camera2.utils.ArrayUtils; @@ -173,20 +172,6 @@ public class GrantPermissionsActivity extends OverlayTouchActivity } } - @Override - public void onConfigurationChanged(Configuration newConfig) { - super.onConfigurationChanged(newConfig); - // This is just gross - we need to relayout the window as - // dialog width may be different in landscape vs portrait - // which affect the min window height needed to show all - // content. We have to re-add the window to force it to be - // resized if needed. The way the permission grant dialog - // is implemented is not correct and has to be rewritten. - View decor = getWindow().getDecorView(); - getWindowManager().removeViewImmediate(decor); - getWindowManager().addView(decor, decor.getLayoutParams()); - } - @Override public boolean dispatchTouchEvent(MotionEvent ev) { View rootView = getWindow().getDecorView(); diff --git a/src/com/android/packageinstaller/permission/ui/GrantPermissionsDefaultViewHandler.java b/src/com/android/packageinstaller/permission/ui/GrantPermissionsDefaultViewHandler.java index 06ca266a..c5d78784 100644 --- a/src/com/android/packageinstaller/permission/ui/GrantPermissionsDefaultViewHandler.java +++ b/src/com/android/packageinstaller/permission/ui/GrantPermissionsDefaultViewHandler.java @@ -20,6 +20,7 @@ import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.ObjectAnimator; import android.content.Context; +import android.content.res.Resources; import android.graphics.drawable.Icon; import android.os.Bundle; import android.util.SparseArray; diff --git a/src/com/android/packageinstaller/permission/ui/ManualLayoutFrame.java b/src/com/android/packageinstaller/permission/ui/ManualLayoutFrame.java index 1af400b3..c9ccf9c1 100644 --- a/src/com/android/packageinstaller/permission/ui/ManualLayoutFrame.java +++ b/src/com/android/packageinstaller/permission/ui/ManualLayoutFrame.java @@ -17,6 +17,7 @@ package com.android.packageinstaller.permission.ui; import android.content.Context; import android.util.AttributeSet; +import android.view.View; import android.widget.FrameLayout; /** @@ -26,10 +27,13 @@ import android.widget.FrameLayout; * but allows the view to grow downwards for animation. */ public class ManualLayoutFrame extends FrameLayout { + private int mDesiredHeight; private int mHeight; private int mWidth; + private View mOffsetView; + public ManualLayoutFrame(Context context, AttributeSet attrs) { super(context, attrs); setClipChildren(false); @@ -43,29 +47,10 @@ public class ManualLayoutFrame extends FrameLayout { @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { if (mWidth != 0) { - int newWidth = mWidth; - final int widthMode = MeasureSpec.getMode(widthMeasureSpec); - switch (widthMode) { - case MeasureSpec.AT_MOST: { - newWidth = Math.min(mWidth, MeasureSpec.getSize(widthMeasureSpec)); - } break; - case MeasureSpec.EXACTLY: { - newWidth = MeasureSpec.getSize(widthMeasureSpec); - } break; - } - // If the width changes we have to re-evaluate the height - if (newWidth != mWidth) { - mWidth = newWidth; - mHeight = 0; - } + // Keep the width constant to avoid weirdness. widthMeasureSpec = MeasureSpec.makeMeasureSpec(mWidth, MeasureSpec.EXACTLY); } - - // Let the content measure how much it needs to be fully shown - heightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); - super.onMeasure(widthMeasureSpec, heightMeasureSpec); - mDesiredHeight = getMeasuredHeight(); if (mHeight == 0 && mDesiredHeight != 0) { // Record the first non-zero width and height, this will be the height henceforth. -- cgit v1.2.3 From 9199155a7f5643e6a07a626973f892e05c7c5bd7 Mon Sep 17 00:00:00 2001 From: Svetoslav Ganov Date: Wed, 20 Jan 2016 18:06:28 -0800 Subject: Make the permission request dialog's layout robust The old implementation was relying on a fixed window size where the content is positioned by a custom layout manager. It is possible however that subsequent permissions requests do not fit in the window as its size is computed based on the content of the first permissions request. There were also cases where the content is chopped after a rotation as the dialog size width was not re-evaluated while it should be. Further, animation from one permission request state to another was not properly done resulting in content being chopped off in some cases. The current approach is to have a dialog width for the content activity but the height is as tall as the screen allowing us to fit arbitrary large permission request content. Also we are resetting the fixed width on a configuration change so the dialog is robust to adjust size as needed. bug:24679384 bug:25755378 Change-Id: I4d23f81d8e59ce23bf9a27155ebb5ec6e2e6752c (cherry picked from commit c6dc4bb52b07886346b02b326c5c32a8299ed73e) --- .../permission/ui/GrantPermissionsActivity.java | 18 +- .../permission/ui/ManualLayoutFrame.java | 60 ++-- .../handheld/GrantPermissionsViewHandlerImpl.java | 316 +++++++-------------- 3 files changed, 151 insertions(+), 243 deletions(-) (limited to 'src') diff --git a/src/com/android/packageinstaller/permission/ui/GrantPermissionsActivity.java b/src/com/android/packageinstaller/permission/ui/GrantPermissionsActivity.java index 102fd6ef..4c052eb9 100644 --- a/src/com/android/packageinstaller/permission/ui/GrantPermissionsActivity.java +++ b/src/com/android/packageinstaller/permission/ui/GrantPermissionsActivity.java @@ -25,6 +25,7 @@ import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.PermissionInfo; +import android.content.res.Configuration; import android.content.res.Resources; import android.graphics.Typeface; import android.graphics.drawable.Icon; @@ -44,8 +45,8 @@ import com.android.packageinstaller.R; import com.android.packageinstaller.permission.model.AppPermissionGroup; import com.android.packageinstaller.permission.model.AppPermissions; import com.android.packageinstaller.permission.model.Permission; +import com.android.packageinstaller.permission.ui.handheld.GrantPermissionsViewHandlerImpl; import com.android.packageinstaller.permission.utils.SafetyNetLogger; -import com.android.packageinstaller.permission.utils.Utils; import java.util.ArrayList; import java.util.LinkedHashMap; @@ -175,6 +176,21 @@ public class GrantPermissionsActivity extends OverlayTouchActivity } } + @Override + public void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); + // We need to relayout the window as dialog width may be + // different in landscape vs portrait which affect the min + // window height needed to show all content. We have to + // re-add the window to force it to be resized if needed. + View decor = getWindow().getDecorView(); + getWindowManager().removeViewImmediate(decor); + getWindowManager().addView(decor, decor.getLayoutParams()); + if (mViewHandler instanceof GrantPermissionsViewHandlerImpl) { + ((GrantPermissionsViewHandlerImpl) mViewHandler).onConfigurationChanged(); + } + } + @Override public boolean dispatchTouchEvent(MotionEvent ev) { View rootView = getWindow().getDecorView(); diff --git a/src/com/android/packageinstaller/permission/ui/ManualLayoutFrame.java b/src/com/android/packageinstaller/permission/ui/ManualLayoutFrame.java index c9ccf9c1..a20c9523 100644 --- a/src/com/android/packageinstaller/permission/ui/ManualLayoutFrame.java +++ b/src/com/android/packageinstaller/permission/ui/ManualLayoutFrame.java @@ -18,58 +18,56 @@ package com.android.packageinstaller.permission.ui; import android.content.Context; import android.util.AttributeSet; import android.view.View; -import android.widget.FrameLayout; +import android.view.ViewGroup; -/** - * Allows one standard layout pass, but afterwards holds getMeasuredHeight constant, - * however still allows drawing larger at the size needed by its children. This allows - * a dialog to tell the window the height is constant (with keeps its position constant) - * but allows the view to grow downwards for animation. - */ -public class ManualLayoutFrame extends FrameLayout { - - private int mDesiredHeight; - private int mHeight; +public class ManualLayoutFrame extends ViewGroup { + private int mContentBottom; private int mWidth; - private View mOffsetView; - public ManualLayoutFrame(Context context, AttributeSet attrs) { super(context, attrs); - setClipChildren(false); - setClipToPadding(false); } - public int getLayoutHeight() { - return mDesiredHeight; + public void onConfigurationChanged() { + mContentBottom = 0; + mWidth = 0; } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { if (mWidth != 0) { - // Keep the width constant to avoid weirdness. + int newWidth = mWidth; + final int widthMode = MeasureSpec.getMode(widthMeasureSpec); + switch (widthMode) { + case MeasureSpec.AT_MOST: { + newWidth = Math.min(mWidth, MeasureSpec.getSize(widthMeasureSpec)); + } break; + case MeasureSpec.EXACTLY: { + newWidth = MeasureSpec.getSize(widthMeasureSpec); + } break; + } + if (newWidth != mWidth) { + mWidth = newWidth; + } widthMeasureSpec = MeasureSpec.makeMeasureSpec(mWidth, MeasureSpec.EXACTLY); } super.onMeasure(widthMeasureSpec, heightMeasureSpec); - mDesiredHeight = getMeasuredHeight(); - if (mHeight == 0 && mDesiredHeight != 0) { - // Record the first non-zero width and height, this will be the height henceforth. - mHeight = mDesiredHeight; + if (mWidth == 0) { mWidth = getMeasuredWidth(); } - if (mHeight != 0) { - // Always report the same height - setMeasuredDimension(getMeasuredWidth(), mHeight); - } + + measureChild(getChildAt(0), widthMeasureSpec, heightMeasureSpec); } @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { - if (mDesiredHeight != 0) { - // Draw at height we expect to be. - setBottom(getTop() + mDesiredHeight); - bottom = top + mDesiredHeight; + View content = getChildAt(0); + if (mContentBottom == 0) { + mContentBottom = (getMeasuredHeight() + content.getMeasuredHeight()) / 2; } - super.onLayout(changed, left, top, right, bottom); + final int contentLeft = (getMeasuredWidth() - content.getMeasuredWidth()) / 2; + final int contentTop = mContentBottom - content.getMeasuredHeight(); + final int contentRight = contentLeft + content.getMeasuredWidth(); + content.layout(contentLeft, contentTop, contentRight, mContentBottom); } } diff --git a/src/com/android/packageinstaller/permission/ui/handheld/GrantPermissionsViewHandlerImpl.java b/src/com/android/packageinstaller/permission/ui/handheld/GrantPermissionsViewHandlerImpl.java index 2d27f069..f2b0912d 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/GrantPermissionsViewHandlerImpl.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/GrantPermissionsViewHandlerImpl.java @@ -16,23 +16,14 @@ package com.android.packageinstaller.permission.ui.handheld; -import android.animation.Animator; -import android.animation.AnimatorListenerAdapter; -import android.animation.ObjectAnimator; import android.content.Context; -import android.content.res.Resources; import android.graphics.drawable.Icon; import android.os.Bundle; -import android.util.SparseArray; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; -import android.view.View.OnLayoutChangeListener; import android.view.ViewGroup; -import android.view.ViewParent; -import android.view.ViewRootImpl; import android.view.WindowManager.LayoutParams; -import android.view.animation.Animation; import android.view.animation.AnimationUtils; import android.view.animation.Interpolator; import android.widget.Button; @@ -45,8 +36,6 @@ import com.android.packageinstaller.permission.ui.ButtonBarLayout; import com.android.packageinstaller.permission.ui.GrantPermissionsViewHandler; import com.android.packageinstaller.permission.ui.ManualLayoutFrame; -import java.util.ArrayList; - public final class GrantPermissionsViewHandlerImpl implements GrantPermissionsViewHandler, OnClickListener { @@ -59,14 +48,8 @@ public final class GrantPermissionsViewHandlerImpl public static final String ARG_GROUP_DO_NOT_ASK_CHECKED = "ARG_GROUP_DO_NOT_ASK_CHECKED"; // Animation parameters. - private static final long SIZE_START_DELAY = 300; - private static final long SIZE_START_LENGTH = 233; - private static final long FADE_OUT_START_DELAY = 300; - private static final long FADE_OUT_START_LENGTH = 217; - private static final long TRANSLATE_START_DELAY = 367; - private static final long TRANSLATE_LENGTH = 317; - private static final long GROUP_UPDATE_DELAY = 400; - private static final long DO_NOT_ASK_CHECK_DELAY = 450; + private static final long OUT_DURATION = 200; + private static final long IN_DURATION = 300; private final Context mContext; @@ -86,22 +69,13 @@ public final class GrantPermissionsViewHandlerImpl private CheckBox mDoNotAskCheckbox; private Button mAllowButton; - private ArrayList mHeightControllers; private ManualLayoutFrame mRootView; // Needed for animation private ViewGroup mDescContainer; private ViewGroup mCurrentDesc; - private ViewGroup mNextDesc; - private ViewGroup mDialogContainer; - - private final Runnable mUpdateGroup = new Runnable() { - @Override - public void run() { - updateGroup(); - } - }; + private ButtonBarLayout mButtonBar; public GrantPermissionsViewHandlerImpl(Context context) { mContext = context; @@ -160,171 +134,148 @@ public final class GrantPermissionsViewHandlerImpl } } - private void animateToPermission() { - if (mHeightControllers == null) { - // We need to manually control the height of any views heigher than the root that - // we inflate. Find all the views up to the root and create ViewHeightControllers for - // them. - mHeightControllers = new ArrayList<>(); - ViewRootImpl viewRoot = mRootView.getViewRootImpl(); - ViewParent v = mRootView.getParent(); - addHeightController(mDialogContainer); - addHeightController(mRootView); - while (v != viewRoot) { - addHeightController((View) v); - v = v.getParent(); - } - // On the heighest level view, we want to setTop rather than setBottom to control the - // height, this way the dialog will grow up rather than down. - ViewHeightController realRootView = - mHeightControllers.get(mHeightControllers.size() - 1); - realRootView.setControlTop(true); - } - - // Grab the current height/y positions, then wait for the layout to change, - // so we can get the end height/y positions. - final SparseArray startPositions = getViewPositions(); - final int startHeight = mRootView.getLayoutHeight(); - mRootView.addOnLayoutChangeListener(new OnLayoutChangeListener() { - @Override - public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, - int oldTop, int oldRight, int oldBottom) { - mRootView.removeOnLayoutChangeListener(this); - SparseArray endPositions = getViewPositions(); - int endHeight = mRootView.getLayoutHeight(); - if (startPositions.get(R.id.do_not_ask_checkbox) == 0 - && endPositions.get(R.id.do_not_ask_checkbox) != 0) { - // If the checkbox didn't have a position before but has one now then set - // the start position to the end position because it just became visible. - startPositions.put(R.id.do_not_ask_checkbox, - endPositions.get(R.id.do_not_ask_checkbox)); - } - animateYPos(startPositions, endPositions, endHeight - startHeight); - } - }); + public void onConfigurationChanged() { + mRootView.onConfigurationChanged(); + } + private void animateOldContent(Runnable callback) { // Fade out old description group and scale out the icon for it. Interpolator interpolator = AnimationUtils.loadInterpolator(mContext, android.R.interpolator.fast_out_linear_in); + + // Icon scale to zero mIconView.animate() .scaleX(0) .scaleY(0) - .setStartDelay(FADE_OUT_START_DELAY) - .setDuration(FADE_OUT_START_LENGTH) + .setDuration(OUT_DURATION) .setInterpolator(interpolator) .start(); + + // Description fade out mCurrentDesc.animate() .alpha(0) - .setStartDelay(FADE_OUT_START_DELAY) - .setDuration(FADE_OUT_START_LENGTH) + .setDuration(OUT_DURATION) .setInterpolator(interpolator) - .setListener(null) + .withEndAction(callback) .start(); - // Update the index of the permission after the animations have started. - mCurrentGroupView.getHandler().postDelayed(mUpdateGroup, GROUP_UPDATE_DELAY); + // Checkbox fade out if needed + if (!mShowDonNotAsk && mDoNotAskCheckbox.getVisibility() == View.VISIBLE) { + mDoNotAskCheckbox.animate() + .alpha(0) + .setDuration(OUT_DURATION) + .setInterpolator(interpolator) + .start(); + } + } - // Add the new description and translate it in. - mNextDesc = (ViewGroup) LayoutInflater.from(mContext).inflate( + private void attachNewContent(final Runnable callback) { + mCurrentDesc = (ViewGroup) LayoutInflater.from(mContext).inflate( R.layout.permission_description, mDescContainer, false); + mDescContainer.removeAllViews(); + mDescContainer.addView(mCurrentDesc); + + mDialogContainer.addOnLayoutChangeListener(new View.OnLayoutChangeListener() { + @Override + public void onLayoutChange(View v, int left, int top, int right, int bottom, + int oldLeft, int oldTop, int oldRight, int oldBottom) { + mDialogContainer.removeOnLayoutChangeListener(this); + + // Prepare new content to the right to be moved in + final int containerWidth = mDescContainer.getWidth(); + mCurrentDesc.setTranslationX(containerWidth); + + // How much scale for the dialog to appear the same? + final int oldDynamicHeight = oldBottom - oldTop - mButtonBar.getHeight(); + final float scaleY = (float) oldDynamicHeight / mDescContainer.getHeight(); + + // How much to translate for the dialog to appear the same? + final int translationCompensatingScale = (int) (scaleY + * mDescContainer.getHeight() - mDescContainer.getHeight()) / 2; + final int translationY = (oldTop - top) + translationCompensatingScale; + + // Animate to the current layout + mDescContainer.setScaleY(scaleY); + mDescContainer.setTranslationY(translationY); + mDescContainer.animate() + .translationY(0) + .scaleY(1.0f) + .setInterpolator(AnimationUtils.loadInterpolator(mContext, + android.R.interpolator.linear_out_slow_in)) + .setDuration(IN_DURATION) + .withEndAction(callback) + .start(); + } + } + ); - mMessageView = (TextView) mNextDesc.findViewById(R.id.permission_message); - mIconView = (ImageView) mNextDesc.findViewById(R.id.permission_icon); - updateDescription(); - - int width = mDescContainer.getRootView().getWidth(); - mDescContainer.addView(mNextDesc); - mNextDesc.setTranslationX(width); - - final View oldDesc = mCurrentDesc; - // Remove the old view from the description, so that we can shrink if necessary. - mDescContainer.removeView(oldDesc); - oldDesc.setPadding(mDescContainer.getLeft(), mDescContainer.getTop(), - mRootView.getRight() - mDescContainer.getRight(), 0); - mRootView.addView(oldDesc); + mMessageView = (TextView) mCurrentDesc.findViewById(R.id.permission_message); + mIconView = (ImageView) mCurrentDesc.findViewById(R.id.permission_icon); - mCurrentDesc = mNextDesc; - mNextDesc.animate() - .translationX(0) - .setStartDelay(TRANSLATE_START_DELAY) - .setDuration(TRANSLATE_LENGTH) - .setInterpolator(AnimationUtils.loadInterpolator(mContext, - android.R.interpolator.linear_out_slow_in)) - .setListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - // This is the longest animation, when it finishes, we are done. - mRootView.removeView(oldDesc); - } - }) - .start(); + final boolean doNotAskWasShown = mDoNotAskCheckbox.getVisibility() == View.VISIBLE; - boolean visibleBefore = mDoNotAskCheckbox.getVisibility() == View.VISIBLE; + updateDescription(); + updateGroup(); updateDoNotAskCheckBox(); - boolean visibleAfter = mDoNotAskCheckbox.getVisibility() == View.VISIBLE; - if (visibleBefore != visibleAfter) { - Animation anim = AnimationUtils.loadAnimation(mContext, - visibleAfter ? android.R.anim.fade_in : android.R.anim.fade_out); - anim.setStartOffset(visibleAfter ? DO_NOT_ASK_CHECK_DELAY : 0); - mDoNotAskCheckbox.startAnimation(anim); + + if (!doNotAskWasShown && mShowDonNotAsk) { + mDoNotAskCheckbox.setAlpha(0); } } - private void addHeightController(View v) { - ViewHeightController heightController = new ViewHeightController(v); - heightController.setHeight(v.getHeight()); - mHeightControllers.add(heightController); - } + private void animateNewContent() { + Interpolator interpolator = AnimationUtils.loadInterpolator(mContext, + android.R.interpolator.linear_out_slow_in); - private SparseArray getViewPositions() { - SparseArray locMap = new SparseArray<>(); - final int N = mDialogContainer.getChildCount(); - for (int i = 0; i < N; i++) { - View child = mDialogContainer.getChildAt(i); - if (child.getId() <= 0) { - // Only track views with ids. - continue; - } - locMap.put(child.getId(), child.getY()); + // Description slide in + mCurrentDesc.animate() + .translationX(0) + .setDuration(IN_DURATION) + .setInterpolator(interpolator) + .start(); + + // Checkbox fade in if needed + if (mShowDonNotAsk && mDoNotAskCheckbox.getVisibility() == View.VISIBLE + && mDoNotAskCheckbox.getAlpha() < 1.0f) { + mDoNotAskCheckbox.setAlpha(0); + mDoNotAskCheckbox.animate() + .alpha(1.0f) + .setDuration(IN_DURATION) + .setInterpolator(interpolator) + .start(); } - return locMap; } - private void animateYPos(SparseArray startPositions, SparseArray endPositions, - int heightDiff) { - final int N = startPositions.size(); - for (int i = 0; i < N; i++) { - int key = startPositions.keyAt(i); - float start = startPositions.get(key); - float end = endPositions.get(key); - if (start != end) { - final View child = mDialogContainer.findViewById(key); - child.setTranslationY(start - end); - child.animate() - .setStartDelay(SIZE_START_DELAY) - .setDuration(SIZE_START_LENGTH) - .translationY(0) - .start(); + private void animateToPermission() { + // Remove the old content + animateOldContent(new Runnable() { + @Override + public void run() { + // Add the new content + attachNewContent(new Runnable() { + @Override + public void run() { + // Animate the new content + animateNewContent(); + } + }); } - } - for (int i = 0; i < mHeightControllers.size(); i++) { - mHeightControllers.get(i).animateAddHeight(heightDiff); - } + }); } @Override public View createView() { mRootView = (ManualLayoutFrame) LayoutInflater.from(mContext) .inflate(R.layout.grant_permissions, null); - ((ButtonBarLayout) mRootView.findViewById(R.id.button_group)).setAllowStacking(true); - - mDialogContainer = (ViewGroup) mRootView.findViewById(R.id.dialog_container); + mButtonBar = (ButtonBarLayout) mRootView.findViewById(R.id.button_group); + mButtonBar.setAllowStacking(true); mMessageView = (TextView) mRootView.findViewById(R.id.permission_message); mIconView = (ImageView) mRootView.findViewById(R.id.permission_icon); mCurrentGroupView = (TextView) mRootView.findViewById(R.id.current_page_text); mDoNotAskCheckbox = (CheckBox) mRootView.findViewById(R.id.do_not_ask_checkbox); mAllowButton = (Button) mRootView.findViewById(R.id.permission_allow_button); + mDialogContainer = (ViewGroup) mRootView.findViewById(R.id.dialog_container); mDescContainer = (ViewGroup) mRootView.findViewById(R.id.desc_container); mCurrentDesc = (ViewGroup) mRootView.findViewById(R.id.perm_desc_root); @@ -402,61 +353,4 @@ public final class GrantPermissionsViewHandlerImpl mResultListener.onPermissionGrantResult(mGroupName, false, doNotAskAgain); } } - - /** - * Manually controls the height of a view through getBottom/setTop. Also listens - * for layout changes and sets the height again to be sure it doesn't change. - */ - private static final class ViewHeightController implements OnLayoutChangeListener { - private final View mView; - private int mHeight; - private int mNextHeight; - private boolean mControlTop; - private ObjectAnimator mAnimator; - - public ViewHeightController(View view) { - mView = view; - mView.addOnLayoutChangeListener(this); - } - - public void setControlTop(boolean controlTop) { - mControlTop = controlTop; - } - - public void animateAddHeight(int heightDiff) { - if (heightDiff != 0) { - if (mNextHeight == 0) { - mNextHeight = mHeight; - } - mNextHeight += heightDiff; - if (mAnimator != null) { - mAnimator.cancel(); - } - mAnimator = ObjectAnimator.ofInt(this, "height", mHeight, mNextHeight); - mAnimator.setStartDelay(SIZE_START_DELAY); - mAnimator.setDuration(SIZE_START_LENGTH); - mAnimator.start(); - } - } - - public void setHeight(int height) { - mHeight = height; - updateHeight(); - } - - @Override - public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, - int oldTop, int oldRight, int oldBottom) { - // Ensure that the height never changes. - updateHeight(); - } - - private void updateHeight() { - if (mControlTop) { - mView.setTop(mView.getBottom() - mHeight); - } else { - mView.setBottom(mView.getTop() + mHeight); - } - } - } } -- cgit v1.2.3