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