1 /* 2 * Copyright (C) 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; 18 19 import android.app.ActivityThread; 20 import android.app.Application; 21 import android.content.Context; 22 23 import androidx.annotation.NonNull; 24 import androidx.window.common.DeviceStateManagerFoldingFeatureProducer; 25 import androidx.window.common.RawFoldingFeatureProducer; 26 import androidx.window.extensions.area.WindowAreaComponent; 27 import androidx.window.extensions.area.WindowAreaComponentImpl; 28 import androidx.window.extensions.embedding.ActivityEmbeddingComponent; 29 import androidx.window.extensions.embedding.SplitController; 30 import androidx.window.extensions.layout.WindowLayoutComponent; 31 import androidx.window.extensions.layout.WindowLayoutComponentImpl; 32 33 import java.util.Objects; 34 35 36 /** 37 * The reference implementation of {@link WindowExtensions} that implements the initial API version. 38 */ 39 public class WindowExtensionsImpl implements WindowExtensions { 40 41 private final Object mLock = new Object(); 42 private volatile DeviceStateManagerFoldingFeatureProducer mFoldingFeatureProducer; 43 private volatile WindowLayoutComponentImpl mWindowLayoutComponent; 44 private volatile SplitController mSplitController; 45 private volatile WindowAreaComponent mWindowAreaComponent; 46 47 // TODO(b/241126279) Introduce constants to better version functionality 48 @Override getVendorApiLevel()49 public int getVendorApiLevel() { 50 return 4; 51 } 52 53 @NonNull getApplication()54 private Application getApplication() { 55 return Objects.requireNonNull(ActivityThread.currentApplication()); 56 } 57 58 @NonNull getFoldingFeatureProducer()59 private DeviceStateManagerFoldingFeatureProducer getFoldingFeatureProducer() { 60 if (mFoldingFeatureProducer == null) { 61 synchronized (mLock) { 62 if (mFoldingFeatureProducer == null) { 63 Context context = getApplication(); 64 RawFoldingFeatureProducer foldingFeatureProducer = 65 new RawFoldingFeatureProducer(context); 66 mFoldingFeatureProducer = 67 new DeviceStateManagerFoldingFeatureProducer(context, 68 foldingFeatureProducer); 69 } 70 } 71 } 72 return mFoldingFeatureProducer; 73 } 74 75 @NonNull getWindowLayoutComponentImpl()76 private WindowLayoutComponentImpl getWindowLayoutComponentImpl() { 77 if (mWindowLayoutComponent == null) { 78 synchronized (mLock) { 79 if (mWindowLayoutComponent == null) { 80 Context context = getApplication(); 81 DeviceStateManagerFoldingFeatureProducer producer = 82 getFoldingFeatureProducer(); 83 mWindowLayoutComponent = new WindowLayoutComponentImpl(context, producer); 84 } 85 } 86 } 87 return mWindowLayoutComponent; 88 } 89 90 /** 91 * Returns a reference implementation of {@link WindowLayoutComponent} if available, 92 * {@code null} otherwise. The implementation must match the API level reported in 93 * {@link WindowExtensions#getWindowLayoutComponent()}. 94 * @return {@link WindowLayoutComponent} OEM implementation 95 */ 96 @Override getWindowLayoutComponent()97 public WindowLayoutComponent getWindowLayoutComponent() { 98 return getWindowLayoutComponentImpl(); 99 } 100 101 /** 102 * Returns a reference implementation of {@link ActivityEmbeddingComponent} if available, 103 * {@code null} otherwise. The implementation must match the API level reported in 104 * {@link WindowExtensions#getWindowLayoutComponent()}. 105 * @return {@link ActivityEmbeddingComponent} OEM implementation. 106 */ 107 @NonNull getActivityEmbeddingComponent()108 public ActivityEmbeddingComponent getActivityEmbeddingComponent() { 109 if (mSplitController == null) { 110 synchronized (mLock) { 111 if (mSplitController == null) { 112 mSplitController = new SplitController( 113 getWindowLayoutComponentImpl(), 114 getFoldingFeatureProducer() 115 ); 116 } 117 } 118 } 119 return mSplitController; 120 } 121 122 /** 123 * Returns a reference implementation of {@link WindowAreaComponent} if available, 124 * {@code null} otherwise. The implementation must match the API level reported in 125 * {@link WindowExtensions#getWindowAreaComponent()}. 126 * @return {@link WindowAreaComponent} OEM implementation. 127 */ getWindowAreaComponent()128 public WindowAreaComponent getWindowAreaComponent() { 129 if (mWindowAreaComponent == null) { 130 synchronized (mLock) { 131 if (mWindowAreaComponent == null) { 132 Context context = ActivityThread.currentApplication(); 133 mWindowAreaComponent = 134 new WindowAreaComponentImpl(context); 135 } 136 } 137 } 138 return mWindowAreaComponent; 139 } 140 } 141