SessionInfoIntentEncoder.java
/*
* Copyright 2022 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;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import androidx.annotation.DoNotInline;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
/** Helper to encode and decode a {@link SessionInfo} from an {@link Intent} */
public class SessionInfoIntentEncoder {
/** Private constructor to prevent instantiation */
private SessionInfoIntentEncoder() {
}
/** The key for a {@link Bundle} extra containing the {@link SessionInfo} for a bind. */
private static final String EXTRA_SESSION_INFO = "androidx.car.app.extra.SESSION_INFO_BUNDLE";
/** Key for {@link SessionInfo#mDisplayType}. */
private static final String KEY_DISPLAY_TYPE = "display-type";
/** Key for {@link SessionInfo#mSessionId}. */
private static final String KEY_SESSION_ID = "session-id";
/**
* Sets the unique identifier for the given {@code intent} and encodes the passed
* {@link SessionInfo} in its extras.
*
* <p>The intent identifier that's created is unique based on {@link SessionInfo#toString()}.
* The {@link Intent} field that's set is either {@link Intent#setIdentifier} on API 29 and
* above, or {@link Intent#setData}.
*/
public static void encode(@NonNull SessionInfo sessionInfo, @NonNull Intent intent) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
Api29.setIdentifier(intent, sessionInfo.toString());
} else {
intent.setData(new Uri.Builder().path(sessionInfo.toString()).build());
}
Bundle sessionInfoBundle = new Bundle();
sessionInfoBundle.putInt(KEY_DISPLAY_TYPE, sessionInfo.getDisplayType());
sessionInfoBundle.putString(KEY_SESSION_ID, sessionInfo.getSessionId());
intent.putExtra(EXTRA_SESSION_INFO, sessionInfoBundle);
}
/**
* Decodes a new {@link SessionInfo} for a given {@code intent}
*/
@NonNull
public static SessionInfo decode(@NonNull Intent intent) {
Bundle extras = intent.getExtras();
if (extras == null) {
throw new IllegalArgumentException(
"Expected the SessionInfo to be encoded in the bind intent extras, but the "
+ "extras were null.");
}
Bundle sessionInfoBundle = extras.getBundle(EXTRA_SESSION_INFO);
int displayType = sessionInfoBundle.getInt(KEY_DISPLAY_TYPE);
String sessionId = sessionInfoBundle.getString(KEY_SESSION_ID);
return new SessionInfo(displayType, sessionId);
}
/** Returns whether or not the given {@code intent} contains an encoded {@link SessionInfo}. */
public static boolean containsSessionInfo(@NonNull Intent intent) {
Bundle extras = intent.getExtras();
if (extras == null) {
return false;
}
return extras.containsKey(EXTRA_SESSION_INFO);
}
/** Android Q method calls wrapped in a {@link RequiresApi} class to appease the compiler. */
@RequiresApi(Build.VERSION_CODES.Q)
private static class Api29 {
// Not instantiable
private Api29() {
}
/** Wrapper for {@link Intent#setIdentifier(String)}. */
@DoNotInline
static void setIdentifier(@NonNull Intent intent, @NonNull String identifier) {
intent.setIdentifier(identifier);
}
}
}