[go: nahoru, domu]

Separate window extension interfaces into different packages

The extension interface has to be updated to
androidx.window.extensions. However, an older version v01 was shipped
on some devices with androidx.window.sidecar package name and
slightly different interfaces. This CL separates the old and the
current versions into different modules, both of which are declared
as dependencies for the core module. To handle these different
version a new wrapper and abstraction was introduced in the core
module, and the ExtensionWindowBackend is provided with the correct
wrapper for available OEM implementation.

Test: androidx.window.ExtensionTest
Test: Manual, using sample on foldable device
Change-Id: I6f7c38512c63070fa97c910435ee41804041496f
diff --git a/buildSrc/src/main/kotlin/androidx/build/LibraryGroups.kt b/buildSrc/src/main/kotlin/androidx/build/LibraryGroups.kt
index a12cf75..49783c6 100644
--- a/buildSrc/src/main/kotlin/androidx/build/LibraryGroups.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/LibraryGroups.kt
@@ -105,7 +105,7 @@
     val VIEWPAGER2 = LibraryGroup("androidx.viewpager2", LibraryVersions.VIEWPAGER2)
     val WEAR = LibraryGroup("androidx.wear", LibraryVersions.WEAR)
     val WEBKIT = LibraryGroup("androidx.webkit", LibraryVersions.WEBKIT)
-    val WINDOW = LibraryGroup("androidx.window", LibraryVersions.WINDOW)
+    val WINDOW = LibraryGroup("androidx.window", null)
     val WORK = LibraryGroup("androidx.work", LibraryVersions.WORK)
 }
 
diff --git a/buildSrc/src/main/kotlin/androidx/build/LibraryVersions.kt b/buildSrc/src/main/kotlin/androidx/build/LibraryVersions.kt
index bc28d5c..abaddfb 100644
--- a/buildSrc/src/main/kotlin/androidx/build/LibraryVersions.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/LibraryVersions.kt
@@ -116,5 +116,6 @@
     val WEAR = Version("1.1.0-alpha01")
     val WEBKIT = Version("1.3.0-alpha01")
     val WINDOW = Version("1.0.0-alpha01")
+    val WINDOW_SIDECAR = Version("0.1.0-alpha01")
     val WORK = Version("2.4.0-alpha01")
 }
diff --git a/settings.gradle b/settings.gradle
index 2efa392..fd51011 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -285,6 +285,7 @@
 includeProject(":webkit:integration-tests:testapp", "webkit/integration-tests/testapp")
 includeProject(":window:window", "window/window")
 includeProject(":window:window-extensions", "window/window-extensions")
+includeProject(":window:window-sidecar", "window/window-sidecar")
 includeProject(":window:window-samples", "window/window-samples")
 includeProject(":work:work-runtime", "work/workmanager")
 includeProject(":work:work-gcm", "work/workmanager-gcm")
