From c84a4421d9e2baa388fff7cffa77ff61cc4796b4 Mon Sep 17 00:00:00 2001 From: amitnj <74272437+amitnj@users.noreply.github.com> Date: Thu, 1 Sep 2022 16:01:32 -0700 Subject: [PATCH] Refactor to separate app platform code. support dynamic discovery. (#22298) --- .../com/matter/tv/server/MainActivity.java | 4 +- .../server/fragments/ContentAppFragment.java | 34 ++---- .../receivers/ContentAppDiscoveryService.java | 33 +++-- .../tv/server/service/AppPlatformService.java | 114 ++++++++++++++++++ .../tv/server/service/MatterServant.java | 26 ---- .../server/service/MatterServantService.java | 9 +- examples/tv-app/android/BUILD.gn | 3 + examples/tv-app/android/java/AppImpl.cpp | 64 +++------- examples/tv-app/android/java/AppImpl.h | 5 +- .../tv-app/android/java/AppPlatform-JNI.cpp | 66 ++++++++++ .../tv-app/android/java/AppPlatform-JNI.h | 35 ++++++ .../java/ContentAppCommandDelegate.cpp | 25 ---- .../android/java/ContentAppCommandDelegate.h | 2 - .../java/MyUserPrompterResolver-JNI.cpp | 2 + examples/tv-app/android/java/TVApp-JNI.cpp | 28 ----- .../matter/tv/server/tvapp/AppPlatform.java | 42 +++++++ .../src/com/matter/tv/server/tvapp/TvApp.java | 12 -- 17 files changed, 313 insertions(+), 191 deletions(-) create mode 100644 examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/service/AppPlatformService.java create mode 100644 examples/tv-app/android/java/AppPlatform-JNI.cpp create mode 100644 examples/tv-app/android/java/AppPlatform-JNI.h create mode 100644 examples/tv-app/android/java/src/com/matter/tv/server/tvapp/AppPlatform.java diff --git a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/MainActivity.java b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/MainActivity.java index 2fb375dbed5c93..895685f03536c8 100644 --- a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/MainActivity.java +++ b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/MainActivity.java @@ -7,7 +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 com.matter.tv.server.service.AppPlatformService; import java.util.LinkedHashMap; public class MainActivity extends AppCompatActivity { @@ -43,7 +43,7 @@ protected void onCreate(Bundle savedInstanceState) { // MainActivity is needed to launch dialog prompt // in UserPrompter - MatterServant.get().setActivity(this); + AppPlatformService.get().setActivity(this); BottomNavigationView bottomNavigationView = findViewById(R.id.bottom_navigation); bottomNavigationView.setOnItemSelectedListener(navListener); diff --git a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/fragments/ContentAppFragment.java b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/fragments/ContentAppFragment.java index c99045fc3ddc28..8ffbd0e6349d39 100644 --- a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/fragments/ContentAppFragment.java +++ b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/fragments/ContentAppFragment.java @@ -5,21 +5,17 @@ import android.content.Intent; import android.content.IntentFilter; import android.os.Bundle; -import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; -import android.widget.Button; import android.widget.ListView; import android.widget.TextView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; import com.matter.tv.server.R; -import com.matter.tv.server.model.ContentApp; import com.matter.tv.server.receivers.ContentAppDiscoveryService; -import com.matter.tv.server.service.MatterServant; import java.util.ArrayList; /** @@ -99,20 +95,6 @@ public View getView(int position, @Nullable View convertView, @NonNull ViewGroup ViewHolder viewHolder = new ViewHolder(); viewHolder.appName = convertView.findViewById(R.id.appNameTextView); viewHolder.appName.setText(getItem(position)); - viewHolder.sendMessageButton = convertView.findViewById(R.id.sendMessageButton); - viewHolder.sendMessageButton.setText(R.string.send_command); - viewHolder.sendMessageButton.setOnClickListener( - view -> { - Log.i(TAG, "Button was clicked for " + position); - for (ContentApp app : - ContentAppDiscoveryService.getReceiverInstance() - .getDiscoveredContentApps() - .values()) { - if (app.getAppName().equals(getItem(position))) { - MatterServant.get().sendTestMessage(app.getEndpointId(), "My Native Message"); - } - } - }); convertView.setTag(viewHolder); } else { mainViewHolder = (ViewHolder) convertView.getTag(); @@ -128,9 +110,11 @@ private void registerReceiver(ArrayAdapter adapter) { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); - String packageName = intent.getStringExtra("com.matter.tv.server.appagent.add.pkg"); - if (action.equals("com.matter.tv.server.appagent.add") - || action.equals("com.matter.tv.server.appagent.remove")) { + String packageName = + intent.getStringExtra( + ContentAppDiscoveryService.DISCOVERY_APPAGENT_EXTRA_PACKAGENAME); + if (action.equals(ContentAppDiscoveryService.DISCOVERY_APPAGENT_ACTION_ADD) + || action.equals(ContentAppDiscoveryService.DISCOVERY_APPAGENT_ACTION_REMOVE)) { adapter.clear(); adapter.addAll( ContentAppDiscoveryService.getReceiverInstance() @@ -141,14 +125,16 @@ public void onReceive(Context context, Intent intent) { } }; getContext() - .registerReceiver(broadcastReceiver, new IntentFilter("com.matter.tv.server.appagent.add")); + .registerReceiver( + broadcastReceiver, + new IntentFilter(ContentAppDiscoveryService.DISCOVERY_APPAGENT_ACTION_ADD)); getContext() .registerReceiver( - broadcastReceiver, new IntentFilter("com.matter.tv.server.appagent.remove")); + broadcastReceiver, + new IntentFilter(ContentAppDiscoveryService.DISCOVERY_APPAGENT_ACTION_REMOVE)); } public class ViewHolder { TextView appName; - Button sendMessageButton; } } diff --git a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/receivers/ContentAppDiscoveryService.java b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/receivers/ContentAppDiscoveryService.java index 0c4555db2b86e0..ebdc10acd3a557 100644 --- a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/receivers/ContentAppDiscoveryService.java +++ b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/receivers/ContentAppDiscoveryService.java @@ -33,6 +33,13 @@ public class ContentAppDiscoveryService extends BroadcastReceiver { private static final String ANDROID_PACKAGE_ADDED_ACTION = "android.intent.action.PACKAGE_ADDED"; private static final String ANDROID_PACKAGE_REPLACED_ACTION = "android.intent.action.PACKAGE_REPLACED"; + public static final String DISCOVERY_APPAGENT_ACTION_ADD = "com.matter.tv.server.appagent.add"; + public static final String DISCOVERY_APPAGENT_ACTION_REMOVE = + "com.matter.tv.server.appagent.remove"; + public static final String DISCOVERY_APPAGENT_EXTRA_PACKAGENAME = + "com.matter.tv.server.appagent.pkg"; + public static final String DISCOVERY_APPAGENT_EXTRA_ENDPOINTID = + "com.matter.tv.server.appagent.endpointId"; private static ResourceUtils resourceUtils = ResourceUtils.getInstance(); @@ -105,9 +112,9 @@ private void handlePackageAdded(Context context, String pkg) { ContentApp app = new ContentApp(pkg, vendorName, vendorId, productId, supportedClusters); applications.put(pkg, app); - Intent in = new Intent("com.matter.tv.server.appagent.add"); + Intent in = new Intent(DISCOVERY_APPAGENT_ACTION_ADD); Bundle extras = new Bundle(); - extras.putString("com.matter.tv.server.appagent.add.pkg", pkg); + extras.putString(DISCOVERY_APPAGENT_EXTRA_PACKAGENAME, pkg); in.putExtras(extras); context.sendBroadcast(in); } catch (PackageManager.NameNotFoundException e) { @@ -117,15 +124,19 @@ private void handlePackageAdded(Context context, String pkg) { private void handlePackageRemoved(final Intent intent, final Context context) { String pkg = intent.getData().getSchemeSpecificPart(); - Log.i(TAG, pkg + " Removed."); - - applications.remove(pkg); - - Intent in = new Intent("com.matter.tv.server.appagent.remove"); - Bundle extras = new Bundle(); - extras.putString("com.matter.tv.server.appagent.add.pkg", pkg); - in.putExtras(extras); - context.sendBroadcast(in); + ContentApp contentApp = applications.get(pkg); + if (contentApp != null) { + applications.remove(pkg); + Intent in = new Intent(DISCOVERY_APPAGENT_ACTION_REMOVE); + Bundle extras = new Bundle(); + extras.putString(DISCOVERY_APPAGENT_EXTRA_PACKAGENAME, pkg); + extras.putInt(DISCOVERY_APPAGENT_EXTRA_ENDPOINTID, contentApp.getEndpointId()); + in.putExtras(extras); + context.sendBroadcast(in); + Log.i(TAG, "Removing Matter content app " + pkg); + } else { + Log.i(TAG, "App not found in set of Matter content apps. Doing nothing for app " + pkg); + } } public void registerSelf(Context context) { diff --git a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/service/AppPlatformService.java b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/service/AppPlatformService.java new file mode 100644 index 00000000000000..bb4ad37a1667c7 --- /dev/null +++ b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/service/AppPlatformService.java @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2021-2022 Project CHIP Authors + * All rights reserved. + * + * 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 com.matter.tv.server.service; + +import android.app.Activity; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import androidx.annotation.NonNull; +import com.matter.tv.server.MatterCommissioningPrompter; +import com.matter.tv.server.handlers.ContentAppEndpointManagerImpl; +import com.matter.tv.server.model.ContentApp; +import com.matter.tv.server.receivers.ContentAppDiscoveryService; +import com.matter.tv.server.tvapp.AppPlatform; + +public class AppPlatformService { + + private AppPlatform mAppPlatform; + private BroadcastReceiver mBroadcastReceiver; + + private AppPlatformService() {} + + private static class SingletonHolder { + static AppPlatformService instance = new AppPlatformService(); + } + + public static AppPlatformService get() { + return SingletonHolder.instance; + } + + private Context context; + private Activity activity; + + public void init(@NonNull Context context) { + this.context = context; + mAppPlatform = + new AppPlatform( + new MatterCommissioningPrompter(activity), new ContentAppEndpointManagerImpl(context)); + ContentAppDiscoveryService.getReceiverInstance().registerSelf(context.getApplicationContext()); + for (ContentApp app : + ContentAppDiscoveryService.getReceiverInstance().getDiscoveredContentApps().values()) { + addContentApp(app); + } + registerReceiver(); + } + + private void registerReceiver() { + mBroadcastReceiver = + new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + String packageName = + intent.getStringExtra( + ContentAppDiscoveryService.DISCOVERY_APPAGENT_EXTRA_PACKAGENAME); + if (action.equals(ContentAppDiscoveryService.DISCOVERY_APPAGENT_ACTION_ADD)) { + ContentApp app = + ContentAppDiscoveryService.getReceiverInstance() + .getDiscoveredContentApps() + .get(packageName); + addContentApp(app); + } else if (action.equals(ContentAppDiscoveryService.DISCOVERY_APPAGENT_ACTION_REMOVE)) { + int endpointId = + intent.getIntExtra( + ContentAppDiscoveryService.DISCOVERY_APPAGENT_EXTRA_ENDPOINTID, -1); + if (endpointId != -1) { + removeContentApp(endpointId); + } + } + } + }; + context.registerReceiver( + mBroadcastReceiver, + new IntentFilter(ContentAppDiscoveryService.DISCOVERY_APPAGENT_ACTION_ADD)); + context.registerReceiver( + mBroadcastReceiver, + new IntentFilter(ContentAppDiscoveryService.DISCOVERY_APPAGENT_ACTION_REMOVE)); + } + + public void setActivity(Activity activity) { + this.activity = activity; + } + + public void addContentApp(ContentApp app) { + app.setEndpointId( + mAppPlatform.addContentApp( + app.getVendorName(), + app.getVendorId(), + app.getAppName(), + app.getProductId(), + "1.0", + new ContentAppEndpointManagerImpl(context))); + } + + public int removeContentApp(int endpointID) { + return mAppPlatform.removeContentApp(endpointID); + } +} diff --git a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/service/MatterServant.java b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/service/MatterServant.java index 2ae498109aec4d..26ebb06f937ebe 100644 --- a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/service/MatterServant.java +++ b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/service/MatterServant.java @@ -17,7 +17,6 @@ */ package com.matter.tv.server.service; -import android.app.Activity; import android.content.Context; import android.util.Log; import androidx.annotation.NonNull; @@ -30,9 +29,6 @@ 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.matter.tv.server.tvapp.ChannelManagerStub; import com.matter.tv.server.tvapp.Clusters; import com.matter.tv.server.tvapp.ContentLaunchManagerStub; @@ -69,7 +65,6 @@ public static MatterServant get() { } private Context context; - private Activity activity; public void init(@NonNull Context context) { @@ -117,7 +112,6 @@ public void init(@NonNull Context context) { } }); mTvApp.setDACProvider(new DACProviderStub()); - mTvApp.setUserPrompter(new MatterCommissioningPrompter(activity)); mTvApp.setChipDeviceEventProvider( new DeviceEventProvider() { @@ -144,8 +138,6 @@ public void onCommissioningComplete() { chipAppServer = new ChipAppServer(); chipAppServer.startApp(); - - mTvApp.postServerInit(new ContentAppEndpointManagerImpl(context)); } public void restart() { @@ -158,10 +150,6 @@ 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 @@ -170,18 +158,4 @@ public void sendCustomCommand(String customCommand) { public void updateLevel(int value) { mTvApp.setCurrentLevel(mLevelEndpoint, value); } - - public int addContentApp(ContentApp app) { - return mTvApp.addContentApp( - app.getVendorName(), - app.getVendorId(), - app.getAppName(), - app.getProductId(), - "1.0", - new ContentAppEndpointManagerImpl(context)); - } - - public void sendTestMessage(int endpoint, String message) { - mTvApp.sendTestMessage(endpoint, message); - } } diff --git a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/service/MatterServantService.java b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/service/MatterServantService.java index cc68f49c09be07..2965ff4d6bc5c8 100644 --- a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/service/MatterServantService.java +++ b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/service/MatterServantService.java @@ -12,8 +12,6 @@ import androidx.core.app.NotificationCompat; import com.matter.tv.server.MainActivity; import com.matter.tv.server.R; -import com.matter.tv.server.model.ContentApp; -import com.matter.tv.server.receivers.ContentAppDiscoveryService; public class MatterServantService extends Service { private static final String CHANNEL_ID = "Matter"; @@ -24,12 +22,7 @@ public void onCreate() { // Start Matter Server MatterServant.get().init(this.getApplicationContext()); - // Register for packages updates - ContentAppDiscoveryService.getReceiverInstance().registerSelf(this.getApplicationContext()); - for (ContentApp app : - ContentAppDiscoveryService.getReceiverInstance().getDiscoveredContentApps().values()) { - app.setEndpointId(MatterServant.get().addContentApp(app)); - } + AppPlatformService.get().init(this.getApplicationContext()); } @Nullable diff --git a/examples/tv-app/android/BUILD.gn b/examples/tv-app/android/BUILD.gn index 2e646454c6fc72..d68700655df04e 100644 --- a/examples/tv-app/android/BUILD.gn +++ b/examples/tv-app/android/BUILD.gn @@ -39,6 +39,8 @@ shared_library("jni") { "include/target-navigator/TargetNavigatorManager.h", "java/AppImpl.cpp", "java/AppImpl.h", + "java/AppPlatform-JNI.cpp", + "java/AppPlatform-JNI.h", "java/AppPlatformShellCommands-JNI.cpp", "java/AppPlatformShellCommands-JNI.h", "java/ChannelManager.cpp", @@ -105,6 +107,7 @@ android_library("java") { ] sources = [ + "java/src/com/matter/tv/server/tvapp/AppPlatform.java", "java/src/com/matter/tv/server/tvapp/AppPlatformShellCommands.java", "java/src/com/matter/tv/server/tvapp/ChannelInfo.java", "java/src/com/matter/tv/server/tvapp/ChannelLineupInfo.java", diff --git a/examples/tv-app/android/java/AppImpl.cpp b/examples/tv-app/android/java/AppImpl.cpp index de3d48505dec67..f099c624163349 100644 --- a/examples/tv-app/android/java/AppImpl.cpp +++ b/examples/tv-app/android/java/AppImpl.cpp @@ -374,48 +374,23 @@ EndpointId ContentAppFactoryImpl::AddContentApp(ContentAppImpl * app, jobject co return epId; } -/** - * @brief Code for testing the message flow path. - * - */ -class TestCommandHandlerCallback : public app::CommandHandler::Callback +EndpointId ContentAppFactoryImpl::RemoveContentApp(EndpointId epId) { - void OnDone(app::CommandHandler & apCommandObj) {} - - void DispatchCommand(app::CommandHandler & apCommandObj, const app::ConcreteCommandPath & aCommandPath, - TLV::TLVReader & apPayload) - {} - - Protocols::InteractionModel::Status CommandExists(const app::ConcreteCommandPath & aCommandPath) - { - return Protocols::InteractionModel::Status::Success; - } -}; - -/** - * @brief Code for testing the message flow path. - * - */ -void ContentAppFactoryImpl::SendTestMessage(EndpointId epId, const char * message) -{ - ChipLogProgress(DeviceLayer, "ContentAppFactoryImpl SendTestMessage called with message %s & endpointId %d", message, epId); for (size_t i = 0; i < mContentApps.size(); ++i) { - ContentAppImpl * app = mContentApps.at(i); - ChipLogProgress(DeviceLayer, "ContentAppFactoryImpl checking app with endpointId %d", app->GetEndpointId()); + auto & app = mContentApps.at(i); if (app->GetEndpointId() == epId) { - ChipLogProgress(DeviceLayer, "ContentAppFactoryImpl SendTestMessage endpoint found"); - app::ConcreteCommandPath commandPath(epId, app::Clusters::ContentLauncher::Id, - app::Clusters::ContentLauncher::Commands::LaunchURL::Id); - chip::AppPlatform::TestCommandHandlerCallback callback; - app::CommandHandler commandHandler(&callback); - CommandResponseHelper helper(&commandHandler, commandPath); - chip::app::Clusters::ContentLauncher::Structs::BrandingInformation::Type branding; - app->GetContentLauncherDelegate()->HandleLaunchUrl(helper, CharSpan::fromCharString(message), - CharSpan::fromCharString("Temp Display"), branding); + ChipLogProgress(DeviceLayer, "ContentAppFactoryImpl RemoveContentApp endpointId %d", epId); + EndpointId removedEndpointID = ContentAppPlatform::GetInstance().RemoveContentApp(app); + if (removedEndpointID != 0) + { + mContentApps.erase(mContentApps.begin() + static_cast(i)); + } + return removedEndpointID; } } + return 0; } void ContentAppFactoryImpl::AddAdminVendorId(uint16_t vendorId) @@ -480,19 +455,6 @@ CHIP_ERROR InitVideoPlayerPlatform(JNIMyUserPrompter * userPrompter, jobject con return CHIP_NO_ERROR; } -CHIP_ERROR PreServerInit() -{ - /** - * Apply any user-defined configurations prior to initializing Server. - * - * Ex. - * DnssdServer::Instance().SetExtendedDiscoveryTimeoutSecs(userTimeoutSecs); - * - */ - - return CHIP_NO_ERROR; -} - EndpointId AddContentApp(const char * szVendorName, uint16_t vendorId, const char * szApplicationName, uint16_t productId, const char * szApplicationVersion, jobject manager) { @@ -505,9 +467,11 @@ EndpointId AddContentApp(const char * szVendorName, uint16_t vendorId, const cha return 0; } -void SendTestMessage(EndpointId epID, const char * message) +EndpointId RemoveContentApp(EndpointId epId) { #if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED - gFactory.SendTestMessage(epID, message); + ChipLogProgress(DeviceLayer, "AppImpl: RemoveContentApp endpointId=%d ", epId); + return gFactory.RemoveContentApp(epId); #endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED + return 0; } diff --git a/examples/tv-app/android/java/AppImpl.h b/examples/tv-app/android/java/AppImpl.h index 0b3039ffdda77c..2ead65e2625553 100644 --- a/examples/tv-app/android/java/AppImpl.h +++ b/examples/tv-app/android/java/AppImpl.h @@ -53,10 +53,9 @@ #include CHIP_ERROR InitVideoPlayerPlatform(JNIMyUserPrompter * userPrompter, jobject contentAppEndpointManager); -CHIP_ERROR PreServerInit(); EndpointId AddContentApp(const char * szVendorName, uint16_t vendorId, const char * szApplicationName, uint16_t productId, const char * szApplicationVersion, jobject manager); -void SendTestMessage(EndpointId epID, const char * message); +EndpointId RemoveContentApp(EndpointId epId); #if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED @@ -133,7 +132,7 @@ class DLL_EXPORT ContentAppFactoryImpl : public ContentAppFactory EndpointId AddContentApp(ContentAppImpl * app, jobject contentAppEndpointManager); - void SendTestMessage(EndpointId epID, const char * message); + EndpointId RemoveContentApp(EndpointId epId); // Gets the catalog vendor ID used by this platform uint16_t GetPlatformCatalogVendorId() override; diff --git a/examples/tv-app/android/java/AppPlatform-JNI.cpp b/examples/tv-app/android/java/AppPlatform-JNI.cpp new file mode 100644 index 00000000000000..5e8c84a79c3740 --- /dev/null +++ b/examples/tv-app/android/java/AppPlatform-JNI.cpp @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2021 Project CHIP Authors + * All rights reserved. + * + * 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. + * + */ + +#include "AppPlatform-JNI.h" +#include "AppImpl.h" + +#include "MyUserPrompter-JNI.h" + +#include +#include +#include +#include +#include + +using namespace chip; +using namespace chip::app; +using namespace chip::AppPlatform; +using namespace chip::Credentials; + +#define JNI_METHOD(RETURN, METHOD_NAME) \ + extern "C" JNIEXPORT RETURN JNICALL Java_com_matter_tv_server_tvapp_AppPlatform_##METHOD_NAME + +AppPlatformJNI AppPlatformJNI::sInstance; + +JNI_METHOD(void, nativeInit)(JNIEnv *, jobject app, jobject prompter, jobject contentAppEndpointManager) +{ + chip::DeviceLayer::StackLock lock; + InitVideoPlayerPlatform(new JNIMyUserPrompter(prompter), contentAppEndpointManager); +} + +JNI_METHOD(jint, addContentApp) +(JNIEnv *, jobject, jstring vendorName, jint vendorId, jstring appName, jint productId, jstring appVersion, jobject manager) +{ + chip::DeviceLayer::StackLock lock; + JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); + + JniUtfString vName(env, vendorName); + JniUtfString aName(env, appName); + JniUtfString aVersion(env, appVersion); + EndpointId epId = AddContentApp(vName.c_str(), static_cast(vendorId), aName.c_str(), static_cast(productId), + aVersion.c_str(), manager); + return static_cast(epId); +} + +JNI_METHOD(jint, removeContentApp) +(JNIEnv *, jobject, jint endpointId) +{ + chip::DeviceLayer::StackLock lock; + EndpointId epId = RemoveContentApp(static_cast(endpointId)); + return static_cast(epId); +} diff --git a/examples/tv-app/android/java/AppPlatform-JNI.h b/examples/tv-app/android/java/AppPlatform-JNI.h new file mode 100644 index 00000000000000..3a6e6fa28233fd --- /dev/null +++ b/examples/tv-app/android/java/AppPlatform-JNI.h @@ -0,0 +1,35 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * All rights reserved. + * + * 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. + */ + +#pragma once + +#include + +class AppPlatformJNI +{ + +private: + friend AppPlatformJNI & AppPlatformJNIMgr(); + + static AppPlatformJNI sInstance; +}; + +inline class AppPlatformJNI & AppPlatformJNIMgr() +{ + return AppPlatformJNI::sInstance; +} diff --git a/examples/tv-app/android/java/ContentAppCommandDelegate.cpp b/examples/tv-app/android/java/ContentAppCommandDelegate.cpp index 966f532ecd18ac..c5b2e11c97e485 100644 --- a/examples/tv-app/android/java/ContentAppCommandDelegate.cpp +++ b/examples/tv-app/android/java/ContentAppCommandDelegate.cpp @@ -37,31 +37,6 @@ namespace AppPlatform { using CommandHandlerInterface = chip::app::CommandHandlerInterface; using LaunchResponseType = chip::app::Clusters::ContentLauncher::Commands::LaunchResponse::Type; -const char * ContentAppCommandDelegate::sendCommand(chip::EndpointId epID, std::string commandPayload) -{ - // to support the hardcoded sample apps. - if (mSendCommandMethod == nullptr) - { - return "Failed"; - } - - JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); - UtfString jCommandPayload(env, commandPayload.c_str()); - ChipLogProgress(Zcl, "ContentAppCommandDelegate::sendCommand with payload %s", commandPayload.c_str()); - jstring resp = (jstring) env->CallObjectMethod(mContentAppEndpointManager, mSendCommandMethod, static_cast(epID), - jCommandPayload.jniValue()); - if (env->ExceptionCheck()) - { - ChipLogError(Zcl, "Java exception in ContentAppCommandDelegate::sendCommand"); - env->ExceptionDescribe(); - env->ExceptionClear(); - // TODO : Need to have proper errors passed back. - return "Failed"; - } - const char * ret = env->GetStringUTFChars(resp, 0); - return ret; -} - void ContentAppCommandDelegate::InvokeCommand(CommandHandlerInterface::HandlerContext & handlerContext) { if (handlerContext.mRequestPath.mEndpointId >= FIXED_ENDPOINT_COUNT) diff --git a/examples/tv-app/android/java/ContentAppCommandDelegate.h b/examples/tv-app/android/java/ContentAppCommandDelegate.h index 908b2e4d1cc0e9..bc607e6254d651 100644 --- a/examples/tv-app/android/java/ContentAppCommandDelegate.h +++ b/examples/tv-app/android/java/ContentAppCommandDelegate.h @@ -59,8 +59,6 @@ class ContentAppCommandDelegate : public CommandHandlerInterface void InvokeCommand(CommandHandlerInterface::HandlerContext & handlerContext) override; - const char * sendCommand(chip::EndpointId epID, std::string commandPayload); - private: void InitializeJNIObjects(jobject manager) { diff --git a/examples/tv-app/android/java/MyUserPrompterResolver-JNI.cpp b/examples/tv-app/android/java/MyUserPrompterResolver-JNI.cpp index 4dc95a2b16b684..ebe342da2f4a43 100644 --- a/examples/tv-app/android/java/MyUserPrompterResolver-JNI.cpp +++ b/examples/tv-app/android/java/MyUserPrompterResolver-JNI.cpp @@ -31,6 +31,7 @@ using namespace chip; JNI_METHOD(void, OnPinCodeEntered)(JNIEnv *, jobject, jint jPinCode) { #if CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE + chip::DeviceLayer::StackLock lock; uint32_t pinCode = (uint32_t) jPinCode; ChipLogProgress(Zcl, "OnPinCodeEntered %d", pinCode); GetCommissionerDiscoveryController()->CommissionWithPincode(pinCode); @@ -40,6 +41,7 @@ JNI_METHOD(void, OnPinCodeEntered)(JNIEnv *, jobject, jint jPinCode) JNI_METHOD(void, OnPinCodeDeclined)(JNIEnv *, jobject) { #if CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE + chip::DeviceLayer::StackLock lock; ChipLogProgress(Zcl, "OnPinCodeDeclined"); GetCommissionerDiscoveryController()->Cancel(); #endif diff --git a/examples/tv-app/android/java/TVApp-JNI.cpp b/examples/tv-app/android/java/TVApp-JNI.cpp index ac1ef7abfd4f66..d2d0897a57e4d5 100644 --- a/examples/tv-app/android/java/TVApp-JNI.cpp +++ b/examples/tv-app/android/java/TVApp-JNI.cpp @@ -17,7 +17,6 @@ */ #include "TvApp-JNI.h" -#include "AppImpl.h" #include "ChannelManager.h" #include "ContentLauncherManager.h" #include "DeviceCallbacks.h" @@ -43,7 +42,6 @@ using namespace chip; using namespace chip::app; -using namespace chip::AppPlatform; using namespace chip::Credentials; #define JNI_METHOD(RETURN, METHOD_NAME) extern "C" JNIEXPORT RETURN JNICALL Java_com_matter_tv_server_tvapp_TvApp_##METHOD_NAME @@ -153,16 +151,12 @@ JNI_METHOD(void, preServerInit)(JNIEnv *, jobject app) { chip::DeviceLayer::StackLock lock; ChipLogProgress(Zcl, "TvAppJNI::preServerInit"); - - PreServerInit(); } JNI_METHOD(void, postServerInit)(JNIEnv *, jobject app, jobject contentAppEndpointManager) { chip::DeviceLayer::StackLock lock; ChipLogProgress(Zcl, "TvAppJNI::postServerInit"); - - InitVideoPlayerPlatform(userPrompter, contentAppEndpointManager); } JNI_METHOD(void, setOnOffManager)(JNIEnv *, jobject, jint endpoint, jobject manager) @@ -189,25 +183,3 @@ JNI_METHOD(void, setChipDeviceEventProvider)(JNIEnv *, jobject, jobject provider { DeviceCallbacks::NewManager(provider); } - -JNI_METHOD(jint, addContentApp) -(JNIEnv *, jobject, jstring vendorName, jint vendorId, jstring appName, jint productId, jstring appVersion, jobject manager) -{ - chip::DeviceLayer::StackLock lock; - JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); - - JniUtfString vName(env, vendorName); - JniUtfString aName(env, appName); - JniUtfString aVersion(env, appVersion); - EndpointId epId = AddContentApp(vName.c_str(), static_cast(vendorId), aName.c_str(), static_cast(productId), - aVersion.c_str(), manager); - return static_cast(epId); -} - -JNI_METHOD(void, sendTestMessage)(JNIEnv *, jobject, jint endpoint, jstring message) -{ - JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); - const char * nmessage = env->GetStringUTFChars(message, 0); - ChipLogProgress(Zcl, "TvApp-JNI SendTestMessage called with message %s", nmessage); - SendTestMessage(static_cast(endpoint), nmessage); -} diff --git a/examples/tv-app/android/java/src/com/matter/tv/server/tvapp/AppPlatform.java b/examples/tv-app/android/java/src/com/matter/tv/server/tvapp/AppPlatform.java new file mode 100644 index 00000000000000..ca6dbd0c74c729 --- /dev/null +++ b/examples/tv-app/android/java/src/com/matter/tv/server/tvapp/AppPlatform.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2021 Project CHIP Authors + * All rights reserved. + * + * 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 com.matter.tv.server.tvapp; + +public class AppPlatform { + private static final String TAG = "AppPlatform"; + + public AppPlatform(UserPrompter userPrompter, ContentAppEndpointManager manager) { + nativeInit(userPrompter, manager); + } + + public native void nativeInit(UserPrompter userPrompter, ContentAppEndpointManager manager); + + public native int addContentApp( + String vendorName, + int vendorId, + String appName, + int productId, + String appVersion, + ContentAppEndpointManager manager); + + public native int removeContentApp(int endpointId); + + static { + System.loadLibrary("TvApp"); + } +} diff --git a/examples/tv-app/android/java/src/com/matter/tv/server/tvapp/TvApp.java b/examples/tv-app/android/java/src/com/matter/tv/server/tvapp/TvApp.java index 0527708235cd2e..ec45db1c8d747c 100644 --- a/examples/tv-app/android/java/src/com/matter/tv/server/tvapp/TvApp.java +++ b/examples/tv-app/android/java/src/com/matter/tv/server/tvapp/TvApp.java @@ -69,18 +69,6 @@ private void postClusterInit(int clusterId, int endpoint) { public native void setChipDeviceEventProvider(DeviceEventProvider provider); - public native int addContentApp( - String vendorName, - int vendorId, - String appName, - int productId, - String appVersion, - ContentAppEndpointManager manager); - - public native void sendTestMessage(int endpoint, String message); - - public native void setUserPrompter(UserPrompter userPrompter); - static { System.loadLibrary("TvApp"); }