Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7fcb5dc5 authored by Jeff Brown's avatar Jeff Brown Committed by Android (Google) Code Review
Browse files

Merge "Pin electron beam surface to natural orientation." into jb-mr1.1-dev

parents 487f8e93 7f3994ec
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -285,6 +285,16 @@ public final class DisplayInfo implements Parcelable {
        getMetricsWithSize(outMetrics, cih, logicalWidth, logicalHeight);
    }

    public int getNaturalWidth() {
        return rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180 ?
                logicalWidth : logicalHeight;
    }

    public int getNaturalHeight() {
        return rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180 ?
                logicalHeight : logicalWidth;
    }

    private void getMetricsWithSize(DisplayMetrics outMetrics, CompatibilityInfoHolder cih,
            int width, int height) {
        outMetrics.densityDpi = outMetrics.noncompatDensityDpi = logicalDensityDpi;
+40 −0
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@ import android.view.DisplayInfo;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * Manages attached displays.
@@ -152,6 +153,10 @@ public final class DisplayManagerService extends IDisplayManager.Stub {
            new SparseArray<LogicalDisplay>();
    private int mNextNonDefaultDisplayId = Display.DEFAULT_DISPLAY + 1;

    // List of all display transaction listeners.
    private final CopyOnWriteArrayList<DisplayTransactionListener> mDisplayTransactionListeners =
            new CopyOnWriteArrayList<DisplayTransactionListener>();

    // Set to true if all displays have been blanked by the power manager.
    private int mAllDisplayBlankStateFromPowerManager;

@@ -260,6 +265,36 @@ public final class DisplayManagerService extends IDisplayManager.Stub {
        return mHeadless;
    }

    /**
     * Registers a display transaction listener to provide the client a chance to
     * update its surfaces within the same transaction as any display layout updates.
     *
     * @param listener The listener to register.
     */
    public void registerDisplayTransactionListener(DisplayTransactionListener listener) {
        if (listener == null) {
            throw new IllegalArgumentException("listener must not be null");
        }

        // List is self-synchronized copy-on-write.
        mDisplayTransactionListeners.add(listener);
    }

    /**
     * Unregisters a display transaction listener to provide the client a chance to
     * update its surfaces within the same transaction as any display layout updates.
     *
     * @param listener The listener to unregister.
     */
    public void unregisterDisplayTransactionListener(DisplayTransactionListener listener) {
        if (listener == null) {
            throw new IllegalArgumentException("listener must not be null");
        }

        // List is self-synchronized copy-on-write.
        mDisplayTransactionListeners.remove(listener);
    }

    /**
     * Overrides the display information of a particular logical display.
     * This is used by the window manager to control the size and characteristics
@@ -298,6 +333,11 @@ public final class DisplayManagerService extends IDisplayManager.Stub {

            performTraversalInTransactionLocked();
        }

        // List is self-synchronized copy-on-write.
        for (DisplayTransactionListener listener : mDisplayTransactionListeners) {
            listener.onDisplayTransaction();
        }
    }

    /**
+26 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.server.display;

/**
 * Called within a Surface transaction whenever the size or orientation of a
 * display may have changed.  Provides an opportunity for the client to
 * update the position of its surfaces as part of the same transaction.
 */
public interface DisplayTransactionListener {
    void onDisplayTransaction();
}
+5 −6
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.server.power;
import com.android.server.LightsService;
import com.android.server.TwilightService;
import com.android.server.TwilightService.TwilightState;
import com.android.server.display.DisplayManagerService;

import android.animation.Animator;
import android.animation.ObjectAnimator;
@@ -29,7 +30,6 @@ import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.hardware.SystemSensorManager;
import android.hardware.display.DisplayManager;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
@@ -40,7 +40,6 @@ import android.util.FloatMath;
import android.util.Slog;
import android.util.Spline;
import android.util.TimeUtils;
import android.view.Display;

import java.io.PrintWriter;

@@ -183,7 +182,7 @@ final class DisplayPowerController {
    private final TwilightService mTwilight;

    // The display manager.
    private final DisplayManager mDisplayManager;
    private final DisplayManagerService mDisplayManager;

    // The sensor manager.
    private final SensorManager mSensorManager;
@@ -346,6 +345,7 @@ final class DisplayPowerController {
     */
    public DisplayPowerController(Looper looper, Context context, Notifier notifier,
            LightsService lights, TwilightService twilight,
            DisplayManagerService displayManager,
            DisplayBlanker displayBlanker,
            Callbacks callbacks, Handler callbackHandler) {
        mHandler = new DisplayControllerHandler(looper);
@@ -357,7 +357,7 @@ final class DisplayPowerController {
        mLights = lights;
        mTwilight = twilight;
        mSensorManager = new SystemSensorManager(mHandler.getLooper());
        mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE);
        mDisplayManager = displayManager;

        final Resources resources = context.getResources();

@@ -518,9 +518,8 @@ final class DisplayPowerController {
    }

    private void initialize() {
        Display display = mDisplayManager.getDisplay(Display.DEFAULT_DISPLAY);
        mPowerState = new DisplayPowerState(
                new ElectronBeam(display), mDisplayBlanker,
                new ElectronBeam(mDisplayManager), mDisplayBlanker,
                mLights.getLight(LightsService.LIGHT_ID_BACKLIGHT));

        mElectronBeamOnAnimator = ObjectAnimator.ofFloat(
+71 −36
Original line number Diff line number Diff line
@@ -16,6 +16,9 @@

package com.android.server.power;

import com.android.server.display.DisplayManagerService;
import com.android.server.display.DisplayTransactionListener;

import android.graphics.Bitmap;
import android.graphics.PixelFormat;
import android.opengl.EGL14;
@@ -72,14 +75,13 @@ final class ElectronBeam {
    private boolean mPrepared;
    private int mMode;

    private final Display mDisplay;
    private final DisplayInfo mDisplayInfo = new DisplayInfo();
    private final DisplayManagerService mDisplayManager;
    private int mDisplayLayerStack; // layer stack associated with primary display
    private int mDisplayRotation;
    private int mDisplayWidth;      // real width, not rotated
    private int mDisplayHeight;     // real height, not rotated
    private SurfaceSession mSurfaceSession;
    private Surface mSurface;
    private NaturalSurfaceLayout mSurfaceLayout;
    private EGLDisplay mEglDisplay;
    private EGLConfig mEglConfig;
    private EGLContext mEglContext;
@@ -111,8 +113,8 @@ final class ElectronBeam {
     */
    public static final int MODE_FADE = 2;

    public ElectronBeam(Display display) {
        mDisplay = display;
    public ElectronBeam(DisplayManagerService displayManager) {
        mDisplayManager = displayManager;
    }

    /**
@@ -129,18 +131,12 @@ final class ElectronBeam {

        mMode = mode;

        // Get the display size and adjust it for rotation.
        mDisplay.getDisplayInfo(mDisplayInfo);
        mDisplayLayerStack = mDisplay.getLayerStack();
        mDisplayRotation = mDisplayInfo.rotation;
        if (mDisplayRotation == Surface.ROTATION_90
                || mDisplayRotation == Surface.ROTATION_270) {
            mDisplayWidth = mDisplayInfo.logicalHeight;
            mDisplayHeight = mDisplayInfo.logicalWidth;
        } else {
            mDisplayWidth = mDisplayInfo.logicalWidth;
            mDisplayHeight = mDisplayInfo.logicalHeight;
        }
        // Get the display size and layer stack.
        // This is not expected to change while the electron beam surface is showing.
        DisplayInfo displayInfo = mDisplayManager.getDisplayInfo(Display.DEFAULT_DISPLAY);
        mDisplayLayerStack = displayInfo.layerStack;
        mDisplayWidth = displayInfo.getNaturalWidth();
        mDisplayHeight = displayInfo.getNaturalHeight();

        // Prepare the surface for drawing.
        if (!tryPrepare()) {
@@ -551,24 +547,8 @@ final class ElectronBeam {
            mSurface.setLayerStack(mDisplayLayerStack);
            mSurface.setSize(mDisplayWidth, mDisplayHeight);

            switch (mDisplayRotation) {
                case Surface.ROTATION_0:
                    mSurface.setPosition(0, 0);
                    mSurface.setMatrix(1, 0, 0, 1);
                    break;
                case Surface.ROTATION_90:
                    mSurface.setPosition(0, mDisplayWidth);
                    mSurface.setMatrix(0, -1, 1, 0);
                    break;
                case Surface.ROTATION_180:
                    mSurface.setPosition(mDisplayWidth, mDisplayHeight);
                    mSurface.setMatrix(-1, 0, 0, -1);
                    break;
                case Surface.ROTATION_270:
                    mSurface.setPosition(mDisplayHeight, 0);
                    mSurface.setMatrix(0, 1, -1, 0);
                    break;
            }
            mSurfaceLayout = new NaturalSurfaceLayout(mDisplayManager, mSurface);
            mSurfaceLayout.onDisplayTransaction();
        } finally {
            Surface.closeTransaction();
        }
@@ -601,6 +581,8 @@ final class ElectronBeam {

    private void destroySurface() {
        if (mSurface != null) {
            mSurfaceLayout.dispose();
            mSurfaceLayout = null;
            Surface.openTransaction();
            try {
                mSurface.destroy();
@@ -711,10 +693,63 @@ final class ElectronBeam {
        pw.println("  mPrepared=" + mPrepared);
        pw.println("  mMode=" + mMode);
        pw.println("  mDisplayLayerStack=" + mDisplayLayerStack);
        pw.println("  mDisplayRotation=" + mDisplayRotation);
        pw.println("  mDisplayWidth=" + mDisplayWidth);
        pw.println("  mDisplayHeight=" + mDisplayHeight);
        pw.println("  mSurfaceVisible=" + mSurfaceVisible);
        pw.println("  mSurfaceAlpha=" + mSurfaceAlpha);
    }

    /**
     * Keeps a surface aligned with the natural orientation of the device.
     * Updates the position and transformation of the matrix whenever the display
     * is rotated.  This is a little tricky because the display transaction
     * callback can be invoked on any thread, not necessarily the thread that
     * owns the electron beam.
     */
    private static final class NaturalSurfaceLayout implements DisplayTransactionListener {
        private final DisplayManagerService mDisplayManager;
        private Surface mSurface;

        public NaturalSurfaceLayout(DisplayManagerService displayManager, Surface surface) {
            mDisplayManager = displayManager;
            mSurface = surface;
            mDisplayManager.registerDisplayTransactionListener(this);
        }

        public void dispose() {
            synchronized (this) {
                mSurface = null;
            }
            mDisplayManager.unregisterDisplayTransactionListener(this);
        }

        @Override
        public void onDisplayTransaction() {
            synchronized (this) {
                if (mSurface == null) {
                    return;
                }

                DisplayInfo displayInfo = mDisplayManager.getDisplayInfo(Display.DEFAULT_DISPLAY);
                switch (displayInfo.rotation) {
                    case Surface.ROTATION_0:
                        mSurface.setPosition(0, 0);
                        mSurface.setMatrix(1, 0, 0, 1);
                        break;
                    case Surface.ROTATION_90:
                        mSurface.setPosition(0, displayInfo.logicalHeight);
                        mSurface.setMatrix(0, -1, 1, 0);
                        break;
                    case Surface.ROTATION_180:
                        mSurface.setPosition(displayInfo.logicalWidth, displayInfo.logicalHeight);
                        mSurface.setMatrix(-1, 0, 0, -1);
                        break;
                    case Surface.ROTATION_270:
                        mSurface.setPosition(displayInfo.logicalWidth, 0);
                        mSurface.setMatrix(0, 1, -1, 0);
                        break;
                }
            }
        }
    }
}
Loading