aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDiego Valenzuela <dvalenzuela@google.com>2022-09-26 19:50:17 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2022-09-26 19:50:17 +0000
commit2468ae8a0dda1d6af5d92a0d0286e56f18c66031 (patch)
treed1b8b10a998a749107307c54fa65277a2223e29d
parent1961fc6ede74ffbad33d5c9f987af062ea88978b (diff)
parent1885f5f5194db1ba4233b48c47d99f975c9b0386 (diff)
downloadsupport-2468ae8a0dda1d6af5d92a0d0286e56f18c66031.tar.gz
Merge "Add API to communicate if the car supports AppDrivenRefresh Relnote: New Api to allow users detect if an OEM has enabled App Driven Refresh Bug:b/243957836 Video: go/a4c-refresh-video Test: Unit + Manual" into androidx-main
-rw-r--r--car/app/app-samples/showcase/common/src/main/java/androidx/car/app/sample/showcase/common/common/SamplePlaces.java12
-rw-r--r--car/app/app-samples/showcase/common/src/main/java/androidx/car/app/sample/showcase/common/navigation/PlaceListNavigationTemplateDemoScreen.java23
-rw-r--r--car/app/app-samples/showcase/common/src/main/java/androidx/car/app/sample/showcase/common/templates/PlaceListTemplateDemoScreen.java2
-rw-r--r--car/app/app/api/public_plus_experimental_1.3.0-beta02.txt1
-rw-r--r--car/app/app/api/public_plus_experimental_current.txt1
-rw-r--r--car/app/app/src/main/aidl/androidx/car/app/constraints/IConstraintHost.aidl5
-rw-r--r--car/app/app/src/main/java/androidx/car/app/constraints/ConstraintManager.java30
-rw-r--r--car/app/app/src/test/java/androidx/car/app/constraints/ConstraintManagerTest.java29
8 files changed, 80 insertions, 23 deletions
diff --git a/car/app/app-samples/showcase/common/src/main/java/androidx/car/app/sample/showcase/common/common/SamplePlaces.java b/car/app/app-samples/showcase/common/src/main/java/androidx/car/app/sample/showcase/common/common/SamplePlaces.java
index 34c1e318f66..ac18ac83f53 100644
--- a/car/app/app-samples/showcase/common/src/main/java/androidx/car/app/sample/showcase/common/common/SamplePlaces.java
+++ b/car/app/app-samples/showcase/common/src/main/java/androidx/car/app/sample/showcase/common/common/SamplePlaces.java
@@ -46,6 +46,7 @@ import androidx.core.graphics.drawable.IconCompat;
import java.util.ArrayList;
import java.util.List;
+import java.util.Random;
/** Provides sample place data used in the demos. */
public class SamplePlaces {
@@ -242,7 +243,7 @@ public class SamplePlaces {
/** Return the {@link ItemList} of the sample places. */
@NonNull
- public ItemList getPlaceList() {
+ public ItemList getPlaceList(boolean randomOrder) {
ItemList.Builder listBuilder = new ItemList.Builder();
int listLimit = 6;
@@ -258,8 +259,13 @@ public class SamplePlaces {
listLimit = min(listLimit, mPlaces.size());
for (int index = 0; index < listLimit; index++) {
- PlaceInfo place = mPlaces.get(index);
-
+ Random rand = new Random();
+ PlaceInfo place;
+ if (randomOrder) {
+ place = mPlaces.get(rand.nextInt(listLimit));
+ } else {
+ place = mPlaces.get(index);
+ }
// Build a description string that includes the required distance span.
int distanceKm = getDistanceFromCurrentLocation(place.location) / 1000;
SpannableString description = new SpannableString(" \u00b7 " + place.description);
diff --git a/car/app/app-samples/showcase/common/src/main/java/androidx/car/app/sample/showcase/common/navigation/PlaceListNavigationTemplateDemoScreen.java b/car/app/app-samples/showcase/common/src/main/java/androidx/car/app/sample/showcase/common/navigation/PlaceListNavigationTemplateDemoScreen.java
index 0db39baa49f..8f12eec8d21 100644
--- a/car/app/app-samples/showcase/common/src/main/java/androidx/car/app/sample/showcase/common/navigation/PlaceListNavigationTemplateDemoScreen.java
+++ b/car/app/app-samples/showcase/common/src/main/java/androidx/car/app/sample/showcase/common/navigation/PlaceListNavigationTemplateDemoScreen.java
@@ -18,10 +18,14 @@ package androidx.car.app.sample.showcase.common.navigation;
import static androidx.car.app.CarToast.LENGTH_SHORT;
+import android.os.Handler;
+import android.os.Looper;
+
import androidx.annotation.NonNull;
import androidx.car.app.CarContext;
import androidx.car.app.CarToast;
import androidx.car.app.Screen;
+import androidx.car.app.constraints.ConstraintManager;
import androidx.car.app.model.Action;
import androidx.car.app.model.ActionStrip;
import androidx.car.app.model.CarIcon;
@@ -39,14 +43,27 @@ public final class PlaceListNavigationTemplateDemoScreen extends Screen {
private boolean mIsFavorite = false;
+ private boolean mIsAppRefresh = false;
+
public PlaceListNavigationTemplateDemoScreen(@NonNull CarContext carContext) {
super(carContext);
mPlaces = SamplePlaces.create(this);
}
+ private final Handler mHandler = new Handler(Looper.getMainLooper());
+
@NonNull
@Override
public Template onGetTemplate() {
+ boolean isAppDrivenRefreshEnabled = this.getCarContext().getCarService(
+ ConstraintManager.class).isAppDrivenRefreshEnabled();
+
+ if (isAppDrivenRefreshEnabled && !mIsAppRefresh) {
+ mIsAppRefresh = true;
+ for (int i = 1; i <= 10; i++) {
+ mHandler.postDelayed(this::invalidate, i * 1000L);
+ }
+ }
Header header = new Header.Builder()
.setStartHeaderAction(Action.BACK)
.addEndHeaderAction(new Action.Builder()
@@ -73,7 +90,7 @@ public final class PlaceListNavigationTemplateDemoScreen extends Screen {
})
.build())
.addEndHeaderAction(new Action.Builder()
- .setOnClickListener(() -> finish())
+ .setOnClickListener(this::finish)
.setIcon(
new CarIcon.Builder(
IconCompat.createWithResource(
@@ -83,9 +100,9 @@ public final class PlaceListNavigationTemplateDemoScreen extends Screen {
.build())
.setTitle(getCarContext().getString(R.string.place_list_nav_template_demo_title))
.build();
-
+ //Return elements in random order.
return new PlaceListNavigationTemplate.Builder()
- .setItemList(mPlaces.getPlaceList())
+ .setItemList(mPlaces.getPlaceList(/*randomOrder=*/isAppDrivenRefreshEnabled))
.setHeader(header)
.setMapActionStrip(RoutingDemoModels.getMapActionStrip(getCarContext()))
.setActionStrip(
diff --git a/car/app/app-samples/showcase/common/src/main/java/androidx/car/app/sample/showcase/common/templates/PlaceListTemplateDemoScreen.java b/car/app/app-samples/showcase/common/src/main/java/androidx/car/app/sample/showcase/common/templates/PlaceListTemplateDemoScreen.java
index a64bf4a9a0e..9d257bba2ba 100644
--- a/car/app/app-samples/showcase/common/src/main/java/androidx/car/app/sample/showcase/common/templates/PlaceListTemplateDemoScreen.java
+++ b/car/app/app-samples/showcase/common/src/main/java/androidx/car/app/sample/showcase/common/templates/PlaceListTemplateDemoScreen.java
@@ -38,7 +38,7 @@ public final class PlaceListTemplateDemoScreen extends Screen {
@Override
public Template onGetTemplate() {
return new PlaceListMapTemplate.Builder()
- .setItemList(mPlaces.getPlaceList())
+ .setItemList(mPlaces.getPlaceList(/*randomOrder=*/false))
.setTitle(getCarContext().getString(R.string.place_list_template_demo_title))
.setHeaderAction(Action.BACK)
.build();
diff --git a/car/app/app/api/public_plus_experimental_1.3.0-beta02.txt b/car/app/app/api/public_plus_experimental_1.3.0-beta02.txt
index 514019a66a6..89bff07ca3e 100644
--- a/car/app/app/api/public_plus_experimental_1.3.0-beta02.txt
+++ b/car/app/app/api/public_plus_experimental_1.3.0-beta02.txt
@@ -228,6 +228,7 @@ package androidx.car.app.constraints {
@androidx.car.app.annotations.RequiresCarApi(2) public class ConstraintManager implements androidx.car.app.managers.Manager {
method public int getContentLimit(int);
+ method @androidx.car.app.annotations.ExperimentalCarApi @androidx.car.app.annotations.RequiresCarApi(6) public boolean isAppDrivenRefreshEnabled();
field public static final int CONTENT_LIMIT_TYPE_GRID = 1; // 0x1
field public static final int CONTENT_LIMIT_TYPE_LIST = 0; // 0x0
field public static final int CONTENT_LIMIT_TYPE_PANE = 4; // 0x4
diff --git a/car/app/app/api/public_plus_experimental_current.txt b/car/app/app/api/public_plus_experimental_current.txt
index 514019a66a6..89bff07ca3e 100644
--- a/car/app/app/api/public_plus_experimental_current.txt
+++ b/car/app/app/api/public_plus_experimental_current.txt
@@ -228,6 +228,7 @@ package androidx.car.app.constraints {
@androidx.car.app.annotations.RequiresCarApi(2) public class ConstraintManager implements androidx.car.app.managers.Manager {
method public int getContentLimit(int);
+ method @androidx.car.app.annotations.ExperimentalCarApi @androidx.car.app.annotations.RequiresCarApi(6) public boolean isAppDrivenRefreshEnabled();
field public static final int CONTENT_LIMIT_TYPE_GRID = 1; // 0x1
field public static final int CONTENT_LIMIT_TYPE_LIST = 0; // 0x0
field public static final int CONTENT_LIMIT_TYPE_PANE = 4; // 0x4
diff --git a/car/app/app/src/main/aidl/androidx/car/app/constraints/IConstraintHost.aidl b/car/app/app/src/main/aidl/androidx/car/app/constraints/IConstraintHost.aidl
index 3f1b7d4f74d..0e058afd707 100644
--- a/car/app/app/src/main/aidl/androidx/car/app/constraints/IConstraintHost.aidl
+++ b/car/app/app/src/main/aidl/androidx/car/app/constraints/IConstraintHost.aidl
@@ -24,4 +24,9 @@ interface IConstraintHost {
* Queries the host for the limit for a content type.
*/
int getContentLimit(int contentType) = 1;
+
+ /**
+ * Queries the host for the ability to support App Driven Refresh.
+ */
+ boolean isAppDrivenRefreshEnabled() = 2;
}
diff --git a/car/app/app/src/main/java/androidx/car/app/constraints/ConstraintManager.java b/car/app/app/src/main/java/androidx/car/app/constraints/ConstraintManager.java
index 4e025f35b88..121dc31073e 100644
--- a/car/app/app/src/main/java/androidx/car/app/constraints/ConstraintManager.java
+++ b/car/app/app/src/main/java/androidx/car/app/constraints/ConstraintManager.java
@@ -31,6 +31,7 @@ import androidx.car.app.CarContext;
import androidx.car.app.HostDispatcher;
import androidx.car.app.HostException;
import androidx.car.app.R;
+import androidx.car.app.annotations.ExperimentalCarApi;
import androidx.car.app.annotations.RequiresCarApi;
import androidx.car.app.managers.Manager;
import androidx.car.app.utils.LogTags;
@@ -120,9 +121,8 @@ public class ConstraintManager implements Manager {
// TODO(b/185805900): consider caching these values if performance is a concern.
limit = mHostDispatcher.dispatchForResult(
CarContext.CONSTRAINT_SERVICE,
- "getContentLimit", (IConstraintHost host) -> {
- return host.getContentLimit(contentLimitType);
- }
+ "getContentLimit",
+ (IConstraintHost host) -> host.getContentLimit(contentLimitType)
);
} catch (RemoteException e) {
// The host is dead, don't crash the app, just log.
@@ -166,7 +166,29 @@ public class ConstraintManager implements Manager {
return new ConstraintManager(requireNonNull(context), requireNonNull(hostDispatcher));
}
- private ConstraintManager(CarContext context, HostDispatcher hostDispatcher) {
+ /**
+ * Determines if the app supports app Driven Refresh Enabled
+ */
+ @RequiresCarApi(6)
+ @ExperimentalCarApi
+ public boolean isAppDrivenRefreshEnabled() {
+ Boolean result;
+ try {
+ // TODO(b/185805900): consider caching these values if performance is a concern.
+ result = mHostDispatcher.dispatchForResult(
+ CarContext.CONSTRAINT_SERVICE,
+ "isAppDrivenRefreshEnabled", IConstraintHost::isAppDrivenRefreshEnabled
+ );
+ return Boolean.TRUE.equals(result);
+ } catch (RemoteException e) {
+ // The host is dead, don't crash the app, just log.
+ Log.w(LogTags.TAG, "Failed to retrieve list limit from the host, using defaults", e);
+ }
+ // Returns default values as documented if host call failed.
+ return false;
+ }
+
+ private ConstraintManager(@NonNull CarContext context, @NonNull HostDispatcher hostDispatcher) {
mCarContext = context;
mHostDispatcher = hostDispatcher;
}
diff --git a/car/app/app/src/test/java/androidx/car/app/constraints/ConstraintManagerTest.java b/car/app/app/src/test/java/androidx/car/app/constraints/ConstraintManagerTest.java
index f152848401a..1329d7d79bd 100644
--- a/car/app/app/src/test/java/androidx/car/app/constraints/ConstraintManagerTest.java
+++ b/car/app/app/src/test/java/androidx/car/app/constraints/ConstraintManagerTest.java
@@ -72,6 +72,11 @@ public class ConstraintManagerTest {
public int getContentLimit(int contentType) throws RemoteException {
return mMockConstraintHost.getContentLimit(contentType);
}
+
+ @Override
+ public boolean isAppDrivenRefreshEnabled() throws RemoteException {
+ return mMockConstraintHost.isAppDrivenRefreshEnabled();
+ }
};
when(mMockCarHost.getHost(any())).thenReturn(hostStub.asBinder());
mHostDispatcher.setCarHost(mMockCarHost);
@@ -91,17 +96,17 @@ public class ConstraintManagerTest {
}
@Test
- public void host_returnLimits() throws RemoteException {
- when(mMockConstraintHost.getContentLimit(CONTENT_LIMIT_TYPE_LIST)).thenReturn(1);
- when(mMockConstraintHost.getContentLimit(CONTENT_LIMIT_TYPE_GRID)).thenReturn(2);
- when(mMockConstraintHost.getContentLimit(CONTENT_LIMIT_TYPE_PLACE_LIST)).thenReturn(3);
- when(mMockConstraintHost.getContentLimit(CONTENT_LIMIT_TYPE_ROUTE_LIST)).thenReturn(4);
- when(mMockConstraintHost.getContentLimit(CONTENT_LIMIT_TYPE_PANE)).thenReturn(5);
-
- assertThat(mConstraintManager.getContentLimit(CONTENT_LIMIT_TYPE_LIST)).isEqualTo(1);
- assertThat(mConstraintManager.getContentLimit(CONTENT_LIMIT_TYPE_GRID)).isEqualTo(2);
- assertThat(mConstraintManager.getContentLimit(CONTENT_LIMIT_TYPE_PLACE_LIST)).isEqualTo(3);
- assertThat(mConstraintManager.getContentLimit(CONTENT_LIMIT_TYPE_ROUTE_LIST)).isEqualTo(4);
- assertThat(mConstraintManager.getContentLimit(CONTENT_LIMIT_TYPE_PANE)).isEqualTo(5);
+ public void host_throwsException_returnsDefault() throws RemoteException {
+ when(mMockConstraintHost.isAppDrivenRefreshEnabled()).thenThrow(new RemoteException());
+
+ assertThat(mConstraintManager.isAppDrivenRefreshEnabled()).isFalse();
+ }
+
+ @Test
+ public void host_returAppDrivenRefreshEnabled() throws RemoteException {
+ when(mMockConstraintHost.isAppDrivenRefreshEnabled()).thenReturn(true);
+
+
+ assertThat(mConstraintManager.isAppDrivenRefreshEnabled()).isTrue();
}
}