Commit 6468d308 authored by Michael Thiessen's avatar Michael Thiessen Committed by Commit Bot

VR: Work around GVR UI not updating when density changes.

This is a hack around b/66493165 that should be removed when a GVR fix
is released. We manually find the views GVR adds to the hierarchy and
resize them/re-generate their Drawables for the new density.

Bug: 767603
Change-Id: Iacf40d81281d2e1a9423c095935d861b15be68fa
Reviewed-on: https://chromium-review.googlesource.com/682107Reviewed-by: default avatarTed Choc <tedchoc@chromium.org>
Reviewed-by: default avatarYash Malik <ymalik@chromium.org>
Commit-Queue: Michael Thiessen <mthiesse@chromium.org>
Cr-Commit-Position: refs/heads/master@{#504479}
parent 64b96149
......@@ -1711,8 +1711,11 @@ public abstract class ChromeActivity extends AsyncInitializationActivity
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
if (newConfig.densityDpi != mDensityDpi) {
if (!VrShellDelegate.onDensityChanged(mDensityDpi, newConfig.densityDpi)) {
recreate();
return;
}
mDensityDpi = newConfig.densityDpi;
if (!VrShellDelegate.onDensityChanged()) recreate();
}
}
......
......@@ -85,4 +85,9 @@ public interface VrShell {
* Triggers VrShell to navigate backward.
*/
void navigateBack();
/**
* Should be called when the density changes. Updates UI in response to the new density.
*/
void onDensityChanged(float oldDpi, float newDpi);
}
......@@ -423,7 +423,7 @@ public class VrShellDelegate
* @return Whether VrShellDelegate handled the density change. If the density change is
* unhandled, the Activity should be recreated in order to handle the change.
*/
public static boolean onDensityChanged() {
public static boolean onDensityChanged(float oldDpi, float newDpi) {
if (sInstance == null) return false;
// If density changed while in VR, we expect a second density change to restore the density
// to what it previously was when we exit VR. We shouldn't have to recreate the activity as
......@@ -434,6 +434,7 @@ public class VrShellDelegate
return true;
}
if (sInstance.mInVr || sInstance.mDonSucceeded) {
sInstance.onDensityChangedInternal(oldDpi, newDpi);
sInstance.mDensityChanged = true;
return true;
}
......@@ -1517,6 +1518,10 @@ public class VrShellDelegate
mRestoreSystemUiVisibilityFlag = -1;
}
private void onDensityChangedInternal(float oldDpi, float newDpi) {
if (mVrShell != null) mVrShell.onDensityChanged(oldDpi, newDpi);
}
/**
* Clean up VrShell, and associated native objects.
*/
......
......@@ -14,8 +14,12 @@ import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.ViewTreeObserver.OnPreDrawListener;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.RelativeLayout;
import com.google.vr.ndk.base.AndroidCompat;
import com.google.vr.ndk.base.GvrLayout;
......@@ -609,6 +613,46 @@ public class VrShellImpl
return this;
}
@Override
public void onDensityChanged(float oldDpi, float newDpi) {
// TODO(mthiesse, crbug.com/767603): Remove this workaround for b/66493165.
// This is extremely hacky. The GvrUiLayout doesn't update in response to density changes,
// so we manually go in and scale their elements to be the correct size (though due to the
// scaling they don't actually look pixel-perfectly identical to what they should be).
// These elements are dynamically loaded and inserted into the view hierarchy so we don't
// have IDs for them that we can look up.
try {
float scale = newDpi / oldDpi;
ViewGroup gvrLayoutImpl = (ViewGroup) getContainer().getChildAt(0);
RelativeLayout relativeLayout = (RelativeLayout) gvrLayoutImpl.getChildAt(1);
ImageButton x_button = (ImageButton) relativeLayout.getChildAt(0);
RelativeLayout alignment_marker = (RelativeLayout) relativeLayout.getChildAt(1);
ImageButton settings_button = (ImageButton) relativeLayout.getChildAt(2);
ViewGroup.LayoutParams params = alignment_marker.getLayoutParams();
params.width = (int) (params.width * scale);
params.height = (int) (params.height * scale);
alignment_marker.setLayoutParams(params);
int padding = (int) (x_button.getPaddingLeft() * scale);
x_button.setImageDrawable(x_button.getDrawable().getConstantState().newDrawable(
mActivity.getResources()));
x_button.setPadding(padding, padding, padding, padding);
settings_button.setImageDrawable(
settings_button.getDrawable().getConstantState().newDrawable(
mActivity.getResources()));
settings_button.setPadding(padding, padding, padding, padding);
} catch (Throwable e) {
// Ignore any errors. We're working around a bug in dynamically loaded code, so if it
// goes wrong that means the loaded code changed. ¯\_(ツ)_/¯
// In the worst case the close and settings buttons won't be drawn for the correct
// density.
}
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
nativeSetSurface(mNativeVrShell, holder.getSurface());
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment