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

Commit b7ce6be9 authored by Kenneth Ford's avatar Kenneth Ford Committed by Android (Google) Code Review
Browse files

Merge changes from topic "concurrent-extensions"

* changes:
  Fix CTS test on devices not supporting concurrent display
  Creates implementation for Concurrent displays
parents adc6f3b8 195aad55
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -6210,6 +6210,18 @@
         different from the home screen wallpaper. -->
    <bool name="config_independentLockscreenLiveWallpaper">false</bool>

    <!-- Device state that corresponds to concurrent display mode where the default display
         is the internal display. Public API for the feature is provided through Jetpack
         WindowManager.
         TODO(b/236022708) Move concurrent display state to device state config file
    -->
    <integer name="config_deviceStateConcurrentRearDisplay">-1</integer>

    <!-- Physical display address that corresponds to the rear display in rear display mode
         and concurrent display mode. Used to get information about the display before
         entering the corresponding modes -->
    <string name="config_rearDisplayPhysicalAddress" translatable="false"></string>

    <!-- List of certificate to be used for font fs-verity integrity verification -->
    <string-array translatable="false" name="config_fontManagerServiceCerts">
    </string-array>
+2 −0
Original line number Diff line number Diff line
@@ -4907,6 +4907,8 @@
  <java-symbol type="string" name="concurrent_display_notification_thermal_content"/>
  <java-symbol type="string" name="device_state_notification_turn_off_button"/>
  <java-symbol type="bool" name="config_independentLockscreenLiveWallpaper"/>
  <java-symbol type="integer" name="config_deviceStateConcurrentRearDisplay" />
  <java-symbol type="string" name="config_rearDisplayPhysicalAddress" />

  <!-- For app language picker -->
  <java-symbol type="string" name="system_locale_title" />
+68 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 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 androidx.window.extensions.area;

import android.app.Presentation;
import android.content.Context;
import android.view.Display;
import android.view.View;

import androidx.annotation.NonNull;
import androidx.window.extensions.core.util.function.Consumer;

/**
 * {@link Presentation} object that is used to present extra content
 * on the rear facing display when in a rear display presentation feature.
 */
class RearDisplayPresentation extends Presentation implements ExtensionWindowAreaPresentation {

    @NonNull
    private final Consumer<@WindowAreaComponent.WindowAreaSessionState Integer> mStateConsumer;

    RearDisplayPresentation(@NonNull Context outerContext, @NonNull Display display,
            @NonNull Consumer<@WindowAreaComponent.WindowAreaSessionState Integer> stateConsumer) {
        super(outerContext, display);
        mStateConsumer = stateConsumer;
    }

    /**
     * {@code mStateConsumer} is notified that their content is now visible when the
     * {@link Presentation} object is started. There is no comparable callback for
     * {@link WindowAreaComponent#SESSION_STATE_INVISIBLE} in {@link #onStop()} due to the
     * timing of when a {@link android.hardware.devicestate.DeviceStateRequest} is cancelled
     * ending rear display presentation mode happening before the {@link Presentation} is stopped.
     */
    @Override
    protected void onStart() {
        super.onStart();
        mStateConsumer.accept(WindowAreaComponent.SESSION_STATE_VISIBLE);
    }

    @NonNull
    @Override
    public Context getPresentationContext() {
        return getContext();
    }

    @Override
    public void setPresentationView(View view) {
        setContentView(view);
        if (!isShowing()) {
            show();
        }
    }
}
+100 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 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 androidx.window.extensions.area;

import static androidx.window.extensions.area.WindowAreaComponent.SESSION_STATE_ACTIVE;
import static androidx.window.extensions.area.WindowAreaComponent.SESSION_STATE_INACTIVE;

import android.content.Context;
import android.hardware.devicestate.DeviceStateRequest;
import android.hardware.display.DisplayManager;
import android.util.Log;
import android.view.Display;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.window.extensions.core.util.function.Consumer;

import java.util.Objects;

