Skip to content

Commit

Permalink
TV Android app - Add commissioning User Prompter to TV android app (#…
Browse files Browse the repository at this point in the history
…18926)

* Initial commit

* Update logic with callbacks

* Minor fixes

* restyle fix

* Update examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/MatterCommissioningPrompter.java

Co-authored-by: chrisdecenzo <61757564+chrisdecenzo@users.noreply.github.com>

* Update examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/MatterCommissioningPrompter.java

Co-authored-by: chrisdecenzo <61757564+chrisdecenzo@users.noreply.github.com>

* Update examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/MatterCommissioningPrompter.java

Co-authored-by: chrisdecenzo <61757564+chrisdecenzo@users.noreply.github.com>

* Update examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/MatterCommissioningPrompter.java

Co-authored-by: chrisdecenzo <61757564+chrisdecenzo@users.noreply.github.com>

* Update examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/MatterCommissioningPrompter.java

Co-authored-by: chrisdecenzo <61757564+chrisdecenzo@users.noreply.github.com>

* Update examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/MatterCommissioningPrompter.java

Co-authored-by: chrisdecenzo <61757564+chrisdecenzo@users.noreply.github.com>

* Restyle fix

* Converted the error to string

* Fix activity

* Restyle fix

* Update examples/tv-app/android/java/src/com/tcl/chip/tvapp/UserPrompterResolver.java

* Update examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/MainActivity.java

* Update examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/MatterCommissioningPrompter.java

* Update examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/MatterCommissioningPrompter.java

* Update examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/MatterCommissioningPrompter.java

* Update examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/MatterCommissioningPrompter.java

* Update examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/MatterCommissioningPrompter.java

* Restyle fix

Co-authored-by: chrisdecenzo <61757564+chrisdecenzo@users.noreply.github.com>
  • Loading branch information
2 people authored and pull[bot] committed Jan 3, 2024
1 parent aeaaef2 commit 243431d
Show file tree
Hide file tree
Showing 19 changed files with 635 additions and 78 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import com.matter.tv.server.fragments.ContentAppFragment;
import com.matter.tv.server.fragments.QrCodeFragment;
import com.matter.tv.server.fragments.TerminalFragment;
import com.matter.tv.server.service.MatterServant;
import java.util.LinkedHashMap;

