Skip to content

Commit

Permalink
tv-casting-app: ShutdownAllSubscriptions and Disconnect APIs (project…
Browse files Browse the repository at this point in the history
sharadb-amazon committed Nov 11, 2022
1 parent d0a3d57 commit 957034d
Showing 13 changed files with 177 additions and 14 deletions.
Original file line number Diff line number Diff line change
@@ -53,7 +53,7 @@ public void handleCommissioningButtonClicked(DiscoveredNodeData commissioner) {

@Override
public void handleCommissioningComplete() {
showFragment(SelectClusterFragment.newInstance());
showFragment(SelectClusterFragment.newInstance(tvCastingApp));
}

@Override
@@ -66,6 +66,11 @@ public void handleMediaPlaybackSelected() {
showFragment(MediaPlaybackFragment.newInstance(tvCastingApp));
}

@Override
public void handleDisconnect() {
showFragment(CommissionerDiscoveryFragment.newInstance(tvCastingApp));
}

/**
* The order is important, must first new TvCastingApp to load dynamic library, then
* AndroidChipPlatform to prepare platform, then start ChipAppServer, then call init on
Original file line number Diff line number Diff line change
@@ -24,6 +24,8 @@ public class MediaPlaybackFragment extends Fragment {

private View.OnClickListener subscribeToCurrentStateButtonClickListener;

private View.OnClickListener shutdownALlSubscriptionsButtonClickListener;

private static final ContentApp kContentApp = new ContentApp((short) 4, null);

public MediaPlaybackFragment(TvCastingApp tvCastingApp) {
@@ -123,6 +125,15 @@ public void run() {
}
};

this.shutdownALlSubscriptionsButtonClickListener =
new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d(TAG, "Shutting down all subscriptions");
tvCastingApp.shutdownAllSubscriptions();
}
};

return inflater.inflate(R.layout.fragment_media_playback, container, false);
}

@@ -133,5 +144,9 @@ public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
getView()
.findViewById(R.id.subscribeToCurrentStateButton)
.setOnClickListener(subscribeToCurrentStateButtonClickListener);

getView()
.findViewById(R.id.shutdownAllSubscriptionsButton)
.setOnClickListener(shutdownALlSubscriptionsButtonClickListener);
}
}
Original file line number Diff line number Diff line change
@@ -7,22 +7,31 @@
import android.view.ViewGroup;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import com.chip.casting.TvCastingApp;

/** An interstitial {@link Fragment} to select one of the supported media actions to perform */
public class SelectClusterFragment extends Fragment {
private static final String TAG = SelectClusterFragment.class.getSimpleName();

private final TvCastingApp tvCastingApp;

private View.OnClickListener selectContentLauncherButtonClickListener;
private View.OnClickListener selectMediaPlaybackButtonClickListener;
private View.OnClickListener disconnectButtonClickListener;

public SelectClusterFragment(TvCastingApp tvCastingApp) {
this.tvCastingApp = tvCastingApp;
}

/**
* Use this factory method to create a new instance of this fragment using the provided
* parameters.
*
* @param tvCastingApp TV Casting App (JNI)
* @return A new instance of fragment SelectActionFragment.
*/
public static SelectClusterFragment newInstance() {
return new SelectClusterFragment();
public static SelectClusterFragment newInstance(TvCastingApp tvCastingApp) {
return new SelectClusterFragment(tvCastingApp);
}

@Override
@@ -52,6 +61,16 @@ public void onClick(View v) {
}
};

this.disconnectButtonClickListener =
new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d(TAG, "Disconnecting from current video player");
tvCastingApp.disconnect();
callback.handleDisconnect();
}
};

return inflater.inflate(R.layout.fragment_select_cluster, container, false);
}

@@ -65,6 +84,7 @@ public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
getView()
.findViewById(R.id.selectMediaPlaybackButton)
.setOnClickListener(selectMediaPlaybackButtonClickListener);
getView().findViewById(R.id.disconnectButton).setOnClickListener(disconnectButtonClickListener);
}

/** Interface for notifying the host. */
@@ -74,5 +94,8 @@ public interface Callback {

/** Notifies listener to trigger transition on selection of Media Playback cluster */
void handleMediaPlaybackSelected();

/** Notifies listener to trigger transition on click of the Disconnect button */
void handleDisconnect();
}
}
Original file line number Diff line number Diff line change
@@ -95,6 +95,10 @@ public native boolean verifyOrEstablishConnection(
FailureCallback onConnectionFailure,
SuccessCallback<ContentApp> onNewOrUpdatedEndpointCallback);

public native void shutdownAllSubscriptions();

public native void disconnect();

public native List<VideoPlayer> getActiveTargetVideoPlayers();

