Skip to content

Commit 9325472

Browse files
Android TvCasting app: Cache/recall/re-target previously connected VideoPlayers/Endpoints
1 parent aad708c commit 9325472

28 files changed

+1428
-472
lines changed

examples/tv-casting-app/android/App/app/src/main/java/com/chip/casting/app/CastingContext.java

-6
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package com.chip.casting.app;
22

33
import android.content.Context;
4-
import android.net.nsd.NsdManager;
54
import android.widget.LinearLayout;
65
import androidx.fragment.app.FragmentActivity;
76

@@ -20,11 +19,6 @@ public FragmentActivity getFragmentActivity() {
2019
return fragmentActivity;
2120
}
2221

23-
public NsdManager getNsdManager() {
24-
return (NsdManager)
25-
fragmentActivity.getApplicationContext().getSystemService(Context.NSD_SERVICE);
26-
}
27-
2822
public LinearLayout getCommissionersLayout() {
2923
return (LinearLayout) fragmentActivity.findViewById(R.id.castingCommissioners);
3024
}

examples/tv-casting-app/android/App/app/src/main/java/com/chip/casting/app/CommissionerDiscoveryFragment.java

+83-39
Original file line numberDiff line numberDiff line change
@@ -4,39 +4,46 @@
44
import android.net.nsd.NsdManager;
55
import android.net.wifi.WifiManager;
66
import android.os.Bundle;
7+
import android.os.Handler;
8+
import android.os.Looper;
79
import android.util.Log;
810
import android.view.LayoutInflater;
911
import android.view.View;
1012
import android.view.ViewGroup;
1113
import android.widget.Button;
14+
import android.widget.LinearLayout;
1215
import androidx.annotation.Nullable;
16+
import androidx.annotation.VisibleForTesting;
1317
import androidx.fragment.app.Fragment;
14-
import com.chip.casting.dnssd.CommissionerDiscoveryListener;
15-
import com.chip.casting.dnssd.DiscoveredNodeData;
16-
import com.chip.casting.util.GlobalCastingConstants;
17-
import java.util.concurrent.Executors;
18-
import java.util.concurrent.TimeUnit;
18+
import com.chip.casting.DiscoveredNodeData;
19+
import com.chip.casting.FailureCallback;
20+
import com.chip.casting.MatterError;
21+
import com.chip.casting.SuccessCallback;
22+
import com.chip.casting.TvCastingApp;
1923