public class MainActivity extends AppCompatActivity {
Expand All @@ -18,13 +19,13 @@ public class MainActivity extends AppCompatActivity {
Fragment selectedFragment = null;
switch (item.getItemId()) {
case R.id.content_app:
selectedFragment = new ContentAppFragment();
selectedFragment = ContentAppFragment.newInstance();
break;
case R.id.qr_code:
selectedFragment = new QrCodeFragment();
selectedFragment = QrCodeFragment.newInstance();
break;
case R.id.terminal:
selectedFragment = new TerminalFragment();
selectedFragment = TerminalFragment.newInstance();
break;
}

Expand All @@ -40,6 +41,10 @@ protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

// MainActivity is needed to launch dialog prompt
// in UserPrompter
MatterServant.get().setActivity(this);

BottomNavigationView bottomNavigationView = findViewById(R.id.bottom_navigation);
bottomNavigationView.setOnItemSelectedListener(navListener);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
package com.matter.tv.server;

import static androidx.core.content.ContextCompat.getSystemService;

import android.app.Activity;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.os.Build;
import android.util.Log;
import android.widget.EditText;
import androidx.appcompat.app.AlertDialog;
import androidx.core.app.NotificationCompat;
import com.tcl.chip.tvapp.UserPrompter;
import com.tcl.chip.tvapp.UserPrompterResolver;

public class MatterCommissioningPrompter extends UserPrompterResolver implements UserPrompter {

private Activity activity;
private NotificationManager notificationManager;
private final String CHANNEL_ID = "MatterCommissioningPrompter.CHANNEL";
private final int SUCCESS_ID = 0;
private final int FAIL_ID = 1;

public MatterCommissioningPrompter(Activity activity) {
this.activity = activity;
this.createNotificationChannel();
}

public void promptForCommissionOkPermission(
int vendorId, int productId, String commissioneeName) {
// TODO: find app by vendorId and productId
Log.d(
TAG,
"Received prompt for OK permission vendor id:"
+ vendorId
+ " productId:"
+ productId
+ ". Commissionee: "
+ commissioneeName);
AlertDialog.Builder builder = new AlertDialog.Builder(activity);

builder
.setMessage(commissioneeName + " is requesting permission to cast to this device, approve?")
.setTitle("Allow access to " + commissioneeName)
.setPositiveButton(
"Ok",
(dialog, which) -> {
OnPromptAccepted();
})
.setNegativeButton(
"Cancel",
(dialog, which) -> {
OnPromptDeclined();
})
.create()
.show();
}

@Override
public void promptForCommissionPinCode(int vendorId, int productId, String commissioneeName) {
// TODO: find app by vendorId and productId
Log.d(
TAG,
"Received prompt for PIN code vendor id:"
+ vendorId
+ " productId:"
+ productId
+ ". Commissionee: "
+ commissioneeName);
EditText editText = new EditText(activity);
AlertDialog.Builder builder = new AlertDialog.Builder(activity);

builder
.setMessage("Please enter PIN displayed in casting app.")
.setTitle("Allow access to " + commissioneeName)
.setView(editText)
.setPositiveButton(
"Ok",
(dialog, which) -> {
String pinCode = editText.getText().toString();
OnPinCodeEntered(Integer.parseInt(pinCode));
})
.setNegativeButton(
"Cancel",
(dialog, which) -> {
OnPinCodeDeclined();
})
.create()
.show();
}

public void promptCommissioningSucceeded(int vendorId, int productId, String commissioneeName) {
Log.d(
TAG,
"Received prompt for success vendor id:"
+ vendorId
+ " productId:"
+ productId
+ ". Commissionee: "
+ commissioneeName);
NotificationCompat.Builder builder =
new NotificationCompat.Builder(activity, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_baseline_check_24)
.setContentTitle("Connection Complete")
.setContentText(
"Success. "
+ commissioneeName
+ " can now cast to this device. Visit settings to manage access control for casting.")
.setPriority(NotificationCompat.PRIORITY_DEFAULT);

notificationManager.notify(SUCCESS_ID, builder.build());
}

public void promptCommissioningFailed(String commissioneeName, String error) {
Log.d(
TAG,
"Received prompt for failure vendor id:"
+ vendorId
+ " productId:"
+ productId
+ ". Commissionee: "
+ commissioneeName);
NotificationCompat.Builder builder =
new NotificationCompat.Builder(activity, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_baseline_clear_24)
.setContentTitle("Connection Failed")
.setContentText("Failed. " + commissioneeName + " experienced error: " + error + ".")
.setPriority(NotificationCompat.PRIORITY_DEFAULT);

notificationManager.notify(FAIL_ID, builder.build());
}

private void createNotificationChannel() {
// Create the NotificationChannel, but only on API 26+ because
// the NotificationChannel class is new and not in the support library
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
CharSequence name = "MatterPromptNotificationChannel";
String description = "Matter Channel for sending notifications";
int importance = NotificationManager.IMPORTANCE_DEFAULT;
NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, importance);
channel.setDescription(description);
// Register the channel with the system; you can't change the importance
// or other notification behaviors after this
this.notificationManager = getSystemService(activity, NotificationManager.class);
notificationManager.createNotificationChannel(channel);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,9 @@ public ContentAppFragment() {
* Use this factory method to create a new instance of this fragment using the provided
* parameters.
*
* @param param1 Parameter 1.
* @param param2 Parameter 2.
* @return A new instance of fragment SettingsFragment.
*/
// TODO: Rename and change types and number of parameters
public static ContentAppFragment newInstance(String param1, String param2) {
public static ContentAppFragment newInstance() {
ContentAppFragment fragment = new ContentAppFragment();
Bundle args = new Bundle();
fragment.setArguments(args);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,9 @@ public QrCodeFragment() {
* Use this factory method to create a new instance of this fragment using the provided
* parameters.
*
* @param param1 Parameter 1.
* @param param2 Parameter 2.
* @return A new instance of fragment QrCodeFragment.
*/
// TODO: Rename and change types and number of parameters
public static QrCodeFragment newInstance(String param1, String param2) {
public static QrCodeFragment newInstance() {
QrCodeFragment fragment = new QrCodeFragment();
Bundle args = new Bundle();
fragment.setArguments(args);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,9 @@ public TerminalFragment() {
* Use this factory method to create a new instance of this fragment using the provided
* parameters.
*
* @param param1 Parameter 1.
* @param param2 Parameter 2.
* @return A new instance of fragment CommssionerFragment.
*/
// TODO: Rename and change types and number of parameters
public static TerminalFragment newInstance(String param1, String param2) {
public static TerminalFragment newInstance() {
TerminalFragment fragment = new TerminalFragment();
Bundle args = new Bundle();
fragment.setArguments(args);
Expand Down Expand Up @@ -63,10 +60,7 @@ public void onResume() {

AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());

builder.setMessage(message).setTitle("Command response:");

AlertDialog dialog = builder.create();
dialog.show();
builder.setMessage(message).setTitle("Response").create().show();
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
*/
package com.matter.tv.server.service;

import android.app.Activity;
import android.content.Context;
import android.util.Log;
import androidx.annotation.NonNull;
Expand All @@ -28,6 +29,7 @@
import chip.platform.NsdManagerServiceResolver;
import chip.platform.PreferencesConfigurationManager;
import chip.platform.PreferencesKeyValueStoreManager;
import com.matter.tv.server.MatterCommissioningPrompter;
import com.matter.tv.server.handlers.ContentAppEndpointManagerImpl;
import com.matter.tv.server.model.ContentApp;
import com.tcl.chip.tvapp.ChannelManagerStub;
Expand Down Expand Up @@ -66,6 +68,7 @@ public static MatterServant get() {
}

private Context context;
private Activity activity;

public void init(@NonNull Context context) {

Expand Down Expand Up @@ -113,6 +116,7 @@ public void init(@NonNull Context context) {
}
});
mTvApp.setDACProvider(new DACProviderStub());
mTvApp.setUserPrompter(new MatterCommissioningPrompter(activity));

mTvApp.setChipDeviceEventProvider(
new DeviceEventProvider() {
Expand Down Expand Up @@ -152,6 +156,10 @@ public void toggleOnOff() {
mIsOn = !mIsOn;
}

public void setActivity(Activity activity) {
this.activity = activity;
}

public void sendCustomCommand(String customCommand) {
Log.i(MatterServant.class.getName(), customCommand);
// TODO: insert logic ot send custom command here
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M9,16.17L4.83,12l-1.42,1.41L9,19 21,7l-1.41,-1.41z"/>
</vector>
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12z"/>
</vector>
6 changes: 6 additions & 0 deletions examples/tv-app/android/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ shared_library("jni") {
"java/MediaInputManager.h",
"java/MediaPlaybackManager.cpp",
"java/MediaPlaybackManager.h",
"java/MyUserPrompter-JNI.cpp",
"java/MyUserPrompter-JNI.h",
"java/MyUserPrompterResolver-JNI.cpp",
"java/MyUserPrompterResolver-JNI.h",
"java/OnOffManager.cpp",
"java/OnOffManager.h",
"java/TVApp-JNI.cpp",
Expand Down Expand Up @@ -129,6 +133,8 @@ android_library("java") {
"java/src/com/tcl/chip/tvapp/OnOffManagerStub.java",
"java/src/com/tcl/chip/tvapp/TvApp.java",
"java/src/com/tcl/chip/tvapp/TvAppCallback.java",
"java/src/com/tcl/chip/tvapp/UserPrompter.java",
"java/src/com/tcl/chip/tvapp/UserPrompterResolver.java",
"java/src/com/tcl/chip/tvapp/WakeOnLanManager.java",
"java/src/com/tcl/chip/tvapp/WakeOnLanManagerStub.java",
]
Expand Down
Loading

0 comments on commit 243431d

Please sign in to comment.