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

Commit 61e21940 authored by Jeff Brown's avatar Jeff Brown Committed by Android Git Automerger
Browse files

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

* commit '7fcb5dc5':
  Pin electron beam surface to natural orientation.
parents dc5b21a5 7fcb5dc5
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