diff --git a/window/window-extensions/api/0.1.0-alpha01.txt b/window/window-extensions/api/0.1.0-alpha01.txt
deleted file mode 100644
index 6202473..0000000
--- a/window/window-extensions/api/0.1.0-alpha01.txt
+++ /dev/null
@@ -1,68 +0,0 @@
-// Signature format: 3.0
-package androidx.window.sidecar {
-
-  public class SidecarDeviceState {
-    ctor public SidecarDeviceState();
-    field public static final int POSTURE_CLOSED = 1; // 0x1
-    field public static final int POSTURE_FLIPPED = 4; // 0x4
-    field public static final int POSTURE_HALF_OPENED = 2; // 0x2
-    field public static final int POSTURE_OPENED = 3; // 0x3
-    field public static final int POSTURE_UNKNOWN = 0; // 0x0
-    field @androidx.window.sidecar.SidecarDeviceState.Posture public int posture;
-  }
-
-  @IntDef({androidx.window.sidecar.SidecarDeviceState.POSTURE_UNKNOWN, androidx.window.sidecar.SidecarDeviceState.POSTURE_CLOSED, androidx.window.sidecar.SidecarDeviceState.POSTURE_HALF_OPENED, androidx.window.sidecar.SidecarDeviceState.POSTURE_OPENED, androidx.window.sidecar.SidecarDeviceState.POSTURE_FLIPPED}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface SidecarDeviceState.Posture {
-  }
-
-  public class SidecarDisplayFeature {
-    ctor public SidecarDisplayFeature();
-    method public android.graphics.Rect getRect();
-    method @androidx.window.sidecar.SidecarDisplayFeature.Type public int getType();
-    method public void setRect(android.graphics.Rect);
-    method public void setType(@androidx.window.sidecar.SidecarDisplayFeature.Type int);
-    field public static final int TYPE_FOLD = 1; // 0x1
-    field public static final int TYPE_HINGE = 2; // 0x2
-  }
-
-  @IntDef({androidx.window.sidecar.SidecarDisplayFeature.TYPE_FOLD, androidx.window.sidecar.SidecarDisplayFeature.TYPE_HINGE}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface SidecarDisplayFeature.Type {
-  }
-
-  public interface SidecarInterface {
-    method public androidx.window.sidecar.SidecarDeviceState getDeviceState();
-    method public androidx.window.sidecar.SidecarWindowLayoutInfo getWindowLayoutInfo(android.os.IBinder);
-    method public void onDeviceStateListenersChanged(boolean);
-    method public void onWindowLayoutChangeListenerAdded(android.os.IBinder);
-    method public void onWindowLayoutChangeListenerRemoved(android.os.IBinder);
-    method public void setSidecarCallback(androidx.window.sidecar.SidecarInterface.SidecarCallback);
-  }
-
-  public static interface SidecarInterface.SidecarCallback {
-    method public void onDeviceStateChanged(androidx.window.sidecar.SidecarDeviceState);
-    method public void onWindowLayoutChanged(android.os.IBinder, androidx.window.sidecar.SidecarWindowLayoutInfo);
-  }
-
-  public class SidecarProvider {
-    method public static String? getApiVersion();
-    method public static androidx.window.sidecar.SidecarInterface? getSidecarImpl(android.content.Context);
-  }
-
-  public class SidecarWindowLayoutInfo {
-    ctor public SidecarWindowLayoutInfo();
-    field public java.util.List<androidx.window.sidecar.SidecarDisplayFeature!>? displayFeatures;
-  }
-
-  public abstract class StubSidecarImpl implements androidx.window.sidecar.SidecarInterface {
-    ctor public StubSidecarImpl();
-    method protected java.util.Set<android.os.IBinder!> getWindowsListeningForLayoutChanges();
-    method protected boolean hasListeners();
-    method public void onDeviceStateListenersChanged(boolean);
-    method protected abstract void onListenersChanged();
-    method public void onWindowLayoutChangeListenerAdded(android.os.IBinder);
-    method public void onWindowLayoutChangeListenerRemoved(android.os.IBinder);
-    method public void setSidecarCallback(androidx.window.sidecar.SidecarInterface.SidecarCallback);
-    method protected void updateDeviceState(androidx.window.sidecar.SidecarDeviceState);
-    method protected void updateWindowLayout(android.os.IBinder, androidx.window.sidecar.SidecarWindowLayoutInfo);
-  }
-
-}
-
diff --git a/window/window-extensions/api/1.0.0-alpha01.txt b/window/window-extensions/api/1.0.0-alpha01.txt
index 0420a14..ae6a4b9e 100644
--- a/window/window-extensions/api/1.0.0-alpha01.txt
+++ b/window/window-extensions/api/1.0.0-alpha01.txt
@@ -1,8 +1,8 @@
 // Signature format: 3.0
-package androidx.window.sidecar {
+package androidx.window.extensions {
 
-  public final class SidecarDeviceState {
-    ctor public SidecarDeviceState(int);
+  public class ExtensionDeviceState {
+    ctor public ExtensionDeviceState(int);
     method public int getPosture();
     field public static final int POSTURE_CLOSED = 1; // 0x1
     field public static final int POSTURE_FLIPPED = 4; // 0x4
@@ -11,36 +11,36 @@
     field public static final int POSTURE_UNKNOWN = 0; // 0x0
   }
 
-  public final class SidecarDisplayFeature {
-    ctor public SidecarDisplayFeature(android.graphics.Rect, int);
+  public class ExtensionDisplayFeature {
+    ctor public ExtensionDisplayFeature(android.graphics.Rect, int);
     method public android.graphics.Rect getBounds();
     method public int getType();
     field public static final int TYPE_FOLD = 1; // 0x1
     field public static final int TYPE_HINGE = 2; // 0x2
   }
 
-  public interface SidecarInterface {
-    method public androidx.window.sidecar.SidecarDeviceState getDeviceState();
-    method public androidx.window.sidecar.SidecarWindowLayoutInfo getWindowLayoutInfo(android.os.IBinder);
+  public interface ExtensionInterface {
+    method public androidx.window.extensions.ExtensionDeviceState getDeviceState();
+    method public androidx.window.extensions.ExtensionWindowLayoutInfo getWindowLayoutInfo(android.os.IBinder);
     method public void onDeviceStateListenersChanged(boolean);
     method public void onWindowLayoutChangeListenerAdded(android.os.IBinder);
     method public void onWindowLayoutChangeListenerRemoved(android.os.IBinder);
-    method public void setSidecarCallback(androidx.window.sidecar.SidecarInterface.SidecarCallback);
+    method public void setExtensionCallback(androidx.window.extensions.ExtensionInterface.ExtensionCallback);
   }
 
-  public static interface SidecarInterface.SidecarCallback {
-    method public void onDeviceStateChanged(androidx.window.sidecar.SidecarDeviceState);
-    method public void onWindowLayoutChanged(android.os.IBinder, androidx.window.sidecar.SidecarWindowLayoutInfo);
+  public static interface ExtensionInterface.ExtensionCallback {
+    method public void onDeviceStateChanged(androidx.window.extensions.ExtensionDeviceState);
+    method public void onWindowLayoutChanged(android.os.IBinder, androidx.window.extensions.ExtensionWindowLayoutInfo);
   }
 
-  public class SidecarProvider {
+  public class ExtensionProvider {
     method public static String? getApiVersion();
-    method public static androidx.window.sidecar.SidecarInterface? getSidecarImpl(android.content.Context);
+    method public static androidx.window.extensions.ExtensionInterface? getExtensionImpl(android.content.Context);
   }
 
-  public final class SidecarWindowLayoutInfo {
-    ctor public SidecarWindowLayoutInfo(java.util.List<androidx.window.sidecar.SidecarDisplayFeature!>);
-    method public java.util.List<androidx.window.sidecar.SidecarDisplayFeature!>? getDisplayFeatures();
+  public class ExtensionWindowLayoutInfo {
+    ctor public ExtensionWindowLayoutInfo(java.util.List<androidx.window.extensions.ExtensionDisplayFeature!>);
+    method public java.util.List<androidx.window.extensions.ExtensionDisplayFeature!>? getDisplayFeatures();
   }
 
 }
diff --git a/window/window-extensions/api/current.txt b/window/window-extensions/api/current.txt
index 0420a14..ae6a4b9e 100644
--- a/window/window-extensions/api/current.txt
+++ b/window/window-extensions/api/current.txt
@@ -1,8 +1,8 @@
 // Signature format: 3.0
-package androidx.window.sidecar {
+package androidx.window.extensions {
 
-  public final class SidecarDeviceState {
-    ctor public SidecarDeviceState(int);
+  public class ExtensionDeviceState {
+    ctor public ExtensionDeviceState(int);
     method public int getPosture();
     field public static final int POSTURE_CLOSED = 1; // 0x1
     field public static final int POSTURE_FLIPPED = 4; // 0x4
@@ -11,36 +11,36 @@
     field public static final int POSTURE_UNKNOWN = 0; // 0x0
   }
 
-  public final class SidecarDisplayFeature {
-    ctor public SidecarDisplayFeature(android.graphics.Rect, int);
+  public class ExtensionDisplayFeature {
+    ctor public ExtensionDisplayFeature(android.graphics.Rect, int);
     method public android.graphics.Rect getBounds();
     method public int getType();
     field public static final int TYPE_FOLD = 1; // 0x1
     field public static final int TYPE_HINGE = 2; // 0x2
   }
 
-  public interface SidecarInterface {
-    method public androidx.window.sidecar.SidecarDeviceState getDeviceState();
-    method public androidx.window.sidecar.SidecarWindowLayoutInfo getWindowLayoutInfo(android.os.IBinder);
+  public interface ExtensionInterface {
+    method public androidx.window.extensions.ExtensionDeviceState getDeviceState();
+    method public androidx.window.extensions.ExtensionWindowLayoutInfo getWindowLayoutInfo(android.os.IBinder);
     method public void onDeviceStateListenersChanged(boolean);
     method public void onWindowLayoutChangeListenerAdded(android.os.IBinder);
     method public void onWindowLayoutChangeListenerRemoved(android.os.IBinder);
-    method public void setSidecarCallback(androidx.window.sidecar.SidecarInterface.SidecarCallback);
+    method public void setExtensionCallback(androidx.window.extensions.ExtensionInterface.ExtensionCallback);
   }
 
-  public static interface SidecarInterface.SidecarCallback {
-    method public void onDeviceStateChanged(androidx.window.sidecar.SidecarDeviceState);
-    method public void onWindowLayoutChanged(android.os.IBinder, androidx.window.sidecar.SidecarWindowLayoutInfo);
+  public static interface ExtensionInterface.ExtensionCallback {
+    method public void onDeviceStateChanged(androidx.window.extensions.ExtensionDeviceState);
+    method public void onWindowLayoutChanged(android.os.IBinder, androidx.window.extensions.ExtensionWindowLayoutInfo);
   }
 
-  public class SidecarProvider {
+  public class ExtensionProvider {
     method public static String? getApiVersion();
-    method public static androidx.window.sidecar.SidecarInterface? getSidecarImpl(android.content.Context);
+    method public static androidx.window.extensions.ExtensionInterface? getExtensionImpl(android.content.Context);
   }
 
-  public final class SidecarWindowLayoutInfo {
-    ctor public SidecarWindowLayoutInfo(java.util.List<androidx.window.sidecar.SidecarDisplayFeature!>);
-    method public java.util.List<androidx.window.sidecar.SidecarDisplayFeature!>? getDisplayFeatures();
+  public class ExtensionWindowLayoutInfo {
+    ctor public ExtensionWindowLayoutInfo(java.util.List<androidx.window.extensions.ExtensionDisplayFeature!>);
+    method public java.util.List<androidx.window.extensions.ExtensionDisplayFeature!>? getDisplayFeatures();
   }
 
 }
diff --git a/window/window-extensions/api/public_plus_experimental_0.1.0-alpha01.txt b/window/window-extensions/api/public_plus_experimental_0.1.0-alpha01.txt
deleted file mode 100644
index 6202473..0000000
--- a/window/window-extensions/api/public_plus_experimental_0.1.0-alpha01.txt
+++ /dev/null
@@ -1,68 +0,0 @@
-// Signature format: 3.0
-package androidx.window.sidecar {
-
-  public class SidecarDeviceState {
-    ctor public SidecarDeviceState();
-    field public static final int POSTURE_CLOSED = 1; // 0x1
-    field public static final int POSTURE_FLIPPED = 4; // 0x4
-    field public static final int POSTURE_HALF_OPENED = 2; // 0x2
-    field public static final int POSTURE_OPENED = 3; // 0x3
-    field public static final int POSTURE_UNKNOWN = 0; // 0x0
-    field @androidx.window.sidecar.SidecarDeviceState.Posture public int posture;
-  }
-
-  @IntDef({androidx.window.sidecar.SidecarDeviceState.POSTURE_UNKNOWN, androidx.window.sidecar.SidecarDeviceState.POSTURE_CLOSED, androidx.window.sidecar.SidecarDeviceState.POSTURE_HALF_OPENED, androidx.window.sidecar.SidecarDeviceState.POSTURE_OPENED, androidx.window.sidecar.SidecarDeviceState.POSTURE_FLIPPED}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface SidecarDeviceState.Posture {
-  }
-
-  public class SidecarDisplayFeature {
-    ctor public SidecarDisplayFeature();
-    method public android.graphics.Rect getRect();
-    method @androidx.window.sidecar.SidecarDisplayFeature.Type public int getType();
-    method public void setRect(android.graphics.Rect);
-    method public void setType(@androidx.window.sidecar.SidecarDisplayFeature.Type int);
-    field public static final int TYPE_FOLD = 1; // 0x1
-    field public static final int TYPE_HINGE = 2; // 0x2
-  }
-
-  @IntDef({androidx.window.sidecar.SidecarDisplayFeature.TYPE_FOLD, androidx.window.sidecar.SidecarDisplayFeature.TYPE_HINGE}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface SidecarDisplayFeature.Type {
-  }
-
-  public interface SidecarInterface {
-    method public androidx.window.sidecar.SidecarDeviceState getDeviceState();
-    method public androidx.window.sidecar.SidecarWindowLayoutInfo getWindowLayoutInfo(android.os.IBinder);
-    method public void onDeviceStateListenersChanged(boolean);
-    method public void onWindowLayoutChangeListenerAdded(android.os.IBinder);
-    method public void onWindowLayoutChangeListenerRemoved(android.os.IBinder);
-    method public void setSidecarCallback(androidx.window.sidecar.SidecarInterface.SidecarCallback);
-  }
-
-  public static interface SidecarInterface.SidecarCallback {
-    method public void onDeviceStateChanged(androidx.window.sidecar.SidecarDeviceState);
-    method public void onWindowLayoutChanged(android.os.IBinder, androidx.window.sidecar.SidecarWindowLayoutInfo);
-  }
-
-  public class SidecarProvider {
-    method public static String? getApiVersion();
-    method public static androidx.window.sidecar.SidecarInterface? getSidecarImpl(android.content.Context);
-  }
-
-  public class SidecarWindowLayoutInfo {
-    ctor public SidecarWindowLayoutInfo();
-    field public java.util.List<androidx.window.sidecar.SidecarDisplayFeature!>? displayFeatures;
-  }
-
-  public abstract class StubSidecarImpl implements androidx.window.sidecar.SidecarInterface {
-    ctor public StubSidecarImpl();
-    method protected java.util.Set<android.os.IBinder!> getWindowsListeningForLayoutChanges();
-    method protected boolean hasListeners();
-    method public void onDeviceStateListenersChanged(boolean);
-    method protected abstract void onListenersChanged();
-    method public void onWindowLayoutChangeListenerAdded(android.os.IBinder);
-    method public void onWindowLayoutChangeListenerRemoved(android.os.IBinder);
-    method public void setSidecarCallback(androidx.window.sidecar.SidecarInterface.SidecarCallback);
-    method protected void updateDeviceState(androidx.window.sidecar.SidecarDeviceState);
-    method protected void updateWindowLayout(android.os.IBinder, androidx.window.sidecar.SidecarWindowLayoutInfo);
-  }
-
-}
-
diff --git a/window/window-extensions/api/public_plus_experimental_1.0.0-alpha01.txt b/window/window-extensions/api/public_plus_experimental_1.0.0-alpha01.txt
index 0420a14..ae6a4b9e 100644
--- a/window/window-extensions/api/public_plus_experimental_1.0.0-alpha01.txt
+++ b/window/window-extensions/api/public_plus_experimental_1.0.0-alpha01.txt
@@ -1,8 +1,8 @@
 // Signature format: 3.0
-package androidx.window.sidecar {
+package androidx.window.extensions {
 
-  public final class SidecarDeviceState {
-    ctor public SidecarDeviceState(int);
+  public class ExtensionDeviceState {
+    ctor public ExtensionDeviceState(int);
     method public int getPosture();
     field public static final int POSTURE_CLOSED = 1; // 0x1
     field public static final int POSTURE_FLIPPED = 4; // 0x4
@@ -11,36 +11,36 @@
     field public static final int POSTURE_UNKNOWN = 0; // 0x0
   }
 
-  public final class SidecarDisplayFeature {
-    ctor public SidecarDisplayFeature(android.graphics.Rect, int);
+  public class ExtensionDisplayFeature {
+    ctor public ExtensionDisplayFeature(android.graphics.Rect, int);
     method public android.graphics.Rect getBounds();
     method public int getType();
     field public static final int TYPE_FOLD = 1; // 0x1
     field public static final int TYPE_HINGE = 2; // 0x2
   }
 
-  public interface SidecarInterface {
-    method public androidx.window.sidecar.SidecarDeviceState getDeviceState();
-    method public androidx.window.sidecar.SidecarWindowLayoutInfo getWindowLayoutInfo(android.os.IBinder);
+  public interface ExtensionInterface {
+    method public androidx.window.extensions.ExtensionDeviceState getDeviceState();
+    method public androidx.window.extensions.ExtensionWindowLayoutInfo getWindowLayoutInfo(android.os.IBinder);
     method public void onDeviceStateListenersChanged(boolean);
     method public void onWindowLayoutChangeListenerAdded(android.os.IBinder);
     method public void onWindowLayoutChangeListenerRemoved(android.os.IBinder);
-    method public void setSidecarCallback(androidx.window.sidecar.SidecarInterface.SidecarCallback);
+    method public void setExtensionCallback(androidx.window.extensions.ExtensionInterface.ExtensionCallback);
   }
 
-  public static interface SidecarInterface.SidecarCallback {
-    method public void onDeviceStateChanged(androidx.window.sidecar.SidecarDeviceState);
-    method public void onWindowLayoutChanged(android.os.IBinder, androidx.window.sidecar.SidecarWindowLayoutInfo);
+  public static interface ExtensionInterface.ExtensionCallback {
+    method public void onDeviceStateChanged(androidx.window.extensions.ExtensionDeviceState);
+    method public void onWindowLayoutChanged(android.os.IBinder, androidx.window.extensions.ExtensionWindowLayoutInfo);
   }
 
-  public class SidecarProvider {
+  public class ExtensionProvider {
     method public static String? getApiVersion();
-    method public static androidx.window.sidecar.SidecarInterface? getSidecarImpl(android.content.Context);
+    method public static androidx.window.extensions.ExtensionInterface? getExtensionImpl(android.content.Context);
   }
 
-  public final class SidecarWindowLayoutInfo {
-    ctor public SidecarWindowLayoutInfo(java.util.List<androidx.window.sidecar.SidecarDisplayFeature!>);
-    method public java.util.List<androidx.window.sidecar.SidecarDisplayFeature!>? getDisplayFeatures();
+  public class ExtensionWindowLayoutInfo {
+    ctor public ExtensionWindowLayoutInfo(java.util.List<androidx.window.extensions.ExtensionDisplayFeature!>);
+    method public java.util.List<androidx.window.extensions.ExtensionDisplayFeature!>? getDisplayFeatures();
   }
 
 }
diff --git a/window/window-extensions/api/public_plus_experimental_current.txt b/window/window-extensions/api/public_plus_experimental_current.txt
index 0420a14..ae6a4b9e 100644
--- a/window/window-extensions/api/public_plus_experimental_current.txt
+++ b/window/window-extensions/api/public_plus_experimental_current.txt
@@ -1,8 +1,8 @@
 // Signature format: 3.0
-package androidx.window.sidecar {
+package androidx.window.extensions {
 
-  public final class SidecarDeviceState {
-    ctor public SidecarDeviceState(int);
+  public class ExtensionDeviceState {
+    ctor public ExtensionDeviceState(int);
     method public int getPosture();
     field public static final int POSTURE_CLOSED = 1; // 0x1
     field public static final int POSTURE_FLIPPED = 4; // 0x4
@@ -11,36 +11,36 @@
     field public static final int POSTURE_UNKNOWN = 0; // 0x0
   }
 
-  public final class SidecarDisplayFeature {
-    ctor public SidecarDisplayFeature(android.graphics.Rect, int);
+  public class ExtensionDisplayFeature {
+    ctor public ExtensionDisplayFeature(android.graphics.Rect, int);
     method public android.graphics.Rect getBounds();
     method public int getType();
     field public static final int TYPE_FOLD = 1; // 0x1
     field public static final int TYPE_HINGE = 2; // 0x2
   }
 
-  public interface SidecarInterface {
-    method public androidx.window.sidecar.SidecarDeviceState getDeviceState();
-    method public androidx.window.sidecar.SidecarWindowLayoutInfo getWindowLayoutInfo(android.os.IBinder);
+  public interface ExtensionInterface {
+    method public androidx.window.extensions.ExtensionDeviceState getDeviceState();
+    method public androidx.window.extensions.ExtensionWindowLayoutInfo getWindowLayoutInfo(android.os.IBinder);
     method public void onDeviceStateListenersChanged(boolean);
     method public void onWindowLayoutChangeListenerAdded(android.os.IBinder);
     method public void onWindowLayoutChangeListenerRemoved(android.os.IBinder);
-    method public void setSidecarCallback(androidx.window.sidecar.SidecarInterface.SidecarCallback);
+    method public void setExtensionCallback(androidx.window.extensions.ExtensionInterface.ExtensionCallback);
   }
 
-  public static interface SidecarInterface.SidecarCallback {
-    method public void onDeviceStateChanged(androidx.window.sidecar.SidecarDeviceState);
-    method public void onWindowLayoutChanged(android.os.IBinder, androidx.window.sidecar.SidecarWindowLayoutInfo);
+  public static interface ExtensionInterface.ExtensionCallback {
+    method public void onDeviceStateChanged(androidx.window.extensions.ExtensionDeviceState);
+    method public void onWindowLayoutChanged(android.os.IBinder, androidx.window.extensions.ExtensionWindowLayoutInfo);
   }
 
-  public class SidecarProvider {
+  public class ExtensionProvider {
     method public static String? getApiVersion();
-    method public static androidx.window.sidecar.SidecarInterface? getSidecarImpl(android.content.Context);
+    method public static androidx.window.extensions.ExtensionInterface? getExtensionImpl(android.content.Context);
   }
 
-  public final class SidecarWindowLayoutInfo {
-    ctor public SidecarWindowLayoutInfo(java.util.List<androidx.window.sidecar.SidecarDisplayFeature!>);
-    method public java.util.List<androidx.window.sidecar.SidecarDisplayFeature!>? getDisplayFeatures();
+  public class ExtensionWindowLayoutInfo {
+    ctor public ExtensionWindowLayoutInfo(java.util.List<androidx.window.extensions.ExtensionDisplayFeature!>);
+    method public java.util.List<androidx.window.extensions.ExtensionDisplayFeature!>? getDisplayFeatures();
   }
 
 }
diff --git a/window/window-extensions/api/restricted_0.1.0-alpha01.txt b/window/window-extensions/api/restricted_0.1.0-alpha01.txt
deleted file mode 100644
index 6202473..0000000
--- a/window/window-extensions/api/restricted_0.1.0-alpha01.txt
+++ /dev/null
@@ -1,68 +0,0 @@
-// Signature format: 3.0
-package androidx.window.sidecar {
-
-  public class SidecarDeviceState {
-    ctor public SidecarDeviceState();
-    field public static final int POSTURE_CLOSED = 1; // 0x1
-    field public static final int POSTURE_FLIPPED = 4; // 0x4
-    field public static final int POSTURE_HALF_OPENED = 2; // 0x2
-    field public static final int POSTURE_OPENED = 3; // 0x3
-    field public static final int POSTURE_UNKNOWN = 0; // 0x0
-    field @androidx.window.sidecar.SidecarDeviceState.Posture public int posture;
-  }
-
-  @IntDef({androidx.window.sidecar.SidecarDeviceState.POSTURE_UNKNOWN, androidx.window.sidecar.SidecarDeviceState.POSTURE_CLOSED, androidx.window.sidecar.SidecarDeviceState.POSTURE_HALF_OPENED, androidx.window.sidecar.SidecarDeviceState.POSTURE_OPENED, androidx.window.sidecar.SidecarDeviceState.POSTURE_FLIPPED}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface SidecarDeviceState.Posture {
-  }
-
-  public class SidecarDisplayFeature {
-    ctor public SidecarDisplayFeature();
-    method public android.graphics.Rect getRect();
-    method @androidx.window.sidecar.SidecarDisplayFeature.Type public int getType();
-    method public void setRect(android.graphics.Rect);
-    method public void setType(@androidx.window.sidecar.SidecarDisplayFeature.Type int);
-    field public static final int TYPE_FOLD = 1; // 0x1
-    field public static final int TYPE_HINGE = 2; // 0x2
-  }
-
-  @IntDef({androidx.window.sidecar.SidecarDisplayFeature.TYPE_FOLD, androidx.window.sidecar.SidecarDisplayFeature.TYPE_HINGE}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface SidecarDisplayFeature.Type {
-  }
-
-  public interface SidecarInterface {
-    method public androidx.window.sidecar.SidecarDeviceState getDeviceState();
-    method public androidx.window.sidecar.SidecarWindowLayoutInfo getWindowLayoutInfo(android.os.IBinder);
-    method public void onDeviceStateListenersChanged(boolean);
-    method public void onWindowLayoutChangeListenerAdded(android.os.IBinder);
-    method public void onWindowLayoutChangeListenerRemoved(android.os.IBinder);
-    method public void setSidecarCallback(androidx.window.sidecar.SidecarInterface.SidecarCallback);
-  }
-
-  public static interface SidecarInterface.SidecarCallback {
-    method public void onDeviceStateChanged(androidx.window.sidecar.SidecarDeviceState);
-    method public void onWindowLayoutChanged(android.os.IBinder, androidx.window.sidecar.SidecarWindowLayoutInfo);
-  }
-
-  public class SidecarProvider {
-    method public static String? getApiVersion();
-    method public static androidx.window.sidecar.SidecarInterface? getSidecarImpl(android.content.Context);
-  }
-
-  public class SidecarWindowLayoutInfo {
-    ctor public SidecarWindowLayoutInfo();
-    field public java.util.List<androidx.window.sidecar.SidecarDisplayFeature!>? displayFeatures;
-  }
-
-  public abstract class StubSidecarImpl implements androidx.window.sidecar.SidecarInterface {
-    ctor public StubSidecarImpl();
-    method protected java.util.Set<android.os.IBinder!> getWindowsListeningForLayoutChanges();
-    method protected boolean hasListeners();
-    method public void onDeviceStateListenersChanged(boolean);
-    method protected abstract void onListenersChanged();
-    method public void onWindowLayoutChangeListenerAdded(android.os.IBinder);
-    method public void onWindowLayoutChangeListenerRemoved(android.os.IBinder);
-    method public void setSidecarCallback(androidx.window.sidecar.SidecarInterface.SidecarCallback);
-    method protected void updateDeviceState(androidx.window.sidecar.SidecarDeviceState);
-    method protected void updateWindowLayout(android.os.IBinder, androidx.window.sidecar.SidecarWindowLayoutInfo);
-  }
-
-}
-
diff --git a/window/window-extensions/api/restricted_1.0.0-alpha01.txt b/window/window-extensions/api/restricted_1.0.0-alpha01.txt
index 0420a14..ae6a4b9e 100644
--- a/window/window-extensions/api/restricted_1.0.0-alpha01.txt
+++ b/window/window-extensions/api/restricted_1.0.0-alpha01.txt
@@ -1,8 +1,8 @@
 // Signature format: 3.0
-package androidx.window.sidecar {
+package androidx.window.extensions {
 
-  public final class SidecarDeviceState {
-    ctor public SidecarDeviceState(int);
+  public class ExtensionDeviceState {
+    ctor public ExtensionDeviceState(int);
     method public int getPosture();
     field public static final int POSTURE_CLOSED = 1; // 0x1
     field public static final int POSTURE_FLIPPED = 4; // 0x4
@@ -11,36 +11,36 @@
     field public static final int POSTURE_UNKNOWN = 0; // 0x0
   }
 
-  public final class SidecarDisplayFeature {
-    ctor public SidecarDisplayFeature(android.graphics.Rect, int);
+  public class ExtensionDisplayFeature {
+    ctor public ExtensionDisplayFeature(android.graphics.Rect, int);
     method public android.graphics.Rect getBounds();
     method public int getType();
     field public static final int TYPE_FOLD = 1; // 0x1
     field public static final int TYPE_HINGE = 2; // 0x2
   }
 
-  public interface SidecarInterface {
-    method public androidx.window.sidecar.SidecarDeviceState getDeviceState();
-    method public androidx.window.sidecar.SidecarWindowLayoutInfo getWindowLayoutInfo(android.os.IBinder);
+  public interface ExtensionInterface {
+    method public androidx.window.extensions.ExtensionDeviceState getDeviceState();
+    method public androidx.window.extensions.ExtensionWindowLayoutInfo getWindowLayoutInfo(android.os.IBinder);
     method public void onDeviceStateListenersChanged(boolean);
     method public void onWindowLayoutChangeListenerAdded(android.os.IBinder);
     method public void onWindowLayoutChangeListenerRemoved(android.os.IBinder);
-    method public void setSidecarCallback(androidx.window.sidecar.SidecarInterface.SidecarCallback);
+    method public void setExtensionCallback(androidx.window.extensions.ExtensionInterface.ExtensionCallback);
   }
 
-  public static interface SidecarInterface.SidecarCallback {
-    method public void onDeviceStateChanged(androidx.window.sidecar.SidecarDeviceState);
-    method public void onWindowLayoutChanged(android.os.IBinder, androidx.window.sidecar.SidecarWindowLayoutInfo);
+  public static interface ExtensionInterface.ExtensionCallback {
+    method public void onDeviceStateChanged(androidx.window.extensions.ExtensionDeviceState);
+    method public void onWindowLayoutChanged(android.os.IBinder, androidx.window.extensions.ExtensionWindowLayoutInfo);
   }
 
-  public class SidecarProvider {
+  public class ExtensionProvider {
     method public static String? getApiVersion();
-    method public static androidx.window.sidecar.SidecarInterface? getSidecarImpl(android.content.Context);
+    method public static androidx.window.extensions.ExtensionInterface? getExtensionImpl(android.content.Context);
   }
 
-  public final class SidecarWindowLayoutInfo {
-    ctor public SidecarWindowLayoutInfo(java.util.List<androidx.window.sidecar.SidecarDisplayFeature!>);
-    method public java.util.List<androidx.window.sidecar.SidecarDisplayFeature!>? getDisplayFeatures();
+  public class ExtensionWindowLayoutInfo {
+    ctor public ExtensionWindowLayoutInfo(java.util.List<androidx.window.extensions.ExtensionDisplayFeature!>);
+    method public java.util.List<androidx.window.extensions.ExtensionDisplayFeature!>? getDisplayFeatures();
   }
 
 }
diff --git a/window/window-extensions/api/restricted_current.txt b/window/window-extensions/api/restricted_current.txt
index 0420a14..ae6a4b9e 100644
--- a/window/window-extensions/api/restricted_current.txt
+++ b/window/window-extensions/api/restricted_current.txt
@@ -1,8 +1,8 @@
 // Signature format: 3.0
-package androidx.window.sidecar {
+package androidx.window.extensions {
 
-  public final class SidecarDeviceState {
-    ctor public SidecarDeviceState(int);
+  public class ExtensionDeviceState {
+    ctor public ExtensionDeviceState(int);
     method public int getPosture();
     field public static final int POSTURE_CLOSED = 1; // 0x1
     field public static final int POSTURE_FLIPPED = 4; // 0x4
@@ -11,36 +11,36 @@
     field public static final int POSTURE_UNKNOWN = 0; // 0x0
   }
 
-  public final class SidecarDisplayFeature {
-    ctor public SidecarDisplayFeature(android.graphics.Rect, int);
+  public class ExtensionDisplayFeature {
+    ctor public ExtensionDisplayFeature(android.graphics.Rect, int);
     method public android.graphics.Rect getBounds();
     method public int getType();
     field public static final int TYPE_FOLD = 1; // 0x1
     field public static final int TYPE_HINGE = 2; // 0x2
   }
 
-  public interface SidecarInterface {
-    method public androidx.window.sidecar.SidecarDeviceState getDeviceState();
-    method public androidx.window.sidecar.SidecarWindowLayoutInfo getWindowLayoutInfo(android.os.IBinder);
+  public interface ExtensionInterface {
+    method public androidx.window.extensions.ExtensionDeviceState getDeviceState();
+    method public androidx.window.extensions.ExtensionWindowLayoutInfo getWindowLayoutInfo(android.os.IBinder);
     method public void onDeviceStateListenersChanged(boolean);
     method public void onWindowLayoutChangeListenerAdded(android.os.IBinder);
     method public void onWindowLayoutChangeListenerRemoved(android.os.IBinder);
-    method public void setSidecarCallback(androidx.window.sidecar.SidecarInterface.SidecarCallback);
+    method public void setExtensionCallback(androidx.window.extensions.ExtensionInterface.ExtensionCallback);
   }
 
-  public static interface SidecarInterface.SidecarCallback {
-    method public void onDeviceStateChanged(androidx.window.sidecar.SidecarDeviceState);
-    method public void onWindowLayoutChanged(android.os.IBinder, androidx.window.sidecar.SidecarWindowLayoutInfo);
+  public static interface ExtensionInterface.ExtensionCallback {
+    method public void onDeviceStateChanged(androidx.window.extensions.ExtensionDeviceState);
+    method public void onWindowLayoutChanged(android.os.IBinder, androidx.window.extensions.ExtensionWindowLayoutInfo);
   }
 
-  public class SidecarProvider {
+  public class ExtensionProvider {
     method public static String? getApiVersion();
-    method public static androidx.window.sidecar.SidecarInterface? getSidecarImpl(android.content.Context);
+    method public static androidx.window.extensions.ExtensionInterface? getExtensionImpl(android.content.Context);
   }
 
-  public final class SidecarWindowLayoutInfo {
-    ctor public SidecarWindowLayoutInfo(java.util.List<androidx.window.sidecar.SidecarDisplayFeature!>);
-    method public java.util.List<androidx.window.sidecar.SidecarDisplayFeature!>? getDisplayFeatures();
+  public class ExtensionWindowLayoutInfo {
+    ctor public ExtensionWindowLayoutInfo(java.util.List<androidx.window.extensions.ExtensionDisplayFeature!>);
+    method public java.util.List<androidx.window.extensions.ExtensionDisplayFeature!>? getDisplayFeatures();
   }
 
 }
diff --git a/window/window-extensions/build.gradle b/window/window-extensions/build.gradle
index c431957..19b52ab 100644
--- a/window/window-extensions/build.gradle
+++ b/window/window-extensions/build.gradle
@@ -40,6 +40,7 @@
     name = "Jetpack WindowManager library Extensions"
     publish = Publish.SNAPSHOT_AND_RELEASE
     mavenGroup = LibraryGroups.WINDOW
+    mavenVersion = LibraryVersions.WINDOW
     inceptionYear = "2020"
     description = "OEM extension interface definition for the Jetpack WindowManager. This module " +
             "declares the interface the the 'Core' component of this library will use when " +
diff --git a/window/window-extensions/src/main/AndroidManifest.xml b/window/window-extensions/src/main/AndroidManifest.xml
index 7a16a48..3c7e1ea 100644
--- a/window/window-extensions/src/main/AndroidManifest.xml
+++ b/window/window-extensions/src/main/AndroidManifest.xml
@@ -14,4 +14,4 @@
   limitations under the License.
   -->
 
-<manifest package="androidx.window.sidecar" />
+<manifest package="androidx.window.extensions" />
diff --git a/window/window-extensions/src/main/java/androidx/window/sidecar/SidecarDeviceState.java b/window/window-extensions/src/main/java/androidx/window/extensions/ExtensionDeviceState.java
similarity index 87%
rename from window/window-extensions/src/main/java/androidx/window/sidecar/SidecarDeviceState.java
rename to window/window-extensions/src/main/java/androidx/window/extensions/ExtensionDeviceState.java
index 1bac24f..899463c 100644
--- a/window/window-extensions/src/main/java/androidx/window/sidecar/SidecarDeviceState.java
+++ b/window/window-extensions/src/main/java/androidx/window/extensions/ExtensionDeviceState.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package androidx.window.sidecar;
+package androidx.window.extensions;
 
 import androidx.annotation.IntDef;
 import androidx.annotation.Nullable;
@@ -26,7 +26,7 @@
  * Information about the current state of the device.
  * <p>Currently only includes the description of the state for foldable devices.
  */
-public final class SidecarDeviceState {
+public class ExtensionDeviceState {
 
     /**
      * The current posture of the foldable device.
@@ -50,7 +50,7 @@
     })
     @interface Posture{}
 
-    public SidecarDeviceState(@Posture int posture) {
+    public ExtensionDeviceState(@Posture int posture) {
         mPosture = posture;
     }
 
@@ -67,10 +67,11 @@
         if (this == obj) {
             return true;
         }
-        if (!(obj instanceof SidecarDeviceState)) {
+        if (!(obj instanceof ExtensionDeviceState)) {
             return false;
         }
-        final SidecarDeviceState other = (SidecarDeviceState) obj;
+        final ExtensionDeviceState
+                other = (ExtensionDeviceState) obj;
         return other.mPosture == mPosture;
     }
 
diff --git a/window/window-extensions/src/main/java/androidx/window/sidecar/SidecarDisplayFeature.java b/window/window-extensions/src/main/java/androidx/window/extensions/ExtensionDisplayFeature.java
similarity index 88%
rename from window/window-extensions/src/main/java/androidx/window/sidecar/SidecarDisplayFeature.java
rename to window/window-extensions/src/main/java/androidx/window/extensions/ExtensionDisplayFeature.java
index e2f2984..90b0468 100644
--- a/window/window-extensions/src/main/java/androidx/window/sidecar/SidecarDisplayFeature.java
+++ b/window/window-extensions/src/main/java/androidx/window/extensions/ExtensionDisplayFeature.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package androidx.window.sidecar;
+package androidx.window.extensions;
 
 import android.graphics.Rect;
 
@@ -28,7 +28,7 @@
 /**
  * Description of a physical feature on the display.
  */
-public final class SidecarDisplayFeature {
+public class ExtensionDisplayFeature {
     /**
      * The bounding rectangle of the feature within the application window in the window
      * coordinate space.
@@ -59,7 +59,7 @@
     })
     @interface Type{}
 
-    public SidecarDisplayFeature(@NonNull Rect bounds, @Type int type) {
+    public ExtensionDisplayFeature(@NonNull Rect bounds, @Type int type) {
         mBounds = new Rect(bounds);
         mType = type;
     }
@@ -81,10 +81,11 @@
         if (this == obj) {
             return true;
         }
-        if (!(obj instanceof SidecarDisplayFeature)) {
+        if (!(obj instanceof ExtensionDisplayFeature)) {
             return false;
         }
-        final SidecarDisplayFeature other = (SidecarDisplayFeature) obj;
+        final ExtensionDisplayFeature
+                other = (ExtensionDisplayFeature) obj;
         if (mType != other.mType) {
             return false;
         }
diff --git a/window/window-extensions/src/main/java/androidx/window/extensions/ExtensionInterface.java b/window/window-extensions/src/main/java/androidx/window/extensions/ExtensionInterface.java
new file mode 100644
index 0000000..6b1720f
--- /dev/null
+++ b/window/window-extensions/src/main/java/androidx/window/extensions/ExtensionInterface.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright 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.extensions;
+
+import android.os.IBinder;
+
+import androidx.annotation.NonNull;
+
+/**
+ * Main Extension interface definition that will be used by the WindowManager library to get custom
+ * OEM-provided information that isn't covered by platform APIs.
+ *
+ * <p>This interface should be implemented by OEM and deployed to the target devices.
+ *
+ * @see ExtensionProvider
+ */
+public interface ExtensionInterface {
+
+    /**
+     * Register the support library as the callback for the extension. This interface will be used
+     * to report all extension changes to the support library.
+     */
+    void setExtensionCallback(@NonNull ExtensionCallback callback);
+
+    /**
+     * Get current information about the display features present within the application window.
+     */
+    @NonNull
+    ExtensionWindowLayoutInfo getWindowLayoutInfo(@NonNull IBinder windowToken);
+
+    /**
+     * Notify extension that a listener for display feature layout changes was registered for the
+     * given window token.
+     */
+    void onWindowLayoutChangeListenerAdded(@NonNull IBinder windowToken);
+
+    /**
+     * Notify extension that a listener for display feature layout changes was removed for the
+     * given window token.
+     */
+    void onWindowLayoutChangeListenerRemoved(@NonNull IBinder windowToken);
+
+    /**
+     * Get current device state.
+     * @see #onDeviceStateListenersChanged(boolean)
+     */
+    @NonNull
+    ExtensionDeviceState getDeviceState();
+
+    /**
+     * Notify the extension that a device state change listener was updated.
+     * @param isEmpty flag indicating if the list of device state change listeners is empty.
+     */
+    void onDeviceStateListenersChanged(boolean isEmpty);
+
+    /**
+     * Callback that will be registered with the WindowManager library, and that the extension
+     * should use to report all state changes.
+     */
+    interface ExtensionCallback {
+        /**
+         * Called by extension when the device state changes.
+         */
+        void onDeviceStateChanged(@NonNull ExtensionDeviceState newDeviceState);
+
+        /**
+         * Called by extension when the feature layout inside the window changes.
+         */
+        void onWindowLayoutChanged(@NonNull IBinder windowToken,
+                @NonNull ExtensionWindowLayoutInfo newLayout);
+    }
+}
diff --git a/window/window-extensions/src/main/java/androidx/window/sidecar/SidecarProvider.java b/window/window-extensions/src/main/java/androidx/window/extensions/ExtensionProvider.java
similarity index 79%
copy from window/window-extensions/src/main/java/androidx/window/sidecar/SidecarProvider.java
copy to window/window-extensions/src/main/java/androidx/window/extensions/ExtensionProvider.java
index e4539ca..46d213e 100644
--- a/window/window-extensions/src/main/java/androidx/window/sidecar/SidecarProvider.java
+++ b/window/window-extensions/src/main/java/androidx/window/extensions/ExtensionProvider.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package androidx.window.sidecar;
+package androidx.window.extensions;
 
 import android.content.Context;
 
@@ -22,25 +22,25 @@
 import androidx.annotation.Nullable;
 
 /**
- * A stub implementation for the class that will instantiate the Sidecar.
+ * A stub implementation for the class that will instantiate the Extension.
  *
  * <p>This class should be implemented by OEM and deployed to the target devices.
  *
- * @see SidecarInterface
+ * @see ExtensionInterface
  */
-public class SidecarProvider {
+public class ExtensionProvider {
 
-    private SidecarProvider() {}
+    private ExtensionProvider() {}
 
     /**
-     * Instantiate the Sidecar for the use by the WindowManager library.
+     * Instantiate the Extension for the use by the WindowManager library.
      *
      * <p>The library will instantiate the vendor implementation using this interface.
-     * @return A compatible version of the {@link SidecarInterface} for the provided library
+     * @return A compatible version of the {@link ExtensionInterface} for the provided library
      *         version string, or {@code null} if not available.
      */
     @Nullable
-    public static SidecarInterface getSidecarImpl(@NonNull Context context) {
+    public static ExtensionInterface getExtensionImpl(@NonNull Context context) {
         throw new UnsupportedOperationException("Stub, replace with implementation.");
     }
 
@@ -57,8 +57,8 @@
      * PATCH version when make backwards-compatible bug fixes.
      * And the description can be ignored.
      *
-     * <p>Vendor sidecar library should provide MAJOR.MINOR.PATCH to the WindowManager library. The
-     * MAJOR and MINOR version are used to identify the interface version that the library will
+     * <p>Vendor extension library should provide MAJOR.MINOR.PATCH to the WindowManager library.
+     * The MAJOR and MINOR version are used to identify the interface version that the library will
      * use. The PATCH version does not indicate compatibility. The patch version should be
      * incremented whenever the vendor library makes bug fixes or updates to the algorithm.
      *
diff --git a/window/window-extensions/src/main/java/androidx/window/sidecar/SidecarWindowLayoutInfo.java b/window/window-extensions/src/main/java/androidx/window/extensions/ExtensionWindowLayoutInfo.java
similarity index 77%
rename from window/window-extensions/src/main/java/androidx/window/sidecar/SidecarWindowLayoutInfo.java
rename to window/window-extensions/src/main/java/androidx/window/extensions/ExtensionWindowLayoutInfo.java
index 2284e51..2cd77a3 100644
--- a/window/window-extensions/src/main/java/androidx/window/sidecar/SidecarWindowLayoutInfo.java
+++ b/window/window-extensions/src/main/java/androidx/window/extensions/ExtensionWindowLayoutInfo.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package androidx.window.sidecar;
+package androidx.window.extensions;
 
 import android.os.IBinder;
 
@@ -26,18 +26,18 @@
 /**
  * Contains information about the layout of display features within the window.
  */
-public final class SidecarWindowLayoutInfo {
+public class ExtensionWindowLayoutInfo {
 
     /**
      * List of display features within the window.
      * <p>NOTE: All display features returned with this container must be cropped to the application
      * window and reported within the coordinate space of the window that was provided by the app.
-     * @see SidecarInterface#getWindowLayoutInfo(IBinder)
+     * @see ExtensionInterface#getWindowLayoutInfo(IBinder)
      */
     @Nullable
-    private List<SidecarDisplayFeature> mDisplayFeatures;
+    private List<ExtensionDisplayFeature> mDisplayFeatures;
 
-    public SidecarWindowLayoutInfo(@NonNull List<SidecarDisplayFeature> displayFeatures) {
+    public ExtensionWindowLayoutInfo(@NonNull List<ExtensionDisplayFeature> displayFeatures) {
         mDisplayFeatures = displayFeatures;
     }
 
@@ -45,7 +45,7 @@
      * Get the list of display features present within the window.
      */
     @Nullable
-    public List<SidecarDisplayFeature> getDisplayFeatures() {
+    public List<ExtensionDisplayFeature> getDisplayFeatures() {
         return mDisplayFeatures;
     }
 
@@ -54,10 +54,11 @@
         if (this == obj) {
             return true;
         }
-        if (!(obj instanceof SidecarWindowLayoutInfo)) {
+        if (!(obj instanceof ExtensionWindowLayoutInfo)) {
             return false;
         }
-        final SidecarWindowLayoutInfo other = (SidecarWindowLayoutInfo) obj;
+        final ExtensionWindowLayoutInfo
+                other = (ExtensionWindowLayoutInfo) obj;
         if (mDisplayFeatures == null) {
             return other.mDisplayFeatures == null;
         }
diff --git a/window/window-extensions/src/main/java/androidx/window/sidecar/StubSidecar.java b/window/window-extensions/src/main/java/androidx/window/extensions/StubExtension.java
similarity index 73%
rename from window/window-extensions/src/main/java/androidx/window/sidecar/StubSidecar.java
rename to window/window-extensions/src/main/java/androidx/window/extensions/StubExtension.java
index 6eaa16a..2846310 100644
--- a/window/window-extensions/src/main/java/androidx/window/sidecar/StubSidecar.java
+++ b/window/window-extensions/src/main/java/androidx/window/extensions/StubExtension.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package androidx.window.sidecar;
+package androidx.window.extensions;
 
 import android.os.IBinder;
 
@@ -24,17 +24,17 @@
 import java.util.Set;
 
 /**
- * Basic implementation of the {@link SidecarInterface}. An OEM can choose to use it as the base
+ * Basic implementation of the {@link ExtensionInterface}. An OEM can choose to use it as the base
  * class for their implementation.
  */
-abstract class StubSidecar implements SidecarInterface {
-    private SidecarCallback mSidecarCallback;
+abstract class StubExtension implements ExtensionInterface {
+    private ExtensionCallback mExtensionCallback;
     private final Set<IBinder> mWindowLayoutChangeListenerTokens = new HashSet<>();
     private boolean mDeviceStateChangeListenerRegistered;
 
     @Override
-    public void setSidecarCallback(@NonNull SidecarCallback callback) {
-        mSidecarCallback = callback;
+    public void setExtensionCallback(@NonNull ExtensionCallback callback) {
+        mExtensionCallback = callback;
     }
 
     @Override
@@ -55,16 +55,16 @@
         onListenersChanged();
     }
 
-    protected void updateDeviceState(@NonNull SidecarDeviceState newState) {
-        if (mSidecarCallback != null) {
-            mSidecarCallback.onDeviceStateChanged(newState);
+    protected void updateDeviceState(@NonNull ExtensionDeviceState newState) {
+        if (mExtensionCallback != null) {
+            mExtensionCallback.onDeviceStateChanged(newState);
         }
     }
 
     protected void updateWindowLayout(@NonNull IBinder windowToken,
-            @NonNull SidecarWindowLayoutInfo newLayout) {
-        if (mSidecarCallback != null) {
-            mSidecarCallback.onWindowLayoutChanged(windowToken, newLayout);
+            @NonNull ExtensionWindowLayoutInfo newLayout) {
+        if (mExtensionCallback != null) {
+            mExtensionCallback.onWindowLayoutChanged(windowToken, newLayout);
         }
     }
 
diff --git a/window/window-samples/build.gradle b/window/window-samples/build.gradle
index 2c9acfe..2ad139b 100644
--- a/window/window-samples/build.gradle
+++ b/window/window-samples/build.gradle
@@ -16,6 +16,7 @@
 
 
 import androidx.build.LibraryGroups
+import androidx.build.LibraryVersions
 import androidx.build.Publish
 
 import static androidx.build.dependencies.DependenciesKt.CONSTRAINT_LAYOUT
@@ -56,6 +57,7 @@
     name = "Jetpack WindowManager library samples"
     publish = Publish.NONE
     mavenGroup = LibraryGroups.WINDOW
+    mavenVersion = LibraryVersions.WINDOW
     inceptionYear = "2020"
     description = "Demo of Jetpack WindowManager library APIs"
 }
diff --git a/window/window-sidecar/api/0.1.0-alpha01.txt b/window/window-sidecar/api/0.1.0-alpha01.txt
new file mode 100644
index 0000000..e07df58
--- /dev/null
+++ b/window/window-sidecar/api/0.1.0-alpha01.txt
@@ -0,0 +1,49 @@
+// Signature format: 3.0
+package androidx.window.sidecar {
+
+  @Deprecated public final class SidecarDeviceState {
+    ctor @Deprecated public SidecarDeviceState();
+    field @Deprecated public static final int POSTURE_CLOSED = 1; // 0x1
+    field @Deprecated public static final int POSTURE_FLIPPED = 4; // 0x4
+    field @Deprecated public static final int POSTURE_HALF_OPENED = 2; // 0x2
+    field @Deprecated public static final int POSTURE_OPENED = 3; // 0x3
+    field @Deprecated public static final int POSTURE_UNKNOWN = 0; // 0x0
+    field @Deprecated public int posture;
+  }
+
+  @Deprecated public final class SidecarDisplayFeature {
+    ctor @Deprecated public SidecarDisplayFeature();
+    method @Deprecated public android.graphics.Rect getRect();
+    method @Deprecated public int getType();
+    method @Deprecated public void setRect(android.graphics.Rect);
+    method @Deprecated public void setType(int);
+    field @Deprecated public static final int TYPE_FOLD = 1; // 0x1
+    field @Deprecated public static final int TYPE_HINGE = 2; // 0x2
+  }
+
+  @Deprecated public interface SidecarInterface {
+    method @Deprecated public androidx.window.sidecar.SidecarDeviceState getDeviceState();
+    method @Deprecated public androidx.window.sidecar.SidecarWindowLayoutInfo getWindowLayoutInfo(android.os.IBinder);
+    method @Deprecated public void onDeviceStateListenersChanged(boolean);
+    method @Deprecated public void onWindowLayoutChangeListenerAdded(android.os.IBinder);
+    method @Deprecated public void onWindowLayoutChangeListenerRemoved(android.os.IBinder);
+    method @Deprecated public void setSidecarCallback(androidx.window.sidecar.SidecarInterface.SidecarCallback);
+  }
+
+  @Deprecated public static interface SidecarInterface.SidecarCallback {
+    method @Deprecated public void onDeviceStateChanged(androidx.window.sidecar.SidecarDeviceState);
+    method @Deprecated public void onWindowLayoutChanged(android.os.IBinder, androidx.window.sidecar.SidecarWindowLayoutInfo);
+  }
+
+  @Deprecated public class SidecarProvider {
+    method @Deprecated public static String? getApiVersion();
+    method @Deprecated public static androidx.window.sidecar.SidecarInterface? getSidecarImpl(android.content.Context);
+  }
+
+  @Deprecated public final class SidecarWindowLayoutInfo {
+    ctor @Deprecated public SidecarWindowLayoutInfo();
+    field @Deprecated public java.util.List<androidx.window.sidecar.SidecarDisplayFeature!>? displayFeatures;
+  }
+
+}
+
diff --git a/window/window-sidecar/api/api_lint.ignore b/window/window-sidecar/api/api_lint.ignore
new file mode 100644
index 0000000..7e925f9
--- /dev/null
+++ b/window/window-sidecar/api/api_lint.ignore
@@ -0,0 +1,5 @@
+// Baseline format: 1.0
+MutableBareField: androidx.window.sidecar.SidecarDeviceState#posture:
+    Bare field posture must be marked final, or moved behind accessors if mutable
+MutableBareField: androidx.window.sidecar.SidecarWindowLayoutInfo#displayFeatures:
+    Bare field displayFeatures must be marked final, or moved behind accessors if mutable
diff --git a/window/window-sidecar/api/current.txt b/window/window-sidecar/api/current.txt
new file mode 100644
index 0000000..e07df58
--- /dev/null
+++ b/window/window-sidecar/api/current.txt
@@ -0,0 +1,49 @@
+// Signature format: 3.0
+package androidx.window.sidecar {
+
+  @Deprecated public final class SidecarDeviceState {
+    ctor @Deprecated public SidecarDeviceState();
+    field @Deprecated public static final int POSTURE_CLOSED = 1; // 0x1
+    field @Deprecated public static final int POSTURE_FLIPPED = 4; // 0x4
+    field @Deprecated public static final int POSTURE_HALF_OPENED = 2; // 0x2
+    field @Deprecated public static final int POSTURE_OPENED = 3; // 0x3
+    field @Deprecated public static final int POSTURE_UNKNOWN = 0; // 0x0
+    field @Deprecated public int posture;
+  }
+
+  @Deprecated public final class SidecarDisplayFeature {
+    ctor @Deprecated public SidecarDisplayFeature();
+    method @Deprecated public android.graphics.Rect getRect();
+    method @Deprecated public int getType();
+    method @Deprecated public void setRect(android.graphics.Rect);
+    method @Deprecated public void setType(int);
+    field @Deprecated public static final int TYPE_FOLD = 1; // 0x1
+    field @Deprecated public static final int TYPE_HINGE = 2; // 0x2
+  }
+
+  @Deprecated public interface SidecarInterface {
+    method @Deprecated public androidx.window.sidecar.SidecarDeviceState getDeviceState();
+    method @Deprecated public androidx.window.sidecar.SidecarWindowLayoutInfo getWindowLayoutInfo(android.os.IBinder);
+    method @Deprecated public void onDeviceStateListenersChanged(boolean);
+    method @Deprecated public void onWindowLayoutChangeListenerAdded(android.os.IBinder);
+    method @Deprecated public void onWindowLayoutChangeListenerRemoved(android.os.IBinder);
+    method @Deprecated public void setSidecarCallback(androidx.window.sidecar.SidecarInterface.SidecarCallback);
+  }
+
+  @Deprecated public static interface SidecarInterface.SidecarCallback {
+    method @Deprecated public void onDeviceStateChanged(androidx.window.sidecar.SidecarDeviceState);
+    method @Deprecated public void onWindowLayoutChanged(android.os.IBinder, androidx.window.sidecar.SidecarWindowLayoutInfo);
+  }
+
+  @Deprecated public class SidecarProvider {
+    method @Deprecated public static String? getApiVersion();
+    method @Deprecated public static androidx.window.sidecar.SidecarInterface? getSidecarImpl(android.content.Context);
+  }
+
+  @Deprecated public final class SidecarWindowLayoutInfo {
+    ctor @Deprecated public SidecarWindowLayoutInfo();
+    field @Deprecated public java.util.List<androidx.window.sidecar.SidecarDisplayFeature!>? displayFeatures;
+  }
+
+}
+
diff --git a/window/window-sidecar/api/public_plus_experimental_0.1.0-alpha01.txt b/window/window-sidecar/api/public_plus_experimental_0.1.0-alpha01.txt
new file mode 100644
index 0000000..e07df58
--- /dev/null
+++ b/window/window-sidecar/api/public_plus_experimental_0.1.0-alpha01.txt
@@ -0,0 +1,49 @@
+// Signature format: 3.0
+package androidx.window.sidecar {
+
+  @Deprecated public final class SidecarDeviceState {
+    ctor @Deprecated public SidecarDeviceState();
+    field @Deprecated public static final int POSTURE_CLOSED = 1; // 0x1
+    field @Deprecated public static final int POSTURE_FLIPPED = 4; // 0x4
+    field @Deprecated public static final int POSTURE_HALF_OPENED = 2; // 0x2
+    field @Deprecated public static final int POSTURE_OPENED = 3; // 0x3
+    field @Deprecated public static final int POSTURE_UNKNOWN = 0; // 0x0
+    field @Deprecated public int posture;
+  }
+
+  @Deprecated public final class SidecarDisplayFeature {
+    ctor @Deprecated public SidecarDisplayFeature();
+    method @Deprecated public android.graphics.Rect getRect();
+    method @Deprecated public int getType();
+    method @Deprecated public void setRect(android.graphics.Rect);
+    method @Deprecated public void setType(int);
+    field @Deprecated public static final int TYPE_FOLD = 1; // 0x1
+    field @Deprecated public static final int TYPE_HINGE = 2; // 0x2
+  }
+
+  @Deprecated public interface SidecarInterface {
+    method @Deprecated public androidx.window.sidecar.SidecarDeviceState getDeviceState();
+    method @Deprecated public androidx.window.sidecar.SidecarWindowLayoutInfo getWindowLayoutInfo(android.os.IBinder);
+    method @Deprecated public void onDeviceStateListenersChanged(boolean);
+    method @Deprecated public void onWindowLayoutChangeListenerAdded(android.os.IBinder);
+    method @Deprecated public void onWindowLayoutChangeListenerRemoved(android.os.IBinder);
+    method @Deprecated public void setSidecarCallback(androidx.window.sidecar.SidecarInterface.SidecarCallback);
+  }
+
+  @Deprecated public static interface SidecarInterface.SidecarCallback {
+    method @Deprecated public void onDeviceStateChanged(androidx.window.sidecar.SidecarDeviceState);
+    method @Deprecated public void onWindowLayoutChanged(android.os.IBinder, androidx.window.sidecar.SidecarWindowLayoutInfo);
+  }
+
+  @Deprecated public class SidecarProvider {
+    method @Deprecated public static String? getApiVersion();
+    method @Deprecated public static androidx.window.sidecar.SidecarInterface? getSidecarImpl(android.content.Context);
+  }
+
+  @Deprecated public final class SidecarWindowLayoutInfo {
+    ctor @Deprecated public SidecarWindowLayoutInfo();
+    field @Deprecated public java.util.List<androidx.window.sidecar.SidecarDisplayFeature!>? displayFeatures;
+  }
+
+}
+
diff --git a/window/window-sidecar/api/public_plus_experimental_current.txt b/window/window-sidecar/api/public_plus_experimental_current.txt
new file mode 100644
index 0000000..e07df58
--- /dev/null
+++ b/window/window-sidecar/api/public_plus_experimental_current.txt
@@ -0,0 +1,49 @@
+// Signature format: 3.0
+package androidx.window.sidecar {
+
+  @Deprecated public final class SidecarDeviceState {
+    ctor @Deprecated public SidecarDeviceState();
+    field @Deprecated public static final int POSTURE_CLOSED = 1; // 0x1
+    field @Deprecated public static final int POSTURE_FLIPPED = 4; // 0x4
+    field @Deprecated public static final int POSTURE_HALF_OPENED = 2; // 0x2
+    field @Deprecated public static final int POSTURE_OPENED = 3; // 0x3
+    field @Deprecated public static final int POSTURE_UNKNOWN = 0; // 0x0
+    field @Deprecated public int posture;
+  }
+
+  @Deprecated public final class SidecarDisplayFeature {
+    ctor @Deprecated public SidecarDisplayFeature();
+    method @Deprecated public android.graphics.Rect getRect();
+    method @Deprecated public int getType();
+    method @Deprecated public void setRect(android.graphics.Rect);
+    method @Deprecated public void setType(int);
+    field @Deprecated public static final int TYPE_FOLD = 1; // 0x1
+    field @Deprecated public static final int TYPE_HINGE = 2; // 0x2
+  }
+
+  @Deprecated public interface SidecarInterface {
+    method @Deprecated public androidx.window.sidecar.SidecarDeviceState getDeviceState();
+    method @Deprecated public androidx.window.sidecar.SidecarWindowLayoutInfo getWindowLayoutInfo(android.os.IBinder);
+    method @Deprecated public void onDeviceStateListenersChanged(boolean);
+    method @Deprecated public void onWindowLayoutChangeListenerAdded(android.os.IBinder);
+    method @Deprecated public void onWindowLayoutChangeListenerRemoved(android.os.IBinder);
+    method @Deprecated public void setSidecarCallback(androidx.window.sidecar.SidecarInterface.SidecarCallback);
+  }
+
+  @Deprecated public static interface SidecarInterface.SidecarCallback {
+    method @Deprecated public void onDeviceStateChanged(androidx.window.sidecar.SidecarDeviceState);
+    method @Deprecated public void onWindowLayoutChanged(android.os.IBinder, androidx.window.sidecar.SidecarWindowLayoutInfo);
+  }
+
+  @Deprecated public class SidecarProvider {
+    method @Deprecated public static String? getApiVersion();
+    method @Deprecated public static androidx.window.sidecar.SidecarInterface? getSidecarImpl(android.content.Context);
+  }
+
+  @Deprecated public final class SidecarWindowLayoutInfo {
+    ctor @Deprecated public SidecarWindowLayoutInfo();
+    field @Deprecated public java.util.List<androidx.window.sidecar.SidecarDisplayFeature!>? displayFeatures;
+  }
+
+}
+
diff --git a/window/window-extensions/api/res-0.1.0-alpha01.txt b/window/window-sidecar/api/res-0.1.0-alpha01.txt
similarity index 100%
rename from window/window-extensions/api/res-0.1.0-alpha01.txt
rename to window/window-sidecar/api/res-0.1.0-alpha01.txt
diff --git a/window/window-sidecar/api/restricted_0.1.0-alpha01.txt b/window/window-sidecar/api/restricted_0.1.0-alpha01.txt
new file mode 100644
index 0000000..e07df58
--- /dev/null
+++ b/window/window-sidecar/api/restricted_0.1.0-alpha01.txt
@@ -0,0 +1,49 @@
+// Signature format: 3.0
+package androidx.window.sidecar {
+
+  @Deprecated public final class SidecarDeviceState {
+    ctor @Deprecated public SidecarDeviceState();
+    field @Deprecated public static final int POSTURE_CLOSED = 1; // 0x1
+    field @Deprecated public static final int POSTURE_FLIPPED = 4; // 0x4
+    field @Deprecated public static final int POSTURE_HALF_OPENED = 2; // 0x2
+    field @Deprecated public static final int POSTURE_OPENED = 3; // 0x3
+    field @Deprecated public static final int POSTURE_UNKNOWN = 0; // 0x0
+    field @Deprecated public int posture;
+  }
+
+  @Deprecated public final class SidecarDisplayFeature {
+    ctor @Deprecated public SidecarDisplayFeature();
+    method @Deprecated public android.graphics.Rect getRect();
+    method @Deprecated public int getType();
+    method @Deprecated public void setRect(android.graphics.Rect);
+    method @Deprecated public void setType(int);
+    field @Deprecated public static final int TYPE_FOLD = 1; // 0x1
+    field @Deprecated public static final int TYPE_HINGE = 2; // 0x2
+  }
+
+  @Deprecated public interface SidecarInterface {
+    method @Deprecated public androidx.window.sidecar.SidecarDeviceState getDeviceState();
+    method @Deprecated public androidx.window.sidecar.SidecarWindowLayoutInfo getWindowLayoutInfo(android.os.IBinder);
+    method @Deprecated public void onDeviceStateListenersChanged(boolean);
+    method @Deprecated public void onWindowLayoutChangeListenerAdded(android.os.IBinder);
+    method @Deprecated public void onWindowLayoutChangeListenerRemoved(android.os.IBinder);
+    method @Deprecated public void setSidecarCallback(androidx.window.sidecar.SidecarInterface.SidecarCallback);
+  }
+
+  @Deprecated public static interface SidecarInterface.SidecarCallback {
+    method @Deprecated public void onDeviceStateChanged(androidx.window.sidecar.SidecarDeviceState);
+    method @Deprecated public void onWindowLayoutChanged(android.os.IBinder, androidx.window.sidecar.SidecarWindowLayoutInfo);
+  }
+
+  @Deprecated public class SidecarProvider {
+    method @Deprecated public static String? getApiVersion();
+    method @Deprecated public static androidx.window.sidecar.SidecarInterface? getSidecarImpl(android.content.Context);
+  }
+
+  @Deprecated public final class SidecarWindowLayoutInfo {
+    ctor @Deprecated public SidecarWindowLayoutInfo();
+    field @Deprecated public java.util.List<androidx.window.sidecar.SidecarDisplayFeature!>? displayFeatures;
+  }
+
+}
+
diff --git a/window/window-sidecar/api/restricted_current.txt b/window/window-sidecar/api/restricted_current.txt
new file mode 100644
index 0000000..e07df58
--- /dev/null
+++ b/window/window-sidecar/api/restricted_current.txt
@@ -0,0 +1,49 @@
+// Signature format: 3.0
+package androidx.window.sidecar {
+
+  @Deprecated public final class SidecarDeviceState {
+    ctor @Deprecated public SidecarDeviceState();
+    field @Deprecated public static final int POSTURE_CLOSED = 1; // 0x1
+    field @Deprecated public static final int POSTURE_FLIPPED = 4; // 0x4
+    field @Deprecated public static final int POSTURE_HALF_OPENED = 2; // 0x2
+    field @Deprecated public static final int POSTURE_OPENED = 3; // 0x3
+    field @Deprecated public static final int POSTURE_UNKNOWN = 0; // 0x0
+    field @Deprecated public int posture;
+  }
+
+  @Deprecated public final class SidecarDisplayFeature {
+    ctor @Deprecated public SidecarDisplayFeature();
+    method @Deprecated public android.graphics.Rect getRect();
+    method @Deprecated public int getType();
+    method @Deprecated public void setRect(android.graphics.Rect);
+    method @Deprecated public void setType(int);
+    field @Deprecated public static final int TYPE_FOLD = 1; // 0x1
+    field @Deprecated public static final int TYPE_HINGE = 2; // 0x2
+  }
+
+  @Deprecated public interface SidecarInterface {
+    method @Deprecated public androidx.window.sidecar.SidecarDeviceState getDeviceState();
+    method @Deprecated public androidx.window.sidecar.SidecarWindowLayoutInfo getWindowLayoutInfo(android.os.IBinder);
+    method @Deprecated public void onDeviceStateListenersChanged(boolean);
+    method @Deprecated public void onWindowLayoutChangeListenerAdded(android.os.IBinder);
+    method @Deprecated public void onWindowLayoutChangeListenerRemoved(android.os.IBinder);
+    method @Deprecated public void setSidecarCallback(androidx.window.sidecar.SidecarInterface.SidecarCallback);
+  }
+
+  @Deprecated public static interface SidecarInterface.SidecarCallback {
+    method @Deprecated public void onDeviceStateChanged(androidx.window.sidecar.SidecarDeviceState);
+    method @Deprecated public void onWindowLayoutChanged(android.os.IBinder, androidx.window.sidecar.SidecarWindowLayoutInfo);
+  }
+
+  @Deprecated public class SidecarProvider {
+    method @Deprecated public static String? getApiVersion();
+    method @Deprecated public static androidx.window.sidecar.SidecarInterface? getSidecarImpl(android.content.Context);
+  }
+
+  @Deprecated public final class SidecarWindowLayoutInfo {
+    ctor @Deprecated public SidecarWindowLayoutInfo();
+    field @Deprecated public java.util.List<androidx.window.sidecar.SidecarDisplayFeature!>? displayFeatures;
+  }
+
+}
+
diff --git a/window/window-sidecar/build.gradle b/window/window-sidecar/build.gradle
new file mode 100644
index 0000000..930dca2
--- /dev/null
+++ b/window/window-sidecar/build.gradle
@@ -0,0 +1,47 @@
+/*
+ * Copyright 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.
+ */
+
+import androidx.build.LibraryGroups
+import androidx.build.LibraryVersions
+import androidx.build.Publish
+
+import static androidx.build.dependencies.DependenciesKt.AUTO_VALUE
+import static androidx.build.dependencies.DependenciesKt.AUTO_VALUE_ANNOTATIONS
+
+plugins {
+    id("AndroidXPlugin")
+    id("com.android.library")
+}
+
+android {
+    defaultConfig {
+        minSdkVersion 16
+    }
+}
+
+dependencies {
+    implementation("androidx.annotation:annotation:1.1.0")
+}
+
+androidx {
+    name = "Jetpack WindowManager library Sidecar"
+    publish = Publish.NONE
+    mavenGroup = LibraryGroups.WINDOW
+    mavenVersion = LibraryVersions.WINDOW_SIDECAR
+    inceptionYear = "2020"
+    description = "This version of the OEM extension is deprecated. Please use window-extensions " +
+            "module instead."
+}
diff --git a/window/window-sidecar/src/main/AndroidManifest.xml b/window/window-sidecar/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..7a16a48
--- /dev/null
+++ b/window/window-sidecar/src/main/AndroidManifest.xml
@@ -0,0 +1,17 @@
+<!--
+  Copyright 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.
+  -->
+
+<manifest package="androidx.window.sidecar" />
diff --git a/window/window-extensions/src/main/java/androidx/window/sidecar/SidecarDeviceState.java b/window/window-sidecar/src/main/java/androidx/window/sidecar/SidecarDeviceState.java
similarity index 64%
copy from window/window-extensions/src/main/java/androidx/window/sidecar/SidecarDeviceState.java
copy to window/window-sidecar/src/main/java/androidx/window/sidecar/SidecarDeviceState.java
index 1bac24f..fe72f88 100644
--- a/window/window-extensions/src/main/java/androidx/window/sidecar/SidecarDeviceState.java
+++ b/window/window-sidecar/src/main/java/androidx/window/sidecar/SidecarDeviceState.java
@@ -17,22 +17,22 @@
 package androidx.window.sidecar;
 
 import androidx.annotation.IntDef;
-import androidx.annotation.Nullable;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 
 /**
  * Information about the current state of the device.
- * <p>Currently only includes the description of the state for foldable devices.
+ * @deprecated Use androidx.window.extensions instead of this package.
  */
+@Deprecated
 public final class SidecarDeviceState {
 
     /**
      * The current posture of the foldable device.
      */
     @Posture
-    private final int mPosture;
+    public int posture;
 
     public static final int POSTURE_UNKNOWN = 0;
     public static final int POSTURE_CLOSED = 1;
@@ -49,33 +49,4 @@
             POSTURE_FLIPPED
     })
     @interface Posture{}
-
-    public SidecarDeviceState(@Posture int posture) {
-        mPosture = posture;
-    }
-
-    /**
-     * Get the current posture of the foldable device.
-     */
-    @Posture
-    public int getPosture() {
-        return mPosture;
-    }
-
-    @Override
-    public boolean equals(@Nullable Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (!(obj instanceof SidecarDeviceState)) {
-            return false;
-        }
-        final SidecarDeviceState other = (SidecarDeviceState) obj;
-        return other.mPosture == mPosture;
-    }
-
-    @Override
-    public int hashCode() {
-        return mPosture;
-    }
 }
diff --git a/window/window-extensions/src/main/java/androidx/window/sidecar/SidecarDisplayFeature.java b/window/window-sidecar/src/main/java/androidx/window/sidecar/SidecarDisplayFeature.java
similarity index 66%
copy from window/window-extensions/src/main/java/androidx/window/sidecar/SidecarDisplayFeature.java
copy to window/window-sidecar/src/main/java/androidx/window/sidecar/SidecarDisplayFeature.java
index e2f2984..015bc15 100644
--- a/window/window-extensions/src/main/java/androidx/window/sidecar/SidecarDisplayFeature.java
+++ b/window/window-sidecar/src/main/java/androidx/window/sidecar/SidecarDisplayFeature.java
@@ -20,27 +20,28 @@
 
 import androidx.annotation.IntDef;
 import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 
 /**
  * Description of a physical feature on the display.
+ * @deprecated Use androidx.window.extensions instead of this package.
  */
+@Deprecated
 public final class SidecarDisplayFeature {
     /**
      * The bounding rectangle of the feature within the application window in the window
      * coordinate space.
      */
     @NonNull
-    private final Rect mBounds;
+    private Rect mRect;
 
     /**
      * The physical type of the feature.
      */
     @Type
-    private final int mType;
+    private int mType;
 
     /**
      * A fold in the flexible screen without a physical gap.
@@ -59,42 +60,24 @@
     })
     @interface Type{}
 
-    public SidecarDisplayFeature(@NonNull Rect bounds, @Type int type) {
-        mBounds = new Rect(bounds);
-        mType = type;
-    }
-
     /** Get the bounding rect of the display feature in window coordinate space. */
     @NonNull
-    public Rect getBounds() {
-        return mBounds;
+    public Rect getRect() {
+        return mRect;
+    }
+
+    /** Set the bounding rect of the display feature in window coordinate space. */
+    public void setRect(@NonNull Rect rect) {
+        mRect.set(rect);
     }
 
     /** Get the type of the display feature. */
-    @Type
-    public int getType() {
+    public @Type int getType() {
         return mType;
     }
 
-    @Override
-    public boolean equals(@Nullable Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (!(obj instanceof SidecarDisplayFeature)) {
-            return false;
-        }
-        final SidecarDisplayFeature other = (SidecarDisplayFeature) obj;
-        if (mType != other.mType) {
-            return false;
-        }
-        return mBounds.equals(other.mBounds);
-    }
-
-    @Override
-    public int hashCode() {
-        int result = mType;
-        result = 31 * result + mBounds.centerX() + mBounds.centerY();
-        return result;
+    /** Set the type of the display feature. */
+    public void setType(@Type int type) {
+        mType = type;
     }
 }
diff --git a/window/window-extensions/src/main/java/androidx/window/sidecar/SidecarInterface.java b/window/window-sidecar/src/main/java/androidx/window/sidecar/SidecarInterface.java
similarity index 93%
rename from window/window-extensions/src/main/java/androidx/window/sidecar/SidecarInterface.java
rename to window/window-sidecar/src/main/java/androidx/window/sidecar/SidecarInterface.java
index 96bb871..3b90b27 100644
--- a/window/window-extensions/src/main/java/androidx/window/sidecar/SidecarInterface.java
+++ b/window/window-sidecar/src/main/java/androidx/window/sidecar/SidecarInterface.java
@@ -23,11 +23,9 @@
 /**
  * Main Sidecar interface definition that will be used by the WindowManager library to get custom
  * OEM-provided information that isn't covered by platform APIs.
- *
- * <p>This interface should be implemented by OEM and deployed to the target devices.
- *
- * @see SidecarProvider
+ * @deprecated Use androidx.window.extensions instead of this package.
  */
+@Deprecated
 public interface SidecarInterface {
 
     /**
@@ -70,7 +68,9 @@
     /**
      * Callback that will be registered with the WindowManager library, and that the sidecar should
      * use to report all state changes.
+     * @deprecated Use androidx.window.extensions instead of this package.
      */
+    @Deprecated
     interface SidecarCallback {
         /**
          * Called by sidecar when the device state changes.
diff --git a/window/window-extensions/src/main/java/androidx/window/sidecar/SidecarProvider.java b/window/window-sidecar/src/main/java/androidx/window/sidecar/SidecarProvider.java
similarity index 96%
rename from window/window-extensions/src/main/java/androidx/window/sidecar/SidecarProvider.java
rename to window/window-sidecar/src/main/java/androidx/window/sidecar/SidecarProvider.java
index e4539ca..701e16c 100644
--- a/window/window-extensions/src/main/java/androidx/window/sidecar/SidecarProvider.java
+++ b/window/window-sidecar/src/main/java/androidx/window/sidecar/SidecarProvider.java
@@ -23,11 +23,10 @@
 
 /**
  * A stub implementation for the class that will instantiate the Sidecar.
- *
- * <p>This class should be implemented by OEM and deployed to the target devices.
- *
  * @see SidecarInterface
+ * @deprecated Use androidx.window.extensions instead of this package.
  */
+@Deprecated
 public class SidecarProvider {
 
     private SidecarProvider() {}
diff --git a/window/window-sidecar/src/main/java/androidx/window/sidecar/SidecarWindowLayoutInfo.java b/window/window-sidecar/src/main/java/androidx/window/sidecar/SidecarWindowLayoutInfo.java
new file mode 100644
index 0000000..aebb615
--- /dev/null
+++ b/window/window-sidecar/src/main/java/androidx/window/sidecar/SidecarWindowLayoutInfo.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 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 androidx.annotation.Nullable;
+
+import java.util.List;
+
+/**
+ * Contains information about the layout of display features within the window.
+ * @deprecated Use androidx.window.extensions instead of this package.
+ */
+@Deprecated
+public final class SidecarWindowLayoutInfo {
+
+    /**
+     * List of display features within the window.
+     * <p>NOTE: All display features returned with this container must be cropped to the application
+     * window and reported within the coordinate space of the window that was provided by the app.
+     * @see SidecarInterface#getWindowLayoutInfo(IBinder)
+     */
+    @Nullable
+    public List<SidecarDisplayFeature> displayFeatures;
+}
diff --git a/window/window/build.gradle b/window/window/build.gradle
index 656013b..0350c25 100644
--- a/window/window/build.gradle
+++ b/window/window/build.gradle
@@ -41,6 +41,7 @@
     implementation "androidx.core:core:1.2.0"
 
     compileOnly(project(":window:window-extensions"))
+    compileOnly(project(":window:window-sidecar"))
 
     androidTestImplementation(ANDROIDX_TEST_EXT_JUNIT)
     androidTestImplementation(ANDROIDX_TEST_RUNNER)
@@ -53,7 +54,11 @@
     name = "Jetpack WindowManager Library"
     publish = Publish.SNAPSHOT_AND_RELEASE
     mavenGroup = LibraryGroups.WINDOW
+    mavenVersion = LibraryVersions.WINDOW
     inceptionYear = "2020"
     description = "WindowManager Jetpack library. Currently only provides additional " +
             "functionality on foldable devices."
+    // Suppressing deprecation warnings, since there is a need to maintain compatibility with old
+    // Sidecar interface.
+    failOnDeprecationWarnings = false
 }
diff --git a/window/window/src/androidTest/AndroidManifest.xml b/window/window/src/androidTest/AndroidManifest.xml
index c190f24..d5eba48 100644
--- a/window/window/src/androidTest/AndroidManifest.xml
+++ b/window/window/src/androidTest/AndroidManifest.xml
@@ -18,7 +18,7 @@
     package="androidx.window.test">
 
     <application>
-        <uses-library android:name="androidx.window.sidecar" android:required="false" />
+        <uses-library android:name="androidx.window.extension" android:required="false" />
 
         <activity android:name="androidx.window.TestActivity" />
         <activity android:name="androidx.window.TestConfigChangeHandlingActivity"
diff --git a/window/window/src/androidTest/java/androidx/window/SidecarTest.java b/window/window/src/androidTest/java/androidx/window/ExtensionTest.java
similarity index 60%
rename from window/window/src/androidTest/java/androidx/window/SidecarTest.java
rename to window/window/src/androidTest/java/androidx/window/ExtensionTest.java
index eb2421b..bafdd82 100644
--- a/window/window/src/androidTest/java/androidx/window/SidecarTest.java
+++ b/window/window/src/androidTest/java/androidx/window/ExtensionTest.java
@@ -21,15 +21,11 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
-import static org.hamcrest.CoreMatchers.equalTo;
-import static org.hamcrest.CoreMatchers.not;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
-import static org.junit.Assume.assumeNotNull;
-import static org.junit.Assume.assumeThat;
 import static org.junit.Assume.assumeTrue;
 
 import android.app.Activity;
@@ -43,10 +39,8 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.LargeTest;
 import androidx.test.rule.ActivityTestRule;
-import androidx.window.sidecar.SidecarDeviceState;
-import androidx.window.sidecar.SidecarDisplayFeature;
-import androidx.window.sidecar.SidecarInterface;
-import androidx.window.sidecar.SidecarWindowLayoutInfo;
+import androidx.window.extensions.ExtensionDeviceState;
+import androidx.window.extensions.ExtensionDisplayFeature;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -54,7 +48,7 @@
 
 @LargeTest
 @RunWith(AndroidJUnit4.class)
-public class SidecarTest {
+public class ExtensionTest {
 
     private Context mContext;
     private ActivityTestRule<TestActivity> mActivityTestRule =
@@ -68,66 +62,61 @@
     }
 
     @Test
-    public void testSidecarInterface() throws Exception {
-        assumeSidecarV10_V01();
-        SidecarInterface sidecar = SidecarHelper.getSidecarImpl(mContext);
-        assertTrue(SidecarHelper.validateSidecarInterface(sidecar,
-                SidecarHelper.getSidecarVersion()));
+    public void testExtensionInterface() throws Exception {
+        assumeExtensionV10_V01();
+        ExtensionInterfaceCompat extension = ExtensionHelper.getExtensionImpl(mContext);
+        assertTrue(extension.validateExtensionInterface());
     }
 
     @Test
     public void testGetDeviceState() throws Exception {
-        assumeSidecarV10_V01();
-        SidecarInterface sidecar = SidecarHelper.getSidecarImpl(mContext);
-        SidecarDeviceState sidecarDeviceState = sidecar.getDeviceState();
-        DeviceState deviceState = SidecarHelper.deviceStateFromSidecar(sidecarDeviceState);
+        assumeExtensionV10_V01();
+        ExtensionInterfaceCompat extension = ExtensionHelper.getExtensionImpl(mContext);
+        DeviceState deviceState = extension.getDeviceState();
 
-        assertThat(deviceState.getPosture()).isAtLeast(SidecarDeviceState.POSTURE_UNKNOWN);
-        assertThat(deviceState.getPosture()).isAtMost(SidecarDeviceState.POSTURE_FLIPPED);
+        assertThat(deviceState.getPosture()).isAtLeast(ExtensionDeviceState.POSTURE_UNKNOWN);
+        assertThat(deviceState.getPosture()).isAtMost(ExtensionDeviceState.POSTURE_FLIPPED);
     }
 
     @Test
     public void testRegisterDeviceStateChangeListener() throws Exception {
-        assumeSidecarV10_V01();
-        SidecarInterface sidecar = SidecarHelper.getSidecarImpl(mContext);
+        assumeExtensionV10_V01();
+        ExtensionInterfaceCompat extension = ExtensionHelper.getExtensionImpl(mContext);
 
-        sidecar.onDeviceStateListenersChanged(false);
-        sidecar.onDeviceStateListenersChanged(true);
+        extension.onDeviceStateListenersChanged(false);
+        extension.onDeviceStateListenersChanged(true);
     }
 
     @Test
     public void testDisplayFeatureDataClass() throws Exception {
-        assumeSidecarV10_V01();
+        assumeExtensionV10_V01();
 
         Rect rect = new Rect(1, 2, 3, 4);
         int type = 1;
-        SidecarDisplayFeature displayFeature = SidecarHelper.versionCompat()
-                .newSidecarDisplayFeature(rect, type);
-        assertEquals(rect, SidecarHelper.versionCompat().getFeatureBounds(displayFeature));
+        ExtensionDisplayFeature displayFeature = new ExtensionDisplayFeature(rect, type);
+        assertEquals(rect, displayFeature.getBounds());
         assertEquals(type, displayFeature.getType());
     }
 
     @Test
     public void testGetWindowLayoutInfo() throws Exception {
-        assumeSidecarV10_V01();
-        SidecarInterface sidecar = SidecarHelper.getSidecarImpl(mContext);
+        assumeExtensionV10_V01();
+        ExtensionInterfaceCompat extension = ExtensionHelper.getExtensionImpl(mContext);
 
         TestActivity activity = mActivityTestRule.launchActivity(new Intent());
         IBinder windowToken = getActivityWindowToken(activity);
         assertNotNull(windowToken);
 
         assertTrue("Layout must happen after launch", activity.waitForLayout());
-        SidecarWindowLayoutInfo sidecarWindowLayoutInfo = sidecar.getWindowLayoutInfo(windowToken);
-        WindowLayoutInfo windowLayoutInfo =
-                SidecarHelper.windowLayoutInfoFromSidecar(sidecarWindowLayoutInfo);
+        WindowLayoutInfo windowLayoutInfo = extension.getWindowLayoutInfo(windowToken);
         if (windowLayoutInfo.getDisplayFeatures().isEmpty()) {
             return;
         }
 
         for (DisplayFeature displayFeature : windowLayoutInfo.getDisplayFeatures()) {
             int featureType = displayFeature.getType();
-            assertThat(featureType).isAtLeast(SidecarDisplayFeature.TYPE_FOLD);
-            assertThat(featureType).isAtMost(SidecarDisplayFeature.TYPE_HINGE);
+            assertThat(featureType).isAtLeast(ExtensionDisplayFeature.TYPE_FOLD);
+            assertThat(featureType).isAtMost(ExtensionDisplayFeature.TYPE_HINGE);
 
             Rect featureRect = displayFeature.getBounds();
             assertFalse(featureRect.width() == 0 && featureRect.height() == 0);
@@ -142,21 +131,21 @@
 
     @Test
     public void testRegisterWindowLayoutChangeListener() throws Exception {
-        assumeSidecarV10_V01();
-        SidecarInterface sidecar = SidecarHelper.getSidecarImpl(mContext);
+        assumeExtensionV10_V01();
+        ExtensionInterfaceCompat extension = ExtensionHelper.getExtensionImpl(mContext);
 
         TestActivity activity = mActivityTestRule.launchActivity(new Intent());
         IBinder windowToken = getActivityWindowToken(activity);
         assertNotNull(windowToken);
 
-        sidecar.onWindowLayoutChangeListenerAdded(windowToken);
-        sidecar.onWindowLayoutChangeListenerRemoved(windowToken);
+        extension.onWindowLayoutChangeListenerAdded(windowToken);
+        extension.onWindowLayoutChangeListenerRemoved(windowToken);
     }
 
     @Test
     public void testWindowLayoutUpdatesOnConfigChange() throws Exception {
-        assumeSidecarV10_V01();
-        SidecarInterface sidecar = SidecarHelper.getSidecarImpl(mContext);
+        assumeExtensionV10_V01();
+        ExtensionInterfaceCompat extension = ExtensionHelper.getExtensionImpl(mContext);
 
         TestConfigChangeHandlingActivity activity =
                 mConfigHandlingActivityTestRule.launchActivity(new Intent());
@@ -167,10 +156,8 @@
         activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
 
         activity.waitForLayout();
-        SidecarWindowLayoutInfo portraitWindowLayoutInfo = sidecar.getWindowLayoutInfo(windowToken);
-        WindowLayoutInfo windowLayoutInfo =
-                SidecarHelper.windowLayoutInfoFromSidecar(portraitWindowLayoutInfo);
-        if (windowLayoutInfo.getDisplayFeatures().isEmpty()) {
+        WindowLayoutInfo portraitWindowLayoutInfo = extension.getWindowLayoutInfo(windowToken);
+        if (portraitWindowLayoutInfo.getDisplayFeatures().isEmpty()) {
             // No display feature to compare, finish test early
             return;
         }
@@ -179,16 +166,16 @@
         activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
 
         assertTrue("Layout must happen after orientation change", activity.waitForLayout());
-        SidecarWindowLayoutInfo landscapeWindowLayoutInfo =
-                sidecar.getWindowLayoutInfo(windowToken);
+        WindowLayoutInfo landscapeWindowLayoutInfo =
+                extension.getWindowLayoutInfo(windowToken);
 
         assertNotEquals(portraitWindowLayoutInfo, landscapeWindowLayoutInfo);
     }
 
     @Test
     public void testWindowLayoutUpdatesOnRecreate() throws Exception {
-        assumeSidecarV10_V01();
-        SidecarInterface sidecar = SidecarHelper.getSidecarImpl(mContext);
+        assumeExtensionV10_V01();
+        ExtensionInterfaceCompat extension = ExtensionHelper.getExtensionImpl(mContext);
 
         TestActivity activity = mActivityTestRule.launchActivity(new Intent());
 
@@ -200,10 +187,8 @@
         assertNotNull(windowToken);
 
         activity.waitForLayout();
-        SidecarWindowLayoutInfo portraitWindowLayoutInfo = sidecar.getWindowLayoutInfo(windowToken);
-        WindowLayoutInfo windowLayoutInfo =
-                SidecarHelper.windowLayoutInfoFromSidecar(portraitWindowLayoutInfo);
-        if (windowLayoutInfo.getDisplayFeatures().isEmpty()) {
+        WindowLayoutInfo portraitWindowLayoutInfo = extension.getWindowLayoutInfo(windowToken);
+        if (portraitWindowLayoutInfo.getDisplayFeatures().isEmpty()) {
             // No display feature to compare, finish test early
             return;
         }
@@ -217,25 +202,27 @@
         assertNotNull(windowToken);
 
         activity.waitForLayout();
-        SidecarWindowLayoutInfo landscapeWindowLayoutInfo =
-                sidecar.getWindowLayoutInfo(windowToken);
+        WindowLayoutInfo landscapeWindowLayoutInfo = extension.getWindowLayoutInfo(windowToken);
 
         assertNotEquals(portraitWindowLayoutInfo, landscapeWindowLayoutInfo);
     }
 
     @Test
     public void testVersionSupport() throws Exception {
-        Version version = SidecarHelper.getSidecarVersion();
-        assumeThat(Version.UNKNOWN, not(equalTo(version)));
         // Only versions 1.0 and 0.1 are supported for now
-        assertTrue(VERSION_1_0.equals(version) || VERSION_0_1.equals(version));
+        Version version = SidecarCompat.getSidecarVersion();
+        if (version != null) {
+            assertEquals(VERSION_0_1, version);
+        }
+        version = ExtensionCompat.getExtensionVersion();
+        if (version != null) {
+            assertEquals(VERSION_1_0, version);
+        }
     }
 
-    private void assumeSidecarV10_V01() {
-        Version version = SidecarHelper.getSidecarVersion();
-        assumeTrue(VERSION_1_0.equals(version) || VERSION_0_1.equals(version));
-        SidecarInterface sidecar = SidecarHelper.getSidecarImpl(mContext);
-        assumeNotNull(sidecar);
+    private void assumeExtensionV10_V01() {
+        assumeTrue(VERSION_1_0.equals(ExtensionCompat.getExtensionVersion())
+                || VERSION_0_1.equals(SidecarCompat.getSidecarVersion()));
     }
 
     private IBinder getActivityWindowToken(Activity activity) {
diff --git a/window/window/src/main/AndroidManifest.xml b/window/window/src/main/AndroidManifest.xml
index a15c847..d7a3c70 100644
--- a/window/window/src/main/AndroidManifest.xml
+++ b/window/window/src/main/AndroidManifest.xml
@@ -19,6 +19,8 @@
     package="androidx.window">
 
     <application>
+        <uses-library android:name="androidx.window.extensions"
+            android:required="false" />
         <uses-library android:name="androidx.window.sidecar"
             android:required="false" />
     </application>
diff --git a/window/window/src/main/java/androidx/window/ExtensionCompat.java b/window/window/src/main/java/androidx/window/ExtensionCompat.java
new file mode 100644
index 0000000..4edf49b
--- /dev/null
+++ b/window/window/src/main/java/androidx/window/ExtensionCompat.java
@@ -0,0 +1,262 @@
+/*
+ * Copyright 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;
+
+import static androidx.window.DeviceState.POSTURE_MAX_KNOWN;
+import static androidx.window.DeviceState.POSTURE_UNKNOWN;
+import static androidx.window.ExtensionHelper.DEBUG;
+
+import android.annotation.SuppressLint;
+import android.content.Context;
+import android.graphics.Rect;
+import android.os.IBinder;
+import android.text.TextUtils;
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.window.extensions.ExtensionDeviceState;
+import androidx.window.extensions.ExtensionDisplayFeature;
+import androidx.window.extensions.ExtensionInterface;
+import androidx.window.extensions.ExtensionProvider;
+import androidx.window.extensions.ExtensionWindowLayoutInfo;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+
+/** Compatibility wrapper for extension versions v1.0+. */
+final class ExtensionCompat implements ExtensionInterfaceCompat {
+    private static final String TAG = "ExtensionVersionCompat";
+
+    private ExtensionInterface mWindowExtension;
+
+    ExtensionCompat(Context context) {
+        mWindowExtension = ExtensionProvider.getExtensionImpl(context);
+        if (mWindowExtension == null) {
+            throw new IllegalArgumentException("Extension provider returned null");
+        }
+    }
+
+    @Override
+    public void setExtensionCallback(@NonNull ExtensionCallbackInterface extensionCallback) {
+        mWindowExtension.setExtensionCallback(new ExtensionInterface.ExtensionCallback() {
+            @Override
+            @SuppressLint("SyntheticAccessor")
+            public void onDeviceStateChanged(@NonNull ExtensionDeviceState newDeviceState) {
+                extensionCallback.onDeviceStateChanged(deviceStateFromExtension(newDeviceState));
+            }
+
+            @Override
+            @SuppressLint("SyntheticAccessor")
+            public void onWindowLayoutChanged(@NonNull IBinder windowToken,
+                    @NonNull ExtensionWindowLayoutInfo newLayout) {
+                extensionCallback.onWindowLayoutChanged(windowToken,
+                        windowLayoutInfoFromExtension(newLayout));
+            }
+        });
+    }
+
+    @NonNull
+    @Override
+    public WindowLayoutInfo getWindowLayoutInfo(@NonNull IBinder windowToken) {
+        ExtensionWindowLayoutInfo windowLayoutInfo =
+                mWindowExtension.getWindowLayoutInfo(windowToken);
+        return windowLayoutInfoFromExtension(windowLayoutInfo);
+    }
+
+    @Override
+    public void onWindowLayoutChangeListenerAdded(@NonNull IBinder windowToken) {
+        mWindowExtension.onWindowLayoutChangeListenerAdded(windowToken);
+    }
+
+    @Override
+    public void onWindowLayoutChangeListenerRemoved(@NonNull IBinder windowToken) {
+        mWindowExtension.onWindowLayoutChangeListenerRemoved(windowToken);
+    }
+
+    @NonNull
+    @Override
+    public DeviceState getDeviceState() {
+        ExtensionDeviceState deviceState = mWindowExtension.getDeviceState();
+        return deviceStateFromExtension(deviceState);
+    }
+
+    @Override
+    public void onDeviceStateListenersChanged(boolean isEmpty) {
+        mWindowExtension.onDeviceStateListenersChanged(isEmpty);
+    }
+
+    @Nullable
+    static Version getExtensionVersion() {
+        try {
+            String vendorVersion = ExtensionProvider.getApiVersion();
+            return !TextUtils.isEmpty(vendorVersion) ? Version.parse(vendorVersion) : null;
+        } catch (NoClassDefFoundError e) {
+            if (DEBUG) {
+                Log.d(TAG, "Extension version not found");
+            }
+            return null;
+        } catch (UnsupportedOperationException e) {
+            if (DEBUG) {
+                Log.d(TAG, "Stub Extension");
+            }
+            return null;
+        }
+    }
+
+    private static DisplayFeature displayFeatureFromExtension(ExtensionDisplayFeature feature) {
+        return new DisplayFeature(feature.getBounds(), feature.getType());
+    }
+
+    @NonNull
+    private static List<DisplayFeature> displayFeatureListFromExtension(
+            ExtensionWindowLayoutInfo extensionWindowLayoutInfo) {
+        List<DisplayFeature> displayFeatures = new ArrayList<>();
+        List<ExtensionDisplayFeature> extensionFeatures =
+                extensionWindowLayoutInfo.getDisplayFeatures();
+        if (extensionFeatures == null) {
+            return displayFeatures;
+        }
+
+        for (ExtensionDisplayFeature extensionFeature : extensionFeatures) {
+            displayFeatures.add(displayFeatureFromExtension(extensionFeature));
+        }
+        return displayFeatures;
+    }
+
+    @NonNull
+    private static WindowLayoutInfo windowLayoutInfoFromExtension(
+            @Nullable ExtensionWindowLayoutInfo extensionInfo) {
+        if (extensionInfo == null) {
+            return new WindowLayoutInfo(new ArrayList<>());
+        }
+
+        List<DisplayFeature> displayFeatures = displayFeatureListFromExtension(extensionInfo);
+        return new WindowLayoutInfo(displayFeatures);
+    }
+
+    @DeviceState.Posture
+    private static int postureFromExtension(ExtensionDeviceState extensionDeviceState) {
+        int extensionPosture = extensionDeviceState.getPosture();
+        if (extensionPosture > POSTURE_MAX_KNOWN) {
+            if (DEBUG) {
+                Log.d(TAG, "Unknown posture reported, WindowManager library should be updated");
+            }
+            return POSTURE_UNKNOWN;
+        }
+        return extensionPosture;
+    }
+
+    @NonNull
+    private static DeviceState deviceStateFromExtension(
+            @Nullable ExtensionDeviceState extensionDeviceState) {
+        if (extensionDeviceState == null) {
+            return new DeviceState(POSTURE_UNKNOWN);
+        }
+
+        int posture = postureFromExtension(extensionDeviceState);
+        return new DeviceState(posture);
+    }
+
+    /** Verify that extension implementation corresponds to the interface of the version. */
+    @Override
+    @SuppressWarnings("unused")
+    public boolean validateExtensionInterface() {
+        try {
+            // extension.setExtensionCallback(ExtensionInterface.ExtensionCallback);
+            Method methodSetExtensionCallback = mWindowExtension.getClass().getMethod(
+                    "setExtensionCallback", ExtensionInterface.ExtensionCallback.class);
+            Class<?> rSetExtensionCallback = methodSetExtensionCallback.getReturnType();
+            if (!rSetExtensionCallback.equals(void.class)) {
+                throw new NoSuchMethodException("Illegal return type for 'setExtensionCallback': "
+                        + rSetExtensionCallback);
+            }
+
+            // extension.getDeviceState()
+            ExtensionDeviceState tmpDeviceState = mWindowExtension.getDeviceState();
+
+            // extension.onDeviceStateListenersChanged(boolean);
+            mWindowExtension.onDeviceStateListenersChanged(true /* empty */);
+
+            // extension.getWindowLayoutInfo(IBinder)
+            Method methodGetWindowLayoutInfo = mWindowExtension.getClass()
+                    .getMethod("getWindowLayoutInfo", IBinder.class);
+            Class<?> rtGetWindowLayoutInfo = methodGetWindowLayoutInfo.getReturnType();
+            if (!rtGetWindowLayoutInfo.equals(ExtensionWindowLayoutInfo.class)) {
+                throw new NoSuchMethodException(
+                        "Illegal return type for 'getWindowLayoutInfo': "
+                                + rtGetWindowLayoutInfo);
+            }
+
+            // extension.onWindowLayoutChangeListenerAdded(IBinder);
+            Method methodRegisterWindowLayoutChangeListener = mWindowExtension.getClass()
+                    .getMethod("onWindowLayoutChangeListenerAdded", IBinder.class);
+            Class<?> rtRegisterWindowLayoutChangeListener =
+                    methodRegisterWindowLayoutChangeListener.getReturnType();
+            if (!rtRegisterWindowLayoutChangeListener.equals(void.class)) {
+                throw new NoSuchMethodException(
+                        "Illegal return type for 'onWindowLayoutChangeListenerAdded': "
+                                + rtRegisterWindowLayoutChangeListener);
+            }
+
+            // extension.onWindowLayoutChangeListenerRemoved(IBinder);
+            Method methodUnregisterWindowLayoutChangeListener = mWindowExtension.getClass()
+                    .getMethod("onWindowLayoutChangeListenerRemoved", IBinder.class);
+            Class<?> rtUnregisterWindowLayoutChangeListener =
+                    methodUnregisterWindowLayoutChangeListener.getReturnType();
+            if (!rtUnregisterWindowLayoutChangeListener.equals(void.class)) {
+                throw new NoSuchMethodException(
+                        "Illegal return type for 'onWindowLayoutChangeListenerRemoved': "
+                                + rtUnregisterWindowLayoutChangeListener);
+            }
+
+            // ExtensionDeviceState constructor
+            ExtensionDeviceState deviceState = new ExtensionDeviceState(
+                    ExtensionDeviceState.POSTURE_UNKNOWN);
+
+            // deviceState.getPosture();
+            int tmpPosture = deviceState.getPosture();
+
+            // ExtensionDisplayFeature constructor
+            ExtensionDisplayFeature displayFeature =
+                    new ExtensionDisplayFeature(new Rect(0, 0, 0, 0),
+                            ExtensionDisplayFeature.TYPE_FOLD);
+
+            // displayFeature.getBounds()
+            Rect tmpRect = displayFeature.getBounds();
+
+            // displayFeature.getType()
+            int tmpType = displayFeature.getType();
+
+            // ExtensionWindowLayoutInfo constructor
+            ExtensionWindowLayoutInfo windowLayoutInfo =
+                    new ExtensionWindowLayoutInfo(new ArrayList<>());
+
+            // windowLayoutInfo.getDisplayFeatures()
+            List<ExtensionDisplayFeature> tmpDisplayFeatures =
+                    windowLayoutInfo.getDisplayFeatures();
+            return true;
+        } catch (Exception e) {
+            if (DEBUG) {
+                Log.e(TAG, "Extension implementation doesn't conform to interface version "
+                        + getExtensionVersion() + ", error: " + e);
+            }
+            return false;
+        }
+    }
+}
diff --git a/window/window/src/main/java/androidx/window/ExtensionHelper.java b/window/window/src/main/java/androidx/window/ExtensionHelper.java
new file mode 100644
index 0000000..f414254
--- /dev/null
+++ b/window/window/src/main/java/androidx/window/ExtensionHelper.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright 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;
+
+import android.content.Context;
+import android.util.Log;
+
+import androidx.annotation.Nullable;
+import androidx.window.extensions.ExtensionInterface;
+
+/**
+ * Helper class that loads the correct {@link ExtensionInterfaceCompat}.
+ */
+final class ExtensionHelper {
+    static final boolean DEBUG = false;
+    private static final String TAG = "WindowExtensionHelper";
+
+    private ExtensionHelper() {}
+
+    /**
+     * Get an instance of {@link ExtensionInterface} implemented by OEM if available on this device.
+     */
+    static ExtensionInterfaceCompat getExtensionImpl(Context context) {
+        ExtensionInterfaceCompat impl = null;
+        try {
+            if (isExtensionVersionSupported(ExtensionCompat.getExtensionVersion())) {
+                impl = new ExtensionCompat(context);
+            } else if (isExtensionVersionSupported(SidecarCompat.getSidecarVersion())) {
+                impl = new SidecarCompat(context);
+            }
+        } catch (Throwable t) {
+            if (DEBUG) {
+                Log.d(TAG, "Failed to load extension: " + t);
+            }
+            return null;
+        }
+
+        if (impl == null) {
+            if (DEBUG) {
+                Log.d(TAG, "No supported extension found");
+            }
+            return null;
+        }
+
+        if (!impl.validateExtensionInterface()) {
+            if (DEBUG) {
+                Log.d(TAG, "Loaded extension doesn't match the interface version");
+            }
+            return null;
+        }
+
+        return impl;
+    }
+
+    /**
+     * Check if the Extension version provided on this device is supported by the current version
+     * of the library.
+     */
+    private static boolean isExtensionVersionSupported(@Nullable Version extensionVersion) {
+        return extensionVersion != null
+                && Version.CURRENT.getMajor() >= extensionVersion.getMajor();
+    }
+}
+
diff --git a/window/window/src/main/java/androidx/window/ExtensionInterfaceCompat.java b/window/window/src/main/java/androidx/window/ExtensionInterfaceCompat.java
new file mode 100644
index 0000000..3f19eba
--- /dev/null
+++ b/window/window/src/main/java/androidx/window/ExtensionInterfaceCompat.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright 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;
+
+import android.os.IBinder;
+
+import androidx.annotation.NonNull;
+
+/**
+ * Base interface for different extension versions that serves as an API compatibility wrapper.
+ * @see ExtensionCompat
+ * @see SidecarCompat
+ */
+interface ExtensionInterfaceCompat {
+
+    /**
+     * Verify if the extension interface conforms to the declared version.
+     */
+    boolean validateExtensionInterface();
+
+    /**
+     * Set the callback that is used by the extension to inform about hardware state changes.
+     */
+    void setExtensionCallback(@NonNull ExtensionCallbackInterface extensionCallback);
+
+    /**
+     * Get current information about the display features present within the application window.
+     */
+    @NonNull
+    WindowLayoutInfo getWindowLayoutInfo(@NonNull IBinder windowToken);
+
+    /**
+     * Notify extension that a listener for display feature layout changes was registered for the
+     * given window token.
+     */
+    void onWindowLayoutChangeListenerAdded(@NonNull IBinder windowToken);
+
+    /**
+     * Notify extension that a listener for display feature layout changes was removed for the
+     * given window token.
+     */
+    void onWindowLayoutChangeListenerRemoved(@NonNull IBinder windowToken);
+
+    /**
+     * Get current device state.
+     * @see #onDeviceStateListenersChanged(boolean)
+     */
+    @NonNull
+    DeviceState getDeviceState();
+
+    /**
+     * Notify the extension that a device state change listener was updated.
+     * @param isEmpty flag indicating if the list of device state change listeners is empty.
+     */
+    void onDeviceStateListenersChanged(boolean isEmpty);
+
+    /**
+     * Callback that will be registered with the WindowManager library, and that the extension
+     * should use to report all state changes.
+     */
+    interface ExtensionCallbackInterface {
+        /**
+         * Called by extension when the device state changes.
+         */
+        void onDeviceStateChanged(@NonNull DeviceState newDeviceState);
+
+        /**
+         * Called by extension when the feature layout inside the window changes.
+         */
+        void onWindowLayoutChanged(@NonNull IBinder windowToken,
+                @NonNull WindowLayoutInfo newLayout);
+    }
+}
diff --git a/window/window/src/main/java/androidx/window/ExtensionWindowBackend.java b/window/window/src/main/java/androidx/window/ExtensionWindowBackend.java
index 3fbb308..e83f3a0 100644
--- a/window/window/src/main/java/androidx/window/ExtensionWindowBackend.java
+++ b/window/window/src/main/java/androidx/window/ExtensionWindowBackend.java
@@ -16,9 +16,7 @@
 
 package androidx.window;
 
-import static androidx.window.SidecarHelper.DEBUG;
-import static androidx.window.SidecarHelper.deviceStateFromSidecar;
-import static androidx.window.SidecarHelper.windowLayoutInfoFromSidecar;
+import static androidx.window.ExtensionHelper.DEBUG;
 import static androidx.window.WindowManager.getActivityFromContext;
 
 import android.annotation.SuppressLint;
@@ -30,9 +28,6 @@
 import androidx.annotation.GuardedBy;
 import androidx.annotation.NonNull;
 import androidx.core.util.Consumer;
-import androidx.window.sidecar.SidecarDeviceState;
-import androidx.window.sidecar.SidecarInterface;
-import androidx.window.sidecar.SidecarWindowLayoutInfo;
 
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -49,7 +44,7 @@
     private static final Object sLock = new Object();
 
     @GuardedBy("sLock")
-    private SidecarInterface mWindowSidecar;
+    private ExtensionInterfaceCompat mWindowExtension;
     /**
      * List of all registered callbacks for window layout info. Not protected by {@link #sLock} to
      * allow iterating and callback execution without holding the global lock.
@@ -64,10 +59,10 @@
             new CopyOnWriteArrayList<>();
     /** Device state that was last reported through callbacks, used to filter out duplicates. */
     @GuardedBy("sLock")
-    private SidecarDeviceState mLastReportedDeviceState;
+    private DeviceState mLastReportedDeviceState;
     /** Window layouts that were last reported through callbacks, used to filter out duplicates. */
     @GuardedBy("sLock")
-    private final HashMap<IBinder, SidecarWindowLayoutInfo> mLastReportedWindowLayouts =
+    private final HashMap<IBinder, WindowLayoutInfo> mLastReportedWindowLayouts =
             new HashMap<>();
 
     private static final String TAG = "WindowServer";
@@ -85,22 +80,22 @@
             synchronized (sLock) {
                 if (sInstance == null) {
                     sInstance = new ExtensionWindowBackend();
-                    sInstance.initSidecar(context.getApplicationContext());
+                    sInstance.initExtension(context.getApplicationContext());
                 }
             }
         }
         return sInstance;
     }
 
-    /** Try to initialize Sidecar, returns early if it's not available. */
+    /** Try to initialize Extension, returns early if it's not available. */
     @SuppressLint("SyntheticAccessor")
     @GuardedBy("sLock")
-    private void initSidecar(Context context) {
-        mWindowSidecar = SidecarHelper.getSidecarImpl(context);
-        if (mWindowSidecar == null) {
+    private void initExtension(Context context) {
+        mWindowExtension = ExtensionHelper.getExtensionImpl(context);
+        if (mWindowExtension == null) {
             return;
         }
-        mWindowSidecar.setSidecarCallback(new SidecarListenerImpl());
+        mWindowExtension.setExtensionCallback(new ExtensionListenerImpl());
     }
 
     @NonNull
@@ -112,32 +107,31 @@
             throw new IllegalStateException("Activity does not have a window attached.");
         }
 
-        SidecarWindowLayoutInfo sidecarWindowLayoutInfo;
         synchronized (sLock) {
-            sidecarWindowLayoutInfo = mWindowSidecar != null
-                    ? mWindowSidecar.getWindowLayoutInfo(windowToken) : null;
-            mLastReportedWindowLayouts.put(windowToken, sidecarWindowLayoutInfo);
+            WindowLayoutInfo extensionWindowLayoutInfo = mWindowExtension != null
+                    ? mWindowExtension.getWindowLayoutInfo(windowToken)
+                    : new WindowLayoutInfo(new ArrayList<>());
+            mLastReportedWindowLayouts.put(windowToken, extensionWindowLayoutInfo);
+            return extensionWindowLayoutInfo;
         }
-        return windowLayoutInfoFromSidecar(sidecarWindowLayoutInfo);
     }
 
     @NonNull
     @Override
     public DeviceState getDeviceState() {
-        SidecarDeviceState sidecarDeviceState;
         synchronized (sLock) {
-            sidecarDeviceState = mWindowSidecar != null ? mWindowSidecar.getDeviceState() : null;
+            return mWindowExtension != null ? mWindowExtension.getDeviceState() :
+                    new DeviceState(DeviceState.POSTURE_UNKNOWN);
         }
-        return deviceStateFromSidecar(sidecarDeviceState);
     }
 
     @Override
     public void registerLayoutChangeCallback(@NonNull Context context,
             @NonNull Executor executor, @NonNull Consumer<WindowLayoutInfo> callback) {
         synchronized (sLock) {
-            if (mWindowSidecar == null) {
+            if (mWindowExtension == null) {
                 if (DEBUG) {
-                    Log.v(TAG, "Sidecar not loaded, skipping callback registration.");
+                    Log.v(TAG, "Extension not loaded, skipping callback registration.");
                 }
                 return;
             }
@@ -149,7 +143,7 @@
             }
 
             // Check if the token was already registered, in case we need to report tracking of a
-            // new token to the sidecar.
+            // new token to the extension.
             boolean registeredToken = false;
             for (WindowLayoutChangeCallbackWrapper callbackWrapper : mWindowLayoutChangeCallbacks) {
                 if (callbackWrapper.mToken.equals(windowToken)) {
@@ -163,7 +157,7 @@
             mWindowLayoutChangeCallbacks.add(callbackWrapper);
             if (!registeredToken) {
                 // Added the first callback for the token.
-                mWindowSidecar.onWindowLayoutChangeListenerAdded(windowToken);
+                mWindowExtension.onWindowLayoutChangeListenerAdded(windowToken);
             }
         }
     }
@@ -171,9 +165,9 @@
     @Override
     public void unregisterLayoutChangeCallback(@NonNull Consumer<WindowLayoutInfo> callback) {
         synchronized (sLock) {
-            if (mWindowSidecar == null) {
+            if (mWindowExtension == null) {
                 if (DEBUG) {
-                    Log.v(TAG, "Sidecar not loaded, skipping callback un-registration.");
+                    Log.v(TAG, "Extension not loaded, skipping callback un-registration.");
                 }
                 return;
             }
@@ -187,7 +181,7 @@
                     itemsToRemove.add(callbackWrapper);
                 }
             }
-            // Remove the items from the list and notify sidecar if needed.
+            // Remove the items from the list and notify extension if needed.
             mWindowLayoutChangeCallbacks.removeAll(itemsToRemove);
             for (WindowLayoutChangeCallbackWrapper callbackWrapper : itemsToRemove) {
                 callbackRemovedForToken(callbackWrapper.mToken);
@@ -196,7 +190,7 @@
     }
 
     /**
-     * Check if there are no more registered callbacks left for the token and inform sidecar if
+     * Check if there are no more registered callbacks left for the token and inform extension if
      * needed.
      */
     @GuardedBy("sLock")
@@ -207,23 +201,23 @@
                 return;
             }
         }
-        // No registered callbacks left for token - report to sidecar.
-        mWindowSidecar.onWindowLayoutChangeListenerRemoved(token);
+        // No registered callbacks left for token - report to extension.
+        mWindowExtension.onWindowLayoutChangeListenerRemoved(token);
     }
 
     @Override
     public void registerDeviceStateChangeCallback(@NonNull Executor executor,
             @NonNull Consumer<DeviceState> callback) {
         synchronized (sLock) {
-            if (mWindowSidecar == null) {
+            if (mWindowExtension == null) {
                 if (DEBUG) {
-                    Log.d(TAG, "Sidecar not loaded, skipping callback registration.");
+                    Log.d(TAG, "Extension not loaded, skipping callback registration.");
                 }
                 return;
             }
 
             if (mDeviceStateChangeCallbacks.isEmpty()) {
-                mWindowSidecar.onDeviceStateListenersChanged(false /* isEmpty */);
+                mWindowExtension.onDeviceStateListenersChanged(false /* isEmpty */);
             }
 
             final DeviceStateChangeCallbackWrapper callbackWrapper =
@@ -235,9 +229,9 @@
     @Override
     public void unregisterDeviceStateChangeCallback(@NonNull Consumer<DeviceState> callback) {
         synchronized (sLock) {
-            if (mWindowSidecar == null) {
+            if (mWindowExtension == null) {
                 if (DEBUG) {
-                    Log.d(TAG, "Sidecar not loaded, skipping callback un-registration.");
+                    Log.d(TAG, "Extension not loaded, skipping callback un-registration.");
                 }
                 return;
             }
@@ -246,7 +240,7 @@
                 if (callbackWrapper.mCallback.equals(callback)) {
                     mDeviceStateChangeCallbacks.remove(callbackWrapper);
                     if (mDeviceStateChangeCallbacks.isEmpty()) {
-                        mWindowSidecar.onDeviceStateListenersChanged(true /* isEmpty */);
+                        mWindowExtension.onDeviceStateListenersChanged(true /* isEmpty */);
                     }
                     return;
                 }
@@ -254,27 +248,27 @@
         }
     }
 
-    private class SidecarListenerImpl implements SidecarInterface.SidecarCallback {
+    private class ExtensionListenerImpl implements
+            ExtensionInterfaceCompat.ExtensionCallbackInterface {
         @Override
         @SuppressLint("SyntheticAccessor")
-        public void onDeviceStateChanged(@NonNull SidecarDeviceState newDeviceState) {
+        public void onDeviceStateChanged(@NonNull DeviceState newDeviceState) {
             synchronized (sLock) {
                 if (newDeviceState.equals(mLastReportedDeviceState)) {
                     // Skipping, value already reported
                     if (DEBUG) {
-                        Log.w(TAG, "Sidecar reported old layout value");
+                        Log.w(TAG, "Extension reported old layout value");
                     }
                     return;
                 }
                 mLastReportedDeviceState = newDeviceState;
             }
 
-            DeviceState deviceState = deviceStateFromSidecar(newDeviceState);
             for (DeviceStateChangeCallbackWrapper callbackWrapper : mDeviceStateChangeCallbacks) {
                 callbackWrapper.mExecutor.execute(new Runnable() {
                     @Override
                     public void run() {
-                        callbackWrapper.mCallback.accept(deviceState);
+                        callbackWrapper.mCallback.accept(newDeviceState);
                     }
                 });
             }
@@ -283,21 +277,19 @@
         @Override
         @SuppressLint("SyntheticAccessor")
         public void onWindowLayoutChanged(@NonNull IBinder windowToken,
-                @NonNull SidecarWindowLayoutInfo newLayout) {
+                @NonNull WindowLayoutInfo newLayout) {
             synchronized (sLock) {
-                SidecarWindowLayoutInfo lastReportedValue =
-                        mLastReportedWindowLayouts.get(windowToken);
+                WindowLayoutInfo lastReportedValue = mLastReportedWindowLayouts.get(windowToken);
                 if (newLayout.equals(lastReportedValue)) {
                     // Skipping, value already reported
                     if (DEBUG) {
-                        Log.w(TAG, "Sidecar reported an old layout value");
+                        Log.w(TAG, "Extension reported an old layout value");
                     }
                     return;
                 }
                 mLastReportedWindowLayouts.put(windowToken, newLayout);
             }
 
-            WindowLayoutInfo layoutInfo = windowLayoutInfoFromSidecar(newLayout);
             for (WindowLayoutChangeCallbackWrapper callbackWrapper : mWindowLayoutChangeCallbacks) {
                 if (!callbackWrapper.mToken.equals(windowToken)) {
                     continue;
@@ -306,7 +298,7 @@
                 callbackWrapper.mExecutor.execute(new Runnable() {
                     @Override
                     public void run() {
-                        callbackWrapper.mCallback.accept(layoutInfo);
+                        callbackWrapper.mCallback.accept(newLayout);
                     }
                 });
             }
diff --git a/window/window/src/main/java/androidx/window/SidecarCompat.java b/window/window/src/main/java/androidx/window/SidecarCompat.java
new file mode 100644
index 0000000..f4e26f4
--- /dev/null
+++ b/window/window/src/main/java/androidx/window/SidecarCompat.java
@@ -0,0 +1,258 @@
+/*
+ * Copyright 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;
+
+import static androidx.window.DeviceState.POSTURE_MAX_KNOWN;
+import static androidx.window.DeviceState.POSTURE_UNKNOWN;
+import static androidx.window.ExtensionHelper.DEBUG;
+import static androidx.window.Version.VERSION_0_1;
+
+import android.annotation.SuppressLint;
+import android.content.Context;
+import android.graphics.Rect;
+import android.os.IBinder;
+import android.text.TextUtils;
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.window.sidecar.SidecarDeviceState;
+import androidx.window.sidecar.SidecarDisplayFeature;
+import androidx.window.sidecar.SidecarInterface;
+import androidx.window.sidecar.SidecarProvider;
+import androidx.window.sidecar.SidecarWindowLayoutInfo;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+
+/** Extension interface compatibility wrapper for v0.1 sidecar. */
+@SuppressWarnings("deprecation")
+final class SidecarCompat implements ExtensionInterfaceCompat {
+    private static final String TAG = "SidecarCompat";
+
+    private SidecarInterface mSidecar;
+
+    SidecarCompat(Context context) {
+        mSidecar = SidecarProvider.getSidecarImpl(context);
+        if (mSidecar == null) {
+            throw new IllegalArgumentException("Sidecar provider returned null");
+        }
+    }
+
+    @Override
+    public void setExtensionCallback(@NonNull ExtensionCallbackInterface extensionCallback) {
+        mSidecar.setSidecarCallback(new SidecarInterface.SidecarCallback() {
+            @Override
+            @SuppressLint("SyntheticAccessor")
+            public void onDeviceStateChanged(@NonNull SidecarDeviceState newDeviceState) {
+                extensionCallback.onDeviceStateChanged(deviceStateFromSidecar(newDeviceState));
+            }
+
+            @Override
+            @SuppressLint("SyntheticAccessor")
+            public void onWindowLayoutChanged(@NonNull IBinder windowToken,
+                    @NonNull SidecarWindowLayoutInfo newLayout) {
+                extensionCallback.onWindowLayoutChanged(windowToken,
+                        windowLayoutInfoFromSidecar(newLayout));
+            }
+        });
+    }
+
+    @NonNull
+    @Override
+    public WindowLayoutInfo getWindowLayoutInfo(@NonNull IBinder windowToken) {
+        SidecarWindowLayoutInfo windowLayoutInfo = mSidecar.getWindowLayoutInfo(windowToken);
+        return windowLayoutInfoFromSidecar(windowLayoutInfo);
+    }
+
+    @Override
+    public void onWindowLayoutChangeListenerAdded(@NonNull IBinder windowToken) {
+        mSidecar.onWindowLayoutChangeListenerAdded(windowToken);
+    }
+
+    @Override
+    public void onWindowLayoutChangeListenerRemoved(@NonNull IBinder windowToken) {
+        mSidecar.onWindowLayoutChangeListenerRemoved(windowToken);
+    }
+
+    @NonNull
+    @Override
+    public DeviceState getDeviceState() {
+        SidecarDeviceState deviceState = mSidecar.getDeviceState();
+        return deviceStateFromSidecar(deviceState);
+    }
+
+    @Override
+    public void onDeviceStateListenersChanged(boolean isEmpty) {
+        mSidecar.onDeviceStateListenersChanged(isEmpty);
+    }
+
+    @Override
+    @SuppressWarnings("unused")
+    public boolean validateExtensionInterface() {
+        try {
+            // sidecar.setSidecarCallback(SidecarInterface.SidecarCallback);
+            Method methodSetSidecarCallback = mSidecar.getClass().getMethod("setSidecarCallback",
+                    SidecarInterface.SidecarCallback.class);
+            Class<?> rSetSidecarCallback = methodSetSidecarCallback.getReturnType();
+            if (!rSetSidecarCallback.equals(void.class)) {
+                throw new NoSuchMethodException("Illegal return type for 'setSidecarCallback': "
+                        + rSetSidecarCallback);
+            }
+
+            // sidecar.getDeviceState()
+            SidecarDeviceState tmpDeviceState = mSidecar.getDeviceState();
+
+            // sidecar.onDeviceStateListenersChanged(boolean);
+            mSidecar.onDeviceStateListenersChanged(true /* isEmpty */);
+
+            // sidecar.getWindowLayoutInfo(IBinder)
+            Method methodGetWindowLayoutInfo = mSidecar.getClass()
+                    .getMethod("getWindowLayoutInfo", IBinder.class);
+            Class<?> rtGetWindowLayoutInfo = methodGetWindowLayoutInfo.getReturnType();
+            if (!rtGetWindowLayoutInfo.equals(SidecarWindowLayoutInfo.class)) {
+                throw new NoSuchMethodException(
+                        "Illegal return type for 'getWindowLayoutInfo': "
+                                + rtGetWindowLayoutInfo);
+            }
+
+            // sidecar.onWindowLayoutChangeListenerAdded(IBinder);
+            Method methodRegisterWindowLayoutChangeListener = mSidecar.getClass()
+                    .getMethod("onWindowLayoutChangeListenerAdded", IBinder.class);
+            Class<?> rtRegisterWindowLayoutChangeListener =
+                    methodRegisterWindowLayoutChangeListener.getReturnType();
+            if (!rtRegisterWindowLayoutChangeListener.equals(void.class)) {
+                throw new NoSuchMethodException(
+                        "Illegal return type for 'onWindowLayoutChangeListenerAdded': "
+                                + rtRegisterWindowLayoutChangeListener);
+            }
+
+            // sidecar.onWindowLayoutChangeListenerRemoved(IBinder);
+            Method methodUnregisterWindowLayoutChangeListener = mSidecar.getClass()
+                    .getMethod("onWindowLayoutChangeListenerRemoved", IBinder.class);
+            Class<?> rtUnregisterWindowLayoutChangeListener =
+                    methodUnregisterWindowLayoutChangeListener.getReturnType();
+            if (!rtUnregisterWindowLayoutChangeListener.equals(void.class)) {
+                throw new NoSuchMethodException(
+                        "Illegal return type for 'onWindowLayoutChangeListenerRemoved': "
+                                + rtUnregisterWindowLayoutChangeListener);
+            }
+
+            // SidecarDeviceState constructor
+            tmpDeviceState = new SidecarDeviceState();
+
+            // deviceState.posture
+            tmpDeviceState.posture = SidecarDeviceState.POSTURE_OPENED;
+
+            // SidecarDisplayFeature constructor
+            SidecarDisplayFeature displayFeature = new SidecarDisplayFeature();
+
+            // displayFeature.getRect()/setRect()
+            Rect tmpRect = displayFeature.getRect();
+            displayFeature.setRect(tmpRect);
+
+            // displayFeature.getType()/setType()
+            int tmpType = displayFeature.getType();
+            displayFeature.setType(SidecarDisplayFeature.TYPE_FOLD);
+
+            // SidecarWindowLayoutInfo constructor
+            SidecarWindowLayoutInfo windowLayoutInfo = new SidecarWindowLayoutInfo();
+
+            // windowLayoutInfo.displayFeatures
+            final List<SidecarDisplayFeature> tmpDisplayFeatures = windowLayoutInfo.displayFeatures;
+
+            return true;
+        } catch (Exception e) {
+            if (DEBUG) {
+                Log.e(TAG, "Extension implementation doesn't conform to interface version "
+                        + VERSION_0_1 + ", error: " + e);
+            }
+            return false;
+        }
+    }
+
+    @Nullable
+    static Version getSidecarVersion() {
+        try {
+            String vendorVersion = SidecarProvider.getApiVersion();
+            return !TextUtils.isEmpty(vendorVersion) ? Version.parse(vendorVersion) : null;
+        } catch (NoClassDefFoundError e) {
+            if (DEBUG) {
+                Log.d(TAG, "Sidecar version not found");
+            }
+            return null;
+        } catch (UnsupportedOperationException e) {
+            if (DEBUG) {
+                Log.d(TAG, "Stub Sidecar");
+            }
+            return null;
+        }
+    }
+
+    private static DisplayFeature displayFeatureFromExtension(SidecarDisplayFeature feature) {
+        return new DisplayFeature(feature.getRect(), feature.getType());
+    }
+
+    @NonNull
+    private static List<DisplayFeature> displayFeatureListFromSidecar(
+            SidecarWindowLayoutInfo sidecarWindowLayoutInfo) {
+        List<DisplayFeature> displayFeatures = new ArrayList<>();
+        if (sidecarWindowLayoutInfo.displayFeatures == null) {
+            return displayFeatures;
+        }
+
+        for (SidecarDisplayFeature sidecarFeature : sidecarWindowLayoutInfo.displayFeatures) {
+            displayFeatures.add(displayFeatureFromExtension(sidecarFeature));
+        }
+        return displayFeatures;
+    }
+
+    @NonNull
+    private static WindowLayoutInfo windowLayoutInfoFromSidecar(
+            @Nullable SidecarWindowLayoutInfo extensionInfo) {
+        if (extensionInfo == null) {
+            return new WindowLayoutInfo(new ArrayList<>());
+        }
+
+        List<DisplayFeature> displayFeatures = displayFeatureListFromSidecar(extensionInfo);
+        return new WindowLayoutInfo(displayFeatures);
+    }
+
+    @DeviceState.Posture
+    private static int postureFromSidecar(SidecarDeviceState sidecarDeviceState) {
+        int sidecarPosture = sidecarDeviceState.posture;
+        if (sidecarPosture > POSTURE_MAX_KNOWN) {
+            if (DEBUG) {
+                Log.d(TAG, "Unknown posture reported, WindowManager library should be updated");
+            }
+            return POSTURE_UNKNOWN;
+        }
+        return sidecarPosture;
+    }
+
+    @NonNull
+    private static DeviceState deviceStateFromSidecar(
+            @Nullable SidecarDeviceState sidecarDeviceState) {
+        if (sidecarDeviceState == null) {
+            return new DeviceState(POSTURE_UNKNOWN);
+        }
+
+        int posture = postureFromSidecar(sidecarDeviceState);
+        return new DeviceState(posture);
+    }
+}
diff --git a/window/window/src/main/java/androidx/window/SidecarHelper.java b/window/window/src/main/java/androidx/window/SidecarHelper.java
deleted file mode 100644
index 03c877a..0000000
--- a/window/window/src/main/java/androidx/window/SidecarHelper.java
+++ /dev/null
@@ -1,385 +0,0 @@
-/*
- * Copyright 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;
-
-import static androidx.window.DeviceState.POSTURE_MAX_KNOWN;
-import static androidx.window.DeviceState.POSTURE_UNKNOWN;
-import static androidx.window.Version.VERSION_0_1;
-
-import android.content.Context;
-import android.graphics.Rect;
-import android.os.IBinder;
-import android.util.Log;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-import androidx.window.sidecar.SidecarDeviceState;
-import androidx.window.sidecar.SidecarDisplayFeature;
-import androidx.window.sidecar.SidecarInterface;
-import androidx.window.sidecar.SidecarProvider;
-import androidx.window.sidecar.SidecarWindowLayoutInfo;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Helper class with convenience methods to communicate with the {@link SidecarInterface}.
- */
-final class SidecarHelper {
-    static final boolean DEBUG = false;
-    private static final String TAG = "WindowSidecarHelper";
-
-    /**
-     * Version of the sidecar present on the device. Inflated only once and not supposed to change
-     * at runtime, so no need for synchronization.
-     */
-    private static Version sSidecarVersion;
-    /**
-     * Wrapper around sidecar interfaces to allow backwards compatibility. The only state it
-     * holds is the {@link #sSidecarVersion}, so no synchronization needed as well.
-     */
-    private static SidecarVersionCompat sSidecarVersionCompat;
-
-    private SidecarHelper() {}
-
-    /**
-     * Get an instance of {@link SidecarInterface} implemented by OEM if available on this device.
-     */
-    static SidecarInterface getSidecarImpl(Context context) {
-        Version sidecarVersion;
-        try {
-            sidecarVersion = getSidecarVersion();
-        } catch (Throwable t) {
-            if (DEBUG) {
-                Log.d(TAG, "Failed to load sidecar version: " + t);
-            }
-            return null;
-        }
-        if (!isSidecarVersionSupported(sidecarVersion)) {
-            return null;
-        }
-
-        SidecarInterface impl;
-        try {
-            impl = SidecarProvider.getSidecarImpl(context);
-            if (impl == null) {
-                throw new IllegalArgumentException("Sidecar provider returned null");
-            }
-        } catch (Throwable t) {
-            if (DEBUG) {
-                Log.d(TAG, "Failed to load sidecar: " + t);
-            }
-            return null;
-        }
-        if (!validateSidecarInterface(impl, sidecarVersion)) {
-            if (DEBUG) {
-                Log.d(TAG, "Loaded sidecar doesn't match the interface version");
-            }
-            return null;
-        }
-        return impl;
-    }
-
-    /**
-     * Get the version of the Sidecar on this device to match the current version of the library.
-     */
-    @VisibleForTesting
-    @NonNull
-    static Version getSidecarVersion() {
-        if (sSidecarVersion == null) {
-            try {
-                String vendorVersion = SidecarProvider.getApiVersion();
-                sSidecarVersion = Version.parse(vendorVersion);
-            } catch (NoClassDefFoundError e) {
-                if (DEBUG) {
-                    Log.d(TAG, "Sidecar version not found");
-                }
-                sSidecarVersion = Version.UNKNOWN;
-            } catch (UnsupportedOperationException e) {
-                if (DEBUG) {
-                    Log.d(TAG, "Stub Sidecar");
-                }
-                sSidecarVersion = Version.UNKNOWN;
-            }
-        }
-
-        return sSidecarVersion;
-    }
-
-    /**
-     * Check if the Sidecar version provided on this device is supported by the current version
-     * of the library.
-     */
-    private static boolean isSidecarVersionSupported(@NonNull Version sidecarVersion) {
-        return Version.CURRENT.getMajor() >= sidecarVersion.getMajor();
-    }
-
-    /**
-     * Get the version compatibility wrapper that invokes the right sidecar method corresponding
-     * to the current sidecar version.
-     */
-    static SidecarVersionCompat versionCompat() {
-        if (sSidecarVersionCompat == null) {
-            sSidecarVersionCompat = new SidecarVersionCompat(getSidecarVersion());
-        }
-        return sSidecarVersionCompat;
-    }
-
-    private static DisplayFeature displayFeatureFromSidecar(SidecarDisplayFeature feature) {
-        Rect featureBounds = versionCompat().getFeatureBounds(feature);
-        int featureType = feature.getType();
-        return new DisplayFeature(featureBounds, featureType);
-    }
-
-    @NonNull
-    private static List<DisplayFeature> displayFeatureListFromSidecar(
-            SidecarWindowLayoutInfo sidecarWindowLayoutInfo) {
-        List<DisplayFeature> displayFeatures = new ArrayList<>();
-        List<SidecarDisplayFeature> sidecarFeatures =
-                versionCompat().getSidecarDisplayFeatures(sidecarWindowLayoutInfo);
-        if (sidecarFeatures == null) {
-            return displayFeatures;
-        }
-
-        for (SidecarDisplayFeature sidecarFeature : sidecarFeatures) {
-            displayFeatures.add(displayFeatureFromSidecar(sidecarFeature));
-        }
-        return displayFeatures;
-    }
-
-    @NonNull
-    static WindowLayoutInfo windowLayoutInfoFromSidecar(
-            @Nullable SidecarWindowLayoutInfo sidecarInfo) {
-        if (sidecarInfo == null) {
-            return new WindowLayoutInfo(new ArrayList<>());
-        }
-
-        List<DisplayFeature> displayFeatures = displayFeatureListFromSidecar(sidecarInfo);
-        return new WindowLayoutInfo(displayFeatures);
-    }
-
-    @DeviceState.Posture
-    private static int postureFromSidecar(SidecarDeviceState sidecarDeviceState) {
-        int sidecarPosture = versionCompat().getSidecarDevicePosture(sidecarDeviceState);
-        if (sidecarPosture > POSTURE_MAX_KNOWN) {
-            if (DEBUG) {
-                Log.d(TAG, "Unknown posture reported, WindowManager library should be updated");
-            }
-            return POSTURE_UNKNOWN;
-        }
-        return sidecarPosture;
-    }
-
-    @NonNull
-    static DeviceState deviceStateFromSidecar(
-            @Nullable SidecarDeviceState sidecarDeviceState) {
-        if (sidecarDeviceState == null) {
-            return new DeviceState(POSTURE_UNKNOWN);
-        }
-
-        int posture = postureFromSidecar(sidecarDeviceState);
-        return new DeviceState(posture);
-    }
-
-    /** Verify that sidecar implementation corresponds to the interface of the provided version. */
-    @VisibleForTesting
-    static boolean validateSidecarInterface(@NonNull SidecarInterface sidecar,
-            @NonNull Version sidecarVersion) {
-        try {
-            if (sidecarVersion.getMajor() >= 1 || VERSION_0_1.equals(sidecarVersion)) {
-                // sidecar.setSidecarCallback(SidecarInterface.SidecarCallback);
-                Method methodSetSidecarCallback = sidecar.getClass().getMethod("setSidecarCallback",
-                        SidecarInterface.SidecarCallback.class);
-                Class<?> rSetSidecarCallback = methodSetSidecarCallback.getReturnType();
-                if (!rSetSidecarCallback.equals(void.class)) {
-                    throw new NoSuchMethodException("Illegal return type for 'setSidecarCallback': "
-                            + rSetSidecarCallback);
-                }
-
-                // sidecar.getDeviceState()
-                Method methodGetDeviceState = sidecar.getClass().getMethod("getDeviceState");
-                Class<?> rtGetDeviceState = methodGetDeviceState.getReturnType();
-                if (!rtGetDeviceState.equals(SidecarDeviceState.class)) {
-                    throw new NoSuchMethodException("Illegal return type for 'getDeviceState': "
-                            + rtGetDeviceState);
-                }
-
-                // sidecar.onDeviceStateListenersChanged(boolean);
-                Method methodRegisterDeviceStateChangeListener = sidecar.getClass()
-                        .getMethod("onDeviceStateListenersChanged", boolean.class);
-                Class<?> rtRegisterDeviceStateChangeListener =
-                        methodRegisterDeviceStateChangeListener.getReturnType();
-                if (!rtRegisterDeviceStateChangeListener.equals(void.class)) {
-                    throw new NoSuchMethodException(
-                            "Illegal return type for 'onDeviceStateListenersChanged': "
-                                    + rtRegisterDeviceStateChangeListener);
-                }
-
-                // sidecar.getWindowLayoutInfo(IBinder)
-                Method methodGetWindowLayoutInfo = sidecar.getClass()
-                        .getMethod("getWindowLayoutInfo", IBinder.class);
-                Class<?> rtGetWindowLayoutInfo = methodGetWindowLayoutInfo.getReturnType();
-                if (!rtGetWindowLayoutInfo.equals(SidecarWindowLayoutInfo.class)) {
-                    throw new NoSuchMethodException(
-                            "Illegal return type for 'getWindowLayoutInfo': "
-                                    + rtGetWindowLayoutInfo);
-                }
-
-                // sidecar.onWindowLayoutChangeListenerAdded(IBinder);
-                Method methodRegisterWindowLayoutChangeListener = sidecar.getClass()
-                        .getMethod("onWindowLayoutChangeListenerAdded", IBinder.class);
-                Class<?> rtRegisterWindowLayoutChangeListener =
-                        methodRegisterWindowLayoutChangeListener.getReturnType();
-                if (!rtRegisterWindowLayoutChangeListener.equals(void.class)) {
-                    throw new NoSuchMethodException(
-                            "Illegal return type for 'onWindowLayoutChangeListenerAdded': "
-                                    + rtRegisterWindowLayoutChangeListener);
-                }
-
-                // sidecar.onWindowLayoutChangeListenerRemoved(IBinder);
-                Method methodUnregisterWindowLayoutChangeListener = sidecar.getClass()
-                        .getMethod("onWindowLayoutChangeListenerRemoved", IBinder.class);
-                Class<?> rtUnregisterWindowLayoutChangeListener =
-                        methodUnregisterWindowLayoutChangeListener.getReturnType();
-                if (!rtUnregisterWindowLayoutChangeListener.equals(void.class)) {
-                    throw new NoSuchMethodException(
-                            "Illegal return type for 'onWindowLayoutChangeListenerRemoved': "
-                                    + rtUnregisterWindowLayoutChangeListener);
-                }
-
-                // SidecarDeviceState constructor
-                SidecarDeviceState deviceState = versionCompat()
-                        .newSidecarDeviceState(POSTURE_UNKNOWN);
-
-                if (sidecarVersion.getMajor() >= 1) {
-                    // deviceState.getPosture();
-                    Method methodSidecarDeviceStateGetPosture = deviceState.getClass().getMethod(
-                            "getPosture");
-                    Class<?> rSidecarDeviceStateGetPosture =
-                            methodSidecarDeviceStateGetPosture.getReturnType();
-                    if (!rSidecarDeviceStateGetPosture.equals(int.class)) {
-                        throw new NoSuchMethodException("Illegal return type for "
-                                + "'SidecarDeviceState.getPosture': "
-                                + rSidecarDeviceStateGetPosture);
-                    }
-                } else {
-                    // deviceState.posture
-                    Field fieldSidecarDeviceStatePosture = deviceState.getClass()
-                            .getField("posture");
-
-                    Class<?> rSidecarDeviceStatePosture =
-                            fieldSidecarDeviceStatePosture.getType();
-                    if (!rSidecarDeviceStatePosture.equals(int.class)) {
-                        throw new NoSuchMethodException("Illegal return type for "
-                                + "'SidecarDeviceState.posture': "
-                                + rSidecarDeviceStatePosture);
-                    }
-                }
-
-                // SidecarDisplayFeature constructor
-                SidecarDisplayFeature displayFeature = versionCompat().newSidecarDisplayFeature(
-                        new Rect(0, 0, 0, 0), SidecarDisplayFeature.TYPE_FOLD);
-
-                // displayFeature.getBoundingRect()
-                Method methodSidecarDisplayFeatureGetRect = displayFeature.getClass().getMethod(
-                        sidecarVersion.getMajor() >= 1 ? "getBounds" : "getRect");
-                Class<?> rSidecarDisplayFeatureGetRect =
-                        methodSidecarDisplayFeatureGetRect.getReturnType();
-                if (!rSidecarDisplayFeatureGetRect.equals(Rect.class)) {
-                    throw new NoSuchMethodException("Illegal return type for "
-                            + "'SidecarDisplayFeature.getRect': " + rSidecarDisplayFeatureGetRect);
-                }
-
-                if (VERSION_0_1.equals(sidecarVersion)) {
-                    // displayFeature.setRect()
-                    Method methodSidecarDisplayFeatureSetRect = displayFeature.getClass().getMethod(
-                            "setRect", Rect.class);
-                    Class<?> rSidecarDisplayFeatureSetRect =
-                            methodSidecarDisplayFeatureSetRect.getReturnType();
-                    if (!rSidecarDisplayFeatureSetRect.equals(void.class)) {
-                        throw new NoSuchMethodException("Illegal return type for "
-                                + "'SidecarDisplayFeature.setRect': "
-                                + rSidecarDisplayFeatureSetRect);
-                    }
-                }
-
-                // displayFeature.getType()
-                Method methodSidecarDisplayFeatureGetType = displayFeature.getClass().getMethod(
-                        "getType");
-                Class<?> rSidecarDisplayFeatureGetType =
-                        methodSidecarDisplayFeatureGetType.getReturnType();
-                if (!rSidecarDisplayFeatureGetType.equals(int.class)) {
-                    throw new NoSuchMethodException("Illegal return type for "
-                            + "'SidecarDisplayFeature.getType': " + rSidecarDisplayFeatureGetType);
-                }
-
-                if (VERSION_0_1.equals(sidecarVersion)) {
-                    // displayFeature.setType()
-                    Method methodSidecarDisplayFeatureSetType = displayFeature.getClass().getMethod(
-                            "setType", int.class);
-                    Class<?> rSidecarDisplayFeatureSetType =
-                            methodSidecarDisplayFeatureSetType.getReturnType();
-                    if (!rSidecarDisplayFeatureSetType.equals(void.class)) {
-                        throw new NoSuchMethodException("Illegal return type for "
-                                + "'SidecarDisplayFeature.setType': "
-                                + rSidecarDisplayFeatureSetType);
-                    }
-                }
-
-                // SidecarWindowLayoutInfo constructor
-                SidecarWindowLayoutInfo windowLayoutInfo =
-                        versionCompat().newSidecarWindowLayoutInfo(new ArrayList<>());
-
-                if (sidecarVersion.getMajor() >= 1) {
-                    // windowLayoutInfo.getDisplayFeatures()
-                    Method methodSidecarWindowLayoutInfoGetDisplayFeatures =
-                            windowLayoutInfo.getClass().getMethod("getDisplayFeatures");
-                    Class<?> rSidecarWindowLayoutInfoGetDisplayFeatures =
-                            methodSidecarWindowLayoutInfoGetDisplayFeatures.getReturnType();
-                    if (!rSidecarWindowLayoutInfoGetDisplayFeatures.equals(List.class)) {
-                        throw new NoSuchMethodException("Illegal return type for "
-                                + "'SidecarWindowLayoutInfo.getDisplayFeatures': "
-                                + rSidecarWindowLayoutInfoGetDisplayFeatures);
-                    }
-                } else {
-                    // windowLayoutInfo.displayFeatures
-                    Field fieldSidecarWindowLayoutInfoDisplayFeatures = windowLayoutInfo.getClass()
-                            .getField("displayFeatures");
-
-                    Class<?> rSidecarWindowLayoutInfoDisplayFeatures =
-                            fieldSidecarWindowLayoutInfoDisplayFeatures.getType();
-                    if (!rSidecarWindowLayoutInfoDisplayFeatures.equals(List.class)) {
-                        throw new NoSuchMethodException("Illegal return type for "
-                                + "'SidecarWindowLayoutInfo.displayFeatures': "
-                                + rSidecarWindowLayoutInfoDisplayFeatures);
-                    }
-                }
-            }
-            return true;
-        } catch (Exception e) {
-            if (DEBUG) {
-                Log.e(TAG, "Sidecar implementation doesn't conform to interface version "
-                        + sidecarVersion + ", error: " + e);
-            }
-            return false;
-        }
-    }
-}
-
diff --git a/window/window/src/main/java/androidx/window/SidecarVersionCompat.java b/window/window/src/main/java/androidx/window/SidecarVersionCompat.java
deleted file mode 100644
index 732c7eb..0000000
--- a/window/window/src/main/java/androidx/window/SidecarVersionCompat.java
+++ /dev/null
@@ -1,233 +0,0 @@
-/*
- * Copyright 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;
-
-import static androidx.window.DeviceState.POSTURE_UNKNOWN;
-import static androidx.window.SidecarHelper.DEBUG;
-
-import android.graphics.Rect;
-
-import androidx.window.sidecar.SidecarDeviceState;
-import androidx.window.sidecar.SidecarDisplayFeature;
-import androidx.window.sidecar.SidecarWindowLayoutInfo;
-
-import java.lang.reflect.InvocationTargetException;
-import java.util.List;
-
-/**
- * Compatibility wrapper for different sidecar versions. Should be used to invoke the correct
- * Sidecar methods depending on the current Sidecar version.
- * <p>To maintain compatibility with {@link Version#VERSION_0_1} that was shipped on some foldable
- * devices before the initial version of the support library API was frozen, some methods of the
- * class use reflection to use the right field and method names.
- */
-final class SidecarVersionCompat {
-    private Version mSidecarVersion;
-
-    /**
-     * @param sidecarVersion Current sidecar version.
-     */
-    SidecarVersionCompat(Version sidecarVersion) {
-        mSidecarVersion = sidecarVersion;
-    }
-
-    Rect getFeatureBounds(SidecarDisplayFeature feature) {
-        if (mSidecarVersion.equals(Version.VERSION_0_1)) {
-            try {
-                return (Rect) SidecarDisplayFeature.class
-                        .getMethod("getRect").invoke(feature);
-            } catch (IllegalAccessException e) {
-                if (DEBUG) {
-                    e.printStackTrace();
-                }
-                return new Rect();
-            } catch (InvocationTargetException e) {
-                if (DEBUG) {
-                    e.printStackTrace();
-                }
-                return new Rect();
-            } catch (NoSuchMethodException e) {
-                if (DEBUG) {
-                    e.printStackTrace();
-                }
-                return new Rect();
-            }
-        } else {
-            return feature.getBounds();
-        }
-    }
-
-    @SuppressWarnings("unchecked")
-    List<SidecarDisplayFeature> getSidecarDisplayFeatures(
-            SidecarWindowLayoutInfo sidecarWindowLayoutInfo) {
-        if (mSidecarVersion.equals(Version.VERSION_0_1)) {
-            try {
-                return (List<SidecarDisplayFeature>) sidecarWindowLayoutInfo.getClass()
-                        .getDeclaredField("displayFeatures")
-                        .get(sidecarWindowLayoutInfo);
-            } catch (IllegalAccessException e) {
-                if (DEBUG) {
-                    e.printStackTrace();
-                }
-                return null;
-            } catch (NoSuchFieldException e) {
-                if (DEBUG) {
-                    e.printStackTrace();
-                }
-                return null;
-            }
-        } else {
-            return sidecarWindowLayoutInfo.getDisplayFeatures();
-        }
-    }
-
-    int getSidecarDevicePosture(SidecarDeviceState sidecarDeviceState) {
-        if (mSidecarVersion.equals(Version.VERSION_0_1)) {
-            try {
-                return sidecarDeviceState.getClass().getDeclaredField("posture")
-                        .getInt(sidecarDeviceState);
-            } catch (IllegalAccessException e) {
-                if (DEBUG) {
-                    e.printStackTrace();
-                }
-                return POSTURE_UNKNOWN;
-            } catch (NoSuchFieldException e) {
-                if (DEBUG) {
-                    e.printStackTrace();
-                }
-                return POSTURE_UNKNOWN;
-            }
-        } else {
-            return sidecarDeviceState.getPosture();
-        }
-    }
-
-    SidecarDisplayFeature newSidecarDisplayFeature(Rect rect, int type) {
-        if (mSidecarVersion.equals(Version.VERSION_0_1)) {
-            try {
-                SidecarDisplayFeature displayFeature =
-                        SidecarDisplayFeature.class.getDeclaredConstructor().newInstance();
-                SidecarDisplayFeature.class.getMethod("setRect", Rect.class)
-                        .invoke(displayFeature, rect);
-                SidecarDisplayFeature.class.getMethod("setType", int.class)
-                        .invoke(displayFeature, type);
-                return displayFeature;
-            } catch (InstantiationException e) {
-                if (DEBUG) {
-                    e.printStackTrace();
-                }
-                return null;
-            } catch (InvocationTargetException e) {
-                if (DEBUG) {
-                    e.printStackTrace();
-                }
-                return null;
-            } catch (NoSuchMethodException e) {
-                if (DEBUG) {
-                    e.printStackTrace();
-                }
-                return null;
-            } catch (IllegalAccessException e) {
-                if (DEBUG) {
-                    e.printStackTrace();
-                }
-                return null;
-            }
-        } else {
-            return new SidecarDisplayFeature(rect, type);
-        }
-    }
-
-    SidecarDeviceState newSidecarDeviceState(int posture) {
-        if (mSidecarVersion.equals(Version.VERSION_0_1)) {
-            try {
-                SidecarDeviceState deviceState =
-                        SidecarDeviceState.class.getDeclaredConstructor().newInstance();
-                SidecarDeviceState.class.getDeclaredField("posture")
-                        .set(deviceState, posture);
-                return deviceState;
-            } catch (InstantiationException e) {
-                if (DEBUG) {
-                    e.printStackTrace();
-                }
-                return null;
-            } catch (IllegalAccessException e) {
-                if (DEBUG) {
-                    e.printStackTrace();
-                }
-                return null;
-            } catch (NoSuchFieldException e) {
-                if (DEBUG) {
-                    e.printStackTrace();
-                }
-                return null;
-            } catch (NoSuchMethodException e) {
-                if (DEBUG) {
-                    e.printStackTrace();
-                }
-                return null;
-            } catch (InvocationTargetException e) {
-                if (DEBUG) {
-                    e.printStackTrace();
-                }
-                return null;
-            }
-        } else {
-            return new SidecarDeviceState(posture);
-        }
-    }
-
-    SidecarWindowLayoutInfo newSidecarWindowLayoutInfo(
-            List<SidecarDisplayFeature> displayFeatures) {
-        if (mSidecarVersion.equals(Version.VERSION_0_1)) {
-            try {
-                SidecarWindowLayoutInfo windowLayoutInfo =
-                        SidecarWindowLayoutInfo.class.getDeclaredConstructor().newInstance();
-                SidecarWindowLayoutInfo.class.getDeclaredField("displayFeatures")
-                        .set(windowLayoutInfo, displayFeatures);
-                return windowLayoutInfo;
-            } catch (InstantiationException e) {
-                if (DEBUG) {
-                    e.printStackTrace();
-                }
-                return null;
-            } catch (IllegalAccessException e) {
-                if (DEBUG) {
-                    e.printStackTrace();
-                }
-                return null;
-            } catch (NoSuchFieldException e) {
-                if (DEBUG) {
-                    e.printStackTrace();
-                }
-                return null;
-            } catch (NoSuchMethodException e) {
-                if (DEBUG) {
-                    e.printStackTrace();
-                }
-                return null;
-            } catch (InvocationTargetException e) {
-                if (DEBUG) {
-                    e.printStackTrace();
-                }
-                return null;
-            }
-        } else {
-            return new SidecarWindowLayoutInfo(displayFeatures);
-        }
-    }
-}
diff --git a/window/window/src/main/java/androidx/window/WindowManager.java b/window/window/src/main/java/androidx/window/WindowManager.java
index ae399ce..c6caf69 100644
--- a/window/window/src/main/java/androidx/window/WindowManager.java
+++ b/window/window/src/main/java/androidx/window/WindowManager.java
@@ -23,7 +23,7 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.core.util.Consumer;
-import androidx.window.sidecar.SidecarInterface;
+import androidx.window.extensions.ExtensionInterface;
 
 import java.util.concurrent.Executor;
 
@@ -36,7 +36,7 @@
     /**
      * Visual context that was registered with this instance of {@link WindowManager} at creation.
      * This is used to find the token identifier of the window when requesting layout information
-     * from the {@link SidecarInterface}.
+     * from the {@link ExtensionInterface}.
      */
     private Context mContext;
     /**