/*
@@ -328,7 +332,7 @@ public native boolean applicationBasic_readVendorName(

public native boolean applicationBasic_readVendorID(
ContentApp contentApp,
SuccessCallback<Short> readSuccessHandler,
SuccessCallback<Integer> readSuccessHandler,
FailureCallback readFailureHandler);

public native boolean applicationBasic_readApplicationName(
@@ -338,7 +342,7 @@ public native boolean applicationBasic_readApplicationName(

public native boolean applicationBasic_readProductID(
ContentApp contentApp,
SuccessCallback<Short> readSuccessHandler,
SuccessCallback<Integer> readSuccessHandler,
FailureCallback readFailureHandler);

public native boolean applicationBasic_readApplicationVersion(
Original file line number Diff line number Diff line change
@@ -34,7 +34,7 @@ CHIP_ERROR CallbackBaseJNI::SetUp(JNIEnv * env, jobject inHandler)
mMethod = env->GetMethodID(mClazz, "handle", mMethodSignature);
if (mMethod == nullptr)
{
ChipLogError(AppServer, "Failed to access 'handle' method");
ChipLogError(AppServer, "Failed to access 'handle' method with signature %s", mMethodSignature);
env->ExceptionClear();
}

@@ -50,7 +50,7 @@ CHIP_ERROR CallbackBaseJNI::SetUp(JNIEnv * env, jobject inHandler)

void FailureHandlerJNI::Handle(CHIP_ERROR callbackErr)
{
ChipLogProgress(AppServer, "FailureHandlerJNI::Handle called");
ChipLogProgress(AppServer, "Handle(CHIP_ERROR) called");

JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
UtfString jniCallbackErrString(env, callbackErr.AsString());
@@ -63,7 +63,7 @@ void FailureHandlerJNI::Handle(CHIP_ERROR callbackErr)
exit:
if (err != CHIP_NO_ERROR)
{
ChipLogError(AppServer, "FailureHandlerJNI::Handle status error: %s", err.AsString());
ChipLogError(AppServer, "Handle(CHIP_ERROR) status error: %s", err.AsString());
}
}

@@ -332,9 +332,10 @@ jobject TargetListSuccessHandlerJNI::ConvertToJObject(
return nullptr;
}

jmethodID constructor = env->GetMethodID(responseTypeClass, "<init>", "(Ljava/lang/Integer;java/lang/String;)V");
jmethodID constructor = env->GetMethodID(responseTypeClass, "<init>", "(Ljava/lang/Integer;Ljava/lang/String;)V");
chip::UtfString targetInfoName(env, targetInfo.name);
jobject jTargetInfo = env->NewObject(responseTypeClass, constructor, targetInfo.identifier, targetInfoName.jniValue());
jobject jTargetInfo = env->NewObject(responseTypeClass, constructor, ConvertToIntegerJObject(targetInfo.identifier),
targetInfoName.jniValue());

chip::JniReferences::GetInstance().AddToList(jArrayList, jTargetInfo);
}
Original file line number Diff line number Diff line change
@@ -204,6 +204,21 @@ JNI_METHOD(jboolean, verifyOrEstablishConnection)
return true;
}

JNI_METHOD(void, shutdownAllSubscriptions)(JNIEnv * env, jobject)
{
chip::DeviceLayer::StackLock lock;
ChipLogProgress(AppServer, "JNI_METHOD shutdownAllSubscriptions called");

CastingServer::GetInstance()->ShutdownAllSubscriptions();
}

JNI_METHOD(void, disconnect)(JNIEnv * env, jobject)
{
chip::DeviceLayer::StackLock lock;
ChipLogProgress(AppServer, "JNI_METHOD disconnect called");
CastingServer::GetInstance()->Disconnect();
}

JNI_METHOD(jobject, getActiveTargetVideoPlayers)(JNIEnv * env, jobject)
{
chip::DeviceLayer::StackLock lock;
Original file line number Diff line number Diff line change
@@ -102,5 +102,19 @@
android:layout_height="wrap_content"
android:textAppearance="@style/TextAppearance.AppCompat.Large" />
</LinearLayout>

<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<Button
android:id="@+id/shutdownAllSubscriptionsButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/shutdown_all_subscriptions_button_text"
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
android:layout_marginRight="10sp" />
</LinearLayout>

</LinearLayout>
</FrameLayout>
Original file line number Diff line number Diff line change
@@ -5,13 +5,14 @@
android:layout_height="match_parent"
tools:context=".SelectClusterFragment">

<LinearLayout
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="10sp">

<TextView
android:id="@+id/select_cluster_heading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/select_cluster_text"
@@ -23,14 +24,25 @@
android:layout_height="wrap_content"
android:text="@string/select_content_launcher_button_text"
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
android:layout_marginRight="10sp" />
android:layout_marginRight="10sp"
android:layout_below="@id/select_cluster_heading" />

<Button
android:id="@+id/selectMediaPlaybackButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/select_media_playback_button_text"
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
android:layout_marginRight="10sp" />
</LinearLayout>
android:layout_marginRight="10sp"
android:layout_below="@id/selectContentLauncherButton"/>

<Button
android:id="@+id/disconnectButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/disconnect_button_text"
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
android:layout_marginRight="10sp"
android:layout_alignParentBottom="true" />
</RelativeLayout>
</FrameLayout>
Original file line number Diff line number Diff line change
@@ -20,4 +20,6 @@
<string name="subscribe_to_current_state_button_text">Subscribe</string>
<string name="current_state_text">Reported Current State</string>
<string name="endpoint_prompt_text">Endpoint ID</string>
<string name="shutdown_all_subscriptions_button_text">Shutdown all Subscriptions</string>
<string name="disconnect_button_text">Disconnect from Video Player</string>
</resources>
Original file line number Diff line number Diff line change
@@ -166,6 +166,24 @@
onConnectionFailureCallback:(void (^_Nonnull)(MatterError * _Nonnull))onConnectionFailureCallback
onNewOrUpdatedEndpointCallback:(void (^_Nonnull)(ContentApp * _Nonnull))onNewOrUpdatedEndpointCallback;

/*!
@brief Tears down all active subscriptions.
@param clientQueue Queue to invoke callbacks on
@param requestSentHandler Called after the request has been sent
*/
- (void)shutdownAllSubscriptions:(dispatch_queue_t _Nonnull)clientQueue requestSentHandler:(nullable void (^)())requestSentHandler;

