diff --git a/AudioFilter/filterAudioSubscriber.h b/AudioFilter/filterAudioSubscriber.h index 628c343796f1544a6f2e51e94c16cd52399e0dc1..98ab5d4c4b270178366048a4d274f6b437f266cb 100644 --- a/AudioFilter/filterAudioSubscriber.h +++ b/AudioFilter/filterAudioSubscriber.h @@ -35,9 +35,9 @@ public: FilterAudioSubscriber(const std::string& dataPath, const std::string& irFile); ~FilterAudioSubscriber(); - virtual void update(jami::Observable<AVFrame*>*, AVFrame* const&) override; - virtual void attached(jami::Observable<AVFrame*>*) override; - virtual void detached(jami::Observable<AVFrame*>*) override; + virtual void update(Observable<AVFrame*>*, AVFrame* const&) override; + virtual void attached(Observable<AVFrame*>*) override; + virtual void detached(Observable<AVFrame*>*) override; void detach(); diff --git a/AudioFilter/filterMediaHandler.h b/AudioFilter/filterMediaHandler.h index c14fec70692c4cbff283c068f15ee5ee1170a74d..fefa821bbc8da456b62db0cd8b15478a97768a10 100644 --- a/AudioFilter/filterMediaHandler.h +++ b/AudioFilter/filterMediaHandler.h @@ -29,23 +29,20 @@ using avSubjectPtr = std::weak_ptr<jami::Observable<AVFrame*>>; namespace jami { -class filterMediaHandler : public jami::CallMediaHandler +class filterMediaHandler : public CallMediaHandler { public: filterMediaHandler(std::map<std::string, std::string>&& ppm, std::string&& dataPath); ~filterMediaHandler(); - virtual void notifyAVFrameSubject(const StreamData& data, jami::avSubjectPtr subject) override; + virtual void notifyAVFrameSubject(const StreamData& data, avSubjectPtr subject) override; virtual std::map<std::string, std::string> getCallMediaHandlerDetails() override; - virtual void detach() override; virtual void setPreferenceAttribute(const std::string& key, const std::string& value) override; virtual bool preferenceMapHasKey(const std::string& key) override; std::shared_ptr<FilterAudioSubscriber> mAS; - const std::string& dataPath() const { return datapath_; } - private: const std::string datapath_; std::map<std::string, std::string> ppm_; diff --git a/AudioFilter/main.cpp b/AudioFilter/main.cpp index f390db833bc67ecdca5a63e9e4df7d6f7b250d37..045a9092e7af58111b1bca065a434fb91dd6c756 100644 --- a/AudioFilter/main.cpp +++ b/AudioFilter/main.cpp @@ -17,6 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ + #include <iostream> #include <string.h> #include <thread> @@ -44,9 +45,9 @@ pluginExit(void) EXPORT_PLUGIN JAMI_PluginExitFunc JAMI_dynPluginInit(const JAMI_PluginAPI* api) { - std::cout << "**************************" << std::endl << std::endl; + std::cout << "*******************" << std::endl << std::endl; std::cout << "** AudioFilter **" << std::endl; - std::cout << "**************************" << std::endl << std::endl; + std::cout << "*******************" << std::endl << std::endl; std::cout << " Version " << AudioFilter_VERSION_MAJOR << "." << AudioFilter_VERSION_MINOR << "." << AudioFilter_VERSION_PATCH << std::endl; @@ -57,11 +58,11 @@ JAMI_dynPluginInit(const JAMI_PluginAPI* api) std::string dataPath; api->invokeService(api, "getPluginDataPath", &dataPath); - auto fmpfilterMediaHandler = std::make_unique<jami::filterMediaHandler>(std::move(ppm), std::move(dataPath)); + auto fmpfilterMediaHandler = std::make_unique<jami::filterMediaHandler>(std::move(ppm), + std::move(dataPath)); if (api->manageComponent(api, "CallMediaHandlerManager", fmpfilterMediaHandler.release())) { return nullptr; } - } return pluginExit; } diff --git a/AutoAnswer/CMakeLists.txt b/AutoAnswer/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..6e893e307471f4a391d9ae2c1b665e68cdd29c80 --- /dev/null +++ b/AutoAnswer/CMakeLists.txt @@ -0,0 +1,78 @@ +cmake_minimum_required(VERSION 3.10) + +# set the project name +set (ProjectName AutoAnswer) +set (Version 0.1.0) + +project(${ProjectName} VERSION ${Version}) + +set (DAEMON ${PROJECT_SOURCE_DIR}/../../daemon) +set (JPL_FILE_NAME ${ProjectName}.jpl) +set (DAEMON_SRC ${DAEMON}/src) +set (CONTRIB_PATH ${DAEMON}/contrib) +set (PLUGINS_LIB ${PROJECT_SOURCE_DIR}/../lib) +set (JPL_DIRECTORY ${PROJECT_BINARY_DIR}/jpl) +set (LIBS_DIR ${PROJECT_SOURCE_DIR}/../contrib/Libs) + +if(WIN32) + message(OS:\ WINDOWS\ ${CMAKE_SYSTEM_PROCESSOR}) + if (NOT ${CMAKE_CL_64}) + message( FATAL_ERROR "\nUse CMake only for x64 Windows" ) + endif() + set (CONTRIB_PLATFORM_CURT x64) + set (CONTRIB_PLATFORM ${CONTRIB_PLATFORM_CURT}-windows) + set (LIBRARY_FILE_NAME ${ProjectName}.dll) +else() + message( FATAL_ERROR "\nUse CMake only for Windows! For linux or Android (linux host), use our bash scripts." ) +endif() + +message(Building:\ ${ProjectName}\ ${Version}) +message(Build\ path:\ ${PROJECT_BINARY_DIR}) +message(JPL\ assembling\ path:\ ${JPL_DIRECTORY}) +message(JPL\ path:\ ${JPL_DIRECTORY}/../../../build/${ProjectName}/${JPL_FILE_NAME}) + +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED True) +set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT") +set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd") + +set(plugin_SRC botchathandler.cpp + botPeerChatSubscriber.cpp + main.cpp + ) + +set(plugin_HDR botchathandler.h + botPeerChatSubscriber.h + ./../lib/pluglog.h + ) + +add_library(${ProjectName} SHARED ${plugin_SRC} + ${plugin_HDR} + ) + +target_include_directories(${ProjectName} PUBLIC ${PROJECT_BINARY_DIR} + ${PROJECT_SOURCE_DIR} + ${PLUGINS_LIB} + ${DAEMON_SRC} + ${CONTRIB_PATH} + ) +target_link_directories(${ProjectName} PUBLIC ${CONTRIB_PATH} + ) + +# target_link_libraries(${ProjectName} PUBLIC ) + +add_custom_command( + TARGET ${ProjectName} + PRE_BUILD + COMMAND python3 ${PROJECT_SOURCE_DIR}/../SDK/jplManipulation.py --preassemble --plugin=${ProjectName} + COMMENT "Assembling Plugin files" +) + +add_custom_command( + TARGET ${ProjectName} + POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_BINARY_DIR}/Release/${ProjectName}.lib ${JPL_DIRECTORY}/lib/${CONTRIB_PLATFORM} + COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_BINARY_DIR}/Release/${LIBRARY_FILE_NAME} ${JPL_DIRECTORY}/lib/${CONTRIB_PLATFORM} + COMMAND python3 ${PROJECT_SOURCE_DIR}/../SDK/jplManipulation.py --assemble --plugin=${ProjectName} + COMMENT "Generating JPL archive" +) diff --git a/AutoAnswer/botPeerChatSubscriber.cpp b/AutoAnswer/botPeerChatSubscriber.cpp new file mode 100644 index 0000000000000000000000000000000000000000..046f1f9f6ba9dbff4c39642dc7d8df973d91d36d --- /dev/null +++ b/AutoAnswer/botPeerChatSubscriber.cpp @@ -0,0 +1,93 @@ +/** + * Copyright (C) 2020 Savoir-faire Linux Inc. + * + * Author: Aline Gondim Santos <aline.gondimsantos@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "botPeerChatSubscriber.h" +#include "pluglog.h" + +const std::string TAG = "bot"; + +namespace jami { + +botPeerChatSubscriber::botPeerChatSubscriber(const JAMI_PluginAPI* api, std::string& textAnswer) + : api_ {api} + , textAnswer_ {textAnswer} +{} + +botPeerChatSubscriber::~botPeerChatSubscriber() +{ + std::ostringstream oss; + oss << "~botChatProcessor" << std::endl; + Plog::log(Plog::LogPriority::INFO, TAG, oss.str()); +} + +void +botPeerChatSubscriber::update(Observable<pluginMessagePtr>*, const pluginMessagePtr& message) +{ + if (isAttached) { + if (message->direction == "0") { + std::map<std::string, std::string> sendMsg; + for (auto& pair : message->data) { + if (pair.first == "text/plain" && pair.second == "hi") { + std::ostringstream sendMsgStream; + sendMsgStream << "HelloWorld from bot plugin"; + sendMsg[pair.first] = sendMsgStream.str(); + } + } + if (!sendMsg.empty()) { + sendText(message->accountId, message->peerId, sendMsg); + } + } + } +} + +void +botPeerChatSubscriber::attached(Observable<pluginMessagePtr>* observable) +{ + if (observables_.find(observable) == observables_.end()) { + std::ostringstream oss; + oss << "::Attached ! " << std::endl; + Plog::log(Plog::LogPriority::INFO, TAG, oss.str()); + observables_.insert(observable); + isAttached = true; + } +} + +void +botPeerChatSubscriber::detached(Observable<pluginMessagePtr>* observable) +{ + if (observables_.find(observable) != observables_.end()) { + observables_.erase(observable); + std::ostringstream oss; + oss << "::Detached()" << std::endl; + Plog::log(Plog::LogPriority::INFO, TAG, oss.str()); + if (observables_.empty()) + isAttached = false; + } +} + +void +botPeerChatSubscriber::sendText(std::string& accountId, + std::string& peerId, + std::map<std::string, std::string>& sendMsg) +{ + pluginMessagePtr botAnswer = std::make_shared<JamiMessage>(accountId, peerId, "0", sendMsg, true); + api_->invokeService(api_, "sendTextMessage", botAnswer.get()); +} +} // namespace jami diff --git a/AutoAnswer/botPeerChatSubscriber.h b/AutoAnswer/botPeerChatSubscriber.h new file mode 100644 index 0000000000000000000000000000000000000000..a319904f68a3bb569d0c0c69db93e6f07a964d9c --- /dev/null +++ b/AutoAnswer/botPeerChatSubscriber.h @@ -0,0 +1,54 @@ +/** + * Copyright (C) 2020 Savoir-faire Linux Inc. + * + * Author: Aline Gondim Santos <aline.gondimsantos@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#pragma once + +#include "observer.h" + +#include "plugin/streamdata.h" +#include "plugin/jamiplugin.h" +#include "plugin/chathandler.h" + +#include <map> +#include <set> + +namespace jami { + +class botPeerChatSubscriber : public Observer<pluginMessagePtr> +{ +public: + botPeerChatSubscriber(const JAMI_PluginAPI* api, std::string& textAnswer); + ~botPeerChatSubscriber(); + virtual void update(Observable<pluginMessagePtr>*, pluginMessagePtr const&) override; + virtual void attached(Observable<pluginMessagePtr>*) override; + virtual void detached(Observable<pluginMessagePtr>*) override; + + void sendText(std::string& accountId, + std::string& peerId, + std::map<std::string, std::string>& sendMsg); + +protected: + // Observer pattern + std::set<Observable<pluginMessagePtr>*> observables_; + bool isAttached {false}; + const JAMI_PluginAPI* api_; + std::string textAnswer_{}; +}; +} // namespace jami diff --git a/AutoAnswer/botchathandler.cpp b/AutoAnswer/botchathandler.cpp new file mode 100644 index 0000000000000000000000000000000000000000..fce506ab1d2cad1bc3577b9f069577164d4119a6 --- /dev/null +++ b/AutoAnswer/botchathandler.cpp @@ -0,0 +1,97 @@ +/** + * Copyright (C) 2020 Savoir-faire Linux Inc. + * + * Author: Aline Gondim Santos <aline.gondimsantos@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "botchathandler.h" + +#include "pluglog.h" + +const char sep = separator(); +const std::string TAG = "bot"; + +#define NAME "bot" + +namespace jami { + +botChatHandler::botChatHandler(const JAMI_PluginAPI* api, + std::map<std::string, std::string>&& ppm, + std::string&& dataPath) + : api_ {api} + , datapath_ {dataPath} +{ + ppm_ = ppm; + setId(datapath_); + peerChatSubscriber_ = std::make_shared<botPeerChatSubscriber>(api_, dataPath); +}; + +void +botChatHandler::notifyChatSubject(std::pair<std::string, std::string>& subjectConnection, + chatSubjectPtr subject) +{ + if (subjects.find(subject) == subjects.end()) { + std::ostringstream oss; + oss << "NEW SUBJECT: account = " << subjectConnection.first + << " peer = " << subjectConnection.second << std::endl; + Plog::log(Plog::LogPriority::INFO, TAG, oss.str()); + subject->attach(peerChatSubscriber_.get()); + subjects.insert(subject); + } +} + +std::map<std::string, std::string> +botChatHandler::getChatHandlerDetails() +{ + return {{"name", NAME}, {"iconPath", datapath_ + sep + "icon.png"}, {"pluginId", id()}}; +} + +void +botChatHandler::setPreferenceAttribute(const std::string& key, const std::string& value) +{ + auto it = ppm_.find(key); + if (it != ppm_.end()) { + if (ppm_[key] != value) { + ppm_[key] = value; + } + } +} + +bool +botChatHandler::preferenceMapHasKey(const std::string& key) +{ + return false; +} + +void +botChatHandler::detach(chatSubjectPtr subject) +{ + if (subjects.find(subject) != subjects.end()) { + subject->detach(peerChatSubscriber_.get()); + subjects.erase(subject); + } +} + +botChatHandler::~botChatHandler() +{ + auto& copy(subjects); + for (const auto& subject : copy) { + detach(subject); + } + copy.clear(); +} +} // namespace jami diff --git a/AutoAnswer/botchathandler.h b/AutoAnswer/botchathandler.h new file mode 100644 index 0000000000000000000000000000000000000000..7c11346c0accda99632c92772dd0012f95d82493 --- /dev/null +++ b/AutoAnswer/botchathandler.h @@ -0,0 +1,60 @@ +/** + * Copyright (C) 2020 Savoir-faire Linux Inc. + * + * Author: Aline Gondim Santos <aline.gondimsantos@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#pragma once + +#include "botPeerChatSubscriber.h" + +#include "plugin/jamiplugin.h" +#include "plugin/chathandler.h" + +#include <string> +#include <map> +#include <memory> +#include <set> + +using chatSubjectPtr = std::shared_ptr<jami::PublishObservable<jami::pluginMessagePtr>>; + +namespace jami { + +class botChatHandler : public jami::ChatHandler +{ +public: + botChatHandler(const JAMI_PluginAPI* api, + std::map<std::string, std::string>&& ppm, + std::string&& dataPath); + ~botChatHandler() override; + + virtual void notifyChatSubject(std::pair<std::string, std::string>& subjectConnection, + chatSubjectPtr subject) override; + virtual std::map<std::string, std::string> getChatHandlerDetails() override; + virtual void detach(chatSubjectPtr subject) override; + virtual void setPreferenceAttribute(const std::string& key, const std::string& value) override; + virtual bool preferenceMapHasKey(const std::string& key) override; + + std::shared_ptr<botPeerChatSubscriber> peerChatSubscriber_; + +private: + const JAMI_PluginAPI* api_; + const std::string datapath_; + std::map<std::string, std::string> ppm_; + std::set<chatSubjectPtr> subjects; +}; +} // namespace jami diff --git a/AutoAnswer/build.sh b/AutoAnswer/build.sh new file mode 100755 index 0000000000000000000000000000000000000000..c4193ab93f846545ad1676b9404b75b995438b4f --- /dev/null +++ b/AutoAnswer/build.sh @@ -0,0 +1,202 @@ +#! /bin/bash +# Build the plugin for the project +export OSTYPE +ARCH=$(arch) +EXTRAPATH='' +# Flags: + +# -p: number of processors to use +# -c: Runtime plugin cpu/gpu setting. +# -t: target platform. + + +if [ -z "${DAEMON}" ]; then + DAEMON="./../../daemon" + echo "DAEMON not provided, building with ${DAEMON}" +fi + +PLUGIN_NAME="AutoAnswer" +JPL_FILE_NAME="${PLUGIN_NAME}.jpl" +SO_FILE_NAME="lib${PLUGIN_NAME}.so" +DAEMON_SRC="${DAEMON}/src" +CONTRIB_PATH="${DAEMON}/contrib" +PLUGINS_LIB="../lib" +LIBS_DIR="./../contrib/Libs" + +if [ -z "${PLATFORM}" ]; then + PLATFORM="linux-gnu" + echo "PLATFORM not provided, building with ${PLATFORM}" + echo "Other options: redhat-linux" +fi + +while getopts t:c:p OPT; do + case "$OPT" in + t) + PLATFORM="${OPTARG}" + ;; + c) + PROCESSOR="${OPTARG}" + ;; + p) + ;; + \?) + exit 1 + ;; + esac +done + +if [ "${PLATFORM}" = "linux-gnu" ] || [ "${PLATFORM}" = "redhat-linux" ] +then + python3 ./../SDK/jplManipulation.py --preassemble --plugin=${PLUGIN_NAME} + + CONTRIB_PLATFORM_CURT=${ARCH} + CONTRIB_PLATFORM=${CONTRIB_PLATFORM_CURT}-${PLATFORM} + + # Compile + clang++ -std=c++17 -shared -fPIC \ + -Wl,-Bsymbolic,-rpath,"\${ORIGIN}" \ + -Wall -Wextra \ + -Wno-unused-variable \ + -Wno-unused-function \ + -Wno-unused-parameter \ + -I"." \ + -I"${DAEMON_SRC}" \ + -I"${CONTRIB_PATH}/${CONTRIB_PLATFORM}/include" \ + -I"${PLUGINS_LIB}" \ + botchathandler.cpp \ + botPeerChatSubscriber.cpp \ + main.cpp \ + -L"${CONTRIB_PATH}/${CONTRIB_PLATFORM}/lib/" \ + -o "build-local/jpl/lib/${CONTRIB_PLATFORM_CURT}-linux-gnu/${SO_FILE_NAME}" + +elif [ "${PLATFORM}" = "android" ] +then + python3 ./../SDK/jplManipulation.py --preassemble --plugin=${PLUGIN_NAME} --distribution=${PLATFORM} + + if [ -z "$ANDROID_NDK" ]; then + ANDROID_NDK="/home/${USER}/Android/Sdk/ndk/21.1.6352462" + echo "ANDROID_NDK not provided, building with ${ANDROID_NDK}" + fi + + #========================================================= + # Check if the ANDROID_ABI was provided + # if not, set default + #========================================================= + if [ -z "$ANDROID_ABI" ]; then + ANDROID_ABI="armeabi-v7a arm64-v8a x86_64" + echo "ANDROID_ABI not provided, building for ${ANDROID_ABI}" + fi + + buildlib() { + echo "$CURRENT_ABI" + + #========================================================= + # ANDROID TOOLS + #========================================================= + export HOST_TAG=linux-x86_64 + export TOOLCHAIN=$ANDROID_NDK/toolchains/llvm/prebuilt/$HOST_TAG + + if [ "$CURRENT_ABI" = armeabi-v7a ] + then + export AR=$TOOLCHAIN/bin/arm-linux-android-ar + export AS=$TOOLCHAIN/bin/arm-linux-android-as + export CC=$TOOLCHAIN/bin/armv7a-linux-androideabi21-clang + export CXX=$TOOLCHAIN/bin/armv7a-linux-androideabi21-clang++ + export LD=$TOOLCHAIN/bin/arm-linux-android-ld + export RANLIB=$TOOLCHAIN/bin/arm-linux-android-ranlib + export STRIP=$TOOLCHAIN/bin/arm-linux-androideabi-strip + export ANDROID_SYSROOT=${DAEMON}/../client-android/android-toolchain-21-arm/sysroot + + elif [ "$CURRENT_ABI" = arm64-v8a ] + then + export AR=$TOOLCHAIN/bin/aarch64-linux-android-ar + export AS=$TOOLCHAIN/bin/aarch64-linux-android-as + export CC=$TOOLCHAIN/bin/aarch64-linux-android21-clang + export CXX=$TOOLCHAIN/bin/aarch64-linux-android21-clang++ + export LD=$TOOLCHAIN/bin/aarch64-linux-android-ld + export RANLIB=$TOOLCHAIN/bin/aarch64-linux-android-ranlib + export STRIP=$TOOLCHAIN/bin/aarch64-linux-android-strip + export ANDROID_SYSROOT=${DAEMON}/../client-android/android-toolchain-21-arm64/sysroot + + elif [ "$CURRENT_ABI" = x86_64 ] + then + export AR=$TOOLCHAIN/bin/x86_64-linux-android-ar + export AS=$TOOLCHAIN/bin/x86_64-linux-android-as + export CC=$TOOLCHAIN/bin/x86_64-linux-android21-clang + export CXX=$TOOLCHAIN/bin/x86_64-linux-android21-clang++ + export LD=$TOOLCHAIN/bin/x86_64-linux-android-ld + export RANLIB=$TOOLCHAIN/bin/x86_64-linux-android-ranlib + export STRIP=$TOOLCHAIN/bin/x86_64-linux-android-strip + export ANDROID_SYSROOT=${DAEMON}/../client-android/android-toolchain-21-x86_64/sysroot + + else + echo "ABI NOT OK" >&2 + exit 1 + fi + + #========================================================= + # CONTRIBS + #========================================================= + if [ "$CURRENT_ABI" = armeabi-v7a ] + then + CONTRIB_PLATFORM=arm-linux-androideabi + + elif [ "$CURRENT_ABI" = arm64-v8a ] + then + CONTRIB_PLATFORM=aarch64-linux-android + + elif [ "$CURRENT_ABI" = x86_64 ] + then + CONTRIB_PLATFORM=x86_64-linux-android + fi + + #NDK SOURCES FOR cpufeatures + NDK_SOURCES=${ANDROID_NDK}/sources/android + + #========================================================= + # LD_FLAGS + #========================================================= + if [ "$CURRENT_ABI" = armeabi-v7a ] + then + export EXTRA_LDFLAGS="${EXTRA_LDFLAGS} -L${ANDROID_SYSROOT}/usr/lib/arm-linux-androideabi -L${ANDROID_SYSROOT}/usr/lib/arm-linux-androideabi/21" + elif [ "$CURRENT_ABI" = arm64-v8a ] + then + export EXTRA_LDFLAGS="${EXTRA_LDFLAGS} -L${ANDROID_SYSROOT}/usr/lib/aarch64-linux-android -L${ANDROID_SYSROOT}/usr/lib/aarch64-linux-android/21" + elif [ "$CURRENT_ABI" = x86_64 ] + then + export EXTRA_LDFLAGS="${EXTRA_LDFLAGS} -L${ANDROID_SYSROOT}/usr/lib/x86_64-linux-android -L${ANDROID_SYSROOT}/usr/lib/x86_64-linux-android/21" + fi + + #========================================================= + # Compile the plugin + #========================================================= + + # Create so destination folder + $CXX --std=c++17 -O3 -g -fPIC \ + -Wl,-Bsymbolic,-rpath,"\${ORIGIN}" \ + -shared \ + -Wall -Wextra \ + -Wno-unused-variable \ + -Wno-unused-function \ + -Wno-unused-parameter \ + -I"." \ + -I"${DAEMON_SRC}" \ + -I"${CONTRIB_PATH}/${CONTRIB_PLATFORM}/include" \ + -I"${PLUGINS_LIB}" \ + botchathandler.cpp \ + botPeerChatSubscriber.cpp \ + main.cpp \ + -L"${CONTRIB_PATH}/${CONTRIB_PLATFORM}/lib/" \ + -llog -lz \ + --sysroot=$ANDROID_SYSROOT \ + -o "build-local/jpl/lib/$CURRENT_ABI/${SO_FILE_NAME}" + } + + # Build the so + for i in ${ANDROID_ABI}; do + CURRENT_ABI=$i + buildlib + done +fi + +python3 ./../SDK/jplManipulation.py --assemble --plugin=${PLUGIN_NAME} --distribution=${PLATFORM} --extraPath=${EXTRAPATH} diff --git a/AutoAnswer/data/icon.png b/AutoAnswer/data/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..2ce0aab9f71679f71f7b3d53d8448f7e9852b322 Binary files /dev/null and b/AutoAnswer/data/icon.png differ diff --git a/AutoAnswer/data/preferences.json b/AutoAnswer/data/preferences.json new file mode 100644 index 0000000000000000000000000000000000000000..1e3ec7217afba05e6dcd456b0e89ec7f17bf7b55 --- /dev/null +++ b/AutoAnswer/data/preferences.json @@ -0,0 +1 @@ +[ ] diff --git a/AutoAnswer/main.cpp b/AutoAnswer/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5c4ed2fb613e3c70dc094fd6ce1178236c0c1277 --- /dev/null +++ b/AutoAnswer/main.cpp @@ -0,0 +1,71 @@ +/** + * Copyright (C) 2020 Savoir-faire Linux Inc. + * + * Author: Aline Gondim Santos <aline.gondimsantos@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include <iostream> +#include <string.h> +#include <thread> +#include <memory> +#include <map> +#include "plugin/jamiplugin.h" +#include "botchathandler.h" + +#ifdef WIN32 +#define EXPORT_PLUGIN __declspec(dllexport) +#else +#define EXPORT_PLUGIN +#endif + +#define AutoAnswer_VERSION_MAJOR 0 +#define AutoAnswer_VERSION_MINOR 1 +#define AutoAnswer_VERSION_PATCH 0 + +extern "C" { + +void +pluginExit(void) +{} + +EXPORT_PLUGIN JAMI_PluginExitFunc +JAMI_dynPluginInit(const JAMI_PluginAPI* api) +{ + std::cout << "******************" << std::endl << std::endl; + std::cout << "** AutoAnswer **" << std::endl; + std::cout << "******************" << std::endl << std::endl; + std::cout << " Version " << AutoAnswer_VERSION_MAJOR << "." << AutoAnswer_VERSION_MINOR << "." + << AutoAnswer_VERSION_PATCH << std::endl; + + // If invokeService doesn't return an error + if (api) { + std::map<std::string, std::string> ppm; + api->invokeService(api, "getPluginPreferences", &ppm); + std::string dataPath; + api->invokeService(api, "getPluginDataPath", &dataPath); + + auto fmpbotChatHandler = std::make_unique<jami::botChatHandler>(api, + std::move(ppm), + std::move(dataPath)); + if (api->manageComponent(api, "ChatHandlerManager", fmpbotChatHandler.release())) { + return nullptr; + } + } + + return pluginExit; +} +} diff --git a/AutoAnswer/manifest.json b/AutoAnswer/manifest.json new file mode 100644 index 0000000000000000000000000000000000000000..bcb9a4b2a5206228e88e376219169cd5600c4de0 --- /dev/null +++ b/AutoAnswer/manifest.json @@ -0,0 +1,5 @@ +{ + "name": "AutoAnswer", + "description" : "A plugin that automatically answers with given text", + "version" : "0.1.0" +} diff --git a/AutoAnswer/package.json b/AutoAnswer/package.json new file mode 100644 index 0000000000000000000000000000000000000000..5d42d67a1efad3ffa544c7056b5049f396a6e23f --- /dev/null +++ b/AutoAnswer/package.json @@ -0,0 +1,16 @@ +{ + "name": "AutoAnswer", + "version": "0.1.0", + "extractLibs": false, + "deps": [], + "defines": [], + "custom_scripts": { + "pre_build": [ + "mkdir msvc" + ], + "build": [ + "cmake --build ./msvc --config Release" + ], + "post_build": [] + } +} \ No newline at end of file diff --git a/GreenScreen/pluginMediaHandler.h b/GreenScreen/pluginMediaHandler.h index 368dbd9f74da32f68186e732da85fbdaf343de5c..41a1693b4446f289deca6beafe612f6a09df579e 100644 --- a/GreenScreen/pluginMediaHandler.h +++ b/GreenScreen/pluginMediaHandler.h @@ -47,8 +47,6 @@ public: std::shared_ptr<VideoSubscriber> mVS; - const std::string& dataPath() const { return datapath_; } - private: const std::string datapath_; std::map<std::string, std::string> ppm_; diff --git a/HelloWorld/CenterCircleMediaHandler.h b/HelloWorld/CenterCircleMediaHandler.h index f431371a9f0ebe27907a8896fb4b873fca4f56c0..f8836f91960fdb43e6c6c7ed83ff018e406951ca 100644 --- a/HelloWorld/CenterCircleMediaHandler.h +++ b/HelloWorld/CenterCircleMediaHandler.h @@ -43,8 +43,6 @@ public: std::shared_ptr<CenterCircleVideoSubscriber> mVS; - const std::string& dataPath() const { return datapath_; } - private: const std::string datapath_; std::map<std::string, std::string> ppm_; diff --git a/HelloWorld/CoinCircleMediaHandler.h b/HelloWorld/CoinCircleMediaHandler.h index def64b382898cf62b7a7cb37be21b955ab70c9f3..d14c63f2c78512b3008bcc6bd04aee40df7f12dc 100644 --- a/HelloWorld/CoinCircleMediaHandler.h +++ b/HelloWorld/CoinCircleMediaHandler.h @@ -43,8 +43,6 @@ public: std::shared_ptr<CoinCircleVideoSubscriber> mVS; - const std::string& dataPath() const { return datapath_; } - private: const std::string datapath_; std::map<std::string, std::string> ppm_; diff --git a/HelloWorld/main.cpp b/HelloWorld/main.cpp index 5d211e50101c765a66294c21059a84714d3638ca..4e924f00d3c7f3a316dea39f9847ff6fa53a21c4 100644 --- a/HelloWorld/main.cpp +++ b/HelloWorld/main.cpp @@ -45,9 +45,9 @@ pluginExit(void) EXPORT_PLUGIN JAMI_PluginExitFunc JAMI_dynPluginInit(const JAMI_PluginAPI* api) { - std::cout << "**************************" << std::endl << std::endl; + std::cout << "******************" << std::endl << std::endl; std::cout << "** HelloWorld **" << std::endl; - std::cout << "**************************" << std::endl << std::endl; + std::cout << "******************" << std::endl << std::endl; std::cout << " Version " << HelloWorld_VERSION_MAJOR << "." << HelloWorld_VERSION_MINOR << "." << HelloWorld_VERSION_PATCH << std::endl; diff --git a/SDK/Templates/genericConversationHandler.h b/SDK/Templates/genericConversationHandler.h index 1906ce6d01c4ba2281efe780481d497bee630246..dd434f6479d9caa7e02457e617ed2eb282521344 100644 --- a/SDK/Templates/genericConversationHandler.h +++ b/SDK/Templates/genericConversationHandler.h @@ -1,21 +1,19 @@ HEADER #pragma once -//Project +// Project #include "chatsubscriber.h" -//Jami plugin +// Jami plugin #include "plugin/jamiplugin.h" -#include "plugin/conversationhandler.h" +#include "plugin/chathandler.h" -class GENERICConversationHandler : public jami::ConversationHandler +class GENERICChatHandler : public jami::ChatHandler { public: - GENERICConversationHandler(const JAMI_PluginAPI * api, std::string &&dataPath); - ~GENERICConversationHandler(); + GENERICChatHandler(const JAMI_PluginAPI* api, std::string&& dataPath); + ~GENERICChatHandler(); void detach(); - virtual void notifyStrMapSubject(const bool direction, - jami::strMapSubjectPtr subject) override; - const std::string& dataPath() const { return dataPath_; } + virtual void notifyStrMapSubject(const bool direction, jami::strMapSubjectPtr subject) override; private: std::string dataPath_; diff --git a/SDK/Templates/genericMediaHandler.h b/SDK/Templates/genericMediaHandler.h index 51c8c9b1b7a3e307bd65e582ff276468359e7810..4a001b9b2b72ea082c6ac4b6da5d3a7c5410752f 100644 --- a/SDK/Templates/genericMediaHandler.h +++ b/SDK/Templates/genericMediaHandler.h @@ -26,8 +26,6 @@ public: std::shared_ptr<GENERICDATATYPESubscriber> mediaSubscriber_; - const std::string& dataPath() const { return datapath_; } - private: const std::string datapath_; std::map<std::string, std::string> ppm_; diff --git a/SDK/sdkConstants.py b/SDK/sdkConstants.py index 36073df682a8e8a1368b1961c6f86e2436064ebe..ab91f02a9e7d66268cb40c1ca6f69fa574636e7e 100644 --- a/SDK/sdkConstants.py +++ b/SDK/sdkConstants.py @@ -27,14 +27,14 @@ pattern = re.compile(r'[\W_]+') PLUGINS_APIS = {"MEDIA_HANDLER": '1', "MEDIA_HANDLER_AUDIO": '2', - "CONVERSATION_HANDLER": '3'} + "CHAT_HANDLER": '3'} APIS_NAMES = {"MEDIA_HANDLER": "MediaHandler", - "CONVERSATION_HANDLER": "ConversationHandler"} + "CHAT_HANDLER": "ChatHandler"} DATA_TYPES = {"VIDEO": 'Video', "AUDIO": 'Audio', - "TEXT": 'Conversation'} + "TEXT": 'Chat'} ACTIONS = {"CREATE": '1', "CREATE_MAIN": '2', diff --git a/SDK/skeletonSrcProfile.py b/SDK/skeletonSrcProfile.py index 1e3e11091c3d7b258cf731c2d9ec1993e00e624b..52d779b2bd00316d80f8617655122ac2ac090bd1 100644 --- a/SDK/skeletonSrcProfile.py +++ b/SDK/skeletonSrcProfile.py @@ -152,21 +152,21 @@ class SkeletonSourceFiles(Preferences): files = os.listdir(self.pluginDirectory) for file in files: if (".h" in file): - if (("MediaHandler" in file or "ConversationHandler" in file)): + if (("MediaHandler" in file or "ChatHandler" in file)): name = file.replace(".h", "") name = name.replace("MediaHandler", "") - name = name.replace("ConversationHandler", "") + name = name.replace("ChatHandler", "") self.names.append(name) if ("MediaHandler" in file): self.apis.append(PLUGINS_APIS["MEDIA_HANDLER"]) - elif ("ConversationHandler" in file): - self.apis.append(PLUGINS_APIS["CONVERSATION_HANDLER"]) + elif ("ChatHandler" in file): + self.apis.append(PLUGINS_APIS["CHAT_HANDLER"]) if ("Subscriber" in file): if ("Video" in file): self.dataTypes.append(DATA_TYPES["VIDEO"]) elif ("Audio" in file): self.dataTypes.append(DATA_TYPES["AUDIO"]) - elif ("Conversation" in file): + elif ("Chat" in file): self.dataTypes.append(DATA_TYPES["TEXT"]) def createHandlers(self, split): @@ -177,9 +177,9 @@ class SkeletonSourceFiles(Preferences): if (self.apis[i] == PLUGINS_APIS["MEDIA_HANDLER"]): temp = split.replace("PLUGINAPI", f"{name}MediaHandler") temp = temp.replace("APIMANAGER", "CallMediaHandlerManager") - elif (self.apis[i] == PLUGINS_APIS["CONVERSATION_HANDLER"]): - temp = split.replace("PLUGINAPI", f"{name}ConversationHandler") - temp = temp.replace("APIMANAGER", "ConversationHandlerManager") + elif (self.apis[i] == PLUGINS_APIS["CHAT_HANDLER"]): + temp = split.replace("PLUGINAPI", f"{name}ChatHandler") + temp = temp.replace("APIMANAGER", "ChatManager") createStr += temp return createStr @@ -225,8 +225,8 @@ class SkeletonSourceFiles(Preferences): localNames[j] = self.names[j] + "MediaHandler" if (split): temp = split.replace("INCLUDESAPI", localNames[j]) - elif (item == PLUGINS_APIS["CONVERSATION_HANDLER"]): - localNames[j] = self.names[j] + "ConversationHandler" + elif (item == PLUGINS_APIS["CHAT_HANDLER"]): + localNames[j] = self.names[j] + "ChatHandler" if (split): temp = split.replace("INCLUDESAPI", localNames[j]) includesStr += temp @@ -272,13 +272,13 @@ class SkeletonSourceFiles(Preferences): with open(f"{self.pluginDirectory}/{self.names[j]}{self.dataTypes[j]}Subscriber.h", 'w') as f: f.write(data) f.close() - elif (item == PLUGINS_APIS["CONVERSATION_HANDLER"]): - with open('./Templates/genericConversationHandler.h', 'r') as f: + elif (item == PLUGINS_APIS["CHAT_HANDLER"]): + with open('./Templates/genericChatHandler.h', 'r') as f: data = f.read() data = data.replace("HEADER", self.header) data = data.replace('GENERIC', self.names[j]) f.close() - with open(f"{self.pluginDirectory}/{self.names[j]}ConversationHandler.h", 'w') as f: + with open(f"{self.pluginDirectory}/{self.names[j]}ChatHandler.h", 'w') as f: f.write(data) f.close() @@ -331,13 +331,13 @@ class SkeletonSourceFiles(Preferences): with open(f"{self.pluginDirectory}/{self.names[j]}{self.dataTypes[j]}Subscriber.cpp", 'w') as f: f.write(data) f.close() - elif (item == PLUGINS_APIS["CONVERSATION_HANDLER"]): - with open('./Templates/genericConversationHandler.cpp', 'r') as f: + elif (item == PLUGINS_APIS["CHAT_HANDLER"]): + with open('./Templates/genericChatHandler.cpp', 'r') as f: data = f.read() data = data.replace("HEADER", self.header) data = data.replace("GENERIC", self.names[j]) f.close() - with open(f"{self.pluginDirectory}/{self.names[j]}ConversationHandler.cpp", 'w') as f: + with open(f"{self.pluginDirectory}/{self.names[j]}ChatHandler.cpp", 'w') as f: f.write(data) f.close() self.createPreferences(self.names) @@ -377,8 +377,8 @@ class SkeletonSourceFiles(Preferences): parts = data.split("----------------") f.write(''.join(parts)) f.close() - elif (item == PLUGINS_APIS["CONVERSATION_HANDLER"]): - with open(f"{self.pluginDirectory}/{self.names[j]}ConversationHandler.cpp", 'r') as f: + elif (item == PLUGINS_APIS["CHAT_HANDLER"]): + with open(f"{self.pluginDirectory}/{self.names[j]}ChatHandler.cpp", 'r') as f: data = f.read() parts = data.split("----------------") for part in parts: @@ -402,7 +402,7 @@ class SkeletonSourceFiles(Preferences): data = data.replace(baseStr1, newStr1) data = data.replace(baseStr2, newStr2) f.close() - with open(f"{self.pluginDirectory}/{self.names[j]}ConversationHandler.cpp", 'w') as f: + with open(f"{self.pluginDirectory}/{self.names[j]}ChatHandler.cpp", 'w') as f: parts = data.split("----------------") f.write(''.join(parts)) f.close()