Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Take connection operations off the UI thread (#122) #25580

Merged
merged 2 commits into from
Mar 10, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import com.chip.casting.TvCastingApp;
import com.chip.casting.VideoPlayer;
import com.chip.casting.util.GlobalCastingConstants;
import java.util.concurrent.Executors;

/** A {@link Fragment} to get the TV Casting App commissioned / connected. */
public class ConnectionFragment extends Fragment {
Expand All @@ -28,6 +29,9 @@ public class ConnectionFragment extends Fragment {
private boolean openCommissioningWindowSuccess;
private boolean sendUdcSuccess;

private TextView commissioningWindowStatusView;
private TextView onboardingPayloadView;

public ConnectionFragment(TvCastingApp tvCastingApp, DiscoveredNodeData selectedCommissioner) {
this.tvCastingApp = tvCastingApp;
this.selectedCommissioner = selectedCommissioner;
Expand All @@ -52,97 +56,123 @@ public void onCreate(Bundle savedInstanceState) {
@Override
public View onCreateView(
LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Callback callback = (ConnectionFragment.Callback) this.getActivity();

SuccessCallback<VideoPlayer> onConnectionSuccess =
new SuccessCallback<VideoPlayer>() {
@Override
public void handle(VideoPlayer videoPlayer) {
Log.d(TAG, "handle() called on OnConnectionSuccess with " + videoPlayer);
callback.handleCommissioningComplete();
}
};

FailureCallback onConnectionFailure =
new FailureCallback() {
@Override
public void handle(MatterError matterError) {
Log.d(TAG, "handle() called on OnConnectionFailure with " + matterError);
}
};

SuccessCallback<ContentApp> onNewOrUpdatedEndpoints =
new SuccessCallback<ContentApp>() {
@Override
public void handle(ContentApp contentApp) {
Log.d(TAG, "handle() called on OnNewOrUpdatedEndpoint with " + contentApp);
}
};

if (selectedCommissioner != null && selectedCommissioner.isPreCommissioned()) {
VideoPlayer videoPlayer = selectedCommissioner.toConnectableVideoPlayer();
Log.d(TAG, "Calling verifyOrEstablishConnectionSuccess with VideoPlayer: " + videoPlayer);
tvCastingApp.verifyOrEstablishConnection(
videoPlayer, onConnectionSuccess, onConnectionFailure, onNewOrUpdatedEndpoints);
} else {
Log.d(TAG, "Running commissioning");
this.openCommissioningWindowSuccess =
tvCastingApp.openBasicCommissioningWindow(
GlobalCastingConstants.CommissioningWindowDurationSecs,
new MatterCallbackHandler() {
@Override
public void handle(MatterError error) {
Log.d(TAG, "handle() called on CommissioningComplete event with " + error);
}
},
onConnectionSuccess,
onConnectionFailure,
onNewOrUpdatedEndpoints);

if (this.openCommissioningWindowSuccess) {
if (selectedCommissioner != null && selectedCommissioner.getNumIPs() > 0) {
String ipAddress = selectedCommissioner.getIpAddresses().get(0).getHostAddress();
Log.d(
TAG,
"ConnectionFragment calling tvCastingApp.sendUserDirectedCommissioningRequest with IP: "
+ ipAddress
+ " port: "
+ selectedCommissioner.getPort());

this.sendUdcSuccess = tvCastingApp.sendCommissioningRequest(selectedCommissioner);
}
}
}

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

@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
String commissioningWindowStatus = "";
if (selectedCommissioner != null && selectedCommissioner.isPreCommissioned()) {
commissioningWindowStatus = "Establishing connection with selected Video Player";
} else {
commissioningWindowStatus = "Failed to open commissioning window";
if (this.openCommissioningWindowSuccess) {
commissioningWindowStatus = "Commissioning window has been opened. Commission manually.";
if (this.sendUdcSuccess) {
commissioningWindowStatus =
"Commissioning window has been opened. Commissioning requested from "
+ selectedCommissioner.getDeviceName();
}
TextView onboardingPayloadView = getView().findViewById(R.id.onboardingPayload);
onboardingPayloadView.setText(
"Onboarding PIN: "
+ GlobalCastingConstants.SetupPasscode
+ "\nDiscriminator: "
+ GlobalCastingConstants.Discriminator);
onboardingPayloadView = getView().findViewById(R.id.onboardingPayload);
commissioningWindowStatusView = getView().findViewById(R.id.commissioningWindowStatus);

String commissioningWindowStatus =
(selectedCommissioner != null && selectedCommissioner.isPreCommissioned())
? "Establishing CASE session with video player..."
: "Requesting to be commissioned by the video player...";
commissioningWindowStatusView.setText(commissioningWindowStatus);

Executors.newSingleThreadExecutor()
.submit(
() -> {
Callback callback = (ConnectionFragment.Callback) this.getActivity();

SuccessCallback<VideoPlayer> onConnectionSuccess =
new SuccessCallback<VideoPlayer>() {
@Override
public void handle(VideoPlayer videoPlayer) {
Log.d(TAG, "handle() called on OnConnectionSuccess with " + videoPlayer);
callback.handleCommissioningComplete();
}
};

FailureCallback onConnectionFailure =
new FailureCallback() {
@Override
public void handle(MatterError matterError) {
Log.d(TAG, "handle() called on OnConnectionFailure with " + matterError);
}
};

SuccessCallback<ContentApp> onNewOrUpdatedEndpoints =
new SuccessCallback<ContentApp>() {
@Override
public void handle(ContentApp contentApp) {
Log.d(TAG, "handle() called on OnNewOrUpdatedEndpoint with " + contentApp);
}
};

if (selectedCommissioner != null && selectedCommissioner.isPreCommissioned()) {
VideoPlayer videoPlayer = selectedCommissioner.toConnectableVideoPlayer();
Log.d(
TAG,
"Calling verifyOrEstablishConnectionSuccess with VideoPlayer: " + videoPlayer);
tvCastingApp.verifyOrEstablishConnection(
videoPlayer, onConnectionSuccess, onConnectionFailure, onNewOrUpdatedEndpoints);
} else {
beginCommissioning(
onConnectionSuccess, onConnectionFailure, onNewOrUpdatedEndpoints);
}
});
}

private void beginCommissioning(
SuccessCallback<VideoPlayer> onConnectionSuccess,
FailureCallback onConnectionFailure,
SuccessCallback<ContentApp> onNewOrUpdatedEndpoints) {
Log.d(TAG, "Running commissioning");
this.openCommissioningWindowSuccess =
tvCastingApp.openBasicCommissioningWindow(
GlobalCastingConstants.CommissioningWindowDurationSecs,
new MatterCallbackHandler() {
@Override
public void handle(MatterError error) {
Log.d(TAG, "handle() called on CommissioningComplete event with " + error);
}
},
onConnectionSuccess,
onConnectionFailure,
onNewOrUpdatedEndpoints);

if (this.openCommissioningWindowSuccess) {
if (selectedCommissioner != null && selectedCommissioner.getNumIPs() > 0) {
String ipAddress = selectedCommissioner.getIpAddresses().get(0).getHostAddress();
Log.d(
TAG,
"ConnectionFragment calling tvCastingApp.sendUserDirectedCommissioningRequest with IP: "
+ ipAddress
+ " port: "
+ selectedCommissioner.getPort());

this.sendUdcSuccess = tvCastingApp.sendCommissioningRequest(selectedCommissioner);
updateUiOnConnectionSuccess();
}
} else {
getActivity()
.runOnUiThread(
() -> {
commissioningWindowStatusView.setText("Failed to open commissioning window");
});
}
}

TextView commissioningWindowStatusView = getView().findViewById(R.id.commissioningWindowStatus);
commissioningWindowStatusView.setText(commissioningWindowStatus);
private void updateUiOnConnectionSuccess() {
getActivity()
.runOnUiThread(
() -> {
String finalCommissioningWindowStatus =
"Commissioning window has been opened. Commission manually.";
if (this.sendUdcSuccess) {
finalCommissioningWindowStatus =
"Commissioning window has been opened. Commissioning requested from "
+ selectedCommissioner.getDeviceName();
}
onboardingPayloadView.setText(
"Onboarding PIN: "
+ GlobalCastingConstants.SetupPasscode
+ "\nDiscriminator: "
+ GlobalCastingConstants.Discriminator);
commissioningWindowStatusView.setText(finalCommissioningWindowStatus);
});
}

/** Interface for notifying the host. */
Expand Down