/*!
@brief Mark any open session with the currently connected Video player as expired.
@param clientQueue Queue to invoke callbacks on
@param requestSentHandler Called after the request has been sent
*/
- (void)disconnect:(dispatch_queue_t _Nonnull)clientQueue requestSentHandler:(nullable void (^)())requestSentHandler;

/*!
@brief Send a ContentLauncher:LaunchURL request to a TV
Original file line number Diff line number Diff line change
@@ -402,6 +402,28 @@ - (void)verifyOrEstablishConnection:(VideoPlayer * _Nonnull)videoPlayer
});
}

- (void)shutdownAllSubscriptions:(dispatch_queue_t _Nonnull)clientQueue requestSentHandler:(nullable void (^)())requestSentHandler
{
ChipLogProgress(AppServer, "CastingServerBridge().shutdownAllSubscriptions() called");
dispatch_async(_chipWorkQueue, ^{
CastingServer::GetInstance()->ShutdownAllSubscriptions();
dispatch_async(clientQueue, ^{
requestSentHandler();
});
});
}

- (void)disconnect:(dispatch_queue_t _Nonnull)clientQueue requestSentHandler:(nullable void (^)())requestSentHandler
{
ChipLogProgress(AppServer, "CastingServerBridge().disconnect() called");
dispatch_async(_chipWorkQueue, ^{
CastingServer::GetInstance()->Disconnect();
dispatch_async(clientQueue, ^{
requestSentHandler();
});
});
}

- (void)contentLauncher_launchUrl:(ContentApp * _Nonnull)contentApp
contentUrl:(NSString * _Nonnull)contentUrl
contentDisplayStr:(NSString * _Nonnull)contentDisplayStr
10 changes: 10 additions & 0 deletions examples/tv-casting-app/tv-casting-common/include/CastingServer.h
Original file line number Diff line number Diff line change
@@ -96,6 +96,16 @@ class CastingServer

CHIP_ERROR PurgeVideoPlayerCache();

/**
* Tears down all active subscriptions.
*/
void ShutdownAllSubscriptions();

/**
* Mark any open session with the currently connected Video player as expired.
*/
void Disconnect();

/**
* @brief Content Launcher cluster
*/
22 changes: 22 additions & 0 deletions examples/tv-casting-app/tv-casting-common/src/CastingServer.cpp
Original file line number Diff line number Diff line change
@@ -424,6 +424,28 @@ void CastingServer::SetDefaultFabricIndex(std::function<void(TargetVideoPlayerIn
ChipLogError(AppServer, " -- No initialized fabrics with video players");
}

void CastingServer::ShutdownAllSubscriptions()
{
ChipLogProgress(AppServer, "Shutting down ALL Subscriptions");
app::InteractionModelEngine::GetInstance()->ShutdownAllSubscriptions();
}

void CastingServer::Disconnect()
{
TargetVideoPlayerInfo * currentVideoPlayer = GetActiveTargetVideoPlayer();

if (currentVideoPlayer != nullptr && currentVideoPlayer->IsInitialized())
{
chip::OperationalDeviceProxy * operationalDeviceProxy = currentVideoPlayer->GetOperationalDeviceProxy();
if (operationalDeviceProxy != nullptr)
{
ChipLogProgress(AppServer, "Disconnecting from VideoPlayer with nodeId=0x" ChipLogFormatX64 " fabricIndex=%d",
ChipLogValueX64(currentVideoPlayer->GetNodeId()), currentVideoPlayer->GetFabricIndex());
operationalDeviceProxy->Disconnect();
}
}
}

/**
* @brief Content Launcher cluster
*/

0 comments on commit 957034d

Please sign in to comment.