/**
 * Controller class that keeps track of the status of the device state request
 * to enable the rear display presentation feature. This controller notifies the session callback
 * when the state request is active, and notifies the callback when the request is canceled.
 *
 * Clients are notified via {@link Consumer} provided with
 * {@link androidx.window.extensions.area.WindowAreaComponent.WindowAreaStatus} values to signify
 * when the request becomes active and cancelled.
 */
class RearDisplayPresentationController implements DeviceStateRequest.Callback {

    private static final String TAG = "RearDisplayPresentationController";

    // Original context that requested to enable rear display presentation mode
    @NonNull
    private final Context mContext;
    @NonNull
    private final Consumer<@WindowAreaComponent.WindowAreaSessionState Integer> mStateConsumer;
    @Nullable
    private ExtensionWindowAreaPresentation mExtensionWindowAreaPresentation;
    @NonNull
    private final DisplayManager mDisplayManager;

    /**
     * Creates the RearDisplayPresentationController
     * @param context Originating {@link android.content.Context} that is initiating the rear
     *                display presentation session.
     * @param stateConsumer {@link Consumer} that will be notified that the session is active when
     *        the device state request is active and the session has been created. If the device
     *        state request is cancelled, the callback will be notified that the session has been
     *        ended. This could occur through a call to cancel the feature or if the device is
     *        manipulated in a way that cancels any device state override.
     */
    RearDisplayPresentationController(@NonNull Context context,
            @NonNull Consumer<@WindowAreaComponent.WindowAreaSessionState Integer> stateConsumer) {
        Objects.requireNonNull(context);
        Objects.requireNonNull(stateConsumer);

        mContext = context;
        mStateConsumer = stateConsumer;
        mDisplayManager = context.getSystemService(DisplayManager.class);
    }

    @Override
    public void onRequestActivated(@NonNull DeviceStateRequest request) {
        Display[] rearDisplays = mDisplayManager.getDisplays(DisplayManager.DISPLAY_CATEGORY_REAR);
        if (rearDisplays.length == 0) {
            mStateConsumer.accept(SESSION_STATE_INACTIVE);
            Log.e(TAG, "Rear display list should not be empty");
            return;
        }

        mExtensionWindowAreaPresentation =
                new RearDisplayPresentation(mContext, rearDisplays[0], mStateConsumer);
        mStateConsumer.accept(SESSION_STATE_ACTIVE);
    }

    @Override
    public void onRequestCanceled(@NonNull DeviceStateRequest request) {
        mStateConsumer.accept(SESSION_STATE_INACTIVE);
    }

    @Nullable
    public ExtensionWindowAreaPresentation getWindowAreaPresentation() {
        return mExtensionWindowAreaPresentation;
    }
}
+62 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 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 androidx.window.extensions.area;

import android.util.DisplayMetrics;

import androidx.annotation.NonNull;

/**
 * Class that provides information around the current status of a window area feature. Contains
 * the current {@link WindowAreaComponent.WindowAreaStatus} value corresponding to the
 * rear display presentation feature, as well as the {@link DisplayMetrics} for the rear facing
 * display.
 */
class RearDisplayPresentationStatus implements ExtensionWindowAreaStatus {

    @WindowAreaComponent.WindowAreaStatus
    private final int mWindowAreaStatus;

    @NonNull
    private final DisplayMetrics mDisplayMetrics;

    RearDisplayPresentationStatus(@WindowAreaComponent.WindowAreaStatus int status,
            @NonNull DisplayMetrics displayMetrics) {
        mWindowAreaStatus = status;
        mDisplayMetrics = displayMetrics;
    }

    /**
     * Returns the {@link androidx.window.extensions.area.WindowAreaComponent.WindowAreaStatus}
     * value that relates to the current status of a feature.
     */
    @Override
    @WindowAreaComponent.WindowAreaStatus
    public int getWindowAreaStatus() {
        return mWindowAreaStatus;
    }

    /**
     * Returns the {@link DisplayMetrics} that corresponds to the window area that a feature
     * interacts with. This is converted to size class information provided to developers.
     */
    @Override
    @NonNull
    public DisplayMetrics getWindowAreaDisplayMetrics() {
        return mDisplayMetrics;
    }
}
Loading