2024
/** A {@link Fragment} to discover commissioners on the network */
2125
public class CommissionerDiscoveryFragment extends Fragment {
2226
private static final String TAG = CommissionerDiscoveryFragment.class.getSimpleName();
27+
private static final long DISCOVERY_DURATION_SECS = 10;
28+
private final TvCastingApp tvCastingApp;
2329

24-
public CommissionerDiscoveryFragment() {}
30+
public CommissionerDiscoveryFragment(TvCastingApp tvCastingApp) {
31+
this.tvCastingApp = tvCastingApp;
32+
}
2533

2634
/**
2735
* Use this factory method to create a new instance of this fragment using the provided
2836
* parameters.
2937
*
3038
* @return A new instance of fragment CommissionerDiscoveryFragment.
3139
*/
32-
public static CommissionerDiscoveryFragment newInstance() {
33-
return new CommissionerDiscoveryFragment();
40+
public static CommissionerDiscoveryFragment newInstance(TvCastingApp tvCastingApp) {
41+
return new CommissionerDiscoveryFragment(tvCastingApp);
3442
}
3543

3644
@Override
3745
public void onCreate(Bundle savedInstanceState) {
3846
super.onCreate(savedInstanceState);
39-
startCommissionerDiscovery();
4047
}
4148

4249
@Override
@@ -49,47 +56,84 @@ public View onCreateView(
4956
@Override
5057
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
5158
super.onViewCreated(view, savedInstanceState);
59+
5260
Button manualCommissioningButton = getView().findViewById(R.id.manualCommissioningButton);
5361
Callback callback = (Callback) this.getActivity();
54-
manualCommissioningButton.setOnClickListener(
62+
View.OnClickListener manualCommissioningButtonOnClickListener =
5563
new View.OnClickListener() {
5664
@Override
5765
public void onClick(View v) {
5866
callback.handleCommissioningButtonClicked(null);
5967
}
60-
});
61-
}
68+
};
69+
manualCommissioningButton.setOnClickListener(manualCommissioningButtonOnClickListener);
70+
71+
Context context = this.getContext();
72+
Context applicationContext = this.getContext().getApplicationContext();
73+
74+
SuccessCallback<DiscoveredNodeData> successCallback =
75+
new SuccessCallback<DiscoveredNodeData>() {
76+
@Override
77+
public void handle(DiscoveredNodeData discoveredNodeData) {
78+
Log.d(TAG, "Discovered a Video Player Commissioner: " + discoveredNodeData);
79+
String buttonText = getCommissionerButtonText(discoveredNodeData);
6280

63-
private void startCommissionerDiscovery() {
64-
Log.d(TAG, "CommissionerDiscoveryFragment.startCommissionerDiscovery called");
65-
WifiManager wifi = (WifiManager) this.getContext().getSystemService(Context.WIFI_SERVICE);
66-
WifiManager.MulticastLock multicastLock = wifi.createMulticastLock("multicastLock");
67-
multicastLock.setReferenceCounted(true);
68-
multicastLock.acquire();
81+
if (!buttonText.isEmpty()) {
82+
Button commissionerButton = new Button(context);
83+
commissionerButton.setText(buttonText);
84+
CommissionerDiscoveryFragment.Callback callback =
85+
(CommissionerDiscoveryFragment.Callback) getActivity();
86+
commissionerButton.setOnClickListener(
87+
new View.OnClickListener() {
88+
@Override
89+
public void onClick(View v) {
90+
Log.d(
91+
TAG,
92+
"CommissionerResolveListener.onServiceResolved.OnClickListener.onClick called for "
93+
+ discoveredNodeData);
94+
callback.handleCommissioningButtonClicked(discoveredNodeData);
95+
}
96+
});
97+
new Handler(Looper.getMainLooper())
98+
.post(
99+
() ->
100+
((LinearLayout) getActivity().findViewById(R.id.castingCommissioners))
101+
.addView(commissionerButton));
102+
}
103+
}
104+
};
69105

70-
CastingContext castingContext = new CastingContext(this.getActivity());
71-
NsdManager.DiscoveryListener commissionerDiscoveryListener =
72-
new CommissionerDiscoveryListener(castingContext);
106+
FailureCallback failureCallback =
107+
new FailureCallback() {
108+
@Override
109+
public void handle(MatterError matterError) {
110+
Log.e(TAG, "Error occurred during video player commissioner discovery: " + matterError);
111+
}
112+
};
73113

74-
NsdManager nsdManager = castingContext.getNsdManager();
75-
nsdManager.discoverServices(
76-
GlobalCastingConstants.CommissionerServiceType,
77-
NsdManager.PROTOCOL_DNS_SD,
78-
commissionerDiscoveryListener);
114+
tvCastingApp.discoverVideoPlayerCommissioners(
115+
(WifiManager) context.getSystemService(Context.WIFI_SERVICE),
116+
(NsdManager) applicationContext.getSystemService(Context.NSD_SERVICE),
117+
DISCOVERY_DURATION_SECS,
118+
successCallback,
119+
failureCallback);
120+
}
79121

80-
// Stop discovery after specified timeout
81-
Executors.newSingleThreadScheduledExecutor()
82-
.schedule(
83-
new Runnable() {
84-
@Override
85-
public void run() {
86-
nsdManager.stopServiceDiscovery(commissionerDiscoveryListener);
87-
multicastLock.release();
88-
}
89-
},
90-
10,
91-
TimeUnit.SECONDS);
92-
Log.d(TAG, "CommissionerDiscoveryFragment.startCommissionerDiscovery ended");
122+
@VisibleForTesting
123+
public String getCommissionerButtonText(DiscoveredNodeData commissioner) {
124+
String main = commissioner.getDeviceName() != null ? commissioner.getDeviceName() : "";
125+
String aux =
126+
"" + (commissioner.getProductId() > 0 ? "Product ID: " + commissioner.getProductId() : "");
127+
aux +=
128+
commissioner.getDeviceType() > 0
129+
? (aux.isEmpty() ? "" : " ") + "Device Type: " + commissioner.getDeviceType()
130+
: "";
131+
aux +=
132+
commissioner.getVendorId() > 0
133+
? (aux.isEmpty() ? "" : " from ") + "Vendor ID: " + commissioner.getVendorId()
134+
: "";
135+
aux = aux.isEmpty() ? aux : "\n[" + aux + "]";
136+
return main + aux;
93137
}
94138

95139
/** Interface for notifying the host. */

examples/tv-casting-app/android/App/app/src/main/java/com/chip/casting/app/CommissioningFragment.java

+25-7
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,14 @@
88
import android.widget.TextView;
99
import androidx.annotation.Nullable;
1010
import androidx.fragment.app.Fragment;
11+
import com.chip.casting.ContentApp;
12+
import com.chip.casting.DiscoveredNodeData;
13+
import com.chip.casting.FailureCallback;
1114
import com.chip.casting.MatterCallbackHandler;
1215
import com.chip.casting.MatterError;
16+
import com.chip.casting.SuccessCallback;
1317
import com.chip.casting.TvCastingApp;
14-
import com.chip.casting.dnssd.DiscoveredNodeData;
18+
import com.chip.casting.VideoPlayer;
1519
import com.chip.casting.util.GlobalCastingConstants;
1620

1721
/** A {@link Fragment} to get the TV Casting App commissioned. */
@@ -56,9 +60,25 @@ public View onCreateView(
5660
@Override
5761
public void handle(MatterError error) {
5862
Log.d(TAG, "handle() called on CommissioningComplete event with " + error);
59-
if (error.isNoError()) {
60-
callback.handleCommissioningComplete();
61-
}
63+
}
64+
},
65+
new SuccessCallback<VideoPlayer>() {
66+
@Override
67+
public void handle(VideoPlayer videoPlayer) {
68+
Log.d(TAG, "handle() called on OnConnectionSuccess with " + videoPlayer);
69+
callback.handleCommissioningComplete();
70+
}
71+
},
72+
new FailureCallback() {
73+
@Override
74+
public void handle(MatterError matterError) {
75+
Log.d(TAG, "handle() called on OnConnectionFailure with " + matterError);
76+
}
77+
},
78+
new SuccessCallback<ContentApp>() {
79+
@Override
80+
public void handle(ContentApp contentApp) {
81+
Log.d(TAG, "handle() called on OnNewOrUpdatedEndpoint with " + contentApp);
6282
}
6383
});
6484
if (this.openCommissioningWindowSuccess) {
@@ -71,9 +91,7 @@ public void handle(MatterError error) {
7191
+ " port: "
7292
+ selectedCommissioner.getPort());
7393

74-
this.sendUdcSuccess =
75-
tvCastingApp.sendUserDirectedCommissioningRequest(
76-
ipAddress, selectedCommissioner.getPort());
94+
this.sendUdcSuccess = tvCastingApp.sendCommissioningRequest(selectedCommissioner);
7795
}
7896
}
7997

