1 /* 2 * Copyright 2021 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 androidx.window.extensions.layout; 18 19 import android.app.Activity; 20 import android.content.Context; 21 import android.os.Bundle; 22 import android.view.Display; 23 24 import androidx.annotation.UiContext; 25 import androidx.window.extensions.RequiresVendorApiLevel; 26 import androidx.window.extensions.WindowExtensions; 27 import androidx.window.extensions.core.util.function.Consumer; 28 29 import org.jspecify.annotations.NonNull; 30 31 /** 32 * The interface definition that will be used by the WindowManager library to get custom 33 * OEM-provided information about the window that isn't covered by platform APIs. Exposes methods 34 * to listen to changes in the {@link WindowLayoutInfo}. A {@link WindowLayoutInfo} contains a list 35 * of {@link DisplayFeature}s. 36 * <p> 37 * Currently {@link FoldingFeature} is the only {@link DisplayFeature}. A {@link FoldingFeature} 38 * exposes the state of a hinge and the relative bounds within the window. Developers can 39 * optimize their UI to support a {@link FoldingFeature} by avoiding it and placing content in 40 * relevant logical areas. 41 * 42 * <p>This interface should be implemented by OEM and deployed to the target devices. 43 * @see WindowExtensions#getWindowLayoutComponent() 44 */ 45 public interface WindowLayoutComponent { 46 /** 47 * @deprecated Use {@link #addWindowLayoutInfoListener(Context, Consumer)} 48 * starting with vendor API level 2. Only used if 49 * {@link #addWindowLayoutInfoListener(Context, Consumer)} can't be 50 * called on vendor API level 1. 51 */ 52 @RequiresVendorApiLevel(level = 1, deprecatedSince = 2) 53 @Deprecated addWindowLayoutInfoListener(@onNull Activity activity, java.util.function.@NonNull Consumer<WindowLayoutInfo> consumer)54 void addWindowLayoutInfoListener(@NonNull Activity activity, 55 java.util.function.@NonNull Consumer<WindowLayoutInfo> consumer); 56 57 /** 58 * @deprecated Use {@link #removeWindowLayoutInfoListener(Consumer)} starting with 59 * vendor API level 2. Only used if {@link #removeWindowLayoutInfoListener(Consumer)} can't 60 * be called on vendor API level 1. 61 */ 62 @RequiresVendorApiLevel(level = 1, deprecatedSince = 2) 63 @Deprecated removeWindowLayoutInfoListener( java.util.function.@onNull Consumer<WindowLayoutInfo> consumer)64 void removeWindowLayoutInfoListener( 65 java.util.function.@NonNull Consumer<WindowLayoutInfo> consumer); 66 67 /** 68 * Adds a listener interested in receiving updates to {@link WindowLayoutInfo}. 69 * Use {@link WindowLayoutComponent#removeWindowLayoutInfoListener} to remove listener. 70 * <p> 71 * A {@link Context} or a Consumer instance can only be registered once. 72 * Registering the same {@link Context} or Consumer more than once will result in 73 * a noop. 74 * 75 * @param context a {@link UiContext} that corresponds to a window or an area on the 76 * screen - an {@link Activity}, a {@link Context} created with 77 * {@link Context#createWindowContext(Display, int, Bundle)}, or 78 * {@link android.inputmethodservice.InputMethodService}. 79 * @param consumer interested in receiving updates to {@link WindowLayoutInfo} 80 */ 81 @RequiresVendorApiLevel(level = 2) 82 @SuppressWarnings("PairedRegistration") 83 // The paired method for unregistering is also removeWindowLayoutInfoListener. addWindowLayoutInfoListener(@iContext @onNull Context context, @NonNull Consumer<WindowLayoutInfo> consumer)84 default void addWindowLayoutInfoListener(@UiContext @NonNull Context context, 85 @NonNull Consumer<WindowLayoutInfo> consumer) { 86 throw new UnsupportedOperationException("This method must not be called unless there is a" 87 + " corresponding override implementation on the device."); 88 } 89 90 /** 91 * Removes a listener no longer interested in receiving updates. 92 * 93 * @param consumer no longer interested in receiving updates to {@link WindowLayoutInfo} 94 */ 95 @RequiresVendorApiLevel(level = 2) removeWindowLayoutInfoListener(@onNull Consumer<WindowLayoutInfo> consumer)96 default void removeWindowLayoutInfoListener(@NonNull Consumer<WindowLayoutInfo> consumer) { 97 throw new UnsupportedOperationException("This method must not be called unless there is a" 98 + " corresponding override implementation on the device."); 99 } 100 101 /** 102 * Returns the {@link SupportedWindowFeatures} for the device. This value will not change 103 * over time. 104 * @see WindowLayoutComponent#addWindowLayoutInfoListener(Context, Consumer) to register a 105 * listener for features that impact the window. 106 */ 107 @RequiresVendorApiLevel(level = 6) getSupportedWindowFeatures()108 default @NonNull SupportedWindowFeatures getSupportedWindowFeatures() { 109 throw new UnsupportedOperationException("This method will not be called unless there is a" 110 + " corresponding override implementation on the device"); 111 } 112 113 /** 114 * Returns the current {@link WindowLayoutInfo} for the given {@link Context}. 115 * <p> 116 * This API provides a convenient way to access the current {@link WindowLayoutInfo} without 117 * registering a listener via {@link #addWindowLayoutInfoListener(Context, Consumer)}. It 118 * simplifies the retrieval of {@link WindowLayoutInfo} in scenarios like 119 * {@link Activity#onCreate(Bundle)}. 120 * 121 * @param context a {@link Context} that corresponds to a window or an area on the screen. 122 * This can be an {@link Activity}, a {@link Context} created with 123 * {@link Context#createWindowContext(Display, int, Bundle)}, or an 124 * {@link android.inputmethodservice.InputMethodService}. 125 * @return the current {@link WindowLayoutInfo} for the given {@link Context}. 126 */ 127 @RequiresVendorApiLevel(level = 9) getCurrentWindowLayoutInfo( @iContext @onNull Context context)128 default @NonNull WindowLayoutInfo getCurrentWindowLayoutInfo( 129 @UiContext @NonNull Context context) { 130 throw new UnsupportedOperationException("This method will not be called unless there is a" 131 + " corresponding override implementation on the device"); 132 } 133 } 134