Loading libs/WindowManager/Jetpack/src/androidx/window/sidecar/SampleSidecarImpl.java→libs/WindowManager/Jetpack/src/androidx/window/sidecar/SidecarImpl.java +84 −19 Original line number Diff line number Diff line /* * Copyright (C) 2020 The Android Open Source Project * Copyright (C) 2024 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. Loading @@ -16,6 +16,7 @@ package androidx.window.sidecar; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.Activity; import android.app.Application; Loading @@ -23,8 +24,9 @@ import android.content.Context; import android.hardware.devicestate.DeviceStateManager; import android.os.Bundle; import android.os.IBinder; import android.util.ArraySet; import android.util.Log; import androidx.annotation.NonNull; import androidx.window.common.BaseDataProducer; import androidx.window.common.DeviceStateManagerFoldingFeatureProducer; import androidx.window.common.EmptyLifecycleCallbacksAdapter; Loading @@ -33,17 +35,27 @@ import androidx.window.common.layout.CommonFoldingFeature; import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.Set; /** * Reference implementation of androidx.window.sidecar OEM interface for use with * WindowManager Jetpack. * Basic implementation of the {@link SidecarInterface}. An OEM can choose to use it as the base * class for their implementation. */ class SampleSidecarImpl extends StubSidecar { class SidecarImpl implements SidecarInterface { private static final String TAG = "WindowManagerSidecar"; @Nullable private SidecarCallback mSidecarCallback; private final ArraySet<IBinder> mWindowLayoutChangeListenerTokens = new ArraySet<>(); private boolean mDeviceStateChangeListenerRegistered; @NonNull private List<CommonFoldingFeature> mStoredFeatures = new ArrayList<>(); SampleSidecarImpl(Context context) { SidecarImpl(Context context) { ((Application) context.getApplicationContext()) .registerActivityLifecycleCallbacks(new NotifyOnConfigurationChanged()); .registerActivityLifecycleCallbacks(new SidecarImpl.NotifyOnConfigurationChanged()); RawFoldingFeatureProducer settingsFeatureProducer = new RawFoldingFeatureProducer(context); BaseDataProducer<List<CommonFoldingFeature>> foldingFeatureProducer = new DeviceStateManagerFoldingFeatureProducer(context, Loading @@ -53,11 +65,46 @@ class SampleSidecarImpl extends StubSidecar { foldingFeatureProducer.addDataChangedCallback(this::onDisplayFeaturesChanged); } private void setStoredFeatures(List<CommonFoldingFeature> storedFeatures) { mStoredFeatures = storedFeatures; @NonNull @Override public SidecarDeviceState getDeviceState() { return SidecarHelper.calculateDeviceState(mStoredFeatures); } @NonNull @Override public SidecarWindowLayoutInfo getWindowLayoutInfo(@NonNull IBinder windowToken) { return SidecarHelper.calculateWindowLayoutInfo(windowToken, mStoredFeatures); } @Override public void setSidecarCallback(@NonNull SidecarCallback sidecarCallback) { mSidecarCallback = sidecarCallback; } @Override public void onWindowLayoutChangeListenerAdded(@NonNull IBinder iBinder) { mWindowLayoutChangeListenerTokens.add(iBinder); onListenersChanged(); } @Override public void onWindowLayoutChangeListenerRemoved(@NonNull IBinder iBinder) { mWindowLayoutChangeListenerTokens.remove(iBinder); onListenersChanged(); } @Override public void onDeviceStateListenersChanged(boolean isEmpty) { mDeviceStateChangeListenerRegistered = !isEmpty; onListenersChanged(); } private void setStoredFeatures(@NonNull List<CommonFoldingFeature> storedFeatures) { mStoredFeatures = Objects.requireNonNull(storedFeatures); } private void onDisplayFeaturesChanged(List<CommonFoldingFeature> storedFeatures) { private void onDisplayFeaturesChanged(@NonNull List<CommonFoldingFeature> storedFeatures) { setStoredFeatures(storedFeatures); updateDeviceState(getDeviceState()); for (IBinder windowToken : getWindowsListeningForLayoutChanges()) { Loading @@ -66,25 +113,43 @@ class SampleSidecarImpl extends StubSidecar { } } @NonNull @Override public SidecarDeviceState getDeviceState() { return SidecarHelper.calculateDeviceState(mStoredFeatures); void updateDeviceState(@NonNull SidecarDeviceState newState) { if (mSidecarCallback != null) { try { mSidecarCallback.onDeviceStateChanged(newState); } catch (AbstractMethodError e) { Log.e(TAG, "App is using an outdated Window Jetpack library", e); } } } void updateWindowLayout(@NonNull IBinder windowToken, @NonNull SidecarWindowLayoutInfo newLayout) { if (mSidecarCallback != null) { try { mSidecarCallback.onWindowLayoutChanged(windowToken, newLayout); } catch (AbstractMethodError e) { Log.e(TAG, "App is using an outdated Window Jetpack library", e); } } } @NonNull @Override public SidecarWindowLayoutInfo getWindowLayoutInfo(@NonNull IBinder windowToken) { return SidecarHelper.calculateWindowLayoutInfo(windowToken, mStoredFeatures); private Set<IBinder> getWindowsListeningForLayoutChanges() { return mWindowLayoutChangeListenerTokens; } @Override protected void onListenersChanged() { protected boolean hasListeners() { return !mWindowLayoutChangeListenerTokens.isEmpty() || mDeviceStateChangeListenerRegistered; } private void onListenersChanged() { if (hasListeners()) { onDisplayFeaturesChanged(mStoredFeatures); } } private final class NotifyOnConfigurationChanged extends EmptyLifecycleCallbacksAdapter { @Override public void onActivityCreated(@NonNull Activity activity, Loading libs/WindowManager/Jetpack/src/androidx/window/sidecar/SidecarProvider.java +1 −1 Original line number Diff line number Diff line Loading @@ -36,7 +36,7 @@ public class SidecarProvider { @Nullable public static SidecarInterface getSidecarImpl(Context context) { return isWindowExtensionsEnabled() ? new SampleSidecarImpl(context.getApplicationContext()) ? new SidecarImpl(context.getApplicationContext()) : null; } Loading libs/WindowManager/Jetpack/src/androidx/window/sidecar/StubSidecar.javadeleted 100644 → 0 +0 −96 Original line number Diff line number Diff line /* * Copyright (C) 2020 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.sidecar; import android.os.IBinder; import android.util.Log; import androidx.annotation.NonNull; import java.util.HashSet; import java.util.Set; /** * Basic implementation of the {@link SidecarInterface}. An OEM can choose to use it as the base * class for their implementation. */ abstract class StubSidecar implements SidecarInterface { private static final String TAG = "WindowManagerSidecar"; private SidecarCallback mSidecarCallback; final Set<IBinder> mWindowLayoutChangeListenerTokens = new HashSet<>(); private boolean mDeviceStateChangeListenerRegistered; StubSidecar() { } @Override public void setSidecarCallback(@NonNull SidecarCallback sidecarCallback) { this.mSidecarCallback = sidecarCallback; } @Override public void onWindowLayoutChangeListenerAdded(@NonNull IBinder iBinder) { this.mWindowLayoutChangeListenerTokens.add(iBinder); this.onListenersChanged(); } @Override public void onWindowLayoutChangeListenerRemoved(@NonNull IBinder iBinder) { this.mWindowLayoutChangeListenerTokens.remove(iBinder); this.onListenersChanged(); } @Override public void onDeviceStateListenersChanged(boolean isEmpty) { this.mDeviceStateChangeListenerRegistered = !isEmpty; this.onListenersChanged(); } void updateDeviceState(SidecarDeviceState newState) { if (this.mSidecarCallback != null) { try { mSidecarCallback.onDeviceStateChanged(newState); } catch (AbstractMethodError e) { Log.e(TAG, "App is using an outdated Window Jetpack library", e); } } } void updateWindowLayout(@NonNull IBinder windowToken, @NonNull SidecarWindowLayoutInfo newLayout) { if (this.mSidecarCallback != null) { try { mSidecarCallback.onWindowLayoutChanged(windowToken, newLayout); } catch (AbstractMethodError e) { Log.e(TAG, "App is using an outdated Window Jetpack library", e); } } } @NonNull Set<IBinder> getWindowsListeningForLayoutChanges() { return mWindowLayoutChangeListenerTokens; } protected boolean hasListeners() { return !mWindowLayoutChangeListenerTokens.isEmpty() || mDeviceStateChangeListenerRegistered; } protected abstract void onListenersChanged(); } Loading
libs/WindowManager/Jetpack/src/androidx/window/sidecar/SampleSidecarImpl.java→libs/WindowManager/Jetpack/src/androidx/window/sidecar/SidecarImpl.java +84 −19 Original line number Diff line number Diff line /* * Copyright (C) 2020 The Android Open Source Project * Copyright (C) 2024 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. Loading @@ -16,6 +16,7 @@ package androidx.window.sidecar; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.Activity; import android.app.Application; Loading @@ -23,8 +24,9 @@ import android.content.Context; import android.hardware.devicestate.DeviceStateManager; import android.os.Bundle; import android.os.IBinder; import android.util.ArraySet; import android.util.Log; import androidx.annotation.NonNull; import androidx.window.common.BaseDataProducer; import androidx.window.common.DeviceStateManagerFoldingFeatureProducer; import androidx.window.common.EmptyLifecycleCallbacksAdapter; Loading @@ -33,17 +35,27 @@ import androidx.window.common.layout.CommonFoldingFeature; import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.Set; /** * Reference implementation of androidx.window.sidecar OEM interface for use with * WindowManager Jetpack. * Basic implementation of the {@link SidecarInterface}. An OEM can choose to use it as the base * class for their implementation. */ class SampleSidecarImpl extends StubSidecar { class SidecarImpl implements SidecarInterface { private static final String TAG = "WindowManagerSidecar"; @Nullable private SidecarCallback mSidecarCallback; private final ArraySet<IBinder> mWindowLayoutChangeListenerTokens = new ArraySet<>(); private boolean mDeviceStateChangeListenerRegistered; @NonNull private List<CommonFoldingFeature> mStoredFeatures = new ArrayList<>(); SampleSidecarImpl(Context context) { SidecarImpl(Context context) { ((Application) context.getApplicationContext()) .registerActivityLifecycleCallbacks(new NotifyOnConfigurationChanged()); .registerActivityLifecycleCallbacks(new SidecarImpl.NotifyOnConfigurationChanged()); RawFoldingFeatureProducer settingsFeatureProducer = new RawFoldingFeatureProducer(context); BaseDataProducer<List<CommonFoldingFeature>> foldingFeatureProducer = new DeviceStateManagerFoldingFeatureProducer(context, Loading @@ -53,11 +65,46 @@ class SampleSidecarImpl extends StubSidecar { foldingFeatureProducer.addDataChangedCallback(this::onDisplayFeaturesChanged); } private void setStoredFeatures(List<CommonFoldingFeature> storedFeatures) { mStoredFeatures = storedFeatures; @NonNull @Override public SidecarDeviceState getDeviceState() { return SidecarHelper.calculateDeviceState(mStoredFeatures); } @NonNull @Override public SidecarWindowLayoutInfo getWindowLayoutInfo(@NonNull IBinder windowToken) { return SidecarHelper.calculateWindowLayoutInfo(windowToken, mStoredFeatures); } @Override public void setSidecarCallback(@NonNull SidecarCallback sidecarCallback) { mSidecarCallback = sidecarCallback; } @Override public void onWindowLayoutChangeListenerAdded(@NonNull IBinder iBinder) { mWindowLayoutChangeListenerTokens.add(iBinder); onListenersChanged(); } @Override public void onWindowLayoutChangeListenerRemoved(@NonNull IBinder iBinder) { mWindowLayoutChangeListenerTokens.remove(iBinder); onListenersChanged(); } @Override public void onDeviceStateListenersChanged(boolean isEmpty) { mDeviceStateChangeListenerRegistered = !isEmpty; onListenersChanged(); } private void setStoredFeatures(@NonNull List<CommonFoldingFeature> storedFeatures) { mStoredFeatures = Objects.requireNonNull(storedFeatures); } private void onDisplayFeaturesChanged(List<CommonFoldingFeature> storedFeatures) { private void onDisplayFeaturesChanged(@NonNull List<CommonFoldingFeature> storedFeatures) { setStoredFeatures(storedFeatures); updateDeviceState(getDeviceState()); for (IBinder windowToken : getWindowsListeningForLayoutChanges()) { Loading @@ -66,25 +113,43 @@ class SampleSidecarImpl extends StubSidecar { } } @NonNull @Override public SidecarDeviceState getDeviceState() { return SidecarHelper.calculateDeviceState(mStoredFeatures); void updateDeviceState(@NonNull SidecarDeviceState newState) { if (mSidecarCallback != null) { try { mSidecarCallback.onDeviceStateChanged(newState); } catch (AbstractMethodError e) { Log.e(TAG, "App is using an outdated Window Jetpack library", e); } } } void updateWindowLayout(@NonNull IBinder windowToken, @NonNull SidecarWindowLayoutInfo newLayout) { if (mSidecarCallback != null) { try { mSidecarCallback.onWindowLayoutChanged(windowToken, newLayout); } catch (AbstractMethodError e) { Log.e(TAG, "App is using an outdated Window Jetpack library", e); } } } @NonNull @Override public SidecarWindowLayoutInfo getWindowLayoutInfo(@NonNull IBinder windowToken) { return SidecarHelper.calculateWindowLayoutInfo(windowToken, mStoredFeatures); private Set<IBinder> getWindowsListeningForLayoutChanges() { return mWindowLayoutChangeListenerTokens; } @Override protected void onListenersChanged() { protected boolean hasListeners() { return !mWindowLayoutChangeListenerTokens.isEmpty() || mDeviceStateChangeListenerRegistered; } private void onListenersChanged() { if (hasListeners()) { onDisplayFeaturesChanged(mStoredFeatures); } } private final class NotifyOnConfigurationChanged extends EmptyLifecycleCallbacksAdapter { @Override public void onActivityCreated(@NonNull Activity activity, Loading
libs/WindowManager/Jetpack/src/androidx/window/sidecar/SidecarProvider.java +1 −1 Original line number Diff line number Diff line Loading @@ -36,7 +36,7 @@ public class SidecarProvider { @Nullable public static SidecarInterface getSidecarImpl(Context context) { return isWindowExtensionsEnabled() ? new SampleSidecarImpl(context.getApplicationContext()) ? new SidecarImpl(context.getApplicationContext()) : null; } Loading
libs/WindowManager/Jetpack/src/androidx/window/sidecar/StubSidecar.javadeleted 100644 → 0 +0 −96 Original line number Diff line number Diff line /* * Copyright (C) 2020 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.sidecar; import android.os.IBinder; import android.util.Log; import androidx.annotation.NonNull; import java.util.HashSet; import java.util.Set; /** * Basic implementation of the {@link SidecarInterface}. An OEM can choose to use it as the base * class for their implementation. */ abstract class StubSidecar implements SidecarInterface { private static final String TAG = "WindowManagerSidecar"; private SidecarCallback mSidecarCallback; final Set<IBinder> mWindowLayoutChangeListenerTokens = new HashSet<>(); private boolean mDeviceStateChangeListenerRegistered; StubSidecar() { } @Override public void setSidecarCallback(@NonNull SidecarCallback sidecarCallback) { this.mSidecarCallback = sidecarCallback; } @Override public void onWindowLayoutChangeListenerAdded(@NonNull IBinder iBinder) { this.mWindowLayoutChangeListenerTokens.add(iBinder); this.onListenersChanged(); } @Override public void onWindowLayoutChangeListenerRemoved(@NonNull IBinder iBinder) { this.mWindowLayoutChangeListenerTokens.remove(iBinder); this.onListenersChanged(); } @Override public void onDeviceStateListenersChanged(boolean isEmpty) { this.mDeviceStateChangeListenerRegistered = !isEmpty; this.onListenersChanged(); } void updateDeviceState(SidecarDeviceState newState) { if (this.mSidecarCallback != null) { try { mSidecarCallback.onDeviceStateChanged(newState); } catch (AbstractMethodError e) { Log.e(TAG, "App is using an outdated Window Jetpack library", e); } } } void updateWindowLayout(@NonNull IBinder windowToken, @NonNull SidecarWindowLayoutInfo newLayout) { if (this.mSidecarCallback != null) { try { mSidecarCallback.onWindowLayoutChanged(windowToken, newLayout); } catch (AbstractMethodError e) { Log.e(TAG, "App is using an outdated Window Jetpack library", e); } } } @NonNull Set<IBinder> getWindowsListeningForLayoutChanges() { return mWindowLayoutChangeListenerTokens; } protected boolean hasListeners() { return !mWindowLayoutChangeListenerTokens.isEmpty() || mDeviceStateChangeListenerRegistered; } protected abstract void onListenersChanged(); }