examples/tv-casting-app/android/App/app/src/main/java/com/chip/casting/app/ContentLauncherFragment.java

+4
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import android.widget.TextView;
1010
import androidx.annotation.Nullable;
1111
import androidx.fragment.app.Fragment;
12+
import com.chip.casting.ContentApp;
1213
import com.chip.casting.MatterCallbackHandler;
1314
import com.chip.casting.MatterError;
1415
import com.chip.casting.TvCastingApp;
@@ -21,6 +22,8 @@ public class ContentLauncherFragment extends Fragment {
2122

2223
private View.OnClickListener launchUrlButtonClickListener;
2324

25+
private static final ContentApp kContentApp = new ContentApp((short) 4, null);
26+
2427
public ContentLauncherFragment(TvCastingApp tvCastingApp) {
2528
this.tvCastingApp = tvCastingApp;
2629
}
@@ -52,6 +55,7 @@ public void onClick(View v) {
5255
EditText contentDisplayString =
5356
getView().findViewById(R.id.contentDisplayStringEditText);
5457
tvCastingApp.contentLauncherLaunchURL(
58+
kContentApp,
5559
contentUrl.getText().toString(),
5660
contentDisplayString.getText().toString(),
5761
new MatterCallbackHandler() {

examples/tv-casting-app/android/App/app/src/main/java/com/chip/casting/app/MainActivity.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@
1616
import chip.platform.PreferencesConfigurationManager;
1717
import chip.platform.PreferencesKeyValueStoreManager;
1818
import com.chip.casting.DACProviderStub;
19+
import com.chip.casting.DiscoveredNodeData;
1920
import com.chip.casting.TvCastingApp;
20-
import com.chip.casting.dnssd.DiscoveredNodeData;
2121
import com.chip.casting.util.GlobalCastingConstants;
2222

2323
public class MainActivity extends AppCompatActivity
@@ -37,7 +37,7 @@ protected void onCreate(Bundle savedInstanceState) {
3737

3838
initJni();
3939

40-
Fragment fragment = CommissionerDiscoveryFragment.newInstance();
40+
Fragment fragment = CommissionerDiscoveryFragment.newInstance(tvCastingApp);
4141
getSupportFragmentManager()
4242
.beginTransaction()
4343
.add(R.id.main_fragment_container, fragment, fragment.getClass().getSimpleName())

examples/tv-casting-app/android/App/app/src/main/java/com/chip/casting/app/MediaPlaybackFragment.java

+4
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import android.widget.TextView;
99
import androidx.annotation.Nullable;
1010
import androidx.fragment.app.Fragment;
11+
import com.chip.casting.ContentApp;
1112
import com.chip.casting.FailureCallback;
1213
import com.chip.casting.MatterError;
1314
import com.chip.casting.MediaPlaybackTypes;
@@ -23,6 +24,8 @@ public class MediaPlaybackFragment extends Fragment {
2324

2425
private View.OnClickListener subscribeToCurrentStateButtonClickListener;
2526

27+
private static final ContentApp kContentApp = new ContentApp((short) 4, null);
28+
2629
public MediaPlaybackFragment(TvCastingApp tvCastingApp) {
2730
this.tvCastingApp = tvCastingApp;
2831
}
@@ -107,6 +110,7 @@ public void run() {
107110

108111
boolean retVal =
109112
tvCastingApp.mediaPlayback_subscribeToCurrentState(
113+
kContentApp,
110114
successCallback,
111115
failureCallback,
112116
Integer.parseInt(minInterval.getText().toString()),

examples/tv-casting-app/android/App/app/src/main/java/com/chip/casting/dnssd/CommissionerDiscoveryListener.java

-62
This file was deleted.

0 commit comments

Comments
 (0)