diff --git a/app/build.gradle b/app/build.gradle index 22e6cdaf72..fe4755df8a 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -711,7 +711,7 @@ dependencies { implementation "com.github.seancfoley:ipaddress:$ipaddress_version" // https://mvnrepository.com/artifact/androidx.car.app/app?repo=google - // implementation "androidx.car.app:app:1.2.0-rc01" + // implementation "androidx.car.app:app:1.4.0-alpha01" // https://github.com/square/leakcanary // https://square.github.io/leakcanary/getting_started/ diff --git a/app/src/main/java/androidx/car/app/connection/CarConnection.java b/app/src/main/java/androidx/car/app/connection/CarConnection.java index 06c4691182..002aec984e 100644 --- a/app/src/main/java/androidx/car/app/connection/CarConnection.java +++ b/app/src/main/java/androidx/car/app/connection/CarConnection.java @@ -1,112 +1,112 @@ - /* - * Copyright 2021 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. - */ +/* + * Copyright 2021 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.car.app.connection; +package androidx.car.app.connection; - import static androidx.annotation.RestrictTo.Scope.LIBRARY; - //import static androidx.car.app.utils.CommonUtils.isAutomotiveOS; +import static androidx.annotation.RestrictTo.Scope.LIBRARY; +//import static androidx.car.app.utils.CommonUtils.isAutomotiveOS; - import static java.util.Objects.requireNonNull; +import static java.util.Objects.requireNonNull; - import android.content.Context; +import android.content.Context; - import androidx.annotation.IntDef; - import androidx.annotation.NonNull; - import androidx.annotation.RestrictTo; - import androidx.lifecycle.LiveData; +import androidx.annotation.IntDef; +import androidx.annotation.MainThread; +import androidx.annotation.NonNull; +import androidx.annotation.RestrictTo; +import androidx.lifecycle.LiveData; - import java.lang.annotation.ElementType; - import java.lang.annotation.Retention; - import java.lang.annotation.RetentionPolicy; - import java.lang.annotation.Target; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; - /** - * A class that allows retrieval of information about connection to a car head unit. - */ - public final class CarConnection { - /** - * Defines current car connection state. - * - *
This is used for communication with the car host's content provider on queries for - * connection type. - */ - public static final String CAR_CONNECTION_STATE = "CarConnectionState"; +/** + * A class that allows retrieval of information about connection to a car head unit. + */ +public final class CarConnection { + /** + * Defines current car connection state. + * + *
This is used for communication with the car host's content provider on queries for
+ * connection type.
+ */
+ public static final String CAR_CONNECTION_STATE = "CarConnectionState";
- /**
- * Broadcast action that notifies that the car connection has changed and needs to be updated.
- */
- public static final String ACTION_CAR_CONNECTION_UPDATED =
- "androidx.car.app.connection.action.CAR_CONNECTION_UPDATED";
+ /**
+ * Broadcast action that notifies that the car connection has changed and needs to be updated.
+ */
+ public static final String ACTION_CAR_CONNECTION_UPDATED =
+ "androidx.car.app.connection.action.CAR_CONNECTION_UPDATED";
- /**
- * Represents the types of connections that exist to a car head unit.
- *
- * @hide
- */
- @IntDef({CONNECTION_TYPE_NOT_CONNECTED, CONNECTION_TYPE_NATIVE, CONNECTION_TYPE_PROJECTION})
- @Retention(RetentionPolicy.SOURCE)
- @Target({ElementType.TYPE_USE})
- @RestrictTo(LIBRARY)
- public @interface ConnectionType {
- }
+ /**
+ * Represents the types of connections that exist to a car head unit.
+ *
+ * @hide
+ */
+ @IntDef({CONNECTION_TYPE_NOT_CONNECTED, CONNECTION_TYPE_NATIVE, CONNECTION_TYPE_PROJECTION})
+ @Retention(RetentionPolicy.SOURCE)
+ @Target({ElementType.TYPE_USE})
+ @RestrictTo(LIBRARY)
+ public @interface ConnectionType {
+ }
- /**
- * Not connected to any car head unit.z
- */
- public static final int CONNECTION_TYPE_NOT_CONNECTED = 0;
+ /**
+ * Not connected to any car head unit.z
+ */
+ public static final int CONNECTION_TYPE_NOT_CONNECTED = 0;
- /**
- * Natively running on a head unit (Android Automotive OS).
- */
- public static final int CONNECTION_TYPE_NATIVE = 1;
+ /**
+ * Natively running on a head unit (Android Automotive OS).
+ */
+ public static final int CONNECTION_TYPE_NATIVE = 1;
- /**
- * Connected to a car head unit by projecting to it.
- */
- public static final int CONNECTION_TYPE_PROJECTION = 2;
+ /**
+ * Connected to a car head unit by projecting to it.
+ */
+ public static final int CONNECTION_TYPE_PROJECTION = 2;
- private final LiveData The recommended pattern is to observe the {@link LiveData} with the activity's
- * lifecycle in order to get updates on the state change throughout the activity's lifetime.
- *
- * Connection types are:
- * The recommended pattern is to observe the {@link LiveData} with the activity's
+ * lifecycle in order to get updates on the state change throughout the activity's lifetime.
+ *
+ * Connection types are:
+ *
- *
- */
- @NonNull
- public LiveData<@ConnectionType Integer> getType() {
- return mConnectionTypeLiveData;
- }
- }
+ /**
+ * Returns a {@link LiveData} that can be observed to get current connection type.
+ *
+ *
+ *
+ */
+ @NonNull
+ public LiveData<@ConnectionType Integer> getType() {
+ return mConnectionTypeLiveData;
+ }
+}
diff --git a/app/src/main/java/androidx/car/app/connection/CarConnectionTypeLiveData.java b/app/src/main/java/androidx/car/app/connection/CarConnectionTypeLiveData.java
index e688eb2d22..f8f6a3cfda 100644
--- a/app/src/main/java/androidx/car/app/connection/CarConnectionTypeLiveData.java
+++ b/app/src/main/java/androidx/car/app/connection/CarConnectionTypeLiveData.java
@@ -18,7 +18,7 @@ package androidx.car.app.connection;
import static androidx.car.app.connection.CarConnection.ACTION_CAR_CONNECTION_UPDATED;
import static androidx.car.app.connection.CarConnection.CAR_CONNECTION_STATE;
-//import static androidx.car.app.utils.LogTags.TAG_CONNECTION_TO_CAR;
+import static androidx.car.app.utils.LogTags.TAG_CONNECTION_TO_CAR;
import android.content.AsyncQueryHandler;
import android.content.BroadcastReceiver;
@@ -28,8 +28,11 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.database.Cursor;
import android.net.Uri;
+import android.os.Build;
import android.util.Log;
+import androidx.annotation.DoNotInline;
+import androidx.annotation.RequiresApi;
import androidx.annotation.VisibleForTesting;
import androidx.car.app.connection.CarConnection.ConnectionType;
import androidx.lifecycle.LiveData;
@@ -60,8 +63,15 @@ final class CarConnectionTypeLiveData extends LiveData<@ConnectionType Integer>
@Override
public void onActive() {
- mContext.registerReceiver(mBroadcastReceiver,
- new IntentFilter(ACTION_CAR_CONNECTION_UPDATED));
+ // TODO(b/240576633): Replace this entire if-block with a call to
+ // ContextCompat#registerReceiver once it's released in androidx.core
+ IntentFilter filter = new IntentFilter(ACTION_CAR_CONNECTION_UPDATED);
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
+ Api33Impl.registerExportedReceiver(mContext, mBroadcastReceiver, filter);
+ } else {
+ mContext.registerReceiver(mBroadcastReceiver, filter);
+ }
+
queryForState();
}
@@ -86,23 +96,23 @@ final class CarConnectionTypeLiveData extends LiveData<@ConnectionType Integer>
@Override
protected void onQueryComplete(int token, Object cookie, Cursor response) {
if (response == null) {
- //Log.w(TAG_CONNECTION_TO_CAR, "Null response from content provider when checking "
- // + "connection to the car, treating as disconnected");
+ Log.w(TAG_CONNECTION_TO_CAR, "Null response from content provider when checking "
+ + "connection to the car, treating as disconnected");
postValue(CarConnection.CONNECTION_TYPE_NOT_CONNECTED);
return;
}
int carConnectionTypeColumn = response.getColumnIndex(CAR_CONNECTION_STATE);
if (carConnectionTypeColumn < 0) {
- //Log.e(TAG_CONNECTION_TO_CAR, "Connection to car response is missing the "
- // + "connection type, treating as disconnected");
+ Log.e(TAG_CONNECTION_TO_CAR, "Connection to car response is missing the "
+ + "connection type, treating as disconnected");
postValue(CarConnection.CONNECTION_TYPE_NOT_CONNECTED);
return;
}
if (!response.moveToNext()) {
- //Log.e(TAG_CONNECTION_TO_CAR, "Connection to car response is empty, treating as "
- // + "disconnected");
+ Log.e(TAG_CONNECTION_TO_CAR, "Connection to car response is empty, treating as "
+ + "disconnected");
postValue(CarConnection.CONNECTION_TYPE_NOT_CONNECTED);
return;
}
@@ -117,4 +127,17 @@ final class CarConnectionTypeLiveData extends LiveData<@ConnectionType Integer>
queryForState();
}
}
+
+ @RequiresApi(33)
+ static class Api33Impl {
+ private Api33Impl() {
+ // Not instantiable
+ }
+
+ @DoNotInline
+ static void registerExportedReceiver(Context context, BroadcastReceiver broadcastReceiver,
+ IntentFilter intentFilter) {
+ context.registerReceiver(broadcastReceiver, intentFilter, Context.RECEIVER_EXPORTED);
+ }
+ }
}