1 /* 2 * Copyright (C) 2016 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 android.view.cts; 18 19 import static org.junit.Assert.fail; 20 21 import android.app.Activity; 22 import android.content.Context; 23 import android.content.pm.ActivityInfo; 24 import android.content.res.AssetManager; 25 import android.graphics.Bitmap; 26 import android.graphics.BitmapFactory; 27 import android.graphics.Canvas; 28 import android.graphics.Point; 29 import android.graphics.Rect; 30 import android.os.Bundle; 31 import android.view.View; 32 import android.view.ViewTreeObserver.OnDrawListener; 33 import android.view.cts.util.DisplayUtils; 34 35 import java.io.IOException; 36 import java.io.InputStream; 37 import java.util.concurrent.CountDownLatch; 38 import java.util.concurrent.TimeUnit; 39 40 public class PixelCopyWideGamutViewProducerActivity extends Activity implements OnDrawListener { 41 private static final int[] ORIENTATIONS = { 42 ActivityInfo.SCREEN_ORIENTATION_PORTRAIT, 43 ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE, 44 ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT, 45 ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE, 46 }; 47 private int mCurrentOrientation = 0; 48 private View mContent; 49 private Rect mContentBounds = new Rect(); 50 private CountDownLatch mFence = new CountDownLatch(3); 51 private boolean mSupportsRotation; 52 53 @Override onCreate(Bundle savedInstanceState)54 protected void onCreate(Bundle savedInstanceState) { 55 super.onCreate(savedInstanceState); 56 57 // Check if the device supports both of portrait and landscape orientation screens. 58 mSupportsRotation = DisplayUtils.supportOrientationRequest(this); 59 if (mSupportsRotation) { 60 setRequestedOrientation(ORIENTATIONS[mCurrentOrientation]); 61 } 62 63 mContent = new WideGamutBitmapView(this); 64 setContentView(mContent); 65 View view = this.getWindow().getDecorView(); 66 view.setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION); 67 mContent.getViewTreeObserver().addOnDrawListener(this); 68 } 69 70 @Override onDraw()71 public void onDraw() { 72 final int requestedOrientation = ORIENTATIONS[mCurrentOrientation]; 73 boolean isRequestingPortrait = 74 requestedOrientation == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT 75 || requestedOrientation == ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT; 76 if (mSupportsRotation && (isRequestingPortrait != DisplayUtils.isDevicePortrait(this))) { 77 return; 78 } 79 mContent.post(() -> { 80 Point offset = new Point(); 81 // We pass mContentBounds here just as a throwaway rect, we don't care about 82 // the visible rect just the global offset. 83 mContent.getGlobalVisibleRect(mContentBounds, offset); 84 mContentBounds.set(offset.x, offset.y, 85 offset.x + mContent.getWidth(), offset.y + mContent.getHeight()); 86 mFence.countDown(); 87 if (mFence.getCount() > 0) { 88 mContent.invalidate(); 89 } 90 }); 91 } 92 waitForFirstDrawCompleted(int timeout, TimeUnit unit)93 public void waitForFirstDrawCompleted(int timeout, TimeUnit unit) { 94 try { 95 if (!mFence.await(timeout, unit)) { 96 fail("Timeout"); 97 } 98 } catch (InterruptedException ex) { 99 fail(ex.getMessage()); 100 } 101 } 102 rotate()103 public boolean rotate() { 104 if (!mSupportsRotation) { 105 // Do not rotate the screen if it is not supported. 106 return false; 107 } 108 mFence = new CountDownLatch(3); 109 runOnUiThread(() -> { 110 mCurrentOrientation = (mCurrentOrientation + 1) % ORIENTATIONS.length; 111 setRequestedOrientation(ORIENTATIONS[mCurrentOrientation]); 112 }); 113 waitForFirstDrawCompleted(3, TimeUnit.SECONDS); 114 return mCurrentOrientation != 0; 115 } 116 offsetForContent(Rect inOut)117 void offsetForContent(Rect inOut) { 118 inOut.offset(mContentBounds.left, mContentBounds.top); 119 } 120 121 private static final class WideGamutBitmapView extends View { 122 private final Bitmap mBitmap; 123 WideGamutBitmapView(Context context)124 WideGamutBitmapView(Context context) { 125 super(context); 126 // We use an asset to ensure aapt will not mess with the data 127 AssetManager assets = context.getResources().getAssets(); 128 try (InputStream in = assets.open("prophoto.png")) { 129 mBitmap = BitmapFactory.decodeStream(in); 130 } catch (IOException e) { 131 throw new RuntimeException("Test failed: ", e); 132 } 133 } 134 135 @Override onDraw(Canvas canvas)136 protected void onDraw(Canvas canvas) { 137 canvas.drawBitmap(mBitmap, 0.0f, 0.0f, null); 138 } 139 } 140 } 141